From 3cf5d7882c303a2dc416a5b332693530f8935658 Mon Sep 17 00:00:00 2001 From: Bernd Zeimetz Date: Sat, 27 Dec 2008 01:46:53 +0100 Subject: [PATCH] Imported Upstream version 1.3.5 --- .cvsignore | 23 + AUTHORS | 70 + COPYING | 339 + Makefile.in | 916 + README.contrib | 114 + README.igc | 127 + README.magnav | 28 + README.mapconverter | 35 + README.psp | 112 + README.xmapwpt | 66 + alan.c | 938 + an1.c | 1222 + an1sym.h | 519 + arcdist.c | 170 + avltree.c | 723 + avltree.h | 94 + axim_gpb.c | 174 + bcr.c | 485 + brauniger_iq.c | 268 + cet.c | 366 + cet.h | 71 + cet/ansi_x3_4_1968.h | 501 + cet/atarist.h | 256 + cet/baltic.h | 178 + cet/bs_4730.h | 127 + cet/bs_viewdata.h | 134 + cet/cp1250.h | 266 + cet/cp1251.h | 275 + cet/cp1252.h | 210 + cet/cp1253.h | 242 + cet/cp1254.h | 228 + cet/cp1255.h | 212 + cet/cp1256.h | 232 + cet/cp1257.h | 205 + cet/csa_z243_4_1985_1.h | 131 + cet/csa_z243_4_1985_2.h | 131 + cet/csa_z243_4_1985_gr.h | 206 + cet/csn_369103.h | 200 + cet/cwi.h | 256 + cet/dec_mcs.h | 129 + cet/din_66003.h | 129 + cet/ds_2089.h | 124 + cet/ecma_cyrillic.h | 219 + cet/es.h | 132 + cet/es2.h | 129 + cet/gb_1988_80.h | 127 + cet/gost_19768_87.h | 189 + cet/hp_roman8.h | 219 + cet/ibm037.h | 381 + cet/ibm1004.h | 152 + cet/ibm1026.h | 380 + cet/ibm1047.h | 380 + cet/ibm256.h | 381 + cet/ibm273.h | 380 + cet/ibm277.h | 380 + cet/ibm278.h | 381 + cet/ibm280.h | 381 + cet/ibm284.h | 381 + cet/ibm285.h | 381 + cet/ibm297.h | 381 + cet/ibm437.h | 256 + cet/ibm500.h | 381 + cet/ibm850.h | 257 + cet/ibm851.h | 255 + cet/ibm852.h | 257 + cet/ibm855.h | 255 + cet/ibm857.h | 252 + cet/ibm860.h | 256 + cet/ibm861.h | 256 + cet/ibm862.h | 255 + cet/ibm863.h | 256 + cet/ibm864.h | 249 + cet/ibm865.h | 256 + cet/ibm868.h | 232 + cet/ibm869.h | 248 + cet/ibm871.h | 381 + cet/ibm891.h | 108 + cet/ibm903.h | 108 + cet/ibm904.h | 131 + cet/iec_p27_1.h | 220 + cet/iso_10367_box.h | 149 + cet/iso_5427.h | 188 + cet/iso_646_irv.h | 127 + cet/iso_6937_2_25.h | 166 + cet/iso_8859_1.h | 111 + cet/iso_8859_10.h | 172 + cet/iso_8859_13.h | 175 + cet/iso_8859_14.h | 157 + cet/iso_8859_15.h | 133 + cet/iso_8859_2.h | 183 + cet/iso_8859_3.h | 154 + cet/iso_8859_4.h | 176 + cet/iso_8859_5.h | 219 + cet/iso_8859_6.h | 173 + cet/iso_8859_7.h | 199 + cet/iso_8859_8.h | 156 + cet/iso_8859_9.h | 129 + cet/iso_8859_supp.h | 212 + cet/it.h | 134 + cet/jis_c6220_1969_ro.h | 120 + cet/jis_x0201.h | 195 + cet/jus_i_b1_002.h | 131 + cet/jus_i_b1_003_mac.h | 182 + cet/jus_i_b1_003_serb.h | 182 + cet/keybcs2.h | 256 + cet/koi8_r.h | 256 + cet/koi8_ru.h | 256 + cet/koi8_u.h | 238 + cet/koi_7.h | 156 + cet/koi_8.h | 191 + cet/koi_8_cs2.h | 222 + cet/ksc5636.h | 118 + cet/latin_greek_1.h | 136 + cet/mac_is.h | 248 + cet/macintosh.h | 250 + cet/macintosh_ce.h | 254 + cet/msz_7795_3.h | 135 + cet/nats_dano.h | 136 + cet/nats_sefi.h | 130 + cet/nc_nc00_10.h | 133 + cet/nextstep.h | 240 + cet/nf_z_62_010.h | 135 + cet/nf_z_62_010__1973_.h | 133 + cet/ns_4551_1.h | 125 + cet/ns_4551_2.h | 133 + cet/pt.h | 128 + cet/pt2.h | 127 + cet/sami.h | 157 + cet/sen_850200_b.h | 133 + cet/sen_850200_c.h | 136 + cet/tcvn.h | 278 + cet/viscii.h | 247 + cet/vps.h | 255 + cet_util.c | 1304 + cet_util.h | 133 + cetus.c | 634 + chkdoc | 67 + coastexp.c | 713 + compegps.c | 658 + config.guess | 1463 ++ config.h.in | 71 + config.sub | 1579 ++ configure | 6020 +++++ configure.in | 395 + contrib/correctCoordinates.pl | 100 + contrib/gpx2xfig | 73 + copilot.c | 323 + coto.c | 429 + cst.c | 362 + csv_util.c | 1930 ++ csv_util.h | 146 + defs.h | 981 + delgpl.c | 141 + destinator.c | 588 + dg-100.c | 689 + discard.c | 142 + dmtlog.c | 796 + doc/.cvsignore | 4 + doc/Makefile | 7 + doc/babelfront2.eps | 19937 ++++++++++++++++ doc/doc.tex | 991 + duplicate.c | 260 + easygps.c | 215 + exif.c | 490 + fatal.c | 41 + filter_skeleton.c | 107 + filter_vecs.c | 334 + filterdefs.h | 46 + format_skeleton.c | 156 + formspec.c | 67 + g7towin.c | 546 + garmin.c | 1055 + garmin_fs.c | 415 + garmin_fs.h | 135 + garmin_gpi.c | 1360 ++ garmin_gpi.h | 112 + garmin_tables.c | 990 + garmin_tables.h | 100 + garmin_txt.c | 1284 + gbfile.c | 885 + gbfile.h | 98 + gbser.c | 181 + gbser.h | 137 + gbser_posix.c | 438 + gbser_private.h | 27 + gbser_win.c | 430 + gbsleep.c | 51 + gbtypes.h | 58 + gbversion.h | 8 + gbversion.h.in | 8 + gcdb.c | 320 + gdb.c | 1734 ++ geo.c | 229 + geocaching.loc | 1 + geoniche.c | 778 + ggv_log.c | 276 + globals.c | 31 + glogbook.c | 182 + google.c | 562 + gpilots.c | 439 + gpsbabel-sample.ini | 35 + gpsbabel.html | 5473 +++++ gpsman | 53 + gpsman2 | 75 + gpspilot.c | 240 + gpssim.c | 204 + gpsutil.c | 172 + gpx.c | 1899 ++ gpxval | 37 + grtcirc.c | 348 + grtcirc.h | 47 + gtm.c | 689 + gtrnctr.c | 302 + guibabel | 99 + hiketech.c | 299 + holux.c | 308 + holux.h | 117 + hsa_ndv.c | 563 + html.c | 295 + igc.c | 908 + ignrando.c | 286 + ik3d.c | 196 + inifile.c | 361 + inifile.h | 62 + install-sh | 323 + intdoc/BraunigerIQformat | 55 + ...Babel Windows GUI 2.00.00 Project Plan.pdf | Bin 0 -> 68640 bytes intdoc/MPSformat | 382 + intdoc/SA2003_an1_dump.pl | 267 + intdoc/SA2003_annotations.txt | 419 + intdoc/SA2005_dump.pl | 156 + intdoc/an1_road_types.txt | 52 + intdoc/jeeps-device.odg | Bin 0 -> 9852 bytes internal_styles.c | 1112 + interpolate.c | 194 + jeeps/.cvsignore | 1 + jeeps/Makefile.in | 0 jeeps/README | 1 + jeeps/garminusb.h | 67 + jeeps/gps.h | 234 + jeeps/gpsapp.c | 6327 +++++ jeeps/gpsapp.h | 105 + jeeps/gpscom.c | 690 + jeeps/gpscom.h | 51 + jeeps/gpsdatum.h | 246 + jeeps/gpsdevice.c | 86 + jeeps/gpsdevice.h | 73 + jeeps/gpsdevice_ser.c | 37 + jeeps/gpsdevice_usb.c | 59 + jeeps/gpsfmt.c | 1562 ++ jeeps/gpsfmt.h | 27 + jeeps/gpsinput.c | 2262 ++ jeeps/gpsinput.h | 23 + jeeps/gpslibusb.c | 358 + jeeps/gpsmath.c | 2251 ++ jeeps/gpsmath.h | 145 + jeeps/gpsmem.c | 341 + jeeps/gpsmem.h | 29 + jeeps/gpsport.h | 15 + jeeps/gpsproj.c | 4485 ++++ jeeps/gpsproj.h | 157 + jeeps/gpsprot.c | 374 + jeeps/gpsprot.h | 377 + jeeps/gpsread.c | 220 + jeeps/gpsread.h | 20 + jeeps/gpsrqst.c | 176 + jeeps/gpsrqst.h | 20 + jeeps/gpssend.c | 213 + jeeps/gpssend.h | 25 + jeeps/gpsserial.c | 529 + jeeps/gpsserial.h | 36 + jeeps/gpsusbcommon.c | 268 + jeeps/gpsusbcommon.h | 45 + jeeps/gpsusbint.h | 27 + jeeps/gpsusbread.c | 78 + jeeps/gpsusbsend.c | 62 + jeeps/gpsusbstub.c | 36 + jeeps/gpsusbwin.c | 258 + jeeps/gpsutil.c | 699 + jeeps/gpsutil.h | 49 + jeeps/main.c | 31 + kml.c | 1256 + lmx.c | 246 + lowranceusr.c | 1042 + mac/dmg-contents/COPYING | 339 + mac/dmg-contents/Credits.rtf | 53 + mac/dmg-contents/GPSBabel+.app | Bin 0 -> 2342908 bytes mac/dmg-contents/README.rtf | 15 + mac/include/expat.h | 927 + mac/lib/libexpat.a | Bin 0 -> 538508 bytes macgpsbabel/Credits.rtf | 36 + macgpsbabel/English.lproj/InfoPlist.strings | Bin 0 -> 616 bytes .../English.lproj/MainMenu.nib/classes.nib | 4 + .../MainMenu.nib/data.dependency | 10 + .../English.lproj/MainMenu.nib/info.nib | 24 + .../English.lproj/MainMenu.nib/objects.nib | Bin 0 -> 27700 bytes macgpsbabel/Info.plist | 28 + macgpsbabel/MacGPSBabel.applescript | 1026 + .../MacGPSBabel.pbproj/default.pbxuser | 26 + .../MacGPSBabel.pbproj/jeremya.pbxuser | 1034 + .../MacGPSBabel.pbproj/project.pbxproj | 480 + .../MacGPSBabel.xcodeproj/project.pbxproj | 354 + macgpsbabel/README.macgpsbabel | 8 + macgpsbabel/main.m | 9 + macgpsbabel/mgb.icns | Bin 0 -> 33545 bytes macgpsbabel/preferences.applescript | 185 + mag_pdb.c | 233 + magellan.h | 54 + maggeo.c | 247 + magnav.c | 253 + magproto.c | 1555 ++ main.c | 698 + make-an1sym.pl | 361 + mapopolis.c | 298 + mapsend.c | 552 + mapsend.h | 44 + mapsource.c | 2020 ++ mingw/Makefile | 41 + mingw/README.expat | 1 + mingw/coldsync/.ignore | 0 mingw/include/expat.h | 1001 + mingw/includew/expat.h | 1013 + mingw/includew/expat_external.h | 115 + mingw/jeeps/.ignore | 0 mingw/lib/README | 2 + mingw/lib/libexpat.a | Bin 0 -> 48984 bytes mingw/lib/libexpat.def | 64 + mingw/libexpat.dll | Bin 0 -> 143360 bytes mingw/libw/README | 1 + mingw/libw/libexpat.a | Bin 0 -> 51328 bytes mingw/mkwintesto.c | 475 + mingw/shapelib/.ignore | 0 mingw/testo | 5 + mingw/wintesto.cmd | 1600 ++ mkicondoc.c | 67 + mkshort.c | 754 + mkstyle.sh | 26 + msroute.c | 683 + msvc/Debug.empty | 0 msvc/Expat/expat.h | 1001 + msvc/Expat/libexpat.dll | Bin 0 -> 143360 bytes msvc/Expat/libexpat.lib | Bin 0 -> 16816 bytes msvc/Expatw/expat.h | 1013 + msvc/Expatw/expat_external.h | 115 + msvc/Expatw/libexpatw.dll | Bin 0 -> 151552 bytes msvc/Expatw/libexpatw.lib | Bin 0 -> 17544 bytes msvc/GPSBabel-msvc7.sln | 21 + msvc/GPSBabel-msvc7.vcproj | 2556 ++ msvc/GPSBabel.dsp | 720 + msvc/GPSBabel.dsw | 29 + msvc/GPSBabel.sln | 22 + msvc/GPSBabel.vcproj | 3331 +++ msvc/README.msvc | 31 + msvc/Unicode.empty | 0 msvc/build.bat | 8 + msvc/config.h | 28 + msvc/mkwintesto.dsp | 100 + msvc/release.empty | 0 mtk_logger.c | 1149 + navicache.c | 278 + navilink.c | 970 + netstumbler.c | 323 + nmea.c | 1377 ++ nmn4.c | 322 + nukedata.c | 64 + osm.c | 926 + overlay.c | 704 + ozi.c | 858 + palmdoc.c | 599 + parse.c | 237 + pathaway.c | 712 + pcx.c | 454 + pdbfile.c | 431 + pdbfile.h | 84 + polygon.c | 364 + position.c | 203 + psitrex.c | 808 + psp.c | 412 + queue.c | 203 + queue.h | 58 + quovadis.c | 269 + quovadis.h | 122 + radius.c | 223 + random.c | 208 + raymarine.c | 509 + reference/GeocachingDB.PDB | Bin 0 -> 5822 bytes reference/Glad_4.exp | Bin 0 -> 19994 bytes reference/Glad_5.exp | 536 + reference/IMG_2065.JPG | Bin 0 -> 18399 bytes reference/UKultralight.pdb | Bin 0 -> 26248 bytes reference/alantrl.gpx | 2448 ++ reference/alantrl.trl | Bin 0 -> 266240 bytes reference/alanwpr.gpx | 381 + reference/alanwpr.wpr | Bin 0 -> 65536 bytes reference/all.usr | Bin 0 -> 2941 bytes reference/an1-an1.ref | Bin 0 -> 3556 bytes reference/an1-in.ref | 26 + reference/an1-line-out.ref | Bin 0 -> 1848 bytes reference/an1-out.ref | Bin 0 -> 326 bytes reference/arcdist_arc.txt | 115 + reference/arcdist_input.txt | 103 + reference/arcdist_output.txt | 11 + reference/cet/cet-sample.cp1250.txt | 17 + reference/cet/cet-sample.gdb | Bin 0 -> 1919 bytes reference/cet/cet-sample.gpx | 122 + reference/cet/cet-sample.latin1.txt | 17 + reference/cet/cet-sample.latin2.txt | 17 + reference/cet/cet-sample.macroman.txt | 17 + reference/cetus.gpu | 9 + reference/cetus.pdb | Bin 0 -> 1095 bytes reference/chicago.trk | Bin 0 -> 58030 bytes reference/coastexp.nob | 370 + reference/coastexp.ref | 221 + reference/coastexp.ref2 | 171 + reference/coastexp.ref3 | 221 + reference/coastexp.ref4 | 171 + reference/compegps-wpt.gpx | 178 + reference/compegps.wpt | 52 + reference/compegps.wpt.gz | Bin 0 -> 967 bytes reference/cototest.style | 33 + reference/cototestmarker.gpx | 22 + reference/cototestmarker.pdb | Bin 0 -> 550 bytes reference/cototesttrack.csv | 135 + reference/cototesttrack.pdb | Bin 0 -> 9800 bytes reference/destinator_poi.dat | Bin 0 -> 10492 bytes reference/destinator_poi.txt | 87 + reference/dnatest.txt | 16 + reference/dop-test.gpx | 17 + reference/dusky.gnuplot | 65 + reference/dusky.trk | 63 + reference/earth-expertgps.kml | 3441 +++ reference/earth-gc.kml | 159 + reference/easygps.loc | Bin 0 -> 1378 bytes reference/enchilada.usr | Bin 0 -> 2977 bytes reference/exif-dat.csv | 2 + reference/expertgps-g7t.txt | 216 + reference/expertgps.g7t | 1145 + reference/expertgps.gpx | 1131 + reference/expertgps.rwf | 2229 ++ reference/foo.an1 | Bin 0 -> 135252 bytes reference/fugawi.notime.txt | 19 + reference/fugawi.ref | 0 reference/fugawi.ref.txt | 19 + reference/fugawi.time.ref.txt | 16 + reference/fugawi.time.txt | 16 + reference/garmin_gpi.gpi | Bin 0 -> 7776 bytes reference/garmin_gpi.gpx | 526 + reference/garmin_gpi2.gpx | 526 + reference/garmin_symbols.gpx | 4620 ++++ reference/garmin_txt-uni.csv | 15 + reference/garmin_txt.txt | 96 + reference/gc/GC7FA4.gpx | 151 + reference/gc/GCGCA8.gpx | 103 + reference/gc/maggeo.gs | 3 + reference/gdb-sample-v3.gdb | Bin 0 -> 69073 bytes reference/gdb-sample.gdb | Bin 0 -> 66829 bytes reference/gdb-sample.gpx | 3176 +++ reference/gdb-sample2.gdb | Bin 0 -> 6314 bytes reference/geocaching.gpx | 73 + reference/geonet-sample.gpx | 55 + reference/geonet-sample.txt | 10 + reference/geoniche.pdb | Bin 0 -> 1422 bytes reference/gl.loc | 56 + reference/gn-targets.gpx | 34 + reference/gn-targets.pdb | Bin 0 -> 586 bytes reference/gnuplot.style | 26 + reference/google.arc | 111 + reference/google.csv | 111 + reference/google.js | 2 + reference/google.xml | 1 + reference/google_jan_06.csv | 111 + reference/google_jan_06.html | 2 + reference/googmap.sh | 5 + reference/googmapjs.sh | 5 + reference/gpi_ext-sample.csv | 10 + reference/gpi_ext-sample.gpi | Bin 0 -> 1507 bytes reference/gpilots.pdb | Bin 0 -> 2744 bytes reference/gpsdrive.txt | 9 + reference/gpspilot.pdb | Bin 0 -> 609 bytes reference/gpsutil-1.pcx | 23 + reference/gu.wpt | 9 + reference/hiketech.gpx | 734 + reference/hiketech.ref | 1530 ++ reference/holux.gpx | 46 + reference/holux.wpo | Bin 0 -> 25512 bytes reference/hsandv.exp | 80 + reference/human.in | 7 + reference/humanread.out | 6 + reference/humanread.style | 20 + reference/humanwrite.out | 6 + reference/humanwrite.style | 28 + reference/igc1.gpx | 549 + reference/igc1_3d.out | 123 + reference/igc1_baro.gpx | 2563 ++ reference/igc1_gpx.out | 384 + reference/igc1_igc.out | 123 + reference/igc2.igc | 46 + reference/igc2_gpx.out | 134 + reference/igc2_igc.out | 32 + reference/ignoreicons.usr | Bin 0 -> 2901 bytes reference/ik3d-sample.gpx | 139 + reference/ik3d-sample.ikt | 433 + reference/kartex-out.kwf | 13 + reference/kartex.txt | 16 + reference/lowrance.usr | Bin 0 -> 622 bytes reference/magfile | 18 + reference/magnav.pdb | Bin 0 -> 1160 bytes reference/magnavr.gpu | 9 + reference/mapsource.mps | Bin 0 -> 1202 bytes reference/mps-empty.mps | Bin 0 -> 52 bytes reference/multiple-links.gpx | 35 + reference/mxf.mxf | 9 + reference/navicache.ref | 2 + reference/navicache.xml | 91 + reference/navilink_tracks.gpx | 2084 ++ reference/navilink_tracks.trk | Bin 0 -> 11040 bytes reference/navilink_tracks_gpx.trk | Bin 0 -> 11040 bytes reference/navilink_waypoints.gpx | 74 + reference/navilink_waypoints.wpt | Bin 0 -> 256 bytes reference/navilink_waypoints_gpx.wpt | Bin 0 -> 256 bytes reference/netstumbler.mps | Bin 0 -> 4838 bytes reference/netstumbler.txt | 42 + reference/nokia.lmx | 112 + reference/osm-data.gpx | 400 + reference/osm-data.xml | 139 + reference/ov2-arc-out.ref | Bin 0 -> 2535 bytes reference/ov2-geo-out.ref | Bin 0 -> 416 bytes reference/ov2-in.ref | 9 + reference/ozi.wpt | 13 + reference/paris.wpo | Bin 0 -> 25600 bytes reference/pathaway-geo.loc | 38 + reference/polygon_allencty.txt | 177 + reference/polygon_output.txt | 37 + reference/ps.psp | Bin 0 -> 964 bytes reference/psitwpts.txt | 17 + reference/quovadis.gpu | 9 + reference/quovadis.pdb | Bin 0 -> 601 bytes reference/radius.csv | 1 + reference/raymarine-sample.gpx | 83 + reference/raymarine-sample.rwf | 164 + reference/route/bcr-sample.bcr | 36 + reference/route/bcr-sample.gpx | 121 + reference/route/bcr-sample2.bcr | 35 + reference/route/compegps-rte.gpx | 48 + reference/route/compegps.rte | 20 + reference/route/cst-sample.cst | 351 + reference/route/cst-sample.cst.gz | Bin 0 -> 4470 bytes reference/route/cst-sample.gpx | 1312 + reference/route/destinator_itn.dat | Bin 0 -> 5752 bytes reference/route/destinator_itn.txt | 47 + reference/route/mag_pdb-sample.gpx | 1034 + reference/route/mag_pdb-sample.pdb | Bin 0 -> 16183 bytes reference/route/magellan.rte | 22 + reference/route/magexplorist.rte | 6 + reference/route/msroute-sample.axe | Bin 0 -> 9216 bytes reference/route/msroute-sample.gpx | 90 + reference/route/nmn4-sample-out.rte | 10 + reference/route/nmn4-sample.gpx | 62 + reference/route/nmn4-sample.rte | 10 + reference/route/psitrtes.txt | 8 + reference/route/route.gpx | 77 + reference/route/route.mapsend | Bin 0 -> 922 bytes reference/route/route.mps | Bin 0 -> 3182 bytes reference/route/stmsdf-route.sdf | 18 + reference/route/stmwpp-route.gpx | 64 + reference/route/stmwpp-route.txt | 10 + reference/route/tef_xml.sample.gpx | 1344 ++ reference/route/tef_xml.sample.xml | 2 + reference/route/tomtom_itn.itn | 46 + reference/route/vieac.README | 14 + reference/route/vieac.rte | 173 + reference/sample.gtm | Bin 0 -> 90544 bytes reference/sample.gtm.gz | Bin 0 -> 56931 bytes reference/simplify_output.txt | 13 + reference/stmsdf.txt | 83 + reference/tomtom_poi.asc | 90 + reference/topomapexample.txt | 8 + reference/topomappro.txt | 10 + reference/tpg.tpg | Bin 0 -> 577 bytes reference/tpo-sample.tpo | Bin 0 -> 9293 bytes reference/tpo-sample3.gpx | 500 + reference/tpo-sample3.tpo | Bin 0 -> 7442 bytes reference/track/TrkDB-GPil.pdb | Bin 0 -> 9544 bytes reference/track/axim-sample.gpb | Bin 0 -> 4128 bytes reference/track/axim-sample.gpx | 62 + reference/track/chi-mapsend.trk | Bin 0 -> 58030 bytes reference/track/compegps-trk.gpx | 183 + reference/track/compegps.trk | 53 + reference/track/destinator_trl.dat | Bin 0 -> 3952 bytes reference/track/destinator_trl.txt | 27 + reference/track/dmtlog-sample.gpx | 722 + reference/track/fugawi.txt | 74 + reference/track/garmin_logbook.xml | 2047 ++ reference/track/ggv_log-sample.log | Bin 0 -> 31397 bytes reference/track/i65.anr | Bin 0 -> 14732 bytes reference/track/i65.anr.gpx | 4971 ++++ reference/track/ignrando-sample.gpx | 45 + reference/track/ignrando-sample.rdn | 76 + reference/track/interptrack.gpx | 154 + reference/track/kartex-out.ktf | 179 + reference/track/kartex.txt | 182 + reference/track/kompass.tk | 64 + reference/track/mapsend.trk | Bin 0 -> 1884 bytes reference/track/meridian.trk | 64 + reference/track/mps-track.mps | Bin 0 -> 2056 bytes reference/track/mtk_logger.bin | Bin 0 -> 65536 bytes reference/track/mtk_logger.csv | 818 + reference/track/mtk_logger.gpx | 7391 ++++++ reference/track/nmea | 894 + reference/track/nmea+ms.gpx | 290 + reference/track/nmea+ms.txt | 125 + reference/track/nmea.gpx | 1708 ++ reference/track/pathaway.gpx | 1999 ++ reference/track/pathaway.pdb | Bin 0 -> 44188 bytes reference/track/pcx.trk | 76 + reference/track/psittrks.txt | 1142 + reference/track/simpletrack.gpx | 21 + reference/track/sportsim-sample.txt | 66 + reference/track/stmsdf-track.sdf | 99 + reference/track/stmwpp-route.gpx | 64 + reference/track/stmwpp-track.gpx | 173 + reference/track/stmwpp-track.txt | 54 + reference/track/tef_xml.sample.xml | 2 + reference/track/tinterptrack.gpx | 58 + reference/track/tpo-sample1.gpx | 4839 ++++ reference/track/tpo-sample1.tpo | Bin 0 -> 9293 bytes reference/track/tpo-sample2.gpx | 3827 +++ reference/track/tpo-sample2.tpo | Bin 0 -> 5933 bytes reference/track/trackDMm.ktf | 179 + reference/track/trackDd.ktf | 179 + reference/track/trackfilter-new.gpx | 280 + reference/track/trackfilter-sdistance.gpx | 366 + reference/track/trackfilter-sdistance2.gpx | 281 + reference/track/trackfilter.gpx | 281 + reference/track/tracks.gpssim | 128 + reference/track/tracks.gpx | 271 + reference/track/vidaone.csv | 65 + reference/track/vidaone.gpb | Bin 0 -> 1280 bytes reference/track/vitosmt_t.gpx | 2204 ++ reference/track/vitovtt-sample.gpx | 7478 ++++++ reference/track/vitovtt-sample.vtt | Bin 0 -> 59720 bytes reference/track/webpark1.gpl | Bin 0 -> 54656 bytes reference/transform-rte.gpx | 785 + reference/transform-wpt.gpx | 380 + reference/unicsv.gpx | 55 + reference/vitosmt.gpx | 2200 ++ reference/vitosmt.smt | Bin 0 -> 15192 bytes reference/waypoints.gpssim | 9 + reference/waypointsDMm.kwf | 13 + reference/waypointsDd.kwf | 13 + reference/wbt-200.bin | Bin 0 -> 3120 bytes reference/wbt-200.gpx | 793 + reference/wbt-201.gpx | 16151 +++++++++++++ reference/wbt-201.tk1 | Bin 0 -> 65512 bytes reference/wfff.gpu | 1 + reference/wfff.xml | 17 + reference/xmap | 4 + reference/xmapwpt.wpt | 9 + reference/xol-sample-gpx.xol | 182 + reference/xol-sample.gpx | 167 + reference/xol-sample.xol | 182 + reverse_route.c | 70 + rgbcolors.c | 248 + route.c | 607 + saroute.c | 451 + shape.c | 319 + shapelib/.cvsignore | 1 + shapelib/Makefile.in | 0 shapelib/README.GPSBabel | 4 + shapelib/dbf_api.html | 408 + shapelib/dbfopen.c | 1509 ++ shapelib/shapefil.h | 490 + shapelib/shapelib.html | 334 + shapelib/shp_api.html | 376 + shapelib/shpopen.c | 1886 ++ smplrout.c | 352 + sort.c | 92 + stackfilter.c | 250 + stmsdf.c | 740 + stmwpp.c | 328 + strptime.c | 1022 + strptime.h | 33 + style/arc.style | 24 + style/cambridge.style | 18 + style/csv.style | 27 + style/cup.style | 46 + style/custom.style | 52 + style/dna.style | 28 + style/fugawi.style | 41 + style/garmin301.style | 34 + style/garmin_poi.style | 34 + style/geonet.style | 49 + style/gpsdrive.style | 32 + style/gpsdrivetrack.style | 30 + style/gpsman.style | 34 + style/kompass_tk.style | 18 + style/kompass_wp.style | 26 + style/ktf2.style | 36 + style/kwf2.style | 38 + style/mapconverter.style | 35 + style/mxf.style | 39 + style/nima.style | 45 + style/openoffice.style | 47 + style/s_and_t.style | 41 + style/saplus.style | 28 + style/sportsim.style | 33 + style/tabsep.style | 57 + style/tomtom_asc.style | 27 + style/tomtom_itn.style | 23 + style/xmap.style | 32 + style/xmap2006.style | 37 + style/xmapwpt.style | 30 + tef_xml.c | 318 + test-all | 213 + testc | 57 + testo | 1335 ++ testw | 166 + text.c | 278 + tiger.c | 288 + tmpro.c | 259 + tomtom.c | 345 + tools/.cvsignore | 1 + tools/cleardebug | 5 + tools/cvslog | 1 + tools/functions | 41 + tools/gcfg | 17 + tools/mac-config | 12 + tools/memdebug | 74 + tools/mkcapabilities.in | 42 + tools/mkchangelog | 62 + tools/mkchanges | 16 + tools/mkdmg | 40 + tools/mkfilelist | 51 + tools/mkmoreclean | 15 + tools/mkrpm | 52 + tools/mkspec | 56 + tools/release-process | 10 + torture_test | 27 + tpg.c | 328 + tpo.README.patch | 51 + tpo.c | 1859 ++ tpo.testo.patch | 27 + trackfilter.c | 999 + transform.c | 199 + unicsv.c | 1444 ++ units.c | 94 + util.c | 1732 ++ util_crc.c | 96 + uuid.c | 37 + uuid.h | 22 + vcf.c | 143 + vecs.c | 1343 ++ vidaone.c | 134 + vitosmt.c | 383 + vitovtt.c | 139 + vmem.c | 67 + vtesto | 9 + waypt.c | 585 + wbt-200.c | 1022 + wfff_xml.c | 295 + win32/.cvsignore | 1 + win32/GPSBabelGUI.exe | Bin 0 -> 1057288 bytes win32/gpsbabel.ico | Bin 0 -> 766 bytes win32/gpsbabel.rc.in | 27 + win32/gui-2/.cvsignore | 2 + win32/gui-2/GPSBabelGUI.cfg | 35 + win32/gui-2/GPSBabelGUI.dof | 84 + win32/gui-2/GPSBabelGUI.dpr | 53 + win32/gui-2/GPSBabelGUI.ico | Bin 0 -> 766 bytes win32/gui-2/GPSBabelGUI.res | Bin 0 -> 1752 bytes win32/gui-2/Makefile | 64 + win32/gui-2/README.gui | 70 + win32/gui-2/about.dfm | Bin 0 -> 3505 bytes win32/gui-2/about.pas | 137 + win32/gui-2/common.pas | 583 + win32/gui-2/default.po | 941 + win32/gui-2/delphi.pas | 93 + win32/gui-2/dof2rc.dpr | 108 + win32/gui-2/filter.dfm | Bin 0 -> 8971 bytes win32/gui-2/filter.pas | 760 + win32/gui-2/gnugettext.pas | 2842 +++ win32/gui-2/gnugettextD4.pas | 290 + win32/gui-2/gnugettextD5.pas | 265 + win32/gui-2/gnugettextDx.pas | 72 + win32/gui-2/gpsbabel.iss | 116 + win32/gui-2/gpsbabel.po | 486 + win32/gui-2/ignore.po | 311 + win32/gui-2/locale/de/LC_MESSAGES/default.po | 924 + win32/gui-2/locale/de/LC_MESSAGES/delphi.po | 10164 ++++++++ win32/gui-2/locale/de/LC_MESSAGES/gpsbabel.po | 498 + win32/gui-2/locale/es/LC_MESSAGES/default.po | 925 + win32/gui-2/locale/es/LC_MESSAGES/delphi.po | 12734 ++++++++++ win32/gui-2/locale/es/LC_MESSAGES/gpsbabel.po | 495 + win32/gui-2/locale/fr/LC_MESSAGES/default.po | 926 + win32/gui-2/locale/fr/LC_MESSAGES/delphi.po | 6177 +++++ win32/gui-2/locale/fr/LC_MESSAGES/gpsbabel.po | 497 + win32/gui-2/locale/hu/LC_MESSAGES/default.po | 930 + win32/gui-2/locale/hu/LC_MESSAGES/delphi.po | 2258 ++ win32/gui-2/locale/hu/LC_MESSAGES/gpsbabel.po | 496 + win32/gui-2/main.dfm | Bin 0 -> 38547 bytes win32/gui-2/main.pas | 1450 ++ win32/gui-2/options.dfm | Bin 0 -> 1332 bytes win32/gui-2/options.pas | 862 + win32/gui-2/readme.dfm | Bin 0 -> 687 bytes win32/gui-2/readme.pas | 74 + win32/gui-2/select.dfm | Bin 0 -> 1450 bytes win32/gui-2/select.pas | 165 + win32/gui-2/utils.pas | 525 + win32/gui/AboutDialogU.ddp | Bin 0 -> 51 bytes win32/gui/AboutDialogU.dfm | 1151 + win32/gui/AboutDialogU.pas | 67 + win32/gui/GPSBabelGUI.cfg | 38 + win32/gui/GPSBabelGUI.dof | 137 + win32/gui/GPSBabelGUI.dpr | 17 + win32/gui/GPSBabelGUI.ico | Bin 0 -> 766 bytes win32/gui/GPSBabelGUI.res | Bin 0 -> 1780 bytes win32/gui/GPSBabelGUI.todo | 28 + win32/gui/GPSBabelGUIDialogU.ddp | Bin 0 -> 51 bytes win32/gui/GPSBabelGUIDialogU.dfm | 218 + win32/gui/GPSBabelGUIDialogU.pas | 480 + win32/gui/README.txt | 4 + win32/gui/VersionInfo.pas | 99 + win32/gui/filelist.txt | 17 + xcsv.c | 664 + xcsv_tokens.gperf | 289 + xcsv_tokens.in | 71 + xhtmlent.c | 515 + xmldoc/.cvsignore | 1 + xmldoc/autogen/.cvsignore | 1 + xmldoc/babelmain.xsl | 35 + xmldoc/babelpdf.xsl | 82 + xmldoc/chapters/_chapters.xml | 11 + xmldoc/chapters/allchapters.xml | 9 + xmldoc/chapters/build.xml | 64 + xmldoc/chapters/datums.xml | 138 + xmldoc/chapters/filters.xml | 23 + xmldoc/chapters/formats.xml | 4 + xmldoc/chapters/garmin_icons.xml | 314 + xmldoc/chapters/glossary.xml | 75 + xmldoc/chapters/preface.xml | 36 + xmldoc/chapters/styles.xml | 1290 + xmldoc/chapters/use.xml | 333 + xmldoc/filters/arc.xml | 42 + xmldoc/filters/discard.xml | 26 + xmldoc/filters/duplicate.xml | 20 + xmldoc/filters/interpolate.xml | 30 + xmldoc/filters/nuketypes.xml | 16 + xmldoc/filters/options/arc-distance.xml | 14 + xmldoc/filters/options/arc-exclude.xml | 6 + xmldoc/filters/options/arc-file.xml | 13 + xmldoc/filters/options/arc-points.xml | 11 + xmldoc/filters/options/discard-hdop.xml | 7 + .../filters/options/discard-hdopandvdop.xml | 6 + xmldoc/filters/options/discard-sat.xml | 4 + xmldoc/filters/options/discard-vdop.xml | 7 + xmldoc/filters/options/duplicate-all.xml | 17 + xmldoc/filters/options/duplicate-correct.xml | 21 + xmldoc/filters/options/duplicate-location.xml | 9 + .../filters/options/duplicate-shortname.xml | 9 + .../filters/options/interpolate-distance.xml | 13 + xmldoc/filters/options/interpolate-route.xml | 5 + xmldoc/filters/options/interpolate-time.xml | 12 + xmldoc/filters/options/nuketypes-routes.xml | 4 + xmldoc/filters/options/nuketypes-tracks.xml | 4 + .../filters/options/nuketypes-waypoints.xml | 5 + xmldoc/filters/options/polygon-exclude.xml | 6 + xmldoc/filters/options/polygon-file.xml | 16 + xmldoc/filters/options/position-all.xml | 8 + xmldoc/filters/options/position-distance.xml | 9 + xmldoc/filters/options/radius-asroute.xml | 13 + xmldoc/filters/options/radius-distance.xml | 13 + xmldoc/filters/options/radius-exclude.xml | 5 + xmldoc/filters/options/radius-lat.xml | 8 + xmldoc/filters/options/radius-lon.xml | 8 + xmldoc/filters/options/radius-maxcount.xml | 22 + xmldoc/filters/options/radius-nosort.xml | 6 + xmldoc/filters/options/simplify-count.xml | 8 + .../filters/options/simplify-crosstrack.xml | 11 + xmldoc/filters/options/simplify-error.xml | 13 + xmldoc/filters/options/simplify-length.xml | 4 + xmldoc/filters/options/sort-description.xml | 8 + xmldoc/filters/options/sort-gcid.xml | 8 + xmldoc/filters/options/sort-shortname.xml | 8 + xmldoc/filters/options/sort-time.xml | 8 + xmldoc/filters/options/stack-append.xml | 5 + xmldoc/filters/options/stack-copy.xml | 6 + xmldoc/filters/options/stack-depth.xml | 6 + xmldoc/filters/options/stack-discard.xml | 5 + xmldoc/filters/options/stack-pop.xml | 9 + xmldoc/filters/options/stack-push.xml | 8 + xmldoc/filters/options/stack-replace.xml | 8 + xmldoc/filters/options/stack-swap.xml | 10 + xmldoc/filters/options/track-course.xml | 10 + xmldoc/filters/options/track-fix.xml | 9 + xmldoc/filters/options/track-merge.xml | 14 + xmldoc/filters/options/track-move.xml | 13 + xmldoc/filters/options/track-name.xml | 7 + xmldoc/filters/options/track-pack.xml | 12 + xmldoc/filters/options/track-sdistance.xml | 36 + xmldoc/filters/options/track-speed.xml | 9 + xmldoc/filters/options/track-split.xml | 28 + xmldoc/filters/options/track-start.xml | 24 + xmldoc/filters/options/track-stop.xml | 15 + xmldoc/filters/options/track-title.xml | 10 + xmldoc/filters/options/transform-del.xml | 9 + xmldoc/filters/options/transform-rte.xml | 11 + xmldoc/filters/options/transform-trk.xml | 13 + xmldoc/filters/options/transform-wpt.xml | 11 + xmldoc/filters/polygon.xml | 78 + xmldoc/filters/position.xml | 15 + xmldoc/filters/radius.xml | 17 + xmldoc/filters/reverse.xml | 19 + xmldoc/filters/simplify.xml | 21 + xmldoc/filters/sort.xml | 5 + xmldoc/filters/stack.xml | 49 + xmldoc/filters/track.xml | 8 + xmldoc/filters/transform.xml | 18 + xmldoc/formats/alantrl.xml | 29 + xmldoc/formats/alanwpr.xml | 30 + xmldoc/formats/an1.xml | 15 + xmldoc/formats/arc.xml | 14 + xmldoc/formats/axim_gpb.xml | 10 + xmldoc/formats/baroiq.xml | 5 + xmldoc/formats/bcr.xml | 21 + xmldoc/formats/cambridge.xml | 8 + xmldoc/formats/cetus.xml | 7 + xmldoc/formats/coastexp.xml | 8 + xmldoc/formats/compegps.xml | 14 + xmldoc/formats/copilot.xml | 17 + xmldoc/formats/coto.xml | 20 + xmldoc/formats/cst.xml | 9 + xmldoc/formats/csv.xml | 27 + xmldoc/formats/cup.xml | 14 + xmldoc/formats/custom.xml | 9 + xmldoc/formats/destinator_itn.xml | 18 + xmldoc/formats/destinator_poi.xml | 19 + xmldoc/formats/destinator_trl.xml | 18 + xmldoc/formats/dg-100.xml | 19 + xmldoc/formats/dmtlog.xml | 10 + xmldoc/formats/dna.xml | 8 + xmldoc/formats/easygps.xml | 12 + xmldoc/formats/exif.xml | 12 + xmldoc/formats/fugawi.xml | 27 + xmldoc/formats/g7towin.xml | 9 + xmldoc/formats/garmin.xml | 265 + xmldoc/formats/garmin301.xml | 13 + xmldoc/formats/garmin_gpi.xml | 37 + xmldoc/formats/garmin_poi.xml | 9 + xmldoc/formats/garmin_txt.xml | 23 + xmldoc/formats/gcdb.xml | 7 + xmldoc/formats/gdb.xml | 12 + xmldoc/formats/geo.xml | 11 + xmldoc/formats/geonet.xml | 8 + xmldoc/formats/geoniche.xml | 7 + xmldoc/formats/ggv_log.xml | 12 + xmldoc/formats/glogbook.xml | 11 + xmldoc/formats/google.xml | 36 + xmldoc/formats/gpilots.xml | 10 + xmldoc/formats/gpl.xml | 8 + xmldoc/formats/gpsdrive.xml | 7 + xmldoc/formats/gpsdrivetrack.xml | 7 + xmldoc/formats/gpsman.xml | 13 + xmldoc/formats/gpspilot.xml | 10 + xmldoc/formats/gpssim.xml | 9 + xmldoc/formats/gpsutil.xml | 12 + xmldoc/formats/gpx.xml | 14 + xmldoc/formats/gtm.xml | 5 + xmldoc/formats/gtrnctr.xml | 16 + xmldoc/formats/hiketech.xml | 8 + xmldoc/formats/holux.xml | 28 + xmldoc/formats/hsandv.xml | 8 + xmldoc/formats/html.xml | 16 + xmldoc/formats/igc.xml | 134 + xmldoc/formats/ignrando.xml | 6 + xmldoc/formats/ik3d.xml | 11 + xmldoc/formats/kml.xml | 33 + xmldoc/formats/kompass_tk.xml | 8 + xmldoc/formats/kompass_wp.xml | 7 + xmldoc/formats/ktf2.xml | 3 + xmldoc/formats/kwf2.xml | 9 + xmldoc/formats/lmx.xml | 6 + xmldoc/formats/lowranceusr.xml | 9 + xmldoc/formats/mag_pdb.xml | 10 + xmldoc/formats/magellan.xml | 38 + xmldoc/formats/magellan1.xml | 96 + xmldoc/formats/magellanx.xml | 14 + xmldoc/formats/maggeo.xml | 12 + xmldoc/formats/magnav.xml | 44 + xmldoc/formats/mapconverter.xml | 61 + xmldoc/formats/mapsend.xml | 8 + xmldoc/formats/mapsource.xml | 28 + xmldoc/formats/msroute.xml | 22 + xmldoc/formats/msroute1.xml | 22 + xmldoc/formats/mtk-bin.xml | 26 + xmldoc/formats/mtk.xml | 21 + xmldoc/formats/mxf.xml | 8 + xmldoc/formats/navicache.xml | 9 + xmldoc/formats/navilink.xml | 32 + xmldoc/formats/netstumbler.xml | 21 + xmldoc/formats/nima.xml | 6 + xmldoc/formats/nmea.xml | 53 + xmldoc/formats/nmn4.xml | 10 + xmldoc/formats/openoffice.xml | 11 + xmldoc/formats/options/an1-color.xml | 4 + xmldoc/formats/options/an1-deficon.xml | 7 + xmldoc/formats/options/an1-nogc.xml | 8 + xmldoc/formats/options/an1-nourl.xml | 12 + xmldoc/formats/options/an1-radius.xml | 5 + xmldoc/formats/options/an1-road.xml | 79 + xmldoc/formats/options/an1-type.xml | 7 + xmldoc/formats/options/an1-wpt_type.xml | 13 + xmldoc/formats/options/an1-zoom.xml | 7 + xmldoc/formats/options/bcr-index.xml | 9 + xmldoc/formats/options/bcr-name.xml | 5 + .../formats/options/bcr-prefer_shortnames.xml | 4 + xmldoc/formats/options/bcr-radius.xml | 9 + xmldoc/formats/options/cetus-appendicon.xml | 7 + xmldoc/formats/options/cetus-dbname.xml | 6 + xmldoc/formats/options/compegps-deficon.xml | 3 + xmldoc/formats/options/compegps-index.xml | 8 + xmldoc/formats/options/compegps-radius.xml | 3 + xmldoc/formats/options/compegps-snlen.xml | 4 + xmldoc/formats/options/coto-zerocat.xml | 4 + xmldoc/formats/options/dg-100-erase.xml | 1 + xmldoc/formats/options/dmtlog-index.xml | 16 + xmldoc/formats/options/exif-filename.xml | 10 + .../formats/options/garmin-bitscategory.xml | 19 + xmldoc/formats/options/garmin-category.xml | 3 + xmldoc/formats/options/garmin-deficon.xml | 17 + xmldoc/formats/options/garmin-get_posn.xml | 5 + xmldoc/formats/options/garmin-power_off.xml | 8 + xmldoc/formats/options/garmin-resettime.xml | 10 + xmldoc/formats/options/garmin-snlen.xml | 7 + xmldoc/formats/options/garmin-snwhite.xml | 2 + xmldoc/formats/options/garmin_gpi-alerts.xml | 15 + xmldoc/formats/options/garmin_gpi-bitmap.xml | 13 + .../formats/options/garmin_gpi-category.xml | 9 + xmldoc/formats/options/garmin_gpi-descr.xml | 10 + xmldoc/formats/options/garmin_gpi-hide.xml | 10 + xmldoc/formats/options/garmin_gpi-notes.xml | 11 + .../formats/options/garmin_gpi-position.xml | 9 + .../formats/options/garmin_gpi-proximity.xml | 64 + xmldoc/formats/options/garmin_gpi-sleep.xml | 16 + xmldoc/formats/options/garmin_gpi-speed.xml | 66 + xmldoc/formats/options/garmin_gpi-unique.xml | 9 + xmldoc/formats/options/garmin_gpi-units.xml | 7 + xmldoc/formats/options/garmin_txt-date.xml | 4 + xmldoc/formats/options/garmin_txt-datum.xml | 4 + xmldoc/formats/options/garmin_txt-dist.xml | 5 + xmldoc/formats/options/garmin_txt-grid.xml | 62 + xmldoc/formats/options/garmin_txt-prec.xml | 5 + xmldoc/formats/options/garmin_txt-temp.xml | 4 + xmldoc/formats/options/garmin_txt-time.xml | 4 + xmldoc/formats/options/garmin_txt-utc.xml | 5 + xmldoc/formats/options/gdb-bitscategory.xml | 19 + xmldoc/formats/options/gdb-cat.xml | 4 + xmldoc/formats/options/gdb-roadbook.xml | 19 + xmldoc/formats/options/gdb-ver.xml | 5 + xmldoc/formats/options/gdb-via.xml | 5 + xmldoc/formats/options/geo-deficon.xml | 17 + xmldoc/formats/options/geo-nuke_placer.xml | 9 + xmldoc/formats/options/geoniche-category.xml | 6 + xmldoc/formats/options/geoniche-dbname.xml | 6 + xmldoc/formats/options/gpilots-dbname.xml | 6 + xmldoc/formats/options/gpspilot-dbname.xml | 6 + xmldoc/formats/options/gpssim-split.xml | 17 + xmldoc/formats/options/gpssim-wayptspd.xml | 3 + xmldoc/formats/options/gpx-gpxver.xml | 11 + xmldoc/formats/options/gpx-logpoint.xml | 6 + xmldoc/formats/options/gpx-snlen.xml | 3 + xmldoc/formats/options/gpx-suppresswhite.xml | 3 + xmldoc/formats/options/gpx-urlbase.xml | 4 + xmldoc/formats/options/html-altunits.xml | 4 + xmldoc/formats/options/html-degformat.xml | 5 + xmldoc/formats/options/html-encrypt.xml | 3 + xmldoc/formats/options/html-logs.xml | 3 + xmldoc/formats/options/html-stylesheet.xml | 4 + xmldoc/formats/options/igc-timeadj.xml | 16 + xmldoc/formats/options/ignrando-index.xml | 9 + xmldoc/formats/options/kml-deficon.xml | 3 + xmldoc/formats/options/kml-extrude.xml | 7 + xmldoc/formats/options/kml-floating.xml | 9 + xmldoc/formats/options/kml-labels.xml | 4 + xmldoc/formats/options/kml-line_color.xml | 5 + xmldoc/formats/options/kml-line_width.xml | 4 + xmldoc/formats/options/kml-lines.xml | 6 + .../options/kml-max_position_points.xml | 4 + xmldoc/formats/options/kml-points.xml | 6 + xmldoc/formats/options/kml-trackdata.xml | 8 + xmldoc/formats/options/kml-trackdirection.xml | 4 + xmldoc/formats/options/kml-units.xml | 5 + xmldoc/formats/options/lowranceusr-break.xml | 4 + .../options/lowranceusr-ignoreicons.xml | 4 + xmldoc/formats/options/lowranceusr-merge.xml | 3 + .../options/lowranceusr-writeasicons.xml | 3 + xmldoc/formats/options/magellan-deficon.xml | 3 + xmldoc/formats/options/magellan-maxcmts.xml | 13 + xmldoc/formats/options/magellan1-baud.xml | 8 + xmldoc/formats/options/magellan1-deficon.xml | 15 + xmldoc/formats/options/magellan1-maxcmts.xml | 13 + xmldoc/formats/options/magellan1-noack.xml | 17 + xmldoc/formats/options/magellan1-nukewpt.xml | 10 + xmldoc/formats/options/magellanx-deficon.xml | 3 + xmldoc/formats/options/magellanx-maxcmts.xml | 13 + xmldoc/formats/options/mapsend-trkver.xml | 6 + .../formats/options/mapsource-mpsmergeout.xml | 5 + .../formats/options/mapsource-mpsusedepth.xml | 5 + .../formats/options/mapsource-mpsuseprox.xml | 5 + .../formats/options/mapsource-mpsverout.xml | 5 + xmldoc/formats/options/mapsource-snlen.xml | 4 + xmldoc/formats/options/mapsource-snwhite.xml | 4 + xmldoc/formats/options/mtk-bin-csv.xml | 8 + xmldoc/formats/options/mtk-csv.xml | 2 + xmldoc/formats/options/mtk-erase.xml | 1 + .../formats/options/navicache-noretired.xml | 3 + xmldoc/formats/options/navilink-nukerte.xml | 10 + xmldoc/formats/options/navilink-nuketrk.xml | 10 + xmldoc/formats/options/navilink-nukewpt.xml | 10 + xmldoc/formats/options/navilink-power_off.xml | 4 + .../formats/options/netstumbler-nseicon.xml | 4 + .../formats/options/netstumbler-nsneicon.xml | 4 + xmldoc/formats/options/netstumbler-seicon.xml | 4 + .../formats/options/netstumbler-sneicon.xml | 4 + xmldoc/formats/options/netstumbler-snmac.xml | 4 + .../options/nmea-append_positioning.xml | 5 + xmldoc/formats/options/nmea-baud.xml | 4 + xmldoc/formats/options/nmea-date.xml | 10 + xmldoc/formats/options/nmea-get_posn.xml | 3 + xmldoc/formats/options/nmea-gisteq.xml | 17 + xmldoc/formats/options/nmea-gpgga.xml | 8 + xmldoc/formats/options/nmea-gpgsa.xml | 12 + xmldoc/formats/options/nmea-gprmc.xml | 11 + xmldoc/formats/options/nmea-gpvtg.xml | 11 + xmldoc/formats/options/nmea-pause.xml | 31 + xmldoc/formats/options/nmea-snlen.xml | 6 + xmldoc/formats/options/nmn4-index.xml | 9 + xmldoc/formats/options/osm-tag.xml | 6 + xmldoc/formats/options/osm-tagnd.xml | 6 + xmldoc/formats/options/ozi-pack.xml | 10 + xmldoc/formats/options/ozi-proximity.xml | 4 + xmldoc/formats/options/ozi-snlen.xml | 3 + xmldoc/formats/options/ozi-snunique.xml | 3 + xmldoc/formats/options/ozi-snupper.xml | 3 + xmldoc/formats/options/ozi-snwhite.xml | 3 + xmldoc/formats/options/ozi-wptbgcolor.xml | 3 + xmldoc/formats/options/ozi-wptfgcolor.xml | 3 + .../options/palmdoc-bookmarks_short.xml | 9 + xmldoc/formats/options/palmdoc-dbname.xml | 5 + xmldoc/formats/options/palmdoc-encrypt.xml | 3 + xmldoc/formats/options/palmdoc-logs.xml | 3 + xmldoc/formats/options/palmdoc-nosep.xml | 3 + xmldoc/formats/options/pathaway-date.xml | 4 + xmldoc/formats/options/pathaway-dbname.xml | 6 + xmldoc/formats/options/pathaway-deficon.xml | 3 + xmldoc/formats/options/pathaway-snlen.xml | 3 + xmldoc/formats/options/pcx-cartoexploreur.xml | 4 + xmldoc/formats/options/pcx-deficon.xml | 3 + xmldoc/formats/options/quovadis-dbname.xml | 6 + xmldoc/formats/options/raymarine-location.xml | 7 + xmldoc/formats/options/saroute-controls.xml | 10 + xmldoc/formats/options/saroute-split.xml | 5 + xmldoc/formats/options/saroute-times.xml | 5 + .../options/saroute-turns_important.xml | 6 + xmldoc/formats/options/saroute-turns_only.xml | 4 + xmldoc/formats/options/stmsdf-index.xml | 15 + xmldoc/formats/options/stmwpp-index.xml | 9 + xmldoc/formats/options/tef-routevia.xml | 3 + xmldoc/formats/options/text-altunits.xml | 4 + xmldoc/formats/options/text-degformat.xml | 5 + xmldoc/formats/options/text-encrypt.xml | 3 + xmldoc/formats/options/text-logs.xml | 3 + xmldoc/formats/options/text-nosep.xml | 3 + xmldoc/formats/options/text-splitoutput.xml | 15 + xmldoc/formats/options/tiger-genurl.xml | 20 + xmldoc/formats/options/tiger-iconismarker.xml | 4 + xmldoc/formats/options/tiger-margin.xml | 7 + xmldoc/formats/options/tiger-newmarker.xml | 3 + xmldoc/formats/options/tiger-nolabels.xml | 3 + xmldoc/formats/options/tiger-oldmarker.xml | 3 + xmldoc/formats/options/tiger-oldthresh.xml | 5 + xmldoc/formats/options/tiger-snlen.xml | 5 + .../formats/options/tiger-suppresswhite.xml | 4 + .../formats/options/tiger-unfoundmarker.xml | 1 + xmldoc/formats/options/tiger-xpixels.xml | 3 + xmldoc/formats/options/tiger-ypixels.xml | 4 + xmldoc/formats/options/tpg-datum.xml | 6 + xmldoc/formats/options/unicsv-datum.xml | 4 + xmldoc/formats/options/unicsv-grid.xml | 8 + xmldoc/formats/options/unicsv-utc.xml | 5 + xmldoc/formats/options/vcard-encrypt.xml | 4 + xmldoc/formats/options/wbt-erase.xml | 1 + xmldoc/formats/options/wfff-ahcicon.xml | 3 + xmldoc/formats/options/wfff-ahoicon.xml | 4 + xmldoc/formats/options/wfff-aicicon.xml | 3 + xmldoc/formats/options/wfff-aioicon.xml | 4 + xmldoc/formats/options/wfff-snmac.xml | 3 + xmldoc/formats/options/xcsv-datum.xml | 4 + .../options/xcsv-prefer_shortnames.xml | 7 + xmldoc/formats/options/xcsv-snlen.xml | 8 + xmldoc/formats/options/xcsv-snunique.xml | 8 + xmldoc/formats/options/xcsv-snupper.xml | 8 + xmldoc/formats/options/xcsv-snwhite.xml | 7 + xmldoc/formats/options/xcsv-style.xml | 10 + xmldoc/formats/options/xcsv-urlbase.xml | 5 + xmldoc/formats/options/yahoo-addrsep.xml | 9 + xmldoc/formats/osm.xml | 13 + xmldoc/formats/ozi.xml | 7 + xmldoc/formats/palmdoc.xml | 13 + xmldoc/formats/pathaway.xml | 10 + xmldoc/formats/pcx.xml | 16 + xmldoc/formats/psitrex.xml | 10 + xmldoc/formats/psp.xml | 223 + xmldoc/formats/quovadis.xml | 21 + xmldoc/formats/raymarine.xml | 7 + xmldoc/formats/s_and_t.xml | 13 + xmldoc/formats/saplus.xml | 17 + xmldoc/formats/saroute.xml | 9 + xmldoc/formats/shape.xml | 15 + xmldoc/formats/sportsim.xml | 14 + xmldoc/formats/stmsdf.xml | 21 + xmldoc/formats/stmwpp.xml | 10 + xmldoc/formats/tabsep.xml | 12 + xmldoc/formats/tef.xml | 15 + xmldoc/formats/text.xml | 8 + xmldoc/formats/tiger.xml | 9 + xmldoc/formats/tmpro.xml | 10 + xmldoc/formats/tomtom.xml | 15 + xmldoc/formats/tomtom_asc.xml | 5 + xmldoc/formats/tomtom_itn.xml | 3 + xmldoc/formats/tpg.xml | 8 + xmldoc/formats/tpo.xml | 12 + xmldoc/formats/tpo2.xml | 9 + xmldoc/formats/tpo3.xml | 6 + xmldoc/formats/unicsv.xml | 105 + xmldoc/formats/vcard.xml | 13 + xmldoc/formats/vidaone.xml | 7 + xmldoc/formats/vitosmt.xml | 10 + xmldoc/formats/vitovtt.xml | 117 + xmldoc/formats/wbt-bin.xml | 12 + xmldoc/formats/wbt-tk1.xml | 11 + xmldoc/formats/wbt.xml | 26 + xmldoc/formats/wfff.xml | 7 + xmldoc/formats/xcsv.xml | 14 + xmldoc/formats/xmap.xml | 10 + xmldoc/formats/xmap2006.xml | 12 + xmldoc/formats/xmapwpt.xml | 80 + xmldoc/formats/xol.xml | 7 + xmldoc/formats/yahoo.xml | 7 + xmldoc/gpsbabel_man.xml | 92 + xmldoc/makedoc.in | 217 + xmldoc/old/extract | 4 + xmldoc/old/extract.xsl | 11 + xmldoc/old/readme.xml | 2296 ++ xmldoc/readme.xml | 20 + xmlgeneric.c | 365 + xmlgeneric.h | 63 + xmltag.c | 156 + xol.c | 354 + yahoo.c | 119 + zlib/.cvsignore | 1 + zlib/ChangeLog | 860 + zlib/FAQ | 339 + zlib/Makefile.in.zlib | 154 + zlib/README | 125 + zlib/README.gpsbabel | 3 + zlib/adler32.c | 149 + zlib/algorithm.txt | 209 + zlib/compress.c | 79 + zlib/crc32.c | 423 + zlib/crc32.h | 441 + zlib/deflate.c | 1736 ++ zlib/deflate.h | 331 + zlib/empty.in | 0 zlib/gzio.c | 1026 + zlib/infback.c | 623 + zlib/inffast.c | 318 + zlib/inffast.h | 11 + zlib/inffixed.h | 94 + zlib/inflate.c | 1368 ++ zlib/inflate.h | 115 + zlib/inftrees.c | 329 + zlib/inftrees.h | 55 + zlib/trees.c | 1219 + zlib/trees.h | 128 + zlib/uncompr.c | 61 + zlib/zconf.h | 332 + zlib/zconf.in.h | 332 + zlib/zlib.3 | 159 + zlib/zlib.h | 1357 ++ zlib/zutil.c | 318 + zlib/zutil.h | 269 + 1291 files changed, 372693 insertions(+) create mode 100644 .cvsignore create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 Makefile.in create mode 100644 README.contrib create mode 100644 README.igc create mode 100644 README.magnav create mode 100644 README.mapconverter create mode 100644 README.psp create mode 100644 README.xmapwpt create mode 100644 alan.c create mode 100644 an1.c create mode 100644 an1sym.h create mode 100644 arcdist.c create mode 100644 avltree.c create mode 100644 avltree.h create mode 100644 axim_gpb.c create mode 100644 bcr.c create mode 100644 brauniger_iq.c create mode 100644 cet.c create mode 100644 cet.h create mode 100644 cet/ansi_x3_4_1968.h create mode 100644 cet/atarist.h create mode 100644 cet/baltic.h create mode 100644 cet/bs_4730.h create mode 100644 cet/bs_viewdata.h create mode 100644 cet/cp1250.h create mode 100644 cet/cp1251.h create mode 100644 cet/cp1252.h create mode 100644 cet/cp1253.h create mode 100644 cet/cp1254.h create mode 100644 cet/cp1255.h create mode 100644 cet/cp1256.h create mode 100644 cet/cp1257.h create mode 100644 cet/csa_z243_4_1985_1.h create mode 100644 cet/csa_z243_4_1985_2.h create mode 100644 cet/csa_z243_4_1985_gr.h create mode 100644 cet/csn_369103.h create mode 100644 cet/cwi.h create mode 100644 cet/dec_mcs.h create mode 100644 cet/din_66003.h create mode 100644 cet/ds_2089.h create mode 100644 cet/ecma_cyrillic.h create mode 100644 cet/es.h create mode 100644 cet/es2.h create mode 100644 cet/gb_1988_80.h create mode 100644 cet/gost_19768_87.h create mode 100644 cet/hp_roman8.h create mode 100644 cet/ibm037.h create mode 100644 cet/ibm1004.h create mode 100644 cet/ibm1026.h create mode 100644 cet/ibm1047.h create mode 100644 cet/ibm256.h create mode 100644 cet/ibm273.h create mode 100644 cet/ibm277.h create mode 100644 cet/ibm278.h create mode 100644 cet/ibm280.h create mode 100644 cet/ibm284.h create mode 100644 cet/ibm285.h create mode 100644 cet/ibm297.h create mode 100644 cet/ibm437.h create mode 100644 cet/ibm500.h create mode 100644 cet/ibm850.h create mode 100644 cet/ibm851.h create mode 100644 cet/ibm852.h create mode 100644 cet/ibm855.h create mode 100644 cet/ibm857.h create mode 100644 cet/ibm860.h create mode 100644 cet/ibm861.h create mode 100644 cet/ibm862.h create mode 100644 cet/ibm863.h create mode 100644 cet/ibm864.h create mode 100644 cet/ibm865.h create mode 100644 cet/ibm868.h create mode 100644 cet/ibm869.h create mode 100644 cet/ibm871.h create mode 100644 cet/ibm891.h create mode 100644 cet/ibm903.h create mode 100644 cet/ibm904.h create mode 100644 cet/iec_p27_1.h create mode 100644 cet/iso_10367_box.h create mode 100644 cet/iso_5427.h create mode 100644 cet/iso_646_irv.h create mode 100644 cet/iso_6937_2_25.h create mode 100644 cet/iso_8859_1.h create mode 100644 cet/iso_8859_10.h create mode 100644 cet/iso_8859_13.h create mode 100644 cet/iso_8859_14.h create mode 100644 cet/iso_8859_15.h create mode 100644 cet/iso_8859_2.h create mode 100644 cet/iso_8859_3.h create mode 100644 cet/iso_8859_4.h create mode 100644 cet/iso_8859_5.h create mode 100644 cet/iso_8859_6.h create mode 100644 cet/iso_8859_7.h create mode 100644 cet/iso_8859_8.h create mode 100644 cet/iso_8859_9.h create mode 100644 cet/iso_8859_supp.h create mode 100644 cet/it.h create mode 100644 cet/jis_c6220_1969_ro.h create mode 100644 cet/jis_x0201.h create mode 100644 cet/jus_i_b1_002.h create mode 100644 cet/jus_i_b1_003_mac.h create mode 100644 cet/jus_i_b1_003_serb.h create mode 100644 cet/keybcs2.h create mode 100644 cet/koi8_r.h create mode 100644 cet/koi8_ru.h create mode 100644 cet/koi8_u.h create mode 100644 cet/koi_7.h create mode 100644 cet/koi_8.h create mode 100644 cet/koi_8_cs2.h create mode 100644 cet/ksc5636.h create mode 100644 cet/latin_greek_1.h create mode 100644 cet/mac_is.h create mode 100644 cet/macintosh.h create mode 100644 cet/macintosh_ce.h create mode 100644 cet/msz_7795_3.h create mode 100644 cet/nats_dano.h create mode 100644 cet/nats_sefi.h create mode 100644 cet/nc_nc00_10.h create mode 100644 cet/nextstep.h create mode 100644 cet/nf_z_62_010.h create mode 100644 cet/nf_z_62_010__1973_.h create mode 100644 cet/ns_4551_1.h create mode 100644 cet/ns_4551_2.h create mode 100644 cet/pt.h create mode 100644 cet/pt2.h create mode 100644 cet/sami.h create mode 100644 cet/sen_850200_b.h create mode 100644 cet/sen_850200_c.h create mode 100644 cet/tcvn.h create mode 100644 cet/viscii.h create mode 100644 cet/vps.h create mode 100644 cet_util.c create mode 100644 cet_util.h create mode 100644 cetus.c create mode 100755 chkdoc create mode 100755 coastexp.c create mode 100644 compegps.c create mode 100755 config.guess create mode 100644 config.h.in create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.in create mode 100755 contrib/correctCoordinates.pl create mode 100644 contrib/gpx2xfig create mode 100644 copilot.c create mode 100644 coto.c create mode 100644 cst.c create mode 100644 csv_util.c create mode 100644 csv_util.h create mode 100644 defs.h create mode 100644 delgpl.c create mode 100644 destinator.c create mode 100644 dg-100.c create mode 100644 discard.c create mode 100644 dmtlog.c create mode 100644 doc/.cvsignore create mode 100644 doc/Makefile create mode 100644 doc/babelfront2.eps create mode 100644 doc/doc.tex create mode 100644 duplicate.c create mode 100644 easygps.c create mode 100644 exif.c create mode 100644 fatal.c create mode 100644 filter_skeleton.c create mode 100644 filter_vecs.c create mode 100644 filterdefs.h create mode 100644 format_skeleton.c create mode 100644 formspec.c create mode 100644 g7towin.c create mode 100644 garmin.c create mode 100644 garmin_fs.c create mode 100644 garmin_fs.h create mode 100644 garmin_gpi.c create mode 100644 garmin_gpi.h create mode 100644 garmin_tables.c create mode 100644 garmin_tables.h create mode 100644 garmin_txt.c create mode 100644 gbfile.c create mode 100644 gbfile.h create mode 100644 gbser.c create mode 100644 gbser.h create mode 100644 gbser_posix.c create mode 100644 gbser_private.h create mode 100644 gbser_win.c create mode 100644 gbsleep.c create mode 100644 gbtypes.h create mode 100644 gbversion.h create mode 100644 gbversion.h.in create mode 100644 gcdb.c create mode 100644 gdb.c create mode 100644 geo.c create mode 100644 geocaching.loc create mode 100644 geoniche.c create mode 100644 ggv_log.c create mode 100644 globals.c create mode 100644 glogbook.c create mode 100644 google.c create mode 100644 gpilots.c create mode 100644 gpsbabel-sample.ini create mode 100644 gpsbabel.html create mode 100644 gpsman create mode 100644 gpsman2 create mode 100644 gpspilot.c create mode 100644 gpssim.c create mode 100644 gpsutil.c create mode 100644 gpx.c create mode 100644 gpxval create mode 100644 grtcirc.c create mode 100644 grtcirc.h create mode 100644 gtm.c create mode 100644 gtrnctr.c create mode 100755 guibabel create mode 100644 hiketech.c create mode 100644 holux.c create mode 100644 holux.h create mode 100644 hsa_ndv.c create mode 100644 html.c create mode 100644 igc.c create mode 100644 ignrando.c create mode 100644 ik3d.c create mode 100644 inifile.c create mode 100644 inifile.h create mode 100755 install-sh create mode 100644 intdoc/BraunigerIQformat create mode 100644 intdoc/GPSBabel Windows GUI 2.00.00 Project Plan.pdf create mode 100644 intdoc/MPSformat create mode 100644 intdoc/SA2003_an1_dump.pl create mode 100644 intdoc/SA2003_annotations.txt create mode 100644 intdoc/SA2005_dump.pl create mode 100644 intdoc/an1_road_types.txt create mode 100644 intdoc/jeeps-device.odg create mode 100644 internal_styles.c create mode 100644 interpolate.c create mode 100644 jeeps/.cvsignore create mode 100644 jeeps/Makefile.in create mode 100644 jeeps/README create mode 100644 jeeps/garminusb.h create mode 100644 jeeps/gps.h create mode 100644 jeeps/gpsapp.c create mode 100644 jeeps/gpsapp.h create mode 100644 jeeps/gpscom.c create mode 100644 jeeps/gpscom.h create mode 100644 jeeps/gpsdatum.h create mode 100644 jeeps/gpsdevice.c create mode 100644 jeeps/gpsdevice.h create mode 100644 jeeps/gpsdevice_ser.c create mode 100644 jeeps/gpsdevice_usb.c create mode 100644 jeeps/gpsfmt.c create mode 100644 jeeps/gpsfmt.h create mode 100644 jeeps/gpsinput.c create mode 100644 jeeps/gpsinput.h create mode 100644 jeeps/gpslibusb.c create mode 100644 jeeps/gpsmath.c create mode 100644 jeeps/gpsmath.h create mode 100644 jeeps/gpsmem.c create mode 100644 jeeps/gpsmem.h create mode 100644 jeeps/gpsport.h create mode 100644 jeeps/gpsproj.c create mode 100644 jeeps/gpsproj.h create mode 100644 jeeps/gpsprot.c create mode 100644 jeeps/gpsprot.h create mode 100644 jeeps/gpsread.c create mode 100644 jeeps/gpsread.h create mode 100644 jeeps/gpsrqst.c create mode 100644 jeeps/gpsrqst.h create mode 100644 jeeps/gpssend.c create mode 100644 jeeps/gpssend.h create mode 100644 jeeps/gpsserial.c create mode 100644 jeeps/gpsserial.h create mode 100644 jeeps/gpsusbcommon.c create mode 100644 jeeps/gpsusbcommon.h create mode 100644 jeeps/gpsusbint.h create mode 100644 jeeps/gpsusbread.c create mode 100644 jeeps/gpsusbsend.c create mode 100644 jeeps/gpsusbstub.c create mode 100644 jeeps/gpsusbwin.c create mode 100644 jeeps/gpsutil.c create mode 100644 jeeps/gpsutil.h create mode 100644 jeeps/main.c create mode 100644 kml.c create mode 100644 lmx.c create mode 100644 lowranceusr.c create mode 100644 mac/dmg-contents/COPYING create mode 100644 mac/dmg-contents/Credits.rtf create mode 100755 mac/dmg-contents/GPSBabel+.app create mode 100644 mac/dmg-contents/README.rtf create mode 100644 mac/include/expat.h create mode 100644 mac/lib/libexpat.a create mode 100644 macgpsbabel/Credits.rtf create mode 100644 macgpsbabel/English.lproj/InfoPlist.strings create mode 100644 macgpsbabel/English.lproj/MainMenu.nib/classes.nib create mode 100644 macgpsbabel/English.lproj/MainMenu.nib/data.dependency create mode 100644 macgpsbabel/English.lproj/MainMenu.nib/info.nib create mode 100644 macgpsbabel/English.lproj/MainMenu.nib/objects.nib create mode 100644 macgpsbabel/Info.plist create mode 100644 macgpsbabel/MacGPSBabel.applescript create mode 100644 macgpsbabel/MacGPSBabel.pbproj/default.pbxuser create mode 100644 macgpsbabel/MacGPSBabel.pbproj/jeremya.pbxuser create mode 100644 macgpsbabel/MacGPSBabel.pbproj/project.pbxproj create mode 100644 macgpsbabel/MacGPSBabel.xcodeproj/project.pbxproj create mode 100644 macgpsbabel/README.macgpsbabel create mode 100644 macgpsbabel/main.m create mode 100644 macgpsbabel/mgb.icns create mode 100644 macgpsbabel/preferences.applescript create mode 100644 mag_pdb.c create mode 100644 magellan.h create mode 100644 maggeo.c create mode 100644 magnav.c create mode 100644 magproto.c create mode 100644 main.c create mode 100755 make-an1sym.pl create mode 100644 mapopolis.c create mode 100644 mapsend.c create mode 100644 mapsend.h create mode 100644 mapsource.c create mode 100644 mingw/Makefile create mode 100644 mingw/README.expat create mode 100644 mingw/coldsync/.ignore create mode 100644 mingw/include/expat.h create mode 100644 mingw/includew/expat.h create mode 100644 mingw/includew/expat_external.h create mode 100644 mingw/jeeps/.ignore create mode 100644 mingw/lib/README create mode 100644 mingw/lib/libexpat.a create mode 100755 mingw/lib/libexpat.def create mode 100644 mingw/libexpat.dll create mode 100644 mingw/libw/README create mode 100644 mingw/libw/libexpat.a create mode 100644 mingw/mkwintesto.c create mode 100644 mingw/shapelib/.ignore create mode 100755 mingw/testo create mode 100644 mingw/wintesto.cmd create mode 100644 mkicondoc.c create mode 100644 mkshort.c create mode 100755 mkstyle.sh create mode 100644 msroute.c create mode 100644 msvc/Debug.empty create mode 100644 msvc/Expat/expat.h create mode 100755 msvc/Expat/libexpat.dll create mode 100644 msvc/Expat/libexpat.lib create mode 100644 msvc/Expatw/expat.h create mode 100644 msvc/Expatw/expat_external.h create mode 100644 msvc/Expatw/libexpatw.dll create mode 100644 msvc/Expatw/libexpatw.lib create mode 100644 msvc/GPSBabel-msvc7.sln create mode 100644 msvc/GPSBabel-msvc7.vcproj create mode 100644 msvc/GPSBabel.dsp create mode 100644 msvc/GPSBabel.dsw create mode 100644 msvc/GPSBabel.sln create mode 100644 msvc/GPSBabel.vcproj create mode 100644 msvc/README.msvc create mode 100644 msvc/Unicode.empty create mode 100644 msvc/build.bat create mode 100644 msvc/config.h create mode 100644 msvc/mkwintesto.dsp create mode 100644 msvc/release.empty create mode 100644 mtk_logger.c create mode 100644 navicache.c create mode 100644 navilink.c create mode 100644 netstumbler.c create mode 100644 nmea.c create mode 100644 nmn4.c create mode 100644 nukedata.c create mode 100644 osm.c create mode 100644 overlay.c create mode 100644 ozi.c create mode 100644 palmdoc.c create mode 100644 parse.c create mode 100644 pathaway.c create mode 100644 pcx.c create mode 100644 pdbfile.c create mode 100644 pdbfile.h create mode 100644 polygon.c create mode 100644 position.c create mode 100755 psitrex.c create mode 100644 psp.c create mode 100644 queue.c create mode 100644 queue.h create mode 100644 quovadis.c create mode 100644 quovadis.h create mode 100644 radius.c create mode 100644 random.c create mode 100644 raymarine.c create mode 100644 reference/GeocachingDB.PDB create mode 100644 reference/Glad_4.exp create mode 100644 reference/Glad_5.exp create mode 100644 reference/IMG_2065.JPG create mode 100644 reference/UKultralight.pdb create mode 100644 reference/alantrl.gpx create mode 100644 reference/alantrl.trl create mode 100644 reference/alanwpr.gpx create mode 100644 reference/alanwpr.wpr create mode 100644 reference/all.usr create mode 100644 reference/an1-an1.ref create mode 100644 reference/an1-in.ref create mode 100644 reference/an1-line-out.ref create mode 100644 reference/an1-out.ref create mode 100644 reference/arcdist_arc.txt create mode 100644 reference/arcdist_input.txt create mode 100644 reference/arcdist_output.txt create mode 100644 reference/cet/cet-sample.cp1250.txt create mode 100644 reference/cet/cet-sample.gdb create mode 100644 reference/cet/cet-sample.gpx create mode 100644 reference/cet/cet-sample.latin1.txt create mode 100644 reference/cet/cet-sample.latin2.txt create mode 100644 reference/cet/cet-sample.macroman.txt create mode 100644 reference/cetus.gpu create mode 100644 reference/cetus.pdb create mode 100644 reference/chicago.trk create mode 100755 reference/coastexp.nob create mode 100755 reference/coastexp.ref create mode 100644 reference/coastexp.ref2 create mode 100644 reference/coastexp.ref3 create mode 100644 reference/coastexp.ref4 create mode 100644 reference/compegps-wpt.gpx create mode 100644 reference/compegps.wpt create mode 100644 reference/compegps.wpt.gz create mode 100644 reference/cototest.style create mode 100644 reference/cototestmarker.gpx create mode 100644 reference/cototestmarker.pdb create mode 100644 reference/cototesttrack.csv create mode 100644 reference/cototesttrack.pdb create mode 100644 reference/destinator_poi.dat create mode 100644 reference/destinator_poi.txt create mode 100644 reference/dnatest.txt create mode 100644 reference/dop-test.gpx create mode 100644 reference/dusky.gnuplot create mode 100755 reference/dusky.trk create mode 100644 reference/earth-expertgps.kml create mode 100644 reference/earth-gc.kml create mode 100755 reference/easygps.loc create mode 100644 reference/enchilada.usr create mode 100644 reference/exif-dat.csv create mode 100644 reference/expertgps-g7t.txt create mode 100644 reference/expertgps.g7t create mode 100755 reference/expertgps.gpx create mode 100644 reference/expertgps.rwf create mode 100755 reference/foo.an1 create mode 100644 reference/fugawi.notime.txt create mode 100644 reference/fugawi.ref create mode 100644 reference/fugawi.ref.txt create mode 100644 reference/fugawi.time.ref.txt create mode 100644 reference/fugawi.time.txt create mode 100644 reference/garmin_gpi.gpi create mode 100644 reference/garmin_gpi.gpx create mode 100644 reference/garmin_gpi2.gpx create mode 100644 reference/garmin_symbols.gpx create mode 100644 reference/garmin_txt-uni.csv create mode 100644 reference/garmin_txt.txt create mode 100644 reference/gc/GC7FA4.gpx create mode 100644 reference/gc/GCGCA8.gpx create mode 100644 reference/gc/maggeo.gs create mode 100644 reference/gdb-sample-v3.gdb create mode 100644 reference/gdb-sample.gdb create mode 100644 reference/gdb-sample.gpx create mode 100644 reference/gdb-sample2.gdb create mode 100644 reference/geocaching.gpx create mode 100644 reference/geonet-sample.gpx create mode 100644 reference/geonet-sample.txt create mode 100644 reference/geoniche.pdb create mode 100644 reference/gl.loc create mode 100644 reference/gn-targets.gpx create mode 100644 reference/gn-targets.pdb create mode 100644 reference/gnuplot.style create mode 100644 reference/google.arc create mode 100644 reference/google.csv create mode 100644 reference/google.js create mode 100644 reference/google.xml create mode 100644 reference/google_jan_06.csv create mode 100644 reference/google_jan_06.html create mode 100644 reference/googmap.sh create mode 100644 reference/googmapjs.sh create mode 100644 reference/gpi_ext-sample.csv create mode 100644 reference/gpi_ext-sample.gpi create mode 100644 reference/gpilots.pdb create mode 100644 reference/gpsdrive.txt create mode 100644 reference/gpspilot.pdb create mode 100644 reference/gpsutil-1.pcx create mode 100644 reference/gu.wpt create mode 100644 reference/hiketech.gpx create mode 100644 reference/hiketech.ref create mode 100644 reference/holux.gpx create mode 100644 reference/holux.wpo create mode 100644 reference/hsandv.exp create mode 100644 reference/human.in create mode 100644 reference/humanread.out create mode 100644 reference/humanread.style create mode 100644 reference/humanwrite.out create mode 100644 reference/humanwrite.style create mode 100644 reference/igc1.gpx create mode 100644 reference/igc1_3d.out create mode 100644 reference/igc1_baro.gpx create mode 100644 reference/igc1_gpx.out create mode 100644 reference/igc1_igc.out create mode 100644 reference/igc2.igc create mode 100644 reference/igc2_gpx.out create mode 100644 reference/igc2_igc.out create mode 100644 reference/ignoreicons.usr create mode 100644 reference/ik3d-sample.gpx create mode 100644 reference/ik3d-sample.ikt create mode 100644 reference/kartex-out.kwf create mode 100644 reference/kartex.txt create mode 100644 reference/lowrance.usr create mode 100644 reference/magfile create mode 100644 reference/magnav.pdb create mode 100644 reference/magnavr.gpu create mode 100755 reference/mapsource.mps create mode 100755 reference/mps-empty.mps create mode 100644 reference/multiple-links.gpx create mode 100644 reference/mxf.mxf create mode 100644 reference/navicache.ref create mode 100644 reference/navicache.xml create mode 100644 reference/navilink_tracks.gpx create mode 100755 reference/navilink_tracks.trk create mode 100755 reference/navilink_tracks_gpx.trk create mode 100644 reference/navilink_waypoints.gpx create mode 100755 reference/navilink_waypoints.wpt create mode 100644 reference/navilink_waypoints_gpx.wpt create mode 100644 reference/netstumbler.mps create mode 100644 reference/netstumbler.txt create mode 100644 reference/nokia.lmx create mode 100644 reference/osm-data.gpx create mode 100644 reference/osm-data.xml create mode 100644 reference/ov2-arc-out.ref create mode 100644 reference/ov2-geo-out.ref create mode 100644 reference/ov2-in.ref create mode 100644 reference/ozi.wpt create mode 100644 reference/paris.wpo create mode 100644 reference/pathaway-geo.loc create mode 100644 reference/polygon_allencty.txt create mode 100644 reference/polygon_output.txt create mode 100644 reference/ps.psp create mode 100755 reference/psitwpts.txt create mode 100644 reference/quovadis.gpu create mode 100644 reference/quovadis.pdb create mode 100644 reference/radius.csv create mode 100644 reference/raymarine-sample.gpx create mode 100644 reference/raymarine-sample.rwf create mode 100644 reference/route/bcr-sample.bcr create mode 100644 reference/route/bcr-sample.gpx create mode 100644 reference/route/bcr-sample2.bcr create mode 100644 reference/route/compegps-rte.gpx create mode 100644 reference/route/compegps.rte create mode 100644 reference/route/cst-sample.cst create mode 100644 reference/route/cst-sample.cst.gz create mode 100644 reference/route/cst-sample.gpx create mode 100644 reference/route/destinator_itn.dat create mode 100644 reference/route/destinator_itn.txt create mode 100644 reference/route/mag_pdb-sample.gpx create mode 100644 reference/route/mag_pdb-sample.pdb create mode 100644 reference/route/magellan.rte create mode 100644 reference/route/magexplorist.rte create mode 100644 reference/route/msroute-sample.axe create mode 100644 reference/route/msroute-sample.gpx create mode 100644 reference/route/nmn4-sample-out.rte create mode 100644 reference/route/nmn4-sample.gpx create mode 100644 reference/route/nmn4-sample.rte create mode 100755 reference/route/psitrtes.txt create mode 100644 reference/route/route.gpx create mode 100644 reference/route/route.mapsend create mode 100755 reference/route/route.mps create mode 100644 reference/route/stmsdf-route.sdf create mode 100644 reference/route/stmwpp-route.gpx create mode 100644 reference/route/stmwpp-route.txt create mode 100644 reference/route/tef_xml.sample.gpx create mode 100644 reference/route/tef_xml.sample.xml create mode 100644 reference/route/tomtom_itn.itn create mode 100644 reference/route/vieac.README create mode 100644 reference/route/vieac.rte create mode 100644 reference/sample.gtm create mode 100644 reference/sample.gtm.gz create mode 100644 reference/simplify_output.txt create mode 100644 reference/stmsdf.txt create mode 100644 reference/tomtom_poi.asc create mode 100644 reference/topomapexample.txt create mode 100644 reference/topomappro.txt create mode 100644 reference/tpg.tpg create mode 100644 reference/tpo-sample.tpo create mode 100644 reference/tpo-sample3.gpx create mode 100644 reference/tpo-sample3.tpo create mode 100644 reference/track/TrkDB-GPil.pdb create mode 100644 reference/track/axim-sample.gpb create mode 100644 reference/track/axim-sample.gpx create mode 100644 reference/track/chi-mapsend.trk create mode 100644 reference/track/compegps-trk.gpx create mode 100644 reference/track/compegps.trk create mode 100644 reference/track/destinator_trl.dat create mode 100644 reference/track/destinator_trl.txt create mode 100644 reference/track/dmtlog-sample.gpx create mode 100644 reference/track/fugawi.txt create mode 100644 reference/track/garmin_logbook.xml create mode 100644 reference/track/ggv_log-sample.log create mode 100755 reference/track/i65.anr create mode 100644 reference/track/i65.anr.gpx create mode 100644 reference/track/ignrando-sample.gpx create mode 100644 reference/track/ignrando-sample.rdn create mode 100644 reference/track/interptrack.gpx create mode 100644 reference/track/kartex-out.ktf create mode 100644 reference/track/kartex.txt create mode 100644 reference/track/kompass.tk create mode 100644 reference/track/mapsend.trk create mode 100644 reference/track/meridian.trk create mode 100644 reference/track/mps-track.mps create mode 100644 reference/track/mtk_logger.bin create mode 100644 reference/track/mtk_logger.csv create mode 100644 reference/track/mtk_logger.gpx create mode 100644 reference/track/nmea create mode 100644 reference/track/nmea+ms.gpx create mode 100644 reference/track/nmea+ms.txt create mode 100644 reference/track/nmea.gpx create mode 100644 reference/track/pathaway.gpx create mode 100644 reference/track/pathaway.pdb create mode 100644 reference/track/pcx.trk create mode 100755 reference/track/psittrks.txt create mode 100644 reference/track/simpletrack.gpx create mode 100644 reference/track/sportsim-sample.txt create mode 100644 reference/track/stmsdf-track.sdf create mode 100644 reference/track/stmwpp-route.gpx create mode 100644 reference/track/stmwpp-track.gpx create mode 100644 reference/track/stmwpp-track.txt create mode 100644 reference/track/tef_xml.sample.xml create mode 100644 reference/track/tinterptrack.gpx create mode 100644 reference/track/tpo-sample1.gpx create mode 100644 reference/track/tpo-sample1.tpo create mode 100644 reference/track/tpo-sample2.gpx create mode 100644 reference/track/tpo-sample2.tpo create mode 100644 reference/track/trackDMm.ktf create mode 100644 reference/track/trackDd.ktf create mode 100644 reference/track/trackfilter-new.gpx create mode 100644 reference/track/trackfilter-sdistance.gpx create mode 100644 reference/track/trackfilter-sdistance2.gpx create mode 100644 reference/track/trackfilter.gpx create mode 100644 reference/track/tracks.gpssim create mode 100644 reference/track/tracks.gpx create mode 100644 reference/track/vidaone.csv create mode 100644 reference/track/vidaone.gpb create mode 100644 reference/track/vitosmt_t.gpx create mode 100644 reference/track/vitovtt-sample.gpx create mode 100644 reference/track/vitovtt-sample.vtt create mode 100644 reference/track/webpark1.gpl create mode 100644 reference/transform-rte.gpx create mode 100644 reference/transform-wpt.gpx create mode 100644 reference/unicsv.gpx create mode 100644 reference/vitosmt.gpx create mode 100644 reference/vitosmt.smt create mode 100644 reference/waypoints.gpssim create mode 100644 reference/waypointsDMm.kwf create mode 100644 reference/waypointsDd.kwf create mode 100644 reference/wbt-200.bin create mode 100644 reference/wbt-200.gpx create mode 100644 reference/wbt-201.gpx create mode 100644 reference/wbt-201.tk1 create mode 100644 reference/wfff.gpu create mode 100644 reference/wfff.xml create mode 100644 reference/xmap create mode 100644 reference/xmapwpt.wpt create mode 100644 reference/xol-sample-gpx.xol create mode 100644 reference/xol-sample.gpx create mode 100644 reference/xol-sample.xol create mode 100644 reverse_route.c create mode 100644 rgbcolors.c create mode 100644 route.c create mode 100644 saroute.c create mode 100644 shape.c create mode 100644 shapelib/.cvsignore create mode 100644 shapelib/Makefile.in create mode 100644 shapelib/README.GPSBabel create mode 100644 shapelib/dbf_api.html create mode 100644 shapelib/dbfopen.c create mode 100644 shapelib/shapefil.h create mode 100644 shapelib/shapelib.html create mode 100644 shapelib/shp_api.html create mode 100644 shapelib/shpopen.c create mode 100644 smplrout.c create mode 100644 sort.c create mode 100644 stackfilter.c create mode 100644 stmsdf.c create mode 100644 stmwpp.c create mode 100644 strptime.c create mode 100644 strptime.h create mode 100644 style/arc.style create mode 100644 style/cambridge.style create mode 100644 style/csv.style create mode 100644 style/cup.style create mode 100644 style/custom.style create mode 100644 style/dna.style create mode 100644 style/fugawi.style create mode 100644 style/garmin301.style create mode 100644 style/garmin_poi.style create mode 100644 style/geonet.style create mode 100644 style/gpsdrive.style create mode 100644 style/gpsdrivetrack.style create mode 100644 style/gpsman.style create mode 100644 style/kompass_tk.style create mode 100644 style/kompass_wp.style create mode 100644 style/ktf2.style create mode 100644 style/kwf2.style create mode 100644 style/mapconverter.style create mode 100644 style/mxf.style create mode 100644 style/nima.style create mode 100644 style/openoffice.style create mode 100644 style/s_and_t.style create mode 100644 style/saplus.style create mode 100644 style/sportsim.style create mode 100644 style/tabsep.style create mode 100644 style/tomtom_asc.style create mode 100644 style/tomtom_itn.style create mode 100644 style/xmap.style create mode 100644 style/xmap2006.style create mode 100644 style/xmapwpt.style create mode 100644 tef_xml.c create mode 100755 test-all create mode 100755 testc create mode 100755 testo create mode 100755 testw create mode 100644 text.c create mode 100644 tiger.c create mode 100644 tmpro.c create mode 100644 tomtom.c create mode 100644 tools/.cvsignore create mode 100755 tools/cleardebug create mode 100644 tools/cvslog create mode 100755 tools/functions create mode 100755 tools/gcfg create mode 100755 tools/mac-config create mode 100755 tools/memdebug create mode 100755 tools/mkcapabilities.in create mode 100755 tools/mkchangelog create mode 100644 tools/mkchanges create mode 100755 tools/mkdmg create mode 100755 tools/mkfilelist create mode 100755 tools/mkmoreclean create mode 100755 tools/mkrpm create mode 100755 tools/mkspec create mode 100644 tools/release-process create mode 100755 torture_test create mode 100644 tpg.c create mode 100644 tpo.README.patch create mode 100644 tpo.c create mode 100644 tpo.testo.patch create mode 100644 trackfilter.c create mode 100644 transform.c create mode 100644 unicsv.c create mode 100644 units.c create mode 100644 util.c create mode 100644 util_crc.c create mode 100755 uuid.c create mode 100755 uuid.h create mode 100644 vcf.c create mode 100644 vecs.c create mode 100644 vidaone.c create mode 100644 vitosmt.c create mode 100644 vitovtt.c create mode 100644 vmem.c create mode 100755 vtesto create mode 100644 waypt.c create mode 100644 wbt-200.c create mode 100644 wfff_xml.c create mode 100644 win32/.cvsignore create mode 100644 win32/GPSBabelGUI.exe create mode 100644 win32/gpsbabel.ico create mode 100644 win32/gpsbabel.rc.in create mode 100644 win32/gui-2/.cvsignore create mode 100644 win32/gui-2/GPSBabelGUI.cfg create mode 100644 win32/gui-2/GPSBabelGUI.dof create mode 100644 win32/gui-2/GPSBabelGUI.dpr create mode 100644 win32/gui-2/GPSBabelGUI.ico create mode 100644 win32/gui-2/GPSBabelGUI.res create mode 100644 win32/gui-2/Makefile create mode 100644 win32/gui-2/README.gui create mode 100644 win32/gui-2/about.dfm create mode 100644 win32/gui-2/about.pas create mode 100644 win32/gui-2/common.pas create mode 100644 win32/gui-2/default.po create mode 100644 win32/gui-2/delphi.pas create mode 100644 win32/gui-2/dof2rc.dpr create mode 100644 win32/gui-2/filter.dfm create mode 100644 win32/gui-2/filter.pas create mode 100644 win32/gui-2/gnugettext.pas create mode 100644 win32/gui-2/gnugettextD4.pas create mode 100644 win32/gui-2/gnugettextD5.pas create mode 100644 win32/gui-2/gnugettextDx.pas create mode 100644 win32/gui-2/gpsbabel.iss create mode 100644 win32/gui-2/gpsbabel.po create mode 100644 win32/gui-2/ignore.po create mode 100644 win32/gui-2/locale/de/LC_MESSAGES/default.po create mode 100644 win32/gui-2/locale/de/LC_MESSAGES/delphi.po create mode 100644 win32/gui-2/locale/de/LC_MESSAGES/gpsbabel.po create mode 100644 win32/gui-2/locale/es/LC_MESSAGES/default.po create mode 100644 win32/gui-2/locale/es/LC_MESSAGES/delphi.po create mode 100644 win32/gui-2/locale/es/LC_MESSAGES/gpsbabel.po create mode 100644 win32/gui-2/locale/fr/LC_MESSAGES/default.po create mode 100644 win32/gui-2/locale/fr/LC_MESSAGES/delphi.po create mode 100644 win32/gui-2/locale/fr/LC_MESSAGES/gpsbabel.po create mode 100644 win32/gui-2/locale/hu/LC_MESSAGES/default.po create mode 100644 win32/gui-2/locale/hu/LC_MESSAGES/delphi.po create mode 100644 win32/gui-2/locale/hu/LC_MESSAGES/gpsbabel.po create mode 100644 win32/gui-2/main.dfm create mode 100644 win32/gui-2/main.pas create mode 100644 win32/gui-2/options.dfm create mode 100644 win32/gui-2/options.pas create mode 100644 win32/gui-2/readme.dfm create mode 100644 win32/gui-2/readme.pas create mode 100644 win32/gui-2/select.dfm create mode 100644 win32/gui-2/select.pas create mode 100644 win32/gui-2/utils.pas create mode 100644 win32/gui/AboutDialogU.ddp create mode 100644 win32/gui/AboutDialogU.dfm create mode 100644 win32/gui/AboutDialogU.pas create mode 100644 win32/gui/GPSBabelGUI.cfg create mode 100644 win32/gui/GPSBabelGUI.dof create mode 100644 win32/gui/GPSBabelGUI.dpr create mode 100644 win32/gui/GPSBabelGUI.ico create mode 100644 win32/gui/GPSBabelGUI.res create mode 100644 win32/gui/GPSBabelGUI.todo create mode 100644 win32/gui/GPSBabelGUIDialogU.ddp create mode 100644 win32/gui/GPSBabelGUIDialogU.dfm create mode 100644 win32/gui/GPSBabelGUIDialogU.pas create mode 100644 win32/gui/README.txt create mode 100644 win32/gui/VersionInfo.pas create mode 100644 win32/gui/filelist.txt create mode 100644 xcsv.c create mode 100644 xcsv_tokens.gperf create mode 100644 xcsv_tokens.in create mode 100644 xhtmlent.c create mode 100644 xmldoc/.cvsignore create mode 100644 xmldoc/autogen/.cvsignore create mode 100644 xmldoc/babelmain.xsl create mode 100644 xmldoc/babelpdf.xsl create mode 100644 xmldoc/chapters/_chapters.xml create mode 100644 xmldoc/chapters/allchapters.xml create mode 100644 xmldoc/chapters/build.xml create mode 100644 xmldoc/chapters/datums.xml create mode 100644 xmldoc/chapters/filters.xml create mode 100644 xmldoc/chapters/formats.xml create mode 100644 xmldoc/chapters/garmin_icons.xml create mode 100644 xmldoc/chapters/glossary.xml create mode 100644 xmldoc/chapters/preface.xml create mode 100644 xmldoc/chapters/styles.xml create mode 100644 xmldoc/chapters/use.xml create mode 100644 xmldoc/filters/arc.xml create mode 100644 xmldoc/filters/discard.xml create mode 100644 xmldoc/filters/duplicate.xml create mode 100644 xmldoc/filters/interpolate.xml create mode 100644 xmldoc/filters/nuketypes.xml create mode 100644 xmldoc/filters/options/arc-distance.xml create mode 100644 xmldoc/filters/options/arc-exclude.xml create mode 100644 xmldoc/filters/options/arc-file.xml create mode 100644 xmldoc/filters/options/arc-points.xml create mode 100644 xmldoc/filters/options/discard-hdop.xml create mode 100644 xmldoc/filters/options/discard-hdopandvdop.xml create mode 100644 xmldoc/filters/options/discard-sat.xml create mode 100644 xmldoc/filters/options/discard-vdop.xml create mode 100644 xmldoc/filters/options/duplicate-all.xml create mode 100644 xmldoc/filters/options/duplicate-correct.xml create mode 100644 xmldoc/filters/options/duplicate-location.xml create mode 100644 xmldoc/filters/options/duplicate-shortname.xml create mode 100644 xmldoc/filters/options/interpolate-distance.xml create mode 100644 xmldoc/filters/options/interpolate-route.xml create mode 100644 xmldoc/filters/options/interpolate-time.xml create mode 100644 xmldoc/filters/options/nuketypes-routes.xml create mode 100644 xmldoc/filters/options/nuketypes-tracks.xml create mode 100644 xmldoc/filters/options/nuketypes-waypoints.xml create mode 100644 xmldoc/filters/options/polygon-exclude.xml create mode 100644 xmldoc/filters/options/polygon-file.xml create mode 100644 xmldoc/filters/options/position-all.xml create mode 100644 xmldoc/filters/options/position-distance.xml create mode 100644 xmldoc/filters/options/radius-asroute.xml create mode 100644 xmldoc/filters/options/radius-distance.xml create mode 100644 xmldoc/filters/options/radius-exclude.xml create mode 100644 xmldoc/filters/options/radius-lat.xml create mode 100644 xmldoc/filters/options/radius-lon.xml create mode 100644 xmldoc/filters/options/radius-maxcount.xml create mode 100644 xmldoc/filters/options/radius-nosort.xml create mode 100644 xmldoc/filters/options/simplify-count.xml create mode 100644 xmldoc/filters/options/simplify-crosstrack.xml create mode 100644 xmldoc/filters/options/simplify-error.xml create mode 100644 xmldoc/filters/options/simplify-length.xml create mode 100644 xmldoc/filters/options/sort-description.xml create mode 100644 xmldoc/filters/options/sort-gcid.xml create mode 100644 xmldoc/filters/options/sort-shortname.xml create mode 100644 xmldoc/filters/options/sort-time.xml create mode 100644 xmldoc/filters/options/stack-append.xml create mode 100644 xmldoc/filters/options/stack-copy.xml create mode 100644 xmldoc/filters/options/stack-depth.xml create mode 100644 xmldoc/filters/options/stack-discard.xml create mode 100644 xmldoc/filters/options/stack-pop.xml create mode 100644 xmldoc/filters/options/stack-push.xml create mode 100644 xmldoc/filters/options/stack-replace.xml create mode 100644 xmldoc/filters/options/stack-swap.xml create mode 100644 xmldoc/filters/options/track-course.xml create mode 100644 xmldoc/filters/options/track-fix.xml create mode 100644 xmldoc/filters/options/track-merge.xml create mode 100644 xmldoc/filters/options/track-move.xml create mode 100644 xmldoc/filters/options/track-name.xml create mode 100644 xmldoc/filters/options/track-pack.xml create mode 100644 xmldoc/filters/options/track-sdistance.xml create mode 100644 xmldoc/filters/options/track-speed.xml create mode 100644 xmldoc/filters/options/track-split.xml create mode 100644 xmldoc/filters/options/track-start.xml create mode 100644 xmldoc/filters/options/track-stop.xml create mode 100644 xmldoc/filters/options/track-title.xml create mode 100644 xmldoc/filters/options/transform-del.xml create mode 100644 xmldoc/filters/options/transform-rte.xml create mode 100644 xmldoc/filters/options/transform-trk.xml create mode 100644 xmldoc/filters/options/transform-wpt.xml create mode 100644 xmldoc/filters/polygon.xml create mode 100644 xmldoc/filters/position.xml create mode 100644 xmldoc/filters/radius.xml create mode 100644 xmldoc/filters/reverse.xml create mode 100644 xmldoc/filters/simplify.xml create mode 100644 xmldoc/filters/sort.xml create mode 100644 xmldoc/filters/stack.xml create mode 100644 xmldoc/filters/track.xml create mode 100644 xmldoc/filters/transform.xml create mode 100644 xmldoc/formats/alantrl.xml create mode 100644 xmldoc/formats/alanwpr.xml create mode 100644 xmldoc/formats/an1.xml create mode 100644 xmldoc/formats/arc.xml create mode 100644 xmldoc/formats/axim_gpb.xml create mode 100644 xmldoc/formats/baroiq.xml create mode 100644 xmldoc/formats/bcr.xml create mode 100644 xmldoc/formats/cambridge.xml create mode 100644 xmldoc/formats/cetus.xml create mode 100644 xmldoc/formats/coastexp.xml create mode 100644 xmldoc/formats/compegps.xml create mode 100644 xmldoc/formats/copilot.xml create mode 100644 xmldoc/formats/coto.xml create mode 100644 xmldoc/formats/cst.xml create mode 100644 xmldoc/formats/csv.xml create mode 100644 xmldoc/formats/cup.xml create mode 100644 xmldoc/formats/custom.xml create mode 100644 xmldoc/formats/destinator_itn.xml create mode 100644 xmldoc/formats/destinator_poi.xml create mode 100644 xmldoc/formats/destinator_trl.xml create mode 100644 xmldoc/formats/dg-100.xml create mode 100644 xmldoc/formats/dmtlog.xml create mode 100644 xmldoc/formats/dna.xml create mode 100644 xmldoc/formats/easygps.xml create mode 100644 xmldoc/formats/exif.xml create mode 100644 xmldoc/formats/fugawi.xml create mode 100644 xmldoc/formats/g7towin.xml create mode 100644 xmldoc/formats/garmin.xml create mode 100644 xmldoc/formats/garmin301.xml create mode 100644 xmldoc/formats/garmin_gpi.xml create mode 100644 xmldoc/formats/garmin_poi.xml create mode 100644 xmldoc/formats/garmin_txt.xml create mode 100644 xmldoc/formats/gcdb.xml create mode 100644 xmldoc/formats/gdb.xml create mode 100644 xmldoc/formats/geo.xml create mode 100644 xmldoc/formats/geonet.xml create mode 100644 xmldoc/formats/geoniche.xml create mode 100644 xmldoc/formats/ggv_log.xml create mode 100644 xmldoc/formats/glogbook.xml create mode 100644 xmldoc/formats/google.xml create mode 100644 xmldoc/formats/gpilots.xml create mode 100644 xmldoc/formats/gpl.xml create mode 100644 xmldoc/formats/gpsdrive.xml create mode 100644 xmldoc/formats/gpsdrivetrack.xml create mode 100644 xmldoc/formats/gpsman.xml create mode 100644 xmldoc/formats/gpspilot.xml create mode 100644 xmldoc/formats/gpssim.xml create mode 100644 xmldoc/formats/gpsutil.xml create mode 100644 xmldoc/formats/gpx.xml create mode 100644 xmldoc/formats/gtm.xml create mode 100644 xmldoc/formats/gtrnctr.xml create mode 100644 xmldoc/formats/hiketech.xml create mode 100644 xmldoc/formats/holux.xml create mode 100644 xmldoc/formats/hsandv.xml create mode 100644 xmldoc/formats/html.xml create mode 100644 xmldoc/formats/igc.xml create mode 100644 xmldoc/formats/ignrando.xml create mode 100644 xmldoc/formats/ik3d.xml create mode 100644 xmldoc/formats/kml.xml create mode 100644 xmldoc/formats/kompass_tk.xml create mode 100644 xmldoc/formats/kompass_wp.xml create mode 100644 xmldoc/formats/ktf2.xml create mode 100644 xmldoc/formats/kwf2.xml create mode 100644 xmldoc/formats/lmx.xml create mode 100644 xmldoc/formats/lowranceusr.xml create mode 100644 xmldoc/formats/mag_pdb.xml create mode 100644 xmldoc/formats/magellan.xml create mode 100644 xmldoc/formats/magellan1.xml create mode 100644 xmldoc/formats/magellanx.xml create mode 100644 xmldoc/formats/maggeo.xml create mode 100644 xmldoc/formats/magnav.xml create mode 100644 xmldoc/formats/mapconverter.xml create mode 100644 xmldoc/formats/mapsend.xml create mode 100644 xmldoc/formats/mapsource.xml create mode 100644 xmldoc/formats/msroute.xml create mode 100644 xmldoc/formats/msroute1.xml create mode 100644 xmldoc/formats/mtk-bin.xml create mode 100644 xmldoc/formats/mtk.xml create mode 100644 xmldoc/formats/mxf.xml create mode 100644 xmldoc/formats/navicache.xml create mode 100644 xmldoc/formats/navilink.xml create mode 100644 xmldoc/formats/netstumbler.xml create mode 100644 xmldoc/formats/nima.xml create mode 100644 xmldoc/formats/nmea.xml create mode 100644 xmldoc/formats/nmn4.xml create mode 100644 xmldoc/formats/openoffice.xml create mode 100644 xmldoc/formats/options/an1-color.xml create mode 100644 xmldoc/formats/options/an1-deficon.xml create mode 100644 xmldoc/formats/options/an1-nogc.xml create mode 100644 xmldoc/formats/options/an1-nourl.xml create mode 100644 xmldoc/formats/options/an1-radius.xml create mode 100644 xmldoc/formats/options/an1-road.xml create mode 100644 xmldoc/formats/options/an1-type.xml create mode 100644 xmldoc/formats/options/an1-wpt_type.xml create mode 100644 xmldoc/formats/options/an1-zoom.xml create mode 100644 xmldoc/formats/options/bcr-index.xml create mode 100644 xmldoc/formats/options/bcr-name.xml create mode 100644 xmldoc/formats/options/bcr-prefer_shortnames.xml create mode 100644 xmldoc/formats/options/bcr-radius.xml create mode 100644 xmldoc/formats/options/cetus-appendicon.xml create mode 100644 xmldoc/formats/options/cetus-dbname.xml create mode 100644 xmldoc/formats/options/compegps-deficon.xml create mode 100644 xmldoc/formats/options/compegps-index.xml create mode 100644 xmldoc/formats/options/compegps-radius.xml create mode 100644 xmldoc/formats/options/compegps-snlen.xml create mode 100644 xmldoc/formats/options/coto-zerocat.xml create mode 100644 xmldoc/formats/options/dg-100-erase.xml create mode 100644 xmldoc/formats/options/dmtlog-index.xml create mode 100644 xmldoc/formats/options/exif-filename.xml create mode 100644 xmldoc/formats/options/garmin-bitscategory.xml create mode 100644 xmldoc/formats/options/garmin-category.xml create mode 100644 xmldoc/formats/options/garmin-deficon.xml create mode 100644 xmldoc/formats/options/garmin-get_posn.xml create mode 100644 xmldoc/formats/options/garmin-power_off.xml create mode 100644 xmldoc/formats/options/garmin-resettime.xml create mode 100644 xmldoc/formats/options/garmin-snlen.xml create mode 100644 xmldoc/formats/options/garmin-snwhite.xml create mode 100644 xmldoc/formats/options/garmin_gpi-alerts.xml create mode 100644 xmldoc/formats/options/garmin_gpi-bitmap.xml create mode 100644 xmldoc/formats/options/garmin_gpi-category.xml create mode 100644 xmldoc/formats/options/garmin_gpi-descr.xml create mode 100644 xmldoc/formats/options/garmin_gpi-hide.xml create mode 100644 xmldoc/formats/options/garmin_gpi-notes.xml create mode 100644 xmldoc/formats/options/garmin_gpi-position.xml create mode 100644 xmldoc/formats/options/garmin_gpi-proximity.xml create mode 100644 xmldoc/formats/options/garmin_gpi-sleep.xml create mode 100644 xmldoc/formats/options/garmin_gpi-speed.xml create mode 100644 xmldoc/formats/options/garmin_gpi-unique.xml create mode 100644 xmldoc/formats/options/garmin_gpi-units.xml create mode 100644 xmldoc/formats/options/garmin_txt-date.xml create mode 100644 xmldoc/formats/options/garmin_txt-datum.xml create mode 100644 xmldoc/formats/options/garmin_txt-dist.xml create mode 100644 xmldoc/formats/options/garmin_txt-grid.xml create mode 100644 xmldoc/formats/options/garmin_txt-prec.xml create mode 100644 xmldoc/formats/options/garmin_txt-temp.xml create mode 100644 xmldoc/formats/options/garmin_txt-time.xml create mode 100644 xmldoc/formats/options/garmin_txt-utc.xml create mode 100644 xmldoc/formats/options/gdb-bitscategory.xml create mode 100644 xmldoc/formats/options/gdb-cat.xml create mode 100644 xmldoc/formats/options/gdb-roadbook.xml create mode 100644 xmldoc/formats/options/gdb-ver.xml create mode 100644 xmldoc/formats/options/gdb-via.xml create mode 100644 xmldoc/formats/options/geo-deficon.xml create mode 100644 xmldoc/formats/options/geo-nuke_placer.xml create mode 100644 xmldoc/formats/options/geoniche-category.xml create mode 100644 xmldoc/formats/options/geoniche-dbname.xml create mode 100644 xmldoc/formats/options/gpilots-dbname.xml create mode 100644 xmldoc/formats/options/gpspilot-dbname.xml create mode 100644 xmldoc/formats/options/gpssim-split.xml create mode 100644 xmldoc/formats/options/gpssim-wayptspd.xml create mode 100644 xmldoc/formats/options/gpx-gpxver.xml create mode 100644 xmldoc/formats/options/gpx-logpoint.xml create mode 100644 xmldoc/formats/options/gpx-snlen.xml create mode 100644 xmldoc/formats/options/gpx-suppresswhite.xml create mode 100644 xmldoc/formats/options/gpx-urlbase.xml create mode 100644 xmldoc/formats/options/html-altunits.xml create mode 100644 xmldoc/formats/options/html-degformat.xml create mode 100644 xmldoc/formats/options/html-encrypt.xml create mode 100644 xmldoc/formats/options/html-logs.xml create mode 100644 xmldoc/formats/options/html-stylesheet.xml create mode 100644 xmldoc/formats/options/igc-timeadj.xml create mode 100644 xmldoc/formats/options/ignrando-index.xml create mode 100644 xmldoc/formats/options/kml-deficon.xml create mode 100644 xmldoc/formats/options/kml-extrude.xml create mode 100644 xmldoc/formats/options/kml-floating.xml create mode 100644 xmldoc/formats/options/kml-labels.xml create mode 100644 xmldoc/formats/options/kml-line_color.xml create mode 100644 xmldoc/formats/options/kml-line_width.xml create mode 100644 xmldoc/formats/options/kml-lines.xml create mode 100644 xmldoc/formats/options/kml-max_position_points.xml create mode 100644 xmldoc/formats/options/kml-points.xml create mode 100644 xmldoc/formats/options/kml-trackdata.xml create mode 100644 xmldoc/formats/options/kml-trackdirection.xml create mode 100644 xmldoc/formats/options/kml-units.xml create mode 100644 xmldoc/formats/options/lowranceusr-break.xml create mode 100644 xmldoc/formats/options/lowranceusr-ignoreicons.xml create mode 100644 xmldoc/formats/options/lowranceusr-merge.xml create mode 100644 xmldoc/formats/options/lowranceusr-writeasicons.xml create mode 100644 xmldoc/formats/options/magellan-deficon.xml create mode 100644 xmldoc/formats/options/magellan-maxcmts.xml create mode 100644 xmldoc/formats/options/magellan1-baud.xml create mode 100644 xmldoc/formats/options/magellan1-deficon.xml create mode 100644 xmldoc/formats/options/magellan1-maxcmts.xml create mode 100644 xmldoc/formats/options/magellan1-noack.xml create mode 100644 xmldoc/formats/options/magellan1-nukewpt.xml create mode 100644 xmldoc/formats/options/magellanx-deficon.xml create mode 100644 xmldoc/formats/options/magellanx-maxcmts.xml create mode 100644 xmldoc/formats/options/mapsend-trkver.xml create mode 100644 xmldoc/formats/options/mapsource-mpsmergeout.xml create mode 100644 xmldoc/formats/options/mapsource-mpsusedepth.xml create mode 100644 xmldoc/formats/options/mapsource-mpsuseprox.xml create mode 100644 xmldoc/formats/options/mapsource-mpsverout.xml create mode 100644 xmldoc/formats/options/mapsource-snlen.xml create mode 100644 xmldoc/formats/options/mapsource-snwhite.xml create mode 100644 xmldoc/formats/options/mtk-bin-csv.xml create mode 100644 xmldoc/formats/options/mtk-csv.xml create mode 100644 xmldoc/formats/options/mtk-erase.xml create mode 100644 xmldoc/formats/options/navicache-noretired.xml create mode 100644 xmldoc/formats/options/navilink-nukerte.xml create mode 100644 xmldoc/formats/options/navilink-nuketrk.xml create mode 100644 xmldoc/formats/options/navilink-nukewpt.xml create mode 100644 xmldoc/formats/options/navilink-power_off.xml create mode 100644 xmldoc/formats/options/netstumbler-nseicon.xml create mode 100644 xmldoc/formats/options/netstumbler-nsneicon.xml create mode 100644 xmldoc/formats/options/netstumbler-seicon.xml create mode 100644 xmldoc/formats/options/netstumbler-sneicon.xml create mode 100644 xmldoc/formats/options/netstumbler-snmac.xml create mode 100644 xmldoc/formats/options/nmea-append_positioning.xml create mode 100644 xmldoc/formats/options/nmea-baud.xml create mode 100644 xmldoc/formats/options/nmea-date.xml create mode 100644 xmldoc/formats/options/nmea-get_posn.xml create mode 100644 xmldoc/formats/options/nmea-gisteq.xml create mode 100644 xmldoc/formats/options/nmea-gpgga.xml create mode 100644 xmldoc/formats/options/nmea-gpgsa.xml create mode 100644 xmldoc/formats/options/nmea-gprmc.xml create mode 100644 xmldoc/formats/options/nmea-gpvtg.xml create mode 100644 xmldoc/formats/options/nmea-pause.xml create mode 100644 xmldoc/formats/options/nmea-snlen.xml create mode 100644 xmldoc/formats/options/nmn4-index.xml create mode 100644 xmldoc/formats/options/osm-tag.xml create mode 100644 xmldoc/formats/options/osm-tagnd.xml create mode 100644 xmldoc/formats/options/ozi-pack.xml create mode 100644 xmldoc/formats/options/ozi-proximity.xml create mode 100644 xmldoc/formats/options/ozi-snlen.xml create mode 100644 xmldoc/formats/options/ozi-snunique.xml create mode 100644 xmldoc/formats/options/ozi-snupper.xml create mode 100644 xmldoc/formats/options/ozi-snwhite.xml create mode 100644 xmldoc/formats/options/ozi-wptbgcolor.xml create mode 100644 xmldoc/formats/options/ozi-wptfgcolor.xml create mode 100644 xmldoc/formats/options/palmdoc-bookmarks_short.xml create mode 100644 xmldoc/formats/options/palmdoc-dbname.xml create mode 100644 xmldoc/formats/options/palmdoc-encrypt.xml create mode 100644 xmldoc/formats/options/palmdoc-logs.xml create mode 100644 xmldoc/formats/options/palmdoc-nosep.xml create mode 100644 xmldoc/formats/options/pathaway-date.xml create mode 100644 xmldoc/formats/options/pathaway-dbname.xml create mode 100644 xmldoc/formats/options/pathaway-deficon.xml create mode 100644 xmldoc/formats/options/pathaway-snlen.xml create mode 100644 xmldoc/formats/options/pcx-cartoexploreur.xml create mode 100644 xmldoc/formats/options/pcx-deficon.xml create mode 100644 xmldoc/formats/options/quovadis-dbname.xml create mode 100644 xmldoc/formats/options/raymarine-location.xml create mode 100644 xmldoc/formats/options/saroute-controls.xml create mode 100644 xmldoc/formats/options/saroute-split.xml create mode 100644 xmldoc/formats/options/saroute-times.xml create mode 100644 xmldoc/formats/options/saroute-turns_important.xml create mode 100644 xmldoc/formats/options/saroute-turns_only.xml create mode 100644 xmldoc/formats/options/stmsdf-index.xml create mode 100644 xmldoc/formats/options/stmwpp-index.xml create mode 100644 xmldoc/formats/options/tef-routevia.xml create mode 100644 xmldoc/formats/options/text-altunits.xml create mode 100644 xmldoc/formats/options/text-degformat.xml create mode 100644 xmldoc/formats/options/text-encrypt.xml create mode 100644 xmldoc/formats/options/text-logs.xml create mode 100644 xmldoc/formats/options/text-nosep.xml create mode 100644 xmldoc/formats/options/text-splitoutput.xml create mode 100644 xmldoc/formats/options/tiger-genurl.xml create mode 100644 xmldoc/formats/options/tiger-iconismarker.xml create mode 100644 xmldoc/formats/options/tiger-margin.xml create mode 100644 xmldoc/formats/options/tiger-newmarker.xml create mode 100644 xmldoc/formats/options/tiger-nolabels.xml create mode 100644 xmldoc/formats/options/tiger-oldmarker.xml create mode 100644 xmldoc/formats/options/tiger-oldthresh.xml create mode 100644 xmldoc/formats/options/tiger-snlen.xml create mode 100644 xmldoc/formats/options/tiger-suppresswhite.xml create mode 100644 xmldoc/formats/options/tiger-unfoundmarker.xml create mode 100644 xmldoc/formats/options/tiger-xpixels.xml create mode 100644 xmldoc/formats/options/tiger-ypixels.xml create mode 100644 xmldoc/formats/options/tpg-datum.xml create mode 100644 xmldoc/formats/options/unicsv-datum.xml create mode 100644 xmldoc/formats/options/unicsv-grid.xml create mode 100644 xmldoc/formats/options/unicsv-utc.xml create mode 100644 xmldoc/formats/options/vcard-encrypt.xml create mode 100644 xmldoc/formats/options/wbt-erase.xml create mode 100644 xmldoc/formats/options/wfff-ahcicon.xml create mode 100644 xmldoc/formats/options/wfff-ahoicon.xml create mode 100644 xmldoc/formats/options/wfff-aicicon.xml create mode 100644 xmldoc/formats/options/wfff-aioicon.xml create mode 100644 xmldoc/formats/options/wfff-snmac.xml create mode 100644 xmldoc/formats/options/xcsv-datum.xml create mode 100644 xmldoc/formats/options/xcsv-prefer_shortnames.xml create mode 100644 xmldoc/formats/options/xcsv-snlen.xml create mode 100644 xmldoc/formats/options/xcsv-snunique.xml create mode 100644 xmldoc/formats/options/xcsv-snupper.xml create mode 100644 xmldoc/formats/options/xcsv-snwhite.xml create mode 100644 xmldoc/formats/options/xcsv-style.xml create mode 100644 xmldoc/formats/options/xcsv-urlbase.xml create mode 100644 xmldoc/formats/options/yahoo-addrsep.xml create mode 100644 xmldoc/formats/osm.xml create mode 100644 xmldoc/formats/ozi.xml create mode 100644 xmldoc/formats/palmdoc.xml create mode 100644 xmldoc/formats/pathaway.xml create mode 100644 xmldoc/formats/pcx.xml create mode 100644 xmldoc/formats/psitrex.xml create mode 100644 xmldoc/formats/psp.xml create mode 100644 xmldoc/formats/quovadis.xml create mode 100644 xmldoc/formats/raymarine.xml create mode 100644 xmldoc/formats/s_and_t.xml create mode 100644 xmldoc/formats/saplus.xml create mode 100644 xmldoc/formats/saroute.xml create mode 100644 xmldoc/formats/shape.xml create mode 100644 xmldoc/formats/sportsim.xml create mode 100644 xmldoc/formats/stmsdf.xml create mode 100644 xmldoc/formats/stmwpp.xml create mode 100644 xmldoc/formats/tabsep.xml create mode 100644 xmldoc/formats/tef.xml create mode 100644 xmldoc/formats/text.xml create mode 100644 xmldoc/formats/tiger.xml create mode 100644 xmldoc/formats/tmpro.xml create mode 100644 xmldoc/formats/tomtom.xml create mode 100644 xmldoc/formats/tomtom_asc.xml create mode 100644 xmldoc/formats/tomtom_itn.xml create mode 100644 xmldoc/formats/tpg.xml create mode 100644 xmldoc/formats/tpo.xml create mode 100644 xmldoc/formats/tpo2.xml create mode 100644 xmldoc/formats/tpo3.xml create mode 100644 xmldoc/formats/unicsv.xml create mode 100644 xmldoc/formats/vcard.xml create mode 100644 xmldoc/formats/vidaone.xml create mode 100644 xmldoc/formats/vitosmt.xml create mode 100644 xmldoc/formats/vitovtt.xml create mode 100644 xmldoc/formats/wbt-bin.xml create mode 100644 xmldoc/formats/wbt-tk1.xml create mode 100644 xmldoc/formats/wbt.xml create mode 100644 xmldoc/formats/wfff.xml create mode 100644 xmldoc/formats/xcsv.xml create mode 100644 xmldoc/formats/xmap.xml create mode 100644 xmldoc/formats/xmap2006.xml create mode 100644 xmldoc/formats/xmapwpt.xml create mode 100644 xmldoc/formats/xol.xml create mode 100644 xmldoc/formats/yahoo.xml create mode 100644 xmldoc/gpsbabel_man.xml create mode 100755 xmldoc/makedoc.in create mode 100755 xmldoc/old/extract create mode 100644 xmldoc/old/extract.xsl create mode 100644 xmldoc/old/readme.xml create mode 100644 xmldoc/readme.xml create mode 100644 xmlgeneric.c create mode 100644 xmlgeneric.h create mode 100644 xmltag.c create mode 100644 xol.c create mode 100644 yahoo.c create mode 100644 zlib/.cvsignore create mode 100644 zlib/ChangeLog create mode 100644 zlib/FAQ create mode 100644 zlib/Makefile.in.zlib create mode 100644 zlib/README create mode 100644 zlib/README.gpsbabel create mode 100644 zlib/adler32.c create mode 100644 zlib/algorithm.txt create mode 100644 zlib/compress.c create mode 100644 zlib/crc32.c create mode 100644 zlib/crc32.h create mode 100644 zlib/deflate.c create mode 100644 zlib/deflate.h create mode 100644 zlib/empty.in create mode 100644 zlib/gzio.c create mode 100644 zlib/infback.c create mode 100644 zlib/inffast.c create mode 100644 zlib/inffast.h create mode 100644 zlib/inffixed.h create mode 100644 zlib/inflate.c create mode 100644 zlib/inflate.h create mode 100644 zlib/inftrees.c create mode 100644 zlib/inftrees.h create mode 100644 zlib/trees.c create mode 100644 zlib/trees.h create mode 100644 zlib/uncompr.c create mode 100644 zlib/zconf.h create mode 100644 zlib/zconf.in.h create mode 100644 zlib/zlib.3 create mode 100644 zlib/zlib.h create mode 100644 zlib/zutil.c create mode 100644 zlib/zutil.h diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 000000000..1ead503aa --- /dev/null +++ b/.cvsignore @@ -0,0 +1,23 @@ +cscope.out +cscope.files + +gpsbabel +gpsbabel-debug +gpsbabel.exe +gpsbabel.fo +gpsbabel.html +gpsbabel.pdf +gpsbabel.spec + +readme.html + +Makefile +config.h +config.log +config.status + +CHANGELOG + +autom4te.cache +coldsync +pilot-link diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..be7d14f4c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,70 @@ +Authors, the people behind GPSBabel + +Chief Babel-Head: + +* Robert Lipe + +Major contributors: + +* Alex Mottram +* Olaf Klein +* Ronald L. Parker + +Other contributors and helpers: + +* Alan Bleasby +* Alan Porter +* Andrew Arensburger +* Andrew Kirmse +* Andy Armstrong +* Bernhard Spinnler +* Bruce Thompson +* Chris Jones +* Claus Broch +* Curtis E. Mills +* Dave Pawson +* Daniel Diaz Quintero +* Eric Cloninger +* Etienne Tasse +* Frank Warmerdam +* Fredie Kern +* Gary Paulson +* Gerhard Olsson +* Gunar Megger +* Gustavo Niemeyer +* Harald Nordius +* HSA Systems, Sven Dowideit +* Jason Rust +* Jeff Kalikstein +* Jeremy Atherton +* Jeremy Ehrhardt +* Jim Bensman +* Jochen Becker +* John Temples +* Jon McClintock +* Josh McKee +* Justin Broughton +* Kjeld Jensen +* Lilian Morinon +* Ling Nero +* Mark Bradley +* Mirko Parthey +* Oyvind Kaurstad +* P. Rosen +* Pasha Phares +* Patrick Ohly +* Paul Fox +* Paul Merchant +* Paul Tomblin +* Per Borgentun +* Richard Messeder +* Rick Richardson +* Robert Shaw +* Scott Brynen +* Sprok Bence +* Steve Chamberlin +* Sven Dovideit +* Tim Zickus +* Tobias Minich +* Tom Hughes +* Vladimir Nadvornik diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..514d6c73f --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 000000000..7da093f41 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,916 @@ +VPATH = @srcdir@ + +# version and release are defined in the head of configure.in +# don't forget 'autoconf' if you change them +VERSD=@GBMAJOR@.@GBMINOR@.@GBMICRO@ +VERSU=@GBMAJOR@_@GBMINOR@_@GBMICRO@ +RELEASE=@PACKAGE_RELEASE@ + +VERSIOND=$(VERSD)$(RELEASE) +VERSIONU=$(VERSU)$(RELEASE) + +DOCVERSION=@DOCVERSION@ +# DOCVERSION=development + +CC=@CC@ +EXEEXT=@EXEEXT@ + +# Resource compiler, currently used under MinGW +RC=@RC@ + +#EXTRA_LIBS -lefence + +# Space is significant, because MSVC wants no space between switch and arg (-Fofoo.o) +# but cc/gcc does: +# $(OUTPUT_SWITCH)main.o +# becomes -o main.o (gcc) +# or -Fomain.o (cl.exe) +OUTPUT_SWITCH=-o # + +# +# Enable either or both of these as you wish. +# +#OPTIMIZATION=-O $(EXTRA_OPTIMIZATION) +#DEBUGGING=-g $(EXTRA_DEBUGGING) +# add -DDEBUG_MEM to turn on memory allocation logging +GBCFLAGS=$(EXTRA_CFLAGS) $(DEBUGGING) -I. \ + $(OPTIMIZATION) @CFLAGS@ +LDFLAGS=$(EXTRA_LDFLAGS) @LDFLAGS@ +PREFIX=@prefix@ +INSTALL_DIR=$(DESTDIR)/$(PREFIX) + +# OTHER_ROOT=/opt/local # For DarwinPorts on OSX +# OTHER_ROOT=/sw # Uncomment For Fink on OS X. + +MINIMAL_FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o garmin.o \ + garmin_tables.o internal_styles.o nmea.o kml.o + +ALL_FMTS=$(MINIMAL_FMTS) gtm.o gpsutil.o pcx.o cetus.o copilot.o \ + gpspilot.o magnav.o \ + psp.o holux.o tmpro.o tpg.o tpo.o \ + xcsv.o gcdb.o tiger.o easygps.o quovadis.o \ + gpilots.o saroute.o navicache.o psitrex.o geoniche.o delgpl.o \ + ozi.o text.o html.o palmdoc.o netstumbler.o hsa_ndv.o \ + igc.o brauniger_iq.o shape.o hiketech.o glogbook.o coastexp.o \ + vcf.o overlay.o google.o xhtmlent.o lowranceusr.o an1.o tomtom.o \ + tef_xml.o maggeo.o pathaway.o vitosmt.o gdb.o bcr.o coto.o \ + ignrando.o stmwpp.o msroute.o cst.o nmn4.o mag_pdb.o compegps.o \ + yahoo.o unicsv.o wfff_xml.o garmin_txt.o axim_gpb.o gpssim.o \ + wbt-200.o stmsdf.o gtrnctr.o dmtlog.o raymarine.o alan.o vitovtt.o \ + ggv_log.o g7towin.o garmin_gpi.o lmx.o random.o xol.o dg-100.o \ + navilink.o mtk_logger.o ik3d.o osm.o destinator.o exif.o vidaone.o + +FMTS=@FMTS@ + +FILTERS=position.o radius.o duplicate.o arcdist.o polygon.o smplrout.o \ + reverse_route.o sort.o stackfilter.o trackfilter.o discard.o \ + nukedata.o interpolate.o transform.o + +JEEPS=jeeps/gpsapp.o jeeps/gpscom.o \ + jeeps/gpsmath.o jeeps/gpsmem.o \ + jeeps/gpsprot.o jeeps/gpsread.o \ + jeeps/gpsdevice.o jeeps/gpsdevice_ser.o jeeps/gpsdevice_usb.o \ + jeeps/gpsrqst.o jeeps/gpssend.o jeeps/gpsserial.o jeeps/gpsutil.o \ + jeeps/gpsusbread.o jeeps/gpsusbsend.o \ + jeeps/gpsusbcommon.o @OSJEEPS@ + +# Extra modules in Jeeps that we don't use +# jeeps/gpsfmt.o jeeps/gpsinput.o jeeps/gpsproj.o + + +@PALM_DB_CMT@PALM_DB=pdbfile.o + +SHAPE=shapelib/shpopen.o shapelib/dbfopen.o + +ZLIB=zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/deflate.o zlib/inffast.o \ + zlib/inflate.o zlib/infback.o zlib/inftrees.o zlib/trees.o \ + zlib/uncompr.o zlib/gzio.o zlib/zutil.o + +LIBOBJS = queue.o route.o waypt.o filter_vecs.o util.o vecs.o mkshort.o \ + csv_util.o strptime.o grtcirc.o vmem.o util_crc.o xmlgeneric.o \ + uuid.o formspec.o xmltag.o cet.o cet_util.o fatal.o rgbcolors.o \ + inifile.o garmin_fs.o gbsleep.o units.o @GBSER@ gbser.o \ + gbfile.o parse.o avltree.o \ + $(PALM_DB) $(GARMIN) $(JEEPS) $(SHAPE) @ZLIB@ $(FMTS) $(FILTERS) +OBJS = main.o globals.o $(LIBOBJS) @FILEINFO@ + +.c.o: + $(CC) @CPPFLAGS@ -c $(GBCFLAGS) $< $(OUTPUT_SWITCH)$@ + + + +# Directory of local web doc. Traditionally a sibling to the GPSBabel tree. +WEB=@DOCDIR@ + + +all: gpsbabel$(EXEEXT) + +gpsbabel$(EXEEXT): configure Makefile $(OBJS) @GPSBABEL_DEBUG@ + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) @LIBS@ @EXPAT_LIB@ @USB_LIBS@ $(OUTPUT_SWITCH)$@ + +gpsbabel-debug: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) @LIBS@ @EFENCE_LIB@ @EXPAT_LIB@ @USB_LIBS@ $(OUTPUT_SWITCH)$@ + +Makefile gbversion.h: Makefile.in config.status xmldoc/makedoc.in gbversion.h.in + CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +xcsv_tokens.gperf: xcsv_tokens.in + gperf -L ANSI-C -D -t $? > $@ + +config.status: configure + $(SHELL) config.status --recheck + +jeeps/gpslibusb.o: + $(CC) @CPPFLAGS@ -c $(GBCFLAGS) @USB_CFLAGS@ @srcdir@/jeeps/gpslibusb.c $(OUTPUT_SWITCH)$@ + +fileinfo.o: win32/gpsbabel.rc + $(RC) -o fileinfo.o win32/gpsbabel.rc + +clean: + rm -f $(OBJS) gpsbabel gpsbabel.exe + +configure: configure.in + autoconf + +tag: + cvs commit + cvs tag gpsbabel_@GBMAJOR@_@GBMINOR@_@GBMICRO@@PACKAGE_RELEASE@ + +more-clean: clean + tools/mkmoreclean + +check: + ./testo + +torture: + @echo "testo in progress... (basic data integrity test)" + @./testo + @echo "vtesto in progress... (valgrind is watching testo)" + @./vtesto + @echo "torture_test in progress... (shortname reduction)" + @./torture_test +# +# Because there are some "non-real" errors like "IGC: bad date" +# test-all does not stop on errors. +# Please inspect the log file (/tmp/gb-test-all.log) for segmentation +# faults, math overflows and other hard errors +# + @echo "test-all in progress... (read/write test between all possible formats)" + @./test-all -s -r reference/expertgps.gpx + +# +# This will only work on UNIX-like substances. +# +install: @INSTALL_DEBUG@ gpsbabel$(EXEEXT) + @mkdir -p $(INSTALL_DIR)/bin + install gpsbabel $(INSTALL_DIR)/bin/ + +install-debug: + @mkdir -p $(INSTALL_DIR)/bin + install gpsbabel-debug $(INSTALL_DIR)/bin/ + +# Nerdy release stuff that needs to work only on Linux. + +leaktest: + make EXTRA_CFLAGS=-DDEBUG_MEM + tools/cleardebug + ./testo + tools/memdebug | grep -v '^command line:' + +dep: + make clean && make EXTRA_CFLAGS="-MMD" && cat *.d */*.d > /tmp/dep && rm *.d */*.d + (echo -n "internal_styles.c: mkstyle.sh " ; echo style/*.style ; /bin/echo -e '\t./mkstyle.sh > internal_styles.c || (rm -f internal_styles.c ; exit 1)' ) >> /tmp/dep + echo Edit Makefile.in and bring in /tmp/dep + +$(WEB)/htmldoc-$(DOCVERSION)/readme.html: FORCE + mkdir -p $(WEB)/htmldoc-$(DOCVERSION) + perl xmldoc/makedoc + xmlwf xmldoc/readme.xml #check for well-formedness + xmllint --noout --valid xmldoc/readme.xml #validate + xsltproc \ + --stringparam base.dir "$(WEB)/htmldoc-$(DOCVERSION)/" \ + --stringparam root.filename "readme" \ + xmldoc/babelmain.xsl \ + xmldoc/readme.xml + chmod 755 tools/mkcapabilities + tools/mkcapabilities + +# +# The .fo and PDF versions depend on additional tools. +# 'fop' must be obtained from http://xmlgraphics.apache.org/fop/ +# 0.92beta seems to work OK, BUT. +# * If you have a package called 'docbook-xml-website' it's reported +# to prevent the build from working. Remove it. (Suse) +# * Sun Java seems to be required. GCJ 1.4.2 doesn't work. You can +# force Sun Java to be used by creating ~/.foprc with 'rpm_mode=' (Fedora) +# Get it from http://www.java.com +# The Hypnenation package must be installed from +# http://offo.sourceforge.net/hyphenation/index.html - be sure to get the +# version that corresponds to the version of FOP that you used above. +# The docbook XSL must be 1.71.1 or higher. +# * Remember to update /etc/xml/catalogs if you manually update this. +# +gpsbabel.fo: FORCE + perl xmldoc/makedoc + xmlwf xmldoc/readme.xml #check for well-formedness + xmllint --noout --valid xmldoc/readme.xml #validate + xsltproc -o $@ xmldoc/babelpdf.xsl xmldoc/readme.xml + +gpsbabel.pdf: gpsbabel.fo + fop -q -fo gpsbabel.fo -pdf gpsbabel.pdf + cp gpsbabel.pdf $(WEB)/htmldoc-$(DOCVERSION)/gpsbabel-$(DOCVERSION).pdf + + +gpsbabel.html: FORCE + xsltproc \ + --stringparam toc.section.depth "1" \ + --stringparam html.stylesheet \ + "http://www.gpsbabel.org/style3.css" \ + http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl \ + xmldoc/readme.xml > $@ || rm $@ + +readme.txt: gpsbabel.html + lynx -nolist -dump gpsbabel.html > $@ + +doc: gpsbabel $(WEB)/htmldoc-$(DOCVERSION)/readme.html gpsbabel.pdf # readme.txt + +FORCE: + +# file list for windows package +WINFILES = gpsbabel.exe mingw/libexpat.dll win32/GPSBabelGUI.exe win32/gui-2/README.gui \ + README.contrib AUTHORS COPYING gpsbabel.html + +# +# Do administrative-y things to the tree. Verify that everything is checked +# in and tagged. +# +release-sourcecheck: + cvs commit + ./chkdoc + make clean + rm -fr gpsbabel-$(VERSIOND) +#rjl make gpsbabel doc gpsbabel.html + @(. tools/functions && ask "Enter 'y' to tag the tree as gpsbabel_$(VERSIONU)." "y") && cvs tag -F gpsbabel_$(VERSIONU) ; exit 0 + cvs export -r gpsbabel_$(VERSIONU) -d gpsbabel-$(VERSIOND) gpsbabel + touch gpsbabel-$(VERSIOND)/internal_styles.c + +# +# Build the release tarball from the exported CVS tree, tweaking +# timestamps and including generated filess as needed. +# +release-tarball: gpsbabel.html +# rm -fr gpsbabel-$(VERSIOND) + cp -ap gpsbabel.html gpsbabel-$(VERSIOND)/ + tar czf /tmp/gpsbabel-$(VERSIOND).tar.gz gpsbabel-$(VERSIOND) +# cd /tmp ; tar xzf gpsbabel-$(VERSIOND).tar.gz + +release-rpm: + test -f gpsbabel.html + mkdir -p /tmp/dist/BUILD \ + /tmp/dist/RPMS /tmp/dist/SPECS \ + /tmp/dist/SOURCES /tmp/dist/SRPMS \ + /tmp/dist/TMP /tmp/dist/install + tools/mkspec $(WEB) $(VERSD) $(RELEASE) > /tmp/dist/SPECS/gpsbabel.spec + cp -ap gpsbabel.html gpsbabel-$(VERSIOND)/ + cp -ap CHANGELOG gpsbabel-$(VERSIOND)/ + rm -rf /tmp/dist/TMP/gpsbabel-$(VERSD) + rm -rf /tmp/dist/SOURCES/gpsbabel-$(VERSD).tgz + cp -apr gpsbabel-$(VERSIOND) /tmp/dist/TMP/gpsbabel-$(VERSD) + cd /tmp/dist/TMP ; tar --owner=0 --group=0 -czf ../SOURCES/gpsbabel-$(VERSD).tgz gpsbabel-$(VERSD) + rpmbuild -ba \ + --define "_topdir /tmp/dist" \ + --define "buildroot /tmp/dist/install" \ + /tmp/dist/SPECS/gpsbabel.spec + + +# +# The Windows executables are cross compiled from the exported CVS image. +# Do the build of that here and make a zip file for distribution. +# Do this build in a temporary tree that was a copy of the tagged one +# to avoid scribbling in the "real" one. +# +# The cross builds are built with mingw. http://mirzam.it.vu.nl/mingw +# and http://mingw.sourceforge.net are convenient sources for that. +# binutils, runtime, w32api, and gcc-core seem to be required. +# + +cross-configure: + CC=i386-mingw32-gcc LDFLAGS="-s" @srcdir@/configure --host=i386-pc-mingw32 --with-cet=all --with-expathdr=@srcdir@/mingw/include --with-libexpat=@srcdir@/mingw/lib + +release-winbuild: + rm -fr /tmp/gpsbabel-$(VERSIOND)-cross + cp -a gpsbabel-$(VERSIOND) /tmp/gpsbabel-$(VERSIOND)-cross + cd /tmp/gpsbabel-$(VERSIOND)-cross ; \ + CC=i386-mingw32-gcc LDFLAGS="-s" ./configure --host=i386-pc-mingw32 --with-cet=all --with-expathdr=mingw/include --with-libexpat=mingw/lib && make && \ + zip -j /tmp/gpsbabel-$(VERSIOND).zip $(WINFILES) + rm -fr /tmp/gpsbabel-$(VERSIOND)-cross + +release-upload: /tmp/gpsbabel-$(VERSIOND).tar.gz /tmp/gpsbabel-$(VERSIOND).zip /tmp/dist/SRPMS/gpsbabel-$(VERSIOND)-0.src.rpm /tmp/dist/RPMS/i386/gpsbabel-$(VERSIOND)-0.i386.rpm + @(. tools/functions && ask "Type 'yes' if you want to do the upload now" "yes" ) + curl -u anonymous:anonymous --upload-file /tmp/gpsbabel-$(VERSIOND).tar.gz ftp://upload.sf.net/incoming/ + curl -u anonymous:anonymous --upload-file /tmp/gpsbabel-$(VERSIOND).zip ftp://upload.sf.net/incoming/ + curl -u anonymous:anonymous --upload-file /tmp/dist/SRPMS/gpsbabel-$(VERSIOND).src.rpm ftp://upload.sf.net/incoming/ + curl -u anonymous:anonymous --upload-file /tmp/dist/RPMS/i386/gpsbabel-$(VERSIOND).i386.rpm ftp://upload.sf.net/incoming/ + +mac-upload: + curl -u anonymous:anonymous --upload-file GPSBabel+-$(VERSIOND).dmg ftp://upload.sf.net/incoming/ + +release: release-sourcecheck release-tarball release-winbuild release-rpm release-upload + +rpm: + tools/mkrpm $(WEB) $(VERSD) $(RELEASE) + +mac-release: + mkdir -p usr/bin usr/share/gpsbabel/doc + cp gpsbabel usr/bin/ + cp README* COPYING usr/share/gpsbabel/doc + tar cvzf gpsbabel-osx.tgz usr/bin/gpsbabel + curl -u anonymous:anonymous --upload-file gpsbabel-osx.tgz ftp://upload.sf.net/incoming/ + +msvc-build: + make CC=@CL.EXE DEBUGGING="" EXTRA_CFLAGS="-nologo -W3 -WL -D__WIN32__ -I msvc/expat " OUTPUT_SWITCH="-Fo" $(OBJS) + echo $(OBJS) > objs.lst + LINK.EXE /NOLOGO @objs.lst ./msvc/expat/libexpat.lib /out:gpsbabel.exe + +# release check using CVS tree +test-release: doc gpsbabel.html + cvs export -r HEAD -d gpsbabel-$(VERSIOND) gpsbabel + rm -f gpsbabel-$(VERSIOND)/internal_styles.c + make release-tarball release-winbuild release-rpm + +# Machine generated from here down. +alan.o: alan.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h +an1.o: an1.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h an1sym.h +arcdist.o: arcdist.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h +avltree.o: avltree.h avltree.c defs.h gbtypes.h config.h +axim_gpb.o: axim_gpb.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +bcr.o: bcr.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h garmin_tables.h +brauniger_iq.o: brauniger_iq.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbser.h +cet.o: cet.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h +cetus.o: cetus.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h pdbfile.h +cet_util.o: cet_util.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h cet/ansi_x3_4_1968.h \ + cet/iso_8859_1.h cet/iso_8859_15.h cet/cp1252.h cet/iso_8859_2.h \ + cet/cp1250.h cet/latin_greek_1.h cet/macintosh.h cet/cp1251.h \ + cet/cp1253.h cet/cp1254.h cet/cp1255.h cet/cp1256.h cet/cp1257.h \ + cet/ibm437.h cet/ibm850.h cet/ibm851.h cet/ibm852.h cet/ibm855.h \ + cet/ibm857.h cet/ibm860.h cet/ibm861.h cet/ibm862.h cet/ibm863.h \ + cet/ibm864.h cet/ibm865.h cet/ibm868.h cet/ibm869.h cet/iso_8859_10.h \ + cet/iso_8859_13.h cet/iso_8859_14.h cet/iso_8859_3.h cet/iso_8859_4.h \ + cet/iso_8859_5.h cet/iso_8859_6.h cet/iso_8859_7.h cet/iso_8859_8.h \ + cet/iso_8859_9.h cet/koi8_r.h cet/koi8_ru.h cet/koi_8.h +coastexp.o: coastexp.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h uuid.h +compegps.o: compegps.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h \ + jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h +copilot.o: copilot.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h pdbfile.h +coto.o: coto.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h grtcirc.h pdbfile.h +cst.o: cst.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h strptime.h +csv_util.o: csv_util.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h grtcirc.h \ + strptime.h jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h xmlgeneric.h xcsv_tokens.gperf garmin_fs.h +delgpl.o: delgpl.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +discard.o: discard.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h +dmtlog.o: dmtlog.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ + xmlgeneric.h +duplicate.o: duplicate.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h +easygps.o: easygps.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +exif.o: exif.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h garmin_tables.h \ + strptime.h +fatal.o: fatal.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +filter_vecs.o: filter_vecs.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + filterdefs.h +formspec.o: formspec.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +g7towin.o: g7towin.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h garmin_fs.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h garmin_tables.h jeeps/gpsmath.h strptime.h +garmin.o: garmin.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ + garmin_tables.h garmin_fs.h +garmin_fs.o: garmin_fs.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h garmin_fs.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h garmin_tables.h +garmin_gpi.o: garmin_gpi.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ + garmin_fs.h jeeps/gps.h garmin_gpi.h +garmin_tables.o: garmin_tables.c garmin_tables.h defs.h config.h queue.h \ + gbtypes.h zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h +garmin_txt.o: garmin_txt.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h garmin_fs.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h garmin_tables.h grtcirc.h jeeps/gpsmath.h strptime.h +gbfile.o: gbfile.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +gbser.o: gbser.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbser.h \ + gbser_private.h +gbser_posix.o: gbser_posix.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbser.h \ + gbser_private.h +gbsleep.o: gbsleep.c config.h +gcdb.o: gcdb.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h pdbfile.h +gdb.o: gdb.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h garmin_fs.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ + garmin_tables.h grtcirc.h jeeps/gpsmath.h +geo.o: geo.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +geoniche.o: geoniche.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h pdbfile.h \ + jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h garmin_tables.h +ggv_log.o: ggv_log.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h \ + jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h +globals.o: globals.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbversion.h +glogbook.o: glogbook.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +google.o: google.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +gpilots.o: gpilots.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h garmin_tables.h \ + pdbfile.h +gpspilot.o: gpspilot.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h pdbfile.h +gpssim.o: gpssim.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +gpsutil.o: gpsutil.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h magellan.h +gpx.o: gpx.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h garmin_fs.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h +grtcirc.o: grtcirc.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +gtm.o: gtm.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +gtrnctr.o: gtrnctr.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +hiketech.o: hiketech.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +holux.o: holux.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h holux.h +hsa_ndv.o: hsa_ndv.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +html.o: html.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +igc.o: igc.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h +ignrando.o: ignrando.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +ik3d.o: ik3d.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +inifile.o: inifile.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +internal_styles.o: internal_styles.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +interpolate.o: interpolate.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + filterdefs.h grtcirc.h +kml.o: kml.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +lowranceusr.o: lowranceusr.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +maggeo.o: maggeo.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h \ + magellan.h +magnav.o: magnav.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h pdbfile.h +mag_pdb.o: mag_pdb.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h pdbfile.h \ + jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +magproto.o: magproto.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h magellan.h gbser.h +main.o: main.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h filterdefs.h csv_util.h +mapsend.o: mapsend.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h mapsend.h magellan.h +mapsource.o: mapsource.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h garmin_tables.h \ + jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h +mkshort.o: mkshort.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +msroute.o: msroute.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +mtk_logger.o: mtk_logger.c defs.h config.h queue.h gbtypes.h \ + gbfile.h cet.h cet_util.h inifile.h gbser.h +navicache.o: navicache.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +netstumbler.o: netstumbler.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h +nmea.o: nmea.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h gbser.h strptime.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +nmn4.o: nmn4.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h +nukedata.o: nukedata.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h +osm.o: osm.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h \ + avltree.h +overlay.o: overlay.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +ozi.o: ozi.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h +palmdoc.o: palmdoc.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ + pdbfile.h +parse.o: parse.c defs.h config.h queue.h gbtypes.h jeeps/gpsmath.h +pathaway.o: pathaway.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h strptime.h \ + pdbfile.h +pcx.o: pcx.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h garmin_tables.h csv_util.h +pdbfile.o: pdbfile.h pdbfile.c defs.h queue.h gbfile.h +polygon.o: polygon.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h +position.o: position.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h +psitrex.o: psitrex.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h garmin_tables.h +psp.o: psp.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h grtcirc.h +queue.o: queue.c queue.h +quovadis.o: quovadis.c quovadis.h defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + pdbfile.h +radius.o: radius.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h +random.o: random.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h \ + jeeps/gpsmath.h +raymarine.o: raymarine.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h +reverse_route.o: reverse_route.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + filterdefs.h +rgbcolors.o: rgbcolors.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +route.o: route.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +saroute.o: saroute.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +shape.o: shape.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h shapelib/shapefil.h +smplrout.o: smplrout.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h +sort.o: sort.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h filterdefs.h +stackfilter.o: stackfilter.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + filterdefs.h +stmsdf.o: stmsdf.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h strptime.h \ + jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h grtcirc.h +stmwpp.o: stmwpp.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h +strptime.o: strptime.c strptime.h +tef_xml.o: tef_xml.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +text.o: text.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +tiger.o: tiger.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h +tmpro.o: tmpro.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h +tomtom.o: tomtom.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +tpg.o: tpg.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +tpo.o: tpo.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +trackfilter.o: trackfilter.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + filterdefs.h strptime.h grtcirc.h +transform.o: transform.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h +unicsv.o: unicsv.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h garmin_fs.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h garmin_tables.h jeeps/gpsmath.h strptime.h +units.o: units.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +util_crc.o: util_crc.c +util.o: util.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +uuid.o: uuid.c uuid.h +vcf.o: vcf.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +vecs.o: vecs.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h +vidaone.o: vidaone.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +vitosmt.o: vitosmt.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +vitovtt.o: vitovtt.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +vmem.o: vmem.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h +waypt.o: waypt.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +wbt-200.o: wbt-200.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbser.h grtcirc.h +wfff_xml.o: wfff_xml.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +xcsv.o: xcsv.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +xhtmlent.o: xhtmlent.c +xmlgeneric.o: xmlgeneric.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +xmltag.o: xmltag.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +xol.o:xol.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h \ + jeeps/gpsmath.h garmin_tables.h +yahoo.o: yahoo.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +jeeps/gpsapp.o: jeeps/gpsapp.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbint.h +jeeps/gpscom.o: jeeps/gpscom.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h +jeeps/gpsdevice.o: jeeps/gpsdevice.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsserial.h +jeeps/gpsdevice_ser.o: jeeps/gpsdevice_ser.c jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/../defs.h jeeps/../config.h jeeps/../queue.h \ + jeeps/../gbtypes.h jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h \ + jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h \ + jeeps/../inifile.h jeeps/gpsport.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsserial.h +jeeps/gpsdevice_usb.o: jeeps/gpsdevice_usb.c jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/../defs.h jeeps/../config.h jeeps/../queue.h \ + jeeps/../gbtypes.h jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h \ + jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h \ + jeeps/../inifile.h jeeps/gpsport.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbint.h \ + jeeps/gpsusbcommon.h +jeeps/gpslibusb.o: jeeps/gpslibusb.c config.h jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbcommon.h +jeeps/gpsmath.o: jeeps/gpsmath.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsdatum.h +jeeps/gpsmem.o: jeeps/gpsmem.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h +jeeps/gpsprot.o: jeeps/gpsprot.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h +jeeps/gpsread.o: jeeps/gpsread.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsserial.h +jeeps/gpsrqst.o: jeeps/gpsrqst.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h +jeeps/gpssend.o: jeeps/gpssend.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsserial.h +jeeps/gpsserial.o: jeeps/gpsserial.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsserial.h jeeps/../gbser.h +jeeps/gpsusbcommon.o: jeeps/gpsusbcommon.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbcommon.h +jeeps/gpsusbread.o: jeeps/gpsusbread.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbint.h +jeeps/gpsusbsend.o: jeeps/gpsusbsend.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbint.h +jeeps/gpsutil.o: jeeps/gpsutil.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h +shapelib/dbfopen.o: shapelib/dbfopen.c shapelib/shapefil.h config.h +shapelib/shpopen.o: shapelib/shpopen.c shapelib/shapefil.h config.h +zlib/adler32.o: zlib/adler32.c zlib/zlib.h zlib/zconf.h +zlib/compress.o: zlib/compress.c zlib/zlib.h zlib/zconf.h +zlib/crc32.o: zlib/crc32.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/crc32.h +zlib/deflate.o: zlib/deflate.c zlib/deflate.h zlib/zutil.h zlib/zlib.h \ + zlib/zconf.h +zlib/gzio.o: zlib/gzio.c zlib/zutil.h zlib/zlib.h zlib/zconf.h +zlib/infback.o: zlib/infback.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/inftrees.h zlib/inflate.h zlib/inffast.h zlib/inffixed.h +zlib/inffast.o: zlib/inffast.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/inftrees.h zlib/inflate.h zlib/inffast.h +zlib/inflate.o: zlib/inflate.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/inftrees.h zlib/inflate.h zlib/inffast.h zlib/inffixed.h +zlib/inftrees.o: zlib/inftrees.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/inftrees.h +zlib/trees.o: zlib/trees.c zlib/deflate.h zlib/zutil.h zlib/zlib.h \ + zlib/zconf.h zlib/trees.h +zlib/uncompr.o: zlib/uncompr.c zlib/zlib.h zlib/zconf.h +zlib/zutil.o: zlib/zutil.c zlib/zutil.h zlib/zlib.h zlib/zconf.h +internal_styles.c: mkstyle.sh style/arc.style style/cambridge.style style/csv.style style/cup.style style/custom.style style/dna.style style/fugawi.style style/garmin301.style style/garmin_poi.style style/geonet.style style/gpsdrive.style style/gpsdrivetrack.style style/gpsman.style style/kompass_tk.style style/kompass_wp.style style/ktf2.style style/kwf2.style style/mapconverter.style style/mxf.style style/nima.style style/openoffice.style style/s_and_t.style style/saplus.style style/sportsim.style style/tabsep.style style/tomtom_asc.style style/tomtom_itn.style style/xmap2006.style style/xmap.style style/xmapwpt.style + ./mkstyle.sh > internal_styles.c || (rm -f internal_styles.c ; exit 1) diff --git a/README.contrib b/README.contrib new file mode 100644 index 000000000..6e447a29d --- /dev/null +++ b/README.contrib @@ -0,0 +1,114 @@ +If you're interested in contributing to this program, here are some +guidelines. Mail patches to gpsbabel-code@lists.sourceforge.net for +consideration and integration. + +Rules to Live By +---------------- + +Standards are good. ISO C and POSIX are greatly preferred. + +Reuse is good, if doing so is not onerous. For example, using the expat +libraries vastly simplifies the XML parsers while increasing their +robustness plus those libraries are ubiquitous. So I consider it OK to +require expat. + +You may find format_skeleton.c and filter_skeleton.c in the source tree +to be helpful examples. Just add meat! + +Compilers complain for a reason. Code shouldn't emit warnings. + +The entire world doesn't run . I've tested this code on +at least five different OSes. If you find yourself wanting to insert +compiler or OS specific magic, please resist. + +Coding consistency is encouraged. The reality is we have a lot of code +that was written by different authors. Some code from other projects is +included. We don't have immutable rules about code style (indention, +curly location, whitespace rules, etc.) but we do ask that you try to +match what is around any code you modify. "When in Rome..." + +If writing new code, we'd prefer a style like: + + int + mumble(int whatever) + { + if (whatevever) { + return blah; + } + } + +...but if you're submitting a new source file that you intend to +maintain and are convinced that two space indents will make the world a +better place, knock yourself out. But if you need to add a line of code +to the above before "return blah" and do it with spaces instead of hard +tabs, that would be bad. + +Submitting Patches +------------------ + +If you are creating a new target you should submit patches (use +"cvs diff -uN" to create patches) to the following files: +* Yourcode.c and/or Yourcode.h - this is the code required to do your + conversions and any support files that your code requires. +* vecs.c - an updated vecs.c file implementing your conversion code into + GPSBabel. +* Makefile - an updated Makefile telling the compiler how to build and link + your conversion into GPSBabel +* testo - an updated script that tests your conversion (this should produce + no output if all is good, see the current testo script for examples) +* YourOutput - a sample file of code produced by your function (used in testo + and lives in a directory called "reference"). +* Documentation - see below. + +Please ensure that you are building and testing against the latest code +from the top of the CVS tree and that any code you modify is the latest +version from the CVS - Note: code changes sometimes occur frequently! + +Documentation +------------- + +HTML and text documentation are generated automatically from DocBook +source located in the "xmldoc" directory. That directory contains +two subdirectories of interest: "formats" and "filters". If your +contribution adds or affects a format, you'll want to be in the "formats" +directory. Otherwise, you'll want to be in the "filters" directory. + +You should contribute a file called "yourname.xml", where "yourname" is the +name you would give on the command-line to invoke your new format or filter. +For example, the arc filter is documented in "filters/arc.xml". + +This file contains a general description of your format or filter, any +limitations in your support for it, and anything else the end user should +know. For file formats, links to manufacturers' websites are encouraged. +The contents of this file are not valid or even well-formed XML on their own; +they are included into a larger framework. If you know DocBook, you should +ensure that the contents of this file will validate if included in a
. +If you do not know DocBook, see the other files in this directory for examples +or see http://docbook.org/tdg/en/html/docbook.html for the gory details. Tags +of interest will almost certainly include for paragraphs, + for web links, and for +example command lines. + +For each option supported by your format or filter, you should also contribute +a file in the "options" subdirectory called "yourname-youroption.xml", again +using the names you would use on the command line to invoke your format or +filter with that particular option. For example, the "distance" option to the +"arc" filter is documented in "filters/options/arc-distance.xml". These +files are similar to the general description above, and should meet the same +validation requirements. + +As of this writing, there are two formats that violate this rule: Magellan +serial and Microsoft Streets & Trips. Because those formats have the same +names as other formats, their descriptions are located in "magellan1.xml" and +"msroute1.xml" respectively. These are special cases, and you should do your +best to ensure that they remain the only special cases. + +Note that the automated framework already includes the name and description of +your format and its options as described in vecs.c and yourcode.c, so there is +no need to repeat that information in your documentation. + + +Enjoy! + +Robert Lipe, +robertlipe@usa.net diff --git a/README.igc b/README.igc new file mode 100644 index 000000000..af057a340 --- /dev/null +++ b/README.igc @@ -0,0 +1,127 @@ +IGC Data Format Notes. +====================== +Refer to Appendix 1 of http://www.fai.org:81/gliding/gnss/tech_spec_gnss.asp +for the specification of the IGC data format. + +A sample list of software applications that use data in IGC format can be +found at http://www.fai.org:81/gliding/gnss/gnss_analysis_software.pdf + +GPSBabel can be used to translate data in IGC format to and from various other +formats. + +Routes in other formats are used to represent IGC task declarations. +Tracks in other formats are used to represent IGC recorded flights. + + + +Converting to IGC format +======================== +IGC files generated by GPSBabel will NOT pass security validation tests since +the data they contain cannot be proven to originate from an approved flight +recorder. For most software applications that use IGC files this is not an +issue but for competition scoring, record and badge claims the generated files +will not be accepted as proof of a flight. + +A track stored in another format (GPX for example) representing a recorded +flight can be converted into an IGC file: + + gpsbabel -i gpx -f mytrk.gpx -o igc -F myflight.igc + +If multiple track segments are provided in the input file, the one with the +most points will be used. + +A route stored in another format representing a task declaration can be +converted into an IGC file: + + gpsbabel -i gpx -f myrte.gpx -o igc -F mytask.igc + +A route and a track in other formats can be included into a single IGC file: + + gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -o igc -F myflight.igc + +A similar result can be obtained by downloading the track log and routes +directly from a GPS device connected to a PC. For example to create an IGC +file from data recorded in a Garmin GPS connected to the first serial port of +a PC running Linux: + + gpsbabel -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc + +For Windows operating systems: + + gpsbabel -t -r -i garmin -f com1 -o igc -F myflight.igc + +A waypoint file in another format containing a waypoint whose short name is +"PILOT" can be merged into an IGC file. The description field of the waypoint +will be used for the pilot name in the IGC file header: + + gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -f mywpt.gpx -o igc -F myflight.igc + gpsbabel -w -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc + +Some formats such as GPX allow routes, tracks and waypoints to exist in the +same file and can be used to fully populate an IGC file: + + gpsbabel -i gpx -f myall.gpx -o igc -F myflight.igc + + + +Converting from IGC format +========================== +Data in an IGC file can be converted into other formats. For example to +generate OziExplorer files containing tracks representing the recorded +flight (myozi.plt) and routes representing declared tasks (myozi.rte): + + gpsbabel -i igc -f myflight.igc -o ozi -F myozi + +Or to GPX format: + + gpsbabel -i igc -f myflight.igc -o gpx -F myflight.gpx + +Header information from the IGC file will be written to the description field +of the track(s). + +If both pressure altitude and GNSS altitude are recorded in the IGC file, two +tracks will be written to the new track file, representing the two altitude +tracks. The latitude, longitude and timestamps in the tracks will be identical. + + +Merging into IGC format +======================= +A route stored in another format can be merged with an existing IGC file that +has no task declaration, to generate a new IGC file with a task declaration: + + gpsbabel -i igc -f myflight.igc -i gpx -f myrte.gpx -o igc -F mynew.igc + +A two dimensional (lat/lon) track recorded during a flight by a GPS receiver +can be merged with a one dimensional (altitude) track recorded during the same +flight by a barograph instrument. The result is a three dimensional IGC file +representing the flight: + + gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc -F my3D.igc + +Sometimes there is a discrepancy between the internal clock in the barograph +instrument and GPS time which can result in the altitude and ground positions +not correlating correctly. This can be corrected manually by passing the time +difference in seconds between the two time domains through the "timeadj" +parameter. This can be any positive or negative integer: + + gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=27 -F my3D.igc + +GPSBabel can also attempt to deduce the time difference automatically. This +is done by comparing the time that it thinks that you landed on the GPS track +and the barograph and adjusting accordingly: + + gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc + +The same can be acheived by downloading directly from a barograph instrument +supported by GPSBabel. For example with a Brauniger IQ Comp GPS variometer: + + gpsbabel -i baroiq -f /dev/ttyS0 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc + +or: + + gpsbabel -i baroiq -f com1 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc + + + +Chris Jones +Aug 2004 diff --git a/README.magnav b/README.magnav new file mode 100644 index 000000000..c0cf42e70 --- /dev/null +++ b/README.magnav @@ -0,0 +1,28 @@ +Translating NAV Companion waypoints to another format is as easy +as with any other format. Just find the Companion_Waypoints database +in your palm backup directory and use it as the input file. + +When translating waypoints back to NAV Companion, though, you need +to jump through some hoops: + +First, you must merge any waypoints that already exist in the database +in your Palm Backup directory with the ones you are adding; failure to +do so will result in only the new points being available in NAV Companion, +even if you give the new database a different name (it will overwrite +the old database, even in your backup directory. That's a feature of +PalmOS, not of NAV Companion.) + +To merge the databases, use a command line like the following: + +gpsbabel -i magnav -f Companion_Waypoints.PDB -i geo -f geocaching.loc -o magnav -F merged.pdb + +Second, you must use the installer to install your new PDB file. Don't +make the mistake of copying it over the existing Companion_Waypoints.PDB +file; the one on the handheld will overwrite it rather than merging with +it. + +Finally, because NAV Companion is not designed to work with desktop +applications, you must tell NAV Companion that its waypoints database +has changed out from under it. One way to do this is to go to the +waypoints screen and attempt to scroll; that will force it to reread +the database and fix the record pointers that it keeps on the heap. diff --git a/README.mapconverter b/README.mapconverter new file mode 100644 index 000000000..9c0791d43 --- /dev/null +++ b/README.mapconverter @@ -0,0 +1,35 @@ +Mapconverter is an application used to create userland maps and map data for +Mapopolis.com's Mapopolis program. The mapconverter format is essentially +waypoint data prepared in a format that the mapconverter application will +accept. + +The steps for using GPSBabel and Mapconverter go something like this: + +Step 1: Create a mapconverter file using gpsbabel. + ./gpsbabel -i geo -f geocaching.loc -o mapconverter -F foo.txt + +Step 2: Launch mapconverter.exe and choose foo.txt as your input file. + Click the begin button to have mapconverter process foo.txt. + +If all goes successfully, you should have a file called "foo.pdb" ready +for syncing with your PDA. Put it wherever Mapopolis thinks it should be +on your PDA. + +NOTES: + +o GPSBabel will write the name of its own output file in the output file + it creates as the input for Mapconverter. Mapconverter will replace + the extension of this filename with ".pdb". + +o The PocketPC version of Mapopolis doesn't notice files with the ".pdb" + extension. To make this work, change the extension to ".mlp" when + copying the mapconverter output to your PocketPC PDA. + +o Mapconverter only works with Mapopolis version 3.x. Mapopolis version + 4 will refuse to load mapconverter maps. There is no known work-around + for this at the time of this writing. + +o Mapconverter is no longer available from the Mapopolis website. If you + need a copy of mapconverter, ask on your local GPS Software discussion + forum and I'm sure someone will have it. As far as I know, It was never + actually acknowledged/supported by Mapopolis to begin with. diff --git a/README.psp b/README.psp new file mode 100644 index 000000000..ab15d0969 --- /dev/null +++ b/README.psp @@ -0,0 +1,112 @@ +MS Pocketstreets 2002/2003 Pushpins (.PSP) Q & A +------------------------------------------------ + +Q: Why should I use gpsbabel/psp to make pushpins when Streets & Trips (S&T) + already does that for me? + +A: gpsbabel/psp has the advantage of being able to create pushpins WITHOUT + creating the associated map file and the need to "import" the waypoint + data into S&T. Through a series of scripts, you can create a dozen + or so PSP files in a few seconds as opposed to a few weeks using the + S&T interface. The maps are not going to change between sessions, + only the pins will. Why waste all that time creating maps when all you + really want are updated pins? As an aside, gpsbabel/psp creates points + WITH THE PROPER coordinates where S&T does not in some areas of the U.S. + (Nashville, TN for instance). + + +Q: I keep getting a blank (32 byte) PSP file? + +A: There are either no points to write, or you have botched the command + line for gpsbabel. gpsbabel is sensitive to UPPER and lower case + on the command line. A simple command line to create PSP files + looks like this: + + gpsbabel -i geo -f geocaching.loc -o psp -F NewOrleans.psp + + Note the use of "-f" for INPUT files and "-F" for OUTPUT files. + + +Q: I've created a PSP file, now what do I do with it? + +A: To use pushpins in Pocketstreets, you need to have both a map and a + pushpin file. These two files must exist in the same folder and have + exactly the same base name as the map. For example, the pins that + correspond to the map "NewOrleans.mps" should be named "NewOrleans.psp". + + +Q: I don't have a map? What do I do now? + +A: Create one using the "Export map to Pocketstreets" option in S&T. You + can also pick up some major city maps on the web from the MS Pocketstreets + website if you are interested in seeing how it works. + + +Q: I have .EST files, not .PSP files. What's up with that? + +A: In order to make PSP files, you need to use the "Export map to + Pocketstreets" function in S&T. .EST files are for use in S&T, not + Pocketstreets. + + +Q: The .PSP files differ when I use gpsbabel/psp versus Pocketstreets to + create them. What's up? + +A: Pocketstreets makes corrections to the S&T waypoint data upon initial + loading. gpsbabel/psp writes PSP files with these corrections already made. + Ask MS. + + +Q: Does gpsbabel/psp work with (Autoroute, Mappoint, etc..) .PSP files? + +A: As of this writing, I haven't seen any so I can't be sure. If they + follow the same layout as S&T 2002, I'd imagine so. + + +Q: Does gpsbabel/psp work with (S&T 2001, S&T 2002, etc...) files? + +A: MS the file layout between S&T 2001 and S&T 2002. The gpsbabel psp + module is known to work fine with S&T 2002 and 2003. + + +Q: Does gpsbabel/psp work with (insert your country/location here) maps? + +A: If it doesn't, feel free to email the PSP files to me at: + geo_alexm at cox-internet.com. I only had USA based data to work + with while figuring out the file layout. Please include as much + information about the points as possible (lat/long, name, etc..) + and do it in English. I don't read or speak any other languages + fluently. + + +Q: What do you mean S&T writes points with the wrong coordinates? + +A: At some point in the "Export map to Pocketstreets" function in S&T, + it goofs the lat/long data. Points in Nashville tended to shift + 1.4 miles WEST of their original location. I'm not a geometry buff, + but I'd imagine they have a reference point for generating coordinates + that's wrong in (at least) that area. + + +Q: I have 800 waypoints that cover a dozen or so Pocketstreets maps. + Do I need to to split my points up into smaller chunks to match the + area covered by the maps? + +A: No. Pocketstreets will "ignore" points that are outside of the map + area. Points that are not on the current map will be "grayed out" + in pushpin explorer in Pocketsreets. This is the reason the PSP + module was written for gpsbabel in the first place. + + +Q: Where can I find documentation for the layout of PSP files? + +A: Just about everything I know about the PSP file format is documented + in the source. To the best of my knowledge, there is no documentation + (and for good reason, I've come to discover). + + +Q: I have some other problem, what do I do? + +A: Email me at geo_alexm at cox-internet.com and I'll see if I can + work it out. + diff --git a/README.xmapwpt b/README.xmapwpt new file mode 100644 index 000000000..6e8539c1e --- /dev/null +++ b/README.xmapwpt @@ -0,0 +1,66 @@ + +NOTE: THIS README PERTAINS TO THE "XMAPWPT" FORMAT, NOT THE XMAP/TOPO USA + 4.0 CONDUIT "XMAP" FORMAT. + + +Delorme XMap Handheld .WPT for PocketPC is a bit of a kludge. This +document covers XMap Handheld Street Atlas USA edition. + +XMap on the PocketPC stores it's waypoints in individual .wpt files. +For example, waypoints generated by XMap on the PocketPC are stored +by default in the "My Documents" folder using the sequential names +"XMap1.wpt", "XMap2.wpt", ad nauseum. Needless to say, not very +efficient. + +As writing multiple waypoint files is outside of the scope of gpsbabel, +gpsbabel chooses to write one big file, one waypoint per line. +Extracting lines from this file is left as an exercise for the end user. +A simple perl script to handle this conversion is included at the end +of this README. + +It should also be noted that READING multiple files is indeed possible, +but if you have more than a few points, it can be a task. For example: + +gpsbabel -i xmapwpt -f Xmap1.wpt -f Xmap2.wpt -o mapsend -F mapsend.wpt + +will read the two Xmap .wpt files and write one mapsend file. This +is fine for a small handful of points, but could be quite cumbersome +for folks like me who have 100+ waypoints loaded into XMap. For *nix +folks, something as simple as: + +cat *.wpt > /tmp/foo.wpt +gpsbabel -i xmapwpt -f foo.wpt -o mapsend -F mapsend.wpt + +will do the trick just fine. + + +############ BEGIN SCRIPT +#!/full/path/to/perl +$INPUTFILE = @ARGV[0]; +$TARGETDIR = @ARGV[1]; +$FILENAME = @ARGV[2]; + +if (! $FILENAME) { + print "Usage: xmap_split.pl INPUT_FILE OUTPUT_DIRECTORY FILENAME_BASE\n"; + print " (i.e. xmapl_split.pl points.wpt /tmp/points GPSB)\n"; + print " (created GPSB0001-GPSBXXXX in /tmp/points/ from points.wpt)\n"; + exit; +} + +open (INFILE, $INPUTFILE) || die "Cannot open $INPUTFILE for read!\n"; + +while () { + $lc++; + $filename = sprintf("%s/Gpsb%04d.wpt", $TARGETDIR, $lc); + + open (OUTFILE, ">$filename") || die "Cannot open $filename for write!\n"; + + print OUTFILE $_; + + close(OUTFILE); +} + +exit; + +########### END SCRIPT + diff --git a/alan.c b/alan.c new file mode 100644 index 000000000..f7ea61850 --- /dev/null +++ b/alan.c @@ -0,0 +1,938 @@ +/* + + Read/write Alan Map500 Waypoints, Routes and Tracklogs. + + Provides "alanwpr" and "alantrl" formats for gpsbabel. + Currently supports OS 2.xx only. + + Copyright (C) 2007 Gunar Megger, 0xff@quantentunnel.de + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include "defs.h" + + +#define MYNAME "alan" + +#define MAXWPT 1000 /* old 500 */ + +#define MAXRTE 50 /* old 20 */ +#define MAXWPTINRTE 150 /* old 30 */ + +#define MAXTRK 8 /* old 5 */ +#define MAXPTINTRK 2500 + +#define WPT_NAME_LEN 8 +#define WPT_COMMENT_LEN 12 + +#define RTE_NAME_LEN 8 +#define RTE_COMMENT_LEN 12 + +#define TRK_NAME_LEN 12 +#define TRK_COMMENT_LEN 13 + +struct wpthdr { + gbuint32 id; + gbint16 num; + gbint16 next; + gbint16 idx[MAXWPT]; + gbuint8 used[MAXWPT]; +}; + +struct wpt { + char name[WPT_NAME_LEN]; + char comment[WPT_COMMENT_LEN]; + struct { + gbint32 x; /* degree * 36000 */ + gbint32 y; /* degree * 36000 */ + } pt; + gbint32 date; + gbint32 time; + gbint16 usecount; + gbint8 checked; + gbint8 reserved; +}; + +struct rtehdr { + gbuint32 id; + gbint16 num; + gbint16 next; + gbint16 idx[MAXRTE]; + gbuint8 used[MAXRTE]; + gbint16 rteno; +}; + +struct rte { + char name[RTE_NAME_LEN]; + char comment[RTE_COMMENT_LEN]; + gbint16 wptnum; + gbint16 wptidx[MAXWPTINRTE]; + gbint16 reserved; + gbint32 date; + gbint32 time; +}; + +struct wprdata { + struct wpthdr wpthdr; + struct wpt wpt[MAXWPT]; + struct rtehdr rtehdr; + struct rte rte[MAXRTE]; +}; + +struct trkhdr { + gbint16 totalpt; + gbint16 next; + char name[TRK_NAME_LEN]; /* 10, null terminated */ + char comment[TRK_COMMENT_LEN]; /* 12, null terminated */ + gbuint8 reserved[3]; + gbuint32 occupied; + gbuint32 show; + gbuint32 fill; +}; + +struct loghdr { + gbuint32 id; + gbint16 num; + gbint16 next; + gbint32 date; + gbint32 time; + struct trkhdr trkhdr[MAXTRK]; +}; + +struct trklog { + struct { + gbint32 x; /* degree * 36000 */ + gbint32 y; /* degree * 36000 */ + } pt[MAXPTINTRK]; + struct { + gbint16 speed; /* km/h * 200 */ + gbint16 height; /* m * 5 */ + } sh[MAXPTINTRK]; +}; + +struct trldata { + struct loghdr loghdr; + struct trklog trklog[MAXTRK]; +}; + +#define WPT_HDR_ID 0x5C38A600 +#define RTE_HDR_ID 0xD87F5900 +#define TRL_HDR_ID 0x38CB1200 + +#define WPT_IDX_NONE -1 /* 0xffff */ +#define WPT_USED 0xff +#define WPT_UNUSED 0 +#define WPT_CHECKED 1 +#define WPT_UNCHECKED 0 + +#define RTE_IDX_NONE -1 /* 0xffff */ +#define RTE_USED 0xff +#define RTE_UNUSED 0 +#define RTE_RTENO_NONE -1 + +#define TRK_USED 1 +#define TRK_UNUSED 0 +#define TRK_SHOW 1 +#define TRK_HIDE 0 +#define TRK_FILL 1 +#define TRK_WRAP 0 + +#define MAP500_PT_SCALE 36000.0 +#define pt2deg(P) ((double)(P) / MAP500_PT_SCALE) +#define deg2pt(D) (gbint32)si_round((double)(D) * MAP500_PT_SCALE) + +#define MAP500_ALTITUDE_SCALE 5.0 +#define hgt2m(A) ((double)(A) / MAP500_ALTITUDE_SCALE) +#define m2hgt(A) (gbint16)si_round((double)(A) * MAP500_ALTITUDE_SCALE) + +#define MAP500_SPEED_SCALE 720.0 +#define sp2mps(S) ((double)(S) / MAP500_SPEED_SCALE) +#define mps2sp(S) (gbint16)si_round((double)(S) * MAP500_SPEED_SCALE) + +#define BYTEORDER_TEST 0x04030201 /* 32bit reference value */ +enum { + SWAP_NONE = 0x1234, /* map500 regular */ + SWAP_BYTES = 0x2143, /* bytes swapped */ + SWAP_WORDS = 0x3412, /* words swapped */ + SWAP_BOTH = 0x4321 /* words + bytes swapped */ +}; + +/**************************************************************************/ + +static gbfile *fin = NULL, *fout = NULL; +struct wprdata WPR; +struct trldata TRL; + +static arglist_t wpr_args[] = { + /* + {"os3", &osversion, "Operating system version 3", + NULL, ARGTYPE_BOOL, ARGNOMINMAX }, + */ + ARG_TERMINATOR +}; +static arglist_t trl_args[] = { + /* + {"os3", &osversion, "Operating system version 3", + NULL, ARGTYPE_BOOL, ARGNOMINMAX }, + */ + ARG_TERMINATOR +}; + +/**************************************************************************/ + +static unsigned int byte_order(void) { + unsigned long test = BYTEORDER_TEST; + unsigned char *ptr; + unsigned int order; + + ptr = (unsigned char *)(&test); + order = (ptr[0] << 12) | (ptr[1] << 8) | (ptr[2] << 4) | ptr[3]; + + return order; +} + +static void sw_bytes(void *word) { + gbuint8 *p = word; + gbuint16 *r = word; + + *r = (gbuint16)(p[1] << 8 | p[0]); +} +static void sw_words(void *dword) { + gbuint16 *p = dword; + gbuint32 *r = dword; + + *r = (gbuint32)(p[0] << 16 | p[1]); +} +static void rev_bytes(void *dword) { + gbuint8 *p = dword; + gbuint32 *r = dword; + + *r = (gbuint32)(p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]); +} + +static void swap_wpthdr(struct wpthdr *wpthdr, + void (*swap16)(void *), void (*swap32)(void *)) { + int i; + + if ( swap32 != NULL ) { + swap32( &wpthdr->id ); + } + if ( swap16 != NULL ) { + swap16( &wpthdr->num ); + swap16( &wpthdr->next ); + for (i=0; iidx[i] ); + } +} + +static void swap_wpt(struct wpt *wpt, + void (*swap16)(void *), void (*swap32)(void *)) { + if ( swap16 != NULL ) { + swap16( &wpt->usecount ); + } + if ( swap32 != NULL ) { + swap32( &wpt->pt.x ); + swap32( &wpt->pt.y ); + swap32( &wpt->date ); + swap32( &wpt->time ); + } +} + +static void swap_rtehdr(struct rtehdr *rtehdr, + void (*swap16)(void *), void (*swap32)(void *)) { + int i; + + if ( swap16 != NULL) { + swap16( &rtehdr->num ); + swap16( &rtehdr->next ); + for (i=0; iidx[i] ); + swap16( &rtehdr->rteno ); + } + if ( swap32 != NULL ) { + swap32( &rtehdr->id ); + } +} + +static void swap_rte(struct rte *rte, + void (*swap16)(void *), void (*swap32)(void *)) { + int i; + + if (swap16 != NULL) { + swap16( &rte->wptnum ); + for (i=0; iwptidx[i] ); + swap16( &rte->reserved ); + } + if ( swap32 != NULL ) { + swap32( &rte->date ); + swap32( &rte->time ); + } +} + +static void wpr_swap(struct wprdata *wprdata) { + void (*swap16)(void *); + void (*swap32)(void *); + int i; + + switch( byte_order() ) { + case SWAP_NONE: /* same byte oder, LITTLE_ENDIAN */ + return; + break; + case SWAP_BOTH: /* swap words and bytes, BIG_ENDIAN */ + swap16 = sw_bytes; + swap32 = rev_bytes; + break; + case SWAP_WORDS: /* swap words, PDP_ENDIAN */ + swap16 = NULL; + swap32 = sw_words; + break; + case SWAP_BYTES: /* swap bytes */ + swap16 = sw_bytes; + swap32 = NULL; + break; + default: + return; /* never reached */ + } + + swap_wpthdr( &(wprdata->wpthdr), swap16, swap32 ); + for (i=0; i< MAXWPT; i++) + swap_wpt( &(wprdata->wpt[i]), swap16, swap32 ); + swap_rtehdr( &(wprdata->rtehdr), swap16, swap32 ); + for (i=0; irte[i]), swap16, swap32 ); +} + +static void swap_trkhdr(struct trkhdr *trkhdr, + void (*swap16)(void *), void (*swap32)(void *)) { + if ( swap16 != NULL ) { + swap16( &(trkhdr->totalpt) ); + swap16( &(trkhdr->next) ); + } + if ( swap32 != NULL ) { + swap32( &(trkhdr->occupied) ); + swap32( &(trkhdr->show) ); + swap32( &(trkhdr->fill) ); + } +} + +static void swap_loghdr(struct loghdr *loghdr, + void (*swap16)(void *), void (*swap32)(void *)) { + int i; + + if ( swap16 != NULL ) { + swap16( &(loghdr->num) ); + swap16( &(loghdr->next) ); + } + if ( swap32 != NULL ) { + swap32( &(loghdr->id) ); + swap32( &(loghdr->date) ); + swap32( &(loghdr->time) ); + } + for (i=0; itrkhdr[i]), swap16, swap32 ); +} + +static void swap_trklog(struct trklog *trklog, + void (*swap16)(void *), void (*swap32)(void *)) { + int i; + + if ( swap16 != NULL ) { + for (i=0; ish[i].speed) ); + swap16( &(trklog->sh[i].height) ); + } + } + if ( swap32 != NULL ) { + for (i=0; ipt[i].x) ); + swap32( &(trklog->pt[i].y) ); + } + } +} + +static void trl_swap(struct trldata *trldata) { + void (*swap16)(void *); + void (*swap32)(void *); + int i; + + switch( byte_order() ) { + case SWAP_NONE: /* same byte oder, LITTLE_ENDIAN */ + return; + break; + case SWAP_BOTH: /* swap words and bytes, BIG_ENDIAN */ + swap16 = sw_bytes; + swap32 = rev_bytes; + break; + case SWAP_WORDS: /* swap words, PDP_ENDIAN */ + swap16 = NULL; + swap32 = sw_words; + break; + case SWAP_BYTES: /* swap bytes */ + swap16 = sw_bytes; + swap32 = NULL; + break; + default: + return; /* never reached */ + } + + swap_loghdr( &(trldata->loghdr), swap16, swap32); + for (i=0; itrklog[i]), swap16, swap32); +} + + +/**************************************************************************/ + +static void str2lab(char *dest, char *src, int len, char *fmt, int n) { + int i,j; + + j = 0; + if (src != NULL) { + for (i=0; itm_mday | ((tm->tm_mon+1)<<8) | ((tm->tm_year+1900)<<16); + *time = t % 86400; +} + +static time_t unpack_time(gbint32 date, gbint32 time) { + time_t result; + short year, month, day; + static int m_to_d[12] = + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + + year = (date >> 16) & 0xffff; + month = (date >> 8) & 0xff; /* 1-12 */ + day = date & 0xff; /* 1-31 */ + + month -= 1; /* fit struct tm */ + year += month / 12; + + if (month < 0) { + year -= 1; + month += 12; + } + result = (year - 1970) * 365 + m_to_d[month]; + if (month <= 1) + year -= 1; + result += (year - 1968) / 4; + result -= (year - 1900) / 100; + result += (year - 1600) / 400; + result += day; + result -= 1; + result *= 86400; + result += time; /* map500 time is inseconds of the day */ + + return result; +} + +/**************************************************************************/ + +static waypoint * get_wpt(struct wprdata *wprdata, unsigned n) { + struct wpthdr *wpthdr; + struct wpt *wpt; + int j, idx; + waypoint *WP; + + wpthdr = &(wprdata->wpthdr); + idx = wpthdr->idx[n]; + + if (idx == WPT_IDX_NONE || wpthdr->used[idx] == WPT_UNUSED) + return NULL; + wpt = &(wprdata->wpt[idx]); + + WP = waypt_new(); + WP->latitude = -pt2deg(wpt->pt.y); + WP->longitude = pt2deg(wpt->pt.x); + WP->creation_time = unpack_time(wpt->date, wpt->time); + for(j=WPT_NAME_LEN-1; j >= 0 && wpt->name[j] == ' '; j--) {}; + WP->shortname = xstrndup(wpt->name,j+1); + for(j=WPT_COMMENT_LEN-1; j >= 0 && wpt->comment[j] == ' '; j--) {}; + if (j >= 0) + WP->description = xstrndup(wpt->comment, j+1); + else + WP->description = xstrdup(""); + WP->notes = xstrdup(""); + + return WP; +} + +static void wpr_read(void) { + struct wprdata wprdata; + struct rtehdr *rtehdr; + struct rte *rte; + int i, j, idx; + waypoint *WP; + route_head *RT; + + if ( gbfread(&wprdata, sizeof(struct wprdata), 1, fin) != 1 ) + fatal(MYNAME ": Read error on %s\n", fin->name); + wpr_swap(&wprdata); + if ( wprdata.wpthdr.id != WPT_HDR_ID || + wprdata.rtehdr.id != RTE_HDR_ID ) + fatal(MYNAME ": %s is not in Alan .wpr format.\n", fin->name); + + /* waypoints */ + for (i=0; iidx[i]; + if (idx == RTE_IDX_NONE || rtehdr->used[idx] == RTE_UNUSED) + continue; + rte = &(wprdata.rte[idx]); + + RT = route_head_alloc(); + RT->rte_num = i; + for(j=RTE_NAME_LEN-1; j >= 0 && rte->name[j] == ' '; j--) {}; + RT->rte_name = xstrndup(rte->name,j+1); + for(j=RTE_COMMENT_LEN-1; j >= 0 && rte->comment[j] == ' '; j--) {}; + if (j >= 0) + RT->rte_desc = xstrndup(rte->comment,j+1); + else + RT->rte_desc = xstrdup(""); + + route_add_head(RT); + + /* route points */ + for(j=0; jwptnum; j++) { + WP = get_wpt(&wprdata, rte->wptidx[j]); + if ( WP != NULL ) + route_add_wpt(RT, WP); + } + } +} + +static void trl_read(void) { + struct trldata trldata; + struct trkhdr *trkhdr; + struct trklog *trklog; + waypoint *WP; + route_head *TL; + int i, j; + + for (i=0; iname); + } + gbfseek(fin, 0x10000 * MAXTRK/2, SEEK_SET); + if ( gbfread( &(trldata.loghdr), sizeof(struct loghdr), 1, fin) != 1) + fatal(MYNAME ": Read error on %s\n", fin->name); + trl_swap(&trldata); + if ( trldata.loghdr.id != TRL_HDR_ID ) + fatal(MYNAME ": %s is not in Alan .trl format.\n", fin->name); + + for(i=0; ioccupied == TRK_UNUSED) + continue; + TL = route_head_alloc(); + for(j=TRK_NAME_LEN-1; + j >= 0 && (trkhdr->name[j] == ' ' || trkhdr->name[j] == '\0'); + j--) {}; + TL->rte_name = xstrndup(trkhdr->name,j+1); + for(j=TRK_COMMENT_LEN-1; + j >= 0 && (trkhdr->comment[j] == ' ' || trkhdr->comment[j] == '\0'); + j--) {}; + TL->rte_desc = xstrndup(trkhdr->comment,j+1); + TL->rte_num = i; + + track_add_head(TL); + + /* track points */ + trklog = &(trldata.trklog[i]); + for(j=0; jtotalpt; j++) { + WP = waypt_new(); + WP->latitude = -pt2deg(trklog->pt[j].y); + WP->longitude = pt2deg(trklog->pt[j].x); + WP->altitude = hgt2m(trklog->sh[j].height); + if ( trklog->sh[j].speed >= 0 ) + WAYPT_SET(WP, speed, sp2mps(trklog->sh[j].speed)) + else /* bad speed < 0 - set to 0.0 */ + WAYPT_UNSET(WP, speed); + track_add_wpt(TL, WP); + } + } +} + +/**************************************************************************/ + +static int find_wpt(struct wprdata *wprdata, const waypoint *WP) { + struct wpt pattern, *wpt; + int i, wpt_idx; + + str2lab(pattern.name, WP->shortname, WPT_NAME_LEN, NULL, 0); + pattern.pt.x = deg2pt(WP->longitude); + pattern.pt.y = deg2pt(-WP->latitude); + + wpt = wprdata->wpt; + for (i=0; iwpthdr.idx[i]; + if ( wpt_idx == WPT_IDX_NONE || + wprdata->wpthdr.used[wpt_idx] == WPT_UNUSED ) + continue; + if ( strncmp( wpt[wpt_idx].name, pattern.name, WPT_NAME_LEN) == 0 && + wpt[wpt_idx].pt.x == pattern.pt.x && + wpt[wpt_idx].pt.y == pattern.pt.y ) + return i; + } + + return -1; +} + +static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { + struct wpthdr *wpthdr; + int hdr_idx, wpt_idx; + struct wpt *wpt; + int i; + + wpthdr = &(wprdata->wpthdr); + + hdr_idx = find_wpt(wprdata, WP); + if ( hdr_idx >= 0 ) { + /* duplicate waypoint */ + if (isroute) { + wpt = &(wprdata->wpt[wpthdr->idx[hdr_idx]]); + wpt->usecount ++; + } + /* + warning(MYNAME ": using duplicate waypoint '%s' at (%f°, %f°)\n", + WP->shortname, WP->latitude, WP->longitude); + */ + return hdr_idx; + } + + for (i=0; iidx[i] != WPT_IDX_NONE; i++) { } + hdr_idx = i; + for (i=0; iused[i] != WPT_UNUSED; i++) { } + wpt_idx = i; + if (wpthdr->num >= MAXWPT || hdr_idx >= MAXWPT || wpt_idx >= MAXWPT ) + fatal(MYNAME ": Can't store more than %u waypoints\n", MAXWPT); + + wpt = &(wprdata->wpt[wpt_idx]); + str2lab(wpt->name, WP->shortname, WPT_NAME_LEN, "W%05d", wpt_idx); + str2lab(wpt->comment, WP->description, WPT_COMMENT_LEN, NULL, 0); + wpt->pt.x = deg2pt(WP->longitude); + wpt->pt.y = deg2pt(-WP->latitude); + wpt->usecount = isroute ? 1 : 0; + wpt->checked = isroute ? 0 : 1; + wpt->reserved = 0; + pack_time(WP->creation_time, &(wpt->date), &(wpt->time)); + + wpthdr->idx[hdr_idx] = wpt_idx; + wpthdr->used[wpt_idx] = WPT_USED; + wpthdr->num++; + wpthdr->next++; + if (wpthdr->next >= MAXWPT) /* overrun */ + wpthdr->next = 0; + + return hdr_idx; +} + +static void wpr_waypoint(const waypoint *WP) { + add_wpt(&WPR, WP, 0); +} + +static void wpr_route_hdr(const route_head *RT) { + struct rtehdr *rtehdr; + int hdr_idx, rte_idx; + struct rte *rte; + int i; + + rtehdr = &(WPR.rtehdr); + for (i=0; iidx[i] != RTE_IDX_NONE; i++) { } + hdr_idx = i; + for (i=0; iused[i] != RTE_UNUSED; i++) { } + rte_idx = i; + if (rtehdr->num >= MAXRTE || hdr_idx >= MAXRTE || rte_idx >= MAXRTE ) + fatal(MYNAME ": Can't store more than %u routes", MAXRTE); + + rte = &(WPR.rte[rte_idx]); + str2lab(rte->name, RT->rte_name, RTE_NAME_LEN, "R%03d", rte_idx); + str2lab(rte->comment, RT->rte_desc, RTE_COMMENT_LEN, NULL, 0); + pack_time(time(NULL), &(rte->date), &(rte->time)); + + rtehdr->idx[hdr_idx] = rte_idx; + rtehdr->used[rte_idx] = RTE_USED; + rtehdr->num++; + rtehdr->next++; + if (rtehdr->next >= MAXRTE) /* overrun */ + rtehdr->next = 0; + + /* if you want the new route to be active, uncomment the next line */ + /* rtehdr->rteno = rte_idx; */ +} + +static void wpr_route_wpt(const waypoint *WP) { + struct rte *rte; + int wpt_idx; + + rte = &(WPR.rte[WPR.rtehdr.num -1]); + if ( rte->wptnum >= MAXWPTINRTE ) + fatal(MYNAME ": Can't store more than %u waypoints per route", MAXWPTINRTE); + + wpt_idx = add_wpt(&WPR, WP, 1); + + rte->wptidx[rte->wptnum] = wpt_idx; + rte->wptnum ++; +} + +static void wpr_route_trl(const route_head *RT) { + /* should we do some final sanity checks? */ +} + +static void wpr_write(void) { + int i; + + WPR.wpthdr.id = WPT_HDR_ID; + WPR.wpthdr.num = WPR.wpthdr.next = 0; + for (i=0; iname); +} + +/**************************************************************************/ + +static void trl_track_hdr(const route_head *TL) { + struct trkhdr *trkhdr; + int idx, l; + + trkhdr = TRL.loghdr.trkhdr; + + for (idx=0; idx< MAXTRK && trkhdr[idx].occupied != TRK_UNUSED; idx++) {}; + if (idx >= MAXTRK) + fatal(MYNAME ": Can't store more than %u tracklogs", MAXTRK); + + if ( TL->rte_name != NULL ) + strncpy(trkhdr[idx].name, TL->rte_name, TRK_NAME_LEN); + if ( *(trkhdr[idx].name) == '\0' ) + sprintf(trkhdr[idx].name, "T%03d", idx); + trkhdr[idx].name[TRK_NAME_LEN-1] = '\0'; + + if ( TL->rte_desc != NULL ) { + strncpy(trkhdr[idx].comment, TL->rte_desc, TRK_COMMENT_LEN); + l = strlen(TL->rte_desc); + if ( l < TRK_COMMENT_LEN-1 ) + memset(trkhdr[idx].comment + l, ' ', TRK_COMMENT_LEN - l); + } + trkhdr[idx].comment[TRK_COMMENT_LEN-1] = '\0'; + + trkhdr[idx].comment[TRK_COMMENT_LEN-1] = '\0'; + trkhdr[idx].occupied = TRK_USED; + trkhdr[idx].totalpt = 0; + trkhdr[idx].next = 0; + + TRL.loghdr.num = idx; +} + +static void trl_track_wpt(const waypoint *WP) { + struct trklog *trklog; + struct trkhdr *trkhdr; + int trk_idx, log_idx; + + trk_idx = TRL.loghdr.num; + + trkhdr = &(TRL.loghdr.trkhdr[trk_idx]); + if ( trkhdr->totalpt >= MAXPTINTRK ) + fatal(MYNAME ": Can't store more than %u points per track", MAXPTINTRK); + log_idx = trkhdr->next; + + trklog = &(TRL.trklog[trk_idx]); + trklog->pt[log_idx].x = deg2pt( WP->longitude); + trklog->pt[log_idx].y = deg2pt(-WP->latitude); + if WAYPT_HAS(WP, speed) + trklog->sh[log_idx].speed = mps2sp(WP->speed); + if ( WP->altitude != unknown_alt ) + trklog->sh[log_idx].height = m2hgt(WP->altitude); + + trkhdr->totalpt ++; + trkhdr->next = trkhdr->totalpt; +} + +static void trl_track_tlr(const route_head *TL) { + struct trkhdr *trkhdr; + int trk_idx; + + trk_idx = TRL.loghdr.num; + trkhdr = &(TRL.loghdr.trkhdr[trk_idx]); + + if ( trkhdr->totalpt == 0 ) + trkhdr->occupied = TRK_UNUSED; + + TRL.loghdr.num = -1; +} + +static void trl_write(void) { + struct trkhdr *trkhdr; + void *buf; + int i; + size_t fill; + + TRL.loghdr.id = TRL_HDR_ID; + TRL.loghdr.num = TRL.loghdr.next = -1; + TRL.loghdr.date = TRL.loghdr.time = 0; + for (i=0; itotalpt = 0; + trkhdr->next = 0; + memset(trkhdr->name, 0, TRK_NAME_LEN); + memset(trkhdr->comment, ' ', TRK_COMMENT_LEN); + trkhdr->comment[TRK_COMMENT_LEN-1] = '\0'; + trkhdr->occupied = TRK_UNUSED; + trkhdr->show = TRK_HIDE; + trkhdr->fill = TRK_FILL; + } + memset(TRL.trklog, 0xff, sizeof(struct trklog) * MAXTRK); + + track_disp_all(trl_track_hdr, trl_track_tlr, trl_track_wpt); + + trl_swap(&TRL); + + fill = 0x10000 - 2 * sizeof(struct trklog); + buf = xmalloc(fill); + if (buf == NULL) + fatal(MYNAME ": Not enough memory\n"); + memset(buf, 0xff, fill); + + for (i=0; iname); + } + xfree(buf); + + fill = 0x1000 - sizeof(struct loghdr); + buf = xmalloc(fill); + if (buf == NULL) + fatal(MYNAME ": Not enough memory\n"); + memset(buf, 0xff, fill); + + if ( gbfwrite(&(TRL.loghdr), sizeof(struct loghdr), 1, fout) != 1 || + gbfwrite(buf, fill, 1, fout) != 1 ) + fatal(MYNAME ": Write error on %s\n", fout->name); + xfree(buf); +} + +/**************************************************************************/ + +static void alan_rd_init(const char *fname) { + fin = gbfopen(fname, "rb", MYNAME); +} + +static void alan_rd_deinit(void) { + gbfclose(fin); + fin = NULL; +} + + +static void alan_wr_init(const char *fname) { + fout = gbfopen(fname, "wb", MYNAME); +} + +static void alan_wr_deinit(void) { + gbfclose(fout); + fout = NULL; +} + + +static void alan_exit(void) { + return; +} + +/**************************************************************************/ + +ff_vecs_t alanwpr_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_read | ff_cap_write /* routes */ + }, + alan_rd_init, + alan_wr_init, + alan_rd_deinit, + alan_wr_deinit, + wpr_read, + wpr_write, + alan_exit, + wpr_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command + line parameter */ +}; + +ff_vecs_t alantrl_vecs = { + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + alan_rd_init, + alan_wr_init, + alan_rd_deinit, + alan_wr_deinit, + trl_read, + trl_write, + alan_exit, + trl_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command + line parameter */ +}; diff --git a/an1.c b/an1.c new file mode 100644 index 000000000..c499b12b4 --- /dev/null +++ b/an1.c @@ -0,0 +1,1222 @@ +/* + Read DeLorme drawing files (.an1) + + Copyright (C) 2005 Ron Parker and Robert Lipe. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include +#include + +#define MYNAME "an1" +#include "defs.h" + +static gbfile *infile; +static gbfile *outfile; + +static char *output_type = NULL; +static char *road_changes = NULL; +static char *nogc = NULL; +static char *nourl = NULL; +static char *opt_symbol = NULL; +static char *opt_color = NULL; +static char *opt_zoom = NULL; +static char *opt_wpt_type = NULL; +static char *opt_radius = NULL; + +static short output_type_num = 0; +static short opt_zoom_num = 0; +static long opt_color_num = 0; +static short wpt_type_num = 0; +static short last_read_type = 0; +static double radius = 0.0; + +static long serial=10000; +static long rtserial=1; + +typedef struct roadchange { + long type; + char *name; +} roadchange; + +roadchange *roadchanges = NULL; + +static +arglist_t an1_args[] = { + {"type", &output_type, "Type of .an1 file", + "", ARGTYPE_STRING, ARG_NOMINMAX }, + {"road", &road_changes, "Road type changes", + "", ARGTYPE_STRING, ARG_NOMINMAX }, + {"nogc", &nogc, "Do not add geocache data to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"nourl", &nourl, "Do not add URLs to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"deficon", &opt_symbol, "Symbol to use for point data", + "Red Flag", ARGTYPE_STRING, ARG_NOMINMAX }, + {"color", &opt_color, "Color for lines or mapnotes", + "red", ARGTYPE_STRING, ARG_NOMINMAX }, + {"zoom", &opt_zoom, "Zoom level to reduce points", + NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"wpt_type", &opt_wpt_type, + "Waypoint type", + "", ARGTYPE_STRING, ARG_NOMINMAX }, + {"radius", &opt_radius, "Radius for circles", + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +typedef struct guid { + unsigned long l; + unsigned short s[3]; + unsigned char c[6]; +} GUID; + +#include "an1sym.h" + +#define ReadShort(f) gbfgetint16(f) +#define WriteShort(f,s) gbfputint16((s),f) +#define ReadLong(f) gbfgetint32(f) +#define WriteLong(f,l) gbfputint32((l),f) +#define ReadDouble(f) gbfgetdbl(f) +#define WriteDouble(f,d) gbfputdbl((d),f) + +static char * +ReadString( gbfile * f, short len ) +{ + char *result = NULL; + result = (char *)xcalloc( 1, len + 1 ); + if ( len ) { + gbfread( result, 1, len, f ); + } + return result; +} + +#define ReadChar(f) (unsigned char) gbfgetc(f) +#define WriteChar(f,c) gbfputc((unsigned char)(c),f) +#define WriteString(f,s) gbfputs((s),f) + +static void +ReadGuid( gbfile *f, GUID *guid ) +{ + int i = 0; + guid->l = ReadLong( f ); + for ( i = 0; i < 3; i++ ) { + guid->s[i] = ReadShort( f ); + } + for ( i = 0; i < 6; i++ ) { + guid->c[i] = ReadChar( f ); + } +} + +static void +WriteGuid( gbfile *f, GUID *guid ) +{ + int i = 0; + WriteLong( f, guid->l ); + for ( i = 0; i < 3; i++ ) { + WriteShort( f, guid->s[i] ); + } + for ( i = 0; i < 6; i++ ) { + WriteChar( f, guid->c[i] ); + } +} + +static void +Skip(gbfile * f, + unsigned long distance) +{ + gbfseek(f, distance, SEEK_CUR); +} + +static double +DecodeOrd( long ord ) +{ + return (double)((gbint32)(0x80000000 - ord)) / 0x800000; +} + +static long +EncodeOrd( double ord ) +{ + return (gbint32)(0x80000000 - (gbint32)(ord * 0x800000)); +} + +typedef struct { + short hotspotxhi; + long hotspoty; + long unk1; + GUID guid; + char *name; +} an1_symbol_record; + +typedef struct { + format_specific_data fs; + short magic; + long unk1; + long lon; + long lat; + short type; + long height; + long width; + short unk2; + short unk3; + short serial; + short unk4; + unsigned char create_zoom; + unsigned char visible_zoom; + short unk5; + double radius; /* in km */ + char *name; + char *fontname; + GUID guid; + long fontcolor; + long fontstyle; + long fontsize; + long outlineweight; + long outlinecolor; + long outlineflags; + long fillcolor; + long unk6; + long fillflags; + + /* Added in SA2006/Topo 6.0 */ + short unk6_1; + char *url; + char *comment; + long creation_time; + long modification_time; + char *image_name; +} an1_waypoint_record; + +typedef struct { + format_specific_data fs; + short magic; + long unk0; + long lon; + long lat; + short unk1; +} an1_vertex_record; + +typedef struct { + format_specific_data fs; + long roadtype; + short serial; + long unk2; + short unk3; + short type; + long unk4; + char *name; + long lineweight; + long linestyle; + long linecolor; + long unk5; + long polyfillcolor; + long unk6; + long unk7; + short unk8; + long pointcount; +} an1_line_record; + +static an1_waypoint_record *Alloc_AN1_Waypoint( ); + +void Destroy_AN1_Waypoint( void *vwpt ) { + + an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt; + xfree( wpt->name ); + xfree( wpt->fontname ); + if ( wpt->url ) xfree( wpt->url ); + if ( wpt->comment ) xfree( wpt->comment ); + if ( wpt->image_name ) xfree( wpt->image_name ); + xfree( vwpt ); +} + +void Copy_AN1_Waypoint( void **vdwpt, void *vwpt ) { + an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt; + an1_waypoint_record *dwpt = Alloc_AN1_Waypoint(); + memcpy( dwpt, wpt, sizeof( an1_waypoint_record )); + dwpt->name = xstrdup( wpt->name ); + dwpt->fontname = xstrdup( wpt->fontname ); + dwpt->url = xstrdup( wpt->url ); + dwpt->comment = xstrdup( wpt->comment ); + dwpt->image_name = xstrdup( wpt->image_name ); + *vdwpt = (void *)dwpt; +} + +static an1_waypoint_record *Alloc_AN1_Waypoint( ) { + an1_waypoint_record *result = NULL; + result = (an1_waypoint_record *)xcalloc( sizeof(*result), 1 ); + result->fs.type = FS_AN1W; + result->fs.copy = Copy_AN1_Waypoint; + result->fs.destroy = Destroy_AN1_Waypoint; + result->fs.convert = NULL; + return result; +} + +static an1_vertex_record *Alloc_AN1_Vertex(); + +void Destroy_AN1_Vertex( void *vvertex ) { + xfree( vvertex ); +} + +void Copy_AN1_Vertex( void **vdvert, void *vvert ) { + an1_vertex_record *vert = (an1_vertex_record *)vvert; + an1_vertex_record *dvert = Alloc_AN1_Vertex(); + memcpy( dvert, vert, sizeof( an1_vertex_record )); + *vdvert = (void *)dvert; +} + +static an1_vertex_record *Alloc_AN1_Vertex() { + an1_vertex_record *result = NULL; + result = (an1_vertex_record *)xcalloc( sizeof( *result), 1 ); + result->fs.type = FS_AN1V; + result->fs.copy = Copy_AN1_Vertex; + result->fs.destroy = Destroy_AN1_Vertex; + result->fs.convert = NULL; + return result; +} + + +static an1_line_record *Alloc_AN1_Line(); + +void Destroy_AN1_Line( void *vline ) { + an1_line_record *line = (an1_line_record *)vline; + xfree( line->name ); + xfree( vline ); +} + +void Copy_AN1_Line( void **vdline, void *vline ) { + an1_line_record *line = (an1_line_record *)vline; + an1_line_record *dline = Alloc_AN1_Line(); + memcpy( dline, line, sizeof( an1_line_record )); + dline->name = xstrdup( line->name ); + *vdline = (void *)dline; +} + +static an1_line_record *Alloc_AN1_Line( ) { + an1_line_record *result = NULL; + result = (an1_line_record *)xcalloc( sizeof(*result), 1 ); + result->fs.type = FS_AN1L; + result->fs.copy = Copy_AN1_Line; + result->fs.destroy = Destroy_AN1_Line; + result->fs.convert = NULL; + return result; +} + + +static void Destroy_AN1_Symbol( an1_symbol_record *symbol ) { + xfree( symbol->name ); +} + +static void Read_AN1_Waypoint( gbfile *f, an1_waypoint_record *wpt ) { + short len; + + wpt->magic = ReadShort( f ); + wpt->unk1 = ReadLong( f ); + wpt->lon = ReadLong( f ); + wpt->lat = ReadLong( f ); + wpt->type = ReadShort( f ); + wpt->height = ReadLong( f ); + wpt->width = ReadLong( f ); + wpt->unk2 = ReadShort( f ); + wpt->unk3 = ReadShort( f ); + wpt->serial = ReadShort( f ); + wpt->unk4 = ReadShort( f ); + wpt->create_zoom = ReadChar( f ); + wpt->visible_zoom = ReadChar( f ); + wpt->unk5 = ReadShort( f ); + wpt->radius = ReadDouble( f ); + len = ReadShort( f ); + wpt->name = ReadString( f, len ); + + if ( len != strlen(wpt->name)) { + /* This happens in 06/6.0 files that put extra data in the + * name record for backward compatibility's sake */ + char *ofs = wpt->name + strlen( wpt->name ) + 1; + wpt->unk6_1 = le_read16( ofs ); + ofs += 2; + + len = le_read16( ofs ); + ofs += 2; + + if ( len ) { + char *oldurlstr; + /* + * Trust URL encoded in new format over one in + * old format if both are present. Whack the + * name starting at '{URL='. + */ + oldurlstr = strstr(wpt->name, "{URL="); + if (oldurlstr) { + *oldurlstr = 0; + } + + wpt->url = xcalloc( len+1, 1 ); + memcpy( wpt->url, ofs, len ); + ofs += len; + } + + len = le_read16( ofs ); + ofs += 2; + + if ( len ) { + wpt->comment = xcalloc( len+1, 1 ); + memcpy( wpt->comment, ofs, len ); + ofs += len; + } + + /* these are quadwords, presumably for year-2038 compat. */ + wpt->creation_time = le_read32( ofs ); + ofs += 8; + + wpt->modification_time = le_read32( ofs ); + ofs += 8; + } + + if ( wpt->type == 0x12 ) { + /* 'image' type */ + ReadShort( f ); /* length of font + filename */ + len = ReadShort( f ); + wpt->fontname = ReadString( f, len ); + len = ReadShort( f ); + wpt->image_name = ReadString( f, len ); + } + else { + len = ReadShort( f ); + wpt->fontname = ReadString( f, len ); + wpt->image_name = NULL; + } + ReadGuid( f, &wpt->guid ); + wpt->fontcolor = ReadLong( f ); + wpt->fontstyle = ReadLong( f ); + wpt->fontsize = ReadLong( f ); + wpt->outlineweight = ReadLong( f ); + wpt->outlinecolor = ReadLong( f ); + wpt->outlineflags = ReadLong( f ); + wpt->fillcolor = ReadLong( f ); + wpt->unk6 = ReadLong( f ); + wpt->fillflags = ReadLong( f ); +} + +static void Write_AN1_Waypoint( gbfile *f, an1_waypoint_record *wpt ) { + short len; + + WriteShort( f, wpt->magic ); + WriteLong( f, wpt->unk1 ); + WriteLong( f, wpt->lon ); + WriteLong( f, wpt->lat ); + WriteShort( f, wpt->type ); + WriteLong( f, wpt->height ); + WriteLong( f, wpt->width ); + WriteShort( f, wpt->unk2 ); + WriteShort( f, wpt->unk3 ); + WriteShort( f, wpt->serial ); + WriteShort( f, wpt->unk4 ); + WriteChar( f, wpt->create_zoom ); + WriteChar( f, wpt->visible_zoom ); + WriteShort( f, wpt->unk5 ); + WriteDouble( f, wpt->radius ); + + len = strlen( wpt->name ) + 1 + 2 + 2 + + (wpt->url ? strlen( wpt->url ) : 0) + 2 + + (wpt->comment ? strlen( wpt->comment ) : 0) + 8 + 8; + WriteShort( f, len ); + WriteString( f, wpt->name ); + WriteChar( f, 0 ); /* name string terminator */ + + WriteShort( f, wpt->unk6_1 ); + + if ( wpt->url ) { + WriteShort( f, strlen(wpt->url)); + WriteString( f, wpt->url ); + } + else { + WriteShort( f, 0 ); + } + + if ( wpt->comment ) { + WriteShort( f, strlen(wpt->comment)); + WriteString( f, wpt->comment ); + } + else { + WriteShort( f, 0 ); + } + + WriteLong( f, wpt->creation_time ); + WriteLong( f, 0 ); + + WriteLong( f, wpt->modification_time ); + WriteLong( f, 0 ); + + if ( wpt->type == 0x12 ) { /* image */ + len = 2 + (wpt->fontname ? strlen( wpt->fontname ) : 0 ) + + 2 + (wpt->image_name ? strlen( wpt->image_name ) : 0 ); + WriteShort( f, len ); + if ( wpt->fontname ) { + len = strlen( wpt->fontname ); + WriteShort( f, len ); + WriteString( f, wpt->fontname ); + } + else { + WriteShort( f, 0 ); + } + if ( wpt->image_name ) { + len = strlen( wpt->image_name ); + WriteShort( f, len ); + WriteString( f, wpt->image_name ); + } + else { + WriteShort( f, 0 ); + } + } + else { + len = strlen( wpt->fontname ); + WriteShort( f, len ); + WriteString( f, wpt->fontname ); + } + WriteGuid( f, &wpt->guid ); + WriteLong( f, wpt->fontcolor ); + WriteLong( f, wpt->fontstyle ); + WriteLong( f, wpt->fontsize ); + WriteLong( f, wpt->outlineweight ); + WriteLong( f, wpt->outlinecolor ); + WriteLong( f, wpt->outlineflags ); + WriteLong( f, wpt->fillcolor ); + WriteLong( f, wpt->unk6 ); + WriteLong( f, wpt->fillflags ); +} + +static void Read_AN1_Vertex( gbfile *f, an1_vertex_record *vertex ) { + + vertex->magic = ReadShort( f ); + vertex->unk0 = ReadLong( f ); + vertex->lon = ReadLong( f ); + vertex->lat = ReadLong( f ); + vertex->unk1 = ReadShort( f ); +} + +static void Write_AN1_Vertex( gbfile *f, an1_vertex_record *vertex ) { + WriteShort( f, vertex->magic ); + WriteLong( f, vertex->unk0 ); + WriteLong( f, vertex->lon ); + WriteLong( f, vertex->lat ); + WriteShort( f, vertex->unk1 ); +} + +static void Read_AN1_Line( gbfile *f, an1_line_record *line ) { + + short len; + + line->roadtype = ReadLong( f ); + line->serial = ReadShort( f ); + line->unk2 = ReadLong( f ); + line->unk3 = ReadShort( f ); + line->type = ReadShort( f ); + line->unk4 = ReadLong( f ); + len = ReadShort( f ); + line->name = ReadString( f, len ); + line->lineweight = ReadShort( f ); + line->linestyle = ReadLong( f ); + line->linecolor = ReadLong( f ); + line->unk5 = ReadLong( f ); + line->polyfillcolor = ReadLong( f ); + line->unk6 = ReadLong( f ); + line->unk7 = ReadLong( f ); + line->unk8 = ReadShort( f ); + line->pointcount = ReadLong( f ); +} + +static void Write_AN1_Line( gbfile *f, an1_line_record *line ) { + short len; + + WriteLong( f, line->roadtype ); + WriteShort( f, line->serial ); + WriteLong( f, line->unk2 ); + WriteShort( f, line->unk3 ); + WriteShort( f, line->type ); + WriteLong( f, line->unk4 ); + len = strlen( line->name ); + WriteShort( f, len ); + WriteString( f, line->name ); + WriteShort( f, (short) line->lineweight ); + WriteLong( f, line->linestyle ); + WriteLong( f, line->linecolor ); + WriteLong( f, line->unk5 ); + WriteLong( f, line->polyfillcolor ); + WriteLong( f, line->unk6 ); + WriteLong( f, line->unk7 ); + WriteShort( f, line->unk8 ); + WriteLong( f, line->pointcount ); +} + +static void Skip_AN1_IL( gbfile *f ) { + Skip( f, 26 ); +} + +static void Skip_AN1_BM( gbfile *f ) { + unsigned long bmsize; + unsigned long palettesize; + unsigned long bmisize; + unsigned long bitoffset; + + Skip( f, 8 ); /* BITMAPFILEHEADER fields 1-3 */ + bitoffset = ReadLong( f ); + + bmisize = ReadLong( f ); + Skip( f, 16 ); /* BITMAPINFOHEADER fields 2-6 */ + bmsize = ReadLong( f ); + Skip( f, 16 ); /* BITMAPINFOHEADER fields 8-11 */ + + palettesize = bitoffset - bmisize - 14; + Skip( f, bmsize + palettesize ); +} + +static void Read_AN1_Symbol( gbfile *f, an1_symbol_record *symbol ) { + short len; + + /* This is just the high word of a long; we ate the low + * word in the caller. Fortunately, we don't care. */ + symbol->hotspotxhi = ReadShort( f ); + symbol->hotspoty = ReadLong( f ); + symbol->unk1 = ReadLong( f ); + ReadGuid( f, &symbol->guid ); + len = ReadChar( f ); + symbol->name = ReadString( f, len ); +} + +static void Read_AN1_Header( gbfile *f ) { + unsigned short magic; + unsigned short type; + + magic = ReadShort( f ); + type = ReadShort( f ); + + last_read_type = type; +} + +static void Write_AN1_Header( gbfile *f ) { + WriteShort( f, 11557 ); + WriteShort( f, output_type_num ); +} + +static void Read_AN1_Bitmaps( gbfile *f ) { + long count; + unsigned short magic; + an1_symbol_record symbol; + + count = ReadLong( f ); + + while ( count ) { + magic = ReadShort( f ); + switch (magic) { + case 0x4d42: + Skip_AN1_BM( f ); + break; + case 0x4c49: + Skip_AN1_IL( f ); + break; + default: + Read_AN1_Symbol( f, &symbol ); + Destroy_AN1_Symbol( &symbol ); + count--; + break; + } + } + + /* Read the symbol table */ +} + +static void Write_AN1_Bitmaps( gbfile *f ) { + /* On write, we don't output any bitmaps, so writing them + * is just a matter of writing a count of zero */ + WriteLong( f, 0 ); +} + +static void Read_AN1_Waypoints( gbfile *f ) { + unsigned long count = 0; + unsigned long i = 0; + an1_waypoint_record *rec = NULL; + waypoint *wpt_tmp; + char *icon = NULL; + char *url = NULL; + ReadShort( f ); + count = ReadLong( f ); + for (i = 0; i < count; i++ ) { + rec = Alloc_AN1_Waypoint(); + Read_AN1_Waypoint( f, rec ); + wpt_tmp = waypt_new(); + + if ( rec->creation_time ) { + wpt_tmp->creation_time = rec->creation_time; + } + wpt_tmp->longitude = -DecodeOrd( rec->lon ); + wpt_tmp->latitude = DecodeOrd( rec->lat ); + wpt_tmp->notes = xstrdup( rec->comment ); + wpt_tmp->description = xstrdup( rec->name ); + if ( rec->url ) { + wpt_tmp->url = xstrdup( rec->url ); + } + else if ( NULL != (url=strstr(wpt_tmp->description, "{URL="))) { + *url = '\0'; + url += 5; + url[strlen(url)-1] = '\0'; + wpt_tmp->url = xstrdup( url ); + } + + if ( rec->image_name ) { + wpt_tmp->icon_descr = xstrdup( rec->image_name ); + } + else if (FindIconByGuid(&rec->guid, &icon)) { + wpt_tmp->icon_descr = icon; + } + + fs_chain_add( &(wpt_tmp->fs), (format_specific_data *)rec); + rec = NULL; + waypt_add( wpt_tmp ); + } +} + +static void +Write_One_AN1_Waypoint( const waypoint *wpt ) +{ + an1_waypoint_record *rec; + int local; + format_specific_data *fs = NULL; + + fs = fs_chain_find( wpt->fs, FS_AN1W ); + if ( fs ) { + rec = (an1_waypoint_record *)fs; + xfree( rec->name ); + local = 0; + if ( opt_zoom ) + rec->visible_zoom = opt_zoom_num; + } + else { + rec = Alloc_AN1_Waypoint(); + local = 1; + rec->magic = 1; + rec->type = wpt_type_num; + rec->unk2 = 3; + rec->unk3 = 18561; + rec->radius = radius; + rec->fillcolor = opt_color_num; + rec->fillflags = 3; + if ( wpt_type_num == 5 ) rec->fillflags = 0x8200; + rec->height = -50; + rec->width = 20; + rec->fontname = xstrdup( "Arial" ); + FindIconByName( opt_symbol, &rec->guid ); + rec->fontsize = 10; + rec->visible_zoom = opt_zoom?opt_zoom_num:10; + rec->unk6_1 = 1; + } + rec->name = xstrdup( wpt->description ); + + if ( !nogc && wpt->gc_data.id ) { + char *extra = xmalloc( 25 + strlen(wpt->gc_data.placer) + strlen( wpt->shortname )); + sprintf( extra, "\r\nBy %s\r\n%s (%1.1f/%1.1f)", + wpt->gc_data.placer, + wpt->shortname, wpt->gc_data.diff/10.0, + wpt->gc_data.terr/10.0); + rec->name = xstrappend( rec->name, extra ); + xfree( extra ); + } + + if ( !nourl && wpt->url ) { + int len = 7+strlen(wpt->url); + char *extra = (char *)xmalloc( len ); + sprintf( extra, "{URL=%s}", wpt->url ); + rec->name = xstrappend( rec->name, extra ); + xfree( extra ); + rec->url = xstrdup( wpt->url ); + } + + if ( wpt->notes ) { + if ( rec->comment ) { + xfree( rec->comment ); + } + rec->comment = xstrdup( wpt->notes ); + } + + + rec->creation_time = rec->modification_time = wpt->creation_time; + rec->lat = EncodeOrd( wpt->latitude ); + rec->lon = EncodeOrd( -wpt->longitude ); + rec->serial = serial++; + + if ( rec->type == 0x12 ) { /* image */ + if ( strstr( wpt->icon_descr, ":\\" )) { + rec->image_name = xstrdup( wpt->icon_descr ); + rec->height = -244; + rec->width = -1; + } + } + if ( !rec->image_name && wpt->icon_descr ) { + FindIconByName( (char *)(void *)wpt->icon_descr, &rec->guid ); + } + + Write_AN1_Waypoint( outfile, rec ); + if ( local ) { + Destroy_AN1_Waypoint( rec ); + } +} + +static void Write_AN1_Waypoints( gbfile *f ) { + WriteShort( f, 2 ); + WriteLong( f, waypt_count() ); + waypt_disp_all( Write_One_AN1_Waypoint ); +} + +static void Read_AN1_Lines( gbfile *f ) { + unsigned long count = 0; + unsigned long i = 0; + unsigned long j = 0; + an1_line_record *rec = NULL; + an1_vertex_record *vert = NULL; + route_head *rte_head; + waypoint *wpt_tmp; + + ReadShort( f ); + count = ReadLong( f ); + for (i = 0; i < count; i++ ) { + rec = Alloc_AN1_Line(); + Read_AN1_Line( f, rec ); + /* create route rec */ + rte_head = route_head_alloc(); + fs_chain_add( &rte_head->fs, (format_specific_data *)rec ); + route_add_head(rte_head); + for (j = 0; j < (unsigned) rec->pointcount; j++ ) { + vert = Alloc_AN1_Vertex(); + Read_AN1_Vertex( f, vert ); + + /* create route point */ + wpt_tmp = waypt_new(); + wpt_tmp->latitude = DecodeOrd( vert->lat ); + wpt_tmp->longitude = -DecodeOrd( vert->lon ); + wpt_tmp->shortname = (char *) xmalloc(7); + sprintf( wpt_tmp->shortname, "\\%5.5lx", rtserial++ ); + fs_chain_add( &wpt_tmp->fs, + (format_specific_data *)vert ); + route_add_wpt(rte_head, wpt_tmp); + } + } +} + +static void +Make_Road_Changes( an1_line_record *rec ) { + int i = 0; + + if ( !rec ) { + return; + } + + if ( !roadchanges ) { + return; + } + + while ( roadchanges[i].name ) { + if ( !case_ignore_strcmp(roadchanges[i].name, rec->name )) { + rec->roadtype = roadchanges[i].type; + break; + } + i++; + } +} + +static void +Write_One_AN1_Line( const route_head *rte ) +{ + an1_line_record *rec; + int local; + format_specific_data *fs = NULL; + + fs = fs_chain_find( rte->fs, FS_AN1L ); + + if ( fs ) { + rec = (an1_line_record *)(void *)fs; + local = 0; + switch (output_type_num) { + case 1: + if ( rec->type != 14 ) { + rec = Alloc_AN1_Line(); + memcpy( rec, fs, sizeof(an1_line_record)); + local = 1; + rec->roadtype = 0x11100541; + rec->unk2 = 655360; + rec->type = 14; + rec->unk8 = 2; + } // end if + Make_Road_Changes( rec ); + break; + case 2: + if ( rec->type != 15 ) { + rec = Alloc_AN1_Line(); + memcpy( rec, fs, sizeof(an1_line_record)); + local = 1; + rec->type = 15; + } // end if + break; + case 4: + if ( rec->type != 16 ) { + rec = Alloc_AN1_Line(); + memcpy( rec, fs, sizeof(an1_line_record)); + local = 1; + rec->type = 16; + } // end if + break; + } + } + else { + rec = Alloc_AN1_Line(); + local = 1; + rec->name = NULL; + switch (output_type_num) { + /* drawing road trail waypoint track */ + case 1: /* road */ + rec->roadtype = 0x11100541; + rec->unk2 = 655360; + rec->type = 14; + rec->unk8 = 2; + rec->name = xstrdup( rte->rte_name ); + break; + + case 2: /* trail */ + rec->roadtype = 0x11071c50; + rec->unk2 = 917504; + rec->type = 15; + rec->unk8 = 2; + break; + + case 4: /* track */ + rec->roadtype = 0x48800015; + rec->unk2 = 917504; + rec->type = 16; + rec->unk4 = 2; + rec->unk8 = 2; + break; + + case 0: /* drawing */ + case 3: /* waypoint - shouldn't have lines */ + default: + rec->roadtype = 0x48800015; + rec->unk2 = 1048576; + rec->type = 2; + rec->unk4 = 2; + rec->lineweight = 6; + rec->linecolor = opt_color_num; /* red */ + rec->unk5 = 3; + rec->unk8 = 2; + break; + } + if ( !rec->name ) { + rec->name = xstrdup( "" ); + } + + } + rec->serial = serial++; + rec->pointcount = rte->rte_waypt_ct; + Write_AN1_Line( outfile, rec ); + if ( local ) { + Destroy_AN1_Line( rec ); + } +} + +static void +Write_One_AN1_Vertex( const waypoint *wpt ) +{ + an1_vertex_record *rec; + int local; + format_specific_data *fs = NULL; + + fs = fs_chain_find( wpt->fs, FS_AN1V ); + + if ( fs ) { + rec = (an1_vertex_record *)(void *)fs; + local = 0; + } + else { + rec = Alloc_AN1_Vertex(); + local = 1; + rec->magic = 1; + } + rec->lat = EncodeOrd( wpt->latitude ); + rec->lon = EncodeOrd( -wpt->longitude ); + + Write_AN1_Vertex( outfile, rec ); + if ( local ) { + Destroy_AN1_Vertex( rec ); + } +} + +static void Write_AN1_Lines( gbfile *f ) { + WriteShort( f, 2 ); + WriteLong( f, route_count()+track_count() ); + + route_disp_all( Write_One_AN1_Line, NULL, Write_One_AN1_Vertex ); + track_disp_all( Write_One_AN1_Line, NULL, Write_One_AN1_Vertex ); +} + +static void +Init_Wpt_Type( void ) +{ + if ( !opt_wpt_type || !opt_wpt_type[0] ) { + wpt_type_num = 1; /* marker */ + return; + } + if ((opt_wpt_type[0] & 0xf0) == 0x30) { + wpt_type_num = atoi( opt_wpt_type ); + } + else { + wpt_type_num = 1; /* marker */ + if ( !case_ignore_strcmp( opt_wpt_type, "marker" )) { + wpt_type_num = 1; + } + else if ( !case_ignore_strcmp( opt_wpt_type, "symbol" )) { + wpt_type_num = 1; /* symbol and marker are synonyms */ + } + else if ( !case_ignore_strcmp( opt_wpt_type, "text" )) { + wpt_type_num = 4; + } + else if ( !case_ignore_strcmp( opt_wpt_type, "mapnote" )) { + wpt_type_num = 6; + } + else if ( !case_ignore_strcmp( opt_wpt_type, "circle" )) { + wpt_type_num = 5; + } + else if ( !case_ignore_strcmp( opt_wpt_type, "image" )) { + wpt_type_num = 18; + } + else { + fatal( MYNAME ": wpt_type must be " + "symbol, text, mapnote, circle, or image\n" ); + } + } +} + +static void +Init_Output_Type( void ) +{ + if ( !output_type || !output_type[0]) { + output_type_num = last_read_type; + return; + } + if ( (output_type[0] & 0xf0 ) == 0x30) { + output_type_num = atoi( output_type ); + } + else { + output_type_num = 0; + if ( !case_ignore_strcmp(output_type, "drawing")) { + output_type_num = 0; + } + else if ( !case_ignore_strcmp(output_type, "road")) { + output_type_num = 1; + } + else if ( !case_ignore_strcmp(output_type, "trail")) { + output_type_num = 2; + } + else if ( !case_ignore_strcmp(output_type, "waypoint")) { + output_type_num = 3; + } + else if ( !case_ignore_strcmp(output_type, "track")) { + output_type_num = 4; + } + else { + fatal(MYNAME ": type must be " + "drawing, road, trail, waypoint, or track\n"); + } + } + last_read_type = output_type_num; +} + +static long +Parse_Change_Type( char *type ) { + long retval = 0x11100541; + + if ( !case_ignore_strcmp( type, "limited" )) { + retval = 0x11070430; + } + else if ( !case_ignore_strcmp( type, "toll" )) { + retval = 0x11070470; + } + else if ( !case_ignore_strcmp( type, "us" )) { + retval = 0x11070870; + } + else if ( !case_ignore_strcmp( type, "state" )) { + retval = 0x11070c10; + } + else if ( !case_ignore_strcmp( type, "primary" )) { + /* primary state/provincial routes */ + retval = 0x11070840; + } + else if ( !case_ignore_strcmp( type, "major" )) { + retval = 0x11070c30; + } + else if ( !case_ignore_strcmp( type, "local" )) { + retval = 0x11071010; + } + else if ( !case_ignore_strcmp( type, "ramp" )) { + retval = 0x11070cb0; + } + else if ( !case_ignore_strcmp( type, "ferry" )) { + retval = 0x11070ca0; + } + else if ( !case_ignore_strcmp( type, "editable" )) { + retval = 0x11100541; + } + else { + fatal( MYNAME ": unknown road type for road changes\n" ); + } + return retval; +} + +static void +Free_Road_Changes( void ) +{ + int i = 0; + if ( roadchanges ) { + while ( roadchanges[i].name ) { + xfree(roadchanges[i].name ); + i++; + } + xfree( roadchanges ); + } + roadchanges = NULL; +} + +static void +Init_Road_Changes( void ) +{ + int count = 0; + char *strType = NULL; + char *name = NULL; + char *bar = NULL; + char *copy = NULL; + Free_Road_Changes(); + + if ( !road_changes || !road_changes[0] ) { + return; + } + bar = strchr( road_changes, '!' ); + while ( bar ) { + count++; + bar = strchr( bar+1, '!' ); + } + if ( !(count&1)) { + fatal( MYNAME ": invalid format for road changes\n" ); + } + count = 1 + count / 2; + roadchanges = (roadchange *)xmalloc( (count+1) * sizeof(roadchange)); + + roadchanges[count].type = 0; + roadchanges[count].name = NULL; + + copy = xstrdup( road_changes ); + bar = copy; + + while ( count ) { + count--; + name = bar; + bar = strchr( name, '!' ); + *bar = '\0'; + bar++; + strType = bar; + bar = strchr( strType, '!' ); + if ( bar ) { + *bar = '\0'; + bar++; + } + roadchanges[count].name = xstrdup( name ); + roadchanges[count].type = Parse_Change_Type( strType ); + } + + xfree( copy ); +} + +static void +rd_init(const char *fname) +{ + infile = gbfopen_le(fname, "rb", MYNAME); +} + +static void +rd_deinit(void) +{ + gbfclose(infile); +} + +static void +my_read(void) +{ + Read_AN1_Header( infile ); + Read_AN1_Bitmaps( infile ); + Read_AN1_Waypoints( infile ); + Read_AN1_Lines( infile ); +} + +static void +wr_init(const char *fname) +{ + outfile = gbfopen_le( fname, "wb", MYNAME ); + Init_Output_Type(); + Init_Road_Changes(); + opt_color_num = color_to_bbggrr(opt_color); + Init_Wpt_Type(); + if ( opt_zoom ) { + opt_zoom_num = atoi(opt_zoom); + } + radius = .1609344; /* 1/10 mi */ + if ( opt_radius ) { + radius = atof(opt_radius); + if ( !strchr(opt_radius,'k') && !strchr(opt_radius,'K')) { + radius *= 5280*12*2.54/100000; + } + } +} + +static void +wr_deinit( void ) +{ + Free_Road_Changes(); + gbfclose(outfile); +} + +static void +my_write( void ) +{ + Write_AN1_Header( outfile ); + Write_AN1_Bitmaps( outfile ); + Write_AN1_Waypoints( outfile ); + Write_AN1_Lines( outfile ); +} + +ff_vecs_t an1_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_write /* tracks */, + ff_cap_read | ff_cap_write /* routes */, + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + my_read, + my_write, + NULL, + an1_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/an1sym.h b/an1sym.h new file mode 100644 index 000000000..bf25c9303 --- /dev/null +++ b/an1sym.h @@ -0,0 +1,519 @@ +/* + + + + + + + + + + THIS FILE IS AUTOMATICALLY GENERATED + + + Please change make-an1sym.pl and + regenerate it rather than changing + this file directly. + + + + + + + + + + + + + + + + + + + + + + + +*/ + +/* + Read DeLorme drawing files (.an1) - supplemental (included by an1.c) + + Copyright (C) 2005 Ron Parker and Robert Lipe. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +struct defguid { + GUID guid; + char *name; +} default_guids[] = { + {{0xb610bc70,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Hiker"}, + {{0xb610bc71,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Canoe"}, + {{0xb610bc72,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Kayak"}, + {{0xb610bc73,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Bike"}, + {{0xb610bc74,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Four wheeler"}, + {{0xb610bc75,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Jeep"}, + {{0xb610bc76,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Snowmobile"}, + {{0xb610bc78,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Rec Vehicle"}, + {{0xb610bc79,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Fire"}, + {{0xb610bc7a,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Fishing"}, + {{0xb610bc7b,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Tree"}, + {{0xb610bc7c,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Pine Tree"}, + {{0xb610bc7d,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Birch"}, + {{0xb610bc7e,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Deer"}, + {{0xb610bc7f,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Moose"}, + {{0x99d8c163,{0x7622, 0x11d5, 0xe8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Mud"}, + {{0x012dfac2,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Tractor"}, + {{0x012dfac3,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Combine Harvester"}, + {{0x012dfac7,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Front-End Loader"}, + {{0xfd163780,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Power Shovel"}, + {{0xfd163781,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Road Grader"}, + {{0xfd163784,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Road Roller"}, + {{0xfd163787,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dump Truck"}, + {{0x5673d712,{0xb28d, 0x11d5, 0x13b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Skid-Steer Loader"}, + {{0xb86045ac,{0x390f, 0x420f, 0x91a7}, {0x76, 0x2f, 0x48, 0xea, 0xe2, 0xd7}}, + "Highway Sign"}, + {{0x1e129e95,{0x13b6, 0x48d8, 0x3fa3}, {0x9c, 0xc8, 0x20, 0x8e, 0x1d, 0x9d}}, + "Orange Cone"}, + {{0xadee7d54,{0xf7c9, 0x4ab6, 0xfb93}, {0x99, 0xc3, 0xbc, 0x9d, 0x15, 0x47}}, + "Barricade"}, + {{0xa170000f,{0x8bd8, 0x4574, 0x58ac}, {0x55, 0x41, 0x67, 0xef, 0x64, 0x62}}, + "Flagger"}, + {{0xa425f90e,{0x6ab6, 0x4ca9, 0x8997}, {0xbf, 0xca, 0xe0, 0xc2, 0x2b, 0x53}}, + "Construction Sign"}, + {{0x0805b240,{0x6b26, 0x4300, 0xebb1}, {0xea, 0x9b, 0xcf, 0x68, 0xc6, 0x18}}, + "Construction Flasher"}, + {{0x56721a6c,{0x8e77, 0x4b62, 0x09aa}, {0xce, 0xdc, 0x69, 0x4a, 0x16, 0x05}}, + "Transit"}, + {{0x623e1ee9,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Left"}, + {{0x623e1eea,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Right"}, + {{0x623e1eeb,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Up"}, + {{0x623e1eec,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Down"}, + {{0x623e1eed,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Up Left"}, + {{0x623e1eee,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Up Right"}, + {{0x623e1eef,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Down Left"}, + {{0x623e1ef0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Down Right"}, + {{0x83f91421,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Left"}, + {{0x83f91422,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Right"}, + {{0x83f91423,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Up"}, + {{0x83f91424,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Down"}, + {{0x83f91425,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Up Left"}, + {{0x83f91426,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Up Right"}, + {{0x83f91427,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Down Left"}, + {{0x83f91428,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Down Right"}, + {{0x83f91429,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Left"}, + {{0x83f9142a,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Right"}, + {{0x83f9142b,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Up"}, + {{0x83f9142c,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Down"}, + {{0x83f9142d,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Down Right"}, + {{0x83f9142e,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Down Left"}, + {{0x83f9142f,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Up Left"}, + {{0x83f91430,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Up Right"}, + {{0x8ff0aad1,{0xc53d, 0x4998, 0x7ebd}, {0x06, 0x60, 0x25, 0x6c, 0x4f, 0x6d}}, + "Accommodation"}, + {{0xaf7bf199,{0x6a8b, 0x49fe, 0xae92}, {0xa3, 0x09, 0x7b, 0xb8, 0x81, 0x6a}}, + "Australia"}, + {{0x6bbcc9d1,{0x6a19, 0x4c7b, 0xc6a2}, {0x3e, 0x17, 0x02, 0xd6, 0xee, 0x3a}}, + "Blue Dome Cross"}, + {{0xfff920fe,{0xd780, 0x49d4, 0x1bad}, {0x55, 0x2e, 0xc7, 0xdf, 0xa2, 0xaa}}, + "Green Dome Cross"}, + {{0x57e75924,{0xd6fa, 0x4666, 0x84bf}, {0x5b, 0x76, 0xa1, 0xd0, 0x14, 0x5f}}, + "Business"}, + {{0xb09ef4a7,{0x95e4, 0x4e5e, 0x5e84}, {0xbe, 0x2b, 0x86, 0xdd, 0x50, 0x65}}, + "Airplane"}, + {{0xf2833c22,{0x3592, 0x4a8a, 0x5693}, {0xee, 0x6c, 0x83, 0xb6, 0x3c, 0x19}}, + "Amusement Recreation"}, + {{0x6f0317d6,{0x7fa3, 0x4dcc, 0x6187}, {0x7e, 0xca, 0xcb, 0x65, 0x49, 0x12}}, + "Green Square"}, + {{0x18a6d3c0,{0x45cb, 0x4d19, 0xf5b9}, {0xc7, 0x9c, 0xbf, 0x8f, 0x6d, 0x46}}, + "Red Triangle"}, + {{0x86e68ea7,{0xb9ab, 0x4bc8, 0xa1bf}, {0xc1, 0x22, 0x13, 0x97, 0x95, 0xe8}}, + "Red Triangle and Green Square"}, + {{0x6afd74bf,{0x0ea5, 0x4680, 0xcd88}, {0x15, 0x87, 0x2f, 0x6c, 0xd2, 0xd8}}, + "City 4"}, + {{0x49dfeb74,{0xbb09, 0x4df1, 0x5687}, {0xd8, 0xa0, 0xff, 0x36, 0x89, 0x3d}}, + "White Square"}, + {{0x3eed62c6,{0xdab9, 0x42b0, 0xe4a3}, {0xd2, 0xf1, 0x7d, 0x54, 0xbf, 0x77}}, + "White Triangle"}, + {{0x6b521940,{0x4492, 0x4c48, 0x58a0}, {0xfc, 0xd1, 0x1f, 0x5e, 0x0c, 0xea}}, + "Red Black Diamond Flag"}, + {{0xbb8ebaa3,{0xac59, 0x4411, 0x9c94}, {0x30, 0xd4, 0xe1, 0x21, 0x25, 0x46}}, + "Yellow Diamond Flag"}, + {{0x8e118862,{0xf6aa, 0x4b34, 0x2b82}, {0x8f, 0x3b, 0x5a, 0x2b, 0x59, 0xeb}}, + "Small Pink Square"}, + {{0xd0ef64c2,{0xe319, 0x4876, 0x1b85}, {0x0e, 0x90, 0x50, 0x89, 0xb7, 0xc5}}, + "Store"}, + {{0xa22b08fb,{0x6193, 0x4f5c, 0xdaa4}, {0xfa, 0xdf, 0xa7, 0x6e, 0x23, 0xe1}}, + "Camping"}, + {{0x27f57c69,{0x575b, 0x4b56, 0x288c}, {0xe8, 0xe1, 0xc7, 0x05, 0x1f, 0x1f}}, + "Green Diamond Flag"}, + {{0xe07abb38,{0x219f, 0x4b52, 0x868b}, {0x45, 0x0f, 0xbc, 0xc1, 0x4f, 0x6a}}, + "Red Diamond Flag"}, + {{0x3a124ac9,{0x3973, 0x4e27, 0x4b82}, {0xa6, 0x3a, 0x94, 0x5c, 0xf8, 0xb3}}, + "Red Green Diamond Flag"}, + {{0x64ed669b,{0x0db8, 0x4ec9, 0xd181}, {0x98, 0x50, 0xb3, 0x8b, 0x2f, 0x2e}}, + "White Globe"}, + {{0x3cb10adc,{0xb090, 0x4960, 0x9f8a}, {0xec, 0xaf, 0x6c, 0xd7, 0xaa, 0x8b}}, + "Yellow Globe"}, + {{0x2779347d,{0x17d4, 0x4021, 0xa6a8}, {0x51, 0x9a, 0xb6, 0xf8, 0x21, 0xff}}, + ""}, + {{0x3ad63f7b,{0x4339, 0x427d, 0x5797}, {0xce, 0xa9, 0x96, 0x33, 0x8b, 0x3c}}, + "Black Cross"}, + {{0x3e89481e,{0x35ff, 0x48b6, 0xc7ae}, {0xb0, 0x75, 0xf6, 0x43, 0xc4, 0xc7}}, + "Church"}, + {{0x68622c10,{0x79b6, 0x466d, 0xa8a3}, {0x27, 0xc6, 0x25, 0x34, 0xfa, 0xa9}}, + "Small Dark Green Square"}, + {{0x42c6a873,{0x2d0c, 0x46e7, 0x9989}, {0xdd, 0x86, 0x01, 0x6e, 0xa4, 0xc9}}, + "Small Black Square"}, + {{0x50e3b06e,{0xbe81, 0x4b2c, 0x1f92}, {0x80, 0xa5, 0x72, 0x9b, 0x33, 0x05}}, + "Danger"}, + {{0x369d0b22,{0xed07, 0x421f, 0x8780}, {0x33, 0x0e, 0xbd, 0x27, 0x4f, 0x3c}}, + "Construction Business"}, + {{0x10603b6c,{0xb02e, 0x49ee, 0x60b9}, {0xed, 0x7e, 0x31, 0x16, 0x27, 0x89}}, + "Airport"}, + {{0x8328aab7,{0xfe04, 0x46dc, 0x7bbf}, {0x29, 0x34, 0x30, 0xd3, 0x4d, 0xeb}}, + "City 5"}, + {{0x96411287,{0xda33, 0x40e3, 0xaa9c}, {0x75, 0x83, 0x78, 0x2d, 0xa6, 0xf3}}, + "USA"}, + {{0xb2f98627,{0x1211, 0x40e8, 0xb287}, {0x6d, 0x66, 0xfd, 0x15, 0x1e, 0xd4}}, + "Diver Down"}, + {{0x3fce26d0,{0xfec6, 0x4f8b, 0x55a2}, {0x89, 0x3a, 0x8e, 0x59, 0x08, 0x0a}}, + "Light Yellow Square"}, + {{0xb4b68597,{0x1aed, 0x4918, 0xd492}, {0x1f, 0xd1, 0x5e, 0xf2, 0x55, 0xc1}}, + "Education Technology"}, + {{0x35d2e6a8,{0xda88, 0x4edb, 0x4b80}, {0x2b, 0x1b, 0xcf, 0xc0, 0xd4, 0x6d}}, + "Computer"}, + {{0x4ddc4e96,{0x8d19, 0x4079, 0x4488}, {0xc0, 0x8f, 0x0f, 0x8e, 0xb5, 0xd7}}, + "Amusement Recreation Red"}, + {{0x79f58929,{0x46c6, 0x4337, 0xc0b1}, {0xf0, 0x09, 0x55, 0xbb, 0x1f, 0xc3}}, + "Telephone Red"}, + {{0x0083b377,{0xfb80, 0x4a83, 0x3593}, {0x56, 0xe5, 0xfe, 0xc4, 0xcd, 0x43}}, + "Exit"}, + {{0x0c232891,{0xab4d, 0x440e, 0x7083}, {0x05, 0x63, 0x3a, 0xf5, 0x66, 0x11}}, + "Exit with Services"}, + {{0xaf63e7c2,{0x03fa, 0x418e, 0xc68b}, {0x02, 0xb8, 0xf5, 0x61, 0xb6, 0x61}}, + "Pizza"}, + {{0xd419c693,{0x39e6, 0x43db, 0xa1b8}, {0x7f, 0xcc, 0x2c, 0xb8, 0x51, 0x4a}}, + "Financial Services"}, + {{0x70740a81,{0xe4ca, 0x4ac2, 0xa498}, {0x21, 0xc8, 0x5b, 0xc0, 0xb7, 0xae}}, + "City 3"}, + {{0x9a582ff6,{0x34c4, 0x41c6, 0xf0a3}, {0x99, 0x69, 0x9d, 0xbe, 0x2e, 0x08}}, + "Food Store"}, + {{0x3cd31689,{0x2f8f, 0x4fb0, 0xcb88}, {0x34, 0x84, 0xfc, 0x8b, 0x03, 0xe4}}, + ""}, + {{0x952557a6,{0xe29e, 0x4512, 0x1184}, {0x1a, 0x3c, 0x9c, 0xd4, 0x83, 0x7d}}, + ""}, + {{0x03dc278c,{0xe8ff, 0x46ac, 0x3daa}, {0x9f, 0xe9, 0x1e, 0xcf, 0x10, 0x35}}, + "Driving Range"}, + {{0xacd28bab,{0x0ec0, 0x4393, 0xaf8b}, {0xbb, 0x5e, 0x74, 0xb3, 0x87, 0x12}}, + "Golf Municipal"}, + {{0x984e7139,{0xeab8, 0x49f6, 0x55a0}, {0x8d, 0x51, 0xe6, 0xdd, 0xcc, 0xf4}}, + "Golf Private"}, + {{0xec5828ab,{0x2a9d, 0x48f8, 0xd79b}, {0xc9, 0xc3, 0x30, 0x8e, 0xe4, 0xea}}, + "Golf Public"}, + {{0xb0120d99,{0x683a, 0x4ecc, 0x129a}, {0x29, 0x94, 0x1f, 0x04, 0xae, 0x10}}, + "Golf Resort"}, + {{0x2ce7685a,{0x6eaf, 0x4061, 0x29a5}, {0x87, 0x5e, 0xfa, 0x41, 0x75, 0x1a}}, + "Golf Semi Private"}, + {{0x10397049,{0x9fc9, 0x4380, 0x5680}, {0x81, 0xd9, 0xe7, 0x43, 0x1f, 0x11}}, + "Medical Service"}, + {{0x2fc28df6,{0xe806, 0x436e, 0xe0b9}, {0x46, 0x1d, 0xeb, 0xad, 0x56, 0x60}}, + "Home Furnishings"}, + {{0x910313db,{0xafce, 0x4019, 0x1aa4}, {0xe6, 0x2c, 0xe6, 0xd1, 0xfd, 0xf7}}, + "Industrial"}, + {{0x9e442c6e,{0xe12a, 0x4407, 0xd68a}, {0x1c, 0x5e, 0x19, 0xe7, 0xfe, 0x01}}, + ""}, + {{0x37e2fe4a,{0xcd71, 0x413f, 0x0cad}, {0x81, 0xc5, 0x2c, 0xf4, 0x78, 0x79}}, + ""}, + {{0x3c756e09,{0xb2dc, 0x48a6, 0x04a9}, {0x20, 0xb7, 0xc9, 0x9d, 0x14, 0x51}}, + ""}, + {{0xa1245b1c,{0x156a, 0x48fc, 0x6f96}, {0xa5, 0xa3, 0x22, 0x54, 0x13, 0x97}}, + "Manufacturing"}, + {{0x5bddbd7a,{0xf3cb, 0x454c, 0x06af}, {0x46, 0x1a, 0x68, 0xea, 0x60, 0x1a}}, + "Note"}, + {{0xcb6777e1,{0xe0e0, 0x45ce, 0x309f}, {0x8d, 0x61, 0x7a, 0xd9, 0x89, 0xf5}}, + "City"}, + {{0xbc168c08,{0x2b7f, 0x44be, 0x3883}, {0x81, 0x31, 0x4a, 0x09, 0xf5, 0x78}}, + "Air Base"}, + {{0xa8857b0f,{0xfc3b, 0x4cd1, 0x9e91}, {0xf5, 0x3b, 0x21, 0xa8, 0x3b, 0xb9}}, + "Battlefield"}, + {{0x06db55c1,{0xf687, 0x4840, 0x7c80}, {0x95, 0x58, 0x77, 0x8e, 0x5a, 0xdd}}, + "Mining"}, + {{0xcc61b277,{0xa48c, 0x445a, 0xd9b9}, {0xe5, 0x91, 0x36, 0x18, 0x4e, 0x09}}, + "Mountain"}, + {{0xfde13186,{0xb6cb, 0x4374, 0xc880}, {0x56, 0x99, 0xeb, 0x51, 0x68, 0x87}}, + "Capital"}, + {{0xb14d90d1,{0xd943, 0x40ff, 0x9fb7}, {0x9b, 0x92, 0xd1, 0x23, 0xca, 0xef}}, + "Route"}, + {{0x7eabc63f,{0x05d0, 0x4465, 0xb1b0}, {0x61, 0x2a, 0xf7, 0x4d, 0x0f, 0x4e}}, + "Overnight"}, + {{0xac39d8b9,{0xfcdc, 0x4b50, 0x9ca6}, {0xea, 0x6c, 0x4b, 0xb5, 0x96, 0x0f}}, + "Route End Active"}, + {{0xe1b9d86b,{0x95e6, 0x4bd8, 0xd880}, {0x7b, 0x6c, 0xc6, 0xd2, 0x00, 0x34}}, + "Route End Inactive"}, + {{0x98712315,{0x7e1e, 0x4024, 0x8392}, {0xe3, 0xb8, 0x5a, 0x51, 0x45, 0xb4}}, + "Fuel Stop"}, + {{0xe5ea5b38,{0x7b80, 0x4b42, 0x0aba}, {0x3d, 0x38, 0xf0, 0xe1, 0x17, 0x9a}}, + "Route Start Active"}, + {{0x18fd0d49,{0x0a29, 0x433a, 0xd584}, {0xe5, 0xb7, 0x5b, 0xe8, 0x25, 0xbc}}, + "Route Start Inactive"}, + {{0x2f52144b,{0x903e, 0x4dd9, 0x79af}, {0xe1, 0x66, 0x9b, 0xfc, 0xa9, 0xc1}}, + "Route Stop Active"}, + {{0xfaf8d826,{0xd27d, 0x4316, 0x0e92}, {0xce, 0x8d, 0x85, 0x93, 0x4c, 0xf5}}, + "Route Stop Inactive"}, + {{0xff44cae2,{0x707c, 0x4a1c, 0x43af}, {0x8b, 0xb6, 0xb1, 0x19, 0x9c, 0xf2}}, + "Route Via"}, + {{0x5a50d59b,{0xc15b, 0x49c4, 0x9faa}, {0xc4, 0x1c, 0x4f, 0xe2, 0x95, 0x2a}}, + "Radiation Green"}, + {{0x19556023,{0xb1e5, 0x4c9c, 0x49ba}, {0x08, 0x52, 0xa1, 0x24, 0x3d, 0x9f}}, + "Radiation Red"}, + {{0xa54be251,{0x6688, 0x49fb, 0x60b3}, {0x89, 0x56, 0x37, 0x68, 0xc5, 0xb0}}, + "Electricity"}, + {{0xd793ff0c,{0xfbe0, 0x4383, 0x3183}, {0xcf, 0x4f, 0x04, 0xb7, 0xee, 0x0a}}, + "Personal Furnishings"}, + {{0x00f90733,{0x7ab5, 0x42cf, 0x468c}, {0xbf, 0x91, 0x27, 0xd3, 0xa8, 0x9c}}, + "Personal Services"}, + {{0xea677f24,{0xbbe8, 0x4238, 0xee9c}, {0x6c, 0x0a, 0xec, 0x0e, 0x34, 0xf4}}, + "Telephone Black"}, + {{0x2d8a05b5,{0x8baf, 0x4f28, 0xf58b}, {0xfb, 0x7f, 0x37, 0x34, 0x28, 0xa7}}, + "Government Light"}, + {{0x40c64dfc,{0xc2d0, 0x4b0e, 0x6582}, {0x3f, 0x26, 0x9c, 0xcb, 0x6f, 0x1d}}, + "Airport Red Square"}, + {{0xf27adb5d,{0x3629, 0x44c7, 0x95a2}, {0x25, 0x2c, 0x95, 0x24, 0x98, 0x2f}}, + "Propeller Aircraft"}, + {{0x5a718e13,{0x3547, 0x42c5, 0x6d9d}, {0xb2, 0x82, 0xa5, 0x53, 0xbd, 0x3a}}, + "Jet Aircraft"}, + {{0x0a471039,{0x2dfe, 0x447e, 0x54be}, {0xa3, 0x93, 0xae, 0x9a, 0xdd, 0xac}}, + "Government"}, + {{0x4a59da2f,{0xe1c3, 0x42c3, 0x6ca1}, {0x06, 0xb9, 0x14, 0x1b, 0x89, 0x99}}, + "USA Regional"}, + {{0xf16500a9,{0xa845, 0x4293, 0xae89}, {0x5c, 0x29, 0xbb, 0x0d, 0x06, 0xf7}}, + "House 2"}, + {{0x7b05524d,{0xcb5a, 0x456f, 0x96b3}, {0x03, 0x61, 0x24, 0x54, 0x6a, 0x54}}, + "Picnic"}, + {{0xb88ad7a1,{0xb94d, 0x42e8, 0x2b9d}, {0xf5, 0x4c, 0x2b, 0xff, 0x57, 0xdc}}, + "Restaurant"}, + {{0xdc48a20a,{0x54a2, 0x4c61, 0x1fbe}, {0x02, 0x74, 0x5b, 0xe9, 0x18, 0x99}}, + "Store 2"}, + {{0x6b5ab040,{0x96df, 0x46ae, 0xacb8}, {0xe4, 0x47, 0x66, 0x3f, 0xec, 0x9b}}, + ""}, + {{0x153b2cff,{0x6232, 0x4294, 0xd59a}, {0xc5, 0xa0, 0x7b, 0xe0, 0x16, 0xeb}}, + "Blue Star"}, + {{0xf276f6b3,{0x586a, 0x4bf8, 0x2f82}, {0xf2, 0x69, 0xe3, 0x76, 0x7e, 0xd5}}, + ""}, + {{0x91d242c8,{0x0986, 0x4fad, 0x8286}, {0xec, 0x79, 0x79, 0xcd, 0xab, 0x02}}, + "Running"}, + {{0x8b0078db,{0x6ee0, 0x4caa, 0xd3b5}, {0xfe, 0xe1, 0xc2, 0xbf, 0x94, 0x7d}}, + "Transportation"}, + {{0x0599f6c9,{0x478e, 0x4f63, 0x78a5}, {0xed, 0x31, 0xb5, 0xae, 0xda, 0x89}}, + "Fishing 2"}, + {{0x7389128c,{0x0e78, 0x4d5d, 0x4189}, {0xb8, 0xf3, 0xb5, 0xbd, 0x70, 0xb1}}, + "Automotive"}, + {{0x0362b593,{0x3df6, 0x48ed, 0xc489}, {0x85, 0x13, 0xc1, 0xc0, 0xb9, 0x0d}}, + "Cloudy"}, + {{0xf0717a94,{0xd048, 0x4770, 0x9bab}, {0x80, 0x09, 0xbd, 0x4b, 0x1e, 0x75}}, + "Partly Cloudy"}, + {{0x14486bbc,{0xae6b, 0x44ea, 0xd6b9}, {0xbf, 0x9a, 0x39, 0x7a, 0x51, 0x6c}}, + "Mostly Cloudy"}, + {{0x7a258c70,{0xabec, 0x4cff, 0x4983}, {0x84, 0xdc, 0x2f, 0x2e, 0xff, 0x28}}, + "Hurricane"}, + {{0xeff260d4,{0x46d5, 0x4fb5, 0xc79c}, {0x5e, 0x06, 0xc8, 0xab, 0x7a, 0x2b}}, + "Lightning"}, + {{0xc3d70220,{0x5154, 0x4766, 0xf0af}, {0xdf, 0x86, 0x74, 0x40, 0x5f, 0x8c}}, + "Rain"}, + {{0xf2dfbc91,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue Flag"}, + {{0xf2dfbc92,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Blue Flag"}, + {{0xf2dfbc93,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Brown Flag"}, + {{0xf2dfbc94,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Yellow Flag"}, + {{0xf2dfbc95,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Red Flag 2"}, + {{0xf2dfbc96,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Red Flag"}, + {{0xf2dfbc97,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Green Flag"}, + {{0xf2dfbc98,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Green Flag"}, + {{0xf2dfbc99,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue-Green Flag"}, + {{0xf2dfbc9a,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Light Blue Flag"}, + {{0x623e1ee1,{0xaf27, 0x100f, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Dark Blue Map Pin"}, + {{0xf2dfbc9d,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue Map Pin"}, + {{0xf2dfbc9e,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Yellow Map Pin"}, + {{0xf2dfbc9f,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Brown Map Pin"}, + {{0xf2dfbca0,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Red Map Pin"}, + {{0xf2dfbca1,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Red Map Pin"}, + {{0xf2dfbca2,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Green Map Pin"}, + {{0xf2dfbca3,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Green Map Pin"}, + {{0xf2dfbca4,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Gray Map Pin"}, + {{0xf2dfbca5,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Gray Map Pin"}, + {{0xd1703de0,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Green Dot"}, + {{0xd1703de1,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Green Dot"}, + {{0xd1703de2,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue Dot"}, + {{0xd1703de3,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Blue Dot"}, + {{0xd1703de5,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Red Dot"}, + {{0x45c088e0,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Red Dot"}, + {{0x45c088e1,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Yellow Dot"}, + {{0x45c088e2,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Brown Dot"}, + {{0x45c088e3,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Light Blue Dot"}, + {{0xbde3a8a1,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue-Green Dot"}, + {{0xbde3a8a2,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Green Dot"}, + {{0xbde3a8a3,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Dark Green Dot"}, + {{0xbde3a8a4,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Blue Dot"}, + {{0xbde3a8a5,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Dark Blue Dot"}, + {{0xbde3a8a6,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Red Dot"}, + {{0xbde3a8a7,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Dark Red Dot"}, + {{0xbde3a8a8,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Yellow Dot"}, + {{0xbde3a8a9,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Brown Dot"}, + {{0xbde3a8aa,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Light Blue Dot"}, + {{0xbde3a8ab,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Blue-Green Dot"}, + {{0x623e1ee0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Red Flag"}, + {{0x623e1ee1,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Map Pin"}, + {{0x623e1ee2,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Yellow Square"}, + {{0x623e1ee3,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Red X"}, + {{0x623e1ee4,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Blue Circle"}, + {{0x623e1ee5,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "House"}, + {{0x623e1ee7,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Triangle"}, + {{0x623e1ee8,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Green Star"}, + {{0x9d277805,{0xe2f8, 0x4f43, 0x3f97}, {0x35, 0x0d, 0x40, 0xae, 0x5c, 0xd3}}, + "Geocache"}, + {{0xcb8aad04,{0xcc2d, 0x47f2, 0x428a}, {0x80, 0xf7, 0xd6, 0x68, 0xed, 0x32}}, + "Geocache Found"}, + {{0x7341c1f4,{0xdecd, 0x4d35, 0x45a5}, {0x52, 0x25, 0x5e, 0xbf, 0xe6, 0x51}}, + "Tent"}, + {{0x835b84e2,{0xf10c, 0x45cb, 0x958f}, {0x18, 0x3a, 0xc2, 0x2a, 0xe5, 0x28}}, + "Tipup Up"}, + {{0xce06fc92,{0xbb0c, 0x4ec1, 0xda93}, {0x64, 0x4a, 0x60, 0xbe, 0x40, 0x90}}, + "Topup Down"}, +}; + +int FindIconByName( const char *name, GUID *guid ) { + int i = 0; + for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ ) + { + if ( !case_ignore_strcmp(name, default_guids[i].name)) { + memcpy( guid, &(default_guids[i].guid), sizeof(GUID)); + return 1; + } + } + return 0; +} + +int FindIconByGuid( GUID *guid, char **name ) { + int i = 0; + for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ ) + { + if ( !memcmp(guid, &default_guids[i].guid, sizeof(GUID))) { + *name = default_guids[i].name; + return 1; + } + } + return 0; +} diff --git a/arcdist.c b/arcdist.c new file mode 100644 index 000000000..ecbc75db2 --- /dev/null +++ b/arcdist.c @@ -0,0 +1,170 @@ +/* + Distance from point to arc filter + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "filterdefs.h" +#include "grtcirc.h" + +#if FILTERS_ENABLED +#define MYNAME "Arc filter" + +static double pos_dist; +static char *distopt = NULL; +static char *arcfileopt = NULL; +static char *exclopt = NULL; +static char *ptsopt = NULL; + +typedef struct { + double distance; +} extra_data; + +static +arglist_t arcdist_args[] = { + {"file", &arcfileopt, "File containing vertices of arc", + NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX}, + {"distance", &distopt, "Maximum distance from arc", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX}, + {"exclude", &exclopt, "Exclude points close to the arc", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX}, + {"points", &ptsopt, "Use distance from vertices not lines", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +#define BADVAL 999999 + +void +arcdist_process(void) +{ + queue * elem, * tmp; + waypoint * waypointp; + double dist; + extra_data *ed; + double lat1, lon1, lat2, lon2; + int fileline = 0; + char *line; + gbfile *file_in; + + file_in = gbfopen(arcfileopt, "r", MYNAME); + + lat1 = lon1 = lat2 = lon2 = BADVAL; + while ((line = gbfgetstr(file_in))) { + char *pound = NULL; + int argsfound = 0; + + fileline++; + + pound = strchr( line, '#' ); + if ( pound ) { + if ( 0 == strncmp( pound, "#break", 6)) { + lat1 = lon1 = BADVAL; + } + *pound = '\0'; + } + + lat2 = lon2 = BADVAL; + argsfound = sscanf( line, "%lf %lf", &lat2, &lon2 ); + + if ( argsfound != 2 && strspn(line, " \t\n") < strlen(line)) { + warning(MYNAME ": Warning: Arc file contains unusable vertex on line %d.\n", fileline ); + } + else if ( lat2 != BADVAL && lon2 != BADVAL && + (ptsopt || (lat1 != BADVAL && lon1 != BADVAL ))) { + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + + waypointp = (waypoint *)elem; + if ( waypointp->extra_data ) { + ed = (extra_data *) waypointp->extra_data; + } + else { + ed = (extra_data *) xcalloc(1, sizeof(*ed)); + ed->distance = BADVAL; + } + if ( ed->distance == BADVAL || ed->distance >= pos_dist ) { + if ( ptsopt ) { + dist = gcdist( RAD(lat2), RAD(lon2), + RAD(waypointp->latitude), + RAD(waypointp->longitude) ); + } + else { + dist = linedist(lat1, lon1, lat2, lon2, + waypointp->latitude, + waypointp->longitude ); + } + + /* convert radians to float point statute miles */ + dist = radtomiles(dist); + + if ( ed->distance > dist ) { + ed->distance = dist; + } + waypointp->extra_data = ed; + } + } + } + lat1 = lat2; + lon1 = lon2; + } + + gbfclose(file_in); + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wp = (waypoint *) elem; + ed = (extra_data *) wp->extra_data; + wp->extra_data = NULL; + if ( ed ) { + if ((ed->distance >= pos_dist) == (exclopt == NULL)) { + waypt_del(wp); + waypt_free(wp); + } + xfree( ed ); + } + } +} + +void +arcdist_init(const char *args) { + char *fm; + + pos_dist = 0; + + if (distopt) { + pos_dist = strtod(distopt, &fm); + + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to feet */ + pos_dist *= .6214; + } + } +} + +void +arcdist_deinit(void) { + /* do nothing */ +} + +filter_vecs_t arcdist_vecs = { + arcdist_init, + arcdist_process, + arcdist_deinit, + NULL, + arcdist_args +}; +#endif // FILTERS_ENABLED diff --git a/avltree.c b/avltree.c new file mode 100644 index 000000000..c90c5680f --- /dev/null +++ b/avltree.c @@ -0,0 +1,723 @@ +/* + + AVL tree implementation. + + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#include "avltree.h" + +#define MYNAME "avltree" + +#ifdef DEBUG_MEM +# define AVLTREE_MAGIC 0x41564c53 +/* ((((((0L | 'A') << 8) | 'V') << 8) | 'L') << 8) | 'T'; */ +#endif + +#ifdef MEM_DEBUG +void avltree_check_handle(const void *tree); +#endif +static void avltree_node_free(const avltree_t *tree, avlnode_t *node); +static int avltree_node_height(avlnode_t *node); +static int avltree_insert_node(avltree_t *tree, avlnode_t **root, const char *key, const void *data); +static int avltree_delete_node(avltree_t *tree, const char *key, avlnode_t **root, int *changed); +static avlnode_t *avltree_right_rotation(avlnode_t *A); +static avlnode_t *avltree_left_rotation(avlnode_t *A); +static avlnode_t *avltree_left_right_rotation(avlnode_t *A); +static avlnode_t *avltree_right_left_rotation(avlnode_t *A); +static avlnode_t *avltree_dupe_node(const avltree_t *tree, const avlnode_t *node); +static int avltree_strcmpr(const char *s1, const char *s2); +static int avltree_case_ignore_strcmpr(const char *s1, const char *s2); +static avlnode_t *avltree_find_next(const avltree_t *tree, avlnode_t *node, const char *key); +static void avltree_save_key(avltree_t *tree, const char *key); + + +#ifdef MEM_DEBUG +# define AVLTREE_CHECK_HANDLE(a) avltree_valid_tree(a) +#else +# define AVLTREE_CHECK_HANDLE(a) +#endif + +#define AVLTREE_INVALID_BALANCE "%s/%s.%d: Invalid balance %d at node \"%s\"!\n", \ + tree->module, MYNAME, __LINE__, node->balance, node->key + + +/* Allocate and initialize an AVL Tree */ + +avltree_t * +avltree_init(const int options, const char *module) +{ + avltree_t *tree; + + if ((module == NULL) || (*module == '\0')) + fatal(MYNAME ": 'avltree_init' should be called with a valid module name!\n"); + + tree = xcalloc(1, sizeof(*tree)); + tree->options = options; + tree->module = module; + + if (options & AVLTREE_NON_CASE_SENSITIVE) { + if (options & AVLTREE_DESCENDING) + tree->compare = avltree_case_ignore_strcmpr; /* descending, non-case-sensitive */ + else + tree->compare = case_ignore_strcmp; /* ascending, non-case-sensitive */ + } + else { + if (options & AVLTREE_DESCENDING) + tree->compare = avltree_strcmpr; /* descending, case-sensitive */ + else + tree->compare = strcmp; /* ascending, case-sensitive */ + } + + return tree; +} + + +/* Destroy an AVL Tree */ + +void +avltree_done(avltree_t *tree) +{ + AVLTREE_CHECK_HANDLE(tree); + + avltree_save_key(tree, NULL); + if (tree->count) + avltree_node_free(tree, tree->root); + xfree(tree); +} + + +/* Get number of items in tree */ + +int +avltree_count(const avltree_t *tree) +{ + AVLTREE_CHECK_HANDLE(tree); + + return tree->count; +} + + +/* Delete item with key [key] */ + +int +avltree_delete(avltree_t *tree, const char *key) +{ + int changed = 0; + + AVLTREE_CHECK_HANDLE(tree); + + if (key == NULL) + fatal("%s/%s.%d: Attempt to delete a NULL-pointer!\n", + tree->module, MYNAME, __LINE__); + + return avltree_delete_node(tree, key, &tree->root, &changed); +} + + +/* Duplicate an existing tree */ + +avltree_t * +avltree_dupe(const avltree_t *tree, const char *module) +{ + avltree_t *dupe; + + AVLTREE_CHECK_HANDLE(tree); + + dupe = avltree_init(tree->options, module); + if ((dupe->count = tree->count)) + dupe->root = avltree_dupe_node(tree, tree->root); + + return dupe; +} + + +/* Find key [key] in tree */ + +int +avltree_find(const avltree_t *tree, const char *key, const void **data) +{ + avlnode_t *node; + + AVLTREE_CHECK_HANDLE(tree); + + node = tree->root; + while (node) { + int compare = tree->compare(key, node->key); + + if (compare < 0) + node = node->left; + else if (compare > 0) + node = node->right; + else { + if (data) + (*data) = node->data; + break; + } + } + + return (node) ? 1 : 0; +} + + +/* Get the first (the MIN-) entry of the tree */ + +const char * +avltree_first(const avltree_t *tree, const void **data) +{ + return avltree_next(tree, NULL, data); +} + + +/* Get the current height of the tree */ + +int +avltree_height(const avltree_t *tree) +{ + AVLTREE_CHECK_HANDLE(tree); + + if (tree->count) + return avltree_node_height(tree->root); + else + return 0; +} + + +/* Insert key [key] and [data] into tree */ + +int +avltree_insert(avltree_t *tree, const char *key, const void *data) +{ + int count; + + AVLTREE_CHECK_HANDLE(tree); + + if (key == NULL) + fatal("%s/%s.%d: Attempt to insert a NULL-pointer!\n", + tree->module, MYNAME, __LINE__); + + count = tree->count; + avltree_insert_node(tree, &tree->root, key, data); + return (count != tree->count) ? 1 : 0; +} + + +/* Get the next (the entry above [key]) */ + +const char * +avltree_next(const avltree_t *tree, const char *key, const void **data) +{ + avlnode_t *node; + + AVLTREE_CHECK_HANDLE(tree); + + if (key == NULL) + fatal("%s/%s.%d: Attempt to look for a NULL-pointer!\n", + tree->module, MYNAME, __LINE__); + + node = tree->root; + if (! node) return NULL; + + if ((node = avltree_find_next(tree, node, key))) { + avltree_save_key((avltree_t *)tree, node->key); + if (data) + (*data) = node->data; + } + else + avltree_save_key((avltree_t *)tree, NULL); + + return tree->key; +} + + +/* ------------------------------ static stuff ------------------------------ */ + + +#ifdef MEM_DEBUG + +void +avltree_check_handle(const avltree_t *tree) +{ + if (! tree) + fatal(MYNAME ": Invalid (NULL-) pointer!\n"); + if (tree->magic != AVLTREE_MAGIC) + fatal(MYNAME ": Invalid (no AVL tree object) pointer!\n"); +} + +#endif + + +static void +avltree_node_free(const avltree_t *tree, avlnode_t *node) +{ + if ((! (tree->options & AVLTREE_STATIC_KEYS)) && node->key) + xfree((char *)node->key); + if (node->left) + avltree_node_free(tree, node->left); + if (node->right) + avltree_node_free(tree, node->right); + xfree(node); +} + + +static int +avltree_node_height(avlnode_t *node) +{ + int height = 1; + + if (node->balance < 0) + height += avltree_node_height(node->left); + else if (node->right) + height += avltree_node_height(node->right); + + return height; +} + + +static avlnode_t * +avltree_right_rotation(avlnode_t *A) +{ +/* +> A B +> / \ / \ +> \ / \ +> B -->> A . +> / \ / \ / \ +> \ +> . +> / \ +*/ + avlnode_t *B; + + B = A->right; + A->right = B->left; + B->left = A; + + /* update balance of all touched nodes */ + /* reference: */ + + B->balance--; + A->balance = -(B->balance); + + return B; +} + + +static avlnode_t * +avltree_left_rotation(avlnode_t *A) +{ +/* +> A B +> / \ / \ +> / / \ +> B -->> . A +> / \ / \ / \ +> / +> . +> / \ +*/ + avlnode_t *B; + + B = A->left; + A->left = B->right; + B->right = A; + + /* update balance of all touched nodes */ + /* reference: */ + + B->balance++; + A->balance = -(B->balance); + + return B; +} + + +static avlnode_t * +avltree_left_right_rotation(avlnode_t *A) +{ +/* +> A C +> / \ / \ +> / / \ +> B -->> B A +> / \ / \ / \ +> \ +> C +*/ + avlnode_t *B, *C; + + B = A->left; + C = B->right; + A->left = C->right; + B->right = C->left; + C->right = A; + C->left = B; + + /* update balance of all touched nodes */ + /* reference: */ + + A->balance = (C->balance > 0) ? 0 : -(C->balance); + B->balance = (C->balance < 0) ? 0 : -(C->balance); + C->balance = 0; + + return C; +} + + +static avlnode_t * +avltree_right_left_rotation(avlnode_t *A) +{ +/* +> A C +> / \ / \ +> \ / \ +> B -->> B A +> / \ / \ / \ +> / +> C +*/ + avlnode_t *B, *C; + + B = A->right; + C = B->left; + A->right = C->left; + B->left = C->right; + C->left = A; + C->right = B; + + /* update balance of all touched nodes */ + /* reference: */ + + A->balance = (C->balance < 0) ? 0 : -(C->balance); + B->balance = (C->balance > 0) ? 0 : -(C->balance); + C->balance = 0; + + return C; +} + + +static int +avltree_insert_node(avltree_t *tree, avlnode_t **root, const char *key, const void *data) +{ + int changed = 0; + int compare; + avlnode_t *node = (*root); + + if (node == NULL) { + (*root) = node = xcalloc(1, sizeof(*node)); + if (tree->options & AVLTREE_STATIC_KEYS) + node->key = key; + else + node->key = xstrdup(key); + node->data = data; + tree->count++; + return 1; /* anyway, our tree has been changed */ + } + + compare = tree->compare(key, node->key); + + if (compare < 0) { + if (avltree_insert_node(tree, &node->left, key, data)) { + changed = (--node->balance != 0); + switch(node->balance) { + case -2: + if (node->left->balance < 0) + node = avltree_left_rotation(node); + else + node = avltree_left_right_rotation(node); + (*root) = node; + case 0: + changed = 0; + case -1: + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + else + changed = 0; + } + else if (compare > 0) { + if (avltree_insert_node(tree, &node->right, key, data)) { + changed = (++node->balance != 0); + switch(node->balance) { + case +2: + if (node->right->balance > 0) + node = avltree_right_rotation(node); + else + node = avltree_right_left_rotation(node); + (*root) = node; + case 0: + changed = 0; + case +1: + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + else + changed = 0; + } + else { + if (tree->options & AVLTREE_PARANOIAC) + fatal("%s/%s.%d: Duplicate keys are not allowed (\"%s\")!\n", + tree->module, MYNAME, __LINE__, key); + changed = 0; + } + + return changed; +} + + + +static int +avltree_delete_node(avltree_t *tree, const char *key, avlnode_t **root, int *changed) +{ + avlnode_t *node = (*root); + int deleted = 0; + int compare; + + if (node == NULL) { + if (tree->options & AVLTREE_PARANOIAC) + fatal("%s/%s.%d: Key to delete \"%s\" not found!\n", + tree->module, MYNAME, __LINE__, key); + return 0; + } + + compare = tree->compare(key, node->key); + + if (compare < 0) { + deleted = avltree_delete_node(tree, key, &node->left, changed); + if (*changed) { + node->balance++; /* shift weight to right */ + switch(node->balance) { + case +1: + (*changed) = 0; /* stop rebalancing */ + case 0: + break; + case +2: + if (node->right->balance >= 0) + node = avltree_right_rotation(node); + else + node = avltree_right_left_rotation(node); + (*root) = node; + if (node->balance == -1) + (*changed) = 0; + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + } + else if (compare > 0) { + deleted = avltree_delete_node(tree, key, &node->right, changed); + if (*changed) { + node->balance--; /* shift weight to left */ + switch(node->balance) { + case -1: + (*changed) = 0; /* stop rebalancing */ + case 0: + break; + case -2: + if (node->left->balance <= 0) + node = avltree_left_rotation(node); + else + node = avltree_left_right_rotation(node); + (*root) = node; + if (node->balance == +1) + (*changed) = 0; + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + } + else { + if (node->left) { + if (node->right) { + const char *temp_key; + const void *temp_data; + avlnode_t *succ = node->right; + + while (succ->left) succ = succ->left; /* find successor */ + + temp_key = succ->key; /* swap contents */ + temp_data = succ->data; + succ->key = node->key; + succ->data = node->data; + node->key = temp_key; + node->data = temp_data; + + deleted = avltree_delete_node(tree, key, &node->right, changed); + + if (*changed) { + node->balance--; /* shift weight to left */ + switch(node->balance) { + case -1: + (*changed) = 0; /* stop rebalancing */ + case 0: + break; + case -2: + if (node->left->balance <= 0) + node = avltree_left_rotation(node); + else + node = avltree_left_right_rotation(node); + (*root) = node; + if (node->balance == +1) + (*changed) = 0; + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + return deleted; + } + else { /* only left branch */ + (*root) = node->left; + node->left = NULL; + } + } + else if (node->right) { /* only right branch */ + (*root) = node->right; + node->right = NULL; + } + else /* only a simple leaf */ + (*root) = NULL; + + avltree_node_free(tree, node); + tree->count--; + (*changed) = 1; + deleted = 1; + } + + return deleted; +} + + +static avlnode_t * +avltree_dupe_node(const avltree_t *tree, const avlnode_t *node) +{ + avlnode_t *res = xcalloc(1, sizeof(*res)); + + if (tree->options & AVLTREE_STATIC_KEYS) + res->key = node->key; + else + res->key = xstrdup(node->key); + + res->balance = node->balance; + if (node->left) + res->left = avltree_dupe_node(tree, node->left); + if (node->right) + res->right = avltree_dupe_node(tree, node->right); + + return res; +} + + +static int +avltree_strcmpr(const char *s1, const char *s2) +{ + return -(strcmp(s1, s2)); +} + + +static int +avltree_case_ignore_strcmpr(const char *s1, const char *s2) +{ + return -(case_ignore_strcmp(s1, s2)); +} + + +static avlnode_t * +avltree_find_next(const avltree_t *tree, avlnode_t *node, const char *key) +{ + avlnode_t *prev = NULL; + + if (key == NULL) { + if ((node = tree->root)) { + while (node->left) + node = node->left; + } + return node; + } + + while (node) { + int compare = tree->compare(key, node->key); + + if (compare < 0) { + prev = node; + node = node->left; + } + else if (compare > 0) + node = node->right; + else { + if ((node = node->right)) + while (node->left) node = node->left; + else + node = prev; + return node; + } + } + /* The previous node was deleted and we could not find it. */ + return prev; +} + + +/* + Save [key] for a possible delete before next op. Now we have no problem with: + + curr = NULL; + while ((curr = avtree_next(tree, curr, NULL))) { + avltree_delete(tree, curr); + } + */ +static void +avltree_save_key(avltree_t *tree, const char *key) +{ + if (tree->options & AVLTREE_STATIC_KEYS) + tree->key = key; + else { + if (key == NULL) { + if (tree->key_sz) { + xfree((char *)tree->key); + tree->key_sz = 0; + } + tree->key = NULL; + } + else { + int n, n8; + + n = strlen(key) + 1; + n8 = ((n + 7) / 8) * 8; + + if (n8 > tree->key_sz) { + if (tree->key_sz == 0) + tree->key = xmalloc(n8); + else + tree->key = xrealloc((char *)tree->key, n8); + tree->key_sz = n8; + } + strncpy((char *)tree->key, key, n); + } + } +} diff --git a/avltree.h b/avltree.h new file mode 100644 index 000000000..d8c9ddb4e --- /dev/null +++ b/avltree.h @@ -0,0 +1,94 @@ +/* + + AVL tree implementation. + + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef AVLTREE_H_INCLUDED +#define AVLTREE_H_INCLUDED + +#include "defs.h" +#include +#include + +typedef int (*avltree_compare_cb) (const char *, const char *); + +typedef struct avltree_s +{ +#ifdef MEM_DEBUG + const int magic; +#endif + struct avlnode_s *root; + const char *module; + int count; /* number of items in tree */ + int options; + const char *key; + int key_sz; + avltree_compare_cb compare; +} avltree_t; + +typedef struct avlnode_s { + int balance; + const char *key; + const void *data; + struct avlnode_s *left; + struct avlnode_s *right; +} avlnode_t; + +/* options for avltree_init */ + +#define AVLTREE_ASCENDING 0 /* default */ +#define AVLTREE_DESCENDING 1 +#define AVLTREE_CASE_SENSITIVE 0 /* default */ +#define AVLTREE_NON_CASE_SENSITIVE 2 +#define AVLTREE_STATIC_KEYS 128 +#define AVLTREE_PARANOIAC 256 /* STOP on "duplicate key" (insert) or on "not found" (delete) */ + +/* Allocate and initialize an AVL Tree */ +avltree_t *avltree_init(const int options, const char *module); + +/* Destroy an AVL Tree */ +void avltree_done(avltree_t *tree); + +/* Get number of items in tree */ +int avltree_count(const avltree_t *tree); + +/* Delete item with key [key] */ +int avltree_delete(avltree_t *tree, const char *key); + +/* Duplicate an existing tree */ +avltree_t *avltree_dupe(const avltree_t *tree, const char *module); + +/* Find key [key] in tree */ +int avltree_find(const avltree_t *tree, const char *key, const void **data); + +/* Get the first (the MIN-) entry of the tree */ +const char *avltree_first(const avltree_t *tree, const void **data); + +/* Get the current height of the tree */ +int avltree_height(const avltree_t *tree); + +/* Insert key [key] and [data] into tree */ +int avltree_insert(avltree_t *tree, const char *key, const void *data); + +/* Get the next (the entry above [key]) */ +const char *avltree_next(const avltree_t *tree, const char *key, const void **data); + + +#endif /* AVLTREE_H_INCLUDED */ diff --git a/axim_gpb.c b/axim_gpb.c new file mode 100644 index 000000000..a931ba033 --- /dev/null +++ b/axim_gpb.c @@ -0,0 +1,174 @@ +/* + + Track reader for "Dell Axim Navigation System" GPB files, + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include +#include +#include + +#define MYNAME "axim_gpb" + +#define RECORD_LEN 344 + +static gbfile *fin; + +static +arglist_t axim_gpb_args[] = { + ARG_TERMINATOR +}; + +static float +le_read32_float(const void *src) +{ + float f; + gbint32 i; + + i = le_read32(src); + memcpy(&f, &i, 4); + + return f; +} + +static void +decode_buff(const char *buff, route_head *track) +{ + struct tm tm; + double lat, lon, alt, dir; + float vdop, hdop, pdop, spd, Uf1; + int sats; + waypoint *wpt; + + wpt = waypt_new(); + + memset(&tm, '\0', sizeof(tm)); + + tm.tm_year = le_read16((void *) (buff + 16)); + tm.tm_mon = le_read16((void *) (buff + 18)); + tm.tm_mday = le_read16((void *) (buff + 22)); + tm.tm_hour = le_read16((void *) (buff + 24)); + tm.tm_min = le_read16((void *) (buff + 26)); + tm.tm_sec = le_read16((void *) (buff + 28)); + lat = le_read_double( (void *) (buff + 32)); + lon = le_read_double( (void *) (buff + 40)); + spd = le_read32_float((void *) (buff + 48)); + dir = le_read32_float((void *) (buff + 52)); + + alt = le_read32_float((void *) (buff + 64)); + Uf1 = le_read32_float((void *) (buff + 68)); + + hdop = le_read32_float((void *) (buff + 84)); + vdop = le_read32_float((void *) (buff + 88)); + pdop = le_read32_float((void *) (buff + 92)); + sats = le_read16((void *) (buff + 96)); + + wpt->latitude = lat; + wpt->longitude = lon; + wpt->altitude = alt; +#if 0 + /* These values can be, but must not be right. */ + /* Further checks are needed to verify that. */ + /* (!!! reference data !!!) */ + WAYPT_SET(wpt, course, dir); + wpt->hdop = hdop; + wpt->vdop = vdop; + wpt->pdop = pdop; + wpt->sat = sats; + WAYPT_SET(wpt, speed, spd * 10); +#endif + /* We don't have a header with some magic fixed numbers or strings. */ + /* So let us check the range for some basic values */ + + is_fatal( + (tm.tm_year < 2005) || + (tm.tm_mon < 1) || (tm.tm_mon > 12) || + (tm.tm_mday < 1) || (tm.tm_mday > 31) || + (tm.tm_hour > 23) || (tm.tm_min > 60) || (tm.tm_sec > 60), + MYNAME ": Invalid or unsupported file (invalid time-stamp)."); + is_fatal( + (fabs(wpt->latitude) > 90) || + (fabs(wpt->longitude) > 180), + MYNAME ": Invalid or unsupported file (lat or/and lon out of range)."); + + /* post work */ + + tm.tm_year-=1900; + tm.tm_mon--; + wpt->creation_time = mkgmtime(&tm); + + track_add_wpt(track, wpt); +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +axim_gpb_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); +} + +static void +axim_gpb_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +axim_gpb_read(void) +{ + char buff[RECORD_LEN]; + route_head *track = NULL; + size_t bytes; + + while ((bytes = gbfread(buff, 1, RECORD_LEN, fin))) + { + is_fatal((bytes != RECORD_LEN), MYNAME ": Invalid or unsupported file (filesize)."); + if (track == NULL) + { + track = route_head_alloc(); + track_add_head(track); + } + decode_buff(buff, track); + } +} + +/**************************************************************************/ + +ff_vecs_t axim_gpb_vecs = { + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */, + }, + axim_gpb_rd_init, + NULL, + axim_gpb_rd_deinit, + NULL, + axim_gpb_read, + NULL, + NULL, + axim_gpb_args, + CET_CHARSET_ASCII, 0 +}; +/**************************************************************************/ diff --git a/bcr.c b/bcr.c new file mode 100644 index 000000000..0be68f4f8 --- /dev/null +++ b/bcr.c @@ -0,0 +1,485 @@ +/* + + Support for Motorrad Routenplaner (Map&Guide) .bcr files. + + Copyright (C) 2005-2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +/* + 2006/01/22: reader simplified with inifile library + 2007/01/30: new option prefer_shortnames + don't check global_opts.objective + 2007/04&14: new handling of DESCRIPTION lines +*/ + +#include "defs.h" +#include "csv_util.h" +#include "garmin_tables.h" +#include +#include +#include +#include +#include "cet_util.h" +#include "inifile.h" + +#define MYNAME "bcr" + +#undef BCR_DEBUG + +#define R_EARTH 6371000 /* radius of our big blue ball */ +#define BCR_DEF_ICON "Standort" +#define BCR_DEF_MPS_ICON "Waypoint" +#define BCR_UNKNOWN (double) 999999999 + +/* + 6371014 would be a better value when converting to f.e. to mapsoure, + but this seems to be used by Map&Guide when exporting to XML. +*/ + +static gbfile *fout; +static char *filename; +static int curr_rte_num, target_rte_num; +static double radius; +static inifile_t *ini; + +/* placeholders for options */ + +static char *rtenum_opt; +static char *rtename_opt; +static char *radius_opt; +static char *prefer_shortnames_opt; + +static +arglist_t bcr_args[] = { + {"index", &rtenum_opt, "Index of route to write (if more the one in source)", + NULL, ARGTYPE_INT, "1", NULL }, + {"name", &rtename_opt, "New name for the route", + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"radius", &radius_opt, "Radius of our big earth (default 6371000 meters)", "6371000", + ARGTYPE_FLOAT, ARG_NOMINMAX }, + {"prefer_shortnames", &prefer_shortnames_opt, "Use shortname instead of description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +typedef struct { + char *bcr_name; + char *mps_name; + char *symbol_DE; + int warned; +} bcr_icon_mapping_t; + +static +bcr_icon_mapping_t bcr_icon_mapping[] = { + { BCR_DEF_ICON, BCR_DEF_MPS_ICON, BCR_DEF_ICON }, + { "", BCR_DEF_MPS_ICON, "Eigene Adressen" }, + { "AdrMon alpen", "Summit", "Pass-Strassen" }, + { "AdrMon bauern", NULL, "Bauern- und Biohoefe" }, + { "AdrMon cmpngs", "Campground", "Campingplaetzte" }, + { "AdrMon p_aeu", "Scenic Area", "Sehenswertes" }, + { "AdrMon p_beu", "Gas Station", "Tanken" }, + { "AdrMon p_deu", "Parking Area", "Parken" }, + { "AdrMon p_feu", "Restaurant", "Gastro" }, + { "AdrMon p_geu", "Museum", "Freizeit" }, + { "AdrMon p_heu", "Gas Station", "Tankstellen" }, + { "AdrMon p_keu", NULL, "Faehrverbindungen" }, + { "AdrMon p_leu", NULL, "Grenzuebergaenge" }, + { "AdrMon p_teu", NULL, "Wein- und Sektgueter" }, + { "AdrMon RUINEN", "Ghost Town", "Burgen und Schloesser" }, + { "AdrMon NFHAUS", "Residence", "Naturfreundehaeuser" }, + { "AdrMon racing", "Bike Trail", "Rennstrecken" }, + { "AdrMon TNKRST", "Bar", "Tankraststaetten" }, + { "AdrMon tpclub", "Contact, Biker", "Motorrad-Clubs" }, + { "AdrMon tpequ", NULL, "Motorrad-Equipment" }, + { "AdrMon tphot", "Hotel", "Motorrad-Hotels" }, + { "AdrMon tpmh", NULL, "Motorradhaendler" }, + { "AdrMon tpss", "Restricted Area", "Sperrungen" }, + { "AdrMon tpsw", "Scenic Area", "Sehenswertes" }, + { "AdrMon tptref", NULL, "Treffpunkte" }, + { "AdrMon VORTE", "Information", "Ortsinformationen" }, + { "AdrMon WEBCAM", NULL, "WebCam-Standorte" }, + { "AdrMon youthh", NULL, "Jugendherbergen" }, + { "Town", "City (Small)", "Orte" }, + { NULL, NULL, NULL, 0 } +}; + +static void +bcr_handle_icon_str(const char *str, waypoint *wpt) +{ + bcr_icon_mapping_t *m; + + wpt->icon_descr = BCR_DEF_MPS_ICON; + + for (m = bcr_icon_mapping; (m->bcr_name); m++) { + if (case_ignore_strcmp(str, m->bcr_name) == 0) { + int nr; + + if (m->symbol_DE == NULL) { + if (! m->warned) { + m->warned = 1; + warning(MYNAME ": Unknown icon \"%s\" found. Please report.\n", str); + } + return; + } + wpt->description = xstrdup(m->symbol_DE); + if (m->mps_name != NULL) { + nr = gt_find_icon_number_from_desc(m->mps_name, MAPSOURCE); + wpt->icon_descr = gt_find_desc_from_icon_number(nr, MAPSOURCE, NULL); + } + return; + } + } +} + +static char * +get_bcr_icon_from_icon_descr(const char *icon_descr) +{ + char *result = BCR_DEF_ICON; + + if (icon_descr) { + bcr_icon_mapping_t *m; + + for (m = bcr_icon_mapping; (m->bcr_name); m++) { + if (! m->mps_name) continue; + if (case_ignore_strcmp(icon_descr, m->mps_name) == 0) { + result = m->bcr_name; + break; + } + } + } + return result; +} + +static void +bcr_init_radius(void) +{ + if (radius_opt != NULL) /* preinitialize the earth radius */ + { + radius = atof(radius_opt); + if (radius <= 0) + fatal(MYNAME ": Sorry, the radius should be greater than zero!\n"); + } + else + radius = (double)R_EARTH; + + if (global_opts.verbose_status > 0) + printf(MYNAME ": We calculate with radius %f meters.\n", radius); +} + +static void +bcr_rd_init(const char *fname) +{ + filename = xstrdup(fname); + ini = inifile_init(fname, MYNAME); + bcr_init_radius(); +} + +static void +bcr_rd_deinit(void) +{ + inifile_done(ini); + xfree(filename); +} + +/* ------------------------------------------------------------*/ + +static void +bcr_create_waypts_from_route(route_head *route) +{ + waypoint *wpt; + queue *elem, *tmp; + + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) + { + wpt = waypt_dupe((waypoint *) elem); + waypt_add(wpt); + } +} + +static void +bcr_wgs84_to_mercator(const double lat, const double lon, int *north, int *east) +{ + double N, E; + + N = log(tan(lat * M_PI / 360 + M_PI / 4)) * radius; + E = lon * radius * M_PI / (double)180; + + if (lat > 0) N += 0.500000000001; /* we go from double to integer */ + else N -= 0.500000000001; /* it's time to round a little bit */ + if (lon > 0) E += 0.500000000001; + else E -= 0.500000000001; + + *north = N; + *east = E; +} + +void +bcr_mercator_to_wgs84(const int north, const int east, double *lat, double *lon) +{ + *lat = 2 * (atan(exp(north / radius)) - M_PI / 4) / M_PI * (double)180; + *lon = (double)east * (double)180 / (radius * M_PI); +} + +/* ------------------------------------------------------------- */ + +static void +bcr_data_read(void) +{ + int index; + char *str; + route_head *route; + + route = route_head_alloc(); + + if ((str = inifile_readstr(ini, "client", "routename"))) + route->rte_name = xstrdup(str); + + route_add_head(route); + + for (index = 1; index > 0; index ++) { + + char station[32]; + char *str; + int mlat, mlon; /* mercator data */ + waypoint *wpt; + + snprintf(station, sizeof(station), "STATION%d", index); + if (NULL == (str = inifile_readstr(ini, "coordinates", station))) break; + + if (2 != sscanf(str, "%d,%d", &mlon, &mlat)) + fatal(MYNAME ": structure error at %s (Coordinates)!\n", station); + + wpt = waypt_new(); + + wpt->shortname = xstrdup(station); + bcr_mercator_to_wgs84(mlat, mlon, &wpt->latitude, &wpt->longitude); + + if (NULL != (str = inifile_readstr(ini, "client", station))) + { + char *cx; + + cx = strchr(str, ','); + if (cx == NULL) + fatal(MYNAME ": structure error at %s (Client)!\n", station); + *cx++ = '\0'; + bcr_handle_icon_str(str, wpt); + } + + if (NULL != (str = inifile_readstr(ini, "description", station))) { + char *c; + + c = strchr(str, ','); + if (c != NULL) *c = '\0'; + if (*str) wpt->notes = xstrdup(str); + if ((str = c)) { + str++; + c = strchr(str, ','); + if (c != NULL) *c = '\0'; + if (*str) { + xfree(wpt->shortname); + wpt->shortname = xstrdup(str); + } + } + } + + route_add_wpt(route, wpt); + } + + /* remove empty route */ + if (route->rte_waypt_ct == 0) + route_del_head(route); + else + bcr_create_waypts_from_route(route); +} + +/* %%% bcr write support %%% ----------------------------------- */ + +static void +bcr_wr_init(const char *fname) +{ + filename = xstrdup(fname); + fout = gbfopen(fname, "wb", MYNAME); + bcr_init_radius(); +} + +static void +bcr_wr_deinit(void) +{ + gbfclose(fout); + xfree(filename); +} + +static void +bcr_route_trailer(const route_head *rte) +{ +} + +static void +bcr_write_wpt(const waypoint *wpt) +{ +} + +void bcr_write_line(gbfile *fout, const char *key, int *index, const char *value) +{ + if (value == NULL) /* this is mostly used in the world of windows */ + { /* so we respectfully add a CR/LF on each line */ + gbfprintf(fout, "%s\r\n", key); + } + else + { + char *tmp; + + tmp = (value != NULL) ? xstrdup(value) : xstrdup(""); + if (index != NULL) + gbfprintf(fout, "%s%d=%s\r\n", key, *index, tmp); + else + gbfprintf(fout, "%s=%s\r\n", key, tmp); + xfree(tmp); + } +} + +static void +bcr_route_header(const route_head *route) +{ + queue *elem, *tmp; + waypoint *wpt; + char *sout; + int i, north, east, nmin, nmax, emin, emax; + + curr_rte_num++; + if (curr_rte_num != target_rte_num) return; + + bcr_write_line(fout, "[CLIENT]", NULL, NULL); /* client section */ + bcr_write_line(fout, "REQUEST", NULL, "TRUE"); + + sout = route->rte_name; + if (rtename_opt != 0) sout = rtename_opt; + if (sout != NULL) + bcr_write_line(fout, "ROUTENAME", NULL, sout); + else + bcr_write_line(fout, "ROUTENAME", NULL, "Route"); + + bcr_write_line(fout, "DESCRIPTIONLINES", NULL, "0"); + + i = 0; + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) + { + char *icon; + waypoint *wpt = (waypoint *) elem; + + i++; + + icon = get_bcr_icon_from_icon_descr(wpt->icon_descr); + + xasprintf(&sout, "%s,%.f", icon, BCR_UNKNOWN); + bcr_write_line(fout, "STATION", &i, sout); + xfree(sout); + } + + bcr_write_line(fout, "[COORDINATES]", NULL, NULL); /* coords section */ + + nmin = emin = (1<<30); + emax = nmax = -nmin; + + i = 0; + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) + { + i++; + wpt = (waypoint *) elem; + + bcr_wgs84_to_mercator(wpt->latitude, wpt->longitude, &north, &east); + + if (north > nmax) nmax = north; + if (east > emax) emax = east; + if (north < nmin) nmin = north; + if (east < emin) emin = east; + + xasprintf(&sout, "%d,%d", east, north); + bcr_write_line(fout, "STATION", &i, sout); + xfree(sout); + } + + bcr_write_line(fout, "[DESCRIPTION]", NULL, NULL); /* descr. section */ + + i = 0; + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) + { + char *s1, *s2, *sout; + + i++; + wpt = (waypoint *) elem; + s1 = wpt->notes; + if (s1 == NULL) s1 = wpt->description; + + if (prefer_shortnames_opt || (s1 == NULL) || (*s1 == '\0')) { + s2 = s1; + s1 = wpt->shortname; + } + else s2 = wpt->shortname; + + if (s1 == NULL) s1 = xstrdup(""); + else s1 = csv_stringclean(s1, ",\t\r\n"); + if (s2 == NULL) s2 = xstrdup(""); + else s2 = csv_stringclean(s2, ",\t\r\n"); + + if (*s2) + xasprintf(&sout, "%s,%s,@,0", s1, s2); + else + xasprintf(&sout, "%s,%s,@,0", s1, s1); + bcr_write_line(fout, "STATION", &i, sout); + + xfree(s1); + xfree(s2); + xfree(sout); + } + + bcr_write_line(fout, "[ROUTE]", NULL, NULL); /* route section */ + + xasprintf(&sout, "%d,%d,%d,%d", emin, nmax, emax, nmin); + bcr_write_line(fout, "ROUTERECT", NULL, sout); + xfree(sout); + +} + +static void +bcr_data_write(void) +{ + target_rte_num = 1; + + if (rtenum_opt != NULL) { + target_rte_num = atoi(rtenum_opt); + if (((unsigned)target_rte_num > route_count()) || (target_rte_num < 1)) + fatal(MYNAME ": invalid route number %d (1..%d))!\n", + target_rte_num, route_count()); + } + curr_rte_num = 0; + route_disp_all(bcr_route_header, bcr_route_trailer, bcr_write_wpt); +} + +ff_vecs_t bcr_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read | ff_cap_write}, + bcr_rd_init, + bcr_wr_init, + bcr_rd_deinit, + bcr_wr_deinit, + bcr_data_read, + bcr_data_write, + NULL, + bcr_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ +}; diff --git a/brauniger_iq.c b/brauniger_iq.c new file mode 100644 index 000000000..eef12030d --- /dev/null +++ b/brauniger_iq.c @@ -0,0 +1,268 @@ +/* + * Serial download of barograph data from a Brauniger IQ Variometer. + * + * Copyright (C) 2004 Chris Jones + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include "defs.h" +#include "gbser.h" +#include + +static void *serial_handle; + +#define MYNAME "BRAUNIGER-IQ" +#define PRESTRKNAME "PRESALTTRK" + +static enum { + st_sync, + st_fl_num, + st_data_len, + st_ser_num, + st_pilot_name, + st_start_date, + st_start_year, + st_max_alt_1, + st_max_alt_2, + st_max_climb, + st_flight_dur, + st_log_ival, + st_start_time, + st_end_time, + st_sample_alt, + st_sample_spd, + num_states +} state; + +static const int reqd_bytes[num_states] = { 6, 1, 2, 2, 25, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1 }; + +static void rd_init(const char *fname) { + if (serial_handle = gbser_init(fname), NULL == serial_handle) { + fatal(MYNAME ": Can't open port '%s'\n", fname); + } + if (gbser_set_port(serial_handle, 9600, 8, 0, 1) != gbser_OK) { + fatal(MYNAME ": Can't configure port '%s'\n", fname); + } +} + +static void rd_deinit(void) { + gbser_deinit(serial_handle); + serial_handle = NULL; +} + +/** + * Process a data record. + * @return zero when all expected data has been received + */ +static int process_data(const unsigned char *data) { + static int remaining = 100; + static struct tm tm; + static time_t start, creation; + static route_head *track; + static unsigned char interval; + time_t finish; + waypoint *wpt = NULL; + int i; + + if (global_opts.debug_level >= 3) { + for (i = 0; i < reqd_bytes[state]; i++) { + printf("%.2x ", data[i]); + } + puts(""); + } + + remaining -= reqd_bytes[state]; + switch (state) { + case st_sync: + if (memcmp(data, "\x30\x31\x32\x33\x34\x35", 6) != 0) { + fatal(MYNAME ": Could not synchronise\n"); + } + break; + + case st_fl_num: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Flight Number: %d\n", data[0]); + } + break; + + case st_data_len: + remaining = (data[0] << 8) + data[1] - 2; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Data Length: %d\n", remaining); + } + break; + + case st_ser_num: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Serial Number: %d\n", (data[0] << 8) + data[1]); + } + break; + + case st_pilot_name: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Pilot Name: %.25s\n", data); + } + break; + + case st_start_date: + i = (data[0] << 8) + data[1]; + tm.tm_mday = i / 100; + tm.tm_mon = (i % 100) - 1; + break; + + case st_start_year: + tm.tm_year = ((data[0] << 8) + data[1]) - 1900; + break; + + case st_max_alt_1: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Max Altitude 1: %dm\n", (data[0] << 8) + data[1]); + } + break; + + case st_max_alt_2: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Max Altitude 2: %dm\n", (data[0] << 8) + data[1]); + } + break; + + case st_max_climb: + if (global_opts.debug_level >= 1) { + i = (data[0] << 8) + data[1]; + printf(MYNAME ": Max climb: %d.%dm/s\n", i / 10, i % 10); + } + break; + + case st_flight_dur: + if (global_opts.debug_level >= 1) { + i = (data[0] << 8) + data[1]; + printf(MYNAME ": Flight Time: %d:%d\n", i / 100, i % 100); + } + break; + + case st_log_ival: + interval = data[0]; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Logging Interval: %ds\n", interval); + } + break; + + case st_start_time: + i = (data[0] << 8) + data[1]; + tm.tm_hour = i / 100; + tm.tm_min = (i % 100) - 1; + tm.tm_sec = 0; + creation = start = mktime(&tm); + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Start Time: %s", ctime(&start)); + } + break; + + case st_end_time: + i = (data[0] << 8) + data[1]; + tm.tm_hour = i / 100; + tm.tm_min = (i % 100) - 1; + finish = mktime(&tm); + if (global_opts.debug_level >= 1) { + printf(MYNAME ": End Time: %s", ctime(&finish)); + } + if (remaining) { + track = route_head_alloc(); + track->rte_name = xstrdup(PRESTRKNAME); + track->rte_desc = xstrdup("Brauniger-IQ Barograph"); + track_add_head(track); + } else { + warning(MYNAME ": No barograph recorded for this flight\n"); + } + break; + + case st_sample_alt: + wpt = waypt_new(); + wpt->latitude = wpt->longitude = 0.0; + wpt->creation_time = creation; + creation += interval; + wpt->altitude = (data[0] << 8) + data[1]; + track_add_wpt(track, wpt); + if (global_opts.debug_level >= 2) { + printf(MYNAME ": remaining=%d, Altitude=%fm, ", remaining, wpt->altitude); + } + break; + + case st_sample_spd: + if (global_opts.debug_level >= 2) { + printf("Airspeed=%dkmh\n", data[0]); + } + state = st_sample_alt; + return remaining; + + default: + fatal(MYNAME ": Bad internal state\n"); + } + state++; + return remaining; +} + +static void data_read(void) { + unsigned char ibuf[25]; + int rd_cnt; + + if (global_opts.debug_level >= 0) { + puts(MYNAME ": Select recorded flight in memo mode."); + puts(MYNAME ": Press Memo button for two seconds..."); + } + + // Wait until something arrives + if (global_opts.debug_level >= 0) { + puts(MYNAME ": Downloading flight..."); + } + + // Read data until there is none left to read + state = st_sync; + for (;;) { + /* wait up to 5 seconds for more data */ + rd_cnt = gbser_read_wait(serial_handle, ibuf, reqd_bytes[state], 5000); + if (rd_cnt < 0) { + fatal(MYNAME ": Serial error\n"); + } else if (rd_cnt < reqd_bytes[state]) { + fatal(MYNAME ": Incomplete download\n"); + } + + if (!process_data(ibuf)) { + if (global_opts.debug_level >= 0) { + puts(MYNAME " ...Finished"); + } + return; + } + } +} + +static arglist_t brauniger_iq_args[] = { + ARG_TERMINATOR +}; + +ff_vecs_t brauniger_iq_vecs = { + ff_type_serial, + { ff_cap_none, ff_cap_read, ff_cap_none}, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + brauniger_iq_args, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ +}; diff --git a/cet.c b/cet.c new file mode 100644 index 000000000..e003e57c5 --- /dev/null +++ b/cet.c @@ -0,0 +1,366 @@ +/* + + Character encoding transformation - basics + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include "defs.h" +#include "cet.h" + +#include +#include +#include +#include + +/* ! ALL vec PARAMETERS HAVE TO BE A VALID POINTER TO A cet_cs_vec_t RECORD ! */ + +/* =========================================================================== */ +/* %%% single character or value transmission %%% */ +/* --------------------------------------------------------------------------- */ + +/* %%% cet_char_to_ucs4 %%% + * + * single character to UCS-4 code %%% + * return values: 0 if convertable character, otherwise 1 + */ + +int +cet_char_to_ucs4(const char src, const cet_cs_vec_t *vec, int *value) +{ + int trash, c; + int *dest; + + c = ((unsigned char)src & 0xFF); + dest = (value != NULL) ? value : &trash; + + *dest = c; + c -= vec->ucs4_offset; + + if (c < 0) return CET_SUCCESS; + else if ((c >= vec->ucs4_count) || (vec->ucs4_map[c] == -1)) return CET_ERROR; + else + { + *dest = vec->ucs4_map[c]; + return CET_SUCCESS; + } +} + +/* %%% cet_ucs4_to_utf8 %%% + * + * convert single UCS-4 value into UTF-8 sequence + * + * return values: >= 0: length of produced UTF-8 sequence + * < 0: -bytes more needed in target space + */ + +int +cet_ucs4_to_utf8(char *dest, size_t dest_size, int value) +{ + int result; + unsigned char trash[16]; + unsigned char *c; + + c = (dest != NULL) ? (unsigned char *) dest : trash; + + if ((value & 0xffffff80) == 0) /* <= 7 bits */ + { + if (dest_size < 1) return (dest_size - 1); + *c++ = value; + result = 1; + } + else if ((value & 0xfffff800) == 0) /* <= 11 bits */ + { + if (dest_size < 2) return (dest_size - 2); + *c++ = (0xc0 | (value >> 6)); + *c++ = (0x80 | (value & 0x3f)); + result = 2; + + } + else if ((value & 0xffff0000) == 0) /* <= 16 bits */ + { + if (dest_size < 3) return (dest_size - 3); + *c++ = (0xe0 | (value >> 12)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 3; + } + else if ((value & 0xffe00000) == 0) /* <= 21 bits */ + { + if (dest_size < 4) return (dest_size - 4); + *c++ = (0xf0 | (value >> 18)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 4; + } + else if ((value & 0xfc000000) == 0) /* <= 26 bits */ + { + if (dest_size < 5) return (dest_size - 5); + *c++ = (0xf8 | (value >> 24)); + *c++ = (0x80 | ((value >> 18) & 0x3f)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 5; + } + else if ((value & 0x80000000) == 0) /* <= 31 bits */ + { + if (dest_size < 6) return (dest_size - 6); + *c++ = (0xfc | (value >> 30)); + *c++ = (0x80 | ((value >> 24) & 0x3f)); + *c++ = (0x80 | ((value >> 18) & 0x3f)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 6; + } + else + { + return 0; /* Value = -1 */ + } + return result; +} + +/* %%% cet_utf8_to_ucs4 %%% + * + * decode single UTF-8 sequence into UCS-4 value + * + * return values: 0 if success, otherwise 1 + */ +int +cet_utf8_to_ucs4(const char *str, int *bytes, int *value) +{ + unsigned char *cp = (unsigned char *)str; + + if (*cp < 0x80) + { + if (bytes != NULL) *bytes = 1; + if (value != NULL) *value = *cp; + return CET_SUCCESS; + } + else + { + unsigned char bits = 0xc0; + unsigned char mask = 0xe0; + int len = 0; + + for (len = 1; len <= 6; len++) /* outer loop, test UTF-8 frame */ + { + if ((*cp & mask) == bits) + { + int i = len; + while (i-- > 0) + { + cp++; + if ((*cp & 0xc0) != 0x80) break; /* invalid */ + else if (i == 0) /* all valid */ + { + char *c = (char *)str; /* found valid sequence, now storing value */ + int res = *c++ & (mask ^ 0xFF); + i = len; + while (i-- > 0) + res = (res << 6) | (*c++ & 0x3f); + + if (bytes != NULL) *bytes = len + 1; + if (value != NULL) *value = res; + return CET_SUCCESS; + } + } + } + bits = (bits >> 1) | 0x80; + mask = (mask >> 1) | 0x80; + } + } + if (bytes != NULL) *bytes = 1; + if (value != NULL) *value = *cp; + return CET_ERROR; /* not valid */ +} + +/* %%% cet_ucs4_to_char %%% + * + * convert single UCS-4 value to original character from CS + * + * return values: coverted character or "CET_NOT_CONVERTABLE_DEFAULT" + * if not possible + */ +short +cet_ucs4_to_char(const int value, const cet_cs_vec_t *vec) +{ + cet_ucs4_link_t *link; + + if ((link = (cet_ucs4_link_t *)vec->ucs4_link)) + { + int i = 0; + int j = vec->ucs4_links - 1; /* validate ucs value against vec */ + while (i <= j) + { + int a = (i + j) >> 1; + int x = link[a].value; + + if (x < value) i = a + 1; + else if (x > value) j = a - 1; + else return link[a].origin; + } + } + + if ((link = (cet_ucs4_link_t *)vec->ucs4_extra)) /* can be NULL */ + { + int i = 0; + int j = vec->ucs4_extras - 1; + while (i <= j) + { + int a = (i + j) >> 1; + int x = link[a].value; + + if (x < value) i = a + 1; + else if (x > value) j = a - 1; + else return link[a].origin; + } + } + + if (value < vec->ucs4_offset + vec->ucs4_count) + return (char)value & 0xFF; + else { + if (vec->fallback && (vec->fallback != vec)) + return cet_ucs4_to_char(value, vec->fallback); + else + return CET_NOT_CONVERTABLE_DEFAULT; + } +} + +/* %%% cet_utf8_to_char %%% + * + * Convert single UTF-8 sequence directly into associated characted + * by given character set. + */ + +short +cet_utf8_to_char(const char *str, const cet_cs_vec_t *vec, /* out */ int *bytes, int *value) +{ + int b, v; + + cet_utf8_to_ucs4(str, &b, &v); /* decode UTF-8 sequence */ + + if (bytes != NULL) *bytes = b; + if (value != NULL) *value = v; + + return cet_ucs4_to_char(v, vec); +} + +/* =========================================================================== */ +/* %%% full string transformation %%% */ +/* =========================================================================== */ + +/* %%% cet_str_utf8_to_any %%% + * + * Converts a UTF-8 string to given character set + */ +char * +cet_str_utf8_to_any(const char *src, const cet_cs_vec_t *vec) +{ + char *c = (char *)src; + int len; + char *res, *dest, *cend; + + if (c == NULL) return NULL; + if (vec->ucs4_count == 0) return xstrdup(src); /* UTF-8 -> UTF-8 */ + + len = strlen(c); + res = dest = xmalloc(len + 1); /* target will become smaller or equal length */ + + cend = c + len; + + while (c < cend) + { + int bytes; + *dest++ = cet_utf8_to_char(c, vec, &bytes, NULL); + c += bytes; + } + *dest = '\0'; + + return res; +} + + +/* %%% cet_str_any_to_utf8 %%% + * + * Converts a string from given character set to UTF-8 + */ +char * +cet_str_any_to_utf8(const char *src, const cet_cs_vec_t *vec) +{ + int len, value; + char *result, *cin, *cout; + char temp = CET_NOT_CONVERTABLE_DEFAULT; + + cin = (char *)src; + if (cin == NULL) return NULL; + if (vec->ucs4_count == 0) return xstrdup(src); /* UTF-8 -> UTF-8 */ + + len = 0; + while (*cin != '\0') /* determine length of resulting UTF-8 string */ + { + if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) + cet_char_to_ucs4(temp, vec, &value); + len += cet_ucs4_to_utf8(NULL, 6, value); + } + + result = cout = xmalloc(len + 1); + cin = (char *)src; + + while (*cin != '\0') + { + if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) + cet_char_to_ucs4(temp, vec, &value); + cout += cet_ucs4_to_utf8(cout, 6, value); + } + *cout = '\0'; + return result; +} + +/* %%% cet_str_uni_to_utf8 %%% + * + * Converts an unicode string to UTF-8 + */ +char * +cet_str_uni_to_utf8(const short *src, const int length) +{ + int i, len; + unsigned short *cin; + char *res, *cout; + + if (src == NULL) return NULL; + + len = 0; + i = length; + cin = (unsigned short *)src; + + while (i-- > 0) + len += cet_ucs4_to_utf8(NULL, 6, le_read16(cin++)); + + res = cout = xmalloc(len + 1); + cin = (unsigned short *)src; + i = length; + + while (i-- > 0) + cout += cet_ucs4_to_utf8(cout, 6, le_read16(cin++)); + + *cout = '\0'; + + return res; +} diff --git a/cet.h b/cet.h new file mode 100644 index 000000000..6b32f1edc --- /dev/null +++ b/cet.h @@ -0,0 +1,71 @@ +/* + + Character encoding transformation - basics header + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#ifndef CET_H +#define CET_H + +#include +#include + +#define CET_ERROR 1 +#define CET_SUCCESS 0 + +typedef struct cet_ucs4_link_s +{ + int value; /* UCS-4 value */ + short origin; /* associeted character */ +} cet_ucs4_link_t; + +typedef struct cet_cs_vec_s +{ + const char *name; /* name of character set */ + const char **alias; /* alias table */ + struct cet_cs_vec_s *fallback; /* fallback character set */ + void *unused; + const int *ucs4_map; /* char to UCS-4 value table */ + const int ucs4_offset; /* first non standard character */ + const int ucs4_count; /* values in table */ + const cet_ucs4_link_t *ucs4_link; /* UCS-4 to char backward links */ + const int ucs4_links; /* number of links */ + const cet_ucs4_link_t *ucs4_extra; /* Non standard UCS-4 to ... */ + const int ucs4_extras; /* number of extra links */ + struct cet_cs_vec_s *next; +} cet_cs_vec_t; + +/* single char/value transmission */ + +int cet_utf8_to_ucs4(const char *str, int *bytes, int *value); +int cet_ucs4_to_utf8(char *dest, size_t dest_size, int value); + +/* single char/value transmission - vec based */ + +int cet_char_to_ucs4(const char src, const cet_cs_vec_t *vec, int *value); +short cet_utf8_to_char(const char *str, const cet_cs_vec_t *vecint, int *bytes, int *value); +short cet_ucs4_to_char(const int value, const cet_cs_vec_t *vec); + +/* string to string - vector based */ + +char *cet_str_utf8_to_any(const char *src, const cet_cs_vec_t *vec); +char *cet_str_any_to_utf8(const char *src, const cet_cs_vec_t *vec); + +char *cet_str_uni_to_utf8(const short *src, const int length); + +#endif diff --git a/cet/ansi_x3_4_1968.h b/cet/ansi_x3_4_1968.h new file mode 100644 index 000000000..f8ce866aa --- /dev/null +++ b/cet/ansi_x3_4_1968.h @@ -0,0 +1,501 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ANSI_X3.4-1968" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ansi_x3_4_1968_h +#define ansi_x3_4_1968_h + +#define cet_cs_name_ansi_x3_4_1968 "US-ASCII" + +const char *cet_cs_alias_ansi_x3_4_1968[] = +{ + "ANSI_X3.4-1968", "367", "ANSI_X3.4-1986", "ASCII", + "CP367", "csASCII", "IBM367", "ISO646-US", + "ISO646.1991-IRV", "iso-ir-6", "ISO_646.irv:1991", "us", + NULL +}; + +#define cet_ucs4_ofs_ansi_x3_4_1968 128 +#define cet_ucs4_cnt_ansi_x3_4_1968 1 + +const int cet_ucs4_map_ansi_x3_4_1968[cet_ucs4_cnt_ansi_x3_4_1968]; + +#define cet_ucs4_to_ansi_x3_4_1968_ct 1 + +const cet_ucs4_link_t cet_ucs4_to_ansi_x3_4_1968_links[cet_ucs4_to_ansi_x3_4_1968_ct]; + +// #define cet_ucs4_to_ansi_x3_4_1968_extra_ct 200 + +const cet_ucs4_link_t cet_ucs4_to_ansi_x3_4_1968_extra[] = +/* ------------------------------------------*/ +/* !!! sorted by UCS-4 value !!! */ +/* ------------------------------------------*/ +{ + {0x00C0, (unsigned char) 'A'}, // latin capital letter a with grave + {0x00C1, (unsigned char) 'A'}, // latin capital letter a with acute + {0x00C2, (unsigned char) 'A'}, // latin capital letter a with circumflex + {0x00C3, (unsigned char) 'A'}, // latin capital letter a with tilde + {0x00C4, (unsigned char) 'A'}, // latin capital letter a with diaeresis + {0x00C5, (unsigned char) 'A'}, // latin capital letter a with ring above + {0x00C7, (unsigned char) 'C'}, // latin capital letter c with cedilla + {0x00C8, (unsigned char) 'E'}, // latin capital letter e with grave + {0x00C9, (unsigned char) 'E'}, // latin capital letter e with acute + {0x00CA, (unsigned char) 'E'}, // latin capital letter e with circumflex + {0x00CB, (unsigned char) 'E'}, // latin capital letter e with diaeresis + {0x00CC, (unsigned char) 'I'}, // latin capital letter i with grave + {0x00CD, (unsigned char) 'I'}, // latin capital letter i with acute + {0x00CE, (unsigned char) 'I'}, // latin capital letter i with circumflex + {0x00CF, (unsigned char) 'I'}, // latin capital letter i with diaeresis + {0x00D1, (unsigned char) 'N'}, // latin capital letter n with tilde + {0x00D2, (unsigned char) 'O'}, // latin capital letter o with grave + {0x00D3, (unsigned char) 'O'}, // latin capital letter o with acute + {0x00D4, (unsigned char) 'O'}, // latin capital letter o with circumflex + {0x00D5, (unsigned char) 'O'}, // latin capital letter o with tilde + {0x00D6, (unsigned char) 'O'}, // latin capital letter o with diaeresis + {0x00D8, (unsigned char) 'O'}, // latin capital letter o with stroke + {0x00D9, (unsigned char) 'U'}, // latin capital letter u with grave + {0x00DA, (unsigned char) 'U'}, // latin capital letter u with acute + {0x00DB, (unsigned char) 'U'}, // latin capital letter u with circumflex + {0x00DC, (unsigned char) 'U'}, // latin capital letter u with diaeresis + {0x00DD, (unsigned char) 'Y'}, // latin capital letter y with acute + {0x00E0, (unsigned char) 'a'}, // latin small letter a with grave + {0x00E1, (unsigned char) 'a'}, // latin small letter a with acute + {0x00E2, (unsigned char) 'a'}, // latin small letter a with circumflex + {0x00E3, (unsigned char) 'a'}, // latin small letter a with tilde + {0x00E4, (unsigned char) 'a'}, // latin small letter a with diaeresis + {0x00E5, (unsigned char) 'a'}, // latin small letter a with ring above + {0x00E7, (unsigned char) 'c'}, // latin small letter c with cedilla + {0x00E8, (unsigned char) 'e'}, // latin small letter e with grave + {0x00E9, (unsigned char) 'e'}, // latin small letter e with acute + {0x00EA, (unsigned char) 'e'}, // latin small letter e with circumflex + {0x00EB, (unsigned char) 'e'}, // latin small letter e with diaeresis + {0x00EC, (unsigned char) 'i'}, // latin small letter i with grave + {0x00ED, (unsigned char) 'i'}, // latin small letter i with acute + {0x00EE, (unsigned char) 'i'}, // latin small letter i with circumflex + {0x00EF, (unsigned char) 'i'}, // latin small letter i with diaeresis + {0x00F1, (unsigned char) 'n'}, // latin small letter n with tilde + {0x00F2, (unsigned char) 'o'}, // latin small letter o with grave + {0x00F3, (unsigned char) 'o'}, // latin small letter o with acute + {0x00F4, (unsigned char) 'o'}, // latin small letter o with circumflex + {0x00F5, (unsigned char) 'o'}, // latin small letter o with tilde + {0x00F6, (unsigned char) 'o'}, // latin small letter o with diaeresis + {0x00F8, (unsigned char) 'o'}, // latin small letter o with stroke + {0x00F9, (unsigned char) 'u'}, // latin small letter u with grave + {0x00FA, (unsigned char) 'u'}, // latin small letter u with acute + {0x00FB, (unsigned char) 'u'}, // latin small letter u with circumflex + {0x00FC, (unsigned char) 'u'}, // latin small letter u with diaeresis + {0x00FD, (unsigned char) 'y'}, // latin small letter y with acute + {0x00FF, (unsigned char) 'y'}, // latin small letter y with diaeresis + {0x0100, (unsigned char) 'A'}, // latin capital letter a with macron + {0x0101, (unsigned char) 'a'}, // latin small letter a with macron + {0x0102, (unsigned char) 'A'}, // latin capital letter a with breve + {0x0103, (unsigned char) 'a'}, // latin small letter a with breve + {0x0104, (unsigned char) 'A'}, // latin capital letter a with ogonek + {0x0105, (unsigned char) 'a'}, // latin small letter a with ogonek + {0x0106, (unsigned char) 'C'}, // latin capital letter c with acute + {0x0107, (unsigned char) 'c'}, // latin small letter c with acute + {0x0108, (unsigned char) 'C'}, // latin capital letter c with circumflex + {0x0109, (unsigned char) 'c'}, // latin small letter c with circumflex + {0x010A, (unsigned char) 'C'}, // latin capital letter c with dot above + {0x010B, (unsigned char) 'c'}, // latin small letter c with dot above + {0x010C, (unsigned char) 'C'}, // latin capital letter c with caron + {0x010D, (unsigned char) 'c'}, // latin small letter c with caron + {0x010E, (unsigned char) 'D'}, // latin capital letter d with caron + {0x010F, (unsigned char) 'd'}, // latin small letter d with caron + {0x0110, (unsigned char) 'D'}, // latin capital letter d with stroke + {0x0111, (unsigned char) 'd'}, // latin small letter d with stroke + {0x0112, (unsigned char) 'E'}, // latin capital letter e with macron + {0x0113, (unsigned char) 'e'}, // latin small letter e with macron + {0x0114, (unsigned char) 'E'}, // latin capital letter e with breve + {0x0115, (unsigned char) 'e'}, // latin small letter e with breve + {0x0116, (unsigned char) 'E'}, // latin capital letter e with dot above + {0x0117, (unsigned char) 'e'}, // latin small letter e with dot above + {0x0118, (unsigned char) 'E'}, // latin capital letter e with ogonek + {0x0119, (unsigned char) 'e'}, // latin small letter e with ogonek + {0x011A, (unsigned char) 'E'}, // latin capital letter e with caron + {0x011B, (unsigned char) 'e'}, // latin small letter e with caron + {0x011C, (unsigned char) 'G'}, // latin capital letter g with circumflex + {0x011D, (unsigned char) 'g'}, // latin small letter g with circumflex + {0x011E, (unsigned char) 'G'}, // latin capital letter g with breve + {0x011F, (unsigned char) 'g'}, // latin small letter g with breve + {0x0120, (unsigned char) 'G'}, // latin capital letter g with dot above + {0x0121, (unsigned char) 'g'}, // latin small letter g with dot above + {0x0122, (unsigned char) 'G'}, // latin capital letter g with cedilla + {0x0123, (unsigned char) 'g'}, // latin small letter g with cedilla + {0x0124, (unsigned char) 'H'}, // latin capital letter h with circumflex + {0x0125, (unsigned char) 'h'}, // latin small letter h with circumflex + {0x0126, (unsigned char) 'H'}, // latin capital letter h with stroke + {0x0127, (unsigned char) 'h'}, // latin small letter h with stroke + {0x0128, (unsigned char) 'I'}, // latin capital letter i with tilde + {0x0129, (unsigned char) 'i'}, // latin small letter i with tilde + {0x012A, (unsigned char) 'I'}, // latin capital letter i with macron + {0x012B, (unsigned char) 'i'}, // latin small letter i with macron + {0x012C, (unsigned char) 'I'}, // latin capital letter i with breve + {0x012D, (unsigned char) 'i'}, // latin small letter i with breve + {0x012E, (unsigned char) 'I'}, // latin capital letter i with ogonek + {0x012F, (unsigned char) 'i'}, // latin small letter i with ogonek + {0x0130, (unsigned char) 'I'}, // latin capital letter i with dot above + {0x0131, (unsigned char) 'i'}, // latin small letter dotless i + {0x0134, (unsigned char) 'J'}, // latin capital letter j with circumflex + {0x0135, (unsigned char) 'j'}, // latin small letter j with circumflex + {0x0136, (unsigned char) 'K'}, // latin capital letter k with cedilla + {0x0137, (unsigned char) 'k'}, // latin small letter k with cedilla + {0x0139, (unsigned char) 'L'}, // latin capital letter l with acute + {0x013A, (unsigned char) 'l'}, // latin small letter l with acute + {0x013B, (unsigned char) 'L'}, // latin capital letter l with cedilla + {0x013C, (unsigned char) 'l'}, // latin small letter l with cedilla + {0x013D, (unsigned char) 'L'}, // latin capital letter l with caron + {0x013E, (unsigned char) 'l'}, // latin small letter l with caron + {0x0141, (unsigned char) 'L'}, // latin capital letter l with stroke + {0x0142, (unsigned char) 'l'}, // latin small letter l with stroke + {0x0143, (unsigned char) 'N'}, // latin capital letter n with acute + {0x0144, (unsigned char) 'n'}, // latin small letter n with acute + {0x0145, (unsigned char) 'N'}, // latin capital letter n with cedilla + {0x0146, (unsigned char) 'n'}, // latin small letter n with cedilla + {0x0147, (unsigned char) 'N'}, // latin capital letter n with caron + {0x0148, (unsigned char) 'n'}, // latin small letter n with caron + {0x014C, (unsigned char) 'O'}, // latin capital letter o with macron + {0x014D, (unsigned char) 'o'}, // latin small letter o with macron + {0x014E, (unsigned char) 'O'}, // latin capital letter o with breve + {0x014F, (unsigned char) 'o'}, // latin small letter o with breve + {0x0150, (unsigned char) 'O'}, // latin capital letter o with double acute + {0x0151, (unsigned char) 'o'}, // latin small letter o with double acute + {0x0152, (unsigned char) 'O'}, // latin capital ligature oe + {0x0153, (unsigned char) 'o'}, // latin small ligature oe + {0x0154, (unsigned char) 'R'}, // latin capital letter r with acute + {0x0155, (unsigned char) 'r'}, // latin small letter r with acute + {0x0156, (unsigned char) 'R'}, // latin capital letter r with cedilla + {0x0157, (unsigned char) 'r'}, // latin small letter r with cedilla + {0x0158, (unsigned char) 'R'}, // latin capital letter r with caron + {0x0159, (unsigned char) 'r'}, // latin small letter r with caron + {0x015A, (unsigned char) 'S'}, // latin capital letter s with acute + {0x015B, (unsigned char) 's'}, // latin small letter s with acute + {0x015C, (unsigned char) 'S'}, // latin capital letter s with circumflex + {0x015D, (unsigned char) 's'}, // latin small letter s with circumflex + {0x015E, (unsigned char) 'S'}, // latin capital letter s with cedilla + {0x015F, (unsigned char) 's'}, // latin small letter s with cedilla + {0x0160, (unsigned char) 'S'}, // latin capital letter s with caron + {0x0161, (unsigned char) 's'}, // latin small letter s with caron + {0x0162, (unsigned char) 'T'}, // latin capital letter t with cedilla + {0x0163, (unsigned char) 't'}, // latin small letter t with cedilla + {0x0164, (unsigned char) 'T'}, // latin capital letter t with caron + {0x0165, (unsigned char) 't'}, // latin small letter t with caron + {0x0166, (unsigned char) 'T'}, // latin capital letter t with stroke + {0x0167, (unsigned char) 't'}, // latin small letter t with stroke + {0x0168, (unsigned char) 'U'}, // latin capital letter u with tilde + {0x0169, (unsigned char) 'u'}, // latin small letter u with tilde + {0x016A, (unsigned char) 'U'}, // latin capital letter u with macron + {0x016B, (unsigned char) 'u'}, // latin small letter u with macron + {0x016C, (unsigned char) 'U'}, // latin capital letter u with breve + {0x016D, (unsigned char) 'u'}, // latin small letter u with breve + {0x016E, (unsigned char) 'U'}, // latin capital letter u with ring above + {0x016F, (unsigned char) 'u'}, // latin small letter u with ring above + {0x0170, (unsigned char) 'U'}, // latin capital letter u with double acute + {0x0171, (unsigned char) 'u'}, // latin small letter u with double acute + {0x0172, (unsigned char) 'U'}, // latin capital letter u with ogonek + {0x0173, (unsigned char) 'u'}, // latin small letter u with ogonek + {0x0174, (unsigned char) 'W'}, // latin capital letter w with circumflex + {0x0175, (unsigned char) 'w'}, // latin small letter w with circumflex + {0x0176, (unsigned char) 'Y'}, // latin capital letter y with circumflex + {0x0177, (unsigned char) 'y'}, // latin small letter y with circumflex + {0x0178, (unsigned char) 'Y'}, // latin capital letter y with diaeresis + {0x0179, (unsigned char) 'Z'}, // latin capital letter z with acute + {0x017A, (unsigned char) 'z'}, // latin small letter z with acute + {0x017B, (unsigned char) 'Z'}, // latin capital letter z with dot above + {0x017C, (unsigned char) 'z'}, // latin small letter z with dot above + {0x017D, (unsigned char) 'Z'}, // latin capital letter z with caron + {0x017E, (unsigned char) 'z'}, // latin small letter z with caron + {0x0180, (unsigned char) 'b'}, // latin small letter b with stroke + {0x0189, (unsigned char) 'D'}, // latin capital letter african d + {0x0191, (unsigned char) 'F'}, // latin capital letter f with hook + {0x0192, (unsigned char) 'f'}, // latin small letter f with hook + {0x0197, (unsigned char) 'I'}, // latin capital letter i with stroke + {0x019A, (unsigned char) 'l'}, // latin small letter l with bar + {0x019F, (unsigned char) 'O'}, // latin capital letter o with middle tilde + {0x01A0, (unsigned char) 'O'}, // latin capital letter o with horn + {0x01A1, (unsigned char) 'o'}, // latin small letter o with horn + {0x01AB, (unsigned char) 't'}, // latin small letter t with palatal hook + {0x01AE, (unsigned char) 'T'}, // latin capital letter t with retroflex hook + {0x01AF, (unsigned char) 'U'}, // latin capital letter u with horn + {0x01B0, (unsigned char) 'u'}, // latin small letter u with horn + {0x01B6, (unsigned char) 'z'}, // latin small letter z with stroke + {0x01C0, (unsigned char) '|'}, // latin letter dental click + {0x01C3, (unsigned char) '!'}, // latin letter retroflex click + {0x01CD, (unsigned char) 'A'}, // latin capital letter a with caron + {0x01CE, (unsigned char) 'a'}, // latin small letter a with caron + {0x01CF, (unsigned char) 'I'}, // latin capital letter i with caron + {0x01D0, (unsigned char) 'i'}, // latin small letter i with caron + {0x01D1, (unsigned char) 'O'}, // latin capital letter o with caron + {0x01D2, (unsigned char) 'o'}, // latin small letter o with caron + {0x01D3, (unsigned char) 'U'}, // latin capital letter u with caron + {0x01D4, (unsigned char) 'u'}, // latin small letter u with caron + {0x01D5, (unsigned char) 'U'}, // latin capital letter u with diaeresis and macron + {0x01D6, (unsigned char) 'u'}, // latin small letter u with diaeresis and macron + {0x01D7, (unsigned char) 'U'}, // latin capital letter u with diaeresis and acute + {0x01D8, (unsigned char) 'u'}, // latin small letter u with diaeresis and acute + {0x01D9, (unsigned char) 'U'}, // latin capital letter u with diaeresis and caron + {0x01DA, (unsigned char) 'u'}, // latin small letter u with diaeresis and caron + {0x01DB, (unsigned char) 'U'}, // latin capital letter u with diaeresis and grave + {0x01DC, (unsigned char) 'u'}, // latin small letter u with diaeresis and grave + {0x01DE, (unsigned char) 'A'}, // latin capital letter a with diaeresis and macron + {0x01DF, (unsigned char) 'a'}, // latin small letter a with diaeresis and macron + {0x01E4, (unsigned char) 'G'}, // latin capital letter g with stroke + {0x01E5, (unsigned char) 'g'}, // latin small letter g with stroke + {0x01E6, (unsigned char) 'G'}, // latin capital letter g with caron + {0x01E7, (unsigned char) 'g'}, // latin small letter g with caron + {0x01E8, (unsigned char) 'K'}, // latin capital letter k with caron + {0x01E9, (unsigned char) 'k'}, // latin small letter k with caron + {0x01EA, (unsigned char) 'O'}, // latin capital letter o with ogonek + {0x01EB, (unsigned char) 'o'}, // latin small letter o with ogonek + {0x01EC, (unsigned char) 'O'}, // latin capital letter o with ogonek and macron + {0x01ED, (unsigned char) 'o'}, // latin small letter o with ogonek and macron + {0x01F0, (unsigned char) 'j'}, // latin small letter j with caron + {0x0261, (unsigned char) 'g'}, // latin small letter script g + {0x02B9, (unsigned char) '\''}, // modifier letter prime + {0x02BA, (unsigned char) '"'}, // modifier letter double prime + {0x02BC, (unsigned char) '\''}, // modifier letter apostrophe + {0x02C4, (unsigned char) '^'}, // modifier letter up arrowhead + {0x02C6, (unsigned char) '^'}, // modifier letter circumflex accent + {0x02C7, (unsigned char) '^'}, // caron + {0x02C8, (unsigned char) '\''}, // modifier letter vertical line + {0x02CB, (unsigned char) '`'}, // modifier letter grave accent + {0x02CD, (unsigned char) '_'}, // modifier letter low macron + {0x02D8, (unsigned char) '^'}, // circumflex accent + {0x02D9, (unsigned char) '\''}, // dot above + {0x02DC, (unsigned char) '~'}, // small tilde + {0x0300, (unsigned char) '`'}, // combining grave accent + {0x0302, (unsigned char) '^'}, // combining circumflex accent + {0x0303, (unsigned char) '~'}, // combining tilde + {0x030E, (unsigned char) '"'}, // combining double vertical line above + {0x0331, (unsigned char) '_'}, // combining macron below + {0x0332, (unsigned char) '_'}, // combining low line + {0x037E, (unsigned char) ';'}, // greek question mark + {0x0393, (unsigned char) 'G'}, // greek capital letter gamma + {0x0398, (unsigned char) 'T'}, // greek capital letter theta + {0x03A3, (unsigned char) 'S'}, // greek capital letter sigma + {0x03A6, (unsigned char) 'F'}, // greek capital letter phi + {0x03A9, (unsigned char) 'O'}, // greek capital letter omega + {0x03B1, (unsigned char) 'a'}, // greek small letter alpha + {0x03B4, (unsigned char) 'd'}, // greek small letter delta + {0x03B5, (unsigned char) 'e'}, // greek small letter epsilon + {0x03C0, (unsigned char) 'p'}, // greek small letter pi + {0x03C3, (unsigned char) 's'}, // greek small letter sigma + {0x03C4, (unsigned char) 't'}, // greek small letter tau + {0x03C6, (unsigned char) 'f'}, // greek small letter phi + {0x04BB, (unsigned char) 'h'}, // cyrillic small letter shha + {0x0589, (unsigned char) ':'}, // armenian full stop + {0x066A, (unsigned char) '%'}, // arabic percent sign + {0x1E02, (unsigned char) 'B'}, // latin capital letter b with dot above + {0x1E03, (unsigned char) 'b'}, // latin small letter b with dot above + {0x1E0A, (unsigned char) 'D'}, // latin capital letter d with dot above + {0x1E0B, (unsigned char) 'd'}, // latin small letter d with dot above + {0x1E1E, (unsigned char) 'F'}, // latin capital letter f with dot above + {0x1E1F, (unsigned char) 'f'}, // latin small letter f with dot above + {0x1E40, (unsigned char) 'M'}, // latin capital letter m with dot above + {0x1E41, (unsigned char) 'm'}, // latin small letter m with dot above + {0x1E56, (unsigned char) 'P'}, // latin capital letter p with dot above + {0x1E57, (unsigned char) 'p'}, // latin small letter p with dot above + {0x1E60, (unsigned char) 'S'}, // latin capital letter s with dot above + {0x1E61, (unsigned char) 's'}, // latin small letter s with dot above + {0x1E6A, (unsigned char) 'T'}, // latin capital letter t with dot above + {0x1E6B, (unsigned char) 't'}, // latin small letter t with dot above + {0x1E80, (unsigned char) 'W'}, // latin capital letter w with grave + {0x1E81, (unsigned char) 'w'}, // latin small letter w with grave + {0x1E82, (unsigned char) 'W'}, // latin capital letter w with acute + {0x1E83, (unsigned char) 'w'}, // latin small letter w with acute + {0x1E84, (unsigned char) 'W'}, // latin capital letter w with diaeresis + {0x1E85, (unsigned char) 'w'}, // latin small letter w with diaeresis + {0x1E94, (unsigned char) 'u'}, + {0x1EF2, (unsigned char) 'Y'}, // latin capital letter y with grave + {0x1EF3, (unsigned char) 'y'}, // latin small letter y with grave + {0x2000, (unsigned char) ' '}, // en quad + {0x2001, (unsigned char) ' '}, // em quad + {0x2002, (unsigned char) ' '}, // en space + {0x2003, (unsigned char) ' '}, // em space + {0x2004, (unsigned char) ' '}, // three-per-em space + {0x2005, (unsigned char) ' '}, // four-per-em space + {0x2006, (unsigned char) ' '}, // six-per-em space + {0x2010, (unsigned char) '-'}, // hyphen + {0x2011, (unsigned char) '-'}, // non-breaking hyphen + {0x2017, (unsigned char) '='}, // double low line + {0x201C, (unsigned char) '"'}, + {0x201D, (unsigned char) '"'}, + {0x2032, (unsigned char) '\''}, // prime + {0x2035, (unsigned char) '`'}, // reversed prime + {0x203C, (unsigned char) '!'}, // double exclamation mark + {0x2044, (unsigned char) '/'}, // fraction slash + {0x2074, (unsigned char) '4'}, // superscript four + {0x2075, (unsigned char) '5'}, // superscript five + {0x2076, (unsigned char) '6'}, // superscript six + {0x2077, (unsigned char) '7'}, // superscript seven + {0x2078, (unsigned char) '8'}, // superscript eight + {0x207F, (unsigned char) 'n'}, // superscript latin small letter n + {0x2080, (unsigned char) '0'}, // subscript zero + {0x2081, (unsigned char) '1'}, // subscript one + {0x2082, (unsigned char) '2'}, // subscript two + {0x2083, (unsigned char) '3'}, // subscript three + {0x2084, (unsigned char) '4'}, // subscript four + {0x2085, (unsigned char) '5'}, // subscript five + {0x2086, (unsigned char) '6'}, // subscript six + {0x2087, (unsigned char) '7'}, // subscript seven + {0x2088, (unsigned char) '8'}, // subscript eight + {0x2089, (unsigned char) '9'}, // subscript nine + {0x20A7, (unsigned char) 'P'}, // peseta sign + {0x2102, (unsigned char) 'C'}, // double-struck capital c + {0x2107, (unsigned char) 'E'}, // euler constant + {0x210A, (unsigned char) 'g'}, // script small g + {0x210B, (unsigned char) 'H'}, // script capital h + {0x210C, (unsigned char) 'H'}, // black-letter capital h + {0x210D, (unsigned char) 'H'}, // double-struck capital h + {0x210E, (unsigned char) 'h'}, // planck constant + {0x2110, (unsigned char) 'I'}, // script capital i + {0x2111, (unsigned char) 'I'}, // black-letter capital i + {0x2112, (unsigned char) 'L'}, // script capital l + {0x2113, (unsigned char) 'l'}, // script small l + {0x2115, (unsigned char) 'N'}, // double-struck capital n + {0x2118, (unsigned char) 'P'}, // script capital p + {0x2119, (unsigned char) 'P'}, // double-struck capital p + {0x211A, (unsigned char) 'Q'}, // double-struck capital q + {0x211B, (unsigned char) 'R'}, // script capital r + {0x211C, (unsigned char) 'R'}, // black-letter capital r + {0x211D, (unsigned char) 'R'}, // double-struck capital r + {0x2124, (unsigned char) 'Z'}, // double-struck capital z + {0x2128, (unsigned char) 'Z'}, // black-letter capital z + {0x212A, (unsigned char) 'K'}, // kelvin sign + {0x212C, (unsigned char) 'B'}, // script capital b + {0x212D, (unsigned char) 'C'}, // black-letter capital c + {0x212E, (unsigned char) 'e'}, // estimated symbol + {0x212F, (unsigned char) 'e'}, // script small e + {0x2130, (unsigned char) 'E'}, // script capital e + {0x2131, (unsigned char) 'F'}, // script capital f + {0x2133, (unsigned char) 'M'}, // script capital m + {0x2134, (unsigned char) 'o'}, // script small o + {0x2190, (unsigned char) '<'}, // leftwards arrow + {0x2191, (unsigned char) '^'}, // upwards arrow + {0x2192, (unsigned char) '>'}, // rightwards arrow + {0x2193, (unsigned char) 'v'}, // downwards arrow + {0x2194, (unsigned char) '-'}, // left right arrow + {0x2195, (unsigned char) '|'}, // up down arrow + {0x21A8, (unsigned char) '|'}, // up down arrow with base + {0x2212, (unsigned char) '-'}, // minus sign + {0x2215, (unsigned char) '/'}, // division slash + {0x2216, (unsigned char) '\\'}, // set minus + {0x2217, (unsigned char) '*'}, // asterisk operator + {0x221A, (unsigned char) 'v'}, // square root + {0x221E, (unsigned char) '8'}, // infinity + {0x221F, (unsigned char) 'L'}, // right angle + {0x2223, (unsigned char) '|'}, // divides + {0x2229, (unsigned char) 'n'}, // intersection + {0x2236, (unsigned char) ':'}, // ratio + {0x223C, (unsigned char) '~'}, // tilde operator + {0x2261, (unsigned char) '='}, // identical to + {0x2264, (unsigned char) '='}, // less-than or equal to + {0x2265, (unsigned char) '='}, // greater-than or equal to + {0x2303, (unsigned char) '^'}, // up arrowhead + {0x2320, (unsigned char) '('}, // top half integral + {0x2321, (unsigned char) ')'}, // bottom half integral + {0x2329, (unsigned char) '<'}, // left-pointing angle bracket + {0x232A, (unsigned char) '>'}, // right-pointing angle bracket + {0x25AC, (unsigned char) '-'}, // black rectangle + {0x25B2, (unsigned char) '^'}, // black up-pointing triangle + {0x25BA, (unsigned char) '>'}, // black right-pointing pointer + {0x25C4, (unsigned char) '<'}, // black left-pointing pointer + {0x25CB, (unsigned char) '0'}, // white circle + {0x25D9, (unsigned char) '0'}, // inverse white circle + {0x263A, (unsigned char) 'O'}, // white smiling face + {0x263B, (unsigned char) 'O'}, // black smiling face + {0x263C, (unsigned char) '0'}, // white sun with rays + {0x2640, (unsigned char) '+'}, // female sign + {0x2642, (unsigned char) '>'}, // male sign + {0x266A, (unsigned char) 'd'}, // eighth note + {0x266B, (unsigned char) 'd'}, // beamed eighth notes + {0x2758, (unsigned char) '|'}, // light vertical bar + {0x3000, (unsigned char) ' '}, // ideographic space + {0x3008, (unsigned char) '<'}, // left angle bracket + {0x3009, (unsigned char) '>'}, // right angle bracket + {0x301A, (unsigned char) '['}, // left white square bracket + {0x301B, (unsigned char) ']'}, // right white square bracket + {0x301D, (unsigned char) '"'}, // reversed double prime quotation mark + {0x301E, (unsigned char) '"'} // double prime quotation mark +}; + +cet_cs_vec_t cet_cs_vec_ansi_x3_4_1968 = /* defined in cet.h */ +{ + cet_cs_name_ansi_x3_4_1968, /* name of character set */ + cet_cs_alias_ansi_x3_4_1968, /* alias table */ + + NULL, /* fallback character set */ + NULL, /* unused */ + + cet_ucs4_map_ansi_x3_4_1968, /* char to UCS-4 value table */ + cet_ucs4_ofs_ansi_x3_4_1968, /* first non standard character */ + cet_ucs4_cnt_ansi_x3_4_1968, /* number of values in table */ + + cet_ucs4_to_ansi_x3_4_1968_links, /* UCS-4 to char links */ + cet_ucs4_to_ansi_x3_4_1968_ct, /* number of links */ + + cet_ucs4_to_ansi_x3_4_1968_extra, /* hand made UCS-4 links */ + sizeof(cet_ucs4_to_ansi_x3_4_1968_extra) / sizeof(cet_ucs4_to_ansi_x3_4_1968_extra[0]), /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ansi_x3_4_1968_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/atarist.h b/cet/atarist.h new file mode 100644 index 000000000..b0403add4 --- /dev/null +++ b/cet/atarist.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "AtariST" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef atarist_h +#define atarist_h + +#define cet_cs_name_atarist "AtariST" + +const char *cet_cs_alias_atarist[] = +{ + "AtariST", NULL +}; + +#define cet_ucs4_ofs_atarist 128 +#define cet_ucs4_cnt_atarist 128 + +const int cet_ucs4_map_atarist[cet_ucs4_cnt_atarist] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x00df, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x00e3, 0x00f5, 0x00d8, 0x00f8, 0x0153, 0x0152, 0x00c0, 0x00c3, + 0x00d5, 0x00a8, 0x00b4, 0x2020, 0x00b6, 0x00a9, 0x00ae, 0x2122, + 0x0133, 0x0132, 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, + 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05db, 0x05dc, 0x05de, 0x05e0, + 0x05e1, 0x05e2, 0x05e4, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, + 0x05df, 0x05da, 0x05dd, 0x05e3, 0x05e5, 0x00a7, 0x2038, 0x221e, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x03b8, 0x2126, 0x03b4, 0x222e, 0x03c6, 0x2208, 0x220f, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2022, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x00b3, 0x00af +}; + +#define cet_ucs4_to_atarist_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_atarist_links[cet_ucs4_to_atarist_ct] = +{ + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a5, 0x9d} /* sign */, + {0x00a7, 0xdd} /* sign */, + {0x00a8, 0xb9} /* diaeresis */, + {0x00a9, 0xbd} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00ae, 0xbe} /* sign */, + {0x00af, 0xff} /* macron */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b3, 0xfe} /* three */, + {0x00b4, 0xba} /* accent */, + {0x00b5, 0xe6} /* sign */, + {0x00b6, 0xbc} /* sign */, + {0x00b7, 0xfa} /* dot */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c0, 0xb6} /* capital letter a with grave */, + {0x00c3, 0xb7} /* capital letter a with tilde */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d5, 0xb8} /* capital letter o with tilde */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d8, 0xb2} /* capital letter o with stroke */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0x9e} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e3, 0xb0} /* small letter a with tilde */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f5, 0xb1} /* small letter o with tilde */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f8, 0xb3} /* small letter o with stroke */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00ff, 0x98} /* small letter y with diaeresis */, + {0x0132, 0xc1} /* capital ligature ij */, + {0x0133, 0xc0} /* small ligature ij */, + {0x0152, 0xb5} /* capital ligature oe */, + {0x0153, 0xb4} /* small ligature oe */, + {0x0192, 0x9f} /* minuscule latine f hameçon */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b2, 0xe1} /* small letter beta */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b8, 0xe9} /* small letter theta */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x03c6, 0xed} /* small letter phi */, + {0x05d0, 0xc2} /* letter alef */, + {0x05d1, 0xc3} /* letter bet */, + {0x05d2, 0xc4} /* letter gimel */, + {0x05d3, 0xc5} /* letter dalet */, + {0x05d4, 0xc6} /* letter he */, + {0x05d5, 0xc7} /* letter vav */, + {0x05d6, 0xc8} /* letter zayin */, + {0x05d7, 0xc9} /* letter het */, + {0x05d8, 0xca} /* letter tet */, + {0x05d9, 0xcb} /* letter yod */, + {0x05da, 0xd9} /* letter final kaf */, + {0x05db, 0xcc} /* letter kaf */, + {0x05dc, 0xcd} /* letter lamed */, + {0x05dd, 0xda} /* letter final mem */, + {0x05de, 0xce} /* letter mem */, + {0x05df, 0xd8} /* letter final nun */, + {0x05e0, 0xcf} /* letter nun */, + {0x05e1, 0xd0} /* letter samekh */, + {0x05e2, 0xd1} /* letter ayin */, + {0x05e3, 0xdb} /* letter final pe */, + {0x05e4, 0xd2} /* letter pe */, + {0x05e5, 0xdc} /* letter final tsadi */, + {0x05e6, 0xd3} /* letter tsadi */, + {0x05e7, 0xd4} /* letter qof */, + {0x05e8, 0xd5} /* letter resh */, + {0x05e9, 0xd6} /* letter shin */, + {0x05ea, 0xd7} /* letter tav */, + {0x2020, 0xbb} /* dagger */, + {0x2022, 0xf9} /* puce */, + {0x2038, 0xde} /* caret */, + {0x207f, 0xfc} /* latin small letter n */, + {0x2122, 0xbf} /* mark sign */, + {0x2126, 0xea} /* sign */, + {0x2208, 0xee} /* of */, + {0x220f, 0xef} /* product */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xdf} /* infinity */, + {0x222e, 0xec} /* integral */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2310, 0xa9} /* not sign */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */ +}; + +/* +#define cet_ucs4_to_atarist_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_atarist_extra[cet_ucs4_to_atarist_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_atarist = /* defined in cet.h */ +{ + cet_cs_name_atarist, /* name of character set */ + cet_cs_alias_atarist, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_atarist, /* char to UCS-4 value table */ + cet_ucs4_ofs_atarist, /* first non standard character */ + cet_ucs4_cnt_atarist, /* number of values in table */ + + cet_ucs4_to_atarist_links, /* UCS-4 to char links */ + cet_ucs4_to_atarist_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int atarist_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x00df, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x00e3, 0x00f5, 0x00d8, 0x00f8, 0x0153, 0x0152, 0x00c0, 0x00c3, + 0x00d5, 0x00a8, 0x00b4, 0x2020, 0x00b6, 0x00a9, 0x00ae, 0x2122, + 0x0133, 0x0132, 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, + 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05db, 0x05dc, 0x05de, 0x05e0, + 0x05e1, 0x05e2, 0x05e4, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, + 0x05df, 0x05da, 0x05dd, 0x05e3, 0x05e5, 0x00a7, 0x2038, 0x221e, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x03b8, 0x2126, 0x03b4, 0x222e, 0x03c6, 0x2208, 0x220f, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2022, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x00b3, 0x00af +}; +*/ + +#endif diff --git a/cet/baltic.h b/cet/baltic.h new file mode 100644 index 000000000..fdc436294 --- /dev/null +++ b/cet/baltic.h @@ -0,0 +1,178 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "baltic" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef baltic_h +#define baltic_h + +#define cet_cs_name_baltic "baltic" + +const char *cet_cs_alias_baltic[] = +{ + "baltic", "iso-ir-179", NULL +}; + +#define cet_ucs4_ofs_baltic 161 +#define cet_ucs4_cnt_baltic 95 + +const int cet_ucs4_map_baltic[cet_ucs4_cnt_baltic] = +{ + 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00d8, + 0x00a9, 0x201e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, 0x00b0, + 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00f8, + 0x00b9, 0x201c, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, 0x012e, + 0x0116, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0104, 0x010c, 0x0122, + 0x00c9, 0x017d, 0x0118, 0x0112, 0x0136, 0x012a, 0x013b, 0x0141, + 0x0145, 0x0143, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, 0x0172, + 0x0160, 0x015a, 0x016a, 0x00dc, 0x017b, 0x0179, 0x00df, 0x012f, + 0x0117, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0105, 0x010d, 0x0123, + 0x00e9, 0x017e, 0x0119, 0x0113, 0x0137, 0x012b, 0x013c, 0x0142, + 0x0146, 0x0144, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, 0x0173, + 0x0161, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017a, 0x0138 +}; + +#define cet_ucs4_to_baltic_ct 54 + +const cet_ucs4_link_t cet_ucs4_to_baltic_links[cet_ucs4_to_baltic_ct] = +{ + {0x00c6, 0xaf} /* capital letter ae */, + {0x00d8, 0xa8} /* capital letter o with stroke */, + {0x00e6, 0xbf} /* small letter ae */, + {0x00f8, 0xb8} /* small letter o with stroke */, + {0x0100, 0xc2} /* capital letter a with macron */, + {0x0101, 0xe2} /* small letter a with macron */, + {0x0104, 0xc6} /* capital letter a with ogonek */, + {0x0105, 0xe6} /* small letter a with ogonek */, + {0x0106, 0xc3} /* capital letter c with acute */, + {0x0107, 0xe3} /* small letter c with acute */, + {0x010c, 0xc7} /* capital letter c with caron */, + {0x010d, 0xe7} /* small letter c with caron */, + {0x0112, 0xcc} /* capital letter e with macron */, + {0x0113, 0xec} /* small letter e with macron */, + {0x0116, 0xc1} /* capital letter e with dot above */, + {0x0117, 0xe1} /* small letter e with dot above */, + {0x0118, 0xcb} /* capital letter e with ogonek */, + {0x0119, 0xeb} /* small letter e with ogonek */, + {0x0122, 0xc8} /* capital letter g with cedilla */, + {0x0123, 0xe8} /* small letter g with cedilla */, + {0x012a, 0xce} /* capital letter i with macron */, + {0x012b, 0xee} /* small letter i with macron */, + {0x012e, 0xc0} /* capital letter i with ogonek */, + {0x012f, 0xe0} /* small letter i with ogonek */, + {0x0136, 0xcd} /* capital letter k with cedilla */, + {0x0137, 0xed} /* small letter k with cedilla */, + {0x0138, 0xff} /* small letter kra (greenlandic) */, + {0x013b, 0xcf} /* capital letter l with cedilla */, + {0x013c, 0xef} /* small letter l with cedilla */, + {0x0141, 0xd0} /* capital letter l with stroke */, + {0x0142, 0xf0} /* small letter l with stroke */, + {0x0143, 0xd2} /* capital letter n with acute */, + {0x0144, 0xf2} /* small letter n with acute */, + {0x0145, 0xd1} /* capital letter n with cedilla */, + {0x0146, 0xf1} /* small letter n with cedilla */, + {0x014c, 0xd4} /* capital letter o with macron */, + {0x014d, 0xf4} /* small letter o with macron */, + {0x015a, 0xda} /* capital letter s with acute */, + {0x015b, 0xfa} /* small letter s with acute */, + {0x0160, 0xd9} /* capital letter s with caron */, + {0x0161, 0xf9} /* small letter s with caron */, + {0x016a, 0xdb} /* capital letter u with macron */, + {0x016b, 0xfb} /* small letter u with macron */, + {0x0172, 0xd8} /* capital letter u with ogonek */, + {0x0173, 0xf8} /* small letter u with ogonek */, + {0x0179, 0xde} /* capital letter z with acute */, + {0x017a, 0xfe} /* small letter z with acute */, + {0x017b, 0xdd} /* capital letter z with dot above */, + {0x017c, 0xfd} /* small letter z with dot above */, + {0x017d, 0xca} /* capital letter z with caron */, + {0x017e, 0xea} /* small letter z with caron */, + {0x201c, 0xba} /* double quotation mark */, + {0x201d, 0xa1} /* double quotation mark */, + {0x201e, 0xaa} /* low-9 quotation mark */ +}; + +/* +#define cet_ucs4_to_baltic_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_baltic_extra[cet_ucs4_to_baltic_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_baltic = /* defined in cet.h */ +{ + cet_cs_name_baltic, /* name of character set */ + cet_cs_alias_baltic, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_baltic, /* char to UCS-4 value table */ + cet_ucs4_ofs_baltic, /* first non standard character */ + cet_ucs4_cnt_baltic, /* number of values in table */ + + cet_ucs4_to_baltic_links, /* UCS-4 to char links */ + cet_ucs4_to_baltic_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int baltic_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00d8, 0x00a9, 0x201e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00f8, 0x00b9, 0x201c, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, + 0x012e, 0x0116, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0104, 0x010c, + 0x0122, 0x00c9, 0x017d, 0x0118, 0x0112, 0x0136, 0x012a, 0x013b, + 0x0141, 0x0145, 0x0143, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0160, 0x015a, 0x016a, 0x00dc, 0x017b, 0x0179, 0x00df, + 0x012f, 0x0117, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0105, 0x010d, + 0x0123, 0x00e9, 0x017e, 0x0119, 0x0113, 0x0137, 0x012b, 0x013c, + 0x0142, 0x0146, 0x0144, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0161, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017a, 0x0138 +}; +*/ + +#endif diff --git a/cet/bs_4730.h b/cet/bs_4730.h new file mode 100644 index 000000000..1aea8fecf --- /dev/null +++ b/cet/bs_4730.h @@ -0,0 +1,127 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "BS_4730" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef bs_4730_h +#define bs_4730_h + +#define cet_cs_name_bs_4730 "BS_4730" + +const char *cet_cs_alias_bs_4730[] = +{ + "BS_4730", "gb", "ISO646-GB", "iso-ir-4", + "uk", NULL +}; + +#define cet_ucs4_ofs_bs_4730 35 +#define cet_ucs4_cnt_bs_4730 93 + +const int cet_ucs4_map_bs_4730[cet_ucs4_cnt_bs_4730] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x007b, 0x007c, 0x007d, 0x203e, 0x007f +}; + +#define cet_ucs4_to_bs_4730_ct 2 + +const cet_ucs4_link_t cet_ucs4_to_bs_4730_links[cet_ucs4_to_bs_4730_ct] = +{ + {0x00a3, 0x23} /* sign */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_bs_4730_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_bs_4730_extra[cet_ucs4_to_bs_4730_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_bs_4730 = /* defined in cet.h */ +{ + cet_cs_name_bs_4730, /* name of character set */ + cet_cs_alias_bs_4730, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_bs_4730, /* char to UCS-4 value table */ + cet_ucs4_ofs_bs_4730, /* first non standard character */ + cet_ucs4_cnt_bs_4730, /* number of values in table */ + + cet_ucs4_to_bs_4730_links, /* UCS-4 to char links */ + cet_ucs4_to_bs_4730_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int bs_4730_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/bs_viewdata.h b/cet/bs_viewdata.h new file mode 100644 index 000000000..b8f450f28 --- /dev/null +++ b/cet/bs_viewdata.h @@ -0,0 +1,134 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "BS_viewdata" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef bs_viewdata_h +#define bs_viewdata_h + +#define cet_cs_name_bs_viewdata "BS_viewdata" + +const char *cet_cs_alias_bs_viewdata[] = +{ + "BS_viewdata", "iso-ir-47", NULL +}; + +#define cet_ucs4_ofs_bs_viewdata 35 +#define cet_ucs4_cnt_bs_viewdata 93 + +const int cet_ucs4_map_bs_viewdata[cet_ucs4_cnt_bs_viewdata] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x2190, 0x00bd, 0x2192, 0x2191, 0x25a1, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00bc, 0x2225, 0x00be, 0x00f7, 0x007f +}; + +#define cet_ucs4_to_bs_viewdata_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_bs_viewdata_links[cet_ucs4_to_bs_viewdata_ct] = +{ + {0x00a3, 0x23} /* sign */, + {0x00bc, 0x7b} /* fraction one quarter */, + {0x00bd, 0x5c} /* fraction one half */, + {0x00be, 0x7d} /* fraction three quarters */, + {0x00f7, 0x7e} /* sign */, + {0x2190, 0x5b} /* arrow */, + {0x2191, 0x5e} /* arrow */, + {0x2192, 0x5d} /* arrow */, + {0x2225, 0x7c} /* to */, + {0x25a1, 0x5f} /* square */ +}; + +/* +#define cet_ucs4_to_bs_viewdata_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_bs_viewdata_extra[cet_ucs4_to_bs_viewdata_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_bs_viewdata = /* defined in cet.h */ +{ + cet_cs_name_bs_viewdata, /* name of character set */ + cet_cs_alias_bs_viewdata, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_bs_viewdata, /* char to UCS-4 value table */ + cet_ucs4_ofs_bs_viewdata, /* first non standard character */ + cet_ucs4_cnt_bs_viewdata, /* number of values in table */ + + cet_ucs4_to_bs_viewdata_links, /* UCS-4 to char links */ + cet_ucs4_to_bs_viewdata_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int bs_viewdata_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x2190, 0x00bd, 0x2192, 0x2191, 0x25a1, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00bc, 0x2225, 0x00be, 0x00f7, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/cp1250.h b/cet/cp1250.h new file mode 100644 index 000000000..4c11b598d --- /dev/null +++ b/cet/cp1250.h @@ -0,0 +1,266 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1250" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1250_h +#define cp1250_h + +#define cet_cs_name_cp1250 "CP1250" + +const char *cet_cs_alias_cp1250[] = +{ + "CP1250", "1250", "ms-ee", "windows-1250", "WIN-CP1250", + NULL +}; + +#define cet_ucs4_ofs_cp1250 128 +#define cet_ucs4_cnt_cp1250 128 + +const int cet_ucs4_map_cp1250[cet_ucs4_cnt_cp1250] = +{ + 0x20ac, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a, + 0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, + 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; + +#define cet_ucs4_to_cp1250_ct 74 + +const cet_ucs4_link_t cet_ucs4_to_cp1250_links[cet_ucs4_to_cp1250_ct] = +{ + {0x0102, 0xc3} /* capital letter a with breve */, + {0x0103, 0xe3} /* small letter a with breve */, + {0x0104, 0xa5} /* capital letter a with ogonek */, + {0x0105, 0xb9} /* small letter a with ogonek */, + {0x0106, 0xc6} /* capital letter c with acute */, + {0x0107, 0xe6} /* small letter c with acute */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x010e, 0xcf} /* capital letter d with caron */, + {0x010f, 0xef} /* small letter d with caron */, + {0x0110, 0xd0} /* capital letter d with stroke */, + {0x0111, 0xf0} /* small letter d with stroke */, + {0x0118, 0xca} /* capital letter e with ogonek */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x011a, 0xcc} /* capital letter e with caron */, + {0x011b, 0xec} /* small letter e with caron */, + {0x0139, 0xc5} /* capital letter l with acute */, + {0x013a, 0xe5} /* small letter l with acute */, + {0x013d, 0xbc} /* capital letter l with caron */, + {0x013e, 0xbe} /* small letter l with caron */, + {0x0141, 0xa3} /* capital letter l with stroke */, + {0x0142, 0xb3} /* small letter l with stroke */, + {0x0143, 0xd1} /* capital letter n with acute */, + {0x0144, 0xf1} /* small letter n with acute */, + {0x0147, 0xd2} /* capital letter n with caron */, + {0x0148, 0xf2} /* small letter n with caron */, + {0x0150, 0xd5} /* capital letter o with double acute */, + {0x0151, 0xf5} /* small letter o with double acute */, + {0x0154, 0xc0} /* capital letter r with acute */, + {0x0155, 0xe0} /* small letter r with acute */, + {0x0158, 0xd8} /* capital letter r with caron */, + {0x0159, 0xf8} /* small letter r with caron */, + {0x015a, 0x8c} /* capital letter s with acute */, + {0x015b, 0x9c} /* small letter s with acute */, + {0x015e, 0xaa} /* capital letter s with cedilla */, + {0x015f, 0xba} /* small letter s with cedilla */, + {0x0160, 0x8a} /* capital letter s with caron */, + {0x0161, 0x9a} /* small letter s with caron */, + {0x0162, 0xde} /* capital letter t with cedilla */, + {0x0163, 0xfe} /* small letter t with cedilla */, + {0x0164, 0x8d} /* capital letter t with caron */, + {0x0165, 0x9d} /* small letter t with caron */, + {0x016e, 0xd9} /* capital letter u with ring above */, + {0x016f, 0xf9} /* small letter u with ring above */, + {0x0170, 0xdb} /* capital letter u with double acute */, + {0x0171, 0xfb} /* small letter u with double acute */, + {0x0179, 0x8f} /* capital letter z with acute */, + {0x017a, 0x9f} /* small letter z with acute */, + {0x017b, 0xaf} /* capital letter z with dot above */, + {0x017c, 0xbf} /* small letter z with dot above */, + {0x017d, 0x8e} /* capital letter z with caron */, + {0x017e, 0x9e} /* small letter z with caron */, + {0x02c7, 0xa1} /* caron */, + {0x02d8, 0xa2} /* breve */, + {0x02d9, 0xff} /* above */, + {0x02db, 0xb2} /* ogonek */, + {0x02dd, 0xbd} /* acute accent */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* Extra table was generated from bestfit1250.txt located at + ftp.unicode.org:/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/ */ + +const cet_ucs4_link_t cet_ucs4_to_cp1250_extra[] = +{ + {0x0189, 0xd0} /* latin capital letter african d */, + {0x02bb, 0x91} /* modifier letter turned comma */, + {0x02c9, 0xaf} /* modifier letter macron */, + {0x02ca, 0xb4} /* modifier letter acute accent */, + {0x02da, 0xb0} /* ring above */, + {0x0301, 0xb4} /* combining acute accent */, + {0x0304, 0xaf} /* combining macron */, + {0x0305, 0xaf} /* combining overline */, + {0x0306, 0xa2} /* combining breve */, + {0x0307, 0xff} /* combining dot above */, + {0x0308, 0xa8} /* combining diaeresis */, + {0x030a, 0xb0} /* combining ring above */, + {0x030c, 0xa1} /* combining caron */, + {0x0327, 0xb8} /* combining cedilla */, + {0x03b2, 0xdf} /* greek small letter beta */, + {0x03bc, 0xb5} /* greek small letter mu */, + {0x2024, 0x95} /* one dot leader */, + {0x2033, 0x94} /* double prime */, + {0x2070, 0xb0} /* superscript zero */, + {0x20a4, 0xa3} /* lira sign */, + {0x212b, 0xc5} /* angstrom sign */, + {0x2190, 0x8b} /* leftwards arrow */, + {0x2192, 0x9b} /* rightwards arrow */, + {0x2193, 0xa1} /* downwards arrow */, + {0x2205, 0xd8} /* empty set */, + {0x2213, 0xb1} /* minus-or-plus sign */, + {0x2218, 0xb0} /* ring operator */, + {0x2219, 0x95} /* bullet operator */, + {0x226a, 0xab} /* much less-than */, + {0x226b, 0xbb} /* much greater-than */, + {0x22c5, 0xb7} /* dot operator */, + {0x2302, 0xa6} /* house */, + {0x2500, 0xa6} /* box drawings light horizontal */, + {0x2510, 0xac} /* box drawings light down and left */, + {0x2551, 0xa6} /* box drawings double vertical */, + {0x2557, 0xac} /* box drawings double down and left */, + {0x2560, 0xa6} /* box drawings double vertical and right */, + {0x2563, 0xa6} /* box drawings double vertical and left */, + {0x2569, 0xa6} /* box drawings double up and horizontal */, + {0x25a0, 0xa6} /* black square */, + {0x25bc, 0xa1} /* black down-pointing triangle */, + {0x25d8, 0x95} /* inverse bullet */, + {0x263a, 0xa2} /* white smiling face */, + {0x263b, 0xa2} /* black smiling face */, + {0x2660, 0xa6} /* black spade suit */, + {0x2663, 0xa6} /* black club suit */, + {0x2665, 0xa6} /* black heart suit */, + {0x2666, 0xa6} /* black diamond suit */, + {0x275b, 0x91} /* heavy single turned comma quotation mark ornament */, + {0x275c, 0x92} /* heavy single comma quotation mark ornament */, + {0x275d, 0x93} /* heavy double turned comma quotation mark ornament */, + {0x275e, 0x94} /* heavy double comma quotation mark ornament */, + {0x300a, 0xab} /* left double angle bracket */, + {0x300b, 0xbb} /* right double angle bracket */, + {0x301d, 0x93} /* reversed double prime quotation mark */, + {0x301e, 0x94} /* double prime quotation mark */, + {0x301f, 0x84} /* low double prime quotation mark */, + {0x30fb, 0xb7} /* katakana middle dot */, + {0x30fc, 0x97} /* katakana-hiragana prolonged sound mark */ +}; + +#define cet_ucs4_to_cp1250_extra_ct sizeof(cet_ucs4_to_cp1250_extra) / sizeof(cet_ucs4_to_cp1250_extra[0]) + +cet_cs_vec_t cet_cs_vec_cp1250 = /* defined in cet.h */ +{ + cet_cs_name_cp1250, /* name of character set */ + cet_cs_alias_cp1250, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1250, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1250, /* first non standard character */ + cet_ucs4_cnt_cp1250, /* number of values in table */ + + cet_ucs4_to_cp1250_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1250_ct, /* number of links */ + + cet_ucs4_to_cp1250_extra, /* hand made UCS-4 links */ + cet_ucs4_to_cp1250_extra_ct, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1250_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a, + 0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, + 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; +*/ + +#endif diff --git a/cet/cp1251.h b/cet/cp1251.h new file mode 100644 index 000000000..4fd0349ac --- /dev/null +++ b/cet/cp1251.h @@ -0,0 +1,275 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1251" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1251_h +#define cp1251_h + +#define cet_cs_name_cp1251 "CP1251" + +const char *cet_cs_alias_cp1251[] = +{ + "CP1251", "1251", "ms-cyrl", "windows-1251", "WIN-CP1251", + NULL +}; + +#define cet_ucs4_ofs_cp1251 128 +#define cet_ucs4_cnt_cp1251 128 + +const int cet_ucs4_map_cp1251[cet_ucs4_cnt_cp1251] = +{ + 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, + 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, + 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, + 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, + 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, + 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, + 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f +}; + +#define cet_ucs4_to_cp1251_ct 112 + +const cet_ucs4_link_t cet_ucs4_to_cp1251_links[cet_ucs4_to_cp1251_ct] = +{ + {0x0401, 0xa8} /* capital letter io */, + {0x0402, 0x80} /* capital letter dje (serbocroatian) */, + {0x0403, 0x81} /* capital letter gje (macedonian) */, + {0x0404, 0xaa} /* capital letter ukrainian ie */, + {0x0405, 0xbd} /* capital letter dze (macedonian) */, + {0x0406, 0xb2} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0xaf} /* capital letter yi (ukrainian) */, + {0x0408, 0xa3} /* capital letter je */, + {0x0409, 0x8a} /* capital letter lje */, + {0x040a, 0x8c} /* capital letter nje */, + {0x040b, 0x8e} /* capital letter tshe (serbocroatian) */, + {0x040c, 0x8d} /* capital letter kje (macedonian) */, + {0x040e, 0xa1} /* capital letter short u (byelorussian) */, + {0x040f, 0x8f} /* capital letter dzhe */, + {0x0410, 0xc0} /* capital letter a */, + {0x0411, 0xc1} /* capital letter be */, + {0x0412, 0xc2} /* capital letter ve */, + {0x0413, 0xc3} /* capital letter ghe */, + {0x0414, 0xc4} /* capital letter de */, + {0x0415, 0xc5} /* capital letter ie */, + {0x0416, 0xc6} /* capital letter zhe */, + {0x0417, 0xc7} /* capital letter ze */, + {0x0418, 0xc8} /* capital letter i */, + {0x0419, 0xc9} /* capital letter short i */, + {0x041a, 0xca} /* capital letter ka */, + {0x041b, 0xcb} /* capital letter el */, + {0x041c, 0xcc} /* capital letter em */, + {0x041d, 0xcd} /* capital letter en */, + {0x041e, 0xce} /* capital letter o */, + {0x041f, 0xcf} /* capital letter pe */, + {0x0420, 0xd0} /* capital letter er */, + {0x0421, 0xd1} /* capital letter es */, + {0x0422, 0xd2} /* capital letter te */, + {0x0423, 0xd3} /* capital letter u */, + {0x0424, 0xd4} /* capital letter ef */, + {0x0425, 0xd5} /* capital letter ha */, + {0x0426, 0xd6} /* capital letter tse */, + {0x0427, 0xd7} /* capital letter che */, + {0x0428, 0xd8} /* capital letter sha */, + {0x0429, 0xd9} /* capital letter shcha */, + {0x042a, 0xda} /* capital letter hard sign */, + {0x042b, 0xdb} /* capital letter yeru */, + {0x042c, 0xdc} /* capital letter soft sign */, + {0x042d, 0xdd} /* capital letter e */, + {0x042e, 0xde} /* capital letter yu */, + {0x042f, 0xdf} /* capital letter ya */, + {0x0430, 0xe0} /* small letter a */, + {0x0431, 0xe1} /* small letter be */, + {0x0432, 0xe2} /* small letter ve */, + {0x0433, 0xe3} /* small letter ghe */, + {0x0434, 0xe4} /* small letter de */, + {0x0435, 0xe5} /* small letter ie */, + {0x0436, 0xe6} /* small letter zhe */, + {0x0437, 0xe7} /* small letter ze */, + {0x0438, 0xe8} /* small letter i */, + {0x0439, 0xe9} /* small letter short i */, + {0x043a, 0xea} /* small letter ka */, + {0x043b, 0xeb} /* small letter el */, + {0x043c, 0xec} /* small letter em */, + {0x043d, 0xed} /* small letter en */, + {0x043e, 0xee} /* small letter o */, + {0x043f, 0xef} /* small letter pe */, + {0x0440, 0xf0} /* small letter er */, + {0x0441, 0xf1} /* small letter es */, + {0x0442, 0xf2} /* small letter te */, + {0x0443, 0xf3} /* small letter u */, + {0x0444, 0xf4} /* small letter ef */, + {0x0445, 0xf5} /* small letter ha */, + {0x0446, 0xf6} /* small letter tse */, + {0x0447, 0xf7} /* small letter che */, + {0x0448, 0xf8} /* small letter sha */, + {0x0449, 0xf9} /* small letter shcha */, + {0x044a, 0xfa} /* small letter hard sign */, + {0x044b, 0xfb} /* small letter yeru */, + {0x044c, 0xfc} /* small letter soft sign */, + {0x044d, 0xfd} /* small letter e */, + {0x044e, 0xfe} /* small letter yu */, + {0x044f, 0xff} /* small letter ya */, + {0x0451, 0xb8} /* small letter io */, + {0x0452, 0x90} /* small letter dje (serbocroatian) */, + {0x0453, 0x83} /* small letter gje (macedonian) */, + {0x0454, 0xba} /* small letter ukrainian ie */, + {0x0455, 0xbe} /* small letter dze (macedonian) */, + {0x0456, 0xb3} /* small letter byelorussian-ukrainian i */, + {0x0457, 0xbf} /* small letter yi (ukrainian) */, + {0x0458, 0xbc} /* small letter je */, + {0x0459, 0x9a} /* small letter lje */, + {0x045a, 0x9c} /* small letter nje */, + {0x045b, 0x9e} /* small letter tshe (serbocroatian) */, + {0x045c, 0x9d} /* small letter kje (macedonian) */, + {0x045e, 0xa2} /* small letter short u (byelorussian) */, + {0x045f, 0x9f} /* small letter dzhe */, + {0x0490, 0xa5} /* capital letter ghe with upturn */, + {0x0491, 0xb4} /* small letter ghe with upturn */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x88} /* euro */, + {0x2116, 0xb9} /* sign */, + {0x2122, 0x99} /* mark sign */ +}; + +/* Extra table was generated from bestfit1251.txt located at + ftp.unicode.org:/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/ */ + +const cet_ucs4_link_t cet_ucs4_to_cp1251_extra[] = +{ + {0x2195, 0xa6} /* up down arrow */, + {0x21a8, 0xa6} /* up down arrow with base */, + {0x2219, 0x95} /* bullet operator */, + {0x2302, 0xa6} /* house */, + {0x2502, 0xa6} /* box drawings light vertical */, + {0x2510, 0xac} /* box drawings light down and left */, + {0x2551, 0xa6} /* box drawings double vertical */, + {0x2553, 0xe3} /* box drawings down double and right single */, + {0x2554, 0xe3} /* box drawings double down and right */, + {0x2555, 0xac} /* box drawings down single and left double */, + {0x2556, 0xac} /* box drawings down double and left single */, + {0x2557, 0xac} /* box drawings double down and left */, + {0x255e, 0xa6} /* box drawings vertical single and right double */, + {0x255f, 0xa6} /* box drawings vertical double and right single */, + {0x2560, 0xa6} /* box drawings double vertical and right */, + {0x2561, 0xa6} /* box drawings vertical single and left double */, + {0x2562, 0xa6} /* box drawings vertical double and left single */, + {0x2563, 0xa6} /* box drawings double vertical and left */, + {0x2567, 0xa6} /* box drawings up single and horizontal double */, + {0x2568, 0xa6} /* box drawings up double and horizontal single */, + {0x2569, 0xa6} /* box drawings double up and horizontal */, + {0x258c, 0xa6} /* left half block */, + {0x2590, 0xa6} /* right half block */, + {0x25a0, 0xa6} /* black square */, + {0x25bc, 0xa1} /* black down-pointing triangle */, + {0x25d8, 0x95} /* inverse bullet */, + {0x2660, 0xa6} /* black spade suit */, + {0x2663, 0xa6} /* black club suit */, + {0x2665, 0xa6} /* black heart suit */, + {0x2666, 0xa6} /* black diamond suit */ +}; + +#define cet_ucs4_to_cp1251_extra_ct sizeof(cet_ucs4_to_cp1251_extra) / sizeof(cet_ucs4_to_cp1251_extra[0]) + +cet_cs_vec_t cet_cs_vec_cp1251 = /* defined in cet.h */ +{ + cet_cs_name_cp1251, /* name of character set */ + cet_cs_alias_cp1251, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1251, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1251, /* first non standard character */ + cet_ucs4_cnt_cp1251, /* number of values in table */ + + cet_ucs4_to_cp1251_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1251_ct, /* number of links */ + + cet_ucs4_to_cp1251_extra, /* hand made UCS-4 links */ + cet_ucs4_to_cp1251_extra_ct, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1251_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, + 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, + 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, + 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, + 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, + 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, + 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f +}; +*/ + +#endif diff --git a/cet/cp1252.h b/cet/cp1252.h new file mode 100644 index 000000000..f270bdb05 --- /dev/null +++ b/cet/cp1252.h @@ -0,0 +1,210 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1252" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1252_h +#define cp1252_h + +#define cet_cs_name_cp1252 "CP1252" + +const char *cet_cs_alias_cp1252[] = +{ + "CP1252", "1252", "ms-ansi", "windows-1252", "WIN-CP1252", + NULL +}; + +#define cet_ucs4_ofs_cp1252 128 +#define cet_ucs4_cnt_cp1252 128 + +const int cet_ucs4_map_cp1252[cet_ucs4_cnt_cp1252] = +{ + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, 0x017d, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, 0x017e, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; + +#define cet_ucs4_to_cp1252_ct 27 + +const cet_ucs4_link_t cet_ucs4_to_cp1252_links[cet_ucs4_to_cp1252_ct] = +{ + {0x0152, 0x8c} /* capital ligature oe */, + {0x0153, 0x9c} /* small ligature oe */, + {0x0160, 0x8a} /* capital letter s with caron */, + {0x0161, 0x9a} /* small letter s with caron */, + {0x0178, 0x9f} /* capital letter y with diaeresis */, + {0x017d, 0x8e} /* capital letter z with caron */, + {0x017e, 0x9e} /* small letter z with caron */, + {0x0192, 0x83} /* minuscule latine f hameçon */, + {0x02c6, 0x88} /* modificative accent circonflexe */, + {0x02dc, 0x98} /* tilde */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* Extra table was generated from bestfit1252.txt located at + ftp.unicode.org:/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/ */ + +const cet_ucs4_link_t cet_ucs4_to_cp1252_extra[] = +{ + {0x0110, 0xd0} /* latin capital letter d with stroke */, + {0x0189, 0xd0} /* latin capital letter african d */, + {0x0191, 0x83} /* latin capital letter f with hook */, + {0x02c9, 0xaf} /* modifier letter macron */, + {0x02ca, 0xb4} /* modifier letter acute accent */, + {0x02da, 0xb0} /* ring above */, + {0x0301, 0xb4} /* combining acute accent */, + {0x0304, 0xaf} /* combining macron */, + {0x0305, 0xaf} /* combining overline */, + {0x0308, 0xa8} /* combining diaeresis */, + {0x030a, 0xb0} /* combining ring above */, + {0x0327, 0xb8} /* combining cedilla */, + {0x03b2, 0xdf} /* greek small letter beta */, + {0x03bc, 0xb5} /* greek small letter mu */, + {0x2024, 0xb7} /* one dot leader */, + {0x2070, 0xb0} /* superscript zero */, + {0x20a1, 0xa2} /* colon sign */, + {0x20a4, 0xa3} /* lira sign */, + {0x212b, 0xc5} /* angstrom sign */, + {0x2205, 0xd8} /* empty set */, + {0x2213, 0xb1} /* minus-or-plus sign */, + {0x2218, 0xb0} /* ring operator */, + {0x2219, 0xb7} /* bullet operator */, + {0x2248, 0x98} /* almost equal to */, + {0x226a, 0xab} /* much less-than */, + {0x226b, 0xbb} /* much greater-than */, + {0x22c5, 0xb7} /* dot operator */, + {0x2302, 0xa6} /* house */, + {0x2310, 0xac} /* reversed not sign */, + {0x2502, 0xa6} /* box drawings light vertical */, + {0x2524, 0xa6} /* box drawings light vertical and left */, + {0x2551, 0xa6} /* box drawings double vertical */, + {0x255e, 0xa6} /* box drawings vertical single and right double */, + {0x255f, 0xa6} /* box drawings vertical double and right single */, + {0x2560, 0xa6} /* box drawings double vertical and right */, + {0x2561, 0xa6} /* box drawings vertical single and left double */, + {0x2562, 0xa6} /* box drawings vertical double and left single */, + {0x2563, 0xa6} /* box drawings double vertical and left */, + {0x2580, 0xaf} /* upper half block */, + {0x2588, 0xa6} /* full block */, + {0x258c, 0xa6} /* left half block */, + {0x2590, 0xa6} /* right half block */, + {0x2591, 0xa6} /* light shade */, + {0x2592, 0xa6} /* medium shade */, + {0x2593, 0xa6} /* dark shade */, + {0x25a0, 0xa6} /* black square */, + {0x263c, 0xa4} /* white sun with rays */, + {0x300a, 0xab} /* left double angle bracket */, + {0x300b, 0xbb} /* right double angle bracket */, + {0x30fb, 0xb7} /* katakana middle dot */ +}; + +#define cet_ucs4_to_cp1252_extra_ct sizeof(cet_ucs4_to_cp1252_extra) / sizeof(cet_ucs4_to_cp1252_extra[0]) + +cet_cs_vec_t cet_cs_vec_cp1252 = /* defined in cet.h */ +{ + cet_cs_name_cp1252, /* name of character set */ + cet_cs_alias_cp1252, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1252, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1252, /* first non standard character */ + cet_ucs4_cnt_cp1252, /* number of values in table */ + + cet_ucs4_to_cp1252_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1252_ct, /* number of links */ + + cet_ucs4_to_cp1252_extra, /* hand made UCS-4 links */ + cet_ucs4_to_cp1252_extra_ct, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1252_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, 0x017d, 0x017e, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, -1, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; +*/ + +#endif diff --git a/cet/cp1253.h b/cet/cp1253.h new file mode 100644 index 000000000..7f4a1b7f9 --- /dev/null +++ b/cet/cp1253.h @@ -0,0 +1,242 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1253" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1253_h +#define cp1253_h + +#define cet_cs_name_cp1253 "CP1253" + +const char *cet_cs_alias_cp1253[] = +{ + "CP1253", "1253", "ms-greek", "windows-1253", "WIN-CP1253", + NULL +}; + +#define cet_ucs4_ofs_cp1253 128 +#define cet_ucs4_cnt_cp1253 127 + +const int cet_ucs4_map_cp1253[cet_ucs4_cnt_cp1253] = +{ + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, 0x0385, 0x0386, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, -1, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x2015, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x00b5, 0x00b6, 0x00b7, + 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + 0x03a0, 0x03a1, -1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce +}; + +#define cet_ucs4_to_cp1253_ct 90 + +const cet_ucs4_link_t cet_ucs4_to_cp1253_links[cet_ucs4_to_cp1253_ct] = +{ + {0x0192, 0x83} /* minuscule latine f hameçon */, + {0x0384, 0xb4} /* grec tonos */, + {0x0385, 0xa1} /* accent and diaeresis (tonos and dialytika) */, + {0x0386, 0xa2} /* capital letter alpha with acute */, + {0x0388, 0xb8} /* capital letter epsilon with acute */, + {0x0389, 0xb9} /* capital letter eta with acute */, + {0x038a, 0xba} /* capital letter iota with acute */, + {0x038c, 0xbc} /* capital letter omicron with acute */, + {0x038e, 0xbe} /* capital letter upsilon with acute */, + {0x038f, 0xbf} /* capital letter omega with acute */, + {0x0390, 0xc0} /* small letter iota with acute and diaeresis */, + {0x0391, 0xc1} /* capital letter alpha */, + {0x0392, 0xc2} /* capital letter beta */, + {0x0393, 0xc3} /* capital letter gamma */, + {0x0394, 0xc4} /* capital letter delta */, + {0x0395, 0xc5} /* capital letter epsilon */, + {0x0396, 0xc6} /* capital letter zeta */, + {0x0397, 0xc7} /* capital letter eta */, + {0x0398, 0xc8} /* capital letter theta */, + {0x0399, 0xc9} /* capital letter iota */, + {0x039a, 0xca} /* capital letter kappa */, + {0x039b, 0xcb} /* capital letter lamda */, + {0x039c, 0xcc} /* capital letter mu */, + {0x039d, 0xcd} /* capital letter nu */, + {0x039e, 0xce} /* capital letter xi */, + {0x039f, 0xcf} /* capital letter omicron */, + {0x03a0, 0xd0} /* capital letter pi */, + {0x03a1, 0xd1} /* capital letter rho */, + {0x03a3, 0xd3} /* capital letter sigma */, + {0x03a4, 0xd4} /* capital letter tau */, + {0x03a5, 0xd5} /* capital letter upsilon */, + {0x03a6, 0xd6} /* capital letter phi */, + {0x03a7, 0xd7} /* capital letter chi */, + {0x03a8, 0xd8} /* capital letter psi */, + {0x03a9, 0xd9} /* capital letter omega */, + {0x03aa, 0xda} /* capital letter iota with diaeresis */, + {0x03ab, 0xdb} /* capital letter upsilon with diaeresis */, + {0x03ac, 0xdc} /* small letter alpha with acute */, + {0x03ad, 0xdd} /* small letter epsilon with acute */, + {0x03ae, 0xde} /* small letter eta with acute */, + {0x03af, 0xdf} /* small letter iota with acute */, + {0x03b0, 0xe0} /* small letter upsilon with acute and diaeresis */, + {0x03b1, 0xe1} /* small letter alpha */, + {0x03b2, 0xe2} /* small letter beta */, + {0x03b3, 0xe3} /* small letter gamma */, + {0x03b4, 0xe4} /* small letter delta */, + {0x03b5, 0xe5} /* small letter epsilon */, + {0x03b6, 0xe6} /* small letter zeta */, + {0x03b7, 0xe7} /* small letter eta */, + {0x03b8, 0xe8} /* small letter theta */, + {0x03b9, 0xe9} /* small letter iota */, + {0x03ba, 0xea} /* small letter kappa */, + {0x03bb, 0xeb} /* small letter lamda */, + {0x03bc, 0xec} /* small letter mu */, + {0x03bd, 0xed} /* small letter nu */, + {0x03be, 0xee} /* small letter xi */, + {0x03bf, 0xef} /* small letter omicron */, + {0x03c0, 0xf0} /* small letter pi */, + {0x03c1, 0xf1} /* small letter rho */, + {0x03c2, 0xf2} /* small letter final sigma */, + {0x03c3, 0xf3} /* small letter sigma */, + {0x03c4, 0xf4} /* small letter tau */, + {0x03c5, 0xf5} /* small letter upsilon */, + {0x03c6, 0xf6} /* small letter phi */, + {0x03c7, 0xf7} /* small letter chi */, + {0x03c8, 0xf8} /* small letter psi */, + {0x03c9, 0xf9} /* small letter omega */, + {0x03ca, 0xfa} /* small letter iota with diaeresis */, + {0x03cb, 0xfb} /* small letter upsilon with diaeresis */, + {0x03cc, 0xfc} /* small letter omicron with acute */, + {0x03cd, 0xfd} /* small letter upsilon with acute */, + {0x03ce, 0xfe} /* small letter omega with acute */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2015, 0xaf} /* bar */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* Extra table was generated from bestfit1253.txt located at + ftp.unicode.org:/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/ */ + +const cet_ucs4_link_t cet_ucs4_to_cp1253_extra[] = +{ + {0x0191, 0x83} /* latin capital letter f with hook */, + {0x030d, 0xb4} /* combining vertical line above */, + {0x2195, 0xa6} /* up down arrow */, + {0x21a8, 0xa6} /* up down arrow with base */, + {0x2302, 0xa6} /* house */, + {0x2502, 0xa6} /* box drawings light vertical */, + {0x2510, 0xac} /* box drawings light down and left */, + {0x2551, 0xa6} /* box drawings double vertical */, + {0x2557, 0xac} /* box drawings double down and left */, + {0x2560, 0xa6} /* box drawings double vertical and right */, + {0x2563, 0xa6} /* box drawings double vertical and left */, + {0x2569, 0xa6} /* box drawings double up and horizontal */, + {0x25a0, 0xa6} /* black square */, + {0x25bc, 0xa1} /* black down-pointing triangle */, + {0x25d8, 0x95} /* inverse bullet */, + {0x2660, 0xa6} /* black spade suit */, + {0x2663, 0xa6} /* black club suit */, + {0x2665, 0xa6} /* black heart suit */, + {0x2666, 0xa6} /* black diamond suit */ +}; + +#define cet_ucs4_to_cp1253_extra_ct sizeof(cet_ucs4_to_cp1253_extra) / sizeof(cet_ucs4_to_cp1253_extra[0]) + +cet_cs_vec_t cet_cs_vec_cp1253 = /* defined in cet.h */ +{ + cet_cs_name_cp1253, /* name of character set */ + cet_cs_alias_cp1253, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1253, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1253, /* first non standard character */ + cet_ucs4_cnt_cp1253, /* number of values in table */ + + cet_ucs4_to_cp1253_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1253_ct, /* number of links */ + + cet_ucs4_to_cp1253_extra, /* hand made UCS-4 links */ + cet_ucs4_to_cp1253_extra_ct, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1253_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, 0x0385, 0x0386, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, -1, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x2015, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x00b5, 0x00b6, 0x00b7, + 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + 0x03a0, 0x03a1, -1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, -1 +}; +*/ + +#endif diff --git a/cet/cp1254.h b/cet/cp1254.h new file mode 100644 index 000000000..085320898 --- /dev/null +++ b/cet/cp1254.h @@ -0,0 +1,228 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1254" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1254_h +#define cp1254_h + +#define cet_cs_name_cp1254 "CP1254" + +const char *cet_cs_alias_cp1254[] = +{ + "CP1254", "1254", "ms-turk", "windows-1254", "WIN-CP1254", + NULL +}; + +#define cet_ucs4_ofs_cp1254 128 +#define cet_ucs4_cnt_cp1254 128 + +const int cet_ucs4_map_cp1254[cet_ucs4_cnt_cp1254] = +{ + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, -1, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff +}; + +#define cet_ucs4_to_cp1254_ct 34 + +const cet_ucs4_link_t cet_ucs4_to_cp1254_links[cet_ucs4_to_cp1254_ct] = +{ + {0x0117, 0xec} /* small letter e with dot above */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x011e, 0xd0} /* capital letter g with breve */, + {0x011f, 0xf0} /* small letter g with breve */, + {0x012b, 0xef} /* small letter i with macron */, + {0x0130, 0xdd} /* capital letter i with dot above */, + {0x0131, 0xfd} /* small letter i dotless */, + {0x0152, 0x8c} /* capital ligature oe */, + {0x0153, 0x9c} /* small ligature oe */, + {0x015e, 0xde} /* capital letter s with cedilla */, + {0x015f, 0xfe} /* small letter s with cedilla */, + {0x0160, 0x8a} /* capital letter s with caron */, + {0x0161, 0x9a} /* small letter s with caron */, + {0x0178, 0x9f} /* capital letter y with diaeresis */, + {0x0192, 0x83} /* minuscule latine f hameçon */, + {0x02c6, 0x88} /* modificative accent circonflexe */, + {0x02dc, 0x98} /* tilde */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* Extra table was generated from bestfit1254.txt located at + ftp.unicode.org:/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/ */ + +const cet_ucs4_link_t cet_ucs4_to_cp1254_extra[] = +{ + {0x0191, 0x83} /* latin capital letter f with hook */, + {0x02bb, 0x91} /* modifier letter turned comma */, + {0x02c9, 0xaf} /* modifier letter macron */, + {0x02ca, 0xb4} /* modifier letter acute accent */, + {0x02da, 0xb0} /* ring above */, + {0x02db, 0xb8} /* ogonek */, + {0x02dd, 0xa8} /* double acute accent */, + {0x0301, 0xb4} /* combining acute accent */, + {0x0303, 0x98} /* combining tilde */, + {0x0304, 0xaf} /* combining macron */, + {0x0305, 0xaf} /* combining overline */, + {0x0306, 0x88} /* combining breve */, + {0x0307, 0xb7} /* combining dot above */, + {0x0308, 0xa8} /* combining diaeresis */, + {0x030a, 0xa7} /* combining ring above */, + {0x030c, 0x88} /* combining caron */, + {0x030e, 0xa8} /* combining double vertical line above */, + {0x0327, 0xb8} /* combining cedilla */, + {0x03b2, 0xdf} /* greek small letter beta */, + {0x03bc, 0xb5} /* greek small letter mu */, + {0x2024, 0x95} /* one dot leader */, + {0x2033, 0xa8} /* double prime */, + {0x2070, 0xb0} /* superscript zero */, + {0x2080, 0xb0} /* subscript zero */, + {0x2082, 0xb2} /* subscript two */, + {0x2083, 0xb3} /* subscript three */, + {0x20a4, 0xa3} /* lira sign */, + {0x212b, 0xc5} /* angstrom sign */, + {0x2190, 0x8b} /* leftwards arrow */, + {0x2192, 0x9b} /* rightwards arrow */, + {0x2205, 0xd8} /* empty set */, + {0x2213, 0xb1} /* minus-or-plus sign */, + {0x2218, 0xb0} /* ring operator */, + {0x2219, 0x95} /* bullet operator */, + {0x226a, 0xab} /* much less-than */, + {0x226b, 0xbb} /* much greater-than */, + {0x22c5, 0xb7} /* dot operator */, + {0x2302, 0xa6} /* house */, + {0x2500, 0xa6} /* box drawings light horizontal */, + {0x2510, 0xac} /* box drawings light down and left */, + {0x2551, 0xa6} /* box drawings double vertical */, + {0x2557, 0xac} /* box drawings double down and left */, + {0x2560, 0xa6} /* box drawings double vertical and right */, + {0x2563, 0xa6} /* box drawings double vertical and left */, + {0x2569, 0xa6} /* box drawings double up and horizontal */, + {0x25a0, 0xa6} /* black square */, + {0x25bc, 0xa1} /* black down-pointing triangle */, + {0x25d8, 0x95} /* inverse bullet */, + {0x2660, 0xa6} /* black spade suit */, + {0x2663, 0xa6} /* black club suit */, + {0x2665, 0xa6} /* black heart suit */, + {0x2666, 0xa6} /* black diamond suit */, + {0x275b, 0x91} /* heavy single turned comma quotation mark ornament */, + {0x275c, 0x92} /* heavy single comma quotation mark ornament */, + {0x275d, 0x93} /* heavy double turned comma quotation mark ornament */, + {0x275e, 0x94} /* heavy double comma quotation mark ornament */, + {0x300a, 0xab} /* left double angle bracket */, + {0x300b, 0xbb} /* right double angle bracket */, + {0x301f, 0x84} /* low double prime quotation mark */, + {0x30fb, 0xb7} /* katakana middle dot */, + {0x30fc, 0x97} /* katakana-hiragana prolonged sound mark */ +}; + +#define cet_ucs4_to_cp1254_extra_ct sizeof(cet_ucs4_to_cp1254_extra) / sizeof(cet_ucs4_to_cp1254_extra[0]) + +cet_cs_vec_t cet_cs_vec_cp1254 = /* defined in cet.h */ +{ + cet_cs_name_cp1254, /* name of character set */ + cet_cs_alias_cp1254, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1254, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1254, /* first non standard character */ + cet_ucs4_cnt_cp1254, /* number of values in table */ + + cet_ucs4_to_cp1254_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1254_ct, /* number of links */ + + cet_ucs4_to_cp1254_extra, /* hand made UCS-4 links */ + cet_ucs4_to_cp1254_extra_ct, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1254_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, -1, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff +}; +*/ + +#endif diff --git a/cet/cp1255.h b/cet/cp1255.h new file mode 100644 index 000000000..c078cefa3 --- /dev/null +++ b/cet/cp1255.h @@ -0,0 +1,212 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1255" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1255_h +#define cp1255_h + +#define cet_cs_name_cp1255 "CP1255" + +const char *cet_cs_alias_cp1255[] = +{ + "CP1255", "1255", "ms-hebr", "windows-1255", "WIN-CP1255", + NULL +}; + +#define cet_ucs4_ofs_cp1255 128 +#define cet_ucs4_cnt_cp1255 127 + +const int cet_ucs4_map_cp1255[cet_ucs4_cnt_cp1255] = +{ + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, -1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x203e, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 0x2017, + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, -1, -1, 0x200e, 0x200f +}; + +#define cet_ucs4_to_cp1255_ct 51 + +const cet_ucs4_link_t cet_ucs4_to_cp1255_links[cet_ucs4_to_cp1255_ct] = +{ + {0x00d7, 0xaa} /* sign */, + {0x00f7, 0xba} /* sign */, + {0x0192, 0x83} /* minuscule latine f hameçon */, + {0x05d0, 0xe0} /* letter alef */, + {0x05d1, 0xe1} /* letter bet */, + {0x05d2, 0xe2} /* letter gimel */, + {0x05d3, 0xe3} /* letter dalet */, + {0x05d4, 0xe4} /* letter he */, + {0x05d5, 0xe5} /* letter vav */, + {0x05d6, 0xe6} /* letter zayin */, + {0x05d7, 0xe7} /* letter het */, + {0x05d8, 0xe8} /* letter tet */, + {0x05d9, 0xe9} /* letter yod */, + {0x05da, 0xea} /* letter final kaf */, + {0x05db, 0xeb} /* letter kaf */, + {0x05dc, 0xec} /* letter lamed */, + {0x05dd, 0xed} /* letter final mem */, + {0x05de, 0xee} /* letter mem */, + {0x05df, 0xef} /* letter final nun */, + {0x05e0, 0xf0} /* letter nun */, + {0x05e1, 0xf1} /* letter samekh */, + {0x05e2, 0xf2} /* letter ayin */, + {0x05e3, 0xf3} /* letter final pe */, + {0x05e4, 0xf4} /* letter pe */, + {0x05e5, 0xf5} /* letter final tsadi */, + {0x05e6, 0xf6} /* letter tsadi */, + {0x05e7, 0xf7} /* letter qof */, + {0x05e8, 0xf8} /* letter resh */, + {0x05e9, 0xf9} /* letter shin */, + {0x05ea, 0xfa} /* letter tav */, + {0x200e, 0xfd} /* gauche-à-droite */, + {0x200f, 0xfe} /* droite-à-gauche */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2017, 0xdf} /* low line */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x203e, 0xaf} /* overline */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* Extra table was generated from bestfit1255.txt located at + ftp.unicode.org:/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/ */ + +const cet_ucs4_link_t cet_ucs4_to_cp1255_extra[] = +{ + {0x02c6, 0x88} /* modifier letter circumflex */, + {0x02dc, 0x98} /* spacing tilde */, + {0x05b0, 0xc0} /* hebrew point sheva */, + {0x05b1, 0xc1} /* hebrew point hataf segol */, + {0x05b2, 0xc2} /* hebrew point hataf patah */, + {0x05b3, 0xc3} /* hebrew point hataf qamats */, + {0x05b4, 0xc4} /* hebrew point hiriq */, + {0x05b5, 0xc5} /* hebrew point tsere */, + {0x05b6, 0xc6} /* hebrew point segol */, + {0x05b7, 0xc7} /* hebrew point patah */, + {0x05b8, 0xc8} /* hebrew point qamats */, + {0x05b9, 0xc9} /* hebrew point holam */, + {0x05ba, 0xca} /* hebrew point ???? */, + {0x05bb, 0xcb} /* hebrew point qubuts */, + {0x05bc, 0xcc} /* hebrew point dagesh */, + {0x05bd, 0xcd} /* hebrew point meteg */, + {0x05be, 0xce} /* hebrew punctuation maqaf */, + {0x05bf, 0xcf} /* hebrew point rafe */, + {0x05c0, 0xd0} /* hebrew point paseq */, + {0x05c1, 0xd1} /* hebrew point shin dot */, + {0x05c2, 0xd2} /* hebrew point sin dot */, + {0x05c3, 0xd3} /* hebrew punctuation sof pasuq */, + {0x05f0, 0xd4} /* hebrew ligature yiddish double vav */, + {0x05f1, 0xd5} /* hebrew ligature yiddish vav yod */, + {0x05f2, 0xd6} /* hebrew ligature yiddish double yod */, + {0x05f3, 0xd7} /* hebrew punctuation geresh */, + {0x05f4, 0xd8} /* hebrew punctuation gershayim */, + {0x20aa, 0xa4} /* new sheqel sign */ +}; + +#define cet_ucs4_to_cp1255_extra_ct sizeof(cet_ucs4_to_cp1255_extra) / sizeof(cet_ucs4_to_cp1255_extra[0]) + +cet_cs_vec_t cet_cs_vec_cp1255 = /* defined in cet.h */ +{ + cet_cs_name_cp1255, /* name of character set */ + cet_cs_alias_cp1255, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1255, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1255, /* first non standard character */ + cet_ucs4_cnt_cp1255, /* number of values in table */ + + cet_ucs4_to_cp1255_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1255_ct, /* number of links */ + + cet_ucs4_to_cp1255_extra, /* hand made UCS-4 links */ + cet_ucs4_to_cp1255_extra_ct, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1255_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, -1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x203e, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 0x2017, + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, -1, -1, 0x200e, 0x200f, -1 +}; +*/ + +#endif diff --git a/cet/cp1256.h b/cet/cp1256.h new file mode 100644 index 000000000..89bc69652 --- /dev/null +++ b/cet/cp1256.h @@ -0,0 +1,232 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1256" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1256_h +#define cp1256_h + +#define cet_cs_name_cp1256 "CP1256" + +const char *cet_cs_alias_cp1256[] = +{ + "CP1256", "1256", "ms-arab", "windows-1256", "WIN-CP1256", + NULL +}; + +#define cet_ucs4_ofs_cp1256 128 +#define cet_ucs4_cnt_cp1256 128 + +const int cet_ucs4_map_cp1256[cet_ucs4_cnt_cp1256] = +{ + 0x20ac, 0x0660, 0x201a, 0x0661, 0x201e, 0x2026, 0x2020, 0x2021, + 0x0662, 0x0663, 0x0664, 0x2039, 0x0665, 0x0666, 0x0667, 0x0668, + 0x0669, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x061b, 0x2122, 0x061f, 0x203a, 0x0621, 0x0622, 0x0623, 0x0178, + 0x00a0, 0x0624, 0x0625, 0x00a3, 0x00a4, 0x0626, 0x00a6, 0x00a7, + 0x0627, 0x00a9, 0x0628, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x067e, + 0x00b0, 0x00b1, 0x0629, 0x062a, 0x062b, 0x00b5, 0x00b6, 0x00b7, + 0x062c, 0x0686, 0x062d, 0x00bb, 0x062e, 0x062f, 0x0630, 0x0631, + 0x00c0, 0x0632, 0x00c2, 0x0698, 0x0633, 0x0634, 0x0635, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0636, 0x0637, 0x00ce, 0x00cf, + 0x3113, 0x0639, 0x063a, 0x0640, 0x00d4, 0x0641, 0x0642, 0x00d7, + 0x0643, 0x00d9, 0x06af, 0x00db, 0x00dc, 0x0644, 0x0645, 0x0646, + 0x00e0, 0x0647, 0x00e2, 0x0681, 0x0648, 0x0649, 0x064a, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x064b, 0x064c, 0x00ee, 0x00ef, + 0x064d, 0x064e, 0x064f, 0x0650, 0x00f4, 0x0651, 0x0652, 0x00f7, + -1, 0x00f9, -1, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x00ff +}; + +#define cet_ucs4_to_cp1256_ct 81 + +const cet_ucs4_link_t cet_ucs4_to_cp1256_links[cet_ucs4_to_cp1256_ct] = +{ + {0x0178, 0x9f} /* capital letter y with diaeresis */, + {0x061b, 0x98} /* semicolon */, + {0x061f, 0x9a} /* question mark */, + {0x0621, 0x9c} /* letter hamza */, + {0x0622, 0x9d} /* letter alef with madda above */, + {0x0623, 0x9e} /* letter alef with hamza above */, + {0x0624, 0xa1} /* letter waw with hamza above */, + {0x0625, 0xa2} /* letter alef with hamza below */, + {0x0626, 0xa5} /* letter yeh with hamza above */, + {0x0627, 0xa8} /* letter alef */, + {0x0628, 0xaa} /* letter beh */, + {0x0629, 0xb2} /* letter teh marbuta */, + {0x062a, 0xb3} /* letter teh */, + {0x062b, 0xb4} /* letter theh */, + {0x062c, 0xb8} /* letter jeem */, + {0x062d, 0xba} /* letter hah */, + {0x062e, 0xbc} /* letter khah */, + {0x062f, 0xbd} /* letter dal */, + {0x0630, 0xbe} /* letter thal */, + {0x0631, 0xbf} /* letter reh */, + {0x0632, 0xc1} /* letter zain */, + {0x0633, 0xc4} /* letter seen */, + {0x0634, 0xc5} /* letter sheen */, + {0x0635, 0xc6} /* letter sad */, + {0x0636, 0xcc} /* letter dad */, + {0x0637, 0xcd} /* letter tah */, + {0x0639, 0xd1} /* letter ain */, + {0x063a, 0xd2} /* letter ghain */, + {0x0640, 0xd3} /* tatweel */, + {0x0641, 0xd5} /* letter feh */, + {0x0642, 0xd6} /* letter qaf */, + {0x0643, 0xd8} /* letter kaf */, + {0x0644, 0xdd} /* letter lam */, + {0x0645, 0xde} /* letter meem */, + {0x0646, 0xdf} /* letter noon */, + {0x0647, 0xe1} /* letter heh */, + {0x0648, 0xe4} /* letter waw */, + {0x0649, 0xe5} /* letter alef maksura */, + {0x064a, 0xe6} /* letter yeh */, + {0x064b, 0xec} /* fathatan */, + {0x064c, 0xed} /* dammatan */, + {0x064d, 0xf0} /* kasratan */, + {0x064e, 0xf1} /* fatha */, + {0x064f, 0xf2} /* damma */, + {0x0650, 0xf3} /* kasra */, + {0x0651, 0xf5} /* shadda */, + {0x0652, 0xf6} /* sukun */, + {0x0660, 0x81} /* arabic-indic digit zero */, + {0x0661, 0x83} /* arabic-indic digit one */, + {0x0662, 0x88} /* arabic-indic digit two */, + {0x0663, 0x89} /* arabic-indic digit three */, + {0x0664, 0x8a} /* arabic-indic digit four */, + {0x0665, 0x8c} /* arabic-indic digit five */, + {0x0666, 0x8d} /* arabic-indic digit six */, + {0x0667, 0x8e} /* arabic-indic digit seven */, + {0x0668, 0x8f} /* arabic-indic digit eight */, + {0x0669, 0x90} /* arabic-indic digit nine */, + {0x067e, 0xaf} /* letter peh */, + {0x0681, 0xe3} /* arabe ha' hamza en chef */, + {0x0686, 0xb9} /* arabe tchim' */, + {0x0698, 0xc3} /* arabe ja' */, + {0x06af, 0xda} /* letter gaf */, + {0x200e, 0xfd} /* gauche-à-droite */, + {0x200f, 0xfe} /* droite-à-gauche */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */, + {0x3113, 0xd0} /* letter zh */ +}; + +/* Extra table was generated from bestfit1256.txt located at + ftp.unicode.org:/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/ */ + +const cet_ucs4_link_t cet_ucs4_to_cp1256_extra[] = +{ + {0x0152, 0x8c} /* latin capital letter o e */, + {0x0153, 0x9c} /* latin small letter o e */, + {0x0192, 0x83} /* latin small letter script f */, + {0x02c6, 0x88} /* modifier letter circumflex */, + {0x060c, 0xa1} /* arabic comma */, + {0x0638, 0xd9} /* arabic letter dhah */, + {0x0679, 0x8a} /* arabic letter tteh */, + {0x0688, 0x8f} /* arabic letter ddal */, + {0x0691, 0x9a} /* arabic letter rreh */, + {0x06a9, 0x98} /* arabic letter keheh */, + {0x06ba, 0x9f} /* arabic letter noon ghunna */, + {0x06be, 0xaa} /* arabic letter heh doachashmee */, + {0x06c1, 0xc0} /* arabic letter heh goal */, + {0x06cc, 0xed} /* best-fit : farsi yeh -> arabic yeh (u+064a) */, + {0x06d2, 0xff} /* arabic letter yeh barree */, + {0x200c, 0x9d} /* zero width non-joiner */, + {0x200d, 0x9e} /* zero width joiner */, + {0x2030, 0x89} /* per mille sign */ +}; + +#define cet_ucs4_to_cp1256_extra_ct sizeof(cet_ucs4_to_cp1256_extra) / sizeof(cet_ucs4_to_cp1256_extra[0]) + +cet_cs_vec_t cet_cs_vec_cp1256 = /* defined in cet.h */ +{ + cet_cs_name_cp1256, /* name of character set */ + cet_cs_alias_cp1256, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1256, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1256, /* first non standard character */ + cet_ucs4_cnt_cp1256, /* number of values in table */ + + cet_ucs4_to_cp1256_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1256_ct, /* number of links */ + + cet_ucs4_to_cp1256_extra, /* hand made UCS-4 links */ + cet_ucs4_to_cp1256_extra_ct, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1256_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, 0x0660, 0x201a, 0x0661, 0x201e, 0x2026, 0x2020, 0x2021, + 0x0662, 0x0663, 0x0664, 0x2039, 0x0665, 0x0666, 0x0667, 0x0668, + 0x0669, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x061b, 0x2122, 0x061f, 0x203a, 0x0621, 0x0622, 0x0623, 0x0178, + 0x00a0, 0x0624, 0x0625, 0x00a3, 0x00a4, 0x0626, 0x00a6, 0x00a7, + 0x0627, 0x00a9, 0x0628, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x067e, + 0x00b0, 0x00b1, 0x0629, 0x062a, 0x062b, 0x00b5, 0x00b6, 0x00b7, + 0x062c, 0x0686, 0x062d, 0x00bb, 0x062e, 0x062f, 0x0630, 0x0631, + 0x00c0, 0x0632, 0x00c2, 0x0698, 0x0633, 0x0634, 0x0635, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0636, 0x0637, 0x00ce, 0x00cf, + 0x3113, 0x0639, 0x063a, 0x0640, 0x00d4, 0x0641, 0x0642, 0x00d7, + 0x0643, 0x00d9, 0x06af, 0x00db, 0x00dc, 0x0644, 0x0645, 0x0646, + 0x00e0, 0x0647, 0x00e2, 0x0681, 0x0648, 0x0649, 0x064a, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x064b, 0x064c, 0x00ee, 0x00ef, + 0x064d, 0x064e, 0x064f, 0x0650, 0x00f4, 0x0651, 0x0652, 0x00f7, + -1, 0x00f9, -1, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x00ff +}; +*/ + +#endif diff --git a/cet/cp1257.h b/cet/cp1257.h new file mode 100644 index 000000000..a629396cc --- /dev/null +++ b/cet/cp1257.h @@ -0,0 +1,205 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1257" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1257_h +#define cp1257_h + +#define cet_cs_name_cp1257 "CP1257" + +const char *cet_cs_alias_cp1257[] = +{ + "CP1257", "1257", "WinBaltRim", "windows-1257", "WIN-CP1257", + NULL +}; + +#define cet_ucs4_ofs_cp1257 128 +#define cet_ucs4_cnt_cp1257 127 + +const int cet_ucs4_map_cp1257[cet_ucs4_cnt_cp1257] = +{ + 0x20ac, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, -1, 0x00a2, 0x00a3, 0x00a4, -1, 0x00a6, 0x00a7, + 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, -1, 0x00b5, 0x00b6, 0x00b7, + 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, + 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, + 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, + 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, + 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, + 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, + 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e +}; + +#define cet_ucs4_to_cp1257_ct 69 + +const cet_ucs4_link_t cet_ucs4_to_cp1257_links[cet_ucs4_to_cp1257_ct] = +{ + {0x00c6, 0xaf} /* capital letter ae */, + {0x00d8, 0xa8} /* capital letter o with stroke */, + {0x00e6, 0xbf} /* small letter ae */, + {0x00f8, 0xb8} /* small letter o with stroke */, + {0x0100, 0xc2} /* capital letter a with macron */, + {0x0101, 0xe2} /* small letter a with macron */, + {0x0104, 0xc0} /* capital letter a with ogonek */, + {0x0105, 0xe0} /* small letter a with ogonek */, + {0x0106, 0xc3} /* capital letter c with acute */, + {0x0107, 0xe3} /* small letter c with acute */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x0112, 0xc7} /* capital letter e with macron */, + {0x0113, 0xe7} /* small letter e with macron */, + {0x0116, 0xcb} /* capital letter e with dot above */, + {0x0117, 0xeb} /* small letter e with dot above */, + {0x0118, 0xc6} /* capital letter e with ogonek */, + {0x0119, 0xe6} /* small letter e with ogonek */, + {0x0122, 0xcc} /* capital letter g with cedilla */, + {0x0123, 0xec} /* small letter g with cedilla */, + {0x012a, 0xce} /* capital letter i with macron */, + {0x012b, 0xee} /* small letter i with macron */, + {0x012e, 0xc1} /* capital letter i with ogonek */, + {0x012f, 0xe1} /* small letter i with ogonek */, + {0x0136, 0xcd} /* capital letter k with cedilla */, + {0x0137, 0xed} /* small letter k with cedilla */, + {0x013b, 0xcf} /* capital letter l with cedilla */, + {0x013c, 0xef} /* small letter l with cedilla */, + {0x0141, 0xd9} /* capital letter l with stroke */, + {0x0142, 0xf9} /* small letter l with stroke */, + {0x0143, 0xd1} /* capital letter n with acute */, + {0x0144, 0xf1} /* small letter n with acute */, + {0x0145, 0xd2} /* capital letter n with cedilla */, + {0x0146, 0xf2} /* small letter n with cedilla */, + {0x014c, 0xd4} /* capital letter o with macron */, + {0x014d, 0xf4} /* small letter o with macron */, + {0x0156, 0xaa} /* capital letter r with cedilla */, + {0x0157, 0xba} /* small letter r with cedilla */, + {0x015a, 0xda} /* capital letter s with acute */, + {0x015b, 0xfa} /* small letter s with acute */, + {0x0160, 0xd0} /* capital letter s with caron */, + {0x0161, 0xf0} /* small letter s with caron */, + {0x016a, 0xdb} /* capital letter u with macron */, + {0x016b, 0xfb} /* small letter u with macron */, + {0x0172, 0xd8} /* capital letter u with ogonek */, + {0x0173, 0xf8} /* small letter u with ogonek */, + {0x0179, 0xca} /* capital letter z with acute */, + {0x017a, 0xea} /* small letter z with acute */, + {0x017b, 0xdd} /* capital letter z with dot above */, + {0x017c, 0xfd} /* small letter z with dot above */, + {0x017d, 0xde} /* capital letter z with caron */, + {0x017e, 0xfe} /* small letter z with caron */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* Extra table was generated from bestfit1257.txt located at + ftp.unicode.org:/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/ */ + +const cet_ucs4_link_t cet_ucs4_to_cp1257_extra[] = +{ + {0x02c7, 0x8e} /* hacek */, + {0x02d9, 0xff} /* dot above */, + {0x02db, 0x9e} /* ogonek */, +}; + +#define cet_ucs4_to_cp1257_extra_ct sizeof(cet_ucs4_to_cp1257_extra) / sizeof(cet_ucs4_to_cp1257_extra[0]) + +cet_cs_vec_t cet_cs_vec_cp1257 = /* defined in cet.h */ +{ + cet_cs_name_cp1257, /* name of character set */ + cet_cs_alias_cp1257, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1257, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1257, /* first non standard character */ + cet_ucs4_cnt_cp1257, /* number of values in table */ + + cet_ucs4_to_cp1257_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1257_ct, /* number of links */ + + cet_ucs4_to_cp1257_extra, /* hand made UCS-4 links */ + cet_ucs4_to_cp1257_extra_ct, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1257_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, -1, 0x00a2, 0x00a3, 0x00a4, -1, 0x00a6, 0x00a7, + 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, -1, 0x00b5, 0x00b6, 0x00b7, + 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, + 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, + 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, + 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, + 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, + 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, + 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, -1 +}; +*/ + +#endif diff --git a/cet/csa_z243_4_1985_1.h b/cet/csa_z243_4_1985_1.h new file mode 100644 index 000000000..9c24e5cea --- /dev/null +++ b/cet/csa_z243_4_1985_1.h @@ -0,0 +1,131 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CSA_Z243.4-1985-1" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef csa_z243_4_1985_1_h +#define csa_z243_4_1985_1_h + +#define cet_cs_name_csa_z243_4_1985_1 "CSA_Z243.4-1985-1" + +const char *cet_cs_alias_csa_z243_4_1985_1[] = +{ + "CSA_Z243.4-1985-1", "ca", "csa7-1", "ISO646-CA", + "iso-ir-121", NULL +}; + +#define cet_ucs4_ofs_csa_z243_4_1985_1 64 +#define cet_ucs4_cnt_csa_z243_4_1985_1 64 + +const int cet_ucs4_map_csa_z243_4_1985_1[cet_ucs4_cnt_csa_z243_4_1985_1] = +{ + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00e2, 0x00e7, 0x00ea, 0x00ee, 0x005f, + 0x00f4, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00fb, 0x007f +}; + +#define cet_ucs4_to_csa_z243_4_1985_1_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_1_links[cet_ucs4_to_csa_z243_4_1985_1_ct] = +{ + {0x00e0, 0x40} /* small letter a with grave */, + {0x00e2, 0x5b} /* small letter a with circumflex */, + {0x00e7, 0x5c} /* small letter c with cedilla */, + {0x00e8, 0x7d} /* small letter e with grave */, + {0x00e9, 0x7b} /* small letter e with acute */, + {0x00ea, 0x5d} /* small letter e with circumflex */, + {0x00ee, 0x5e} /* small letter i with circumflex */, + {0x00f4, 0x60} /* small letter o with circumflex */, + {0x00f9, 0x7c} /* small letter u with grave */, + {0x00fb, 0x7e} /* small letter u with circumflex */ +}; + +/* +#define cet_ucs4_to_csa_z243_4_1985_1_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_1_extra[cet_ucs4_to_csa_z243_4_1985_1_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_csa_z243_4_1985_1 = /* defined in cet.h */ +{ + cet_cs_name_csa_z243_4_1985_1, /* name of character set */ + cet_cs_alias_csa_z243_4_1985_1, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_csa_z243_4_1985_1, /* char to UCS-4 value table */ + cet_ucs4_ofs_csa_z243_4_1985_1, /* first non standard character */ + cet_ucs4_cnt_csa_z243_4_1985_1, /* number of values in table */ + + cet_ucs4_to_csa_z243_4_1985_1_links, /* UCS-4 to char links */ + cet_ucs4_to_csa_z243_4_1985_1_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int csa_z243_4_1985_1_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00e2, 0x00e7, 0x00ea, 0x00ee, 0x005f, + 0x00f4, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00fb, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/csa_z243_4_1985_2.h b/cet/csa_z243_4_1985_2.h new file mode 100644 index 000000000..0d5e54bea --- /dev/null +++ b/cet/csa_z243_4_1985_2.h @@ -0,0 +1,131 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CSA_Z243.4-1985-2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef csa_z243_4_1985_2_h +#define csa_z243_4_1985_2_h + +#define cet_cs_name_csa_z243_4_1985_2 "CSA_Z243.4-1985-2" + +const char *cet_cs_alias_csa_z243_4_1985_2[] = +{ + "CSA_Z243.4-1985-2", "csa7-2", "ISO646-CA2", "iso-ir-122", + NULL +}; + +#define cet_ucs4_ofs_csa_z243_4_1985_2 64 +#define cet_ucs4_cnt_csa_z243_4_1985_2 64 + +const int cet_ucs4_map_csa_z243_4_1985_2[cet_ucs4_cnt_csa_z243_4_1985_2] = +{ + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00e2, 0x00e7, 0x00ea, 0x00c9, 0x005f, + 0x00f4, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00fb, 0x007f +}; + +#define cet_ucs4_to_csa_z243_4_1985_2_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_2_links[cet_ucs4_to_csa_z243_4_1985_2_ct] = +{ + {0x00c9, 0x5e} /* capital letter e with acute */, + {0x00e0, 0x40} /* small letter a with grave */, + {0x00e2, 0x5b} /* small letter a with circumflex */, + {0x00e7, 0x5c} /* small letter c with cedilla */, + {0x00e8, 0x7d} /* small letter e with grave */, + {0x00e9, 0x7b} /* small letter e with acute */, + {0x00ea, 0x5d} /* small letter e with circumflex */, + {0x00f4, 0x60} /* small letter o with circumflex */, + {0x00f9, 0x7c} /* small letter u with grave */, + {0x00fb, 0x7e} /* small letter u with circumflex */ +}; + +/* +#define cet_ucs4_to_csa_z243_4_1985_2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_2_extra[cet_ucs4_to_csa_z243_4_1985_2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_csa_z243_4_1985_2 = /* defined in cet.h */ +{ + cet_cs_name_csa_z243_4_1985_2, /* name of character set */ + cet_cs_alias_csa_z243_4_1985_2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_csa_z243_4_1985_2, /* char to UCS-4 value table */ + cet_ucs4_ofs_csa_z243_4_1985_2, /* first non standard character */ + cet_ucs4_cnt_csa_z243_4_1985_2, /* number of values in table */ + + cet_ucs4_to_csa_z243_4_1985_2_links, /* UCS-4 to char links */ + cet_ucs4_to_csa_z243_4_1985_2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int csa_z243_4_1985_2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00e2, 0x00e7, 0x00ea, 0x00c9, 0x005f, + 0x00f4, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00fb, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/csa_z243_4_1985_gr.h b/cet/csa_z243_4_1985_gr.h new file mode 100644 index 000000000..32bd6053f --- /dev/null +++ b/cet/csa_z243_4_1985_gr.h @@ -0,0 +1,206 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CSA_Z243.4-1985-gr" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef csa_z243_4_1985_gr_h +#define csa_z243_4_1985_gr_h + +#define cet_cs_name_csa_z243_4_1985_gr "CSA_Z243.4-1985-gr" + +const char *cet_cs_alias_csa_z243_4_1985_gr[] = +{ + "CSA_Z243.4-1985-gr", "iso-ir-123", NULL +}; + +#define cet_ucs4_ofs_csa_z243_4_1985_gr 162 +#define cet_ucs4_cnt_csa_z243_4_1985_gr 94 + +const int cet_ucs4_map_csa_z243_4_1985_gr[cet_ucs4_cnt_csa_z243_4_1985_gr] = +{ + 0x00a8, 0x00a3, 0x00a2, 0x00a5, 0x00b1, 0x00b4, 0x207d, 0x207e, + 0x00bd, 0x207a, 0x00b8, 0x00ad, 0x00b7, 0x207b, 0x2070, 0x00b9, + 0x00b2, 0x00b3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079, + 0x00bc, 0x00be, 0x21d0, 0x2260, 0x2265, 0x00bf, 0x00c0, 0x00c1, + 0x00c2, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cd, 0x00ce, + 0x00cf, 0x00d1, 0x00d3, 0x00d4, 0x00d9, 0x00da, 0x00db, 0x00dc, + 0x00ae, 0x00a7, 0x00b6, 0x00b5, 0x00aa, 0x00ba, 0x2018, 0x2019, + 0x201c, 0x201d, 0x00ab, 0x00bb, 0x00b0, 0x00a6, 0x00e0, 0x00e1, + 0x00e2, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ed, 0x00ee, + 0x00ef, 0x00f1, 0x00f3, 0x00f4, 0x00f9, 0x00fa, 0x00fb, 0x00fc, + 0x00a9, 0x2500, 0x2502, 0x2514, 0x2518, 0x2510, 0x250c, 0x251c, + 0x2534, 0x2524, 0x252c, 0x253c, 0x00ac, 0x2588 +}; + +#define cet_ucs4_to_csa_z243_4_1985_gr_ct 82 + +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_gr_links[cet_ucs4_to_csa_z243_4_1985_gr_ct] = +{ + {0x00a2, 0xa4} /* sign */, + {0x00a6, 0xdf} /* bar */, + {0x00a7, 0xd3} /* sign */, + {0x00a8, 0xa2} /* diaeresis */, + {0x00a9, 0xf2} /* sign */, + {0x00aa, 0xd6} /* ordinal indicator */, + {0x00ab, 0xdc} /* double angle quotation mark */, + {0x00ac, 0xfe} /* sign */, + {0x00ae, 0xd2} /* sign */, + {0x00b0, 0xde} /* sign */, + {0x00b1, 0xa6} /* sign */, + {0x00b4, 0xa7} /* accent */, + {0x00b5, 0xd5} /* sign */, + {0x00b6, 0xd4} /* sign */, + {0x00b7, 0xae} /* dot */, + {0x00b8, 0xac} /* cedilla */, + {0x00b9, 0xb1} /* one */, + {0x00ba, 0xd7} /* ordinal indicator */, + {0x00bb, 0xdd} /* double angle quotation mark */, + {0x00bc, 0xba} /* fraction one quarter */, + {0x00bd, 0xaa} /* fraction one half */, + {0x00be, 0xbb} /* fraction three quarters */, + {0x00c7, 0xc3} /* capital letter c with cedilla */, + {0x00c8, 0xc4} /* capital letter e with grave */, + {0x00c9, 0xc5} /* capital letter e with acute */, + {0x00ca, 0xc6} /* capital letter e with circumflex */, + {0x00cb, 0xc7} /* capital letter e with diaeresis */, + {0x00cd, 0xc8} /* capital letter i with acute */, + {0x00ce, 0xc9} /* capital letter i with circumflex */, + {0x00cf, 0xca} /* capital letter i with diaeresis */, + {0x00d1, 0xcb} /* capital letter n with tilde */, + {0x00d3, 0xcc} /* capital letter o with acute */, + {0x00d4, 0xcd} /* capital letter o with circumflex */, + {0x00d9, 0xce} /* capital letter u with grave */, + {0x00da, 0xcf} /* capital letter u with acute */, + {0x00db, 0xd0} /* capital letter u with circumflex */, + {0x00dc, 0xd1} /* capital letter u with diaeresis */, + {0x00e7, 0xe3} /* small letter c with cedilla */, + {0x00e8, 0xe4} /* small letter e with grave */, + {0x00e9, 0xe5} /* small letter e with acute */, + {0x00ea, 0xe6} /* small letter e with circumflex */, + {0x00eb, 0xe7} /* small letter e with diaeresis */, + {0x00ed, 0xe8} /* small letter i with acute */, + {0x00ee, 0xe9} /* small letter i with circumflex */, + {0x00ef, 0xea} /* small letter i with diaeresis */, + {0x00f1, 0xeb} /* small letter n with tilde */, + {0x00f3, 0xec} /* small letter o with acute */, + {0x00f4, 0xed} /* small letter o with circumflex */, + {0x00f9, 0xee} /* small letter u with grave */, + {0x00fa, 0xef} /* small letter u with acute */, + {0x00fb, 0xf0} /* small letter u with circumflex */, + {0x00fc, 0xf1} /* small letter u with diaeresis */, + {0x2018, 0xd8} /* single quotation mark */, + {0x2019, 0xd9} /* single quotation mark */, + {0x201c, 0xda} /* double quotation mark */, + {0x201d, 0xdb} /* double quotation mark */, + {0x2070, 0xb0} /* digit zero */, + {0x2074, 0xb4} /* digit four */, + {0x2075, 0xb5} /* digit five */, + {0x2076, 0xb6} /* digit six */, + {0x2077, 0xb7} /* digit seven */, + {0x2078, 0xb8} /* digit eight */, + {0x2079, 0xb9} /* digit nine */, + {0x207a, 0xab} /* plus sign */, + {0x207b, 0xaf} /* minus */, + {0x207d, 0xa8} /* left parenthesis */, + {0x207e, 0xa9} /* right parenthesis */, + {0x21d0, 0xbc} /* double arrow */, + {0x2260, 0xbd} /* equal to */, + {0x2265, 0xbe} /* or equal to */, + {0x2500, 0xf3} /* drawings light horizontal */, + {0x2502, 0xf4} /* drawings light vertical */, + {0x250c, 0xf8} /* drawings light down and right */, + {0x2510, 0xf7} /* drawings light down and left */, + {0x2514, 0xf5} /* drawings light up and right */, + {0x2518, 0xf6} /* drawings light up and left */, + {0x251c, 0xf9} /* drawings light vertical and right */, + {0x2524, 0xfb} /* drawings light vertical and left */, + {0x252c, 0xfc} /* drawings light down and horizontal */, + {0x2534, 0xfa} /* drawings light up and horizontal */, + {0x253c, 0xfd} /* drawings light vertical and horizontal */, + {0x2588, 0xff} /* block */ +}; + +/* +#define cet_ucs4_to_csa_z243_4_1985_gr_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_gr_extra[cet_ucs4_to_csa_z243_4_1985_gr_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_csa_z243_4_1985_gr = /* defined in cet.h */ +{ + cet_cs_name_csa_z243_4_1985_gr, /* name of character set */ + cet_cs_alias_csa_z243_4_1985_gr, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_csa_z243_4_1985_gr, /* char to UCS-4 value table */ + cet_ucs4_ofs_csa_z243_4_1985_gr, /* first non standard character */ + cet_ucs4_cnt_csa_z243_4_1985_gr, /* number of values in table */ + + cet_ucs4_to_csa_z243_4_1985_gr_links, /* UCS-4 to char links */ + cet_ucs4_to_csa_z243_4_1985_gr_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int csa_z243_4_1985_gr_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a8, 0x00a3, 0x00a2, 0x00a5, 0x00b1, 0x00b4, + 0x207d, 0x207e, 0x00bd, 0x207a, 0x00b8, 0x00ad, 0x00b7, 0x207b, + 0x2070, 0x00b9, 0x00b2, 0x00b3, 0x2074, 0x2075, 0x2076, 0x2077, + 0x2078, 0x2079, 0x00bc, 0x00be, 0x21d0, 0x2260, 0x2265, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, + 0x00cd, 0x00ce, 0x00cf, 0x00d1, 0x00d3, 0x00d4, 0x00d9, 0x00da, + 0x00db, 0x00dc, 0x00ae, 0x00a7, 0x00b6, 0x00b5, 0x00aa, 0x00ba, + 0x2018, 0x2019, 0x201c, 0x201d, 0x00ab, 0x00bb, 0x00b0, 0x00a6, + 0x00e0, 0x00e1, 0x00e2, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, + 0x00ed, 0x00ee, 0x00ef, 0x00f1, 0x00f3, 0x00f4, 0x00f9, 0x00fa, + 0x00fb, 0x00fc, 0x00a9, 0x2500, 0x2502, 0x2514, 0x2518, 0x2510, + 0x250c, 0x251c, 0x2534, 0x2524, 0x252c, 0x253c, 0x00ac, 0x2588 +}; +*/ + +#endif diff --git a/cet/csn_369103.h b/cet/csn_369103.h new file mode 100644 index 000000000..4b6cca844 --- /dev/null +++ b/cet/csn_369103.h @@ -0,0 +1,200 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CSN_369103" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef csn_369103_h +#define csn_369103_h + +#define cet_cs_name_csn_369103 "CSN_369103" + +const char *cet_cs_alias_csn_369103[] = +{ + "CSN_369103", "iso-ir-139", "koi8l2", "KOI-8_L2", + NULL +}; + +#define cet_ucs4_ofs_csn_369103 36 +#define cet_ucs4_cnt_csn_369103 220 + +const int cet_ucs4_map_csn_369103[cet_ucs4_cnt_csn_369103] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, + 0x009c, 0x009d, 0x009e, 0x009f, 0x00a0, 0x0104, 0x02d8, 0x0141, + 0x0024, 0x013d, 0x015a, 0x00a7, 0x00a8, 0x0160, 0x015e, 0x0164, + 0x0179, 0x00ad, 0x017d, 0x017b, 0x00b0, 0x0105, 0x02db, 0x0142, + 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, 0x0161, 0x015f, 0x0165, + 0x017a, 0x02dd, 0x017e, 0x017c, 0x0154, 0x00c1, 0x00c2, 0x0102, + 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, + 0x011a, 0x00cd, 0x00ce, 0x010e, 0x0110, 0x0143, 0x0147, 0x00d3, + 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, + 0x00dc, 0x00dd, 0x0162, 0x00df, 0x0155, 0x00e1, 0x00e2, 0x0103, + 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, + 0x011b, 0x00ed, 0x00ee, 0x010f, 0x0111, 0x0144, 0x0148, 0x00f3, + 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, + 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; + +#define cet_ucs4_to_csn_369103_ct 59 + +const cet_ucs4_link_t cet_ucs4_to_csn_369103_links[cet_ucs4_to_csn_369103_ct] = +{ + {0x0024, 0xa4} /* sign */, + {0x00a4, 0x24} /* sign */, + {0x0102, 0xc3} /* capital letter a with breve */, + {0x0103, 0xe3} /* small letter a with breve */, + {0x0104, 0xa1} /* capital letter a with ogonek */, + {0x0105, 0xb1} /* small letter a with ogonek */, + {0x0106, 0xc6} /* capital letter c with acute */, + {0x0107, 0xe6} /* small letter c with acute */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x010e, 0xcf} /* capital letter d with caron */, + {0x010f, 0xef} /* small letter d with caron */, + {0x0110, 0xd0} /* capital letter d with stroke */, + {0x0111, 0xf0} /* small letter d with stroke */, + {0x0118, 0xca} /* capital letter e with ogonek */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x011a, 0xcc} /* capital letter e with caron */, + {0x011b, 0xec} /* small letter e with caron */, + {0x0139, 0xc5} /* capital letter l with acute */, + {0x013a, 0xe5} /* small letter l with acute */, + {0x013d, 0xa5} /* capital letter l with caron */, + {0x013e, 0xb5} /* small letter l with caron */, + {0x0141, 0xa3} /* capital letter l with stroke */, + {0x0142, 0xb3} /* small letter l with stroke */, + {0x0143, 0xd1} /* capital letter n with acute */, + {0x0144, 0xf1} /* small letter n with acute */, + {0x0147, 0xd2} /* capital letter n with caron */, + {0x0148, 0xf2} /* small letter n with caron */, + {0x0150, 0xd5} /* capital letter o with double acute */, + {0x0151, 0xf5} /* small letter o with double acute */, + {0x0154, 0xc0} /* capital letter r with acute */, + {0x0155, 0xe0} /* small letter r with acute */, + {0x0158, 0xd8} /* capital letter r with caron */, + {0x0159, 0xf8} /* small letter r with caron */, + {0x015a, 0xa6} /* capital letter s with acute */, + {0x015b, 0xb6} /* small letter s with acute */, + {0x015e, 0xaa} /* capital letter s with cedilla */, + {0x015f, 0xba} /* small letter s with cedilla */, + {0x0160, 0xa9} /* capital letter s with caron */, + {0x0161, 0xb9} /* small letter s with caron */, + {0x0162, 0xde} /* capital letter t with cedilla */, + {0x0163, 0xfe} /* small letter t with cedilla */, + {0x0164, 0xab} /* capital letter t with caron */, + {0x0165, 0xbb} /* small letter t with caron */, + {0x016e, 0xd9} /* capital letter u with ring above */, + {0x016f, 0xf9} /* small letter u with ring above */, + {0x0170, 0xdb} /* capital letter u with double acute */, + {0x0171, 0xfb} /* small letter u with double acute */, + {0x0179, 0xac} /* capital letter z with acute */, + {0x017a, 0xbc} /* small letter z with acute */, + {0x017b, 0xaf} /* capital letter z with dot above */, + {0x017c, 0xbf} /* small letter z with dot above */, + {0x017d, 0xae} /* capital letter z with caron */, + {0x017e, 0xbe} /* small letter z with caron */, + {0x02c7, 0xb7} /* caron */, + {0x02d8, 0xa2} /* breve */, + {0x02d9, 0xff} /* above */, + {0x02db, 0xb2} /* ogonek */, + {0x02dd, 0xbd} /* acute accent */ +}; + +/* +#define cet_ucs4_to_csn_369103_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_csn_369103_extra[cet_ucs4_to_csn_369103_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_csn_369103 = /* defined in cet.h */ +{ + cet_cs_name_csn_369103, /* name of character set */ + cet_cs_alias_csn_369103, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_csn_369103, /* char to UCS-4 value table */ + cet_ucs4_ofs_csn_369103, /* first non standard character */ + cet_ucs4_cnt_csn_369103, /* number of values in table */ + + cet_ucs4_to_csn_369103_links, /* UCS-4 to char links */ + cet_ucs4_to_csn_369103_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int csn_369103_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0104, 0x02d8, 0x0141, 0x0024, 0x013d, 0x015a, 0x00a7, + 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, + 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, + 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; +*/ + +#endif diff --git a/cet/cwi.h b/cet/cwi.h new file mode 100644 index 000000000..3b5be2206 --- /dev/null +++ b/cet/cwi.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CWI" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cwi_h +#define cwi_h + +#define cet_cs_name_cwi "CWI" + +const char *cet_cs_alias_cwi[] = +{ + "CWI", "cp-hu", "CWI-2", NULL +}; + +#define cet_ucs4_ofs_cwi 128 +#define cet_ucs4_cnt_cwi 128 + +const int cet_ucs4_map_cwi[cet_ucs4_cnt_cwi] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00cd, 0x00c4, 0x00c1, + 0x00c9, 0x00e6, 0x00c6, 0x0151, 0x00f6, 0x00d3, 0x0171, 0x00da, + 0x0170, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0xe01f, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x0150, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x03bc, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_cwi_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_cwi_links[cet_ucs4_to_cwi_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a5, 0x9d} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b7, 0xf9} /* dot */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c1, 0x8f} /* capital letter a with acute */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00cd, 0x8d} /* capital letter i with acute */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d3, 0x95} /* capital letter o with acute */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00da, 0x97} /* capital letter u with acute */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x0150, 0xa7} /* capital letter o with double acute */, + {0x0151, 0x93} /* small letter o with double acute */, + {0x0170, 0x98} /* capital letter u with double acute */, + {0x0171, 0x96} /* small letter u with double acute */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b2, 0xe1} /* small letter beta */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03bc, 0xe6} /* small letter mu */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x2205, 0xed} /* set */, + {0x2218, 0xf8} /* operator */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2310, 0xa9} /* not sign */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */, + {0xe01f, 0x9f} /* guilder sign (ibm437 159) */ +}; + +/* +#define cet_ucs4_to_cwi_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_cwi_extra[cet_ucs4_to_cwi_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_cwi = /* defined in cet.h */ +{ + cet_cs_name_cwi, /* name of character set */ + cet_cs_alias_cwi, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cwi, /* char to UCS-4 value table */ + cet_ucs4_ofs_cwi, /* first non standard character */ + cet_ucs4_cnt_cwi, /* number of values in table */ + + cet_ucs4_to_cwi_links, /* UCS-4 to char links */ + cet_ucs4_to_cwi_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cwi_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00cd, 0x00c4, 0x00c1, + 0x00c9, 0x00e6, 0x00c6, 0x0151, 0x00f6, 0x00d3, 0x0171, 0x00da, + 0x0170, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0xe01f, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x0150, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x03bc, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/dec_mcs.h b/cet/dec_mcs.h new file mode 100644 index 000000000..b7a319df8 --- /dev/null +++ b/cet/dec_mcs.h @@ -0,0 +1,129 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "DEC-MCS" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef dec_mcs_h +#define dec_mcs_h + +#define cet_cs_name_dec_mcs "DEC-MCS" + +const char *cet_cs_alias_dec_mcs[] = +{ + "DEC-MCS", "dec", NULL +}; + +#define cet_ucs4_ofs_dec_mcs 160 +#define cet_ucs4_cnt_dec_mcs 94 + +const int cet_ucs4_map_dec_mcs[cet_ucs4_cnt_dec_mcs] = +{ + -1, 0x00a1, 0x00a2, 0x00a3, -1, 0x00a5, -1, 0x00a7, + 0x00a4, 0x00a9, 0x00aa, 0x00ab, -1, -1, -1, -1, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, -1, 0x00b5, 0x00b6, 0x00b7, + -1, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, -1, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + -1, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0152, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0178, -1, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + -1, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0153, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00ff +}; + +#define cet_ucs4_to_dec_mcs_ct 5 + +const cet_ucs4_link_t cet_ucs4_to_dec_mcs_links[cet_ucs4_to_dec_mcs_ct] = +{ + {0x00a4, 0xa8} /* sign */, + {0x00ff, 0xfd} /* small letter y with diaeresis */, + {0x0152, 0xd7} /* capital ligature oe */, + {0x0153, 0xf7} /* small ligature oe */, + {0x0178, 0xdd} /* capital letter y with diaeresis */ +}; + +/* +#define cet_ucs4_to_dec_mcs_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_dec_mcs_extra[cet_ucs4_to_dec_mcs_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_dec_mcs = /* defined in cet.h */ +{ + cet_cs_name_dec_mcs, /* name of character set */ + cet_cs_alias_dec_mcs, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_dec_mcs, /* char to UCS-4 value table */ + cet_ucs4_ofs_dec_mcs, /* first non standard character */ + cet_ucs4_cnt_dec_mcs, /* number of values in table */ + + cet_ucs4_to_dec_mcs_links, /* UCS-4 to char links */ + cet_ucs4_to_dec_mcs_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int dec_mcs_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + -1, 0x00a1, 0x00a2, 0x00a3, -1, 0x00a5, -1, 0x00a7, + 0x00a4, 0x00a9, 0x00aa, 0x00ab, -1, -1, -1, -1, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, -1, 0x00b5, 0x00b6, 0x00b7, + -1, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, -1, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + -1, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0152, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0178, -1, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + -1, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0153, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00ff, -1, -1 +}; +*/ + +#endif diff --git a/cet/din_66003.h b/cet/din_66003.h new file mode 100644 index 000000000..cd0b69d18 --- /dev/null +++ b/cet/din_66003.h @@ -0,0 +1,129 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "DIN_66003" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef din_66003_h +#define din_66003_h + +#define cet_cs_name_din_66003 "DIN_66003" + +const char *cet_cs_alias_din_66003[] = +{ + "DIN_66003", "de", "ISO646-DE", "iso-ir-21", + NULL +}; + +#define cet_ucs4_ofs_din_66003 64 +#define cet_ucs4_cnt_din_66003 64 + +const int cet_ucs4_map_din_66003[cet_ucs4_cnt_din_66003] = +{ + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00dc, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00fc, 0x00df, 0x007f +}; + +#define cet_ucs4_to_din_66003_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_din_66003_links[cet_ucs4_to_din_66003_ct] = +{ + {0x00a7, 0x40} /* sign */, + {0x00c4, 0x5b} /* capital letter a with diaeresis */, + {0x00d6, 0x5c} /* capital letter o with diaeresis */, + {0x00dc, 0x5d} /* capital letter u with diaeresis */, + {0x00df, 0x7e} /* small letter sharp s (german) */, + {0x00e4, 0x7b} /* small letter a with diaeresis */, + {0x00f6, 0x7c} /* small letter o with diaeresis */, + {0x00fc, 0x7d} /* small letter u with diaeresis */ +}; + +/* +#define cet_ucs4_to_din_66003_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_din_66003_extra[cet_ucs4_to_din_66003_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_din_66003 = /* defined in cet.h */ +{ + cet_cs_name_din_66003, /* name of character set */ + cet_cs_alias_din_66003, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_din_66003, /* char to UCS-4 value table */ + cet_ucs4_ofs_din_66003, /* first non standard character */ + cet_ucs4_cnt_din_66003, /* number of values in table */ + + cet_ucs4_to_din_66003_links, /* UCS-4 to char links */ + cet_ucs4_to_din_66003_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int din_66003_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00dc, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00fc, 0x00df, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ds_2089.h b/cet/ds_2089.h new file mode 100644 index 000000000..1035225e7 --- /dev/null +++ b/cet/ds_2089.h @@ -0,0 +1,124 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "DS_2089" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ds_2089_h +#define ds_2089_h + +#define cet_cs_name_ds_2089 "DS_2089" + +const char *cet_cs_alias_ds_2089[] = +{ + "DS_2089", "dk", "DS2089", "ISO646-DK", + NULL +}; + +#define cet_ucs4_ofs_ds_2089 91 +#define cet_ucs4_cnt_ds_2089 37 + +const int cet_ucs4_map_ds_2089[cet_ucs4_cnt_ds_2089] = +{ + 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e6, 0x00f8, 0x00e5, 0x007e, 0x007f +}; + +#define cet_ucs4_to_ds_2089_ct 6 + +const cet_ucs4_link_t cet_ucs4_to_ds_2089_links[cet_ucs4_to_ds_2089_ct] = +{ + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00c6, 0x5b} /* capital letter ae */, + {0x00d8, 0x5c} /* capital letter o with stroke */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00e6, 0x7b} /* small letter ae */, + {0x00f8, 0x7c} /* small letter o with stroke */ +}; + +/* +#define cet_ucs4_to_ds_2089_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ds_2089_extra[cet_ucs4_to_ds_2089_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ds_2089 = /* defined in cet.h */ +{ + cet_cs_name_ds_2089, /* name of character set */ + cet_cs_alias_ds_2089, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ds_2089, /* char to UCS-4 value table */ + cet_ucs4_ofs_ds_2089, /* first non standard character */ + cet_ucs4_cnt_ds_2089, /* number of values in table */ + + cet_ucs4_to_ds_2089_links, /* UCS-4 to char links */ + cet_ucs4_to_ds_2089_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ds_2089_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ecma_cyrillic.h b/cet/ecma_cyrillic.h new file mode 100644 index 000000000..dda8a7058 --- /dev/null +++ b/cet/ecma_cyrillic.h @@ -0,0 +1,219 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ECMA-cyrillic" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ecma_cyrillic_h +#define ecma_cyrillic_h + +#define cet_cs_name_ecma_cyrillic "ECMA-cyrillic" + +const char *cet_cs_alias_ecma_cyrillic[] = +{ + "ECMA-cyrillic", "ECMA-113", "ECMA-113:1986", "iso-ir-111", + NULL +}; + +#define cet_ucs4_ofs_ecma_cyrillic 161 +#define cet_ucs4_cnt_ecma_cyrillic 95 + +const int cet_ucs4_map_ecma_cyrillic[cet_ucs4_cnt_ecma_cyrillic] = +{ + 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, + 0x0459, 0x045a, 0x045b, 0x045c, 0x00ad, 0x045e, 0x045f, 0x2116, + 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, + 0x0409, 0x040a, 0x040b, 0x040c, 0x00a4, 0x040e, 0x040f, 0x044e, + 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, 0x044c, + 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, 0x042e, + 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 0x042c, + 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; + +#define cet_ucs4_to_ecma_cyrillic_ct 94 + +const cet_ucs4_link_t cet_ucs4_to_ecma_cyrillic_links[cet_ucs4_to_ecma_cyrillic_ct] = +{ + {0x00a4, 0xbd} /* sign */, + {0x0401, 0xb3} /* capital letter io */, + {0x0402, 0xb1} /* capital letter dje (serbocroatian) */, + {0x0403, 0xb2} /* capital letter gje (macedonian) */, + {0x0404, 0xb4} /* capital letter ukrainian ie */, + {0x0405, 0xb5} /* capital letter dze (macedonian) */, + {0x0406, 0xb6} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0xb7} /* capital letter yi (ukrainian) */, + {0x0408, 0xb8} /* capital letter je */, + {0x0409, 0xb9} /* capital letter lje */, + {0x040a, 0xba} /* capital letter nje */, + {0x040b, 0xbb} /* capital letter tshe (serbocroatian) */, + {0x040c, 0xbc} /* capital letter kje (macedonian) */, + {0x040e, 0xbe} /* capital letter short u (byelorussian) */, + {0x040f, 0xbf} /* capital letter dzhe */, + {0x0410, 0xe1} /* capital letter a */, + {0x0411, 0xe2} /* capital letter be */, + {0x0412, 0xf7} /* capital letter ve */, + {0x0413, 0xe7} /* capital letter ghe */, + {0x0414, 0xe4} /* capital letter de */, + {0x0415, 0xe5} /* capital letter ie */, + {0x0416, 0xf6} /* capital letter zhe */, + {0x0417, 0xfa} /* capital letter ze */, + {0x0418, 0xe9} /* capital letter i */, + {0x0419, 0xea} /* capital letter short i */, + {0x041a, 0xeb} /* capital letter ka */, + {0x041b, 0xec} /* capital letter el */, + {0x041c, 0xed} /* capital letter em */, + {0x041d, 0xee} /* capital letter en */, + {0x041e, 0xef} /* capital letter o */, + {0x041f, 0xf0} /* capital letter pe */, + {0x0420, 0xf2} /* capital letter er */, + {0x0421, 0xf3} /* capital letter es */, + {0x0422, 0xf4} /* capital letter te */, + {0x0423, 0xf5} /* capital letter u */, + {0x0424, 0xe6} /* capital letter ef */, + {0x0425, 0xe8} /* capital letter ha */, + {0x0426, 0xe3} /* capital letter tse */, + {0x0427, 0xfe} /* capital letter che */, + {0x0428, 0xfb} /* capital letter sha */, + {0x0429, 0xfd} /* capital letter shcha */, + {0x042a, 0xff} /* capital letter hard sign */, + {0x042b, 0xf9} /* capital letter yeru */, + {0x042c, 0xf8} /* capital letter soft sign */, + {0x042d, 0xfc} /* capital letter e */, + {0x042e, 0xe0} /* capital letter yu */, + {0x042f, 0xf1} /* capital letter ya */, + {0x0430, 0xc1} /* small letter a */, + {0x0431, 0xc2} /* small letter be */, + {0x0432, 0xd7} /* small letter ve */, + {0x0433, 0xc7} /* small letter ghe */, + {0x0434, 0xc4} /* small letter de */, + {0x0435, 0xc5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xda} /* small letter ze */, + {0x0438, 0xc9} /* small letter i */, + {0x0439, 0xca} /* small letter short i */, + {0x043a, 0xcb} /* small letter ka */, + {0x043b, 0xcc} /* small letter el */, + {0x043c, 0xcd} /* small letter em */, + {0x043d, 0xce} /* small letter en */, + {0x043e, 0xcf} /* small letter o */, + {0x043f, 0xd0} /* small letter pe */, + {0x0440, 0xd2} /* small letter er */, + {0x0441, 0xd3} /* small letter es */, + {0x0442, 0xd4} /* small letter te */, + {0x0443, 0xd5} /* small letter u */, + {0x0444, 0xc6} /* small letter ef */, + {0x0445, 0xc8} /* small letter ha */, + {0x0446, 0xc3} /* small letter tse */, + {0x0447, 0xde} /* small letter che */, + {0x0448, 0xdb} /* small letter sha */, + {0x0449, 0xdd} /* small letter shcha */, + {0x044a, 0xdf} /* small letter hard sign */, + {0x044b, 0xd9} /* small letter yeru */, + {0x044c, 0xd8} /* small letter soft sign */, + {0x044d, 0xdc} /* small letter e */, + {0x044e, 0xc0} /* small letter yu */, + {0x044f, 0xd1} /* small letter ya */, + {0x0451, 0xa3} /* small letter io */, + {0x0452, 0xa1} /* small letter dje (serbocroatian) */, + {0x0453, 0xa2} /* small letter gje (macedonian) */, + {0x0454, 0xa4} /* small letter ukrainian ie */, + {0x0455, 0xa5} /* small letter dze (macedonian) */, + {0x0456, 0xa6} /* small letter byelorussian-ukrainian i */, + {0x0457, 0xa7} /* small letter yi (ukrainian) */, + {0x0458, 0xa8} /* small letter je */, + {0x0459, 0xa9} /* small letter lje */, + {0x045a, 0xaa} /* small letter nje */, + {0x045b, 0xab} /* small letter tshe (serbocroatian) */, + {0x045c, 0xac} /* small letter kje (macedonian) */, + {0x045e, 0xae} /* small letter short u (byelorussian) */, + {0x045f, 0xaf} /* small letter dzhe */, + {0x2116, 0xb0} /* sign */ +}; + +/* +#define cet_ucs4_to_ecma_cyrillic_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ecma_cyrillic_extra[cet_ucs4_to_ecma_cyrillic_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ecma_cyrillic = /* defined in cet.h */ +{ + cet_cs_name_ecma_cyrillic, /* name of character set */ + cet_cs_alias_ecma_cyrillic, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ecma_cyrillic, /* char to UCS-4 value table */ + cet_ucs4_ofs_ecma_cyrillic, /* first non standard character */ + cet_ucs4_cnt_ecma_cyrillic, /* number of values in table */ + + cet_ucs4_to_ecma_cyrillic_links, /* UCS-4 to char links */ + cet_ucs4_to_ecma_cyrillic_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ecma_cyrillic_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00ad, 0x045e, 0x045f, + 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00a4, 0x040e, 0x040f, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; +*/ + +#endif diff --git a/cet/es.h b/cet/es.h new file mode 100644 index 000000000..4fd66e8a0 --- /dev/null +++ b/cet/es.h @@ -0,0 +1,132 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ES" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef es_h +#define es_h + +#define cet_cs_name_es "ES" + +const char *cet_cs_alias_es[] = +{ + "ES", "ISO646-ES", "iso-ir-17", NULL +}; + +#define cet_ucs4_ofs_es 35 +#define cet_ucs4_cnt_es 93 + +const int cet_ucs4_map_es[cet_ucs4_cnt_es] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x00a7, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x00a1, 0x00d1, 0x00bf, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00b0, 0x00f1, 0x00e7, 0x007e, 0x007f +}; + +#define cet_ucs4_to_es_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_es_links[cet_ucs4_to_es_ct] = +{ + {0x00a1, 0x5b} /* exclamation mark */, + {0x00a3, 0x23} /* sign */, + {0x00a7, 0x40} /* sign */, + {0x00b0, 0x7b} /* sign */, + {0x00bf, 0x5d} /* question mark */, + {0x00d1, 0x5c} /* capital letter n with tilde */, + {0x00e7, 0x7d} /* small letter c with cedilla */, + {0x00f1, 0x7c} /* small letter n with tilde */ +}; + +/* +#define cet_ucs4_to_es_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_es_extra[cet_ucs4_to_es_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_es = /* defined in cet.h */ +{ + cet_cs_name_es, /* name of character set */ + cet_cs_alias_es, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_es, /* char to UCS-4 value table */ + cet_ucs4_ofs_es, /* first non standard character */ + cet_ucs4_cnt_es, /* number of values in table */ + + cet_ucs4_to_es_links, /* UCS-4 to char links */ + cet_ucs4_to_es_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int es_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00a1, 0x00d1, 0x00bf, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00b0, 0x00f1, 0x00e7, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/es2.h b/cet/es2.h new file mode 100644 index 000000000..ec3e2a91b --- /dev/null +++ b/cet/es2.h @@ -0,0 +1,129 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ES2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef es2_h +#define es2_h + +#define cet_cs_name_es2 "ES2" + +const char *cet_cs_alias_es2[] = +{ + "ES2", "ISO646-ES2", "iso-ir-85", NULL +}; + +#define cet_ucs4_ofs_es2 64 +#define cet_ucs4_cnt_es2 64 + +const int cet_ucs4_map_es2[cet_ucs4_cnt_es2] = +{ + 0x2022, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00a1, 0x00d1, 0x00c7, 0x00bf, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00b4, 0x00f1, 0x00e7, 0x00a8, 0x007f +}; + +#define cet_ucs4_to_es2_ct 9 + +const cet_ucs4_link_t cet_ucs4_to_es2_links[cet_ucs4_to_es2_ct] = +{ + {0x00a1, 0x5b} /* exclamation mark */, + {0x00a8, 0x7e} /* diaeresis */, + {0x00b4, 0x7b} /* accent */, + {0x00bf, 0x5e} /* question mark */, + {0x00c7, 0x5d} /* capital letter c with cedilla */, + {0x00d1, 0x5c} /* capital letter n with tilde */, + {0x00e7, 0x7d} /* small letter c with cedilla */, + {0x00f1, 0x7c} /* small letter n with tilde */, + {0x2022, 0x40} /* puce */ +}; + +/* +#define cet_ucs4_to_es2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_es2_extra[cet_ucs4_to_es2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_es2 = /* defined in cet.h */ +{ + cet_cs_name_es2, /* name of character set */ + cet_cs_alias_es2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_es2, /* char to UCS-4 value table */ + cet_ucs4_ofs_es2, /* first non standard character */ + cet_ucs4_cnt_es2, /* number of values in table */ + + cet_ucs4_to_es2_links, /* UCS-4 to char links */ + cet_ucs4_to_es2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int es2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x2022, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00a1, 0x00d1, 0x00c7, 0x00bf, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00b4, 0x00f1, 0x00e7, 0x00a8, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/gb_1988_80.h b/cet/gb_1988_80.h new file mode 100644 index 000000000..90cb5fbb0 --- /dev/null +++ b/cet/gb_1988_80.h @@ -0,0 +1,127 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "GB_1988-80" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef gb_1988_80_h +#define gb_1988_80_h + +#define cet_cs_name_gb_1988_80 "GB_1988-80" + +const char *cet_cs_alias_gb_1988_80[] = +{ + "GB_1988-80", "cn", "csISO57GB1988", "ISO646-CN", + "iso-ir-57", NULL +}; + +#define cet_ucs4_ofs_gb_1988_80 36 +#define cet_ucs4_cnt_gb_1988_80 92 + +const int cet_ucs4_map_gb_1988_80[cet_ucs4_cnt_gb_1988_80] = +{ + 0x00a5, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x203e, 0x007f +}; + +#define cet_ucs4_to_gb_1988_80_ct 2 + +const cet_ucs4_link_t cet_ucs4_to_gb_1988_80_links[cet_ucs4_to_gb_1988_80_ct] = +{ + {0x00a5, 0x24} /* sign */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_gb_1988_80_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_gb_1988_80_extra[cet_ucs4_to_gb_1988_80_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_gb_1988_80 = /* defined in cet.h */ +{ + cet_cs_name_gb_1988_80, /* name of character set */ + cet_cs_alias_gb_1988_80, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_gb_1988_80, /* char to UCS-4 value table */ + cet_ucs4_ofs_gb_1988_80, /* first non standard character */ + cet_ucs4_cnt_gb_1988_80, /* number of values in table */ + + cet_ucs4_to_gb_1988_80_links, /* UCS-4 to char links */ + cet_ucs4_to_gb_1988_80_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int gb_1988_80_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a5, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/gost_19768_87.h b/cet/gost_19768_87.h new file mode 100644 index 000000000..6a18ac504 --- /dev/null +++ b/cet/gost_19768_87.h @@ -0,0 +1,189 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "GOST_19768-87" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef gost_19768_87_h +#define gost_19768_87_h + +#define cet_cs_name_gost_19768_87 "GOST_19768-87" + +const char *cet_cs_alias_gost_19768_87[] = +{ + "GOST_19768-87", "iso-ir-153", "ST_SEV_358-88", NULL +}; + +#define cet_ucs4_ofs_gost_19768_87 161 +#define cet_ucs4_cnt_gost_19768_87 81 + +const int cet_ucs4_map_gost_19768_87[cet_ucs4_cnt_gost_19768_87] = +{ + 0x0401, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 0x00ad, -1, -1, 0x0410, + 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, + 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x0420, + 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, + 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, + 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, + 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, + 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, + 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, -1, + 0x0451 +}; + +#define cet_ucs4_to_gost_19768_87_ct 66 + +const cet_ucs4_link_t cet_ucs4_to_gost_19768_87_links[cet_ucs4_to_gost_19768_87_ct] = +{ + {0x0401, 0xa1} /* capital letter io */, + {0x0410, 0xb0} /* capital letter a */, + {0x0411, 0xb1} /* capital letter be */, + {0x0412, 0xb2} /* capital letter ve */, + {0x0413, 0xb3} /* capital letter ghe */, + {0x0414, 0xb4} /* capital letter de */, + {0x0415, 0xb5} /* capital letter ie */, + {0x0416, 0xb6} /* capital letter zhe */, + {0x0417, 0xb7} /* capital letter ze */, + {0x0418, 0xb8} /* capital letter i */, + {0x0419, 0xb9} /* capital letter short i */, + {0x041a, 0xba} /* capital letter ka */, + {0x041b, 0xbb} /* capital letter el */, + {0x041c, 0xbc} /* capital letter em */, + {0x041d, 0xbd} /* capital letter en */, + {0x041e, 0xbe} /* capital letter o */, + {0x041f, 0xbf} /* capital letter pe */, + {0x0420, 0xc0} /* capital letter er */, + {0x0421, 0xc1} /* capital letter es */, + {0x0422, 0xc2} /* capital letter te */, + {0x0423, 0xc3} /* capital letter u */, + {0x0424, 0xc4} /* capital letter ef */, + {0x0425, 0xc5} /* capital letter ha */, + {0x0426, 0xc6} /* capital letter tse */, + {0x0427, 0xc7} /* capital letter che */, + {0x0428, 0xc8} /* capital letter sha */, + {0x0429, 0xc9} /* capital letter shcha */, + {0x042a, 0xca} /* capital letter hard sign */, + {0x042b, 0xcb} /* capital letter yeru */, + {0x042c, 0xcc} /* capital letter soft sign */, + {0x042d, 0xcd} /* capital letter e */, + {0x042e, 0xce} /* capital letter yu */, + {0x042f, 0xcf} /* capital letter ya */, + {0x0430, 0xd0} /* small letter a */, + {0x0431, 0xd1} /* small letter be */, + {0x0432, 0xd2} /* small letter ve */, + {0x0433, 0xd3} /* small letter ghe */, + {0x0434, 0xd4} /* small letter de */, + {0x0435, 0xd5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xd7} /* small letter ze */, + {0x0438, 0xd8} /* small letter i */, + {0x0439, 0xd9} /* small letter short i */, + {0x043a, 0xda} /* small letter ka */, + {0x043b, 0xdb} /* small letter el */, + {0x043c, 0xdc} /* small letter em */, + {0x043d, 0xdd} /* small letter en */, + {0x043e, 0xde} /* small letter o */, + {0x043f, 0xdf} /* small letter pe */, + {0x0440, 0xe0} /* small letter er */, + {0x0441, 0xe1} /* small letter es */, + {0x0442, 0xe2} /* small letter te */, + {0x0443, 0xe3} /* small letter u */, + {0x0444, 0xe4} /* small letter ef */, + {0x0445, 0xe5} /* small letter ha */, + {0x0446, 0xe6} /* small letter tse */, + {0x0447, 0xe7} /* small letter che */, + {0x0448, 0xe8} /* small letter sha */, + {0x0449, 0xe9} /* small letter shcha */, + {0x044a, 0xea} /* small letter hard sign */, + {0x044b, 0xeb} /* small letter yeru */, + {0x044c, 0xec} /* small letter soft sign */, + {0x044d, 0xed} /* small letter e */, + {0x044e, 0xee} /* small letter yu */, + {0x044f, 0xef} /* small letter ya */, + {0x0451, 0xf1} /* small letter io */ +}; + +/* +#define cet_ucs4_to_gost_19768_87_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_gost_19768_87_extra[cet_ucs4_to_gost_19768_87_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_gost_19768_87 = /* defined in cet.h */ +{ + cet_cs_name_gost_19768_87, /* name of character set */ + cet_cs_alias_gost_19768_87, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_gost_19768_87, /* char to UCS-4 value table */ + cet_ucs4_ofs_gost_19768_87, /* first non standard character */ + cet_ucs4_cnt_gost_19768_87, /* number of values in table */ + + cet_ucs4_to_gost_19768_87_links, /* UCS-4 to char links */ + cet_ucs4_to_gost_19768_87_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int gost_19768_87_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0401, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0x00ad, -1, -1, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + -1, 0x0451, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/hp_roman8.h b/cet/hp_roman8.h new file mode 100644 index 000000000..8663e43b8 --- /dev/null +++ b/cet/hp_roman8.h @@ -0,0 +1,219 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "hp-roman8" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef hp_roman8_h +#define hp_roman8_h + +#define cet_cs_name_hp_roman8 "hp-roman8" + +const char *cet_cs_alias_hp_roman8[] = +{ + "hp-roman8", "csHPRoman8", "r8", "roman8", + NULL +}; + +#define cet_ucs4_ofs_hp_roman8 161 +#define cet_ucs4_cnt_hp_roman8 94 + +const int cet_ucs4_map_hp_roman8[cet_ucs4_cnt_hp_roman8] = +{ + 0x00c0, 0x00c2, 0x00c8, 0x00ca, 0x00cb, 0x00ce, 0x00cf, 0x00b4, + 0x02cb, 0x02c6, 0x00a8, 0x02dc, 0x00d9, 0x00db, 0x20a4, 0x00af, + 0x00dd, 0x00fd, 0x00b0, 0x00c7, 0x00e7, 0x00d1, 0x00f1, 0x00a1, + 0x00bf, 0x00a4, 0x00a3, 0x00a5, 0x00a7, 0x0192, 0x00a2, 0x00e2, + 0x00ea, 0x00f4, 0x00fb, 0x00e1, 0x00e9, 0x00f3, 0x00fa, 0x00e0, + 0x00e8, 0x00f2, 0x00f9, 0x00e4, 0x00eb, 0x00f6, 0x00fc, 0x00c5, + 0x00ee, 0x00d8, 0x00c6, 0x00e5, 0x00ed, 0x00f8, 0x00e6, 0x00c4, + 0x00ec, 0x00d6, 0x00dc, 0x00c9, 0x00ef, 0x00df, 0x00d4, 0x00c1, + 0x00c3, 0x00e3, 0x00d0, 0x00f0, 0x00cd, 0x00cc, 0x00d3, 0x00d2, + 0x00d5, 0x00f5, 0x0160, 0x0161, 0x00da, 0x0178, 0x00ff, 0x00de, + 0x00fe, 0x00b7, 0x00b5, 0x00b6, 0x00be, 0x2014, 0x00bc, 0x00bd, + 0x00aa, 0x00ba, 0x00ab, 0x25a0, 0x00bb, 0x00b1 +}; + +#define cet_ucs4_to_hp_roman8_ct 94 + +const cet_ucs4_link_t cet_ucs4_to_hp_roman8_links[cet_ucs4_to_hp_roman8_ct] = +{ + {0x00a1, 0xb8} /* exclamation mark */, + {0x00a2, 0xbf} /* sign */, + {0x00a3, 0xbb} /* sign */, + {0x00a4, 0xba} /* sign */, + {0x00a5, 0xbc} /* sign */, + {0x00a7, 0xbd} /* sign */, + {0x00a8, 0xab} /* diaeresis */, + {0x00aa, 0xf9} /* ordinal indicator */, + {0x00ab, 0xfb} /* double angle quotation mark */, + {0x00af, 0xb0} /* macron */, + {0x00b0, 0xb3} /* sign */, + {0x00b1, 0xfe} /* sign */, + {0x00b4, 0xa8} /* accent */, + {0x00b5, 0xf3} /* sign */, + {0x00b6, 0xf4} /* sign */, + {0x00b7, 0xf2} /* dot */, + {0x00ba, 0xfa} /* ordinal indicator */, + {0x00bb, 0xfd} /* double angle quotation mark */, + {0x00bc, 0xf7} /* fraction one quarter */, + {0x00bd, 0xf8} /* fraction one half */, + {0x00be, 0xf5} /* fraction three quarters */, + {0x00bf, 0xb9} /* question mark */, + {0x00c0, 0xa1} /* capital letter a with grave */, + {0x00c1, 0xe0} /* capital letter a with acute */, + {0x00c2, 0xa2} /* capital letter a with circumflex */, + {0x00c3, 0xe1} /* capital letter a with tilde */, + {0x00c4, 0xd8} /* capital letter a with diaeresis */, + {0x00c5, 0xd0} /* capital letter a with ring above */, + {0x00c6, 0xd3} /* capital letter ae */, + {0x00c7, 0xb4} /* capital letter c with cedilla */, + {0x00c8, 0xa3} /* capital letter e with grave */, + {0x00c9, 0xdc} /* capital letter e with acute */, + {0x00ca, 0xa4} /* capital letter e with circumflex */, + {0x00cb, 0xa5} /* capital letter e with diaeresis */, + {0x00cc, 0xe6} /* capital letter i with grave */, + {0x00cd, 0xe5} /* capital letter i with acute */, + {0x00ce, 0xa6} /* capital letter i with circumflex */, + {0x00cf, 0xa7} /* capital letter i with diaeresis */, + {0x00d0, 0xe3} /* capital letter eth (icelandic) */, + {0x00d1, 0xb6} /* capital letter n with tilde */, + {0x00d2, 0xe8} /* capital letter o with grave */, + {0x00d3, 0xe7} /* capital letter o with acute */, + {0x00d4, 0xdf} /* capital letter o with circumflex */, + {0x00d5, 0xe9} /* capital letter o with tilde */, + {0x00d6, 0xda} /* capital letter o with diaeresis */, + {0x00d8, 0xd2} /* capital letter o with stroke */, + {0x00d9, 0xad} /* capital letter u with grave */, + {0x00da, 0xed} /* capital letter u with acute */, + {0x00db, 0xae} /* capital letter u with circumflex */, + {0x00dc, 0xdb} /* capital letter u with diaeresis */, + {0x00dd, 0xb1} /* capital letter y with acute */, + {0x00de, 0xf0} /* capital letter thorn (icelandic) */, + {0x00df, 0xde} /* small letter sharp s (german) */, + {0x00e0, 0xc8} /* small letter a with grave */, + {0x00e1, 0xc4} /* small letter a with acute */, + {0x00e2, 0xc0} /* small letter a with circumflex */, + {0x00e3, 0xe2} /* small letter a with tilde */, + {0x00e4, 0xcc} /* small letter a with diaeresis */, + {0x00e5, 0xd4} /* small letter a with ring above */, + {0x00e6, 0xd7} /* small letter ae */, + {0x00e7, 0xb5} /* small letter c with cedilla */, + {0x00e8, 0xc9} /* small letter e with grave */, + {0x00e9, 0xc5} /* small letter e with acute */, + {0x00ea, 0xc1} /* small letter e with circumflex */, + {0x00eb, 0xcd} /* small letter e with diaeresis */, + {0x00ec, 0xd9} /* small letter i with grave */, + {0x00ed, 0xd5} /* small letter i with acute */, + {0x00ee, 0xd1} /* small letter i with circumflex */, + {0x00ef, 0xdd} /* small letter i with diaeresis */, + {0x00f0, 0xe4} /* small letter eth (icelandic) */, + {0x00f1, 0xb7} /* small letter n with tilde */, + {0x00f2, 0xca} /* small letter o with grave */, + {0x00f3, 0xc6} /* small letter o with acute */, + {0x00f4, 0xc2} /* small letter o with circumflex */, + {0x00f5, 0xea} /* small letter o with tilde */, + {0x00f6, 0xce} /* small letter o with diaeresis */, + {0x00f8, 0xd6} /* small letter o with stroke */, + {0x00f9, 0xcb} /* small letter u with grave */, + {0x00fa, 0xc7} /* small letter u with acute */, + {0x00fb, 0xc3} /* small letter u with circumflex */, + {0x00fc, 0xcf} /* small letter u with diaeresis */, + {0x00fd, 0xb2} /* small letter y with acute */, + {0x00fe, 0xf1} /* small letter thorn (icelandic) */, + {0x00ff, 0xef} /* small letter y with diaeresis */, + {0x0160, 0xeb} /* capital letter s with caron */, + {0x0161, 0xec} /* small letter s with caron */, + {0x0178, 0xee} /* capital letter y with diaeresis */, + {0x0192, 0xbe} /* minuscule latine f hameçon */, + {0x02c6, 0xaa} /* modificative accent circonflexe */, + {0x02cb, 0xa9} /* modificative accent grave */, + {0x02dc, 0xac} /* tilde */, + {0x2014, 0xf6} /* dash */, + {0x20a4, 0xaf} /* sign */, + {0x25a0, 0xfc} /* square */ +}; + +/* +#define cet_ucs4_to_hp_roman8_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_hp_roman8_extra[cet_ucs4_to_hp_roman8_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_hp_roman8 = /* defined in cet.h */ +{ + cet_cs_name_hp_roman8, /* name of character set */ + cet_cs_alias_hp_roman8, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_hp_roman8, /* char to UCS-4 value table */ + cet_ucs4_ofs_hp_roman8, /* first non standard character */ + cet_ucs4_cnt_hp_roman8, /* number of values in table */ + + cet_ucs4_to_hp_roman8_links, /* UCS-4 to char links */ + cet_ucs4_to_hp_roman8_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int hp_roman8_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00c0, 0x00c2, 0x00c8, 0x00ca, 0x00cb, 0x00ce, 0x00cf, + 0x00b4, 0x02cb, 0x02c6, 0x00a8, 0x02dc, 0x00d9, 0x00db, 0x20a4, + 0x00af, 0x00dd, 0x00fd, 0x00b0, 0x00c7, 0x00e7, 0x00d1, 0x00f1, + 0x00a1, 0x00bf, 0x00a4, 0x00a3, 0x00a5, 0x00a7, 0x0192, 0x00a2, + 0x00e2, 0x00ea, 0x00f4, 0x00fb, 0x00e1, 0x00e9, 0x00f3, 0x00fa, + 0x00e0, 0x00e8, 0x00f2, 0x00f9, 0x00e4, 0x00eb, 0x00f6, 0x00fc, + 0x00c5, 0x00ee, 0x00d8, 0x00c6, 0x00e5, 0x00ed, 0x00f8, 0x00e6, + 0x00c4, 0x00ec, 0x00d6, 0x00dc, 0x00c9, 0x00ef, 0x00df, 0x00d4, + 0x00c1, 0x00c3, 0x00e3, 0x00d0, 0x00f0, 0x00cd, 0x00cc, 0x00d3, + 0x00d2, 0x00d5, 0x00f5, 0x0160, 0x0161, 0x00da, 0x0178, 0x00ff, + 0x00de, 0x00fe, 0x00b7, 0x00b5, 0x00b6, 0x00be, 0x2014, 0x00bc, + 0x00bd, 0x00aa, 0x00ba, 0x00ab, 0x25a0, 0x00bb, 0x00b1, -1 +}; +*/ + +#endif diff --git a/cet/ibm037.h b/cet/ibm037.h new file mode 100644 index 000000000..3e4913720 --- /dev/null +++ b/cet/ibm037.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM037" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm037_h +#define ibm037_h + +#define cet_cs_name_ibm037 "IBM037" + +const char *cet_cs_alias_ibm037[] = +{ + "IBM037", "037", "CP037", "ebcdic-cp-ca", + "ebcdic-cp-nl", "ebcdic-cp-us", "ebcdic-cp-wt", NULL +}; + +#define cet_ucs4_ofs_ibm037 4 +#define cet_ucs4_cnt_ibm037 252 + +const int cet_ucs4_map_ibm037[cet_ucs4_cnt_ibm037] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x00a2, 0x002e, + 0x003c, 0x0028, 0x002b, 0x007c, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x0021, 0x0024, + 0x002a, 0x0029, 0x003b, 0x00ac, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x007e, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x005e, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x005b, 0x005d, + 0x00af, 0x00a8, 0x00b4, 0x00d7, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm037_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm037_links[cet_ucs4_to_ibm037_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x5a} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0xba} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0xbb} /* square bracket */, + {0x005e, 0xb0} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0x4f} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xa1} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0x4a} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0x5f} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00af, 0xbc} /* macron */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */ +}; + +/* +#define cet_ucs4_to_ibm037_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm037_extra[cet_ucs4_to_ibm037_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm037 = /* defined in cet.h */ +{ + cet_cs_name_ibm037, /* name of character set */ + cet_cs_alias_ibm037, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm037, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm037, /* first non standard character */ + cet_ucs4_cnt_ibm037, /* number of values in table */ + + cet_ucs4_to_ibm037_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm037_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm037_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x00a2, 0x002e, 0x003c, 0x0028, 0x002b, 0x007c, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x0021, 0x0024, 0x002a, 0x0029, 0x003b, 0x00ac, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x007e, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x005e, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x005b, 0x005d, 0x00af, 0x00a8, 0x00b4, 0x00d7, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm1004.h b/cet/ibm1004.h new file mode 100644 index 000000000..152dcd9d0 --- /dev/null +++ b/cet/ibm1004.h @@ -0,0 +1,152 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM1004" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm1004_h +#define ibm1004_h + +#define cet_cs_name_ibm1004 "IBM1004" + +const char *cet_cs_alias_ibm1004[] = +{ + "IBM1004", "1004", "CP1004", "os2latin1", + NULL +}; + +#define cet_ucs4_ofs_ibm1004 128 +#define cet_ucs4_cnt_ibm1004 128 + +const int cet_ucs4_map_ibm1004[cet_ucs4_cnt_ibm1004] = +{ + -1, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, -1, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; + +#define cet_ucs4_to_ibm1004_ct 23 + +const cet_ucs4_link_t cet_ucs4_to_ibm1004_links[cet_ucs4_to_ibm1004_ct] = +{ + {0x0152, 0x8c} /* capital ligature oe */, + {0x0153, 0x9c} /* small ligature oe */, + {0x0160, 0x8a} /* capital letter s with caron */, + {0x0161, 0x9a} /* small letter s with caron */, + {0x0178, 0x9f} /* capital letter y with diaeresis */, + {0x02c6, 0x88} /* modificative accent circonflexe */, + {0x02dc, 0x98} /* tilde */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x2122, 0x99} /* mark sign */ +}; + +/* +#define cet_ucs4_to_ibm1004_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm1004_extra[cet_ucs4_to_ibm1004_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm1004 = /* defined in cet.h */ +{ + cet_cs_name_ibm1004, /* name of character set */ + cet_cs_alias_ibm1004, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm1004, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm1004, /* first non standard character */ + cet_ucs4_cnt_ibm1004, /* number of values in table */ + + cet_ucs4_to_ibm1004_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm1004_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm1004_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, -1, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; +*/ + +#endif diff --git a/cet/ibm1026.h b/cet/ibm1026.h new file mode 100644 index 000000000..18b86c1aa --- /dev/null +++ b/cet/ibm1026.h @@ -0,0 +1,380 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM1026" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm1026_h +#define ibm1026_h + +#define cet_cs_name_ibm1026 "IBM1026" + +const char *cet_cs_alias_ibm1026[] = +{ + "IBM1026", "1026", "CP1026", NULL +}; + +#define cet_ucs4_ofs_ibm1026 4 +#define cet_ucs4_cnt_ibm1026 252 + +const int cet_ucs4_map_ibm1026[cet_ucs4_cnt_ibm1026] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x007b, 0x00f1, 0x00c7, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x011e, 0x0130, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x005b, 0x00d1, 0x015f, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0131, 0x003a, 0x00d6, + 0x015e, 0x0027, 0x003d, 0x00dc, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x007d, 0x0060, 0x00a6, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x02db, 0x00c6, 0x00a4, 0x00b5, 0x00f6, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x005d, 0x0024, 0x0040, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x2014, 0x00a8, 0x00b4, 0x00d7, 0x00e7, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x007e, 0x00f2, 0x00f3, 0x00f5, 0x011f, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x005c, 0x00f9, 0x00fa, 0x00ff, 0x00fc, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x0023, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x0022, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm1026_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm1026_links[cet_ucs4_to_ibm1026_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0xfc} /* mark */, + {0x0023, 0xec} /* sign */, + {0x0024, 0xad} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0xae} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x68} /* square bracket */, + {0x005c, 0xdc} /* solidus */, + {0x005d, 0xac} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x8d} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x48} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x8c} /* curly bracket */, + {0x007e, 0xcc} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x8e} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x4a} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0x7b} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0x7f} /* capital letter u with diaeresis */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0xc0} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xa1} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xe0} /* small letter u with diaeresis */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x011e, 0x5a} /* capital letter g with breve */, + {0x011f, 0xd0} /* small letter g with breve */, + {0x0130, 0x5b} /* capital letter i with dot above */, + {0x0131, 0x79} /* small letter i dotless */, + {0x015e, 0x7c} /* capital letter s with cedilla */, + {0x015f, 0x6a} /* small letter s with cedilla */, + {0x02db, 0x9d} /* ogonek */, + {0x2014, 0xbc} /* dash */ +}; + +/* +#define cet_ucs4_to_ibm1026_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm1026_extra[cet_ucs4_to_ibm1026_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm1026 = /* defined in cet.h */ +{ + cet_cs_name_ibm1026, /* name of character set */ + cet_cs_alias_ibm1026, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm1026, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm1026, /* first non standard character */ + cet_ucs4_cnt_ibm1026, /* number of values in table */ + + cet_ucs4_to_ibm1026_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm1026_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm1026_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x007b, 0x00f1, 0x00c7, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x011e, 0x0130, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x005b, 0x00d1, 0x015f, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0131, 0x003a, 0x00d6, 0x015e, 0x0027, 0x003d, 0x00dc, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x007d, 0x0060, 0x00a6, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x02db, 0x00c6, 0x00a4, + 0x00b5, 0x00f6, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x005d, 0x0024, 0x0040, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x2014, 0x00a8, 0x00b4, 0x00d7, + 0x00e7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x007e, 0x00f2, 0x00f3, 0x00f5, + 0x011f, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x005c, 0x00f9, 0x00fa, 0x00ff, + 0x00fc, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x0023, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x0022, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm1047.h b/cet/ibm1047.h new file mode 100644 index 000000000..873d11d3c --- /dev/null +++ b/cet/ibm1047.h @@ -0,0 +1,380 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM1047" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm1047_h +#define ibm1047_h + +#define cet_cs_name_ibm1047 "IBM1047" + +const char *cet_cs_alias_ibm1047[] = +{ + "IBM1047", "1047", "CP1047", NULL +}; + +#define cet_ucs4_ofs_ibm1047 4 +#define cet_ucs4_cnt_ibm1047 252 + +const int cet_ucs4_map_ibm1047[cet_ucs4_cnt_ibm1047] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x00a2, 0x002e, + 0x003c, 0x0028, 0x002b, 0x007c, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x0021, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x007e, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x005b, 0x00de, 0x00ae, 0x00ac, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00dd, 0x00a8, + 0x00af, 0x005d, 0x00b4, 0x00d7, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm1047_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm1047_links[cet_ucs4_to_ibm1047_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x5a} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0xad} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0xbd} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0x4f} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xa1} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0x4a} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbb} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xb0} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00af, 0xbc} /* macron */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xba} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */ +}; + +/* +#define cet_ucs4_to_ibm1047_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm1047_extra[cet_ucs4_to_ibm1047_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm1047 = /* defined in cet.h */ +{ + cet_cs_name_ibm1047, /* name of character set */ + cet_cs_alias_ibm1047, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm1047, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm1047, /* first non standard character */ + cet_ucs4_cnt_ibm1047, /* number of values in table */ + + cet_ucs4_to_ibm1047_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm1047_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm1047_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x00a2, 0x002e, 0x003c, 0x0028, 0x002b, 0x007c, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x0021, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x007e, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x005b, 0x00de, 0x00ae, + 0x00ac, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00dd, 0x00a8, 0x00af, 0x005d, 0x00b4, 0x00d7, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm256.h b/cet/ibm256.h new file mode 100644 index 000000000..8603ab569 --- /dev/null +++ b/cet/ibm256.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM256" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm256_h +#define ibm256_h + +#define cet_cs_name_ibm256 "IBM256" + +const char *cet_cs_alias_ibm256[] = +{ + "IBM256", "256", "CP256", "EBCDIC-INT1", + NULL +}; + +#define cet_ucs4_ofs_ibm256 4 +#define cet_ucs4_cnt_ibm256 252 + +const int cet_ucs4_map_ibm256[cet_ucs4_cnt_ibm256] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x005b, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x005d, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x007e, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x20a7, + 0x0192, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x00a8, 0x00b4, 0x2017, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x2003, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm256_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm256_links[cet_ucs4_to_ibm256_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x4a} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0x5a} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xa1} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x0192, 0xb4} /* minuscule latine f hameçon */, + {0x2003, 0xe1} /* space */, + {0x2017, 0xbf} /* low line */, + {0x203e, 0xbc} /* overline */, + {0x20a7, 0xb3} /* sign */ +}; + +/* +#define cet_ucs4_to_ibm256_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm256_extra[cet_ucs4_to_ibm256_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm256 = /* defined in cet.h */ +{ + cet_cs_name_ibm256, /* name of character set */ + cet_cs_alias_ibm256, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm256, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm256, /* first non standard character */ + cet_ucs4_cnt_ibm256, /* number of values in table */ + + cet_ucs4_to_ibm256_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm256_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm256_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x005b, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x005d, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x007e, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x00a8, 0x00b4, 0x2017, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x2003, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm273.h b/cet/ibm273.h new file mode 100644 index 000000000..63fd4ddd8 --- /dev/null +++ b/cet/ibm273.h @@ -0,0 +1,380 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM273" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm273_h +#define ibm273_h + +#define cet_cs_name_ibm273 "IBM273" + +const char *cet_cs_alias_ibm273[] = +{ + "IBM273", "273", "CP273", NULL +}; + +#define cet_ucs4_ofs_ibm273 4 +#define cet_ucs4_cnt_ibm273 252 + +const int cet_ucs4_map_ibm273[cet_ucs4_cnt_ibm273] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x007b, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x00c4, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x007e, 0x00dc, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x005b, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00f6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x00a7, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x00df, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x0040, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x00a8, 0x00b4, 0x00d7, 0x00e4, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00a6, 0x00f2, 0x00f3, 0x00f5, 0x00fc, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x007d, 0x00f9, 0x00fa, 0x00ff, 0x00d6, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x005c, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x005d, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm273_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm273_links[cet_ucs4_to_ibm273_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0xb5} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x63} /* square bracket */, + {0x005c, 0xec} /* solidus */, + {0x005d, 0xfc} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x43} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0xdc} /* curly bracket */, + {0x007e, 0x59} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0xcc} /* bar */, + {0x00a7, 0x7c} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x4a} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xe0} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0x5a} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0xa1} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0xc0} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0x6a} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xd0} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm273_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm273_extra[cet_ucs4_to_ibm273_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm273 = /* defined in cet.h */ +{ + cet_cs_name_ibm273, /* name of character set */ + cet_cs_alias_ibm273, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm273, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm273, /* first non standard character */ + cet_ucs4_cnt_ibm273, /* number of values in table */ + + cet_ucs4_to_ibm273_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm273_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm273_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x007b, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x00c4, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x007e, 0x00dc, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x005b, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00f6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x00a7, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x00df, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x0040, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x00a8, 0x00b4, 0x00d7, + 0x00e4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00a6, 0x00f2, 0x00f3, 0x00f5, + 0x00fc, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x007d, 0x00f9, 0x00fa, 0x00ff, + 0x00d6, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x005c, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x005d, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm277.h b/cet/ibm277.h new file mode 100644 index 000000000..c1356e86f --- /dev/null +++ b/cet/ibm277.h @@ -0,0 +1,380 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM277" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm277_h +#define ibm277_h + +#define cet_cs_name_ibm277 "IBM277" + +const char *cet_cs_alias_ibm277[] = +{ + "IBM277", "EBCDIC-CP-DK", "EBCDIC-CP-NO", NULL +}; + +#define cet_ucs4_ofs_ibm277 4 +#define cet_ucs4_cnt_ibm277 252 + +const int cet_ucs4_map_ibm277[cet_ucs4_cnt_ibm277] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x007d, 0x00e7, 0x00f1, 0x0023, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x00a4, 0x00c5, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x0024, 0x00c7, 0x00d1, 0x00f8, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00a6, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x00c6, + 0x00d8, 0x0027, 0x003d, 0x0022, 0x0040, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x007b, 0x00b8, 0x005b, 0x005d, 0x00b5, 0x00fc, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x00a8, 0x00b4, 0x00d7, 0x00e6, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x00e5, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x007e, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm277_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm277_links[cet_ucs4_to_ibm277_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x4a} /* sign */, + {0x0024, 0x67} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x80} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x9e} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0x9f} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x9c} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x47} /* curly bracket */, + {0x007e, 0xdc} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x5a} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x70} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x5b} /* capital letter a with ring above */, + {0x00c6, 0x7b} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x7c} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0xd0} /* small letter a with ring above */, + {0x00e6, 0xc0} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x6a} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xa1} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm277_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm277_extra[cet_ucs4_to_ibm277_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm277 = /* defined in cet.h */ +{ + cet_cs_name_ibm277, /* name of character set */ + cet_cs_alias_ibm277, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm277, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm277, /* first non standard character */ + cet_ucs4_cnt_ibm277, /* number of values in table */ + + cet_ucs4_to_ibm277_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm277_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm277_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x007d, + 0x00e7, 0x00f1, 0x0023, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x00a4, 0x00c5, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x0024, + 0x00c7, 0x00d1, 0x00f8, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00a6, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x00c6, 0x00d8, 0x0027, 0x003d, 0x0022, + 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x007b, 0x00b8, 0x005b, 0x005d, + 0x00b5, 0x00fc, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x00a8, 0x00b4, 0x00d7, + 0x00e6, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x00e5, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x007e, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm278.h b/cet/ibm278.h new file mode 100644 index 000000000..c89719db6 --- /dev/null +++ b/cet/ibm278.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM278" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm278_h +#define ibm278_h + +#define cet_cs_name_ibm278 "IBM278" + +const char *cet_cs_alias_ibm278[] = +{ + "IBM278", "278", "CP278", "ebcdic-cp-fi", + "ebcdic-cp-se", NULL +}; + +#define cet_ucs4_ofs_ibm278 4 +#define cet_ucs4_cnt_ibm278 252 + +const int cet_ucs4_map_ibm278[cet_ucs4_cnt_ibm278] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x007b, + 0x00e0, 0x00e1, 0x00e3, 0x007d, 0x00e7, 0x00f1, 0x00a7, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x0060, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x00a4, 0x00c5, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x0023, + 0x00c0, 0x00c1, 0x00c3, 0x0024, 0x00c7, 0x00d1, 0x00f6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00e9, 0x003a, 0x00c4, + 0x00d6, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x005d, 0x00b5, 0x00fc, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x005b, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x00a8, 0x00b4, 0x00d7, 0x00e4, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00a6, 0x00f2, 0x00f3, 0x00f5, 0x00e5, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x007e, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x0040, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm278_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm278_links[cet_ucs4_to_ibm278_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x63} /* sign */, + {0x0024, 0x67} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0xec} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0xb5} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0x9f} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x51} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x43} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x47} /* curly bracket */, + {0x007e, 0xdc} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x5a} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0xcc} /* bar */, + {0x00a7, 0x4a} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x7b} /* capital letter a with diaeresis */, + {0x00c5, 0x5b} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0x7c} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0xc0} /* small letter a with diaeresis */, + {0x00e5, 0xd0} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x79} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0x6a} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xa1} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm278_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm278_extra[cet_ucs4_to_ibm278_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm278 = /* defined in cet.h */ +{ + cet_cs_name_ibm278, /* name of character set */ + cet_cs_alias_ibm278, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm278, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm278, /* first non standard character */ + cet_ucs4_cnt_ibm278, /* number of values in table */ + + cet_ucs4_to_ibm278_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm278_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm278_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x007b, 0x00e0, 0x00e1, 0x00e3, 0x007d, + 0x00e7, 0x00f1, 0x00a7, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x0060, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x00a4, 0x00c5, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x0023, 0x00c0, 0x00c1, 0x00c3, 0x0024, + 0x00c7, 0x00d1, 0x00f6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x00e9, 0x003a, 0x00c4, 0x00d6, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x005d, + 0x00b5, 0x00fc, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x005b, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x00a8, 0x00b4, 0x00d7, + 0x00e4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00a6, 0x00f2, 0x00f3, 0x00f5, + 0x00e5, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x007e, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x0040, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm280.h b/cet/ibm280.h new file mode 100644 index 000000000..da3e7e30d --- /dev/null +++ b/cet/ibm280.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM280" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm280_h +#define ibm280_h + +#define cet_cs_name_ibm280 "IBM280" + +const char *cet_cs_alias_ibm280[] = +{ + "IBM280", "280", "CP280", "ebcdic-cp-it", + NULL +}; + +#define cet_ucs4_ofs_ibm280 4 +#define cet_ucs4_cnt_ibm280 252 + +const int cet_ucs4_map_ibm280[cet_ucs4_cnt_ibm280] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x007b, 0x00e1, 0x00e3, 0x00e5, 0x005c, 0x00f1, 0x00b0, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x005d, 0x00ea, 0x00eb, + 0x007d, 0x00ed, 0x00ee, 0x00ef, 0x007e, 0x00df, 0x00e9, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00f2, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00f9, 0x003a, 0x00a3, + 0x00a7, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x005b, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x00ec, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x0023, 0x00a5, 0x00b7, + 0x00a9, 0x0040, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x00a8, 0x00b4, 0x00d7, 0x00e0, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00a6, 0x00f3, 0x00f5, 0x00e8, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x0060, 0x00fa, 0x00ff, 0x00e7, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm280_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm280_links[cet_ucs4_to_ibm280_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0xb1} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0xb5} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x90} /* square bracket */, + {0x005c, 0x48} /* solidus */, + {0x005d, 0x51} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0xdd} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x44} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x54} /* curly bracket */, + {0x007e, 0x58} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0x7b} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0xcd} /* bar */, + {0x00a7, 0x7c} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x4a} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0xc0} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0xe0} /* small letter c with cedilla */, + {0x00e8, 0xd0} /* small letter e with grave */, + {0x00e9, 0x5a} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0xa1} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0x6a} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0x79} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm280_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm280_extra[cet_ucs4_to_ibm280_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm280 = /* defined in cet.h */ +{ + cet_cs_name_ibm280, /* name of character set */ + cet_cs_alias_ibm280, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm280, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm280, /* first non standard character */ + cet_ucs4_cnt_ibm280, /* number of values in table */ + + cet_ucs4_to_ibm280_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm280_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm280_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x007b, 0x00e1, 0x00e3, 0x00e5, + 0x005c, 0x00f1, 0x00b0, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x005d, 0x00ea, 0x00eb, 0x007d, 0x00ed, 0x00ee, 0x00ef, + 0x007e, 0x00df, 0x00e9, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00f2, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x00f9, 0x003a, 0x00a3, 0x00a7, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x005b, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x00ec, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x0023, 0x00a5, 0x00b7, 0x00a9, 0x0040, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x00a8, 0x00b4, 0x00d7, + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00a6, 0x00f3, 0x00f5, + 0x00e8, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x0060, 0x00fa, 0x00ff, + 0x00e7, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm284.h b/cet/ibm284.h new file mode 100644 index 000000000..84e61712f --- /dev/null +++ b/cet/ibm284.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM284" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm284_h +#define ibm284_h + +#define cet_cs_name_ibm284 "IBM284" + +const char *cet_cs_alias_ibm284[] = +{ + "IBM284", "284", "CP284", "ebcdic-cp-es", + NULL +}; + +#define cet_ucs4_ofs_ibm284 4 +#define cet_ucs4_cnt_ibm284 252 + +const int cet_ucs4_map_ibm284[cet_ucs4_cnt_ibm284] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00a6, 0x005b, 0x002e, + 0x003c, 0x0028, 0x002b, 0x007c, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x005d, 0x0024, + 0x002a, 0x0029, 0x003b, 0x00ac, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x0023, 0x00f1, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x00d1, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x00a8, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x005e, 0x0021, + 0x203e, 0x007e, 0x00b4, 0x00d7, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm284_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm284_links[cet_ucs4_to_ibm284_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0xbb} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x69} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x4a} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0x5a} /* square bracket */, + {0x005e, 0xba} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0x4f} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xbd} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x49} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xa1} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0x5f} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x7b} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x6a} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm284_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm284_extra[cet_ucs4_to_ibm284_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm284 = /* defined in cet.h */ +{ + cet_cs_name_ibm284, /* name of character set */ + cet_cs_alias_ibm284, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm284, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm284, /* first non standard character */ + cet_ucs4_cnt_ibm284, /* number of values in table */ + + cet_ucs4_to_ibm284_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm284_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm284_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00a6, 0x005b, 0x002e, 0x003c, 0x0028, 0x002b, 0x007c, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x005d, 0x0024, 0x002a, 0x0029, 0x003b, 0x00ac, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x0023, 0x00f1, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x00d1, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x00a8, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x005e, 0x0021, 0x203e, 0x007e, 0x00b4, 0x00d7, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm285.h b/cet/ibm285.h new file mode 100644 index 000000000..9fbdd32bb --- /dev/null +++ b/cet/ibm285.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM285" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm285_h +#define ibm285_h + +#define cet_cs_name_ibm285 "IBM285" + +const char *cet_cs_alias_ibm285[] = +{ + "IBM285", "285", "CP285", "ebcdic-cp-gb", + NULL +}; + +#define cet_ucs4_ofs_ibm285 4 +#define cet_ucs4_cnt_ibm285 252 + +const int cet_ucs4_map_ibm285[cet_ucs4_cnt_ibm285] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x0024, 0x002e, + 0x003c, 0x0028, 0x002b, 0x007c, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x0021, 0x00a3, + 0x002a, 0x0029, 0x003b, 0x00ac, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x203e, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x005b, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x005e, 0x005d, + 0x007e, 0x00a8, 0x00b4, 0x00d7, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm285_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm285_links[cet_ucs4_to_ibm285_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x5a} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x4a} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0xb1} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0xbb} /* square bracket */, + {0x005e, 0xba} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0x4f} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xbc} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0x5b} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0x5f} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xa1} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm285_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm285_extra[cet_ucs4_to_ibm285_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm285 = /* defined in cet.h */ +{ + cet_cs_name_ibm285, /* name of character set */ + cet_cs_alias_ibm285, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm285, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm285, /* first non standard character */ + cet_ucs4_cnt_ibm285, /* number of values in table */ + + cet_ucs4_to_ibm285_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm285_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm285_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x0024, 0x002e, 0x003c, 0x0028, 0x002b, 0x007c, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x0021, 0x00a3, 0x002a, 0x0029, 0x003b, 0x00ac, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x203e, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x005b, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x005e, 0x005d, 0x007e, 0x00a8, 0x00b4, 0x00d7, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm297.h b/cet/ibm297.h new file mode 100644 index 000000000..9b327eee5 --- /dev/null +++ b/cet/ibm297.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM297" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm297_h +#define ibm297_h + +#define cet_cs_name_ibm297 "IBM297" + +const char *cet_cs_alias_ibm297[] = +{ + "IBM297", "297", "CP297", "ebcdic-cp-fr", + NULL +}; + +#define cet_ucs4_ofs_ibm297 4 +#define cet_ucs4_cnt_ibm297 252 + +const int cet_ucs4_map_ibm297[cet_ucs4_cnt_ibm297] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x0040, 0x00e1, 0x00e3, 0x00e5, 0x005c, 0x00f1, 0x00b0, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x007b, 0x00ea, 0x00eb, + 0x007d, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x00a7, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00f9, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00b5, 0x003a, 0x00a3, + 0x00e0, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x005b, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x0060, 0x00a8, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x0023, 0x00a5, 0x00b7, + 0x00a9, 0x005d, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x007e, 0x00b4, 0x00d7, 0x00e9, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x00e8, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00a6, 0x00fa, 0x00ff, 0x00e7, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm297_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm297_links[cet_ucs4_to_ibm297_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0xb1} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x44} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x90} /* square bracket */, + {0x005c, 0x48} /* solidus */, + {0x005d, 0xb5} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0xa0} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x51} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x54} /* curly bracket */, + {0x007e, 0xbd} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0x7b} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0xdd} /* bar */, + {0x00a7, 0x5a} /* sign */, + {0x00a8, 0xa1} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x4a} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0x79} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x7c} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0xe0} /* small letter c with cedilla */, + {0x00e8, 0xd0} /* small letter e with grave */, + {0x00e9, 0xc0} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0x6a} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm297_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm297_extra[cet_ucs4_to_ibm297_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm297 = /* defined in cet.h */ +{ + cet_cs_name_ibm297, /* name of character set */ + cet_cs_alias_ibm297, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm297, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm297, /* first non standard character */ + cet_ucs4_cnt_ibm297, /* number of values in table */ + + cet_ucs4_to_ibm297_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm297_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm297_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x0040, 0x00e1, 0x00e3, 0x00e5, + 0x005c, 0x00f1, 0x00b0, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x007b, 0x00ea, 0x00eb, 0x007d, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x00a7, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00f9, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x00b5, 0x003a, 0x00a3, 0x00e0, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x005b, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x0060, 0x00a8, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x0023, 0x00a5, 0x00b7, 0x00a9, 0x005d, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x007e, 0x00b4, 0x00d7, + 0x00e9, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x00e8, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00a6, 0x00fa, 0x00ff, + 0x00e7, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm437.h b/cet/ibm437.h new file mode 100644 index 000000000..7c0520ea8 --- /dev/null +++ b/cet/ibm437.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM437" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm437_h +#define ibm437_h + +#define cet_cs_name_ibm437 "IBM437" + +const char *cet_cs_alias_ibm437[] = +{ + "IBM437", "437", "CP437", NULL +}; + +#define cet_ucs4_ofs_ibm437 128 +#define cet_ucs4_cnt_ibm437 128 + +const int cet_ucs4_map_ibm437[cet_ucs4_cnt_ibm437] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm437_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm437_links[cet_ucs4_to_ibm437_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a5, 0x9d} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b5, 0xe6} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00ff, 0x98} /* small letter y with diaeresis */, + {0x0192, 0x9f} /* minuscule latine f hameçon */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x03c6, 0xed} /* small letter phi */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2310, 0xa9} /* not sign */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm437_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm437_extra[cet_ucs4_to_ibm437_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm437 = /* defined in cet.h */ +{ + cet_cs_name_ibm437, /* name of character set */ + cet_cs_alias_ibm437, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm437, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm437, /* first non standard character */ + cet_ucs4_cnt_ibm437, /* number of values in table */ + + cet_ucs4_to_ibm437_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm437_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm437_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm500.h b/cet/ibm500.h new file mode 100644 index 000000000..8d64499a0 --- /dev/null +++ b/cet/ibm500.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM500" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm500_h +#define ibm500_h + +#define cet_cs_name_ibm500 "IBM500" + +const char *cet_cs_alias_ibm500[] = +{ + "IBM500", "500", "500V1", "CP500", + "ebcdic-cp-be", "ebcdic-cp-ch", NULL +}; + +#define cet_ucs4_ofs_ibm500 4 +#define cet_ucs4_cnt_ibm500 252 + +const int cet_ucs4_map_ibm500[cet_ucs4_cnt_ibm500] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x005b, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x005d, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x007e, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x00af, 0x00a8, 0x00b4, 0x00d7, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm500_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm500_links[cet_ucs4_to_ibm500_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x4a} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0x5a} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xa1} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00af, 0xbc} /* macron */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */ +}; + +/* +#define cet_ucs4_to_ibm500_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm500_extra[cet_ucs4_to_ibm500_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm500 = /* defined in cet.h */ +{ + cet_cs_name_ibm500, /* name of character set */ + cet_cs_alias_ibm500, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm500, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm500, /* first non standard character */ + cet_ucs4_cnt_ibm500, /* number of values in table */ + + cet_ucs4_to_ibm500_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm500_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm500_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x005b, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x005d, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x007e, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x00af, 0x00a8, 0x00b4, 0x00d7, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm850.h b/cet/ibm850.h new file mode 100644 index 000000000..cb4e04ad5 --- /dev/null +++ b/cet/ibm850.h @@ -0,0 +1,257 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM850" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm850_h +#define ibm850_h + +#define cet_cs_name_ibm850 "IBM850" + +const char *cet_cs_alias_ibm850[] = +{ + "IBM850", "850", "CP850", "csPC850Multilingual", + NULL +}; + +#define cet_ucs4_ofs_ibm850 128 +#define cet_ucs4_cnt_ibm850 128 + +const int cet_ucs4_map_ibm850[cet_ucs4_cnt_ibm850] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, + 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, + 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm850_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm850_links[cet_ucs4_to_ibm850_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0xbd} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a4, 0xcf} /* sign */, + {0x00a5, 0xbe} /* sign */, + {0x00a6, 0xdd} /* bar */, + {0x00a7, 0xf5} /* sign */, + {0x00a8, 0xf9} /* diaeresis */, + {0x00a9, 0xb8} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00ad, 0xf0} /* hyphen */, + {0x00ae, 0xa9} /* sign */, + {0x00af, 0xee} /* macron */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b3, 0xfc} /* three */, + {0x00b4, 0xef} /* accent */, + {0x00b5, 0xe6} /* sign */, + {0x00b6, 0xf4} /* sign */, + {0x00b7, 0xfa} /* dot */, + {0x00b8, 0xf7} /* cedilla */, + {0x00b9, 0xfb} /* one */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00be, 0xf3} /* fraction three quarters */, + {0x00bf, 0xa8} /* question mark */, + {0x00c0, 0xb7} /* capital letter a with grave */, + {0x00c1, 0xb5} /* capital letter a with acute */, + {0x00c2, 0xb6} /* capital letter a with circumflex */, + {0x00c3, 0xc7} /* capital letter a with tilde */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c8, 0xd4} /* capital letter e with grave */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00ca, 0xd2} /* capital letter e with circumflex */, + {0x00cb, 0xd3} /* capital letter e with diaeresis */, + {0x00cc, 0xde} /* capital letter i with grave */, + {0x00cd, 0xd6} /* capital letter i with acute */, + {0x00ce, 0xd7} /* capital letter i with circumflex */, + {0x00cf, 0xd8} /* capital letter i with diaeresis */, + {0x00d0, 0xd1} /* capital letter eth (icelandic) */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d2, 0xe3} /* capital letter o with grave */, + {0x00d3, 0xe0} /* capital letter o with acute */, + {0x00d4, 0xe2} /* capital letter o with circumflex */, + {0x00d5, 0xe5} /* capital letter o with tilde */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d7, 0x9e} /* sign */, + {0x00d8, 0x9d} /* capital letter o with stroke */, + {0x00d9, 0xeb} /* capital letter u with grave */, + {0x00da, 0xe9} /* capital letter u with acute */, + {0x00db, 0xea} /* capital letter u with circumflex */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00dd, 0xed} /* capital letter y with acute */, + {0x00de, 0xe8} /* capital letter thorn (icelandic) */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e3, 0xc6} /* small letter a with tilde */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f0, 0xd0} /* small letter eth (icelandic) */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f5, 0xe4} /* small letter o with tilde */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f8, 0x9b} /* small letter o with stroke */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00fd, 0xec} /* small letter y with acute */, + {0x00fe, 0xe7} /* small letter thorn (icelandic) */, + {0x00ff, 0x98} /* small letter y with diaeresis */, + {0x0131, 0xd5} /* small letter i dotless */, + {0x0192, 0x9f} /* minuscule latine f hameçon */, + {0x2017, 0xf2} /* low line */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm850_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm850_extra[cet_ucs4_to_ibm850_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm850 = /* defined in cet.h */ +{ + cet_cs_name_ibm850, /* name of character set */ + cet_cs_alias_ibm850, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm850, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm850, /* first non standard character */ + cet_ucs4_cnt_ibm850, /* number of values in table */ + + cet_ucs4_to_ibm850_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm850_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm850_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, + 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, + 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm851.h b/cet/ibm851.h new file mode 100644 index 000000000..95bab532c --- /dev/null +++ b/cet/ibm851.h @@ -0,0 +1,255 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM851" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm851_h +#define ibm851_h + +#define cet_cs_name_ibm851 "IBM851" + +const char *cet_cs_alias_ibm851[] = +{ + "IBM851", "851", "CP851", NULL +}; + +#define cet_ucs4_ofs_ibm851 128 +#define cet_ucs4_cnt_ibm851 128 + +const int cet_ucs4_map_ibm851[cet_ucs4_cnt_ibm851] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x0386, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0388, 0x00c4, 0x0389, + 0x038a, -1, 0x038c, 0x00f4, 0x00f6, 0x038e, 0x00fb, 0x00f9, + 0x038f, 0x00d6, 0x00dc, 0x03ac, 0x00a3, 0x03ad, 0x03ae, 0x03af, + 0x03ca, 0x0390, 0x03cc, 0x03cd, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x00bd, 0x0398, 0x0399, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039a, 0x039b, 0x039d, + 0x039c, 0x2563, 0x2551, 0x2557, 0x255d, 0x039e, 0x039f, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x03a0, 0x03a1, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, + 0x03b3, 0x2518, 0x250c, 0x2588, 0x2584, 0x03b4, 0x03b5, 0x2580, + 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, + 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x00b4, + 0x00ad, 0x00b1, 0x03c5, 0x03c6, 0x03c7, 0x00a7, 0x03c8, 0x02db, + 0x00b0, 0x00a8, 0x03c9, 0x03cb, 0x03b0, 0x03ce, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm851_ct 127 + +const cet_ucs4_link_t cet_ucs4_to_ibm851_links[cet_ucs4_to_ibm851_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a3, 0x9c} /* sign */, + {0x00a7, 0xf5} /* sign */, + {0x00a8, 0xf9} /* diaeresis */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ad, 0xf0} /* hyphen */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b4, 0xef} /* accent */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bd, 0xab} /* fraction one half */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x02db, 0xf7} /* ogonek */, + {0x0386, 0x86} /* capital letter alpha with acute */, + {0x0388, 0x8d} /* capital letter epsilon with acute */, + {0x0389, 0x8f} /* capital letter eta with acute */, + {0x038a, 0x90} /* capital letter iota with acute */, + {0x038c, 0x92} /* capital letter omicron with acute */, + {0x038e, 0x95} /* capital letter upsilon with acute */, + {0x038f, 0x98} /* capital letter omega with acute */, + {0x0390, 0xa1} /* small letter iota with acute and diaeresis */, + {0x0391, 0xa4} /* capital letter alpha */, + {0x0392, 0xa5} /* capital letter beta */, + {0x0393, 0xa6} /* capital letter gamma */, + {0x0394, 0xa7} /* capital letter delta */, + {0x0395, 0xa8} /* capital letter epsilon */, + {0x0396, 0xa9} /* capital letter zeta */, + {0x0397, 0xaa} /* capital letter eta */, + {0x0398, 0xac} /* capital letter theta */, + {0x0399, 0xad} /* capital letter iota */, + {0x039a, 0xb5} /* capital letter kappa */, + {0x039b, 0xb6} /* capital letter lamda */, + {0x039c, 0xb8} /* capital letter mu */, + {0x039d, 0xb7} /* capital letter nu */, + {0x039e, 0xbd} /* capital letter xi */, + {0x039f, 0xbe} /* capital letter omicron */, + {0x03a0, 0xc6} /* capital letter pi */, + {0x03a1, 0xc7} /* capital letter rho */, + {0x03a3, 0xcf} /* capital letter sigma */, + {0x03a4, 0xd0} /* capital letter tau */, + {0x03a5, 0xd1} /* capital letter upsilon */, + {0x03a6, 0xd2} /* capital letter phi */, + {0x03a7, 0xd3} /* capital letter chi */, + {0x03a8, 0xd4} /* capital letter psi */, + {0x03a9, 0xd5} /* capital letter omega */, + {0x03ac, 0x9b} /* small letter alpha with acute */, + {0x03ad, 0x9d} /* small letter epsilon with acute */, + {0x03ae, 0x9e} /* small letter eta with acute */, + {0x03af, 0x9f} /* small letter iota with acute */, + {0x03b0, 0xfc} /* small letter upsilon with acute and diaeresis */, + {0x03b1, 0xd6} /* small letter alpha */, + {0x03b2, 0xd7} /* small letter beta */, + {0x03b3, 0xd8} /* small letter gamma */, + {0x03b4, 0xdd} /* small letter delta */, + {0x03b5, 0xde} /* small letter epsilon */, + {0x03b6, 0xe0} /* small letter zeta */, + {0x03b7, 0xe1} /* small letter eta */, + {0x03b8, 0xe2} /* small letter theta */, + {0x03b9, 0xe3} /* small letter iota */, + {0x03ba, 0xe4} /* small letter kappa */, + {0x03bb, 0xe5} /* small letter lamda */, + {0x03bc, 0xe6} /* small letter mu */, + {0x03bd, 0xe7} /* small letter nu */, + {0x03be, 0xe8} /* small letter xi */, + {0x03bf, 0xe9} /* small letter omicron */, + {0x03c0, 0xea} /* small letter pi */, + {0x03c1, 0xeb} /* small letter rho */, + {0x03c2, 0xed} /* small letter final sigma */, + {0x03c3, 0xec} /* small letter sigma */, + {0x03c4, 0xee} /* small letter tau */, + {0x03c5, 0xf2} /* small letter upsilon */, + {0x03c6, 0xf3} /* small letter phi */, + {0x03c7, 0xf4} /* small letter chi */, + {0x03c8, 0xf6} /* small letter psi */, + {0x03c9, 0xfa} /* small letter omega */, + {0x03ca, 0xa0} /* small letter iota with diaeresis */, + {0x03cb, 0xfb} /* small letter upsilon with diaeresis */, + {0x03cc, 0xa2} /* small letter omicron with acute */, + {0x03cd, 0xa3} /* small letter upsilon with acute */, + {0x03ce, 0xfd} /* small letter omega with acute */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm851_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm851_extra[cet_ucs4_to_ibm851_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm851 = /* defined in cet.h */ +{ + cet_cs_name_ibm851, /* name of character set */ + cet_cs_alias_ibm851, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm851, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm851, /* first non standard character */ + cet_ucs4_cnt_ibm851, /* number of values in table */ + + cet_ucs4_to_ibm851_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm851_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm851_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x0386, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0388, 0x00c4, 0x0389, + 0x038a, -1, 0x038c, 0x00f4, 0x00f6, 0x038e, 0x00fb, 0x00f9, + 0x038f, 0x00d6, 0x00dc, 0x03ac, 0x00a3, 0x03ad, 0x03ae, 0x03af, + 0x03ca, 0x0390, 0x03cc, 0x03cd, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x00bd, 0x0398, 0x0399, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039a, 0x039b, 0x039d, + 0x039c, 0x2563, 0x2551, 0x2557, 0x255d, 0x039e, 0x039f, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x03a0, 0x03a1, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, + 0x03b3, 0x2518, 0x250c, 0x2588, 0x2584, 0x03b4, 0x03b5, 0x2580, + 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, + 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x00b4, + 0x00ad, 0x00b1, 0x03c5, 0x03c6, 0x03c7, 0x00a7, 0x03c8, 0x02db, + 0x00b0, 0x00a8, 0x03c9, 0x03cb, 0x03b0, 0x03ce, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm852.h b/cet/ibm852.h new file mode 100644 index 000000000..8332c19c3 --- /dev/null +++ b/cet/ibm852.h @@ -0,0 +1,257 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM852" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm852_h +#define ibm852_h + +#define cet_cs_name_ibm852 "IBM852" + +const char *cet_cs_alias_ibm852[] = +{ + "IBM852", "852", "CP852", "pcl2", + "pclatin2", NULL +}; + +#define cet_ucs4_ofs_ibm852 128 +#define cet_ucs4_cnt_ibm852 128 + +const int cet_ucs4_map_ibm852[cet_ucs4_cnt_ibm852] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x016f, 0x0107, 0x00e7, + 0x0142, 0x00eb, 0x0150, 0x0151, 0x00ee, 0x0179, 0x00c4, 0x0106, + 0x00c9, 0x0139, 0x013a, 0x00f4, 0x00f6, 0x013d, 0x013e, 0x015a, + 0x015b, 0x00d6, 0x00dc, 0x0164, 0x0165, 0x0141, 0x00d7, 0x010d, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x0104, 0x0105, 0x017d, 0x017e, + 0x0118, 0x0119, 0x00ac, 0x017a, 0x010c, 0x015f, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x011a, + 0x015e, 0x2563, 0x2551, 0x2557, 0x255d, 0x017b, 0x017c, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x0102, 0x0103, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x0111, 0x0110, 0x010e, 0x00cb, 0x010f, 0x0147, 0x00cd, 0x00ce, + 0x011b, 0x2518, 0x250c, 0x2588, 0x2584, 0x0162, 0x016e, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, + 0x0154, 0x00da, 0x0155, 0x0170, 0x00fd, 0x00dd, 0x0163, 0x00b4, + 0x00ad, 0x02dd, 0x02db, 0x02c7, 0x02d8, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x02d9, 0x0171, 0x0158, 0x0159, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm852_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm852_links[cet_ucs4_to_ibm852_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a4, 0xcf} /* sign */, + {0x00a7, 0xf5} /* sign */, + {0x00a8, 0xf9} /* diaeresis */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00ad, 0xf0} /* hyphen */, + {0x00b0, 0xf8} /* sign */, + {0x00b4, 0xef} /* accent */, + {0x00b8, 0xf7} /* cedilla */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00c1, 0xb5} /* capital letter a with acute */, + {0x00c2, 0xb6} /* capital letter a with circumflex */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00cb, 0xd3} /* capital letter e with diaeresis */, + {0x00cd, 0xd6} /* capital letter i with acute */, + {0x00ce, 0xd7} /* capital letter i with circumflex */, + {0x00d3, 0xe0} /* capital letter o with acute */, + {0x00d4, 0xe2} /* capital letter o with circumflex */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d7, 0x9e} /* sign */, + {0x00da, 0xe9} /* capital letter u with acute */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00dd, 0xed} /* capital letter y with acute */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00fd, 0xec} /* small letter y with acute */, + {0x0102, 0xc6} /* capital letter a with breve */, + {0x0103, 0xc7} /* small letter a with breve */, + {0x0104, 0xa4} /* capital letter a with ogonek */, + {0x0105, 0xa5} /* small letter a with ogonek */, + {0x0106, 0x8f} /* capital letter c with acute */, + {0x0107, 0x86} /* small letter c with acute */, + {0x010c, 0xac} /* capital letter c with caron */, + {0x010d, 0x9f} /* small letter c with caron */, + {0x010e, 0xd2} /* capital letter d with caron */, + {0x010f, 0xd4} /* small letter d with caron */, + {0x0110, 0xd1} /* capital letter d with stroke */, + {0x0111, 0xd0} /* small letter d with stroke */, + {0x0118, 0xa8} /* capital letter e with ogonek */, + {0x0119, 0xa9} /* small letter e with ogonek */, + {0x011a, 0xb7} /* capital letter e with caron */, + {0x011b, 0xd8} /* small letter e with caron */, + {0x0139, 0x91} /* capital letter l with acute */, + {0x013a, 0x92} /* small letter l with acute */, + {0x013d, 0x95} /* capital letter l with caron */, + {0x013e, 0x96} /* small letter l with caron */, + {0x0141, 0x9d} /* capital letter l with stroke */, + {0x0142, 0x88} /* small letter l with stroke */, + {0x0143, 0xe3} /* capital letter n with acute */, + {0x0144, 0xe4} /* small letter n with acute */, + {0x0147, 0xd5} /* capital letter n with caron */, + {0x0148, 0xe5} /* small letter n with caron */, + {0x0150, 0x8a} /* capital letter o with double acute */, + {0x0151, 0x8b} /* small letter o with double acute */, + {0x0154, 0xe8} /* capital letter r with acute */, + {0x0155, 0xea} /* small letter r with acute */, + {0x0158, 0xfc} /* capital letter r with caron */, + {0x0159, 0xfd} /* small letter r with caron */, + {0x015a, 0x97} /* capital letter s with acute */, + {0x015b, 0x98} /* small letter s with acute */, + {0x015e, 0xb8} /* capital letter s with cedilla */, + {0x015f, 0xad} /* small letter s with cedilla */, + {0x0160, 0xe6} /* capital letter s with caron */, + {0x0161, 0xe7} /* small letter s with caron */, + {0x0162, 0xdd} /* capital letter t with cedilla */, + {0x0163, 0xee} /* small letter t with cedilla */, + {0x0164, 0x9b} /* capital letter t with caron */, + {0x0165, 0x9c} /* small letter t with caron */, + {0x016e, 0xde} /* capital letter u with ring above */, + {0x016f, 0x85} /* small letter u with ring above */, + {0x0170, 0xeb} /* capital letter u with double acute */, + {0x0171, 0xfb} /* small letter u with double acute */, + {0x0179, 0x8d} /* capital letter z with acute */, + {0x017a, 0xab} /* small letter z with acute */, + {0x017b, 0xbd} /* capital letter z with dot above */, + {0x017c, 0xbe} /* small letter z with dot above */, + {0x017d, 0xa6} /* capital letter z with caron */, + {0x017e, 0xa7} /* small letter z with caron */, + {0x02c7, 0xf3} /* caron */, + {0x02d8, 0xf4} /* breve */, + {0x02d9, 0xfa} /* above */, + {0x02db, 0xf2} /* ogonek */, + {0x02dd, 0xf1} /* acute accent */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm852_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm852_extra[cet_ucs4_to_ibm852_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm852 = /* defined in cet.h */ +{ + cet_cs_name_ibm852, /* name of character set */ + cet_cs_alias_ibm852, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm852, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm852, /* first non standard character */ + cet_ucs4_cnt_ibm852, /* number of values in table */ + + cet_ucs4_to_ibm852_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm852_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm852_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x016f, 0x0107, 0x00e7, + 0x0142, 0x00eb, 0x0150, 0x0151, 0x00ee, 0x0179, 0x00c4, 0x0106, + 0x00c9, 0x0139, 0x013a, 0x00f4, 0x00f6, 0x013d, 0x013e, 0x015a, + 0x015b, 0x00d6, 0x00dc, 0x0164, 0x0165, 0x0141, 0x00d7, 0x010d, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x0104, 0x0105, 0x017d, 0x017e, + 0x0118, 0x0119, 0x00ac, 0x017a, 0x010c, 0x015f, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x011a, + 0x015e, 0x2563, 0x2551, 0x2557, 0x255d, 0x017b, 0x017c, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x0102, 0x0103, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x0111, 0x0110, 0x010e, 0x00cb, 0x010f, 0x0147, 0x00cd, 0x00ce, + 0x011b, 0x2518, 0x250c, 0x2588, 0x2584, 0x0162, 0x016e, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, + 0x0154, 0x00da, 0x0155, 0x0170, 0x00fd, 0x00dd, 0x0163, 0x00b4, + 0x00ad, 0x02dd, 0x02db, 0x02c7, 0x02d8, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x02d9, 0x0171, 0x0158, 0x0159, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm855.h b/cet/ibm855.h new file mode 100644 index 000000000..4ed6603e8 --- /dev/null +++ b/cet/ibm855.h @@ -0,0 +1,255 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM855" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm855_h +#define ibm855_h + +#define cet_cs_name_ibm855 "IBM855" + +const char *cet_cs_alias_ibm855[] = +{ + "IBM855", "855", "CP855", NULL +}; + +#define cet_ucs4_ofs_ibm855 128 +#define cet_ucs4_cnt_ibm855 128 + +const int cet_ucs4_map_ibm855[cet_ucs4_cnt_ibm855] = +{ + 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, + 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, + 0x0459, 0x0409, 0x045a, 0x040a, 0x045b, 0x0093, 0x045c, 0x040c, + 0x045e, 0x040e, 0x045f, 0x040f, 0x044e, 0x042e, 0x044a, 0x042a, + 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, + 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, + 0x0418, 0x2563, 0x2551, 0x2557, 0x255d, 0x0439, 0x0419, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x043a, 0x041a, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x043b, 0x041b, 0x043c, 0x041c, 0x043d, 0x041d, 0x043e, 0x041e, + 0x043f, 0x2518, 0x250c, 0x2588, 0x2584, 0x041f, 0x044f, 0x2580, + 0x042f, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, + 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044c, 0x042c, 0x00b4, + 0x00ad, 0x044b, 0x042b, 0x0437, 0x0417, 0x0448, 0x0428, 0x044d, + 0x042d, 0x0449, 0x0429, 0x0447, 0x0427, -1, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm855_ct 127 + +const cet_ucs4_link_t cet_ucs4_to_ibm855_links[cet_ucs4_to_ibm855_ct] = +{ + {0x0093, 0x95} /* transmit state (sts) */, + {0x00a0, 0xff} /* space */, + {0x00a4, 0xcf} /* sign */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ad, 0xf0} /* hyphen */, + {0x00b4, 0xef} /* accent */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x0401, 0x85} /* capital letter io */, + {0x0402, 0x81} /* capital letter dje (serbocroatian) */, + {0x0403, 0x83} /* capital letter gje (macedonian) */, + {0x0404, 0x87} /* capital letter ukrainian ie */, + {0x0405, 0x89} /* capital letter dze (macedonian) */, + {0x0406, 0x8b} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0x8d} /* capital letter yi (ukrainian) */, + {0x0408, 0x8f} /* capital letter je */, + {0x0409, 0x91} /* capital letter lje */, + {0x040a, 0x93} /* capital letter nje */, + {0x040c, 0x97} /* capital letter kje (macedonian) */, + {0x040e, 0x99} /* capital letter short u (byelorussian) */, + {0x040f, 0x9b} /* capital letter dzhe */, + {0x0410, 0xa1} /* capital letter a */, + {0x0411, 0xa3} /* capital letter be */, + {0x0412, 0xec} /* capital letter ve */, + {0x0413, 0xad} /* capital letter ghe */, + {0x0414, 0xa7} /* capital letter de */, + {0x0415, 0xa9} /* capital letter ie */, + {0x0416, 0xea} /* capital letter zhe */, + {0x0417, 0xf4} /* capital letter ze */, + {0x0418, 0xb8} /* capital letter i */, + {0x0419, 0xbe} /* capital letter short i */, + {0x041a, 0xc7} /* capital letter ka */, + {0x041b, 0xd1} /* capital letter el */, + {0x041c, 0xd3} /* capital letter em */, + {0x041d, 0xd5} /* capital letter en */, + {0x041e, 0xd7} /* capital letter o */, + {0x041f, 0xdd} /* capital letter pe */, + {0x0420, 0xe2} /* capital letter er */, + {0x0421, 0xe4} /* capital letter es */, + {0x0422, 0xe6} /* capital letter te */, + {0x0423, 0xe8} /* capital letter u */, + {0x0424, 0xab} /* capital letter ef */, + {0x0425, 0xb6} /* capital letter ha */, + {0x0426, 0xa5} /* capital letter tse */, + {0x0427, 0xfc} /* capital letter che */, + {0x0428, 0xf6} /* capital letter sha */, + {0x0429, 0xfa} /* capital letter shcha */, + {0x042a, 0x9f} /* capital letter hard sign */, + {0x042b, 0xf2} /* capital letter yeru */, + {0x042c, 0xee} /* capital letter soft sign */, + {0x042d, 0xf8} /* capital letter e */, + {0x042e, 0x9d} /* capital letter yu */, + {0x042f, 0xe0} /* capital letter ya */, + {0x0430, 0xa0} /* small letter a */, + {0x0431, 0xa2} /* small letter be */, + {0x0432, 0xeb} /* small letter ve */, + {0x0433, 0xac} /* small letter ghe */, + {0x0434, 0xa6} /* small letter de */, + {0x0435, 0xa8} /* small letter ie */, + {0x0436, 0xe9} /* small letter zhe */, + {0x0437, 0xf3} /* small letter ze */, + {0x0438, 0xb7} /* small letter i */, + {0x0439, 0xbd} /* small letter short i */, + {0x043a, 0xc6} /* small letter ka */, + {0x043b, 0xd0} /* small letter el */, + {0x043c, 0xd2} /* small letter em */, + {0x043d, 0xd4} /* small letter en */, + {0x043e, 0xd6} /* small letter o */, + {0x043f, 0xd8} /* small letter pe */, + {0x0440, 0xe1} /* small letter er */, + {0x0441, 0xe3} /* small letter es */, + {0x0442, 0xe5} /* small letter te */, + {0x0443, 0xe7} /* small letter u */, + {0x0444, 0xaa} /* small letter ef */, + {0x0445, 0xb5} /* small letter ha */, + {0x0446, 0xa4} /* small letter tse */, + {0x0447, 0xfb} /* small letter che */, + {0x0448, 0xf5} /* small letter sha */, + {0x0449, 0xf9} /* small letter shcha */, + {0x044a, 0x9e} /* small letter hard sign */, + {0x044b, 0xf1} /* small letter yeru */, + {0x044c, 0xed} /* small letter soft sign */, + {0x044d, 0xf7} /* small letter e */, + {0x044e, 0x9c} /* small letter yu */, + {0x044f, 0xde} /* small letter ya */, + {0x0451, 0x84} /* small letter io */, + {0x0452, 0x80} /* small letter dje (serbocroatian) */, + {0x0453, 0x82} /* small letter gje (macedonian) */, + {0x0454, 0x86} /* small letter ukrainian ie */, + {0x0455, 0x88} /* small letter dze (macedonian) */, + {0x0456, 0x8a} /* small letter byelorussian-ukrainian i */, + {0x0457, 0x8c} /* small letter yi (ukrainian) */, + {0x0458, 0x8e} /* small letter je */, + {0x0459, 0x90} /* small letter lje */, + {0x045a, 0x92} /* small letter nje */, + {0x045b, 0x94} /* small letter tshe (serbocroatian) */, + {0x045c, 0x96} /* small letter kje (macedonian) */, + {0x045e, 0x98} /* small letter short u (byelorussian) */, + {0x045f, 0x9a} /* small letter dzhe */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm855_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm855_extra[cet_ucs4_to_ibm855_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm855 = /* defined in cet.h */ +{ + cet_cs_name_ibm855, /* name of character set */ + cet_cs_alias_ibm855, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm855, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm855, /* first non standard character */ + cet_ucs4_cnt_ibm855, /* number of values in table */ + + cet_ucs4_to_ibm855_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm855_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm855_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, + 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, + 0x0459, 0x0409, 0x045a, 0x040a, 0x045b, 0x0093, 0x045c, 0x040c, + 0x045e, 0x040e, 0x045f, 0x040f, 0x044e, 0x042e, 0x044a, 0x042a, + 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, + 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, + 0x0418, 0x2563, 0x2551, 0x2557, 0x255d, 0x0439, 0x0419, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x043a, 0x041a, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x043b, 0x041b, 0x043c, 0x041c, 0x043d, 0x041d, 0x043e, 0x041e, + 0x043f, 0x2518, 0x250c, 0x2588, 0x2584, 0x041f, 0x044f, 0x2580, + 0x042f, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, + 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044c, 0x042c, 0x00b4, + 0x00ad, 0x044b, 0x042b, 0x0437, 0x0417, 0x0448, 0x0428, 0x044d, + 0x042d, 0x0449, 0x0429, 0x0447, 0x0427, -1, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm857.h b/cet/ibm857.h new file mode 100644 index 000000000..4b26cdb28 --- /dev/null +++ b/cet/ibm857.h @@ -0,0 +1,252 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM857" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm857_h +#define ibm857_h + +#define cet_cs_name_ibm857 "IBM857" + +const char *cet_cs_alias_ibm857[] = +{ + "IBM857", "857", "CP857", NULL +}; + +#define cet_ucs4_ofs_ibm857 128 +#define cet_ucs4_cnt_ibm857 128 + +const int cet_ucs4_map_ibm857[cet_ucs4_cnt_ibm857] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0131, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x0130, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x015e, 0x015f, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x011e, 0x011f, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x00ba, 0x00aa, 0x00ca, 0x00cb, 0x00c8, -1, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, -1, + 0x00d7, 0x00da, 0x00db, 0x00d9, 0x00ec, 0x00ff, 0x2014, 0x00b4, + 0x00ad, 0x00b1, -1, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x02db, + 0x00b0, 0x00a8, 0x02d9, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm857_ct 124 + +const cet_ucs4_link_t cet_ucs4_to_ibm857_links[cet_ucs4_to_ibm857_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0xbd} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a4, 0xcf} /* sign */, + {0x00a5, 0xbe} /* sign */, + {0x00a6, 0xdd} /* bar */, + {0x00a7, 0xf5} /* sign */, + {0x00a8, 0xf9} /* diaeresis */, + {0x00a9, 0xb8} /* sign */, + {0x00aa, 0xd1} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00ad, 0xf0} /* hyphen */, + {0x00ae, 0xa9} /* sign */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b3, 0xfc} /* three */, + {0x00b4, 0xef} /* accent */, + {0x00b5, 0xe6} /* sign */, + {0x00b6, 0xf4} /* sign */, + {0x00b9, 0xfb} /* one */, + {0x00ba, 0xd0} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00be, 0xf3} /* fraction three quarters */, + {0x00bf, 0xa8} /* question mark */, + {0x00c0, 0xb7} /* capital letter a with grave */, + {0x00c1, 0xb5} /* capital letter a with acute */, + {0x00c2, 0xb6} /* capital letter a with circumflex */, + {0x00c3, 0xc7} /* capital letter a with tilde */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c8, 0xd4} /* capital letter e with grave */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00ca, 0xd2} /* capital letter e with circumflex */, + {0x00cb, 0xd3} /* capital letter e with diaeresis */, + {0x00cc, 0xde} /* capital letter i with grave */, + {0x00cd, 0xd6} /* capital letter i with acute */, + {0x00ce, 0xd7} /* capital letter i with circumflex */, + {0x00cf, 0xd8} /* capital letter i with diaeresis */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d2, 0xe3} /* capital letter o with grave */, + {0x00d3, 0xe0} /* capital letter o with acute */, + {0x00d4, 0xe2} /* capital letter o with circumflex */, + {0x00d5, 0xe5} /* capital letter o with tilde */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d7, 0xe8} /* sign */, + {0x00d8, 0x9d} /* capital letter o with stroke */, + {0x00d9, 0xeb} /* capital letter u with grave */, + {0x00da, 0xe9} /* capital letter u with acute */, + {0x00db, 0xea} /* capital letter u with circumflex */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e3, 0xc6} /* small letter a with tilde */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f5, 0xe4} /* small letter o with tilde */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f8, 0x9b} /* small letter o with stroke */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00ff, 0xed} /* small letter y with diaeresis */, + {0x011e, 0xa6} /* capital letter g with breve */, + {0x011f, 0xa7} /* small letter g with breve */, + {0x0130, 0x98} /* capital letter i with dot above */, + {0x0131, 0x8d} /* small letter i dotless */, + {0x015e, 0x9e} /* capital letter s with cedilla */, + {0x015f, 0x9f} /* small letter s with cedilla */, + {0x02d9, 0xfa} /* above */, + {0x02db, 0xf7} /* ogonek */, + {0x2014, 0xee} /* dash */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm857_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm857_extra[cet_ucs4_to_ibm857_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm857 = /* defined in cet.h */ +{ + cet_cs_name_ibm857, /* name of character set */ + cet_cs_alias_ibm857, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm857, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm857, /* first non standard character */ + cet_ucs4_cnt_ibm857, /* number of values in table */ + + cet_ucs4_to_ibm857_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm857_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm857_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0131, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x0130, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x015e, 0x015f, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x011e, 0x011f, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x00ba, 0x00aa, 0x00ca, 0x00cb, 0x00c8, -1, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, -1, + 0x00d7, 0x00da, 0x00db, 0x00d9, 0x00ec, 0x00ff, 0x2014, 0x00b4, + 0x00ad, 0x00b1, -1, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x02db, + 0x00b0, 0x00a8, 0x02d9, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm860.h b/cet/ibm860.h new file mode 100644 index 000000000..c2d2ced62 --- /dev/null +++ b/cet/ibm860.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM860" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm860_h +#define ibm860_h + +#define cet_cs_name_ibm860 "IBM860" + +const char *cet_cs_alias_ibm860[] = +{ + "IBM860", "860", "CP860", NULL +}; + +#define cet_ucs4_ofs_ibm860 128 +#define cet_ucs4_cnt_ibm860 128 + +const int cet_ucs4_map_ibm860[cet_ucs4_cnt_ibm860] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e3, 0x00e0, 0x00c1, 0x00e7, + 0x00ea, 0x00ca, 0x00e8, 0x00ce, 0x00d4, 0x00ec, 0x00c3, 0x00c2, + 0x00c9, 0x00c0, 0x00c8, 0x00f4, 0x00f5, 0x00f2, 0x00da, 0x00f9, + 0x00cc, 0x00d5, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00d3, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm860_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm860_links[cet_ucs4_to_ibm860_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b5, 0xe6} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c0, 0x91} /* capital letter a with grave */, + {0x00c1, 0x86} /* capital letter a with acute */, + {0x00c2, 0x8f} /* capital letter a with circumflex */, + {0x00c3, 0x8e} /* capital letter a with tilde */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c8, 0x92} /* capital letter e with grave */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00ca, 0x89} /* capital letter e with circumflex */, + {0x00cc, 0x98} /* capital letter i with grave */, + {0x00ce, 0x8b} /* capital letter i with circumflex */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d2, 0x9f} /* capital letter o with grave */, + {0x00d3, 0xa9} /* capital letter o with acute */, + {0x00d4, 0x8c} /* capital letter o with circumflex */, + {0x00d5, 0x99} /* capital letter o with tilde */, + {0x00d9, 0x9d} /* capital letter u with grave */, + {0x00da, 0x96} /* capital letter u with acute */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e3, 0x84} /* small letter a with tilde */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f5, 0x94} /* small letter o with tilde */, + {0x00f7, 0xf6} /* sign */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x03c6, 0xed} /* small letter phi */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm860_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm860_extra[cet_ucs4_to_ibm860_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm860 = /* defined in cet.h */ +{ + cet_cs_name_ibm860, /* name of character set */ + cet_cs_alias_ibm860, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm860, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm860, /* first non standard character */ + cet_ucs4_cnt_ibm860, /* number of values in table */ + + cet_ucs4_to_ibm860_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm860_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm860_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e3, 0x00e0, 0x00c1, 0x00e7, + 0x00ea, 0x00ca, 0x00e8, 0x00ce, 0x00d4, 0x00ec, 0x00c3, 0x00c2, + 0x00c9, 0x00c0, 0x00c8, 0x00f4, 0x00f5, 0x00f2, 0x00da, 0x00f9, + 0x00cc, 0x00d5, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00d3, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm861.h b/cet/ibm861.h new file mode 100644 index 000000000..cd8520f4e --- /dev/null +++ b/cet/ibm861.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM861" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm861_h +#define ibm861_h + +#define cet_cs_name_ibm861 "IBM861" + +const char *cet_cs_alias_ibm861[] = +{ + "IBM861", "861", "CP861", "cp-is", + NULL +}; + +#define cet_ucs4_ofs_ibm861 128 +#define cet_ucs4_cnt_ibm861 128 + +const int cet_ucs4_map_ibm861[cet_ucs4_cnt_ibm861] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00d0, 0x00f0, 0x00de, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00fe, 0x00fb, 0x00dd, + 0x00fd, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00c1, 0x00cd, 0x00d3, 0x00da, + 0x00bf, -1, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm861_ct 127 + +const cet_ucs4_link_t cet_ucs4_to_ibm861_links[cet_ucs4_to_ibm861_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a3, 0x9c} /* sign */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b5, 0xe6} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c1, 0xa4} /* capital letter a with acute */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00cd, 0xa5} /* capital letter i with acute */, + {0x00d0, 0x8b} /* capital letter eth (icelandic) */, + {0x00d2, 0x9f} /* capital letter o with grave */, + {0x00d3, 0xa6} /* capital letter o with acute */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d8, 0x9d} /* capital letter o with stroke */, + {0x00da, 0xa7} /* capital letter u with acute */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00dd, 0x97} /* capital letter y with acute */, + {0x00de, 0x8d} /* capital letter thorn (icelandic) */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f8, 0x9b} /* small letter o with stroke */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00fd, 0x98} /* small letter y with acute */, + {0x00fe, 0x95} /* small letter thorn (icelandic) */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x03c6, 0xed} /* small letter phi */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm861_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm861_extra[cet_ucs4_to_ibm861_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm861 = /* defined in cet.h */ +{ + cet_cs_name_ibm861, /* name of character set */ + cet_cs_alias_ibm861, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm861, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm861, /* first non standard character */ + cet_ucs4_cnt_ibm861, /* number of values in table */ + + cet_ucs4_to_ibm861_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm861_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm861_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00d0, 0x00f0, 0x00de, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00fe, 0x00fb, 0x00dd, + 0x00fd, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00c1, 0x00cd, 0x00d3, 0x00da, + 0x00bf, -1, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm862.h b/cet/ibm862.h new file mode 100644 index 000000000..f7a559f65 --- /dev/null +++ b/cet/ibm862.h @@ -0,0 +1,255 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM862" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm862_h +#define ibm862_h + +#define cet_cs_name_ibm862 "IBM862" + +const char *cet_cs_alias_ibm862[] = +{ + "IBM862", "862", "CP862", NULL +}; + +#define cet_ucs4_ofs_ibm862 128 +#define cet_ucs4_cnt_ibm862 128 + +const int cet_ucs4_map_ibm862[cet_ucs4_cnt_ibm862] = +{ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0x00a2, 0x00a3, 0x00d9, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, -1, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm862_ct 127 + +const cet_ucs4_link_t cet_ucs4_to_ibm862_links[cet_ucs4_to_ibm862_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b5, 0xe6} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d2, 0x9f} /* capital letter o with grave */, + {0x00d9, 0x9d} /* capital letter u with grave */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f7, 0xf6} /* sign */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x03c6, 0xed} /* small letter phi */, + {0x05d0, 0x80} /* letter alef */, + {0x05d1, 0x81} /* letter bet */, + {0x05d2, 0x82} /* letter gimel */, + {0x05d3, 0x83} /* letter dalet */, + {0x05d4, 0x84} /* letter he */, + {0x05d5, 0x85} /* letter vav */, + {0x05d6, 0x86} /* letter zayin */, + {0x05d7, 0x87} /* letter het */, + {0x05d8, 0x88} /* letter tet */, + {0x05d9, 0x89} /* letter yod */, + {0x05da, 0x8a} /* letter final kaf */, + {0x05db, 0x8b} /* letter kaf */, + {0x05dc, 0x8c} /* letter lamed */, + {0x05dd, 0x8d} /* letter final mem */, + {0x05de, 0x8e} /* letter mem */, + {0x05df, 0x8f} /* letter final nun */, + {0x05e0, 0x90} /* letter nun */, + {0x05e1, 0x91} /* letter samekh */, + {0x05e2, 0x92} /* letter ayin */, + {0x05e3, 0x93} /* letter final pe */, + {0x05e4, 0x94} /* letter pe */, + {0x05e5, 0x95} /* letter final tsadi */, + {0x05e6, 0x96} /* letter tsadi */, + {0x05e7, 0x97} /* letter qof */, + {0x05e8, 0x98} /* letter resh */, + {0x05e9, 0x99} /* letter shin */, + {0x05ea, 0x9a} /* letter tav */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm862_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm862_extra[cet_ucs4_to_ibm862_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm862 = /* defined in cet.h */ +{ + cet_cs_name_ibm862, /* name of character set */ + cet_cs_alias_ibm862, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm862, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm862, /* first non standard character */ + cet_ucs4_cnt_ibm862, /* number of values in table */ + + cet_ucs4_to_ibm862_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm862_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm862_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0x00a2, 0x00a3, 0x00d9, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, -1, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm863.h b/cet/ibm863.h new file mode 100644 index 000000000..97909f6db --- /dev/null +++ b/cet/ibm863.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM863" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm863_h +#define ibm863_h + +#define cet_cs_name_ibm863 "IBM863" + +const char *cet_cs_alias_ibm863[] = +{ + "IBM863", "863", "CP863", NULL +}; + +#define cet_ucs4_ofs_ibm863 128 +#define cet_ucs4_cnt_ibm863 128 + +const int cet_ucs4_map_ibm863[cet_ucs4_cnt_ibm863] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00c2, 0x00e0, 0x00b6, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c0, 0x00a7, + 0x00c9, 0x00c8, 0x00ca, 0x00f4, 0x00cb, 0x00cf, 0x00fb, 0x00f9, + 0x00a4, 0x00d4, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x00db, 0x0192, + 0x00a6, 0x00b4, 0x00f3, 0x00fa, 0x00a8, 0x00b8, 0x00b3, 0x00af, + 0x00ce, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00be, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm863_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm863_links[cet_ucs4_to_ibm863_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a4, 0x98} /* sign */, + {0x00a6, 0xa0} /* bar */, + {0x00a7, 0x8f} /* sign */, + {0x00a8, 0xa4} /* diaeresis */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00af, 0xa7} /* macron */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b3, 0xa6} /* three */, + {0x00b4, 0xa1} /* accent */, + {0x00b5, 0xe6} /* sign */, + {0x00b6, 0x86} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00b8, 0xa5} /* cedilla */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00be, 0xad} /* fraction three quarters */, + {0x00c0, 0x8e} /* capital letter a with grave */, + {0x00c2, 0x84} /* capital letter a with circumflex */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c8, 0x91} /* capital letter e with grave */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00ca, 0x92} /* capital letter e with circumflex */, + {0x00cb, 0x94} /* capital letter e with diaeresis */, + {0x00ce, 0xa8} /* capital letter i with circumflex */, + {0x00cf, 0x95} /* capital letter i with diaeresis */, + {0x00d4, 0x99} /* capital letter o with circumflex */, + {0x00d9, 0x9d} /* capital letter u with grave */, + {0x00db, 0x9e} /* capital letter u with circumflex */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f7, 0xf6} /* sign */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x0192, 0x9f} /* minuscule latine f hameçon */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x2205, 0xed} /* set */, + {0x2218, 0xf8} /* operator */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2310, 0xa9} /* not sign */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm863_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm863_extra[cet_ucs4_to_ibm863_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm863 = /* defined in cet.h */ +{ + cet_cs_name_ibm863, /* name of character set */ + cet_cs_alias_ibm863, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm863, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm863, /* first non standard character */ + cet_ucs4_cnt_ibm863, /* number of values in table */ + + cet_ucs4_to_ibm863_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm863_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm863_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00c2, 0x00e0, 0x00b6, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c0, 0x00a7, + 0x00c9, 0x00c8, 0x00ca, 0x00f4, 0x00cb, 0x00cf, 0x00fb, 0x00f9, + 0x00a4, 0x00d4, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x00db, 0x0192, + 0x00a6, 0x00b4, 0x00f3, 0x00fa, 0x00a8, 0x00b8, 0x00b3, 0x00af, + 0x00ce, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00be, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm864.h b/cet/ibm864.h new file mode 100644 index 000000000..5dfac836f --- /dev/null +++ b/cet/ibm864.h @@ -0,0 +1,249 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM864" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm864_h +#define ibm864_h + +#define cet_cs_name_ibm864 "IBM864" + +const char *cet_cs_alias_ibm864[] = +{ + "IBM864", "864", "CP864", NULL +}; + +#define cet_ucs4_ofs_ibm864 128 +#define cet_ucs4_cnt_ibm864 128 + +const int cet_ucs4_map_ibm864[cet_ucs4_cnt_ibm864] = +{ + 0x00b0, 0x00b7, 0x2218, 0x221a, 0x2592, 0x2500, 0x2502, 0x253c, + 0x2524, 0x252c, 0x251c, 0x2534, 0x2510, 0x250c, 0x2514, 0x2518, + 0x00df, 0x221e, 0x00f8, 0x00b1, 0x00bd, 0x00bc, 0x2248, 0x00ab, + 0x00bb, 0xfef7, 0xfef8, -1, -1, 0xfefb, 0xfefc, 0xe016, + -1, 0x00ad, 0xfe82, 0x00a3, 0x00a4, 0xfe84, -1, -1, + 0xfe8e, 0x0628, 0x062a, 0x062b, 0x060c, 0x062c, 0x062d, 0x062e, + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0x06a4, 0x061b, 0x0633, 0x0634, 0x0635, 0x061f, + 0x00a2, 0x0621, 0x0622, 0x0623, 0x0624, 0xfeca, 0x0626, 0x0627, + 0xfe91, 0x0629, 0xfe97, 0xfe9b, 0xfe9f, 0xfea3, 0xfea7, 0x062f, + 0x0630, 0x0631, 0x0632, 0xfeb3, 0xfeb7, 0xfebb, 0xfebf, 0x0637, + 0x0638, 0xfecb, 0xfecf, 0x00a6, 0x00ac, 0x00f7, 0x00d7, 0x0639, + 0x0640, 0xfed2, 0xfed6, 0xfedb, 0xfede, 0xfee3, 0xfee6, 0xfeeb, + 0x0648, 0x0649, 0xfef3, 0x0636, 0xfee2, 0xfece, 0x063a, 0x0645, + 0xfe7d, 0x0651, 0x0646, 0x0647, 0xfeec, 0xfef0, 0xfef2, 0x0641, + 0x0642, 0xfef5, 0xfef6, 0x0644, 0x0643, 0x064a, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm864_ct 121 + +const cet_ucs4_link_t cet_ucs4_to_ibm864_links[cet_ucs4_to_ibm864_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a2, 0xc0} /* sign */, + {0x00a6, 0xdb} /* bar */, + {0x00ab, 0x97} /* double angle quotation mark */, + {0x00ac, 0xdc} /* sign */, + {0x00ad, 0xa1} /* hyphen */, + {0x00b0, 0x80} /* sign */, + {0x00b1, 0x93} /* sign */, + {0x00b7, 0x81} /* dot */, + {0x00bb, 0x98} /* double angle quotation mark */, + {0x00bc, 0x95} /* fraction one quarter */, + {0x00bd, 0x94} /* fraction one half */, + {0x00d7, 0xde} /* sign */, + {0x00df, 0x90} /* small letter sharp s (german) */, + {0x00f7, 0xdd} /* sign */, + {0x00f8, 0x92} /* small letter o with stroke */, + {0x060c, 0xac} /* comma */, + {0x061b, 0xbb} /* semicolon */, + {0x061f, 0xbf} /* question mark */, + {0x0621, 0xc1} /* letter hamza */, + {0x0622, 0xc2} /* letter alef with madda above */, + {0x0623, 0xc3} /* letter alef with hamza above */, + {0x0624, 0xc4} /* letter waw with hamza above */, + {0x0626, 0xc6} /* letter yeh with hamza above */, + {0x0627, 0xc7} /* letter alef */, + {0x0628, 0xa9} /* letter beh */, + {0x0629, 0xc9} /* letter teh marbuta */, + {0x062a, 0xaa} /* letter teh */, + {0x062b, 0xab} /* letter theh */, + {0x062c, 0xad} /* letter jeem */, + {0x062d, 0xae} /* letter hah */, + {0x062e, 0xaf} /* letter khah */, + {0x062f, 0xcf} /* letter dal */, + {0x0630, 0xd0} /* letter thal */, + {0x0631, 0xd1} /* letter reh */, + {0x0632, 0xd2} /* letter zain */, + {0x0633, 0xbc} /* letter seen */, + {0x0634, 0xbd} /* letter sheen */, + {0x0635, 0xbe} /* letter sad */, + {0x0636, 0xeb} /* letter dad */, + {0x0637, 0xd7} /* letter tah */, + {0x0638, 0xd8} /* letter zah */, + {0x0639, 0xdf} /* letter ain */, + {0x063a, 0xee} /* letter ghain */, + {0x0640, 0xe0} /* tatweel */, + {0x0641, 0xf7} /* letter feh */, + {0x0642, 0xf8} /* letter qaf */, + {0x0643, 0xfc} /* letter kaf */, + {0x0644, 0xfb} /* letter lam */, + {0x0645, 0xef} /* letter meem */, + {0x0646, 0xf2} /* letter noon */, + {0x0647, 0xf3} /* letter heh */, + {0x0648, 0xe8} /* letter waw */, + {0x0649, 0xe9} /* letter alef maksura */, + {0x064a, 0xfd} /* letter yeh */, + {0x0651, 0xf1} /* shadda */, + {0x0660, 0xb0} /* arabic-indic digit zero */, + {0x0661, 0xb1} /* arabic-indic digit one */, + {0x0662, 0xb2} /* arabic-indic digit two */, + {0x0663, 0xb3} /* arabic-indic digit three */, + {0x0664, 0xb4} /* arabic-indic digit four */, + {0x0665, 0xb5} /* arabic-indic digit five */, + {0x0666, 0xb6} /* arabic-indic digit six */, + {0x0667, 0xb7} /* arabic-indic digit seven */, + {0x0668, 0xb8} /* arabic-indic digit eight */, + {0x0669, 0xb9} /* arabic-indic digit nine */, + {0x06a4, 0xba} /* letter veh */, + {0x2218, 0x82} /* operator */, + {0x221a, 0x83} /* root */, + {0x221e, 0x91} /* infinity */, + {0x2248, 0x96} /* equal to */, + {0x2500, 0x85} /* drawings light horizontal */, + {0x2502, 0x86} /* drawings light vertical */, + {0x250c, 0x8d} /* drawings light down and right */, + {0x2510, 0x8c} /* drawings light down and left */, + {0x2514, 0x8e} /* drawings light up and right */, + {0x2518, 0x8f} /* drawings light up and left */, + {0x251c, 0x8a} /* drawings light vertical and right */, + {0x2524, 0x88} /* drawings light vertical and left */, + {0x252c, 0x89} /* drawings light down and horizontal */, + {0x2534, 0x8b} /* drawings light up and horizontal */, + {0x253c, 0x87} /* drawings light vertical and horizontal */, + {0x2592, 0x84} /* shade */, + {0x25a0, 0xfe} /* square */, + {0xe016, 0x9f} /* letter alef final form compatibility (ibm868 144) */, + {0xfe7d, 0xf0} /* shadda medial form */, + {0xfe82, 0xa2} /* letter alef with madda above final form */, + {0xfe84, 0xa5} /* letter alef with hamza above final form */, + {0xfe8e, 0xa8} /* letter alef final form */, + {0xfe91, 0xc8} /* letter beh initial form */, + {0xfe97, 0xca} /* letter teh initial form */, + {0xfe9b, 0xcb} /* letter theh initial form */, + {0xfe9f, 0xcc} /* letter jeem initial form */, + {0xfea3, 0xcd} /* letter hah initial form */, + {0xfea7, 0xce} /* letter khah initial form */, + {0xfeb3, 0xd3} /* letter seen initial form */, + {0xfeb7, 0xd4} /* letter sheen initial form */, + {0xfebb, 0xd5} /* letter sad initial form */, + {0xfebf, 0xd6} /* letter dad initial form */, + {0xfeca, 0xc5} /* letter ain final form */, + {0xfecb, 0xd9} /* letter ain initial form */, + {0xfece, 0xed} /* letter ghain final form */, + {0xfecf, 0xda} /* letter ghain initial form */, + {0xfed2, 0xe1} /* letter feh final form */, + {0xfed6, 0xe2} /* letter qaf final form */, + {0xfedb, 0xe3} /* letter kaf initial form */, + {0xfede, 0xe4} /* letter lam final form */, + {0xfee2, 0xec} /* letter meem final form */, + {0xfee3, 0xe5} /* letter meem initial form */, + {0xfee6, 0xe6} /* letter noon final form */, + {0xfeeb, 0xe7} /* letter heh initial form */, + {0xfeec, 0xf4} /* letter heh medial form */, + {0xfef0, 0xf5} /* letter alef maksura final form */, + {0xfef2, 0xf6} /* letter yeh final form */, + {0xfef3, 0xea} /* letter yeh initial form */, + {0xfef5, 0xf9} /* ligature lam with alef with madda above */, + {0xfef6, 0xfa} /* ligature lam with alef with madda above */, + {0xfef7, 0x99} /* ligature lam with alef with hamza above */, + {0xfef8, 0x9a} /* ligature lam with alef with hamza above */, + {0xfefb, 0x9d} /* ligature lam with alef isolated form */, + {0xfefc, 0x9e} /* ligature lam with alef final form */ +}; + +/* +#define cet_ucs4_to_ibm864_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm864_extra[cet_ucs4_to_ibm864_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm864 = /* defined in cet.h */ +{ + cet_cs_name_ibm864, /* name of character set */ + cet_cs_alias_ibm864, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm864, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm864, /* first non standard character */ + cet_ucs4_cnt_ibm864, /* number of values in table */ + + cet_ucs4_to_ibm864_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm864_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm864_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00b0, 0x00b7, 0x2218, 0x221a, 0x2592, 0x2500, 0x2502, 0x253c, + 0x2524, 0x252c, 0x251c, 0x2534, 0x2510, 0x250c, 0x2514, 0x2518, + 0x00df, 0x221e, 0x00f8, 0x00b1, 0x00bd, 0x00bc, 0x2248, 0x00ab, + 0x00bb, 0xfef7, 0xfef8, -1, -1, 0xfefb, 0xfefc, 0xe016, + -1, 0x00ad, 0xfe82, 0x00a3, 0x00a4, 0xfe84, -1, -1, + 0xfe8e, 0x0628, 0x062a, 0x062b, 0x060c, 0x062c, 0x062d, 0x062e, + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0x06a4, 0x061b, 0x0633, 0x0634, 0x0635, 0x061f, + 0x00a2, 0x0621, 0x0622, 0x0623, 0x0624, 0xfeca, 0x0626, 0x0627, + 0xfe91, 0x0629, 0xfe97, 0xfe9b, 0xfe9f, 0xfea3, 0xfea7, 0x062f, + 0x0630, 0x0631, 0x0632, 0xfeb3, 0xfeb7, 0xfebb, 0xfebf, 0x0637, + 0x0638, 0xfecb, 0xfecf, 0x00a6, 0x00ac, 0x00f7, 0x00d7, 0x0639, + 0x0640, 0xfed2, 0xfed6, 0xfedb, 0xfede, 0xfee3, 0xfee6, 0xfeeb, + 0x0648, 0x0649, 0xfef3, 0x0636, 0xfee2, 0xfece, 0x063a, 0x0645, + 0xfe7d, 0x0651, 0x0646, 0x0647, 0xfeec, 0xfef0, 0xfef2, 0x0641, + 0x0642, 0xfef5, 0xfef6, 0x0644, 0x0643, 0x064a, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm865.h b/cet/ibm865.h new file mode 100644 index 000000000..2cde68dd8 --- /dev/null +++ b/cet/ibm865.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM865" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm865_h +#define ibm865_h + +#define cet_cs_name_ibm865 "IBM865" + +const char *cet_cs_alias_ibm865[] = +{ + "IBM865", "865", "CP865", NULL +}; + +#define cet_ucs4_ofs_ibm865 128 +#define cet_ucs4_cnt_ibm865 128 + +const int cet_ucs4_map_ibm865[cet_ucs4_cnt_ibm865] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm865_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm865_links[cet_ucs4_to_ibm865_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a3, 0x9c} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b5, 0xe6} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d8, 0x9d} /* capital letter o with stroke */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f8, 0x9b} /* small letter o with stroke */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00ff, 0x98} /* small letter y with diaeresis */, + {0x0192, 0x9f} /* minuscule latine f hameçon */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x2205, 0xed} /* set */, + {0x2218, 0xf8} /* operator */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2310, 0xa9} /* not sign */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm865_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm865_extra[cet_ucs4_to_ibm865_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm865 = /* defined in cet.h */ +{ + cet_cs_name_ibm865, /* name of character set */ + cet_cs_alias_ibm865, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm865, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm865, /* first non standard character */ + cet_ucs4_cnt_ibm865, /* number of values in table */ + + cet_ucs4_to_ibm865_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm865_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm865_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm868.h b/cet/ibm868.h new file mode 100644 index 000000000..1c278ef62 --- /dev/null +++ b/cet/ibm868.h @@ -0,0 +1,232 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM868" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm868_h +#define ibm868_h + +#define cet_cs_name_ibm868 "IBM868" + +const char *cet_cs_alias_ibm868[] = +{ + "IBM868", "868", "CP868", "cp-ar", + NULL +}; + +#define cet_ucs4_ofs_ibm868 128 +#define cet_ucs4_cnt_ibm868 128 + +const int cet_ucs4_map_ibm868[cet_ucs4_cnt_ibm868] = +{ + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0x060c, 0x061b, 0x061f, 0x0622, 0x0627, 0xfe8e, + 0xe016, 0x0628, 0xfe91, 0x067e, -1, 0x0629, 0x062a, 0xfe97, + -1, -1, 0x062b, 0xfe9b, 0x062c, 0xfe9f, -1, -1, + 0x062d, 0xfea3, 0x062e, 0xfea7, 0x062f, -1, 0x0630, 0x0631, + -1, 0x0632, -1, 0x0633, 0xfeb3, 0x0634, 0x00ab, 0x00bb, + 0xfeb7, 0x0635, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0xfebb, + 0x0636, 0xfebf, 0x0637, 0x2563, 0x2551, 0x2557, 0x255d, 0x0638, + 0x0639, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, + 0xfeca, 0xfecb, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, + 0x256c, 0xfecc, 0x063a, 0xfece, 0xfecf, 0xfed0, 0x0641, 0xfed3, + 0x0642, 0xfed7, 0xfeda, 0x2518, 0x250c, 0x2588, 0x2580, 0xfedb, + -1, 0x2584, -1, 0x0644, 0xfede, 0xfee0, 0x0645, 0xfee3, + -1, 0x0646, 0xfee7, -1, 0x0648, -1, -1, -1, + -1, 0x0621, 0x00ad, -1, -1, -1, -1, -1, + -1, -1, -1, 0x0651, 0xfe7d, -1, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm868_ct 103 + +const cet_ucs4_link_t cet_ucs4_to_ibm868_links[cet_ucs4_to_ibm868_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ad, 0xf2} /* hyphen */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x060c, 0x8a} /* comma */, + {0x061b, 0x8b} /* semicolon */, + {0x061f, 0x8c} /* question mark */, + {0x0621, 0xf1} /* letter hamza */, + {0x0622, 0x8d} /* letter alef with madda above */, + {0x0627, 0x8e} /* letter alef */, + {0x0628, 0x91} /* letter beh */, + {0x0629, 0x95} /* letter teh marbuta */, + {0x062a, 0x96} /* letter teh */, + {0x062b, 0x9a} /* letter theh */, + {0x062c, 0x9c} /* letter jeem */, + {0x062d, 0xa0} /* letter hah */, + {0x062e, 0xa2} /* letter khah */, + {0x062f, 0xa4} /* letter dal */, + {0x0630, 0xa6} /* letter thal */, + {0x0631, 0xa7} /* letter reh */, + {0x0632, 0xa9} /* letter zain */, + {0x0633, 0xab} /* letter seen */, + {0x0634, 0xad} /* letter sheen */, + {0x0635, 0xb1} /* letter sad */, + {0x0636, 0xb8} /* letter dad */, + {0x0637, 0xba} /* letter tah */, + {0x0638, 0xbf} /* letter zah */, + {0x0639, 0xc0} /* letter ain */, + {0x063a, 0xd2} /* letter ghain */, + {0x0641, 0xd6} /* letter feh */, + {0x0642, 0xd8} /* letter qaf */, + {0x0644, 0xe3} /* letter lam */, + {0x0645, 0xe6} /* letter meem */, + {0x0646, 0xe9} /* letter noon */, + {0x0648, 0xec} /* letter waw */, + {0x0651, 0xfb} /* shadda */, + {0x0660, 0x80} /* arabic-indic digit zero */, + {0x0661, 0x81} /* arabic-indic digit one */, + {0x0662, 0x82} /* arabic-indic digit two */, + {0x0663, 0x83} /* arabic-indic digit three */, + {0x0664, 0x84} /* arabic-indic digit four */, + {0x0665, 0x85} /* arabic-indic digit five */, + {0x0666, 0x86} /* arabic-indic digit six */, + {0x0667, 0x87} /* arabic-indic digit seven */, + {0x0668, 0x88} /* arabic-indic digit eight */, + {0x0669, 0x89} /* arabic-indic digit nine */, + {0x067e, 0x93} /* letter peh */, + {0x2500, 0xc6} /* drawings light horizontal */, + {0x2502, 0xb5} /* drawings light vertical */, + {0x250c, 0xdc} /* drawings light down and right */, + {0x2510, 0xc1} /* drawings light down and left */, + {0x2514, 0xc2} /* drawings light up and right */, + {0x2518, 0xdb} /* drawings light up and left */, + {0x251c, 0xc5} /* drawings light vertical and right */, + {0x2524, 0xb6} /* drawings light vertical and left */, + {0x252c, 0xc4} /* drawings light down and horizontal */, + {0x2534, 0xc3} /* drawings light up and horizontal */, + {0x253c, 0xc7} /* drawings light vertical and horizontal */, + {0x2550, 0xcf} /* drawings heavy horizontal */, + {0x2551, 0xbc} /* drawings heavy vertical */, + {0x2554, 0xcb} /* drawings heavy down and right */, + {0x2557, 0xbd} /* drawings heavy down and left */, + {0x255a, 0xca} /* drawings heavy up and right */, + {0x255d, 0xbe} /* drawings heavy up and left */, + {0x2560, 0xce} /* drawings heavy vertical and right */, + {0x2563, 0xbb} /* drawings heavy vertical and left */, + {0x2566, 0xcd} /* drawings heavy down and horizontal */, + {0x2569, 0xcc} /* drawings heavy up and horizontal */, + {0x256c, 0xd0} /* drawings heavy vertical and horizontal */, + {0x2580, 0xde} /* half block */, + {0x2584, 0xe1} /* half block */, + {0x2588, 0xdd} /* block */, + {0x2591, 0xb2} /* shade */, + {0x2592, 0xb3} /* shade */, + {0x2593, 0xb4} /* shade */, + {0x25a0, 0xfe} /* square */, + {0xe016, 0x90} /* letter alef final form compatibility (ibm868 144) */, + {0xfe7d, 0xfc} /* shadda medial form */, + {0xfe8e, 0x8f} /* letter alef final form */, + {0xfe91, 0x92} /* letter beh initial form */, + {0xfe97, 0x97} /* letter teh initial form */, + {0xfe9b, 0x9b} /* letter theh initial form */, + {0xfe9f, 0x9d} /* letter jeem initial form */, + {0xfea3, 0xa1} /* letter hah initial form */, + {0xfea7, 0xa3} /* letter khah initial form */, + {0xfeb3, 0xac} /* letter seen initial form */, + {0xfeb7, 0xb0} /* letter sheen initial form */, + {0xfebb, 0xb7} /* letter sad initial form */, + {0xfebf, 0xb9} /* letter dad initial form */, + {0xfeca, 0xc8} /* letter ain final form */, + {0xfecb, 0xc9} /* letter ain initial form */, + {0xfecc, 0xd1} /* letter ain medial form */, + {0xfece, 0xd3} /* letter ghain final form */, + {0xfecf, 0xd4} /* letter ghain initial form */, + {0xfed0, 0xd5} /* letter ghain medial form */, + {0xfed3, 0xd7} /* letter feh initial form */, + {0xfed7, 0xd9} /* letter qaf initial form */, + {0xfeda, 0xda} /* letter kaf final form */, + {0xfedb, 0xdf} /* letter kaf initial form */, + {0xfede, 0xe4} /* letter lam final form */, + {0xfee0, 0xe5} /* letter lam medial form */, + {0xfee3, 0xe7} /* letter meem initial form */, + {0xfee7, 0xea} /* letter noon initial form */ +}; + +/* +#define cet_ucs4_to_ibm868_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm868_extra[cet_ucs4_to_ibm868_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm868 = /* defined in cet.h */ +{ + cet_cs_name_ibm868, /* name of character set */ + cet_cs_alias_ibm868, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm868, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm868, /* first non standard character */ + cet_ucs4_cnt_ibm868, /* number of values in table */ + + cet_ucs4_to_ibm868_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm868_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm868_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0x060c, 0x061b, 0x061f, 0x0622, 0x0627, 0xfe8e, + 0xe016, 0x0628, 0xfe91, 0x067e, -1, 0x0629, 0x062a, 0xfe97, + -1, -1, 0x062b, 0xfe9b, 0x062c, 0xfe9f, -1, -1, + 0x062d, 0xfea3, 0x062e, 0xfea7, 0x062f, -1, 0x0630, 0x0631, + -1, 0x0632, -1, 0x0633, 0xfeb3, 0x0634, 0x00ab, 0x00bb, + 0xfeb7, 0x0635, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0xfebb, + 0x0636, 0xfebf, 0x0637, 0x2563, 0x2551, 0x2557, 0x255d, 0x0638, + 0x0639, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, + 0xfeca, 0xfecb, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, + 0x256c, 0xfecc, 0x063a, 0xfece, 0xfecf, 0xfed0, 0x0641, 0xfed3, + 0x0642, 0xfed7, 0xfeda, 0x2518, 0x250c, 0x2588, 0x2580, 0xfedb, + -1, 0x2584, -1, 0x0644, 0xfede, 0xfee0, 0x0645, 0xfee3, + -1, 0x0646, 0xfee7, -1, 0x0648, -1, -1, -1, + -1, 0x0621, 0x00ad, -1, -1, -1, -1, -1, + -1, -1, -1, 0x0651, 0xfe7d, -1, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm869.h b/cet/ibm869.h new file mode 100644 index 000000000..57f2d9e0f --- /dev/null +++ b/cet/ibm869.h @@ -0,0 +1,248 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM869" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm869_h +#define ibm869_h + +#define cet_cs_name_ibm869 "IBM869" + +const char *cet_cs_alias_ibm869[] = +{ + "IBM869", "869", "CP869", "cp-gr", + NULL +}; + +#define cet_ucs4_ofs_ibm869 128 +#define cet_ucs4_cnt_ibm869 128 + +const int cet_ucs4_map_ibm869[cet_ucs4_cnt_ibm869] = +{ + -1, -1, -1, -1, -1, -1, 0x0386, -1, + 0x00b7, 0x00ac, 0x00a6, 0x201b, 0x2019, 0x0388, 0x2014, 0x0389, + 0x038a, 0x03aa, 0x038c, -1, -1, 0x038e, 0x03ab, 0x00a9, + 0x038f, 0x00b2, 0x00b3, 0x03ac, 0x00a3, 0x03ad, 0x03ae, 0x03af, + 0x03ca, 0x0390, 0x03cc, 0x03cd, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x00bd, 0x0398, 0x0399, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039a, 0x039b, 0x039c, + 0x039d, 0x2563, 0x2551, 0x2557, 0x255d, 0x039e, 0x039f, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x03a0, 0x03a1, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, + 0x03b3, 0x2518, 0x250c, 0x2588, 0x2584, 0x03b4, 0x03b5, 0x2580, + 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, + 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x00b4, + 0x00ad, 0x00b1, 0x03c5, 0x03c6, 0x03c7, 0x00a7, 0x03c8, 0x0385, + 0x00b0, 0x00a8, 0x03c9, 0x03cb, 0x03b0, 0x03ce, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm869_ct 119 + +const cet_ucs4_link_t cet_ucs4_to_ibm869_links[cet_ucs4_to_ibm869_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a3, 0x9c} /* sign */, + {0x00a6, 0x8a} /* bar */, + {0x00a7, 0xf5} /* sign */, + {0x00a8, 0xf9} /* diaeresis */, + {0x00a9, 0x97} /* sign */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0x89} /* sign */, + {0x00ad, 0xf0} /* hyphen */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0x99} /* two */, + {0x00b3, 0x9a} /* three */, + {0x00b4, 0xef} /* accent */, + {0x00b7, 0x88} /* dot */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bd, 0xab} /* fraction one half */, + {0x0385, 0xf7} /* accent and diaeresis (tonos and dialytika) */, + {0x0386, 0x86} /* capital letter alpha with acute */, + {0x0388, 0x8d} /* capital letter epsilon with acute */, + {0x0389, 0x8f} /* capital letter eta with acute */, + {0x038a, 0x90} /* capital letter iota with acute */, + {0x038c, 0x92} /* capital letter omicron with acute */, + {0x038e, 0x95} /* capital letter upsilon with acute */, + {0x038f, 0x98} /* capital letter omega with acute */, + {0x0390, 0xa1} /* small letter iota with acute and diaeresis */, + {0x0391, 0xa4} /* capital letter alpha */, + {0x0392, 0xa5} /* capital letter beta */, + {0x0393, 0xa6} /* capital letter gamma */, + {0x0394, 0xa7} /* capital letter delta */, + {0x0395, 0xa8} /* capital letter epsilon */, + {0x0396, 0xa9} /* capital letter zeta */, + {0x0397, 0xaa} /* capital letter eta */, + {0x0398, 0xac} /* capital letter theta */, + {0x0399, 0xad} /* capital letter iota */, + {0x039a, 0xb5} /* capital letter kappa */, + {0x039b, 0xb6} /* capital letter lamda */, + {0x039c, 0xb7} /* capital letter mu */, + {0x039d, 0xb8} /* capital letter nu */, + {0x039e, 0xbd} /* capital letter xi */, + {0x039f, 0xbe} /* capital letter omicron */, + {0x03a0, 0xc6} /* capital letter pi */, + {0x03a1, 0xc7} /* capital letter rho */, + {0x03a3, 0xcf} /* capital letter sigma */, + {0x03a4, 0xd0} /* capital letter tau */, + {0x03a5, 0xd1} /* capital letter upsilon */, + {0x03a6, 0xd2} /* capital letter phi */, + {0x03a7, 0xd3} /* capital letter chi */, + {0x03a8, 0xd4} /* capital letter psi */, + {0x03a9, 0xd5} /* capital letter omega */, + {0x03aa, 0x91} /* capital letter iota with diaeresis */, + {0x03ab, 0x96} /* capital letter upsilon with diaeresis */, + {0x03ac, 0x9b} /* small letter alpha with acute */, + {0x03ad, 0x9d} /* small letter epsilon with acute */, + {0x03ae, 0x9e} /* small letter eta with acute */, + {0x03af, 0x9f} /* small letter iota with acute */, + {0x03b0, 0xfc} /* small letter upsilon with acute and diaeresis */, + {0x03b1, 0xd6} /* small letter alpha */, + {0x03b2, 0xd7} /* small letter beta */, + {0x03b3, 0xd8} /* small letter gamma */, + {0x03b4, 0xdd} /* small letter delta */, + {0x03b5, 0xde} /* small letter epsilon */, + {0x03b6, 0xe0} /* small letter zeta */, + {0x03b7, 0xe1} /* small letter eta */, + {0x03b8, 0xe2} /* small letter theta */, + {0x03b9, 0xe3} /* small letter iota */, + {0x03ba, 0xe4} /* small letter kappa */, + {0x03bb, 0xe5} /* small letter lamda */, + {0x03bc, 0xe6} /* small letter mu */, + {0x03bd, 0xe7} /* small letter nu */, + {0x03be, 0xe8} /* small letter xi */, + {0x03bf, 0xe9} /* small letter omicron */, + {0x03c0, 0xea} /* small letter pi */, + {0x03c1, 0xeb} /* small letter rho */, + {0x03c2, 0xed} /* small letter final sigma */, + {0x03c3, 0xec} /* small letter sigma */, + {0x03c4, 0xee} /* small letter tau */, + {0x03c5, 0xf2} /* small letter upsilon */, + {0x03c6, 0xf3} /* small letter phi */, + {0x03c7, 0xf4} /* small letter chi */, + {0x03c8, 0xf6} /* small letter psi */, + {0x03c9, 0xfa} /* small letter omega */, + {0x03ca, 0xa0} /* small letter iota with diaeresis */, + {0x03cb, 0xfb} /* small letter upsilon with diaeresis */, + {0x03cc, 0xa2} /* small letter omicron with acute */, + {0x03cd, 0xa3} /* small letter upsilon with acute */, + {0x03ce, 0xfd} /* small letter omega with acute */, + {0x2014, 0x8e} /* dash */, + {0x2019, 0x8c} /* single quotation mark */, + {0x201b, 0x8b} /* high-reversed-9 quotation mark */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm869_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm869_extra[cet_ucs4_to_ibm869_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm869 = /* defined in cet.h */ +{ + cet_cs_name_ibm869, /* name of character set */ + cet_cs_alias_ibm869, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm869, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm869, /* first non standard character */ + cet_ucs4_cnt_ibm869, /* number of values in table */ + + cet_ucs4_to_ibm869_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm869_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm869_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, 0x0386, -1, + 0x00b7, 0x00ac, 0x00a6, 0x201b, 0x2019, 0x0388, 0x2014, 0x0389, + 0x038a, 0x03aa, 0x038c, -1, -1, 0x038e, 0x03ab, 0x00a9, + 0x038f, 0x00b2, 0x00b3, 0x03ac, 0x00a3, 0x03ad, 0x03ae, 0x03af, + 0x03ca, 0x0390, 0x03cc, 0x03cd, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x00bd, 0x0398, 0x0399, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039a, 0x039b, 0x039c, + 0x039d, 0x2563, 0x2551, 0x2557, 0x255d, 0x039e, 0x039f, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x03a0, 0x03a1, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, + 0x03b3, 0x2518, 0x250c, 0x2588, 0x2584, 0x03b4, 0x03b5, 0x2580, + 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, + 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x00b4, + 0x00ad, 0x00b1, 0x03c5, 0x03c6, 0x03c7, 0x00a7, 0x03c8, 0x0385, + 0x00b0, 0x00a8, 0x03c9, 0x03cb, 0x03b0, 0x03ce, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm871.h b/cet/ibm871.h new file mode 100644 index 000000000..1fddaca3b --- /dev/null +++ b/cet/ibm871.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM871" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm871_h +#define ibm871_h + +#define cet_cs_name_ibm871 "IBM871" + +const char *cet_cs_alias_ibm871[] = +{ + "IBM871", "871", "CP871", "ebcdic-cp-is", + NULL +}; + +#define cet_ucs4_ofs_ibm871 4 +#define cet_ucs4_cnt_ibm871 252 + +const int cet_ucs4_map_ibm871[cet_ucs4_cnt_ibm871] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x00fe, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x00c6, 0x0024, + 0x002a, 0x0029, 0x003b, 0x00d6, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00f0, 0x003a, 0x0023, + 0x00d0, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x0060, 0x00fd, 0x007b, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x007d, 0x00b8, 0x005d, 0x00a4, 0x00b5, 0x00f6, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x0040, 0x00dd, 0x005b, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x00af, 0x00a8, 0x005c, 0x00d7, 0x00de, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x007e, 0x00f2, 0x00f3, 0x00f5, 0x00e6, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x00b4, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x005e, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm871_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm871_links[cet_ucs4_to_ibm871_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0xac} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0xae} /* square bracket */, + {0x005c, 0xbe} /* solidus */, + {0x005d, 0x9e} /* square bracket */, + {0x005e, 0xec} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x8c} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x8e} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x9c} /* curly bracket */, + {0x007e, 0xcc} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00af, 0xbc} /* macron */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xe0} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x5a} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0x7c} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0x5f} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xc0} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0xd0} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x79} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xa1} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x4a} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */ +}; + +/* +#define cet_ucs4_to_ibm871_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm871_extra[cet_ucs4_to_ibm871_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm871 = /* defined in cet.h */ +{ + cet_cs_name_ibm871, /* name of character set */ + cet_cs_alias_ibm871, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm871, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm871, /* first non standard character */ + cet_ucs4_cnt_ibm871, /* number of values in table */ + + cet_ucs4_to_ibm871_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm871_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm871_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x00fe, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x00c6, 0x0024, 0x002a, 0x0029, 0x003b, 0x00d6, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x00f0, 0x003a, 0x0023, 0x00d0, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x0060, 0x00fd, 0x007b, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x007d, 0x00b8, 0x005d, 0x00a4, + 0x00b5, 0x00f6, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x0040, 0x00dd, 0x005b, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x00af, 0x00a8, 0x005c, 0x00d7, + 0x00de, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x007e, 0x00f2, 0x00f3, 0x00f5, + 0x00e6, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x00b4, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x005e, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm891.h b/cet/ibm891.h new file mode 100644 index 000000000..2d0f3a6ab --- /dev/null +++ b/cet/ibm891.h @@ -0,0 +1,108 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM891" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm891_h +#define ibm891_h + +#define cet_cs_name_ibm891 "IBM891" + +const char *cet_cs_alias_ibm891[] = +{ + "IBM891", "891", "CP891", NULL +}; + +#define cet_ucs4_ofs_ibm891 128 +#define cet_ucs4_cnt_ibm891 1 + +const int cet_ucs4_map_ibm891[cet_ucs4_cnt_ibm891]; + +#define cet_ucs4_to_ibm891_ct 1 + +const cet_ucs4_link_t cet_ucs4_to_ibm891_links[cet_ucs4_to_ibm891_ct]; + +/* +#define cet_ucs4_to_ibm891_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm891_extra[cet_ucs4_to_ibm891_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm891 = /* defined in cet.h */ +{ + cet_cs_name_ibm891, /* name of character set */ + cet_cs_alias_ibm891, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm891, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm891, /* first non standard character */ + cet_ucs4_cnt_ibm891, /* number of values in table */ + + cet_ucs4_to_ibm891_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm891_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm891_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ibm903.h b/cet/ibm903.h new file mode 100644 index 000000000..b9a4d6c19 --- /dev/null +++ b/cet/ibm903.h @@ -0,0 +1,108 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM903" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm903_h +#define ibm903_h + +#define cet_cs_name_ibm903 "IBM903" + +const char *cet_cs_alias_ibm903[] = +{ + "IBM903", "903", "CP903", NULL +}; + +#define cet_ucs4_ofs_ibm903 128 +#define cet_ucs4_cnt_ibm903 1 + +const int cet_ucs4_map_ibm903[cet_ucs4_cnt_ibm903]; + +#define cet_ucs4_to_ibm903_ct 1 + +const cet_ucs4_link_t cet_ucs4_to_ibm903_links[cet_ucs4_to_ibm903_ct]; + +/* +#define cet_ucs4_to_ibm903_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm903_extra[cet_ucs4_to_ibm903_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm903 = /* defined in cet.h */ +{ + cet_cs_name_ibm903, /* name of character set */ + cet_cs_alias_ibm903, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm903, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm903, /* first non standard character */ + cet_ucs4_cnt_ibm903, /* number of values in table */ + + cet_ucs4_to_ibm903_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm903_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm903_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ibm904.h b/cet/ibm904.h new file mode 100644 index 000000000..78f489c8b --- /dev/null +++ b/cet/ibm904.h @@ -0,0 +1,131 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM904" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm904_h +#define ibm904_h + +#define cet_cs_name_ibm904 "IBM904" + +const char *cet_cs_alias_ibm904[] = +{ + "IBM904", "904", "CP904", NULL +}; + +#define cet_ucs4_ofs_ibm904 128 +#define cet_ucs4_cnt_ibm904 127 + +const int cet_ucs4_map_ibm904[cet_ucs4_cnt_ibm904] = +{ + 0x00a2, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0x00ac, 0x00a6 +}; + +#define cet_ucs4_to_ibm904_ct 3 + +const cet_ucs4_link_t cet_ucs4_to_ibm904_links[cet_ucs4_to_ibm904_ct] = +{ + {0x00a2, 0x80} /* sign */, + {0x00a6, 0xfe} /* bar */, + {0x00ac, 0xfd} /* sign */ +}; + +/* +#define cet_ucs4_to_ibm904_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm904_extra[cet_ucs4_to_ibm904_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm904 = /* defined in cet.h */ +{ + cet_cs_name_ibm904, /* name of character set */ + cet_cs_alias_ibm904, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm904, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm904, /* first non standard character */ + cet_ucs4_cnt_ibm904, /* number of values in table */ + + cet_ucs4_to_ibm904_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm904_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm904_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00a2, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0x00ac, 0x00a6, -1 +}; +*/ + +#endif diff --git a/cet/iec_p27_1.h b/cet/iec_p27_1.h new file mode 100644 index 000000000..44ba106bc --- /dev/null +++ b/cet/iec_p27_1.h @@ -0,0 +1,220 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IEC_P27-1" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iec_p27_1_h +#define iec_p27_1_h + +#define cet_cs_name_iec_p27_1 "IEC_P27-1" + +const char *cet_cs_alias_iec_p27_1[] = +{ + "IEC_P27-1", "iso-ir-143", NULL +}; + +#define cet_ucs4_ofs_iec_p27_1 160 +#define cet_ucs4_cnt_iec_p27_1 96 + +const int cet_ucs4_map_iec_p27_1[cet_ucs4_cnt_iec_p27_1] = +{ + 0x02c7, 0x2261, 0x2227, 0x2228, 0x2229, 0x222a, 0x2282, 0x2283, + 0x21d0, 0x21d2, 0x2234, 0x2235, 0x2208, 0x220b, 0x2286, 0x2287, + 0x222b, 0x222e, 0x221e, 0x2207, 0x2202, 0x223c, 0x2248, 0x2243, + 0x2245, 0x2264, 0x2260, 0x2265, 0x2194, 0x00ac, 0x2200, 0x2203, + 0x05d0, 0x25a1, 0x2225, 0x0393, 0x0394, 0x22a5, 0x2220, 0x221f, + 0x0398, 0x2329, 0x232a, 0x039b, 0x2032, 0x2033, 0x039e, 0x2213, + 0x03a0, 0x00b2, 0x03a3, 0x00d7, 0x00b3, 0x03a5, 0x03a6, 0x00b7, + 0x03a8, 0x03a9, 0x2205, 0x21c0, 0x221a, 0x0192, 0x221d, 0x00b1, + 0x00b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x2030, + 0x03c0, 0x03c1, 0x03c3, 0x00f7, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x2020, 0x2190, 0x2191, 0x2192, 0x2193, 0x203e +}; + +#define cet_ucs4_to_iec_p27_1_ct 96 + +const cet_ucs4_link_t cet_ucs4_to_iec_p27_1_links[cet_ucs4_to_iec_p27_1_ct] = +{ + {0x00ac, 0xbd} /* sign */, + {0x00b0, 0xe0} /* sign */, + {0x00b1, 0xdf} /* sign */, + {0x00b2, 0xd1} /* two */, + {0x00b3, 0xd4} /* three */, + {0x00b7, 0xd7} /* dot */, + {0x00d7, 0xd3} /* sign */, + {0x00f7, 0xf3} /* sign */, + {0x0192, 0xdd} /* minuscule latine f hameçon */, + {0x02c7, 0xa0} /* caron */, + {0x0393, 0xc3} /* capital letter gamma */, + {0x0394, 0xc4} /* capital letter delta */, + {0x0398, 0xc8} /* capital letter theta */, + {0x039b, 0xcb} /* capital letter lamda */, + {0x039e, 0xce} /* capital letter xi */, + {0x03a0, 0xd0} /* capital letter pi */, + {0x03a3, 0xd2} /* capital letter sigma */, + {0x03a5, 0xd5} /* capital letter upsilon */, + {0x03a6, 0xd6} /* capital letter phi */, + {0x03a8, 0xd8} /* capital letter psi */, + {0x03a9, 0xd9} /* capital letter omega */, + {0x03b1, 0xe1} /* small letter alpha */, + {0x03b2, 0xe2} /* small letter beta */, + {0x03b3, 0xe3} /* small letter gamma */, + {0x03b4, 0xe4} /* small letter delta */, + {0x03b5, 0xe5} /* small letter epsilon */, + {0x03b6, 0xe6} /* small letter zeta */, + {0x03b7, 0xe7} /* small letter eta */, + {0x03b8, 0xe8} /* small letter theta */, + {0x03b9, 0xe9} /* small letter iota */, + {0x03ba, 0xea} /* small letter kappa */, + {0x03bb, 0xeb} /* small letter lamda */, + {0x03bc, 0xec} /* small letter mu */, + {0x03bd, 0xed} /* small letter nu */, + {0x03be, 0xee} /* small letter xi */, + {0x03c0, 0xf0} /* small letter pi */, + {0x03c1, 0xf1} /* small letter rho */, + {0x03c3, 0xf2} /* small letter sigma */, + {0x03c4, 0xf4} /* small letter tau */, + {0x03c5, 0xf5} /* small letter upsilon */, + {0x03c6, 0xf6} /* small letter phi */, + {0x03c7, 0xf7} /* small letter chi */, + {0x03c8, 0xf8} /* small letter psi */, + {0x03c9, 0xf9} /* small letter omega */, + {0x05d0, 0xc0} /* letter alef */, + {0x2020, 0xfa} /* dagger */, + {0x2030, 0xef} /* mille sign */, + {0x2032, 0xcc} /* prime */, + {0x2033, 0xcd} /* prime */, + {0x203e, 0xff} /* overline */, + {0x2190, 0xfb} /* arrow */, + {0x2191, 0xfc} /* arrow */, + {0x2192, 0xfd} /* arrow */, + {0x2193, 0xfe} /* arrow */, + {0x2194, 0xbc} /* right arrow */, + {0x21c0, 0xdb} /* vector above (iso-10646-1dis 032/032/038/046) */, + {0x21d0, 0xa8} /* double arrow */, + {0x21d2, 0xa9} /* double arrow */, + {0x2200, 0xbe} /* all */, + {0x2202, 0xb4} /* differential */, + {0x2203, 0xbf} /* exists */, + {0x2205, 0xda} /* set */, + {0x2207, 0xb3} /* nabla */, + {0x2208, 0xac} /* of */, + {0x220b, 0xad} /* as member */, + {0x2213, 0xcf} /* sign */, + {0x221a, 0xdc} /* root */, + {0x221d, 0xde} /* to */, + {0x221e, 0xb2} /* infinity */, + {0x221f, 0xc7} /* angle */, + {0x2220, 0xc6} /* angle */, + {0x2225, 0xc2} /* to */, + {0x2227, 0xa2} /* and */, + {0x2228, 0xa3} /* or */, + {0x2229, 0xa4} /* intersection */, + {0x222a, 0xa5} /* union */, + {0x222b, 0xb0} /* integral */, + {0x222e, 0xb1} /* integral */, + {0x2234, 0xaa} /* therefore */, + {0x2235, 0xab} /* because */, + {0x223c, 0xb5} /* operator */, + {0x2243, 0xb7} /* equal to */, + {0x2245, 0xb8} /* equal to */, + {0x2248, 0xb6} /* equal to */, + {0x2260, 0xba} /* equal to */, + {0x2261, 0xa1} /* to */, + {0x2264, 0xb9} /* or equal to */, + {0x2265, 0xbb} /* or equal to */, + {0x2282, 0xa6} /* of */, + {0x2283, 0xa7} /* of */, + {0x2286, 0xae} /* of or equal to */, + {0x2287, 0xaf} /* of or equal to */, + {0x22a5, 0xc5} /* tack */, + {0x2329, 0xc9} /* angle bracket */, + {0x232a, 0xca} /* angle bracket */, + {0x25a1, 0xc1} /* square */ +}; + +/* +#define cet_ucs4_to_iec_p27_1_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iec_p27_1_extra[cet_ucs4_to_iec_p27_1_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iec_p27_1 = /* defined in cet.h */ +{ + cet_cs_name_iec_p27_1, /* name of character set */ + cet_cs_alias_iec_p27_1, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iec_p27_1, /* char to UCS-4 value table */ + cet_ucs4_ofs_iec_p27_1, /* first non standard character */ + cet_ucs4_cnt_iec_p27_1, /* number of values in table */ + + cet_ucs4_to_iec_p27_1_links, /* UCS-4 to char links */ + cet_ucs4_to_iec_p27_1_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iec_p27_1_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x02c7, 0x2261, 0x2227, 0x2228, 0x2229, 0x222a, 0x2282, 0x2283, + 0x21d0, 0x21d2, 0x2234, 0x2235, 0x2208, 0x220b, 0x2286, 0x2287, + 0x222b, 0x222e, 0x221e, 0x2207, 0x2202, 0x223c, 0x2248, 0x2243, + 0x2245, 0x2264, 0x2260, 0x2265, 0x2194, 0x00ac, 0x2200, 0x2203, + 0x05d0, 0x25a1, 0x2225, 0x0393, 0x0394, 0x22a5, 0x2220, 0x221f, + 0x0398, 0x2329, 0x232a, 0x039b, 0x2032, 0x2033, 0x039e, 0x2213, + 0x03a0, 0x00b2, 0x03a3, 0x00d7, 0x00b3, 0x03a5, 0x03a6, 0x00b7, + 0x03a8, 0x03a9, 0x2205, 0x21c0, 0x221a, 0x0192, 0x221d, 0x00b1, + 0x00b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x2030, + 0x03c0, 0x03c1, 0x03c3, 0x00f7, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x2020, 0x2190, 0x2191, 0x2192, 0x2193, 0x203e +}; +*/ + +#endif diff --git a/cet/iso_10367_box.h b/cet/iso_10367_box.h new file mode 100644 index 000000000..c29333d0f --- /dev/null +++ b/cet/iso_10367_box.h @@ -0,0 +1,149 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO_10367-box" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_10367_box_h +#define iso_10367_box_h + +#define cet_cs_name_iso_10367_box "ISO_10367-box" + +const char *cet_cs_alias_iso_10367_box[] = +{ + "ISO_10367-box", "iso-ir-155", NULL +}; + +#define cet_ucs4_ofs_iso_10367_box 160 +#define cet_ucs4_cnt_iso_10367_box 62 + +const int cet_ucs4_map_iso_10367_box[cet_ucs4_cnt_iso_10367_box] = +{ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x2551, 0x2550, 0x2554, 0x2557, 0x255a, 0x255d, 0x2560, 0x2563, + 0x2566, 0x2569, 0x256c, 0xe019, 0x2584, 0x2588, 0x25aa, -1, + 0x2502, 0x2500, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2591, 0x2592, 0x2593 +}; + +#define cet_ucs4_to_iso_10367_box_ct 29 + +const cet_ucs4_link_t cet_ucs4_to_iso_10367_box_links[cet_ucs4_to_iso_10367_box_ct] = +{ + {0x2500, 0xd1} /* drawings light horizontal */, + {0x2502, 0xd0} /* drawings light vertical */, + {0x250c, 0xd2} /* drawings light down and right */, + {0x2510, 0xd3} /* drawings light down and left */, + {0x2514, 0xd4} /* drawings light up and right */, + {0x2518, 0xd5} /* drawings light up and left */, + {0x251c, 0xd6} /* drawings light vertical and right */, + {0x2524, 0xd7} /* drawings light vertical and left */, + {0x252c, 0xd8} /* drawings light down and horizontal */, + {0x2534, 0xd9} /* drawings light up and horizontal */, + {0x253c, 0xda} /* drawings light vertical and horizontal */, + {0x2550, 0xc1} /* drawings heavy horizontal */, + {0x2551, 0xc0} /* drawings heavy vertical */, + {0x2554, 0xc2} /* drawings heavy down and right */, + {0x2557, 0xc3} /* drawings heavy down and left */, + {0x255a, 0xc4} /* drawings heavy up and right */, + {0x255d, 0xc5} /* drawings heavy up and left */, + {0x2560, 0xc6} /* drawings heavy vertical and right */, + {0x2563, 0xc7} /* drawings heavy vertical and left */, + {0x2566, 0xc8} /* drawings heavy down and horizontal */, + {0x2569, 0xc9} /* drawings heavy up and horizontal */, + {0x256c, 0xca} /* drawings heavy vertical and horizontal */, + {0x2584, 0xcc} /* half block */, + {0x2588, 0xcd} /* block */, + {0x2591, 0xdb} /* shade */, + {0x2592, 0xdc} /* shade */, + {0x2593, 0xdd} /* shade */, + {0x25aa, 0xce} /* small square */, + {0xe019, 0xcb} /* space b (iso-ir-8-1 096) */ +}; + +/* +#define cet_ucs4_to_iso_10367_box_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_10367_box_extra[cet_ucs4_to_iso_10367_box_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_10367_box = /* defined in cet.h */ +{ + cet_cs_name_iso_10367_box, /* name of character set */ + cet_cs_alias_iso_10367_box, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_10367_box, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_10367_box, /* first non standard character */ + cet_ucs4_cnt_iso_10367_box, /* number of values in table */ + + cet_ucs4_to_iso_10367_box_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_10367_box_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_10367_box_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x2551, 0x2550, 0x2554, 0x2557, 0x255a, 0x255d, 0x2560, 0x2563, + 0x2566, 0x2569, 0x256c, 0xe019, 0x2584, 0x2588, 0x25aa, -1, + 0x2502, 0x2500, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2591, 0x2592, 0x2593, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_5427.h b/cet/iso_5427.h new file mode 100644 index 000000000..7876a4336 --- /dev/null +++ b/cet/iso_5427.h @@ -0,0 +1,188 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO_5427" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_5427_h +#define iso_5427_h + +#define cet_cs_name_iso_5427 "ISO_5427" + +const char *cet_cs_alias_iso_5427[] = +{ + "ISO_5427", "iso-ir-37", NULL +}; + +#define cet_ucs4_ofs_iso_5427 36 +#define cet_ucs4_cnt_iso_5427 92 + +const int cet_ucs4_map_iso_5427[cet_ucs4_cnt_iso_5427] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x044e, 0x0430, 0x0431, 0x0446, + 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, 0x0438, 0x0439, 0x043a, + 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x044f, 0x0440, 0x0441, + 0x0442, 0x0443, 0x0436, 0x0432, 0x044c, 0x044b, 0x0437, 0x0448, + 0x044d, 0x0449, 0x0447, 0x044a, 0x042e, 0x0410, 0x0411, 0x0426, + 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041a, + 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x042f, 0x0420, 0x0421, + 0x0422, 0x0423, 0x0416, 0x0412, 0x042c, 0x042b, 0x0417, 0x0428, + 0x042d, 0x0429, 0x0427, 0x007f +}; + +#define cet_ucs4_to_iso_5427_ct 64 + +const cet_ucs4_link_t cet_ucs4_to_iso_5427_links[cet_ucs4_to_iso_5427_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x0410, 0x61} /* capital letter a */, + {0x0411, 0x62} /* capital letter be */, + {0x0412, 0x77} /* capital letter ve */, + {0x0413, 0x67} /* capital letter ghe */, + {0x0414, 0x64} /* capital letter de */, + {0x0415, 0x65} /* capital letter ie */, + {0x0416, 0x76} /* capital letter zhe */, + {0x0417, 0x7a} /* capital letter ze */, + {0x0418, 0x69} /* capital letter i */, + {0x0419, 0x6a} /* capital letter short i */, + {0x041a, 0x6b} /* capital letter ka */, + {0x041b, 0x6c} /* capital letter el */, + {0x041c, 0x6d} /* capital letter em */, + {0x041d, 0x6e} /* capital letter en */, + {0x041e, 0x6f} /* capital letter o */, + {0x041f, 0x70} /* capital letter pe */, + {0x0420, 0x72} /* capital letter er */, + {0x0421, 0x73} /* capital letter es */, + {0x0422, 0x74} /* capital letter te */, + {0x0423, 0x75} /* capital letter u */, + {0x0424, 0x66} /* capital letter ef */, + {0x0425, 0x68} /* capital letter ha */, + {0x0426, 0x63} /* capital letter tse */, + {0x0427, 0x7e} /* capital letter che */, + {0x0428, 0x7b} /* capital letter sha */, + {0x0429, 0x7d} /* capital letter shcha */, + {0x042b, 0x79} /* capital letter yeru */, + {0x042c, 0x78} /* capital letter soft sign */, + {0x042d, 0x7c} /* capital letter e */, + {0x042e, 0x60} /* capital letter yu */, + {0x042f, 0x71} /* capital letter ya */, + {0x0430, 0x41} /* small letter a */, + {0x0431, 0x42} /* small letter be */, + {0x0432, 0x57} /* small letter ve */, + {0x0433, 0x47} /* small letter ghe */, + {0x0434, 0x44} /* small letter de */, + {0x0435, 0x45} /* small letter ie */, + {0x0436, 0x56} /* small letter zhe */, + {0x0437, 0x5a} /* small letter ze */, + {0x0438, 0x49} /* small letter i */, + {0x0439, 0x4a} /* small letter short i */, + {0x043a, 0x4b} /* small letter ka */, + {0x043b, 0x4c} /* small letter el */, + {0x043c, 0x4d} /* small letter em */, + {0x043d, 0x4e} /* small letter en */, + {0x043e, 0x4f} /* small letter o */, + {0x043f, 0x50} /* small letter pe */, + {0x0440, 0x52} /* small letter er */, + {0x0441, 0x53} /* small letter es */, + {0x0442, 0x54} /* small letter te */, + {0x0443, 0x55} /* small letter u */, + {0x0444, 0x46} /* small letter ef */, + {0x0445, 0x48} /* small letter ha */, + {0x0446, 0x43} /* small letter tse */, + {0x0447, 0x5e} /* small letter che */, + {0x0448, 0x5b} /* small letter sha */, + {0x0449, 0x5d} /* small letter shcha */, + {0x044a, 0x5f} /* small letter hard sign */, + {0x044b, 0x59} /* small letter yeru */, + {0x044c, 0x58} /* small letter soft sign */, + {0x044d, 0x5c} /* small letter e */, + {0x044e, 0x40} /* small letter yu */, + {0x044f, 0x51} /* small letter ya */ +}; + +/* +#define cet_ucs4_to_iso_5427_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_5427_extra[cet_ucs4_to_iso_5427_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_5427 = /* defined in cet.h */ +{ + cet_cs_name_iso_5427, /* name of character set */ + cet_cs_alias_iso_5427, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_5427, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_5427, /* first non standard character */ + cet_ucs4_cnt_iso_5427, /* number of values in table */ + + cet_ucs4_to_iso_5427_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_5427_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_5427_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_646_irv.h b/cet/iso_646_irv.h new file mode 100644 index 000000000..26be677db --- /dev/null +++ b/cet/iso_646_irv.h @@ -0,0 +1,127 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO_646.irv" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_646_irv_h +#define iso_646_irv_h + +#define cet_cs_name_iso_646_irv "ISO_646.irv" + +const char *cet_cs_alias_iso_646_irv[] = +{ + "ISO_646.irv", "irv", "iso-ir-2", "ISO_646.irv:1983", + NULL +}; + +#define cet_ucs4_ofs_iso_646_irv 36 +#define cet_ucs4_cnt_iso_646_irv 92 + +const int cet_ucs4_map_iso_646_irv[cet_ucs4_cnt_iso_646_irv] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x203e, 0x007f +}; + +#define cet_ucs4_to_iso_646_irv_ct 2 + +const cet_ucs4_link_t cet_ucs4_to_iso_646_irv_links[cet_ucs4_to_iso_646_irv_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_iso_646_irv_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_646_irv_extra[cet_ucs4_to_iso_646_irv_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_646_irv = /* defined in cet.h */ +{ + cet_cs_name_iso_646_irv, /* name of character set */ + cet_cs_alias_iso_646_irv, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_646_irv, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_646_irv, /* first non standard character */ + cet_ucs4_cnt_iso_646_irv, /* number of values in table */ + + cet_ucs4_to_iso_646_irv_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_646_irv_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_646_irv_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_6937_2_25.h b/cet/iso_6937_2_25.h new file mode 100644 index 000000000..fbc7a8e4d --- /dev/null +++ b/cet/iso_6937_2_25.h @@ -0,0 +1,166 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO_6937-2-25" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_6937_2_25_h +#define iso_6937_2_25_h + +#define cet_cs_name_iso_6937_2_25 "ISO_6937-2-25" + +const char *cet_cs_alias_iso_6937_2_25[] = +{ + "ISO_6937-2-25", "iso-ir-152", NULL +}; + +#define cet_ucs4_ofs_iso_6937_2_25 36 +#define cet_ucs4_cnt_iso_6937_2_25 218 + +const int cet_ucs4_map_iso_6937_2_25[cet_ucs4_cnt_iso_6937_2_25] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, + 0x009c, 0x009d, 0x009e, 0x009f, 0x00a0, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0x201c, -1, + 0x2190, 0x2191, 0x2192, 0x2193, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0x201d, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x2122, 0x266a, -1, -1, -1, -1, -1, -1, + 0x215b, 0x215c, 0x215d, 0x215e, 0x2126, -1, -1, -1, + -1, -1, 0x0132, 0x013f, -1, -1, 0x0152, -1, + 0x0174, 0x0176, 0x0178, 0x0149, -1, -1, -1, -1, + -1, -1, 0x0133, 0x0140, -1, -1, 0x0153, -1, + 0x0175, 0x0177 +}; + +#define cet_ucs4_to_iso_6937_2_25_ct 26 + +const cet_ucs4_link_t cet_ucs4_to_iso_6937_2_25_links[cet_ucs4_to_iso_6937_2_25_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x0132, 0xe6} /* capital ligature ij */, + {0x0133, 0xf6} /* small ligature ij */, + {0x013f, 0xe7} /* capital letter l with middle dot */, + {0x0140, 0xf7} /* small letter l with middle dot */, + {0x0149, 0xef} /* small letter n preceded by apostrophe */, + {0x0152, 0xea} /* capital ligature oe */, + {0x0153, 0xfa} /* small ligature oe */, + {0x0174, 0xec} /* capital letter w with circumflex */, + {0x0175, 0xfc} /* small letter w with circumflex */, + {0x0176, 0xed} /* capital letter y with circumflex */, + {0x0177, 0xfd} /* small letter y with circumflex */, + {0x0178, 0xee} /* capital letter y with diaeresis */, + {0x201c, 0xaa} /* double quotation mark */, + {0x201d, 0xba} /* double quotation mark */, + {0x2122, 0xd4} /* mark sign */, + {0x2126, 0xe0} /* sign */, + {0x215b, 0xdc} /* fraction one eighth */, + {0x215c, 0xdd} /* fraction three eighths */, + {0x215d, 0xde} /* fraction five eighths */, + {0x215e, 0xdf} /* fraction seven eighths */, + {0x2190, 0xac} /* arrow */, + {0x2191, 0xad} /* arrow */, + {0x2192, 0xae} /* arrow */, + {0x2193, 0xaf} /* arrow */, + {0x266a, 0xd5} /* note */ +}; + +/* +#define cet_ucs4_to_iso_6937_2_25_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_6937_2_25_extra[cet_ucs4_to_iso_6937_2_25_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_6937_2_25 = /* defined in cet.h */ +{ + cet_cs_name_iso_6937_2_25, /* name of character set */ + cet_cs_alias_iso_6937_2_25, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_6937_2_25, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_6937_2_25, /* first non standard character */ + cet_ucs4_cnt_iso_6937_2_25, /* number of values in table */ + + cet_ucs4_to_iso_6937_2_25_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_6937_2_25_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_6937_2_25_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0x201c, -1, 0x2190, 0x2191, 0x2192, 0x2193, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0x201d, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 0x2122, 0x266a, -1, -1, + -1, -1, -1, -1, 0x215b, 0x215c, 0x215d, 0x215e, + 0x2126, -1, -1, -1, -1, -1, 0x0132, 0x013f, + -1, -1, 0x0152, -1, 0x0174, 0x0176, 0x0178, 0x0149, + -1, -1, -1, -1, -1, -1, 0x0133, 0x0140, + -1, -1, 0x0153, -1, 0x0175, 0x0177, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_8859_1.h b/cet/iso_8859_1.h new file mode 100644 index 000000000..8dab41ff0 --- /dev/null +++ b/cet/iso_8859_1.h @@ -0,0 +1,111 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-1" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_1_h +#define iso_8859_1_h + +#define cet_cs_name_iso_8859_1 "ISO-8859-1" + +const char *cet_cs_alias_iso_8859_1[] = +{ + "ISO-8859-1", "819", "CP819", "csISOLatin1", + "IBM819", "ISO8859-1", "iso-ir-100", "ISO_8859-1", + "ISO_8859-1:1987", "l1", "lat1", "latin1", + "Latin-1", NULL +}; + +#define cet_ucs4_ofs_iso_8859_1 256 +#define cet_ucs4_cnt_iso_8859_1 1 + +const int cet_ucs4_map_iso_8859_1[cet_ucs4_cnt_iso_8859_1]; + +#define cet_ucs4_to_iso_8859_1_ct 1 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_1_links[cet_ucs4_to_iso_8859_1_ct]; + +/* +#define cet_ucs4_to_iso_8859_1_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_1_extra[cet_ucs4_to_iso_8859_1_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_1 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_1, /* name of character set */ + cet_cs_alias_iso_8859_1, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_1, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_1, /* first non standard character */ + cet_ucs4_cnt_iso_8859_1, /* number of values in table */ + + cet_ucs4_to_iso_8859_1_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_1_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_1_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; +*/ + +#endif diff --git a/cet/iso_8859_10.h b/cet/iso_8859_10.h new file mode 100644 index 000000000..8adfc7132 --- /dev/null +++ b/cet/iso_8859_10.h @@ -0,0 +1,172 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-10" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_10_h +#define iso_8859_10_h + +#define cet_cs_name_iso_8859_10 "ISO-8859-10" + +const char *cet_cs_alias_iso_8859_10[] = +{ + "ISO-8859-10", "csISOLatin6", "ISO8859-10", "iso-ir-157", + "ISO_8859-10", "ISO_8859-10:1992", "ISO_8859-10:1993", + "l6", "lat6", "latin6", NULL +}; + +#define cet_ucs4_ofs_iso_8859_10 161 +#define cet_ucs4_cnt_iso_8859_10 95 + +const int cet_ucs4_map_iso_8859_10[cet_ucs4_cnt_iso_8859_10] = +{ + 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7, 0x013b, + 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a, 0x00b0, + 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, 0x013c, + 0x0111, 0x0161, 0x0167, 0x017e, 0x2014, 0x016b, 0x014b, 0x0100, + 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, + 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf, 0x00d0, + 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, 0x00d8, + 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x0101, + 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, + 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef, 0x00f0, + 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, 0x00f8, + 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138 +}; + +#define cet_ucs4_to_iso_8859_10_ct 46 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_10_links[cet_ucs4_to_iso_8859_10_ct] = +{ + {0x0100, 0xc0} /* capital letter a with macron */, + {0x0101, 0xe0} /* small letter a with macron */, + {0x0104, 0xa1} /* capital letter a with ogonek */, + {0x0105, 0xb1} /* small letter a with ogonek */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x0110, 0xa9} /* capital letter d with stroke */, + {0x0111, 0xb9} /* small letter d with stroke */, + {0x0112, 0xa2} /* capital letter e with macron */, + {0x0113, 0xb2} /* small letter e with macron */, + {0x0116, 0xcc} /* capital letter e with dot above */, + {0x0117, 0xec} /* small letter e with dot above */, + {0x0118, 0xca} /* capital letter e with ogonek */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x0122, 0xa3} /* capital letter g with cedilla */, + {0x0123, 0xb3} /* small letter g with cedilla */, + {0x0128, 0xa5} /* capital letter i with tilde */, + {0x0129, 0xb5} /* small letter i with tilde */, + {0x012a, 0xa4} /* capital letter i with macron */, + {0x012b, 0xb4} /* small letter i with macron */, + {0x012e, 0xc7} /* capital letter i with ogonek */, + {0x012f, 0xe7} /* small letter i with ogonek */, + {0x0136, 0xa6} /* capital letter k with cedilla */, + {0x0137, 0xb6} /* small letter k with cedilla */, + {0x0138, 0xff} /* small letter kra (greenlandic) */, + {0x013b, 0xa8} /* capital letter l with cedilla */, + {0x013c, 0xb8} /* small letter l with cedilla */, + {0x0145, 0xd1} /* capital letter n with cedilla */, + {0x0146, 0xf1} /* small letter n with cedilla */, + {0x014a, 0xaf} /* capital letter eng (lappish) */, + {0x014b, 0xbf} /* small letter eng (lappish) */, + {0x014c, 0xd2} /* capital letter o with macron */, + {0x014d, 0xf2} /* small letter o with macron */, + {0x0160, 0xaa} /* capital letter s with caron */, + {0x0161, 0xba} /* small letter s with caron */, + {0x0166, 0xab} /* capital letter t with stroke */, + {0x0167, 0xbb} /* small letter t with stroke */, + {0x0168, 0xd7} /* capital letter u with tilde */, + {0x0169, 0xf7} /* small letter u with tilde */, + {0x016a, 0xae} /* capital letter u with macron */, + {0x016b, 0xbe} /* small letter u with macron */, + {0x0172, 0xd9} /* capital letter u with ogonek */, + {0x0173, 0xf9} /* small letter u with ogonek */, + {0x017d, 0xac} /* capital letter z with caron */, + {0x017e, 0xbc} /* small letter z with caron */, + {0x2014, 0xbd} /* dash */ +}; + +/* +#define cet_ucs4_to_iso_8859_10_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_10_extra[cet_ucs4_to_iso_8859_10_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_10 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_10, /* name of character set */ + cet_cs_alias_iso_8859_10, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_10, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_10, /* first non standard character */ + cet_ucs4_cnt_iso_8859_10, /* number of values in table */ + + cet_ucs4_to_iso_8859_10_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_10_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_10_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7, + 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a, + 0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, + 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2014, 0x016b, 0x014b, + 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, + 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, + 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138 +}; +*/ + +#endif diff --git a/cet/iso_8859_13.h b/cet/iso_8859_13.h new file mode 100644 index 000000000..e67175e09 --- /dev/null +++ b/cet/iso_8859_13.h @@ -0,0 +1,175 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-13" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_13_h +#define iso_8859_13_h + +#define cet_cs_name_iso_8859_13 "ISO-8859-13" + +const char *cet_cs_alias_iso_8859_13[] = +{ + "ISO-8859-13", "ISO8859-13", "iso-baltic", "ISO-IR-179", + "iso-ir-179a", "ISO_8859-13", "ISO_8859-13:1998", + "l7", "lat7", "latin7", NULL +}; + +#define cet_ucs4_ofs_iso_8859_13 165 +#define cet_ucs4_cnt_iso_8859_13 91 + +const int cet_ucs4_map_iso_8859_13[cet_ucs4_cnt_iso_8859_13] = +{ + 0x201e, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, + 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, + 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, + 0x00bd, 0x00be, 0x00bf, 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, + 0x00c5, 0x0118, 0x0112, 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, + 0x0136, 0x012a, 0x013b, 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, + 0x00d5, 0x00d6, 0x00d7, 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, + 0x017b, 0x017d, 0x00df, 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, + 0x00e5, 0x0119, 0x0113, 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, + 0x0137, 0x012b, 0x013c, 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, + 0x00f5, 0x00f6, 0x00f7, 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, + 0x017c, 0x017e, 0x2019 +}; + +#define cet_ucs4_to_iso_8859_13_ct 49 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_13_links[cet_ucs4_to_iso_8859_13_ct] = +{ + {0x0100, 0xc2} /* capital letter a with macron */, + {0x0101, 0xe2} /* small letter a with macron */, + {0x0104, 0xc0} /* capital letter a with ogonek */, + {0x0105, 0xe0} /* small letter a with ogonek */, + {0x0106, 0xc3} /* capital letter c with acute */, + {0x0107, 0xe3} /* small letter c with acute */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x0112, 0xc7} /* capital letter e with macron */, + {0x0113, 0xe7} /* small letter e with macron */, + {0x0116, 0xcb} /* capital letter e with dot above */, + {0x0117, 0xeb} /* small letter e with dot above */, + {0x0118, 0xc6} /* capital letter e with ogonek */, + {0x0119, 0xe6} /* small letter e with ogonek */, + {0x0122, 0xcc} /* capital letter g with cedilla */, + {0x0123, 0xec} /* small letter g with cedilla */, + {0x012a, 0xce} /* capital letter i with macron */, + {0x012b, 0xee} /* small letter i with macron */, + {0x012e, 0xc1} /* capital letter i with ogonek */, + {0x012f, 0xe1} /* small letter i with ogonek */, + {0x0136, 0xcd} /* capital letter k with cedilla */, + {0x0137, 0xed} /* small letter k with cedilla */, + {0x013b, 0xcf} /* capital letter l with cedilla */, + {0x013c, 0xef} /* small letter l with cedilla */, + {0x0141, 0xd9} /* capital letter l with stroke */, + {0x0142, 0xf9} /* small letter l with stroke */, + {0x0143, 0xd1} /* capital letter n with acute */, + {0x0144, 0xf1} /* small letter n with acute */, + {0x0145, 0xd2} /* capital letter n with cedilla */, + {0x0146, 0xf2} /* small letter n with cedilla */, + {0x014c, 0xd4} /* capital letter o with macron */, + {0x014d, 0xf4} /* small letter o with macron */, + {0x015a, 0xda} /* capital letter s with acute */, + {0x015b, 0xfa} /* small letter s with acute */, + {0x0160, 0xd0} /* capital letter s with caron */, + {0x0161, 0xf0} /* small letter s with caron */, + {0x016a, 0xdb} /* capital letter u with macron */, + {0x016b, 0xfb} /* small letter u with macron */, + {0x0172, 0xd8} /* capital letter u with ogonek */, + {0x0173, 0xf8} /* small letter u with ogonek */, + {0x0179, 0xca} /* capital letter z with acute */, + {0x017a, 0xea} /* small letter z with acute */, + {0x017b, 0xdd} /* capital letter z with dot above */, + {0x017c, 0xfd} /* small letter z with dot above */, + {0x017d, 0xde} /* capital letter z with caron */, + {0x017e, 0xfe} /* small letter z with caron */, + {0x2019, 0xff} /* single quotation mark */, + {0x201c, 0xb4} /* double quotation mark */, + {0x201e, 0xa5} /* low-9 quotation mark */ +}; + +/* +#define cet_ucs4_to_iso_8859_13_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_13_extra[cet_ucs4_to_iso_8859_13_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_13 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_13, /* name of character set */ + cet_cs_alias_iso_8859_13, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_13, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_13, /* first non standard character */ + cet_ucs4_cnt_iso_8859_13, /* number of values in table */ + + cet_ucs4_to_iso_8859_13_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_13_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_13_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, + 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, + 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, + 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, + 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, + 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019 +}; +*/ + +#endif diff --git a/cet/iso_8859_14.h b/cet/iso_8859_14.h new file mode 100644 index 000000000..fb47dd817 --- /dev/null +++ b/cet/iso_8859_14.h @@ -0,0 +1,157 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-14" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_14_h +#define iso_8859_14_h + +#define cet_cs_name_iso_8859_14 "ISO-8859-14" + +const char *cet_cs_alias_iso_8859_14[] = +{ + "ISO-8859-14", "ISO8859-14", "iso-celtic", "iso-ir-199", + "ISO_8859-14", "ISO_8859-14:1998", "l8", "lat8", "latin8", + NULL +}; + +#define cet_ucs4_ofs_iso_8859_14 161 +#define cet_ucs4_cnt_iso_8859_14 95 + +const int cet_ucs4_map_iso_8859_14[cet_ucs4_cnt_iso_8859_14] = +{ + 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, 0x1e80, + 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x1e61, 0x1e1e, + 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, 0x1e81, + 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x0178, 0x00c0, + 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, + 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x0174, + 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, 0x00d8, + 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df, 0x00e0, + 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, + 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x0175, + 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, 0x00f8, + 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff +}; + +#define cet_ucs4_to_iso_8859_14_ct 31 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_14_links[cet_ucs4_to_iso_8859_14_ct] = +{ + {0x010a, 0xa4} /* capital letter c with dot above */, + {0x010b, 0xa5} /* small letter c with dot above */, + {0x0120, 0xb2} /* capital letter g with dot above */, + {0x0121, 0xb3} /* small letter g with dot above */, + {0x0174, 0xd0} /* capital letter w with circumflex */, + {0x0175, 0xf0} /* small letter w with circumflex */, + {0x0176, 0xde} /* capital letter y with circumflex */, + {0x0177, 0xfe} /* small letter y with circumflex */, + {0x0178, 0xbf} /* capital letter y with diaeresis */, + {0x1e02, 0xa1} /* capital letter b with dot above */, + {0x1e03, 0xa2} /* small letter b with dot above */, + {0x1e0a, 0xa6} /* capital letter d with dot above */, + {0x1e0b, 0xab} /* small letter d with dot above */, + {0x1e1e, 0xb0} /* capital letter f with dot above */, + {0x1e1f, 0xb1} /* small letter f with dot above */, + {0x1e40, 0xb4} /* capital letter m with dot above */, + {0x1e41, 0xb5} /* small letter m with dot above */, + {0x1e56, 0xb7} /* capital letter p with dot above */, + {0x1e57, 0xb9} /* small letter p with dot above */, + {0x1e60, 0xbb} /* capital letter s with dot above */, + {0x1e61, 0xaf} /* small letter s with dot above */, + {0x1e6a, 0xd7} /* capital letter t with dot above */, + {0x1e6b, 0xf7} /* small letter t with dot above */, + {0x1e80, 0xa8} /* capital letter w with grave */, + {0x1e81, 0xb8} /* small letter w with grave */, + {0x1e82, 0xaa} /* capital letter w with acute */, + {0x1e83, 0xba} /* small letter w with acute */, + {0x1e84, 0xbd} /* capital letter w with diaeresis */, + {0x1e85, 0xbe} /* small letter w with diaeresis */, + {0x1ef2, 0xac} /* capital letter y with grave */, + {0x1ef3, 0xbc} /* small letter y with grave */ +}; + +/* +#define cet_ucs4_to_iso_8859_14_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_14_extra[cet_ucs4_to_iso_8859_14_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_14 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_14, /* name of character set */ + cet_cs_alias_iso_8859_14, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_14, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_14, /* first non standard character */ + cet_ucs4_cnt_iso_8859_14, /* number of values in table */ + + cet_ucs4_to_iso_8859_14_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_14_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_14_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, + 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x1e61, + 0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, + 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x0178, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff +}; +*/ + +#endif diff --git a/cet/iso_8859_15.h b/cet/iso_8859_15.h new file mode 100644 index 000000000..88750962b --- /dev/null +++ b/cet/iso_8859_15.h @@ -0,0 +1,133 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-15" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_15_h +#define iso_8859_15_h + +#define cet_cs_name_iso_8859_15 "ISO-8859-15" + +const char *cet_cs_alias_iso_8859_15[] = +{ + "ISO-8859-15", "ISO8859-15", "iso-ir-203", "ISO_8859-15", + "ISO_8859-15:1998", "l9", "lat9", "latin9", NULL +}; + +#define cet_ucs4_ofs_iso_8859_15 164 +#define cet_ucs4_cnt_iso_8859_15 92 + +const int cet_ucs4_map_iso_8859_15[cet_ucs4_cnt_iso_8859_15] = +{ + 0x20ac, 0x00a5, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x00aa, 0x00ab, + 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, + 0x017d, 0x00b5, 0x00b6, 0x00b7, 0x017e, 0x00b9, 0x00ba, 0x00bb, + 0x0152, 0x0153, 0x0178, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, + 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, + 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, + 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, + 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e2, 0x00e3, + 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, + 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, + 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, + 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; + +#define cet_ucs4_to_iso_8859_15_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_15_links[cet_ucs4_to_iso_8859_15_ct] = +{ + {0x0152, 0xbc} /* capital ligature oe */, + {0x0153, 0xbd} /* small ligature oe */, + {0x0160, 0xa6} /* capital letter s with caron */, + {0x0161, 0xa8} /* small letter s with caron */, + {0x0178, 0xbe} /* capital letter y with diaeresis */, + {0x017d, 0xb4} /* capital letter z with caron */, + {0x017e, 0xb8} /* small letter z with caron */, + {0x20ac, 0xa4} /* euro */ +}; + +/* +#define cet_ucs4_to_iso_8859_15_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_15_extra[cet_ucs4_to_iso_8859_15_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_15 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_15, /* name of character set */ + cet_cs_alias_iso_8859_15, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_15, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_15, /* first non standard character */ + cet_ucs4_cnt_iso_8859_15, /* number of values in table */ + + cet_ucs4_to_iso_8859_15_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_15_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_15_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, + 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, + 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; +*/ + +#endif diff --git a/cet/iso_8859_2.h b/cet/iso_8859_2.h new file mode 100644 index 000000000..6e348cc06 --- /dev/null +++ b/cet/iso_8859_2.h @@ -0,0 +1,183 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_2_h +#define iso_8859_2_h + +#define cet_cs_name_iso_8859_2 "ISO-8859-2" + +const char *cet_cs_alias_iso_8859_2[] = +{ + "ISO-8859-2", "912", "CP912", "csISOLatin2", + "IBM912", "ISO8859-2", "iso-ir-101", "ISO_8859-2", + "ISO_8859-2:1987", "l2", "lat2", "latin2", NULL +}; + +#define cet_ucs4_ofs_iso_8859_2 161 +#define cet_ucs4_cnt_iso_8859_2 95 + +const int cet_ucs4_map_iso_8859_2[cet_ucs4_cnt_iso_8859_2] = +{ + 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, 0x00a8, + 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, 0x00b0, + 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, + 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, 0x0154, + 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, + 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, 0x0110, + 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, + 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, 0x0155, + 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, + 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, 0x0111, + 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, + 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; + +#define cet_ucs4_to_iso_8859_2_ct 57 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_2_links[cet_ucs4_to_iso_8859_2_ct] = +{ + {0x0102, 0xc3} /* capital letter a with breve */, + {0x0103, 0xe3} /* small letter a with breve */, + {0x0104, 0xa1} /* capital letter a with ogonek */, + {0x0105, 0xb1} /* small letter a with ogonek */, + {0x0106, 0xc6} /* capital letter c with acute */, + {0x0107, 0xe6} /* small letter c with acute */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x010e, 0xcf} /* capital letter d with caron */, + {0x010f, 0xef} /* small letter d with caron */, + {0x0110, 0xd0} /* capital letter d with stroke */, + {0x0111, 0xf0} /* small letter d with stroke */, + {0x0118, 0xca} /* capital letter e with ogonek */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x011a, 0xcc} /* capital letter e with caron */, + {0x011b, 0xec} /* small letter e with caron */, + {0x0139, 0xc5} /* capital letter l with acute */, + {0x013a, 0xe5} /* small letter l with acute */, + {0x013d, 0xa5} /* capital letter l with caron */, + {0x013e, 0xb5} /* small letter l with caron */, + {0x0141, 0xa3} /* capital letter l with stroke */, + {0x0142, 0xb3} /* small letter l with stroke */, + {0x0143, 0xd1} /* capital letter n with acute */, + {0x0144, 0xf1} /* small letter n with acute */, + {0x0147, 0xd2} /* capital letter n with caron */, + {0x0148, 0xf2} /* small letter n with caron */, + {0x0150, 0xd5} /* capital letter o with double acute */, + {0x0151, 0xf5} /* small letter o with double acute */, + {0x0154, 0xc0} /* capital letter r with acute */, + {0x0155, 0xe0} /* small letter r with acute */, + {0x0158, 0xd8} /* capital letter r with caron */, + {0x0159, 0xf8} /* small letter r with caron */, + {0x015a, 0xa6} /* capital letter s with acute */, + {0x015b, 0xb6} /* small letter s with acute */, + {0x015e, 0xaa} /* capital letter s with cedilla */, + {0x015f, 0xba} /* small letter s with cedilla */, + {0x0160, 0xa9} /* capital letter s with caron */, + {0x0161, 0xb9} /* small letter s with caron */, + {0x0162, 0xde} /* capital letter t with cedilla */, + {0x0163, 0xfe} /* small letter t with cedilla */, + {0x0164, 0xab} /* capital letter t with caron */, + {0x0165, 0xbb} /* small letter t with caron */, + {0x016e, 0xd9} /* capital letter u with ring above */, + {0x016f, 0xf9} /* small letter u with ring above */, + {0x0170, 0xdb} /* capital letter u with double acute */, + {0x0171, 0xfb} /* small letter u with double acute */, + {0x0179, 0xac} /* capital letter z with acute */, + {0x017a, 0xbc} /* small letter z with acute */, + {0x017b, 0xaf} /* capital letter z with dot above */, + {0x017c, 0xbf} /* small letter z with dot above */, + {0x017d, 0xae} /* capital letter z with caron */, + {0x017e, 0xbe} /* small letter z with caron */, + {0x02c7, 0xb7} /* caron */, + {0x02d8, 0xa2} /* breve */, + {0x02d9, 0xff} /* above */, + {0x02db, 0xb2} /* ogonek */, + {0x02dd, 0xbd} /* acute accent */ +}; + +/* +#define cet_ucs4_to_iso_8859_2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_2_extra[cet_ucs4_to_iso_8859_2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_2 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_2, /* name of character set */ + cet_cs_alias_iso_8859_2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_2, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_2, /* first non standard character */ + cet_ucs4_cnt_iso_8859_2, /* number of values in table */ + + cet_ucs4_to_iso_8859_2_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, + 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, + 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, + 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; +*/ + +#endif diff --git a/cet/iso_8859_3.h b/cet/iso_8859_3.h new file mode 100644 index 000000000..1a264d196 --- /dev/null +++ b/cet/iso_8859_3.h @@ -0,0 +1,154 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-3" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_3_h +#define iso_8859_3_h + +#define cet_cs_name_iso_8859_3 "ISO-8859-3" + +const char *cet_cs_alias_iso_8859_3[] = +{ + "ISO-8859-3", "csISOLatin3", "ISO8859-3", "iso-ir-109", + "ISO_8859-3", "ISO_8859-3:1988", "l3", "lat3", "latin3", + NULL +}; + +#define cet_ucs4_ofs_iso_8859_3 161 +#define cet_ucs4_cnt_iso_8859_3 95 + +const int cet_ucs4_map_iso_8859_3[cet_ucs4_cnt_iso_8859_3] = +{ + 0x0126, 0x02d8, 0x00a3, 0x00a4, -1, 0x0124, 0x00a7, 0x00a8, + 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, -1, 0x017b, 0x00b0, + 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, 0x00b8, + 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, -1, 0x017c, 0x00c0, + 0x00c1, 0x00c2, -1, 0x00c4, 0x010a, 0x0108, 0x00c7, 0x00c8, + 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, -1, + 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, 0x011c, + 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df, 0x00e0, + 0x00e1, 0x00e2, -1, 0x00e4, 0x010b, 0x0109, 0x00e7, 0x00e8, + 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, -1, + 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, 0x011d, + 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9 +}; + +#define cet_ucs4_to_iso_8859_3_ct 28 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_3_links[cet_ucs4_to_iso_8859_3_ct] = +{ + {0x0108, 0xc6} /* capital letter c with circumflex */, + {0x0109, 0xe6} /* small letter c with circumflex */, + {0x010a, 0xc5} /* capital letter c with dot above */, + {0x010b, 0xe5} /* small letter c with dot above */, + {0x011c, 0xd8} /* capital letter g with circumflex */, + {0x011d, 0xf8} /* small letter g with circumflex */, + {0x011e, 0xab} /* capital letter g with breve */, + {0x011f, 0xbb} /* small letter g with breve */, + {0x0120, 0xd5} /* capital letter g with dot above */, + {0x0121, 0xf5} /* small letter g with dot above */, + {0x0124, 0xa6} /* capital letter h with circumflex */, + {0x0125, 0xb6} /* small letter h with circumflex */, + {0x0126, 0xa1} /* capital letter h with stroke */, + {0x0127, 0xb1} /* small letter h with stroke */, + {0x0130, 0xa9} /* capital letter i with dot above */, + {0x0131, 0xb9} /* small letter i dotless */, + {0x0134, 0xac} /* capital letter j with circumflex */, + {0x0135, 0xbc} /* small letter j with circumflex */, + {0x015c, 0xde} /* capital letter s with circumflex */, + {0x015d, 0xfe} /* small letter s with circumflex */, + {0x015e, 0xaa} /* capital letter s with cedilla */, + {0x015f, 0xba} /* small letter s with cedilla */, + {0x016c, 0xdd} /* capital letter u with breve */, + {0x016d, 0xfd} /* small letter u with breve */, + {0x017b, 0xaf} /* capital letter z with dot above */, + {0x017c, 0xbf} /* small letter z with dot above */, + {0x02d8, 0xa2} /* breve */, + {0x02d9, 0xff} /* above */ +}; + +/* +#define cet_ucs4_to_iso_8859_3_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_3_extra[cet_ucs4_to_iso_8859_3_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_3 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_3, /* name of character set */ + cet_cs_alias_iso_8859_3, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_3, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_3, /* first non standard character */ + cet_ucs4_cnt_iso_8859_3, /* number of values in table */ + + cet_ucs4_to_iso_8859_3_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_3_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_3_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, -1, 0x0124, 0x00a7, + 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, -1, 0x017b, + 0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, + 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, -1, 0x017c, + 0x00c0, 0x00c1, 0x00c2, -1, 0x00c4, 0x010a, 0x0108, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + -1, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, + 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df, + 0x00e0, 0x00e1, 0x00e2, -1, 0x00e4, 0x010b, 0x0109, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + -1, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, + 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9 +}; +*/ + +#endif diff --git a/cet/iso_8859_4.h b/cet/iso_8859_4.h new file mode 100644 index 000000000..e9d8a6e04 --- /dev/null +++ b/cet/iso_8859_4.h @@ -0,0 +1,176 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-4" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_4_h +#define iso_8859_4_h + +#define cet_cs_name_iso_8859_4 "ISO-8859-4" + +const char *cet_cs_alias_iso_8859_4[] = +{ + "ISO-8859-4", "csISOLatin4", "ISO8859-4", "iso-ir-110", + "ISO_8859-4", "ISO_8859-4:1988", "l4", "lat4", "latin4", + NULL +}; + +#define cet_ucs4_ofs_iso_8859_4 161 +#define cet_ucs4_cnt_iso_8859_4 95 + +const int cet_ucs4_map_iso_8859_4[cet_ucs4_cnt_iso_8859_4] = +{ + 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7, 0x00a8, + 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, 0x00b0, + 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, 0x00b8, + 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b, 0x0100, + 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, + 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a, 0x0110, + 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, + 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df, 0x0101, + 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, + 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, 0x0111, + 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, + 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9 +}; + +#define cet_ucs4_to_iso_8859_4_ct 50 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_4_links[cet_ucs4_to_iso_8859_4_ct] = +{ + {0x0100, 0xc0} /* capital letter a with macron */, + {0x0101, 0xe0} /* small letter a with macron */, + {0x0104, 0xa1} /* capital letter a with ogonek */, + {0x0105, 0xb1} /* small letter a with ogonek */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x0110, 0xd0} /* capital letter d with stroke */, + {0x0111, 0xf0} /* small letter d with stroke */, + {0x0112, 0xaa} /* capital letter e with macron */, + {0x0113, 0xba} /* small letter e with macron */, + {0x0116, 0xcc} /* capital letter e with dot above */, + {0x0117, 0xec} /* small letter e with dot above */, + {0x0118, 0xca} /* capital letter e with ogonek */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x0122, 0xab} /* capital letter g with cedilla */, + {0x0123, 0xbb} /* small letter g with cedilla */, + {0x0128, 0xa5} /* capital letter i with tilde */, + {0x0129, 0xb5} /* small letter i with tilde */, + {0x012a, 0xcf} /* capital letter i with macron */, + {0x012b, 0xef} /* small letter i with macron */, + {0x012e, 0xc7} /* capital letter i with ogonek */, + {0x012f, 0xe7} /* small letter i with ogonek */, + {0x0136, 0xd3} /* capital letter k with cedilla */, + {0x0137, 0xf3} /* small letter k with cedilla */, + {0x0138, 0xa2} /* small letter kra (greenlandic) */, + {0x013b, 0xa6} /* capital letter l with cedilla */, + {0x013c, 0xb6} /* small letter l with cedilla */, + {0x0145, 0xd1} /* capital letter n with cedilla */, + {0x0146, 0xf1} /* small letter n with cedilla */, + {0x014a, 0xbd} /* capital letter eng (lappish) */, + {0x014b, 0xbf} /* small letter eng (lappish) */, + {0x014c, 0xd2} /* capital letter o with macron */, + {0x014d, 0xf2} /* small letter o with macron */, + {0x0156, 0xa3} /* capital letter r with cedilla */, + {0x0157, 0xb3} /* small letter r with cedilla */, + {0x0160, 0xa9} /* capital letter s with caron */, + {0x0161, 0xb9} /* small letter s with caron */, + {0x0166, 0xac} /* capital letter t with stroke */, + {0x0167, 0xbc} /* small letter t with stroke */, + {0x0168, 0xdd} /* capital letter u with tilde */, + {0x0169, 0xfd} /* small letter u with tilde */, + {0x016a, 0xde} /* capital letter u with macron */, + {0x016b, 0xfe} /* small letter u with macron */, + {0x0172, 0xd9} /* capital letter u with ogonek */, + {0x0173, 0xf9} /* small letter u with ogonek */, + {0x017d, 0xae} /* capital letter z with caron */, + {0x017e, 0xbe} /* small letter z with caron */, + {0x02c7, 0xb7} /* caron */, + {0x02d9, 0xff} /* above */, + {0x02db, 0xb2} /* ogonek */ +}; + +/* +#define cet_ucs4_to_iso_8859_4_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_4_extra[cet_ucs4_to_iso_8859_4_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_4 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_4, /* name of character set */ + cet_cs_alias_iso_8859_4, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_4, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_4, /* first non standard character */ + cet_ucs4_cnt_iso_8859_4, /* number of values in table */ + + cet_ucs4_to_iso_8859_4_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_4_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_4_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7, + 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, + 0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, + 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b, + 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a, + 0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df, + 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9 +}; +*/ + +#endif diff --git a/cet/iso_8859_5.h b/cet/iso_8859_5.h new file mode 100644 index 000000000..c70e4919a --- /dev/null +++ b/cet/iso_8859_5.h @@ -0,0 +1,219 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-5" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_5_h +#define iso_8859_5_h + +#define cet_cs_name_iso_8859_5 "ISO-8859-5" + +const char *cet_cs_alias_iso_8859_5[] = +{ + "ISO-8859-5", "csISOLatinCyrillic", "cyrillic", "ISO8859-5", + "iso-ir-144", "ISO_8859-5", "ISO_8859-5:1988", NULL +}; + +#define cet_ucs4_ofs_iso_8859_5 161 +#define cet_ucs4_cnt_iso_8859_5 95 + +const int cet_ucs4_map_iso_8859_5[cet_ucs4_cnt_iso_8859_5] = +{ + 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, + 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, 0x0410, + 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, + 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x0420, + 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, + 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, + 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, + 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, + 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, + 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x2116, + 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, + 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f +}; + +#define cet_ucs4_to_iso_8859_5_ct 94 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_5_links[cet_ucs4_to_iso_8859_5_ct] = +{ + {0x00a7, 0xfd} /* sign */, + {0x0401, 0xa1} /* capital letter io */, + {0x0402, 0xa2} /* capital letter dje (serbocroatian) */, + {0x0403, 0xa3} /* capital letter gje (macedonian) */, + {0x0404, 0xa4} /* capital letter ukrainian ie */, + {0x0405, 0xa5} /* capital letter dze (macedonian) */, + {0x0406, 0xa6} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0xa7} /* capital letter yi (ukrainian) */, + {0x0408, 0xa8} /* capital letter je */, + {0x0409, 0xa9} /* capital letter lje */, + {0x040a, 0xaa} /* capital letter nje */, + {0x040b, 0xab} /* capital letter tshe (serbocroatian) */, + {0x040c, 0xac} /* capital letter kje (macedonian) */, + {0x040e, 0xae} /* capital letter short u (byelorussian) */, + {0x040f, 0xaf} /* capital letter dzhe */, + {0x0410, 0xb0} /* capital letter a */, + {0x0411, 0xb1} /* capital letter be */, + {0x0412, 0xb2} /* capital letter ve */, + {0x0413, 0xb3} /* capital letter ghe */, + {0x0414, 0xb4} /* capital letter de */, + {0x0415, 0xb5} /* capital letter ie */, + {0x0416, 0xb6} /* capital letter zhe */, + {0x0417, 0xb7} /* capital letter ze */, + {0x0418, 0xb8} /* capital letter i */, + {0x0419, 0xb9} /* capital letter short i */, + {0x041a, 0xba} /* capital letter ka */, + {0x041b, 0xbb} /* capital letter el */, + {0x041c, 0xbc} /* capital letter em */, + {0x041d, 0xbd} /* capital letter en */, + {0x041e, 0xbe} /* capital letter o */, + {0x041f, 0xbf} /* capital letter pe */, + {0x0420, 0xc0} /* capital letter er */, + {0x0421, 0xc1} /* capital letter es */, + {0x0422, 0xc2} /* capital letter te */, + {0x0423, 0xc3} /* capital letter u */, + {0x0424, 0xc4} /* capital letter ef */, + {0x0425, 0xc5} /* capital letter ha */, + {0x0426, 0xc6} /* capital letter tse */, + {0x0427, 0xc7} /* capital letter che */, + {0x0428, 0xc8} /* capital letter sha */, + {0x0429, 0xc9} /* capital letter shcha */, + {0x042a, 0xca} /* capital letter hard sign */, + {0x042b, 0xcb} /* capital letter yeru */, + {0x042c, 0xcc} /* capital letter soft sign */, + {0x042d, 0xcd} /* capital letter e */, + {0x042e, 0xce} /* capital letter yu */, + {0x042f, 0xcf} /* capital letter ya */, + {0x0430, 0xd0} /* small letter a */, + {0x0431, 0xd1} /* small letter be */, + {0x0432, 0xd2} /* small letter ve */, + {0x0433, 0xd3} /* small letter ghe */, + {0x0434, 0xd4} /* small letter de */, + {0x0435, 0xd5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xd7} /* small letter ze */, + {0x0438, 0xd8} /* small letter i */, + {0x0439, 0xd9} /* small letter short i */, + {0x043a, 0xda} /* small letter ka */, + {0x043b, 0xdb} /* small letter el */, + {0x043c, 0xdc} /* small letter em */, + {0x043d, 0xdd} /* small letter en */, + {0x043e, 0xde} /* small letter o */, + {0x043f, 0xdf} /* small letter pe */, + {0x0440, 0xe0} /* small letter er */, + {0x0441, 0xe1} /* small letter es */, + {0x0442, 0xe2} /* small letter te */, + {0x0443, 0xe3} /* small letter u */, + {0x0444, 0xe4} /* small letter ef */, + {0x0445, 0xe5} /* small letter ha */, + {0x0446, 0xe6} /* small letter tse */, + {0x0447, 0xe7} /* small letter che */, + {0x0448, 0xe8} /* small letter sha */, + {0x0449, 0xe9} /* small letter shcha */, + {0x044a, 0xea} /* small letter hard sign */, + {0x044b, 0xeb} /* small letter yeru */, + {0x044c, 0xec} /* small letter soft sign */, + {0x044d, 0xed} /* small letter e */, + {0x044e, 0xee} /* small letter yu */, + {0x044f, 0xef} /* small letter ya */, + {0x0451, 0xf1} /* small letter io */, + {0x0452, 0xf2} /* small letter dje (serbocroatian) */, + {0x0453, 0xf3} /* small letter gje (macedonian) */, + {0x0454, 0xf4} /* small letter ukrainian ie */, + {0x0455, 0xf5} /* small letter dze (macedonian) */, + {0x0456, 0xf6} /* small letter byelorussian-ukrainian i */, + {0x0457, 0xf7} /* small letter yi (ukrainian) */, + {0x0458, 0xf8} /* small letter je */, + {0x0459, 0xf9} /* small letter lje */, + {0x045a, 0xfa} /* small letter nje */, + {0x045b, 0xfb} /* small letter tshe (serbocroatian) */, + {0x045c, 0xfc} /* small letter kje (macedonian) */, + {0x045e, 0xfe} /* small letter short u (byelorussian) */, + {0x045f, 0xff} /* small letter dzhe */, + {0x2116, 0xf0} /* sign */ +}; + +/* +#define cet_ucs4_to_iso_8859_5_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_5_extra[cet_ucs4_to_iso_8859_5_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_5 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_5, /* name of character set */ + cet_cs_alias_iso_8859_5, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_5, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_5, /* first non standard character */ + cet_ucs4_cnt_iso_8859_5, /* number of values in table */ + + cet_ucs4_to_iso_8859_5_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_5_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_5_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f +}; +*/ + +#endif diff --git a/cet/iso_8859_6.h b/cet/iso_8859_6.h new file mode 100644 index 000000000..dbd7730c4 --- /dev/null +++ b/cet/iso_8859_6.h @@ -0,0 +1,173 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-6" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_6_h +#define iso_8859_6_h + +#define cet_cs_name_iso_8859_6 "ISO-8859-6" + +const char *cet_cs_alias_iso_8859_6[] = +{ + "ISO-8859-6", "arabic", "ASMO-708", "csISOLatinArabic", + "ECMA-114", "ISO8859-6", "iso-ir-127", "ISO_8859-6", + "ISO_8859-6:1987", NULL +}; + +#define cet_ucs4_ofs_iso_8859_6 161 +#define cet_ucs4_cnt_iso_8859_6 82 + +const int cet_ucs4_map_iso_8859_6[cet_ucs4_cnt_iso_8859_6] = +{ + -1, -1, -1, 0x00a4, -1, -1, -1, -1, + -1, -1, -1, 0x060c, 0x00ad, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0x061b, -1, -1, -1, 0x061f, -1, + 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, + 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, 0x0630, + 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, + 0x0639, 0x063a, -1, -1, -1, -1, -1, 0x0640, + 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, + 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, 0x0650, + 0x0651, 0x0652 +}; + +#define cet_ucs4_to_iso_8859_6_ct 48 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_6_links[cet_ucs4_to_iso_8859_6_ct] = +{ + {0x060c, 0xac} /* comma */, + {0x061b, 0xbb} /* semicolon */, + {0x061f, 0xbf} /* question mark */, + {0x0621, 0xc1} /* letter hamza */, + {0x0622, 0xc2} /* letter alef with madda above */, + {0x0623, 0xc3} /* letter alef with hamza above */, + {0x0624, 0xc4} /* letter waw with hamza above */, + {0x0625, 0xc5} /* letter alef with hamza below */, + {0x0626, 0xc6} /* letter yeh with hamza above */, + {0x0627, 0xc7} /* letter alef */, + {0x0628, 0xc8} /* letter beh */, + {0x0629, 0xc9} /* letter teh marbuta */, + {0x062a, 0xca} /* letter teh */, + {0x062b, 0xcb} /* letter theh */, + {0x062c, 0xcc} /* letter jeem */, + {0x062d, 0xcd} /* letter hah */, + {0x062e, 0xce} /* letter khah */, + {0x062f, 0xcf} /* letter dal */, + {0x0630, 0xd0} /* letter thal */, + {0x0631, 0xd1} /* letter reh */, + {0x0632, 0xd2} /* letter zain */, + {0x0633, 0xd3} /* letter seen */, + {0x0634, 0xd4} /* letter sheen */, + {0x0635, 0xd5} /* letter sad */, + {0x0636, 0xd6} /* letter dad */, + {0x0637, 0xd7} /* letter tah */, + {0x0638, 0xd8} /* letter zah */, + {0x0639, 0xd9} /* letter ain */, + {0x063a, 0xda} /* letter ghain */, + {0x0640, 0xe0} /* tatweel */, + {0x0641, 0xe1} /* letter feh */, + {0x0642, 0xe2} /* letter qaf */, + {0x0643, 0xe3} /* letter kaf */, + {0x0644, 0xe4} /* letter lam */, + {0x0645, 0xe5} /* letter meem */, + {0x0646, 0xe6} /* letter noon */, + {0x0647, 0xe7} /* letter heh */, + {0x0648, 0xe8} /* letter waw */, + {0x0649, 0xe9} /* letter alef maksura */, + {0x064a, 0xea} /* letter yeh */, + {0x064b, 0xeb} /* fathatan */, + {0x064c, 0xec} /* dammatan */, + {0x064d, 0xed} /* kasratan */, + {0x064e, 0xee} /* fatha */, + {0x064f, 0xef} /* damma */, + {0x0650, 0xf0} /* kasra */, + {0x0651, 0xf1} /* shadda */, + {0x0652, 0xf2} /* sukun */ +}; + +/* +#define cet_ucs4_to_iso_8859_6_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_6_extra[cet_ucs4_to_iso_8859_6_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_6 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_6, /* name of character set */ + cet_cs_alias_iso_8859_6, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_6, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_6, /* first non standard character */ + cet_ucs4_cnt_iso_8859_6, /* number of values in table */ + + cet_ucs4_to_iso_8859_6_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_6_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_6_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, -1, -1, -1, 0x00a4, -1, -1, -1, + -1, -1, -1, -1, 0x060c, 0x00ad, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 0x061b, -1, -1, -1, 0x061f, + -1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, + 0x0638, 0x0639, 0x063a, -1, -1, -1, -1, -1, + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, + 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, + 0x0650, 0x0651, 0x0652, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_8859_7.h b/cet/iso_8859_7.h new file mode 100644 index 000000000..09a6f50c7 --- /dev/null +++ b/cet/iso_8859_7.h @@ -0,0 +1,199 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-7" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_7_h +#define iso_8859_7_h + +#define cet_cs_name_iso_8859_7 "ISO-8859-7" + +const char *cet_cs_alias_iso_8859_7[] = +{ + "ISO-8859-7", "csISOLatinGreek", "ECMA-118", "ELOT_928", + "greek", "greek8", "ISO8859-7", "iso-ir-126", + "ISO_8859-7", "ISO_8859-7:1987", NULL +}; + +#define cet_ucs4_ofs_iso_8859_7 161 +#define cet_ucs4_cnt_iso_8859_7 94 + +const int cet_ucs4_map_iso_8859_7[cet_ucs4_cnt_iso_8859_7] = +{ + 0x201b, 0x2019, 0x00a3, -1, -1, 0x00a6, 0x00a7, 0x00a8, + 0x00a9, -1, 0x00ab, 0x00ac, 0x00ad, -1, 0x2014, 0x00b0, + 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x0385, 0x0386, 0x00b7, 0x0388, + 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, 0x0390, + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + 0x03a1, -1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, + 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03b0, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, + 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce +}; + +#define cet_ucs4_to_iso_8859_7_ct 73 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_7_links[cet_ucs4_to_iso_8859_7_ct] = +{ + {0x0385, 0xb5} /* accent and diaeresis (tonos and dialytika) */, + {0x0386, 0xb6} /* capital letter alpha with acute */, + {0x0388, 0xb8} /* capital letter epsilon with acute */, + {0x0389, 0xb9} /* capital letter eta with acute */, + {0x038a, 0xba} /* capital letter iota with acute */, + {0x038c, 0xbc} /* capital letter omicron with acute */, + {0x038e, 0xbe} /* capital letter upsilon with acute */, + {0x038f, 0xbf} /* capital letter omega with acute */, + {0x0390, 0xc0} /* small letter iota with acute and diaeresis */, + {0x0391, 0xc1} /* capital letter alpha */, + {0x0392, 0xc2} /* capital letter beta */, + {0x0393, 0xc3} /* capital letter gamma */, + {0x0394, 0xc4} /* capital letter delta */, + {0x0395, 0xc5} /* capital letter epsilon */, + {0x0396, 0xc6} /* capital letter zeta */, + {0x0397, 0xc7} /* capital letter eta */, + {0x0398, 0xc8} /* capital letter theta */, + {0x0399, 0xc9} /* capital letter iota */, + {0x039a, 0xca} /* capital letter kappa */, + {0x039b, 0xcb} /* capital letter lamda */, + {0x039c, 0xcc} /* capital letter mu */, + {0x039d, 0xcd} /* capital letter nu */, + {0x039e, 0xce} /* capital letter xi */, + {0x039f, 0xcf} /* capital letter omicron */, + {0x03a0, 0xd0} /* capital letter pi */, + {0x03a1, 0xd1} /* capital letter rho */, + {0x03a3, 0xd3} /* capital letter sigma */, + {0x03a4, 0xd4} /* capital letter tau */, + {0x03a5, 0xd5} /* capital letter upsilon */, + {0x03a6, 0xd6} /* capital letter phi */, + {0x03a7, 0xd7} /* capital letter chi */, + {0x03a8, 0xd8} /* capital letter psi */, + {0x03a9, 0xd9} /* capital letter omega */, + {0x03aa, 0xda} /* capital letter iota with diaeresis */, + {0x03ab, 0xdb} /* capital letter upsilon with diaeresis */, + {0x03ac, 0xdc} /* small letter alpha with acute */, + {0x03ad, 0xdd} /* small letter epsilon with acute */, + {0x03ae, 0xde} /* small letter eta with acute */, + {0x03af, 0xdf} /* small letter iota with acute */, + {0x03b0, 0xe0} /* small letter upsilon with acute and diaeresis */, + {0x03b1, 0xe1} /* small letter alpha */, + {0x03b2, 0xe2} /* small letter beta */, + {0x03b3, 0xe3} /* small letter gamma */, + {0x03b4, 0xe4} /* small letter delta */, + {0x03b5, 0xe5} /* small letter epsilon */, + {0x03b6, 0xe6} /* small letter zeta */, + {0x03b7, 0xe7} /* small letter eta */, + {0x03b8, 0xe8} /* small letter theta */, + {0x03b9, 0xe9} /* small letter iota */, + {0x03ba, 0xea} /* small letter kappa */, + {0x03bb, 0xeb} /* small letter lamda */, + {0x03bc, 0xec} /* small letter mu */, + {0x03bd, 0xed} /* small letter nu */, + {0x03be, 0xee} /* small letter xi */, + {0x03bf, 0xef} /* small letter omicron */, + {0x03c0, 0xf0} /* small letter pi */, + {0x03c1, 0xf1} /* small letter rho */, + {0x03c2, 0xf2} /* small letter final sigma */, + {0x03c3, 0xf3} /* small letter sigma */, + {0x03c4, 0xf4} /* small letter tau */, + {0x03c5, 0xf5} /* small letter upsilon */, + {0x03c6, 0xf6} /* small letter phi */, + {0x03c7, 0xf7} /* small letter chi */, + {0x03c8, 0xf8} /* small letter psi */, + {0x03c9, 0xf9} /* small letter omega */, + {0x03ca, 0xfa} /* small letter iota with diaeresis */, + {0x03cb, 0xfb} /* small letter upsilon with diaeresis */, + {0x03cc, 0xfc} /* small letter omicron with acute */, + {0x03cd, 0xfd} /* small letter upsilon with acute */, + {0x03ce, 0xfe} /* small letter omega with acute */, + {0x2014, 0xaf} /* dash */, + {0x2019, 0xa2} /* single quotation mark */, + {0x201b, 0xa1} /* high-reversed-9 quotation mark */ +}; + +/* +#define cet_ucs4_to_iso_8859_7_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_7_extra[cet_ucs4_to_iso_8859_7_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_7 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_7, /* name of character set */ + cet_cs_alias_iso_8859_7, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_7, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_7, /* first non standard character */ + cet_ucs4_cnt_iso_8859_7, /* number of values in table */ + + cet_ucs4_to_iso_8859_7_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_7_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_7_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x201b, 0x2019, 0x00a3, -1, -1, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, -1, 0x00ab, 0x00ac, 0x00ad, -1, 0x2014, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x0385, 0x0386, 0x00b7, + 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + 0x03a0, 0x03a1, -1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, -1 +}; +*/ + +#endif diff --git a/cet/iso_8859_8.h b/cet/iso_8859_8.h new file mode 100644 index 000000000..e22f04a60 --- /dev/null +++ b/cet/iso_8859_8.h @@ -0,0 +1,156 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-8" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_8_h +#define iso_8859_8_h + +#define cet_cs_name_iso_8859_8 "ISO-8859-8" + +const char *cet_cs_alias_iso_8859_8[] = +{ + "ISO-8859-8", "csISOLatinHebrew", "hebrew", "ISO8859-8", + "iso-ir-138", "ISO_8859-8", "ISO_8859-8:1988", NULL +}; + +#define cet_ucs4_ofs_iso_8859_8 161 +#define cet_ucs4_cnt_iso_8859_8 90 + +const int cet_ucs4_map_iso_8859_8[cet_ucs4_cnt_iso_8859_8] = +{ + -1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, + 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x203e, 0x00b0, + 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, + 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0x2017, 0x05d0, + 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, + 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, 0x05e0, + 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, + 0x05e9, 0x05ea +}; + +#define cet_ucs4_to_iso_8859_8_ct 31 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_8_links[cet_ucs4_to_iso_8859_8_ct] = +{ + {0x00d7, 0xaa} /* sign */, + {0x00f7, 0xba} /* sign */, + {0x05d0, 0xe0} /* letter alef */, + {0x05d1, 0xe1} /* letter bet */, + {0x05d2, 0xe2} /* letter gimel */, + {0x05d3, 0xe3} /* letter dalet */, + {0x05d4, 0xe4} /* letter he */, + {0x05d5, 0xe5} /* letter vav */, + {0x05d6, 0xe6} /* letter zayin */, + {0x05d7, 0xe7} /* letter het */, + {0x05d8, 0xe8} /* letter tet */, + {0x05d9, 0xe9} /* letter yod */, + {0x05da, 0xea} /* letter final kaf */, + {0x05db, 0xeb} /* letter kaf */, + {0x05dc, 0xec} /* letter lamed */, + {0x05dd, 0xed} /* letter final mem */, + {0x05de, 0xee} /* letter mem */, + {0x05df, 0xef} /* letter final nun */, + {0x05e0, 0xf0} /* letter nun */, + {0x05e1, 0xf1} /* letter samekh */, + {0x05e2, 0xf2} /* letter ayin */, + {0x05e3, 0xf3} /* letter final pe */, + {0x05e4, 0xf4} /* letter pe */, + {0x05e5, 0xf5} /* letter final tsadi */, + {0x05e6, 0xf6} /* letter tsadi */, + {0x05e7, 0xf7} /* letter qof */, + {0x05e8, 0xf8} /* letter resh */, + {0x05e9, 0xf9} /* letter shin */, + {0x05ea, 0xfa} /* letter tav */, + {0x2017, 0xdf} /* low line */, + {0x203e, 0xaf} /* overline */ +}; + +/* +#define cet_ucs4_to_iso_8859_8_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_8_extra[cet_ucs4_to_iso_8859_8_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_8 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_8, /* name of character set */ + cet_cs_alias_iso_8859_8, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_8, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_8, /* first non standard character */ + cet_ucs4_cnt_iso_8859_8, /* number of values in table */ + + cet_ucs4_to_iso_8859_8_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_8_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_8_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, -1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x203e, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 0x2017, + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_8859_9.h b/cet/iso_8859_9.h new file mode 100644 index 000000000..4babb270b --- /dev/null +++ b/cet/iso_8859_9.h @@ -0,0 +1,129 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-9" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_9_h +#define iso_8859_9_h + +#define cet_cs_name_iso_8859_9 "ISO-8859-9" + +const char *cet_cs_alias_iso_8859_9[] = +{ + "ISO-8859-9", "csISOLatin5", "ISO8859-9", "iso-ir-148", + "ISO_8859-9", "ISO_8859-9:1989", "l5", "lat5", "latin5", + NULL +}; + +#define cet_ucs4_ofs_iso_8859_9 208 +#define cet_ucs4_cnt_iso_8859_9 48 + +const int cet_ucs4_map_iso_8859_9[cet_ucs4_cnt_iso_8859_9] = +{ + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff +}; + +#define cet_ucs4_to_iso_8859_9_ct 9 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_9_links[cet_ucs4_to_iso_8859_9_ct] = +{ + {0x0117, 0xec} /* small letter e with dot above */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x011e, 0xd0} /* capital letter g with breve */, + {0x011f, 0xf0} /* small letter g with breve */, + {0x012b, 0xef} /* small letter i with macron */, + {0x0130, 0xdd} /* capital letter i with dot above */, + {0x0131, 0xfd} /* small letter i dotless */, + {0x015e, 0xde} /* capital letter s with cedilla */, + {0x015f, 0xfe} /* small letter s with cedilla */ +}; + +/* +#define cet_ucs4_to_iso_8859_9_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_9_extra[cet_ucs4_to_iso_8859_9_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_9 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_9, /* name of character set */ + cet_cs_alias_iso_8859_9, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_9, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_9, /* first non standard character */ + cet_ucs4_cnt_iso_8859_9, /* number of values in table */ + + cet_ucs4_to_iso_8859_9_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_9_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_9_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff +}; +*/ + +#endif diff --git a/cet/iso_8859_supp.h b/cet/iso_8859_supp.h new file mode 100644 index 000000000..1c7f05724 --- /dev/null +++ b/cet/iso_8859_supp.h @@ -0,0 +1,212 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO_8859-supp" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_supp_h +#define iso_8859_supp_h + +#define cet_cs_name_iso_8859_supp "ISO_8859-supp" + +const char *cet_cs_alias_iso_8859_supp[] = +{ + "ISO_8859-supp", "iso-ir-154", "latin1-2-5", NULL +}; + +#define cet_ucs4_ofs_iso_8859_supp 160 +#define cet_ucs4_cnt_iso_8859_supp 96 + +const int cet_ucs4_map_iso_8859_supp[cet_ucs4_cnt_iso_8859_supp] = +{ + -1, -1, 0x0100, 0x0108, 0x010a, -1, 0x0116, 0x0112, + 0x011c, 0x2018, 0x201c, 0x2122, 0x2190, 0x2191, 0x2192, 0x2193, + -1, -1, 0x0101, 0x0109, 0x010b, 0x00f0, 0x0117, 0x0113, + 0x011d, 0x2019, 0x201d, 0x266a, 0x215b, 0x215c, 0x215d, 0x215e, + -1, 0x011e, 0x0120, 0x0122, 0x0124, 0x0126, 0x0128, 0x0130, + 0x012a, 0x012e, 0x0132, 0x0134, 0x0136, 0x013b, 0x013f, 0x0145, + 0x2014, 0x014a, 0x014c, 0x0152, 0x0156, 0x015c, 0x0166, 0x00de, + 0x0168, 0x016c, 0x016a, 0x0172, 0x0174, 0x00dd, 0x0176, 0x0178, + 0x2126, 0x011f, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0x0131, + 0x012b, 0x012f, 0x0133, 0x0135, 0x0137, 0x013c, 0x0140, 0x0146, + 0x0138, 0x014b, 0x014d, 0x0153, 0x0157, 0x015d, 0x0167, 0x00fe, + 0x0169, 0x016d, 0x016b, 0x0173, 0x0175, 0x00fd, 0x0177, 0x0149 +}; + +#define cet_ucs4_to_iso_8859_supp_ct 88 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_supp_links[cet_ucs4_to_iso_8859_supp_ct] = +{ + {0x00de, 0xd7} /* capital letter thorn (icelandic) */, + {0x00f0, 0xb5} /* small letter eth (icelandic) */, + {0x00fe, 0xf7} /* small letter thorn (icelandic) */, + {0x0100, 0xa2} /* capital letter a with macron */, + {0x0101, 0xb2} /* small letter a with macron */, + {0x0108, 0xa3} /* capital letter c with circumflex */, + {0x0109, 0xb3} /* small letter c with circumflex */, + {0x010a, 0xa4} /* capital letter c with dot above */, + {0x010b, 0xb4} /* small letter c with dot above */, + {0x0112, 0xa7} /* capital letter e with macron */, + {0x0113, 0xb7} /* small letter e with macron */, + {0x0116, 0xa6} /* capital letter e with dot above */, + {0x0117, 0xb6} /* small letter e with dot above */, + {0x011c, 0xa8} /* capital letter g with circumflex */, + {0x011d, 0xb8} /* small letter g with circumflex */, + {0x011e, 0xc1} /* capital letter g with breve */, + {0x011f, 0xe1} /* small letter g with breve */, + {0x0120, 0xc2} /* capital letter g with dot above */, + {0x0121, 0xe2} /* small letter g with dot above */, + {0x0122, 0xc3} /* capital letter g with cedilla */, + {0x0123, 0xe3} /* small letter g with cedilla */, + {0x0124, 0xc4} /* capital letter h with circumflex */, + {0x0125, 0xe4} /* small letter h with circumflex */, + {0x0126, 0xc5} /* capital letter h with stroke */, + {0x0127, 0xe5} /* small letter h with stroke */, + {0x0128, 0xc6} /* capital letter i with tilde */, + {0x0129, 0xe6} /* small letter i with tilde */, + {0x012a, 0xc8} /* capital letter i with macron */, + {0x012b, 0xe8} /* small letter i with macron */, + {0x012e, 0xc9} /* capital letter i with ogonek */, + {0x012f, 0xe9} /* small letter i with ogonek */, + {0x0130, 0xc7} /* capital letter i with dot above */, + {0x0131, 0xe7} /* small letter i dotless */, + {0x0132, 0xca} /* capital ligature ij */, + {0x0133, 0xea} /* small ligature ij */, + {0x0134, 0xcb} /* capital letter j with circumflex */, + {0x0135, 0xeb} /* small letter j with circumflex */, + {0x0136, 0xcc} /* capital letter k with cedilla */, + {0x0137, 0xec} /* small letter k with cedilla */, + {0x0138, 0xf0} /* small letter kra (greenlandic) */, + {0x013b, 0xcd} /* capital letter l with cedilla */, + {0x013c, 0xed} /* small letter l with cedilla */, + {0x013f, 0xce} /* capital letter l with middle dot */, + {0x0140, 0xee} /* small letter l with middle dot */, + {0x0145, 0xcf} /* capital letter n with cedilla */, + {0x0146, 0xef} /* small letter n with cedilla */, + {0x0149, 0xff} /* small letter n preceded by apostrophe */, + {0x014a, 0xd1} /* capital letter eng (lappish) */, + {0x014b, 0xf1} /* small letter eng (lappish) */, + {0x014c, 0xd2} /* capital letter o with macron */, + {0x014d, 0xf2} /* small letter o with macron */, + {0x0152, 0xd3} /* capital ligature oe */, + {0x0153, 0xf3} /* small ligature oe */, + {0x0156, 0xd4} /* capital letter r with cedilla */, + {0x0157, 0xf4} /* small letter r with cedilla */, + {0x015c, 0xd5} /* capital letter s with circumflex */, + {0x015d, 0xf5} /* small letter s with circumflex */, + {0x0166, 0xd6} /* capital letter t with stroke */, + {0x0167, 0xf6} /* small letter t with stroke */, + {0x0168, 0xd8} /* capital letter u with tilde */, + {0x0169, 0xf8} /* small letter u with tilde */, + {0x016a, 0xda} /* capital letter u with macron */, + {0x016b, 0xfa} /* small letter u with macron */, + {0x016c, 0xd9} /* capital letter u with breve */, + {0x016d, 0xf9} /* small letter u with breve */, + {0x0172, 0xdb} /* capital letter u with ogonek */, + {0x0173, 0xfb} /* small letter u with ogonek */, + {0x0174, 0xdc} /* capital letter w with circumflex */, + {0x0175, 0xfc} /* small letter w with circumflex */, + {0x0176, 0xde} /* capital letter y with circumflex */, + {0x0177, 0xfe} /* small letter y with circumflex */, + {0x0178, 0xdf} /* capital letter y with diaeresis */, + {0x2014, 0xd0} /* dash */, + {0x2018, 0xa9} /* single quotation mark */, + {0x2019, 0xb9} /* single quotation mark */, + {0x201c, 0xaa} /* double quotation mark */, + {0x201d, 0xba} /* double quotation mark */, + {0x2122, 0xab} /* mark sign */, + {0x2126, 0xe0} /* sign */, + {0x215b, 0xbc} /* fraction one eighth */, + {0x215c, 0xbd} /* fraction three eighths */, + {0x215d, 0xbe} /* fraction five eighths */, + {0x215e, 0xbf} /* fraction seven eighths */, + {0x2190, 0xac} /* arrow */, + {0x2191, 0xad} /* arrow */, + {0x2192, 0xae} /* arrow */, + {0x2193, 0xaf} /* arrow */, + {0x266a, 0xbb} /* note */ +}; + +/* +#define cet_ucs4_to_iso_8859_supp_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_supp_extra[cet_ucs4_to_iso_8859_supp_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_supp = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_supp, /* name of character set */ + cet_cs_alias_iso_8859_supp, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_supp, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_supp, /* first non standard character */ + cet_ucs4_cnt_iso_8859_supp, /* number of values in table */ + + cet_ucs4_to_iso_8859_supp_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_supp_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_supp_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + -1, -1, 0x0100, 0x0108, 0x010a, -1, 0x0116, 0x0112, + 0x011c, 0x2018, 0x201c, 0x2122, 0x2190, 0x2191, 0x2192, 0x2193, + -1, -1, 0x0101, 0x0109, 0x010b, 0x00f0, 0x0117, 0x0113, + 0x011d, 0x2019, 0x201d, 0x266a, 0x215b, 0x215c, 0x215d, 0x215e, + -1, 0x011e, 0x0120, 0x0122, 0x0124, 0x0126, 0x0128, 0x0130, + 0x012a, 0x012e, 0x0132, 0x0134, 0x0136, 0x013b, 0x013f, 0x0145, + 0x2014, 0x014a, 0x014c, 0x0152, 0x0156, 0x015c, 0x0166, 0x00de, + 0x0168, 0x016c, 0x016a, 0x0172, 0x0174, 0x00dd, 0x0176, 0x0178, + 0x2126, 0x011f, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0x0131, + 0x012b, 0x012f, 0x0133, 0x0135, 0x0137, 0x013c, 0x0140, 0x0146, + 0x0138, 0x014b, 0x014d, 0x0153, 0x0157, 0x015d, 0x0167, 0x00fe, + 0x0169, 0x016d, 0x016b, 0x0173, 0x0175, 0x00fd, 0x0177, 0x0149 +}; +*/ + +#endif diff --git a/cet/it.h b/cet/it.h new file mode 100644 index 000000000..178d100bf --- /dev/null +++ b/cet/it.h @@ -0,0 +1,134 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IT" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef it_h +#define it_h + +#define cet_cs_name_it "IT" + +const char *cet_cs_alias_it[] = +{ + "IT", "ISO646-IT", "iso-ir-15", NULL +}; + +#define cet_ucs4_ofs_it 35 +#define cet_ucs4_cnt_it 93 + +const int cet_ucs4_map_it[cet_ucs4_cnt_it] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x00a7, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x00b0, 0x00e7, 0x00e9, 0x005e, 0x005f, 0x00f9, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e0, 0x00f2, 0x00e8, 0x00ec, 0x007f +}; + +#define cet_ucs4_to_it_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_it_links[cet_ucs4_to_it_ct] = +{ + {0x00a3, 0x23} /* sign */, + {0x00a7, 0x40} /* sign */, + {0x00b0, 0x5b} /* sign */, + {0x00e0, 0x7b} /* small letter a with grave */, + {0x00e7, 0x5c} /* small letter c with cedilla */, + {0x00e8, 0x7d} /* small letter e with grave */, + {0x00e9, 0x5d} /* small letter e with acute */, + {0x00ec, 0x7e} /* small letter i with grave */, + {0x00f2, 0x7c} /* small letter o with grave */, + {0x00f9, 0x60} /* small letter u with grave */ +}; + +/* +#define cet_ucs4_to_it_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_it_extra[cet_ucs4_to_it_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_it = /* defined in cet.h */ +{ + cet_cs_name_it, /* name of character set */ + cet_cs_alias_it, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_it, /* char to UCS-4 value table */ + cet_ucs4_ofs_it, /* first non standard character */ + cet_ucs4_cnt_it, /* number of values in table */ + + cet_ucs4_to_it_links, /* UCS-4 to char links */ + cet_ucs4_to_it_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int it_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00b0, 0x00e7, 0x00e9, 0x005e, 0x005f, + 0x00f9, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e0, 0x00f2, 0x00e8, 0x00ec, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/jis_c6220_1969_ro.h b/cet/jis_c6220_1969_ro.h new file mode 100644 index 000000000..2227d0fcf --- /dev/null +++ b/cet/jis_c6220_1969_ro.h @@ -0,0 +1,120 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "JIS_C6220-1969-ro" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef jis_c6220_1969_ro_h +#define jis_c6220_1969_ro_h + +#define cet_cs_name_jis_c6220_1969_ro "JIS_C6220-1969-ro" + +const char *cet_cs_alias_jis_c6220_1969_ro[] = +{ + "JIS_C6220-1969-ro", "csISO14JISC6220ro", "ISO646-JP", "iso-ir-14", + "jp", NULL +}; + +#define cet_ucs4_ofs_jis_c6220_1969_ro 92 +#define cet_ucs4_cnt_jis_c6220_1969_ro 36 + +const int cet_ucs4_map_jis_c6220_1969_ro[cet_ucs4_cnt_jis_c6220_1969_ro] = +{ + 0x00a5, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x203e, 0x007f +}; + +#define cet_ucs4_to_jis_c6220_1969_ro_ct 2 + +const cet_ucs4_link_t cet_ucs4_to_jis_c6220_1969_ro_links[cet_ucs4_to_jis_c6220_1969_ro_ct] = +{ + {0x00a5, 0x5c} /* sign */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_jis_c6220_1969_ro_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_jis_c6220_1969_ro_extra[cet_ucs4_to_jis_c6220_1969_ro_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_jis_c6220_1969_ro = /* defined in cet.h */ +{ + cet_cs_name_jis_c6220_1969_ro, /* name of character set */ + cet_cs_alias_jis_c6220_1969_ro, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_jis_c6220_1969_ro, /* char to UCS-4 value table */ + cet_ucs4_ofs_jis_c6220_1969_ro, /* first non standard character */ + cet_ucs4_cnt_jis_c6220_1969_ro, /* number of values in table */ + + cet_ucs4_to_jis_c6220_1969_ro_links, /* UCS-4 to char links */ + cet_ucs4_to_jis_c6220_1969_ro_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int jis_c6220_1969_ro_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x00a5, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/jis_x0201.h b/cet/jis_x0201.h new file mode 100644 index 000000000..0675cb3ac --- /dev/null +++ b/cet/jis_x0201.h @@ -0,0 +1,195 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "JIS_X0201" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef jis_x0201_h +#define jis_x0201_h + +#define cet_cs_name_jis_x0201 "JIS_X0201" + +const char *cet_cs_alias_jis_x0201[] = +{ + "JIS_X0201", "csHalfWidthKatakana", "JIS0201", "JISX0201-1976", + "JISX0201.1976-0", "X0201", NULL +}; + +#define cet_ucs4_ofs_jis_x0201 92 +#define cet_ucs4_cnt_jis_x0201 132 + +const int cet_ucs4_map_jis_x0201[cet_ucs4_cnt_jis_x0201] = +{ + 0x00a5, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x203e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, + 0x009c, 0x009d, 0x009e, 0x009f, -1, 0x3002, 0x300c, 0x300d, + 0x3001, 0x30fb, 0x30f2, 0x30a1, 0x30a3, 0x30a5, 0x30a7, 0x30a9, + 0x30e3, 0x30e5, 0x30e7, 0x30c3, 0x30fc, 0x30a2, 0x30a4, 0x30a6, + 0x30a8, 0x30aa, 0x30ab, 0x30ad, 0x30af, 0x30b1, 0x30b3, 0x30b5, + 0x30b7, 0x30b9, 0x30bb, 0x30bd, 0x30bf, 0x30c1, 0x30c4, 0x30c6, + 0x30c8, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d2, + 0x30d5, 0x30d8, 0x30db, 0x30de, 0x30df, 0x30e0, 0x30e1, 0x30e2, + 0x30e4, 0x30e6, 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, + 0x30ef, 0x30f3, 0x309b, 0x309c +}; + +#define cet_ucs4_to_jis_x0201_ct 65 + +const cet_ucs4_link_t cet_ucs4_to_jis_x0201_links[cet_ucs4_to_jis_x0201_ct] = +{ + {0x00a5, 0x5c} /* sign */, + {0x203e, 0x7e} /* overline */, + {0x3001, 0xa4} /* comma */, + {0x3002, 0xa1} /* period */, + {0x300c, 0xa2} /* corner bracket */, + {0x300d, 0xa3} /* corner bracket */, + {0x309b, 0xde} /* voiced sound mark */, + {0x309c, 0xdf} /* semi-voiced sound mark */, + {0x30a1, 0xa7} /* letter small a */, + {0x30a2, 0xb1} /* letter a */, + {0x30a3, 0xa8} /* letter small i */, + {0x30a4, 0xb2} /* letter i */, + {0x30a5, 0xa9} /* letter small u */, + {0x30a6, 0xb3} /* letter u */, + {0x30a7, 0xaa} /* letter small e */, + {0x30a8, 0xb4} /* letter e */, + {0x30a9, 0xab} /* letter small o */, + {0x30aa, 0xb5} /* letter o */, + {0x30ab, 0xb6} /* letter ka */, + {0x30ad, 0xb7} /* letter ki */, + {0x30af, 0xb8} /* letter ku */, + {0x30b1, 0xb9} /* letter ke */, + {0x30b3, 0xba} /* letter ko */, + {0x30b5, 0xbb} /* letter sa */, + {0x30b7, 0xbc} /* letter si */, + {0x30b9, 0xbd} /* letter su */, + {0x30bb, 0xbe} /* letter se */, + {0x30bd, 0xbf} /* letter so */, + {0x30bf, 0xc0} /* letter ta */, + {0x30c1, 0xc1} /* letter ti */, + {0x30c3, 0xaf} /* letter small tu */, + {0x30c4, 0xc2} /* letter tu */, + {0x30c6, 0xc3} /* letter te */, + {0x30c8, 0xc4} /* letter to */, + {0x30ca, 0xc5} /* letter na */, + {0x30cb, 0xc6} /* letter ni */, + {0x30cc, 0xc7} /* letter nu */, + {0x30cd, 0xc8} /* letter ne */, + {0x30ce, 0xc9} /* letter no */, + {0x30cf, 0xca} /* letter ha */, + {0x30d2, 0xcb} /* letter hi */, + {0x30d5, 0xcc} /* letter hu */, + {0x30d8, 0xcd} /* letter he */, + {0x30db, 0xce} /* letter ho */, + {0x30de, 0xcf} /* letter ma */, + {0x30df, 0xd0} /* letter mi */, + {0x30e0, 0xd1} /* letter mu */, + {0x30e1, 0xd2} /* letter me */, + {0x30e2, 0xd3} /* letter mo */, + {0x30e3, 0xac} /* letter small ya */, + {0x30e4, 0xd4} /* letter ya */, + {0x30e5, 0xad} /* letter small yu */, + {0x30e6, 0xd5} /* letter yu */, + {0x30e7, 0xae} /* letter small yo */, + {0x30e8, 0xd6} /* letter yo */, + {0x30e9, 0xd7} /* letter ra */, + {0x30ea, 0xd8} /* letter ri */, + {0x30eb, 0xd9} /* letter ru */, + {0x30ec, 0xda} /* letter re */, + {0x30ed, 0xdb} /* letter ro */, + {0x30ef, 0xdc} /* letter wa */, + {0x30f2, 0xa6} /* letter wo */, + {0x30f3, 0xdd} /* letter n */, + {0x30fb, 0xa5} /* middle dot */, + {0x30fc, 0xb0} /* prolonged sound mark */ +}; + +/* +#define cet_ucs4_to_jis_x0201_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_jis_x0201_extra[cet_ucs4_to_jis_x0201_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_jis_x0201 = /* defined in cet.h */ +{ + cet_cs_name_jis_x0201, /* name of character set */ + cet_cs_alias_jis_x0201, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_jis_x0201, /* char to UCS-4 value table */ + cet_ucs4_ofs_jis_x0201, /* first non standard character */ + cet_ucs4_cnt_jis_x0201, /* number of values in table */ + + cet_ucs4_to_jis_x0201_links, /* UCS-4 to char links */ + cet_ucs4_to_jis_x0201_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int jis_x0201_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x00a5, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + -1, 0x3002, 0x300c, 0x300d, 0x3001, 0x30fb, 0x30f2, 0x30a1, + 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, + 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, + 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, + 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, + 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, + 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, + 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/jus_i_b1_002.h b/cet/jus_i_b1_002.h new file mode 100644 index 000000000..fc8c7e936 --- /dev/null +++ b/cet/jus_i_b1_002.h @@ -0,0 +1,131 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "JUS_I.B1.002" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef jus_i_b1_002_h +#define jus_i_b1_002_h + +#define cet_cs_name_jus_i_b1_002 "JUS_I.B1.002" + +const char *cet_cs_alias_jus_i_b1_002[] = +{ + "JUS_I.B1.002", "ISO646-YU", "iso-ir-141", "js", + "yu", NULL +}; + +#define cet_ucs4_ofs_jus_i_b1_002 64 +#define cet_ucs4_cnt_jus_i_b1_002 64 + +const int cet_ucs4_map_jus_i_b1_002[cet_ucs4_cnt_jus_i_b1_002] = +{ + 0x017d, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x0160, 0x0110, 0x0106, 0x010c, 0x005f, + 0x017e, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x0161, 0x0111, 0x0107, 0x010d, 0x007f +}; + +#define cet_ucs4_to_jus_i_b1_002_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_002_links[cet_ucs4_to_jus_i_b1_002_ct] = +{ + {0x0106, 0x5d} /* capital letter c with acute */, + {0x0107, 0x7d} /* small letter c with acute */, + {0x010c, 0x5e} /* capital letter c with caron */, + {0x010d, 0x7e} /* small letter c with caron */, + {0x0110, 0x5c} /* capital letter d with stroke */, + {0x0111, 0x7c} /* small letter d with stroke */, + {0x0160, 0x5b} /* capital letter s with caron */, + {0x0161, 0x7b} /* small letter s with caron */, + {0x017d, 0x40} /* capital letter z with caron */, + {0x017e, 0x60} /* small letter z with caron */ +}; + +/* +#define cet_ucs4_to_jus_i_b1_002_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_002_extra[cet_ucs4_to_jus_i_b1_002_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_jus_i_b1_002 = /* defined in cet.h */ +{ + cet_cs_name_jus_i_b1_002, /* name of character set */ + cet_cs_alias_jus_i_b1_002, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_jus_i_b1_002, /* char to UCS-4 value table */ + cet_ucs4_ofs_jus_i_b1_002, /* first non standard character */ + cet_ucs4_cnt_jus_i_b1_002, /* number of values in table */ + + cet_ucs4_to_jus_i_b1_002_links, /* UCS-4 to char links */ + cet_ucs4_to_jus_i_b1_002_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int jus_i_b1_002_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x017d, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x0160, 0x0110, 0x0106, 0x010c, 0x005f, + 0x017e, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x0161, 0x0111, 0x0107, 0x010d, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/jus_i_b1_003_mac.h b/cet/jus_i_b1_003_mac.h new file mode 100644 index 000000000..7082a0d43 --- /dev/null +++ b/cet/jus_i_b1_003_mac.h @@ -0,0 +1,182 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "JUS_I.B1.003-mac" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef jus_i_b1_003_mac_h +#define jus_i_b1_003_mac_h + +#define cet_cs_name_jus_i_b1_003_mac "JUS_I.B1.003-mac" + +const char *cet_cs_alias_jus_i_b1_003_mac[] = +{ + "JUS_I.B1.003-mac", "iso-ir-147", "macedonian", NULL +}; + +#define cet_ucs4_ofs_jus_i_b1_003_mac 64 +#define cet_ucs4_cnt_jus_i_b1_003_mac 64 + +const int cet_ucs4_map_jus_i_b1_003_mac[cet_ucs4_cnt_jus_i_b1_003_mac] = +{ + 0x0416, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0408, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0409, 0x0420, 0x0421, 0x0422, 0x0423, 0x0412, 0x040a, + 0x040f, 0x0405, 0x0417, 0x0428, 0x0403, 0x040c, 0x0427, 0x005f, + 0x0436, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0458, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0459, 0x0440, 0x0441, 0x0442, 0x0443, 0x0432, 0x045a, + 0x045f, 0x0455, 0x0437, 0x0448, 0x0453, 0x045c, 0x0447, 0x007f +}; + +#define cet_ucs4_to_jus_i_b1_003_mac_ct 62 + +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_003_mac_links[cet_ucs4_to_jus_i_b1_003_mac_ct] = +{ + {0x0403, 0x5c} /* capital letter gje (macedonian) */, + {0x0405, 0x59} /* capital letter dze (macedonian) */, + {0x0408, 0x4a} /* capital letter je */, + {0x0409, 0x51} /* capital letter lje */, + {0x040a, 0x57} /* capital letter nje */, + {0x040c, 0x5d} /* capital letter kje (macedonian) */, + {0x040f, 0x58} /* capital letter dzhe */, + {0x0410, 0x41} /* capital letter a */, + {0x0411, 0x42} /* capital letter be */, + {0x0412, 0x56} /* capital letter ve */, + {0x0413, 0x47} /* capital letter ghe */, + {0x0414, 0x44} /* capital letter de */, + {0x0415, 0x45} /* capital letter ie */, + {0x0416, 0x40} /* capital letter zhe */, + {0x0417, 0x5a} /* capital letter ze */, + {0x0418, 0x49} /* capital letter i */, + {0x041a, 0x4b} /* capital letter ka */, + {0x041b, 0x4c} /* capital letter el */, + {0x041c, 0x4d} /* capital letter em */, + {0x041d, 0x4e} /* capital letter en */, + {0x041e, 0x4f} /* capital letter o */, + {0x041f, 0x50} /* capital letter pe */, + {0x0420, 0x52} /* capital letter er */, + {0x0421, 0x53} /* capital letter es */, + {0x0422, 0x54} /* capital letter te */, + {0x0423, 0x55} /* capital letter u */, + {0x0424, 0x46} /* capital letter ef */, + {0x0425, 0x48} /* capital letter ha */, + {0x0426, 0x43} /* capital letter tse */, + {0x0427, 0x5e} /* capital letter che */, + {0x0428, 0x5b} /* capital letter sha */, + {0x0430, 0x61} /* small letter a */, + {0x0431, 0x62} /* small letter be */, + {0x0432, 0x76} /* small letter ve */, + {0x0433, 0x67} /* small letter ghe */, + {0x0434, 0x64} /* small letter de */, + {0x0435, 0x65} /* small letter ie */, + {0x0436, 0x60} /* small letter zhe */, + {0x0437, 0x7a} /* small letter ze */, + {0x0438, 0x69} /* small letter i */, + {0x043a, 0x6b} /* small letter ka */, + {0x043b, 0x6c} /* small letter el */, + {0x043c, 0x6d} /* small letter em */, + {0x043d, 0x6e} /* small letter en */, + {0x043e, 0x6f} /* small letter o */, + {0x043f, 0x70} /* small letter pe */, + {0x0440, 0x72} /* small letter er */, + {0x0441, 0x73} /* small letter es */, + {0x0442, 0x74} /* small letter te */, + {0x0443, 0x75} /* small letter u */, + {0x0444, 0x66} /* small letter ef */, + {0x0445, 0x68} /* small letter ha */, + {0x0446, 0x63} /* small letter tse */, + {0x0447, 0x7e} /* small letter che */, + {0x0448, 0x7b} /* small letter sha */, + {0x0453, 0x7c} /* small letter gje (macedonian) */, + {0x0455, 0x79} /* small letter dze (macedonian) */, + {0x0458, 0x6a} /* small letter je */, + {0x0459, 0x71} /* small letter lje */, + {0x045a, 0x77} /* small letter nje */, + {0x045c, 0x7d} /* small letter kje (macedonian) */, + {0x045f, 0x78} /* small letter dzhe */ +}; + +/* +#define cet_ucs4_to_jus_i_b1_003_mac_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_003_mac_extra[cet_ucs4_to_jus_i_b1_003_mac_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_jus_i_b1_003_mac = /* defined in cet.h */ +{ + cet_cs_name_jus_i_b1_003_mac, /* name of character set */ + cet_cs_alias_jus_i_b1_003_mac, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_jus_i_b1_003_mac, /* char to UCS-4 value table */ + cet_ucs4_ofs_jus_i_b1_003_mac, /* first non standard character */ + cet_ucs4_cnt_jus_i_b1_003_mac, /* number of values in table */ + + cet_ucs4_to_jus_i_b1_003_mac_links, /* UCS-4 to char links */ + cet_ucs4_to_jus_i_b1_003_mac_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int jus_i_b1_003_mac_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0416, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0408, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0409, 0x0420, 0x0421, 0x0422, 0x0423, 0x0412, 0x040a, + 0x040f, 0x0405, 0x0417, 0x0428, 0x0403, 0x040c, 0x0427, 0x005f, + 0x0436, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0458, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0459, 0x0440, 0x0441, 0x0442, 0x0443, 0x0432, 0x045a, + 0x045f, 0x0455, 0x0437, 0x0448, 0x0453, 0x045c, 0x0447, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/jus_i_b1_003_serb.h b/cet/jus_i_b1_003_serb.h new file mode 100644 index 000000000..10b81f1ec --- /dev/null +++ b/cet/jus_i_b1_003_serb.h @@ -0,0 +1,182 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "JUS_I.B1.003-serb" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef jus_i_b1_003_serb_h +#define jus_i_b1_003_serb_h + +#define cet_cs_name_jus_i_b1_003_serb "JUS_I.B1.003-serb" + +const char *cet_cs_alias_jus_i_b1_003_serb[] = +{ + "JUS_I.B1.003-serb", "iso-ir-146", "serbian", NULL +}; + +#define cet_ucs4_ofs_jus_i_b1_003_serb 64 +#define cet_ucs4_cnt_jus_i_b1_003_serb 64 + +const int cet_ucs4_map_jus_i_b1_003_serb[cet_ucs4_cnt_jus_i_b1_003_serb] = +{ + 0x0416, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0408, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0409, 0x0420, 0x0421, 0x0422, 0x0423, 0x0412, 0x040a, + 0x040f, 0x0405, 0x0417, 0x0428, 0x0402, 0x040b, 0x0427, 0x005f, + 0x0436, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0458, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0459, 0x0440, 0x0441, 0x0442, 0x0443, 0x0432, 0x045a, + 0x045f, 0x0455, 0x0437, 0x0448, 0x0452, 0x045b, 0x0447, 0x007f +}; + +#define cet_ucs4_to_jus_i_b1_003_serb_ct 62 + +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_003_serb_links[cet_ucs4_to_jus_i_b1_003_serb_ct] = +{ + {0x0402, 0x5c} /* capital letter dje (serbocroatian) */, + {0x0405, 0x59} /* capital letter dze (macedonian) */, + {0x0408, 0x4a} /* capital letter je */, + {0x0409, 0x51} /* capital letter lje */, + {0x040a, 0x57} /* capital letter nje */, + {0x040b, 0x5d} /* capital letter tshe (serbocroatian) */, + {0x040f, 0x58} /* capital letter dzhe */, + {0x0410, 0x41} /* capital letter a */, + {0x0411, 0x42} /* capital letter be */, + {0x0412, 0x56} /* capital letter ve */, + {0x0413, 0x47} /* capital letter ghe */, + {0x0414, 0x44} /* capital letter de */, + {0x0415, 0x45} /* capital letter ie */, + {0x0416, 0x40} /* capital letter zhe */, + {0x0417, 0x5a} /* capital letter ze */, + {0x0418, 0x49} /* capital letter i */, + {0x041a, 0x4b} /* capital letter ka */, + {0x041b, 0x4c} /* capital letter el */, + {0x041c, 0x4d} /* capital letter em */, + {0x041d, 0x4e} /* capital letter en */, + {0x041e, 0x4f} /* capital letter o */, + {0x041f, 0x50} /* capital letter pe */, + {0x0420, 0x52} /* capital letter er */, + {0x0421, 0x53} /* capital letter es */, + {0x0422, 0x54} /* capital letter te */, + {0x0423, 0x55} /* capital letter u */, + {0x0424, 0x46} /* capital letter ef */, + {0x0425, 0x48} /* capital letter ha */, + {0x0426, 0x43} /* capital letter tse */, + {0x0427, 0x5e} /* capital letter che */, + {0x0428, 0x5b} /* capital letter sha */, + {0x0430, 0x61} /* small letter a */, + {0x0431, 0x62} /* small letter be */, + {0x0432, 0x76} /* small letter ve */, + {0x0433, 0x67} /* small letter ghe */, + {0x0434, 0x64} /* small letter de */, + {0x0435, 0x65} /* small letter ie */, + {0x0436, 0x60} /* small letter zhe */, + {0x0437, 0x7a} /* small letter ze */, + {0x0438, 0x69} /* small letter i */, + {0x043a, 0x6b} /* small letter ka */, + {0x043b, 0x6c} /* small letter el */, + {0x043c, 0x6d} /* small letter em */, + {0x043d, 0x6e} /* small letter en */, + {0x043e, 0x6f} /* small letter o */, + {0x043f, 0x70} /* small letter pe */, + {0x0440, 0x72} /* small letter er */, + {0x0441, 0x73} /* small letter es */, + {0x0442, 0x74} /* small letter te */, + {0x0443, 0x75} /* small letter u */, + {0x0444, 0x66} /* small letter ef */, + {0x0445, 0x68} /* small letter ha */, + {0x0446, 0x63} /* small letter tse */, + {0x0447, 0x7e} /* small letter che */, + {0x0448, 0x7b} /* small letter sha */, + {0x0452, 0x7c} /* small letter dje (serbocroatian) */, + {0x0455, 0x79} /* small letter dze (macedonian) */, + {0x0458, 0x6a} /* small letter je */, + {0x0459, 0x71} /* small letter lje */, + {0x045a, 0x77} /* small letter nje */, + {0x045b, 0x7d} /* small letter tshe (serbocroatian) */, + {0x045f, 0x78} /* small letter dzhe */ +}; + +/* +#define cet_ucs4_to_jus_i_b1_003_serb_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_003_serb_extra[cet_ucs4_to_jus_i_b1_003_serb_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_jus_i_b1_003_serb = /* defined in cet.h */ +{ + cet_cs_name_jus_i_b1_003_serb, /* name of character set */ + cet_cs_alias_jus_i_b1_003_serb, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_jus_i_b1_003_serb, /* char to UCS-4 value table */ + cet_ucs4_ofs_jus_i_b1_003_serb, /* first non standard character */ + cet_ucs4_cnt_jus_i_b1_003_serb, /* number of values in table */ + + cet_ucs4_to_jus_i_b1_003_serb_links, /* UCS-4 to char links */ + cet_ucs4_to_jus_i_b1_003_serb_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int jus_i_b1_003_serb_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0416, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0408, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0409, 0x0420, 0x0421, 0x0422, 0x0423, 0x0412, 0x040a, + 0x040f, 0x0405, 0x0417, 0x0428, 0x0402, 0x040b, 0x0427, 0x005f, + 0x0436, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0458, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0459, 0x0440, 0x0441, 0x0442, 0x0443, 0x0432, 0x045a, + 0x045f, 0x0455, 0x0437, 0x0448, 0x0452, 0x045b, 0x0447, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/keybcs2.h b/cet/keybcs2.h new file mode 100644 index 000000000..29b0cbb1b --- /dev/null +++ b/cet/keybcs2.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KEYBCS2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef keybcs2_h +#define keybcs2_h + +#define cet_cs_name_keybcs2 "KEYBCS2" + +const char *cet_cs_alias_keybcs2[] = +{ + "KEYBCS2", "Kamenicky", NULL +}; + +#define cet_ucs4_ofs_keybcs2 128 +#define cet_ucs4_cnt_keybcs2 128 + +const int cet_ucs4_map_keybcs2[cet_ucs4_cnt_keybcs2] = +{ + 0x010c, 0x00fc, 0x00e9, 0x010f, 0x00e4, 0x010e, 0x0164, 0x010d, + 0x011b, 0x011a, 0x0139, 0x00cd, 0x013e, 0x013a, 0x00c4, 0x00c1, + 0x00c9, 0x017e, 0x017d, 0x00f4, 0x00f6, 0x00d3, 0x016f, 0x00da, + 0x00fd, 0x00d6, 0x00dc, 0x0160, 0x013d, 0x00dd, 0x0158, 0x0165, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x0148, 0x0147, 0x016e, 0x00d4, + 0x0161, 0x0159, 0x0155, 0x0154, 0x00bc, 0x00a7, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x03bc, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2219, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_keybcs2_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_keybcs2_links[cet_ucs4_to_keybcs2_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a7, 0xad} /* sign */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b7, 0xf9} /* dot */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00c1, 0x8f} /* capital letter a with acute */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00cd, 0x8b} /* capital letter i with acute */, + {0x00d3, 0x95} /* capital letter o with acute */, + {0x00d4, 0xa7} /* capital letter o with circumflex */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00da, 0x97} /* capital letter u with acute */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00dd, 0x9d} /* capital letter y with acute */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00fd, 0x98} /* small letter y with acute */, + {0x010c, 0x80} /* capital letter c with caron */, + {0x010d, 0x87} /* small letter c with caron */, + {0x010e, 0x85} /* capital letter d with caron */, + {0x010f, 0x83} /* small letter d with caron */, + {0x011a, 0x89} /* capital letter e with caron */, + {0x011b, 0x88} /* small letter e with caron */, + {0x0139, 0x8a} /* capital letter l with acute */, + {0x013a, 0x8d} /* small letter l with acute */, + {0x013d, 0x9c} /* capital letter l with caron */, + {0x013e, 0x8c} /* small letter l with caron */, + {0x0147, 0xa5} /* capital letter n with caron */, + {0x0148, 0xa4} /* small letter n with caron */, + {0x0154, 0xab} /* capital letter r with acute */, + {0x0155, 0xaa} /* small letter r with acute */, + {0x0158, 0x9e} /* capital letter r with caron */, + {0x0159, 0xa9} /* small letter r with caron */, + {0x0160, 0x9b} /* capital letter s with caron */, + {0x0161, 0xa8} /* small letter s with caron */, + {0x0164, 0x86} /* capital letter t with caron */, + {0x0165, 0x9f} /* small letter t with caron */, + {0x016e, 0xa6} /* capital letter u with ring above */, + {0x016f, 0x96} /* small letter u with ring above */, + {0x017d, 0x92} /* capital letter z with caron */, + {0x017e, 0x91} /* small letter z with caron */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b2, 0xe1} /* small letter beta */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03bc, 0xe6} /* small letter mu */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x207f, 0xfc} /* latin small letter n */, + {0x2205, 0xed} /* set */, + {0x2218, 0xf8} /* operator */, + {0x2219, 0xfa} /* operator */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_keybcs2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_keybcs2_extra[cet_ucs4_to_keybcs2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_keybcs2 = /* defined in cet.h */ +{ + cet_cs_name_keybcs2, /* name of character set */ + cet_cs_alias_keybcs2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_keybcs2, /* char to UCS-4 value table */ + cet_ucs4_ofs_keybcs2, /* first non standard character */ + cet_ucs4_cnt_keybcs2, /* number of values in table */ + + cet_ucs4_to_keybcs2_links, /* UCS-4 to char links */ + cet_ucs4_to_keybcs2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int keybcs2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x010c, 0x00fc, 0x00e9, 0x010f, 0x00e4, 0x010e, 0x0164, 0x010d, + 0x011b, 0x011a, 0x0139, 0x00cd, 0x013e, 0x013a, 0x00c4, 0x00c1, + 0x00c9, 0x017e, 0x017d, 0x00f4, 0x00f6, 0x00d3, 0x016f, 0x00da, + 0x00fd, 0x00d6, 0x00dc, 0x0160, 0x013d, 0x00dd, 0x0158, 0x0165, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x0148, 0x0147, 0x016e, 0x00d4, + 0x0161, 0x0159, 0x0155, 0x0154, 0x00bc, 0x00a7, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x03bc, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2219, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/koi8_r.h b/cet/koi8_r.h new file mode 100644 index 000000000..36f63e453 --- /dev/null +++ b/cet/koi8_r.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI8-R" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi8_r_h +#define koi8_r_h + +#define cet_cs_name_koi8_r "KOI8-R" + +const char *cet_cs_alias_koi8_r[] = +{ + "KOI8-R", "csKOI8R", NULL +}; + +#define cet_ucs4_ofs_koi8_r 128 +#define cet_ucs4_cnt_koi8_r 128 + +const int cet_ucs4_map_koi8_r[cet_ucs4_cnt_koi8_r] = +{ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2022, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; + +#define cet_ucs4_to_koi8_r_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_koi8_r_links[cet_ucs4_to_koi8_r_ct] = +{ + {0x00a0, 0x9a} /* space */, + {0x00a9, 0xbf} /* sign */, + {0x00b0, 0x9c} /* sign */, + {0x00b2, 0x9d} /* two */, + {0x00b7, 0x9e} /* dot */, + {0x00f7, 0x9f} /* sign */, + {0x0401, 0xb3} /* capital letter io */, + {0x0410, 0xe1} /* capital letter a */, + {0x0411, 0xe2} /* capital letter be */, + {0x0412, 0xf7} /* capital letter ve */, + {0x0413, 0xe7} /* capital letter ghe */, + {0x0414, 0xe4} /* capital letter de */, + {0x0415, 0xe5} /* capital letter ie */, + {0x0416, 0xf6} /* capital letter zhe */, + {0x0417, 0xfa} /* capital letter ze */, + {0x0418, 0xe9} /* capital letter i */, + {0x0419, 0xea} /* capital letter short i */, + {0x041a, 0xeb} /* capital letter ka */, + {0x041b, 0xec} /* capital letter el */, + {0x041c, 0xed} /* capital letter em */, + {0x041d, 0xee} /* capital letter en */, + {0x041e, 0xef} /* capital letter o */, + {0x041f, 0xf0} /* capital letter pe */, + {0x0420, 0xf2} /* capital letter er */, + {0x0421, 0xf3} /* capital letter es */, + {0x0422, 0xf4} /* capital letter te */, + {0x0423, 0xf5} /* capital letter u */, + {0x0424, 0xe6} /* capital letter ef */, + {0x0425, 0xe8} /* capital letter ha */, + {0x0426, 0xe3} /* capital letter tse */, + {0x0427, 0xfe} /* capital letter che */, + {0x0428, 0xfb} /* capital letter sha */, + {0x0429, 0xfd} /* capital letter shcha */, + {0x042a, 0xff} /* capital letter hard sign */, + {0x042b, 0xf9} /* capital letter yeru */, + {0x042c, 0xf8} /* capital letter soft sign */, + {0x042d, 0xfc} /* capital letter e */, + {0x042e, 0xe0} /* capital letter yu */, + {0x042f, 0xf1} /* capital letter ya */, + {0x0430, 0xc1} /* small letter a */, + {0x0431, 0xc2} /* small letter be */, + {0x0432, 0xd7} /* small letter ve */, + {0x0433, 0xc7} /* small letter ghe */, + {0x0434, 0xc4} /* small letter de */, + {0x0435, 0xc5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xda} /* small letter ze */, + {0x0438, 0xc9} /* small letter i */, + {0x0439, 0xca} /* small letter short i */, + {0x043a, 0xcb} /* small letter ka */, + {0x043b, 0xcc} /* small letter el */, + {0x043c, 0xcd} /* small letter em */, + {0x043d, 0xce} /* small letter en */, + {0x043e, 0xcf} /* small letter o */, + {0x043f, 0xd0} /* small letter pe */, + {0x0440, 0xd2} /* small letter er */, + {0x0441, 0xd3} /* small letter es */, + {0x0442, 0xd4} /* small letter te */, + {0x0443, 0xd5} /* small letter u */, + {0x0444, 0xc6} /* small letter ef */, + {0x0445, 0xc8} /* small letter ha */, + {0x0446, 0xc3} /* small letter tse */, + {0x0447, 0xde} /* small letter che */, + {0x0448, 0xdb} /* small letter sha */, + {0x0449, 0xdd} /* small letter shcha */, + {0x044a, 0xdf} /* small letter hard sign */, + {0x044b, 0xd9} /* small letter yeru */, + {0x044c, 0xd8} /* small letter soft sign */, + {0x044d, 0xdc} /* small letter e */, + {0x044e, 0xc0} /* small letter yu */, + {0x044f, 0xd1} /* small letter ya */, + {0x0451, 0xa3} /* small letter io */, + {0x2022, 0x95} /* puce */, + {0x221a, 0x96} /* root */, + {0x2248, 0x97} /* equal to */, + {0x2264, 0x98} /* or equal to */, + {0x2265, 0x99} /* or equal to */, + {0x2320, 0x93} /* half integral */, + {0x2321, 0x9b} /* half integral */, + {0x2500, 0x80} /* drawings light horizontal */, + {0x2502, 0x81} /* drawings light vertical */, + {0x250c, 0x82} /* drawings light down and right */, + {0x2510, 0x83} /* drawings light down and left */, + {0x2514, 0x84} /* drawings light up and right */, + {0x2518, 0x85} /* drawings light up and left */, + {0x251c, 0x86} /* drawings light vertical and right */, + {0x2524, 0x87} /* drawings light vertical and left */, + {0x252c, 0x88} /* drawings light down and horizontal */, + {0x2534, 0x89} /* drawings light up and horizontal */, + {0x253c, 0x8a} /* drawings light vertical and horizontal */, + {0x2550, 0xa0} /* drawings heavy horizontal */, + {0x2551, 0xa1} /* drawings heavy vertical */, + {0x2552, 0xa2} /* drawings down light and right heavy */, + {0x2553, 0xa4} /* drawings down heavy and right light */, + {0x2554, 0xa5} /* drawings heavy down and right */, + {0x2555, 0xa6} /* drawings down light and left heavy */, + {0x2556, 0xa7} /* drawings down heavy and left light */, + {0x2557, 0xa8} /* drawings heavy down and left */, + {0x2558, 0xa9} /* drawings up light and right heavy */, + {0x2559, 0xaa} /* drawings up heavy and right light */, + {0x255a, 0xab} /* drawings heavy up and right */, + {0x255b, 0xac} /* drawings up light and left heavy */, + {0x255c, 0xad} /* drawings up heavy and left light */, + {0x255d, 0xae} /* drawings heavy up and left */, + {0x255e, 0xaf} /* drawings vertical light and right heavy */, + {0x255f, 0xb0} /* drawings vertical heavy and right light */, + {0x2560, 0xb1} /* drawings heavy vertical and right */, + {0x2561, 0xb2} /* drawings vertical light and left heavy */, + {0x2562, 0xb4} /* drawings vertical heavy and left light */, + {0x2563, 0xb5} /* drawings heavy vertical and left */, + {0x2564, 0xb6} /* drawings down light and horizontal heavy */, + {0x2565, 0xb7} /* drawings down heavy and horizontal light */, + {0x2566, 0xb8} /* drawings heavy down and horizontal */, + {0x2567, 0xb9} /* drawings up light and horizontal heavy */, + {0x2568, 0xba} /* drawings up heavy and horizontal light */, + {0x2569, 0xbb} /* drawings heavy up and horizontal */, + {0x256a, 0xbc} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xbd} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xbe} /* drawings heavy vertical and horizontal */, + {0x2580, 0x8b} /* half block */, + {0x2584, 0x8c} /* half block */, + {0x2588, 0x8d} /* block */, + {0x258c, 0x8e} /* half block */, + {0x2590, 0x8f} /* half block */, + {0x2591, 0x90} /* shade */, + {0x2592, 0x91} /* shade */, + {0x2593, 0x92} /* shade */, + {0x25a0, 0x94} /* square */ +}; + +/* +#define cet_ucs4_to_koi8_r_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi8_r_extra[cet_ucs4_to_koi8_r_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi8_r = /* defined in cet.h */ +{ + cet_cs_name_koi8_r, /* name of character set */ + cet_cs_alias_koi8_r, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi8_r, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi8_r, /* first non standard character */ + cet_ucs4_cnt_koi8_r, /* number of values in table */ + + cet_ucs4_to_koi8_r_links, /* UCS-4 to char links */ + cet_ucs4_to_koi8_r_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi8_r_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2022, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; +*/ + +#endif diff --git a/cet/koi8_ru.h b/cet/koi8_ru.h new file mode 100644 index 000000000..7800847bc --- /dev/null +++ b/cet/koi8_ru.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI8-RU" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi8_ru_h +#define koi8_ru_h + +#define cet_cs_name_koi8_ru "KOI8-RU" + +const char *cet_cs_alias_koi8_ru[] = +{ + "KOI8-RU", NULL +}; + +#define cet_ucs4_ofs_koi8_ru 128 +#define cet_ucs4_cnt_koi8_ru 128 + +const int cet_ucs4_map_koi8_ru[cet_ucs4_cnt_koi8_ru] = +{ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x201c, 0x25a0, 0x2022, 0x201d, 0x2014, + 0x2116, 0x2122, 0x00a0, 0x00bb, 0x00ae, 0x00ab, 0x00b7, 0x00a4, + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x045e, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x040e, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; + +#define cet_ucs4_to_koi8_ru_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_koi8_ru_links[cet_ucs4_to_koi8_ru_ct] = +{ + {0x00a0, 0x9a} /* space */, + {0x00a4, 0x9f} /* sign */, + {0x00a9, 0xbf} /* sign */, + {0x00ab, 0x9d} /* double angle quotation mark */, + {0x00ae, 0x9c} /* sign */, + {0x00b7, 0x9e} /* dot */, + {0x00bb, 0x9b} /* double angle quotation mark */, + {0x0401, 0xb3} /* capital letter io */, + {0x0404, 0xb4} /* capital letter ukrainian ie */, + {0x0406, 0xb6} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0xb7} /* capital letter yi (ukrainian) */, + {0x040e, 0xbe} /* capital letter short u (byelorussian) */, + {0x0410, 0xe1} /* capital letter a */, + {0x0411, 0xe2} /* capital letter be */, + {0x0412, 0xf7} /* capital letter ve */, + {0x0413, 0xe7} /* capital letter ghe */, + {0x0414, 0xe4} /* capital letter de */, + {0x0415, 0xe5} /* capital letter ie */, + {0x0416, 0xf6} /* capital letter zhe */, + {0x0417, 0xfa} /* capital letter ze */, + {0x0418, 0xe9} /* capital letter i */, + {0x0419, 0xea} /* capital letter short i */, + {0x041a, 0xeb} /* capital letter ka */, + {0x041b, 0xec} /* capital letter el */, + {0x041c, 0xed} /* capital letter em */, + {0x041d, 0xee} /* capital letter en */, + {0x041e, 0xef} /* capital letter o */, + {0x041f, 0xf0} /* capital letter pe */, + {0x0420, 0xf2} /* capital letter er */, + {0x0421, 0xf3} /* capital letter es */, + {0x0422, 0xf4} /* capital letter te */, + {0x0423, 0xf5} /* capital letter u */, + {0x0424, 0xe6} /* capital letter ef */, + {0x0425, 0xe8} /* capital letter ha */, + {0x0426, 0xe3} /* capital letter tse */, + {0x0427, 0xfe} /* capital letter che */, + {0x0428, 0xfb} /* capital letter sha */, + {0x0429, 0xfd} /* capital letter shcha */, + {0x042a, 0xff} /* capital letter hard sign */, + {0x042b, 0xf9} /* capital letter yeru */, + {0x042c, 0xf8} /* capital letter soft sign */, + {0x042d, 0xfc} /* capital letter e */, + {0x042e, 0xe0} /* capital letter yu */, + {0x042f, 0xf1} /* capital letter ya */, + {0x0430, 0xc1} /* small letter a */, + {0x0431, 0xc2} /* small letter be */, + {0x0432, 0xd7} /* small letter ve */, + {0x0433, 0xc7} /* small letter ghe */, + {0x0434, 0xc4} /* small letter de */, + {0x0435, 0xc5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xda} /* small letter ze */, + {0x0438, 0xc9} /* small letter i */, + {0x0439, 0xca} /* small letter short i */, + {0x043a, 0xcb} /* small letter ka */, + {0x043b, 0xcc} /* small letter el */, + {0x043c, 0xcd} /* small letter em */, + {0x043d, 0xce} /* small letter en */, + {0x043e, 0xcf} /* small letter o */, + {0x043f, 0xd0} /* small letter pe */, + {0x0440, 0xd2} /* small letter er */, + {0x0441, 0xd3} /* small letter es */, + {0x0442, 0xd4} /* small letter te */, + {0x0443, 0xd5} /* small letter u */, + {0x0444, 0xc6} /* small letter ef */, + {0x0445, 0xc8} /* small letter ha */, + {0x0446, 0xc3} /* small letter tse */, + {0x0447, 0xde} /* small letter che */, + {0x0448, 0xdb} /* small letter sha */, + {0x0449, 0xdd} /* small letter shcha */, + {0x044a, 0xdf} /* small letter hard sign */, + {0x044b, 0xd9} /* small letter yeru */, + {0x044c, 0xd8} /* small letter soft sign */, + {0x044d, 0xdc} /* small letter e */, + {0x044e, 0xc0} /* small letter yu */, + {0x044f, 0xd1} /* small letter ya */, + {0x0451, 0xa3} /* small letter io */, + {0x0454, 0xa4} /* small letter ukrainian ie */, + {0x0456, 0xa6} /* small letter byelorussian-ukrainian i */, + {0x0457, 0xa7} /* small letter yi (ukrainian) */, + {0x045e, 0xae} /* small letter short u (byelorussian) */, + {0x0490, 0xbd} /* capital letter ghe with upturn */, + {0x0491, 0xad} /* small letter ghe with upturn */, + {0x2014, 0x97} /* dash */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x96} /* double quotation mark */, + {0x2022, 0x95} /* puce */, + {0x2116, 0x98} /* sign */, + {0x2122, 0x99} /* mark sign */, + {0x2500, 0x80} /* drawings light horizontal */, + {0x2502, 0x81} /* drawings light vertical */, + {0x250c, 0x82} /* drawings light down and right */, + {0x2510, 0x83} /* drawings light down and left */, + {0x2514, 0x84} /* drawings light up and right */, + {0x2518, 0x85} /* drawings light up and left */, + {0x251c, 0x86} /* drawings light vertical and right */, + {0x2524, 0x87} /* drawings light vertical and left */, + {0x252c, 0x88} /* drawings light down and horizontal */, + {0x2534, 0x89} /* drawings light up and horizontal */, + {0x253c, 0x8a} /* drawings light vertical and horizontal */, + {0x2550, 0xa0} /* drawings heavy horizontal */, + {0x2551, 0xa1} /* drawings heavy vertical */, + {0x2552, 0xa2} /* drawings down light and right heavy */, + {0x2554, 0xa5} /* drawings heavy down and right */, + {0x2557, 0xa8} /* drawings heavy down and left */, + {0x2558, 0xa9} /* drawings up light and right heavy */, + {0x2559, 0xaa} /* drawings up heavy and right light */, + {0x255a, 0xab} /* drawings heavy up and right */, + {0x255b, 0xac} /* drawings up light and left heavy */, + {0x255e, 0xaf} /* drawings vertical light and right heavy */, + {0x255f, 0xb0} /* drawings vertical heavy and right light */, + {0x2560, 0xb1} /* drawings heavy vertical and right */, + {0x2561, 0xb2} /* drawings vertical light and left heavy */, + {0x2563, 0xb5} /* drawings heavy vertical and left */, + {0x2566, 0xb8} /* drawings heavy down and horizontal */, + {0x2567, 0xb9} /* drawings up light and horizontal heavy */, + {0x2568, 0xba} /* drawings up heavy and horizontal light */, + {0x2569, 0xbb} /* drawings heavy up and horizontal */, + {0x256a, 0xbc} /* drawings vertical light and horizontal heavy */, + {0x2580, 0x8b} /* half block */, + {0x2584, 0x8c} /* half block */, + {0x2588, 0x8d} /* block */, + {0x258c, 0x8e} /* half block */, + {0x2590, 0x8f} /* half block */, + {0x2591, 0x90} /* shade */, + {0x2592, 0x91} /* shade */, + {0x2593, 0x92} /* shade */, + {0x25a0, 0x94} /* square */ +}; + +/* +#define cet_ucs4_to_koi8_ru_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi8_ru_extra[cet_ucs4_to_koi8_ru_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi8_ru = /* defined in cet.h */ +{ + cet_cs_name_koi8_ru, /* name of character set */ + cet_cs_alias_koi8_ru, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi8_ru, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi8_ru, /* first non standard character */ + cet_ucs4_cnt_koi8_ru, /* number of values in table */ + + cet_ucs4_to_koi8_ru_links, /* UCS-4 to char links */ + cet_ucs4_to_koi8_ru_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi8_ru_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x201c, 0x25a0, 0x2022, 0x201d, 0x2014, + 0x2116, 0x2122, 0x00a0, 0x00bb, 0x00ae, 0x00ab, 0x00b7, 0x00a4, + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x045e, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x040e, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; +*/ + +#endif diff --git a/cet/koi8_u.h b/cet/koi8_u.h new file mode 100644 index 000000000..1f3d88cfc --- /dev/null +++ b/cet/koi8_u.h @@ -0,0 +1,238 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI8-U" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi8_u_h +#define koi8_u_h + +#define cet_cs_name_koi8_u "KOI8-U" + +const char *cet_cs_alias_koi8_u[] = +{ + "KOI8-U", NULL +}; + +#define cet_ucs4_ofs_koi8_u 128 +#define cet_ucs4_cnt_koi8_u 112 + +const int cet_ucs4_map_koi8_u[cet_ucs4_cnt_koi8_u] = +{ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x255d, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x256c, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e +}; + +#define cet_ucs4_to_koi8_u_ct 112 + +const cet_ucs4_link_t cet_ucs4_to_koi8_u_links[cet_ucs4_to_koi8_u_ct] = +{ + {0x00a0, 0x9a} /* space */, + {0x00a9, 0xbf} /* sign */, + {0x00b0, 0x9c} /* sign */, + {0x00b2, 0x9d} /* two */, + {0x00b7, 0x9e} /* dot */, + {0x00f7, 0x9f} /* sign */, + {0x0401, 0xb3} /* capital letter io */, + {0x0404, 0xb4} /* capital letter ukrainian ie */, + {0x0406, 0xb6} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0xb7} /* capital letter yi (ukrainian) */, + {0x0410, 0xe1} /* capital letter a */, + {0x0411, 0xe2} /* capital letter be */, + {0x0413, 0xe7} /* capital letter ghe */, + {0x0414, 0xe4} /* capital letter de */, + {0x0415, 0xe5} /* capital letter ie */, + {0x0418, 0xe9} /* capital letter i */, + {0x0419, 0xea} /* capital letter short i */, + {0x041a, 0xeb} /* capital letter ka */, + {0x041b, 0xec} /* capital letter el */, + {0x041c, 0xed} /* capital letter em */, + {0x041d, 0xee} /* capital letter en */, + {0x041e, 0xef} /* capital letter o */, + {0x0424, 0xe6} /* capital letter ef */, + {0x0425, 0xe8} /* capital letter ha */, + {0x0426, 0xe3} /* capital letter tse */, + {0x042e, 0xe0} /* capital letter yu */, + {0x0430, 0xc1} /* small letter a */, + {0x0431, 0xc2} /* small letter be */, + {0x0432, 0xd7} /* small letter ve */, + {0x0433, 0xc7} /* small letter ghe */, + {0x0434, 0xc4} /* small letter de */, + {0x0435, 0xc5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xda} /* small letter ze */, + {0x0438, 0xc9} /* small letter i */, + {0x0439, 0xca} /* small letter short i */, + {0x043a, 0xcb} /* small letter ka */, + {0x043b, 0xcc} /* small letter el */, + {0x043c, 0xcd} /* small letter em */, + {0x043d, 0xce} /* small letter en */, + {0x043e, 0xcf} /* small letter o */, + {0x043f, 0xd0} /* small letter pe */, + {0x0440, 0xd2} /* small letter er */, + {0x0441, 0xd3} /* small letter es */, + {0x0442, 0xd4} /* small letter te */, + {0x0443, 0xd5} /* small letter u */, + {0x0444, 0xc6} /* small letter ef */, + {0x0445, 0xc8} /* small letter ha */, + {0x0446, 0xc3} /* small letter tse */, + {0x0447, 0xde} /* small letter che */, + {0x0448, 0xdb} /* small letter sha */, + {0x0449, 0xdd} /* small letter shcha */, + {0x044a, 0xdf} /* small letter hard sign */, + {0x044b, 0xd9} /* small letter yeru */, + {0x044c, 0xd8} /* small letter soft sign */, + {0x044d, 0xdc} /* small letter e */, + {0x044e, 0xc0} /* small letter yu */, + {0x044f, 0xd1} /* small letter ya */, + {0x0451, 0xa3} /* small letter io */, + {0x0454, 0xa4} /* small letter ukrainian ie */, + {0x0456, 0xa6} /* small letter byelorussian-ukrainian i */, + {0x0457, 0xa7} /* small letter yi (ukrainian) */, + {0x0490, 0xbd} /* capital letter ghe with upturn */, + {0x0491, 0xad} /* small letter ghe with upturn */, + {0x2219, 0x95} /* operator */, + {0x221a, 0x96} /* root */, + {0x2248, 0x97} /* equal to */, + {0x2264, 0x98} /* or equal to */, + {0x2265, 0x99} /* or equal to */, + {0x2320, 0x93} /* half integral */, + {0x2321, 0x9b} /* half integral */, + {0x2500, 0x80} /* drawings light horizontal */, + {0x2502, 0x81} /* drawings light vertical */, + {0x250c, 0x82} /* drawings light down and right */, + {0x2510, 0x83} /* drawings light down and left */, + {0x2514, 0x84} /* drawings light up and right */, + {0x2518, 0x85} /* drawings light up and left */, + {0x251c, 0x86} /* drawings light vertical and right */, + {0x2524, 0x87} /* drawings light vertical and left */, + {0x252c, 0x88} /* drawings light down and horizontal */, + {0x2534, 0x89} /* drawings light up and horizontal */, + {0x253c, 0x8a} /* drawings light vertical and horizontal */, + {0x2550, 0xa0} /* drawings heavy horizontal */, + {0x2551, 0xa1} /* drawings heavy vertical */, + {0x2552, 0xa2} /* drawings down light and right heavy */, + {0x2554, 0xa5} /* drawings heavy down and right */, + {0x2557, 0xa8} /* drawings heavy down and left */, + {0x2558, 0xa9} /* drawings up light and right heavy */, + {0x2559, 0xaa} /* drawings up heavy and right light */, + {0x255a, 0xab} /* drawings heavy up and right */, + {0x255b, 0xac} /* drawings up light and left heavy */, + {0x255d, 0xae} /* drawings heavy up and left */, + {0x255e, 0xaf} /* drawings vertical light and right heavy */, + {0x255f, 0xb0} /* drawings vertical heavy and right light */, + {0x2560, 0xb1} /* drawings heavy vertical and right */, + {0x2561, 0xb2} /* drawings vertical light and left heavy */, + {0x2563, 0xb5} /* drawings heavy vertical and left */, + {0x2566, 0xb8} /* drawings heavy down and horizontal */, + {0x2567, 0xb9} /* drawings up light and horizontal heavy */, + {0x2568, 0xba} /* drawings up heavy and horizontal light */, + {0x2569, 0xbb} /* drawings heavy up and horizontal */, + {0x256a, 0xbc} /* drawings vertical light and horizontal heavy */, + {0x256c, 0xbe} /* drawings heavy vertical and horizontal */, + {0x2580, 0x8b} /* half block */, + {0x2584, 0x8c} /* half block */, + {0x2588, 0x8d} /* block */, + {0x258c, 0x8e} /* half block */, + {0x2590, 0x8f} /* half block */, + {0x2591, 0x90} /* shade */, + {0x2592, 0x91} /* shade */, + {0x2593, 0x92} /* shade */, + {0x25a0, 0x94} /* square */ +}; + +/* +#define cet_ucs4_to_koi8_u_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi8_u_extra[cet_ucs4_to_koi8_u_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi8_u = /* defined in cet.h */ +{ + cet_cs_name_koi8_u, /* name of character set */ + cet_cs_alias_koi8_u, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi8_u, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi8_u, /* first non standard character */ + cet_ucs4_cnt_koi8_u, /* number of values in table */ + + cet_ucs4_to_koi8_u_links, /* UCS-4 to char links */ + cet_ucs4_to_koi8_u_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi8_u_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x255d, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x256c, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/koi_7.h b/cet/koi_7.h new file mode 100644 index 000000000..7e94ce3cb --- /dev/null +++ b/cet/koi_7.h @@ -0,0 +1,156 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI-7" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi_7_h +#define koi_7_h + +#define cet_cs_name_koi_7 "KOI-7" + +const char *cet_cs_alias_koi_7[] = +{ + "KOI-7", NULL +}; + +#define cet_ucs4_ofs_koi_7 36 +#define cet_ucs4_cnt_koi_7 92 + +const int cet_ucs4_map_koi_7[cet_ucs4_cnt_koi_7] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x042e, 0x0410, 0x0411, 0x0426, + 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041a, + 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x042f, 0x0420, 0x0421, + 0x0422, 0x0423, 0x0416, 0x0412, 0x042c, 0x042b, 0x0417, 0x0428, + 0x042d, 0x0429, 0x0427, 0x007f +}; + +#define cet_ucs4_to_koi_7_ct 32 + +const cet_ucs4_link_t cet_ucs4_to_koi_7_links[cet_ucs4_to_koi_7_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x0410, 0x61} /* capital letter a */, + {0x0411, 0x62} /* capital letter be */, + {0x0412, 0x77} /* capital letter ve */, + {0x0413, 0x67} /* capital letter ghe */, + {0x0414, 0x64} /* capital letter de */, + {0x0415, 0x65} /* capital letter ie */, + {0x0416, 0x76} /* capital letter zhe */, + {0x0417, 0x7a} /* capital letter ze */, + {0x0418, 0x69} /* capital letter i */, + {0x0419, 0x6a} /* capital letter short i */, + {0x041a, 0x6b} /* capital letter ka */, + {0x041b, 0x6c} /* capital letter el */, + {0x041c, 0x6d} /* capital letter em */, + {0x041d, 0x6e} /* capital letter en */, + {0x041e, 0x6f} /* capital letter o */, + {0x041f, 0x70} /* capital letter pe */, + {0x0420, 0x72} /* capital letter er */, + {0x0421, 0x73} /* capital letter es */, + {0x0422, 0x74} /* capital letter te */, + {0x0423, 0x75} /* capital letter u */, + {0x0424, 0x66} /* capital letter ef */, + {0x0425, 0x68} /* capital letter ha */, + {0x0426, 0x63} /* capital letter tse */, + {0x0427, 0x7e} /* capital letter che */, + {0x0428, 0x7b} /* capital letter sha */, + {0x0429, 0x7d} /* capital letter shcha */, + {0x042b, 0x79} /* capital letter yeru */, + {0x042c, 0x78} /* capital letter soft sign */, + {0x042d, 0x7c} /* capital letter e */, + {0x042e, 0x60} /* capital letter yu */, + {0x042f, 0x71} /* capital letter ya */ +}; + +/* +#define cet_ucs4_to_koi_7_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi_7_extra[cet_ucs4_to_koi_7_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi_7 = /* defined in cet.h */ +{ + cet_cs_name_koi_7, /* name of character set */ + cet_cs_alias_koi_7, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi_7, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi_7, /* first non standard character */ + cet_ucs4_cnt_koi_7, /* number of values in table */ + + cet_ucs4_to_koi_7_links, /* UCS-4 to char links */ + cet_ucs4_to_koi_7_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi_7_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/koi_8.h b/cet/koi_8.h new file mode 100644 index 000000000..8b4795be9 --- /dev/null +++ b/cet/koi_8.h @@ -0,0 +1,191 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI-8" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi_8_h +#define koi_8_h + +#define cet_cs_name_koi_8 "KOI-8" + +const char *cet_cs_alias_koi_8[] = +{ + "KOI-8", "GOST_19768-74", NULL +}; + +#define cet_ucs4_ofs_koi_8 128 +#define cet_ucs4_cnt_koi_8 127 + +const int cet_ucs4_map_koi_8[cet_ucs4_cnt_koi_8] = +{ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427 +}; + +#define cet_ucs4_to_koi_8_ct 63 + +const cet_ucs4_link_t cet_ucs4_to_koi_8_links[cet_ucs4_to_koi_8_ct] = +{ + {0x0410, 0xe1} /* capital letter a */, + {0x0411, 0xe2} /* capital letter be */, + {0x0412, 0xf7} /* capital letter ve */, + {0x0413, 0xe7} /* capital letter ghe */, + {0x0414, 0xe4} /* capital letter de */, + {0x0415, 0xe5} /* capital letter ie */, + {0x0416, 0xf6} /* capital letter zhe */, + {0x0417, 0xfa} /* capital letter ze */, + {0x0418, 0xe9} /* capital letter i */, + {0x0419, 0xea} /* capital letter short i */, + {0x041a, 0xeb} /* capital letter ka */, + {0x041b, 0xec} /* capital letter el */, + {0x041c, 0xed} /* capital letter em */, + {0x041d, 0xee} /* capital letter en */, + {0x041e, 0xef} /* capital letter o */, + {0x041f, 0xf0} /* capital letter pe */, + {0x0420, 0xf2} /* capital letter er */, + {0x0421, 0xf3} /* capital letter es */, + {0x0422, 0xf4} /* capital letter te */, + {0x0423, 0xf5} /* capital letter u */, + {0x0424, 0xe6} /* capital letter ef */, + {0x0425, 0xe8} /* capital letter ha */, + {0x0426, 0xe3} /* capital letter tse */, + {0x0427, 0xfe} /* capital letter che */, + {0x0428, 0xfb} /* capital letter sha */, + {0x0429, 0xfd} /* capital letter shcha */, + {0x042b, 0xf9} /* capital letter yeru */, + {0x042c, 0xf8} /* capital letter soft sign */, + {0x042d, 0xfc} /* capital letter e */, + {0x042e, 0xe0} /* capital letter yu */, + {0x042f, 0xf1} /* capital letter ya */, + {0x0430, 0xc1} /* small letter a */, + {0x0431, 0xc2} /* small letter be */, + {0x0432, 0xd7} /* small letter ve */, + {0x0433, 0xc7} /* small letter ghe */, + {0x0434, 0xc4} /* small letter de */, + {0x0435, 0xc5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xda} /* small letter ze */, + {0x0438, 0xc9} /* small letter i */, + {0x0439, 0xca} /* small letter short i */, + {0x043a, 0xcb} /* small letter ka */, + {0x043b, 0xcc} /* small letter el */, + {0x043c, 0xcd} /* small letter em */, + {0x043d, 0xce} /* small letter en */, + {0x043e, 0xcf} /* small letter o */, + {0x043f, 0xd0} /* small letter pe */, + {0x0440, 0xd2} /* small letter er */, + {0x0441, 0xd3} /* small letter es */, + {0x0442, 0xd4} /* small letter te */, + {0x0443, 0xd5} /* small letter u */, + {0x0444, 0xc6} /* small letter ef */, + {0x0445, 0xc8} /* small letter ha */, + {0x0446, 0xc3} /* small letter tse */, + {0x0447, 0xde} /* small letter che */, + {0x0448, 0xdb} /* small letter sha */, + {0x0449, 0xdd} /* small letter shcha */, + {0x044a, 0xdf} /* small letter hard sign */, + {0x044b, 0xd9} /* small letter yeru */, + {0x044c, 0xd8} /* small letter soft sign */, + {0x044d, 0xdc} /* small letter e */, + {0x044e, 0xc0} /* small letter yu */, + {0x044f, 0xd1} /* small letter ya */ +}; + +/* +#define cet_ucs4_to_koi_8_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi_8_extra[cet_ucs4_to_koi_8_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi_8 = /* defined in cet.h */ +{ + cet_cs_name_koi_8, /* name of character set */ + cet_cs_alias_koi_8, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi_8, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi_8, /* first non standard character */ + cet_ucs4_cnt_koi_8, /* number of values in table */ + + cet_ucs4_to_koi_8_links, /* UCS-4 to char links */ + cet_ucs4_to_koi_8_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi_8_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, -1 +}; +*/ + +#endif diff --git a/cet/koi_8_cs2.h b/cet/koi_8_cs2.h new file mode 100644 index 000000000..3398b91e6 --- /dev/null +++ b/cet/koi_8_cs2.h @@ -0,0 +1,222 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI-8_CS2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi_8_cs2_h +#define koi_8_cs2_h + +#define cet_cs_name_koi_8_cs2 "KOI-8_CS2" + +const char *cet_cs_alias_koi_8_cs2[] = +{ + "KOI-8_CS2", NULL +}; + +#define cet_ucs4_ofs_koi_8_cs2 36 +#define cet_ucs4_cnt_koi_8_cs2 219 + +const int cet_ucs4_map_koi_8_cs2[cet_ucs4_cnt_koi_8_cs2] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, + 0x009c, 0x009d, 0x009e, 0x009f, 0x00a0, -1, 0x00b4, -1, + 0x007e, -1, 0x02d8, 0x02d9, 0x00a8, -1, 0x02da, 0x00b8, + -1, 0x02dd, 0x02db, 0x02c7, 0x00a9, 0x2122, 0x250c, 0x2510, + 0x2514, 0x2518, 0x2500, 0x2193, 0x03a9, 0x00a7, 0x03b1, 0x03b3, + 0x03b5, 0x03bc, 0x03c0, 0x03c9, 0x00e0, 0x00e1, 0x01ce, 0x010d, + 0x010f, 0x011b, 0x0155, -1, 0x00fc, 0x00ed, 0x016f, 0x013a, + 0x013e, 0x00f6, 0x0148, 0x00f3, 0x00f4, 0x00e4, 0x0159, 0x0161, + 0x0165, 0x00fa, 0x00eb, 0x00e9, 0x0171, 0x00fd, 0x017e, -1, + -1, 0x0151, 0x0117, 0x00df, 0x00c0, 0x00c1, 0x01cd, 0x010c, + 0x010e, 0x011a, 0x0154, -1, 0x00dc, 0x00cd, 0x016e, 0x0139, + 0x013d, 0x00d6, 0x0147, 0x00d3, 0x00d4, 0x00c4, 0x0158, 0x0160, + 0x0164, 0x00da, 0x00cb, 0x00c9, 0x0170, 0x00dd, 0x017d, -1, + -1, 0x0150, 0x0116 +}; + +#define cet_ucs4_to_koi_8_cs2_ct 82 + +const cet_ucs4_link_t cet_ucs4_to_koi_8_cs2_links[cet_ucs4_to_koi_8_cs2_ct] = +{ + {0x007e, 0xa4} /* tilde */, + {0x00a4, 0x24} /* sign */, + {0x00a7, 0xb9} /* sign */, + {0x00a9, 0xb0} /* sign */, + {0x00b4, 0xa2} /* accent */, + {0x00b8, 0xab} /* cedilla */, + {0x00c0, 0xe0} /* capital letter a with grave */, + {0x00c1, 0xe1} /* capital letter a with acute */, + {0x00c4, 0xf1} /* capital letter a with diaeresis */, + {0x00c9, 0xf7} /* capital letter e with acute */, + {0x00cb, 0xf6} /* capital letter e with diaeresis */, + {0x00cd, 0xe9} /* capital letter i with acute */, + {0x00d3, 0xef} /* capital letter o with acute */, + {0x00d4, 0xf0} /* capital letter o with circumflex */, + {0x00d6, 0xed} /* capital letter o with diaeresis */, + {0x00da, 0xf5} /* capital letter u with acute */, + {0x00dc, 0xe8} /* capital letter u with diaeresis */, + {0x00dd, 0xf9} /* capital letter y with acute */, + {0x00e0, 0xc0} /* small letter a with grave */, + {0x00e1, 0xc1} /* small letter a with acute */, + {0x00e4, 0xd1} /* small letter a with diaeresis */, + {0x00e9, 0xd7} /* small letter e with acute */, + {0x00eb, 0xd6} /* small letter e with diaeresis */, + {0x00ed, 0xc9} /* small letter i with acute */, + {0x00f3, 0xcf} /* small letter o with acute */, + {0x00f4, 0xd0} /* small letter o with circumflex */, + {0x00f6, 0xcd} /* small letter o with diaeresis */, + {0x00fa, 0xd5} /* small letter u with acute */, + {0x00fc, 0xc8} /* small letter u with diaeresis */, + {0x00fd, 0xd9} /* small letter y with acute */, + {0x010c, 0xe3} /* capital letter c with caron */, + {0x010d, 0xc3} /* small letter c with caron */, + {0x010e, 0xe4} /* capital letter d with caron */, + {0x010f, 0xc4} /* small letter d with caron */, + {0x0116, 0xfe} /* capital letter e with dot above */, + {0x0117, 0xde} /* small letter e with dot above */, + {0x011a, 0xe5} /* capital letter e with caron */, + {0x011b, 0xc5} /* small letter e with caron */, + {0x0139, 0xeb} /* capital letter l with acute */, + {0x013a, 0xcb} /* small letter l with acute */, + {0x013d, 0xec} /* capital letter l with caron */, + {0x013e, 0xcc} /* small letter l with caron */, + {0x0147, 0xee} /* capital letter n with caron */, + {0x0148, 0xce} /* small letter n with caron */, + {0x0150, 0xfd} /* capital letter o with double acute */, + {0x0151, 0xdd} /* small letter o with double acute */, + {0x0154, 0xe6} /* capital letter r with acute */, + {0x0155, 0xc6} /* small letter r with acute */, + {0x0158, 0xf2} /* capital letter r with caron */, + {0x0159, 0xd2} /* small letter r with caron */, + {0x0160, 0xf3} /* capital letter s with caron */, + {0x0161, 0xd3} /* small letter s with caron */, + {0x0164, 0xf4} /* capital letter t with caron */, + {0x0165, 0xd4} /* small letter t with caron */, + {0x016e, 0xea} /* capital letter u with ring above */, + {0x016f, 0xca} /* small letter u with ring above */, + {0x0170, 0xf8} /* capital letter u with double acute */, + {0x0171, 0xd8} /* small letter u with double acute */, + {0x017d, 0xfa} /* capital letter z with caron */, + {0x017e, 0xda} /* small letter z with caron */, + {0x01cd, 0xe2} /* capital letter a with caron */, + {0x01ce, 0xc2} /* small letter a with caron */, + {0x02c7, 0xaf} /* caron */, + {0x02d8, 0xa6} /* breve */, + {0x02d9, 0xa7} /* above */, + {0x02da, 0xaa} /* above */, + {0x02db, 0xae} /* ogonek */, + {0x02dd, 0xad} /* acute accent */, + {0x03a9, 0xb8} /* capital letter omega */, + {0x03b1, 0xba} /* small letter alpha */, + {0x03b3, 0xbb} /* small letter gamma */, + {0x03b5, 0xbc} /* small letter epsilon */, + {0x03bc, 0xbd} /* small letter mu */, + {0x03c0, 0xbe} /* small letter pi */, + {0x03c9, 0xbf} /* small letter omega */, + {0x2122, 0xb1} /* mark sign */, + {0x2193, 0xb7} /* arrow */, + {0x2500, 0xb6} /* drawings light horizontal */, + {0x250c, 0xb2} /* drawings light down and right */, + {0x2510, 0xb3} /* drawings light down and left */, + {0x2514, 0xb4} /* drawings light up and right */, + {0x2518, 0xb5} /* drawings light up and left */ +}; + +/* +#define cet_ucs4_to_koi_8_cs2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi_8_cs2_extra[cet_ucs4_to_koi_8_cs2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi_8_cs2 = /* defined in cet.h */ +{ + cet_cs_name_koi_8_cs2, /* name of character set */ + cet_cs_alias_koi_8_cs2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi_8_cs2, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi_8_cs2, /* first non standard character */ + cet_ucs4_cnt_koi_8_cs2, /* number of values in table */ + + cet_ucs4_to_koi_8_cs2_links, /* UCS-4 to char links */ + cet_ucs4_to_koi_8_cs2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi_8_cs2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, -1, 0x00b4, -1, 0x007e, -1, 0x02d8, 0x02d9, + 0x00a8, -1, 0x02da, 0x00b8, -1, 0x02dd, 0x02db, 0x02c7, + 0x00a9, 0x2122, 0x250c, 0x2510, 0x2514, 0x2518, 0x2500, 0x2193, + 0x03a9, 0x00a7, 0x03b1, 0x03b3, 0x03b5, 0x03bc, 0x03c0, 0x03c9, + 0x00e0, 0x00e1, 0x01ce, 0x010d, 0x010f, 0x011b, 0x0155, -1, + 0x00fc, 0x00ed, 0x016f, 0x013a, 0x013e, 0x00f6, 0x0148, 0x00f3, + 0x00f4, 0x00e4, 0x0159, 0x0161, 0x0165, 0x00fa, 0x00eb, 0x00e9, + 0x0171, 0x00fd, 0x017e, -1, -1, 0x0151, 0x0117, 0x00df, + 0x00c0, 0x00c1, 0x01cd, 0x010c, 0x010e, 0x011a, 0x0154, -1, + 0x00dc, 0x00cd, 0x016e, 0x0139, 0x013d, 0x00d6, 0x0147, 0x00d3, + 0x00d4, 0x00c4, 0x0158, 0x0160, 0x0164, 0x00da, 0x00cb, 0x00c9, + 0x0170, 0x00dd, 0x017d, -1, -1, 0x0150, 0x0116, -1 +}; +*/ + +#endif diff --git a/cet/ksc5636.h b/cet/ksc5636.h new file mode 100644 index 000000000..ff513c529 --- /dev/null +++ b/cet/ksc5636.h @@ -0,0 +1,118 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KSC5636" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ksc5636_h +#define ksc5636_h + +#define cet_cs_name_ksc5636 "KSC5636" + +const char *cet_cs_alias_ksc5636[] = +{ + "KSC5636", "ISO646-KR", NULL +}; + +#define cet_ucs4_ofs_ksc5636 92 +#define cet_ucs4_cnt_ksc5636 36 + +const int cet_ucs4_map_ksc5636[cet_ucs4_cnt_ksc5636] = +{ + 0x20a9, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x007e, 0x007f +}; + +#define cet_ucs4_to_ksc5636_ct 1 + +const cet_ucs4_link_t cet_ucs4_to_ksc5636_links[cet_ucs4_to_ksc5636_ct] = +{ + {0x20a9, 0x5c} /* sign */ +}; + +/* +#define cet_ucs4_to_ksc5636_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ksc5636_extra[cet_ucs4_to_ksc5636_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ksc5636 = /* defined in cet.h */ +{ + cet_cs_name_ksc5636, /* name of character set */ + cet_cs_alias_ksc5636, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ksc5636, /* char to UCS-4 value table */ + cet_ucs4_ofs_ksc5636, /* first non standard character */ + cet_ucs4_cnt_ksc5636, /* number of values in table */ + + cet_ucs4_to_ksc5636_links, /* UCS-4 to char links */ + cet_ucs4_to_ksc5636_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ksc5636_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x20a9, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/latin_greek_1.h b/cet/latin_greek_1.h new file mode 100644 index 000000000..ffb016353 --- /dev/null +++ b/cet/latin_greek_1.h @@ -0,0 +1,136 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "Latin-greek-1" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef latin_greek_1_h +#define latin_greek_1_h + +#define cet_cs_name_latin_greek_1 "Latin-greek-1" + +const char *cet_cs_alias_latin_greek_1[] = +{ + "Latin-greek-1", "iso-ir-27", NULL +}; + +#define cet_ucs4_ofs_latin_greek_1 33 +#define cet_ucs4_cnt_latin_greek_1 95 + +const int cet_ucs4_map_latin_greek_1[cet_ucs4_cnt_latin_greek_1] = +{ + 0x039e, 0x0022, 0x0393, 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, + 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, + 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, + 0x0039, 0x03a8, 0x003b, 0x003c, 0x003d, 0x003e, 0x03a0, 0x0394, + 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, + 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x03a9, 0x0398, 0x03a6, 0x039b, 0x03a3, 0x0060, + 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, + 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f +}; + +#define cet_ucs4_to_latin_greek_1_ct 12 + +const cet_ucs4_link_t cet_ucs4_to_latin_greek_1_links[cet_ucs4_to_latin_greek_1_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x0393, 0x23} /* capital letter gamma */, + {0x0394, 0x40} /* capital letter delta */, + {0x0398, 0x5c} /* capital letter theta */, + {0x039b, 0x5e} /* capital letter lamda */, + {0x039e, 0x21} /* capital letter xi */, + {0x03a0, 0x3f} /* capital letter pi */, + {0x03a3, 0x5f} /* capital letter sigma */, + {0x03a6, 0x5d} /* capital letter phi */, + {0x03a8, 0x3a} /* capital letter psi */, + {0x03a9, 0x5b} /* capital letter omega */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_latin_greek_1_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_latin_greek_1_extra[cet_ucs4_to_latin_greek_1_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_latin_greek_1 = /* defined in cet.h */ +{ + cet_cs_name_latin_greek_1, /* name of character set */ + cet_cs_alias_latin_greek_1, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_latin_greek_1, /* char to UCS-4 value table */ + cet_ucs4_ofs_latin_greek_1, /* first non standard character */ + cet_ucs4_cnt_latin_greek_1, /* number of values in table */ + + cet_ucs4_to_latin_greek_1_links, /* UCS-4 to char links */ + cet_ucs4_to_latin_greek_1_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int latin_greek_1_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x039e, 0x0022, 0x0393, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x03a8, 0x003b, 0x003c, 0x003d, 0x003e, 0x03a0, + 0x0394, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x03a9, 0x0398, 0x03a6, 0x039b, 0x03a3, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/mac_is.h b/cet/mac_is.h new file mode 100644 index 000000000..6c0050324 --- /dev/null +++ b/cet/mac_is.h @@ -0,0 +1,248 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "mac-is" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef mac_is_h +#define mac_is_h + +#define cet_cs_name_mac_is "mac-is" + +const char *cet_cs_alias_mac_is[] = +{ + "mac-is", NULL +}; + +#define cet_ucs4_ofs_mac_is 128 +#define cet_ucs4_cnt_mac_is 128 + +const int cet_ucs4_map_mac_is[cet_ucs4_cnt_mac_is] = +{ + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + 0x2014, 0x2013, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25c6, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x0110, 0x0111, 0x00de, 0x00fe, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xe01e, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, -1, -1, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7 +}; + +#define cet_ucs4_to_mac_is_ct 120 + +const cet_ucs4_link_t cet_ucs4_to_mac_is_links[cet_ucs4_to_mac_is_ct] = +{ + {0x00a0, 0xca} /* space */, + {0x00a1, 0xc1} /* exclamation mark */, + {0x00a4, 0xdb} /* sign */, + {0x00a5, 0xb4} /* sign */, + {0x00a7, 0xa4} /* sign */, + {0x00a8, 0xac} /* diaeresis */, + {0x00aa, 0xbb} /* ordinal indicator */, + {0x00ab, 0xc7} /* double angle quotation mark */, + {0x00ac, 0xc2} /* sign */, + {0x00ae, 0xa8} /* sign */, + {0x00af, 0xf8} /* macron */, + {0x00b0, 0xa1} /* sign */, + {0x00b4, 0xab} /* accent */, + {0x00b6, 0xa6} /* sign */, + {0x00b7, 0xe1} /* dot */, + {0x00b8, 0xfc} /* cedilla */, + {0x00ba, 0xbc} /* ordinal indicator */, + {0x00bb, 0xc8} /* double angle quotation mark */, + {0x00bf, 0xc0} /* question mark */, + {0x00c0, 0xcb} /* capital letter a with grave */, + {0x00c1, 0xe7} /* capital letter a with acute */, + {0x00c2, 0xe5} /* capital letter a with circumflex */, + {0x00c3, 0xcc} /* capital letter a with tilde */, + {0x00c4, 0x80} /* capital letter a with diaeresis */, + {0x00c5, 0x81} /* capital letter a with ring above */, + {0x00c6, 0xae} /* capital letter ae */, + {0x00c7, 0x82} /* capital letter c with cedilla */, + {0x00c8, 0xe9} /* capital letter e with grave */, + {0x00c9, 0x83} /* capital letter e with acute */, + {0x00ca, 0xe6} /* capital letter e with circumflex */, + {0x00cb, 0xe8} /* capital letter e with diaeresis */, + {0x00cc, 0xed} /* capital letter i with grave */, + {0x00cd, 0xea} /* capital letter i with acute */, + {0x00ce, 0xeb} /* capital letter i with circumflex */, + {0x00cf, 0xec} /* capital letter i with diaeresis */, + {0x00d1, 0x84} /* capital letter n with tilde */, + {0x00d2, 0xf1} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xef} /* capital letter o with circumflex */, + {0x00d5, 0xcd} /* capital letter o with tilde */, + {0x00d6, 0x85} /* capital letter o with diaeresis */, + {0x00d8, 0xaf} /* capital letter o with stroke */, + {0x00d9, 0xf4} /* capital letter u with grave */, + {0x00da, 0xf2} /* capital letter u with acute */, + {0x00db, 0xf3} /* capital letter u with circumflex */, + {0x00dc, 0x86} /* capital letter u with diaeresis */, + {0x00df, 0xa7} /* small letter sharp s (german) */, + {0x00e0, 0x88} /* small letter a with grave */, + {0x00e1, 0x87} /* small letter a with acute */, + {0x00e2, 0x89} /* small letter a with circumflex */, + {0x00e3, 0x8b} /* small letter a with tilde */, + {0x00e4, 0x8a} /* small letter a with diaeresis */, + {0x00e5, 0x8c} /* small letter a with ring above */, + {0x00e6, 0xbe} /* small letter ae */, + {0x00e7, 0x8d} /* small letter c with cedilla */, + {0x00e8, 0x8f} /* small letter e with grave */, + {0x00e9, 0x8e} /* small letter e with acute */, + {0x00ea, 0x90} /* small letter e with circumflex */, + {0x00eb, 0x91} /* small letter e with diaeresis */, + {0x00ec, 0x93} /* small letter i with grave */, + {0x00ed, 0x92} /* small letter i with acute */, + {0x00ee, 0x94} /* small letter i with circumflex */, + {0x00ef, 0x95} /* small letter i with diaeresis */, + {0x00f1, 0x96} /* small letter n with tilde */, + {0x00f2, 0x98} /* small letter o with grave */, + {0x00f3, 0x97} /* small letter o with acute */, + {0x00f4, 0x99} /* small letter o with circumflex */, + {0x00f5, 0x9b} /* small letter o with tilde */, + {0x00f6, 0x9a} /* small letter o with diaeresis */, + {0x00f7, 0xd6} /* sign */, + {0x00f8, 0xbf} /* small letter o with stroke */, + {0x00f9, 0x9d} /* small letter u with grave */, + {0x00fa, 0x9c} /* small letter u with acute */, + {0x00fb, 0x9e} /* small letter u with circumflex */, + {0x00fc, 0x9f} /* small letter u with diaeresis */, + {0x00fe, 0xdf} /* small letter thorn (icelandic) */, + {0x00ff, 0xd8} /* small letter y with diaeresis */, + {0x0110, 0xdc} /* capital letter d with stroke */, + {0x0111, 0xdd} /* small letter d with stroke */, + {0x0131, 0xf5} /* small letter i dotless */, + {0x0152, 0xce} /* capital ligature oe */, + {0x0153, 0xcf} /* small ligature oe */, + {0x0178, 0xd9} /* capital letter y with diaeresis */, + {0x0192, 0xc4} /* minuscule latine f hameçon */, + {0x02c7, 0xff} /* caron */, + {0x02d8, 0xf9} /* breve */, + {0x02d9, 0xfa} /* above */, + {0x02da, 0xfb} /* above */, + {0x02db, 0xfe} /* ogonek */, + {0x02dd, 0xfd} /* acute accent */, + {0x0394, 0xc6} /* capital letter delta */, + {0x03a9, 0xbd} /* capital letter omega */, + {0x03c0, 0xb9} /* small letter pi */, + {0x2013, 0xd1} /* dash */, + {0x2014, 0xd0} /* dash */, + {0x2018, 0xd4} /* single quotation mark */, + {0x2019, 0xd5} /* single quotation mark */, + {0x201a, 0xe2} /* low-9 quotation mark */, + {0x201c, 0xd2} /* double quotation mark */, + {0x201d, 0xd3} /* double quotation mark */, + {0x201e, 0xe3} /* low-9 quotation mark */, + {0x2020, 0xa0} /* dagger */, + {0x2021, 0xe0} /* dagger */, + {0x2022, 0xa5} /* puce */, + {0x2026, 0xc9} /* horizontal ellipsis */, + {0x2030, 0xe4} /* mille sign */, + {0x2044, 0xda} /* slash */, + {0x2122, 0xaa} /* mark sign */, + {0x2202, 0xb6} /* differential */, + {0x220f, 0xb8} /* product */, + {0x2211, 0xb7} /* summation */, + {0x221a, 0xc3} /* root */, + {0x221e, 0xb0} /* infinity */, + {0x222b, 0xba} /* integral */, + {0x2248, 0xc5} /* equal to */, + {0x2260, 0xad} /* equal to */, + {0x2264, 0xb2} /* or equal to */, + {0x2265, 0xb3} /* or equal to */, + {0x25c6, 0xd7} /* diamond */, + {0xe01e, 0xf0} /* */ +}; + +/* +#define cet_ucs4_to_mac_is_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_mac_is_extra[cet_ucs4_to_mac_is_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_mac_is = /* defined in cet.h */ +{ + cet_cs_name_mac_is, /* name of character set */ + cet_cs_alias_mac_is, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_mac_is, /* char to UCS-4 value table */ + cet_ucs4_ofs_mac_is, /* first non standard character */ + cet_ucs4_cnt_mac_is, /* number of values in table */ + + cet_ucs4_to_mac_is_links, /* UCS-4 to char links */ + cet_ucs4_to_mac_is_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int mac_is_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + 0x2014, 0x2013, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25c6, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x0110, 0x0111, 0x00de, 0x00fe, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xe01e, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, -1, -1, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7 +}; +*/ + +#endif diff --git a/cet/macintosh.h b/cet/macintosh.h new file mode 100644 index 000000000..f4f29735f --- /dev/null +++ b/cet/macintosh.h @@ -0,0 +1,250 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "macintosh" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef macintosh_h +#define macintosh_h + +#define cet_cs_name_macintosh "macintosh" + +const char *cet_cs_alias_macintosh[] = +{ + "macintosh", "csMacintosh", "mac", "MacRoman", + NULL +}; + +#define cet_ucs4_ofs_macintosh 128 +#define cet_ucs4_cnt_macintosh 128 + +const int cet_ucs4_map_macintosh[cet_ucs4_cnt_macintosh] = +{ + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x2126, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x2039, 0x203a, 0xfb01, 0xfb02, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xe01e, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, -1, -1, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7 +}; + +#define cet_ucs4_to_macintosh_ct 121 + +const cet_ucs4_link_t cet_ucs4_to_macintosh_links[cet_ucs4_to_macintosh_ct] = +{ + {0x00a0, 0xca} /* space */, + {0x00a1, 0xc1} /* exclamation mark */, + {0x00a4, 0xdb} /* sign */, + {0x00a5, 0xb4} /* sign */, + {0x00a7, 0xa4} /* sign */, + {0x00a8, 0xac} /* diaeresis */, + {0x00aa, 0xbb} /* ordinal indicator */, + {0x00ab, 0xc7} /* double angle quotation mark */, + {0x00ac, 0xc2} /* sign */, + {0x00ae, 0xa8} /* sign */, + {0x00af, 0xf8} /* macron */, + {0x00b0, 0xa1} /* sign */, + {0x00b4, 0xab} /* accent */, + {0x00b6, 0xa6} /* sign */, + {0x00b7, 0xe1} /* dot */, + {0x00b8, 0xfc} /* cedilla */, + {0x00ba, 0xbc} /* ordinal indicator */, + {0x00bb, 0xc8} /* double angle quotation mark */, + {0x00bf, 0xc0} /* question mark */, + {0x00c0, 0xcb} /* capital letter a with grave */, + {0x00c1, 0xe7} /* capital letter a with acute */, + {0x00c2, 0xe5} /* capital letter a with circumflex */, + {0x00c3, 0xcc} /* capital letter a with tilde */, + {0x00c4, 0x80} /* capital letter a with diaeresis */, + {0x00c5, 0x81} /* capital letter a with ring above */, + {0x00c6, 0xae} /* capital letter ae */, + {0x00c7, 0x82} /* capital letter c with cedilla */, + {0x00c8, 0xe9} /* capital letter e with grave */, + {0x00c9, 0x83} /* capital letter e with acute */, + {0x00ca, 0xe6} /* capital letter e with circumflex */, + {0x00cb, 0xe8} /* capital letter e with diaeresis */, + {0x00cc, 0xed} /* capital letter i with grave */, + {0x00cd, 0xea} /* capital letter i with acute */, + {0x00ce, 0xeb} /* capital letter i with circumflex */, + {0x00cf, 0xec} /* capital letter i with diaeresis */, + {0x00d1, 0x84} /* capital letter n with tilde */, + {0x00d2, 0xf1} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xef} /* capital letter o with circumflex */, + {0x00d6, 0x85} /* capital letter o with diaeresis */, + {0x00d8, 0xaf} /* capital letter o with stroke */, + {0x00d9, 0xf4} /* capital letter u with grave */, + {0x00da, 0xf2} /* capital letter u with acute */, + {0x00db, 0xf3} /* capital letter u with circumflex */, + {0x00dc, 0x86} /* capital letter u with diaeresis */, + {0x00df, 0xa7} /* small letter sharp s (german) */, + {0x00e0, 0x88} /* small letter a with grave */, + {0x00e1, 0x87} /* small letter a with acute */, + {0x00e2, 0x89} /* small letter a with circumflex */, + {0x00e3, 0x8b} /* small letter a with tilde */, + {0x00e4, 0x8a} /* small letter a with diaeresis */, + {0x00e5, 0x8c} /* small letter a with ring above */, + {0x00e6, 0xbe} /* small letter ae */, + {0x00e7, 0x8d} /* small letter c with cedilla */, + {0x00e8, 0x8f} /* small letter e with grave */, + {0x00e9, 0x8e} /* small letter e with acute */, + {0x00ea, 0x90} /* small letter e with circumflex */, + {0x00eb, 0x91} /* small letter e with diaeresis */, + {0x00ec, 0x93} /* small letter i with grave */, + {0x00ed, 0x92} /* small letter i with acute */, + {0x00ee, 0x94} /* small letter i with circumflex */, + {0x00ef, 0x95} /* small letter i with diaeresis */, + {0x00f1, 0x96} /* small letter n with tilde */, + {0x00f2, 0x98} /* small letter o with grave */, + {0x00f3, 0x97} /* small letter o with acute */, + {0x00f4, 0x99} /* small letter o with circumflex */, + {0x00f5, 0x9b} /* small letter o with tilde */, + {0x00f6, 0x9a} /* small letter o with diaeresis */, + {0x00f7, 0xd6} /* sign */, + {0x00f8, 0xbf} /* small letter o with stroke */, + {0x00f9, 0x9d} /* small letter u with grave */, + {0x00fa, 0x9c} /* small letter u with acute */, + {0x00fb, 0x9e} /* small letter u with circumflex */, + {0x00fc, 0x9f} /* small letter u with diaeresis */, + {0x00ff, 0xd8} /* small letter y with diaeresis */, + {0x0131, 0xf5} /* small letter i dotless */, + {0x0152, 0xce} /* capital ligature oe */, + {0x0153, 0xcf} /* small ligature oe */, + {0x0178, 0xd9} /* capital letter y with diaeresis */, + {0x0192, 0xc4} /* minuscule latine f hameçon */, + {0x02c7, 0xff} /* caron */, + {0x02d8, 0xf9} /* breve */, + {0x02d9, 0xfa} /* above */, + {0x02da, 0xfb} /* above */, + {0x02db, 0xfe} /* ogonek */, + {0x02dd, 0xfd} /* acute accent */, + {0x0394, 0xc6} /* capital letter delta */, + {0x03a9, 0xbd} /* capital letter omega */, + {0x03c0, 0xb9} /* small letter pi */, + {0x2013, 0xd0} /* dash */, + {0x2014, 0xd1} /* dash */, + {0x2018, 0xd4} /* single quotation mark */, + {0x2019, 0xd5} /* single quotation mark */, + {0x201a, 0xe2} /* low-9 quotation mark */, + {0x201c, 0xd2} /* double quotation mark */, + {0x201d, 0xd3} /* double quotation mark */, + {0x201e, 0xe3} /* low-9 quotation mark */, + {0x2020, 0xa0} /* dagger */, + {0x2021, 0xe0} /* dagger */, + {0x2022, 0xa5} /* puce */, + {0x2026, 0xc9} /* horizontal ellipsis */, + {0x2030, 0xe4} /* mille sign */, + {0x2039, 0xdc} /* left-pointing angle quotation mark */, + {0x203a, 0xdd} /* right-pointing angle quotation mark */, + {0x2044, 0xda} /* slash */, + {0x2122, 0xaa} /* mark sign */, + {0x2126, 0xcd} /* sign */, + {0x2202, 0xb6} /* differential */, + {0x220f, 0xb8} /* product */, + {0x2211, 0xb7} /* summation */, + {0x221a, 0xc3} /* root */, + {0x221e, 0xb0} /* infinity */, + {0x222b, 0xba} /* integral */, + {0x2248, 0xc5} /* equal to */, + {0x2260, 0xad} /* equal to */, + {0x2264, 0xb2} /* or equal to */, + {0x2265, 0xb3} /* or equal to */, + {0x25ca, 0xd7} /* lozenge */, + {0xe01e, 0xf0} /* */, + {0xfb01, 0xde} /* small ligature fi */, + {0xfb02, 0xdf} /* small ligature fl */ +}; + +/* +#define cet_ucs4_to_macintosh_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_macintosh_extra[cet_ucs4_to_macintosh_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_macintosh = /* defined in cet.h */ +{ + cet_cs_name_macintosh, /* name of character set */ + cet_cs_alias_macintosh, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_macintosh, /* char to UCS-4 value table */ + cet_ucs4_ofs_macintosh, /* first non standard character */ + cet_ucs4_cnt_macintosh, /* number of values in table */ + + cet_ucs4_to_macintosh_links, /* UCS-4 to char links */ + cet_ucs4_to_macintosh_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int macintosh_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x2126, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x2039, 0x203a, 0xfb01, 0xfb02, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xe01e, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, -1, -1, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7 +}; +*/ + +#endif diff --git a/cet/macintosh_ce.h b/cet/macintosh_ce.h new file mode 100644 index 000000000..4507de637 --- /dev/null +++ b/cet/macintosh_ce.h @@ -0,0 +1,254 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "macintosh_ce" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef macintosh_ce_h +#define macintosh_ce_h + +#define cet_cs_name_macintosh_ce "macintosh_ce" + +const char *cet_cs_alias_macintosh_ce[] = +{ + "macintosh_ce", "macce", NULL +}; + +#define cet_ucs4_ofs_macintosh_ce 128 +#define cet_ucs4_cnt_macintosh_ce 128 + +const int cet_ucs4_map_macintosh_ce[cet_ucs4_cnt_macintosh_ce] = +{ + 0x00c4, 0x0100, 0x0101, 0x00c9, 0x0104, 0x00d6, 0x00dc, 0x00e1, + 0x0105, 0x010c, 0x00e4, 0x010d, 0x0106, 0x0107, 0x00e9, 0x0179, + 0x017a, 0x010e, 0x00ed, 0x010f, 0x0112, 0x0113, 0x0116, 0x00f3, + 0x0117, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x011a, 0x011b, 0x00fc, + 0x2020, 0x00b0, 0x0118, 0x00a3, 0x00a7, 0x2219, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x0119, 0x00a8, 0x2260, 0x01f5, 0x012e, + 0x012f, 0x012a, 0x2264, 0x2265, 0x012b, 0x0136, 0x2202, 0x2211, + 0x0142, 0x013b, 0x013c, 0x013d, 0x013e, 0x0139, 0x013a, 0x0145, + 0x0146, 0x0143, 0x00ac, 0x221a, 0x0144, 0x0147, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x0148, 0x0150, 0x00d5, 0x0151, 0x014c, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25c6, + 0x014d, 0x0154, 0x0155, 0x0158, 0x2039, 0x203a, 0x0159, 0x0156, + 0x0157, 0x0160, 0x201a, 0x201e, 0x0161, 0x015a, 0x015b, 0x00c1, + 0x0164, 0x0165, 0x00cd, 0x017d, 0x017e, 0x016a, 0x00d3, 0x00d4, + 0x016b, 0x016e, 0x00da, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, + 0x00dd, 0x00fd, 0x0137, 0x017b, 0x0141, 0x017c, 0x0122, 0x02c7 +}; + +#define cet_ucs4_to_macintosh_ce_ct 126 + +const cet_ucs4_link_t cet_ucs4_to_macintosh_ce_links[cet_ucs4_to_macintosh_ce_ct] = +{ + {0x00a0, 0xca} /* space */, + {0x00a7, 0xa4} /* sign */, + {0x00a8, 0xac} /* diaeresis */, + {0x00ab, 0xc7} /* double angle quotation mark */, + {0x00ac, 0xc2} /* sign */, + {0x00ae, 0xa8} /* sign */, + {0x00b0, 0xa1} /* sign */, + {0x00b6, 0xa6} /* sign */, + {0x00bb, 0xc8} /* double angle quotation mark */, + {0x00c1, 0xe7} /* capital letter a with acute */, + {0x00c4, 0x80} /* capital letter a with diaeresis */, + {0x00c9, 0x83} /* capital letter e with acute */, + {0x00cd, 0xea} /* capital letter i with acute */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xef} /* capital letter o with circumflex */, + {0x00d5, 0xcd} /* capital letter o with tilde */, + {0x00d6, 0x85} /* capital letter o with diaeresis */, + {0x00da, 0xf2} /* capital letter u with acute */, + {0x00dc, 0x86} /* capital letter u with diaeresis */, + {0x00dd, 0xf8} /* capital letter y with acute */, + {0x00df, 0xa7} /* small letter sharp s (german) */, + {0x00e1, 0x87} /* small letter a with acute */, + {0x00e4, 0x8a} /* small letter a with diaeresis */, + {0x00e9, 0x8e} /* small letter e with acute */, + {0x00ed, 0x92} /* small letter i with acute */, + {0x00f3, 0x97} /* small letter o with acute */, + {0x00f4, 0x99} /* small letter o with circumflex */, + {0x00f5, 0x9b} /* small letter o with tilde */, + {0x00f6, 0x9a} /* small letter o with diaeresis */, + {0x00f7, 0xd6} /* sign */, + {0x00fa, 0x9c} /* small letter u with acute */, + {0x00fc, 0x9f} /* small letter u with diaeresis */, + {0x00fd, 0xf9} /* small letter y with acute */, + {0x0100, 0x81} /* capital letter a with macron */, + {0x0101, 0x82} /* small letter a with macron */, + {0x0104, 0x84} /* capital letter a with ogonek */, + {0x0105, 0x88} /* small letter a with ogonek */, + {0x0106, 0x8c} /* capital letter c with acute */, + {0x0107, 0x8d} /* small letter c with acute */, + {0x010c, 0x89} /* capital letter c with caron */, + {0x010d, 0x8b} /* small letter c with caron */, + {0x010e, 0x91} /* capital letter d with caron */, + {0x010f, 0x93} /* small letter d with caron */, + {0x0112, 0x94} /* capital letter e with macron */, + {0x0113, 0x95} /* small letter e with macron */, + {0x0116, 0x96} /* capital letter e with dot above */, + {0x0117, 0x98} /* small letter e with dot above */, + {0x0118, 0xa2} /* capital letter e with ogonek */, + {0x0119, 0xab} /* small letter e with ogonek */, + {0x011a, 0x9d} /* capital letter e with caron */, + {0x011b, 0x9e} /* small letter e with caron */, + {0x0122, 0xfe} /* capital letter g with cedilla */, + {0x012a, 0xb1} /* capital letter i with macron */, + {0x012b, 0xb4} /* small letter i with macron */, + {0x012e, 0xaf} /* capital letter i with ogonek */, + {0x012f, 0xb0} /* small letter i with ogonek */, + {0x0136, 0xb5} /* capital letter k with cedilla */, + {0x0137, 0xfa} /* small letter k with cedilla */, + {0x0139, 0xbd} /* capital letter l with acute */, + {0x013a, 0xbe} /* small letter l with acute */, + {0x013b, 0xb9} /* capital letter l with cedilla */, + {0x013c, 0xba} /* small letter l with cedilla */, + {0x013d, 0xbb} /* capital letter l with caron */, + {0x013e, 0xbc} /* small letter l with caron */, + {0x0141, 0xfc} /* capital letter l with stroke */, + {0x0142, 0xb8} /* small letter l with stroke */, + {0x0143, 0xc1} /* capital letter n with acute */, + {0x0144, 0xc4} /* small letter n with acute */, + {0x0145, 0xbf} /* capital letter n with cedilla */, + {0x0146, 0xc0} /* small letter n with cedilla */, + {0x0147, 0xc5} /* capital letter n with caron */, + {0x0148, 0xcb} /* small letter n with caron */, + {0x014c, 0xcf} /* capital letter o with macron */, + {0x014d, 0xd8} /* small letter o with macron */, + {0x0150, 0xcc} /* capital letter o with double acute */, + {0x0151, 0xce} /* small letter o with double acute */, + {0x0154, 0xd9} /* capital letter r with acute */, + {0x0155, 0xda} /* small letter r with acute */, + {0x0156, 0xdf} /* capital letter r with cedilla */, + {0x0157, 0xe0} /* small letter r with cedilla */, + {0x0158, 0xdb} /* capital letter r with caron */, + {0x0159, 0xde} /* small letter r with caron */, + {0x015a, 0xe5} /* capital letter s with acute */, + {0x015b, 0xe6} /* small letter s with acute */, + {0x0160, 0xe1} /* capital letter s with caron */, + {0x0161, 0xe4} /* small letter s with caron */, + {0x0164, 0xe8} /* capital letter t with caron */, + {0x0165, 0xe9} /* small letter t with caron */, + {0x016a, 0xed} /* capital letter u with macron */, + {0x016b, 0xf0} /* small letter u with macron */, + {0x016e, 0xf1} /* capital letter u with ring above */, + {0x016f, 0xf3} /* small letter u with ring above */, + {0x0170, 0xf4} /* capital letter u with double acute */, + {0x0171, 0xf5} /* small letter u with double acute */, + {0x0172, 0xf6} /* capital letter u with ogonek */, + {0x0173, 0xf7} /* small letter u with ogonek */, + {0x0179, 0x8f} /* capital letter z with acute */, + {0x017a, 0x90} /* small letter z with acute */, + {0x017b, 0xfb} /* capital letter z with dot above */, + {0x017c, 0xfd} /* small letter z with dot above */, + {0x017d, 0xeb} /* capital letter z with caron */, + {0x017e, 0xec} /* small letter z with caron */, + {0x01f5, 0xae} /* small letter g with acute */, + {0x02c7, 0xff} /* caron */, + {0x0394, 0xc6} /* capital letter delta */, + {0x2013, 0xd0} /* dash */, + {0x2014, 0xd1} /* dash */, + {0x2018, 0xd4} /* single quotation mark */, + {0x2019, 0xd5} /* single quotation mark */, + {0x201a, 0xe2} /* low-9 quotation mark */, + {0x201c, 0xd2} /* double quotation mark */, + {0x201d, 0xd3} /* double quotation mark */, + {0x201e, 0xe3} /* low-9 quotation mark */, + {0x2020, 0xa0} /* dagger */, + {0x2026, 0xc9} /* horizontal ellipsis */, + {0x2039, 0xdc} /* left-pointing angle quotation mark */, + {0x203a, 0xdd} /* right-pointing angle quotation mark */, + {0x2122, 0xaa} /* mark sign */, + {0x2202, 0xb6} /* differential */, + {0x2211, 0xb7} /* summation */, + {0x2219, 0xa5} /* operator */, + {0x221a, 0xc3} /* root */, + {0x2260, 0xad} /* equal to */, + {0x2264, 0xb2} /* or equal to */, + {0x2265, 0xb3} /* or equal to */, + {0x25c6, 0xd7} /* diamond */ +}; + +/* +#define cet_ucs4_to_macintosh_ce_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_macintosh_ce_extra[cet_ucs4_to_macintosh_ce_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_macintosh_ce = /* defined in cet.h */ +{ + cet_cs_name_macintosh_ce, /* name of character set */ + cet_cs_alias_macintosh_ce, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_macintosh_ce, /* char to UCS-4 value table */ + cet_ucs4_ofs_macintosh_ce, /* first non standard character */ + cet_ucs4_cnt_macintosh_ce, /* number of values in table */ + + cet_ucs4_to_macintosh_ce_links, /* UCS-4 to char links */ + cet_ucs4_to_macintosh_ce_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int macintosh_ce_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c4, 0x0100, 0x0101, 0x00c9, 0x0104, 0x00d6, 0x00dc, 0x00e1, + 0x0105, 0x010c, 0x00e4, 0x010d, 0x0106, 0x0107, 0x00e9, 0x0179, + 0x017a, 0x010e, 0x00ed, 0x010f, 0x0112, 0x0113, 0x0116, 0x00f3, + 0x0117, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x011a, 0x011b, 0x00fc, + 0x2020, 0x00b0, 0x0118, 0x00a3, 0x00a7, 0x2219, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x0119, 0x00a8, 0x2260, 0x01f5, 0x012e, + 0x012f, 0x012a, 0x2264, 0x2265, 0x012b, 0x0136, 0x2202, 0x2211, + 0x0142, 0x013b, 0x013c, 0x013d, 0x013e, 0x0139, 0x013a, 0x0145, + 0x0146, 0x0143, 0x00ac, 0x221a, 0x0144, 0x0147, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x0148, 0x0150, 0x00d5, 0x0151, 0x014c, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25c6, + 0x014d, 0x0154, 0x0155, 0x0158, 0x2039, 0x203a, 0x0159, 0x0156, + 0x0157, 0x0160, 0x201a, 0x201e, 0x0161, 0x015a, 0x015b, 0x00c1, + 0x0164, 0x0165, 0x00cd, 0x017d, 0x017e, 0x016a, 0x00d3, 0x00d4, + 0x016b, 0x016e, 0x00da, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, + 0x00dd, 0x00fd, 0x0137, 0x017b, 0x0141, 0x017c, 0x0122, 0x02c7 +}; +*/ + +#endif diff --git a/cet/msz_7795_3.h b/cet/msz_7795_3.h new file mode 100644 index 000000000..0034a41bf --- /dev/null +++ b/cet/msz_7795_3.h @@ -0,0 +1,135 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "MSZ_7795.3" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef msz_7795_3_h +#define msz_7795_3_h + +#define cet_cs_name_msz_7795_3 "MSZ_7795.3" + +const char *cet_cs_alias_msz_7795_3[] = +{ + "MSZ_7795.3", "hu", "ISO646-HU", "iso-ir-86", + NULL +}; + +#define cet_ucs4_ofs_msz_7795_3 36 +#define cet_ucs4_cnt_msz_7795_3 92 + +const int cet_ucs4_map_msz_7795_3[cet_ucs4_cnt_msz_7795_3] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x00c1, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00c9, + 0x00d6, 0x00dc, 0x005e, 0x005f, 0x00e1, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00e9, + 0x00f6, 0x00fc, 0x02dd, 0x007f +}; + +#define cet_ucs4_to_msz_7795_3_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_msz_7795_3_links[cet_ucs4_to_msz_7795_3_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x00c1, 0x40} /* capital letter a with acute */, + {0x00c9, 0x5b} /* capital letter e with acute */, + {0x00d6, 0x5c} /* capital letter o with diaeresis */, + {0x00dc, 0x5d} /* capital letter u with diaeresis */, + {0x00e1, 0x60} /* small letter a with acute */, + {0x00e9, 0x7b} /* small letter e with acute */, + {0x00f6, 0x7c} /* small letter o with diaeresis */, + {0x00fc, 0x7d} /* small letter u with diaeresis */, + {0x02dd, 0x7e} /* acute accent */ +}; + +/* +#define cet_ucs4_to_msz_7795_3_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_msz_7795_3_extra[cet_ucs4_to_msz_7795_3_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_msz_7795_3 = /* defined in cet.h */ +{ + cet_cs_name_msz_7795_3, /* name of character set */ + cet_cs_alias_msz_7795_3, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_msz_7795_3, /* char to UCS-4 value table */ + cet_ucs4_ofs_msz_7795_3, /* first non standard character */ + cet_ucs4_cnt_msz_7795_3, /* number of values in table */ + + cet_ucs4_to_msz_7795_3_links, /* UCS-4 to char links */ + cet_ucs4_to_msz_7795_3_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int msz_7795_3_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00c1, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c9, 0x00d6, 0x00dc, 0x005e, 0x005f, + 0x00e1, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f6, 0x00fc, 0x02dd, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/nats_dano.h b/cet/nats_dano.h new file mode 100644 index 000000000..beb3433a4 --- /dev/null +++ b/cet/nats_dano.h @@ -0,0 +1,136 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NATS-DANO" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nats_dano_h +#define nats_dano_h + +#define cet_cs_name_nats_dano "NATS-DANO" + +const char *cet_cs_alias_nats_dano[] = +{ + "NATS-DANO", "iso-ir-9-1", NULL +}; + +#define cet_ucs4_ofs_nats_dano 34 +#define cet_ucs4_cnt_nats_dano 94 + +const int cet_ucs4_map_nats_dano[cet_ucs4_cnt_nats_dano] = +{ + 0x00ab, 0x00bb, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, + 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, + 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0xe018, 0x0041, + 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, + 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, + 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x25a0, 0x005f, 0xe019, 0x0061, + 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, + 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, + 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x2013, 0x007f +}; + +#define cet_ucs4_to_nats_dano_ct 12 + +const cet_ucs4_link_t cet_ucs4_to_nats_dano_links[cet_ucs4_to_nats_dano_ct] = +{ + {0x00ab, 0x22} /* double angle quotation mark */, + {0x00bb, 0x23} /* double angle quotation mark */, + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00c6, 0x5b} /* capital letter ae */, + {0x00d8, 0x5c} /* capital letter o with stroke */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00e6, 0x7b} /* small letter ae */, + {0x00f8, 0x7c} /* small letter o with stroke */, + {0x2013, 0x7e} /* dash */, + {0x25a0, 0x5e} /* square */, + {0xe018, 0x40} /* space a (iso-ir-8-1 064) */, + {0xe019, 0x60} /* space b (iso-ir-8-1 096) */ +}; + +/* +#define cet_ucs4_to_nats_dano_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nats_dano_extra[cet_ucs4_to_nats_dano_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nats_dano = /* defined in cet.h */ +{ + cet_cs_name_nats_dano, /* name of character set */ + cet_cs_alias_nats_dano, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nats_dano, /* char to UCS-4 value table */ + cet_ucs4_ofs_nats_dano, /* first non standard character */ + cet_ucs4_cnt_nats_dano, /* number of values in table */ + + cet_ucs4_to_nats_dano_links, /* UCS-4 to char links */ + cet_ucs4_to_nats_dano_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nats_dano_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x00ab, 0x00bb, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0xe018, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x25a0, 0x005f, + 0xe019, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x2013, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/nats_sefi.h b/cet/nats_sefi.h new file mode 100644 index 000000000..93c0713ec --- /dev/null +++ b/cet/nats_sefi.h @@ -0,0 +1,130 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NATS-SEFI" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nats_sefi_h +#define nats_sefi_h + +#define cet_cs_name_nats_sefi "NATS-SEFI" + +const char *cet_cs_alias_nats_sefi[] = +{ + "NATS-SEFI", "iso-ir-8-1", NULL +}; + +#define cet_ucs4_ofs_nats_sefi 64 +#define cet_ucs4_cnt_nats_sefi 64 + +const int cet_ucs4_map_nats_sefi[cet_ucs4_cnt_nats_sefi] = +{ + 0xe018, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00c5, 0x25a0, 0x005f, + 0xe019, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00e5, 0x2013, 0x007f +}; + +#define cet_ucs4_to_nats_sefi_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_nats_sefi_links[cet_ucs4_to_nats_sefi_ct] = +{ + {0x00c4, 0x5b} /* capital letter a with diaeresis */, + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00d6, 0x5c} /* capital letter o with diaeresis */, + {0x00e4, 0x7b} /* small letter a with diaeresis */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00f6, 0x7c} /* small letter o with diaeresis */, + {0x2013, 0x7e} /* dash */, + {0x25a0, 0x5e} /* square */, + {0xe018, 0x40} /* space a (iso-ir-8-1 064) */, + {0xe019, 0x60} /* space b (iso-ir-8-1 096) */ +}; + +/* +#define cet_ucs4_to_nats_sefi_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nats_sefi_extra[cet_ucs4_to_nats_sefi_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nats_sefi = /* defined in cet.h */ +{ + cet_cs_name_nats_sefi, /* name of character set */ + cet_cs_alias_nats_sefi, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nats_sefi, /* char to UCS-4 value table */ + cet_ucs4_ofs_nats_sefi, /* first non standard character */ + cet_ucs4_cnt_nats_sefi, /* number of values in table */ + + cet_ucs4_to_nats_sefi_links, /* UCS-4 to char links */ + cet_ucs4_to_nats_sefi_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nats_sefi_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0xe018, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00c5, 0x25a0, 0x005f, + 0xe019, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00e5, 0x2013, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/nc_nc00_10.h b/cet/nc_nc00_10.h new file mode 100644 index 000000000..256cc493c --- /dev/null +++ b/cet/nc_nc00_10.h @@ -0,0 +1,133 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NC_NC00-10" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nc_nc00_10_h +#define nc_nc00_10_h + +#define cet_cs_name_nc_nc00_10 "NC_NC00-10" + +const char *cet_cs_alias_nc_nc00_10[] = +{ + "NC_NC00-10", "cuba", "ISO646-CU", "iso-ir-151", + "NC_NC00-10:81", NULL +}; + +#define cet_ucs4_ofs_nc_nc00_10 36 +#define cet_ucs4_cnt_nc_nc00_10 92 + +const int cet_ucs4_map_nc_nc00_10[cet_ucs4_cnt_nc_nc00_10] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00a1, + 0x00d1, 0x005d, 0x00bf, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00b4, + 0x00f1, 0x005b, 0x00a8, 0x007f +}; + +#define cet_ucs4_to_nc_nc00_10_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_nc_nc00_10_links[cet_ucs4_to_nc_nc00_10_ct] = +{ + {0x005b, 0x7d} /* square bracket */, + {0x00a1, 0x5b} /* exclamation mark */, + {0x00a4, 0x24} /* sign */, + {0x00a8, 0x7e} /* diaeresis */, + {0x00b4, 0x7b} /* accent */, + {0x00bf, 0x5e} /* question mark */, + {0x00d1, 0x5c} /* capital letter n with tilde */, + {0x00f1, 0x7c} /* small letter n with tilde */ +}; + +/* +#define cet_ucs4_to_nc_nc00_10_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nc_nc00_10_extra[cet_ucs4_to_nc_nc00_10_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nc_nc00_10 = /* defined in cet.h */ +{ + cet_cs_name_nc_nc00_10, /* name of character set */ + cet_cs_alias_nc_nc00_10, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nc_nc00_10, /* char to UCS-4 value table */ + cet_ucs4_ofs_nc_nc00_10, /* first non standard character */ + cet_ucs4_cnt_nc_nc00_10, /* number of values in table */ + + cet_ucs4_to_nc_nc00_10_links, /* UCS-4 to char links */ + cet_ucs4_to_nc_nc00_10_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nc_nc00_10_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00a1, 0x00d1, 0x005d, 0x00bf, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00b4, 0x00f1, 0x005b, 0x00a8, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/nextstep.h b/cet/nextstep.h new file mode 100644 index 000000000..f4e4a5d3a --- /dev/null +++ b/cet/nextstep.h @@ -0,0 +1,240 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NeXTSTEP" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nextstep_h +#define nextstep_h + +#define cet_cs_name_nextstep "NeXTSTEP" + +const char *cet_cs_alias_nextstep[] = +{ + "NeXTSTEP", "next", NULL +}; + +#define cet_ucs4_ofs_nextstep 128 +#define cet_ucs4_cnt_nextstep 126 + +const int cet_ucs4_map_nextstep[cet_ucs4_cnt_nextstep] = +{ + 0x00a0, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d9, + 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00b5, 0x00d7, 0x00f7, + 0x00a9, 0x00a1, 0x00a2, 0x00a3, 0x2044, 0x00a5, 0x0192, 0x00a7, + 0x00a4, -1, 0x201c, 0x00ab, -1, -1, 0xfb01, 0xfb02, + 0x00ae, 0x2013, 0x2020, 0x2021, 0x00b7, 0x00a6, 0x00b6, 0x2022, + -1, -1, 0x201d, 0x00bb, 0x2026, 0x2030, 0x00ac, 0x00bf, + 0x00b9, 0x02cb, 0x00b4, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, + 0x00a8, 0x00b2, 0x02da, 0x00b8, 0x00b3, 0x02dd, 0x02db, 0x02c7, + 0x2014, 0x00b1, 0x00bc, 0x00bd, 0x00be, 0x00e0, 0x00e1, 0x00e2, + 0x00e3, 0x00e4, 0x00e5, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, + 0x00ec, 0x00c6, 0x00ed, 0x00aa, 0x00ee, 0x00ef, 0x00f0, 0x00f1, + 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00f2, 0x00f3, 0x00f4, 0x00f5, + 0x00f6, 0x00e6, 0x00f9, 0x00fa, 0x00fb, 0x0131, 0x00fc, 0x00fd, + 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x00ff +}; + +#define cet_ucs4_to_nextstep_ct 112 + +const cet_ucs4_link_t cet_ucs4_to_nextstep_links[cet_ucs4_to_nextstep_ct] = +{ + {0x00a0, 0x80} /* space */, + {0x00a4, 0xa8} /* sign */, + {0x00a6, 0xb5} /* bar */, + {0x00a8, 0xc8} /* diaeresis */, + {0x00a9, 0xa0} /* sign */, + {0x00aa, 0xe3} /* ordinal indicator */, + {0x00ac, 0xbe} /* sign */, + {0x00ae, 0xb0} /* sign */, + {0x00af, 0xc5} /* macron */, + {0x00b1, 0xd1} /* sign */, + {0x00b2, 0xc9} /* two */, + {0x00b3, 0xcc} /* three */, + {0x00b4, 0xc2} /* accent */, + {0x00b5, 0x9d} /* sign */, + {0x00b7, 0xb4} /* dot */, + {0x00b8, 0xcb} /* cedilla */, + {0x00b9, 0xc0} /* one */, + {0x00ba, 0xeb} /* ordinal indicator */, + {0x00bc, 0xd2} /* fraction one quarter */, + {0x00bd, 0xd3} /* fraction one half */, + {0x00be, 0xd4} /* fraction three quarters */, + {0x00c0, 0x81} /* capital letter a with grave */, + {0x00c1, 0x82} /* capital letter a with acute */, + {0x00c2, 0x83} /* capital letter a with circumflex */, + {0x00c3, 0x84} /* capital letter a with tilde */, + {0x00c4, 0x85} /* capital letter a with diaeresis */, + {0x00c5, 0x86} /* capital letter a with ring above */, + {0x00c6, 0xe1} /* capital letter ae */, + {0x00c7, 0x87} /* capital letter c with cedilla */, + {0x00c8, 0x88} /* capital letter e with grave */, + {0x00c9, 0x89} /* capital letter e with acute */, + {0x00ca, 0x8a} /* capital letter e with circumflex */, + {0x00cb, 0x8b} /* capital letter e with diaeresis */, + {0x00cc, 0x8c} /* capital letter i with grave */, + {0x00cd, 0x8d} /* capital letter i with acute */, + {0x00ce, 0x8e} /* capital letter i with circumflex */, + {0x00cf, 0x8f} /* capital letter i with diaeresis */, + {0x00d0, 0x90} /* capital letter eth (icelandic) */, + {0x00d1, 0x91} /* capital letter n with tilde */, + {0x00d2, 0x92} /* capital letter o with grave */, + {0x00d3, 0x93} /* capital letter o with acute */, + {0x00d4, 0x94} /* capital letter o with circumflex */, + {0x00d5, 0x95} /* capital letter o with tilde */, + {0x00d6, 0x96} /* capital letter o with diaeresis */, + {0x00d7, 0x9e} /* sign */, + {0x00d8, 0xe9} /* capital letter o with stroke */, + {0x00d9, 0x97} /* capital letter u with grave */, + {0x00da, 0x98} /* capital letter u with acute */, + {0x00db, 0x99} /* capital letter u with circumflex */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00dd, 0x9b} /* capital letter y with acute */, + {0x00de, 0x9c} /* capital letter thorn (icelandic) */, + {0x00df, 0xfb} /* small letter sharp s (german) */, + {0x00e0, 0xd5} /* small letter a with grave */, + {0x00e1, 0xd6} /* small letter a with acute */, + {0x00e2, 0xd7} /* small letter a with circumflex */, + {0x00e3, 0xd8} /* small letter a with tilde */, + {0x00e4, 0xd9} /* small letter a with diaeresis */, + {0x00e5, 0xda} /* small letter a with ring above */, + {0x00e6, 0xf1} /* small letter ae */, + {0x00e7, 0xdb} /* small letter c with cedilla */, + {0x00e8, 0xdc} /* small letter e with grave */, + {0x00e9, 0xdd} /* small letter e with acute */, + {0x00ea, 0xde} /* small letter e with circumflex */, + {0x00eb, 0xdf} /* small letter e with diaeresis */, + {0x00ec, 0xe0} /* small letter i with grave */, + {0x00ed, 0xe2} /* small letter i with acute */, + {0x00ee, 0xe4} /* small letter i with circumflex */, + {0x00ef, 0xe5} /* small letter i with diaeresis */, + {0x00f0, 0xe6} /* small letter eth (icelandic) */, + {0x00f1, 0xe7} /* small letter n with tilde */, + {0x00f2, 0xec} /* small letter o with grave */, + {0x00f3, 0xed} /* small letter o with acute */, + {0x00f4, 0xee} /* small letter o with circumflex */, + {0x00f5, 0xef} /* small letter o with tilde */, + {0x00f6, 0xf0} /* small letter o with diaeresis */, + {0x00f7, 0x9f} /* sign */, + {0x00f8, 0xf9} /* small letter o with stroke */, + {0x00f9, 0xf2} /* small letter u with grave */, + {0x00fa, 0xf3} /* small letter u with acute */, + {0x00fb, 0xf4} /* small letter u with circumflex */, + {0x00fc, 0xf6} /* small letter u with diaeresis */, + {0x00fd, 0xf7} /* small letter y with acute */, + {0x00fe, 0xfc} /* small letter thorn (icelandic) */, + {0x00ff, 0xfd} /* small letter y with diaeresis */, + {0x0131, 0xf5} /* small letter i dotless */, + {0x0141, 0xe8} /* capital letter l with stroke */, + {0x0142, 0xf8} /* small letter l with stroke */, + {0x0152, 0xea} /* capital ligature oe */, + {0x0153, 0xfa} /* small ligature oe */, + {0x0192, 0xa6} /* minuscule latine f hameçon */, + {0x02c6, 0xc3} /* modificative accent circonflexe */, + {0x02c7, 0xcf} /* caron */, + {0x02cb, 0xc1} /* modificative accent grave */, + {0x02d8, 0xc6} /* breve */, + {0x02d9, 0xc7} /* above */, + {0x02da, 0xca} /* above */, + {0x02db, 0xce} /* ogonek */, + {0x02dc, 0xc4} /* tilde */, + {0x02dd, 0xcd} /* acute accent */, + {0x2013, 0xb1} /* dash */, + {0x2014, 0xd0} /* dash */, + {0x201c, 0xaa} /* double quotation mark */, + {0x201d, 0xba} /* double quotation mark */, + {0x2020, 0xb2} /* dagger */, + {0x2021, 0xb3} /* dagger */, + {0x2022, 0xb7} /* puce */, + {0x2026, 0xbc} /* horizontal ellipsis */, + {0x2030, 0xbd} /* mille sign */, + {0x2044, 0xa4} /* slash */, + {0xfb01, 0xae} /* small ligature fi */, + {0xfb02, 0xaf} /* small ligature fl */ +}; + +/* +#define cet_ucs4_to_nextstep_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nextstep_extra[cet_ucs4_to_nextstep_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nextstep = /* defined in cet.h */ +{ + cet_cs_name_nextstep, /* name of character set */ + cet_cs_alias_nextstep, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nextstep, /* char to UCS-4 value table */ + cet_ucs4_ofs_nextstep, /* first non standard character */ + cet_ucs4_cnt_nextstep, /* number of values in table */ + + cet_ucs4_to_nextstep_links, /* UCS-4 to char links */ + cet_ucs4_to_nextstep_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nextstep_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00a0, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d9, + 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00b5, 0x00d7, 0x00f7, + 0x00a9, 0x00a1, 0x00a2, 0x00a3, 0x2044, 0x00a5, 0x0192, 0x00a7, + 0x00a4, -1, 0x201c, 0x00ab, -1, -1, 0xfb01, 0xfb02, + 0x00ae, 0x2013, 0x2020, 0x2021, 0x00b7, 0x00a6, 0x00b6, 0x2022, + -1, -1, 0x201d, 0x00bb, 0x2026, 0x2030, 0x00ac, 0x00bf, + 0x00b9, 0x02cb, 0x00b4, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, + 0x00a8, 0x00b2, 0x02da, 0x00b8, 0x00b3, 0x02dd, 0x02db, 0x02c7, + 0x2014, 0x00b1, 0x00bc, 0x00bd, 0x00be, 0x00e0, 0x00e1, 0x00e2, + 0x00e3, 0x00e4, 0x00e5, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, + 0x00ec, 0x00c6, 0x00ed, 0x00aa, 0x00ee, 0x00ef, 0x00f0, 0x00f1, + 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00f2, 0x00f3, 0x00f4, 0x00f5, + 0x00f6, 0x00e6, 0x00f9, 0x00fa, 0x00fb, 0x0131, 0x00fc, 0x00fd, + 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x00ff, -1, -1 +}; +*/ + +#endif diff --git a/cet/nf_z_62_010.h b/cet/nf_z_62_010.h new file mode 100644 index 000000000..97a0cea8f --- /dev/null +++ b/cet/nf_z_62_010.h @@ -0,0 +1,135 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NF_Z_62-010" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nf_z_62_010_h +#define nf_z_62_010_h + +#define cet_cs_name_nf_z_62_010 "NF_Z_62-010" + +const char *cet_cs_alias_nf_z_62_010[] = +{ + "NF_Z_62-010", "fr", "ISO646-FR", "iso-ir-69", + NULL +}; + +#define cet_ucs4_ofs_nf_z_62_010 35 +#define cet_ucs4_cnt_nf_z_62_010 93 + +const int cet_ucs4_map_nf_z_62_010[cet_ucs4_cnt_nf_z_62_010] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x00e0, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x005f, 0x00b5, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e9, 0x00f9, 0x00e8, 0x00a8, 0x007f +}; + +#define cet_ucs4_to_nf_z_62_010_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_nf_z_62_010_links[cet_ucs4_to_nf_z_62_010_ct] = +{ + {0x00a3, 0x23} /* sign */, + {0x00a7, 0x5d} /* sign */, + {0x00a8, 0x7e} /* diaeresis */, + {0x00b0, 0x5b} /* sign */, + {0x00b5, 0x60} /* sign */, + {0x00e0, 0x40} /* small letter a with grave */, + {0x00e7, 0x5c} /* small letter c with cedilla */, + {0x00e8, 0x7d} /* small letter e with grave */, + {0x00e9, 0x7b} /* small letter e with acute */, + {0x00f9, 0x7c} /* small letter u with grave */ +}; + +/* +#define cet_ucs4_to_nf_z_62_010_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nf_z_62_010_extra[cet_ucs4_to_nf_z_62_010_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nf_z_62_010 = /* defined in cet.h */ +{ + cet_cs_name_nf_z_62_010, /* name of character set */ + cet_cs_alias_nf_z_62_010, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nf_z_62_010, /* char to UCS-4 value table */ + cet_ucs4_ofs_nf_z_62_010, /* first non standard character */ + cet_ucs4_cnt_nf_z_62_010, /* number of values in table */ + + cet_ucs4_to_nf_z_62_010_links, /* UCS-4 to char links */ + cet_ucs4_to_nf_z_62_010_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nf_z_62_010_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x005f, + 0x00b5, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00a8, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/nf_z_62_010__1973_.h b/cet/nf_z_62_010__1973_.h new file mode 100644 index 000000000..b1b027cad --- /dev/null +++ b/cet/nf_z_62_010__1973_.h @@ -0,0 +1,133 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NF_Z_62-010_(1973)" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nf_z_62_010__1973__h +#define nf_z_62_010__1973__h + +#define cet_cs_name_nf_z_62_010__1973_ "NF_Z_62-010_(1973)" + +const char *cet_cs_alias_nf_z_62_010__1973_[] = +{ + "NF_Z_62-010_(1973)", "ISO646-FR1", "iso-ir-25", NULL +}; + +#define cet_ucs4_ofs_nf_z_62_010__1973_ 35 +#define cet_ucs4_cnt_nf_z_62_010__1973_ 93 + +const int cet_ucs4_map_nf_z_62_010__1973_[cet_ucs4_cnt_nf_z_62_010__1973_] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x00e0, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e9, 0x00f9, 0x00e8, 0x00a8, 0x007f +}; + +#define cet_ucs4_to_nf_z_62_010__1973__ct 9 + +const cet_ucs4_link_t cet_ucs4_to_nf_z_62_010__1973__links[cet_ucs4_to_nf_z_62_010__1973__ct] = +{ + {0x00a3, 0x23} /* sign */, + {0x00a7, 0x5d} /* sign */, + {0x00a8, 0x7e} /* diaeresis */, + {0x00b0, 0x5b} /* sign */, + {0x00e0, 0x40} /* small letter a with grave */, + {0x00e7, 0x5c} /* small letter c with cedilla */, + {0x00e8, 0x7d} /* small letter e with grave */, + {0x00e9, 0x7b} /* small letter e with acute */, + {0x00f9, 0x7c} /* small letter u with grave */ +}; + +/* +#define cet_ucs4_to_nf_z_62_010__1973__extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nf_z_62_010__1973__extra[cet_ucs4_to_nf_z_62_010__1973__extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nf_z_62_010__1973_ = /* defined in cet.h */ +{ + cet_cs_name_nf_z_62_010__1973_, /* name of character set */ + cet_cs_alias_nf_z_62_010__1973_, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nf_z_62_010__1973_, /* char to UCS-4 value table */ + cet_ucs4_ofs_nf_z_62_010__1973_, /* first non standard character */ + cet_ucs4_cnt_nf_z_62_010__1973_, /* number of values in table */ + + cet_ucs4_to_nf_z_62_010__1973__links, /* UCS-4 to char links */ + cet_ucs4_to_nf_z_62_010__1973__ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nf_z_62_010__1973__ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00a8, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ns_4551_1.h b/cet/ns_4551_1.h new file mode 100644 index 000000000..edad059e4 --- /dev/null +++ b/cet/ns_4551_1.h @@ -0,0 +1,125 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NS_4551-1" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ns_4551_1_h +#define ns_4551_1_h + +#define cet_cs_name_ns_4551_1 "NS_4551-1" + +const char *cet_cs_alias_ns_4551_1[] = +{ + "NS_4551-1", "ISO646-NO", "iso-ir-60", "no", + NULL +}; + +#define cet_ucs4_ofs_ns_4551_1 91 +#define cet_ucs4_cnt_ns_4551_1 37 + +const int cet_ucs4_map_ns_4551_1[cet_ucs4_cnt_ns_4551_1] = +{ + 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e6, 0x00f8, 0x00e5, 0x203e, 0x007f +}; + +#define cet_ucs4_to_ns_4551_1_ct 7 + +const cet_ucs4_link_t cet_ucs4_to_ns_4551_1_links[cet_ucs4_to_ns_4551_1_ct] = +{ + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00c6, 0x5b} /* capital letter ae */, + {0x00d8, 0x5c} /* capital letter o with stroke */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00e6, 0x7b} /* small letter ae */, + {0x00f8, 0x7c} /* small letter o with stroke */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_ns_4551_1_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ns_4551_1_extra[cet_ucs4_to_ns_4551_1_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ns_4551_1 = /* defined in cet.h */ +{ + cet_cs_name_ns_4551_1, /* name of character set */ + cet_cs_alias_ns_4551_1, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ns_4551_1, /* char to UCS-4 value table */ + cet_ucs4_ofs_ns_4551_1, /* first non standard character */ + cet_ucs4_cnt_ns_4551_1, /* number of values in table */ + + cet_ucs4_to_ns_4551_1_links, /* UCS-4 to char links */ + cet_ucs4_to_ns_4551_1_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ns_4551_1_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ns_4551_2.h b/cet/ns_4551_2.h new file mode 100644 index 000000000..9b21e20e2 --- /dev/null +++ b/cet/ns_4551_2.h @@ -0,0 +1,133 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NS_4551-2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ns_4551_2_h +#define ns_4551_2_h + +#define cet_cs_name_ns_4551_2 "NS_4551-2" + +const char *cet_cs_alias_ns_4551_2[] = +{ + "NS_4551-2", "ISO646-NO2", "iso-ir-61", "no2", + NULL +}; + +#define cet_ucs4_ofs_ns_4551_2 35 +#define cet_ucs4_cnt_ns_4551_2 93 + +const int cet_ucs4_map_ns_4551_2[cet_ucs4_cnt_ns_4551_2] = +{ + 0x00a7, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e6, 0x00f8, 0x00e5, 0x007c, 0x007f +}; + +#define cet_ucs4_to_ns_4551_2_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_ns_4551_2_links[cet_ucs4_to_ns_4551_2_ct] = +{ + {0x007c, 0x7e} /* line */, + {0x00a7, 0x23} /* sign */, + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00c6, 0x5b} /* capital letter ae */, + {0x00d8, 0x5c} /* capital letter o with stroke */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00e6, 0x7b} /* small letter ae */, + {0x00f8, 0x7c} /* small letter o with stroke */ +}; + +/* +#define cet_ucs4_to_ns_4551_2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ns_4551_2_extra[cet_ucs4_to_ns_4551_2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ns_4551_2 = /* defined in cet.h */ +{ + cet_cs_name_ns_4551_2, /* name of character set */ + cet_cs_alias_ns_4551_2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ns_4551_2, /* char to UCS-4 value table */ + cet_ucs4_ofs_ns_4551_2, /* first non standard character */ + cet_ucs4_cnt_ns_4551_2, /* number of values in table */ + + cet_ucs4_to_ns_4551_2_links, /* UCS-4 to char links */ + cet_ucs4_to_ns_4551_2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ns_4551_2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a7, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x007c, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/pt.h b/cet/pt.h new file mode 100644 index 000000000..d664042c7 --- /dev/null +++ b/cet/pt.h @@ -0,0 +1,128 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "PT" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef pt_h +#define pt_h + +#define cet_cs_name_pt "PT" + +const char *cet_cs_alias_pt[] = +{ + "PT", "ISO646-PT", "iso-ir-16", NULL +}; + +#define cet_ucs4_ofs_pt 64 +#define cet_ucs4_cnt_pt 64 + +const int cet_ucs4_map_pt[cet_ucs4_cnt_pt] = +{ + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c3, 0x00c7, 0x00d5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e3, 0x00e7, 0x00f5, 0x00b0, 0x007f +}; + +#define cet_ucs4_to_pt_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_pt_links[cet_ucs4_to_pt_ct] = +{ + {0x00a7, 0x40} /* sign */, + {0x00b0, 0x7e} /* sign */, + {0x00c3, 0x5b} /* capital letter a with tilde */, + {0x00c7, 0x5c} /* capital letter c with cedilla */, + {0x00d5, 0x5d} /* capital letter o with tilde */, + {0x00e3, 0x7b} /* small letter a with tilde */, + {0x00e7, 0x7c} /* small letter c with cedilla */, + {0x00f5, 0x7d} /* small letter o with tilde */ +}; + +/* +#define cet_ucs4_to_pt_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_pt_extra[cet_ucs4_to_pt_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_pt = /* defined in cet.h */ +{ + cet_cs_name_pt, /* name of character set */ + cet_cs_alias_pt, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_pt, /* char to UCS-4 value table */ + cet_ucs4_ofs_pt, /* first non standard character */ + cet_ucs4_cnt_pt, /* number of values in table */ + + cet_ucs4_to_pt_links, /* UCS-4 to char links */ + cet_ucs4_to_pt_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int pt_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c3, 0x00c7, 0x00d5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e3, 0x00e7, 0x00f5, 0x00b0, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/pt2.h b/cet/pt2.h new file mode 100644 index 000000000..fcbb01c82 --- /dev/null +++ b/cet/pt2.h @@ -0,0 +1,127 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "PT2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef pt2_h +#define pt2_h + +#define cet_cs_name_pt2 "PT2" + +const char *cet_cs_alias_pt2[] = +{ + "PT2", "ISO646-PT2", "iso-ir-84", NULL +}; + +#define cet_ucs4_ofs_pt2 64 +#define cet_ucs4_cnt_pt2 64 + +const int cet_ucs4_map_pt2[cet_ucs4_cnt_pt2] = +{ + 0x00b4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c3, 0x00c7, 0x00d5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e3, 0x00e7, 0x00f5, 0x007e, 0x007f +}; + +#define cet_ucs4_to_pt2_ct 7 + +const cet_ucs4_link_t cet_ucs4_to_pt2_links[cet_ucs4_to_pt2_ct] = +{ + {0x00b4, 0x40} /* accent */, + {0x00c3, 0x5b} /* capital letter a with tilde */, + {0x00c7, 0x5c} /* capital letter c with cedilla */, + {0x00d5, 0x5d} /* capital letter o with tilde */, + {0x00e3, 0x7b} /* small letter a with tilde */, + {0x00e7, 0x7c} /* small letter c with cedilla */, + {0x00f5, 0x7d} /* small letter o with tilde */ +}; + +/* +#define cet_ucs4_to_pt2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_pt2_extra[cet_ucs4_to_pt2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_pt2 = /* defined in cet.h */ +{ + cet_cs_name_pt2, /* name of character set */ + cet_cs_alias_pt2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_pt2, /* char to UCS-4 value table */ + cet_ucs4_ofs_pt2, /* first non standard character */ + cet_ucs4_cnt_pt2, /* number of values in table */ + + cet_ucs4_to_pt2_links, /* UCS-4 to char links */ + cet_ucs4_to_pt2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int pt2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00b4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c3, 0x00c7, 0x00d5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e3, 0x00e7, 0x00f5, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/sami.h b/cet/sami.h new file mode 100644 index 000000000..4dfce1713 --- /dev/null +++ b/cet/sami.h @@ -0,0 +1,157 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "sami" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef sami_h +#define sami_h + +#define cet_cs_name_sami "sami" + +const char *cet_cs_alias_sami[] = +{ + "sami", "iso-ir-158", "lap", "latin-lap", + NULL +}; + +#define cet_ucs4_ofs_sami 160 +#define cet_ucs4_cnt_sami 80 + +const int cet_ucs4_map_sami[cet_ucs4_cnt_sami] = +{ + 0x00b4, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x02bb, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x0102, 0x00c0, 0x01de, 0x01e0, 0x01e2, 0x0114, 0x00c8, 0x01e4, + 0x01e6, 0x01e8, 0x014e, 0x00d2, 0x01ea, 0x01ec, 0x01b7, 0x01ee, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x0103, 0x00e0, 0x01df, 0x01e1, 0x01e3, 0x0115, 0x00e8, 0x01e5, + 0x01e7, 0x01e9, 0x014f, 0x00f2, 0x01eb, 0x01ed, 0x0292, 0x01ef +}; + +#define cet_ucs4_to_sami_ct 34 + +const cet_ucs4_link_t cet_ucs4_to_sami_links[cet_ucs4_to_sami_ct] = +{ + {0x00b4, 0xa0} /* accent */, + {0x00c0, 0xc1} /* capital letter a with grave */, + {0x00c8, 0xc6} /* capital letter e with grave */, + {0x00d2, 0xcb} /* capital letter o with grave */, + {0x00e0, 0xe1} /* small letter a with grave */, + {0x00e8, 0xe6} /* small letter e with grave */, + {0x00f2, 0xeb} /* small letter o with grave */, + {0x0102, 0xc0} /* capital letter a with breve */, + {0x0103, 0xe0} /* small letter a with breve */, + {0x0114, 0xc5} /* capital letter e with breve */, + {0x0115, 0xe5} /* small letter e with breve */, + {0x014e, 0xca} /* capital letter o with breve */, + {0x014f, 0xea} /* small letter o with breve */, + {0x01b7, 0xce} /* capital letter ezh */, + {0x01de, 0xc2} /* capital letter a with diaeresis and macron */, + {0x01df, 0xe2} /* small letter a with diaeresis and macron */, + {0x01e0, 0xc3} /* capital letter a with dot above and macron */, + {0x01e1, 0xe3} /* small letter a with dot above and macron */, + {0x01e2, 0xc4} /* capital letter ae with macron */, + {0x01e3, 0xe4} /* small letter ae with macron */, + {0x01e4, 0xc7} /* capital letter g with stroke */, + {0x01e5, 0xe7} /* small letter g with stroke */, + {0x01e6, 0xc8} /* capital letter g with caron */, + {0x01e7, 0xe8} /* small letter g with caron */, + {0x01e8, 0xc9} /* capital letter k with caron */, + {0x01e9, 0xe9} /* small letter k with caron */, + {0x01ea, 0xcc} /* capital letter o with ogonek */, + {0x01eb, 0xec} /* small letter o with ogonek */, + {0x01ec, 0xcd} /* capital letter o with ogonek and macron */, + {0x01ed, 0xed} /* small letter o with ogonek and macron */, + {0x01ee, 0xcf} /* capital letter ezh with caron */, + {0x01ef, 0xef} /* small letter ezh with caron */, + {0x0292, 0xee} /* small letter ezh (iso-ir-158 142) */, + {0x02bb, 0xb0} /* letter left half ring */ +}; + +/* +#define cet_ucs4_to_sami_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_sami_extra[cet_ucs4_to_sami_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_sami = /* defined in cet.h */ +{ + cet_cs_name_sami, /* name of character set */ + cet_cs_alias_sami, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_sami, /* char to UCS-4 value table */ + cet_ucs4_ofs_sami, /* first non standard character */ + cet_ucs4_cnt_sami, /* number of values in table */ + + cet_ucs4_to_sami_links, /* UCS-4 to char links */ + cet_ucs4_to_sami_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int sami_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00b4, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x02bb, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x0102, 0x00c0, 0x01de, 0x01e0, 0x01e2, 0x0114, 0x00c8, 0x01e4, + 0x01e6, 0x01e8, 0x014e, 0x00d2, 0x01ea, 0x01ec, 0x01b7, 0x01ee, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x0103, 0x00e0, 0x01df, 0x01e1, 0x01e3, 0x0115, 0x00e8, 0x01e5, + 0x01e7, 0x01e9, 0x014f, 0x00f2, 0x01eb, 0x01ed, 0x0292, 0x01ef, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/sen_850200_b.h b/cet/sen_850200_b.h new file mode 100644 index 000000000..0c3123199 --- /dev/null +++ b/cet/sen_850200_b.h @@ -0,0 +1,133 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "SEN_850200_B" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef sen_850200_b_h +#define sen_850200_b_h + +#define cet_cs_name_sen_850200_b "SEN_850200_B" + +const char *cet_cs_alias_sen_850200_b[] = +{ + "SEN_850200_B", "FI", "ISO646-FI", "ISO646-SE", + "iso-ir-10", "se", "SS636127", NULL +}; + +#define cet_ucs4_ofs_sen_850200_b 36 +#define cet_ucs4_cnt_sen_850200_b 92 + +const int cet_ucs4_map_sen_850200_b[cet_ucs4_cnt_sen_850200_b] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00c4, + 0x00d6, 0x00c5, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00e4, + 0x00f6, 0x00e5, 0x203e, 0x007f +}; + +#define cet_ucs4_to_sen_850200_b_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_sen_850200_b_links[cet_ucs4_to_sen_850200_b_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x00c4, 0x5b} /* capital letter a with diaeresis */, + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00d6, 0x5c} /* capital letter o with diaeresis */, + {0x00e4, 0x7b} /* small letter a with diaeresis */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00f6, 0x7c} /* small letter o with diaeresis */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_sen_850200_b_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_sen_850200_b_extra[cet_ucs4_to_sen_850200_b_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_sen_850200_b = /* defined in cet.h */ +{ + cet_cs_name_sen_850200_b, /* name of character set */ + cet_cs_alias_sen_850200_b, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_sen_850200_b, /* char to UCS-4 value table */ + cet_ucs4_ofs_sen_850200_b, /* first non standard character */ + cet_ucs4_cnt_sen_850200_b, /* number of values in table */ + + cet_ucs4_to_sen_850200_b_links, /* UCS-4 to char links */ + cet_ucs4_to_sen_850200_b_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int sen_850200_b_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00c5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00e5, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/sen_850200_c.h b/cet/sen_850200_c.h new file mode 100644 index 000000000..606157b0b --- /dev/null +++ b/cet/sen_850200_c.h @@ -0,0 +1,136 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "SEN_850200_C" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef sen_850200_c_h +#define sen_850200_c_h + +#define cet_cs_name_sen_850200_c "SEN_850200_C" + +const char *cet_cs_alias_sen_850200_c[] = +{ + "SEN_850200_C", "ISO646-SE2", "iso-ir-11", "se2", + NULL +}; + +#define cet_ucs4_ofs_sen_850200_c 36 +#define cet_ucs4_cnt_sen_850200_c 92 + +const int cet_ucs4_map_sen_850200_c[cet_ucs4_cnt_sen_850200_c] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x00c9, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00c4, + 0x00d6, 0x00c5, 0x00dc, 0x005f, 0x00e9, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00e4, + 0x00f6, 0x00e5, 0x00fc, 0x007f +}; + +#define cet_ucs4_to_sen_850200_c_ct 11 + +const cet_ucs4_link_t cet_ucs4_to_sen_850200_c_links[cet_ucs4_to_sen_850200_c_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x00c4, 0x5b} /* capital letter a with diaeresis */, + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00c9, 0x40} /* capital letter e with acute */, + {0x00d6, 0x5c} /* capital letter o with diaeresis */, + {0x00dc, 0x5e} /* capital letter u with diaeresis */, + {0x00e4, 0x7b} /* small letter a with diaeresis */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00e9, 0x60} /* small letter e with acute */, + {0x00f6, 0x7c} /* small letter o with diaeresis */, + {0x00fc, 0x7e} /* small letter u with diaeresis */ +}; + +/* +#define cet_ucs4_to_sen_850200_c_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_sen_850200_c_extra[cet_ucs4_to_sen_850200_c_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_sen_850200_c = /* defined in cet.h */ +{ + cet_cs_name_sen_850200_c, /* name of character set */ + cet_cs_alias_sen_850200_c, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_sen_850200_c, /* char to UCS-4 value table */ + cet_ucs4_ofs_sen_850200_c, /* first non standard character */ + cet_ucs4_cnt_sen_850200_c, /* number of values in table */ + + cet_ucs4_to_sen_850200_c_links, /* UCS-4 to char links */ + cet_ucs4_to_sen_850200_c_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int sen_850200_c_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00c9, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00c5, 0x00dc, 0x005f, + 0x00e9, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00e5, 0x00fc, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/tcvn.h b/cet/tcvn.h new file mode 100644 index 000000000..894c0b025 --- /dev/null +++ b/cet/tcvn.h @@ -0,0 +1,278 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "TCVN" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef tcvn_h +#define tcvn_h + +#define cet_cs_name_tcvn "TCVN" + +const char *cet_cs_alias_tcvn[] = +{ + "TCVN", "TCVN5712-1", "TCVN5712-1:1993", "TCVN-5712", + NULL +}; + +#define cet_ucs4_ofs_tcvn 1 +#define cet_ucs4_cnt_tcvn 255 + +const int cet_ucs4_map_tcvn[cet_ucs4_cnt_tcvn] = +{ + 0x00da, 0x1ee4, 0x0003, 0x1eea, 0x1eec, 0x1eee, 0x0007, 0x0008, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, + 0x1ee8, 0x1ef0, 0x1ef2, 0x1ef6, 0x1ef8, 0x00dd, 0x1ef4, 0x0018, + 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, + 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, + 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, + 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, + 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, + 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, + 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, + 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, + 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x00c0, + 0x1ea2, 0x00c3, 0x00c1, 0x1ea0, 0x1eb6, 0x1eac, 0x00c8, 0x1eba, + 0x1ebc, 0x00c9, 0x1eb8, 0x1ec6, 0x00cc, 0x1ec8, 0x0128, 0x00cd, + 0x1eca, 0x00d2, 0x1ece, 0x00d5, 0x00d3, 0x1ecc, 0x1ed8, 0x1edc, + 0x1ede, 0x1ee0, 0x1eda, 0x1ee2, 0x00d9, 0x1ee6, 0x0168, -1, + 0x0102, 0x00c2, 0x00ca, 0x00d4, 0x01a0, 0x01af, 0x0110, 0x0103, + 0x00e2, 0x00ea, 0x00f4, 0x01a1, 0x01b0, 0x0111, 0x1eb0, -1, + -1, -1, -1, -1, 0x00e0, 0x1ea3, 0x00e3, 0x00e1, + 0x1ea1, 0x1eb2, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eaf, 0x1eb4, 0x1eae, + 0x1ea6, 0x1ea8, 0x1eaa, 0x1ea4, 0x1ec0, 0x1eb7, 0x1ea7, 0x1ea9, + 0x1eab, 0x1ea5, 0x1ead, 0x00e8, 0x1ec2, 0x1ebb, 0x1ebd, 0x00e9, + 0x1eb9, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ebf, 0x1ec7, 0x00ec, 0x1ec9, + 0x1ec4, 0x1ebe, 0x1ed2, 0x0129, 0x00ed, 0x1ecb, 0x00f2, 0x1ed4, + 0x1ecf, 0x00f5, 0x00f3, 0x1ecd, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed1, + 0x1ed9, 0x1edd, 0x1edf, 0x1ee1, 0x1edb, 0x1ee3, 0x00f9, 0x1ed6, + 0x1ee7, 0x0169, 0x00fa, 0x1ee5, 0x1eeb, 0x1eed, 0x1eef, 0x1ee9, + 0x1ef1, 0x1ef3, 0x1ef7, 0x1ef9, 0x00fd, 0x1ef5, 0x1ed0 +}; + +#define cet_ucs4_to_tcvn_ct 133 + +const cet_ucs4_link_t cet_ucs4_to_tcvn_links[cet_ucs4_to_tcvn_ct] = +{ + {0x00c0, 0x80} /* capital letter a with grave */, + {0x00c1, 0x83} /* capital letter a with acute */, + {0x00c2, 0xa2} /* capital letter a with circumflex */, + {0x00c3, 0x82} /* capital letter a with tilde */, + {0x00c8, 0x87} /* capital letter e with grave */, + {0x00c9, 0x8a} /* capital letter e with acute */, + {0x00ca, 0xa3} /* capital letter e with circumflex */, + {0x00cc, 0x8d} /* capital letter i with grave */, + {0x00cd, 0x90} /* capital letter i with acute */, + {0x00d2, 0x92} /* capital letter o with grave */, + {0x00d3, 0x95} /* capital letter o with acute */, + {0x00d4, 0xa4} /* capital letter o with circumflex */, + {0x00d5, 0x94} /* capital letter o with tilde */, + {0x00d9, 0x9d} /* capital letter u with grave */, + {0x00da, 0x01} /* capital letter u with acute */, + {0x00dd, 0x16} /* capital letter y with acute */, + {0x00e0, 0xb5} /* small letter a with grave */, + {0x00e1, 0xb8} /* small letter a with acute */, + {0x00e2, 0xa9} /* small letter a with circumflex */, + {0x00e3, 0xb7} /* small letter a with tilde */, + {0x00e8, 0xcc} /* small letter e with grave */, + {0x00e9, 0xd0} /* small letter e with acute */, + {0x00ea, 0xaa} /* small letter e with circumflex */, + {0x00ec, 0xd7} /* small letter i with grave */, + {0x00ed, 0xdd} /* small letter i with acute */, + {0x00f2, 0xdf} /* small letter o with grave */, + {0x00f3, 0xe3} /* small letter o with acute */, + {0x00f4, 0xab} /* small letter o with circumflex */, + {0x00f5, 0xe2} /* small letter o with tilde */, + {0x00f9, 0xef} /* small letter u with grave */, + {0x00fa, 0xf3} /* small letter u with acute */, + {0x0102, 0xa1} /* capital letter a with breve */, + {0x0103, 0xa8} /* small letter a with breve */, + {0x0110, 0xa7} /* capital letter d with stroke */, + {0x0111, 0xae} /* small letter d with stroke */, + {0x0128, 0x8f} /* capital letter i with tilde */, + {0x0129, 0xdc} /* small letter i with tilde */, + {0x0168, 0x9f} /* capital letter u with tilde */, + {0x0169, 0xf2} /* small letter u with tilde */, + {0x01a0, 0xa5} /* capital letter o with horn */, + {0x01a1, 0xac} /* small letter o with horn */, + {0x01af, 0xa6} /* capital letter u with horn */, + {0x01b0, 0xad} /* small letter u with horn */, + {0x1ea0, 0x84} /* capital letter a with dot below */, + {0x1ea1, 0xb9} /* small letter a with dot below */, + {0x1ea2, 0x81} /* capital letter a with hook above */, + {0x1ea3, 0xb6} /* small letter a with hook above */, + {0x1ea4, 0xc4} /* capital letter a with circumflex and acute */, + {0x1ea5, 0xca} /* small letter a with circumflex and acute */, + {0x1ea6, 0xc1} /* capital letter a with circumflex and grave */, + {0x1ea7, 0xc7} /* small letter a with circumflex and grave */, + {0x1ea8, 0xc2} /* capital letter a with circumflex and hook above */, + {0x1ea9, 0xc8} /* small letter a with circumflex and hook above */, + {0x1eaa, 0xc3} /* capital letter a with circumflex and tilde */, + {0x1eab, 0xc9} /* small letter a with circumflex and tilde */, + {0x1eac, 0x86} /* latine a accent circonflexe et point souscrit */, + {0x1ead, 0xcb} /* latine a accent circonflexe et point souscrit */, + {0x1eae, 0xc0} /* capital letter a with breve and acute */, + {0x1eaf, 0xbe} /* small letter a with breve and acute */, + {0x1eb0, 0xaf} /* capital letter a with breve and grave */, + {0x1eb1, 0xbb} /* small letter a with breve and grave */, + {0x1eb2, 0xba} /* capital letter a with breve and hook above */, + {0x1eb3, 0xbc} /* small letter a with breve and hook above */, + {0x1eb4, 0xbf} /* capital letter a with breve and tilde */, + {0x1eb5, 0xbd} /* small letter a with breve and tilde */, + {0x1eb6, 0x85} /* latine a brève et point souscrit */, + {0x1eb7, 0xc6} /* latine a brève et point souscrit */, + {0x1eb8, 0x8b} /* capital letter e with dot below */, + {0x1eb9, 0xd1} /* small letter e with dot below */, + {0x1eba, 0x88} /* capital letter e with hook above */, + {0x1ebb, 0xce} /* small letter e with hook above */, + {0x1ebc, 0x89} /* capital letter e with tilde */, + {0x1ebd, 0xcf} /* small letter e with tilde */, + {0x1ebe, 0xda} /* capital letter e with circumflex and acute */, + {0x1ebf, 0xd5} /* small letter e with circumflex and acute */, + {0x1ec0, 0xc5} /* capital letter e with circumflex and grave */, + {0x1ec1, 0xd2} /* small letter e with circumflex and grave */, + {0x1ec2, 0xcd} /* capital letter e with circumflex and hook above */, + {0x1ec3, 0xd3} /* small letter e with circumflex and hook above */, + {0x1ec4, 0xd9} /* capital letter e with circumflex and tilde */, + {0x1ec5, 0xd4} /* small letter e with circumflex and tilde */, + {0x1ec6, 0x8c} /* latine e accent circonflexe et point souscrit */, + {0x1ec7, 0xd6} /* latine e accent circonflexe et point souscrit */, + {0x1ec8, 0x8e} /* capital letter i with hook above */, + {0x1ec9, 0xd8} /* small letter i with hook above */, + {0x1eca, 0x91} /* capital letter i with dot below */, + {0x1ecb, 0xde} /* small letter i with dot below */, + {0x1ecc, 0x96} /* capital letter o with dot below */, + {0x1ecd, 0xe4} /* small letter o with dot below */, + {0x1ece, 0x93} /* capital letter o with hook above */, + {0x1ecf, 0xe1} /* small letter o with hook above */, + {0x1ed0, 0xff} /* capital letter o with circumflex and acute */, + {0x1ed1, 0xe8} /* small letter o with circumflex and acute */, + {0x1ed2, 0xdb} /* capital letter o with circumflex and grave */, + {0x1ed3, 0xe5} /* small letter o with circumflex and grave */, + {0x1ed4, 0xe0} /* capital letter o with circumflex and hook above */, + {0x1ed5, 0xe6} /* small letter o with circumflex and hook above */, + {0x1ed6, 0xf0} /* capital letter o with circumflex and tilde */, + {0x1ed7, 0xe7} /* small letter o with circumflex and tilde */, + {0x1ed8, 0x97} /* latine o accent circonflexe et point souscrit */, + {0x1ed9, 0xe9} /* latine o accent circonflexe et point souscrit */, + {0x1eda, 0x9b} /* capital letter o with horn and acute */, + {0x1edb, 0xed} /* small letter o with horn and acute */, + {0x1edc, 0x98} /* capital letter o with horn and grave */, + {0x1edd, 0xea} /* small letter o with horn and grave */, + {0x1ede, 0x99} /* capital letter o with horn and hook above */, + {0x1edf, 0xeb} /* small letter o with horn and hook above */, + {0x1ee0, 0x9a} /* capital letter o with horn and tilde */, + {0x1ee1, 0xec} /* small letter o with horn and tilde */, + {0x1ee2, 0x9c} /* latine o cornu point souscrit */, + {0x1ee3, 0xee} /* latine o cornu point souscrit */, + {0x1ee4, 0x02} /* capital letter u with dot below */, + {0x1ee5, 0xf4} /* small letter u with dot below */, + {0x1ee6, 0x9e} /* capital letter u with hook above */, + {0x1ee7, 0xf1} /* small letter u with hook above */, + {0x1ee8, 0x11} /* capital letter u with horn and acute */, + {0x1ee9, 0xf8} /* small letter u with horn and acute */, + {0x1eea, 0x04} /* capital letter u with horn and grave */, + {0x1eeb, 0xf5} /* small letter u with horn and grave */, + {0x1eec, 0x05} /* capital letter u with horn and hook above */, + {0x1eed, 0xf6} /* small letter u with horn and hook above */, + {0x1eee, 0x06} /* capital letter u with horn and tilde */, + {0x1eef, 0xf7} /* small letter u with horn and tilde */, + {0x1ef0, 0x12} /* latine u cornu point souscrit */, + {0x1ef1, 0xf9} /* latine u cornu point souscrit */, + {0x1ef2, 0x13} /* capital letter y with grave */, + {0x1ef3, 0xfa} /* small letter y with grave */, + {0x1ef4, 0x17} /* capital letter y with dot below */, + {0x1ef5, 0xfe} /* small letter y with dot below */, + {0x1ef6, 0x14} /* capital letter y with hook above */, + {0x1ef7, 0xfb} /* small letter y with hook above */, + {0x1ef8, 0x15} /* capital letter y with tilde */, + {0x1ef9, 0xfc} /* small letter y with tilde */ +}; + +/* +#define cet_ucs4_to_tcvn_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_tcvn_extra[cet_ucs4_to_tcvn_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_tcvn = /* defined in cet.h */ +{ + cet_cs_name_tcvn, /* name of character set */ + cet_cs_alias_tcvn, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_tcvn, /* char to UCS-4 value table */ + cet_ucs4_ofs_tcvn, /* first non standard character */ + cet_ucs4_cnt_tcvn, /* number of values in table */ + + cet_ucs4_to_tcvn_links, /* UCS-4 to char links */ + cet_ucs4_to_tcvn_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int tcvn_ucs4_full_map[] = +{ + 0x0000, 0x00da, 0x1ee4, 0x0003, 0x1eea, 0x1eec, 0x1eee, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x1ee8, 0x1ef0, 0x1ef2, 0x1ef6, 0x1ef8, 0x00dd, 0x1ef4, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c0, 0x1ea2, 0x00c3, 0x00c1, 0x1ea0, 0x1eb6, 0x1eac, 0x00c8, + 0x1eba, 0x1ebc, 0x00c9, 0x1eb8, 0x1ec6, 0x00cc, 0x1ec8, 0x0128, + 0x00cd, 0x1eca, 0x00d2, 0x1ece, 0x00d5, 0x00d3, 0x1ecc, 0x1ed8, + 0x1edc, 0x1ede, 0x1ee0, 0x1eda, 0x1ee2, 0x00d9, 0x1ee6, 0x0168, + -1, 0x0102, 0x00c2, 0x00ca, 0x00d4, 0x01a0, 0x01af, 0x0110, + 0x0103, 0x00e2, 0x00ea, 0x00f4, 0x01a1, 0x01b0, 0x0111, 0x1eb0, + -1, -1, -1, -1, -1, 0x00e0, 0x1ea3, 0x00e3, + 0x00e1, 0x1ea1, 0x1eb2, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eaf, 0x1eb4, + 0x1eae, 0x1ea6, 0x1ea8, 0x1eaa, 0x1ea4, 0x1ec0, 0x1eb7, 0x1ea7, + 0x1ea9, 0x1eab, 0x1ea5, 0x1ead, 0x00e8, 0x1ec2, 0x1ebb, 0x1ebd, + 0x00e9, 0x1eb9, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ebf, 0x1ec7, 0x00ec, + 0x1ec9, 0x1ec4, 0x1ebe, 0x1ed2, 0x0129, 0x00ed, 0x1ecb, 0x00f2, + 0x1ed4, 0x1ecf, 0x00f5, 0x00f3, 0x1ecd, 0x1ed3, 0x1ed5, 0x1ed7, + 0x1ed1, 0x1ed9, 0x1edd, 0x1edf, 0x1ee1, 0x1edb, 0x1ee3, 0x00f9, + 0x1ed6, 0x1ee7, 0x0169, 0x00fa, 0x1ee5, 0x1eeb, 0x1eed, 0x1eef, + 0x1ee9, 0x1ef1, 0x1ef3, 0x1ef7, 0x1ef9, 0x00fd, 0x1ef5, 0x1ed0 +}; +*/ + +#endif diff --git a/cet/viscii.h b/cet/viscii.h new file mode 100644 index 000000000..43dfbe3eb --- /dev/null +++ b/cet/viscii.h @@ -0,0 +1,247 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "VISCII" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef viscii_h +#define viscii_h + +#define cet_cs_name_viscii "VISCII" + +const char *cet_cs_alias_viscii[] = +{ + "VISCII", "csVISCII", "VISCII1.1-1", NULL +}; + +#define cet_ucs4_ofs_viscii 2 +#define cet_ucs4_cnt_viscii 254 + +const int cet_ucs4_map_viscii[cet_ucs4_cnt_viscii] = +{ + 0x1eb2, 0x0003, 0x0004, 0x1eb4, 0x1eaa, 0x0007, 0x0008, 0x0009, + 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, + 0x0012, 0x0013, 0x1ef6, 0x0015, 0x0016, 0x0017, 0x0018, 0x1ef8, + 0x001a, 0x001b, 0x001c, 0x001d, 0x1ef4, 0x001f, 0x0020, 0x0021, + 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, + 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, + 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, + 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, + 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, + 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, + 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, + 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, + 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x1ea0, 0x1eae, + 0x1eb0, 0x1eb6, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eac, 0x1ebc, 0x1eb8, + 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ed0, 0x1ed2, 0x1ed4, + 0x1ed6, 0x1ed8, 0x1ee2, 0x1eda, 0x1edc, 0x1ede, 0x1eca, 0x1ece, + 0x1ecc, 0x1ec8, 0x1ee6, 0x0168, 0x1ee4, 0x1ef2, 0x00d5, 0x1eaf, + 0x1eb1, 0x1eb7, 0x1ea5, 0x1ea7, 0x1ea9, 0x1ead, 0x1ebd, 0x1eb9, + 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ed1, 0x1ed3, 0x1ed5, + 0x1ed7, 0x1ee0, 0x01a0, 0x1ed9, 0x1edd, 0x1edf, 0x1ecb, 0x1ef0, + 0x1ee8, 0x1eea, 0x1eec, 0x01a1, 0x1edb, 0x01af, 0x00c0, 0x00c1, + 0x00c2, 0x00c3, 0x1ea2, 0x0102, 0x1eb3, 0x1eb5, 0x00c8, 0x00c9, + 0x00ca, 0x1eba, 0x00cc, 0x00cd, 0x0128, 0x1ef3, 0x0110, 0x1ee9, + 0x00d2, 0x00d3, 0x00d4, 0x1ea1, 0x1ef7, 0x1eeb, 0x1eed, 0x00d9, + 0x00da, 0x1ef9, 0x1ef5, 0x00dd, 0x1ee1, 0x01b0, 0x00e0, 0x00e1, + 0x00e2, 0x00e3, 0x1ea3, 0x0103, 0x1eef, 0x1eab, 0x00e8, 0x00e9, + 0x00ea, 0x1ebb, 0x00ec, 0x00ed, 0x0129, 0x1ec9, 0x0111, 0x1ef1, + 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x1ecf, 0x1ecd, 0x1ee5, 0x00f9, + 0x00fa, 0x0169, 0x1ee7, 0x00fd, 0x1ee3, 0x1eee +}; + +#define cet_ucs4_to_viscii_ct 103 + +const cet_ucs4_link_t cet_ucs4_to_viscii_links[cet_ucs4_to_viscii_ct] = +{ + {0x00d5, 0xa0} /* capital letter o with tilde */, + {0x0102, 0xc5} /* capital letter a with breve */, + {0x0103, 0xe5} /* small letter a with breve */, + {0x0110, 0xd0} /* capital letter d with stroke */, + {0x0111, 0xf0} /* small letter d with stroke */, + {0x0128, 0xce} /* capital letter i with tilde */, + {0x0129, 0xee} /* small letter i with tilde */, + {0x0168, 0x9d} /* capital letter u with tilde */, + {0x0169, 0xfb} /* small letter u with tilde */, + {0x01a0, 0xb4} /* capital letter o with horn */, + {0x01a1, 0xbd} /* small letter o with horn */, + {0x01af, 0xbf} /* capital letter u with horn */, + {0x01b0, 0xdf} /* small letter u with horn */, + {0x1ea0, 0x80} /* capital letter a with dot below */, + {0x1ea1, 0xd5} /* small letter a with dot below */, + {0x1ea2, 0xc4} /* capital letter a with hook above */, + {0x1ea3, 0xe4} /* small letter a with hook above */, + {0x1ea4, 0x84} /* capital letter a with circumflex and acute */, + {0x1ea5, 0xa4} /* small letter a with circumflex and acute */, + {0x1ea6, 0x85} /* capital letter a with circumflex and grave */, + {0x1ea7, 0xa5} /* small letter a with circumflex and grave */, + {0x1ea8, 0x86} /* capital letter a with circumflex and hook above */, + {0x1ea9, 0xa6} /* small letter a with circumflex and hook above */, + {0x1eaa, 0x06} /* capital letter a with circumflex and tilde */, + {0x1eab, 0xe7} /* small letter a with circumflex and tilde */, + {0x1eac, 0x87} /* latine a accent circonflexe et point souscrit */, + {0x1ead, 0xa7} /* latine a accent circonflexe et point souscrit */, + {0x1eae, 0x81} /* capital letter a with breve and acute */, + {0x1eaf, 0xa1} /* small letter a with breve and acute */, + {0x1eb0, 0x82} /* capital letter a with breve and grave */, + {0x1eb1, 0xa2} /* small letter a with breve and grave */, + {0x1eb2, 0x02} /* capital letter a with breve and hook above */, + {0x1eb3, 0xc6} /* small letter a with breve and hook above */, + {0x1eb4, 0x05} /* capital letter a with breve and tilde */, + {0x1eb5, 0xc7} /* small letter a with breve and tilde */, + {0x1eb6, 0x83} /* latine a brève et point souscrit */, + {0x1eb7, 0xa3} /* latine a brève et point souscrit */, + {0x1eb8, 0x89} /* capital letter e with dot below */, + {0x1eb9, 0xa9} /* small letter e with dot below */, + {0x1eba, 0xcb} /* capital letter e with hook above */, + {0x1ebb, 0xeb} /* small letter e with hook above */, + {0x1ebc, 0x88} /* capital letter e with tilde */, + {0x1ebd, 0xa8} /* small letter e with tilde */, + {0x1ebe, 0x8a} /* capital letter e with circumflex and acute */, + {0x1ebf, 0xaa} /* small letter e with circumflex and acute */, + {0x1ec0, 0x8b} /* capital letter e with circumflex and grave */, + {0x1ec1, 0xab} /* small letter e with circumflex and grave */, + {0x1ec2, 0x8c} /* capital letter e with circumflex and hook above */, + {0x1ec3, 0xac} /* small letter e with circumflex and hook above */, + {0x1ec4, 0x8d} /* capital letter e with circumflex and tilde */, + {0x1ec5, 0xad} /* small letter e with circumflex and tilde */, + {0x1ec6, 0x8e} /* latine e accent circonflexe et point souscrit */, + {0x1ec7, 0xae} /* latine e accent circonflexe et point souscrit */, + {0x1ec8, 0x9b} /* capital letter i with hook above */, + {0x1ec9, 0xef} /* small letter i with hook above */, + {0x1eca, 0x98} /* capital letter i with dot below */, + {0x1ecb, 0xb8} /* small letter i with dot below */, + {0x1ecc, 0x9a} /* capital letter o with dot below */, + {0x1ecd, 0xf7} /* small letter o with dot below */, + {0x1ece, 0x99} /* capital letter o with hook above */, + {0x1ecf, 0xf6} /* small letter o with hook above */, + {0x1ed0, 0x8f} /* capital letter o with circumflex and acute */, + {0x1ed1, 0xaf} /* small letter o with circumflex and acute */, + {0x1ed2, 0x90} /* capital letter o with circumflex and grave */, + {0x1ed3, 0xb0} /* small letter o with circumflex and grave */, + {0x1ed4, 0x91} /* capital letter o with circumflex and hook above */, + {0x1ed5, 0xb1} /* small letter o with circumflex and hook above */, + {0x1ed6, 0x92} /* capital letter o with circumflex and tilde */, + {0x1ed7, 0xb2} /* small letter o with circumflex and tilde */, + {0x1ed8, 0x93} /* latine o accent circonflexe et point souscrit */, + {0x1ed9, 0xb5} /* latine o accent circonflexe et point souscrit */, + {0x1eda, 0x95} /* capital letter o with horn and acute */, + {0x1edb, 0xbe} /* small letter o with horn and acute */, + {0x1edc, 0x96} /* capital letter o with horn and grave */, + {0x1edd, 0xb6} /* small letter o with horn and grave */, + {0x1ede, 0x97} /* capital letter o with horn and hook above */, + {0x1edf, 0xb7} /* small letter o with horn and hook above */, + {0x1ee0, 0xb3} /* capital letter o with horn and tilde */, + {0x1ee1, 0xde} /* small letter o with horn and tilde */, + {0x1ee2, 0x94} /* latine o cornu point souscrit */, + {0x1ee3, 0xfe} /* latine o cornu point souscrit */, + {0x1ee4, 0x9e} /* capital letter u with dot below */, + {0x1ee5, 0xf8} /* small letter u with dot below */, + {0x1ee6, 0x9c} /* capital letter u with hook above */, + {0x1ee7, 0xfc} /* small letter u with hook above */, + {0x1ee8, 0xba} /* capital letter u with horn and acute */, + {0x1ee9, 0xd1} /* small letter u with horn and acute */, + {0x1eea, 0xbb} /* capital letter u with horn and grave */, + {0x1eeb, 0xd7} /* small letter u with horn and grave */, + {0x1eec, 0xbc} /* capital letter u with horn and hook above */, + {0x1eed, 0xd8} /* small letter u with horn and hook above */, + {0x1eee, 0xff} /* capital letter u with horn and tilde */, + {0x1eef, 0xe6} /* small letter u with horn and tilde */, + {0x1ef0, 0xb9} /* latine u cornu point souscrit */, + {0x1ef1, 0xf1} /* latine u cornu point souscrit */, + {0x1ef2, 0x9f} /* capital letter y with grave */, + {0x1ef3, 0xcf} /* small letter y with grave */, + {0x1ef4, 0x1e} /* capital letter y with dot below */, + {0x1ef5, 0xdc} /* small letter y with dot below */, + {0x1ef6, 0x14} /* capital letter y with hook above */, + {0x1ef7, 0xd6} /* small letter y with hook above */, + {0x1ef8, 0x19} /* capital letter y with tilde */, + {0x1ef9, 0xdb} /* small letter y with tilde */ +}; + +/* +#define cet_ucs4_to_viscii_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_viscii_extra[cet_ucs4_to_viscii_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_viscii = /* defined in cet.h */ +{ + cet_cs_name_viscii, /* name of character set */ + cet_cs_alias_viscii, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_viscii, /* char to UCS-4 value table */ + cet_ucs4_ofs_viscii, /* first non standard character */ + cet_ucs4_cnt_viscii, /* number of values in table */ + + cet_ucs4_to_viscii_links, /* UCS-4 to char links */ + cet_ucs4_to_viscii_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int viscii_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x1eb2, 0x0003, 0x0004, 0x1eb4, 0x1eaa, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x1ef6, 0x0015, 0x0016, 0x0017, + 0x0018, 0x1ef8, 0x001a, 0x001b, 0x001c, 0x001d, 0x1ef4, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x1ea0, 0x1eae, 0x1eb0, 0x1eb6, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eac, + 0x1ebc, 0x1eb8, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ed0, + 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, 0x1ee2, 0x1eda, 0x1edc, 0x1ede, + 0x1eca, 0x1ece, 0x1ecc, 0x1ec8, 0x1ee6, 0x0168, 0x1ee4, 0x1ef2, + 0x00d5, 0x1eaf, 0x1eb1, 0x1eb7, 0x1ea5, 0x1ea7, 0x1ea9, 0x1ead, + 0x1ebd, 0x1eb9, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ed1, + 0x1ed3, 0x1ed5, 0x1ed7, 0x1ee0, 0x01a0, 0x1ed9, 0x1edd, 0x1edf, + 0x1ecb, 0x1ef0, 0x1ee8, 0x1eea, 0x1eec, 0x01a1, 0x1edb, 0x01af, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x1ea2, 0x0102, 0x1eb3, 0x1eb5, + 0x00c8, 0x00c9, 0x00ca, 0x1eba, 0x00cc, 0x00cd, 0x0128, 0x1ef3, + 0x0110, 0x1ee9, 0x00d2, 0x00d3, 0x00d4, 0x1ea1, 0x1ef7, 0x1eeb, + 0x1eed, 0x00d9, 0x00da, 0x1ef9, 0x1ef5, 0x00dd, 0x1ee1, 0x01b0, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x1ea3, 0x0103, 0x1eef, 0x1eab, + 0x00e8, 0x00e9, 0x00ea, 0x1ebb, 0x00ec, 0x00ed, 0x0129, 0x1ec9, + 0x0111, 0x1ef1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x1ecf, 0x1ecd, + 0x1ee5, 0x00f9, 0x00fa, 0x0169, 0x1ee7, 0x00fd, 0x1ee3, 0x1eee +}; +*/ + +#endif diff --git a/cet/vps.h b/cet/vps.h new file mode 100644 index 000000000..73bf86ee4 --- /dev/null +++ b/cet/vps.h @@ -0,0 +1,255 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "VPS" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef vps_h +#define vps_h + +#define cet_cs_name_vps "VPS" + +const char *cet_cs_alias_vps[] = +{ + "VPS", NULL +}; + +#define cet_ucs4_ofs_vps 2 +#define cet_ucs4_cnt_vps 254 + +const int cet_ucs4_map_vps[cet_ucs4_cnt_vps] = +{ + 0x1ea0, 0x1eac, 0x1eb6, 0x1eb8, 0x1ec6, 0x0007, 0x0008, 0x0009, + 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x1eca, 0x1ecc, + 0x1ed8, 0x1ee2, 0x1ee4, 0x1ef0, 0x0016, 0x0017, 0x0018, 0x1ef4, + 0x001a, 0x001b, 0x1eaa, 0x1eee, 0x001e, 0x001f, 0x0020, 0x0021, + 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, + 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, + 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, + 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, + 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, + 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, + 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, + 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, + 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x00c0, 0x1ea2, + 0x00c3, 0x1ea4, 0x1ea6, 0x1ea8, 0x1ecd, 0x1ed7, 0x0102, 0x1ebf, + 0x1ec1, 0x1ec3, 0x1ec7, 0x1eae, 0x1eb0, 0x1eb2, 0x1ebe, -1, + -1, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ed0, 0x1ed2, 0x1ed4, -1, + 0x00fd, 0x1ef7, 0x1ef5, 0x1eda, 0x1edc, 0x1ede, -1, 0x1eaf, + 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1ee0, 0x1edb, 0x00d9, 0x1edd, + 0x1edf, 0x1ee1, 0x0168, 0x1ee8, 0x1ee3, 0x1eea, 0x1ed5, 0x1eec, + 0x1ef2, 0x1ef8, 0x00cd, 0x00cc, 0x1ed9, 0x1ec8, 0x0128, 0x00d3, + 0x1eed, 0x1eef, 0x00d2, 0x1ece, 0x00d5, 0x1ef1, 0x1ea7, 0x00c1, + 0x00c2, 0x1ea5, 0x1ea9, 0x1eab, 0x1ead, 0x0111, 0x1ebb, 0x00c9, + 0x00ca, 0x1eb9, 0x1ec9, 0x1ec5, 0x1ecb, 0x1ef9, 0x01af, 0x1ee6, + 0x1ed3, 0x1ed1, 0x00d4, 0x1ecf, 0x01a1, 0x00c8, 0x1eeb, 0x1ee9, + 0x00da, 0x0169, 0x01b0, 0x00dd, 0x1eba, -1, 0x00e0, 0x00e1, + 0x00e2, 0x00e3, 0x1ea3, 0x1ea1, 0x0103, -1, 0x00e8, 0x00e9, + 0x00ea, 0x1ebd, 0x00ec, 0x00ed, -1, 0x0129, 0x1eb4, 0x0110, + 0x00f2, 0x00f3, 0x00f4, 0x00f5, -1, 0x01a0, 0x1ee5, 0x00f9, + 0x00fa, 0x1ee7, -1, 0x1ef6, 0x1ebc, 0x1ef3 +}; + +#define cet_ucs4_to_vps_ct 111 + +const cet_ucs4_link_t cet_ucs4_to_vps_links[cet_ucs4_to_vps_ct] = +{ + {0x00c0, 0x80} /* capital letter a with grave */, + {0x00c3, 0x82} /* capital letter a with tilde */, + {0x00c8, 0xd7} /* capital letter e with grave */, + {0x00cc, 0xb5} /* capital letter i with grave */, + {0x00cd, 0xb4} /* capital letter i with acute */, + {0x00d2, 0xbc} /* capital letter o with grave */, + {0x00d3, 0xb9} /* capital letter o with acute */, + {0x00d5, 0xbe} /* capital letter o with tilde */, + {0x00d9, 0xa8} /* capital letter u with grave */, + {0x00fd, 0x9a} /* small letter y with acute */, + {0x0102, 0x88} /* capital letter a with breve */, + {0x0103, 0xe6} /* small letter a with breve */, + {0x0110, 0xf1} /* capital letter d with stroke */, + {0x0111, 0xc7} /* small letter d with stroke */, + {0x0128, 0xb8} /* capital letter i with tilde */, + {0x0129, 0xef} /* small letter i with tilde */, + {0x0168, 0xac} /* capital letter u with tilde */, + {0x0169, 0xdb} /* small letter u with tilde */, + {0x01a0, 0xf7} /* capital letter o with horn */, + {0x01a1, 0xd6} /* small letter o with horn */, + {0x01af, 0xd0} /* capital letter u with horn */, + {0x01b0, 0xdc} /* small letter u with horn */, + {0x1ea0, 0x02} /* capital letter a with dot below */, + {0x1ea1, 0xe5} /* small letter a with dot below */, + {0x1ea2, 0x81} /* capital letter a with hook above */, + {0x1ea3, 0xe4} /* small letter a with hook above */, + {0x1ea4, 0x83} /* capital letter a with circumflex and acute */, + {0x1ea5, 0xc3} /* small letter a with circumflex and acute */, + {0x1ea6, 0x84} /* capital letter a with circumflex and grave */, + {0x1ea7, 0xc0} /* small letter a with circumflex and grave */, + {0x1ea8, 0x85} /* capital letter a with circumflex and hook above */, + {0x1ea9, 0xc4} /* small letter a with circumflex and hook above */, + {0x1eaa, 0x1c} /* capital letter a with circumflex and tilde */, + {0x1eab, 0xc5} /* small letter a with circumflex and tilde */, + {0x1eac, 0x03} /* latine a accent circonflexe et point souscrit */, + {0x1ead, 0xc6} /* latine a accent circonflexe et point souscrit */, + {0x1eae, 0x8d} /* capital letter a with breve and acute */, + {0x1eaf, 0xa1} /* small letter a with breve and acute */, + {0x1eb0, 0x8e} /* capital letter a with breve and grave */, + {0x1eb1, 0xa2} /* small letter a with breve and grave */, + {0x1eb2, 0x8f} /* capital letter a with breve and hook above */, + {0x1eb3, 0xa3} /* small letter a with breve and hook above */, + {0x1eb4, 0xf0} /* capital letter a with breve and tilde */, + {0x1eb5, 0xa4} /* small letter a with breve and tilde */, + {0x1eb6, 0x04} /* latine a brève et point souscrit */, + {0x1eb7, 0xa5} /* latine a brève et point souscrit */, + {0x1eb8, 0x05} /* capital letter e with dot below */, + {0x1eb9, 0xcb} /* small letter e with dot below */, + {0x1eba, 0xde} /* capital letter e with hook above */, + {0x1ebb, 0xc8} /* small letter e with hook above */, + {0x1ebc, 0xfe} /* capital letter e with tilde */, + {0x1ebd, 0xeb} /* small letter e with tilde */, + {0x1ebe, 0x90} /* capital letter e with circumflex and acute */, + {0x1ebf, 0x89} /* small letter e with circumflex and acute */, + {0x1ec0, 0x93} /* capital letter e with circumflex and grave */, + {0x1ec1, 0x8a} /* small letter e with circumflex and grave */, + {0x1ec2, 0x94} /* capital letter e with circumflex and hook above */, + {0x1ec3, 0x8b} /* small letter e with circumflex and hook above */, + {0x1ec4, 0x95} /* capital letter e with circumflex and tilde */, + {0x1ec5, 0xcd} /* small letter e with circumflex and tilde */, + {0x1ec6, 0x06} /* latine e accent circonflexe et point souscrit */, + {0x1ec7, 0x8c} /* latine e accent circonflexe et point souscrit */, + {0x1ec8, 0xb7} /* capital letter i with hook above */, + {0x1ec9, 0xcc} /* small letter i with hook above */, + {0x1eca, 0x10} /* capital letter i with dot below */, + {0x1ecb, 0xce} /* small letter i with dot below */, + {0x1ecc, 0x11} /* capital letter o with dot below */, + {0x1ecd, 0x86} /* small letter o with dot below */, + {0x1ece, 0xbd} /* capital letter o with hook above */, + {0x1ecf, 0xd5} /* small letter o with hook above */, + {0x1ed0, 0x96} /* capital letter o with circumflex and acute */, + {0x1ed1, 0xd3} /* small letter o with circumflex and acute */, + {0x1ed2, 0x97} /* capital letter o with circumflex and grave */, + {0x1ed3, 0xd2} /* small letter o with circumflex and grave */, + {0x1ed4, 0x98} /* capital letter o with circumflex and hook above */, + {0x1ed5, 0xb0} /* small letter o with circumflex and hook above */, + {0x1ed7, 0x87} /* small letter o with circumflex and tilde */, + {0x1ed8, 0x12} /* latine o accent circonflexe et point souscrit */, + {0x1ed9, 0xb6} /* latine o accent circonflexe et point souscrit */, + {0x1eda, 0x9d} /* capital letter o with horn and acute */, + {0x1edb, 0xa7} /* small letter o with horn and acute */, + {0x1edc, 0x9e} /* capital letter o with horn and grave */, + {0x1edd, 0xa9} /* small letter o with horn and grave */, + {0x1ede, 0x9f} /* capital letter o with horn and hook above */, + {0x1edf, 0xaa} /* small letter o with horn and hook above */, + {0x1ee0, 0xa6} /* capital letter o with horn and tilde */, + {0x1ee1, 0xab} /* small letter o with horn and tilde */, + {0x1ee2, 0x13} /* latine o cornu point souscrit */, + {0x1ee3, 0xae} /* latine o cornu point souscrit */, + {0x1ee4, 0x14} /* capital letter u with dot below */, + {0x1ee5, 0xf8} /* small letter u with dot below */, + {0x1ee6, 0xd1} /* capital letter u with hook above */, + {0x1ee7, 0xfb} /* small letter u with hook above */, + {0x1ee8, 0xad} /* capital letter u with horn and acute */, + {0x1ee9, 0xd9} /* small letter u with horn and acute */, + {0x1eea, 0xaf} /* capital letter u with horn and grave */, + {0x1eeb, 0xd8} /* small letter u with horn and grave */, + {0x1eec, 0xb1} /* capital letter u with horn and hook above */, + {0x1eed, 0xba} /* small letter u with horn and hook above */, + {0x1eee, 0x1d} /* capital letter u with horn and tilde */, + {0x1eef, 0xbb} /* small letter u with horn and tilde */, + {0x1ef0, 0x15} /* latine u cornu point souscrit */, + {0x1ef1, 0xbf} /* latine u cornu point souscrit */, + {0x1ef2, 0xb2} /* capital letter y with grave */, + {0x1ef3, 0xff} /* small letter y with grave */, + {0x1ef4, 0x19} /* capital letter y with dot below */, + {0x1ef5, 0x9c} /* small letter y with dot below */, + {0x1ef6, 0xfd} /* capital letter y with hook above */, + {0x1ef7, 0x9b} /* small letter y with hook above */, + {0x1ef8, 0xb3} /* capital letter y with tilde */, + {0x1ef9, 0xcf} /* small letter y with tilde */ +}; + +/* +#define cet_ucs4_to_vps_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_vps_extra[cet_ucs4_to_vps_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_vps = /* defined in cet.h */ +{ + cet_cs_name_vps, /* name of character set */ + cet_cs_alias_vps, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_vps, /* char to UCS-4 value table */ + cet_ucs4_ofs_vps, /* first non standard character */ + cet_ucs4_cnt_vps, /* number of values in table */ + + cet_ucs4_to_vps_links, /* UCS-4 to char links */ + cet_ucs4_to_vps_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int vps_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x1ea0, 0x1eac, 0x1eb6, 0x1eb8, 0x1ec6, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x1eca, 0x1ecc, 0x1ed8, 0x1ee2, 0x1ee4, 0x1ef0, 0x0016, 0x0017, + 0x0018, 0x1ef4, 0x001a, 0x001b, 0x1eaa, 0x1eee, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c0, 0x1ea2, 0x00c3, 0x1ea4, 0x1ea6, 0x1ea8, 0x1ecd, 0x1ed7, + 0x0102, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec7, 0x1eae, 0x1eb0, 0x1eb2, + 0x1ebe, -1, -1, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ed0, 0x1ed2, + 0x1ed4, -1, 0x00fd, 0x1ef7, 0x1ef5, 0x1eda, 0x1edc, 0x1ede, + -1, 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1ee0, 0x1edb, + 0x00d9, 0x1edd, 0x1edf, 0x1ee1, 0x0168, 0x1ee8, 0x1ee3, 0x1eea, + 0x1ed5, 0x1eec, 0x1ef2, 0x1ef8, 0x00cd, 0x00cc, 0x1ed9, 0x1ec8, + 0x0128, 0x00d3, 0x1eed, 0x1eef, 0x00d2, 0x1ece, 0x00d5, 0x1ef1, + 0x1ea7, 0x00c1, 0x00c2, 0x1ea5, 0x1ea9, 0x1eab, 0x1ead, 0x0111, + 0x1ebb, 0x00c9, 0x00ca, 0x1eb9, 0x1ec9, 0x1ec5, 0x1ecb, 0x1ef9, + 0x01af, 0x1ee6, 0x1ed3, 0x1ed1, 0x00d4, 0x1ecf, 0x01a1, 0x00c8, + 0x1eeb, 0x1ee9, 0x00da, 0x0169, 0x01b0, 0x00dd, 0x1eba, -1, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x1ea3, 0x1ea1, 0x0103, -1, + 0x00e8, 0x00e9, 0x00ea, 0x1ebd, 0x00ec, 0x00ed, -1, 0x0129, + 0x1eb4, 0x0110, 0x00f2, 0x00f3, 0x00f4, 0x00f5, -1, 0x01a0, + 0x1ee5, 0x00f9, 0x00fa, 0x1ee7, -1, 0x1ef6, 0x1ebc, 0x1ef3 +}; +*/ + +#endif diff --git a/cet_util.c b/cet_util.c new file mode 100644 index 000000000..d8fd3930f --- /dev/null +++ b/cet_util.c @@ -0,0 +1,1304 @@ +/* + + Character encoding transformation - utilities + + Copyright (C) 2005,2006,2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include +#include +#include +#include +#include + +#include "defs.h" +#include "cet.h" +#include "cet_util.h" + +#if HAVE_LIBEXPAT +# include +#endif + +#define MYNAME "cet_util" + +static cet_cs_vec_t *cet_cs_vec_root = NULL; + +typedef struct cet_cs_alias_s +{ + char *name; + cet_cs_vec_t *vec; +} cet_cs_alias_t; + +static cet_cs_alias_t *cet_cs_alias; +static int cet_cs_alias_ct = 0; +static int cet_cs_vec_ct = 0; +static int cet_output = 0; + +/* %%% fixed inbuild character sets %%% */ + +#include "cet/ansi_x3_4_1968.h" +#include "cet/iso_8859_1.h" +#include "cet/iso_8859_15.h" +#include "cet/cp1252.h" + +/* %%% short hand strings transmission for main character sets %%% */ + +char * +cet_str_utf8_to_iso8859_1(const char *src) +{ + return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_1); +} + +char * +cet_str_iso8859_1_to_utf8(const char *src) +{ + return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_1); +} + +char * +cet_str_utf8_to_iso8859_15(const char *src) +{ + return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_15); +} + +char * +cet_str_iso8859_15_to_utf8(const char *src) +{ + return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_15); +} + +char * +cet_str_utf8_to_us_ascii(const char *src) +{ + return cet_str_utf8_to_any(src, &cet_cs_vec_ansi_x3_4_1968); +} + +char * +cet_str_us_ascii_to_utf8(const char *src) +{ + return cet_str_any_to_utf8(src, &cet_cs_vec_ansi_x3_4_1968); +} + +char * +cet_str_utf8_to_cp1252(const char *src) +{ + return cet_str_utf8_to_any(src, &cet_cs_vec_cp1252); +} + +char * +cet_str_cp1252_to_utf8(const char *src) +{ + return cet_str_any_to_utf8(src, &cet_cs_vec_cp1252); +} + + +/* helpers */ + +/* %%% %%% + * + * + */ +#if HAVE_LIBEXPAT +int XMLCALL cet_lib_expat_UnknownEncodingHandler(void *data, const XML_Char *xml_encoding, XML_Encoding *info) +{ + cet_cs_vec_t *cs; + int i, c, ucs4_def; + const char *encoding; + + encoding = xml_convert_to_char_string(xml_encoding); + cs = cet_find_cs_by_name(encoding); + if (cs == NULL) return XML_STATUS_ERROR; /* fatal(MYNAME ": Unknown character set \"%s\"!\n", encoding); */ + + cet_char_to_ucs4(CET_NOT_CONVERTABLE_DEFAULT, cs, &ucs4_def); + + for (i = 0; i < cs->ucs4_offset; i++) info->map[i] = i; /* equal to ascii part */ + for (i = 0; i < cs->ucs4_count; i++) /* mixed table */ + { + c = cs->ucs4_map[i]; + if (c == -1) c = ucs4_def; + info->map[i + cs->ucs4_offset] = c; + } + for (i = cs->ucs4_offset + cs->ucs4_count; i < 256; i++) info->map[i] = ucs4_def; /* non convertable trailer */ + + info->data = NULL; + info->convert = NULL; + info->release = NULL; + + cet_convert_init(CET_CHARSET_UTF8, 1); /* We do not need to transform any string */ + + if (global_opts.verbose_status > 0) + printf(MYNAME ": XML parser - encoding handler for character set \"%s\" established.\n", encoding); + + xml_free_converted_string(encoding); + return XML_STATUS_OK; +} +#endif + + +char * +cet_str_uni_to_any(const short *src, int length, const cet_cs_vec_t *dest_vec) +{ + char *res, *c; + const cet_cs_vec_t *cs = (dest_vec != NULL) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; + + res = cet_str_uni_to_utf8(src, length); + if (cs != &cet_cs_vec_utf8) + { + c = cet_str_utf8_to_any(res, cs); + xfree(res); + res = c; + } + return res; +} + +/* %%% cet_str_any_to_any %%% + * + * -->> for use in mkshort */ + +char * +cet_str_any_to_any(const char *src, const cet_cs_vec_t *src_vec, const cet_cs_vec_t *dest_vec) +{ + char *c0, *c1; + const cet_cs_vec_t *v_in = (src_vec != NULL ) ? src_vec : &cet_cs_vec_ansi_x3_4_1968; + const cet_cs_vec_t *v_out = (dest_vec != NULL ) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; + + if (src == NULL) + return NULL; + else + if ((*src == '\0') || (v_in == v_out)) return xstrdup(src); + + c0 = (v_in == &cet_cs_vec_utf8) ? xstrdup(src) : cet_str_any_to_utf8(src, v_in); + c1 = (v_out == &cet_cs_vec_utf8) ? xstrdup(c0) : cet_str_utf8_to_any(c0, v_out); + xfree(c0); + + return c1; +} + +/* %%% cet_valid_char %%% + * + * returnes 1 if convertable otherwise 0 + * + */ + +int +cet_valid_char(const char *src, const cet_cs_vec_t *vec) +{ + int value; + + const cet_cs_vec_t *v = (vec != NULL) ? vec : &cet_cs_vec_ansi_x3_4_1968; + return cet_char_to_ucs4(*src, v, &value); +} + +/* %%% include character set headers %%% */ +#if defined (CET_WANTED) +#include "cet/iso_8859_2.h" +#include "cet/cp1250.h" +#include "cet/latin_greek_1.h" +#include "cet/macintosh.h" +#include "cet/cp1250.h" +#include "cet/cp1251.h" +#include "cet/cp1252.h" +#include "cet/cp1253.h" +#include "cet/cp1254.h" +#include "cet/cp1255.h" +#include "cet/cp1256.h" +#include "cet/cp1257.h" +#include "cet/ibm437.h" +#include "cet/ibm850.h" +#include "cet/ibm851.h" +#include "cet/ibm852.h" +#include "cet/ibm855.h" +#include "cet/ibm857.h" +#include "cet/ibm860.h" +#include "cet/ibm861.h" +#include "cet/ibm862.h" +#include "cet/ibm863.h" +#include "cet/ibm864.h" +#include "cet/ibm865.h" +#include "cet/ibm868.h" +#include "cet/ibm869.h" +#include "cet/iso_8859_1.h" +#include "cet/iso_8859_10.h" +#include "cet/iso_8859_13.h" +#include "cet/iso_8859_14.h" +#include "cet/iso_8859_15.h" +#include "cet/iso_8859_2.h" +#include "cet/iso_8859_3.h" +#include "cet/iso_8859_4.h" +#include "cet/iso_8859_5.h" +#include "cet/iso_8859_6.h" +#include "cet/iso_8859_7.h" +#include "cet/iso_8859_8.h" +#include "cet/iso_8859_9.h" +#include "cet/koi8_r.h" +#include "cet/koi8_ru.h" +#include "cet/koi_8.h" +#endif + +#if CET_WANTED +#include "cet/ansi_x3_4_1968.h" +#include "cet/atarist.h" +#include "cet/baltic.h" +#include "cet/bs_4730.h" +#include "cet/bs_viewdata.h" +#include "cet/csa_z243_4_1985_1.h" +#include "cet/csa_z243_4_1985_2.h" +#include "cet/csa_z243_4_1985_gr.h" +#include "cet/csn_369103.h" +#include "cet/cwi.h" +#include "cet/dec_mcs.h" +#include "cet/din_66003.h" +#include "cet/ds_2089.h" +#include "cet/ecma_cyrillic.h" +#include "cet/es.h" +#include "cet/es2.h" +#include "cet/gb_1988_80.h" +#include "cet/gost_19768_87.h" +#include "cet/hp_roman8.h" +#include "cet/ibm037.h" +#include "cet/ibm1004.h" +#include "cet/ibm1026.h" +#include "cet/ibm1047.h" +#include "cet/ibm256.h" +#include "cet/ibm273.h" +#include "cet/ibm277.h" +#include "cet/ibm278.h" +#include "cet/ibm280.h" +#include "cet/ibm284.h" +#include "cet/ibm285.h" +#include "cet/ibm297.h" +#include "cet/ibm500.h" +#include "cet/ibm871.h" +#include "cet/ibm891.h" +#include "cet/ibm903.h" +#include "cet/ibm904.h" +#include "cet/iec_p27_1.h" +#include "cet/iso_10367_box.h" +#include "cet/iso_5427.h" +#include "cet/iso_646_irv.h" +#include "cet/iso_6937_2_25.h" +#include "cet/iso_8859_supp.h" +#include "cet/it.h" +#include "cet/jis_c6220_1969_ro.h" +#include "cet/jis_x0201.h" +#include "cet/jus_i_b1_002.h" +#include "cet/jus_i_b1_003_mac.h" +#include "cet/jus_i_b1_003_serb.h" +#include "cet/keybcs2.h" +#include "cet/koi8_u.h" +#include "cet/koi_7.h" +#include "cet/koi_8_cs2.h" +#include "cet/ksc5636.h" +#include "cet/latin_greek_1.h" +#include "cet/mac_is.h" +#include "cet/macintosh.h" +#include "cet/macintosh_ce.h" +#include "cet/msz_7795_3.h" +#include "cet/nats_dano.h" +#include "cet/nats_sefi.h" +#include "cet/nc_nc00_10.h" +#include "cet/nextstep.h" +#include "cet/nf_z_62_010.h" +#include "cet/nf_z_62_010__1973_.h" +#include "cet/ns_4551_1.h" +#include "cet/ns_4551_2.h" +#include "cet/pt.h" +#include "cet/pt2.h" +#include "cet/sami.h" +#include "cet/sen_850200_b.h" +#include "cet/sen_850200_c.h" +#include "cet/tcvn.h" +#include "cet/viscii.h" +#include "cet/vps.h" +#endif + +#ifdef DEBUG_MEM + +void +cet_check_cs(cet_cs_vec_t *vec) /* test well sorted link & extra tables */ +{ + cet_ucs4_link_t *link; + + if ((link = (cet_ucs4_link_t *)vec->ucs4_link)) + { + int i, j; + + for (i = 0, j = 1; j < vec->ucs4_links; i++, j++) + { + if (link[i].value >= link[j].value) + { + printf(MYNAME ": checked 0x%04x with 0x%04x\n", link[i].value, link[j].value); + fatal(MYNAME ": \"%s\"-link-table unsorted !!!\n", vec->name); + } + + } + } + if ((link = (cet_ucs4_link_t *)vec->ucs4_extra)) + { + int i, j; + + for (i = 0, j = 1; j < vec->ucs4_extras; i++, j++) + { + if (link[i].value >= link[j].value) + { + printf(MYNAME ": check 0x%04x with 0x%04x\n", link[i].value, link[j].value); + fatal(MYNAME ": \"%s\"-extra-table unsorted !!!\n", vec->name); + } + + } + } +} + +#endif + +static signed int +cet_cs_alias_qsort_cb(const void *a, const void *b) +{ + const cet_cs_alias_t *va = a; + const cet_cs_alias_t *vb = b; + return case_ignore_strcmp(va->name, vb->name); +} + +static signed int +cet_cs_vec_qsort_cb(const void *a, const void *b) +{ + const cet_cs_vec_t *va = *(cet_cs_vec_t **)a; + const cet_cs_vec_t *vb = *(cet_cs_vec_t **)b; + return case_ignore_strcmp(va->name, vb->name); +} + +void +cet_register_cs(cet_cs_vec_t *vec) +{ + if (vec->next == NULL) + { + vec->next = cet_cs_vec_root; + cet_cs_vec_root = vec; + cet_cs_vec_ct++; +#ifdef DEBUG_MEM + cet_check_cs(vec); +#endif + } +} + +/* Dummy vector for our native character set */ + +const char *cet_cs_utf8_alias[] = +{ + "utf8", NULL +}; + +cet_cs_vec_t cet_cs_vec_utf8 = +{ + CET_CHARSET_UTF8, + cet_cs_utf8_alias, + NULL, /* dec */ + NULL, /* enc */ + NULL, /* link */ + 0, + 0, + NULL, /* extra */ + 0, /* extras */ + NULL +}; + +void +cet_register(void) +{ + int i, c; + + if (cet_cs_vec_root != NULL) return; + + cet_cs_vec_ct = 0; + cet_register_cs(&cet_cs_vec_utf8); /* internal place holder */ + +#ifdef cet_cs_name_ansi_x3_4_1968 +cet_register_cs(&cet_cs_vec_ansi_x3_4_1968); +#endif +#ifdef cet_cs_name_atarist +cet_register_cs(&cet_cs_vec_atarist); +#endif +#ifdef cet_cs_name_baltic +cet_register_cs(&cet_cs_vec_baltic); +#endif +#ifdef cet_cs_name_bs_4730 +cet_register_cs(&cet_cs_vec_bs_4730); +#endif +#ifdef cet_cs_name_bs_viewdata +cet_register_cs(&cet_cs_vec_bs_viewdata); +#endif +#ifdef cet_cs_name_cp1250 +cet_register_cs(&cet_cs_vec_cp1250); +#endif +#ifdef cet_cs_name_cp1251 +cet_register_cs(&cet_cs_vec_cp1251); +#endif +#ifdef cet_cs_name_cp1252 +cet_register_cs(&cet_cs_vec_cp1252); +#endif +#ifdef cet_cs_name_cp1253 +cet_register_cs(&cet_cs_vec_cp1253); +#endif +#ifdef cet_cs_name_cp1254 +cet_register_cs(&cet_cs_vec_cp1254); +#endif +#ifdef cet_cs_name_cp1255 +cet_register_cs(&cet_cs_vec_cp1255); +#endif +#ifdef cet_cs_name_cp1256 +cet_register_cs(&cet_cs_vec_cp1256); +#endif +#ifdef cet_cs_name_cp1257 +cet_register_cs(&cet_cs_vec_cp1257); +#endif +#ifdef cet_cs_name_csa_z243_4_1985_1 +cet_register_cs(&cet_cs_vec_csa_z243_4_1985_1); +#endif +#ifdef cet_cs_name_csa_z243_4_1985_2 +cet_register_cs(&cet_cs_vec_csa_z243_4_1985_2); +#endif +#ifdef cet_cs_name_csa_z243_4_1985_gr +cet_register_cs(&cet_cs_vec_csa_z243_4_1985_gr); +#endif +#ifdef cet_cs_name_csn_369103 +cet_register_cs(&cet_cs_vec_csn_369103); +#endif +#ifdef cet_cs_name_cwi +cet_register_cs(&cet_cs_vec_cwi); +#endif +#ifdef cet_cs_name_dec_mcs +cet_register_cs(&cet_cs_vec_dec_mcs); +#endif +#ifdef cet_cs_name_din_66003 +cet_register_cs(&cet_cs_vec_din_66003); +#endif +#ifdef cet_cs_name_ds_2089 +cet_register_cs(&cet_cs_vec_ds_2089); +#endif +#ifdef cet_cs_name_ecma_cyrillic +cet_register_cs(&cet_cs_vec_ecma_cyrillic); +#endif +#ifdef cet_cs_name_es +cet_register_cs(&cet_cs_vec_es); +#endif +#ifdef cet_cs_name_es2 +cet_register_cs(&cet_cs_vec_es2); +#endif +#ifdef cet_cs_name_gb_1988_80 +cet_register_cs(&cet_cs_vec_gb_1988_80); +#endif +#ifdef cet_cs_name_gost_19768_87 +cet_register_cs(&cet_cs_vec_gost_19768_87); +#endif +#ifdef cet_cs_name_hp_roman8 +cet_register_cs(&cet_cs_vec_hp_roman8); +#endif +#ifdef cet_cs_name_ibm037 +cet_register_cs(&cet_cs_vec_ibm037); +#endif +#ifdef cet_cs_name_ibm1004 +cet_register_cs(&cet_cs_vec_ibm1004); +#endif +#ifdef cet_cs_name_ibm1026 +cet_register_cs(&cet_cs_vec_ibm1026); +#endif +#ifdef cet_cs_name_ibm1047 +cet_register_cs(&cet_cs_vec_ibm1047); +#endif +#ifdef cet_cs_name_ibm256 +cet_register_cs(&cet_cs_vec_ibm256); +#endif +#ifdef cet_cs_name_ibm273 +cet_register_cs(&cet_cs_vec_ibm273); +#endif +#ifdef cet_cs_name_ibm277 +cet_register_cs(&cet_cs_vec_ibm277); +#endif +#ifdef cet_cs_name_ibm278 +cet_register_cs(&cet_cs_vec_ibm278); +#endif +#ifdef cet_cs_name_ibm280 +cet_register_cs(&cet_cs_vec_ibm280); +#endif +#ifdef cet_cs_name_ibm284 +cet_register_cs(&cet_cs_vec_ibm284); +#endif +#ifdef cet_cs_name_ibm285 +cet_register_cs(&cet_cs_vec_ibm285); +#endif +#ifdef cet_cs_name_ibm297 +cet_register_cs(&cet_cs_vec_ibm297); +#endif +#ifdef cet_cs_name_ibm437 +cet_register_cs(&cet_cs_vec_ibm437); +#endif +#ifdef cet_cs_name_ibm500 +cet_register_cs(&cet_cs_vec_ibm500); +#endif +#ifdef cet_cs_name_ibm850 +cet_register_cs(&cet_cs_vec_ibm850); +#endif +#ifdef cet_cs_name_ibm851 +cet_register_cs(&cet_cs_vec_ibm851); +#endif +#ifdef cet_cs_name_ibm852 +cet_register_cs(&cet_cs_vec_ibm852); +#endif +#ifdef cet_cs_name_ibm855 +cet_register_cs(&cet_cs_vec_ibm855); +#endif +#ifdef cet_cs_name_ibm857 +cet_register_cs(&cet_cs_vec_ibm857); +#endif +#ifdef cet_cs_name_ibm860 +cet_register_cs(&cet_cs_vec_ibm860); +#endif +#ifdef cet_cs_name_ibm861 +cet_register_cs(&cet_cs_vec_ibm861); +#endif +#ifdef cet_cs_name_ibm862 +cet_register_cs(&cet_cs_vec_ibm862); +#endif +#ifdef cet_cs_name_ibm863 +cet_register_cs(&cet_cs_vec_ibm863); +#endif +#ifdef cet_cs_name_ibm864 +cet_register_cs(&cet_cs_vec_ibm864); +#endif +#ifdef cet_cs_name_ibm865 +cet_register_cs(&cet_cs_vec_ibm865); +#endif +#ifdef cet_cs_name_ibm868 +cet_register_cs(&cet_cs_vec_ibm868); +#endif +#ifdef cet_cs_name_ibm869 +cet_register_cs(&cet_cs_vec_ibm869); +#endif +#ifdef cet_cs_name_ibm871 +cet_register_cs(&cet_cs_vec_ibm871); +#endif +#ifdef cet_cs_name_ibm891 +cet_register_cs(&cet_cs_vec_ibm891); +#endif +#ifdef cet_cs_name_ibm903 +cet_register_cs(&cet_cs_vec_ibm903); +#endif +#ifdef cet_cs_name_ibm904 +cet_register_cs(&cet_cs_vec_ibm904); +#endif +#ifdef cet_cs_name_iec_p27_1 +cet_register_cs(&cet_cs_vec_iec_p27_1); +#endif +#ifdef cet_cs_name_iso_10367_box +cet_register_cs(&cet_cs_vec_iso_10367_box); +#endif +#ifdef cet_cs_name_iso_5427 +cet_register_cs(&cet_cs_vec_iso_5427); +#endif +#ifdef cet_cs_name_iso_646_irv +cet_register_cs(&cet_cs_vec_iso_646_irv); +#endif +#ifdef cet_cs_name_iso_6937_2_25 +cet_register_cs(&cet_cs_vec_iso_6937_2_25); +#endif +#ifdef cet_cs_name_iso_8859_1 +cet_register_cs(&cet_cs_vec_iso_8859_1); +#endif +#ifdef cet_cs_name_iso_8859_10 +cet_register_cs(&cet_cs_vec_iso_8859_10); +#endif +#ifdef cet_cs_name_iso_8859_13 +cet_register_cs(&cet_cs_vec_iso_8859_13); +#endif +#ifdef cet_cs_name_iso_8859_14 +cet_register_cs(&cet_cs_vec_iso_8859_14); +#endif +#ifdef cet_cs_name_iso_8859_15 +cet_register_cs(&cet_cs_vec_iso_8859_15); +#endif +#ifdef cet_cs_name_iso_8859_2 +cet_register_cs(&cet_cs_vec_iso_8859_2); +#endif +#ifdef cet_cs_name_iso_8859_3 +cet_register_cs(&cet_cs_vec_iso_8859_3); +#endif +#ifdef cet_cs_name_iso_8859_4 +cet_register_cs(&cet_cs_vec_iso_8859_4); +#endif +#ifdef cet_cs_name_iso_8859_5 +cet_register_cs(&cet_cs_vec_iso_8859_5); +#endif +#ifdef cet_cs_name_iso_8859_6 +cet_register_cs(&cet_cs_vec_iso_8859_6); +#endif +#ifdef cet_cs_name_iso_8859_7 +cet_register_cs(&cet_cs_vec_iso_8859_7); +#endif +#ifdef cet_cs_name_iso_8859_8 +cet_register_cs(&cet_cs_vec_iso_8859_8); +#endif +#ifdef cet_cs_name_iso_8859_9 +cet_register_cs(&cet_cs_vec_iso_8859_9); +#endif +#ifdef cet_cs_name_iso_8859_supp +cet_register_cs(&cet_cs_vec_iso_8859_supp); +#endif +#ifdef cet_cs_name_it +cet_register_cs(&cet_cs_vec_it); +#endif +#ifdef cet_cs_name_jis_c6220_1969_ro +cet_register_cs(&cet_cs_vec_jis_c6220_1969_ro); +#endif +#ifdef cet_cs_name_jis_x0201 +cet_register_cs(&cet_cs_vec_jis_x0201); +#endif +#ifdef cet_cs_name_jus_i_b1_002 +cet_register_cs(&cet_cs_vec_jus_i_b1_002); +#endif +#ifdef cet_cs_name_jus_i_b1_003_mac +cet_register_cs(&cet_cs_vec_jus_i_b1_003_mac); +#endif +#ifdef cet_cs_name_jus_i_b1_003_serb +cet_register_cs(&cet_cs_vec_jus_i_b1_003_serb); +#endif +#ifdef cet_cs_name_keybcs2 +cet_register_cs(&cet_cs_vec_keybcs2); +#endif +#ifdef cet_cs_name_koi8_r +cet_register_cs(&cet_cs_vec_koi8_r); +#endif +#ifdef cet_cs_name_koi8_ru +cet_register_cs(&cet_cs_vec_koi8_ru); +#endif +#ifdef cet_cs_name_koi8_u +cet_register_cs(&cet_cs_vec_koi8_u); +#endif +#ifdef cet_cs_name_koi_7 +cet_register_cs(&cet_cs_vec_koi_7); +#endif +#ifdef cet_cs_name_koi_8 +cet_register_cs(&cet_cs_vec_koi_8); +#endif +#ifdef cet_cs_name_koi_8_cs2 +cet_register_cs(&cet_cs_vec_koi_8_cs2); +#endif +#ifdef cet_cs_name_ksc5636 +cet_register_cs(&cet_cs_vec_ksc5636); +#endif +#ifdef cet_cs_name_latin_greek_1 +cet_register_cs(&cet_cs_vec_latin_greek_1); +#endif +#ifdef cet_cs_name_mac_is +cet_register_cs(&cet_cs_vec_mac_is); +#endif +#ifdef cet_cs_name_macintosh +cet_register_cs(&cet_cs_vec_macintosh); +#endif +#ifdef cet_cs_name_macintosh_ce +cet_register_cs(&cet_cs_vec_macintosh_ce); +#endif +#ifdef cet_cs_name_msz_7795_3 +cet_register_cs(&cet_cs_vec_msz_7795_3); +#endif +#ifdef cet_cs_name_nats_dano +cet_register_cs(&cet_cs_vec_nats_dano); +#endif +#ifdef cet_cs_name_nats_sefi +cet_register_cs(&cet_cs_vec_nats_sefi); +#endif +#ifdef cet_cs_name_nc_nc00_10 +cet_register_cs(&cet_cs_vec_nc_nc00_10); +#endif +#ifdef cet_cs_name_nextstep +cet_register_cs(&cet_cs_vec_nextstep); +#endif +#ifdef cet_cs_name_nf_z_62_010 +cet_register_cs(&cet_cs_vec_nf_z_62_010); +#endif +#ifdef cet_cs_name_nf_z_62_010__1973_ +cet_register_cs(&cet_cs_vec_nf_z_62_010__1973_); +#endif +#ifdef cet_cs_name_ns_4551_1 +cet_register_cs(&cet_cs_vec_ns_4551_1); +#endif +#ifdef cet_cs_name_ns_4551_2 +cet_register_cs(&cet_cs_vec_ns_4551_2); +#endif +#ifdef cet_cs_name_pt +cet_register_cs(&cet_cs_vec_pt); +#endif +#ifdef cet_cs_name_pt2 +cet_register_cs(&cet_cs_vec_pt2); +#endif +#ifdef cet_cs_name_sami +cet_register_cs(&cet_cs_vec_sami); +#endif +#ifdef cet_cs_name_sen_850200_b +cet_register_cs(&cet_cs_vec_sen_850200_b); +#endif +#ifdef cet_cs_name_sen_850200_c +cet_register_cs(&cet_cs_vec_sen_850200_c); +#endif +#ifdef cet_cs_name_tcvn +cet_register_cs(&cet_cs_vec_tcvn); +#endif +#ifdef cet_cs_name_viscii +cet_register_cs(&cet_cs_vec_viscii); +#endif +#ifdef cet_cs_name_vps +cet_register_cs(&cet_cs_vec_vps); +#endif + + if ( cet_cs_vec_ct > 0) + { + cet_cs_vec_t *p; + cet_cs_alias_t *list; + c = 0; + + /* enumerate count of all names and aliases */ + + for (p = cet_cs_vec_root; p != NULL; p = p->next) + { + c++; + if (p->alias != NULL) + { + char **a = (char **)p->alias; + while ((*a) != NULL) + { + a++; + c++; + } + } + } + /* create name to vec table */ + + list = xcalloc(c, sizeof(*list)); + i = 0; + for (p = cet_cs_vec_root; p != NULL; p = p->next) + { + if (p->alias != NULL) + { + char **a = (char **)p->alias; + + list[i].name = xstrdup(p->name); + list[i].vec = p; + i++; + while (*a != NULL) + { + list[i].name = xstrdup(*a); + list[i].vec = p; + i++; + a++; + } + } + } + qsort(list, c, sizeof(*list), cet_cs_alias_qsort_cb); + cet_cs_alias = list; + cet_cs_alias_ct = c; + + /* install fallback for ascii-like (first 128 ch.) character sets */ + for (i = 1250; i <= 1258; i++) { + char name[16]; + cet_cs_vec_t *vec; + + snprintf(name, sizeof(name), "WIN-CP%d", i); + if ((vec = cet_find_cs_by_name(name))) + vec->fallback = &cet_cs_vec_ansi_x3_4_1968; + } + for (i = 1; i <= 15; i++) { + char name[16]; + cet_cs_vec_t *vec; + + snprintf(name, sizeof(name), "ISO-8859-%d", i); + if ((vec = cet_find_cs_by_name(name))) + vec->fallback = &cet_cs_vec_ansi_x3_4_1968; + } + } +#ifdef CET_DEBUG + printf("We have registered %d character sets with %d aliases\n", cet_cs_vec_ct, cet_cs_alias_ct); +#endif +} + +cet_cs_vec_t * +cet_find_cs_by_name(const char *name) +{ + int i, j; + + cet_register(); + + if (cet_cs_alias == NULL) return NULL; + + i = 0; + j = cet_cs_alias_ct - 1; + + while (i <= j) + { + int a, x; + cet_cs_alias_t *n; + + a = (i + j) >> 1; + n = &cet_cs_alias[a]; + x = case_ignore_strcmp(name, n->name); + if (x == 0) return n->vec; + else if (x < 0) j = a - 1; + else i = a + 1; + } + return NULL; +} + +void +cet_deregister(void) +{ + int i; + int j = cet_cs_alias_ct; + cet_cs_alias_t *p = cet_cs_alias; + + if (p == NULL) return; + + cet_cs_alias_ct = 0; + cet_cs_alias = NULL; + + for (i = 0; i < j; i++) + xfree(p[i].name); + xfree(p); +} + +/* gpsbabel additions */ + +int +cet_validate_cs(const char *cs, cet_cs_vec_t **vec, char **cs_name) +{ + cet_cs_vec_t *v; + + if ((cs == NULL) || (strlen(cs) == 0)) /* set default us-ascii */ + { + *vec = &cet_cs_vec_ansi_x3_4_1968; + *cs_name = xstrdup(CET_CHARSET_ASCII); + return 1; + } + + v = cet_find_cs_by_name(cs); + if (v != NULL) + { + *cs_name = strupper(xstrdup(v->name)); + *vec = v; + return 1; + } + else + { + *cs_name = NULL; + *vec = NULL; + return 0; + } +} + +void +cet_convert_deinit(void) +{ + if (global_opts.charset_name != NULL) xfree(global_opts.charset_name); + global_opts.charset = NULL; + global_opts.charset_name = NULL; +} + +void +cet_convert_init(const char *cs_name, const int force) +{ + if ((force != 0) || (global_opts.charset == NULL)) + { + cet_convert_deinit(); + if (0 == cet_validate_cs(cs_name, &global_opts.charset, &global_opts.charset_name)) + fatal("Unsupported character set \"%s\"!\n", cs_name); + } +} + +/* -------------------------------------------------------------------- */ + +static void +cet_flag_waypt(const waypoint *wpt) +{ + ((waypoint *)(wpt))->wpt_flags.cet_converted = 1; +} + +static void +cet_flag_route(const route_head *rte) +{ + ((route_head *)(rte))->cet_converted = 1; +} + +static void +cet_flag_all(void) +{ + waypt_disp_all(cet_flag_waypt); + route_disp_all(cet_flag_route, NULL, cet_flag_waypt); + track_disp_all(cet_flag_route, NULL, cet_flag_waypt); +} + +/* -------------------------------------------------------------------- */ +/* %%% complete data strings transformation %%% */ +/* -------------------------------------------------------------------- */ + +static char * (*converter) (const char *) = NULL; + +/* two converters */ + +static char * +cet_convert_to_utf8(const char *str) +{ + return cet_str_any_to_utf8(str, global_opts.charset); +} + +static char * +cet_convert_from_utf8(const char *str) +{ + return cet_str_utf8_to_any(str, global_opts.charset); +} + +/* cet_convert_string: internal used within cet_convert_strings process */ + +char * +cet_convert_string(char *str) +{ + char *res; + + if (str == NULL) return NULL; /* return origin if empty or NULL */ + else if (*str == '\0') return str; + + res = converter(str); + xfree(str); + return res; +} + +/* cet_convert_waypt: internal used within cet_convert_strings process */ + +static void +cet_convert_waypt(const waypoint *wpt) +{ + waypoint *w = (waypoint *)wpt; + format_specific_data *fs; + url_link *url_next; + + if ((cet_output == 0) && (w->wpt_flags.cet_converted != 0)) return; + + w->wpt_flags.cet_converted = 1; + + w->shortname = cet_convert_string(wpt->shortname); + w->description = cet_convert_string(wpt->description); + w->notes = cet_convert_string(wpt->notes); + w->url = cet_convert_string(wpt->url); + w->url_link_text = cet_convert_string(wpt->url_link_text); + for (url_next = w->url_next; url_next; url_next = url_next->url_next) { + url_next->url = cet_convert_string(url_next->url); + url_next->url_link_text = cet_convert_string(url_next->url_link_text); + } + + fs = wpt->fs; + while (fs != NULL) + { + if (fs->convert != NULL) + fs->convert(fs); + fs = fs->next; + } +} + +/* cet_convert_route_hdr: internal used within cet_convert_strings process */ + +static void +cet_convert_route_hdr(const route_head *route) +{ + route_head *rte = (route_head *)route; + + if ((cet_output == 0) && (rte->cet_converted != 0)) return; + + rte->cet_converted = 1; + + rte->rte_name = cet_convert_string(route->rte_name); + rte->rte_desc = cet_convert_string(route->rte_desc); + rte->rte_url = cet_convert_string(route->rte_url); +} + +/* cet_convert_route_tlr: internal used within cet_convert_strings process */ + +static void +cet_convert_route_tlr(const route_head *route) +{ +} + +/* %%% cet_convert_strings (public) %%% + * + * - Convert all well known strings of GPS data from or to UTF-8 - + * + * !!! One of "source" or "target" must be internal cet_cs_vec_utf8 or NULL !!! */ + +void +cet_convert_strings(const cet_cs_vec_t *source, const cet_cs_vec_t *target, const char *format) +{ + char *cs_name_from, *cs_name_to; + + converter = NULL; + + if ((source == NULL) || (source == &cet_cs_vec_utf8)) + { + if ((target == NULL) || (target == &cet_cs_vec_utf8)) { + cet_flag_all(); + return; + } + + cet_output = 1; + + converter = cet_convert_from_utf8; + cs_name_from = (char *)cet_cs_vec_utf8.name; + cs_name_to = (char *)target->name; + } + else { + if ((target != NULL) && (target != &cet_cs_vec_utf8)) + fatal(MYNAME ": Internal error!\n"); + + cet_output = 0; + + converter = cet_convert_to_utf8; + cs_name_to = (char *)cet_cs_vec_utf8.name; + cs_name_from = (char *)source->name; + } + + if (global_opts.debug_level > 0) + printf(MYNAME ": Converting from \"%s\" to \"%s\"", cs_name_from, cs_name_to); + + waypt_disp_all(cet_convert_waypt); + route_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); + track_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); + + cet_output = 0; + + if (global_opts.debug_level > 0) + printf(", done.\n"); +} + +/* %%% cet_disp_character_set_names %%% + * + * - Put all character set names and aliases to "FILE" - */ + +void +cet_disp_character_set_names(FILE *fout) +{ + int i, c, ac; + cet_cs_vec_t *vec; + cet_cs_vec_t **list; + + if (cet_cs_alias_ct == 0) return; + + c = 0; + for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) c++; + + if (cet_cs_vec_ct != c) + fatal(MYNAME ": internal error \"%s\"!\n", "cet_disp_character_set_names"); + + list = (cet_cs_vec_t **)xcalloc(c, sizeof(*list)); + + i = 0; /* fill the list */ + for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) list[i++] = vec; + qsort(list, c, sizeof(*list), cet_cs_vec_qsort_cb); /* sort list by name */ + + ac = 0; + + fprintf(fout, "GPSbabel builtin character sets: (-c option)\n"); + for (i = 0; i < c; i++) + { + char **a; + + vec = list[i]; + fprintf(fout, "\n* %s", vec->name); + + a = (char **)vec->alias; + if (a != NULL) + { + int column = 0; + int alias = 0; + + while (*a != NULL) + { + if (case_ignore_strcmp(*a, vec->name) != 0) + { + ac++; + fprintf(fout, "%s%s%s", + (alias++ > 0) ? ", " : "", + (column++ % 6 == 0) ? "\n\t" : "", + *a); + } + a++; + } + } + } + fprintf(fout, "\n\n"); + fprintf(fout, "We have %d builtin character sets with %d aliases!\n", c, ac); + xfree(list); +} + +/* %%% cet_fprintf / cet_vfprintf %%% + * + * - print any special hard-coded characters from inside a module - */ + +int cet_gbfprintf(gbfile *stream, const cet_cs_vec_t *src_vec, const char *fmt, ...) +{ + int res; + char *cout; + va_list args; + + va_start(args, fmt); + xvasprintf(&cout, fmt, args); + va_end(args); + + if (global_opts.charset != src_vec) + { + if (src_vec != &cet_cs_vec_utf8) { + char *ctemp = cet_str_any_to_utf8(cout, src_vec); + xfree(cout); + cout = ctemp; + } + if (global_opts.charset != &cet_cs_vec_utf8) { + char *ctemp = cet_str_utf8_to_any(cout, global_opts.charset); + xfree(cout); + cout = ctemp; + } + } + + res = gbfprintf(stream, "%s", cout); + xfree(cout); + + return res; +} + +/* + * 'str' points to an array of XML_Chars which may be UNICODE16 + * words in native endianness. + */ + +const char *xml_convert_to_char_string_n(const XML_Char *src, int *n) +{ +#ifdef XML_UNICODE + char *utf8; + char *utf8b; + int i, j; + + /* + * '*n' is the number of source bytes. + * Walk over that, converting each character and + * discarding it, but tallying 'i' as the number of + * bytes in the destination string. + */ + i = 0; + for (j = 0; j < *n; j++) { + i += cet_ucs4_to_utf8(NULL, 6, src[j]); + } + + /* Update output byte count in caller. */ + *n = i; + + /* Appropriately size (not zero terminated) buffer */ + utf8 = utf8b = xmalloc(i); + + for (j = 0; utf8 < utf8b + i; j++) { + utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); + } + + return utf8b; +#else + return src; +#endif +} + +/* + * 'str' points to NULL terminated string of XML_Chars which + * may be UNICODE16 words in native endianness. + */ + +const char *xml_convert_to_char_string(const XML_Char *src) +{ +#ifdef XML_UNICODE + char *utf8; + char *utf8b; + int i, j; + const XML_Char *in = src; + + /* Walk source array until we find source terminator */ + i = 0; + for (j = 0; src[j]; j++) { + i += cet_ucs4_to_utf8(NULL, 6, src[j]); + } + + /* We return a NUL terminated string. */ + utf8 = utf8b = xmalloc(i + 1); + in = src; + + for (j = 0; utf8 < utf8b + i; j++) { + utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); + } + *utf8 = '\0'; + + return utf8b; + +#else + return src; +#endif +} + + +void xml_free_converted_string(const char *str) +{ +#ifdef XML_UNICODE + xfree((void *) str); +#endif +} + +const char **xml_convert_attrs_to_char_string(const XML_Char **xml_attr) +{ +#ifdef XML_UNICODE + // First count size of array + int size = 0; + int i; + const XML_Char **ptr; + const char **char_attrs; + + if (xml_attr == NULL) + return NULL; + + for (ptr = xml_attr; *ptr != NULL; ++ptr) + ++size; + + // Allocate space + char_attrs = xmalloc((size + 1) * sizeof(char *)); + + // Duplicate strings + for (i = 0; i < size; ++i) + char_attrs[i] = xml_convert_to_char_string(xml_attr[i]); + char_attrs[size] = NULL; + + return char_attrs; +#else + return xml_attr; +#endif +} + +void xml_free_converted_attrs(const char **attr) +{ +#ifdef XML_UNICODE + while (attr != NULL && *attr != NULL) { + xfree((void *)*attr); + ++attr; + } +#endif +} diff --git a/cet_util.h b/cet_util.h new file mode 100644 index 000000000..9a010a459 --- /dev/null +++ b/cet_util.h @@ -0,0 +1,133 @@ +/* + + Character encoding transformation - utilities header + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#ifndef CET_UTIL_H +#define CET_UTIL_H + +#include +#include +#include "config.h" + +#if HAVE_LIBEXPAT +# include +#else +typedef char XML_Char; +#endif + +#include "cet.h" + +cet_cs_vec_t *cet_find_cs_by_name(const char *name); +void cet_register(void); +void cet_deregister(void); + +/* short hand transmissions */ + +char *cet_str_utf8_to_cp1252(const char *src); +char *cet_str_cp1252_to_utf8(const char *src); +extern cet_cs_vec_t cet_cs_vec_cp1252; + +char *cet_str_iso8859_1_to_utf8(const char *src); +char *cet_str_utf8_to_iso8859_1(const char *src); +extern cet_cs_vec_t cet_cs_vec_iso8859_1; + +char *cet_str_iso8859_15_to_utf8(const char *src); +char *cet_str_utf8_to_iso8859_15(const char *src); +extern const cet_cs_vec_t cet_cs_vec_iso8859_15; + +char *cet_str_utf8_to_us_ascii(const char *src); +char *cet_str_us_ascii_to_utf8(const char *src); +extern cet_cs_vec_t cet_cs_vec_ansi_x3_4_1968; + + +extern cet_cs_vec_t cet_cs_vec_utf8; + + +/* Missing defines in older expat libraries | CET-REVIEW */ + +/* Taken from expat_external.h (Expat 1.95.7) */ + +#ifndef XML_STATUS_OK +# define XML_STATUS_OK 1 +#endif +#ifndef XML_STATUS_ERROR +# define XML_STATUS_ERROR 0 +#endif + + +#ifndef XMLCALL +#if defined(XML_USE_MSC_EXTENSIONS) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + +#if HAVE_LIBEXPAT +int XMLCALL cet_lib_expat_UnknownEncodingHandler(void *data, const XML_Char *encoding, XML_Encoding *info); +#endif + +/* helpers */ + +char *cet_str_uni_to_any(const short *src, int length, const cet_cs_vec_t *dest_vec); +char *cet_str_any_to_any(const char *src, const cet_cs_vec_t *src_vec, const cet_cs_vec_t *dest_vec); +int cet_valid_char(const char *src, const cet_cs_vec_t *vec); + +int cet_gbfprintf(gbfile *stream, const cet_cs_vec_t *src_vec, const char *fmt, ...); + +/* cet_convert_string: !!! ONLY VALID WITHIN 'cet_convert_strings' process !!! */ +char *cet_convert_string(char *str); + +/* gpsbabel extensions */ + +void cet_convert_init(const char *cs_name, const int force); +void cet_convert_strings(const cet_cs_vec_t *source, const cet_cs_vec_t *target, const char *format); +void cet_convert_deinit(void); + +void cet_disp_character_set_names(FILE *fout); + +/* + * Conversion from XML_Char string to char string. If XML_Char is the + * same as char, these routines do nothing. If XML_Char is a wide + * character, xml_convert_to_char_string converts the string to a + * newly allocated char string, and xml_free_converted_string frees + * it. + */ + +const char *xml_convert_to_char_string_n(const XML_Char *str, int *nbytes); +const char *xml_convert_to_char_string(const XML_Char *str); +void xml_free_converted_string(const char *str); + +const char **xml_convert_attrs_to_char_string(const XML_Char **xml_attr); +void xml_free_converted_attrs(const char **attr); + +#endif diff --git a/cetus.c b/cetus.c new file mode 100644 index 000000000..138625966 --- /dev/null +++ b/cetus.c @@ -0,0 +1,634 @@ +/* + Read and write Cetus files. + + Copyright (C) 2002-2008 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +/* + + History: + + 2005/08/03: Added track_read by O.K. + (Thanx to Adam Schneider for additional information) + +*/ + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "pdbfile.h" + +#define MYNAME "Cetus" +#define MYTYPE_WPT 0x43577074 /* CWpt */ +#define MYTYPE_TRK 0x7374726d /* strm */ + +#define MYCREATOR 0x63475053 /* cGPS */ +#define MYTRACK 0x44424c4b /* DBLK */ + +#define NOTESZ 4096 +#define DESCSZ 4096 + +typedef enum { + WptEdit = 0, /* the position has been edited or it was */ + /* imported from another source */ + WptGPS2D = 1, /* retrieved from a GPS with a 2D fix */ + WptGPS3D = 2, /* retrieved from a GPS with a 3D fix */ + WptDGPS2D = 3, /* retrieved from a GPS with a 2D fix and DGPS signal */ + WptDGPS3D = 4, /* retrieved from a GPS with a 3D fix and DGPS signal */ + WptAverage = 5, /* averaging over 3D positions */ + WptCache = 50, /* this position is a geocache reference */ + WptGarmin = 70 /* this position was imported from a Garmin GPS */ + /* the icon field contains the garmin symbol number */ +} wpt_type; + +struct cetus_wpt_s { + char type; + + char readonly; + + pdb_32 latitude; /* Big endian, degrees*1e7, s=negative */ + pdb_32 longitude; /* same as lat; w=negative */ + pdb_32 elevation; /* Big endian, meters*100. blank=-1e8 */ + + pdb_16 year; /* sample time, UTC */ + unsigned char mon; + unsigned char day; + unsigned char hour; + unsigned char min; + unsigned char sec; + + /* accuracy and precision information for use where applicable */ + unsigned char sat; /* ff if averaged or unknown */ + pdb_16 pdop; /* pdop * 100 */ + pdb_16 hdop; + pdb_16 vdop; + pdb_16 dgpstime; + pdb_32 dgpsstn; + pdb_32 avgtime; + pdb_32 avgite; + + pdb_16 dopmask; + pdb_16 elevmask; + + pdb_16 radius; + pdb_32 distance; + + pdb_16 vyear; /* date visited */ + unsigned char vmon; + unsigned char vday; + unsigned char vhour; + unsigned char vmin; + unsigned char vsec; + + char flagged; + + pdb_32 icon; + pdb_16 category; +}; + +typedef struct cetus_track_head_s +{ + char id[2]; + char version; + unsigned char interval; + unsigned short gps; + char year; + char month; + char day; + char hour; + char min; + char sec; + char dsec; + char tz; + char desc; +} cetus_track_head_t; + +#define TRACK_HEAD_SIZE sizeof(struct cetus_track_head_s) + +typedef struct cetus_track_point_s +{ + char hour; + char min; + char sec; + char dsec; + char sat; + char hdop; + pdb_32 latitude; + pdb_32 longitude; + short speed; + short course; + pdb_32 elevation; +} cetus_track_point_t; + +#define TRACK_POINT_SIZE sizeof(struct cetus_track_point_s) + +static pdbfile *file_in, *file_out; +static const char *out_fname; +static short_handle mkshort_wr_handle; +static int ct; + +static char *dbname = NULL; +static char *appendicon = NULL; + +static +arglist_t cetus_args[] = { + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX }, + {"appendicon", &appendicon, "Append icon_descr to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static waypoint * +read_track_point(cetus_track_point_t *data, const time_t basetime) +{ + int i, ilat, ilon; + waypoint *wpt; + + ilat = be_read32(&data->latitude); + ilon = be_read32(&data->longitude); + + if (data->hour == -1 || data->min == -1 || data->sec == -1 || + ilat == 2000000000 || ilon == 2000000000) return NULL; /* At least one of basic data is not available */ + + wpt = waypt_new(); + + wpt->latitude = (double)ilat / 10000000.0; + wpt->longitude = (double)ilon / 10000000.0; + + i = be_read32(&data->elevation); + wpt->altitude = (i == -100000000) ? unknown_alt : (double) i / 100.0; + + if (data->sat != -1) wpt->sat = data->sat; + if (data->hdop != -1) wpt->hdop = (float) data->hdop / 10; + + i = be_read16(&data->speed); + if (i != 10000) WAYPT_SET(wpt, speed, KNOTS_TO_MPS((float) i / 10)); /* meters/second */ + i = be_read16(&data->course); + if (i != 4000) WAYPT_SET(wpt, course, (float) i / 10); + + switch(data->hour >> 5) /* extract fix */ + { + case 1: wpt->fix = fix_none; break; + case 2: wpt->fix = fix_2d; break; + case 3: wpt->fix = fix_3d; break; + case 4: wpt->fix = fix_dgps; break; + default: break; /* no GPS */ + } + + wpt->creation_time = basetime + + ((data->hour & 0x1F) * 3600) + (data->min * 60) + data->sec; + if (data->dsec) + wpt->microseconds = (int)data->dsec * 10000; + + return wpt; +} + + +static void +read_tracks(const pdbfile *pdb) +{ + pdbrec_t *pdb_rec; + int reclen, records, total, points, dropped; + char descr[(2 * TRACK_POINT_SIZE) + 1]; + char temp_descr[TRACK_POINT_SIZE + 1]; + cetus_track_head_t *head; + waypoint *wpt; + route_head *track; + time_t basetime; + + track = route_head_alloc(); + track_add_head(track); + + total = 0; + points = 0; + dropped = 0; + basetime = 0; + + for (pdb_rec = pdb->rec_list; pdb_rec; pdb_rec = pdb_rec->next) + { + int i, magic; + char *c = (char *)pdb_rec->data; + + magic = be_read32(c); + if (magic != MYTRACK) + fatal(MYNAME ": Invaid track data or unsupported version!\n"); + + reclen = be_read32(c+4); + records = reclen / TRACK_POINT_SIZE; + + c += 8; + + for (i = 0; i < records; i++, c += TRACK_POINT_SIZE) + { + switch(total++) + { + struct tm tm; + + case 0: /* track header */ + head = (cetus_track_head_t *)c; + if (head->id[0] != 'C' || head->id[1] != 'G') + fatal(MYNAME ": Invalid track header!\n"); + + memset(&tm, 0, sizeof(tm)); + tm.tm_mday = head->day; + tm.tm_mon = head->month - 1; + tm.tm_year = head->year + 100; + basetime = mkgmtime(&tm); + break; + + case 1: /* first part of description */ + strncpy(descr, c, TRACK_POINT_SIZE); + break; + + case 2: /* continued description */ + strncpy(temp_descr, c, TRACK_POINT_SIZE); + strcat(descr, temp_descr); /* here is no need to check target size */ + if (strlen(descr) > 0) + track->rte_desc = xstrdup(descr); + break; + + default: + wpt = read_track_point((cetus_track_point_t *)c, basetime); + if (wpt != NULL) + { + track_add_wpt(track, wpt); + points++; + } + else + dropped++; + } + + } + } + + if (global_opts.verbose_status > 0) + { + printf(MYNAME ": Loaded %d track point(s) from source.\n", points); + if (dropped > 0) + printf(MYNAME ": ! %d dropped because of missing data (no time, no coordinates) !\n", dropped); + } +} + +static void +read_waypts(const pdbfile *pdb) +{ + struct cetus_wpt_s *rec; + pdbrec_t *pdb_rec; + char *vdata; + + for(pdb_rec = pdb->rec_list; pdb_rec; pdb_rec = pdb_rec->next) + { + waypoint *wpt_tmp; + int i; + + wpt_tmp = waypt_new(); + + rec = (struct cetus_wpt_s *) pdb_rec->data; + if ( be_read32(&rec->elevation) == -100000000 ) { + wpt_tmp->altitude = unknown_alt; + } + else { + wpt_tmp->altitude = be_read32(&rec->elevation) / 100.0; + } + + wpt_tmp->latitude = be_read32(&rec->latitude) / 10000000.0; + wpt_tmp->longitude = be_read32(&rec->longitude) / 10000000.0; + + if (rec->sat != 0xff) + wpt_tmp->sat = rec->sat; + + i = be_read16(&rec->pdop); + if (i != 0xffff) wpt_tmp->pdop = i / 100.0; + i = be_read16(&rec->hdop); + if (i != 0xffff) wpt_tmp->hdop = i / 100.0; + i = be_read16(&rec->vdop); + if (i != 0xffff) wpt_tmp->vdop = i / 100.0; + + switch (rec->type) { + case WptGPS2D: wpt_tmp->fix = fix_2d; break; + case WptGPS3D: wpt_tmp->fix = fix_3d; break; + case WptDGPS2D: wpt_tmp->fix = fix_dgps; break; + case WptDGPS3D: wpt_tmp->fix = fix_dgps; break; + } + + if (be_read16(&rec->year) != 0xff) { + struct tm tm; + + memset (&tm, 0, sizeof(tm)); + tm.tm_min = rec->min; + tm.tm_hour = rec->hour; + tm.tm_mday = rec->day; + tm.tm_mon = rec->mon - 1; + tm.tm_year = be_read16(&rec->year) - 1900; + + wpt_tmp->creation_time = mkgmtime(&tm); + + } + + vdata = (char *) pdb_rec->data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + waypt_add(wpt_tmp); + + } +} + +/* --------------------------------------------------------------------------- */ + +static void +rd_init(const char *fname) +{ + file_in = pdb_open(fname, MYNAME); +} + +static void +rd_deinit(void) +{ + pdb_close(file_in); + if ( dbname ) { + xfree(dbname); + dbname = NULL; + } +} + +static void +wr_init(const char *fname) +{ + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; +} + +static void +wr_deinit(void) +{ + pdb_close(file_out); + if ( dbname ) { + xfree(dbname); + dbname = NULL; + } +} + +static void +data_read(void) +{ + if (file_in->creator != MYCREATOR) fatal(MYNAME ": Not a Cetus file.\n"); + + switch(file_in->type) + { + case MYTYPE_TRK: + read_tracks(file_in); + break; + + case MYTYPE_WPT: + read_waypts(file_in); + break; + } +} + + +static void +cetus_writewpt(const waypoint *wpt) +{ + struct cetus_wpt_s *rec; + struct tm *tm; + char *vdata; + char *desc_long; + char *desc_short; + char *desc_geo; + char *desc; + + rec = xcalloc(sizeof(*rec)+18 + NOTESZ + DESCSZ,1); + + if (wpt->creation_time && (NULL != (tm = gmtime(&wpt->creation_time)))){ + rec->min = tm->tm_min; + rec->hour = tm->tm_hour; + rec->sec = tm->tm_sec; + rec->day = tm->tm_mday; + rec->mon = tm->tm_mon + 1; + be_write16( &rec->year, tm->tm_year + 1900); + } else { + rec->min = 0xff; + rec->hour = 0xff; + rec->sec = 0xff; + rec->day = 0xff; + rec->mon = 0xff; + be_write16(&rec->year, 0xff); + } + be_write32(&rec->longitude, (unsigned int) (int) (wpt->longitude * 10000000.0)); + be_write32(&rec->latitude, (unsigned int) (wpt->latitude * 10000000.0)); + if ( wpt->altitude == unknown_alt ) { + be_write32(&rec->elevation, -100000000); + } + else { + be_write32(&rec->elevation, (unsigned int) (wpt->altitude * 100.0)); + } + + be_write16( &rec->pdop, wpt->pdop ? wpt->pdop * 100 : 0xffff ); + be_write16( &rec->hdop, wpt->hdop ? wpt->hdop * 100 : 0xffff ); + be_write16( &rec->vdop, wpt->vdop ? wpt->vdop * 100 : 0xffff ); + be_write16( &rec->dgpstime, 0xffff ); + be_write32( &rec->distance, 0xffffffff ); + + rec->vmin = 0xff; + rec->vhour = 0xff; + rec->vsec = 0xff; + rec->vday = 0xff; + rec->vmon = 0xff; + be_write16(&rec->vyear, 0xff); + + rec->sat = wpt->sat ? wpt->sat : 0xff; + + vdata = (char *)rec + sizeof(*rec); + if ( wpt->shortname ) { + char *sn = xstrdup(wpt->shortname); + strncpy( vdata, sn, 16 ); + vdata[15] = '\0'; + xfree(sn); + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + + if (wpt->gc_data.diff) { + xasprintf(&desc_geo, "%s%s by %s\n%.4s/%.4s %3.1f/%3.1f\n", + wpt->gc_data.is_available==status_true ? + "" : " (Disabled)", + wpt->gc_data.is_archived==status_true ? + " (Archived)" : "", + wpt->gc_data.placer, + gs_get_cachetype(wpt->gc_data.type), + gs_get_container(wpt->gc_data.container), + wpt->gc_data.diff/10.0, + wpt->gc_data.terr/10.0); + } else { + desc_geo = xstrdup(""); + } + + if (wpt->gc_data.desc_short.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data.desc_short); + desc_short = xstrdup(wpt->gc_data.diff == 0 ? "\n\n" : ""); + desc_short = xstrappend(desc_short, xstrdup(stripped_html)); + xfree(stripped_html); + } else { + desc_short = xstrdup(""); + } + + if (wpt->gc_data.desc_long.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data.desc_long); + desc_long = xstrdup("\n\n"); + desc_long = xstrappend(desc_long, xstrdup(stripped_html)); + xfree(stripped_html); + } else { + desc_long = xstrdup(""); + } + + desc = wpt->description ? xstrdup(wpt->description) : + xstrdup(""); + + snprintf(vdata, DESCSZ, "%s%s%s%s", + desc, + desc_geo, + desc_short, + desc_long); + + xfree(desc); + xfree(desc_geo); + xfree(desc_short); + xfree(desc_long); + + if (appendicon && wpt->icon_descr) { + int left = DESCSZ - strlen( vdata ); + int ilen = strlen( wpt->icon_descr ); + if (ilen && left > (ilen+3)) { + strcat( vdata, " (" ); + strcat( vdata, wpt->icon_descr ); + strcat( vdata, ")" ); + } + } + vdata += strlen( vdata ) + 1; + + if (wpt->gc_data.hint) { + char *hint = xstrdup(wpt->gc_data.hint); + rec->type = WptCache; + strncpy( vdata, hint, NOTESZ + 1 ) ; + xfree(hint); + vdata[NOTESZ] = '\0'; + } else { + rec->type = WptEdit; + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + + pdb_write_rec(file_out, 0, 2, ct++, rec, (char *)vdata - (char *)rec); + + xfree(rec); +} + +struct hdr{ + char *wpt_name; + waypoint *wpt; +}; + +static +int +compare(const void *a, const void *b) +{ + const struct hdr *wa = a; + const struct hdr *wb = b; + + return strcmp(wa->wpt->shortname, wb->wpt->shortname); +} + +static void +data_write(void) +{ + int i, ct = waypt_count(); + struct hdr *htable, *bh; + queue *elem, *tmp; + extern queue waypt_head; + waypoint *waypointp; + mkshort_wr_handle = mkshort_new_handle(); + setshort_length(mkshort_wr_handle, 15); + setshort_whitespace_ok(mkshort_wr_handle, 0); + + if ( dbname ) { + strncpy( file_out->name, dbname, PDB_DBNAMELEN ); + } + else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE_WPT; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + + /* + * All this is to sort by waypoint names before going to Cetus. + * Turns out plain old strcmp will do the trick... + */ + + htable = xmalloc(ct * sizeof(*htable)); + bh = htable; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + bh->wpt = waypointp; + if (global_opts.synthesize_shortnames && waypointp->description) { + if (waypointp->shortname) + xfree(waypointp->shortname); + waypointp->shortname = mkshort_from_wpt(mkshort_wr_handle, waypointp); + } + bh->wpt_name = waypointp->shortname; + bh ++; + } + qsort(htable, ct, sizeof(*bh), compare); + + for (i=0;i + static XML_Parser psr; +#endif + +#include +#include "cet_util.h" + +#include "uuid.h" + +static gbfile *fd, *ofd; + +#define MYNAME "coastexp" +#define MY_CBUF 4096 +#define MY_UBUF 128 +#define MY_TBUF 64 +#define MY_XBUF 128 + + +static char *element; // Current element being parsed +static char *cdatastr; // Current XML character data being built up (until a ) + +/* CE-specific mark structure - used for both route marks and standalone marks */ +struct CE_MARK { + queue Q; + char *id; // CE's mark ID (of the form "{}") + char *created; // CE's creation time (of the form "
TZ") + waypoint *wp; // GPSBabel waypoint + int used; // Is this mark used in a route or not? +}; +typedef struct CE_MARK ce_mark; + +/* CE-specific route structure */ +struct CE_ROUTE { + queue Q; + char *id; // CE's route ID (of the form "{}") + route_head *r; // GPSBabel route header + queue ce_mark_head; // list of CE marks in this route +}; +typedef struct CE_ROUTE ce_route; + +static queue ce_route_head; // List of routes currently found +static ce_route *currentRoute = NULL; // Current route being processed +static queue ce_mark_head; // List of stand-alone marks currently found +static ce_mark *currentMark = NULL; // Current mark being processed +static char *time_buffer = NULL; // Time buffer for processing times +static char *uuid_buffer = NULL; // UUID buffer for processing uuid's +static char *xml_buffer = NULL; // XML buffer for processing XML strings +static int inRoute = 0; // Are we processing a route? +static int inMark = 0; // Are we processing a mark? + +/* Add a route to the list of routes */ +static void +ce_add_route(ce_route *route) +{ + ENQUEUE_TAIL(&ce_route_head, &route->Q); +} + +/* Add a mark to the list of stand-alone marks */ +static void +ce_add_mark(ce_mark *mark) +{ + ENQUEUE_TAIL(&ce_mark_head, &mark->Q); +} + +/* Add a mark to the specified route */ +static void +ce_add_mark_to_route(ce_route *route, ce_mark *mark) +{ + ENQUEUE_TAIL(&route->ce_mark_head, &mark->Q); +} + +/* Free a mark */ +static void +ce_free_mark(ce_mark *mark) +{ + dequeue(&mark->Q); + if (mark->id) + xfree(mark->id); + if (mark->created) + xfree(mark->created); + xfree(mark); +} + +/* Free a route */ +static void +ce_free_route(ce_route *route) +{ + queue *elem, *tmp; + QUEUE_FOR_EACH(&route->ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + ce_free_mark(mark); + } + xfree(route->id); + xfree(route); + // Don't free the waypoint since this is done elsewhere +} + +/* Allocate a mark */ +static ce_mark * +ce_alloc_mark(const waypoint *wpt, const char *id) +{ + ce_mark *res = xcalloc(sizeof(ce_mark), 1); + res->id = (char *) id; + res->wp = (waypoint *) wpt; + return res; +} + +#if !HAVE_LIBEXPAT +void +ce_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded CoastalExplorer support because expat was not installed.\n"); +} + +void +ce_read(void) +{ +} +#else + +/* Start processing an XML item */ +static void +ce_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) +{ + const char *el = xml_convert_to_char_string(xml_el); + const char **ap; + const char **attr; + + attr = xml_convert_attrs_to_char_string(xml_attr); + strcpy(element, el); + if (0 == strcmp(el, "Route")) { + inRoute = 1; + for (ap = attr; *ap; ap+=2) { + if (0 == strcmp(ap[0], "id")) { + // Create a CE route object and add it to the list of routes + currentRoute = (ce_route *) xcalloc(sizeof (ce_route), 1); + currentRoute->id=xstrdup(ap[1]); + currentRoute->r = route_head_alloc(); + QUEUE_INIT(¤tRoute->ce_mark_head); + ce_add_route(currentRoute); + } + } + } else if (0 == strcmp(el, "Mark")) { + inMark = 1; + currentMark = ce_alloc_mark(NULL, NULL); + ce_add_mark(currentMark); + for (ap = attr; *ap; ap+=2) { + if (0 == strcmp(ap[0], "id")) { + // Create a CE mark object and add it to the list of stand-alone marks + currentMark->id = xstrdup(ap[1]); + } + else if (0 == strcmp(ap[0], "created")) { + currentMark->created = xstrdup(ap[1]); + } + } + } + xml_free_converted_string(el); + xml_free_converted_attrs(attr); +} + +/* Finish processing an XML item */ +static void +ce_end(void *data, const XML_Char *xml_el) +{ + const char *el = xml_convert_to_char_string(xml_el); + if (0 == strcmp(el, "Route")) { + inRoute = 0; /* ??? */ + } + else if (0 == strcmp(el, "Mark")) + inMark = 0; + xml_free_converted_string(el); +} + +/* Process some XML character data for the current item */ +static void +ce_cdata(void *dta, const XML_Char *xml_s, int len) +{ + const char *origs = xml_convert_to_char_string_n(xml_s, &len); + const char *s = origs; + if (*s != '\n') { + char *edatastr; + // We buffer up characters in 'cdatastr' until a single is received + if ((strlen(cdatastr) + len) > MY_CBUF) { + printf("Buffer overflow - line too long!"); + exit(-1); + } + edatastr = cdatastr+strlen(cdatastr); + memcpy(edatastr, s, len); + edatastr[len] = '\0'; + } else { + // Now process what we have in 'cdatastr' + s = cdatastr; + while (*s != '\0' && (*s == '\b' || *s == '\t')) + s++; + if (strlen(s) <= 0) + return; + if (0 == strcmp(element, "Marks")) { + if (inRoute) { + // We are processing the marks in a route so create a CE mark object + // and add it to the current route + ce_mark *mark = (ce_mark *) ce_alloc_mark(NULL, xstrdup(s)); + ce_add_mark_to_route(currentRoute, mark); + } + } else if (0 == strcmp(element, "Position")) { + if (inMark) { + // We are processing a standalone mark so read the lat/long position + // and create a waypoint to add to the current mark + char *position = xstrdup(s); + char *lat = position; + char *latNorS = position; + char *lng; + char *longEorW; + while (*latNorS != ' ') + latNorS++; + *latNorS++ = '\0'; + lng = latNorS; + lng++; lng++; + longEorW = lng; + while (*longEorW != ' ') + longEorW++; + *longEorW++ = '\0'; + if (!currentMark->wp) + currentMark->wp = waypt_new(); + currentMark->wp->latitude = atof(lat); + if (*latNorS == 'S') + currentMark->wp->latitude = -currentMark->wp->latitude; + currentMark->wp->longitude = atof(lng); + if (*longEorW == 'W') + currentMark->wp->longitude = -currentMark->wp->longitude; + xfree(position); + } + } else if (0 == strcmp(element, "Name")) { + // Names we care about may be either for routes or marks + if (inMark) + { + if (!currentMark->wp) + currentMark->wp = waypt_new(); + currentMark->wp->shortname = xstrdup(s); + + // Also set the creation time + if (currentMark->created) + { + struct tm t; + char yearString[5], monthString[3], dayString[3], hourString[3], minString[3], secString[3]; + memset(&t, 0, sizeof(struct tm)); + strncpy(yearString, currentMark->created, 4); + yearString[4] = '\0'; + t.tm_year = atoi(yearString) - 1900; + strncpy(monthString, currentMark->created+4, 2); + monthString[2] = '\0'; + t.tm_mon = atoi(monthString) - 1; + strncpy(dayString, currentMark->created+6, 2); + dayString[2] = '\0'; + t.tm_mday = atoi(dayString); + strncpy(hourString, currentMark->created+9, 2); + hourString[2] = '\0'; + t.tm_hour = atoi(hourString); + strncpy(minString, currentMark->created+11, 2); + minString[2] = '\0'; + t.tm_min = atoi(minString); + strncpy(secString, currentMark->created+13, 2); + secString[2] = '\0'; + t.tm_sec = atoi(secString); + currentMark->wp->creation_time = mkgmtime(&t); + } + } + else if (inRoute) { + currentRoute->r->rte_name = xstrdup(s); + } + } else if (0 == strcmp(element, "Description")) { + // Descriptions we care about may be either for routes or marks + char *desc = xstrdup(s); + if (inMark) + { + if (!currentMark->wp) + currentMark->wp = waypt_new(); + currentMark->wp->description = desc; + } + else if (inRoute) + currentRoute->r->rte_desc = desc; + } + + // Start building a new string since we are done with this one + cdatastr[0] = '\0'; + } + + xml_free_converted_string(origs); +} + +/* Set up reading the CE input file */ +void +ce_rd_init(const char *fname) +{ + fd = gbfopen(fname, "r", MYNAME); + QUEUE_INIT(&ce_route_head); + QUEUE_INIT(&ce_mark_head); + + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ":Cannot create XML parser\n"); + } + + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, ce_start, ce_end); + cdatastr = xcalloc(MY_CBUF,1); + element = xcalloc(MY_CBUF,1); + XML_SetCharacterDataHandler(psr, ce_cdata); +} + +/* Parse the input file */ +void +ce_read(void) +{ + int len; + char buf[MY_CBUF + 1]; + + while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) { + buf[len] = '\0'; + if (!XML_Parse(psr, buf, len, gbfeof(fd))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + + XML_ParserFree(psr); +} + +#endif + +/* Fix waypoints in route marks from the standalone marks */ +void +ce_fix_route_mark_waypoints(void) +{ + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route *route = (ce_route *) elem; + queue *elem2, *tmp2; + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark *mark = (ce_mark *) elem2; + queue *elem3, *tmp3; + QUEUE_FOR_EACH(&ce_mark_head, elem3, tmp3) { + ce_mark *mark2 = (ce_mark *) elem3; + if (0 == strcmp(mark->id, mark2->id)) { + mark->wp = waypt_dupe(mark2->wp); + mark2->used = 1; + break; + } + } + } + } +} + +/* Check route name and if NULL assign a name */ +void +ce_check_route_names(void) +{ + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route *route = (ce_route *) elem; + if (route->r->rte_name == NULL) { + *cdatastr = '\0'; + strcat(cdatastr, ((ce_mark *) QUEUE_FIRST(&route->ce_mark_head))->wp->shortname); + strcat(cdatastr, "->"); + strcat(cdatastr, ((ce_mark *) QUEUE_LAST(&route->ce_mark_head))->wp->shortname); + route->r->rte_name = xstrdup(cdatastr); + } + } +} + +/* Remove marks used in routes */ +void +ce_remove_used_marks(void) +{ + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + if (mark->used) + { + if (mark->wp) + waypt_free(mark->wp); + ce_free_mark(mark); + } + } +} + +/* Print out results */ +void +ce_print_results(void) +{ + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + queue *elem2, *tmp2; + ce_route *route = (ce_route *) elem; + printf("Route name=%s id=%s\n", route->r->rte_name, route->id); + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark *mark = (ce_mark *) elem2; + if (mark->wp == NULL) + printf(" null\n"); + else + printf(" %s (%f, %f)\n", mark->wp->shortname, mark->wp->latitude, mark->wp->longitude); + } + } + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + printf("Mark name=%s id=%s ", mark->wp->shortname, mark->id); + if (mark->wp == NULL) + printf("(null)\n"); + else + printf("(%f, %f)\n", mark->wp->latitude, mark->wp->longitude); + } +} + +/* Finish reading the input file */ +void +ce_rd_deinit(void) +{ + /* If doing routes, we create GPSBabel route structures and waypoint structures for + any standalone waypoints. + If doing waypoints, we create only waypoint structures for both route waypoints and + standalone waypoints. + */ + queue *elem, *tmp; + + ce_fix_route_mark_waypoints(); + ce_check_route_names(); + ce_remove_used_marks(); + + // Log results + if (global_opts.debug_level > 1) + ce_print_results(); + + // Add routes to GPSBabel + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route *route = (ce_route *) elem; + queue *elem2, *tmp2; + route_add_head(route->r); + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark *mark = (ce_mark *) elem2; + if (mark->wp) + route_add_wpt(route->r, mark->wp); + else + printf("Undefined mark: %s\n", mark->id); + } + ce_free_route(route); + } + + // Add (unused) marks to GPSBabel + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + waypt_add(mark->wp); + ce_free_mark(mark); + } + + gbfclose(fd); + xfree(element); + xfree(cdatastr); +} + +/* Setup for writing */ +void +ce_wr_init(const char *fname) +{ + QUEUE_INIT(&ce_mark_head); + + // Alloocate all buffers used for writing + time_buffer = xcalloc(MY_TBUF,1); + uuid_buffer = xcalloc(MY_UBUF,1); + xml_buffer = xcalloc(MY_XBUF, 1); + + ofd = gbfopen(fname, "w", MYNAME); + srand(gpsbabel_now); +} + +void +ce_wr_deinit(void) +{ + gbfclose(ofd); + + // Free the buffers used for writing + xfree(time_buffer); + xfree(uuid_buffer); + xfree(xml_buffer); +} + +/* Generate a CE-style creation time based on supplied time */ +static char * +ce_gen_creation_time(time_t tm) +{ + xml_fill_in_time(time_buffer, tm, 0, XML_SHORT_TIME); + return time_buffer; +} + +/* Generate a CE-style creation time based on current time */ +static char * +ce_gen_current_time(void) +{ + return ce_gen_creation_time(current_time()); +} + +/* Generate a UUID (has same format as Microsoft registry GUIDs */ +static char * +ce_gen_uuid(void) +{ + uuid_t uu; + + memset(&uu, 0, sizeof(uu)); + gb_uuid_generate(uu); + sprintf(uuid_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7], + uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]); + return uuid_buffer; +} + +/* Generate route header XML */ +static void +ce_route_hdr(const route_head *rte) +{ + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + write_xml_entity_begin2(ofd, "\t", "Route", "created", ce_gen_current_time(), "id", xml_buffer); + write_xml_entity_begin0(ofd, "\t\t", "Marks"); +} + +/* Generate route body XML */ +static void +ce_route_disp(const waypoint *waypointp) +{ + char *uuid = ce_gen_uuid(); + char *id = xcalloc(strlen(uuid)+3, 1); + + sprintf(id, "{%s}", uuid); + currentMark = ce_alloc_mark(waypointp, id); + ENQUEUE_TAIL(&ce_mark_head, ¤tMark->Q); + + gbfprintf(ofd, "\t\t\t%s\n", id); // CE's departure from XML standard! +} + +/* Generate route trailer XML */ +static void +ce_route_tlr(const route_head *rte) +{ + write_xml_entity_end(ofd, "\t\t", "Marks"); + write_optional_xml_entity(ofd, "\t\t", "Name", rte->rte_name); + write_xml_entity_end(ofd, "\t", "Route"); +} + +/* Generate waypoint body XML */ +static void +ce_waypt_pr(const waypoint *wp) +{ + double latitude = wp->latitude; + char NorS = 'N'; + char EorW = 'E'; + double longitude = wp->longitude; + + if (latitude < 0) { + latitude = -latitude; + NorS = 'S'; + } + if (longitude < 0) { + longitude = -longitude; + EorW = 'W'; + } + sprintf(xml_buffer, "%3.6f %c %3.6f %c", latitude, NorS, longitude, EorW); + write_xml_entity(ofd, "\t\t", "Position", xml_buffer); + write_optional_xml_entity(ofd, "\t\t", "Name", wp->shortname); +} + +static char * +ce_find_uuid(const waypoint *wpt) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + if (mark->wp == wpt) { + return mark->id; + } + } + return NULL; +} + +static waypoint * +ce_find_wpt(const waypoint *wpt) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + if ((mark->wp->shortname == wpt->shortname) && + (mark->wp->latitude == wpt->latitude) && + (mark->wp->longitude == wpt->longitude)) + return mark->wp; + } + return NULL; +} + +/* Generate a mark XML; look for created id's */ +static void +ce_mark_pr(const waypoint *wp) +{ + char *id; + + if (inRoute) { + id = ce_find_uuid(wp); + if (id == NULL) { + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + id = xml_buffer; + } + } + /* Have we seen and written the (nearly) same waypoint ? */ + else if (ce_find_wpt(wp) != NULL) return; + else { + ce_mark *mark = ce_alloc_mark(wp, NULL); + ENQUEUE_TAIL(&ce_mark_head, &mark->Q); + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + id = xml_buffer; + } + write_xml_entity_begin2(ofd, "\t", "Mark", + "created", ce_gen_creation_time(wp->creation_time), + "id", id); + ce_waypt_pr(wp); + write_xml_entity_end(ofd, "\t", "Mark"); +} + +/* Generate all route marks */ +static void +ce_marks_pr(void) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + ce_mark_pr(mark->wp); + } +} + +/* Release all generated marks */ +static void +ce_marks_flush_all(void) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + ce_free_mark(mark); + } +} + +/* Write all routes and marks */ +void +ce_write(void) +{ + /* If doing routes, we write out the routes and all the standalone waypoints. + If doing waypoints, we write out the route waypoints (without the routes) and + the standalone waypoints. + */ + time_t now = 0; + now = current_time(); + + write_xml_header(ofd); + write_xml_entity_begin1(ofd, "", "NavObjectCollection", "created", + ce_gen_current_time()); + write_xml_entity(ofd, "\t", "Name", "Navigation Objects"); + + inRoute = 1; + route_disp_all(ce_route_hdr, ce_route_tlr, ce_route_disp); + ce_marks_pr(); + inRoute = 0; + + waypt_disp_all(ce_mark_pr); + ce_marks_flush_all(); + + write_xml_entity_end(ofd, "", "NavObjectCollection"); +} + +ff_vecs_t coastexp_vecs = { + ff_type_file, + { ff_cap_read|ff_cap_write, ff_cap_none, ff_cap_read|ff_cap_write }, + ce_rd_init, + ce_wr_init, + ce_rd_deinit, + ce_wr_deinit, + ce_read, + ce_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/compegps.c b/compegps.c new file mode 100644 index 000000000..a47400d8c --- /dev/null +++ b/compegps.c @@ -0,0 +1,658 @@ +/* + + Support for CompeGPS waypoint (.wpt), route (.rte) and track (.trk) files, + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +/* + History: + 10/23/2005: First release; only a reader + 10/25/2005: becomes a writer too + 10/26/2005: received documention from CompeGPS team + added fatals for "G" and "U" if not WGS84 and lat/lon + 08/13/2006: switch to gbfile api +*/ + +/* + + the meaning of leading characters in CompeGPS data lines (enhanced PCX): + + header lines: + + "G": WGS 84 - Datum of the map + "N": Anybody - Name of the user + "L": -02:00:00 - Difference to UTC + "M": ... - Any comments + "R": 16711680 , xxxx , 1 - Route header + "U": 1 - System of coordinates (0=UTM 1=Latitude/Longitude) + + "C": 0 0 255 2 -1.000000 - ??? + "V": 0.0 0.0 0 0 0 0 0.0 - ??? + "E": 0|1|00-NUL-00 00:00:00|00:00:00|0 - ??? + + data lines: + + "W": if(route) routepoint; else waypoint + "T": trackpoint + "t": if(track) additionally track info + if(!track) additionally trackpoint info + "a": link to ... + "w": waypoint additional info + +*/ + +#include "defs.h" +#include "csv_util.h" + +#if CSVFMTS_ENABLED +#include +#include +#include +#include +#include +#include "jeeps/gpsmath.h" + +#define MYNAME "CompeGPS" + +#define SHORT_NAME_LENGTH 16 + +static gbfile *fin, *fout; +static int target_index, curr_index; +static int track_info_flag; +static short_handle sh; +static int snlen; +static int radius; +static int input_datum; + +static route_head *curr_track; +static route_head *curr_route; + +/* placeholders for options */ + +static char *option_icon; +static char *option_index; +static char *option_radius; +static char *option_snlen; + +static +arglist_t compegps_args[] = { + {"deficon", &option_icon, "Default icon name", + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"index", &option_index, "Index of route/track to write (if more the one in source)", + NULL, ARGTYPE_INT, "1", NULL}, + {"radius", &option_radius, "Give points (waypoints/route points) a default radius (proximity)", + NULL, ARGTYPE_FLOAT, "0", NULL}, + {"snlen", &option_snlen, "Length of generated shortnames (default 16)", + "16", ARGTYPE_INT, "1", NULL}, + ARG_TERMINATOR +}; + +static +void fix_datum(double *lat, double *lon) +{ + double amt; + + /* + * Avoid FP jitter in the common case. + */ + if (input_datum != DATUM_WGS84) { + GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, lat, lon, + &amt, input_datum); + } +} + +/* specialized readers */ + +static waypoint* +parse_wpt(char *buff) +{ + int col = -1; + char *c, *cx; + waypoint *wpt = waypt_new(); + + c = strstr(buff, "A "); + if (c == buff) col++; + + c = csv_lineparse(buff, " ", "", col++); + while (c != NULL) + { + c = lrtrim(c); + if (*c != '\0') + { +#if 0 + printf(MYNAME "_read_wpt: col(%d)=%s\n", col, c); +#endif + switch(col) + { + case 0: + + cx = c + strlen(c) - 1; /* trim trailing underscores */ + while ((cx >= c) && (*cx == '_')) *cx-- = '\0'; + if (*c != '\0') + wpt->shortname = xstrdup(c); + break; + case 2: + human_to_dec(c, &wpt->latitude, NULL, 1); + break; + case 3: + human_to_dec(c, NULL, &wpt->longitude, 2); + break; + case 4: break; /* Unused date and time */ + case 5: break; /* always "27-MAR-62 00:00:00" */ + case 6: + wpt->altitude = atof(c); + break; + case 7: + wpt->description = xstrdup(c); + break; + default: + if (col > 7) + { + wpt->description = xstrappend(wpt->description, " "); + wpt->description = xstrappend(wpt->description, c); + } + } + } + c = csv_lineparse(NULL, " ", "", col++); + } + fix_datum(&wpt->latitude, &wpt->longitude); + return wpt; +} + +static void +parse_wpt_info(const char *buff, waypoint *wpt) /* "w" */ +{ + char *c; + int col = -1; + double fx; + + c = csv_lineparse(buff, ",", "", col++); + while (c != NULL) + { + c = lrtrim(c); + if (*c != '\0') + { +#if 0 + printf(MYNAME "_read_wpt_info: col(%d)=%s\n", col, c); +#endif + switch(col) + { + case 0: + wpt->icon_descr = xstrdup(c); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + break; + case 1: break; /* Text postion */ + case 2: break; /* Lens zoom level */ + case 3: break; /* Text colour */ + case 4: break; /* Background colour */ + case 5: break; /* Transparent text  (0=transparent, 1=no transparent) */ + case 6: break; /* ??? */ + case 7: break; /* ??? */ + case 8: /* radius */ + fx = atof(c); + if (fx > 0) WAYPT_SET(wpt, proximity, fx); + break; + } + } + c = csv_lineparse(NULL, ",", "", col++); + } +} + +static waypoint * +parse_trkpt(char *buff) +{ + int col = -1; + char *c; + struct tm tm; + char month[4]; + waypoint *wpt = waypt_new(); + + c = strstr(buff, "A "); + if (c == buff) col++; + + memset(&tm, 0, sizeof(tm)); + c = csv_lineparse(buff, " ", "", col++); + while (c != NULL) + { + c = lrtrim(c); + if (*c != '\0') + { +#if 0 + printf(MYNAME "_read_trkpt: col(%d)=%s\n", col, c); +#endif + switch(col) + { + case 2: + human_to_dec(c, &wpt->latitude, NULL, 1); + break; + case 3: + human_to_dec(c, NULL, &wpt->longitude, 2); + break; + case 4: + tm.tm_mday = atoi(c); + strncpy(month, c+3, 3); + month[3] = 0; + tm.tm_mon = month_lookup(month); + tm.tm_year = atoi(c + 7); + if (tm.tm_year < 70) tm.tm_year += 100; + break; + case 5: + tm.tm_hour = atoi(c); + tm.tm_min = atoi(c+3); + tm.tm_sec = atoi(c+6); + wpt->creation_time = mkgmtime(&tm); + break; + case 7: + wpt->altitude = atof(c); + break; + } + } + c = csv_lineparse(NULL, " ", "", col++); + } + fix_datum(&wpt->latitude, &wpt->longitude); + return wpt; +} + +static void +parse_track_info(const char *buff, route_head *track) /* "t" */ +{ + char *c; + int col = -1; + + c = csv_lineparse(buff, "|", "", col++); + while (c != NULL) + { + c = lrtrim(c); + if (*c != '\0') + { +#if 0 + printf(MYNAME "_read_track_info: col(%d)=%s\n", col, c); +#endif + switch(col) + { + case 0: + break; /* unknown field */ + case 1: + track->rte_name = xstrdup(c); + break; + case 2: + break; /* unknown field */ + case 3: + break; /* unknown field */ + } + } + c = csv_lineparse(NULL, "|", "", col++); + } +} + +static void +parse_rte_info(const char *buff, route_head *route) /* "R" */ +{ + char *c; + int col = -1; + + c = csv_lineparse(buff, ",", "", col++); + while (c != NULL) + { + c = lrtrim(c); + if (*c != '\0') + { +#if 0 + printf(MYNAME "_read_rte_info: col(%d)=%s\n", col, c); +#endif + switch(col) + { + case 0: break; /* unknown field (colour?) */ + case 1: + route->rte_name = xstrdup(c); + break; + case 2: break; /* unknown field */ + + } + } + c = csv_lineparse(NULL, ",", "", col++); + } +} + +/* main functions */ + +static void +compegps_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); + input_datum = DATUM_WGS84; +} + +static void +compegps_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +compegps_data_read(void) +{ + char *buff; + int line = 0; + int input_datum; + waypoint *wpt = NULL; + route_head *route = NULL; + route_head *track = NULL; + + while ((buff = gbfgetstr(fin))) + { + char *cin = buff; + char *ctail; + + line++; + cin = lrtrim(buff); + if (strlen(cin) == 0) continue; + + ctail = strchr(cin, ' '); + if (ctail == NULL) continue; + ctail = lrtrim(ctail); + + switch(*cin) + { + case 'G': + input_datum = GPS_Lookup_Datum_Index(ctail); + if (input_datum < 0) { + fatal( MYNAME ": Unsupported datum \"%s\"!", ctail); + } + break; + case 'U': + switch(*ctail) + { + case '1': /* lat/lon, that's we want to see */ + break; + case '0': /* UTM not supported yet */ + fatal(MYNAME "Sorry, UTM is not supported yet!\n"); + default: + fatal(MYNAME "Invalid system of coordinates (%s)!\n", cin); + } + break; + case 'R': + route = route_head_alloc(); + route_add_head(route); + parse_rte_info(ctail, route); + break; + case 'M': + break; + case 'W': + wpt = parse_wpt(ctail); + if (wpt != NULL) + { + if (route != NULL) + route_add_wpt(route, wpt); + else + waypt_add(wpt); + } + break; + case 'w': + is_fatal((wpt == NULL), MYNAME ": No waypoint data before \"%s\"!", cin); + parse_wpt_info(ctail, wpt); + break; + case 'T': + wpt = parse_trkpt(ctail); + if (wpt != NULL) + { + if (track == NULL) + { + track = route_head_alloc(); + track_add_head(track); + } + track_add_wpt(track, wpt); + } + break; + case 't': + if (track != NULL) + parse_track_info(ctail, track); + break; + } + } +} + +/* ----------------------------------------------------------- */ + +static void +write_waypt_cb(const waypoint *wpt) +{ + char *name; + + if (curr_index != target_index ) return; + + name = (snlen > 0) ? mkshort_from_wpt(sh, wpt) : csv_stringclean(wpt->shortname, " "); + + gbfprintf(fout, "W %s A ", name); + gbfprintf(fout, "%.10f%c%c ", + fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S'); + gbfprintf(fout, "%.10f%c%c ", + fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); + gbfprintf(fout, "27-MAR-62 00:00:00 %.6f", + (wpt->altitude != unknown_alt) ? wpt->altitude : 0.0); + if (wpt->description != NULL) + gbfprintf(fout, " %s", wpt->description); + gbfprintf(fout, "\n"); + + if ((wpt->icon_descr != NULL) || (wpt->wpt_flags.proximity) || \ + (option_icon != NULL)) + { + char *icon = option_icon; + + if (wpt->icon_descr != NULL) icon = (char *) wpt->icon_descr; + + gbfprintf(fout, "w %s,0,0.0,16777215,255,1,7,,%.1f\n", + (icon != NULL) ? icon : "Waypoint", + WAYPT_GET(wpt, proximity, 0)); + } + xfree(name); +} + +static void +write_route_hdr_cb(const route_head *rte) +{ + char *name; + curr_route = (route_head *) rte; + curr_index++; + if (curr_index != target_index) return; + + name = rte->rte_name; + if (name != NULL) + name = csv_stringclean(name, ","); + else + name = xstrdup(" "); + gbfprintf(fout, "R 16711680,%s,1,-1\n", name); + xfree(name); +} + +static void +write_route(void) +{ + curr_index = 0; + route_disp_all(write_route_hdr_cb, NULL, write_waypt_cb); +} + +static void +write_track_hdr_cb(const route_head *trk) +{ + track_info_flag = 0; + curr_track = (route_head *) trk; + + curr_index++; + if (curr_index != target_index) return; + + track_info_flag = 1; +} + +static void +write_trkpt_cb(const waypoint *wpt) +{ + char buff[128]; + struct tm tm; + + if ((curr_index != target_index) || (wpt == NULL)) return; + + buff[0] = '\0'; + + if (wpt->creation_time != 0) + { + tm = *gmtime(&wpt->creation_time); + strftime(buff, sizeof(buff), "%d-%b-%y %H:%M:%S", &tm); + strupper(buff); + } + else strncpy(buff, "01-JAN-70 00:00:00", sizeof(buff)); + + gbfprintf(fout, "T A %.10f%c%c %.10f%c%c ", + fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S', + fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); + gbfprintf(fout, "%s s %.1f %.1f %.1f %.1f %d ", + buff, + wpt->altitude, + 0.0, + 0.0, + 0.0, + 0); + gbfprintf(fout, "%.1f %.1f %.1f %.1f %.1f\n", + -1000.0, + -1.0, + -1.0, + -1.0, + -1.0); + if (track_info_flag != 0) + { + track_info_flag = 0; + if (curr_track->rte_name != NULL) + { + char *name; + + name = csv_stringclean(curr_track->rte_name, "|"); + gbfprintf(fout, "t 4294967295|%s|-1|-1\n", name); + xfree(name); + } + } +} + +static void +write_track(void) +{ + curr_index = 0; + +// gbfprintf(fout, "L +02:00:00\n"); + track_disp_all(write_track_hdr_cb, NULL, write_trkpt_cb); + gbfprintf(fout, "F 1234\n"); +} + +static void +write_waypoints(void) +{ + waypt_disp_all(write_waypt_cb); +} + +/* --------------------------------------------------------------------------- */ + +static void +compegps_wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); + sh = mkshort_new_handle(); +} + +static void +compegps_wr_deinit(void) +{ + mkshort_del_handle(&sh); + gbfclose(fout); +} + +static void +compegps_data_write(void) +{ + /* because of different file extensions we can only write one GPS data type at time */ + + gbfprintf(fout, "G WGS 84\n"); + gbfprintf(fout, "U 1\n"); + + /* process options */ + + target_index = 1; + if (option_index != NULL) + target_index = atoi(option_index); + + snlen = 0; + if (global_opts.synthesize_shortnames != 0) + { + if (option_snlen != NULL) + snlen = atoi(option_snlen); + else + snlen = SHORT_NAME_LENGTH; + + is_fatal((snlen < 1), MYNAME "Invalid length for generated shortnames!"); + + setshort_whitespace_ok(sh, 0); + setshort_length(sh, snlen); + } + + radius = -1; + if (option_radius != 0) + { + radius = atof(option_radius); + is_fatal((radius <= 0.0), MYNAME "Invalid value for radius!"); + } + + if (option_icon != NULL) + { + if (*option_icon == '\0') + option_icon = NULL; + else if (case_ignore_strcmp(option_icon, "deficon") == 0) + option_icon = NULL; + } + + switch(global_opts.objective) + { + case wptdata: + curr_index = target_index = 0; + write_waypoints(); + break; + case trkdata: + write_track(); + break; + case rtedata: + write_route(); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } +} + +/* --------------------------------------------------------------------------- */ + +ff_vecs_t compegps_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + compegps_rd_init, + compegps_wr_init, + compegps_rd_deinit, + compegps_wr_deinit, + compegps_data_read, + compegps_data_write, + NULL, + compegps_args, + CET_CHARSET_MS_ANSI, 1 +}; +#endif /* CSVFMTS_ENABLED */ diff --git a/config.guess b/config.guess new file mode 100755 index 000000000..917bbc50f --- /dev/null +++ b/config.guess @@ -0,0 +1,1463 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-07-08' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 000000000..ff1bfe607 --- /dev/null +++ b/config.h.in @@ -0,0 +1,71 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* 0 for most-used character sets */ +#undef CET_WANTED + +/* 1 to enable the CSV formats support */ +#undef CSVFMTS_ENABLED + +/* 1 to enable all the filters. */ +#undef FILTERS_ENABLED + +/* Defined if you have libexpat */ +#undef HAVE_LIBEXPAT + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Defined if you have libusb */ +#undef HAVE_LIBUSB + +/* Define to 1 if you have the `z' library (-lz). */ +#undef HAVE_LIBZ + +/* Define to 1 if you have the `nanosleep' function. */ +#undef HAVE_NANOSLEEP + +/* Define to 1 if you have the `sleep' function. */ +#undef HAVE_SLEEP + +/* Define if we have va_copy */ +#undef HAVE_VA_COPY + +/* Define if we have __va_copy */ +#undef HAVE___VA_COPY + +/* Define as 1 if your va_list type is an array */ +#undef HAVE_VA_LIST_AS_ARRAY + +/* 1 to enable as many formats as possible */ +#undef MAXIMAL_ENABLED + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the release name of this package. */ +#undef PACKAGE_RELEASE + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* 1 to enable Palm PDB support */ +#undef PDBFMTS_ENABLED + +/* 1 to enable shapefile support */ +#undef SHAPELIB_ENABLED + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* 1 to inhibit our use of zlib. */ +#undef ZLIB_INHIBITED diff --git a/config.sub b/config.sub new file mode 100755 index 000000000..1c366dfde --- /dev/null +++ b/config.sub @@ -0,0 +1,1579 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-07-08' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ms1 \ + | msp430 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m32c) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | ms1-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + m32c-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 000000000..ba89b6b49 --- /dev/null +++ b/configure @@ -0,0 +1,6020 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61 for GPSBabel 1.3.5. +# +# Report bugs to . +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='GPSBabel' +PACKAGE_TARNAME='gpsbabel' +PACKAGE_VERSION='1.3.5' +PACKAGE_STRING='GPSBabel 1.3.5' +PACKAGE_BUGREPORT='BUG-REPORT-ADDRESS' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +PACKAGE_RELEASE +DOCVERSION +GBMAJOR +GBMINOR +GBMICRO +GBBUILD +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +target +target_cpu +target_vendor +target_os +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +SET_MAKE + +CPP +GREP +EGREP +PALM_DB_CMT +FMTS +FILEINFO +RC +LIBUSBCONFIG +USB_LIBS +USB_CFLAGS +OSJEEPS +GBSER +ZLIB +EXPAT_LIB +EFENCE_LIB +GPSBABEL_DEBUG +INSTALL_DEBUG +DOCDIR +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures GPSBabel 1.3.5 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/gpsbabel] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of GPSBabel 1.3.5:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-shapefile=(yes)|no + --enable-pdb=(yes)|no + --enable-csv=(yes)|no + --enable-most=(yes)|no + --enable-filters=(yes)|no + --enable-efence=yes|(no) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-cet=(default,all,minimal) + --with-zlib=(included)|system|no + --with-expathdr=DIR Use this to specify the location of expat.h + --with-libexpat=DIR Use this to specify expat library . + --with-doc=DIR Path where the documentation will be stored. + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +GPSBabel configure 1.3.5 +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by GPSBabel $as_me 1.3.5, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Increase GBBUILD for a new release +GBBUILD=16 +# YYYYMMDD, please, if beta, i.e. "-beta20060413" +# PACKAGE_RELEASE="-beta20080305" + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_RELEASE "$PACKAGE_RELEASE" +_ACEOF + + + +DOCVERSION=`echo $PACKAGE_VERSION` +DOCVERSION=development +DOCVERSION=1.3.5 + + +GBMAJOR=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $major)` +GBMINOR=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $minor)` +GBMICRO=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $micro)` + + + + + +# AC_CONFIG_SRCDIR([nmea.c]) +ac_config_headers="$ac_config_headers config.h" + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6; } +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 +echo "$as_me: error: invalid value of canonical target" >&2;} + { (exit 1); exit 1; }; };; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; } +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \ + && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN) + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_bigendian=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6; } +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + + +# Checks for libraries. + +{ echo "$as_me:$LINENO: checking for cos in -lm" >&5 +echo $ECHO_N "checking for cos in -lm... $ECHO_C" >&6; } +if test "${ac_cv_lib_m_cos+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char cos (); +int +main () +{ +return cos (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_m_cos=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_m_cos=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_cos" >&5 +echo "${ECHO_T}$ac_cv_lib_m_cos" >&6; } +if test $ac_cv_lib_m_cos = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + + + +# Check whether --with-cet was given. +if test "${with_cet+set}" = set; then + withval=$with_cet; cet="$withval" +else + cet="default" +fi + + +if test $GCC = yes; then + CFLAGS="$CFLAGS -Wall" +fi + +if test "$cet" = "all"; then + +cat >>confdefs.h <<\_ACEOF +#define CET_WANTED 1 +_ACEOF + +fi +if test "$cet" = "default"; then + +cat >>confdefs.h <<\_ACEOF +#define CET_WANTED 0 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking whether to support shapefiles" >&5 +echo $ECHO_N "checking whether to support shapefiles... $ECHO_C" >&6; } +# Check whether --enable-shapefile was given. +if test "${enable_shapefile+set}" = set; then + enableval=$enable_shapefile; enable_shapefile="$enableval" +else + enable_shapefile="yes" +fi + + if test "$enable_shapefile" != "no" ; then + +cat >>confdefs.h <<\_ACEOF +#define SHAPELIB_ENABLED 1 +_ACEOF + + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + fi + +{ echo "$as_me:$LINENO: checking whether to support Palm/OS pdb formats" >&5 +echo $ECHO_N "checking whether to support Palm/OS pdb formats... $ECHO_C" >&6; } +# Check whether --enable-pdb was given. +if test "${enable_pdb+set}" = set; then + enableval=$enable_pdb; enable_pdb="$enableval" +else + enable_pdb="yes" +fi + + if test "$enable_pdb" != "no" ; then + +cat >>confdefs.h <<\_ACEOF +#define PDBFMTS_ENABLED 1 +_ACEOF + + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + else + PALM_DB_CMT=# + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + fi + + +{ echo "$as_me:$LINENO: checking whether to support csv formats" >&5 +echo $ECHO_N "checking whether to support csv formats... $ECHO_C" >&6; } +# Check whether --enable-csv was given. +if test "${enable_csv+set}" = set; then + enableval=$enable_csv; enable_csv="$enableval" +else + enable_csv="yes" +fi + + if test "$enable_csv" != "no" ; then + +cat >>confdefs.h <<\_ACEOF +#define CSVFMTS_ENABLED 1 +_ACEOF + + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + fi + +{ echo "$as_me:$LINENO: checking whether to support maximum number of formats" >&5 +echo $ECHO_N "checking whether to support maximum number of formats... $ECHO_C" >&6; } +# Check whether --enable-most was given. +if test "${enable_most+set}" = set; then + enableval=$enable_most; enable_most="$enableval" +else + enable_most="yes" +fi + + if test "$enable_most" != "no" ; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define MAXIMAL_ENABLED 1 +_ACEOF + + FMTS='$(ALL_FMTS)' + else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + FMTS='$(MINIMAL_FMTS)' + fi + + +{ echo "$as_me:$LINENO: checking whether to support filters" >&5 +echo $ECHO_N "checking whether to support filters... $ECHO_C" >&6; } +# Check whether --enable-filters was given. +if test "${enable_filters+set}" = set; then + enableval=$enable_filters; enable_filters="$enableval" +else + enable_filters="yes" +fi + + if test "$enable_filters" != "no" ; then + +cat >>confdefs.h <<\_ACEOF +#define FILTERS_ENABLED 1 +_ACEOF + + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + fi + +{ echo "$as_me:$LINENO: checking whether to support zlib" >&5 +echo $ECHO_N "checking whether to support zlib... $ECHO_C" >&6; } + +# Check whether --with-zlib was given. +if test "${with_zlib+set}" = set; then + withval=$with_zlib; +fi + + case $with_zlib in + "system") + +{ echo "$as_me:$LINENO: checking for gzopen in -lz" >&5 +echo $ECHO_N "checking for gzopen in -lz... $ECHO_C" >&6; } +if test "${ac_cv_lib_z_gzopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gzopen (); +int +main () +{ +return gzopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_z_gzopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_z_gzopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_gzopen" >&5 +echo "${ECHO_T}$ac_cv_lib_z_gzopen" >&6; } +if test $ac_cv_lib_z_gzopen = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBZ 1 +_ACEOF + + LIBS="-lz $LIBS" + +fi + + ;; + "no") + +cat >>confdefs.h <<\_ACEOF +#define ZLIB_INHIBITED 1 +_ACEOF + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + ;; + *) ZLIB="\$(ZLIB)" + { echo "$as_me:$LINENO: result: using included version" >&5 +echo "${ECHO_T}using included version" >&6; };; + esac + +case "$target" in + *-*-mingw32*) + FILEINFO=fileinfo.o + if test "$CC" = gcc ; then + RC=windres + else + RC=`echo "$CC" | sed -e 's/gcc$/windres/'` + fi + ;; + *) + RC=false + ;; +esac + + + +case "$target" in + *-*-cygwin* | *-*-mingw32*) + + GBSER=gbser_win.o + + if test "$with_libusb" = no ; then + { echo "$as_me:$LINENO: result: USB skipped" >&5 +echo "${ECHO_T}USB skipped" >&6; } + OSJEEPS=jeeps/gpsusbstub.o + else + OSJEEPS=jeeps/gpsusbwin.o + USB_LIBS=-lsetupapi + fi + ;; + *) + GBSER=gbser_posix.o + { echo "$as_me:$LINENO: checking for libusb" >&5 +echo $ECHO_N "checking for libusb... $ECHO_C" >&6; } + if test "$with_libusb" = no ; then + { echo "$as_me:$LINENO: result: check not done" >&5 +echo "${ECHO_T}check not done" >&6; } + OSJEEPS=jeeps/gpsusbstub.o + else + # Extract the first word of "libusb-config", so it can be a program name with args. +set dummy libusb-config; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_LIBUSBCONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$LIBUSBCONFIG"; then + ac_cv_prog_LIBUSBCONFIG="$LIBUSBCONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIBUSBCONFIG="true" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_LIBUSBCONFIG" && ac_cv_prog_LIBUSBCONFIG="false" +fi +fi +LIBUSBCONFIG=$ac_cv_prog_LIBUSBCONFIG +if test -n "$LIBUSBCONFIG"; then + { echo "$as_me:$LINENO: result: $LIBUSBCONFIG" >&5 +echo "${ECHO_T}$LIBUSBCONFIG" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + if test "$LIBUSBCONFIG" = true; then + OLDFLAGS=$LDFLAGS + OCFLAGS=$CFLAGS + LDFLAGS="$LDFLAGS `libusb-config --libs`" + CFLAGS="$OCFLAGS `libusb-config --cflags`" + + { echo "$as_me:$LINENO: checking for usb_interrupt_read in -lusb" >&5 +echo $ECHO_N "checking for usb_interrupt_read in -lusb... $ECHO_C" >&6; } +if test "${ac_cv_lib_usb_usb_interrupt_read+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lusb $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char usb_interrupt_read (); +int +main () +{ +return usb_interrupt_read (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_usb_usb_interrupt_read=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_usb_usb_interrupt_read=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_usb_usb_interrupt_read" >&5 +echo "${ECHO_T}$ac_cv_lib_usb_usb_interrupt_read" >&6; } +if test $ac_cv_lib_usb_usb_interrupt_read = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBUSB 1 +_ACEOF + + USB_CFLAGS="`libusb-config --cflags`" + USB_LIBS="`libusb-config --libs`" +# ,[AC_MSG_ERROR([libusb >= 0.1.8 is needed])] + +fi + + # Override libusb for Darwin to reduce external + # runtime requirement. + case "$target" in + *-*-darwin*) + if test "x$ac_cv_lib_usb_usb_interrupt_read" = "xyes" ; then + USB_LIBS="`libusb-config --prefix`/lib/libusb.a -framework IOKit -framework CoreFoundation" + LDFLAGS=$OLDFLAGS + CDFLAGS=$OCDFLAGS + OSJEEPS=jeeps/gpslibusb.o + else + OSJEEPS=jeeps/gpsusbstub.o + fi + ;; + *) + OSJEEPS=jeeps/gpslibusb.o + ;; + esac + CFLAGS="$OCFLAGS" + # LIBS="$LIBS `libusb-config --libs`" + else + OSJEEPS=jeeps/gpsusbstub.o + fi + fi + ;; +esac + + + + + + + +{ echo "$as_me:$LINENO: checking for random stuff to make you feel better" >&5 +echo $ECHO_N "checking for random stuff to make you feel better... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6; } + + +# Check whether --with-expathdr was given. +if test "${with_expathdr+set}" = set; then + withval=$with_expathdr; xpathdr="$withval" +else + + case "$target" in + *-*-darwin6*|*-*-darwin7*|*-*-darwin8*) + # Restrict test to OS/X 10.4 and earlier. Leopard (10.5) + # provides expat and in a sensible location. + if test -f /sw/include/expat.h ; then + xpathdr=/sw/include/ + fi + ;; + *-*-freebsd*) + if test -f /usr/local/include/expat.h ; then + xpathdr=/usr/local/include + fi + ;; + *) ;; + esac + + +fi + + +if test "x-$xpathdr" != "x-" ; then + CFLAGS="$CFLAGS -I$xpathdr" +fi + +{ echo "$as_me:$LINENO: checking for libexpat" >&5 +echo $ECHO_N "checking for libexpat... $ECHO_C" >&6; } + +# Check whether --with-libexpat was given. +if test "${with_libexpat+set}" = set; then + withval=$with_libexpat; + # If the developer specified a reference + # to a FILE and not a directory, assume they are a highly + # trained professional that has specified a .a to to be used. + if test -f $withval ; then + EXPAT_LIB=$withval + else + CFLAGS="$CFLAGS -L$withval" + EXPAT_LIB="-L$withval -lexpat" + fi + +else + + case "$target" in + *-*-darwin6*|*-*-darwin7*|*-*-darwin8*) + # Restrict test to OS/X 10.4 and earlier. Leopard (10.5) + # provides expat and in a sensible location. + if test -f /sw/lib/libexpat.a ; then + # libexpat installed via fink + EXPAT_LIB=/sw/lib/libexpat.a + LIBS="$LIBS -L/sw/lib" + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBEXPAT 1 +_ACEOF + + + fi + if test -f /opt/local/lib/libexpat.a ; then + # libexpat installed via macports + EXPAT_LIB=/opt/local/lib/libexpat.a + LIBS="$LIBS -L/opt/local/lib" + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBEXPAT 1 +_ACEOF + + + fi + if test -f /usr/local/lib/libexpat.a ; then + # libexpat installed from source + EXPAT_LIB=/usr/local/lib/libexpat.a + LIBS="$LIBS -L/usr/local/lib" + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBEXPAT 1 +_ACEOF + + + fi + ;; + *-*-freebsd*) + if test -f /usr/local/lib/libexpat.a ; then + EXPAT_LIB=/usr/local/lib/libexpat.a + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBEXPAT 1 +_ACEOF + + + fi + ;; + *) + EXPAT_LIB=-lexpat + ;; + esac + + +fi + +{ echo "$as_me:$LINENO: result: $EXPAT_LIB" >&5 +echo "${ECHO_T}$EXPAT_LIB" >&6; } + +{ echo "$as_me:$LINENO: checking for XML_ParserCreate in -lexpat" >&5 +echo $ECHO_N "checking for XML_ParserCreate in -lexpat... $ECHO_C" >&6; } +if test "${ac_cv_lib_expat_XML_ParserCreate+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lexpat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XML_ParserCreate (); +int +main () +{ +return XML_ParserCreate (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_expat_XML_ParserCreate=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_expat_XML_ParserCreate=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_expat_XML_ParserCreate" >&5 +echo "${ECHO_T}$ac_cv_lib_expat_XML_ParserCreate" >&6; } +if test $ac_cv_lib_expat_XML_ParserCreate = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBEXPAT 1 +_ACEOF + + + +fi + + +{ echo "$as_me:$LINENO: checking for efence" >&5 +echo $ECHO_N "checking for efence... $ECHO_C" >&6; } +# Check whether --enable-efence was given. +if test "${enable_efence+set}" = set; then + enableval=$enable_efence; if test "$enable_efence" != "no" ; then + EFENCE_LIB=-lefence + GPSBABEL_DEBUG=gpsbabel-debug + INSTALL_DEBUG=install-debug + fi +fi + + + + +{ echo "$as_me:$LINENO: result: $EFENCE_LIB" >&5 +echo "${ECHO_T}$EFENCE_LIB" >&6; } + +{ echo "$as_me:$LINENO: checking for docdir" >&5 +echo $ECHO_N "checking for docdir... $ECHO_C" >&6; } + +# Check whether --with-doc was given. +if test "${with_doc+set}" = set; then + withval=$with_doc; DOCDIR="$withval" +else + DOCDIR="../babelweb/" +fi + + + +# Checks for header files. +# AC_HEADER_STDC + +# AC_CHECK_HEADERS([fcntl.h inttypes.h libintl.h limits.h malloc.h stddef.h stdint.h stdlib.h string.h strings.h sys/ioctl.h sys/time.h termios.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +# AC_C_CONST +# AC_C_INLINE +# AC_TYPE_OFF_T +# AC_TYPE_SIZE_T +# AC_HEADER_TIME +# AC_STRUCT_TM +# AC_STRUCT_TIMEZONE + +# Checks for library functions. +# AC_FUNC_MALLOC +# AC_FUNC_MEMCMP +# AC_FUNC_MKTIME +# AC_FUNC_REALLOC +# AC_FUNC_SELECT_ARGTYPES +# AC_FUNC_STRFTIME +# AC_FUNC_STRTOD +# AC_FUNC_VPRINTF +# AC_CHECK_FUNCS([atexit floor localtime_r memmove memset pow select sqrt strchr strcspn strdup strerror strncasecmp strrchr strspn strstr strtol strtoul]) + + +for ac_func in nanosleep sleep +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# +# Checks for how the system handles va_list +# paul.bromiley@man.ac.uk +# +{ echo "$as_me:$LINENO: checking for va_copy" >&5 +echo $ECHO_N "checking for va_copy... $ECHO_C" >&6; } +if test "${ac_cv_c_va_copy+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +va_list ap1, ap2; + va_copy(ap1,ap2); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_c_va_copy="yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_va_copy="no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_va_copy" >&5 +echo "${ECHO_T}$ac_cv_c_va_copy" >&6; } +if test "$ac_cv_c_va_copy" = "yes" +then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_VA_COPY 1 +_ACEOF + +fi +{ echo "$as_me:$LINENO: checking for __va_copy" >&5 +echo $ECHO_N "checking for __va_copy... $ECHO_C" >&6; } +if test "${ac_cv_c___va_copy+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +va_list ap1, ap2; + __va_copy(ap1,ap2); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_c___va_copy="yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c___va_copy="no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c___va_copy" >&5 +echo "${ECHO_T}$ac_cv_c___va_copy" >&6; } +if test "$ac_cv_c___va_copy" = "yes" +then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___VA_COPY 1 +_ACEOF + +fi + +# +# Does this platform require array notation to assign to a va_list? +# +{ echo "$as_me:$LINENO: checking va_list assignments need array notation" >&5 +echo $ECHO_N "checking va_list assignments need array notation... $ECHO_C" >&6; } +if test "${ac_cv_valistisarray+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_valistisarray=false +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + #include + void foo(int i, ...) { + va_list ap1, ap2; + va_start(ap1, i); + ap2 = ap1; + if (va_arg(ap2, int) != 123 || va_arg(ap1, int) != 123) { exit(1); } + va_end(ap1); va_end(ap2); + } + int main() + { foo(0, 123); return(0); } +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_valistisarray=false +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_valistisarray=true +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + + +if test "$ac_cv_valistisarray" = true ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_VA_LIST_AS_ARRAY 1 +_ACEOF + + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi +ac_config_files="$ac_config_files Makefile gbversion.h xmldoc/makedoc tools/mkcapabilities win32/gpsbabel.rc jeeps/Makefile shapelib/Makefile zlib/empty" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by GPSBabel $as_me 1.3.5, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +GPSBabel config.status 1.3.5 +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "gbversion.h") CONFIG_FILES="$CONFIG_FILES gbversion.h" ;; + "xmldoc/makedoc") CONFIG_FILES="$CONFIG_FILES xmldoc/makedoc" ;; + "tools/mkcapabilities") CONFIG_FILES="$CONFIG_FILES tools/mkcapabilities" ;; + "win32/gpsbabel.rc") CONFIG_FILES="$CONFIG_FILES win32/gpsbabel.rc" ;; + "jeeps/Makefile") CONFIG_FILES="$CONFIG_FILES jeeps/Makefile" ;; + "shapelib/Makefile") CONFIG_FILES="$CONFIG_FILES shapelib/Makefile" ;; + "zlib/empty") CONFIG_FILES="$CONFIG_FILES zlib/empty" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +PACKAGE_RELEASE!$PACKAGE_RELEASE$ac_delim +DOCVERSION!$DOCVERSION$ac_delim +GBMAJOR!$GBMAJOR$ac_delim +GBMINOR!$GBMINOR$ac_delim +GBMICRO!$GBMICRO$ac_delim +GBBUILD!$GBBUILD$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +target!$target$ac_delim +target_cpu!$target_cpu$ac_delim +target_vendor!$target_vendor$ac_delim +target_os!$target_os$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +PALM_DB_CMT!$PALM_DB_CMT$ac_delim +FMTS!$FMTS$ac_delim +FILEINFO!$FILEINFO$ac_delim +RC!$RC$ac_delim +LIBUSBCONFIG!$LIBUSBCONFIG$ac_delim +USB_LIBS!$USB_LIBS$ac_delim +USB_CFLAGS!$USB_CFLAGS$ac_delim +OSJEEPS!$OSJEEPS$ac_delim +GBSER!$GBSER$ac_delim +ZLIB!$ZLIB$ac_delim +EXPAT_LIB!$EXPAT_LIB$ac_delim +EFENCE_LIB!$EFENCE_LIB$ac_delim +GPSBABEL_DEBUG!$GPSBABEL_DEBUG$ac_delim +INSTALL_DEBUG!$INSTALL_DEBUG$ac_delim +DOCDIR!$DOCDIR$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 86; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" + ;; + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + diff --git a/configure.in b/configure.in new file mode 100644 index 000000000..15982033c --- /dev/null +++ b/configure.in @@ -0,0 +1,395 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) + +AC_INIT(GPSBabel, 1.3.5, BUG-REPORT-ADDRESS) +# Increase GBBUILD for a new release +GBBUILD=16 +# YYYYMMDD, please, if beta, i.e. "-beta20060413" +# PACKAGE_RELEASE="-beta20080305" +AC_DEFINE_UNQUOTED(PACKAGE_RELEASE, "$PACKAGE_RELEASE", [Define to the release name of this package.]) +AC_SUBST(PACKAGE_RELEASE) + +DOCVERSION=`echo $PACKAGE_VERSION` +DOCVERSION=development +DOCVERSION=1.3.5 +AC_SUBST(DOCVERSION) + +GBMAJOR=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $major)` +GBMINOR=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $minor)` +GBMICRO=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $micro)` +AC_SUBST(GBMAJOR) +AC_SUBST(GBMINOR) +AC_SUBST(GBMICRO) +AC_SUBST(GBBUILD) + +# AC_CONFIG_SRCDIR([nmea.c]) +AC_CONFIG_HEADER([config.h]) + +dnl Detect the canonical host and target build environment +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +# Checks for programs. +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_MAKE_SET +AC_EXEEXT +AC_SUBST(AC_EXEEXT) +AC_C_BIGENDIAN + +# Checks for libraries. +AC_CHECK_LIB([m], [cos]) + +AC_ARG_WITH(cet,[ --with-cet=(default,all,minimal)], + cet="$withval", cet="default") + +if test $GCC = yes; then + CFLAGS="$CFLAGS -Wall" +fi + +if test "$cet" = "all"; then + AC_DEFINE(CET_WANTED, 1, [1 for all character sets]) +fi +if test "$cet" = "default"; then + AC_DEFINE(CET_WANTED, 0, [0 for most-used character sets]) +fi + +AC_MSG_CHECKING(whether to support shapefiles) +AC_ARG_ENABLE(shapefile, + [ --enable-shapefile=[(yes)|no]], + [ enable_shapefile="$enableval"],[enable_shapefile="yes"]) + if test "$enable_shapefile" != "no" ; then + AC_DEFINE(SHAPELIB_ENABLED, 1, [1 to enable shapefile support]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + +AC_MSG_CHECKING(whether to support Palm/OS pdb formats) +AC_ARG_ENABLE(pdb, + [ --enable-pdb=[(yes)|no]], + [ enable_pdb="$enableval"],[enable_pdb="yes"]) + if test "$enable_pdb" != "no" ; then + AC_DEFINE(PDBFMTS_ENABLED, 1, [1 to enable Palm PDB support]) + AC_MSG_RESULT(yes) + else + PALM_DB_CMT=# + AC_MSG_RESULT(no) + fi +AC_SUBST(PALM_DB_CMT) + +AC_MSG_CHECKING(whether to support csv formats) +AC_ARG_ENABLE(csv, + [ --enable-csv=[(yes)|no]], + [ enable_csv="$enableval"],[enable_csv="yes"]) + if test "$enable_csv" != "no" ; then + AC_DEFINE(CSVFMTS_ENABLED, 1, [1 to enable the CSV formats support]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + +AC_MSG_CHECKING(whether to support maximum number of formats) +AC_ARG_ENABLE(most, + [ --enable-most=[(yes)|no]], + [ enable_most="$enableval"],[enable_most="yes"]) + if test "$enable_most" != "no" ; then + AC_MSG_RESULT(yes) + AC_DEFINE(MAXIMAL_ENABLED, 1, [1 to enable as many formats as possible]) + FMTS='$(ALL_FMTS)' + else + AC_MSG_RESULT(no) + FMTS='$(MINIMAL_FMTS)' + fi + AC_SUBST(FMTS) + +AC_MSG_CHECKING(whether to support filters) +AC_ARG_ENABLE(filters, + [ --enable-filters=[(yes)|no]], + [ enable_filters="$enableval"],[enable_filters="yes"]) + if test "$enable_filters" != "no" ; then + AC_DEFINE(FILTERS_ENABLED, 1, [1 to enable all the filters.]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + +AC_MSG_CHECKING(whether to support zlib) +AC_ARG_WITH(zlib, [ --with-zlib=[(included)|system|no]]) + case $with_zlib in + "system") + AC_CHECK_LIB([z], [gzopen]) + ;; + "no") + AC_DEFINE(ZLIB_INHIBITED, 1, [1 to inhibit our use of zlib.]) + AC_MSG_RESULT(no) + ;; + *) ZLIB="\$(ZLIB)" + AC_MSG_RESULT(using included version);; + esac + +case "$target" in + *-*-mingw32*) + FILEINFO=fileinfo.o + if test "$CC" = gcc ; then + RC=windres + else + RC=`echo "$CC" | sed -e 's/gcc$/windres/'` + fi + ;; + *) + RC=false + ;; +esac +AC_SUBST(FILEINFO) +AC_SUBST(RC) + +case "$target" in + *-*-cygwin* | *-*-mingw32*) + + GBSER=gbser_win.o + + if test "$with_libusb" = no ; then + AC_MSG_RESULT(USB skipped) + OSJEEPS=jeeps/gpsusbstub.o + else + OSJEEPS=jeeps/gpsusbwin.o + USB_LIBS=-lsetupapi + fi + ;; + *) + GBSER=gbser_posix.o + AC_MSG_CHECKING(for libusb) + if test "$with_libusb" = no ; then + AC_MSG_RESULT(check not done) + OSJEEPS=jeeps/gpsusbstub.o + else + AC_CHECK_PROG(LIBUSBCONFIG, libusb-config, true, false) + if test "$LIBUSBCONFIG" = true; then + OLDFLAGS=$LDFLAGS + OCFLAGS=$CFLAGS + LDFLAGS="$LDFLAGS `libusb-config --libs`" + CFLAGS="$OCFLAGS `libusb-config --cflags`" + + AC_CHECK_LIB([usb], [usb_interrupt_read], + AC_DEFINE(HAVE_LIBUSB, 1, [Defined if you have libusb]) + [USB_CFLAGS="`libusb-config --cflags`"] + [USB_LIBS="`libusb-config --libs`"] +# ,[AC_MSG_ERROR([libusb >= 0.1.8 is needed])] + ) + # Override libusb for Darwin to reduce external + # runtime requirement. + case "$target" in + *-*-darwin*) + if test "x$ac_cv_lib_usb_usb_interrupt_read" = "xyes" ; then + USB_LIBS="`libusb-config --prefix`/lib/libusb.a -framework IOKit -framework CoreFoundation" + LDFLAGS=$OLDFLAGS + CDFLAGS=$OCDFLAGS + OSJEEPS=jeeps/gpslibusb.o + else + OSJEEPS=jeeps/gpsusbstub.o + fi + ;; + *) + OSJEEPS=jeeps/gpslibusb.o + ;; + esac + CFLAGS="$OCFLAGS" + # LIBS="$LIBS `libusb-config --libs`" + else + OSJEEPS=jeeps/gpsusbstub.o + fi + fi + ;; +esac + +AC_SUBST(USB_LIBS) +AC_SUBST(USB_CFLAGS) +AC_SUBST(OSJEEPS) +AC_SUBST(GBSER) +AC_SUBST(ZLIB) + +AC_MSG_CHECKING(for random stuff to make you feel better) +AC_MSG_RESULT(failed) + +AC_ARG_WITH(expathdr, + [ --with-expathdr[=DIR] Use this to specify the location of expat.h], + [ xpathdr="$withval" ], [ + case "$target" in + *-*-darwin6*|*-*-darwin7*|*-*-darwin8*) + # Restrict test to OS/X 10.4 and earlier. Leopard (10.5) + # provides expat and in a sensible location. + if test -f /sw/include/expat.h ; then + xpathdr=/sw/include/ + fi + ;; + *-*-freebsd*) + if test -f /usr/local/include/expat.h ; then + xpathdr=/usr/local/include + fi + ;; + *) ;; + esac +] +) + +if test "x-$xpathdr" != "x-" ; then + CFLAGS="$CFLAGS -I$xpathdr" +fi + +AC_MSG_CHECKING(for libexpat) +AC_ARG_WITH(libexpat, + [ --with-libexpat[=DIR] Use this to specify expat library .], + [ + # If the developer specified a reference + # to a FILE and not a directory, assume they are a highly + # trained professional that has specified a .a to to be used. + if test -f $withval ; then + EXPAT_LIB=$withval + else + CFLAGS="$CFLAGS -L$withval" + EXPAT_LIB="-L$withval -lexpat" + fi + ], [ + case "$target" in + *-*-darwin6*|*-*-darwin7*|*-*-darwin8*) + # Restrict test to OS/X 10.4 and earlier. Leopard (10.5) + # provides expat and in a sensible location. + if test -f /sw/lib/libexpat.a ; then + # libexpat installed via fink + EXPAT_LIB=/sw/lib/libexpat.a + LIBS="$LIBS -L/sw/lib" + AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) + AC_SUBST(EXPAT_LIB) + fi + if test -f /opt/local/lib/libexpat.a ; then + # libexpat installed via macports + EXPAT_LIB=/opt/local/lib/libexpat.a + LIBS="$LIBS -L/opt/local/lib" + AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) + AC_SUBST(EXPAT_LIB) + fi + if test -f /usr/local/lib/libexpat.a ; then + # libexpat installed from source + EXPAT_LIB=/usr/local/lib/libexpat.a + LIBS="$LIBS -L/usr/local/lib" + AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) + AC_SUBST(EXPAT_LIB) + fi + ;; + *-*-freebsd*) + if test -f /usr/local/lib/libexpat.a ; then + EXPAT_LIB=/usr/local/lib/libexpat.a + AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) + AC_SUBST(EXPAT_LIB) + fi + ;; + *) + EXPAT_LIB=-lexpat + ;; + esac + ] +) +AC_MSG_RESULT($EXPAT_LIB) + +AC_CHECK_LIB([expat], [XML_ParserCreate], + AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) + AC_SUBST(EXPAT_LIB) +) + +AC_MSG_CHECKING(for efence) +AC_ARG_ENABLE(efence, + [ --enable-efence=[yes|(no)]], + [ if test "$enable_efence" != "no" ; then + EFENCE_LIB=-lefence + GPSBABEL_DEBUG=gpsbabel-debug + INSTALL_DEBUG=install-debug + fi]) +AC_SUBST(EFENCE_LIB) +AC_SUBST(GPSBABEL_DEBUG) +AC_SUBST(INSTALL_DEBUG) +AC_MSG_RESULT($EFENCE_LIB) + +AC_MSG_CHECKING(for docdir) +AC_ARG_WITH(doc,[ --with-doc=DIR Path where the documentation will be stored.], + DOCDIR="$withval", DOCDIR="../babelweb/") +AC_SUBST(DOCDIR) + +# Checks for header files. +# AC_HEADER_STDC + +# AC_CHECK_HEADERS([fcntl.h inttypes.h libintl.h limits.h malloc.h stddef.h stdint.h stdlib.h string.h strings.h sys/ioctl.h sys/time.h termios.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +# AC_C_CONST +# AC_C_INLINE +# AC_TYPE_OFF_T +# AC_TYPE_SIZE_T +# AC_HEADER_TIME +# AC_STRUCT_TM +# AC_STRUCT_TIMEZONE + +# Checks for library functions. +# AC_FUNC_MALLOC +# AC_FUNC_MEMCMP +# AC_FUNC_MKTIME +# AC_FUNC_REALLOC +# AC_FUNC_SELECT_ARGTYPES +# AC_FUNC_STRFTIME +# AC_FUNC_STRTOD +# AC_FUNC_VPRINTF +# AC_CHECK_FUNCS([atexit floor localtime_r memmove memset pow select sqrt strchr strcspn strdup strerror strncasecmp strrchr strspn strstr strtol strtoul]) +AC_CHECK_FUNCS([nanosleep sleep]) + +# +# Checks for how the system handles va_list +# paul.bromiley@man.ac.uk +# +dnl **** Check for va_copy **** +AC_CACHE_CHECK([for va_copy], ac_cv_c_va_copy, + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[va_list ap1, ap2; + va_copy(ap1,ap2); + ]])],[ac_cv_c_va_copy="yes"],[ac_cv_c_va_copy="no"]) + ) +if test "$ac_cv_c_va_copy" = "yes" +then + AC_DEFINE(HAVE_VA_COPY, 1, [Define if we have va_copy]) +fi +AC_CACHE_CHECK([for __va_copy], ac_cv_c___va_copy, + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[va_list ap1, ap2; + __va_copy(ap1,ap2); + ]])],[ac_cv_c___va_copy="yes"],[ac_cv_c___va_copy="no"]) + ) +if test "$ac_cv_c___va_copy" = "yes" +then + AC_DEFINE(HAVE___VA_COPY, 1, [Define if we have __va_copy]) +fi + +# +# Does this platform require array notation to assign to a va_list? +# +AC_MSG_CHECKING(va_list assignments need array notation) +AC_CACHE_VAL(ac_cv_valistisarray, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[#include + #include + void foo(int i, ...) { + va_list ap1, ap2; + va_start(ap1, i); + ap2 = ap1; + if (va_arg(ap2, int) != 123 || va_arg(ap1, int) != 123) { exit(1); } + va_end(ap1); va_end(ap2); + } + int main() + { foo(0, 123); return(0); }]])],[ac_cv_valistisarray=false],[ac_cv_valistisarray=true],[ac_cv_valistisarray=false])]) + +if test "$ac_cv_valistisarray" = true ; then + AC_DEFINE(HAVE_VA_LIST_AS_ARRAY, 1, [Define as 1 if your va_list type is an array]) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi +AC_CONFIG_FILES([Makefile gbversion.h xmldoc/makedoc tools/mkcapabilities win32/gpsbabel.rc jeeps/Makefile shapelib/Makefile zlib/empty]) +AC_OUTPUT + diff --git a/contrib/correctCoordinates.pl b/contrib/correctCoordinates.pl new file mode 100755 index 000000000..baaf61307 --- /dev/null +++ b/contrib/correctCoordinates.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl + +############################################################################################################ +# +# GPX Coordinate corrector +# 3/17/2004 +# +# Takes a GPX Spinner-formatted CorrectedCaches.txt file and substitutes the coordinates into a GPX file +# most likely from a Geocaching pocket query, based on the short name (GCXXXX). +# Useful for updating coordinates for puzzle caches or changing to the next stage of a multi-cache. +# Caches that appear in the corrections file but are not in the GPX are ignored. +# +# Usage: +# correctCoordinates.pl my.gpx CorrectedCaches.txt > corrected.gpx +# +# requires XML::Twig +# +# Jeff Boulter +# +############################################################################################################ + +use strict; +use XML::Twig; + +my $fname = $ARGV[0]; +my $correctFile = $ARGV[1]; + +open(CORR, $correctFile) || die "can't find corrections file: $!"; + +my %correct; + +while () +{ + s/\#.*//; + tr/\r//d; + chomp; + my $line = trim($_); + if ($line) + { +# print "\"$line\"\n"; + my($wp, $lat, $lon) = split(/\,/, $line); +# print "coords: $wp $lat $lon\n"; + + $correct{$wp} = {'lat' => coordsToDec(trim($lat)), 'lon' => coordsToDec(trim($lon))}; + } +} + +close(CORR); + +my $twig = XML::Twig->new( + twig_roots => { 'wpt' => \&wpt, + }, + twig_print_outside_roots => 1, # print the rest +); + +$twig->parsefile($fname); # build the twig + +sub trim +{ + my $str = $_[0]; + $str =~ s/\s*(.*\S)\s*/$1/; + return $str; +} + +sub coordsToDec +{ + my $CoordString = @_[0]; + my $Result = 0; + if ($CoordString =~ /\s*([N|S|E|W])\D*(\d+)\D*([\d|.]+)/i) { + my $Direction = uc($1); + $Result = $2 + $3 / 60.; + if ($Direction eq 'S' || $Direction eq 'W') { + $Result = -$Result; + } + } + elsif ($CoordString =~ /\s*-{0,1}\d+\.\d+/) { + $Result = $CoordString; + } + return $Result; +} + + + sub wpt +{ + my( $t, $wpt)= @_; # arguments for all twig_handlers + my $title = $wpt->first_child( 'name')->text; # find the title + + if ($correct{$title}) + { +# print STDERR "correcting " . $wpt->first_child( 'urlname')->text . "\n"; + $wpt->set_att('lat' => $correct{$title}->{'lat'}); + $wpt->set_att('lon' => $correct{$title}->{'lon'}); + } + + # bug in Twig doesn't keep > escaped + $wpt->subs_text( qr{>}, '&ent( ">")'); + + $wpt->flush; # outputs the section and frees memory + } + diff --git a/contrib/gpx2xfig b/contrib/gpx2xfig new file mode 100644 index 000000000..edd43cc22 --- /dev/null +++ b/contrib/gpx2xfig @@ -0,0 +1,73 @@ +From: David Slimp +Date 02/09/04 +Subject: [Gpsbabel-misc] gpx2xfig and transparent gif + +Hello All, + +I don't know if anyone would be interested in this or not, +but I've created a small perl script that will convert a gpx +file to an xfig data file, so I could then take track +information and edit in a visual way, and then using fig2dev +I create a transparent gif of my track/route. + +I was planning to use this as an overlay for a Yahoo or +MapQuest map, but after driving a couple miles and then +trying to fit my track path over the Yahoo map for that area +it seemed to be a bit off -- rotation wise. At first I +thought it might be the difference between true north and +magnetic north, but appearantly not. + +Anyway, in case anyone out there might benefit from this or +want to work on it more here's my script and sample linux +command lines: + +==================== gpx2xfig =============================== +#!/usr/bin/perl -w +# +# gpx2xfig - converts GPS gpx file to xfig vector file +# +# author: David Slimp +# created: 20040206 +# updated: 20040208 + +$VERSION=".001"; + +($infl,$outfl)=@ARGV; + +open(IN,"$infl") or die "$!"; +open(OUT,">$outfl") or die "$!"; + +while () { + s/longitude = + DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = + DEG(pdb_read_double(&rec->latitude)); + wpt_tmp->altitude = FEET_TO_METERS(be_read32(&rec->elevation)); + + vdata = (char *) data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = NULL; + + return wpt_tmp; +} + +static waypoint* +read_version1(void *data) +{ + char *vdata; + waypoint *wpt_tmp; + struct record1* rec = (struct record1*)data; + + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = + DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = + DEG(pdb_read_double(&rec->latitude)); + wpt_tmp->altitude = + FEET_TO_METERS(pdb_read_double(&rec->elevation)); + + vdata = (char *) data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + return wpt_tmp; +} + +static waypoint* +read_version3(void *data) +{ + char *vdata; + waypoint *wpt_tmp; + struct record3* rec = (struct record3*)data; + + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = + DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = + DEG(pdb_read_double(&rec->latitude)); + wpt_tmp->altitude = + FEET_TO_METERS(pdb_read_double(&rec->elevation)); + + vdata = (char *) data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + return wpt_tmp; +} + +static waypoint* +read_version4(void *data) +{ + char *vdata; + waypoint *wpt_tmp; + struct record4* rec = (struct record4*)data; + + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = + DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = + DEG(pdb_read_double(&rec->latitude)); + wpt_tmp->altitude = + FEET_TO_METERS(pdb_read_float(&rec->elevation)); + + vdata = (char *) data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + return wpt_tmp; +} + +static void +data_read(void) +{ + pdbrec_t *pdb_rec; + + if ((file_in->creator != GXPU_CREATOR && file_in->creator != AP_P_CREATOR) || + (file_in->type != wayp_TYPE && file_in->type != swpu_TYPE && + file_in->type != wayu_TYPE)) { + fatal(MYNAME ": Not a CoPilot file.\n"); + } + if (file_in->version > 4) { + fatal(MYNAME ": %d is not a known version.\n", file_in->version); + } + + + for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint *wpt_tmp; + + switch (file_in->version) + { + case 0: + wpt_tmp = read_version0(pdb_rec->data); + break; + case 1: + case 2: + wpt_tmp = read_version1(pdb_rec->data); + break; + case 3: + wpt_tmp = read_version3(pdb_rec->data); + break; + case 4: + wpt_tmp = read_version4(pdb_rec->data); + break; + default: + fatal(MYNAME ": Unknown version %d.\n", file_in->version); + } + waypt_add(wpt_tmp); + } +} + +static void +copilot_writewpt(const waypoint *wpt) +{ + struct record4 *rec; + char *vdata; + + rec = xcalloc(sizeof(*rec)+1141,1); + + pdb_write_double(&rec->latitude, RAD(wpt->latitude)); + pdb_write_double(&rec->longitude, RAD(-wpt->longitude)); + pdb_write_float(&rec->magvar, 0); + pdb_write_float(&rec->elevation, + METERS_TO_FEET(wpt->altitude)); + + vdata = (char *)rec + sizeof(*rec); + if ( wpt->shortname ) { + strncpy( vdata, wpt->shortname, 10 ); + vdata[9] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + if ( wpt->description ) { + strncpy( vdata, wpt->description, 100 ); + vdata[99] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + + if ( wpt->notes ) { + strncpy( vdata, wpt->notes, 1000 ); + vdata[999] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + + pdb_write_rec(file_out, 0, 2, ct++, rec, (char *)vdata - (char *)rec); + + xfree(rec); +} + +static void +data_write(void) +{ + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = wayp_TYPE; + file_out->creator = GXPU_CREATOR; + file_out->version = 4; + + waypt_disp_all(copilot_writewpt); +} + + +ff_vecs_t copilot_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; +#endif diff --git a/coto.c b/coto.c new file mode 100644 index 000000000..eff0692e7 --- /dev/null +++ b/coto.c @@ -0,0 +1,429 @@ +/* + Read and write cotoGPS files. + + Copyright (C) 2005 Tobias Minich, + + Based on the Cetus I/O Filter, + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "csv_util.h" +#include "pdbfile.h" +#include "grtcirc.h" + +#define MYNAME "cotoGPS" + +#define MYTYPETRACK 0x5452434b /* TRCK */ +#define MYTYPEWPT 0x44415441 /* DATA */ +#define MYCREATOR 0x636f4750 /* coGP */ + +#define NOTESZ 4096 +#define DESCSZ 4096 + +#define MAX_MARKER_NAME_LENGTH 20 +#define CATEGORY_NAME_LENGTH 16 + +typedef enum { + cotofixNone = 0, /* No Fix or Warning */ + cotofixReserved = 1, /* Shouldn't occur*/ + cotofix2D = 2, /* retrieved from a GPS with a 2D fix */ + cotofix3D = 3, /* retrieved from a GPS with a 3D fix */ + cotofixDGPS = 4, /* retrieved from a GPS with a DGPS signal */ +} fix_quality; + +struct record_track { + + pdb_double latitude; /* radians, s=negative */ + pdb_double longitude; /* same as lat; e=negative */ + pdb_double distance; /* Distance to thel last point; discarded since it's calculated by gpsbabel on write */ + pdb_double arc; /* Course, unknown dimension */ + pdb_double x,y; /* Internal virtual coordinates used for drawing the track on the Palm */ + + gbuint16 alt; /* Altitude */ + + /* accuracy and precision information for use where applicable */ + gbuint16 hdop; /* _dop * 10 */ + gbuint16 vdop; + gbuint16 pdop; + gbuint8 sat_tracked; + gbuint8 fix_quality; + + gbuint16 speed; /* *10 */ + gbuint32 time; /* Palm Time */ +}; + +struct record_wpt { + char lon[8]; + char lat[8]; + char name[MAX_MARKER_NAME_LENGTH]; + char notes[1]; +}; + + +// We need the pdb AppInfo for waypoint categories + +typedef char appinfo_category[16]; + +typedef struct appinfo { + gbuint8 U0; + gbuint8 renamedCategories; + appinfo_category categories[CATEGORY_NAME_LENGTH]; + gbuint8 ids[16]; + gbuint8 maxid; +} appinfo_t; + +#define APPINFO_SIZE sizeof(appinfo_t) + +static pdbfile *file_in, *file_out; +static const char *out_fname; +static const char *in_fname; /* We might need that for naming tracks */ +static short_handle mkshort_wr_handle; +static int ct; + +static char *zerocat = NULL; +static char *internals = NULL; + +static +arglist_t coto_args[] = { + {"zerocat", &zerocat, "Name of the 'unassigned' category", NULL, + ARGTYPE_STRING, ARG_NOMINMAX }, + {"internals", &internals, "Export some internal stuff to notes", NULL, + ARGTYPE_STRING | ARGTYPE_HIDDEN, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static void +rd_init(const char *fname) +{ + file_in = pdb_open(fname, MYNAME); + in_fname = fname; +} + +static void +rd_deinit(void) +{ + pdb_close(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; +} + +static void +wr_deinit(void) +{ + pdb_close(file_out); +} + +/* helpers */ + +static char * +coto_get_icon_descr(int category, const appinfo_t *app) +{ + char buff[CATEGORY_NAME_LENGTH + 1] = "Not Assigned"; + if ((category >= 0) && (category < 16)) + { + if ((category > 0) && (app->categories[category][0] == '\0')) + category = 0; + + strncpy(buff, app->categories[category], sizeof(buff) - 1); + if (buff[0] == '\0') + return NULL; + } + return xstrdup(buff); +} + +static void +coto_track_read(void) +{ + struct record_track *rec; + pdbrec_t *pdb_rec; + route_head *trk_head; + char *track_name; + + if (strncmp(file_in->name, "cotoGPS TrackDB", PDB_DBNAMELEN) != 0) + // Use database name if not default + track_name = xstrndup(file_in->name, PDB_DBNAMELEN); + else { + // Use filename for new track title + const char *fnametmp = strrchr(in_fname, '/'); + if (fnametmp == NULL) + fnametmp = strrchr(in_fname, '\\'); + if (fnametmp) + fnametmp++; + else + fnametmp = in_fname; + if (strrchr(fnametmp, '.') != NULL) + track_name = xstrndup(fnametmp, strrchr(fnametmp,'.') - fnametmp); + else + track_name = xstrdup(fnametmp); + } + + trk_head = route_head_alloc(); + track_add_head(trk_head); + + trk_head->rte_name = track_name; + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) + { + waypoint *wpt_tmp; + + wpt_tmp = waypt_new(); + + rec = (struct record_track *) pdb_rec->data; + + wpt_tmp->longitude = DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = DEG(pdb_read_double(&rec->latitude)); + + // It's not the course, so leave it out for now + // WAYPT_SET(wpt_tmp, course, pdb_read_double(&rec->arc)); + wpt_tmp->altitude = be_read16(&rec->alt); + + if (internals) + { + // Parse the option as xcsv delimiter + const char *inter = xcsv_get_char_from_constant_table(internals); + char temp[256]; + snprintf(temp, sizeof(temp), "%.20f%s%.20f%s%.20f%s%.20f", pdb_read_double(&rec->distance), inter, + pdb_read_double(&rec->arc), inter, pdb_read_double(&rec->x), inter, pdb_read_double(&rec->y)); + wpt_tmp->notes = xstrdup(temp); + } + + wpt_tmp->pdop = be_read16(&rec->pdop)/10.0; + wpt_tmp->hdop = be_read16(&rec->hdop)/10.0; + wpt_tmp->vdop = be_read16(&rec->vdop)/10.0; + wpt_tmp->sat = rec->sat_tracked; + switch (rec->fix_quality) + { + case cotofixNone: + wpt_tmp->fix = fix_none; + break; + case cotofixReserved: + wpt_tmp->fix = fix_unknown; + break; + case cotofix2D: + wpt_tmp->fix = fix_2d; + break; + case cotofix3D: + wpt_tmp->fix = fix_3d; + break; + case cotofixDGPS: + wpt_tmp->fix = fix_dgps; + break; + } + WAYPT_SET(wpt_tmp, speed, be_read16(&rec->speed)/10.0); + rec->time = be_read32(&rec->time); + if (rec->time != 0) + { + rec->time -= 2082844800U; + wpt_tmp->creation_time = rec->time; + } + track_add_wpt(trk_head, wpt_tmp); + } +} + +static void +coto_wpt_read(void) +{ + struct record_wpt *rec; + pdbrec_t *pdb_rec; + appinfo_t *app; + app = (struct appinfo *) file_in->appinfo; + + for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) + { + waypoint *wpt_tmp; + char *c; + + wpt_tmp = waypt_new(); + + rec = (struct record_wpt *) pdb_rec->data; + + wpt_tmp->longitude = DEG(-pdb_read_double(&rec->lon)); + wpt_tmp->latitude = DEG(pdb_read_double(&rec->lat)); + + wpt_tmp->shortname = xstrndup(rec->name, sizeof(rec->name)); + + wpt_tmp->icon_descr = coto_get_icon_descr(pdb_rec->category, app); + if (wpt_tmp->icon_descr) + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + + if ((c = strstr(rec->notes, "\nNotes:\n"))) { /* remove our contruct */ + wpt_tmp->notes = xstrdup(c + 8); + if (c != rec->notes) { + wpt_tmp->description = xstrndup(rec->notes, c - rec->notes); + } + } else { + wpt_tmp->notes = xstrdup(rec->notes); + } + + waypt_add(wpt_tmp); + } +} + +static void +data_read(void) +{ + if ((file_in->creator != MYCREATOR) || ((file_in->type != MYTYPETRACK) && (file_in->type != MYTYPEWPT))) { + warning("Creator %x Type %x Version %d\n", (int) file_in->creator, (int) file_in->type, (int) file_in->version); + fatal(MYNAME ": Not a cotoGPS file.\n"); + } + + is_fatal((file_in->version > 0), + MYNAME ": This file is from an unsupported newer version of cotoGPS. It may be supported in a newer version of GPSBabel.\n"); + + switch(file_in->type) + { + case MYTYPETRACK: + coto_track_read(); + break; + case MYTYPEWPT: + coto_wpt_read(); + break; + } +} + +static void +coto_prepare_wpt_write(void) +{ + struct appinfo *ai; + + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->type = MYTYPEWPT; + file_out->creator = MYCREATOR; + file_out->version = 0; + + strncpy(file_out->name, "cotoGPS MarkerDB", PDB_DBNAMELEN); + + file_out->appinfo_len = APPINFO_SIZE; + file_out->appinfo = calloc(APPINFO_SIZE,1); + + ai = (struct appinfo *) file_out->appinfo; + be_write16(&ai->renamedCategories, 31); // Don't ask me why... + if (zerocat) + strncpy(ai->categories[0], zerocat, 16); + else + strncpy(ai->categories[0], "Not Assigned", 16); // FIXME: Replace by default English Palm 'Not Assigned' category + +} + +static void +coto_wpt_write(const waypoint *wpt) +{ + struct record_wpt *rec; + struct appinfo *ai = (struct appinfo *) file_out->appinfo; + char *notes = NULL; + char *shortname = NULL; + int size; + gbuint8 cat = 0; + int i; + + mkshort_wr_handle = mkshort_new_handle(); + setshort_length(mkshort_wr_handle, MAX_MARKER_NAME_LENGTH); + setshort_whitespace_ok(mkshort_wr_handle, 1); + + if ((global_opts.synthesize_shortnames && wpt->description) || (wpt->shortname == NULL)) + shortname = mkshort_from_wpt(mkshort_wr_handle, wpt); + else + shortname = xstrdup(wpt->shortname); + + if ((wpt->description) && ((strlen(wpt->description) > MAX_MARKER_NAME_LENGTH) || (strcmp(wpt->description, wpt->shortname)))) + { + if ((wpt->notes) && (strcmp(wpt->description, wpt->notes) != 0)) + { + notes = xcalloc(strlen(wpt->description) + strlen(wpt->notes) + 9, 1); + sprintf(notes, "%s\nNotes:\n%s", wpt->description, wpt->notes); + } else { + notes = xstrdup(wpt->description); + } + } + else if (wpt->notes != NULL) + { + notes = xstrdup(wpt->notes); + } + + size = sizeof(*rec); + if (notes != NULL) + size += strlen(notes); + rec = xcalloc(size, 1); + + pdb_write_double(&rec->lon, RAD(-wpt->longitude)); + pdb_write_double(&rec->lat, RAD(wpt->latitude)); + strncpy(rec->name, shortname, MAX_MARKER_NAME_LENGTH); + + if (notes) + { + strcpy(rec->notes, notes); + xfree(notes); + } + + if (wpt->icon_descr) + { + for(i = 1; i < 16; i++) + if (!strncmp(wpt->icon_descr, ai->categories[i], 16)) {cat=i; break;} + if (!cat) { + // We have a new one + if (ai->maxid<15) { + i = ++ai->maxid; + snprintf(ai->categories[i], 16, "%s", wpt->icon_descr); + cat = ai->ids[i] = i; + } else { + // We're full! + warning(MYNAME ": Categories full. Category '%s' written as %s.\n", wpt->icon_descr, zerocat?zerocat:"Not Assigned"); + } + } + } + + pdb_write_rec(file_out, 0, cat, ct++, (const gbuint8 *)rec, size); + + xfree(shortname); + xfree(rec); + + mkshort_del_handle(&mkshort_wr_handle); +} + +static void +data_write(void) +{ + coto_prepare_wpt_write(); + waypt_disp_all(coto_wpt_write); +} + + +ff_vecs_t coto_vecs = { + ff_type_file, + {ff_cap_read|ff_cap_write, ff_cap_read, ff_cap_none}, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + coto_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; +#endif diff --git a/cst.c b/cst.c new file mode 100644 index 000000000..34f9b44d4 --- /dev/null +++ b/cst.c @@ -0,0 +1,362 @@ +/* + + Support for CarteSurTable data file, + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include "defs.h" +#include "strptime.h" +#include +#include +#include +#include + +#define MYNAME "cst" + +#undef CST_DEBUG + +#define CST_UNKNOWN 0 +#define CST_HEADER 1 +#define CST_ROUTE 2 +#define CST_NOTES 3 +#define CST_REFERENCE 4 +#define CST_VERSION 5 + +static gbfile *fin; + +static route_head *temp_route; + +/* placeholders for options */ + +static +arglist_t cst_args[] = { + ARG_TERMINATOR +}; + +/* helpers */ + +static void +cst_add_wpt(const route_head *track, waypoint *wpt) +{ + if ((wpt == NULL) || (track == NULL)) return; + + if (wpt->shortname != NULL) + { + waypt_add(waypt_dupe(wpt)); + if (wpt->url != NULL) + { + xfree(wpt->url); + wpt->url = NULL; + } + + if (temp_route == NULL) + { + temp_route = route_head_alloc(); + route_add_head(temp_route); + } + route_add_wpt(temp_route, waypt_dupe(wpt)); + } + track_add_wpt((route_head *)track, (waypoint *)wpt); +} + +static char * +cst_make_url(char *str) +{ + int len = strlen(str); + char *res; + + if (len < 3) return NULL; + + if (strstr(str, "://") > str) + return xstrdup(str); + else if (strstr(str, ":\\") == str+1) /* DOS 0.01++ file format */ + { + res = xstrdup("file://*:"); + res[7] = *str++; + res[8] = *str++; + res = xstrappend(res, str); + { + char *c; + int i; + + c = res; /* replace all backslashes with a slash */ + while ((c = strchr(c, '\\'))) *c++ = '/'; + + c = res; /* enumerate number of spaces within filename */ + i = 0; + while ((c = strchr(c, ' '))) + { + c++; + i++; + } + + if (i > 0) /* .. and replace them with "%20" */ + { + char *src, *dest, *last; + + last = src = res; + res = dest = xcalloc(strlen(src) + (2*i) + 1, 1); + while ((c = strchr(src, ' '))) + { + if (c != src) strncpy(dest, src, c - src); + strcat(dest, "%20"); + c++; + src = c; + dest = res + strlen(res); + } + while (*src != '\0') + *dest++ = *src++; + xfree(last); + } + } + return res; + + } + else + return NULL; + +} + +/* --------------------------------------------------------------------------- */ + +static void +cst_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); + temp_route = NULL; +} + +static void +cst_rd_deinit(void) +{ + gbfclose(fin); +} + +/* --------------------------------------------------------------------------- */ + +static void +cst_data_read(void) +{ + char *buff; + int line = 0; + int data_lines = -1; + int line_of_count = -1; + int valid = 0; + int section = CST_UNKNOWN; + int cst_version; + int cst_points = -1; + route_head *track = NULL; + waypoint *wpt = NULL; + + while ((buff = gbfgetstr(fin))) + { + char *cin = buff; + + line++; + cin = lrtrim(buff); + if (strlen(cin) == 0) continue; + + if (strncmp(cin, "; ", 2) == 0) continue; + if (*cin == '#') + { + section = CST_UNKNOWN; + if (strcmp(cin+1, "ROUTE") == 0) section = CST_ROUTE; + else if (strcmp(cin+1, "VERSION") == 0) section = CST_VERSION; + else if (strcmp(cin+1, "NOTES") == 0) section = CST_NOTES; + else if (strcmp(cin+1, "REFERENCE") == 0) section = CST_REFERENCE; + else if (strcmp(cin+1, "CARTE SUR TABLE DATA FILE") == 0) + { + section = CST_HEADER; + valid = 1; + } + else + warning(MYNAME ": Unknown section \"%s\".\n", cin+1); + + continue; + } + + if (valid == 0) continue; + + switch(section) + { + case CST_ROUTE: + if (*cin == ';') + { + int data = 0; + + if (*(cin+1) != '\xA4') continue; + + if (strncmp(cin + 2, "bitmap", 6) == 0) + { + cin = lrtrim(cin + 8); + if (*cin != '\0') + wpt->url = cst_make_url(cin); + } + + while ((buff = gbfgetstr(fin))) + { + line++; + cin = lrtrim(buff); + + if (strcmp(cin + 2, "note") == 0) + { + buff = gbfgetstr(fin); + if (buff == NULL) buff = ""; + line++; + cin = lrtrim(buff); + if (*cin != '\0') + wpt->notes = xstrdup(cin); + } + else if (strcmp(cin + 2, "end") == 0) + { + data = 1; + break; + } + } + if (data == 0) + fatal(MYNAME ": Unexpected end of file!\n"); + } + else + { + int interp, i; + char name[256]; + char *pow; + + if (data_lines < 0) + { + if ((2 != sscanf(cin, "%d %128s", &i, name)) || + (case_ignore_strcmp(name, "Points") != 0)) + fatal(MYNAME "-line %d: Number of points expected!\n", line); + line_of_count = line; + data_lines = 0; + cst_points = i; + continue; + } + + cst_add_wpt(track, wpt); + wpt = NULL; + + + wpt = waypt_new(); + + if (5 != sscanf(cin, "%lf %lf %lf %d %s", + &wpt->longitude, + &wpt->latitude, + &wpt->altitude, + &interp, name)) + { + fatal(MYNAME ": Could not interprete line %d!\n", line); + } + + data_lines++; + + if (strcmp(name, "1") == 0) + { + track = route_head_alloc(); + track_add_head(track); + } + else if (strncmp(name, "NAME:", 5) == 0) + wpt->shortname = xstrdup(((char *)&name) + 5); + + pow = strrchr(cin, '^'); + if (pow != NULL) + { + struct tm tm; + + pow = lrtrim(++pow); + strptime(pow, "%Y %m %d %H:%M:%S", &tm); + + wpt->creation_time = mkgmtime(&tm); + } + wpt->latitude /= 100000.0; + wpt->longitude /= 100000.0; + } + break; + + + case CST_VERSION: + cst_version = atoi(cin); + if (cst_version != 40) + warning(MYNAME ": Not tested with file version %d.\n", cst_version); + break; + + case CST_REFERENCE: + if ((strncmp(cin, "DATUM ", 6) == 0) && (strstr(cin, "WGS 84") == NULL)) + fatal(MYNAME ": Unsupported datum (%s)!\n", cin); + break; + + case CST_HEADER: + case CST_NOTES: + break; + } + } + cst_add_wpt(track, wpt); + wpt = NULL; + + if ((cst_points >= 0) && (data_lines != cst_points)) + warning(MYNAME ": Loaded %d point(s), but line %d says %d!\n", data_lines, line_of_count, cst_points); +} + +#if 0 +static void +cst_wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); +} + +static void +cst_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +cst_route_hdr(const route_head *rte) +{ +} + +static void +cst_route_tlr(const route_head *rte) +{ +} + +static void +cst_write_wpt(const waypoint *wpt) +{ +} + +static void +cst_data_write(void) +{ +} +#endif + +ff_vecs_t cst_vecs = { + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_read }, + cst_rd_init, + NULL, /* cst_wr_init, */ + cst_rd_deinit, + NULL, /* cst_wr_deinit, */ + cst_data_read, + NULL, /* cst_data_write, */ + NULL, + cst_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ +}; diff --git a/csv_util.c b/csv_util.c new file mode 100644 index 000000000..31886f4b4 --- /dev/null +++ b/csv_util.c @@ -0,0 +1,1930 @@ +/* + Utilities for parsing Character Separated Value files (CSV) + + Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com) + Copyright (C) 2002-2007 Robert Lipe + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include "defs.h" +#include "csv_util.h" +#include "grtcirc.h" +#include "strptime.h" +#include "jeeps/gpsmath.h" +#include "xmlgeneric.h" // for xml_fill_in_time. +#include "garmin_fs.h" + +#define MYNAME "CSV_UTIL" + +/* macros */ +#define LAT_DIR(a) a < 0.0 ? 'S' : 'N' +#define LON_DIR(a) a < 0.0 ? 'W' : 'E' +#define NONULL(a) a ? a : "" +#define ISWHITESPACE(a) ((a == ' ') || (a == '\t')) + +/* convert excel time (days since 1900) to time_t and back again */ +#define EXCEL_TO_TIMET(a) ((a - 25569.0) * 86400.0) +#define TIMET_TO_EXCEL(a) ((a / 86400.0) + 25569.0) + +#define GPS_DATUM_WGS84 118 + + +/* + * Internal numeric value to associate with each keyword in a style file. + * To add new keywords, just add an entry here, handle it in the switch + * statements below, add it to xcsv_tokens.in, and rebuild on a system + * that has GNU gperf on it. + */ +typedef enum { + XT_unused = 0, + XT_ALT_FEET, + XT_ALT_METERS, + XT_ANYNAME, + XT_CADENCE, + XT_CITY, + XT_CONSTANT, + XT_COUNTRY, + XT_DESCRIPTION, + XT_EXCEL_TIME, + XT_FACILITY, + XT_GEOCACHE_CONTAINER, + XT_GEOCACHE_DIFF, + XT_GEOCACHE_HINT, + XT_GEOCACHE_LAST_FOUND, + XT_GEOCACHE_PLACER, + XT_GEOCACHE_TERR, + XT_GEOCACHE_TYPE, + XT_GEOCACHE_ISAVAILABLE, + XT_GEOCACHE_ISARCHIVED, + XT_GMT_TIME, + XT_GPS_FIX, + XT_GPS_HDOP, + XT_GPS_PDOP, + XT_GPS_SAT, + XT_GPS_VDOP, + XT_HEART_RATE, + XT_HMSG_TIME, + XT_HMSL_TIME, + XT_ICON_DESCR, + XT_IGNORE, + XT_INDEX, + XT_ISO_TIME, + XT_ISO_TIME_MS, + XT_LATLON_HUMAN_READABLE, + XT_LAT_DECIMAL, + XT_LAT_DECIMALDIR, + XT_LAT_DIR, + XT_LAT_DIRDECIMAL, + XT_LAT_HUMAN_READABLE, + XT_LAT_INT32DEG, + XT_LAT_NMEA, + XT_LOCAL_TIME, + XT_LON_DECIMAL, + XT_LON_DECIMALDIR, + XT_LON_DIR, + XT_LON_DIRDECIMAL, + XT_LON_HUMAN_READABLE, + XT_LON_INT32DEG, + XT_LON_NMEA, + XT_MAP_EN_BNG, + XT_NOTES, + XT_PATH_COURSE, + XT_PATH_DISTANCE_KM, + XT_PATH_DISTANCE_MILES, + XT_PATH_SPEED, + XT_PATH_SPEED_KNOTS, + XT_PATH_SPEED_KPH, + XT_PATH_SPEED_MPH, + XT_PHONE_NR, + XT_POSTAL_CODE, + XT_ROUTE_NAME, + XT_SHORTNAME, + XT_STATE, + XT_STREET_ADDR, + XT_TIMET_TIME, + XT_TRACK_NAME, + XT_URL, + XT_URL_LINK_TEXT, + XT_YYYYMMDD_TIME +} xcsv_token; + +#include "xcsv_tokens.gperf" + +/****************************************************************************/ +/* obligatory global struct */ +/****************************************************************************/ +xcsv_file_t xcsv_file; + +extern char *xcsv_urlbase; +extern char *prefer_shortnames; + +extern geocache_type gs_mktype(const char *t); +extern geocache_container gs_mkcont(const char *t); + +static double pathdist = 0; +static double oldlon = 999; +static double oldlat = 999; + +static int waypt_out_count; +static route_head *csv_track, *csv_route; + +/*********************************************************************/ +/* csv_stringclean() - remove any unwanted characters from string. */ +/* returns copy of string. */ +/* usage: p = csv_stringclean(stringtoclean, "&,\"") */ +/* (strip out ampersands, commas, and quotes. */ +/*********************************************************************/ +char * +#ifdef DEBUG_MEM +CSV_STRINGCLEAN(const char *string, const char *chararray, DEBUG_PARAMS) +#else +csv_stringclean(const char *string, const char *chararray) +#endif +{ + char * p1; + char * p2; + const char * cp; + char * tmp = xxstrdup(string,file,line); + + if ((! string) || (! chararray)) { + return (tmp); + } + + /* p2 - end of the original string */ + p2 = tmp + strlen(tmp); + + cp = chararray; + + while (*cp) { + p1 = tmp; + while (*p1) { + if (*cp == *p1) { + /* we don't want this character! */ + memmove(p1, p1 + 1, (p2 - p1)); + p1[p2 - p1] = '\0'; + p2--; + } + else + p1++; + } + cp++; + } + return (tmp); +} + +/***********************************************************************************/ +/* csv_stringtrim() - trim whitespace and leading and trailing enclosures (quotes) */ +/* returns a copy of the modified string */ +/* usage: p = csv_stringtrim(string, "\"", 0) */ +/***********************************************************************************/ +char * +#ifdef DEBUG_MEM +CSV_STRINGTRIM(const char *string, const char *enclosure, int strip_max, DEBUG_PARAMS) +#else +csv_stringtrim(const char *string, const char *enclosure, int strip_max) +#endif +{ + static const char *p1 = NULL; + char *p2 = NULL; + char * tmp = xxstrdup(string,file,line); + size_t elen; + int stripped = 0; + + if (!strlen(string)) { + return (tmp); + } + + if (!enclosure) { + elen = 0; + } else { + elen = strlen(enclosure); + } + + p2 = tmp + strlen(tmp) - 1; + p1 = tmp; + + /* trim off trailing whitespace */ + while ((p2 > p1) && isspace(*p2)) { + p2--; + } + + /* advance p1 past any leading whitespace */ + while ((p1 < p2) && (isspace(*p1))) { + p1++; + } + + /* if no maximum strippage, assign a reasonable value to max */ + strip_max = strip_max ? strip_max : 9999; + + /* if we have enclosures, skip past them in pairs */ + if (elen) { + while ( + (stripped < strip_max) && + ((size_t) (p2 - p1 + 1) >= (elen * 2)) && + (strncmp(p1, enclosure, elen) == 0) && + (strncmp((p2 - elen + 1), enclosure, elen) == 0)) { + p2 -= elen; + p1 += elen; + stripped++; + } + } + + /* copy what's left over back into tmp. */ + memmove(tmp, p1, (p2 - p1) + 1); + + tmp[(p2 - p1) + 1] = '\0'; + + return (tmp); +} + +/*****************************************************************************/ +/* csv_lineparse() - extract data fields from a delimited string. designed */ +/* to handle quoted and delimited data within quotes. */ +/* returns temporary COPY of delimited data field (use it */ +/* or lose it on the next call). */ +/* usage: p = csv_lineparse(string, ",", "\"", line) [initial call] */ +/* p = csv_lineparse(NULL, ",", "\"", line) [subsequent calls] */ +/*****************************************************************************/ +char * +csv_lineparse(const char *stringstart, const char *delimited_by, + const char *enclosed_in, const int line_no) +{ + const char *sp; + static const char *p = NULL; + static char *tmp = NULL; + size_t dlen = 0, elen = 0, efound = 0; + int enclosedepth = 0; + short int dfound; + short int hyper_whitespace_delimiter = 0; + + if (tmp) { + xfree(tmp); + tmp = NULL; + } + + if (strcmp(delimited_by, "\\w") == 0) + hyper_whitespace_delimiter = 1; + + /* + * This is tacky. Our "csv" format is actually "commaspace" format. + * Changing that causes unwanted churn, but it also makes "real" + * comma separated data (such as likely to be produced by Excel, etc.) + * unreadable. So we silently change it here on a read and let the + * whitespace eater consume the space. + */ + if (strcmp(delimited_by, ", ") == 0) { + delimited_by = ","; + } + + if (!p) { + /* first pass thru */ + p = stringstart; + + if (!p) { + /* last pass out */ + return (NULL); + } + } + + /* the beginning of the string we start with (this pass) */ + sp = p; + + /* length of delimiters and enclosures */ + if ((delimited_by) && (!hyper_whitespace_delimiter)) + dlen = strlen(delimited_by); + if (enclosed_in) + elen = strlen(enclosed_in); + dfound = 0; + + while ((*p) && (!dfound)) { + if ((elen) && (strncmp(p, enclosed_in, elen) == 0)) + { + efound = 1; + p+=elen; + if (enclosedepth) + enclosedepth--; + else + enclosedepth++; + continue; + } + + if (!enclosedepth) { + if ((dlen) && (strncmp(p, delimited_by, dlen) == 0)) { + dfound = 1; + } else if ((hyper_whitespace_delimiter) && (ISWHITESPACE(*p))) { + dfound = 1; + while (ISWHITESPACE(*p)) + p++; + } else { + p++; + } + } + else { + p++; + } + } + + /* allocate enough space for this data field */ + tmp = xcalloc((p - sp) + 1, sizeof(char)); + + strncpy(tmp, sp, (p - sp)); + tmp[p - sp] = '\0'; + + if (elen && efound) { + char *c = csv_stringtrim(tmp, enclosed_in, 0); + xfree(tmp); + tmp = c; + } + + if (dfound) { + /* skip over the delimited_by */ + p += dlen; + } else { + /* end of the line */ + p = NULL; + } + + if (enclosedepth != 0) { + warning(MYNAME + ": Warning- Unbalanced Field Enclosures (%s) on line %d\n", + enclosed_in, line_no); + } + return (tmp); +} + +#if CSVFMTS_ENABLED +/*****************************************************************************/ +/* dec_to_intdeg() - convert decimal degrees to integer degreees */ +/* usage: i = dec_to_intdeg(31.1234); */ +/*****************************************************************************/ +static int +dec_to_intdeg(const double d) +{ + int ideg = 0; + + if (d >= 0) { + ideg = (2147483647) - (d * 8388608); + } else { + ideg = (2147483647) - (fabs(d) * 8388608) + 1; + } + + return(ideg); +} + +/*****************************************************************************/ +/* intdeg_to_dec() - convert integer degrees to decimal degreees */ +/* usage: lat = dec_to_intdeg(ilat); */ +/*****************************************************************************/ +static double +intdeg_to_dec(const int ideg) +{ + double d; + + if (ideg >= 0) { + d = ((2147483647) - ideg) / (double)8388608; + } else { + d = ((-2147483647-1) + ideg) / (double)8388608; + } + + return(d); +} + +/*****************************************************************************/ +/* decdir_to_dec() - convert a decimal/direction value into pure decimal. */ +/* usage: lat = decdir_to_dec("W90.1234"); */ +/* lat = decdir_to_dec("30.1234N"); */ +/*****************************************************************************/ +static double +decdir_to_dec(const char * decdir) +{ + char *p; + const char *cp; + double rval; + int sign = 0; + + cp = &decdir[0]; + + if ((*cp == 'W') || (*cp == 'S')) + sign = -1; + else + if ((*cp == 'N') || (*cp == 'E')) + sign = 1; + + rval = sign ? strtod(&decdir[1], &p) : strtod(&decdir[0], &p); + + if (sign == 0) { + if ((*p == 'W') || (*p == 'S')) + sign = -1; + else + if ((*p == 'N') || (*p == 'E')) + sign = 1; + } + + return(rval * sign); +} +#endif + +/***************************************************************************** + * human_to_dec() - convert a "human-readable" lat and/or lon to decimal + * usage: human_to_dec( "N 41° 09.12' W 085° 09.36'", &lat, &lon ); + * human_to_dec( "41 9 5.652 N", &lat, &lon ); + * + * which: 0-no preference 1-prefer lat 2-prefer lon + *****************************************************************************/ + +void +human_to_dec( const char *instr, double *outlat, double *outlon, int which ) +{ + double unk[3] = {999,999,999}; + double lat[3] = {999,999,999}; + double lon[3] = {999,999,999}; + int latsign = 0; + int lonsign = 0; + int unksign = 1; + + const char *cur; + double *numres = unk; + int numind = 0; + char *buff; + + if (strchr(instr, ',') != NULL) { + char *c; + buff = xstrdup(instr); + while ((c = strchr(buff, ','))) *c = '.'; + } + else { + buff = (char *)instr; + } + + cur = buff; + + while ( cur && *cur ) { + switch (*cur) { + case 'n': case 's': case 'N': case 'S': + if ( unk[0] != 999 ) { + numind = 0; + numres = unk; + lat[0] = unk[0]; + lat[1] = unk[1]; + lat[2] = unk[2]; + unk[0] = unk[1] = unk[2] = 999; + } + else { + numres = lat; + numind = 0; + lat[0] = lat[1] = lat[2] = 999; + } + + if ( *cur == 'n' || *cur == 'N' ) + latsign = 1; + else + latsign = -1; + cur++; + break; + case 'w': case 'e': case 'W': case 'E': + if ( unk[0] != 999 ) { + numind = 0; + numres = unk; + lon[0] = unk[0]; + lon[1] = unk[1]; + lon[2] = unk[2]; + unk[0] = unk[1] = unk[2] = 999; + } + else { + numres = lon; + numind = 0; + lon[0] = lon[1] = lon[2] = 999; + } + + if ( *cur == 'e' || *cur == 'E' ) + lonsign = 1; + else + lonsign = -1; + cur++; + break; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case '0': + case '.': case ',': + numres[numind] = atof(cur); + while (cur && *cur && strchr("1234567890.,",*cur)) cur++; + break; + case '-': + unksign = -1; + cur++; + break; + default: + if (numres[numind] != 999) { + numind++; + if ( numind > 2 ) { + numres = unk; + numind = 0; + } + } + cur++; + break; + } + } + + if ( lat[0] == 999 && lon[0] == 999 ) { + if ( which == 1 ) { + lat[0] = unk[0]; lat[1] = unk[1]; lat[2] = unk[2]; + latsign = unksign; + } + else if ( which == 2 ) { + lon[0] = unk[0]; lon[1] = unk[1]; lon[2] = unk[2]; + lonsign = unksign; + } + } + + if ( outlat ) { + if ( lat[0] != 999 ) *outlat = lat[0]; + if ( lat[1] != 999 ) *outlat += lat[1]/60.0; + if ( lat[2] != 999 ) *outlat += lat[2]/3600.0; + if ( *outlat > 360) *outlat = ddmm2degrees(*outlat); /* NMEA style */ + if ( latsign ) *outlat *= latsign; + } + if ( outlon ) { + if ( lon[0] != 999 ) *outlon = lon[0]; + if ( lon[1] != 999 ) *outlon += lon[1]/60.0; + if ( lon[2] != 999 ) *outlon += lon[2]/3600.0; + if ( *outlon > 360) *outlon = ddmm2degrees(*outlon); /* NMEA style */ + if ( lonsign ) *outlon *= lonsign; + } + if (buff != instr) { + xfree(buff); + } +} + +#if CSVFMTS_ENABLED +/* + * dec_to_human - convert decimal degrees to human readable + */ + +void +dec_to_human( char *buff, const char *format, const char *dirs, double val ) +{ + char *subformat = NULL; + const char *formatptr = NULL; + char *percent = NULL; + char *type = NULL; + + int index = 0; + int intvals[3] = {0,0,0}; + double dblvals[3] = {0,0,0}; + int sign = 0; + + sign = (val < 0) ? 0 : 1; + + dblvals[0] = fabs(val); + intvals[0] = (int)dblvals[0]; + dblvals[1] = 60*(dblvals[0]-intvals[0]); + intvals[1] = (int)dblvals[1]; + dblvals[2] = 60*(dblvals[1]-intvals[1]); + intvals[2] = (int)dblvals[2]; + + subformat = xmalloc( strlen(format)+2); + formatptr = format; + + buff[0] = '\0'; + + while ( formatptr && *formatptr ) { + strcpy( subformat, formatptr ); + percent = strchr( subformat, '%' ); + if ( percent ) { + type = percent+1+strcspn( percent+1, "cdiouxXeEfgG%" ); + *(type+1) = '\0'; + switch( *type ) { + case 'c': + sprintf( buff+strlen(buff), subformat, dirs[sign] ); + break; + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + if (index>2) fatal(MYNAME ": too many format specifiers\n"); + sprintf( buff+strlen(buff), subformat, intvals[index]); + index++; + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (index>2) fatal(MYNAME ": too many format specifiers\n"); + sprintf( buff+strlen(buff), subformat, dblvals[index]); + index++; + break; + case '%': + sprintf( buff+strlen(buff), subformat ); + break; + default: + fatal(MYNAME ": invalid format specifier\n"); + break; + + } + } + else { + sprintf( buff+strlen(buff), subformat ); + } + formatptr += strlen(subformat); + } + + xfree(subformat); +} + +/*****************************************************************************/ +/* xcsv_file_init() - prepare xcsv_file for first use. */ +/*****************************************************************************/ +void +xcsv_file_init(void) +{ + memset(&xcsv_file, '\0', sizeof(xcsv_file_t)); + + QUEUE_INIT(&xcsv_file.prologue); + QUEUE_INIT(&xcsv_file.epilogue); + + QUEUE_INIT(&xcsv_file.ifield); + /* ofield is alloced to allow pointing back at ifields + * where applicable. + */ + xcsv_file.ofield = xcalloc(sizeof(queue), 1); + QUEUE_INIT(xcsv_file.ofield); + /* + * Provide a sane default for CSV _files_. + */ + xcsv_file.type = ff_type_file; + + xcsv_file.mkshort_handle = mkshort_new_handle(); + xcsv_file.gps_datum = GPS_DATUM_WGS84; +} + +/*****************************************************************************/ +/* xcsv_ifield_add() - add input field to ifield queue. */ +/* usage: xcsv_ifield_add("DESCRIPTION", "", "%s") */ +/*****************************************************************************/ +void +xcsv_ifield_add(char *key, char *val, char *pfc) +{ + field_map_t *fmp = xcalloc(sizeof(*fmp), 1); + struct xt_mapping *xm = in_word_set(key, strlen(key)); + + fmp->key = key; + fmp->hashed_key = xm ? xm->xt_token : -1; + fmp->val = val; + fmp->printfc = pfc; + + ENQUEUE_TAIL(&xcsv_file.ifield, &fmp->Q); + xcsv_file.ifield_ct++; +} + +/*****************************************************************************/ +/* xcsv_ofield_add() - add output field to ofield queue. */ +/* usage: xcsv_ofield_add("LAT_DECIMAL", "", "%08.5lf") */ +/*****************************************************************************/ +void +xcsv_ofield_add(char *key, char *val, char *pfc, int options) +{ + field_map_t *fmp = xcalloc(sizeof(*fmp), 1); + struct xt_mapping *xm = in_word_set(key, strlen(key)); + + fmp->key = key; + fmp->hashed_key = xm ? xm->xt_token : -1; + fmp->val = val; + fmp->printfc = pfc; + fmp->options = options; + + ENQUEUE_TAIL(xcsv_file.ofield, &fmp->Q); + xcsv_file.ofield_ct++; +} + +/*****************************************************************************/ +/* xcsv_prologue_add() - add prologue line to prologue queue */ +/* usage: xcsv_prologue_add("Four score and seven years ago today,") */ +/*****************************************************************************/ +void +xcsv_prologue_add(char *prologue) +{ + ogue_t* ogp = xcalloc(sizeof(*ogp), 1); + + ogp->val = prologue; + ENQUEUE_TAIL(&xcsv_file.prologue, &ogp->Q); + xcsv_file.prologue_lines++; +} + +/*****************************************************************************/ +/* xcsv_epilogue_add() - add epilogue line to epilogue queue */ +/* usage: xcsv_epilogue_add("shall not perish from the earth.") */ +/*****************************************************************************/ +void +xcsv_epilogue_add(char *epilogue) +{ + ogue_t * ogp = xcalloc(sizeof(*ogp), 1); + + ogp->val = epilogue; + ENQUEUE_TAIL(&xcsv_file.epilogue, &ogp->Q); + xcsv_file.epilogue_lines++; +} + +static +time_t +yyyymmdd_to_time(const char *s) +{ + int t = atol(s); + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + tm.tm_mday = t % 100; + t = t / 100; + tm.tm_mon = t % 100 - 1; + t = t / 100; + tm.tm_year = t - 1900; + return mktime(&tm); +} + + + +/* + * sscanftime - Parse a date buffer using strftime format + */ +static +time_t +sscanftime( const char *s, const char *format, const int gmt ) +{ + struct tm stm; + memset(&stm, 0, sizeof(stm)); + + if ( strptime( s, format, &stm ) ) + { + if ((stm.tm_mday == 0) && (stm.tm_mon == 0) && (stm.tm_year == 0)) { + stm.tm_mday = 1; + stm.tm_mon = 0; + stm.tm_year = 70; + } + stm.tm_isdst = -1; + if (gmt) + return mkgmtime(&stm); + else + return mktime(&stm); + } + // Don't fuss for empty strings. + if (*s) { + warning("date parse of string '%s' with format '%s' failed.\n", + s, format); + } + return 0; +} + +static +time_t +addhms( const char *s, const char *format ) +{ + time_t tt =0; + int hour =0; + int min =0; + int sec =0; + char * ampm = NULL; + int ac; + + ampm = xmalloc( strlen(s) ); + ac = sscanf(s, format, &hour, &min, &sec, &m); + /* If no time format in arg string, assume AM */ + if (ac < 4) { + ampm[0] = 0; + } + if (ac) { + tt = ((tolower(ampm[0])=='P')?43200:0)+3600*hour+60*min+sec; + } + xfree(ampm); + + return tt; +} + +static +int +writetime(char * buff, size_t bufsize, const char * format, time_t t, int gmt ) +{ + static struct tm * stmp; + + if (gmt) + stmp = gmtime(&t); + else + stmp = localtime(&t); + + return strftime(buff, bufsize, format, stmp ); +} + +#if 0 +/* not used */ +static +int +writeisotime(char * buff, size_t bufsize, const char * format, time_t t) +{ + static struct tm * stmp; + char * ibuff = NULL; + int i; + + ibuff = xmalloc(bufsize); + stmp = gmtime(&t); + strftime(ibuff, bufsize, format, stmp ); + i = snprintf(buff, bufsize, format, ibuff ); + xfree(ibuff); + return i; +} +#endif + + +static +int +writehms(char * buff, size_t bufsize, const char * format, time_t t, int gmt ) +{ + static struct tm no_time = {0}; + static struct tm * stmp = &no_time; + + if (gmt) + stmp = gmtime(&t); + else + stmp = localtime(&t); + + if (stmp == NULL) stmp = &no_time; + + return snprintf(buff, bufsize, format, + stmp->tm_hour, stmp->tm_min, stmp->tm_sec, + (stmp->tm_hour>=12?"PM":"AM") ); +} + +static +long +time_to_yyyymmdd(time_t t) +{ + long b; + struct tm *tm = gmtime(&t); + + b = (1900 + tm->tm_year) * 10000 + + (1 + tm->tm_mon) * 100 + + tm->tm_mday; + + return b; +} + +static garmin_fs_t * +gmsd_init(waypoint *wpt) +{ + garmin_fs_t *gmsd = GMSD_FIND(wpt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + return gmsd; +} + +/*****************************************************************************/ +/* xcsv_parse_val() - parse incoming data into the waypt structure. */ +/* usage: xcsv_parse_val("-123.34", *waypt, *field_map) */ +/*****************************************************************************/ +static void +xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) +{ + char *enclosure = ""; + + if (0 == strcmp(fmp->printfc, "\"%s\"")) { + enclosure = "\""; + } + switch(fmp->hashed_key) { + case XT_IGNORE: + /* IGNORE -- Categorically ignore this... */ + break; + case XT_CONSTANT: + /* CONSTANT -- Ignore on Input... */ + break; + case XT_ANYNAME: + /* ANYNAME -- Ignore -- this is output magic. */ + break; + case XT_INDEX: + /* IGNORE -- Calculated Sequence # For Ouput*/ + break; + case XT_SHORTNAME: + wpt->shortname = csv_stringtrim(s, enclosure, 0); + break; + case XT_DESCRIPTION: + wpt->description = csv_stringtrim(s, enclosure, 0); + break; + case XT_NOTES: + wpt->notes = csv_stringtrim(s, "", 0); + break; + case XT_URL: + wpt->url = csv_stringtrim(s, "", 0); + break; + case XT_URL_LINK_TEXT: + wpt->url_link_text = csv_stringtrim(s, "", 0); + break; + case XT_ICON_DESCR: + wpt->icon_descr = csv_stringtrim(s, "", 0); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + break; + + /* LATITUDE CONVERSIONS**************************************************/ + case XT_LAT_DECIMAL: + /* latitude as a pure decimal value */ + wpt->latitude = atof(s); + break; + case XT_LAT_DECIMALDIR: + case XT_LAT_DIRDECIMAL: + /* latitude as a decimal with N/S in it. */ + wpt->latitude = decdir_to_dec(s); + break; + case XT_LAT_INT32DEG: + /* latitude as a 32 bit integer offset */ + wpt->latitude = intdeg_to_dec((int) atof(s)); + break; + case XT_LAT_HUMAN_READABLE: + human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 ); + break; + case XT_LAT_NMEA: + wpt->latitude = ddmm2degrees(atof(s)); + break; + // XT_LAT_10E is handled outside the switch. + /* LONGITUDE CONVERSIONS ***********************************************/ + case XT_LON_DECIMAL: + /* longitude as a pure decimal value */ + wpt->longitude = atof(s); + break; + case XT_LON_DECIMALDIR: + case XT_LON_DIRDECIMAL: + /* longitude as a decimal with N/S in it. */ + wpt->longitude = decdir_to_dec(s); + break; + case XT_LON_INT32DEG: + /* longitude as a 32 bit integer offset */ + wpt->longitude = intdeg_to_dec((int) atof(s)); + break; + case XT_LON_HUMAN_READABLE: + human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 ); + break; + case XT_LON_NMEA: + wpt->longitude = ddmm2degrees(atof(s)); + break; + // case XT_LON_10E is handled outside the switch. + /* LAT AND LON CONVERSIONS ********************************************/ + case XT_LATLON_HUMAN_READABLE: + human_to_dec( s, &wpt->latitude, &wpt->longitude, 0 ); + break; + /* DIRECTIONS **********************************************************/ + case XT_LAT_DIR: + /* latitude N/S. Ignore on input for now */ + break; + case XT_LON_DIR: + /* longitude E/W. Ingore on input for now */ + break; + /* SPECIAL COORDINATES/GRID */ + case XT_MAP_EN_BNG: + parse_coordinates(s, DATUM_OSGB36, grid_bng, + &wpt->latitude, &wpt->longitude, MYNAME); + break; + /* ALTITUDE CONVERSIONS ************************************************/ + case XT_ALT_FEET: + /* altitude in feet as a decimal value */ + wpt->altitude = FEET_TO_METERS(atof(s)); + if (wpt->altitude < unknown_alt + 1) + wpt->altitude = unknown_alt; + break; + case XT_ALT_METERS: + /* altitude in meters as a decimal value */ + wpt->altitude = atof(s); + if (wpt->altitude < unknown_alt + 1) + wpt->altitude = unknown_alt; + break; + + /* PATH CONVERSIONS ************************************************/ + case XT_PATH_SPEED: + WAYPT_SET(wpt, speed, atof(s)); + break; + case XT_PATH_SPEED_KPH: + WAYPT_SET(wpt, speed, KPH_TO_MPS(atof(s))); + break; + case XT_PATH_SPEED_MPH: + WAYPT_SET(wpt, speed, MPH_TO_MPS(atof(s))); + break; + case XT_PATH_SPEED_KNOTS: + WAYPT_SET(wpt, speed, KNOTS_TO_MPS(atof(s))); + break; + case XT_PATH_COURSE: + WAYPT_SET(wpt, course, atof(s)); + break; + + /* TIME CONVERSIONS ***************************************************/ + case XT_EXCEL_TIME: + /* Time as Excel Time */ + wpt->creation_time = EXCEL_TO_TIMET(atof(s)); + break; + case XT_TIMET_TIME: + /* Time as time_t */ + wpt->creation_time = atol(s); + break; + case XT_YYYYMMDD_TIME: + wpt->creation_time = yyyymmdd_to_time(s); + break; + case XT_GMT_TIME: + wpt->creation_time += sscanftime(s, fmp->printfc, 1); + break; + case XT_LOCAL_TIME: + wpt->creation_time += sscanftime(s, fmp->printfc, 0); + break; + /* Useful when time and date are in separate fields + GMT / Local offset is handled by the two cases above */ + case XT_HMSG_TIME: + case XT_HMSL_TIME: + wpt->creation_time += addhms(s, fmp->printfc); + break; + case XT_ISO_TIME: + case XT_ISO_TIME_MS: + wpt->creation_time = xml_parse_time(s, &wpt->microseconds); + break; + case XT_GEOCACHE_LAST_FOUND: + wpt->gc_data.last_found = yyyymmdd_to_time(s); + break; + + /* GEOCACHING STUFF ***************************************************/ + case XT_GEOCACHE_DIFF: + /* Geocache Difficulty as an int */ + wpt->gc_data.diff = atof(s) * 10; + break; + case XT_GEOCACHE_TERR: + /* Geocache Terrain as an int */ + wpt->gc_data.terr = atof(s) * 10; + break; + case XT_GEOCACHE_TYPE: + /* Geocache Type */ + wpt->gc_data.type = gs_mktype(s); + break; + case XT_GEOCACHE_CONTAINER: + wpt->gc_data.container = gs_mkcont(s); + break; + case XT_GEOCACHE_HINT: + wpt->gc_data.hint = csv_stringtrim(s, "", 0); + break; + case XT_GEOCACHE_PLACER: + wpt->gc_data.placer = csv_stringtrim(s, "", 0); + break; + case XT_GEOCACHE_ISAVAILABLE: + if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "False") == 0 ) + wpt->gc_data.is_available = status_false; + else if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "True") == 0 ) + wpt->gc_data.is_available = status_true; + else + wpt->gc_data.is_available = status_unknown; + break; + case XT_GEOCACHE_ISARCHIVED: + if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "False") == 0 ) + wpt->gc_data.is_archived = status_false; + else if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "True") == 0 ) + wpt->gc_data.is_archived = status_true; + else + wpt->gc_data.is_archived = status_unknown; + break; + + /* GPS STUFF *******************************************************/ + case XT_GPS_HDOP: + wpt->hdop = atof(s); + break; + case XT_GPS_VDOP: + wpt->vdop = atof(s); + break; + case XT_GPS_PDOP: + wpt->pdop = atof(s); + break; + case XT_GPS_SAT: + wpt->sat = atoi(s); + break; + case XT_GPS_FIX: + wpt->fix = atoi(s)-1; + if ( wpt->fix < fix_2d) { + if (!case_ignore_strcmp(s, "none")) + wpt->fix = fix_none; + else if (!case_ignore_strcmp(s, "dgps")) + wpt->fix = fix_dgps; + else if (!case_ignore_strcmp(s, "pps")) + wpt->fix = fix_pps; + else + wpt->fix = fix_unknown; + } + break; + /* Tracks and routes *********************************************/ + case XT_ROUTE_NAME: + if (csv_route) csv_route->rte_name = csv_stringtrim(s, enclosure, 0); + break; + case XT_TRACK_NAME: + if (csv_track) csv_track->rte_name = csv_stringtrim(s, enclosure, 0); + break; + + /* OTHER STUFF ***************************************************/ + case XT_PATH_DISTANCE_MILES: + /* Ignored on input */ + break; + case XT_HEART_RATE: + wpt->heartrate = atoi(s); + break; + case XT_CADENCE: + wpt->cadence = atoi(s); + break; + case XT_PATH_DISTANCE_KM: + /* Ignored on input */ + break; + /* GMSD ****************************************************************/ + case XT_COUNTRY: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(country, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_STATE: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(state, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_CITY: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(city, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_STREET_ADDR: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(addr, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_POSTAL_CODE: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(postal_code, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_PHONE_NR: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(phone_nr, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_FACILITY: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(facility, csv_stringtrim(s, enclosure, 0)); + } + break; + case -1: + if (strncmp(fmp->key, "LON_10E", 7) == 0) { + wpt->longitude = atof(s) / pow((double)10, atof(fmp->key+7)); + } else + if (strncmp(fmp->key, "LAT_10E", 7) == 0) { + wpt->latitude = atof(s) / pow((double)10, atof(fmp->key+7)); + } else { + warning( MYNAME ": Unknown style directive: %s\n", fmp->key); + } + break; + + default: + fatal("This can't happen\n"); + break; + } +} + +/*****************************************************************************/ +/* xcsv_data_read() - read input file, parsing lines, fields and handling */ +/* any data conversion (the input meat) */ +/*****************************************************************************/ +void +xcsv_data_read(void) +{ + char *buff; + char *s; + waypoint *wpt_tmp; + int linecount = 0; + queue *elem, *tmp; + field_map_t *fmp; + ogue_t *ogp; + route_head *rte = NULL; + route_head *trk = NULL; + + csv_route = csv_track = NULL; + if (xcsv_file.datatype == trkdata) { + csv_track = trk; + } else + if (xcsv_file.datatype == rtedata) { + csv_route = rte; + } + + while ((buff = gbfgetstr(xcsv_file.xcsvfp))) { + linecount++; + /* Whack trailing space; leading space may matter if our field sep + * is whitespace and we have leading whitespace. + */ + rtrim(buff); + + /* skip over x many lines on the top for the prologue... */ + if ((xcsv_file.prologue_lines) && ((linecount - 1) < + xcsv_file.prologue_lines)) { + continue; + } + + /* We should skip over epilogue lines also. Since we don't want to + * pre-read the file to know how many data lines we should be seeing, + * we take this cheap shot at the data and cross our fingers. + */ + + QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { + ogp = (ogue_t *) elem; + if (strncmp(buff, ogp->val, strlen(ogp->val)) == 0) { + buff[0] = '\0'; + break; + } + } + + if (strlen(buff)) { + wpt_tmp = waypt_new(); + + s = buff; + s = csv_lineparse(s, xcsv_file.field_delimiter, "", linecount); + + if (QUEUE_EMPTY(&xcsv_file.ifield)) { + fatal(MYNAME ": attempt to read, but style '%s' has no IFIELDs in it.\n", xcsv_file.description? xcsv_file.description : "unknown"); + } + + /* reset the ifield queue */ + elem = QUEUE_FIRST(&xcsv_file.ifield); + + /* now rip the line apart, advancing the queue for each tear + * off the beginning of buff since there's no index into queue. + */ + while (s) { + fmp = (field_map_t *) elem; + xcsv_parse_val(s, wpt_tmp, fmp); + + elem = QUEUE_NEXT(elem); + + if (elem == &xcsv_file.ifield) { + /* we've wrapped the queue. so stop parsing! */ + while (s) { + s=csv_lineparse(NULL, "\xff","",linecount); + } + break; + } + + s = csv_lineparse(NULL, xcsv_file.field_delimiter, "", + linecount); + } + if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { + double alt; + GPS_Math_Known_Datum_To_WGS84_M(wpt_tmp->latitude, wpt_tmp->longitude, 0.0, + &wpt_tmp->latitude, &wpt_tmp->longitude, &alt, xcsv_file.gps_datum); + } + switch(xcsv_file.datatype) { + case 0: + case wptdata: + waypt_add(wpt_tmp); + break; + case trkdata: + if (trk == NULL) { + trk = route_head_alloc(); + track_add_head(trk); + } + track_add_wpt(trk, wpt_tmp); + break; + case rtedata: + if (rte == NULL) { + rte = route_head_alloc(); + route_add_head(rte); + } + route_add_wpt(rte, wpt_tmp); + break; + default: ; + } + } + + } +} + +static void +xcsv_resetpathlen(const route_head *head) +{ + pathdist = 0; + oldlat = 999; + oldlon = 999; + csv_route = csv_track = NULL; + switch (xcsv_file.datatype) { + case trkdata: + csv_track = (route_head *) head; + break; + case rtedata: + csv_route = (route_head *) head; + break; + default: + break; + } +} + +/*****************************************************************************/ +/* xcsv_waypt_pr() - write output file, handling output conversions */ +/* (the output meat) */ +/*****************************************************************************/ +static void +xcsv_waypt_pr(const waypoint *wpt) +{ + char buff[1024]; + char *shortname = NULL; + char *description = NULL; + char * anyname = NULL; + char * write_delimiter; + int i; + field_map_t *fmp; + queue *elem, *tmp; + double latitude, longitude; + + buff[0] = '\0'; + + if ( oldlon < 900 ) { + pathdist += radtomiles(gcdist(RAD(oldlat),RAD(oldlon), + RAD(wpt->latitude),RAD(wpt->longitude))); + } + longitude = oldlon = wpt->longitude; + latitude = oldlat = wpt->latitude; + + if (xcsv_file.field_delimiter && strcmp(xcsv_file.field_delimiter, "\\w") == 0) + write_delimiter = " "; + else + write_delimiter = xcsv_file.field_delimiter; + + if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) + shortname = mkshort_from_wpt(xcsv_file.mkshort_handle, wpt); + else + shortname = csv_stringclean(wpt->description, xcsv_file.badchars); + } else { + /* no shortname available -- let shortname default on output */ + } + } else{ + shortname = csv_stringclean(wpt->shortname, xcsv_file.badchars); + } + + if (! wpt->description) { + if (shortname) { + description = csv_stringclean(shortname, xcsv_file.badchars); + } else { + /* no description -- let description default on output */ + } + } else { + description = csv_stringclean(wpt->description, xcsv_file.badchars); + } + + if (prefer_shortnames) { + if (description) { + xfree(description); + } + description = shortname; + } else if (description) { + char *odesc = description; + description = xstrdup(odesc); + xfree(odesc); + } + if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { + double alt; + GPS_Math_WGS84_To_Known_Datum_M(latitude, longitude, 0.0, + &latitude, &longitude, &alt, xcsv_file.gps_datum); + } + + i = 0; + QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { + char *obuff; + double lat = latitude; + double lon = longitude; + /* + * A klunky concept. This should evaluate to true for any + * field if we think we don't have realistic value for it. + * This is used by the 'optional' attribute for suppressing + * fields on output. + */ + int field_is_unknown = 0; + + fmp = (field_map_t *) elem; + + if ((i != 0) && !(fmp->options & OPTIONS_NODELIM)) + gbfprintf (xcsv_file.xcsvfp, write_delimiter); + + if (fmp->options & OPTIONS_ABSOLUTE) { + lat = fabs(lat); + lon = fabs(lon); + } + + i++; +#define writebuff(b, fmt, data) snprintf(b, sizeof(b), fmt, data) + switch(fmp->hashed_key) { + case XT_IGNORE: + /* IGNORE -- Write the char printf conversion */ + writebuff(buff, fmp->printfc, ""); + break; + case XT_INDEX: + writebuff(buff, fmp->printfc, waypt_out_count + atoi(fmp->val)); + break; + case XT_CONSTANT: { + const char *cp = xcsv_get_char_from_constant_table(fmp->val); + if (cp) { + writebuff(buff, fmp->printfc, cp); + } else { + writebuff(buff, fmp->printfc, fmp->val); + } + } + break; + case XT_SHORTNAME: + writebuff(buff, fmp->printfc, + (shortname && *shortname) ? shortname : fmp->val); + break; + case XT_ANYNAME: + if (wpt->shortname) { + anyname = xstrdup(wpt->shortname); + } else + if (wpt->description) { + anyname = mkshort(xcsv_file.mkshort_handle, wpt->description); + } else + if (wpt->notes) { + anyname = xstrdup(wpt->notes); + } else + anyname = xstrdup(fmp->val); + + if ((anyname) && (global_opts.synthesize_shortnames)) { + anyname = xstrdup(shortname); + } + + writebuff(buff, fmp->printfc, anyname); + + xfree(anyname); + break; + case XT_DESCRIPTION: + writebuff(buff, fmp->printfc, + (description && *description) ? description : fmp->val); + break; + case XT_NOTES: + writebuff(buff, fmp->printfc, + (wpt->notes && *wpt->notes) ? wpt->notes : fmp->val); + break; + case XT_URL: { + int off = 0; + if (xcsv_urlbase) { + strcpy(buff, xcsv_urlbase); + off = strlen(xcsv_urlbase); + } + if (wpt->url) + snprintf(buff + off, sizeof(buff) - off, fmp->printfc, wpt->url); + else + strcpy(buff, (fmp->val && *fmp->val) ? fmp->val : "\"\""); + } + break; + case XT_URL_LINK_TEXT: + snprintf(buff, sizeof(buff), fmp->printfc, + (wpt->url_link_text && *wpt->url_link_text) ? wpt->url_link_text : fmp->val); + break; + case XT_ICON_DESCR: + writebuff(buff, fmp->printfc, + (wpt->icon_descr && *wpt->icon_descr) ? + wpt->icon_descr : fmp->val); + break; + + /* LATITUDE CONVERSION***********************************************/ + case XT_LAT_DECIMAL: + /* latitude as a pure decimal value */ + writebuff(buff, fmp->printfc, lat); + break; + case XT_LAT_DECIMALDIR: + /* latitude as a decimal value with N/S after it */ + snprintf(buff, sizeof(buff), fmp->printfc, fabs(lat), + LAT_DIR(lat)); + break; + case XT_LAT_DIRDECIMAL: + /* latitude as a decimal value with N/S before it */ + snprintf(buff, sizeof(buff), fmp->printfc, + LAT_DIR(lat), + fabs(lat)); + break; + case XT_LAT_INT32DEG: + /* latitude as an integer offset from 0 degrees */ + writebuff(buff, fmp->printfc, + dec_to_intdeg(lat)); + break; + case XT_LAT_HUMAN_READABLE: + dec_to_human( buff, fmp->printfc, "SN", lat ); + break; + case XT_LAT_NMEA: + writebuff(buff, fmp->printfc, degrees2ddmm(lat)); + break; + // case XT_LAT_10E is handled outside the switch. + /* LONGITUDE CONVERSIONS*********************************************/ + case XT_LON_DECIMAL: + /* longitude as a pure decimal value */ + writebuff(buff, fmp->printfc, lon); + break; + case XT_LON_DECIMALDIR: + /* latitude as a decimal value with N/S after it */ + snprintf(buff, sizeof(buff), fmp->printfc, + fabs(lon), + LON_DIR(lon)); + break; + case XT_LON_DIRDECIMAL: + /* latitude as a decimal value with N/S before it */ + snprintf(buff, sizeof(buff), fmp->printfc, + LON_DIR(lon), + fabs(lon)); + break; + case XT_LON_INT32DEG: + /* longitudee as an integer offset from 0 degrees */ + writebuff(buff, fmp->printfc, + dec_to_intdeg(lon)); + break; + case XT_LON_HUMAN_READABLE: + dec_to_human( buff, fmp->printfc, "WE", lon ); + break; + case XT_LATLON_HUMAN_READABLE: + dec_to_human( buff, fmp->printfc, "SN", lat ); + if ( !isspace(buff[strlen(buff)])) strcat( buff, " " ); + dec_to_human( buff+strlen(buff), fmp->printfc, "WE", + lon ); + break; + case XT_LON_NMEA: + writebuff(buff, fmp->printfc, degrees2ddmm(lon)); + break; + // case XT_LON_10E is handled outside the switch. + /* DIRECTIONS *******************************************************/ + case XT_LAT_DIR: + /* latitude N/S as a char */ + writebuff(buff, fmp->printfc, + LAT_DIR(lat)); + break; + case XT_LON_DIR: + /* longitude E/W as a char */ + writebuff(buff, fmp->printfc, + LON_DIR(lon)); + break; + + /* SPECIAL COORDINATES */ + case XT_MAP_EN_BNG: { + char map[3]; + double north, east; + if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map)) + fatal(MYNAME ": Position (%.5f/%.5f) outside of BNG.\n", + wpt->latitude, wpt->longitude); + snprintf(buff, sizeof(buff), fmp->printfc, map, (int)(east + 0.5), (int)(north + 0.5)); + } + break; + + /* ALTITUDE CONVERSIONS**********************************************/ + case XT_ALT_FEET: + /* altitude in feet as a decimal value */ + writebuff(buff, fmp->printfc, + METERS_TO_FEET(wpt->altitude)); + break; + case XT_ALT_METERS: + /* altitude in meters as a decimal value */ + writebuff(buff, fmp->printfc, + wpt->altitude); + break; + + /* DISTANCE CONVERSIONS**********************************************/ + case XT_PATH_DISTANCE_MILES: + /* path (route/track) distance in miles */ + writebuff( buff, fmp->printfc, pathdist ); + break; + case XT_PATH_DISTANCE_KM: + /* path (route/track) distance in */ + writebuff( buff, fmp->printfc, pathdist * 5280*12*2.54/100/1000 ); + break; + case XT_PATH_SPEED: + writebuff( buff, fmp->printfc, wpt->speed ); + break; + case XT_PATH_SPEED_KPH: + writebuff( buff, fmp->printfc, MPS_TO_KPH(wpt->speed)); + break; + case XT_PATH_SPEED_MPH: + writebuff( buff, fmp->printfc, MPS_TO_MPH(wpt->speed)); + break; + case XT_PATH_SPEED_KNOTS: + writebuff( buff, fmp->printfc, MPS_TO_KNOTS(wpt->speed)); + break; + case XT_PATH_COURSE: + writebuff( buff, fmp->printfc, wpt->course ); + break; + + /* HEART RATE CONVERSION***********************************************/ + case XT_HEART_RATE: + writebuff(buff, fmp->printfc, wpt->heartrate); + break; + /* CADENCE CONVERSION***********************************************/ + case XT_CADENCE: + writebuff(buff, fmp->printfc, wpt->cadence); + break; + /* TIME CONVERSIONS**************************************************/ + case XT_EXCEL_TIME: + /* creation time as an excel (double) time */ + writebuff(buff, fmp->printfc, TIMET_TO_EXCEL(wpt->creation_time)); + break; + case XT_TIMET_TIME: + /* time as a time_t variable */ + writebuff(buff, fmp->printfc, wpt->creation_time); + break; + case XT_YYYYMMDD_TIME: + writebuff(buff, fmp->printfc, time_to_yyyymmdd(wpt->creation_time)); + break; + case XT_GMT_TIME: + writetime(buff, sizeof buff, fmp->printfc, wpt->creation_time, 1 ); + break; + case XT_LOCAL_TIME: + writetime(buff, sizeof buff, fmp->printfc, wpt->creation_time, 0 ); + break; + case XT_HMSG_TIME: + writehms(buff, sizeof buff, fmp->printfc, wpt->creation_time, 1 ); + break; + case XT_HMSL_TIME: + writehms(buff, sizeof buff, fmp->printfc, wpt->creation_time, 0 ); + break; + case XT_ISO_TIME: + writetime(buff, sizeof buff, "%Y-%m-%dT%H:%M:%SZ", wpt->creation_time, 1 ); + break; + case XT_ISO_TIME_MS: + xml_fill_in_time(buff, wpt->creation_time, + wpt->microseconds, XML_LONG_TIME); + break; + case XT_GEOCACHE_LAST_FOUND: + writebuff(buff, fmp->printfc, time_to_yyyymmdd(wpt->gc_data.last_found)); + break; + + /* GEOCACHE STUFF **************************************************/ + case XT_GEOCACHE_DIFF: + /* Geocache Difficulty as a double */ + writebuff(buff, fmp->printfc, wpt->gc_data.diff / 10.0); + field_is_unknown = !wpt->gc_data.diff; + break; + case XT_GEOCACHE_TERR: + /* Geocache Terrain as a double */ + writebuff(buff, fmp->printfc, wpt->gc_data.terr / 10.0); + field_is_unknown = !wpt->gc_data.terr; + break; + case XT_GEOCACHE_CONTAINER: + /* Geocache Container */ + writebuff(buff, fmp->printfc, gs_get_container(wpt->gc_data.container)); + field_is_unknown = wpt->gc_data.container == gc_unknown; + break; + case XT_GEOCACHE_TYPE: + /* Geocache Type */ + writebuff(buff, fmp->printfc, gs_get_cachetype(wpt->gc_data.type)); + field_is_unknown = wpt->gc_data.type == gt_unknown; + break; + case XT_GEOCACHE_HINT: + writebuff(buff, fmp->printfc, NONULL(wpt->gc_data.hint)); + field_is_unknown = !wpt->gc_data.hint; + break; + case XT_GEOCACHE_PLACER: + writebuff(buff, fmp->printfc, NONULL(wpt->gc_data.placer)); + field_is_unknown = !wpt->gc_data.placer; + break; + case XT_GEOCACHE_ISAVAILABLE: + if ( wpt->gc_data.is_available == status_false ) + writebuff(buff, fmp->printfc, "False"); + else if ( wpt->gc_data.is_available == status_true ) + writebuff(buff, fmp->printfc, "True"); + else + writebuff(buff, fmp->printfc, "Unknown"); + break; + case XT_GEOCACHE_ISARCHIVED: + if ( wpt->gc_data.is_archived == status_false ) + writebuff(buff, fmp->printfc, "False"); + else if ( wpt->gc_data.is_archived == status_true ) + writebuff(buff, fmp->printfc, "True"); + else + writebuff(buff, fmp->printfc, "Unknown"); + break; + /* Tracks and Routes ***********************************************/ + case XT_TRACK_NAME: + if (csv_track) writebuff(buff, fmp->printfc, NONULL(csv_track->rte_name)); + break; + case XT_ROUTE_NAME: + if (csv_route) writebuff(buff, fmp->printfc, NONULL(csv_route->rte_name)); + break; + + /* GPS STUFF *******************************************************/ + case XT_GPS_HDOP: + writebuff(buff, fmp->printfc, wpt->hdop); + field_is_unknown = !wpt->hdop; + break; + case XT_GPS_VDOP: + writebuff(buff, fmp->printfc, wpt->vdop); + field_is_unknown = !wpt->vdop; + break; + case XT_GPS_PDOP: + writebuff(buff, fmp->printfc, wpt->pdop); + field_is_unknown = !wpt->pdop; + break; + case XT_GPS_SAT: + writebuff(buff, fmp->printfc, wpt->sat); + field_is_unknown = !wpt->sat; + break; + case XT_GPS_FIX: { + char *fix = NULL; + switch (wpt->fix) { + case fix_unknown: + field_is_unknown = 1; + fix = "Unknown"; + break; + case fix_none: + fix = "None"; + break; + case fix_2d: + fix = "2d"; + break; + case fix_3d: + fix = "3d"; + break; + case fix_dgps: + fix = "dgps"; + break; + case fix_pps: + fix = "pps"; + break; + } + writebuff(buff, fmp->printfc, fix); + } + break; + /* GMSD ************************************************************/ + case XT_COUNTRY: { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(country, "")); + } + break; + case XT_STATE: { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(state, "")); + } + break; + case XT_CITY: { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(city, "")); + } + break; + case XT_POSTAL_CODE: { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(postal_code, "")); + } + break; + case XT_STREET_ADDR: { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(addr, "")); + } + break; + case XT_PHONE_NR: { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(phone_nr, "")); + } + break; + case XT_FACILITY: { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(facility, "")); + } + break; + case -1: + if (strncmp(fmp->key, "LON_10E", 7) == 0) { + writebuff(buff, fmp->printfc, lon * pow((double)10, atof(fmp->key+7))); + } else + if (strncmp(fmp->key, "LAT_10E", 7) == 0) { + writebuff(buff, fmp->printfc, lat * pow((double)10, atof(fmp->key+7))); + } + break; + default: + warning( MYNAME ": Unknown style directive: %s\n", fmp->key); + break; + } + obuff = csv_stringclean(buff, xcsv_file.badchars); + + if (field_is_unknown && fmp->options & OPTIONS_OPTIONAL) { + goto next; + } + + + /* As a special case (pronounced "horrible hack") we allow + * ""%s"" to smuggle bad characters through. + */ + if (0 == strcmp(fmp->printfc, "\"%s\"")) { + gbfprintf (xcsv_file.xcsvfp, "\"%s\"", obuff); + } else { + gbfprintf (xcsv_file.xcsvfp, "%s", obuff); + } + +next: + xfree(obuff); + } + + gbfprintf (xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); + + if (description && description != shortname) + xfree(description); + + if (shortname) + xfree(shortname); + + /* increment the index counter */ + waypt_out_count++; +} + +static void +xcsv_noop(const route_head *wp) +{ + /* no-op */ +} + +/*****************************************************************************/ +/* xcsv_data_write(void) - write prologues, spawn the output loop, and write */ +/* epilogues. */ +/*****************************************************************************/ +void +xcsv_data_write(void) +{ + queue *elem, *tmp; + ogue_t *ogp; + time_t time; + struct tm tm; + char tbuf[32]; + + /* reset the index counter */ + waypt_out_count = 0; + + time = gpsbabel_time; + if (time == 0) /* testo script ? */ + tm = *gmtime(&time); + else + tm = *localtime(&time); + + /* output prologue lines, if any. */ + QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { + char *cout, *ctmp; + ogp = (ogue_t *) elem; + + cout = xstrdup((ogp->val) ? ogp->val : ""); + + while ((ctmp = strsub(cout, "__FILE__", xcsv_file.fname))) { + xfree(cout); + cout = ctmp; + } + + while ((ctmp = strsub(cout, "__VERSION__", (time == 0) ? "" : gpsbabel_version))) { + xfree(cout); + cout = ctmp; + } + + while (strstr(cout, "__DATE__")) { + strftime(tbuf, sizeof(tbuf), "%m/%d/%Y", &tm); + ctmp = strsub(cout, "__DATE__", tbuf); + xfree(cout); + cout = ctmp; + } + + while (strstr(cout, "__TIME__")) { + strftime(tbuf, sizeof(tbuf), "%H:%S:%M", &tm); + ctmp = strsub(cout, "__TIME__", tbuf); + xfree(cout); + cout = ctmp; + } + + while (strstr(cout, "__DATE_AND_TIME__")) { + strftime(tbuf, sizeof(tbuf), "%a %b %d %H:%M:%S %Y", &tm); + ctmp = strsub(cout, "__DATE_AND_TIME__", tbuf); + xfree(cout); + cout = ctmp; + } + + gbfprintf(xcsv_file.xcsvfp, "%s", cout); + xfree(cout); + gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); + } + + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) + waypt_disp_all(xcsv_waypt_pr); + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == rtedata)) + route_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == trkdata)) + track_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); + + /* output epilogue lines, if any. */ + QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { + ogp = (ogue_t *) elem; + gbfprintf (xcsv_file.xcsvfp, "%s%s", ogp->val, xcsv_file.record_delimiter); + } +} +#endif diff --git a/csv_util.h b/csv_util.h new file mode 100644 index 000000000..ab29e3771 --- /dev/null +++ b/csv_util.h @@ -0,0 +1,146 @@ +/* + Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +/* function prototypes */ + +char * +#ifndef DEBUG_MEM +csv_stringtrim(const char *string, const char *enclosure, int strip_max); +#else +CSV_STRINGTRIM(const char *string, const char *enclosure, int strip_max, DEBUG_PARAMS); +#define csv_stringtrim( s, e,m ) CSV_STRINGTRIM( s, e, m, __FILE__, __LINE__) +#endif + +char * +csv_lineparse(const char *stringstart, const char *delimited_by, const char *enclosed_in, const int line_no); + +void +human_to_dec( const char *instr, double *outlat, double *outlon, int which ); + +char * +#ifndef DEBUG_MEM +csv_stringclean(const char *string, const char *chararray); +#else +CSV_STRINGCLEAN(const char *string, const char *chararray,DEBUG_PARAMS); +#define csv_stringclean(s,c) CSV_STRINGCLEAN(s,c,__FILE__,__LINE__) +#endif + +void +xcsv_data_read(void); + +void +xcsv_data_write(void); + +void +xcsv_file_init(void); + +void +xcsv_prologue_add(char *); + +void +xcsv_epilogue_add(char *); + +void +xcsv_ifield_add(char *, char *, char *); + +void +xcsv_ofield_add(char *, char *, char *, int options); + +void +xcsv_destroy_style(void); + +const char * +xcsv_get_char_from_constant_table(char *key); + +/****************************************************************************/ +/* types required for various xcsv functions */ +/****************************************************************************/ + +/* something to map fields to waypts */ +#define OPTIONS_NODELIM 1 +#define OPTIONS_ABSOLUTE 2 +#define OPTIONS_OPTIONAL 3 +typedef struct field_map { + queue Q; + char * key; + char * val; + char * printfc; + int hashed_key; + int options; +} field_map_t; + +/* a queuing struct for prologues / epilogues */ +typedef struct ogue { + queue Q; + char * val; +} ogue_t; + +/* something to map config file constants to chars */ +typedef struct char_map { + const char * key; + const char * chars; +} char_map_t; + +/* + * a type describing all the wonderful elements of xcsv files, in a + * nutshell. + */ +typedef struct { + int is_internal; /* bool - is internal (1) or parsed (0) */ + + int prologue_lines; /* # of lines to ignore at top of the file */ + int epilogue_lines; /* # of lines to ignore at bottom of file */ + + /* header lines for writing at the top of the file. */ + queue prologue; + + /* footer lines for writing at the bottom of the file. */ + queue epilogue; + + char * field_delimiter; /* comma, quote, etc... */ + char * record_delimiter; /* newline, c/r, etc... */ + + char * badchars; /* characters we never write to output */ + + queue ifield; /* input field mapping */ + queue * ofield; /* output field mapping */ + + int ifield_ct; /* actual # of ifields */ + int ofield_ct; /* actual # of ofields */ + + gbfile * xcsvfp; /* ptr to current *open* data file */ + char * fname; /* ptr to filename of above. */ + + char * description; /* Description for help text */ + char * extension; /* preferred filename extension (for wrappers)*/ + + short_handle mkshort_handle;/* handle for mkshort() */ + ff_type type; /* format type for GUI wrappers. */ + + int gps_datum; /* result of GPS_Lookup_Datum_Index */ + gpsdata_type datatype; /* can be wptdata, rtedata or trkdata */ + /* ... or ZERO to keep the old behaviour */ + +} xcsv_file_t; + + +/****************************************************************************/ +/* obligatory global struct */ +/****************************************************************************/ +extern xcsv_file_t xcsv_file; diff --git a/defs.h b/defs.h new file mode 100644 index 000000000..40b487eef --- /dev/null +++ b/defs.h @@ -0,0 +1,981 @@ +/* + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#ifndef gpsbabel_defs_h_included +#define gpsbabel_defs_h_included +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "queue.h" +#include "gbtypes.h" +#if HAVE_LIBZ +#include +#elif !ZLIB_INHIBITED +#include "zlib/zlib.h" +#endif +#include "gbfile.h" +#include "cet.h" +#include "cet_util.h" +#include "inifile.h" + +// Turn on Unicode in expat? +#ifdef _UNICODE +# define XML_UNICODE +#endif + +/* + * Amazingly, this constant is not specified in the standard... + */ +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +#define FEET_TO_METERS(feetsies) ((feetsies) * 0.3048) +#define METERS_TO_FEET(meetsies) ((meetsies) * 3.2808399) + +#define NMILES_TO_METERS(a) ((a) * 1852.0) /* nautical miles */ +#define MILES_TO_METERS(a) ((a) * 1609.344) +#define METERS_TO_MILES(a) ((a) / 1609.344) +#define FATHOMS_TO_METERS(a) ((a) * 1.8288) + +#define CELSIUS_TO_FAHRENHEIT(a) (((a) * 1.8) + 32) +#define FAHRENHEIT_TO_CELSIUS(a) (((a) - 32) / 1.8) + +#define SECONDS_PER_HOUR (60L*60) +#define SECONDS_PER_DAY (24L*60*60) + +/* meters/second to kilometers/hour */ +#define MPS_TO_KPH(a) ((double)(a)*SECONDS_PER_HOUR/1000) + +/* meters/second to miles/hour */ +#define MPS_TO_MPH(a) (METERS_TO_MILES(a) * SECONDS_PER_HOUR) + +/* meters/second to knots */ +#define MPS_TO_KNOTS(a) (MPS_TO_KPH((a)/1.852)) + +/* kilometers/hour to meters/second */ +#define KPH_TO_MPS(a) ((double)(a)*1000/SECONDS_PER_HOUR) + +/* miles/hour to meters/second */ +#define MPH_TO_MPS(a) (MILES_TO_METERS(a) / SECONDS_PER_HOUR) + +/* knots to meters/second */ +#define KNOTS_TO_MPS(a) (KPH_TO_MPS((a)*1.852)) + +/* + * Snprintf is in SUS (so it's in most UNIX-like substance) and it's in + * C99 (albeit with slightly different semantics) but it isn't in C89. + * This tweaks allows us to use snprintf on the holdout. + */ +#if __WIN32__ +# define snprintf _snprintf +# define vsnprintf _vsnprintf +# ifndef fileno +# define fileno _fileno +# endif +# define strdup _strdup +#endif + +/* Turn off numeric conversion warning */ +#if __WIN32__ +# if _MSC_VER +# pragma warning(disable:4244) +# endif +# define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/* Pathname separator character */ +#if __WIN32__ +# define GB_PATHSEP '\\' +#else +# define GB_PATHSEP '/' +#endif + +/* + * Toss in some GNU C-specific voodoo for checking. + */ +#if __GNUC__ +# define PRINTFLIKE(x,y) __attribute__ ((__format__ (__printf__, (x), (y)))) +# define NORETURN void __attribute__ ((__noreturn__)) +#else +# define PRINTFLIKE(x,y) +# define NORETURN void +#endif + +#ifndef HAVE_VA_COPY +# ifdef __va_copy +# define va_copy(DEST,SRC) __va_copy((DEST),(SRC)) +# else +# ifdef HAVE_VA_LIST_AS_ARRAY +# define va_copy(DEST,SRC) (*(DEST) = *(SRC)) +# else +# define va_copy(DEST,SRC) ((DEST) = (SRC)) +# endif +# endif +#endif + +/* + * Common definitions. There should be no protocol or file-specific + * data in this file. + */ +#define BASE_STRUCT(memberp, struct_type, member_name) \ + ((struct_type *)((char *)(memberp) - offsetof(struct_type, member_name))) + +typedef enum { + fix_unknown=-1, + fix_none=0, + fix_2d=1, + fix_3d, + fix_dgps, + fix_pps +} fix_type; + +typedef enum { + status_unknown=0, + status_true, + status_false +} status_type; + +/* + * Define globally on which kind of data gpsbabel is working. + * Important for "file types" that are essentially a communication + * protocol for a receiver, like the Magellan serial data. + */ +typedef enum { + trkdata = 1 , + wptdata, + rtedata, + posndata +} gpsdata_type; + +#define NOTHINGMASK 0 +#define WPTDATAMASK 1 +#define TRKDATAMASK 2 +#define RTEDATAMASK 4 +#define POSNDATAMASK 8 + +/* mask objective testing */ +#define doing_nothing (global_opts.masked_objective == NOTHINGMASK) +#define doing_wpts ((global_opts.masked_objective & WPTDATAMASK) == WPTDATAMASK) +#define doing_trks ((global_opts.masked_objective & TRKDATAMASK) == TRKDATAMASK) +#define doing_rtes ((global_opts.masked_objective & RTEDATAMASK) == RTEDATAMASK) +#define doing_posn ((global_opts.masked_objective & POSNDATAMASK) == POSNDATAMASK) + +typedef struct { + int synthesize_shortnames; + int debug_level; + gpsdata_type objective; + unsigned int masked_objective; + int verbose_status; /* set by GUI wrappers for status */ + int smart_icons; + int smart_names; + cet_cs_vec_t *charset; + char *charset_name; + inifile_t *inifile; +} global_options; + +extern global_options global_opts; +extern const char gpsbabel_version[]; +extern time_t gpsbabel_now; /* gpsbabel startup-time; initialized in main.c with time() */ +extern time_t gpsbabel_time; /* gpsbabel startup-time; initialized in main.c with current_time(), ! ZERO within testo ! */ +extern int geocaches_present; + +#define MILLI_TO_MICRO(t) (t * 1000) /* Milliseconds to Microseconds */ +#define MICRO_TO_MILLI(t) (t / 1000) /* Microseconds to Milliseconds*/ +#define CENTI_TO_MICRO(t) (t * 10000) /* Centiseconds to Microseconds */ +#define MICRO_TO_CENTI(t) (t / 10000) /* Centiseconds to Microseconds */ + +/* Short or Long XML Times */ +#define XML_SHORT_TIME 1 +#define XML_LONG_TIME 2 + +/* + * Extended data if waypoint happens to represent a geocache. This is + * totally voluntary data... + */ + +typedef enum { + gt_unknown = 0 , + gt_traditional, + gt_multi, + gt_virtual, + gt_letterbox, + gt_event, + gt_suprise, + gt_webcam, + gt_earth, + gt_locationless, + gt_benchmark, /* Extension to Groundspeak for GSAK */ + gt_cito, + gt_ape, + gt_mega +} geocache_type; + +typedef enum { + gc_unknown = 0, + gc_micro, + gc_other, + gc_regular, + gc_large, + gc_virtual, + gc_small +} geocache_container; + +typedef struct { + int is_html; + char *utfstring; +} utf_string; + +typedef struct { + int id; /* The decimal cache number */ + geocache_type type:5; + geocache_container container:4; + unsigned int diff:6; /* (multiplied by ten internally) */ + unsigned int terr:6; /* (likewise) */ + status_type is_archived:2; + status_type is_available:2; + time_t exported; + time_t last_found; + char *placer; /* Placer name */ + int placer_id; /* Placer id */ + char *hint; /* all these UTF8, XML entities removed, May be not HTML. */ + utf_string desc_short; + utf_string desc_long; +} geocache_data ; + +typedef struct xml_tag { + char *tagname; + char *cdata; + int cdatalen; + char *parentcdata; + int parentcdatalen; + char **attributes; + struct xml_tag *parent; + struct xml_tag *sibling; + struct xml_tag *child; +} xml_tag ; + +typedef void (*fs_destroy)(void *); +typedef void (*fs_copy)(void **, void *); +typedef void (*fs_convert)(void *); + +typedef struct format_specific_data { + long type; + struct format_specific_data *next; + + fs_destroy destroy; + fs_copy copy; + fs_convert convert; +} format_specific_data; + +format_specific_data *fs_chain_copy( format_specific_data *source ); +void fs_chain_destroy( format_specific_data *chain ); +format_specific_data *fs_chain_find( format_specific_data *chain, long type ); +void fs_chain_add( format_specific_data **chain, format_specific_data *data ); + +typedef struct fs_xml { + format_specific_data fs; + xml_tag *tag; +} fs_xml; + +fs_xml *fs_xml_alloc( long type ); + +#define FS_GPX 0x67707800L +#define FS_AN1W 0x616e3177L +#define FS_AN1L 0x616e316cL +#define FS_AN1V 0x616e3176L +#define FS_OZI 0x6f7a6900L +#define FS_GMSD 0x474d5344L /* GMSD = Garmin specific data */ + +/* + * Structures and functions for multiple URLs per waypoint. + */ +typedef struct url_link { + struct url_link *url_next; + char *url; + char *url_link_text; +} url_link; + +/* + * Misc bitfields inside struct waypoint; + */ +typedef struct { + unsigned int icon_descr_is_dynamic:1; + unsigned int shortname_is_synthetic:1; + unsigned int cet_converted:1; /* strings are converted to UTF8; interesting only for input */ + unsigned int fmt_use:1; /* lightweight "extra data" */ + /* "flagged fields" */ + unsigned int temperature:1; /* temperature field is set */ + unsigned int proximity:1; /* proximity field is set */ + unsigned int course:1; /* course field is set */ + unsigned int speed:1; /* speed field is set */ + unsigned int depth:1; /* depth field is set */ + /* !ToDo! + unsigned int altitude:1; /+ altitude field is set +/ + ... and others + */ + +} wp_flags; + +#define WAYPT_SET(wpt,member,val) { wpt->member = (val); wpt->wpt_flags.member = 1; } +#define WAYPT_GET(wpt,member,def) ((wpt->wpt_flags.member) ? (wpt->member) : (def)) +#define WAYPT_UNSET(wpt,member) wpt->wpt_flags.member = 0 +#define WAYPT_HAS(wpt,member) (wpt->wpt_flags.member) +/* + * This is a waypoint, as stored in the GPSR. It tries to not + * cater to any specific model or protocol. Anything that needs to + * be truncated, edited, or otherwise trimmed should be done on the + * way to the target. + */ + +typedef struct { + queue Q; /* Master waypoint q. Not for use + by modules. */ + + double latitude; /* Degrees */ + double longitude; /* Degrees */ + double altitude; /* Meters. */ + + /* + * The "thickness" of a waypoint; adds an element of 3D. Can be + * used to construct rudimentary polygons for, say, airspace + * definitions. The units are meters. + */ + double depth; + + /* + * An alarm trigger value that can be considered to be a circle + * surrounding a waypoint (or cylinder if depth is also defined). + * The units are meters. + */ + double proximity; + + /* shortname is a waypoint name as stored in receiver. It should + * strive to be, well, short, and unique. Enforcing length and + * character restrictions is the job of the output. A typical + * minimum length for shortname is 6 characters for NMEA units, + * 8 for Magellan and 10 for Vista. These are only guidelines. + */ + char *shortname; + /* + * description is typically a human readable description of the + * waypoint. It may be used as a comment field in some receivers. + * These are probably under 40 bytes, but that's only a guideline. + */ + char *description; + /* + * notes are relatively long - over 100 characters - prose associated + * with the above. Unlike shortname and description, these are never + * used to compute anything else and are strictly "passed through". + * Few formats support this. + */ + char *notes; + + /* This is a bit icky. Multiple waypoint support is an + * afterthought and I don't want to change our data structures. + * So we have the first in the waypoint itself and subsequent + * ones in a linked list. + * We also use an implicit anonymous union here, so these three + * members must match struct url_link... + */ + struct url_link *url_next; + char *url; + char *url_link_text; + + wp_flags wpt_flags; + const char *icon_descr; + time_t creation_time; /* standardized in UTC/GMT */ + int microseconds; /* Optional millionths of a second. */ + + /* + * route priority is for use by the simplify filter. If we have + * some reason to believe that the route point is more important, + * we can give it a higher (numerically; 0 is the lowest) priority. + * This causes it to be removed last. + * This is currently used by the saroute input filter to give named + * waypoints (representing turns) a higher priority. + * This is also used by the google input filter because they were + * nice enough to use exactly the same priority scheme. + */ + int route_priority; + + /* Optional dilution of precision: positional, horizontal, veritcal. + * 1 <= dop <= 50 + */ + float hdop; + float vdop; + float pdop; + float course; /* Optional: degrees true */ + float speed; /* Optional: meters per second. */ + fix_type fix; /* Optional: 3d, 2d, etc. */ + int sat; /* Optional: number of sats used for fix */ + + unsigned char heartrate; /* Beats/min. likely to get moved to fs. */ + unsigned char cadence; /* revolutions per minute */ + float temperature; /* Degrees celsius */ + geocache_data gc_data; + format_specific_data *fs; + void *extra_data; /* Extra data added by, say, a filter. */ +} waypoint; + +typedef struct { + queue Q; /* Link onto parent list. */ + queue waypoint_list; /* List of child waypoints */ + char *rte_name; + char *rte_desc; + char *rte_url; + int rte_num; + int rte_waypt_ct; /* # waypoints in waypoint list */ + format_specific_data *fs; + unsigned short cet_converted; /* strings are converted to UTF8; interesting only for input */ +} route_head; + +/* + * Structure of recomputed track/roue data. + */ +typedef struct { + double distance_meters; + double max_alt; + double min_alt; + double max_spd; /* Meters/sec */ + double min_spd; /* Meters/sec */ + double avg_hrt; /* Avg Heartrate */ + double avg_cad; /* Avg Cadence */ + time_t start; /* Min time */ + time_t end; /* Max time */ + int min_hrt; /* Min Heartrate */ + int max_hrt; /* Max Heartrate */ + int max_cad; /* Max Cadence */ +} computed_trkdata; + +/* + * Bounding box information. + */ +typedef struct { + double max_lat; + double max_lon; + double max_alt; + double min_lat; + double min_lon; + double min_alt; +} bounds; + +typedef struct { + volatile int request_terminate; +} posn_status; + +extern posn_status tracking_status; + +typedef void (*ff_init) (char const *); +typedef void (*ff_deinit) (void); +typedef void (*ff_read) (void); +typedef void (*ff_write) (void); +typedef void (*ff_exit) (void); +typedef void (*ff_writeposn) (waypoint *); +typedef waypoint * (*ff_readposn) (posn_status *); + +#ifndef DEBUG_MEM +char * get_option(const char *iarglist, const char *argname); +#else +#define DEBUG_PARAMS const char *file, const int line +char *GET_OPTION(const char *iarglist, const char *argname, DEBUG_PARAMS); +#define get_option(iarglist, argname) GET_OPTION(iarglist, argname, __FILE__, __LINE__) +#endif + +typedef void (*filter_init) (char const *); +typedef void (*filter_process) (void); +typedef void (*filter_deinit) (void); +typedef void (*filter_exit) (void); + +typedef void (*waypt_cb) (const waypoint *); +typedef void (*route_hdr)(const route_head *); +typedef void (*route_trl)(const route_head *); +void waypt_add (waypoint *); +waypoint * waypt_dupe (const waypoint *); +waypoint * waypt_new(void); +void waypt_del (waypoint *); +void waypt_free (waypoint *); +void waypt_disp_all(waypt_cb); +void waypt_init_bounds(bounds *bounds); +int waypt_bounds_valid(bounds *bounds); +void waypt_add_to_bounds(bounds *bounds, const waypoint *waypointp); +void waypt_compute_bounds(bounds *); +void waypt_flush(queue *); +void waypt_flush_all(void); +unsigned int waypt_count(void); +void set_waypt_count(unsigned int nc); +void waypt_add_url(waypoint *wpt, char *link, char *url_link_text); +void free_gpx_extras (xml_tag * tag); +void xcsv_setup_internal_style(const char *style_buf); +void xcsv_read_internal_style(const char *style_buf); +waypoint * find_waypt_by_name(const char *name); +void waypt_backup(signed int *count, queue **head_bak); +void waypt_restore(signed int count, queue *head_bak); + +route_head *route_head_alloc(void); +void route_add (waypoint *); +void route_add_wpt(route_head *rte, waypoint *wpt); +void route_del_wpt(route_head *rte, waypoint *wpt); +void track_add_wpt(route_head *rte, waypoint *wpt); +void track_del_wpt(route_head *rte, waypoint *wpt); +void route_add_head(route_head *rte); +void route_del_head(route_head *rte); +void route_reverse(const route_head *rte_hd); +waypoint * route_find_waypt_by_name(route_head *rh, const char *name); +void track_add_head(route_head *rte); +void track_del_head(route_head *rte); +void route_disp(const route_head *rte, waypt_cb); +void route_disp_all(route_hdr, route_trl, waypt_cb); +void track_disp_all(route_hdr, route_trl, waypt_cb); +void route_flush( queue *); +void route_flush_all(void); +void route_flush_all_routes(void); +void route_flush_all_tracks(void); +route_head * route_find_route_by_name(const char *name); +route_head * route_find_track_by_name(const char *name); +unsigned int route_waypt_count(void); +unsigned int route_count(void); +unsigned int track_waypt_count(void); +unsigned int track_count(void); +void route_copy( int *dst_count, int *dst_wpt_count, queue **dst, queue *src ); +void route_backup(signed int *count, queue **head_bak); +void route_restore( queue *head_bak); +void route_append( queue *src ); +void track_backup(signed int *count, queue **head_bak); +void track_restore( queue *head_bak); +void track_append( queue *src ); +void route_flush( queue *head ); +void track_recompute( const route_head *trk, computed_trkdata **); + +/* + * All shortname functions take a shortname handle as the first arg. + * This is an opaque pointer. Callers must not fondle the contents of it. + */ +typedef struct short_handle * short_handle; +#ifndef DEBUG_MEM +char *mkshort (short_handle, const char *); +void *mkshort_new_handle(void); +#else +char *MKSHORT(short_handle, const char *, DEBUG_PARAMS); +void *MKSHORT_NEW_HANDLE(DEBUG_PARAMS); +#define mkshort( a, b) MKSHORT(a,b,__FILE__, __LINE__) +#define mkshort_new_handle() MKSHORT_NEW_HANDLE(__FILE__,__LINE__) +#endif +char *mkshort_from_wpt(short_handle h, const waypoint *wpt); +void mkshort_del_handle(short_handle *h); +void setshort_length(short_handle, int n); +void setshort_badchars(short_handle, const char *); +void setshort_goodchars(short_handle, const char *); +void setshort_mustupper(short_handle, int n); +void setshort_mustuniq(short_handle, int n); +void setshort_whitespace_ok(short_handle, int n); +void setshort_repeating_whitespace_ok(short_handle, int n); +void setshort_defname(short_handle, const char *s); + +/* + * Vmem flags values. + */ +#define VMFL_NOZERO (1 << 0) +typedef struct vmem { + void *mem; /* visible memory object */ + size_t size; /* allocated size of object */ +} vmem_t; +vmem_t vmem_alloc(size_t, int flags); +void vmem_free(vmem_t*); +void vmem_realloc(vmem_t*, size_t); + + +#define ARGTYPE_UNKNOWN 0x00000000 +#define ARGTYPE_INT 0x00000001 +#define ARGTYPE_FLOAT 0x00000002 +#define ARGTYPE_STRING 0x00000003 +#define ARGTYPE_BOOL 0x00000004 +#define ARGTYPE_FILE 0x00000005 +#define ARGTYPE_OUTFILE 0x00000006 + +/* REQUIRED means that the option is required to be set. + * See also BEGIN/END_REQ */ +#define ARGTYPE_REQUIRED 0x40000000 + +/* HIDDEN means that the option does not appear in help texts. Useful + * for debugging or testing options */ +#define ARGTYPE_HIDDEN 0x20000000 + +/* BEGIN/END_EXCL mark the beginning and end of an exclusive range of + * options. No more than one of the options in the range may be selected + * or set. If exactly one must be set, use with BEGIN/END_REQ + * Both of these flags set is just like neither set, so avoid doing that. */ +#define ARGTYPE_BEGIN_EXCL 0x10000000 +#define ARGTYPE_END_EXCL 0x08000000 + +/* BEGIN/END_REQ mark the beginning and end of a required range of + * options. One or more of the options in the range MUST be selected or set. + * If exactly one must be set, use with BEGIN/END_EXCL + * Both of these flags set is synonymous with REQUIRED, so use that instead + * for "groups" of exactly one option. */ +#define ARGTYPE_BEGIN_REQ 0x04000000 +#define ARGTYPE_END_REQ 0x02000000 + +#define ARGTYPE_TYPEMASK 0x00000fff +#define ARGTYPE_FLAGMASK 0xfffff000 + +#define ARG_NOMINMAX NULL, NULL +#define ARG_TERMINATOR {0, 0, 0, 0, 0, ARG_NOMINMAX} + +typedef struct arglist { + char *argstring; + char **argval; + char *helpstring; + char *defaultvalue; + gbuint32 argtype; + char *minvalue; /* minimum value for numeric options */ + char *maxvalue; /* maximum value for numeric options */ +} arglist_t; + +typedef enum { + ff_type_file = 1, /* normal format: useful to a GUI. */ + ff_type_internal, /* fmt not useful with default options */ + ff_type_serial /* format describes a serial protocol (GUI can display port names) */ +} ff_type; + +typedef enum { + ff_cap_rw_wpt, + ff_cap_rw_trk, + ff_cap_rw_rte +} ff_cap_array; + +typedef enum { + ff_cap_none, + ff_cap_read = 1, + ff_cap_write = 2 +} ff_cap; + +#define FF_CAP_RW_ALL \ + { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write } + +#define FF_CAP_RW_WPT \ + { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none} + +/* + * Format capabilities for realtime positioning. + */ +typedef struct position_ops { + ff_init rd_init; + ff_readposn rd_position; + ff_deinit rd_deinit; + + ff_init wr_init; + ff_writeposn wr_position; + ff_deinit wr_deinit; +} position_ops_t; + +/* + * Describe the file format to the caller. + */ +typedef struct ff_vecs { + ff_type type; + ff_cap cap[3]; + ff_init rd_init; + ff_init wr_init; + ff_deinit rd_deinit; + ff_deinit wr_deinit; + ff_read read; + ff_write write; + ff_exit exit; + arglist_t *args; + char *encode; + int fixed_encode; + position_ops_t position_ops; +} ff_vecs_t; + +typedef struct style_vecs { + const char *name; + const char *style_buf; +} style_vecs_t; +extern style_vecs_t style_list[]; + +void waypt_init(void); +void route_init(void); +void waypt_disp(const waypoint *); +void waypt_status_disp(int total_ct, int myct); +double waypt_time(const waypoint *wpt); +double waypt_speed(const waypoint *A, const waypoint *B); +double waypt_speed_ex(const waypoint *A, const waypoint *B); +double waypt_course(const waypoint *A, const waypoint *B); +double waypt_distance(const waypoint *A, const waypoint *B); +double waypt_distance_ex(const waypoint *A, const waypoint *B); + +NORETURN fatal(const char *, ...) PRINTFLIKE(1, 2); +void is_fatal(const int condition, const char *, ...) PRINTFLIKE(2, 3); +void warning(const char *, ...) PRINTFLIKE(1, 2); + +ff_vecs_t *find_vec(char * const, char **); +void assign_option(const char *vecname, arglist_t *ap, const char *val); +void disp_vec_options(const char *vecname, arglist_t *ap); +void disp_vecs(void); +void disp_vec( const char *vecname ); +void exit_vecs(void); +void disp_formats(int version); +const char * name_option(long type); +void printposn(const double c, int is_lat); + +#ifndef DEBUG_MEM +void *xcalloc(size_t nmemb, size_t size); +void *xmalloc(size_t size); +void *xrealloc(void *p, size_t s); +void xfree(void *mem); +char *xstrdup(const char *s); +char *xstrndup(const char *s, size_t n); +char *xstrndupt(const char *s, size_t n); +char *xstrappend(char *src, const char *addon); +#define xxcalloc(nmemb, size, file, line) xcalloc(nmemb, size) +#define xxmalloc(size, file, line) xmalloc(size) +#define xxrealloc(p, s, file, line) xrealloc(p,s) +#define xxfree(mem, file, line) xfree(mem) +#define xxstrdup(s, file, line) xstrdup(s) +#define xxstrappend(src, addon, file, line) xstrappend(src, addon) +#else /* DEBUG_MEM */ +void *XCALLOC(size_t nmemb, size_t size, DEBUG_PARAMS ); +void *XMALLOC(size_t size, DEBUG_PARAMS ); +void *XREALLOC(void *p, size_t s, DEBUG_PARAMS ); +void XFREE(void *mem, DEBUG_PARAMS ); +char *XSTRDUP(const char *s, DEBUG_PARAMS ); +char *XSTRNDUP(const char *src, size_t size, DEBUG_PARAMS ); +char *XSTRNDUPT(const char *src, size_t size, DEBUG_PARAMS ); +char *XSTRAPPEND(char *src, const char *addon, DEBUG_PARAMS ); +void debug_mem_open(); +void debug_mem_output( char *format, ... ); +void debug_mem_close(); +#define xcalloc(nmemb, size) XCALLOC(nmemb, size, __FILE__, __LINE__) +#define xmalloc(size) XMALLOC(size, __FILE__, __LINE__) +#define xrealloc(p, s) XREALLOC(p,s,__FILE__,__LINE__) +#define xfree(mem) XFREE(mem, __FILE__, __LINE__) +#define xstrdup(s) XSTRDUP(s, __FILE__, __LINE__) +#define xstrndup(s, z) XSTRNDUP(s, z, __FILE__, __LINE__) +#define xstrndupt(s, z) XSTRNDUPT(s, z, __FILE__, __LINE__) +#define xstrappend(src,addon) XSTRAPPEND(src, addon, __FILE__, __LINE__) +#define xxcalloc XCALLOC +#define xxmalloc XMALLOC +#define xxrealloc XREALLOC +#define xxfree XFREE +#define xxstrdup XSTRDUP +#define xxstrndupt XSTRNDUPT +#define xxstrappend XSTRAPPEND +#endif /* DEBUG_MEM */ + +FILE *xfopen(const char *fname, const char *type, const char *errtxt); +void xfprintf(const char *errtxt, FILE *stream, const char *format, ...); +void xfputs(const char *errtxt, const char *s, FILE *stream); + +int case_ignore_strcmp(const char *s1, const char *s2); +int case_ignore_strncmp(const char *s1, const char *s2, int n); +int str_match(const char *str, const char *match); +int case_ignore_str_match(const char *str, const char *match); +char * strenquote(const char *str, const char quot_char); + +char *strsub(const char *s, const char *search, const char *replace); +char *gstrsub(const char *s, const char *search, const char *replace); +char *xstrrstr(const char *s1, const char *s2); +void rtrim(char *s); +char * lrtrim(char *s); +int xasprintf(char **strp, const char *fmt, ...); +int xvasprintf(char **strp, const char *fmt, va_list ap); +char *strupper(char *src); +char *strlower(char *src); +signed int get_tz_offset(void); +time_t mklocaltime(struct tm *t); +time_t mkgmtime(struct tm *t); +time_t current_time(void); +signed int month_lookup(const char *m); +const char *get_cache_icon(const waypoint *waypointp); +const char *gs_get_cachetype(geocache_type t); +const char *gs_get_container(geocache_container t); +char * xml_entitize(const char * str); +char * html_entitize(const char * str); +char * strip_html(const utf_string*); +char * strip_nastyhtml(const char * in); +char * convert_human_date_format(const char *human_datef); /* "MM,YYYY,DD" -> "%m,%Y,%d" */ +char * convert_human_time_format(const char *human_timef); /* "HH+mm+ss" -> "%H+%M+%S" */ +char * pretty_deg_format(double lat, double lon, char fmt, char *sep, int html); /* decimal -> dd.dddd or dd mm.mmm or dd mm ss */ + +char * get_filename(const char *fname); /* extract the filename portion */ + +/* + * Character encoding transformations. + */ + +#define CET_NOT_CONVERTABLE_DEFAULT '$' +#define CET_CHARSET_ASCII "US-ASCII" +#define CET_CHARSET_UTF8 "UTF-8" +#define CET_CHARSET_MS_ANSI "MS-ANSI" +#define CET_CHARSET_LATIN1 "ISO-8859-1" + +#define str_utf8_to_cp1252(str) cet_str_utf8_to_cp1252((str)) +#define str_cp1252_to_utf8(str) cet_str_cp1252_to_utf8((str)) + +#define str_utf8_to_iso8859_1(str) cet_str_utf8_to_iso8859_1((str)) +#define str_iso8859_1_to_utf8(str) cet_str_iso8859_1_to_utf8((str)) + +/* this lives in gpx.c */ +time_t xml_parse_time( const char *cdatastr, int * microsecs ); + +xml_tag *xml_findfirst( xml_tag *root, char *tagname ); +xml_tag *xml_findnext( xml_tag *root, xml_tag *cur, char *tagname ); +char *xml_attribute( xml_tag *tag, char *attrname ); + +char * rot13( const char *str ); + +/* + * PalmOS records like fixed-point numbers, which should be rounded + * to deal with possible floating-point representation errors. + */ + +signed int si_round( double d ); + +/* + * Data types for Palm/OS files. + */ +typedef struct { + unsigned char data[4]; +} pdb_32; + +typedef struct { + unsigned char data[2]; +} pdb_16; + +typedef struct { + unsigned char data[8]; +} pdb_double; + +typedef struct { + unsigned char data[4]; +} pdb_float; + +/* + * Protypes for Endianness helpers. + */ + +signed int be_read16(const void *p); +signed int be_read32(const void *p); +signed int le_read16(const void *p); +unsigned int le_readu16(const void *p); +signed int le_read32(const void *p); +unsigned int le_readu32(const void *p); +void le_read64(void *dest, const void *src); +void be_write16(void *pp, const unsigned i); +void be_write32(void *pp, const unsigned i); +void le_write16(void *pp, const unsigned i); +void le_write32(void *pp, const unsigned i); + +double endian_read_double(void* ptr, int read_le); +float endian_read_float(void* ptr, int read_le); +void endian_write_double(void* ptr, double d, int write_le); +void endian_write_float(void* ptr, float f, int write_le); + +float be_read_float(void *p); +double be_read_double(void *p); +void be_write_float(void *pp, float d); +void be_write_double(void *pp, double d); + +float le_read_float(void *p); +double le_read_double(void *p); +void le_write_float(void *ptr, float f); +void le_write_double(void *p, double d); + +#define pdb_write_float be_write_float +#define pdb_read_float be_read_float +#define pdb_write_double be_write_double +#define pdb_read_double be_read_double + +/* + * Prototypes for generic conversion routines (util.c). + */ + +double ddmm2degrees(double ddmm_val); +double degrees2ddmm(double deg_val); + +typedef enum { + grid_unknown = -1, + grid_lat_lon_ddd = 0, + grid_lat_lon_dmm = 1, + grid_lat_lon_dms = 2, + grid_bng = 3, + grid_utm = 4, + grid_swiss = 5 +} grid_type; + +#define GRID_INDEX_MIN grid_lat_lon_ddd +#define GRID_INDEX_MAX grid_swiss + +#define DATUM_OSGB36 86 +#define DATUM_WGS84 118 + +/* + * From parse.c + */ +int parse_coordinates(const char *str, int datum, const grid_type grid, + double *latitude, double *longitude, const char *module); +int parse_distance(const char *str, double *val, double scale, const char *module); +int parse_speed(const char *str, double *val, const double scale, const char *module); + +/* + * From util_crc.c + */ +unsigned long get_crc32(const void * data, int datalen); +unsigned long get_crc32_s(const void * data); + +/* + * From units.c + */ +typedef enum { + units_unknown = 0, + units_statute = 1, + units_metric =2 +} fmt_units; + +int fmt_setunits(fmt_units); +double fmt_distance(const double, char **tag); +double fmt_speed(const double, char **tag); + +/* + * From gbsleep.c + */ +void gb_sleep(unsigned long microseconds); + +/* + * From nmea.c + */ +int nmea_cksum(const char *const buf); + +/* + * Color helpers. + */ +int color_to_bbggrr(char *cname); + +/* + * A constant for unknown altitude. It's tempting to just use zero + * but that's not very nice for the folks near sea level. + */ +#define unknown_alt -99999999.0 + +#endif /* gpsbabel_defs_h_included */ diff --git a/delgpl.c b/delgpl.c new file mode 100644 index 000000000..37dac7ac2 --- /dev/null +++ b/delgpl.c @@ -0,0 +1,141 @@ +/* + DeLorme GPL Track Format. + + Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include + +#include "defs.h" + +#define MYNAME "GPL" + +typedef struct gpl_point { + unsigned int status; + unsigned int dummy1; + double lat; + double lon; + double alt; /* in feet */ + double heading; + double speed; /* mph */ + unsigned int tm; + unsigned int dummy3; +} gpl_point_t; + +static gbfile *gplfile_in; +static gbfile *gplfile_out; + +static void +gpl_rd_init(const char *fname) +{ + gplfile_in = gbfopen_le(fname, "rb", MYNAME); + if (sizeof(struct gpl_point) != 56) { + fatal(MYNAME ": gpl_point is %lu instead of 56.\n", + (unsigned long) sizeof(struct gpl_point)); + } +} + +static void +gpl_read(void) +{ + waypoint *wpt_tmp; + route_head *track_head; + gpl_point_t gp; + double alt_feet; + + track_head = route_head_alloc(); + track_add_head(track_head); + + while (gbfread(&gp, sizeof(gp), 1, gplfile_in) > 0) { + wpt_tmp = waypt_new(); + wpt_tmp->latitude = le_read_double(&gp.lat); + wpt_tmp->longitude = le_read_double(&gp.lon); + alt_feet = le_read_double(&gp.alt); + wpt_tmp->altitude = FEET_TO_METERS(alt_feet); + if (wpt_tmp->altitude <= unknown_alt + 1) + wpt_tmp->altitude = unknown_alt; + wpt_tmp->creation_time = le_read32(&gp.tm); + + WAYPT_SET(wpt_tmp, course, le_read_double(&gp.heading)); + WAYPT_SET(wpt_tmp, speed, le_read_double(&gp.speed)); + WAYPT_SET(wpt_tmp, speed, MILES_TO_METERS(wpt_tmp->speed)/3600); + + track_add_wpt(track_head, wpt_tmp); + } +} + + +static void +gpl_rd_deinit(void) +{ + gbfclose(gplfile_in); +} + +static void +gpl_wr_init(const char *fname) +{ + gplfile_out = gbfopen_le(fname, "wb", MYNAME); +} + +static void +gpl_wr_deinit(void) +{ + gbfclose(gplfile_out); +} + +static void +gpl_trackpt(const waypoint *wpt) +{ + double alt_feet = METERS_TO_FEET(wpt->altitude); + int status = 3; + gpl_point_t gp; + double speed = 3600*METERS_TO_MILES(wpt->speed); + double heading = wpt->course; + + memset(&gp, 0, sizeof(gp)); + le_write32(&gp.status, status); + le_write_double(&gp.lat, wpt->latitude); + le_write_double(&gp.lon, wpt->longitude); + le_write_double(&gp.alt, alt_feet ); + le_write_double(&gp.speed, speed ); + le_write_double(&gp.heading, heading ); + le_write32(&gp.tm, wpt->creation_time); + + gbfwrite(&gp, sizeof(gp), 1, gplfile_out); +} + +static void +gpl_write(void) +{ + track_disp_all(NULL, NULL, gpl_trackpt); +} + +ff_vecs_t gpl_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, + gpl_rd_init, + gpl_wr_init, + gpl_rd_deinit, + gpl_wr_deinit, + gpl_read, + gpl_write, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* there is no need to convert anything | CET-REVIEW */ +}; diff --git a/destinator.c b/destinator.c new file mode 100644 index 000000000..59b3c323b --- /dev/null +++ b/destinator.c @@ -0,0 +1,588 @@ +/* + + Support for Destinator POI's, Itineraries and Tracklogs. + ( as described at "http://mozoft.com/d3log.html" ) + + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "cet.h" +#include "garmin_fs.h" +#include "strptime.h" +#include +#include + +#define MYNAME "destinator" +#define DST_DYN_POI "Dynamic POI" +#define DST_ITINERARY "City->Street" + +static +arglist_t destinator_args[] = { + ARG_TERMINATOR +}; + +static gbfile *fin, *fout; +static gpsdata_type data_type; + + +/*******************************************************************************/ +/* READER */ +/*-----------------------------------------------------------------------------*/ + +static garmin_fs_t * +gmsd_init(waypoint *wpt) +{ + garmin_fs_t *gmsd = GMSD_FIND(wpt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + return gmsd; +} + +static char * +read_wcstr(const int discard) +{ + short *buff = NULL, c; + int size = 0, pos = 0; + + while ((c = gbfgetint16(fin))) { + if (size == 0) { + size = 16; + buff = xmalloc(size * 2); + } + else if (pos == size) { + size += 16; + buff = xrealloc(buff, size * 2); + } + buff[pos] = c; + pos += 1; + } + + if (pos != 0) { + char *res; + if (discard) res = NULL; + else { + res = cet_str_uni_to_utf8(buff, pos); + res = lrtrim(res); + if (*res == '\0') { + xfree(res); + res = NULL; + } + } + xfree(buff); + return res; + } + else + return NULL; +} + +static void +write_wcstr(const char *str) +{ + if (str && *str) { + int bytes, value; + char *cin = (char *)str; + char *ce = cin + strlen(cin); + while (cin < ce) { + cet_utf8_to_ucs4(cin, &bytes, &value); + cin += bytes; + gbfputint16(value, fout); + } + } + gbfputint16(0, fout); +} + +static int +read_until_wcstr(const char *str) +{ + char *buff; + int len, sz; + int eos = 0, res = 0; + + len = strlen(str); + sz = (len + 1) * 2; + buff = xcalloc(sz, 1); + + while (! gbfeof(fin)) { + + char c = gbfgetc(fin); + memmove(buff, buff + 1, sz - 1); + buff[sz - 1] = c; + + if (c == 0) { + eos++; + if (eos >= 2) { /* two or more zero bytes => end of string */ + char *test = cet_str_uni_to_utf8((short *)buff, len); + if (test) { + res = (strcmp(str, test) == 0); + xfree(test); + if (res) break; + } + } + } + else eos = 0; + } + xfree(buff); + return res; +} + +static void +destinator_read_poi(void) +{ + waypoint *wpt; + int count = 0; + + gbfrewind(fin); + + while (! (gbfeof(fin))) { + char *str, *hnum; + double ll; + garmin_fs_t *gmsd; + + if (count == 0) { + str = read_wcstr(0); + if ((str == NULL) || (strcmp(str, DST_DYN_POI) != 0)) + fatal(MYNAME "_poi: Invalid record header!\n"); + xfree(str); + } + else if (! read_until_wcstr(DST_DYN_POI)) break; + + count++; + + wpt = waypt_new(); + + wpt->shortname = read_wcstr(0); + wpt->notes = read_wcstr(0); /* comment */ + + hnum = read_wcstr(0); /* house number */ + + str = read_wcstr(0); /* street */ + if (!str) { + str = hnum; + hnum = NULL; + } + if (str) { + gmsd = gmsd_init(wpt); + if (hnum) { + str = xstrappend(str, " "); + str = xstrappend(str, hnum); + } + GMSD_SET(addr, str); + } + + if ((str = read_wcstr(0))) { /* city */ + gmsd = gmsd_init(wpt); + GMSD_SET(city, str); + } + + if (hnum) xfree(hnum); + + (void) read_wcstr(1); /* unknown */ + + if ((str = read_wcstr(0))) { /* postcode */ + gmsd = gmsd_init(wpt); + GMSD_SET(postal_code, str); + } + + (void) read_wcstr(1); /* unknown */ + + (void) gbfgetdbl(fin); + + wpt->longitude = gbfgetdbl(fin); + wpt->latitude = gbfgetdbl(fin); + ll = gbfgetdbl(fin); + if (ll != wpt->longitude) + fatal(MYNAME "_poi: Invalid file!\n"); + ll = gbfgetdbl(fin); + if (ll != wpt->latitude) + fatal(MYNAME "_poi: Invalid file!\n"); + + waypt_add(wpt); + } +} + +static void +destinator_read_rte(void) +{ + int count = 0; + route_head *rte = NULL; + + gbfrewind(fin); + + while (! (gbfeof(fin))) { + char *str; + waypoint *wpt; + + if (count == 0) { + str = read_wcstr(0); + if ((str == NULL) || (strcmp(str, DST_ITINERARY) != 0)) + fatal(MYNAME "_itn: Invalid record header!\n"); + xfree(str); + } + else if (! read_until_wcstr(DST_ITINERARY)) break; + + count++; + + wpt = waypt_new(); + + wpt->shortname = read_wcstr(0); + wpt->notes = read_wcstr(0); + + (void) gbfgetint32(fin); + (void) gbfgetdbl(fin); + (void) gbfgetdbl(fin); + + wpt->longitude = gbfgetdbl(fin); + wpt->latitude = gbfgetdbl(fin); + if (gbfgetdbl(fin) != wpt->longitude) + fatal(MYNAME "_itn: Invalid file!\n"); + if (gbfgetdbl(fin) != wpt->latitude) + fatal(MYNAME "_itn: Invalid file!\n"); + + if (! rte) { + rte = route_head_alloc(); + route_add_head(rte); + } + route_add_wpt(rte, wpt); + + (void) gbfgetdbl(fin); + (void) gbfgetdbl(fin); + } +} + +static void +destinator_read_trk(void) +{ + char TXT[4] = "TXT"; + int recno = -1; + route_head *trk = NULL; + + gbfrewind(fin); + + while (! (gbfeof(fin))) { + waypoint *wpt; + struct tm tm; + char buff[20]; + int date; + double time; + + recno++; + + if (gbfeof(fin)) break; + + wpt = waypt_new(); + + wpt->longitude = gbfgetdbl(fin); + wpt->latitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + (void) gbfgetdbl(fin); /* unknown */ + (void) gbfgetdbl(fin); /* unknown */ + (void) gbfgetdbl(fin); /* unknown */ + + wpt->fix = gbfgetint32(fin); + wpt->sat = gbfgetint32(fin); + + gbfseek(fin, 12 * sizeof(gbint32), SEEK_CUR); /* SAT info */ + + date = gbfgetint32(fin); + time = gbfgetflt(fin); + + gbfseek(fin, 2 * 12, SEEK_CUR); /* SAT info */ + + gbfread(TXT, 1, 3, fin); + if (strcmp(TXT, "TXT") != 0) + fatal(MYNAME "_trk: No (or unknown) file!\n"); + + gbfseek(fin, 13, SEEK_CUR); /* unknown */ + + memset(&tm, 0, sizeof(tm)); + + snprintf(buff, sizeof(buff), "%06d%.f", date, time); + strptime(buff, "%d%m%y%H%M%S", &tm); + wpt->creation_time = mkgmtime(&tm); + wpt->microseconds = ((int)time % 1000) * 1000; + + if ((wpt->sat > 0) && (wpt->fix > 0)) { + + wpt->fix++; + + if (! trk) { + trk = route_head_alloc(); + track_add_head(trk); + } + + track_add_wpt(trk, wpt); + } + else + waypt_free(wpt); + } +} + +static void +destinator_read(void) +{ + int i0, i1; + double d0, d1; + char buff[16]; + + gbfread(buff, sizeof(buff), 1, fin); + i0 = le_read32(&buff[0]); + i1 = le_read32(&buff[4]); + + if ((i0 == 0x690043) && (i1 == 0x790074)) { + if (data_type != rtedata) + warning(MYNAME ": Using Destinator Itinerary Format!\n"); + destinator_read_rte(); + } + else if ((i0 == 0x790044) && (i1 == 0x61006e)) { + if (data_type != wptdata) + warning(MYNAME ": Using Destinator POI Format!\n"); + destinator_read_poi(); + } + else { + if (data_type != trkdata) + warning(MYNAME ": Using Destinator Tracklog Format!\n"); + + le_read64(&d0, &buff[0]); + le_read64(&d1, &buff[8]); + if ((fabs(d0) > 180) || (fabs(d1) > 90)) + fatal(MYNAME ": No Destinator (.dat) file!\n"); + destinator_read_trk(); + } +} + +/*******************************************************************************/ +/* WRITER */ +/*-----------------------------------------------------------------------------*/ + +static void +destinator_wpt_disp(const waypoint *wpt) +{ + garmin_fs_t *gmsd = GMSD_FIND(wpt); + + write_wcstr(DST_DYN_POI); + write_wcstr((wpt->shortname) ? wpt->shortname : "WPT"); + write_wcstr((wpt->notes) ? wpt->notes : wpt->description); + + write_wcstr(NULL); /* house number */ + write_wcstr(GMSD_GET(addr, NULL)); /* street */ + write_wcstr(GMSD_GET(city, NULL)); /* city */ + write_wcstr(NULL); /* unknown */ + write_wcstr(GMSD_GET(postal_code, NULL)); /* postcode */ + write_wcstr(NULL); /* unknown */ + + gbfputint32(0, fout); + gbfputint32(0, fout); + + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + + gbfputdbl(0, fout); + gbfputdbl(0, fout); +} + +static void +destinator_trkpt_disp(const waypoint *wpt) +{ + int i; + + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->altitude, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); + gbfputint32(wpt->fix > fix_unknown ? wpt->fix - 1 : 0, fout); + gbfputint32(wpt->sat, fout); + for (i = 0; i < 12; i++) gbfputint32(0, fout); + + if (wpt->creation_time) { + struct tm tm; + double time; + int date; + + tm = *gmtime(&wpt->creation_time); + tm.tm_mon += 1; + tm.tm_year -= 100; + date = ((int)tm.tm_mday * 10000) + ((int)tm.tm_mon * 100) + tm.tm_year; + gbfputint32(date, fout); + + time = ((int)tm.tm_hour * 10000) + ((int)tm.tm_min * 100) + tm.tm_sec; + time = (time * 1000) + (wpt->microseconds / 1000); + gbfputflt(time, fout); + } + else { + gbfputint32(0, fout); /* Is this invalid ? */ + gbfputflt(0, fout); + } + + for (i = 0; i < 12; i++) gbfputint16(0, fout); + gbfputcstr("TXT", fout); + for (i = 0; i < 12; i++) gbfputc(0, fout); +} + +static void +destinator_rtept_disp(const waypoint *wpt) +{ + write_wcstr(DST_ITINERARY); + write_wcstr((wpt->shortname) ? wpt->shortname : "RTEPT"); + write_wcstr((wpt->notes) ? wpt->notes : wpt->description); + + gbfputint32(0, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); + + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + + gbfputdbl(0, fout); + gbfputdbl(0, fout); +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +destinator_rd_init(const char *fname) +{ + fin = gbfopen_le(fname, "rb", MYNAME); +} + +static void +destinator_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +destinator_read_poi_wrapper(void) +{ + data_type = wptdata; + destinator_read(); +} + +static void +destinator_read_rte_wrapper(void) +{ + data_type = rtedata; + destinator_read(); +} + +static void +destinator_read_trk_wrapper(void) +{ + data_type = trkdata; + destinator_read(); +} + +static void +destinator_wr_init(const char *fname) +{ + fout = gbfopen_le(fname, "wb", MYNAME); +} + +static void +destinator_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +destinator_write_poi(void) +{ + waypt_disp_all(destinator_wpt_disp); +} + +static void +destinator_write_rte(void) +{ + route_disp_all(NULL, NULL, destinator_rtept_disp); +} + +static void +destinator_write_trk(void) +{ + track_disp_all(NULL, NULL, destinator_trkpt_disp); +} + +/**************************************************************************/ + +ff_vecs_t destinator_poi_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + destinator_rd_init, + destinator_wr_init, + destinator_rd_deinit, + destinator_wr_deinit, + destinator_read_poi_wrapper, + destinator_write_poi, + NULL, + destinator_args, + CET_CHARSET_UTF8, 1 /* fixed */ +}; + +ff_vecs_t destinator_itn_vecs = { + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_read | ff_cap_write /* routes */ + }, + destinator_rd_init, + destinator_wr_init, + destinator_rd_deinit, + destinator_wr_deinit, + destinator_read_rte_wrapper, + destinator_write_rte, + NULL, + destinator_args, + CET_CHARSET_UTF8, 1 /* fixed */ +}; + +ff_vecs_t destinator_trl_vecs = { + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + destinator_rd_init, + destinator_wr_init, + destinator_rd_deinit, + destinator_wr_deinit, + destinator_read_trk_wrapper, + destinator_write_trk, + NULL, + destinator_args, + CET_CHARSET_UTF8, 1 /* fixed */ +}; + +/**************************************************************************/ diff --git a/dg-100.c b/dg-100.c new file mode 100644 index 000000000..051857858 --- /dev/null +++ b/dg-100.c @@ -0,0 +1,689 @@ +/* + + GlobalSat DG-100 GPS data logger download. + + Copyright (C) 2007 Mirko Parthey, mirko.parthey@informatik.tu-chemnitz.de + Copyright (C) 2005-2008 Robert Lipe, robertlipe@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +/* + DG-100 communication protocol specification: + http://www.usglobalsat.com/forum/topic.asp?TOPIC_ID=607#1375 + */ + +#include "defs.h" +#include + +#include "gbser.h" +#include +#include + +#define MYNAME "DG-100" + +static void *serial_handle; + +/* maximum frame size observed so far: 1817 bytes + * (dg100cmd_getfileheader returning 150 entries) + * dg100cmd_getfileheader is the only answer type of variable length, + * answers of other types are always shorter than 1817 bytes */ +#define FRAME_MAXLEN 4096 + +enum dg100_command_id { + dg100cmd_getconfig = 0xB7, + dg100cmd_setconfig = 0xB8, + dg100cmd_getfileheader = 0xBB, + dg100cmd_getfile = 0xB5, + dg100cmd_erase = 0xBA, + dg100cmd_getid = 0xBF, + dg100cmd_setid = 0xC0, + dg100cmd_gpsmouse = 0xBC +}; + +struct dg100_command { + int id; + int sendsize; + int recvsize; + int trailing_bytes; + const char *text; /* Textual description for debugging */ +}; + +struct dg100_command dg100_commands[] = { + { dg100cmd_getconfig, 0, 44+2, 2, "getconfig" }, + { dg100cmd_setconfig, 41, 4+2, 2, "setconfig" }, + /* the getfileheader answer has variable length, -1 is a dummy value */ + { dg100cmd_getfileheader, 2, -1 , 2, "getfileheader" }, + { dg100cmd_getfile, 2, 1024+2, 2, "getfile" }, + { dg100cmd_erase, 2, 4+2, 2, "erase" }, + { dg100cmd_getid, 0, 8+2, 2, "getid" }, + { dg100cmd_setid, 8, 4+2, 2, "setid" }, + { dg100cmd_gpsmouse, 1, 0 , 0, "gpsmouse" } +}; +const unsigned dg100_numcommands = sizeof(dg100_commands) / sizeof(dg100_commands[0]); + +/* TODO: use obstacks or vmem_t instead? */ +struct dynarray16 { + unsigned count; /* number of elements used */ + unsigned limit; /* number of elements allocated */ + gbint16 *data; +}; + +/* helper functions */ +static struct dg100_command * +dg100_findcmd(int id) +{ + unsigned int i; + + /* linear search should be OK as long as dg100_numcommands is small */ + for (i = 0; i < dg100_numcommands; i++) { + if (dg100_commands[i].id == id) + return(&dg100_commands[i]); + } + + return NULL; +} + +static void +dynarray16_init(struct dynarray16 *a, unsigned limit) +{ + a->count = 0; + a->limit = limit; + a->data = xmalloc(sizeof(a->data[0]) * a->limit); +} + +static gbint16 * +dynarray16_alloc(struct dynarray16 *a, unsigned n) +{ + unsigned int i; + unsigned int need; + const unsigned elements_per_chunk = 4096 / sizeof(a->data[0]); + + i = a->count; + a->count += n; + + need = a->count - a->limit; + if (need > 0) { + need = (need > elements_per_chunk) ? need : elements_per_chunk; + a->limit += need; + xrealloc(a->data, sizeof(a->data[0]) * a->limit); + } + return(a->data + i); +} + +static time_t +bintime2utc(int date, int time) +{ + struct tm gpstime; + + gpstime.tm_sec = time % 100; + time /= 100; + gpstime.tm_min = time % 100; + time /= 100; + gpstime.tm_hour = time; + + /* + * GPS year: 2000+; struct tm year: 1900+ + * GPS month: 1-12, struct tm month: 0-11 + */ + gpstime.tm_year = date % 100 + 100; + date /= 100; + gpstime.tm_mon = date % 100 - 1; + date /= 100; + gpstime.tm_mday = date; + + return(mkgmtime(&gpstime)); +} + +static void +dg100_debug(const char *hdr, int include_nl, size_t sz, unsigned char *buf) +{ + unsigned int i; + + /* Only give byte dumps for higher debug levels */ + if (global_opts.debug_level < 5) { + return; + } + + fprintf(stderr, "%s", hdr); + + for (i = 0; i < sz; i++) { + fprintf(stderr, "%02x ", buf[i]); + } + + if (include_nl) { + fprintf(stderr, "\n"); + } +} + +static void +dg100_log(const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + if (global_opts.debug_level < 1) { + return; + } + + vfprintf(stderr, fmt, ap); + va_end(ap); +} + + +/* TODO: check whether negative lat/lon (West/South) are handled correctly */ +static float +bin2deg(int val) +{ + /* Assume that val prints in decimal digits as [-]dddmmffff + * ddd: degrees + * mm: the integer part of minutes + * ffff: the fractional part of minutes (decimal fraction 0.ffff) + */ + + float deg; + int deg_int, min_scaled, isneg; + unsigned absval; + + /* avoid division of negative integers, + * which has platform-dependent results */ + absval = abs(val); + isneg = (val < 0); + + deg_int = absval / 1000000; /* extract ddd */ + min_scaled = absval % 1000000; /* extract mmffff (minutes * 10^4) */ + deg = deg_int + (double) min_scaled / (10000 * 60); + + /* restore the sign */ + deg = isneg ? -deg : deg; + return(deg); +} + +static void +process_gpsfile(gbuint8 data[], route_head *track) +{ + const int recordsizes[3] = {8, 20, 32}; + int i, style, recsize; + int lat, lon, bintime, bindate; + waypoint *wpt; + + /* the first record of each file is always full-sized; its style field + * determines the format of all subsequent records in the file */ + style = be_read32(data + 28); + if (style > 2) { + fprintf(stderr, "unknown GPS record style %d", style); + return; + } + recsize = recordsizes[style]; + + for (i = 0; i <= 2048 - recsize; i += (i == 0) ? 32 : recsize) { + + lat = be_read32(data + i + 0); + lon = be_read32(data + i + 4); + + /* skip invalid trackpoints (blank records) */ + if (lat == -1 && lon == -1) { + continue; + } + + wpt = waypt_new(); + wpt->latitude = bin2deg(lat); + wpt->longitude = bin2deg(lon); + + if (style >= 1) { + bintime = be_read32(data + i + 8); + bindate = be_read32(data + i + 12); + wpt->creation_time = bintime2utc(bindate, bintime); + /* The device presents the speed as a fixed-point number + * with a scaling factor of 100, in km/h. + * The waypoint struct wants the speed as a + * floating-point number, in m/s. */ + wpt->speed = KPH_TO_MPS(be_read32(data + i + 16) / 100.0); + wpt->wpt_flags.speed = 1; + } + + if (style >= 2) { + wpt->altitude = be_read32(data + i + 20) / 10000.0; + } + + track_add_wpt(track, wpt); + } +} + +static gbuint16 +dg100_checksum(gbuint8 buf[], int count) +{ + gbuint16 sum = 0; + int i; + + for (i = 0; i < count; i++) { + sum += buf[i]; + } + sum &= (1<<15) - 1; + + return(sum); +} + +/* communication functions */ +static size_t +dg100_send(gbuint8 cmd, const void *payload, size_t count) +{ + gbuint8 frame[FRAME_MAXLEN]; + gbuint16 checksum, payload_len; + size_t framelen, param_len; + int n; + + param_len = count; + payload_len = 1 + count; + /* Frame length calculation: + * frame start sequence(2), payload length field(2), command id(1), + * param(variable length), + * checksum(2), frame end sequence(2) */ + framelen = 2 + 2 + 1 + count + 2 + 2; + assert(framelen <= FRAME_MAXLEN); + + /* create frame head + command */ + be_write16(frame + 0, 0xA0A2); + be_write16(frame + 2, payload_len); + frame[4] = cmd; + + /* copy payload */ + memcpy(frame + 5, payload, count); + + /* create frame tail */ + checksum = dg100_checksum(frame + 4, framelen - 8); + be_write16(frame + framelen - 4, checksum); + be_write16(frame + framelen - 2, 0xB0B3); + + n = gbser_write(serial_handle, frame, framelen); + + if (global_opts.debug_level) { + struct dg100_command *cmdp = dg100_findcmd(cmd); + + dg100_debug(n == 0 ? "Sent: " : "Error Sending:", + 1, framelen, frame); + dg100_log("TX: Frame Start %02x %02x Payload_Len %04x Cmd: %s\n", + frame[0], frame[1], payload_len, cmdp->text); + } + + if (n == gbser_ERROR) { + fatal("dg_100_send: write failed\n"); + } + return (n); +} + +static int +dg100_recv_byte() +{ + int result; + + /* allow for a delay of 40s; + * erasing the whole DG-100 memory takes about 21s */ + result = gbser_readc_wait(serial_handle, 40000); + switch(result){ + case gbser_ERROR: + fatal("dg100_recv_byte(): error reading one byte\n"); + case gbser_NOTHING: + fatal("dg100_recv_byte(): read timeout\n"); + } + return result; +} + +/* payload returns a pointer into a static buffer (which also contains the + * framing around the data), so the caller must copy the data before calling + * this function again */ +static int +dg100_recv_frame(struct dg100_command **cmdinfo_result, gbuint8 **payload) +{ + static gbuint8 buf[FRAME_MAXLEN]; + gbuint16 frame_start_seq, payload_len_field; + gbuint16 payload_end_seq, payload_checksum, frame_end_seq; + gbuint16 frame_head, numheaders, sum; + gbuint8 c, cmd; + int i, param_len, frame_len; + struct dg100_command *cmdinfo; + + /* consume input until frame head sequence 0xA0A2 was received */ + frame_head = 0; + dg100_debug("Receiving ", 0, 0, NULL); + do { + c = dg100_recv_byte(); + dg100_debug("", 0, 1, &c); + frame_head <<= 8; + frame_head |= c; + + } while (frame_head != 0xA0A2); + + be_write16(buf + 0, frame_head); + + /* To read the remaining data, we need to know how long the frame is. + * + * The obvious source of this information would be the payload length + * field, but the spec says that this field should be ignored in answers. + * Indeed, its value differs from the actual payload length. + * + * We could scan for the frame end sequences, + * but there is no guarantee that they do not appear within valid data. + * + * This means we can only calculate the length using information from + * the beginning of the frame, other than the payload length. + * + * The solution implemented here is to derive the frame length from the + * Command ID field, which is more of an answer ID. This is possible + * since for each answer ID, the frame length is either constant or it + * can be derived from the first two bytes of payload data. + */ + + /* read Payload Length, Command ID, and two further bytes */ + for (i = 2; i < 7; i++) { + buf[i] = dg100_recv_byte(); + dg100_debug("", 0, 1, &buf[i]); + } + + payload_len_field = be_read16(buf + 2); + cmd = buf[4]; + + /* + * getconfig/setconfig have the same answer ID - + * this seems to be a firmware bug we must work around. + * Distinguish them by the (otherwise ignored) Payload Len field, + * which was observed as 53 for getconfig and 5 for setconfig. + */ + if (cmd == dg100cmd_getconfig && payload_len_field <= 20) { + cmd = dg100cmd_setconfig; + } + + cmdinfo = dg100_findcmd(cmd); + if (!cmdinfo) { + /* TODO: consume data until frame end signature, + * then report failure to the caller? */ + fatal("unknown answer ID %02x\n", cmd); + } + + param_len = cmdinfo->recvsize; + + /* + * the getfileheader answer has a varying param_len, + * we need to calculate it + */ + if (cmd == dg100cmd_getfileheader) { + numheaders = be_read16(buf + 5); + param_len = 2 + 2 + 12 * numheaders + 2; + } + + /* Frame length calculation: + * frame start sequence(2), payload length field(2), command id(1), + * param(variable length), + * payload end seqence(2), checksum(2), frame end sequence(2) */ + frame_len = 2 + 2 + 1 + param_len + 2 + 2 + 2; + + if (frame_len > FRAME_MAXLEN) { + fatal("frame too large (frame_len=%d, FRAME_MAXLEN=%d)\n", + frame_len, FRAME_MAXLEN); + } + + /* TODO: Since we know how long the frame should be, we could try to + * read the rest of the frame at once using gbser_read_wait(). */ +#if 0 + for (i = 7; i < frame_len; i++) { + buf[i] = dg100_recv_byte(); + dg100_debug("", 0, 1, &buf[i]); + } +#else + i = gbser_read_wait(serial_handle, &buf[7], frame_len - 7, 1000); + dg100_debug("", 0, frame_len - 7, &buf[7]); + if (i < frame_len - 7) { + fatal("Expected to read %d bytes, but got %d\n", + frame_len - 7, i); + } +#endif + + frame_start_seq = be_read16(buf + 0); + payload_len_field = be_read16(buf + 2); + payload_end_seq = be_read16(buf + frame_len - 6); + payload_checksum = be_read16(buf + frame_len - 4); + frame_end_seq = be_read16(buf + frame_len - 2); + + dg100_log("RX: Start %04x Len %04x Cmd: %s\n", + frame_start_seq, payload_len_field, cmdinfo->text); + + /* calculate checksum */ + sum = dg100_checksum(buf + 4, frame_len - 8); + if (sum != payload_checksum) { + fatal("checksum mismatch: data sum is 0x%04x, checksum received is 0x%04x\n", + sum, payload_checksum); + } + + /* + * TODO: check signatures; + * on failure, flush input or scan for end sequence + */ + + *cmdinfo_result = cmdinfo; + *payload = buf + 5; + dg100_debug("\n", 0, 0, &buf[i]); + return(param_len); +} + +/* return value: number of bytes copied into buf, -1 on error */ +static int +dg100_recv(gbuint8 expected_id, void *buf, unsigned int len) +{ + int n; + struct dg100_command *cmdinfo; + gbuint8 *data; + unsigned int copysize, trailing_bytes; + + n = dg100_recv_frame(&cmdinfo, &data); + + /* check whether the received frame matches the expected answer type */ + if (cmdinfo->id != expected_id) { + fprintf(stderr, "ERROR: answer type %02x, expecting %02x", cmdinfo->id, expected_id); + return -1; + } + + trailing_bytes = cmdinfo->trailing_bytes; + copysize = n - trailing_bytes; + + /* check for buffer overflow */ + if (len < copysize) { + fprintf(stderr, "ERROR: buffer too small, size=%d, need=%d", len, copysize); + return -1; + } + + memcpy(buf, data, copysize); + return(copysize); +} + +/* the number of bytes to be sent is determined by cmd, + * count is the size of recvbuf */ +static int +dg100_request(gbuint8 cmd, const void *sendbuf, void *recvbuf, size_t count) +{ + struct dg100_command *cmdinfo; + int n, i, frames, fill; + gbuint8 *buf; + + cmdinfo = dg100_findcmd(cmd); + assert (cmdinfo != NULL); + dg100_send(cmd, sendbuf, cmdinfo->sendsize); + + /* the number of frames the answer will comprise */ + frames = (cmd == dg100cmd_getfile) ? 2 : 1; + /* alias pointer for easy typecasting */ + buf = recvbuf; + fill = 0; + for (i = 0; i < frames; i++) { + n = dg100_recv(cmd, buf + fill, count - fill); + if (n < 0) + return(-1); + fill += n; + } + return(fill); +} + +/* higher level communication functions */ +static void +dg100_getfileheaders(struct dynarray16 *headers) +{ + gbuint8 request[2]; + gbuint8 answer[FRAME_MAXLEN]; + int seqnum; + gbint16 numheaders, nextheader, *h; + int i, offset; + + nextheader = 0; + do { + /* request the next batch of headers */ + be_write16(request, nextheader); + dg100_request(dg100cmd_getfileheader, request, answer, sizeof(answer)); + + /* process the answer */ + numheaders = be_read16(answer); + nextheader = be_read16(answer + 2); + dg100_log("found %d headers, nextheader=%d\n", + numheaders, nextheader); + + h = dynarray16_alloc(headers, numheaders); + for (i = 0; i < numheaders; i++) { + offset = 4 + i * 12; + seqnum = be_read32(answer + offset + 8); + h[i] = seqnum; + if (global_opts.debug_level) { + int time = be_read32(answer + offset); + int date = be_read32(answer + offset + 4); + time_t ti = bintime2utc(date, time); + dg100_log("Header #%d: Seq: %d Time: %s", + i, seqnum, ctime(&ti)); + } + } + } while (nextheader != 0); +} + +static void +dg100_getfile(gbint16 num, route_head *track) +{ + gbuint8 request[2]; + gbuint8 answer[2048]; + + be_write16(request, num); + dg100_request(dg100cmd_getfile, request, answer, sizeof(answer)); + process_gpsfile(answer, track); +} + +static void +dg100_getfiles() +{ + unsigned int i; + int filenum; + struct dynarray16 headers; + route_head *track; + + track = route_head_alloc(); + track->rte_name = xstrdup("DG-100 tracklog"); + track->rte_desc = xstrdup("DG-100 GPS tracklog data"); + track_add_head(track); + + /* maximum number of headers observed so far: 672 + * if necessary, the dynarray will grow even further */ + dynarray16_init(&headers, 1024); + + dg100_getfileheaders(&headers); + + for (i = 0; i < headers.count; i++) { + filenum = headers.data[i]; + dg100_getfile(filenum, track); + } +} + +static int +dg100_erase() +{ + gbuint8 request[2] = { 0xFF, 0xFF }; + gbuint8 answer[4]; + + dg100_request(dg100cmd_erase, request, answer, sizeof(answer)); + if (be_read32(answer) != 1) { + fprintf(stderr, "dg100_erase() FAILED\n"); + return(-1); + } + return(0); +} + +/* GPSBabel integration */ + +static char *erase; + +static +arglist_t dg100_args[] = { + { "erase", &erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +dg100_rd_init(const char *fname) +{ + if (serial_handle = gbser_init(fname), NULL == serial_handle) { + fatal(MYNAME ": Can't open port '%s'\n", fname); + } + if (gbser_set_speed(serial_handle, 115200) != gbser_OK) { + fatal(MYNAME ": Can't configure port '%s'\n", fname); + } +} + +static void +dg100_rd_deinit(void) +{ + gbser_deinit(serial_handle); + serial_handle = NULL; +} + +static void +dg100_read(void) +{ + dg100_getfiles(); + if (*erase == '1') { + dg100_erase(); + } +} + +/**************************************************************************/ + +// capabilities below means: we can only read tracks + +ff_vecs_t dg100_vecs = { + ff_type_serial, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + dg100_rd_init, + NULL, + dg100_rd_deinit, + NULL, + dg100_read, + NULL, + NULL, + dg100_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ +}; +/**************************************************************************/ diff --git a/discard.c b/discard.c new file mode 100644 index 000000000..0a8d29e4d --- /dev/null +++ b/discard.c @@ -0,0 +1,142 @@ +/* + Discard points based on high Degree of Precision (DOP) values. + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED +static char *hdopopt = NULL; +static char *vdopopt = NULL; +static char *andopt = NULL; +static char *satopt = NULL; +static double hdopf; +static double vdopf; +static int satpf; +static gpsdata_type what; +static route_head *head; + +static +arglist_t fix_args[] = { + {"hdop", &hdopopt, "Suppress waypoints with higher hdop", + "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX}, + {"vdop", &vdopopt, "Suppress waypoints with higher vdop", + "-1.0", ARGTYPE_END_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX}, + {"hdopandvdop", &andopt, "Link hdop and vdop supression with AND", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"sat", &satopt, "Minimium sats to keep waypoints", + "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +/* + * Decide whether to keep or toss this point. + */ +static void +fix_process_wpt(const waypoint *wpt) +{ + int del = 0; + int delh = 0; + int delv = 0; + + waypoint *waypointp = (waypoint *) wpt; + + if ((hdopf >= 0.0) && (waypointp->hdop > hdopf)) + delh = 1; + if ((vdopf >= 0.0) && (waypointp->vdop > vdopf)) + delv = 1; + + if (andopt) + del = delh && delv; + else + del = delh || delv; + + if ((satpf >= 0) && (waypointp->sat < satpf)) + del = 1; + + if (del) { + switch(what) { + case wptdata: + waypt_del(waypointp); + break; + case trkdata: + track_del_wpt(head, waypointp); + break; + case rtedata: + route_del_wpt(head, waypointp); + break; + default: + return; + } + waypt_free(waypointp); + } +} + +static void +fix_process_head(const route_head *trk) +{ + head = (route_head *)trk; +} + +static void +fix_process(void) +{ + // Filter waypoints. + what = wptdata; + waypt_disp_all(fix_process_wpt); + + // Filter tracks + what = trkdata; + track_disp_all(fix_process_head, NULL, fix_process_wpt); + + // And routes + what = rtedata; + route_disp_all(fix_process_head, NULL, fix_process_wpt); + +} + +static void +fix_init(const char *args) +{ + if (hdopopt) + hdopf = atof(hdopopt); + else + hdopf = -1.0; + + if (vdopopt) + vdopf = atof(vdopopt); + else + vdopf = -1.0; + + if (satopt) + satpf = atoi(satopt); + else + satpf = -1; + +} + +filter_vecs_t discard_vecs = { + fix_init, + fix_process, + NULL, + NULL, + fix_args +}; +#endif diff --git a/dmtlog.c b/dmtlog.c new file mode 100644 index 000000000..0d11cf2ca --- /dev/null +++ b/dmtlog.c @@ -0,0 +1,796 @@ +/* + + Support for TrackLogs digital mapping (.trl) files, + + Copyright (C) 2006,2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "jeeps/gpsmath.h" +#include "xmlgeneric.h" + +#include +#include +#include + +#define MYNAME "dmtlog" + +#define DEFLATE_BUFF_SIZE 16384 + +static gbfile *fin, *fout; + +static char *xmlbin; +static waypoint *xmlwpt; +static route_head *xmltrk; +static char *xmlgrid; +static int xmldatum; +static double xmlEasting, xmlNorthing; +static double xmlLatitude, xmlLongitude; +static double xmlAltitude; + +#if !ZLIB_INHIBITED +static int xmlbinsize; +#endif + +static char header_written; +static char *opt_index; +static int track_index, this_index; + +static +arglist_t dmtlog_args[] = { + { "index", &opt_index, + "Index of track (if more the one in source)", "1", ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + + +#if !ZLIB_INHIBITED +static xg_callback tlog3a_xgcb_version, tlog3a_xgcb_length, tlog3a_xgcb_data; + +static xg_tag_mapping tlog3a_xgcb_map[] = { + { tlog3a_xgcb_version, cb_cdata, "/CXMLSafe/Version" }, + { tlog3a_xgcb_length, cb_cdata, "/CXMLSafe/Length" }, + { tlog3a_xgcb_data, cb_cdata, "/CXMLSafe/Data" }, + { NULL, 0, NULL} +}; +#endif + +static xg_callback tlog3b_xgcb_tfna, tlog3b_xgcb_tfdes; +static xg_callback tlog3b_xgcb_wptst, tlog3b_xgcb_tptst; +static xg_callback tlog3b_xgcb_tpten, tlog3b_xgcb_wpten; +static xg_callback tlog3b_xgcb_wptid, tlog3b_xgcb_wptdt; +static xg_callback tlog3b_xgcb_wptgr, tlog3b_xgcb_wptea; +static xg_callback tlog3b_xgcb_wptno, tlog3b_xgcb_wptal; +static xg_callback tlog3b_xgcb_tptdt; + +static xg_tag_mapping tlog3b_xgcb_map[] = { + { tlog3b_xgcb_tfna, cb_cdata, "/CTrackFile/Name" }, + { tlog3b_xgcb_tfdes, cb_cdata, "/CTrackFile/Description" }, + { tlog3b_xgcb_wptst, cb_start, "/CTrackFile/CWayPoint" }, + { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CWayPoint/Id" }, + { tlog3b_xgcb_wptdt, cb_cdata, "/CTrackFile/CWayPoint/Datum" }, + { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CWayPoint/Grid" }, + { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CWayPoint/Easting" }, + { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CWayPoint/Northing" }, + { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CWayPoint/Altitude" }, + { tlog3b_xgcb_wpten, cb_end, "/CTrackFile/CWayPoint" }, + { tlog3b_xgcb_tptst, cb_start, "/CTrackFile/CTrackPoint" }, + { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CTrackPoint/Id" }, + { tlog3b_xgcb_tptdt, cb_cdata, "/CTrackFile/CTrackPoint/Datum" }, + { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CTrackPoint/Grid" }, + { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CTrackPoint/Easting" }, + { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CTrackPoint/Northing" }, + { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CTrackPoint/Altitude" }, + { tlog3b_xgcb_tpten, cb_end, "/CTrackFile/CTrackPoint" }, + { NULL, 0, NULL} +}; + +/* helpers */ + +static void +convert_datum(waypoint *wpt, int datum) +{ + if (datum != DATUM_WGS84) { + double lat = wpt->latitude; + double lon = wpt->longitude; + double alt = wpt->altitude; + GPS_Math_Known_Datum_To_WGS84_C(lat, lon, alt, + &wpt->latitude, &wpt->longitude, &wpt->altitude, + datum); + } +} + + +static void +finalize_pt(waypoint *wpt) +{ + if (strcmp(xmlgrid, "BNG") == 0) { + GPS_Math_NGENToAiry1830LatLon(xmlEasting, xmlNorthing, + &wpt->latitude, &wpt->longitude); + xmldatum = DATUM_OSGB36; + } + else { + wpt->latitude = xmlLatitude; + wpt->longitude = xmlLongitude; + } + /* NOTE: + * Alan White reports this program actually subtracts a number + * of meters ranging between 46 and 50 meters. It appears to be + * constant for each location, but different without an obvious + * correlation to ground altitude. We considered offsetting this + * in GPSBabel, but concluded it wasn't worth the bother. + * If we get complaints, probably all of our alt reading and writing + * should offset an average of 46m or so. + */ + wpt->altitude = xmlAltitude; + convert_datum(wpt, xmldatum); +} + +/* xml-reader callbacks */ + +#if !ZLIB_INHIBITED +static void +tlog3a_xgcb_version(const char *args, const char **unused) +{ + if (strcmp(args, "1") != 0) + fatal(MYNAME ": Unsupported file version '%s'!\n", args); +} + +static void +tlog3a_xgcb_length(const char *args, const char **unused) +{ +} + +static void +tlog3a_xgcb_data(const char *args, const char **unused) +{ + int len; + char *bin; + char *cin, *cout; + char cl, ch; + + len = strlen(args); + bin = xmalloc((len >> 1) + 1); + + cin = (char *)args; + cout = bin; + + cl = 0x10; + while (*cin) { + char c = *cin++; + + if (c == '\0') break; + else if ((c >= 'A') && (c <= 'F')) c -= 'A' - 10; + else if ((c >= 'a') && (c <= 'f')) c -= 'a' - 10; + else if ((c >= '0') && (c <= '9')) c -= '0'; + else continue; + + if (cl == 0x10) cl = c; + else { + ch = (cl << 4) | c; + *cout++ = ch; + cl = 0x10; + } + } + xmlbin = bin; + xmlbinsize = (cout - bin); +} +#endif + + +static void +tlog3b_xgcb_tfna(const char *args, const char **unused) +{ + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + xmltrk->rte_name = strdup(args); +} + + +static void +tlog3b_xgcb_tfdes(const char *args, const char **unused) +{ + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + xmltrk->rte_desc = strdup(args); +} + + +static void +tlog3b_xgcb_wptst(const char *args, const char **unused) +{ + xmlwpt = waypt_new(); + xmldatum = DATUM_WGS84; +} + + +static void +tlog3b_xgcb_tptst(const char *args, const char **unused) +{ + xmlwpt = waypt_new(); + xmldatum = DATUM_WGS84; +} + + +static void +tlog3b_xgcb_tpten(const char *args, const char **unused) +{ + finalize_pt(xmlwpt); + + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + track_add_wpt(xmltrk, xmlwpt); + xmlwpt = NULL; +} + + +static void +tlog3b_xgcb_wptid(const char *args, const char **unused) +{ + if (*args) + xmlwpt->shortname = xstrdup(args); +} + + +static void +tlog3b_xgcb_wptdt(const char *args, const char **unused) +{ + xmldatum = GPS_Lookup_Datum_Index(args); +} + + +static void +tlog3b_xgcb_wptgr(const char *args, const char **unused) +{ + if (xmlgrid != NULL) { + if (strcmp(xmlgrid, args) == 0) return; + xfree(xmlgrid); + } + xmlgrid = xstrdup(args); +} + + +static void +tlog3b_xgcb_wptno(const char *args, const char **unused) +{ + xmlNorthing = atof(args); +} + + +static void +tlog3b_xgcb_wptea(const char *args, const char **unused) +{ + xmlEasting = atof(args); +} + + +static void +tlog3b_xgcb_wptal(const char *args, const char **unused) +{ + xmlAltitude = atof(args); +} + + +static void +tlog3b_xgcb_tptdt(const char *args, const char **unused) +{ + xmldatum = GPS_Lookup_Datum_Index(args); +} + + +static void +tlog3b_xgcb_wpten(const char *args, const char **unused) +{ + finalize_pt(xmlwpt); + waypt_add(xmlwpt); + xmlwpt = NULL; +} + + +static char * +read_str(gbfile *f) +{ + int i; + char *res; + + i = gbfgetc(f); + if (i == 0xff) i = gbfgetint16(f); + + res = xmalloc(i + 1); + res[i] = '\0'; + if (i) gbfread(res, 1, i, f); + + return res; +} + +static void +write_str(const char *str, gbfile *f) +{ + if (str && *str) { + int len = strlen(str); + if (len > 0xfe) { +#if 0 + if (len > 0x7fff) len = 0x7fff; + gbfputc((unsigned char) 0xff, f); + gbfputint16(len, f); +#else + len = 0xfe; + gbfputc(len, f); +#endif + } + else gbfputc(len, f); + gbfwrite(str, len, 1, f); + } + else gbfputc(0, f); +} + +static int +read_datum(gbfile *f) +{ + int res; + char *d, *g; + + d = read_str(f); + g = read_str(f); + + res = GPS_Lookup_Datum_Index(d); + + if (*g && (strcmp(d, g) != 0)) { + fatal(MYNAME ": Unsupported combination of datum '%s' and grid '%s'!\n", + d, g); + } + xfree(d); + xfree(g); + + return res; +} + + +static void +read_CTrackFile(const int version) +{ + char buf[128]; + gbuint32 ver; + gbint32 tcount, wcount; + gbint16 u1; + gbint32 ux; + route_head *track; + int i; + int datum; + + u1 = gbfgetint16(fin); + + gbfread(buf, 1, 10, fin); + if ((u1 != 0x0a) || (strncmp("CTrackFile", buf, 10) != 0)) + fatal(MYNAME ": Unknown or invalid track file.\n"); + + if (version == 8) + gbfseek(fin, 36, SEEK_CUR); /* skip unknown 36 bytes */ + + ver = gbfgetint32(fin); + if (ver != version) + fatal(MYNAME ": Unknown or invalid track file (%d).\n", ver); + + ux = gbfgetint32(fin); // Unknown 2 + ux = gbfgetint32(fin); // Unknown 3 + ux = gbfgetint32(fin); // Unknown 4 + + track = route_head_alloc(); + track_add_head(track); + + /* S1 .. S9: comments, hints, jokes, aso */ + for (i = 0; i < 9; i++) { + char *s = read_str(fin); + xfree(s); + } + + tcount = gbfgetint32(fin); + if (tcount > 0) { + datum = read_datum(fin); + if (version == 8) { + int len; + + gbfread(buf, 1, 4, fin); + len = gbfgetint16(fin); + gbfseek(fin, len, SEEK_CUR); + } + } + + while (tcount > 0) + { + waypoint *wpt; + + tcount--; + + if (version == 8) + datum = read_datum(fin); + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + convert_datum(wpt, datum); + + track_add_wpt(track, wpt); + + if (version == 8) + gbfseek(fin, 34, SEEK_CUR); /* skip unknown 34 bytes */ + } + + if (version == 8) { + + i = gbfgetint16(fin); + i = gbfgetc(fin); + if (i == 0) return; + + gbfungetc(i, fin); + datum = read_datum(fin); + + (void) gbfgetint16(fin); + (void) gbfgetint32(fin); + + gbfread(buf, 1, 9, fin); + if (strncmp(buf, "CWayPoint", 9) != 0) { + warning(MYNAME ": Unsupported waypoint structure!\n"); + return; + } + + while (! gbfeof(fin)) { + waypoint *wpt; + + i = gbfgetc(fin); + if (i == 0) break; + + gbfungetc(i, fin); + datum = read_datum(fin); + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + gbfseek(fin, 36, SEEK_CUR); /* skip unknown 36 bytes */ + + wpt->notes = read_str(fin); + wpt->description = read_str(fin); + (void) gbfgetint16(fin); + + waypt_add(wpt); + } + return; + } + + wcount = gbfgetint32(fin); + if (wcount == 0) return; + + datum = read_datum(fin); + + while (wcount > 0) { + waypoint *wpt; + gbint32 namect, i; + + wcount--; + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + convert_datum(wpt, datum); + + namect = gbfgetint32(fin); + + // variants of shortname + + for (i = 0; i < namect; i++) { + char *name; + + name = read_str(fin); + if (name && *name) { + switch(i) { + case 0: wpt->description = xstrdup(name); break; + case 1: wpt->shortname = xstrdup(name); break; + } + } + xfree(name); + } + + waypt_add(wpt); + } +} + + +#if !ZLIB_INHIBITED + +static int +inflate_buff(const char *buff, const size_t size, char **out_buff) +{ + int res = Z_OK; + z_stream strm; + char out[DEFLATE_BUFF_SIZE]; + char *cout = NULL; + gbuint32 bytes = 0; + gbuint32 have; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + + res = inflateInit(&strm); + if (res != Z_OK) { + return res; + } + + strm.avail_in = size; + strm.next_in = (void *)buff; + + do { + strm.avail_out = DEFLATE_BUFF_SIZE; + strm.next_out = (void *)out; + res = inflate(&strm, Z_NO_FLUSH); + + switch (res) { + case Z_NEED_DICT: + res = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return res; + } + have = DEFLATE_BUFF_SIZE - strm.avail_out; + if (have > 0) { + cout = xrealloc(cout, bytes + have); + memcpy(cout+bytes, out, have); + bytes+=have; + } + } while (strm.avail_out == 0); + + *out_buff = cout; + return res; +} + + +static void +read_CXMLSafe(void) +{ + char *xmlstr = NULL; + + xmlbin = NULL; + xmlbinsize = 0; + + xml_init(fin->name, tlog3a_xgcb_map, NULL); + xml_read(); + xml_deinit(); + + if (xmlbin != NULL) { + inflate_buff(xmlbin, xmlbinsize, &xmlstr); + xfree(xmlbin); + + xml_init(NULL, tlog3b_xgcb_map, NULL); + xml_readstring(xmlstr); + xml_deinit(); + + xfree(xmlstr); + } +} + +#endif + +static void +read_XML(void) +{ + xml_init(fin->name, tlog3b_xgcb_map, NULL); + xml_read(); + xml_deinit(); + + return; +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +dmtlog_rd_init(const char *fname) +{ + fin = gbfopen_le(fname, "rb", MYNAME); + + xmlbin = NULL; + xmltrk = NULL; + xmlwpt = NULL; + xmlgrid = NULL; +} + +static void +dmtlog_rd_deinit(void) +{ + gbfclose(fin); + if (xmlgrid != NULL) xfree(xmlgrid); +} + +static void +dmtlog_read(void) +{ + switch(gbfgetuint32(fin)) { + + case 0x4FFFF: + read_CTrackFile(4); + break; + + case 0x8FFFF: + read_CTrackFile(8); + break; + + case 0x4d58433c: +#if !ZLIB_INHIBITED + read_CXMLSafe(); +#else + fatal(MYNAME ": Zlib was not included in this build.\n"); +#endif + break; + case 0x7254433c: + read_XML(); + break; + + default: + fatal(MYNAME ": Unknown or unsupported file type.\n"); + } +} + +static void +dmtlog_wr_init(const char *fname) +{ + fout = gbfopen_le(fname, "wb", MYNAME); +} + +static void +dmtlog_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +write_header(const route_head *trk) +{ + int count, i; + char *cout; + const char ZERO = '\0'; + + header_written = 1; + + count = 0; + if (trk != NULL) { + queue *curr, *prev; + QUEUE_FOR_EACH(&trk->waypoint_list, curr, prev) count++; + } + write_str(trk && trk->rte_name && *trk->rte_name ? trk->rte_name : "Name", fout); + + xasprintf(&cout, "%d trackpoints and %d waypoints", count, waypt_count()); + write_str(cout, fout); + xfree(cout); + + for (i = 3; i <= 8; i++) gbfputc(ZERO, fout); + write_str("GPSBabel", fout); + gbfputint32(count, fout); + if (count > 0) { + write_str("WGS84", fout); + write_str("WGS84", fout); + } +} + +static void +track_hdr_cb(const route_head *trk) +{ + + this_index++; + if (this_index != track_index) return; + write_header(trk); +} + +static void +track_tlr_cb(const route_head *trk) +{ +} + +static void +track_wpt_cb(const waypoint *wpt) +{ + if (this_index != track_index) return; + + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); +} + +static void +wpt_cb(const waypoint *wpt) +{ + int names; + + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); + + names = 1; + if (wpt->description && *wpt->description) names = 2; + gbfputint32(names, fout); + if (names > 1) write_str(wpt->description, fout); + write_str(wpt->shortname && *wpt->shortname ? wpt->shortname : "Name", fout); +} + +static void +dmtlog_write(void) +{ + track_index = atoi(opt_index); + /* ... validate index */ + + gbfputint32(0x4FFFF, fout); + gbfputuint16(0x0A, fout); + gbfputs("CTrackFile", fout); + gbfputint32(4, fout); + gbfputint32(1, fout); + gbfputint32(0x100001, fout); + gbfputuint32((const gbuint32)gpsbabel_time, fout); + + header_written = 0; + this_index = 0; + track_disp_all(track_hdr_cb, track_tlr_cb, track_wpt_cb); + if (!header_written) + write_header(NULL); + gbfputint32(waypt_count(), fout); + if (waypt_count() > 0) { + write_str("WGS84", fout); + write_str("WGS84", fout); + waypt_disp_all(wpt_cb); + } +} + +/**************************************************************************/ + +ff_vecs_t dmtlog_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + dmtlog_rd_init, + dmtlog_wr_init, + dmtlog_rd_deinit, + dmtlog_wr_deinit, + dmtlog_read, + dmtlog_write, + NULL, + dmtlog_args, + CET_CHARSET_ASCII, 0 + +}; + +/**************************************************************************/ diff --git a/doc/.cvsignore b/doc/.cvsignore new file mode 100644 index 000000000..d82a47efd --- /dev/null +++ b/doc/.cvsignore @@ -0,0 +1,4 @@ +*.toc +*.aux +*.dvi +*.log diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 000000000..acda41108 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,7 @@ +doc.dvi: doc.tex + latex doc.tex + latex doc.tex + latex doc.tex + +clean: + rm -f *.toc *.aux *.dvi *.log diff --git a/doc/babelfront2.eps b/doc/babelfront2.eps new file mode 100644 index 000000000..478d74241 --- /dev/null +++ b/doc/babelfront2.eps @@ -0,0 +1,19937 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (ImageMagick) +%%Title: (babelfront2.eps) +%%CreationDate: (Tue Jun 17 21:11:51 2003) +%%BoundingBox: 0 0 563 419 +%%DocumentData: Clean7Bit +%%LanguageLevel: 1 +%%Pages: 1 +%%EndComments + +%%BeginDefaults +%%PageOrientation: Portrait +%%EndDefaults + +%%BeginProlog +% +% Display a color image. The image is displayed in color on +% Postscript viewers or printers that support color, otherwise +% it is displayed as grayscale. +% +/DirectClassPacket +{ + % + % Get a DirectClass packet. + % + % Parameters: + % red. + % green. + % blue. + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/DirectClassImage +{ + % + % Display a DirectClass image. + % + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { DirectClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayDirectClassPacket } image + } ifelse +} bind def + +/GrayDirectClassPacket +{ + % + % Get a DirectClass packet; convert to grayscale. + % + % Parameters: + % red + % green + % blue + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/GrayPseudoClassPacket +{ + % + % Get a PseudoClass packet; convert to grayscale. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassPacket +{ + % + % Get a PseudoClass packet. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassImage +{ + % + % Display a PseudoClass image. + % + % Parameters: + % class: 0-PseudoClass or 1-Grayscale. + % + currentfile buffer readline pop + token pop /class exch def pop + class 0 gt + { + currentfile buffer readline pop + token pop /depth exch def pop + /grays columns 8 add depth sub depth mul 8 idiv string def + columns rows depth + [ + columns 0 0 + rows neg 0 rows + ] + { currentfile grays readhexstring pop } image + } + { + % + % Parameters: + % colors: number of colors in the colormap. + % colormap: red, green, blue color packets. + % + currentfile buffer readline pop + token pop /colors exch def pop + /colors colors 3 mul def + /colormap colors string def + currentfile colormap readhexstring pop pop + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { PseudoClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayPseudoClassPacket } image + } ifelse + } ifelse +} bind def + +/DisplayImage +{ + % + % Display a DirectClass or PseudoClass image. + % + % Parameters: + % x & y translation. + % x & y scale. + % label pointsize. + % image label. + % image columns & rows. + % class: 0-DirectClass or 1-PseudoClass. + % compression: 0-none or 1-RunlengthEncoded. + % hex color packets. + % + gsave + /buffer 512 string def + /byte 1 string def + /color_packet 3 string def + /pixels 768 string def + + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + /Times-Roman findfont pointsize scalefont setfont + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + class 0 gt { PseudoClassImage } { DirectClassImage } ifelse + grestore +} bind def +%%EndProlog +%%Page: 1 1 +%%PageBoundingBox: 0 0 563 419 +userdict begin +DisplayImage +0 0 +563 419 +12.000000 +563 419 +0 +0 +e6f5ffd9f2ffdbffff000f20c5ffff0652b00043d5065dff004aed004ee30052d40056ce +0057d60057dc0056e70056e1075cdb0a5dd30a5dd30b5ed40a5fd40a5fd4095ed3095ed3 +075ed2075ed2075ed2065dd1065dd1065dd1035cd0025cd6005de0005de5005de5005de3 +005de3005ee0005ee0005fdc0060da0061d70061d70061d30062d30062d10062d10062d3 +0060d70060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +0060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d80060d8 +005ed6005ed6005ed6005ed6005ed6005ed6005ed6005ed6005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd8 +005dd8005dd8005dd8005dd8005dd8005dd8005dd8005dd1085fc8085bc50659d30658e0 +0253eb004feb0052eb035ae8045ed90460cf0760c8065ec8085bd10758dd0a54eb0257f2 +0060f4005ae90061f40069ff005cf8005eef0068e50061d60261e30355dd1057e3004ed0 +0061d3006cd90047c50347d00050e70052ec0052e90052e9004deb004ce3004cd6004ec6 +004fb1005cc0035fda004fd90039cc0949cdc3ffffd1ffffe9ffffe4ebfffbffffdaf0ff +daf6ffc7f1ff2c64950347921e6dd4146af3005af31d7aff1e7eff2282ff2789ff2b8dff +2d91ff2f91ff3192ff3894ff3a94ff3b95ff3b95ff3b95ff3996ff3a94ff3895ff3895ff +3895ff3794ff3794ff3794ff3693ff3594ff3593ff3593ff3593ff3593ff3593ff3593ff +3594ff3394ff3395ff3296ff3296ff3296ff3296ff3097ff3098ff3097ff3297ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff3395ff +3395ff3395ff3395ff3395ff3395ff3395ff3595ff2f8cff3a94ff3c95ff3893ff3c97ff +44a0ff3e9aff2f8cff3493ff3494ff3594ff3694ff3693ff3790ff388eff348fff2a92ff +2998ff2796ff2691ff2a90ff268dff2091ff2a98ff3597ff3a8eff4b94ff3289ff168eff +2196ff358aff4d97ff378fff3192ff3092ff3090ff328cff348aff3389ff328cff389aff +258af61c79fc2779ff3076ff1c61ed0042a9003a83e4fffff0fefff8ffffdcfcffe0ffff +1a45a41c50c6175bd6095cd63390ff0d6fec1677ff1878ff1d7cff2181ff2689fe298efa +2c91fd2c91ff2890ff278fff2990ff2990ff2990ff2890ff288fff268eff278fff278fff +278fff268eff268eff268eff258dff268dff2a8dff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2a8dff2a8dff2a8dff2a8dff2a8dff2a8dff2a8dff2a8dff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff2b8cff +2b8cff2b8cff2b8cff2b8cff2b8cff2a8bff3196ff268dff208aff1e8bff1e8cff1c8aff +1f8cff2591ff2590ff2590ff2791ff2792ff2793ff2794ff2993ff2b93ff2a8afa3894ff +2b89fb2784fd3792ff3193ff1d8dfd2393ff268aff1f78fa3083ff2c8bff1897ff1c9eff +2688ff2680fa248bf2218eed208ef0218bfb2487ff2582ff2580ff2581ff2080f91173f2 +2782ff2076ff0754ff1563ff0d61dd2269c3163c7aebfffff2ffffc6f0ff0e3b7f1946c5 +0e45dd2068f81067e8004fb90c75e20268f00466ff0866ff0b6afc0f6fe81173e21074e4 +0d74eb0676f60476fb0676fe0676fc0575fd0575fb0474fc0473f90573fc0574fa0573fc +0574fa0472fb0473f90371fa0670f70b70f20e6ff10e6ff10e6ff10e6ff10e6ff20e6ff2 +0e6ff40d6ff40d6ff60d6ff80d6ff80d6ff80d6ef90e6ef90e6ef80e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef8 +0e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60e6ef80e6ef60b6bf50b6bf30b6bf5 +0b6bf30b6bf50b6bf30b6bf50b6bf50b6bf50b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf60b6bf50b6bf6 +0b6bf50b6bf60b6bf50b6bf6086bfd0064ff006dff0577fc067bed0176e00071db0070ea +0473f90068fa0067fe0069f8006bf1006deb006ee8006ee8036ce20960d11d6ddc2175e9 +1b6fe91366e80865e8006de70274f0076aec065ee41365ed0965ea0060d80060d9005ee3 +085fe00660d00562ca0662d10461da065dea055bf0045aef045be80962e4004ed40356f0 +0856fe115cff0653f91f71f80044ae1640922a447de6fcffd5ffff23599f0b42c11456eb +0046d00464df016dd20059c50066f70264ff0463ff0765ff0869ee0869eb0867f70468fa +006ef8006ff60070f90070f7006ef8006ef5006cf6006bf3006cf6006cf4006bf6006af3 +0069f50069f30068f40068f00168e90467e60467e80467e80467e90466eb0466ed0466ef +0565f00564f20564f40564f60563f70563f90762f90762f70763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20763f40763f20763f40763f2 +0763f40763f20763f40763f20763f40763f20763f40763f20561f20561f00561f20561f0 +0561f20561f00561f20561f20561f20561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40561f20561f40561f20561f40561f20561f40561f20561f40561f2 +0561f40561f20561f40063f40060ee0273f70173e30062c50060c00570d80b71ed0063ec +0667f60667f60469ef036aeb026beb006af20068ff0466fb1466f0044ed30653dd105fef +0e5cf20f68ff0274ff0060f70060f5085aee0f57ea0f60ef006af10069f0085dec0748e0 +184aeb1b48ec194aed154bf3104cfc0b4cfc074ef40751e80b55d8135cdc0043d20039d5 +1354fa0038d70041ca0d49c10d37a5001979e4feff002b710e45a00742ca1057ef004fdc +0061e00056c50473e90060f4005eff005eff0061fa0264eb0365ec0361fe0063ff0067f6 +006af0006af2006af00068f10068ee0064ee0065ec0064ee0064ec0062ed0062eb0060ec +0061ea0060ec0060e90060e40060e20060e2005fe4005fe6005fe8005ee9005eeb005ded +005def005cf2005bf4005af6005af6005af8005af6005bf0005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef005cef +005cef005cef005cef005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0005bf0 +005bf0005bf0015bed035de7005ad4065fc3116bc1166cbf1162bd0f58c91257d61457dc +1358d9125ad00f5bc90c5ccb085bd30759e30a56e7195de40f4fd3165ae32063ef1251de +004adb0057ed0059eb0048d02457d61e46bf1540b30f4dba0e4db71e49b9243db42a33bc +2e31be2d34b92836bb1e38c0183bbd143cb5133ea710388f1a3f97183fa81039b50021b4 +1e51e80035c10133ba0024aa1938b5011d880c39b6002cb10642d80248e40051e4005be6 +005ce00054da0061f50061f80063f30066ee0168e80269ec0268fb0267fd0168f30269ec +0268ee0168eb0166ec0264e90262ea0162e70260e8035fe6035de7035de5055ce7045ce4 +055be6025ce6005de7005ee7005ee7005de8005de8005cea005cec005cee005aef005af1 +005af10059f30059f50059f50058f70059f5005aef005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee005aee +005aee005aee005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef005aef +005aef0856ea0a42d5426ff08cbaffccf8ffdbffffdcffffdef9ffe3faffe4f8ffe4f9ff +e2fcffdfffffdbffffd7ffffd5feffd1fdffc7f6ffcfffffcfffffbeedff90b7ff3665d1 +0045bb2062d0334ea5b9bafdfbeafffff3fffff7fff8ecffffeafffff1fffff1fffff2ff +fff3fffff6fffff9fffffbfffffdfffffdfffffcf8fffafffdf7ffcad0ff1c33a50325ad +0932c20932c81236d2000ea400199b0029c30022bd0c43e40246e50048e2004fe30065f5 +0060ee0061f10063ef0065e90067e70068e70068ea0066f50065f60063ec0263e80263e8 +0361e70260e6025ee5025ce4035be30258e10457e10356e00456e00555e00653df0653df +0255e10056e50057e90057e90057e90056e90056e90055ea0055ea0055ec0054ec0054ec +0054ec0054ec0053ee0053ee0054ec0054e90055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e70055e7 +0055e70055e70055e70055e70055e70053e50053e50053e50053e50053e50053e50053e5 +0053e50053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +0053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e70053e7 +034fe02251db8fb2ffc3e5ff90b1f6637db86c81c0737fd35b63c5656ad2626acd606cc2 +5c6eb8576eb2536eb3506cbf4a6cc64371d3376bd11748ae527cdec3e1ff96bbff1958c1 +1348a6b5baf2fedffed8a4b0b27676bb8382b87d77ba746ab97163b07160b0725bb5714e +b27149aa734ca6724aa47146a86e40ae6834a05c379b6563f4d8feb6baff1731aa0930bb +0029c1001bba0526bf000f960018b7052dcb0839de0140e5004ced0054ec0058e70061e8 +0061e6006bed0055d8036bee0772f6005fe70371fc005dea0057e20966f1015ee90054e0 +025ce8065dea0055e20156e40457e50455e4004fdf0b57e80b57e8024dde0651e20452e6 +004be20058f1004ce50054eb015af20050e80056ee0056ee0056eb0055eb0055ea0055ea +0055ea0055ea0055ea0056e80056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e60056e6 +0056e60056e60056e60056e60053e30053e30053e30053e30053e30053e30053e30053e3 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e5 +0053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50053e50052d9 +0e50c1c5fdff6ba2f28cc1ff85b2f686adfa7d9efd6d89f4758ffd7691fc6c8aea6e90ea +6589e75980e55f86fd507ef84481f63a7dee2f71e12a61c6274da2d6ffff0b53c2124caf +f7f9ffc198a6e9a9a0eda08ce89b89efa18bd98668dd886bdc8773e08572e37a5ce67a54 +dd7751ea845cd0653be97343ea632bdd5d2ebc5743804355fef5ff122f950335b20033c1 +0024b90526b3000f8a0019b4092dc90939d7053fde044de70054e50056e2005fe4005fe4 +0060e20369e9005ede005cde0066ee0060ef0061f20666f8005cec0057e80864f50059eb +025cee045def0d63f6085cf00053e70456ea004fe4004ee40553e9014fe50959f00255f1 +085ffc0459f40052ed0051ea0156ef0459f00050e70055ea0055ea0055e80055e60055e6 +0056e40056e40056e40056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30056e40057e30056e40057e30056e40057e30056e40057e30056e4 +0057e30056e40057e30054e20055e10054e20055e10054e20055e10054e20054e20054e2 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40054e20053e4 +0054e20053e40054e20053e40054e20053e40054e20053e40054e20053e40254d2155ab5 +c9ffff629ce57db2ff81afff89b1ff7fa5ff7899ff6689e7779bf1648ad56289d46d96e8 +638beb5d85f75785ff407ef9367bf42e6fe52b60c82c4c9fd8ffff0a51c71248b2fff7ff +bf8d90fbaf98ffb193f89c85da7e65f59b78e58866e6826bd5654fff9372f4734ced7552 +e16a48fa7b58ef643bfb5928f05328cd503a8c3e4bfff4ff1630910535b50031c20024b5 +0626ad001085001aab092fbe0d3bcc0843cf0750d30456d60057da035de50e68f4025ce6 +0965e20562d90563d70865e6005af30965ff005efa0055ee0058f10f71ff0056ef005bf5 +0055f00051ec0056f20050ec055efa0054f00052ef055cf9004dea0053ee0253ed0043dd +004ee70958f10352eb004ee5004bdf0051e50055e60055e60055e40055e30055e30055e3 +0055e30055e30055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e10055e30056e1 +0055e30056e10055e30056e10055e30056e10055e30056e10055e30056e30055e30056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40056e30055e40056e3 +0055e40056e30055e40056e30055e40056e30055e40056e30055e40956cc1a559bd8ffff +6690da81a6ff8faeff89a5ff728ef27894e899b7f3d8f8ffdeffffddffffe4ffffc9e7ff +8ba8ee5678d24274e73c72f0376ae0365bc33a4796e6faff114bc81742b2ffedffc58482 +f39c81ff9a7ce98273ffa293cd7359e38667f6876bf27353dc522bfb764dde6c4ae57b61 +cf654fd55941f05737eb5135cb4f438b3c4ffff2ff192e990c31be042cca0021ba0924af +000e86001bb70830c60c3dca0945ca0a51cf0756d50355dd0a5be80858e30b5adb0354c0 +0f62c21467c70b5cc80f5de50355e9005ef40466fd005bf40264fb0051ea0463fb005af4 +005af2015ef9025ff8005af60052eb0051ed0059f3035cf8055af31462f80047da054fe2 +0551e3004adc0450e20554e51160f00354e30354e30255e30255e30255e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e30055e3 +0055e30054e20054e20054e20054e20054e20054e20054e20054e20054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e30054e3 +0054e30054e30054e30054e30054e30054e30054e30054e30954c91b5191dbffff6084d0 +7b9cfb8da9ff7894ff6784e08fb0f7d2f2ffe3ffffceedffc2dffddef8ffe9ffffd4eaff +81a0e33d6ddb376eed3668e1395cc23d478fe8f9ff0f4aca1441b4fff3ffbc786fed9474 +f5916ffe988cffaea6ffead6d6866bd2664ae36646e25a32f87a52c66545b46048ffe8d8 +ffaa9be45640e4513dc950478a3b50fff1ff1d2d9e142ec90928d1031fc00a23b4000d8c +0017da052ee2083dd70645d00951d90853e00851eb1058eb0c52d45ea5ffb1f6ffc8ffff +c8ffffaff1ff6babff1f66d2004fd30662f10058e90561f00864f50964f3004ee0015ceb +004ddf015ceb0050e20059e90058ea004fdf0059eb004ad8054ed81056dc195fe50c54dc +0850d8125be50a56e00047d10653df0454e10354e30254e40254e60254e60054e80055e6 +0055e60055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e40055e4 +0054e30054e30054e30054e30054e30054e30054e30054e30054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e50054e5 +0054e50054e50054e50054e50054e50054e50054e50953cc265aa3daffff5279c66a8fe8 +789ffc648de56e9ae3c0edffdbffff9dc3ff5a7acf4f6ac16a81d1b9d1ffeaffffb4d9ff +2e6dd7266fef2a6ce42f61c4364b8ce1fdff054ece0b47b9fff1ffbe8371db9066dd885f +e28a7effe8e4ffe3d0fff2dad17963dd6f56e46f4cc15934a25b3dfff1daffe0d2ffe9da +d55740de533cc65243883b4bfff2ff212ea0192dce0c25da051dc80a21bd000b95001ae2 +0030e80541d70448d10951e40952ed0b51f11557e92568d1bdfcffc2fcff063978002971 +b5e4ffcfffff5590d61d66d51063e50659dd0457d90f62e60154d60050d41164e60b5ee2 +0c5fe10053d70659db0657dc0052d40b5ce10d5ada084ec81456d00348c10e52cd165bda +054ccc0851d40e58df0753dd0653e10453e40353e60253ea0253eb0053ed0054eb0054ea +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e8 +0054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80054e80052e6 +0052e60052e60052e60052e60052e60052e60052e60052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e80052e8 +0052e80052e80052e80052e80052e80052e80a51d12558abdaffff5478d6668df66f9aff +5a88e66296e2b0e4ffbcebff6691f04969e0536de8455ac58196e5e0f6ffc9eeff266ad9 +1e6ef7256cec2c61c9364b8ee1fcff064ed40d48befff3ffae6d57de8d5ee58c60d67a6f +d0807ffff3e3fff4e1ffeee1bf7262c1674cb96646fff1d6ffe7d0fff1e3ab5846d85134 +e55030ce50378b3b3efff5ff1d349c1432d00727da021ec80922bd000b950020d20036d8 +0145ca014bce074fef0a51fb0c50f3195ada94d5ffc9ffff76a3e4294ba42b42b68098fc +e3ffffb9e5ff1955ad094cbd2366d91053c41154c71659ca2b71e3094fbf1258ca0042b2 +175dcf125ac91359cb155dcc0040b21056c50649b42c6cd60143b10d4fbf2063d60348c1 +0d54d20d56d90952dc0752e10452e60353ea0253ed0252f10052f30052f30253ed0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea0253ea +0253ea0253ea0253ea0253ea0253ea0253ea0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb0253eb +0253eb0253eb0253eb0253eb0253eb0c52d81f4baedbfcff5a77f56586ff6b90ff5b86ff +4e7fe66ca2fc5d8eeb426cd84868ef586ff95265de93a4fee3f6ffc0e3ff2666e41f6aff +2669f82f5cd13c4592e9f8ff104ada1a45c5ffefffcf7a65ec8857f6875adf6a63df7b7d +cd897effded0fff8f4ffebe7a26a59ffefd8fff3dcffedd7b46b5ac7573fef461ffd461a +df4a1f953a28fff8ff143c91043dca0030d50023c00824b3000e8a0023c10039cf0048cb +004dd50054fc0055ff0953f21c5bccd2ffffd7ffff0830761b41ac2d51db2e4ebdeaffff +cfefff073a8d3b71dbcbf8ffd5ffffcafeffc8fcffbbe9ff2655a71c55ac215cb6aee0ff +d2ffffcfffffa9e0ff205abd1754b1205cb4bbf5ffbff6ffbdf3ffcdffffaee8ff78b2ff +0b4abc0a53d40454df0354e40054eb0054f10053f40053f30053f10054ed0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb +0055ea0054eb0055ea0054eb0055ea0054eb0055ea0054eb0055ea0155ec0056eb0155ec +0056eb0155ec0056eb0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec0155ec +0155ec0155ec0155ec0155ec0b53d91e4cacdafcff5372ff5274ff5c85ff618fff4e80f1 +4f80e74873d9557ae45573e35d74e6899dffe3f8ffe7ffff83abf02465e51f6aff2568f7 +2f5cd33c4592e9f7ff114ae21f45ceffedffc86953e37041f4774bfa786bdf6c69c87766 +b08272fff7f6fffcfbfff5e7ffe8d1fff2daa8684db45d41d25330f84213ff4312e64819 +9a3724fff9ff123f900041ce0032d80025c00526b3000f8c0025b2063bc90349dc0052ed +005fff0061ff005aee215dbfebffffefffff022d7b1758ce0a5de72067d3e0fbffeeffff +0b3c981746aeebfefff0fcff00127499bafff1fdffbecef22a5a8ab0e4ffe6fdffa9b9ff +8ba6fddaffffc5f1ff1d4e9d2b5d9accfaffe2ffff7594c387abe5ddffffbee3ff1e4da5 +0d58cd025adf0259e4005aeb005bf6005bf70059ee0258eb005aeb005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb005bed005beb +005bed005beb005bed005beb005bed005beb005bed005beb0059ec0059ea0057eb0058e9 +0057eb0057e80056ea0057e80058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea +0058ec0059ea0058ec0059ea0058ec0059ea0058ec0059ea0056ea0057e80056ea0057e8 +0056ea0057e80056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea0056ea +0056ea0056ea0056ea0755d11e539fd8ffff3c65f54b77ff548bff4d85f65385f45781ed +5572da6a82d8657cb2d3eaffe4feffd6f6ff8fb9ff3f76d3236ae01d6aec246aec295dca +2d4285e0faff1052f11744d5ffedffbd6247de6a3bf9764afa725cf07766c26b4fb17960 +a1847cfff3eefff7e4ffeacfb17050c4744fb15025df6131f44816fb4619d93c1d9c3934 +fff4ff18409f0039d90035eb002ed00020b300159e0023ad0a39c70548df0053f20063ff +0066ff005def245bbff0fefff7ffff00176d2067e30f71fa085ac6eaffffe8f6ff002a8f +2c5dc3ecf3fff6f6ff001970425ab2f7f1fff9faff164161dbffffe0e7ff221c5c383f83 +daeeffd2f0ff1c4388204d84ddffffe9ffff0e244b274375dcf9ffe5feff1942940e59ce +005ce5005be8005cef005dfc005dfc005af1015aec005aef005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1005bf1 +005bf1005bf1005bf1005bf1005bf1005bf1005bf10059f00059f00057ef0058ef0057ef +0057ee0056ee0057ee0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef0058ef0057ef +0058ef0057ef0058ef0057ef0058ef0057ef0058ef0059f1005af10059f1005af10059f1 +005af10059f10059f10059f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10059f10159f10059f10159f10059f10159f10059f10159f10059f10159f1 +0059f10159f10b59d51b569ad5ffff3563f44276ff4e8cff4786ef5085f95780f4627eec +617acebfd9fcd9f8ffbce1ff709ffb336ed62870df1d6ee41b6dea1f6deb245ec9284483 +dcfdff0d52f51745d8fff0ffc86a4ee26b41ed6741fa6f5ce36859e78d75c1836cffe9dd +fff6ecfff3e3fff1daffe3c89b4f2bcf7b4dc75523ed4b1cf74720d93b209c3836fef6ff +17429e0539db0033ee012ed20022b80015a60220b20e38ca0648da0053ea0063ff0065ff +0259f42559cfe2f3ffeaf7ff0128852462dd0d60e4195dccebfeffe4f2ff002290205abe +f1ffffebf0ff0e2b6f405aa5f4f2fffbfdff23496ecaeffffcfaffffedffefe9fff7fbff +edfdff0522642c599cd9ffffe3ffff0c255e3d5ba1e0ffffdefbff0026880c59dd005bf0 +015af4005bfb005dff005cff0059fb0458f60458f90258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb0258fb +0258fb0258fb0258fb0258fb0258fb0457fb0457fb0457fb0456fa0356fa0456fa0255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90255f90355f90255f90355f90255f90355f90255f90355f90255f90355f90255f9 +0355f90355f90355f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90355f90554f90355f90554f90355f90554f90355f90554f90355f90554f90355f9 +0554f90d55dd1d56a5d4ffff3160f43d73ff4788ff4184f54985ff4f80ff5b82fb5074d4 +c7f1ffd8ffff5c92e83a7ae81a67dd247cf81473f51270f4176df41d5fcf234487dcfcff +1153f01c45d1ffeaffcb6b52dc6441ee674ae55c56e97172c36b67ffddd3fff2e1ffead9 +b47266ffeadfffefe1fff1dca26c4aba623ce54b25f74423d93a1c9d382cfbfcff174992 +0e3ccf0a35e40531d20024ba0017a8061dc30f35d60847e00052e80063fa0063ff0759fa +2359dfcae6ffe7ffff709cf32a65cd1b62ce8ec9ffeafeffa8c1ff003cae246acce0f9ff +f5ffff092a6026478af5fcffe3efff001d4fcaf4ffeef1ff3729402b263d171b3e00124a +07286f2b59a7d4ffffdffdff001d633d5db0dcfeffd8f6ff001a86115ae4045df7075cf7 +035dfc005eff005eff055bfc085bf9055bfc045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff045cfe055bff +045cfe055bff045cfe055bff055bfe055bff045afd0659ff045afd0558fe0359fc0558fe +0359fc0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd0258fb0457fd +0258fb0457fd0258fb0457fd0258fb0356fc0157fa0356fc0157fa0356fc0157fa0356fc +0356fa0356fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc0356fa0455fc +0d56e02158abd6ffff305cf03b6dff4483ff3f80f64883ff4e80ff3f6aec6691fab3e4ff +d0ffff4080e42f76f22276fa1e7bff0f72ff0e6eff1369fa195bd521438bddfdff1555ea +2148cbfff0ffab5033d4623ded7253e66d64d36b6affe8e5ffeee3ffe1c8c47a5fc87263 +be6c61ffede4ffe5d4fff5d8b1633fe34b26f6421dd738119a3a22f8ffff154f8e0e42ca +0a38e30834d30027bd0019aa0717de1130ed0844f00051f10060fa0061fd0a58ff1e5ceb +6696ebd4ffffbaf0ff19559d165799d1ffffc6e8ff09336d004fbc1669c9e1ffffecffff +002a54a9d5ffe4feffb5d4ff014189a5e2ffebffffb0b5cbc9d4ead8eeffbbe4ff285bae +2559afd6ffffe0ffff011e6c3759b2d9fcffe2fcff072d98165be40c5df40e5cf00c5df5 +055eff055eff0d5cf50d5df20560f50063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90063f70062f90063f70062f90063f70062f90063f70062f90063f7 +0062f90063f70062f90062f70062f90062f70261f90062f70160f80061f60160f80060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5005ff70060f5 +005ff70060f5005ff70060f50261f90062f70261f90062f70261f90062f70261f90262f7 +0261f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f90262f7 +0360f90262f70360f90262f70360f90262f70360f90262f70360f90262f70360f9105fe0 +285aafdcffff3457e73d65ff467bfb4179f24b7dff4d7bff648cff4871e34b7ccb3770bf +3274e52f79ff247bff106bff146eff1066ff1361ff1852d71f3e90defdff1b56e0244cbe +fff2ffb06339c86836cb6638cb6d51ffebd6fff3dfffead2d6835bd56f47e07257c4614c +bb705dfff0d8ffedc9ffebbfe4491bf34111d43607973a1bf5ffff12548e0649ce0340e8 +0737d50129bf001aab0616e71030f50845f80051f5005ff70260fd0959ff165ffa266dd7 +6eb2ffbcffffc8ffffcbffffafebff588abf00347d116ee5196cd2e3ffffe7feffcaf8ff +d4ffffb9deff00207f0048b10857b4bfe8ffe0fbffdffbffcdf6ff64a4ff0852bd2061c9 +cdffffcbf7ff00227c3363c7d2ffffcef4ff0014831460ea0a62f71060f30d61f50563ff +0563ff0d61f50d62f30366f70068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa0068f80068fa +0068f80068fa0068f80067fa0068f80067fa0067f70066f90067f70065f80066f60066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70066f90067f70066f90067f70066f90067f70066f90067f70066f9 +0067f70066f90067f70065f80066f60065f80066f60065f80066f60065f80066f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80065f60065f8 +0065f60065f80065f60065f80065f60065f80065f60065f80065f60065f80d62e1295cb7 +dbffff2e53df355ef64073f33b73ee4478ff4776ff3c68ef3867ddc0f7ffc8ffff448aff +2777ff1e79ff2685ff0f6aff0d62ff0c5aff114eda1a3c96dbfdff1e59db294eb8fff4ff +9c5127c96736d66d3dd2724cf9a88affefd3c47b5bdc6b41d44f24e5633fe56c4dca6247 +c6694affe9c1ffb183ea4412f23e0dd0320595351df8feff13539a014cdd0044f1063adb +022ac0001bac0319de0d33f00546f60051f5015ff50461fc065bff0c63ff005de31271e5 +055ad10032a2002084002f901055bc1c6be11774ff1e69ded9f5fff0ffff032a770d3ea7 +00128e1856df1470ff0866ee1b59c81c4cb005369d0023990046d50057e81a76f30858c9 +0039a1002590125bce0d54ca0240b10027a10766f60067ff0666f90466fb0068ff0069ff +0367fb0467f90069fd0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff006aff006aff006aff0069ff0069ff0069ff0068ff0068fe006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff006aff +006aff006aff0065fd0065fb0065fd0065fb0065fd0065fb0065fd0065fb0064fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb +0063fd0064fb0063fd0064fb0063fd0064fb0063fd0064fb0063fd0762e7215fc2d1ffff +2153da275bec316eeb2e6ee93873fb3972fd4982ff427df3b0f1ffc1ffff1e6cea176ef9 +1374ff066cff076aff0261ff0159ff054ddd0f3d9fd4ffff1f5ada2e4fb6fff2ffa75233 +c9552ee46137d3532eed7250ce5b3edd5d40ff6746fc5531ec542de9572eec5832e8542e +e55226e64616f53d0bf2390dcd2c0f962e2dfff5ff1a4bb10049f40045ff053ce1022ac0 +001bac001ed10936e70149f30054f40460f10462f6045eff0567ff006eff0071f90e73ff +0a61ef236ced246fee0561e81175ff0767f9276fe7e3ffffecfdff0026852258d2366ffc +115af4005fff1279ff115ee81757db2867f21161f60060ff0075ff0064ee0c6ae8156ae1 +0c5fd71a73f50960e30f5ad71366e8006afe006bff0369fc0169fc006bff006cff006aff +0169fc0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff0069ff +0069ff016aff016aff016aff0069ff0069ff0069ff0068ff0068ff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff016aff +016aff0068ff0068ff0068ff0068ff0068ff0068ff0068ff0068ff0067ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff +0067ff0266ff0067ff0266ff0067ff0266ff0067ff0266ff0b65f11c5fcacbffff1a51d2 +1f59e12c6ae52a68e3346ef4366ef52f66e5437cef2a6bc92e72d52872ed1768ed2782ff +0664ea0c68fb055ef60058f0024cd3083d9dd0ffff1f5dd62e52b3ffeeffa95845bf492f +d24929df5531e15532e7583aea5036ea412af44c2ffa653bdc4818e64415fe5325e93d0d +ef4011ee3c0ee33b17bf2e1d8b2d3dfff1ff1f47b90148f80044ff053ce1022ac0001aab +0020ba0940db0042e4015bf7005ae50666f00057f00372ff0075fd0076ff006eff046aff +1268fd0e6afb0072ff0073ff0670f71864d2ddffffe4ffff001d832764e12a6ef70c61f2 +006cff006dff0e67f71763f41a61fb1064ff006eff0071ff006dfb086af30f68ea0f68ea +0969f40b68f41465ea1066ef016aff006bff0569fd0569fb006cff006dff006bff046afd +0568ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff0667ff +0669ff0669ff0669ff0568ff0568ff0568ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff0467ff +0467ff0467ff0467ff0467ff0467ff0467ff0467ff0566ff0566ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff0765ff0566ff +0765ff0566ff0765ff0566ff0765ff0566ff0765ff0f64f31859cdcdffff295fdd0e43c5 +2359d3295dd72051d23562e32f5bd42f5eca2e5fbe295dc0235acf1d5bd6175cd1155cce +084fc1175ed20d55ce0446b62357abcfffff1b5fcc2653aef7e8ffa566619b342bc64b39 +bf4224c43f1ede4a30d53e29d44233cd452fc44b20c64913d74009dc3b05da3a08d53a0c +d7431fb32c16a735348c4360fef5ff1d41af104aea0544f40b3dde022ac00016a70029c0 +013dd9004bef0059f8055eec0460e7005ceb006cf80077f50078fd0070ff006bff0c68ff +096cff0075ff0078ff0a80ff126de0235ab704329000289e1766e90659e30e6dfb006efb +006ffd046afd0c65ff1360ff0c64ff006eff0070ff006dff066afe0d68f50c68f7056aff +0769ff1166f41066f7026aff006bff0968ff0969fe006bff006dff006cff056aff0669ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff +0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0768ff0667ff +0467ff0467ff0467ff0366ff0366ff0366ff0366ff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff +086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff086bff0265ff +0265ff0265ff0265ff0265ff0265ff0265ff0265ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff0364ff +0364ff0364ff0364ff0364ff0364ff0364ff0c62f31c61d896d0ffa9e0ff2960d40032a2 +0e40b1204cc51038b11b44b01d45a71a469f1845a21342ae0f42af0d44a80c44a1164ba9 +083ea2002f9d1650bcaee5ff8ac9ff2576e92061c7cfdfffd2b8d39d5d787928398b3d3b +98413a952929992c329539468d3e438942308f40219f3817a334169d351c963525822827 +7828358f4e6cecceffb2c5ff2858c7043ad20f44ec0c3ad80028be0016a70021ca0030dc +0048fe004fff0758f00354e3045be90061e70071e50071ee006aff0066ff0864ff0569fd +0073fe0077ff006ef7077dff1068e30051ce0f70fb0069f90c75ff0674ff006ef3006ef7 +006afe0066ff0a5fff0a60ff006af0006dee0069ff0266ff0764ff0664ff0066ff0066ff +0d62fd0b62fd0066ff0066ff0764ff0764ff0067ff0068ff0067ff0067ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0067ff0066ff0066ff +0066ff0065ff0065ff0065ff0064ff0064ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff +0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0061ff0067ff0067ff +0067ff0067ff0067ff0067ff0067ff0067ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff0066ff +0066ff0066ff0066ff0066ff0066ff0766f81562d80b4fb4a1e1ffb8f7ffcdffffcfffff +d2ffffd1fcffd6ffffd6ffffd6ffffd5ffffd5ffffd2ffffd2ffffd4ffffd3f8ffd9ffff +cefdffbbf2ff99d7ff115ed40061eb005adf104aabaec9fff5f6fffaf2fff7fafffbfaff +ffe7fffff0fffcf6fff6f9fffafafffff9fffff5fffff4fffdf6fff8f7fffaf5fffbf5ff +eaedffabc6ff1254b40045bb1c55ec1443e70c38d50028be0015a60023d80033ea0149ff +044fff094ee90b4edd1055e1095add0065d50066de0060fe025cff0d5cff0b60f90167f7 +006df9006afc0062f60d70ff1372ff0672ff0059f11179ff0054e1006aeb006bef006afb +0065ff0c5cff105cfd0965e40567e20064f80063ff0461fa0361fe0063ff0062ff085ffa +0a5ff80062ff0063ff0860f80860f60064ff0064ff0064ff0064fe0063fe0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff +0162ff0162ff0162ff0162ff0162ff0162ff0162ff0162ff0063ff0164ff0064ff0063ff +0063ff0063ff0062fe0062fe0062fe0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff +0165ff0265ff0165ff0265ff0165ff0265ff0165ff0265ff0165ff0062fe0062fe0062fe +0062fe0062fe0062fe0062fe0062fe0062fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe0061fe +0061fe0061fe0061fe0061fe0560f51b6cef0651c6165fc61c60c3215ec91850c12154ca +2d5fd0285abd285bb7285ab9285abd2659c4265ac0265cb2295cad365dba2b50ba2353cf +2863e50447c90d60ea0062fc0058f0125fdf1e55cc2b49cb2543bb1749a82554ac374ab0 +2638a42550b91f54b42554a62b53993051962c52991e57a61b56b21a49b31a43b51a45b8 +0942b50660d2004dcd0840dd0a35da0d38d50028be0016a7001ad90030ed003bf20141eb +043ccf1041ca123dca1446cb0447b80049c20244e30441f10c42ed0d44e90848e6004ce8 +005bfb0058f70051ee0047e2005bf40055ee0054eb0c5dec0050d00052d20054e20051eb +0447f00d44e50d49cb064ec70050da0052e10050dc0051e10053ed0052ec004edc004eda +0051e60051e6004fd6004fd50052e10054e40053e10052dd004edd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd +004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ddd004ede004fde004ede004fde +004ddd004edd004cdc004ddc004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df004fdf0050df +004fdf0050df004fdf0050df004fdf0050df004fdf0050df0048d80049d80048d80049d8 +0048d80049d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d80048d8 +0048d80048d80048d80047de003cde0d5ef8014fd7044dce003fcd0945db0c44df063dd5 +0a44cc0945ca0944d00743d50844da0845d40848c40b49b80b41ab0a3faf1753d50039c5 +0853e2004ce20041e40462ff0b53e6002dbf1838d9274be70036b90036b52746d52540d7 +093dce0242c80244be0645b60844b60346b9004bc7004ad00039c50e4bd9002ab4002cb3 +003cbf0051df0035df1139e80d37d70028be0017a80024df0839ed033ddf0034c3194ac0 +1c42ad1932a61c34a01e43941b45991841b51840c31d40c01e40bc2141b81c43ba0538b7 +0c43c2154bc50542b5024cb9064db90033a6254fbb1946a1114aa30050b3004dbf1342c6 +1f3ebd2341a31d459c0f4bad094db20d4bae094db2014fbe024ebc104aae124aab084cb7 +094cb51449a5144aa4094db0054eb5064eb20b4cb01249ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae1448ae +1448ae1448ae1448ae1448ae1448ae1448ae1348ae1247ad1148ad1148ad1047ac1047ac +1047ac0f46ab0f46ab0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a80c43a8 +0c43a80c43a80c43a80c43a80c43a80c43a80c43a80e45aa0e45aa0e45aa0e45aa0e45aa +0e45aa0e45aa0e45aa0f44aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa1044aa +1044aa1044aa0c44b31753d70026a4003ca10e46a71141af1640b9123bbb123bb71543b2 +1444b01243ba1143c01142c31143bc1246ab14489c1948961847991547aa0339a61951c0 +0340b30248c2003ab21040af1334a71d30b31e3ab80747ab0042a30d30a61029a81837b4 +113bb10841a80743a30d41a60b42a90244b40045b70d4abd0a3eae153ba63863cb0644ab +0035a90d3ac90d34cf0d36d00027bd0016a70017c20533cf255cdb2d63c5b4e1ffc5e4ff +e5f0ffebf1ffddeafad9edf4d3ecffd0ecffd2ecffd6ebffdeeaffe2e7fffaf7ffe1deff +e2e6ffd7e7ffd2efffdffaffeaeeffe3ddffe8e5f6dbebf8c4f4ffc1f3ffd3e8ffe0e3ff +e8e2ffe7e5fbe1e8ffdee9ffe1e8ffdee9ffd4ebffd5ebffe3e6ffe5e6ffdce9ffdee8ff +eae5fbeae5f9dee9ffdaeaffdbeaffdceaffdee9ffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaffdeeaff +deeaffdeeaffdeeaffdeeaffdeeaffdceaffdbe9ffdaeaffd9e9ffd9e9ffd8e8ffd8e8ff +d8e8ffd8e8ffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedffddedff +ddedffddedffddedffddedffddedffddedffdbebffdbebffdbebffdbebffdbebffdbebff +dbebffdbebffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaffdceaff +dceaffdaebffdbf2ffc9e1ffeeffffe7faf8d5e1efe7ecffe7ebffe0e6ffdeebfcdbecfe +d8ebffd7eaffd4e9ffd4ebffd6eefad9eef1dbe9f2e5f2ffdfecffdfedffc9d7fcdaeaff +ecffffd2e3ffe1e8fbf7f3ffefe4ffdae0ffcdffffcbffffd6f6ffebf3fff3e1fff0e3ff +daefffd5f1ffe1eaffe5e8ffe3e8ffdeeaffd3e4ffd8e4fcece9fcddd9f0dae7ffddf4ff +d4f4ff2146b00b35bf0024ba0014a50021c70433c92b63da1d51a4d8faffd0e2f6ecf0ff +e1dfeceeefdfecf2d8e6f2e6e4f1e8e5f1e3e7f0dfeceddbf3e9ddf5ddddfde3e4ffeee7 +ece6d6f1f6dfe4e6d1fdeee7f8e1dbfee9d8f3eed8dff6e4dbf6efe9edf8f3e9f4fae8e6 +fbe9dff7e8e1f6e9e1f9e8e0f6e9e3efeaeef0eaecfae7e0fbe7def6e8e7f7e8e5ffe6d9 +ffe6d7f7e8e1f3eae5f4e9e3f4eae1f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0 +f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f2ece0f2ece0f2ece0 +f2ece0f2ece0f2ece0f2ece0f2ece0f2ece0f2ece0f2ece0f2ece0f2ece0f2ece0f2ece0 +f2ece0f2ece0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0 +f2ece0f3ebe0f2ece0f3ebe0f2ece0f2ecdef2ecdef2ece0f3ebe0f3eae1f3eae1f3eae1 +f3eae1f3ebe0f3ebdef3ebdef3ebdef3ebdef3ebdef3ebdef3ebe0f3eae1f3eae1f3eae1 +f3ebe0f3ebe0f2ece0f2ece0f2ece0f2ebe1f2ebe3f2ebe3f2ebe3f2ebe5f2ebe3f3eae3 +f2ebe1f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0 +f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0 +f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0 +f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0 +f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0f2ece0f3ebe0 +f2ece0f3ebe0f2ece0f3ebe0f2ece0f1ede1f1ede1f1ede1f0ece0f0ece0efebdfefebdf +efebdfeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeebdceeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadef0eadeeeeadef0eadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdf +f1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdf +f1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebddf1ebddf2eadf +f1ebdff2e9e0f1eae0f1eae0f1eae2f1eae2f1eae2f1eae2f1eae0f1eae0f1ebdff1ebdf +f1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdf +f1ebdff1ebdff1ebddf1ebdff1ebddf1ebdff1ebddf1ebdff1ebddf1ebddf1ebddf1ebdd +f1ebddf1ebddf1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdfefebe0efebdfefebe0 +efebdfefebe0efebdfefebe0efebdfefebe0efebdfefebe0efebdfefebe0efebdfefebe0 +efebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdf +f1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdf +f1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdf +f1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdf +eeebe2e7e8e3f4f6e9e5e7c2f1efc6eae3c7f8eddbf0e4d8f5ebdff2edd7efefd7eceee3 +ebede8eaece9eaede4e9efd3eaefcfedebd4f2efe0f6f1edddd7d7fffcf9f2ede7dfdbd0 +fdf7e7efe3cbfae9d5feeae1ede9ddd1f0cecef8d2def4dfedeae3ffe1e6ffe2e4ecece0 +e8efdff4e6e3f8e4e3f6e4e2f3e6e0f0eedff8f3dff6e1ccfee7d7f6ede6e0e6f6cae2ff +2a4ca30b32b50021b70012a1001cc50838d61e60ea1f55b5d9ecffededede7e9e6ebeee5 +eeeddbeeeddbebece4ecebe6efebe0f1ebddeeecddefebdff3e9e0f3e9e0f2eadfefecdd +eeecddeeecddf2eadff3e9dff3eadbefecdbeaeee0e8eee4ecebe6efeae6f2e9e0f2eadf +f2eadff1ebdff2eadff1eae0efeae4efebe2f2eadff3e9dff1eae0f2e9e0f5e9ddf5e9db +f2eadff1eae0f1eae0f1ebdff1ebdfefebdff1ebdfefebdff1ebdfefebdff1ebdfefebdf +f1ebdfefebdff1ebdfefebdff1ebdfefebdff1ebdfefebdfefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efebdfefebdff1ebdfefebdff1ebdfefebdff1ebdfefebdff1ebdfefebdff1ebdfefebdf +f1ebdfefebdff1ebdfefecddf1eedbf3f0ddf1eedfe8e1d7efe8e2f6eceaeee5e0f5eae4 +f6ece2f9f0e1f0e7d6e8e0cdf1e9d6f6eedbf3ead9f1e9dcf3eae5f2eae7f2ebe3f2ebe1 +f2ecdef0eddef0ece0f0ece1f0ebe5f0ebe8f0eaecf0eaecf0eaeef0eaecf2e9eaf0ebe7 +f2ebe1f0eddef2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0edde +f2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0edde +f2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0edde +f2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0edde +f2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0eddef2ecdef0edde +f2ecdef0eddef2ecdef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0eddef0edde +f0eddef0eddef0eddef0eddeefeddeefeedcefeddeefeddef0eddef0eddef2ecdef2ecde +f1ebdff1ebdff0eadef0eadef2eadff2ece0f4ece1f4eee2eeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadef0ece0eeeadee5e1d5ede9ddf2eee2ede9ddefebdfeae6da +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf2ebd9f2ebd9f3e9ddf2eadf +f3e8e2f2e9e4f2e8e6f2e8e7f2e8e7f2e8e7f1e9e7f1e9e6f1eae4f1eae0f1ebdff1ebdd +efebdfefebdfefebdfefebdfefebdfefebdfefecddefecddefecddefecddefecddefecdd +efecddefecdbefecddefecdbefecddefecdbefecddefecdbefecdbefecdbefecdbefecdb +efecdbefecddefecddefebdfefebdfefebe0efebe0efebe0eeebe2eeece0eeebe2eeece0 +eeebe2eeece0eeebe2eeece0eeebe2eeece0eeebe2eeece0eeebe2eeece0eeebe2eeece0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0 +eeebe2eeecdfefedd8efedd6f1ecd9f1ebddf1ebdff1ebdfefecdbefecdbeeece0eeebe2 +eeebe2eeece0eeeddbeeedd9efecdbefebdfefebe0efebe2efebe2efebe0efebdfefecdd +f2ebdbf2ebdbf3e9dfefebdfe8f0dbe5f1dbeaeedfeeece0f2e9e0f2e9e0f1ebddf2eadf +f6e6e7f5e7e6f1ebdfeeeddbebecdcf1eedff9e9dcf9e9dcedeadbe8f2fbd1e7ff2748a9 +1035b90021b300129e001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddecebd7efeedaf2efe0eeeadff4ede7f4ece9ece2e0efe4e0ede3d9 +f0e7d8f8efdefff7e4fbf3e0f0e9d6f1e8d7f8f0e3f1eae4f1e9e6f1eae2f1ebdfefecdb +efecd9eeeddbeeecdfeeebe2eeebe6eeeae9eeeae9efe9e9efeae7efeae6efebe2efebdf +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddeeecddeeeddbeeeddbeeeddbefecddefecddf1ebddf1ebddf3ede1 +f2ece0f3ebe0f3ebe0f3ebe0f4ece1f5ede2f5efe3f3ede1f1ede1f1ede1f1ede1f1ede1 +f1ede1f1ede1f1ede1eeeadeefebdffefaeeece8dcf0ece0e8e4d8eae6daf7f3e7efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff1ebddf2ebd9f3ead9f3e9ddf3e9dff3e9e0 +f2e9e2f2e9e2f2e9e2f2e9e2f2e9e2f1eae4f1eae4f1eae2f1eae0f1ebdbf1ebdbefecdd +efebdfefebdfefebdfefebdfefebdfefecddefecddefecddefecddefecddefecddefecdd +efecdbefecddefecdbefecddefecdbefecdbefecdbefecdbefecd9efecdbefecdbefecdb +efecdbefecddefebdfefebdfefebe0efebe2efebe0eeece0eeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9 +f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1035b9 +0021b100129c001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddeeebdaefecdbefebdff2eee3f6efe9f2ebe5f0e9e3f2e9e2f5ece3ede5d8 +efe8d8f2ebd9ede6d6ede7d7f0e8dbeae4d8f2ebe1f2ece0f0eddcf0eddaf0eed9f0eed7 +efefd7efeed9efeedcefeddeefeddeefeddeefeedaefeed9efefd5efefd7efeedcefede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efeddeefeddeefeddeefeddeefeddef0eddef0eddef0ece0f0ece0eee8dceee8dc +ede7dbede7dbefe7dcefe7dcf0e7def0e9dfefe9ddede9ddede9ddede9ddede9ddede9dd +ede9ddede9ddeae6dae3dfd3f4f0e4e4e0d4fbf7ebfbf7ebebe7dbede9ddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff1ebddf2ebd9f2ebdbf2eadff2e9e0f2eadff1ebdb +f1edd4f1edd0f1edd0f1edd4f1ecd9f1ebddefecddefecdbefedd6efedd6efecdbefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdd +efebdfefecddefebdfefecddefecddefecddefecddefecdbefecddefecddefecddefecdd +efebdfefebdfefebdfefebdfefebe0efebdff1ebdbf1ecd9f1ecd9f1ecd9f1ecd9f1ecd9 +f1ecd9f1ecd9f1ecd9f1ecd9f1ecd9f1ecd9f1ecd9f1ecd9f1ecd9f1ebdbefecddefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7 +eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1035b90021b1 +00129c001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff5f2e3f0eddeeae6daf1ede2f2ebe3f0e9e1faf3ebf6efe7f4ede3f6f0e4f9f3e7 +efe9dde7e1d5f4f0e5fcf5edebe4daf2ece0f2ecdcf0eddaf0eed9f0eed9f0eed7efeed9 +efeed9efeed9efeed9efeed9efefd5eff0d1eff0ceeff1cceff0d0efeedaefede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0efede0 +efede0efede0efeddeefede0efeddef0ece0f0ece0f0ece0f0ece0f5efe3f4eee2f4eee2 +f3ede1f4ece1f5ede2f6ede4f5eee4f5efe3f3efe3f3efe3f3efe3f3efe3f3efe3f3efe3 +f3efe3ede9ddf6f2e6f5f1e5f3efe3ece8dcede9ddeae6daf5f1e5efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddf1ebdbf1ebdff2e8e6f1e9e7f1e9e6f1ebdff1edd2 +f1eecdf1eecdf1edd0f1ecd9f1ebdfefebdfefecdbefedd4efedd4efecdbefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0 +efebdfefebe0efebdfefebdfefebdfefebdfefebdfefebdfefecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdff1ebddf2ebd9f2ebd8f3ebd8f2ebd8f3ebd8f2ebd8f3ebd8 +f2ebd8f3ebd8f2ebd8f3ebd8f2ebd8f3ebd8f2ebd8f3ebd8f2ebd9f1ebddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddb +eaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1035b90021b100129c +001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f7f1e5f4eee2eae3d9f4ede3ede9deeae6dbf6f2e7e0dcd1dfdbd0ebe7dcf6f2e9f2eee5 +e7e2dce7e4dfeee9e5ede8e2ece8dcece9d8ece9d8ece9d8ece9d8ece9d8ece9daece9d8 +ebead8ebead6e9ebd3e9eccfe9edcce9edc8e9eec5e9edcaebead6ebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9ddebe9dd +ebe9ddebe9dcebe9ddebe9dcebe9ddebe9ddece8ddece8ddede9deede9deeee7ddede6dc +ede6dceee7ddefe6ddefe8deefe8deede9deede9deede9deede9deede9deede9deede9de +f5f1e6f5f1e6d5d1c6faf6ebe6e2d7f1ede2f1ede2eae6dbefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddefeae4f1e7efefe7f4efe7f2efe9ebefecddefedd4 +efedd4efecd9efeae4efe9e9efe9e9efebe2efedd6efeed2efecdbefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebe0efebe0efebe0efebe0efebe0efebe0efebe2efebe0 +efebe2efebe0efebe0efebe0efebe0efebe0efebe0efebdfefebe0efebdfefebdfefebdf +efebdfefebdfefebdff1ebddf3eadbf3eadbf5e9dbf3eadbf5e9dbf3eadbf5e9dbf3eadb +f5e9dbf3eadbf5e9dbf3eadbf5e9dbf3eadbf5e9dbf3eadbf1ebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8 +ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1035b90021b100129c001cc7 +0738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0e9df +f4ede5ebe4daf8f1e7eeeadee7e3d7ede9ddbbb9acbbb9adb2afa6a4a19aa9a6a1b5b1ae +aba7a4a4a09fb1aea9b1ada1b1ae9fb1ada1b1ada2b1ada4b1aca6b3aca6b1aca6b1ada4 +b0aea1b0af9daeb09aaeb196adb292adb391adb294aeaf9fb0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4b0aea2b0ada4 +b0aea2b0ada4b0aea2b0aea2b0aea2b1ada2b1ada2afaba0afaba0b0a99fafa89eafa89e +afa89eb0a79eb0a99faeaa9faeaa9faeaa9faeaa9faeaa9faeaa9faeaa9faeaa9fa8a499 +a5a196bab6abfffff4eeeadff6f2e7f4f0e5e7e3d8efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddefedd8eeecdfefe8efefe7f6efe6f7efe8f0efebe2efecd9efecd9 +efebdfefe9ebefe8f0efe9edefeae4efeed2efeecfefecd9efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebe0efebe0efebe0efebe0efebe2efebe2efebe2efebe2efebe2 +efebe2efebe2efebe2efebe2efebe2efebe2efebe0efebe0efebe0efebe0efebdfefebdf +efecddefecddf1ebddf2e9e0f3e9e0f3e8e2f3e9e0f3e8e2f3e9e0f3e8e2f3e9e0f3e8e2 +f3e9e0f3e8e2f3e9e0f3e8e2f3e9e0f3e8e2f2e9e0f1ebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecde +f1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1035b90021b100129c001cc70738db +1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1eae0ede4ddf7eee9 +ebe4dcf7f1e5edeadbebe8d9edebdca4a5975e5e5477776f6b6a6662615d7a7977797876 +6b676475726b706c60726c5e726b63726a6772696c72687073687072687072696e706a6c +6f6b686d6d656d6d636c6e616c6e606c6e616d6d636d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d636d6d656d6d63 +6d6d656d6d636f6c636f6c636f6c636f6c63747067747067736f64726e63736c62736c62 +736c62746d63726e63726e63726e63726e63726e63726e63726e63726e6379756a6d695e +e6e2d7fffff4e7e3d8ddd9ceebe7dcfffef3efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefedd8eef0cbecf0cfeeebe2eee9efeee8f4eee9efeeebe2eeeddbeeeddbeeece0 +efe9edefe8f0efe9ebefebdfefefcbefefc9efedd8efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe2efebe2 +efebe2efebe2efeae4efeae4efeae4efebe2efebe2efebe0efebe0efebdfefebdfefecdd +efecddefebdff1e9e6f1e8e9f1e8ebf1e8e9f1e8ebf1e8e9f1e8ebf1e8e9f1e8ebf1e8e9 +f1e8ebf1e8e9f1e8ebf1e8e9f1e8ebf1e9e7efebe2efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2 +f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1035b90021b100129c001cc70738db1c60f3 +1c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1eae0efe6e1faefebeae1d8 +f3ede1ebe8d7f0efddf5f6e6a6a79974756dedeee8fffffdf7f6f4fdfcf8fffffaf9f6ef +fffff3ffffecffffeafffef1fffdf6fffbfffffafffffafffffafffffafffffbfffffdff +fffefffffefffffffffefffffefffffffffbfffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffafffff8fffffa +fffff8fffff8fffff6fffff8fffff6f7f3eaf7f3eaf6f2e9f5f1e6f6efe5f6efe5f6efe5 +f7f0e6f4f0e5f4f0e5f4f0e5f4f0e5f4f0e5f4f0e5f4f0e5f4f0e5e9e5da7d796ef6f2e7 +fcf8edf4f0e5f6f2e7eae6dbede9deefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeedd8eef0cbecf0cdecece0eceaedeee9f0eee9edeeece0eeedd9eeeddbeeece0efe8ef +efe7f2efe8f0efeae4f1edd2efeecfefecd9efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebe0efebdfefebdfefebdfefebdfefebdfefebe0efebe0efebe0 +efebe2efebe2efeae4efeae4efeae4efebe2efebe2efebe0efebdfefebdfefecddefecdb +efebdfeeeae7eceaebeeeaebeceaebeeeaebeceaebeeeaebeceaebeeeaebeceaebeeeaeb +eceaebeeeaebeceaebeeeaebeeeae7efebe2efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0 +f4eadeecebd9e8f3f9cfe7ff2747ae1035b90021b100129c001dc80738db1c60f31b54bb +e0e9fff4ebe2e9ecdbecf1ddeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeae6daf8f4e8ede9ddf3efe3f6f2e6e8e4d8f9f5e9e6e2d6 +eceadef7f5e9e7e5d9e9e7dbf7f5e9f4f2e6f7f5e9e9e7dbe5e3d7f4f2e6f3f1e5e0ded2 +f9f7ebe9e7dbf1efe3efede1ece8dceeeadef1ede1eae6daf0ece0efebdfebe7dbf0ece0 +e5e1d5f8f4e8e3dfd3f6f2e6efebdfe5e1d5efebdfede6dcf4eae8f0e5e1f6ede4eee8da +efecd9efeedaeeefdfa8aa9d666761fffffdfffffde2e1dffffff8fffcf1fffeeeffffe7 +fdf9d4ffffdbffffe3f9f1defffcf4fffbfafffafdfdeef3fffbfff5ebecfff9fafffdff +fcfafffcfbfffefdfff3f3fdfbfbfbfcfbf6fffffbfffffaf4f3effffffafdfcf8fffffa +fffffbfbfaf5faf9f5fefdf8fffffbfbfaf5fffffbfffffafffffbf4f3eefffffbf5f4ef +fffffbfdfcf7fbfaf6fffffafdfcf8fefdf8f5f4f0fffffaf3f2eefefdf8fffffbfaf9f4 +fffffbf8f7f2f9f8f4f8f7f2fffffbfffffafcfbf7fefdf8fffffbf9f8f3fffffbfdfcf7 +fffffbf1f0ebfffefafffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffafffff8fffffafffff8fffcf5efece3fffff6fffff6f9f5eafffff4fffff4fffcf1 +fffff6fcf8effefaf1fffdf4fffff6f6f2e9fffff6fffff6ada9a0726e65f5f1e8fffdf4 +f0ece3f0ece3ede9e0efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeeadef2eee2f4f0e4f0ece0ebe7dbebe7dbefebdff3efe3efebdff7f3e7e9e5d9ece8dc +f0ece0ede9ddf0ece0f2eee2eeeadeebe7dbf4f0e4e4e0d4ebe7dbf7f3e7e7e3d7f2f0e1 +fefde8d8d9c9f1f0eeeae7eee4dfe6f9f5f4f1efe0eeedd8e8e5d2f0ece1ede3ebf1e6f7 +f6eafef1e6f4e0d6d5f5eee6eeeadff2eee3e8e4d8ede9ddfaf6eaeae6daeae6daf3efe3 +e4e0d4fffdeee6e2d6efecddf3f0e1e9e6d7e9e6d7f1eedfe7e3d7faf6eaece8dcf7f3e8 +040000fbf7eee2ddd7f5f0eaefeae4ede9e0f2eee3f6f2e6f9f5e9edeadbe2dfcef2f0e1 +e9ebe0dce2d8f9fcf3e0e6dce1e4dbf5fbf1ebeee5e6ece2dee1d8f3f9efe8ebe2dbe1d7 +f7faf1edf3e9eaede4e6e8ddeceadef2eee2ede9ddf8f4e8eeeadefaf6eaf0ece0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdf +eaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eade +ecebd9e8f3f9cfe7ff2747ae1338bc001dad00119b001dc80738db1c60f31b54bbe0e9ff +f4ebe2e9ecdbecf1ddeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdffcf8ece7e3d7ebe7dbefebdfe0dcd0d6d2c6f3efe3f8f4e8edebdf +f3f1e5e7e5d9fffff4e0ded2e1dfd3dbd9cdf4f2e6f8f6eaefede1dcdacefbf9edebe9dd +eceadedfddd1faf8ecf0ece0f1ede1e7e3d7fdf9edece8dcede9ddf7f3e7e8e4d8eeeade +faf6eaf4f0e4f1ede1e3dfd3f7f3e7ebe7dbf2ebe1f4ebe6f0e5e1f6eee3eee8d8efecd9 +efeedaeeefdfa8aa9f747570fffeffe6e4e5fffffafffff3fcf5e2ffffe3b4af85b2b077 +afab6eb9b381ffffdcfceed4fffcecfff1e4fffceffffceffffdf1fffef3fffbf5f7f3f4 +fffefff6f5fffefdfff8f8fafffffbf2f1edf1f0ecfffffbecebe7fffffbfffffbf6f5f1 +fffffbfffffbfffffbf1f0ecfffffbf1f0ecf9f8f4faf9f5f2f1edfdfcf8fffffbfffffb +fffffbfdfcf8efeeeafffffbfffefafffffbf7f6f2fffffbfbfaf6f8f7f3fffffbfefdf9 +fffffbfffffbfffffbfbfaf6f8f7f3fffffbfffffbfffffbfffffbfffffbfffffbfaf9f5 +fcfbf7fffffbf2f1edfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffdfffffbfffffb +fffffafffffafffffafffffaf4f1eafffef8d6d2c9ece8dff1ede2ebe7dceeeadfe0dcd3 +fbf7eef2eee5efebe2ede9e0f1ede4e7e3dae8e4dbada9a0726e65f5f1e8fffdf4f0ece3 +f0ece3ede9e0efebe0efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdff3efe3 +ebe7dbeae6daf1ede1f5f1e5f1ede1ede9ddece8dce5e1d5e9e5d9f9f5e9f4f0e4f2eee2 +eae6daede9ddeeeadef6f2e6f0ece0faf6eaefebdfece8dcf3efe3e7e3d7eeece0dfdcd3 +edece7f8f7f5f6f5f3030000030200090a000404000c0c00f1edd2f5eee4eee3e7fbeffb +ecdeedfff7fff5eaeefaf3edf2eee3f8f4e9e5e1d5e5e1d5fcf8ecf4f0e4e8e5d6fcf9ea +dbd8c7fbf8e7e7e4d1edead7fffce9efecd9fcf9e6f8f5e2e4e1d0e3e0d1f6f2e6f6f2e7 +e8e4dbf7f3eaece7e1f5f0eae2ddd7f3efe6f1ede2d9d5c9f1eeddffffefe4e5d70a0f0b +000204000204060e1000020400020400050700020401090b0005070002040a1214000204 +0006080002040d1110f2f2e8f0ece0e9e5d9e2ded2f1ede1e5e1d5ebe7dbfffbefefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedf +ebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9 +e8f3f9cfe7ff2747ae1338bc001dad00119b001dc80738db1c60f31b54bbe0e9fff4ebe2 +e9ecdbecf1ddeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfe5e1d5f1ede1f9f5e9ece8dcfffff3fffff3e0dcd0f1ede1eeece0e8e6da +f4f2e6e8e6daeeece0faf8ecfdfbeff3f1e5e8e6daebe9ddf9f7ebedebdfe6e4d8f6f4e8 +f8f6eadfddd1f5f1e5f0ece0f8f4e8d5d1c5e7e3d7fdf9ede3dfd3f6f2e6f5f1e5f1ede1 +d4d0c4f7f3e7f3efe3ece8dcf2eee2ece5dbf4ebe6f0e5dff6eee1eee9d6efedd8efeeda +eeefe1a9a9a16c6a6bfffdfffffdfdf2ebe3fffbe8ffffdfa79f70fdf7b9ffffb6ffffaa +f1eba1aea467fffbcafff9d0ffffd8fff1caffffd8fff9d2fff9d5ffffe6fdfaebfffffb +f1f1f9fefefff7f7f9fffffdfffffdfffffdf1f1effffffdfffffdefefedfffffdfbfbf9 +efefedf7f7f5fffffdfbfbf9fffffdfffffdfcfcfafffffdf5f5f3fffffdf9f9f7fbfbf9 +fdfdfbfffffdfffffdfffffdededebfffffdf9f9f7fefefcfffffdfffffdfffffdfffffd +fefefcededebfffffdfffffdededebfffffdfffffdf5f5f3f7f7f5f2f2f0fffffdfffffd +e7e7e5fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffffffffdfffffdfffffb +fffffbfffffafffcf7ebe8e1f4f1eafffff6f6f2e9e4e0d7fffef3e4e0d5fffcf3e6e2d9 +f3efe6eeeae1f4f0e7e4e0d7f9f5ecfcf8efada9a0726e65f5f1e8fffdf4f0ece3f0ece3 +ede9e0efebe0efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdff5f1e5eae6da +e7e3d7efebdff4f0e4f0ece0eeeadef0ece0fdf9eddcd8ccf8f4e8e5e1d5f1ede1f3efe3 +f2eee2e7e3d7efebdfe5e1d5f3efe3f1ede1ebe7dbf0ece0ede9ddf0ede4f3eff0f3f1f2 +dedbd2030200eaeac6fafccbebefb4f1f3b2eaecab070600fbf8cbf3edcde4dbcafdefec +f7e8efecdfe6ebe3e0dbd7ccf7f3e8f7f3e8e8e4d8f4f0e4e6e3d4eeebdae6e3d0f4f2dd +ecead5eeecd5f7f5dedad8bff5f3dae5e3caf5f3dceeecd7ece9d6f1eedd040000f5f1e6 +f0ece3e9e5dceae5dfe9e4deebe7def9f5eafcf8ecedead9e7e4d3eeede8000015676d91 +4f557960668a5c628643496d676d915a6084585e82494f736a70945a60844d537753597d +676d91000015e9e8e6eeeadefefaeef9f5e9e8e4d8eeeadef3efe3dbd7cbefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeedd +f3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9 +cfe7ff2747ae1338bc001dad00119b001dc80738db1c60f31b54bbe0e9fff4ebe2e9ecdb +ecf1ddeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff1ede1ebe7dbe8e4d8070300f0ece0dad6cae9e5d9f9f5e9fcfaeee3e1d5f9f7eb +eeece0efede1e0ded2e5e3d7ebe9ddf5f3e7e2e0d4eceadee4e2d6f5f3e70d0b00f1efe3 +eceadef0ece0d2cec2fffff3efebdff3efe3eae6da130f03ece8dce3dfd3f0ece0f2eee2 +faf6eaf5f1e5e1ddd1ece8dcfff8eef4ebe4f0e6ddf6efdfeee9d5efedd8efeedceeeee2 +a9a8a3737174fcf7fbfff9fafffdf3f0e5c9ac9f72ffffc3ffffaef4f192ffffa1ffffaf +ffffbaaea061aa9a5fa3925ab4a56aa6985baea467ffffcdffffd6ffffe6f0eee2ffffff +eeedf5fffffffffffdebebebfffffdfdfdfdf9f9f7fbfbfbfffffdf7f7f7fffffdffffff +fffffdf4f4f4fefefcfffffffffffd000000f7f7f5fffffff5f5f3fffffffffffdfafafa +f6f6f4fafafaececeafffffffffffdfffffffffffdfafafafffffdfdfdfdf0f0eef6f6f6 +fffffdf6f6f6eeeeecfffffff1f1effffffffefefcfffffff5f5f3fffffff5f5f3ffffff +f3f3f1fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffdfffffd +fffffbfffffaf6f3eefffff8e7e4ddf5f1e8e8e4dbe4e0d5faf6ebe4e0d7f0ece3eae6dd +f5f1e8e5e1d8fffdf4e8e4dbe7e3daada9a0726e65f5f1e8fffdf4f0ece3f0ece3ede9e0 +efebe2efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdff0ece0f1ede1f0ece0 +ebe7dbeae6daede9ddf3efe3f6f2e6eae6dabfbbaff6f2e6e0dcd0f1ede1f7f3e7f7f3e7 +e8e4d8efebdfe3dfd3ece8dcf1ede1ebe7dbf0ece0f3efe3f0ece1f5f2edebe9dc080900 +0d11000b1000060b00060b000d1100070c00181b001013000a09001712000b03001b1000 +0a0000f9f2e8fffef5e9e5dce6e2d7f1ede1fbf8e9e9e6d5ebe8d5f7f5e0f0eed7f3f1d8 +e8e7cbf4f3d5efeecff8f7d8e5e4c5eeedcf040300fffee5e5e3cef5f2e1ebe7dbe4e0d5 +120e05f4f0e7fffef8e4e0d7d9d5caf9f5e9faf7e8ece9d8e9e8e410152b000023000023 +00052a000023040c310000230000230003290a1237000023000023050a3000002300052b +000017ebe9eaf4f0e4eae6daf2eee2dcd8ccfbf7ebf9f5e9f5f1e5efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9dd +f6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff +2747ae1338bc001dad00119b001dc80738db1c60f31b54bbe0e9fff4ebe2e9ecdbecf1dd +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +e9e5d9fefaeef1ede1040000fbf7ebfffff3ede9ddf0ece0e6e4d8f8f5ece7e4dbdbd8cf +faf7eef9f6ede3e0d7f8f5ecf0ede4e8e5dcfefbf2edeae1eae7de030000ece9e0edebdf +fcf8ecf6f2e6e4e0d4ebe7dbf7f3e7eae6daf0ece0eae6daf7f3e7e4e0d4fffff3e4e0d4 +e1ddd1fcf8ecebe7dbece6daf4ebe2f0e6daf6efddeee9d5efedd8efeedceeeee4a9a8a6 +746f76fff9fffffbfbfef1e1ffffd8b0a265fbec9bfff596fdf894ffffa6fffaa3e5d88a +ffffbcffffbdffffbdffffbaffffb2b3a75b726b25ffffc9fffbd5ffffedefeeecfffeff +ffffffeeeeeefffffffffffff4f4f6f5f5f5fffffff3f3f3ffffffd7d7d7fefeffffffff +f4f4f6fffffffffffffcfcfc000002fffffff6f6f8fffffffbfbfdfffffff8f8faffffff +fffffff8f8f8fdfdffffffffededeff6f6f6fffffff5f5f5fffffffffffff6f6f8ffffff +fffffff7f7f7fcfcfefefefef6f6f8fffffffffffffffffffbfbfdffffffe7e7e9ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffefffffefffffffffffffffffffffffffffdfffffdfffffb +f5f4eff7f6f1fffff8e4e1daf6f3eadddad1fffff4e1dfd3efebe2f1ece6efeae4e6e1db +f9f4eeece7e1d7d2ccfffdf7ada8a2726d67f5f0eafffcf6f0ebe5f0ebe5ede8e2efebe2 +efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfece8dcf5f1e5f3efe3eae6da +ece8dcf6f2e6f1ede1e0dcd0a4a094a09c90fffbeff2eee2f2eee2e9e5d9efebdfeeeade +f7f3e7f4f0e4f1ede1f2eee2f0ece0f0ece0f2eee2eae7d6e9e8ccf3f4c8040a00f1fa9f +e4ed84eff88beff68feff48ee2e87cf0f57fe0e662fcff79eaed6ae8e974f3f093ffffc6 +070100dbd7cef9f5ecf2eee3eeeadee8e5d6eeebd8f4f2dde7e5cce4e3c7f6f5d7040400 +050500151500040400f1f1cbe5e5c1ffffe1040300f0efd3070500fdfae9040000eae6db +e3dfd6e2ded5e7e3dafdf9eeece8dcd9d6c7f1eeddf1f1e5000104f7fffff8ffffe1ecf2 +f8fffff3fefff5fefff7fffff0f9ffedf8fef8fffff6fffff3fcfff7fffff8ffff000508 +eeeee6f6f2e6e3dfd3ede9ddfcf8eceeeaded9d5c9f3efe3efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8df +f6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae +1338bc001dad00119b001dc80738db1c60f31b54bbe0e9fff4ebe2e9ecdbecf1ddeeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff6f2e6 +e0dcd0fffdf1040000f7f3e7e4e0d4fcf8ece8e4d8e8e5dce3e0d7f1eee5fdfaf1efece3 +e3e0d7faf7eee3e0d7f8f5ecdfdcd3e9e6dde6e3dafcf9f0030000f5f2e9eeece0e1ddd2 +e7e3d7faf6eae8e4d8faf6eaede9dde6e2d6fffef2f2eee2f1ede1dedacef8f4e8e7e3d7 +e9e5d9f7f3e7faf4e8f4ecdfefe8d8f6efdcecead3efedd8efeedceeeee6aba7a86c646f +fffafffff5f4fffceaffffd1aa9850f8e888d4c55eb0a645938930a89b4dc2b16bb7a462 +ad9857b6a25daf9c50ae9d4bb7ab57a89f528f8a4afffcd2fbf9e4fffefdfefbfffffeff +fcfcfefffffff6f6f8fefefffffffffffffff7f7f9fdfdfffffffffffffffafafcffffff +f3f3f5fffffffdfdff09090bfffffffafafcfffffffffffffafafcf5f5f7fcfcfef8f8fa +fffffffffffffcfcfefffffffffffffbfbfdffffffefeff1ffffffffffffececeef8f8fa +fffffff6f6f8fffffffffffffffffffcfcfefcfcfefffffffffffffffffff9f9fbffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffefffffefffffffefffffffffffffffffffffffffdfffffdfffffb +f5f4efeeebe4f3f0e9f2efe6fffff6e4e2d6f3f1e5f4efe9dbd6d0fbf6f0fef9f3ded9d3 +f6f1ebf2ede7efeae4ada8a2726d67f5f0eafffcf6f0ebe5f0ebe5ede8e2efebe2efebe0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfece8dcf1ede1eeeadeece8dcf6f2e6 +faf6eadedaceb9b5a9b4b0a4b8b4a8fcf8ecf6f2e6f4f0e4eae6daefebdff0ece0dedace +f8f4e8f0ece0ebe7dbf1ede1efebdff1ede1ece9d6f6f5d7d8daa8192000e2e989eff790 +e9ef8ff3f4a60e0c00f9f8a6f7f892feff7af1f65bf2f856f9fe64f7f775e5e1860d0900 +fffcf6eae5dfe2ded5f7f3e7efecddf1eedbf0eed7ffffe5f3f2d4040400e5e5bfecedc5 +e0e1b7e6e7bb0d0e00eaebc3d6d6b0ffffdc080700e5e3ca080500e1decff7f3e7f7f3e8 +fffff6e7e3daefebe0faf6eaece9daf3f0dfe8e8dc000200f4fcfe979fa1151d1ff9ffff +000204020a0cf5fdfff9ffff949c9e131b1df5fdff000204000204f9ffff040807f5f5eb +e9e5d9faf6eaeae6daede9ddece8dcfffcf0e6e2d6efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9 +f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1338bc +001dad00119b001dc80738db1c60f31b54bbe0e9fff4ebe2e9ecdbecf1ddeeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0ece0e9e5d9 +eeeade191509e2ded2efebdfede9ddeeeadeebe8dffffef5030000030000030000f5f2e9 +faf7eeece9e0030000211e15030000eeebe2fffff6030000edeae1efede1040000f8f4e8 +e4e0d4f0ece0ede9ddf0ece00b0700e2ded2040000fdf9ed070300040000fffff3e6e2d6 +040000eae4d6f4edddefe8d6f6f0daecead3efedd8efeddef0ede8aba6aa6e646ffffaff +fff1f1fffce6fff7c4a2903efff488bcab3fd5c671ffffbdffffc3fff1baffebb8fffec8 +ffffc1fffdb7fffeaffff09ffcf0a47b7335ffffdafffeeefffcfffcf8fff6f5fbf7f7f9 +030305000002101012ffffff0000020d0d0ff4f4f6f8f8fafcfcfe000002020204000002 +ffffffffffff000002ffffffffffff000002ffffffffffffffffff0c0c0e0d0d0f000002 +f8f8fafdfdff000002050507000002000002ffffffffffffededef161618000002ffffff +f7f7f9010103040406000002000002fffffffcfcfeeaeaecfffffffbfbfdffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffefffffefffffefffffefffffffffffffffffffffdfffffdf9f8f4f6f5f0 +fffff8e6e3dcf3f0e7ebe8df030100050300040000110c06040000050000060100e4dfd9 +f5f0eae6e1dbada8a2726d67f5f0eafffcf6f0ebe5f0ebe5ede8e2efebe2efebe0efebdf +efebdfefebdfefebdfefebdfefebdfefebdff0ece0ece8dcede9ddf2eee2f1ede1dfdbcf +c0bcb0a7a397aca89ca6a296aca89ca9a599b1ada1b0aca0b0aca0aca89cb5b1a5f5f1e5 +f0ece0e5e1d5f1ede1ece8dceeeadef2eee2dbd5c7ffffe4060700f3f6b3eeeeb0fdf8ce +0800000c00000d0000e3d8abf2ef8ef5f770f1f55af6fa5dffff74f7f591070300ebe6e0 +e9e4def3efe6faf6eae7e4d3e3e1ccf6f4dbe3e2c40404001f1f00090a00040500040600 +202200040600040500181900090900040400ecebcff6f4df060300efebdf0a0600cecac1 +fffbf2e3dfd4ede9ddf1eedff7f4e3eae7e0000009fcfdff13142816172be7e8fcfcfdff +fcfdfff3f4fff4f5ff111226090a1efcfdfffcfdfff9fafffcfdff00000be1ded9efebdf +eeeadef9f5e9ebe7dbf4f0e4ede9ddf3efe3efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7 +eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1338bc001dad +00119b001dc80837db1c60f31d54bbe0e9fff4ebe2e9ecdbecf1ddeeeddbefebdfefeae4 +f1eae4f5e8dff5e9dbefebdfeceddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfe9e5d9f5f1e5f0ece0 +040000fcf8ecede9ddefebdff3efe3edeae1030000f2efe6ebe8dffbf8ef030000e2dfd6 +080500faf7eed9d6cdfdfaf1040100e1ded50d0a01f5f2e9030100f6f2e7e0dcd0f2eee2 +f3efe3f0ece0e3dfd30d0900ebe7db040000070300e4e0d4f6f2e6040000f4f0e4ede9dd +f3f0e1f4edddefe8d6f5f0daecead3eeedd8efeddef0ede8aba6aa7c717ffff7fffffbf8 +ffeed4ffffc6bba750efdb68ae9d2bfff3a4ffebaefff5bcfff7bffff5bbffedaefff4ad +fff6a6fffca6d3c36effffb8797133ffffdcfffdedfffdfffefbfffffeffffffff000002 +fffffff6f6f8000000fffffff8f8f8050507fbfbfbfffffffffffff4f4f6ffffff000002 +ffffff111113f0f0f0000002ffffffffffffffffff000002fafafafafafcffffff000002 +f9f9f9060608f9f9f9ffffffffffff000002ffffff000002f9f9f9fcfcfe000000ffffff +000000fefefff6f6f6ffffff000000f9f9fbfffffffffffffbfbfbffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffefffffefffffefffffefffffffffffffffffffffdfffffbfffffbedece7fefbf4 +eae7def3f0e7dedcd0fffff40301000400000400000d0802040000f1ece6fcf8efddd8d2 +f5f1e8ada8a2726e65f5f0eafffdf4f0ebe5f0ece3ede8e2efebe2efebe0efebdfefebdf +efebdfefebdfefebdfefebdfefebdff3efe3ece8dcf1ede1f6f2e6e0dcd0bab6aaa8a498 +aeaa9eada99db7b3a7aaa69aada99dafab9faaa69aada99dafab9fa5a195fefaeefcf8ec +e9e5d9f4f0e4e8e4d8e8e4d8f1ede1fcf6eadcd8bf0f0f00eaeaaeedebb20f0800110500 +0c00000f0000130600faf49cf2f077f8f866f6f75dfaf969efec83080400ebe6e2f9f5e9 +ebe8d5e5e3cef9f7e2eeebdaede8d5f4f0d7181600dadaa4e8eba8ffffbaeaeda0e0e299 +f2f4abf2f3a5e5e59beeeeaeedebba0a0700040200e5e2d3faf7eee6e3dcfffcf5e6e3da +f1ede2f4f0e4e3e0d1f8f2e2eae7e201000dfefbffece8fffefafffefbfffdfbfff9f7ff +fefcfffefbfff7f4fffefbfffefcfff8f6fffefcfffdfaff010011f5f1eeede9dd0d0900 +0400000400000e0a00040000f2eee2efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddb +eaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1338bc001dad00119b +001cc80837db1c60f31d54bbe0e9fff4ebe2e9ecdbecf1ddeeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeeecdfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeae6dafcf8eceeeade090500 +eae6daeeeadef9f5e9eae6daedeae1030000f1eee5ece9e0f6f3ea030000f3f0e7030000 +e8e5dceeebe2e8e5dc0e0b02e2dfd60d0a010f0c03e3e1d5e6e4d8eceaddfffef1e7e5d8 +f0eee1f1efe2070500f2f0e3030100f3f1e4eceaddedebde0e0c00f3f1e4dcdacdf6f2e6 +f4ecdfefe8d8f5f0dcecead5eeedd9edeee0eeede9aba6aa726a77fff4fcfff8f3fffce0 +ffffc5a9983edccb55baa633fff5a8ffeeafffe9a6ffe89effed9affef95ffef8effed89 +fff08ddecd71c5b76c80773cfffed8ffffedfffffdfffefffefefefbfbf9040404fcfcfa +fcfcfc040402fbfbfbfefefc070707fffffdfcfcfc000000060606050503000000fffffd +010101090907fffffff6f6f4f7f7f7fffffd0000000000000b0b0b0000000b0b0bfdfdfb +000000fffffdfefefefffffd000000fffffdf2f2f20a0a08fdfdfdfafaf8ffffff000000 +fffffffffffdfbfbfb000000fcfcfcf8f8f6fffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffffffffff +fefffffefffffefffffefffffffffffffffdfffffdfffffbfdfcf7f3f3ebfffef7eae7de +edebdfe8e6d9eceaddf3f1e5050100040000040000e7e3d8faf6ede8e4d9e4e0d7faf6eb +ada9a0726e63f5f1e8fffdf2f0ece3f0ece1ede9e0efebe0efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff3efe3ece8dcf1ede1f6f2e6e0dcd0bab6aaa8a498aeaa9e +aca89cb4b0a4a8a498ada99db2aea2ada99daba79baaa69aa19d91fcf8ecefebdfe6e2d6 +f7f3e7e9e5d9f0ece0f1eedff2edd9f6f2cf080700f4f5a9e7ea8ff3f594eceb8f0d0900 +e8e48bfbf698ebe77cffff93eeeb68f9f669f0ed5efaf68a070200e7e4ddf3f3d7edeec6 +eaeac4f3efd2ece5dbf4ebe4f7eedd080400fefdaaf3f786f3f877ebf06ff9fc87f1f27a +f9fa70ebec64fbf98cffffae080400f7f3da0d0a01e4e3e1ebebebebece7ecece0eeecdd +efecdbf1ecd9f2ebdbefeae406040ffcfcff8987af0e0c34fcfcff000010030511fafcff +fbfaffa5a4c611112bf6f8ff000005000106fcfdff00000eefebe8e6e2d6fffdf1040000 +0400000c0800f3efe3efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8 +ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1439bd001eae00119b001cc8 +0837db1d5ff31d54bbe2e8fff4ebe2eaebdbecf1ddeeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff9f5e9e4e0d4ede9dd040000fcf8ec +e4e0d4f0ece0f7f3e7edeae1070400eeebe2e6e3daeeebe2040100ebe8df030000f1eee5 +f3f0e7eae7de090600fbf8ef030000dfdcd30b0900fffff4d6d4c7efede0eae8dbe7e5d8 +fbf9ec030100e8e6d90b0900fcfaede7e5d8eeecdf030100e1dfd2fffff3dedacef3ede1 +eee8daf5f0ddebead6eeedd9edeee0eeede8a9a7aa6b656ffffbfffffcf6fff5dbffffc6 +af9f48c3b441c3af3efff7a2fff0a6ffec99ffec90fff08afff386fff281fff082fbe57f +cfbe6480722bffffcdffffe3f7f3e7fffdfff6f5fbfffffffffffd000000fffffdfffffd +000000fffffdfffffd000000fffffd080806fffffdfffffdfcfcfa000000f8f8f6000000 +efefed000000fffffdfffffdfffffd000000fffffdf9f9f7fcfcfafafaf8fffffd050503 +e7e7e5fffffdfffffd010100fbfbf9fcfcfafffffd030301fffffdfefefc000000fffffd +fbfbf9fffffd070705fffffdfefefcfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffffeffff +fefffffefffffefffffffffdfffffdfffffbfffffafffffaf6f6eefffff6efece3f5f3e7 +edebdeebe9dcedebdef0ece1040000fcf8edf5f1e6e1ddd2fbf7ecfffcf1e3dfd4ada99e +726e63f5f1e6fffdf2f0ece1f0ece1ede9deefebe0efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff0ece0ece8dcede9ddf2eee2f1ede1dfdbcfc0bcb0a7a397a6a296 +a7a397b5b1a5afab9faeaa9ea7a397aba79bada99dc6c2b6fffff3f2eee2eae6daf7f3e7 +ebe7dbf2eee2ebe8d7f1ecd8f1edca080500e2e395fafc97ecf17be6ea6f101200ffff91 +eae877f4f084e9e375fffa85fff97df7f36df6f18d140e00f7f3f4ededd1eff0c6efedc6 +f5f1d4eee4e2f3e9eaf7ebdf0a0300f3f391dbe159f8ff63f2f85affff77ecee5fffff5c +e4e446fdf97befec8f080500f7f3dae3e0db070709ebebedeaece7ecece0eceddbefecd9 +f1ecd9f2eaddf1eae4000007fcfcff222048181540e9e9fffcfefffbfefffcfffffcfcff +06052706061efcfefffcfffbf2f7f3eef0ff0b0a18f0ece9f9f5e9cfcbbffaf6ea1a160a +d5d1c5f9f5e9e1ddd1efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecde +f1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1439bd001eae00119b001cc80837db +1d5ff31d54bbe2e8fff4ebe2eaebdbecf1ddeeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfe8e4d8e7e3d7fdf9ed0a0600ede9ddf3efe3 +f0ece0eeeadefcf9f0030000ebe8dfebe8dffdfaf1080500e5e2d9050200eae7def1eee5 +ece9e0050200e2dfd6120f06eae7def2f0e4030100fdfbeeeeecdff0eee1edebdee5e3d6 +0b0900f4f2e5030100e6e4d7e7e5d8fcfaed040200f6f4e7ebe9dcf7f3e7f3ece2eee8dc +f5efdfebead6eeedd9edeedeedeee6a9a7a869646bfffbfffffbf7fffce5ffffcda29245 +ab9e38fffd8effec86ffe782fee37afde374ffe671ffe871ffe773fce476fbe484d4c270 +847438fff4cdfffdedfffcfdfff7fffcf8fff4f3f9ffffff000000ffffffffffff000000 +fffffff4f4f4070707f3f3f3000000fffffffafafaffffff000000ffffff0d0d0df2f2f2 +ffffff000000fffffff8f8f8080808f7f7f7ffffffffffff000000eeeeee040404ffffff +fffffff7f7f7090909ffffff060606f5f5f5ffffff000000ffffff000000fefefef6f6f6 +ffffff000000f6f6f6fffffffffffff6f6f6ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffeffff +fffffffffffffffffdfffffdfffffbfffffafefdf8f0f0e8fcf9f0e9e6ddf2f0e4edebdf +eceaddedebdef6f2e7e8e4d9e5e1d6f0ece1f5f1e6e7e3d8e3dfd4f0ece1ada99e726e63 +f5f1e6fffdf2f0ece1f0ece1ede9deefebe0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfece8dcf1ede1eeeadeece8dcf6f2e6faf6eadedaceb9b5a9b0aca0b5b1a5 +fdf9edfefaeefffff3fffef2fffff3fffff3ebe7dbfffff3eeeadeeeeadef4f0e4ede9dd +f6f2e6e8e5d6ece6d8eae6cb121000f0f1adedf097ffff9ef9fd8f0c0e000d0b002c2800 +0e09000f09000f0a00fffb91f6f17cfcf5a4070000f0e9f9ebe7dbfaf9ddeeeacfefead7 +ede2e6f6ebf1efe2d9181100eaea88ffff86eff65af1f85ae4e758fdfe72e5e64dffff7f +e8e572f9f4a20e0a00f0ebd5f7f4efebebedebebebeaede6eceddfeceddbefecd9f1ebdb +f2eadfefeae606050bf9fafff8f6ffedebfffcfcfffcfefffcffffebeef5fcfcfffcfbff +fcfdffd8dbe2fcfffbfcfffbedeffc00000be6e3defffbeff3efe3ece8dce9e5d9fdf9ed +f2eee2f0ece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2 +f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1439bd001eae00119b001cc80837db1d5ff3 +1d54bbe2e8fff4ebe2eaebdbecf1ddeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfebe7dbfffdf1e4e0d40400000b0700040000040000 +0e0a00dfddd1f5f2e9070400100d04030000e8e5dce8e5dcefece3030000151209030000 +e3e0d7fdfaf1030000ece9e0f0eee2efede0030100eceaddf3f1e4fffff2e4e2d5030100 +e7e5d8110f02f6f4e7f0eee1e8e6d90e0c00e5e3d6030100efebe0f3ece4eee7ddf5efe1 +ebead6eeedd9edeedeedefe4a8a8a66c6a6ffffbfffff8f6fffeecfffdd3b6ab69a59943 +fff690f8e474f6e16af5df67f4de64f8e064f9e167f8df6bf3dc72edd87bb3a05484733d +ffffdcf7ebdffff5f9fffafffffcfffffdffffffff010101f8f8f8f8f8f8010101ffffff +ffffff050505fffffff8f8f8000000111111000000070707f4f4f4000000ffffffefefef +ffffff080808fefefef4f4f4030303010101000000ffffffffffff000000000000030303 +010101ecececfffffffbfbfb040404040404ffffffefefef101010000000040404030303 +fbfbfbfdfdfdfffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffeffffffffff +fffffdfffffdfffffbfffffbfffffafffff8f5f5edfffdf4eae7def1efe3eeece0efede0 +f4f2e5f3efe4ebe7dcf7f3e8f6f2e7dfdbd0fffdf2efebe0f9f5eaada99e726e63f5f1e6 +fffdf2f0ece1f0ece1ede9deefebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfece8dcf5f1e5f3efe3eae6daece8dcf6f2e6f1ede1e0dcd0aba79ba39f93fffbef +f4f0e4f9f5e9f0ece0f2eee2ebe7dbf7f3e7f7f3e7e8e4d8eeeadeefebdfece8dcf8f4e8 +eae6daf9f5ecfffaea060300ebeab2edefa4e1e48de7eb8df2f396ffffb2e7e495fff9af +f0eaa0fdf6a6f2ec96e3dd7ff0e8a9110809fff9ffdfdad6ebe8d5eae5d1fcf6eaf8edf5 +ece1e9faf0e70a0200f4f399e6ea6fffff7cf0f662f7fa75f0f171fffd78e2de61f4f08d +fcf8af080300e4dfcbe7e4dff8f6f7ebebe9ebece4eceddfeceddbefecdbefecdbf2e9e0 +efeae605040aeff0ffafaece121131fcfdff000009060a0bfcfffff9faffdcdcf4040615 +fcffff000200000300fcffff02020cedeae5ece8dcebe7dbeeeadef3efe3ede9ddede9dd +f4f0e4efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0 +f4eadeecebd9e8f3f9cfe7ff2747ae1439bd001eae00119b001cc80837db1d5ff31d54bb +e2e8fff4ebe2eaebdbecf1ddeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff1ede1f0ece0ede9dde5e1d5f9f5e9faf6eaf0ece0e2ded2 +e7e5d9fefcf0e4e2d6eeece0e3e1d5f5f3e7f9f7ebf0eee2f6f4e8e4e2d6f7f5e9fcfaee +e1dfd3edebdfeeece0edebdffefcefe3e1d4f4f2e5f7f5e8e0ded1f1efe2f8f6e9f3f1e4 +dcdacdf6f4e7dedccff5f3e6eceaddf3f1e4f4f2e5ebe7dcf3ece6eee7dff5efe3ebead8 +eeedd9edeedcedefe2a8a9a3707072fffefffffefbfff8ebfffddcf8f1bdbab16e998e35 +ae9e2db09e20af9b1eaf9b1eb19b21b09b24b09a2bae9833a7933c907e36ffffcafff4cf +fffeecfffcf7f1ebeffffdfff9f7fafffffffdfdfdfffffffffffffdfdfdfffffff8f8f8 +fffffff8f8f8fffffffffffff0f0f0fffffffffffffffffffdfdfdffffffffffffffffff +fbfbfbf0f0f0fffffffcfcfcfffffffffffffafafaffffff000000fffffffafafaffffff +fffffff5f5f5fffffffffffff1f1f1ffffffffffff000000fffffffefefef1f1f1ffffff +fffffffcfcfcfefefeffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffdfffffd +fffffdfffffbfffffbfffffafefbf4f4f1eafffff6ece9e0f1ede2eae6dbe9e5d9ede9dd +e2ded3f6f2e7ece8dde8e4d9f5f1e6e6e2d7f1ede2e6e2d7ada99e726e63f5f1e6fffdf2 +f0ece1f0ece1ede9deefebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f0ece0f1ede1f0ece0ebe7dbeae6daede9ddf3efe3f6f2e6e5e1d5c7c3b7fffff3e9e5d9 +e9e5d9e7e3d7eeeadeebe7dbf3efe3ebe7dbe8e4d8f1ede1ece8dceae6daf6f2e6ede9de +eae5e2ddd9d0131100f3f1c8f4f5bbeaeba7eaeca3fbfbb3eae9a9f7f2b8ece5b1f4edb9 +e8dfa8fdf5b7fcf3b0fff7c9060002ebe4f6eee9e3f9f6e3e9e4d1f3ece2f8edf5eee2ec +f2e7e50c0600f3f1a7eff289d7db62ffff88f6f88af6f58bfefa8ef5f08cfbf6a5e0dba1 +151100e9e6d5faf7f2e7e6e4ebece6ebede2ecedddeceddbefecdbefecddf2e9e2efeae7 +000004fefdff0b092104021af8f7fffeffffeaecebfefffffefdff06051721212df9fafc +f5f8f1fbfef7f8f9fe050409f3f0e9dcd8ccf6f2e6fbf7ebe6e2d6e0dcd0f9f5e9e9e5d9 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdf +eaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eade +ecebd9e8f3f9cfe7ff2747ae1439bd001eae00119b001cc80837db1d5ff31d54bbe2e8ff +f4ebe2eaebdbecf1ddeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1ede1f0ece0f2eee2f8f4e8ebe7dbdbd7cbfffff3faf6eaf1efe3 +edebdfe1dfd3f2f0e4f7f5e9f3f1e5e4e2d6e7e5d9eae8dcebe9ddeeece0f1efe3ebe9dd +f8f6eae6e4d8f2f0e4dfddd0fcfaedeae8dbdddbcef4f2e50c0a00030100f2f0e3f2f0e3 +f8f6e9f4f2e5e6e4d7fdfbeee2e0d3edebdefaf6ebf3ece6efe6e1f5eee4ece9d8eeedd9 +ecefdaedefe1a7aaa1717171f7f7f7fffefdfffdf2ffffeaffffdde9e3b3a59c5b8d7e29 +8f7f1f917e20917e20917c21907c25907b2a8e7a318f7b3cffffccfffcd8fffbe1fffdf1 +fffdfafffbfffcfafffffffffefefefffffffdfdfdfdfdfdfffffffefefefffffff5f5f5 +fffffffffffff3f3f3fffffff9f9f9f8f8f8f8f8f8fefefefffffffafafaf5f5f5ffffff +f6f6f6fffffff1f1f1f3f3f3fffffffbfbfbf4f4f4242424ebebebfffffff5f5f5f9f9f9 +fdfdfdf5f5f5fffffffdfdfde5e5e5ffffff000000f9f9f9ffffffffffffffffffffffff +e7e7e7ffffffefefefffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffdfffffdfffffdfffffbfffffb +fffffafffffafffff8faf7f0f1eee7fffff6f3f0e7fdf9eef6f2e7f4f0e4f5f1e5f5f1e6 +efebe0eae6dbfffff4e2ded3f7f3e8f0ece1e8e4d9ada99e726e63f5f1e6fffdf2f0ece1 +f0ece1ede9deefebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff5f1e5 +eae6dae7e3d7efebdff4f0e4f0ece0eeeadef0ece0f7f3e7dfdbcffffef2ede9ddf3efe3 +f4f0e4faf6eaf7f3e7f0ece0ebe7dbf0ece0f3efe3ede9ddece8dcf1ede1efebe2f1edec +f5f1ee0503000403000c0d000d0d000607000706000c0a00080300080200080200150d00 +0a02000b03000a01001d1415dbd6dcf5f2e3fdfbe4ebe6d0eae4d8f5eaf0f2e6f2f4e8ea +130b00efeab3edec9cffffade6e589f0ed9ee8e598e5de8dfbf4a6eee8aaf8f1c50d0700 +f6f3e4ece9e2e7e6e1ecece2ebeddfeceddbeceddbefecddefebdff1eae2efeae70c0a0d +fefefff1eefffefdfffffdffe8e9ebfffffdfefffff5f3fef7f7fffbfafffbfdfcfffff8 +f8fbf2ffffff000000e4e1d8fffef2ece8dceae6dafaf6eaf7f3e7ddd9cdf7f3e7efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedf +ebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9 +e8f3f9cfe7ff2747ae1439bd001eae00119b001cc80837db1d5ff31d54bbe2e8fff4ebe2 +eaebdbecf1ddeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfe9e5d9f1ede1f2eee2e6e2d6f2eee2ebe7dbfaf6ead8d4c8e3e1d5faf8ec +fbf9eddddbcffaf8ecedebdfe3e1d5fbf9edfdfbeff3f1e5ebe9ddebe9ddf1efe3fdfbef +dfddd1f6f4e8f7f5e8f2f0e3e2e0d3fcfaedf1efe2f5f3e6e1dfd2eeecdfeceadde5e3d6 +f8f6e9e7e5d8f5f3e6dad8cbf5f3e6e5e1d6f3ebe8efe6e1f5eee4ece9daeeedd9ecefda +edf0dfa7aa9f6f716cf3f3f3fcfcfafffffafffff3ffffe8ffffe3fbf5d3fffddefffddf +fffce1fffce1fffce1fffbe3fffbe4fffbe6fffaebfdede0fffcf6fffcfbf8f2f6fffcff +fffdfffdfdfff7f7f9fffefffffefffdfbfcfdfbfcfffefffffefff8f6f7fffefffcfafb +fffdfef5f3f4fffefffffefff3f1f2fffefffffefffffefffffefffffefffffefffbf9fa +fffefffffefffffefffdfbfcfffefff5f3f4fdfbfcfffefffdfbfcfffefffdfbfcfffeff +faf8f9fffefffffefffcfafbfffefff9f7f8fdfbfcfffefffffefff1eff0fffefffffeff +e4e2e3fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffffdfffffbfffffbfffffbfffffbfffffa +fffffafffff8fffff8f4f1e8f7f3eae2ded5efebe0efebe0ede9deece8ddf2eee3e4e0d5 +efebe0ede9def2eee3e8e4d9faf6ebede9deada99e726e63f5f1e6fffdf2f0ece1f0ece1 +ede9deefebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff3efe3ebe7db +eae6daf1ede1f5f1e5f1ede1ede9ddece8dceeeadeeae6daf3efe3eeeadef1ede1e9e5d9 +e6e2d6dfdbcfeeeadeefebdff4f0e4f0ece0eeeadef0ece0ede9ddefebe2e8e4e5f7f5f6 +e8e8def5f4dff7f8d8dddeb6f7f8d0f5f3cdfaf7d8e9e3c9f4eed8ebe4d1fef6e3f2ead5 +f4edd1f4eed6ded8ccfffff1e2e1c3dfdfbbf3f0d1faf5e1faf1f2ece2ebe6dbe3150c05 +0802000804000a05000a04000a02001b12001b14000c05000c0500080200070000e7e3d8 +f5f2ebedede5ecece0ecedddeceddbeceddbefecddefebe0f1eae4efeae7010000000004 +0300090a09110100040e0e0c0a09050001000a080b030305050304030400010100000100 +0f0e0a010000f1eee5ebe7dbf4f0e4e0dcd0f7f3e7e9e5d9f6f2e6ece8dcefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeedd +f3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9 +cfe7ff2747ae1439bd001eae00119b001cc80837db1d5ff31d54bbe2e8fff4ebe2eaebdb +ecf1ddeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff2eee2ebe7dbebe7dbf9f5e9f4f0e4e4e0d4fbf7ebfcfaeededcd0eae8dc +fffff3d6d4c8f5f3e7efede1e9e7dbe4e2d6efede1f0eee2eceadeeeece0dbd9cdfffff4 +e1dfd3ebe9dcefede0eeecdfe7e5d8f7f5e8e6e4d7f3f1e4eceaddf6f4e7e8e6d9edebde +efede0e4e2d5fdfbeee7e5d8f6f2e7f3ebe8eee6e3f5eee4ece9daeeedd9edefdaedf0df +a7ab9d6c6f68fefffdfffffff4f4f2fffffafcfaeeffffeffffbeffff9f9fff9fffff9ff +fff9fffff9fffff9fffff9fffffafffffbfffffbfffffafdfffefff8f8fafefffff7fbfc +f8fcfdfffffffffefffbf9fafffefffffefffbf9fafffefffffefffefcfdfaf8f9fffeff +fffefffcfafbf4f2f3fffefff4f2f3fffefff7f5f6fcfafbfffefff8f6f7fffefffffeff +f6f4f5fcfafbfffefffffefffffefffaf8f9fbf9fafffefffffdfefcfafbfffefffffeff +f6f4f5fdfbfcfffefff8f6f7fffefffffefffffefff4f2f3fffefffffefff1eff0fffeff +f3f1f2fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffffdfffffbfffffafffffbfffffafffffafffff8fffff8 +fffff8fffff6dedbd2c8c4bba39f96ada99eafaba0aeaa9faba79cafaba0b1ada2b1ada2 +aaa69bafaba0aca89da8a499aeaa9fada99e726e63f5f1e6fffdf2f0ece1f0ece1ede9de +efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeadef2eee2f4f0e4 +f0ece0ebe7dbebe7dbefebdff3efe3ede9ddf5f1e5e8e4d8ece8dcf2eee2f0ece0f5f1e5 +f8f4e8ebe7dbf0ece0f3efe3eae6daefebdff4f0e4ebe7dbefece3ede9eae6e4e5ecece4 +f3f4e4e9e9d1edeecff5f4d6e9e8ccf0eed9e9e6d5fcf6eaf6efe5e2dbd1fffaeee2dacd +fcf7e4f1eedbf3f1d8efefc9f4f5cdfdfad7e7e2ccede5e2f9eff7f6ebf3f4eaebf0e7d8 +f4edd3fbf4d7efe8cefdf1e5ece0d2efe6c7f1e9c4ede6c9f5efd9fdf7e9f4f0e7e6e3da +f3f0e7eceddfeceddbeceed9eeeddbefecddefebe0f1eae4efeae6ede9e8f0eeefe4e2e3 +f6f4f5e8e7e5ebeae6f1f0ebefeee9e9e8e4ebeae6f1f0ebe5e4dfefefe7edede5efefe7 +f2efe8ece8ddeeeadeede9ddf3efe3ebe7dbf0ece0ede9ddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9dd +f6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff +2747ae1439bd001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dc +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfefebe0f5eee8e9e2dcf1eae0f3f0e1ebead8f5f6e4e1e4d3a5a799 +73766dedefeafefffdf7f7f7fcfcfafffffbf7f6f1fffefbfffcfffffbfffffbfffffbff +fffbfffffbfffffcfffffdfffffefbfffff8fffff6fcfff3fbfff1f9ffedf8ffedf9fff1 +fffffafffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffafffff8fffffafffff8fffff8fffff8fffff8fffff6 +fcf8ef837f765a564d7a766d766f6570695f7c756b736c62747065747065747065747065 +7470657470657470657470656b675c868277dcd8cdfffff4eeeadfece8ddfdf9eee8e4d9 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeebe2eeeae7ecebe7ecece2eceddf +eceed9eceed6eeeed6eeedd8eeeddbeeecdfefebe0efebe2efeae4efeae4f1eae2efebdf +efedd8efeed2efefcbefefc9f1eecdf1ecd6f1eae4f1e8ebf1e7eff1e8ebf2e9e2f2eadd +f2eaddf2e9e0f3e7e9f3e7e7f3eadbf3ebd6f2ebd9f2eaddf1eae0efebe2eeebe2eeece0 +ecedddeceddbeeedd9eeeddbefecddefebe0efebe2efeae6eeebe6eeebe6eeebe6eeebe4 +eeebe6eeebe6eeebe6eeebe4eeebe2eeebe2eeebe2eeebe2eeebe4eeebe4eeebe2eeece0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8df +f6e6e9f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae +1439bd001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeece0f0ece3e9e2daf2eee3f4f0e4e9e7d8f3f1e2ebecdcc1c3b5dddfd4 +f6f9f0ebece7e1e1dffafafaf9f9f9e9e7e8f4f2f5f1f0f6f1effaf1f0f8f1f0f8f2eff8 +f2eff6f1f0f6f1f1f3f0f2efeef3ecedf5e8ebf6e5eaf8e1eaf8dfe9f9dcebf7dff1f2ea +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1eff2f1edf2f1ef +f2f1edf2f1eff2f1edf2f2eaf2f2eaf2f2eaf2f2eaf4f1eaf4f1eaf4f1e8f4f1e8fffff6 +ece8dff8f4ebfffef5ece5dbece5dbfdf6ecf2ebe1f4f0e5f4f0e5f4f0e5f4f0e5f4f0e5 +f4f0e5f4f0e5f4f0e5ece8dde8e4d9fffff4fffff4e5e1d6e5e1d6f8f4e9eeeadfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebe0eeebe4ecece4ecece2eceddfeceddd +eceddbeeeddbeeeddbeeecddeeecdfeeebe2eeebe2efeae4efeae4efeae4efebe2efecdd +efedd8efeed2efeed0f1edd4f1ecd9f1eae4f1e8e9f1e8ebf1e9e7f2e9e2f2e9e0f2e9e0 +f2e9e4f2e7ebf2e8e9f2e9e2f1ebdff2e9e0f1eae2efebe2efebe0eeece0eeecdfeceddd +eceddbeeeddbeeeddbefecddefebe0efebe2efeae4eeebe6eeebe4eeecdfeeecdfeeebe2 +eeebe4eeebe6eeebe4eeecdfeeecddeeecdfeeece0eeebe6eeebe4eeecdfeeecddefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9 +f3e7e7eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1439bd +001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfefebe0e8e4d9f3efe3f6f2e6e8e6d9eeecdff5f3e6e4e5d7fffff4fffff6 +fafaf2fffefafffffdfffefff9f7f8fffffffefffffefffffefffffefffffefefffefeff +fcfffffcfffffbfffffbfffff9fffff9fffff8fffdf8fffbf8fffbf9fffafffffafffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffa +fffefbfffffafffff8fffff6fffff6fffff6fffff6fffff6fffff6fffff6f6f2e9fffbf2 +fffef6fffef6fef7effffef6fffdf6fffbf3fffff4fffff4fffff4fffff4fffff4fffff4 +fffff4fffff4fffff4fffff4fffff4fffcf1eeeadfece8ddf2eee3ede9deefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeece0eeece0eeece0eeecdfeeecdfeeecdd +eeecddeeecddeeecddeeecdfeeecdfeeece0eeebe2eeebe2eeebe2efeae4efeae7f1e9e7 +f1eae2f1eae0f1eae0f1eae0f1eae4f1e9e6f1eae4f1eae2f1ebddf1ebdbf1ebdbf1ebdd +f1eae0f1eae2f1eae2efebe2f1eae4efebe2efebe2eeece0eeece0eeecdfeeecddeeecdd +eeecddeeecddefebdfefebdfefebe0efebe2efeae4efebe2efecd9efecd9efebdfefebe2 +efeae7efeae4efecdbefedd8efecdbefebe0efeae6efeae6efecddefecdbefecddefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7 +eceddbeaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1439bd001eae +00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdff0eddee9e6d7f1ede1f5f1e5e9e7daeae8dbf5f3e7f6f4e8dedcd0eae8dcf5f2e9 +eeeee6e6e3dee5e4e0ede9e8eae9e7e9eae2e8ebe0e8ebe2e8ebe4e8eae5e6ebe5e6ebe7 +e6ebe7e5ebe9e5ebe9e5ebe9e5ebe9e5ebe9e3ece9e5ebe9e6ebe7eae9e4ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2ece9e2 +ece9e2ece9e0ece9e0ece9e0ece9e0ece9e0ece9e0ede9e0ede9e0faf6edefebe2e6dfd7 +eae3dbf5eee6f3ece4eee5deeee7dfefe8deede9deede9deede9deede9deede9deede9de +ede9dee6e2d7ebe7dceeeadff2eee3f9f5eaf5f1e6ede9deeae6dbefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdfeeece0eeece0eeece0 +eeecdfeeecddeeecddeeecddeeecddeeecdfeeecdfeeece0eeebe4f1e8edf1e7eff1e8ed +f1e8e9f1e9e6f1eae4f1eae2f1eae0f1ebdff1ebddf1ecd9f1ecd9f1ecd8f1ecd9f1ebdb +efebdfefebe2eeebe4efeae4eeebe2eeece0eeecdfeeecdfeeecdfeeecdfeeecddeeecdf +eeecdfefebdfefecddefecddefebdfefeae4efebe0efedd6efedd4efecddefebe2efeae7 +efeae4efedd8efedd4efecd9efebdfefeae7efeae7efecddefecd9efecddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddb +eaefd8ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1439bd001eae00119b +001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdd +f1f0dceae9d5eceadbf1efe2ece8ddeae6dbefebe2f3efe4f2eee3f4f0e4f7f3e7eceade +e5e1d8f3f0e9fbf6f2e8e6daeef1d6eef2d1edf2d2edf2d2edf2d4edf2d4edf1d6ecf2d8 +ecf1daecf1dbedf0dfedf0dfedefe2ecf0e2edefe2edefe4eeeee4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0eee2 +f0eee2f0eee2f0eee2f0eee2f1ede2f1ede2f1ede2f1ede2f2ebe1f0e9dfede6def7f0e8 +fff7f0f1e8e1eae1dafbf4ecf3ece2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +eae6dbf1ede2ece8dde9e5daf2eee3f0ece1eae6dbf1ede2efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddefecddefebdfefebe0efebe2efebe2efebe2efebe0 +efebdfefecdbeeeddbeeedd9eeeddbeeeddbeeecddeeebe2f1e8ebf1e7f0f1e7eff1e8eb +f1e9e7f1eae2efebdfefecdbefecd9efedd8efedd8efedd8efecd9efecd9efecd9eeeddb +eeebe2ecece4eeece0eeecdfeeecddeeecddeeecddeeecdfefebdfefebdfefebe0efebdf +eeecdfeeeddbeeedd9efecdbefebe2f1ebdff1edd2f1edd0f1ebdbf1eae2f1e9e7f1eae4 +f1ecd6f1edd2f1ecd8f1ebdff1e8e9f1e8e9f1ebdbf1ecd8efecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8 +ebecdef1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1439bd001eae00119b001bc7 +0837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecddf0efda +edecd7ebead8edebdeefebe2ece8dfeae5dfebe7def5eee4ede7dbefe9dbf0eddeeee8dc +ece8ddf0e9e1e9e5d9edebd2edeccdedeccdecedcdecedcdecedcdecedceeaedceeaedd2 +ececd4ecebd6ecebd7eceadbede9ddede9ddede9deeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadd +eceaddeceadeeceadeede9deede9deede9deede9dee8e1d7f0e9dfeee7dfebe4dcf1e8e1 +f0e7e0eee5def3ece4efe8deede9deede9deede9deede9deede9deede9deede9def3efe4 +f7f3e8f0ece1ebe7dceeeadfede9deede9def5f1e6efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefecddefecddefebe0efebe2efeae4efeae6efeae4efebe2efebdf +efecdbeeedd9eeedd8eeedd8eeedd9eeeddbeeecdff1e9e6f1e8e9f1e8e9f1e9e7f1eae4 +f1ebdfefecd9efedd6efedd6efedd6efecd9efecddefebdfefebdfeeecdfeeecdfecece2 +ecece0eceddfecedddeeeddbeeeddbeeecddeeecdfefebe0efebe0efebe2efebe0eeecdd +eeeddbeeedd8eeedd9f1eae2f1ebdff1edd0f1eecff1ecd9f1eae2f1e9e7f1eae4f1edd4 +f1edd0f1ecd6f1ebdff1e8ebf1e8e9f1ebdbf1ecd6efecdbefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecde +f1ede2f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1439bd001eae00119b001bc70837db +1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeeddbebedd5eff1d9 +edecd8eae8dbf1ede4f1ece6eee6e3eee7e1ebe2d9eee6d9f6efdffcf7e4f9f2e2eee8da +eee6dbf7eee5f5ece5f5ece5f5ece3f5ede2f5ede2f4eee0f4eedef4eedef4eedef5ede0 +f5ede2f5ece3f5ece5f6ebe7f6ebe9f5ece7f4ede3f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f1efe2f1efe2 +f1efe2f1efe2f2eee2f2eee2f4ede3f4ede3fdf6ecfaf3e9f3eae3ece3dcf0e7e0faf1ea +faf1eaf1eae2f4ede3f2eee3f2eee3f2eee3f2eee3f2eee3f2eee3f2eee3e7e3d8e9e5da +ede9deefebe0efebe0efebe0f0ece1f1ede2efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff1ebddf1ebdff1eae2f1eae4f1e9e7f1e8e9f1e9e7f1eae4efebdfefecdb +efedd8efedd6eeeed6eeedd8eeedd9eeedd9f1ecd9f1ebdbf1ebddf1ebddf1ebdbf1ecd8 +efeed2efeed0efeed2efedd8eeecdfeeebe4eeeae9eeeaebeeeaebeeeae7ecece2ebeddf +ebeeddeceed9eeedd9eeedd9efecdbefebdfefebe2efebe2efeae4efebe0eeecddeeedd9 +eeeed6eeedd8f1eae0f1ebdff1eecff1eecdf1ecd9f1eae2f1e8e9f1eae4f1edd4f1eecf +f1ecd6f1ebdff1e8ebf1e8e9f1ebdbf1ecd6efecdbefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeecdfeaeedfebeeddf3e9ddf6e8dff6e6e9f3e7e7eceddbeaefd8ebecdef1ede2 +f6e9e0f4eadeecebd9e8f3f9cfe7ff2747ae1439bd001eae00119b001bc70837db1c60f3 +1e55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeeecdf +ebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff1ebddf1ebdff1ebdff1eae0f1eae0f1eae0efebe0 +efebe0efebdfefecddefecddefecdbefecddf1ebddf1ebddf1ebddf1ebddefebdfefebdf +efebdfeeece0eeece0eeece0ecece0eeece0eeece0eeecdfeeecdfefecddefecddf1ebdd +efecddefecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeeddbe7e9d1f2f5daefeeda +e9e7d8f1ece6f4efebf0ebe7f1ece6f1ede2f5f1e5ebe8d7e4e1d0eee8daf4eee2f2e9e0 +f1e8e1f1eae4efeae6f1e9e6f1e9e6f2e9e4f2e9e4f1eae2f1eae0f1ebdfefebdfefebdf +efebe0f1eae0f2e9e2f3e8e4f2e9e4efebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +eeebe2eeebe2efebe2efebe0eeece0eeecdfeeeddbeeedd9eceed9eeedd9ecedddeeebe2 +eeebe4eeece0eeecddeeecddeeecddeeece0ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2ecece2ecece2ecece2 +ecece2ecece2eeebe2eeebe2eeebe2e9e6dfe6e3dcf0ebe5f8f3edefeae4e9e4deede8e2 +eee9e3edeae3ebebe1edeae3ebebe1edeae3ebebe1edeae3ebebe1f1eee7e9e9dfedeae3 +edede3eae7e0ebebe1f0ede6e9e9dfeeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +eeebe2eeece0eeebe2eeebe4eeeae7eeeae9eeeaebeeeae9eeebe6eeebe2eceddfeeecdd +eceddbeceddbeceddbecedddecedddeeedd9eeedd9eeeddbeeecddeeeddbeeedd9eeeed6 +eceed6eeedd8ecedddecece4ecebe9eceaefece9f0eceaefebebebebece6eaeee0eaeedf +ebeeddebeeddecedddeceddfecece2eeebe4ecebe6eeebe6ecece4ecece0ecedddeceed9 +ecedddeeebe4eeece0eeeed6eeeed4eeecddeeebe4eeeae9eeebe6eeedd9eeeed6eeeddb +eeebe2eeeaebeeeaebeeecdfeeeddbeeecdfecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2 +ecece0eaeee0ebede0efebe0f3e8e4f5e6e9f2e8e7ecece0eaeedfe7ede1edeee6f3ebe0 +f4eadeedeadbe9f2fbcfe7ff2648ac1439bd001eae00119b001ec90130d42165f81b52b9 +e3ecfff0e7def0f3e2e9eedaeeeddbefebdfefeae4f1eae4f5e8dff5e9dbefebdfeceddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1ebddf3eadbf3e7dbf6e9e1f1e6e0efe4e2f5ebe9ece5dfeee7df +eeeadeeeebdaf1ecd8f1ecd6f2edd9f3ecd9f4eddbf4edddf3ecdcefe9dbece8dcefede1 +f2f2e8f2f4e9ebeee5e2e8deeaede2eaede2ebede0ecedddefecdbf1ecd9f2ebd8f2ebd9 +efecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeddbe4e8cdf2f6dbeceed9e4e2d3 +f8f3ede3dedaefece7f3f3ebdde0d5f4faecf0f6e8dde1d3e9e9e1f2edeaede3e4f0e8e5 +e4ecd7f6ffe7dfe6d4eff1e4f1eee7e9e4e0eae7e0ebebe1ecf0e1dde4d2e9f3dbecf4dd +e7ecd6f1f4e1f0eedfe5e3d7ecede7e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8ebede8 +eeede9f5f1eedddad5f6f6ece6e9d8e7ebd2f1f8d6e3edc8ebf2d1eaf2dde7e9e8e8e9eb +f2f5eaedf2dee6ead3e8ebd6ebeee5e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8e9eee8e9eee8e9eee8e9eee8 +e9eee8ebede8ebede8ebede8ebedeaebedeaebedeaebedeaebedeaebedeaebedeaebedea +ebedeae9eee8ebedeae9eee8ebedeae9eee8ebedeae9eee8ebedeae9eee8ebedeae9eee8 +ebedeae9eee8ebedeae9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8ebede8 +ebede8ebede8ebedeaebedeaebedecebedecebedecebedeaebede8e9eee8ebeee7e9eee7 +e9eee7e9eee7e9eee7e9eee7ebeee7ebeee7ebeee7ebeee7ebeee7ebeee7ebeee5e9efe5 +ebeee5e9eee7e9eeeae9edece9edeee9edeee9edeee9edece9eeeae9eee8e9eee8e9eee7 +e9eee7e9eee7e9eee8e9eee8ebedeae9eeeaebedeae9eeeae9eee8e9eee7e9eee7e9eee7 +ebedeaebede8ebeee5ebeee5ebeee7ebedeaebedecebedeaebeee7ebeee5ebeee7ebede8 +ebedecebedecebede8ebeee7ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8 +ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8ebeee7 +ebeee3ebeee5ebedecedebeef2e9eef2e9ecedece8e9eeeae6f5f2e9f4eee3e1d5f8f0e3 +ede4dde3e6f5ddf8ff1a419e133abb001eae00119b001ec90031d42165f81952b9e3ecff +f0e7def0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff1ebddf1e8d7f2e6d8f5e8dff3e8e4f6ecebfcf3f4f9f4f1fbf6f0f0eee2 +f0eedff0eddaefedd8f0ebd8efe9d9f0e8dbefe7dcede7dbf3efe3f3efe4eae8dce4e4da +eaece1eef0e5ecefe4ebede0ebeddfeceddfeeecddefecdbf1ecd9f2ebd8f1ecd9efecdd +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeeddbebefd6f1f5dcf0efddeae6dbfaf5f1 +ebe6e3edece8d6d9d2e9f3e8e5f1e3d4e2d3f8fff8e6ebe5f1f1eff7f0f7e8e7e5e5f2de +d5e9cef1feece7eee6dededef5f3f6f4f2f5efefefe4ebe4f7fff7edfae9dfecdadbe6d5 +e2e9d9f1f3e6eff0e8e7ece8e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae7ebece6e5ea +e1dee5fbf8ffe1e1e3eff2e7e0e8d1e8f3d5e4f1d3e6efdee6f0e8f4f9ffcfd3dcebf1ef +e0e5def6fceeedf3e5e7ece6e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae7ece6e9ece3 +e9ece5e6ebeee7eaf1eee8ecf0e7eaebe9ece6ebeec8dadce4f4f1e8eaddfaf2e5f3e8e4 +e6e7f9dcf7ff1f48a2133abb001eae00119b001ec90031d42165f81952b9e3ecfff0e7de +f0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddf6f1def2eddaf0eadeeae5dfebe7e4e3e1e2e5e4e2e1e2ddebece4ebede2 +ebebdfebebdfedeae1edeae3eee9e6ede9e6f1f0ebe7e7dfe8e8e0f3f0e7eeece0e1decf +e4ded0f1ebdbf2ebd9f1ecd9f1ecd9f1ecd9efecdbefecdbefecddeeecddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecddeef0dbe9ecd9edebdee9e4def4eeeeede9ea +e6e6e6a9afab98a59b83958595aa998fa1917b887e919b939498999aa09e93a599778b80 +8d99979fa6ae9190a0908da29390a59291a3838793929ba2828c8e929c9da1a9ab8e9196 +92919999989e969799949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +94989794989794989794989794989794989794989794989794989794989b9b99a79591a8 +9691af8b899f9ea2a39ea59d939d958f999b9296af8d92af9298a699a0aa9ca2b29295a6 +8b8f9a8d9097949899949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949897949897949897 +949897949897949897949897949897949897949897949897949897949993969990969992 +93989b94979e9b95999d949798969993989b9fb1b3deeeebebede0f5ede0f3e8e4e3e4f6 +d3eeff214aa4133abb001eae00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2 +e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecddedecd7eaecd6eceddfecede5f4f6f3e5e9eaf1f5f6ecf0efe2e7e3e2e7e1e6e8e3 +e7e9e4eaeaeaeceaededeaf1eeebf2e8e9ebe4e6e3e7e8e2f2f2eafcf8ecfdf6e6faeede +f9ecd9f6e9d6f5ead6f3ebd8f2ebd9efecddeeecdfecece0ecece0eeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecdfeeefdfe5e6d8f0ebe5ebe6e3ede7ebebe9eee4e5e7 +8c9793f4fffad9f2dfecfff3edfff4e6ffecf2fff8e0f0e6f4fffdf0fffbf0fffdf4ffff +f7fffff0f3fffefcfffefcfffefcfffbfefff9fffff5fefff6fffffbfffff9fbfffdfbff +fffdfffefffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffefefffefdfff9f7ff +fcfdfffbfeffeaeffff4f9fff7fbfff4f4fff7f8fff5fbfff2fbffe1e7fff8fefff9ffff +f9fdfffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff859799deeeebebede0ede5d8f4e9e5e5e6f8cee9ff +224ba5133abb001eae00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2e9eeda +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdd +e8ecd5e8f0d8eaf1e1e8f0e5f2f8f6d4dcdee8f0f3dfe9ebe9f1f3e9f2f1eaf0f0e9eef1 +e9ecf3eaeaf6eae7f8e9e8f6e1e6ecf2f8f8eff1eed9d8d3dbd7ccf6ece0fef1e0eedfcc +f8e9d6f8e9d6f5ead8f2ebdbefebdfecece0ebede2ebede2eeece0efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff3f1e5ebe7def7f2eff0eaecece5eceeebf2e8edf0899893 +ecfff64869546e957a3f684a72997c6789707b9b866b8874698b724969526880737f8f8c +798289808490f4f6fff0f2fff5f9ffeff6fef8fffff5ffffe7ecf0fefefffffdfffcf9ff +fefffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffff0f7eff7ffedf9fffd +f8fcfff3f4ffc4c5ffb6b3ffc5bfffb0acffc0c5fff5fefff7fffff4fefff1fbfaf9fffd +fbfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff849698e4f4f1eef0e3ece4d7f9eeeaecedffd2edff244da7 +133abb001eae00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2e9eedaeeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfecedddecf1db +edf7dfe9f4e4e0eae1e3edecb7c1c3d4dfe3ccd7dbbcc6c8b9c3c5b7bfc1b4b9bdafb2bb +acabb9a9a6b9a6a5b59b9fa89a9fa29ea2a3a6a6a4aca9a4beb7afe0d8cdfff7ebf3e9dd +f3e9ddf2eaddf1ebdfefebe0ecece2ebece4ebede2eeece0efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1ede2ede6e0f9f0f1f0e7ecebe4ecebeaf0e5edef8d9e98dcfbe9 +70987d305f3d63956f2e603a6c9b77d1fddc7aa3812d57315f85604f6d53f1fff7f5fffd +8a9294000105fbfffffbffffebf4f3f6fffdf9fffffafefdfefffffdfafff6f3fafcfdff +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfbfffdebf5ecf9fff4f8ffffb0adff +b6b1ff1e1c8a08077c1b17a00a078a141778b0b3ffbfc4fff5fcffe1eef6f7fffbf9fffb +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefdfafefd +fafefdfafefdfafefdfafefdfafefdfafefdfcfef9fdfef6fcfff8f9fefffafdfffffbff +fffafdfefcfff9feff899b9de4f4f1eceee1ebe3d6f7ece8ecedffd2edff214aa4133abb +001eae00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2e9eedaeeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddde5e9d8eaf3e0 +e9f3e8e3ece7edf7f8c3ccd1f5fefff5fefff9fffff9fffff9fffff5fafdf3f4f9f0eef9 +edebf9ebe9f6f7f8fddee2e5d9dde0e5e9ecd9dde0bcc0c3c0c1c5dbdcdeeaebedebebeb +ecebe9ecebe7eeebe4eeebe2eeece0efebe0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff0e9dfeee5def5ebeaede2e6eee7eeeae9eedfeae68ca296e9fff4366543 +ddffe81e592967a3702864316fa778295f2e6d9f6c487645648862e2fce1f5fff67a857d +fbfffd000200eef4f0f9fffbf6fff7f9fffafcfffbf1f1effffefffffefffffffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffcfffff1f8fef8fffff7fdffb8b9ff1509b51b0fc7 +04057b1217730205702524a30f0ba00e08a8160fadbebafff4fdfff3fffffbfffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8c9ea0deeeebebede0eee6d9f4e9e5e7e8fad1ecff1e47a1133abb001eae +00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2e9eedaeeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfe7ebdcedf3e7ecf1eb +e1e7e5e8f0f3bcc3cbf8fffff9fffffbfffffbfffffcfffdfcfffdfffffffffefffffdff +fffdfff9f7fafefffffbfffff4fdfff0faffe8f6ffc0d1e191a2b2ddeefee0eefbe4edf6 +e7ecefebece7efebe2f2eaddf2ebdbf1ebddefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f1ebdff5ede2f2e9e0f6ebe7efe5e6f6f0f2edefeeddeae38fa797e5ffefdfffe92a6633 +d2ffdb2a6e3360a4671e5d2464a1682c632a659764e9ffe6eeffedf4fff6000400000301 +060a09090f0bebf5edf9fffbf6fdf6fcfffdf0f0f0fffefff7f5fafffffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffcfffff9fffff1f8ffb6b8ff1b159b0600c60a00c6f0f3ff +eef7fff0f6ffe2e4ffeae6ff1a12ca0700c80900a9c9d0ffecf8fffbfffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff90a2a4ddedeaeff1e4f7efe2f6ebe7e7e8fad5f0ff224ba5133abb001eae00119b +001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0e9e9dfeeefe9ebebebe9eaee +e9ecf3bfc2cbfbfffff9fefffcfffffcfffafefff8fffff6fffff8fffffafffefbfffefb +fffcf8fffffbf4f9fdf5ffffebffffc4dffab7dafa9fc3e57093b3cbeaffe2f9ffe5f3fc +e9edece9e5dafef1e0ecdfccf2ebdbefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdd +f1ead8f5ecddf4eae1f1e8e3f2edeae8eae5e5f2e887a38de6ffeddfffe6d7ffdd1c6122 +d6ffd81d621f70b370266629639c67dfffe7e5ffededfff6effffaedf7f8fbffffc3c6cd +000209fbfffffbfffffafffff9fcfffffdfff7f3fffffcfffffefff4f6f5fefffff7f9f8 +fefffff6f8f7fefffff6f8f7fefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffcfffbeffbeff5ffffbbb8ff140bb40900bff0eaffe6ecff16226c +040c6f0f1585e7ecfff0edff0b00d40d02c2b6bdfff4fffffbfffffefffff9fbfafeffff +fafcfbfefffffcfefdfefffff6f8f7fefffffeffffeff1f0fefffffcfefdfbfdfcfeffff +fefffff9fbfafefffffefffffbfdfcfefffff1f3f2fefffffbfdfcfefffff4f6f5feffff +fafcfbfefffffefffffbfdfcfefffffcfefdf7f9f8fefffff6f8f7000100fdfffefdfffe +fafcfbfefffffefffffefffff8faf9fefffffefffffdfffefefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc8 +0030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebe0ede8e2f1edeaeee9edebe8efeceaf5 +c0c0cafefefffcfdfffefffdfdfff7fefff3fefff2fffff3fffff3fffef5fffdf7fffff6 +fffffbf2f7fbe2f2ffdbf7ffcbf2ffabd8ff7aabd67faed86890b4c5e5fee1f4ffedf3f3 +ece5dbfff3defdedd6f2ebdbefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf1ead7 +f5eddaf4eadef1e8dff2ede9e8ebe4e5f3e689a28ce4ffe9dcffe02e6b306eb070296c27 +d8ffd427692257955429622d6b9e73446d4de7fff0f4fffff9fffff9fcffc7c7d1000007 +fcffffeaedf203060b00000700000902000d01000bfbfafffefffffeffff020403f8faf9 +f8faf9fbfdfcfefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffcfffaf7ffefb9c4e0140fa10100c01103d20600aae8f1ffe2f0ffedf5ff +edf3ffeef3ff05059b0e00de1004d215187fb3bce3f8fcfff0f2f1fefffffafcfbfeffff +e4e6e5fefffffefffffefffff0f2f1fefffffefffffefffffefffffeffffe2e4e3feffff +fcfefdfcfefdfdfffefcfefdfefffffefffff6f8f7fefffffdfffef8faf9fefffffeffff +f4f6f5fefffffeffffeceeedfefffff5f7f6fefffffbfdfc000100fefffff7f9f8feffff +fbfdfcfefffffcfefdf7f9f8fefffffafcfbfefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d3 +2064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebe0efe7e4f3eaebf1e8edeee7efeee8f4c0bdc8 +fffdfffdfefffefffdfefff8fefff4fffff3fffff3fffff4fffff6fffff8f7f3eafcfbf7 +f8ffffefffffddfcffbee8ff7babd9467aac5386b56794bd456783d0e6f4ebf3f5eeeade +f0e1caf7e7cef2ebd9efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdbf0ebd5f4eed6 +f3ecdaf0eadef2ede7e9eae4e6f2e68aa18de9ffed38673b669f681c581c6eaa6a195613 +dfffd641793a5e955c386a395b845ce8ffe9f5fff8fbfffdf2f4f3cacacc070707fbfdfa +fcfffd000200fefffffffffff4f1f8fffefffafafcf2f2f2090909000000ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffcfff8eefee4bfc9ec0a00ae2b18ff0b00ea160bd1161d85edfaff0d138fd4d8ff +2121c10000a70e01e70d03d609098bc4c9fffbfdfffbfbfbfbfbfbfffffff3f3f3ffffff +fffffff9f9f9f3f3f3fffffffdfdfdfdfdfdeeeeeefffffffffffffffffff5f5f5f9f9f9 +fffffffffffff1f1f1f7f7f7fdfdfdfffffffcfcfcfffffffffffffcfcfcf9f9f9ffffff +fffffffdfdfdfffffffffffffbfbfbf8f8f8ffffff000000eaeaeafffffffffffff5f5f5 +fffffffffffffefefefffffffffffff3f3f3ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f7 +1851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebe0f0e9e3f3ebe9f1e8ebefe8efeee8f4bdbac5fefcff +fefffff9fdfcfafff9fafff6fafff6fcfff6fdfff9fdfffcfdfffcfffffbf0f4f3f5ffff +e8feffdafaffbfe7ff88b5df7babd96692bf7199bd597992718492e8f1f0f6f4e8e3d8c2 +fffbe3f2ebdbefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdbeeecd3f3efd6f2edda +f0eadef2ede7e9eae5e9f0e98d9f91ebfff1648e682657286ba06a295f2570a368316029 +d4ffca34672c689961567d50eaffe4f3ffedfcfff6fffffabfbeb9010100f5f7ecfcfff2 +000300fefff6f6f7effffffbfbfaf8fffffffffffffdfdfd060606f4f4f4ffffffffffff +f8f8f8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fcfffaf7fff1bac2f02518d70000d80f00e7120cc4d4dbffedf8ff131b98ebf0ffecedff +1916c50900df1409e30c09a0b2b4fffbfcfffffffff8f8f8fafafa000000010101000000 +000000fffffff4f4f4000000060606151515e4e4e4fefefef2f2f2151515000000060606 +f3f3f3ffffffffffff000000000000000000ffffffffffff0e0e0e000000000000fafafa +f6f6f6ffffff000000000000000000ffffff0000000d0d0d000000000000fbfbfbf1f1f1 +fcfcfc000000050505000000ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff1eae0f3ece6efeae7eee9edeae9f1b9b9c3fafdfffbffff +f9fffff8fffff8fffff8fffff8fffff9fffff9fffff8fffff8ffffdfedeee2f3fae0f6ff +e5ffffe4ffffc5e6ffcaedffcfeeffc2ddf89aafc066757cd4dddae4e6dbf0ebd8f2ebd8 +f1ebddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdbeeecd5f1efd6f2ecdcf0e9df +f2edeaeae8e9eaeeed909d96e9fff1486a4f78a07d2d572f79a27632592c7a9d73416736 +e2ffd63363255c824f455f38ebf8defeffeffffff3c8c4b8070500ffffeffeffed050a00 +000400060900010100fffff8f5f5f3ffffffeeeeee000000fffffffbfbfbffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffff +f7fffda8aeea0500ba1f0df51b12c3e2e5ff0f167eedf7ffe1e8ffdde5ffedf9ffeaf1ff +160cdf0100d7120db2bebefff6f6ffffffffffffff000000fffffffffffff3f3f30a0a0a +f4f4f4060606fffffffefefefbfbfb0d0d0dffffff050505fdfdfdffffffededed0d0d0d +ececec000000fffffffafafaffffffe2e2e2fffffff5f5f5fffffff8f8f8131313fdfdfd +000000ffffffffffffffffffeaeaea151515f4f4f4ffffffffffff131313ffffff000000 +fffffffbfbfbffffff000000ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff0eddef0ece0edeae3ececece8e9eeb3b7c0f5fcfff7fffff5ffff +f4fffff4fffff4fffff4fffff3fffff3fffff1ffffdceef8e6fbfff0ffffe5fbffdef1ff +e3f5ffdff1ffe2f4ffd5e6f8e6f4ff79838c788283eef4f0eef4eaf1f3e5dddeceeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefecdbededd5f0efdaf0eddef0e9e3f2ecee +ece7eeecedf2919b9ceefff9e2fdecebfff4dcfde07f9e7ff0ffece1f8db77926f47723d +628f583d61357e9676000500e6e6dafffef8d1cac4040000deded2fffff3fefff1fdfff2 +f8fceefffff8010000fcfcfaffffffffffff000000fffffffffffff0f0f0ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfffff6ffff +b6bbfb1609bb1606da0b04acf0efffeef2ff0000660b15761e2a80edfbffdde4ff0a01ce +0f03e1120db1c2c2fffbfbfff1f1f1ffffff000000fffffff7f7f7ffffff000000ffffff +000000000000000000000000000000ffffff000000f1f1f1f8f8f8f7f7f7060606ffffff +0b0b0be8e8e8ffffffedededfffffffcfcfc0000000b0b0b0d0d0d000000ffffff000000 +f4f4f4ffffffedededffffff030303f7f7f7efefeff7f7f7000000ffffff000000000000 +000000000000111111ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddefeedaedefdaeaecdfebede8e5eaedaeb7bef2fcfff4ffffb9c9d6b8cad8 +b6c9d8b5c7dbb4c6deb3c4e2b2c2e4afc4e3b3cedfbad6e1afc7d1a5b9c2a0aeb7a6afb8 +bbbfc8c0c1c6b3b2b7a3a1a2a1a19f676964eff4ede4ebe3dde7dcf8fff3ecece0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefecddedecd7f0efdbf0ece1eee9e6f4eaf3ece6f2 +edebf89498a1f5fffff1fffff0fffbf0fff6748976f2fff1f1feedf4fff1dfffe3001000 +edfff4e7f9ed131718fffbfffff9ffc4b8c60b040cfffdfff7f5f8ffffffecedf1feffff +fffeff000007ffffffefefefffffff070707f8f8f8fffffff0f0f0ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffcfffff8ffffb7bdf9 +1711991004be0000c01307d3eeecffeef3ffedfbffcedcffedf2ff1f1dc00700cd1105d1 +120ea0b1b3fff2f3ffffffffffffff060606f2f2f2fdfdfdffffff020202ffffff040404 +fdfdfdf6f6f6fffffffbfbfbfdfdfd060606ffffffffffffffffff000000ffffff030303 +fafafafffffff9f9f9ffffff000000fffffffdfdfdf0f0f0040404ffffff000000ffffff +fffffffefefeffffff000000ffffffffffffffffff050505f5f5f5090909ffffffffffff +ecececfbfbfbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecddf0efdaedefd9eaeddcebeee5e4eaeaadb6bdeffcfff1ffffe4f9ffe1faffdffaff +ddf7ffdcf5ffdbf1ffdaf0ffd9f0ffd5f0ffb9d5e39cb7c2cce0e7f5fffff3f7faeeeaeb +d3c9c8ddcfcee7dcd8dad5d1bfc0ba8186827d8681d6dfdceaefebecece4eeece0efebe0 +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0efebe0 +efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecddebecdaeeefdff2ebe3f0e7e8f4eaf3ece6f2ececf8 +9498a3eaf3faf7ffffe9f9f6f2fffd77887ef7fffafcfffaf6fff3f0fff3dffbe5000a01 +00040600000efffafffff6ffd1c3da060009fffbfffffeff000000fffffff8f7fdf7f5ff +0b0914faf9fefffffffefefe000000fffffff6f6f6fffffffbfbfbffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffefffff8fcfff8fbffb7b2ff +140dab1107e10000dd0c08ce090aa0e5ebff1a1f7a110fae0000c20f0bdc0000aec2c2ff +f8f8fffcfdfffffffff6f6f6000000fffffffffffffafafa000000f7f7f70a0a0af8f8f8 +ffffffffffff000000ffffff000000fffffffbfbfbfbfbfb040404ffffff040404f9f9f9 +fdfdfdffffffebebeb0c0c0cfcfcfcefefefffffff000000ffffff000000fffffffbfbfb +fefefeffffff020202f8f8f8fcfcfcffffff010101f8f8f8090909f4f4f4fcfcfcffffff +030303ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9 +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdd +edecdaf0efdbeceed8e9ebddeeeff1a3aab0f4fffff0ffffadc6e4b0cef2a6cae4b1d5ef +a7c8eba5c1e6b8d1efb2c8e0abbacfb5c5d5eeffffd8ecf3b5c4c7a3a9a9afa5a6b4a2a2 +c1afada49695aca8a59b9f9eced6d891969c93919cece6f0fbf7f6e2e2daefece3f3f3e7 +e7e5d9f4f2e5e3e1d4faf8e9efecddefecddefebdfefebdff1eae0f1eae2f1eae2f1eae2 +efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecdfeaecdeeeeee2f4e9e5f4e6e6f2ecf0e9e8eee9eef49299a1 +fcfffff0f3faf8fffff4ffff728780f5fffdf8f9f4fffff8f4fbe9171f10f0f4f5f2f2fe +010015fff9fffff7ffcbc0d1060002fffbf2ffffeeffffed010200000200030303feffff +ffffffe8e8e80a0a0a070707000000fffffffefefef8f8f8ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfcfef0fefeffc8c0ff0d0889 +060cc60004de0000df0e0ad0f5e8ff1205910700c60000d60c19e1000ea2babdfffffcff +fffefff0f0f0ffffffffffff000000060606000000000000ffffffe8e8e80a0a0a070707 +000000fffffffefefef8f8f8070707010101000000fffffff8f8f8f6f6f6181818000000 +000000fffffffafafa0000000404040a0a0a000000fffffffdfdfd060606010101000000 +ffffff0a0a0af1f1f1ffffffffffff000000fffffff1f1f10d0d0d000000000000ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfedebde +efeedceeedd8eaebdbeeeef0a4a9aff2ffffeeffffd9f6ffd1f2ffd6feffc6eeffcbedff +dcfaffc5e1f9bbd0e3d9e1f4eff8ffbaced79fb7bbcce0e1edf7f6fffdfdcbbdbde2d4d3 +dbd3d1d3d9d7b8c6c66f7e81bbc8d0a3a2b2736f7dd6d4d5fffffae1e1d9fcfcf2e7e7dd +f0f0e4f2f0e3eae8d9efecddefecddefebdfefebdff1eae0f1eae2f1eae2f1eae2efebe0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfedebdff1ede2f3eae3eee9e5edefece5ebebe9eef197989dfffbff +fffcfff2f7fbf5ffff7c918ae6f5eefffefbfffbf9fffff800010009080d0b0916090619 +fcf7ff110a1ac9c2ca0b0602fcf8ecffffedfefde8fffff1fffff6f0f2effbfcfef6f6f6 +fefefefefefefffffffbfbfbffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff3f8f3f7fff7ffb8b5ff0f1c9f +0006b30000d0110cdafce7ff0c008b241ad10208c0000ca4afc6fff9fafff9f2faf2f0f3 +ffffffeeeeeef8f8f8fffffff6f6f6ffffff000000f6f6f6fefefefefefefffffffbfbfb +fffffffffffffffffff3f3f3f9f9f9f9f9f9fffffff9f9f9fdfdfdfdfdfdffffffffffff +eeeeeefffffffbfbfbf3f3f3fffffff3f3f3fdfdfdfcfcfcffffffeaeaeaffffffffffff +fffffffffffff8f8f8fdfdfdfffffffdfdfdfffffffcfcfcf5f5f5ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfedeede +eceed9eaecdeecedef9fa6aef0ffffedffffc4e1ffabccf5c4e9ffa9cee8b4d5f8c3e0ff +9ab4cbb0c3d2f8ffffa7afbcb9ccd2e6ffffeeffffeffffff9ffffd7d7d7f4f4f4f9ffff +e6fcf9b7d7d2cceeed6d8b8d96a7af888f978c8e8ddad9d4e7e6e1eeeee6e8e8deebebdf +f4f2e5e6e4d7efecddefecddefecddefebdff1eae0f1eae0f1eae0f1eae0efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff2eadff5e7dcf5ebdfeceee0e3efe1e1f5e9dfeee7eceeed9e959afff4fefffaff +fcffffeefdfa7a8d87c1ccc6d1c7c6cbbcbfcecbd2c9ccd3bec1c6bdc1c2c3c8c4b7bcb5 +000200caccbf050500fffff6fbfbf3f2f1edfffffdf9fafcfcfffffcfffffefffffefefe +fffffffafafafffffff8f8f8fdfdfdfbfbfbffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffefffff9fffffbfff0e7fafcfbffeefdffb7c9ff +060eae0d09b51000862916890d0773bac3ffaec7ffe2f9fffcfafffff8fffffdfffbfbfb +fffffff5f5f5030303000000000000fffffffffffffefefefffffffafafafffffff8f8f8 +fdfdfdfbfbfbfffffffffffffffffffefefefffffffffffffffffffafafafefefeffffff +fffffffffffffffffff9f9f9fffffffffffff8f8f8ffffffffffffffffffefefefffffff +f5f5f5fffffff6f6f6fffffffffffffafafafffffffffffff0f0f0fefefeffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfecece0eceee0ebecda +eaecdfe9edf09ba2aaecfcfcecffffcbe8ffaecef5c7ecffbce2f9c5e3ffb5cff0aec7dd +edfdffcfcedcacacb6f3fffff0ffffe3fdfcf0fffff7fffff3fbfee7f1f3f2ffffc9ece8 +8db7b355827fb0d8d76e8a8d98a7ac696d6e7a7975fefdf9e0dfdaeeeee6ebebe1e7e5d9 +f2f0e3efecddefecddefecddefecddf1ebdff1ebdff1eae0f1ebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f2eaddf5e8d8f5ecdbe9f1dce0f1dee0f7e5def0e4eceeeb9e9598fffafffff9fff9f9fb +eef7f489968f00020007000011050701000505080f070b0a0b1308000600061200000600 +010900000300fbfcf6faf8fbfffefff0f0f8fcfffffbffffeff4f8f6f7f9fffffffefefe +fffffff8f8f8fffffffffffff7f7f7ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffefffffbfffffbfffffafffffafff7fffff0feffafbbff +c1c3ffc4b9ffcfc1ffc7c4fbe5eefff0fffff0fffffffbfff8ebfff7f4fdfffffffafafa +f7f7f7fffffffffffff6f6f6f3f3f3f7f7f7fffffffefefefffffff8f8f8ffffffffffff +f7f7f7fffffffafafaebebebfffffffdfdfdfffffff6f6f6fffffffffffffffffff9f9f9 +f8f8f8fbfbfbffffffffffffe6e6e6fffffff8f8f8fffffff7f7f7fdfdfdfffffffdfdfd +fffffffffffff6f6f6fffffffffffff2f2f2f9f9f9ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0eceee3eaede2eaeddceaede2 +e8ebf0969fa8e8f8f8ebffffbfd9fcb5d5fcb9ddf7bce0f6bfdcfc98b1cfc0d7e9ebf5ff +b0a6affffafffcffffecfcfcf0ffffedfffff5ffffecf6fff4ffffcee7eb8ab2b20d3e3b +447571cdf7f59fbdbf5e6d708c90934d4b4ce2e1dfedece8efefe7f1f1e7e4e2d6f7f5e8 +efecddefecddefecdbefecddf1ebddf1ebddf1ebdff1ebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdb +f0ebd7f1efd8edefd9e7efdae7f4e3e1efe2e7f1e9959a96f9f7fafffdfffffdfffffeff +eceeebfefefcfffbf8fef9f5fffffae5e5dbfefff3e5edd6f9ffeaf9ffeaf2fee6fbfff1 +f9fcf5ffffffefecf3fffdfffefefff3f5fff6fdfffbfffffefffff9f9f9fffffff4f4f4 +ffffffedededffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffefffdfcf8f9fff3fdfff3ffedebeef8fffff1ffffe6f2ff +fbfbfff2ebfffffbfffffefff9fff3fbffeffffefbfffdfffffeffffffffffffffffffff +f6f6f6f9f9f9fcfcfcfffffffffffff9f9f9fffffff4f4f4ffffffedededffffffffffff +f8f8f8fcfcfcfffffffbfbfbfffffff8f8f8fffffff6f6f6fdfdfdf2f2f2ffffffffffff +fcfcfcf8f8f8fffffffdfdfdf7f7f7fffffffffffffffffffffffffefefefafafaf4f4f4 +fdfdfdffffffedededf9f9f9fffffffffffffffffff2f2f2ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc8 +0030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeece0ecede7eaede4e9eddee8eee4e7eaf1 +929aa5e5f4f7e9ffffc3ddffd3f0ffc0e2fbbee1f5c1defc9eb6d2daefffbcc3cdebd8de +fff8fbfefafbf4fefff2ffffeeffffe1edf9f4ffffe9f9ff95adb720474c5a8888b0dcdb +d0f4f4cfe4e7717c80a6a7ab5a585b817f80f7f6f2e4e3def0f0e6edebdfedebdeefecdd +efecdbefecdbefecdbf1ebdbf1ebdbf1ebddf1ebddefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeddbeaeed5 +eef1d6f2edd9eeebdaedf1e2e3ede2e5f2e9919c96fcfffffafbfffafbfdf0f6f6ebf6f2 +0d18140001000905000801001914000404000a0d00010a00edf6e3fbfff6fbfffaffffff +fffefffffdfff5f2fbf7f7fffcfffff9ffffedf5f7fefffff7f7f7ffffffffffffffffff +fbfbfbfffffff7f7f7ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffefffdf7fef6fffffa9e8a93aa939b92878186878165747b7f8f9c757b87 +8f8d98867f868d867e9c9d7ee6eac7ffffeffcf9f2fffffde8e8e8fdfdfdffffffffffff +f7f7f7fefefefffffffffffff7f7f7fffffffffffffffffffbfbfbfffffff7f7f7ffffff +ffffffffffffecececfffffffcfcfcfffffffbfbfbfffffffffffff7f7f7ecececffffff +ffffffeeeeeefffffffffffff8f8f8f8f8f8f9f9f9ffffffeaeaeaffffffffffffffffff +fbfbfbfffffffcfcfcfffffffdfdfde1e1e1ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d3 +2064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeebe2eceee9e7ece6e9ece1e9eee7e6e9f29098a5 +e2f1f4e8ffffc6deffd3f1ffc2e5fbbfe0f3bfdaf7a4b9d4e8faffa2a5acfff1f6ffe9eb +fffcfbf3f7f8d4e1e7f4fffff2fbffe7edff97a2b62033445c7a85b6d8e1b7d6dbedffff +e8edf3918e9599979c7a787b4a4849eeedebe4e3dfebebe3f1eee5e7e5d8efecddefecdb +efecdbefecd9f1ecd9f1ecd9f1ebdbf1ebdbefecddefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddbe6f0d5ecf2d6 +f6ebd9f7e7daf2eee3e6ebe4e3f2eb8e9d9afbfffff2fafdf1ffffeaffffe4ffff000a04 +fbfffff7ecdaf7e8a7ffffb5eee4a9ffffdb0a0800000002fefefff4f1fffffbfffaf2fd +fffafdfffefbfffefafafffbf1faf7f9fffff6f8f7fffffffffffffbfbfbe9e9e9fefefe +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffcfffff8fffff8fdf97a6a6af1d9d5ebd9cbf3ece2e2ebf0dcecfbe3ecfde2e4f1 +d7d1d3f8eee2afaa8a5e5b3afefff1fafbf6fefefcfdfdfdfffffffffffff6f6f6ffffff +fffffff1f1f1f7f7f7fffffffffffffbfbfbe9e9e9fefefefffffffffffff3f3f3fafafa +fffffffffffffffffffafafaf4f4f4fffffff8f8f8fbfbfbfffffffffffff7f7f7ffffff +fffffff3f3f3fbfbfbfffffffbfbfbfffffff5f5f5fffffffffffff0f0f0f6f6f6ffffff +fcfcfcfafafaf3f3f3fffffffffffffefefeffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f7 +1851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeebe2eceee9e7ece8e9ece3e9eee8e6e8f48e96a3e1f0f3 +e8ffffbbd3f5b6d2f9b7d7eeb8d9eab2cce796aac3e0f0fda4a7acead4d6fff7f6f6f1ee +f9fffff0ffffd8eaf6a0adc0616b84323e563d4f658faabb9cbac5c0d8e2d7e4ecd7d1db +aea2ac8f8a90989699615f62e9e8e6f6f5f1ebebe3ece9e0e9e7daefecddefecdbefecd9 +efecd9f1ecd9f1ecd9f1ecd9f1ebdbefecddefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddde6f0d7ecf1daf9e9dc +f8e5def2ede7e6ebe5e6f0ef94999dfff9fff8ffff000e0900190b001b0900160a000007 +fff9e8ffffadf8dc78ffffb6f4e7ba070000fffbff010013fffafffaeefffff9fffffbfb +f6ebe5fffff4f8fbf0f9fffaf9fffbfefffdfbfbfbfbfbfbfefefefffffffffffffefefe +f1f1f1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fbfffff0fffff8ffff8e847afffce8fffde3fdf2defbfffff2fffff2fffff7fffffffff8 +fff7e69c9579ffffea474946fbfffff9fafcfffffffafafaf7f7f7ffffffe9e9e9ffffff +fafafafffffffbfbfbfbfbfbfefefefffffffffffffefefef1f1f1fffffffffffff5f5f5 +f5f5f5fffffffffffffffffffdfdfdfffffffffffff9f9f9fbfbfbfdfdfdfefefeffffff +fefefefcfcfcf8f8f8fffffffcfcfcfdfdfdf9f9f9fbfbfbfffffffbfbfbfffffff9f9f9 +fffffffffffff6f6f6fdfdfdf5f5f5ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80334d71c60f31e57be +dee7fff4ebe2edf0dfeaefdbeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeebe2e8eae7e7ece8eaede4e5eae6eaecf8818996e5f4f7e7fbff +cce3ffcbe7ffcbebffb9d8eabdd5f1aec2dbbbcbd8acb4b6c2b8b6dcd3ccf8fffbe2f8f5 +dcfbfde3ffff7d94a6a0b4cc30415b283e55294658203e499cb2bddde5f0897f8a968691 +8780879896995c5a5decebe9f6f5f1e9e9e1f2efe6e6e4d7efecddefecdbefecd9efecd9 +f1ecd9f1ecd9f1ecd9f1ebdbefecddefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddeaeddaf0efddf7e9e0f2e7e1 +eaf1eae2ede9edecf2a092a1fff3fffbfeff00180e5ad5b90792716bccb8070311733e36 +764800ffff93ffea97fff4bf110600fffcfffdf6ff030012fff9fffff2fefffafafffcf3 +fffef1fdfeeefbfff4f4fef3fefffdfffffffefefef9f9f9fffffff5f5f5fffffffafafa +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffff +f1fffff4ffff7f7e69ffffd8fffad1ffffdffefff4f2fffee5f9faf2fffffcfff1faf8e3 +afa79a4f49495c6174434a5df3f6fdfffffffffffff9f9f9fffffffafafafafafaffffff +ffffffffffffeeeeeefffffffffffff7f7f7fffffffafafafffffff3f3f3fffffff4f4f4 +fffffffffffff1f1f1fffffffefefefffffffafafafcfcfcfbfbfbfffffffffffffcfcfc +fefefefffffff8f8f8fcfcfcfffffffffffffdfdfdf7f7f7fffffffffffff9f9f9f9f9f9 +fffffff8f8f8fffffff6f6f6fffffffafafafffffff6f6f6fffffff8f8f8fffffffdfdfd +fbfbfbfcfcfcfffffff9f9f9fffffffdfdfdf3f3f3fffffffffffff1f1f1ffffffffffff +fffffffffffffafafafefefeffffffe4e4e4fffffff7f7f7fffffff8f8f8fffffffefefe +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80334d71c60f31e57bedee7ff +f4ebe2edf0dfeaefdbeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeebe2e9e9e7e9ebe8eaede4e7e9e6e9ebf7818795e5f3f6e6faffb6cdef +b2cef3b9d9eeafcee0b5cde79fb3ccd6e6f3a0abadf5fcf5eaf6ecdbf9efe3ffffc5f6f2 +d1ffffb9ddeb39586c5e7a90adcce1b3d7e7aaccd8bfdae3e8f5fefcf4ffbfb2bc878087 +969497575556e4e3e1e9e8e4eaeae2f7f4ebf0eee1efecddefecdbefecdbefecd9f1ecd9 +f1ecd9f1ebdbf1ebdbefecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfedebdef3ede1f9e7e3f2e7e5e8f1ec +e1ededf0eaf6a58fa4fff2ffe9ecfd002417008a6b45eac20b7d6401000cffebeafff4ab +f0c964ffffaffff4b907030000020017181a000007060005fff9fffff9faffefebfffdf3 +fdfbeefcfff3fbfff6f6f8f3f9f9f9fffffffffffffffffffcfcfcefefefffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffe9faff +e2f3fd9a9e8ff7f1d9917f71958383847e8a787e948192ae8293ad7e8796818090867c97 +100a26abb3ca5b6777fcfffffffffff3f3f3fffffffffffffffffff6f6f6fffffff1f1f1 +fffffffffffff4f4f4efefeffffffff3f3f3fffffff6f6f6fffffff5f5f5fbfbfbffffff +f5f5f5fffffffbfbfbffffffdfdfdffffffffffffff5f5f5f4f4f4fffffffffffff4f4f4 +fffffff2f2f2ffffffffffff000000fffffffffffff9f9f9f7f7f7ffffffffffffffffff +fffffff4f4f4fffffffffffffffffffffffffffffffffffffffffff5f5f5fffffffefefe +fffffffffffff5f5f5fffffffffffffffffffffffff2f2f2fffffffefefeffffffe9e9e9 +fffffffcfcfcfffffff8f8f8fffffffffffffffffffbfbfbfdfdfdffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001dc80334d71c60f31e57bedee7fff4ebe2 +edf0dfeaefdbeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeebe2eaebe6eaeae8ebece4e9eae5ebebf7808392e2f0f3e5f7ffd5ecffcae6ff +ceeeffbfe0f1bad4ed92a8c0dbedf9879b9cc8e2d9dbfff3c4f8ebbefef0bbfef5c4ffff +c5faffc6f4ffb2dcecb6e0f0c6f4ffbde9f2a6cbd1eeffffe7eaf397919bb2b0b58c8a8d +626061f2f1edf4f3eeeeeee4eceadeebe9dcefecddefecdbefecdbefecdbf1ebdbf1ebdb +f1ebddf1ebddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecdfebecdef1ede2fbe6e5f7e4e6edefeee3ebee +edebf69f92a4fff4fff7ffff001c1056e1c400967066d6be00010efff0f3fff2c0fffeb3 +5b4d06ffffc6d5e7adf4ffdde8fddef7fff30e0f09f5ebecfff8fe1d080d0a00000b0602 +020500000400fefffdffffffffffff050505f1f1f1fffffffbfbfbffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff2fffff2ffff +737a80fff9ffac90cd11003cd0b8ff1a0e6000005a00036400026303005e2b1e7a000037 +f5ffff31403bfafefdfcfcfcfffffff8f8f8f8f8f8f6f6f6fffffff3f3f3fffffff5f5f5 +fffffffffffffffffff7f7f7fffffff1f1f1fffffff7f7f7fffffffffffffffffffefefe +f3f3f3fdfdfdf2f2f2ffffffffffffe9e9e9fffffffffffff7f7f7fcfcfcffffffffffff +fafafaffffffeeeeee101010fbfbfbf4f4f4fcfcfcfffffffafafaf6f6f6ffffffffffff +ecececffffffffffffddddddfffffffffffff2f2f2fffffffefefefffffffffffffbfbfb +efefefffffffffffffffffffefefeffffffffefefeffffffeeeeeeffffffffffffffffff +f4f4f4f7f7f7fefefefafafaf8f8f8fafafafffffff3f3f3fcfcfcffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001dc80334d71c60f31e57bedee7fff4ebe2edf0df +eaefdbeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeebe2ebeae6ebeae6eeebe2ebeae6ebe9f67d7f8edfeaeee3f5ffaec4e9a6c2e9afcfe6 +abccdfa9c4df8ba1b9bbcedc8da5a7cdede8c8f6ecccfffdb9fff5b3fcf3b8fdfaaae4e8 +c4f4fec5f1feb5e1eeafe1eaa3d4d9d4fdffd5f0f7e5eef777767ec9c7cc4745465f5e5c +e8e7e3f3f3ebeaeae0e9e7dbf4f2e5efecddefecddefecdbefecddf1ebddf1ebddf1ebdf +f1ebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecdfeaecdef1ede2fde5e5f9e3e5f1edeee5eaede9edf6 +9797a3fffaffe5f3fc00251a0e7a635bd8ba1f7c6700090cffe9e7ffecc4ffffc446510f +ecffc4e7ffcfe3ffd6e4ffe1ddffdc000600f8f7f5fff4fe0d0004fff9fff5eceffffffa +fbfff9f1f3f0ffffff000000000000fffffff9f9f9fffffffcfcfcffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffcfffdf7fff8e4f5ed757f8b +fef9ff896bb5170043320e5417014912116e0b147b060f7800026b0000560b0649f5ffff +425247f3f8f4fffffffffffffffffff5f5f5ffffffffffffffffffecececfffffff0f0f0 +fffffff1f1f1fffffffffffffffffff4f4f4fffffffffffff0f0f0fefefef1f1f1ffffff +fffffffffffffffffffbfbfbf5f5f5fffffff0f0f0f8f8f8fffffff9f9f9fdfdfdffffff +efefefffffff000000fffffffffffffdfdfdfffffffffffffafafafffffff2f2f2ffffff +ebebebfdfdfdfffffff2f2f2f6f6f6fcfcfcfafafafffffffffffff6f6f6ffffffffffff +fbfbfbfdfdfdfffffffafafafffffffbfbfbfffffffffffffffffff1f1f1ffffffffffff +fffffffffffffdfdfdf3f3f3fffffff4f4f4f2f2f2ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001dc80334d71c60f31e57bedee7fff4ebe2edf0dfeaefdb +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0 +eeebe6ece9e4f0ece1f0ebe7ece9f47b7a88dce5eae1f2fcd6ecffd0ecffceeeffc7e8fb +bdd8f5a3bbd591a7b5a0b7bd8eadafc0eae8baf3edabece6b0f2eeb6f4f3c8f9feb3dbe5 +afd5e0c0e6f1a7d4dac1f1f5e3ffffeaffffb2bcc88f8f99c1c1c32c2b2794938fe4e3de +e5e5dde5e5dbf0eee2f5f3e6efecddefecddefecddefecddf1ebdff1ebdff1eae0f1ebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecdfe9eddcf0eedffbe6e1fbe3e3f5ebece8e9ebe3f1f18b9d9f +f5fffff2ffff000b0700190d002110001202000900f7fff4f7ffdff0ffd4e3ffd43a7d36 +166820237835135d28043e18001200f8fffffff9ff0a0007fff9fffffbfffffefff7f9f6 +ffffffffffffececec1c1c1cfffffffdfdfdfdfdfdf6f6f6ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffefffffcfffff3fcfb8d989cfcfeff +8c798ffff4fffff6ecffeae4ecedffeeffffe2f9ffebffffe9ecff000023edf7ff586261 +fcfffff5f5f5f2f2f2ffffff000000000000000000050505fffffffafafa000000010101 +060606ffffffeaeaeaf9f9f9010101000000000000ffffffffffffffffff000000000000 +000000f0f0f0ffffff040404060606050505fffffffefefeffffff000000050505060606 +fbfbfb0404040202020000000b0b0beaeaeafefefeffffff000000131313000000ffffff +ffffffe4e4e4ffffffffffffffffff000000fffffff6f6f6ffffff000000ffffff000000 +090909000000ffffff000000000000f4f4f4fffffff8f8f8000000030303000000fefefe +e5e5e5030303070707000000020202fffffffafafafafafaffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001dc80334d71c60f31e57bedee7fff4ebe2edf0dfeaefdbeeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0efeae6 +efe8e2f2ece0f1ece6ede7f3777684d8e1e6dff0facbe1ffc9e5ffc7e7ffc4e7fbc2dffd +bad4ef899eafb1c5ce869da5b4d1d7d3ffffb8ebecb4e7eab1e1e5bbdde6c7e2edcbe2f0 +c0dbe6c6e8f1e1ffffdeffffd3e9f4707787bdbbc8757374474641dfded9f5f5ede7e7dd +ecece0f6f4e7e3e1d4efecddefecddefecddefebdff1eae0f1eae0f1eae0f1eae0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddeeebdaf4edddf6eadef2e8dff1eee9e5ece5e0f3ed89a09aedffff +f4ffff020c0b000300f3fffb001003001201dbffe6dcffda2a702a1d742f41a6624cbd7d +2091590b6e42166546001002f0fffffefeff120612180b150700040d080cfbfbfdfcfcfc +f5f5f5ffffff000000fafafaffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffefff9f5f6ffffff768185fbffff978486 +ffecddf8d1a64b2d0bfffcffe5f4ff001d2ce9ffffc7d5e20f1722f8ffff3b4345fafbfd +fffffffefefe020202f5f5f5fffffffafafa000000f3f3f30b0b0bf8f8f8fffffffafafa +000000ffffff000000fffffffffffff8f8f81f1f1fefefef000000fffffff7f7f7ffffff +fffffffafafafffffffcfcfce2e2e2040404f8f8f8000000fffffffafafafdfdfdffffff +000000f6f6f6fbfbfbebebeb0e0e0effffff000000f5f5f5f9f9f9f9f9f9000000ffffff +fbfbfbfffffff7f7f7ffffffffffff000000fdfdfd000000fdfdfdf5f5f50d0d0dfdfdfd +f5f5f5080808fbfbfbf2f2f2222222fafafaf3f3f3fffffffffffff1f1f1090909ffffff +070707f9f9f9f3f3f3ffffff000000f3f3f3ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001dc80334d71c60f31e57bedee7fff4ebe2edf0dfeaefdbeeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0f1eae4f0e7e2 +f3ebe0f4ede5ede5f0757381d4dde2ddeef8e0f6ffdaf6ffcff1ffc6e9fdc4e1ffb7d2ed +8fa6b68c9ca99fa4b76f7689b4cad7d0eef8d2f0fae3fbffdce8f8a8abbcd8d9edf2f9ff +f1ffffe1f7ffd2e6f1636f7db5b2c5afa7b62b27287e7d78e8e8e0f0f0e6eaeae0eeeee2 +f8f6e9e5e3d4efecddefecddefebdfefebdff1eae0f1eae2f1eae2f1eae2efebe0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff3e9ddfbe5d8fbeadaecefdae3f0dce4f5e3dfefe2e3f3e98d9e94f4fffdf0f9f4 +0e0202fff6f8190401f6f2e7001d05d0ffdd1e752483ed914ec778119655008858007554 +007966003c34001310e7fffff6fffffcf6faf9eef2fffbfffef9ff09070cf1f1f3ffffff +f9f9f9000000fffffff2f2f2fcfcfcffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffefdfffbfbfdf7f97f8792fbffff98848dfff0eb +511e03663a31fff4ff101555a2c0dc06292dd1e6dd030f01f0f7f0515652f9fbfaffffff +f7f7f7000000fffffffffffff4f4f40a0a0affffff000000060606070707000000000000 +ffffff101010fffffffbfbfbffffff000000ffffff000000fffffff5f5f5f7f7f7f3f3f3 +ffffff010101040404060606111111fcfcfc040404fffffffffffff2f2f2ffffff0b0b0b +fdfdfdffffffffffff0d0d0df2f2f2000000090909090909000000070707e6e6e6ffffff +f8f8f8fffffff7f7f7fafafafdfdfd060606ffffffffffffffffff030303f1f1f1f9f9f9 +131313f7f7f7fefefe000000f8f8f8ffffff080808000000141414000000fcfcfc080808 +f5f5f5ffffffffffff000000fffffff9f9f9ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001dc80334d71c60f31e57bedee7fff4ebe2edf0dfeaefdbeeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0f2ebe5efe8e2f3ece4 +f2ede9ece6f2727181d4dbe5dfecfdd3e3ffcde3ffcae3ffc7e2fdd2e9ffcadffec7d9ef +919cae908ea4b9b5cc6f7688828f9fdfedfad4ddecdcdbed918d9eb5adc2efecfde4ebfb +bdc9d5636c7ba8aebebdb5ca413948635f5eebebe3eeeee4edede1ecece0e3e4d6eeecdf +f1efe0efecddefecddefebdfefebdfefebe0efebe2f1eae2efebe2efebe0efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f5e8dffee3dcfee8ddebf0dadff3d8e1f7e0dcf1dee5f2e8909d94f5fffbfcfef90b0000 +250b0effeff4060000000904246a4888f5a643c86b008e42007d4600452959f3eb48cfd5 +6ed6e1001217defcfcfbfffdfffefafffdfdfcf8f9ffffff000002fffffff0f0f0fcfcfc +090909efefeffffffff8f8f8ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffefdfff5f1fffdfb7f838cf7f9ff8e7e88fff5f6fff1e1 +471f20ffeefff7f8ff3f556c375450dff0de020b00fefff650514cfffffdf6f6f6ffffff +090909f9f9f9f8f8f8ffffff000000f3f3f30e0e0effffffeeeeeefffffffffffff5f5f5 +000000fbfbfbfffffffbfbfb000000ffffff000000f8f8f8ffffffffffffffffff000000 +fffffff7f7f7ffffff000000f8f8f8000000fffffff9f9f9ffffffffffff000000fafafa +f9f9f9f8f8f8040404ffffff000000fffffff1f1f1fefefefefefefffffffafafafcfcfc +fffffffafafaffffffffffff000000fffffff4f4f4ffffff000000ffffffffffff000000 +ffffffffffff020202ffffff020202f4f4f4fffffffbfbfb000000f8f8f8000000ffffff +fffffffcfcfc030303fefefeffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0ece9e2f5f4f0e2e1dfe9e7ec +f2f0fd605e739e9eb6babedbaeb2d8abb2dcaab3daaab4d8aab3daaab4d8abb4d5aeb3d0 +aeafc47978889597a69093a26b6e7d757887aaa9b983818f8380919998a66062718b8f9b +c4c7d69799a843405158555e7e7b76dddbcff6f4e8e2e0d3f3f1e4f5f3e6e4e2d5f0eee1 +eeecdfeeecdfeeecdfeeecdfeeecdfeeece0efebe0efebe0efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff3e9e0 +fbe2e5fce7e6f0eddce7efd7e6f6dcdff1dbe5f2e8919c98fbfffff7f9f8030000120d11 +00000c050f2a00072f002736098151008e47007f4500512d37ddd944e7f853e0fe003550 +000f19f5fffcfef5ec0f0500f3f3f1f9fffff8fffb000400fafcf9fffffffefefe000000 +fafafafffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff6fefbf27c7c7affffff857f83ede1e3f0e1dceddfde +e8e0ebe7e7f1e5eeebedf7ecd2d8ca0a0c00fffffa4a4a48fffffff1f1f1fefefe000000 +fffffff4f4f4fdfdfd020202ffffff000000fffffffbfbfbffffff000000f4f4f40e0e0e +ffffffffffffededed0e0e0effffff000000fffffffafafafdfdfdf9f9f90e0e0ef7f7f7 +f7f7f7ffffff000000ffffff040404fffffff0f0f0fffffff5f5f5000000fffffff0f0f0 +ffffff020202fefefe000000fffffffbfbfbffffff000000fffffff0f0f0101010ffffff +f8f8f8ffffff000000ffffff000000ffffffffffff000000f9f9f9ffffff000000ffffff +fdfdfd040404ffffff000000fffffffffffffafafa000000f5f5f50c0c0cfbfbfbfbfbfb +fdfdfd000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc7 +0738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeece0ebebe1f0f1ebe8e8e6eeedf2eceaf5 +89889a69677f646382747395737399737399717399717399707497717497717590787a89 +7e7e886b6b756c6c76a4a4aeb0b0baaeaeb8bebec8bebec8adadb7c7c7d1b1b1bb5b5b65 +38384276768078777cd7d7cffcfaedf1efe2dedccff0eee1f3f1e4e8e6d9f3f1e4eeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff2e9e2f8e4e6 +fae8e8f3ebdeeaeed7e8f5dbe1f0dbe5f2e9929b9afcfffffafafcfffffdecf0f3f7ffff +000123001049cfffff4ad5c200885a00926e3ceacf32edda008d7f009c910e837b00120a +f8fffbfffcf5fffdf400020000040001090bf9fefffeffffe3e3e30707070000000a0a0a +ffffffe8e8e8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdf6f5f0fffffa999896f1eff216141908060b0100020b0a08080702 +08080001010001010015140f080705f2f0f5626065ffffffffffffffffffffffff000000 +0f0f0f000000010101f2f2f2ffffff000000000000080808ffffffffffffffffff000000 +0b0b0b000000fffffffafafaffffff000000070707000000ffffffeeeeee070707101010 +000000000000fefefeeeeeee0c0c0c000000000000ffffff020202eeeeeefffffffbfbfb +000000fdfdfdffffff000000000000000000ffffffffffffffffff000000f2f2f2ffffff +000000f6f6f6ffffffffffff000000f6f6f6040404ffffffffffff000000f6f6f6ffffff +030303fdfdfdf3f3f3090909000000010101141414ffffff0000001515150404040b0b0b +fbfbfbfefefefafafaffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc70738db +1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecdfeeefe1edede1ebebe3eaebe6e4e4e6d6d6e0 +87869682809573718971718d71718d70718d70728b6e738970728970738466666e6c6b70 +68676c68676c5b5a5f6261666b6a6f77767b87868b5352574e4d522f2e3352515679787d +e8e7ece2e2e2f8f8eef6f4e7eae8dbeae8dbf6f4e7f2f0e3e9e7daefede0eeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff2e9e0f5e5e5f7e9e6 +f0eddceaeed7e8f5dbe1f0dde6f1eb94999cfefdfffffefffffefbf6f6f4eff3fc020c25 +cad8ff6eafd73de4ea29fff517e4df2fffe500a75c00b74d0bd15a33c765001f00d0ebe2 +fefffffffefff9fff5fbfffffaf3fffff8fff9f6fffffffffefefefffffff1f1f1fcfcfc +fffffff3f3f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffefffffeff7a7885fffdfff6f4fffffdfff8f7fffffffff4f4f2fefffa +fffffbfffffffffefffffdfffffcff454253edecf2fffffff7f7f7f1f1f1fcfcfcefefef +ffffff000000fffffffffffff7f7f7fffffffffffff6f6f6fbfbfbf1f1f1fffffff7f7f7 +fffffffcfcfcfafafafcfcfcefefefffffffffffffedededfffffffdfdfdf8f8f8ffffff +fffffff7f7f7fffffffdfdfdfffffff1f1f1f9f9f9fffffff4f4f4f8f8f8f8f8f8ffffff +f2f2f2e8e8e8fffffffcfcfcfffffffffffff2f2f2fffffffffffffffffffefefef6f6f6 +fffffffffffffbfbfbfffffffbfbfbfffffff2f2f2f2f2f2fffffffffffffffffffcfcfc +fffffffffffffbfbfbffffffffffffedededfafafa000000fefefeffffffe1e1e1ffffff +fafafaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc70738db1c60f3 +1c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddeeeddbedeedceeefe1e9e9dfe3e2deffffffd5d4da +e5e5efeceaf8ebeafaebeafce9ebfae9ebf8e9ebf7e9ebf7e9ecf3f9f9f9e2e3def4f3ef +e7e8e37877736f706b87868274757064635f7879747a7975787974efeeeaeaebe6f5f4f0 +e8e7e2e8e5dce3e1d4ebe9dcf7f5e8f4f2e5eceaddebe9dceeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1eae0f2e7e3f4ebe4efeeda +e9efd5e8f4dce2efdee7f0ed95989dfffefffcf8f9fffff6fffff8feffff00000ec4cdee +33688a006c7d3ce7ee3ddfe200836a00a5571ece5f4beb6d44bd54001800f1fffbfeffff +fefcfffbfffbf5fbfbfaf4fff8effffffdfffffffff2f2f2fffffffffffff5f5f5ffffff +edededffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffefff0f0fc878592dddceac3c1cfc6c6d0d5d4dac2c4c3dfe0dbcccfc8c9cac5 +d0d2d1c7c6cedbdae8bcb8cf5b586bfffefffdfdfdffffffffffff030303020202000000 +fffffffafafafffffff7f7f7fbfbfbfbfbfbfffffffffffffffffffcfcfcfffffff1f1f1 +f9f9f9fffffffafafafffffff0f0f0fafafafdfdfdfffffffffffff5f5f5fffffff5f5f5 +fffffffffffff2f2f2fdfdfdfffffffdfdfdfffffffffffffffffff6f6f6f7f7f7ffffff +fffffff0f0f0fffffff6f6f6f7f7f7fffffffffffff2f2f2f6f6f6ffffffffffffe4e4e4 +fffffffffffffefefefffffffffffffffffff4f4f4fffffff6f6f6fefefef5f5f5ffffff +fafafafefefefffffffefefeffffffffffff020202fffffffffffffffffffffffff5f5f5 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc70738db1c60f31c55bc +e0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefecddecead5f0f0d8f2f1ddf1efe0edebdff7f7efe9e8e4f3f3f3 +eae8ebe9e8ede9e8ede8e9ede8e9ebe8eae9e8eae9e9eae5e5e5ddefefe5eeebe2f4f4ea +dedbd2e6e6dce6e3daefefe5eeebe2f6f6ecece9e0dbdbd1faf7eedfdfd5edeae1f1efe3 +f0eee2ebe9ddf1efe3f1efe3e6e4d8e8e6daf3f1e5f1efe3eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1e8e1f3ede1edefd9e7f0d5 +e8f4dee2eee0e7f0ef95989ffffdfffffefdefebdfffffeffffff40002000c1524000319 +00122200161b000d02000f00001c00001500001300001400000800fffff3fff7f4f0eeef +f8ffffeffefbf9fff8fcfff6f4f6f1fffffffefefefafafafffffff0f0f0ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fafcfbf9fdfe5a5b5f43474a595a5e5357564f514c545a504d5143464d3b4e5243595f53 +4a4c49494d50585864545460fcfbffecececfffffff8f8f8f9f9f9fffffffafafaffffff +ffffffeaeaeafffffffffffff0f0f0f2f2f2fcfcfcfbfbfbfffffffffffffafafaffffff +fefefeffffffeaeaeafffffffffffff1f1f1fffffffffffffffffff7f7f7f5f5f5ffffff +fdfdfdfffffffdfdfdffffffebebebf9f9f9fffffffafafafffffff4f4f4fafafaffffff +eeeeeefffffffffffffffffff6f6f6fdfdfdfffffffffffffffffffffffffffffffafafa +fcfcfcf3f3f3ffffffffffffe6e6e6fffffffffffffffffffdfdfdfffffffffffff0f0f0 +fffffffffffff2f2f2fffffffffffff8f8f8f1f1f1fffffff7f7f7f8f8f8fffffff8f8f8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc70738db1c60f31c55bce0e9ff +f4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecdbf2f0d9edebd2e9e9d1f0efdbf3f1e2e8e6d9eae7dee4e4dcf1eee9 +efeeeaefeee9eeefe9efefe7eef0e5efefe5efefe3e7e5d8faf8e9e6e2d6e5e3d4fbf7eb +faf8e9e6e2d6f7f5e6f3efe3efeddee2ded2edebdcf7f3e7e9e7d8ede9ddebe9dcf4f2e6 +eeece0eeece0eceadeeae8dcf3f1e5f5f3e7e9e7dbeeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff0eadef1eedfedefd9e9eed7eaf3e0 +e3ede4e7eff29498a1fdfefffdfef9ffffedfeffe8fbffeaf2ffedeffefbf1fffff3fbf0 +feffedf9f3d9ffffecfffefffefdffebebfffffcfffff4f0fffdedf0eadafffff6f6ffff +f5ffffeefae4f2fae3fefffafbfbfbfafafafffffff6f6f6fffffff5f5f5ecececffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffdf9fef7 +fcfffaf8fdf9fcfffff0f4f5f4f8f7fcfffdedf2ebfcfff6fcfff3fcfff3fcfff4fafff8 +edf2eefcfffffbfffffefffffffffffcfcfcfbfbfbfffffffffffffcfcfcf9f9f9ffffff +fffffffffffff2f2f2fffffffffffffefefef8f8f8eeeeeefffffffffffff7f7f7fdfdfd +fffffffbfbfbfffffff6f6f6fffffffffffff7f7f7efefefffffffffffffffffffffffff +fbfbfbfffffffcfcfcf4f4f4fffffffffffff9f9f9fffffffffffffffffffffffff1f1f1 +fffffff3f3f3fbfbfbfffffff4f4f4ffffffffffffefefeffefefeffffffffffffffffff +fbfbfbf8f8f8fbfbfbfffffff8f8f8fffffffefefefbfbfbfbfbfbf1f1f1ffffffffffff +e5e5e5fffffffcfcfcf7f7f7fafafafffffffefefefffffffffffff2f2f2ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001cc70738db1c60f31c55bce0e9fff4ebe2 +e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecdbf6f4ddeae8cfe8e6cff0eddaedead9f1eedff1ede1f2f0e4ede9e0ece9e0 +eceadeeaebddeceaddeaebdbecebd9ecebd9f4f1e0f2efdef9f3e5f1eeddf4eee0ebe8d7 +f1ebddedead9e8e2d4f8f5e4eee8daefecdbfffbededead9efe9dbf9f6e7e9e7dae9e7db +ebe9ddefede1f4f2e6f4f2e6eeece0e9e7dbeeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff0eadcf1eeddedefd7eaeed7ebf2e2e5ece5 +e7eef49299a3f1f9fc4b574d79886b33481f758c62839d787692797e9f80739f64335d1e +809b6e808f7c686f818d8fb5f9fafff9f8fffffffff6f8e3feffe4fcffe8f8fff0f1f6ef +fffff8fffefafffffdfafafafffffffffffffcfcfcfdfdfdfffffffefefeffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffbfcfff6f4fced +edf4edf7fdfdfbfffffbfffff6fafffbfffffbfffff7fdfbf3faf3f9fff8fbfffafbfffb +fbfffdf0f4f3edefeefffffffcfcfcf8f8f8fffffffffffff2f2f2fffffff6f6f6ffffff +f2f2f2ffffffffffffffffffefefeffffffffffffffffffff0f0f0fefefeffffffececec +fffffffbfbfbfffffff8f8f8fffffffafafafffffff9f9f9fefefeebebebfffffff7f7f7 +fcfcfcfffffffcfcfcfffffff1f1f1fdfdfdf7f7f7f5f5f5f2f2f2f3f3f3fffffff8f8f8 +fffffffefefefbfbfbfffffffffffff6f6f6fffffff8f8f8ffffffecececedededffffff +fffffff8f8f8fffffffefefef8f8f8fdfdfdfffffff8f8f8ffffffffffffecececffffff +fbfbfbfffffffdfdfdfffffff9f9f9fffffff3f3f3fdfdfdfffffff9f9f9ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001cc70738db1c60f31c55bce0e9fff4ebe2e8ebda +ebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecddf1efdaeae8d3f6f3e0faf7e4e2dfcef8f5e6e6e2d6f4f0e5f0ece1f0ece1f0ece0 +efeddef0eddeefeedcf0eddaf0eddaf2ecdcede7d9f4eee0e9e3d5faf4e6efe9dbf5efe1 +efe9dbf6f0e2f2ecdef2ecdeede7d9f4eee0e9e3d5fbf5e7e8e2d4f1ede2f1efe3efede1 +f0eee2efede1e5e3d7e7e5d9faf8eceeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddf0eadcf3eedbf0eed7ebedd7eef0e2e6ebe5e7eef6 +909aa4f4ffff7e9487405e38769b674269305e8953e6ffe65d8f5c2c681e6ca55e355e34 +e8fff3f5ffff8182a100001cfefcfff9fdfffbfff4eaf7dbf7ffe2feffedfffcf3fffaff +fff9fff6f1f5ffffffeeeeeefffffffefefefffffffbfbfbffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffefffbf2f8ee8b93887b8181 +8a8e998082978182a078789a8687a68485a17f8196858897878b94777c808186897d8383 +85898a888a89f9f9f9fefefefffffff7f7f7fffffffffffffbfbfbffffffffffffffffff +fafafafefefef9f9f9fffffff1f1f1fafafaf4f4f4fffffffffffff6f6f6ffffffffffff +fafafaf8f8f8fffffff4f4f4fffffffafafafffffff8f8f8fffffffffffffbfbfbffffff +f0f0f0fffffff2f2f2fffffffffffffffffffffffffffffffffffff9f9f9fffffff7f7f7 +fffffffcfcfcfafafafbfbfbffffffefefeffffffffbfbfbfffffffffffff7f7f7f4f4f4 +fffffffdfdfdf2f2f2fffffffffffffffffffffffff3f3f3ffffffffffffe8e8e8ffffff +f6f6f6fffffffffffff7f7f7fcfcfcffffffffffffedededffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9 +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdffefaeee4e0d4f5f1e5f0ece0050100f6f2e6f0ece0eeebdc +f0eddceeebda040100f0eddeeeeadeebe7dcfbf7ece6e2d7eee7ddf5eee4efe9dde8e5d6 +fcf6e8040100070100060000090300070000fbf3e8dfd7ccf7efe4eee6dbeee6dbf5ede2 +f7efe4eae2d7e5ddd2faf2e7f1e9dee9e1d6fbf3e8ebe4daf8f4e9e2dfd6ece9e0f4f1e8 +e4e1d8f0ede4f2efe6e8e5dcebe8dfefece3eeebe2f0ede4edeae1e9e6ddece9e0edebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1ebddf1e9dcf4eddbf2edd7eeecd7eff0e2e8eae5e6eff68d9ba4 +eeffff375a46e2ffe22a60226aa6602966215f9c6335713b5c965b396a3b668677f2ffff +fcffff7d7978fffef8060100feffffdee3e6f9fffbfafff2fdfeecfffdf8fff7fffff7ff +f2edf4fffffffefefef6f6f6fffffffefefef3f3f3ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffefffffcffff7e8387bcbfd0c1c2e1 +cccafbbebaf7cec9ffbcb6fcbfbafcc4c1fab8b6e5c7c7ebc9cbe4b7bacdcdd0df7b7e87 +000004f4f4f4fffffffffffffafafafefefefffffffefefefffffff6f6f6ffffffffffff +f8f8f8fdfdfdfffffff6f6f6ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfece8dcede9ddfbf7ebf4f0e4040000ede9ddeae6daefebdfeeeade +e9e5d9110d02e5e1d6efebe2f8f4ebe8e4dbf9f5ecfbf4ecf7f0e6e8e1d7ede7dbede7db +060000fdf7e9ece6dae9e0d7f4ebe40e0500f4ebe4ece3dcfffdf6ebe2dbf1e8e1e8dfd8 +fff6effff7f0e1d8d1f2e9e2fffcf5e2d9d2fbf4ece8e4dbfdfaf1faf7eee5e2d9fcf9f0 +f0ede4edeae1f2efe6f5f2e9e1ded5f1eee5e7e4dbf7f4eb100d04edeae1edebdfefebe0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff1ebdff1e9dcf5ecdbf3edd7f0ebd7f1efe2e8eae5e6eff68a9da3eaffff +dffff2326d37d8ffd417601167b166236b2b539660346c3d76a382e4fffaeefffdf8fef2 +060000100700070000000004fbfffffbfffffefffffffdfafcedf0fff8fffdeefffffdff +fdfdfdfffffffffffffffffff6f6f6fffffffbfbfbffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffefffff7fbfc91959ecfd1e80a093106033c +08024a090252130b5e0d0653201b5e0c09400000270e0e301719320b0e217f818d000004 +ffffffffffffffffffffffffffffffe6e6e6fffffffffffffcfcfcf9f9f9ffffffffffff +fefefefafafaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff3efe3f8f4e8e4e0d4f1ede10f0b000b0700f3efe3e7e3d8eeebe2090600 +030000eae7e0f1eee7eeebe4f3eee8f0ebe5eae5dfdfdbd2f6efe7fdf6ecf2ebe1060000 +f8f1e7efe8e0f8f1ebe3dcd6060000f0e9e3f4ede7e5ded8f2ebe5faf3edfaf3edece5df +ebe4deece5dffbf4eee8e1dbfef7f1e5ded8eae6ddf4f1e8dbd8cff9f6edf2efe6e9e6dd +e4e1d8ebe8dfe8e5dcfffef5eeebe2ebe8dfedeae1030000f0ede4fdfbefefebe0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff1ebdff1e9def4edddf4ecd9f1ead8f2eee2e9eae5e6eff48a9da1e4ffffdbfff0 +d8ffe1145d14d1ffcf1e6c205fab6a286c395d9572dcffefdfffeae9ffecf7fff1fffff6 +fef4f5c4bac205080dedf4fcfafcfff4f0fffff8fffff2fffef2f6fffefbfbfaf8ffffff +f2f2f2fcfcfcfcfcfcfffffff5f5f5fdfdfdffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffefffffcfffd797d80b5b7c60e0d2d130f410a0442 +120b4f120b510d0649e4dfff0b0835fcfbff05051ff9faff00000c999ca3010204fbfbfb +f5f5f5edededfffffffffffffefefef5f5f5fffffffffffffcfcfcf6f6f6fcfcfcffffff +ffffffedededffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfe8e4d8e4e0d4f5f1e5f2eee2040000040000f1ede1fffff3e5e5dd12110c010000 +eae9e4f3f0eb030000f3f0e9e1dcd6050000ede8e2f4ede5f4ede5ded7cf0d0600e1dad2 +f2ebe5f2ebe5f3ebe81d1512e2dad7f6eeebf9f1ee060000060000060000ece4e1fff7f4 +faf2ef080000070000110906eae5dfeeebe4f5f2e9060300060300030000efece3eae7de +100d04e6e3da110e05030000e5e2d9fefbf2030000120f06d5d2c9efebe0efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeeadef3eddff3ecdaf1ead8f4eee2eae9e5e7eef48a9da1e7ffffdffff31c5d25 +69b269237022c4ffc6297034589768285939749f813f7043deffddedffe9fffffafffaff +d6cad6000004fbfffffefefff9f0fffff6ff150216030000fbfcf4fffffdf7f7f7ffffff +0a0a0afafafaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffdfefffa828781cacbd07f80928683a28e8cb17a759e +78769e8682a781809f8a889e8c8e9d81818d7c7f86a3a4a96e6f730c0c0ef6f6f6ffffff +fffffffffffff6f6f6fffffffffffff0f0f0fffffffcfcfcfffffffefefefffffff7f7f7 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f5f1e5f6f2e6f8f4e8ede9dd151105f5f1e5040000e1dfd3080a00d5d6ce040500f2f3eb +efefe7010100fbfbf3f4f1e8030000f5f2e9f6f2e9f0ece3fdf6f00700000e0701060000 +040000050000dcd7d1f3eee8eee9e3040000fffaf4e9e4deeae5df130e08e4dfd9040000 +f9f4eee3ded8efeae4110c06eeebe4030000ebe8e1f0ede6f1eee7050200fffff8030000 +080500e0ddd6eae7e0060300faf7f0030000e7e4ddfffff6efebe0efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdf +ebebdfeeefe1f2eddaf0ebd8f5ede2ece9e4eaedf28d9c9fdafaef487659629d672c6f2a +5a9c55317230dcffe338683e7897753654325f8764eaffefeaf8ebf8f4f3fff9ffd2c1c7 +060500fbfef5fffffafffcfd0d0005fff9fff8fbfff7fffff1f5f6fefefe060606000000 +f5f5f5fffffff6f6f6ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff674786ae0e1d9ebede8fcfcfcfefffff6f6f4fefffa +fffff6fdfff2fffff3edf1e2fffff6fefffaf5f5f3828282000000fffffffcfcfcfafafa +f6f6f6fffffffbfbfbffffffffffffffffffffffffe9e9e9fffffff2f2f2fffffffdfdfd +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc8 +0030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfe3dfd3 +f3efe3f0ece0d5d1c5040000f7f3e7060200f8f6ea000200fafdf2000200eaece1cfd1c6 +0f1106e2e2d8e9e9dd030000fffcf3cdc9c0e8e4dbfdf6f0060000efe8e2f6f1ebe2ddd7 +f7f3ea100b05faf6ede7e2dc050100040000040000080300090500f4efe9040000fdf8f2 +eae6ddece7e1ddd8d2f0ede60b0801030000060300030000030000ebe8e10a0700f4f1ea +ebe8e1f9f6ef030000e1ded7030000efece5eae7deefebe0efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0e9ece1 +ecf0e2efeedcf0ebd8f5ede2ede8e2ecedf1909b9dedfffd4c7459366b37639e5e275e1d +6b9e652c562ee4ffe439562882a27336643dd3fee2f1fffbfcfffffbf0f6cfc3c7000100 +fbfef5fbf7ee080000fff9fbfffbfff1fcfff2fffff7fdfdffffffffffff000000ffffff +edededfffffff3f3f3ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdfffffa7a7b73c6c8bdfffff3ffffefeff3daffffe360673e6f7748 +000800fbffd8ffffe3feffecfffff6fcfcfe8a898f070709fffffffefefeffffff000000 +000000000000000000f0f0f0f1f1f10b0b0b020202050505fffffff6f6f6ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d3 +2064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdffefaeedfdbcf +fefaeefefaee0e0a00e2ded2f0ece0030100e8ecdee2e8da000400eef2e4fbfff1070b00 +d8dacdfbfdef060600dbdbcffffff4f3f1e5e4e0d7040000fffbf5e4dfd9fcf8efe4e2d6 +030000e6e4d8fbf8ef171509dedbd2faf8ecf3f0e7e1dfd3f9f6ed030100f5f2e9f6f4e8 +e2dfd6fffff6e7e4dd030000f2efe8e4e1daefece5fffff8e4e1da090600edeae3e4e1da +f6f3ec0c0902e9e6df080500f4f1eae5e2d9efebe0efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfecece0e6eee3e9f1e4 +ecefdeeeebdaf5ede0efe8e2eeecef929a9ce9fef53c5e45749f7136662c6f9a62365a2c +8fa98c3c5736ebffd42457145a9e652c6d43e3fffaeafffbf0f3facecdd5000205fbffff +fffefb0b0000110000070000000700eefff8f9fffdf0f0f0f6f6f6000000f4f4f4ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffff1eef798959ec6c4c5fefef4f4f6e0ffffdffcffcf101800e7f0ad798241 +030a00fdffdaffffefe3e1e2fffcff858094000005fffffff5f5f5000000f8f8f8ffffff +ffffff020202ffffff000000fffffff8f8f8fbfbfb000000fffffff2f2f2ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f7 +1851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfe5e1d5f8f4e8ece8dc +e8e4d8060200e8e4d8faf6ea030100e8eaddf0f4e6010500e3e7d9e9ebddf4f6e8000200 +010200ebecdef3f4e6d9d7cbefede1f8f4eb040000e5e1d8f3efe6e9e7dbf3f1e5090700 +f4f2e6e9e7db030100fefcf0e9e7dbeeece0030100efede1090700e3e1d5f0eee2f8f6ea +030100f2efe6090600e4e1daf1eee5e9e6df0b0800d9d6cf080500ece9e2faf7eeebe8e1 +030000f1eee70e0b02e0ddd6eeebe2efebe0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfecece0e9ece1eaf0e4ecefde +edebdcf4eee2efe8e2eeecef95999cf7fffff2fff6e6ffe2ebffde829872f4ffe7edf8e7 +7e90763c5f276b9e5c2968335f9973001200e6fdf7fbffffbebeca010510fcfffffaf6f7 +0a0000fffbf4fffceff8fff3000700fbfffbf6f6f6ffffff000000fbfbfbfffffff6f6f6 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffff858587c8c8c8f8f7f2ffffedffffe36b6e43ebf0b889904d89904d010800 +767a55feffebfffffdfffcff868398040309f1f1f1ffffff060606f7f7f7f6f6f6ffffff +000000f8f8f8050505fefefeffffffffffff010101f5f5f5ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001ec90031d42165f81952b9 +e3ecfff0e7def0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdff7f5e8e7e5d8eeecdff1efe2 +030100f2f0e3fcfaede6e4d7edede1eaeade010100edede1f7f7ebdfdfd3010100f7f5e9 +e5e3d7f4f2e6eeece0dfddd1fbf9ed090700e6e4d8f3f1e5f0eee2e2e0d40d0b00f6f4e8 +e4e2d6eae8dc0a0800030100030100e7e5d9efede1efede1030100030100070500eeece0 +eceadeeeece0090600030100030000edebdfedeae1060400f1eee5eeece0e6e3da030100 +f0ede4f4f2e6040100eae8dcefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeadef1ede1f0ece0eeeadf +f2ede7ece8e5eeecef98979cfbfcfffefffffaf9f5fbf8f1878078fff9f3fffffafcfff4 +f4ffea000d00eeffefedfff0000800fcfefdfdf8fed5cdd806030cfcf9fffffdff060002 +fffbfdfffcfbfef9f6010000fffffdfafafaffffff000000fffffffcfcfcf9f9f9ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefff8 +feffec878f77c5c8bffffffdfffff8f8f5ecfffff6060100d0cf9feef1bc050700eff2d5 +ffffe8f9feeafcffff7b7e830c0c0eefefefffffff000000f3f3f3ffffffffffff000000 +f8f8f8050505fefefeffffffffffff010101f5f5f5ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001ec90031d42165f81952b9e3ecff +f0e7def0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfe4e2d5f5f3e6f5f3e6e3e1d4f9f7ea +dfddd0e6e4d7eeecdfe6e4d8fffef2eae8dce6e4d8eceadefffdf1030100ebe9ddf9f7eb +eeece0f5f3e7e5e3d7eae8dceeece0ebe9ddefede1e8e6dafffff4e9e7dbe8e6dafffef2 +dfddd1f6f4e8f0eee2f2f0e4fffef2edebdfeae8dcf7f5e9f5f3e7e1dfd3efede1f0eee2 +f1efe3e5e3d7fffff4eae8dce4e2d6fffef2e6e4d8e8e6daf1efe3eeece0f2f0e4eeece0 +e6e4d8e8e6daeeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff1ebddf1e9dcf4ecdff2ece0eeeae1f1eee9 +eae9e7ededef98979cfbfafffffefffaf5fbfffdff969094fffdfff9f3f3f7f8f3e5f1e5 +f7fff80003000a0c07030000fffdfffef8fcbcb6ba010004f7f6fbfeffff000004f5f5f7 +fcfafdfffdff030002fffeffffffffffffff080808ffffffefefefffffffeaeaeaffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefff8f6fee6 +7e866ecbcdc8e9e8edfffdfefffdfffff9fffffcfd060300040500ffffedfffff3ffffea +f0f5e1fcffff80838c000004f7f7f7ffffff000000fffffffdfdfdededed131313ffffff +000000fffffff8f8f8fbfbfb000000fffffff2f2f2ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001ec90031d42165f81952b9e3ecfff0e7de +f0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdff4f2e5efede0edebdef5f3e6f3f1e4eeecdf +fffff2efede0f4f2e6e4e2d6fbf9ededebdf030100050300dddbcff8f6eadddbcfe8e6da +f9f7ebf3f1e5e5e3d7f8f6eae7e5d9f1efe3e4e2d6eeece0e6e4d8f7f5e9e5e3d7f1efe3 +f9f7ebe4e2d6ebe9dde0ded2efede1eceadeebe9dde8e6daf7f5e9eceadeebe9dddbd9cd +f9f7ebeceadeeeece0e2e0d4efede1f3f1e5f0eee2efede1f6f4e8eceadeeeece0e5e3d7 +f1efe3f5f3e7efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefecddf0eadcf3eddff2ece0eeeae1efeee9e8eae7 +eaeeef95999cf5f8fdf9fffff2fffff0ffff607973f0fffdf8fefafefffffcffff000104 +fefffff2f0f30c0809fefafbf6f5f3d3d5d2000200f8fffdecfbf6f4ffff000603000505 +000405f8fffffcfffffbfbfb0000000000000b0b0bffffffeeeeeeffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffff8b8c90 +d0d0dcfefefffffefffffdfff0ebfff5f2fbffffe6feffe2fcfafbfffefff7faefeceee9 +fefcff7a77940f0d18fffffffffffff8f8f8090909000000020202000000f0f0f0f1f1f1 +0b0b0b020202050505fffffff6f6f6ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2 +e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeceaddebe9dceae8dbf2f0e3e6e4d7eeecdfe8e6d9 +e9e7dae3e1d5f2f0e4e5e3d7f8f6eaf4f2e6f8f6eaf6f4e8edebdfefede1f3f1e5e2e0d4 +f3f1e5fffef2d2d0c4f6f4e8e6e4d8fefcf0e3e1d5e7e5d9fdfbefedebdff1efe3eceade +eae8dcf4f2e6edebdfebe9ddfdfbefe1dfd3f3f1e5f1efe3eae8dcfffdf1f0eee2edebdf +e5e3d7e8e6dafbf9ede5e3d7eeece0e9e7dbefede1e8e6dae9e7dbfdfbefeeece0fefcf0 +e0ded2efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddf0eadaf3edddf2ece0edeae1eeefe9e6ebe7e9efef +929a9cf9fffff7ffffe5f9f8edffff75948cedfffff0fffaf6fcfcf9f7ff0802100c0612 +09020a050003fffefd010000ced1ca000400f7fffaecfdf3f2fffdf1fffff2fffff2ffff +f7fffff0f4f5fffffffffffffffffffcfcfcfffffffffffff7f7f7ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdff85848c7b7a8a +81808e7d7e82898a8e898b988d9095757e63828b707d7d85807f8d8385848f91906e6a81 +9692ab000007fffffffdfdfdfffffffefefef5f5f5fefefe000000ffffffffffffffffff +e9e9e9fffffff2f2f2fffffffdfdfdffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2e9eeda +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfe8e6d9fdfbeee6e4d7f6f4e7e8e6d9efede0fffdf0e6e4d7 +faf8eceeece0e5e3d7e9e7dbdddbcff0eee2f4f2e6dad8ccf3f1e5f5f3e7e9e7dbedebdf +e3e1d5fffff4eeece0ebe9dde2e0d4eceadefefcf0e3e1d5e2e0d4e8e6daedebdff7f5e9 +eceadeeae8dcf6f4e8e6e4d8f7f5e9e6e4d8f3f1e5f1efe3e1dfd3f5f3e7ebe9ddfefcf0 +efede1f3f1e5e1dfd3f2f0e4eeece0eae8dcf1efe3f6f4e8d6d4c8f8f6eae4e2d6ebe9dd +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1ebddf1eadaf3edddefede0eaecdfebf0e9e3ece7e6f0ef919b9c +e9f3f5f8fffff8fffff2fdff7b8787c0cfccbfd0cac2cccddfd9e7b6a7badaccdddcd0da +bdb2b8bfb7b5050000c4c4ba030500ebf1e5fbfffaeef7f2f9fffff9ffffe6edf5f9feff +feffffebebebfffffffffffffffffff4f4f4ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffafffff1010100000005111119 +00020000040000040000050000080007150001090b00000b06070c010100010000010000 +141412e5e5e5fffffff1f1f1101010010101000000fffffff0f0f0fffffffcfcfcffffff +fefefefffffff7f7f7ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2e9eedaeeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdff7f5e8e9e7daf0eee10301000301000301000b0900efede0ebe9dd +e9e7dbfbf9ede2e0d4fffff4f3f1e5e0ded2fffff4dfddd1edebdff9f7ebf1efe3d5d3c7 +f7f5e9e0ded2f3f1e5e8e6dafffff3e6e4d8f6f4e8e9e7dbfffff4dcdacee3e1d5f1efe3 +eae8dce6e4d8d6d4c8fffff4f2f0e4eeece0e7e5d9e6e4d8fbf9ede5e3d7dedcd0eae8dc +f0eee2fbf9ede8e6daf8f6eae8e6daedebdfe8e6dafcfaeee5e3d7efede1fffef2efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff1ebddf2e9daf4edddedeedee7eddfeaf1e9e3ece7e6f0ef919b9df8ffff +f8fdfffff8fffffaff90838d0e090f000402000806030004180b14070002060000130e0b +06030018150e010100010100fffff8f9f8f3fbfaf8f4f2f5fefcfffffdfffffdffffffff +fafafaffffffffffffeeeeeefffffffbfbfbffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff8ffffebfffeeaffffffebecf1f9fff8 +f7fff4f5fff8f0fff4f4fff6f2fff5f7fffff1f8fffefdfffffefffefcedffffedf6f5f0 +fffffffcfcfcf9f9f9fefefefdfdfdfffffffbfbfbfffffffffffffcfcfcf6f6f6fcfcfc +ffffffffffffedededffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2e9eedaeeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfe0ded1f4f2e5f1efe2030100fbf9ecf3f1e4eae8db060400e9e7dbf3f1e5 +edebdfefede1f0eee2dbd9cdf1efe3dddbcffaf8ececeadeebe9ddeeece0fefcf0ebe9dd +efede1e9e7dbf1efe3edebdfe2e0d4e9e7dbedebdfe8e6daeeece0fbf9ede8e6daf6f4e8 +f2f0e4f6f4e8e7e5d9ebe9dde6e4d8f5f3e7f0eee2ebe9ddedebdff6f4e8f7f5e9dfddd1 +ebe9ddf2f0e4e1dfd3161408f7f5e9dddbcff4f2e6f9f7ebe0ded2e5e3d7efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff1ebddf5e7daf5ecddebefdee4efdfe8f2e9e3ece7e7f0ef929a9deaeff5fffcff +fff2ffffe1f8ffefffffe1f0feffffe7f4ebfdfff2ffffefffffeffcffeffbfff4f7fff2 +e8ede6fdfffaf7f6f4fef8f8fff6f9fff9fdfffbfffff9fdf4e5eafffbfffefafbf0f0f0 +fffffff9f9f9ffffffffffffffffffefefefffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffafffff1fefcf0edecf2fcfffff8fff8e5f7e7 +f1fffdecfffff0ffffedfffff1fffff0f9fefcfcffe9e6fbfbf8efffffeff7f6f1ffffff +fbfbfbfffffffffffffffffff7f7f7fffffffffffffcfcfcf9f9f9fffffffffffffefefe +fafafaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2e9eedaeeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdff5f3e6f0eee1e8e6d9080600eeecdff0eee1e3e1d4f7f5e8060400eeece0e7e5d9 +eceadef5f3e7edebdffaf8ececeadef2f0e4e7e5d9f4f2e6e8e6dae8e6daf9f7ebe7e5d9 +f2f0e4eeece0f2f0e4edebdffbf9ede8e6dae9e7dbf5f3e7e6e4d8f2f0e4e6e4d8eeece0 +f0eee2ebe9ddedebdff5f3e7e9e7dbedebdfeeece0eeece0f0eee2e2e0d4faf8ecefede1 +e9e7dbf2f0e4030100dfddd1fdfbefe6e4d8edebdfebe9ddf5f3e7efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f1ebddf4e8daf5ecddedeedee6eedfeaf1e9e3ece7e7f0ef94999dfefefffff6fffff4ff +fff2ffffe3f817000b050308000400000700000800000c00000a00000800f5fff3eefef3 +f8fffffcfffff9f6fdfffbfff9eef6f9edf1fffbfbfffcf8fffbf8fffffdffffffffffff +fdfdfdfffffff9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff6fefaf7fffcfff8faffe6f1fff1ffffb5c5f9 +b5c4ffb3c0ffbecaffbac5fbf5fcfff2f1fffefbfffffdfff9f6effffffdf7f7f7ffffff +fffffff7f7f7fffffffefefefefefefffffff6f6f6fffffffffffff8f8f8fdfdfdffffff +f6f6f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +f4f2e5efede0e5e3d6080600e3e1d4fcfaeddedccfedebde030100fefcf0ebe9dde5e3d7 +030100040200030100eeece0f4f2e6edebdf030100131105030100eceadefaf8ec030100 +ebe9ddfaf8ece8e6da030100f3f1e5030100030100040200e9e7db0705000d0b00ebe9dd +dfddd1fffef2030100060400030100e7e5d9fbf9ed040200eae8dc050300030100efede1 +eeece00c0a00030100f1efe3f6f4e8040200030100f6f4e8efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdd +f0eadaf4edddf2ecdeedebdfebf0e9e3ece7e9eef197989dfffbfffffbfff7f9fff4fdff +f4ffff000305fffdfffffeeeeaeaaaffffb5e1efa4f2ffc9000d00000e00f0fffbe8fafa +f3fdfff9fffff5f5fffffefffbf9faf7f8f0fafeedfcfff3fdfffafefefeffffffffffff +ebebebfefefefdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffdfffffbfffefff0effff8f9ffbabcffabadff100eb90704c3 +0b09c20b08b702009fc7c2ffc5c4fffcfafffaf5fffffcfffcfbfffffffffffffff2f2f2 +fffffffcfcfcfffffff5f5f5fafafaf8f8f8fffffffffffff8f8f8fffffffffffff6f6f6 +fffffffdfdfdfffffffffffffbfbfbfffffff7f7f7fcfcfcfafafaf4f4f4ffffffffffff +f6f6f6fffffffffffffafafafbfbfbf6f6f6fffffffffffffafafaf5f5f5fffffff6f6f6 +f6f6f6fffffff5f5f5fafafafffffffffffff6f6f6fbfbfbf4f4f4fffffff8f8f8f7f7f7 +fffffffdfdfdfffffffbfbfbfffffffefefefffffffffffff7f7f7fbfbfbfffffffcfcfc +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc7 +0738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfe9e7da +dfddd0f3f1e4090700eae8dbf8f6e9fcfaede9e7da030100dddbcfedebdf0d0b00fdfbef +e5e3d7e7e5d90b0900e8e6da090700e8e6dae5e3d7fbf9ed030100edebdf030100e9e7db +faf8ecf1efe3060400dfddd1100e02f3f1e5f7f5e9090700f4f2e6e4e2d6050300f4f2e6 +050300e3e1d5e9e7dbf7f5e9030100dfddd10301000b0900e3e1d5f5f3e7030100f1efe3 +030100f1efe3e2e0d4040200f3f1e5e0ded2030100efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddebecda +f1eeddf7e9def4e7dfedf0e9e3ece7e9eef198979ffff9ffe8e8f4001614001d11001c09 +002215000007fff9ecffffb6e6dd78ffffb0f5fdb4000a00f1ffe6021309f2fffff5fcff +fbfefffffcfffffdfffefffdfcfff4f8ffedf4ffeaf9fcf5fffffff7f7f7fdfdfdffffff +fffffff6f6f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdf8f9f4fcfefff9f8ffc7c3ff0e0c89201cb70000bb0f0cd90000cb +110dd40b04b41712a4160f7faba7f4fcf9fff1eefffcfbfffffffff7f7f7fffffff9f9f9 +fafafafcfcfcfffffffffffffffffffafafaf6f6f6ffffffecececfffffffffffff7f7f7 +ffffffe4e4e4fffffff6f6f6fffffff0f0f0fffffffffffffffffff0f0f0fefefeffffff +ecececfffffffbfbfbfcfcfcffffffeaeaeafffffffbfbfbfffffffbfbfbffffffffffff +fbfbfbfffffffbfbfbffffffeaeaeafffffffcfcfcfffffffffffff3f3f3ffffffffffff +f6f6f6fcfcfcffffffefefeffffffff1f1f1ffffffffffffffffffefefefffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc70738db +1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdff6f4e7f3f1e4 +eceadd030100dfddd0e6e4d7e1dfd2f8f6e9030100fffff4eae8dc030100eceadee8e6da +f3f1e5030100fffef2030100dedcd0fffff4eceaded7d5c9fffdf1090700fcfaeed2d0c4 +f9f7eb030100ebe9dd030100ebe9dde1dfd3030100dfddd1f7f5e9080600e6e4d8030100 +0301000e0c00030100030100f3f1e50a0800f1efe3eeece0e8e6da121004e5e3d718160a +e5e3d7e9e7dbf4f2e60c0a00fdfbefe5e3d7efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddde6f0d8eef0db +fee5defce3dfeeefe9e2ede7e7eff199969ff8e3f4f5ffff001f0c47ddb7009d6f4fcfae +00020972413a673300fffc98f3cf77fffeb8140a00fdf9def6f5f0080510fffafffff7ff +fff2fffff7fffffefdecf0e2f9ffedf9ffedfefffafefefefafafafffffff6f6f6eaeaea +fdfdfdf9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffefffbfbfff3f2f7ffbab6ff02008315129d050889edf5ffe2ebffebeeffedefff +eef7ff1115790900a411039ecdccfffafefff9fafefffffffbfbfbfffffff5f5f5ffffff +ffffffededede7e7e7fcfcfcfffffffffffffcfcfcfffffffcfcfcfffffffffffffefefe +fffffffffffffffffff6f6f6ffffffe9e9e9eeeeeefffffffffffff7f7f7fdfdfdffffff +fbfbfbfffffffffffff1f1f1fffffff7f7f7fefefefffffff8f8f8fbfbfbfbfbfbf8f8f8 +fffffffefefef7f7f7fffffff1f1f1fffffffbfbfbecececfffffffffffff9f9f9ffffff +f4f4f4f2f2f2fffffffffffffffffff7f7f7efefeffafafafffffff3f3f3ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc70738db1c60f3 +1c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfe1dfd2f7f5e8eae8db +040200fdfbeef3f1e4fffdf0d9d7ca0b0900e3e1d5e7e5d9100e02e9e7dbf8f6eaefede1 +0a0800dedcd0080600f5f3e7ebe9ddedebdff6f4e8ebe9dd030100dcdacefefcf0e4e2d6 +030100f1efe30d0b00f7f5e9f1efe30d0b00e5e3d7f1efe3060400e9e7db090700f1efe3 +e8e6daedebdff7f5e9f0eee2030100f4f2e6faf8ecdcdace030100eeece0030100ebe9dd +fffff4dddbcfe1dfd3060400f3f1e5efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddde4f0d8eef0dbffe4de +fee2dfeeefe9dfeee7e7eff199969ffff2fff0ffff00260c0092622efdc5009871000f16 +ffe8e5fff0b0ffd57afffaaafbdc99120000140d000600000d060d0f0013fff6fffff6ff +fff8fffffbfdfffff6f2f7e3fcfff1fafdf6fffffff5f5f5fffffff5f5f5fffffffefefe +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fcfffbf2fef0f5feffada7ff3126dc0e06b3dcdeffeef9ff0f1e6106107200086fe6eeff +e2e3ff2011e01b0ad2afaefff8fdfffcffffe7e7e7fafafa000000fefefeffffffffffff +ffffffffffffffffffecececfffffffffffff2f2f2fcfcfcf6f6f6f9f9f9fffffffefefe +edededfffffffffffff6f6f6fffffffffffffffffffafafafffffffefefeffffffeaeaea +ffffffefefeffffffffafafaf5f5f5fffffff2f2f2fffffffffffffffffffffffff2f2f2 +fffffff5f5f5fafafaffffffefefeffdfdfdfffffffbfbfb000000fffffff0f0f0ffffff +fffffffbfbfbfafafafdfdfdfefefefffffffafafaf4f4f4ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc70738db1c60f31c55bc +e0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefede0fbf9ecefede0030100 +e6e4d7e2e0d3f2f0e3050300e8e6daeeece0fcfaee030100e5e3d7f5f3e7dcdace060400 +eeece00a0800f1efe3efede1e7e5d9151307d0cec2151307faf8ecf7f5e9030100171509 +dbd9cd030100e1dfd3f1efe3030100f4f2e6fffdf1030100f0eee2030100e8e6daf6f4e8 +fffef2030100fdfbef030100eae8dcedebdffffdf1070500e5e3d70f0d01eae8dcf4f2e6 +0d0b00f5f3e7eae8dc030100efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddde6f0d8eef0dbfee6dcfbe3df +ebf0e9deefe7e6f0f198979ffff7ffedfeff0024104cf1c7009b684edbb800050bfff1f1 +ffe5b2ffeda1643f00ffffc3fbf5c5f5f9d8f6fbe7eaebe5070004fff8ffffeffffff0ff +ffecf30d0000060000fffff6fbfaf6fefefeffffff080808ffffffeeeeeefcfcfcf7f7f7 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffff +f5ffffb6c1f9160ebb0000d31001e2160ec4f0f5fff0fcffeffdfff0fafff0efff0f06c3 +0b00df0900cf0c0a91c5c7ffededffffffffffffff0a0a0afdfdfdf2f2f2ffffffeeeeee +fbfbfbfcfcfcffffffe9e9e9fffffffffffff9f9f9fffffffffffffffffff1f1f1ffffff +ffffffefefeffcfcfcfffffffcfcfcfffffff1f1f1f9f9f9fffffffafafafffffff0f0f0 +fffffffcfcfcfffffffffffff6f6f6fffffffffffffcfcfcfcfcfcfffffffffffff6f6f6 +fffffffffffffcfcfcfffffffffffff4f4f4ffffff040404fafafaffffffeeeeeefbfbfb +fffffffafafafbfbfbfdfdfdf5f5f5f9f9f9fffffffbfbfbffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc70738db1c60f31c55bce0e9ff +f4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdffcfaedd5d3c6f5f3e6030100121003 +090700030100f1efe2f3f1e5edebdfe1dfd3efede10b09000f0d01030100efede1faf8ec +efede1030100080600050300efede1fefcf0e0ded2030100030100e4e2d6030100f5f3e7 +121004e9e7dbeceade030100f6f4e8e0ded20b0900fdfbefe5e3d7030100060400030100 +dddbcfe4e2d6090700faf8ecefede1e1dfd3050300f2f0e4fbf9ed030100eeece0e0ded2 +0c0a00030100fcfaeeefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeecddeaedd8f0efdbfae8dcf5e7dee8f2e9 +deefe7e5f0f29598a1f8eafbeff9ff00241b087c6553daba1c836e00050cfff7f6fff4c8 +ffffbf565616f6ffc8e1ffc9d9ffd0eaffeaeefff3000500fffffdf3e7ebfff8ff150208 +faebf0fffcfdfefaf9fffeffffffff000000070707f4f4f4ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffe4f6fa +c9d7ff0f09c10000d3200eff1508d1030478f1fbff142046dbe5ff110e992218db0300dc +1d11ed1a19b5aaadfff4f5fffffffff8f8f8000000fffffff4f4f4fffffffefefeffffff +f7f7f7f9f9f9ffffffecececfdfdfdfcfcfcfcfcfcfafafafffffffdfdfdfffffffcfcfc +fffffffffffff6f6f6fffffff7f7f7fffffffcfcfcfafafafcfcfcefefeffffffffcfcfc +f6f6f6fffffffafafafffffffffffffbfbfbf9f9f9f9f9f9fbfbfbfffffffffffffafafa +fffffff6f6f6fcfcfcf3f3f3fcfcfcffffff030303f8f8f8ffffffffffffffffffffffff +fbfbfbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001cc70738db1c60f31c55bce0e9fff4ebe2 +e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeae8dbeae8dbf1efe2fffff3d6d4c7f3f1e4 +eceadde7e5d8f2f0e4e8e6daf8f6eaf3f1e5d7d5c9fbf9ede5e3d7f7f5e9e1dfd3e5e3d7 +f4f2e6f4f2e6e4e2d6f7f5e9eeece0efede1f0eee2eeece0f1efe3efede1eceadeeae8dc +fffef2e8e6daf4f2e6f0eee2f3f1e5dcdacef8f6eae2e0d4fffff4dddbcfe5e3d7fffff4 +edebdff9f7ebe7e5d9e1dfd3fbf9edeae8dcf5f3e7dfddd1ebe9ddf3f1e5f3f1e5eae8dc +eceadee9e7dbefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefecddf0ebd8f3eedbf2ecdceaecdee6f3e9dcf0e7 +e3f1f29498a1fffbfffffcff00040e000e13000d0c000f11000813fafffbebffdee4ffd6 +c9ffc638884314712b207f3d00561c003403001400ebfff3f7fff8020401eeeceffffeff +f6f6fef5f8fdfeffffffffffffffff000000f7f7f7ffffffffffffefefefffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffff9fffff0ffffacbff9 +0506b01409eb0d00dd1006bff2f2fff2f8ff161968f2f7fff1f6ff0000771a0fe70000cf +0306a3c5ccfff9fcffffffffffffff000000ffffffffffff0000000d0d0d000000f8f8f8 +fffffffefefefffffffbfbfbfffffffbfbfbfffffffefefe000000080808000000000000 +fffffff8f8f80000000b0b0b000000fffffffafafaffffff000000070707000000ffffff +fbfbfbf4f4f40c0c0c000000000000ffffffffffff0000000000000c0c0cf4f4f4fbfbfb +ffffff000000101010000000f8f8f80101010000000101010d0d0df1f1f1fffffff2f2f2 +000000000000000000ffffffe9e9e9fdfdfdffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001cc70837db1c60f31e55bce0e9fff4ebe2e8ebda +ebf0dceeeddbefebdfefeae4f1eae4f5e8dff5e9dbefebdfeceddfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeceaddf8f6e9f1efe2dbd9ccfaf8ebf0eee1e8e6d9 +f9f7eaf3f5e8eaecdfdfe1d4ebeddff6f7e9e5e3d6f7f1e5eee5dcf5ece5fdf6f0e8e3df +e4e1dcfbf8f1e4e4dae8e9dbf5f3e6f3ece4ece5dfeeede8f5f6f0e5e6dee9e9ddf4f1e2 +f4eddbefe6d7ede3d7f2ebe1fbf7eee9e5dcf6efe5eae0d4faf1e2f4ede3eae7def3efe4 +e6e4d8f8f4e9f3f1e5ece8ddf0eee1e9e5d9f9f7eaeeeadef2f0e4ece8ddebe9ddf9f7eb +e6e4d8efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff1ebdff4e7def5ebdfefeddee7eedee4f4e7deefe7e3f1f1 +92999ffcf9fff9eefc100611030007fefeff00000b00010eedffffd6ffe6146f29167c3a +45b97a33b77e139b6900784c0e7852001700e1ffeaedfbea050d02000302010a0f00020b +f8fffff9fdfffefefeffffff000000fffffffffffff5f5f5ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffff9fffff0ffffb5c8ff0708b2 +140ae70700cdf1e9ff0d0f7ef1f7ffebeefff1f5ffeaf5ffeef6ff140dd50d07e30205a8 +b7bffff9fcffedededffffff040404fffffffdfdfdfffffff6f6f6ffffff080808f7f7f7 +fffffffffffff2f2f2fffffffffffffefefe000000fffffffafafafafafa040404fdfdfd +040404ffffffffffffededed0e0e0effffff000000fffffffafafafefefe000000ffffff +000000f9f9f9fffffffdfdfdfffffffffffffdfdfdfffffff9f9f9000000ffffff000000 +fefefef9f9f9ffffffffffff000000fffffffcfcfcfcfcfc060606f7f7f7090909ffffff +f1f1f1ffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001bc70837db1c60f31e55bce0e9fff4ebe2e8ebdaebf0dc +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeeecdfebeddfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddf +e7efe0e4f1e0e4f1e0e7f0ddebeedbefecd9f5e9dbf9e6dff9e5e6f8e4edf3e5f2efe7f2 +eceaedebece6ebeeddefecddf9e7e5fbebeeedecf2dee6e9dee9e5ebf1e5f6eed7f6e5c9 +ffe7cfffe9d9f9eae5f1e5e5efe5e4f6e7e0fee7d5fce6d1f8ebe2f1ece6f4ede5f5f1e6 +f5eee4efebdfefe9ddefecddf1ebddefecddf1ebddefebdff1ebdfefebdfefebe0efebe0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff2e9e2f7e4e6fae7e9f2ebe1eaecdee8f3e3e1eee4e6f0f194999f +fffdfffffdff060000fffff8000200ecf5fa021222dcfffd156c2785f69c4abf7b038559 +008878007a7a007f85003d45000913fffdfffff9f3040000f8fffde8fcfbf0ffff00080e +fcffffe9e9e9ffffff030303f1f1f1fffffffffffff2f2f2ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffbffffefffffbccbff0f09c30200dd +0d05cceeecffedf3ff0f1978070e8019228bebfcffeaf6ff0000b90e09df0102b2bcbeff +f7f9fffdfdfdfafafa070707fcfcfcffffff000000000000000000010101fffffff8f8f8 +fffffffffffffafafafbfbfbffffff060606fffffff9f9f9fefefe0e0e0eeeeeee020202 +030303000000060606000000f5f5f5030303fffffff9f9f9fdfdfd090909ffffff000000 +fdfdfdffffffeaeaeaffffffffffff0000000000000101010c0c0cfbfbfb000000fefefe +fffffffffffff4f4f4040404f5f5f5fffffff6f6f60a0a0afdfdfd000000080808000000 +0000000a0a0afafafaffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0eaede2 +e7efe2e7efe0e7f0ddebeed9efedd8f5e9d9f8e7ddf9e5e6f6e5edf3e5f4efe7f4eee9ed +eeebe4efecd9f5ead8f7ded7f8e2e4eeedf2e9f4f6e7f6f3ebf3e6f5eed4fdeaccf9ddc7 +ffe6d9fceeeef3ecf3ece7edefe5e3ffebd8fff2ddefe2d9eee9e3f1eae4ebe7dcede6dc +f2ece0f5efe1f5efe1f1ebdbf1ebdbf1ebddf1ebddf1ebdff1ebdfefebe0efebe0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff2e9e2f7e4eafae7ebf3eae3ebecdeeaf2e3e2eee4e7eff195989ffffcff +fffdff040000040200f6fbf505101600031933646196fcba4dcf77007030058d69004743 +29d3e441edff51cde700031efff5fffff5f5120500fbfffdf4ffffe4f0f0000709fafbfd +fffffff6f6f6080808fffffffffffff6f6f6ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffcfffff5ffffabb4ed0c05ad1c0ee90c03ce +0805b6ebeeffe0e8ffeaf2ffd0d9ffeaf5ff0a11960502c11d1add0b0ca5babefffbfbff +ffffffffffff080808fefefe000000fffffffefefeffffff000000fffffffdfdfdf2f2f2 +ffffffe7e7e7fffffffefefe000000fffffffffffff5f5f5000000ffffff000000ffffff +f0f0f0f8f8f8ffffffffffff000000fffffffffffffefefe000000fcfcfc080808fcfcfc +eeeeeeffffffffffff000000fffffff6f6f6f3f3f3000000fbfbfb191919f4f4f4fafafa +ffffffffffff060606fffffffefefeffffff000000f8f8f80e0e0ef3f3f3fdfdfdffffff +fcfcfcfafafaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1eae0f3e8e6f3e8e6 +f1eae2eeecdfeceed9eceed8efedd8efecdbefebe2efeae7efe9ebefe9ebf2e8e6f5e9dd +f8e9d4fce8cfffead4ffe8d6f0ece1e7f1e9e0ede4dee6d9eae5d1f9ead5ffecdef3e4df +e6e3ece5ebf9eaf4fee9f1f3e8e6d7e3decbece8dff3f0e9f5f0eaeceadeebe7dcf1ede1 +f3f0e1eeebdcefecdbefecdbefecddefecddf1ebdff1ebdff1eae0f1eae0efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff2e9e2f7e4e6f8e8e8f2ece0eaeddceaf3e2e2eee4e7eff29498a1fffdfffffcff +030000010000000104000210011132002c3a00653900833f0b9258003e1448e5d44bf1f1 +33dae2004957000419fff5fffff1f80d0000fbf6faf9f9f9fffef6060000f5f4f0ffffff +fefefe000000fffffff3f3f3fffffff5f5f5ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffcffffeef7fcf5fcffd6d2ff00009e0a00d70a00e2 +1008d91412cfeaecff1719c60000b41911e20500cb00009dbfc4ffe1e8fffafcffffffff +f5f5f5000000ffffff040404f7f7f7fffffffdfdfd000000f9f9f9ffffffffffffffffff +fffffff9f9f9ffffff000000fafafaf8f8f8fafafa0b0b0bffffff000000f6f6f6ffffff +ffffff000000ffffff000000f8f8f8ffffffffffff000000ffffff0c0c0cf3f3f3ffffff +f0f0f0f3f3f3000000f2f2f2ffffffffffff0f0f0ffafafa000000ffffffffffffefefef +ffffff000000fcfcfcf2f2f2ffffff030303ffffff000000fffffffbfbfbf1f1f1000000 +fffffff7f7f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff2e9e2f9e5e7fae4e7f8e6e4 +f3e9dff1ecd9eeedd8eceed8ebeedbebeddfebede2eeebe4f1eae4f3e9dff8e8d8fae8d2 +fde8cbffe9c9f9eacbebedd8e3f0dfe2f2e5e8f4e6f6f5e1fdf5e2f8eadff3eae5e9eaef +dee7f0d5e4e9d6e5deeaf2dbfafee7eeeee2eeeee6eeeee6efefe3f0f0e4f1efe2edebdc +eae7d8efecdbefecdbefecddefecddf1ebdff1ebdff1eae0f1eae0efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f1eae0f5e6e3f7eae4f0eddceaedd8eaf3e2e2eee4e7eef49498a4f6f5fffffdfffaf8f9 +fefffff6fdff00091d000f36ceffff54dcc8009c750079553fe1bc4efad2009268009164 +098f6e00150ef5eaf0fffbfffffcfd0602010c06060d0000fff9fdfffdfff6f6f60b0b0b +000000000000ffffffedededffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffefffffbfffff0f4ffbabbfc15118a0e02c61c0ef70000d1 +0400d7e6e5ff0100bf1105ef0d00e4160bbd181588c1c8f2f8fffff1f2f4ffffffffffff +000000f8f8f8ffffff000000000000000000000000fffffffefefef1f1f1fffffff9f9f9 +ffffffeeeeeeffffff070707000000080808000000fffffffafafa0101010a0a0a000000 +fffffff0f0f0f3f3f30a0a0a000000000000fffffffbfbfbf7f7f7000000020202000000 +ffffffffffff000000080808000000070707fffffff5f5f50000000000000a0a0af2f2f2 +000000ffffffffffffeaeaea030303f7f7f7fafafa0000000e0e0e000000fcfcfcffffff +f6f6f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff2e9e2f9e4ebfce2ebfae5e4f8e7df +f5e9d9f1ecd8eeedd8ebeedbebeddfebeddfeeecdff1ebddf3ead9f6ead4f6ead2f6ebcd +eee6c1efefcbe5f4d7dcf2ddddf6e3e5f8e5e8edd9e2ddc9eee5d4f0e8dbeeeee6edf2eb +eff7eaeef8dfeef2cde9eac8f1f2e2e4e5dde0e1d9eaecdfeff1e4eceddfebecdcf2f0e1 +eeeddbeeeddbefecddefecddf1ebdff1ebdff1eae0f1eae0efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdf +f2e7e1f4ece1efeedae9eed7e8f4e0e2ede5e6eff69298a6fcfefff0f0fcfefffff6fafd +f8ffff000218b9c8f182c6eb32dfe618f0eb2df5f530f4de00ab6100a2341cf06722ca53 +001c00ecffeff4fffaf2fff5f5fff1f9f9f9fff4fffff0fffffbffffffffffffffffffff +f6f6f6fdfdfdfffffff7f7f7ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffefff3f3fbfbffffc5c8fd08048d0000b61e17f10601d7 +e7e7ff0a08c30a00de0000b7131077c6caf0f1f6faf1f7edfffffdedededefefefffffff +fffffffbfbfbfffffffffffff9f9f9fffffff1f1f1fffffffffffffffffff6f6f6ffffff +ffffffefefeffffffffcfcfcffffff000000e6e6e6ffffffffffffe5e5e5fffffff7f7f7 +fffffffffffffffffffffffffffffffefefefffffffffffffffffffffffffffffff1f1f1 +f5f5f5fffffff2f2f2fdfdfdfffffff9f9f9fffffffffffffffffffffffff9f9f9ffffff +fffffff4f4f4fffffff7f7f7fffffffffffff3f3f3ffffffffffffffffffebebebffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc7 +0837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff1eae2f5e6ebf6e5ebf9e5e4f9e7ddf8e8d9 +f5ead8f1ebddeeecdfecece2ecece2f1ebdff1ebdbf1ecd9efedd8eceed8eceed6f5f0d2 +f3f2d6e7f0dddeeee1ddf1e8e5f6eeedf2ebedede5f5f0ecf6f2f1e9ecf1dce5eadceaeb +e5f5f2e5f3e6dce7d9f3f9efebeee5e6e9e0e9eddfeaecdfe7e9dbecedddf4f5e5eeeddb +eeeddbefecddefecddf1ebdff1ebdff1eae0f1eae0efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1e8df +f3eddfedefd9e9eed7eaf3e0e2ede5e6eff69199a6eff2fffbfffffafffff8ffffe4f2f5 +000313cadafe316d9100859429dee73ddfec0091850084412cd46527d74e46d45e001800 +eefffdedffffe8fff8f1fff3f9fff8f6e8fffff6fffaf4fef8f8f8ecececffffffffffff +fffffffafafaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffefffbf6fdfaf8fbfefff8eff4fff4f6ffb5b5ff000091181db7040d90 +0e149c0300abc5c0ffb8baedfcfffffffffbfffffafffffdfffffffbfbfbffffffffffff +efefeffffffff5f5f5fffffff6f6f6ffffff000000010101000000151515000000000000 +ffffff0e0e0e000000000000fdfdfdfffffffffffffcfcfcfffffffdfdfdffffffececec +f8f8f8fffffff3f3f3f2f2f2fffffff9f9f9fafafafffffffdfdfdfafafaffffffffffff +f8f8f8ffffffebebebfffffffefefef3f3f3fffffff3f3f3ecececfffffffafafaf4f4f4 +fffffff0f0f0fffffffcfcfcfffffffffffff9f9f9fefefeeeeeeeffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db +1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeebe2eaecebebebebf2e9e0f6e8dbfae7d9f9e7db +f6e7e4f3e7e7f1e8ebf1e8e9f2e9e4f1eae0ebeddfe4f1e0dcf4e6e1f1e6f9ece4f6e1de +f2e6e8f5f2f9eceefadbe1efe0e2f1eff0ffe5e7ffe8eeffc6d3fd8399c85472a65073a9 +5a7fb46280a6cedbe3e8eee4f4faf0ecf2e4e6eadce8ecddedf0dfedeedeeeeddbeeeddb +efecddefecddf1ebdff1ebdff2e9e0f1eae0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeadff0eee1 +edefdae9eed7eaf3e0e3ede4e6eff49199a4f8fffff8ffffe2efe6f5fff8f2fffd001215 +00041900071c00191e001112001619000b05001500001e00001b0000190006101cfefbff +e4f5ffe1feffeafff6e8ffe4fbffe6fdffeafafbf3fffffffffffff2f2f2f9f9f9f6f6f6 +fafafaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffefffffafffffafffffdfff5f7fff7fdffeffcffbacdf8afc7ebabc5deb5cbf2 +bbc4fff1f5fff9fefff1f0f5fef5fffff8fff8f5fcfffffff1f1f1f6f6f6ffffffffffff +fdfdfdfbfbfbffffffffffffffffffffffffebebebfbfbfbf5f5f5fffffffffffff5f5f5 +fffffff2f2f2fffffffcfcfcefefeffbfbfbf3f3f3fffffffbfbfbfffffffffffffbfbfb +fffffffffffffefefefffffffefefefffffff7f7f7fafafafffffffffffffffffffafafa +f3f3f3fffffff1f1f1fffffffffffffffffffffffffcfcfcf7f7f7fdfdfdffffffffffff +f1f1f1fffffffffffff0f0f0f9f9f9fffffff9f9f9ffffffecececffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff3 +1e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfebede2e1f0e9e3f0e7eeecdff5e9d9f9e7dbf8e6e2f2e7ed +efe7f4ece8f7ece9f4efe9ebecebe7e5efe7dcf3edd0f7f6d3f4fbe9ecfde6dcf4ebe9ff +f2f8ffcad5f18292ac61728c6a7d9b607495667da66b87b77ea1dbacd7ffc6f7ff94caff +5682c390a1b1d1d7cdf4faf0edf1e3e3e7d9eef2e3f2f5e4e6e7d7eeeddbeeeddbefecdd +efecddf1ebdff1ebdff2e9e0f1eae0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0edeae1eeeee2ecefda +e9eed8ebf2e2e5ece4e7eff2909aa3f5fffff0fffbf1fff2f1ffededfff0e6fff3ecffff +edffffe4fbf3f7fff6fefcedfffdeffff9f1fffcf9f4fffff2fffffdeefffff3fff5ffff +edffffddf7eef4ffedeef7ccffffddfefef2f6f6f6fefefeffffffffffffffffffffffff +fcfcfcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffdfffef2fcfff9fffcf4fff8f8fff8fffff1ffffe8ffffebffffe8ffffedfffff1ffff +ebf4fffafdfffffdfffff7fffff7fffffdfffffffffffffff7f7f7fcfcfcfefefefcfcfc +fffffffffffff8f8f8fdfdfdfefefefffffffffffffffffffdfdfdfffffffffffff5f5f5 +fffffffcfcfcfafafafffffffffffffffffff6f6f6ffffffeaeaeafffffff6f6f6fafafa +fffffffafafafffffff7f7f7fcfcfcfffffffffffff8f8f8fefefef8f8f8ffffffffffff +fefefefffffffdfdfdf4f4f4fffffff2f2f2fffffff7f7f7fffffffffffff5f5f5fefefe +fffffffffffffffffffffffffffffff1f1f1fffffffffffff7f7f7ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc90534d81e60f42158bf +dfe5fff4ebe2edeedee9eedaeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeaeee0d9ede1dcf1e2e6e9d6eee7d5fef4eaf4ebece4e5f7e4ebff +d9e4ffe3edffeff3ffe3eaf0e5f4f9cbe8f05683965083a24f78a6587db25b83b43d6a93 +5c8cb0a8dbf8b4e8ffabdff491c1d583b1c85683a085b2db97caff88c1ff7dbbff4879bc +5467787e8178e8ebe2e3e5d8f5f7eaeaecdeecedddedeedeeeeddbeeeddbefecddefecdd +f1ebdff1ebdff1eae0f1eae0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0ebebe3edefe4ecefdceaedda +edf1e2e6ebe4e7eff2909b9fedfffc3f58457694703c60326f93656b8f697799816c937e +6fa18426553179986e84926f8c8678847e7ef4fffff7fffffff4fffffafff9fffff5ffff +fcfefff8edf3fffaeffffaedfff9f6fafafaffffffffffffffffffefefeffefefeffffff +f9f9f9fffffff8f8f8f1f1f1fafafaffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefd +fffbfbf4e9e7d8d0cd08080a00000c0a172800031700041c00022700032800011e00011a +050922f8f5fffffefff7f2eefbfaf8fcfcfcf9f9f9fffffffafafafffffffffffffdfdfd +fffffff1f1f1fffffff9f9f9fffffffafafafffffff7f7f7f7f7f7fffffffafafaffffff +f9f9f9fffffff1f1f1fffffff8f8f8fffffffefefefcfcfcfcfcfcfffffffbfbfbffffff +fffffffbfbfbfbfbfbfefefefffffffffffffefefef1f1f1ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc90534d81e60f42158bfdfe5ff +f4ebe2edeedee9eedaeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeaeee0eefff0e0f3e0f8fce5ede8d5e0ddd4eaf1f7e2faff5274995f85ac +5f80a15c6e826878857587955e798ea3cef0beefffb0ddff9cc7fc92bdea739fc46594b0 +6fa3b873abb88cc5ceaadfe3ceffffdfffff638fa883b3e189c0ff7dbeff4e80c54a5b6d +777870f0f0e8e8e8dcedede1e8e9dbe8e9d9eceadbeeeddbeeeddbefecddefecddf1ebdf +f1ebdff1eae0f1eae0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeece0ebeae5edeee6edeedeeaeddaeef0e3 +e8ebe4e7eff18e9c9df1fffb6a886c29511f78a4653e6c2c649156e3ffe06c9c74205f30 +68a77231602ae3fed5fefef297919500010cf7fefffff9fbfffcf8eff5f1f6fffffffaff +ffecfffff3ffffe4e9fffcfdfffffff2f2f2fffffffffffff3f3f3ffffffe2e2e2ffffff +efefeffffffffffffffffffffffffff9f9f9f8f8f8ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff8fc +fffbfb867f77bebdb80001050002100003174f61875160a148569757658c000822eaefff +000012fefffffffff8fffffdffffffffffffedededf1f1f1ffffffe9e9e9fffffffafafa +fffffffffffffffffff6f6f6fcfcfcf5f5f5fffffffffffff5f5f5fcfcfcf6f6f6ffffff +fffffffffffffafafaffffffdfdfdfffffffffffffedededfcfcfcfffffffbfbfbf7f7f7 +fffffffffffffbfbfbe9e9e9fefefeffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001dc90534d81e60f42158bfdfe5fff4ebe2 +edeedee9eedaeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeceddfd6decfebf2e2ece7d1fcf7e4fcfffd445c685186a694d8ffa2e9ffa3e1ff +b4d9f39eb8c997a8ba7f93ae7998c66f8ebd9fadd4a8adcad0d2e7eff3fff5feffeafcfc +e1fefae9ffffe7ffffe9ffffe5fffee9ffff43678b81afea8ac4ff2d5da54b576d75706a +f5f0eaeeeadfeae6dbf2eee2f0eddeeeebdcefecdbefecdbefecddefecddefebdfefebdf +efebe0efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeece0ebeae5eeeee6efede0edebdcf1efe3e9eae4 +e9eef18e9c9ceefffa466b49e4ffd8275d1263994b346a1f6fa1642f652b6ba966256121 +80af7be7ffe0fffffa867a84ecf0f9060910fffbfbfffdf6f7fff4f7fffbf6f1f8fff7ff +f5d9f2fff5fffffcfff1f1f1fffffffffffff0f0f0fffffffefefefffffffafafaffffff +f5f5f5fcfcfcf4f4f4fefefeffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff6fffff9ff +0400008b8c7ecdd5ca04110a0005050005224b53a8585ebc515e95000120f4fffff5ffff +000012fbfffffeffffeaeaeafffffffffffffffffff4f4f4ffffffffffffffffffffffff +f6f6f6f2f2f2fffffffffffff8f8f8fafafafafafaf8f8f8fffffffffffff2f2f2f6f6f6 +fffffffffffffffffffffffffffffff7f7f7fffffffffffffffffff3f3f3fffffff7f7f7 +fffffffffffffffffffbfbfbfffffff7f7f7ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001dc90534d81e60f42158bfdfe5fff4ebe2edeede +e9eedaeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecdff7f9ecdedfd1eee6d3efe9dbd1dbdc4d7285a2e9ff54afe46bc9fd70c1ec6da1b9 +91aebebbcbdbf2ffffd6ecffe9fffff1fffff8fffffcfefffbfbfffbfffff5ffffebffff +e5ffffe6fffeddfdeeeefffbe8ffffcdf0ff6591be6ba7ef4373b34d5568776e69f3eae5 +f3eae1ebe2d9f8f2e6f4eee0f0eadcf1ebdbefecdbefecddefecddefebdfefebdfefebe0 +efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeece0ebebe3eeeee4f0eddeeeebdcf2eee3eae9e4e9eef1 +8d9d9cddfcece4ffea225a1bd5ffc538762169a7542e6722629958275e1a72a664d1f9c5 +f4ffecfffcfd0c000d0706140000070d0200eae4d6f7fff1f4fff8fffeffece0f4fff9ff +fdf1fffcf9fffffffffffffff3f3f3fffffffffffff9f9f9f3f3f3ffffffedededfefefe +fffffffffffffffffff5f5f5ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffefffffafffff5ff030000 +0506007a8076c4d0c40008000004145b62b24046a8515ba0000531e6f7fff0fffff1ffff +000212fbfffffffffff4f4f4fffffffafafafefefeffffffecececfefefeffffffffffff +fbfbfbfffffff9f9f9fffffffffffffffffffffffff9f9f9fffffffbfbfbffffffffffff +fefefefbfbfbf4f4f4f5f5f5fffffffffffffbfbfbf6f6f6fdfdfdfffffff9f9f9ffffff +f4f4f4ffffffedededffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001dc90534d81e60f42158bfdfe5fff4ebe2edeedee9eeda +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0 +e3e3d9fbf7ecfaedddefe6ddf3fdff37607c7ecfff59c1ff43ade94faad94f899fd3f3fe +effdfff3feffedffffe3ffffc6f7ffd1ffffdcffffe1ffffe3ffffdbffffbdf0ff99d1de +8fc4c8bfeee6e3fff8e7fffde2ffffb8ecff3b7fac598eb8424a57827370f3e5e2fff5ed +f0e6ddf1e7ddf0e6daf0e8dbf2ebdbf1ebdbf1ebddf1ebddefebdfefebdfeeece0eeece0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecdfebebe1f0eee2f2ecdcf0eadaf4ede3ece8e5eaedf28d9d9d +eafffbe2ffeddcffdc286c1fd5ffc6357828528f4c3c6f346b935eebffdaeeffdaf7ffe6 +fcf0f4fff0fffffaffbbb8c9080000ffffeae9ffe3effff5eaf3fcf9fffff7fffff7ffff +fcfffffffffffffffff4f4f4fffffffffffff4f4f4fffffffdfdfdfffffff9f9f9ffffff +f5f5f5fdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffaffffedffffee08060b02000d +05080d000300e9f6e2c3d1d1535d924d54a45661b000014100092d000619001721000d11 +f9fffff3f3f3ffffff000000fefefef7f7f7fffffffffffffffffffbfbfbfdfdfdffffff +f8f8f8fffffffffffff8f8f8f8f8f8fffffffffffff8f8f8fffffffdfdfdfbfbfbffffff +fefefeffffffffffff000000fffffff8f8f8fffffffffffff7f7f7fffffffefefeffffff +f8f8f8fffffffffffff7f7f7ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001dc90534d81e60f42158bfdfe5fff4ebe2edeedee9eedaeeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0e0e3da +f5f5ebf5e9dde3dad5ebf4ff355c837bcaff3da3ee4bb4f8419dd097d0e4e9fffff5ffff +f7ffffebffffd5fcffd5ffffbef8ff98c5da84aac17b9ebc7da5c897c9eea4d9f990c3d6 +77a3a6ddfdf0edfff8dafbf2d6ffff9edef92b5d783b3f4a8d7978e1cfcdfff6effeefe8 +ebded5f2e6daf5ebdff3eadbf2ebdbf1ebddf1ebddefebdfeeecdfeeece0eeece0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfedebdef0eedff2edd9f1ead8f6ece2ede8e5eaedf48d9c9fe9ffff +c8fbdc18591f65ad631b6415d6ffd12f6f325d925c5179476586593e6236ecffe9fff9fd +fff7fffffbffc9c8d6070000fffff1f4ffeff1fff6000908070e14000604edfffcf8fefc +0000000303030a0a0a000000000000ffffff000000000000000000000000000000ffffff +fafafafffffff9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff6ffffe4fcffe700000500001000000b +c8cbd0f9fffff7ffffbac6e0707daa4c5c9a364a8950699f44648a446a81000912edf6fb +ffffffffffff000000fafafafffffff1f1f1ffffffffffffedededfffffff6f6f6ffffff +f6f6f6fffffffcfcfcfcfcfcfffffff6f6f6fffffff6f6f6ffffffedededfffffffdfdfd +ffffffebebeb0b0b0bfefefef8f8f8fffffffbfbfbfffffffefefefffffffafafaffffff +f8f8f8fdfdfdfbfbfbffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001dc90534d81e60f42158bfdfe5fff4ebe2edeedee9eedaeeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfebede0ebf8eee4eee5 +f6efe5f5ecede7ecff3958878ccfff54aeff3a97e464b5ecdbffffe4fefbe6f6ebf4fffd +81a3ad90baca90b6bfafcdd5cbdce6f7fefff8fdffecf5ffe6faffd8f2ffbed6fc8a9bad +dce2e0fefff4f8fffae3fdfcdaffff385e7144414a816c6b978281dac5c0ffede7f2e1d9 +fceee3f7ebdff3eadbf2ebdbf1ebddf1ebddefebdfeeecdfeeece0eeece0efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddedebdcf1eedbf3edd7f2ead7f8ebe2efe7e5ececf48d9ca3e2fffe356a50 +6bae79236e2b58a45c28712cd3ffde356f3d5a8d5538693a689880e7fffff8fffffffeff +f8fefebfc3c409000afbeff9fbfffb000600ffffedf9f6e5f9fffd000708fcffffffffff +fcfcfcf6f6f6ffffff000000ffffffffffffffffffffffffffffff000000ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffaf1f5e6fefff405060b00000bccccd4cdcfde +f0f0fff4f9fff2ffffcee2e0697f944f67954460a94465b22e569100193ef7ffffffffff +efefef060606fcfcfcffffffedededfefefefefefefffffffffffffafafafffffffefefe +efefefffffffffffffefefeffefefefffffffafafafffffffffffffefefef9f9f9ffffff +fafafa0d0d0df6f6f6fffffff8f8f8fffffff6f6f6fefefefefefefffffffbfbfbffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001dc90534d81d61f42158bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeeecdfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfebede2ddeae1e9f4ecf0e9e1 +e8dde1f1f3ff4b65967dbfff499ae93681bbc9ffffe5fffff4fff6f9fff1f1fff87399a6 +dfffffe2fffff0fffff3fafffefbfffff8fff6f0fff6f9ffdae5ffc3d4ff798aa4eefbff +eefaf8e7f7f4e5fdffc1e5f3576e7c534248704e4d492a27a0837df7ded7f8e4dbfff2e8 +eee1d8f3e9dff2eadff1eae0f1eae0f1eae0f1ebdff1ebdff1ebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecddeaeddaf0efdbf6ebd7f7e7d8f8ebe2ece8e5e6f0f2879f9fe7ffff699681245b33 +5c98652d6c35569560366f44d6ffe237713659925d265e43defffdf0fffdf6fff9f6fff5 +c6cdc606000bfff9ffffffff000200fffde6fffae5fffffa000103fffffff8f6f7fffdff +fffcff030004fffdfffffcfbfdf9fafffefff8f6fb070709fcfcfcfffffbfffefcf1eff4 +fffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffefffffcfffffaffff00000e060d1d7b838ebac2d5c5c8f1 +f8fdfff7fff4eafde1c0d3d16d82a14960a6435fb2466db2000532f4fffffcfcfcffffff +000000fffffff5f5f50d0d0d000000020202f8f8f8fefefeffffff000000020202080808 +fefefefefefe080808020202000000fffffffefefef8f8f8020202030303000000ffffff +000000030303000000000000ffffffffffffe8e8e80a0a0a070707000000fffffffefefe +f8f8f8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001dc8002fd32064f71a51b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4 +f5e8dff5e9dbefebdfeceddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfecece2e8ede9edededf5e7e6f7eaf1 +e6e7fc44618984caff2e7bafbdeffaddfae8f9ffe4fbffdcffffebf3fdff85a3c9ddffff +dbffffe6ffffeefffff5fcfff7f4fff1edffeceeffe0f0ffb4d5f66f9db7ceffffc4f9ff +99c9d7446b7a496676d2d6e25d39399a655f8b5b518e665af3d3c6fff1e5f8e7ddf2e7e1 +f2e8e6f1e9e7f1e8e9f2e8e7f3e8e4f5e8dff8e8dbf6e8dbf2eaddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfebeedd +e4f0daecf1ddfae8dcfbe4dcf8ebe5e6ebe4dbf7eb7fa598e7fffb345343768f7a415d44 +71947637603e6e9779305f35dfffd823601d68a16c316137eaffecf0ffefe7fde8bfcdc0 +000100f4f2f5fffffdfffff80901000b0100070000fffef8fffffafffdfffff5fffbedff +0c000ffff9fff2e6e6fffcfdf8f0fdfffbff0e0b12fcfcfafffff5fffefbfbf0fffffaff +fffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffefffffcfefff8feff0000205a6d8b445d737a94a1b9ced1bccdc3 +fbffe8feffeafefffdf7fcff6b78a4576ea434588a000629f3fdfffffffffefefe000000 +fdfdfdfefefefffffffdfdfdfbfbfb0a0a0affffff000000fffffff7f7f7fffffffbfbfb +fffffff8f8f8fbfbfbffffff000000ffffff000000fcfcfcfbfbfbfffffffafafa030303 +fffffff1f1f1ffffff000000fafafa070707fffffffafafaf6f6f6030303fafafaffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc8 +0030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeebe2f0f0eeece8e7f2e2e2f7ebefe4e7f8 +3c5d8084cdff4994bed8fbf5f5ffdcffffd6fffcd2fffee5f3fbfe81a1caddffffe6ffff +dff9f6f2ffffeef8ffe8eafff5f9ffddebffc7e1ffacdafb5a96b8387ea0498db26ea8ce +c1eeffa4c1e9aaabc9a17a7f612821612f24865c4effebdce7d0c2f9ebe0f8efe8efeae7 +eeeaebefe9ebf1e8e9f3e8e4f6e7e0f8e8dbf6e9d9f2eaddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfebeddfe0f2dc +e9f2dffbe7e0fee2dff8ebe5e3ede2d7f9e87ca794e7fff8f2fffbebf5ecf7fff66a7f6e +eefff4d6f3dd7da0802c58275f8e57335d2d759a71001100d3edd4f4fff6c3d0c7040a08 +feffffffffff010000fffdfafcf7f1fffff6030100f6f8ebf5f5f3fff9ff0f001dfff9ff +fff6fbfffcf6fff9f6fffcff00000bf0f1f5fcfffaf6f9e8fefef4fffbfffdf4fffffdff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffefffffafbfff6fcff0006333951815978a40006256c8b90bbd3c6becab4 +040700030000fefdffb8bee25264925373a400072df2fcfff7f7f7f6f6f6161616ffffff +f4f4f40e0e0e0000000c0c0c000000fdfdfd0c0c0cfffffffffffffffffff2f2f2ffffff +040404080808060606000000ffffff010101fffffffffffffafafaffffff000000fbfbfb +ffffffffffff020202ffffff0000000000000303030d0d0d000000f9f9f9efefefffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d3 +2064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeece0f2f1ece8e5e0f1e4dcf9efede5ebf7375a7a +7dc8ff579fd1e8ffffffffedffffdffff6d4fffce4f3fefa80a5bfdeffffe6f1f7fffefb +fcf8f7f5f6faeff7ffdcf1ffd5f8ff95c5eb508bb75190c36cabe1bdf8ff96c8ff80abf9 +5a80d55e6dae674e636c403d7a554dffe2d7f0d9cbfffcece2d8cce9e5daeeebe4ecebe7 +eeeae9eeeae7f1eae4f2e9e0f3eadbf3eadbf1ebddefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfebeddfe2f1dce9f2df +fbe7e0fee2dff8ebe5e5ede2d8f9e87fa693e8fff5f5fffbf8fdf6fcfff8859686ebffee +f1fff4e3fae6f4fff4091a08f7fff6edf9ef000601f9fffffbffffbcbfc4000005feffff +f5f9fc020607fbfffef9fff9e7eee6040f01f8ffeff9fff4eceff600000bfffdfefffff6 +fefdebfffff3fbfffe000608f8fffbeffeebf9ffeaecf5e0fafbfdfffeffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffefffff0f4fff5ffff0004384960a633509e5172b90004337c94aeb9c6ce82878a +01010dfafcfff4fcff3b4e883b589a000137f7fffffafafaffffff000000fcfcfc0c0c0c +f6f6f6fffffff8f8f8090909ffffff000000ebebebfffffffdfdfdffffff000000ffffff +e9e9e9ffffff060606fcfcfc000000fdfdfdffffffeeeeeefbfbfb090909f4f4f4ffffff +e7e7e7000000fcfcfc040404fffffff5f5f5f9f9f9ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f7 +1851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeece0edede3e9e7dbf4ebdcf6f2e9e5f2fa39607d73bffb +5097cfecfffffffbf1fffae2fff2d6fffee4f6fff77dadb7dcfffff7fffffaf1f4fcf2f1 +d7d3d2eaf1f7d5ecfc5e8bac538dbb92d5ff9ddfff9ad5ff84b8f45b88c93e6baf6797e1 +34528e3e344c7a6061fae2def9e7ddfff3e6e3dac9ffffefeeecddecece2ebece4ebece6 +ecebe6eeebe4eeece0efecddefecdbefecddefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfebeddfe3f0dceaf1dffbe7e0 +fce3dff6ebe5e6ece2dbf7e883a493f1fffaf0faf2fffffaf4f7f0808e81def0e0f5fff6 +f8fff8f5f7f6fffeff0100040100040b060df7f4fbf9f6ffc8c5ce08070ffefefff5f8ff +060b0ff9fffff8fffff0fcfa011107f5ffeff6fff20c1212f5f8fdfbfcf7fffff4ffffef +f5fcea040d08e5f1efeafaeff5fff3f7ffecf9ffeffcfffdfeffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fefffdfbfffbf5ffff000030475da9405cbf3f5dbf405dad00013a7d8dafb8c3d9bfc5dd +00001ef2fdff596da2375490001646ebf2ffffffffffffff000000ffffff000000fafafa +ffffffffffff090909ececec0b0b0bfffffff7f7f7fffffffcfcfc0d0d0df9f9f9ffffff +ededed070707fefefe000000fffffffffffffffffff5f5f5151515ffffffeeeeeeffffff +000000ffffff030303f8f8f8fdfdfdffffff020202efefeffafafaffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefede0efecddf8f1deebebdfe2f4f8416d8873bffd4d91ce +ebf9fffff3f3fff3e5ffeed7fffde2f4fff375b0accdffffe9ffffe8effffbf9fcfffefb +d7d8da7e909e527ca277b3e99fe3ff6cb0f1447bb134658d90bed5c3f4ffd5ffff29555e +323a45887e87eae4e4f4efe9e6e4d7e7e6d4e9ebd6f4f5e3ebeeddebede0ebede2ebece4 +ebede2ebede0ebeddfecedddeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddfe4f0dcecf0dffbe7e0fce3df +f6ebe5e6ece2def6e887a293f8fffbfefffbfffefbfffffa79837af7fff8eff9eeeef0eb +fbf6fa0d030bfff6fefffbff070002fffafffffcffd3ccd3030004fffdfffffeffececf6 +03071200071100010ceffafef8fff8e8f4e8000306fefefff9f8f6dfdfd7fffff4fefff6 +000104f8fffff2fefcf1fef4effae9f1f7ebf8f8fafaf7feffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefff8 +fcffe8f1fff000012242599f3d59bd516fdf4562c84963b800003e7583b2737ca5c9d3f7 +000025edffff506d8d00041cf7fffffffffff3f3f3060606fefefeffffff080808000000 +060606000000fffffffafafa040404101010000000ffffffeeeeee101010000000121212 +000000fbfbfbffffff0000000000000b0b0bffffff000000fffffffffffff7f7f7000000 +f6f6f6ffffff0000000d0d0d000000f4f4f4fffffffcfcfcffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff3f1e2f2efdef7f2dee0e4d6dcf1f643729071bfff5799d6ecf6ff +fff0eefff2e2ffedd1fffbddedffec6baca6c2ffffbfe8feeeffffd1d8def0f6f667767b +0007194c83aa2f72a72267a03b75a5a1c6e1e5ffffebffffd7fff2d2ffff5b928f1e3441 +757b89e7ecf2dde2def9fcf1eef1dee4e7d2e0e2cceceddbecedddebede0ebede2eaede2 +eaede2e8eee0eaeedfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeceddfe6efdcedefe1fae7e1fbe3dff6ebe7 +e8ebe2e0f4e88b9f94f8fdf7f7f3f2fbf5f5f0efed87908bf8fffbfcfffdfffffffffdff +030005120b12040002040000fffdfb060000ccc4c2040000fffdfdf1ecf0fffefff5f4fc +fafafffcfefffbfffff4faf6fcfffbfffefffbf8fffffdfffffefaf3f0e9fffffbf9f9ff +fbfffff9fffffbfffffefffafcfbf7fffcfffffcfffffeffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6feffe8 +f1fceb00031c5b6fae3b55b22847b13754ba425db83b519c5565a3606ba14c5483bfcbf3 +00021e41586a061a23f9ffffe0e0e0f6f6f6fffffffffffff2f2f2fffffffcfcfceeeeee +fffffff8f8f8fbfbfbf6f6f6ffffffedededfffffffffffffffffffafafaf9f9f9ffffff +fffffffffffff6f6f6fffffffffffff8f8f8fdfdfdfffffffffffffffffffffffff6f6f6 +ffffffeeeeeeffffffebebebfffffffffffffefefeffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddf3f0dfedead7f7f2dfe2e5dcdbf2fa3a688a62b0f05a9bd5eef7fffff1e6 +fff3d6ffedc7fff9d6e9ffea66aaabbeffffd7ffffdcf7ffd7eff3d0eff290c1cf6db0ca +80d8ff73caf593d6f385adb7dde1d2fff9def5f3daeffff7c2faff437f991f3d57728196 +eaf8ffd3dfdfe4ece1edf1e0f5f7e1f0f0d8efedd8efecdbeeecdfecece0ebede2eaede2 +e8eee0eaeee0eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeceddfe7eedeeeefe1f9e8e1f9e4dff5ece7e8ebe2 +e3f3e8909d94fefdfbfffcfffff6fbfffeff7b8483b8c2c1cdccd1cccbd0c3cad0a1aaaf +d5dddfcad0cebec3bccccfc4050600c7c5b6070400fffff0fffef4fffef8fffdfbfffafd +fffcffefeaf0fffefffffefffcf5fcfef3fbfff3f7fffbfbfffaf9fffdfffffcfffaf8ff +fdfbfff9f8fefffafcfff9fafff8fffff2f9fffeffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbeeeee6fcffff +000020404f88576eba526ec13352a24663af5970b64554993b4489595f9d5157894b5578 +586875000407fbfffffffffffffffffffffff9f9f9fffffffffffffefefeffffffffffff +fffffffafafafffffff5f5f5ffffffffffffffffffefefeffcfcfcffffffffffffffffff +fdfdfdffffffeeeeeefdfdfdfffffffffffffbfbfbf5f5f5fffffff7f7f7fffffff9f9f9 +fffffff6f6f6fffffffffffff5f5f5fcfcfcffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecddeeebdae6e3d2f8f2e2eceee9dff5ff2c59804d9bdb5293c9edf6fdfff3d9fff5c8 +ffecbdfff6d0e8fdea67a9b5c1ffffc5f5ffd6f7ffc9e7f1cbf1febcf6ff62b0d43698c7 +7cdbff98e0f8729899ede9ccfff6cffff6dcf6fbf7caf5ff5e91be2240645e728bd4e6f4 +f5ffffdbe5ddeff3e2e5e4cff3efd6f2ecd6f2ebd9f2eaddefebdfeeece0ebede2eaeee0 +eaeee0eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecdfe9eddef0eee1f9e8e1f7e6dff4ede5e8ebe4e6f1e9 +929b96fdf7f9fff5fdfff8fffefeff7a878d0003090b0b1500000b000511000c1600070e +000505000500000700000500060b00000400ffffedffffedfffcf0fffff6fbf6f2fffdfd +fffdfffffefffcfbfffffdfffffcfffff8fcfffbfffffcfffffafff5f3fffefdfffcfbff +fffdfffffdfffffbfffff2f8fffafdfffeffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffefffffdffefebf9050827 +00002b00003200063700052e000a3000022b00093700003300033a00002b000021040a16 +000104feffffedededfdfdfdfbfbfbfffffff7f7f7fffffffdfdfdfffffff8f8f8f8f8f8 +fffffffcfcfcfffffffdfdfdfafafaf8f8f8fffffffffffffffffffefefeffffffeeeeee +fffffffffffffbfbfbfffffffcfcfcf7f7f7fffffffffffffcfcfcf5f5f5ffffffffffff +fafafafffffffffffffafafaffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eeda +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdd +f0efdde1dfd0fff8eee3e4e8e1f3ff35608b3c87c85ea0d0f5fff9fff0c4fff7bbfff6bb +fdf4cbebfff36ca8c4b5feffc4fcffc6efffcae6fcc7e5ffb4deff91cdff6bbfff5db7f3 +73c0ea78abbcdbe9dcf7efd8fff6ebf7f4fdaabfec3f5e952a416a61728ee2f2ffdbe6ec +e9eee8eff0e2f7f2deeae2cbf5ead6f5ead8f5e9dbf3e9dff1eae0eeebe2ecece2ecece0 +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecdfebecdcf1eedff7e9e0f5e6dff2eee5e6ebe4e7f1e9959998 +fffafffff7fffefafff8fffff0ffffecfefffbfefffbfdfff1ffffeafefff0fffff1ffff +effefff5fffff5fff6f2ffedf8fff0f7ffebfbfff1fbfff4f7fff4f0f7f0fbfffdf9ffff +edf6fff4fcfffbfffffcfffffcfdffecedf1fcfffff6fdfff7fffff5fffff5fffff8ffff +edeffbfffdfffffcfdf9f1effffffdffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffefffffafffff6fffffbfff3f7ff +f2ffffeeffffe8fffaebfff8eefff8eafffaf5fffff9fdfffcfcfffffbfffffdfff7f6fb +fffffffdfdfdfffffffffffff3f3f3fffffffafafaffffffffffffffffffffffffffffff +fffffffffffffffffffffffff6f6f6fffffff4f4f4fffffffefefefffffff3f3f3ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdff3f4e4 +ebe9dcede4dff1eef7e0eeff47709e2f79ba4a8ebbe4f9eafef4bffffab7fff6b4fbf4c8 +e8f9ef6ea3c5b2f4ffb9efffbde9ffc9e4ffcce4ffbdddffa0ceff7dc0ff72b9f79ad8ff +658f9be8f5e4faf5dfebe7dee8f0ff3458922851931d3460657390ecf7ffe6edf5eaece7 +ebe9dcf7f0ddf5ead6f6e9d6f8e8d8f6e8ddf5e8dff3e9e0f1eae2efebe2efebe0efebe0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfedebdcf3eddff6e9e0f2e8dfefefe5e5ece4e7f0eb95999afffbff +fff9fffbfefff1ffffe9ffff18334618213e2225462c3755172540303f56263646202e37 +f2ffffeffffcf4fffff4ffff8b9c965e716f8fa2a6566d7595adb9465d6d879db45e7594 +889dba45576b8fa1af5868779cadbf50627a889db8445e777792ad3e57759fb4d35c6b88 +8a95a94e555dfcfffffeffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffefffffcfdf6ebf1fffcfffefdfff4fdff +eefff9f1fff1e8ffdfecffe0f5ffececf7efedf0f5fffdfff3ecfcfffcfffffdfffaf8f9 +fffffff8f8f8f7f7f7f9f9f9fffffffffffff8f8f8ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffdededefffffffffffff3f3f3fffffffffffff9f9f9ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdff1f3e6ecece2 +eee3e1f3ebf6e6ebff4567971f66a83178a6defaeefbfbc9ffffbefffdbdfffdd3e3f0e6 +79a6c5c6fdffbeedfdc1e7f2c5e1f9c5deffbbdaffadd2ffa4cfffa7cfffa6c0cf869181 +f3ecc2fffbd1f0feed75a2b70e63a61769b5163665717894eef4ffebeef5edece7eae6da +f7efdcf8edd9f6e9d8f8e8d9f8e7dff6e7e0f5e8e2f3e8e2f2e9e2f1eae0efebe0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeebdcf3eddff6e9e0f1e8dfedf0e5e3ede4e7f0ed95989dfff5fffffaff +f5ffffe5ffffdbffff1e46609badd3b3b9dd9a9eb79699aaa1a4b3acb2be272f3a1c2630 +f4ffffe3f5ffeeffff415b744f6e8d40638b3c6293325d945c88c52f5b9c3b63a8375f9d +4e74a34b71983f628c476c993b6097466fa74a75aa3f6da1446ea83a619c4e6ea7415c8b +92a9c8dff1fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffff8ffffea918a788a84888c879b82829e676c82 +868f947f8c8375827084917d969d958789887f7d829790977b7074918889858384ffffff +fdfdfdfffffffffffffffffffffffffafafaffffffffffffffffffffffffffffffffffff +fffffffffffff9f9f9fffffff6f6f6ffffffffffffedededfffffff8f8f8ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfecece0e8ebe0e6e7dffff3f0 +ebdee5efefff3f5a89175ca1246b9fe7fffff7ffdef2f2befbf8c3ffffdce4f1e081a4b8 +b1e0fabbeaf0bee7e9bfdfeab8d2e9a9c1e598b0d68ba3c58c9dadbfc5b9cfccabf2eabc +f9fad8accac8004066076dc20059b21d3d6c7b7d92e3e5f2eae9eef1eee7efe9dbf3ecda +f2ead7f5e9d9f6e8ddf6e7e0f5e8e2f5e8e2f3e8e2f2e9e2f1eae0f1ebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecddf0eadaf4edddf4eadeeeeadfeaf2e5e1eee5e6f0ef95989ffffbfffefcff11253e +1a425b0038530436592d48778995bdaeafc1adaab19b9aa09da0a7222631afb6c6212d43 +f0ffffeaffff81a0cf4468a4406bb04574c42c5fb8336ac7356bcd3d6fd2406fc74273b8 +184984416eaf3d6cb23b6ab83467b63f75bf2c64ae3267b53667b6315aaa4c6fb33a5b88 +ebfffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffff6f7f8d97e7c65c6c0cabcb2d7e2d9ffc4bcf7c9c6f3 +bdbcdcc2c5d6bec2cdbcbecbb2b1bfdfdbeac2bac7dad0d8867d820a0809f1f1f1ffffff +fffffffffffff2f2f2ffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffff8f8f8fefefef7f7f7ffffffeaeaeaffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfecece0e4ebe3e4e7defff2e9efdddb +f6efff6b81aa195ca2276eaed0f6ffeefff7eaf2daecf0cdffffe1f0fae195afac84afb5 +73a9ab78aca885ada497b1a4aebdaac8d0b8e0e5c5eef3cbfdffd5eff6cceaf3d6d6ede7 +406b8d2363ab0259ca0e57be1c3261817f8ddedde3edeceaf3f0e7edeadbf0ebd8f2edda +f2eaddf2e9e0f2e9e2f2e9e4f2e9e4f2e9e2f2e9e2f1eae0f1ebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdd +f1eadaf4edddf3ebdeebecdee7f3e7deefe5e5f1f19299a3fffcffe7ebff0f2d496194b1 +2f74933c7ba4143c704d608b474b56aeada9a4a4a4afb0b42f333eabb3c68694b1192b53 +dff6ff4f6dad375caa3f6bc22c5cc03468d51c55c6447df12659cf2e5eca3c6ec3487cc7 +3566b5396bc03c6ecd275dbd235cb3437cd3386fca396bca436ecd456abb7495cae7ffff +f8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffafeffef959891cdc8e809003d0d005808005c0f00610e0258 +0d054e00003a150f4b1a154b0a04300d0628191126837d89010004fffffff9f9f9fefefe +fefefef8f8f8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffdfdfdfffffffffffffafafaf5f5f5fefefeffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001ec9 +0435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfecece2e8f2eae8eee4efdfd0fce8ddf5eaf0 +becef01b59a22870bc6d98c5c8def3f4fffff5fdeef5f8dbf6fddbcce0c7a6c7b6b1dcd3 +b7e4ddc8ecded6f2dce3f7dbecfcd8ecfbd4e7f5d1edfcddbacdbaa0b9b66d8ca1042c5d +25559f003091002176303d5f979299e4e2e3f4f4ecf1f2e4e8e7d5ebead8f6f4e5eeece0 +efebe2efeae6efeae6f1eae4f1eae2f1eae0f1eae0efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf2e9da +f5ecdbf2ecdceaecdee4f4e7dcf0e7e3f1f19199a4f4f2fff5feff1f4665407fa04090b3 +337daa002f6990acdc9ea9bba5a9ac969ba1afb5c11a2134222c47303e61273967294076 +718fcf4f73bd2e57a94370cb497bda2359bd275cc63c6bdf3766d03463b32e5fa2416fba +3867b92756b24174cf3b72c42d66b53165bb3362ba375eb94163ad43638cedfffff9ffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffefffbeffaec808988c1c0e00300370f005314015d0d0056190c5e1c115d +f7f0ff070245f9f5ff00002bf5f4ff1211217c7b81000002fffffff9f9f9fcfcfcffffff +fffffffffffffdfdfdfffffffffffffffffffffffffffffffffffffffffffffffff1f1f1 +000000fffffff8f8f8e9e9e9fffffff5f5f5ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001ec90435d8 +1d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfebede2e8f3ede7ede3f1e1caffe9d4f3e4dfedf8ff +104b971b62ba1b488b6c88b7bbd0ebe8f6f9f0f4dbf3f9cdf8ffd7e6f8cedbe8d4e6f3ec +e8fefbdefefdc7eff1a3cfd877a5b4568398254e6a173e5f1b3d6315305b253a6530416c +4d5a84656b8b898794ccc6c8edeae5f0f0e6eeefdfe8ebd8e8ebd8eff3e4eaede2ebece6 +ebece7ecebe7eeebe6eeebe2efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf2e9d8f5ecdb +f2ecdce9eddee3f5e7dbf0e7e2f2f29199a4fbfdfff2ffff0023444c92b40f678d4fa3d2 +02397987abe7889ec3b0bed945547191a0bf92a0c39cabd29fb1d991a4cf112756526c9d +3d5b8d4a6ea2d1f6ffc9f2ffd9ffff4874b53f64bddbffffddffffd7ffffdbffffddffff +3f66abd9ffffd4ffffd6ffffd9ffffdcffff4764a64b63939cb2c0e6f6f3fbffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffcfffff5fffd768685b9c0d0888aa3938eac8a84a07a7289837e927f7d93797a98 +8082a9777ba19499b78086966670688e9689000100fffffffefefeffffffffffffffffff +fafafaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 +fffffffffffffffffffefefef5f5f5ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001ec90435d81d61f4 +1f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfecece0e7ede3e3e5d8fff5e2efddcfece3e4e6f5ff063c86 +1051ad0f3e900d2f7646659cb4cbede8f5fbe6f2e4f1ffe8e4f2d9cdcec8b1b2b677858e +3f5b691e445714425c0f40600c3c6219436d3456834b6691687aa0747b9878768b7e747d +efe3e7e8deddfffbf7f1ede4e6e4d8ecedddeff2dfe9ecdbe6eadbeaede2eaede4ebece6 +ebece6ecece4eeebe2efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf2e9daf4edddf0edde +e9eddee6f4e5deefe5e5f1ef919aa3f7fcffeffeff0d36563773974d98c2276ea2033678 +88b0ee94b5e089a7c93c5d7e97bada8fb3d396b9d989aacd95b3d71c385d829cc14e6a8f +e3ffff4e70954a70943e6b8cd6ffff3f65b63a5faf466c9b42688c456b98ddffff3b63a8 +406baf3e699e4771a1386197d6faff4d6aa6516691526164f9fff8fefffdffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fcfffff4fffa7b8a87c6cfd4fcfffff3f3f5fffff8ffffedffffe8ffffecfbfef3fbffff +f9ffffe7edf9f9fffff9fff6818a79000100fffffff6f6f6fffffffdfdfdfffffff8f8f8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe000000fcfcfc +fefefef2f2f2fffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001ec90435d81d61f41f58bf +dde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1ebddf5eedef4ecdff4ebe4e7e5eadee9ffd4ecff032f762e64ba +0a3c9504338b022c822e549f87a5e3849ed15d75a12a3e63323b5a1a213b2f39522d3c51 +3b4d615568794c5f6e6b7d896e7f8966737c8a919bd2d5defaf7fef0eaeee9dee2f4eae9 +f1eae4efebe0efebe0efebdfeeecdfeeecddeeecdfeeecdfeeece0eeece0eeece0eeece0 +eeece0efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeadef1ede1efede0ebecde +edf1e3e6ece0eaefe9949a9af5fcfff4ffff142e4917395e0b34620d35700b30748cb3ee +80aed08bbfd57bb8ca30748118606c195f69296877174c5e09314a4f6e8b576f93e1fbff +4a6c92446e943a6e95d2ffff3c6fca2d5cb64770a84e77a5cffbff3768b54274d33164bf +3a66ad4a71b2d7fdff4367b34262af536ca48a97a0fdfff7fffffdffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffb +f6fef1828981c0c3c8fffefffffafefffff3f5f3cd85854f7c7d43040700ffffe3fafdec +fefffbf6faf9fcfffa7f847d000000fffffffdfdfd0000000a0a0a000000fdfdfd030303 +020202f8f8f8ffffffffffff000000111111010101f3f3f3ffffff020202f6f6f6ffffff +020202fefefef9f9f9020202080808020202f1f1f1ffffff000000000000010101000000 +fffffffdfdfdf9f9f90606060000000b0b0bfefefe000000030303000000010101ffffff +f6f6f6fbfbfbfffffff8f8f8ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001ec90435d81d61f41f58bfdde6ff +f4ebe2ecefdee9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff2ebdbf1e5cff7ead7f4f0e7e3e8eee2f2ffd8f4ff224680244f940c3b89 +154597123f90042d7c0b3077001e61213b7831457a4e5c83545d7c7b829e6d758a606777 +757c84909598d1d6d2f2f3ede4e4dae4e1d8f3efe6faf3edf1e8e3efe4e2f6ede8f1eae0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfedebdff0eee2efede0edebdeeff0e2 +e9ebdeedeee6959a96f8ffffeffbff2939530e22479bb1e2122c670b286a98bff889c2df +2e748011616c38919937949b27818a206f7e1f607413405f7e9cc2435a845a709fd4f3ff +ddffffd6ffff225d952762c03065c3426fa83b6595ccfdff4179ce205bc32e68cc3361af +4068aedbffff3f65b63b5fb3526fab4b5763fefff8fffffdffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf7faef +94978ecdccd2f9f6fffffafefffff1ffffda070700ebeca68a8d4a040600feffe0f9f9ed +fffffdfeffff848587010101fffffffdfdfd000000f4f4f4ffffff000000fffffff6f6f6 +0a0a0afefefeffffffffffffebebebffffff0e0e0ef0f0f0222222f6f6f6000000ffffff +ffffff070707fefefef0f0f0ffffff050505e7e7e7040404fdfdfdffffffffffff000000 +ffffff000000ffffffffffffedededffffff080808fffffffffffff7f7f7080808ffffff +fffffffefefefdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001ec90435d81d61f41f58bfdde6fff4ebe2 +ecefdee9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff2ebd9f5eaccfdf2d4f6f1dddee1d8deebf1d2e9fb4b688821446c0b315e062f5d +1036632346704664884e69866d839b62748a5c667f80889dd0d7e9edf3ffedf4fcecf2f2 +dfe4defbfef5eceee1f1f2e2f3f1e2eeebdceee8dcf1ebdff6ede4f5ece3f1ebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfedebdff0eee2efede0edebdeefefe3e9ebe0 +edeee6959a96f1fafff2feff2e3e5798accf253b6a97b0e80e2a6983ace024667e479aa2 +38929d2585930c6f8217758f06567b0f4e7a133e753a57936072b0e3f6ff5871a9355787 +3d6a94d2ffff3773cb326bc2336296d9ffff4b81bf1d58a83979da2867c43e70b7cdfaff +3965ac416db63f6bb645689e98aab4f1f9eefefffdffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfcfef98c8e8d +bbbac0fffdfffaf5f9fffff4787554f6f6c48283498b8c530c0d0079795dfffff6fbfbfb +feffff83838b000002fcfcfcf6f6f6000000ffffffffffff000000fcfcfcffffff000000 +fafafaffffff000000050505000000000000fafafa000000000000ffffffecececffffff +0000000000000b0b0b000000000000ffffff050505fefefefffffffdfdfd050505ffffff +070707060606f0f0f0fffffff7f7f7000000fffffff8f8f8fbfbfb070707f7f7f7f6f6f6 +fffffffcfcfcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefde +e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f2ebd9f3e8caf8edcdf4eed4e5e6d4eff6efeefcffb6cad589a3b2658093668395708c9a +647f8a5f777b738786cdded8f0fffcedf6ffe2e8f4eff3fceaeff3e8ecebe9eee7dcdfd4 +e6e9d8dddeccecebd7f4f1def0eddaefe9d9f2ecdcf2eaddeae4d6efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfedebdff0eee2efede0edebdeefefe3e9ebe0ecefe6 +959a96f0f9fef5ffff1c2b420e214298adda243b6f1a346f325c8e60abc23b97a4218594 +086e8400506d2b8bb15eb0e05394ce00266a84a0e94a5ca6e5f6ff556aab5572ac335b8e +d5ffff2561b93774c7386a9fd4ffff235b982c6ab72f71cf2c6dc74379bfd0ffff4e7fc4 +3666ae2c5ca6436b9f415965f8fffbfcffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffeffff5b5c61d2d1d9 +fffefffffefff9f6edffffe8060300d7d6aadddeb2030500f7fadffffff6fdfdfff5f5ff +8d8c9a000004fffffffefefe191919f2f2f2f8f8f8121212f5f5f5fbfbfb0b0b0bffffff +050505ffffffebebebffffff040404ffffff070707fefefe000000fcfcfcf8f8f80c0c0c +f9f9f9fffffffcfcfcffffffffffff000000efefeffffffff6f6f6000000f7f7f7ffffff +f1f1f10000000b0b0bffffff000000fffffff9f9f9ffffff000000fbfbfbffffffeaeaea +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eeda +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ecd9 +f4eacff3eacdf3ecd2efedd8f2f3e5eff5ebf2fbf6dfeae6eefaf8d9e8e3d9e6dddceadb +e7f4e0e2efd5f7ffe4dce4cde2e7e1e1e2e4ecececebece7ebede2edefe1e9ead8f2f1dc +f8f8e0f7f5dcf3f1d8f0eed7f0ebd7f0ebd7f1ecd9f2ecdcefecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfedebdff0eee2efede0edebdeefefe3e9ebe0ecefe8949a98 +f5fdfff5ffff27364b2c3d5b1f325c001647233a701b45751263810d738900627a005976 +319ebf52b5df348abd094b880c3b815f7cc8485ba8e7f7ff485ca5465ea4486aaad2feff +2a65bf3674c9ceffff4271a53e75b83976c72466c62a6bc7c4faff3566a92557a03a6bb7 +4071be4973ad86a1b6e6f4f5fcffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffefff9f9ff92929ed5d4dcf4f4f6 +eeeae7fcf9f0fffff1ffffec040300040300ffffe4ffffe9fffff4fffffffefdff868499 +000005fffffff5f5f5000000fffffff9f9f9000000ffffffffffff000000ffffff000000 +fffffffffffff6f6f6000000f0f0f0000000ffffffffffff000000ffffff000000ffffff +f6f6f6f0f0f0000000f8f8f8050505fdfdfdffffffffffff070707fffffffbfbfbfafafa +ffffff000000f2f2f2101010fafafafffffff7f7f7060606fffffff9f9f9fffffff6f6f6 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf6efdc +f2ead7f3ecdaf4eedee7e3d7dedacfebe9dde8e8dceeeee2ecedddeff1dcedefd7f2f5d8 +e1e5c2f2f6d1e2e5c6f6f7e9f2f1ecf1eee7edebdfeceadbedecd8f0efdaf5f3daf0eed5 +e8e7cbe6e5c9ecead1f3eed8f2edd9f3eedaf6f1deefecddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfedebdff0eee2efede0edebdeefefe3e9ebe0ecefe8949a98f9ffff +dce6f0f3fffff1ffffddefff1d325d2c417083aedb4ea3c80067881184a336acca33a6c5 +03709117749d1f6d9b0032685e8ac74263a64663a9e2ffffd8faffd0f8ff4677c63974d0 +356ec7d8ffff426faa2759a22c64b93877d82a66c6d2ffff4d7cc44272be2a5baa3e6fbe +3962a2617a99f0fcfffcffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffefffdfcff858494b5b4bafffffdfffff8 +fffff6fffcf5f8f5ecfffff3ffffeffafae2ffffecf6f8ebf3f3f5fefcff7d7b91000007 +fbfbfbffffff000000fcfcfcffffff0e0e0efffffffdfdfd030303ffffffffffff080808 +000000000000000000ffffff060606f7f7f7ffffffffffff000000efefef0404040e0e0e +020202fffffffdfdfd0000000d0d0d000000000000f5f5f5ffffff000000101010000000 +ffffffffffff000000000000080808000000fffffffdfdfdfffffff4f4f4ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0ebe6e0ece7e3 +efeae6f8f0edf0e6e4f5ece7f9eee8fdf3eaebe1d7f7ede1f8efdef1ead7fbf5dfe7e3c8 +f5f4d6f4f2d9efe9dbefe8deebe5d9f1ebddf4f1e0f2f0dbedebd4e5e1c8f2eed5f3efd6 +f3f1d8f5f3dcf5f3def2efdcedead7e9e6d5efecddefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeeadef1ede1efede1edebdfefefe5e9eae2eceee9949a98f9fffff7ffff +f4ffffe8f7fff1ffff1b2d518092ba6c97c23693bf36add72ca8ca0d8aa60a8799148c9a +2694a13595a5004b623274944d86b134679c3669aa4175be245dac2f68bf235bba3b6ec7 +365ca34d70b4355ead4476cd2f66ca376dcd3966b9385fae3861b3426cc0325fb24c71b7 +7487b2f7fffffcffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffefff9f6ff87849587878986877f7e7f718c8c80 +8c8b897f7d7e7c787787877d9799847779638689788f8f8d79768b938fa603020af8f8f8 +f0f0f0fffffffbfbfbffffffebebebfefefef8f8f8ffffffedededffffffffffffeaeaea +ffffffffffffeeeeeeffffffe8e8e8fffffffffffff8f8f8fffffffffffffdfdfdededed +f4f4f4ffffff000000fffffff1f1f1ffffffffffffeeeeeefffffffefefef6f6f6fdfdfd +ffffff050505fffffffffffffffffffbfbfbf7f7f7fefefefffffff6f6f6ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeebe2ecececececeee9e7ea +eee8eae9dfe0fbf0eeeee0ddeedfd8f7e6deffeee4f0e2d7e9ddd1fff9eaefe8d8f5efdf +f2ecdceee6dbf6eee3f3ebe0f3ebdeefe8d8ece7d4f7f2def7f2dcede8d2f4efdbf2f0db +e9e6d3e8e5d4f1eeddf4f1e2f0eddeefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeeadef1ede1efede1ebebdfefefe5e8ebe2eceee9949a98f9fffff2fbfff5ffff +f0fdffe6f4ff2433508493b4395c822a72a43392c23799c02c8fac086c7b2b8c923f9999 +40908f0042487ab2c1336580426f993b659f3a65aa406ebc3666ba3a6cc13f6ab9415ea0 +4e67a94969b23b64b43463bd3a68c04266b44565ae4a6cb63d61ad4369b44160a06875a2 +f3f7fffefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffefffffcff00000c020300000200000300080a00010000 +0403090502090505030102001519020003000001000f0c1d000012000005ffffffffffff +fbfbfbfefefefffffffffffffffffffffffff9f9f9fffffff5f5f5ffffffffffffffffff +f9f9f9fffffffbfbfbffffffefefeffffffff9f9f9fffffff9f9f9fbfbfbffffffffffff +fefefe020202f0f0f0fffffff7f7f7f4f4f4fffffff8f8f8f3f3f3fffffff4f4f4ffffff +000000fafafaffffffebebebfffffff9f9f9fffffffdfdfdfbfbfbffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfecece4e2e6e7eaeff3edeef2eae8eb +e8e2e2f3e9e7fceeebefe0dbf8e7e0fbeae3f6e7e2fff1eeddd2d0fffcfaf3ebe9ede5e2 +f2e9e2ebe1d7fff7ede4dad0f8eee2fcf4e7ebe4d4f4edddeee8d8f2ecdcf2efe0f2eee2 +e5e1d5f6f2e7e3dfd6f3efe4f2eee2f4f0e4ede9dde3dfd3fcf8ece4e0d4fbf7ebefebdf +f4f0e4ebe7dbebe7dbf2eee2f0ece0eae6daf4f0e4ebe7dbefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeeadef1ede1efede1ebebdfefefe5e8ebe4eceee9949a98f9fffff8fffff1fbfff5ffff +f5ffff1b273d25314b1a2a4c122c5f14336a1436631a3e60052b401b414c0f3133203c3d +1d303653616e585f796c7199545990494e905a62ab4b5da73f60a5486aa74e5f934a5a8d +5167a14f6dad385da34b6eb2445e9b4f659e46609945629a3d5e944b6393989cc1fffbff +fffefffffffffffffffffffffffffffffffffffffffffffffffffff2f2f2ffffffffffff +f9f9f9fffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffefffdfafffffdfff4f5edffffedf9fde6f2f6e5fffffffcfcff +fffdfff2f3f5fffff4fcffeaf7fae7fffff8fefcfffffdfffffeffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fafafafffffffafafaffffffffffffedededfffffffafafaffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffafafafffffffafafaffffff +ffffffedededfffffffafafafffffff3f3f3fffffffffffff0f0f0fffffff5f5f5ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc8 +0030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfecece2ebf1ede1eae700030004050016130c +060000ddd3cafff2e9f6e5ddfeefe8eedfdae8dddbfffbfaddd4d7e6e0e4f1ebedf4ebe6 +f0e6ddebe1d8fdf3eaece2d9070000eee6dbfff9eee5dfd3fffdf3e8e4dbf8f4ebeee9e3 +f1ece6efeae6f5f0eae7e3d8efebdfeeeadefcf8ecefebdfe8e4d8f2eee2e4e0d4eeeade +ece8dcf5f1e5f5f1e5ebe7dbeeeadef4f0e4ebe7dbefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeade +f1ede1efede1ebebe1efefe7e8ebe4eaefeb949a98f9ffffe4ebf1f8fffff2fcfff7ffff +f7fffff5fdfff7fefff8fcfff8fbffe2e8fff7fefff2fafff8fffff8fdfff8fbfffefdff +a4a2ad676477837e9c6a658da2a0cf5c5c908b93c44b648d8ca6c95962839da2c2536186 +8399c24a6793819cc753658b9dabce5d70917a91b16781a28296b1757389f8f0fdfffeff +fffffffffffffffffffffffffffffffffffffffffff6f6f6fefefef9f9f9fffffffefefe +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffefffffdfffffefffffff6f2f5e0feffecfefff1f8faf9fcfffffafaff +fefffffefffafefff3f7f9ebfffff6f8f7fcfaf9ffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +eaeaeafffffff7f7f7fffffffffffffcfcfcffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffeaeaeafffffff7f7f7ffffff +fffffffcfcfcfffffffefefefffffffffffffbfbfbffffffe1e1e1fffffffafafaffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d3 +2064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeceddfe7efe0f2fded000500e2e6d5e7e8d6e1decb +251e0beee6d3f2e6d6f4ebdcf8eee4f1eae2e9e4e0fefaf7eeecedf3efeef6eeebe6ddd6 +f6ede6ece3dcfffbf4070000fffaf5d6cfc9fdf6f0f4ede7ece7e3040000efeae6f6f1ed +f4efece6e1ddfdf9eee5e1d5ece8dcefebdfdfdbcff6f2e6f8f4e8f3efe3f9f5e9e9e5d9 +ede9ddf5f1e5ece8dcf0ece0eeeadef0ece0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeebdcf1ede1 +efede1ebebe1efefe7e8ebe4eaefeb949a9af9ffffebf3f6f9fffff3fcffedf6fff8ffff +f9ffffeff5ffe1eaf3f7fffff8ffffecf5fcf8fffff8fffff9fffff8fffff8ffffeef8ff +ecf9fff4fffff0fffff1ffffe3f6ffeeffffedfffff0ffffe7eaf1fffeffeaf0fcf4ffff +eeffffebfefff2fcfff9ffffeaf7ffe3f6faeeffffeffefff0ecedfffcfbfffefdffffff +fffffffffffffffffffffffffffffffffffffffffffffffff9f9f9f8f8f8fffffff3f3f3 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffcfff3f1f48d8f84888b78797e6a858b7d797d7c83888e8d8f9b7f828b +797d7e7f817cbbbcb4e4e5ddfffffdfffeffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefeffffff +f7f7f7f8f8f8fffffff2f2f2fffffffbfbfbffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffefefefffffff7f7f7f8f8f8fffffff2f2f2 +fffffffbfbfbfffffff8f8f8fcfcfcfffffff9f9f9fffffff1f1f1ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f7 +1851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeceddde6ebd7dde5ce0b1000eaeed7f9f9e1fefce5dad6bd +080200f2ebd8f0e9d7f1ebddf0ece1f0ede4dfded9e4e3dfebeae6f1ece8fff9f3ede6e0 +f0e9e3ece5df060000e6dedbfffdfae2dad7ede5e2f4efec110c09e8e3e0ede8e5dfdad7 +f4efebece8ddf9f5e9f0ece0f0ece0fffff3ede9ddede9dde4e0d4f2eee2e1ddd1ddd9cd +f3efe3f2eee2f2eee2e5e1d5f0ece0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeebdcf1eedfefede1 +ebebe1eeefe7e8eae5eaefeb949a9ae7eff1f9fffff7fffff9fffff2f7fdfbfffff7faff +fbfffff9fffbf1fdf1f0faf2f9fffff7fcffeef3f9f2f6fff9fffff6fffff4fffff0ffff +e8fdfeeeffffdff8f2edfffdddf7eae4fbebf7fff8fffff8fffdfafffffdf9ffffebfaf7 +f5fffffefffdfcfdf7fbfffaf7fff8ecfff2f8fff8fffdf4fffcf6fffefbffffffffffff +fffffffffffffffffffffffffffffffdfdfdfffffffcfcfcfffffffffffffffffffefefe +f4f4f4ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffefffffeff8b8c84dfe2d7d5d8cddde2dbf8fefcdadfe5dce0ecdde0efe8eaf7 +d5d8e197969b5d5d5bfffffafffffafffffdffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedededfefefe +fefefeeeeeeefffffffffffff8f8f8ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffedededfefefefefefeeeeeeeffffffffffff +f8f8f8f2f2f2fffffffffffffafafafdfdfdefefeff8f8f8fafafaffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecddffffede6e8d2050500e5e5cdf4f2dbedebd4f3f1da060100 +f6f1ddf2efdcefecdd0d0b00030100010100fffff6dadad2f4f1ea040000040000f6f1eb +f1ece80c0703eae5e1f0ebe70d0804fffefaece7e304000017120eddd8d4efeae60c0701 +040000040000f7f3e7e7e3d7040000040000040000070300e8e4d8fffff3faf6eaf2eee2 +e3dfd3ebe7dbe8e4d8f4f0e4efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0eadcf1eedfefede1ebebe1 +eeefe7e8eae5eaefeb949a9af9fffff9fffffbffff0001040c10110001020000020c110b +00040000050012180af8fbf4fafafcfffdfffffdfffefdfff9fdfff5fefff5fffff4ffff +f1fffcf2fffaecfeeef4fff3f5fff1f7ffedfffdf4fff2ecfffaf7fefffaf5fff6f9fff8 +fffff8fffff6f7fbedf8fff2edfeebfbfff3fff5effff8f5fffdfdffffffffffffffffff +fffffffffffffffffffffffffffffff3f3f3fefefef8f8f8fafafafdfdfdffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +f7f5f6eeeced8a8a8af7f9f8fefffffafefffbffffeff6fef5fbfffbfdffe5e5fffcfcff +9d9aabf2f1f745453dfffff6fffffbffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffefefefffffffffffff9f9f9 +fffffffffffff0f0f0ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffefefefffffffffffff9f9f9fffffffffffff0f0f0ffffff +fffffffffffffafafaf9f9f9fffffffffffffffffffcfcfcffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecdde8e2d2e9e2d20b0500f4eedeebe5d5eae4d4ece9d8050200efecdd +e8e6d9030100f9f7ebdbdbcfedede1020200edede3030000f6f6eef1eee7030000e7e4dd +060300ece9e4040000eae5e1dbd6d0e5e0da130e08eae5dffcf7f1040000ece8dff7f3e8 +f1ede1090500f2eee2040000f4f0e4efebdff7f3e7070300c9c5b9ece8dcf6f2e6f2eee2 +fdf9edf2eee2dedaceefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff0eadcf1eedff0ece0ebebe1eeefe7 +e6ebe5eaeeed949a9af3fcfbf9fffff4fafa000100feffffdadad8fffffbbfc0baf9fff1 +c6cdbd777a6f060500fbf5f7fffcfffffcfff5f2fbfefefffbfffff5fdfff4fefde9f4ee +f5fff7f9fff6f9fff4f8fff1f3faeafffbf8fff9fbfff6f7fffffdfbfffbfcfffafffefa +fdf8f4fcfdf5f8fff3f7fff6fbfff8fffbfdfff5fbfffdffffffffffffffffffffffffff +fffffffffffffffffff6f6f6fffffffffffffffffffffffff4f4f4fafafaffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd +fffeff807f85fefeffeceff8fbffffdfe6ecf9fffff9fefff1f5fffbfafff8f6ffa9a6c3 +54525f55544f58584cfffffbffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffafafaf3f3f3fafafafefefeffffff +f6f6f6f3f3f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffafafaf3f3f3fafafafefefefffffff6f6f6f3f3f3ffffffffffff +f3f3f3f1f1f1fffffff7f7f7f5f5f5fdfdfdffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff1eae0f5e8e2f4e5e20a0000fff8f4e7dcd8fffdf8e9e2dc0b0600f5f2ede8e5e0 +0300000505000c090215120b030000f0ede4ddddd3080a00e1e1d7f5f5ebedede3010100 +0c0c04f0ede4eeebe4fffcf3f0ece3110d04dbd7ccf2eee3191208e3dcd2eeeadef8f4e8 +040000e0dcd0171307dcd8ccf9f5e9e2ded20c0800fffcf0f7f3e7e9e5d9e1ddd1eae6da +fbf7ebf8f4e8efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff0eadcf1eedff0ece0ebebe1eeefe9e6ebe5 +eaeeed949a9afbffffedf3f3fcffff000100c3c5c0f4f5efc3c3bbfefff9c4c9c5fbffff +7c7c7ccdc9c8060000fffcfdf5ebecfffcfdfffefdfffffdf0f2f1fcfffffeffffffffff +f8f6f9fcfcfcf3fdf5fefffdfeecfafff6fffff3fff8f2fefcfffff8fbfffff9fffffbff +fffdfffbfffff4fffffbfffffff0fffff6fffffcffffffffffffffffffffffffffffffff +ffffffffffffffffffecececfdfdfd050505f0f0f0171717fdfdfdfdfdfdffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f2f0fffeff +6d6b78fefdff8f90a48588979097a1727a85787e947376999c9acc7571a478739b08051a +c5c4bf545547fffffbffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffefefe0f0f0fffffffffffffdcdcdcffffff +fffffff9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffefefe0f0f0fffffffffffffdcdcdcfffffffffffff9f9f9f0f0f0ffffff +fffffffffffff3f3f3151515fefefef0f0f0ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001dc8002fd32064f71a51b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f5e8dff5e9dbefebdfeceddfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f1eae0f0e2dffff5f50a0000e4d9d7f8ececf1e7e5efe7e5040000eae6e3f3f0eb040100 +f2efeae4e1dae9e6dff5f1e8f1eee5edede1f7f7eb010100e0e0d4f7f7ed060600dbd8cf +0c0a00eeebe2f2f0e4e9e5da040000fefaeeddd9cd0d0700f1ebdfece8dcefebdf0a0600 +e9e5d9070300f7f3e7e6e2d6f9f5e9040000f9f5e9e4e0d4f4f0e4fbf7ebe5e1d5efebdf +f2eee2efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfedebdcf0eedfefede1ebebe1edefeae6ebe7e7f0ef +919b9cf7fffffcfffff6f4f7040000fffdfbcac5c1fffff8c5c8c1fcffffc1c5c6888687 +8f8b8a8f8785070000fffcfafbf3f0fffaf6fcf8f5fffffdf3f3f301000209060d030007 +fffdfffcffff0000050e00110a000e08000d060210fefeff00000904000b04000b05020d +000007f8fffff5f7fffff8fffff8fffffcffffffffffffffffffffffffffffffffffffff +fffffff4f4f6fffffff3f3f5000002ffffff000002f2f2f4fffffffffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfcfef9feffff878392 +fffbff807a960d0723c6c4dc14142e080b2c181b4602053c06073d1b1a46010019fffeff +54544cfffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffff000000fffffff6f6f4fffffffbfbf9fbfbfb +fffffdfffffffffffdfffffffffffdfffffffffffdffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffff000002fffffff6f6f8fffffffbfbfdfbfbfdfffffffffffffffffff4f4f6 +fffffff6f6f8000002ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001cc80433d71c60f32057bedee7fff4ebe2edf0dfeaefdb +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeeecdfebeddfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f7f0e6eee5dc060000fffaf0f3ece4e9e2d80e0a01e6e2d7f7f3eae4e0d5050100e5e1d6 +faf6ebeae6db090500e3dfd4030100fefcefe2e0d3030100ebe9dd030100eeeadfefebdf +040000f8f4e8e8e4d8040000e5e1d5fffff3040000ede9ddf1ede1e9e5d9040000f6f2e6 +040000ede9ddf1ede1ece8dc0a0600dedacefaf6eae9e5d9f7f3e7e8e4d8f9f5e9eae6da +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecdfeaecdeecf0e1eceee3e9ece3ebf0ece3ece9e2f2f18b9d9d +f7ffffe9eaeffff9ff120002d7b9c1fff9fbc9ccc5f7fff6c0c3bafffff8d1cec7fbf6f2 +c7c2be060000fffdfbf9f3f3fffefdf6f2f3fffeff010002fffefffcfbfffcfbff040309 +f9fafefffefffffcfffbf5fffffdff000005fcfbfffffefffffefffffdfffaf9ff010207 +fcfffff9f9fffffbfffffbfffaf7fffffeffebeaeffffefff5f4f9fffefff6f5fafffeff +faf9fefefdfffffeff000004fffeff000004fffefffffffff8f8f6fffffbf1f1effefffa +fffffdf6f7f2fffffdf7f8f3fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfefffbf9fffbfbffff86838cfff7ff +8b73971e04311500301e10450502390f144c000a40041040070f3600001bfffcff534d57 +fdfafffffefff9f8fdfaf9fefffefff0eff4f9f8fdfffefff9f8fdfffefffffefffbfaff +f6f5fafffeffefeef3fffffffffffd060702fafaf8fffffbf9f9f7fffffbf4f4f2fffffb +fffffdf8f9f4fffffdfbfcf7fffffdfafbf6fffffdf0f0eef8f8fafffefffdfcfffffeff +fcfbfff9f8fdfffefffaf9fefffeffeeedf2fffefffffefff3f2f7fffefffffefffcfbff +faf9fe030207fffefffefdfffffefff1f0f5faf9fefffefffdfcfffffefffcfbfffcfbff +fffeff08070ce5e4e9fffefffffefff2f1f6fffefffefdfff8f7fcfffeffecebf0fffeff +fffefffffefffffefffffefffffefffffefffffefffffefffcfcfefdfdfffefefefdfdfd +fcfcfcfffffff9f9f7fffffdffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001cc80433d71d5ff32057bee0e6fff4ebe2eeefdfeaefdbeeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0ece0 +f7f3e7040000040000040000070300f5f1e5e8e4d8f4f0e4eeeadefbf7eb0d0900040000 +0b0700eae6dafffff3f7f3e70400001a160aece8dcf6f2e60d0900e3dfd3efebdff4f0e4 +090500e5e1d5ece8dc181408c7c3b7fffcf00c0800040000130f03dedacef4f0e4040000 +0400000a0600060200e4e0d4fffff3e6e2d6efebdff9f5e9dcd8ccefebdff4f0e4efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecdfeaecdeecf0e1ebeee3e7ece5eaf0ece1ede9e0f3f18a9e9df5ffff +fffefffff7ff170004fff4ffd1bec0eef5eebccabdfefff6cbc8bff3f0e9e1ded9fffefa +030000faf4f4fffefdfffcfdfffdfffffeff010004fffefff8f7fcfeffff000004fffeff +f6f5fafffeffffffff000002fffffff1f1f1fefefef9f9f9fefeff050507f8f7fcfdfcff +fcfbfffffdfff9f7fffffeff0000040f0e14010005111016fffefffffefff2f1f608070d +06050a000005000004fffeff000004000005000002070707eaebe6fffffdf4f5f0fffffd +fffffbf5f5f3fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfcfffff7fffff1fbfd858086fff8ffa2869c +fff2fffff2fffeebfffcf6ffeef3ffeefcffe6f6ffe7f0ff050922efecf74d474bfefcff +faf9fefffeff0302070000050a090efffeff000004030208fffefff4f3f9fdfcff0a090f +050409000005f7f7f9f0f0f0000100fffffdf2f3ee0e0e0cf7f8f3fffffd000100010100 +000100fffffdfffffb000000000100000000171715fffefff9f8fdfcfbff020106000005 +07060bfffeff03020703020808070c000005f0eff4fbfafff8f7fcfefdfffefdfffffeff +00000403020807060b000005fffefffaf9fff9f8fd0000050c0b10000005fefdfffffeff +07060bfffefffbfaff000005fffefffdfcfffffefffffeffecebf0fffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffffffbfbfdfffffff0f0f0fdfdfd +fafafafffffdf2f2f0fffffffffffffffffffffffffffffffffffffffeffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001cc80433d71d5ff32057bee0e6fff4ebe2eeefdfeaefdbeeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfe6e2d6e6e2d6 +f7f3e7fdf9eddcd8ccf4f0e4f1ede1efebdfe7e3d7f3efe3e8e4d8e6e2d6f2eee2f7f3e7 +e6e2d6e3dfd3ece8dcefebdfe5e1d5f1ede1e1ddd1e8e4d8fffff3ebe7dbeae6dae8e4d8 +fffbefeae6dae7e3d7fffcf0ebe7dbe2ded2ede9ddeae6daf8f4e8eeeade1c180cece8dc +e4e0d4f7f3e7f5f1e5e7e3d7e2ded2f7f3e7f5f1e5ece8dcf5f1e5e3dfd3efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff0eadcf1ede1eceee3e7ede3e8f2eae1ede9e0f3f18d9d9cebf6f8feffff +fffbff817078cfc0c5fffefbc2cdc5f5fffac2c4bffffffbd1d0ceefeeecccc8c7060503 +fffdfcf2f1effffffdf9f7f8fcfafbfffeff000004000004000004fffefffdfcfffffeff +fcfbfff2f2f4161616f9f9f7fdfdfbfffffdfffffdffffff040404e1e1e3fffefffffeff +f8f7fdfffefff8f7fc0e0e10f9f8fdfafafcfbfaff000002f3f2f7121214fffefff2f2f4 +fffeff000002f0eff4000002fffeffffffffffffff000000f9f9f9fffffdf2f2f2f4f4f2 +fffffff8f8f6fdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfb +fdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfb +fdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfdfdfb +fdfdfdfdfdfbfdfdfdfdfdfbfdfdfdfafdfff4fcfff8ffff7f7d80fdf0e7978271fff4ea +e5d0d72f203feee8fff5f7ff0b1364f0faffd2dbff0d1321ffffef55553dfffffaffffff +f7f6fb050507fffeffffffff000004fffffffffeff000002fffefffafafcf5f4f9ffffff +fffeff060608ffffff000000ffffff000000f7f7f7fffffd000000fffffdf6f6f6fffffd +000000ececea0d0d0dfffffdedededf2f2f2000002ffffff020106ffffffefeef3ffffff +fdfcff000002faf9fefffffffdfcff0c0c0efffefff9f9fbfffefffffffffaf9fe000002 +fffefffffffffefdff020204fdfcfffffffffffefff7f7f9fffeff070709fdfcff000002 +fffeff000002fffefffffffff6f5fafdfdfff3f2f7fffffffffefff8f8fafdfcfffdfdff +fdfcfffdfdfffdfcfffdfdfffdfcfffdfdfff3f3f5f9f9f9fffffffffffffffffdf9f9f7 +fffffdfffffdfffffffffffffffffffffffffffffffffffffffeffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001cc80433d71d5ff32057bee0e6fff4ebe2eeefdfeaefdbeeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff5f1e5fffcf0eae6da +e0dcd0f6f2e6eeeadee8e4d8f7f3e7f0ece0f8f4e8eeeadeeae6daf2eee2f6f2e6f0ece0 +f8f4e8e8e4d8fcf8ecfaf6eaf4f0e4e6e2d6efebdfdedacef2eee2eae6daf0ece0e6e2d6 +eeeadef4f0e4ece8dcf1ede1f8f4e8f3efe3ede9ddf5f1e5ebe7db040000ece8dce4e0d4 +ebe7dbe7e3d7e7e3d7f8f4e8f0ece0e1ddd1f3efe3faf6eae8e4d8efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f1ebdff2e8dcf4ecdfefede1e9ece1e8f2eae1eee7e2f2ef8e9c9cf8fffffcfffffffeff +908c8dfffffdb8bfb8f5fffabacac0f9fdfec1c0c5fffeffbdbdbffffdfe050505f8f7f5 +fffffdf3f2f0fffffdfcfbf9010000fffffff7f6fbfbfaff000004f3f3f5fffffff0f0f2 +020202fffffdfffffbfdfef9f9faf4fffffb000100fffffdfffffdf4f4f6f5f5f7fffeff +ffffffffffff000000fffffffefefeffffff070707f8f8f8000000fffffff6f6f6ffffff +000000efefef090909fffffff3f3f3fcfcfc000000fdfdfdfffffffffffffffffffafafa +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffcfffff7ffffecf4ff8d8c88fffeed817056fffbe646332d +504452fef9ff080a43aab4f2131e54e2ebff000508ffffe95a5b3cfefef4f3f3f3ffffff +000000fffffffefefe000000ffffffffffff090909f0f0f0ffffff030303000000060606 +000000ffffff000000030303f7f7f7fcfcfcffffff000000000000050505000000070707 +fafafa010101fffffffcfcfcffffff000000fafafa050505000000fbfbfbffffffececec +111111fffffff8f8f8ffffff000000fcfcfcfcfcfcf5f5f5ffffffffffff020202fbfbfb +f4f4f4ffffff000000ffffffffffff000000020202000000000000f5f5f50d0d0d000000 +fffffff6f6f6f8f8f8fffffffffffffcfcfcfffffffdfdfdfefefeffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffde9e9e9fcfcfafffffdfffffdfefefc +fffffdfffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001cc80433d71d5ff32057bee0e6fff4ebe2eeefdfeaefdbeeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfece8dcdedacefffff3e8e4d8 +f4f0e4eae6daf4f0e4ebe7dbf8f4e8e2ded2eeeadefffef2eae6dae4e0d4ece8dceae6da +f3efe3e0dcd0d7d3c7efebdffffff3f0ece0dedacefdf9edfcf8ecf1ede1e8e4d8ede9dd +efebdfeae6daeae6dae8e4d8dfdbcffffff3e1ddd1f4f0e4ece8dce4e0d4fffff3f1ede1 +fffcf0eeeadeefebdfede9ddf2eee2f1ede1e4e0d4f3efe3efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdd +f4e8daf7ebddf2ece0ebebdfeaf1e9e1eee5e3f2ed909c9af9ffffeff3f6f4f5f7fcffff +88938df2fff86c807481928ac1c6ccfefeffc0bec9f9f9ff929196fefffff1f1f1f7f9f6 +fffffbfffffbfbfcf7000000f6f4f5fffefffffeff010002fffffff2f2f0fffffd13140f +eeefe9f7f8f0fffff8fffff8fffff8050600fdfef8f0f1ebfffffdfffffdfffffff7f7f5 +fbfbf9080904fffffbf3f4effffffb000100fafbf6070803f4f5f0fffffbfffffb000100 +fffffb000100ecede8fffffbfdfdfd171717ffffffefefefffffffffffffecececffffff +fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc +fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc +fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc +fcfcfcfcfcfcfcfcfcf9fefaf8fffaeffaec7b7b6ffffdf494817bfff7f6feebef2c2129 +ededf7f8ffff36444d485a5edce8e8000300fffff6525044f8f7f2fffffbf1f2ed020300 +fffffbedeee9000100fffffbf2f3ee070803fffffb000100fffffbfffffbfafbf6080904 +f2f2f2020202ffffff000000ffffffffffff000000fffffffffffff3f3f3fffffffafafa +000000fdfdfdfffffff5f5f30b0b09fffffbfefffafffffb040500000100f8f9f4000100 +fffffbf7f8f3fffffb000100f5f6f1fffffbfffffbf9faf5fdfef9000100fffffbfffffb +f4f5f010110cf6f7f2060702fbfcf7fffffbf5f6f1010200fffffb0c0d08fffffb000100 +fffffbfffffbf3f4eff7f8f3fdfef9fffffbf0f1ecfffffbfcfdf8fcfdf8fcfdf8fcfdf8 +fcfdf8fcfdf8fcfdf8fcfdf8f7f8f3fffffbf8f8f6fffffdfffffdfffffdf1f1f1ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc8 +0433d71d5ff32057bee0e6fff4ebe2eeefdfeaefdbeeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff5f1e5ede9dddfdbcffffff3e9e5d9 +e9e5d9f2eee2f2eee2e8e4d8fcf8ecf9f5e9d8d4c8ede9ddf4f0e4fdf9edf9f5e9ebe7db +fcf8ecfefaeef9f5e9e3dfd3ede9ddfdf9ede7e3d7eeeadee8e4d8fffcf0fbf7ebe4e0d4 +ece8dcf6f2e6faf6eafdf9eddad6caf7f3e7ece8dcece8dcefebdfeae6dae1ddd1e5e1d5 +e6e2d6e7e3d7ede9ddfdf9edf1ede1ddd9cdf2eee2efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf1eada +f5ecdbf6eadef0e9dfedf0e7e3ede5e3f2eb8e9d98f4fafafcfffffeffffedf3f1f7fffd +75867cf4fffa85948dfbffffc0bfcff0effd9f9fa9e9eaeff5f9fafefffffefffdeaece7 +fefffbf4f5f0010200fffffdfefcfdebe9ec131114f3f2f0fffffb040500f6f7f1fbfcf4 +fffff6fffff6fefff3000200fdfff2fffff6fefff5fffffafffffa000100fffffafffffa +000100fffff8fffff8f6f7ef0a0b03f6f7ef060700fffff8fcfdf5fffff8000100f6f7ef +0f1008fffff8fffffafffffb000000fffffdfffffdf7f7f5f6f6f4fffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfefff8f0fce6fbffed898a7afaf1ea9f8d8df2dee0f0e0e1f6eceadbddd2 +f9fff3daecd6c9dbc5f8fff3070f02fffff857544ffffff8eeefe7fefff7070800fdfef6 +fffff8000100fefff7fffff8000100fffff8010200edeee6fffff8fcfdf5000100fffffb +020200f3f3f1f8f8f6000000f1f1ef000000eeeeecf1f1effffffd000000fffffd010100 +fffffdfdfdfbfffffb000100fcfdf5fdfef6f3f4ecfffff8040500fffff8020300f8f9f1 +f6f7effffff8000100f4f5edfffff8000100fffff8fffff8000100f2f3ebecede5fffff8 +000100fffff8000100fffff8f6f7effbfcf414150dfafbf3000100f2f3ebfdfef6000100 +fffff8fffff8fafbf3fffff8eeefe7f8f9f1fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fbfcf6fffffafffffaf6f7f2f1f2edfffffdffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc80433d7 +1d5ff32057bee0e6fff4ebe2eeefdfeaefdbeeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff2eee2fefaeeeeeadedbd7cbeeeadef2eee2 +f3efe3e9e5d9efebdfefebdfede9ddfffff3e1ddd1f4f0e4e8e4d8e3dfd3ebe7dbefebdf +e9e5d9eeeadeeeeadee9e5d9f0ece0ece8dcf8f4e8e5e1d5f0ece0efebdfe6e2d6f2eee2 +f0ece0e1ddd1e0dcd0f8f4e8fcf8ecdedacef7f3e7ece8dcf4f0e4f7f3e7f0ece0fefaee +f6f2e6e9e5d9e6e2d6ebe7dbf3efe3f6f2e6efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddebedd8f3eedb +f9e9dcf7e6def4ede5e6ebe4e2f3eb8d9e98f9fffffffffff3eef2fffeffeff5f1f8fffb +f8fffaedf8f475798588899b818392f3f5fffcfffff2f7fafcfffffcfffdfcfffbf0f5ee +fefffbf6f7f20c0b09030102030002fcfafbfffffb010000010100040400040400060700 +010200070800010200010200030400020300050500010100010100090900070700010100 +0101000101000707000101000a0a000101000202000101000101000707000d0d01010100 +06060001010005050001010001010001010001010016160e050500010100010100010100 +010100010100010100010100010100010100010100010100010100010100010100010100 +010100010100010100010100010100010100010100010100010100010100010100010100 +010100010100010100010100010100010100010100010100010100010100010100010100 +010100000200020b000005000f10000700000b00001f0e040a00000b06000e1000000600 +000e00041200000600010800010200030100010100010100111105010100010100010100 +0404000101000a0a000101000202000101000202000303000d0d01040400040400010100 +01010014140c02020005050014140c010100020200010100010100010100010100010100 +0606000101001111070101000101001515090101000b0b00010100030300060600111105 +0101000505000c0c000101000101000404000a0a00010100101004030300010100030300 +0101000101000101001212060808000101000909000101000202000a0a00010100020200 +040400010100010100111105010100020200010100010100010100010100010100010100 +01010001010007090000010000010012130d080904e0e0deffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001cc80433d71d5ff3 +2057bee0e6fff4ebe2eeefdfeaefdbeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfebe7dbe8e4d8f0ece0f9f5e9f1ede1eeeadeebe7db +f9f5e9ebe7dbf5f1e5eae6dae8e4d8f1ede1f6f2e6ece8dcf2eee2f8f4e8e4e0d4fdf9ed +efebdfefebdfe8e4d8fffcf0e8e4d8e9e5d9f8f4e8efebdfebe7dbf7f3e7f2eee2eae6da +f8f4e8fbf7ebdbd7cbefebdff2eee2ece8dcf2eee2ede9ddeae6daf0ece0e9e5d9e5e1d5 +f5f1e5f2eee2efebdffcf8ece9e5d9efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddde4f0d8edf1dafde7da +fee3dcf9eae5e9eae4e0f4eb89a098f2fbfafffefffffafffbeef5fffefdf8faf5fdfffa +fcfffffefefffcfbfffefefff5f8fffbfefffbfffff9fffdf8fefafbfffafcfffbeff1ec +fefffbfffefcf2f1effffefff9f5f4f1f0ec0d0d05fffff5f3f3e7fffff3f4f5e5fffff1 +ffffefffffeff9fae8ffffeffffff1eeefe1fffff3fffff4f6f6eafcfdeffeffeffeffef +fbfcecfeffeffafbebfdfeeefffff1fffff1f5f6e6fffff1fbfcecf2f3e3fffff1fdfeee +fbfcecfefff1fdfef0fffff3fffff3fffff3f3f4e6f9faecfffff3fdfef0fdfef0fdfef0 +fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0 +fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0 +fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0fdfef0 +fcfef1f6fbf4f7fcf5fffff3fffce9ffffe6fef5d8ffffe3ffffe4fbfde5feffedfaffee +f1fde9fbffefeff4deffffecffffeafafbe9fffff1ebecdcfffff1fffff1fffff0feffef +feffeffbfcecfffff1fcfdedfffff1fffff0eeefdffffff0feffeff7f8eafffff3fffff2 +f3f4e6f7f8eafffff3eceddffffff3fafbedfffff3f7f8eafdfef0fafbedfffff3f9faec +fdfef0f3f4e6fffff1fcfdedfbfcecfffff1fbfcecfffff1fafbebf8f9e9f9faeafcfded +fffff1f5f6e6fffff1f4f5e5fffff1f4f5e5fffff1fafbebf9faeafffff1fffff0fafbeb +fffff1fdfeeef7f8e8f6f7e7fffff1feffeffbfcecfffff0f6f7e7f8f9e9fffff1f2f3e3 +fffff1feffeffdfeeefeffeffeffeffdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeee +fdfef0f4f6e9fffff6f9fbf0eeefe70d0e08fffffbfffffffdfdfdffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bc +e2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeaeeddddf4d7e6f4dafee6daffdfdc +ffe7e5ece9e4def5eb86a198e9f3f2fffcfffff7fffff7fffaebf0fffcfdfffdfdfffefd +fffefff8f7fcfffefffcfdfff6faf9fbfffefbfffdedf3effbfffdf0f5f1fefffdfefffd +fcfbf9fffffdfffefdf7f3f0fffffa010100fdfdf3fffff4f9faecfffff1fdfeecfdffea +ffffedffffeceff1dcfeffebf4f5e3ffffeffffff1f9faeafdfeecfdfeecfdfeecfdfeec +fdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdffea +fdffeafdffeafdffeafdffeafdffeafdffeafdffeafdffeafbfde8ffffedf2f4dfffffed +fdffeaffffecffffedf1f3defbfde8ffffecfeffebfcfee9f2f4dff4f6e1fcfee9ffffed +fdffeaf1f3defeffebffffedf9fbe6ffffedfeffebf2f4dff8fae5ffffedfcfee9ffffec +f9fbe6ffffedf9fbe6ffffedf6f8e3ffffedeaecd7ffffedffffecf7f9e4ffffedf6f8eb +f9fcfffbfcfffdfdf3fffee5ffffd7ffffd1ffffd3ffffdcfffee9fcfef1fbfdf8f9fef8 +f9fff3fbffeafdffe0fdffe0fdffe7fdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeec +f2f3e1feffedffffeff9fae8ffffeffeffedf1f2e0fdffeaffffedeff1dcfafce7ffffed +eff1dcfafce7ffffedfeffebfdffeafdffeafdffeafdffeafdffeafdffeafdffeafdffea +fdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeec +fdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeec +fdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeec +fdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeecfdfeec +fffff1f1f3e5fffff4fffff6000100fffffbfcfcfcfffffffffffffffefffffefffffeff +fefefffefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8ff +f4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfe8efddd9f6d7e3f6daffe5dcffdedcffe6e5 +ede8e4def5eb84a29af9ffffe6dce4fff2ffffeffcfffafffffbfff9edf1fffbfbfffbf5 +fffff6f7f7effffffafefffafcfffbe9eeeafbfffdf9fffdfbfffffefffff9fbfaf7f6f4 +faf9f7fffdfdfffefbfffff8010100fdfdf1fffff3f9faeaffffeffdffeafdffe9f1f3dd +f6f8e0ffffecfdffe9fbfde7ffffedffffedf7f9e4fdffeafdffe9fdffeafdffe9fdffea +fdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffe7 +fdffe5fdffe5fdffe5fdffe5fdffe5fdffe5fdffe5ffffe8ffffe8fdffe5fdffe5feffe6 +eef1d6ffffe8ffffe8ffffe8f1f4d9f7fadfffffe8ffffe8ffffe7f8fbe0f0f3d8fbfee3 +ffffe8ffffe8f8fbe0f4f7dcf7fadfffffe8ffffe8ffffe8f8fbe0f1f4d9ffffe8ffffe8 +fbfee3f3f6dbffffe8ffffe8f9fce1ffffe8ffffe7f4f7dcffffe8e7eacffffff0fbfcfe +fbfcfffdfdf3ffffe7ffffdaffffd5ffffd7ffffdcfffee7fffdeefdfdf5fcfdf5fcfef1 +fcffeafcffe3fdffe1fdffe7fdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9ffffed +ffffecf7f9e4f4f6e0f8fae5ffffecffffedfbfde7f7f9e1ffffe8f5f8ddf7fadfedf0d5 +ffffe8e8ebd0f6f9defdffe5fdffe5fdffe5fdffe5fdffe5fdffe5fdffe5fdffe7fdffe9 +fdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffea +fdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffea +fdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffea +fdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffeafdffe9fdffeafdffeaffffef +f3f6e5fffff3fdfff4000100fffffbfbfbfbfffffffffefffffefffffefffffeffffffff +fefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2 +e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfe8efddd8f7d8e2f6dafee6dcffdedeffe6e7ece8e5 +def5ed86a19cf6f9fefffafffeecfafff9fff6f1f8f9f4fafffaffffefeffffeecfffee4 +ffffeaffffedf3f4e6fffff8fbfffafcffffecf2f2fbfffff1f2f4fefffffffefffbfaf8 +fffaf7fffefafffff8030000fffdf1fffff3fbf9eaffffeffffeeafffee9ffffeaf7f7dd +ffffeaffffe8f6f6defbfae5faf9e4ffffecfffee9ffffe7fffee9ffffe7fffee9ffffe7 +fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3fefee2f1f1d5ffffe6f3f3d7fdfde1ffffe6 +f2f2d6ffffe6fcfce0ffffe6fafadeffffe5ededd1ffffe6ffffe6ffffe6f0f0d4ffffe6 +f2f2d6ffffe5ffffe6fafadefbfbdfffffe5ffffe6fdfde1ffffe6ededd1ffffe6fbfbdf +ffffe6e9e9cdfafadeffffe6f1f1d5ffffe6f7f7dbf7f7dbffffe6fcfee6fcffecfcfef0 +fdfdf1fffdf0fffdeefffdecfffde9fffee5fffee1ffffe0ffffe1ffffe3fdffe9fcffec +fcfef1fdfdf1fdffeaffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7ffffebfbfbe3 +faf9e4ffffeaffffebf2f2daffffecf0f0d8f8f8dcfafadeffffe6ffffe6ffffe6f2f2d6 +ffffe6ffffe6ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe7ffffe7 +fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7 +fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7 +fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7 +fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9fdffe9ffffedf6f9e6 +fffff3fafcef020300fcfdf8fefefefffffffefdfffffefffffefffffefffffffffefefe +fffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eada +ebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfe8efdddbf5d8e5f5dbfde6deffe0dff9eae7e8eae7def5ef +8a9e9dfffdfffffafffdf7fff9fefff0ffff0004050800041200000e00000e06000b0600 +060300040200fffff3fefffafcfffffcfffffcfffffafbfffcfdfffffefffdfcfafffbf7 +fffef8fffff8030000fffdf1fffff3fbf9eaffffedfffeeaffffe7fcfce4f7f7ddf2f2d8 +ffffe8fcfce4ffffeafbfae5fcfce4ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3efefd3ffffe6f6f6daffffe6fefee2fcfce0fefee2 +ffffe6f7f7dbffffe5f6f6daffffe6fbfbdfffffe6fcfce0f6f6daffffe6ffffe6fbfbdf +fdfde1ffffe4fcfce0fcfce0ffffe6f7f7dbfafadeffffe6ffffe6f6f6dafcfce0ffffe6 +ffffe6f8f8dcffffe6ffffe5ededd1fefee2fefee2ededd1ffffe3fdffe3fdffe7fdfeee +fdfdf1fdfdf5fffcf5fffcf0fffde9fffee1ffffdcffffdaffffdeffffe5fdfeecfcfdf5 +fcfdf5fdfeecffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffeafcfce4fcfce4 +ffffe8fdfde5fbfbe3ffffeaffffe8ffffe6ffffe6eaeacef9f9ddf0f0d4fafadeffffe6 +ebebcfffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe5ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7fdffe7feffeaf9fce7fffff1 +f9fbee060700f1f2edfafafafffffffdfcfffffefffffefffffffffffffffefefefffffd +fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dc +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfebeedde3f1daeaf2dbf9e8def8e5dfefeee9e1ede9e0f3f1909b9f +fff9fff7ecfcf2ffffe2ffffd9ffff001a14fffcfffff7f2f6e6b5fff4b2ffffc8ffffd4 +0a0700030200f3f4eefcfdfff6f9fff2f4fffefefffafaffeceaedfffffdfffefafffaf4 +fffff8030000fffdf1fffff3fbf9eaffffedfffeeaffffe7f7f7dfffffe8fbfbe1fefee4 +f3f3d9fdfde3ffffeaececd4ffffe7ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe8ffffe7f5f5dbf7f7ddfafae0ffffe8f7f7ddf9f9df +ffffe8f4f4dafdfde3fafae0ffffe8eaead0f8f8deffffe8f9f9dff5f5dbffffe8fbfbe1 +ebebd1ffffe8ffffe8fbfbe1ffffe8f9f9dffdfde3f5f5dbffffe7fcfce2ffffe7f4f4da +ffffe8f0f0d6ffffe8ffffe8f9f9dfffffe8ffffe8fefee4ffffe3fdffe5fdffe9fdfeec +fdfeeefdfeeefffdecfffde7fffde3fffee0fffee0fffee1fffee5fffeeafcfef0fcffee +fdffe9ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5fbfbe1ffffe8ffffe8ebebd1 +fbfbe1ffffe8f5f5dbf9f9dff9f9dfffffe8ffffe8ffffe7ffffe8f8f8deeeeed4ffffe8 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5fdffe7fdffe7fbffe8ffffeff7f9eb +050700d7d8d2e6e6e6f6f6f8fbfafffdfcfffffefffffffffffffffffffffffffdfffffd +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecddebecdaf0efddf6e9e0f0e9e1e4f4eadaf1e9e2f2f29598a1fff7ff +fffaff001b1c00170c00210f001609000009fff8f1ffffc3f4e894ffffb8d4cb92080300 +ffffea0a0a02fcfbfffefefff0f2fffefdfffefefffffefffffffdfffef7fcf8effffff8 +030000fffcf3fffff3fbf9eaffffeffffeeaffffe7ffffe7fbfbe1ffffe8ffffe6ffffe8 +f1f1d7ffffeaffffeaffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe7fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fcfbe6f2f1dcffffecffffecffffecfcfbe6ffffecffffecfaf9e4 +ffffecfffee9ffffecfefde8ffffecffffecffffecffffecf3f2ddffffeaffffecfffee9 +ffffecfefde8f8f7e2ffffecffffecffffecf7f6e1ffffecfcfbe6ffffecffffecffffeb +f4f3def7f6e1ffffecfefde8fbfae5f4f3defafae2ffffe1ffffe1fdffe5fcffe7fcffe9 +fcffeafffee9fffde7fffde5fffde3fffde3fffde3fffee5ffffe7fcffeafcffeafdffe7 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5f8f8defefee4ffffe8ffffe5ffffe8 +ffffe6f3f3d9ffffeaffffecf4f3deffffecfffee9efeed9ffffecffffebffffecfffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9ffffe7ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe9fdffe8ffffedf6f9e8000200 +b4b5afc7c7c7e2e2e4faf9fffcfbfffffefffffefffffffffffffdfffffdfffffbffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff1ebddf4e8daf7ebdff3eae1e7ede3daf9ead3f4ebe3f1f49c94a1ffe7fefffbff +00120e6ad1bc007a5e7eddc900040d5e433a5e4a03ffffa5f0e490ffffc10f0700fff9df +f5f2e906050af0effdfcfdfffaf9fffefefffffefff0efebfffff6fffff4fffff6040000 +fffcf3fffff3fcf9eaffffeffffdeafffee7ffffeaf7f5dcffffe8ffffe6f1efd6ffffe8 +eeecd5f7f5defffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5 +fffee5fffee5fffee5fffee5fffee5fffee7fffdecfffdeefffdeefffdeefffdeefffdee +fffdeefffdeefffff1fcf9eaf2efe0fffff1eeebdcf9f6e7fffff1f4f1e2fffff1fffced +fefbecfaf7e8fffff1fcf9eafbf8e9f4f1e2f2efe0fffff1fcf9eafffdeefffff1f0edde +fffeeffffff1f2efe0fffff1f9f6e7f2efe0fffff1fefbecf2efe0fffff1fbf8e9fffff1 +fffff1dedbccfffff1fffff1110e00fffee9ffffe0ffffdcfdffe0fcffe1fcffe5fcffe7 +ffffe7fffee7fffce5fffce3fffce3fffce3fffde3fffee5fcffe7fcffe7ffffe5fffee5 +fffee5fffee5fffee5fffee5fffee5fffee5ffffe8ffffe6f0eed5ffffe8fffee5fcfae1 +ffffe8f2f0d9fbf8e7fffff1f3f0e1fffff1fcf9eafffff1f3f0e1050200fffdeefffdee +fffdeefffdeefffdeefffdeefffdeefffdecfffee7fffee5fffee5fffee5fffee5fffee5 +fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5 +fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5 +fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5 +fffee5fffee5fffee5fffee5fffee5ffffe5feffe6fbffe6ffffedf9fceb0002009b9c96 +b1b1b1d9d9dbf9f8fefcfbfffffefffffefffffffffffffdfffffdfffffbffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1eae0f2e9e2f2e9e2f1eae0 +efebdfeeecddeeecddeeecddeeecddefebdfefebdff1eae0f1eae0f1eae0f1eae0efebe0 +f1ebdff1ebdff1ebdff1eae0efebe0efebe0efebe0efebe0efebe0f1ebdff1ebdff1ebdf +efebe0efebe2eeebe2ecece4ecece4eeece0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f3e9ddf9e5dafce8ddf4eae0e6eee3dcf8ecd5f2ede7eef49f92a3fff4fff4f5ff00180f +1a92774fdcba107e65000709fffbedffffbdf9e58cffffb8eeda9f0d03000604000a0900 +0000000a0b1deeeefffffcfffaf9fffcfffbeff2e9fffefffcf3f6fffefb030000fffcf1 +fffff3fcf9e8ffffedfffee9ffffe70402000808000402000303000e0c00ffffeaf3f1da +ffffeafffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffeeafffdecfffdeefffdeefffdeefffdeefffdeefffdee +fffdf0fffbef0301000f0b000301000e0a00fdfbee0400000907000400001a180bf8f4e8 +fbf9ecfffff30301000501000907000e0a00f1efe2fffef2faf8ebfffff3f0eee1fffff3 +f6f4e7fffff3fffff2fffcf0030100fffef2fffff2fffcf0030100fffff3fcfaedfdf9ed +fffff3f8f4e8fffff3040000ffffefffffe3ffffe0fdffe1fcffe5fcffe7fcffe9fdffea +fffdeafffce9fffce9fffce7fffde7fffde7ffffe7fcffe9fcffe9fffee9ffffe7fffee9 +ffffe7fffee9ffffe7fffee9ffffe7f7f5e0ffffeaf1efdaffffeafbf9e4ffffe9f2f0db +0d0c00040100030100110d01030100fdf9ed030100fffef2030100fffcf0fffdf0fffcf0 +fffdf0fffcf0fffdf0fffcf0fffdecfffee9fffee5fffee5fffee5fffee5fffee5fffee5 +fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5 +fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5fffee5 +fffee5fffee5fffee5fffee7fffee5fffee7fffee5fffee7fffee5fffee7fffee5fffee7 +fffee5fffee7fffee5fffee7ffffe5fbfee3f9fde4feffecfdffef03050091928cababab +dbdbddf8f7fcfbfafffffefffffefffffffffffffdfffffbfffffbfffffdffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff2e9e2f6e6e7f6e6e7f3e8e4efebdf +eceddbeaefd9eaefd9ebeedbeeecddefebe0f2e9e2f2e9e4f2e8e6f2e9e4f1eae4f2e9e0 +f5e8dff6e9e0f1e8e1f4ede7f6f1edede8e4e6e1dbf0e9e1f2e9e0f3e9e0f2e9e0f1eae4 +eeeae7ebebebe7ecefe8ecedecece4efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff3e9dd +fce4d8ffe6dbf9e8deeeeae1e7f2ece1ededeeeaf89f92a6fff8fff0ffff001a115cd7bb +0089655dcfae001d13f8f9e7ebdba8fffcc36c401bfff8d4e1d8a1ffffcdf3f5cdfffff3 +000015fbfbfffffbfff6f6f4f5ffec000900fffafffff3fffffcff010100fffdf1ffffef +fbfae5ffffeaffffe7fdffe7f3f2ddffffed111000f5f6e4ffffedffffecf4f3deffffec +fffdeef7f8eafffff3f5f6e8fdfbeefffff3f6f4e7fffff3fffff2fdfef0f3f1e4fffff3 +fffef1f3f4e6fffff3eff0e0ffffeff7f9e4fffeecfeffedfefdebfdfeecffffeffbfcec +040200fffff1f4f2e5f7f8eafffff4fcfcf0030100fffff3f9f7eaf9faea090700f8f9e9 +030100fffff1f7f5e6fffff1fffff1f6f7e7fffff1fffff1f7f5e6fffff1fcfaebfeffef +fffff3f0f1e3fffff3010200f6f4e7fffff3fffdf0050600fffff3f2f3e5f2f0e3fffff3 +f9f7eaf3f4e6090700fefff1fffff1f4f5e3f9faeafffff1f5f6e8fffff3f8f9ebfbf9ec +fefceffffdf1fffff3fbf9ecfffff3fffff3fffff3f6f7e9fffff0ffffeff9f7e8ffffef +f9f7e8f5f6e4fffff1ffffeff6f4e5ffffeff9f7e8f8f9e7fffff1f8f9e7fefced010200 +fffff2f5f6e8fffdf0fffff3f8f6e9fafbedfffff3030400fffff3eff0e2fffff3f9faec +f9f7eafffff2fbf9ecffffeffffee9ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe7ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7fffee9ffffe7 +fffee9ffffe7fffee9ffffe7fdffe7feffe8fcfee9feffef010100908f8aaaa9a7d8d6d9 +f8f6f9fefcfffffefffffefffffefffffffdfffffbfefdf9fffffdffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc7 +0837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff2e9e2f9e5e7f9e5e7f5e7e4efebdfebeed9 +e8f0d8e8f0d8eaefd9ecedddefebe0f2e9e2f3e8e4f3e8e6f2e9e4f1eae2f2e9e0fbefe1 +f7ebddefe7dcebe7deebe8e1ece9e2f1ede4f8f1e7f3e9ddf5e9dbf3e9ddf2eadfeeebe4 +eaece9e5edefe7edebecece4efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff2eaddf8e6d8 +fbe9dbf4eadeebebe1e8f1ece5eaedf0eaf69e92a6fef5fff0ffff00160e187f6a74e7ca +18765c000d04fbfff4ffffdcffffd1543d14ffffd1f5ffc8deffbdf1ffdaecffe900101a +f2f8fffffafffffefb000900000800fffafffff5fffffcff010100fdfdf1ffffeff9fbe3 +ffffe8fdffe5fdffe7ffffedffffee010200fcfdedf7f8e8feffeb0d0f00ffffedfafbed +fffff30f0f05fffff4010100010100010100010100fffff6f5f5e9f9f9ef030300030300 +040400fffff5fafbedf8fae5010300ffffedffffedf8fae5ffffedfcfdeb010200fafbeb +f8f9e9fffff3fffff3f2f2e6f7f7eb0e0e02e7e8dafffff1f6f7e7050600fffff1010200 +fffff1fcfdedfeffeff1f2e2fffff1e5e6d6fffff0fffff1fffff1040500010200040500 +fcfdefeff0e2f6f7e9090a00fdfef0010200eceddffcfdeffffff20f1002050600010200 +fffff3010200010200010100060600fffff6f0f0e4fffff6010100111107010100fefef4 +f7f7eb010100010100010100020200ecece2fffff4fbfcee0102000d0e000102000d0e00 +fffff3fcfdef010200010200090a00fffff3ebecdefffff2fffff3f0f1e30c0d00fbfcee +fffff3f5f6e8f8f9ebfffff3010200fdfef0010200fffff3fafbed010200070800010200 +fffff3eff0e2ffffefffffe7ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe7 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fdffe7feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9 +fefcfffffefffffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db +1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff2e9e0f8e6e2f9e6e2f5e8dfefecdbebefd8eaf0d6 +e8f0d8eaefd9eeeddbf1ebdff2e9e0f3e8e2f2e9e0f2e9e0efebdfefecdbeee8d2ece6ce +eeecd7ebecdae5e8d7e9ecdbedeedce9e7d2f2ecd4f3ecd2f5ebd0f3ecd2efedd8eceddb +e8eee0e8eee0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddeeebd8eef0db +e6f2dee0f1e1e0f6eadfeeebedecf49c94a3fffafff1f9ff00161400160e00170b002119 +000407fcfffbe1fedfe9ffd8eeffc1174e00237e1e177a281c6436003016000e00f4fffa +fff7fafff4faf8ffff000600fdfff4fefaeefffff8010100fdfdf1ffffeff9fbe3ffffe8 +fdffe5fdffe7ffffedffffee030400fffff1fffff1ffffed010300ffffebfafbebf9faec +010100fafbed060600fffff3f4f4e8fffff3010100fffff3010100fafbedf5f5e9fffff3 +010100fffff1ffffed010300fafce6ffffecffffececeed8ffffed0a0c00fcfdebfbfcea +e7e8d8f1f2e2fcfdeffffff3030400fffff3f8f9e9ffffef010200f4f5e3ffffef010200 +010200010200ffffeff9fae8ffffeff5f6e4ffffef010200e0e1cfffffeff4f5e5101101 +fbfcecfffff1f3f4e4010200fffff1fffff1ebecdc111202eeefdff1f2e2fffff1eaebdb +010200fffff3fffff3fffff2010100fffff3f0f0e4f5f6e8fcfcf0fffff3010100f3f4e6 +101004fbfceefffff4fefff1121206f6f7e9050600f9faeafffff1fffff0060700f3f4e4 +010200fffff1fffff0f6f7e7010200fffff1f8f9e9f0f1e1fffff1010200050600010200 +080900010200fffff1010200f6f7e7070800fbfcec010200feffeffbfcecfeffef010200 +fffff1fdfeecffffe7ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7fdffe7feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcff +fffefffffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff3 +1e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff2eadff8e7ddf8e7ddf3eadbefecd9ebefd8eaefd8eaefd8 +ebeed9eeeddbf1ebddf2eadff3e9dff2eadff1ebddeeecddeeedd9eeecd3ededd3f1f5de +f1f6e0e5eed9eaf3deeff4dee3e5cdf1edd0f3eccff5eccdf3edcdf2edd0efedd4ebefd8 +ebeedbeeecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdde9eedae7f3dddff5de +d9f5dfddf8e9dcf0e7eaeef19b969dfffafffbfdff00050c00090ce9ffff00060b01000b +f8fcfde3fff3286e3028771c54b85554d6800c9253005837247660001b00d9e5cffffaf8 +fff3fffefdff000912f3ffeefbffecfffff6010100fdfdf1ffffeff9fbe3ffffe8fdffe5 +fdffe7eef0dbffffef080900f4f5e5f4f5e5ffffedffffec010300feffed101101f3f4e6 +fffff1010200f6f7e7fffff3f9faea010200f8f9e9010200060700010200171808010200 +fbfceafcfee8ffffeaf5f7e1f5f7e1fbfde7ffffecfdffea010300f7f9e4ffffef010200 +090a00171808eceddd0a0b00010200010200070900ffffefffffedf0f1dfffffedffffef +ffffed010200ffffedfbfceaffffedffffef080a000f1000010200090a00010200fffff1 +f8f9e7fdfeee070800fffff1eeefddfffff1050600fffff1ffffefe4e5d5ffffef010200 +fcfdedf8f9e9fdfeee0d0e00ebecdcfffff31112020607000102000c0d00fdfeee060700 +f4f5e5fffff3f6f7e7010200fffff1010200fbfcecf6f7e7fcfded0e0f00fffff1050600 +080900010200080900141505fffff1f2f3e3fffff1f8f9e9040500edeedeffffeffffff0 +fafbe9f3f4e4111200eaebdb010200fbfcec030400010200070800020300080900f7f8e8 +fdffeaffffe7ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7fdffe7feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffeff +fffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bc +e2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff2eaddf6e9d9f8e8d8f3ebd8efedd8ebefd8eaefd8eaefd9eceddb +efecddf1ebddf2eaddf2eaddf1ebddefecdbeceed9ebeed9ebefd8e8edd7e5eedbe0ebdb +dbe9dae0eedfe6f1e0e7ecd8eeeed6f2edd0f3eccff5eccdf3eccff1edd0efedd4eeedd8 +efecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeddce7f3dfddf6e0d8f5df +ddf8e7dcf0e5eaefeb99979afffdfffffdff060411eeedfb01000efffbff04000ef9ffff +33603f90dea456bb77088245006e4d008b7900857b003932000b01fffcf4fff3f4fff4ff +fff2ff08091eeafefcdcf2e5fbfffb010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7 +ffffedf7f8e6010200fcfdedfffff1eff1dcffffec030500ffffef010200fffff1ffffef +010200ffffeefbfcecf4f5e3060700f7f8e6080900f5f6e4f7f8e8eaebd9fffff1ffffef +feffeaf3f5ddffffeafdffe7eff1d9ffffeaf7f9e3151701eceed8ffffedfafce7f1f2e0 +010200ffffef010200ffffeff9fbe6ffffecffffedfafce6ffffedffffecebedd8eef0da +060800ffffece9ebd6fbfde7ffffec010300fcfee9f9fbe6f6f8e3ffffedfcfdebf7f9e4 +010200ffffed010200ffffedf4f5e3080a00eff0defbfde8fafbe9f1f3de040500ffffef +ffffeff4f5e30d0e00f8f9e7010200f5f6e4eff0e0ffffef010200ffffef010200ffffef +fffff1f9fae81a1b0bf6f7e7020300fffff1fcfdedf8f9e9010200feffef010200f3f4e4 +f7f8e8f6f7e7f7f8e8ecedddfffff0fffff1eeefdf0c0d00ffffeff5f7e2feffedffffed +fafbe9010300ffffef060800ffffef0e1000f2f3e1ffffecfafbe9fbfde8ffffefffffed +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +fdffe7feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffeff +fffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8ff +f4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff2ebdbf6e9d6f6ead4f2ecd6efedd8ebeed9eaefdbebeeddeceddfefebdf +f2eadff3e9ddf2eaddefecddeceddbeaefdbe8efdde3ebdce8f2e9e3f0e9e3f2ede8fbf9 +e1f4f0dfebe7eaf4ebebeddfefecd9f3ebd6f5ead4f5ead4f3ebd6f1ecd8f1ecd9efecdd +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff0eadeedefe1e2f3e0dcf3dfe1f6e5 +e1efe2eaefe8979996fbfffef7f6fb070007190619f5ddf51d0d2700001535524e8dcc9f +5dbd7d1b945e007a5700515035d1e04ae7f85dcedc000710ffeef7fff7fffff6fffcecff +000013eeffffedfffafbfffb010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7ffffed +e5e6d4090a00fffff1e4e5d5ffffedf6f8e2f7f9e3010300ffffedffffefe7e9d4010200 +ffffedf8f9e7ffffed010200ffffed010200ffffecfbfceaffffed010200eef0dbffffea +010300ffffeaffffeaffffeaeef0d8f9fbe5e7e9d3161802f1f3ddffffecfafce6151702 +f9fbe6050700fcfee9ffffecf8fae4f0f2dcfeffeaffffecf8fae4f6f8e2ffffec010300 +feffeaffffecffffecfafce6080a00ffffecffffecf7f9e3030500ffffed010300ffffed +f8fae4ffffed090b00fbfde80f1100feffebffffecffffedffffec010300e2e4cfffffed +ffffed010200ffffed0d0e00f7f9e4ffffefe9ebd6151604f0f2dd040500ffffede9ead8 +f6f8e3050600f6f7e50f1000e6e7d7fffff1fffff1010200fffff1010200fffff1fffff1 +fffff1010200fffff1fbfcecf6f7e7f8f9e9010200ffffedffffedeef0dbfcfee9ffffed +010300f6f8e3010300f4f6e1010300ffffedfeffebffffed010300ffffecf7f9e3ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5fdffe7 +feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffeff +fffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2 +e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff1ebdbf5ead4f5ebd2f2ebd8efecd9eceddfebede0ecece2eeebe2f1eae2f2e9e0 +f3e9dff2eadfefebdfebeddfe8efdfe5efe4eaf4f5edfaffd6e6f3d2e4f2e2f7ffd3e9f7 +ccdce9f0faffe8ecefeeeae9f2e9e4f5e8e0f5e8dff5e8dff3e9e0f2e9e0f1ebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff3e9dff9e4dffae9e2edede1e6eedfebf1e3e8ecde +ecefe4949c91f7fffbebf4f109000717001411000e0400130006150027182d904f038130 +007942004d352bd6e739e5ff3cd7ff003e67000a27fff9fffff2ffffe2fffff6ff00000c +f2fff3dff8dafcfff6010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7fbfde8ffffef +020300f8f9e9fffff1eef0dbffffebffffea020400feffeaedefdaffffec010300030500 +010300010300fdffeaf5f7e1ffffed0103000406000a0c00f2f4dfffffecf7f9e1101300 +f5f8ddeff2d7ffffeaffffeaf7f9e1ffffeaf5f7df0103000103000103000d0f00f4f6e0 +010300fafce6fdffe7ffffeaffffeaf9fbe3080a00010300292b13010300ffffeaf4f6de +ffffeaf8fae2f4f6def2f4dc0a0c00010300010300ffffeaffffec010300ffffeceef0d8 +ffffec010300feffeaf6f8e0010300090b00010300f6f8e0030500ffffecffffecffffec +070900f1f3ddf9fbe6010300010300101200010300f5f7e1010300ffffecfcfee9ffffec +050700f6f8e3fafbe9010200010200010200101100f2f3e1ffffef010200010200010200 +ffffefe9ead8ffffefeaebd9ffffef020300fcfee9fcfee8ffffecf8fae4f1f3dd0a0c00 +ffffec080a00ffffecffffec010300090b00010300ffffebfdffe9ffffecffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe5fdffe7feffea +fcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffb +fffffbfefdf9fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eada +ebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f1ebdbf3ebd6f5ead4f2ebd9efebdfecece2ecebe6ecebe7eeebe6f2e9e4f3e8e2f3e9e0 +f1eae0eeece0eaede2e5efe4e3efebe2eff8d4e3f69dafc78398b399b1cd91a9c59aaec7 +dae9fee4ebfbeaeaf4efe9edf3e7e7f5e7e6f5e7e6f5e7e6f2e9e4f1eae0efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff5e8dffee2e1ffe5e4f4eae1edebdff2eee2eceaddecf0e2 +909e8fe6fceff5fffdfef4fcfff3fffff4ff05011800232ec0ffff4dda9800893e009368 +32e9d534f7f3009c9b008c86038681000e19fcfdfffce7fffff4ff08000c040003000500 +f9ffedfefff6010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7f9fbe6ffffefedeee0 +fffff1fafbebffffecffffec010300ffffecf4f6e0ffffecffffec050700ebedd7ffffec +f7f9e3fdffe9ffffecf3f5dffbfde7ffffebf8fae4ffffecfbfde7ffffeaffffe7f4f7dc +ffffe8ebedd5ffffeaffffe9f4f6deffffe9ffffe9ffffeaf5f7dfffffeaffffeafcfee6 +ffffeafdffe7fcfee6ffffeaf8fae2f5f7dfffffeaeef0d8ffffeaffffe9ffffeaeef0d8 +ffffeafeffe8ffffeafdffe7fcfee6ffffeafbfde5ebedd5ffffeaffffeaf6f8e0ffffea +ffffeafdffe7f5f7dfffffeaf7f9e1fcfee6ffffeaf6f8e0f6f8e0f5f7e1ffffecf5f7e1 +ffffecffffecf2f4deffffecfcfee8ffffecffffecfdffe9eff1dbffffecf7f9e3f8fae4 +ffffecffffeffafbe9ffffeffcfdeb020300f8f9e7ffffeffeffedffffeeffffeffafbe9 +ffffeffeffedffffeff8f9e7f9fbe6ffffedeef0daffffecf9fbe5ffffebffffecfafce6 +f2f4defbfde7f2f4deffffecffffecfdffe9fbfde7fcfee8fbfde7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe5fdffe7feffeafcfee9 +feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffbfffffb +fefdf9fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dc +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdd +f3ebd8f3ebd8f1ebddefebe2ecebe9eceaebeeeaebefe9e9f0e5e3fdf2ece8ded5fbf4ec +e9eae4e3e9e5dbe7e5e4f1f7e6f3ff8c9cb3dcf0ffa8bfde89a6c698b5d598b1cf8195ae +dbe8fbe5e9f5f4f1f8efe6e9efe3e3f5e7e7fceeeeece1dff1eae0efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff5e8dfffe1e1ffe4e4f9e8e1f1e8dff6ece2ede9ddeaf0e28d9f8f +ebfff8ebfff8fffdffffeefefff6ff0000129ed5da66ddca34f2c410f2c41effee20ffe8 +00965600b0490bef6427d961001900f8ffffeff9fffcfefffffbf8ffeee9fff5f8fffcff +fffefd010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7ffffedf8f9e7fcfdeffffff1 +eeefdfffffedffffec010300ffffecfbfde7ffffecf8fae4010300ffffecf7f9e3ffffec +ffffecfbfde7ffffebffffecf7f9e3fafce6ffffecf8fae4f7f9e1ffffeaf1f3dbf8fae2 +ffffeafafce4fcfee6ffffeaf9fbe3ffffeaf3f5ddfdffe7f8fbe0ffffe8ffffe8fcffe4 +f3f5ddffffeaf2f4dcf6f8e0ffffeaffffeaf4f6deffffeaf0f2daffffeafbfde5f4f6de +ffffeaeef0d8f5f7dfffffeaf6f8e0ffffeaf8fae2fafce4ffffe9ffffeaeef0d8f8fae2 +ffffe9ffffe9fdffe7fbfde5ffffeafbfde5feffe8fcfee6ffffecf5f7e1ffffebffffec +f7f9e3f8fae4ffffecf5f7e1fafce6ffffecf6f8e2ffffecffffecfafce6f7f9e3fdffe9 +feffed010200040500101100f1f2e0fafbe9ffffeffafbe9ffffeffeffedfafbe9ffffef +ffffeff1f2e0fbfceaffffedf7f9e4f8fae4ffffecffffecf6f8e2fbfde7f1f3ddffffec +fcfee8fdffe9eff1dbffffecfbfde7f5f7e1ffffecf3f5dfffffecf9f8e3ffffeaffffec +f1f0dbedecd7ffffecfaf9e4ffffecf7f6e1ffffeaffffeaf7f6e1fefde8ffffeaffffec +ffffecffffeaffffecf4f3deffffecedecd7f8f7e2ffffecfbfae5fffee9f7f6e1ffffec +ffffebffffeafefde8ffffe9ffffe6ffffe6ffffe8f4f4daf8f8deffffe8ffffe8fdfde3 +ffffe6fefee4fdfde3ffffe8ffffe7ffffe8ffffe5ffffe8fdffe7feffeafcfee9feffef +010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffbfffffbfefdf9 +fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf2ebd9 +f2ebd9efebe0eeebe6eeeaebeee9edefe9edf1e8e9fdf2eee6d9d1fcf2e8eeeae1e7e9e4 +eaf2f4f5ffffd9eaf496a6b3deefffedffffd9f3ff85a4c18fb1cde0ffffeaffff98a9bb +e6f0fadcdde2efebeafcf4f1f6ede8e5dad6f6ede6f1eae0efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff3e9dff9e4dffce7e4f6e9e1f1e8dff5ece3eceadee7f2e48aa18fdeffee +eefffdf4f2f7fff9fffff7ff00000e97cacd1e867d00857345feee1fd6d400947e08b367 +14c24927e54535c93d002500fbfff8f5ffffecf5fcfdf4edfffaf3fff9fbfffafffffdfd +010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7f1f3deffffeff8f9ebf8f9e9fffff1 +f8fae5ffffecfeffe8f5f7e1ffffecf6f8e2ffffecfafce6f4f6e0ffffecf6f8e2eef0da +ffffeceef0daffffecffffecffffecedefd9ffffecf1f3ddf6f8e2ffffecffffeafcfee8 +ffffeaf4f6defbfde5ffffeae8ead2ffffeaffffe9ffffe8e7eacfffffe8fafde2ffffea +e7e9d1ffffeaffffeafeffe8f6f8e0eef0d8f4f6deffffeaf0f2daf7f9e1feffe8fbfde5 +ffffeafdffe7f8fae2fbfde5f6f8e0f3f5ddf8fae2ffffeae4e6ceffffeaffffeaf3f5dd +ffffeaf3f5ddffffeaf5f7dfffffeaf6f8e0ffffeafcfee8ffffecf2f4deffffecfeffea +ffffecfafce6ffffecffffecf2f4deffffecf9fbe5f1f3ddffffecffffecffffebfdffea +fcfdebffffeef1f2e0fcfdebffffefedeedcffffefffffeeffffeeffffefebecdaffffef +ffffeffeffedf5f7e2ffffedfdffe9fcfee8dcdec8ffffecffffecffffecfcfee8ffffec +fcfee8ffffecf7f9e3ffffecffffebf2f4defdffe9f8f7e2ffffecffffeaf0efdaffffec +ffffecfaf9e4f9f8e3edecd7ffffecfffee9fbfae5ffffecffffeaf6f5e0f6f5e0f7f6e1 +ffffecf7f6e1ffffecf8f7e2fdfce7ffffece8e7d2ffffecfbfae5ffffecf0efdafdfce7 +ffffeaf8f7e2f4f3defafae2fafae0fafae2ffffe7ffffeaf0f0d6ffffe9ffffe7fdfde5 +ffffe8fefee6ffffe8ffffe7f7f7ddffffeaf3f3dbfdffe7feffeafcfee9feffef010100 +908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffbfffffbfefdf9fffffd +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddf1ebdbf1ebdd +efeae4eeeae7eee9edeee9edf1e8e9f2e9e4f0e3dafef2e4e8dfd0f4f0e5f5f7f4cad3d8 +deeefd91a3b1c5d4dbf2ffffe9ffffdffcffc9ecffe3ffffe0ffffe2ffffe4fcff899b9d +ecf5f2f0f3eae3e1d5ebe7dbf2ecdef4eee0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfedebdff0eee2efede1edebdff1eee5e8ebe0e3f3e689a193e7fff9f1ffff +fbf9fefff7fffff0ff0a0815001214000f13000d1e000e21000915000c06001800001700 +001d00001900000600e1d8d1fffafffffbfffafdfffcfffbfffdeafdf8e4fffff6010100 +fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7ffffedffffeff9faecfffff0f6f7e7ffffed +ffffebf4f6deffffecffffebebedd7ffffebffffecffffecf8fae4fcfee8ffffecffffec +ffffecf2f4deebedd7f7f9e3ffffecf3f5dfffffedfafce7f5f7e2f3f5dff6f8e3feffea +ffffecfbfde7ffffecffffecffffeaeaecd4ffffeaffffeaf5f7dfffffe9edefd9ffffec +f9fbe5ffffebf4f6e0ffffebffffecffffeceff1dbffffecffffecfdffe9fcfee8f4f6e0 +feffeaffffebffffeaf9fbe3ffffeafdffe7f2f4dcffffeafdffe7eceed6ffffeaffffea +f7f9e1ffffeaf6f8e0fbfde5ffffe9f3f5ddf8fae4ffffecf0f2dcfbfde7ffffecfcfee8 +fdffe9fafce6ffffecf4f6e0ffffecfeffeaf6f8e2ffffecf4f6e0fdffe9f8fae5ffffed +fbfde8ffffedfbfde8ffffecffffedf2f4dff5f7e2ffffedfafce7ffffedf1f3deffffed +f1f3deffffedffffecf4f6e1ffffedffffedfdffeaf1f3defeffebfafce7ffffedeaecd7 +fdffeaffffecffffedfeffebf2f4dfffffedffffececebd7ffffebffffede9e8d4ffffed +f5f4e0faf9e5ffffedf5f4e0f0efdbffffedf2f1ddffffedf3f2deffffedffffedf6f5e1 +ffffedf8f7e3ffffedfefde9efeedaffffedf0efdbffffede5e4d0ffffedffffedfffeea +f9f8e4ffffecffffecf5f5ddffffecffffeaeae9d4ffffeaf7f6e1ffffe8f5f4dfffffe9 +f3f2ddffffeaf3f2ddffffeaffffeaffffeafdffe7feffeafcfee9feffef010100908f8a +aaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffbfffffbfefdf9fffffdffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddf1ebdbefecddeeebe4 +eeeae7eeeaebefe9e9f2e9e4f3e9ddf5e8d5f5ebd2fffee7e8e5d4e2e7e1e7f4fa92a5b6 +d1e4f5f4fffff3ffffeeffffe7ffffe4ffffe2ffffafd6e7b1d5e3e8fffff0ffff95a19d +e2eadfeceee1dbdcccfdfbeceae8d9efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +ebeddfe4efdee6f3e1ebefe1ebebe1f1eee7e8ebe4e3f3e98a9f96f0ffffe2f1eefffdff +fff3fcfff9fffffdffeefdffebfefffcfcfffff7fffff4ffffedf3fff2effffff4fffef4 +fffaf1fff7f0fffafafff9fffcf4fff4fefff5fffffbfdefffffeffffff8010100fdfdf1 +ffffeff9fbe3ffffe8fdffe5fdffe7f2f4dfeaebd9fffff3fffff1fffff1ffffedfcfee8 +ffffeafcfee8f8fae4ffffedf0f2dcf7f9e4f7f9e3ffffedf4f6e0fbfde8f8fae4fafce7 +fafce6ffffedf7f9e3f3f5e0ffffedf2f3e1ffffefffffefffffefffffeff7f9e4ebedd8 +ffffeceaecd6ffffecf6f8e2ffffeaf8fae2f8fae2fafce4ffffeafdffe9ffffecedefda +ffffec0b0d00f1f3ddffffedf0f2dcffffec111300010300ffffecf9fbe6ffffebffffed +fdffe9ffffebedefd7f7f9e1ffffeaffffeaffffeafeffe8ffffea010300f8fae2ffffea +f9fbe3fdffe7ffffeafcfee6ffffecfafce6ffffecffffedeff1dbffffedfcfee8ffffed +f5f7e1ffffed010300eff1dcfcfee8ffffedfdffe9ffffedfbfde8ffffedffffedfdffea +f3f5e0f9fbe6fbfde8f6f8e3ffffedfcfee9010300ffffeceef0dbffffedf4f6e1ffffed +e5e7d2f3f5e0ffffedf7f8e6f3f5e0ffffefffffedffffefffffedffffeffeffebffffef +edefdaf5f6e4eceed9ffffeff6f8e3fefde9ffffedfaf9e5f5f4e0ffffedfbfae6ffffed +ffffedf8f7e3f4f3dfffffedf4f3dfffffedffffedffffedfcfbe7ffffebffffedffffed +ebead6fbfae6ffffedffffedffffedfcfbe7fffeeaffffedf8f7e3f8f7e3fbfae6fefde9 +f6f5e1f9f8e4ffffecf8f7e3ffffebffffedffffecfefde9fffee9ffffedffffecfffeea +ffffecffffedf9f8e3fcfbe7f7f6e1fdffe7feffeafcfee9feffef010100908f8aaaa9a7 +d8d6d7f8f6f9fefcfffffefffffefffffefffffffbfffffbfefdf9fffffdffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddefecdbefecddeeebe2eeebe6 +efeae6f1eae2f3e9ddf5ead4fff7d7e8debbf2eccae9e9d1eaf2e7e2f1f68da2b7dff4ff +f2fffff7ffffecffffeaffffd4f8ffa5cee0b2dbedbbe2f3c4e4efe3ffffefffff8f9c95 +e1e8e0fefff6dadccfeeeee2eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeaeedf +ddf3dce0f6dfeceee0f0e9e1f2ede9e9e9e7e6f0ef8e9c9ceef9fbf9ffff8b898e797279 +8a84888783848080808b8c8e81858e777582907e8c9b8494998b9cfbf4fffefdfffffbff +ffeefafff3f9fff8f9fefffdf5fffff2fdfff3f1fffffbfffffdff010100fdfdf1ffffef +f9fbe3ffffe8fdffe5fdffe70b0d00070800050600010200eff0e0fbfde8fcfee8f7f9e3 +fcfee9ffffecffffeff2f4dffeffed0f1100e8e9d7ffffedffffeff7f9e4fafbe9fcfee9 +f5f6e4f8fae5ffffeef8f9e7fffff1f4f5e5010200010200f3f4e4ffffefffffef010300 +1a1c07f3f5dffcfee8ffffecffffecf9fbe5fbfde5f7f9e3fcfee9fcfee9ffffeefcfee9 +010200ffffed010200ffffed010200ffffedf7f8e6ffffed060700fcfee9f7f8e6f8fae5 +f0f2dcffffecffffecf8fae4ffffece7e9d3ffffecf8fae4090b00fbfde7f4f6e0f8fae4 +ffffececeed8ffffecf1f3ddffffedfbfde80102000b0d00010200e5e7d2ffffefffffed +ffffee040600ffffeffdffeaffffef010300ffffeefcfee9fcfee9f1f3deffffed050700 +ffffedffffedfbfde8fcfee9ffffed010300f7f9e4ffffed0103000204000b0d00ffffed +fbfceaffffef0405000102000e0f00f6f7e5f4f5e5f5f6e4010200010200010200ffffef +fffff1ffffef010200070800030200fcfbe7fffeeaffffedf9f8e4ffffedf4f3dfffffec +030200ffffedf0efdbfefde9ffffedf1f0dcffffedf8f7e3f5f4e00504000302000a0900 +ffffedffffed0302000302000f0e00030200030200ffffedffffedfcfbe7ffffedf2f1dd +ffffed030200030200ffffecfffeecf6f5e1050400090800faf9e7ffffedffffed030200 +030200ffffedffffeffdfce8fdffe9feffeafcfee9feffef010100908f8aaaa9a7d8d6d7 +f8f6f9fefcfffffefffffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc7 +0837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefecddefecd9efecdbeeece0eeebe2efebe2 +f1ebddf3ebd4f6ebcbf8ecc2f8f0c1ebe6bcffffe0dde5d692a4a6dff5ffeefffff8ffff +f2fcfde8f9ffe7ffffb2d5e9bee6ffb1dbf4b3dbf4b3d6eac7e2f3efffffe4f3f899a3a4 +dce2e2f5f9f8e7e9e4eeebe2efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeaeedddcf4da +e2f5dff0ece0f7e5e3f9e9eaefe6ebeaedf292999ffcfffff5f5fd797a7ff7f8faeaefeb +d3d4cff7eee9efe7e4e2ebe6e0e9e6f9eef2ecdfe6a9a6b1535466e8e8fffbf7fffff9ff +fff6fdfaf1eaf9fbeef4fffaf4fffffdfbfffcf4fffffeff010100fdfdf1ffffeff9fbe3 +ffffe8fdffe5fdffe7030500f1f2e0fffff3f3f4e40b0c00ffffedf8fae4ffffebf6f8e3 +f9fae8f9fae8ffffefffffef010200ffffeff0f1dffdfeecf8f9e7ffffefffffefffffee +feffedffffeffcfdedfcfdeffffff3010200010200fffff3f8f9e9fffff1010200010200 +ffffedf8fae5ffffeceff1dbffffecffffecffffecfcfdebffffeffcfdebfeffed090a00 +ffffefffffeef4f5e3151604ffffeee3e4d2ffffeff4f5e3fcfdebffffeeffffefffffed +eceed8fcfee8f6f8e2fdffe9ffffecf6f8e2fdffe9010300ffffeceff1dbffffecfcfee8 +fdffe9f3f5dfffffedfdfeec050600fbfceaffffeeffffee121301ffffeff1f2e0ffffef +010200f5f6e4fcfdeb0506000e0f00edeedcffffefffffecfbfde8010300101200e5e7d2 +ffffedebedd8ffffedf3f5e0010300ffffed010300feffebffffededefda010300fffff1 +010200fffff1fffff0f6f7e7010200feffef090a00f8f9e9fffff1fffff1010200fffff1 +010200f9faeafbfcecffffef060500fffeeafbfae6f7f6e2ffffedffffed030200030200 +f6f5e1f8f7e3fcfbe7ffffedffffedfdfce8ffffed040300ffffedfbfae6ffffed030200 +ffffed100f00ffffedf9f8e4ffffecffffedffffedfaf9e5efeedaffffebffffedf7f6e4 +060500030200ffffeffcfbe9ffffef131200030200fdfceafaf9e7ffffed1817050f0e00 +f4f3e1f6f5e3ffffedfdffe9feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9 +fefcfffffefffffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db +1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefecddeeedd9eeedd9eeecddeeecdfefecddf1ecd8 +f3edcdf6edc2f4eab5b1a86f9f9c6795976fabb7a3c8dadaecffffd8ecfff1f7fff2f6ff +f4ffffd3e8ffadceefbfe5ffa6d0f8abd2fbb9dbffc6e0ffc9ddf8ecfbffd3dced9097a7 +e0e6f4ebeef5ecebe6efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfebeedde0f2dae9f2dd +fbe6e1ffdfe3ffe4ecf6e2edf0eaf49797a1f7f4fffffdff899194e5f4f1eafff4f8fff8 +f9efe6fffbf2f8fffaf7fff6fbf4e1fff9e395a693eefff9686775fff9fff6f3fcfffdfb +fffbefffffecebffece8fff7f9fffffffdfffffeff010100fdfdf1ffffeff9fbe3ffffe8 +fdffe5fdffe7010300ffffeff6f7e9fffff1feffef010300ffffecffffec090b00030400 +030400eff0def3f4e20102000a0b00010200ffffeff0f1df010200010200010200ffffef +e7e8d6fbfcecf5f6e8fffff4010100fffff3060700fdfeee010200ffffef010200f3f5e0 +ffffed020400010300010300f5f7e1fafce6ffffef0102000d0e00090a00010200f9faea +010200fffff10203000102001c1d0df7f8e8010200fffff1fffff1010200040600010300 +ffffedffffedf4f6e1010300040600010300010300ffffedffffed010300ffffedf5f7e2 +f6f8e3f5f7e2ffffefe7e8d6ffffeeffffeffdfeec010200eceddbffffef010200ffffef +fafbe9ffffeff6f7e5060700f7f8e6f3f4e2ffffedf9fbe5fcfee8030500ffffecffffec +ffffecfdffe9050700fcfee8ffffecffffecf0f2dcfbfde7ffffec030500fdfeee010200 +fffff3fffff3f6f7e90a0b00fffff3010200f8f9ebfbfceefdfef00f1002f7f8eafdfef0 +fffff3fcfdedfaf9e7050400eae9d5ffffedffffedefeedaffffedffffec060500ffffed +ffffedffffedf5f4e0030200ffffedf2f1ddffffedffffedfdfce8faf9e50b0a00fffeea +030200edecd8f2f1ddffffedffffedf2f1ddffffedffffedefeedafefde9030200fffff1 +fffff1030100fffff1f6f4e5030100fffff1080600fffeef080600e6e4d5030100fffff1 +fefcedfefdebfdffe9feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcff +fffefffffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff3 +1e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddefedd8eeedd8eeedd9eeeddbefecd9f1edd2f3eec8 +f6eebda69e5febe4a0ebeaaae2e6b3c6d3b9dcefede2fbffe3f8ffdde9fff5ffffc2d3f1 +adc7eacaebff93bce8caf5ffa4cffcb8ddffa3c2eeb8cff8d7e9ffe3f0ffc1cae7979eb8 +e1e4f3eeeae7f1ebdff1eae0f1eae0f1eae2f1eae2efebe2efebe0efebdfefebdfefecdd +f1ebddf1ebdff1ebdff1ebdff1ebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddde7efdaf0efddfde6e0 +ffe0e3ffe5ecf4e3edeeebf49597a3fffdfff0f2fe7d8b8ef1ffffe4fef5f5fffbfcf5ef +fffdfbf7fffff4fffffcf9f0fffff394a99840554e4b4956534a5bfffefffffffafff7ea +fffdeaf5fff1f0fff8f9fffff8f9fdfffffd010100fdfdf1ffffeff9fbe3ffffe8fdffe5 +fdffe7070900fafbe9f9faecfbfcecfffff00a0c00f0f2dcffffecf9fae8ffffeff5f6e6 +050600fffff1010200ffffefffffeff7f8e6080900ffffefedeedcffffef010200ffffef +ffffeffffff3f9faec040400fbfcee010200fbfcee010200fcfded090a00f9fae8010200 +ffffedf8f9e7ffffed030500ffffed010200fffff1f7f8e8f8f9e9050600fffff1010200 +feffef010200fffff0fafbebfffff1010200fbfcec010200fffff1fafbe9ffffed010300 +f7f9e4131500e7e9d4ffffedffffed121400e5e7d2ffffed111300e0e2cdffffedf8fae5 +fbfde8f4f6e1ffffeffdfeec010200010200fafbe9ffffeff0f1df010200fdfeecf7f8e6 +ffffeff6f7e5010200fdfeecffffedf1f3deffffecf8fae4010300ffffecfafce6f8fae4 +ffffec010300fdffe9f5f7e1fdffe9ffffebfdffe9010300fafce7f5f6e6080900fffff3 +f2f3e5fffff3010200fbfcee060700fffff3fcfdeff5f6e8040500fcfdeffdfef0fafbed +030400030200ffffedfffeeafdfce8f5f4e0ffffedfcfbe7ffffeb060500fcfbe7f2f1dd +ffffedf5f4e0100f00f7f6e2ffffedfefde9f8f7e3ffffed030200f9f8e4ffffed030200 +0a09000a0900030200ffffedfaf9e5ffffedf3f2deffffebffffed030100fcfaebfffeef +040200fffeeffcfaeb030100fbf9ea030100fffff1030100fffff1040200fbf9eafaf8e9 +ffffeffdffe9feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffeff +fffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bc +e2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefecddefedd8f1efd8efedd8edebd6f3eed8f0ebcef7f0c6a49d66 +faf3adf8f2a6ffffbcecf2b4aab692afc2bcdaf3ffd9f3ffd2ecffc8e4ffb3d3fcb8ddff +9dc8f2b6e5ff9fd0f8b1e2ffa7d3ffb0d6ffb6d6ffd3eaffd1e1ffdce8ffb3bbdf8f90a5 +f4ebecf0e3dbeee1dbf1e6e4faeeeef4eaebeee6e4f3ece6f1eae0f1ebddf1ebdbf2ebdb +f2eaddf2eadff3e9e0f2e9e0f1ebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf1eadaf5ecddf7e9e0f4e7e1 +f4eceae9e9ebe6eff48e9ba3f5ffffeaf8ff809199edfeff77868d868f9485848c807f91 +757da27981af7c7ea47d819e80889f091023b9b7cc5c5867fffefffffffdfff8f2141005 +fcfff6eef8edfcfffbf6f8f3fffffb010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7 +010300ffffeffffff2f9faeafdfeee0d0f00fafce6f8fae4010200090a00030400010200 +fffff3010200fafbebfbfcecfdfeee0102000a0b000102000102000b0c00fbfde8ffffef +fffff1f0eedf090700fdfbecfffff0080600faf8e9fffff0030100fffff1040200f7f6e4 +faf8e9ffffef030200fffff1050600f4f5e7fafbedfdfef0010200fffff3010200fffff2 +050600fafbedfffff3f5f6e8050600fafbed010200010200010200010200030400fdfeec +010200fdfeecffffedffffed080a00eceed9ffffecffffecf4f6e0f8fae4ffffecfcfee8 +f6f5e1ffffecffffede7e6d2ffffed0e0d00efeedaffffed030200ffffedf3f2deffffed +ffffed030200f9f8e4fefde9ffffedffffedfbfae6030200ffffedecebd7ffffedfdfce8 +030200ffffedf3f2deffffedffffed030200ffffedfbfae6f7f5e60a0800fffff1f4f2e3 +fffff1030100fdfbec080600fdfbecfffeeffffff1030100f9f7e8fffeeffcfaebfffff1 +ffffef030200f9f8e4ffffebf4f3dfffffedffffedffffed080700f1f0dcffffedfdfce8 +efeedaffffebffffecffffecffffedffffec050400fefde9f9f8e4ffffedfbfae6ffffed +ffffedfbfae6030200ffffedf7f6e2ffffedfffeeaffffed070500fdfbecfcfaeb0e0c00 +f8f6e7fffff1030100fffeeffffff0030100fffff1f6f4e5121001f1efe0fffff1ffffef +fdffe9feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffeff +fffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8ff +f4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddefedd8f1efd8efedd8edebd6f3eed8f0ebcbf7f0c2a69e60ffffb5 +fffba5ffffa8fcffb4d8e4b4b2c3b1b3c9d6cbe6ffd9f7ffafd0fbb7dcff9ac4eebbe7ff +a1d1f5a2d4f59bcdeeafddffadd7fdc1e2ffd6f2ffedffffecfaffd3dbeeacadb2988e84 +f6e6d7fff4eaf9eae5ebdddcf3e9e8ede3e2f5edeaf1eae0f1ebddf2ebdbf2ebdbf2eadd +f3e9dff3e8e2f3e8e2f1eae0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff1ebddf4e8daf8eaddf3ebdeedeae1edefea +e3ece9e3f1f28d9ca1f1fffff4ffff8a96a2edf5ff808392161523c7c0d01712320c0d50 +1319670f135a0608430a0b39000020fefcff585661faf8fbfffffbfffffa010000fffffa +f8f9f4fefffdfefffdfffffb010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe70e1000 +ffffeff3f4e6fffff1fffff1010300ffffec121400fffff1f0f1e3fffff20f1002eeefe1 +101101f8f9e9fffff1f5f6e60c0d00f1f2e0fcfdebffffeffafce7f7f9e4ffffedfcfbe9 +fffff1100e00fffeeffffff1030100fffeeff7f5e60a0800f3f1e2030100fffff1fcfaeb +fbf9ea100e00efedde020300fffff3eff0e2fffff3010200fffff3010200fffff3010200 +fefff1fdfef0fffff3040500fffff3010200fffff1ffffeffafbe9f5f6e4ffffef020300 +f5f6e4ffffedf2f4df010300ffffedffffebdee0caffffecffffececeed6ffffe9ffffed +f4f3dff1f0dcffffecffffed030200ffffedffffed0d0c00fefde9ffffedf6f5e1fbfae6 +070600ffffecffffedf5f4e0fdfce8fefde9030200ffffedffffedffffedffffed040300 +ffffebffffecffffed060500f6f5e1ffffedffffecfffeec030100fffff1fffff1f8f6e7 +0c0a00fffff1030100fffff1fdfbecfffff10f0d00fffff1fffff1fffeefeeeddbfefde9 +060500fcfbe7ffffedffffedf1f0dcffffedf4f3df030200ffffecf2f1ddf4f3dfffffed +ffffedfcfbe7f9f8e4f9f8e4030200f7f6e2ffffedffffedf5f4e0ffffedf8f7e3efeeda +ffffed030200f9f8e4ffffedf6f5e1ffffed030200030200141203030100030100131102 +e9e7d80c0a00fffff1fffdee030100fffff1fefced030100fffff1fffff0faf9e7fdffe9 +feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffeff +fffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2 +e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddefecdbf0efddeeecddedead9f3eed8f1ebcbf8f0bfa79e5bfffda6ffff9f +faf693ffffabffffcac8d6b2a1b2a8bdd3e0bcd5f3afcbf2afcff6b5d9fda9d0f1aedaf7 +aad8f0c6f4ffafdaeda5ccddbedeebc6e1e8e0f3f1cbd9ccb4c0a88e91727e7652f4e7c5 +f1e3c9fff3e0ece0d4faf1e8e6ddd6f1eae2efebe0efecddf1ebdbf1ebdbf1ebddf2e9e0 +f2e9e4f2e9e4f1eae0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff1ebddf1eadaf4edddf2ece0ebebe1ebf0eae3ece9 +e6f0f2909ba1f8ffffeff5ff747683fffcff9a8f9f0b000c200b1c1c0b350b075e000062 +04056102044e04053b171a3bfcfeff47484afffffafbfdf0fffff5020200fffffff8f7fd +e9e9f5fafafffffeff010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7010300ffffef +fffff3edeede010200ffffedffffec010300f8f9e7fffff1fcfded050600fffff1010200 +fffff1f0f1dfffffef010300ffffedfcfee9f2f4df010300ffffecf6f8e3ffffefedecda +040300f7f6e4eae9d7ffffeffbfae8ffffef070600ffffef030200fffeecffffeff3f2e0 +030200ffffef050600f2f3e3feffefeceddd010200fffff1060700f7f8e80c0d00fffff1 +f2f3e3fffff1010200f8f9e90f1000f8f9e9ffffefffffef010200fbfcea040500ffffef +fafce7ffffed080a00f0f2ddffffec121400ffffecd9dbc5ffffeafdffe7f6f5e1090800 +ffffedffffede4e3cf030200ffffedf9f8e40b0a00e5e4d0ffffedffffecfffeea030200 +ffffecfaf9e5ffffedf9f8e4ffffed070600f3f2deffffecf5f4e0faf9e5030200ffffed +f2f1dd030200f7f6e2ffffedffffedf7f6e2ffffef030200ffffefffffeef8f7e5030200 +ffffed0b0a00fcfbe9fffeecf5f4e20c0b00eeeddb030200ffffefffffeff3f2de090800 +f3f2deffffedffffedfffeeaffffecffffed030200ffffedfcfbe7ffffedfaf9e5030200 +fffeeaffffed030200ffffedfffeeaffffedfdfce8ffffec0c0b00fffeeaffffedeeedd9 +030200ffffedfbfae6f5f4e0ffffed0a0900f9f8e6ffffeff6f5e3ffffef0e0d00ffffef +030200f7f6e4f5f4e2ffffeff7f6e4faf9e7090800fcfbe9f6f5e3ffffedfdffe9feffea +fcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffb +fffffbfefdf9fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eada +ebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeecdff0eee1eeece0edeadbf3eedaf3eac9fbefbbaa9e54fdf092ffff9bfff98f +fbf794ffffbce7f0b9b8c6a5b0c4bbc5e0f3b1d0edc5e4ffafcfe8c0e0f5afd0e1aecedb +aacbd4bfdce2b9d5d6cee5dfd1e7dad4e7d3bfcfb4afbf9b9aa378958f5da89c6a84764f +e7dcbcf0e5cffff9eaebe3d8fcf5ebefebe0efebdfefecddf1ebddf1ebdff1eae0f1eae4 +f1eae4efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddf0eadaf1eeddefede0eaece1ebf0eae5ebe9e7eff1 +94999ff8fbfff7f5ff9c94a1fff9ff776070fff5ffffe6f7fff3fff9f3ffe9ecfff2f5ff +f4f8ffd8dbff050926f3f5ff4f514cfefff4eef1e0fffff4010000000002000009050318 +fffcfffffeff010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe70305000102000c0d00 +090a00fafbebffffedeaecd6ffffec0c0d00010200010200090a00fbfcecf7f8e6050600 +101200f7f9e4fbfde8010300101200010300feffeaffffecf7f9e3faf9e5f4f3df141301 +fdfce8ffffeff8f7e3fefdebf5f4e0090800e2e1cdffffef030200040300070600fffeec +f8f7e5eaebd91617050304000304000e0f00f4f5e3020300ffffef010200feffedf8f9e9 +f7f8e60a0b00ffffeff6f7e7010200010200010200ffffefffffefffffee010200010300 +010300010300ffffedfafce6010300f6f8e2ffffecffffeafbfde5ffffedfffeea030200 +070600131200fdfce8ffffed030200ffffedffffecfdfce8f8f7e3050400040300030200 +ffffedffffece9e8d40403000504000b0a00ffffedffffed030200fdfce8f6f5e1ffffed +030200111000030200030200111000fdfce8ffffed060500030200100f00f8f7e3f6f5e3 +f7f6e20403000d0c00191806eeedd9ffffeeffffed0302000302000d0c00ffffecffffec +f5f4e0fffeeafefde9f3f2de030200050400030200ffffedeae9d5ffffec080700ffffed +f1f0dc0302000302000403000a0900040300f1f0dcf3f2de0a0900030200030200ffffed +fefde9ffffedffffecf5f4e0030200fdfce8ffffedfdfceaf0efdb030200ffffed030200 +ffffedffffeff4f3dfffffeff8f7e3030200ffffededecdafcfbe7fdffe9feffeafcfee9 +feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffbfffffb +fefdf9fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dc +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeece0eeeee4eeebe4ede9def4eddbf4eac7fcf0b6ad9e4dfff690ffff8dffff8bfff88c +fffa9ffafcb1e0e8afbacdaf9cbfc1a9d4e4c7edf6bbdce1b2cccdb7cac8b4bfb9b8bfb8 +a8aea4b1b7abbec6b7d1deccc9dac7dcf1dee6ffecf4ffe5fffec3aba05e7d723cfff5c8 +fdf2d4f8f0dbe6ded1efe8deefebe0efebdfefebdfefebdfefebdfefebe0efeae4efebe2 +efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfedebdceeefdfeceee0e9ece1ebf0eae6eae9eaeef197989d +fffdfffaf0fb92808cfff2ffa28291ffe7f6ffddec321031f7f1fff1f7ff1e246ee7eeff +d4d9ff000619fbffff53594ff4f8e9fefff1f9fbee000100fffefff4f2fffffbff000010 +fffeff010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7f7f9e4ffffefe3e4d6f9faea +fdfeeeffffedfcfee8fcfee8ffffedf1f2e0ffffeff5f7e2fdfeecfafce7ffffecebedd7 +feffeafcfee8f1f3ddffffeaffffeaffffeae7e9d1fdffe9faf9e4ffffecf9f8e4edecd7 +ffffedfaf9e4ffffedffffeaf5f4e0ffffecfffeeaffffeafefde9f3f2ddffffedffffed +ffffedf4f6e1feffedffffedf5f6e4ffffede4e5d3feffebffffefffffedf9fae8ffffed +eceddbffffedfcfdebffffefffffefffffefeeefddffffeff0f1dffdfeecf9fbe6ffffed +ffffedf5f7e2ffffecffffecffffecfeffeaf5f7dffbfde5fcfbe7f9f8e4ffffedf6f5e1 +fdfce8ffffebfffeea0b0a00f5f4e0ffffedfcfbe7ffffedf2f1ddffffebf9f8e4eeedd9 +fffeeaffffedffffebfefde9f0efdbffffedf3f2de070600ffffedffffedf4f3dfffffed +f5f4e0fdfce8ffffedfbfae6f5f4e0ffffecf9f8e4f5f4dfffffedffffecffffedffffec +f9f8e4fbfae5f0efdbffffecffffedfffee9e6e5d1ffffedf5f4e0fbfae6f1f0dcffffed +f7f6e2ffffebffffedfcfbe7fffeeafffeeaf4f3dfffffedffffedeae9d5faf9e5fefde9 +ffffecf5f4e0fdfce8fcfbe7fefde9ffffedffffedf5f4e0faf9e5ffffedfaf9e5f1f0dc +ffffedffffedfbfae6ffffedffffedf9f8e3ffffedffffecffffedfefde8ffffebfdfce7 +faf9e5ffffecf3f2deffffeceeedd9ffffecffffedffffecfdffe7feffeafcfee9feffef +010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffbfffffbfefdf9 +fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfecece0 +eeeee6ecebe7ede8e2f4edddf4eac7ffefb3af9d47fffa8dffeb73fff37bfffc8cfff492 +fff9a5fbfbb3dbe7b590ad99a4c8c49fc0b7bad8ce9db2abdcede7ced8d7ecf2f2fafeff +fcfffbeff5ebeef6e7d2ddccedfbeaf5fff8fcffead0cc8d7d742993874bf8eebdebe1be +eae2cbf4ecdffaf3e9efebe2eeece0eeece0eeecdfeeecdfefebe0efebe2efebe0efebe0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecdfebecdcedefe1eceee1e9ece1ebf0eae6ebe7ecedef98979ceee7ef +fffaff897580fff5ffa7838fffedf74d1d2967465bfaf8ff06124297a3cb1c2745dce7f9 +030e14f9ffff474f44fafff2f3f7e9fffff8030400f5f4f9fffdfffffcff01000cfffeff +010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7fbfde8f3f4e2fffff3fffff1eeefdf +fbfde8ffffecf3f5dfeaecd7ffffedf6f8e3feffebffffedf4f6e0ffffecffffecf9fbe5 +ffffeaffffeaf8fae2fdffe7eceed6ffffeaffffeaffffeaf7f6e1f5f4dfffffecffffec +fcfbe6f0efdaffffecffffecffffecffffecfffee9fdfce7ffffecfdfce7ffffecfdffea +eff1dcfeffebfeffebf5f7e2ffffecffffedf7f9e4edefdaffffedf5f7e2fafce7ffffed +e8ead5ffffedeff1dcf7f8e6fdfeecffffefe4e5d3ffffefffffeffdffeaeceed9ffffed +f8fae5fcfee8f2f4def4f6e0ffffebffffeaffffeaffffecfdfce8f8f7e3ffffedfcfbe7 +ffffedebead6060500ffffedfaf9e5f9f8e4fefde9ffffedf6f5e1ffffedffffedffffeb +f8f7e3ffffebfffeeaffffedfaf9e5ffffed050400f4f3dfffffecf8f7e3ffffedffffec +ffffedfbfae6fcfbe6ffffebf6f6deffffecffffeafffee9f3f3dbffffeafcfce4fbfae5 +ffffeaffffecf7f7dfffffecf6f6deffffecfcfbe6ffffebfffeeaffffedf9f8e4ffffec +fcfbe7fcfbe7fffeeaffffecfefde9f5f4e0ffffebf1f0dcffffedffffedfdfce8f3f2de +ffffedfdfce8ffffedfdfce8f6f5e1f5f4e0ffffedf6f5e1fffeeaffffebffffebefeeda +fcfbe7f5f4e0ffffecffffecf2f2daffffecffffe9fefde8fafae2fcfbe6ffffe7ffffec +fafae2f7f6e1ffffeaffffecf2f2dafefde8f3f3dbfdffe7feffeafcfee9feffef010100 +908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffbfffffbfefdf9fffffd +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfebede0edeee6 +ecebe7ede8e4f4edddf6e9c6ffefafb29d44fff182fcdf67ffe36effee80ffe989f7e78f +f0e897e1e09de0e5bcadb89aacbca1a1b6a3d9f0ead9f4fdd3eeffc0dafbd5edffd6ecff +d3e4ecd2ddd7dcded0fffae7fffdedfeefd0aba0628c823ae2d69cfff4c6f2e7c9ebe3d0 +f5ece3f3ece6efeae4eeebe4eeece0eceddfeceddfeeecdfeeecdfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeecdfebecdeedefe1eceee1e9ece3ebf0e9e6ebe7ecedef98989afffdfffcf1f7 +918086fff7fd88696fffecf0fff2f83e2425fafffbf1ffff3f534a384941e8f7f0000500 +f9fffb535a53fcfffbfcfefbfffffd000000fefcfffefcfffffeff010002fffffd010100 +fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7f9fbe6ffffeff5f6e8f2f3e3fffff1f3f5e0 +ffffecf9fbe3fbfde7ffffece8ead4ffffecf7f9e3f9fbe5edefd9ffffeaffffeaf0f2da +fafce4ffffe8fafde2ffffe8ecefd4ffffe8f5f5ddffffeaffffeaf6f6deffffe7f8f8e0 +ffffeaf2f2daf9f9e1fcfce4f4f4dcffffeaf2f2daffffeafcfce4ffffeaffffecfdffe9 +feffeaffffecf6f8e2eff1dbffffecffffebf1f3ddffffecf1f3ddffffebffffecffffec +f3f5dfffffedfeffedf1f2e0ffffeffeffedffffeffeffedf2f4dfffffedf3f5e0ffffed +f9fbe5ffffecf8fae4ffffecfdffe7f8fae2ffffecfffee9f7f6e1ffffecffffecf6f5e0 +ffffecf5f4dfffffecf9f8e3ffffecf9f8e3f2f1dcffffecf2f1dcf6f5e0ffffecf8f7e2 +ffffecfdfce7fffee9ffffecf3f2ddffffecffffece5e4cfffffecffffecf5f4dfffffec +ffffecfcfbe6ffffeaffffe5fefee6dedec4ffffeaffffe8ffffeafefee4ffffeaffffe7 +f6f6deffffe8fefee6ffffe8f8f8e0fafae2ffffecf8f7e2faf9e4ffffecfbfae5ebead5 +ffffeceeedd8fcfbe6ffffecffffecfefde8ffffecffffebeae9d4fffee9ffffecedecd7 +ffffecfaf9e4fffee9ffffecf2f1dcffffecffffecfefde8fefde8f5f4dfffffecffffec +ffffecf1f0dbf8f8e0ffffe8fafae2efefd5fefee6ffffe8ffffeaffffe8ffffeaf9f9df +ffffe8ffffe8e2e2caffffe5ffffeaffffeafdffe7feffeafcfee9feffef010100908f8a +aaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffbfffffbfefdf9fffffdffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfebeddfecf0e2ecebe7 +ece9e4f5ecddf7e9c6ffefadb49c42ffeb7dffe975ffdf73f9d773f6d87ee8d27cd1c26d +c0b86fc8c494c0c09ee0e7c6edfce7e4faf7c2ddeeaccaf0b9daffc7e4ffc4def9d2e5e9 +ccd9c8f4f4d8fffedefff7dcddc7a282733a887d3ffef2c0f3e7c1fff5dff7ede1f5ebe9 +ede8e5eeeae7eeebe6ecece2eceddfecedddeceddbeeeddbeeecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfedebdeeeefe1edede3eaebe3edf0e9e6ebe7eaeeed97989af7f5f8fffdff857b7c +fffafb978183ffeae9f2d4d2f3e1d5e0ebcdcae2bedcf1d2eeffe7ccddca0e1c0ff1fcf4 +4a5350f4f8fbfcffffeff0f4020204fffefffffffdfdfcf7020100fffffb010100fdfdf1 +ffffeff9fbe3ffffe8fdffe5fdffe7ffffedf5f6e4fffff2fffff1fafbebffffedebedd7 +ffffeaffffecf7f9e3ffffecffffecf7f9e3ffffecf8fae2ffffeafbfde5ffffeafcffe4 +ffffe8eff2d7ffffe8ffffe6f3f6d9ffffeafbfbe3fbfbe3ffffeaf1f1d9ffffeaf7f7df +ffffeaffffe7ffffeafcfce4fdfde5ffffeaf8f8e0ffffeaf8f8e0ffffecf9fbe5ffffec +f0f2dcfcfee8ffffecf0f2dcffffecffffecf9fbe5ffffecffffece6e8d2ffffecfeffea +f6f8e2fbfceaffffefebecdaffffeffbfceafafbe9ffffedf4f6e1f4f6e1ffffedf7f9e3 +f3f5dfffffecf4f6e0f3f5ddffffeafffee9f9f8e3ffffecffffecf0efdaffffecf0efda +ffffecfbfae5ffffecf9f8e3ffffecffffecf4f3deffffecffffecffffecffffebfbfae5 +ffffecf6f5e0ffffebffffecfbfae5f5f4dfffffecfcfbe6efeed9ffffecf6f5e0fdfce7 +ffffe8f9f9dffafae0ffffe8ffffe8f8f8defdfde3f3f3d9ffffe8fefee4fdfde3ffffe8 +ffffe8f9f9dfffffe7fbfbe1ffffe8f8f8e0ffffecfdfce7fbfae5f8f7e2ffffece7e6d1 +ffffecfaf9e4ffffecf6f5e0fdfce7ffffebffffecf3f2ddffffecfaf9e4ffffecfffee9 +fbfae5ffffebfdfce7ffffebfaf9e4ffffeaf6f5e0ffffecffffeaf9f8e3fdfce7fcfbe6 +ffffe8fdfde3ffffe8fafae0ffffe8f7f7ddffffe6ffffe7f9f9dffdfde3fdfde3fafae0 +ffffe8ffffe8fdfde3ffffe6f9f9dffdffe7feffeafcfee9feffef010100908f8aaaa9a7 +d8d6d7f8f6f9fefcfffffefffffefffffefffffffbfffffbfefdf9fffffdffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddebeed9ecf0dfecebe6ece9e4 +f5ebdff7e9c6ffefadb59c42f5d66cffdf71ffdc7ce4bf67e5c475ffe699fff2a0ffffbf +fffedbfafde8f0f8e1dfecdacddddac4d7e5c6dbfacce3ffcde1fccbdee5c2d4bccedbaf +fbffc8ffffcdffffd4aa9d717a6e3cf7eabdfff3d0f1e5cdfbefe3eee4e2f4ebeeebe5e9 +eeeae9ecebe6ecece2ecedddeeeddbeeedd9eeedd9eeeddbefecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeeadef1ede1efece3ebebe3edf0e9e6ebe7eaeeed95999afcfffff8faf98c8b89fffffa +0600000f06000f0200070200000b00122300011100000700051302000b03f9ffff495154 +f2f5fcfcfffff6f7fc0000020a0907050400030000fffff6fffffa010100fdfdf1ffffef +f9fbe3ffffe8fdffe5fdffe7ffffedeceddbfffff3fffff0f8f9e9f9fbe6ffffecf8fae2 +fdffe9f7f9e3ffffecf1f3ddffffecfdffe9f7f9e1ffffeaffffeaf8fae2fafde2ffffe8 +f7fadfffffe8fcffe2ffffe6f9f9e1ffffeafcfce4f8f8e0ffffeaffffe9ffffe9fefee6 +f7f7dfffffeafdfde5ffffeaffffe9ffffeaf3f3dbfcfce4ffffece7e9d3ffffecfdffe9 +ffffebfeffeaebedd7ffffecffffeceff1dbffffeceff1dbf9fbe5ffffecffffebf8fae4 +ffffefffffefeeefddffffefffffefffffefeceed9ffffedfdffeafdffeafdffe9fdffe9 +fdffe9fdffe9fdffe7fdffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe5ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe5ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe5ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe5fdffe7feffeafcfee9feffef010100908f8aaaa9a7d8d6d7 +f8f6f9fefcfffffefffffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc7 +0837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeeddbebefd8edf0dbecebe6ede8e4f5ebdf +f7e8c7ffefabb59c42ffe67ffcd76ff6cd75ecc276ffe4a0fff6b0ffffadfffbb2fffac9 +fffdd7fafcd4e7f1cecfe0cdc2d6d5c0d6ebc3ddf6bdd7e4bbd2c8d7edbfe7f6b1ffffb6 +fdf7a9e1d1939b8a56a09168f1e4c4f0e4ceefe3d5f9eeecece1e5f4edf4f0ebf1eceaeb +ecebe6ecece0ecedddeeedd9eeedd8eeedd8efecd9efecddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0eade +f3ede1f0ece3ebebe3eeefe9e8eae7e9efed949a9af9fffff6fffc7a807cfcfffafcfff8 +fefff6fffff3fbffeef7feece6efdefbfff6f9fffaf5fef9f1faf9f9ffff4a4f55fcffff +f3f6fdfeffffeaebedfbfbf9fefdf8fffff6fffff6fffffa010100fdfdf1ffffeff9fbe3 +ffffe8fdffe5fdffe7f8fae5090a000102000102000d0e00fcfee9020400ffffeaffffec +f6f8e2ffffecf4f6e0f8fae4ffffecf7f9e3f5f7dff9fbe3ffffeafcfee6ffffe8feffe6 +e8ebd0ffffe8ecefd4ffffe9ffffe8ffffeaffffea030300ffffeaf2f2daffffe8ffffea +fafae2ffffeaf7f7dfffffea0303000c0c00090900f6f8e2ffffecf2f4de050700010300 +090b00ffffecf1f3ddfafce6ffffebf9fbe50e1000010300ffffeceaecd6ffffed010200 +030400ffffef0c0d000102000102000f1100edefdafdffeafdffeafdffe9fdffe9fdffe9 +fdffe9fdffe7fdffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe5ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe5fdffe7feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9 +fefcfffffefffffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db +1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeeddbecefd4edf1daecebe6ede8e5f5ebe1f7e8c7 +ffefabb59c40ffe581efc968e5ba6cf6cd8bfff8bcfff8b5ffffaefff39bfff49dfffba5 +ffffa9f3faadd6eab5bedcc4b0d7dcadd9e6aad6d9b7dfc7e6ffc7daed93ffff9effff9a +d0ac58896527e5d1aef9eedcede0d7f5eae6f9eef2eae0e8f3ecf4eee9efecebe9ecece4 +eeecdfeeeddbefecd9efedd8efecd9efecdbefecddefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdff1e9def4ece1 +f0ece3edeae3efeeeae8eae7e9efed929b9af1fbfaf7ffff808d86bfccc3c0cdc3d0decf +b2bfaec5cfc7e3e3efd2cfe4c1bed1cfcee0cdcfdccbcdd9c8cbd454575ef2f5faf4f8fb +f6f7f9fefffffffffff7f7f5fffffdf6f5f3fffffb010100fdfdf1ffffeff9fbe3ffffe8 +fdffe5fdffe7010300f1f2e0fffff3fffff1e7e8d8ffffede9ebd5f8fae4fdffeaffffed +eaecd7ffffedf9fbe6fbfde7fcfee8ffffecfeffeaeff1d9ffffeaf6f8e0ffffeafcfee6 +f4f6deffffeaffffe7ffffeafdfce7030200030200f9f8e3ffffecfefde8fefde8ffffec +ffffeafefde8060500f9f8e3fffee9fcfbe6020400f0f2dd121400f6f8e3ffffedeff1dc +010300feffebffffedeceed9ffffed010300080a00f5f7e2fcfee9eef0db010200030400 +fafbe9010200ffffeffdfeecf8fae5060800fdffeafdffeafdffe9fdffe9fdffe9fdffe9 +fdffe7fdffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5fdffe7feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcff +fffefffffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff3 +1e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeeddbecefd2eef0d8eeebe6efe6e7f7eae1f7e8c7ffefaa +b59c3ffbdb74e7c363deb46affe3a5fff2b8ffedaafff69dfff991fff587fff985ffff89 +fcff92e6f5a0cee7aeb9d9c2afd3c9bee1cdcdeec1f1ffb7d2df75ffff92ffef87b18a3b +ad8551fff2d7fbf1e7ede4ddf8eeedf6edf2eae3eaf4eff3e9e5e6ecebe6ecece0eeecdd +efecd9efecd9f1ecd9f2eaddf1ebddefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdff1e9def4ece1f0ece1 +edeae3efeeeae8eae9e9efef929b9af7fffff5ffff4c5b5652615a415146516154556656 +49524d433e525c516f5c526d4b435a524e5f504e5b58586046474cfcfffffcfffffeffff +f9fbfaffffffffffffeeeceffffefffffffd010100fdfdf1ffffeff9fbe3ffffe8fdffe5 +fdffe7060800f0f1dffbfceefffff1feffefedefda151701fafce6010300010200121301 +010300fdfeecf9fbe6020400040600010300ffffecf7f9e3fcfee6010300ffffe9ffffea +eceed8f9f8e3fcfbe6ffffedfefde80b0a00fefde8fbfae6ffffecffffedefeed9fdfce8 +ffffec030200ffffeaffffedfffeea050700fbfde8feffedffffede9ead8ffffed030400 +ffffedf8f9e7ffffedf3f4e2030500fbfcea010300ffffef0f1000fcfdeb101100f8f9e7 +0c0d00fafbe9fbfceaffffed010300fdffeafdffeafdffe9fdffe9fdffe9fdffe9fdffe7 +fdffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5fdffe7feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffeff +fffefffffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bc +e2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeeddbecefd2eef0daeeeae7efe6e9f7eae2f7e8c7fff0a8b49d3d +fade73e9c765e1bb70fff9b9ffecadfff2a6f5f08affff8efffa82fffa7cfdfe74fdff79 +f9fe88edf294dcde9fced09ee9eab1ebeda2fcff96edec76ffff96bfad57876b3bf2d8bf +f4e7d6ece6dae9e5dcf0ebe7ebe7e6eeeae9f6f5f1e6e6deeeecdfeeeddbefecd9efecd9 +f2ebdbf2eadff3e8e2f2e9e2f1eae0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0eadcf1ede1f0ece1edeae3 +efeeeae8eae9eaeeef929a9cf9ffffedf7f8ebf5f4f8ffffe7f2eceffaf2effbf1fcfffb +fffbffeddde8fffafffffbfffffcfffdf8fcfdfbfefafafafbfdfcf0f2f1fcfdfffeffff +f8f8fafffefffbf9fefffefffffffd010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7 +eff1dc20210f010200010200f0f1e1ffffed060800f8fae4feffedf5f6e6eeefdf0a0b00 +fdfeee0b0c00ffffeffbfde8ffffed010300fbfde8ffffec0a0c00f1f3ddffffecffffec +ffffedffffedfdfceafcfbe7030200f7f6e2ffffeff5f4e0ffffefffffedffffeffaf9e5 +060500ffffedffffeef5f4e2010200fcfdebfffff0f6f7e5fffff1030400edeedefbfcea +fffff1f8f9e7f8f9e9090a00fffff1080900eaebdb050600fbfcea040500f7f8e6020300 +010200010200010300fdffeafdffeafdffeafdffe9fdffe9fdffe9fdffe9fdffe7fdffe7 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +fdffe7feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffeff +fffefffffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8ff +f4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecdbeeeed4f0efdbefe9ebefe5edf7eae4f7e8c7fff0a6b29f39ffe577 +e0c35de9c879fff8b5ffe8a4fffda9eded7bf8fc81fafa88f8f781f8f971fefd71fffe7e +fff68af6e492edd690ffea9efff495fff378f3e868f7ea7aa392409e8662ffeee0ebe4d2 +eae8d9efede0edede3e8e8e0eeeee4f1f1e5e6e7d7eeedd9eeedd8efedd8f1ecd9f3e9df +f5e8e2f5e7e7f3e7e7f1eae2efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfedebdcf0eee1edede1ebebe3eeefea +e8eae9eaeeef95999cf7fcfffbfffffbffffecf0f1fcffff0f14100002000101000a0000 +1f10000d00000a0000080000fffef4fefbf4fffffbfffffffefffff9fafefeffffebeaef +f3f3f5fffefffffefffffffd010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7ffffed +fdfeecf7f8eafffff10a0b00f4f6e1040600f3f5dffcfdebfffff1080900fafbebf9faea +040500010200070800010200020400f7f9e4feffebffffecf5f7e1fbfde7f6f8e3ffffef +ebead8ffffeffcfbe91c1b09f0efddffffefffffeffcfbe9efeedcffffeff6f5e3030200 +ffffefffffeeffffef010200fffff1fffff1f2f3e3010200fbfcecf6f7e7fffff1f8f9e9 +feffeffffff0030400e6e7d7fffff1030400f9faeafbfcea010200ffffef010200ffffef +ffffefffffed010300fdffeafdffeafdffe9fdffe9fdffe9fdffe9fdffe7fdffe7ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7fdffe7 +feffeafcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffeff +fffffbfffffbfefdf9fffffdffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2 +e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecdbeeeed6f0efddefe8efefe5eef7e9e6f7e8c7fff1a4b29f38f8e16fd2b74c +ffe491ffeca3fbea9cfffb9be8ef6eeff877f6f392f7f095fcf281fff47afff480fff08a +ffe797ffe197ffe591fff78dffec66efdc51ccb940a38f36e5cca4f0ddccf6f0daeef0da +f2f4dfeef1deebeeddeaeddae6e9d4ebedd5eeeed4eeeed4efedd6f1ecd9f3e9e0f5e7e7 +f6e5edf5e6edf1eae4efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecdfebecdcedefe1eceee1eaebe3edefeae8eae9 +ecedf197989dfffefffffefff4f3f9fffefffffdff030000fffdfdffffe6fffbb2fff99c +fbf3a2ffffc10a0400161100fcf9e8fdfcf7faf9fefffdffeaeaf4fefefffffefffffffd +fffffaf8f9f3fffffb010100fdfdf1ffffeff9fbe3ffffe8fdffe5fdffe7f5f7e2ffffef +fffff3ebecdc080900feffeb010300feffeaf9faea010200f4f5e7f8f9ebfffff3010200 +f1f2e2fffff1fcfdedffffefffffefffffefffffeffafce7ffffedfeffebf8f7e5fffff1 +fffff1f4f2e3030100fffff1fdfbecefeddefffff1fffff1fcfaebfffff1030100fffff1 +f8f6e7f7f5e6020300fffff3f9faec010200fffff3fffff3fffff3f8f9ebfffff3f9faec +f4f5e7080900f5f6e8fffff3020300fffff0ffffef080900e4e5d3080900f8f9e7eaebd9 +ffffed020400fdffeafdffeafdffe9fdffe9fdffe9fdffe9fdffe7fdffe7ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe7fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9ffffe7ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe7fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fdffe7feffea +fcfee9feffef010100908f8aaaa9a7d8d6d7f8f6f9fefcfffffefffffefffffefffffffb +fffffbfefdf9fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eada +ebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecddeeedd9f0eedfeeeaebefe6e9f5ebe2f6e9c7fff1aaaf9f3feed86bc9b147ffffa6 +ffe994ffed94fdf088f3f06ffdf97cfbec91ffec96ffef88ffee7effeb7cffe881ffe890 +ffea97ffe68affea80ffe96bffea6ba8962a867324fff8d1feedd9f3eed8e7e9d3e8ead4 +e9ecd7eef0dbe7ead5e2e4cef6f8e0eeeed4eeeed4efedd6f1ebdbf2e9e0f3e8e6f5e6eb +f3e7ebf1eae2efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeceddfe9eddeeaf1e1edeee0edebdfefefe7e9eae5e9efef +94999dfaf8fffcfeff00050f000c11000d0c000f0e000007fffde8fffca7fff280ffff9a +f9ee9c080500ffffe2080800fdfdfbf7fbfafefffffffcfffffcfff4f8ffeff7f9fcfef1 +fffff1fffff8010000fffcf3fffff1fbfae6ffffecffffe7fdffe9ffffedf8f9e7f5f3e4 +fffff1030200ffffed030200feffeb060400fcfdeffffff2fffff3efede0030400fffff1 +fafbebfffff1010200ffffeff2f3e1060500ffffeffaf9e7fffeecffffeffcfbe9f4f2e3 +ffffef0b0900e9e8d6fffff1ffffeffefced070600f2f0e1ffffee030100fdfceafffff1 +fffff1030100fffff10d0b00f9faeafffff1f9faeafffff1f6f7e7fffff1fbfcecfbf9ea +070800fffff0fafbebfffff1fafbebf5f4e2050600ffffef010200ffffedffffeff6f5e1 +080a00fffeeafdffeafffee9fdffe9fffee9fdffe9fffee9ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fdffe7feffe8fcfee9 +feffef010100908f8aaaa9a7d8d6d9f8f6f9fefcfffffefffffefffffefffffffdfffffb +fefdf9fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dc +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfecedddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +f3f6e5e1e4d3f2f0e4f5f1e5e8e2ccfff8d4f5e9ada69649f5e085dbc35ffff995ffe47e +fedf75ffe97bffe671ffe977ffe27effdf7effea7ffedd6cffed7cffe677ffec82fbe079 +f0d773d8c161c8b556b1a14a8e7f3af1e1aefff0d1ebdfc9f1ecd9eeeddbeeeddbeceddb +eeeddbeceddbeeeddbeeeddbeeedd9eeedd9eeeddbefecddefebdfefebe0f1eae2f1eae2 +efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfebeddfe4efdee9f2e1f3ecdcf5e7daf6eddeeaeadee2f3e98b9d9f +fbfcfff1ffff00102064cccf0391835dd1c8000a1b614446674a0effffa6ffea94fff6b2 +0b0b00fafff9f7faff000107f4fff3f9fff1ffebf6fff7ffecfafff0fffffbfde8ffffe4 +fffef4030000fffaf6fffff6fdf9edfffff1fbf8e7f8f7e50b0800030200171403030200 +f8f5e2fefde9040100ffffef0401000a0800040100171506f6f3e4fefced060300030100 +040100fffdeefffff0fffff0040100fffdeefffff0ffffeffaf7e6fffce9ffffef040100 +0906000c0900e9e6d5ffffedfffdec040100f7f4e3ffffedf3f0df040100120f00040100 +ffffeff8f7e5110e000302000401000e0d00040100fffeecfefbeaffffeffefbea030200 +ffffefffffefefecdbffffeff3f0dd181703fbf8e5030200100d00030200040100ffffed +fffdeafffeeafffdeafffeeafffdeafffeeafffdeafffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffdeafffdeafffdeafffdeafffdeafffdeafffdeafffdea +fffdeafffdeafffdeafffdeafffdeafffdeafffdeafffdeafffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffdeafffdeafffdeafffdeafffdeafffdeafffdeafffdea +fffdeafffdeafffdeafffdeafffdeafffdeafffdeafffee9fdffe7fdffe8fbfee9fdffef +0002008f908aa9a9a9d7d7d9f7f6fbfdfcfffffefffffefffffffffffffdfffffbfdfef9 +fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfecedddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddecedddeceee0 +e2e4d6eeefdff0eed9e6e0c6faf2cdf4e8b6bfb06fd7c475f3dc7ffff995fbdc72ffdf73 +ffe479f9d368ffdc76ffdf7dffd979ffdd7afcd973f3d46ad3b74cbea63cb09a34a39334 +92832e91853d82763cfff9ccf4e9c9fff7def0e8d5efecdbeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfebeddfe2f0dfe7f2e1f4ebdcf8e6d8f9ecdceaebdbdff5e8899f9dfbfdff +dcf0ff001b2a0381803bebd7008476000619fff3f8fff7c2ecc776fffbadffefb2070200 +000300151723000105000700f1fbe3fffbfdfffaffebfafff1fffff5f4dfffffe3fffbf1 +191410fffefafdf9f0f8f4e9fdf9edfffff0ffffeff7f4e1f1efdafbf9e4fffde8ffffec +ffffecfffce9fffce9fffeedf1eeddffffeff8f5e4f8f5e4ffffeff2efdeffffefffffef +f2efdefefbeaffffeff2efdef9f6e5ffffeff2efdeffffedffffecffffebfbf9e4ffffec +ffffeafffde8f6f4dfffffecf9f7e2ffffecfdfbe6f9f7e2ffffecf2f0dbffffecf8f6e1 +fffde8fbf9e4ffffecf7f5e0fffde8fbf9e4ffffecffffebf3f1dcffffecfbf9e4fefce7 +ffffecf9f7e2ffffecffffecfefce7fefce7f7f5e0fffee9fdfbe6faf8e3f7f5e0fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9fffee9 +fffee9fffee9fffee9fffee9fffee9fffee9fffee9fdffe7fdffe8fbfee9fdffef000200 +8f908aa9a9a9d7d7d9f7f6fcfdfcfffffefffffefffffffffffffdfffffdfdfef9ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfecedddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddecedddebeddfebeddf +f1f2e2f0eddaece6cef7eecdf9eec0e8d99ebaa961ffffadf6dd80fbdf7cffe986f1cf6d +ffe686f9d479dbb864dab968c5a653aa8e3a8e741d8f7a218e7d2591822f85782afff8b3 +eae1a8efe7b9e6e0bef1ebd3e3dccafffceeefecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfebede0e3efe1e7f2e4f3ebe0f5e7daf9ebdeeceadbe0f4e88a9e9cfcfefff4ffff +00101b6fd1d000907962d7c400070efff7effff7b7fffea67a4000fff6bceddaafffffe8 +f4f4eafffffb141007f7f7edf8fffaf2fffaecf7f3f8faf5ffffeffdf4e3f3efe4060300 +f0ede4fffff3fffff1fcfbe9f5f4e0ffffecffffeaffffeaffffe8fdfde3fdfde5f7f7df +ffffebffffebffffecfbfae5fcfbe6ffffecfefde8fffee9ffffecfcfbe6ffffecffffec +fcfbe6ffffecf7f6e1ffffecffffecffffecfdfde5fdfde5f7f7dfffffeafbfbe3ffffe9 +fefee6ffffeaf0f0d8ffffeaeaead2ffffe9fcfce4ffffeaf9f9e1ffffeaffffeaf8f8e0 +ffffeafdfde5ffffe8fcfce4ffffeaf8f8e0ffffeaffffeaf8f8e0ffffeaeaead2fafae2 +ffffe9ffffe9fbfbe3fefee6ffffeaffffeafcfce4ffffeaffffe8ffffeaffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7 +ffffe7ffffe7ffffe7ffffe7ffffe7ffffe7fdffe7fdffe8fbfee9fdffef0002008f908a +a9a9a9d7d7d9f7f6fcfdfcfffffefffffefffffffffffffdfffffdfdfef9ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfecedddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddebecdef1f2e4f1efe0 +efecdbf3edd7f6edd0f9edc5fff3bfaa9b5af1df95ecd784e0c870ddc26bddbf69b2923f +aa8a3d977c39a08848846c2c7e69289d8a48f3e4a1fff7b6f0e6a8f6edb4faf4c2ebe6be +ffffe1f9f7e0efeddeeae8dce5e2d9eeecdfeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +ebede0e4eee3e7f1e6f2ebe1f4e8dcf8ece0eceadde3f3e68b9e98fefeffe9f1fe001721 +276c6966d1bd227b67000907ffecdefbf0b8ffffb6624600fffcb2f9ffc1edffcfedffe3 +e6fae1010000fffdfdf5fcf5f8fffaf7f8f0fffff8fffaf4fffef8fffff60a0800f9f7ea +fffdeeffffeefefde9f7f7dfffffe8ffffe8e6e6caf5f5d9f8f8dcffffe8ffffe8f0f0d8 +ffffeaf3f3dbffffeaeeeed6f7f7dfffffeaffffe8f8f8e0f6f6def4f4dcffffe9fcfce4 +ffffe9f5f5ddfdfde5f9f9e1ffffe8f8f8deffffe8ffffe8f7f7ddffffe8ffffe6ffffe8 +f5f5dbffffe8fbfbe1fefee4ffffe8ffffe8f6f6dcffffe8ededd3fefee4ffffe7f0f0d6 +fefee4ffffe8fdfde3e7e7cdffffe8f3f3d9ffffe8fafae0ebebd1ffffe8ffffe7ffffe8 +f4f4daffffe8f6f6dcfbfbe1fbfbe1ffffe8e9e9cffafae0ffffe8ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5fdffe5fdffe7fdffeafbfeebfdfff10002008f908aa9a9a9 +d7d7d9f7f6fcfdfcfffffefffffffffffffffffffffffffdfdfdfbffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddfecedddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdde8e9d9edeedeeae8dbeae7d8 +f5eedcf1e9d2f1e6c6fef2c8b0a36ed7c789af9c57ad9950846e257c641c9e834091793d +8d7b49ddcfa2fffacdfff8cce7dcaffff7ccfcf4cdefeac4fffadad0ccaff9f7e0e6e5d3 +ebebdfd8d9d1f6f7f2eeefe9ecece0eeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfecece0 +e6ede5e9f0e8f0ece3f1e8dff6ece2eceadee5f3e68d9e96fafdfffcffff00030b001211 +002111001300000400fffff4f4ffefebffe1e7ffc83b821a08770011890d036b0c00440a +001000fffdffffebfcfff4ff09030700010206060ee5e6eaf9f8f3030100fffff1fdfcea +ecebd7ffffecffffe7fefee2fafadeffffe4ffffe1ffffe4fbfbdff7f7dbffffe8f3f3d9 +ffffe8ffffe8ffffe8ffffe7f0f0d6f4f4daffffe8ffffe8ffffe8ffffe8fcfce2f6f6dc +ffffe8ffffe8fafae0f7f7ddffffe8fefee2ebebcfffffe4f4f4d8ffffe6f9f9ddffffe6 +fcfce0ffffe6f8f8dcf5f5d9f6f6daffffe6ffffe6ffffe6fbfbdfffffe3f5f5d9ffffe5 +ebebcfffffe6ffffe6ffffe6fdfde1fafadeffffe5ffffe6ffffe3ffffe5fdfde1ffffe4 +f0f0d4ffffe6ececd0ffffe6ffffe6ffffe6ffffe6efefd3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3ffffe3 +ffffe3ffffe3ffffe3fdffe5fdffe9fdffebfbfeedfdfff20001008f908ba9a9a9d7d7d9 +f7f6fcfdfcfffffefffffffffffffffffffffffffdfdfdfbffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc7 +0837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfecedddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddedebdcefeddeebe7dbebe7dbf5efe1 +f2ebd8f0e6cdf7edcaefe3b98e814d83743b817136a7945afff1b9ffe9b7f8e6b8f8ebc8 +f7f1d1f0e7caebe4c8e7e1c7f6f2d9f6f1ddf3f0ddf0eedff5f6e8f1f1e7e4e5dddbdcd6 +fefffbe1e3e0e4e7e0ecece0eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0e9ece3 +ecefe8f0ebe5f1e8e1f5ece3ece9e0e5f2e88d9e96f7fcfffffeff090810000205e8ffff +001203000a00eefcefdffff7236e43147a2736b1463dcc560ca234007f2d076f3e000c04 +fcf4ffffe9fe18000cfffbfffbfefff5f8fffcfffffffffb030100fefcedffffefffffeb +ffffecf9f9e1fbfbe1ececd0ffffe6f9f9ddf2f2d6ffffe8fefee4fbfbe3ffffeaffffe9 +e7e7cffbfbe3fefee6fcfce4ffffeaffffeaf6f6dee9e9d1ffffeafbfbe3ffffeaededd5 +ffffeafdfde5ffffeaf8f8deffffe5fafae0ffffe8ffffe6ffffe8f8f8deffffe8fefee4 +fcfce2ffffe8ffffe7ffffe8ffffe6e6e6ccffffe8fefee4fdfde3ffffe8ffffe8fafae0 +fefee4ffffe8f0f0d6ffffe8f1f1d7ffffe8ffffe8efefd5fbfbe1fbfbe1ffffe8ffffe6 +fdfde3ffffe8fdfde3e9e9cfffffe8f6f6dcffffe8ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5ffffe5 +ffffe5ffffe5fdffe7fcffeafdffedfbfdeffdfff20001008f908ba9a9a9d7d7d9f7f6fb +fdfcfffffefffffefffffffffffffffffffffdfdfbffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db +1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeceddfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecddf0eedff1eedff0ece0efebe0f2ebe1f4ecdf +f3ecd9f2ebd1fff7d6f1e8c1fcf1c4fbeec2ebdeb2eedfb6fffad6f9ecccefe9cfeae8d3 +f6f1def6f3e2f8f4e8e8e6dae7e4dde6e5e0e6e5e1e9eae5e5e6e1ebece7fcfdf8e3e6df +d5d8d1fbfcf4ecece0eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0ebebe1f0ede6 +f2ebe3f1e8e1f5ece5eaeae2e5f2e98b9e98f7fffff5f6fb0d010dfff8ff070b0eeaf6f2 +06170fe0ffed276c4083e9a744cd750d9b4909824f006f5600807800414800061cfff8ff +fff9ff070005fcf6fffffdfffdfcfff2f2faf1f0ec1b1b11f7f7ebfffff2fffff1f0f1df +f8fae5ffffecffffeceef0dafdffe9fcfee8fdffeaffffedf0f1dfffffeeffffedffffed +ffffedf8fae5ffffedffffedf1f3defdffeaffffedf3f5e0fbfde8ffffedffffedf1f3de +f8fae5ffffedffffecffffecfafce6e6e8d2fafce6ffffecffffecf4f6e0fbfde7f8fae4 +ffffecf2f4def5f7e1ffffecffffecf7f9e3ffffecfdffe9f6f8e2f3f5dfffffecf3f5df +f9fbe5ffffecfbfde7ffffecffffecf0f2dcffffecffffecfdffe9f2f4deffffecf4f6e0 +f4f6e0f9fbe5ffffecfcfee8fbfde7f7f9e3fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9 +fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9 +fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9 +fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9 +fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9 +fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9 +fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9 +fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9 +fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9fdffe9 +fdffe9fdffeafcffecfdffeffbfdeffdfff40001008f908ba9a9a9d7d7d9f7f6fbfdfcff +fffefffffefffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff3 +1e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddfeceddfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeebdaedead9f0ece0ede9dee9e2daeee7dff4ece1 +ede6d4f3ebd4eae3c6fff7d6f0e7c6f7eccef8ecd2fff5ddeee6d1f1eedbefeedcf6f4e7 +e5e3d7f0f0e8eae9e4f4f3f1eceaebe3e1e2fcfafbebeae8e6e5e1ecece4e8e8def8faed +eaeadeeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeadef3ece2f3eae1 +f2e7e1f5ece7eae9e5e3f2eb8a9f9af2fffff9feff080009200b1cfff3ff000007000807 +2b654d8defb643c67a009144007e45003a2e67e9f93ad1ec61d8f6000723fef6fff6f7fc +000004fffcfffaf6fffdfdfffeffff0c0c0a010000fdfdf5fafaf0fffff4f1f2e4fffff1 +f7f8e8f9faeafafbebfffff1fbfcecfefff1fefff1f4f4e8fffff3f8f9ebfcfdeff9faec +fefff1fffff2fcfdeffffff3fefff1fffff3f9faecfffff3f9faecfffff2fcfdeffffff3 +f8f9ebf0f1e1fcfdedfffff1fffff1fcfdedfafbebf9faeafdfeeefafbebfffff1eff0e0 +fffff1f8f9e9fffff0f8f9e9fcfdedf6f7e7fafbebf7f8e8fffff1fdfeeefffff1f7f8e8 +f8f9e9f9faeafffff1f1f2e2fffff1f0f1e1feffeffdfeeefffff0f8f9e9f6f7e7fffff1 +fffff0f6f7e7fcfdedf4f5e5fffff1fdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeee +fdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeee +fdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeee +fdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeee +fdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeee +fdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeee +fdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeee +fdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeee +fdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeeefdfeee +fdfeeefcfef0fdfff1fbfdf0fdfff40001008f908ba9a9a9d7d7d7f7f7f9fdfcfffffeff +fffefffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bc +e2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +eaeadee7e5d9f1efe3f6f4e8efede1eeece0efede1edebdff9f7ebf4f2e6e8e6daf0eee2 +e7e5d9f5f3e7f8f6eaeceadde6e3d2f9f6e5e5e1d5f9f5eceee9e3ece7e3f7f0e8e9e3d7 +eee7d5f1ebd5fcf6def9f3dbe6dfccf8f1dff6eee1ece6d8f2efe0e7e6d4e9e7daf0eee2 +faf7eededbd6fffbfae9e5e4e9e5e4f0ece9edeae3fbf8efe8e4d8fbf8e7e0ddcaf6f3e0 +e6e4d7fffff4dfddd1ebe9ddfaf8ece6e4d8f3f1e5edebdfebe9dde0ded2f1efe3f7f5e9 +edebdff0eee2edebdff7f5e9f2eee2ebe7dbf2eee2efebdfede9ddf8f4e8eeeadef0ece0 +efebdfede9ddf2eee2f6f2e6f9f5e9ede9dde2ded2f3f0e1f1eadaf5ecddf7e9e0f4e7e1 +f4ece9e8eae7e3f1f1899e9ff0fffff4feff0800100b000e0a001007081c000e15003423 +007a3f008843008a54004f303ee8e53fe6f643dbf2003f55001422e9f7fff8ffff000005 +fffcfffffcffebf1edfbfffa0404020100000100000100000100000c0b06010100040400 +0101000505000101000808000302000100000100000302000201000101000f0f07010100 +010100080800010100090901050500010100010100010100050500010100010100010100 +0707000101000101000101000a0a02090901010100090901010100010100010100010100 +010100010100010100010100010100010100010100010100010100010100010100010100 +010100010100010100010100010100010100010100010100010100010100010100010100 +010100010100010100010100010100010100010100010100010100010100010100010100 +0707000606000101001111090101000101001010080101000303000101000d0d05010100 +0c0c0401010012120a010100090901010100010100090901010100070700050500010100 +0b0b03010100010100111109010100010100080800010100010100050500010100050500 +0101000101000101000606000a0a02010100010100070700010100010100030300020200 +0b0b03010100010100111109010100010100080800010100090901010100080800010100 +0101000f0f070101000202000b0b03010100010100020200010100010100040400050500 +0808000101000f0f07050500010100010100010100060600010100010100010100010100 +0404000a0a02060600010100010100010100010100010100010100010100010100010100 +0002000a0c010002000102000a0b057f807ba7a7a7d9d9d9f8f8fafbfbfdffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8ff +f4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeeee2 +f5f3e7f6f4e8d6d4c8f1efe3f2f0e4eeece0e8e6dae5e3d7e6e4d8f6f4e8f7f5e9ebe9dd +eceadee6e4d8f6f4e7ffffede5e2cfdfdbcff6f2e9e4dfdbede8e5fff9f6f9f2ecfaf4e8 +eeebdaded8c8e1decdf8f2e4f2eee3e5e0daf9f5eceae7d8f6f5e3f6f3e4e4e2d5ede9de +f6f1ebe2ddd9f4efebf4efebefeae4ede6dce4ded0e6e1cef0ebd7f8f2daeee9d5f0edde +dddbcffefcf0e8e6daeceadef2f0e4eeece0efede1fffef2f4f2e6edebdff5f3e7e3e1d5 +eeece0f7f5e9dbd9cde9e5d9fcf8ece7e3d7eeeadef8f4e8dad6caece8dcf2eee2f5f1e5 +e2ded2f3efe3f1ede1d9d5c9f1ede1fffff3e7e4d3f1ead7f7ecd8fae8dcf7e6dff4ecea +e6eaebe3f1f2899ea1e7fffff2fffffaf7fffff8fffff7ff000017002535bdffff60f3c9 +009b6a00785c3ae3d023e7d300a08a00866c1c9782001209f2ffffeef7fefafaff170d18 +0b0708000600f3fff0feffff0100040100040c0a0d010000fffffd010000d8d7d3bfbeba +0706029796947c7b7905030483818209070a0503060907080100008988868887851f1e1c +807f7d9a99970100009392908685830e0d0b8887858b8a880100001b1a18010000010000 +908f8d060503070604010000010000adacaa81807e8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a +8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a +8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a +8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a807f7d +8c8b894d4c4a8c8b89030200060503010000070604040301010000010000010000030200 +12110f6a69673d3c3a908f8d7e7d7b9b9a980100000d0c0a01000088878592918f8c8b89 +8a89877f7e7c8d8c8a89888691908e8c8b89010000040301050402010000908f8d010000 +9695938988868b8a88010000a2a19f757472010000100f0d0100000100008d8c8a8c8b89 +8a89877f7e7c8d8c8a89888691908e8c8b890100000100009a9997807f7d1f1e1c888785 +8988860100000908060100009b9a9898979582817f1b1a180100008685838e8d8b8d8c8a +0706048a898792918f8887850f0e0c9a999781807e010000010000232220757472999896 +86858381807e9b9a988d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c8a8d8c888a8b85 +8f90888e8f878e8f8981827db2b2b0bababadcdcdcf9f9fbfcfcfeffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2 +e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeaeadeefede1 +f5f3e70f0d01eceadef3f1e5eae8dcf2f0e4fdfbef030100f0eee2eae8dcf0eee2e7e5d9 +fffff3e6e4d7dfdcc9eae7d4fffff3ebe7de100b08040000040000040000dfdbd2f2f0e3 +fffbeff1efe2f4f0e5e0ddd6f8f5f0e1ded7e3e0d1f4f1e0e9e3d3ece9daf6f0e4fef8ec +ddd6ccfff8eef1eae0faf4e8f5ede0ffffedede6d3f5efd7faf2dbe7e1cbf9f6e7f4f2e6 +dcdacefaf8ecf1efe3e1dfd3f6f4e8f2f0e4e3e1d5eeece0e8e6dae9e7dbf5f3e7fcfaee +dfddd1fefcf0e8e4d8f2eee2f8f4e8efebdfede9ddfffdf1eae6daf2eee2eae6dae9e5d9 +ebe7dbf9f5e9fcf8ecede9dde7e3d7f1eeddeeecd3f5edd6fde7daf9e4dff2ecece6eaed +e3f1f48a9da3ecffffe9fcffeff6fffffcfff9eeff00001bb4def474cdd543d0c730dbcb +37ebe23bf8e200995b00bc5f1ce9732cc45f001500fcfffdf8fafff9f6fffff4f8fffcf3 +f5ffefeffff0fafffffffefff7f6fefbfafffffefff3f3f5ffffffeaeaeacbcbcbababab +a4a4a6b5b5b7aeadb2b6b5bb0c0b139e9da3aaa9aeaaaaacb4b4b6a0a0a2a4a4a6afafb1 +9d9d9fb1b1b3a7a7a9a3a3a5a1a1a3a7a7a9b7b7b9b6b6b8a5a5a7a5a5a7b7b6bba9a8ad +020106aeadb2a5a4a9a8a7ac9d9ca1abaaafabaaafabaaafabaaafabaaafabaaafabaaaf +abaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaaf +abaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaaf +abaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafabaaafb0afb4b5b4b9 +56555aa2a1a6b1b0b5a5a4a99a999ec0bfc4b1b0b5adacb1acabb0b3b2b7adacb19d9ca1 +bcbbc03a393eabaaafaeadb2b5b4b9a9a8ada8a7acb2b1b6b7b6bb9f9ea3adacb1b4b3b8 +bdbcc1a3a2a7b2b1b6afaeb3bbbabfa2a1a6a1a0a5adacb1afaeb39c9ba0b6b5baa4a3a8 +a5a4a9b1b0b5adacb1b0afb4bbbabfaeadb299989daaa9aeb9b8bda3a2a7adacb1b4b3b8 +bdbcc1a3a2a7b2b1b6afaeb3bbbabfa2a1a6b1b0b59d9ca1afaeb3a4a3a8a09fa4b4b3b8 +aaa9aeaaa9aeb0afb4a6a5aab0afb49b9a9f9c9ba0bebdc2b5b4b9abaaaf0302079e9da2 +abaaafa7a6abb4b3b8a6a5aab5b4b9a4a3a8b0afb4a1a0a5a1a0a5b2b1b6b7b6bbaaa9ae +a6a5aab0afb4abaaafabaaafabaaafabaaafabaaafabaaafabaaafababadaaaba6a3a49e +adaea8b0b1acabaca7b3b3b1c0c0c0e3e3e3fafafafcfcfcffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eada +ebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfe2e2d6f5f3e7e3e1d5 +040200e3e1d5f2f0e4e9e7dbf3f1e5e7e5d9030100eceadee6e4d8f2f0e4f6f4e8d6d4c8 +f4f2e5f6f4dfeae8d3dedbcce6e2d9130e0be5dfdfece6e6f5f0ed080500f5f3e7e6e4d8 +eceadef7f4ebe2dfd8e9e8e4f4f1ecf8f4e8f6f0e0fdf7e9e8e2d4f3eddfe1dbcdfffff1 +e8e2d4f2ecdee9e3d3e7e0d0f0e9d7e6dfccebe5cffcf6e0ebe6d3e1ddd1ebe9ddf7f5e9 +eeece0f1efe3f9f7ebe9e7dbe9e7dbf0eee2f1efe3f1efe3fbf9eddedcd0e3e1d5fffff4 +d9d7cbf7f3e7ebe7db040000e8e4d8f1ede1dfdbcffefaeee3dfd3f4f0e4fffff3e4e0d4 +d9d5c9f9f5e9faf6eaece8dcebead8eaeed3f3efd6fde7dcfbe3e1f2eceee5eaeee6eff6 +8e9ba3f2ffffe8f9fff4ffffe2e8f6fffbff0000199abed4337d880477745de8e34edee6 +00998d008f531bc45d2ad65047ca58001d00f7f9f4fffcfffffcfff4f6e9e9f3daf7ffef +f5fff4f7fbfefffefffffefff9f8fef4f3f8fffffff8f8faeaeaece5e5e7dfdfe1e1e0e5 +c7c6cbd4d3d9cccbd3000009dbdae2dddce2cfced3dfdee3e0dfe4dddce1dad9decfced3 +dfdee3dddce1dad9def7f6fbcccbd0c4c3c8dfdee3c8c7cceae9eee3e2e8cbcad0000005 +dddce2dad9dfd5d4dae0dfe5e2e1e7d8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7dd +d8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7dd +d8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7dd +d8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddcfced4626167 +c6c5cba8a7adbbbac0a4a3a9a2a1a7aeadb3a9a8aea7a6acacabb1b2b1b7a7a6aca4a3a9 +35343ae2e1e7d8d7ddcdccd2dcdbe1d7d6dcdfdee4d6d5dbd7d6dc010006000005000005 +0b0a10000005000005c4c3c9e0dfe5d7d6dcdbdae0d9d8dedddce2d7d6dcdbdae0dad9df +dedde3d7d6dcc9c8cecdccd2dfdee4dfdee4d0cfd5d1d0d6e1e0e6010006000005000005 +0b0a10000005000005c4c3c9e0dfe5dfdee4cfced4dad9dfdddce2e0dfe5dfdee4cfced4 +dddce2e2e1e7cccbd1d1d0d6e5e4eae1e0e6d3d2d8d3d2d8dad9df000005e3e2e8e9e8ee +dbdae0d1d0d6d1d0d6cfced4dddce2d6d5dbe3e2e8dfdee4cfced4d0cfd5e0dfe5e0dfe5 +cecdd3d8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7ddd8d7dce2e2e2d2d3cedadad8 +d4d4d2dcdcdad3d3d1e9e9e9fffffffbfbfbfdfdfdffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dc +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddffdfdf1e2dfd6fffef5030000 +131007f3f0e7dedbd2efece31b180f030000f5f2e9f7f4ebf6f3eadfdcd3fffff6e4e2d5 +f4f2ddf8f6e1f7f4e5f6f2e9040000fef8f8f1edeee3dfdeeae7e0030100ebe9ddf4f2e6 +eae7dee9e6dffffffbebe8e3e9e5dcebe7dce4e0d4f4f0e4ebe8d9efecddf8f5e6e2dfce +f9f6e5e4e1d0fffdede1dbcbfef8eaefe9dbf0eadcf2eee2fefcf0f3f0e7e8e5dcf4f1e8 +f4f1e8f2efe6d9d6cdf8f5ecf2efe6e5e2d9fdfaf1e1ded5edeae1edeae1f3f0e7f7f5e9 +e5e1d5f7f3e7040000f5f1e5f4f0e4f8f4e8e6e2d6fffbefe3dfd3e2ded2e7e3d7fdf9ed +ece8dcd9d5c9f1ede1f1f2e0e4f1d3edf1d8fde6defce2e5f1ecf0e3eaf0e7eef692999f +f9fffff4ffffeafdfbf2fffffffdff02031500051700131900180200170500111e00232f +001502002000001d00001e00000d00f5fffffffbfff4ede3eeffe3ebffe3f7fbedfff9fc +fffdffe7e6ecfffefffbfafffffffffffffff9f9f9fffffff1f1f1fefefee7e7e9fffeff +f2f1f7fcfbfff4f3fbf8f7fde6e5eaf8f8faf4f4f6e0e0e2eeeef0fbfbfdf1f1f3fbfbfd +ededefeeeef0e6e6e8f6f6f8fefeffededefededeff7f7f9eeedf2f9f8fdfdfcfffaf9fe +f0eff4f9f8fde6e5eaecebf0f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9 +f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9 +f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9 +f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9efeef3f6f5fa54535846454a +4e4d5251505543424762616647464b47464b4f4e533d3c414b4a4f55545959585d535257 +e2e1e6f4f3f8fffeffedecf1f8f7fce3e2e7f8f7fcf1f0f5f5f4f9fdfcfffffeffe4e3e8 +fefdffe8e7ecf5f4f9fbfafffffeffdcdbe0fefdfff9f8fde8e7ece4e3e8fffeffe3e2e7 +fffefff2f1f6f1f0f5f0eff4ecebf0f9f8fdfefdffebeaeff5f4f9fdfcfffffeffe4e3e8 +fefdffe8e7ecf5f4f9fbfafffbfafff1f0f5fbfaffeeedf2e0dfe4f4f3f8f8f7fce6e5ea +e8e7ecfffeffe9e8edfffefffaf9fee2e1e6fffeffe6e5eaefeef3edecf1e7e6ebf5f4f9 +fffeffefeef3fefdfff7f6fbf4f3f8f0eff4f3f2f7faf9fefbfafff5f4f9f1f0f5f3f2f7 +f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f5f4f9f8f8f8f1f1eff9f9f9eeeeec +fdfdfbeaeae8f7f7f5f1f1effdfdfdfffffffffffffffffffffffffefefffffeffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfe8e8dee4e1d8e4e1d8040100030000 +f6f3eafbf8efefece3030000030000f0ede4ece9e0030000f6f3eafbf8ef030100ecead5 +dfddc6f0eddee3dfd4040000eee8e8f4f0f1eae6e5fcf9f2030100fefceff4f2e5e0ded2 +100d04010000030000f8f5f0edeae3f9f6ef030000141205050300dddbccfefced030100 +fefcede3e1d4f5f3e7040100f6f3ec030000030000030000efece3030000030000f7f4eb +e7e4dbfffff6030000040100040100dad7cef7f4eb030000fcf9f0030000050300fefaef +ddd9cd060200050100eeeadef0ece0040000040000f7f3e7fffff3e7e3d7efebdffaf6ea +ece8dcf3efe3e6ebd7dff4d5e7f4dafde5e1fce1e6efedf2e3eaf0e9edf697989df9f9f9 +fbfffbf1fffae9fdf2fefffffffdfff8ffffe3f7f8ebfff4e9fff1f9ffffeef1fff5ffff +f0fff0f4ffe8f8ffeff4fffff9fffffdeaecfffef1deffd6e9ffe8fffffffff3fffffcff +fffefff7f7f9fbfbfdfdfdfdfffffdfffffdededebfffffdfffffdf4f4f4f9f9fbfcfbff +fffefffffefff8f7fcfffffffafafafffffffffffffffffffefefefcfcfcf7f7f7ffffff +fffffffffffffbfbfbfffffffffffffbfbfbf8f8f8fffffffbfbfdfffffffafafcffffff +fafafcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffefefffcfcfeededefffffff +f4f4f6ffffffe9e9ebfffffffffffffffffff8f8faffffffffffffe6e6e8ffffffffffff +fffffff4f4f6f6f6f8fffffffffffffffffffffffffdfdfff7f7f9f3f3f5fefeffffffff +fafafcffffffe8e8eaf9f9fbfffffffcfcfefafafcfffffffffffff5f5f7ffffffeaeaec +fffffffffffffffffffffffffffffff4f4f6fbfbfdfdfdfff7f7f9f3f3f5fefeffffffff +fafafcffffffe8e8eaf7f7f9fcfcfefefefffffffffffffffffffffafafcffffffffffff +f7f7f9fffffff7f7f9f5f5f7fffffffffffffffffffffffffffffffffffffffffff1f1f3 +f7f7f9f5f5f7fffffffffffffefefff8f8fafefefffefefffafafcffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffbfbfdfdfdfdfefefef7f7f7fffffd +fefefcfffffdfafaf8fefefefffffffffffffffffffffffffefefffffeffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfeeeee4f1eee5f0ede4090600fffcf3030000 +dfdcd3050200efece3070400f1eee5e7e4db030000f4f1e8dcd9d0141205f2f0dbf0eed7 +fffeeff2eee30e0906dfd9d9ebe5e5f0ebe8ebe8e1090700e1dfd0dedccd201e0fdedccf +f2efe6f7f4ef030000e7e5e6080703f0efeae3e3d9e3e3d717180ae3e4d6010200e6e6da +e1e3d8eff0ea000000ebebeb0e0d12e7e7e9dedbd616130aeeebe2f2efe6060300eeebe2 +030000e8e5dce4e1d8fffff6060300ece9e0030000030000f6f3eaf3f1e5040000f9f5e9 +040000e6e2d6e8e4d80d0900f0ece0faf6ea0a0600cecabefffbefe3dfd3ede9ddf1ede1 +f7f3e7e4ebd9dbf6d7e3f5dbfbe6e3fce1e8efecf3e3eaf2ececf499979afffdfafbfdf0 +f1fff15c745c797b6e6b63606660647b7b7d68716c828481f7e3eefffafff5fffbecfff6 +fefffffff7fffffafff9ecfefff4fbfffbf7f7fff4e5f9f0fafafffff9fffffdfff9f9f9 +fffffdfffffdfffffbf5f6f1fbfcf6fffffafffffaeff0eafffffbfffffdfcfcfcffffff +f7f6fbfffffff8f8f6fffffbfcfdf8f4f5f0f3f4effffffbfffffbfefffafffffbfffffb +f0f1ecfffffbfffffbe8e9e4fcfdf8fffffbfcfcfaffffffe7e7e7fffffffffffffefefe +fffffff7f7f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffafafafffffffffffffffffffafafaf9f9f9 +f4f4f4fffffffffffff9f9f9fbfbfbfcfcfcfffffffffffffdfdfdfffffffcfcfcffffff +fffffff7f7f7fffffff3f3f3f8f8f8fffffffffffff7f7f7fffffffdfdfdfffffffefefe +e6e6e6fffffffffffffefefefffffff9f9f9fffffffafafafcfcfcfbfbfbffffffffffff +f0f0f0f6f6f6fffffffffffff7f7f7fffffffffffff7f7f7fffffffdfdfdfffffffefefe +e6e6e6fffffffefefefffffffffffff3f3f3f4f4f4fcfcfcfffffff8f8f8fffffff4f4f4 +f8f8f8fffffffffffffdfdfdffffffffffffffffffe8e8e8ffffffffffffffffffffffff +fffffff4f4f4fafafafffffffffffffffffffdfdfdfffffffdfdfdf0f0f0ffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffafafaf9f9f9fffffff5f5f5 +fffffdfbfbf9fffffffffffffffffffffffffffffffefefffffeffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfe5e5dbfbf8efeae7de030000e6e3da040100fbf8ef +030000eeebe2030000f6f3eae8e5dc0a0700f3f0e7e8e5dc040200ebe8d5f7f4e1e8e5d6 +ebe7dc090400f5f0ecede8e5f0ebe7eae7de040200faf8e9eeecdd030100fcfaede8e6da +f1eee7040000eceaeb060503edeee8f1f1e9f1f3e8dadacef4f6e9070700e6e8ddf5f6ee +e4e5df020200f0f0f2000004f2f2f2f5f4ef030100f8f5ece5e3d7090600ebe9dd040100 +060400060300030100030000f8f6ea030000ebe9ddece9e0ebe9dd0d0900ece8dc050100 +f6f2e6f5f1e5f1ede1040000f0ece0e7e3d7fffcf0e7e3d7f1ede1f4f0e4e3dfd3f6f2e6 +e6ead9dcf4dae5f4dffae7e3fbe2e6efedf0e5eaeeececf499979cfff8f6fffff3697d64 +eaffecf8fffffefffffffdfffffdfff8ffffeaeefa8e7e8b786d755265616b817e6c6f78 +fff8fffff7fffff9fffff9fffffcfbf6f8f5f8fffffbfcfff9f9fffcfcfffffffdfffffd +f7f8f3fffffbfbfcf7fffffafbfcf6fcfdf7fffffaf5f6f1fffffdfcfcfcfdfdfdffffff +f6f6f6fefefcfffffbfbfcf7fffffbfffffbfdfef9f7f8f3fffffbfafbf6fffffbfffffb +fbfcf7fffffbfffffbfefffafffffbfffffdfafaf8fffffdfffffdfcfcfaf6f6f4fffffd +fffffdfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc +fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc +fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc +fefefcfefefcfefefcfefefcfefefcfefffd8b8d8c7e7f837e7e868786948281938c8aa0 +7f7d9582809683819686859592919f79798378797e8f90947f80828f8f8fededebfffffd +fffffdf1f1effffffdfffffdfffffdfffffdf2f2f0fffffdfffffdfefefcfffffdf8f8f6 +fffffdfffffdfffffdfffffdf9f9f7fffffdfefefcfffffdfffffdfffffdfefefcfdfdfb +fffffdfffffdfcfcfafbfbf9fffffdfffffdf2f2f0fffffdfffffdfefefcfffffdf8f8f6 +fffffdfffffdf7f7f5fdfdfbfffffdfffffdfbfbf9fffffdfefefcfffffdf9f9f7fffffd +fffffdfffffdfafaf8fbfbf9fcfcfafbfbf9fffffdf8f8f6f1f1effffffdf9f9f7f9f9f7 +fffffdf7f7f5fffffdfffffdfcfcfafcfcfafffffdfffffdfffffdfefefcfefefcfefefc +fefefcfefefcfefefcfefefcfefefefafafafffffff7f7f7fffffffffffff6f6f6fffffd +fffffdfffffffffffffffffffffffffefefffefeffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddff9f9efd6d3cafcf9f0030000dfdcd3f5f2e9030000f7f4eb +e8e5dc070400f2efe6f1eee5030000f2efe6f0ede40b0900eae7d8e7e4d5fffbeff0ece0 +040000e8e4d9fffff6e8e4d9e4e0d50e0a00ede9ddf4f0e4070300e6e2d6f1ede1eae8dc +040100eeebe6080500eeeee6f3f0e7f2f2e8dcd9d0f5f5eb060300f2f2e8e0e0d6f5f5ed +010100eae9e4020100ecece4f4f1e8060400dcdacef7f5e8030100f9f7ea030100f2f0e3 +e6e4d8f9f7eaeceadef3f1e4030100f1efe2eceadeefede0050100e7e3d70f0b00efebdf +dbd7cbfdf9edf7f3e7040000e7e3d7fffcf0e7e3d7f1ede1f4f0e4e3dfd3f6f2e6e7e9db +e3f0dceaf1e1f7e8e1f8e5e1f2eee5e8eae7e9edf69797a1fffcfdfcf9f07a8678edffff +eaffffe6feffbccde9a6bad3a3c0deceebffdff3fff0ffffe4fcffe2f7fcaeb7bc636468 +fffffffefaf9fffbf8fbf7f4fffffffcfffff4f3fffefdfffffefff7f7f7fffffffdfdfb +fffffdfefefcfffffdf9f9f7fffffdf7f7f5fffffdfafafaf6f6f6fffffff3f3f3ffffff +f2f2f2fffffdfffffdfffffdf3f3f1fffffdfbfbf9fffffdf6f6f4fffffdeeeeecf7f7f5 +fffffdfcfcfafffffdfefefcfffffffffffff7f7f7fffffffcfcfcfdfdfdfffffffefefe +fdfdfdfffffff6f6f6fffffffffffffffffffffffffdfdfdffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffefffdfbfffb7c8584bac0cebfc3e0cacbfbbcbbf7ccc9ffbab6ff +bdb9ffc2c0ffb6b6ecc5c6f2c7cae9b5bad0cbd1e17a7e87000004fefefefffffffefefe +f4f4f4fffffff4f4f4fffffffffffffefefefcfcfcf7f7f7fffffffffffffffffffbfbfb +fafafafffffffffffff5f5f5fefefef4f4f4fffffffcfcfcf9f9f9fffffffffffff9f9f9 +fffffffafafafffffffffffffffffffffffff4f4f4fffffffdfdfdfffffff7f7f7ffffff +fffffffffffffafafafdfdfdfffffffffffffffffff9f9f9ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc7 +0837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfecece2fffff6d4d1c80c0900fefbf2efece3040100e7e4dbedeae1 +080500ebe8dfe3e0d7fdfaf1040100030000efede1f8f4e9e9e5d9d9d5c9ebe7db161206 +e0dcd0efebdfe9e5d9100c00e4e0d4e1ddd1f3efe3050100e8e4d8f7f3e7f1ede1030000 +e9e6dd0a0700f2efe6e5e2d9e5e2d919160de5e2d9030000e3e0d7fbf8ef080500030000 +f4f1e80e0b02e8e6daf2f0e4030100fffdf0e8e6d9141205e5e3d6040200eeecdffbf9ec +e1dfd2040200eae8db030100f7f5e8e5e3d6f2f0e30a0600e9e5d9040000f1ede1f2eee2 +040000dedacef5f1e50a0600cecabefffbefe3dfd3ede9ddf1ede1f7f3e7e8e9dbe7eede +edefe1f6e9e1f7e6def4eee2e9eae4e9edf89498a4fffdfff7f4ef717b72eeffffd2f3ff +89addf84a0c5809ec07198c182acd48cb0d4d1f3ffeafffff0ffff99a7aa5f6865f4f9f3 +fefffafffffafffffbf2f2f2fffffffefffff6f7fcf5f5f7fefefefffffffffffff7f7f7 +ffffffe8e8e8fffffffffffffffffff4f4f4f7f7f7ffffffefefefffffffffffffffffff +eeeeeefdfdfdf3f3f3fffffffffffffffffffafafafffffff0f0f0fffffffffffff7f7f7 +fdfdfdfffffff6f6f6fffffffffffffafafaf4f4f4ffffffffffffedededfdfdfdeeeeee +fffffffcfcfcfffffffffffffffffffcfcfcffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffefffff6fcf88e9899cdd2e5070b2e04033c050448070252100d5e0b0656 +1d1c620a094500002b0c0e34141a34090e247e8190000005fffffffffffffcfcfcffffff +f0f0f0fffffffffffffffffffcfcfcfffffff5f5f5fffffffefefef2f2f2fffffff5f5f5 +fffffffdfdfdfdfdfdffffffffffffedededfffffffbfbfbffffffe8e8e8ffffffececec +fffffff5f5f5ffffffffffffebebebffffffe8e8e8fffffffffffffffffffafafaf5f5f5 +fffffffffffffffffff8f8f8f9f9f9ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db +1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfd8d8cefcf9f0f8f5ec030000eae7def3f0e7f0ede4fefbf2eeebe2030000 +f9f6ede5e2d9f0ede4060300edeae1f2f0e4e9e5dafffcf0fefaeee8e4d8040000110d01 +040000090500e8e4d8efebdffffcf0ebe7dbe3dfd3040000090500040000f8f5ecedeae1 +f9f6ed030000141108050200dddad1fefbf2f6f3ea090600030000fcf9f0030000e7e4db +030000efede1e9e7db030100eceadde6e4d7030100fffff2f1efe20301000301000b0900 +e5e3d6fcfaed030100ebe9dcf5f3e6e1dfd2040000e7e3d7ebe7db0f0b00dbd7cbfffff3 +070300040000f7f3e7fffff3e7e3d7efebdffaf6eaece8dcf3efe3e8e9dbe7eedcedefe1 +f6e9e1f7e6def4eee2e8ebe4e7eef89498a4fffbfffefdf9747f77eeffff98b9e2678cc0 +c5e3ffe6ffffdfffffacd7ffa4caf184a5c4d7f1ffdef4ff97a6ab6c7675fbfffdf1f4ed +fefff9fefffafffffde6e6e8fffefffffefffefefffffffffffffffdfdfdfffffff8f8f8 +fffffffffffffffffff7f7f7fffffffffffffffffffffffffffffff0f0f0e2e2e2ffffff +fffffffffffffefefef7f7f7fffffffefefef5f5f5fffffffffffffdfdfdfffffff3f3f3 +fffffffffffff4f4f4fffffff7f7f7ffffffffffffffffffffffffffffffffffffffffff +fbfbfbeeeeeefffffffffffff8f8f8ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffefffffbffff767e81b4b7c60b0f28121236070932110f3e0f103e0c0b35e1e3ff +0a0b2af9fdff04061df6fbff000013989bac030409fafafaf9f9f9f8f8f8f9f9f9ffffff +fffffff5f5f5f2f2f2fffffff6f6f6f8f8f8fcfcfcfffffffffffffefefeffffffeaeaea +ffffffffffffefefeffefefefafafafffffffffffff9f9f9fffffff9f9f9ffffffffffff +fffffffafafafbfbfbfffffffffffffffffff7f7f7fafafafafafafefefefffffffbfbfb +f3f3f3f9f9f9fffffffffffffefefef9f9f9ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff3 +1e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddff9f9ede7e4dbe2dfd6fbf8eff1eee5f1eee5e5e2d9e3e0d7eeebe2e4e1d8fbf8ef +e9e6dde0ddd4120f06f7f4ebedebdfece8dcdcd8cce3dfd3fbf7ebede9ddf1ede1f8f4e8 +e6e2d6fbf7ebeeeadededacef7f3e7ece8dcfaf6eae8e4d8efebdfe8e6daeae7dee3e0d7 +f3f0e7eae7deeeebe2f7f4ebe1ded5e8e5dcedeae1efece3e5e2d9efece3e9e6ddf6f3ea +f8f6eae4e2d5fffff2f7f5e8eceaddf5f3e6ebe9dcedebdee8e6d9e8e6d9e3e1d4f1efe2 +eae8dbf4f2e5f6f4e7eeecdff7f5e8fffbeffcf8ece0dcd0eeeadefffff3dad6caf4f0e4 +eae6dae3dfd3e2ded2e7e3d7fdf9edece8dcd9d5c9f1ede1f1f2e4e7eedcedf0dff6e9e0 +f5e6dff4eee2e8ebe4e7edf99298a6fdfbfffffffb6a756de3fcff88abd5aacfffe2ffff +c8e8ff9ac3f183adddd1f6ff91b3d6cbe6ffebffffa8b9c1606b6dfbfffffbfffaeceee9 +fffffbfffffd0505050a090e000004000002f6f6f6fffffff1f1f1f6f6f6ffffffffffff +efefeffafafaffffffffffffedededffffffffffffeeeeeefffffffffffff4f4f4fdfdfd +f5f5f5fafafafafafa181818000000fffffff8f8f8ffffff000000000000ffffffeaeaea +fffffffffffff7f7f7ffffffeeeeeefefefee7e7e7fffffff4f4f4f3f3f3f0f0f0ffffff +fffffffffffff9f9f9f4f4f4ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fefffffcffff81868cc8cad67e81908485978d909f787a87777b8484878c808588888c8d +8b90937f828b7b7e8da1a2b76c6d7f000005fffffffbfbfb0d0d0dfffffffffffff5f5f5 +fffffffffffffffffffcfcfcffffffffffffeaeaeafffffffffffffbfbfbf9f9f9070707 +fffffffffffff6f6f6fffffffffffffffffffdfdfdf7f7f7fffffff3f3f3fefefeeeeeee +ffffffffffffffffffe6e6e6fffffffffffffffffffffffffffffff5f5f5f9f9f9fbfbfb +fffffffdfdfdfafafaf3f3f3ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bc +e2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +e7e7dbeae8dcf1efe3eeece0ebe9ddebe9ddfffef2f2f0e4f5f3e7f0eee2e8e6da030100 +131105dddbcfe5e3d7eceadefaf6eaf7f3e7f5f1e5e9e5d9f8f4e8dcd8ccf5f1e5f5f1e5 +e2ded2fffff3ece8dcf4f0e4ede9ddeeeadeebe7dbf3efe3f7f5e9f3f1e5faf8ece5e3d7 +f0eee2dedcd0fffff4e5e3d7fcfaeedddbcffffdf1dddbcfedebdffffff4d8d6cae8e6da +f2f0e3e7e5d8f2f0e3e3e1d4e9e7daeae8dbeeecdff3f1e4e8e6d9fdfbeef2f0e3f0eee1 +e4e2d5dcdacdefede0ebe9dce5e1d5ddd9cdf5f1e5f7f3e7e0dcd0f5f1e5e4e0d4efebdf +f4f0e4fffff3e4e0d4d9d5c9f9f5e9faf6eaece8dce9eadce7eedcedf0dff6e9e0f5e6df +f4eee2e8ebe4e6eef99298a6fffdfffffffd6f7c75e4ffff7398c4d7feffd0f0ff90b0d7 +83abde83aee3dcffffbddeff7895b3e6ffff99abb7586669f1faf9f4f9f5fefffbf3f4ef +010000fffefffbf9fcfffefffefefefffffffffffffffffffffffffefefef6f6f6ffffff +fffffff8f8f8ffffffffffffffffffeaeaeafffffff6f6f6fffffffffffffefefeffffff +fffffffafafa000000040404fbfbfbfbfbfbffffff0b0b0b090909f1f1f1fffffff9f9f9 +f1f1f1f6f6f6fffffffffffffffffffffffff7f7f7fffffffffffffcfcfcfdfdfdffffff +fcfcfcfffffffffffffefefeffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fefeff72757edfdfe7e9edf0fbfdfafcfff6f5fae4fcffe8feffe3fbffe2feffe8ebf3de +fefffbfcfffff4f3ff81809209080effffffffffff000000fdfdfdf5f5f5ffffffffffff +f9f9f9fdfdfdf5f5f5fffffffffffff1f1f1ffffffebebebfffffffafafa000000fefefe +fffffffdfdfdfdfdfdf4f4f4fafafafefefefffffff8f8f8fcfcfcffffffffffffffffff +ecececfffffff4f4f4fffffffffffffffffffffffff5f5f5fbfbfbfffffffffffff8f8f8 +fcfcfcfffffffbfbfbffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8ff +f4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddff1f1e5 +ebe9ddedebdff0eee2f1efe3eceadee4e2d6e9e7dbefede1dedcd0fffdf1f0eee2e5e3d7 +fefcf0fbf9ededebdfe2ded2f0ece0e6e2d6f2eee2f9f5e9f7f3e7eeeadeece8dcf2eee2 +eeeadee8e4d8e4e0d4f9f5e9e9e5d9f0ece0f0ece0e2e0d4f3f1e5e6e4d8ebe9ddf3f1e5 +fbf9eddad8ccfcfaeef9f7ebe4e2d6efede1fcfaeee5e3d7dddbcffffdf1eae8dcf3f1e4 +d5d3c6fefceffefcefeceaddf7f5e8e6e4d7ebe9dcf2f0e3eeecdfe0ded1f6f4e7f6f4e7 +eeecdffefcefe7e5d8f2eee2fffff3efebdfdedaceeeeadef5f1e5f1ede1fdf9edeae6da +e9e5d9ebe7dbf9f5e9fcf8ecede9dde7e3d7f0eedfe9eedaeeefddf7e9e0f7e6dff2eee2 +e8eae5e6eef99198a8fefdfffffffd6f7e79eaffff6489b5dbffffe4ffffdfffff79a1d5 +6d95d0dfffffe2ffff84a1c3eaffffa4b5c55f6c74f5fdfffbfffffafcf9000100fffffd +f8f7f5fffefffcfafbfafafaffffffe8e8e8000000141414000000ffffffffffff050505 +000000000000fcfcfc000000121212fefefeffffff0000000000000b0b0b000000ffffff +ffffff000000ffffff000000ffffff000000ffffff000000f8f8f8f4f4f4000000050505 +080808fffffffefefe0000000b0b0b000000060606e7e7e7fffffff6f6f6fffffff7f7f7 +fffffffffffffafafaffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffdff +797985c6c5cbfefffdfffff3eef4d8ffffdc5f69356f783f000a00fbffd2feffe3fefff0 +fefffffcfaff8a8798000005e5e5e5fdfdfd0f0f0f0000000b0b0bf3f3f3ffffff080808 +030303080808f2f2f2f1f1f1ffffff0000000b0b0b000000ffffff0b0b0b000000000000 +ffffff000000141414020202fcfcfc030303000000fffffffafafaf0f0f00303030a0a0a +000000efefeff9f9f9f3f3f3050505000000131313000000dadadafffffffffffffdfdfd +fffffffcfcfcf7f7f7ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2 +e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddff6f6eae2e0d4 +e8e6dafaf8ece5e3d7f8f6eaf2f0e4f2f0e4e8e6dafffdf1e7e5d9f0eee2f4f2e6d0cec2 +f3f1e5e9e7dbf6f2e6f6f2e6ece8dcefebdfe7e3d7f7f3e7ebe7dbf0ece0f1ede1e8e4d8 +f3efe3fffef2dad6cafdf9ede9e5d9f0ece0e9e7dbf6f4e8f5f3e7e4e2d6eceadef5f3e7 +e1dfd3f3f1e5e3e1d5fdfbefe9e7dbefede1f1efe3f6f4e8e0ded2faf8ecefede0fffef1 +e1dfd2dbd9cce9e7daf4f2e5f0eee1eae8dbe6e4d7f8f6e9efede0fbf9ecd6d4c7faf8eb +e3e1d4f1efe2e9e5d9efebdfefebdfece8dcfefaeee9e5d9e5e1d5e2ded2f5f1e5e2ded2 +f3efe3f1ede1d9d5c9f1ede1fffff3e6e4d5e9eedaeeefddf7e9e0f7e6def2eee2e6ebe5 +e5effb9198a8fffefff4f6f55c6b66ebffff7ea3cfccf1ffe6ffffe1feff8fb4e97098d3 +dfffffd7f9ff8eaacfd0e8ff9cafc058666ff7ffffeff5f5fefffd0c0c0afffefcf4f3f1 +fffffdf9f7f8f6f6f6fffffffffffffdfdfdfffffff6f6f6040404f9f9f9000000ffffff +fefefe030303fffffff7f7f7000000fbfbfb000000fffffffffffff5f5f50a0a0af8f8f8 +000000ffffff111111f1f1f1000000fcfcfc000000fffffffffffffefefeffffffffffff +000000f7f7f7040404fffffff8f8f8f6f6f6151515e9e9e9fffffffffffff9f9f9f8f8f8 +f0f0f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffefff0eef99795a0 +c6c4c9fdfef8f4f5e3ffffe3fcffd20f1900e7f0af788341030a00fcffd9ffffede2e3de +fffdff8482900f0e13fffffff8f8f8000000f8f8f8fbfbfbffffff000000f9f9f9ffffff +f3f3f3050505ffffff000000f7f7f7fffffffafafaffffff0f0f0fefefefffffffffffff +040404f1f1f1fdfdfd000000ffffffffffff000000f2f2f2fffffffcfcfcf6f6f6ffffff +030303ffffff000000f0f0f0fffffffafafa0e0e0efffffffffffff3f3f3f6f6f6ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eada +ebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeaeadef2f0e4efede1 +f8f6eae3e1d5f2f0e4e7e5d9f1efe3f2f0e4eae8dceae8dcf4f2e6eceadefefcf0ebe9dd +f0eee2f1ede1e3dfd3f8f4e8eae6daefebdfeeeadeeeeadeede9ddf0ece0faf6eadfdbcf +f6f2e6f5f1e5e2ded2ece8dcf0ece0f1efe3e7e5d9e9e7dbf0eee2faf8ecdedcd0fffdf1 +e9e7dbf7f5e9eae8dcebe9ddf1efe3eeece0f6f4e8eae8dcedebdfe4e2d5f7f5e8edebde +f3f1e4faf8ebedebdee4e2d5f6f4e7f8f6e9e4e2d5efede0ebe9dcf9f7eaeae8dbf0eee1 +eae8dbf3efe3e3dfd3f6f2e6f2eee2e7e3d7f1ede1f8f4e8f0ece0efebdfede9ddf2eee2 +f6f2e6f9f5e9ede9dde2ded2f2f0e1e9eedaf0efddf9e8def7e6def2eee2e6ebe5e5effb +9099aafbfcfffeffff6d7c77edffff7b9ec895b9ede7ffffe7ffff7d9ed483a7e1ddffff +e0ffff89a5cae4fcff99acbd65737ef8fffff9fffffcffff000100fffffdfffffdf8f7f5 +fffffdffffffe9e9e9ffffff000000000000000000060606ffffff050505fcfcfcffffff +000000fefefefbfbfb080808fdfdfd020202f9f9f9ffffffffffff000000ffffff000000 +fbfbfbf1f1f10c0c0cf7f7f7ffffff000000fffffff7f7f7020202000000000000070707 +ffffff000000fafafaffffffffffff000000fffffffbfbfbf5f5f5fffffffffffff1f1f1 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffdff86838cc9c7cc +f8f7f2fffff1ffffe4696f43e9f0ba878f53878f53010800767b53feffeafffffafffdff +87848f000004ffffffffffff000000ffffffffffffe9e9e90e0e0e070707000000080808 +020202eeeeee070707101010f8f8f8fffffff6f6f6000000fffffffffffff2f2f2060606 +ffffffffffff010101fbfbfbffffff020202ffffffededed0b0b0b070707000000000000 +fcfcfc000000fffffffffffffefefe000000fffffff7f7f7fffffffffffff4f4f4fafafa +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dc +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeceddfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecddeaeddaf0efddf9e8def7e6def2eee3e6ebe7e3effd9099aa +fcfdfff4f6f56d7a73eeffffb5d5fe7d9dcec1d9fbeaffff88a6da7495cbe3ffffdffcff +7892b5e0f5ffb2c3d554626bf8fffffbfffffafefd000100fffffdfaf9f7fffcfbfffefc +fefefefcfcfc000000fffffffffffffdfdfd050505ffffff0b0b0bf8f8f8f8f8f8040404 +fefefeffffff000000ffffff080808f6f6f6fffffff4f4f4000000ffffff000000ffffff +ffffff000000fffffffdfdfd020202ffffff000000fffffffcfcfcfcfcfc0c0c0cfefefe +000000fffffffffffff9f9f9000000fffffffbfbfbf5f5f5fffffffffffff1f1f1ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffeff838087c0bec1fffffd +fffff8f7f8e8ffffe8010500c1c69deff5c9010600feffe2ffffeffffffafffeff86838a +000002ffffffffffff000000f6f6f6ffffffffffff000000fafafafffffffffffffbfbfb +fcfcfcfffffff3f3f3010101111111e7e7e7131313f9f9f9f8f8f8ffffff000000ffffff +ffffff050505fffffff6f6f6050505ffffff000000fffffffdfdfdffffff000000ffffff +040404efefefffffffffffff060606f9f9f9fffffffffffff6f6f6ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeceddfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecddeaeddaf0efddf9e8def7e6def2eee3e6ebe7e3effd9099aafffeff +fffffd6c776fecffffd4f0ff839fce8497b7c9dcfccee9ffe4ffffe7ffffb6cff7a8bfdf +ecffff899aaa66737ceaf4f6f0f6f6fcfffff7f9f611100efffffdfaf6f5fffffdfffeff +f1f1f1010101ffffffe0e0e0fdfdfd000000f7f7f7000000ffffffffffff000000fafafa +ffffff000000ffffff000000fffffffafafaffffff000000f0f0f0101010f5f5f5efefef +fffffff5f5f5f6f6f6040404f3f3f3030303fefefeffffffffffff000000fdfdfd000000 +f8f8f8efefefffffff151515e9e9e9fffffffffffff9f9f9f8f8f8f0f0f0ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffeff878588cdcbcefffefffffeff +fffffbf0f0e6fffff1080a00050700feffe8ffffedf9f9edf3f2edfdfbfe939196010103 +fffffffefefe000000fffffff5f5f5fafafa000000ffffffffffffffffff050505f9f9f9 +f9f9f9fffffffefefe000000ffffff000000fcfcfcfffffff2f2f2000000fbfbfbfdfdfd +020202ffffffffffff050505f5f5f5000000f9f9f9fafafafefefe000000ffffff000000 +fffffff7f7f7ffffff000000fcfcfcfbfbfbfffffffffffff5f5f5fbfbfbffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfecedddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeecdde9eedaeeefddf7e9e0f5e6dff1efe3e5ebe7e5effb9198aafcfafffdfcf8 +71796ef4ffffe1f8ffeaffff9caac479859f879ac2eaffff9db3da9aaecfd1e5fedff0ff +9fadba69767cf8fffffbffffedf1f0fcfefbf3f2f0010000030000010000010000ffffff +f6f6f6050505131313030303090909ffffff121212f2f2f2fcfcfc060606efefefffffff +000000ffffff070707000000000000000000fcfcfcffffff000000ffffffffffffffffff +f6f6f6ffffff000000fffffffcfcfc070707000000000000000000ffffff000000151515 +070707000000e7e7e7fffffff6f6f6fffffff7f7f7fffffffffffffafafaffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffdfaf9f5878684c3c1c4fffefff8f5fefffdff +f0eef3fffefffffffbedede5fffff5fffff6fffff8fffffbfffeff757376000000ffffff +fefefeeeeeee000000030303f3f3f3ffffff080808000000000000ffffffffffff090909 +000000000000fbfbfbf9f9f9f4f4f4000000000000ffffff000000ffffffffffff000000 +fefefefdfdfd000000ffffffffffff020202000000000000000000ffffffe7e7e7111111 +000000040404010101fffffffffffff1f1f1fffffffffffffffffff6f6f6ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfecedddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecdde9eedaeeefddf7e9e0f5e6dff1efe3e5ebe7e5effb9198a8f3f1f4fffef8e7ebdd +828e8ce5f8ffd5e5fff8feffe1e8fbdcebff91a4c59cadcbe6f6fff2fffff4ffffa2afb7 +5a6569f9ffffecf2f0fcfffdf6f8f5fffffdfffffdf6f2f3fffefffffffffcfcfcffffff +f9f9f9fafafafffffff0f0f0f8f8f8edededfffffffffffffcfcfcffffffffffffffffff +fdfdfd000000fffffffffffffffffffffffffdfdfdeeeeeefffffff0f0f0ffffffffffff +fffffffffffff5f5f5fffffff4f4f4fdfdfdfffffff7f7f7ffffff000000f4f4f4fcfcfc +fafafafffffffcfcfcfdfdfdfffffffcfcfcfffffffffffffefefeffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffdfbfcf48f908a8b898a7c7b81827f8a8d8b98918d9b +8b89948583889090908786827778727877738f8f8d7371748c8c8e0e0e0ef1f1f1fdfdfd +fffffffffffffffffffffffff9f9f9fffffffffffffffffff5f5f5fffffff0f0f0fdfdfd +fcfcfcfffffffefefefffffff1f1f1fafafafafafafefefeffffffffffffffffffffffff +ffffffffffffebebebffffffeeeeeefffffff9f9f9fbfbfbffffffffffffe5e5e5ffffff +f6f6f6000000eeeeeefffffffffffffcfcfcf6f6f6fffffffdfdfdffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddfecedddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdd +e9eedaeeefdff7e9e0f5e6dff1efe3e5ebe7e5effb9298a6fffefffffef6fffff1ecf5f0 +72809a7580a075778670707c60687ff4fffff4ffffe0ebfdeffbffe5f2faa8b3b5606a6b +f7fffdfbfffdfcfffdfefffdf3f3f3efefeffffefffffdfff9f9f9fbfbfbffffffffffff +f7f7f7f0f0f0fffffffffffffffffff9f9f9f5f5f5fbfbfbfffffff4f4f4fffffffdfdfd +060606fdfdfdfefefef5f5f5fbfbfbfdfdfdfffffffcfcfcfffffff4f4f4fffffffcfcfc +fffffffafafafffffff7f7f7fdfdfdfbfbfbfefefeffffff050505fcfcfcfcfcfcffffff +f3f3f3f0f0f0fffffffffffffffffff9f9f9f4f4f4ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff60002000001000f101200000702020c000009000007 +000004080a0900000000010009090700010009090b000002020202fdfdfdffffffffffff +f8f8f8efefeffffffff6f6f6fefefeeaeaeafffffffffffff5f5f5ffffffffffffffffff +fbfbfbf6f6f6fdfdfdfffffffffffffdfdfdfffffffffffffefefeffffffefefefffffff +f9f9f9fbfbfbffffffffffffe4e4e4fffffff9f9f9fffffffdfdfd0a0a0a0000000c0c0c +fffffffffffff4f4f4fafafafffffffffffffdfdfdfefefeffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc7 +0837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfecedddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdde9eddc +eeefdff7e9e0f5e6dff1efe3e5ece5e6eefb9298a6fffcfcfef6ebf9f8e6fcfffae9f4ff +f7fefff1eef9fffdfffbfeff6f7688585f6f7179847780876d7779788281f9fffffbfffd +f4f9f5fefffdf8faf7fffffffffffffffefff9f7faf7f7f7fffffff5f5f5fdfdfdffffff +fffffffffffff1f1f1f8f8f8fffffff1f1f1fefefeffffffefefefffffffffffffeeeeee +ffffffedededfffffffafafaf9f9f9ffffffffffffecececf6f6f6fdfdfdfffffffdfdfd +fffffffafafafffffff4f4f4ffffffffffffeaeaeafffffffffffff2f2f2fcfcfcffffff +fffffffbfbfbeeeeeefffffffffffff8f8f8ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbf4f7ecfefff4fefffafafcf9fefffffeffffeff0f5fdfefffeffff +f7f9f4f6f9f2fefffafbfdf8fefffffefffffefffffbfbfdf6f6f6fffffff6f6f6fbfbfb +fffffff5f5f5fffffffffffffbfbfbfffffff0f0f0fffffffffffffffffff9f9f9ffffff +fffffff0f0f0fffffffffffffffffff8f8f8fffffffdfdfdf2f2f2ffffffffffffffffff +fffffff6f6f6fffffffffffffffffffbfbfbfafafaf9f9f9fffffff5f5f5fafafafdfdfd +edededfffffffffffffbfbfbfafafaf8f8f8ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db +1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfecedddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdde9eddcedf0df +f6e9e1f4e7e1f1efe3e5ece5e6eefb9497a6fffcfdf4eae0ffffecfefff5f5fcfff9fdff +fffcfff6edf0fcfcfffbfffffbfffffbfffff9fffff4fdfcf7fffbf9fffbfbfffbfcfffb +fdfffcf3f5f2fefefeffffffe1e0e5fffffffffffff4f4f4fffffffffffffffffff6f6f6 +fbfbfbfffffffdfdfdf0f0f0fffffffefefef3f3f3fffffff8f8f8fffffffffffff3f3f3 +f3f3f3fffffffcfcfcfbfbfbffffffe7e7e7fffffffffffffffffff8f8f8fafafaffffff +fefefefafafaf5f5f5ffffffffffffffffffffffffedededf3f3f3ffffffeeeeeeffffff +fcfcfcfffffffffffffffffffcfcfcffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbf5f9ebfcfff3f4faeefcfffafcfffbeff4f0fcfffbfcfffafcfff6f4faec +fcfff4f6fcf0f7fcf6fcfffff7fafff5f6fbfffffff8f8f8f9f9f9fffffffafafaffffff +ffffffedededfffffffffffff6f6f6f7f7f7fffffff9f9f9fdfdfdfffffffffffffcfcfc +fffffff8f8f8fafafafafafafffffff7f7f7fffffffffffff8f8f8e6e6e6fffffff8f8f8 +fffffffafafaf3f3f3fffffff0f0f0fffffffffffff6f6f6f5f5f5ffffffffffffffffff +fffffff7f7f7f6f6f6fffffffffffffafafaffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff3 +1e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddfecedddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddefecddefebdfefebdff1ebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeece0efebe0eeece0eeece0eeecdfecedddeceddbeceddd +eeecddeeecdfeeecdfeeecddeeecddeeecddeceddbeceddbecedddeeecddeeecdfefebe0 +efebdfeeecdfeeecddeeecddeeecddeeecddeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeece0eeecdfeeece0eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdde9eed7edf1d8f3ecd9 +f1eadaeff0e0e6ebe4e6eff89498a3fdf9fafffef4fdfce8fdfff9f8fdfff4f4ffc8bdf9 +cebfffc3bcffbcb9fccfd0ffeaedfff8fffff7fffff9fffffbfffff5f9fafbfdfcfffff6 +fffff6fffffbf7f7f7fffffff3f3f5fffffff3f3f3fffffff3f3f3fefefefffffff5f5f5 +fffffffdfdfdfffffff9f9f9fafafafffffffffffffafafafffffff8f8f8ffffffffffff +fafafafbfbfbfffffffcfcfcfffffff8f8f8f8f8f8fffffffffffff7f7f7ffffffffffff +fffffffffffff5f5f5fffffff6f6f6f5f5f5fffffffcfcfcfcfcfcfdfdfdfffffff6f6f6 +fffffffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fefffff9fffdeef9f1c7cfc2000200000100080806000106000107000407000407000d0b +000504000607f0f3f8fffdfffffdfffffdfffffffffffffff3f3f3fffffffffffff2f2f2 +fffffff8f8f8fffffffffffff7f7f7fffffffffffffbfbfbfffffffffffffefefeffffff +fffffffffffff5f5f5f8f8f8fffffffbfbfbfdfdfdfbfbfbfffffff8f8f8fbfbfbf7f7f7 +fffffffffffffbfbfbfffffff3f3f3fdfdfdfffffffffffff8f8f8f8f8f8fffffff7f7f7 +fcfcfcfffffff7f7f7fffffffcfcfcffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bc +e2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff1ebdff1ebdff2eaddf1ebddf1ebddf1ebddefecddefecdd +eeecdfeeecdfeeece0ecece2eeebe2ecece2ecece4ebede0e8f0dbe8f0d9ebeedbeceddf +eeece0efebe0efebdfeeecddeceddbebeed9ebeed9ebeedbeeecdfefebe2f2e8e6f2e9e4 +efecddeeedd9eeeddbeeeddbeeeddbeeecddeeecdfeeecdfeeece0eeece0eeece0eeece0 +eeebe2eeece0eeebe2eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeedd9ebefceeef3caeff1c9edefca +eef2d9e6ece0e9eef194999ffcfffffcfffbedf8e7f8ffffbbc0f8b0acff1b0ab21300c3 +1404c91004be03009fc4c5ffbecbf7f2fffff1fcfef9fffff7f6fffffdfffaf8e1ffffe4 +fffff3eeede9fffffdfdfffefffffff6f6f6fffffff9f9f9f7f7f7ffffffffffffffffff +f8f8f8fffffffbfbfbfffffffffffff6f6f6f5f5f5fffffffffffffdfdfdfefefefcfcfc +fffffffefefef4f4f4fffffffdfdfdfdfdfdfffffffffffff4f4f4fffffffffffffbfbfb +fcfcfcfdfdfdf4f4f4fffffff2f2f2fdfdfdfffffff9f9f9fffffff3f3f3ffffffffffff +fbfbfbfffffffffffff4f4f4ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffff +e6f8fff1ffff808a81c3c5b70700000400070201235159874058864c6f974b728f00081c +f1ffff020111f9e7f5fff7fffcf6fafffffff6f6f6fffffff9f9f9fffffffbfbfbffffff +fffffff5f5f5fffffffffffffcfcfcfffffffffffffbfbfbfffffff4f4f4fffffffcfcfc +f6f6f6ffffffedededfffffff8f8f8fffffffcfcfcfefefefffffff9f9f9ffffffffffff +fafafaf4f4f4fffffffffffff6f6f6fffffffffffffafafafbfbfbfffffffdfdfdfdfdfd +fdfdfdf5f5f5fffffff9f9f9ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8ff +f4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1ebdff1ebdff1ebddf1ebddefecddefecddefecddeeecddeeecdf +eeecdfecece0ecece2ecece2ecece4ebece4eaeee0e7f1d9e8f0d8ebeedbeceddfefebe2 +f1eae2f1eae0efecddeceddbebefd8ebefd8ebeed9eeecddf1eae2f3e7e7f3e8e6efebdf +eeeddbeeecddeeecddeeecddeeecdfeeecdfeeece0eeece0eeece0eeebe2eeebe2eeebe2 +eeece0eeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefecd9edeeceeef2cdedf1ceeaefd1edf2dc +e6ece0e9efeb929a9cf1fafff7fffff5ffffc4ccfd101070221daf0700bc1606e20400d4 +140adc0804bd1213a90d1578a2aee8f4ffffebf1fffffbffede5f4fffdebfcf7daffffef +fffff8fafafcfefffff6f6f8fffffffefefefffffffffffff2f2f2fafafaffffffffffff +fbfbfbfefefef4f4f4efefeffffffffffffffffffff5f5f5ffffffffffffffffffffffff +fbfbfbfffffff7f7f7ffffffe5e5e5fffffffafafaf6f6f6fffffff2f2f2f9f9f9ffffff +fefefefffffff6f6f6fffffffafafaf7f7f7fffffffdfdfdfffffffffffffafafaf6f6f6 +f9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff1ffff +f1ffff0003008b877bd5c7c407000900002500003a4e68b3355ba4325f9600072eedffff +f3f5ff2d1925ffebf3fffcfffffffff9f9f9fffffff8f8f8fffffff3f3f3ffffffffffff +f9f9f9fffffff1f1f1ffffffffffffecececfffffffffffffffffffefefefffffff9f9f9 +f8f8f8fffffffafafafcfcfcfffffffdfdfdfffffffffffffefefef6f6f6f8f8f8ffffff +fffffff0f0f0fefefeffffffecececfffffffbfbfbfffffff8f8f8f6f6f6ffffffffffff +fffffff8f8f8fcfcfcffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2 +e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddecedddeceddfeceddf +eceddfecece0ecece0ecece2ecece2ebede0ebeed9ebeed9eeecddefebdff2e9e2f2e9e2 +f2e9e0f1ebdfeeedd9eceed8eceed8eceed8eeeddbf1eae0f2e9e4f2e8e6efeae4eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeece0eeece0eeece0eeecdf +eeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefecddedecdaeeefe1edeceaeaeaecedefece6ebe5 +e9f0e8929b98f8fffff0f4ffb7b7ff00007f1510a807049df0efffe7e6ffeeefffeeefff +edf2ff0b119d0100b10a06a1c8ccfff7fcffede9fffff9fffff5fdfffef6fffff1fbfbf1 +f9f9fff8f7fffffefff8f8f8fffffffafafaf6f6f6fffffffcfcfcfffffffbfbfbfafafa +ffffffffffffffffffe5e5e5fafafafcfcfcffffffebebebfdfdfdfefefef9f9f9ffffff +f2f2f2fffffff2f2f2fffffff9f9f9fffffffafafaf7f7f7fbfbfbffffffffffffffffff +edededfffffff9f9f9fefefefffffffffffff0f0f0fffffff2f2f2fffffffffffffafafa +fbfbfbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffbf3fef0fbfff4 +0301000c02008a7b74d2c3ca120b2d00003e4855b35169cb3655a5001147ecfffff8ffff +f7f1f1080000fffefdf7f7f7fffffff7f7f7fffffffffffffffffff9f9f9fefefefdfdfd +fafafafffffffcfcfcfbfbfbfffffff4f4f4f4f4f4edededfdfdfdfafafafffffff2f2f2 +f2f2f2fffffffffffff4f4f4fffffffcfcfcf9f9f9ffffffffffffffffffeeeeeeffffff +fffffff7f7f7fdfdfdfffffffbfbfbfffffffefefefafafafffffff2f2f2efefeff5f5f5 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eada +ebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecdfecedddebeeddebeeddebeeddecedddecedddecedddecedddeceddfeceddfeceddf +eceddfeceddfecece0eeece0eeecdfeeeddbefecdbf1ebdff2e9e0f3e8e4f3e8e4f3e8e2 +f2eadfefecdbeeedd8eeeed6eeedd8efecd9f1ebddf2e9e2f2e8e6efeae7eeeae7eeeae7 +eeeae7eeeae7eeebe6eeebe6eeebe4eeebe2eeebe2eeece0eeecdfeeecdfeeecddeeecdd +eeecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebe0edeae1f0ecebede9f8eae8f6eeedf2e6ebe5e9f1e6 +919c96f1fbfff5f9ffaba6ff3025e50d03c4dcd9ffeef4ff0f1b71071168000968e3eaff +dcdfff1b10f0150cd9acaefff8fafffef9fff4ebfffdf3fefffdfafdfbecf7f9eefefdff +fcfdfffcfcfff2f2f2ffffffeeeeeefffffffffffff0f0f0fcfcfcfffffffefefefefefe +ffffffeeeeeefffffffffffffffffffafafafafafafffffffffffffffffffbfbfbffffff +f2f2f2ffffffe6e6e6f8f8f8fffffffbfbfbf8f8f8fffffff0f0f0fafafaecececffffff +fffffffffffffffffffafafafffffffffffffffffffbfbfbfdfdfdfffffffcfcfcfcfcfc +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffdfcfff6f8faef070300 +100900080000080000fffcffb2b7e14f5ba54256ac4c65b500024100032700031700020c +050a0efefffffdfdfdfffffffffffffdfdfdf2f2f2fbfbfbffffffedededfffffffcfcfc +fffffffffffffffffff2f2f2ffffff0a0a0a090909ffffffedededf2f2f2ffffffffffff +fffffffcfcfcfdfdfdfffffffffffff8f8f8fffffff3f3f3f1f1f1fffffffffffffafafa +fffffffefefeffffffeaeaeaffffffffffff000000fbfbfbfffffffffffffffffff4f4f4 +fefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dc +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdf +ebeeddeaefdbeaefdbeaefdbebeeddebeeddebeeddebeeddecedddecedddeeecddeeecdd +eeecddeeecdfefebdfefecddf2ebdbf3e9ddf3e9e0f3e8e4f5e7e6f3e8e6f3e8e4f2e9e0 +f2ebdbf1ecd8f1ecd6efedd6f1ecd8f1ebdbf1ebdff1eae4efe9e9eee9edeeeaebeeeaeb +eeeae9eeeae7eeebe6eeebe4eeebe2eeebe2eeece0eeecdfeeecdfeeecddeeecddeeecdd +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebe0eeeae1f0ecebede9f7eae8f3eeefeae6ece0e9f0e8919c98 +f5ffffb9bffb160eb90000d30d02e2110fc8ebf5ffebfcffecfeffedfaffedeeff0a06cf +0500e50600ca0d0d7fc7c9fff3f0fffffbfffffefbfffeedfdfeec00020000000b030615 +0f1015fdfdfdf1f1f1ffffffe8e8e8f0f0f0fffffffffffffbfbfbfffffffffffff8f8f8 +fffffffffffff0f0f0fffffffffffffffffffdfdfdffffffefefeffafafa020202050505 +fcfcfcffffffffffff000000060606fffffffffffffffffffffffff8f8f8fdfdfdffffff +edededf6f6f6fffffff5f5f5f9f9f9f5f5f5fffffffbfbfbebebebfffffffffffffbfbfb +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffefffefcfff9f8ff020200000300 +000300ccd4c5e5f2ebf2ffffb9d0de6b86a4506ba03350924a67ad4d6bab46659100041c +f4fdfffcfcfcfffffff5f5f5fdfdfdfffffffffffff7f7f7fffffffffffffafafaf0f0f0 +fffffff2f2f2ffffff000000fffffff9f9f9fafafafffffffefefefcfcfcffffffefefef +fffffffffffffffffff4f4f4fefefefffffffffffffffffffcfcfcfffffff1f1f1f9f9f9 +fffffffafafafffffff0f0f0ffffff141414f8f8f8f8f8f8fffffff9f9f9fefefeffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddebeedb +eaefdbeaefdbebeedbebeeddebeeddecedddecedddeeecdfeeecddefecddefecddf1ebdd +f1ebddf1ebddf2eaddf5e9ddf6e8dff5e7e4f5e7e7f3e7e9f3e7e9f3e7e7f3e8e2f2eadd +f2ebd9f2ecd6f2ecd6f1ecd8f1ecd9efecddefebe0eeeae7eeeaebeeeaebeeeae9eeeae7 +eeebe6eeebe4eeebe2eeebe2eeece0eeecdfeeecdfeeecddeeecddeeecddeeecddefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeeadef1ece6efeaf0ebe9eceef0e2e6eddde9efef919a9fe7f6f3 +cdd6ff1109be0000d11b11fb0e0dcb000874eafeff0f214fd7e5ff0d0fa01d1add0000da +1c14e31d1ba0afaff9fcfbfff8f8f8ffffefffffea010200fefffafbffffeff3fcf2f3f7 +fcfcfcfffffff5f5f5ffffffffffffffffffeaeaeaffffffffffffedededfffffff4f4f4 +fffffffffffff8f8f8f3f3f3fffffff5f5f5fafafafffffffbfbfb020202000000fdfdfd +ffffffffffff000000000000fffffff2f2f2fdfdfdf8f8f8fffffffffffffcfcfcffffff +fffffffbfbfbfffffffffffff3f3f3fffffffffffffffffffffffffefefef8f8f8ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffefffefafff8f5ff0b0e15000300becec1 +c9dcc9f2fff1efffefe0f9e4bcd6d55c73935870ac405baa3455a438629e00062cf2feff +fffffff7f7f7fffffff8f8f8fffffff0f0f0fffffffbfbfbe6e6e6ffffffffffffffffff +fcfcfcf8f8f80a0a0af6f6f6fffffffffffff7f7f7fffffff9f9f9f9f9f9ffffffffffff +fffffff2f2f2fffffffffffff3f3f3f3f3f3fcfcfcfffffff7f7f7fffffffcfcfcfafafa +fcfcfcefefeffffffff2f2f2060606f3f3f3fafafafefefeffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddeceddbebeed9 +ebeedbeceddbecedddecedddeeecdfeeecdfefebe0efebdff1ebdff1ebdff2eaddf2eadd +f2eaddf3e9ddf6e7e0f8e6e2f6e6e7f3e7ebf2e7edf2e7edf2e7ebf2e8e6f3e9e0f3eadb +f3ebd8f3ebd6f2ebd8efecd9eeeddbeeecdfeeebe2eeebe4eeebe4eeebe2eeebe2eeece0 +eeece0eeecdfeeecdfeeecdfeeecddeeecddeeecdfeeecdfeeecdfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddf0ebd7f1eedbefece3ebebe1eef2d9e6eddbe7edf99099aaf4ffffb2beee +0804b31407f40700e2080abfe7f9ffe9ffff0f1e63edf9ffedf6ff0000801712e20000c4 +09049fcacbfffbfffffaffd8ffffe61b1c0af5f6f1fcfffff9fffff8fffff8f9fbffffff +f3f3f30000000b0b0b000000efefefffffff0000000f0f0f000000ffffff121212000000 +f9f9f9ffffff0909090c0c0c000000000000fcfcfcfefefe000000ffffff000000f4f4f4 +000000ffffff000000fffffff9f9f90c0c0c0d0d0d000000f8f8f8fdfdfd000000050505 +000000000000f1f1f1fffffffbfbfbffffffffffffefefefffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffebe6edfffdff00001300061685989cb5cdc0 +a8c1a3f4ffe4f7ffecebf8efc2cde1818eba465a97506fb2365f9f000636f2fefff9f9f9 +ffffff000000fcfcfcffffffffffff000000ffffff030303121212000000000000ffffff +ffffff000000040404050505fefefef4f4f40000000e0e0e000000f8f8f8fefefe000000 +ffffffedededf6f6f60d0d0dffffff0000000000000b0b0b000000fffffffafafaffffff +000000070707090909000000fffffffffffff9f9f9eeeeeefffffffdfdfdffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddeeeddbeeedd9eeeddb +eeecddefecddefebdff1eae0f1eae2f1eae2f2e9e2f2e9e0f2e9e0f3e9e0f3e9dff3e9df +f5e8e0f6e7e2f6e6e6f3e7ebf1e7efefe7f2eee8f2efe8eff1e8ebf2e9e4f3e9dff5e9db +f3ebd8f2ebd9efecd9eceddbebeeddeeecdfeeecdfeeecddeeecddeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeecddeeecddeeecdfeeece0eeebe2eeebe2efebe0efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecdbf0ebd5f3eed8f0ece0ebecdeeef2d7e6ecdee7ecff9097b3f4ffffbbc7f90a05b7 +1208f40100d9e9ecff03176ee9ffffe7f3ffeef8ffe7f6ffebf6ff120ed41007de0903a5 +bebefff9fff8ffffd6fcffe2010100fffffff5f8fff8fffff8fffffefffffafafaffffff +fffffff5f5f5ffffff040404ffffff000000fbfbfbffffff000000f6f6f6ffffff000000 +ffffff000000fffffffbfbfbffffff000000ffffff010101f6f6f6070707ffffff000000 +ffffff000000fffffffffffffafafafafafaffffff000000f9f9f9060606f9f9f9ffffff +ffffff0d0d0df1f1f1fffffffafafafffffff0f0f0fffffff6f6f6ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffdfffefbf0edf6070a2d4e57824e5e80708694c6dace +bccab1f4f9e5fffffafef7fff1efff7e85b94357964a6bb200023af7fffffffffff8f8f8 +050505fbfbfbfffffffcfcfc000000fdfdfd050505f9f9f9eeeeeeffffff000000f8f8f8 +060606fefefefafafaffffff060606fffffff6f6f6fdfdfd000000ffffff000000ffffff +fdfdfdffffff000000ffffff010101ffffffffffffededed0e0e0effffff000000ffffff +fafafaffffff000000fdfdfdf6f6f6fffffffbfbfbfffffffafafaffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddf2ecdce6dfcdf7f0e0fdf5e8 +f3eae1f5ece5ebe2ddf4ebe6f1e7e5f3e8e6f4e9e7f2e7e3f0e5e1f0e5e1f2e9e2f6ebe7 +fceeeef3e7ebe6dfe7eae7f2f2f1ffeaecf9e6e6f0f2eff6f3eaebf7ece8f9ece3f4e8dc +ebe5d5e7e5d6e8ecddedf1e0f2f4dfeaead2f3f3dbe9e9d1f0f0d6f4f4dae7e7cde7e7cf +eeedd8eeedd9eeeddbeeecdfeeece0eeebe4eeebe6eeebe6efebe0efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdd +f0ebd7f3edddf0ebe5edeae3eff0dee8ebe4e9eaff9195b8f2ffffc0c9ff1108c30100e6 +0a02e3e9edffe6fcff0b23510813631c2574edffffecf8ff0000c01206e209029dc3c1ff +f9feffffffeafcfdef010000fffefff5f7fff8fffff8fffff7f8fdffffffffffff000000 +0000000d0d0d000000ffffff000000fbfbfbffffff050505f8f8f8ffffff000000fefefe +000000fefefeffffffececec0c0c0cffffff000000fffffffbfbfb030303fefefeffffff +080808f2f2f2ffffff000000020202000000060606ffffff000000fffffffbfbfbfefefe +000000fffffff7f7f7fffffffffffff4f4f4fafafaffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffdfffef8fffcff00002e5357a1565fac00003c8089aac7c9d6 +d0c5cb0d000210000cfff1ffd4cafe5758994554a500084bf9fefff6f6f6ffffff090909 +f9f9f9f8f8f8ffffff000000ffffff000000fcfcfcfffffff4f4f4050505fafafa010101 +f6f6f6ffffffffffff000000fffffffcfcfcffffff000000f8f8f8010101fffffff6f6f6 +ffffff000000fbfbfb010101f7f7f7ffffffffffff000000ffffff010101fefefeffffff +fdfdfd030303fffffffcfcfcf4f4f4fffffffbfbfbffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc7 +0837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff1ebddfaf1e2f7ebddf4e8dce5dbd1eadfd9 +fbf0ecf4eae9eee4e5f5ebecf4e9edf2e9ecf4ebeef7eeeff4eeeeeee9e6e8e2e2bab4b6 +c2bdc4bfc2cbb7bdcbacb5c6a8b4c4c0c7d7e5e7f3e7e2e9e8dedfecdeddf2e7e1f8f1e7 +f5f5e9eaf0e4e2e8dae5e7d1f5f5dbf3f3d9f1f1d5ededd1f8f8dcefefd3f7f7ddeeeed6 +eeedd9eeeddbeeecdfeeebe2eeebe6eeeae7eeebe6efebe2efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1e9dc +f3ede1f2ebe3edebdfeff1dce8ebe4e9eaff9195baf5ffffabb4eb0c04af1a0df00901de +0505bde7f4ffe0edfff0f4ffd7daffeef9ff0d13850800ce2215e8100d8ec0c1fffcfdff +fafaf8fffdff1b191ef5f4fafcfffff9fffff8fefffefffff0f0f0000000ffffffffffff +ffffff000000ffffff0e0e0efffffff1f1f1050505fbfbfbf9f9f9020202fcfcfc080808 +fafafaffffffffffff000000fefefe080808f8f8f8ffffff000000f9f9f9fbfbfb000000 +ffffff000000fffffffafafaffffff010101efefef0c0c0cffffffe9e9e9ffffff0e0e0e +fffffffffffff3f3f3f6f6f6ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbf9fcf3f3f8fe010b3c414e9c4555b45d6cc700003f72759ec5bece +88797e0d0004fff5fffff4ff5657905a66ae000039f4f9fffffffff7f7f7000000ffffff +fffffff4f4f40a0a0af3f3f3000000ffffffffffffffffff040404ffffff000000ffffff +fffffff4f4f40b0b0bf7f7f7fefefef0f0f0000000ffffff080808fbfbfbfffffff2f2f2 +000000ffffff000000ffffffecececffffff030303f3f3f3080808f8f8f8fbfbfbffffff +000000fefefefffffffffffffffffff5f5f5fefefeffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db +1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff1ebddeee2d4f8eaddf7e9e0f2e5ddfbf0ecf7edec +f3eaedefe8eff6eff7ded9e0bfbcc5aeadb5afb0b5b6b9bebdc1c4bfc3c6b6b9beb9c0c8 +bac8d3b7cad9a7bed08fa5ba7b8ca0747d8eeeedfbf8f1f9fff2f9f9edefede5e3e2e3de +e3e9e5eaf1e9e9ecdbfdfce7dfdec9e3e3cbe3e3cbefefd5e5e5cbeaead0eeeed6eeedd9 +eeeddbeeecdfeeebe4eeebe6eeeae7eeebe6efebe2efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0f1e8e3f3ece4 +f2ecdcededd5eff2d3e9ebddeaeaff9295b4edf8fef4fdffd4d1ff0000a90800d30a00db +0e09d71611cdf1ebff1f17b80000a21c11d90700d90000adc2c3ffe4e8fffefafff9f3ff +fffbfffffaff010002fcfffff9ffffedf6f5f7f9f8ffffff000000ffffffeeeeeeffffff +000000f7f7f7000000ffffffffffff0f0f0ff1f1f1fefefe121212f5f5f5000000f5f5f5 +f6f6f6ffffff000000fcfcfc040404fffffffcfcfcfffffffbfbfbffffff1c1c1cf6f6f6 +000000fffffffefefefcfcfc000000ffffff000000fffffffffffff5f5f5000000dadada +fffffffffffffdfdfdfffffffcfcfcf7f7f7ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffbfffbf2fff8eaffff00081e567bb0476cc42648a94463b6000f488797a4c2cec2 +ccd2c6000202f7feff4a5982475f8d000c31f4fcfffffffffefefe020202f5f5f5ffffff +fafafa000000ffffff080808f3f3f3ffffffffffff000000fbfbfb020202fffffff0f0f0 +ffffff000000fbfbfbffffffffffff000000f7f7f7070707eeeeeef0f0f0ffffff000000 +f5f5f5000000fdfdfdfafafaffffff0a0a0afafafa0a0a0afffffffffffff7f7f7131313 +fffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff3 +1e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff1ebddf4e8dafceee1f7eae1f7ece6ede3e2b5acafb7b2b9 +c2c0cbb2b2beb4b8c4bdc5d2ccd6e2d5e2ebcfdde6bbccd3abbdc1a3b2b9889aa46f8996 +6d8e9f7ca1b48eb1c78ba7bd7d8da4868b9fafabbadfd3e1f6ebf3f3ecf3e8e8eae1e9eb +e4edecddded9f7f4ede8e6daf5f3e6fffff1f6f5e3edecd8f1f0dbeeedd9eeedd9eeecdd +eeecdfeeebe2eeebe6eeeae7eeebe6efebe0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0f0e8e6f3ece4f0eed5 +edefcaf1f3cee9ecd9eaebff9495b1f8ffffeef6ffb7baff1210970e04bb1e10eb0000da +0900e7f0dfff0a00bc1605e11100dd1607d21611a3c3c6fdf9fffff6f2fffff9fffff9ff +fff8fffdfbfe000200000400010c00000100ffffffffffff0000000707070000000b0b0b +ffffff000000fffffffdfdfd000000f9f9f9ffffff000000ffffff060606030303070707 +000000f8f8f8ffffff0f0f0ff7f7f7fcfcfcf3f3f3fffffff5f5f5000000ffffffffffff +000000030303000000121212ffffff000000020202000000101010fbfbfbffffffffffff +f8f8f8fcfcfcfffffffbfbfbffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +f8fffdebfffbdbffff000e2533629a1946a3436ddd3b61cc3456ad000432647f926d848a +bdd4dc00041ce9ffff4d6f95000523f8fffff5f5f5f2f2f2ffffff000000000000000000 +050505f4f4f4000000fcfcfcffffffffffff080808f7f7f7040404f9f9f9ffffffeeeeee +ffffff000000000000000000f8f8f8ffffffffffff000000131313000000000000ffffff +0a0a0afffffffdfdfdf1f1f1000000f4f4f4f9f9f90b0b0b000000111111000000f0f0f0 +fffffffffffff5f5f5ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bc +e2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1ebddeee5d6f6ece0ece3daf5eee8f5f1f0c0bfc4e1e4ede3e9f7 +d8e4f4c4d4e4a9bccd90a7b7819da97e9ca77fa0a982a3aaa6c3cbaeccd6bce4f0c2f1ff +b9ecffadddf48db2cd627c97bec8e3c0bed4beb2c8b9acbdb7afbeb5b5bfb2bbc4b3bcc5 +f0eefcf6f0feefe9f3e7e2e8f0eceddbd8d3e6e3daf6f4e7eeecddeeecddeeecddeeecdf +eeece0eeebe2eeebe4eeebe2efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0f0e8e6f3ede1f0f0ceedf0c3 +f1f3cbe9ecd7ecebfb9595adf9ffffedf7f6f7ffffc2c7ff0a05830100ac2412fc0e00f0 +f2dcff1600cd1100c90200a9120b97c2c4ffeef4fff0f7f0fffffaf5eff1fdf1fffff9ff +fdf8fcf6faebfbffe8fbffeafefff8f8f8f8f4f4f4fefefefefefefffffff9f9f9f1f1f1 +fdfdfdfefefefdfdfdfffffffffffff3f3f3fffffff7f7f7000000fffffff9f9f9ffffff +fffffff5f5f5fafafafffffffffffff6f6f6fffffffffffff2f2f2fffffff4f4f4fefefe +fffffffffffff8f8f8ffffff000000fefefefffffffbfbfbf5f5f5f9f9f9fbfbfbffffff +fdfdfdfafafaf3f3f3ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8ffff +e3fffde2ffff000b42476cc43c64d63f66e9375de63c5ee32f4dc5617fe1355497395a87 +c3e6ff0006295374a7000230eff6fffffffffffffffffffff5f5f5ffffffffffffffffff +fffffffefefefcfcfcfffffffcfcfcf4f4f4fffffffafafafffffff3f3f3fffffff5f5f5 +fdfdfdfffffffdfdfdfffffff3f3f3f9f9f9fffffffffffff4f4f4fffffffffffff7f7f7 +fffffffffffff9f9f9fffffffffffffffffff3f3f3ffffffffffffeeeeeefffffffbfbfb +ffffffffffffffffffe9e9e9ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8ff +f4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff2eaddfef8eae9e5dae4e1dce4e4e6b7bcc2d4dee895a5b47f94a7 +809bae86a5b98fb4c69ec8d8b2e0edc9f9ffd9ffffc0e8f0c3eef7ccffffc6ffffb1eeff +ade6ff97c6e26b8cabcbd8f8d2d1f0d6cce7d9cbe4d6cee3d3d2e2cad3e2c9d1e4b4b1d0 +a99fc2b7aecdc4bcd4e5deeefff9fff3eff0e8e5e0eeebe2eeecdfeeecdfeeecddeeecdf +eeecdfeeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebe0f0e9e3f3ede1f0efd0eeeec8f1f1d5 +eaeae0edeafb9795abf4f9fcf3fdf4f8fff8edf7fff5f9ffb9b6ff00009a2312d01200ae +1b0ca70c018cc8c4ffb5b6fff5fcfff9fffffcfff4f1eee7fffcfdfff4fffffbfffffefd +fafceff7ffeaf5feebfefffafffffffffffffffffffffffff3f3f3ffffffffffffffffff +fbfbfbf9f9f9f7f7f7fffffffffffff0f0f0ffffff000000f6f6f6fffffffcfcfcf8f8f8 +fffffffdfdfdffffffffffffffffffe6e6e6f5f5f5fffffff6f6f6ffffffffffffececec +fffffff7f7f7fdfdfd0e0e0efdfdfdfffffff2f2f2fffffffbfbfbf3f3f3f9f9f9ffffff +fffffffefefef9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff4ffff +ecfdff000337364a934c61ba3750b5405acb405bd0435cd2324eb14b6aad3e5e8745637d +47617c415587000732f9fcfffcfcfcfffffff8f8f8f8f8f8f6f6f6fffffff3f3f3f3f3f3 +f7f7f7fffffffbfbfbf9f9f9fffffffffffffdfdfdfffffff5f5f5fdfdfdffffffffffff +ffffffedededfafafafffffffffffff7f7f7fffffffffffff9f9f9fffffff5f5f5fcfcfc +fffffff9f9f9f8f8f8ffffffeeeeeefffffff3f3f3fbfbfbfffffffdfdfdfcfcfcf7f7f7 +f3f3f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2 +e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfe5e2d3f2f0e3e8e8deeef0ebf0f5f8c4cfd5e9f9ff869dadaac6dbadd0e4 +b4dff2bbeafcbcf1ffbcf6ffbffbffc2fcffdbffffccfeffc0fbffadf0ff9ce3f9a6e8ff +96cbea6286a8dcecffe8e8ffeee5fff0e3ffebe3fbe7e5fbe2eaffe5ecffeae4ffb8abe3 +9084b6766b95766c8ef1e9ffefe9f5ede8eceeeae7eeebe2eeecdfeeecddeeeddbeeeddb +eeeddbeeecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff0e9dff3ede1f0eddceeeadef1edeaeae7f0 +ede9ff9795adfcfefffbfffff9ffeff1ffe8f8fffdf5fdffc4c7fcbcbdfebab9f3c3c4f2 +c2c9e6f4fcfff7ffffe9f4faf6ffeefcfff2fffaffefe3f9fffbf2fcf5e2fffff4fffffd +f7fafffcfefffefffff1f1f1f9f9f9fffffffffffffffffff6f6f6f3f3f3eeeeeeffffff +fffffffffffffdfdfdfffffffffffffefefefdfdfdfffffff7f7f7efefeffffffffafafa +fffffffffffffbfbfbfffffffffffffffffff7f7f7fffffffffffff7f7f7ffffffffffff +fffffff6f6f6fffffffefefef7f7f7fffffff5f5f5fffffffffffffffffff8f8f8f9f9f9 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffdeefffff6ff +0a00070d030c04000c0304190000220e153f000b2e00031b00050b0b1b1b00030500000c +080120010017fffdfffffffff3f3f3fffffffffffffffffff6f6f6ffffffffffffffffff +f9f9f9fffffffbfbfbf8f8f8f3f3f3fffffffafafafffffffffffff2f2f2f4f4f4fafafa +ffffffffffffffffffefefeffffffff7f7f7ebebebfffffffefefeffffffffffffeeeeee +ffffffffffffeeeeeefffffff6f6f6fffffffefefefdfdfdf4f4f4ffffffffffffffffff +fdfdfdfcfcfcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001bc70837db1c60f31e55bce0e9fff4ebe2e8ebda +ebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeeecdfebeddfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff4eee0efecdde4e4d8eff4ede0eae9a6b5bae2f5ff89a5baa7cce6a5d4f0a3dffb +a7e9ffaaf1ffaef6ffb3f7ffb8f8ffbaf3fab4eff7b4f8ffa9f2ff99e5ffa8edff9ad2f5 +638bafbbcdf3c8caf0ded4f7f6e8fffef4ffe3e2ffb1b7db888fbb726caa786cae7e73af +756b9d4a4267f5edffe9e3eff0ebefeeebe6eeebe2efebdfeeecddeeeddbeeeddbeeeddb +eeeddbefecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeeadef1ede1f0ece3eee9e6f1ecf3ece5f5eee9fd +9895a8f6f5fffcfffff4fde8f3ffe0f8ffe6f7ffebf2fff5f8fffff7fff8fbfff4f9ffec +eefce3f7fff7f9fff8faffebfdfff4fbf3fffff9fffcf6e8ffffe8fffff4edecf1fcfdff +fbfcfffdfefffffffffffffffffffff5f5f5f8f8f8fffffffffffffffffffffffff6f6f6 +fffffffffffffbfbfbfffffffcfcfcfffffffffffff7f7f7fffffffffffffdfdfdf8f8f8 +fdfdfdffffffedededfffffffcfcfcfffffffbfbfbf7f7f7ffffffffffffedededfcfcfc +fffffff6f6f6fffffffffffffafafafffffffffffffafafafdfdfdffffffffffffffffff +f9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffcfffff5ffffebfffff8f4 +fffaebfff7e7fffdf1fffefbeeeef0f7fcf8f9fff8f5ffeffcfff3fffffafffcfffff9ff +fff9fff9f4fafffffffffffff9f9f9fffffffafafafafafafffffff9f9f9fffffffcfcfc +fffffffffffff7f7f7fffffffefefefdfdfdfffffff2f2f2fffffffffffffdfdfdf5f5f5 +fffffff8f8f8fffffff1f1f1fffffffefefefffffffafafafcfcfcfdfdfdfcfcfcffffff +f1f1f1fffffffdfdfdfffffff8f8f8fffffff2f2f2fffffffefefef4f4f4ffffffffffff +fdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001ec90534d81d61f42158bfdde6fff4ebe2ecefdee9eeda +eeeddbefebdfefeae4f1eae4f5e8dff5e9dbefebdfeceddfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff2eadd +ecded1fceee1ece9dae3e7d9eef9f1aebdc0c7daeb93b1cda1cef595d4ff8ee1ff90edff +94efff98edffa9edffb5f3ffb3f0f5adeef4a8f0ffa7f3ff96e2ff9adfff97cdfb6086b3 +abbce7b8b7dfc4b8e0c2b1db9e92c27c77ad7476b36d70b36e6ab4746db1756da8726c98 +524e69eeeaf8f0ecede9e6dfefebe0efebdff1ebdfefebdfefecddefecddeeecddeeecdd +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfedebdef0eee1efece3edeae3f1edecece7ebf0ebf299969d +fffefffeffff7b81777f8877838f7978866f7b8a7782917e818b7390997e6e775a828a72 +a4ab99fefff3fffff3fffff8fbf6fdfffafffffefbfffffafffffff6f7fcfcfffff0f3fc +fefffffafafafdfdfdfffffff4f4f4fffffff9f9f9fffffff8f8f8fffffffbfbfbffffff +f7f7f7f9f9f9fefefefffffffdfdfdfefefef9f9f9fffffffbfbfbfffffff8f8f8fbfbfb +f6f6f6fffffffffffffffffff6f6f6fffffff7f7f7fffffffbfbfbf7f7f7fffffff2f2f2 +fffffffafafaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffefffffcfffffbfffffdfbfffef8 +fffef8fffffafffffdfffffffefffffefffdfefffbfefffbfffffdfffefffffdfffffdff +fffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff2eaddf6e4da +fcecdff1eeddebefe0e6f2e8cbdbdbb6c7d7a4c1df93c2ec8ad1ff84e1ff82eaff84ecff +8febffa2ebfeacebfaa9eef5a3ecf59be9fd9becff8cddff92dcff95cfff668ebfa4b7e2 +b8bae3c4b9e3bfafdc988bc1736dab6f72b96f72bf7976c37a77bc7772aa706e95504c63 +ecebf3f3efecefede1f1ebdff1ebddf1ebdff1ebdfefebdfefebdfeeecddeeecddefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfedebdcf0eee1efede1edeae1f1eee9ece8e7eeeced99979affffff +feffff868887e5eae4eaf1e9e3eee0d7e4d3e0eddbe4edd8d4ddc8fcfff1e7ebdc8f9385 +494b40fffffafffdfafffefdfffefffffdfff4f3f8fdfefffeffffdee2e5fefffff9f9fb +fffffffdfdfde1e1e1fffffffffffffbfbfbffffffffffffffffffedededfefefeffffff +f5f5f5fefefef9f9f9fcfcfcfffffffffffff5f5f5f6f6f6f9f9f9ffffffffffffffffff +ffffffffffffe8e8e8fffffffffffff6f6f6f9f9f9fcfcfcffffffedededffffffffffff +fffffff3f3f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff2eadff7e9e0f4e7de +f2f0e1eff6e6dee8ddeaf6f4a7b5c2b8d2ed85b1d687c8f281ddff7be2ff7de2ff8ae6fd +9ce5f89ee3f29be9f392e8f588e2fa87e4ff7ed9ff86d8ff8ed0ff6c9ccc91acd7b4bde6 +c0bbe4bdb1df978ec37170ac767ac17b81cb9292dc908dd08681b977759c524e65ebeaf0 +f2eeebeeece0f1ebdff1ebddf1ebdff1ebdfefebdfefebdfeeecddeeecddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddeeebdaf1eeddf0eddeedebdff1eee9eae9e7ededef98979cf6f7fcfefeff +727378feffffeef2f5fcfffffcfffffcffffe5edf0f9ffffe8edf1fbffffa6aaadfeffff +4c4c4efffefffffefff8f6f7fffefff9f9f9fefffffefffffefffff7f9f8fffffffdfdfd +fffffffffffff7f7f7f5f5f5fcfcfcfdfdfdffffffedededffffffffffffecececffffff +fffffffffffff9f9f9ffffffeeeeeefffffffffffffffffffffffffefefefffffff7f7f7 +fffffffffffff9f9f9eeeeeeffffffffffffffffffffffffffffffe3e3e3fefefefbfbfb +f8f8f8fbfbfbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdff4e7dff0e6ddebecde +ecf3e3e2eaddeffaf6aab4bebfd3eb7da5c882c2e880d8fe74dbfe73daf982e2fb92e0f7 +8edbef8ae3f384e5f879defc79dfff75d7ff78d2ff83ccff6ea3d57fa0cdb0bfe8babce5 +beb8e4a09ccf7a7bb48489cb888fd79090d8918fd08984ba7a789d535065eae9eff0ede8 +eceadef1ebdff1ebddf1ebdff1ebdfefebdfefebdfeeecddeeecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecddf0ebd7f3eedaf0eddcedebdeefefe7e9e9e7ecedef95989df7faffeef0fc888795 +fffdfffffdfff2eefcfffcfffffcfff9fdfff7fefff0f5fff8fdff9699ac393b4a61616d +45444cfdfcfffffefffffffffffffdf2f4f1eef0ebfefffbfdfffcfdfdfdfffffff4f4f4 +f4f4f4f9f9f9fffffffdfdfdfffffffffffffffffffdfdfdf8f8f8f6f6f6ffffffededed +fffffffffffffffffffffffffffffff6f6f6f3f3f3f9f9f9fffffff9f9f9ffffffeaeaea +fffffffffffffefefef0f0f0fbfbfbefefeff5f5f5fffffffffffffafafafffffff4f4f4 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001ec90435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff1eae0f0e5dff1e8e1e7e7dbe8ecdd +ecf2e4e6ebe5c4c8d1bbcadf7fa2c282bee37bd3f96dd5fa6ad7f876ddfc86dbf880d6f1 +77ddf675e2ff6adaff6eddff6cd8ff6bccff75c5fa6aa8db7298c5aec3eeb4bbe5babbe7 +a6a4d67a7bb38186c68186ca7372b67978b47b77a9757496535063ebeaeff1eee9edebdf +f1ebdff1ebddf1ebdff1ebdfefebdfefebdfeeecddeeecddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdb +f1ebd5f4eed8f2eddaedebdeeeefe7e8eae7e9eef19299a1fbfffffbfeff8f8da2fffbff +7369819e90a988768e7e70918989bd6b71ab7b81b5767aa7868aaf0a0e29d3d4e852525e +fffefff0f0f0fffffbf7f8f2fffffafffffaf2f5eefefffbfbfbf9f8f8f8fcfcfcffffff +fffffffffffffffffff3f3f3f8f8f8ffffffe8e8e8fffffffffffff1f1f1ffffffffffff +fdfdfdf1f1f1ffffffe1e1e1fffffffffffffffffff7f7f7f9f9f9fffffffffffff4f4f4 +f4f4f4fffffffdfdfdfffffffffffffffffff3f3f3fffffffffffff1f1f1ffffffefefef +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001ec9 +0435d81d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff1eae0f0e7e2f4ebe6e9e9dde8eadcf4f6e8 +e1e4dde2e3e8b5c0d285a6c57ebadf71caf463cef85ed2fb67d7ff73d5fc70d2f766d4f9 +69ddff60d5ff64d8ff66d3ff60c3fc6abcf46aa9de6893c0b0c8f4b1bae5b7bae5a3a4d4 +7071a7767ab77377b67272b27a79b37e7ba8787796545162ebebedefece5ebe9ddf1ebdf +f1ebddf1ebdff1ebdfefebdfefebdfeeecddeeecddefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdbf2ead5 +f5edd8f2eddaedebdeeeefe7e5ebe7e6f0f1919aa1f1f9ffebeeff838196fffaff857590 +120019e4cae7221038030142000046161e5f00003514184500001ff7f9ff484a56feffff +fffffdf0f1ebfdfef6f2f3eb0001000002000001000b0b09f4f4f4fffffff3f3f3f3f3f3 +ffffffebebebfffffffffffffffffffffffffefefefffffffffffffbfbfbf5f5f5ffffff +fffffffffffffffffffffffffffffff7f7f7fffffffffffffffffffffffff7f7f7ffffff +ebebebfffffffafafaffffffeeeeee0f0f0ffffffff3f3f3ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001ec90435d8 +1d61f41f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff1eae0f4e9e3f1e8e1f1efe2ecedddebecdce9e9df +efeef3aeb9cb8aabcc77b5de60bfef54c8fb51cdff54d0ff5ecdff5fcdff58cafc61d5ff +56cbff5ccdff61cbff59b9f564b5ed6eabe15d85b6b1c9f5b1bae5b8b9e5a5a3d4706da2 +7d7eb68080bc8c8bc79090c68d8ab580809c565462e9e9ebeeebe4eae8dcf1ebdff1ebdf +f1eae0f1eae0efebdfefebdfeeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf4e9d7f7ecda +f3ecdcedebdeedf0e7e3ece7e5f1f18e9c9ff7fffff8feff908f9febe2f5a794aa2e152b +14000c280f371110540e1766081058040d480007350e1434f8fdff51545df0f2f1f3f6ef +fffff8f8f9f1101109fffffaf7f8f3fffffdfdfdfdfffffff5f5f5fffffffffffff3f3f3 +fffffffffffff7f7f7ffffffeeeeeefbfbfbf7f7f7fefefefdfdfdfffffff4f4f4ffffff +ecececfdfdfdfffffff6f6f6fffffffafafaf3f3f3fefefefefefeffffffffffffffffff +f8f8f8fffffffdfdfdffffff000000f4f4f4ffffffffffffedededffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001ec90435d81d61f4 +1f58bfdde6fff4ebe2ecefdee9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff1eae0f8ebe5ece2d9f5f2e3efeedae0ddcaf5f3e7efedf2 +acb4c78dafd271afde56b7ec4ac2fe45c9ff45c9ff4dc7ff55c8ff52c3ff5fcdff53c1fe +5ac4ff61c3ff5bb0f067afea76ade35579abb1c6f3b2bbe6bdbce8aaa7d67a73a6918cc2 +9b98cf9898ce9898ca918fb67f7f9953515ee9e9e9f1eee7f0eee2f1ebdff1ebdff1eae0 +f1eae0efebdfefebdfeeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf4e8d8f7ebdbf3ebde +edebdfedf0e7e3ede5e3f2ef8d9d9df0fbfff5fcff82828afffbff887480ffedfbfff3ff +ffeefff8f8ffdfebfff1fafff2fbffdce5ff00001bf9ffff3f4448fefffbfefff8fdfff4 +000200fffffaf9faf5fdfdfbfefefefffffff4f4f4ffffff030303040404000000ffffff +f5f5f5030303000000050505ffffff010101000000ffffffefefef0b0b0b030303000000 +040404fffffff8f8f8ffffff000000111111000000fffffffefefe000000fafafaffffff +fcfcfc020202ffffff000000000000000000fefefefffffff9f9f9ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff2eadff9eae3f3e5daf3ecdaedebd6e9e4d0f3efe4e9e4eab6bed3 +8fb1d75f9ed14fb3ef45c2ff3ac3ff38c2ff3bbaff4ec3ff4db5fc5bbcff5dbcff5cb8fb +55a8ec68afef609bd77face3607eb0a3b4e2c0c4f1b4b1dcb0a8d7837aa98f85b7a79fd2 +a4a2d4898ab87776988a8ba04d4b56f7f7f5e8e5dcedebdef1ebdff1ebdff1eae0f1eae0 +efebdfefebdfeeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdff4e8dcf7ebdff3eae1ebebe1 +ebf0e9e2ede5e3f2eb8d9e98f7fffff3fcf9868684fffdfb907e7cffefeefbdcda311b28 +f8fbffeefdff0a1648effbffe1ecff0d1627e2e9ef555b57fefff8fcfff4fffff6000100 +fffffbfffffff7f7f9fffffffafafcfffffff1f1f1fffffffefefef0f0f00d0d0dfdfdfd +030303f8f8f8ffffff010101fefefefcfcfc040404ffffff000000f8f8f8fffffffbfbfb +000000f7f7f7070707fffffffdfdfdf9f9f9040404ffffff040404fbfbfbfbfbfbffffff +050505fdfdfd000000fffffff6f6f6fdfdfdfffffffbfbfbffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff2eadff8eae1eee0d3f3ebd8f7f2dcf2ebd8f7f1e5f6f1f7dbe1f99ebee7 +67a4da49abea35b0f42db2fd34b9ff35afff40adff59b5ff55a4ef519fe769b2f773b4f8 +7db4f5618ec97091c7a1b7e8bcc7f5b9bae6afa9d5bbb2dd9388b38e81af9087b4716e9b +9294bb7c7b9b7c7d91595860eaeae8e5e2d9f8f6e9f1ebdff1ebdff1eae0f1eae0efebdf +efecddeeecddeeeddbefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff1ebdff2e8def5ebe2f2ebe3ebebe3ebf0e9 +e2ede5e5f2eb8e9d96f7fffbf9fffa7f8078fffbf194867bfffaed34180a64504ff8fcff +0c1b42aab9da091731dae6f6000309f9ffff4a4f48fdfff5f2f6e8fffff60c0d07fefefc +f3f3f5fffefff8f7fdffffffe9e9e9ffffff000000030303131313000000fdfdfd030303 +ffffffeeeeee000000fffffff3f3f3060606ffffff000000fffffff7f7f7ffffff030303 +ffffff000000fffffffffffffafafa030303ffffff000000ffffffffffffffffff000000 +fafafa080808f2f2f2ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff2eadffceee3f1e4d4f3ebd6f8f3ddf0e9d6ebe4daf0e9f1eaeeff96b1dc558cc4 +419bda46b5fa42bcff3bb3ff3dabfa5dbaff59a0f074affd7eb6ff74a6ed5683c66a90ce +7996cea2b8eaa3b1e0bcc3efc1c3ecbab5deb8b0d9867ba58a7ea6988db7817fa7717497 +6969856d6f7e5e5d62edeee9fffff6dedccff1ebdff1ebdff1eae0f1eae0efebdfefecdd +eeecddeeeddbefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff1e8dff3ece4efece3eaebe3ebf0e9e3ede5 +e6f1e9919c94ebf7edfbfff6818375fffcec8d8270fff6e2fffbe425170af9ffffeffeff +4b5b6a4f5d66d6e1e5000400fbfffa4e5448fafdf2fffff6fbfcf4000100fffffff7f6fb +fefefffafbffffffffffffff000000fbfbfbfffffffbfbfb000000ffffff080808e5e5e5 +ffffff000000f1f1f1ffffff000000ffffff000000fffffff1f1f1fbfbfb000000ffffff +0e0e0ef1f1f1ffffffe8e8e80b0b0bffffff060606f7f7f7f8f8f8f1f1f1070707ffffff +010101ffffffffffffffffffe2e2e2ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f1ebdffbefe3f6eadcf3eedaf1efdaece7d4e7e0d6ebe1eae8e8ffa4b7e16795c94d99d5 +419fdf389ee040a3e655a9ef7abeff83b6ff759eee5276c24061a8617dbebdd1ffbacafe +9da7d8a2a9d5a2a5ce9ea0c7a9a7cebcb6dc8e86ab847a9d7b73987270958c8fb09797af +8d8f9c525254dbdcd6e8e6dafefceff1ebdff1eae0f1eae2f1eae0efebe0efecddeeecdd +eeeddbefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeeadff0ede4edede3eaebe3ebf0e9e5ece5e7f1e9 +929c94fbfffae9efe38e8f81ffffef7d7562e8dcc6fff0d7efe6d5d5dbdbecfbffd1dfe2 +ccd8d8f6fffd08120af9fff54f5247f7f9eef7f8f0fffffaf3f3f1000002fffefff9f9ff +fefffffffffff2f2f2000000fbfbfbfffffffdfdfd020202ffffff000000ffffffffffff +000000fcfcfcffffff000000ffffff000000ffffffffffffffffff000000fbfbfb000000 +fffffffafafaffffff000000ececec0d0d0dedededfffffffdfdfd020202eeeeee050505 +efefeffffffffffffffdfdfdf8f8f8ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9 +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdf +efe6ddf5ede2f0efddedecd8f1eeddf7f0e8f6ebf3eee9ffaab3da7898c75c95ca549bd1 +71baef97daff8bbef37096d45772bf6077c75e70bc5362a7656facbfc6fcd2d6ffc1c4ef +b7bbe1abafd4a2a5c8a2a5c6a8a9c87e7d9c7f7a987875949c9cbe888ca9bfc0d5989aa6 +565658ebece6fffdf1e0ded1f1eae0f1eae0f1eae2f1eae0efebe0efecddeeecddeeeddb +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecdfebecdeedefe1eceee3e9ece3ebf0e9e6ebe5e9efeb949a96 +f9fef8f6f9f287877ffffff4140e00261f0f08000004010009100900040016211b000601 +000300040902f6f9f25c5d57fffffafffefaededebfffffffeffff040509090a0f000005 +0c0c0ef4f4f4ffffff0606060000000000000d0d0df9f9f9121212fdfdfdededed000000 +fffffffefefe000000ffffff000000000000000000202020ffffffffffffffffff000000 +000000000000fffffffffffff3f3f30606060000001515150f0f0ff8f8f8fcfcfc060606 +000000f2f2f2fffffff9f9f9ffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0ebe4dc +f5f1e8edefe1e7ead9f3f1e2f9f2eaf3e3edeadef4b3b6d994a7d19ac3ef9fd2fd8dbee6 +789fc67288ad8490c06e78bf5b64b35e62ab6c6dae7574adb5b3e4c3c0ebbfbfe5c7caed +c5caeac1c7e7b0b7d49ca1be767c969496afa2a4bd9a9dbca6aac5aaabbf8f929b4d4d4d +f4f5edf1efe3f0eee1f1eae0f1eae0f1eae2f1eae0efebe0efecddeeecddeeeddbefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecdfe9eddceaf1dfe9efe1e7ede1ebf0e9e6ebe5eceeed979998feffff +f7f7f7878684fffffbfaf7f2f1eee5fdfbeffffff6fafff9f9fffafbfffaf1f8f0f6fbf4 +fefffbfffffb52514dfffffdf3f2f0fffdfefefefefeffffe5e6e8fefffffefffff7f7f9 +f4f4f4f6f6f6fffffffffffffffffff2f2f2fefefeedededfffffffffffff5f5f5ffffff +fafafaffffffffffff010101ffffffffffffe7e7e7fdfdfdfbfbfbffffffffffffffffff +fdfdfdf7f7f7f1f1f1fffffffffffff9f9f9f5f5f5edededf7f7f7fffffff8f8f8ffffff +fbfbfbf5f5f5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0edeae5f2f1ec +e7eddfe4ebdbf0f1e3e9e2dce0cfd7e3d4e7ded9f7828aae677fa392b0d2bad5f0bdcce3 +b1acc2b8acd0a29de07574c26e68b07b75b37a71a6a89fccada7cda9a5c6b9bcdbb0b7d4 +adb8d4aab8d3b1bdd59da8beacb4c99ea4ba9599b68f93ac7a7b8d383b44f5f5f5e2e3db +e9e7dbedebdef1eae0f1eae0f1eae2f1eae0efebe0efecddeeecddeeeddbefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeceddde7efdae9f3dbe8f1dee7eddfebf1e7e8eae5ededed98979cfaf9fffffdff +76737ad2cfd6d4d3d8cfcfd1d7d7d7c6c8c5ced3ccc9d0c8c7ccc5d8dbd4d0d2cdb9b9b7 +cac8c9534f50faf5f9fffefffffefffffffff1f3f2fefffffcfffff6f8f7ffffffffffff +fffffff3f3f3fbfbfbfffffffffffffffffffffffffbfbfbf8f8f8fffffffffffff4f4f4 +fffffffbfbfb0a0a0af2f2f2fffffff7f7f7fffffffffffffafafafdfdfdf7f7f7ffffff +fffffffdfdfdfefefefdfdfdfdfdfdffffffffffffffffffedededfefefef9f9f9ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0efece5eeede8e5e8dd +eaeee0f3f3e7e1dad4d7c8cdeadce9f8f0ffe5e7ffe8f6ffe3f5ffe3f0ffe5e8f7c9bdc9 +a999b3aaa3d78280c17b75b1817aae7b73a2aca4cda49ec28885a47475918b91abaeb8d1 +b8c2dbb2bdd3979fb4a4aac0959aae74778a5456654c4c56f7f6fbdedfdaedede3f4f2e5 +ede9ddefebdff1eae0f1eae0f1eae0efebdfefebdfeeecddeeecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecdde9eed8e9f3dbe9f0dee7eddfedf0e5e9eae4eeecf199969ffffdfffefbff4e4856 +5d5763514f5452505156555351504b56584d46483b5d5f544b4d424f4e4961605c534f4e +4e4a4bfffefffcfafdfdfbfef8f8f8fefffffefffff2f6f5fefffff5f5f5fcfcfcfbfbfb +fefefefffffffbfbfbfcfcfcfffffff5f5f5fffffffffffff7f7f7fffffff9f9f9fefefe +fdfdfdf4f4f4fffffffcfcfcfffffff9f9f9fafafafffffffdfdfdfffffff2f2f2ffffff +fcfcfcfffffffffffffafafafffffff1f1f1fffffffffffffefefeffffffffffffffffff +f5f5f5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0e9dfeeeadfece8ddebe9dd +f7f3eabeb9b3eee6e4ebe5e9fffdfffbfbffeff5fff7ffffe8eefae3e7f3dcdce89897a9 +c4c9e78187ab8589af8789af8282a8a0a0c4a3a2c49897b67c7e97e0e2f76e708587889c +9d9eb3b0aec684819c555267636166dcdbd7fffffae7e4ddece9e0f2f0e4e8e4d8f0ece0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdd +ebecdaedf0ddeceee3eaece1eef1e0e9eae2eeebf69995a4fffdfffffdfffff8fffffaff +fffdf8fcf3e4fffdedfffeedf8f3e0ffffedffffeffffdecfffdf0fffff4fffff6fbf8f1 +f9f8f4fffffdf7f6f4fffffffefffff7f8fafefffffcfdffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc8 +0030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff2eadff3ebe0f4eee2f1eae0ede9e0 +b2ada7e8e5e0f7f6f4efedeefffefffdfeffeff2f9dddfebe4e8f3d8dce8858b9bced6eb +9097b17b829f8d92b27f83a6a6a9ccbdbedd9595b1696a7fe4e3f5f8f6ffe9e7f4868291 +4a45595a526aeae3f3dcd7d4f6f2e6eae6dae0dcd0f8f4e8f8f4e8e7e3d7f2eee2efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddedecda +eeefdfedede5ebebe3eef1dee9ebe0eeeaf89994a8fffbfffcf7fdfff5fff1e4f5bcafa9 +b4a794a3947f8f836dc8c2ac8d8874a6a18e736e5b999685fdfaebf9f7ebfffff6fffffa +efeeeafffffdffffffe9eaecfefffffefffffdfeffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d3 +2064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff5ede0f3ebdef3ede1f2ebe1ede9e0b7b2ac +dfdcd7ecebe9f9f7f8efeef3e8e9eeebeef5e1e3efdde1ecd8dce8adb3c3cbd1ebbec3e3 +8286a99193b98b8db39898bca2a3c29292aa676678f7f5ffebeaf0e3e1e4e5e0e6ede8ef +f7effaece5ecfffaf4f6f2e6e9e5d9ede9ddf9f5e9efebdfe8e4d8f5f1e5efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddedecdaf0eedf +edede3ebebe1eef1dee9ebe0edebf89895a8fffdfffffdfffffaff8b8293827974857c6b +7e7361a79f8c847d6bb7b1a1aaa796bcb9aa908c807c786df7f4ebfffef7fffffafdfcf8 +fffffdfafafafefffffefffffefffff2f3f5ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f7 +1851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddf5efdff1eadaede7d9efe9ddf7f3e8d3cfc6dad7d2 +cac6c3e3e1e2dcdcdee7e6ecf3f3fbe0e0eac9cbd7c8cad7c2c5d89599b6c6c9ec9294ba +74739b7c7ba3b2b0d5a5a4c3807e945a5865e9e7ece8e7e3ebe8e1f1eee7e5e0dcfffefb +e5e0dce2ded3eeeadef9f5e9f5f1e5eae6daece8dcf2eee2f1ede1efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddedecdaf0eedfefece3 +ebebe1eef1dee9ebe0edebf89895a8fffefff7f6fefffbff726a7fd1ccc9686254ede6d6 +716b5bfbf5e9726e62fffff36f6b60fffdf467645bfffff8fefbf6f1f0ecfffffdf5f5f5 +fffffffeffffeaebedfcfdfffeffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefecddefe9d9f2ecdcf0eadaece6d8f8f4e8ede9dee3e0d9c2bebb +eae8e9e6e6e8e0dfe5d0d0d8d2d2dce3e5f1dbddeac4c5d9b6b7d68080a68382aaa2a0c8 +9c9ac1aeaacd827f9a524f60e0dde4eeeae7f7f5e9edead9fcf9e6f5efdfe3ddcff0eadc +f1ede1f3efe3f6f2e6ece8dce4e0d4f3efe3faf6eae8e4d8efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddeeebdaf0eedfefece3ebebe1 +eef1dee9ebe0ecebf99795aae9e9f1fefefff6f2ff858198cccacbf5f5e9f2f0e4f9f7eb +fffff6e0ddd6fffff8f6f3ecfffffa6f6c67fffffafefdf9fffffbf0efedffffffffffff +f6f6f6fdfdfdfefffffeffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddeae4d4f5f0ddf8f2e2ede7d7eeebdcf2eee3f0ede6dfdcd7a4a3a1 +bebcbddfdde2dad9dfd2d0dbd0d0dcc5c4d2c7c6d8bcb9d6c0bcdfbbb7daa8a4c7a29cbe +595472514e63efecf7f2eeeff6f3eaeae7d4e4e2cbefebd2f0ecd3f5f0daf2eddaf6f3e4 +eeeadef0ece0f3efe3eeeadeefebdff1ede1ece8dcefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefecddeeebdaf1eedff0ece3edeae1eff0de +e8ebe0eaecf99596aafcfffffcfefffcfcff7a7a94b5b6bae8ebe4fffffaf3f4eeecebe7 +fffefbfffefbfffefbede9e87d7c7afdfcfafffffdf9f8f6fffffdfafafaf3f3f3000000 +131313f2f3f5f2f3f5ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddefead7f2edd9f7f2dff2ecdcebe8d9ede9ddeeebe2f5f2edf6f2f1b0aeaf +7c7a7f6b6a708d8b96aaa8b39a98a59c99aaa3a0b56a667f736f8a524e6946405a7a758b +dfdbeae8e3e9ece9e4fbf8e9e2ddc7ffffe6faf4dad6d0b6faf4dcf9f4e0e6e3d4e9e5d9 +f1ede1f8f4e8f4f0e4eae6daeae6daf2eee2efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefecddf0eadaf1eedff0ece3edeae1eff0dee8ebe0 +eaecf99497aafbffffecf2fef9fdff686c87c6cad3f8fefc6e74727074737f7f7fb8b6b7 +fefcfdfdfbfcfffeff7b797afaf8f9fafafaffffffdfdfdfffffff060606ffffffeeeeee +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecddf8f3e0ebe6d2eee9d6f7f2dff1eedfebe7dbe3e0d7f3f0e9eae6e3f2eeede0dee1 +918f9464616a61606853505b5b58634f4c575b57657773829f98aaf0e9fbdbd5e3fbf6fd +f2eeedf3efe6ece9d8f2eed5efebd0e4dec4fffbe3f1ebd5ece7d4f2efe0f5f1e5ece8dc +e4e0d4ede9ddf3efe3efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddf0eadaf3eddff0ece3edeae1eff0dee8ebe0eaecf9 +9497aaf6fdfff8fffff8fdff737896c4cdd6eef7f6e5edeffbffffeff0f4fffffffcfaff +f8f8fafffeff6b6b6dfffffffffffffffffffffffffbfbfb020202fdfdfdf9f9f9ffffff +f6f6f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9 +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfede9ddf0ece0f6f2e6e4e0d4 +ece8dcfbf7ebe4e0d4fcf8ecf0ece0fbf7ebdfdbcff4f0e4ece8dcfaf6eaebe7dbf0edde +ece7d4f7f2dee8e5d2ece9d6f3f0e1f3efe3e7e3d8f5f0eaf1eee9e5e1defbf7f8e2dde1 +e8e3e9f5f2f9e7e1ebede8eeefebeae4e0dfefebecfbf4fbf0e9f0e1dbdff3edeff2ede9 +efe9ddfbf6e3f0ebd5e7e2ccf8f3ddf1ecd9f0eadaf2ecdef6f2e6e3dfd3f9f5e9ece8dc +f4f0e4eae6daf4f0e4f5f1e5e1ddd1f8f4e8f0ece0f3efe3f3efe3f0ece0f1ede1ebe7db +eeeadef1ede1e4e0d4eeeadef7f3e7eae6dafbf7ebe6e2d6efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefecddf0eadaf3eddff0ece3edeae1eff1dce8ecdeeaecf89497aa +f5fcfff8ffffeff4ff6e7592c3cdd7e3edee808a8c767e8072757a808185bfbec4feffff +fdfcff6a696ef7f6fbfffffffffffffffffff7f7f7040404000000030303fffffdf1f1ef +000000000000101010f5f5f5f2f2f2ffffff030303000000020202fffffffafafaf6f6f6 +fffffffefefef6f6f6ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfe7e3d7e4e0d4f2eee2fdf9edf7f3e7 +e7e3d7dedacee8e4d8e5e1d5f5f1e5fbf7ebf1ede1e9e5d9f7f3e7e9e5d9eae7d8faf4e4 +f1ecd9f0eddaf4f1e0efecdde6e2d6e7e3d8ece8dfece9e2f1eee9d5d1cef9f5f4f7f3f4 +e9e4e8e4dfe5f8f4f3f1efe3fefcefe6e2d9f1ece8e1dcd9fbf6f3e7e2deeae6dde6e0d2 +fcf7e4e0dbc7ffffecebe5d5fbf5e7eae3d9eee7dfebe7dcf8f4e8ece8dce9e5d9e7e3d7 +ece8dcf6f2e6e3dfd3fcf8ece2ded2ebe7dbe8e4d8f2eee2e9e5d9eae6dafbf7ebf1ede1 +ede9ddf8f4e8e3dfd3f5f1e5eeeadee5e1d5f0ece0efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1e9dcf3ede1f2ebe5edeae1eff1dce8ecdeeaecf89298a8f9ffff +f4fcfff7feff7c83a0b9c3cde4eff1e9f3f5eaf2f5fcffffe7e8edf7f8fdecedf1fdfeff +727377fffefff1f1f3eeeef0fffffffafafa121212fefefeeaeaeafffffd0a0a08ffffff +ffffffe8e8e8080808ffffff000000fbfbfbfffffff0f0f0000000fffffff7f7f7ffffff +f8f8f8fffffff9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddffffdf1ede9dddedaceece8dce9e5d9f2eee2 +fffff3eeeadefaf6eae4e0d4f2eee2eae6daeeeadef2eee2efebdff6f2e6e5e2d3ece9d8 +f1eeddeae7d8edeadbf2eee2f7f3e8f1ede4e8e4dbf9f4eef8f3effcf7f3dbd6d3ede8e5 +fffdfde3ded8f0eddcedebd6f0eddef1ede2fffff6f4efe9e2ddd7f1ede2e8e5d6f8f5e4 +f3f0ddedead9e0dcd0ece8dff9f4f0e6e1ddeeeadfe5e1d5fcf8ecf6f2e6f4f0e4f8f4e8 +e8e4d8f9f5e9f6f2e6e9e5d9faf6eaf1ede1f1ede1f7f3e7f0ece0e5e1d5eeeadeece8dc +eeeadefcf8ecdedacef8f4e8e7e3d7f0ece0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff1e9dcf3ede1f2ebe5edeae1eff1dce8ecdeeaedf69298a8f9ffffeff8ff +f8fdff717693b8c0cbf8ffff7d8588777f82707477818588cdd1d4f4f8fbfcffff767a7b +f9fafcfefffffefffffefffff5f5f5000000f9f9f9fffffff6f5f3010000f8f8f8ffffff +ffffff000000eeeeee101010e7e7e7ffffffffffff0b0b0bffffffefefeff3f3f3fdfdfd +edededffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfebe7dbf6f2e6f0ece0fbf7ebeeeadee4e0d4ccc8bc +0d0900eae6daefebdff0ece0ebe7dbede9dd090500e6e2d6f0ece0f7f3e7f0ece0efebdf +f5f1e5ede9ddede9deebe7dcebe7dcf0ece3040000040000070300040000e4dfd9f2ede9 +f4f0e5e7e5d0f9f7e0edead9e6e2d6d6d2c9f6f2e9efebe2f5f1e6fffff0e5e4d2e2dfce +fefcedf5f1e6efece5e3dedbfffefbf6f2e9ece8dce4e0d4ebe7dbeeeadedfdbcffefaee +f0ece0e4e0d4f2eee2f1ede1f5f1e5f2eee2dbd7cbf3efe3faf6eae0dcd0fffdf1e9e5d9 +dad6cafffff3e9e5d9ebe7dbf4f0e4efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff0eadcf3ece2f0ebe7edeae1eff1dce8ecddeaedf69497a6f9ffffe8f1f8f8fcff +787c97b6bdc7e0e8eaeef3f6f0f5f8f5fafdebeff0f7fbfcfcfffffcffff6f7372f1f2f4 +f5f7f6f2f4f3eef0effefefe0e0e0ef6f6f6fffffff9f8f6010000fffffff0f0f0ffffff +000000ffffff000000ffffffffffffefefef040404fffffffffffffffffff6f6f6ffffff +fefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdffaf6eaeae6daede9ddede9ddfffef2fcf8ec040000 +ede9ddf1ede1f6f2e6e8e4d8efebdf080400fefaeeece8dce5e1d6f6f2e7efebe0e6e2d7 +eae6dbfaf6ebf3efe4ebe7dc120b01f3ece2efe8dee4ddd3f7f0e60d0600e6dfd5e2ded2 +efecd9f1f0dbf3f1e2fffff4edeae3f2efe8f8f5eee4e1d8f5f3e6d3d4c2ffffeeeeefdd +ebe9dcefefe5eeebe6d8d5d0eae6dbf4f0e4f8f4e8e5e1d5fdf9edfffcf0dbd7cbe3dfd3 +ebe7db171307e7e3d7f7f3e7dfdbcffffbeff2eee2dfdbcff2eee2efebdfeeeadef4f0e4 +eae6dae3dfd3f9f5e9e9e5d9efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f0eadef3ece2f0ebe7edeae1eff1dce8ecddeaedf49498a4f5fafdf3fafffbfdff7d7f98 +d3d7e0f5fbfb75797abfc3c4f3f9f7fbfffff6fcfafafffefbffff676d69fcfffffcfffd +fefffdf0f2efffffff000000fffefffffefffffeff050304fdfdfdfffffff9f9f9090909 +ffffff010101fcfcfcecececffffff000000fcfcfcfbfbfbfcfcfcf8f8f8fffffff2f2f2 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc8 +0030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdff1ede1ebe7dbf3efe3ebe7dbf1ede1f5f1e5040000040000 +efebdfeae6daf9f5e9040000110d01c9c5b9f5f1e6fdf9f0e5e1d8fcf7f1f4f0e7f6f2e9 +e0dcd3f7f3e8ede9de060000e5dfd3fef8ecf4eee0fcf6e8ede7d9f5efe1fbf5e7f1eedd +f1efe0d1cfc3fffdf6f0ede8e6e2dffaf7f2e7e4dbe9eadcfeffedf6f8e3dfe1cceff0e0 +eaeadeeeeee6f7f7efeae8dce6e2d6fdf9ede1ddd1e9e5d9eae6dafcf8ecf2eee2e9e5d9 +0b0700e7e3d7fbf7ebf3efe3e5e1d5fffff3ede9ddf1ede1e9e5d9f2eee2f5f1e5e9e5d9 +eeeadefcf8ecf5f1e5efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0eade +f3ece2f0ebe7edeae1eff1dce9ecdbecedf29597a3f7fbfcfbfffff1f3ff73738baeb1b8 +fafcfbf9fbfaeaecebf4faf6bdc7bfbdc3bf5c635c6d736ffbfffdeef3effcfffde8eae7 +fefffde7e7e7080808fffefff9f7f8fffefffffeff070707030303000000f7f7f7ffffff +efefef0b0b0b0e0e0e000000fffffffffffff5f5f5ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d3 +2064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddff4f0e4ebe7dbeeeadef3efe3ebe7dbe9e5d9f1ede1070300080400f8f4e8 +eeeadee8e4d80e0a00040000f7f3e7fefaef040000fffef8ded9d5040000e8e3ddfffff6 +e4ddd3f3ece20d0700f0eadef5efe1efe9d9e3dcccf0e9d9f3ecdce7e1d3060200030000 +1c1914dad6d3ecebe90f0e0c010000101008e9eadc030400000400f5f9e2eef1dc080b00 +000200010100030100eeeadeece8dc130f03e4e0d4ebe7dbf2eee2070300eae6da050100 +060200e2ded2f0ece00804000400000a0600efebdfe9e5d9040000040000f5f1e5f5f1e5 +e8e4d8e8e4d8efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0e9dff3ece4 +f0ebe8edeae3eff1dce9ecdbecedf29597a3f6faf9eff3f6fcfdff737187d5d6dbd1d1cf +afafad858784606760768077626c64f8fff9f7fef7fbfffbf4f9f3fcfffbfefffdf1f3f0 +fffffffffffffcfafbfffefffffefff8f6f7fafafaf9f9f9fffffffffffff6f6f6ffffff +fffffff0f0f0ffffffeeeeeef4f4f4fffffff8f8f8fffffffffffffafafaffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f7 +1851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddff4f0e4eae6daf1ede1efebdfeeeadef3efe3f3efe3040000e8e4d8080400ebe7db +0d0900e8e4d8040000f7f3e7e5e1d6070200e7e2dcf6f1ed070200efeae4e3dfd6f1ede4 +efebe0080100ede9ddf6f0e2efe9dbefe9d9fef8e8ece6d6090300f7f3eae2dfd8efece7 +070300e7e6e4010000faf9f5e2e2da0b0c00dedfcdf8fae5060900dedfcd020500f5f6e8 +eceddff0eee2040000e7e3d8070300f7f3e8efebdfefebe0040000f2eee3080400e9e5da +f5f1e5040000ede9ddfaf6ebebe7db050100ece8dc0a0600eeeadee6e2d6f4f0e4e5e1d5 +f5f1e5efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeadef1ede2efece7 +edeae3eff0e0eaeadeedecf297979ffcfffdfbffffeff3fefcfeff6567665e615a777672 +f6f7f1f2faeff9fff8f8fff9f5fcf4fbfffdecf1edfcfffff5f9f8f3f7f6fcfffff6f8f7 +f4f6f5fffffffffefff5f1f2fffefff8f6f7fffffff4f4f4fefefeffffffffffffececec +fffffffefefefffffffffffff7f7f7fcfcfcfffffff1f1f1ffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +ebe7dbeeeadef9f5e9e5e1d5ebe7dbf9f5e9ebe7db050100ede9dd040000f8f4e8040000 +ede9dd070300f0ece0ebe7dc030000fcf9f0e8e5de030000fffdf4e2dfd6f0ede4e7e4db +040000e5e3d7f8f4e9ece8ddfcf8edeae6dbe5e1d6090500ece9e0f1eee5e3e0d90e0b04 +edeae3030000faf7f0dfdcd3030100f7f5e9f5f3e6010200eceade030300f2f0e4e7e5d9 +f2efe6030100efece3030100f1eee5efede1edeae1030100f3f0e7030100e9e6ddebe9dd +030000030100030000080600040000fbf7eb040000e7e3d7fcf8ecf2eee2dcd8ccf5f1e5 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddedecd8eeefddefede1eee9e3 +f2ede9ece8e7eeecf197989cf9fffdf5fff7f2fff6f8fffaf3fef0fcfff6fffff8fefff6 +f9fff3eefbeaedf7ecfbfffbfdfefff7f8fdfcfffffbfffffbfffff9fffff4fdf8f9fffb +fffffdfffefffffcfffff6fbfffeffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffff3f3f3fffffffffffff0f0f0fffffff5f5f5ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddff6f2e6 +e3dfd3e7e3d7faf6eaf3efe3e9e5d9ebe7db040000f5f1e5e9e5d9040000f1ede1fdf9ed +090500e9e5d9f0ece0151209f9f6edd5d2c917140be5e2d9f5f2e9e5e2d9f2efe6090600 +f8f5ece1ded5ebe8dfece9e0e8e5dcfffff6030000ece9e0fefbf2f5f2e9030000ebe8df +110e05e2dfd6fffff60f0c03f7f4ebd9d6cd0e0b02e3e0d70b0800d4d1c8fffdf4e5e2d9 +080500f0ede4030000f1eee5f3f0e7f1eee5080500e5e2d9030000f7f4ebeae7de050200 +f8f5ecf7f4ebe4e2d6ebe7dce7e3d70a0600f8f4e8eae6daede9ddfffff3ebe7dbefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeecddebedd7eef0dbf0ece0eee9e3f4ebee +ede7ebededef959998e5f0e8f4fff6f2fff3f2fff1eafce6f2ffebfafff1fbfff3eaf9e2 +f5fff1f8fff6fbfffbf5f6fafefefffefefff2f5feeff7faf9fffff9fffdfbfffbf7f9f6 +fcf8f9fffbfffffbfffffeffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffefefefffffffffffffbfbfbffffffe1e1e1fffffffafafaffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddff0ece0f1ede1 +efebdff7f3e7e2ded2eae6dafffdf10a0600dfdbcff2eee2141004ebe7dbe9e5d9040000 +f8f4e8f2eee2e3e0d70300000f0c03e6e3daf3f0e7e0ddd4fefbf2f0ede4030000dad7ce +f5f2e9f4f1e8e4e1d8120f06ece9e0030000ebe8dfdbd8cff8f5ec030000fffcf3030000 +f5f2e9e4e1d8030000f4f1e8f5f2e9030000f3f0e70f0c03f4f1e8e7e4dbfffdf4030000 +f7f4eb030000e4e1d8f9f6ed0300000e0b02ece9e0040100ebe8dff8f5ec030000f0ede4 +e9e6ddeeece0070300eeeade0a0600e1ddd1f3efe3f1ede1e2ded2f3efe3efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefecddedecd8f0efdbf0ece0f0e9e3f2eceeece7eb +ecedef929b96f5fffa445b47728f733a57398ca5887c9075899881778971768f71496245 +6f806e7682787e828384858af2f2fafefefffcfffff7fdfbeff5f1f5fcf5fefffdfffeff +fffbfffff6fbfffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffff8f8f8fcfcfcfffffff9f9f9fffffff1f1f1ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddff4f0e4eeeadee8e4d8 +eeeadef2eee2f9f5e9dbd7cb040000f9f5e9e5e1d5f0ece0ddd9cdfbf7eb040000e8e4d8 +f1ede1f4f2e6030000f5f2e9eeebe2f3f0e7f4f1e8e4e1d8edeae1f6f3ea030000151209 +0f0c03030000e2dfd6ebe8dff2efe60b0800060300090600fffcf3dfdcd3030000ece9e0 +f2efe6100d04e3e0d7ebe8df151209e0ddd40300000c0900030000030000edeae1edeae1 +f9f6ed030000030000fcf9f0030000edeae1e7e4db0e0b02e2dfd6eae7de090600080500 +030100f1ede1ede9dd050100f8f4e8f1ede1f0ece0fbf7ebe2ded2efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddeeebd8f1eeddf2ebe1f0e8e5f2eceeeae8ebeaeeed +909d94f0fff576947a3d603f6084603c5e39769671e4ffde819c7b375934799b7a445c44 +f5fff8f4faf6929397000005fffefff4f5f7f6faf9f8fdf9fcfffbfcfefbfbf9faf7f1f5 +fffdfffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffff2f2f2fffffffffffffafafafdfdfdefefeff8f8f8fafafaffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9 +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfebe7dbe9e5d9fbf7ebf1ede1 +e6e2d6e9e5d9fffef2f7f3e7eae6dafaf6eaf4f0e4efebdfe1ddd1fffff3e6e2d6f8f4e8 +f4f2e6050300f2f0e4efede1eeece0eae8dcf7f5e9eceadee7e5d9f2f0e4dcdacee3e1d5 +fcfaeef0eee2eae8dcf4f2e6e8e6daeae8dcd1cfc3eceadefefcf0f2f0e4eae8dceeece0 +efede1e7e5d9eeece0e7e5d9f9f7eb090700efede1eae8dceeece0f5f3e7e5e3d7dddbcf +fffff4ebe9ddf3f1e5e5e3d7f8f6eaeeece0edebdfeae8dcf3f1e5f9f7ebd2d0c4fffff4 +e5e1d5f4f0e4e3dfd3f4f0e4dfdbcfe5e1d5f4f0e4fbf7ebefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefecddeeebdaf3edddf2ebe1f0e8e5f2eceeeae8e9e9efeb8d9f93 +eefff4315635e3ffe74d7c4e629061426d3f648b5f3b62366e9c6e345e366b8a6bf2fff4 +e6f0e88c8e8dfffdff030004fcfafdfffffffefffdf7f9f4fbfdfafffffffcfafdfffeff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffafafaf9f9f9fffffffffffffffffffcfcfcffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfeeeadee6e2d6f4f0e4e8e4d8f7f3e7 +f7f3e7dbd7cbe9e5d9f4f0e4e2ded2f4f0e4f5f1e5f0ece0e4e0d4f9f5e9040000030100 +e8e6daeae8dcf3f1e5eae8dce9e7dbebe9ddf0eee2f2f0e4eceadefdfbeff8f6eaedebdf +ebe9ddf5f3e7f0eee2edebdffefcf0fffff3edebdfdcdacee7e5d9f9f7ebe3e1d5eeece0 +f3f1e5e6e4d8eceadeebe9dd030100e4e2d6f6f4e8e6e4d8f8f6eaefede1f3f1e5dad8cc +efede1e2e0d4fffdf1e9e7dbe5e3d7edebdffefcf0dcdaceefede1e4e2d6e9e7dbf9f5e9 +eae6daf2eee2eeeadefbf7ebfefaeeebe7dbe5e1d5efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddf0eadaf3eddff3eae3f1e7e5f2eceee9e9e9e7f0eb8ba091e4ffea +e4ffec245828dcffde356c355d925a33632f679964285e2a5b8c5de9ffecf0fff0f8fffa +0507040300020b0509030000dbdad8fffffbfefffbfcfefbfefffffbfcfff6f7fbffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +f3f3f3f1f1f1fffffff7f7f7f5f5f5fdfdfdffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfe8e4d8f4f0e4fcf8ece5e1d5e5e1d5f8f4e8 +f2eee2f8f4e8ece8dcf5f1e5eeeadedfdbcffffdf1f1ede1e8e4d8f7f3e7f0eee2f4f2e6 +ebe9ddf3f1e5e5e3d7f2f0e4fffff4e0ded2eeece0eae8dce0ded2eae8dcf0eee2e7e5d9 +eceadeedebdfedebdfdbd9cdeae8dceeece0fffff3edebdfe8e6daf6f4e8f1efe3e4e2d6 +fffff3faf8ece8e6dafdfbefe9e7dbf0eee2f5f3e7e6e4d8e9e7dbf2f0e4f8f6eaf3f1e5 +e5e3d7eceadeedebdffffff4dddbcfefede1ebe9ddf2f0e4f6f4e8e8e6dae7e3d7fbf7eb +dfdbcff5f1e5e6e2d6e4e0d4e8e4d8f9f5e9efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddf0eadaf4ecdff4e9e3f1e7e5f2ecece9e9e7e6f1e98aa18fe9ffefcfffd7 +ddffe32d6a2fd8ffd9316f3066a0652c662b75b277caffd0e6ffeaebffeceefaeefffffb +fffdffc9c0c5140b0efffefdfffffbf2f4eff5f7f4fcfffffcfffffcfffffeffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0f0f0ffffff +fffffffffffff3f3f3151515fefefef0f0f0ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddff3efe3eae6daeae6dafaf6eaede9dde8e4d8f2eee2 +eeeadef2eee2eae6daefebdff3efe3e9e5d9e4e0d4f6f2e6ede9ddf0eee2eae8dcf0eee2 +f0eee2eeece0eceadedddbcff9f7ebe7e5d9fffff3f0eee2e5e3d7f6f4e8f4f2e6eeece0 +eae8dcf3f1e5f2f0e4ebe9dde9e7dbeceadee6e4d8f7f5e9e9e7dbe9e7dbf6f4e8dddbcf +f1efe3efede1e3e1d5f9f7ebe8e6dae3e1d5faf8ecf4f2e6e6e4d8eeece0efede1f0eee2 +f0eee2f1efe3e1dfd3f7f5e9f4f2e6eeece0edebdff1efe3f0eee2fbf7ebddd9cdfffbef +e8e4d8f3efe3f9f5e9ede9ddeae6daefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecddf1e9dcf4ecdff4e9e3f1e7e5f2ecece9e9e7e6f1e989a28fe7ffefe0ffe8306b35 +63a3671c5d1dd9ffda1f5b1d64a0641d5d216faa742a572eedffeff8fff6fcfdf8fffdff +d0c5c9060000fffdfdf8f7f3fefffbfefffff1f5f6f6fbfefcfffffeffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f4f4 +fffffff6f6f6000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdd +f1e9dcf4ecdff3eae3f0e8e5f2ecece9e9e7e6f1e98aa191e1ffe94171495a9360306d32 +67a468205d21d6ffd53671375d9d6129642e6c9970ebffedf8fff6fffffbf4eef0d9ced2 +060000fbf5f5fffffbfafcf7fefffffbfffff5fafdfbfffffefffffcfcfcfffffffefefe +fefefefffffffffffffffffffffffffffffffffffff7f7f7fefefefffffff5f5f5ffffff +fffffffffffffffffffefefefffffffffffff4f4f4fffffffffffffffffffffffffbfbfb +ffffff080808f7f7f7fafafaf3f3f3fffffffafafafffffffffffffffffff5f5f5ffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc8 +0030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddf0eada +f4ecdff3eae1f0e8e5f2ecece9e9e9e7f0eb8b9f93eafff36c98742359285e97622c652e +6aa16a316330e0ffdf29642c6ca57237613becffedf8fff8fefffafffdffbeb5ba060000 +fffefdfdfcf8f2f4ef000100000100010508000306fefffff8f8f8000000080808000000 +f8f8f8fffffff3f3f3000000000000020202fefefefffffff5f5f5000000080808040404 +efefefffffff000000151515000000fffffffffffffefefe0b0b0b000000000000ffffff +000000101010060606030303f8f8f8ffffffe9e9e9000000050505000000ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d3 +2064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddeeebd8f3eddd +f2ebe1f0e8e5f2ececeae8e9e9efed8e9e94eafff12e55367eab843d6c405d8c603f6a3d +668c632b5629e2ffe33b6c3d6b906e3d553df8fffafefffde7e2e6d9d3d70b0708f5f4f2 +fcfdf811130efefffdf5f7f6feffff000004f5f5f7080808fffffffbfbfbffffff090909 +f9f9f90c0c0cfffffffffffffdfdfd0c0c0cf4f4f4070707fffffff5f5f5f7f7f7ffffff +fffffff9f9f9f0f0f0ffffff000000ffffff000000fffffff4f4f4fffffff0f0f0000000 +fffffff1f1f1fbfbfb060606fbfbfb131313fffffffffffffcfcfc000000ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f7 +1851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddedecd8f1eedbf0ece0 +f0e9e3f2ececeae8ebeaeeef909d96f1fff8edfff3e2ffe7e9ffed759877e2ffe1f0ffed +7693743e673d5c865e476647758a77000400eceeedfffeffc7c2c8010002fffffff5f7f4 +040601f7f9f6fffffff6f4f7131114fefeff000000000000030303000000080808f6f6f6 +000000fdfdfdffffffffffff000000fefefe000000f9f9f9fffffffffffff0f0f0f8f8f8 +050505070707000000080808f3f3f30f0f0fe7e7e7fffffffdfdfdffffff010101ffffff +fefefefafafa030303f8f8f80000000000001010100000000b0b0bffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddebedd7eef0daf0ece0eee9e3 +f2ececece7ebecedef929b98e9f9eff2fff8e2fbe6f0fff36c826df5fff3f3feeef7fff3 +eeffec000e00f1fff1f5fff80b110df1f2f6fffeffc8c7cd000002fcfffffcfffd000200 +f5f7f4fffeffe9e3e7040002fffeff090909f2f2f2fbfbfbf1f1f1fafafaffffff020202 +fdfdfdffffffffffff000000fefefe000000f9f9f9fffffffffffff9f9f9060606ffffff +edededffffff0e0e0efafafa000000ffffffffffffeeeeeefefefe000000fdfdfdffffff +ffffff000000ffffff010101fbfbfbffffffe8e8e8ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeeddbeaeed5edf1d8efeddeeee9e3f2ecec +ece7ebeeecf195999cf9ffffe7f4ebf5fffaf5fff68b958afcfffafffffbf5f8efecffe7 +f1ffed000700000500010506fcfdfffefeffb7b7bf000104f4faf8fbfffd000500fefffd +fffefffff7fc0d0409f0eeef000000fffffffefefeffffff0d0d0df1f1f1050505ffffff +fffffffdfdfd0c0c0cf4f4f4070707fffffff5f5f5fcfcfcffffff000000f6f6f6ffffff +ffffff000000ffffff060606edededfffffff5f5f5ffffff0a0a0afffffff6f6f6ffffff +000000f3f3f3101010fcfcfce5e5e5ffffff000000ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeeddbeaeed5ecf2d8edeedeeeeae1f2ececede6ed +f0ebf298979decf0f1fbfffff9fffde7ece6878785fef8fafffafffffdfdf7fff10c1e08 +eefaecfbfffb040509f9f9fffefeffcdd0d9000205f9ffffebf4effbfffb000100030000 +11060c070002fffeffffffff000000090909000000f0f0f0fffffff7f7f7000000000000 +020202fefefefffffff5f5f5000000080808000000ffffffffffff010101040404010101 +000000fbfbfbfdfdfd0909090000000b0b0bffffff000000fcfcfcfcfcfcfefefe171717 +edededf3f3f30f0f0f0d0d0d000000f8f8f8ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddefecddefecddeeeddbeeeddbeeecddecedddeceddfeceddfeceddf +eceddfeceddfeeecddeeeddbecedddebeddfeaeedfebeeddebeeddeceddbeceddbeeeddb +eeecddefecddefebdfefebdfefebdfefebdfefecddefecddefecddeeecddeeecddeeecdd +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecddeeecddeeecddeeecdd +efecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecddeaeed7edf1daedeedeedeae1f2edeaece7ebf0ebf2 +98979dfeffffe0e4e5fcfffffeffff807c7dfffcfffff3fcfffcfffcfff8000500070e06 +000200000105fffeff080810b9bcc3000104f9fffff0f9f4fbfffdfefefcfffefffef5f8 +11080dfcfafbfffffffffffffffffffffffffcfcfcfffffffcfcfcffffffffffffffffff +f7f7f7fefefefffffff5f5f5fffffffffffff2f2f2fffffffafafafefefefbfbfbffffff +fbfbfbfffffffffffff7f7f7fcfcfcfffffffffffffefefefffffffcfcfcf6f6f6ffffff +fffffffafafaf9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9 +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f2eadff2eadff1ebddf1ebdbefecd9eeedd9eceddbebeeddebede0ebede2ebede2ebede2 +ebede0ecedddeceed9eaefdbe4f1e0e3f1e2e4f1dfe5f1dbe8f0d9eaefd9eceed9efecdb +f1ebdff2e9e0f3e8e2f3e8e2f3e8e2f3e9dff3e9ddf2eaddefecddeeecdfeeecdfeeece0 +ecece0ecece0ecece2ecece2ecece2ecece2eeece0eeecdfefecddefecddefecdbefecdd +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefecddeeebdaf0efddefeddeedebdfefeee9e9e9e7ededef97989c +f0f4f7fcfffff7fbfcfcfefd878787c9c8c6cdc9c8c4c3bfbdbfbad4d6d1bdbfbcbdbfbe +cacaccccccce000002cfd0d2000002fefffff7f9f8f7f9f80e0e0e010000100e0ff3f1f2 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1eae0 +f1ebdff1ebddefecdbeeedd9eceed9eceddbecedddebede0ebece4ebece6ecece4ecece0 +ecedddeeedd9eeeddbecece0ebede2eceddfeceddbeeedd9efedd8f1ecd9f1ebdbf2eadf +f3e9e0f3e8e4f3e8e4f3e8e2f5e8e0f5e9ddf3e9ddf1ebdfeeecdfeeece0eeece0eeebe2 +ecece2ecece4ecece4ecece4ecece2eeece0eeecdfefecddefecddf1ebdbf1ebddefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddf0eadcf1eeddf0ece0ebebdfefeee9e8eae7eceeed95999afcffff +f2f6f9f7fbfcfcffff7a7c7b0f110c00010011120d0505030000000505050e0e0e000000 +0000000000000303030b0b0bedededffffffffffffe6e6e6fffffff8f8f8ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfecece0eceddf +ecedddeceddbeceddbeceddbeeeddbeeecdfefebe2efeae4efeae6f1eae4f1eae2f1eae0 +f2eaddf8e7ddffe2e0ffdfe0ffe1ddffe3dbffe4d9fce6d8f8e8d9f5e9dbf3e9ddf2e9e0 +f2e9e2f2e9e2f2e9e2f3e9e0f3e9ddf3e9ddf1ebdfefebdfefebe0efebe0efebe0eeece0 +eeebe2eeebe2eeebe2eeece0efebe0efebdfefecddefecddefecddefecddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddf0eadcf1eeddf0ece0ebebdfefeee9e8eae7eceeed95999afcfffff1f5f8 +f9fdfefcfffffefffffefffbfffffbf6f7f2fdfdfbfefefefffffffcfcfcfffffffafafa +fffffff9f9f9fbfbfbfffffff4f4f4f7f7f7fffffffffffffffffffefefeffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeaeee0e8eee0eaeedf +ebeeddecedddeeecddefecddf1ebdff2e9e2f2e9e4f3e8e6f3e8e4f3e8e4f3e8e2f3e9e0 +f9e6dfffe1dfffdfdfffe1ddffe3dbfce6d9f8e8d9f2ebd9efecdbeeecddeceddfeeece0 +efebe0f2e9e0f3e9dff5e8dff5e9ddf2eadff1ebdff1eae0efebe0efebe0efebe0efebe0 +eeece0efebe0efebdfefebdfefebdfefecddefecddefecddefecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecddf0eadcf1eeddf0ece0ebebdfefeee9e8eae7eceeed95999afcfffffcfffffcffff +f0f4f3fefffffefffbfffffbfafbf6fcfcfafffffffcfcfcf7f7f7ffffffffffffececec +fdfdfdfafafafbfbfbf3f3f3fffffffdfdfdf2f2f2fdfdfdfcfcfcffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b +001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddfe7efe0e5f0e0e7efe0eaeedf +eceddfefebdff1ebdff3e9e0f5e8e2f6e7e2f6e7e4f6e7e4f5e7e4f3e8e4f3e8e2f2e9e0 +f1ebdfefecddeceddbeaefdbe5f1dbe3f2dbe0f4dbe0f3dde1f2dfe3f2dfe7efe0ecece0 +f2e9e0f6e8dff9e6dff9e6dff3e9e0f2e9e0f2e9e0f1eae0f1ebdff1ebdff1ebdfefebdf +f1ebdfefebdfefebdfefebdfefebdfefebdfeeecdfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdd +f0eadcf1eeddf0ece0ebebdfefeee9e8eae7eceeed95999aeef2f5fafefffbfffffcffff +fefffff7f9f4f8f9f4fffffbfffffdf7f7f7fffffffffffff3f3f3fffffff1f1f1fefefe +ffffffffffffffffffffffffe8e8e8ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff +8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc8 +0030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeceddfe7efe0e5f0e2e8eee2eaede2eeebe2 +f1eae2f3e9e0f5e8e0f6e7e0f6e7e0f6e7e2f5e8e2f2e9e4f1eae4efeae4eeebe2eaeedd +e7f1d9e5f1dbe3f2dbe0f3dddef4ddddf5dfdef4dfe0f3dfe3f2dfe8eee0ecece0f1eae0 +f5e8e0f8e7e0f8e7e0f3e8e2f2e9e2f2e9e2f2e9e0f1eae0f1ebdff1ebdff1ebddf1ebdd +f1ebddf1ebdfefebdfefebdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddf0eadc +f1eeddf0ece0ebebdfefeee9e8eae7eceeed95999afcfffffcfffff5f9faf0f4f3f2f4f3 +fefffbfffffbf8f9f4fefefcfffffffffffffffffff6f6f6fafafafffffffdfdfdffffff +efefeffafafafffffffffffffffffffffffff8f8f8ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9e +e0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d3 +2064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecdfeaeee0e8eee2ebede2eeebe4efeae4f2e9e4 +f5e8e2f5e8e0f6e8dff5e8dff2eadfefebe0ecece2eaede4e8ede6e8eee2eceddbeeedd8 +eceddbecedddecece0ebede2ebede2ebede2ecece0ecece0efebdfefebe0f1eae0f2e9e2 +f2e9e4f2e9e4f1e9e6f1e9e6f1eae4f1eae2f2e9e0f2eadff2eaddf2ebdbf2ebdbf1ebdb +f1ebddefecddefebdfeeecdfeeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddf0eadcf1eedd +f0ece0ebebdfefeee9e8eae7eceeed95999af7fbfef7fbfefafefffcfffffefffffbfdf8 +f5f6f1fffffbf5f5f3fffffff8f8f8f5f5f5fffffff2f2f2fffffffcfcfcffffffffffff +fffffff4f4f4f4f4f4fffffffffffffcfcfcffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ed +edefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f7 +1851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeece0eeebe2efeae4f1e9e6f2e8e6f3e8e6f3e8e2 +f3e9e0f2eaddefecd9eceed9e8f0dbe4f1dfe1f2e2def2e6def3e2e4f2d9e7f1d8eaeedd +ebede0efeae6f1e9e7f3e7e7f5e7e6f6e7e4f5e8e2f5e8e0f2e9e0f1eae2eeebe6ecebe7 +ecebe9eeeaebeeeae9efeae7efeae6f1eae2f2e9e0f2eaddf2ebdbf2ebdbf2ebdbf1ebdd +efecddefebdfeeece0ecece2ecece2efebe0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddf0eadcf1eeddf0ece0 +ebebdfefeee9e8eae7eceeed95999afcfffffcfffffcfffffbfffefafcfbfdfffafffffb +fffffbfffffdfffffff6f6f6fffffffffffffffffffcfcfcfffffff6f6f6fffffff6f6f6 +fffffffdfdfdffffffefefefffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffbfffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2 +efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1ebdff1e7def2e5dff5e7e6f9ebebf7e9e9f0e5e3f0e9e1f4f2e5 +e4e8d1ecf7d9e9fad8d8f2cfd5f4d5ddffe7d8ffeac8f2dacbf4d2dcffdfd5f1daddede0 +eaeeede9e3e7f9e8f0fbe4ecfee3e8fde4e7fce8e7f2e4e1e6e1ddececeaeef4f4e4e9ed +e5e5edefeef4f2f0f3e9e5e4f8f3efefe8defef6e9e8e1d1f2ebd9f2ebd9f1ebdbefecdd +efebdfeeece0ecece2ecece2efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddf0eadcf1eeddf0ece0ebebdf +efeee9e8eae7eceeed95999afcfffffcfffffcfffffcfffffefffffefffbfffffbfffffb +fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb +fffff8fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7da +f4e9e5e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff2eadffbeae2ffeae7fae6e7f1e1e2f2e6e8f8f0eeefefe5dee7d2eafbd9 +ddf8cdcbefbfbbe5b5aedfb2a5d9b39ad1b28dcaa88ed5a988cfa38fc8a8ccf5e5def4f2 +eaeef7e6dbe9f7e5f3fbe4eef3dce2f5e2e4f8eeedf5f3f4ebf0f3cedbe1aebbc4a1a7b5 +a6a8b5989ba4eaebefebeae8f6f1ebe9e3d7fff8e8f2ebd9f2ebd9f1ebdbf1ebdbefebdf +eeece0ecece2ecece2efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefecddf0eadcf1eeddf0ece0ebebdfefeee9 +e8eae7eceeed95999afcfffffcfffffcfffffcfffffefffffefffbfffffbfffffbfffffd +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8 +fefffafbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5 +e8e9fbd2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff3e9dff9e5deffe6e2fae4e6f3e3e4f2e9eaf4f5f0ecf9e8dff6d9d5f9cbbdeab1 +abdf9fa4e0a09edea28ed19e81c69a75c79947ae7749b67f3e9a7557a08c6ea09dd9f7ff +eaf6ffedecfce7dfeac6bbc3aba2a5a19fa0a1a6a9a8b3b9a7b9c59eafbfafbccfa2aabf +848b9beaeef9eff0f4f4f3efd6d2c7f5efe1f2ebd9f2ebd8f1ecd9f1ebdbefebdfeeece0 +ecece2ecece2efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefecddf0eadcf1eeddf0ece0ebebdfefeee9e8eae7 +eceeed95999afcfffffcfffffcfffffcfffffefffffefffbfffffbfffffbfffffdffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffa +fbfffffcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fb +d2edff1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f3e9dff5e1d8f8e1dbf9e7e5f7edecededebdfebe1d9f3dad9ffd6a3d69d96d38d93d888 +9ce697a4f0a89febab91deaa84d8a667c8934cae7f3a8f70488c7f4a7b808daebf97a9bf +a6aec3c2c4d3bebec6c6cacdced6d9bccbd0a4b8c390aabb849cb48293af6d7b965e6a80 +969faedce3ebe8eae9efefe7f7f4e5f1ecd9f2ebd8f1ecd9f1ebdbefecddefebe0eeebe2 +eeebe2efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefecddf0eadcf1eeddf0ece0ebebdfefeee9e8eae7eceeed +95999afcfffffcfffffcfffffcfffffefffffefffbfffffbfffffbfffffdffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbffff +fcfffffffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff +1f48a2133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9 +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff2eadf +f5e4dafbeae2f7ece8ebeae6e0ede6d6f1e0c1edccabe4b173b9717cca748ade809bf093 +aafea9aeffb6a0eeb293d9a778ac868db79fa9ccc5bcd7e0c9dbf3d9e6ffd4ddfecbd2ef +a9b1c493a0a987999d7e9698728f95789aa693b7cda9cbe7b9d3f499adce7f90ac8594a9 +e4eef8e2e7eaf1f4ede7e5d8efecdbf1ecd9f2ebd9f1ebdbefecddefebe0eeebe2eeebe2 +efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefecddf0eadcf1eeddf0ece0ebebdfefeee9e8eae7eceeed95999a +fcfffffcfffffcfffffcfffffefffffefffbfffffbfffffbfffffdffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcffff +fffdfffffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2 +133abb001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebddf1e5d7 +fdf3e7f3f0e9dbe5dddcf3e9dffff1b6eec77bc2865fb26073ce6e8dea809ffc94afffa8 +b5ffb8adf9b8a8e4b1aacbacddefe1cbdadd9babbb8f9ebf8998bf8597bd647b9a8facbe +97b8c1b7dadcd3fbfbd8ffffd1fbffc4eeffb5dcfdb7d7fe95aed66980a08a9cb4e1eefe +e5eef3e8ede7efefe3efecdbf1ecd9f2ebd9f1ebdbf1ebddefebe0eeebe2eeebe2efebe0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddf0eadcf1eeddf0ece0ebebdfefeee9e8eae7eceeed95999afcffff +fcfffffcfffffcfffffefffffefffbfffffbfffffbfffffdffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdff +fffcfffffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb +001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddefe9d9f0eedf +e8f0e5dcf0e5d2f6e8bdf2d88bd0a358aa6857b65c67ca6080e47297f789a4fc98a8f8a3 +adf6afb9f3c0b2d5b5c9e4d586a2a390b0bf97bcd988b3d5a8d9f9c8ffffc8ffffc0fdff +c0fcfac1f9f8c0f2f9c8f5ffccf5ffc5e8ffb9daff99b6e2657fa48ba0bddeeefee7f2f8 +e2e7e3f0f2e7eeecddefecd9f1ecd9f1ebdbf1ebddefebe0eeebe2eeebe2efebe0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddf0eadcf1eeddf0ece0ebebdfefeee9e8eae7eceeed95999afcfffffcffff +fcfffffcfffffefffffefffbfffffbfffffbfffffdffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbfffff8fefffafbfffffcfffffffdfffffcff +fffefffbffff8a9c9ee0f0ededefe2efe7daf4e9e5e8e9fbd2edff1f48a2133abb001eae +00119b001dc8002fd32064f71a51b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4 +f1eae4f5e8dff5e9dbefebdfeceddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdbf6f1dde6e5d1e2ece3 +e8fff9c3ece47db7ab47918236916649b65d4dc04962d5527bea6781e8727ddc808de0ac +adeed68bb9afd9fcfe8fb0bfa6cee7a6dffc9fe4ffa1ebffa0edffaaf4ffb3fcffbfffff +bfffffb8f4febcf1ffbeebffb1ddffb0dcff95beec6c8ab07b8eacdfe7fae8ebf2ebece7 +ebebdfecedddeceddbeeeddbefecddf1ebdff1eae0f1eae0efebe0efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff0eadcf1eedff0ece0ebebdfefeee9e8eae5eceeed95999afcfffffcfffffcffff +fcfffffefffffefffdfffffbfffffbfffffdffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffdfffff8fefffafbfffffcfffffffdfffffcfffffeff +fbffff8a9c9ee0f0ededefe1efe7daf4e9e5e8e9fdd2edff1f48a4133abb001eae00119b +001cc80433d71c60f32057bedee7fff4ebe2edf0dfeaefdbeeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeeecdfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff1ecd9f7eed1ede7cfeef2f1e2f4fe +c5edf567a4b92e7aab1c7e8b28a35335bf3642d23246d4304dd43c5cd6736fd4cc80d2f7 +6faed1d1ffff82a5cfa1cef790dcfc87e2fd95f1ff96edffaaf2ffaff3ffabf9ffadfbff +b1f7ffb0efffaee8fca7e4ff98ddff97d4ff5d7da47d86a3ede4f5f4e5eaf4ebe2efedde +e8efdde5f0dfeaeee0ecece0f2e9e2f3e9e0f3e9ddf3e9ddf1ebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f0eadef1ede1f0ece0ebebe1efefe7e8eae5eceeeb959998fcfffffcfffffcfffffcffff +fefffffefffdfffffdfffffdffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffdfffffafefffbfbfffffcfffffffdfffffcfffffefffbffff +8a9c9ce0f1ebedefe1efe7daf4e9e5e8e9fdd2ecff1f48a4133abb001eae00119b001cc8 +0433d71d5ff32057bee0e6fff4ebe2eeefdfeaefdbeeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff2ebd9f8ecd2f0e8d3efefeddff2f9c6f1fa +619dc11f69c21272af1d9a6e24b4432bc4342fc92d37cb3545cc6e53c4d25fbdfb569fd4 +b1e9ff8aafe496c6f688deff7ee6ff8aeeff91e9ffa5eaffaaecffa2f3ffa1f7ffa5f2ff +a3ecfd9ee7f897e4fe8bdfff8ed6ff5d82ac7f85a5f4e3f5f9e3e6f7e9e0f0eddce7f0dd +e4f1dfe7efe2ecece4f2e9e2f5e8e0f5e9ddf3eadbf1ebddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0eade +f1ede1f0ece1ebebe1efefe7e8ebe4eceeeb959a96fcfffffcfffffcfffffcfffffeffff +fefffffffffdfffffdffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdfffffafefffbfbfffffcfffffffcfffffcfffffffdfbffff8a9d9b +e0f1e9edefe1efe8d8f4e9e7e8e9fdd2ecff1f47a6133abb001eae00119b001cc80433d7 +1d5ff32057bee0e6fff4ebe2eeefdfeaefdbeeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff2eaddf6e9d9f3eadbebede2def3ead1fcf5609dbc +1559c41168cf11849612976c15a45419ac4422b33e2cb36733a6b93a9dd83c8fbb89c8f1 +98c4f387bae585daf981e5fd86e6fe8de1fda0e1ffa3e2ff9aeaff97edff98eaff94e6fe +8ee2fa87e0fe82deff87d4ff618ab87b85a8f2e5f7f8e3e8f5e8dff0eddae7f0dbe5f0df +e8eee2ecece4f2e9e2f5e8e0f3e9ddf2eaddf1ebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0eadef1ede1 +f0ece1ebebe1efefe7e8ebe4eceeeb959a96fcfffffcfffffcfffffcfffffefffffeffff +fffffdfffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffdfffffafefffbfbfffffcfffffffcfffffcfffffffdfbffff8a9d9be0f1e9 +edefe1efe8d8f4e9e7e8e9fdd2ecff1f47a6133abb001eae00119b001cc80433d71d5ff3 +2057bee0e6fff4ebe2eeefdfeaefdbeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddf +ebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff2eadff3e5daf4eae0e8ebe0ddf3e7d8fff9659ebc0f51c1 +1063dd0c74b30a83940c8f810d9668109d4f169c5f1b9296228aad2b84a463a9cda7d8ff +7ab1d87ed5f17ee2fa80defa8bdbfc99d9ff9adaff8fe2ff8be6ff8ae5ff85e2ff80dffd +7adcff77daff7ed0ff6593c47686aaf1e8fdf7e4e8f4e7def0eddae8f0d9e7f0ddebede0 +eeebe4f2e9e2f3e8e2f2eadff1ebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0eadef1ede1f0ece1 +ebebe1efefe7e8ebe4eceeeb959a96fcfffffcfffffcfffffcfffffefffffefffffffffd +fffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffdfffffafefffbfbfffffcfffffffcfffffcfffffffdfbffff8a9d9be0f1e9edefe1 +efe8d8f4e9e7e8e9fdd2ecff1f47a6133abb001eae00119b001cc80433d71d5ff32057be +e0e6fff4ebe2eeefdfeaefdbeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff2eaddf4e7d7f5ebdfe7e9e4ddf0eed8ffff659bbd0d4cb50856d2 +0b6bc20a78b70c81b60c899d0a8d6d088c5b0b8a6c16887e1f7f8f448fafade0ff72acd4 +74cdeb74dcf775d6f684d8fd90d3ff90d4ff85ddff7fe1ff7cdfff78deff70dcff6ddaff +6ad4ff72caff689bd07184aceee9fff4e5eaf1e7ddf1efdaeaefd8e8f0dbecece0efebe2 +f2e9e4f2e9e2efebe0eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0eadef1ede1f0ece1ebebe1 +efefe7e8ebe4eceeeb959a96fcfffffcfffffcfffffcfffffefffffefffffffffdfffffd +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd +fffffafefffbfbfffffcfffffffcfffffcfffffffdfbffff8a9d9be0f1e9edefe1efe8d8 +f4e9e7e8e9fdd2ecff1f47a6133abb001eae00119b001cc80433d71d5ff32057bee0e6ff +f4ebe2eeefdfeaefdbeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff1ebddf6ebd9f5ebdfebebebdeedf4d4f7fb6799ba124da90048b9025dba +0166be056eca0577b5007d79007b4f007e40067e5117757d2b759ca6daff70aad868c6e8 +66d3f268d0f577d4ff82ceff82cfff76d6ff70dbff6fdaff6cd8ff66d7ff64d4ff5ecbff +68c4ff6ba2da6b82acedebfff1e5e9efe7dcf2f0dbebefd8ebeed9efebdff1eae2f2e9e4 +f1eae4eeebe2ecece0eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff0eadef1ede1f0ece1ebebe1efefe7 +e8ebe4eceeeb959a96fcfffffcfffffcfffffcfffffefffffefffffffffdfffffdffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffa +fefffbfbfffffcfffffffcfffffcfffffffdfbffff8a9d9be0f1e9edefe1efe8d8f4e9e7 +e8e9fdd2ecff1f47a6133abb001eae00119b001cc80433d71d5ff32057bee0e6fff4ebe2 +eeefdfeaefdbeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff1ebdbf6ebd7f2e9daeeedf2e1edf9d2f0f873a0bd245da40247a20052a50055ad +0058c20065b4006e7900704200731b00712a0b656d195b8f99caff70abe35dbfec55ccf4 +56cbf663cffe6dcbff6ecbff64d2ff60d4ff63d3ff62d0ff60ceff5dccff56c3ff60bbff +6da5de6780a9ebecffefe4e8ede7d9f3f1daeceed6eceed9f1ebdff2e9e2f3e8e4f1eae4 +ebece4eaede2eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff0eadef1ede1f0ece1ebebe1efefe7e8ebe4 +eceeeb959a96fcfffffcfffffcfffffcfffffefffffefffffffffdfffffdfefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffdfffffafefffb +fbfffffcfffffffcfffffcfffffffdfbffff8a9d9be0f1e9edefe1efe8d8f4e9e7e8e9fd +d2ecff1f47a6133abb001eae00119b001cc80433d71d5ff32057bee0e6fff4ebe2eeefdf +eaefdbeeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f1ebddf4e9d7eee6d9f2f0f1e6f1f7d7f0f482abbd3b6ea7104e9b07509f004ea4004eb8 +015eae026b7e006e4c006e1e00672a06546a1148898fb9ff71acee55bdf248c8f747c9fa +51cdff5ec8ff5fc9ff57cfff56cfff5ccbff5fc8ff5ec6fd5dc4ff56bdff5fb6fb72a6df +667fa7e9ecffeee5e6ede7d9f3f1daeeeed6eeedd9f2eadff5e8e2f3e8e6f1e9e6eaede4 +e8eee2ecece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff0eadef1ede1f0ece1ebebe1efefe7e8ebe4eceeeb +959a96fcfffffcfffffcfffffcfffffefffffefffffffffdfffffdfefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffdfffffafefffbfbffff +fcfffffffcfffffcfffffffdfbffff8a9d9be0f1e9edefe1efe8d8f4e9e7e8e9fdd2ecff +1f47a6133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dc +eeeddbefebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdf +f3e9ddeae2d7edede3eaf4ebdaf2e5caedf37ea8d80d3f86074592004396004aa3005095 +00526a005c4f0369420962500b48771c45955373c881b8ff4fb8f943caff43d0ff40cbff +55d0ff46bcf943c2f94cc8fe55bff963c1fe67c0fc56abeb64c0ff57a5e56998cc6d83a8 +edf0ffe1dcd9edead9f2f2daeceed8efecd9f3e9dff6e7e2f5e7e6f1e9e6e8eee4e7efe2 +ecece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeee8dcefebdfe6e2d7f6f6ecebebe3eaede6eceeeb909591 +fcfffffcfffffcfffffcfffffefffffefffffffffdfffffdfefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffdfffffafefffbfbfffffcffff +fffcfffffcfffffffdfbffff849795e9faf2e7e9dbf3ecdcfcf1efe0e1f5d2ecff1d45a4 +133abb001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddb +efebdfefeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdffaf0e4 +eee6d9f0eedfebf2e2dff1e1defafbb7d9fe6c94d10b3c7f073c88033e8e003b7f00456c +0e5c700f5f6a00415b133e8217328b4a61be91c1ff3aa1e62bb2ec28b9f235c2fa38b6f3 +46befb52cfff57cbff52b2ef56a5e764a9ec69aef1539edf75b7f16b91be647593dbdbe7 +fffefaf2f1dfe6e8d0eceed8efecdbf5e8e0f8e6e4f6e7e4f1eae4e8eee2e7efe0eceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff1ebdff1ede1e7e3d8f0f0e6e8e8e0ecefe8edefec959a96fcffff +fcfffffcfffffcfffffefffffefffffffffdfffffdfefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeffff +fefffffefffffefffffefffffefffffefffffefffdfffffafefffbfbfffffcfffffffcff +fffcfffffffdfbffff889b99eafbf3e9ebddf0e9d9f7eceae1e2f6d5efff2048a7133abb +001eae00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdf +efeae4f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdbf7f1dbede7d1 +efecd9e9eddedeeadee7f9fbe1f9ffc0ddff5679af2d549517418d18469414468d0e4484 +1248881a478b2340902839914f5cb894baff3b9ade47c5ff3bc3fd34bbf542b5f648b5f6 +3fafee43a9e75aa9eb6ca8ee7aacf386b7fa619cd65488b77793b8dce7fdfaf7feede6de +d9d8c4fbffe8ebeed9efebdff5e8e2f8e6e4f6e7e4f2e9e2eaeedfe8efddeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefe9ddf3efe3ebe7dcefefe5e8e8e0edf0e9e6e8e5919692fbfffefbfffe +fbfffefbfffefdfffefdfffefefefcfefefcfdfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffefbfffe +fbfffefbfffefbfffefbfffefbfffefdfffcfefff9fdfffafafffffbfefffffbfffffbfe +fffefcfafffe849795e3f4eceaecdef0e9d9f5eae8e4e5f9d6f0ff1e46a5133abb001eae +00119b001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4 +f1eae4f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdbf2ecd2ece6ccefecd9 +edede1e1e6e0e3edefe5f5ffdbefffd2eaff809bca425e9f3f5aa74665b74363b83959ae +324ea14d60ad515cab6368ba85a0ef3f90cf35a4dc289fd734a6e246a5e754abf04fa8ea +5daef082bcff82aef76d8dd86685c8668ec1c4e8ffd4e4fedfe1f0f5ecedfffef3e2e1cd +e9edd6ebeeddeeece0f5e7e6f9e5e6f8e6e4f2e9e0ebeedbe8f0dbecedddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfebe5d9f2eee2efebe0f0f0e6eaeae2edf0e9dddfdc909591fcfffffcfffffcffff +fcfffffefffffefffffffffdfefffdfefffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcfffffcffff +fcfffffcfffffcfffffcfffffcfffdfffffafefffbfbfffffcfffffffcfffffcfffffffd +fbffff849795daebe3eaecdef3ecdcf6ebe9e9eafed5efff1a42a1133abb001eae00119b +001bc70837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4 +f5e8dff3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff1ecd9f5f0d3f1ebd1f3eddff3f0eb +ebe9eae4e8e9e4ede8e2eeece1eff8e6f5ffcfdeff8c9bd64f5da64959a75a6ab5596aaf +4c5c974d58905e5e9e798bc978b7ec4da5d53893c854a6e25894da82b8ff8ac6ff78aef8 +6388d64a63b34c5dad6b7abfe9ffffd7ebffe7eafbfcf5fce5d8d2ede4d5f5f4dfebf0da +eaeedfecece4f5e7e7f9e5e7f9e5e4f3e9dfeceed9eaefd8eeecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eee8dcf1ede1efebe0ecece2eaeae2eef1eae1e3e0abb0ac919594919594919594919594 +939594939594949492939592939594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +919594919594919594919594919594919594919594919594919594919594919594919594 +91959491959491959491969294958f93959090959b91949b9891989a9194959492909694 +9fb2b0deefe7eceee0f3ecdcf3e8e6e9eafed4eeff1d45a4133abb001eae00119b001bc7 +0837db1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8df +f3eadbeceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefecddf4eddbf2ebd9efe9dbf0e9dfefeae4 +ebebe3eaecdeecf0e2e1e6e0e8edf1ebf1fddfe5fdd7dcffe2e8ffe7edffd4dfffd3e3ff +eefbffe3e0ff9199c86596bf4d90ba75b4e7a9ddffa6c4ff8ca3f15b7bc84a67b55b6dbf +6670c56368bc6065a9cdd7fae7edfbf6ecf5f2e2e2fcebe1f6ebd9e8ead4e9f1dce8eee2 +ecebe6f5e6e9f9e4e9f9e5e4f5e8dfeceed8ebefd6eeeddbefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff6f0e4 +efebdfece8dde7e7dde8e8e0eff2ebedefecd6dbd7ebefeeebefeeebefeeebefeeedefee +edefeeeeeeecedefecebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefeeebefee +ebefeeebefeeebf0ecedf0e9edefeaeaeff5ebeef5f2ebf2f4ebeeefeeeceaf0eec9dcda +e9faf2edefe1f1eadaeee3e1e6e7fbd3edff254dac133abb001eae00119b001bc70837db +1d5ff31e55bce2e8fff4ebe2e9eadaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadb +eceddfebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebe2efe4eaf2e8e9ede6d4ebe5cbf0ecd1f2eed5 +efecd9f2efe0f1ede4e6e4d7f2f2d6ffffe4f5f8e5e4e7e0e5e5f1e6edfddff3fed6e8f6 +c9c5de9da0bf8baecc98c6e891b7e67086c09c9ce69a95e78d94e57b83d66668bf6360b9 +6f6cc57776ba9f9ebda9a4abe8d5d7fff9f3f8e5d6f8ecd6f9fbe5dde6d1e7efe2ebece7 +f3e7ebf9e4e9f9e5e4f6e8ddeeeed6ebefd4eeeddbefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff7f1e5ebe7db +ece8ddeaeae0ebebe3ecefe8eceeebedf2eee7ebeae7ebeae7ebeae7ebeae9ebeae9ebea +eaeae8e9ebe8e7ebeae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6eceae6ecea +e6eceae7ece8e9ece5e9ebe6e6ebf1e7eaf1eee7eef0e7eaebeae8e6eceae0f3f1e8f9f1 +eaecdef3ecdcf0e5e3e6e7fbcfe9ff264ead133abb001eae00119b001bc70837db1c60f3 +1e55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f5e8dff3eadbeeecdf +ebeddfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefeae4ece2ebf6edf0f3ecdaeeeacdf5f0d2f5f1d6f1ead7 +f2ecdef6ede4ece7d4ebe9c2ebedbee8e9c1ededd1f3f0e7e7ebeae2f2f2b9c8cdc7c5d2 +d4d3e58398a97995aaaabfdcd8dfffd5cbffbcaeeca3a1e29091d47975c17470bd7471c0 +6765a6b1adce98909fab9ba5f1dfdff2e1d9f5ecddecefdcf3fae8e8eee0ebece4f2e8e6 +f6e6e6f8e6e2f5e9ddefedd8eeedd8efecddefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff2ece0e7e3d7efebe0 +f3f1e5f0f0e6e9eae2e3e4deeef0ebebede8ebede8ebede8ebede8ecede8ecede8edece8 +ecede8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8ebede8ebede8ebede8ebedea +ebede8ebede8ebede8ebede8ebede8ebede8ebede8ebede8e9eee8e9eee8e9eee8e9eee8 +e9eee8e9eee8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8ebede8ebede8 +ebede8ebede8ebede8ebede8ebede8ebede8ebede8ebede8ebede8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8e9eee8ebede8 +e9eee8ebede8e9eee8ebede8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8 +e9eee8e9eee8e9eee8e9eeeae9eeeae9eeeae9eeeae9eeeae9eeeae9eee8e9eee8e9eee8 +e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8 +e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8 +e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8 +e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8 +e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8e9eee8 +e9eee7ebeee5ebeee7ebeceeecebf0f2e9eef2e9eaedece7e8efe7e2f1ece1eee5e8e6d9 +f8f0e3f7eee7e8ebfccbe5ff2249a8133abd001eae00119b001dc8002fd32064f71a51b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f5e8dff5e9dbefebdfeceddf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebe0efeae4efebe2f1ebddefecd9f1ecd9efecdbf1ebddefebdf +f1ebdfefecddefedd8efedd6efedd8efecdbefebe0ecebe7babfc3bcc3cbf1f1f9f8fbff +f6ffffe9f7f7f7ffffe5edf0e4e6f2bbbccea3a7c2aaaed17475a37777ad8383bf6b6aa4 +b8b6e59391b89e99b9938ea4ebe8f1f2f1efe9ebe0edefe1ebeeddeceddbf1ebddf2eadd +f2eadff2eadff1ebdff1ebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeece0eeece0eeece0eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2 +eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2 +eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2 +eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2 +eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2 +eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2 +eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2eeebe2ede9e0f5f1e8f1ece6ece8df +f0ece3eeeae1ece9e0f5f2e9efece3efece3efede1edede1edede1edede1edede1edede1 +edede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1efede1edede1 +efede1edede1efede1edede1edeee0edeee0edeee0edeee0edede1efede1efede1efede1 +efece3efece3f0ece3f0ece3f0ece3f0ece3f0ece3f0ece3efece3edede3efece3edede3 +efece3edede3efece3edede3f4f1e8e8e8def4f1e8e3e3d9e8e5dcf7f7edece9e0efefe5 +eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2eeebe2ecece2 +eeebe2ecece2eeebe2ecece2ecece0ecece0ecece0ecece0ecece0ecece0ecece2ecece2 +ecece2e4e4daefefe7ebebe3edede5dbdbd3fcfcf4ecece4edede3edede1edede1edede1 +edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1 +edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1 +edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1 +edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1 +edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1edede1eceee1 +e9eddfeaeee0f3efe6f0e7e2e8dcdeeee6e4f1f3e5ebf2e0e6eee1f6f9eee9e1d6f6eee1 +f1efe0e0eaf3d9f3ff2144a81439bd001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeebe6bebec6dcdeeae6e9f0fafefff4f9f5 +fcfffaebf3e8e7efe4ecf3ecd1d7d79ba2acc6cbdf898cad7a7ca57f81b26c6ea1a3a3d7 +b0b1e1a09fc7a8a9c7e4e5f7f5f6fbd7d8d2eef0e2eeedd9eeedd8efedd8efecd9f1ebdd +f1eae0f2e9e2f1eae2f1eae0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff3eae1f4ebe2f1e8dff1e8dff5ede2 +f2eadfeee8dcf3ede1eee8dceee8dcece9daece9daebe9daebe9daebe9daebe9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9daece9da +ece9daece9daece9daebe9daebead8ebead8ebead8ece9daece9daeee8daeee8daeee8dc +eee8dcefe7dcefe7dcefe7dcefe7dcefe7dceee8dceee8dcece8dcece8dcece8dcece8dc +ece8dcece8dcece8dcece8dce4e0d4f3efe3f1ede1f1ede1f3efe3e2ded2eae6daefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdffcfaee +edebdfeae8dcf3f1e5fbf8efeae7dee6e3dae6e4d8ebe9dcebe9daebe9dcebe9daebe9dc +ebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dc +ebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dc +ebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dc +ebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dc +ebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dcebe9daebe9dce9eadcedf4e4 +e7ebdaefe7dafcefe6fff1f4f5edebe7ead7e1e9d1d9ddceeae8dcf0e6dcf4ecdfeceddb +dce9efd8f2ff2344ab1439bd001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeebe6c4c3cbf1f0feededf7f1f2f7f0f4f5fafefd +e3e8e4f2f6f5d5daddced2db898f9fd2d6efa1a4c78788b48a8abc8686b8afaddeb1b0da +8e8daf85859ff1f0feecedf1e9eae4f0f2e4eeedd9eeedd8efedd8efecd9f1ebddf1eae0 +f2e9e2f1eae2f1eae0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff6ede4f0e7deeee5dcf3eae1f6f0e4f1ebdf +eee8dcf1ebdff4f0e4f4f0e4f4f0e4f4f0e4f3f1e2f3f1e2f3f1e2f3f1e2f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e2f3f1e2f3f1e2f3f1e2f3f1e2f4f1e2f4f1e2f4f0e4f4f0e4f6f0e4f6f0e4 +f6f0e4f6f0e4f7efe4f7efe4f7eee5f6efe5f6f0e4f4f0e4f4f0e4f4f0e4f4f0e4f4f0e4 +f4f0e4f4f0e4f4f0e4eae6daf4f0e4f6f2e6f4f0e4f1ede1ebe7dbfaf6eaefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdfdfddd1f4f2e6 +f0eee2e9e7dbe3e0d7ece9e0eeebe2f9f6edf1efe3f1efe2f1efe3f1efe2f1efe3f1efe2 +f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2 +f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2 +f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2 +f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2 +f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3f1efe2f1efe3eff0e2e4ebdbecf0df +f2eaddf4e7def9eaedf2eae8eaeddaeff7dffefff3f2f0e4f4eae0e9e1d4edeedce2eff5 +daf4ff2041a81439bd001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeebe6b8b7bfd4d3e1f0f0fce9e9f3fbfbffe1e4e9e3e6eb +e9ecf3e3e5f1dde0efa6a8bfc8cce9a6a8ce898ab68384b48e8fbda4a3cda8a8cc9797b3 +a9aabef3f3fddddfdeeaebe3edeedeeeedd9eeedd8efedd8efecd9f1ebddf1eae0f2e9e4 +f1eae2efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff6ede4ede4dbefe6ddf6ede4f3ede1f0eadef2ece0 +f3ede1ece8dcece8dcece8dcece8dcebe9dcebe9daebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dcebe9dc +ebe9dcebe9dcebe9daebe9dcebe9daece8dcece8dcece8dcece8dceee8dceee8dceee8dc +eee8dcefe7dcefe7dcefe6ddeee7ddeee8dcece8dcece8dcece8dcece8dcece8dcece8dc +ece8dcede9ddeae6daeeeadeeeeadeebe7dbebe7dbece8dcf5f1e5efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdff3f1e5f7f5e9e6e4d8 +eae8dceeebe2f1eee5f9f6ede7e4dbeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeaeadee1e8d8f4f8e7f6eee1 +eaddd4f1e2e5f8f0eeeff2dfeaf2dadbdfd0e1dfd3fff6ecf7efe2f1f2e0d6e3e9cfe9ff +2a4bb21439bd001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9 +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeebe4b4b1b8aba9b6d2d0dee5e5f1f3f2ffe0dfede7e6f4d6d7e9 +c6c7dbc8cae1c8c9e5bcbddcb0b0d69493bd7877a37f7ea6b9b8daa7a7c37d7b90e2e1ef +d8d7dcf9faf5e8e8dce8e9d9eeedd9eeedd8efecd9efecdbf1ebdff1eae0f1eae4f1eae4 +efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff5ede2ece4d9f2ece0f6f0e4ede7dbeee8dcf3efe3efebdf +efebe0efebe0eeece0eeece0eeece0eeecdfeeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeecdfeeece0eeecdfeeece0eeece0efebe0efebe0efebe0efebe0f1eae0f1eae0 +f1eae0f1eae0f2e9e0f1eae0f1ebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff6f2e6f6f2e6f5f1e5f4f0e4f3efe3f2eee2e9e5d9efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdff2f0e4eae8dce9e7dbfffff3 +fcf9f0dedbd2f3f0e7ece9e0edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1edeae1ebebdfeaf1e1edf1e0efe7daf1e4db +fcedf0fcf4f2ebeedbdce4ccf6faebf6f4e8f1e7dde9e1d4f2f3e1deebf1cfe9ff2849b0 +1439bd001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeebe4dddbdeb5b3beaaa8b3cfcddacac8d6e6e5f5e8e6fbdcdaf0e3e1f9 +ceceeac9c8e78b8cab8d8daf9b9bbfa3a3c7bbbadc9898b2807f91878694eeeff4dbdbdb +f8f9f1f4f5e7edeedceeedd9eeedd8efecd9efecdbf1ebdff1eae2f1eae4f1eae4efebe0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff2ece0ede5daf6f0e4f6f0e4e8e2d6f0eadef2eee2dedaceede9de +ede9deeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0eceadeece9e0 +eceadeece9e0eceadeeceadeeceadeede9deede9deede9deede9deefe8deefe8deefe8de +efe8def0e7deefe8deede9ddede9ddede9ddede9ddede9ddede9ddede9ddede9ddf0ece0 +efebdfe1ddd1e9e5d9f2eee2f3efe3f9f5e9efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdd +eeecddeeecddeeecddeeecddeeecddeeecdfeeecdfebe9ddefede1e7e5d9dedcd0e6e3da +f7f4ebe4e1d8f4f1e8edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1ebebe1e9efe1dee2d1ede5d8f9ece3eedfe2 +e5dddbecefdcf3fbe3cfd3c4fffff4e9dfd5e5ddd0f0f1dfe7f4fad2ecff2445ac1439bd +001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeebe2f9f8f6e0dee1b6b3bab1b0b8a9a7b4ccc9dacecbe0cccae0c5c3dbc9c9e3 +d5d5f1c0c0dcb8b8d4b4b4d0a0a0bc8f8fa7757484878590e3e2e8fffffff5f4efd9d9cf +edebdcf3f2e0eeedd9eeedd9efecdbefecddf1eae0f1eae2f1eae4f1eae4efebe0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff2ece0ede7dbf7f1e5f4eee2e5e1d5f2eee2ece8ddc1bdb2aeaca0aeaca0 +aeaba2aeaba2acaca2acaca2acaca2acaca2acaca2acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2acaca4acaca2 +acaca4acaca2aeaba2aeaba2aeaba2aeaba2afaba2afaba2afaba0afaba0b1aaa0b1aaa0 +b1aaa0b1aaa0afab9fafab9fafab9fafab9fafab9fafab9fafab9fafab9fb5b1a5a9a599 +a19d91cecabeebe7dbe6e2d6efebdfece8dcefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddeeecdd +eeecddeeecddeeecddeeecddeeecdfeeecdfe7e5d9f5f3e7f8f6eaeceadef6f3eae8e5dc +0300000b0800050200050200050200050200050200050200050200050200050200050200 +050200050200050200050200050200050200050200050200050200050200050200050200 +050200050200050200050200050200050200050200050200050200050200050200050200 +050200050200050200050200050200050200050200050200050200050200050200050200 +050200050200050200050200050200050200050200050200050200050200050200050200 +050200050200050200050200050200030300050b00000300140c00180b020a0000060000 +0c0f000005000e1203dfddd1fdf3e9fffbeee8e9d7d8e5ebcce6ff294ab11439bd001eae +00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebe0e6e3dcf5f4f0e2e0e1a7a5a8aeabb4a2a0ada19eaf9d9aaf9793aaa09eb4918fa5 +9e9fb39293a7999aac9799a881808ef7f6fee3e3e5edebece3e2dee6e6def7f7ebe8e6d7 +ebead8eeedd9eeeddbefecdbefecddf1eae0f1eae2f1e9e6f1eae4efebe0efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff2ece0ede7dbf6f0e4f2ece0e7e3d7f6f2e6e6e2d7aaa69b706e62706e62706d64 +706d646e6e646e6e646e6e646e6e666e6e666e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d686e6e666e6d68 +6e6e66706d66706d64706d66706d64716d64716d64716d64716d62736c62736c62736c62 +736c62716d61716d61716d61716d61716d61716d61716d61716d61736f636d695d827e72 +dedacefffff3f7f3e7f1ede1ece8dcefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecdd +eeecddeeecddeeecddeeecdfeeecdff4f2e6e8e6daebe9ddeceadeece9e0f2efe60a0700 +f3f0e7fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff6fbfff3f4f8e7fffef1fff8effff1f4fffdfbedf0dd +707860000300f0eee2f0e6dcefe7dadedfcdebf8fed9f3ff1c3da41439bd001eae00119b +001ec90031d42165f81952b9e3ecfff0e7def0f3e2e9eedaeeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f0ece0ede9ddefebdfeeeadeebe7dbf7f3e7e5e1d5fbf7ebf1ede1f0ece0e1ddd1f7f3e7 +f7f3e7e7e3d7f8f4e8ebe7dbf3efe3e5e1d5f9f5e9e1ddd1f0ece0f7f3e7eae6daefebdf +ebe9ddf1efe3ece9e2f1edeaf1ecf09592998986917a788577758382808e807e8b80808c +84848c86878cdbdce0f5f6f8f3f1f2deddd9fefbf6e5e2dbf4f2e6eceadddddbccf7f6e4 +edead9f4f1e0e9e6d7eae6dae7e3d8fffdf4eee6e3f4ede7f0ece1e9e5d9e5e1d5f5f1e5 +f2eee2efebdffcf8ece9e5d9efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfece8dcf5f1e5ebe7db +f4f0e4ede9ddf2eee2e8e4d8f4f0e4eae6daf1ede1f3efe3e6e2d6f4f0e4f2eee2f4f0e4 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f1ede1ece8dcf3efe3ece8dcefebe0f0ece1f0eee2aba99d7a776efaf7eefffff8fcfcf4 +fffff8fffff8ebece4fffffafcfbf6fbfaf5fffffbfffffafffffbf0efeafffefafffffa +faf9f5fffffaf9f8f4f2f1ecfbfaf6fffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffafffffbfffffa +fffffafffff8fffffafffff8fffdf6fffff6f6f2e9f9f5ecfaf6ebeae6dbf5f1e6f8f4e9 +f7f3e7f1ede1efebdffcf8ecede9ddfffdf1f4f0e4f5f1e5fffff3d0ccc07c786cf7f3e7 +fffdf1f2eee2f1ede1f3efe3efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecdd +eeecddeeecddeeecdfeeecdfedebdfeeece0eeece0edebdfeeebe2edeae1050200fffef5 +f5f2ebf3f0e9f1eee7f1eee7f2efe8f3f0e9f2efe8f1eee7f3f0e9f3f0e9f3f0e9f3f0e9 +f3f0e9f3f0e9f3f0e9f3f0e9f0ede6faf7f0f0ede6f5f2ebf7f4edf1eee7f0ede6f9f6ef +eae7e0fffef7edeae3edeae3f0ede6f4f1eaf2efe8f6f3ecf5f2ebf6f3ecf6f3ecf0ede6 +f0ede6f1eee7f5f2ebf5f2ebe6e3dcfffff8f0ede6f1eee7f6f3ecf7f4eddddad3fffef7 +f3f0e9f3f0e9f3f0e9f3f0e9f3f0e9f3f0e9f3f0e9f3f0e9f3f0e9f3f0e9f3f0e9f3f0e9 +f3f0e9f3f0e9f3f0e9f1f1e7ebf1e3f0f4e3f5ede0faede4f7e8ebf8f0eea9ac99707860 +000400eeece0f2e8def3ebdeeaebd9e4f1f7cee8ff2546ad1439bd001eae00119b001ec9 +0031d42165f81952b9e3ecfff0e7def0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeae6da +f2eee2f8f4e8e1ddd1f2eee2ebe7dbf4f0e4e3dfd3f2eee2ebe7dbfffff3d9d5c9e5e1d5 +fbf7ebdfdbcfeeeadef4f0e4f2eee2e7e3d7f5f1e5f3efe3e7e3d7fffcf0ebe7dbf0eedf +edebdceeecdff9f6edefece7ede9e8f0ebeff2f0f5e9e6edf5f4f9e7e6ebe4e4e6e4e4e4 +e1e3e0e5e7e2f0f1ebe2dfdaf4f1eaeeebe2eceadef5f3e6f4f2e5faf8e9dfddcee8e5d6 +f5f2e3e9e5d9ede9defffff6d5d1c8ece5dff4ede7f0ece1fefaeef6f2e6e9e5d9e6e2d6 +ebe7dbf3efe3f6f2e6efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfece8dcf3efe3e8e4d8faf6eaece8dc +f0ece0f5f1e5f8f4e8f2eee2e3dfd3eeeadef3efe3ebe7dbf2eee2e6e2d6e2ded2efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ede1 +ece8dcf3efe3ece8dcefebe0f0ece1f0eee2aba99d646158fffff6fffff8fdfdf5fcfcf4 +fdfcf7fffffafffffafffffbfffffbf3f2eefffffbfffffbf4f3effffffbe3e2defffffb +f0efebfffffbfffffbfffffbfffffbfaf9f5f9f8f4fffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffb +fffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffbfffffdfffffbfffffb +fffffafffffafffffafffef9faf7f0f7f2ecfffef5fcf8effffff4fffff4f7f3e8fefaee +fffff3fffff3fffff3fffdf1fdf9edfffff3fffef2f7f3e7c0bcb0726e62f3efe3fffcf0 +f2eee2f0ece0f2eee2efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecdd +eeecddeeecdfeeecdfedebdfeeece0eeece0edebdfeeebe2edeae1050200fffef5f3f0e9 +f1eee7efece5efece5f0ede6f1eee7f0ede6efece5efece5efece5efece5efece5efece5 +efece5efece5efece5e9e6dff2efe8ece9e2e9e6dff3f0e9f4f1eaebe8e1ece9e2f6f3ec +dfdcd5f7f4edfffef7f9f6efeae7e0e3e0d9f5f2ebe1ded7e9e6dfeeebe4fffff8f2efe8 +eeebe4e5e2dbf2efe8f7f4eddbd8d1edeae3ece9e2ece9e2ebe8e1fefbf4e1ded7efece5 +efece5efece5efece5efece5efece5efece5efece5efece5efece5efece5efece5efece5 +efece5efece5edede3e9efe1eef2e1f3ebdef8ebe2f5e6e9f6eeeca7aa976e765e000400 +eeece0f2e8def3ebdeeaebd9e4f1f7cee8ff2546ad1439bd001eae00119b001ec90031d4 +2165f81952b9e3ecfff0e7def0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0ece0f2eee2 +ece8dcfcf8ecf9f5e9e9e5d9f4f0e4f7f3e7dad6cafcf8ecede9ddf5f1e5fffdf1dcd8cc +faf6eaf6f2e6e5e1d5ebe7dbf4f0e4f1ede1f2eee2ede9ddeae6dae8e5d6f1eedde4e1d0 +fcf9eaede9ddeeeae1f1eee7f4f1ece7e6e1fdfcf8d3d2cef4f3eff0f1ebf5f6eefffff6 +eaece1e9ebe0f7f4ebe6e2d7eeeadff8f4e8eae6dae2ded2e4e0d4f4f0e4fdf9ede5e1d5 +f7f3e8f0ece1e3dfd6fbf7eef1ece6eeeae1e5e1d6e6e2d6e7e3d7ede9ddfdf9edf1ede1 +ddd9cdf2eee2efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfebe7dbfaf6eae3dfd3e3dfd3eae6daefebdf +eeeadeebe7dbebe7dbf8f4e8f1ede1f5f1e5e7e3d7ece8dcf1ede1fffdf1efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1eedfece9da +f3efe3ece8dceeece0efede1f0ede4aba89f797971fffff8e9e8e3fffffafffffafffffb +f8f9f4f3f4effffffdf1f1effffffdfffffdf0f0eefffffdfefefcfffffdfafaf8fffffd +f5f5f3fcfcfaf4f4f2fefefcfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffffffffdfffffdfffffb +fffffbfffffafffffaf3f0e9f3f0e9fffff6e5e1d8f0ece3ede9def3efe4ede9ddf5f1e5 +e0dcd0e5e1d5f3efe3ebe7dbf7f3e7f1ede1e9e5d9b4b0a46b675bf2eee2fffef2f2eee2 +ede9ddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecdd +eeecdfeeecdfedebdfeeece0eeece0edebdfeeebe2edeae1050200fffef5f1eee5efece3 +edeae1edeae1eeebe2eeebe2eeebe2edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1edeae1efece3edeae1efece3ebe8dff4f1e8edeae1e8e5dcf8f5ecece9e0edeae1 +e5e2d9efece3d1cec5fffcf3fcf9f0dddad1f8f5eceeebe2eeebe2d4d1c8efece3efece3 +faf7eee5e2d9e4e1d8f5f2e9f6f3eaf3f0e7edeae1eae7deebe8dffcf9f0edeae1edeae1 +edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1edeae1 +edeae1ebebe1e7eddfebefdef1e9dcf6e9e0f3e4e7f4eceaa5a8956c745c000400eeece0 +f2e8def3ebdeeaebd9e4f1f7cee8ff2546ad1439bd001eae00119b001ec90031d42165f8 +1952b9e3ecfff0e7def0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff8f4e8e4e0d4f3efe3 +e0dcd0e9e5d9f4f0e4e7e3d7f5f1e5fffff3e5e1d5e9e5d9eae6dadcd8ccf8f4e8f9f5e9 +e0dcd0f4f0e4e2ded2f7f3e7ebe7dbe4e0d4f2eee2efebdfefecdde6e3d4ffffeff3f0df +dfdccde4e0d4f1ede2eeeadfebe9ddeae7deeeeee4f2f2e6f3f3e7d4d4c8dbddd0f0f2e5 +edede1f1ede2e8e4d9f8f4e8ebe7dbe7e3d7ece8ddf7f3e8f4f0e5f1ede2dad6cbf0ece3 +ede9e0f3efe6e9e5dcf6f1ebeeeae1fffcf1eeeadeefebdfede9ddf2eee2f1ede1e4e0d4 +f3efe3efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfe4e0d4efebdffffff3e9e5d9f1ede1ece8dcfaf6ea +ebe7dbf5f1e5eeeadee5e1d5f1ede1e4e0d4f9f5e9ede9dddbd7cbefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1eedfece9daf3efe3 +ece8dceeece0efede1f0ede4aba89f6f6f67fcfcf4fffffaf7f8f2fefffaf6f7f2fffffb +fffffdfbfbf9fffffdfffffff3f3f1fffffffffffdf9f9f9f3f3f1ffffffededebfefefe +fffffdfffffffffffdf5f5f5fffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdffffff +fffffdfffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffdfffffd +fffffbfffffaf8f5f0f5f2ebfffff8e7e3daf7f3eae4e0d5f9f5eaebe7dbf5f1e5ebe7db +f4f0e4f8f4e8f8f4e8e6e2d6e7e3d7ebe7dbb5b1a56c685cf5f1e5fffff3f1ede1ece8dc +eeeadeefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdf +eeecdfedebdfeeece0eeece0edebdfeeebe2edeae1050200fffef5f0ede4eeebe2ece9e0 +ece9e0edeae1eeebe2edeae1ece9e0efece3efece3efece3efece3efece3efece3efece3 +efece3f3f0e7e7e4dbf4f1e8f4f1e8f6f3eadfdcd3e4e1d8f5f2e9ebe8dffffdf4e1ded5 +e7e4dbfffff6e1ded5ebe8dff0ede4e0ddd4ece9e0fffef5eae7def3f0e7e6e3daf3f0e7 +e8e5dceeebe2eeebe2e6e3daefece3e9e6ddf2efe6eae7deeae7deefece3efece3efece3 +efece3efece3efece3efece3efece3efece3efece3efece3efece3efece3efece3efece3 +edede1e6edddebefdef1e9dcf5e8dff2e3e6f4eceaa4a7946c745c000400eeece0f2e8de +f3ebdeeaebd9e4f1f7cee8ff2546ad1439bd001eae00119b001ec90031d42165f81952b9 +e3ecfff0e7def0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfe7e3d7f6f2e60c0800f6f2e6 +f8f4e8e6e2d6fffff3e3dfd3040000e8e4d8f7f3e7f4f0e4f7f3e7f1ede1e4e0d4f6f2e6 +f8f4e8f6f2e6dfdbcf141004fbf7ebdad6caf4f0e4e8e4d8090300e5dfd3eee8dcfffff1 +ebe5d9f9f6e7e6e3d4f9f7e8e9e7d8f9f7e8e0ded1e3e4d6fefef2f1f1e5eeeee2ebebdf +f6f2e7f3ede1f2ebe1f0e9dffffcf2e6dfd7faf3ebdfd8d0e8e4dbfffff6f9f4eee1ddd4 +f5f1e8060200d6d2c9f6f2e9e7e3d8e7e3d7f8f4e8f0ece0e1ddd1f3efe3faf6eae8e4d8 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdffcf8ecdedacee7e3d7f6f2e6e6e2d6e9e5d9eae6daefebdf +f1ede1e6e2d6f5f1e5fbf7ebe3dfd3f2eee2fffdf1efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0eedfebe9daf2f0e1ebe9dc +eeece0efede1eeeee4a9a99f7c7c74f7f7effffffafbfcf7fbfbf9fffffdeef0edf8faf9 +fffffffffffffffffff4f4f4fffffffffffff4f4f6fffffffdfdfffffffff9f9fbffffff +f5f5f7fdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffefffffefffffffffffffffffffffffffffdfffffdfffffb +f7f6f1fffffaf8f5eefefbf4ece9e0fffff6e3e1d5e8e6daeae6daede9ddeeeadef0ece0 +ddd9cdfaf6eae6e2d6fffff3f0ece0b6b2a66d695df6f2e6fffff3f1ede1ece8dcf1ede1 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdf +edebdfeeece0eeece0edebdfeeebe2edeae1050200fffef5f1efe3efede1edebdfedebdf +eeece0efede1eeece0edebdfefede1efede1efede1efede1efede1efede1efede1efede1 +f4f2e6e8e6daebe9dde3e1d5f1efe3faf8ecfffff4e8e6da030100030100110f03030100 +eeece0e2e0d4f1efe3f9f7ebeeece0e8e6dadedcd0f7f5e9eae8dceeece0e5e3d7f7f5e9 +eae8dcf3f1e5eceadee2e0d4f9f7ebefede1e8e6daf1efe3efede1efede1efede1efede1 +efede1efede1efede1efede1efede1efede1efede1efede1efede1efede1efede1edede1 +e7eedeecf0dff2eaddf6e9e0f3e4e7f5edeba5a8956d755d000400eeece0f2e8def3ebde +eaebd9e4f1f7cee8ff2546ad1439bd001eae00119b001ec90031d42165f81952b9e3ecff +f0e7def0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfebe7dbf0ece0040000e3dfd3ece8dc +fbf7ebece8dcf2eee2040000f6f2e6f5f1e5e3dfd3f7f3e7f9f5e9e6e2d6f7f3e7d6d2c6 +f8f4e8ece8dc070300040000faf6eaf6f2e6f5f1e6060000fcf5edf8f1e7e1dad0f5efe3 +f2ecdeeae7d6e4e1d0efeedc030200eeecddefede0ecece0e7e7ddf6f6eee8e5dce6dfd5 +e4ded2fff8eeddd6ccefe8e0f6efe7ebe4defef7f1f0ebe5eae5dfe1dcd6eee9e3fefaf1 +040000fffff6eeeadff5f1e5e7e3d7e2ded2f7f3e7f5f1e5ece8dcf5f1e5e3dfd3efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfe8e4d8faf6ea080400040000040000060200040000f5f1e5040000 +fffff3040000f8f4e8f7f3e7e6e2d6d2cec2f9f5e9efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff0eedfebe9daf2f0e1ebe9daeeece0 +efede1eeeee4a9a99f595951fffffaf0f1ecfffffb0e0e0c000000010302fefffffcfcfe +0000020303050a0a0c000002000002ffffff000002000002000002000002000002ffffff +fafafcfffffff9f9fbffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffefffffefffffffefffffffffffffffffffffffffdfffffdfffffb +fffffaf1eee7fffff8eae7dee4e1d8e8e6dafffdf1faf6eaede9ddede9ddf6f2e6e3dfd3 +f6f2e6e5e1d5e2ded2eeeadeb3afa3696559f4f0e4fffff3f0ece0ede9ddf5f1e5efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdfedebdf +eeece0eeece0edebdfeeebe2edeae1050200fffef5f2f0e4f0eee1eeece0eeecdfefede1 +f0eee1efede1eeecdfeeece0eeecdfeeece0eeecdfeeece0eeecdfeeece0eeecdfdcdace +f0eee1fbf9edf1efe2f5f3e7eae8dbc8c6ba060400fbf9edebe9dcf4f2e6f2f0e3060400 +f2f0e3e2e0d4e3e1d4f4f2e6f2f0e3f3f1e5e7e5d8f5f3e7f4f2e5f2f0e4e0ded1eeece0 +f3f1e4e4e2d6fcfaede5e3d7fefcefefede1f3f1e4eeece0eeecdfeeece0eeecdfeeece0 +eeecdfeeece0eeecdfeeece0eeecdfeeece0eeecdfeeece0eeecdfeeece0eceddfe8efdf +edf1e0f2eaddf7eae1f4e5e8f5edeba6a9966d755d000400eeece0f2e8def3ebdeeaebd9 +e4f1f7cee8ff2546ad1439bd001eae00119b001ec90031d42165f81952b9e3ecfff0e7de +f0f3e2e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff7f3e7e9e5d9040000080400f1ede1eae6da +eeeade0804001d190ddbd7cbf5f1e5ece8dcf3efe3ddd9cdfbf7ebede9ddfefaeef6f2e6 +e7e3d70400001f1b0feae6daf3efe3e5e1d6130b08ede3e2e7dfdce8e1d9f9f2e8f8f2e4 +e6e3d2fcf9e6f9f6e3040100f2f1dffffff2d8d5ccfdfaf3dad7d2faf7f2ebe4dafffef3 +eae1d8f4ebe2f9f2eaf7f0eae8e0ddeee6e3efe7e4fffbf8ede8e2eee9e3efebe2070300 +f3efe4dfdbd0e4e0d4fffff3e6e2d6efebdff9f5e9dcd8ccefebdff4f0e4efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdffbf7ebddd9cd090500efebdff3efe3fffff3d5d1c5f0ece0f2eee2e7e3d7 +141004d5d1c5efebdff8f4e8fefaeeece8dcefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff0eedfebe9daf2f0e1ebe9daeeece0efede1 +eeeee4a9a99f787971f6f7f1fffffb000100f3f5f2fefffffdfffe010302ffffffffffff +fcfcfef6f6f8ffffff000002ffffffffffffffffffffffffffffff000002ffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffefffffefffffefffffefffffffffffffffffffffdfffffdfffffbfaf9f4 +edeae3fffff8f4f1e8e4e1d8fffef2d6d4c8eae6dae6e2d6eeeadefcf8ecf5f1e5e0dcd0 +fffff3e8e4d8ece8dcb0aca0686458f6f2e6fffff3efebdfebe7dbf3efe3efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdfeeecdfedebdfeeece0 +eeece0edebdfeeebe2edeae1050200fffff3f2f0e3f0eedfeeecdfedebdcefede0efedde +efede0edebdceeecdfeeecddeeecdfeeecddeeecdfeeecddeeecdfeeecddf7f5e8fbf9ea +e9e7dae0decfe9e7daf6f4e5fffdf00c0a00e9e7daf0eedfeeecdfe0decf040200f0eedf +f8f6e9f9f7e8eceaddefeddeeae8dbeceadbe7e5d8f0eedff1efe2f5f3e4ebe9dcf2f0e1 +f4f2e5edebdceeecdfe7e5d6e9e7daf0eedfeeecdfeeecddeeecdfeeecddeeecdfeeecdd +eeecdfeeecddeeecdfeeecddeeecdfeeecddeeecdfeeecddeeecdfeceddfe8efdfecf0df +f2eaddf7eae1f4e5e8f5edeba6a9966d755d000400eeece0f2e8def3ebdeeaebd9e4f1f7 +cee8ff2546ad1439bd001eae00119b001ec90031d42165f81952b9e3ecfff0e7def0f3e2 +e9eedaeeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeeadef5f1e5040000050100fcf8ece8e4d8efebdf +040000050100e1ddd1f4f0e4040000e4e0d4fbf7eb0e0a00e8e4d8ede9dde6e2d6f4f0e4 +070300efebdf040000e2ded2fcf8ef060000fff8f6efe7e4f9f4ee060000040000090600 +ece9d8edead9050200060400e2e0d4040100f3f0ebf2eeeb040000f5eee6e7e0d6060000 +f7f0e8eee7e1040000100805040000f3ebe8e8e3df060100040000f3efe6040000ebe7de +f9f5ea0a0600dedacefaf6eae9e5d9f7f3e7e8e4d8f9f5e9eae6daefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfe6e2d6faf6ea040000ede9ddede9ddeae6daf4f0e4f0ece0f3efe4f0ece1040000 +fdf9eef7f3e8e5e1d6eae6dbece8ddefebe0efebe0efebe0efebe0efebe0efebe0efebe0 +efebe0efebe0eeece0efebe0eeece0efebe0eeece0efebe0eeece0efebe0eeece0efebe0 +eeece0efebe0eeece0efebe0efebe0efebe0efebdfefebe0efebdfefebe0efebdfefebe0 +efebdfefebe0efebdfefebe0efebdfefebe0efebdfefebe0efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff1eedfebe9daf3f0e1ebe9daeeece0efede1f0ede4 +a9a9a16b6a65fffffbfdfef9020200fffffffeffffffffff000002fffffff7f7f7ffffff +ffffff000002fffffffdfdfffafafafffffff7f7f7070709fcfcfcfffffffefefef0f0f2 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffefffffefffffefffffefffffffffffffffffffffdfffffdfdfcf8fffffaf3f0e9 +fffcf3e8e5dcf5f3e7e3e1d4110f020501000c0800040000040000040000060200e2ded2 +f6f2e6eeeadeb2aea26b675bf9f5e9fffff3efebdfe8e4d8efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeecdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdfedebdeeeece0eeece0 +edebdfeeebe2edeae1050200fffef5f1efe2efeddeedebdcedebdceeecddefeddeeeecdd +edebdcefeddeefeddeefeddeefeddeefeddeefeddeefeddeefeddeeeecddeceadbe2e0d3 +f8f6e7f1efe2e1dfd0f6f4e7030100e9e7daf0eedfeae8dbfaf8e9030100e9e7d8f4f2e5 +030100040200050300030100fffef1e4e2d5e4e2d5131104030100040200ebe9dceae8db +0a0800e8e6d9070500060400edebdeefeddeefeddeefeddeefeddeefeddeefeddeefedde +efeddeefeddeefeddeefeddeefeddeefeddeefeddeefeddeedeedee7eedcebefdef1eada +f6e9e0f3e4e7f4eceaa5a8976c745d000400eeece0f2e8dff3ebdeeaebd9e4f2f5cee8ff +2547ab1439bd001eae00119b001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dc +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfe9e5d9f6f2e6070300f5f1e5040000ede9dd040000f6f2e6 +0c0a00e2e0d4e9e7db0e0c00e2e0d4f5f3e7090700eae8dcefede1f0eee2ebe9dd080600 +ebe9dd030100fffdf1e3e0d7040000fffaf6f0ebe5030000f0ebe5e7e4dbf2efe6030100 +e6e4d8090700e8e5dcebe8df030000fffcf5dfdcd7080500e3ded8f9f5ec050100e7e2dc +040000f4f1eaece7e1f0ede60f0a04e4e1da030000ebe8e1f3f0e9030000fcf9f2030000 +e7e3d8fefaeee7e3d7f2eee2ece8dce7e3d7f1ede1f2eee2efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f2eee2ece8dc0b0700fefaeee2ded2eeeadef8f4e8e6e2d7040100eeebe2030000eeebe2 +e7e4db151209030000030000f2efe6e3e0d7f8f5ecf3f0e7e1ded5040100ece9e0080500 +0a0700deded4f0ede4edede30603000303000b0800e5e5dbece9e0070700060300010100 +eeebe2010100080500ece9e0edeae1f2f0e4030000030100070400f5f3e7e0ddd4060400 +eeebe2eeece0eeebe2eeece0eeebe2eeece0eeebe2eeece0efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff1eedfece9d8f5efe1ece9daefebe0f0ece1f1ede4aba8a1 +686560fffffbf8f7f5030102fffefff1f0f5fffeff000004f8f8f8fffffdf2f2f2fffffd +050505fcfcfafdfdfdfffffdfffffffffffd010101f1f1effffffff7f7f5fffffffdfdfb +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffdfffffffffffd +fefffdfefffdfefffffefffffffffffffffdfffffdfffffdfffefafffffaf3f0e9fffff6 +eceaddeceadbf1f0deedebdc0602000400000b0700040000050100f1ede2f3efe4f1ede2 +f0ece1aaa69b767267f1ede2fffff4eeeadfeeeadff0ece1efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeecdfeeecdfeeecdfeeecdfeeecddeeecddeeecddeeecddedebdceeecdfeeecdfedebdf +eeebe2edeae1050200fffef7f3efe4f1ede1efebdfefebdff0ece0f0ece0f0ece0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfedebdeefede0fcfaeee1dfd2 +f1efe3ebe9dcefede1030100eeece0f0eee1e6e4d8eeecdf030100edebdef0eee2030100 +ece9e0f4f1e8e4e1d8050200f2efe6151209e1ded5edeae1ebe8df030000ece9e0030000 +0b0800f1eee5eeebe2030100efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeceddde7eedcebf0dcf1eadaf6e9e0 +f3e4e7f4ebeca5a7996c745f000400eeebe2f2e8dff3ebe0eaecd7e4f2f5cee8ff2547ab +1439bd001eae00119b001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff3efe3e6e2d6040000f0ece0090500f6f2e60a0600e4e0d4050300 +fffef2e5e3d7040200f2f0e4e8e6da060400efede1f5f3e7e3e1d5eeece0080600e5e3d7 +efede1030100f9f7eb120f06eae7e0e3e0d903000005020016130c030000100d06f9f6ef +030000fffcf5f0ede6030000e4e1da131009e8e5de14110ae3e0d9030000fbf8f1030000 +e6e3dcf4f1eaece9e2030000f8f5ee0c0902e9e6dfe6e3dc060300030000f9f6edf7f3e8 +f2eee2e3dfd3eeeadefffff3f8f4e8e3dfd3eeeadeefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfe8e4d8 +fdf9ed040000040000040000070300f7f3e7f1ede20e0b02e7e4dd090600e9e6df080500 +e0ddd6e2dfd8fffef7030000f8f5eef6f3ece7e4ddfcf9f2070400030000e9e6dfeeeee6 +080800ecece4e4e4dce1e1d9e0e0d8f0f0e8050500edede5010100f1f1e9d3d3cb090901 +e5e5ddf9f9f1040400efece3030000ebe8dff2efe6f9f6ed030000fefbf2ebe8dfeeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeece0efebe0efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddf3eddfeee8d8f5efe1eee8daefebe0f0ece1f1ece6aca7a1787471 +f3efecfffefff2f0f10f0d10010004010005fffefffffffff3f3f1fffffd000000fffffd +fbfbf9fffffdf8f8f6f8f8f6090907eeeeecfffffdfffffdfffffdf6f6f4fefefcfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfefffd +fefffbfefffdfefffdfffffdfffffdfffffdfffffdfffefafffffaf3f0e9fffff4eceadd +eceadbf1f0deedecdae9e5d91713080400000f0b00ddd9cef2eee3f8f4e9e3dfd4f0ece1 +aaa69b767267f1ede2fffff4eeeadfeeeadff0ece1efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0 +eeece0eeecdfeeecdfeeecddeeecddeeeddbeeeddbedebdceeecddeeecdfedebdeeeebe2 +edeae1050200fffef7f3efe4f1ede1efebdfefebdff0ece0f0ece0f0ece0efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff2f0e4e1dfd3e2e0d4fffff4f9f7eb +dad8ccfffff4030100efede1eeece0f5f3e7e9e7db171509e5e3d7eceade040200f5f2e9 +edeae3faf7f00a0700d1cec70704000c0902030000120f08030000f7f4ed0c0902d2cfc8 +f3f0e9e7e4dd030000efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeceddde9eddcebf0dcf1ead8f6e9e0f3e4e7 +f4ebeca5a7996c745f000300eeebe2f2e7e1f3ebe0eaecd7e4f2f3cee8ff2547a91439bd +001eae00119b001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfe6e2d6f8f4e80b0700dfdbcff2eee2040000ede9ddf4f0e4030100e2e0d4 +f5f3e70a0800faf8ece4e2d6030100fcfaeee0ded2f4f2e6efede10c0a00edebdff1efe3 +fffff4030100050200e9e6ddf8f5ec070400f1eee5e2dfd6f9f6edefece3ebe8df060300 +efece3e9e6dd030000f8f5ec090600dfdcd3030000f0ede619160feae7e0090600ece9e2 +f3f0e9ece9e20a0700e3e0d9030000f2efe8fffff8030000fefbf4030000ede9dee5e1d5 +faf6eaebe7dbdedaceede9ddfffef2f1ede1efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0ece0ede9dd +0a0600f2eee2f0ece0f0ece0e9e5d9e2ded3030000e4e1da030000fffcf5030000100d06 +050200030000070400d7d4cde5e2dbf2efe8f3f0e9090600f2efe8e8e5deefefe7010100 +fffff8eeeee601010014140c030300010100eeeee6050500e4e4dcfffff812120aeeeee6 +d9d9d1010100ebe8df16130a080500030000030000070400eae7deeeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeece0efebe0efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddf3eddfeee8d8f5efe1eee8daefebe0f0ece1f1ece6aca7a1787471f1edea +fffeff010000fffefff9f7fafffeff010004fffffffffffff5f5f5000000fffffffefefe +edededfffffffafafa000000fffffffcfcfcf0f0f0fefefefafafaffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfefffdfefffd +fffffffffffffffffffffffffffefffffffdfffefafffffaf3f0e9fffff6eceadeeceadb +f1f0deedebdcf3efe3f4f0e5040000f1ede2efebe0f0ece1ede9def5f1e6f0ece1aaa69b +767267f1ede2fffff4eeeadfeeeadff0ece1efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0eeece0 +eeecdfeeecdfeeecddeeecddeeeddbeeeddbedebdceeecddeeecdfedebdeeeebe2edeae1 +050200fffef7f3efe4f1ede1efebdfefebdff0ece0f0ece0f0ece0efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefede1f2f0e4f4f2e6e5e3d7e7e5d9e8e6da +e9e7db030100edebdff7f5e9e3e1d5f9f7eb030100f4f2e6f4f2e6030100e2dfd6fffcf3 +e0ddd4030000fffff6030000ebe8dfefece3e7e4dbe3e0d7e1ded50f0c03f3f0e7eeebe2 +e7e4db141108efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeceddde9eddcebf0dcf1ead8f6e9e0f3e4e7f4ebec +a5a7996c745f000300eeebe2f2e7e1f3ebe0eaecd7e4f2f3cee8ff2547a91439bd001eae +00119b001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff4f0e4e8e4d80d0900f7f3e7f7f3e7040000e1ddd1f7f3e7030100fffff4eae8dc +dad8cc0705000b0900f3f1e5dfddd1fffff4e4e2d6eae8dc030100f5f3e7fcfaeed0cec2 +151307030000e1ded5ebe8df0e0b02efece3e7e4dbfdfaf1030000f1eee5030000eeebe2 +fffff6e7e4db030000f7f4ebf9f6edfaf7f0080500e9e6dfe8e5de030000f9f6efe5e2db +f1eee7050200f4f1ea16130cdcd9d2e8e5de030000e1ded7f9f6ed040000eeeadeede9dd +fefaeeeeeadef9f5e9e0dcd0eae6daefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff8f4e8ebe7db040000 +fdf9ede8e4d8fdf9eddcd8ccfffff4030000fffff8030000e4e1da0b0801dddad3e3e0d9 +f9f6efefece5fffff8e4e1daf1eee7eae7e0030000e4e1dafffdf6edede50f0f07e1e1d9 +050500ebebe3e3e3dbe2e2da060600fafaf2010100eaeae2e8e8e0010100e4e4dcfefef6 +010100efece3030000f6f3eaf8f5ecfbf8efefece3e8e5dcf7f4ebeeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff3eddfeee8d8f5efe1eee8daefebe0f0ece1f1ede4aca7a16c6964fffefbeeedeb +010000f8f6f9fffefffbf9fe0e0c0ffefefef8f8f80a0a0afafafaffffffffffffffffff +ffffff111111f3f3f3fffffff2f2f2ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffdfefffdffffff +fffffffffffffffffffffefffffefffffefcfffffbf3f0ebfffff8eceadeeceaddf1efe0 +edebdce5e1d5f0ece1f5f1e6e0dcd1f9f5eafbf7ecdcd8cdf6f2e7f0ece1aaa69b767267 +f1ede2fffff4eeeadfeeeadff0ece1efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0eeece0eeecdf +eeecdfeeecddeeecddeeeddbeeeddbedebdceeecddeeecdfedebdeeeebe2edeae1050200 +fffef7f3efe4f1ede1efebdfefebdff0ece0f0ece0f0ece0efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfe9e7dbefede1e5e3d7fffff4f3f1e5ebe9ddfdfbef +030100f7f5e9dbd9cde7e5d9f4f2e6080600eae8dcfaf8ec050300efece3e7e4dbf5f2e9 +030000e2dfd60e0b02f1eee5f0ede4f8f5ec030000f8f5ec030000eeebe2eae7def8f5ec +030100efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeceddde9eddcebf0dcf1ead8f6e9e0f3e4e7f4ebeca5a799 +6c745f000300eeebe2f2e7e1f3ebe0eaecd7e4f2f3cee8ff2547a91439bd001eae00119b +001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f3efe3e3dfd3040000f3efe3e3dfd3e8e4d8fefaeee3dfd3050300d7d5c9fcfaeef4f2e6 +030100efede1e1dfd3f9f7ebe2e0d4f6f4e8eceade030100eceadef7f5e9eceadef4f2e6 +070500faf8ececeadedbd9cd050300030100030100e8e6daf8f6eaf1efe30d0b00dedcd0 +eceade090700d0cec2f3f1e5f0ede4030000fcf9f0e5e2d9e7e4db030000050200030000 +eeebe2e5e2d9060300f4f1e8e8e5dc030000fbf8eff0ede4e8e4d9130f03e3dfd3e9e5d9 +f3efe3eae6dafaf6eaf1ede1efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfdbd7cbfefaee040000f2eee2 +f3efe3dad6caf9f5e9e8e4d9090600e1ded5030000fdfaf1040100fdfaf1efece3edeae1 +030000f7f4ebebe8dfe9e6ddf6f3ea030000fefbf2d8d5ccecece2010100e3e3d9020200 +ecece2fdfdf3e5e5db0e0e04ecece2010100fdfdf3e7e7dd010100fffff6d9d9cf020200 +e7e4db1a180cf2f0e4dddbcff2f0e4030100f3f1e5e4e2d6eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f3eddfeee8daf5efe1eee8daefebe0f0ece1f1ede4aca7a165625dfffefbfffefc010000 +fffefffffefffffeff010002fffffff7f7f70a0a0af7f7f7fffffff2f2f2fffffff2f2f2 +000000fffffff2f2f2ffffffffffffe9e9e9ffffffefefefffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffdffffffffffff +fffffffffffffffefffffefffffdfefffefdf3f0ebfffff8ede9e0ede9def2eee2eeeade +efebe0f1ede2fffff4e3dfd4eeeadfefebe0f1ede2ece8ddf0ece1aaa69b767267f1ede2 +fffff4eeeadfeeeadff0ece1efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0eeece0eeecdfeeecdf +eeecddeeecddeeeddbeeeddbedebdceeecddeeecdfedebdeeeebe2edeae1050200fffef7 +f3efe4f1ede1efebdfefebdff0ece0f0ece0f0ece0efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff6f4e8efede1f9f7ebd5d3c7eeece0fdfbefdcdacef2f0e4 +030100090700151307050300edebdfebe9dde7e5d90301000b0900040200060400fbf9ed +ebe9ddf9f7eb030100050300030100f7f5e9e4e2d6121004f0eee2f0eee2f9f7eb030100 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeceddde9eddcebf0dcf1ead8f6e9e0f3e4e7f4ebeca5a7996c745f +000300eeebe2f2e7e1f3ebe0eaecd7e4f2f3cee8ff2547a91439bd001eae00119b001cc7 +0738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdffcf8ec +efebdffcf8ecebe7dbf7f3e7f2eee2f1ede1f4f0e4f9f7ebe5e3d7fffff4dfddd1060400 +f2f0e4f0eee2edebdfefede1e9e7dbefede1fffff4e7e5d9eae8dcf6f4e8e5e3d7f4f2e6 +dad8cbf9f7ebf7f5e8e6e4d8f6f4e7eae8dcfbf9ece5e3d7f0eee1e8e6daebe9dcf5f3e7 +fffdf0f8f6eaf3f1e5efece3fbf8efe4e1d8fffef5f3f0e7e5e2d9f9f6edf1eee5eeebe2 +f9f6ede3e0d7fffff6e9e6ddf0ede4f1eee5e4e2d6faf6ebd9d5c9faf6eaefebdfede9dd +f3efe3e1ddd1f8f4e8efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdffdf9ede8e4d8151105e4e0d4efebdf +fbf7ebefebdfefebdf030000efece3060300f1eee5e5e2d90300000a0700030000fbf8ef +e3e0d7f9f6ede4e1d8eeebe2030000efece3f8f5ecf4f4ea010100fdfdf3ebebe1020200 +0101000a0a00010100dcdcd20f0f05e6e6dcebebe10b0b01d7d7cdf5f5eb0b0b01f1efe3 +faf8ec030100030100171509faf8ece7e5d9070500eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff3eddf +eee8daf5efe1eee8dcefebe0f0ece1f1ede4aca89f76736efdfaf5fffffbfffffd010000 +010000010000fffefffcfcfcffffff000000fffffffbfbfbffffffffffffffffff000000 +efefeffffffff6f6f6fffffffffffffcfcfcffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffdfffffdffffffffffffffffff +fffffffffefffffefffffdfefffefdf3efecfffffaede8e2ede9e0f2eee3eeeadffaf6eb +e3dfd4ede9defdf9eee3dfd4ece8ddebe7dcf5f1e6f0ece1aaa69b767267f1ede2fffff4 +eeeadfeeeadff0ece1efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0eeece0eeecdfeeecdfeeecdd +eeecddeeeddbeeeddbedebdceeecddeeecdfedebdeeeebe2edeae1050200fffef7f3efe4 +f1ede1efebdfefebdff0ece0f0ece0f0ece0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeceadeedebdfedebdff1efe3f1efe3f4f2e6e9e7dbf2f0e4f4f2e6 +dedcd0f9f7ebdedcd0e6e4d8f1efe3f2f0e4030100eeece0e6e4d7f0eee2e5e3d6f3f1e5 +e3e1d4f8f6eaeeecdff6f4e8e2e0d3f9f7ebe6e4d7e9e7dbdddbceebe9ddf5f3e6efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeceddde9eddcebf0dcf1ead8f6e9e0f3e4e7f4ebeca5a7996c745f000300 +eeebe2f2e7e1f3ebe0eaecd7e4f2f3cee8ff2547a91439bd001eae00119b001cc70738db +1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfebe7dbe5e1d5 +f2eee2e7e3d7f1ede1f8f4e8e0dcd0ebe7dbd3d1c5fffff4030100030100fefcf0eeece0 +dedcd0f7f5e9eceadefaf8ecdbd9cdf3f1e5e4e2d6f4f2e6dddbcff9f7ebeae8dbf3f1e2 +f2f0e3e0decff7f5e8e8e6d7f2f0e3e3e1d2f9f7eaeae8d9e2e0d3eeecddebe9dcd4d2c3 +f0eee1eae8dbf1efe3ece9e0dcd9d0f5f2e9f3f0e7eae7deefece3e6e3dae6e3daf4f1e8 +ebe8dfdedbd2ece9e0f7f4ebefece3e9e7dbf3efe4efebdff8f4e8f9f5e9dcd8ccf8f4e8 +f8f4e8e8e4d8efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfe9e5d9f0ece0e6e2d6f2eee2eae6daf4f0e4 +e3dfd3f9f5e9eeebe2eae7defffcf3e1ded5f8f5ecebe8dfe7e4dbfffcf3e7e4dbf7f4eb +f3f0e7e3e0d7f7f4ebe8e5dceeebe2e9e6dde9e6ddedeae1eae7defefbf2dad7ceedeae1 +f8f5ecefece3fdfaf1f0ede4edeae1e9e6ddf8f5ecefece3eeebe2ebe8dfeeece0e3e1d5 +edebdff3f1e5e8e6dadcdacef6f4e8ebe9ddeeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff3eddfeee8da +f5efe3eee8dcefebe0f0ece1f1ede4aca89f74716cfffcf7fcfbf7fffffbfbfaf8f8f7f5 +fffffdfffdfef3f1f2fffefffffefffffefffffefffefcfdfffefff3f1f2fffefffffeff +f9f7f8fffefffffdfefffdfef4f2f3fffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffffdfffffdfffefffffefffffefffffeff +fffdfffffdfffffdfefffefff4eeeefffefbede8e2ede9e0f2eee5eeeadffaf6ebdedacf +f2eee3eae6dbf9f5eaf5f1e6f3efe4e4e0d5f0ece1aaa69b767267f1ede2fffff4eeeadf +eeeadff0ece1efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeece0eeece0eeecdfeeecdfeeecddeeecdd +eeeddbeeeddbedebdceeecddeeecdfedebdeeeebe2edeae1050200fffef7f3efe4f1ede1 +efebdfefebdff0ece0f0ece0f0ece0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfedebdff2f0e4f2f0e4e1dfd3f8f6eadbd9cd1e1c100301000301001f1d11 +030100070500141206030100f4f2e6030100ebe9dceceadbfffff3f1efe0eeecdff1efe0 +edebdeebe9dae6e4d7fbf9eae0ded1faf8e9f4f2e5f6f4e5f8f6e9eae8dbefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeceddde9eddcebf0dcf1ead8f6e9e0f3e4e7f4ebeca5a7996c745f000300eeebe2 +f2e7e1f3ebe0eaecd7e4f2f3cee8ff2547a91439bd001eae00119b001cc70738db1c60f3 +1c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeae6dafffcf0f1ede1 +e6e2d6fcf8ece2ded2f9f5e9f3efe3fbf9eddfddd1fefcf0eceadeefede1eceadeefede1 +eeece0e7e5d9eeece0f7f5e9e3e1d5f6f4e8edebdff4f2e6eceaddf3f1e4e8e6d7eae8d9 +f7f5e6ebe9daf0eedfedebdcf2f0e1e7e5d6f8f6e7f2f0e1e3e1d2f8f6e7f3f1e2efedde +e9e7dae6e4d8fcf9f0f6f3eae8e5dcece9e0f2efe6eae7def9f6edf4f1e8e4e1d8f6f3ea +f6f3eaeeebe2e4e1d8f6f3eaf2f0e4e9e5d9f1ede1e3dfd3f4f0e4ebe7dbfbf7ebe8e4d8 +f4f0e4efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff1ede1efebdff9f5e9eae6daebe7dbf2eee2ede9dd +f1ede1f0eee2f4f1e8dddad1f6f3eae8e5dcf0ede4f3f0e7e4e1d8e7e4dbf8f5eceae7de +f1eee50401000401000300000502000502000b0800ebe8dfe4e1d8f9f6edf6f3eae1ded5 +f1eee5ebe8dfe3e0d7f7f4ebfaf7eed4d1c8f4f1e8f2efe6e9e7dbf3f1e5efede1eae8dc +eceadef0eee2eae8dcfefcf0e6e4d8eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff3eddfeee8daf5efe3 +eee8dcefebe0f0ece1f1ede4aca89f726f68fefbf6fffffbf1f0ecfffffbfcfbf9f8f7f5 +fffffdfffefff0eeeffffdfefffefffcfafbfaf8f9fffefffcfafbfffefff3f1f2fffeff +f7f5f6fdfbfcfffefffffefffdfbfcfffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffffdfffffdfffffdfffffdfffefffffefffffefffffdff +fffdfffffdfefffefff4eeeefffefbede8e4ede8e2f2eee5eeeae1e5e1d6fcf8edefebe0 +f2eee3e3dfd4eeeadfeeeadff4f0e5f0ece1aaa69b767267f1ede2fffff4eeeadfeeeadf +f0ece1efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeece0eeece0eeecdfeeecdfeeecddeeecddeeeddb +eeeddbedebdceeecddeeecdfedebdeeeebe2edeae1050200fffef7f3efe4f1ede1efebdf +efebdff0ece0f0ece0f0ece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfedebdfefede1e6e4d8f6f4e8eae8dcf4f2e6e4e2d6f9f7ebefede1e2e0d4f8f6ea +edebdfebe9ddf1efe3f4f2e6f0eee1edebdef1efe0e3e1d2e8e6d7f2f0e1f2f0e1e8e6d7 +f0eedff4f2e3e8e6d7e9e7d8e6e4d5e9e7d8faf8e9d5d3c4f8f6e7efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eceddde9eddcebf0dcf1ead8f6e9e0f3e4e7f4ebeca5a7996c745f000300eeebe2f2e7e1 +f3ebe0eaecd7e4f2f3cee8ff2547a91439bd001eae00119b001dc80030d32064f71851b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff1efe3f0eee2eae8dcf6f4e8e4e2d6f3f1e5e8e6daf4f2e6 +e7e5d9f8f6eae9e7dbf1efe3f5f3e7e8e6dae6e4d8f2f0e3f2f0e3e8e6d7f6f4e5e8e6d7 +fbf9eaf1efe0f6f4e5eeecddf3f1e2e7e5d6f2f0e1eceadbeae8d9e6e4d5f0eedff0eee1 +eeece0ebe9ddf7f5e9e1dfd3fdfbefefede1e1dfd3f8f6eaeeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0 +efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0eeece0eeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff2ece0eee8dcf5efe3eee8dc +e4e0d5f8f4e9eae6ddaba79e6b6861fffff8fffffaf8f7f2fffffaf9f8f4fffffbf6f5f1 +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefcfffefc +fffefcfffefcfffefcfffefcfffefafffefafffefafffefcfffdfefffdfefffdfefffdfe +fff9fbfffdffece6e6b4afacaaa29fa9a29ca9a29abbb4acaeaa9faeaa9faeaa9faeaa9f +aeaa9faeaa9faeaa9faeaa9fafaba0a7a3986e6a5ff9f5eafcf8edeeeadfebe7dcf6f2e7 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeece0eeece0eeecdfeeecdfeeecddeeecddeeeddbeeeddb +eae8d9e9e7d8f0eee1edebdee5e2d9faf7ee040100fffff8efebe0efebdfefebdfefebdf +efebdfefebdfefebdfefebdfeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdeedebdeedebdcedebdcedebdcedebdcedebdcedebdcedebdc +edebdcedebdcedebdcedebdcedebdcedebdcedebdcedebdceeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeebecdc +edf1e0eff4e0f2ebd9f3e6ddfcedf0ede4e5abad9f656d58000200efece3f6ebe5f3ebe0 +e7e9d4e8f6f7cce6ff2749ab1439bd001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfe8e6daf3f1e5f3f1e5eae8dce7e5d9efede1090700030100110f03 +03010018160adfddd1eceade070500edebdff5f3e7e9e7dae7e5d6f0eee1f7f5e6dedccf +ebe9dadcdacdf5f3e4e8e6d9f9f7e8f9f7ead9d7c8fffff3f1efe0e4e2d5efede0e8e6da +fefcf0f5f3e7eeece0e2e0d4f1efe3eeece0ebe9ddeeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0 +efebe0efebe0efebe0efebe0efebe0efebe0efebe0eeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefe9ddebe5d9f6f0e4f4eee2e9e5da +f5f1e6e5e1d8aeaaa184817af0ede6f7f6f1fbfaf5fffffafefdf8fffffafaf9f5fffffb +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffd +fffffbfffffdfffffbfffffafffffafffffafffffbfffefdfffefdfffefffffefffffdff +e5dfdf8e88885b5653756d6a867f79736c64676058716d62716d62716d62716d62716d62 +716d62716d62716d6269655a74706579756aeeeadffffff4efebe0ede9deeae6dbefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfeeece0eeece0eeecdfeeecdfeeecddeeecddeeeddbeeeddbf9f7e8 +e6e4d5efede0eae8dbf0ede4f1eee5030000fffff8f1ede2f1ede1f1ede1f1ede1f1ede1 +f1ede1f1ede1f1ede1f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0efede1 +efede1efede1efede1efede1efede1efede1efede1efede1efede1efede1efede1efede1 +efede1efede1efede1efede0efeddeefede0efeddeefede0efeddeefede0efeddeefede0 +efeddeefede0efeddeefede0efeddeefede0efede0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0edeedee6ead9 +ebf0dcf0e9d7f0e3daf5e6e9e7dedfadafa1717964030600eeebe2ece1dbf0e8ddebedd8 +e5f3f4cde7ff2749ab1439bd001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfedebdff6f4e8e6e4d8e9e7dbfffff3f4f2e6030100fffff3f1efe3eae8dc +f2f0e4080600dedcd0080600fffff4d7d5c9f1efe3f5f3e6edebdff0eee1fffef2e7e5d8 +fffff3ebe9dcf9f7ebe4e2d5e9e7dbf5f3e6dcdacef6f4e7e3e1d5f2f0e4ebe9dde1dfd3 +dbd9cdf5f3e7f1efe3ebe9ddfbf9edebe9ddeeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0 +efebe0efebe0efebe0efebe0efebe0efebe0eeecdfeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff0eadeeae4d8f4eee2f6f0e4ebe7dcf2eee3 +e9e5dac5c1b6e1ded5fffcf3f7f7eff6f6eef5f5ede9e9e1edede5ecebe6f1eee9f1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9f1edeaf1eee9 +f1edeaf1eee9f1eee7f1eee7f1eee7f1eee9f1eee9f1edeaf2ececf2ececf5efeffef8f8 +f3ebe9eae2dffaf2effcf5eff5ece5fdf6eef6f2e7f6f2e7f6f2e7f6f2e7f6f2e7f6f2e7 +f6f2e7f6f2e7fcf8edede9deede9defcf8edfffff4e5e1d6f2eee3f2eee3efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfeeece0eeece0eeecdfeeecdfeeecddeeecddeeeddbeeeddbe7e5d6e7e5d6 +fffff3eeecdff6f3eaeeebe2030000fffff8aeaa9faeaa9eaeaa9eaeaa9eaeaa9eaeaa9e +aeaa9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9eadab9fadab9f +adab9fadab9fadab9fadab9fadab9fadab9fadab9fadab9fadab9fadab9fadab9fadab9f +adab9fadab9fadab9fadab9eadab9fadab9eadab9fadab9eadab9fadab9eadab9fadab9e +adab9fadab9eadab9fadab9eadab9fadab9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9e +aeaa9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9eaeaa9eabac9ca8ac9baeb39f +b5ae9cb5a89fbcadb0b9b0b1989a8c727a65000200f1eee5f4e9e3f0e8ddebedd8e2f0f1 +d3edff2244a61439bd001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeceadee7e5d9f3f1e5fbf9ede5e3d7edebdf030100efede1efede1e0ded2eae8dc +0a0800fffdf1030100eae8dcf3f1e5eae8dcf4f2e6e9e7dbeae8dceceadee2e0d4e9e7db +edebdfefede1dedcd0edebdffaf8ecf6f4e8eeece0eceadefaf8ece7e5d9fefcf0f7f5e9 +f0eee2eae8dcebe9ddf0eee2eceadeeeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0 +efebe0efebe0efebe0efebe0efebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff5efe3ece6daefe9ddf2ece0ebe7dcf1ede2f4f0e5 +e8e4d9fffff6fffff6fffff8fffff8fdfdf5fefef6fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff6fffff4fffff6fffff8fffff8fffffafffefbfffefbfffdfafffefbfffdfa +fffef8fffef8fffdf5fbf2ebfffcf2fffaf0fffbf0fffbf0fffbf0fffbf0fffbf0fffbf0 +fffbf0fffff4fffff4fffff4f8f4e9fffff4ede9def5f1e6f4f0e5efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfeeece0eeece0eeecdfeeecdfeeecddeeecddeeeddbeeeddbf8f6e7edebdceae8db +d8d6c9f6f3eaf4f1e80300006e6b64706c61706c60706c60706c60706c60706c60706c60 +706c60706c60706c60706c60706c60706c60706c60706c60706c606f6d616f6d616f6d61 +6f6d616f6d616f6d616f6d616f6d616f6d616f6d616f6d616f6d616f6d616f6d616f6d61 +6f6d616f6d616f6d616f6d616f6d616f6d616f6d616f6d616f6d616f6d616f6d616f6d61 +6f6d616f6d616f6d616f6d616f6d61706c60706c60706c60706c60706c60706c60706c60 +706c60706c60706c60706c60706c60706c60706c60706c606d6e5e656958696e5a6f6856 +6e61587465687b7273737567646c57000200f9f6edfffaf4f1e9dee5e7d2e0eeefdcf6ff +2143a51439bd001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9 +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efede1fcfaeedddbcfe7e5d9f6f4e8eceade171509e5e3d7f4f2e6f5f3e7f9f7eb030100 +d6d4c8030100e8e6daefede1040100030000030000e7e4dbf5f2e9faf7ee0b0800030000 +030000fffff6f2efe6e7e4db030000030000030000e3e1d5eceadee3e1d40d0b00030100 +fffdf0f4f2e5dddbcef9f7eaeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +efebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdf +f1ebdff1ebdff1ebdfefebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff5efe3eee8dcefe9ddf2ece0ede9deefebe0f5f1e6f7f3e8 +ebe9dddcdaceecece2f0f0e6ecece2f3f3e9ecece2eaeae0eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2 +eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeebe2eeece0 +eeecdfeeecdfeeece0eeece0efebe2efeae4efeae4efeae6f6eeebede5e2e5dddaeae3dd +f6ede6f7eee5f5ece3f9f2e8f3ece2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +dedacfdedacff3efe4e7e3d8f0ece1f4f0e5eeeadfece8ddefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +eeece0eeece0eeecdfeeecdfeeecddeeecddeeeddbeeeddbe5e3d4efeddef3f1e4f6f4e7 +f6f3ead6d3ca16130e030000080400080400080400080400080400080400080400080400 +080400080400080400080400080400080400080400080400070500070500070500070500 +070500070500070500070500070500070500070500070500070500070500070500070500 +070400070400070400070400070400070400070400070400070400070400070400070400 +070400070400070400070500080400080400080400080400080400080400080400080400 +0804000804000804000804000804000804000804000506000105000409000a03000a0000 +0a0000070000050700010900090c01c8c5bce7dcd6f3ebe0f3f5e0e7f5f6d8f2ff1e40a2 +1439bd001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfe2e0d4 +eeece0f3f1e5faf8eceae8dcf4f2e6030100030100030100030100171509e3e1d5fffff4 +0e0c00eeece0f4f2e6f9f6ede3e0d7fbf8ef131007e0ddd4030000f0ede4e0ddd4eae7de +030000f0ede4030000f3f0e7fefbf2e0ddd416130aeceade131104e6e4d7f2f0e30b0900 +dfddd0fdfbeee6e4d7eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdff1ebdf +f1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdf +f1ebdff1ebdfefebdfefecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefe9ddf0eadef2ece0f4eee2f2eee3eeeadfece8ddefebe0f6f4e8 +f0eee2f8f8eef3f3e9ebebe1f0f0e6ecece2e7e7dbedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdeedebdc +edebdcedebdcedebdeeeeadfeeeae1eeeae1eee9e3efe8e2f5eee8fef7f1fef7eff4ebe2 +e9e1d6eae2d7eee8dcf0e9dfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadffffdf2 +fcf8edf7f3e8ece8dde8e4d9f2eee3ede9deeeeadfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0 +eeece0eeecdfeeecdfeeecddeeecddeeeddbeeeddbeae8d9f1efe0f0eee1f5f3e6e8e5dc +f0ede4eae7e2f8f5eeece8ddece8dcece8dcece8dcece8dcece8dcece8dcece8dcede9dd +ede9ddede9ddede9ddede9ddede9ddede9ddede9ddeceadeeceadeeceadeeceadeeceade +eceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeeceadeece9e0 +ece9e0ece9e0ece9e0ece9e0ece9e0ece9e0ece9e0ece9e0ece9e0ece9e0ece9e0ece9e0 +ece9e0ece9e0ece9e0ede9deede9ddede9ddede9ddede9ddede9ddede9ddede9ddede9dd +ede9ddede9ddede9ddede9ddede9ddede9ddeaebdbe7ebdaebf0dcf7f0def9ece3f6e7ea +efe6e7e8eadce4ecd7eaede2fffff6f5eae4eee6dbe4e6d1d5e3e4cfe9ff3456b81439bd +001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff8f6eaf3f1e5 +eae8dcebe9dde7e5d9dedcd0100e02e4e2d6faf8eceeece0e0ded2edebdfe6e4d8050300 +e9e7dbeae8dc030000131009030000030000f4f1ea030000f3f0e9fdfaf3e4e1dafbf8f1 +e5e2db0a0700030000040100030000030000f6f4e8e6e4d7030100fffef1f1efe2efede0 +e5e3d6f2f0e3eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdff1ebdff1ebdf +f1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdff1ebdf +f1ebdfefebdfefecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfede7dbf4eee2f3ece2f1eae0f2eee3efebe0eae6dbebe7dcedebdfeeece0 +e5e5d9e3e3d7e4e4d8e7e7dbf1f1e5f4f4e8eeece0efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeddbeeeddb +eeeddbeeecddefebdfefebe0f1eae2f1eae2f5eee6ebe4dce8dfd8e8dfd8ece3daf6eee3 +faf2e7f2ece0f2ebe1f0ece1f0ece1f0ece1f0ece1f0ece1f0ece1f0ece1e4e0d5e5e1d6 +e9e5daf0ece1f7f3e8f0ece1f2eee3efebe0efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0eeece0 +eeecdfeeecdfeeecddeeecddeeeddbeeeddbf0eedfebe9daeae8dbedebdef2efe6edeae1 +ece9e4e7e4ddf1ede2f1ede1f1ede1f1ede1f1ede1f1ede1f1ede1f1ede1f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f1efe3f1efe3f1efe3f1efe3f1efe3f1efe3 +f1efe3f1efe3f1efe3f1efe3f1efe3f1efe3f1efe3f1efe3f1efe3f1efe3f1eee5f1eee7 +f1eee7f1eee7f1eee7f1eee7f1eee7f1eee7f1eee7f1eee7f1eee7f1eee7f1eee7f1eee7 +f1eee7f1eee5f2eee3f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2f2eee2 +f2eee2f2eee2f2eee2f2eee2f2eee2eff0e0e4e8d7e6ebd7f2ebd9f9ece3f9eaedf2e9ea +eaecdee8f0dbe5e8dddad7ceeadfd9fbf3e8f5f7e2e9f7f8c6e0ff1a3c9e1439bd001eae +00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff0eee2e2e0d4f0eee2 +ebe9ddf0eee2fffdf1030100f2f0e4e2e0d4faf8ece8e6daf5f3e7f5f3e7030100f3f1e5 +030100ece9e0e6e3dcf9f6ef030000fffcf5030000e6e3dceeebe4f9f6efe3e0d9eae7e0 +0c0902efece5e9e6dffcf9f2e8e5dceae8dcf5f3e6eceadd030100e8e6d9e9e7dafaf8eb +e7e5d8eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfefebdff1ebdf +efebdff1ebdfefebdff1ebdfefebdff1ebdfefebdff1ebdfefebdff1ebdfefebdff1ebdf +efebdfeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff0eadef8f2e6f2ebe1ebe4daeeeadff1ede2f0ece1f4f0e5efede1f7f5e9e8e8dc +f0f0e4f4f4e8e6e6daebebdfecece0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddeeeddbeeedd9eeeddb +eeeddbefebdfefebdfefebe2f1eae2efe8e0f3ece4fdf4edf9f0e7eee5dcf1e9def5ede0 +ece6d8eeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadff7f3e8f0ece1eeeadf +ece8ddf8f4e9ddd9cef2eee3efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0eeece0eeecdf +eeecdfeeecddeeecddeeeddbeeeddbe8e6d7f1efe0f8f6e9e0ded1f0ede4f1eee5ece9e4 +f0ede6ede9deede9ddede9deede9ddede9deede9ddede9deede9ddeeeadfeeeadeeeeadf +eeeadeeeeadfeeeadeeeeadfeeeadfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedeae1edeae1edeae3 +edeae1edeae3edeae1edeae3edeae1edeae3edeae1edeae3edeae1edeae3edeae1edeae3 +edeae1eeeadfeeeadfeeeadfeeeadfeeeadfeeeadeeeeadfeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeebecdef0f4e3ecefdcf1eadaf5e8dff5e6e9f1e7e8eceee0 +edf5e0f9fbeee1ded5fdf3eaf2e8dedcdec9edfbfed3ecff2042a61439bd001eae00119b +001dc80030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeeadeede9dde8e4d8f1ede1 +f5f1e5f6f2e6040000f7f3e7efebdff1ede1f0ece0efebdff4f0e4040000f3efe3060200 +f7f3eae4e0d7f7f3ea040000efebe2040000faf6edeae6ddf3efe6040000f1ede4070300 +ebe7dee6e2d9f2eee5040000e9e5da040000efebdff4f0e4040000f2eee2eeeadeeeeade +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfede9ddf2eee2ede9ddf8f4e8 +eeeadefaf6eaf0ece0efebdff1efe2e5e3d6fcfaeddbd9ccf8f6e9f7f5e8e2e0d3f6f4e7 +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfefebdfeeecdf +efebdfeeecdfefebdfeeecdfeae6daf5f3e6efebdfeeecdff8f4e8e1dfd2f9f5e9e7e5d8 +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f1ebdff4eee2ebe4daf5eee4f3efe4eae6dbf5f1e6f5f1e6eeece0eae8dce8e8dce8e8dc +e8e8dceaeadef3f3e7e5e5d9eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeade +eeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeeadeeeebdcedecdaebedd8ebecdaebecda +edebdeedebdeedeae1eeeae1f0ece3f0ece3f3ece4f3ece2f3ece2f2ece0f1ebddf1ebdd +efebe0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0f9f7ebe6e4d8f6f4e8 +e3e1d5f9f7ebe2e0d4f0eee2efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0efebe0efebdfefebdf +efecddefecddefecdbefecdbece9daefecddeae6daf0ece0eeeae1f2eee5fffefaf8f3ed +fffff6fffff4fffff6fffff4fffff6fffff4fffff6fffff4fffff6fffff4fffff6fffff4 +fffff6fffff4fffff6fffff4fffff4fffff4efede1fffff4fcfaeefffff3fffff4fffdf1 +fffff3fffff4fffff4fffff4f7f5e9fffff4fefcf0fffff4fffff4fffff4fffff6fffff4 +fffff6fffff4fffff6fffff4fffff6fffff4fffff6fffff4fffff6fffff4fffff6fffff6 +fffff6f4f1e8fffff6fffff6fffdf4fffff4fffff6fefcf0fffff4fffff4fffff3fffff3 +fffff3fffff3fffff3fffff3fefff3fafdecffffeffffaf1fffafdfff8f7fffff1f1f6e0 +6f7163eeeadff4e7dff7ede1eaebd9e3f1f4d3ebff2444a91439bd001eae00119b001dc8 +0030d32064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfece8dcfffff3ece8dcddd9cdf9f5e9 +e0dcd0262216e5e1d5eeeadee5e1d5f3efe3fffff3e0dcd0090500f1ede1ede9dd040000 +040000090500040000f5f1e8f9f5ec040000120e05040000ede9e0e6e2d9f4f0e70e0a01 +0703000a0600ebe7dcf7f3e8eeeade050100070300d6d2c6f3efe3e4e0d4f6f2e6efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff5f1e5f0ece0e9e5d9e2ded2f1ede1 +e5e1d5ebe7dbfffbefeae8dbf3f1e4e8e6d9fffff2eeecdff1efe2f1efe2e5e3d6eeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdffbf9ece8e6d9eceaddf9f7eaeae8dbefede0edebdef1efe2eeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdf +f4eee2ebe4daf3ece2f4f0e5eeeadfefebe0dedacfe5e3d7ebe9ddeeeee2f6f6eaf0f0e4 +e5e5d9eeeee2eeeee2efede1f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0 +f0ece0f0ece0f0ece0f0ece0f0ece0f0ece0efede0edeedcedeedcedeedcedeedeefede0 +efede1efece3efece3ece8dfece8dfefe8e0f0e9e1f1eae0f1ebdff1ebdfefebdff1ede2 +f0eee2f0eee2f0eee2f0eee2f0eee2f0eee2f0eee2eeece0e7e5d9f0eee2ebe9ddfaf8ec +eae8dcfffdf1e9e7dbefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0efebe0efebdfefebdfefecdd +efecddefecdbefecdbedeadbefecddeae6daf0ece0eeeae1f1ede4fffefaf7f2ecf4efe9 +f4f0e7f4f0e7f4f0e7f4f0e7f4f0e7f4f0e7f4f0e7f4f0e7f4f0e7f4f0e7f4f0e7f4f0e7 +f4f0e7f4f0e7f4f0e7eceadefefcf0fffff3e8e6daf3f1e5fffff4edebdff9f7ebf8f6ea +efede1e3e1d5f2f0e4fffdf1eae8dcf4f2e6f7f5e9f3f1e5f3f1e5f3f1e5f3f1e5f3f1e5 +f3f1e5f3f1e5f3f1e5f3f1e5f3f1e5f3f1e5f3f1e5f3f1e5f3f1e5f3f1e5f3f1e5f5f2eb +f0ede6f4f1eae9e6dff1eee5f3f0e7f6f3eaf5f2e9f3f1e5f3f1e5f3f1e4f3f1e4f3f1e4 +f3f1e4f3f1e4f1f2e4f6faebf0f3e2fcf2e6fceee5ffeff2f0e4e4ebecdab7bca5707163 +eeeadff4e7def7ede1ecebd9e5f0f6d3ebff2444ab1439bd001eae00119b001dc80030d3 +2064f71851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff5f1e5dedacef9f5e9fbf7ebefebdfebe7db +dad6caf1ede1ede9ddf4f0e4e0dcd0e0dcd0fefaeedcd8ccfffff3e8e4d8fffdf4e8e4db +f0ece3f4f0e7e4e0d7f0ece3f1ede4e0dcd3f8f4ebf9f5ece4e0d7ede9e0f2eee5e4e0d7 +efebe2f2eee3f6f2e7d9d5c9fffff3eeeadefaf6eaede9ddfcf8ece6e2d6efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfece8dceeeadefefaeef9f5e9e8e4d8eeeade +f3efe3dbd7cbedebdeebe9dcf0eee1e9e7daeeecdfeeecdfedebdef4f2e5eeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfdad8cbfaf8ebdedccfe0ded1f2f0e3eeecdff6f4e7eceaddeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ebdff4eee2 +ece6daf1ebdff3efe4f3efe4e9e5dac1bdb2b7b5a9b8b6aa9f9f95a9a99fadada3a7a79d +aaaaa0a9a99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99daba99d +aba99daba99daba99daba99daba99daba99ca9aa9aa9aa9aa9aa9aa9aa9caba99daba89f +aba89faba8a1b1aca6b1aca6b1aca6b1ada4b2aba1b2aca0b2aca0b0aca0aaa69ba9a79b +a9a79ba9a79ba9a79ba9a79ba9a79ba9a79ba6a498c0beb2aba99db4b2a6fffff4dbd9cd +f1efe3f0eee2efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebe0efebe0efebdfefebdfefecddefecdd +efecdbefecdbedeadbf0eddeebe7dbf1ede1ede9e0f1ede4fffefaf7f2eceee9e3eeeae1 +eeeae1eeeae1eeeae1eeeae1eeeae1eeeae1eeeae1eeeae1eeeae1eeeae1eeeae1eeeae1 +eeeae1eeeae1f2f0e4e1dfd3efede1f6f4e8e8e6dadcdacef2f0e4e9e7dbe5e3d7f3f1e5 +fffef2f9f7ebe1dfd3faf8ecdfddd1f1efe3edebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfe2dfd8f7f4ed +e7e4ddfcf9f2f1eee5f8f5ece8e5dceeebe2edebdfedebdfedebdeedebdeedebdeedebde +edebdeebecdeeaeedfe7ead9f3e9ddf1e3dafaeaedf1e5e5e1e2d09da28b707163eeeadf +f4e7def7ede1ecebd9e5f0f6d3ebff2444ab1439bd001eae00119b001dc80030d32064f7 +1851b8e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdf +eceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff0ece0f7f3e7e7e3d7f7f3e7e8e4d8fefaee +f0ece0e6e2d6fffbeff5f1e5eae6daebe7dbfffff3e5e1d5f6f2e6e6e2d7fffbf2e6e2d9 +ece8dffffcf3ede9e0faf6edfbf7eeece8dfe3dfd6faf6edeae6dddad6cdfffff6ebe7de +f5f1e6e9e5d9fffff3e1ddd1ebe7dbf6f2e6d9d5c9faf6eaeeeadeefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfeeeadef4f0e4eae6daf2eee2dcd8ccfbf7ebf9f5e9 +f5f1e5f1efe2fffef1f7f5e8dddbcefaf8ebedebdedfddd0f9f7eaeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfebe9dcf8f6e9faf8ebe4e2d5fbf9ece9e7daf3f1e4e4e2d5eeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefe9ddf5efe3efe9dd +f1ebdfeeeadff4f0e5e8e4d9b0aca15c5a4e807e7265655b6b6b61717167727268727268 +6f6f65726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66726f66 +726f66726f66726f66726f66727064707163707163707064707064726f66726f68726f68 +726f6a716c68716c686f6a666d68626e675f6d665c6c655b6a665b736f64727064727064 +727064727064727064727064727064676559706e62656357e1dfd3fffff4f3f1e5fefcf0 +dedcd0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebe0efebe0efebdfefebdfefecddefecddefecdb +efecdbedeadbf0eddeebe7dbf1ede1ede9e0f1ede4fffdf9f7f2ecf1ede4f1ede4f1ede4 +f1ede4f1ede4f1ede4f1ede4f1ede4f1ede4f1ede4f1ede4f1ede4f1ede4f1ede4f1ede4 +f1ede4e2e0d4f9f7ebe9e7dbefede1e3e1d5fffff4e8e6daf5f3e7f7f5e9e9e7dbd1cfc3 +f4f2e6e6e4d8ebe9ddfbf9edf1efe3f0eee2f0eee2f0eee2f0eee2f0eee2f0eee2f0eee2 +f0eee2f0eee2f0eee2f0eee2f0eee2f0eee2f0eee2f0eee2f0eee2f2efe8eae7e0efece5 +e4e1daf3f0e7d7d4cbf7f4ebf3f0e7f0eee2f0eee2f0eee1f0eee1f0eee1f0eee1f0eee1 +eeefe1eaeedfebeeddf4eadeeddfd6f9e9ecfaeeeeeff0dea8ad96707163eeeadff4e7de +f7ede1ecebd9e5f0f6d3ebff2444ab1439bd001eae00119b001dc80030d32064f71851b8 +e2ebffefe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff3efe3f3efe3f4f0e4e4e0d4efebdfe8e4d8f2eee2e7e3d7 +f6f2e6eeeadee3dfd3f1ede1e5e1d5f8f4e8ddd9cdf8f4e8efebe0ebe7dcf1ede2f3efe4 +e7e3d8eeeadfe7e3d8e9e5daf1ede2fbf7eceae6dbf1ede2fefaefe8e4d9e1ddd2f0ece1 +e5e1d5efebdfe9e5d9efebdff4f0e4f9f5e9ece8dcf7f3e7efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff1ede1f6f2e6e3dfd3ede9ddfcf8eceeeaded9d5c9f3efe3 +d9d7cbf1efe3dfddd1efede1f3f1e5eceadeeeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +faf8eccbc9bdfaf8ecf2f0e4e4e2d6eeece0e8e6daf8f6eaeeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeee8dcf5efe3f4eee2f2ece0 +e8e4d9f3efe4ece8ddaeaa9f838077fbf8effffff8fffff8fdfdf5fcfcf4fffff7fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8fffff8 +fffff8fffff8fffff8fffff8fffff6fffff4fffff6fffff8fffff8fffffafffefbfffefb +fefaf7fdf9f6fcf7f3faf5eff9f4eef9f5ecfbf4ecf9f5eaf4f0e5f3f1e5f3f1e5f3f1e5 +f3f1e5f3f1e5f3f1e5f3f1e5fffff4f3f1e57b796debe9ddfffff4efede1dddbcffbf9ed +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebe0efebe0efebdfefebdfefecddefecddefecdbefecdb +eeebdcf1eedfebe7dbf1ede1ede9e0f1ede4fffdf9f6f1ebefebe2efebe0efebe0efebe0 +efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0 +fefcf0d5d3c7fffff4e7e5d9edebdff2f0e4e3e1d5e2e0d4f3f1e5f0eee2fffff4ebe9dd +fffff3f6f4e8e1dfd3e4e2d6eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0efece5efece5edeae3fffff8 +eeebe2f2efe6f0ede4eeebe2eeece0eeece0eeecdfeeecdfeeecdfeeecdfeeecdfeceddf +ecf0e1f1f4e3faf0e4eddfd6f5e5e8f5e9e9edeedca8ad96707163eeeadff4e7def7ede1 +ecebd9e5f0f6d3ebff2444ab1439bd001eae00119b001dc80030d32064f71851b8e2ebff +efe6ddeff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff8f4e8dcd8ccf4f0e4faf6eae6e2d6f7f3e7fffdf1f2eee2dfdbcf +f0ece0f4f0e4f9f5e9e4e0d4f3efe3f4f0e4e7e3d7f7f3e8f2eee3f0ece1f1ede2f3efe4 +dbd7ccfffff4ebe7dcf0ece1e8e4d9dedacff8f4e9f3efe4e3dfd4fcf8edefebe0f7f3e7 +e8e4d8f5f1e5eeeadef1ede1e9e5d9f3efe3e3dfd3efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff8f4e8e9e5d9faf6eaeae6daede9ddece8dcfffcf0e6e2d6fffff4 +d9d7cbfffff4eae8dceeece0efede1f9f7ebebe9ddeeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0e3e1d5 +fffff4e1dfd3e9e7dbe5e3d7efede1eceadef5f3e7eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfeee8dcf2ece0f5efe3f5efe3e5e1d6 +f1ede2efebe0b0aca1605d54fcf9f0fffff8fffff8fafaf2fffff8fffff8fffffafffffa +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefbfffffafffefb +fffffafffefbfffffafffff8fffff8fffff8fffffafffffafffffbfffefdfffefdfffefd +fffdfcfffcf9fffbf7fffaf6fffbf5fffcf4fffef5fffff4fffff4fffff4fffff4fffff4 +fffff4fffff4fffff4faf8ecaba99d6c6a5ef8f6eafffff4e3e1d5f1efe3e1dfd3efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebe0efebe0efebdfefebdfefecddefecddefecdbefecdbefecdd +f1eedfece8dcf1ede1ede9e0f0ece3fffcf8f5f0eaeeeae1eeeadfeeeadfeeeadfeeeadf +eeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadfe5e3d7 +fcfaeee1dfd3f3f1e5f1efe3dedcd0fffff4f2f0e4f2f0e4dfddd1dfddd1f9f7ebd6d4c8 +faf8ecf5f3e7f2f0e4edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfedebdfedebdfebe8e1f0ede6eeebe4d5d2cbefece3 +fffdf4edeae1e7e4dbedebdfedebdfedebdeedebdeedebdeedebdeedebdeebecdee4e8d9 +ebeeddfaf0e4f2e4dbf8e8ebf3e7e7eaebd9a7ac95707163eeeadff4e7def7ede1ecebd9 +e5f0f6d3ebff2444ab1439bd001eae00119b001dc80030d32064f71851b8e2ebffefe6dd +eff2e1e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfebe7dbfaf6eaeeeadee2ded2f7f3e7f0ece0d6d2c6f3efe3fffdf1f1ede1 +dbd7cbf0ece0efebdfede9ddf5f1e5f0ece0ede9dedfdbd0f2eee3fefaefe9e5dafefaef +eae6dbe6e2d7e7e3d8fffff4f0ece1eae6dbeae6dbfaf6ebdfdbd0f7f3e8ece8dcede9dd +eeeadedad6cafcf8ecede9ddf0ece0f6f2e6efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfe2ded2efebdfeeeadef9f5e9ebe7dbf4f0e4ede9ddf3efe3e6e4d8f4f2e6 +dedcd0eceadef6f4e8eeece0f1efe3e9e7dbeeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0efede1f1efe3 +f0eee2edebdffbf9edeae8dcf2f0e4dfddd1eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdff1ebdfede7dbf2ece0f7f1e5e7e3d8f2eee3 +f0ece3aeaaa179766ffffff8f9f8f3fdfcf7fefdf8fffffafffffafffffbfffffbfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffbfffffdfffffb +fffffdfffffbfffffafffffafffffafffffbfffffdfffffdfffefffffefffffbfcfdf9f8 +faf6f5f7f3f0f5f0ecf5f0eaf5f1e8f6f2e9edebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdff5f3e7afada1716f63e4e2d6fffff4eae8dcf4f2e6f9f7ebefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebe0efebe0efebdfefebdfefecddefecddefecdbefecdbefecddf1eedf +ece8dcf1ede1ede9e0f0ece3fffcf8f5f0eaefebe2efebe0efebe0efebe0efebe0efebe0 +efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0efebe0eceadef2f0e4 +e3e1d5eae8dcfffff40301000301000a0800030100fbf9edfaf8eceae8dce5e3d7eeece0 +f7f5e9eceadeeeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0fcf9f2dddad3f6f3ec15120bf1eee5c9c6bd +fffff6ebe8dfeeece0eeece0eeecdfeeecdfeeecdfeeecdfeeecdfeceddfe5e9dae7ead9 +f6ece0f4e6ddfdedf0f6eaeaeceddbacb19a707163eeeadff4e7def7ede1ecebd9e5f0f6 +d3ebff2444ab1439bd001eae00119b001dc80030d32064f71851b8e2ebffefe6ddeff2e1 +e8edd9eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff5f1e5e7e3d7f4f0e4f7f3e7ebe7dbede9ddfcf8ecede9dde0dcd0fcf8ecf0ece0 +f2eee2ece8dcefebdff1ede1ece8dcf1ede2f1ede2f3efe4dedacff9f5eaeae6dbede9de +f4f0e5eae6dbf2eee3ebe7dcebe7dcfaf6ebddd9cef5f1e6e7e3d8ede9ddece8dcf0ece0 +fefaeeece8dce6e2d6f9f5e9e3dfd3efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff6f2e6ede9dd0d09000400000400000e0a00040000f2eee2040200eeece0030100 +f1efe3eceadee5e3d7f8f6eaedebdfeeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0ebe9dd030100eeece0 +f0eee2e9e7dbeceadef5f3e7efede1eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0eeece0efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdff4eee2eae4d8eee8dcf9f3e7eae6dbf3efe4efebe2 +a9a59c6a6760fffff8faf9f4fffffafffffafdfcf8f7f6f2fffffbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfbfefdfb +fefdfbfdfef9fdfef9fdfef9fdfdfbfefcfdfefcfdfefcfdfefcfdfffefffffefffdf9f8 +f7f3f0f3eeeaf0ebe5eeeae1eeeae1eeece0eeece0eeece0eeece0eeece0eeece0eeece0 +eeece0eeece0a4a2967d7b6ffaf8ecf7f5e9efede1f4f2e6e3e1d5efebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebe0efebe0efebdfefebdfefecddefecddefecdbefecdbefecddf2efe0ece8dc +f1ede1ede9e0f0ece3fffcf8f5f0eaeeeae1eeeadfeeeadfeeeadfeeeadfeeeadfeeeadf +eeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadfeeeadfe9e7dbf3f1e5eeece0 +f1efe3030100f9f7ebebe9ddefede1edebdf060400e5e3d7eeece0fcfaeeeceadee7e5d9 +efede1edebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdfedebdf +edebdfedebdfedebdfedebdfedebdfe7e4ddf8f5eeece9e2030000f3f0e7f7f4ebf2efe6 +e7e4dbedebdfedebdfedebdeedebdeedebdeedebdeedebdeebecdef4f8e9ecefdef4eade +f0e2d9f9e9ecf1e5e5e8e9d7abb099707163eeeadff4e7def7ede1ecebd9e5f0f6d3ebff +2444ab1439bd001eae00119b001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dc +eeeddbefebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f3efe3f3efe3040000ede9ddeae6daf6f2e6f0ece0e7e3d7f2f0e4dfdcd30d0a01f1eee5 +e9e6ddf3f0e7e9e6ddf2efe6eae7def8f5eceeebe2f2efe6ebe8dfeeebe2eae7def3f0e7 +eae7deedeae1e4e1d8fefbf2e6e3daedeae1f1eee5e9e6dd050200e9e6ddfbf8efe8e5dc +e7e4dbfffdf4030000f2efe6f3f0e7efece3f7f4ebebe8dfe9e6ddf6f3ead8d5ccfaf7ee +edeae1f1eee5edeae1f0ede4f1eee5e3e0d7f5f2e9eeece0f0ece0fbf7ebeae6daede9dd +fcf8ecede9ddf5f1e5eae6daefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdff3eddfeee8daf5efe3eee8dcefebe0f0ece1f1ede4aca89f +6e6b64fffffafffffbfffffbfffffbfbfaf8020100fdfcfafcfafbfffefff4f2f3010000 +fffeff010000fdfbfcfffefffffefffefcfdfffeff030102fffeff040203f6f4f5080607 +f7f5f6fffefffbf9faf8f6f7fdfbfcfefcfdfffdfefffefffffefff6f4f5fefcfdf8f6f7 +fffefffffefffefcfdfffeff010000fffeff050304e9e7e80d0b0cfffefff9f7f8fffeff +fffeff010000fffeff010000fffeff070506f2f0f1fffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffffd +fffffdfefffdfefffdfefffffffffffffffffffefffffefffffefff8f6f7fdf9f8fffdfa +e7e4dff4f1eaebe8dfeeebe2f0eee2eceadeeceadeefede1f3f1e5eae8dcfffff3dfddd1 +efede1a9a79b757367f0eee2fffff4edebdfedebdfefede1efebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebe0efebe0efebdfefebdfefecddefecddefecdbefecdbeeebdcf1eedfece8dcf2eee2 +eeeae1f0ece3fffcf8f4efe9efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfeeece0f3f1e5e2e0d4f4f2e6 +030100f1efe3f0eee2edebdff3f1e5e5e3d7fbf9ede9e7dbf6f4e8f1efe3e8e6daf6f4e8 +e7e5d9eceadef6f4e8eae8dcfaf8ece1dfd3faf8ecf0eee2eeece0f3f1e5eae8dcf0eee2 +e8e6daf1efe3e5e3d7f8f6eaf8f5eeece9e2edeae3030000ebe8dfeae7deeeebe2eae7de +eeece0eeece0eeecdfeeecdfeeecdfeeecdfeeecdfeceddfecf0e1e8ebdaf7ede1f3e5dc +f6e6e9f4e8e8eeefdda7ac95707163eeeadff4e7def7ede1ecebd9e5f0f6d3ebff2444ab +1439bd001eae00119b001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddb +efebdfefeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfe6e2d6 +f4f0e4040000fffff3e5e1d5efebdfece8dcfffbefeae7defcf9f0030000e4e1d8f2efe6 +f0ede4f6f3eaece9e0e8e5dce0ddd4f1eee5f6f3eae5e2d9f6f3eae4e1d8f3f0e7f2efe6 +faf7eef2efe6e0ddd4f7f4ebeae7def9f6ededeae1070400e9e6dde2dfd6fffff6e9e6dd +e2dfd6030000e8e5dce4e1d8f4f1e8e1ded5e6e3daf6f3eaece9e0fffff6dfdcd3d6d3ca +fffff6d9d6cdf2efe6edeae1ece9e0f0ede4eae8dce4e0d5e4e0d4f1ede1eeeadef2eee2 +e8e4d8eeeadef1ede1efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdff3eddfeee8daf5efe3eee8dcefebe0f0ece1f1ede4aca89f726f6a +fffffafffffbebeae6fffffdfffffd010000fffefffffefffffefffffeff0d0b0cf3f1f2 +010000fffefffffefffffeffedebec171516edebecfffefffffefffaf8f9010000fffeff +fffdfefffefffdfbfcfffefff7f5f6fcfafbfffefff9f7f8fffefffffefffffefffcfafb +f9f7f8fefcfd010000fffefff4f2f3f5f3f4292728f6f4f5f1eff0fffefffffefffefcfd +fdfbfc020001fffefffffdfefffeff010000fffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffeff +fffefffffefffffefffffefffffefffffefffffefffffefffffefffffefffffffffefffd +fefffdfefffffefffffffffffffffffffefffffefffdfbfcfcfafbf1edecfffdfaf3f0e9 +eeebe2e5e2d9f2f0e4eceadef1efe3f2f0e4e9e7dbe7e5d9faf8ecdad8ccfffff4efede1 +a9a79b757367f0eee2fffff4edebdfedebdfefede1efebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0 +efebe0efebdfefebdfefecddefecddefecdbefecdbeeebdcf1eedfece8dcf2eee2eeeae1 +f0ece3fffcf8f4efe9efebe0efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdff4f2e6ebe9ddefede1f2f0e4030100 +e9e7dbefede1f5f3e7efede1edebdffaf8ecd4d2c60c0a00060400030100edebdff3f1e5 +030100eeece0030100030100f2f0e4d4d2c6f6f4e8070500030100050300eeece0eeece0 +fdfbef030100030100030000e1ded7f5f2eb16130cebe8dfe7e4dbe6e3daf2efe6eeece0 +eeece0eeecdfeeecdfeeecdfeeecdfeeecdfeceddfecf0e1e8ebdaf7ede1f3e5dcf6e6e9 +f4e8e8eeefdda7ac95707163eeeadff4e7def7ede1ecebd9e5f0f6d3ebff2444ab1439bd +001eae00119b001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdf +efeae4f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefecddefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff1ede1ede9dd +040000e8e4d8f1ede1efebdff3efe3e8e4d8030000f7f4eb030000f7f4ebeeebe20e0b02 +060300030000fffff6f0ede4dfdcd3090600070400e4e1d8fcf9f0e2dfd6e3e0d7eae7de +f0ede4060300030000070400e6e3daf9f6ed030000040100f0ede4e0ddd4eae7deedeae1 +151209030000f2efe6030000fffdf4f3f0e7030000efece30300000f0c031a170e030000 +efece3f4f1e8e4e1d80c09000d0a01030100f4f0e5fffff3040000f7f3e7e8e4d8f3efe3 +f7f3e7eae6daefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdff3eddfeee8daf5efe1eee8dcefebe0f0ece1f1ede4aca89f6e6b66f3f0eb +f5f4f0fffffdf5f3f4070506fffeff010000f8f8f8f2f2f2fbfbfb090909f8f8f8030303 +fffffff3f3f3ffffffffffff000000fffffffcfcfcf8f8f8ffffff060606f1f1f1fcfcfc +fffffffffffff0f0f0fffffffffffff3f3f3fffffffffffff5f5f5eeeeeeffffffffffff +f6f6f6040404fcfcfcffffff010101ececec000000fffffffffffffafafaffffff000000 +fcfcfc060606f4f4f4fefefe0b0b0bf7f7f7ffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffdfefffd +fefffffefffffefffffefffffffffffffffffffefffffffde8e7e3fdfcf7f2efe8f0ede4 +f5f3e7e8e6dae7e5d9eeece0fefcf0e3e1d5f4f2e6e3e1d5eae8dceae8dcefede1a9a79b +757367f0eee2fffff4edebdfedebdfefede1efebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0efebe0 +efebdfefebdfefecddefecddefecdbefecdbeeebdcf1eedfece8dcf2eee2eeeae1f0ece3 +fffcf8f4efe9efebdfefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefebdff8f6eadddbcffbf9ede2e0d40c0a00eceade +d6d4c8f7f5e9e6e4d8fffff3dddbcffefcf0f6f4e8e3e1d5f6f4e8030100f4f2e6030100 +030100f4f2e6fbf9ed040200e9e7db080600e7e5d9fffff4e0ded2060400f2f0e4030100 +f6f4e8ebe9ddf0ede6030000e9e6df030000eae7def3f0e7fcf9f0e8e5dceeece0eeece0 +eeecdfeeecdfeeecdfeeecdfeeecdfeceddfecf0e1e8ebdaf7ede1f3e5dcf6e6e9f4e8e8 +eeefdda7ac95707163eeeadff4e7def7ede1ecebd9e5f0f6d3ebff2444ab1439bd001eae +00119b001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4 +f1eae4f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecddefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdff8f4e8faf6ea0b0700 +040000090500161206e5e1d5f1ede20f0c03eae7de0d0a01ece9e0030000e7e4dbe6e3da +f7f4eb030000edeae10d0a01e1ded5ece9e0060300ebe8dff1eee5efece3fcf9f0030000 +eae7defffff6edeae1030000ebe8df030000f2efe6f6f3eaf6f3eaeeebe2e7e4db030000 +f3f0e7f2efe6030000f4f1e8e8e5dc030000fffcf30c0900e2dfd6e1ded5dcd9d0030000 +fffcf3030000f1eee5e5e2d9eeebe20e0a00d6d2c6f0ece0f5f1e5eae6daf2eee2ece8dc +eeeadeefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdff3eddfeee8daf5efe1eee8daefebe0f0ece1f1ede4aca7a17a7772fffefbfffffd +f5f4f2fffeff010000fffeff010002fffffffffffffbfbfb000000ffffff000000ffffff +fcfcfcfafafafdfdfd0000000e0e0efafafa000000f8f8f8000000ffffffffffff060606 +000000080808f4f4f4fffffffefefe000000030303fffffffcfcfcffffffecececffffff +000000fffffffffffffbfbfbfffffffffffff1f1f1fffffff3f3f3f2f2f2ffffffffffff +f8f8f8fffffff7f7f70c0c0cf7f7f7ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffdfefffdfeffff +fefffffefffffefffffffffffffffffefcfdfdfcfafdfcf7fffff8dad7cefffff4dfddd0 +0503000503000301000301000301000f0d010d0b00eeece0f5f3e7efede1a9a79b757367 +f0eee2fffff4edebdfedebdfefede1efebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0efebe0efebdf +efebdfefecddefecddefecdbefecdbeeebdcf1eedfece8dcf2eee2eeeae1f0ece3fffcf8 +f4efe9efebdfefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefecdddbd9cdfffff4dcdacef0eee2080600f9f7ebfffdf1 +e6e4d8ebe9dde5e3d7fdfbefdfddd10705000301000301000f0d01eeece0070500e4e2d6 +e1dfd3e8e6da110f03f2f0e4030100f5f3e7dfddd1faf8eceeece0f3f1e50301000e0c00 +030100030000030000fffff8030000e7e4dbf1eee5edeae1e6e3daeeece0eeece0eeecdf +eeecdfeeecdfeeecdfeeecdfeceddfecf0e1e8ebdaf7ede1f3e5dcf6e6e9f4e8e8eeefdd +a7ac95707163eeeadff4e7def7ede1ecebd9e5f0f6d3ebff2444ab1439bd001eae00119b +001cc70738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4 +f6e8dff5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfe2ded2e3dfd3040000faf6ea +f5f1e5ede9ddeeeadef6f2e7030000f1eee70b0801e4e1da090600030000030000030000 +120f08e9e6dff7f4ed030000f2efe8f6f3ecdfdcd5fcf9f2f2efe8e7e4dd030000e4e1da +eeebe4e4e1da131009edeae3080500eae7e0ece9e2e3e0d9ece9e2f5f2eb030000f1eee7 +f2efe8030000e5e2dbfaf7f0040100e5e2db030000f1eee7fbf8f1f1eee714110ae3e0d9 +0401000300000e0b04030000040000eeeadef8f4e8f4f0e4e7e3d7eeeadef5f1e5fcf8ec +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +f3eddfeee8d8f5efe1eee8daefebe0f0ece1f1ede4aca7a166635efcf8f5fffffdfffeff +060407fffeffedebf0fffeff000000fffffffcfcfc010101ffffff000000f6f6f6ffffff +fffffffefefe060606f1f1f1ffffff0c0c0cffffff000000ffffff000000fbfbfbffffff +eeeeee191919e9e9e9000000fffffff5f5f5000000fcfcfcfffffffffffff2f2f2030303 +fbfbfbfefefefcfcfcfefefefffffff9f9f9fffffffffffffffffff5f5f5fafafafdfdfd +fdfdfdf5f5f5020202ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffefffdfcfffdfcfffffcffff +fefffffefffffffffffffffffbfbf9fffffbe3e2ddfefef6fbfbefddded0e1e2d2f1f2e2 +070500030100070500030100030100f0eee2f1efe3e5e3d7efede1a9a79b757367f0eee2 +fffff4edebdfedebdfefede1efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0efebe0efebdfefebdf +efecddefecddefecdbefecdbeeebdcf1eedfece8dcf2eee2eeeae1f0ece3fffcf8f4efe9 +efebdfefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefecddf4f2e6f1efe3f1efe3e6e4d8070500e6e4d8dddbcfeae8dc +f5f3e7eceadeedebdf0d0b00eeece0efede1e6e4d8030100e9e7db060400fffef2f8f6ea +edebdf030100e9e7db040200ebe9ddfffff4edebdfe7e5d9e4e2d6131105cbc9bdfefcf0 +e8e5def3f0e9e8e5de050200fffff6d3d0c7f7f4ebf8f5eceeece0eeece0eeecdfeeecdf +eeecdfeeecdfeeecdfeceddfecf0e1e8ebdaf7ede1f3e5dcf6e6e9f4e8e8eeefdda7ac95 +707163eeeadff4e7def7ede1ecebd9e5f0f6d3ebff2444ab1439bd001eae00119b001cc7 +0738db1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8df +f5e9dbefebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdffcf8ecf9f5e90b0700e8e4d8f0ece0 +f1ede1f8f4e8e9e5da100d04fffef7030000ebe8e1040100f5f2ebeeebe4eae7e0ece9e2 +e6e3dcf1eee7f9f6ef080500ece9e2e2dfd8eae7e0edeae3f5f2eb030000fffdf6fefbf4 +e5e2db030000efece5030000f4f1eadedbd4fbf8f1eeebe4f3f0e9030000f0ede6eeebe4 +030000edeae3eeebe4090600efece5030000edeae3e7e4ddedeae3030000eae7e00e0b04 +e9e6dff0ede6faf7eeebe7dcf1ede1e8e4d8faf6eaf5f1e5e8e4d8fefaeee0dcd0efebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddf3eddf +eee8d8f5efe1eee8daefebe0f0ece1f1ece6aca7a1777370fffcf9fffdfefffeff010002 +fffefff2f0f5fffeff171717e8e8e8fdfdfd111111f2f2f2161616e8e8e8fffffff4f4f4 +ffffff000000fffffffdfdfd000000f6f6f60e0e0efbfbfb090909000000010101000000 +000000ffffffffffff0d0d0deeeeeeffffffffffffffffffeeeeeeffffff000000ffffff +fafafafffffff8f8f8fcfcfcffffffebebebfbfbfbf8f8f8fffffffafafaf9f9f9fefefe +ffffff000000fcfcfcffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffefffdfefffdfcfffdfcfffffcfffffeffff +fefffffffffffffffdfffffbf4f5efe8e8e0fffff6ddddd1eff0e0ffffefe8e9d9e5e3d6 +030100090700060400f8f6eaf8f6eaf3f1e5f0eee2efede1a9a79b757367f0eee2fffff4 +edebdfedebdfefede1efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebe0efebe0efebdfefebdfefecdd +efecddefecdbefecdbeeebdcf1eedfece8dcf2eee2eeeae1f0ece3fffcf8f4efe9efebdf +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefecddf3f1e5dad8ccfffff4fbf9ed030100edebdffffff4ebe9ddefede1 +030100f0eee2030100eeece0e5e3d7fefcf0030100eceade050300e5e3d7e8e6dae9e7db +110f03e7e5d90b0900ebe9dde9e7dbf1efe3050300fcfaee131105eae8dcf0eee2f8f5ee +030000f6f3ec0b0801e0ddd4f8f5ecf3f0e7e5e2d9eeece0eeece0eeecdfeeecdfeeecdf +eeecdfeeecdfeceddfecf0e1e8ebdaf7ede1f3e5dcf6e6e9f4e8e8eeefdda7ac95707163 +eeeadff4e7def7ede1ecebd9e5f0f6d3ebff2444ab1439bd001eae00119b001cc70738db +1c60f31c55bce0e9fff4ebe2e8ebdaebf0dceeeddbefebdfefeae4f1eae4f6e8dff5e9db +efebdfeceddfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecddefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfe6e2d6e8e4d8040000fdf9edefebdfeae6da +e7e3d7f3efe4030000e8e5de060300f6f3ec030000efece5e5e2dbf5f2eb040100f6f3ec +030000edeae3e0ddd6030000fffff8e7e4ddf4f1eae4e1da030000e9e6dfebe8e1ebe8e1 +17140de4e1da050200eeebe4f9f6efe2dfd8fffdf6e4e1da030000f1eee7eae7e0fffff8 +030000030000eeebe4f1eee7030000f4f1eaefece5f6f3ec030000f6f3ec030000f9f6ef +efece5dbd8cf040000fbf7ebece8dce7e3d7fbf7ebe7e3d7cfcbbffffff3efebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefecddf3eddfeee8d8 +f5efe1eee8daefebe0f0ece1f1ece6aca7a1706c69fffefbfffeffe8e6e70b090c060409 +010005050308000000fffffdfffffd000000fffffd000000fffffdfffffdfffffdfffffd +000000fcfcfafffffd030301fffffd000000fffffd000000fffffdfffffdfffffdfbfbf9 +fffffde1e1dff8f8f6020200fffffdfffffdfafaf8f6f6f4fffffd000000fdfdfbf6f6f4 +fffffdfffffdfbfbf9fffffdfffffdfffffdfffffdfcfcfafffffdfdfdfbfefefcf4f4f2 +000000fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffdfffffd +fffffdfffffdfffffdfffffdfffffdfefffdfefffdfcfffbfcfffdfcfffdfefffdfefffd +fefffdfefffdfefffaeff0eaf6f7effffff4e9eadcdfe0d0e2e3d1e4e5d3fffff2e8e6da +030100efede1f1efe3e2e0d4e8e6daedebdfefede1a9a79b757367f0eee2fffff4edebdf +edebdfefede1efebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdfefebdf +efebdfefebdfefebdfefebdfefebdfefebdfefebe0efebe0efebdfefebdfefecddefecdd +efecdbefecdbeeebdcf1eedfece8dcf2eee2eeeae1f0ece3fffcf8f4efe9efebdfefecdd +efecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecddefecdd +efecddefecdde3e1d5f8f6eaedebdfe2e0d4f7f5e9030100030100030100090700e2e0d4 +efede1f0eee2050300030100040200070500eceade090700f2f0e4e6e4d8faf8ec090700 +e0ded2eceade090700060400030100eceadee6e4d8e3e1d50c0a00030100030000e9e6df +eeebe4030000ece9e0f3f0e7e9e6ddf0ede4eeece0eeece0eeecdfeeecdfeeecdfeeecdf +eeecdfeceddfecf0e1e8ebdaf7ede1f3e5dcf6e6e9f4e8e8eeefdda7ac95707163eeeadf +f4e7def7ede1ecebd9e5f0f6d3ebff2444ab1439bd001eae00119b001cc50838da1c60f3 +1f54bce2e8fff5ebe2ebe9dcecefdeefecdbf1ebdff1eae4f2e9e2f5e9dbf3ead9eeedd9 +ebeedbecedddeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecddeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecddeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdff3f1e4f0eee1030100eae8dbedebdeeeecdff3f1e4 +eceade090900eeeee4010100efefe5edede30101000c0c02010100ecece2e9e9dfeeeee4 +0d0d03010100e6e6dcedede3e2e2d8eaeae0ebebe1f6f6ec010100010100010100e6e6dc +f6f6ec0b0b01e3e3d9f5f5ebe7e7dde3e3d9f4f4eaf3f3e9010100efefe5d8d8ce131309 +eeeee4eeeee4ddddd3101006010100060600010100f5f5ebe6e6dce8e8de010100060600 +060600f5f3e7dedccf0c0a00efede0e6e4d7f3f1e4fbf9ecdedccfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdff0eedfebead8f2f0e1 +ebe9dceeece0edede1f0ede4a9a9a16e6d68fffffbfffffd060606fffffff7f6fbfefdff +fffffffeffff000100fefffd030502fefffd040603fefffdf8faf7f5f7f4fefffd000200 +fbfdfafefffd000100fafcf9060805fefffd000100fefffdf9fbf8eceeeb0a0c09f1f3f0 +121411fefffdfafcf9000100f6f8f5fdfffcfefffde9ebe80b0d0afefffdfefffdf7f9f6 +fefffdf8faf7f5f7f4fefffdf9fbf8fafcf9fefffdfefffdf9fbf8fefffdfefffd050704 +fbfdfafefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffdfefffd +fefffdfefffdfefffdfefffdfcfffdfcfffdfcfffdfcfffffcfffffcfffffcfffdfefffd +fefffdfefffbfefffaf1f4ebf1f4e9eceee0f5f8e7e2e5d4f4f7e6e5e6d8eceddfebecde +f1f2e4eaebddebecdefefff1e0e1d3edeee0a7a89a737466eeefe1fffff3ebecdeebecde +edeee0eeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdfeeecdf +eeecdfeeecdfeeecdfeeecdfeeecdfeeece0eeece0eeecdfeeecdfeeecddeeecddeeecdd +eeecddedebdcf0eedfebe9dcf1efe2edebdfefece3fffdf6f3f0e7eeecdfeeecddeeecdd +eeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecddeeecdd +eeecdff8f9ebddddd1edede1f1f1e5ebebdfefefe3efefe3eeeee2e0e0d4fffff4edede1 +e1e1d5e7e7dbf9f9ede2e2d6edede1f4f4e8e7e7dbe5e5d9fefef2e0e0d4dbdbcffffff3 +e9e9dde9e9ddedede1f3f3e7f4f4e8e8e8dcf4f4e8dbdbcff5f5e9ebebe1f4f4eaeaeae0 +deded4fafaf0e7e7dbe9e9dff0f0e4ecece0ecece0eceddfeceddfeceddfeceddfeceddf +eceddfedefe2e9e9ddf6eee1f2e5ddf5e7e7f3e9e7f0efdda9ab95727063f0e9e1f2e7e1 +f6ede4e9ecdbe3f0f6d5ebff2643ab1638bd001eae00119b001cc20a38d61e5fef2253ba +e4e7fff8e9e4eee7ddf0ece0f3e9ddf3e9dff2e9e2f2e9e0f5ead6f2ecd2ebf0d2e8f1d4 +eaefdbeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0 +eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0 +e3e7d9f6faecd9ddcff6faeceaeee0e3e7d9f2f6e8ebefe1eaeee0dee2d4101406ecf0e2 +e6eadce3e7d9000300e7ebddeaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0eaeee0 +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeef2e1e3e7d6e8ecddf2f6e7 +e5e9dbedf3e5ecefe4a6aca2797e77e7ece6fbfffa000300fcfffff0f4f5fcfffff9fdfc +fbfffd000500f9fffd000300f9fffd07100bf3fcf7f6fffaeef7f2f9fffd000300f9fffd +eff8f3000803f1faf5050e09f9fffde2ebe6040d08020b06000300f9fffdf9fffdf3fcf7 +00030009120df4fdf8f3fcf7f9fffdf9fffdf3fcf7000300f4fdf8f5fef9f9fffdf2fbf6 +f9fffdeef7f2050e09eef7f2f9fffdf3fcf7f9fffdedf6f1f9fffdf7fffb0d1611f0f9f4 +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffdf9fffd +f9fffdf9fffdf9fffdf9fffffbfffffbfffffbfffffbfffffbfffffbfffffcfffffcfffd +fcfffbf9fef7e9efe5fcfff6e8eee2e4eadce7eddfe6eddde9eddce9eddce9eddce9eddc +e9eddce9eddce9eddce9eddcebefde999d8c737766eff3e2fcffeff1f5e4e5e9d8e7ebda +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +eaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeedf +e4e8d9f2f6e7e5e9dae3e7d8e2e6d7eef2e4fefff4e8ecdee8ecdde8ecdde8ecdde8ecdd +e8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdd +e8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdd +e8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdd +e8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdee8ecdee8ecdee8ecde +e8ecdee8ecdde8ecdee8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde8ecdde9ebde +edeae5ede8e4e9e2d8fff8eef0e8e5e9e4def5f0ddaba6927b7269efe5e3f4eae8efeae4 +e0e6d8d7e6edddefff263da51738bd001eae00119b001cc20a38d61e5ff12253bae4e7ff +fae8e6eee7dff0ece1f3e9e0f5e8e0f2e8e6f2e9e2f3ead9f1edd4eaf0d4e8f1d6ebeedb +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddfcfdef +cccfbefffff3e5e8d7e8e9db0003000607000003000102001a1d0cd2d3c5eaeddcf6f7e9 +ebeedd151608f0f3e2eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeff2e1e9eddcecefdeeff3e2e0e2d4 +e8ecdee5e7daa1a49964655dfefffafffffaf4f6f1f1f1effefffdf6f6f4fefffdfcfffd +e6ebe5fcfffbfcfffbe3e8e2fcfffbf8fdf7fcfffbfcfffbf1f6f0f3f8f2fcfffbfbfffa +fcfffbfcfffbeef3edf2f7f1fafff9fafff9fcfffbf7fcf6fcfffbfcfffbfcfffbfcfffb +e6ebe5fcfffbf6fbf5fcfffbfbfffaeef3ed121711fcfffbfcfffbf5faf4fcfffbeff4ee +fcfffbf6fbf5fcfffbeef3edfcfffbfcfffbf8fdf7fcfffbeef3ed000200fcfffbfafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9fafff9 +fafff9fafff9fafffbfcfdfffcfdfffdfcfffcfdfffdfdfffcfefdfdfdfdfcfefbfafbf6 +fefffaf9faf2fefff6edefe4e6eadcebede0f3f5e7ecefdeecefdcedeedcecefdcedeedc +ecefdcedeedcecefdcf8f9e7a5a895717260e8ebd8f9fae8ebeedbeeefddeef1deeceddd +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddf +ebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedde3e4d6 +eff2e1f0f1e3f7fae9f0f1e3ebeeddfcfdefebeeddeeefe1edf0dfeeefe1edf0dfeeefe1 +edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1 +edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1 +edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1 +edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1 +edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1edf0dfeeefe1eeeee2f5f0ec +f4efe9e9e5d9f8f6e9ebe8dfedebdffbf6e0b5af996e645aefe4e0f6eeebdeded6f8fff2 +e0f1f8d3e3ff3248ae1738bd001eae00119b001dc50739da1c60f31f54bee2e8fff7e9e8 +ece7e1efece5f2e9e4f2e8e6f1e8edf1e8ebf3e8e4f1eae0eaeee0eaeee0efecddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbe9dfd3faf3e3 +f4eadef7f0e0f6ece0e5decefff8ecfdf6e6e9dfd3f4edddf0e6daede6d6fffaeee7e0d0 +e8ded2e8e1d1f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf1eadaf1ebdbf4edddf4eedeebe3d6f6f0e2 +f3ebe0b0a99f847b72f3ece4fff9f4fffdfafffcfaf7efedfffcfbf4ece9fffdfafffefa +fffcf8fffefafdf8f4fffdf9fffefafbf6f2f9f4f0fffefafffefafffcf8fffefafef9f5 +fffefafffefafffefafffefafffefafffbf7fffefafef9f5fffefafffdf9fffbf7fffdf9 +fffefafffcf8f8f3effffefafffefafaf5f1040000fffefafffefaede8e4fffefaf6f1ed +fffdf9fffbf7fffefafdf8f4fffefafdf8f4ece7e3100b07fffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefafffefa +fffefafffdfbfffcfffffcfffffbfffffcfdfffcfdfffdfbfffcfbfffdfafbf2edfffef6 +f1e8e1f7f0e6f7eee5f8f2e6f1e9def3ebdef0e9d9f0e9d7f1e8d7f0e9d7f1e8d7f0e9d7 +f1e8d7f0e9d7f0e7d6afa8967c7362f5eedcfffeedf0e9d7f9f0dff0e9d9f3eadbf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdb +f3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbf3e9ddf2ebdbfff5e9f3ecdc +e8ded2f1eadaf4eadef6efdffffdf1fffbebf1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9 +f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9 +f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9 +f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9 +f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9 +f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e9d9f1e7dbf0e8dbf1eae0f1ede1 +e7e6d2edefd9e3e4d4e8e9d7efeed0aca88b6f6657fffdf4e1ddd4fffff4d2e0c9ddf1f0 +def1ff21399d1738bb001eae00119b001ec3043ad81a61f11c56bae0e9fff4ebe4e9e9dd +edeee0efebe0f1eae4efe9edf1e8edf2e8e7f1eae4eaede6eaede6f2e9e2f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff4e5defff3eae8d9d2 +f3e5dcf5e6dffff6edfff0e9e3d5ccf6e7e0f5e7defff0e9fff3eae8d9d2faece3fff2eb +faece3f6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff1e4dbf6eadef5e8dff6e9e0f4e7defff3ebf7eae4 +b5a8a270625ffff7f6fffbfbfffbfbfffafdfff1f4fffafdfffafdfffbfdfffafaf0e4e4 +fffbfbfffbfbfff4f4fff9f9fffbfbfffbfbfdf1f1fff8f8fef2f2fffbfbfffbfbece0e0 +fffbfbfbefeffffbfbfff7f7fffafafcf0f0fffbfbfffbfbfcf0f0fffbfbfcf0f0fff7f7 +fcf0f0fffbfbfffbfbf3e7e7fffbfbfffafafffbfbfffbfbfffbfbfffbfbf5e9e9fffbfb +fffafafffbfbfffbfbfff5f5fffbfbfffbfbf6eaeafffbfbfffbfbfffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafafffafa +fffafcfff9fffff8fffff9fffff9fffff9fefff9fefff9fcfff9fcfff7f7fffbfaecdedd +cdbfbcb4a6a3ab9e98a69993b9aca4b4a69db4a69db4a69db4a69db4a69db4a69db4a69d +b4a69db8aaa19e908783756cfef0e7fffcf3f3e5dcfaece3ebddd4f6e8dff6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0 +f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff6e7e0f6e8dff8e9e2f3e5dcf2e3dc +f6e8dff4e5def8eae1feefe8f4e6ddf9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3 +f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3 +f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3 +f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3 +f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3 +f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f9ebe2f9eae3f8ebe3f0e9dff3f1e4eff1db +f3f5dfebeeddeff0dee9e9cdaca88d746c5fece3dcf0ebe5dfe2d7e1f0dbe7fbfce9feff +2942a61738bd001eae00119b0020be033cd31963ea1b58b3dfecfff3eedae8ecd3ebf1d5 +eeeed6efecdbefeae4efeae7f2e9e2f1eae2eaede4ebece7f2e8e7f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7fcecefeededff6e6e9ebdbdc +fff2f5e5d5d6fff0f3ffeff0ffeff2f5e5e6f0e0e3eddddef8e8ebecdcddfff4f7edddde +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e8e8f9ebeaf2e4e4f3e5e5f4e6e6f9eaedeadbdeae9fa4 +85767dfffafffff9fffff7fffff5fffff9fff8e8f5fff9fffef1fbfffafffffafffff6ff +fffafffffafffff8fffff6fffdf0fafffafffff5fffffafffffafffff5fffffafffff9ff +fffafffff7fffffafffff2fcfffafff8ebf5fffafffffafffff4fefffafffff9fffffaff +fffafff4e7f1fffafffffafffffafff7eaf4fffafffffafff2e5effffafffffafffff3fd +fff7fffff9fffffafffff6fffaedf7fffafffff8fffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffaff +fffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffffafffff9ff +fff8fffff8fffff8fffff8fffff9fffff9fffff9fffff9fffff9fff1e2e97e6f765b4c51 +6e5f6488797e7e6f7478696c79696c79696c79696c79696c79696c79696c79696c79696c +77676a7b6b6e7b6b6ee7d7dafff7faefdfe2fff1f4fbebeef6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7 +f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7f6e6e9f6e6e7eddde0f6e6e7fff2f5f8e8e9 +f1e1e4fff4f5fffafdfff5f6f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5 +f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5 +f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5 +f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5 +f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5 +f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f4e4e5f4e4e7f3e5e5eae2dfece9e0ebecdcecefde +e8e9e1eeeee4e6e5d1bab5a2756c67f7eeefe9e5e6e4e6e3e3f1e4f1ffff8497d93850ba +1737be001eae00119b001fc0043bd31963ea1b58b1dfecfcf3efd6e8edcdebf2d1eeefd0 +efedd6efebe0f1eae4f3e9e0f2e9e0ebece4ebece6f1e9e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7e7dbdbfbefeffff5f5f9ededf0e4e4 +f4e8e8f2e6e6eadedeede1e1f5e9e9fff7f7ede1e1f5e9e9faeeeef0e4e4fcf0f0f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f2e8e7f2e8e6f4ece9ece2e0f0e8e5f4eae9f4eceaece2e3c3babbf1e6ea +eee5e8f8edf3dcd3d8fff5fdf9eff7fff4fcf4eaf2f6ecf4fff6fbf8eef6f4ebf0e3d9e1 +fffbffece2eafff7fcfcf2faf2e9eefff9fffbf2f7ece2eafbf2f7f8eef6ebe2e7fcf2fa +ede4e9fbf1f9f5ecf1fffbfff1e8edf5ebf3ede4e9fbf1f9f4ebf0f3e9f1f4ebf0f5ebf3 +f0e7ecfaf0f8eae1e6fffaffe9e0e5efe5edfffcfff7edf5faf1f6e9dfe7f3eaeff4eaf2 +f6edf2fbf1f9faf1f6f9eff7faf1f6f5ebf3efe6ebf5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3 +f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ecf1f5ebf3f5ebf3f5ebf6 +f5ebf6f6eaf6f5ebf4f6eaf4f5ebf3f6ebf3f5ecf1ebe0e6fffcfffdf2f6fffcfdfff5f6 +f7eeefece2e3f0e6e7f5ebecf6eaecf6eaecf6eaecf6eaecf6eaecf6eaecf6eaecfef2f4 +fdf1f3eee2e4fffbfdfffbfdeee2e4f1e5e7efe3e5f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7 +f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f3e7e7f9ededf2e6e6f7ebebebdfdfede1e1 +fcf0f0dfd3d3b8acacb3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7 +b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7 +b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7 +b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7 +b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7 +b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b3a7a7b2a8a6b3aca6aeaca0acad9babac9aababa1 +b2b2a6b2af9ca19b8b6d645feee4e5fbf5f9f5f7f4ecf8ec9aacb68d9fe1283fa91738bd +001eae00119b001dc90539db1a61f11c56b7dfebfff3eedae8edcfebf2d1eeefd0f1ecd6 +f1ebdff2e9e2f5e8dff3e9dfeeebe4ebece4eceddfeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbf3f4e2dedfcde6e7d5e0e1cff2f3e1e4e5d3 +edeedcf2f3e1eaebd9f7f8e6e2e3d1eaebd9ebecdaffffefe1e2d0e7e8d6eceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbe8ebd8ecf1dde6e9d6ecf1ddeef1e0eaeeddf3f6e5e6ead9fffff3fdfff2 +fffff4fefff4fafcf1fefff6fbfdf2f9fcf1fcfff4eef2e4fefff6fefff4fefff6fafef0 +f6f9eefefff4fefff6edf1e3f5f8edfefff4fefff6fefff4fafdf2fefff4f6f9eefefff4 +fefff6f9fdefe7eadffcfff2fefff6fefff4fefff6f2f6e8fefff6fefff4fcfff4fefff4 +f8fbf0fefff4f1f4e9fefff4fefff6f7fbedeff2e7fefff4fefff6fefff4fefff6f8fcee +fefff6fafef0fefff6eaeee0fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4 +fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff4fefff6fefff6fefff8fefffa +fffffafefff8fffff8fefff6fffff6fefff6f5f7ecfefff4f4f6e9fefff3fafceefcffef +fffff1fffff1fffff3fffff3fffff3fffff3fffff3fffff3fffff3fffff3fffff2fffff3 +fbfceef4f5e7f4f5e7eff0e2eceddff1f2e4ecedddeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddbeceddb +eceddbeceddbeceddbeceddbeceddbeceddbeff0dee1e2d0f0f1dfeeefddeceddbdfe0ce +9899875f604e6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d +6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d +6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d +6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d +6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d +6e6f5d6e6f5d6e6f5d6e6f5d6e6f5d706f5d787360716c56706f516f6f536e6d5973705d +756f5578715784786ceadfd9e4dcd9fffff6a9b5a199abadddedff3248ad1738bb001eae +00119b0019d30835e61c5efb1e54c0e0e9fff4ece1e9ebd5ecf0d7efedd4f1ecd8f2e9e0 +f3e8e4f6e7e0f6e7e0f1eae4ecece2ebeedbeaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8e6e9d4f1f6dff0f3def1f6dfe4e7d2f8fde6e6e9d4 +e3e8d1ebeed9eaefd8e7ead5e7ecd5f3f6e1e3e8d1e9ecd7f2f7e0ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8e7efd8edf5dde5edd6eaf2dbe3ebd4dbe3ccedf5def4fce5e3ebd6f2fae5e0e7d5 +e7eedce8efdfe7eedee9f0e0eaf1e1f1f8e6ecf3e1e5ecdaecf3e1e6eddbe7eedcf0f7e5 +eaf1dfe6eddbf4fbe9e9f0dee8efddeef5e3e5ecdae6eddbf1f8e6ecf3e1e7eedce7eedc +eaf1dff5fceaf4fbe9ebf2e0dde4d2e2e9d7fbfff0d7decceaf1dfe4ebd9e5ecdae3ead8 +ebf2e0f1f8e6d8dfcde6eddbecf3e1eff6e4e9f0dedfe6d4eef5e3edf4e2dbe2d0f2f9e7 +e5ecdadfe6d4faffefd3dac8e9f0dee7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedc +e7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedce7eedee7eddfe7eddfe7eddf +e7eddfe7eedee7eedee7eedee7eedeeef5e3eaf1dfdce4cff5fde8e8f0dbe7efd8eaf2db +e7efdaeaefdbeaefdbebeeddeaefdbebeeddeaefdbebeeddeaefdbe8ebdaedf2def9fceb +e2e7d3eaeddcf2f7e3e4e7d6e6ebd7ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8eaedd8dde2cbf4f7e2edf2dbe4e7d2ebf0d9e3e6d1 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9eaefd8ebeed9 +eaefd8ebeed9eaefd8ebeed9eceed8f5f0ddede7d1f2eed1f4f0d5f2ecdcede7d7eae3c9 +f7ecd6f2e4dbfaebe8fffcfaaaa7a0959e8bedfbfeedf9ff2a3da31738bb001eae00119b +021de8052ced235fff1c4cc8e8eafff0e1e4f1eee5eceddff1ebddf2eadff3e8e6f5e7e7 +f9e5e4f8e6e2f2e8e6efeae4ebebdfeaeddcebecdeeaeddcebecdeeaeddcebecdeeaeddc +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +ebeddfeaeeddeaeedfeaeedfeaeedfeaeedfeaeedfeaeedfeaeee0eaeee0eaeee0eaeee0 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2 +eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede2eaede4eaede4eaede2eaede2 +eaede2eaede2eaede2eaede2eaeee0eaeee0eaeee0eaeee0eaeee0eaeedfeaeedfebeddf +ebede0ebede0ecece2ebede0ecece2ebede0ecece2ebede0ecece2ebede0ecece2ebede0 +ecece2ebede0ecece2ebede0eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeeddeceddfebeedd +eceddfebeeddeceddfeeecdfece2d9fef1e8f2e9daf0e9d9f7eee9f5ece7ece0d4fceee5 +f6e2e4fff2fdb9a9b3aba2a7edf0e9f7ffff959ee12a3ba71a38be001faf00129c0012db +0c2eef255dff2451cee4e5fff0e1e4edeae3f7f8eaf4eee0f5ede2f5ece7f6ebe9fce9e2 +fbeae0f5ede2f2eee3f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f0eee2 +f0eee2f0eee2f0eee2f0eee2f0eee2f0eee2f0eee2f0ede4f0ede4f0ede4f0ede4f0ede4 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede6f0ede4f0ede6f0ede6f0ede6f0ede6f0ede6f0ede4f0ede6 +f0ede4f0ede6f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0ede4f0eee2f0eee2f1ede4 +f1ede4f1ece6f1ede4f1ece6f1ede4f1ece6f1ede4f1ece6f1ede4f1ece6f1ede4f1ece6 +f1ede4f1ece6f1ede4f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2f1ede2 +f1ede2f1ede2f3ece4ede2e0f3e8e4fff8efe7ded7ede4e5f1e7e8fff6f2ebdcd9fff8ff +bba6b5ad9cacebe4ecfefffb919aab9fa9f03648b41a37bf001eae00129c031ed11339e4 +1d58f22150bce7ecfff7ede3e3e4d2ebf0d9ececd4edebd4edead9efe9d9f4e8d2f3e9ce +edecd0ececd4f1e8d9f3e6ddf3e6ddf3e6ddf3e6ddf3e6ddf3e6ddf3e6ddf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf0e6ddf0e6dd +f0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6dd +f0e5dff0e6ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dff0e5dff0e5dff0e5dff0e6ddf0e5dff0e6dd +f0e5dff0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf0e6ddf2e5ddf2e5dd +f2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5ddf2e5dff2e5dd +f2e5dff2e5ddf2e5ddf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dcf2e5dc +f2e5dcf0e5dff8edebf2eae7e3dcd4fffbf5eae6e7f0eaece8e0ddfffcfab5a5afbcabbb +e6dae6fffeffa7aea69caab5d6e5ff2a3fa81738bd001eae00129c0018b90932cc1958e3 +1449a7eaf2fff2ecdce2ead3e7f4daedf2dbeef1dceef1e0eff0def4f0d7f2f1d3edf4d3 +eef2d7f5f0ddf7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f7ede3f6eee3f7ede3 +f6eee3f7ede3f6eee3f7ede3f6eee3f7ede3f6eee3f7ede3f6eee3f7ede3f6eee3f7ede3 +f7ede3f7ede3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3f9ece3 +f9ece3f9ece3f9ece3f9ece3f7ede3f7ede3f6eee3f7ede3f6eee3f7ede3f6eee3f7ede3 +f6eee3f7ede3f6eee3f7ede3f6eee3f7ede3f6eee3f7ede3f7ede3f7ede3f7ede3f9ece3 +f7ede3f9ece3f7ede3f9ece3f7ede3f9ece3f7ede3f9ece3f7ede3f9ece3f7ede3f9ece3 +f7ede3f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1f7ede1f9ede1 +f6ede4faf5efd6d6cefdfff2e9ece1e4e6e3eceeebfffff6b3b0a9a89fa4e6dfe7fffdff +aaafab9eaf9ddff7f7e3faff2642a31639bb001eae00119b0024b60e3dc92e73f21c55ac +eaf9ffe2e3d3e1f0dde4f7e4e1efe0e2eee2e2ede9e3ece7e6ecdee6eed9e1f0d9e2f0d9 +eaefdbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeceddbebeedbeceddbebeedb +eceddbebeedbeceddbebeedbeceddbebeedbeceed9ebeed9eceed9ebeed9eceed9eceed9 +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddbeeeddb +eeeddbeeeddbeeeddbeeeddbeceed9ebeed9eceed9ebeed9eceed9ebeed9eceed9ebeed9 +eceddbebeedbeceddbebeedbeceddbebeedbeceddbeceddbeceed9eceed9eeedd9eceed9 +eeedd9eceed9eeedd9eceed9eeedd9eceed9eeedd9eceed9eeedd9eceed9eeedd9eceed9 +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddb +eeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbeceddbeeeddbebeedd +e2e8daf5ffefd2e0c9e5f4dfe8f6e9edf9eda7b39f99a28ff0f3ecfcfffba3aaa29dae9c +c4e2c0e7fffd91b4da2145991339b8001dad00119b001eb40027b8135be3114fb2e0f3ff +ebeff2e7f9fdd8eff5dceefadcedffdcecffddebffe2ebfce0edf6dceff6dbf0f5dfeef3 +e2edf3e2edf3e2edf3e2edf3e2edf3e2edf3e2edf3e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e1eef4e1eef4e1eef4e1eef4e1eef4e1eef4 +e1eef4e1eef4e1eef4e1eef4e1eff2e1eff2e1eff2e1eff2e1eff2e1eff2e1eff2e3eef4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4e4edf4 +e4edf4e4edf4e3eef2e1eff2e1eff2e1eff2e1eff2e1eff2e1eff2e1eff2e1eff2e1eef4 +e1eef4e1eef4e1eef4e1eef4e1eef4e1eef4e1eef4e3eef2e3eef0e3eef2e3eef0e3eef2 +e3eef0e3eef2e3eef0e3eef2e3eef0e3eef2e3eef0e3eef2e3eef0e3eef2e3eef2e3eef2 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4 +e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e3eef4e1eef4e5f4fb +e8f9ffdbefeed3e7e8f1ffff9caeb890a2a4ecfafdf7ffff8e97a896a4afe8ffffe7fffd +68949787b2e91b45a71239bc001dad00119b0029d90033de165fff2b6aebc7dcffe7ecff +daedffcde4ffd9ecffd9ebffd9e9ffd9e9ffdee9ffdcebffd8edffd5eeffd4edffd4ecff +d4ecffd4ecffd4ecffd4ecffd4ecffd4ecffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd4eeffd4eeffd4eeffd4eeffd4eeff +d4eeffd4eeffd4eeffd4eeffd4eeffd4eeffd4eeffd4eeffd4eeffd5eeffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edffd7edff +d7edffd7edffd5eeffd4eeffd4eeffd4eeffd4eeffd4eeffd4eeffd4eeffd4eeffd4eeff +d4eeffd4eeffd4eeffd4eeffd4eeffd4eeffd5eeffd5eeffd5eeffd5eeffd5eeffd5eeff +d5eeffd5eeffd5eeffd5eeffd5eeffd5eeffd5eeffd5eeffd5eeffd5eeffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edff +d5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd5edffd7edffd5e7ffc7d7ff +e2f5ffe9feff8ea1e3a2b4f6dcecffebf7ff929bdea9b3fadeedffe7feff85a8ce88b3ea +d0fbff1842ca1036c5001cac00119b0018c8083ae7175aff114bda354eb2394695223b8f +2f4aa32c44a62c43ab2c42b12c42b12f42a92f43a42b45a42846a62545aa2545ac2545ac +2545ac2545ac2545ac2545ac2545ac2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2344ab2344ab2344ad2344ab2344ad2344ab2344ab +2344ab2344ab2344ab2345a92345a92345a92345a92345a92345a92444ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab2444ab2643ab +2444a92345a92345a72345a92345a92345a92345a92345a92345a92344ab2344ab2344ab +2344ab2344ab2344ab2344ab2344ab2444a92444a72444a72444a72444a72444a72444a7 +2444a72444a72444a72444a72444a72444a72444a72444a72444a92444a92444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab +2444ab2444ab2444ab2444ab2444ab2444ab2444ab2444ab2643ab2d44ac2f45ab2b43a7 +243da12e44b1253ca6273da23245ab2d3eaa2e40ac2439a22642a32a4ea41f49ab1d47cf +0a32c81235c5001ba7000f970023be0530ca1140d81845d41e41c11d3bb5183ab5173bb6 +1839ba1839bc1839be1839be1839ba183ab8173ab8173aba1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439be1439bd1439be1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd1638bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd1439bd +1439bd1439bd1439bd1439bd1439bd1439bd1439bd1638bd1738bd1738bd1738bb1639bb +1737be1738bd1738bb1738bb1836bc1637bc1637bc1538ba1339b81239bc1137c61336c6 +0a24ac071c9c0013930016a2001ca80023af0125b10023af0020ac0020ac0021ad0021ad +0021ad0021ad0021ad0021ad0021ad0021ad0020ae001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf001faf +001faf001faf001faf001eae001eae001eae001eae001eae001eae001eae001da9081d9d +061592000f8c00129a001199001098000f97000e96000e96000f97001098001098001098 +00109800109800109800109800109800109800109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a00109a +00109a00109a00109a00109a00109a00109a00109a00109a00109a000f97001393000f8c +000c89 +end +%%PageTrailer +%%Trailer +%%EOF diff --git a/doc/doc.tex b/doc/doc.tex new file mode 100644 index 000000000..671b2ef5c --- /dev/null +++ b/doc/doc.tex @@ -0,0 +1,991 @@ + +\documentclass[12pt]{article} + +\usepackage{a4, epsfig, times, fancyhdr} +%\usepackage[T1]{fontenc} + +\nonstopmode + +\hbadness=2000 +\vbadness=2500 +\clubpenalty9000 +\widowpenalty9000 +\tolerance=9999 +\textheight=24cm +\footskip=3\baselineskip +\lefthyphenmin=3 +\parindent=0pt +\parskip=0.5\baselineskip +\hyphenation{ } + +\pagestyle{fancy} +\renewcommand{\headrulewidth}{1pt} +\lhead{\scriptsize V \number\year -\number\month -\number\day} +\chead{} +%\rhead{} +\rhead{\thepage} +\lfoot{} +\cfoot{} +\rfoot{} + +\renewcommand{\topfraction}{1.0} +\renewcommand{\bottomfraction}{1.0} +\renewcommand{\dbltopfraction}{1.0} +\renewcommand{\textfraction}{0.0} +\renewcommand{\floatpagefraction}{.5} + + +\newcommand{\gpsbabel}{{\sc gpsbabel}} +\newcommand{\bsl}{$\backslash$} + + + +\begin{document} + + +{\center +\Large \bfseries The \gpsbabel\ Manual\\[5mm] +Version 0.0.2\\[10mm] + +{\rm \normalsize Principal developer:}\\ +\large Robert Lipe\\[2mm] +robertlipe@usa.net\\ +} + +\tableofcontents + +\newpage + +\section{What \gpsbabel\ is} + +{\bfseries \gpsbabel\ is a conversion utility for a large and still increasing number of GPS related formats that represent waypoints, track points and route points.} + +There are simply too many and annoyingly different file formats to hold waypoint, route and track related information in various programs used by computers. Even though there are some promising attempts to create format standards, e.g. GPX as an XML variant, to carry all data types, there are too many programs that don't understand them yet and too much existing data that are in alternate formats. + +\gpsbabel\ is based on an extensible foundation so that it is quite easy to add new formats. Most file formats implemented so far have taken less than 200 lines of reasonable ISO C code, so they can be stamped out pretty trivially. If you would like to contribute new features, see appendix~\ref{HowToContribute} + +\gpsbabel\ is designed for simple command line invocation for all supported platforms. For users not familiar with the command line (read: many Windows users) there is a mouse pitchforker's GUI interface to ease its use (see section~\ref{GUI}). A full fathoming of \gpsbabel 's features will need some command line familiarity, though. + +\gpsbabel\ is released under the GNU general public license. For further details, see appendix~\ref{GPL}. + + +\subsubsection*{What \gpsbabel\ is not:} + +\gpsbabel\ is not intended to {\em create} any GPS related data, like waypoints or tracks. It does not support uploads or downloads of maps. + + + +\section{General usage: the command line interface} + +On every supported operating system platform \gpsbabel\ basically is a command line program. This kind of invocation, providing the utmost freedom of including runtime options, creates the best possible flexibility. Unfortunately, that can +sometimes lead to unwieldy command lines. + +To use this program, just tell it +\begin{itemize} +\item what kind of data you want to read, +\item where to read it from, +\item what format you want to be written, +\item and what file or device to write it to. +\end{itemize} + +For example% +\footnote{In our examples we frequently split the respective command lines into several real lines to create a better readability. If a command line ends in a "\bsl " (being the usual continuation character of an input line), this means for actual usage that the command itself extends into the next given line.} + +{\tt \small +\begin{tabbing} +gpsbabel~\= -i geo ... \kill +gpsbabel \> -i geo -f /tmp/infile.loc \+ \bsl \\ + -o gpx -F outfile.gpx +\end{tabbing} +} + +tells it to read the file ~{\tt infile.loc}~ in the ~{\tt /tmp}~ directory% +\footnote{Directory delimiters are always given in the Unix-ish variant, i.e.: "/" is used where Windows users would enter a "\bsl" or similar.} in the {\sc geocaching.com} format and create a new file named ~{\tt outfile.gpx}~ in GPX format, to be placed in the present working directory. + +The next command will read waypoint data from a Magellan unit attached to the first +serial port and write them as a geocaching loc file. The first command is the Linux variant, the second command does the same for windows. + +{\tt \small +gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc + +gpsbabel -i magellan -f com1 -o geo -F mag.loc +} + +\bigskip + +{\tt \small gpsbabel -?} will always show you the supported file types. + +\bigskip + +People less familiar with the command line will find a GUI interface helpful. A first one, for Windows, is described in section~\ref{GUI}. + + + +\section{Modes of operation: waypoints, routes, tracks} + +There are three basic entities of GPS data that are of interest for a general conversion utility: waypoints, routes, and tracks. + +\begin{description} + +\item[Waypoints] describe isolated and unrelated points in space each. Each is specified by its position (latitude, longitude, height above sea level), a "short" name (that is usually displayed to describe it on the receiver), a comment (or "long" name; an extended text associated to the waypoint), an icon (to display it on a receiver's map display page), and several less important featurs (like time of creation, display options, ...) that even vary between the different receivers.\\ +Transferring waypoints is \gpsbabel 's {\bfseries default mode of operation}. It may as well be invoked by entering a {\tt -w} as {\em first} command line argument.\\ +Optionally, you may specify {\tt -s} as a command line switch. This causes the program to ignore any "short" names that may be present in the source data format and synthesize one from the long name. This is particularly useful if you're writing to a target format that +supports more elaborated short names but the source data was written in a very simple style. I use this for writing data from geocaching.com to my Magellan so my waypoints have "real" names instead of the 'GC1234' ones that are optimized for NMEA-only +receivers. + +\item[Routes] are ordered sets of waypoints that describe a path to follow. Since most contemporary GPS receivers have very limited possible set sizes (typically 30 or 50), but support multiple routes to be administered in parallel, the usual way to handle them is to work on a set of routes at the same time. Read: a set of sets is handled.\\ +Treatment of routes is only implemented for a part of \gpsbabel 's formats. Details are given in the respective section on the various format types. To invoke route treatment, {\bfseries enter {\tt -r} as {\em first} command line argument}. + +\item[Tracks] are lists of waypoints with position and creation time information only. They are sampled in larger quantities when traveling. They are intended to describe the traveled path as exactly as possible (if so desired). Track logging memory of the receivers usually can gather 1000 to 10000 individual points.\\ +Treatment of track data is only implemented for a part of \gpsbabel 's formats. Details are given in the respective section on the various format types. To invoke track treatment, {\bfseries enter {\tt -t} as {\em first} command line argument}. + +\end{description} + + + +\section{Supported input and output formats} + +This section describes the supported file or transmission protocol formats in detail. Please remember that the capabilities of the various receiver types are quite different, so transfers from one receiver to another, or from a general file format to a receiver, might go wrong: you cannot deliver more waypoints, route or track points than the target is able to swallow. This kind of error cannot be handled by \gpsbabel . + + + +\subsection{Tabular overview on formats} + +\begin{tabular}{|l|cc|cc|cc|} +\hline + & \multicolumn{2}{c}{Waypoints} & \multicolumn{2}{c}{Tracks} & \multicolumn{2}{c|}{Routes} \\ +File format & Read & Write & Read & Write & Read & Write\\ +\hline +\hline +Cetus & yes & yes & & & & \\ +CoPilot Flight Planner & yes & yes\footnote{Magnetic declination is not written.} + & & & & \\ +CSV & yes & yes & & & & \\ +Delorme S\&A & yes & yes & & & & \\ +Delorme TopoUSA/XMap Conduit + & yes & yes & & & & \\ +~~~~~(XMap) & & & & & & \\ +Delorme HandHeld & yes & yes & & & & \\ +~~~~~Street Atlas USA (XMapWpt) & & & & & & \\ +Garmin serial & yes & yes & yes & & & \\ +GEO & yes & yes & & & & \\ +Geocaching DB & yes & yes & & & --- & --- \\ +GPSDrive & yes & yes & & & & \\ +GPSman & yes & yes & & & & \\ +GPSPilot & yes & yes & & & & \\ +gpsutil & yes & yes & & & & \\ +GPX & yes & yes & yes & yes & yes & yes \\ +Holux & yes & yes & & & & \\ +Magellan serial & yes & yes & yes & yes & yes & yes \\ +Magellan SD card & yes & yes & yes & yes & yes & yes \\ +Magellan Navigator Companion + & yes & yes & & & & \\ +Mapsend & yes & yes & yes & yes & yes & yes \\ +Mapsource & yes & yes & & & & \\ +Maptech Exchange Format (MXF) + & yes & yes & & & & \\ +Navitrack DNA & yes & yes & & & & \\ +OziExplorer & yes & yes & & & & \\ +PCX5 & yes & yes & & & & \\ +PocketStreets 2002 Pushpin + & yes & yes & & & & \\ +Tiger & yes & yes & & & & \\ +TopoMapPro & yes & yes & & & & \\ +Topo by National Geographic + & yes & yes & & & & \\ +XCSV & yes & yes & & & & \\ +\hline +\end{tabular} + +In this table ``---'' means: not applicable since format will by definition not +support a respective type of data. + + +\subsection{CETUS} + + Cetus GPS (http://www.cetusgps.dk/) is a program for Palm/OS. + Working with Ron Parker and Kjeld Jensen, we can now read and write + files for that program. It hasn't been exhaustively tested, but + has seemed fine on every input and output we've tried. + + + +\subsection{CoPilot Flight Planner for Palm OS} + + This code is mostly intended to convert CoPilot databases into + other formats. I don't think you should use this to write + CoPilot databases, although the code is there, mostly because + GPSBabel doesn't convert magnetic declination values. + + Questions, bug reports, etc, to ptomblin at xcski.com + + + http://xcski.com/~ptomblin/CoPilot/ + http://navaid.com/CoPilot/ + + + +\subsection{Delorme S\&A} + + There are a billion variants of Comma Separated Value data. This + is the one that makes Delorme S\&A Deluxe 9 happy. + + + +\subsection{Delorme TopoUSA/XMap Conduit (XMap)} + + Delorme TopoUSA/XMap Conduit is a CSV variant. It's just like S\&A with the addition of a + completely pointless line at the beginning and end of the file. + This is the format used to hot-sync to XMap from withing TopoUSA. + Done with help of Dan Edwards. + + + +\subsection{Delorme XMapHandHeld Street Atlas USA (XMapWpt)} + + Delorme XMapHandHeld Street Atlas USA is CSV variant. This is the format used by XmapHH SA USA on + (at least) PocketPC O/S. This XMap is not to be confused + with the XMap mentioned above. Contributed to gpsbabel by + Alex Mottram. + +Delorme XMap Handheld .WPT for PocketPC is a bit of a kludge. This +document covers XMap Handheld Street Atlas USA edition. + +XMap on the PocketPC stores it's waypoints in individual .wpt files. +For example, waypoints generated by XMap on the PocketPC are stored +by default in the "My Documents" folder using the sequential names +"XMap1.wpt", "XMap2.wpt", ad nauseum. Needless to say, not very +efficient. + +As writing multiple waypoint files is outside of the scope of gpsbabel, +gpsbabel chooses to write one big file, one waypoint per line. +Extracting lines from this file is left as an exercise for the end user. +A simple perl script to handle this conversion is included at the end +of this README. + +It should also be noted that READING multiple files is indeed possible, +but if you have more than a few points, it can be a task. For example: + +gpsbabel -i xmapwpt -f Xmap1.wpt -f Xmap2.wpt -o mapsend -F mapsend.wpt + +will read the two Xmap .wpt files and write one mapsend file. This +is fine for a small handful of points, but could be quite cumbersome +for folks like me who have 100+ waypoints loaded into XMap. For *nix +folks, something as simple as: + +cat *.wpt > /tmp/foo.wpt +gpsbabel -i xmapwpt -f foo.wpt -o mapsend -F mapsend.wpt + +will do the trick just fine. + +\scriptsize +\begin{verbatim} +############ BEGIN SCRIPT +#!/full/path/to/perl +$INPUTFILE = @ARGV[0]; +$TARGETDIR = @ARGV[1]; +$FILENAME = @ARGV[2]; + +if (! $FILENAME) { + print "Usage: xmap_split.pl INPUT_FILE OUTPUT_DIRECTORY FILENAME_BASE\n"; + print " (i.e. xmapl_split.pl points.wpt /tmp/points GPSB)\n"; + print " (created GPSB0001-GPSBXXXX in /tmp/points/ from points.wpt)\n"; + exit; +} + +open (INFILE, $INPUTFILE) || die "Cannot open $INPUTFILE for read!\n"; + +while () { + $lc++; + $filename = sprintf("%s/Gpsb%04d.wpt", $TARGETDIR, $lc); + + open (OUTFILE, ">$filename") || die "Cannot open $filename for write!\n"; + + print OUTFILE $_; + + close(OUTFILE); +} + +exit; + +########### END SCRIPT +\end{verbatim} +\normalsize + + +\subsection{GARMIN serial} + + Waypoint serial upload and download works reliably under both + POSIX and Windows. I tested it with a Vista graciously provided + on loan by Joe Armstrong. The communications library used, jeeps, + claims to support most models of Garmin hardware. Be sure the GPS + is set for "Garmin mode" in setup and that nothing else (gpsd, getty, + pppd, etc.) is using the serial port. + + + +\subsection{GEO} + + geocaching.com spits up geocaching.loc files that are XML-ish but + not quite GPX. Because it's so close to GPX, this format is very + well supported. + + + +\subsection{Geocaching DB} + + This is a PDA file format. It was tested against version 2 + of GeocachingDB and a development snapshot of version 3. + Information on the file format came from Dougs Brat and Ron Parker. + A particularly handy way to use GPSBabel on these files is to use + GPSBabel to read a GPX file with Groundspeak (geocaching.com) + extensions and let it write you a GeocachingDB file that contains + the cache names, difficulty, terrain, and such. + + http://vip.hyperusa.com/~dougs/geocachingdb/geocachingdb.htm + + + +\subsection{GPSDRIVE} + + GpsDrive way.txt file format. A space seperated format file. Tested + against GpsDrive v 1.30 found @ http://www.kraftvoll.at/software. + Contributed by Alan Curry. + + + +\subsection{GPSMAN} + + GPS Manager can read and write formats that this converter doesn't + understand. The default formats (WGS84, DDD) work reliably. + + + +\subsection{GPSPILOT} + + The file format for GPSPILOT (http://www.gpspilot.com) was provided + by Ron Parker. The output from this module has been tested with + GPSPilot Tracker v5.05sx, but it is based on reverse-engineering + so it may not work with all versions of all GPSPilot products. + It had read-only support for Airport, Navaid, City and Landmark + files but will read and write Point files. + + + +\subsection{GPSUTIL} + + GPSUtil has a simple file format of this program that runs on POSIX- + compliant OSes like UNIX and Linux. Reads and writes of this format + are reliable. (I've also contributed to this program.) It's + available at http://www.cs.uakron.edu/~hennings/gpsutil/. + + + +\subsection{GPX} + + This is the most capable and expressive of all the file formats + supplied. It is described at http://www.topografix.com/gpx.asp + and is supported by EasyGPS, ExpertGPS, and man other programs + described at http://www.topografix.com/gpx\_resources.asp + + + +\subsection{HOLUX} + + The Holuxgm-100 (e-fox) gps receiver uses standard compact + flash cards. File formats were provided by Holux-Taiwan + http://www.holux.com.tw to the author. The code was tested + against version 2.27E1; other versions and receivers may + work but have not been explictly tested. Anyone with + information on other Holux receivers is encouraged to contact + jochen@bauerbahn.net. + + When copying the .wpo file to a flash card, the file must be + named "tempwprt.wpo" as the receiver will ignore all other + files. + + Comparing the waypoints of a .wpo files against other formats + like .gpx you may notice a small difference in the latitude + and longitude values. The reason is the low resolution of + the coordinates in the wpo file format. In a .wpo file the + reolution is 1/10"; in gpx for example it is 1/100". A a practical + matter, this loss is only about 1.7meters (5 feet). + + + The generated waypoint failes can also be used by MapShow + version 1.14. This program is free of charge from the Holux web + site. + + This format was contributed by Jochen Becker. + + + +\subsection{MAGELLAN (serial and SD card formats)} +\label{MagellanSerial} + +\begin{description} + +\item[Description:] This protocol supports serial uploads and downloads for the majority of the Magellan units. It has been tested to work reliably with the 315, 330, Meridian, and SportTrak family. In fact, it should work on any modern Magellan unit.\\ +Since the contents of the serial interface data transfer is the same that is written to or read from SD cards in the Meridian series, this kind of transfer is automatically supported as well.\\ +\gpsbabel\ can also read and write the files that are written to or read from the SD flash memory cards in the Meridian models. Simply specify a file instead of a serial port.\\ +% +{\small As of this writing, there is still a lot of "scribbling" in the +source for functionality that isn't hooked up to the rest of the +program. Communication errors are handled.} + +\item[Applicability:] Waypoints, tracks, routes + +\item[Additional invocation options:]~\\ +{\bfseries baud}: Baud rate settings may be 1200, 2400, 4800, 9600, 19200 for serial line connections and must match receiver settings. Default value is 4800.\\ +{\bfseries noack}: Specifying "noack" turns handshake mode off. Without handshaking transfer of data is sped up significantly but {\em might} lead to overlooked transmission faults. Those have never been experienced during any testing, though. Default setting is "handshake on".\\ +{\bfseries deficon}: It is possible to specify a default icon to be displayed for every transmitted waypoint. Please refer to appendix~\ref{MagellanDefIcons} for a list of those. + +\item[Usage example:] Read waypoint data from a Magellan receiver via the first serial line interface (Linux/Unix nomenclature given; for Windows replace "/dev/ttyS0" by "com1" etc.) with increased speed, but without handshaking, and write it to a Magellan formatted file.\\[-8mm] +{\tt \small +\begin{tabbing} +gpsbabel~\= -i ... \kill +gpsbabel \> -i magellan,noack,baud=9600 -f /dev/ttyS0 \bsl \+ \\ + -o magellan -F outfile.mag +\end{tabbing} +} + +\end{description} + + + + +\subsection{Magellan Navigator Companion (MAGNAV)} + +Magellan NAV Companion for Palm/OS is not really designed for this +sort of use, but its file format is supported and with a little bit +of patience you can both read and write NAV Companion waypoints. + +This conversion is based on partially +incomplete reverse-engineering of the record format, so it may not +work with all versions of NAV Companion. It has been tested with +version 2.10. + +Translating NAV Companion waypoints to another format is as easy +as with any other format. Just find the Companion\_Waypoints database +in your palm backup directory and use it as the input file. + +When translating waypoints back to NAV Companion, though, you need +to jump through some hoops: + +First, you must merge any waypoints that already exist in the database +in your Palm Backup directory with the ones you are adding; failure to +do so will result in only the new points being available in NAV Companion, +even if you give the new database a different name (it will overwrite +the old database, even in your backup directory. That's a feature of +PalmOS, not of NAV Companion.) + +To merge the databases, use a command line like the following: + +gpsbabel -i magnav -f Companion\_Waypoints.PDB -i geo -f geocaching.loc -o magnav -F merged.pdb + +Second, you must use the installer to install your new PDB file. Don't +make the mistake of copying it over the existing Companion\_Waypoints.PDB +file; the one on the handheld will overwrite it rather than merging with +it. + +Finally, because NAV Companion is not designed to work with desktop +applications, you must tell NAV Companion that its waypoints database +has changed out from under it. One way to do this is to go to the +waypoints screen and attempt to scroll; that will force it to reread +the database and fix the record pointers that it keeps on the heap. + + + +\subsection{MAPSEND} + + Magellan was smart enough to document their file format to make + creating software like this possible. + + + +\subsection{MAPSOURCE} + + Garmin Mapsource format appears compatible with the various + members of that product family. Icon mapping is oriented toward + versions above 4.07. Altitude, proximity, and depth are not + supported. + + Information on the Garmin Mapsource format was provided by Ian + Cowley. The code was implemented by Robert Lipe. + + + +\subsection{Maptech Exchange Format (MXF)} + + Maptech Exchange Format - Another CSV format file. This format + complies with (at least) Maptech Terrain Navigator, Terrain + Professional, Take a Hike, and ExpertGPS import/export MFX. + Contributed by Alex Mottram. + + + +\subsection{Navitrak DNA} + + Navitrak DNA marker format - Another CSV format file. + This is the format that is compatible with the DNA Desktop + import/export command. Reading the binary Markers.jwp + format directly off the data card is not supported yet. + Contributed by Tim Zickus. + + + +\subsection{OZI} + + OziExplorer Waypoint Format - Another CSV format file. Tested + against OziExplorer v 3.90.3a / Shareware. Contributed by Alex + Mottram. + + + +\subsection{PCX5} + + Garmin documents only PCX5, an older format limited to the lame NMEA + six-character waypoint names that's treated as a second-class citizien + in current versions of MapSource. Use file->import to read these + files. Anyone with information on the *.mps file format that is + now preferred is encouraged to contact me with the details or better + yet, a module that implements it. I spent time trying to reverse- + engineer a couple of *.mps files then I remembered that I don't own + a Garmin and wasn't that inspired. + + + +\subsection{Pocket Streets Pushpin (PSP)} + + Microsoft's PocketStreets 2002 Pushpin (.PSP) format is not yet + completely documented. THE .PSP MODULE DOES NOT WORK WITH MS + STREETS \& TRIPS 2002 .EST FILES. To create .PSP files from + Streets \& Trips 2002, you will need to have PocketStreets support + installed. Please note that MS Streets \& Trips only *EXPORTS* + .PSP files. It does not import them. MS Streets \& Trips 2002 + only imports CSV files. To use .PSP files, simply copy them + over to the same folder on the mobile device as the map (.MPS), + and open PocketStreets. It should also be noted that in the case + a pushpin is outside of the exported map area, the pin will be + "grayed-out" and unused in PocketStreets. This is a good thing + as it allows us to create one big .PSP file that covers multiple + .MPS files. Unfortunately, you need one .PSP file for every + .MPS file. :( + +Q: Why should I use gpsbabel/psp to make pushpins when Streets \& Trips (S\&T) + already does that for me? + +A: gpsbabel/psp has the advantage of being able to create pushpins WITHOUT + creating the associated map file and the need to "import" the waypoint + data into S\&T. Through a series of scripts, you can create a dozen + or so PSP files in a few seconds as opposed to a few weeks using the + S\&T interface. The maps are not going to change between sessions, + only the pins will. Why waste all that time creating maps when all you + really want are updated pins? As an aside, gpsbabel/psp creates points + WITH THE PROPER coordinates where S\&T does not in some areas of the U.S. + (Nashville, TN for instance). + + +Q: I keep getting a blank (32 byte) PSP file? + +A: There are either no points to write, or you have botched the command + line for gpsbabel. gpsbabel is sensitive to UPPER and lower case + on the command line. A simple command line to create PSP files + looks like this: + + gpsbabel -i geo -f geocaching.loc -o psp -F NewOrleans.psp + + Note the use of "-f" for INPUT files and "-F" for OUTPUT files. + + +Q: I've created a PSP file, now what do I do with it? + +A: To use pushpins in Pocketstreets, you need to have both a map and a + pushpin file. These two files must exist in the same folder and have + exactly the same base name as the map. For example, the pins that + correspond to the map "NewOrleans.mps" should be named "NewOrleans.psp". + + +Q: I don't have a map? What do I do now? + +A: Create one using the "Export map to Pocketstreets" option in S\&T. You + can also pick up some major city maps on the web from the MS Pocketstreets + website if you are interested in seeing how it works. + + +Q: I have .EST files, not .PSP files. What's up with that? + +A: In order to make PSP files, you need to use the "Export map to + Pocketstreets" function in S\&T. .EST files are for use in S\&T, not + Pocketstreets. + + +Q: The .PSP files differ when I use gpsbabel/psp versus Pocketstreets to + create them. What's up? + +A: Pocketstreets makes corrections to the S\&T waypoint data upon initial + loading. gpsbabel/psp writes PSP files with these corrections already made. + Ask MS. + + +Q: Does gpsbabel/psp work with (Autoroute, Mappoint, etc..) .PSP files? + +A: As of this writing, I haven't seen any so I can't be sure. If they + follow the same layout as S\&T 2002, I'd imagine so. + + +Q: Does gpsbabel/psp work with (S\&T 2001, S\&T 2002, etc...) files? + +A: MS the file layout between S\&T 2001 and S\&T 2002. The gpsbabel psp + module is known to work fine with S\&T 2002 and 2003. + + +Q: Does gpsbabel/psp work with (insert your country/location here) maps? + +A: If it doesn't, feel free to email the PSP files to me at: + geo\_alexm at cox-internet.com. I only had USA based data to work + with while figuring out the file layout. Please include as much + information about the points as possible (lat/long, name, etc..) + and do it in English. I don't read or speak any other languages + fluently. + + +Q: What do you mean S\&T writes points with the wrong coordinates? + +A: At some point in the "Export map to Pocketstreets" function in S\&T, + it goofs the lat/long data. Points in Nashville tended to shift + 1.4 miles WEST of their original location. I'm not a geometry buff, + but I'd imagine they have a reference point for generating coordinates + that's wrong in (at least) that area. + + +Q: I have 800 waypoints that cover a dozen or so Pocketstreets maps. + Do I need to to split my points up into smaller chunks to match the + area covered by the maps? + +A: No. Pocketstreets will "ignore" points that are outside of the map + area. Points that are not on the current map will be "grayed out" + in pushpin explorer in Pocketsreets. This is the reason the PSP + module was written for gpsbabel in the first place. + + +Q: Where can I find documentation for the layout of PSP files? + +A: Just about everything I know about the PSP file format is documented + in the source. To the best of my knowledge, there is no documentation + (and for good reason, I've come to discover). + + +Q: I have some other problem, what do I do? + +A: Email me at geo\_alexm at cox-internet.com and I'll see if I can + work it out. + + + +\subsection{TIGER} + + The U.S. Census Bureau proives online mapping facilities. This + format is described at: http://tiger.census.gov/instruct.html. + + + +\subsection{TopoMapPro} + + TopoMapPro Places File. Reads and writes places files for use + in TopoMapPro (http://www.topomappro.com). As this file type + can store links other than web links, anything that is not a + http url will be discarded. Note that this does not do datum + conversions, so if your input file does not have WGS84/NZGD2000 + data, your output file won't either. + Colour of waypoint icons defaults to red. + + + +\subsection{National Geographic Topo! (TPG)} + + National Geographic Topo! Waypoint Format. This filter + reads and writes .TPG files created by various editions of NG Topo! + This filter will *not* work with the newer combined .TPO files. + Contributed by Alex Mottram. + + + +\subsection{XCSV} + +XCSV is an open-ended "Whatever Separated Values" parser / writer +designed to work with user-supplied "style" files. It should handle +at least a few thousand of the billion CSV variants available. +By itself, it doesn't comply to any format, however *most* CSV +variants can be described as a "style" and fine-tuned by the end +user. For more information on it's use, please see README.style +in the style/ sub-directory of gpsbabel. For an example of using +the XCSV module within your C program, look at the ozi.c, mxf.c, and +xmapwpt.c sources in the gpsbabel directory. This module was +contributed to gpsbabel by Alex Mottram. + +Additional Options: +style - **REQUIRED** Path to XCSV style file. + +snlen - Maximum length of synthesized shortnames. +snwhite - Switch defining whether or not to allow whitespace + in synthesized shortnames. + (0 = NO WHITESPACE, 1 = WHITESPACE OK). +snupper - Switch defining whether or not to force uppercase + in shortnames. (0 = LEAVE AS IS, 1 = UPPERCASE ALL). + +NOTE: sn* options require use of the '-s' command line option. + +Example Usage: +{\tt \small +\begin{tabbing} +gpsbabel~\= -i geo -f 1.loc -f 2.loc \kill +gpsbabel \> -i gpsbabel -s -i gpx -f infile.gpx \bsl \+ \\ + -o xcsv,style=my.style,snlen=8 -F outfile +\end{tabbing} +} +{\tt \small +\begin{tabbing} +gpsbabel~\= -i geo -f 1.loc -f 2.loc \kill +gpsbabel \> -i xcsv,style=your.style -f infile \bsl \+ \\ + -o xcsv,style=my.style -F outfile +\end{tabbing} +} + + + + +\section{Format-independent data filtering options} + +\gpsbabel\ supports data filtering. Data filters are invoked from +the command line via the {\tt -x} option. They are invoked in the order they appear on the command +line and can be used intermittently between several variations +of input and output functions. It should also be noted that +filtering data from different input types can sometimes produce +undesirable results due to differences in the native data formats. + + + +\subsection{POSITION} + +The position filter is designed to remove points based on their +proximity to each other. Distances can be passed on the command +line by passing the distance=XXX option to the filter. Distance +options may be expressed in feet (distance=3f) or meters +(distance=1m). The default is zero feet, essentially a duplicate +position. + +For example: +{\tt \small +\begin{tabbing} +gpsbabel~\= -i geo -f 1.loc -f 2.loc \= \kill +gpsbabel \> -i geo -f 1.loc -f 2.loc \> \bsl \+ \\ + -x position,distance=1f \> \bsl \\ + -o mapsend -F 3.wpt +\end{tabbing} +} +would load two input files of the {\sc geo} type, remove multiple points that are within 1~foot of each other, +leaving just one, and finally would save a {\sc mapsend} type output file. + + + +\subsection{RADIUS} + +The radius filter is designed to include points based on their +proximity to a central point. Distances and the central point +are declared on the command line by passing the distance=X.XX, +lat=X.XX, and lon=X.XX options to the filter. Distance options +may be expressed in miles (distance=3M) or kilometers (distance=3K). +The default is zero miles. + +For example: +{\tt \small +\begin{tabbing} +gpsbabel~\= -i geo -f 1.loc -f 2.loc \kill +gpsbabel \> -i geo -f 1.loc \bsl \+ \\ + -x radius,distance=1.5M,lat=30.0,lon=-90.0 \bsl \\ + -o mapsend -F 2.wpt +\end{tabbing} +} +would load a {\sc geo} input file, but include only points that lie within 1.5 miles of N\,30.000 ~W\,90.000~ into the {\sc mapsend} output file. + + + +\subsection{DUPLICATE} + +The duplicate filter is designed to remove duplicate points based +on their shortname (traditionally a waypoint's name on the GPS +receiver), and/or their location (to a precision of 6 decimals). +This filter supports two options, "shortname" and "location". +Generally, at least one of these options is REQUIRED. + +For example: +{\tt \small +\begin{tabbing} +gpsbabel~\= -i geo ... \kill +gpsbabel \> -i gpx -f 1.gpx -f 2.gpx \bsl \+ \\ + -x duplicate,location,shortname \bsl \\ + -o gpx -F merged\_with\_no\_dupes.gpx +\end{tabbing} +} +would remove points that have duplicate shortnames *AND* duplicate +locations. The result would be a GPX file that more than likely +contains only unique points and point data. + + + +\section{GUI wrappers} +\label{GUI} + +gpsbabelfront(.exe) is is a Windows front-end for GPSBabel. It was contributed and is +maintained by Josh McKee. It is written in Delphi. Figure~\ref{babelfrontfig1} shows a screenshot of it. + +\begin{figure}[htb] +\hfil\psfig{figure=babelfront2.eps,width=0.8\textwidth}\hfil +\caption{Screenshot of the Babel frontend.} +\label{babelfrontfig1} +\end{figure} + + + +\section{Power usage} + +Argument are processed in the order they appear on the command line. +{\bfseries Input is cumulative}. The input file type remains unchanged until a +new -i argument is seen. Files are read in the order they appear. +So you could merge three input files into one output file with: +{\tt \small +\begin{tabbing} +gpsbabel~\= -i geo ... \kill +gpsbabel \> -i geo -f in-1.loc -f in-2.loc -f in-3.loc \+ \bsl \\ + -o geo -F big-out.loc +\end{tabbing} +} + +You can as well {\bfseries merge files of different types}: +{\tt \small +\begin{tabbing} +gpsbabel~\= -i geo ... \kill +gpsbabel \> -i geo -f 1.loc \+ \bsl \\ + -i gpx -f 2.gpx \bsl \\ + -i pcx -f 3.pcx \bsl \\ + -o gpsutil -F big-out.gps +\end{tabbing} +} + +You can {\bfseries write} the same data {\bfseries in different output formats}: +{\tt \small +\begin{tabbing} +gpsbabel~\= -i geo ... \kill +gpsbabel \> -i geo -f 1.loc \+ \bsl \\ + -o gpx -F out-1.gpx \bsl \\ + -o pcx -F out-2.wpt +\end{tabbing} +} + + + +\section{Building it from source} + +The source code should be compilable on any system with ISO C89 compilers. +It has been tested on UnixWare, OpenServer, OS/X, Linux, Solaris, and +a variety of further processors and compilers. + +{\sc Libexpat} is required. If you get errors about {\sc expat.h} being +missing, you must either edit the {\sc Makefile} to tell the compiler +where it is or install it in a sensible place. Expat can be +downloaded from http://expat.sourceforge.net. As part of Apache +it is very portable. + + + +\begin{appendix} + + +\section{How to contribute} +\label{HowToContribute} + +If you are interested in contributing to this program, here are some +guidelines: + +\begin{itemize} + +\item The frontier development state can always be obtained from a publicly accessible CVS on Sourceforge: {\sc cvs.gpsbabel.sourceforge.net}. Check this CVS first before beginning your own enhancement efforts. + +\item Please ensure that you are building and testing against the latest code +from the top of the CVS tree and that any code you modify is the latest +version from the CVS. Please remember: Code changes sometimes occur frequently! + +\item Standards are good. ISO C and POSIX are greal preferred. + +\item Reuse is OK, if doing so is not onerous. For example, using the {\sc expat} +libraries vastly simplifies the XML parsers while increasing their +robustness plus those libraries are ubiquitous. So I consider it OK to +require {\sc expat}. + +\item Mail patches to {\bfseries robertlipe$@$usa.net} for consideration and +integration. + +\item If you are creating a new target you should submit patches (use +"cvs diff -uN" to create patches) to the following files: + \begin{itemize} +\item Yourcode.c and/or Yourcode.h - this is the code required to do your + conversions and any support files that your code requires. +\item vecs.c - an updated vecs.c file implementing your conversion code into + GPSBabel. +\item Makefile - an updated Makefile telling the compiler how to build and link + your conversion into GPSBabel +\item README - an excerpt for the README about your conversion and any + idiosyncrasies it may have. +\item testo - an updated script that tests your conversion (this should produce + no output if all is good, see the current testo script for examples) +\item YourOutput - a sample file of code produced by your function (used in testo + and lives in a directory called "reference"). + \end{itemize} + +\item Compilers complain for a reason. Code shouldn't emit warnings. + +\item The entire world doesn't run just {\em $<$enter your favorite OS here$>$}. I've tested the present code on +five different OSes. If you find yourself wanting to insert compiler or +OS specific magic, please resist. We do not want to separate but to integrate. + +\end{itemize} + + +\section{Magellan icon names} +\label{MagellanDefIcons} + +The table shows the list of icon names available on a variety of Magellan receivers. The names may be used to define a default icon that will be displayed after uploading sets of waypoints to a respective receiver (see section~\ref{MagellanSerial}). + +... + + +\section{Acknowledgements and contact addresses} + + + +\section{Gnu general public license} +\label{GPL} + +... + +\end{appendix} +%============================================================ +%\newpage +%\bibliographystyle{galphac} +%\bibliography{antrag} + +\end{document} + + + + + + + + + + + + + diff --git a/duplicate.c b/duplicate.c new file mode 100644 index 000000000..f40e1bf5f --- /dev/null +++ b/duplicate.c @@ -0,0 +1,260 @@ +/* + exact duplicate point filter utility. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include +#include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED +static char *snopt = NULL; +static char *lcopt = NULL; +static char *purge_duplicates = NULL; +static char *correct_coords = NULL; + +static +arglist_t dup_args[] = { + {"shortname", &snopt, "Suppress duplicate waypoints based on name", + NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, + {"location", &lcopt, "Suppress duplicate waypoint based on coords", + NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, + {"all", &purge_duplicates, "Suppress all instances of duplicates", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"correct", &correct_coords, "Use coords from duplicate points", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + + +typedef struct btree_node { + struct btree_node *left, *right; + unsigned long data; + waypoint *wpt; +} btree_node; + +static btree_node * +addnode (btree_node * tree, btree_node * newnode, btree_node **oldnode) +{ + btree_node * tmp, * last = NULL; + + if ( *oldnode ) {*oldnode = NULL;} + + if (!tree) + return (newnode); + + tmp = tree; + + while (tmp) { + last = tmp; + if (newnode->data < tmp->data) { + tmp = tmp->right; + } else if (newnode->data > tmp->data) { + tmp = tmp->left; + } else { + if ( oldnode ) { + *oldnode = tmp; + } + return (NULL); + } + } + + if (newnode->data < last->data) { + last->right = newnode; + } else { + last->left = newnode; + } + + return (tree); +} + +void +free_tree (btree_node *tree) +{ + if ( tree->left ) { + free_tree(tree->left); + } + if ( tree->right ) { + free_tree(tree->right); + } + xfree(tree); +} + +typedef struct { + waypoint *wpt; + int index; +} wpt_ptr; + +/* + +It looks odd that we have different comparisons for date and index. + If exported if a < b return 1 + if index if a < b return -1 + +The reason is that we want to sort in reverse order by date, but forward +order by index. So if we have four records: + + date index + June 24 0 + June 25 1 + June 25 2 + June 24 3 + +we want to sort them like this: + + date index + June 25 1 + June 25 2 + June 24 0 + June 24 3 + +Thus, the first point we come across is the latest point, but if we +have two points with the same export date/time, we will first see the +one with the smaller index (i.e. the first of those two points that we +came across while importing waypoints.) + +In the (common) case that we have no exported dates, the dates will all +be zero so the sort will end up being an expensive no-op (expensive +because, sadly, quicksort can be O(n^2) on presorted elements.) +*/ + + +static +int +compare(const void *a, const void *b) +{ + const wpt_ptr *wa = (wpt_ptr *)a; + const wpt_ptr *wb = (wpt_ptr *)b; + + if ( wa->wpt->gc_data.exported < wb->wpt->gc_data.exported ) { + return 1; + } else if ( wa->wpt->gc_data.exported > wb->wpt->gc_data.exported ) { + return -1; + } + + /* If the exported dates are the same, sort by index. */ + if ( wa->index < wb->index ) { + return -1; + } else if (wa->index > wb->index ) { + return 1; + } + + /* If index and date are the same, it's the same element. */ + return 0; + +} + + +static void +duplicate_process(void) +{ + waypoint * waypointp; + btree_node * newnode, * btmp, * sup_tree = NULL; + btree_node * oldnode = NULL; + unsigned long crc = 0; + struct { char shortname[32]; char lat[13]; char lon[13]; } dupe; + waypoint * delwpt = NULL; + + int i, ct = waypt_count(); + wpt_ptr *htable, *bh; + queue *elem, *tmp; + + htable = (wpt_ptr *) xmalloc(ct * sizeof(*htable)); + bh = htable; + + i = 0; + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + bh->wpt = (waypoint *) elem; + bh->index = i; + i ++; + bh ++; + } + qsort(htable, ct, sizeof(*htable), compare); + + for (i=0;ishortname, sizeof(dupe.shortname) - 1); + } + + if (lcopt) { + /* let sprintf take care of rounding */ + sprintf(dupe.lat, "%11.4f", waypointp->latitude); + sprintf(dupe.lon, "%11.4f", waypointp->longitude); + /* The degrees2ddmm stuff is a feeble attempt to + * get everything rounded the same way in a precision + * that's "close enough" for determining duplicates. + */ + sprintf(dupe.lat, "%11.3f", degrees2ddmm(waypointp->latitude)); + sprintf(dupe.lon, "%11.3f", degrees2ddmm(waypointp->longitude)); + + } + + crc = get_crc32(&dupe, sizeof(dupe)); + + newnode = (btree_node *)xcalloc(sizeof(btree_node), 1); + newnode->data = crc; + newnode->wpt = waypointp; + + btmp = addnode(sup_tree, newnode, &oldnode ); + + if (btmp == NULL) { + if ( delwpt ) { + waypt_free(delwpt); + } + if ( correct_coords && oldnode && oldnode->wpt ) { + oldnode->wpt->latitude = waypointp->latitude; + oldnode->wpt->longitude = waypointp->longitude; + } + delwpt = waypointp; + waypt_del(waypointp); /* collision */ + xfree(newnode); + if ( purge_duplicates && oldnode ) { + if ( oldnode->wpt ) { + waypt_del( oldnode->wpt ); + waypt_free( oldnode->wpt ); + oldnode->wpt = NULL; + } + } + + } else { + sup_tree = btmp; + } + } + + if ( delwpt ) { + waypt_free(delwpt); + } + + xfree(htable); + if ( sup_tree ) { + free_tree(sup_tree); + } +} + +filter_vecs_t duplicate_vecs = { + NULL, + duplicate_process, + NULL, + NULL, + dup_args +}; +#endif diff --git a/easygps.c b/easygps.c new file mode 100644 index 000000000..2bc95850b --- /dev/null +++ b/easygps.c @@ -0,0 +1,215 @@ +/* + Access to EasyGPS files. + + Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include "defs.h" +#include + +static gbfile *file_in; +static gbfile *file_out; +static short_handle mkshort_handle; +/* static char *deficon = NULL; */ + +#define MYNAME "EasyGPS" + +static +arglist_t easygps_args[] = { +/* {"deficon", &deficon, "Default icon name", "Waypoint", + ARGTYPE_STRING}, */ + ARG_TERMINATOR +}; + +static void +rd_init(const char *fname) +{ + int sz; + char ibuf[100] = {'0'} ; + const char *ezsig = "TerraByte Location File"; + + file_in = gbfopen_le(fname, "rb", MYNAME); + + sz = gbfread(ibuf, 1, 52, file_in); + + if ((sz < 52) || + strncmp(ibuf, ezsig, sizeof(ezsig)-1) || + (ibuf[51] != 'W')) { + fatal(MYNAME ": %s is not an EasyGPS file.\n", fname); + } +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); +} + +static void +data_read(void) +{ + char p; + char ibuf[10]; + do { + unsigned char tag; + waypoint *wpt_tmp; + + wpt_tmp = waypt_new(); + + for (tag = gbfgetc(file_in); tag != 0xff; tag = gbfgetc(file_in)) { + switch (tag) { + case 1: + wpt_tmp->shortname = gbfgetpstr(file_in); + break; + case 2: + case 3: + wpt_tmp->description = gbfgetpstr(file_in);; + break; + case 5: + wpt_tmp->notes = gbfgetpstr(file_in);; + break; + case 6: + wpt_tmp->url_link_text = gbfgetpstr(file_in);; + break; + case 7: + wpt_tmp->icon_descr = gbfgetpstr(file_in);; + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + break; + case 8: /* NULL Terminated (vs. pascal) descr */ + wpt_tmp->notes = gbfgetcstr(file_in); + break; + case 9: /* NULL Terminated (vs. pascal) link */ + wpt_tmp->url = gbfgetcstr(file_in); + break; + case 0x10: + wpt_tmp->url_link_text = gbfgetcstr(file_in); + break; + case 0x63: + wpt_tmp->latitude = gbfgetdbl(file_in); + break; + case 0x64: + wpt_tmp->longitude = gbfgetdbl(file_in); + break; + case 0x65: + case 0x66: + gbfread(ibuf, 8, 1, file_in); + break; + case 0x84: + case 0x85: + gbfread(ibuf, 4, 1, file_in); + break; + case 0x86: /* May be proximity. I think it's time. */ + gbfread(ibuf, 4, 1, file_in); + break; + default: + printf("Unknown tag %x\n", tag); + ; + } + } + waypt_add(wpt_tmp); + p = gbfgetc(file_in); + } while (!gbfeof(file_in) && (p == 'W')); +} + + +static void +ez_disp(const waypoint *wpt) +{ + gbfputc('W', file_out); + + if (wpt->shortname) { + gbfputc(1, file_out); + gbfputpstr(wpt->shortname, file_out); + } + if (wpt->description) { + gbfputc(3, file_out); + gbfputpstr(wpt->description, file_out); + } + if (wpt->icon_descr) { + gbfputc(7, file_out); + gbfputpstr(wpt->icon_descr, file_out); + } + gbfputc(0x63, file_out); + gbfputdbl(wpt->latitude, file_out); + + gbfputc(0x64, file_out); + gbfputdbl(wpt->longitude, file_out); + + if (wpt->notes) { + gbfputc(5, file_out); + gbfputpstr(wpt->notes, file_out); + } + if (wpt->url_link_text) { + gbfputc(6, file_out); + gbfputpstr(wpt->url_link_text, file_out); + } + if (1 && wpt->url) { + gbfputc(9, file_out); + gbfputcstr(wpt->url, file_out); + } + gbfputc(0xff, file_out); +} + +static void +data_write(void) +{ + setshort_length(mkshort_handle, 6); + + gbfprintf(file_out, + "TerraByte Location File Copyright 2001 TopoGrafix\n"); + /* + * I don't know what this is. + */ + gbfprintf(file_out, "%c", 0xb); + + waypt_disp_all(ez_disp); + + /* + * Files seem to always end in a zero. + */ + gbfputc(0x00, file_out); +} + + +ff_vecs_t easygps_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + easygps_args, + CET_CHARSET_ASCII, 0 /* CET REVIEW */ +}; diff --git a/exif.c b/exif.c new file mode 100644 index 000000000..d81e210fa --- /dev/null +++ b/exif.c @@ -0,0 +1,490 @@ +/* + + Support for embedded Exif-GPS information. + + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "config.h" +#include "garmin_tables.h" +#include "jeeps/gpsmath.h" +#include "strptime.h" +#include + +#define MYNAME "exif" + +#define UNKNOWN_TIMESTAMP 999999999 + +typedef struct exif_tag_s { + gbuint16 tag; + gbuint16 type; + gbint32 count; + gbuint32 offs; +} exif_tag_t; + +static gbfile *fin; +static gbsize_t exif_ifd, gps_ifd; +static char byte_order; +static waypoint *wpt; +static gbsize_t fileoffs; +static char *opt_filename; +static time_t timestamp; + +static +arglist_t exif_args[] = { + {"filename", &opt_filename, "Set waypoint name to source filename.", "Y", ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +#define EXIF_IFD -1 +#define GPS_IFD -2 + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +exif_rd_init(const char *fname) +{ + fin = gbfopen_le(fname, "rb", MYNAME); +} + +static void +exif_rd_deinit(void) +{ + gbfclose(fin); +} + +#if 0 +static int +exif_tag_size(const exif_tag_t *tag) +{ + int size; + + switch(tag->type) { + case 1: + case 2: + case 7: size = 1; break; + case 3: size = 2; break; + case 4: + case 9: size = 4; break; + case 5: + case 10: size = 8; break; + default: + return 0; + } + return size * tag->count; +} +#endif + +static double +exif_read_double(const gbsize_t offs) +{ + unsigned int num, den; + + if (offs) gbfseek(fin, fileoffs + offs, SEEK_SET); + + num = gbfgetuint32(fin); + den = gbfgetuint32(fin); + if (den == 0) den = 1; + + return (double)num / den; +} + +static double +exif_read_coord(const exif_tag_t *tag) +{ + double deg, min, sec; + + deg = exif_read_double(tag->offs); + if (tag->count == 1) return deg; + + min = exif_read_double(0); + deg += (min / 60); + if (tag->count == 2) return deg; + + sec = exif_read_double(0); + deg += (sec / 3600); + + return deg; +} + +static char * +exif_read_string(const exif_tag_t *tag) +{ + if (tag->count > 4) { + gbfseek(fin, fileoffs + tag->offs, SEEK_SET); + return gbfgetcstr(fin); + } + else { + char buff[5]; + if (fin->big_endian) be_write32(buff, tag->offs); + else le_write32(buff, tag->offs); + if (tag->count < 5) buff[tag->count] = '\0'; + else buff[4] = '\0'; + return xstrdup(buff); + } +} + +static time_t +exif_read_timestamp(const exif_tag_t *tag) +{ + double hour, min, sec; + + hour = exif_read_double(tag->offs); + min = exif_read_double(0); + sec = exif_read_double(0); + + return ((int)hour * SECONDS_PER_HOUR) + ((int)min * 60) + (int)sec; +} + +static int +exif_sort_tags_cb(const void *a, const void *b) +{ + const exif_tag_t *ea = a; + const exif_tag_t *eb = b; + return (int)ea->offs - (int)eb->offs; +} + +static gbsize_t +exif_read_tags(const int ifd) +{ + int entries; + exif_tag_t *tags = NULL; + gbsize_t next_ifd = 0; + double gpsdop = unknown_alt; + char speed_ref = 'K'; + char lat_ref = '*'; + char lon_ref = '*'; + char mode = 'N'; + int datum = DATUM_WGS84; + + entries = gbfgetint16(fin); + if (entries > 0) { + int i; + tags = xmalloc(entries * sizeof(*tags)); + for (i = 0; i < entries; i++) { + tags[i].tag = gbfgetuint16(fin); + tags[i].type = gbfgetuint16(fin); + tags[i].count = gbfgetint32(fin); + tags[i].offs = gbfgetuint32(fin); + } + } + + next_ifd = gbfgetuint32(fin); + + if (entries > 0) { + int i; + char *str, *c; + struct tm tm; + + if (entries > 1) /* avoid backward seek */ + qsort(tags, entries, sizeof(*tags), exif_sort_tags_cb); + + for (i = 0; i < entries; i++) { + exif_tag_t *tag = &tags[i]; + + switch(ifd) { + case 0: + switch(tag->tag) { + case 0x8769: + exif_ifd = tag->offs; + break; + case 0x8825: + gps_ifd = tag->offs; + break; + } + break; + case 1: /* IFD1 */ + break; + case -1: /* Exif */ + switch(tag->tag) { + + case 0x9003: /* DateTimeOriginal */ + str = exif_read_string(tag); + c = strptime(str, "%Y:%m:%d %H:%M:%S", &tm); + if (c && (*c == '\0')) + wpt->creation_time = mklocaltime(&tm); + xfree(str); + break; + } + break; + case -2: /* GPS */ + switch(tag->tag) { + + case 0x0001: /* GPSLatitudeRef */ + str = exif_read_string(tag); + lat_ref = *str & 127; + xfree(str); + break; + + case 0x0002: /* GPSLatitude */ + wpt->latitude = exif_read_coord(tag); + break; + + case 0x0003: /* GPSLongitudeRef */ + str = exif_read_string(tag); + lon_ref = *str & 127; + xfree(str); + break; + + case 0x0004: /* GPSLongitude */ + wpt->longitude = exif_read_coord(tag); + break; + + case 0x0005: /* GPSAltitudeRef */ + break; + + case 0x0006: /* GPSAltitude */ + wpt->altitude = exif_read_double(tag->offs); + break; + + case 0x0007: /* GPSTimeStamp */ + timestamp = exif_read_timestamp(tag); + break; + + case 0x0008: /* GPSSatellites */ + str = exif_read_string(tag); + wpt->sat = atoi(str); + xfree(str); + break; + + case 0x000a: /* GPSMeasureMode */ + str = exif_read_string(tag); + mode = *str & 127; + xfree(str); + break; + + case 0x000b: /* GPSDOP */ + gpsdop = exif_read_double(tag->offs); + break; + + case 0x000c: /* GPSSpeedRef */ + str = exif_read_string(tag); + speed_ref = *str & 127; + xfree(str); + break; + + case 0x000d: /* GPSSpeed */ + WAYPT_SET(wpt, speed, exif_read_double(tag->offs)); + break; + + case 0x0012: /* GPSMapDatum */ + str = exif_read_string(tag); + datum = gt_lookup_datum_index(str, MYNAME); + if (datum < 0) + fatal(MYNAME ": Unknown GPSMapDatum \"%s\"!\n", str); + xfree(str); + break; + } + break; + } + } + xfree(tags); + } + + if (ifd == GPS_IFD) { + + /* Did we get our minimum data ? */ + if ((wpt->latitude == unknown_alt) || (wpt->longitude == unknown_alt)) { + warning(MYNAME ": GPSLatitude and/or GPSLongitude not set!\n"); + waypt_free(wpt); + wpt = NULL; + return 0; + } + + if WAYPT_HAS(wpt, speed) { + switch(speed_ref) { + case 'K': + wpt->speed = KPH_TO_MPS(wpt->speed); + break; + case 'M': + wpt->speed = MPH_TO_MPS(wpt->speed); + break; + case 'N': + wpt->speed = KNOTS_TO_MPS(wpt->speed); + break; + default: + wpt->speed = 0; + WAYPT_UNSET(wpt, speed); + warning(MYNAME ": Unknown GPSSpeedRef unit %c (0x%02x)!\n", speed_ref, speed_ref); + } + } + + if (lat_ref == 'S') wpt->latitude *= -1; + else if (lat_ref != 'N') warning(MYNAME ": GPSLatitudeRef not set! Using N(orth).\n"); + if (lon_ref == 'W') wpt->longitude *= -1; + else if (lon_ref != 'E') warning(MYNAME ": GPSLongitudeRef not set! Using E(east).\n"); + + if (datum != DATUM_WGS84) { + double alt; + GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, + &wpt->latitude, &wpt->longitude, &alt, datum); + } + + if (mode == '2') { + wpt->fix = fix_2d; + if (gpsdop != unknown_alt) wpt->hdop = gpsdop; + } + else if (mode == '3') { + wpt->fix = fix_3d; + if (gpsdop != unknown_alt) wpt->pdop = gpsdop; + } + } + + return next_ifd; +} + +static void +exif_read(void) +{ + gbint32 code = 0; + + fileoffs = 0; + wpt = NULL; + + while (!gbfeof(fin)) { + + unsigned char c = (unsigned)gbfgetc(fin); + + code = (code << 8) | c; + if (code == 0x45786966) { /* Look for "Exif" */ + + gbsize_t next_ifd; + gbint32 ifd; + + int order = gbfgetint32(fin); + switch(order) { + case 0x49490000: /* "II" - Intel */ + byte_order = 'I'; + break; + case 0x4D4D0000: /* "MM" - Motorola */ + byte_order = 'M'; + break; + + default: + continue; + } + fin->big_endian = (byte_order == 'M'); + if (gbfgetint16(fin) != 0x002a) continue; + + fileoffs = gbftell(fin) - 4; + + next_ifd = gbfgetuint32(fin); + if (! next_ifd) continue; /* No IFD0 ? */ + + ifd = gps_ifd = exif_ifd = 0; + timestamp = UNKNOWN_TIMESTAMP; + + /* we need the wpt not only during GPS IFD */ + wpt = waypt_new(); + wpt->latitude = unknown_alt; + wpt->longitude = unknown_alt; + + while (next_ifd) { + gbfseek(fin, fileoffs + next_ifd, SEEK_SET); + next_ifd = exif_read_tags(ifd++); + } + if (exif_ifd) { + gbfseek(fin, fileoffs + exif_ifd, SEEK_SET); + (void) exif_read_tags(EXIF_IFD); + } + if (gps_ifd) { + gbfseek(fin, fileoffs + gps_ifd, SEEK_SET); + (void) exif_read_tags(GPS_IFD); + } + else { + warning(MYNAME ": No Exif-GPS information in file \"%s\"!\n", fin->name); + waypt_free(wpt); + wpt = NULL; + } + + if (! wpt) return; + + if (wpt->creation_time && (timestamp != UNKNOWN_TIMESTAMP)) { + struct tm tm; + tm = *gmtime(&wpt->creation_time); + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + wpt->creation_time = mkgmtime(&tm) + timestamp; + } + + if (opt_filename) { + char *c, *cx; + char *str = xstrdup(fin->name); + + cx = str; + if ((c = strrchr(cx, ':'))) cx = c + 1; + if ((c = strrchr(cx, '\\'))) cx = c + 1; + if ((c = strrchr(cx, '/'))) cx = c + 1; + if (((c = strchr(cx, '.'))) && (c != cx)) *c = '\0'; + + if (wpt->shortname) xfree(wpt->shortname); + wpt->shortname = xstrdup(cx); + xfree(str); + } + waypt_add(wpt); + + return; + } + } + warning(MYNAME ": No Exif header in file \"%s\"!\n", fin->name); +} + +#if 0 +static void +exif_wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); +} + +static void +exif_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +exif_write(void) +{ +} +#endif + +/**************************************************************************/ + +ff_vecs_t exif_vecs = { + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + exif_rd_init, + NULL, /* exif_wr_init, */ + exif_rd_deinit, + NULL, /* exif_wr_deinit, */ + exif_read, + NULL, /* exif_write */ + NULL, + exif_args, + CET_CHARSET_ASCII, 0 +}; + +/**************************************************************************/ diff --git a/fatal.c b/fatal.c new file mode 100644 index 000000000..30275f474 --- /dev/null +++ b/fatal.c @@ -0,0 +1,41 @@ +/* + Functions to indicate inconsistent or fatal conditions. + + Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +void +fatal(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + +void +warning(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + diff --git a/filter_skeleton.c b/filter_skeleton.c new file mode 100644 index 000000000..8c5651af7 --- /dev/null +++ b/filter_skeleton.c @@ -0,0 +1,107 @@ +/* + + Filter skeleton: + + Simply copy this file to .c and + rename all filter_skeleton tokens to . Replace + the stupid name and address in the Copyright few lines below. + To active your new filter you have to create a new section in + filter_vecs and finally add complying statements to Makefile. + + Copyright (C) YYYY John Doe, anybody@wherever.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" +#include + +#define MYNAME "filter_skeleton" + +#if FILTERS_ENABLED + +// Any arg in this list will appear in command line help and will be +// populated for you. +static +arglist_t filter_skeleton_args[] = { +// {"foo", &fooopt, "The text of the foo option in help", +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR +}; + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +filter_skeleton_init(const char *args) +{ + /* Called before filter processing */ + + /* optional. If not needed, delete and replace entry in vecs with NULL */ + + /* This may be used to parse filter options, allocate memory, and do other + * housekeeping that should be done before filtering */ +} + +static void +filter_skeleton_process(void) /* this procedure must be present in vecs */ +{ +// Here is how you register callbacks for all waypoints, routes, tracks. +// waypt_disp_all(waypt) +// route_disp_all(head, tail, rtept); +// track_disp_all(head, tail, trkpt); +} + +static void +filter_skeleton_deinit(void) +{ + /* called after filter processing */ + + /* optional. If not needed, delete and replace entry in vecs with NULL */ + + /* This should be used to clean up any memory allocations that are no longer + * needed after the filter terminates. */ +} + +static void +filter_skeleton_exit(void) +{ + /* called on program exit */ + + /* optional. If not needed, delete and replace entry in vecs with NULL */ + + /* You should not need this for simple filters, but it may be used to + * clean up memory allocations that must persist from one invocation of + * your filter to the next (for example, the stack in the stack filter.) + * Note that this member will be called even if your filter has not been + * used, so it *cannot* assume that _init or _process has been called + * previously. */ +} + +/*******************************************************************************/ + +filter_vecs_t filter_skeleton_vecs = { + filter_skeleton_init, + filter_skeleton_process, + filter_skeleton_deinit, + filter_skeleton_exit, + filter_skeleton_args +}; + +/*******************************************************************************/ +#endif // FILTERS_ENABLED diff --git a/filter_vecs.c b/filter_vecs.c new file mode 100644 index 000000000..10d4670d9 --- /dev/null +++ b/filter_vecs.c @@ -0,0 +1,334 @@ +/* + Describe vectors containing filter operations. + + Copyright (C) 2002,2004,2005,2006,2007 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" +#include "inifile.h" +#include "gbversion.h" + +typedef struct { + filter_vecs_t *vec; + const char *name; + const char *desc; +} fl_vecs_t; + +extern filter_vecs_t position_vecs; +extern filter_vecs_t radius_vecs; +extern filter_vecs_t duplicate_vecs; +extern filter_vecs_t arcdist_vecs; +extern filter_vecs_t polygon_vecs; +extern filter_vecs_t routesimple_vecs; +extern filter_vecs_t reverse_route_vecs; +extern filter_vecs_t sort_vecs; +extern filter_vecs_t stackfilt_vecs; +extern filter_vecs_t trackfilter_vecs; +extern filter_vecs_t discard_vecs; +extern filter_vecs_t nuke_vecs; +extern filter_vecs_t interpolatefilt_vecs; +extern filter_vecs_t transform_vecs; + +static +fl_vecs_t filter_vec_list[] = { +#if FILTERS_ENABLED + { + &arcdist_vecs, + "arc", + "Include Only Points Within Distance of Arc", + }, + { + &discard_vecs, + "discard", + "Remove unreliable points with high hdop or vdop" + }, + { + &duplicate_vecs, + "duplicate", + "Remove Duplicates", + }, + { + &interpolatefilt_vecs, + "interpolate", + "Interpolate between trackpoints" + }, + { + &nuke_vecs, + "nuketypes", + "Remove all waypoints, tracks, or routes" + }, + { + &polygon_vecs, + "polygon", + "Include Only Points Inside Polygon", + }, + { + &position_vecs, + "position", + "Remove Points Within Distance", + }, + { + &radius_vecs, + "radius", + "Include Only Points Within Radius", + }, + { + &routesimple_vecs, + "simplify", + "Simplify routes", + }, + { + &sort_vecs, + "sort", + "Rearrange waypoints by resorting", + }, + { + &stackfilt_vecs, + "stack", + "Save and restore waypoint lists" + }, + { + &reverse_route_vecs, + "reverse", + "Reverse stops within routes", + }, + { + &trackfilter_vecs, + "track", + "Manipulate track lists" + }, + { + &transform_vecs, + "transform", + "Transform waypoints into a route, tracks into routes, ..." + }, +#endif + { + NULL, + NULL, + NULL + } +}; + +filter_vecs_t * +find_filter_vec(char *const vecname, char **opts) +{ + fl_vecs_t *vec = filter_vec_list; + char *v = xstrdup(vecname); + char *svecname = strtok(v, ","); + int found = 0; + + while (vec->vec) { + arglist_t *ap; + char *res; + + if (case_ignore_strcmp(svecname, vec->name)) { + vec++; + continue; + } + + /* step 1: initialize by inifile or default values */ + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + char *temp; + + temp = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); + if (temp == NULL) temp = inifile_readstr(global_opts.inifile, "Common filter settings", ap->argstring); + if (temp == NULL) temp = ap->defaultvalue; + assign_option(vec->name, ap, temp); + } + } + + /* step 2: override settings with command-line values */ + res = strchr(vecname, ','); + if (res) { + *opts = res+1; + + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++){ + char *opt; + + opt = get_option(*opts, ap->argstring); + if ( opt ) { + found = 1; + assign_option(vec->name, ap, opt); + xfree(opt); + } + } + } + } + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, vec->name); + } + + if (global_opts.debug_level >= 1) + disp_vec_options(vec->name, vec->vec->args); + + xfree(v); + return vec->vec; + + } + xfree(v); + return NULL; +} + +void +free_filter_vec( filter_vecs_t *fvec ) +{ + arglist_t *ap; + + if ( fvec->args ) { + for ( ap = fvec->args; ap->argstring; ap++) { + if (ap->argval && *ap->argval) { + xfree(*ap->argval); + *ap->argval = NULL; + } + } + } +} + +void +exit_filter_vecs( void ) +{ + fl_vecs_t *vec = filter_vec_list; + while ( vec->vec ) { + if ( vec->vec->f_exit ) { + (vec->vec->f_exit)(); + } + vec++; + } +} + + +/* + * Display the available formats in a format that's easy for humans to + * parse for help on available command line options. + */ +void +disp_filter_vecs(void) +{ + fl_vecs_t *vec; + arglist_t *ap; + + for (vec = filter_vec_list; vec->vec; vec++) { + printf(" %-20.20s %-50.50s\n", + vec->name, vec->desc); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if ( !(ap->argtype & ARGTYPE_HIDDEN )) + printf(" %-18.18s %-.50s %s\n", + ap->argstring, ap->helpstring, + (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); + } + } +} + +void +disp_filter_vec( const char *vecname ) +{ + fl_vecs_t *vec; + arglist_t *ap; + + for (vec = filter_vec_list; vec->vec; vec++) { + if ( case_ignore_strcmp( vec->name, vecname )) { + continue; + } + printf(" %-20.20s %-50.50s\n", + vec->name, vec->desc); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if ( !(ap->argtype & ARGTYPE_HIDDEN )) + printf(" %-18.18s %-.50s %s\n", + ap->argstring, ap->helpstring, + (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); + } + } +} + +static signed int +alpha (const void *a, const void *b) +{ + const fl_vecs_t *const ap = a; + const fl_vecs_t *const bp = b; + + return case_ignore_strcmp(ap->desc , bp->desc); +} + +static +void disp_help_url(const fl_vecs_t *vec, arglist_t *arg) +{ + printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); + if (arg) { + printf("#fmt_%s_o_%s",vec->name, arg->argstring); + } +} + +static void +disp_v1(const fl_vecs_t *vec) +{ + arglist_t *ap; + + disp_help_url(vec, NULL); + printf("\n"); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if ( !(ap->argtype & ARGTYPE_HIDDEN)) { + printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", + vec->name, + ap->argstring, + ap->helpstring, + name_option(ap->argtype), + ap->defaultvalue? ap->defaultvalue : "", + ap->minvalue? ap->minvalue : "", + ap->maxvalue? ap->maxvalue : ""); + disp_help_url(vec, ap); + printf("\n"); + } + } +} + +/* + * Display the available formats in a format that's easy to machine + * parse. Typically invoked by programs like graphical wrappers to + * determine what formats are supported. + */ +void +disp_filters(int version) +{ + fl_vecs_t *vec; + + qsort(filter_vec_list, + sizeof(filter_vec_list) / sizeof(filter_vec_list[0]) - 1, + sizeof(filter_vec_list[0]), + alpha); + + + switch(version) { + case 0: + case 1: + for (vec = filter_vec_list; vec->vec; vec++) { + if (version == 0) { + printf("%s\t%s\n", vec->name, vec->desc); + } else { + printf("%s\t%s", vec->name, vec->desc); + disp_v1(vec); + } + } + break; + default: + ; + } +} diff --git a/filterdefs.h b/filterdefs.h new file mode 100644 index 000000000..570450000 --- /dev/null +++ b/filterdefs.h @@ -0,0 +1,46 @@ +/* + Filter definitions. + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + + +/* + * Filters can do some things that modules really shouldn't do. + * This is our (weak) attempt to make that distinction. + */ + +extern queue waypt_head; + +typedef struct filter_vecs { + filter_init f_init; + filter_process f_process; + filter_deinit f_deinit; + filter_exit f_exit; + arglist_t *args; +} filter_vecs_t; + +filter_vecs_t * find_filter_vec(char * const, char **); +void free_filter_vec(filter_vecs_t *); +void disp_filters(int version); +void disp_filter( const char *vecname ); +void disp_filter_vec( const char *vecname ); +void disp_filter_vecs(void); +void exit_filter_vecs(void); + diff --git a/format_skeleton.c b/format_skeleton.c new file mode 100644 index 000000000..82285d916 --- /dev/null +++ b/format_skeleton.c @@ -0,0 +1,156 @@ +/* + + Format converter module skeleton. + + Steps to create a new format. + + 1) Copy this file to .c + 2) Rename all format_skeleton tokens to . + 3) Replace the fictional name and address in the Copyright section below. + As your work is likely built on the work of others, please retain + the original line. + 4) Create a new section in vecs.c. + 5) Add compilation instructions to Makefile. + 6) Add sample files (it's better when they're created by the "real" + application and not our own output) to reference/ along with + files in a well supported (preferably non-binary) format and + entries in our 'testo' program. This allows users of different + OSes and hardware to exercise your module. + + Copyright (C) YYYY John Doe, anybody@wherever.com + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include + +#define MYNAME "format_skeleton" + + +// Any arg in this list will appear in command line help and will be +// populated for you. +// Values for ARGTYPE_xxx can be found in defs.h and are used to +// select the type of option. +static +arglist_t format_skeleton_args[] = { +// {"foo", &fooopt, "The text of the foo option in help", +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR +}; + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +format_skeleton_rd_init(const char *fname) +{ +// fin = gbfopen(fname, "r", MYNAME); +} + +static void +format_skeleton_rd_deinit(void) +{ +// gbfclose(fin); +} + +static void +format_skeleton_read(void) +{ +// your special code to extract waypoint, route and track +// information from gbfile "fin" +// +// Sample text-file read code: +// char *s; +// while ((s = gbfgetstr(fin))) { +// do_anything(s); +// } +// +// +// For waypoints: +// while (have waypoints) { +// waypoint = waypt_new() +// populate waypoint +// waypt_add(waypoint); +// } +// +// For routes: +// +// route = route_head_alloc(); +// populate struct route_hdr +// route_add_head(route); +// while (have more routepoints) { +// waypoint = waypt_new() +// populate waypoint +// route_add_wpt(route, waypoint) +// } +// +// Tracks are just like routes, except the word "track" replaces "routes". +// +} + +static void +format_skeleton_wr_init(const char *fname) +{ +// fout = gbfopen(fname, "w", MYNAME); +} + +static void +format_skeleton_wr_deinit(void) +{ +// gbfclose(fout); +} + +static void +format_skeleton_write(void) +{ +// Here is how you register callbacks for all waypoints, routes, tracks. +// waypt_disp_all(waypt) +// route_disp_all(head, tail, rtept); +// track_disp_all(head, tail, trkpt); +} + +static void +format_skeleton_exit(void) /* optional */ +{ +} + +/**************************************************************************/ + +// capabilities below means: we can only read and write waypoints +// please change this depending on your new module + +ff_vecs_t format_skeleton_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + format_skeleton_rd_init, + format_skeleton_wr_init, + format_skeleton_rd_deinit, + format_skeleton_wr_deinit, + format_skeleton_read, + format_skeleton_write, + format_skeleton_exit, + format_skeleton_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ +}; +/**************************************************************************/ diff --git a/formspec.c b/formspec.c new file mode 100644 index 000000000..ce1dbf90b --- /dev/null +++ b/formspec.c @@ -0,0 +1,67 @@ +/* + Functions to manage the format_specific_data chain + + Copyright (C) 2005 Ron Parker and Robert Lipe. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include + +#include "defs.h" + +format_specific_data *fs_chain_copy( format_specific_data *source ) { + format_specific_data *result = NULL; + + format_specific_data **copy = &result; + while ( source ) { + source->copy( (void **)copy, (void *)source ); + /* prevent segfaults from badly-behaved copy functions */ + (*copy)->next = NULL; + copy = &((*copy)->next); + source = source->next; + } + return result; +} + +void fs_chain_destroy( format_specific_data *chain ) { + format_specific_data *cur = chain; + format_specific_data *next = NULL; + while ( cur ) { + next = cur->next; + cur->destroy( cur ); + cur = next; + } +} + +format_specific_data *fs_chain_find( format_specific_data *chain, long type ) { + format_specific_data *cur = chain; + while ( cur ) { + if (cur->type == type ) { + return cur; + } + cur = cur->next; + } + return NULL; +} + +void fs_chain_add( format_specific_data **chain, format_specific_data *data ) { + data->next = *chain; + *chain = data; +} + diff --git a/g7towin.c b/g7towin.c new file mode 100644 index 000000000..2aca83e66 --- /dev/null +++ b/g7towin.c @@ -0,0 +1,546 @@ +/* + + Support for G7ToWin data files (.g7t), + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +/* + History: + 04/07/2007: start programming + 04/15/2007: added to gpsbabel +*/ + +#include "defs.h" +#include "csv_util.h" +#include "garmin_fs.h" +#include "garmin_tables.h" +#include "jeeps/gpsmath.h" +#include "strptime.h" + +#include + +#if CSVFMTS_ENABLED + +#define MYNAME "g7towin" + +#define G7T_HEADER "Version 2:G7T" + +static gbfile *fin; +static grid_type grid; +static int datum; +static gpsdata_type mode; +static double altf; +static int gardown; +static int event_ct; + +static +arglist_t g7towin_args[] = { + ARG_TERMINATOR +}; + +#define WAYPT__OFS 0x00000 +#define TRKPT__OFS 0x01000 + +#define WPT_c0_OFS 0x0c000 +#define WPT_c1_OFS 0x0c100 +#define WPT_c2_OFS 0x0c200 +#define WPT_c3_OFS 0x0c300 +#define WPT_c4_OFS 0x0c400 +#define WPT_c5_OFS 0x0c500 +#define WPT_c6_OFS 0x0c600 +#define WPT_c7_OFS 0x0c700 +#define WPT_c8_OFS 0x0c800 +#define WPT_cA_OFS 0x0cA00 +#define WPT_cB_OFS 0x0cB00 +#define WPT_cC_OFS 0x0cC00 +#define WPT_cD_OFS 0x0cD00 + +static void +parse_line(char *buff, int index, const char *delimiter, waypoint *wpt) +{ + char *cin; + garmin_fs_p gmsd = GMSD_FIND(wpt); + + while ((cin = csv_lineparse(buff, delimiter, "", index++))) { + + buff = NULL; + cin = lrtrim(cin); + + if ((*cin == '\0') || + (strcmp(cin, "INF") == 0) || + (strcmp(cin, "1e25") == 0) || + (strcmp(cin, "1.0e25") == 0)) continue; + + switch(index) { + + int categories, dyn; + struct tm tm; + char *cerr; + + case TRKPT__OFS + 1: + cin += parse_coordinates(cin, datum, grid, + &wpt->latitude, &wpt->longitude, MYNAME); + while (isspace(*cin)) cin++; + + memset(&tm, 0, sizeof(tm)); + cerr = strptime(cin, "%a %b %d %H:%M:%S %Y", &tm); + if (cerr == NULL) { + fatal(MYNAME ": Unable to convert date (%s)!\n", cin); + } + wpt->creation_time = mkgmtime(&tm); + break; + + case WAYPT__OFS + 1: + wpt->description = xstrdup(cin); + break; + + case WAYPT__OFS + 2: + wpt->icon_descr = gt_find_desc_from_icon_number( + atoi(cin), PCX, &dyn); + wpt->wpt_flags.icon_descr_is_dynamic = dyn; + break; + + case WAYPT__OFS + 4: + if (strcmp(cin, "S+C") == 0) { + GMSD_SET(display, gt_display_mode_symbol_and_comment); + } + else if (strcmp(cin, "S") == 0) { + GMSD_SET(display, gt_display_mode_symbol); + } + else if (strcmp(cin, "S+N") == 0) { + GMSD_SET(display, gt_display_mode_symbol_and_name); + } + break; + + case WPT_cA_OFS + 1: + case WPT_c1_OFS + 1: + if (wpt->shortname) xfree(wpt->shortname); + wpt->shortname = xstrdup(cin); + break; + + case WPT_cA_OFS + 4: + case WPT_c4_OFS + 2: + GMSD_SETSTR(city, cin); + break; + + case WPT_cA_OFS + 5: + case WPT_c4_OFS + 3: + GMSD_SETSTR(state, cin); + break; + + case WPT_cA_OFS + 6: + case WPT_c4_OFS + 4: + GMSD_SETSTR(cc, cin); + break; + + case WPT_cB_OFS + 1: + case WPT_c6_OFS + 2: + GMSD_SETSTR(facility, cin); + break; + + case WPT_cB_OFS + 2: + case WPT_c6_OFS + 3: + GMSD_SETSTR(addr, cin); + break; + + case WPT_cB_OFS + 3: /*cross road */ + case WPT_c6_OFS + 4: + GMSD_SETSTR(cross_road, cin); + break; + + case TRKPT__OFS + 2: /* altitude */ + case WPT_cC_OFS + 1: + case WPT_c5_OFS + 1: + case WPT_c8_OFS + 1: + wpt->altitude = altf * atof(cin); + break; + + case TRKPT__OFS + 3: /* depth */ + case WPT_cC_OFS + 2: + case WPT_c5_OFS + 2: + case WPT_c8_OFS + 2: + WAYPT_SET(wpt, depth, altf * atof(cin)); + break; + + case TRKPT__OFS + 10: /* temperature */ + if (*cin == '|') cin++; /* in track points */ + if (strcmp(cin, "1e25") == 0) break; + if (strcmp(cin, "1.0e25") == 0) break; + /* !!! NO BREAK !!! */ + case WPT_cD_OFS + 1: + case WPT_cB_OFS + 6: + WAYPT_SET(wpt, temperature, atof(cin)); + break; + + case WAYPT__OFS + 6: /* proximity */ + case WPT_cD_OFS + 2: + WAYPT_SET(wpt, proximity, atof(cin)); + break; + + case WPT_cB_OFS + 5: + case WPT_cD_OFS + 3: + categories = atoi(cin); + if (categories != 0) + GMSD_SET(category, atoi(cin)); + break; + +#if 0 + +/* currently unused */ + + case TRKPT__OFS + 5: /* distance from previous point */ + case TRKPT__OFS + 6: /* distance from segment start */ + case TRKPT__OFS + 7: /* distance from start */ + case TRKPT__OFS + 8: /* velocity from previous point */ + case TRKPT__OFS + 9: /* time (in seconds) from previous point */ + break; + + case WAYPT__OFS + 3: /* ignore color */ + break; + + case WAYPT__OFS + 5: /* always '0' */ + break; + + case TRKPT__OFS + 4: + if (case_ignore_strcmp(cin, "FT") == 0) ; + else if (case_ignore_strcmp(cin, "M") == 0) ; + else if (case_ignore_strcmp(cin, "SM") == 0) ; + else if (case_ignore_strcmp(cin, "NM") == 0) ; + else if (case_ignore_strcmp(cin, "KM") == 0) ; + break; + + case WPT_cB_OFS + 4: /* unknown (datatype) */ + break; + + case WPT_cC_OFS + 3: /* waypt_class (always FF) */ + break; + + case WPT_cC_OFS + 4: /* class & subclass */ + case WPT_cC_OFS + 5: + case WPT_cC_OFS + 6: + case WPT_cC_OFS + 7: + case WPT_cC_OFS + 8: + case WPT_cC_OFS + 9: + case WPT_cC_OFS + 10: + case WPT_cC_OFS + 11: + case WPT_cC_OFS + 12: + case WPT_cC_OFS + 13: + case WPT_cC_OFS + 14: + case WPT_cC_OFS + 15: + case WPT_cC_OFS + 16: + case WPT_cC_OFS + 17: + case WPT_cC_OFS + 18: + case WPT_cC_OFS + 19: + case WPT_cC_OFS + 20: + case WPT_cC_OFS + 21: + break; + + case WPT_cC_OFS + 22: + /* distance */ + break; +#endif + } + } +} + +static waypoint * +parse_waypt(char *buff) +{ + char *cin, *cerr; + int i; + struct tm tm; + waypoint *wpt; + garmin_fs_p gmsd; + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + if (gardown) + cin = buff + 6; + else { + /* We've seen waypoints with length of 14 and 15 !!! */ + cin = buff + 15; + while ((cin > buff) && (! isspace(*cin))) cin--; + } + + while (isspace(*cin)) cin--; + if (cin >= buff) + wpt->shortname = xstrndup(buff, cin - buff + 1); + + if (gardown) + buff += 6; + else + buff += 15; + while (isspace(*buff)) buff++; + + buff += parse_coordinates(buff, datum, grid, + &wpt->latitude, &wpt->longitude, MYNAME); + while (isspace(*buff)) buff++; + + memset(&tm, 0, sizeof(tm)); + cerr = strptime(buff, "%a %b %d %H:%M:%S %Y", &tm); + if (cerr == NULL) + fatal(MYNAME ": Unable to convert date (%s)!\n", buff); + wpt->creation_time = mkgmtime(&tm); + + /* go over time stamp */ + i = 5; + while (buff && i) { + i--; + buff = strchr(buff, ' '); + if (buff) buff++; + } + if (gardown && (buff == NULL)) return wpt; + is_fatal((buff == NULL), MYNAME ": Incomplete waypoint line!"); + + while (isspace(*buff)) buff++; + + parse_line(buff, WAYPT__OFS, "^", wpt); + + return wpt; +} + +static waypoint * +parse_trkpt(char *buff) +{ + garmin_fs_p gmsd; + waypoint *wpt; + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + parse_line(buff, TRKPT__OFS, ";", wpt); + + return wpt; +} + +/* + * parse_categories is currently only a dummy procedure. + * w'll need a central storage with binding to the module + * which has established a list of category names. + */ + +static void +parse_categories(char *buff) +{ + char *cin; + int cat = 0; + + while ((cin = csv_lineparse(buff, ",", "", cat++))) { + gbuint16 cx; + + buff = NULL; + + cin = lrtrim(cin); + if (*cin == 0) continue; + + garmin_fs_convert_category(cin, &cx); + } +} + + +/* main functions */ + +static void +rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); + + gardown = 1; + mode = wptdata; + grid = grid_lat_lon_dmm; + datum = DATUM_WGS84; + altf = 1; + event_ct = 0; +} + +static void +rd_deinit(void) +{ + gbfclose(fin); +} + +static void +data_read(void) +{ + char *buff; + int line = 0; + waypoint *wpt = NULL; + waypoint *prev = NULL; + route_head *head = NULL; + + while ((buff = gbfgetstr(fin))) { + char *cin = buff; + char *cdata; + + line++; + + cin = lrtrim(buff); + if (!*cin) continue; + + cdata = cin+1; + while (! isspace(*cdata)) cdata++; + while (isspace(*cdata)) cdata++; + if (! *cdata) continue; + + switch(*cin) { + + case '#': /* comment */ + break; + + case 'A': + if (case_ignore_strncmp(cdata, "Meter", 5) == 0) + altf = 1.0; + else if (case_ignore_strncmp(cdata, "Feet", 4) == 0) + altf = FEET_TO_METERS(1.0); + break; + + case 'C': /* categories */ + parse_categories(cdata); + break; + + case 'D': + datum = gt_lookup_datum_index(cdata, MYNAME); + break; + + case 'I': /* event point */ + wpt = waypt_new(); + cdata += parse_coordinates(cdata, datum, grid, + &wpt->latitude, &wpt->longitude, MYNAME); + xasprintf(&wpt->shortname, "Event%d", ++event_ct); + while (isspace(*cdata)) cdata++; + if (*cdata == ';') { + int dyn; + + cdata++; + wpt->icon_descr = gt_find_desc_from_icon_number( + atoi(cdata), PCX, &dyn); + wpt->wpt_flags.icon_descr_is_dynamic = dyn; + } + waypt_add(wpt); + break; + + case 'M': + grid = gt_lookup_grid_type(cdata, MYNAME); + break; + + case 'P': /* proximity waypoint */ + case 'W': /* normal waypoint */ + wpt = parse_waypt(cin + 3); + prev = wpt; + if (wpt) { + if (mode == rtedata) + route_add_wpt(head, wpt); + else + waypt_add(wpt); + } + break; + + case 'c': /* additional lines */ + switch(*(cin+1)) { + int index; + + case 'A': case 'B': + case 'C': case 'D': + + index = WPT_cA_OFS + ((*(cin+1) - 'A') * 256); + parse_line(cdata, index, "|", wpt); + break; + + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': + + index = WPT_c0_OFS + ((*(cin+1) - '0') * 256); + parse_line(cdata, index, ";", wpt); + break; + + case 'L': + waypt_add_url(wpt, xstrdup(cdata), NULL); + break; + + default: + break; + } + break; + + case 'N': /* track log header */ + mode = trkdata; + head = route_head_alloc(); + cdata = strchr(cdata, '-'); + if (cdata) { + while (isspace(*cdata)) cdata++; + if (*cdata) { + char *s; + s = strrchr(cdata, ','); + if (s) { + *s = '\0'; + s = strrchr(cdata, ','); + if (s) { + *s = '\0'; + head->rte_name = xstrdup(cdata); + } + } + } + } + track_add_head(head); + break; + + case 'R': /* route header */ + mode = rtedata; + head = route_head_alloc(); + cdata += 3; /*skip route number */ + if (*cdata) head->rte_name = xstrdup(cdata); + route_add_head(head); + break; + + case 'T': + wpt = parse_trkpt(cdata); + if (wpt) track_add_wpt(head, wpt); + break; + + case 'V': + if (strcmp(cin, G7T_HEADER) != 0) { + fatal(MYNAME ": Invalid version or invalid file!\n"); + } + gardown = 0; + break; + + default: + break; + } + } +} + +/* --------------------------------------------------------------------------- */ + +ff_vecs_t g7towin_vecs = { + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_read }, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + g7towin_args, + CET_CHARSET_MS_ANSI, 0 +}; + +#endif /* CSVFMTS_ENABLED */ diff --git a/garmin.c b/garmin.c new file mode 100644 index 000000000..7ee0126cf --- /dev/null +++ b/garmin.c @@ -0,0 +1,1055 @@ +/* + Jeeps wrapper for Garmin serial protocol. + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include "defs.h" +#include "jeeps/gps.h" +#include "garmin_tables.h" +#include "garmin_fs.h" + +#define SOON 1 + +#define MYNAME "GARMIN" +static const char *portname; +static short_handle mkshort_handle; +static GPS_PWay *tx_routelist; +static GPS_PWay *cur_tx_routelist_entry; +static GPS_PTrack *tx_tracklist; +static GPS_PTrack *cur_tx_tracklist_entry; +static int my_track_count = 0; +static char *getposn = NULL; +static char *poweroff = NULL; +static char *resettime = NULL; +static char *snlen = NULL; +static char *snwhiteopt = NULL; +static char *deficon = NULL; +static char *category = NULL; +static char *categorybitsopt = NULL; +static int categorybits; + +#define MILITANT_VALID_WAYPT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + +/* Technically, even this is a little loose as spaces arent allowed */ +static const char *valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " "; + +static +arglist_t garmin_args[] = { + { "snlen", &snlen, "Length of generated shortnames", NULL, + ARGTYPE_INT, "1", NULL }, + { "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + { "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "get_posn", &getposn, "Return current position as a waypoint", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + { "power_off", &poweroff, "Command unit to power itself down", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + { "resettime", &resettime, "Sync GPS time to computer time", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + { "category", &category, "Category number to use for written waypoints", + NULL, ARGTYPE_INT, "1", "16"}, + { "bitscategory", &categorybitsopt, "Bitmap of categories", + NULL, ARGTYPE_INT, "1", "65535"}, + ARG_TERMINATOR +}; + +static const char * d103_symbol_from_icon_number(unsigned int n); +static int d103_icon_number_from_symbol(const char *s); + +static void +rw_init(const char *fname) +{ + int receiver_short_length; + int receiver_must_upper = 1; + char * receiver_charset = NULL; + + if (!mkshort_handle) + mkshort_handle = mkshort_new_handle(); + + if (global_opts.debug_level > 0) { + GPS_Enable_Warning(); + GPS_Enable_User(); + } + if (global_opts.debug_level > 1) { + GPS_Enable_Diagnose(); + } + GPS_Enable_Error(); + + if (poweroff) { + GPS_Command_Off(fname); + return; + } + + /* + * THis is Gross. The B&W Vista sometimes sets its time decades into + * the future with no way to reset it. This apparently can "cure" + * an affected unit. + */ + if (resettime) { + GPS_Command_Send_Time(fname, current_time()); + return; + } + + if (categorybitsopt) { + categorybits = strtol(categorybitsopt, NULL, 0); + } + + if (GPS_Init(fname) < 0) { + fatal(MYNAME ":Can't init %s\n", fname); + } + portname = fname; + + /* + * Grope the unit we're talking to to set setshort_length to + * 20 for the V, + * 10 for Street Pilot, Rhino, 76 + * 6 for the III, 12, emap, and etrex + * Fortunately, getting this "wrong" only results in ugly names + * when we're using the synthesize_shortname path. + */ + receiver_short_length = 10; + + switch ( gps_waypt_type ) /* waypoint type as defined by jeeps */ + { + case 0: + fatal("Garmin unit %d does not support waypoint xfer.", + gps_save_id); + + break; + case 100: /* The GARMIN GPS Interface Specification, */ + case 101: /* says these waypoint types use an ident */ + case 102: /* length of 6. Waypoint types 106, 108 */ + case 103: /* and 109 are all variable length */ + case 104: + case 105: + case 107: + case 150: + case 151: + case 152: + case 154: + case 155: + receiver_short_length = 6; + break; + case 106: /* Waypoint types with variable ident length */ + case 108: /* Need GPSr id to know the actual length */ + case 109: + case 110: + switch ( gps_save_id ) + { + case 130: /* Garmin Etrex (yellow) */ + receiver_short_length = 6; + break; + case 295: /* eTrex (yellow, fw v. 3.30) */ + case 696: /* eTrex HC */ + receiver_short_length = 6; + valid_waypt_chars = + MILITANT_VALID_WAYPT_CHARS " +-"; + setshort_badchars(mkshort_handle, "\"$.,'!"); + break; + + case 155: /* Garmin V */ + case 404: /* SP2720 */ + case 520: /* SP2820 */ + receiver_short_length = 20; + break; + case 382: /* C320 */ + receiver_short_length = 30; + receiver_must_upper = 0; + break; + case 292: /* (60|76)C[S]x series */ + case 421: /* Vista|Legend Cx */ + case 694: /* Legend HCx */ + case 695: /* Vista HCx */ + case 786: /* HC model */ + receiver_short_length = 14; + snwhiteopt = xstrdup("1"); + receiver_must_upper = 0; + /* This might be 8859-1 */ + receiver_charset = CET_CHARSET_MS_ANSI; + break; + case 291: /* GPSMAP 60CS, probably others */ + receiver_short_length = 10; + valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " +-"; + setshort_badchars(mkshort_handle, "\"$.,'!"); + break; + case 231: /* Quest */ + case 463: /* Quest 2 */ + receiver_must_upper = 0; + receiver_short_length = 30; + receiver_charset = CET_CHARSET_MS_ANSI; + break; + case 260: /* GPSMap 296 */ + default: + break; + } + break; + default: + break; + + } + if (global_opts.debug_level > 0) { + fprintf(stderr, "Waypoint type: %d\n" + "Chosen waypoint length %d\n", + gps_waypt_type, receiver_short_length); + if (gps_category_type) { + fprintf(stderr, "Waypoint category type: %d\n", + gps_category_type); + } + + } + /* + * If the user provided a short_length, override the calculated value. + */ + if (snlen) + setshort_length(mkshort_handle, atoi(snlen)); + else + setshort_length(mkshort_handle, receiver_short_length); + + if (snwhiteopt) + setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + + /* + * Until Garmins documents how to determine valid character space + * for the new models, we just release this safety check manually. + */ + if (receiver_must_upper) { + setshort_goodchars(mkshort_handle, valid_waypt_chars); + } else { + setshort_badchars(mkshort_handle, ""); + } + + setshort_mustupper(mkshort_handle, receiver_must_upper); + + if (receiver_charset) + cet_convert_init(receiver_charset, 1); + + +} + +static void +rw_deinit(void) +{ + if (mkshort_handle) { + mkshort_del_handle(&mkshort_handle); + } +} + +static int +waypt_read_cb(int total_ct, GPS_PWay *way) +{ + static int i; + + if (global_opts.verbose_status) { + i++; + waypt_status_disp(total_ct, i); + } + return 0; +} + +static void +waypt_read(void) +{ + int i,n; + GPS_PWay *way = NULL; + + if (getposn) { + waypoint *wpt = waypt_new(); + wpt->latitude = gps_save_lat; + wpt->longitude = gps_save_lon; + wpt->shortname = xstrdup("Position"); + if (gps_save_time) + wpt->creation_time = gps_save_time; + waypt_add(wpt); + return; + } + + if ((n = GPS_Command_Get_Waypoint(portname, &way, waypt_read_cb)) < 0) { + fatal(MYNAME ":Can't get waypoint from %s\n", portname); + } + + for (i = 0; i < n; i++) { + waypoint *wpt_tmp = waypt_new(); + + wpt_tmp->shortname = xstrdup(way[i]->ident); + wpt_tmp->description = xstrdup(way[i]->cmnt); + rtrim(wpt_tmp->shortname); + rtrim(wpt_tmp->description); + wpt_tmp->longitude = way[i]->lon; + wpt_tmp->latitude = way[i]->lat; + if (gps_waypt_type == 103) { + wpt_tmp->icon_descr = d103_symbol_from_icon_number( + way[i]->smbl); + } else { + int dyn = 0; + wpt_tmp->icon_descr = gt_find_desc_from_icon_number( + way[i]->smbl, PCX, &dyn); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = dyn; + } + /* + * If a unit doesn't store altitude info (i.e. a D103) + * gpsmem will default the alt to INT_MAX. Other units + * (I can't recall if it was the V (D109) hor the Vista (D108) + * return INT_MAX+1, contrary to the Garmin protocol doc which + * says they should report 1.0e25. So we'll try to trap + * all the cases here. Yes, libjeeps should probably + * do this and not us... + */ + if ((way[i]->alt == (float) (1U<<31)) || + (way[i]->alt == INT_MAX) || + (way[i]->alt >= (float) 1.0e20) + ) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = way[i]->alt; + } + if (way[i]->time_populated) { + wpt_tmp->creation_time = way[i]->time; + } +#if SOON + garmin_fs_garmin_after_read(way[i], wpt_tmp, gps_waypt_type); +#endif + waypt_add(wpt_tmp); + GPS_Way_Del(&way[i]); + } + if (way) { + xfree(way); + } +} + +static +void +track_read(void) +{ + int32 ntracks; + GPS_PTrack *array; + route_head *trk_head = NULL; + int trk_num = 0; + int i; + int trk_seg_num = 1; + char trk_seg_num_buf[10]; + char *trk_name = ""; + + ntracks = GPS_Command_Get_Track(portname, &array, waypt_read_cb); + + if ( ntracks <= 0 ) + return; + + for(i = 0; i < ntracks; i++) { + waypoint *wpt; + + /* + * This is probably always in slot zero, but the Garmin + * serial spec says these can appear anywhere. Toss them + * out so we don't treat it as an extraneous trackpoint. + */ + if (array[i]->ishdr) { + trk_name = array[i]->trk_ident; + if (!trk_name) + trk_name = ""; + trk_seg_num = 1; + } + + + if ((trk_head == NULL) || array[i]->tnew) { + trk_head = route_head_alloc(); + trk_head->rte_num = trk_num; + if (trk_seg_num == 1) { + trk_head->rte_name = xstrdup(trk_name); + } else { + /* name in the form TRACKNAME #n */ + snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); + trk_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); + sprintf(trk_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); + } + trk_seg_num++; + trk_num++; + track_add_head(trk_head); + } + + if (array[i]->no_latlon || array[i]->ishdr) { + continue; + } + wpt = waypt_new(); + + wpt->longitude = array[i]->lon; + wpt->latitude = array[i]->lat; + wpt->altitude = array[i]->alt; + wpt->heartrate = array[i]->heartrate; + wpt->cadence = array[i]->cadence; + wpt->shortname = xstrdup(array[i]->trk_ident); + wpt->creation_time = array[i]->Time; + + track_add_wpt(trk_head, wpt); + } + + while(ntracks) { + GPS_Track_Del(&array[--ntracks]); + } + xfree(array); +} + +static +void +route_read(void) +{ + int32 nroutepts; + int i; + GPS_PWay *array; + /* TODO: Fixes warning but is it right? + * RJL: No, the warning isn't right; GCC's flow analysis is broken. + * still, it's good taste... + */ + route_head *rte_head = NULL; + + nroutepts = GPS_Command_Get_Route(portname, &array); + +// fprintf(stderr, "Routes %d\n", (int) nroutepts); +#if 1 + for (i = 0; i < nroutepts; i++) { + if (array[i]->isrte) { + char *csrc = NULL; + /* What a horrible API has libjeeps for making this + * my problem. + */ + switch (array[i]->rte_prot) { + case 201: csrc = array[i]->rte_cmnt; break; + case 202: csrc = array[i]->rte_ident; break; + default: break; + } + rte_head = route_head_alloc(); + route_add_head(rte_head); + if (csrc) { + rte_head->rte_name = xstrdup(csrc); + } + } else { + if (array[i]->islink) { + continue; + } else { + waypoint *wpt_tmp = xcalloc(sizeof (*wpt_tmp), 1); + wpt_tmp->latitude = array[i]->lat; + wpt_tmp->longitude = array[i]->lon; + wpt_tmp->shortname = array[i]->ident; + route_add_wpt(rte_head, wpt_tmp); + } + } + } +#else + GPS_Fmt_Print_Route(array, nroutepts, stderr); +#endif + +} + +#if 0 +static +void +lap_read_as_track(void) +{ + int32 ntracks; + GPS_PLap *array; + route_head *trk_head = NULL; + int trk_num = 0; + int index; + int i; + + ntracks = GPS_Command_Get_Lap(portname, &array, waypt_read_cb); + if ( ntracks <= 0 ) + return; + for (i = 0; i < ntracks; i++) { + waypoint *wpt; + if (array[i]->index == -1){ + index=i; + } else { + index=array[i]->index; + index=i; + } + + if ((trk_head == NULL) || (i == 0) || + /* D906 - last track:index is the track index */ + (array[i]->index == -1 && array[i]->track_index != 255) || + /* D10xx - no real separator, use begin/end time to guess */ + (abs(array[i-1]->start_time + array[i]->total_time/100-array[i]->start_time) > 2) + ) { + static struct tm * stmp; + stmp = gmtime(&array[i]->start_time); + trk_head = route_head_alloc(); + /*For D906, we would like to use the track_index in the last packet instead...*/ + trk_head->rte_num = ++trk_num; + trk_head->rte_name = xmalloc(32); + strftime(trk_head->rte_name, 32, "%Y-%m-%dT%H:%M:%SZ", stmp); + track_add_head(trk_head); + + wpt = waypt_new(); + + wpt->longitude = array[i]->begin_lon; + wpt->latitude = array[i]->begin_lat; + wpt->heartrate = array[i]->avg_heart_rate; + wpt->cadence = array[i]->avg_cadence; + wpt->speed = array[i]->max_speed; + wpt->creation_time = array[i]->start_time; + wpt->microseconds = 0; + + wpt->shortname = xmalloc(8); + sprintf(wpt->shortname, "#%d-0", index); + wpt->description = xmalloc(128); + sprintf(wpt->description, "D:%f Cal:%d MS:%f AH:%d MH:%d AC:%d I:%d T:%d", + array[i]->total_distance, array[i]->calories, array[i]->max_speed, array[i]->avg_heart_rate, + array[i]->max_heart_rate, array[i]->avg_cadence, array[i]->intensity, array[i]->trigger_method); + + track_add_wpt(trk_head, wpt); + } +/*Allow even if no correct location, no skip if invalid */ +/* if (array[i]->no_latlon) { +* continue; +* } +*/ + wpt = waypt_new(); + + wpt->longitude = array[i]->end_lon; + wpt->latitude = array[i]->end_lat; + wpt->heartrate = array[i]->avg_heart_rate; + wpt->cadence = array[i]->avg_cadence; + wpt->speed = array[i]->max_speed; + wpt->creation_time = array[i]->start_time + array[i]->total_time/100; + wpt->microseconds = 10000*(array[i]->total_time % 100); + /*Add fields with no mapping in the description */ + wpt->shortname = xmalloc(8); + sprintf(wpt->shortname, "#%d", index); + wpt->description = xmalloc(128); + sprintf(wpt->description, "D:%f Cal:%d MS:%f AH:%d MH:%d AC:%d I:%d T:%d (%f,%f)", + array[i]->total_distance, array[i]->calories, array[i]->max_speed, array[i]->avg_heart_rate, + array[i]->max_heart_rate, array[i]->avg_cadence, array[i]->intensity, array[i]->trigger_method, + array[i]->begin_lon, array[i]->begin_lat); + + track_add_wpt(trk_head, wpt); + } + while(ntracks) { + GPS_Lap_Del(&array[--ntracks]); + } + xfree(array); +} +#endif + +/* + * Rather than propogate Garmin-specific data types outside of the Garmin + * code, we convert the PVT (position/velocity/time) data from the receiver + * to the data type we use throughout. Yes, we do lose some data that way. + */ +static void +pvt2wpt(GPS_PPvt_Data pvt, waypoint *wpt) +{ + double wptime, wptimes; + + wpt->altitude = pvt->alt; + wpt->latitude = pvt->lat; + wpt->longitude = pvt->lon; + + /* + * The unit reports time in three fields: + * 1) The # of days to most recent Sun. since 1989-12-31 midnight UTC. + * 2) The number of seconds (fractions allowed) since that Sunday. + * 3) The number of leap seconds that offset the current UTC and GPS + * reference clocks. + */ + wptime = 631065600.0 + pvt->wn_days * 86400.0 + + pvt->tow + - pvt->leap_scnds; + wptimes = floor(wptime); + wpt->creation_time = wptimes; + wpt->microseconds = 1000000.0 * (wptime - wptimes); + + /* + * The Garmin spec fifteen different models that use a different + * table for 'fix' without a really good way to tell if the model + * we're talking to happens to be one of those...By inspection, + * it looks like even though the models (Summit, Legend, etc.) may + * be popular, it's older (2001 and earlier or so) versions that + * are affected and I think there are relatively few readers of + * the fix field anyway. Time will tell if this is a good plan. + */ + switch (pvt->fix) { + case 0: wpt->fix = fix_unknown;break; + case 1: wpt->fix = fix_none;break; + case 2: wpt->fix = fix_2d;break; + case 3: wpt->fix = fix_3d;break; + case 4: wpt->fix = fix_dgps;break; /* 2D_diff */ + case 5: wpt->fix = fix_dgps;break; /* 3D_diff */ + default: + /* undocumented type. */ + break; + } +} + +static gpsdevh *pvt_fd; + +static void +pvt_init(const char *fname) +{ + rw_init(fname); + GPS_Command_Pvt_On(fname, &pvt_fd); +} + +static waypoint * +pvt_read(posn_status *posn_status) +{ + waypoint *wpt = waypt_new(); + GPS_PPvt_Data pvt = GPS_Pvt_New(); + + if (GPS_Command_Pvt_Get(&pvt_fd, &pvt)) { + pvt2wpt(pvt, wpt); + GPS_Pvt_Del(&pvt); + + wpt->shortname = xstrdup("Position"); + + if (gps_errno && posn_status) { + posn_status->request_terminate = 1; + } + + return wpt; + } + + /* + * If the caller has not given us a better way to return the + * error, do it now. + */ + if (gps_errno) { + fatal(MYNAME ": Fatal error reading position.\n"); + } + + waypt_free(wpt); + GPS_Pvt_Del(&pvt); + + return NULL; +} + +static void +data_read(void) +{ + if (poweroff) { + return; + } + + if (global_opts.masked_objective & WPTDATAMASK) + waypt_read(); + if (global_opts.masked_objective & TRKDATAMASK) + track_read(); + if (global_opts.masked_objective & RTEDATAMASK) + route_read(); + if (!(global_opts.masked_objective & + (WPTDATAMASK | TRKDATAMASK | RTEDATAMASK | POSNDATAMASK))) + fatal(MYNAME ": Nothing to do.\n"); +} + +static GPS_PWay +sane_GPS_Way_New(void) +{ + GPS_PWay way; + way = GPS_Way_New(); + if (!way) { + fatal(MYNAME ":not enough memory\n"); + } + + /* + * Undo less than helpful defaults from Way_New. + */ + way->rte_ident[0] = 0; + way->rte_cmnt[0] = 0; + way->rte_link_subclass[0] = 0; + way->rte_link_ident[0] = 0; + way->city[0] = 0; + way->state[0] = 0; + way->facility[0] = 0; + way->addr[0] = 0; + way->cross_road[0] = 0; + way->cross_road[0] = 0; + way->dpth = 1.0e25f; + way->wpt_class = 0; + + return way; +} + +static int +waypt_write_cb(GPS_PWay *way) +{ + static int i; + int n = waypt_count(); + + if (global_opts.verbose_status) { + i++; + waypt_status_disp(n, i); + } + return 0; +} + +/* + * If we're using smart names, try to put the cache info in the + * description. + */ +const char * +get_gc_info(waypoint *wpt) +{ + if (global_opts.smart_names) { + if (wpt->gc_data.type == gt_virtual) return "V "; + if (wpt->gc_data.type == gt_unknown) return "? "; + if (wpt->gc_data.type == gt_multi) return "Mlt "; + if (wpt->gc_data.type == gt_earth) return "EC "; + if (wpt->gc_data.type == gt_event) return "Ev "; + if (wpt->gc_data.container == gc_micro) return "M "; + if (wpt->gc_data.container == gc_small) return "S "; + } + return ""; +} + +static void +waypoint_write(void) +{ + int i; + int32 ret; + int n = waypt_count(); + queue *elem, *tmp; + extern queue waypt_head; + GPS_PWay *way; + int icon; + + way = xcalloc(n,sizeof(*way)); + + for (i = 0; i < n; i++) { + way[i] = sane_GPS_Way_New(); + } + + i = 0; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wpt; + char *ident; + char *src = NULL; + char obuf[256]; + + wpt = (waypoint *) elem; + + if(wpt->description) src = wpt->description; + if(wpt->notes) src = wpt->notes; + + /* + * mkshort will do collision detection and namespace + * cleaning + */ + ident = mkshort(mkshort_handle, + global_opts.synthesize_shortnames ? src : + wpt->shortname); + /* Should not be a strcpy as 'ident' isn't really a C string, + * but rather a garmin "fixed length" buffer that's padded + * to the end with spaces. So this is NOT (strlen+1). + */ + memcpy(way[i]->ident, ident, strlen(ident)); + + if (global_opts.synthesize_shortnames) { + xfree(ident); + } + way[i]->ident[sizeof(way[i]->ident)-1] = 0; + + // If we were explictly given a comment from GPX, use that. + if (wpt->description) { + memcpy(way[i]->cmnt, wpt->description, strlen(wpt->description)); + } else { + if (global_opts.smart_names && + wpt->gc_data.diff && wpt->gc_data.terr) { +#if 0 +xasprintf(&src, "%s %s", &wpt->shortname[2], src); +#endif + snprintf(obuf, sizeof(obuf), "%s%d/%d %s", + get_gc_info(wpt), + wpt->gc_data.diff, wpt->gc_data.terr, + src); + memcpy(way[i]->cmnt, obuf, strlen(obuf)); + } else { + memcpy(way[i]->cmnt, src, strlen(src)); + } + } + + + + way[i]->lon = wpt->longitude; + way[i]->lat = wpt->latitude; + + if (deficon) { + icon = gt_find_icon_number_from_desc(deficon, PCX); + } else { + if (get_cache_icon(wpt)) { + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + } else { + icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + } + } + + /* For units that support tiny numbers of waypoints, just + * overwrite that and go very literal. + */ + if (gps_waypt_type == 103) { + icon = d103_icon_number_from_symbol(wpt->icon_descr); + } + way[i]->smbl = icon; + if (wpt->altitude == unknown_alt) { + way[i]->alt_is_unknown = 1; + way[i]->alt = 0; + } else { + way[i]->alt = wpt->altitude; + } + if (wpt->creation_time) { + way[i]->time = wpt->creation_time; + way[i]->time_populated = 1; + } + if (category) { + way[i]->category = 1 << (atoi(category) - 1); + } + if (categorybits) { + way[i]->category = categorybits; + } +#if SOON + garmin_fs_garmin_before_write(wpt, way[i], gps_waypt_type); +#endif + i++; + } + + if ((ret = GPS_Command_Send_Waypoint(portname, way, n, waypt_write_cb)) < 0) { + fatal(MYNAME ":communication error sending wayoints..\n"); + } + + for (i = 0; i < n; ++i) { + GPS_Way_Del(&way[i]); + } + if (global_opts.verbose_status) { + fprintf(stdout, "\r\n"); + fflush(stdout); + } + xfree(way); +} + +static void +route_hdr_pr(const route_head *rte) +{ + (*cur_tx_routelist_entry)->rte_num = rte->rte_num; + (*cur_tx_routelist_entry)->isrte = 1; + if (rte->rte_name) { + strncpy((*cur_tx_routelist_entry)->rte_ident, rte->rte_name, + sizeof ((*cur_tx_routelist_entry)->rte_ident)); + } +} + +static void +route_waypt_pr(const waypoint *wpt) +{ + GPS_PWay rte = *cur_tx_routelist_entry; + char *s, *d; + + /* + * As stupid as this is, libjeeps seems to want an empty + * waypoint between every link in a route that has nothing + * but the 'islink' member set. Rather than "fixing" libjeeps, + * we just double them up (sigh) and do that here. + */ + rte->islink = 1; + rte->lon = wpt->longitude; + rte->lat = wpt->latitude; + cur_tx_routelist_entry++; + rte = *cur_tx_routelist_entry; + + rte->lon = wpt->longitude; + rte->lat = wpt->latitude; + rte->smbl = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + + if (wpt->altitude != unknown_alt) { + rte->alt = wpt->altitude; + } else { + rte->alt_is_unknown = 1; + rte->alt = 0; + } + + // Garmin protocol spec says no spaces, no lowercase, etc. in a route. + // enforce that here, since jeeps doesn't. + // + // This was strncpy(rte->ident, wpt->shortname, sizeof(rte->ident)); + d = rte->ident; + for (s = wpt->shortname; *s; s++) { + int c = *s; + if (isalpha(c)) c = toupper(c); + if (strchr(MILITANT_VALID_WAYPT_CHARS, c)) { + *d++ = c; + } + } + + rte->ident[sizeof(rte->ident)-1] = 0; + + if (wpt->description) { + strncpy(rte->cmnt, wpt->description, sizeof(rte->cmnt)); + rte->cmnt[sizeof(rte->ident)-1] = 0; + } else { + rte->cmnt[0] = 0; + } + cur_tx_routelist_entry++; +} + +static void +route_noop(const route_head *wp) +{ +} + +static void +route_write(void) +{ + int i; + int n = 2 * route_waypt_count(); /* Doubled for the islink crap. */ + + tx_routelist = xcalloc(n,sizeof(GPS_PWay)); + cur_tx_routelist_entry = tx_routelist; + + for (i = 0; i < n; i++) { + tx_routelist[i] = sane_GPS_Way_New(); + } + + route_disp_all(route_hdr_pr, route_noop, route_waypt_pr); + GPS_Command_Send_Route(portname, tx_routelist, n); +} + +static void +track_hdr_pr(const route_head *trk_head) +{ + (*cur_tx_tracklist_entry)->tnew = gpsTrue; + (*cur_tx_tracklist_entry)->ishdr = gpsTrue; + if ( trk_head->rte_name ) { + strncpy((*cur_tx_tracklist_entry)->trk_ident, trk_head->rte_name, sizeof((*cur_tx_tracklist_entry)->trk_ident)); + (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; + } else { + sprintf((*cur_tx_tracklist_entry)->trk_ident, "TRACK%02d", my_track_count); + } + cur_tx_tracklist_entry++; + my_track_count++; +} + +static void +track_waypt_pr(const waypoint *wpt) +{ + (*cur_tx_tracklist_entry)->lat = wpt->latitude; + (*cur_tx_tracklist_entry)->lon = wpt->longitude; + (*cur_tx_tracklist_entry)->alt = wpt->altitude; + (*cur_tx_tracklist_entry)->Time = wpt->creation_time; + if ( wpt->shortname ) { + strncpy((*cur_tx_tracklist_entry)->trk_ident, wpt->shortname, sizeof((*cur_tx_tracklist_entry)->trk_ident)); + (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; + } + cur_tx_tracklist_entry++; +} + +static void +track_write(void) +{ + int i; + int n = track_waypt_count() + track_count(); + + tx_tracklist = xcalloc(n, sizeof(GPS_PTrack)); + cur_tx_tracklist_entry = tx_tracklist; + for (i = 0; i < n; i++) { + tx_tracklist[i] = GPS_Track_New(); + } + my_track_count = 0; + track_disp_all(track_hdr_pr, route_noop, track_waypt_pr); + + GPS_Command_Send_Track(portname, tx_tracklist, n); + + for (i = 0; i < n; i++) { + GPS_Track_Del(&tx_tracklist[i]); + } + xfree(tx_tracklist); +} + +static void +data_write(void) +{ + if (poweroff) { + return; + } + + if (global_opts.masked_objective & WPTDATAMASK) + waypoint_write(); + if (global_opts.masked_objective & RTEDATAMASK) + route_write(); + if (global_opts.masked_objective & TRKDATAMASK) + track_write(); +} + + +ff_vecs_t garmin_vecs = { + ff_type_serial, + FF_CAP_RW_ALL, + rw_init, + rw_init, + rw_deinit, + rw_deinit, + data_read, + data_write, + NULL, + garmin_args, + CET_CHARSET_ASCII, 0, + { pvt_init, pvt_read, rw_deinit, NULL, NULL, NULL } +}; + +static const char *d103_icons[16] = { + "dot", + "house", + "gas", + "car", + "fish", + "boat", + "anchor", + "wreck", + "exit", + "skull", + "flag", + "camp", + "circle_x", + "deer", + "1st_aid", + "back-track" +}; + +static const char * +d103_symbol_from_icon_number(unsigned int n) +{ + if (n <= 15) + return d103_icons[n]; + else + return "unknown"; +} + +static int +d103_icon_number_from_symbol(const char *s) +{ + unsigned int i; + + if (NULL == s) { + return 0; + } + + for (i = 0; i < sizeof(d103_icons) / sizeof(d103_icons[0]); i++) { + if (0 == case_ignore_strcmp(s, d103_icons[i])) + return i; + } + return 0; +} diff --git a/garmin_fs.c b/garmin_fs.c new file mode 100644 index 000000000..76a65aa8d --- /dev/null +++ b/garmin_fs.c @@ -0,0 +1,415 @@ +/* + + Implementation of special data used by Garmin products. + + Copyright (C) 2006, 2007, 2008 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "garmin_fs.h" +#include "garmin_tables.h" +#include "inifile.h" + +#define MYNAME "garmin_fs" + +#define GARMIN_GPX_EXT_REFERENCE \ + "xmlns:gpxx=\"" \ + "http://www.garmin.com/xmlschemas/GpxExtensions/v3\" " \ + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \ + "xsi:schemaLocation=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3 " \ + "http://www.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd" + +garmin_fs_t * +garmin_fs_alloc(const int protocol) +{ + garmin_fs_t *result = NULL; + + result = (garmin_fs_t *)xcalloc(1, sizeof(*result)); + result->fs.type = FS_GMSD; + result->fs.copy = (fs_copy) garmin_fs_copy; + result->fs.destroy = garmin_fs_destroy; + result->fs.convert = garmin_fs_convert; + result->fs.next = NULL; + + result->protocol = protocol; + + return result; +} + +void +garmin_fs_destroy(void *fs) +{ + garmin_fs_t *data = (garmin_fs_t *) fs; + if (data != NULL) + { + garmin_ilink_t *ilinks; + + if (data->addr != NULL) xfree(data->addr); + if (data->cc != NULL) xfree(data->cc); + if (data->city != NULL) xfree(data->city); + if (data->country != NULL) xfree(data->country); + if (data->cross_road != NULL) xfree(data->cross_road); + if (data->facility != NULL) xfree(data->facility); + if (data->phone_nr != NULL) xfree(data->phone_nr); + if (data->postal_code != NULL) xfree(data->postal_code); + if (data->state != NULL) xfree(data->state); + + if ((ilinks = data->ilinks) != NULL) { + ilinks->ref_count--; + if (ilinks->ref_count <= 0) { + while (ilinks != NULL) { + garmin_ilink_t *tmp = ilinks; + ilinks = ilinks->next; + xfree(tmp); + } + } + } + xfree(data); + } +} + +void garmin_fs_copy(garmin_fs_t **dest, garmin_fs_t *src) +{ + if (src == NULL) + { + *dest = NULL; + return; + } + *dest = (garmin_fs_t *) xmalloc(sizeof(*src)); + + /* do not copy interlinks, only increment the refrence counter */ + if (src->ilinks != NULL) src->ilinks->ref_count++; + + memcpy(*dest, src, sizeof(*src)); + + (*dest)->addr = (src->addr != NULL) ? xstrdup(src->addr) : NULL; + (*dest)->cc = (src->cc != NULL) ? xstrdup(src->cc) : NULL; + (*dest)->city = (src->city != NULL) ? xstrdup(src->city) : NULL; + (*dest)->country = (src->country != NULL) ? xstrdup(src->country) : NULL; + (*dest)->cross_road = (src->cross_road != NULL) ? xstrdup(src->cross_road) : NULL; + (*dest)->facility = (src->facility != NULL) ? xstrdup(src->facility) : NULL; + (*dest)->phone_nr = (src->phone_nr != NULL) ? xstrdup(src->phone_nr) : NULL; + (*dest)->postal_code = (src->postal_code != NULL) ? xstrdup(src->postal_code) : NULL; + (*dest)->state = (src->state != NULL) ? xstrdup(src->state) : NULL; +} + +void garmin_fs_convert(void *fs) +{ + garmin_fs_t *gmsd = (garmin_fs_t *) fs; + + if (gmsd->addr) gmsd->addr = cet_convert_string(gmsd->addr); + if (gmsd->cc) gmsd->cc = cet_convert_string(gmsd->cc); + if (gmsd->city) gmsd->city = cet_convert_string(gmsd->city); + if (gmsd->country) gmsd->country = cet_convert_string(gmsd->country); + if (gmsd->cross_road) gmsd->cross_road = cet_convert_string(gmsd->cross_road); + if (gmsd->facility) gmsd->facility = cet_convert_string(gmsd->facility); + if (gmsd->phone_nr) gmsd->phone_nr = cet_convert_string(gmsd->phone_nr); + if (gmsd->postal_code) gmsd->postal_code = cet_convert_string(gmsd->postal_code); + if (gmsd->state) gmsd->state = cet_convert_string(gmsd->state); +} + +/* GPX - out */ + +void +garmin_fs_xml_fprint(gbfile *ofd, const waypoint *waypt) +{ + char *phone, *addr; + garmin_fs_t *gmsd = GMSD_FIND(waypt); + + if (gmsd == NULL) return; + + /* Find out if there is at least one field set */ + addr = GMSD_GET(addr, ""); + if (! *addr) addr = GMSD_GET(city, ""); + if (! *addr) addr = GMSD_GET(country, ""); + if (! *addr) addr = GMSD_GET(postal_code, ""); + if (! *addr) addr = GMSD_GET(state, ""); + + phone = GMSD_GET(phone_nr, ""); + + if (*addr || *phone || + (gmsd->flags.category && gmsd->category) || + WAYPT_HAS(waypt, depth) || + WAYPT_HAS(waypt, proximity) || + WAYPT_HAS(waypt, temperature) || + gmsd->flags.display) + { + int space = 1; + + gbfprintf(ofd, "%*s\n", space++ * 2, ""); + gbfprintf(ofd, "%*s\n", space++ * 2, "", GARMIN_GPX_EXT_REFERENCE); + if WAYPT_HAS(waypt, proximity) + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->proximity); + if WAYPT_HAS(waypt, temperature) + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->temperature); + if WAYPT_HAS(waypt, depth) + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->depth); + if (gmsd->flags.display) + { + char *cx; + switch(gmsd->display) + { + case gt_display_mode_symbol: + cx = "SymbolOnly"; + break; + case gt_display_mode_symbol_and_comment: + cx = "SymbolAndDescription"; + break; + default: + cx = "SymbolAndName"; + break; + } + gbfprintf(ofd, "%*s%s\n", space * 2, "", cx); + } + if (gmsd->flags.category && gmsd->category) + { + int i; + gbuint16 cx = gmsd->category; + gbfprintf(ofd, "%*s\n", space++ * 2, ""); + for (i = 0; i < 16; i++) + { + if (cx & 1) + gbfprintf(ofd, "%*sCategory %d\n", space*2, "", i+1); + cx = cx >> 1; + } + gbfprintf(ofd, "%*s\n", --space * 2, ""); + } + if (*addr) { + char *str, *tmp; + gbfprintf(ofd, "%*s\n", space++ * 2, ""); + + if ((str = GMSD_GET(addr, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(city, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(state, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(country, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(postal_code, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + + gbfprintf(ofd, "%*s\n", --space * 2, ""); + } + + if (*phone) { + char *tmp = xml_entitize(phone); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + + gbfprintf(ofd, "%*s\n", --space * 2, ""); + gbfprintf(ofd, "%*s\n", --space * 2, ""); + } + +} + +void +garmin_fs_xml_convert(const int base_tag, int tag, const char *cdatastr, waypoint *waypt) +{ + garmin_fs_t *gmsd; + + gmsd = GMSD_FIND(waypt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&waypt->fs, (format_specific_data *) gmsd); + } + + tag -= base_tag; +/* + tt_garmin_waypt_extension, -> 0 + tt_garmin_proximity, -> 1 + tt_garmin_temperature,-> 2 + tt_garmin_depth, -> 3 + tt_garmin_display_mode, -> 4 + tt_garmin_categories, -> 5 + tt_garmin_category, -> 6 + tt_garmin_addr, -> 7 + tt_garmin_city, -> 8 + tt_garmin_state, -> 9 + tt_garmin_country, -> 10 + tt_garmin_postal_code, -> 11 + tt_garmin_phone_nr, -> 12 +*/ + switch(tag) { + case 1: + if (*cdatastr) WAYPT_SET(waypt, proximity, atof(cdatastr)); + break; + case 2: + if (*cdatastr) WAYPT_SET(waypt, temperature, atof(cdatastr)); + break; + case 3: + if (*cdatastr) WAYPT_SET(waypt, depth, atof(cdatastr)); + break; + case 4: + if (case_ignore_strcmp(cdatastr, "SymbolOnly") == 0) { + GMSD_SET(display, gt_display_mode_symbol); + } + else if (case_ignore_strcmp(cdatastr, "SymbolAndDescription") == 0) { + GMSD_SET(display, gt_display_mode_symbol_and_comment); + } + else { + GMSD_SET(display, gt_display_mode_symbol_and_name); + } + break; + case 6: + if ( ! garmin_fs_merge_category(cdatastr, waypt)) + warning(MYNAME ": Unable to convert category \"%s \"!\n", cdatastr); + break; + case 7: + GMSD_SETSTR(addr, cdatastr); + break; + case 8: + GMSD_SETSTR(city, cdatastr); + break; + case 9: + GMSD_SETSTR(state, cdatastr); + break; + case 10: + GMSD_SETSTR(country, cdatastr); + break; + case 11: + GMSD_SETSTR(postal_code, cdatastr); + break; + case 12: + GMSD_SETSTR(phone_nr, cdatastr); + break; + } +} + +unsigned char +garmin_fs_convert_category(const char *category_name, gbuint16 *category) +{ + int i; + int cat = 0; + + if ((case_ignore_strncmp(category_name, "Category ", 9) == 0) && + (1 == sscanf(category_name + 9, "%d", &i)) && + (i >= 1) && (i <= 16)) { + cat = (1 << --i); + } + else if (global_opts.inifile != NULL) { + for (i = 0; i < 16; i++) { + char *c; + char key[3]; + + snprintf(key, sizeof(key), "%d", i + 1); + c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); + if ((c != NULL) && (case_ignore_strcmp(c, category_name) == 0)) { + cat = (1 << i); + break; + } + } + } + if (cat == 0) { + return 0; + } + else { + *category = cat; + return 1; + } +} + +unsigned char +garmin_fs_merge_category(const char *category_name, waypoint *waypt) +{ + gbuint16 cat; + garmin_fs_t *gmsd; + + if (!garmin_fs_convert_category(category_name, &cat)) { + return 0; + } + + gmsd = GMSD_FIND(waypt); + cat = cat | ( GMSD_GET(category, 0) ); + + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&waypt->fs, (format_specific_data *) gmsd); + } + GMSD_SET(category, cat); + return 1; +} + +void +garmin_fs_garmin_after_read(const GPS_PWay way, waypoint *wpt, const int protoid) +{ + garmin_fs_t *gmsd = NULL; + + gmsd = garmin_fs_alloc(protoid); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + /* nothing happens until gmsd is allocated some lines above */ + + /* !!! class needs protocol specific conversion !!! (ToDo) + GMSD_SET(wpt_class, way[i]->wpt_class); + */ + /* flagged data fields */ + GMSD_SET(display, gt_switch_display_mode_value(way->dspl, gps_waypt_type, 1)); + if (way->category != 0) GMSD_SET(category, way->category); + if (way->dst < 1.0e25f) WAYPT_SET(wpt, proximity, way->dst); + if (way->temperature_populated) WAYPT_SET(wpt, temperature, way->temperature); + if (way->dpth < 1.0e25f) WAYPT_SET(wpt, depth, way->dpth); + GMSD_SETNSTR(cc, way->cc, sizeof(way->cc)); + GMSD_SETNSTR(state, way->state, sizeof(way->state)); + GMSD_SETSTR(city, way->city); + GMSD_SETSTR(facility, way->facility); + GMSD_SETSTR(cross_road, way->cross_road); + GMSD_SETSTR(addr, way->addr); +} + +void +garmin_fs_garmin_before_write(const waypoint *wpt, GPS_PWay way, const int protoid) +{ + garmin_fs_t *gmsd = GMSD_FIND(wpt); + + if (gmsd == NULL) return; + + /* ToDo: protocol specific conversion of class + way[i]->wpt_class = GMSD_GET(wpt_class, way[i]->wpt_class); + */ + way->dspl = gt_switch_display_mode_value( + GMSD_GET(display, way->dspl), gps_waypt_type, 0); + way->category = GMSD_GET(category, way->category); + way->dpth = WAYPT_GET(wpt, depth, way->dpth); + way->dst = WAYPT_GET(wpt, proximity, way->dpth); + way->temperature = WAYPT_GET(wpt, temperature, way->temperature); + + GMSD_GETNSTR(cc, way->cc, sizeof(way->cc)); + GMSD_GETNSTR(city, way->city, sizeof(way->city)); + GMSD_GETNSTR(state, way->state, sizeof(way->state)); + GMSD_GETNSTR(facility, way->facility, sizeof(way->facility)); + GMSD_GETNSTR(cross_road, way->cross_road, sizeof(way->cross_road)); + GMSD_GETNSTR(addr, way->addr, sizeof(way->addr)); +} + diff --git a/garmin_fs.h b/garmin_fs.h new file mode 100644 index 000000000..c1999e1d9 --- /dev/null +++ b/garmin_fs.h @@ -0,0 +1,135 @@ +/* + + Implementation of special data used by Garmin products. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifndef GARMIN_FS_H +#define GARMIN_FS_H + +#include +#include "defs.h" +#include "jeeps/gps.h" + +/* this order is used by most devices */ +/* typedef enum { + garmin_display_symbol_and_name = 0, + garmin_display_symbol_only = 1, + garmin_display_symbol_and_description = 2 +} garmin_display_t; +*/ + +/* macros */ + +#define GMSD_FIND(a) (garmin_fs_t *) fs_chain_find((a)->fs, FS_GMSD) +#define GMSD_HAS(a) (gmsd && gmsd->flags.a) + +/* GMSD_GET(a,b): a = any gmsd field, b = default value */ +#define GMSD_GET(a,b) ((gmsd) && (gmsd->flags.a)) ? (gmsd->a) : (b) + +/* GMSD_SET(a,b): a = numeric gmsd field, b = numeric source */ +#define GMSD_SET(a,b) if (gmsd) {gmsd->a = (b); gmsd->flags.a = 1; } + +/* GMSD_UNSET(a): a = gmsd field */ +#define GMSD_UNSET(a) if (gmsd) { gmsd->flags.a = 0; } + +/* GMSD_SETSTR(a,b): a = gmsd field, b = null terminated source */ +#define GMSD_SETSTR(a,b) if (gmsd && (b) && (b)[0]) { gmsd->a = xstrdup((b)); gmsd->flags.a = 1; } + +/* GMSD_SETNSTR(a,b,c): a = gmsd field, b = source, c = sizeof(source) */ +#define GMSD_SETNSTR(a,b,c) if (gmsd && (b) && (b)[0]) { gmsd->a = xstrndup((b),(c)); gmsd->flags.a = 1; } + +/* GMSD_GETNSTR(a,b,c): a = gmsd field, b = target, c = sizeof(target) */ +#define GMSD_GETNSTR(a,b,c) if (gmsd && gmsd->flags.a) strncpy((b),gmsd->a,(c)) + +typedef struct garmin_ilink_s { + int ref_count; + double lat, lon, alt; + struct garmin_ilink_s *next; +} garmin_ilink_t; + +typedef struct { + unsigned int icon:1; + unsigned int wpt_class:1; + unsigned int display:1; + unsigned int category:1; + unsigned int city:1; + unsigned int state:1; + unsigned int facility:1; + unsigned int cc:1; + unsigned int cross_road:1; + unsigned int addr:1; + unsigned int country:1; + unsigned int phone_nr:1; + unsigned int postal_code:1; +#ifdef GMSD_EXPERIMENTAL + unsigned int subclass:1; +#endif +} garmin_fs_flags_t; + +typedef struct garmin_fs_s +{ + format_specific_data fs; + garmin_fs_flags_t flags; + + int protocol; /* ... used by device (-1 is MapSource) */ + + gbint32 icon; + int wpt_class; + gbint32 display; + gbint16 category; + char *city; /* city name */ + char *facility; /* facility name */ + char *state; /* state */ + char *cc; /* country code */ + char *cross_road; /* Intersection road label */ + char *addr; /* address + number */ + char *country; /* country */ + char *phone_nr; /* phone number */ + char *postal_code; /* postal code */ + garmin_ilink_t *ilinks; +#ifdef GMSD_EXPERIMENTAL + char subclass[22]; +#endif +} garmin_fs_t, *garmin_fs_p; + +garmin_fs_t *garmin_fs_alloc(const int protocol); +void garmin_fs_destroy(void *fs); +void garmin_fs_copy(garmin_fs_t **dest, garmin_fs_t *src); +void garmin_fs_convert(void *fs); +char *garmin_fs_xstrdup(const char *src, size_t size); + +/* for GPX */ +void garmin_fs_xml_convert(const int base_tag, int tag, const char *cdatastr, waypoint *waypt); +void garmin_fs_xml_fprint(gbfile *ofd, const waypoint *waypt); + +/* common garmin_fs utilities */ + +/* ..convert_category: returns 1=OK; 0=Unable to convert category */ +unsigned char garmin_fs_convert_category(const char *category_name, gbuint16 *category); + +/* ..merge_category: returns 1=OK; 0=Unable to convert category */ +unsigned char garmin_fs_merge_category(const char *category_name, waypoint *waypt); + +#define GMSD_SECTION_CATEGORIES "Garmin Categories" + +void garmin_fs_garmin_after_read(const GPS_PWay way, waypoint *wpt, const int protoid); +void garmin_fs_garmin_before_write(const waypoint *wpt, GPS_PWay way, const int protoid); + +#endif diff --git a/garmin_gpi.c b/garmin_gpi.c new file mode 100644 index 000000000..e2b9ec07f --- /dev/null +++ b/garmin_gpi.c @@ -0,0 +1,1360 @@ +/* + + Support for Garmin Points of Interest (.gpi files) + + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +/* + History: + + * 2007/05/18: initial release (only a reader) + * 2007/05/20: added writer code with embedded bitmap + * 2007/05/22: add support for multiple bounding boxes + (useful / required!) for large waypoints lists + * 2007/05/23: add optional user bitmap + * 2007/06/02: new method to compute center (mean) of bounds + avoid endless loop in group splitting + * 2007/07/10: put address fields (i.e. city) into GMSD + * 2007/07/12: add write support for new address fields + * 2007/10/20: add option unique + * 2007/12/02: support speed and proximity distance (+ alerts) + * 2008/01/14: fix structure error after adding speed/proximity + * 2008/03/22: add options "speed" and "proximity" (default values) and "sleep" + + ToDo: + + * Display mode ("Symbol & Name") ??? not in gpi ??? + * support category from GMSD "Garmin Special Data" +*/ + +#include "defs.h" +#include "cet_util.h" +#include "jeeps/gpsmath.h" +#include "garmin_fs.h" +#include "garmin_gpi.h" +#include +#include +#include +#include + +#define MYNAME "garmin_gpi" + +#define GPI_DBG 1 +#undef GPI_DBG + +#define DEFAULT_ICON "Waypoint" +#define WAYPOINTS_PER_BLOCK 128 + +/* flags used in the gpi address mask */ +#define GPI_ADDR_CITY 1 +#define GPI_ADDR_COUNTRY 2 +#define GPI_ADDR_STATE 4 +#define GPI_ADDR_POSTAL_CODE 8 +#define GPI_ADDR_ADDR 16 + +static char *opt_cat, *opt_pos, *opt_notes, *opt_hide_bitmap, *opt_descr, *opt_bitmap; +static char *opt_unique, *opt_alerts, *opt_units, *opt_speed, *opt_proximity, *opt_sleep; +static double defspeed, defproximity; +static int alerts; + +static arglist_t garmin_gpi_args[] = { + {"alerts", &opt_alerts, "Enable alerts on speed or proximity distance", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"bitmap", &opt_bitmap, "Use specified bitmap on output", + NULL, ARGTYPE_FILE, ARG_NOMINMAX}, + {"category", &opt_cat, "Default category on output", + "My points", ARGTYPE_STRING, ARG_NOMINMAX}, + {"hide", &opt_hide_bitmap, "Don't show gpi bitmap on device", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"descr", &opt_descr, "Write description to address field", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"notes", &opt_notes, "Write notes to address field", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"position", &opt_pos, "Write position to address field", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"proximity", &opt_proximity, "Default proximity", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX}, + {"sleep", &opt_sleep, "After output job done sleep n second(s)", + NULL, ARGTYPE_INT, "1", NULL}, + {"speed", &opt_speed, "Default speed", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX}, + {"unique", &opt_unique, "Create unique waypoint names (default = yes)", + "Y", ARGTYPE_BOOL, ARG_NOMINMAX}, + {"units", &opt_units, "Units used for names with @speed ('s'tatute or 'm'etric)", + "m", ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +typedef struct { + int D2; + char S3[9]; /* "GRMRECnn" */ + time_t crdate; /* creation date and time */ + char POI[4]; /* "POI" */ + char S8[3]; + char *group; + char *category; +} reader_data_t; + +typedef struct writer_data_s { + queue Q; + int ct; + int sz; + int alert; + bounds bds; + struct writer_data_s *top_left; + struct writer_data_s *top_right; + struct writer_data_s *buttom_left; + struct writer_data_s *buttom_right; +} writer_data_t; + +typedef struct gpi_waypt_data_s { + int sz; + char *addr; + char *postal_code; +} gpi_waypt_data_t; + +typedef struct { + gbint32 size; + gbint16 res1; + gbint16 res2; + gbint32 image_offset; + gbint32 header_size; + gbint32 width; + gbint32 height; + gbint16 planes; + gbint16 bpp; + gbint32 compression_type; + gbint32 image_data_size; + gbint32 resolution_h; + gbint32 resolution_v; + gbint32 used_colors; + gbint32 important_colors; +} bmp_header_t; + +typedef struct { + gbint16 index; + gbint16 height; + gbint16 width; + gbint16 line_sz; + gbint16 bpp; + gbint16 fixed_0; + gbint32 image_size; + gbint32 fixed_2c; + gbint32 flag1; + gbint32 tr_color; + gbint32 flag2; + gbint32 size_2c; +} gpi_bitmap_header_t; + +typedef struct { + int sz; + int alerts; + short mask; + char addr_is_dynamic; + char *addr; + char *city; + char *country; + char *phone_nr; + char *postal_code; + char *state; +} gpi_waypt_t; + +static gbfile *fin, *fout; +static gbint32 codepage; /* code-page, i.e. 1252 */ +static reader_data_t *rdata; +static writer_data_t *wdata; +static short_handle short_h; +static char units; +static time_t gpi_timestamp = 0; + +#ifdef GPI_DBG +# define PP warning("@%1$6x (%1$8d): ", gbftell(fin)) +# define dbginfo warning +#else +# define PP +#endif + +/******************************************************************************* +* %%% gpi reader %%% * +*******************************************************************************/ + +/* look for or initialize GMSD */ +static garmin_fs_t * +gpi_gmsd_init(waypoint *wpt) +{ + garmin_fs_t *gmsd = GMSD_FIND(wpt); + if (wpt == NULL) { + fatal(MYNAME ": Error in file structure.\n"); + } + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + return gmsd; +} + +/* read a standard string with or without 'EN' (or whatever) header */ +static char * +gpi_read_string(const char *field) +{ + int l1; + char *res = NULL; + + l1 = gbfgetint16(fin); + if (l1 > 0) { + short l2; + char first; + + first = gbfgetc(fin); + if (first == 0) { + char en[2]; + + is_fatal((gbfgetc(fin) != 0), + MYNAME ": Error reading field '%s'!", field); + + gbfread(en, 1, sizeof(en), fin); + l2 = gbfgetint16(fin); + is_fatal((l2 + 4 != l1), + MYNAME ": Error out of sync (wrong size %d/%d) on field '%s'!", l1, l2, field); + + if ((en[0] < 'A') || (en[0] > 'Z') || (en[1] < 'A') || (en[1] > 'Z')) + fatal(MYNAME ": Invalid country code!\n"); + res = xmalloc(l2 + 1); + res[l2] = '\0'; + PP; + if (l2 > 0) + gbfread(res, 1, l2, fin); + } + else { + res = xmalloc(l1 + 1); + *res = first; + *(res + l1) = '\0'; + PP; + l1--; + if (l1 > 0) + gbfread(res + 1, 1, l1, fin); + + } + } +#ifdef GPI_DBG + dbginfo("%s: %s\n", field, (res == NULL) ? "" : res); +#endif + return res; +} + +static void +read_header(void) +{ + int len, i; +#ifdef GPI_DBG + struct tm tm; + char stime[32]; +#endif + + i = gbfgetint32(fin); + if (i != 0) i = gbfgetint32(fin); + rdata->D2 = gbfgetint32(fin); + + gbfread(&rdata->S3, 1, sizeof(rdata->S3) - 1, fin); /* GRMRECnn */ + if (strncmp(rdata->S3, "GRMREC", 6) != 0) + fatal(MYNAME ": No GPI file!\n"); + + PP; + rdata->crdate = gbfgetint32(fin); +#ifdef GPI_DBG + tm = *localtime(&rdata->crdate); + tm.tm_year += 20; /* !!! */ + tm.tm_mday -= 1; /* !!! */ + strftime(stime, sizeof(stime), "%Y/%m/%d %H:%M:%S", &tm); + dbginfo("crdate = %lu (%s)\n", rdata->crdate, stime); +#endif + + (void) gbfgetint16(fin); /* 0 */ + + len = gbfgetint16(fin); + gbfseek(fin, len, SEEK_CUR); /* "my.gpi" */ + + (void) gbfgetint32(fin); /* 1 */ + (void) gbfgetint32(fin); /* 12 */ + + gbfread(&rdata->POI, 1, sizeof(rdata->POI) - 1, fin); + if (strcmp(rdata->POI, "POI") != 0) + fatal(MYNAME ": Wrong or unsupported GPI file!\n"); + + for (i = 0; i < 3; i++) (void)gbfgetc(fin); + gbfread(&rdata->S8, 1, sizeof(rdata->S8) - 1, fin); + + codepage = gbfgetint32(fin); + +#ifdef GPI_DBG + PP; + dbginfo("< leaving header\n"); +#endif +} + +/* gpi tag handler */ +static int read_tag(const char *caller, const int tag, waypoint *wpt); + + +/* read a single poi with all options */ +static void +read_poi(const int sz) +{ + int pos, len; + waypoint *wpt; + +#ifdef GPI_DBG + PP; + dbginfo("> reading poi (size %d)\n", sz); +#endif + PP; + len = gbfgetint32(fin); /* sub-header size */ +#ifdef GPI_DBG + dbginfo("poi sublen = %1$d (0x%1$x)\n", len); +#endif + pos = gbftell(fin); + + wpt = waypt_new(); + wpt->icon_descr = DEFAULT_ICON; + + wpt->latitude = GPS_Math_Semi_To_Deg(gbfgetint32(fin)); + wpt->longitude = GPS_Math_Semi_To_Deg(gbfgetint32(fin)); + + (void) gbfgetint16(fin); /* ? always 1 ? */ + (void) gbfgetc(fin); /* seems to 1 when extra options present */ + + wpt->shortname = gpi_read_string("Shortname"); + + while (gbftell(fin) < (gbsize_t)(pos + sz - 4)) { + int tag = gbfgetint32(fin); + if (! read_tag("read_poi", tag, wpt)) break; + } + + if (wpt->notes && !wpt->description) wpt->description = xstrdup(wpt->notes); + if (wpt->description && !wpt->notes) wpt->notes = xstrdup(wpt->description); + + waypt_add(wpt); + +#ifdef GPI_DBG + PP; + dbginfo("< leaving poi\n"); +#endif +} + +/* read poi's following a group header */ +static void +read_poi_list(const int sz) +{ + int pos, i; + + pos = gbftell(fin); +#ifdef GPI_DBG + PP; + dbginfo("> reading poi list (-> %1$x / %1$d )\n", pos + sz); +#endif + PP; + i = gbfgetint32(fin); /* mostly 23 (0x17) */ +#ifdef GPI_DBG + dbginfo("list sublen = %1$d (0x%1$x)\n", i); +#endif + (void) gbfgetint32(fin); /* max-lat */ + (void) gbfgetint32(fin); /* max-lon */ + (void) gbfgetint32(fin); /* min-lat */ + (void) gbfgetint32(fin); /* min-lon */ + + (void) gbfgetc(fin); /* three unknown bytes */ + (void) gbfgetc(fin); /* ? should be zero ? */ + (void) gbfgetc(fin); + + (void) gbfgetint32(fin); /* ? const 0x1000100 ? */ + + while (gbftell(fin) < (gbsize_t)(pos + sz - 4)) { + int tag = gbfgetint32(fin); + if (! read_tag("read_poi_list", tag, NULL)) return; + } +#ifdef GPI_DBG + PP; + dbginfo("< leaving poi list\n"); +#endif +} + + +static void +read_poi_group(const int sz, const int tag) +{ + int pos; + + pos = gbftell(fin); +#ifdef GPI_DBG + PP; + dbginfo("> reading poi group (-> %1$x / %1$d)\n", pos + sz); +#endif + if (tag == 0x80009) { + int subsz; + + PP; + subsz = gbfgetint32(fin); /* ? offset to category data ? */ +#ifdef GPI_DBG + dbginfo("group sublen = %d (-> %x / %d)\n", subsz, pos + subsz + 4, pos + subsz + 4); +#endif + } + if (rdata->group) xfree(rdata->group); /* currently unused */ + rdata->group = gpi_read_string("Group"); + + while (gbftell(fin) < (gbsize_t)(pos + sz)) { + int subtag = gbfgetint32(fin); + if (! read_tag("read_poi_group", subtag, NULL)) break; + } + +#ifdef GPI_DBG + PP; + dbginfo("< leaving poi group\n"); +#endif +} + + +/* gpi tag handler */ +static int +read_tag(const char *caller, const int tag, waypoint *wpt) +{ + int pos, sz, dist; + double speed; + short mask; + char *str; + garmin_fs_t *gmsd; + + sz = gbfgetint32(fin); + pos = gbftell(fin); + +#ifdef GPI_DBG + PP; + dbginfo("%s: tag = 0x%x (size %d)\n", caller, tag, sz); +#endif + if ((tag >= 0x80000) && (tag <= 0x800ff)) sz += 4; + + switch(tag) { + case 0x3: /* size = 12 */ + + dist = gbfgetint16(fin); /* proximity distance in meters */ + speed = (double)gbfgetint16(fin) / 100; /* speed in meters per second */ + + if (dist > 0) WAYPT_SET(wpt, proximity, dist); + if (speed > 0) { + /* speed isn't part of a normal waypoint + WAYPT_SET(wpt, speed, speed); + */ + if ((wpt->shortname == NULL) || (! strchr(wpt->shortname, '@'))) { + if (units == 's') speed = MPS_TO_MPH(speed); + else speed = MPS_TO_KPH(speed); + xasprintf(&str, "%s@%.f", wpt->shortname ? wpt->shortname : "WPT", speed); + if (wpt->shortname) xfree(wpt->shortname); + wpt->shortname = str; + } + } + + (void) gbfgetint32(fin); + (void) gbfgetint32(fin); + break; + + case 0x4: /* size = 2 ? */ + case 0x6: /* size = 2 ? */ + break; + + case 0x5: /* group bitmap */ + break; + + case 0x7: + (void) gbfgetint16(fin); /* category number */ + if (rdata->category) xfree(rdata->category); + rdata->category = gpi_read_string("Category"); + break; + + case 0xa: + wpt->description = gpi_read_string("Description"); + break; + + case 0xe: /* ? notes or description / or both ? */ + mask = gbfgetc(fin); + if (mask == 0x01) { + str = gpi_read_string("Notes"); + } + else if (mask == 0x32) { + str = gpi_read_string("Notes"); + } + else break; + + if (wpt->description) wpt->notes = str; + else wpt->description = str; + break; + + case 0x80002: + read_poi(sz); + break; + + case 0x80008: + read_poi_list(sz); + break; + + case 0x9: /* ? older versions / no category data ? */ + case 0x80009: /* current POI loader */ + read_poi_group(sz, tag); + break; + + case 0x8000b: /* address (street/city...) */ + (void) gbfgetint32(fin); + PP; + mask = gbfgetint16(fin); /* address fields mask */ +#ifdef GPI_DBG + dbginfo("GPI Address field mask: %d (0x%02x)\n", mask, mask); +#endif + if ((mask & GPI_ADDR_CITY) && (str = gpi_read_string("City"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(city, str); + } + if ((mask & GPI_ADDR_COUNTRY) && (str = gpi_read_string("Country"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(country, str); + } + if ((mask & GPI_ADDR_STATE) && (str = gpi_read_string("State"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(state, str); + } + if ((mask & GPI_ADDR_POSTAL_CODE) && (str = gpi_read_string("Postal code"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(postal_code, str); + } + if ((mask & GPI_ADDR_ADDR) && (str = gpi_read_string("Street address"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(addr, str); + } + break; + + case 0x8000c: /* phone-number */ + (void) gbfgetint32(fin); + PP; + + mask = gbfgetint16(fin); /* phone fields mask */ +#ifdef GPI_DBG + dbginfo("GPI Phone field mask: %d (0x%02x)\n", mask, mask); +#endif + if ((mask & 1) && (str = gpi_read_string("Phone"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(phone_nr, str); + } + break; + + case 0x80012: /* ? sounds / images ? */ + break; + + default: + warning(MYNAME ": Unknown tag (0x%x). Please report!\n", tag); + return 0; + } + gbfseek(fin, pos + sz, SEEK_SET); + return 1; +} + +/******************************************************************************* +* %%% gpi writer %%% * +*******************************************************************************/ + +static void +write_string(const char *str, const char long_format) +{ + int len; + + len = strlen(str); + if (long_format) { + gbfputint32(len + 4, fout); + gbfwrite("EN", 1, 2, fout); + } + gbfputint16(len, fout); + gbfwrite(str, 1, len, fout); +} + + +static int +compare_wpt_cb(const queue *a, const queue *b) +{ + const waypoint *wa = (waypoint *) a; + const waypoint *wb = (waypoint *) b; + + return strcmp(wa->shortname, wb->shortname); +} + + +static char +compare_strings(const char *s1, const char *s2) +{ + if (s1 == s2) return 0; + else if (s1) { + if (s2) return strcmp(s1, s2); + else return 1; + } + else return 1; +} + + +static writer_data_t * +wdata_alloc() +{ + writer_data_t *res; + + res = xcalloc(1, sizeof(*res)); + QUEUE_INIT(&res->Q); + waypt_init_bounds(&res->bds); + + return res; +} + + +static void +wdata_free(writer_data_t *data) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + + if (wpt->extra_data) { + gpi_waypt_t *dt = (gpi_waypt_t *) wpt->extra_data; + if (dt->addr_is_dynamic) xfree(dt->addr); + xfree(dt); + } + waypt_free(wpt); + } + + if (data->top_left) wdata_free(data->top_left); + if (data->top_right) wdata_free(data->top_right); + if (data->buttom_left) wdata_free(data->buttom_left); + if (data->buttom_right) wdata_free(data->buttom_right); + + xfree(data); +} + + +static void +wdata_add_wpt(writer_data_t *data, waypoint *wpt) +{ + data->ct++; + ENQUEUE_TAIL(&data->Q, &wpt->Q); + waypt_add_to_bounds(&data->bds, wpt); +} + + +static void +wdata_check(writer_data_t *data) +{ + queue *elem, *tmp; + double center_lat, center_lon; + + if ((data->ct <= WAYPOINTS_PER_BLOCK) || + /* avoid endless loop for points (more than WAYPOINTS_PER_BLOCK) + at same coordinates */ + ((data->bds.min_lat >= data->bds.max_lat) && (data->bds.min_lon >= data->bds.max_lon))) { + if (data->ct > 1) + sortqueue(&data->Q, compare_wpt_cb); + return; + } + + /* compute the (mean) center of current bounds */ + + center_lat = center_lon = 0; + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint *wpt = (waypoint *) elem; + center_lat += wpt->latitude; + center_lon += wpt->longitude; + } + center_lat /= data->ct; + center_lon /= data->ct; + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint *wpt = (waypoint *) elem; + writer_data_t **ref; + + if (wpt->latitude < center_lat) { + if (wpt->longitude < center_lon) + ref = &data->buttom_left; + else + ref = &data->buttom_right; + } else { + if (wpt->longitude < center_lon) + ref = &data->top_left; + else + ref = &data->top_right; + } + + if (*ref == NULL) *ref = wdata_alloc(); + + data->ct--; + dequeue(&wpt->Q); + + wdata_add_wpt(*ref, wpt); + } + + if (data->top_left) wdata_check(data->top_left); + if (data->top_right) wdata_check(data->top_right); + if (data->buttom_left) wdata_check(data->buttom_left); + if (data->buttom_right) wdata_check(data->buttom_right); +} + + +static int +wdata_compute_size(writer_data_t *data) +{ + queue *elem, *tmp; + int res; + + res = 23; /* bounds, ... of tag 0x80008 */ + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint *wpt = (waypoint *) elem; + gpi_waypt_t *dt; + garmin_fs_t *gmsd; + char *str; + + res += 12; /* tag/sz/sub-sz */ + res += 19; /* poi fixed size */ + res += strlen(wpt->shortname); + if (! opt_hide_bitmap) res += 10; /* tag(4) */ + + dt = xcalloc(1, sizeof(*dt)); + wpt->extra_data = dt; + + if (alerts) { + char *pos; + + if ((pos = strchr(wpt->shortname, '@'))) { + double speed, scale; + if (units == 's') scale = MPH_TO_MPS(1); + else scale = KPH_TO_MPS(1); + parse_speed(pos + 1, &speed, scale, MYNAME); + if (speed > 0) WAYPT_SET(wpt, speed, speed); +#if 0 + if (pos > wpt->shortname) wpt->shortname[pos - wpt->shortname] = '\0'; +#endif + } + else if ((opt_speed) && (! WAYPT_HAS(wpt, speed))) + WAYPT_SET(wpt, speed, defspeed); + + if ((opt_proximity) && (! WAYPT_HAS(wpt, proximity))) + WAYPT_SET(wpt, proximity, defproximity); + + if ((WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) || + (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0))) { + data->alert = 1; + dt->alerts++; + res += 20; /* tag(3) */ + } + } + + str = NULL; + if (opt_descr) { + if (wpt->description && *wpt->description) + str = xstrdup(wpt->description); + } + else if (opt_notes) { + if (wpt->notes && *wpt->notes) + str = xstrdup(wpt->notes); + } + else if (opt_pos) + str = pretty_deg_format(wpt->latitude, wpt->longitude, 's', " ", 0); + + + if (str) { + dt->addr_is_dynamic = 1; + dt->addr = str; + dt->mask |= GPI_ADDR_ADDR; + dt->sz += (8 + strlen(dt->addr)); + } + + if ((gmsd = GMSD_FIND(wpt))) { + if ((dt->mask == 0) && ((dt->addr = GMSD_GET(addr, NULL)))) { + dt->mask |= GPI_ADDR_ADDR; + dt->sz += (8 + strlen(dt->addr)); + } + if ((dt->city = GMSD_GET(city, NULL))) { + dt->mask |= GPI_ADDR_CITY; + dt->sz += (8 + strlen(dt->city)); + } + if ((dt->country = GMSD_GET(country, NULL))) { + dt->mask |= GPI_ADDR_COUNTRY; + dt->sz += (8 + strlen(dt->country)); + } + if ((dt->state = GMSD_GET(state, NULL))) { + dt->mask |= GPI_ADDR_STATE; + dt->sz += (8 + strlen(dt->state)); + } + if ((dt->postal_code = GMSD_GET(postal_code, NULL))) { + dt->mask |= GPI_ADDR_POSTAL_CODE; + dt->sz += (2 + strlen(dt->postal_code)); /* short form */ + } + + if ((dt->phone_nr = GMSD_GET(phone_nr, NULL))) + res += (12 + 4 + strlen(dt->phone_nr)); + } + if (dt->mask) dt->sz += 2; /* + mask (two bytes) */ + if (dt->sz) res += (dt->sz + 12); /* + header size */ + + str = wpt->description; + if (! str) str = wpt->notes; +// if (str && (strcmp(str, wpt->shortname) == 0)) str = NULL; + if (str) res += (12 + 4 + strlen(str)); + } + + if (data->top_left) res += wdata_compute_size(data->top_left); + if (data->top_right) res += wdata_compute_size(data->top_right); + if (data->buttom_left) res += wdata_compute_size(data->buttom_left); + if (data->buttom_right) res += wdata_compute_size(data->buttom_right); + + data->sz = res; + + return res + 12; /* + 12 = caller needs info about tag header size */ +} + + +static void +wdata_write(const writer_data_t *data) +{ + queue *elem, *tmp; + + gbfputint32(0x80008, fout); + gbfputint32(data->sz, fout); + gbfputint32(23, fout); /* bounds + three bytes */ + + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.max_lat), fout); + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.max_lon), fout); + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.min_lat), fout); + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.min_lon), fout); + + gbfputint32(0, fout); + gbfputint16(1, fout); + gbfputc(data->alert, fout); + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + char *str; + int s0, s1; + waypoint *wpt = (waypoint *)elem; + gpi_waypt_t *dt = wpt->extra_data; + + str = wpt->description; + if (! str) str = wpt->notes; +// if (str && (strcmp(str, wpt->shortname) == 0)) str = NULL; + + gbfputint32(0x80002, fout); + + s0 = s1 = 19 + strlen(wpt->shortname); + if (! opt_hide_bitmap) s0 += 10; /* tag(4) */ + if (str) s0 += (12 + 4 + strlen(str)); /* descr */ + if (dt->sz) s0 += (12 + dt->sz); /* address part */ + if (dt->phone_nr) s0 += (12 + 4 + strlen(dt->phone_nr)); + if (dt->alerts) s0 += 20; /* tag(3) */ + + gbfputint32(s0, fout); /* size of following data (tag) */ + gbfputint32(s1, fout); /* basic size (without options) */ + + gbfputint32(GPS_Math_Deg_To_Semi(wpt->latitude), fout); + gbfputint32(GPS_Math_Deg_To_Semi(wpt->longitude), fout); + + gbfputint16(1, fout); /* ? always 1 ? */ + gbfputc(0, fout); /* seems to be 1 when extra options present */ + + write_string(wpt->shortname, 1); + + if (dt->alerts) { + char flag = 0; + + gbfputint32(3, fout); /* tag(3) */ + gbfputint32(12, fout); /* always 12 */ + + if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) { + gbfputint16((int) wpt->proximity, fout); + flag = 4; + } + else + gbfputint16(0, fout); + if (WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) { + gbfputint16((int) (wpt->speed * 100), fout); + flag = 5; + } + else + gbfputint16(0, fout); + + gbfputint32(0x100100, fout); /* ??? */ + gbfputc(1, fout); /* ??? */ + gbfputc(1, fout); /* ??? */ + gbfputc(flag, fout); + gbfputc(0x10, fout); /* ??? */ + } + + if (! opt_hide_bitmap) { + gbfputint32(4, fout); /* tag(4) */ + gbfputint32(2, fout); /* ? always 2 == version ??? */ + gbfputint16(0, fout); + } + + if (str) { + gbfputint32(0xa, fout); + gbfputint32(strlen(str) + 8, fout); /* string + string header */ + write_string(str, 1); + } + + if (dt->sz) { /* gpi address */ + gbfputint32(0x8000b, fout); + gbfputint32(dt->sz, fout); + gbfputint32(0x2, fout); /* ? always 2 ? */ + gbfputint16(dt->mask, fout); + if (dt->mask & GPI_ADDR_CITY) write_string(dt->city, 1); + if (dt->mask & GPI_ADDR_COUNTRY) write_string(dt->country, 1); + if (dt->mask & GPI_ADDR_STATE) write_string(dt->state, 1); + if (dt->mask & GPI_ADDR_POSTAL_CODE) write_string(dt->postal_code, 0); + if (dt->mask & GPI_ADDR_ADDR) write_string(dt->addr, 1); + } + + if (dt->phone_nr) { + gbfputint32(0x8000c, fout); + gbfputint32(strlen(dt->phone_nr) + 2 + 2, fout); + gbfputint32(0x2, fout); /* ? always 2 ? */ + gbfputint16(1, fout); /* mask */ + write_string(dt->phone_nr, 0); + } + } + + if (data->top_left) wdata_write(data->top_left); + if (data->top_right) wdata_write(data->top_right); + if (data->buttom_left) wdata_write(data->buttom_left); + if (data->buttom_right) wdata_write(data->buttom_right); +} + + +static void +write_category(const char *category, const char *image, const int image_sz) +{ + int sz; + + sz = wdata_compute_size(wdata); + sz += 8; /* string header */ + sz += strlen(opt_cat); + + gbfputint32(0x80009, fout); + if ((! opt_hide_bitmap) && image_sz) + gbfputint32(sz + image_sz + 8, fout); + else + gbfputint32(sz, fout); + gbfputint32(sz, fout); + write_string(opt_cat, 1); + + wdata_write(wdata); + + if ((! opt_hide_bitmap) && image_sz) { + gbfputint32(5, fout); + gbfputint32(image_sz, fout); + gbfwrite(image, 1, image_sz, fout); + } +} + + +static void +write_header(void) +{ + time_t time = gpi_timestamp; + + if (time != 0) { + struct tm tm; + tm = *gmtime(&time); + tm.tm_year -= 20; + time = mkgmtime(&tm); + time += SECONDS_PER_DAY; + } + + gbfputint32(0, fout); + gbfputint32(0x16, fout); + gbfwrite("GRMREC00", 1, 8, fout); + gbfputint32(time, fout); + gbfputint16(0, fout); + gbfputint16(6, fout); + gbfwrite("my.gpi", 1, 6, fout); + gbfputint32(1, fout); + gbfputint32(0xc, fout); + gbfwrite("POI", 1, 3, fout); + gbfputc(0, fout); + gbfputc(0, fout); + gbfputc(0, fout); + gbfwrite("00", 1, 2, fout); + gbfputint32(codepage, fout); +} + + +static void +enum_waypt_cb(const waypoint *ref) +{ + waypoint *wpt; + char *str; + queue *elem, *tmp; + + QUEUE_FOR_EACH(&wdata->Q, elem, tmp) { + waypoint *cmp = (waypoint *) elem; + + /* sort out nearly equal waypoints */ + if ((compare_strings(cmp->shortname, ref->shortname) == 0) && + (cmp->latitude == ref->latitude) && + (cmp->longitude == ref->longitude) && + (compare_strings(cmp->description, ref->description) == 0) && + (compare_strings(cmp->notes, ref->notes) == 0)) return; + } + + wpt = waypt_dupe(ref); + + if (*opt_unique == '1') { + str = mkshort(short_h, wpt->shortname); + xfree(wpt->shortname); + wpt->shortname = str; + } + + wdata_add_wpt(wdata, wpt); +} + + +static void +load_bitmap_from_file(const char *fname, char **data, int *data_sz) +{ + gbfile *f; + int i, sz; + int dest_bpp; + int src_line_sz, dest_line_sz; + bmp_header_t src_h; + int *color_table = NULL; + gpi_bitmap_header_t *dest_h; + char *ptr; + + f = gbfopen_le(fname, "rb", MYNAME); + is_fatal(gbfgetint16(f) != 0x4d42, MYNAME ": No BMP image."); + + /* read a standard bmp file header */ + src_h.size = gbfgetint32(f); + src_h.res1 = gbfgetint16(f); + src_h.res2 = gbfgetint16(f); + src_h.image_offset = gbfgetint32(f); + src_h.header_size = gbfgetint32(f); + src_h.width = gbfgetint32(f); + src_h.height = gbfgetint32(f); + src_h.planes = gbfgetint16(f); + src_h.bpp = gbfgetint16(f); + src_h.compression_type = gbfgetint32(f); + src_h.image_data_size = gbfgetint32(f); + src_h.resolution_h = gbfgetint32(f); + src_h.resolution_v = gbfgetint32(f); + src_h.used_colors = gbfgetint32(f); + src_h.important_colors = gbfgetint32(f); + + /* Workaround for indexed BMP's with used_colors = 0 */ + if ((src_h.bpp == 8) && (src_h.used_colors == 0)) + src_h.used_colors = (src_h.image_offset - gbftell(f)) / 4; + +#ifdef GPI_DBG + printf("data size: 0x%1$x (%1$d)\n", src_h.size); + printf("image data offset: 0x%1$x (%1$d)\n", src_h.image_offset); + printf("header size: 0x%1$x (%1$d)\n", src_h.header_size); + printf("image width: 0x%1$x (%1$d)\n", src_h.width); + printf("image height: 0x%1$x (%1$d)\n", src_h.height); + printf("number of planes: 0x%1$x (%1$d)\n", src_h.planes); + printf("bits per pixel: 0x%1$x (%1$d)\n", src_h.bpp); + printf("compression type: 0x%1$x (%1$d)\n", src_h.compression_type); + printf("image size: 0x%1$x (%1$d)\n", src_h.image_data_size); + printf("horizontal resolution: 0x%1$x (%1$d)\n", src_h.resolution_h); + printf("vertical resolution: 0x%1$x (%1$d)\n", src_h.resolution_v); + printf("number of colors: 0x%1$x (%1$d)\n", src_h.used_colors); + printf("important colors: 0x%1$x (%1$d)\n", src_h.important_colors); +#endif + + /* sort out unsupported files */ + if (! ((src_h.width <= 24) && (src_h.height <= 24) && + (src_h.width > 0) && (src_h.height > 0))) + fatal(MYNAME ": Unsupported format (%dx%d)!\n", src_h.width, src_h.height); + if (! ((src_h.bpp == 8) || (src_h.bpp == 24) || (src_h.bpp == 32))) + fatal(MYNAME ": Unsupported color depth (%d)!\n", src_h.bpp); + if (! (src_h.compression_type == 0)) + fatal(MYNAME ": Sorry, we don't support compressed bitmaps.\n"); + + if (src_h.used_colors > 0) { + color_table = xmalloc(4 * src_h.used_colors); + gbfread(color_table, 1, 4 * src_h.used_colors, f); + for (i = 0; i < src_h.used_colors; i++) { + int color = color_table[i]; + /* swap blue and red value */ + color = (color >> 16) | (color << 16) | (color & 0x00ff00); + color_table[i] = color & 0xffffff; + } + } + + /* calculate line-size for source and destination */ + src_line_sz = (src_h.width * src_h.bpp) / 8; + src_line_sz = ((int)((src_line_sz + 3) / 4)) * 4; + + if (src_h.bpp == 24) dest_bpp = 32; + else dest_bpp = src_h.bpp; + + dest_line_sz = (src_h.width * dest_bpp) / 8; + dest_line_sz = ((int)((dest_line_sz + 3) / 4)) * 4; + + sz = sizeof(*dest_h) + (src_h.height * dest_line_sz); + if (src_h.used_colors) sz += (src_h.used_colors * 4); + + ptr = xmalloc(sz); + dest_h = (void *)ptr; + *data = ptr; + *data_sz = sz; + + le_write16(&dest_h->index, 0); + le_write16(&dest_h->height, src_h.height); + le_write16(&dest_h->width, src_h.width); + le_write16(&dest_h->line_sz, dest_line_sz); + le_write16(&dest_h->bpp, dest_bpp); + le_write16(&dest_h->fixed_0, 0); /* seems to be fixed */ + le_write32(&dest_h->image_size, dest_line_sz * src_h.height); + le_write32(&dest_h->fixed_2c, 0x2c); /* seems to be fixed */ + le_write32(&dest_h->flag1, (dest_bpp == 8) ? 0x100 : 0); + le_write32(&dest_h->tr_color, 0xff00ff); /* magenta = transparent color */ + le_write32(&dest_h->flag2, 0x1); /* ? enable transparent mode ? */ + le_write32(&dest_h->size_2c, (dest_line_sz * src_h.height) + 0x2c); + + /* copy and revert order of BMP lines */ + ptr = (void *)dest_h; + ptr += (sizeof(*dest_h) + (dest_line_sz * (src_h.height - 1))); + + if (src_h.bpp == 24) { + /* 24 bpp seems to be not supported, convert to 32 bpp */ + for (i = 0; i < src_h.height; i++) { + int j; + char *p = ptr; + + for (j = 0; j < src_h.width; j++) { + int color; + color = (gbint32)gbfgetint16(f) | (gbfgetc(f) << 16); + le_write32(p, color); + p += 4; + } + ptr -= dest_line_sz; + } + } + else for (i = 0; i < src_h.height; i++) { + gbfread(ptr, 1, src_line_sz, f); + ptr -= dest_line_sz; + } + + if (src_h.used_colors > 0) { + ptr = (void *)dest_h; + ptr += (sizeof(*dest_h) + (src_h.height * src_line_sz)); + + for (i = 0; i < src_h.used_colors; i++) { + le_write32(ptr, color_table[i]); + ptr += 4; + } + } + + if (color_table) xfree(color_table); + gbfclose(f); +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +garmin_gpi_rd_init(const char *fname) +{ + char cp[8]; + + fin = gbfopen_le(fname, "rb", MYNAME); + rdata = xcalloc(1, sizeof(*rdata)); + + read_header(); + + if ((codepage >= 1250) && (codepage <= 1257)) { + snprintf(cp, sizeof(cp), "CP%d", codepage); + cet_convert_init(cp, 1); + } + else warning(MYNAME ": Unsupported code page (%d).\n", codepage); + + units = tolower(opt_units[0]); + if ((units != 'm') && (units != 's')) + fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]); +} + + +static void +garmin_gpi_wr_init(const char *fname) +{ + char cp[8]; + cet_cs_vec_t *vec; + int i; + + if (gpi_timestamp != 0) { /* not the first gpi output session */ + time_t t = time(NULL); + if (t <= gpi_timestamp) + gpi_timestamp++; /* don't create files with same timestamp */ + else + gpi_timestamp = t; + } + else + gpi_timestamp = gpsbabel_time; /* always ZERO during 'testo' */ + + fout = gbfopen_le(fname, "wb", MYNAME); + + short_h = mkshort_new_handle(); + + setshort_length(short_h, 1024); + setshort_badchars(short_h, "\r\n"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 1); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 0); + setshort_defname(short_h, "POI"); + + codepage = 0; + + for (i = 1250; i <= 1257; i++) { + snprintf(cp, sizeof(cp), "CP%d", i); + vec = cet_find_cs_by_name(cp); + if (vec == global_opts.charset) { + codepage = i; + break; + } + } + + if (! codepage) { + warning(MYNAME ": Unsupported character set (%s)!\n", global_opts.charset_name); + fatal(MYNAME ": Valid values are CP1250 to CP1257.\n"); + } + + units = tolower(opt_units[0]); + if ((units != 'm') && (units != 's')) + fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]); + + alerts = (opt_alerts) ? 1 : 0; + + if (opt_speed) { + double scale; + alerts = 1; /* Force alerts to be enabled */ + if (units == 's') scale = MPH_TO_MPS(1); /* We need speed in meters per second */ + else scale = KPH_TO_MPS(1); + parse_speed(opt_speed, &defspeed, scale, MYNAME); + } + + if (opt_proximity) { + double scale; + alerts = 1; /* Force alerts to be enabled */ + if (units == 's') scale = MILES_TO_METERS(1); /* We need proximity in meters */ + else scale = 1000.0; /* one kilometer in meters */ + parse_distance(opt_proximity, &defproximity, scale, MYNAME); + } + wdata = wdata_alloc(); +} + + +static void +garmin_gpi_rd_deinit(void) +{ + if (rdata->category) xfree(rdata->category); + if (rdata->group) xfree(rdata->group); + xfree(rdata); + gbfclose(fin); +} + + +static void +garmin_gpi_wr_deinit(void) +{ + wdata_free(wdata); + mkshort_del_handle(&short_h); + gbfclose(fout); + + if ((opt_sleep) && (gpi_timestamp != 0)) { /* don't sleep during 'testo' */ + int sleep = atoi(opt_sleep); + if (sleep < 1) sleep = 1; + gpi_timestamp += sleep; + while (gpi_timestamp > time(NULL)) { + gb_sleep(100); + } + } +} + + +static void +garmin_gpi_read(void) +{ + while (1) { + int tag = gbfgetint32(fin); + if (tag == 0xffff) return; + if (! read_tag("garmin_gpi_read", tag, NULL)) return; + }; +} + + +static void +garmin_gpi_write(void) +{ + char *image; + int image_sz; + + if (strlen(opt_cat) == 0) fatal(MYNAME ": Can't write empty category!\n"); + + if (opt_hide_bitmap) { + image = NULL; + image_sz = 0; + } + else if (opt_bitmap && *opt_bitmap) + load_bitmap_from_file(opt_bitmap, &image, &image_sz); + else { + image = gpi_bitmap; /* embedded GPSBabel icon in gpi format */ + image_sz = GPI_BITMAP_SIZE; + } + waypt_disp_all(enum_waypt_cb); + + wdata_check(wdata); + write_header(); + write_category(opt_cat, image, image_sz); + + gbfputint32(0xffff, fout); /* final tag */ + gbfputint32(0, fout); /* ? dummy size ? */ + + if (image != gpi_bitmap) xfree(image); +} + +/**************************************************************************/ + +ff_vecs_t garmin_gpi_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + garmin_gpi_rd_init, + garmin_gpi_wr_init, + garmin_gpi_rd_deinit, + garmin_gpi_wr_deinit, + garmin_gpi_read, + garmin_gpi_write, + NULL, + garmin_gpi_args, + CET_CHARSET_MS_ANSI, 0 /* WIN-CP1252 */ +}; + +/**************************************************************************/ diff --git a/garmin_gpi.h b/garmin_gpi.h new file mode 100644 index 000000000..8c2bab369 --- /dev/null +++ b/garmin_gpi.h @@ -0,0 +1,112 @@ +#ifndef GARMIN_GPI_H +#define GARMIN_GPI_H + +static char gpi_bitmap[] = { + 0x00,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x08,0x00,0x00,0x00,0x40,0x02,0x00,0x00, + 0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0x00,0xff,0x00,0x01,0x00,0x00,0x00, + 0x6c,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x7f,0x59,0x67,0x65,0x7f,0x7f,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x74,0x3d,0x42,0x56,0x7e,0x7e,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x72,0x38,0x49,0x47,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7d,0x37,0x47,0x7d,0x7e,0x7e,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x7d,0x37,0x47,0x7d,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7f,0x7f,0x7c,0x6c,0x50,0x44,0x5e,0x4f,0x76,0x7e,0x7f,0x7f,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x77,0x7e,0x7f,0x7f,0x7e,0x62,0x0d,0x00,0x05, + 0x10,0x08,0x09,0x59,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x29,0x1c, + 0x4c,0x7f,0x7f,0x60,0x02,0x0c,0x2a,0x37,0x51,0x63,0x57,0x15,0x58,0x7e,0x7e,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x68,0x5a,0x41,0x5f,0x5f,0x07,0x0e,0x3d,0x41,0x41, + 0x4d,0x55,0x6b,0x61,0x26,0x57,0x57,0x2b,0x2f,0x30,0x00,0x7e,0x00,0x7e,0x77,0x7d, + 0x4e,0x3d,0x3d,0x16,0x35,0x41,0x7d,0x49,0x18,0x48,0x52,0x54,0x5b,0x31,0x31,0x63, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x40,0x7d,0x75,0x47,0x47,0x41,0x35,0x40,0x72,0x1e, + 0x7c,0x5d,0x1d,0x20,0x49,0x3d,0x3d,0x5b,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x60,0x5c, + 0x7a,0x1a,0x1a,0x3b,0x38,0x5d,0x0e,0x59,0x7d,0x3c,0x72,0x37,0x78,0x60,0x60,0x28, + 0x4f,0x71,0x00,0x7e,0x00,0x7e,0x7e,0x43,0x33,0x69,0x69,0x17,0x22,0x7d,0x2c,0x27, + 0x2a,0x2b,0x7d,0x32,0x61,0x4f,0x4f,0x36,0x3f,0x4c,0x00,0x7e,0x00,0x7e,0x7f,0x7e, + 0x3a,0x2b,0x2b,0x45,0x1a,0x40,0x47,0x7d,0x37,0x41,0x12,0x25,0x5e,0x46,0x46,0x4d, + 0x62,0x53,0x00,0x7e,0x00,0x7e,0x7f,0x7e,0x73,0x71,0x71,0x6a,0x13,0x39,0x1b,0x45, + 0x62,0x50,0x3a,0x7e,0x7e,0x7b,0x7b,0x5c,0x5b,0x49,0x00,0x7e,0x00,0x7e,0x7f,0x7e, + 0x59,0x01,0x01,0x06,0x64,0x35,0x4e,0x3e,0x26,0x21,0x66,0x7f,0x45,0x04,0x04,0x11, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7e,0x59,0x01,0x01,0x06,0x64,0x35,0x4e,0x3e, + 0x26,0x21,0x66,0x7f,0x45,0x04,0x04,0x11,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7e, + 0x7c,0x0a,0x0a,0x0f,0x65,0x7d,0x74,0x71,0x7c,0x7e,0x7e,0x7e,0x58,0x03,0x03,0x2b, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x6d,0x6d,0x6f,0x2d,0x1d,0x63,0x7a, + 0x7e,0x75,0x5d,0x19,0x32,0x70,0x70,0x6f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7e,0x7d,0x53,0x35,0x0b,0x1f,0x0e,0x34,0x5a,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x7f,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x7e,0x7e,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x16,0x16,0x16,0x00, + 0x1f,0x1f,0x1f,0x00,0x28,0x28,0x28,0x00,0x2d,0x2d,0x2d,0x00,0x35,0x35,0x35,0x00, + 0x3d,0x3d,0x3d,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x43,0x43,0x43,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x4b,0x4b,0x4b,0x00,0x4e,0x4e,0x4e,0x00, + 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x56,0x00,0x59,0x59,0x59,0x00, + 0x5a,0x5a,0x5a,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x62,0x62,0x62,0x00, + 0x63,0x63,0x63,0x00,0x6a,0x6a,0x6a,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00, + 0x85,0x85,0x85,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8e,0x8e,0x8e,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x9b,0x9b,0x9b,0x00, + 0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00, + 0xa2,0xa2,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00, + 0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00, + 0xc9,0xc9,0xc9,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xce,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00, + 0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd9,0xd9,0xd9,0x00, + 0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00, + 0xe4,0xe4,0xe4,0x00,0xe6,0xe6,0xe6,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00, + 0xee,0xee,0xee,0x00,0xf0,0xf0,0xf0,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00, + 0xf5,0xf5,0xf5,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00, + 0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xff,0xff,0xff,0x00, + 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00 +}; + +#define GPI_BITMAP_SIZE sizeof(gpi_bitmap) + +#endif diff --git a/garmin_tables.c b/garmin_tables.c new file mode 100644 index 000000000..11a064ad0 --- /dev/null +++ b/garmin_tables.c @@ -0,0 +1,990 @@ +/* + Garmin icon tables + Based on information provided by Ian Cowley, Sigurd Humerfelt, + and Garmin MapSource + + Copyright (C) 2003-2007 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include "garmin_tables.h" +#include "jeeps/gpsmath.h" + +#include +#include + +#define MYNAME "garmin_tables" + +/* MapSource 4.13 */ +icon_mapping_t garmin_icon_table[] = { +/* mps pcx desc */ + { 107, 16384, "Airport" }, + { 73, 8204, "Amusement Park" }, + { 55, 169, "Ball Park" }, + { 6, 6, "Bank" }, + { 13, 13, "Bar" }, + { 104, 8244, "Beach" }, + { 1, 1, "Bell" }, + { 37, 150, "Boat Ramp" }, + { 74, 8205, "Bowling" }, + { 93, 8233, "Bridge" }, + { 94, 8234, "Building" }, + { 38, 151, "Campground" }, + { 56, 170, "Car" }, + { 75, 8206, "Car Rental" }, + { 76, 8207, "Car Repair" }, + { 95, 8235, "Cemetery" }, + { 96, 8236, "Church" }, + { 65, 179, "Circle with X" }, + { 72, 8203, "City (Capitol)" }, + { 71, 8200, "City (Large)" }, + { 70, 8199, "City (Medium)" }, + { 69, 8198, "City (Small)" }, + { 69, 8198, "Small City" }, + { 97, 8237, "Civil" }, + { 119, 8262, "Contact, Afro" }, + { 120, 8272, "Contact, Alien" }, + { 121, 8258, "Contact, Ball Cap" }, + { 122, 8259, "Contact, Big Ears" }, + { 123, 8271, "Contact, Biker" }, + { 124, 8273, "Contact, Bug" }, + { 125, 8274, "Contact, Cat" }, + { 126, 8275, "Contact, Dog" }, + { 127, 8263, "Contact, Dreadlocks" }, + { 128, 8264, "Contact, Female1" }, + { 129, 8265, "Contact, Female2" }, + { 130, 8266, "Contact, Female3" }, + { 131, 8261, "Contact, Goatee" }, + { 132, 8268, "Contact, Kung-Fu" }, + { 133, 8276, "Contact, Pig" }, + { 134, 8270, "Contact, Pirate" }, + { 135, 8267, "Contact, Ranger" }, + { 136, 8257, "Contact, Smiley" }, + { 137, 8260, "Contact, Spike" }, + { 138, 8269, "Contact, Sumo" }, + { 52, 165, "Controlled Area" }, + { 89, 8220, "Convenience Store" }, + { 98, 8238, "Crossing" }, + { 51, 164, "Dam" }, + { 53, 166, "Danger Area" }, + { 87, 8218, "Department Store" }, + { 4, 4, "Diver Down Flag 1" }, + { 5, 5, "Diver Down Flag 2" }, + { 41, 154, "Drinking Water" }, + { 63, 177, "Exit" }, + { 77, 8208, "Fast Food" }, + { 7, 7, "Fishing Area" }, + { 78, 8209, "Fitness Center" }, + { 64, 178, "Flag" }, + { 105, 8245, "Forest" }, + { 8, 8, "Gas Station" }, + { 117, 8255, "Geocache" }, + { 118, 8256, "Geocache Found" }, + { 99, 8239, "Ghost Town" }, + { 113, 16393, "Glider Area" }, + { 68, 8197, "Golf Course" }, + { 2, 2, "Diamond, Green" }, + { 15, 15, "Square, Green" }, + { 108, 16388, "Heliport" }, + { 9, 9, "Horn" }, + { 57, 171, "Hunting Area" }, + { 44, 157, "Information" }, + { 100, 8240, "Levee" }, + { 12, 12, "Light" }, + { 90, 8221, "Live Theater" }, + { 59, 173, "Lodging" }, + { 59, 173, "Hotel" }, + { 20, 21, "Man Overboard" }, + { 0, 0, "Anchor" }, + { 43, 156, "Medical Facility" }, + { 66, 8195, "Mile Marker" }, + { 101, 8241, "Military" }, + { 60, 174, "Mine" }, + { 79, 8210, "Movie Theater" }, + { 80, 8211, "Museum" }, + { 21, 22, "Navaid, Amber" }, + { 22, 23, "Navaid, Black" }, + { 23, 24, "Navaid, Blue" }, + { 24, 25, "Navaid, Green" }, + { 25, 26, "Navaid, Green/Red" }, + { 26, 27, "Navaid, Green/White" }, + { 27, 28, "Navaid, Orange" }, + { 28, 29, "Navaid, Red" }, + { 29, 30, "Navaid, Red/Green" }, + { 30, 31, "Navaid, Red/White" }, + { 31, 32, "Navaid, Violet" }, + { 32, 33, "Navaid, White" }, + { 33, 34, "Navaid, White/Green" }, + { 34, 35, "Navaid, White/Red" }, + { 102, 8242, "Oil Field" }, + { 115, 16395, "Parachute Area" }, + { 46, 159, "Park" }, + { 45, 158, "Parking Area" }, + { 81, 8212, "Pharmacy" }, + { 47, 160, "Picnic Area" }, + { 82, 8213, "Pizza" }, + { 83, 8214, "Post Office" }, + { 109, 16389, "Private Field" }, + { 36, 37, "Radio Beacon" }, + { 3, 3, "Diamond, Red" }, + { 16, 16, "Square, Red" }, + { 10, 10, "Residence" }, + { 10, 10, "House" }, + { 11, 11, "Restaurant" }, + { 54, 167, "Restricted Area" }, + { 39, 152, "Restroom" }, + { 84, 8215, "RV Park" }, + { 91, 8226, "Scales" }, + { 48, 161, "Scenic Area" }, + { 85, 8216, "School" }, + { 116, 16402, "Seaplane Base" }, + { 19, 19, "Shipwreck" }, + { 58, 172, "Shopping Center" }, + { 112, 16392, "Short Tower" }, + { 40, 153, "Shower" }, + { 49, 162, "Skiing Area" }, + { 14, 14, "Skull and Crossbones" }, + { 110, 16390, "Soft Field" }, + { 86, 8217, "Stadium" }, + { 106, 8246, "Summit" }, + { 50, 163, "Swimming Area" }, + { 111, 16391, "Tall Tower" }, + { 42, 155, "Telephone" }, + { 92, 8227, "Toll Booth" }, + { 67, 8196, "TracBack Point" }, + { 61, 175, "Trail Head" }, + { 62, 176, "Truck Stop" }, + { 103, 8243, "Tunnel" }, + { 114, 16394, "Ultralight Area" }, + { 139, 8282, "Water Hydrant" }, /* new in MapSource V5 */ + { 18, 18, "Waypoint" }, + { 17, 17, "Buoy, White" }, + { 35, 36, "Dot, White" }, + { 88, 8219, "Zoo" }, + + /* Custom icons. The spec reserves 7680-8191 for the custom + * icons on the C units, Quest, 27xx, 276, 296, and other units. + * Note that firmware problems on the earlier unit result in these + * being mangled, so be sure you're on a version from at least + * late 2005. + * { -2, 7680, "Custom 0" }, + * .... + * { -2, 8192, "Custom 511" }, + */ +#if 1 +/* Since Garmin is busily adding icons to new units, we have to hide + * these so we can pass them through to the new entries. 6/2/07 robertl + */ + { 92, 8227, "Micro-Cache" }, /* icon for "Toll Booth" */ + { 48, 161, "Virtual cache" }, /* icon for "Scenic Area" */ + { 86, 8217, "Multi-Cache" }, /* icon for "Stadium" */ + { 44, 157, "Unknown Cache" }, /* icon for "Information" */ + { 64, 178, "Locationless (Reverse) Cache" }, /* Icon for "Flag" */ + { 83, 8214, "Post Office" }, /* Icon for "Post Office" */ + { 47, 160, "Event Cache" }, /* Icon for "Event" */ + { 90, 8221, "Webcam Cache" }, /* Icon for "Live Theatre" */ +#endif + /* MapSource V6.x */ + + { 140, 8286, "Flag, Red" }, + { 141, 8284, "Flag, Blue" }, + { 142, 8285, "Flag, Green" }, + { 143, 8289, "Pin, Red" }, + { 144, 8287, "Pin, Blue" }, + { 145, 8288, "Pin, Green" }, + { 146, 8292, "Block, Red" }, + { 147, 8290, "Block, Blue" }, + { 148, 8291, "Block, Green" }, + { 149, 8293, "Bike Trail" }, + { 150, 181, "Fishing Hot Spot Facility" }, + { 151, 8249, "Police Station"}, + { 152, 8251, "Ski Resort" }, + { 153, 8252, "Ice Skating" }, + { 154, 8253, "Wrecker" }, + { 155, 184, "Anchor Prohibited" }, + { 156, 185, "Beacon" }, + { 157, 186, "Coast Guard" }, + { 158, 187, "Reef" }, + { 159, 188, "Weed Bed" }, + { 160, 189, "Dropoff" }, + { 161, 190, "Dock" }, + { 162, 191, "Marina" }, + { 163, 192, "Bait and Tackle" }, + { 164, 193, "Stump" }, + + /* New in Garmin protocol spec from June 2006. Extracted from + * spec and fed through some horrible awk to add ones we didn't + * have before but normalized for consistency. */ + { -1, 8359, "Asian Food" }, + { 167, 8296, "Circle, Blue" }, + { 168, 8299, "Diamond, Blue" }, + { 178, 8317, "Letter A, Blue" }, + { 181, 8318, "Letter B, Blue" }, + { 184, 8319, "Letter C, Blue" }, + { 187, 8320, "Letter D, Blue" }, + { 190, 8341, "Number 0, Blue" }, + { 193, 8342, "Number 1, Blue" }, + { 196, 8343, "Number 2, Blue" }, + { 199, 8344, "Number 3, Blue" }, + { 202, 8345, "Number 4, Blue" }, + { 205, 8346, "Number 5, Blue" }, + { 208, 8347, "Number 6, Blue" }, + { 211, 8348, "Number 7, Blue" }, + { 214, 8349, "Number 8, Blue" }, + { 217, 8350, "Number 9, Blue" }, + { 171, 8302, "Oval, Blue" }, + { 174, 8305, "Rectangle, Blue" }, + { 175, 8308, "Square, Blue" }, + { 218, 8351, "Triangle, Blue" }, + { -1, 8254, "Border Crossing (Port Of Entry)" }, + { -1, 182, "Bottom Conditions" }, + { -1, 8360, "Deli" }, + { -1, 8228, "Elevation point" }, + { -1, 8229, "Exit without services" }, + { -1, 16398, "First approach fix" }, + { -1, 8250, "Gambling/casino" }, + { -1, 8232, "Geographic place name, land" }, + { -1, 8230, "Geographic place name, Man-made" }, + { -1, 8231, "Geographic place name, water" }, + { 166, 8295, "Circle, Green" }, + { 177, 8313, "Letter A, Green" }, + { 180, 8315, "Letter B, Green" }, + { 183, 8314, "Letter C, Green" }, + { 186, 8316, "Letter D, Green" }, + { 189, 8331, "Number 0, Green" }, + { 192, 8332, "Number 1, Green" }, + { 195, 8333, "Number 2, Green" }, + { 198, 8334, "Number 3, Green" }, + { 201, 8335, "Number 4, Green" }, + { 204, 8336, "Number 5, Green" }, + { 207, 8337, "Number 6, Green" }, + { 210, 8338, "Number 7, Green" }, + { 213, 8339, "Number 8, Green" }, + { 216, 8340, "Number 9, Green" }, + { 170, 8301, "Oval, Green" }, + { 173, 8304, "Rectangle, Green" }, + { 219, 8352, "Triangle, Green" }, + { -1, 16385, "Intersection" }, + { -1, 8201, "Intl freeway hwy" }, + { -1, 8202, "Intl national hwy" }, + { -1, 8361, "Italian food" }, + { -1, 8248, "Large exit without services" }, + { -1, 8247, "Large Ramp intersection" }, + { -1, 16399, "Localizer Outer Marker" }, + { -1, 16400, "Missed approach point" }, + { -1, 16386, "Non-directional beacon" }, + { -1, 168, "Null" }, + { -1, 180, "Open 24 Hours" }, + { -1, 8222, "Ramp intersection" }, + { 165, 8294, "Circle, Red" }, + { 176, 8309, "Letter A, Red" }, + { 179, 8310, "Letter B, Red" }, + { 182, 8311, "Letter C, Red" }, + { 185, 8312, "Letter D, Red" }, + { 188, 8321, "Number 0, Red" }, + { 191, 8322, "Number 1, Red" }, + { 194, 8323, "Number 2, Red" }, + { 197, 8324, "Number 3, Red" }, + { 200, 8325, "Number 4, Red" }, + { 203, 8326, "Number 5, Red" }, + { 206, 8327, "Number 6, Red" }, + { 209, 8328, "Number 7, Red" }, + { 212, 8329, "Number 8, Red" }, + { 215, 8330, "Number 9, Red" }, + { 169, 8300, "Oval, Red" }, + { 172, 8303, "Rectangle, Red" }, + { 220, 8353, "Triangle, Red" }, + { -1, 8362, "Seafood" }, + { -1, 8194, "State Hwy" }, + { -1, 8363, "Steak" }, + { -1, 8223, "Street Intersection" }, + { -1, 16401, "TACAN" }, + { -1, 183, "Tide/Current PRediction Station" }, + { -1, 191, "U Marina" }, + { -1, 8193, "US hwy" }, + { -1, 193, "U stump" }, + { -1, 16387, "VHF Omni-range" }, + { -1, 16397, "VOR-DME" }, + { -1, 16396, "VOR/TACAN" }, + + /* This block new on 1/15 from the Mapsource 6.12 beta */ + { 221, -1, "Contact, Blonde" }, + { 222, -1, "Contact, Clown" }, + { 223, -1, "Contact, Glasses" }, + { 224, -1, "Contact, Panda" }, + { 225, -1, "Multi-Cache" }, + { 226, -1, "Letterbox Cache" }, + { 227, -1, "Puzzle Cache" }, + { 228, -1, "Library" }, + { 229, -1, "Ground Transportation" }, + { 230, -1, "City Hall" }, + { 231, -1, "Winery" }, + { 232, -1, "ATV" }, + { 233, -1, "Big Game" }, + { 234, -1, "Blind" }, + { 235, -1, "Blood Trail" }, + { 236, -1, "Cover" }, + { 237, -1, "Covey" }, + { 238, -1, "Food Source" }, + { 239, -1, "Furbearer" }, + { 240, -1, "Lodge" }, + { 241, -1, "Small Game" }, + { 242, -1, "Animal Tracks" }, + { 243, -1, "Treed Quarry" }, + { 244, -1, "Tree Stand" }, + { 245, -1, "Truck" }, + { 246, -1, "Upland Game" }, + { 247, -1, "Waterfowl" }, + { 248, -1, "Water Source" }, + + + { -1, -1, NULL }, +}; + +/* ICAO coutry code table */ + +/* source: http://en.wikipedia.org/wiki/ICAO_airport_code */ + +gt_country_code_t gt_country_codes[] = +{ + { "ZM,", "Mongolia" }, + { "ZK,", "North Korea" }, + { "Z*,", "China" }, + { "Y*,", "Australia" }, + { "WS,", "Singapore" }, + { "WM,", "Brunei/Malaysia" }, + { "WB,", "Malaysia" }, + { "WA,WI,WQ,WR,", "Indonesia" }, + { "VV,", "Vietnam" }, + { "VT,", "Thailand" }, + { "VR,", "Maldives" }, + { "VQ,", "Bhutan" }, + { "VN,", "Nepal" }, + { "VM,", "Macau" }, + { "VL,", "Laos" }, + { "VH,", "Hong Kong" }, + { "VG,", "Bangladesh" }, + { "VD,", "Kampuchea" }, + { "VC,", "Sri Lanka" }, + { "VB,VY,", "Myanmar/Burma" }, + { "VA,VE,VI,VO,", "India" }, + { "UR,", "Kazakhstan/Russia" }, + { "UT,", "Kazakhstan/Tadzhikistan/Turkmenistan/Uzbekistan" }, + { "UM,", "Belorussia/Russia" }, + { "UK,", "Ukraine" }, + { "UB,", "Azerbaijan" }, + { "UA,", "Kazakhstan/Kirgizia" }, + { "U*,", "Russia" }, + { "TX,", "Bermuda" }, + { "TV,", "St Vincent and the Grenadines" }, + { "TU,", "British Virgin Islands" }, + { "TT,", "Trinidad and Tobago" }, + { "TR,", "Montserrat Island" }, + { "TQ,", "Anguilla" }, + { "TN,", "Aruba/Neth Antilles" }, + { "TL,", "St Lucia" }, + { "TK,", "St Kitts/Nevis Islands" }, + { "TJ,", "Puerto Rico" }, + { "TG,", "Grenada" }, + { "TF,", "Guadeloupe/Martinique" }, + { "TD,", "Dominica" }, + { "TB,", "Barbados" }, + { "TA,", "Antigua" }, + { "SY,", "Guyana" }, + { "SV,", "Venezuela" }, + { "SU,", "Uruguay" }, + { "SP,", "Peru" }, + { "SO,", "French Guiana" }, + { "SM,", "Suriname" }, + { "SL,", "Bolivia" }, + { "SK,", "Colombia/San Andres" }, + { "SG,", "Paraguay" }, + { "SF,", "Falkland Islands" }, + { "SE,", "Ecuador" }, + { "SC,", "Chile/Easter Island" }, + { "SB,SD,SN,SS,SW,", "Brazil" }, + { "SA,", "Argentina" }, + { "S1,", "Antarctica (Argentina/Chile)" }, + { "RP,", "Philippines" }, + { "RK,", "South Korea" }, + { "RJ,", "Japan" }, + { "RC,", "Taiwan" }, + { "PW,", "Wake Island" }, + { "PT,", "Caroline Islands/Micronesia/Palau" }, + { "PM,", "Midway Islands" }, + { "PK,", "Marshall Islands" }, + { "PJ,", "Johnston Atoll" }, + { "PG,", "Guam/Mariana Islands/Northern Mariana Islands" }, + { "PC,", "Kiribati" }, + { "P", "Oakland Octa" }, + { "OY,", "Yemen Arab Rep" }, + { "OT,", "Qatar" }, + { "OS,", "Syria" }, + { "OR,", "Iraq" }, + { "OP,", "Pakistan" }, + { "OO,", "Oman" }, + { "OM,", "United Arab Emirates" }, + { "OL,", "Lebanon" }, + { "OK,", "Kuwait" }, + { "OJ,", "Jordan" }, + { "OI,", "Iran" }, + { "OE,", "Saudi Arabia" }, + { "OB,", "Bahrain" }, + { "OA,", "Afghanistan" }, + { "NZ,PL,", "New Zealand" }, + { "NW,", "New Caledonia" }, + { "NV,", "Vanuatu" }, + { "NT,", "French Polynesia/Society Islands/Tuamotu Islands" }, + { "NS,", "American Samoa/Western Samoa" }, + { "NL,", "Futuna Island/Wallis Island" }, + { "NI,", "Niue" }, + { "NG,", "Kiribati/Tuvalu" }, + { "NF,", "Fiji Island/Tonga" }, + { "NC,", "Cook Islands" }, + { "MZ,", "Belize" }, + { "MY,", "Bahamas" }, + { "MW,", "Cayman Islands" }, + { "MU,", "Cuba" }, + { "MT,", "Haiti" }, + { "MS,", "El Salvador" }, + { "MR,", "Costa rica" }, + { "MP,", "Panama" }, + { "MN,", "Nicaragua" }, + { "MM,", "Mexico" }, + { "MK,", "Jamaica" }, + { "MI,TI,", "Virgin Islands (U.S.)" }, + { "MH,", "Honduras" }, + { "MG,", "Guatemala" }, + { "MD,", "Dominican Republic" }, + { "MB,", "Turks Island/Caicos Island" }, + { "LZ,", "Slovakia" }, + { "LY,", "Yugoslavia" }, + { "LX,", "Gibraltar" }, + { "LW,", "Macedonia" }, + { "LV,", "Gaza" }, + { "LU,", "Moldova" }, + { "LT,", "Turkey" }, + { "LS,", "Switzerland" }, + { "LR,", "Romania" }, + { "LQ,", "Bosnia-Herzegovina" }, + { "LP,", "Portugal/Azores/Madeira Islands" }, + { "LO,", "Austria" }, + { "LN,", "Monaco" }, + { "LM,", "Malta" }, + { "LL,", "Israel/Jerusalem" }, + { "LK,", "Czech" }, + { "LI,", "Italy" }, + { "LH,", "Hungary" }, + { "LG,", "Slovenia" }, + { "LG,", "Greece" }, + { "LF,", "France" }, + { "LF,", "Miquelon Island/St Pierre Island" }, + { "LE,", "Spain" }, + { "LD,", "Croatia" }, + { "LC,", "Cyprus/Turkey (Northern Cyprus)" }, + { "LB,", "Bulgaria" }, + { "LA,", "Albania" }, + { "K*,X*,PA,PB,PF,PJ,PL,PM,PO,PP,PH,PW,", "United States of America" }, + { "HU,", "Uganda" }, + { "HT,", "Tanzania" }, + { "HS,", "Sudan" }, + { "HR,", "Rwanda" }, + { "HL,", "Libya, Spa Jamahiriya" }, + { "HK,", "Kenya" }, + { "HH,", "Eritrea" }, + { "HE,", "Egypt" }, + { "HD,HF,", "Djibouti" }, + { "HC,", "Somalia" }, + { "HB,", "Burundi" }, + { "HA,", "Ethiopia" }, + { "GV,", "Cape Verde" }, + { "GU,", "Guinea Tepublic" }, + { "GQ,", "Mauritania" }, + { "GO,", "Senegal" }, + { "GM,", "Morocco/Ad Dakhla/La'Youn" }, + { "GL,", "Liberia" }, + { "GG,", "Guinea-Bissau" }, + { "GF,", "Sierra Leone" }, + { "GE,", "Melilla" }, + { "GC,", "Canary Island" }, + { "GB,", "Gambia" }, + { "GA,", "Mali" }, + { "FZ,", "Democratic Republic of Congo" }, + { "FY,", "Namibia" }, + { "FX,", "Lesotho" }, + { "FW,", "Malawi" }, + { "FV,", "Zimbabwe" }, + { "FT,", "Chad" }, + { "FS,", "Seychelles" }, + { "FQ,", "Mozambique" }, + { "FP,", "Sao Tome & Principe" }, + { "FO,", "Gabon" }, + { "FN,", "Angola" }, + { "FM,", "Madagascar/Comoros/Reunion/Mayotte Islands" }, + { "FL,", "Zambia" }, + { "FK,", "Cameroon" }, + { "FJ,", "Chagos Archipelago/British Indian Ocean Territory" }, + { "FI,", "Mauritius" }, + { "FH,", "Ascension Island/St Helena Island" }, + { "FG,", "Equitorial Guinea" }, + { "FE,", "Central African Republic" }, + { "FD,", "Swaziland" }, + { "FC,", "Congo" }, + { "FB,", "Botswana" }, + { "FA,", "South African Republic" }, + { "EY,", "Lithuania" }, + { "EV,", "Latvia" }, + { "ES,", "Sweden" }, + { "EP,", "Poland" }, + { "EN,", "Norway" }, + { "EL,", "Luxembourg" }, + { "EK,", "Denmark/Faroe Island" }, + { "EI,", "Ireland" }, + { "EH,", "Netherlands" }, + { "EG,LX,", "United Kingdom" }, + { "EF,", "Finland" }, + { "EE,", "Estonia" }, + { "ED,ET,", "Germany" }, + { "EB,", "Belgium" }, + { "DX,", "Togo" }, + { "DT,", "Tunisia" }, + { "DR,", "Niger" }, + { "DN,", "Nigeria" }, + { "DI,", "Ivory Coast" }, + { "DG,", "Ghana" }, + { "DF,", "Burkina Faso" }, + { "DB,", "Benin" }, + { "DA,", "Algeria" }, + { "C*,", "Canada" }, + { "BI,", "Iceland" }, + { "BG,", "Greenland" }, + { "AY,", "Papua New Guinea" }, + { "AN,", "Nauru" }, + { "AG,", "Solomon Island" }, + { NULL, NULL } +}; + +/* gt_waypt_classes: gdb internal order */ +char *gt_waypt_class_names[] = { + "User Waypoint", + "Airport", + "Intersection", + "NDB", + "VOR", + "Runway Threshold", + "Airport Intersection", + "Airport NDB", + "Map Point", + "Map Area", + "Map Intersection", + "Map Address", + "Map Line", + NULL +}; + +/* gt_display_mode_names: this order is used by most devices */ +char *gt_display_mode_names[] = { + "Symbol & Name", + "Symbol", + "Symbol & Description" +}; + +typedef struct { + char *shortname; + char *longname; + grid_type grid; +} grid_mapping_t; + +/* gt_mps_grid_names: !!! degree sign substituted with '*' !!! */ + +grid_mapping_t gt_mps_grid_names[] = +{ + { "ddd", "Lat/Lon hddd.ddddd*", grid_lat_lon_ddd }, + { "dmm", "Lat/Lon hddd*mm.mmm'", grid_lat_lon_dmm }, + { "dms", "Lat/Lon hddd*mm'ss.s\"", grid_lat_lon_dms }, + { "bng", "British National Grid", grid_bng }, + { "utm", "UTM", grid_utm }, + { "swiss", "Swiss grid", grid_swiss }, + { NULL, NULL, 0 } +}; + +/* gt_mps_datum_names: */ + +typedef struct { + char *jeeps_name; + char *mps_name; +} datum_mapping_t; + +/* will be continued (when requested) */ +datum_mapping_t gt_mps_datum_names[] = +{ + { "Alaska-NAD27", "NAD27 Alaska" }, + { "Bahamas NAD27", "NAD27 Bahamas" }, + { "Canada_Mean(NAD27)", "NAD27 Canada" }, + { "Canal_Zone_(NAD27)", "NAD27 Canal Zone" }, + { "Carribean NAD27", "NAD27 Caribbean" }, + { "Cent America NAD27", "NAD27 Central" }, + { "Cuba NAD27", "NAD27 Cuba" }, + { "Geodetic Datum 49", "Geodetic Datum '49" }, + { "Greenland NAD27", "NAD27 Greenland" }, + { "Mexico NAD27", "NAD27 Mexico" }, + { "North America 83", "NAD83" }, + { "OSGB36", "Ord Srvy Grt Britn" }, + { NULL, NULL } +}; + +unsigned char +gt_switch_display_mode_value(const unsigned char display_mode, const int protoid, const char device) +{ + if (device) { + switch(protoid) { + + case 103: + case 107: + case 108: + case 109: + case 110: return display_mode & 3; + case 104: + switch(display_mode) { + case 0: + case 1: return gt_display_mode_symbol; + case 3: return gt_display_mode_symbol_and_name; + case 5: return gt_display_mode_symbol_and_comment; + } + case 155: + switch(display_mode) { + case 1: return gt_display_mode_symbol; + case 3: return gt_display_mode_symbol_and_name; + case 5: return gt_display_mode_symbol_and_comment; + } + } + return gt_display_mode_symbol_and_name; + } else { + switch(protoid) { + + case 103: + case 107: + case 108: + case 109: + case 110: return display_mode & 3; + case 104: + case 155: + switch(display_mode) { + case gt_display_mode_symbol: return 1; + case gt_display_mode_symbol_and_name: return 3; + case gt_display_mode_symbol_and_comment: return 5; + } + } + return 0; + } +} + +char * +gt_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format, int *dynamic) +{ + icon_mapping_t *i; + char custom[] = "Custom 63 "; + + if ((garmin_format == GDB) && (icon >= 500) && (icon <= 563)) + { + snprintf(custom, sizeof(custom), "Custom %d", icon - 500); + *dynamic = 1; + return xstrdup(custom); + } + + if ((garmin_format == PCX) && (icon >= 7680) && (icon <= 8191)) { + snprintf(custom, sizeof(custom), "Custom %d", icon - 7680); + *dynamic = 1; + return xstrdup(custom); + } + + if (dynamic) *dynamic = 0; + + for (i = garmin_icon_table; i->icon; i++) { + switch (garmin_format) { + case MAPSOURCE: + case GDB: + if (icon == i->mpssymnum) + return (char *)i->icon; + break; + case PCX: + case GARMIN_SERIAL: + if (icon == i->pcxsymnum) + return (char *)i->icon; + break; + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + } + return DEFAULT_ICON_DESCR; +} + +int gt_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_format) +{ + static int find_flag = 0; + icon_mapping_t *i; + int def_icon = DEFAULT_ICON_VALUE; + int n; + + if (!desc) + return def_icon; + + /* + * If we were given a numeric icon number as a description + * (i.e. 8255), just return that. + */ + n = atoi(desc); + if (n) { + return n; + } + + if (0 == case_ignore_strncmp(desc, "Custom ", 7)) { + int base = 0; + if (garmin_format == GDB) base = 500; + if (garmin_format == PCX) base = 7680; + if (base) { + n = atoi(&desc[7]); + return n + base; + } + } + + for (i = garmin_icon_table; i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + switch (garmin_format) { + case MAPSOURCE: + case GDB: + return i->mpssymnum; + case PCX: + case GARMIN_SERIAL: + return i->pcxsymnum; + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + } + } + + /* + * try to handle some complex icon names: i.e. "Blue Diamond" and "Diamond, Blue" + * "find_flag" prevents us from a possible endless loop + */ + + if (find_flag == 0) + { + char **prefix; + char *prefixes[] = {"White ", "Red ", "Green ", "Blue ", "Black ", NULL}; + + for (prefix = prefixes; *prefix != NULL; prefix++) + { + int len = strlen(*prefix); + + if (case_ignore_strncmp(desc, *prefix, len) == 0) + { + char buff[64]; + int result; + + snprintf(buff, sizeof(buff), "%s, %s", &desc[len], *prefix); + rtrim(buff); + + find_flag = 1; + result = gt_find_icon_number_from_desc(buff, garmin_format); + find_flag = 0; + + return result; + } + } + } + return def_icon; +} + +char * +gt_get_icao_country(const char *cc) +{ + gt_country_code_t *x = >_country_codes[0]; + + if ((cc == NULL) || (*cc == '\0')) return NULL; + + do { + char *ccx = x->cc; + while (ccx != NULL) { + if (strncmp(ccx, cc, 2) == 0) return x->country; + if ((ccx[0] == cc[0]) && (ccx[1] == '*')) return x->country; + ccx = strchr(ccx, ','); + if (ccx == NULL) break; + ccx++; + } + x++; + } while (x->cc != NULL); + return NULL; +} + +char * +gt_get_icao_cc(const char *country, const char *shortname) +{ + static char res[3]; + gt_country_code_t *x = >_country_codes[0]; + + if ((country == NULL) || (*country == '\0')) { + char *test; + if (shortname == NULL) return NULL; + switch(strlen(shortname)) { + case 3: strncpy(res, shortname, 1); break; + case 4: strncpy(res, shortname, 2); break; + default: return NULL; + } + test = gt_get_icao_country(res); + if (test != NULL) + return res; + else + return NULL; + } + + do { + if (case_ignore_strcmp(country, x->country) != 0) { + x++; + continue; + } + + if (strlen(x->cc) <= 3) { + strncpy(res, x->cc, 3); + if (res[1] == '*') + res[1] = '\0'; + else + res[2] = '\0'; + return res; + } + if (shortname && (strlen(shortname) == 4)) { + char *ccx = x->cc; + + strncpy(res, shortname, 2); + res[2] = '\0'; + while (ccx != NULL) { + if (strncmp(ccx, res, 2) == 0) return res; + if ((ccx[0] == res[0]) && (ccx[1] == '*')) return res; + ccx = strchr(ccx, ','); + if (ccx == NULL) break; + ccx++; + } + } + return NULL; + } while (x->country != NULL); + return NULL; +} + +grid_type +gt_lookup_grid_type(const char *grid_name, const char *module) +{ + grid_mapping_t *g; + + for (g = gt_mps_grid_names; (g->shortname); g++) { + if ((case_ignore_strcmp(grid_name, g->shortname) == 0) || + (case_ignore_strcmp(grid_name, g->longname) == 0)) + return g->grid; + } + + fatal("%s: Unsupported grid (%s)! See GPSBabel help for supported grids.\n", + module, grid_name); + + return grid_unknown; /* (warnings) */ +} + +char * +gt_get_mps_grid_longname(const grid_type grid, const char *module) +{ + if ((grid < GRID_INDEX_MIN) || (grid > GRID_INDEX_MAX)) + fatal("%s: Grid index out of range %d (%d..%d)!", + module, (int) grid, + (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); + return gt_mps_grid_names[grid].longname; +} + +char * +gt_get_mps_datum_name(const int datum_index) +{ + char *result; + datum_mapping_t *d; + + result = GPS_Math_Get_Datum_Name(datum_index); + + for (d = gt_mps_datum_names; (d->jeeps_name); d++) + if (case_ignore_strcmp(result, d->jeeps_name) == 0) return d->mps_name; + + return result; +} + +int +gt_lookup_datum_index(const char *datum_str, const char *module) +{ + datum_mapping_t *d; + int result; + const char *name = datum_str; + + for (d = gt_mps_datum_names; (d->jeeps_name); d++) { + if (case_ignore_strcmp(name, d->mps_name) == 0) { + name = d->jeeps_name; + break; + } + } + + result = GPS_Lookup_Datum_Index(name); + + if (result < 0) { + char *tmp; + xasprintf(&tmp, "%s mean", datum_str); + result = GPS_Lookup_Datum_Index(tmp); + xfree(tmp); + } + + is_fatal(result < 0, + "%s: Unsupported datum (%s)! See GPSBabel help for supported datums.", + module, datum_str); + + return result; +} + +#if MAKE_TABLE + +/* + * Used to generate icon tables in appendix. + * cc -DMAKE_TABLE garmin_tables.c fatal.o util.o globals.o -lm + */ + +int cet_utf8_to_ucs4(const char *str, int *bytes, int *value) +{ + fatal("Should not be here."); +} + + +int +sortem(const void *a, const void *b) +{ + const icon_mapping_t *aa = a; + const icon_mapping_t *bb = b; + +// return aa->mpssymnum - bb->mpssymnum; + return strcmp(aa->icon, bb->icon); + +} + +main() +{ + icon_mapping_t *i; + qsort(garmin_icon_table, sizeof(garmin_icon_table) / sizeof(garmin_icon_table[0]) - 1, sizeof(garmin_icon_table[0]), sortem); + for (i = garmin_icon_table; i->icon; i++) { +// printf("%03d\t%s\n", i->mpssymnum, i->icon); + printf("%s\n", i->icon); + } +} +#endif diff --git a/garmin_tables.h b/garmin_tables.h new file mode 100644 index 000000000..c846c94c5 --- /dev/null +++ b/garmin_tables.h @@ -0,0 +1,100 @@ +/* + Garmin icon tables + Based on information provided by Ian Cowley, Sigurd Humerfelt, + and Garmin MapSource + + Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#ifndef GARMIN_TABLES_H +#define GARMIN_TABLES_H + +#include "defs.h" + +#define DEFAULT_ICON_DESCR "Waypoint" +#define DEFAULT_ICON_VALUE 18 + +typedef struct icon_mapping { + const int mpssymnum; + const int pcxsymnum; + const char *icon; +} icon_mapping_t; + +typedef enum {MAPSOURCE, PCX, GARMIN_SERIAL, GDB} garmin_formats_e; + +char *gt_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format, int *dynamic); +int gt_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_format); + +extern icon_mapping_t garmin_icon_table[]; + +typedef enum { + gt_waypt_class_user_waypoint = 0, + gt_waypt_class_airport, + gt_waypt_class_intersection, + gt_waypt_class_ndb, + gt_waypt_class_vor, + gt_waypt_class_runway_threshold, + gt_waypt_class_airport_intersection, + gt_waypt_class_airport_ndb, + gt_waypt_class_map_point, + gt_waypt_class_map_area, + gt_waypt_class_map_intersection, + gt_waypt_class_map_address, + gt_waypt_class_map_line +} gt_waypt_classes_e; + +extern char *gt_waypt_class_names[]; + +typedef struct gt_country_code_s +{ + char *cc; + char *country; +} gt_country_code_t; + +extern gt_country_code_t gt_country_codes[]; + +char *gt_get_icao_country(const char *cc); +char *gt_get_icao_cc(const char *country, const char *shortname); + +/* this order is used by most devices */ +typedef enum { + gt_display_mode_symbol_and_name = 0, + gt_display_mode_symbol, + gt_display_mode_symbol_and_comment +} gt_display_modes_e; + +extern char *gt_display_mode_names[]; + +#define GT_DISPLAY_MODE_MIN gt_display_mode_symbol_and_name +#define GT_DISPLAY_MODE_MAX gt_display_mode_symbol_and_comment + +typedef enum { + gt_gdb_display_mode_symbol = 0, + gt_gdb_display_mode_symbol_and_name, + gt_gdb_display_mode_symbol_and_comment +} gt_gdb_display_modes_e; + +unsigned char gt_convert_category(const char *name, int *category); + +unsigned char gt_switch_display_mode_value(const unsigned char display_mode, const int protoid, const char device); + +grid_type gt_lookup_grid_type(const char *grid_name, const char *module); +char *gt_get_mps_grid_longname(const grid_type grid, const char *module); +int gt_lookup_datum_index(const char *datum_str, const char *module); +char *gt_get_mps_datum_name(const int datum_index); + +#endif diff --git a/garmin_txt.c b/garmin_txt.c new file mode 100644 index 000000000..e17a9a6fc --- /dev/null +++ b/garmin_txt.c @@ -0,0 +1,1284 @@ +/* + + Support for MapSource Text Export (Tab delimited) files. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +#if CSVFMTS_ENABLED +#include +#include +#include +#include +#include +#include "cet_util.h" +#include "csv_util.h" +#include "garmin_fs.h" +#include "garmin_tables.h" +#include "grtcirc.h" +#include "inifile.h" +#include "jeeps/gpsmath.h" +#include "strptime.h" + +#define MYNAME "garmin_txt" + +typedef struct gtxt_flags_s { + unsigned int metric:1; + unsigned int celsius:1; + unsigned int utc:1; + unsigned int enum_waypoints:1; + unsigned int route_header_written:1; + unsigned int track_header_written:1; +} gtxt_flags_t; + +static gbfile *fin, *fout; +static route_head *current_trk, *current_rte; +static int waypoints; +static int routepoints; +static waypoint **wpt_a; +static int wpt_a_ct; +static grid_type grid_index; +static int datum_index; +static char *datum_str; +static int current_line; +static char *date_time_format = NULL; +static int precision = 3; +static time_t utc_offs = 0; + +static gtxt_flags_t gtxt_flags; + +typedef enum { + waypt_header = 0, + rtept_header, + trkpt_header, + route_header, + track_header, + unknown_header +} header_type; + +#define MAX_HEADER_FIELDS 36 + +static char *header_lines[unknown_header + 1][MAX_HEADER_FIELDS]; +static int header_fields[unknown_header + 1][MAX_HEADER_FIELDS]; +static int header_ct[unknown_header + 1]; + +#define GARMIN_UNKNOWN_ALT 1.0e25f +#define DEFAULT_DISPLAY garmin_display_symbol_and_name +#define DEFAULT_DATE_FORMAT "dd/mm/yyyy" +#define DEFAULT_TIME_FORMAT "HH:mm:ss" + +/* macros */ + +#define IS_VALID_ALT(a) (((a) != unknown_alt) && ((a) < GARMIN_UNKNOWN_ALT)) +#define DUPSTR(a) (((a) != NULL) && ((a)[0] != 0)) ? xstrdup((a)) : NULL + +static char *opt_datum = NULL; +static char *opt_dist = NULL; +static char *opt_temp = NULL; +static char *opt_date_format = NULL; +static char *opt_time_format = NULL; +static char *opt_precision = NULL; +static char *opt_utc = NULL; +static char *opt_grid = NULL; + +static +arglist_t garmin_txt_args[] = { + {"date", &opt_date_format, "Read/Write date format (i.e. yyyy/mm/dd)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"datum", &opt_datum, "GPS datum (def. WGS 84)", "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, + {"dist", &opt_dist, "Distance unit [m=metric, s=statute]", "m", ARGTYPE_STRING, ARG_NOMINMAX}, + {"grid", &opt_grid, "Write position using this grid.", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"prec", &opt_precision, "Precision of coordinates", "3", ARGTYPE_INT, ARG_NOMINMAX}, + {"temp", &opt_temp, "Temperature unit [c=Celsius, f=Fahrenheit]", "c", ARGTYPE_STRING, ARG_NOMINMAX}, + {"time", &opt_time_format, "Read/Write time format (i.e. HH:mm:ss xx)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"utc", &opt_utc, "Write timestamps with offset x to UTC time", NULL, ARGTYPE_INT, "-23", "+23"}, + ARG_TERMINATOR +}; + +typedef struct info_s +{ + double length; + time_t start; + time_t time; + double speed; + double total; + int count; + waypoint *prev_wpt; + waypoint *first_wpt; + waypoint *last_wpt; +} info_t; + +static info_t *route_info; +static int route_idx; +static info_t *cur_info; + +static char *headers[] = { + "Name\tDescription\tType\tPosition\tAltitude\tDepth\tProximity\tTemperature\t" + "Display Mode\tColor\tSymbol\tFacility\tCity\tState\tCountry\t" + "Date Modified\tLink\tCategories", + "Waypoint Name\tDistance\tLeg Length\tCourse", + "Position\tTime\tAltitude\tDepth\tTemperature\tLeg Length\tLeg Time\tLeg Speed\tLeg Course", + "Name\tLength\tCourse\tWaypoints\tLink", + "Name\tStart Time\tElapsed Time\tLength\tAverage Speed\tLink", + NULL +}; + +/* helpers */ + +static char * +get_option_val(char *option, char *def) +{ + char *c = (option != NULL) ? option : def; + return c; +} + +static void +init_date_and_time_format(void) +{ + char *f, *c; + + f = get_option_val(opt_date_format, DEFAULT_DATE_FORMAT); + date_time_format = convert_human_date_format(f); + + date_time_format = xstrappend(date_time_format, " "); + + f = get_option_val(opt_time_format, DEFAULT_TIME_FORMAT); + c = convert_human_time_format(f); + date_time_format = xstrappend(date_time_format, c); + xfree(c); +} + +static void +convert_datum(const waypoint *wpt, double *dest_lat, double *dest_lon) +{ + double alt; + + if (datum_index == DATUM_WGS84 ) { + *dest_lat = wpt->latitude; + *dest_lon = wpt->longitude; + } + else GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, + dest_lat, dest_lon, &alt, datum_index); +} + +/* WRITER *****************************************************************/ + +/* Waypoint preparation */ + +static void +enum_waypt_cb(const waypoint *wpt) +{ + garmin_fs_p gmsd; + int wpt_class; + + gmsd = GMSD_FIND(wpt); + wpt_class = GMSD_GET(wpt_class, 0); + if (wpt_class < 0x80) + { + int i; + + if (gtxt_flags.enum_waypoints) /* enumerate only */ + { + waypoints++; + return; + } + for (i = 0; i < wpt_a_ct; i++) { /* check for duplicates */ + waypoint *tmp = wpt_a[i]; + if (case_ignore_strcmp(tmp->shortname, wpt->shortname) == 0) + { + wpt_a[i] = (waypoint *)wpt; + waypoints--; + return; + + } + } + wpt_a[wpt_a_ct++] = (waypoint *)wpt; + } + +} + +static int +sort_waypt_cb(const void *a, const void *b) +{ + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; + + return case_ignore_strcmp(wa->shortname, wb->shortname); +} + + +/* common route and track pre-work */ + +static void +prework_hdr_cb(const route_head *rte) +{ + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->length = 0; + cur_info->time = 0; +} + +static void +prework_tlr_cb(const route_head *rte) +{ + cur_info->last_wpt = cur_info->prev_wpt; + route_idx++; +} + +static void +prework_wpt_cb(const waypoint *wpt) +{ + waypoint *prev = cur_info->prev_wpt; + + if (prev != NULL) { + cur_info->time += (wpt->creation_time - prev->creation_time); + cur_info->length += waypt_distance_ex(prev, wpt); + } + else { + cur_info->first_wpt = (waypoint *)wpt; + cur_info->start = wpt->creation_time; + } + cur_info->prev_wpt = (waypoint *)wpt; + cur_info->count++; + routepoints++; +} + + +/* output helpers */ + +static void +print_position(const waypoint *wpt) +{ + int valid = 1; + double lat, lon, north, east; + char latsig, lonsig; + double latmin, lonmin, latsec, lonsec; + int latint, lonint, zone; + char map[3], zonec; + + convert_datum(wpt, &lat, &lon); + + /* ----------------------------------------------------------------------------*/ + /* the following code is from pretty_deg_format (util.c) */ + /* ----------------------------------------------------------------------------*/ + /* !ToDo! generate common code for calculating of degrees, minutes and seconds */ + /* ----------------------------------------------------------------------------*/ + + latsig = lat < 0 ? 'S':'N'; + lonsig = lon < 0 ? 'W':'E'; + latint = abs((int) lat); + lonint = abs((int) lon); + latmin = 60.0 * (fabs(lat) - latint); + lonmin = 60.0 * (fabs(lon) - lonint); + latsec = 60.0 * (latmin - floor(latmin)); + lonsec = 60.0 * (lonmin - floor(lonmin)); + + switch(grid_index) { + + case grid_lat_lon_ddd: + + gbfprintf(fout, "%c%0.*f %c%0.*f\t", + latsig, precision, fabs(lat), + lonsig, precision, fabs(lon)); + break; + + case grid_lat_lon_dmm: + + gbfprintf(fout, "%c%d %0*.*f %c%d %0*.*f\t", + latsig, latint, precision + 3, precision, latmin, + lonsig, lonint, precision + 3, precision, lonmin); + break; + + case grid_lat_lon_dms: + + gbfprintf(fout, "%c%d %d %.*f %c%d %d %.*f\t", + latsig, latint, (int)latmin, precision, latsec, + lonsig, lonint, (int)lonmin, precision, lonsec); + break; + + case grid_bng: + + valid = GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map); + if (valid) gbfprintf(fout, "%s %5.0f %5.0f\t", map, east, north); + break; + + case grid_utm: + + valid = GPS_Math_Known_Datum_To_UTM_EN(lat, lon, + &east, &north, &zone, &zonec, datum_index); + if (valid) gbfprintf(fout, "%02d %c %.0f %.0f\t", zone, zonec, east, north); + break; + + case grid_swiss: + + valid = GPS_Math_WGS84_To_CH1903_NGEN(wpt->latitude, wpt->longitude, &east, &north); + if (valid) gbfprintf(fout, "%.f %.f\t", east, north); + break; + + default: + fatal("ToDo\n"); + } + + if (! valid) { + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": %s (%s) is outside of convertable area \"%s\"!\n", + wpt->shortname ? wpt->shortname : "Waypoint", + pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), + gt_get_mps_grid_longname(grid_index, MYNAME)); + } +} + +static void +print_date_and_time(const time_t time, const int time_only) +{ + struct tm tm; + char tbuf[32]; + + if (time < 0) { + gbfprintf(fout, "\t"); + return; + } + if (time_only) { + tm = *gmtime(&time); + snprintf(tbuf, sizeof(tbuf), "%d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); + gbfprintf(fout, "%s", tbuf); + } + else if (time != 0) { + if (gtxt_flags.utc) { + time_t t = time + utc_offs; + tm = *gmtime(&t); + } + else + tm = *localtime(&time); + strftime(tbuf, sizeof(tbuf), date_time_format, &tm); + gbfprintf(fout, "%s ", tbuf); + } + gbfprintf(fout, "\t"); +} + +static void +print_categories(gbuint16 categories) +{ + int i, count; + char *c; + + if (categories == 0) return; + + count = 0; + for (i = 0; i < 16; i++) { + if ((categories & 1) != 0) { + if (global_opts.inifile != NULL) { + char key[3]; + snprintf(key, sizeof(key), "%d", i + 1); + c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); + } + else c = NULL; + + gbfprintf(fout, "%s", (count++ > 0) ? "," : ""); + if (c == NULL) + gbfprintf(fout, "Category %d", i+1); +// gbfprintf(fout, "%s", gps_categories[i]); + else + gbfprintf(fout, "%s", c); + + } + categories = categories >> 1; + } +} + +static void +print_course(const waypoint *A, const waypoint *B) /* seems to be okay */ +{ + if ((A != NULL) && (B != NULL) && (A != B)) { + int course; + course = si_round(waypt_course(A, B)); + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "%d%c true", course, 0xB0); + } +} + +static void +print_distance(const double distance, const int no_scale, const int with_tab, const int decis) +{ + double dist = distance; + + if (gtxt_flags.metric == 0) { + dist = METERS_TO_FEET(dist); + + if ((dist < 5280) || no_scale) + gbfprintf(fout, "%.*f ft", decis, dist); + else { + dist = METERS_TO_MILES(distance); + if (dist < (double)100) + gbfprintf(fout, "%.1f mi", dist); + else + gbfprintf(fout, "%d mi", si_round(dist)); + } + } + else + { + if ((dist < 1000) || no_scale) + gbfprintf(fout, "%.*f m", decis, dist); + else { + dist = dist / (double)1000.0; + if (dist < (double)100) + gbfprintf(fout, "%.1f km", dist); + else + gbfprintf(fout, "%d km", si_round(dist)); + } + } + if (with_tab) gbfprintf(fout, "\t"); +} + +static void +print_speed(double *distance, time_t *time) +{ + int idist; + double dist = *distance; + char *unit; + + if (!gtxt_flags.metric) { + dist = METERS_TO_MILES(dist) * 1000.0; + unit = "mph"; + } + else unit = "kph"; + idist = si_round(dist); + + if ((*time != 0) && (idist > 0)) { + double speed = MPS_TO_KPH(dist / (double)*time); + int ispeed = si_round(speed); + + if (speed < (double)0.01) + gbfprintf(fout, "0 %s", unit); + else if (ispeed < 2) + gbfprintf(fout, "%.1f %s", speed, unit); + else + gbfprintf(fout, "%d %s", ispeed, unit); + } + else + gbfprintf(fout, "0 %s", unit); + gbfprintf(fout, "\t"); +} + +static void +print_temperature(const float temperature) +{ + if (gtxt_flags.celsius) + gbfprintf(fout, "%.f C", temperature); + else + gbfprintf(fout, "%.f F", (temperature * 1.8) + 32); +} + +static void +print_string(const char *fmt, const char *string) +{ + char *c; + char *buff; + + buff = xstrdup(string); + /* remove unwanted characters from source string */ + for (c = buff; *c; c++) { + if (iscntrl(*c)) { + *c = ' '; + } + } + gbfprintf(fout, fmt, buff); + xfree(buff); +} + + +/* main cb's */ + +static void +write_waypt(const waypoint *wpt) +{ + unsigned char wpt_class; + garmin_fs_p gmsd; + char *wpt_type; + char *dspl_mode; + char *country; + double x; + int i, icon, dynamic; + char *icon_descr; + + gmsd = GMSD_FIND(wpt); + + i = GMSD_GET(display, 0); + if (i > GT_DISPLAY_MODE_MAX) i = 0; + dspl_mode = gt_display_mode_names[i]; + + wpt_class = GMSD_GET(wpt_class, 0); + if (wpt_class <= gt_waypt_class_map_line) + wpt_type = gt_waypt_class_names[wpt_class]; + else + wpt_type = gt_waypt_class_names[0]; + + gbfprintf(fout, "Waypoint\t%s\t", (wpt->shortname) ? wpt->shortname : ""); + if (wpt_class <= gt_waypt_class_airport_ndb) { + char *temp = wpt->notes; + if (temp == NULL) { + if (wpt->description && (strcmp(wpt->description, wpt->shortname) != 0)) + temp = wpt->description; + else + temp = ""; + } + print_string("%s\t", temp); + } + else + gbfprintf(fout, "\t"); + gbfprintf(fout, "%s\t", wpt_type); + + print_position(wpt); + + if IS_VALID_ALT(wpt->altitude) + print_distance(wpt->altitude, 1, 0, 0); + gbfprintf(fout, "\t"); + + x = WAYPT_GET(wpt, depth, unknown_alt); + if (x != unknown_alt) + print_distance(x, 1, 0, 1); + gbfprintf(fout, "\t"); + + x = WAYPT_GET(wpt, proximity, unknown_alt); + if (x != unknown_alt) + print_distance(x, 0, 0, 0); + gbfprintf(fout, "\t"); + + x = WAYPT_GET(wpt, temperature, -999); + if (x != -999) + print_temperature(x); + gbfprintf(fout, "\t%s\t", dspl_mode); + + gbfprintf(fout, "Unknown\t"); /* Color is fixed: Unknown */ + + icon = GMSD_GET(icon, -1); + if (icon == -1) { + icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); + } + icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); + print_string("%s\t", icon_descr); + if (dynamic) xfree(icon_descr); + + print_string("%s\t", GMSD_GET(facility, "")); + print_string("%s\t", GMSD_GET(city, "")); + print_string("%s\t", GMSD_GET(state, "")); + country = gt_get_icao_country(GMSD_GET(cc, "")); + print_string("%s\t", (country != NULL) ? country : ""); + print_date_and_time(wpt->creation_time, 0); + print_string("%s\t", wpt->url ? wpt->url : ""); + print_categories(GMSD_GET(category, 0)); + + gbfprintf(fout, "\r\n"); +} + +static void +route_disp_hdr_cb(const route_head *rte) +{ + current_trk = (route_head *)rte; + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->total = 0; + if (rte->rte_waypt_ct <= 0) return; + + if (!gtxt_flags.route_header_written) { + gtxt_flags.route_header_written = 1; + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[route_header]); + } + + print_string("\r\nRoute\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); + print_distance(cur_info->length, 0, 1, 0); + print_course(cur_info->first_wpt, cur_info->last_wpt); + gbfprintf(fout, "\t%d waypoints\t", cur_info->count); + print_string("%s\r\n", rte->rte_url ? rte->rte_url : ""); + gbfprintf(fout, "\r\nHeader\t%s\r\n\r\n", headers[rtept_header]); +} + +static void +route_disp_tlr_cb(const route_head *rte) +{ + route_idx++; +} + +static void +route_disp_wpt_cb(const waypoint *wpt) +{ + waypoint *prev = cur_info->prev_wpt; + + gbfprintf(fout, "Route Waypoint\t"); + gbfprintf(fout, "%s\t", wpt->shortname); + + if (prev != NULL) + { + double dist = waypt_distance_ex(prev, wpt); + cur_info->total += dist; + print_distance(cur_info->total, 0, 1, 0); + print_distance(dist, 0, 1, 0); + print_course(prev, wpt); + } + else + print_distance(0, 1, 0, 0); + + gbfprintf(fout, "\r\n"); + + cur_info->prev_wpt = (waypoint *)wpt; +} + +static void +track_disp_hdr_cb(const route_head *track) +{ + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->total = 0; + current_trk = (route_head *)track; + if (track->rte_waypt_ct <= 0) return; + + if (!gtxt_flags.track_header_written) { + gtxt_flags.track_header_written = 1; + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[track_header]); + } + + print_string("\r\nTrack\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); + print_date_and_time(cur_info->start, 0); + print_date_and_time(cur_info->time, 1); + print_distance(cur_info->length, 0, 1, 0); + print_speed(&cur_info->length, &cur_info->time); + print_string("%s", (track->rte_url != NULL) ? track->rte_url : ""); + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n\r\n", headers[trkpt_header]); +} + +static void +track_disp_tlr_cb(const route_head *track) +{ + route_idx++; +} + +static void +track_disp_wpt_cb(const waypoint *wpt) +{ + waypoint *prev = cur_info->prev_wpt; + time_t delta; + double dist, depth; + + gbfprintf(fout, "Trackpoint\t"); + + print_position(wpt); + print_date_and_time(wpt->creation_time, 0); + if IS_VALID_ALT(wpt->altitude) + print_distance(wpt->altitude, 1, 0, 0); + + gbfprintf(fout, "\t"); + depth = WAYPT_GET(wpt, depth, unknown_alt); + if (depth != unknown_alt) + print_distance(depth, 1, 0, 1); + + if (prev != NULL) { + float temp; + gbfprintf(fout, "\t"); + delta = wpt->creation_time - prev->creation_time; + temp = WAYPT_GET(wpt, temperature, -999); + if (temp != -999) + print_temperature(temp); + gbfprintf(fout, "\t"); + dist = waypt_distance_ex(prev, wpt); + print_distance(dist, 0, 1, 0); + print_date_and_time(delta, 1); + print_speed(&dist, &delta); + print_course(prev, wpt); + } + gbfprintf(fout, "\r\n"); + + cur_info->prev_wpt = (waypoint *)wpt; +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +garmin_txt_wr_init(const char *fname) +{ + char *grid_str; + + memset(>xt_flags, 0, sizeof(gtxt_flags)); + + fout = gbfopen(fname, "wb", MYNAME); + + gtxt_flags.metric = (toupper(*get_option_val(opt_dist, "m")) == 'M'); + gtxt_flags.celsius = (toupper(*get_option_val(opt_temp, "c")) == 'C'); + init_date_and_time_format(); + if (opt_precision) { + precision = atoi(opt_precision); + is_fatal(precision < 0, MYNAME ": Invalid precision (%s)!", opt_precision); + } + + datum_str = get_option_val(opt_datum, NULL); + grid_str = get_option_val(opt_grid, NULL); + + grid_index = grid_lat_lon_dmm; + if (grid_str != NULL) { + int i; + + if (sscanf(grid_str, "%d", &i)) { + grid_index = (grid_type) i; + if ((grid_index < GRID_INDEX_MIN) || (grid_index > GRID_INDEX_MAX)) + fatal(MYNAME ": Grid index out of range (%d..%d)!", + (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); + } + else grid_index = gt_lookup_grid_type(grid_str, MYNAME); + } + + switch(grid_index) { + case grid_bng: /* force datum to "Ord Srvy Grt Britn" */ + datum_index = DATUM_OSGB36; + break; + case grid_swiss: /* force datum to "Ord Srvy Grt Britn" */ + datum_index = DATUM_WGS84; + break; + default: + datum_index = gt_lookup_datum_index(datum_str, MYNAME); + } + + if (opt_utc != NULL) { + if (case_ignore_strcmp(opt_utc, "utc") == 0) + utc_offs = 0; + else + utc_offs = atoi(opt_utc); + utc_offs *= (60 * 60); + gtxt_flags.utc = 1; + } +} + +static void +garmin_txt_wr_deinit(void) +{ + gbfclose(fout); + xfree(date_time_format); +} + +static void +garmin_txt_write(void) +{ + char *grid_str, *c; + + grid_str = xstrdup(gt_get_mps_grid_longname(grid_index, MYNAME)); + while ((c = strchr(grid_str, '*'))) *c = 0xB0; /* degree sign */ + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\t%s\r\n", grid_str); + xfree(grid_str); + + datum_str = gt_get_mps_datum_name(datum_index); + gbfprintf(fout, "Datum\t%s\r\n\r\n", datum_str); + + waypoints = 0; + gtxt_flags.enum_waypoints = 1; /* enum all waypoints */ + waypt_disp_all(enum_waypt_cb); + route_disp_all(NULL, NULL, enum_waypt_cb); + gtxt_flags.enum_waypoints = 0; + + if (waypoints > 0) { + int i; + + wpt_a_ct = 0; + wpt_a = (waypoint **)xcalloc(waypoints, sizeof(*wpt_a)); + waypt_disp_all(enum_waypt_cb); + route_disp_all(NULL, NULL, enum_waypt_cb); + qsort(wpt_a, waypoints, sizeof(*wpt_a), sort_waypt_cb); + + gbfprintf(fout, "Header\t%s\r\n\r\n", headers[waypt_header]); + for (i = 0; i < waypoints; i++) + { + waypoint *wpt = wpt_a[i]; + write_waypt(wpt); + } + xfree(wpt_a); + + route_idx = 0; + route_info = xcalloc(route_count(), sizeof(struct info_s)); + routepoints = 0; + route_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); + if (routepoints > 0) + { + route_idx = 0; + route_disp_all(route_disp_hdr_cb, route_disp_tlr_cb, route_disp_wpt_cb); + } + xfree(route_info); + } + + route_idx = 0; + route_info = xcalloc(track_count(), sizeof(struct info_s)); + routepoints = 0; + track_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); + + if (routepoints > 0) { + route_idx = 0; + track_disp_all(track_disp_hdr_cb, track_disp_tlr_cb, track_disp_wpt_cb); + } + xfree(route_info); +} + +/* READER *****************************************************************/ + +/* helpers */ + +static void +free_header(const header_type ht) +{ + int i; + + for (i = 0; i < MAX_HEADER_FIELDS; i++) { + char *c = header_lines[ht][i]; + if (c != NULL) { + xfree(c); + header_lines[ht][i] = NULL; + } + } + header_ct[ht] = 0; + memset(header_fields[ht], 0, sizeof(header_fields[ht])); +} + +/* data parsers */ + +static int +parse_date_and_time(char *str, time_t *value) +{ + struct tm tm; + char *cerr, *cin; + + memset(&tm, 0, sizeof(tm)); + cin = lrtrim(str); + if (*cin == '\0') return 0; + + cerr = strptime(cin, date_time_format, &tm); + if (cerr == NULL) { + cerr = strptime(cin, "%m/%d/%Y %I:%M:%S %p", &tm); + is_fatal(cerr == NULL, MYNAME ": Invalid date or/and time \"%s\" at line %d!", cin, current_line); + } + +// printf(MYNAME "_parse_date_and_time: %02d.%02d.%04d, %02d:%02d:%02d\n", +// tm.tm_mday, tm.tm_mon+1, tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec); + + *value = mklocaltime(&tm); + return 1; +} + +static gbuint16 +parse_categories(const char *str) +{ + char buff[256]; + gbuint16 val; + gbuint16 res = 0; + char *cin, *cx; + + if (*str == '\0') return 0; + + strncpy(buff, str, sizeof(buff)); + cin = lrtrim(buff); + if (*cin == '\0') return 0; + + strcat(cin, ","); + + while ((cx = strchr(cin, ','))) { + *cx++ = '\0'; + cin = lrtrim(cin); + if (*cin != '\0') { + if (!garmin_fs_convert_category(cin, &val)) + warning(MYNAME ": Unable to convert category \"%s\" at line %d!\n", cin, current_line); + else + res = res | val; + } + cin = cx; + } + return res; +} + +static int +parse_temperature(const char *str, double *temperature) +{ + double value; + unsigned char unit; + + if ((str == NULL) || (*str == '\0')) return 0; + + if (sscanf(str, "%lf %c", &value, &unit) == 2) { + unit = toupper(unit); + switch(unit) { + case 'C': *temperature = value; break; + case 'F': *temperature = FAHRENHEIT_TO_CELSIUS(value); break; + default: + fatal(MYNAME ": Unknown temperature unit \"%c\" at line %d!\n", unit, current_line); + } + return 1; + } + else + fatal(MYNAME ": Invalid temperature \"%s\" at line %d!\n", str, current_line); + return 0; +} + +static void +parse_header(void) +{ + char *str; + int column = -1; + + free_header(unknown_header); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + header_lines[unknown_header][column] = strupper(xstrdup(str)); + header_ct[unknown_header]++; + if (header_ct[unknown_header] >= MAX_HEADER_FIELDS) break; + } +} + +static int +parse_display(const char *str, int *val) +{ + gt_display_modes_e i; + + if ((str == NULL) || (*str == '\0')) return 0; + + for (i = GT_DISPLAY_MODE_MIN; i <= GT_DISPLAY_MODE_MAX; i++) { + if (case_ignore_strcmp(str, gt_display_mode_names[i]) == 0) { + *val = i; + return 1; + } + } + warning(MYNAME ": Unknown display mode \"%s\" at line %d.\n", str, current_line); + return 0; +} + +static void +bind_fields(const header_type ht) +{ + int i; + char *fields, *c; + + is_fatal((grid_index < 0) || (datum_index < 0), MYNAME ": Incomplete or invalid file header!"); + + if (header_ct[unknown_header] <= 0) return; + free_header(ht); + + /* make a copy of headers[ht], uppercase, replace "\t" with "\0" */ + + i = strlen(headers[ht]); + fields = xmalloc(i + 2); + strcpy(fields, headers[ht]); + strcat(fields, "\t"); + c = strupper(fields); + while ((c = strchr(c, '\t'))) *c++ = '\0'; + + for (i = 0; i < header_ct[unknown_header]; i++) { + char *name; + int field_no; + name = header_lines[ht][i] = header_lines[unknown_header][i]; + header_lines[unknown_header][i] = NULL; + + c = fields; + field_no = 1; + while (*c) { + if (strcmp(c, name) == 0) { + header_fields[ht][i] = field_no; +#if 0 + printf("Binding field \"%s\" to internal number %d (%d,%d)\n", name, field_no, ht, i); +#endif + break; + } + field_no++; + c = c + strlen(c) + 1; + } + } + header_ct[unknown_header] = 0; + xfree(fields); +} + +static void +parse_grid(void) +{ + char *str = csv_lineparse(NULL, "\t", "", 1); + + if (str != NULL) { + if (strstr(str, "dd.ddddd") != 0) grid_index = grid_lat_lon_ddd; + else if (strstr(str, "mm.mmm") != 0) grid_index = grid_lat_lon_dmm; + else if (strstr(str, "mm'ss.s") != 0) grid_index = grid_lat_lon_dms; + else grid_index = gt_lookup_grid_type(str, MYNAME); + } + else + fatal(MYNAME ": Missing grid headline!\n"); +} + +static void +parse_datum(void) +{ + char *str = csv_lineparse(NULL, "\t", "", 1); + + if (str != NULL) + datum_index = gt_lookup_datum_index(str, MYNAME); + else + fatal(MYNAME ": Missing GPS datum headline!\n"); +} + +static void +parse_waypoint(void) +{ + char *str; + int column = -1; + waypoint *wpt; + garmin_fs_p gmsd = NULL; + + bind_fields(waypt_header); + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) + { + int i, dynamic; + double d; + int field_no = header_fields[waypt_header][column]; + + switch(field_no) { + case 1: wpt->shortname = DUPSTR(str); break; + case 2: wpt->notes = DUPSTR(str); break; + case 3: + for (i = 0; i <= gt_waypt_class_map_line; i++) { + if (case_ignore_strcmp(str, gt_waypt_class_names[i]) == 0) { + GMSD_SET(wpt_class, i); + break; + } + } + break; + case 4: + parse_coordinates(str, datum_index, grid_index, + &wpt->latitude, &wpt->longitude, MYNAME); + break; + case 5: if (parse_distance(str, &d, 1, MYNAME)) wpt->altitude = d; break; + case 6: if (parse_distance(str, &d, 1, MYNAME)) WAYPT_SET(wpt, depth, d); break; + case 7: if (parse_distance(str, &d, 1, MYNAME)) WAYPT_SET(wpt, proximity, d); break; + case 8: if (parse_temperature(str, &d)) WAYPT_SET(wpt, temperature, d); break; + case 9: if (parse_display(str, &i)) GMSD_SET(display, i); break; + case 10: break; /* skip color */ + case 11: + i = gt_find_icon_number_from_desc(str, GDB); + GMSD_SET(icon, i); + wpt->icon_descr = gt_find_desc_from_icon_number(i, GDB, &dynamic); + wpt->wpt_flags.icon_descr_is_dynamic = dynamic; + break; + case 12: GMSD_SETSTR(facility, str); break; + case 13: GMSD_SETSTR(city, str); break; + case 14: GMSD_SETSTR(state, str); break; + case 15: + GMSD_SETSTR(country, str); + GMSD_SETSTR(cc, gt_get_icao_cc(str, wpt->shortname)); + break; + case 16: parse_date_and_time(str, &wpt->creation_time); break; + case 17: wpt->url = DUPSTR(str); break; + case 18: GMSD_SET(category, parse_categories(str)); break; + default: break; + } + } + waypt_add(wpt); +} + +static void +parse_route_header(void) +{ + char *str; + int column = -1; + route_head *rte; + + rte = route_head_alloc(); + + bind_fields(route_header); + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[route_header][column]; + switch(field_no) { + case 1: rte->rte_name = DUPSTR(str); break; + case 5: rte->rte_url = DUPSTR(str); break; + } + } + route_add_head(rte); + current_rte = rte; +} + +static void +parse_track_header(void) +{ + char *str; + int column = -1; + route_head *trk; + + bind_fields(track_header); + trk = route_head_alloc(); + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[track_header][column]; + switch(field_no) { + case 1: trk->rte_name = DUPSTR(str); break; + case 6: trk->rte_url = DUPSTR(str); break; + } + } + track_add_head(trk); + current_trk = trk; +} + +static void +parse_route_waypoint(void) +{ + char *str; + int column = -1; + waypoint *wpt = NULL; + + bind_fields(rtept_header); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[rtept_header][column]; + switch(field_no) { + case 1: + is_fatal((*str == '\0'), MYNAME ": Route waypoint without name at line %d!\n", current_line); + wpt = find_waypt_by_name(str); + is_fatal((wpt == NULL), MYNAME ": Route waypoint \"%s\" not in waypoint list (line %d)!\n", str, current_line); + wpt = waypt_dupe(wpt); + break; + } + } + if (wpt != NULL) + route_add_wpt(current_rte, wpt); +} + +static void +parse_track_waypoint(void) +{ + char *str; + int column = -1; + waypoint *wpt; + + bind_fields(trkpt_header); + wpt = waypt_new(); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no; + double x; + + if (! *str) continue; + + field_no = header_fields[trkpt_header][column]; + switch(field_no) { + case 1: + parse_coordinates(str, datum_index, grid_index, + &wpt->latitude, &wpt->longitude, MYNAME); + break; + case 2: + parse_date_and_time(str, &wpt->creation_time); + break; + case 3: + if (parse_distance(str, &x, 1, MYNAME)) + wpt->altitude = x; + break; + case 4: + if (parse_distance(str, &x, 1, MYNAME)) WAYPT_SET(wpt, depth, x); + break; + case 5: + if (parse_temperature(str, &x)) WAYPT_SET(wpt, temperature, x); + break; + case 8: + if (parse_speed(str, &x, 1, MYNAME)) WAYPT_SET(wpt, speed, x); + break; + case 9: + WAYPT_SET(wpt, course, atoi(str)); + break; + } + } + track_add_wpt(current_trk, wpt); +} + +/***************************************************************/ + +static void +garmin_txt_rd_init(const char *fname) +{ + memset(>xt_flags, 0, sizeof(gtxt_flags)); + + fin = gbfopen(fname, "rb", MYNAME); + memset(&header_ct, 0, sizeof(header_ct)); + + datum_index = -1; + grid_index = -1; + + init_date_and_time_format(); +} + +static void +garmin_txt_rd_deinit(void) +{ + header_type h; + + for (h = waypt_header; h <= unknown_header; h++) { + free_header(h); + } + gbfclose(fin); + xfree(date_time_format); +} + +static void +garmin_txt_read(void) +{ + char *buff; + + current_line = 0; + + while ((buff = gbfgetstr(fin))) { + char *cin; + + current_line++; + cin = lrtrim(buff); + if (*cin == '\0') continue; + + cin = csv_lineparse(cin, "\t", "", 0); + + if (cin == NULL) continue; + + if (case_ignore_strcmp(cin, "Header") == 0) parse_header(); + else if (case_ignore_strcmp(cin, "Grid") == 0) parse_grid(); + else if (case_ignore_strcmp(cin, "Datum") == 0) parse_datum(); + else if (case_ignore_strcmp(cin, "Waypoint") == 0) parse_waypoint(); + else if (case_ignore_strcmp(cin, "Route Waypoint") == 0) parse_route_waypoint(); + else if (case_ignore_strcmp(cin, "Trackpoint") == 0) parse_track_waypoint(); + else if (case_ignore_strcmp(cin, "Route") == 0) parse_route_header(); + else if (case_ignore_strcmp(cin, "Track") == 0) parse_track_header(); + else if (case_ignore_strcmp(cin, "Map") == 0) /* do nothing */ ; + else + fatal(MYNAME ": Unknwon identifier (%s) at line %d!\n", cin, current_line); + + /* flush pending data */ + while (csv_lineparse(NULL, "\t", "", 0)); + } +} + +ff_vecs_t garmin_txt_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + garmin_txt_rd_init, + garmin_txt_wr_init, + garmin_txt_rd_deinit, + garmin_txt_wr_deinit, + garmin_txt_read, + garmin_txt_write, + NULL, + garmin_txt_args, + CET_CHARSET_MS_ANSI, 0 +}; + +#endif // CSVFMTS_ENABLED diff --git a/gbfile.c b/gbfile.c new file mode 100644 index 000000000..6bb978599 --- /dev/null +++ b/gbfile.c @@ -0,0 +1,885 @@ +/* + + Common GPSBabel file I/O API + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "gbfile.h" + +#include +#include +#include +#include +#include + + +#if __WIN32__ +/* taken from minigzip.c (part of the zlib project) */ +# include +# include +# define SET_BINARY_MODE(file) _setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#define MYNAME "gbfile" +#define NO_ZLIB MYNAME ": No zlib support.\n" + +/* About the ZLIB_INHIBITED stuff: + * + * If a user goes out of his way to build with ZLIB_INHIBITED set, + * we jettison our use of zlib entirely within this file, replacing + * all calls out to zlib with calls to abort() as that's an internal + * consistency error. + * + */ + +/* GPSBabel 'file' standard calls */ + +/* + * gbfopen: (as xfopen) plus the name of the calling GPSBabel module (MYNAME) + */ + +gbfile * +gbfopen(const char *filename, const char *mode, const char *module) +{ + gbfile *file; + const char *m; + int len; + + file = xcalloc(1, sizeof(*file)); + + file->name = xstrdup(filename); + file->module = xstrdup(module); + file->line = xstrdup(""); + file->mode = 'r'; // default + file->binary = (strchr(mode, 'b') != NULL); + file->back = -1; + + for (m = mode; *m; m++) { + switch(tolower(*m)) { + case 'r': + file->mode = 'r'; +#if !ZLIB_INHIBITED + file->gzapi = 1; /* native or transparent */ +#endif + break; + case 'w': + file->mode = 'w'; + break; + } + } + + /* Do we have a '.gz' extension in the filename ? */ + len = strlen(file->name); + if ((len > 3) && (case_ignore_strcmp(&file->name[len-3], ".gz") == 0)) { +#if !ZLIB_INHIBITED + /* force gzipped files on output */ + file->gzapi = 1; +#else + fatal(NO_ZLIB); +#endif + } + + if (file->gzapi) { +#if !ZLIB_INHIBITED + char openmode[32]; + + /* under non-posix systems files MUST be opened in binary mode */ + + strcpy(openmode, mode); + if (strchr(mode, 'b') == NULL) + strncat(openmode, "b", sizeof(openmode)); + + if (strcmp(filename, "-") == 0) { + FILE *fd; + if (file->mode == 'r') + fd = stdin; + else + fd = stdout; + SET_BINARY_MODE(fd); + file->handle.gz = gzdopen(fileno(fd), openmode); + } + else + file->handle.gz = gzopen(filename, openmode); + + if (file->handle.gz == NULL) { + fatal("%s: Cannot %s file '%s'!\n", + module, + (file->mode == 'r') ? "open" : "create", + filename); + } + file->gzapi = 1; +#else + /* This is the only runtime test we make */ + fatal("%s: Zlib was not included in this build.\n", file->module); +#endif + } + else { + file->handle.std = xfopen(filename, mode, module); + } +#ifdef DEBUG_MEM + file->buffsz = 1; +#else + file->buffsz = 256; +#endif + file->buff = xmalloc(file->buffsz); + + return file; +} + +/* + * gbfopen_be: as gbfopen, but set the BIG-ENDIAN flag + */ + +gbfile * +gbfopen_be(const char *filename, const char *mode, const char *module) +{ + gbfile *result; + + result = gbfopen(filename, mode, module); + result->big_endian = 1; + + return result; +} + +/* + * gbfclose: (as fclose) + */ + +void +gbfclose(gbfile *file) +{ + if (!file) return; + + if (file->gzapi) { +#if !ZLIB_INHIBITED + gzclose(file->handle.gz); +#else + fatal(NO_ZLIB); +#endif + } + else { + fclose(file->handle.std); + } + xfree(file->name); + xfree(file->module); + xfree(file->line); + xfree(file->buff); + xfree(file); +} + +/* + * gbfgetc: (as fgetc) + */ + +int +gbfgetc(gbfile *file) +{ + unsigned char c; + + /* errors are caught in gbfread */ + if (gbfread(&c, 1, 1, file) == 0) { + return EOF; + } + else { + return (unsigned int)c; + } +} + +/* + * gbfgets: (as fgets) + */ + +char * +gbfgets(char *buf, int len, gbfile *file) +{ + char *result = buf; + + while (--len > 0) { + int c = gbfgetc(file); + + if (c == EOF) break; + + *(unsigned char *)buf = (unsigned char)c; + buf++; + + if (c == '\r') { + c = gbfgetc(file); + if ((c != '\n') && (c != EOF)) gbfungetc(c, file); + break; + } + else if (c == '\n') + break; + } + *buf = '\0'; + return (*result != '\0') ? result : NULL; +} + +/* + * gbfread: (as fread) + */ + +gbsize_t +gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) +{ + if ((size == 0) || (members == 0)) return 0; + + if (file->gzapi) { +#if !ZLIB_INHIBITED + int result = 0; + char *target = buf; + int count = size * members; + + if (file->back != -1) { + *target++ = file->back; + count--; + result++; + file->back = -1; + } + result += gzread(file->handle.gz, target, count); + result /= size; + + if ((result < 0) || ((gbsize_t)result < members)) { + int errnum; + const char *errtxt; + + errtxt = gzerror(file->handle.gz, &errnum); + + /* Workaround for zlib bug: buffer error on empty files */ + if ((errnum == Z_BUF_ERROR) && (gztell(file->handle.gz) == 0)) { + return (gbsize_t) 0; + } + if ((errnum != Z_STREAM_END) && (errnum != 0)) + fatal("%s: zlib returned error %d ('%s')!\n", + file->module, errnum, errtxt); + } + return (gbsize_t) result; +#else + fatal(NO_ZLIB); + return -1; +#endif + } + else { + int errno; + gbsize_t result = fread(buf, size, members, file->handle.std); + + if ((result < members) && (errno = ferror(file->handle.std))) { + fatal("%s: Error %d occured during read of file '%s'!\n", + file->module, errno, file->name); + } + return result; + } +} + +/* + * gbvfprintf: (as vfprintf) + */ + +int gbvfprintf(gbfile *file, const char *format, va_list ap) +{ + int len; + + for (;;) { + va_list args; + + va_copy(args, ap); + len = vsnprintf(file->buff, file->buffsz, format, args); + va_end(args); + + /* Unambiguous Success */ + if ((len > -1) && (len < file->buffsz)) + break; + + /* First case: C99 behaviour. Len is correctly sized. + * add space for null terminator. Next time through the + * loop we're guaranteed success. + * + * Second case: SUS (and Windows) behaviour. We know it + * doesn't fit, but we don't know how big it has to be. +` * double it and try again. We'll loop until we succeed. + * + * Since we keep the I/O buffer in the file handle, we + * quickly reach a steady state on the size of these buffers. + */ + if (len > -1) + file->buffsz = len + 1; + else + file->buffsz *= 2; + + file->buff = xrealloc(file->buff, file->buffsz); + } + return gbfwrite(file->buff, 1, len, file); +} + +/* + * gbfprintf: (as fprintf) + */ + +int +gbfprintf(gbfile *file, const char *format, ...) +{ + va_list args; + int result; + + va_start(args, format); + result = gbvfprintf(file, format, args); + va_end(args); + + return result; +} + +/* + * gbfputc: (as fputc) + */ + +int +gbfputc(int c, gbfile *file) +{ + unsigned char temp = (unsigned int) c; + + gbfwrite(&temp, 1, 1, file); + + return c; +} + +/* + * gbfputs: (as fputs) + */ + +int +gbfputs(const char *s, gbfile *file) +{ + return gbfwrite(s, 1, strlen(s), file); +} + +/* + * gbfwrite: (as fwrite) + */ + +int +gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) +{ + int result; + + if ((size == 0) || (members == 0)) return 0; + + if (file->gzapi) { +#if !ZLIB_INHIBITED + result = gzwrite(file->handle.gz, buf, size * members) / size; +#else + fatal(NO_ZLIB); + return -1; +#endif + } + else { + result = fwrite(buf, size, members, file->handle.std); + } + + if (result != members) { + fatal("%s: Could not write %lld bytes to %s!\n", + file->module, + (long long int) (members - result) * size, + file->name); + } + + return result; +} + +/* + * gbfflush: (as fflush) + */ + +int +gbfflush(gbfile *file) +{ + if (file->gzapi) { +#if !ZLIB_INHIBITED + return gzflush(file->handle.gz, Z_SYNC_FLUSH); +#else + fatal(NO_ZLIB); + return -1; +#endif + } + else { + return fflush(file->handle.std); + } +} + +/* + * gbfclearerr: (as clearerr) + */ + +void +gbfclearerr(gbfile *file) +{ + if (file->gzapi) { +#if !ZLIB_INHIBITED + gzclearerr(file->handle.gz); +#else + fatal(NO_ZLIB); +#endif + } + else { + clearerr(file->handle.std); + } +} + +/* + * gbferror: (as ferror) + */ + +int +gbferror(gbfile *file) +{ + int errnum; + + if (file->gzapi) { +#if !ZLIB_INHIBITED + (void)gzerror(file->handle.gz, &errnum); +#else + fatal(NO_ZLIB); + return -1; +#endif + } + else { + errnum = ferror(file->handle.std); + } + return errnum; +} + +/* + * gbfrewind: (as frewind) + */ + +void +gbfrewind(gbfile *file) +{ + (void) gbfseek(file, 0, SEEK_SET); + gbfclearerr(file); +} + +/* + * gbfseek: (as fseek) + */ + +int +gbfseek(gbfile *file, gbint32 offset, int whence) +{ + int result; + + if (file->gzapi) { + + assert(whence != SEEK_END); + +#if !ZLIB_INHIBITED + if ((whence == SEEK_CUR) && (file->back != -1)) offset--; + result = gzseek(file->handle.gz, offset, whence); + file->back = -1; +#else + result = 1; +#endif + if (result < 0) { + if (strcmp(file->name, "-") == 0) + fatal("%s: This format cannot be used in piped commands!\n", file->module); + fatal("%s: online compression not yet supported for this format!", file->module); + } + return 0; + } + else { + gbsize_t pos = 0; + + if (whence != SEEK_SET) pos = ftell(file->handle.std); + + result = fseek(file->handle.std, offset, whence); + if (result != 0) { + switch (whence) { + case SEEK_CUR: + case SEEK_END: pos = pos + offset; break; + case SEEK_SET: pos = offset; break; + default: + fatal("%s: Unknown seek operation (%d) for file %s!\n", + file->module, whence, file->name); + } + fatal("%s: Unable to set file (%s) to position (%llu)!\n", + file->module, file->name, (long long unsigned) pos); + } + return 0; + } +} + +/* + * gbftell: (as ftell) + */ + +gbsize_t +gbftell(gbfile *file) +{ + gbsize_t result; + + if (file->gzapi) { +#if !ZLIB_INHIBITED + result = gztell(file->handle.gz); + if (file->back != -1) { +// file->back = -1; + result--; + } +#else + fatal(NO_ZLIB); + result = -1; +#endif + } + else { + result = ftell(file->handle.std); + } + if ((signed) result == -1) + fatal("%s: Could not determine position of file '%s'!\n", + file->module, file->name); + return result; +} + +/* + * gbfeof: (as feof) + */ + +int +gbfeof(gbfile *file) +{ + if (file->gzapi) { +#if !ZLIB_INHIBITED + int res; + + if (file->back != -1) return 0; + + res = gzeof(file->handle.gz); + if (!res) { + unsigned char test; + int len = gzread(file->handle.gz, &test, 1); + if (len == 1) { + /* No EOF, put the single byte back into stream */ + file->back = test; + } + else { + /* we are at the end of the file */ + if (global_opts.debug_level > 0) { + /* now gzeof() should return 1 */ + is_fatal(!gzeof(file->handle.gz), "zlib gzeof error!\n"); + } + res = 1; + } + } + return res; +#else + fatal(NO_ZLIB); + return 0; +#endif + } + else { + return feof(file->handle.std); + } +} + +/* + * gbfungetc: (as fungetc) + */ + +int +gbfungetc(const int c, gbfile *file) +{ + int res; + + if (file->gzapi) { +#if !ZLIB_INHIBITED + if (file->back == -1) { + file->back = c; + res = c; + } + else { + fatal(MYNAME ": Cannot store more than one byte back!\n"); + } +#else + fatal(NO_ZLIB); +#endif + } + else { + res = ungetc(c, file->handle.std); + } + return res; +} + +/* GPSBabel 'file' enhancements */ + +/* + * gbfgetint32: read a signed 32-bit integer from input stream + */ + +gbint32 +gbfgetint32(gbfile *file) +{ + char buf[4]; + + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); + + if (file->big_endian) + return be_read32(buf); + else + return le_read32(buf); +} + +/* + * gbfgetint16: read a signed 16-bit integer from input stream + */ + +gbint16 +gbfgetint16(gbfile *file) +{ + char buf[2]; + + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); + + if (file->big_endian) + return be_read16(buf); + else + return le_read16(buf); +} + +/* + * gbfgetdbl: read a double value (8 byte, double precision) from input stream + */ + +double +gbfgetdbl(gbfile *file) +{ + char buf[8]; + + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); + + return endian_read_double(buf, ! file->big_endian); +} + +/* + * gbfgetflt: read a float value (4 byte, single precision) from input stream + */ + +float +gbfgetflt(gbfile *file) +{ + char buf[4]; + + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); + + return endian_read_float(buf, ! file->big_endian); +} + +/* + * gbfgetcstr: Reads a string from file until either a '\0' or eof. + * The result is a temporary allocated entity: use it or free it! + */ + +char * +gbfgetcstr(gbfile *file) +{ + char *result; + int len = 0; + char *str = file->buff; + + for (;;) { + char c = gbfgetc(file); + + if ((c == 0) || (c == EOF)) break; + + if (len == file->buffsz) { + file->buffsz += 64; + str = file->buff = xrealloc(file->buff, file->buffsz + 1); + } + str[len] = c; + len++; + } + + result = (char *) xmalloc(len + 1); + if (len > 0) + memcpy(result, str, len); + result[len] = '\0'; + + return result; +} + +/* + * gbfgetpstr: Reads a pascal string (first byte is length) from file. + * The result is a temporary allocated entity: use it or free it! + */ + +char * +gbfgetpstr(gbfile *file) +{ + int len; + char *result; + + len = gbfgetc(file); + result = xmalloc(len + 1); + if (len > 0) { + gbfread(result, 1, len, file); + } + result[len] = '\0'; + + return result; +} + +/* + * gbfgetstr: Reads a string from file (util any type of line-breaks or eof or error) + * except xfree and free you can do all possible things with the result + */ + +char * +gbfgetstr(gbfile *file) +{ + int len = 0; + char *result = file->line; + + for (;;) { + char c = gbfgetc(file); + + if ((c == EOF) || (c == 0x1A)) { + if (len == 0) { + return NULL; + } + break; + } + else if (c == '\r') { + c = gbfgetc(file); + if ((c != '\n') && (c != EOF)) + gbfungetc(c, file); + break; + } + else if (c == '\n') { + break; + } + if (len == file->linesz) { + file->linesz += 64; + result = file->line = xrealloc(file->line, file->linesz + 1); + } + result[len] = c; + len++; + } + result[len] = '\0'; // terminate resulting string + + return result; +} + +/* + * gbfputint16: write a signed 16-bit integer value into output stream + */ + +int +gbfputint16(const gbint16 i, gbfile *file) +{ + char buf[2]; + + if (file->big_endian) + be_write16(buf, i); + else + le_write16(buf, i); + return gbfwrite(buf, 1, sizeof(buf), file); +} + +/* + * gbfputint32: write a signed 32-bit integer value into output stream + */ + +int +gbfputint32(const gbint32 i, gbfile *file) +{ + char buf[4]; + + if (file->big_endian) + be_write32(buf, i); + else + le_write32(buf, i); + return gbfwrite(buf, 1, sizeof(buf), file); +} + +/* + * gbfputdbl: write a double value (8 byte, double precision) into output stream + */ + +int +gbfputdbl(const double d, gbfile *file) +{ + char buf[8]; + + endian_write_double(buf, d, ! file->big_endian); + return gbfwrite(buf, 1, sizeof(buf), file); +} + +/* + * gbfputflt: write a float value (4 byte, single precision) into output stream + */ + +int +gbfputflt(const float f, gbfile *file) +{ + char buf[4]; + + endian_write_float(buf, f, ! file->big_endian); + return gbfwrite(buf, 1, sizeof(buf), file); +} + +/* + * gbfputcstr: write a NULL terminated string into a stream (!) including NULL + * return the number of written characters + */ + +int +gbfputcstr(const char *s, gbfile *file) +{ + int len; + + len = (s == NULL) ? 0 : strlen(s); + if (len > 0) { + return gbfwrite(s, 1, len + 1, file); + } else { + gbfputc(0, file); + return 1; + } +} + +/* + * gbfputcstr: write a pascal string into a stream + * return the number of written characters + */ + +int +gbfputpstr(const char *s, gbfile *file) +{ + int len; + + len = (s == NULL) ? 0 : strlen(s); + if (len > 255) len = 255; /* the maximum size of a standard pascal string */ + gbfputc(len, file); + if (len > 0) { + gbfwrite(s, 1, len, file); + } + return (len + 1); +} + +/* Thats all, sorry. */ diff --git a/gbfile.h b/gbfile.h new file mode 100644 index 000000000..545ebfc68 --- /dev/null +++ b/gbfile.h @@ -0,0 +1,98 @@ +/* + + Common GPSBabel file I/O API + + Copyright (C) 2006 Olaf Klein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifndef GBFILE_H +#define GBFILE_H + +#include "config.h" +#include "defs.h" +#include + +typedef struct gbfile_s { +#ifdef DEBUG_MEM + void *dummy; /* ZERO pointer for stdio oop's */ +#endif + union { + FILE *std; +#if !ZLIB_INHIBITED + gzFile *gz; +#endif + } handle; + char *name; + char *module; + char *line; + int linesz; + char *buff; /* static growing buffer, primary used by gbprintf */ + int buffsz; + char mode; + int back; + unsigned char big_endian:1; + unsigned char binary:1; + unsigned char gzapi:1; +} gbfile; + + +gbfile *gbfopen(const char *filename, const char *mode, const char *module); +gbfile *gbfopen_be(const char *filename, const char *mode, const char *module); +#define gbfopen_le gbfopen +void gbfclose(gbfile *file); + +gbsize_t gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file); +int gbfgetc(gbfile *file); +char *gbfgets(char *buf, int len, gbfile *file); + +int gbvfprintf(gbfile *file, const char *format, va_list ap); +int gbfprintf(gbfile *file, const char *format, ...); +int gbfputc(int c, gbfile *file); +int gbfputs(const char *s, gbfile *file); +int gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *file); +int gbfflush(gbfile *file); + +void gbfclearerr(gbfile *file); +int gbferror(gbfile *file); +void gbfrewind(gbfile *file); +int gbfseek(gbfile *file, gbint32 offset, int whence); +gbsize_t gbftell(gbfile *file); +int gbfeof(gbfile *file); +int gbfungetc(const int c, gbfile *file); + +gbint32 gbfgetint32(gbfile *file); +#define gbfgetuint32 (gbuint32)gbfgetint32 +gbint16 gbfgetint16(gbfile *file); +#define gbfgetuint16 (gbuint16)gbfgetint16 +double gbfgetdbl(gbfile *file); // read a double value +float gbfgetflt(gbfile *file); // read a float value +char *gbfgetstr(gbfile *file); // read until any type of line-breaks or EOF +char *gbfgetpstr(gbfile *file); // read a pascal string +char *gbfgetcstr(gbfile *file); // read a null terminated string + +int gbfputint16(const gbint16 i, gbfile *file); +#define gbfputuint16(a,b) gbfputint16((gbuint16)(a),(b)) +int gbfputint32(const gbint32 i, gbfile *file); +#define gbfputuint32(a,b) gbfputint32((gbuint32)(a),(b)) + +int gbfputdbl(const double d, gbfile *file); // write a double value +int gbfputflt(const float f, gbfile *file); // write a float value +int gbfputcstr(const char *s, gbfile *file); // write string including '\0' +int gbfputpstr(const char *s, gbfile *file); // write as pascal string + +#endif diff --git a/gbser.c b/gbser.c new file mode 100644 index 000000000..a43777c5a --- /dev/null +++ b/gbser.c @@ -0,0 +1,181 @@ +/* + Serial interface + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "gbser.h" +#include "gbser_private.h" + +#include +#include + +void gbser__db(int l, const char *msg, ...) { + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vprintf(msg, ap); + } + va_end(ap); +} + +/* Set the serial port speed. + */ +int gbser_set_speed(void *handle, unsigned speed) { + return gbser_set_port(handle, speed, 8, 0, 1); +} + +static int parity_letter(char c) { + switch (c) { + case 'N': case 'n': + return 0; + case 'O': case 'o': + return 1; + case 'E': case 'e': + return 2; + default: + return -1; + } +} + +/* Set the serial port up by parsing the supplied parameter string. + * Valid parameter strings look like '4800,8,N,1'. Parsing is case- + * insensitive, spaces are allowed around the commas and omitted + * trailing fields will default to '8', 'N' and '1' + */ +int gbser_setup(void *handle, const char *spec) { + unsigned arg[] = { 4800, 8, 0, 1 }; + int ap; + + for (ap = 0; ap < sizeof(arg) / sizeof(arg[0]); ap++) { + unsigned t = 0; + int pl; + while (isspace(*spec)) { spec++; } + /* Allow 'N', 'O' or 'E' as the parity spec */ + if (ap == 2 && (pl = parity_letter(*spec), pl >= 0)) { + t = pl; + spec++; + } else { + if (!isdigit(*spec)) { break; } + while (isdigit(*spec)) { t = t * 10 + *spec++ - '0'; } + } + arg[ap] = t; + while (isspace(*spec)) { spec++; } + if (*spec != ',') { break; } + spec++; + } + + if (*spec != '\0') { + return gbser_ERROR; + } + + return gbser_set_port(handle, arg[0], arg[1], arg[2], arg[3]); +} + +/* Return true if there are characters available on the serial port + */ +int gbser_avail(void *handle) { + return gbser__fill_buffer(handle, 1, NULL); +} + +/* Read as many bytes as are available without blocking. At most |len| + * bytes will be read. Returns the number of bytes read or gbser_ERROR if an + * error occurs. + */ +int gbser_read(void *handle, void *buf, unsigned len) { + int got = 0; + + while (len > 0) { + int rc = gbser__fill_buffer(handle, len, NULL); + if (rc < 0) { + /* error */ + return rc; + } else if (rc == 0) { + /* nothing available */ + break; + } + got += gbser__read_buffer(handle, &buf, &len); + } + + return got; +} + +/* Read the specified number of bytes. Block until the requested number + * of bytes have been read or the timeout (in ms) is exceeded. + */ +int gbser_read_wait(void *handle, void *buf, unsigned len, unsigned ms) { + int got = 0; + + while (len > 0 && ms != 0) { + int rc; + if (rc = gbser__fill_buffer(handle, len, &ms), rc < 0) { + return rc; + } + got += gbser__read_buffer(handle, &buf, &len); + } + + return got; +} + +/* Read a single character from the port, returning immediately if + * none are available. + */ +int gbser_readc(void *handle) { + unsigned char buf; + int rc; + + rc = gbser_read(handle, &buf, 1); + if (rc > 0) { + return buf; + } else if (rc == 0) { + return gbser_NOTHING; + } else { + return gbser_ERROR; + } +} + +/* Read a single character from the port, waiting up to |ms| + * milliseconds for a character to be available. + */ +int gbser_readc_wait(void *handle, unsigned ms) { + unsigned char buf; + int rc; + + rc = gbser_read_wait(handle, &buf, 1, ms); + if (rc > 0) { + return buf; + } else if (rc == 0) { + return gbser_NOTHING; + } else { + return gbser_ERROR; + } +} + +/* Write a null terminated string in |str| to the serial + * port. + */ +int gbser_print(void *handle, const char *str) { + return gbser_write(handle, str, (unsigned) strlen(str)); +} + +/* Write a single character to the serial port. + */ +int gbser_writec(void *handle, int c) { + return gbser_write(handle, &c, 1); +} diff --git a/gbser.h b/gbser.h new file mode 100644 index 000000000..550c5313d --- /dev/null +++ b/gbser.h @@ -0,0 +1,137 @@ +/* + OS Abstraction for serial interface. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifndef __GBSER_H +#define __GBSER_H + +#define gbser_OK 0 +#define gbser_NOTHING -1 +#define gbser_TIMEOUT -2 +#define gbser_ERROR -3 + +#if defined(__WIN32__) || defined(__CYGWIN__) +#define WINSERIAL 1 +#else +#define POSIXSERIAL 1 +#endif + +/* Open a serial port. |port_name| is the (platform specific) name + * of the serial device to open. Under WIN32 familiar DOS port names + * ('com1:') are translated into the equivalent name required by + * WIN32 + */ +void *gbser_init(const char *port_name); + +/* Close a serial port + */ +void gbser_deinit(void *handle); + +/* Set the serial port speed. + */ +int gbser_set_speed(void *handle, unsigned speed); + +/* Set the serial port speed, start, parity and stop bits */ +int gbser_set_port(void *handle, unsigned speed, + unsigned bits, + unsigned parity, + unsigned stop); + +/* Set the serial port up by parsing the supplied parameter string. + * Valid parameter strings look like '4800,8,N,1'. Parsing is case- + * insensitive, spaces are allowed around the commas and omitted + * trailing fields will default to '8', 'N' and '1' + */ +int gbser_setup(void *handle, const char *spec); + +/* Return true if there are characters available on the serial port + */ +int gbser_avail(void *handle); + +/* Read as many bytes as are available without blocking. At most |len| + * bytes will be read. Returns the number of bytes read or gbser_ERROR if an + * error occurs. + */ +int gbser_read(void *handle, void *buf, unsigned len); + +/* Read the specified number of bytes. Block until the requested number + * of bytes have been read or the timeout (in ms) is exceeded. + */ +int gbser_read_wait(void *handle, void *buf, unsigned len, unsigned ms); + +/* Read from the serial port until the specified |eol| character is + * found. Any character matching |discard| will be discarded. To + * read lines terminated by 0x0A0x0D discarding linefeeds use + * gbser_read_line(h, buf, len, 1000, 0x0D, 0x0A); + */ +int gbser_read_line(void *handle, void *buf, + unsigned len, unsigned ms, + int eol, int discard); + +/* Read a single character from the port, returning immediately if + * none are available. TODO: Define return values + */ +int gbser_readc(void *handle); + +/* Read a single character from the port, waiting up to |ms| + * milliseconds for a character to be available. + */ +int gbser_readc_wait(void *handle, unsigned ms); + +/* Discard any pending input on the serial port. + */ +int gbser_flush(void *handle); + +/* Write |len| bytes from |buf| to the serial port. + */ +int gbser_write(void *handle, const void *buf, unsigned len); + +/* Write a null terminated string in |str| to the serial + * port. + */ +int gbser_print(void *handle, const char *str); + +/* Write a single character to the serial port. + */ +int gbset_writec(void *handle, int c); + +/* Return true if a port name seems to refer to a serial port. + * On Windows this tests the filename (against the regex + * /^(\\\\\.\\\\)?com\d+:?$/i). On Posix it returns the value of + * isatty() + */ +int gbser_is_serial(const char *port_name); + +/* This isn't part of the above abstraction; it's just a helper for + * the other serial modules in the tree. + * + * Windows does a weird thing with serial ports. + * COM ports 1 - 9 are "COM1:" through "COM9:" + * The one after that is \\.\\com10 - this function tries to plaster over + * that. + * It returns a pointer to a staticly allocated buffer and is therefore not + * thread safe. The buffer pointed to remains valid only until the next + * call to this function. + */ + +const char *fix_win_serial_name_r(const char *comname, char *obuf, size_t len); +const char *fix_win_serial_name(const char *comname); + +#endif /* GBSER_H */ diff --git a/gbser_posix.c b/gbser_posix.c new file mode 100644 index 000000000..4667ffce3 --- /dev/null +++ b/gbser_posix.c @@ -0,0 +1,438 @@ +/* + Serial interface for POSIX tty handling. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "gbser.h" +#include "gbser_private.h" + +#include +#include +#include +#include +#include + +#include +#include + +typedef struct { + struct termios old_tio; + struct termios new_tio; + int fd; + unsigned vmin, vtime; + unsigned long magic; + + unsigned char inbuf[BUFSIZE]; + unsigned inbuf_used; +} gbser_handle; + +/* Wrapper to safely cast a void * into a gbser_handle */ +static gbser_handle *gbser__get_handle(void *p) { + gbser_handle *h = (gbser_handle *) p; + assert(h->magic == MYMAGIC); + return h; +} + +static speed_t mkspeed(unsigned br) { + switch (br) { + case 1200: return B1200; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; + case 38400: return B38400; +#if defined B57600 + case 57600: return B57600; +#endif +#if defined B115200 + case 115200: return B115200; +#endif + default: + fatal("Unsupported serial speed: %d\n", br); + return 0; /* keep compiler happy */ + } +} + +typedef struct timeval hp_time; + +static void get_time(hp_time *tv) { + gettimeofday(tv, NULL); +} + +static double elapsed(hp_time *tv) { + hp_time now; + double ot = (double) tv->tv_sec * 1000 + + (double) tv->tv_usec / 1000; + double nt; + gettimeofday(&now, NULL); + nt = (double) now.tv_sec * 1000 + + (double) now.tv_usec / 1000; + /*printf("elapsed -> %f\n", nt - ot);*/ + return nt - ot; +} + +static int set_rx_timeout(gbser_handle *h, unsigned vmin, unsigned vtime) { + if (vmin > 255) { vmin = 255; } + if (vtime > 255) { vtime = 255; } + if (vmin != h->vmin || vtime != h->vtime) { + h->vmin = h->new_tio.c_cc[VMIN] = vmin; + h->vtime = h->new_tio.c_cc[VTIME] = vtime; + + /*printf("VMIN=%d, VTIME=%d\n", h->vmin, h->vtime);*/ + + return tcsetattr(h->fd, TCSANOW, &h->new_tio) ? gbser_ERROR : gbser_OK; + } else { + return 0; + } +} + +/* Open a serial port. |port_name| is the (platform specific) name + * of the serial device to open. Under WIN32 familiar DOS port names + * ('com1:') are translated into the equivalent name required by + * WIN32 + */ +void *gbser_init(const char *port_name) { + gbser_handle *h; + + gbser__db(4, "gbser_init(\"%s\")\n", port_name); + + h = xcalloc(sizeof *h, 1); + h->magic = MYMAGIC; + h->vmin = h->vtime = 0; + + if (0 == strcmp(port_name, "-")) { + h->fd = 0; + return h; + } + else if (h->fd = open(port_name, O_RDWR | O_NOCTTY), h->fd == -1) { + gbser__db(1, "Failed to open port (%s)\n", strerror(errno)); + goto failed; + } + + if (!isatty(h->fd)) { + gbser__db(1, "%s is not a TTY\n"); + goto failed; + } + + if (gbser_set_port(h, 4800, 8, 0, 1)) { + gbser__db(1, "gbser_set_port() failed\n"); + goto failed; + } + + return h; + +failed: + if (h->fd != -1) { + close(h->fd); + } + + xfree(h); + + return NULL; +} + +/* Close a serial port + */ +void gbser_deinit(void *handle) { + gbser_handle *h = gbser__get_handle(handle); + + tcsetattr(h->fd, TCSAFLUSH, &h->old_tio); + close(h->fd); + + xfree(h); +} + +int gbser_set_port(void *handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) { + gbser_handle *h = gbser__get_handle(handle); + speed_t s; + + static unsigned bit_flags[] = { + 0, 0, 0, 0, 0, CS5, CS6, CS7, CS8 + }; + + if (bits < 5 || bits > 8) { + fatal("Unsupported bits setting: %d\n", bits); + } + + if (parity > 2) { + fatal("Unsupported parity setting: %d\n", parity); + } + + if (stop < 1 || stop > 2) { + fatal("Unsupported stop setting: %d\n", stop); + } + + s = mkspeed(speed); + + /* TODO: We don't /fully/ initialise the port's stat here... */ + + tcgetattr(h->fd, &h->old_tio); + + h->new_tio = h->old_tio; + + /* clear bits */ +// cfmakeraw(&h->new_tio); + h->new_tio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + h->new_tio.c_oflag &= ~OPOST; + h->new_tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + h->new_tio.c_cflag &= ~(CSIZE|PARENB); + h->new_tio.c_cflag |= CS8; + + h->new_tio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | + INLCR | IGNCR | IXON); + h->new_tio.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); + + /* set data bits, */ + h->new_tio.c_cflag |= bit_flags[bits]; + + /* stop bits and... */ + if (stop == 2) { + h->new_tio.c_cflag |= CSTOPB; + } + + /* parity */ + if (parity != 0) { + h->new_tio.c_cflag |= PARENB; + if (parity == 1) { + h->new_tio.c_cflag |= PARODD; + } + } + + h->new_tio.c_oflag = 0; + h->new_tio.c_lflag = 0; + + h->new_tio.c_cc[VMIN] = h->vmin; + h->new_tio.c_cc[VTIME] = h->vtime; + + cfsetospeed(&h->new_tio, s); + cfsetispeed(&h->new_tio, s); + + return tcsetattr(h->fd, TCSADRAIN, &h->new_tio) ? gbser_ERROR : gbser_OK; +} + +unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { + gbser_handle *h = gbser__get_handle(handle); + unsigned count = *len; + unsigned char *cp = *buf; + if (count > h->inbuf_used) { + count = h->inbuf_used; + } + + memcpy(cp, h->inbuf, count); + memmove(h->inbuf, h->inbuf + count, + h->inbuf_used - count); + h->inbuf_used -= count; + *len -= count; + cp += count; + *buf = (void *) cp; + return count; +} + +/* Return when the input buffer contains at least |want| bytes or |*ms| + * milliseconds have elapsed. |ms| may be NULL or |*ms| may be zero to + * poll the port for available bytes and return immediately. |*ms| will + * be updated to indicate the remaining time on exit. + * Returns the number of bytes available (>=0) or an error code (<0). + */ +int gbser__fill_buffer(void *handle, unsigned want, unsigned *ms) { + int rc; + gbser_handle *h = gbser__get_handle(handle); + + if (want > BUFSIZE) { + want = BUFSIZE; + } + + /* Already got enough bytes? */ + if (h->inbuf_used >= want) { + return h->inbuf_used; + } + + if (NULL == ms || 0 == *ms) { + if ((rc = set_rx_timeout(h, 0, 0), rc < 0) || + (rc = read(h->fd, h->inbuf + h->inbuf_used, + want - h->inbuf_used), rc < 0)) { + return gbser_ERROR; + } + h->inbuf_used += rc; + /*printf("Got %d bytes\n", rc);*/ + } else { + double time_left = *ms; + hp_time tv; + get_time(&tv); + + for (;;) { + fd_set rec; + struct timeval t; + + time_left = *ms - elapsed(&tv); + if (time_left <= 0 || h->inbuf_used >= want) { + break; + } + + FD_ZERO(&rec); + FD_SET(h->fd, &rec); + + t.tv_sec = (time_t) time_left / 1000; + t.tv_usec = ((unsigned) time_left % 1000) * 1000; + + if (select(h->fd + 1, &rec, NULL, NULL, &t) < 0) { + return gbser_ERROR; + } + + time_left = *ms - elapsed(&tv); + + if (FD_ISSET(h->fd, &rec)) { + unsigned vmin = 0, vtime = 0; + if (time_left >= 100) { + vmin = want - h->inbuf_used; + vtime = (unsigned) time_left / 100; + } + // The commented out call to set_rx_timeout here is totally + // legal by POSIX standards but does result in a flurry of + // of tcsetattrs that slightly tweak VMIN/VTIME while there + // is incoming data. This has been shown to trigger driver + // bugs in the Prolific drivers for Mac and in certain Linux + // kernels, thought the latter has since been fixed. + // So althogh removing this means that the timeout behaviour + // is actually different on POSIX and WIN32, it triggers + // fewer buts this way. 2/12/2008 RJL + if (/* (rc = set_rx_timeout(h, vmin, vtime), rc < 0) || */ + (rc = read(h->fd, h->inbuf + h->inbuf_used, + want - h->inbuf_used), rc < 0)) { + return gbser_ERROR; + } + h->inbuf_used += rc; + /*printf("Got %d bytes\n", rc);*/ + } + } + *ms = (time_left < 0) ? 0 : time_left; + } + + return h->inbuf_used; +} + +/* Discard any pending input on the serial port. + */ +int gbser_flush(void *handle) { + gbser_handle *h = gbser__get_handle(handle); + h->inbuf_used = 0; + if (tcflush(h->fd, TCIFLUSH)) { + return gbser_ERROR; + } + + return gbser_OK; +} + +/* Write |len| bytes from |buf| to the serial port. + */ +int gbser_write(void *handle, const void *buf, unsigned len) { + gbser_handle *h = gbser__get_handle(handle); + const char *bp = buf; + int rc; + while (len > 0) { + /*printf("write(%d, %p, %d)\n", h->fd, bp, len);*/ + if (rc = write(h->fd, bp, len), rc < 0) { + printf("rc = %d, errno = %d (%s)\n", rc, errno, strerror(errno)); + return gbser_ERROR; + } + len -= rc; + bp += rc; + } + return gbser_OK; +} + +/* Return true if a port name seems to refer to a serial port. + * On Windows this tests the filename (against the regex + * /^(\\\\\.\\\\)?com\d+:?$/i). On Posix it returns the value of + * isatty() + */ + +int gbser_is_serial(const char *port_name) { + int fd; + int is_port = 0; + + if (fd = open(port_name, O_RDWR | O_NOCTTY), fd == -1) { + gbser__db(1, "Failed to open port (%s) to check its type\n", strerror(errno)); + return 0; + } + + is_port = isatty(fd); + + close(fd); + + return is_port; +} + +/* This isn't part of the above abstraction; it's just a helper for + * the other serial modules in the tree. + * + * Windows does a weird thing with serial ports. + * COM ports 1 - 9 are "COM1:" through "COM9:" + * The one after that is \\.\\com10 - this function tries to plaster over + * that. + * It returns a pointer to a staticly allocated buffer and is therefore not + * thread safe. The buffer pointed to remains valid only until the next + * call to this function. + */ + +const char *fix_win_serial_name_r(const char *comname, char *obuf, size_t len) { + strncpy(obuf, comname, len); + return obuf; +} + +static char gb_com_buffer[100]; + +const char *fix_win_serial_name(const char *comname) { + return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); +} + +/* Read from the serial port until the specified |eol| character is + * found. Any character matching |discard| will be discarded. To + * read lines terminated by 0x0A, 0x0D discarding linefeeds use + * gbser_read_line(h, buf, len, 1000, 0x0D, 0x0A); + * The terminating character and any discarded characters are not + * stored in the buffer. + */ +int gbser_read_line(void *handle, void *buf, unsigned len, unsigned ms, int eol, int discard) { + char *bp = buf; + unsigned pos = 0; + hp_time tv; + get_time(&tv); + bp[pos] = '\0'; + for (;;) { + signed time_left = ms - elapsed(&tv); + int c; + + if (time_left <= 0) { + return gbser_TIMEOUT; + } + c = gbser_readc_wait(handle, time_left); + if (c == gbser_ERROR) { + return c; + } else if (c == eol) { + return gbser_OK; + } + if (c != gbser_NOTHING && c != discard && pos < len - 1) { + bp[pos++] = c; + bp[pos] = '\0'; + } + } +} diff --git a/gbser_private.h b/gbser_private.h new file mode 100644 index 000000000..318455e80 --- /dev/null +++ b/gbser_private.h @@ -0,0 +1,27 @@ +/* + Serial interface - private header for gbser*.c + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#define MYMAGIC 0x91827364 +#define BUFSIZE 512 + +void gbser__db(int l, const char *msg, ...); +int gbser__fill_buffer(void *h, unsigned want, unsigned *ms); +unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len); diff --git a/gbser_win.c b/gbser_win.c new file mode 100644 index 000000000..c1a05269c --- /dev/null +++ b/gbser_win.c @@ -0,0 +1,430 @@ +/* + Serial interface - Windows layer. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "gbser.h" +#include "gbser_private.h" + +#include +#include + +#include +#include + +typedef struct { + HANDLE comport; + DWORD timeout; + unsigned long magic; + + unsigned char inbuf[BUFSIZE]; + unsigned inbuf_used; +} gbser_handle; + +#define DEV_PREFIX "\\\\.\\\\" + +/* Wrapper to safely cast a void * into a gbser_handle */ +static gbser_handle *gbser__get_handle(void *p) { + gbser_handle *h = (gbser_handle *) p; + assert(h->magic == MYMAGIC); + return h; +} + +static DWORD mkspeed(unsigned br) { + switch (br) { + case 1200: return CBR_1200; + case 2400: return CBR_2400; + case 4800: return CBR_4800; + case 9600: return CBR_9600; + case 19200: return CBR_19200; + case 38400: return CBR_38400; + case 57600: return CBR_57600; + case 115200: return CBR_115200; + default: + fatal("Unsupported serial speed: %d\n", br); + return 0; /* keep compiler happy */ + } +} + +typedef LARGE_INTEGER hp_time; + +static void get_time(hp_time *tv) { + QueryPerformanceCounter(tv); +} + +static double elapsed(hp_time *tv) { + hp_time now; + LARGE_INTEGER tps; + + QueryPerformanceFrequency(&tps); + QueryPerformanceCounter(&now); + + return ((double) (now.QuadPart - tv->QuadPart) / + (double) tps.QuadPart) * 1000; +} + +static int set_rx_timeout(gbser_handle *h, DWORD timeout) { + if (timeout != h->timeout) { + COMMTIMEOUTS to; + + if (!GetCommTimeouts(h->comport, &to)) { + return gbser_ERROR; + } + + to.ReadIntervalTimeout = timeout; + to.ReadTotalTimeoutMultiplier = 0; + to.ReadTotalTimeoutConstant = timeout; + to.WriteTotalTimeoutMultiplier = 0; + to.WriteTotalTimeoutConstant = 0; + + if (!SetCommTimeouts(h->comport, &to)) { + return gbser_ERROR; + } else { + h->timeout = timeout; + return gbser_OK; + } + } else { + return gbser_OK; + } +} + +/* This isn't part of the above abstraction; it's just a helper for + * the other serial modules in the tree. + * + * Windows does a weird thing with serial ports. + * COM ports 1 - 9 are "COM1:" through "COM9:" + * The one after that is \\.\\com10 - this function tries to plaster over + * that. + * + * Worse still, Win98 and ME fail the open if you rename com1 to be \\.\\com1: + * + * It returns a pointer to a staticly allocated buffer and is therefore not + * thread safe. The buffer pointed to remains valid only until the next + * call to this function. + */ + +const char * +fix_win_serial_name_r(const char *comname, char *obuf, size_t len) +{ + if (!gbser_is_serial(comname) || + ((strlen(comname) == 5) && (comname[4] == ':')) || + ((strlen(comname) == 4) && (case_ignore_strncmp(comname, "com", 3) == 0)) + ) { + strncpy(obuf, comname, len); + } else { + size_t l; + snprintf(obuf, len, DEV_PREFIX "%s", comname); + l = strlen(obuf); + if (obuf[l - 1] == ':') { + obuf[l - 1] = '\0'; + } + } + + return obuf; +} + +static char gb_com_buffer[100]; + +const char *fix_win_serial_name(const char *comname) +{ + return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); +} + +/* Open a serial port. |port_name| is the (platform specific) name + * of the serial device to open. Under WIN32 familiar DOS port names + * ('com1:') are translated into the equivalent name required by + * WIN32 + */ +void *gbser_init(const char *port_name) +{ + HANDLE comport; + gbser_handle* h = xcalloc(1, sizeof(*h)); + const char *xname = fix_win_serial_name(port_name); + + gbser__db(2, "Translated port name: \"%s\"\n", xname); + + h->magic = MYMAGIC; + + comport = CreateFile(xname, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + + if (comport == INVALID_HANDLE_VALUE) { + goto failed; + } + + h->comport = comport; + h->timeout = 1; + if (gbser_set_port(h, 4800, 8, 0, 1) || set_rx_timeout(h, 0)) { + goto failed; + } + + return h; + +failed: + if (comport) { + CloseHandle(h->comport); + } + xfree(h); + + return NULL; +} + +/* Close a serial port + */ +void gbser_deinit(void *handle) { + gbser_handle *h = gbser__get_handle(handle); + + CloseHandle(h->comport); + + xfree(h); +} + +int gbser_set_port(void *handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) { + gbser_handle *h = gbser__get_handle(handle); + DCB tio; + + if (bits < 5 || bits > 8) { + fatal("Unsupported bits setting: %d\n", bits); + } + + if (parity > 2) { + fatal("Unsupported parity setting: %d\n", parity); + } + + if (stop < 1 || stop > 2) { + fatal("Unsupported stop setting: %d\n", stop); + } + + tio.DCBlength = sizeof(DCB); + GetCommState(h->comport, &tio); + + tio.BaudRate = mkspeed(speed); + tio.fBinary = TRUE; + tio.fParity = TRUE; + tio.fOutxCtsFlow = FALSE; + tio.fOutxDsrFlow = FALSE; + tio.fDtrControl = DTR_CONTROL_ENABLE; + tio.fDsrSensitivity = FALSE; + tio.fTXContinueOnXoff = TRUE; + tio.fOutX = FALSE; + tio.fInX = FALSE; + tio.fErrorChar = FALSE; + tio.fNull = FALSE; + tio.fRtsControl = RTS_CONTROL_ENABLE; + tio.fAbortOnError = FALSE; + tio.ByteSize = bits; + tio.Parity = parity == 0 ? NOPARITY : + (parity == 1 ? ODDPARITY : EVENPARITY); + tio.StopBits = stop == 1 ? ONESTOPBIT : TWOSTOPBITS; + + if (!SetCommState(h->comport, &tio)) { + return gbser_ERROR; + } + return gbser_OK; +} + +unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { + gbser_handle *h = gbser__get_handle(handle); + unsigned count = *len; + unsigned char *cp = *buf; + if (count > h->inbuf_used) { + count = h->inbuf_used; + } + + memcpy(cp, h->inbuf, count); + memmove(h->inbuf, h->inbuf + count, + h->inbuf_used - count); + h->inbuf_used -= count; + *len -= count; + cp += count; + *buf = (void *) cp; + return count; +} + +/* Return when the input buffer contains at least |want| bytes or |*ms| + * milliseconds have elapsed. |ms| may be NULL or |*ms| may be zero to + * poll the port for available bytes and return immediately. |*ms| will + * be updated to indicate the remaining time on exit. + * Returns the number of bytes available (>=0) or an error code (<0). + */ +int gbser__fill_buffer(void *handle, unsigned want, unsigned *ms) { + int rc; + gbser_handle *h = gbser__get_handle(handle); + + if (want > BUFSIZE) { + want = BUFSIZE; + } + + /* Already got enough bytes? */ + if (h->inbuf_used >= want) { + return h->inbuf_used; + } + + if (NULL == ms || 0 == *ms) { + DWORD err, nread; + COMSTAT stat; + ClearCommError(h->comport, &err, &stat); + if (stat.cbInQue > 0) { + DWORD count = want - h->inbuf_used; + if (count > stat.cbInQue) { + count = stat.cbInQue; + } + if (rc = set_rx_timeout(h, 1), rc) { + return rc; + } + if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, + count, &nread, NULL)) { + err = GetLastError(); + if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { + return gbser_ERROR; + } + } + h->inbuf_used += nread; + } + } else { + hp_time tv; + double time_left; + DWORD err, nread; + get_time(&tv); + if (rc = set_rx_timeout(h, *ms), rc) { + return rc; + } + if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, + want - h->inbuf_used, + &nread, NULL)) { + err = GetLastError(); + if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { + return gbser_ERROR; + } + } + h->inbuf_used += nread; + time_left = *ms - elapsed(&tv); + *ms = time_left < 0 ? 0 : (unsigned) time_left; + } + + return h->inbuf_used; +} + +/* Discard any pending input on the serial port. + */ +int gbser_flush(void *handle) { + gbser_handle *h = gbser__get_handle(handle); + h->inbuf_used = 0; + if (!PurgeComm(h->comport, PURGE_RXCLEAR)) { + return gbser_ERROR; + } + return gbser_OK; +} + +/* Write |len| bytes from |buf| to the serial port. + */ +int gbser_write(void *handle, const void *buf, unsigned len) { + gbser_handle *h = gbser__get_handle(handle); + DWORD nwritten; + const char *bp = buf; + /* Not sure we need to spin here - but this'll work even if we don't */ + while (len > 0) { + if (!WriteFile(h->comport, bp, len, &nwritten, NULL)) { + return gbser_ERROR; + } + len -= nwritten; + bp += nwritten; + } + return gbser_OK; +} + +/* Return true if a port name seems to refer to a serial port. + * On Windows this tests the filename (against the regex + * /^(\\\\\.\\\\)?com\d+:?$/i). On Posix it returns the value of + * isatty() + */ + +int gbser_is_serial(const char *port_name) { + const char *pfx = DEV_PREFIX; + size_t pfx_l = strlen(pfx); + const char *com = "COM"; + size_t com_l = strlen(com); + unsigned digits; + + if (NULL == port_name) { + return 0; + } + + /* Skip any prefix */ + if (memcmp(port_name, pfx, pfx_l) == 0) { + port_name += pfx_l; + } + + if (case_ignore_strncmp(port_name, com, com_l) != 0) { + return 0; + } + + port_name += com_l; + for (digits = 0; isdigit(*port_name); port_name++, digits++) { + /* do nothing */ + } + + if (digits == 0) { + return 0; + } + + if (*port_name == ':') { + port_name++; + } + + if (*port_name != '\0') { + return 0; + } + + /* Success! */ + return 1; +} + +/* Read from the serial port until the specified |eol| character is + * found. Any character matching |discard| will be discarded. To + * read lines terminated by 0x0A0x0D discarding linefeeds use + * gbser_read_line(h, buf, len, 1000, 0x0D, 0x0A); + */ +int gbser_read_line(void *handle, void *buf, + unsigned len, unsigned ms, + int eol, int discard) { + char *bp = buf; + unsigned pos = 0; + hp_time tv; + get_time(&tv); + bp[pos] = '\0'; + for (;;) { + signed time_left = ms - elapsed(&tv); + int c; + if (time_left <= 0) { + return gbser_TIMEOUT; + } + c = gbser_readc_wait(handle, time_left); + if (c == gbser_ERROR) { + return c; + } else if (c == eol) { + return gbser_OK; + } + if (c != gbser_NOTHING && c != discard && pos < len - 1) { + bp[pos++] = c; + bp[pos] = '\0'; + } + } +} diff --git a/gbsleep.c b/gbsleep.c new file mode 100644 index 000000000..a4b9ed6be --- /dev/null +++ b/gbsleep.c @@ -0,0 +1,51 @@ +/* + OS abstraction to sleep a given number of milliseconds. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "config.h" + +#if __WIN32__ + +#include +void +gb_sleep(unsigned long microseconds) +{ + Sleep(microseconds/1000 + 1); +} + +#elif defined HAVE_NANOSLEEP + +#include +void +gb_sleep(unsigned long microseconds) +{ + struct timespec req; + req.tv_sec = microseconds / 1000000; + req.tv_nsec = (microseconds * 1000) % 1000000000; + nanosleep(&req, NULL); +} +#elif defined HAVE_SLEEP +/* Amazingly underachieving, but probably "good enough" */ +#include +void +gb_sleep(unsigned long microseconds) +{ + sleep(microseconds / 1000000); +} +#endif diff --git a/gbtypes.h b/gbtypes.h new file mode 100644 index 000000000..d247648af --- /dev/null +++ b/gbtypes.h @@ -0,0 +1,58 @@ +/* + Abstract fixed size data types. + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifndef gb_types_h_included +#define gb_types_h_included + + +/* + * If this is a problem and any interesting system doesn't have the C99-ism + * of we'll come up with something more clever that'll likely + * include a gross collection of __STDC_VERSION >= 199901L || __GNUC__ + */ + +#if defined(_MSC_VER) + +typedef unsigned long gbuint32; +typedef unsigned short gbuint16; +typedef long gbint32; +typedef short gbint16; + +#else + +# if defined (__FreeBSD__) +# include +# else +# include +# endif + +typedef uint32_t gbuint32; +typedef uint16_t gbuint16; +typedef int32_t gbint32; +typedef int16_t gbint16; + +#endif /* defined(_MSC_VER) */ + +typedef gbuint32 gbsize_t; +typedef unsigned char gbuint8; +typedef signed char gbint8; + +#endif /* gb_types_h_included */ diff --git a/gbversion.h b/gbversion.h new file mode 100644 index 000000000..070161cad --- /dev/null +++ b/gbversion.h @@ -0,0 +1,8 @@ +/* + * gbversion.h is generated from gbversion.h.in which uses autoconf voodoo + * to get the version number from configure.in. + * + * Isn't simplification via automation grand? + */ +#define VERSION "1.3.5" +#define WEB_DOC_DIR "http://www.gpsbabel.org/htmldoc-1.3.5" diff --git a/gbversion.h.in b/gbversion.h.in new file mode 100644 index 000000000..e15e4bb11 --- /dev/null +++ b/gbversion.h.in @@ -0,0 +1,8 @@ +/* + * gbversion.h is generated from gbversion.h.in which uses autoconf voodoo + * to get the version number from configure.in. + * + * Isn't simplification via automation grand? + */ +#define VERSION "@GBMAJOR@.@GBMINOR@.@GBMICRO@@PACKAGE_RELEASE@" +#define WEB_DOC_DIR "http://www.gpsbabel.org/htmldoc-@DOCVERSION@" diff --git a/gcdb.c b/gcdb.c new file mode 100644 index 000000000..0509e6546 --- /dev/null +++ b/gcdb.c @@ -0,0 +1,320 @@ +/* + Read and write GeocachingPDB files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "pdbfile.h" + +#define MYNAME "GeocachingDB" +#define MYTYPE 0x44415441 /* DATA */ +#define MYCREATOR 0x42726174 /* Brat */ + +#define MAXRECSZ 500 /* This is overkill as the records seem to be around 100 + bytes a piece, but being conservative and dealing + with realloc issues just doesn't seem worth it. */ + +typedef enum { + RECTYPE_TEXT = 0, + RECTYPE_DATE = 2 +} gcdb_rectype; + +struct dbfld { + char fldname[4]; + pdb_16 fldtype; + pdb_16 fldlen; +}; + +struct dbrec { + pdb_16 nflds; + struct dbfld dbfld[1]; +}; + +static pdbfile *file_in, *file_out; +static const char *out_fname; +static int ct; + +static char *tbuf = NULL; +static char *tbufp = NULL; + +static void +rd_init(const char *fname) +{ + file_in = pdb_open(fname, MYNAME); +} + +static void +rd_deinit(void) +{ + pdb_close(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; +} + +static void +wr_deinit(void) +{ + pdb_close(file_out); + if ( tbuf ) + xfree(tbuf); +} + +static void +data_read(void) +{ + pdbrec_t *pdb_rec; + + if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { + fatal(MYNAME ": Not a GeocachingDB file.\n"); + } + + for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec=pdb_rec->next) { + waypoint *wpt = waypt_new(); + struct dbrec *rec = (struct dbrec *) pdb_rec->data; + int nflds; + int length; + int type; + int i; + char *recdata; + int lat_dir = 0; + int lat_deg = 0; + float lat_min = 0.0; + int lon_dir = 0; + int lon_deg = 0; + float lon_min = 0.0; + + nflds = be_read16(&rec->nflds); + recdata = (char *) &rec->dbfld[nflds]; + + for (i = 0; i < nflds; i++) { + length = (unsigned short) be_read16(&rec->dbfld[i].fldlen); + type = be_read16(&rec->dbfld[i].fldtype); + + switch(type) { + case RECTYPE_TEXT: /* Text */ + if (!strncmp("gcid", rec->dbfld[i].fldname,4)) { + wpt->shortname = xstrdup(recdata); + } else + if (!strncmp("gcna", rec->dbfld[i].fldname,4)) { + wpt->description = xstrdup(recdata); + } else + if (!strncmp("lat0", rec->dbfld[i].fldname,4)) { + lat_dir = *recdata == 'N' ? 1 : -1; + } else + if (!strncmp("lat1", rec->dbfld[i].fldname,4)) { + lat_deg = atoi(recdata); + } else + if (!strncmp("lat2", rec->dbfld[i].fldname,4)) { + lat_min = atof(recdata); + } + if (!strncmp("lon0", rec->dbfld[i].fldname,4)) { + lon_dir = *recdata == 'E' ? 1 : -1; + } else + if (!strncmp("lon1", rec->dbfld[i].fldname,4)) { + lon_deg = atoi(recdata); + } else + if (!strncmp("lon2", rec->dbfld[i].fldname,4)) { + lon_min = atof(recdata); + } else + if (!strncmp("take", rec->dbfld[i].fldname,4)) { + wpt->notes = xstrappend(wpt->notes, " Took "); + wpt->notes = xstrappend(wpt->notes, recdata); + } else + if (!strncmp("left", rec->dbfld[i].fldname,4)) { + wpt->notes = xstrappend(wpt->notes, " Left "); + wpt->notes = xstrappend(wpt->notes, recdata); + } else + if (!strncmp("diff", rec->dbfld[i].fldname,4)) { + wpt->gc_data.diff = 10 * atof(recdata); + } else + if (!strncmp("terr", rec->dbfld[i].fldname,4)) { + wpt->gc_data.terr = 10 * atof(recdata); + } + break; +#if 0 + /* This really is the date of the find, + * not the cache creation date. + */ + case RECTYPE_DATE: + if (!strncmp("date", rec->dbfld[i].fldname,4)) { + time_t tm; + tm = be_read32(recdata) * 24 * 3600; + tm -= EPOCH_1904; + wpt->creation_time = tm; + warning( "date %d\n", tm); + } + break; +#endif + } + recdata += (length + 1) & (~1); + } + wpt->latitude = lat_dir * (lat_deg + lat_min/60); + wpt->longitude = lon_dir * (lon_deg + lon_min/60); + waypt_add(wpt); + } +} + + +static int +gcdb_add_to_rec(struct dbrec *rec, char *fldname, gcdb_rectype rectype, void *data) +{ + int length; + static int rec_cnt; + + if (!tbuf) { + tbuf = xcalloc(MAXRECSZ, 1); + tbufp = tbuf; + } + + if (fldname == NULL) { + length = tbufp - tbuf; + be_write16(&rec->nflds, rec_cnt); + memcpy(&rec->dbfld[rec_cnt],tbuf, length); + tbufp = tbuf; + length += 4 + sizeof(struct dbfld) * rec_cnt; + rec_cnt = 0; + return length; + } + + be_write16(&rec->dbfld[rec_cnt].fldtype,rectype); + strncpy(rec->dbfld[rec_cnt].fldname, fldname, 4); + + switch (rectype) { + case RECTYPE_TEXT: + length = 1 + strlen(data); + be_write16(&rec->dbfld[rec_cnt].fldlen, length); + strcpy(tbufp, data); + tbufp += (length + 1) & (~1); + break; + case RECTYPE_DATE: + length = 4; + be_write16(&rec->dbfld[rec_cnt].fldlen, length); + be_write32(tbufp, ((time_t)data - EPOCH_1904)/ (3600 * 24)); + tbufp += length; + break; + default: + abort(); + } + rec_cnt++; + + return length; +} + +static void +gcdb_write_wpt(const waypoint *wpt) +{ + struct dbrec *rec; + int reclen; + char tbuf[100]; + + /* + * We don't really know how many fields we'll have or how long + * they'll be so we'll just lazily create a huge place to hold them. + */ + rec = xcalloc(sizeof(*rec) + 500, 1); + + gcdb_add_to_rec(rec, "gcna", RECTYPE_TEXT, wpt->description); + gcdb_add_to_rec(rec, "gcid", RECTYPE_TEXT, wpt->shortname); + + gcdb_add_to_rec(rec, "lat0", RECTYPE_TEXT, + wpt->latitude < 0 ? "S" : "N"); + + sprintf(tbuf, "%d", (int) wpt->latitude); + gcdb_add_to_rec(rec, "lat1", RECTYPE_TEXT, tbuf); + + sprintf(tbuf, "%f", 60 * (wpt->latitude - + (int) wpt->latitude)); + gcdb_add_to_rec(rec, "lat2", RECTYPE_TEXT, tbuf); + + + gcdb_add_to_rec(rec, "lon0", RECTYPE_TEXT, + wpt->longitude < 0 ? "W" : "E"); + + sprintf(tbuf, "%d", (int) wpt->longitude); + gcdb_add_to_rec(rec, "lon1", RECTYPE_TEXT, tbuf); + + sprintf(tbuf, "%f", 60 * (wpt->longitude - + (int) wpt->longitude)); + gcdb_add_to_rec(rec, "lon2", RECTYPE_TEXT, tbuf); + + if (wpt->gc_data.diff) { + sprintf(tbuf, "%f", wpt->gc_data.diff / 10.0); + gcdb_add_to_rec(rec, "diff", RECTYPE_TEXT, tbuf); + } + + if (wpt->gc_data.terr) { + sprintf(tbuf, "%f", wpt->gc_data.terr / 10.0); + gcdb_add_to_rec(rec, "terr", RECTYPE_TEXT, tbuf); + } + +#if 0 + /* This really is the date of the find, + * not the cache creation date. + */ + if (wpt->creation_time) { + gcdb_add_to_rec(rec, "date", RECTYPE_DATE, (void *) wpt->creation_time); + } +#endif + + /* + * We're done. Build the record. + */ + reclen = gcdb_add_to_rec(rec, NULL, 0, NULL); + + pdb_write_rec(file_out, 0, 2, ct++, rec, reclen); + xfree(rec); +} + +static void +data_write(void) +{ + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + strncpy(file_out->name, "GeocachingDB", PDB_DBNAMELEN); + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + + waypt_disp_all(gcdb_write_wpt); +} + + +ff_vecs_t gcdb_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; +#endif diff --git a/gdb.c b/gdb.c new file mode 100644 index 000000000..7893dceec --- /dev/null +++ b/gdb.c @@ -0,0 +1,1734 @@ +/* + Garmin GPS Database Reader/Writer + + Copyright (C) 2005-2008 Olaf Klein, o.b.klein@gpsbabel.org + Mainly based on mapsource.c, + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +/* + History: + + 2005/06/27: initial release (reader only) + 2005/07/26: added write support + 2005/07/27: replaced "tricky code" in route reader + 2005/07/28: fixed handling of single point routes + new option "via" + new option "ver" + fixed compiler warnings + 2005/07/29: fixed compiler warnings + 2005/08/04: Read/write URL (reference data changed) + 2005/08/11: Display sym and name in GDB + 2005/08/12: Neuter proximity and depth for now + 2005/08/29: big CET merge + 2005/09/13: Make sure routes have unique wpt names + 2005/10/10: MSVC fixes from Andrew + 2005/10/17: RJL: Tighten up types of a short handle. It's now a "real" type and not a void * + 2005/10/31: RJL: Add v3 format, min/max, provide defaults, data types, etc + 2005/11/09: RJL: Clarify help text for dropping via points + 2005/12/01: changed waypt's URL to descr for hidden waypoints (-> reference data changed) + removed unused procedure gdb_add_to_hidden + 2005/12/04: additional testo sequences + 2006/02/24: last field of a route is rte url + 2006/02/25: rte_read_loop: zero check replaced with a dummy read (8 unknown bytes) + 2006/03/05: first implementation of Garmin special data (garmin_fs) + 2006/04/04: Use track_add_wpt for all tracks + 2006/04/19: add url i/o to tracks and routes + 2006/04/19: check for empty waypoint shortnames (paranioa) + 2006/11/01: Use version of GPSBabel and date/time of gdb.c (managed by CVS) for watermark + 2007/01/23: add support for GDB version 3 + 2007/02/07: Add special code for unknown bytes in waypoints with class GE 8 (calculated points) + 2007/02/15: Nearly full rewrite. Full support for GDB V3. New option roadbook. + 2007/05/03: Add code for tricky V3 descriptions + 2007/06/18: Tweak some forgotten "flagged" fields + 2007/07/07: Better support for new fields since V3 (postal code/street address/instruction) + 2008/01/09: Fix handling of option category (cat) + 2008/04/27: Add zero to checklist of "unknown bytes" +*/ + +#include +#include +#include +#include + +#include "defs.h" + +#include "cet.h" +#include "cet_util.h" +#include "csv_util.h" +#include "garmin_fs.h" +#include "garmin_tables.h" +#include "grtcirc.h" +#include "jeeps/gpsmath.h" + +#define MYNAME "gdb" + +#define GDB_VER_1 1 +#define GDB_VER_2 2 +#define GDB_VER_3 3 + +#define GDB_VER_UTF8 GDB_VER_3 +#define GDB_VER_MIN GDB_VER_1 +#define GDB_VER_MAX GDB_VER_3 + +#define GDB_DEF_CLASS gt_waypt_class_user_waypoint +#define GDB_DEF_HIDDEN_CLASS gt_waypt_class_map_point +#define GDB_DEF_ICON 18 + +#define GDB_NAME_BUFFERLEN 1024 + +#define GDB_DBG_WPT 1 +#define GDB_DBG_RTE 2 +#define GDB_DBG_TRK 4 + +#define GDB_DBG_WPTe 8 +#define GDB_DBG_RTEe 16 +#define GDB_DBG_TRKe 32 + +#define GDB_DEBUG (GDB_DBG_WPTe) /* | GDB_DBG_RTE) */ +#undef GDB_DEBUG +// #define GDB_DEBUG 0xff + +#define DBG(a,b) if ((GDB_DEBUG & (a)) && (b)) + +/*******************************************************************************/ + +/* static char gdb_release[] = "$Revision: 1.65 $"; */ +static char gdb_release_date[] = "$Date: 2008/05/04 23:09:08 $"; + +static gbfile *fin, *fout; +static int gdb_ver, gdb_category, gdb_via, gdb_roadbook; + +static queue wayptq_in, wayptq_out, wayptq_in_hidden; +static short_handle short_h; + +static char *gdb_opt_category; +static char *gdb_opt_ver; +static char *gdb_opt_via; +static char *gdb_opt_roadbook; +static char *gdb_opt_bitcategory; + +static int waypt_flag; +static int route_flag; + +static int waypt_ct; /* informational: total number of waypoints in/out */ +static int waypth_ct; /* informational: total number of hidden waypoints in/out */ +static int rtept_ct; /* informational: total number of route points in/out */ +static int trkpt_ct; /* informational: total number of track points in/out */ +static int rte_ct; /* informational: total number of routes in/out */ +static int trk_ct; /* informational: total number of tracks in/out */ + +/*******************************************************************************/ + +#define ELEMENTS(a) a->rte_waypt_ct +#define NOT_EMPTY(a) (a && *a) + +static void +gdb_flush_waypt_queue(queue *Q) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(Q, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + dequeue(elem); + if (wpt->extra_data) + xfree(wpt->extra_data); + waypt_free(wpt); + } +} + + +#if GDB_DEBUG +static void +disp_summary(const gbfile *f) +{ + int i, len; + + len = strlen(f->name); + + warning(MYNAME ": ====================="); + for (i = 0; i < len; i++) warning("="); + warning("\n" MYNAME ": %s summary for \"%s\"\n", + (f->mode == 'r') ? "Reader" : "Writer", f->name); + + warning(MYNAME ": ---------------------"); + for (i = 0; i < len; i++) warning("-"); + + warning("\n" MYNAME ": %d waypoint(s)\n", waypt_ct - waypth_ct); + warning(MYNAME ": %d hidden waypoint(s)\n", waypth_ct); + warning(MYNAME ": %d route(s) with total %d point(s)\n", rte_ct, rtept_ct); + warning(MYNAME ": %d track(s) with total %d point(s)\n", trk_ct, trkpt_ct); + warning(MYNAME ": ---------------------"); + + for (i = 0; i < len; i++) warning("-"); + warning("\n"); +} +#else +#define disp_summary(a) +#endif + +/*******************************************************************************/ +/* TOOLS AND MACROS FOR THE READER */ +/*-----------------------------------------------------------------------------*/ + +#define FREAD_C gbfgetc(fin) +#define FREAD(a,b) gbfread(a,(b),1,fin) +#define FREAD_i32 gbfgetint32(fin) +#define FREAD_i16 gbfgetint16(fin) +#define FREAD_STR(a) gdb_fread_str(a,sizeof(a),fin) +#define FREAD_CSTR gdb_fread_cstr(fin) +#define FREAD_DBL gbfgetdbl(fin) +#define FREAD_LATLON GPS_Math_Semi_To_Deg(gbfgetint32(fin)) + +#if GDB_DEBUG +static char * +nice(const char *str) +{ + char *res, *env; + cet_cs_vec_t *vec; + + if (!(str && *str)) return ""; + + env = getenv("LANG"); + if (env == NULL) return (char *)str; + + if ((res = strchr(env, '.'))) env = ++res; + vec = cet_find_cs_by_name(env); + + if ((vec != NULL) && (vec != global_opts.charset)) { + static char buf[128]; + res = cet_str_any_to_any(str, global_opts.charset, vec); + strncpy(buf, res, sizeof(buf)); + xfree(res); + return buf; + } + else return (char *)str; +} +#endif + +static char * +gdb_fread_cstr(gbfile *fin) +{ + char *result = gbfgetcstr(fin); + + if (result && (*result == '\0')) { + xfree(result); + result = NULL; + } + return result; +} + +static int +gdb_fread_str(char *buf, int size, gbfile *fin) +{ + char c; + int res = 0; + + while (size--) { + gbfread(&c, 1, 1, fin); + buf[res] = c; + if (c == '\0') return res; + res++; + } + buf[res] = '\0'; + return res; +} + +static char * +gdb_fread_strlist(void) +{ + char *res = NULL; + int count; + + count = FREAD_i32; + + while (count > 0) { + char *str = FREAD_CSTR; + if (str != NULL) { + if (*str && (res == NULL)) res = str; + else xfree(str); + } + count--; + } + + return res; +} + +static waypoint * +gdb_find_wayptq(const queue *Q, const waypoint *wpt, const char exact) +{ + queue *elem, *tmp; + const char *name = wpt->shortname; + + QUEUE_FOR_EACH(Q, elem, tmp) { + waypoint *tmp = (waypoint *)elem; + if (case_ignore_strcmp(name, tmp->shortname) == 0) { + + if (! exact) return tmp; + + if ((tmp->latitude == wpt->latitude) && + (tmp->longitude == wpt->longitude)) + return tmp; + } + } + return NULL; +} + +static waypoint * +gdb_reader_find_waypt(const waypoint *wpt, const char exact) +{ + waypoint *res; + res = gdb_find_wayptq(&wayptq_in, wpt, exact); + if (res == NULL) + res = gdb_find_wayptq(&wayptq_in_hidden, wpt, exact); + return res; +} + +static waypoint * +gdb_add_route_waypt(route_head *rte, waypoint *ref, const int wpt_class) +{ + waypoint *tmp, *res; + int turn_point; + + tmp = gdb_reader_find_waypt(ref, 1); + if (tmp == NULL) { + double dist; + + tmp = find_waypt_by_name(ref->shortname); + if (tmp == NULL) { + route_add_wpt(rte, ref); + return ref; + } + + /* At this point we have found a waypoint with same name, + but probably from another data stream. Check coordinates! + */ + dist = radtometers(gcdist( + RAD(ref->latitude), RAD(ref->longitude), + RAD(tmp->latitude), RAD(tmp->longitude))); + + if (fabs(dist) > 100) { + warning(MYNAME ": Route point mismatch!\n"); + warning(MYNAME ": \"%s\" from waypoints differs to \"%s\"\n", + tmp->shortname, ref->shortname); + fatal(MYNAME ": from route table by more than %0.1f meters!\n", + dist); + + } + } + res = NULL; + turn_point = (gdb_roadbook && (wpt_class > gt_waypt_class_map_point) && tmp->description); + if (turn_point || (gdb_via == 0) || (wpt_class < gt_waypt_class_map_point)) { + res = waypt_dupe(tmp); + route_add_wpt(rte, res); + } + waypt_free(ref); + return res; +} + +/*******************************************************************************/ +/* TOOLS AND MACROS FOR THE WRITER */ +/*-----------------------------------------------------------------------------*/ + +#define FWRITE_CSTR(a) ((a) == NULL) ? gbfputc(0,fout) : gbfputcstr((a),fout) +#define FWRITE_i16(a) gbfputint16((a),fout) +#define FWRITE_i32(a) gbfputint32((a),fout) +#define FWRITE(a, b) gbfwrite(a,(b),1,fout) +#define FWRITE_C(a) gbfputc((a),fout) +#define FWRITE_DBL(a,b) gdb_write_dbl((a),(b)) +#define FWRITE_TIME(a) gdb_write_time((a)) +#define FWRITE_CSTR_LIST(a) gdb_write_cstr_list((a)) +#define FWRITE_LATLON(a) gbfputint32(GPS_Math_Deg_To_Semi((a)),fout) + +static void +gdb_write_cstr_list(const char *str) +{ + if NOT_EMPTY(str) { + gbfputint32(1, fout); + gbfputcstr(str, fout); + } else + gbfputint32(0, fout); +} + +static void +gdb_write_dbl(const double value, const double def) +{ + if (value == def) gbfputc(0, fout); + else { + gbfputc(1, fout); + gbfputdbl(value, fout); + } +} + +static void +gdb_write_time(const int time) +{ + if (time > 0) { + gbfputc(1, fout); + gbfputint32(time, fout); + } + else + gbfputc(0, fout); +} + +/*******************************************************************************/ +/* GDB "Garmin Database" READER CODE */ +/*-----------------------------------------------------------------------------*/ + +static void +read_file_header(void) +{ + char buf[128]; + int i, reclen; + +/* + We are beginning with a simple binary read. +*/ + FREAD(buf, 6); +/* + A "gbfgetcstr" (FREAD_CSTR) works too, but if we get a wrong file as input, + the file validation my be comes too late. For example a XML base file normally + has no binary zeros inside and produce, if big enought, a buffer overflow. + The following message "local buffer overflow detected..." could be + misinterpreted. +*/ + is_fatal(strcmp(buf, "MsRcf") != 0, MYNAME ": Invalid file \"%s\"!", fin->name); + + reclen = FREAD_i32; + i = FREAD_STR(buf); + is_fatal(buf[0] != 'D', MYNAME ": Invalid file \"%s\"!", fin->name); + + gdb_ver = buf[1] - 'k' + 1; + is_fatal((gdb_ver < GDB_VER_MIN) || (gdb_ver > GDB_VER_MAX), + MYNAME ": Unknown or/and unsupported GDB version (%d.0)!", gdb_ver); + + if (global_opts.verbose_status > 0) + printf(MYNAME ": Reading Garmin GPS Database version %d.0\n", gdb_ver); + + reclen = FREAD_i32; + i = FREAD(buf, reclen + 1); + if (global_opts.verbose_status > 0) { + char *name = buf+2; + if (strstr(name, "SQA") == 0) name = "MapSource"; + else if (strstr(name, "neaderhi") == 0) name = "MapSource BETA"; + warning(MYNAME ": File created with \"%s\"\n", name); + } + + i = FREAD_STR(buf); + is_fatal((i != 9) || (strcmp(buf, "MapSource") != 0), "Invalid header!"); +} + +/*-----------------------------------------------------------------------------*/ + +static waypoint * +read_waypoint(gt_waypt_classes_e *waypt_class_out) +{ + char buf[128]; /* used for temporary stuff */ + int wpt_class, display, icon, dynamic; + int i; + waypoint *res; + garmin_fs_t *gmsd; + char *str; + char *bufp = buf; +#ifdef GMSD_EXPERIMENTAL + char subclass[22]; +#endif +#if GDB_DEBUG + char *sn; +#endif + waypt_ct++; + res = waypt_new(); + + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&res->fs, (format_specific_data *) gmsd); + + res->shortname = FREAD_CSTR; +#if GDB_DEBUG + sn = xstrdup(nice(res->shortname)); +#endif + wpt_class = FREAD_i32; + GMSD_SET(wpt_class, wpt_class); + if (wpt_class != 0) waypth_ct++; + + FREAD_STR(buf); /* Country code */ + GMSD_SETSTR(cc, bufp); + +#ifdef GMSD_EXPERIMENTAL + FREAD(subclass, sizeof(subclass)); + if (gmsd && (wpt_class >= gt_waypt_class_map_point)) { + memcpy(gmsd->subclass, subclass, sizeof(gmsd->subclass)); + gmsd->flags.subclass = 1; + } +#else + FREAD(buf, 22); +#endif + res->latitude = FREAD_LATLON; + res->longitude = FREAD_LATLON; + + if (FREAD_C == 1) { + double alt = FREAD_DBL; + if (alt < 1.0e24) { + res->altitude = alt; +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): Altitude = %.1f\n", + sn, wpt_class, alt); +#endif + } + } +#if GDB_DEBUG + DBG(GDB_DBG_WPT, 1) + printf(MYNAME "-wpt \"%s\": coordinates = %c%0.6f %c%0.6f\n", + sn, + res->latitude < 0 ? 'S' : 'N', res->latitude, + res->longitude < 0 ? 'W' : 'E', res->longitude); +#endif + res->notes = FREAD_CSTR; +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, res->notes) { + char *str = gstrsub(res->notes, "\r\n", ", "); + printf(MYNAME "-wpt \"%s\" (%d): notes = %s\n", + sn, wpt_class, nice(str)); + xfree(str); + } +#endif + if (FREAD_C == 1) { + WAYPT_SET(res, proximity, FREAD_DBL); +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): Proximity = %.1f\n", + sn, wpt_class, res->proximity / 1000); +#endif + } + i = FREAD_i32; +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, i) + printf(MYNAME "-wpt \"%s\" (%d): display = %d\n", + sn, wpt_class, i); +#endif + switch(i) { /* display value */ + case gt_gdb_display_mode_symbol: + display = gt_display_mode_symbol; break; + case gt_gdb_display_mode_symbol_and_comment: + display = gt_display_mode_symbol_and_comment; break; + default: + display = gt_display_mode_symbol_and_name; break; + } + GMSD_SET(display, display); + + FREAD_i32; /* color/colour !not implemented! */ + icon = FREAD_i32; + GMSD_SET(icon, icon); /* icon */ + FREAD_STR(buf); /* city */ + GMSD_SETSTR(city, bufp); + FREAD_STR(buf); /* state */ + GMSD_SETSTR(state, bufp); + FREAD_STR(buf); /* facility */ + GMSD_SETSTR(facility, bufp); + + FREAD(buf, 1); + + if (FREAD_C == 1) { + WAYPT_SET(res, depth, FREAD_DBL); +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): Depth = %.1f\n", + sn, wpt_class, res->depth); +#endif + } + + /* VERSION DEPENDENT CODE */ + + if (gdb_ver <= GDB_VER_2) { + char *temp; + + FREAD(buf, 2); /* ?????????????????????????????????? */ + waypt_flag = FREAD_C; + if (waypt_flag == 0) + FREAD(buf, 3); + else + FREAD(buf, 2); + + temp = FREAD_CSTR; /* undocumented & unused string */ +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, temp) + printf(MYNAME "-wpt \"%s\" (%d): Unknown string = %s\n", + sn, wpt_class, nice(temp)); +#endif + if (temp) xfree(temp); + + res->url = FREAD_CSTR; + if (wpt_class != 0) { + res->description = res->url; + res->url = NULL; + } + } + else { // if (gdb_ver >= GDB_VER_3) + int i, url_ct; + + waypt_flag = 0; + + FREAD_STR(buf); /* street address */ + GMSD_SETSTR(addr, bufp); + + FREAD(buf, 5); /* instruction depended */ + res->description = FREAD_CSTR; /* instruction */ + + url_ct = FREAD_i32; + for (i = url_ct; (i); i--) { + char *str = FREAD_CSTR; + if (str && *str) { + waypt_add_url(res, str, NULL); +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): url(%d) = %s\n", + sn, wpt_class, url_ct - i, str); +#endif + } + } + } + +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, res->description) + printf(MYNAME "-wpt \"%s\" (%d): description = %s\n", + sn, wpt_class, nice(res->description)); + DBG(GDB_DBG_WPTe, res->url) + printf(MYNAME "-wpt \"%s\" (%d): url = %s\n", + sn, wpt_class, nice(res->url)); +#endif + i = FREAD_i16; + if (i != 0) GMSD_SET(category, i); +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, i) + printf(MYNAME "-wpt \"%s\" (%d): category = %d\n", + sn, wpt_class, i); +#endif + + if (FREAD_C == 1) { + WAYPT_SET(res, temperature, FREAD_DBL); +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): temperature = %.1f\n", + sn, wpt_class, res->temperature); +#endif + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + if (waypt_flag != 0) FREAD(buf, 1); + } + if (FREAD_C == 1) { + res->creation_time = FREAD_i32; + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + if (FREAD_i32 == 1) { + FREAD_STR(buf); /* phone number */ + GMSD_SETSTR(phone_nr, bufp); + FREAD_STR(buf); /* ?? fax / mobile ?? */ + } + FREAD_STR(buf); /* country */ + GMSD_SETSTR(country, bufp); + FREAD_STR(buf); /* postal code */ + GMSD_SETSTR(postal_code, bufp); + } + + res->icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); + res->wpt_flags.icon_descr_is_dynamic = dynamic; + +#if GDB_DEBUG + DBG(GDB_DBG_WPTe, icon != GDB_DEF_ICON) + printf(MYNAME "-wpt \"%s\" (%d): icon = \"%s\" (MapSource symbol %d)\n", + sn, wpt_class, nice(res->icon_descr), icon); +#endif + if ((str = GMSD_GET(cc, NULL))) { + if (! GMSD_HAS(country)) + GMSD_SETSTR(country, gt_get_icao_country(str)); + } + + if (gdb_roadbook && (wpt_class > gt_waypt_class_map_point) && res->description) { + wpt_class = gt_waypt_class_user_waypoint; + GMSD_SET(wpt_class, wpt_class); +#ifdef GMSD_EXPERIMENTAL + GMSD_UNSET(subclass); +#endif + } +#if GDB_DEBUG + xfree(sn); +#endif + *waypt_class_out = wpt_class; + return res; +} + +/*-----------------------------------------------------------------------------*/ + +static route_head * +read_route(void) +{ + route_head *rte; + int points, warnings, links, i; + char buf[128]; + bounds bounds; + + rte_ct++; + warnings = 0; + + rte = route_head_alloc(); + rte->rte_name = FREAD_CSTR; + FREAD(buf, 1); /* display/autoname - 1 byte */ + + if (FREAD_C == 0) { /* max. data flag */ + /* maxlat = */ (void) FREAD_i32; + /* maxlon = */ (void) FREAD_i32; + if (FREAD_C == 1) /* maxalt = */ FREAD_DBL; + /* minlat = */ (void) FREAD_i32; + /* minlon = */ (void) FREAD_i32; + if (FREAD_C == 1) /* minalt = */ FREAD_DBL; + } + + links = 0; + points = FREAD_i32; + +#if GDB_DEBUG + DBG(GDB_DBG_RTE, 1) + printf(MYNAME "-rte \"%s\": loading route with %d point(s)...\n", + nice(rte->rte_name), points); +#endif + + for (i = 0; i < points; i++) { + int wpt_class, j; + char buf[128]; + garmin_ilink_t *il_root, *il_anchor; + + waypoint *wpt; + + wpt = waypt_new(); + rtept_ct++; + + wpt->shortname = FREAD_CSTR; /* shortname */ + wpt_class = FREAD_i32; /* waypoint class */ + FREAD_STR(buf); /* country code */ + FREAD(buf, 18 + 4); /* subclass part 1-3 / unknown */ + + if (FREAD_C != 0) { + FREAD(buf, 8); /* aviation data (?); only seen with class "1" (Airport) */ + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) + FREAD(buf, 8); /* a second block since V3 */ + } + + FREAD(buf, 18); /* unknown 18 bytes; but first should be 0x01 or 0x03 */ + /* seen also 0 with VER3 */ + if ((buf[0] != 0x00) && (buf[0] != 0x01) && (buf[0] != 0x03)) { + int i; + + warnings++; + if (warnings > 3) + fatal(MYNAME "-rte_pt \"%s\": too many warnings!\n", wpt->shortname); + warning(MYNAME "-rte_pt \"%s\" (class %d): possible error in route.\n", wpt->shortname, wpt_class); + warning(MYNAME "-rte_pt (dump):"); + for (i = 0; i < 18; i++) { + warning(" %02x", (unsigned char)buf[i]); + } + warning("\n"); + } + + links = FREAD_i32; + il_anchor = NULL; + il_root = NULL; +#if GDB_DEBUG + DBG(GDB_DBG_RTE, links) + printf(MYNAME "-rte_pt \"%s\" (%d): %d interlink step(s)\n", + nice(wpt->shortname), wpt_class, links); +#endif + for (j = 0; j < links; j++) { + garmin_ilink_t *il_step = xmalloc(sizeof(*il_step)); + + il_step->ref_count = 1; + + il_step->lat = FREAD_LATLON; + il_step->lon = FREAD_LATLON; + if (FREAD_C == 1) il_step->alt = FREAD_DBL; + else il_step->alt = unknown_alt; + + if (j == 0) { + wpt->latitude = il_step->lat; + wpt->longitude = il_step->lon; + wpt->altitude = il_step->alt; + } + + il_step->next = NULL; + if (il_anchor == NULL) + il_root = il_step; + else + il_anchor->next = il_step; + il_anchor = il_step; + +#if GDB_DEBUG + DBG(GDB_DBG_RTEe, 1) { + printf(MYNAME "-rte_il \"%s\" (%d of %d): %c%0.6f %c%0.6f\n", + nice(wpt->shortname), j + 1, links, + il_step->lat < 0 ? 'S' : 'N', il_step->lat, + il_step->lon < 0 ? 'W' : 'E', il_step->lon); + } +#endif + } + + waypt_init_bounds(&bounds); + + if (FREAD_C == 0) { /* interlink bounds */ + bounds.max_lat = FREAD_LATLON; + bounds.max_lon = FREAD_LATLON; + if (FREAD_C == 1) + bounds.max_alt = FREAD_DBL; + bounds.min_lat = FREAD_LATLON; + bounds.min_lat = FREAD_LATLON; + if (FREAD_C == 1) + bounds.min_alt = FREAD_DBL; + } + + if (links == 0) { + /* Without links we need all informations from wpt */ + waypoint *tmp = gdb_reader_find_waypt(wpt, 0); + if (tmp != NULL) { + waypt_free(wpt); + wpt = waypt_dupe(tmp); + } + else { + if (waypt_bounds_valid(&bounds)) + warning(MYNAME ": (has bounds)\n"); + + warning(MYNAME ": Data corruption detected!\n"); + fatal(MYNAME ": Sleeping route point without coordinates!\n"); + } + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_2) { + FREAD(buf, 8); + if (gdb_ver >= GDB_VER_3) { + FREAD(buf, 2); + } + } +#if GDB_DEBUG + DBG(GDB_DBG_RTE, 1) + printf(MYNAME "-rte_pt \"%s\": coordinates = %c%0.6f, %c%0.6f\n", + nice(wpt->shortname), + wpt->latitude < 0 ? 'S' : 'N', wpt->latitude, + wpt->longitude < 0 ? 'W' : 'E', wpt->longitude); +#endif + wpt = gdb_add_route_waypt(rte, wpt, wpt_class); + if (wpt != NULL) { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + GMSD_SET(wpt_class, wpt_class); + gmsd->ilinks = il_root; + il_root = NULL; + } + + while (il_root) { + garmin_ilink_t *il = il_root; + il_root = il_root->next; + xfree(il); + } + } /* ENDFOR: for (i = 0; i < points; i++) */ + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + rte->rte_url = FREAD_CSTR; + } + else { + rte->rte_url = gdb_fread_strlist(); + + FREAD(buf, 4); /* ?????????????????????????????????? */ + FREAD(buf, 1); /* ?????????????????????????????????? */ + + rte->rte_desc = FREAD_CSTR; +#if 0 + /* replace CRLF's with ", " */ + if (rte->rte_desc) { + char *c = rte->rte_desc; + while ((c = strstr(c, "\r\n"))) { + *c++ = ','; + *c++ = ' '; + } + } +#endif + } + return rte; +} + +/*-----------------------------------------------------------------------------*/ + +static route_head * +read_track(void) +{ + route_head *res; + int points, index; + char dummy; + + trk_ct++; + + res = route_head_alloc(); + res->rte_name = FREAD_CSTR; +// res->rte_num = trk_ct; + + FREAD(&dummy, 1); /* display - 1 byte */ + FREAD_i32; /* color - 1 dword */ + + points = FREAD_i32; + + for (index = 0; index < points; index++) + { + waypoint *wpt = waypt_new(); + + trkpt_ct++; + + wpt->latitude = FREAD_LATLON; + wpt->longitude = FREAD_LATLON; + if (FREAD_C == 1) { + double alt = FREAD_DBL; + if (alt < 1.0e24) wpt->altitude = alt; + } + if (FREAD_C == 1) { + wpt->creation_time = FREAD_i32; + } + if (FREAD_C == 1) { + WAYPT_SET(wpt, depth, FREAD_DBL); + } + if (FREAD_C == 1) { + WAYPT_SET(wpt, temperature, FREAD_DBL); + } + + track_add_wpt(res, wpt); + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + res->rte_url = gdb_fread_strlist(); + } + else /* if (gdb_ver <= GDB_VER_2) */ { + res->rte_url = FREAD_CSTR; + } +#if GDB_DEBUG + DBG(GDB_DBG_TRK, res->rte_url) + printf(MYNAME "-trk \"%s\": url = %s\n", + res->rte_name, res->rte_url); +#endif + return res; +} + +/*******************************************************************************/ + +static void +init_reader(const char *fname) +{ + fin = gbfopen_le(fname, "rb", MYNAME); + read_file_header(); + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_UTF8) + cet_convert_init(CET_CHARSET_UTF8, 1); + + QUEUE_INIT(&wayptq_in); + QUEUE_INIT(&wayptq_in_hidden); + + gdb_via = (gdb_opt_via && *gdb_opt_via) ? atoi(gdb_opt_via) : 0; + gdb_roadbook = (gdb_opt_roadbook && *gdb_opt_roadbook) ? atoi(gdb_opt_roadbook) : 0; + if (gdb_roadbook) /* higher priority */ gdb_via = 1; + + waypt_ct = 0; + waypth_ct = 0; + rtept_ct = 0; + trkpt_ct = 0; + rte_ct = 0; + trk_ct = 0; +} + +static void +done_reader(void) +{ + disp_summary(fin); + gdb_flush_waypt_queue(&wayptq_in); + gdb_flush_waypt_queue(&wayptq_in_hidden); + gbfclose(fin); +} + +static void +read_data(void) +{ + int incomplete = 0; /* number of incomplete reads */ + + for (;;) { + int len, delta; + char typ, dump; + gt_waypt_classes_e wpt_class; + gbsize_t pos; + waypoint *wpt; + route_head *trk, *rte; + + len = FREAD_i32; + FREAD(&typ, 1); + pos = gbftell(fin); + + if (typ == 'V') break; /* break the loop */ + + dump = 1; + wpt_class = GDB_DEF_CLASS; + + switch(typ) { + case 'W': + wpt = read_waypoint(&wpt_class); + if ((gdb_via == 0) || (wpt_class == 0)) { + waypoint *dupe; + waypt_add(wpt); + dupe = waypt_dupe(wpt); + ENQUEUE_TAIL(&wayptq_in, &dupe->Q); + } + else + ENQUEUE_TAIL(&wayptq_in_hidden, &wpt->Q); + break; + case 'R': + rte = read_route(); + if (rte) route_add_head(rte); + break; + case 'T': + trk = read_track(); + if (trk) track_add_head(trk); + break; + default: + dump = 0; /* make a dump only for main types */ + break; + } + + delta = (pos + len) - gbftell(fin); + if (dump && delta) { + if (! incomplete++) { + warning(MYNAME ":==========================================\n"); + warning(MYNAME ":=== W A R N I N G ===\n"); + } + if (typ == 'W') + warning(MYNAME ":(%d%c-%02d): delta = %d (flag=%3d/%02x)-", + gdb_ver, typ, wpt_class, delta, waypt_flag, waypt_flag); + else + warning(MYNAME ":(%d%c): delta = %d -", gdb_ver, typ, delta); + if (delta > 0) { + int i; + char *buf = xmalloc(delta); + FREAD(buf, delta); + for (i = 0; i < delta; i++) { + warning(" %02x", (unsigned char)buf[i]); + } + xfree(buf); + } + warning("\n"); + } + gbfseek(fin, pos + len, SEEK_SET); + } + + + if (incomplete) { + warning(MYNAME ":------------------------------------------\n"); + warning(MYNAME ": \"%s\"\n", fin->name); + warning(MYNAME ":------------------------------------------\n"); + warning(MYNAME ": Please mail this information\n"); + warning(MYNAME " and, if you can, the used GDB file\n"); + warning(MYNAME ": to gpsbabel-misc@lists.sourceforge.net\n"); + warning(MYNAME ":==========================================\n"); + } +} + +/*******************************************************************************/ + +/* + * reset_short_handle: used for waypoint, route and track names + */ +static void +reset_short_handle(const char *defname) +{ + if (short_h != NULL) + mkshort_del_handle(&short_h); + + short_h = mkshort_new_handle(); + + setshort_length(short_h, GDB_NAME_BUFFERLEN); + setshort_badchars(short_h, "\r\n\t"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 1); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 1); + setshort_defname(short_h, defname); +} + +/* ----------------------------------------------------------------------------*/ + +static void +write_header(void) +{ + char buff[128], tbuff[32]; + char *c; + int len; + struct tm tm; + + FWRITE_CSTR("MsRcf"); + FWRITE_i32(2); + + strncpy(buff, "Dx", sizeof(buff)); + buff[1] = 'k' - 1 + gdb_ver; + FWRITE_CSTR(buff); + +#if 0 + /* Take this if anything is wrong with our self generated watermark */ + strncpy(buff, "A].SQA*Dec 27 2004*17:40:51", sizeof(buff)); /* MapSource V6.5 */ +#else + /* This is our "Watermark" to show this file was created by GPSbabel */ + + /* history: + + "A].GPSBabel_1.2.7-beta*Sep 13 2005*20:10:00" - gpsbabel V1.2.7 BETA + "A].GPSBabel_1.2.8-beta*Jan 18 2006*20:11:00" - gpsbabel 1.2.8-beta01182006_clyde + "A].GPSBabel_1.2.8-beta*Apr 18 2006*20:12:00" - gpsbabel 1.2.8-beta20060405 + "A].GPSBabel-1.3*Jul 02 2006*20:13:00" - gpsbabel 1.3.0 + "A].GPSBabel-1.3.1*Sep 03 2006*20:14:00" - gpsbabel 1.3.1 + "A].GPSBabel-1.3.2*Nov 01 2006*22:23:39" - gpsbabel 1.3.2 + + New since 11/01/2006: + version: version and release of gpsbabel (defined in configure.in) + timestamp: date and time of gdb.c (handled by CVS) + + "A].GPSBabel-1.3.2*Nov 01 2006*22:23:39" - gpsbabel 1.3.2 + "A].GPSBabel-beta20061125*Feb 06 2007*23:24:14" gpsbabel beta20061125 + "A].GPSBabel-1.3.3*Feb 20 2007*20:51:15" - gpsbabel 1.3.3 + + */ + + memset(&tm, 0, sizeof(tm)); + sscanf(gdb_release_date+7, "%d/%d/%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + tm.tm_year -= 1900; + tm.tm_mon -= 1; + strftime(tbuff, sizeof(tbuff), "%b %d %Y*%H:%M:%S", &tm); + snprintf(buff, sizeof(buff), "A].GPSBabel-%s*%s", gpsbabel_version, tbuff); +#endif + len = strlen(buff); + buff[2] = 2; + + c = buff; + while ((c = strchr(c, '*'))) *c++ = '\0'; + + FWRITE_i32(len); + FWRITE(buff, len + 1); + FWRITE_CSTR("MapSource"); /* MapSource magic */ +} + +/*-----------------------------------------------------------------------------*/ + +/* + * gdb_check_waypt: As implemented in waypt_add, but we have some leaks where + * waypoints are modified after waypt_add. Maybe we need a data check + * after each input module. + */ + +static void +gdb_check_waypt(waypoint *wpt) +{ + double lat_orig = wpt->latitude; + double lon_orig = wpt->longitude; + + if (wpt->latitude < -90) wpt->latitude += 180; + else if (wpt->latitude > +90) wpt->latitude -= 180; + if (wpt->longitude < -180) wpt->longitude += 360; + else if (wpt->longitude > +180) wpt->longitude -= 360; + + if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) + fatal ("Invalid latitude %f in waypoint %s.\n", + lat_orig, wpt->shortname ? wpt->shortname : ""); + if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) + fatal ("Invalid longitude %f in waypoint %s.\n", + lon_orig, wpt->shortname ? wpt->shortname : ""); +} + +/*-----------------------------------------------------------------------------*/ + +static void +write_waypoint( + const waypoint *wpt, const char *shortname, garmin_fs_t *gmsd, + const int icon, const int display) +{ + char zbuf[32], ffbuf[32]; + int wpt_class; + + waypt_ct++; /* increase informational number of written waypoints */ + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xFF, sizeof(ffbuf)); + + wpt_class = wpt->microseconds; /* trick */ + + FWRITE_CSTR(shortname); /* uniqe (!!!) shortname */ + FWRITE_i32(wpt_class); /* waypoint class */ + FWRITE_CSTR(GMSD_GET(cc, "")); /* country code */ + + if (wpt_class != 0) waypth_ct++; + +#ifdef GMSD_EXPERIMENTAL + if (gmsd && gmsd->flags.subclass && (wpt_class >= gt_waypt_class_map_point)) { + FWRITE(gmsd->subclass, sizeof(gmsd->subclass)); + } + else +#endif + { + FWRITE(zbuf, 4); /* subclass part 1 */ + FWRITE(ffbuf, 12); /* subclass part 2 */ + FWRITE(zbuf, 2); /* subclass part 3 */ + FWRITE(ffbuf, 4); /* unknown */ + } + + FWRITE_LATLON(wpt->latitude); /* latitude */ + FWRITE_LATLON(wpt->longitude); /* longitude */ + FWRITE_DBL(wpt->altitude, unknown_alt); /* altitude */ + if (wpt->notes) + FWRITE_CSTR(wpt->notes); + else + FWRITE_CSTR(wpt->description); + FWRITE_DBL(WAYPT_GET(wpt, proximity, unknown_alt), unknown_alt); /* proximity */ + FWRITE_i32(display); /* display */ + FWRITE_i32(0); /* color (colour) */ + FWRITE_i32(icon); /* icon */ + FWRITE_CSTR(GMSD_GET(city, "")); /* city */ + FWRITE_CSTR(GMSD_GET(state, "")); /* state */ + FWRITE_CSTR(GMSD_GET(facility, "")); /* facility */ + FWRITE_C(0); /* unknown */ + FWRITE_DBL(WAYPT_GET(wpt, depth, unknown_alt), unknown_alt); /* depth */ + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + char *descr; + + FWRITE(zbuf, 3); + FWRITE(zbuf, 4); + descr = (wpt_class < gt_waypt_class_map_point) ? + wpt->url : wpt->description; + if ((descr != NULL) && (wpt_class >= gt_waypt_class_map_point) && \ + (strcmp(descr, wpt->shortname) == 0)) + descr = NULL; + FWRITE_CSTR(descr); + } + else /* if (gdb_ver > GDB_VER_3) */ { + int cnt; + url_link *url_next; + char *str; + + if (wpt_class < gt_waypt_class_map_point) /* street address */ + str = GMSD_GET(addr, ""); + else + str = ""; + FWRITE_CSTR(str); + FWRITE(zbuf, 5); /* instruction dependend */ + + /* GBD doesn't have a native description field */ + /* here we misuse the instruction field */ + + str = wpt->description; + if (str && (strcmp(str, wpt->shortname) == 0)) str = NULL; + if (str && wpt->notes && (strcmp(str, wpt->notes) == 0)) str = NULL; + FWRITE_CSTR(str); /* instruction */ + + cnt = 0; + if (wpt->url) cnt++; + for (url_next = wpt->url_next; (url_next); url_next = url_next->url_next) + if (url_next->url) cnt++; + FWRITE_i32(cnt); + if (wpt->url) FWRITE_CSTR(wpt->url); + for (url_next = wpt->url_next; (url_next); url_next = url_next->url_next) + if (url_next->url) FWRITE_CSTR(url_next->url); + } + + FWRITE_i16(GMSD_GET(category, gdb_category)); + FWRITE_DBL(WAYPT_GET(wpt, temperature, 0), 0); + FWRITE_TIME(wpt->creation_time); + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + char *str = GMSD_GET(phone_nr, ""); + if (*str) { + FWRITE_i32(1); + FWRITE_CSTR(str); + FWRITE_CSTR(""); + } + else { + FWRITE_i32(0); + } + FWRITE_CSTR(GMSD_GET(country, "")); + FWRITE_CSTR(GMSD_GET(postal_code, "")); + } +} + +static void +route_compute_bounds(const route_head *rte, bounds *bounds) +{ + queue *elem, *tmp; + waypt_init_bounds(bounds); + QUEUE_FOR_EACH((queue *)&rte->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + gdb_check_waypt(wpt); + waypt_add_to_bounds(bounds, wpt); + } +} + +static void +route_write_bounds(bounds *bounds) +{ + if (waypt_bounds_valid(bounds)) { + FWRITE_C(0); + FWRITE_LATLON(bounds->max_lat); + FWRITE_LATLON(bounds->max_lon); + FWRITE_DBL(bounds->max_alt, -(unknown_alt)); + FWRITE_LATLON(bounds->min_lat); + FWRITE_LATLON(bounds->min_lon); + FWRITE_DBL(bounds->min_alt, unknown_alt); + } + else FWRITE_C(1); +} + +static void +write_route(const route_head *rte, const char *rte_name) +{ + bounds bounds; + int points, index; + queue *elem, *tmp; + char zbuf[32], ffbuf[32]; + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xFF, sizeof(ffbuf)); + + FWRITE_CSTR(rte_name); + FWRITE_C(0); /* display/autoname - 1 byte */ + + route_compute_bounds(rte, &bounds); + route_write_bounds(&bounds); + + points = ELEMENTS(rte); + FWRITE_i32(points); + + index = 0; + + QUEUE_FOR_EACH((queue *)&rte->waypoint_list, elem, tmp) { + + waypoint *wpt = (waypoint *)elem; + waypoint *next = (waypoint *)tmp; + waypoint *test; + garmin_fs_t *gmsd = NULL; + int wpt_class; + + index++; + rtept_ct++; /* increase informational number of written route points */ + + if (index == 1) gdb_check_waypt(wpt); + if (index < points) gdb_check_waypt(next); + + test = gdb_find_wayptq(&wayptq_out, wpt, 1); + if (test != NULL) wpt = test; + else { + fatal(MYNAME ": Sorry, that should never happen!!!\n"); + } + + gmsd = GMSD_FIND(wpt); + + /* extra_data may contain a modified shortname */ + FWRITE_CSTR((wpt->extra_data) ? (char *)wpt->extra_data : wpt->shortname); + + wpt_class = wpt->microseconds; /* trick */ + + FWRITE_i32(wpt_class); /* waypoint class */ + FWRITE_CSTR(GMSD_GET(cc, "")); /* country */ +#ifdef GMSD_EXPERIMENTAL + if (gmsd && gmsd->flags.subclass && (wpt_class >= gt_waypt_class_map_point)) + FWRITE(gmsd->subclass, sizeof(gmsd->subclass)); + else +#endif + { + FWRITE(zbuf, 4); /* subclass part 1 */ + FWRITE(ffbuf, 12); /* subclass part 2 */ + FWRITE(zbuf, 2); /* subclass part 3 */ + FWRITE(ffbuf, 4); /* unknown */ + } + + FWRITE_C(0); /* unknown value or string */ + FWRITE_C(3); /* unknown 18 bytes starting with 0x03 */ + FWRITE(zbuf, 3); + FWRITE(ffbuf, 4); + FWRITE(zbuf, 10); + + if (index == points) { + FWRITE_i32(0); /* no more steps */ + FWRITE_C(1); /* skip bounds */ + } + else /* if (index < points) */ { + FWRITE_i32(2); /* two interstep links */ + + FWRITE_LATLON(wpt->latitude); + FWRITE_LATLON(wpt->longitude); + FWRITE_DBL(wpt->altitude, unknown_alt); + FWRITE_LATLON(next->latitude); + FWRITE_LATLON(next->longitude); + FWRITE_DBL(next->altitude, unknown_alt); + + waypt_init_bounds(&bounds); + waypt_add_to_bounds(&bounds, wpt); + waypt_add_to_bounds(&bounds, next); + route_write_bounds(&bounds); + + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_2) { + FWRITE(ffbuf, 8); + if (gdb_ver >= GDB_VER_3) + FWRITE(zbuf, 2); + } + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + FWRITE_CSTR(rte->rte_url); + } + else /* if (gdb_ver >= GDB_VER_3) */ { + FWRITE_CSTR_LIST(rte->rte_url); + FWRITE_i32(0x0E); /* color ??? */ + FWRITE_C(0); + FWRITE_CSTR(rte->rte_desc); + } +} + +static void +write_track(const route_head *trk, const char *trk_name) +{ + queue *elem, *tmp; + int points = ELEMENTS(trk); + + FWRITE_CSTR(trk_name); + FWRITE_C(0); + FWRITE_i32(0); + + FWRITE_i32(points); /* total number of waypoints in waypoint list */ + + QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) + { + double d; + waypoint *wpt = (waypoint *)elem; + + trkpt_ct++; /* increase informational number of written route points */ + + FWRITE_LATLON(wpt->latitude); + FWRITE_LATLON(wpt->longitude); + FWRITE_DBL(wpt->altitude, unknown_alt); + FWRITE_TIME(wpt->creation_time); + d = WAYPT_GET(wpt, depth, unknown_alt); + FWRITE_DBL(d, unknown_alt); + d = WAYPT_GET(wpt, temperature, -99999); + FWRITE_DBL(d, -99999); + } + + /* finalize track */ + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + FWRITE_CSTR(trk->rte_url); + } + else /* if (gdb_ver >= GDB_VER_3 */ { + FWRITE_CSTR_LIST(trk->rte_url); + } +} + +/*-----------------------------------------------------------------------------*/ + +static void +finalize_item(const gbsize_t anchor) +{ + gbsize_t mark; + int len; + + mark = gbftell(fout); + len = mark - anchor; + gbfseek(fout, -(len + 5), SEEK_CUR); + FWRITE_i32(mark - anchor); + gbfseek(fout, len + 1, SEEK_CUR); +} + +/*-----------------------------------------------------------------------------*/ + +static char +str_not_equal(const char *s1, const char *s2) +{ + if (s1) { + if (!s2) return 1; + if (strcmp(s1, s2) != 0) return 1; + else return 0; + } + else if (s2) return 1; + else return 0; +} + +static void +write_waypoint_cb(const waypoint *refpt) +{ + garmin_fs_t *gmsd; + waypoint *test; + gbsize_t anchor; + + /* do this when backup always happens in main */ + + rtrim(((waypoint *)refpt)->shortname); + test = gdb_find_wayptq(&wayptq_out, refpt, 1); + + if ((test != NULL) && (route_flag == 0)) { + if ((str_not_equal(test->notes, refpt->notes)) || + (str_not_equal(test->url, refpt->url))) + test = NULL; + } + + if (test == NULL) { + int icon, display, wpt_class; + char *name; + waypoint *wpt = waypt_dupe(refpt); + + gdb_check_waypt(wpt); + ENQUEUE_TAIL(&wayptq_out, &wpt->Q); + + FWRITE_i32(-1); + FWRITE_C('W'); + anchor = gbftell(fout); + + /* prepare the waypoint */ + gmsd = GMSD_FIND(wpt); + + wpt_class = GMSD_GET(wpt_class, -1); + if (wpt_class == -1) + wpt_class = (route_flag) ? GDB_DEF_HIDDEN_CLASS : GDB_DEF_CLASS; + wpt->microseconds = wpt_class; /* trick, we need this for the route(s) */ + + icon = GMSD_GET(icon, -1); + if (icon < 0) { + if (wpt->icon_descr) + icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); + else + icon = GDB_DEF_ICON; + } + + switch(GMSD_GET(display, -1)) { /* display */ + case -1: + if (wpt_class < 8) + display = gt_gdb_display_mode_symbol_and_name; + else + display = gt_gdb_display_mode_symbol; + break; + case gt_display_mode_symbol: + display = gt_gdb_display_mode_symbol; + break; + case gt_display_mode_symbol_and_comment: + display = gt_gdb_display_mode_symbol_and_comment; + break; + default: + display = gt_gdb_display_mode_symbol_and_name; + break; + } + + name = wpt->shortname; + + if (global_opts.synthesize_shortnames || (*name == '\0')) { + name = wpt->notes; + if (!name) name = wpt->description; + if (!name) name = wpt->shortname; + } + + name = mkshort(short_h, name); + wpt->extra_data = (void *)name; + write_waypoint(wpt, name, gmsd, icon, display); + + finalize_item(anchor); + } +} + +static void +write_route_cb(const route_head *rte) +{ + gbsize_t anchor; + char *name; + char buf[32]; + + if (ELEMENTS(rte) <= 0) return; + + if (rte->rte_name == NULL) { + snprintf(buf, sizeof(buf), "Route%04d", rte->rte_num); + name = mkshort(short_h, buf); + } + else + name = mkshort(short_h, rte->rte_name); + + rte_ct++; /* increase informational number of written routes */ + + FWRITE_i32(-1); + FWRITE_C('R'); + + anchor = gbftell(fout); + write_route(rte, name); + finalize_item(anchor); + + xfree(name); +} + +static void +write_track_cb(const route_head *trk) +{ + gbsize_t anchor; + char *name; + char buf[32]; + + if (ELEMENTS(trk) <= 0) return; + + if (trk->rte_name == NULL) { + snprintf(buf, sizeof(buf), "Track%04d", trk->rte_num); + name = mkshort(short_h, buf); + } + else + name = mkshort(short_h, trk->rte_name); + + trk_ct++; /* increase informational number of written tracks */ + + FWRITE_i32(-1); + FWRITE_C('T'); + + anchor = gbftell(fout); + write_track(trk, name); + finalize_item(anchor); + + xfree(name); +} + +/*-----------------------------------------------------------------------------*/ + +static void +init_writer(const char *fname) +{ + fout = gbfopen_le(fname, "wb", MYNAME); + + gdb_category = (gdb_opt_category) ? atoi(gdb_opt_category) : 0; + gdb_ver = (gdb_opt_ver && *gdb_opt_ver) ? atoi(gdb_opt_ver) : 0; + + if (gdb_category) { + is_fatal((gdb_category < 1) || (gdb_category > 16), + MYNAME ": cat must be between 1 and 16!"); + gdb_category = 1 << (gdb_category - 1); + } + + if (gdb_opt_bitcategory) { + gdb_category = strtol(gdb_opt_bitcategory, NULL, 0); + } + + if (gdb_ver >= GDB_VER_UTF8) + cet_convert_init(CET_CHARSET_UTF8, 1); + + QUEUE_INIT(&wayptq_out); + short_h = NULL; + + waypt_ct = 0; + waypth_ct = 0; + rtept_ct = 0; + trkpt_ct = 0; + rte_ct = 0; + trk_ct = 0; +} + +static void +done_writer(void) +{ + disp_summary(fout); + gdb_flush_waypt_queue(&wayptq_out); + mkshort_del_handle(&short_h); + gbfclose(fout); +} + +static void +write_data(void) +{ + if (gdb_opt_ver) gdb_ver = atoi(gdb_opt_ver); + write_header(); + + reset_short_handle("WPT"); + route_flag = 0; + waypt_disp_all(write_waypoint_cb); + route_flag = 1; + route_disp_all(NULL, NULL, write_waypoint_cb); + + reset_short_handle("Route"); + route_disp_all(write_route_cb, NULL, NULL); + + reset_short_handle("Track"); + track_disp_all(write_track_cb, NULL, NULL); + + FWRITE_i32(2); /* finalize gdb with empty map segment */ + FWRITE_CSTR("V"); + FWRITE_C(1); +} + +/*******************************************************************************/ + +#define GDB_OPT_VER "ver" +#define GDB_OPT_VIA "via" +#define GDB_OPT_CATEGORY "cat" +#define GDB_OPT_BITCATEGORY "bitscategory" +#define GDB_OPT_ROADBOOK "roadbook" + +static arglist_t gdb_args[] = { + {GDB_OPT_CATEGORY, &gdb_opt_category, + "Default category on output (1..16)", + NULL, ARGTYPE_INT, "1", "16"}, + {GDB_OPT_BITCATEGORY, &gdb_opt_bitcategory, "Bitmap of categories", + NULL, ARGTYPE_INT, "1", "65535"}, + {GDB_OPT_VER, &gdb_opt_ver, + "Version of gdb file to generate (1..3)", + "2", ARGTYPE_INT, "1", "3"}, + {GDB_OPT_VIA, &gdb_opt_via, + "Drop route points that do not have an equivalent waypoint (hidden points)", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {GDB_OPT_ROADBOOK, &gdb_opt_roadbook, + "Include major turn points (with description) from calculated route", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + + ARG_TERMINATOR +}; + +ff_vecs_t gdb_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + init_reader, + init_writer, + done_reader, + done_writer, + read_data, + write_data, + NULL, + gdb_args, + CET_CHARSET_MS_ANSI, 0 /* O.K.: changed to NON-FIXED */ + /* because of utf8 strings since GDB V3 */ +}; + +/*******************************************************************************/ diff --git a/geo.c b/geo.c new file mode 100644 index 000000000..47d3f26f3 --- /dev/null +++ b/geo.c @@ -0,0 +1,229 @@ +/* + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "xmlgeneric.h" + +static char *deficon = NULL; +static char *nuke_placer; + +static waypoint *wpt_tmp; + +static gbfile *ofd; + +static +arglist_t geo_args[] = { + {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"nuke_placer", &nuke_placer, "Omit Placer name", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +#define MYNAME "geo" +#define MY_CBUF 4096 + +#if ! HAVE_LIBEXPAT +static void +geo_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded GEO support because expat was not installed.\n"); +} + +void +geo_read(void) +{ +} +#else + +static xg_callback wpt_s, wpt_e; +static xg_callback wpt_link_s, wpt_link; +static xg_callback wpt_name, wpt_name_s, wpt_type, wpt_coord; + +static +xg_tag_mapping loc_map[] = { + { wpt_s, cb_start, "/loc/waypoint" }, + { wpt_e, cb_end, "/loc/waypoint" }, + { wpt_name_s, cb_start, "/loc/waypoint/name" }, + { wpt_name, cb_cdata, "/loc/waypoint/name" }, + { wpt_type, cb_cdata, "/loc/waypoint/type" }, + { wpt_link_s, cb_start, "/loc/waypoint/link" }, + { wpt_link, cb_cdata, "/loc/waypoint/link" }, + { wpt_coord, cb_start, "/loc/waypoint/coord" }, + { NULL, 0, NULL } +}; + +void wpt_s(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); + /* + * 'geo' doesn't really have an 'unknown' and doesn't have any + * concept of alt. Unfortunately, we have many reference files + * that have leaked the 'unknown_alt' value into them, so we paper + * over that here. + */ + wpt_tmp->altitude = 0; +} + +void wpt_e(const char *args, const char **unused) +{ + waypt_add(wpt_tmp); +} + +void wpt_name_s(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "id")) { + wpt_tmp->shortname = xstrdup(avp[1]); + } + avp+=2; + } +} + +void wpt_name(const char *args, const char **unused) +{ + char *s; + if (!args) return; + + wpt_tmp->description = xstrappend(wpt_tmp->description,args); + s = xstrrstr(wpt_tmp->description, " by "); + if (s) { + wpt_tmp->gc_data.placer = xstrdup(s + 4); + + if (nuke_placer) { + *s = '\0'; + } + } +} + +void wpt_link_s(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "text")) { + wpt_tmp->url_link_text = xstrdup(avp[1]); + } + avp+=2; + } +} +void wpt_link(const char *args, const char **attrv) +{ + wpt_tmp->url = xstrdup(args); +} + +void wpt_type(const char *args, const char **unused) +{ + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + wpt_tmp->icon_descr = xstrdup(args); +} + +void wpt_coord(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->latitude); + } + else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->longitude); + } + avp+=2; + } +} + +static void +geo_rd_init(const char *fname) +{ + xml_init(fname, loc_map, NULL); +} + +static void +geo_read(void) +{ + xml_read(); +} +#endif + +static void +geo_rd_deinit(void) +{ + xml_deinit(); +} + +static void +geo_wr_init(const char *fname) +{ + ofd = gbfopen(fname, "w", MYNAME); +} + +static void +geo_wr_deinit(void) +{ + gbfclose(ofd); +} + +static void +geo_waypt_pr(const waypoint *waypointp) +{ + char *tmp; + + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "", waypointp->shortname); + gbfprintf(ofd, "", waypointp->description); + gbfprintf(ofd, "\n"); + + gbfprintf(ofd, "", + waypointp->latitude, + waypointp->longitude); + gbfprintf(ofd, "\n"); + + if (waypointp->icon_descr) { + gbfprintf(ofd, "%s\n", deficon ? deficon : waypointp->icon_descr); + } + if (waypointp->url) { + tmp = xml_entitize(waypointp->url); + gbfprintf(ofd, "%s\n", + tmp); + xfree(tmp); + } + gbfprintf(ofd, "\n"); +} + +static void +geo_write(void) +{ + gbfprintf(ofd, "\n"); + waypt_disp_all(geo_waypt_pr); + gbfprintf(ofd, "\n"); +} + +ff_vecs_t geo_vecs = { + ff_type_file, + { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none }, + geo_rd_init, + geo_wr_init, + geo_rd_deinit, + geo_wr_deinit, + geo_read, + geo_write, + NULL, + geo_args, + CET_CHARSET_UTF8, 0 /* CET-REVIEW */ +}; diff --git a/geocaching.loc b/geocaching.loc new file mode 100644 index 000000000..4073f2c98 --- /dev/null +++ b/geocaching.loc @@ -0,0 +1 @@ +geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=3771geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=6711geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=7211geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=9641geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=10019geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=11121geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=12447geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=12666geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=12669 \ No newline at end of file diff --git a/geoniche.c b/geoniche.c new file mode 100644 index 000000000..d9a6c0f53 --- /dev/null +++ b/geoniche.c @@ -0,0 +1,778 @@ +/* + Read and write GeoNiche files. + + Copyright (C) 2003 Rick Richardson + Copyright (C) 2006 Robert Lipe + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "pdbfile.h" +#include "jeeps/gpsmath.h" +#include "garmin_tables.h" + +#include +#include + +#define MYNAME "Geoniche" +#define MYTYPE_ASC 0x50454e44 /* PEND */ +#define MYTYPE_BIN 0x44415441 /* DATA */ +#define MYCREATOR 0x47656f4e /* GeoN */ + +#undef GEONICHE_DBG + +static pdbfile *file_in, *file_out; +static const char *FilenameOut; +static int rec_ct; +static int ct; +static char Rec0Magic[] = "68000NV4Q2"; + +static char *Arg_dbname = NULL; +static char *Arg_category = NULL; + +static +arglist_t Args[] = { + {"dbname", &Arg_dbname, + "Database name (filename)", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"category", &Arg_category, + "Category name (Cache)", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +#define ARG_FREE(X) do { if (X) { xfree(X); X = NULL; } } while (0) + +/* + * Conversions between gc.com ID's and GID's + */ +static char GcSet[] = "0123456789ABCDEFGHJKMNPQRTVWXYZ"; +static int GcOffset = 16 * 31 * 31 * 31 - 65536; + +static int +gid2id(char *gid) +{ + char *p; + int i, val; + + if (strncmp(gid, "GC", 2) != 0) + return -1; + if (strlen(gid) != 6) + return -1; + gid += 2; + + if (strcmp(gid, "G000") < 0) + return strtol(gid, NULL, 16); + + for (val = i = 0; i < 4; ++i) + { + val *= 31; + p = strchr(GcSet, gid[i]); + if (!p) return -1; + val += p - GcSet; + } + return val - GcOffset; +} + +static void +id2gid(char gid[6+1], int id) +{ + gid[0] = 0; + if (id < 0) + return; + else if (id < 65536) + snprintf(gid, 6+1, "GC%04X", id); + else + { + int i; + + id += GcOffset; + gid[0] = 'G'; + gid[1] = 'C'; + for (i = 5; i >= 2; --i) { + gid[i] = GcSet[id%31]; + id /= 31; + } + gid[6] = 0; + if (id) + gid[0] = 0; + } + return; +} + +static void +rd_init(const char *fname) +{ + file_in = pdb_open(fname, MYNAME); +} + +static void +rd_deinit(void) +{ + pdb_close(file_in); + ARG_FREE(Arg_dbname); + ARG_FREE(Arg_category); +} + +static void +wr_init(const char *fname) +{ + file_out = pdb_create(fname, MYNAME); + FilenameOut = fname; +} + +static void +wr_deinit(void) +{ + pdb_close(file_out); + ARG_FREE(Arg_dbname); + ARG_FREE(Arg_category); +} + +static char * +field(char **pp, int *lenp) +{ + int len = *lenp; + char *p = *pp; + char *dp, *dbuf; + int state = 0; + + if (len == 0 || *p == 0) + return NULL; + + dbuf = dp = xmalloc(len); + while (len) + { + char ch; + + ch = *p++; + --len; + if (ch == 0 || len == 0) + break; + switch (state) + { + case 0: + if (ch == '\\') + state = 1; + else if (ch == ',') + goto eof; + else + *dp++ = ch; + break; + default: + *dp++ = ch; + state = 0; + break; + } + } +eof: + *dp++ = 0; + dbuf = xrealloc(dbuf, dp - dbuf); + /* fprintf(stderr, "<%.8s> dbuf=%x, len=%d\n", *pp, dbuf, len); */ + *pp = p; + *lenp = len; + return dbuf; +} + +static void +geoniche_read_asc(void) +{ + pdbrec_t *pdb_rec; + + /* Process record 0 */ + pdb_rec = file_in->rec_list; + if (strcmp((char *) pdb_rec->data, Rec0Magic)) + fatal(MYNAME ": Bad record 0, not a GeoNiche file.\n"); + pdb_rec = pdb_rec->next; + + /* Process the rest of the records */ + for (; pdb_rec; pdb_rec = pdb_rec->next) + { + waypoint *wpt; + char *vdata; + int vlen; + char *p; + + int id; + int route_id; + char *title; + char *category; + double lat, lon, alt; + char *datestr, *timestr; + int icon; + char *notes; + char gid[6+1]; + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + wpt = waypt_new(); + if (!wpt) + fatal(MYNAME ": Couldn't allocate waypoint.\n"); + vdata = (char *) pdb_rec->data; + vlen = pdb_rec->size; + + /* Field 1: Target */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 1 (target).\n"); + if (strcmp(p, "Route") == 0) + fatal(MYNAME ": Route record type is not implemented.\n"); + if (strcmp(p, "Target")) + fatal(MYNAME ": Unknown record type '%s'.\n", p); + xfree(p); + + /* Field 2: Import ID number */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 2 (ID).\n"); + id = atoi(p); + xfree(p); + + /* Field 3: Title */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 3 (Title).\n"); + title = p; + + /* Field 4: Route ID number */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 4 (Route ID).\n"); + route_id = atoi(p); + xfree(p); + + /* Field 5: Category */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 5 (Category).\n"); + category = p; + + /* Field 6: Latitude */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 6 (Latitude).\n"); + lat = atof(p); + xfree(p); + + /* Field 7: Longitude */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 7 (Longitude).\n"); + lon = atof(p); + xfree(p); + + /* Field 8: Altitude */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 8 (Altitude).\n"); + alt = atof(p); + xfree(p); + + /* Field 9: Creation date */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 9 (Creation date).\n"); + datestr = p; + + /* Field 10: Creation time */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 10 (Creation time).\n"); + timestr = p; + + /* Field 11: Visited date */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 11 (Visited date).\n"); + xfree(p); + + /* Field 12: Visited time */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 12 (Visited time).\n"); + xfree(p); + + /* Field 13: Icon color (R G B) */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 13 (Icon color).\n"); + xfree(p); + + /* Field 14: icon number */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 14 (Icon number).\n"); + icon = atoi(p); + xfree(p); + + /* Field 15: unused */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 15 (unused1).\n"); + xfree(p); + + /* Field 16: unused */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 16 (unused2).\n"); + xfree(p); + + /* Field 17: unused */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 17 (unused3).\n"); + xfree(p); + + /* Field 18: Notes */ + p = field(&vdata, &vlen); + if (!p) fatal(MYNAME ": Premature EOD processing field 18 (Notes).\n"); + notes = p; + + sscanf(datestr, "%d/%d/%d", &tm.tm_mon, &tm.tm_mday, &tm.tm_year); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + sscanf(timestr, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + if (tm.tm_year >= 1970) { + wpt->creation_time = mktime(&tm); + } + xfree(datestr); + xfree(timestr); + + id2gid(gid, id); + wpt->latitude = lat; + wpt->longitude = lon; + wpt->altitude = alt; + wpt->icon_descr = category; + wpt->wpt_flags.icon_descr_is_dynamic = 1; + + if (gid[0]) + { + wpt->shortname = xstrdup(gid); + wpt->description = title; + wpt->notes = notes; + } + else + { + wpt->shortname = xstrdup(title); + wpt->description = title; + wpt->notes = notes; + } + + waypt_add(wpt); + } +} + +static char *geoniche_icon_map[] = /* MPS */ +{ + /* 21 */ "Cross", + /* 22 */ "Cross (light)", + /* 23 */ "Cross (little)", + /* 24 */ "Cross (straight)", + /* 25 */ "Cross (light straight)", + /* 26 */ "Cross (little straight)", + /* 27 */ NULL, + /* 28 */ NULL, + /* 29 */ NULL, + /* 2A */ "Flag", + /* 2B */ "Car", /* 56 */ + /* 2C */ "Gas Station", /* 8 */ + /* 2D */ "Observation Point", + /* 2E */ "Scenic Area", /* 48 */ + /* 2F */ "City", + /* 30 */ "Mountains", + /* 31 */ "Park", /* 46 */ + /* 32 */ "Forest", /* 105 */ + /* 33 */ "Campground", /* 38 */ + /* 34 */ NULL, + /* 35 */ "Men", + /* 36 */ "Woman", + /* 37 */ "Hotel", /* 59 */ + /* 38 */ "Residence", /* 10 */ + /* 39 */ "Restaurant", /* 11 */ + /* 3A */ "Cafe", + /* 3B */ NULL, + /* 3C */ "Airport", /* 107 */ + /* 3D */ "Medical Facility", /* 43 */ + /* 3E */ "Ropeway", + /* 3F */ "Sailing Area", + /* 40 */ "Anchor", + /* 41 */ NULL, /* Half Anchor ??? */ + /* 42 */ "Fishing Area", /* 7 */ + /* 43 */ "Stop Sign", + /* 44 */ "Question Sign", + /* 45 */ NULL, + /* 46 */ NULL, + /* 47 */ "Euro Sign", + /* 48 */ "Bank", /* 6 */ + /* 49 */ NULL, + /* 4A */ "Left Arrow", + /* 4B */ "Right Arrow", + /* 4C */ "Traditional Cache", + /* 4D */ "Multi-Cache", /* 86 */ + /* 4E */ "Virtual Cache", /* 48 */ + /* 4F */ "Letterbox Cache", + /* 50 */ "Event Cache", /* 47 */ + /* 51 */ "Webcam Cache", /* 90 */ + /* 52 */ "Mystery or puzzle Cache", +}; + +static char * +geoniche_icon_to_descr(const int no) +{ + char *result = NULL; + + if (no >= 0x21) + { + int i = no - 0x21; + if (i <= 49) + { + result = geoniche_icon_map[i]; + } + } + if (result != NULL) + { + result = xstrdup(result); + } + return result; +} + +static void +geoniche_read_bin(void) +{ + pdbrec_t *pdb_rec; + + /* Process records */ + + for (pdb_rec = file_in->rec_list; pdb_rec != NULL; pdb_rec = pdb_rec->next) + { + char *vdata = (char *) pdb_rec->data; + struct tm created, visited; + int icon_nr, selected; + int latdeg, londeg; + double lat, lon, altitude; + waypoint *waypt; + + memset(&visited, 0, sizeof(visited)); + memset(&created, 0, sizeof(created)); + + latdeg = be_read16(vdata + 0); + lat = be_read32(vdata + 2); + londeg = be_read16(vdata + 6); + lon = be_read32(vdata + 8); + altitude = (float) be_read32(vdata + 12); + selected = vdata[16]; + created.tm_min = be_read16(vdata + 20); + created.tm_hour = be_read16(vdata + 22); + created.tm_mday = be_read16(vdata + 24); + created.tm_mon = be_read16(vdata + 26); + created.tm_year = be_read16(vdata + 28); + visited.tm_min = be_read16(vdata + 34); + visited.tm_hour = be_read16(vdata + 36); + visited.tm_mday = be_read16(vdata + 38); + visited.tm_mon = be_read16(vdata + 40); + visited.tm_year = be_read16(vdata + 42); + +#ifdef GEONICHE_DBG + printf(MYNAME "-date: %04d/%02d/%02d, %02d:%02d (%04d/%02d/%02d, %02d:%02d)\n", + created.tm_year, created.tm_mon, created.tm_mday, created.tm_hour, created.tm_min, + visited.tm_year, visited.tm_mon, visited.tm_mday, visited.tm_hour, visited.tm_min); +#endif + icon_nr = vdata[62]; + + latdeg = 89 - latdeg; + lat = lat * (double) 0.0000006; + if (latdeg >= 0) + lat = (double) 60.0 - lat; + else + latdeg++; + + lon = lon * (double) 0.0000006; + while (londeg >= 360) londeg-=360; + if (londeg > 180) + { + lon = (double) 60.0 - lon; + londeg = londeg - 359; + } + + created.tm_year-=1900; + created.tm_mon--; + + waypt = waypt_new(); + + waypt->shortname = xstrdup(vdata + 63); + waypt->altitude = altitude; + waypt->creation_time = mkgmtime(&created); + + GPS_Math_DegMin_To_Deg(latdeg, lat, &waypt->latitude); + GPS_Math_DegMin_To_Deg(londeg, lon, &waypt->longitude); + + waypt->icon_descr = geoniche_icon_to_descr(icon_nr); + if (waypt->icon_descr != NULL) + waypt->wpt_flags.icon_descr_is_dynamic = 1; + + waypt_add(waypt); + } +} + +static void +data_read(void) +{ + if (file_in->creator != MYCREATOR) + fatal(MYNAME ": Not a GeoNiche file.\n"); + + switch(file_in->type) + { + case MYTYPE_ASC: + geoniche_read_asc(); + break; + case MYTYPE_BIN: + geoniche_read_bin(); + break; + default: + fatal(MYNAME ": Unsupported GeoNiche file.\n"); + } +} + +static char * +enscape(char *s) +{ + char *buf, *d; + + if (!s) + { + d = xmalloc(1); + *d = 0; + return d; + } + buf = d = xmalloc(strlen(s) * 2 + 1); + for (; *s; ++s) + { + +/* + * 3 May 06: need to escape single quotes for v1.40 release + */ + + if (*s == '\\' || *s == ',' || *s == '\'') + { + *d++ = '\\'; + *d++ = *s; + } + +/* 3 May 06: stop stripping for better readability + * + * else if ((*s == '\r') || (*s == '\n')) + * *d++ = ' '; + */ + else + *d++ = *s; + } + + *d = 0; + return buf; +} + +/* + * Attempt to map an icon description into a GeoNiche icon number + */ +static int +wpt2icon(const waypoint *wpt) +{ + const char *desc = wpt->icon_descr; + + if (!desc) return 0; + else if (strstr(desc, "reg")) return 43; + else if (strstr(desc, "trad")) return 43; + else if (strstr(desc, "multi")) return 44; + else if (strstr(desc, "offset")) return 44; + else if (strstr(desc, "virt")) return 45; + else if (strstr(desc, "loca")) return 45; + else if (strstr(desc, "event")) return 46; + else if (strstr(desc, "lett")) return 47; + else if (strstr(desc, "hyb")) return 47; + else if (strstr(desc, "unk")) return 48; + else if (strstr(desc, "cam")) return 49; + + switch (wpt->gc_data.type) { + case gt_traditional: return 43; + case gt_multi: return 44; + case gt_locationless: return 45; + case gt_earth: return 45; + case gt_virtual: return 45; + case gt_letterbox: return 46; + case gt_event: return 47; + case gt_cito: return 47; + case gt_suprise: return 48; + case gt_webcam: return 49; + case gt_unknown: return 0; + case gt_benchmark: return 0; + case gt_ape: return 0; + case gt_mega: return 0; + } + + return 0; +} + +static char * +geoniche_geostuff(const waypoint *wpt) +{ + char *gs = NULL, *tmp1, *tmp2, *tmp3; + char tbuf[10240]; + + if (!wpt->gc_data.terr) { + return NULL; + } + + snprintf(tbuf, sizeof(tbuf), "\n%s by %s\n\n", gs_get_cachetype(wpt->gc_data.type), wpt->gc_data.placer); + gs = xstrappend(gs, tbuf); + +/* + * 3 May 06: Removed duplicated information + * + * snprintf(tbuf, sizeof(tbuf), "Waypoint: %s %s\n", wpt->shortname, wpt->description); + * gs = xstrappend(gs, tbuf); + */ + +/* + * 3 May 06: Added container type + */ + snprintf(tbuf, sizeof(tbuf), "Container: %s\nDifficulty: %3.1f\nTerrain: %3.1f\n\n", gs_get_container(wpt->gc_data.container), wpt->gc_data.diff/10.0, wpt->gc_data.terr/10.0); + gs = xstrappend(gs, tbuf); + + tmp1 = strip_html(&wpt->gc_data.desc_short); + tmp2 = strip_html(&wpt->gc_data.desc_long); + gs = xstrappend(gs, tmp1); + gs = xstrappend(gs, tmp2); + + tmp3 = rot13(wpt->gc_data.hint); + snprintf(tbuf, sizeof(tbuf), "\n\nHint: %s\n", tmp3); + gs = xstrappend(gs, tbuf); + + xfree(tmp1); + xfree(tmp2); + xfree(tmp3); + + tmp1 = enscape(gs); + xfree(gs); + + return tmp1; +} + +static void +geoniche_writewpt(const waypoint *wpt) +{ + int vlen; + char *vdata; + char *title; + struct tm tm; + char datestr[10+1]; + char timestr[8+1]; + char *notes; + int id; + time_t tx; + char *gs; + + if (rec_ct == 0) { + pdb_write_rec(file_out, 0, 0, ct++, Rec0Magic, sizeof(Rec0Magic)); + } + + if ( wpt->description && wpt->description[0] ) + title = enscape(wpt->description); + else + title = enscape(wpt->shortname); + + id = gid2id(wpt->shortname); + if (id < 0) + id = rec_ct; + + tx = (wpt->creation_time != 0) ? wpt->creation_time : gpsbabel_time; + if (tx == 0) { /* maybe zero during testo (freezed time) */ + strcpy(datestr, "01/01/1904"); /* this seems to be the uninitialized date value for geoniche */ + strcpy(timestr, "00:00:00"); + } + else { + tm = *localtime(&tx); + strftime(datestr, sizeof(datestr), "%m/%d/%Y", &tm); + strftime(timestr, sizeof(timestr), "%H:%M:%S", &tm); + } + + /* Notes field MUST have soemthing in it */ + if (!wpt->notes || wpt->notes[0] == 0) + notes = xstrdup(title); + else + notes = enscape(wpt->notes); + + gs = geoniche_geostuff(wpt); + if (gs) { + notes = xstrappend(notes, gs); + xfree (gs); + } + /* last chance to fill notes with something */ + if (*notes == '\0') notes = xstrappend(notes, "(notes)"); + + vlen = xasprintf(&vdata, + "Target,%d,%s,,%s,%f,%f,%f,%s,%s,,,,%d,,,,%s" + , id + , title + /* route ID */ + , Arg_category ? Arg_category : "Cache" + , wpt->latitude + , wpt->longitude + , wpt->altitude + , datestr + , timestr + /* visited date */ + /* visited time */ + /* icon color R G B */ + , wpt2icon(wpt) + /* unused1 */ + /* unused2 */ + /* unused3 */ + , notes + ); + + pdb_write_rec(file_out, 0, 0, ct++, vdata, vlen + 1); + + xfree(notes); + xfree(title); + xfree(vdata); + + rec_ct++; +} + +static void +data_write(void) +{ + if (Arg_dbname) { + if (case_ignore_strcmp(Arg_dbname, "GeoNiche Targets") == 0) + fatal(MYNAME ": Reserved database name!\n"); + strncpy(file_out->name, Arg_dbname, PDB_DBNAMELEN); + } + else + strncpy(file_out->name, FilenameOut, PDB_DBNAMELEN); + file_out->name[PDB_DBNAMELEN-1] = 0; + + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + (49*365 + 17*366) * (60*60*24); + file_out->type = MYTYPE_ASC; + file_out->creator = MYCREATOR; + file_out->version = 0; + file_out->revision = 1; + + rec_ct = 0; + ct = 0; + waypt_disp_all(geoniche_writewpt); +} + + +ff_vecs_t geoniche_vecs = +{ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + Args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ +}; +#endif diff --git a/ggv_log.c b/ggv_log.c new file mode 100644 index 000000000..ef31cba31 --- /dev/null +++ b/ggv_log.c @@ -0,0 +1,276 @@ +/* + + Support for "GeoGrid Viewer" binary tracklogs (*.log) + + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include + +#include "defs.h" +#include "grtcirc.h" +#include "jeeps/gpsmath.h" + +#define MYNAME "ggv_log" + +static gbfile *fin, *fout; +static int ggv_log_ver; + +static +arglist_t ggv_log_args[] = { + ARG_TERMINATOR +}; + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +ggv_log_rd_init(const char *fname) +{ + static char magic[32]; + int len = 0; + + fin = gbfopen(fname, "rb", MYNAME); + + for (;;) { + int cin; + + cin = gbfgetc(fin); + if (cin < 0) break; + + magic[len++] = cin; + + if (cin == '\0') { + double ver = 0; + char *sver; + if (strncmp(magic, "DOMGVGPS Logfile V", 18) != 0) break; + + sver = &magic[18]; + sscanf(sver, "%lf:", &ver); + ggv_log_ver = ver * 10; + if ((ggv_log_ver == 10) || (ggv_log_ver == 25)) return; /* header accepted */ + + fatal(MYNAME ": Sorry, unsupported version (%s)!\n", sver); + } + else if (len == sizeof(magic)) + break; + } + fatal(MYNAME ": Invalid header. Probably no " MYNAME " file!\n"); +} + +static void +ggv_log_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +ggv_log_read(void) +{ + signed char *buf; + int bufsz = 0, len; + route_head *trk = NULL; + + switch(ggv_log_ver) { + case 10: bufsz = 0x2A; break; + case 25: bufsz = 0x6F; break; + } + + buf = xmalloc(bufsz); + + while ((len = gbfread(buf, 1, bufsz, fin))) { + int deg, min; + double xlat, xlon; + float sec; + struct tm tm; + waypoint *wpt; + + if (len != bufsz) break; + + if (trk == NULL) { + trk = route_head_alloc(); + track_add_head(trk); + } + + memset(&tm, 0, sizeof(tm)); + + wpt = waypt_new(); + + deg = (gbint16) le_read16(&buf[0]); + min = le_read16(&buf[2]); + sec = le_read_float(&buf[4]); + xlat = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0); + wpt->latitude = xlat; + + deg = (gbint16) le_read16(&buf[8]); + min = le_read16(&buf[10]); + sec = le_read_float(&buf[12]); + xlon = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0); + wpt->longitude = xlon; + + WAYPT_SET(wpt, course, le_read16(&buf[16 + 0])); + + if (ggv_log_ver == 10) { + double secs; + + wpt->altitude = le_read16(&buf[16 + 2]); + WAYPT_SET(wpt, speed, le_read16(&buf[16 + 4])); + tm.tm_year = le_read16(&buf[16 + 8]); + tm.tm_mon = le_read16(&buf[16 + 10]); + tm.tm_mday = le_read16(&buf[16 + 12]); + tm.tm_hour = le_read16(&buf[16 + 14]); + tm.tm_min = le_read16(&buf[16 + 16]); + secs = le_read_double(&buf[16 + 18]); + tm.tm_sec = (int)secs; + wpt->microseconds = (secs - tm.tm_sec) * 1000000; + } + else { + wpt->altitude = le_read16(&buf[16 + 4]); + wpt->sat = (unsigned char)buf[16 + 14]; + + /* other probably valid double values at offset: + + 22: 0.0 - 20.0 + 43: 0.0 - 59.0 + 51: -1.0 + 61: -1.0 + 79: .. - 20.0 ? speed over ground ? (++) + 87: ? course ? + 95: 0.0 - 3.1 (++) + 103: -1 + + */ + } + + if (wpt->altitude == 0) + wpt->altitude = unknown_alt; + + if (tm.tm_year >= 1900) { + tm.tm_year -= 1900; + if (tm.tm_mon > 0) { + tm.tm_mon--; + wpt->creation_time = mkgmtime(&tm); + } + } + + track_add_wpt(trk, wpt); + } + xfree(buf); +} + +static void +ggv_log_wr_init(const char *fname) +{ + fout = gbfopen(fname, "wb", MYNAME); + + gbfputcstr("DOMGVGPS Logfile V1.0:", fout); +} + +static void +ggv_log_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +ggv_log_track_head_cb(const route_head *trk) +{ + queue *elem, *tmp; + waypoint *prev = NULL; + + QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { + double latmin, lonmin, latsec, lonsec; + int latint, lonint; + double course = 0, speed = 0; + struct tm tm; + waypoint *wpt = (waypoint *)elem; + double secs = 0; + + latint = wpt->latitude; + lonint = wpt->longitude; + latmin = 60.0 * (fabs(wpt->latitude) - latint); + lonmin = 60.0 * (fabs(wpt->longitude) - lonint); + latsec = 60.0 * (latmin - floor(latmin)); + lonsec = 60.0 * (lonmin - floor(lonmin)); + + if (wpt->creation_time > 0) { + tm = *gmtime(&wpt->creation_time); + tm.tm_mon += 1; + tm.tm_year += 1900; + } + else + memset(&tm, 0, sizeof(tm)); + + if (prev != NULL) { + course = heading_true_degrees( + prev->latitude, prev->longitude, + wpt->latitude, wpt->longitude); + speed = waypt_speed(prev, wpt); + } + if (wpt->creation_time > 0) + secs = (double)tm.tm_sec + ((double)wpt->microseconds / 1000000); + + gbfputint16((gbint16) latint, fout); + gbfputint16((gbint16) latmin, fout); + gbfputflt(latsec, fout); + gbfputint16((gbint16) lonint, fout); + gbfputint16((gbint16) lonmin, fout); + gbfputflt(lonsec, fout); + gbfputint16((gbint16) course, fout); + gbfputint16((gbint16) (wpt->altitude != unknown_alt) ? wpt->altitude : 0, fout); + gbfputint16((gbint16) speed, fout); + gbfputint16(0, fout); + gbfputint16(tm.tm_year, fout); + gbfputint16(tm.tm_mon, fout); + gbfputint16(tm.tm_mday, fout); + gbfputint16(tm.tm_hour, fout); + gbfputint16(tm.tm_min, fout); + gbfputdbl(secs, fout); + + prev = wpt; + } +} + +static void +ggv_log_write(void) +{ + track_disp_all(ggv_log_track_head_cb, NULL, NULL); +} + +/**************************************************************************/ + +ff_vecs_t ggv_log_vecs = { + ff_type_file, + { + ff_cap_none, /* waypoints */ + ff_cap_read | ff_cap_write, /* tracks */ + ff_cap_none /* routes */ + }, + ggv_log_rd_init, + ggv_log_wr_init, + ggv_log_rd_deinit, + ggv_log_wr_deinit, + ggv_log_read, + ggv_log_write, + NULL, + ggv_log_args, + CET_CHARSET_ASCII, 1 +}; +/**************************************************************************/ diff --git a/globals.c b/globals.c new file mode 100644 index 000000000..3891a45e7 --- /dev/null +++ b/globals.c @@ -0,0 +1,31 @@ +/* + Global data for GPSBabel. + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +#include "defs.h" +#include "gbversion.h" + +global_options global_opts; +const char gpsbabel_version[] = VERSION; +time_t gpsbabel_now; /* gpsbabel startup-time; initialized in main.c with time() */ +time_t gpsbabel_time; /* gpsbabel startup-time; initialized in main.c with current_time(), ! ZERO within testo ! */ + +posn_status tracking_status; diff --git a/glogbook.c b/glogbook.c new file mode 100644 index 000000000..8a8d738c2 --- /dev/null +++ b/glogbook.c @@ -0,0 +1,182 @@ +/* + Access Garmin Logbook (Forerunner/Foretracker) data files. + + Copyright (C) 2004, 2005, 2006, 2007 Robert Lipe, robertlipe@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "xmlgeneric.h" + +static gbfile *ofd; +static waypoint *wpt_tmp; +static route_head *trk_head; + + +#define MYNAME "glogbook" + +static +arglist_t glogbook_args[] = { + ARG_TERMINATOR +}; + +/* Tracks */ +static xg_callback gl_trk_s; +// static xg_callback gl_trk_ident; +static xg_callback gl_trk_pnt_s, gl_trk_pnt_e; +static xg_callback gl_trk_utc; +static xg_callback gl_trk_lat; +static xg_callback gl_trk_long; +static xg_callback gl_trk_alt; + +static xg_tag_mapping gl_map[] = { + { gl_trk_s, cb_start, "/History/Run/Track" }, + { gl_trk_pnt_s,cb_start, "/History/Run/Track/Trackpoint/Position" }, + { gl_trk_pnt_e,cb_end, "/History/Run/Track/Trackpoint/Position" }, + { gl_trk_lat, cb_cdata, "/History/Run/Track/Trackpoint/Position/Latitude" }, + { gl_trk_long, cb_cdata, "/History/Run/Track/Trackpoint/Position/Longitude" }, + { gl_trk_alt, cb_cdata, "/History/Run/Track/Trackpoint/Position/Altitude" }, + { gl_trk_utc, cb_cdata, "/History/Run/Track/Trackpoint/Time" }, + { NULL, 0, NULL} +}; + +static void +glogbook_rd_init(const char *fname) +{ + xml_init(fname, gl_map, NULL); +} + +static void +glogbook_read(void) +{ + xml_read(); +} + +static void +glogbook_rd_deinit(void) +{ + xml_deinit(); +} + +static void +glogbook_wr_init(const char *fname) +{ + ofd = gbfopen(fname, "w", MYNAME); +} + +static void +glogbook_wr_deinit(void) +{ + gbfclose(ofd); +} + +static void +glogbook_waypt_pr(const waypoint *wpt) +{ + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " %.5f\n", wpt->latitude); + gbfprintf(ofd, " %.5f\n", wpt->longitude); + if (wpt->altitude != unknown_alt) { + gbfprintf(ofd, " %.3f\n", wpt->altitude); + } + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " "); + xml_write_time(ofd, wpt->creation_time, wpt->microseconds, "Time"); + gbfprintf(ofd, " \n"); +} + +static void +glogbook_hdr( const route_head *rte) +{ + gbfprintf(ofd, " \n"); +} + +static void +glogbook_ftr(const route_head *rte) +{ + gbfprintf(ofd, " \n"); +} + +static void +glogbook_write(void) +{ + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, " \n"); + track_disp_all(glogbook_hdr, glogbook_ftr, glogbook_waypt_pr); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, "\n"); +} + +void gl_trk_s(const char *args, const char **unused) +{ + trk_head = route_head_alloc(); + track_add_head(trk_head); +} +#if 0 +void gl_trk_ident(const char *args, const char **unused) +{ + trk_head->rte_name = xstrdup(args); +} +#endif + +void gl_trk_pnt_s(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); +} + +void gl_trk_pnt_e(const char *args, const char **unused) +{ + track_add_wpt(trk_head, wpt_tmp); +} + +void gl_trk_utc(const char *args, const char **unused) +{ + wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); +} + +void gl_trk_lat(const char *args, const char **unused) +{ + wpt_tmp->latitude = atof(args); +} + +void gl_trk_long(const char *args, const char **unused) +{ + wpt_tmp->longitude = atof(args); +} + +void gl_trk_alt(const char *args, const char **unused) +{ + wpt_tmp->altitude = atof(args); +} + + + +ff_vecs_t glogbook_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none}, + glogbook_rd_init, + glogbook_wr_init, + glogbook_rd_deinit, + glogbook_wr_deinit, + glogbook_read, + glogbook_write, + NULL, + glogbook_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/google.c b/google.c new file mode 100644 index 000000000..889405696 --- /dev/null +++ b/google.c @@ -0,0 +1,562 @@ +/* + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "xmlgeneric.h" + +static char *encoded_points = NULL; +static char *encoded_levels = NULL; +static char *script = NULL; +static route_head **routehead; +static int *routecount; +static short_handle desc_handle; + +static int serial = 0; + +#define MYNAME "google" +#define MY_CBUF 4096 + +#if ! HAVE_LIBEXPAT +static void +google_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded Google Maps support because expat was not installed.\n"); +} + +static void +google_read(void) +{ +} +#else + +static xg_callback goog_points, goog_levels, goog_poly_e, goog_script; +static xg_callback goog_segment_s, goog_segment, goog_td_s, goog_td_b; +static xg_callback goog_td_e; + +static +xg_tag_mapping google_map[] = { + { goog_points, cb_cdata, "/page/directions/polyline/points" }, + { goog_levels, cb_cdata, "/page/directions/polyline/levels" }, + { goog_poly_e, cb_end, "/page/directions/polyline" }, + { goog_script, cb_cdata, "/html/head/script" }, + { goog_segment_s, cb_start, "/page/directions/segments/segment" }, + { goog_segment, cb_cdata, "/page/directions/segments/segment" }, + { goog_td_s, cb_start, "/div/table/tr/td" }, + { goog_td_s, cb_start, "/div/div/table/tr/td" }, + { goog_td_b, cb_cdata, "/div/table/tr/td/b" }, + { goog_td_b, cb_cdata, "/div/div/table/tr/td/b" }, + { goog_td_e, cb_end, "/div/table/tr/td" }, + { goog_td_e, cb_end, "/div/div/table/tr/td" }, + { NULL, 0, NULL } +}; + +void goog_script( const char *args, const char **unused ) +{ + if (args) + { + if ( script ) + { + script = xstrappend( script, args ); + } + else + { + script = xstrdup( args ); + } + } +} + +void goog_points( const char *args, const char **unused ) +{ + if (args) + { + if ( encoded_points ) + { + encoded_points = xstrappend( encoded_points, args ); + } + else + { + encoded_points = xstrdup(args); + } + } +} + +void goog_levels( const char *args, const char **unused ) +{ + if (args) + { + if ( encoded_levels ) + { + encoded_levels = xstrappend( encoded_levels, args ); + } + else + { + encoded_levels = xstrdup(args); + } + } +} + +static char goog_segname[7]; +static char *goog_realname = NULL; +static int goog_segroute = 0; + +/* + * The segments contain an index into the points array. We use that + * index to find the waypoint and insert a better name for it. + */ +void goog_segment_s( const char *args, const char **attrv ) +{ + const char **avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "pointIndex")) { + snprintf(goog_segname, sizeof(goog_segname), "\\%5.5x", atoi(avp[1])); + } + avp += 2; + } + +} + +void goog_segment( const char *args, const char **unused ) +{ + waypoint *wpt_tmp; + + wpt_tmp = route_find_waypt_by_name( routehead[goog_segroute], goog_segname); + if (wpt_tmp) { + xfree(wpt_tmp->shortname); + wpt_tmp->shortname = mkshort(desc_handle,args); + wpt_tmp->description = xstrdup(args); + } +} + +void goog_td_s( const char *args, const char **attrv ) +{ + const char **avp = &attrv[0]; + int isdesc = 0; + int isseg = 0; + while (*avp) { + if ( 0 == strcmp(avp[0], "class" )) { + isdesc = !strcmp(avp[1], "desc" ); + isseg = !strcmp(avp[1], "dirsegtext" ); + } + else if ( isdesc && (0 == strcmp( avp[0], "id" ))) { + goog_segroute = 0; + snprintf( goog_segname, sizeof(goog_segname), + "\\%5.5x", + atoi(avp[1] + 6 )); + } + else if ( isseg && (0 == strcmp( avp[0], "id" ))) { + if ( strchr(strchr(avp[1],'_')+1,'_')) { + goog_segroute = atoi(strchr(avp[1],'_')+1); + } + else { + goog_segroute = 0; + } + snprintf( goog_segname, sizeof(goog_segname), + "\\%5.5x", + atoi(strrchr( avp[1],'_') + 1 )+routecount[goog_segroute]); + } + avp += 2; + } +} + +void goog_td_b( const char *args, const char **attrv ) { + if ( goog_segname[0] == '\\' && !strchr( args, '\xa0')) { + if ( goog_realname ) { + xfree( goog_realname ); + goog_realname = NULL; + } + goog_realname = xmalloc( strlen(args)+1); + strcpy( goog_realname, args ); + } +} +void goog_td_e( const char *args, const char **attrv ) +{ + if ( goog_segname[0] == '\\' && goog_realname ) { + goog_segment( goog_realname, attrv ); + } + goog_segname[0] = '\0'; + if ( goog_realname ) { + xfree( goog_realname ); + goog_realname = NULL; + } +} + +static long decode_goog64( char **str ) +{ + long result = 0; + unsigned char c = 0; + unsigned char shift = 0; + + if ( !(**str)) { + return 0; + } + + do + { + c = (unsigned char)(*(*str)++)-'?'; + result |= (c & 31)<latitude = lat / 100000.0; + wpt_tmp->longitude = lon / 100000.0; + wpt_tmp->route_priority=level; + wpt_tmp->shortname = (char *) xmalloc(7); + sprintf( wpt_tmp->shortname, "\\%5.5x", serial++ ); + route_add_wpt(routehead[goog_segroute], wpt_tmp); + } + } + +} + +static void +google_rd_init(const char *fname) +{ + desc_handle = mkshort_new_handle(); + setshort_length(desc_handle, 12); + + xml_init(fname, google_map, "ISO-8859-1" ); +} + +static void +google_read(void) +{ + routehead = (route_head **)xmalloc(sizeof(route_head *)); + routecount = (int *)xmalloc(sizeof(int)); + goog_segroute = 0; + xml_read(); + xfree( routehead ); + xfree( routecount ); + + if ( encoded_points ) + { + xfree( encoded_points ); + encoded_points = NULL; + } + if ( encoded_levels ) + { + xfree( encoded_levels ); + encoded_levels = NULL; + } + if ( script ) + { + char *xml = strchr( script, '\'' ); + char *dict = strstr( script, "({" ); + + char *end = NULL; + + if ( xml && (!dict || (xml < dict ))) { + routehead = (route_head **)xmalloc(sizeof(route_head *)); + routecount = (int *)xmalloc(sizeof(int)); + goog_segroute = 0; + xml++; + end = strchr( xml+1, '\'' ); + if ( end ) { + *end = '\0'; + xml_deinit(); + xml_init( NULL, google_map, NULL ); + xml_readstring( xml ); + if ( encoded_points ) + { + xfree( encoded_points ); + encoded_points = NULL; + } + if ( encoded_levels ) + { + xfree( encoded_levels ); + encoded_levels = NULL; + } + } + } + else if ( dict ) { + char qc = '\''; + int ofs = 9; + int panelofs = 8; + int count = 0; + char *tmp = NULL; + char *start = NULL; + + char *panel = strstr( dict, "panel: '" ); + encoded_points = strstr( dict, "points: '" ); + encoded_levels = strstr( dict, "levels: '" ); + if ( !encoded_points ) { + ofs = 10; + qc = '"'; + encoded_points = strstr( dict, "\"points\":\"" ); + encoded_levels = strstr( dict, "\"levels\":\"" ); + if ( !encoded_points ) { + encoded_points = strstr(dict, "points:\"" ); + encoded_levels = strstr(dict, "levels:\"" ); + ofs = 8; + } + } + + if ( !panel ) { + panel = strstr( dict, "panel:\""); + panelofs = 7; + } + tmp = panel; + while ( tmp ) { + if ( qc == '"' ) { + char *tmp1 = strstr( tmp, "\"points\":\"" ); + if ( !tmp1 ) { + tmp1 = strstr( tmp, "points:\"" ); + } + tmp = tmp1; + } + else { + tmp = strstr( tmp, "points: '" ); + } + count++; + if ( tmp ) { + tmp++; + } + } + routehead = (route_head **)xmalloc(sizeof(route_head *)*count); + routecount = (int *)xmalloc(sizeof(int)*count); + goog_segroute = 0; + + do { + + if ( encoded_points && encoded_levels ) { + encoded_points += ofs; + encoded_levels += ofs; + end = strchr( encoded_points, qc ); + if ( end ) { + *end = '\0'; + end = encoded_points; + while ( (end = strstr(end, "\\\\" ))) { + memmove( end, end+1, strlen(end)+1 ); + end++; + } + end = strchr( encoded_levels, qc ); + if ( end ) { + start = end; + *end = '\0'; + end = encoded_levels; + while ( (end = strstr(end, "\\\\" ))) { + memmove( end, end+1, strlen(end)+1 ); + end++; + } + goog_poly_e( NULL, NULL ); + + goog_segroute++; + start++; + { + encoded_points = strstr( start, "points: '" ); + encoded_levels = strstr( start, "levels: '" ); + } + if ( !encoded_points ) { + encoded_points = strstr( start, "\"points\":\"" ); + encoded_levels = strstr( start, "\"levels\":\"" ); + } + if ( !encoded_points ) { + encoded_points = strstr( start, "points:\"" ); + encoded_levels = strstr( start, "levels:\"" ); + } + } + } + } + } while ( start && encoded_points && encoded_levels ); + if ( panel ) { + panel += panelofs; + end = strstr( panel, "/table>
"); + } + if ( !end ) { + end = strstr( panel, "/div>
"); + } + } + if ( end ) { + char *to = panel; + char *from = panel; + while ( *from ) { + if ( !strncmp( from, "\\\"", 2 )) { + *to++ = '"'; + from += 2; + if ( *(to-2) != '=' ) { + *to++ = ' '; + } + } + else if ( !strncmp( from, "\\042", 4)) { + *to++ = '"'; + from += 4; + + if ( *(to-2) != '=' ) { + *to++ = ' '; + } + } + else if ( !strncmp( from, "\\u0026utm", 9)) { + strcpy( to, "&utm" ); + to += 8; + from += 9; + } + else if ( !strncmp( from, "\\u0026", 6 )) { + *to++='&'; + from += 6; + } + else if ( !strncmp( from, "\\u003c", 6 )) { + *to++='<'; + from += 6; + } + else if ( !strncmp( from, "\\u003e", 6 )) { + *to++='>'; + from += 6; + } + else if ( !strncmp( from, "\\x", 2)) { + unsigned int c; + sscanf(from+2, "%2x", &c); + *to++ = (char)c; + from += 4; + } + else if ( !strncmp( from, "\\'", 2)) { + *to++ = '\''; + from += 2; + } + else if ( !strncmp( from, " nowrap ", 8)) { + *to++ = ' '; + from += 8; + } + else if ( !strncmp( from, "tr style=\\\"display:none", 23 )) { + if ( strcmp( to-5, "/tr><" )) { + /* broken 6-26-07 missing that apparently doesn't bother browsers */ + strcpy(to, "/tr><" ); + to += 5; + } + *to++ = *from++; + } + else { + *to++ = *from++; + } + } + *to = '\0'; + +#if 0 + { + FILE *foo = fopen( "foo.xml", "w" ); + fprintf(foo, "\n", xhtml_entities ); + fwrite( panel, sizeof(char), strlen(panel), foo ); + fclose( foo ); + } +#endif + + xml_deinit(); + xml_init( NULL, google_map, NULL ); + xml_readprefixstring( "" ); + xml_readstring( panel ); + } + } + } + xfree( script ); + xfree( routehead ); + xfree( routecount ); + script = NULL; + } + + /* + * 'Tis better to leak than crash when we are merging and + * don't see an 'end' in the first file. This feels a bit + * like plastering over a deeper problem... + * + */ + if ( encoded_points ) { + encoded_points = NULL; + } + if ( encoded_levels ) { + encoded_levels = NULL; + } +} +#endif + +static void +google_rd_deinit(void) +{ + xml_deinit(); + mkshort_del_handle(&desc_handle); +} + +ff_vecs_t google_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none}, + google_rd_init, + NULL, + google_rd_deinit, + NULL, + google_read, + NULL, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* CET-REVIEW */ +}; diff --git a/gpilots.c b/gpilots.c new file mode 100644 index 000000000..f7ada83b3 --- /dev/null +++ b/gpilots.c @@ -0,0 +1,439 @@ +/* + Read and write GPilotS files. + + Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "pdbfile.h" +#include "garmin_tables.h" + +#define MYNAME "GPilotS" +#define MYWPT 0x57707473 /* Wpts */ +#define MYTRK 0x54726b73 /* Trks */ +#define MYRTE 0x57707473 /* Wpts */ +#define MYCREATOR 0x4750696c /* GPil */ + + +/* + * Structures grafted from http://www.cru.fr/perso/cc/GPilotS/ + */ + + +typedef struct +{ + long lat; /* latitude in semicircles */ + long lon; /* longitude in semicircles */ +} +Semicircle_Type; + +typedef struct +{ + char ident[6]; /* identifier */ + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + unsigned char unused[4]; /* should be set to zero */ + char cmnt[40]; /* comment */ + unsigned char smbl; /* symbol id */ + unsigned char dspl; /* display option */ +} D103_Wpt_Type; + +typedef union { + float f; + unsigned int i; +} fi_t; + +typedef struct /* size */ +{ + unsigned char wpt_class; /* class (see below) 1 */ + unsigned char color; /* color (see below) 1 */ + unsigned char dspl; /* display options (see below) 1 */ + unsigned char attr; /* attributes (see below) 1 */ + unsigned char smbl[2]; /* waypoint symbol 2 */ + unsigned char subclass[18]; /* subclass 18 */ + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + float alt; /* altitude in meters 4 */ + float dpth; /* depth in meters 4 */ + float dist; /* proximity distance in meters 4 */ + char state[2]; /* state 2 */ + char cc[2]; /* country code 2 */ + char varlenstrs[1]; /* start of variable length strings */ + /* G_char ident[]; variable length string 1-51 */ + /* G_char comment[]; waypoint user comment 1-51 */ + /* G_char facility[]; facility name 1-31 */ + /* G_char city[]; city name 1-25 */ + /* G_char addr[]; address number 1-51 */ + /* G_char cross_road[]; intersecting road label 1-51 */ +} +D108_Wpt_Type; + +typedef struct /* structure de waypoint "interne" */ +{ + unsigned char ident[51]; /* identifier (50 + '0') */ + Semicircle_Type posn; /* position (common to all Garmin types) */ + unsigned char cmnt[51]; /* comment (50 + '0') */ + float dst; /* proximity distance */ + float alt; /* altitude */ + int smbl; /* symbol id */ + unsigned char dspl; /* display option */ + unsigned char color; /* color */ +} +Custom_Wpt_Type; + +typedef struct /* internal track header */ +{ + char name[256]; /* nom du groupe de trackpoints */ + unsigned char dspl; /* display on the map ? */ + unsigned char color; /* color */ + unsigned char type; /* type of following track points */ + unsigned char unused; /* type of following track points */ + unsigned char number[2]; /* number of track points */ + unsigned char latmin[4]; /* latitude min */ + unsigned char latmax[4]; /* latitude max */ + unsigned char lonmin[4]; /* longitude min */ + unsigned char lonmax[4]; /* longitude max */ + unsigned char unused2[2]; /* type of following track points */ +} +Custom_Trk_Hdr_Type; + +typedef struct +{ + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + unsigned char time[4]; + unsigned char alt[4]; + unsigned char new_trk; + unsigned char unused; +} Custom_Trk_Point_Type; + +typedef struct /* custom compact track point type */ +{ + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + unsigned char new_trk; + unsigned char unused; +} Compact_Trk_Point_Type; /* size : 10 bytes */ + +struct record +{ + struct { + unsigned char type; + unsigned short size; + unsigned int version; + } header; + union { + D103_Wpt_Type d103; + D108_Wpt_Type d108; + Custom_Wpt_Type CustWpt; + Custom_Trk_Hdr_Type CustTrkHdr; +#if LATER + Custom_Rte_Hdr_Type CustRteHdr; +#endif + } wpt; +}; + + +static pdbfile *file_in, *file_out; +static const char *out_fname; +static int ct = 0; +static char *dbname = NULL; + +static +arglist_t my_args[] = { + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +static void +rd_init(const char *fname) +{ + file_in = pdb_open(fname, MYNAME); +} + +static void +rd_deinit(void) +{ + pdb_close(file_in); + if ( dbname ) { + xfree(dbname); + dbname = NULL; + } +} + +static void +wr_init(const char *fname) +{ + file_out = pdb_create(fname, MYNAME); + out_fname = fname; +} + +static void +wr_deinit(void) +{ + pdb_close(file_out); + if ( dbname ) { + xfree(dbname); + dbname = NULL; + } +} + +static void +data_read(void) +{ + struct record *rec; + pdbrec_t *pdb_rec; + route_head *track_head = NULL; + + if (file_in->creator != MYCREATOR) { + fatal(MYNAME ": Not a %s file.\n", MYNAME); + } + + switch(file_in->type) { + case MYWPT: + /* blah */ + break; + case MYTRK: + /* blah */ + break; + default: + fatal(MYNAME ": Unknown file type 0x%x\n", (int) file_in->type); + } + + for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec=pdb_rec->next) { + waypoint *wpt_tmp; + Custom_Trk_Point_Type *tp_cust; + Compact_Trk_Point_Type *tp_comp; + int lat; + int lon; + int sz; + fi_t fi; + int trk_num = 0; + int trk_seg_num = 1; + char trk_seg_num_buf[10]; + char *trk_name = ""; + + wpt_tmp = waypt_new(); + + rec = (struct record *) pdb_rec->data; + switch(rec->header.type) { + /* + * G103Type + */ + case 4: + wpt_tmp->shortname = xstrndupt(rec->wpt.d103.ident, sizeof(rec->wpt.d103.ident)); + wpt_tmp->description = xstrndupt(rec->wpt.d103.cmnt, sizeof(rec->wpt.d103.cmnt)); + /* This is odd. This is a Palm DB file, + * yet the data appears to be little endian, + * not appropriate the the actual Palm. + */ + lon = le_read32(&rec->wpt.d103.lon); + lat = le_read32(&rec->wpt.d103.lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + waypt_add(wpt_tmp); + break; + /* + * G108Type + */ + case 9: + wpt_tmp->shortname = xstrndupt(rec->wpt.d108.varlenstrs, 50); + wpt_tmp->description = xstrndupt(rec->wpt.d108.varlenstrs + strlen(wpt_tmp->shortname) + 1, 50); + /* This is odd. This is a Palm DB file, + * yet the data appears to be little endian, + * not appropriate the the actual Palm. + */ + lon = le_read32(&rec->wpt.d108.lon); + lat = le_read32(&rec->wpt.d108.lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + fi.i = le_read32(&rec->wpt.d108.alt); + wpt_tmp->altitude = fi.f; + fi.i = le_read32(&rec->wpt.d108.dpth); + WAYPT_SET(wpt_tmp, depth, fi.f); + fi.i = le_read32(&rec->wpt.d108.dist); + WAYPT_SET(wpt_tmp, proximity, fi.f); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 0; + wpt_tmp->icon_descr = gt_find_desc_from_icon_number((rec->wpt.d108.smbl[1] << 8) + rec->wpt.d108.smbl[0], PCX, NULL); + waypt_add(wpt_tmp); + break; + + /* + * CustomTrkHdr + */ + case 101: + trk_name = rec->wpt.CustTrkHdr.name; + sz = be_read16(&rec->wpt.CustTrkHdr.number); + + /* switch between custom track points and compact track points. + * (compact points have no altitude and time info. + */ + switch (rec->wpt.CustTrkHdr.type) { + case 102: + tp_cust = (Custom_Trk_Point_Type *) ((char *) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr)); + while (sz--) { + if ((int)(tp_cust->new_trk) == 1 || trk_seg_num == 1) { + /* + * Start a new track segment + */ + track_head = route_head_alloc(); + if (trk_seg_num == 1) { + track_head->rte_name = xstrdup(trk_name); + } else { + /* name in the form TRACKNAME #n */ + snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); + track_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); + sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); + } + trk_seg_num++; + track_head->rte_num = trk_num; + trk_num++; + track_add_head(track_head); + } + + wpt_tmp = waypt_new(); + + /* This is even more odd. + * Track data is stored as big endian while + * waypoint data is little endian!? + */ + lon = be_read32(&tp_cust->lon); + lat = be_read32(&tp_cust->lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + /* + * Convert Garmin/GPilotS time format to gpsbabel time format. + * Garmin/GPilotS count seconds from "UTC 12:00 AM December 31 1989". + * gpsbabel counts seconds from "UTC 12:00 AM January 1 1970". + */ + wpt_tmp->creation_time = be_read32(&tp_cust->time) + 631065600; + fi.i = be_read32(&tp_cust->alt); + wpt_tmp->altitude = fi.f; + track_add_wpt(track_head, wpt_tmp); + tp_cust++; + } + break; + case 104: + tp_comp = (Compact_Trk_Point_Type *) ((char *) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr)); + while (sz--) { + if ((int)(tp_comp->new_trk) == 1 || trk_seg_num == 1) { + /* + * Start a new track segment + */ + track_head = route_head_alloc(); + if (trk_seg_num == 1) { + track_head->rte_name = xstrdup(trk_name); + } else { + /* name in the form TRACKNAME #n */ + snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); + track_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); + sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); + } + trk_seg_num++; + track_head->rte_num = trk_num; + trk_num++; + track_add_head(track_head); + } + + wpt_tmp = waypt_new(); + lon = be_read32(&tp_comp->lon); + lat = be_read32(&tp_comp->lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + track_add_wpt(track_head, wpt_tmp); + tp_comp++; + } + break; + default: + fatal(MYNAME ": track point type %d not supported.\n", rec->wpt.CustTrkHdr.type); + } + break; + default: + fatal(MYNAME ": input record type %d not supported.\n", rec->header.type); + } + + } +} + + +struct hdr{ + char *wpt_name; + waypoint *wpt; +}; + +static void +my_write_wpt(const waypoint *wpt) +{ + struct record *rec; + char *vdata; + int lat, lon; + + rec = xcalloc(sizeof *rec, 1); + vdata = (char *)rec + sizeof (*rec); + + rec->header.type = 4; + strncpy(rec->wpt.d103.ident, wpt->shortname, sizeof(rec->wpt.d103.ident)); + strncpy(rec->wpt.d103.cmnt, wpt->description, sizeof(rec->wpt.d103.cmnt)); + lat = wpt->latitude / 180.0 * 2147483648.0; + lon = wpt->longitude / 180.0 * 2147483648.0; + le_write32(&rec->wpt.d103.lat, lat); + le_write32(&rec->wpt.d103.lon, lon); + + pdb_write_rec(file_out, 0, 0, ct++, rec, (char *)vdata - (char *)rec); + xfree(rec); +} + +static void +data_write(void) +{ + if ( dbname ) { + strncpy( file_out->name, dbname, PDB_DBNAMELEN ); + } else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + + /* + * Populate header. + */ + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + + file_out->type = MYWPT; + file_out->creator = MYCREATOR; + file_out->version = 1; + + waypt_disp_all(my_write_wpt); +} + + +ff_vecs_t gpilots_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + my_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; +#endif diff --git a/gpsbabel-sample.ini b/gpsbabel-sample.ini new file mode 100644 index 000000000..743e9d704 --- /dev/null +++ b/gpsbabel-sample.ini @@ -0,0 +1,35 @@ +;------------------------------------------------------------------ +[Common format settings] +# snlen = 6 + +;------------------------------------------------------------------ +[Common filter settings] + +;------------------------------------------------------------------ +[Garmin categories] +; any # from 1 to 16 + +1 = Biker Stuff +2 = Slow food +3 = Fast food +16 = Fixed + +;------------------------------------------------------------------ +[ garmin_txt ] +Date = DD.MM.YYYY +Time = HH:mm:ss XX +Dist = M +Temp = C +Prec = 6 + +[ gdb ] +via = 1 + +;------------------------------------------------------------------ +[ tiger ] +snlen=7 + +;------------------------------------------------------------------ +[pathaway] +# dbname = The Last Trip +deficon = Golf Course diff --git a/gpsbabel.html b/gpsbabel.html new file mode 100644 index 000000000..bbdf18a2a --- /dev/null +++ b/gpsbabel.html @@ -0,0 +1,5473 @@ + +GPSBabel Documentation

GPSBabel Documentation


Table of Contents

Introduction
The Problem: Too many incompatible GPS file formats
The Solution
1. Getting it and Building it
2. Usage
Invocation
Suboptions
Advanced Usage
Route and Track Modes
Working with predefined options
Realtime tracking
Batch mode (command files)
3. The Formats
? Character Separated Values (xcsv)
Alan Map500 tracklogs (.trl) (alantrl)
Alan Map500 waypoints and routes (.wpr) (alanwpr)
All database fields on one tab-separated line (tabsep)
Brauniger IQ Series Barograph Download (baroiq)
Cambridge/Winpilot glider software (cambridge)
CarteSurTable data file (cst)
Cetus for Palm/OS (cetus)
CoastalExplorer XML (coastexp)
Comma separated values (csv)
CompeGPS data files (.wpt/.trk/.rte) (compegps)
CoPilot Flight Planner for Palm/OS (copilot)
cotoGPS for Palm/OS (coto)
Custom "Everything" Style (custom)
Dell Axim Navigation System (.gpb) file format (axim_gpb)
DeLorme .an1 (drawing) file (an1)
DeLorme GPL (gpl)
DeLorme Street Atlas Plus (saplus)
DeLorme Street Atlas Route (saroute)
DeLorme XMap HH Native .WPT (xmap)
DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)
DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)
Destinator Itineraries (.dat) (destinator_itn)
Destinator Points of Interest (.dat) (destinator_poi)
Destinator TrackLogs (.dat) (destinator_trl)
EasyGPS binary format (easygps)
Embedded Exif-GPS data (.jpg) (exif)
FAI/IGC Flight Recorder Data Format (igc)
Franson GPSGate Simulation (gpssim)
Fugawi (fugawi)
G7ToWin data files (.g7t) (g7towin)
Garmin 301 Custom position and heartrate (garmin301)
Garmin Logbook XML (glogbook)
Garmin MapSource - gdb (gdb)
Garmin MapSource - mps (mapsource)
Garmin MapSource - txt (tab delimited) (garmin_txt)
Garmin PCX5 (pcx)
Garmin POI database (garmin_poi)
Garmin Points of Interest (.gpi) (garmin_gpi)
Garmin serial/USB protocol (garmin)
Garmin Training Centerxml (gtrnctr)
Geocaching.com .loc (geo)
GeocachingDB for Palm/OS (gcdb)
Geogrid Viewer tracklogs (.log) (ggv_log)
GEOnet Names Server (GNS) (geonet)
GeoNiche .pdb (geoniche)
GlobalSat DG-100/BT-335 Download (dg-100)
Google Earth (Keyhole) Markup Language (kml)
Google Maps XML (google)
GpilotS (gpilots)
GPS TrackMaker (gtm)
GPSBabel arc filter file (arc)
GpsDrive Format (gpsdrive)
GpsDrive Format for Tracks (gpsdrivetrack)
GPSman (gpsman)
GPSPilot Tracker for Palm/OS (gpspilot)
gpsutil (gpsutil)
GPX XML (gpx)
HikeTech (hiketech)
Holux (gm-100) .wpo Format (holux)
HSA Endeavour Navigator export File (hsandv)
HTML Output (html)
IGN Rando track files (ignrando)
Kartex 5 Track File (ktf2)
Kartex 5 Waypoint File (kwf2)
Kompass (DAV) Track (.tk) (kompass_tk)
Kompass (DAV) Waypoints (.wp) (kompass_wp)
KuDaTa PsiTrex text (psitrex)
Lowrance USR (lowranceusr)
Magellan Explorist Geocaching (maggeo)
Magellan Mapsend (mapsend)
Magellan NAV Companion for Palm/OS (magnav)
Magellan SD files (as for eXplorist) (magellanx)
Magellan SD files (as for Meridian) (magellan)
Magellan serial protocol (magellan)
MagicMaps IK3D project file (.ikt) (ik3d)
Map&Guide 'TourExchangeFormat' XML (tef)
Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)
Mapopolis.com Mapconverter CSV (mapconverter)
MapTech Exchange Format (mxf)
Microsoft AutoRoute 2002 (pin/route reader) (msroute)
Microsoft Streets and Trips (pin/route reader) (msroute)
Microsoft Streets and Trips 2002-2007 (s_and_t)
Motorrad Routenplaner (Map&Guide) .bcr files (bcr)
MS PocketStreets 2002 Pushpin (psp)
MTK Logger (iBlue 747,...) Binary File Format (mtk-bin)
MTK Logger (iBlue 747,Qstarz BT-1000,...) download (mtk)
National Geographic Topo .tpg (waypoints) (tpg)
National Geographic Topo 2.x .tpo (tpo2)
National Geographic Topo 3.x/4.x .tpo (tpo3)
Navicache.com XML (navicache)
Navigon Mobile Navigator .rte files (nmn4)
NaviGPS GT-11/BGT-11 Download (navilink)
Navitrak DNA marker format (dna)
NetStumbler Summary File (text) (netstumbler)
NIMA/GNIS Geographic Names File (nima)
NMEA 0183 sentences (nmea)
Nokia Landmark Exchange (lmx)
OpenStreetMap data files (osm)
OziExplorer (ozi)
PalmDoc Output (palmdoc)
PathAway Database for Palm/OS (pathaway)
Quovadis (quovadis)
Raymarine Waypoint File (.rwf) (raymarine)
See You flight analysis data (cup)
Sportsim track files (part of zipped .ssz files) (sportsim)
Suunto Trek Manager (STM) .sdf files (stmsdf)
Suunto Trek Manager (STM) WaypointPlus files (stmwpp)
Swiss Map # (.xol) format (xol)
Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)
Textual Output (text)
TomTom Itineraries (.itn) (tomtom_itn)
TomTom POI file (.asc) (tomtom_asc)
TomTom POI file (.ov2) (tomtom)
TopoMapPro Places File (tmpro)
TrackLogs digital mapping (.trl) (dmtlog)
U.S. Census Bureau Tiger Mapping Service (tiger)
Universal csv with field structure in first line (unicsv)
Vcard Output (for iPod) (vcard)
VidaOne GPS for Pocket PC (.gpb) (vidaone)
Vito Navigator II tracks (vitosmt)
Vito SmartMap tracks (.vtt) (vitovtt)
WiFiFoFum 2.0 for PocketPC XML (wfff)
Wintec WBT-100/200 Binary File Format (wbt-bin)
Wintec WBT-100/200 GPS Download (wbt)
Wintec WBT-201/G-Rays 2 Binary File Format (wbt-tk1)
Yahoo Geocode API data (yahoo)
4. Data Filters
Include Only Points Inside Polygon (polygon)
Include Only Points Within Distance of Arc (arc)
Include Only Points Within Radius (radius)
Interpolate between trackpoints (interpolate)
Manipulate track lists (track)
Rearrange waypoints by resorting (sort)
Remove all waypoints, tracks, or routes (nuketypes)
Remove Duplicates (duplicate)
Remove Points Within Distance (position)
Remove unreliable points with high hdop or vdop (discard)
Reverse stops within routes (reverse)
Save and restore waypoint lists (stack)
Simplify routes (simplify)
Transform waypoints into a route, tracks into routes, ... (transform)
A. Supported Datums
B. Garmin Icons
C. GPSBabel XCSV Style Files
Introduction
Style file overview
Internal Constants
Global Properties of the File
GPSBabel Behavior Directives
Defining the Layout of the File
Defining Fields Within the File
Examples
Miscellaneous Notes
Glossary

List of Examples

2.1. Command showing Linux download from Magellan serial and writing to .loc file
2.2. Command showing Windows download from Magellan serial and writing to .loc file
2.3. Merging multiple files into one
2.4. Merging multiple files of differing types.
2.5. Writing the same data in multiple output formats.
2.6. Read realtime positioning from Garmin USB, write to Keyhole Markup
3.1. Example 'csv' file
3.2. Example for gdb bitcategory option to put all waypoints in categories 1 and 16.
3.3. Using gdb option roadbook to create simple html roadbook
3.4. Command showing garmin_txt output with all options
3.5. Command showing garmin_gpi output example
3.6. Read GPX file, create GPI to alert when you're 1/2 mile from a speed camera.
3.7. Example for garmin bitcategory option to put all waypoints in categories 1 and 16.
3.8. Command showing DG-100 download and erase on Linux
3.9. Sample BCR command with all options
3.10. Convert MTK binary trackpoints to GPX
3.11. Command showing MTK download track and waypoints and erase on Linux
3.12. Example for splitoutput option to text format
3.13. Command showing conversion of a Wintec binary file to GPX
3.14. Command showing WBT-200 download and erase over Bluetooth on Mac OS X
3.15. Command showing conversion of a Wintec binary file to GPX
4.1. Using the polygon filter
4.2. Using the polygon and arc filters to find points in or nearly in a +polygon
4.3. Using the arc filter
4.4. Using the radius filter to find points close to a given point
4.5. Using the interpolate filter
4.6. Time-shifting a track with the track filter
4.7. Merging tracks with the track filter
4.8. Extracting a period of time with the track filter
4.9. Filtering data types with nuketypes
4.10. Using the duplicate filter to suppress points with the same + name and location
4.11. Using the duplicate filter to implement an "ignore list."
4.12. Using the duplicate filter to correct the locations of "puzzle" +geocaches
4.13. Using the position filter to suppress close points
4.14. Using the discard filter for HDOP and VDOP.
4.15. Using the discard filter to require at least three satellites.
4.16. Converting a track to a sequence of waypoints
4.17. Converting a pile of waypoints to a GPX route
4.18. Converting a pile of waypoints to a GPX track
4.19. Convert a GPX track to GPX waypoints, tossing the original track

Introduction

The Problem: Too many incompatible GPS file formats

There are simply too many gratuitously different file formats +to hold waypoint, track, and route information in various programs +used by computers and GPS receivers. +GPX defines a +standard in XML to contain all the data, but there are too many +programs that don't understand it yet and too much data in +alternate formats. +

+Perhaps you have an Explorist 600 and your friend has a StreetPilot 2720. +You've collected a a list of your favorite locations as waypoints and you'd +like to be able to share them. Unfortunately, his copy of Garmin Mapsource +won't read data created by your copy of Magellan Mapsend DirectRoute. What you need +is a program that converts data bewteen the two programs. +

+GPSBabel actually solves that problem for you and much more... +

The Solution

The original author of GPSBabel, Robert Lipe, needed to convert waypoints between a couple of formats, so he +whipped up a converter and designed it upon an extensible foundation so +that it was easy to add new formats and made the program freely available. Many others have contributed to the program since then.

Most file formats added so far have taken under 200 + lines of reasonable ISO C so they can be stamped + out pretty trivially. Formats that are ASCII text delimited in some + fixed way can be added with no programming at all via our + style mechanism. +

Chapter 1. Getting it and Building it

+GPSBabel is distributed "ready to run" on most common +operating systems via the +download page. +

As GPSBabel runs on a wide variety of operating systems, +be sure to visit the +OS-Specific notes for +additional information. +

+ For operating systems where no binary is provided or if +you want the latest development version, you will have to build it from +source. The code should be compilable on any system with +ISO C89 compilers. It's been tested on UnixWare, OpenServer, OS/X, +Linux, Solaris, and a variety of processors and compilers. +

+ In most cases, the code is as simple to build as running: +

./configure && make

Expat +is strongly recommended for source builds as it is +required for reading all the XML formats such as GPX. Fedora users +may need to 'yum install expat-devel'. Ubuntu users may need to +'apt-get install expat libexpat-dev'. +

libusb +is recommended for OS/X and Linux if you want to use a USB Garmin. +Fedora users may need to 'yum install expat-devel'. Ubuntu users may +need to 'apt-get install libusb-dev'. +

There are additional flags that can be passed to configure to + customize your build of GPSBabel. +

./configure --help

+lists all the supported options, but of interest we have:

+ --disable-shapefile Excludes the shapefile support. +

+ --disable-pdb Excludes the Palm database support and all formats that rely on it. +

+ --disable-csv Excludes all support for our something-separated formats. +

+ --disable-filters Excludes all filter support. +

+ --enable-efence Activate debugging mode for gpsbabel-debug. +

+ --with-doc=dir Specifies that the doc should be created and installed in dir. +

+ --without-libusb Disables use of libusb, even it's it's available. +

+ --with-zlib=(included)|system|no By default, we use our own version of zlib. If you specify system the system zlib is used. A value of no (or --without-zlib) disables zlib. +

Chapter 2. Usage

Invocation

+If you're using GPSBabel, you will need to know how to do at least two things: +read data from a file, and write it to another file. There are four basic +options you need to know to do those things: +

CommandMeaning
-i formatSet input format
-f filenameRead file
-o formatSet output format
-F filenameWrite output file

Important

+Case matters. Notably -f (lowercase) sets the input file. -F (uppercase) sets the output file. +

+The format parameters in the above list +refer to the names of formats or file types supported by GPSBabel. +

gpsbabel -?

will always show you the supported file types. In this document, the +various supported formats are listed in Chapter 3, The Formats. The +name that you would use on the command line follows the format name in +parentheses. +

+Options are always processed in order from left to right. +In practical terms, this means that things you want to read should appear +in the command before things you want to write. This sometimes surprises +new users as adding options to turn on debugging at the end, for example, +doesn't work as the debugging is turned on after all the interesting work is +done. The reason for this strict ordering becomes more apparent once you +learn about mixing formats and filters. +

+The filename parameters specify the +name of a file to be read or written. +

To use + GPSBabel in its simplest form, just tell it what you're reading, where to read + it from, what you're writing, and what to write it to. For + example:

gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx

tells it to read the file /tmp/geocaching.loc in geocaching.com + format and create a new file /tmp/geocaching.gpx in GPX format. It's important to note that the names have nothing to do with the formats actually used.

This command will read from a Magellan unit attached + to the first serial port on a Linux system (device names will + vary on other OSes; typically COMx: on WIndows) and write them as a geocaching loc file.

Example 2.1. Command showing Linux download from Magellan serial and writing to .loc file

gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc


This second command does the same on Microsoft Windows.

Example 2.2. Command showing Windows download from Magellan serial and writing to .loc file

gpsbabel -i magellan -f com1 -o geo -F mag.loc


Optionally, you may specify -s in any command line. This + causes the program to ignore any "short" names that may be + present in the source data format and synthesize one from the + long name. This is particularly useful if you're writing to + a target format that isn't the lowest common denominator but + the source data was written for the lowest common + denominator. This is useful for writing data from geocaching.com + to a GPS so my waypoints have "real" names instead of + the 'GC1234' ones that are optimized for receivers of the lowest + common denominator. + A geocacher using Linux with a Magellan receiver may thus find commands + like this useful.

gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0

His counterpart on Windows will find this equivalent

gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1

Suboptions

+ Many of the available format options in GPSBabel can themselves + take options. While we try to make all the formats do the most + sensible thing possible without any extra options; this allows + great power and flexibility in the operation of the program. +

+ Suboptions are comma separated and immediately follow the option + itself. The available suboptions are listed on the individual + format pages. We'll make an example from the section called “Google Earth (Keyhole) Markup Language (kml)”: +

gpsbabel -i gpx -f file.gpx -o kml,deficon="file://myicon.png",lines=0 -F one.kml -o kml -F two.kml

+ This command will read the GPX file file.gpx + and create two KML files. one.kml will + have the given icon and no lines between track and routepoints. + two.kml will be created with the defaults used + in the KML writer. +

+ Suboptions for the various formats allow you to change serial speeds, + pass arguments to filters, change the type of file written, override + icon defaults, and lots of other things. The suboptions for each + filetype are documented on the page in this document that describes + the option itself. +

Advanced Usage

Argument are processed in the order they appear on the command +line and are translated internally into a pipeline that data flows +through when executed. Normally one would:

read from one input
optionally apply filters
write into one output

but GPSBabel is flexible enough to allow more complicated +operations such as reading from several files (potentially of +different types), applying a filter, reading more data, then writing the +merged data to multiple destinations. +

The input file type remains unchanged until a new + -i argument is seen. + Files are read in the order they appear. So you could merge + three input files into one output file with:

Example 2.3. Merging multiple files into one

gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc


You can merge files of different types:

Example 2.4. Merging multiple files of differing types.

gpsbabel -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx -o gpsutil -F big.gps


Example 2.5. Writing the same data in multiple output formats.

You can write the same data in different output formats:

gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx -F 1.wpt


If you want to change the character set of input or/and + output side you can do this with the option -c + <character set>. You can get a complete list + of supported character sets with "gpsbabel -l". To change + the character set on both sides you should do this:

gpsbabel -i xcsv,style=foo.style -c latin1 -f foo -o xcsv,style=bar.style -c ms-ansi -F bar

Note, that some formats have a fixed character set and ignore this option.

Route and Track Modes

Most formats supported by GPSBabel will make a reasonable attempt to work + transparently with waypoints, tracks, and routes. Some + formats, like garmin and magellan require the -t flag to work with tracks and + -r to work with + routes. -w is for + waypoints, and is the default. So if you wanted to read all + data from a Magellan Meridian GPS receiver into a gpx file, you might use a command + like:

gpsbabel -t -r -w -i magellan -f com1: -o gpx -F backup.gpx

Tracks and routes are advanced features and don't try + to handle every possible hazard that can be encountered + during a conversion. If you're merging or converting files + of similar limitations, things work very well.

Many of those hazards can be overcome with our filters + but there are often compromises to be made. For example, if you + have a GPX route that contains 150 turn points but you're sending + the route to a GPS receiver that supports only 30 turnpoints, something has + to go. One might use our 'simplify' filter to produce a route that + retained the 30 most mathematically significant turnpoints but that + may not really be the route you had in mind. +

Tracks and routes will sometimes be converted to a + list of waypoints when necessary, One example is when writing into one + of the CSV formats. The inverse operation is not supported + right now, so reading the converted track back from CSV will + always result in a list of waypoints, not the original track. +

The presence of -s on the command line tends to + creats havoc on tracks and routes since many of these formats + rely on internal linkages between such points and renaming + them may break those linkages. In general, don't use + -s when tracks or + routes are present. +

Working with predefined options

+ GPSBabel can read a file on startup to set defaults for options. All + module and filter options may be set this way. +

+ The format of the file is identical to the inifile-format often seen + on Windows. Here is an example: +

[Common format settings]
snupper=Y
snlen=10
[gpx]
gpxver=1.1
[magellan]
baud=115200
[tiger]
[Garmin categories]
; any # from 1 to 16
1=fixed waypoints
2=temporary waypoints

+ Each section of the file starts with a '[section]' header followed by any + number of lines formatted option=value. Leading and trailing whitespace + will be + automatically removed from header, option and value items. + + Lines starting + with '#' or ';' will be treated as comments and ignored. +

+ There are three optional sections. +

  • Common format settings.

    Any option from any of the formats listed here will be used by + GPSBabel unless explictly provided on the command line. +

  • Common filter settings.

    As above, but for filters.

  • Garmin categories

    This allows you to give readable names to the numeric categories + used internally in some Garmin devices and the Mapsource formats + such as GDB and MPS. This is information is also used by our GPX + and garmin_txt formats as well.

+

+ By default, GPSBabel tries at startup to load the file named + gpsbabel.ini from the following locations: +

  • current working directory

  • Windows: all paths "APPDATA", "WINDIR", "SYSTEMROOT" declared in environment.

  • Unix like OS'ses: ${HOME}/.gpsbabel/, /usr/local/etc/ and /etc/

+ If the -p option is specified, the above locations are not searched. + Only the filename specified by that option will be used. +

+ There may be situations where predefined values are not useable + (i.e. wrapper applications using GPSBabel in the background). + The inifile mechanism can be disabled with an empty filename. +

gpsbabel -p "" -i gpx -f something.gpx -o tiger -F -

Realtime tracking

+ Introduced in GPSBabel 1.3.1, we now have an experimental feature for realtime tracking via the new -T option. This reads position reports from selected formats and writes an output file when a position report is received. +

+ As of this writing, Garmin's PVT protocol and NMEA are supported + inputs. KML, NMEA, and the variou XCSV formats are supported on + output. Additional formats may be added by interested parties + later. +

Example 2.6. Read realtime positioning from Garmin USB, write to Keyhole Markup

gpsbabel -T -i garmin -f usb: -o kml -F xxx.kml


+ Will read the USB-connected Garmin and rewrite 'xxx.kml' atomically, + suitable for a self-refreshing network link in Google Earth. +

Batch mode (command files)

+ In addition to reading arguments from the command line, GPSBabel can + read directions from batch (or command) files via the -b option. +

+ These files are ideal for holding long command lines, long file lists, complex filters + and so on. You can use all GPSBabel options and combinations when writing + such files. Nesting batch files by using the -b option within a batch file is supported. +

+ Here is an example demonstrating segmenting a large command line + by placing the input and filtering directives in a file called 'all_my_files'. +

gpsbabel -b all_my_files -o gdb -F all_my_tracks.gdb

+ 'all_my_files' could look like this: +

-i gpx
-f saxony_in_summer_2004.gpx -f austria_2005.gpx
-i gdb
-f croatia_2006.gdb
-x nuketypes,waypoints,routes
-x track,pack,split,title="LOG # %Y%m%d"

Chapter 3. The Formats

Table of Contents

? Character Separated Values (xcsv)
Alan Map500 tracklogs (.trl) (alantrl)
Alan Map500 waypoints and routes (.wpr) (alanwpr)
All database fields on one tab-separated line (tabsep)
Brauniger IQ Series Barograph Download (baroiq)
Cambridge/Winpilot glider software (cambridge)
CarteSurTable data file (cst)
Cetus for Palm/OS (cetus)
CoastalExplorer XML (coastexp)
Comma separated values (csv)
CompeGPS data files (.wpt/.trk/.rte) (compegps)
CoPilot Flight Planner for Palm/OS (copilot)
cotoGPS for Palm/OS (coto)
Custom "Everything" Style (custom)
Dell Axim Navigation System (.gpb) file format (axim_gpb)
DeLorme .an1 (drawing) file (an1)
DeLorme GPL (gpl)
DeLorme Street Atlas Plus (saplus)
DeLorme Street Atlas Route (saroute)
DeLorme XMap HH Native .WPT (xmap)
DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)
DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)
Destinator Itineraries (.dat) (destinator_itn)
Destinator Points of Interest (.dat) (destinator_poi)
Destinator TrackLogs (.dat) (destinator_trl)
EasyGPS binary format (easygps)
Embedded Exif-GPS data (.jpg) (exif)
FAI/IGC Flight Recorder Data Format (igc)
Franson GPSGate Simulation (gpssim)
Fugawi (fugawi)
G7ToWin data files (.g7t) (g7towin)
Garmin 301 Custom position and heartrate (garmin301)
Garmin Logbook XML (glogbook)
Garmin MapSource - gdb (gdb)
Garmin MapSource - mps (mapsource)
Garmin MapSource - txt (tab delimited) (garmin_txt)
Garmin PCX5 (pcx)
Garmin POI database (garmin_poi)
Garmin Points of Interest (.gpi) (garmin_gpi)
Garmin serial/USB protocol (garmin)
Garmin Training Centerxml (gtrnctr)
Geocaching.com .loc (geo)
GeocachingDB for Palm/OS (gcdb)
Geogrid Viewer tracklogs (.log) (ggv_log)
GEOnet Names Server (GNS) (geonet)
GeoNiche .pdb (geoniche)
GlobalSat DG-100/BT-335 Download (dg-100)
Google Earth (Keyhole) Markup Language (kml)
Google Maps XML (google)
GpilotS (gpilots)
GPS TrackMaker (gtm)
GPSBabel arc filter file (arc)
GpsDrive Format (gpsdrive)
GpsDrive Format for Tracks (gpsdrivetrack)
GPSman (gpsman)
GPSPilot Tracker for Palm/OS (gpspilot)
gpsutil (gpsutil)
GPX XML (gpx)
HikeTech (hiketech)
Holux (gm-100) .wpo Format (holux)
HSA Endeavour Navigator export File (hsandv)
HTML Output (html)
IGN Rando track files (ignrando)
Kartex 5 Track File (ktf2)
Kartex 5 Waypoint File (kwf2)
Kompass (DAV) Track (.tk) (kompass_tk)
Kompass (DAV) Waypoints (.wp) (kompass_wp)
KuDaTa PsiTrex text (psitrex)
Lowrance USR (lowranceusr)
Magellan Explorist Geocaching (maggeo)
Magellan Mapsend (mapsend)
Magellan NAV Companion for Palm/OS (magnav)
Magellan SD files (as for eXplorist) (magellanx)
Magellan SD files (as for Meridian) (magellan)
Magellan serial protocol (magellan)
MagicMaps IK3D project file (.ikt) (ik3d)
Map&Guide 'TourExchangeFormat' XML (tef)
Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)
Mapopolis.com Mapconverter CSV (mapconverter)
MapTech Exchange Format (mxf)
Microsoft AutoRoute 2002 (pin/route reader) (msroute)
Microsoft Streets and Trips (pin/route reader) (msroute)
Microsoft Streets and Trips 2002-2007 (s_and_t)
Motorrad Routenplaner (Map&Guide) .bcr files (bcr)
MS PocketStreets 2002 Pushpin (psp)
MTK Logger (iBlue 747,...) Binary File Format (mtk-bin)
MTK Logger (iBlue 747,Qstarz BT-1000,...) download (mtk)
National Geographic Topo .tpg (waypoints) (tpg)
National Geographic Topo 2.x .tpo (tpo2)
National Geographic Topo 3.x/4.x .tpo (tpo3)
Navicache.com XML (navicache)
Navigon Mobile Navigator .rte files (nmn4)
NaviGPS GT-11/BGT-11 Download (navilink)
Navitrak DNA marker format (dna)
NetStumbler Summary File (text) (netstumbler)
NIMA/GNIS Geographic Names File (nima)
NMEA 0183 sentences (nmea)
Nokia Landmark Exchange (lmx)
OpenStreetMap data files (osm)
OziExplorer (ozi)
PalmDoc Output (palmdoc)
PathAway Database for Palm/OS (pathaway)
Quovadis (quovadis)
Raymarine Waypoint File (.rwf) (raymarine)
See You flight analysis data (cup)
Sportsim track files (part of zipped .ssz files) (sportsim)
Suunto Trek Manager (STM) .sdf files (stmsdf)
Suunto Trek Manager (STM) WaypointPlus files (stmwpp)
Swiss Map # (.xol) format (xol)
Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)
Textual Output (text)
TomTom Itineraries (.itn) (tomtom_itn)
TomTom POI file (.asc) (tomtom_asc)
TomTom POI file (.ov2) (tomtom)
TopoMapPro Places File (tmpro)
TrackLogs digital mapping (.trl) (dmtlog)
U.S. Census Bureau Tiger Mapping Service (tiger)
Universal csv with field structure in first line (unicsv)
Vcard Output (for iPod) (vcard)
VidaOne GPS for Pocket PC (.gpb) (vidaone)
Vito Navigator II tracks (vitosmt)
Vito SmartMap tracks (.vtt) (vitovtt)
WiFiFoFum 2.0 for PocketPC XML (wfff)
Wintec WBT-100/200 Binary File Format (wbt-bin)
Wintec WBT-100/200 GPS Download (wbt)
Wintec WBT-201/G-Rays 2 Binary File Format (wbt-tk1)
Yahoo Geocode API data (yahoo)

? Character Separated Values (xcsv)

+ This format can... +

  • + read and write waypoints +

+This format is a very flexible module that can be used to read or write +nearly any plain-text record-based waypoint file. This flexibility is +achieved by combining this format with "style" files that describe the +format of the waypoint files. +

+There are several formats built in to GPSBabel that use the underlying xcsv +machinery. Each of those formats takes the same options as the xcsv format, +with the obvious exception of the style option. +Those formats are all based on style files that can be found in +the "style" directory in the GPSBabel source distribution. +

style option

+ Full path to XCSV style file. +

+This option specifies the style file that defines the records to be read on +input or written on output. This is not a valid option for the various +built-in xcsv-based styles; they have prebuilt style definitions. +

+For information on the format of xcsv style files, see +Appendix C, GPSBabel XCSV Style Files. +

snlen option

+ Max synthesized shortname length. +

+This option specifies the maximum allowable length for a short name on +output. This option overrides the style file. +

+Valid values for this option are 0 (off) and 1 (on). +

snwhite option

+ Allow whitespace synth. shortnames. +

+When this option is specified, GPSBabel will allow whitespace (spaces or tabs) +in generated short names. This option overrides the style file. +

+Valid values for this option are 0 (off) and 1 (on). +

snupper option

+ UPPERCASE synth. shortnames. +

+When this option is specified, GPSBabel will make all short names contain +only UPPERCASE characters. This option overrides the style file. +

+Valid values for this option are 0 (off) and 1 (on). +

snunique option

+ Make synth. shortnames unique. +

+When this option is specified, GPSBabel will ensure that all short names are +unique within the output file. This option overrides the style file. +

+Valid values for this option are 0 (off) and 1 (on). +

urlbase option

+ Basename prepended to URL on output. +

+This option specifies the base name to prepend to a URL on output. This +might be useful if an input file contains URLs in a relative format and you +need them to be in an absolute format. +

prefer_shortnames option

+ Use shortname instead of description. +

+This option causes GPSBabel to use the short name of the waypoint instead +of the description. This overrides the style file. +

+Valid values for this option are 0 (off) and 1 (on). +

datum option

+ GPS datum (def. WGS 84). +

+This option specifies the GPS datum to be used on read or write. Valid values for this +option are listed in Appendix A, Supported Datums. +

Alan Map500 tracklogs (.trl) (alantrl)

+ This format can... +

  • + read and write tracks +

+GPSBabel supports .wpr and .trl files for Alan Map500 devices running operating +system versions 2.xx. +

+.trl contain files tracklogs. If you use a CF-Card based +operating system, tracklog files must have a .TRL extension when +copied to the CF-Card. The default filename is TEMP_TRK.TRL. +Only one .TRL file may be present. +

+Alan's operating system 3.0 for Map500 is not supported yet. +At the time of this writing, OS3 is still beta. +Documentation on the new dataformats is sparse. +

+The Alan Map500 handheld GPSr is identical to the Holux GM101. +This GPSBabel module has only been tested against the Alan Map500. +Still, if you use a GM101, GPSBabel will probably be able to convert +your waypoints, routes and tracklogs. +

+For more information on the Alan Map500 visit +Alan Germany. There is very informative forum, too. The forum language is German but posts in English will be answered, too. +

Alan Map500 waypoints and routes (.wpr) (alanwpr)

+ This format can... +

  • + read and write waypoints +

  • + read and write routes +

+GPSBabel supports .wpr and .trl files for Alan Map500 devices running operating +system versions 2.xx. +

+.wpr files contain waypoints and routes. If you use a CF-Card based +operating system, waypoint files must have a .WPR extension when +copied to the CF-Card. The default filename is TEMPWPRT.WPR. +Only one .WPR file may be present. +

+Alan's operating system 3.0 for Map500 is not supported yet. +At the time of this writing, OS3 is still beta. +Documentation on the new dataformats is sparse. +

+The Alan Map500 handheld GPSr is identical to the Holux GM101. +This GPSBabel module has only been tested against the Alan Map500. +Still, if you use a GM101, GPSBabel will probably be able to convert +your waypoints, routes and tracklogs. +

+For more information on the Alan Map500 visit +Alan Germany. There is very informative forum, too. Forum language is German but posts in English will be answered, +too. +

All database fields on one tab-separated line (tabsep)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+This format, like the custom format, is +mainly used for the purpose of testing GPSBabel. It is supposed to contain +one field for each piece of information supported by the +xcsv format writer, but it may not be entirely +in sync with the documentation at Appendix C, GPSBabel XCSV Style Files. +

+For a list of fields, see the style/tabsep.style file in the GPSBabel source +distribution. +

Brauniger IQ Series Barograph Download (baroiq)

+ This format can... +

  • + read tracks +

Serial download protocol for the Brauniger IQ series of +barograph recording flight instruments. This format creates a +track of altitude vs time which can be merged with a GPS track +of the same flight to create a three dimensional IGC file.

Cambridge/Winpilot glider software (cambridge)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Support for +Cambridge +and Winpilot + flight analysis and planning software for glider pilots.

CarteSurTable data file (cst)

+ This format can... +

  • + read waypoints +

  • + read tracks +

  • + read routes +

With this format we can read CarteSurTable data files. + CarteSurTable is a shareware program widely used in France. The data +inside have to be seen as a mixture of a waypoints list, one route and +several tracks. +

Cetus for Palm/OS (cetus)

+ This format can... +

  • + read and write waypoints +

  • + read tracks +

Cetus GPS is a program for +Palm/OS. Working with Ron Parker and Kjeld Jensen, we can now read +and write files for that program.

dbname option

+ Database name. +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

appendicon option

+ Append icon_descr to description. +

+This option will add the icon description to the end of the waypoint +description on output. This can be useful if the icon is used to convey +important information about the waypoint. For example, the icon might be +"found geocache" or "unfound geocache"; it might be useful to know that when +looking at a list of icons in Cetus. +

CoastalExplorer XML (coastexp)

+ This format can... +

  • + read and write waypoints +

  • + read and write routes +

This is the format used by CoastalExplorer™. The +format is XML with items uniquely identified by Windows-style UUIDs. +http://www.rosepointnav.com +

Comma separated values (csv)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

There are a billion variants of Comma Separated Value +data. This is the one specifically that makes Delorme S&A Deluxe 9™ happy. It's +also a very simple program and useful for many other programs like +spreadsheets.

CSV is also the correct format for + Lowrance MapCreate™, +their commercial mapping program, or GDM6 (their free waypoint +manager) for iFinder which is available at lowrance.com +

+ On write, this format writes simple "latitude, longitude" pairs, but +on read it will read anything supported by our human readable definition. +

+ For something-separated data that has headers identifying the various + fields, see our universal csv format. +

Example 3.1. Example 'csv' file

+35.97203, -87.13470, Mountain Bike Heaven by susy1313
+36.09068, -86.67955, The Troll by a182pilot & Family
+35.99627, -86.62012, Dive Bomber by JoGPS & family
+36.03848, -86.64862, FOSTER by JoGPS & Family
+

CompeGPS data files (.wpt/.trk/.rte) (compegps)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+CompeGPS™ data files are "character" separated text files like +the pcx format. "Character" means special data lines can have their +own separator. +

+Since release 6.1 of CompeGPS™, GPX is also a +supported import/export format for waypoints, routes and tracks. +

+For more information please have a look at +http://www.compegps.com +

deficon option

+ Default icon name. +

+This option specifies the default icon name on output. +

index option

+ Index of route/track to write (if more the one in source). +

+Because this format supports only one route or track, this option may be used +on output to select a single route or track from a collection of routes and +tracks read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. +

gpsbabel -i gpx -f routes.gpx -o compegps,index=1 -F route1.txt -o compegps,index=2 -F route2.txt

radius option

+ Give points (waypoints/route points) a default radius (proximity). +

+This option specifies the default proximity for waypoints and route points. +

snlen option

+ Length of generated shortnames (default 16). +

+This option specifies the default length for short names generated on output. +The default length is 16. +

CoPilot Flight Planner for Palm/OS (copilot)

+ This format can... +

  • + read and write waypoints +

This code is mostly intended to convert CoPilot Flight +Planner for Palm/OS" databases into other formats. You probably should +not use this to write CoPilot databases, although the code is there, +because GPSBabel doesn't convert magnetic declination values.

This version now reads all CoPilot file versions up to 4, but only +writes version 4 files. If you have a need for a version flag, please let +me know.

Questions, bug reports, etc, to ptomblin at +xcski.com

+ http://xcski.com/~ptomblin/CoPilot/ +and http://navaid.com/CoPilot +

cotoGPS for Palm/OS (coto)

+ This format can... +

  • + read and write waypoints +

  • + read tracks +

+This format supports cotoGPS™, a Palm™ GPS program. +It can read both track and marker (waypoint) files. It is currently unable +to write track files, so only marker files can be written. The marker +categories are written to and read from the icon description. The 'Not +Assigned' category leaves the icon description empty on read. +Currently geocache info is ignored. +

In addition to the documented options, this format also has a +debugging option called internals which takes an XCSV +delimiter value. It writes some internal values (distance, arc, x and y) +of the cotoGPS track format to the notes field. +

+Contributed by Tobias Minich. +

+cotoGPS +

zerocat option

+ Name of the 'unassigned' category. +

+This option specifies a name for the "Not Assigned" category in the Palm +database. The default is "Not Assigned". +

Custom "Everything" Style (custom)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+This format is not actually used by any real product. It is most useful +for debugging purposes when developing a new format module for GPSBabel. +

+To understand the contents of this file, look at the +style/custom.style file in the GPSBabel source +distribution as well as Appendix C, GPSBabel XCSV Style Files. +

Dell Axim Navigation System (.gpb) file format (axim_gpb)

+ This format can... +

  • + read tracks +

+ This format reads the binary (.gpb) track logs recorded on + Dell Axim Navigation Systems. +

+ This is a read-only format for now as the format was reverse + engineered and there are many unknown bytes. We can successfully + extract the common GPS data. +

DeLorme .an1 (drawing) file (an1)

+ This format can... +

  • + read and write waypoints +

  • + write tracks +

  • + read and write routes +

+This format supports the DeLorme ".an1" drawing file format. It can +currently be used to either read or write drawing files. If you use +this format to create drawing files with routes or waypoints from another +source, by default it will create "Red Flag" symbols for waypoints, and +thick red lines for routes or tracks. It is possible to merge two drawing +layers by doing something like this: +

gpsbabel -i an1 -f one.an1 -f two.an1 -o an1 -F merged.an1

+In this case, the merged data will contain all of the +properties of the original data. +

type option

+ Type of .an1 file. +

This option specifies the type of the drawing layer +to be created. The supported values are "drawing", "road", "trail", +"waypoint", or "track". If you do not specify a type, the default +will be either the type of the previous an1 file or "drawing" if there +is no previous file. This lets you merge, for example, two road layers +without having to specify "type=road" for the output.

road option

+ Road type changes. +

+If you are creating a road layer, you may use the "road" option, which +allows you to change the types of roads based on their names. You can +change multiple roads at the same time. Currently supported types are +

+

TypeMeaning
limitedLimited-access freeways
tollLimited-access toll highways
rampAccess ramps for limited-access highways
usNational highways (e.g. US routes)
primaryPrimary State/Provincial routes
stateState/Provincial routes
majorMajor Connectors
ferryFerry Routes
localLocal Roads
editableUser-drawn Roads

+

+GPSBabel defaults to creating editable roads. These are routed just like +local roads, but may be edited with the drawing tools in Street Atlas. +

+This option has a special format that is best demonstrated by example: +

 "road=I-599!limited!Beecher St.!major" 

+This option will cause any road named "I-599" to become a limited-access +highway and any road named "Beecher St." to become a major connector. Note +that roads that have had their types changed in this way are not editable +in Street Atlas, so make sure they are where you want them before you +change them, and make sure to keep a backup of your original road layer. +Note that the ! is a shell metacharacter in bash and possibly other shells, +so you may have to use single quotes or some other escape mechanism. +

+There is a tutorial on +how +to create an onramp for a limited access highway in Street Atlas USA +using GPSBabel. +

nogc option

+ Do not add geocache data to description. +

+If your original data contains geocaching-specific information such as +difficulty and terrain, GPSBabel will automatically include that information +in the waypoint descriptions in the generated drawing file. If you do not +want that, specify the "nogc" option on the command line: +

gpsbabel -i gpx -f 12345.gpx -o an1,nogc -F 12345.an1

nourl option

+ Do not add URLs to description. +

+If your original waypoint data contains URLs, GPSBabel will include them as +links in the generated drawing file. This causes the waypoint symbol to have +a blue border, and it causes the waypoint text to be drawn in blue with an +underline. +

+If you do not want this behavior, specify the "nourl" option on the command +line: +

gpsbabel -i gpx -f 12345.gpx -o an1,nourl -F 12345.an1

deficon option

+ Symbol to use for point data. +

+This option allows you to specify which symbol to use for points that +don't have a symbol already. It defaults to "Red Flag" but it accepts +any symbol name you can put in a DeLorme export file. To find the name +of a specific symbol in Street Atlas, let the mouse pointer hover over +it for a few seconds and the name will be displayed. +

color option

+ Color for lines or mapnotes. +

This option allows you to specify the color for +line or mapnote data. It accepts color names of the form "#FF0000" (red) or any +of the color names from the Cascading Style Sheets (CSS) +specification.

zoom option

+ Zoom level to reduce points. +

+This option specifies at what zoom level Street Atlas will begin showing +reduced versions of your symbols. The default is 10. Setting zoom to 0 will +disable this feature. Setting it to anything but the default will override +the zoom level specified on any waypoints that were read from an existing +an1 file; this is by design. +

wpt_type option

+ Waypoint type. +

+This option specifies how to represent point data in the draw file. +Valid waypoint types are "symbol", "text", "mapnote", "circle", and "image". +The default is "symbol". +

+If you specify a waypoint type of "image", you should make sure that the +icon descriptions of your waypoints are the full names, including drive letters +and full path, of image files in a format that works with your DeLorme +product. Note that this means that the .an1 file you generate will not work +on any computer that does not have those images in the same place; this is +part of the design of the an1 format and cannot be avoided. +

radius option

+ Radius for circles. +

+If the waypoint type is "circle", the "radius" option specifies +the radius of the circles. By default, this is in miles, but it may be +specified in kilometers by adding a 'k'. The default radius is 1/10 mile. +

DeLorme GPL (gpl)

+ This format can... +

  • + read and write tracks +

This is the 'gpl' format as used in Delorme mapping +products. It is a track format and contains little more than the +tracklog of a GPS that was attached while driving. frontiernet.net +

DeLorme Street Atlas Plus (saplus)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

This format is for Delorme Street Atlas USA 2004 Plus and later. +

For geocachers importing data from a tool like GSAK or +Spinner, import the file twice in XData. One will create a file with +the Cache description as a hyperlink on the flag. This can clutter up +the screen and when you try to zoom in, it causes problems. So the +second one will only have a flag. Thus you can turn off and on which +one you want to view. The first time you import the file, in the +assign field types, check the circle above Full Name and then next. +The second time you import the file do not check any circle and in the +second to last column, change URL to none and then click next. Use the +same name you used the first time but add -Flag to it. +

DeLorme Street Atlas Route (saroute)

+ This format can... +

  • + read tracks +

+This format reads route files from many Delorme mapping products. +It supports the anr, rte, and rtd formats as either tracks or +routes.

All options only apply to route files from newer (anr) +versions of DeLorme software; older versions didn't store the turn +information with the route. +

turns_important option

+ Keep turns if simplify filter is used. +

This option only makes sense in +conjunction with the 'simplify' filter. It ensures that the route +simplification process will remove the points corresponding to turns +only after it has removed all other route points. +

turns_only option

+ Only read turns; skip all other points. +

This option causes GPSBabel to read only the +waypoints associated with named turns. This should create a list of +waypoints that correspond to the itinerary from Street Atlas.

split option

+ Split into multiple routes at turns. +

This option causes GPSBabel to create separate +routes for each street, creating a new route at each turn point. For +obvious reasons, 'split' cannot be used at the same time as the +'turns_only' or 'turns_important' options.

controls option

+ Read control points as waypoint/route/none. +

This option lets you read the control points +(start, end, vias, and stops) for your route as well as the route +itself. The default for this option is 'none', which won't read the +control points. You may also specify 'waypoints', which reads the +control points as waypoints, or 'route', which creates an extra route +named 'control points' containing just the control points in order. +Note that if your goal is to create an arc or other CSV file, you +should use 'none' (or not use this option, which is the same +thing.)

times option

+ Synthesize track times. +

This option causes GPSBabel to read the route as if +it were a track, synthesizing times starting from the current time, using +the estimated travel times specified in your route file (you can change your +travel speeds in the DeLorme product you used to create the route file.)

DeLorme XMap HH Native .WPT (xmap)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Delorme TopoUSA/XMap Conduit is one of the bazillion +CSV variants +variants mentioned above. It's just like Delorme Streets & Atlas with the addition of +a completely pointless line at the beginning and end of the file. This +is the format used to hot-sync to XMap from withing TopoUSA. Done with +help of Dan Edwards.

DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Delorme XMap2006 Conduit is just like +XMap +, except there are + no spaces between fields and the coordinate format is slightly + different. The completely pointless header and footer lines + are the same, at least. Use this to create the XMapHHWptsSend.txt + file needed to sync to Street Atlas Handheld 2006.

Note that in order to keep from creating duplicates on your handheld, you must first remove the file "XMapWptsDB" from your handheld, restart SAHH2006 on the handheld to create an empty database, and THEN sync the new file.

DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+Delorme XMapHandHeld Street Atlas USA is another of the +billion CSV variants. +This is the format used by XmapHH SA USA on (at least) PocketPC O/S. +

+This XMap is not the same as the simpler +XMap format, which is used with Topo USA 4.0 +and XMapHH for Palm. +

+Delorme XMap Handheld .WPT for PocketPC is a bit of a kludge. This +chapter covers XMap Handheld Street Atlas USA edition. +

+XMap on the PocketPC stores its waypoints in individual .wpt files. +For example, waypoints generated by XMap on the PocketPC are stored +by default in the "My Documents" folder using the sequential names +"XMap1.wpt", "XMap2.wpt", ad nauseum. Needless to say, this is not very +efficient. +

+As writing multiple waypoint files is outside of the scope of GPSBabel, +GPSBabel chooses to write one big file, one waypoint per line. +Extracting lines from this file is left as an exercise for the end user. +A simple Perl script to handle this conversion is included at the end +of this chapter. +

+It should also be noted that reading multiple files +is indeed possible, but if you have more than a few points, it can be a task. +For example: +

gpsbabel -i xmapwpt -f Xmap1.wpt -f Xmap2.wpt -o mapsend -F mapsend.wpt

+will read the two Xmap .wpt files and write one mapsend file. This +is fine for a small handful of points, but could be quite cumbersome +for folks like me who have 100+ waypoints loaded into XMap. For *nix +folks, something as simple as: +

cat *.wpt > /tmp/foo.wpt +gpsbabel -i xmapwpt -f foo.wpt -o mapsend -F mapsend.wpt

+will do the trick just fine. +

+#!/full/path/to/perl
+$INPUTFILE = @ARGV[0];
+$TARGETDIR = @ARGV[1];
+$FILENAME  = @ARGV[2];
+
+if (! $FILENAME) {
+    print "Usage: xmap_split.pl " . 
+	"INPUT_FILE OUTPUT_DIRECTORY FILENAME_BASE\n";
+    print " (i.e. xmapl_split.pl points.wpt /tmp/points GPSB)\n";
+    print " (created GPSB0001-GPSBXXXX " .
+	" in /tmp/points/ from points.wpt)\n";
+    exit;
+}
+
+open (INFILE, $INPUTFILE) || die "Cannot open $INPUTFILE for read!\n";
+
+while (<INFILE>) {
+    $lc++;
+    $filename = sprintf("%s/Gpsb%04d.wpt", $TARGETDIR, $lc);
+
+    open (OUTFILE, ">$filename") || 
+	die "Cannot open $filename for write!\n";
+
+    print OUTFILE $_;
+
+    close(OUTFILE);
+}
+
+exit;
+
+

Contributed to GPSBabel by Alex Mottram.

Destinator Itineraries (.dat) (destinator_itn)

+ This format can... +

  • + read and write routes +

+ Support for Destinator™ itinerary files. +

+ These have (mostly) extension .dat and are binary files. The file structure is undocumented + and so this format was reverse engineered from some .dat files. + At this time we can read and write name, comment and the coordinates of the route points. +

+ Destinator™ by + Destinator Technologies + is a software for PNDs, Smartphones and PDAs. +

+ + gpsbabel -i destinator_itn -f from_A_to_B.dat -o gpx -F from_A_to_B.gpx + +

Destinator Points of Interest (.dat) (destinator_poi)

+ This format can... +

  • + read and write waypoints +

+ Support for Destinator™ binary POI files (.dat). +

+ The basic information was found at mozoft.com. + GPSBabel can read and write all fields described at this document. Please note that 'house number' isn't + supported as a separate field. This field, if available in any source file, will be stored together with 'street' + into GSPBabel's internal 'address' field. +

+ Destinator™ by + Destinator Technologies + is a software for PNDs, Smartphones and PDAs. +

+ + gpsbabel -i destinator_poi -f interesting_places.dat -o gpx -F interesting_places.gpx + +

Destinator TrackLogs (.dat) (destinator_trl)

+ This format can... +

  • + read and write tracks +

+ Support for Destinator™ binary tracklogs (.dat). +

+ The basic information was found at mozoft.com. + In addition to the standard GPS track data of coordinates and timestamp, this format also stores the + position fix and the number of satelites seen during recording. +

+ Destinator™ by + Destinator Technologies + is a software for PNDs, Smartphones and PDAs. +

+ + gpsbabel -i destinator_trl -f last_trip.dat -o gpx -F last_trip.gpx + +

EasyGPS binary format (easygps)

+ This format can... +

  • + read and write waypoints +

This is the binary file format used by EasyGPS +format is seemingly being phased out in favor of GPX in newer versions +of EasyGPS, but this allows conversions to and from the old binary +.loc format. +

Information about and sketchy code to implement this file +format were provided by Eric Cloninger. +

Embedded Exif-GPS data (.jpg) (exif)

+ This format can... +

  • + read waypoints +

+ This format reads GPS information embedded in + EXIF , + the Exchangeable Image Format, data. EXIF is a standardized method + of encoding data in pictures such as JPEG, TIFF, and WAV and is frequently + used by mobile phones with cameras, cameras with built-in GPS. +

+ EXIF is frequently used for Geolocating photographs so their images can be + correlated with time and location. +

filename option

+ Set waypoint name to source filename.. +

+ With this default option waypoint names are generated from source filename. +

+ + gpsbabel -i exif -f "C:\Pictures\IMG_1199.JPG",filename=Y -o gpx -F OUT.GPX + + The resulting waypoint in OUT.GPX has name IMG_1199. +

FAI/IGC Flight Recorder Data Format (igc)

+ This format can... +

  • + read and write tracks +

  • + read and write routes +

+FAI/IGC Data File -- Used by the international gliding +community to record gliding flights. IGC files can be converted to +and from tracks representing recorded flights, and routes representing +task declarations in other formats. +

IGC Data Format Notes

+Refer to Appendix 1 of +http://www.fai.org:81/gliding/gnss/tech_spec_gnss.asp +for the specification of the IGC data format. +

+A sample list of software applications that use data in IGC format can be +found at +http://www.fai.org:81/gliding/gnss/gnss_analysis_software.pdf +

+GPSBabel can be used to translate data in IGC format to and from various other +formats. +

+Routes in other formats are used to represent IGC task declarations. +

+Tracks in other formats are used to represent IGC recorded flights. +

Converting to IGC format

+IGC files generated by GPSBabel will NOT pass security validation tests since +the data they contain cannot be proven to originate from an approved flight +recorder. For most software applications that use IGC files this is not an +issue but for competition scoring, record and badge claims the generated files +will not be accepted as proof of a flight. +

+A track stored in another format (GPX for example) representing a recorded +flight can be converted into an IGC file: +

gpsbabel -i gpx -f mytrk.gpx -o igc -F myflight.igc

+If multiple track segments are provided in the input file, the one with the +most points will be used. +

+A route stored in another format representing a task declaration can be +converted into an IGC file: +

gpsbabel -i gpx -f myrte.gpx -o igc -F mytask.igc

+A route and a track in other formats can be included into a single IGC file: +

gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -o igc -F myflight.igc

+A similar result can be obtained by downloading the track log and routes +directly from a GPS device connected to a PC. For example to create an IGC +file from data recorded in a Garmin GPS connected to the first serial port of +a PC running Linux: +

gpsbabel -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc

+For Windows operating systems: +

gpsbabel -t -r -i garmin -f com1 -o igc -F myflight.igc

+A waypoint file in another format containing a waypoint whose short name is +"PILOT" can be merged into an IGC file. The description field of the waypoint +will be used for the pilot name in the IGC file header: +

gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -f mywpt.gpx -o igc -F myflight.igc +gpsbabel -w -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc

+Some formats such as GPX allow routes, tracks and waypoints to exist in the +same file and can be used to fully populate an IGC file: +

gpsbabel -i gpx -f myall.gpx -o igc -F myflight.igc

Converting from IGC format

+Data in an IGC file can be converted into other formats. For example to +generate OziExplorer files containing tracks representing the recorded +flight (myozi.plt) and routes representing declared tasks (myozi.rte): +

gpsbabel -i igc -f myflight.igc -o ozi -F myozi

+Or to GPX format: +

gpsbabel -i igc -f myflight.igc -o gpx -F myflight.gpx

+Header information from the IGC file will be written to the description field +of the track(s). +

+If both pressure altitude and GNSS altitude are recorded in the IGC file, two +tracks will be written to the new track file, representing the two altitude +tracks. The latitude, longitude and timestamps in the tracks will be identical. +

Merging into IGC format

+A route stored in another format can be merged with an existing IGC file that +has no task declaration, to generate a new IGC file with a task declaration: +

gpsbabel -i igc -f myflight.igc -i gpx -f myrte.gpx -o igc -F mynew.igc

+A two dimensional (lat/lon) track recorded during a flight by a GPS receiver +can be merged with a one dimensional (altitude) track recorded during the same +flight by a barograph instrument. The result is a three dimensional IGC file +representing the flight: +

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc -F my3D.igc

+The same can be acheived by downloading directly from a barograph instrument +supported by GPSBabel. For example with a Brauniger IQ Comp GPS variometer: +

gpsbabel -i baroiq -f /dev/ttyS0 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

+or: +

gpsbabel -i baroiq -f com1 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

+(Documentation contributed by Chris Jones, Aug 2004) +

timeadj option

+ (integer sec or 'auto') Barograph to GPS time diff. +

+Sometimes there is a discrepancy between the internal clock in the barograph +instrument and GPS time which can result in the altitude and ground positions +not correlating correctly. This can be corrected manually by passing the time +difference in seconds between the two time domains through the "timeadj" +parameter. This can be any positive or negative integer: +

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=27 -F my3D.igc

+GPSBabel can also attempt to deduce the time difference automatically. This +is done by comparing the time that it thinks that you landed on the GPS track +and the barograph and adjusting accordingly: +

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

Franson GPSGate Simulation (gpssim)

+ This format can... +

  • + write waypoints +

  • + write tracks +

  • + write routes +

+ This is a write-only format used to feed waypoints, tracks, and routes + into Franson Technolgies' + GpsGate simulator. +

+ To use these files in GpsGate, select 'Simulator' and then + "File->Open". +

wayptspd option

+ Default speed for waypoints (knots/hr). +

+ This option specifies the speed of the simulation in knots. +

split option

+ Split input into separate files. +

When this option is specified, GPSBabel will split + split the output into multiple files using the output filename + as a base. For example, if you specify an output file of 'mytrip', +

mytrip-waypoints.gpssim - will contain the waypoints.
mytrip-track0000.gpssim - will contain the first track.
mytrip-track0001.gpssim - will contain the second track.
... and so on.
mytrip-route0000.gpssim - will contain the first route.
mytrip-route0001.gpssim - will contain the seconds route.
... and so on.

+

+Valid values for this option are 0 (off) and 1 (on). The default is '0'. +

Fugawi (fugawi)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

This was a requested CSV format, and is not the proprietary +binary format used by Fugawi. Like any other CSV format, GPSBabel +cannot read tracks in this format, but converting a track into it and +then importing as track in Fugawi works.

It is known to work with Fugawi V3.1.4.635. When +importing/exporting waypoints, one has to specify the order of fields +as follows (names of fields may depend on the language used by +Fugawi):

- Name
- Comment
- Description
- Latidude
- Longitude
- Altitude (metres)
- Date (yyyymmdd/yymmdd)
- Time of day (hhmmss)

When importing tracks, use "[ignore]" instead of "Name", +"Comment" and "Description".

+ http://www.fugawi.com/ +

G7ToWin data files (.g7t) (g7towin)

+ This format can... +

  • + read waypoints +

  • + read tracks +

  • + read routes +

+ Like GPSBabel, G7ToWin is a program which allows uploading and + downloading information from several GPS devices (Garmin, Lowrance/Eagle, Magellan). + G7ToWin has its own data format, which is an enhanced format used in Gardown. +

+ This format can read both file types, G7ToWin (.g7t) and Gardown (.gdn). +

Garmin 301 Custom position and heartrate (garmin301)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

This is a very simple format that +is most useful for exporting data from units that support heart rate +data such as +Garmin Forerunner 301™, +Garmin Forerunner 305™, and +Garmin Edge 305™, and +to other programs +for analysis. It's a simple comma delimited format that includes the +timestamp, 3D position information and heart rate so you can pull it +into a spreadsheet or graphing program.

Garmin Logbook XML (glogbook)

+ This format can... +

  • + read and write tracks +

This is the XML format used by the Garmin Logbook product +that ships with Forerunner and Foretrex. +As of early 2006, this program is apparently been discontinued in favor of +Garmin Training Center. + +See: http://www.garmin.com +

Garmin MapSource - gdb (gdb)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+Support for the "Garmin GPS Database" format used by +default in MapSource™ versions since release 6.0 of +that product. By default GPSBabel creates +gdb files of version 2. Version 2 is used in Mapsource 6.3 and 6.5. +

+Garmin GPS database is an undocumented file format. The +basic info for this module came from the existing MapSource +conversion code. +

cat option

+ Default category on output (1..16). +

+This option specifies the default category for gdb output. It should be a +number from 1 to 16. +

bitscategory option

+ Bitmap of categories. +

+ This option is closely related to the 'category' option. While category + allows you to choose a single category that waypoints should appear in, + this options allows you to specify a bitmask to be used for the category. + Options may be specified in either decimal or hex. +

Example 3.2. Example for gdb bitcategory option to put all waypoints in categories 1 and 16.

+ The following two commands are equivalent. They place a the point in both the first and last of the sixteen available categories. + + gpsbabel -i gpx -f PocketQuery.gpx -o gdb,bitscategory=32769 -F foo.gdb + + + gpsbabel -i gpx -f PocketQuery.gpx -o gdb,bitscategory=0x8001 -F foo.gdb + + +


ver option

+ Version of gdb file to generate (1..3). +

+This option specifies the data format version for the output file. Version +2 is the default. Currently, the only other valid values for this option are +1 and 3. +

via option

+ Drop route points that do not have an equivalent waypoint (hidden points). +

+This option instructs GPSBabel to drop hidden (calculated) points from +routes. +

roadbook option

+ Include major turn points (with description) from calculated route. +

+ If this option is specified, GPSBabel drops all calculated route points, + with exception of points with a description (i.e. "Make U-turns until you know where you are."). + The priority of this option is higher than of the via option. + A value of 1 or y overwrites the via settings. +

Example 3.3. Using gdb option roadbook to create simple html roadbook

+ + gpsbabel -i gdb,roadbook -f sample.gdb -x nuketypes,waypoints,tracks -x transform,wpt=rte -o html -F roadbook.html + +

+ Because gdb internally creates a route AND a waypoint list, you have to drop all + waypoints and transform the route into waypoints in order to get a well ordered + html output. We suggest these steps for all waypoint-only formats as html. +


Garmin MapSource - mps (mapsource)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+This format supports the Garmin Mapsource™ +product family. +

+This format is based on significant reverse-engineering and guesswork. +GPSBabel's output appears to be compatible with the various versions of +MapSource. Icon mapping is attempted between different MapSource versions. +Altitude is supported, but proximity and depth are not. +

+Naming files *.mps will allow file->open in Mapsource to find the files +more easily. +

+Versions 3, 4, and 5 of the Mapsource data format are handled automatically +on input. By default the output is version 5. (Until 3/2004, it was +version 3, but since Mapsource updates are free, the convenience of +having modern icon sets outweighs the backward compatibility concern. +Users of other versions can either upgrade or specify the switches to +get output in a compatible format.) Waypoints, routes, and tracklogs are +all handled, but map sets are ignored. +

+Information on the Garmin Mapsource format was provided by Ian Cowley and +Mark Bradley. The code was implemented by Robert Lipe and Mark Bradley. +

snlen option

+ Length of generated shortnames. +

+This option specifies the length of generated short names on output. The +default is 10 characters. +

snwhite option

+ Allow whitespace synth. shortnames. +

+This option specifies whether to allow whitespace (space, tab, etc.) in +generated short names on output. The default is to not allow whitespace. +

mpsverout option

+ Version of mapsource file to generate (3,4,5). +

+This option specifies the format version for the output file. The default +is version 5, as noted above. Supported versions are 3, 4, and 5. +

mpsmergeout option

+ Merge output with existing file. +

+This option causes the output to be merged with a pre-existing output file. +This allows MapSource sections that aren't handled by GPSBabel (e.g. map sets) +to be preserved. +

mpsusedepth option

+ Use depth values on output (default is ignore). +

+This option causes GPSBabel to write depth values for waypoints. Most +input formats do not support depth values, so the default is to not write +them. +

mpsuseprox option

+ Use proximity values on output (default is ignore). +

+This option causes GPSBabel to write proximity values for waypoints. Most +input formats do not support proximity values, so the default is to not write +them. +

Garmin MapSource - txt (tab delimited) (garmin_txt)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+This is a textual format that contains nearly all of the information +contained in the MapSource™ main format, GDB. +This format also contains some computed values such as distances between +routepoints and trackpoints, speed, and course (heading). +

+The main goal of garmin_txt is to make aviation data more available. Because +MapSource™ supports only the export, GPSBabel gives you the possibility to +bring aviation data into MapSource™. +

+During the export with MapSource™, some fields are written using local settings +of MapSource™ and Windows. These include grid format, gps datum, distance and +temperature units, and the representation of date and time fields. GPSBabel +tries to read all items automatically. Problems with date and time format can +be solved with the 'date' and 'time' options. +

Example 3.4. Command showing garmin_txt output with all options

gpsbabel -i garmin_txt,date="MM/DD/YYYY",time="hh:mm:ss xx" -f in.txt -o garmin_txt,date="DD.MM.YYYY",datum="WGS 72",dist=m,prec=6,temp=c,time="HH:mm:ss",utc=+2 -F out.txt


date option

+ Read/Write date format (i.e. yyyy/mm/dd). +

+This option specifies the input and output format for the date. The format +is written similarly to those in Windows. An example format is "YYYY/MM/DD". +

datum option

+ GPS datum (def. WGS 84). +

+This option specifies the datum to be used on output. Valid values for this +option are listed in Appendix A, Supported Datums. +

dist option

+ Distance unit [m=metric, s=statute]. +

+This option specifies the unit to be used when outputting distance +values. Valid values are M for metric (m/km/kph) or S for statute +(ft/mi/mph). +

grid option

+ Write position using this grid.. +

+ This value specifies the grid to be used on write. +

Table 3.1. Grid values for garmin_txt

# idxshortfile-headersample
0dddLat/Lon hddd.ddddd S26.25333 E27.92333
1dmmLat/Lon hddd°mm.mmN33 56.539 W118 24.471
2dmsLat/Lon hddd°mm'ss.sS25 25 26.8 E28 06 07.3
3bngBritish National GridTQ 18919 69392
4utmUniversal Transverse Mercator33 U 318293 5637154
5swissSwiss grid776519 167359

+ Idx or short are valid params for this option. +

prec option

+ Precision of coordinates. +

+This option specifies the precision to be used when writing coordinate values. +Precision is the number of digits after the decimal point. The default +precision is 3. +

temp option

+ Temperature unit [c=Celsius, f=Fahrenheit]. +

+This option specifies the unit to be used when writing temperature values. +Valid values are C for Celsius or F for Fahrenheit. +

time option

+ Read/Write time format (i.e. HH:mm:ss xx). +

+This option specifies the input and output format for the time. The format +is written similarly to those in Windows. An example format is "hh:mm:ss xx". +

utc option

+ Write timestamps with offset x to UTC time. +

+This option specifies the local time zone to use when writing times. It +is specified as an offset from Universal Coordinated Time (UTC) in hours. +Valid values are from -23 to +23. +

Garmin PCX5 (pcx)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

Garmin documents only PCX5, an older format limited to +the lame NMEA six-character waypoint names that's treated as a +second-class citizien in current versions of MapSource. In Mapsource, +use file->import to read these files. If you name the files *.wpt, +Mapsource will find them more easily. +

In general, you should prefer the "mapsource" file format +to this one. +

This format has been extended to handle many - but not all - + files from GPS Utility. If you encounter something that GPSBabel does not handle well, use +the free version of GPSUtil to read it and save as something more common. +

deficon option

+ Default icon name. +

+ The deficon option is used to control the icon output when writing to this format. It overrides any icon informatino that might be present in the source data. +

cartoexploreur option

+ Write tracks compatible with Carto Exploreur. +

+ Carto Exploreur requires a slightly incompatible variation of the PCX format +when written. Specifying this option on write tells us to create that strain of PCX. +

Garmin POI database (garmin_poi)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

The Garmin POI loader +loads custom points of interest into certain models of +Garmin GPS receivers. (As of this writing, only the models introduced +in 2005 and later are supported. See Garmin's site for more info.) +This is the format readable that that program.

Garmin Points of Interest (.gpi) (garmin_gpi)

+ This format can... +

  • + read and write waypoints +

+ The format garmin_gpi supports the binary POI (.gpi) files that are useable + on newer Garmin GPS receivers. See garmin_poi for additional information about Garmin's own Poiloader program. + Garmin POI-Loader is the standard application that creates GPI files + with all possible features. +

+ The layout of GPI files isn't documented and our module was created + via reverse engeneering. If you get a problem on reading or writing + a GPI file, please provide that file (mailto:gpsbabel-misc@lists.sourceforge.net). +

+ At this time we don't support special features as "Tour-Guide" or links + to sounds and pictures. +

Important

+ Creation timestamp issue: See option sleep !!! +

+ This module does not support direct transfer of .GPI files to + receivers in Garmin protocol mode. For units like Nuvi, Zumo, or + Streetpilot, just choose a file that's on the drive where your + GPS is mounted. For units like the X series (GPSMap 60CSx, GPSMap 60Cx, Legend Hcx, etc.) + you must explictly put the unit in mass storage mode or mount + the memory chip in an external reader and transfer the file + directly. +

Example 3.5. Command showing garmin_gpi output example

+ + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,category="Nice Restaurants",bitmap=restaurant.bmp,notes -F "My Points.gpi" + +


alerts option

+ Enable alerts on speed or proximity distance. +

+ Because speed isn't a real member of a normal waypoint, you can put the speed values into + the waypoint names. "Point@30" will result in a speed value of 30. By default we assume these + values are in kilometers per hour. +

+ Proximity distance is also supported by GPX, Garmin GDB, OZI Explorer, + CompeGPS and Universal CSV. +

+ + gpsbabel -i gpx -f "warnings.gpx" -o garmin_gpi,alerts=1 -F "warnings.gpi" + +

bitmap option

+ Use specified bitmap on output. +

+ The bitmap (BMP) should be 24x24 (or smaller) and can be in + RGB-colors (24- and 32-bit) or 8-bit indexed color format. +

+ A color value of 0xFF00FF (blue=255, green=0, red=255), + also called "Magenta", can be used for transparent areas. +

+ + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,bitmap="tux.bmp" -F "My Points.gpi" + +

category option

+ Default category on output. +

+ With this option you can specify the category which is primary + visible on the device (default is "My points"). +

+ + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,category="Best Restaurants" -F "My Points.gpi" + +

hide option

+ Don't show gpi bitmap on device. +

+ For a large list of points (or whyever) it can be useful when + no bitmaps are displayed on device. With this option no bitmap + is stored and displayed. +

+ + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,hide -F "My Points.gpi" + +

descr option

+ Write description to address field. +

+ The GPI address field is often visible in lists on the device. Use this + option if you want to see the waypoint description (which can be an address too) + in this lists. +

+ + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,descr -F "My Points.gpi" + +

notes option

+ Write notes to address field. +

+ The GPI address field is often visible in lists on the device. Use this + option if you want to see the waypoint notes (which can be an address too) + in this lists. +

+ + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,notes -F "My Points.gpi" + +

position option

+ Write position to address field. +

+ The GPI address field is often visible in lists on the device. Use this + option if you want to see the waypoint position (coordinates) in this lists. +

+ + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,position -F "My Points.gpi" + +

proximity option

+ Default proximity. +

+ When no proximity data is available in the source input, GPSBabel uses this as the default proximity value. + The parameter has to be in meters, or, when units=s specified, in miles. + alerts are automatically enabled. +

Example 3.6. Read GPX file, create GPI to alert when you're 1/2 mile from a speed camera.

+ + gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,units=s,proximity=0.5 -F "SpeedCameras.gpi" + +


+ Its also possible to append a specific distance unit to the parameter. +

+ + gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,proximity=500m -F "SpeedCameras.gpi" + +

+

Table 3.2. Supported distance units

UnitDescription
faFathoms
feetFeet
ftFeet
kmKilometers
mMeters
miMiles
nmNautical miles


+

sleep option

+ After output job done sleep n second(s). +

+ The Garmin units seem to use the creation timestamp of GPI files for internal purposes. + In other words, if you load GPI files with same creation timestamp on your device, + strange things will happen, such as having missing or repeated POIs. With the sleep option, GPSBabel waits a given + number of seconds after the GPI file was written. +

+ In the normal case of using GPSBabel from the command line or from the GUI, the chance of creating files + with the same timestamp is in the nearly ZERO. In scripts or batch files where you are writing multiple files - even from different GPSBabel instances - the odds of this happening is rather good. + The sleep option forces GPSBabel to wait after creating a file to ensure the timestamps are unique. Values are specified in seconds and can be 1 or more. +

+ + gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,sleep=1 -F "SpeedCameras.gpi" + +

speed option

+ Default speed. +

+ When no speed data is available in the source input, GPSBabel uses this as the default speed value. + The parameter has to be in kilometers per hour, or, when units=s specified, + in miles per hour. alerts are + automatically enabled. +

+ + gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,units=s,speed=30 -F "SpeedCameras.gpi" + +

+ Its also possible to append a specific speed unit to the parameter. +

+ + gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,speed=30mph -F "SpeedCameras.gpi" + +

+

Table 3.3. Supported speed units

UnitDescription
km/hKilometers per hour
kmhKilometers per hour
kphKilometers per hour
ktKnots
knotKnots
m/sMeters per second
mpsMeters per second
mi/hMiles per hour


+

unique option

+ Create unique waypoint names (default = yes). +

+ Don't create unique names sample: +

+ + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,unique=0 -F "My Points.gpi" + +

units option

+ Units used for names with @speed ('s'tatute or 'm'etric). +

+ Sample command tells GPSBabel to handle speed values in miles per hour: + + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,units=s -F "My Points.gpi" + +

Garmin serial/USB protocol (garmin)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+ GPSBabel supports a wide variety of Garmin hardware via serial + on most operating systems and USB on Windows, Linux, and OS X. +

+ For serial models, be sure the GPS is set for "Garmin + mode" in setup and that nothing else (PDA hotsync programs, gpsd, + getty, pppd, etc.) is using the serial port. +

+ Supported Garmin GPS receivers with USB include +

AstroForerunner 301GPSMAP 60CSxStreetPilot 2620
Edge 205Forerunner 305GPSMAP 60CxStreetPilot 2650
Edge 305Foretrex 201GPSMAP 76CStreetPilot 2720
eTrex Legend CForetrex 301GPSMAP 76CSStreetPilot 2730
eTrex Legend CxGPS 18[1]GPSMAP 76CSXStreetPilot 2820
eTrex Legend HCxGPSMAP 195GPSMAP 76CxStreetPilot 7200
eTrex Summit CxGPSMAP 276CGPSMAP 96StreetPilot 7500
eTrex Summit HCGPSMAP 295GPSMAP 96CStreetPilot c310
eTrex Venture CGPSMAP 296CQuestStreetPilot c320
eTrex Venture CxGPSMAP 378Quest IIStreetPilot c330
eTrex Venture HCGPSMAP 396Rhino 520StreetPilot c340
eTrex Vista CGPSMAP 478Rhino 530StreetPilot i2
eTrex Vista CxGPSMAP 496Rhino 520 HCxStreetPilot i3
eTrex Vista HCxGPSMAP 60CRhino 530 HCxStreetPilot i5
Forerunner 205GPSMAP 60CSStreetPilot 2610 

+

the following Bluetooth Garmin products: +

GPS 10[1]   

+

and most serial Garmin GPS receivers including: +

eMapeTrex HGPS 12 Rhino 110
eTrex CamoForerunner 201GPS 12XL Rhino 120
eTrex LegendForetrex 201GPS III Rhino 130
eTrex SummitGeko 201GPS III+ StreetPilot III
eTrex VentureGeko 301GPS II StreetPilot III+
eTrex VistaGPS 12CX GPS II+  
eTrex (Basic Yellow)GPS 12Map GPS V 

+

+The following Garmin GPS receivers are supported, but they do not +support Garmin communication protocol and don't work with the +garmin option. To use these receivers, read or write +GPX files from the mass storage device as mounted on your computer. +

Colorado 300[2]Nuvi 250W[2]Nuvi 650[2]StreetPilot c510[2]
Colorado 400c[2]Nuvi 255W[2]Nuvi 650FM[2]StreetPilot c530[2]
Colorado 400i[2]Nuvi 260[2]Nuvi 660[2]StreetPilot c550[2]
Colorado 400t[2]Nuvi 260W[2]Nuvi 670[2]StreetPilot c580[2]
Nuvi 200[2]Nuvi 270[2]Nuvi 680[2]Zumo 450[2]
Nuvi 205[2]Nuvi 300[2]Nuvi 750[2]Zumo 500[2]
Nuvi 200W[2]Nuvi 310[2]Nuvi 760[2]Zumo 550[2]
Nuvi 205W[2]Nuvi 350[2]Nuvi 770[2] 
Nuvi 250[2]Nuvi 370[2]Nuvi 780[2] 
Nuvi 255[2]Nuvi 600[2]Nuvi 880[2] 

+

+ None of the GPSBabel developers has access to every model on that + list, but we've received reports of success and/or have reasonable + expectations that the above models work. If you succeed with + a model that is not on that list, please send a message to the + gpsbabel-misc mailing list with the details so that we may add it. +

+ Not every feature on every model is supported. For example, + while we do extract data such as heart rate and temperature from + tracks on the sporting models like Edge and Forerunner, GPSBabel + is not a fitness program at its core and does not support features + like courses or calorie/fitness zone data. +

+ To communicate with a Garmin GPS serially, use the name of that + serial port such as COM1 or /dev/cu.serial. +

+ To communicate via USB use usb: as the filename on all OSes. + Thus, to read the waypoints from a Garmin USB receiver and write + them to a GPX file: +

gpsbabel -i garmin -f usb: -o gpx -F blah.gpx

+ If you have multiple units attached via USB, you may provide + a unit number, with zero being the implied default. So if you + have three USB models on your system, they can be addressed as + usb:0, usb:1, and usb:2. To get a list of recognized devices, + specifiy a negative number such as: +

gpsbabel -i garmin -f usb:-1

+When reporting problems with the Garmin format, be sure to include +the full unit model, firmware version, and be prepared to offer +debugging dumps by adding -D9 to the command line, like: +

gpsbabel -D9 -i garmin -f usb: -o gpx -F blah.gpx

+Custom icons are supported on units that support that. +Neither GPSBabel nor your firmware know what is associated with any +given slot number. They don't know that the picture you placed in the +first slot is a happy face, they only know they're in the lowest +numbered slot. GPSBabel names the them consistently with Mapsource, +so they are named 'Custom 0' through 'Custom 511'. +

+ For models where the connection on the GPS is a serial interface, + be sure the GPS is set for "Garmin + mode" in setup and that nothing else (PDA hotsync programs, gpsd, + getty, pppd, etc.) is using the serial port. +

+ For models connected via USB, we recommend use of the usb: + filename. For this to work on Windows, you must install + the Garmin driver. For Linux, this will fail if have the garmin_gps + kernel module loaded. + See the Operating System Notes for details. +

+This module also supports realtime tracking +which allows realtime position reports from a Garmin GPS receiver over USB +or serial. +

Important

The following Garmin units do not follow the standard Garmin +communications protocol and are not supported +by GPSBabel.

+Marine plotters: +

GPSMap 420GPSMap 450GPSMap 530GPSMap 545
GPSMap 430GPSMap 520GPSMap 535GPSMap 550
GPSMap 440GPSMap 525GPSMap 540GPSMap 555

+

The PDA products +

iQue 3000
iQue 3200
iQue 3600
iQue M3
iQue M4
iQue M5

+

snlen option

+ Length of generated shortnames. +

This option overrides the internal logic to figure out how many +characters an addressed Garmin GPS will support when using the '-s' smartname +option. This should be necessary only if you have a receiver type that +GPSBabel doesn't know about or if you want to "dumb down" one unit to match +another, such as wanting waypoint names in a StreetPilot 2720 (which supports +20 character names) to exactly match those in a 60CS (which supports 10). +

snwhite option

+ Allow whitespace synth. shortnames. +

This options controls whether spaces are allowed in generated +smart names when using the '-s' option.

deficon option

+ Default icon name. +

+This option specifies the icon or waypoint type to write for each waypoint on +output. +

+If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. +

+Value specified may be a number from the Garmin Protocol Spec or a name +as described in the Appendix B, Garmin Icons. +

+This option has no effect on input. +

get_posn option

+ Return current position as a waypoint. +

This options gets the current longtitude and latitude from the attached GPS device +and returns it as a single waypoint for further processing. For example, +to return the current position from a USB Garmin to a KML file: +

gpsbabel -i garmin,get_posn -f usb: -o kml -F myposition.kml

power_off option

+ Command unit to power itself down. +

This command forces an immediate powerdown of the addressed Garmin +receiver. It is ignored on hardware that does not support this command. +Obviously, further processing once you have sent a "power off" command to +a unit that supports it is rather futile, so place this option carefully +in your command. + +

gpsbabel -o garmin,power_off -F /dev/ttyS0

resettime option

+ Sync GPS time to computer time. +

+ This option is experimental and was added to solve a very specific problem. + Certain Garmin units (the original black and white Vista is known to have + this) will sometimes scramble their clock crazy far into the future (like + 2066). When this happens, the GPS itself may or may not work and + later conversations with GPSBabel may fail as the time overflows the + documented range. The use of resettime brings the GPS's internal clock + back close enough to reality that the GPS itself can then "fix" it when + it has next a lock. +

category option

+ Category number to use for written waypoints. +

This numeric option will force waypoints to be written with that +category number when sending to a Garmin receiver that has category +support. It is ignored on receivers without that capability.

bitscategory option

+ Bitmap of categories. +

+ This option is closely related to the 'category' option. While category + allows you to choose a single category that waypoints should appear in, + this options allows you to specify a bitmask to be used for the category. + Options may be specified in either decimal or hex. +

Example 3.7. Example for garmin bitcategory option to put all waypoints in categories 1 and 16.

+ The following two commands are equivalent. They place a the point in both the first and last of the sixteen available categories. + + gpsbabel -i gpx -f PocketQuery.gpx -o garmin,bitcategory=32769 -F usb: + + + gpsbabel -i gpx -f PocketQuery.gpx -o garmin,bitcategory=0x8001 -F usb: + + +


Garmin Training Centerxml (gtrnctr)

+ This format can... +

  • + write tracks +

+GPSBabel has limited support for Garmin Training Center files. That program is the successor to Garmin' Logbook program for their workout units. It is a free upgrade. +

+This format is somewhat underachieving in GPSBabel. It is a write-only +format; we never read it. The bigger problem, however, is a fundamental +impedance mismatch between this format and most of what we support. GPSBabel +fundamentally deals in waypoints, tracks, and routes. While we do record +things like heart rate and temperature when we know it, the fundamentals +of Training Center are different - it deals in concepts like laps and calories +which are rather alien to GPSBabel and most of the formats we support. As +such, while we can describe the tracks pretty accurately, things like +calories and heart zone tracking are not supported. +

Geocaching.com .loc (geo)

+ This format can... +

  • + read and write waypoints +

+This format supports the Geocaching.com/EasyGPS ".loc" format. This format +was created specifically for Geocaching.com and is not the same as the +standard EasyGPS .loc format. See the EasyGPS +or GPX formats for more general EasyGPS support. +

+This is a simple XML-based format containing only very basic information +about geocaches. If you can use the GPX +format instead, you should consider doing so as it is a much richer format. +

deficon option

+ Default icon name. +

+This option specifies the icon or waypoint type to write for each waypoint on +output. +

+If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. +

+There is no list of valid values for this option. +

+This option has no effect on input. +

nuke_placer option

+ Omit Placer name. +

+If this option is specified, GPSBabel will not read geocache placer information +from a .loc file on input. That is, it will ignore any placeer names in the +input file. +

+This option has no effect on output. +

GeocachingDB for Palm/OS (gcdb)

+ This format can... +

  • + read and write waypoints +

This is format for the + +GeocachingDB program by DougsBrat. It works with v2 +and v3 of this program. +

Geogrid Viewer tracklogs (.log) (ggv_log)

+ This format can... +

  • + read and write tracks +

+ Binary track logs used by the Geogrid™-Viewer, a very + popular product in Germany. +

+ GPSBabel has full support for version 1.0 of this file format. +

+ We can also read some GPS data (including coordinates) from version 2.5. But + it seems, that this newer version no longer stores time stamps. This can be + a problem when converting to other formats or if you want to use our track filter. +

GEOnet Names Server (GNS) (geonet)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Input support for the GEOnet Names Server (GNS) country +file structure. Export to this format is not possible, as this format +has too many fields that we never get populated by any other +format.

GeoNiche .pdb (geoniche)

+ This format can... +

  • + read and write waypoints +

Geoniche is a Palm/OS application oriented for the +off-road user. This module was contributed by Rick Richardson. +

dbname option

+ Database name (filename). +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

category option

+ Category name (Cache). +

+This option specifies the name of the category in which to place the +waypoints. If this option is not specified, the default category is +"Cache". +

GlobalSat DG-100/BT-335 Download (dg-100)

+ This format can... +

  • + read tracks +

Serial download protocol for the GlobalSat DG-100™ GPS data logger. Although untested it is expected that this will also support the BT-335.

While the DG-100 has a button to record waypoints, they seem to be indistinguishable from trackpoints. Therefore, all points will be presented as trackpoints, disregarding whether they were recorded automatically or manually.

+GlobalSat DG-100 +

Example 3.8. Command showing DG-100 download and erase on Linux

gpsbabel -t -i dg-100,erase -o gpx /dev/ttyUSB0 outputfile.gpx


+The DG-100 provides a physical USB interface to the host computer, but +internally it uses a Prolific PL-2303 chip to do this. So you must have +drivers installed on your computer to recognize the PL-2303 and provide +that data as a serial port to software like GPSBabel. Such software +comes with the unit for Windows. Prolific provides software for Mac OS/X, +but unfortunately their driver has a defect which makes it unusable with +GPSBabel. +

erase option

+ Erase device data after download. +

This option erases the track log from the device after download.

Google Earth (Keyhole) Markup Language (kml)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+KML, the Keyhole Markup Language, is used by Keyhole and +Google Earth. +

There are concepts in KML that GPSBabel can't support very well on +read becuase they don't map well into other programs. For example, KML has +ideas of camera views and names and descriptions can have arbitrarily +complicated HTML in them. KML files may have tiered "Styles" which +can identify sizing info and URLs of associated icons. Reading such +files with GPSBabel - even if your goal it to out to KML - can often +have suprising results. Simple files with waypoints and paths (which +GPSBabel represents internally as tracks) work fine. +

+Google Earth also uses GPSBabel internally for receiver communications +and several file format imports and exports. +

+In general, GPSBabel's KML writer is relatively strong. GPSBabel handles simple KML on read fairly well, but if you're dealing with handcrafted KML that uses extensive features that have no analog in other formats like nested folders, ringgeometry, camera angles, and such, don't expect GPSBabel to do well with them on read. +

+ Google Earth 4.0 and later have a feature that can suprise users of this + format. Earth's "time slider" feature controls what timestamped data + gets displayed. If you're using data that has timestampes (e.g. GPX + points that contain time or almost any track data) this will be important + to you. The time slider defaults to the far left position and fully closed. + This means that only the first data point will be displayed. You can + tweak Earth's settings to "view->show time->never" or + you can widen the time slider to show the range of data of interest. +

+ See Google Earth's documentation on timelines for more info. +

deficon option

+ Default icon name. +

+This option specifies the default name for waypoint icons +

lines option

+ Export linestrings for tracks and routes. +

+When this option is nonzero, GPSBabel draws lines between points in +tracks and routes. The default value for this option is 1, which causes +lines to be drawn by default. To disable line-drawing, specify +lines=0. +

points option

+ Export placemarks for tracks and routes. +

+When this option is nonzero, GPSBabel draws placemarks for tracks and routes. +The default value for this option is 1, which causes placemarks to be drawn. +To disable drawing of placemarks, specify points=0. +

line_width option

+ Width of lines, in pixels. +

+This option specifies the width of the drawn lines in pixels. The default +value is six pixels. +

line_color option

+ Line color, specified in hex AABBGGRR. +

+This option specifies the line color as a hexadecimal number in +AABBGGRR format, where A is alpha, B is blue, G is green, and R is red. +

floating option

+ Altitudes are absolute and not clamped to ground. +

+When this option is nonzero, altitudes are allowed to float above or below +the ground surface. By default, this option is zero so that altitudes are +clamped to the ground. Specify floating=1 to allow them to +float. +

+This option is more useful to pilots than to hikers. +

extrude option

+ Draw extrusion line from trackpoint to ground. +

+This option is a boolean flag to specicy whether Google Earth should +draw lines from trackpoints to the ground. It defaults to '0', which +means no extrusion lines are drawn. The option of '1' is, of course, +most useful for points that aren't actually on the ground such as those +be captured from planes. +

trackdata option

+ Include extended data for trackpoints (default = 1). +

+This is a boolean flag that controls +whether GPSBabel writes extensive data for each trackpoint generated. +By default computed speed, timestamps, and so on are written with the default +of '1' for this option. If you are writing large tracks and do not value +this information, you can reduce the size of the generated file substantially +by turning this flag off by setting it to '0'. +

trackdirection option

+ Indicate direction of travel in track icons (default = 0). +

+ If set, this options creates directional icons for trackpoints. Arrows + will show the direction of travel on drawn tracks and routes. +

units option

+ Units used when writing comments ('s'tatute or 'm'etric). +

+Units is a simple option. Specify 's' for "statute" (miles, feet, and +other things that don't sensibly convert to each other, but are craved +by Americans) or 'm' for "metric". +

labels option

+ Display labels on track and routepoints (default = 1). +

+When this option is zero, no labels are added for track and route points. +This option defaults to one, so labels are added by default. +

max_position_points option

+ Retain at most this number of position points (0 = unlimited). +

+ This option allows you to specify the number of points kept + in the 'snail trail' generated in the realtime tracking mode. +

Google Maps XML (google)

+ This format can... +

  • + read tracks +

This format is designed to read the XML emitted when you +tack "&output=js" onto the end of a Google Maps route URL (use +the "link to this page" option to get a usable URL.) This allows you +to plan a route using Google Maps, then download it and use it in your +own mapping program or GPS receiver. To get a file suitable for use +with GPSBabel, plan your route as usual with Google Maps. Once you've +got it the way you want it, click the "Link to this page" link in the +upper right-hand corner of the Google Maps page. Then, edit the URL +that appears in your address bar by adding "&output=js" (without +the quotes) onto the end. Hit enter, and the resulting page will be +mostly empty. It doesn't look like much, but it contains exactly what +GPSBabel needs. Save it to disk using whatever menu option your web +browser provides. +

+Note that if you are using Microsoft Internet Explorer, you should make sure +to save the web page as "Web Page, HTML Only". If you save it as "Web Page, +Complete", it will be reformatted into a non-XHTML format that GPSBabel +cannot read. +

+If you use a Unix-compatible +operating system, this shell script might be useful: +

+#!/bin/sh 
+FROM="233 S. Upper Wacker Dr, Chicago, IL" 
+TO="1060 W. Addison St, Chicago, IL" 
+wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" \
+2&>/dev/null >google_map.js
+gpsbabel -i google -f google_map.js -o gpx -F google_map.gpx
+

GpilotS (gpilots)

+ This format can... +

  • + read and write waypoints +

This is a Palm/OS file format for + GPilotS. + It was tested against version 6.2 of GPilotsS +

Neither tracks nor routes are supported at this +time.

dbname option

+ Database name. +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

GPS TrackMaker (gtm)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

Input and output support for waypoints, tracks and routes in + the GPS TrackMaker + binary format.

Code implemented by Gustavo Niemeyer.

GPSBabel arc filter file (arc)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+This format is used by GPSBabel itself as the input to the +arc and +polygon filters. See those filters +for more information. +

+The arc format reads two numeric fields, a latitude and a longitude, +in any format recognized as human +readable and writes as simple degrees decimal. It really is +intended for GPSBabel's own internal use more than general use, though +it turns out to be a convenient way of expressing simple polylines and +polygons. +

GpsDrive Format (gpsdrive)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

GpsDrive way.txt file format. A space seperated format +file. Tested against GpsDrive v 1.30 found at gpsdrive.de. +Contributed by Alan Curry.

GpsDrive Format for Tracks (gpsdrivetrack)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Format used by GpsDrive to save tracks. Like GPSDRIVE a +space seperated format file. See above for a link to GpsDrive. +Contributed by Tobias Minich.

GPSman (gpsman)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

GPS Manager +can read and write formats GPSBabel doesn't understand. The format defaults +(WGS84, DDD) work reliably. Tracks, routes, and non-default format options +are not supported. +

This format is documented at the GPS Manager + doc site. +

GPSPilot Tracker for Palm/OS (gpspilot)

+ This format can... +

  • + read and write waypoints +

The file format for GPSPILOT gpspilot.com was provided by Ron +Parker. The output from this module has been tested with GPSPilot +Tracker v5.05sx, but it is based on reverse-engineering so it may not +work with all versions of all GPSPilot products. It had read-only +support for Airport, Navaid, City and Landmark files but will read and +write Point files.

dbname option

+ Database name. +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

gpsutil (gpsutil)

+ This format can... +

  • + read and write waypoints +

The format we call gpsutil is a simple file format used by a program that runs +on POSIX- compliant OSes like UNIX and Linux. Reads and writes of +this format are very reliable. (The lead +developer of GPSBabel also contributed to this that 'gpsutil' +the early days.)

+ Note that 'gpsutil' is a different format - and program - than the one called GPS Utility; for that one, you should probably use our PCX module. +

GPX XML (gpx)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

This is the most capable and expressive of all the file +formats supplied. It is described at topografix.com and is +supported by EasyGPS, ExpertGPS, and many other programs described at +topografix.com +

+ GPSBabel's reader of this module attempts to preserve tags it doesn't + really understand. It also tries to glean interesting data from + pocket queries from Geocaching.com and Garmin's "gpxx" GPX extensions. +

snlen option

+ Length of generated shortnames. +

+ When used with the -s to control shortnames, the snlen suboption to GPX controls how long the generated smartname will be. This can be useful for cases like writing GPX files to a GPS that has a fixed waypoint name length. +

suppresswhite option

+ No whitespace in generated shortnames. +

+When used with the -s to generate smart shortnames, this suboption controls whether whitespace is allowed in the generated shortnames. +

logpoint option

+ Create waypoints from geocache log entries. +

+ When reading Groundspeak Pocket Queries , the logpoint option creates additional waypoints from the log entries. +

+ A typical use for this is to get coordinates read from "corrected coordinates" logs. +

urlbase option

+ Base URL for link tag in output. +

+ This is a fairly esoteric option. If the GPX file you are reading has only base pathnames (e.g "foo.html") the value you specify to this argument will be prepended to that. For example, "-o gpx,urlbase=c:\My Documents\Whatever" would result in the link to that waypoint being written to refer to c:\My Document\WHatever\foo.html +

gpxver option

+ Target GPX version for output. +

+This option specifies the version of the GPX specification to use for +output. The default version is 1.0. The only other valid value for this +option is 1.1. +

+Notice that this is not a full scale XML schema conversion. In particular, +if you have a GPX 1.0 file that has extended namespaces in it (such as a +pocket query from Geocaching.com) just writing it with this option will +result in a horribly mangled GPX file as we can't convert the schema data. +

HikeTech (hiketech)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

This is the .gps format used by the Mac OS X applications +written by HikeTech. These include TopoDraw, Link2GPS, and GPSWrite. +More information about these products can be found at hiketech.com +

Holux (gm-100) .wpo Format (holux)

+ This format can... +

  • + read and write waypoints +

The Holux gm-100 (e-fox) gps receiver uses standard +compact flash cards. File formats were provided by Holux-Taiwan +holux.com to the author. +The code was tested against version 2.27E1; other versions and +receivers may work but have not been explictly tested. Anyone with +information on other Holux receivers is encouraged to contact +jochen@bauerbahn.net. +

When copying the .wpo file to a flash card, the file must +be named tempwprt.wpo as the +receiver will ignore all other files. +

Comparing the waypoints of a .wpo files against other +formats like .gpx you may notice a small difference in the latitude +and longitude values. The reason is the low resolution of the +coordinates in the wpo file format. In a .wpo file the reolution is +1/10"; in gpx for example it is 1/100". A a practical matter, this +loss is only about 1.7 meters (5 feet). +

The generated waypoint failes can also be used by MapShow +version 1.14. This program is free of charge from the Holux web site. +

This format was contributed by Jochen Becker. +

HSA Endeavour Navigator export File (hsandv)

+ This format can... +

  • + read and write waypoints +

HSA Systems Endeavour Navigator format - will import both +the old version 4.x binary files, and the newer XML based ones. Only +writes the new XML (5.0 and above) format. (use the .exp +extension)

HTML Output (html)

+ This format can... +

  • + write waypoints +

GPSBabel's HTML output generates a single HTML file of all of the +waypoints in the input file. It supports a number of Groundspeak GPX +extensions and filters out potentially harmful HTML from the +input file while maintaining almost all of the source HTML formatting. +This makes this format well suited for generating HTML to hand to programs +like Plucker for putting in a PDA and especially so for "paperless caching" +for Geocachers with pocket queries. +

This format is similar to the text format. +

The following command line reads a GPX file with +Groundspeak extensions and writes an HTML file with encrypted hints +that is rendered using a custom stylesheet: +

gpsbabel -i gpx -f 12345.gpx -o html,stylesheet=green.css,encrypt -F 12345.html

stylesheet option

+ Path to HTML style sheet. +

+Use this option to specify a CSS style sheet to be used with the +resulting HTML file. +

encrypt option

+ Encrypt hints using ROT13. +

+Use this option to encrypt hints from Groundspeak GPX files. +

logs option

+ Include groundspeak logs if present. +

+Use this option to include Groundspeak cache logs in the created document. +

degformat option

+ Degrees output as 'ddd', 'dmm'(default) or 'dms'. +

+When GPSBabel writes coordinates, this option is consulted to see if it +should write decimal degrees ('ddd') decimal minutes ('dmm') or degrees, +minutes, seconds ('dms'). The default is 'dmm'. +

altunits option

+ Units for altitude (f)eet or (m)etres. +

+This option should be 'f' if you want the altitude expressed in feet and +'m' for meters. The default is 'f'. +

IGN Rando track files (ignrando)

+ This format can... +

  • + read and write tracks +

+This format supports IGN Rando track files. IGN Rando is a program mainly +used in France for Topo maps. The files are XML based and are "windows-1252" +encoded. Trackpoints do not have time stamps. +

index option

+ Index of track to write (if more the one in source). +

+Because the format supports only one track, this option may be used +on output to select a single track from a collection of +tracks read from a more expressive format. If you have, say, a +gpx file that contains two tracks, you may +use this option to write them one at a time to individual files. +

gpsbabel -i gpx -f tracks.gpx -o ignrando,index=1 -F track1.txt -o ignrando,index=2 -F track2.txt

Kartex 5 Track File (ktf2)

+ This format can... +

  • + read and write tracks +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Support for Kartex 5 trackfiles. For more info see kwf2.

Kartex 5 Waypoint File (kwf2)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Support for Kartex 5 waypoint files. Kartex is a Swedish + map and GPS positioning system. GPSBabel can read and write + files from Kartex 4 and 5 with WGS84 coordinates. UTM or + Swedish grid are not supported. +

Kompass (DAV) Track (.tk) (kompass_tk)

+ This format can... +

  • + read and write tracks +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+ This module supports track files used by Kompass and DAV "Deutscher Alpenverein". +

+ Kompass is a publishing company from Austria. + If you want to get more information about DAV, the German alpine association, + and if you are familiar with the german language, please have a look at their homepage. +

Kompass (DAV) Waypoints (.wp) (kompass_wp)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+ This module supports waypoint files used by Kompass and DAV "Deutscher Alpenverein". +

+ Some more information under kompass_tk format. +

KuDaTa PsiTrex text (psitrex)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

This is a text format created by KuDaTa's PsiTrex program +for the Psion PDAs. The format can't be readily handled by XCSV, so +this format is handled explicitly. Waypoints, routes and tracks are +all handled, with icon names used corresponding to verison 1.13 of +PsiTrex. This module was contributed to GPSBabel by Mark +Bradley.

Lowrance USR (lowranceusr)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+The Lowrance iFinder GPS series has the unique capability +to output its data to an MMC card. The data is saved to the card as a +.USR file and can be read by your computer using a card reader. +Waypoints, icons, routes, tracks are supported. Event marker icons contain a symbol, name, latitude and longitude +only. By default, Event marker +icons are converted to waypoints on read. On write, you are able to create icons from waypoints. +

ignoreicons option

+ Ignore event marker icons on read. +

+This option instructs GPSBabel to not convert icons to waypoints on input, +but to instead disregard them altogether +

writeasicons option

+ Treat waypoints as icons on write. +

+(USR output) This option converts the waypoint information to an event marker icon. +

merge option

+ (USR output) Merge into one segmented track. +

+(USR output) This option merges all tracks into a single track with multiple segments. +

break option

+ (USR input) Break segments into separate tracks. +

+(USR input) Break track segments into separate tracks. +file. +

Magellan Explorist Geocaching (maggeo)

+ This format can... +

  • + write waypoints +

This format support the on-card format used by the Magellan Explorist 400, +Explorist 500, Explorist 600, Explorist 210, and Explorist XL +to describe geocaches. Notice what while the format can +hold an infinite number of geocaches, the unit will read and silently +discard all but 200 geocache POIs at a time.

You should name any file created with this format with a +".gs" extension so the firmware can read it. +

Magellan Mapsend (mapsend)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+This format supports the Magellan MapSend™ native +file format. +

+Kudos to Magellan for having the foresight to document their file formats, +making software like this possible. +

trkver option

+ MapSend version TRK file to generate (3,4). +

+This option sets the MapSend version to generate TRK files, +since new MapSend versions can't open version 3 files. +Valid values are 3 (MapSend v3.0) or 4 (MapSend v4.0 and v4.1). +

Magellan NAV Companion for Palm/OS (magnav)

+ This format can... +

  • + read and write waypoints +

+Magellan NAV Companion for Palm/OS is not really designed +for this sort of use, but its file format is supported and with a +little bit of patience you can both read and write NAV Companion +waypoints. This conversion is based on +partially incomplete reverse-engineering of the record format, so it +may not work with all versions of NAV Companion. It has been tested +with version 2.10 and 3.20. +

+Translating NAV Companion waypoints to another format is as easy +as with any other format. Just find the Companion_Waypoints database +in your palm backup directory and use it as the input file. +

+When translating waypoints back to NAV Companion, though, you need +to jump through some hoops: +

+First, you must merge any waypoints that already exist in the database +in your Palm Backup directory with the ones you are adding; failure to +do so will result in only the new points being available in NAV Companion, +even if you give the new database a different name (it will overwrite +the old database, even in your backup directory. That's a feature of +PalmOS, not of NAV Companion.) +

+To merge the databases, use a command line like the following: +

gpsbabel -i magnav -f Companion_Waypoints.PDB -i geo -f geocaching.loc -o magnav -F merged.pdb

+Second, you must use the installer to install your new PDB file. Don't +make the mistake of copying it over the existing Companion_Waypoints.PDB +file; the one on the handheld will overwrite it rather than merging with +it. +

+Finally, because NAV Companion is not designed to work with desktop +applications, you must tell NAV Companion that its waypoints database +has changed out from under it. One way to do this is to go to the +waypoints screen and attempt to scroll; that will force it to reread +the database and fix the record pointers that it keeps on the heap. +

Magellan SD files (as for eXplorist) (magellanx)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+ This is the SD card format used by the Magellan Explorist 400, + Explorist 500, Explorist 600, and Explorist XL and internally on those devices plus the + Explorist 210. Stored waypoints are identical to the Magellan SD format + used by Meridian, but the newer models allow longer waypoint names. Routes are + subtly different. +

+ You should name any file containing waypoints created with + this format with a ".upt" extension so the firmware can read it. + Similarly, routes should be named ".rte" and tracks should be + named ".log". +

deficon option

+ Default icon name. +

+ The deficon option is used to control the icon output when writing to this format. It overrides any icon informatino that might be present in the source data. +

maxcmts option

+ Max number of comments to write (maxcmts=200). +

+The maxcmts option allows you to specify the number comments that will +be sent to the unit. +

+Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. +

Magellan SD files (as for Meridian) (magellan)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

GPSBabel supports the following Magellan receivers: +

310Meridian Color
315Explorist 100 (with aftermarket cable)
Map330Explorist 200 (with aftermarket cable)
SporTrak Map ColorExplorist 300 (with aftermarket cable)
SporTrak MapExplorist 210
SporTrak Map ProExplorist 300
SporTrak Map TopoExplorist 400
Meridian (green or yellow)Explorist 500
Meridian GoldExplorist 600
Meridian PlatinumExplorist XL

+

+ This format is used for both the serial protocol used on the + devices with serial ports such as Map330 and Meridian and for + the files stored either in either the unit's internal memory + (Explorist 210, Explorist 400, Explorist 500, Explorist 600, + Explorist XL) or on removable memory. +

+ If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyS0") + to be read or written, GPSBabel will use serial protocol. Specifying + a file, either on local filesystem or on a mounted flash card reader, + will results in the file-based format being used. +

deficon option

+ Default icon name. +

+ The deficon option is used to control the icon output when writing to this format. It overrides any icon informatino that might be present in the source data. +

maxcmts option

+ Max number of comments to write (maxcmts=200). +

+The maxcmts option allows you to specify the number comments that will +be sent to the unit. +

+Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. +

Magellan serial protocol (magellan)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

GPSBabel supports the following Magellan receivers: +

310Meridian Color
315Explorist 100 (with aftermarket cable)
Map330Explorist 200 (with aftermarket cable)
SporTrak Map ColorExplorist 300 (with aftermarket cable)
SporTrak MapExplorist 210
SporTrak Map ProExplorist 300
SporTrak Map TopoExplorist 400
Meridian (green or yellow)Explorist 500
Meridian GoldExplorist 600
Meridian PlatinumExplorist XL

+

+The RoadMate family of products is not supported. +

+ This format is used for both the serial protocol used on the + devices with serial ports such as Map330 and Meridian and for + the files stored either in either the unit's internal memory + (Explorist 210, 400, 500, 600, XL) or on removable memory. +

+ If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyS0") + to be read or written, GPSBabel will use serial protocol. Specifying + a file, either on local filesystem or on a mounted flash card reader, + will result in the file-based format being used. +

+ Users of the Explorist generation of receivers should probably + prefer to use the magellanx + format over this one. + +

Important

+This module does not support the units that do not follow Magellan's +documented communications protocols including:

Maestro 3100 RoadMate 800
Maestro 3140 RoadMate 860T
Maestro 3200 RoadMate 1200
Maestro 3210 RoadMate 1400
Maestro 3220 RoadMate 1412
Maestro 3225 RoadMate 1430
Maestro 3250 RoadMate 2000
Maestro 4000 RoadMate 2000
Maestro 4040 RoadMate 2200T
Maestro 4050 RoadMate 3000T
Maestro 4200 RoadMate 3050T
Maestro 4210 RoadMate 6000T
Maestro 4220 RoadMate AAA
Maestro 4250 Triton 200
Maestro 5310 Triton 300
RoadMate 300 Triton 400
RoadMate 360 Triton 500
RoadMate 500 Triton 1500
RoadMate 700 Triton 2000
RoadMate 760 

deficon option

+ Default icon name. +

+This option specifies the icon or waypoint type to write for each waypoint on +output. +

+If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. +

+This option has no effect on input. +

maxcmts option

+ Max number of comments to write (maxcmts=200). +

+The maxcmts option allows you to specify the number comments that will +be sent to the unit. +

+Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. +

baud option

+ Numeric value of bitrate (baud=4800). +

+ This option causes GPSBabel to use the given baud rate for serial + communications. It must match the given baud rate on the receiver. The + default value matches the default on the receiver, 4800. +

+ Valid options are 1200, 2400, 4800, 9600, 19200, 57600, and 115200. +

noack option

+ Suppress use of handshaking in name of speed. +

+Magellan's protocol specification strongly encourages the use of software +acknowledgements on every packets. This is a simple "this is what I think +I heard. If you agree that I heard it correctly, let's go to the next packet" +handshake that is used to ensure the integrity of the data transfer. +

+Certain firmware versions have problems handling this which makes transfers +unnecessarily slow. Transfers on all units at high serial speeds are also +severely restricted by this process. +

+In controlled environments (good cables, low electrical noise, receiving +from the unit, not doing donuts with the unit set to "track up" at a 150 +mile scale with 500 waypoints on the screen) it is sometimes useful to +release that safety belt by using the "noack" suboption. +

nukewpt option

+ Delete all waypoints. +

+This option erases all waypoints in the receiver before doing a transfer. +

+This is a convenient option to use in automated processes where you want +to ensure the units starts with a clean state before sending waypoints to +it. Using this option on transmit is a better idea than doing it on +receive since the latter would erase all the waypoints before asking the +unit to send all the waypoints. +

MagicMaps IK3D project file (.ikt) (ik3d)

+ This format can... +

  • + read waypoints +

  • + read tracks +

+ This is the format for MagicMaps project (.ikt) files. +

+ MagicMaps "Das interaktive Kartenwerk"™ is a Software from Germany. It's a + route-planning software with a 3-dimensional envirounment. +

+ The project files are XML based and we can read the main GPS items (names and coordinates). + For an output these files are too complex. +

Map&Guide 'TourExchangeFormat' XML (tef)

+ This format can... +

  • + read routes +

+TEF, internally called "TourExchangeFormat", is an XML based export format +used by Map&Guide Motorrad-Routenplaner 2005/06™. +

+Because this is only an export format, GPSBabel does not support writing to +this format. +

+GPSBabel also supports the bcr format, which +may also be used with this program and supports both reading and writing. +

gpsbabel -r -i tef,routevia -f in.xml -o gpx -F out.gpx

routevia option

+ Include only via stations in route. +

+This option may be used to eliminate calculated route points from the route. +

Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)

+ This format can... +

  • + read waypoints +

  • + read routes +

With this format we support the Palm/OS export for +Map&Guide based products like "PowerRoute", +"Motorrad-Routenplaner" and (maybe) other software. The exported files +can contain maps and/or route descriptions. The reader for this format +has been tested with PowerRoute 5+6, Motorrad-Routenplaner +2002(-2006).

Mapopolis.com Mapconverter CSV (mapconverter)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+Mapconverter is a format that is read by Mapopolis.com's +mapconverter application. +

+Mapconverter is an application used to create userland maps and map data for +Mapopolis.com's Mapopolis program. The mapconverter format is essentially +waypoint data prepared in a format that the mapconverter application will +accept. +

+The steps for using GPSBabel and Mapconverter go something like this: +

+Step 1: Create a mapconverter file using gpsbabel. +

gpsbabel -i geo -f geocaching.loc -o mapconverter -F foo.txt

+Step 2: Launch mapconverter.exe and choose foo.txt as your input file. + Click the begin button to have mapconverter process foo.txt. +

+If all goes successfully, you should have a file called "foo.pdb" ready +for syncing with your PDA. Put it wherever Mapopolis thinks it should be +on your PDA. +

Notes

  • +GPSBabel will write the name of its own output file in the output file + it creates as the input for Mapconverter. Mapconverter will replace + the extension of this filename with ".pdb". +

  • +The PocketPC version of Mapopolis doesn't notice files with the ".pdb" + extension. To make this work, change the extension to ".mlp" when + copying the mapconverter output to your PocketPC PDA. +

  • +Mapconverter only works with Mapopolis version 3.x. Mapopolis version + 4 will refuse to load mapconverter maps. There is no known work-around + for this at the time of this writing. +

  • +Mapconverter is no longer available from the Mapopolis website. If you + need a copy of mapconverter, ask on your local GPS Software discussion + forum and I'm sure someone will have it. As far as I know, It was never + actually acknowledged/supported by Mapopolis to begin with. +

MapTech Exchange Format (mxf)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Maptech Exchange Format - Another CSV format file. This +format complies with (at least) Maptech Terrain Navigator, Terrain +Professional, Take a Hike, and ExpertGPS import/export MFX. +Contributed by Alex Mottram.

Microsoft AutoRoute 2002 (pin/route reader) (msroute)

+ This format can... +

  • + read routes +

Input support for Microsoft AutoRoute 2002-2006 .axe files +and Microsoft Streets and Trips .est files. This is for reading routes +created this program and is different than the +s_and_t format used for writing pushpins.

+These files contains only routes. We can extract the coordinates and +the names of the points within route. An export to this format will +not be supported.

Only the start, stops, and end points are stored in the +.est/.axe/.ptm files. Turn-by-turn route data is not stored in the +.est/.axe/.ptm files, and is recalculated by the Microsoft title each +time on opening the file. This means that the output of GPSBabel will +not contain turns needed for driving directions.

One possible approach to achieve similar results is to +use the Streets and Trips drawing tools to trace a line over the +interesting parts of the route to capture intersections or key turns. +GPSBabel will capture stops in the route and insert those as turns, so +adding stops at intersections can also improve the results when converting. +

Microsoft Streets and Trips (pin/route reader) (msroute)

+ This format can... +

  • + read routes +

Input support for Microsoft AutoRoute 2002-2006 .axe files +and Microsoft Streets and Trips .est files. This is for reading routes +created this program and is different than the +s_and_t format used for writing pushpins.

+These files contains only routes. We can extract the coordinates and +the names of the points within route. An export to this format will +not be supported.

Only the start, stops, and end points are stored in the +.est/.axe/.ptm files. Turn-by-turn route data is not stored in the +.est/.axe/.ptm files, and is recalculated by the Microsoft title each +time on opening the file. This means that the output of GPSBabel will +not contain turns needed for driving directions.

One possible approach to achieve similar results is to +use the Streets and Trips drawing tools to trace a line over the +interesting parts of the route to capture intersections or key turns. +GPSBabel will capture stops in the route and insert those as turns, so +adding stops at intersections can also improve the results when converting. +

Microsoft Streets and Trips 2002-2007 (s_and_t)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

This is a format for creating data to be read by + Microsoft Streets and +Trips. It's been exercised on versions from 2003 through 2008. Detailed +instructions on how to use it, including preserving hyperlinks, are at +gpsbabel.org +

+ This format has nothing to do with the .est/axe format used by this program to store routes. +

Motorrad Routenplaner (Map&Guide) .bcr files (bcr)

+ This format can... +

  • + read and write routes +

+This file format (extension .bcr) is used in Map&Guide +Motorrad Routenplaner 2002™ and later versions. +BCR is a route-only format. If you own a newer release (2005 or later) you +may also use the XML export with GPSBabel's tef +input format. +

+There may be other products from Map&Guide that use this format as well. +

+Coordinates are stored in a BCR file in a Mercator projection. The +conversion from the Mercator projection to polar (latitude/longitude) +coordinates and back again may result in visible differences. Experience +reports are welcome. +

Example 3.9. Sample BCR command with all options

gpsbabel -r -i gpx -f in.gpx -o bcr,index=1,name="From A to B",radius=6371012 -F a_to_b.bcr


index option

+ Index of route to write (if more the one in source). +

+Because the format supports only one route, this option may be used +on output to select a single route from a collection of +routes read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. +

gpsbabel -i gpx -f routes.gpx -o bcr,index=1 -F route1.bcr -o bcr,index=2 -F route2.bcr

name option

+ New name for the route. +

+This route specifies the name of the route. This is particularly useful if +the route came from an input format that did not support named routes, but +it may also be used to rename a route. +

radius option

+ Radius of our big earth (default 6371000 meters). +

+This option instructs GPSBabel to use a different value for the radius of +the earth when converting between the Mercator projection and geographic +coordinates. The default value is 6371000.0 meters. +

+Careful experimentation with this value may help to reduce conversion +errors. +

prefer_shortnames option

+ Use shortname instead of description. +

+This option causes GPSBabel to use the short name of the waypoint instead +of the description. +

MS PocketStreets 2002 Pushpin (psp)

+ This format can... +

  • + read and write waypoints +

+Microsoft's PocketStreets 2002 Pushpin (.PSP) format is +not yet completely documented. The .PSP module does not work with +MS Streets & Trips 2002 .EST files To create .PSP files from +Streets & Trips 2002, you will need to have PocketStreets support +installed. +

+Please note that MS Streets & Trips only exports +.PSP files. It does not import them. MS Streets & Trips 2002 only +imports CSV files. To use .PSP files, simply copy them over to the +same folder on the mobile device as the map (.MPS), and open +PocketStreets. It should also be noted that in the case a pushpin is +outside of the exported map area, the pin will be "grayed-out" and +unused in PocketStreets. This is a good thing as it allows us to +create one big .PSP file that covers multiple .MPS files. +Unfortunately, you need one .PSP file for every .MPS file. +

Frequently Asked Questions

1. +Why should I use GPSBabel/psp to make pushpins when Streets & Trips (S&T) + already does that for me? +
2. +I keep getting a blank (32 byte) PSP file. +
3. +I've created a PSP file, now what do I do with it? +
4. +I don't have a map. What do I do now? +
5. +I have .EST files, not .PSP files. What's up with that? +
6. + The .PSP files differ when I use GPSBabel/psp versus Pocketstreets to + create them. What's up? +
7. +Does GPSBabel/psp work with (Autoroute, Mappoint, etc..) .PSP files? +
8. + Does GPSBabel/psp work with (S&T 2001, S&T 2002, etc...) files? +
9. +Does GPSBabel/psp work with (insert your country/location here) maps? +
10. +What do you mean S&T writes points with the wrong coordinates? +
11. +I have 800 waypoints that cover a dozen or so Pocketstreets maps. + Do I need to to split my points up into smaller chunks to match the + area covered by the maps? +
12. +Where can I find documentation for the layout of PSP files? +
13. +I have some other problem, what do I do? +

1.

+Why should I use GPSBabel/psp to make pushpins when Streets & Trips (S&T) + already does that for me? +

+GPSBabel/psp has the advantage of being able to create pushpins +without + creating the associated map file and the need to "import" the waypoint + data into S&T. Through a series of scripts, you can create a dozen + or so PSP files in a few seconds as opposed to a few weeks using the + S&T interface. The maps are not going to change between sessions, + only the pins will. Why waste all that time creating maps when all you + really want are updated pins? As an aside, GPSBabel/psp creates points + with the proper coordinates + where S&T does not in some areas of the U.S. + (Nashville, TN for instance). +

2.

+I keep getting a blank (32 byte) PSP file. +

+There are either no points to write, or you have botched the command + line for GPSBabel. GPSBabel is sensitive to UPPER and lower case + on the command line. A simple command line to create PSP files + looks like this: +

gpsbabel -i geo -f geocaching.loc -o psp -F NewOrleans.psp

+ Note the use of "-f" for INPUT files and "-F" for OUTPUT files. +

3.

+I've created a PSP file, now what do I do with it? +

+To use pushpins in Pocketstreets, you need to have both a map and a + pushpin file. These two files must exist in the same folder and have + exactly the same base name as the map. For example, the pins that + correspond to the map "NewOrleans.mps" should be named "NewOrleans.psp". +

4.

+I don't have a map. What do I do now? +

+Create one using the "Export map to Pocketstreets" option in S&T. You + can also pick up some major city maps on the web from the MS Pocketstreets + website if you are interested in seeing how it works. +

5.

+I have .EST files, not .PSP files. What's up with that? +

+In order to make PSP files, you need to use the "Export map to + Pocketstreets" function in S&T. .EST files are for use in S&T, not + Pocketstreets. +

6.

+ The .PSP files differ when I use GPSBabel/psp versus Pocketstreets to + create them. What's up? +

+Pocketstreets makes corrections to the S&T waypoint data upon initial + loading. GPSBabel/psp writes PSP files with these corrections already made. + Ask MS. +

7.

+Does GPSBabel/psp work with (Autoroute, Mappoint, etc..) .PSP files? +

+As of this writing, I haven't seen any so I can't be sure. If they + follow the same layout as S&T 2002, I'd imagine so. +

8.

+ Does GPSBabel/psp work with (S&T 2001, S&T 2002, etc...) files? +

+MS changed the file layout between S&T 2001 and S&T 2002. The GPSBabel psp + module is known to work fine with S&T 2002 and 2003. +

9.

+Does GPSBabel/psp work with (insert your country/location here) maps? +

+If it doesn't, feel free to inquire on the +GPSBabel-Misc +mailing list. +

10.

+What do you mean S&T writes points with the wrong coordinates? +

+At some point in the "Export map to Pocketstreets" function in S&T, + it goofs the lat/long data. Points in Nashville tended to shift + 1.4 miles WEST of their original location. I'm not a geometry buff, + but I'd imagine they have a reference point for generating coordinates + that's wrong in (at least) that area. +

11.

+I have 800 waypoints that cover a dozen or so Pocketstreets maps. + Do I need to to split my points up into smaller chunks to match the + area covered by the maps? +

+ No. Pocketstreets will "ignore" points that are outside of the map + area. Points that are not on the current map will be "grayed out" + in pushpin explorer in Pocketsreets. This is the reason the PSP + module was written for GPSBabel in the first place. +

12.

+Where can I find documentation for the layout of PSP files? +

+Just about everything I know about the PSP file format is documented + in the source. To the best of my knowledge, there is no documentation + (and for good reason, I've come to discover). +

13.

+I have some other problem, what do I do? +

+Ask your question on the GPSBabel-Misc mailing list. +

MTK Logger (iBlue 747,...) Binary File Format (mtk-bin)

+ This format can... +

  • + read tracks +

Binary file protocol converter for MTK based GPS loggers. +This format reads the raw binary format created by the MTK Windows application +and outputs to other formats supported by GPSBabel +When using the csv option a MTK application compatible output file will also be created.

+It has been tested with Transystem i-Blue 747™ but other devices should +work as well (Qstarz BT-Q1000, iTrek Z1, ...) +

+All position items (including button push) will be listed as trackpoints in the output. +Log items due to button push are presented as waypoints. +In theory we would not add waypoints to the list of trackpoints. But as the MTK logger restart the +log session from the button press we would loose a trackpoint unless we include/duplicate it. + +

+Transystem i-Blue 747 +

Example 3.10. Convert MTK binary trackpoints to GPX

+ gpsbabel -t -i mtk-bin,csv=extra.csv -f data.bin -o gpx -F out.gpx + Additionally a CSV output file is created. +


csv option

+ MTK compatible CSV output file. +

+ Specifies a filename into which MTK-compatible CSV output will be written. +

+ Note that this option is a bit of an oddity in the GPSBabel arsenal. This + should probably be a "real" output type of its own instead of being bolted + onto an input type. +

MTK Logger (iBlue 747,Qstarz BT-1000,...) download (mtk)

+ This format can... +

  • + read tracks +

Serial download protocol for the i-Blue 747™ and other MTK based GPS data loggers. Observe that it is only possible to download data using USB cable, Bluetooth requires a hardware modification.

+Transystem i-Blue 747 +Downloaded data will be stored in data.bin file in the current directory together with +the choosen output format. +

It has been tested with Transystem i-Blue 747 but other devices should work as well (Qstarz BT-Q1000, iTrek Z1, ...)

See mtk-bin on how trackpoints/waypoints are handled

Example 3.11. Command showing MTK download track and waypoints and erase on Linux

gpsbabel -t -w -i mtk,erase -f /dev/ttyUSB0 -o gpx -F out.gpx


+ For more info and tweaks on MTK based loggers: + MTK Tips ans Tweaks + iBlue 747 Logger + For info about the used log format: + MTK binary format +

erase option

+ Erase device data after download. +

This option erases the track log from the device after download.

csv option

+ MTK compatible CSV output file. +

This option will create an additional CSV output file. +The CSV file is compatible with the original MTK logger application.

National Geographic Topo .tpg (waypoints) (tpg)

+ This format can... +

  • + read and write waypoints +

National Geographic Topo! Waypoint and Route Format. This module +reads and writes .TPG files created by various editions of NG Topo! +Reading/writing of route data is not supported yet.

Contributed by Alex Mottram.

datum option

+ Datum (default=NAD27). +

The option 'datum="datum name"' can be used to override +the default of NAD27 ("N. America 1927 mean") which is correct for the +continental U.S.

Any legal datum supported +by GPSBabel may be used. For example, points in Hawaii should +use "Old Hawaiian_mean".

National Geographic Topo 2.x .tpo (tpo2)

+ This format can... +

  • + read tracks +

+ This module reads tracks from .TPO files created by + National Geographic Topo! version 2.x +

+ Contributed by Steve Chamberlin. +

National Geographic Topo 3.x/4.x .tpo (tpo3)

+ This format can... +

  • + read waypoints +

  • + read tracks +

  • + read routes +

This module reads .TPO files created by National Geographic Topo! version +3.x and 4.x. It will read tracks, routes, waypoints, map notes, symbols, and +text notes. The latter three are converted to waypoints.

Contributed by Curt Mills.

Navicache.com XML (navicache)

+ This format can... +

  • + read waypoints +

This is the XML format that's used by Navicache.com for +their geocaching data. There are a number of fields in it that are +marked "required" but are Navicache-specific, so GPSBabel can not +write these files, but we can still read them. navicache.com +

noretired option

+ Suppress retired geocaches. +

+ If this option is present, retired (archived) caches will be suppressed on write. +

Navigon Mobile Navigator .rte files (nmn4)

+ This format can... +

  • + read and write routes +

Support for Navigon Mobile Navigator route (.rte) files. +This is a very simple text format that only requires coordinates, but +has fields for many other things. We only write coordinates as fields +like 'city' and 'street' cannot typically be populated from other +formats. www.navigon.com +

index option

+ Index of route to write (if more the one in source). +

+Because the format supports only one route, this option may be used +on output to select a single route from a collection of +routes read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. +

gpsbabel -i gpx -f routes.gpx -o nmn4,index=1 -F route1.rte -o nmn4,index=2 -F route2.rte

NaviGPS GT-11/BGT-11 Download (navilink)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+ GPSBabel supports the Navilink protocol used by the + Locosys GT-11 + GPS receivers. These are sold under a variety of names including: +

NaviGPSGT-11Amaryllo
NaviGPS-BTBGT-11 

+

+ This format is used for both the serial protocol used on + the USB link and for the files which can be copied from the + internal memory to the SD card using recent firmware versions. +

+ If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyUSB0") + to be read or written, GPSBabel will use the serial protocol. Specifying + a file, either on local filesystem or on a mounted flash card reader, + will results in the file-based format being used. +

+ To access the device using the serial protocol over USB the + device needs to be in Navilink mode, which can be activated + from the main menu of the device. +

+ Details of the Navilink serial protocol can be found + here. +

nuketrk option

+ Delete all track points. +

+This option erases all track data in the receiver before doing a transfer. +

+This is a convenient option to use in automated processes where you want +to ensure the units starts with a clean state before sending track data to +it. Using this option on transmit is a better idea than doing it on +receive since the latter would erase all the waypoints before asking the +unit to send all the waypoints. +

nukerte option

+ Delete all routes. +

+This option erases all routes in the receiver before doing a transfer. +

+This is a convenient option to use in automated processes where you want +to ensure the units starts with a clean state before sending routes to +it. Using this option on transmit is a better idea than doing it on +receive since the latter would erase all the waypoints before asking the +unit to send all the waypoints. +

nukewpt option

+ Delete all waypoints. +

+This option erases all waypoints in the receiver before doing a transfer. +

+This is a convenient option to use in automated processes where you want +to ensure the units starts with a clean state before sending waypoints to +it. Using this option on transmit is a better idea than doing it on +receive since the latter would erase all the waypoints before asking the +unit to send all the waypoints. +

power_off option

+ Command unit to power itself down. +

+This options powers down the Navilink receiver once any transfers are +complete. +

Navitrak DNA marker format (dna)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Navitrak DNA marker format - Another CSV format file. This +is the format that is compatible with the DNA Desktop import/export +command. Reading the binary Markers.jwp format directly off the data +card is not supported yet. Contributed by Tim Zickus.

NetStumbler Summary File (text) (netstumbler)

+ This format can... +

  • + read waypoints +

+This format reads summary files from NetStumbler™ +0.4 or MacStumbler™. +

+The default behavior when creating waypoints is to use the SSID for +the short name, and information about the access point for the +description. When the SSID is not unique, is not available, or +consists of whitespace, a short name is synthesized. +

+Different icons are assigned to encrypted, +non-encrypted, stealth, and non-stealth access points; these may be +changed with options. +

+NetStumbler +

+MacStumbler +

nseicon option

+ Non-stealth encrypted icon name. +

+This option specifies the name of the icon to use for +non-stealth, encrypted access points. +

nsneicon option

+ Non-stealth non-encrypted icon name. +

+This option specifies the name of the icon to use for +non-stealth, non-encrypted access points. +

seicon option

+ Stealth encrypted icon name. +

+This option specifies the name of the icon to use for +stealth, encrypted access points. +

sneicon option

+ Stealth non-encrypted icon name. +

+This option specifies the name of the icon to use for +stealth, non-encrypted access points. +

snmac option

+ Shortname is MAC address. +

+This option causes GPSBabel to use the MAC address as the short name for the +waypoint. The unmodified SSID is included in the waypoint description. +

NIMA/GNIS Geographic Names File (nima)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

This is a CSV format from the National Imagery and Mapping +Agency.

NMEA 0183 sentences (nmea)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

This format is the file representation of the NMEA +(National Marine Electronics Association) 0183 +log and waypoint format for GPS devices. Some hardware and software +that work with NMEA-0183 formatted data include: +

+ GPS Data Logger + + VisualGPS + + SparkFun GPS Datalogger +
+ GPS TrackMaker + + GPS Utility + + Sony GPS-CS1 +
+ GPSMaster + + GeoConv + 
+ NMEAlog + + CommLinx GPS recorder + 

+This module also supports realtime tracking +which allows realtime position reports from a GPS, such as one connected +serially, over Bluetooth, or a USB module emulating a serial port, to be used +with selected output formats. +

+When used in realtime tracking mode, if +GPSBabel does not sense incoming NMEA sentences arriving from the port, it +will send Sirf "reset to NMEA" commands to the port at a variety of speeds +in an attempt to communicate with an attached GPS. This lets devices +like the Microsoft GPS or Pharos GPS that are Sirf chips with an integrated +USB/Serial adapter work with this input format. +

snlen option

+ Max length of waypoint name to write. +

+This option specifies the maximum length to be used for waypoint names in +the GPWPL sentence. Longer names will be shortened to no more than this +length, but all waypoint names will remain unique. +

gprmc option

+ Read/write GPRMC sentences. +

+This option tells GPSBabel whether to read (on input) or write (on output) +GPRMC sentences. The default is to read or write GPRMC sentences. To +disable GPRMC sentences, specify gprmc=0. +

+GPRMC sentences contain the "recommended mimimum" positional information, +including date and time, heading, and velocity. Note that they do not +include altitude. For altitude, you will have to include GPGGA sentences. +

gpgga option

+ Read/write GPGGA sentences. +

+This option tells GPSBabel whether to read (on input) or write (on output) +GPGGA sentences. The default is to read or write GPGGA sentences. To +disable GPGGA sentences, specify gpgga=0. +

+GPGGA sentences contain the location and quality of the GPS position fix. +

gpvtg option

+ Read/write GPVTG sentences. +

+This option tells GPSBabel whether to read (on input) or write (on output) +GPVTG sentences. The default is to read or write GPVTG sentences. To +disable GPVTG sentences, specify gpvtg=0. +

+GPVTG sentences contain information about the heading and the speed at the +time of the fix. They do not contain any location information; for that +you will need either or both of GPGGA or GPRMC. +

gpgsa option

+ Read/write GPGSA sentences. +

+This option tells GPSBabel whether to read (on input) or write (on output) +GPGSA sentences. The default is to read or write GPGSA sentences. To +disable GPGSA sentences, specify gpgsa=0. +

+GPGSA sentences contain information on the quality of the positional fix +and the individual satellites from which it was derived. However, GPSBabel +neither reads nor writes the individual satellite data. On input, the +satellite fields are ignored and on output they are left blank. +

date option

+ Complete date-free tracks with given date (YYYYMMDD).. +

+On input, track points with times but no dates will have this date applied. +

+This is necessary because some NMEA sentences contain times but no dates. If +this option is not specified and the date cannot be determined from one or +more of the available NMEA sentences, the tracks will be discarded. +

get_posn option

+ Return current position as a waypoint. +

This options, when specified, returns the current position as a single +waypoint. +

pause option

+ Decimal seconds to pause between groups of strings. +

+This option tells GPSBabel to pause between individual track records when +used on output. This may be used with appropriate external software or +hardware to simulate a GPS receiver for testing purposes. On Unix, for +example, you may use a named pipe to feed the output from GPSBabel to gpsd. +

+If a value for this option is specified, it is in seconds and it may be +either a whole number of seconds or a fraction (e.g. 0.5 for a 1/2 second +pause between trackpoints.) +

+If this option is specified without a value, the time between adjacent +trackpoints will be computed and used for the length of the pause. That is, +if your trackpoints are 5 seconds apart, GPSBabel will pause 5 seconds +between trackpoints. +

+Note that very long tracks may be subject to clock drift, as GPSBabel does +not take into account the amount of time it may take to write the NMEA +sentences. Also, there is no guarantee that it will pause for exactly the +specified number of seconds between samples; different operating systems +will allow greater or lesser precision for timers, so actual precision may +be as much as plus or minus 100 milliseconds. +

+If you are using this option with compressed or simplified tracks from +your handheld GPS receiver, you might find the +interpolate filter useful. +

append_positioning option

+ Append realtime positioning data to the output file instead of truncating. +

+ When writing NMEA realtime positioning data, append to the + output file instead of truncating it on each successive position + fix. +

baud option

+ Speed in bits per second of serial port (baud=4800). +

+To the "nmea" module, the "baud" option specifies the baud rate of the +serial connection when used with the real-time tracking option. +

gisteq option

+ Write tracks for Gisteq Phototracker. +

+ This option writes the Gisteq format - which has the extension of .GPS - + to allow third-party GPS hardware with the Gisteq PhotoTrackr software. +

+ The Gisteq PhotoTrackr is a GPS data logger hardware and software package + that allows one to easily record the locations of where the user has taken + photos. The PhotoTrackr software works by comparing EXIF timestamps in + digital photos with the timestamps in the tracking data. In doing so, the + software plots the locations of the photos using Google Maps. The logging + format used by the Gisteq hardware is very close to NMEA format, but with a + few small quirks. +

+More information can be found at the +Gisteq site. +

Nokia Landmark Exchange (lmx)

+ This format can... +

  • + read and write waypoints +

+This format supports Nokia Landmark Exchange (LMX) files used by several +Nokia phones. GPSBabel supports only the traditional XML format and +not the compressed binary format. +

OpenStreetMap data files (osm)

+ This format can... +

  • + read and write waypoints +

  • + write tracks +

  • + read and write routes +

+ This format is used to exchange data with the OpenStreetMap project. + The main goal of this collaborative project is to create free editable maps. +

+ These data files are XML based. Every GPS element (way or node) described by the files has a unique + number as identifier. When we write OSM data files and don't know something about the id's, + negative numbers will be used as identifier. This has been tested with JOSM. +

+ Because the resulting timestamps of OSM ways differ from real GPS tracks, + we read OSM ways into routes. On the output side we write all available routes and tracks into the osm target file. +

tag option

+ Write additional way tag key/value pairs. +

+ With this option you can preset OSM features (tags) on all exported ways. +

+ gpsbabel -i gdb -f ways.gdb -o osm,tag="highway:motorway" -F ways.osm +

tagnd option

+ Write additional node tag key/value pairs. +

+ With this option you can preset OSM features (tags) on every written nodes. +

+ gpsbabel -i gdb -f nodes.gdb -o osm,tagnd="amenity:pub;building:yes" -F nodes.osm +

OziExplorer (ozi)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

OziExplorer Waypoint Format - Another CSV format file. +Tested against OziExplorer v 3.90.3a / Shareware. Contributed by Alex +Mottram

pack option

+ Write all tracks into one file. +

+ In normal case GPSBabel creates for each track a separate file (track.plt, track-1.plt, ...). + With this option all tracks will be written into one file. A '1' in the third field of the + trackpoint record signals the beginning of a new track. +

+ + gpsbabel -i gpx -f tracks.gpx -o ozi,pack -F track + +

snlen option

+ Max synthesized shortname length. +

+ This option allows you to specify the length of waypoint names written to this format when used with the -s option. +

snwhite option

+ Allow whitespace synth. shortnames. +

+ This option forces waypoint names generated with -s to allow whitespace in the names. +

snupper option

+ UPPERCASE synth. shortnames. +

+ When specified, this option will force generated shortnames to be in all uppercase letters. +

snunique option

+ Make synth. shortnames unique. +

+ When specified, this option will force the generated waypoint names to be unique. +

wptfgcolor option

+ Waypoint foreground color. +

+ This option allows you to specify a foreground color of a waypoint. You can specify it as either a decimal number or one of the standard web colors. +

wptbgcolor option

+ Waypoint background color. +

+ This option allows you to specify a background color of a waypoint. You can specify it as either a decimal number or one of the standard web colors. +

proximity option

+ Proximity distance. +

+ This option, specified in meters, allows you to set the proximity of +written in waypoints. +

PalmDoc Output (palmdoc)

+ This format can... +

  • + write waypoints +

+PalmDoc output is similar to Text +output, except that it generates a Palm Database (PDB) file suitable for +use with programs like CSpotRun, TealDoc, AportisDoc, Palm Reader, and +others. The resulting file also contains bookmarks to make it easy to jump +to a particular waypoint. +

+The following command line reads a GPX file with Groundspeak extensions +and writes a Palm document with encrypted hints and logs: +

gpsbabel -i gpx -f 12345.gpx -o "palmdoc,dbname=Unfound Geocaches,encrypt,logs" -F 12345.pdb

nosep option

+ No separator lines between waypoints. +

+To suppress the dashed lines between waypoints, use this option. +

dbname option

+ Database name. +

+This option specifies the internal name for the document. This is the name +that appears in your document reader, not the name of the file that is created +on your computer. +

encrypt option

+ Encrypt hints with ROT13. +

+Use this option to encrypt hints from Groundspeak GPX files. +

logs option

+ Include groundspeak logs if present. +

+Use this option to include Groundspeak cache logs in the created document. +

bookmarks_short option

+ Include short name in bookmarks. +

+If you would like the generated bookmarks to start with +the short name for the waypoint, specify this option. +

+This is particularly useful when used in combination with the 'sort' +filter. +

PathAway Database for Palm/OS (pathaway)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

PathAway is a Palm software designed for handling "most" +GPS devices (including BlueTooth). In this time (I mean 2005) a free +tool to convert this database is located on the homepage of PathAway +(www.pathaway.com). But I've read there ... for windows and the output +formats are also very limited. +

date option

+ Read/Write date format (i.e. DDMMYYYY). +

+This option specifies the input and output format for the date. The format +is written similarly to those in Windows. An example format is "YYMMDD". +

dbname option

+ Database name. +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

deficon option

+ Default icon name. +

+ The deficon option is used to control the icon output when writing to this format. It overrides any icon informatino that might be present in the source data. +

snlen option

+ Length of generated shortnames. +

+ This option allows you to specify the length of waypoint names written to this format when used with the -s option. +

Quovadis (quovadis)

+ This format can... +

  • + read and write waypoints +

QuoVadis for Palm OS marcosoft.com is a program for +Palm/OS. Working with record definitions provided by MarcoSoft and +further experimentation by Bruce Thompson and "Fuzzy" from the +Geocaching Forums to nail down the format precisely.

Should work fine for import and export.

One thing of note, QuoVadis stores all waypoints in a +single Palm Database without using categories. This means that it may +be difficult to keep personal waypoints separate from generated +waypoints. What Bruce recommends is taking the QuoVadisMarkerDB.PDB +file synced down from your Palm Powered device and extract the +waypoints you personally set to a GPX file. Then using GPSBabel's +joining capabilities generate a new PDB file from the personal file +and the other waypoint files of interest.

Currently the selection of icons to display and the scale +at which to display them is hardcoded. Also there is no support for +notes associated with waypoints. This will be addressed in a future +revision.

dbname option

+ Database name. +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

Raymarine Waypoint File (.rwf) (raymarine)

+ This format can... +

  • + read and write waypoints +

  • + read and write routes +

+ This format supports the "Raymarine Waypoint File" format (.rwf). + More information to Raymarine you'll find at their homepage. +

+ Known limits: max. 16 characters for waypoint names and max. 50 waypoints per route. +

location option

+ Default location. +

+ With this option you can specify the name of the folder + where the waypoints are placed. +

+ This name is also limited to 16 characters. +

See You flight analysis data (cup)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+ This format supports flight analysis data from the + See You + program. +

+ Position information is preserved, but the aviation-specific + information such as runway length and airport frequency, are + written as blanks and ignored on read. +

+ Tasks are not supported. +

Sportsim track files (part of zipped .ssz files) (sportsim)

+ This format can... +

  • + read and write tracks +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+ With this format we support Sportsim trackfiles located in zipped .ssz archives. +

+ Currently we cannot read zipped files directly with GPSBabel. So you have + to extract the archive before you can use any file. The trackfiles have .txt extensions. +

+From the Sportsim homepage: +

+ Sportsim provide software applications and web-based graphically + simulated performance information and image solutions to outdoor active people. +

Suunto Trek Manager (STM) .sdf files (stmsdf)

+ This format can... +

  • + read and write tracks +

  • + read and write routes +

+ This format supports the .sdf files from the Suunto product family + 'Suunto Trek Manager', 'Suunto Ski Manager' and 'Suunto Sail Manager'. + The contents of the sdf file depends on the used product and can + be one route or one track. Thatswhy when you want to use sdf on the + output side you have to use the + -r OR the -t option. This will tell + GPSBabel which type of data should be written. +

+ Currently we can read the following file types: +

4 = M9 TrackLog
5 = Route
28 = X9 TrackLog

+

gpsbabel -i gpx -f some-routes.gpx -r -o stmsdf,index=3 -F single-route.sdf

+ Suunto Website +

index option

+ Index of route (if more the one in source). +

+ Convert route number 'index' from source into sdf format. +

+ We have a lot of more expressive formats thats support more than one route. + At this place sdf files are limited to only one single route. With option index + you can specify which route from source should be converted. +

+ Our default index is 1. +

+ This example will convert route number two and three into separate sdf files: +

gpsbabel -i gdb -f routes.gdb -r -o stmsdf,index=2 -F route-one.sdf -r -o stmsdf,index=3 -F route-three.sdf

Suunto Trek Manager (STM) WaypointPlus files (stmwpp)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+This format supports the Suunto Trek Manager (STM) WaypointPlus format. +This is a simple format with coordinates and a time stamp. Route points +also have a short name. A single file may only contain one route or one +track. +

+Suunto Website +

index option

+ Index of route/track to write (if more the one in source). +

+Because the format supports only one route or track, this option may be used +on output to select a single route or track from a collection of routes and +tracks read from a more expressive format. If you have, say, a +gpx file that contains three routes, you may +use this option to write them one at a time to individual files. +

gpsbabel -i gpx -f routes.gpx -o stmwpp,index=1 -F route1.txt -o stmwpp,index=2 -F route2.txt -o stmwpp,index=3 -F route3.txt

Swiss Map # (.xol) format (xol)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

+ This module reads and writes xml based (.xol) files used by + Swiss Map software. +

+ These files uses the "Swiss national grid" (CS-1903) to store coordinates. +

Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Tab seperated export-all (except geocaching data) file +format. Intended to serve as source for number-processing +applications like OpenOffice, Ploticus and others. Tab was chosen as +delimiter because it is a) supported by both OpenOffice and Ploticus +and b) is not ',', so you can use sed -i +"s/./,/g" <x>.csv' to adapt it to locales where ',' is +used as decimal seperator. Contributed by Tobias Minich.

Textual Output (text)

+ This format can... +

  • + write waypoints +

This is a simple human readable version of the data file, +handy for listings of any type of waypoint files. +

The following command line reads a GPX file with +Groundspeak extensions and writes a text file with encrypted hints: +

gpsbabel -i gpx -f 12345.gpx -o text,encrypt -F 12345.txt

nosep option

+ Suppress separator lines between waypoints. +

+To suppress the dashed lines between waypoints, use this option. +

encrypt option

+ Encrypt hints using ROT13. +

+Use this option to encrypt hints from Groundspeak GPX files. +

logs option

+ Include groundspeak logs if present. +

+Use this option to include Groundspeak cache logs in the created document. +

degformat option

+ Degrees output as 'ddd', 'dmm'(default) or 'dms'. +

+When GPSBabel writes coordinates, this option is consulted to see if it +should write decimal degrees ('ddd') decimal minutes ('dmm') or degrees, +minutes, seconds ('dms'). The default is 'dmm'. +

altunits option

+ Units for altitude (f)eet or (m)etres. +

+This option should be 'f' if you want the altitude expressed in feet and +'m' for meters. The default is 'f'. +

splitoutput option

+ Write each waypoint in a separate file. +

+ Splits output into separate files for each waypoint by appending a + decimal number to the output filename. +

Example 3.12. Example for splitoutput option to text format

+ If "MyPQ.gpx" contains five waypoints, + + gpsbabel -i gpx -f MyPocketQuery -o text,split -F blah + + will result in files named blah1 ... blah5, each containing info + from one of those waypoints. +


TomTom Itineraries (.itn) (tomtom_itn)

+ This format can... +

  • + read and write routes +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+ tomtom_itn can be used to read and write TomTom Navigator Itineraries (Routes). +

TomTom POI file (.asc) (tomtom_asc)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+ With this format you can read and write TomTom + Points of Interest - POI (ascii) files. + It is a simple text (csv) format with only latitude, longitude and a short name. +

TomTom POI file (.ov2) (tomtom)

+ This format can... +

  • + read and write waypoints +

This format can read and write TomTom .ov2 (POI) files, +as used by the TomTom GO and TomTom Navigator. It has been tested +with an original TomTom GO running version 5.00 of the TomTom +software. There may be some records that confuse the input module - +if you have an example of such a record "in the wild", and you aren't +restricted from sharing it, we encourage you to post to the +gpsbabel-misc mailing list to contact a developer.

Note that in addition to the .ov2 file, you will need a +.bmp file for the icon. It should be 22x22 and 16 colors, and have +the same name (not including the extension) as the .ov2 file. +

TopoMapPro Places File (tmpro)

+ This format can... +

  • + read and write waypoints +

Reads and writes places files for +use in TopoMapPro places files. As this file +type can store links other than web links, anything that is not a http +url will be discarded. Note that this does not do datum conversions, +so if your input file does not have WGS84/NZGD2000 data, your output +file won't either. Colour of waypoint icons defaults to red.

TrackLogs digital mapping (.trl) (dmtlog)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

+ This format can be used to convert files from + TrackLogs Digital Mapping. The files + have extension .trl and can contain waypoints and tracks. +

+ We have seen three different types of this format. Two are binary + and one is an XML based format. All three types are supported + by our reader. +

index option

+ Index of track (if more the one in source). +

+ Convert track number 'index' from source into dmtlog format. +

+ The known variants of Tracklog 'digital mapping' files supports only + one track per file. If you have more than one track in source + (f.e MapSource and many others can do such heavy things), you + can specify which track should by used for the conversion. +

+ The default index is 1 (the first track of a possible list of tracks). +

+ An example usage you can find at the ignrando format, + which uses option index in same manner. +

U.S. Census Bureau Tiger Mapping Service (tiger)

+ This format can... +

  • + read and write waypoints +

The U.S. Census Bureau provides online mapping facilities. +This format is described at: tiger.census.gov. +Do notice that this format is not the actual Tiger line mapping +records, but rather the interface to their online mapping +program.

nolabels option

+ Suppress labels on generated pins. +

This option tells GPSBabel to not generate labels on the pins. If +this is true, the description of the incoming waypoints are ignored and not +placed on the pins.

genurl option

+ Generate file with lat/lon for centering map. +

+genurl is a convenience option for generating the scaling paramaters +when accessing the Tiger servers. It will output the latitude, longitude, +height, and width parameters in a form suitable for use in the URL to generate +a map that will hold all the points to be displayed and is suitably scaled +and centered. +

For example:

gpsbabel -i geo -f geocaching.loc -o tiger,genurl=tiger.ctr -F tiger.dat

+may create tiger.ctr with +

+lat=36.042108&lon=-86.877408&ht=0.161172&wid=0.591771&iwd=768&iht=768

+ +After uploading tiger.dat to a public server, a request to +

 http://tiger.census.gov/cgi-bin/mapgen?murl=$THATFILE$(cat tiger.ctr)

+will return a gif file from the tiger server that's suitably scaled. + +

margin option

+ Margin for map. Degrees or percentage. +

This option specifies a margin around the maps for the genurl options. +The margin may be specified in either decimal degrees or as a +percentage.

+This option is most useful for ensuring there is adaequate space for +the label around the markers when generating automatically scaled maps. +

snlen option

+ Max shortname length when used with -s. +

+The snlen option controls the maximum length of names generated by the '-s' +option. It's particularly useful in Tiger maps to avoid the amount of clutter +generated by potentially lengthy labels on the markers. +

oldthresh option

+ Days after which points are considered old. +

This options allows you to control the threshold in days between +whether a pin is considered "new" (and thus potentially governed by the +'newmarker' option) or "old" (and thus potentially governed by the +'oldmarker' option). +

oldmarker option

+ Marker type for old points. +

This option specifies the pin to be used if a waypoint has a creation +time newer than 'oldthresh' days.

The default is "redpin".

newmarker option

+ Marker type for new points. +

This option specifies the pin to be used if a waypoint has a creation +time older than 'oldthresh' days.

The default is "greenpin".

suppresswhite option

+ Suppress whitespace in generated shortnames. +

+When set, this options tells the '-s' smartname generator to not allow +any spaces in the labels generated for markers. +

unfoundmarker option

+ Marker type for unfound points. +

xpixels option

+ Width in pixels of map. +

The xpixels argument lets you specify the number of pixels to be +generated by the Tiger server along the horizontal axis when using the +'genurl' option.

ypixels option

+ Height in pixels of map. +

The ypixels argument lets you specify the number of pixels to be +generated by the Tiger server along the vertical axis when using the +'genurl' option.

iconismarker option

+ The icon description is already the marker. +

This options signifies that the icon in the incoming format is to be used +without change in the generated Tiger output file. Without this option, +GPSBabel tries to color pins based on their creation time and certain +Geocaching traits when available.

Universal csv with field structure in first line (unicsv)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+ Unicsv examines the first line of a file to determine the field + order and field separator in that file. On write, it tries to + figure out what data it has and writes headers and all the data it can. +

+ If the first line contains any tabs, the data lines are assumed + to be tab separated. Otherwise the fields are assumed to be + separated by commas. +

+ The list of keywords include: +

+      alt =      Elevation (in meters) of the point
+      bng_e =    British National Grid's easting
+      bng =      full coordinate in BNG format (zone easting northing)
+      bng_pos =  full coordinate in BNG format (zone easting northing)
+      bng_n =    British National Grid's northing
+      bng_z =    British National Grid's zone
+      caden =    Cadence
+      comment =  Notes
+      cour =     Heading / Course true
+      date =     Date (yyyy/mm/dd)
+      depth =    Depth
+      desc =     Description
+      ele =      Elevation (in meters) of the point
+      e/w =      'e' for eastern hemisphere, 'w' for western
+      fix =      3d, 2d, etc.
+      geschw =   Geschwindigkeit (speed)
+      hdop =     Horizontal dilution of precision
+      head =     Heading / Course true
+      heart =    Heartrate
+      height =   Elevation (in meters) of the point
+      icon =     Symbol (icon) name
+      lat =      Latitude
+      lon =      Longitude
+      name =     Waypoint name ("Shortname")
+      n/s =      'n' for northern hemisphere, 's' for southern
+      notes =    Notes
+      pdop =     Position dilution of precision
+      prox =     Proximity
+      sat =      Number of sats used for fix
+      speed =    Speed
+      symb =     Symbol (icon) name
+      tempf =    Temperature (degrees Fahrenheit)
+      temp =     Temperature (degrees Celsius)
+      time =     Time (hh:mm:ss[.msec])
+      url =      URL
+      utc_d =    UTC date
+      utc_t =    UTC time
+      utm_c =    UTM zone character
+      utm_e =    UTM easting
+      utm =      full coordinate in UTM format (zone zone-ch easting northing)
+      utm_pos =  full coordinate in UTM format (zone zone-ch easting northing)
+      utm_n =    UTM northing
+      utm_z =    UTM zone
+      vdop =     Vertical dilution of precision
+      x =        Longitude
+      x_pos =    Longitude
+      y =        Latitude
+      y_pos =    Latitude
+      z =        Altitude (elevation)
+   

+ We support some enhanced Garmin attributes. They are also available in + gpx, gdb, + garmin_gpi and partly + garmin_txt. These entities are currently + not visible in MapSource™ (6.12.4), but are NOT dropped + when working with GDB (version 3) or GPX files. +

+ Please note, that these do NOT provide a geocoding service; don't expect + to "convert" a street address to a latitude and longitude. +

+      addr =     Street address
+      city =     City
+      country =  Country
+      faci =     Facility (not available in GPX)
+      phone =    Phone number
+      post =     Postal code
+      state =    State
+   

+ Fuller spellings (i.e. "longitude") may be used. You can also + use keywords with a whitespace instead of an underscore. +

+ A typical file may be: +

+     Name, Latitude, Longitude, Description 
+     GCEBB,35.972033,-87.134700,Mountain Bike Heaven by susy1313
+     GC1A37,36.090683,-86.679550,The Troll by a182pilot & Family
+   

+

+ On the output side unicsv writes fixed number of columns (waypoint index, latitude and longitude) + followed by a variable column list depending on internal data. +

+ With at least ONE valid timestamp in data a unicsv output may look like that: +

+     No,Name,Latitude,Longitude,Description,Date,Time
+     1,"GCEBB",35.972033,-87.134700,"Mountain Bike Heaven by susy1313",2003/06/29,09:00:00
+     2,"GC1A37",36.090683,-86.679550,"The Troll by a182pilot & Family",,
+   

+

datum option

+ GPS datum (def. WGS 84). +

+ This option specifies the datum to be used on output. Valid values for this + option are listed in Appendix A, Supported Datums. +

grid option

+ Write position using this grid.. +

+ This value specifies the grid to be used on write. It is similar to + the grid option of garmin_txt (see Table 3.1, “Grid values for garmin_txt”). The only difference is that unicsv does not + write a degree sign (°) into the output file. +

+ Without this option unicsv writes the coordinates as simple numbers like in the samples above. +

utc option

+ Write timestamps with offset x to UTC time. +

+This option specifies the local time zone to use when writing times. It +is specified as an offset from Universal Coordinated Time (UTC) in hours. +Valid values are from -23 to +23. +

Vcard Output (for iPod) (vcard)

+ This format can... +

  • + write waypoints +

The vCard output is intended to be in a format that +enables waypoints to be viewed with an Apple iPod. This is achieved by +mapping waypoint fields into vCard fields that can be displayed as +'Contacts' on the iPod. With the iPod mounted as a hard disk (see your +iPod manual for instructions), the resulting VCF file should be moved +into the iPod 'Contacts' folder. As an alternative, Mac OS X users may +prefer to drag the VCF file into their address book and synchronize +with the iPod using iSync. +

encrypt option

+ Encrypt hints using ROT13. +

+By default geocaching hints are unencrypted; use this option to encrypt them. +

VidaOne GPS for Pocket PC (.gpb) (vidaone)

+ This format can... +

  • + read and write tracks +

+ This format supports the VidaOne GPS for pocket PC GPB file type. +

+ This is have a very simple binary format which stores only the coordinates + in the tracklog (.gpb) files. +

Vito Navigator II tracks (vitosmt)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

Vito Navigator II is a Pocket PC GPS application. This +format reads a Vito Navigator II .SMT track file and can work in +either waypoint or track mode. The speed, heading and Dilution of +Position data is written in the notes field.

Support for writing .SMT tracks is very experimental and +may crash VitoNavigator II on the Pocket PC.

Vito SmartMap tracks (.vtt) (vitovtt)

+ This format can... +

  • + read tracks +

+ This format reads the binary (.vtt) track logs recorded by + + VITO SmartMap for Nokia Series 60 + 1.0, a GPS application for smartphones connected to + NMEA 0183-compatible Bluetooth GPS receivers. It may work + with .vtt files produced by versions of VITO SmartMap + for other platforms. +

+ This format was reverse engineered from a .vtt file. + Currently, the coordinates, altitude, and time are + available for each point recorded in a track. + The course speed and heading fields have been identified, + but the units are not certain and so those fields are ignored. + The rest of the entry has not yet been decoded. The format + uses little-endian byte ordering. The application displays + metric units by default. Time is UTC. +

Table 3.4. track file header (8 bytes)

PositionField info
bytes 0-3Probably a version field. Int value is 3 in sample file.
bytes 4-7Number of points in file as int.

Table 3.5. track point (32 bytes)

PositionField info
bytes 0-3Decimal latitude multiplied by 20000000 as int.
bytes 4-7Decimal longitude multiplied by 10000000 as int.
bytes 8-11Altitude in meters as float.
bytes 12-13Year, with century, as int.
byte 14Month, ranging 1-12.
byte 15Day of month, ranging 1-31.
byte 16Hour, ranging 0-23.
byte 17Minute, ranging 0-59.
bytes 18-21Decimal second multiplied by 30000000 as int.
bytes 22-25 + Probably speed in meters per second as float. + Ranges 0-~3 in file, seems reasonable since sample + file was acquired on foot. +
bytes 26-27 + Probably decimal heading multiplied by something. + Ranges between min and max values possible when + decoded as integer. Doesn't change when speed field is 0. + Doesn't change smoothly, jumps around a bit. +
bytes 28-31 + Status field of some kind. Changes only twice in file. + May contain satellite count or PDOP info, as both are + reported by the application's GUI. +

WiFiFoFum 2.0 for PocketPC XML (wfff)

+ This format can... +

  • + read waypoints +

WFFF is the export format for Aspecto Software's WiFiFoFum 2.0 for Windows Mobile PCs.

It is a simple XML format that is read-only to GPSBabel and stores information about a WiFi stumbling session.

All WiFi-specific elements are written in the description field, similar to the netstumbler format.

aicicon option

+ Infrastructure closed icon name. +

+This option lets you specify an icon for infrastructure closed points. +

aioicon option

+ Infrastructure open icon name. +

+This option lets you specify an icon for infrastructure open points. +

ahcicon option

+ Ad-hoc closed icon name. +

+This options lets you specify an icon for an Ad-hoc, closed, waypoint. +

ahoicon option

+ Ad-hoc open icon name. +

+This options lets you specify an icon for an Ad-hoc, open, waypoint. +

snmac option

+ Shortname is MAC address. +

+ This options lets you specify that the shortname of the waypoint is the MAC address. +

Wintec WBT-100/200 Binary File Format (wbt-bin)

+ This format can... +

  • + read tracks +

File protocol for the Wintec WBT-200™ +and Wintec WBT-201™ (sometimes called the G-Rays 2™)GPS data loggers. This format reads the binary file format created +by Wintec's Windows application.

+Wintec WBT-201 +

Example 3.13. Command showing conversion of a Wintec binary file to GPX

gpsbabel -i wbt-bin -f tracks.bin -o +gpx -F out.gpx


Wintec WBT-100/200 GPS Download (wbt)

+ This format can... +

  • + read waypoints +

  • + read tracks +

Serial download protocol for the +Wintec WBT-200™ and +Wintec WBT-201™ +GPS data loggers. Although untested it is expected that this will also support the WBT-100.

+Wintec WBT-201 +

Example 3.14. Command showing WBT-200 download and erase over Bluetooth on Mac OS X

gpsbabel -t -w -i wbt,erase -f /dev/cu.WBT200-SPPslave-1 -o gpx -F out.gpx


+Internally, this is actually a serial device that has a serial/USB adapter +built into it. It uses the CP210x chip by Silicon labs. You will probably +need a driver for this chip. The product ships with one for Windows. +The Linux 210x driver seems to work fine. Mac users will need to download +the Mac driver for CP210x. +

+GPSBabel does not try to offer an interface to configure these units. That +is left to the Windows software that comes with it or tools like the +WBT 201 Viewer for Mac OS/X +and Linux. +

erase option

+ Erase device data after download. +

This option erases the track log from the device after download.

Wintec WBT-201/G-Rays 2 Binary File Format (wbt-tk1)

+ This format can... +

  • + read tracks +

File protocol for the Wintec WBT-201 / G-Rays 2™ +GPS data logger. This format reads the binary file format created +by Wintec's Time Machine X application.

+Wintec WBT-201 +

Example 3.15. Command showing conversion of a Wintec binary file to GPX

gpsbabel -w -t -i wbt-tk1 -f tracks.tk1 -o gpx -F out.gpx


Yahoo Geocode API data (yahoo)

+ This format can... +

  • + read waypoints +

+This format reads output from the +Yahoo geocoding API. +This feature of GPSBabel makes it easy to get geocoded results from +Yahoo into your favorite mapping program, GPS receiver, or other format. +

addrsep option

+ String to separate concatenated address fields (default=", "). +

+This option specifies the string GPSBabel should use to separate the parts +of the street address. Since most other formats supported by GPSBabel do +not support street addresses, the street address fields from the Yahoo file +are concatenated into the waypoint "notes" field. +

+The default value for this option is a comma followed by a space (", "). +



[1] This model does not support transfer of waypoints, tracks, or routes, but may be used with the realtime tracking feature.

[2] This unit uses GPX format, not Garmin protocol. Therefore one should communicate with it by reading and writing GPX files instead of using this format. Members of this class of products do not support realtime positioning protocol.

Chapter 4. Data Filters

GPSBabel supports data filtering. Data filters are + invoked from the command line via the '-x' option. It should be + noted that data filters are invoked in the internal pipeline at + the point that corresponds to their position on the + command. This implies that specifying a filter before reading + any data ('-x <filter> -f <file>'), despite being + legal, will not have any effect. The advantage is that filters + can be used intermittently between several variations of input + and output functions. It should also be noted that filtering + data from different input types can sometimes produce + undesirable results due to differences in the native data + formats. +

Beware that most filters only apply to a certain kind of + data. This is usually indicated below by referring to points, + tracks or routes in the first sentence which describes each + filter or in the table at gpsbabel.org + . +

Include Only Points Inside Polygon (polygon)

+The polygon filter includes points if they are inside +of a polygon. A polygon file looks like an +arc file, except +that the arc it describes must be a closed cycle. That is, +for a simple polygon, the first and last points must be the +same. Here's a square: +

+# A square (not really) polygon
+41.0000       -85.0000
+41.0000       -86.0000
+42.0000       -86.0000
+42.0000       -85.0000
+41.0000       -85.0000
+

+Polygons may include islands and holes. To include an +island or a hole, just append it to the main polygon. +

+# A square polygon with a triangular hole
+41.0000       -85.0000
+41.0000       -86.0000
+42.0000       -86.0000
+42.0000       -85.0000
+41.0000       -85.0000
+# The hole begins here
+41.5000       -85.5000
+41.6000       -85.5000
+41.6000       -85.6000
+41.5000       -85.5000
+

+As with the arc filter, you define a polygon by +giving the name of the file that contains it, using +the file option. +

+Note that this filter currently will not work properly +if your polygon contains one or both poles or if it spans the +line of 180 degrees east or west longitude. +

Example 4.1. Using the polygon filter

+Suppose you have a polygon file that defines the border of your county, +called mycounty.txt. This command line will give you only the points +in your county: +

gpsbabel -i geo -f 1.loc -x polygon,file=mycounty.txt -o mapsend -F 2.wpt


Example 4.2. Using the polygon and arc filters to find points in or nearly in a +polygon

+Because the polygon and arc filters use +the same file format, you can use them together to find all points that are +"in or nearly in" a polygon. This can be useful if your waypoints or the +boundaries of your polygon are not quite perfect, so you want to provide a +buffer zone around it in case there are points nearby that should be in the +polygon but aren't quite. +

+gpsbabel -i gpx -f points.gpx -x stack,push -x polygon,file=mycounty.txt +-x stack,swap -x arc,file=mycounty.txt,distance=1k -x stack,pop,append +-x duplicate,shortname -o gpx -F nearmycounty.gpx +

+This command makes a copy of the points, finds the ones that are in your +your county, swaps that result with the copy of the original set of points, +finds the ones from that set that are within 1 km of the border of the county, +puts the two lists together, and then filters out any points that appear twice +(This step is necessary because points inside the county but near the county +line will be kept by both the polygon and the arc filter.) +


file option

+ File containing vertices of polygon. +

+This option is required. +

+This option specifies the name of the file containing the polygon to use for +filtering. The format of the file is as described above. +

+GPSBabel supports converting any route or track to a file usable by this +filter; simply read it in the normal way and write it using the +arc file format. Afterward, you will +need to make sure that the first point and the last point in the +file are the same, as the polygon filter depends on that. You can do so +with any text editor. +

exclude option

+ Exclude points inside the polygon. +

+When this option is specified, the usual sense of the polygon filter is +reversed. That is, points that are inside the polygon are discarded +while points that are further away are kept. +

Include Only Points Within Distance of Arc (arc)

+This filter keeps or removes waypoints based on their proximity to an arc, +which is a series of connected line segments similar to a route or a track +but without any associated data other than the coordinates. +

+The arc is defined in a file whose name must be provided with the +file. That file contains pairs of coordinates for the +vertices of the arc, one coordinate pair per line. Comments may be +included by preceding them with a '#' character. An arc file looks +something like this sample: +

	  
+# Lima Road/SR3 north of Fort Wayne, Indiana 	  
+41.150064468    -85.166207433 	  
+41.150064468    -85.165371895 	  
+41.149034500    -85.165157318 	  
+41.147832870    -85.164771080 	  
+41.146631241    -85.164384842 	  
+41.144270897    -85.163655281 	  
+41.141953468    -85.162882805
+

+An arc file may optionally contain gaps in the arc. You may specify +such a gap by inserting a line containing "#break" either on a line by +itself or after the coordinates of the starting point of the new arc segment. +

Example 4.3. Using the arc filter

+Assuming the arc above is in a file called +lima_rd.txt, the following command line +would include only points within one mile of the section of Lima Road +covered by the arc. +

gpsbabel -i geo -f 1.loc -x arc,file=lima_rd.txt,distance=1 -o mapsend -F 2.wpt


file option

+ File containing vertices of arc. +

+This option is required. +

+This option specifies the name of the file containing the arc to use for +filtering. The format of the file is as described above. +

+GPSBabel supports converting any route or track to a file usable by this +filter; simply read it in the normal way and write it using the +arc file format. +

distance option

+ Maximum distance from arc. +

+This option is not required, but if it is not specified the distance +defaults to zero miles, which isn't very useful. +

+This option specifies the maximum distance a point may be from the arc +without being discarded. Points that are closer to the arc are kept, while +points that are further away are discarded. +

+Distances may be specified in miles (3M) or kilometers (5K). If no units +are specified, the distance is assumed to be in miles. +

exclude option

+ Exclude points close to the arc. +

+When this option is specified, the usual sense of the arc filter is reversed. +That is, points that are closer than distance are discarded +while points that are further away are kept. +

points option

+ Use distance from vertices not lines. +

+When this option is specified, only points that are within the specified +distance of one of the vertices of the arc are kept. This differs from the +normal mode of operation in that in the normal mode, points that are close to +the lines between points are also kept. +

+This option makes the arc filter act like a multi-point version of the +radius filter. +

Include Only Points Within Radius (radius)

+This filter includes or excludes waypoints based on their proximity to a +central point. All waypoints more than the specified distance from the +specified point will be removed from the dataset. +

+By default, all remaining points are sorted so that points closer to the +center appear earlier in the output file. +

Example 4.4. Using the radius filter to find points close to a given point

This example command line would include only points within 1 1/2 miles + of N30.000 W 90.000

gpsbabel -i geo -f 1.loc -x radius,distance=1.5M,lat=30.0,lon=-90.0 -o mapsend -F 2.wpt


lat option

+ Latitude for center point (D.DDDDD). +

+This option is required. +

+This option specifies the latitude of the central point in decimal degrees. +South latitudes should be expressed as a negative number. Valid values for +this option are from -90 to 90. +

lon option

+ Longitude for center point (D.DDDDD). +

+This option is required. +

+This option specifies the longitude of the central point in decimal degrees. +West longitudes should be expressed as a negative number. Valid values for +this option are from -180 to 180. +

distance option

+ Maximum distance from center. +

+This option is required. +

+This option specifies the maximum distance a point may be from the central +point in order to remain in the dataset. Points closer than this distance +will be kept and points further away will be removed (unless the +exclude option is specified.) +

+Distances may be expressed in miles (3M) or kilometers (4K). If no units +are provided, the distance is assumed to be in miles. +

exclude option

+ Exclude points close to center. +

+If this option is included, the action of the radius filter will be reversed: +points within the given distance will be removed, and points further away +will be kept. +

nosort option

+ Inhibit sort by distance to center. +

+If this option is specified, the radius filter will not sort the remaining +points by distance from the center. They will remain in whatever order they +were originally. +

maxcount option

+ Output no more than this number of points. +

+This option specifies the maximum number of points that the radius filter may +keep. If there are more than this number of points within the specified +distance of the center, the more distant points will be discarded even though +they are within the specified distance. If this option is not specified, +all points are kept regardless of how many there are. +

+Note that if the nosort option is also specified, this +option will instead keep points based on their position within the input +file rather than on their distance from the center. This may or may not be +what you want. +

+Note, too, that this option may be used with the exclude +option, but the results might not be what you expect. In particular, the +results will not be the same as if you had kept all of the points you'd +otherwise throw away. You will still get no more than +maxcount points, but they will all be at least +distance away from the center. (And possibly sorted.) +

asroute option

+ Put resulting waypoints in route of this name. +

+This option specifies the name of a route. If this option is specified, the +radius filter puts all points that are kept into a route with the given name. +The order of points in the route is by distance from the center (unless the +nosort option is also specified.) +

+Note that this route is not necessarily the most efficient route to visit +all of the points. In fact, for some data sets, it might be the least +efficient route. +

Interpolate between trackpoints (interpolate)

+This filter modifies any tracks so that either the distance or the time +between consecutive points is no less than the specified interval. Where +points are missing, the filter fills them in by following a straight +line (actually a great circle) between the adjacent points. You +must specify either the +distance or the time option. +

Example 4.5. Using the interpolate filter

+This command line reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 10 seconds apart: +

gpsbabel -i gpx -f track.gpx -x interpolate,time=10 -o gpx -F newtrack.gpx

+This command reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 15 kilometers apart: +

gpsbabel -i gpx -f track.gpx -x interpolate,distance=15k -o gpx -F newtrack.gpx

+This command reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 2 miles apart: +

gpsbabel -i gpx -f track.gpx -x interpolate,distance=2m -o gpx -F newtrack.gpx


time option

+ Time interval in seconds. +

+This option specifies the maximum allowable time interval between points in the +track. If two points in the track are further apart than this value, new +points will be inserted between them. +

+This value is always specified in units of seconds. +

+Either this option or the distance must be specified. +

distance option

+ Distance interval in miles or kilometers. +

+This option specifies the maximum allowable distance between points in the +track. If two points in the track are further apart than this value, new +points will be inserted between them. +

+This value may be specified in units of miles (3M) or kilometers (5K). If +no units are specified, the units are assumed to be miles. +

+Either this option or the time must be specified. +

route option

+ Interpolate routes instead. +

+If this option is specified, the interpolate filter interpolates routes +rather than tracks. Because route points do not have time stamps, it is an +error to use this option with the time option. +

Manipulate track lists (track)

+WARNING: This filter always drops empty tracks. +

+This filter performs various operations on track data. +

move option

+ Correct trackpoint timestamps by a delta. +

+This option changes the time of all trackpoints. This might be useful if +your track must be moved by one or more hours because of an incorrect +time zone. +

Example 4.6. Time-shifting a track with the track filter

+The following command line will shift all tracks to be one hour later. +

gpsbabel -t -i gpx -f in.gpx -x track,move=+1h -o gpx -F out.gpx


pack option

+ Pack all tracks into one. +

+This option causes all tracks to be appended to one another to form a single +track. This option does not work if any two tracks overlap in time; in that +case, consider using the merge option. +

+This option is most useful for rejoining tracks that might have +been interrupted by an equipment malfunction or an overnight stop. +

+If no other option is given to the track filter, this option is assumed. +

split option

+ Split by date or time interval (see README). +

The input track will be split into several tracks + depending on date of track points. If there is more than one + track, use the pack option before before using this. To + split a single tracks into separate tracks for each day and + name them, use this: +

gpsbabel -t -i gpx -f in.gpx -x track,split,title="ACTIVE LOG # %Y%m%d" -o gpx -F out.gpx

If the input has multiple tracks, pack them together before +splitting them back apart per day thusly:

gpsbabel -t -i gpx -f in.gpx + -x track,pack,split,title="ACTIVE LOG # %D" + -o gpx -F out.gpx

Additionally you can add an interval to the split + option. With this the track will be split if the time + between two points is greater than this parameter. The + interval must be numeric and can be int days, hours, minutes + or seconds, expressed as one of the character "d", "h", "m", + or "s". If no trailing character is present, the units are + assumed to be in seconds. +

For example, to split a track based on an four hour + interval, use this:

+gpsbabel -t + -i gpx -f in.gpx + -x track,pack,split=4h,title="LOG # %c" + -o gpx -F out.gpx +

sdistance option

+ Split by distance. +

The input track will be split into several tracks + if the distance between successive track points + is greater than the distance given as a parameter. + The distance must be numeric and can be in miles or kilometers, + expressed as one of the character "k", or "m". + If sdistance is given no parameters, this option has the same + effect as the split option without parameters. If there is more + than one track, + use the pack option before before using this.

For example, to split the track if the distance between + points is greater than 100 meters, use this:

+gpsbabel -t + -i gpx -f in.gpx + -x track,pack,sdistance=0.1k" + -o gpx -F out.gpx +

The sdistance option can be combined with the split option. + The track then will be split only if both time and distance + interval exceeds the supplied values. This technique can be used to + filter out gaps from + the tracklog. The gap is kept only if the gps device is without + signal for longer time than that given and during that time it moves + a distance over that given. + This example splits the track + if the device is without signal for at least 5 minutes + and during this time moves more than 300 meters:

+gpsbabel -t + -i gpx -f in.gpx + -x track,pack,sdistance=0.3k,split=5m + -o gpx -F out.gpx +

merge option

+ Merge multiple tracks for the same way. +

+This option puts all track points from all tracks into a single track +and sorts them by time stamp. Points with identical time stamps will be +dropped. +

Example 4.7. Merging tracks with the track filter

+Suppose you want to merge tracks recorded with two different GPS devices +at the same time. To do that, use this command line: +

gpsbabel -t -i gpx -f john.gpx -i gpx -f doe.gpx -x track,merge,title="COMBINED LOG" -o gpx -F john_doe.gpx


name option

+ Use only track(s) where title matches given name. +

+With the name option you can filter out a track by title. +

+The comparison is always non-case-sensitive. Wildcards are allowed. +

start option

+ Use only track points after this timestamp. +

+This option is used along with the stop to discard +trackpoints that were recorded outside of a specific period of time. +This option specifies the beginning of the time period. +

+If this option is not specified, the time period is assumed to begin at the +dawn of time or January 1, 1970, whichever was later. The time for this +option is expressed in UTC. +

+The value of this option must be in the form of YYYYMMDDHHMMSS, but it is +not necessary to specify the smaller time units if they are not needed. +That is, if you only care about points logged between 10 AM and 6 PM on a +given date, you need not specify the minutes or seconds. +

Example 4.8. Extracting a period of time with the track filter

+To get only the parts of a track that were mapped on 20 July 2005 +between 10 AM and 6 PM, use this command line: +

gpsbabel -t -i gpx -f in.gpx -x track,start=2005072010,stop=2005072018 -o gpx -F out.gpx


stop option

+ Use only track points before this timestamp. +

+This option is used in conjunction with the start option to +discard all trackpoints outside of a given period of time. This option +defines the end of the time period. +

+If this option is not specified, the time period is assumed to end at the +end of civilization as we know it or the year 2038, whichever comes first. +The time for this option is expressed in UTC. +

+See the start option for the format of this value and an +example of usage. +

title option

+ Basic title for new track(s). +

+This option specifies a title for tracks generated by the track filter. +By default, the title of the new track is composed of the start time of +the track appended to this value. +

+If this value contains a percent (%) character, it is treated as a format +string for the POSIX strftime function, allowing custom time-based +track names. +

fix option

+ Synthesize GPS fixes (PPS, DGPS, 3D, 2D, NONE). +

+This option sets the GPS fix status for all trackpoints to the specified +value. Valid values for this option are PPS, DGPS, 3D, 2D, or NONE. +

+This option is most useful when converting from a format that doesn't +contain GPS fix status to one that requires it. +

course option

+ Synthesize course. +

+This option computes (or recomputes) a value for the GPS heading at each +trackpoint. This is most useful with trackpoints from formats that don't +support heading information or for trackpoints synthesized by the +interpolate +filter. The heading at each trackpoint is simply the course from the +previous trackpoint in the track. The first trackpoint in each track +is arbitrarily assigned a heading of 0 degrees. +

speed option

+ Synthesize speed. +

+This option computes a value for the GPS speed at each trackpoint. +This is most useful with trackpoints from formats that don't support +speed information or for trackoints synthesized by the +interpolate +filter. The speed at each trackpoint is the average speed from the +previous trackpoint (distance divided by time). The first trackpoint +in each track is assigned a speed of "unknown." +

Rearrange waypoints by resorting (sort)

+This filter sorts waypoints into alphabetical order by the selected field. +You must specify exactly one of the options. +

gcid option

+ Sort by numeric geocache ID. +

+If the data contains Groundspeak geocache IDs, this option causes the +waypoints to be sorted in alphabetical order by geocache ID. +

+This option is not valid in combination with any other option. +

shortname option

+ Sort by waypoint short name. +

+This option causes the waypoints to be sorted in alphabetical order by +short name. +

+This option is not valid in combination with any other option. +

description option

+ Sort by waypoint description. +

+This option causes the waypoints to be sorted in alphabetical order by +description. +

+This option is not valid in combination with any other option. +

time option

+ Sort by time. +

+This option causes the waypoints to be sorted in chronological order by +creation time. +

+This option is not valid in combination with any other option. +

Remove all waypoints, tracks, or routes (nuketypes)

+There are three main types of data that GPSBabel deals with: +waypoints, tracks, and routes. The nuketypes filter allows +removing all the data of any or all of those three types. +

Example 4.9. Filtering data types with nuketypes

+If you have a GPX file that contains routes, tracks, and +waypoints and you want a GPX file that contains only tracks, +you may use this filter to remove the waypoints and the routes +with this command: +

gpsbabel -i gpx -f bigfile.gpx -x nuketypes,waypoints,routes -o gpx -F tracksonly.gpx


waypoints option

+ Remove all waypoints from data stream. +

+This option causes the nuketypes filter to discard all waypoints that are not +associated with a track or route. +

tracks option

+ Remove all tracks from data stream. +

+This option causes the nuketypes filter to discard all track data. +

routes option

+ Remove all routes from data stream. +

+This option causes the nuketypes filter to discard all route data. +

Remove Duplicates (duplicate)

+The duplicate filter is designed to remove duplicate points based on their +short name (traditionally a waypoint's name on the GPS receiver), and/or +their location (to a precision of 6 decimals). This filter supports two +options that specify how duplicates will be recognized, +shortname and location. +Generally, at least one of these options is required. +

Example 4.10. Using the duplicate filter to suppress points with the same + name and location

+ This command line removes points that have duplicate short names + and duplicate locations. The result would be a + gpx file that more than likely + contains only unique points and point data. +

gpsbabel -i gpx -f 1.gpx -f 2.gpx -x duplicate,location,shortname -o gpx -F merged_with_no_dupes.gpx


shortname option

+ Suppress duplicate waypoints based on name. +

+This option is the one most often used with the duplicate filter. This +option instructs the duplicate filter to remove any waypoints that share +a short name with a waypoint that has come before. This option might be +used to remove duplicates if you are merging two datasets that were +each created in part from a common ancestor dataset. +

location option

+ Suppress duplicate waypoint based on coords. +

+This option causes the duplicate filter to remove any additional waypoint +that has the same coordinates (to six decimal degrees) as a waypoint that +came before. This option may be used to remove duplicate waypoints if the +names are not expected to be the same. It also might be used along with the +shortname option to remove duplicate waypoints if the names +of several unrelated groups of waypoints might be the same. +

all option

+ Suppress all instances of duplicates. +

+When this option is specified, GPSBabel will remove all instances of a +duplicated waypoint, not just the second and subsequent instances. If +your input file contains waypoints A, B, B, and C, the output file will +contain waypoints A, B, and C without the all option, +or just A and C with the all option. +

Example 4.11. Using the duplicate filter to implement an "ignore list."

+This option may be used to implement an "ignore list." In the following +example, the duplicate filter is used to remove a list of waypoints to be +ignored from a larger collection of waypoints: +

gpsbabel -i gpx -f waypoints.gpx -i csv -f to_ignore.csv -x duplicate,shortname,all -o gpx -F filtered.gpx


correct option

+ Use coords from duplicate points. +

+This option is used to change the locations of waypoints without losing any +of the other associated information. When this option is specified, the +latitude and longitude from later duplicates will replace the latitude and +longitude in the original waypoint. +

+As an example, this option may be used to adjust the locations of "puzzle" +geocaches in a Groundspeak pocket query: +

Example 4.12. Using the duplicate filter to correct the locations of "puzzle" +geocaches

gpsbabel -i gpx -f 43622.gpx -i csv -f corrections.csv -x duplicate,shortname,correct -o gpx -F 43622-corrected.gpx

+After this command is run, the waypoints in the output file will have all +of the descriptive information from 43622.gpx, but +waypoints that were also found in corrections.csv +will have their coordinates replaced with the coordinates from that file. +


Remove Points Within Distance (position)

+This filter removes points based on their proximity to each other. A +point is removed if it is within the specified distance of a point that +has come before. +

Example 4.13. Using the position filter to suppress close points

+The following command removes multiple points that are within +one foot of each other, leaving just one. +

gpsbabel -i geo -f 1.loc -f 2.loc -x position,distance=1f -o mapsend -F 3.wpt


distance option

+ Maximum positional distance. +

+This option specifies the minimum allowable distance between two points. If +two points are closer than this distance, only one of them is kept. +

+Distances may be expressed in feet (30f) or meters (10m). If no unit is +specified, the distance is assumed to be in feet. +

all option

+ Suppress all points close to other points. +

+This option causes the position filter to remove all points that are within +the specified distance of one another, rather than leaving just one of them. +

+This option may be used to entirely remove clusters of points. +

Remove unreliable points with high hdop or vdop (discard)

+This filter is used to "fix" unreliable GPS data by discarding points +that are believed to be unreliable. You may specify an +HDOP and/or VDOP above a specified limit, a minimum number of satellits +that must have been in view for a fix to be considered, or both. +

+HDOP and VDOP are measures of the best possible horizontal or vertical precision for a given configuration of GPS satellites. Higher numbers indicate a higher dilution of precision and therefore mathematically less useful. +

+

Example 4.14. Using the discard filter for HDOP and VDOP.

gpsbabel -i gpx -f in.gpx -x discard,hdop=10,vdop=20,hdopandvdop -o gpx -F out.gpx


+

+You may specify a minimmum number of satellites. +

+

Example 4.15. Using the discard filter to require at least three satellites.

gpsbabel -i gpx -f in.gpx -x discard,sat=3 -o gpx -F out.gpx


+

Contributed by Tobias Minich and Serge Droz.

hdop option

+ Suppress waypoints with higher hdop. +

+This option specifies the maximum allowable Horizontal Dilution of +Precision (HDOP). By default, any point with an HDOP in excess of +this value will be discarded regardless of its VDOP, but see +hdopandvdop. +

vdop option

+ Suppress waypoints with higher vdop. +

+This option specifies the maximum allowable Vertical Dilution of +Precision (VDOP). By default, any point with an VDOP in excess of +this value will be discarded regardless of its HDOP, but see +hdopandvdop. +

hdopandvdop option

+ Link hdop and vdop supression with AND. +

+If this option is used, only points that exceed both the maximum +allowable HDOP and the maximum allowable VDOP will be discarded. This +option requires that both the hdop and +vdop options be specified. +

sat option

+ Minimium sats to keep waypoints. +

+This option specifies the minimum required number of satelites. +

Reverse stops within routes (reverse)

The reverse filter is used to reverse tracks and routes. + It's mostly useful for those few formats where track/route + sequence matters and there isn't a way to reverse them using + the program itself.

The reversal is performed in the laziest way possible. + Timestamps are kept with the original waypoints so the + resulting track or route will have the interesting + characteristic that time runs backwards. This tends to make + Magellan Mapsend, in particular, do a wierd thing and place + each waypoint on a separate day. +

Additionally, if you're using this to reverse a route + that navigates, say, an exit ramp or a one way street, you + will be in for unpleasant ride. application cares about + timestamps +

Save and restore waypoint lists (stack)

+This filter is designed to solve advanced problems that involve shuffling +multiple lists of waypoints, tracks, or routes. +

+The stack filter can be used to save the current state of the entire +collection of data. That state is placed on top of a stack of collections, +so you can simultaneously have as many stored collections of data as you +can fit in your computer's memory. +

+ The stack filter can be used in conjunction with other + filters to implement a "union" or "logical or" functionality. + The basic idea is to use the stack to store copies of the + original list of waypoints, then use the 'swap' function to + replace each copy with a filtered list. Finally, append all + of the filtered lists to create one big list, which is then + output. The following example finds a list of all points + that are either inside county A or inside county B. Any + points that are inside both counties are duplicated (but the + duplicates can be removed with the DUPLICATE filter; see + above.) +

+gpsbabel -i gpx -f in.gpx + -x stack,push,copy + -x polygon,file=county_a.txt + -x stack,swap + -x polygon,file=county_b.txt + -x stack,pop,append + -o gpx -F out.gpx +

This example reads a large list of waypoints and + extracts the points within 20 miles of each of two cities, + writing the waypoint descriptions into two different PalmDoc + files and exporting all of the points to the GPS receiver: +

+gpsbabel -i gpx -f indiana.gpx + -x stack,push,copy + -x radius,lat=41.0765,lon=-85.1365,distance=20m + -o palmdoc,dbname=Fort\ Wayne -F fortwayne.pdb + -x stack,swap + -x radius,lat=39.7733,lon=-86.1433,distance=20m + -o palmdoc,dbname=Indianapolis -F indianapolis.pdb + -x stack,pop,append + -o magellan -F fwaind.wpt +

push option

+ Push waypoint list onto stack. +

+This is one of three "primary" options to the stack filter. +

+When this option is specified, the current state is pushed onto the top of +the stack. By default, the current state is then cleared, but the +copy option can be used to cause it to be saved. +

pop option

+ Pop waypoint list from stack. +

+This is one of three "primary" options to the stack filter. +

+This option "pops" the collection of data from the top of the stack. +By default, the saved state replaces the current state, but see the +discard and append options for +alternatives. +

swap option

+ Swap waypoint list with <depth> item on stack. +

+This is one of three "primary" options to the stack filter. +

+When this option is specified, the current state is swapped with a saved +state from the stack. By default, it is swapped with the top of the stack, +but the depth can be used to specify a different saved +state. +

copy option

+ (push) Copy waypoint list. +

+This option is only valid when used with the push option. +When this option is specified, a copy of the current state is pushed onto +the stack but the current state is left unchanged. Otherwise, the push +operation clears the current data collection. +

append option

+ (pop) Append list. +

+This option is only valid in conjunction with the pop. +When it is specified, the topmost collection of data from the stack is +appended to the current collection of data. +

discard option

+ (pop) Discard top of stack. +

+This option is only valid when used with the pop option. +When this option is specified, the popped state is discarded and the current +state remains unchanged. +

replace option

+ (pop) Replace list (default). +

+This option is only valid when used with the pop option. +This is the default behavior of the pop option, so you +should never need to specify it, but it is included for the sake of +readability. When this option is specified, the popped state replaces +the current state. +

depth option

+ (swap) Item to use (default=1). +

+This option is only valid when used along with the swap +option. If specified, it indicates which item on the stack should be +swapped with the current state. The default value is 1, which corresponds +to the top of the stack. +

Simplify routes (simplify)

+The Simplify filter is used to simplify routes and tracks for use with +formats that limit the number of points they can contain or just to +reduce the complexity of a route. +

+The filter attempts to remove points from each route until the number +of points or the error is within the given bounds, while also attempting +to preserve the shape of the original route as much as possible. +

+The quality of the results will vary depending on the density of points +in the original route and the length of the original route. +

+For example, suppose you have a route from Street Atlas 2003 that you +wish to use with a Magellan GPS receiver that only supports up to 50 points +in a route: +

gpsbabel -r -i saroute -f RoadTrip.anr -x simplify,count=50 -o magellan -F grocery.rte

count option

+ Maximum number of points in route. +

+This option specifies the maximum number of points which may appear in the +simplified route. For example, if you specify "count=50", all resulting +routes will contain 50 points or fewer. +

+You must specify either this option or the error option. +

error option

+ Maximum error. +

+This option specifies the maximum allowable error that may be introduced +by removing a single point. The value of this option is a distance, +specified in miles by default. You may also specify the distance in +kilometers by adding a 'k' to the end of the number. +

+How the error is determined depends on whether the length +or crosstrack method is used. If you are using the length +method, the error is the change in the length of the route introduced by +removing a point. If you are using the crosstrack method, the error is the +distance from the point to the line that results if that point is removed. +

crosstrack option

+ Use cross-track error (default). +

+This option instructs GPSBabel to remove points that have the smallest +overall effect on the overall shape of the route. Using this method, the +first point to be removed will be the one that is closest to a line drawn +between the two points adjacent to it. +

+If neither this option nor the length option is specified, +this is the default. +

length option

+ Use arclength error. +

+This option instructs GPSBabel to simplify by removing points that cause the +smallest change in the overall length of the route first. +

Transform waypoints into a route, tracks into routes, ... (transform)

+ This filter can be used to convert GPS data between different data types. +

+ Some GPS data formats support only some subset of waypoints, tracks, + and routes. The transform filter allows you to convert between these + types. For example, it can be used to convert a pile of waypoints (such + as those from a CSV file) into a track or vice versa. +

+ The following example show you how to create a route from a waypoint table. +

gpsbabel -i csv waypts.txt -x transform,rte=wpt -o gpx -F route.gpx

+ Only the first letter of option value decides which transformation will be done. + Depending on the used option it can be only 'W' for waypoints, 'R' for routes or + 'T' for tracks. +

wpt option

+ Transform track(s) or route(s) into waypoint(s) [R/T]. +

+This option selects the destination type of this filter to be waypoints. +Choose this when you want to convert tracks or routes into waypoints. +

Example 4.16. Converting a track to a sequence of waypoints

+Say you you have a KML file that contains a track but you want to convert it to a CSV file that can contain only waypoints, perhaps to import into a spreadsheet. Use the following command: +

gpsbabel -i kml -f blah.kml -x transform,wpt=trk -o csv -F blah.txt


rte option

+ Transform waypoint(s) or track(s) into route(s) [W/T]. +

+This option selects the destination type of this filter to be routes. Choose this when you want to convert tracks into waypoints routes. A single route will be created in the sequence they appear in the input. +

Example 4.17. Converting a pile of waypoints to a GPX route

+Say you you have a data file that came from CSV file that you want to convert +to a GPX route that can be loaded into Mapsource. Use the following command: +

gpsbabel -i csv -f blah.txt -x transform,rte=wpt -o gdb -F blah.gdb


trk option

+ Transform waypoint(s) or route(s) into tracks(s) [W/R]. +

+This option selects the destination type of this filter to be tracks. +Choose this when you want to create tracks from a list of waypoints or routes. +A single track will be created in the sequence they appear in the input. +

Example 4.18. Converting a pile of waypoints to a GPX track

+Say you you have a data file that came from CSV file that you want to convert +to a GPX track that can be loaded into Mapsource. Use the following command: +

gpsbabel -i csv -f blah.txt -x transform,trk=wpt -o gdb -F blah.gdb


del option

+ Delete source data after transformation. +

+This option, when used in connction with the wpt, rte, or trk options, tells +GPSBabel to delete the source data after conversion. This is most useful if +you are trying to avoid duplicated data in the output. +

Example 4.19. Convert a GPX track to GPX waypoints, tossing the original track

gpsbabel -i gpx -f blah.gpx -x transform,wpt=trk,del -o gpx -F converted.gpx


Appendix A. Supported Datums

+Some formats in GPSBabel support multiple datums. For example, the +datum option to the +garmin_txt format allows you to specify +a datum for the output file. +

+The following is a list of the datums supported by GPSBabel. +

AdindanCuba NAD27La ReunionQornoq
AFGCyprusLiberia 1964Quatar National
Ain-El-AbdDjakarta(Batavia)LuzonRome 1940
Alaska-NAD27DOS 1968Mahe 1971S-42(Pulkovo1942)
Alaska-CanadaEaster lsland 1967Marco AstroS.E.Asia_(Indian)
Anna-1-AstroEgyptMasirah Is. NahrwanSAD-69/Brazil
ARC 1950 MeanEuropean 1950MassawaSanta Braz
ARC 1960 MeanEuropean 1950 meanMerchichSanto (DOS)
Asc Island 58European 1979 meanMexico NAD27Sapper Hill 43
Astro B4Finnish NauticalMidway Astro 61Schwarzeck
Astro Beacon EGandajika BaseMindanaoSicily
Astro pos 71/4Geodetic Datum 49MinnaSierra Leone 1960
Astro stn 52GhanaMontjong LoweS. Am. 1969 mean
Australia Geo 1984Greenland NAD27NahrwanSouth Asia
Bahamas NAD27Guam 1963Naparima BWISoutheast Base
Bellevue IGNGunung SegaraNorth America 83Southwest Base
Bermuda 1957Gunung Serindung 1962N. America 1927 meanTananarive Obs 25
Bukit RimpahGUX1 AstroObservatorio 1966Thai/Viet (Indian)
Camp_Area_AstroHerat NorthOld EgyptianTimbalai 1948
Campo_InchauspeHjorsey 1955Old Hawaiian_meanTokyo mean
Canada_Mean(NAD27)Hong Kong 1963Old Hawaiian KauaiTristan Astro 1968
Canal_Zone_(NAD27)Hu-Tzu-ShanOld Hawaiian MauiUnited Arab Emirates
Canton_Island_1966IndianOld Hawaiian OahuViti Levu 1916
CapeIranOmanWake Eniwetok 60
Cape_Canaveral_meanIreland 1965OSGB36WGS 72
Carribean NAD27ISTS 073 Astro 69Pico De Las NievesWGS 84
CarthageJohnston Island 61Pitcairn Astro 67Yacare
Cent America NAD27KandawalaS. Am. 1956 mean(P)Zanderij
Chatham 1971Kerguelen IslandS. Chilean 1963 (P)Sweden
Chua AstroKertau 48Puerto Rico 
Corrego AlegreL.C. 5 AstroPulkovo 1942 

Appendix B. Garmin Icons

+Following is a list of the valid values for the +garmin deficon option. +These values are also used internally by the +GDB, +BCR, +Mapsource, +Geoniche, +GPilotS, +PCX, and +PSITrex +formats. +

ATVContact, GlassesHunting AreaNumber 0, GreenScales
AirportContact, GoateeIce SkatingNumber 0, RedScenic Area
Amusement ParkContact, Kung-FuInformationNumber 1, BlueSchool
AnchorContact, PandaIntersectionNumber 1, GreenSeafood
Anchor ProhibitedContact, PigIntl freeway hwyNumber 1, RedSeaplane Base
Animal TracksContact, PirateIntl national hwyNumber 2, BlueShipwreck
Asian FoodContact, RangerItalian foodNumber 2, GreenShopping Center
Bait and TackleContact, SmileyLarge Ramp intersectionNumber 2, RedShort Tower
Ball ParkContact, SpikeLarge exit without servicesNumber 3, BlueShower
BankContact, SumoLetter A, BlueNumber 3, GreenSki Resort
BarControlled AreaLetter A, GreenNumber 3, RedSkiing Area
BeachConvenience StoreLetter A, RedNumber 4, BlueSkull and Crossbones
BeaconCoverLetter B, BlueNumber 4, GreenSmall City
BellCoveyLetter B, GreenNumber 4, RedSmall Game
Big GameCrossingLetter B, RedNumber 5, BlueSoft Field
Bike TrailDamLetter C, BlueNumber 5, GreenSquare, Blue
BlindDanger AreaLetter C, GreenNumber 5, RedSquare, Green
Block, BlueDeliLetter C, RedNumber 6, BlueSquare, Red
Block, GreenDepartment StoreLetter D, BlueNumber 6, GreenStadium
Block, RedDiamond, BlueLetter D, GreenNumber 6, RedState Hwy
Blood TrailDiamond, GreenLetter D, RedNumber 7, BlueSteak
Boat RampDiamond, RedLetterbox CacheNumber 7, GreenStreet Intersection
Border Crossing (Port Of Entry)Diver Down Flag 1LeveeNumber 7, RedStump
Bottom ConditionsDiver Down Flag 2LibraryNumber 8, BlueSummit
BowlingDockLightNumber 8, GreenSwimming Area
BridgeDot, WhiteLive TheaterNumber 8, RedTACAN
BuildingDrinking WaterLocalizer Outer MarkerNumber 9, BlueTall Tower
Buoy, WhiteDropoffLocationless (Reverse) CacheNumber 9, GreenTelephone
CampgroundElevation pointLodgeNumber 9, RedTide/Current PRediction Station
CarEvent CacheLodgingOil FieldToll Booth
Car RentalExitMan OverboardOpen 24 HoursTracBack Point
Car RepairExit without servicesMarinaOval, BlueTrail Head
CemeteryFast FoodMedical FacilityOval, GreenTree Stand
ChurchFirst approach fixMicro-CacheOval, RedTreed Quarry
Circle with XFishing AreaMile MarkerParachute AreaTriangle, Blue
Circle, BlueFishing Hot Spot FacilityMilitaryParkTriangle, Green
Circle, GreenFitness CenterMineParking AreaTriangle, Red
Circle, RedFlagMissed approach pointPharmacyTruck
City (Capitol)Flag, BlueMovie TheaterPicnic AreaTruck Stop
City (Large)Flag, GreenMulti-CachePin, BlueTunnel
City (Medium)Flag, RedMulti-CachePin, GreenU Marina
City (Small)Food SourceMuseumPin, RedU stump
City HallForestNavaid, AmberPizzaUS hwy
CivilFurbearerNavaid, BlackPolice StationUltralight Area
Coast GuardGambling/casinoNavaid, BluePost OfficeUnknown Cache
Contact, AfroGas StationNavaid, GreenPost OfficeUpland Game
Contact, AlienGeocacheNavaid, Green/RedPrivate FieldVHF Omni-range
Contact, Ball CapGeocache FoundNavaid, Green/WhitePuzzle CacheVOR-DME
Contact, Big EarsGeographic place name, Man-madeNavaid, OrangeRV ParkVOR/TACAN
Contact, BikerGeographic place name, landNavaid, RedRadio BeaconVirtual cache
Contact, BlondeGeographic place name, waterNavaid, Red/GreenRamp intersectionWater Hydrant
Contact, BugGhost TownNavaid, Red/WhiteRectangle, BlueWater Source
Contact, CatGlider AreaNavaid, VioletRectangle, GreenWaterfowl
Contact, ClownGolf CourseNavaid, WhiteRectangle, RedWaypoint
Contact, DogGround TransportationNavaid, White/GreenReefWebcam Cache
Contact, DreadlocksHeliportNavaid, White/RedResidenceWeed Bed
Contact, Female1HornNon-directional beaconRestaurantWinery
Contact, Female2HotelNullRestricted AreaWrecker
Contact, Female3HouseNumber 0, BlueRestroomZoo

Appendix C. GPSBabel XCSV Style Files

Introduction

+Often it is desirable to add a new file format for "one-off" work (perhaps +you want to export something to a spreadsheet or graphing program) or to read +a format that GPSBabel does not yet support. For suitably simple formats, +this can be done by a user with no programming experience by providing a +GPSBabel style file. +

+For a format to be described by a style file, it must be predictable and +generally readable by humant. Formats with binary or unreadable content +are not good fits for this scheme. It should have: +

A fixed header at the beginning, if it has any at all. This is called a 'prologue'.
Waypoints that are grouped by fixed separators, often a newline. In style file parlance, this is called a 'record'.
Traits of that waypoint described in that record. In the style files, these are called 'fields' and examples may include longitude or a name.
Fields that are grouped by fixed separators, often a comma or a tab. In the style files, this is called the field separator.
A fixed footer at the end, if it has any at all. This is called the 'epilogue'.

+

+Once you have created a style file that describes the file format you have +or want, you must tell GPSBabel to use the xcsv format and have the xcsv +format use that file. If you created a new style file called +"mystyle.style" and you want to write the waypoints from +a GPX file named "mine.gpx" to it, you would issue a command like: +

gpsbabel -i gpx -f mine.gpx -o xcsv,style=mystyle.style -F mine.new

+You might then examine mine.new to see if it met +your expectations. If not, you could continue to tweak +mystyle.style until it did, rerunning the above +command each time. If 'mystyle' is a format +that describes a popular program or is likely to be of use to others, you can +then share mystyle.style with other GPSBabel users. +Send it along with a coherent descripton to the GPSBabel-misc mailing +list for consideration to be included in a future version. +

Style file overview

+The first and foremost important step is understanding how the style +file is laid out itself. The format is: +

DIRECTIVE<whitespace>VALUE

+Where <whitespace> is one or more spaces or tabs. There should +be no spaces or tabs at the beginning of the line; all directives start +at the left edge in column zero. +

+An example style format is shown here: +


+
+# Format: MS S&T 2002/2003
+# Author: Alex Mottram
+#   Date: 12/09/2002
+#
+
+DESCRIPTION  Microsoft Streets and Trips 2002-2006
+EXTENSION               txt
+
+#
+# FILE LAYOUT DEFINITIIONS:
+#
+FIELD_DELIMITER TAB
+RECORD_DELIMITER NEWLINE
+BADCHARS ,"
+
+PROLOGUE Name Latitude Longitude Description URL Type Container Diff Terr
+
+#
+# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:
+# NOTE: MS S&T ONLY IMPORTS DATA, IT DOESN'T 
+#       EXPORT THIS ANYWHERE SO WE CAN HAVE OUR 
+#       WAY WITH THE FORMATTING. 
+#
+IFIELD SHORTNAME, "", "%s" # Name
+IFIELD LAT_DECIMAL, "", "%f" # Latitude
+IFIELD LON_DECIMAL, "", "%f" # Longitude
+IFIELD DESCRIPTION, "", "%s" # Name 2 (Big Description)
+IFIELD URL, "", "%s" # URL
+IFIELD GEOCACHE_TYPE, "", "%s" # Geocache Type
+IFIELD GEOCACHE_CONTAINER, "", "%s" # Geocache Type
+IFIELD GEOCACHE_DIFF, "", "%3.1f" # Geocache Type
+IFIELD GEOCACHE_TERR, "", "%3.1f" # Geocache Type
+

+Each of these lines will be explained in the following sections. +

Internal Constants

+A few internal constants are defined in the XCSV parser to make the style +file simpler. They may or may not be used and are optional in most cases. +Note that only certain style file directives map these constants. +

+

Style ConstantMaps to Char(s)
COMMA,
COMMASPACE,<space>
SINGLEQUOTE'
DOUBLEQUOTE"
COLON:
SEMICOLON;
NEWLINE\n
CR\r
CRNEWLINE\r\n
TAB\t
SPACE<space>
HASH#
PIPE|
WHITESPACEsee below

+

WHITESPACE

+The WHITESPACE constant has special properties. When reading data, +WHITESPACE refers to sequential runs of SPACES and/or TABS. When +writing data, WHITESPACE is always a single SPACE. +

+For example, the following line: +

SOME_NAME       30.1208 -91.1365    SOME OTHER NAME
+

+Parses into the following data fields: +

SOME_NAME,30.1208,-91.1365,SOME,OTHER,NAME
+

COMMENTS

+Anything after a hash (#) on a line is not parsed. For example: +

#THIS ENTIRE LINE IS A COMMENT.
+#FIELD	LAT_DECIMAL, "", "%f"   THIS ENTIRE LINE IS A COMMENT
+FIELD LAT_DECIMAL, "", "%f"  # ONLY THIS SENTENCE IS A COMMENT.
+

Global Properties of the File

+There are a few available directives to describe general traits of the +file being described and not specific data within the file itself. +

DESCRIPTION

+This is the description of the file format being described. This text +appears in the help screens and in menus used by the various GUI wrappers. +

EXTENSION

+This directive gives the filename extension generally associated with +this file. +

ENCODING

+Describes the character set used by this format. The value given +must be one listed by 'gpsbabel -l'. example: +

   ENCODING          UTF-8	# Use UTF-8 for input and output.
+

DATUM

+This value specifies the GPS datum to be used on read or write. Valid values for this +option are listed in Appendix A, Supported Datums. +

   DATUM             European 1950
+

DATATYPE

+Specifies the kind of data we have to read or write. +

+By default all data are seen as waypoint data. With DATATYPE you are now able to bind +a specific type to this format. Possible values are WAYPOINT, ROUTE or TRACK. +

   DATATYPE          ROUTE # route-only format
+

GPSBabel Behavior Directives

+There are a few available directives to control some of the internal +processing functions of GPSbabel. +

SHORTLEN

+ This sets the maximum allowed shortname length when using the internal + shortname synthesizer. +

+ example: +

   SHORTLEN	16	# shortnames will be at most 16 characters long.
+

SHORTWHITE

+ This tells the shortname synthesizer whether or not to allow whitespace + in the synthesized shortnames. Allowed values are zero and one. +

+ example: +

   SHORTWHITE	0	# Do not allow whitespace in shortname.
+   SHORTWHITE   1	# Allow whitespace in shortname.
+

Defining the Layout of the File

+The first few directives define the layout the physical file itself: +

FIELD_DELIMITER

+ The field delimiter defines the character(s) that separate the fields in + the rows of data inside the XCSV file. Common field delimiters are commas + and tabs. (referred to as "comma separated values" and "tab separated + values") +

+ examples: +

   FIELD_DELIMITER    COMMA
+   FIELD_DELIMITER    ~
+

+ The directive FIELD_DELIMITER is parsed for STYLE CONSTANTS as defined in + the table above. +

RECORD_DELIMITER

+ The record delimiter defines that character(s) that separate ROWS of + data (FIELDS) in the XCSV file. The most common record delimiters + are NEWLINE and CR (carriage return). +

+ examples: +

   RECORD_DELIMITER    NEWLINE
+   RECORD_DELIMITER    |
+

+ The directive RECORD_DELIMITER is parsed for STYLE CONSTANTS as defined + in the table above. +

BADCHARS

+ Bad characters are things that should *never* be written into the XCSV + file as data on output. GPSBabel automatically includes any non-blank + FIELD_DELIMITER and RECORD_DELIMITER characters as BADCHARS by default. +

+ examples: +

  BADCHARS    COMMA
+  BADCHARS    ~|
+

+ The directive BADCHARS is parsed for STYLE CONSTANTS as defined in the + table above. +

PROLOGUE

+ A prologue is basically constant data that is written to the output + file BEFORE any waypoints are processed. PROLOGUE can be defined + multiple times in the style file, once for each "line" before the data + begins. This is commonly used in XCSV files as a "header" row. +

+ examples: +

  PROLOGUE	OziExplorer Waypoint File Version 1.1
+  PROLOGUE	WGS 84
+  PROLOGUE	Symbol,Name,Latitude,Longitude
+

EPILOGUE

+ An Epilogue is the same as a prologue, except this data is written at + the END of the file. See the examples for PROLOGUE above. +

Defining Fields Within the File

+A field defines data. There are two different classifications of FIELDS, +IFIELD (file input) and OFIELD (file output). In the absence of any OFIELDS, +IFIELDS are use as both input and output. The existence of OFIELDS is +primarily to allow more flexible mapping of GPSBabel data to output data +(say, for instance, to map the internal GPSBabel "description" variable to +two or more fields on output). For all practical purposes, IFIELDS and +OFIELDS are defined the same way in the style file.

The following per-field options are defined: +

  • + "no_delim_before" is supported on in OFIELD tags to specify that this + field should be written without a field delimiter before it. It's + useful for limited field concatenation. +

  • + "absolute" is supported on OFIELD tags for lat and lon to indicate + that only absolute values (never negative) are to be printed. +

  • + "optional" is supported only OFIELD tags and indicates that the + field may or may not be available in the source data. If the + field is absent, no trailing field separator is written. +

    + This attribute is most useful when paired with "no_delim_before" as + it allows you to concatenate fields without concern for whether those + fields are actually populated or not. +

+There are several different types of fields that may be defined. Each field +consists of three pieces of information: the FIELD TYPE, a DEFAULT VALUE, and +a PRINTF CONVERSION (for output). In many cases, not all pieces are used, +but all 3 pieces are required. Additionally, an fourth field is supported +that modifies the behaviour of the field being described. +

+FIELDS should be defined in the style file in the logical order that they +appear in the data, from left to right. This is the order in which they are +parsed from input and written to output. +

+The fields used by the XCSV parser are as follows: +

IGNORE

+ IGNORE fields are, guess what, ignored on input. Internally, IGNORE + fields are treated as CHARACTER data, and as such, require a printf + conversion for a character array. +

+examples: +

   IFIELD IGNORE,"","%14.14s"   # (writes a 14 character blank field)
+   IFIELD IGNORE,"","%s"        # (writes a blank field on output)
+

CONSTANT

+ CONSTANT fields are, of course, constant. They are ignored on input, + however they write CONSTANT data on output. As such, they require a + DEFAULT VALUE and a printf conversion for a character array. +

+examples: +

   IFIELD CONSTANT,"FFFFFF","%s"   # (writes "FFFFFF" in the field)
+   IFIELD CONSTANT,"01/01/70","%s" # (a constant date field)
+

INDEX

+ An INDEX field is used ONLY on output. The INDEX constant defines a field + that, at output, contains the sequence number of the waypoint being + written, starting at 0. An index is managed internally as an INTEGER + and requires an INTEGER printf conversion. An INDEX has one special + property. The DEFAULT VALUE of the index is added to the index + on each iteration (to allow indexes starting at 1, 100, etc..). +

+examples: +

   IFIELD INDEX,"0","%04d"     # (Starts counting at zero)
+   IFIELD INDEX,"","%04d"      # (Starts counting at zero)
+   IFIELD INDEX,"1","%04d"     # (Starts counting at one)
+

SHORTNAME

+ A SHORTNAME is generally the waypoint name of the data being processed. + SHORTNAME maps directly to the GPSBabel variable ->shortname. A SHORTNAME + is CHARACTER data and requires a character array printf conversion. +

+example: +

   IFIELD SHORTNAME,"","%s"
+

DESCRIPTION

+ A DESCRIPTION is generally a long description of the waypoint. A + DESCRIPTION maps to the GPSBabel variable ->description and is otherwise + handled exactly like a SHORTNAME. +

+examples: +

   IFIELD DESCRIPTION,"","%s" 
+

NOTES

+ NOTES are generally everything else about a waypoints. NOTES map to the + GPSBabel variable ->notes and is otherwise handled exactly like a + SHORTNAME. +

URL

+ URL is a URL for the waypoint. URL maps to the GPSBabel variable + ->url and is otherwise handled exactly like a SHORTNAME. +

+example: +

   IFIELD URL,"","%s"
+

URL_LINK_TEXT

+ URL_LINK_TEXT is a textual description of where a URL points. + URL_LINK_TEXT maps to the GPSBabel variable ->url_link_text and + is otherwise handled exactly like a SHORTNAME. +

+example: +

   IFIELD URL_LINK_TEXT,"","%s" 
+

ICON_DESCR

+ ICON_DESCR is a textual description of an icon type for a waypoint. + ICON_DESCR maps to the GPSBabel variable ->icon_desc and is otherwise + handled exactly like a SHORTNAME. +

+example: +

   IFIELD ICON_DESCR,"","%s" 
+

LAT_DECIMAL

+ LAT_DECIMAL defines LATITUDE in DECIMAL format. Note that this is a PURE + signed decimal format (i.e. -91.0000). This data is handled internally as + a DOUBLE PRECISION FLOAT and requires a FLOATING POINT printf conversion. +

+example: +

   IFIELD LAT_DECIMAL,"","%f"
+

LON_DECIMAL

+ See LAT_DECIMAL, except LON_DECIMAL defines LONGITUDE. +

LAT_INT32DEG

+ LAT_INT32DEG defines LATITUDE in what I call INT32DEGREES. This value is + a signed LONG INTEGER and requires a LONG INTEGER printf conversion. + (This format is only used by some DeLorme products.) +

+example: +

   IFIELD LAT_INT32DEG,"","%ld"
+

LON_INT32DEG

+ See LON_INT32DEG except LON_INT32DEG defines LONGITUDE. +

LAT_DECIMALDIR / LAT_DIRDECIMAL

+ LAT_DECIMALDIR and LAT_DIRDECIMAL define LATITUDE in DECIMAL format + with the added bonus of a 'N/S' or 'E/W' direction character. This data + is handled internally as a DOUBLE PRECISION FLOAT and a single + CHARACTER and requires a FLOATING POINT as well as a CHARACTER printf + conversion. The only difference between the two is whether the directional + character appears before (LAT_DIRDECIMAL) or after (LAT_DECIMALDIR) the + decimal number. +

+examples: +

   IFIELD LAT_DECIMALDIR,"","%f %c"     #  (writes 31.333 N)
+   IFIELD LAT_DIRDECIMAL,"","%c %f"     #  (writes N 31.333)
+

LON_DECIMALDIR / LON_DIRDECIMAL

+ Same as LAT_DECIMALDIR / LAT_DIRDECIMAL except LON_ defines LONGITUDE. +

LAT_DIR / LON_DIR

+ LAT_DIR returns the single character 'N' or 'S' depending on the + hemisphere of the latitude. LON_DIR returns 'E' or 'W' depending on + the hemisphere of the longitude. +

LAT_HUMAN_READABLE

+ LAT_HUMAN_READABLE defines LATITUDE in a human-readable format. This + format is probably the most expressive format. It is similar to + LAT_DECIMALDIR in that it requires multiple printf conversions, but it + is far more flexible as to the contents of those conversions. On read, + the printf conversions are ignored and GPSBabel attempts to determine the + latitude and longitude based on what is in the file. +

+examples: +

+   #  (writes N 31 40.000)
+   IFIELD LAT_HUMAN_READABLE,"","%c %d %f"   
+   #  (writes "31 deg 40.000 min N")
+   IFIELD LAT_HUMAN_READABLE,"","%d deg %f min %c"
+   #  Note that this string will confuse the reading routine due 
+   #  to the letter "n" in "min" and the letter "e" in "deg."
+   # (writes 31 40 00.000N)
+   IFIELD LAT_HUMAN_READABLE,"","%d %d %f%c" 
+

MAP_EN_BNG

+ MAP_EN_BNG converts coordinates from/to British National Grid (BNG). +

+ The only supported order of the items is: Map,Easting,Northing. + During output all coordinates have to be located within this limited area. +

+examples: +

+   IFIELD MAP_EN_BNG,"","%s%5d %5d"   #  (writes i.e. "SJ00001 00001")
+   IFIELD MAP_EN_BNG,"","%s %d %d"    #  (writes i.e. "TQ 888 999")
+

LON_HUMAN_READABLE

+ See LAT_HUMAN_READABLE except LON_HUMAN_READABLE defines LONGITUDE. +

LATLON_HUMAN_READABLE

+ LATLON_HUMAN_READABLE is like LAT_HUMAN_READABLE and LON_HUMAN_READABLE + except that it reads and writes both latitude and longitude as a single + field. On write, the same format specifier is used for both coordinates. + On read, GPSBabel does exactly the same thing it does for + LAT_HUMAN_READABLE or LON_HUMAN_READABLE. +

+example: +

   IFIELD LATLON_HUMAN_READABLE,"","%c %d %f"
+           # (writes "N 31 40.126 W 85 09.62" as a single field)
+

LAT_NMEA

+ Defines the latitude in the format used by the NMEA standard which is + degrees multiplied by 100 plus decimal minutes. +

+example: +

   IFIELD  LAT_NMEA, "%f", "%08.3f"     # (writes  3558.322)
+

LON_NMEA

+ Defines the longitude in the format used by the NMEA standard which is + degrees multiplied by 100 plus decimal minutes. +

+example: +

   IFIELD  LON_NMEA, "%f", "%010.3f"  # (writes -08708.082)
+

LAT_10EX / LON_10EX

+ Defines the latitude or longitude in the format used i.e. by TomTom Navigator + itinerary files. It is degress multiplied by 10 power X. X have to be replaced with + a valid decimal value. A factor of 10000 would be generated by LAT_10E5 as shown + in the examples below. +

+examples: +

   IFIELD  LAT_10E5, "%f", "%.f"       # (writes  3558322)
+
   IFIELD  LON_10E5, "%f", "%.f"       # (writes -8708082)
+

ALT_FEET

+ ALT_FEET is the position's ALTITUDE in FEET. This value is treated as + a SIGNED DOUBLE PRECISION FLOAT and requires a FLOATING POINT printf + conversion. +

+example: +

   IFIELD ALT_FEET,"","%.0f"
+

ALT_METERS

+ ALT_METERS is identical to ALT_FEET with the exception that the altitude + is in METERS. +

HEART_RATE

+ Heart rate, measured in beats per minute. Only valid for units with + heart rate monitor features (i.e. Garmin Forerunner 301). +

+example: +

   IFIELD HEART_RATE,"","%d"
+

CADENCE

+ Cadence in revolutions per minute. Only valid for units with + heart rate monitor features (i.e. Garmin Edge 305). +

+example: +

   IFIELD CADENCE,"","%d"
+

EXCEL_TIME

+ EXCEL_TIME is the waypoint's creation time, if any. This is actually + the decimal days since 1/1/1900 and is handled internally as a DOUBLE + PRECISION FLOAT and requires a FLOATING POINT printf conversion. +

+example: +

   IFIELD EXCEL_TIME,"","%11.5f"
+

TIMET_TIME

+ TIMET_TIME is the waypoint's creation time, if any. This is actually + the integer seconds since 1/1/1970 (let's not start the holy war) and + is handled internally as a LONG INTEGER and requires a LONG INTEGER + printf conversion. +

+example: +

   IFIELD TIMET_TIME,"","%ld"
+

YYYYMMDD_TIME

+ YYYYMMDD_TIME is the waypoint's creation time, if any. It's a single + decimal field containing four digits of year, two digits of month, + and two digits of date. Internally it is a LONG INTEGER and thus + requires a LONG INTEGER printf conversion. +

+example: +

   IFIELD YYYYMMDD_TIME,"","%ld"
+

GMT_TIME

+ GMT_TIME is the waypoint's creation time, in UTC time zone. It uses the + strptime conversion format tags. +

+example: +

   IFIELD GMT_TIME,"","%m/%d/%Y %I:%M:%D %p"
+

+ Search the web for 'strptime man page' for details strptime, but one + such page can be found at +http://www.die.net/doc/linux/man/man3/strptime.3.html +

LOCAL_TIME

+ LOCAL_TIME is the waypoint's creation time, in the local + time zone. It uses strptime conversion format tags. See GMT_TIME for a + reference. +

+example: +

   IFIELD LOCAL_TIME,"","%y-%m-%d"
+

HMSG_TIME

+ HMSG_TIME parses up to three time parts and am/pm string to add + this value to the previously parsed *_TIME field that contains + only a date. On output, will print the time in UTC. +

+example: +

   IFIELD HMSG_TIME,"","%d:%d:%d %s"
+

HMSL_TIME

+ HMSG_TIME parses up to three time parts and am/pm string to add + this value to the previously parsed *_TIME field that contains + only a date. On output, will print the time in local time. +

+example: +

   IFIELD HMSL_TIME,"","%dh%dm"
+

ISO_TIME

+ ISO_TIME is the waypoint's creation time, in ISO 8601 format, + which include time zone information. + It is expected to be in the format yyyy-mm-ddThh:mm:sszzzzz + where zzzzzz is the local time offset or the character Z + for UTC time. + On output, UTC 'Z' time zone will always be used. +

+example: +

   IFIELD ISO_TIME,"","%s"
+

ISO_TIME_MS

+ ISO_TIME_MS is much like ISO_TIME, but expresses milliseconds at the + end of the timestamp. + It is thus in the format yyyy-mm-ddThh:mm:ss.SSSzzzzz + where 'SSS' is milliseconds and zzzzzz is the local time offset + or the character Z for UTC time. + On output, UTC 'Z' time zone will always be used. +

+example: +

   IFIELD ISO_TIME_MS,"","%s"
+

GEOCACHE_DIFF

+ GEOCACHE_DIFF is valid only for geocaches and represents a DOUBLE + PRECISION FLOAT. This is the geocache "difficulty" rating as defined by + Groundspeak. A "three and a half star" cache would therefore be "3.5" +

+example: +

   IFIELD GEOCACHE_DIFF,"","%3.1f"
+

GEOCACHE_TERR

+ GEOCACHE_TERR is valid only for geocaches and represents a DOUBLE + PRECISION FLOAT. This is the geocache "terrain" rating as defined + by Groundspeak. A "three and a half star" cache would therefore be "3.5" +

+example: +

   IFIELD GEOCACHE_TERR,"","%3.1f"
+

GEOCACHE_CONTAINER

+ GEOCACHE_CONTAINER is valid only for geocaches and is heavily influenced + by the Groundspeak container types. Examples would include "Micro" + and "Virtual". +

+example: +

   GEOCACHE_CONTAINER,"","%s"
+

GEOCACHE_TYPE

+ GEOCACHE_TYPE is valid only for geocaches and is heavily influenced + by the Groundspeak cache types. Examples would include "Event cache" + and "Multi-Cache". +

+example: +

   GEOCACHE_TYPE,"","%s"
+

GEOCACHE_PLACER

+ GEOCACHE_PLACER is a string containing the name of the placer of a + geocache. +

+example: +

   GEOCACHE_PLACER,"","%s"
+

GEOCACHE_ISAVAILABLE

+ GEOCACHE_ISAVAILABLE is a string containing "True" or "False" + indicating whether a geocache is currently available or not. +

+example: +

   GEOCACHE_ISAVAILABLE,"","%s"
+

GEOCACHE_ISARCHIVED

+ GEOCACHE_ISARCHIVED is a string containing "True" or "False" + indicating whether a geocache has been archived. +

+example: +

   GEOCACHE_ISARCHIVED,"","%s"
+

GEOCACHE_LAST_FOUND

+ A long integer in format YYYYMMDD containing the last time this geocache + was found. +

+example: +

   GEOCACHE_LAST_FOUND,"","%ld"
+

GEOCACHE_HINT

+ The hint for this geocache. No additional transformation (such as rot13) + will be performed on this string. +

+example: +

   GEOCACHE_HINT,"","%s"
+

PATH_DISTANCE_MILES

+ PATH_DISTANCE_MILES outputs the total length of the route or track from + the start point to the current point, in miles. This and the altitude + could be used to create an elevation profile. PATH_DISTANCE_MILES is + a DOUBLE PRECISION FLOAT. +

+ PATH_DISTANCE_MILES is not valid as an input field. +

+ PATH_DISTANCE_MILES is only meaningful if the data comes from a track + or a route; waypoint data will generate essentially meaningless output. +

+example: +

   PATH_DISTANCE_MILES,"","%f"
+

PATH_DISTANCE_KM

+ PATH_DISTANCE_KM is like PATH_DISTANCE_MILES except it outputs the + length in kilometers. +

PATH_SPEED

+ Speed in meters per second. Gpsbabel does NOT calculate this data by + default; it is read from the input file if present. (If not present, + it may be calculated with the track + filter.) +

+example: +

   PATH_SPEED,"","%f"
+

PATH_SPEED_KPH

+ Like PATH_SPEED but means kilometers per hour. +

+example: +

   PATH_SPEED_KPH,"","%.1f"
+

PATH_SPEED_MPH

+ Like PATH_SPEED but means miles per hour. +

+example: +

   PATH_SPEED_MPH,"","%.1f"
+

PATH_SPEED_KNOTS

+ Like PATH_SPEED but means knots (nautical). +

+example: +

   PATH_SPEED_KNOTS,"","%.1f"
+

PATH_COURSE

+ Course in degerees. Gpsbabel does not calculate this data by default; + it is read from the input file if present. (If not present, it may be + calculated with the track filter.) +

+example: +

   PATH_COURSE,"","%f"
+

GPS_HDOP / GPS_VDOP / GPS_PDOP

+ GPS horizontal / vertical / positional dilution of precision + parameters. Needs float conversion. +

+example: +

   GPS_HDOP,"","%f"
+

GPS_SAT

+ Number of satellites used for determination of the position. Needs + integer conversion. +

+example: +

   GPS_SAT,"","%d"
+

GPS_FIX

+ Type of fix (see GPX spec or track +filter). Needs string conversion. +

+example: +

   GPS_FIX,"","%s"
+

TRACK_NAME

The name of the track currently being operated on. Needs string conversion.

example:

TRACK_NAME, "", "%s"

ROUTE_NAME

The name of the route currently being operated on. Needs string conversion.

example:

ROUTE_NAME, "", "%s"

STREET_NAME

Street address including house number. Notice that this is not used for any geocoding, it's merely textual description associated with a position.

example:

STREET_ADDR, "", "%s"

CITY

The name of a city. Sometimes part of "Points of Interest". This is simple textual data associated with a position, no geocoding will be done..

example:

CITY, "", "%s"

COUNTRY

The name of a country associated with a position.

example:

COUNTRY, "", "%s"

FACILITY

The name of a facility to associate with a position.

example:

FACILITY, "", "%s"

PHONE_NR

A phone number associated with a position. This is just textual data attached for convenience.

example:

PHONE_NR, "", "%s"

POSTAL_CODE

A postal code to associate with a position. It is freeform text and is not used by GPSBabel for any geocoding or such.

example:

POSTAL_CODE, "", "%s"

Examples

+Here is one example style file from the GPSBabel source. +


+# gpsbabel XCSV style file
+#
+# Format: Garmin POI
+# Author: Robert Lipe
+# Date: 10/07/2005
+# Reference: http://forums.groundspeak.com/GC/index.php?showtopic=110641&st=0&#entry1752204
+#
+DESCRIPTION Garmin POI database
+#
+#
+# FILE LAYOUT DEFINITIIONS:
+#
+FIELD_DELIMITER COMMA
+RECORD_DELIMITER NEWLINE
+BADCHARS COMMA
+SHORTLEN 24
+
+#
+# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:
+#
+IFIELD LON_HUMAN_READABLE, "", "%08.5f"
+IFIELD LAT_HUMAN_READABLE, "", "%08.5f"
+IFIELD SHORTNAME, "", "%s"
+IFIELD DESCRIPTION, "", "%s"
+
+OFIELD LON_DECIMAL, "", "%08.5f"
+OFIELD LAT_DECIMAL, "", "%08.5f"
+OFIELD SHORTNAME, "", "%-.24s"
+OFIELD GEOCACHE_TYPE, "", " %-.4s", "no_delim_before,optional"
+OFIELD GEOCACHE_CONTAINER, "", "/%-.4s ", "no_delim_before,optional"
+OFIELD GEOCACHE_DIFF, "", "(%3.1f", "no_delim_before,optional"
+OFIELD GEOCACHE_TERR, "", "/%3.1f)", "no_delim_before,optional"
+OFIELD DESCRIPTION, "", "%-.50s"
+

+When used on a Groundspeak Pocket Query, it will output lines that +look like: +


+-76.76234,38.39123,GC5370 Loca/Virt (1.0/1.0),Dude.. Wheres my Limo??
+-90.42345,38.55234,GCC8B Trad/Regu (2.0/2.0),Sweet Reward
+-90.81456,38.62456,GC3091 Trad/Regu (1.5/2.0),Matson Hill
+

+that are suitable for Garmin's POI loader. +

+For additional examples, please see the +*.style files in the +style/ subdirectory of GPSBabel or at the online source tree. +

Miscellaneous Notes

Default Values

+Default values are supported for any output fields that contain pure + character data output such as URL and NOTES. Default values are only + written on output and are not used to supplement missing input. When + using default values your mileage will vary greatly depending on the + input formats used to populate waypoint data. +

Glossary

Terms that are used in conjunction with GPSBabel.

G

Geocaching

GPS based "paper chase", see + http://en.wikipedia.org/wiki/Geocaching

I

Itinerary

same as a Route (e.g. used by TomTom)

P

Points of Interest (POI)

a collection of gas stations, post boxes, shops and + like.

R

Route

a list of geopoints (often with names) connected in + a specific order. Usually a collection of geopoints + defining the route you want to pass while traveling, + created by PC software, or generated inside a GPS device. + They can be composed of existing waypoints, or new + "routepoints" might be generated.

T

Track

a collection of geopoints recorded by your GPS + device while traveling -- "breadcrumb trails". The order + of trackpoints within the track is important. Usually a + trackpoint doesn't have a name or comment, but a + timestamp. This distinguishes a trackpoint from a + waypoint.

W

Waypoints

are geopoints that are not necessarily connected to + other points, and their order is unimportant. They can be + entered before, while or after you actually visit the + place and might have tags like name, comment and the + like. Usually used to mark special locations as your + home, a hotel or a geocache.

diff --git a/gpsman b/gpsman new file mode 100644 index 000000000..771a261f5 --- /dev/null +++ b/gpsman @@ -0,0 +1,53 @@ +% Written by GPSManager 05-Apr-2002 21:52:36 (EST) +% Edit at your own risk! + +!Format: DMS 1 WGS 84 +!Creation: no + +!W: +GC894 N41 20 07.9 W85 24 31.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC1F78 N40 43 04.1 W85 06 25.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +003 N41 07 21.3 W85 09 23.5 symbol=boat_ramp alt=220.506469727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC93 N41 43 09.4 W85 58 59.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2193 N40 25 29.0 W86 54 52.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +004 N41 07 22.6 W85 09 24.3 symbol=flag alt=250.787719727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCA80 N40 29 14.3 W86 51 50.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC28CB N40 50 32.8 W85 25 20.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2665 N40 45 56.4 W85 35 58.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +005 N41 02 51.4 W85 16 41.6 symbol=flag alt=263.044433594 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCB78 N40 26 17.9 W86 54 02.2 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2ADC N40 26 16.4 W86 48 21.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +ABACUS N41 04 20.6 W85 13 50.8 symbol=building alt=243.577880859 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCD85 N41 05 03.3 W85 08 11.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCB8 N40 26 09.5 W87 09 49.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2BE8 N40 52 45.9 W85 32 26.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CASH1 N41 04 41.8 W85 08 19.3 symbol=flag alt=245.740844727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +H0ME N41 02 51.7 W85 16 42.1 symbol=house alt=272.176879883 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C81 N41 12 24.2 W85 02 23.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CENCEN N41 41 39.0 W86 14 53.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +TOSB2 N41 44 00.4 W84 59 46.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C90 N40 50 08.2 W85 27 14.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CWORK N41 07 23.0 W85 09 24.7 symbol=flag alt=254.633056641 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +TOSB3 N41 43 21.9 W86 15 20.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C91 N41 05 01.4 W85 08 18.7 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB1 N41 40 34.1 W86 15 01.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +UNITA N41 02 52.2 W85 16 41.6 symbol=flag alt=256.795898438 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2F53 N41 43 57.0 W86 04 48.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB2 N41 38 10.3 W86 15 04.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC333A N41 01 42.7 W85 11 49.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB4 N41 37 27.7 W86 15 08.7 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB5 N41 38 53.4 W85 56 55.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC34D4 N41 58 16.8 W86 11 05.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB6 N41 34 46.3 W85 50 01.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC42A1 N41 05 02.1 W85 03 14.2 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC37C4 N41 38 15.5 W85 54 19.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB7 N41 07 42.2 W85 11 47.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC4378 N40 53 27.2 W85 28 13.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC11EF N40 01 45.3 W86 53 17.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC44E5 N41 01 03.7 W85 15 07.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC12FF N41 33 23.9 W86 21 26.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC47A5 N40 25 15.3 W86 54 17.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC17E0 N41 52 01.5 W86 36 12.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC488D N41 33 43.7 W85 50 18.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC1A9C N41 06 36.2 W85 09 20.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA + diff --git a/gpsman2 b/gpsman2 new file mode 100644 index 000000000..4cf6db838 --- /dev/null +++ b/gpsman2 @@ -0,0 +1,75 @@ +% Written by GPSManager 24-May-2002 13:51:04 (CST) +% Edit at your own risk! + +!Format: DMM 1 WGS 84 +!Creation: no + +!W: +!Position: DMS +GC37C4 N41 38 15.5 W85 54 19.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +H0ME N41 02 51.7 W85 16 42.1 symbol=house alt=272.176879883 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC894 N41 20 07.9 W85 24 31.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB7 N41 07 42.2 W85 11 47.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C81 N41 12 24.2 W85 02 23.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC1F78 N40 43 04.1 W85 06 25.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC4378 N40 53 27.2 W85 28 13.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +TOSB2 N41 44 00.4 W84 59 46.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CENCEN N41 41 39.0 W86 14 53.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +003 N41 07 21.3 W85 09 23.5 symbol=boat_ramp alt=220.506469727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC11EF N40 01 45.3 W86 53 17.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C90 N40 50 08.2 W85 27 14.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC93 N41 43 09.4 W85 58 59.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC12FF N41 33 23.9 W86 21 26.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC44E5 N41 01 03.7 W85 15 07.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CWORK N41 07 23.0 W85 09 24.7 symbol=flag alt=254.633056641 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2193 N40 25 29.0 W86 54 52.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC47A5 N40 25 15.3 W86 54 17.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +TOSB3 N41 43 21.9 W86 15 20.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +004 N41 07 22.6 W85 09 24.3 symbol=flag alt=250.787719727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC17E0 N41 52 01.5 W86 36 12.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C91 N41 05 01.4 W85 08 18.7 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCA80 N40 29 14.3 W86 51 50.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC488D N41 33 43.7 W85 50 18.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB1 N41 40 34.1 W86 15 01.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC28CB N40 50 32.8 W85 25 20.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC1A9C N41 06 36.2 W85 09 20.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +UNITA N41 02 52.2 W85 16 41.6 symbol=flag alt=256.795898438 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2665 N40 45 56.4 W85 35 58.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2F53 N41 43 57.0 W86 04 48.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +005 N41 02 51.4 W85 16 41.6 symbol=flag alt=263.044433594 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCB78 N40 26 17.9 W86 54 02.2 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB2 N41 38 10.3 W86 15 04.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2ADC N40 26 16.4 W86 48 21.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB4 N41 37 27.7 W86 15 08.7 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC333A N41 01 42.7 W85 11 49.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +ABACUS N41 04 20.6 W85 13 50.8 symbol=building alt=243.577880859 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB5 N41 38 53.4 W85 56 55.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCD85 N41 05 03.3 W85 08 11.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC34D4 N41 58 16.8 W86 11 05.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCB8 N40 26 09.5 W87 09 49.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB6 N41 34 46.3 W85 50 01.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2BE8 N40 52 45.9 W85 32 26.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC42A1 N41 05 02.1 W85 03 14.2 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CASH1 N41 04 41.8 W85 08 19.3 symbol=flag alt=245.740844727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA + +!Position: DMM +!R: 34 +!Position: DMS +003 N41 07 21.3 W85 09 23.5 symbol=boat_ramp alt=220.506469727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +004 N41 07 22.6 W85 09 24.3 symbol=flag alt=250.787719727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +005 N41 02 51.4 W85 16 41.6 symbol=flag alt=263.044433594 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +ABACUS N41 04 20.6 W85 13 50.8 symbol=building alt=243.577880859 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CASH1 N41 04 41.8 W85 08 19.3 symbol=flag alt=245.740844727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CENCEN N41 41 39.0 W86 14 53.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CWORK N41 07 23.0 W85 09 24.7 symbol=flag alt=254.633056641 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB1 N41 40 34.1 W86 15 01.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC11EF N40 01 45.3 W86 53 17.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCD85 N41 05 03.3 W85 08 11.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA + +!R: 23 Route 23 +!NB: blah blah blah + +GC11EF N40 01 45.3 W86 53 17.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC12FF N41 33 23.9 W86 21 26.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC1A9C N41 06 36.2 W85 09 20.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA + diff --git a/gpspilot.c b/gpspilot.c new file mode 100644 index 000000000..31ebf8dcc --- /dev/null +++ b/gpspilot.c @@ -0,0 +1,240 @@ +/* + Read and write GPSPilot Tracker files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "pdbfile.h" + +#define MYNAME "GPSPilot" +#define MYTYPE_POINTS 0x706f696e /* poin */ +#define MYTYPE_AIRPORT 0x706f3030 /* po00 */ +#define MYTYPE_CITIES 0x706f3031 /* po01 */ +#define MYTYPE_LNDMRKS 0x706f3032 /* po02 */ +#define MYTYPE_NAVAIDS 0x706f3033 /* po03 */ +#define MYCREATOR 0x47704c69 /* GpLi */ + +struct record { + pdb_32 longitude; /* Big endian, long * 3.6e6 */ + pdb_32 latitude; /* similarly */ + pdb_16 elevation; /* meters */ + pdb_16 magvar; /* magnetic variation in degrees, neg = west */ +}; + +struct runways { + pdb_32 be_longitude; /* Big endian, long * 3.6e6 */ + pdb_32 be_latitude; /* similarly */ + pdb_32 en_longitude; /* Big endian, long * 3.6e6 */ + pdb_32 en_latitude; /* similarly */ +}; + +static pdbfile *file_in, *file_out; +static const char *out_fname; +static char *dbname = NULL; +static int ct; + +static +arglist_t gpspilot_args[] = { + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +static void +rd_init(const char *fname) +{ + file_in = pdb_open(fname, MYNAME); +} + +static void +rd_deinit(void) +{ + pdb_close(file_in); + if ( dbname ) { + xfree(dbname); + dbname = NULL; + } +} + +static void +wr_init(const char *fname) +{ + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; +} + +static void +wr_deinit(void) +{ + pdb_close(file_out); + if ( dbname ) { + xfree(dbname); + dbname = NULL; + } +} + +static void +data_read(void) +{ + struct record *rec; + pdbrec_t *pdb_rec; + + if ((file_in->creator != MYCREATOR)) { + fatal(MYNAME ": Not a gpspilot file.\n"); + } + + switch (file_in->type) + { + case MYTYPE_AIRPORT: + case MYTYPE_POINTS: + case MYTYPE_CITIES: + case MYTYPE_LNDMRKS: + case MYTYPE_NAVAIDS: + break; + default: + fatal(MYNAME ": Not a gpspilot file.\n"); + } + + for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint *wpt_tmp; + char *vdata; + + wpt_tmp = waypt_new(); + + rec = (struct record *) pdb_rec->data; + wpt_tmp->longitude = be_read32(&rec->longitude) / 3.6e6; + wpt_tmp->latitude = be_read32(&rec->latitude) / 3.6e6; + wpt_tmp->altitude = + be_read16(&rec->elevation); + + vdata = (char *) pdb_rec->data + sizeof(*rec); + + /* + * skip runway records if an airport. + */ + if (pdb_rec->category == 0) + { + int numRunways; + numRunways = be_read16(vdata); + vdata += 2; + vdata += (sizeof(struct runways) * numRunways); + } + + /* + * This maping is a bit contrived. + * Name is up to 36. ID is up to 9. + * Since 'ID' maps more clearly to "shortname" (and this + * more likely to be resemble a wayoint name in another + * receiver) we use that for shortname and use 'name' as + * our description. + */ + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + waypt_add(wpt_tmp); + + } +} + + +static void +gpspilot_writewpt(const waypoint *wpt) +{ + struct record *rec; + char *vdata; + + rec = xcalloc(sizeof(*rec)+206,1); + + be_write32(&rec->longitude, si_round(wpt->longitude * 3.6e6)); + be_write32(&rec->latitude, si_round(wpt->latitude * 3.6e6)); + be_write16(&rec->elevation, si_round(wpt->altitude)); + be_write16(&rec->magvar, 0 ); + + vdata = (char *)rec + sizeof(*rec); + if ( wpt->description ) { + strncpy( vdata, wpt->description, 36 ); + vdata[35] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + if ( wpt->shortname ) { + strncpy( vdata, wpt->shortname, 9 ); + vdata[8] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + + if ( wpt->notes ) { + strncpy( vdata, wpt->notes, 161 ); + vdata[160] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + + pdb_write_rec(file_out, 0, 2, ct++, (void *)rec, (char *)vdata - (char *)rec); + + xfree(rec); +} + +static void +data_write(void) +{ + if ( dbname ) { + strncpy(file_out->name, dbname, PDB_DBNAMELEN); + } + else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE_POINTS; + file_out->creator = MYCREATOR; + file_out->version = 0; + + waypt_disp_all(gpspilot_writewpt); +} + + +ff_vecs_t gpspilot_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + gpspilot_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; +#endif diff --git a/gpssim.c b/gpssim.c new file mode 100644 index 000000000..8a0d3e6b4 --- /dev/null +++ b/gpssim.c @@ -0,0 +1,204 @@ +/* + Write points to Franson Technology GpsGate simulator + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +#define MYNAME "gpssim" + +static gbfile *fout; +static char *wayptspd; +static char *splitfiles_opt; +static int splitfiles; +static char *fnamestr; +static int trk_count; +static int doing_tracks; + +static +arglist_t gpssim_args[] = { + { "wayptspd", &wayptspd, "Default speed for waypoints (knots/hr)", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX }, + { "split", &splitfiles_opt, "Split input into separate files", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +/* + * The only thing kind of odd about this format is the "split" + * option. There's some trashing about with the 'splitfiles' toggle + * to ensure that waypoints land in one file and each track and each + * route land in files of their own. + */ + +static void +gpssim_wr_init(const char *fname) +{ + fnamestr = xstrdup(fname); + trk_count = 0; + splitfiles = splitfiles_opt ? atoi(splitfiles_opt) : 0; + + /* If writing to stdout, never split files */ + if (0 == strcmp("-",splitfiles_opt)) { + splitfiles = 0; + } + + if (!splitfiles) { + fout = gbfopen(fname, "wb", MYNAME); + } +} + +static void +gpssim_wr_deinit(void) +{ + if (fout) { + gbfclose(fout); + fout = NULL; + } + + xfree(fnamestr); +} + + +/* + * All these files are written in binary mode, so put CR/NL pairs + * in them explictly in case we're writing from a UNIX-like host. + */ + +static void +gpssim_write_sentence(const char *const s) +{ + gbfprintf(fout, "$%s*%02X\r\n", s, nmea_cksum(s)); +} + +static void +gpssim_write_spd(double knotsperhour) +{ + char obuf[1024]; + + snprintf(obuf, sizeof(obuf), "FRSPD,%.2f", knotsperhour); + gpssim_write_sentence(obuf); +} + +static void +gpssim_write_pt(const waypoint *wpt) +{ + char obuf[1024]; + double lat, lon; + + if WAYPT_HAS(wpt, speed) { + gpssim_write_spd(MPS_TO_KNOTS(wpt->speed)); + } + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + + snprintf(obuf, sizeof(obuf), "FRWPT,%10.5f,%c,%011.5f,%c,%.1f", + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + wpt->altitude == unknown_alt ? 0 : wpt->altitude + ); + + if ( wpt->creation_time ) { + char tbuf[20]; + int hms, ymd; + struct tm *tm; + + tm = gmtime(&wpt->creation_time); + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; + ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; + snprintf(tbuf, sizeof(tbuf), ",%d,%d",ymd, hms); + strcat(obuf, tbuf); + } + + gpssim_write_sentence(obuf); +} + +static void +gpssim_trk_hdr(const route_head *rh) +{ + if (splitfiles) { + char c[1024]; + char *ofname = xstrdup(fnamestr); + + if (fout) { + fatal(MYNAME ": output file already open.\n"); + } + + snprintf(c, sizeof(c), "%s%04d.gpssim", + doing_tracks ? "-track" : "-route", + trk_count++); + ofname = xstrappend(ofname, c); + fout = gbfopen(ofname, "wb", MYNAME); + xfree(ofname); + } + track_recompute(rh, NULL); +} + +static void +gpssim_trk_ftr(const route_head *rh) +{ + if (splitfiles) { + gbfclose(fout); + fout = NULL; + } +} + +static void +gpssim_write(void) +{ + if (waypt_count()) { + if (splitfiles) { + char *ofname = xstrdup(fnamestr); + ofname = xstrappend(ofname, "-waypoints.gpssim"); + fout = gbfopen(ofname, "wb", MYNAME); + xfree(ofname); + } + if (wayptspd && wayptspd[0]) { + gpssim_write_spd(atof(wayptspd)); + } + waypt_disp_all(gpssim_write_pt); + if (splitfiles) { + gbfclose(fout); + fout = NULL; + } + } + + doing_tracks = 1; + track_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); + + trk_count = 0; + doing_tracks = 0; + route_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); +} + + +ff_vecs_t gpssim_vecs = { + ff_type_file, + { ff_cap_write, ff_cap_write, ff_cap_write }, + NULL, + gpssim_wr_init, + NULL, + gpssim_wr_deinit, + NULL, + gpssim_write, + NULL, + gpssim_args, + CET_CHARSET_ASCII, 0 +}; diff --git a/gpsutil.c b/gpsutil.c new file mode 100644 index 000000000..d9f7dcbe3 --- /dev/null +++ b/gpsutil.c @@ -0,0 +1,172 @@ +/* + Access gpsutil files. + + Copyright (C) 2002, 2003, 2004 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "magellan.h" + +static gbfile *file_in, *file_out; +static short_handle mkshort_handle; + +#define MYNAME "GPSUTIL" + +static void +rd_init(const char *fname) +{ + file_in = gbfopen(fname, "rb", MYNAME); +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); +} + +static void +data_read(void) +{ + char *ibuf; + char desc[31]; + double lat,lon; + char latdir, londir; + int ilat, ilon; + long alt; + char alttype; + char icon[3]; + waypoint *wpt_tmp; + + /* + * Make sure that all waypoints in single read have same + * timestamp. + */ + time_t now = current_time(); + icon[0] = 0; + + while ((ibuf = gbfgetstr(file_in))) { + int n, len; + char *sn; + /* A sharp in column zero or an blank line is a comment */ + ibuf = lrtrim(ibuf); + len = strlen(ibuf); + if ((len == 0) || (*ibuf == '#')) continue; + + if (len > 71) { + int offs = len - 71; + sn = xstrndup(ibuf, offs + 8); + ibuf += (offs + 9); + } + else { + sn = xstrndup(ibuf, 8); + ibuf += 9; + } + + n = sscanf(ibuf, "%lf%c %lf%c %ld%c %30[^,] %2s", + &lat, &latdir, &lon, &londir, + &alt, &alttype, desc, icon); + /* Require at least first threee fields, otherwise ignore */ + if (n < 2) { + xfree(sn); + continue; + } + rtrim(sn); + rtrim(desc); + rtrim(icon); + wpt_tmp = waypt_new(); + wpt_tmp->altitude = alt; + wpt_tmp->shortname = sn; + wpt_tmp->description = xstrdup(desc); + wpt_tmp->creation_time = now; + + if (latdir == 'S') lat = -lat; + if (londir == 'W') lon = -lon; + + lat /= 100.0; + lon /= 100.0; + ilon = (int)(lon); + wpt_tmp->longitude = ilon + (lon - ilon)*(100.0/60.0); + ilat = (int)(lat); + wpt_tmp->latitude = ilat + (lat - ilat) * (100.0/60.0); + wpt_tmp->icon_descr = mag_find_descr_from_token(icon); + waypt_add(wpt_tmp); + } +} + +static void +gpsutil_disp(const waypoint *wpt) +{ + double lon,lat; + const char *icon_token; + char *tdesc = xstrdup(wpt->description); + + icon_token = mag_find_token_from_descr(wpt->icon_descr); + + lon = degrees2ddmm(wpt->longitude); + lat = degrees2ddmm(wpt->latitude); + + gbfprintf(file_out, "%-8.8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n", + global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, wpt) : + wpt->shortname, + fabs(lat), + lat < 0.0 ? 'S' : 'N', + fabs(lon), + lon < 0.0 ? 'W' : 'E', + ((wpt->altitude == unknown_alt) || + (wpt->altitude < 0.0)) ? 0 : wpt->altitude, + 'm', + wpt->description ? tdesc : "", + icon_token); + + xfree(tdesc); +} + +static void +data_write(void) +{ + waypt_disp_all(gpsutil_disp); +} + + +ff_vecs_t gpsutil_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/gpx.c b/gpx.c new file mode 100644 index 000000000..20121117b --- /dev/null +++ b/gpx.c @@ -0,0 +1,1899 @@ +/* + Access GPX data files. + + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "xmlgeneric.h" +#include "cet_util.h" +#include "garmin_fs.h" +#if HAVE_LIBEXPAT + #include + static XML_Parser psr; +#endif + +static xml_tag *cur_tag; +static vmem_t cdatastr; +static char *opt_logpoint = NULL; +static int logpoint_ct = 0; + +static const char *gpx_version; +static char *gpx_wversion; +static int gpx_wversion_num; +static const char *gpx_creator; +static char *xsi_schema_loc = NULL; + +static char *gpx_email = NULL; +static char *gpx_author = NULL; +static vmem_t current_tag; + +static waypoint *wpt_tmp; +static int cache_descr_is_html; +static gbfile *fd; +static const char *input_fname; +static gbfile *ofd; +static short_handle mkshort_handle; +static const char *link_url; +static char *link_text; + +static const char *input_string = NULL; +static int input_string_len = 0; + +static time_t file_time; + +static char *snlen = NULL; +static char *suppresswhite = NULL; +static char *urlbase = NULL; +static route_head *trk_head; +static route_head *rte_head; +/* used for bounds calculation on output */ +static bounds all_bounds; + +static format_specific_data **fs_ptr; + +#define MYNAME "GPX" +#define MY_CBUF_SZ 4096 +#define DEFAULT_XSI_SCHEMA_LOC "http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd" +#define DEFAULT_XSI_SCHEMA_LOC_11 "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" +#define DEFAULT_XSI_SCHEMA_LOC_FMT "\"http://www.topografix.com/GPX/%c/%c http://www.topografix.com/GPX/%c/%c/gpx.xsd\"" +#ifndef CREATOR_NAME_URL +# define CREATOR_NAME_URL "GPSBabel - http://www.gpsbabel.org" +#endif + + +/* + * Format used for floating point formats. Put in one place to make it + * easier to tweak when comparing output with other GPX programs that + * have more or less digits of output... + */ +/* #define FLT_FMT "%.9lf" */ /* ExpertGPS */ +#define FLT_FMT "%0.9lf" +#define FLT_FMT_T "%0.9lf" +#define FLT_FMT_R "%0.9lf" + +typedef enum { + tt_unknown = 0, + tt_gpx, + + tt_name, /* Optional file-level info */ + tt_desc, + tt_author, + tt_email, + tt_url, + tt_urlname, + tt_keywords, + + tt_wpt, + tt_wpt_cmt, + tt_wpt_desc, + tt_wpt_name, + tt_wpt_sym, + tt_wpt_url, + tt_wpt_ele, + tt_wpt_time, + tt_wpt_type, + tt_wpt_urlname, + tt_wpt_link, /* New in GPX 1.1 */ + tt_wpt_link_text, /* New in GPX 1.1 */ + tt_pdop, /* PDOPS are common for all three */ + tt_hdop, /* PDOPS are common for all three */ + tt_vdop, /* PDOPS are common for all three */ + tt_fix, + tt_sat, + tt_cache, + tt_cache_name, + tt_cache_container, + tt_cache_type, + tt_cache_difficulty, + tt_cache_terrain, + tt_cache_hint, + tt_cache_desc_short, + tt_cache_desc_long, + tt_cache_log_wpt, + tt_cache_log_type, + tt_cache_log_date, + tt_cache_placer, + + tt_wpt_extensions, + + tt_garmin_wpt_extensions, /* don't change this order */ + tt_garmin_wpt_proximity, + tt_garmin_wpt_temperature, + tt_garmin_wpt_depth, + tt_garmin_wpt_display_mode, + tt_garmin_wpt_categories, + tt_garmin_wpt_category, + tt_garmin_wpt_addr, + tt_garmin_wpt_city, + tt_garmin_wpt_state, + tt_garmin_wpt_country, + tt_garmin_wpt_postal_code, + tt_garmin_wpt_phone_nr, /* don't change this order */ + + tt_rte, + tt_rte_name, + tt_rte_desc, + tt_rte_cmt, + tt_rte_number, + tt_rte_rtept, + tt_rte_rtept_ele, + tt_rte_rtept_name, + tt_rte_rtept_desc, + tt_rte_rtept_sym, + tt_rte_rtept_time, + tt_rte_rtept_cmt, + tt_rte_rtept_url, + tt_rte_rtept_urlname, + tt_trk, + tt_trk_desc, + tt_trk_name, + tt_trk_trkseg, + tt_trk_number, + tt_trk_trkseg_trkpt, + tt_trk_trkseg_trkpt_cmt, + tt_trk_trkseg_trkpt_name, + tt_trk_trkseg_trkpt_sym, + tt_trk_trkseg_trkpt_url, + tt_trk_trkseg_trkpt_urlname, + tt_trk_trkseg_trkpt_desc, + tt_trk_trkseg_trkpt_ele, + tt_trk_trkseg_trkpt_time, + tt_trk_trkseg_trkpt_course, + tt_trk_trkseg_trkpt_speed, +} tag_type; + +typedef struct { + queue queue; + char *tagdata; +} gpx_global_entry; + +/* + * The file-level information. + */ +static +struct gpx_global { + gpx_global_entry name; + gpx_global_entry desc; + gpx_global_entry author; + gpx_global_entry email; + gpx_global_entry url; + gpx_global_entry urlname; + gpx_global_entry keywords; + /* time and bounds aren't here; they're recomputed. */ +} *gpx_global ; + +static void +gpx_add_to_global(gpx_global_entry *ge, char *cdata) +{ + queue *elem, *tmp; + gpx_global_entry * gep; + + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + if (0 == strcmp(cdata, gep->tagdata)) + return; + } + + gep = xcalloc(sizeof(*gep), 1); + QUEUE_INIT(&gep->queue); + gep->tagdata = xstrdup(cdata); + ENQUEUE_TAIL(&ge->queue, &gep->queue); +} + +static void +gpx_rm_from_global(gpx_global_entry *ge) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gpx_global_entry *g = (gpx_global_entry *) dequeue(elem); + xfree(g->tagdata); + xfree(g); + } +} + +static void +gpx_write_gdata(gpx_global_entry *ge, char *tag) +{ + queue *elem, *tmp; + gpx_global_entry * gep; + + if (!gpx_global || QUEUE_EMPTY(&ge->queue)) { + return; + } + + gbfprintf(ofd, "<%s>", tag); + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + gbfprintf(ofd, "%s", gep->tagdata); + /* Some tags we just output once. */ + if ((0 == strcmp(tag, "url")) || + (0 == strcmp(tag, "email"))) { + break; + } + gbfprintf(ofd, " "); + } + gbfprintf(ofd, "\n", tag); +} + + +typedef struct tag_mapping { + tag_type tag_type; /* enum from above for this tag */ + int tag_passthrough; /* true if we don't generate this */ + const char *tag_name; /* xpath-ish tag name */ + unsigned long crc; /* Crc32 of tag_name */ +} tag_mapping; + +/* + * xpath(ish) mappings between full tag paths and internal identifers. + * These appear in the order they appear in the GPX specification. + * If it's not a tag we explictly handle, it doesn't go here. + */ + +tag_mapping tag_path_map[] = { + { tt_gpx, 0, "/gpx", 0UL }, + { tt_name, 0, "/gpx/name", 0UL }, + { tt_desc, 0, "/gpx/desc", 0UL }, + { tt_author, 0, "/gpx/author", 0UL }, + { tt_email, 0, "/gpx/email", 0UL }, + { tt_url, 0, "/gpx/url", 0UL }, + { tt_urlname, 0, "/gpx/urlname", 0UL }, + { tt_keywords, 0, "/gpx/keywords", 0UL }, + + { tt_wpt, 0, "/gpx/wpt", 0UL }, + { tt_wpt_ele, 0, "/gpx/wpt/ele", 0UL }, + { tt_wpt_time, 0, "/gpx/wpt/time", 0UL }, + { tt_wpt_name, 0, "/gpx/wpt/name", 0UL }, + { tt_wpt_cmt, 0, "/gpx/wpt/cmt", 0UL }, + { tt_wpt_desc, 0, "/gpx/wpt/desc", 0UL }, + { tt_wpt_url, 0, "/gpx/wpt/url", 0UL }, + { tt_wpt_urlname, 0, "/gpx/wpt/urlname", 0UL }, + { tt_wpt_link, 0, "/gpx/wpt/link", 0UL }, /* GPX 1.1 */ + { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ + { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, + { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, + + /* Double up the GPX 1.0 and GPX 1.1 styles */ +#define GEOTAG(type,name) \ + {type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:" name, 0UL }, \ + {type, 1, "/gpx/wpt/extensions/cache/" name, 0UL }, \ + {type, 1, "/gpx/wpt/geocache/" name, 0UL } /* opencaching.de */ + +#define GARMIN_WPT_EXT "/gpx/wpt/extensions/gpxx:WaypointExtension" + +// GEOTAG( tt_cache, "cache"), + { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, + + GEOTAG( tt_cache_name, "name"), + GEOTAG( tt_cache_container, "container"), + GEOTAG( tt_cache_type, "type"), + GEOTAG( tt_cache_difficulty, "difficulty"), + GEOTAG( tt_cache_terrain, "terrain"), + GEOTAG( tt_cache_hint, "encoded_hints"), + GEOTAG( tt_cache_hint, "hints"), /* opencaching.de */ + GEOTAG( tt_cache_desc_short, "short_description"), + GEOTAG( tt_cache_desc_long, "long_description"), + GEOTAG( tt_cache_placer, "owner"), + { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, + { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, + { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, + { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, + { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, + { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, + + { tt_wpt_extensions, 0, "/gpx/wpt/extensions", 0UL }, + + { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT, 0UL }, + { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity", 0UL }, + { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature", 0UL }, + { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth", 0UL }, + { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode", 0UL }, + { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories", 0UL }, + { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", 0UL }, + { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", 0UL }, + { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", 0UL }, + { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", 0UL }, + { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", 0UL }, + { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", 0UL }, + { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber", 0UL }, + + { tt_rte, 0, "/gpx/rte", 0UL }, + { tt_rte_name, 0, "/gpx/rte/name", 0UL }, + { tt_rte_desc, 0, "/gpx/rte/desc", 0UL }, + { tt_rte_number, 0, "/gpx/rte/number", 0UL }, + { tt_rte_rtept, 0, "/gpx/rte/rtept", 0UL }, + { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele", 0UL }, + { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time", 0UL }, + { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name", 0UL }, + { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt", 0UL }, + { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc", 0UL }, + { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url", 0UL }, + { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname", 0UL }, + { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym", 0UL }, + + { tt_trk, 0, "/gpx/trk", 0UL }, + { tt_trk_name, 0, "/gpx/trk/name", 0UL }, + { tt_trk_desc, 0, "/gpx/trk/desc", 0UL }, + { tt_trk_trkseg, 0, "/gpx/trk/trkseg", 0UL }, + { tt_trk_number, 0, "/gpx/trk/number", 0UL }, + { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt", 0UL }, + { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele", 0UL }, + { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time", 0UL }, + { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name", 0UL }, + { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt", 0UL }, + { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc", 0UL }, + { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url", 0UL }, + { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname", 0UL }, + { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym", 0UL }, + { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course", 0UL }, + { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed", 0UL }, + + /* Common to tracks, routes, and waypts */ + { tt_fix, 0, "/gpx/wpt/fix", 0UL }, + { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix", 0UL }, + { tt_fix, 0, "/gpx/rte/rtept/fix", 0UL }, + { tt_sat, 0, "/gpx/wpt/sat", 0UL }, + { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat", 0UL }, + { tt_sat, 0, "/gpx/rte/rtept/sat", 0UL }, + { tt_pdop, 0, "/gpx/wpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/rte/rtept/pdop", 0UL }, + { tt_hdop, 0, "/gpx/wpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + { tt_vdop, 0, "/gpx/wpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + {0, 0, NULL, 0UL} +}; + +static tag_type +get_tag(const char *t, int *passthrough) +{ + tag_mapping *tm; + unsigned long tcrc = get_crc32_s(t); + + for (tm = tag_path_map; tm->tag_type != 0; tm++) { + if ((tcrc == tm->crc) && (0 == strcmp(tm->tag_name, t))) { + *passthrough = tm->tag_passthrough; + return tm->tag_type; + } + } + *passthrough = 1; + return tt_unknown; +} + +static void +prescan_tags(void) +{ + tag_mapping *tm; + for (tm = tag_path_map; tm->tag_type != 0; tm++) { + tm->crc = get_crc32_s(tm->tag_name); + } +} + +static void +tag_gpx(const char **attrv) +{ + const char **avp; + for (avp = &attrv[0]; *avp; avp += 2) { + if (strcmp(avp[0], "version") == 0) { + gpx_version = avp[1]; + } + else if (strcmp(avp[0], "src") == 0) { + gpx_creator = avp[1]; + } + /* + * Our handling of schemaLocation really is weird. + * If we see we have a "normal" GPX 1.1 header, on read, + * flip our default on write to use that and don't append + * it to the rest... + */ + else if (strcmp(avp[0], "xsi:schemaLocation") == 0) { + if (0 == strcmp(avp[1], DEFAULT_XSI_SCHEMA_LOC_11)) { + if (0 == strcmp(xsi_schema_loc, DEFAULT_XSI_SCHEMA_LOC)) + xfree(xsi_schema_loc); + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC_11); + continue; + } + if (0 == strstr(xsi_schema_loc, avp[1])) { + xsi_schema_loc = xstrappend(xsi_schema_loc, " "); + xsi_schema_loc = xstrappend(xsi_schema_loc, avp[1]); + } + } + } +} + +static void +tag_wpt(const char **attrv) +{ + const char **avp = &attrv[0]; + + wpt_tmp = waypt_new(); + + cur_tag = NULL; + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->latitude); + } + else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->longitude); + } + avp+=2; + } + fs_ptr = &wpt_tmp->fs; +} + +static void +tag_cache_desc(const char ** attrv) +{ + const char **avp; + + cache_descr_is_html = 0; + for (avp = &attrv[0]; *avp; avp+=2) { + if (strcmp(avp[0], "html") == 0) { + if (strcmp(avp[1], "True") == 0) { + cache_descr_is_html = 1; + } + } + } +} + +static void +tag_gs_cache(const char **attrv) +{ + const char **avp; + + for (avp = &attrv[0]; *avp; avp+=2) { + if (strcmp(avp[0], "id") == 0) { + wpt_tmp->gc_data.id = atoi(avp[1]); + } else if (strcmp(avp[0], "available") == 0) { + if (case_ignore_strcmp(avp[1], "True") == 0) { + wpt_tmp->gc_data.is_available = status_true; + } + else if (case_ignore_strcmp(avp[1], "False") == 0) { + wpt_tmp->gc_data.is_available = status_false; + } + } else if (strcmp(avp[0], "archived") == 0) { + if (case_ignore_strcmp(avp[1], "True") == 0) { + wpt_tmp->gc_data.is_archived = status_true; + } + else if (case_ignore_strcmp(avp[1], "False") == 0) { + wpt_tmp->gc_data.is_archived = status_false; + } + } + } +} + +static void +start_something_else(const char *el, const char **attrv) +{ + const char **avp = attrv; + char **avcp = NULL; + int attr_count = 0; + xml_tag *new_tag; + fs_xml *fs_gpx; + + if ( !fs_ptr ) { + return; + } + + new_tag = (xml_tag *)xcalloc(sizeof(xml_tag),1); + new_tag->tagname = xstrdup(el); + + /* count attributes */ + while (*avp) { + attr_count++; + avp++; + } + + /* copy attributes */ + avp = attrv; + new_tag->attributes = (char **)xcalloc(sizeof(char *),attr_count+1); + avcp = new_tag->attributes; + while (*avp) { + *avcp = xstrdup(*avp); + avcp++; + avp++; + } + *avcp = NULL; + + if ( cur_tag ) { + if ( cur_tag->child ) { + cur_tag = cur_tag->child; + while ( cur_tag->sibling ) { + cur_tag = cur_tag->sibling; + } + cur_tag->sibling = new_tag; + new_tag->parent = cur_tag->parent; + } + else { + cur_tag->child = new_tag; + new_tag->parent = cur_tag; + } + } + else { + fs_gpx = (fs_xml *)fs_chain_find( *fs_ptr, FS_GPX ); + + if ( fs_gpx && fs_gpx->tag ) { + cur_tag = fs_gpx->tag; + while ( cur_tag->sibling ) { + cur_tag = cur_tag->sibling; + } + cur_tag->sibling = new_tag; + new_tag->parent = NULL; + } + else { + fs_gpx = fs_xml_alloc(FS_GPX); + fs_gpx->tag = new_tag; + fs_chain_add( fs_ptr, (format_specific_data *)fs_gpx ); + new_tag->parent = NULL; + } + } + cur_tag = new_tag; +} + +static void +end_something_else() +{ + if ( cur_tag ) { + cur_tag = cur_tag->parent; + } +} + +static void +tag_log_wpt(const char **attrv) +{ + waypoint * lwp_tmp; + const char **avp = &attrv[0]; + + /* create a new waypoint */ + lwp_tmp = waypt_new(); + + /* extract the lat/lon attributes */ + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &lwp_tmp->latitude); + } + else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &lwp_tmp->longitude); + } + avp+=2; + } + /* Make a new shortname. Since this is a groundspeak extension, + we assume that GCBLAH is the current shortname format and that + wpt_tmp refers to the currently parsed waypoint. Unfortunatley, + we need to keep track of log_wpt counts so we don't collide with + dupe shortnames. + */ + + if ((wpt_tmp->shortname) && (strlen(wpt_tmp->shortname) > 2)) { + /* copy of the shortname */ + lwp_tmp->shortname = xcalloc(7, 1); + sprintf(lwp_tmp->shortname, "%-4.4s%02d", + &wpt_tmp->shortname[2], logpoint_ct++); + + waypt_add(lwp_tmp); + } +} + +static void +gpx_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) +{ + char *e; + char *ep; + int passthrough; + const char *el = xml_convert_to_char_string(xml_el); + const char **attr = xml_convert_attrs_to_char_string(xml_attr); + + vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); + e = current_tag.mem; + ep = e + strlen(e); + *ep++ = '/'; + strcpy(ep, el); + + + /* + * FIXME: Find out why a cdatastr[0] doesn't adequately reset the + * cdata handler. + */ + memset(cdatastr.mem, 0, cdatastr.size); + + switch (get_tag(current_tag.mem, &passthrough)) { + case tt_gpx: + tag_gpx(attr); + break; + case tt_wpt: + tag_wpt(attr); + break; + case tt_wpt_link: + if (0 == strcmp(attr[0], "href")) { + link_url = attr[1]; + } + break; + case tt_wpt_link_text: + link_text = cdatastr.mem; + break; + case tt_rte: + rte_head = route_head_alloc(); + route_add_head(rte_head); + fs_ptr = &rte_head->fs; + break; + case tt_rte_rtept: + tag_wpt(attr); + break; + case tt_trk: + trk_head = route_head_alloc(); + track_add_head(trk_head); + fs_ptr = &trk_head->fs; + break; + case tt_trk_trkseg_trkpt: + tag_wpt(attr); + break; + case tt_unknown: + start_something_else(el, attr); + return; + case tt_cache: + tag_gs_cache(attr); + break; + case tt_cache_log_wpt: + if (opt_logpoint) + tag_log_wpt(attr); + break; + case tt_cache_desc_long: + case tt_cache_desc_short: + tag_cache_desc(attr); + break; + case tt_cache_placer: + if (*attr && (0 == strcmp(attr[0], "id"))) { + wpt_tmp->gc_data.placer_id = atoi(attr[1]); + } + default: + break; + } + if (passthrough) { + start_something_else(el, attr); + } + xml_free_converted_string(el); + xml_free_converted_attrs(attr); +} + +struct +gs_type_mapping{ + geocache_type type; + const char *name; +} gs_type_map[] = { + { gt_traditional, "Traditional Cache" }, + { gt_traditional, "Traditional" }, /* opencaching.de */ + { gt_multi, "Multi-cache" }, + { gt_multi, "Multi" }, /* opencaching.de */ + { gt_virtual, "Virtual Cache" }, + { gt_virtual, "Virtual" }, /* opencaching.de */ + { gt_event, "Event Cache" }, + { gt_event, "Event" }, /* opencaching.de */ + { gt_webcam, "Webcam Cache" }, + { gt_webcam, "Webcam" }, /* opencaching.de */ + { gt_suprise, "Unknown Cache" }, + { gt_earth, "Earthcache" }, + { gt_earth, "Earth" }, /* opencaching.de */ + { gt_cito, "Cache In Trash Out Event" }, + { gt_letterbox, "Letterbox Hybrid" }, + { gt_locationless, "Locationless (Reverse) Cache" }, + { gt_ape, "Project APE Cache" }, + { gt_mega, "Mega-Event Cache" }, + + { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK */ +}; + +struct +gs_container_mapping{ + geocache_container type; + const char *name; +} gs_container_map[] = { + { gc_other, "Unknown" }, + { gc_other, "Other" }, /* Synonym on read. */ + { gc_micro, "Micro" }, + { gc_regular, "Regular" }, + { gc_large, "Large" }, + { gc_small, "Small" }, + { gc_virtual, "Virtual" } +}; + +geocache_type +gs_mktype(const char *t) +{ + int i; + int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, gs_type_map[i].name)) { + return gs_type_map[i].type; + } + } + return gt_unknown; +} + +const char * +gs_get_cachetype(geocache_type t) +{ + int i; + int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); + + for (i = 0; i < sz; i++) { + if (t == gs_type_map[i].type) { + return gs_type_map[i].name; + } + } + return "Unknown"; +} + +geocache_container +gs_mkcont(const char *t) +{ + int i; + int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, gs_container_map[i].name)) { + return gs_container_map[i].type; + } + } + return gc_unknown; +} + +const char * +gs_get_container(geocache_container t) +{ + int i; + int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); + + for (i = 0; i < sz; i++) { + if (t == gs_container_map[i].type) { + return gs_container_map[i].name; + } + } + return "Unknown"; +} + +time_t +xml_parse_time( const char *cdatastr, int *microsecs ) +{ + int off_hr = 0; + int off_min = 0; + int off_sign = 1; + char *offsetstr = NULL; + char *pointstr = NULL; + struct tm tm; + time_t rv = 0; + char *timestr = xstrdup( cdatastr ); + + memset(&tm, 0, sizeof(tm)); + + offsetstr = strchr( timestr, 'Z' ); + if ( offsetstr ) { + /* zulu time; offsets stay at defaults */ + *offsetstr = '\0'; + } else { + offsetstr = strchr( timestr, '+' ); + if ( offsetstr ) { + /* positive offset; parse it */ + *offsetstr = '\0'; + sscanf( offsetstr+1, "%d:%d", &off_hr, &off_min ); + } else { + offsetstr = strchr( timestr, 'T' ); + if ( offsetstr ) { + offsetstr = strchr( offsetstr, '-' ); + if ( offsetstr ) { + /* negative offset; parse it */ + *offsetstr = '\0'; + sscanf( offsetstr+1, "%d:%d", + &off_hr, &off_min ); + off_sign = -1; + } + } + } + } + + pointstr = strchr( timestr, '.' ); + if ( pointstr ) { + if (microsecs) { + double fsec; + sscanf(pointstr, "%le", &fsec); + /* Round to avoid FP jitter */ + *microsecs = .5 + (fsec * 1000000.0) ; + } + *pointstr = '\0'; + } + + sscanf(timestr, "%d-%d-%dT%d:%d:%d", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday, + &tm.tm_hour, + &tm.tm_min, + &tm.tm_sec); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; + + rv = mkgmtime(&tm) - off_sign*off_hr*3600 - off_sign*off_min*60; + + xfree(timestr); + + return rv; +} + +static void +gpx_end(void *data, const XML_Char *xml_el) +{ + const char *el = xml_convert_to_char_string(xml_el); + char *s = strrchr(current_tag.mem, '/'); + float x; + char *cdatastrp = cdatastr.mem; + int passthrough; + static time_t gc_log_date; + tag_type tag; + + if (strcmp(s + 1, el)) { + fprintf(stderr, "Mismatched tag %s\n", el); + } + + tag = get_tag(current_tag.mem, &passthrough); + switch(tag) { + /* + * First, the tags that are file-global. + */ + case tt_name: + gpx_add_to_global(&gpx_global->name, cdatastrp); + break; + case tt_desc: + gpx_add_to_global(&gpx_global->desc, cdatastrp); + break; + case tt_author: + gpx_add_to_global(&gpx_global->author, cdatastrp); + break; + case tt_email: + gpx_add_to_global(&gpx_global->email, cdatastrp); + if (gpx_email == NULL) { + gpx_email = xstrdup(cdatastrp); + } + break; + case tt_url: + gpx_add_to_global(&gpx_global->url, cdatastrp); + break; + case tt_urlname: + gpx_add_to_global(&gpx_global->urlname, cdatastrp); + break; + case tt_keywords: + gpx_add_to_global(&gpx_global->keywords, cdatastrp); + break; + + /* + * Waypoint-specific tags. + */ + case tt_wpt: + waypt_add(wpt_tmp); + logpoint_ct = 0; + cur_tag = NULL; + wpt_tmp = NULL; + break; + case tt_cache_name: + if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); + wpt_tmp->notes = xstrdup(cdatastrp); + break; + case tt_cache_container: + wpt_tmp->gc_data.container = gs_mkcont(cdatastrp); + break; + case tt_cache_type: + wpt_tmp->gc_data.type = gs_mktype(cdatastrp); + break; + case tt_cache_difficulty: + sscanf(cdatastrp, "%f", &x); + wpt_tmp->gc_data.diff = x * 10; + break; + case tt_cache_hint: + rtrim(cdatastrp); + if (cdatastrp[0]) { + wpt_tmp->gc_data.hint = xstrdup(cdatastrp); + } + break; + case tt_cache_desc_long: + rtrim(cdatastrp); + if (cdatastrp[0]) { + wpt_tmp->gc_data.desc_long.is_html = cache_descr_is_html; + wpt_tmp->gc_data.desc_long.utfstring = xstrdup(cdatastrp); + } + break; + case tt_cache_desc_short: + rtrim(cdatastrp); + if (cdatastrp[0]) { + wpt_tmp->gc_data.desc_short.is_html = cache_descr_is_html; + wpt_tmp->gc_data.desc_short.utfstring = xstrdup(cdatastrp); + } + break; + case tt_cache_terrain: + sscanf(cdatastrp, "%f", &x); + wpt_tmp->gc_data.terr = x * 10; + break; + case tt_cache_placer: + wpt_tmp->gc_data.placer = xstrdup(cdatastrp); + break; + case tt_cache_log_date: + gc_log_date = xml_parse_time( cdatastrp, NULL ); + break; + /* + * "Found it" logs follow the date according to the schema, + * if this is the first "found it" for this waypt, just use the + * last date we saw in this log. + */ + case tt_cache_log_type: + if ((0 == strcmp(cdatastrp, "Found it")) && + (0 == wpt_tmp->gc_data.last_found)) { + wpt_tmp->gc_data.last_found = gc_log_date; + } + gc_log_date = 0; + break; + + /* + * Garmin-waypoint-specific tags. + */ + case tt_garmin_wpt_proximity: + case tt_garmin_wpt_temperature: + case tt_garmin_wpt_depth: + case tt_garmin_wpt_display_mode: + case tt_garmin_wpt_category: + case tt_garmin_wpt_addr: + case tt_garmin_wpt_city: + case tt_garmin_wpt_state: + case tt_garmin_wpt_country: + case tt_garmin_wpt_postal_code: + case tt_garmin_wpt_phone_nr: + garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag, cdatastrp, wpt_tmp); + break; + + /* + * Route-specific tags. + */ + case tt_rte_name: + rte_head->rte_name = xstrdup(cdatastrp); + break; + case tt_rte: + break; + case tt_rte_rtept: + route_add_wpt(rte_head, wpt_tmp); + wpt_tmp = NULL; + break; + case tt_rte_desc: + rte_head->rte_desc = xstrdup(cdatastrp); + break; + case tt_rte_number: + rte_head->rte_num = atoi(cdatastrp); + break; + /* + * Track-specific tags. + */ + case tt_trk_name: + trk_head->rte_name = xstrdup(cdatastrp); + break; + case tt_trk: + break; + case tt_trk_trkseg_trkpt: + track_add_wpt(trk_head, wpt_tmp); + wpt_tmp = NULL; + break; + case tt_trk_desc: + trk_head->rte_desc = xstrdup(cdatastrp); + break; + case tt_trk_number: + trk_head->rte_num = atoi(cdatastrp); + break; + case tt_trk_trkseg_trkpt_course: + WAYPT_SET(wpt_tmp, course, atof(cdatastrp)); + break; + case tt_trk_trkseg_trkpt_speed: + WAYPT_SET(wpt_tmp, speed, atof(cdatastrp)); + break; + + /* + * Items that are actually in multiple categories. + */ + case tt_wpt_ele: + case tt_rte_rtept_ele: + case tt_trk_trkseg_trkpt_ele: + sscanf(cdatastrp, "%lf", &wpt_tmp->altitude); + break; + case tt_wpt_name: + case tt_rte_rtept_name: + case tt_trk_trkseg_trkpt_name: + wpt_tmp->shortname = xstrdup(cdatastrp); + break; + case tt_wpt_sym: + case tt_rte_rtept_sym: + case tt_trk_trkseg_trkpt_sym: + wpt_tmp->icon_descr = xstrdup(cdatastrp); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + break; + case tt_wpt_time: + case tt_trk_trkseg_trkpt_time: + case tt_rte_rtept_time: + wpt_tmp->creation_time = xml_parse_time( cdatastrp, &wpt_tmp->microseconds ); + break; + case tt_wpt_cmt: + case tt_rte_rtept_cmt: + case tt_trk_trkseg_trkpt_cmt: + wpt_tmp->description = xstrdup(cdatastrp); + break; + case tt_wpt_desc: + case tt_trk_trkseg_trkpt_desc: + case tt_rte_rtept_desc: + if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); + wpt_tmp->notes = xstrdup(cdatastrp); + break; + case tt_pdop: + wpt_tmp->pdop = atof(cdatastrp); + break; + case tt_hdop: + wpt_tmp->hdop = atof(cdatastrp); + break; + case tt_vdop: + wpt_tmp->vdop = atof(cdatastrp); + break; + case tt_sat: + wpt_tmp->sat = atof(cdatastrp); + break; + case tt_fix: + wpt_tmp->fix = atoi(cdatastrp)-1; + if ( wpt_tmp->fix < fix_2d) { + if (!case_ignore_strcmp(cdatastrp, "none")) + wpt_tmp->fix = fix_none; + else if (!case_ignore_strcmp(cdatastrp, "dgps")) + wpt_tmp->fix = fix_dgps; + else if (!case_ignore_strcmp(cdatastrp, "pps")) + wpt_tmp->fix = fix_pps; + else + wpt_tmp->fix = fix_unknown; + } + break; + case tt_wpt_url: + case tt_trk_trkseg_trkpt_url: + case tt_rte_rtept_url: + wpt_tmp->url = xstrdup(cdatastrp); + break; + case tt_wpt_urlname: + case tt_trk_trkseg_trkpt_urlname: + case tt_rte_rtept_urlname: + wpt_tmp->url_link_text = xstrdup(cdatastrp); + break; + case tt_wpt_link: +//TODO: implement GPX 1.1 case tt_trk_trkseg_trkpt_link: +//TODO: implement GPX 1.1 case tt_rte_rtept_link: + { + char *lt = link_text; + if (lt) { + lt = xstrdup(lrtrim(link_text)); + } + + waypt_add_url(wpt_tmp, xstrdup(link_url), lt); + link_text = NULL; + } + break; + case tt_unknown: + end_something_else(); + *s = 0; + return; + default: + break; + } + + if (passthrough) { + end_something_else(); + } + + *s = 0; + xml_free_converted_string(el); +} + +#if ! HAVE_LIBEXPAT +static void +gpx_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); +} + +static void +gpx_rd_deinit(void) +{ +} + +#else /* NO_EXPAT */ + +static void +gpx_cdata(void *dta, const XML_Char *xml_el, int len) +{ + char *estr; + int *cdatalen; + char **cdata; + xml_tag *tmp_tag; + size_t slen = strlen(cdatastr.mem); + const char *s = xml_convert_to_char_string_n(xml_el, &len); + + vmem_realloc(&cdatastr, 1 + len + slen); + estr = ((char *) cdatastr.mem) + slen; + memcpy(estr, s, len); + estr[len] = 0; + + if (!cur_tag) + return; + + if ( cur_tag->child ) { + tmp_tag = cur_tag->child; + while ( tmp_tag->sibling ) { + tmp_tag = tmp_tag->sibling; + } + cdata = &(tmp_tag->parentcdata); + cdatalen = &(tmp_tag->parentcdatalen); + } + else { + cdata = &(cur_tag->cdata); + cdatalen = &(cur_tag->cdatalen); + } + estr = *cdata; + *cdata = xcalloc( *cdatalen + len + 1, 1); + if ( estr ) { + memcpy( *cdata, estr, *cdatalen); + xfree( estr ); + } + estr = *cdata + *cdatalen; + memcpy( estr, s, len ); + *(estr+len) = '\0'; + *cdatalen += len; + + xml_free_converted_string(s); +} + +static void +gpx_rd_init(const char *fname) +{ + if ( fname[0] ) { + fd = gbfopen(fname, "r", MYNAME); + input_fname = fname; + } + else { + fd = NULL; + input_string = fname+1; + input_string_len = strlen(input_string); + input_fname = NULL; + } + + + file_time = 0; + current_tag = vmem_alloc(1, 0); + *((char *)current_tag.mem) = '\0'; + + prescan_tags(); + + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ": Cannot create XML Parser\n"); + } + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + + cdatastr = vmem_alloc(1, 0); + *((char *)cdatastr.mem) = '\0'; + + if (!xsi_schema_loc) { + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC); + } + if (!xsi_schema_loc) { + fatal("gpx: Unable to allocate %ld bytes of memory.\n", + (unsigned long) strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); + } + + if (NULL == gpx_global) { + gpx_global = xcalloc(sizeof(*gpx_global), 1); + QUEUE_INIT(&gpx_global->name.queue); + QUEUE_INIT(&gpx_global->desc.queue); + QUEUE_INIT(&gpx_global->author.queue); + QUEUE_INIT(&gpx_global->email.queue); + QUEUE_INIT(&gpx_global->url.queue); + QUEUE_INIT(&gpx_global->urlname.queue); + QUEUE_INIT(&gpx_global->keywords.queue); + } + + XML_SetElementHandler(psr, gpx_start, gpx_end); + XML_SetCharacterDataHandler(psr, gpx_cdata); + fs_ptr = NULL; +} + +static +void +gpx_rd_deinit(void) +{ + vmem_free(¤t_tag); + vmem_free(&cdatastr); + /* + * Don't free schema_loc. It really is important that we preserve + * this across reads or else merges/copies of files with different + * schemas won't retain the headers. + * + * moved to gpx_exit + + if ( xsi_schema_loc ) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + */ + + if ( gpx_email ) { + xfree(gpx_email); + gpx_email = NULL; + } + if ( gpx_author ) { + xfree(gpx_author); + gpx_author = NULL; + } + if (fd) { + gbfclose(fd); + } + XML_ParserFree(psr); + psr = NULL; + wpt_tmp = NULL; + cur_tag = NULL; + input_fname = NULL; +} +#endif + +static void +gpx_wr_init(const char *fname) +{ + mkshort_handle = mkshort_new_handle(); + + ofd = gbfopen(fname, "w", MYNAME); +} + +static void +gpx_wr_deinit(void) +{ + gbfclose(ofd); + mkshort_del_handle(&mkshort_handle); +} + +void +gpx_read(void) +{ +#if HAVE_LIBEXPAT + int len; + int done = 0; + char *buf = xmalloc(MY_CBUF_SZ); + int result = 0; + int extra; + + while (!done) { + if ( fd ) { + /* + * The majority of this block (in fact, all but the + * call to XML_Parse) are a disgusting hack to + * correct defective GPX files that Geocaching.com + * issues as pocket queries. They contain escape + * characters as entities (�-) which makes + * them not validate which croaks expat and torments + * users. + * + * Look for '&' in the last maxentlength chars. If + * we find it, strip it, then read byte-at-a-time + * until we find a non-entity. + */ + char *badchar; + char *semi; + int maxentlength = 8; + len = gbfread(buf, 1, MY_CBUF_SZ - maxentlength, fd); + done = gbfeof(fd) || !len; + buf[len] = '\0'; + if (len < maxentlength) { + maxentlength = len; + } + badchar = buf+len-maxentlength; + badchar = strchr( badchar, '&' ); + extra = maxentlength - 1; /* for terminator */ + while ( badchar && len < MY_CBUF_SZ-1) { + semi = strchr( badchar, ';'); + while ( extra && !semi ) { + len += gbfread( buf+len, 1, 1, fd); + buf[len]='\0'; + extra--; + if ( buf[len-1] == ';') + semi= buf+len-1; + } + badchar = strchr( badchar+1, '&' ); + } + { + char *hex="0123456789abcdef"; + badchar = strstr( buf, "&#x" ); + while ( badchar ) { + int val = 0; + char *hexit = badchar+3; + semi = strchr( badchar, ';' ); + if ( semi ) { + while (*hexit && *hexit != ';') { + char hc = isalpha(*hexit) ? tolower (*hexit) : *hexit; + val *= 16; + val += strchr( hex, hc)-hex; + hexit++; + } + + if ( val < 32 ) { + warning( MYNAME ": Ignoring illegal character %s;\n\tConsider emailing %s at <%s>\n\tabout illegal characters in their GPX files.\n", badchar, gpx_author?gpx_author:"(unknown author)", gpx_email?gpx_email:"(unknown email address)" ); + memmove( badchar, semi+1, strlen(semi+1)+1 ); + len -= (semi-badchar)+1; + badchar--; + } + } + badchar = strstr( badchar+1, "&#x" ); + } + } + result = XML_Parse(psr, buf, len, done); + } + else if (input_string) { + done = 0; + result = XML_Parse(psr, input_string, + input_string_len, done ); + done = 1; + } + else { + done = 1; + result = -1; + } + if (!result) { + fatal(MYNAME ": XML parse error at line %d of '%s' : %s\n", + (int) XML_GetCurrentLineNumber(psr), + input_fname ? input_fname : "unknown file", + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + xfree(buf); +#endif /* HAVE_LIBEXPAT */ +} + +static void +fprint_tag_and_attrs( char *prefix, char *suffix, xml_tag *tag ) +{ + char **pa; + gbfprintf( ofd, "%s%s", prefix, tag->tagname ); + pa = tag->attributes; + if ( pa ) { + while ( *pa ) { + gbfprintf( ofd, " %s=\"%s\"", pa[0], pa[1] ); + pa += 2; + } + } + gbfprintf( ofd, "%s", suffix ); +} + +static void +fprint_xml_chain( xml_tag *tag, const waypoint *wpt ) +{ + char *tmp_ent; + while ( tag ) { + if ( !tag->cdata && !tag->child ) { + fprint_tag_and_attrs( "<", " />", tag ); + } + else { + fprint_tag_and_attrs( "<", ">", tag ); + + if ( tag->cdata ) { + tmp_ent = xml_entitize( tag->cdata ); + gbfprintf( ofd, "%s", tmp_ent ); + xfree(tmp_ent); + } + if ( tag->child ) { + fprint_xml_chain(tag->child, wpt); + } + if ( wpt && wpt->gc_data.exported && + strcmp(tag->tagname, "groundspeak:cache" ) == 0 ) { + xml_write_time( ofd, wpt->gc_data.exported, 0, + "groundspeak:exported" ); + } + gbfprintf( ofd, "\n", tag->tagname); + } + if ( tag->parentcdata ) { + tmp_ent = xml_entitize(tag->parentcdata); + gbfprintf(ofd, "%s", tmp_ent ); + xfree(tmp_ent); + } + tag = tag->sibling; + } +} + +void free_gpx_extras( xml_tag *tag ) +{ + xml_tag *next = NULL; + char **ap; + + while ( tag ) { + if (tag->cdata) { + xfree(tag->cdata); + } + if (tag->child) { + free_gpx_extras(tag->child); + } + if (tag->parentcdata) { + xfree(tag->parentcdata); + } + if (tag->tagname) { + xfree(tag->tagname); + } + if (tag->attributes) { + ap = tag->attributes; + + while (*ap) + xfree(*ap++); + + xfree(tag->attributes); + } + + next = tag->sibling; + xfree(tag); + tag = next; + } +} + +/* + * Handle the grossness of GPX 1.0 vs. 1.1 handling of linky links. + */ +static void +write_gpx_url(const waypoint *waypointp) +{ + char *tmp_ent; + + if (waypointp->url == NULL) { + return; + } + + if (gpx_wversion_num > 10) { + url_link *tail; + for (tail = (url_link *)&waypointp->url_next; tail; tail = tail->url_next) { + tmp_ent = xml_entitize(tail->url); + gbfprintf(ofd, " \n", + urlbase ? urlbase : "", tmp_ent); + write_optional_xml_entity(ofd, " ", "text", + tail->url_link_text); + gbfprintf(ofd, " \n"); + xfree(tmp_ent); + } + } else { + tmp_ent = xml_entitize(waypointp->url); + gbfprintf(ofd, " %s%s\n", + urlbase ? urlbase : "", tmp_ent); + write_optional_xml_entity(ofd, " ", "urlname", + waypointp->url_link_text); + xfree(tmp_ent); + } +} + +/* + * Write optional accuracy information for a given (way|track|route)point + * to the output stream. Done in one place since it's common for all three. + * Order counts. + */ +static void +gpx_write_common_acc(const waypoint *waypointp, const char *indent) +{ + char *fix = NULL; + + switch (waypointp->fix) { + case fix_2d: + fix = "2d"; + break; + case fix_3d: + fix = "3d"; + break; + case fix_dgps: + fix = "dgps"; + break; + case fix_pps: + fix = "pps"; + break; + case fix_none: + fix = "none"; + break; + /* GPX spec says omit if we don't know. */ + case fix_unknown: + default: + break; + } + if (fix) { + gbfprintf(ofd, "%s%s\n", indent, fix); + } + if (waypointp->sat > 0) { + gbfprintf(ofd, "%s%d\n", indent, waypointp->sat); + } + if (waypointp->hdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->hdop); + } + if (waypointp->vdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->vdop); + } + if (waypointp->pdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->pdop); + } +} + +static void +gpx_write_common_position(const waypoint *waypointp, const char *indent) +{ + if (waypointp->altitude != unknown_alt) { + gbfprintf(ofd, "%s%f\n", + indent, waypointp->altitude); + } + if (waypointp->creation_time) { + xml_write_time(ofd, waypointp->creation_time, waypointp->microseconds, "time"); + } +} + +static void +gpx_write_common_description(const waypoint *waypointp, const char *indent, + const char *oname) +{ + write_optional_xml_entity(ofd, indent, "name", oname); + write_optional_xml_entity(ofd, indent, "cmt", waypointp->description); + if (waypointp->notes && waypointp->notes[0]) + write_xml_entity(ofd, indent, "desc", waypointp->notes); + else + write_optional_xml_entity(ofd, indent, "desc", waypointp->description); + write_gpx_url(waypointp); + write_optional_xml_entity(ofd, indent , "sym", waypointp->icon_descr); +} + +static void +gpx_waypt_pr(const waypoint *waypointp) +{ + const char *oname; + char *odesc; + fs_xml *fs_gpx; + garmin_fs_t *gmsd; /* gARmIN sPECIAL dATA */ + + /* + * Desparation time, try very hard to get a good shortname + */ + odesc = waypointp->notes; + if (!odesc) { + odesc = waypointp->description; + } + if (!odesc) { + odesc = waypointp->shortname; + } + + oname = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, odesc) : + waypointp->shortname; + + gbfprintf(ofd, "\n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + gpx_write_common_description(waypointp, " ", oname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); + gmsd = GMSD_FIND(waypointp); + if ( fs_gpx ) { + if (! gmsd) fprint_xml_chain( fs_gpx->tag, waypointp ); + } + if (gmsd && (gpx_wversion_num > 10)) { + /* MapSource doesn't accepts extensions from 1.0 */ + garmin_fs_xml_fprint(ofd, waypointp); + } + gbfprintf(ofd, "\n"); +} + +static void +gpx_track_hdr(const route_head *rte) +{ + fs_xml *fs_gpx; + + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "name", rte->rte_name); + write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); + if (rte->rte_num) { + gbfprintf(ofd, "%d\n", rte->rte_num); + } + gbfprintf(ofd, "\n"); + + fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); + if ( fs_gpx ) { + fprint_xml_chain( fs_gpx->tag, NULL ); + } +} + +static void +gpx_track_disp(const waypoint *waypointp) +{ + fs_xml *fs_gpx; + + gbfprintf(ofd, "\n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + + /* These were accidentally removed from 1.1 */ + if (gpx_wversion_num == 10) { + if WAYPT_HAS(waypointp, course) { + gbfprintf(ofd, " %f\n", + waypointp->course); + } + if WAYPT_HAS(waypointp, speed) { + gbfprintf(ofd, " %f\n", + waypointp->speed); + } + } + + /* GPX doesn't require a name on output, so if we made one up + * on input, we might as well say nothing. + */ + gpx_write_common_description(waypointp, " ", + waypointp->wpt_flags.shortname_is_synthetic ? + NULL : waypointp->shortname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); + if ( fs_gpx ) { + fprint_xml_chain( fs_gpx->tag, waypointp ); + } + + gbfprintf(ofd, "\n"); +} + +static void +gpx_track_tlr(const route_head *rte) +{ + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); +} + +static +void gpx_track_pr() +{ + track_disp_all(gpx_track_hdr, gpx_track_tlr, gpx_track_disp); +} + +static void +gpx_route_hdr(const route_head *rte) +{ + fs_xml *fs_gpx; + + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "name", rte->rte_name); + write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); + if (rte->rte_num) { + gbfprintf(ofd, " %d\n", rte->rte_num); + } + + fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); + if ( fs_gpx ) { + fprint_xml_chain( fs_gpx->tag, NULL ); + } +} + +static void +gpx_route_disp(const waypoint *waypointp) +{ + fs_xml *fs_gpx; + + gbfprintf(ofd, " \n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + gpx_write_common_description(waypointp, " ", waypointp->shortname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); + if ( fs_gpx ) { + fprint_xml_chain( fs_gpx->tag, waypointp ); + } + + gbfprintf(ofd, " \n"); +} + +static void +gpx_route_tlr(const route_head *rte) +{ + gbfprintf(ofd, "\n"); +} + +static +void gpx_route_pr() +{ + /* output routes */ + route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp); +} + +static void +gpx_waypt_bound_calc(const waypoint *waypointp) +{ + waypt_add_to_bounds(&all_bounds, waypointp); +} + +static void +gpx_write_bounds(void) +{ + waypt_init_bounds(&all_bounds); + + waypt_disp_all(gpx_waypt_bound_calc); + route_disp_all(NULL, NULL, gpx_waypt_bound_calc); + track_disp_all(NULL, NULL, gpx_waypt_bound_calc); + + if (waypt_bounds_valid(&all_bounds)) { + gbfprintf(ofd, "\n", + all_bounds.min_lat, all_bounds.min_lon, + all_bounds.max_lat, all_bounds.max_lon); + } +} + +static void +gpx_write(void) +{ + time_t now = 0; + int short_length; + + gpx_wversion_num = strtod(gpx_wversion, NULL) * 10; + + if (gpx_wversion_num <= 0) { + fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion); + } + + now = current_time(); + + short_length = atoi(snlen); + + if (suppresswhite) { + setshort_whitespace_ok(mkshort_handle, 0); + } + + setshort_length(mkshort_handle, short_length); + + gbfprintf(ofd, "\n", global_opts.charset_name); + gbfprintf(ofd, "\n", xsi_schema_loc); + } else { + gbfprintf(ofd, + "xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n", + gpx_wversion[0], gpx_wversion[2], + gpx_wversion[0], gpx_wversion[2]); + } + + if (gpx_wversion_num > 10) { + gbfprintf(ofd, "\n"); + } + gpx_write_gdata(&gpx_global->name, "name"); + gpx_write_gdata(&gpx_global->desc, "desc"); + /* In GPX 1.1, author changed from a string to a PersonType. + * since it's optional, we just drop it instead of rewriting it. + */ + if (gpx_wversion_num < 11) { + gpx_write_gdata(&gpx_global->author, "author"); + } + gpx_write_gdata(&gpx_global->email, "email"); + gpx_write_gdata(&gpx_global->url, "url"); + gpx_write_gdata(&gpx_global->urlname, "urlname"); + xml_write_time( ofd, now, 0, "time" ); + gpx_write_gdata(&gpx_global->keywords, "keywords"); + + gpx_write_bounds(); + + if (gpx_wversion_num > 10) { + gbfprintf(ofd, "\n"); + } + + waypt_disp_all(gpx_waypt_pr); + gpx_route_pr(); + gpx_track_pr(); + + gbfprintf(ofd, "\n"); +} + + +static void +gpx_free_gpx_global(void) +{ + gpx_rm_from_global(&gpx_global->name); + gpx_rm_from_global(&gpx_global->desc); + gpx_rm_from_global(&gpx_global->author); + gpx_rm_from_global(&gpx_global->email); + gpx_rm_from_global(&gpx_global->url); + gpx_rm_from_global(&gpx_global->urlname); + gpx_rm_from_global(&gpx_global->keywords); + xfree(gpx_global); +} + +static void +gpx_exit(void) +{ + if ( xsi_schema_loc ) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + + if (gpx_global) { + gpx_free_gpx_global(); + gpx_global = NULL; + } +} + +static +arglist_t gpx_args[] = { + { "snlen", &snlen, "Length of generated shortnames", + "32", ARGTYPE_INT, "1", NULL }, + { "suppresswhite", &suppresswhite, + "No whitespace in generated shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + { "logpoint", &opt_logpoint, + "Create waypoints from geocache log entries", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + { "urlbase", &urlbase, "Base URL for link tag in output", + NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + { "gpxver", &gpx_wversion, "Target GPX version for output", + "1.0", ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +ff_vecs_t gpx_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + gpx_rd_init, + gpx_wr_init, + gpx_rd_deinit, + gpx_wr_deinit, + gpx_read, + gpx_write, + gpx_exit, + gpx_args, + CET_CHARSET_UTF8, 0 /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */ +}; diff --git a/gpxval b/gpxval new file mode 100644 index 000000000..ffa5d87b4 --- /dev/null +++ b/gpxval @@ -0,0 +1,37 @@ +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/robertl/xerces-c1_7_0-linux7.2/lib +export PATH=$PATH:/home/robertl/xerces-c1_7_0-linux7.2/bin + +validate() +{ + SAX2Count -p -f -v=always $* +} + +gpxval() +{ + echo "Validating $*" + ./gpsbabel $* -o gpx -F /tmp/$$.gpx + validate /tmp/$$.gpx + ./gpsbabel $* -o gpx,gpxver=1.0 -F /tmp/$$.gpx + validate /tmp/$$.gpx + ./gpsbabel $* -o gpx,gpxver=1.1 -F /tmp/$$.gpx + validate /tmp/$$.gpx +} + + +# gpxval "-i gpx -f reference/holux.gpx" +gpxval -i mapsend -f reference/chicago.trk + +SAX2Count reference/holux.gpx + +# Routes + +# gpxval -i gpx -f reference/route/blah.gpx +gpxval -i magellan -f reference/route/magellan.rte +gpxval -i psitrex -f reference/route/psitrtes.txt +# gpxval -i gpx -f reference/route/route.gpx +gpxval -i mapsend -f reference/route/route.mapsend +gpxval -i mapsource -f reference/route/route.mps + +# Tracks + +gpxval -i mapsource -f reference/route/route.mps diff --git a/grtcirc.c b/grtcirc.c new file mode 100644 index 000000000..44ecf1adf --- /dev/null +++ b/grtcirc.c @@ -0,0 +1,348 @@ +/* + Great Circle utility functions + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include +#include +#include "defs.h" +#include "grtcirc.h" + +static const double EARTH_RAD = 6378137.0; + +static void crossproduct( double x1, double y1, double z1, + double x2, double y2, double z2, + double *xa, double *ya, double *za ) { + *xa = y1*z2-y2*z1; + *ya = z1*x2-z2*x1; + *za = x1*y2-y1*x2; +} + +static double dotproduct( double x1, double y1, double z1, + double x2, double y2, double z2 ) { + return (x1*x2+y1*y2+z1*z2); +} + +/* + * Note: this conversion to miles uses the WGS84 value for the radius of + * the earth at the equator. + * (radius in meters)*(100cm/m) -> (radius in cm) + * (radius in cm) / (2.54 cm/in) -> (radius in in) + * (radius in in) / (12 in/ft) -> (radius in ft) + * (radius in ft) / (5280 ft/mi) -> (radius in mi) + * If the compiler is half-decent, it'll do all the math for us at compile + * time, so why not leave the expression human-readable? + */ + +double radtomiles( double rads ) { + const double radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0; + return (rads*radmiles); +} + +double radtometers( double rads ) { + return ( rads * EARTH_RAD ); +} + +double gcdist( double lat1, double lon1, double lat2, double lon2 ) +{ + double res; + double sdlat, sdlon; + + errno = 0; + + sdlat = sin((lat1 - lat2) / 2.0); + sdlon = sin((lon1 - lon2) / 2.0); + + res = sqrt(sdlat * sdlat + cos(lat1) * cos(lat2) * sdlon * sdlon); + + if (res > 1.0) { + res = 1.0; + } else if (res < -1.0) { + res = -1.0; + } + + res = asin(res); + + if ( +#if defined isnan + /* This is a C99-ism. */ + (isnan(res)) || +#endif + (errno == EDOM)) { /* this should never happen: */ + errno = 0; /* Math argument out of domain of + function, */ + return 0; /* or value returned is not a number */ + } + + return 2.0 * res; +} + +/* This value is the heading you'd leave point 1 at to arrive at point 2. + * Inputs and outputs are in radians. + */ +double heading( double lat1, double lon1, double lat2, double lon2 ) { + double v1, v2; + v1 = sin(lon1 - lon2) * cos(lat2); + v2 = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon1 - lon2); + /* rounding error protection */ + if (fabs(v1) < 1e-15) v1 = 0.0; + if (fabs(v2) < 1e-15) v2 = 0.0; + return atan2(v1, v2); +} + +/* As above, but outputs is in degrees from 0 - 359. Inputs are still radians. */ +double heading_true_degrees( double lat1, double lon1, double lat2, double lon2 ) +{ + double h = 360.0 - DEG(heading(lat1, lon1, lat2, lon2)); + if (h >= 360.0) h -= 360.0; + + return h; +} + + +double linedist(double lat1, double lon1, + double lat2, double lon2, + double lat3, double lon3 ) { + + static double _lat1 = -9999; + static double _lat2 = -9999; + static double _lon1 = -9999; + static double _lon2 = -9999; + + static double x1,y1,z1; + static double x2,y2,z2; + static double xa,ya,za,la; + + double x3,y3,z3; + double xp,yp,zp,lp; + + double xa1,ya1,za1; + double xa2,ya2,za2; + + double d1, d2; + double c1, c2; + + double dot; + + int newpoints; + + /* degrees to radians */ + lat1 = RAD(lat1); lon1 = RAD(lon1); + lat2 = RAD(lat2); lon2 = RAD(lon2); + lat3 = RAD(lat3); lon3 = RAD(lon3); + + newpoints = 1; + if ( lat1 == _lat1 && lat2 == _lat2 && lon1 == _lon1 && lon2 == _lon2) { + newpoints = 0; + } + else { + _lat1 = lat1; + _lat2 = lat2; + _lon1 = lon1; + _lon2 = lon2; + } + + /* polar to ECEF rectangular */ + if ( newpoints ) { + x1 = cos(lon1)*cos(lat1); y1 = sin(lat1); z1 = sin(lon1)*cos(lat1); + x2 = cos(lon2)*cos(lat2); y2 = sin(lat2); z2 = sin(lon2)*cos(lat2); + } + x3 = cos(lon3)*cos(lat3); y3 = sin(lat3); z3 = sin(lon3)*cos(lat3); + + if ( newpoints ) { + /* 'a' is the axis; the line that passes through the center of the earth + * and is perpendicular to the great circle through point 1 and point 2 + * It is computed by taking the cross product of the '1' and '2' vectors.*/ + crossproduct( x1, y1, z1, x2, y2, z2, &xa, &ya, &za ); + la = sqrt(xa*xa+ya*ya+za*za); + + if ( la ) { + xa /= la; + ya /= la; + za /= la; + } + } + if ( la ) { + + /* dot is the component of the length of '3' that is along the axis. + * What's left is a non-normalized vector that lies in the plane of + * 1 and 2. */ + + dot = dotproduct(x3,y3,z3,xa,ya,za); + + xp = x3-dot*xa; + yp = y3-dot*ya; + zp = z3-dot*za; + + lp = sqrt(xp*xp+yp*yp+zp*zp); + + if ( lp ) { + + /* After this, 'p' is normalized */ + xp /= lp; + yp /= lp; + zp /= lp; + + crossproduct(x1,y1,z1,xp,yp,zp,&xa1,&ya1,&za1); + d1 = dotproduct( xa1, ya1, za1, xa, ya, za ); + + crossproduct(xp,yp,zp,x2,y2,z2,&xa2,&ya2,&za2); + d2 = dotproduct( xa2, ya2, za2, xa, ya, za ); + + if ( d1 >= 0 && d2 >= 0 ) { + /* rather than call gcdist and all its sines and cosines and + * worse, we can get the angle directly. It's the arctangent + * of the length of the component of vector 3 along the axis + * divided by the length of the component of vector 3 in the + * plane. We already have both of those numbers. + * + * atan2 would be overkill because lp and fabs(dot) are both + * known to be positive. */ + + return atan( fabs(dot)/lp ); + } + + /* otherwise, get the distance from the closest endpoint */ + c1 = dotproduct( x1,y1,z1,xp,yp,zp ); + c2 = dotproduct( x2,y2,z2,xp,yp,zp ); + d1 = fabs(d1); + d2 = fabs(d2); + + /* This is a hack. d$n$ is proportional to the sine of the angle + * between point $n$ and point p. That preserves orderedness up + * to an angle of 90 degrees. c$n$ is proportional to the cosine + * of the same angle; if the angle is over 90 degrees, c$n$ is + * negative. In that case, we flop the sine across the y=1 axis + * so that the resulting value increases as the angle increases. + * + * This only works because all of the points are on a unit sphere. */ + + if ( c1 < 0 ) { + d1 = 2 - d1; + } + if ( c2 < 0 ) { + d2 = 2 - d2; + } + + if ( fabs(d1) < fabs(d2)) { + return gcdist(lat1,lon1,lat3,lon3); + } + else { + return gcdist(lat2,lon2,lat3,lon3); + } + } + else { + /* lp is 0 when 3 is 90 degrees from the great circle */ + return M_PI/2; + } + } + else { + /* la is 0 when 1 and 2 are either the same point or 180 degrees apart */ + dot = dotproduct(x1,y1,z1,x2,y2,z2); + if ( dot >= 0 ) { + return gcdist(lat1,lon1,lat3,lon3); + } + else { + return 0; + } + } + return 0; +} + +/* + * Compute the position of a point partially along the geodesic from + * lat1,lon1 to lat2,lon2 + * + * Ref: http://mathworld.wolfram.com/RotationFormula.html + */ + +void linepart(double lat1, double lon1, + double lat2, double lon2, + double frac, + double *reslat, double *reslon ) { + + double x1,y1,z1; + double x2,y2,z2; + double xa,ya,za,la; + double xr, yr, zr; + double xx, yx, zx; + + double theta = 0; + double phi = 0; + double cosphi = 0; + double sinphi = 0; + + /* result must be in degrees */ + *reslat = lat1; + *reslon = lon1; + + /* degrees to radians */ + lat1 = RAD(lat1); lon1 = RAD(lon1); + lat2 = RAD(lat2); lon2 = RAD(lon2); + + /* polar to ECEF rectangular */ + x1 = cos(lon1)*cos(lat1); y1 = sin(lat1); z1 = sin(lon1)*cos(lat1); + x2 = cos(lon2)*cos(lat2); y2 = sin(lat2); z2 = sin(lon2)*cos(lat2); + + /* 'a' is the axis; the line that passes through the center of the earth + * and is perpendicular to the great circle through point 1 and point 2 + * It is computed by taking the cross product of the '1' and '2' vectors.*/ + crossproduct( x1, y1, z1, x2, y2, z2, &xa, &ya, &za ); + la = sqrt(xa*xa+ya*ya+za*za); + + if ( la ) { + xa /= la; + ya /= la; + za /= la; + } + /* if la is zero, the points are either equal or directly opposite + * each other. Either way, there's no single geodesic, so we punt. */ + if ( la ) { + crossproduct( x1, y1, z1, xa, ya, za, &xx, &yx, &zx ); + + + theta = atan2( dotproduct(xx,yx,zx,x2,y2,z2), + dotproduct(x1,y1,z1,x2,y2,z2)); + + phi = frac * theta; + cosphi = cos(phi); + sinphi = sin(phi); + + + /* The second term of the formula from the mathworld reference is always + * zero, because r (lat1,lon1) is always perpendicular to n (a here) */ + xr = x1*cosphi + xx * sinphi; + yr = y1*cosphi + yx * sinphi; + zr = z1*cosphi + zx * sinphi; + + if ( xr > 1 ) xr = 1; + if ( xr < -1 ) xr = -1; + if ( yr > 1 ) yr = 1; + if ( yr < -1 ) yr = -1; + if ( zr > 1 ) zr = 1; + if ( zr < -1 ) zr = -1; + + *reslat = DEG(asin(yr)); + if( xr == 0 && zr == 0 ) { + *reslon = 0; + } + else { + *reslon = DEG(atan2( zr, xr )); + } + } +} diff --git a/grtcirc.h b/grtcirc.h new file mode 100644 index 000000000..c47e77dd4 --- /dev/null +++ b/grtcirc.h @@ -0,0 +1,47 @@ +/* + Great Circle utility functions + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifndef GRTCIRC_H +#define GRTCIRC_H + +double gcdist( double lat1, double lon1, double lat2, double lon2 ); +double heading( double lat1, double lon1, double lat2, double lon2 ); +double heading_true_degrees( double lat1, double lon1, double lat2, double lon2 ); + +double linedist(double lat1, double lon1, + double lat2, double lon2, + double lat3, double lon3 ); + +double radtometers( double rads ); +double radtomiles( double rads ); + +void linepart(double lat1, double lon1, + double lat2, double lon2, + double frac, + double *reslat, double *reslon ); + +/* Degrees to radians */ +#define DEG(x) ((x)*180.0/M_PI) + +/* Radians to degrees */ +#define RAD(x) ((x)*M_PI/180.0) + +#endif diff --git a/gtm.c b/gtm.c new file mode 100644 index 000000000..a1f7a2a5e --- /dev/null +++ b/gtm.c @@ -0,0 +1,689 @@ +/* + Support for GPS TrackMaker data file. + + Copyright (C) 2005 Gustavo Niemeyer . + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include "defs.h" +#include "jeeps/gpsmath.h" + +static gbfile *file_in, *file_out; +static int indatum; +static int wp_count; +static int ws_count; +static int tr_count; +static int ts_count; +static int rt_count; +static int im_count; +static const route_head *rte_active; +static int start_new; + +#define MYNAME "GTM" +#define EPOCH89DIFF 631065600 +/* was 631076400 but that seems to include a three-hour bias */ +#define WAYPOINTSTYLES \ + "\xf5\xff\xff\xff\x0f\x00Times New Roman\x00\x00\x00\x00\x00\x90\x01"\ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\ + "\xf5\xff\xff\xff\x0f\x00Times New Roman\x01\x00\x00\x00\x00\x90\x01"\ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\ + "\xf5\xff\xff\xff\x0f\x00Times New Roman\x02\x00\x00\x00\x00\x90\x01"\ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\ + "\xf5\xff\xff\xff\x0f\x00Times New Roman\x03\x00\x00\x00\x00\x90\x01"\ + "\x00\x00\x00\x00\x00\x00\x8b\xff\xff\xff\xff\x00\x00\x00\x00\x00\x01" + +#define unknown_alt_gtm -10000000 + +/* Read functions, according to specification. */ + +#define fread_discard(a,b) gbfseek(a, (b), SEEK_CUR) +#define fread_byte(a) (unsigned char) gbfgetc(a) + +#if 0 +/* not used */ +static short int +fread_bool(gbfile *fd) +{ + char buf[2]; + gbfread(buf, 2, 1, fd); + return le_read16(buf) ? 1 : 0; +} +#endif + +#define fread_integer(a) gbfgetint16(a) +#define fread_long(a) gbfgetint32(a) +#define fread_single(a) gbfgetflt(a) +#define fread_double(a) gbfgetdbl(a) + +static char * +fread_string(gbfile *fd) +{ + char *val; + int len = fread_integer(fd); + + if (len == 0) return NULL; + + val = xmalloc(len+1); + gbfread(val, 1, len, fd); + while (len != 0 && val[len-1] == ' ') + len--; + val[len] = 0; + return val; +} + +static void +fread_string_discard(gbfile *fd) +{ + char *temp = fread_string(fd); + + if (temp != NULL) { + xfree(temp); + } +} + +static char * +fread_fixedstring(gbfile *fd, int len) +{ + char *val = xmalloc(len+1); + + gbfread(val, 1, len, fd); + while (len != 0 && val[len-1] == ' ') + len--; + val[len] = 0; + return val; +} + +/* Write functions, according to specification. */ + +static void +fwrite_null(gbfile *fd, int len) +{ + char buf[1024]; + + memset(buf, 0, len); + gbfwrite(buf, 1, len, fd); +} + +#define fwrite_byte(a,b) gbfputc((signed char)(b), a) +#define fwrite_bool(a,b) gbfputuint16((b) ? 0xffff : 0, a) +#define fwrite_integer(a,b) gbfputint16((b), a) +#define fwrite_long(a,b) gbfputint32((b), a) +#define fwrite_single(a,b) gbfputflt((b), a) +#define fwrite_double(a,b) gbfputdbl((b), a) + +static void +fwrite_string(gbfile *fd, const char *str) +{ + if (str && str[0]) { + int len = strlen(str); + fwrite_integer(fd, len); + gbfwrite(str, 1, len, fd); + } + else { + fwrite_integer(fd, 0); + } +} + +void +fwrite_fixedstring(gbfile *fd, const char *str, int fieldlen) +{ + int len = str ? strlen(str) : 0; + + if (len > fieldlen) + len = fieldlen; + if (str) + gbfwrite(str, 1, len, fd); + for (; len != fieldlen; len++) + gbfputc(' ', fd); +} + +/* Auxiliar functions */ + +void +set_datum(int n) +{ + indatum = -1; + if (n < 1) {} + else if (n < 8) { indatum = 0; } /* Adindan */ + else if (n < 9) { indatum = 1; } /* Afgooye */ + else if (n < 10) { indatum = 2; } /* Ain el Abd */ + else if (n < 14) {} + else if (n < 23) { indatum = 6; } /* ARC 1950 */ + else if (n < 26) { indatum = 7; } /* ARC 1960 */ + else if (n < 27) { indatum = 8; } /* Ascension Island 58 */ + else if (n < 32) {} + else if (n < 33) { indatum = 13; } /* Australian Geo 84 */ + else if (n < 34) {} + else if (n < 35) { indatum = 15; } /* Bellevue IGN */ + else if (n < 36) { indatum = 16; } /* Bermuda 1957 */ + else if (n < 38) {} + else if (n < 39) { indatum = 17; } /* Bukit Rimpah */ + else if (n < 40) { indatum = 18; } /* Camp Area Astro */ + else if (n < 41) { indatum = 19; } /* Campo Inchauspe */ + else if (n < 42) { indatum = 22; } /* Canton Islan 1966 */ + else if (n < 43) { indatum = 23; } /* Cape */ + else if (n < 44) { indatum = 24; } /* Cape Canaveral */ + else if (n < 45) { indatum = 26; } /* Carthe */ + else if (n < 46) { indatum = 28; } /* Chatham */ + else if (n < 47) { indatum = 29; } /* Chua Astro */ + else if (n < 48) { indatum = 30; } /* Corrego Alegre*/ + else if (n < 50) {} + else if (n < 51) { indatum = 33; } /* Djakarta (Batavia) */ + else if (n < 52) { indatum = 34; } /* DOS 1968 */ + else if (n < 53) { indatum = 35; } /* Easter Island 1967 */ + else if (n < 54) {} + else if (n < 69) { indatum = 38; } /* European 1950 Mean */ + else if (n < 70) { indatum = 39; } /* European 1979 Mean */ + else if (n < 71) {} + else if (n < 72) { indatum = 41; } /* Gandajika */ + else if (n < 73) { indatum = 42; } /* Geodetic Datum 49 */ + else if (n < 74) {} + else if (n < 75) { indatum = 45; } /* Guam 1963 */ + else if (n < 76) { indatum = 46; } /* Gunung Segara */ + else if (n < 77) {} + else if (n < 78) { indatum = 49; } /* Hearth North */ + else if (n < 79) {} + else if (n < 80) { indatum = 50; } /* Hjorsey 1955 */ + else if (n < 81) { indatum = 51; } /* Hong Kong 1963 */ + else if (n < 82) { indatum = 52; } /* Hu-Tzu-Shan */ + else if (n < 89) { indatum = 53; } /* Indian */ + else if (n < 90) {} + else if (n < 91) { indatum = 55; } /* Ireland 1965 */ + else if (n < 92) {} + else if (n < 93) { indatum = 56; } /* ISTS 073 69 */ + else if (n < 94) { indatum = 57; } /* Johnston Island 61 */ + else if (n < 95) { indatum = 58; } /* Kandawala */ + else if (n < 96) { indatum = 59; } /* Kerguelen Island */ + else if (n < 97) { indatum = 60; } /* Kertau 48 */ + else if (n < 99) {} + else if (n < 100) { indatum = 61; } /* L.C. 5 Astro */ + else if (n < 101) {} + else if (n < 102) { indatum = 63; } /* Liberia 1964 */ + else if (n < 104) { indatum = 64; } /* Luzon */ + else if (n < 105) {} + else if (n < 106) { indatum = 65; } /* Mahe 1971 */ + else if (n < 107) {} + else if (n < 108) { indatum = 69; } /* Merchich */ + else if (n < 109) { indatum = 71; } /* Midway Astro 61 */ + else if (n < 111) { indatum = 73; } /* Minna */ + else if (n < 112) {} + else if (n < 115) { indatum = 75; } /* Nahrwan */ + else if (n < 116) { indatum = 76; } /* Naparima BWI */ + else if (n < 116) {} + else if (n < 119) { indatum = 3; } /* Alaska NAD27 */ + else if (n < 121) { indatum = 14; } /* Bahamas NAD27 */ + else if (n < 126) { indatum = 20; } /* Canada Mean NAD27 */ + else if (n < 127) { indatum = 21; } /* Canal Zone NAD27 */ + else if (n < 128) { indatum = 31; } /* Cuba NAD27 */ + else if (n < 129) { indatum = 44; } /* Greenland NAD27 */ + else if (n < 131) {} + else if (n < 132) { indatum = 20; } /* Canada Mean NAD27 */ + else if (n < 135) {} + else if (n < 136) { indatum = 70; } /* Mexico NAD27 */ + else if (n < 144) {} + else if (n < 145) { indatum = 80; } /* Old Egyptian */ + else if (n < 146) { indatum = 81; } /* Old Hawaiian */ + else if (n < 147) { indatum = 82; } /* Old Hawaiian Kauai */ + else if (n < 148) { indatum = 83; } /* Old Hawaiian Maui */ + else if (n < 149) { indatum = 81; } /* Old Hawaiian Mean */ + else if (n < 150) { indatum = 84; } /* Old Hawaiian Oahu */ + else if (n < 151) { indatum = 85; } /* Oman */ + else if (n < 156) { indatum = 86; } /* OSG Britain */ + else if (n < 157) { indatum = 87; } /* Pico de Las Nieves */ + else if (n < 158) { indatum = 88; } /* Pitcairn Astro 67 */ + else if (n < 171) {} + else if (n < 172) { indatum = 91; } /* Puerto Rico */ + else if (n < 173) { indatum = 92; } /* Pulkovo 1942 */ + else if (n < 174) { indatum = 94; } /* Quatar National */ + else if (n < 176) {} + else if (n < 177) { indatum = 95; } /* Rome 1940 */ + else if (n < 184) { indatum = 96; } /* S-42 (Pulkovo 1942) */ + else if (n < 185) {} + else if (n < 186) { indatum = 100; } /* Santo DOS */ + else if (n < 187) { indatum = 99; } /* Sao Braz */ + else if (n < 191) {} + else if (n < 193) { indatum = 105; } /* SAD-69/Mean */ + else if (n < 194) { indatum = 98; } /* SAD-69/Brazil */ + else if (n < 204) { indatum = 105; } /* SAD-69/Mean */ + else if (n < 205) { indatum = 106; } /* South Asia */ + else if (n < 206) { indatum = 109; } /* Tananarive 1926 */ + else if (n < 207) { indatum = 111; } /* Timbalai 1948 */ + else if (n < 211) { indatum = 112; } /* Tokyo mean */ + else if (n < 212) { indatum = 113; } /* Tristan Astro 1968 */ + else if (n < 213) { indatum = 115; } /* Viti Levu 1916 */ + else if (n < 215) {} + else if (n < 216) { indatum = 116; } /* Wake Eniwetok 1960 */ + else if (n < 217) { indatum = 117; } /* WGS 72 */ + else if (n < 218) { indatum = 118; } /* WGS 84 */ + else if (n < 219) { indatum = 119; } /* Yacare */ + else if (n < 220) { indatum = 120; } /* Zanderij */ + else if (n < 231) {} + else if (n < 232) { indatum = 98; } /* SAD-69/Brazil*/ + else if (n < 234) {} + else if (n < 235) { indatum = 117; } /* WGS 72 */ + else if (n < 236) { indatum = 0; } /* Adindan */ + else if (n < 237) { indatum = 2; } /* Ain el Abd */ + else if (n < 238) { indatum = 7; } /* ARC 1960 */ + else if (n < 239) { indatum = 8; } /* Ascension Island 58 */ + else if (n < 241) {} + else if (n < 242) { indatum = 52; } /* Hu-Tzu-Shan */ + else if (n < 245) { indatum = 53; } /* Indian */ + else if (n < 246) {} + else if (n < 247) { indatum = 57; } /* Johnston Island 61 */ + else if (n < 248) { indatum = 64; } /* Luzon */ + else if (n < 249) {} + else if (n < 250) { indatum = 75; } /* Nahrwan */ + else if (n < 251) { indatum = 76; } /* Naparima BWI */ + else if (n < 254) {} + else if (n < 255) { indatum = 82; } /* Old Hawaiian Kauai */ + else if (n < 256) { indatum = 83; } /* Old Hawaiian Maui */ + else if (n < 257) { indatum = 84; } /* Old Hawaiian Oahu */ + else if (n < 259) {} + else if (n < 260) { indatum = 101; } /* Sapper Hill 43 */ + else if (n < 261) { indatum = 111; } /* Timbalai 1948 */ + else if (n < 262) { indatum = 112; } /* Tokyo mean */ + else if (n < 263) { indatum = 116; } /* Wake Eniwetok 1960 */ + + if (indatum == -1) + warning(MYNAME ": Unsupported datum (%d), won't convert to WGS84\n", n); +} + +static const char *icon_descr[] = { +"", "Airport", "Ball Park", "Bank", "Bar", "Boat Ramp", "Campground", "Car", +"City (Large)", "City (Medium)", "City (Small)", "Dam", "Danger Area", +"Drinking Water", "Fishing Area", "Gas Station", "Glider Area", "Golf Course", +"Heliport", "Hotel", "Animals", "Information", "Man Overboard", "Marina", +"Mine", "Medical Facility", "Parachute Area", "Park", "Parking Area", +"Picnic Area", "Private Field", "Residence", "Restaurant", "Restroom", +"Scenic Area", "School", "Seaplane Base", "Shipwreck", "Shopping Center", +"Short Tower", "Policy Station", "Ski Resort", "Soft Field", "Swimming Area", +"Tall Tower", "Telephone", "Tracback Point", "Ultralight Area", "Waypoint", +"Boat", "Exit", "Flag", "Duck", "Buoy", "Back Track", "Beach", "Bridge", +"Building", "Car Repair", "Cemetery", "Church", "Civil", "Convenience Store", +"Crossing", "Fast Food", "Forest", "Ghost Town", "Levee", "Military", +"Oil Field", "Post Office", "Rv Park", "Scales", "Summit", "Toll Booth", +"Trail Head", "Truck Stop", "Tunnel", "Highway", "Gate", "Fall", "Fence", +"Mata-Burro", "Fitness Center", "Movie Theater", "Live Theater", "Zoo", "Horn", +"Bowling", "Car Rental", "City (Capitol)", "Controlled Area", "Stadium", +"Museum", "Amusement Park", "Skull", "Department Store", "Pharmacy", "Pizza", +"Diver Down Flag 1", "Light", "Pin", "", "Pigsty", "Tree", "Bamboo", +"Banana Plant", "Arrow-Down", "Bifurcation", "Cavern", "River", "Rock", +"Arrow-Up", "Trunk", "Soccer Field", "Sporting Court", "Flag, Green", "Trench", +"Ship-Yellow", "Green Sign", "Swamp", "Lake", "Stop!", +"Fishing Hot Spot Facility", "Speed Reducer", "Stairway", "Cactus", "Ship-Red", +"Letter - S", "Letter - D", "Letter - N", +"Crossing", "Cross", "Flag, Red", "Curve1", "Curve2", "Curve3", "Curve4", +"Letter - W", "Letter - L", "Letter - R", "Radio Beacon", "Road Sign", +"Geocache", "Geocache Found", "Traffic Light", "Bus Station", "Train Station", +"School", "Mile Marker", "Conservation Area", "Waypoint", "Box", "Aerial", +"Auto Repair", "Boat", "Exit Ramp", "Fixed Nav Aid", "Floating Buoy", "Garden", +"Fish Farm", "Lighthouse", "Truck Service", "Resort", "Scuba", "Shooting", +"Sight Seeing", "Sounding", "Winery", "Navaid, Amber", "Navaid, Black", +"Navaid, Blue", "Navaid, Green", "Navaid, Green/Red", "Navaid, Green/White", +"Navaid, Orange", "Navaid, Red", "Navaid, Red/Green", "Navaid, Red/White", +"Navaid, Violet", "Navaid, White", "Navaid, White/Green", "Navaid, White/Red", +"Buoy, White", "Dot, White", "Red Square", "Red Diamond", "Green Square", +"Green Diamond", "Restricted Area", "Navaid (unlit)", "Dot (Small)", "Libraries", "Waypoint", "Waypoint1", +"Waypoint2", "Mark (1)", "Mark (2)", "Mark (3)", "Cross (Red)", "Store", +"Exclamation", "Flag (EUA)", "Flag (CAN)", "Flag (BRA)", "Man", "Animals", +"Deer Tracks", "Tree Stand", "Bridge", "Fence", "Intersection", +"Non Direct Beacon", "VHF Omni Range", "Vor/Tacan", "Vor-Dme", +"1st Approach Fix", "Localizer Outer", "Missed Appr. Pt", "Tacan", +"CheckPoint", NULL +}; + + +void convert_datum(double *lat, double *lon) +{ + double amt; + if (indatum != -1 && indatum != 118) { + GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, + lat, lon, &amt, indatum); + } +} + +/* Callbacks */ + +static void +gtm_rd_init(const char *fname) +{ + int version; + char *name; + file_in = gbfopen_le(fname, "rb", MYNAME); + version = fread_integer(file_in); + name = fread_fixedstring(file_in, 10); + if (version == -29921) + fatal(MYNAME ": Uncompress the file first\n"); + if (strcmp(name, "TrackMaker") != 0) + fatal(MYNAME ": Invalid file format\n"); + if (version != 211) + fatal(MYNAME ": Invalid format version\n"); + xfree(name); + + /* Header */ + fread_discard(file_in, 15); + ws_count = fread_long(file_in); + fread_discard(file_in, 4); + wp_count = fread_long(file_in); + tr_count = fread_long(file_in); + rt_count = fread_long(file_in); + fread_discard(file_in, 16); + im_count = fread_long(file_in); + ts_count = fread_long(file_in); + fread_discard(file_in, 28); + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_string_discard(file_in); + + /* User Grid and Datum */ + fread_discard(file_in, 34); + set_datum(fread_integer(file_in)); + fread_discard(file_in, 22); +} + +static void +gtm_rd_deinit(void) +{ + gbfclose(file_in); +} + +static void count_route_waypts(const waypoint *wpt) { rt_count++; } +static void count_track_waypts(const waypoint *wpt) { tr_count++; } + +static void +gtm_wr_init(const char *fname) +{ + rt_count = tr_count = 0; + track_disp_all(NULL, NULL, count_track_waypts); + route_disp_all(NULL, NULL, count_route_waypts); + + file_out = gbfopen_le(fname, "wb", MYNAME); /* little endian */ + + /* Header */ + fwrite_integer(file_out, 211); + fwrite_fixedstring(file_out, "TrackMaker", 10); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 8); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_long(file_out, 0); + fwrite_long(file_out, 16777215); + fwrite_long(file_out, waypt_count() ? 4 : 0); /* num waypoint styles */ + fwrite_long(file_out, 0); + fwrite_long(file_out, waypt_count()); /* num waypoints */ + fwrite_long(file_out, tr_count); + fwrite_long(file_out, rt_count); + fwrite_single(file_out, 0); /* maxlon */ + fwrite_single(file_out, 0); /* minlon */ + fwrite_single(file_out, 0); /* maxlat */ + fwrite_single(file_out, 0); /* minlat */ + fwrite_long(file_out, 0); + fwrite_long(file_out, track_count()); /* num tracklog styles */ + fwrite_single(file_out, 0); + fwrite_single(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_string(file_out, "Times New Roman"); + fwrite_string(file_out, ""); + fwrite_string(file_out, ""); + fwrite_string(file_out, ""); + + /* User Grid and Datum */ + fwrite_null(file_out, 34); + fwrite_integer(file_out, 217); /* WGS84 */ + fwrite_null(file_out, 22); +} + +static void +gtm_wr_deinit(void) +{ + gbfclose(file_out); +} + +static void +gtm_read(void) +{ + route_head *first_trk_head = NULL; + route_head *trk_head = NULL; + route_head *rte_head = NULL; + waypoint *wpt; + int real_tr_count = 0; + char *route_name; + unsigned int icon; + int i; + + /* Image information */ + for (i = 0; i != im_count; i++) { + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_discard(file_in, 30); + } + + /* Waypoints */ + for (i = 0; i != wp_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->shortname = fread_fixedstring(file_in, 10); + wpt->description = fread_string(file_in); + icon = fread_integer(file_in); + if (icon < sizeof(icon_descr)/sizeof(char*)) + wpt->icon_descr = icon_descr[icon]; + fread_discard(file_in, 1); + wpt->creation_time = fread_long(file_in); + if (wpt->creation_time) + wpt->creation_time += EPOCH89DIFF; + fread_discard(file_in, 2); + wpt->altitude = fread_single(file_in); + if (wpt->altitude == unknown_alt_gtm) + wpt->altitude = unknown_alt; + fread_discard(file_in, 2); + waypt_add(wpt); + } + + /* Waypoint Styles */ + if (wp_count) { + for (i = 0; i != ws_count; i++) { + fread_discard(file_in, 4); + fread_string_discard(file_in); + fread_discard(file_in, 24); + } + } + + /* Tracklogs */ + for (i = 0; i != tr_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->creation_time = fread_long(file_in); + if (wpt->creation_time) + wpt->creation_time += EPOCH89DIFF; + start_new = fread_byte(file_in); + wpt->altitude = fread_single(file_in); + if (wpt->altitude == unknown_alt_gtm) + wpt->altitude = unknown_alt; + if (start_new || !trk_head) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + real_tr_count++; + if (!first_trk_head) + first_trk_head = trk_head; + } + track_add_wpt(trk_head, wpt); + } + + /* Tracklog styles */ + trk_head = first_trk_head; + for (i = 0; i != ts_count && i != real_tr_count; i++) { + trk_head->rte_name = fread_string(file_in); + fread_discard(file_in, 12); + trk_head = (route_head *)QUEUE_NEXT(&trk_head->Q); + } + + /* Routes */ + for (i = 0; i != rt_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->shortname = fread_fixedstring(file_in, 10); + wpt->description = fread_string(file_in); + route_name = fread_string(file_in); + icon = fread_integer(file_in); + if (icon < sizeof(icon_descr)/sizeof(char*)) + wpt->icon_descr = icon_descr[icon]; + fread_discard(file_in, 1); + start_new = fread_byte(file_in); + fread_discard(file_in, 6); + wpt->altitude = fread_single(file_in); + if (wpt->altitude == unknown_alt_gtm) + wpt->altitude = unknown_alt; + fread_discard(file_in, 2); + + if (start_new || !rte_head) { + rte_head = route_head_alloc(); + rte_head->rte_name = route_name; + route_add_head(rte_head); + } + else { + xfree(route_name); + } + route_add_wpt(rte_head, wpt); + } +} + +int icon_from_descr(const char *descr) +{ + if (descr) { + int i; + for (i = 0; icon_descr[i]; i++) + if (strcmp(icon_descr[i], descr) == 0) + return i; + } + return 48; +} + +static void write_waypt(const waypoint *wpt) +{ + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_fixedstring(file_out, wpt->shortname, 10); + fwrite_string(file_out, wpt->description); + fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); + fwrite_byte(file_out, 3); + if (wpt->creation_time) + fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); + else + fwrite_long(file_out, 0); + fwrite_integer(file_out, 0); + if (wpt->altitude == unknown_alt) + fwrite_single(file_out, unknown_alt_gtm); + else + fwrite_single(file_out, wpt->altitude); + fwrite_integer(file_out, 0); +} + +static void start_rte(const route_head *rte) +{ + rte_active = rte; + start_new = 1; +} + +static void write_trk_waypt(const waypoint *wpt) +{ + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); + fwrite_byte(file_out, start_new); + if (wpt->altitude == unknown_alt) + fwrite_single(file_out, unknown_alt_gtm); + else + fwrite_single(file_out, wpt->altitude); + start_new = 0; +} + +static void write_trk_style(const route_head *trk) +{ + fwrite_string(file_out, trk->rte_name); + fwrite_byte(file_out, 1); + fwrite_long(file_out, 0); + fwrite_single(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_integer(file_out, 0); +} + +static void write_rte_waypt(const waypoint *wpt) +{ + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_fixedstring(file_out, wpt->shortname, 10); + fwrite_string(file_out, wpt->description); + fwrite_string(file_out, rte_active->rte_name); + fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); + fwrite_byte(file_out, 3); + fwrite_byte(file_out, start_new); + fwrite_long(file_out, 0); + fwrite_integer(file_out, 0); + if (wpt->altitude == unknown_alt) + fwrite_single(file_out, unknown_alt_gtm); + else + fwrite_single(file_out, wpt->altitude); + fwrite_integer(file_out, 0); + start_new = 0; +} + +static void +gtm_write(void) +{ + waypt_disp_all(write_waypt); + if (waypt_count()) + gbfwrite(WAYPOINTSTYLES, 1, sizeof(WAYPOINTSTYLES)-1, file_out); + track_disp_all(start_rte, NULL, write_trk_waypt); + track_disp_all(write_trk_style, NULL, NULL); + route_disp_all(start_rte, NULL, write_rte_waypt); +} + +static +arglist_t gtm_args[] = { + ARG_TERMINATOR +}; + +ff_vecs_t gtm_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + gtm_rd_init, + gtm_wr_init, + gtm_rd_deinit, + gtm_wr_deinit, + gtm_read, + gtm_write, + NULL, + gtm_args, +}; diff --git a/gtrnctr.c b/gtrnctr.c new file mode 100644 index 000000000..12446e91b --- /dev/null +++ b/gtrnctr.c @@ -0,0 +1,302 @@ +/* + Access Garmin Training Center (Forerunner/Foretracker/Edge) data files. + + Copyright (C) 2006, 2007 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "xmlgeneric.h" + +static gbfile *ofd; +static waypoint *wpt_tmp; +static route_head *trk_head; + +#define MYNAME "gtc" + +static +arglist_t gtc_args[] = { + ARG_TERMINATOR +}; +#if 0 +/* Tracks */ +static xg_callback gl_trk_s; +// static xg_callback gl_trk_ident; +static xg_callback gl_trk_pnt_s, gl_trk_pnt_e; +static xg_callback gl_trk_utc; +static xg_callback gl_trk_lat; +static xg_callback gl_trk_long; +static xg_callback gl_trk_alt; + +static xg_tag_mapping gl_map[] = { + { gl_trk_s, cb_start, "/History/Run/Track" }, + { gl_trk_pnt_s,cb_start, "/History/Run/Track/Trackpoint/Position" }, + { gl_trk_pnt_e,cb_end, "/History/Run/Track/Trackpoint/Position" }, + { gl_trk_lat, cb_cdata, "/History/Run/Track/Trackpoint/Position/Latitude" }, + { gl_trk_long, cb_cdata, "/History/Run/Track/Trackpoint/Position/Longitude" }, + { gl_trk_alt, cb_cdata, "/History/Run/Track/Trackpoint/Position/Altitude" }, + { gl_trk_utc, cb_cdata, "/History/Run/Track/Trackpoint/Time" }, + { NULL, 0, NULL} +}; +#endif + +static void +gtc_rd_init(const char *fname) +{ + fatal(MYNAME ": this format does not support reading.\n"); +} + +#if 0 +static void +gtc_read(void) +{ + xml_read(); +} + +static void +gtc_rd_deinit(void) +{ + xml_deinit(); +} +#endif + +static void +gtc_wr_init(const char *fname) +{ + ofd = gbfopen(fname, "w", MYNAME); +} + +static void +gtc_wr_deinit(void) +{ + gbfclose(ofd); +} + +static int gtc_indent_level; +static void +gtc_write_xml(int indent, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + + if (indent < 0) gtc_indent_level--; + + gbfprintf(ofd, "%*s", gtc_indent_level * 2, ""); + gbvfprintf(ofd, fmt, args); + + if (indent > 0) gtc_indent_level++; + + va_end(args); +} + +static void +gtc_waypt_pr(const waypoint *wpt) +{ +#if 0 + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " %.5f\n", wpt->latitude); + gbfprintf(ofd, " %.5f\n", wpt->longitude); + if (wpt->altitude != unknown_alt) { + gbfprintf(ofd, " %.3f\n", wpt->altitude); + } + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " "); + xml_write_time(ofd, wpt->creation_time, "Time"); + gbfprintf(ofd, " \n"); +#else + gtc_write_xml(1, "\n"); + if (wpt->creation_time) { + char time_string[100]; + xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, + XML_LONG_TIME); + if (time_string[0]) { + gtc_write_xml(0, "\n", + time_string); + } + } + gtc_write_xml(1, "\n"); + gtc_write_xml(0, "%f\n", wpt->latitude); + gtc_write_xml(0, "%f\n", wpt->longitude); + gtc_write_xml(-1, "\n"); + if (wpt->altitude != unknown_alt) { + gtc_write_xml(0, "%f\n", wpt->altitude); + } + if (wpt->heartrate) { + gtc_write_xml(0, "%d\n", wpt->heartrate); + } + if (wpt->cadence) { + gtc_write_xml(0, "%d\n", wpt->cadence); + } + + + gtc_write_xml(-1, "\n"); +#endif +} + +static void +gtc_hdr( const route_head *rte) +{ + gtc_write_xml(1,"\n"); +} + +static void +gtc_ftr(const route_head *rte) +{ + gtc_write_xml(-1,"\n"); +} + +static time_t gtc_least_time; +static time_t gtc_most_time; + +static void +gtc_lap_start(const route_head *rte) +{ + gtc_least_time = 0; + gtc_most_time = 0; +} + +static void +gtc_study_lap(const waypoint *wpt) +{ + if (wpt->creation_time && (gtc_least_time == 0)) + gtc_least_time = wpt->creation_time; + + if (wpt->creation_time && (gtc_least_time > wpt->creation_time)) + gtc_least_time = wpt->creation_time; + + if (wpt->creation_time > gtc_most_time) + gtc_most_time = wpt->creation_time; +} + +static void +gtc_fake_hdr(void) +{ + long secs = 0; + if (gtc_least_time && gtc_most_time) { + secs = gtc_most_time - gtc_least_time; + } + gtc_write_xml(0, "%d\n", secs); + gtc_write_xml(0, "0\n"); + gtc_write_xml(0, "0\n"); + gtc_write_xml(0, "0\n"); + gtc_write_xml(0, "0\n"); + gtc_write_xml(0, "Active\n"); + gtc_write_xml(0, "Manual\n"); +} + +void +gtc_write(void) +{ +#if 0 + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, " \n"); + track_disp_all(gtc_hdr, gtc_ftr, gtc_waypt_pr); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, "\n"); +#else + gtc_write_xml(0, "\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(1, "\n"); + + gtc_write_xml(1, "\n"); + gtc_write_xml(1, "\n"); + + gtc_lap_start(NULL); + track_disp_all(NULL, NULL, gtc_study_lap); + + if (gtc_least_time) { + char time_string[100]; + xml_fill_in_time(time_string, gtc_least_time, 0, XML_LONG_TIME); + gtc_write_xml(1, "\n", time_string); + } else { + gtc_write_xml(1, "\n"); + } + gtc_fake_hdr(); + track_disp_all(gtc_hdr, gtc_ftr, gtc_waypt_pr); + gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); + gtc_write_xml(0, "\n"); + gtc_write_xml(0, "\n"); + gtc_write_xml(0, "\n"); + + gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); + +#endif +} + +void gl_trk_s(const char *args, const char **unused) +{ + trk_head = route_head_alloc(); + track_add_head(trk_head); +} +#if 0 +void gl_trk_ident(const char *args, const char **unused) +{ + trk_head->rte_name = xstrdup(args); +} +#endif + +void gl_trk_pnt_s(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); +} + +void gl_trk_pnt_e(const char *args, const char **unused) +{ + track_add_wpt(trk_head, wpt_tmp); +} + +void gl_trk_utc(const char *args, const char **unused) +{ + wpt_tmp->creation_time = xml_parse_time(args, NULL); +} + +void gl_trk_lat(const char *args, const char **unused) +{ + wpt_tmp->latitude = atof(args); +} + +void gl_trk_long(const char *args, const char **unused) +{ + wpt_tmp->longitude = atof(args); +} + +void gl_trk_alt(const char *args, const char **unused) +{ + wpt_tmp->altitude = atof(args); +} + + + +ff_vecs_t gtc_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_write, ff_cap_none}, + gtc_rd_init, + gtc_wr_init, + NULL, + gtc_wr_deinit, + NULL, + gtc_write, + NULL, + gtc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/guibabel b/guibabel new file mode 100755 index 000000000..6afd8a5ed --- /dev/null +++ b/guibabel @@ -0,0 +1,99 @@ +#!/bin/sh +# the next line restarts using wish \ +exec wish "$0" "$@" + +# +# This was largely cribbed from the TCL demo code. My TCL skills weren't +# that great when I last used it about ten years ago and my Tk skills never +# existed before. So be kind. +# + +set font {Helvetica 14} +set ifile {} +set ofile {} +set use_shortnames 0 + +proc positionWindow w { + wm geometry $w +300+300 +} + +proc showCmd w { + global ifile ofile use_shortnames ftyperead ftypewrite + set cmd "gpsbabel -i $ftyperead -f $ifile" + if {$use_shortnames > 0} { + set cmd [concat $cmd "-s"] + } + set cmd [concat $cmd "-o $ftypewrite -F $ofile"] + eval exec $cmd + +# tk_messageBox -icon info -message $cmd +} + +set w .filebox +catch {destroy $w} +toplevel $w +wm title $w "gpsbabel" +wm iconname $w "filebox" +positionWindow $w + +#label $w.msg -font $font -wraplength 4i -justify left -text "Enter a file name in the entry box or click on the \"Browse\" buttons to select a file name using the file selection dialog." +#pack $w.msg -side top + +frame $w.buttons +pack $w.buttons -side bottom -fill x -pady 2m +button $w.buttons.dismiss -text End -command "destroy $w" +button $w.buttons.code -text OK -command "showCmd $w" +pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + +foreach i {read write} { + set f [frame $w.$i] + set ftype "ftype$i" + label $f.lab -text "Select a file to $i: " -anchor e + entry $f.ent -width 20 + button $f.but -text "Browse ..." -command "fileDialog $w $f.ent $i" +# TODO: Get this list from 'gpsbabel -?' instead of hardcoding it here. + tk_optionMenu $f.ftypes $ftype geo gpsman gpx \ + magellan mapsend pcx mapsource gpsutil tiger csv xmap dna psp \ + cetus gpspilot magnav garmin mxf holux ozi tpg tpo igc baroiq + pack $f.lab -side left + pack $f.ent -side left -expand yes -fill x + pack $f.but -side left + pack $f -fill x -padx 1c -pady 3 + pack $f.ftypes -side right -padx 45 +} +set ftyperead "geo" +set ftypewrite "mapsend" + + checkbutton $w.strict -text "Make Up Shortnames" \ + -variable use_shortnames -onvalue 1 -offvalue 0 + pack $w.strict -anchor c + +proc fileDialog {w ent operation} { + # Type names Extension(s) Mac File Type(s) + # + #--------------------------------------------------------- + set types { + {"All files" * } + {"loc files" {.loc} } + {"Waypoint files" {.wpt} } + {"GPX files" {.gpx} } + {"Various Palm/OS files" {.pdb} } + } + global ifile ofile + if {$operation == "read"} { + set ifile [tk_getOpenFile -filetypes $types -parent $w] + if [string compare $ifile ""] { + $ent delete 0 end + $ent insert 0 $ifile + $ent xview end + } ; + } else { + set ofile [tk_getSaveFile -filetypes $types -parent $w \ + -initialfile Untitled ] + if [string compare $ofile ""] { + $ent delete 0 end + $ent insert 0 $ofile + $ent xview end + } ; + } +} diff --git a/hiketech.c b/hiketech.c new file mode 100644 index 000000000..c5f35b08d --- /dev/null +++ b/hiketech.c @@ -0,0 +1,299 @@ +/* + Access Hiketech XML data files. + + Copyright (C) 2004,2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "xmlgeneric.h" + +static gbfile *ofd; +static waypoint *wpt_tmp; +static route_head *trk_head; + + +#define MYNAME "hiketech" + +static +arglist_t hiketech_args[] = { + ARG_TERMINATOR +}; + +/* Waypoints */ +static xg_callback ht_wpt_s; +static xg_callback ht_wpt_e; +static xg_callback ht_ident; +static xg_callback ht_sym; +static xg_callback ht_lat; +static xg_callback ht_long; +static xg_callback ht_alt; + +/* Tracks */ +static xg_callback ht_trk_s, ht_trk_e; +static xg_callback ht_trk_ident; +static xg_callback ht_trk_pnt_s, ht_trk_pnt_e; +static xg_callback ht_trk_utc; +static xg_callback ht_trk_lat; +static xg_callback ht_trk_long; +static xg_callback ht_trk_alt; + +static xg_tag_mapping ht_map[] = { + { ht_wpt_s, cb_start, "/hiketech/gpsdata/wpt" }, + { ht_wpt_e, cb_end, "/hiketech/gpsdata/wpt" }, + { ht_ident, cb_cdata, "/hiketech/gpsdata/wpt/ident" }, + { ht_sym, cb_cdata, "/hiketech/gpsdata/wpt/sym" }, + { ht_lat, cb_cdata, "/hiketech/gpsdata/wpt/lat" }, + { ht_long, cb_cdata, "/hiketech/gpsdata/wpt/long" }, + { ht_alt, cb_cdata, "/hiketech/gpsdata/wpt/alt" }, + + { ht_trk_s, cb_start, "/hiketech/gpsdata/trk" }, + { ht_trk_e, cb_end, "/hiketech/gpsdata/trk" }, + { ht_trk_ident, cb_cdata, "/hiketech/gpsdata/trk/ident" }, + { ht_trk_pnt_s, cb_start, "/hiketech/gpsdata/trk/pnt" }, + { ht_trk_pnt_e, cb_end, "/hiketech/gpsdata/trk/pnt" }, + { ht_trk_utc, cb_cdata, "/hiketech/gpsdata/trk/pnt/utc" }, + { ht_trk_lat, cb_cdata, "/hiketech/gpsdata/trk/pnt/lat" }, + { ht_trk_long, cb_cdata, "/hiketech/gpsdata/trk/pnt/long" }, + { ht_trk_alt, cb_cdata, "/hiketech/gpsdata/trk/pnt/alt" }, + { NULL, 0, NULL} +}; + +static void +hiketech_rd_init(const char *fname) +{ + xml_init(fname, ht_map, NULL); +} + +static void +hiketech_read(void) +{ + xml_read(); +} + +static void +hiketech_rd_deinit(void) +{ + xml_deinit(); +} + +static void +hiketech_wr_init(const char *fname) +{ + ofd = gbfopen(fname, "w", MYNAME); +} + +static void +hiketech_wr_deinit(void) +{ + gbfclose(ofd); +} + +static void +hiketech_trk_hdr(const route_head *rte) +{ + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "ident", rte->rte_name); +} + +static void +hiketech_trk_tlr(const route_head *rte) +{ + gbfprintf(ofd, "\n"); +} + +static void +hiketech_print_utc(time_t tm, const char *indent, const char *tag) +{ + char tbuf[80]; + strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %I:%M:%S", gmtime(&tm)); + gbfprintf(ofd, "%s<%s>%s\n",indent,tag,tbuf,tag); +} + +static void +hiketech_trkpt_pr(const waypoint *waypointp) +{ + gbfprintf(ofd, " \n"); + if (waypointp->creation_time) { + hiketech_print_utc(waypointp->creation_time, " ", "utc"); + } + gbfprintf(ofd, " %f\n", waypointp->latitude); + gbfprintf(ofd, " %f\n", waypointp->longitude); + if (waypointp->altitude != unknown_alt) { + gbfprintf(ofd, " %f\n", + waypointp->altitude); + } + gbfprintf(ofd, " \n"); +} + +static void +hiketech_waypt_pr(const waypoint *wpt) +{ + gbfprintf(ofd, "\n"); + write_xml_entity(ofd, "\t", "ident", wpt->shortname); + write_optional_xml_entity(ofd, "\t", "sym", wpt->icon_descr); + gbfprintf(ofd, "\t%f\n", wpt->latitude); + gbfprintf(ofd, "\t%f\n", wpt->longitude); + + /* + * These probably aren't technicallyconstants, but it's all + * we can do for now. + */ + gbfprintf(ofd, "\t\n\t\tFAFFB4\n\t\tFF8000\n\t\n"); + gbfprintf(ofd, "\n"); +} + +static void +hiketech_write(void) +{ + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + track_disp_all(hiketech_trk_hdr, hiketech_trk_tlr, hiketech_trkpt_pr); + track_disp_all(NULL, NULL, hiketech_trkpt_pr); + waypt_disp_all(hiketech_waypt_pr); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); +} + +static +void ht_wpt_s(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); +} + +static +void ht_ident(const char *args, const char **unused) +{ + wpt_tmp->shortname = xstrdup(args); +} + +static +void ht_sym(const char *args, const char **unused) +{ + wpt_tmp->icon_descr = xstrdup(args); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; +} + +static +void ht_lat(const char *args, const char **unused) +{ + wpt_tmp->latitude = atof(args); +} + +static +void ht_long(const char *args, const char **unused) +{ + wpt_tmp->longitude = atof(args); +} + +static +void ht_alt(const char *args, const char **unused) +{ + wpt_tmp->altitude = atof(args); +} + +static +void ht_wpt_e(const char *args, const char **unused) +{ + waypt_add(wpt_tmp); + wpt_tmp = NULL; +} + +static +void ht_trk_s(const char *args, const char **unused) +{ + trk_head = route_head_alloc(); + track_add_head(trk_head); +} + +static +void ht_trk_e(const char *args, const char **unused) +{ + +} + +static +void ht_trk_ident(const char *args, const char **unused) +{ + trk_head->rte_name = xstrdup(args); +} + +static +void ht_trk_pnt_s(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); +} + +static +void ht_trk_pnt_e(const char *args, const char **unused) +{ + track_add_wpt(trk_head, wpt_tmp); +} + +static +void ht_trk_utc(const char *args, const char **unused) +{ + struct tm tm; + time_t utc; + + sscanf(args, "%d-%d-%d %d:%d:%d", + &tm.tm_year, &tm.tm_mon, + &tm.tm_mday, &tm.tm_hour, + &tm.tm_min, &tm.tm_sec); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; + + utc = mkgmtime(&tm); + + wpt_tmp->creation_time = utc; +} + +static +void ht_trk_lat(const char *args, const char **unused) +{ + wpt_tmp->latitude = atof(args); +} + +static +void ht_trk_long(const char *args, const char **unused) +{ + wpt_tmp->longitude = atof(args); +} + +static +void ht_trk_alt(const char *args, const char **unused) +{ + wpt_tmp->altitude = atof(args); +} + + + +ff_vecs_t hiketech_vecs = { + ff_type_file, + { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write }, + hiketech_rd_init, + hiketech_wr_init, + hiketech_rd_deinit, + hiketech_wr_deinit, + hiketech_read, + hiketech_write, + NULL, + hiketech_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; + diff --git a/holux.c b/holux.c new file mode 100644 index 000000000..ba1010c0c --- /dev/null +++ b/holux.c @@ -0,0 +1,308 @@ +/* + Access to holux wpo files. + + Copyright (C) 2002 Jochen Becker, jb@bepo.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + +History: + 2002-09-15 J. Becker start programming + + +*/ +/* This module is for the holux (gm-100) .wpo format */ + + + +#include +#include "defs.h" +#include "holux.h" + + +static gbfile *file_in, *file_out; +static unsigned char *HxWFile; +static short_handle mkshort_handle; + +#define MYNAME "Holux" + + +static void rd_init(const char *fname) +{ + file_in = gbfopen_le(fname, "rb", MYNAME); +} + + +static void rd_deinit(void) +{ + gbfclose(file_in); +} + + + + + +static void +wr_init(const char *fname) +{ + mkshort_handle = mkshort_new_handle(); + + HxWFile = xcalloc(GM100_WPO_FILE_SIZE, 1); + + file_out = gbfopen_le(fname, "wb", MYNAME); +} + + + + + +static void wr_deinit(void) +{ + mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); +} + + + +static void data_read(void) +{ + char name[9], desc[90]; + double lat,lon; + unsigned char *HxWpt; + waypoint *wpt_tmp; + int iCount; + int iDataRead; + int iWptNum; + int iWptIndex; + WPT *pWptHxTmp; + struct tm tm; + struct tm *ptm; + + memset(&tm, 0, sizeof(tm)); + + HxWpt = xcalloc(GM100_WPO_FILE_SIZE, 1); + + /* read the wpo file to the data-array */ + iDataRead = gbfread( HxWpt, 1, GM100_WPO_FILE_SIZE, file_in ); + + if (iDataRead == 0) + { + fatal(MYNAME ": Error reading data from %s.\n", file_in->name); + } + + iWptNum = le_read16(&((WPTHDR *)HxWpt)->num); + + /* Get the waypoints */ + for (iCount = 0; iCount < iWptNum ; iCount ++) + { + wpt_tmp = waypt_new(); + + iWptIndex = le_read16(&((WPTHDR *)HxWpt)->idx[iCount]); + pWptHxTmp = (WPT *)&HxWpt[OFFS_WPT + (sizeof(WPT) * iWptIndex)]; + + wpt_tmp->altitude = 0; + strncpy(name,pWptHxTmp->name,sizeof(pWptHxTmp->name)); + name[sizeof(pWptHxTmp->name)]=0; + + strncpy(desc,pWptHxTmp->comment,sizeof(pWptHxTmp->comment)); + desc[sizeof(pWptHxTmp->comment)]=0; + + wpt_tmp->shortname = xstrdup(name); + wpt_tmp->description = xstrdup(desc); + + wpt_tmp->creation_time = 0; + if (pWptHxTmp->date.year) + { +#if 0 + /* Unless there's some endian swapping that I don't see, + * this can't be right. Then again, the definition of the + * the structure itself has a pretty serious disregard for + * host word size issues... - rjl + */ + ptm = gmtime((time_t*)&pWptHxTmp->time); +#else + time_t wt = le_read32(&pWptHxTmp->time); + ptm = gmtime(&wt); +#endif + tm.tm_hour = ptm->tm_hour; + tm.tm_min = ptm->tm_min; + tm.tm_sec = ptm->tm_sec; + + tm.tm_mday = pWptHxTmp->date.day; + tm.tm_mon = pWptHxTmp->date.month - 1; + tm.tm_year = pWptHxTmp->date.year - 1900; + wpt_tmp->creation_time = mktime(&tm); + } + + lon = le_read32(&pWptHxTmp->pt.iLongitude) / 36000.0; + lat = (le_read32(&pWptHxTmp->pt.iLatitude) / 36000.0) * -1.0; + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + waypt_add(wpt_tmp); + } + xfree(HxWpt); +} + + + + +char *mknshort (char *stIn,unsigned int sLen) +{ + #define MAX_STRINGLEN 255 + static char strOut[MAX_STRINGLEN]; + char strTmp[MAX_STRINGLEN]; + char *shortstr = NULL; + + if (sLen > MAX_STRINGLEN) + return (stIn); + + if (stIn == NULL) + return NULL; + + setshort_length(mkshort_handle, sLen); + setshort_mustuniq(mkshort_handle, 0); + + shortstr = mkshort(mkshort_handle, stIn); + strcpy(strTmp,shortstr); + xfree(shortstr); + + memset(strOut,' ', MAX_STRINGLEN); + strncpy (strOut,strTmp,strlen(strTmp)); + return (strOut); +} + + + + +static void holux_disp(const waypoint *wpt) +{ + double lon,lat; + struct tm *tm; + short sIndex; + WPT *pWptHxTmp; + + lon =(double)wpt->longitude * 36000; + lat =(double)wpt->latitude * -36000; + + + /* round it to increase the accuracy */ + if (lon != 0) lon += (double)((int)lon/abs((int)lon)) * .5; + if (lat != 0) lat += (double)((int)lat/abs((int)lat)) * .5; + + sIndex = le_read16(&((WPTHDR *)HxWFile)->num); + ((WPTHDR *)HxWFile)->idx[sIndex] = sIndex; /* set the waypoint index */ + le_write16(&((WPTHDR *)HxWFile)->idx[sIndex], sIndex); /* set the waypoint index */ + ((WPTHDR *)HxWFile)->used[sIndex] = 0xff; /* Waypoint used */ + + + /* set Waypoint */ + pWptHxTmp = (WPT *)&HxWFile[OFFS_WPT + (sizeof(WPT) * sIndex)]; + + memset (pWptHxTmp->name,0x20,sizeof(pWptHxTmp->name)); + if (wpt->shortname != NULL) + strncpy(pWptHxTmp->name, mknshort(wpt->shortname,sizeof(pWptHxTmp->name)),sizeof(pWptHxTmp->name)); + else + sprintf(pWptHxTmp->name,"W%d",sIndex); + + memset (pWptHxTmp->comment,0x20,sizeof(pWptHxTmp->comment)); + if (wpt->description != NULL) + strncpy(pWptHxTmp->comment, mknshort(wpt->description,sizeof(pWptHxTmp->comment)),sizeof(pWptHxTmp->comment)); + + /*set the time */ + if (wpt->creation_time) + { + /* tm = gmtime(&wpt->creation_time);*/ /* I get the wrong result with gmtime ??? */ + tm = localtime(&wpt->creation_time); + pWptHxTmp->time = (tm->tm_hour * 3600) + (tm->tm_min * 60) +tm->tm_sec; + pWptHxTmp->date.day = tm->tm_mday; + pWptHxTmp->date.month = tm->tm_mon + 1; + pWptHxTmp->date.year = tm->tm_year + 1900; + } + else + { + pWptHxTmp->time = 0; + pWptHxTmp->date.day = 0; + pWptHxTmp->date.month = 0; + pWptHxTmp->date.year = 0; + } + + + le_write32(&pWptHxTmp->pt.iLatitude,(unsigned int) lat); + le_write32(&pWptHxTmp->pt.iLongitude,(unsigned int) lon); + pWptHxTmp->checked = 01; + pWptHxTmp->vocidx = (short)0xffff; + le_write16(&((WPTHDR *)HxWFile)->num, ++sIndex); + le_write16(&((WPTHDR *)HxWFile)->next, ++sIndex); +} + + + + + + +static void data_write(void) +{ + int iWritten; + short sCount; + + /* init the waypoint area*/ + le_write32(&((WPTHDR *)HxWFile)->id, WPT_HDR_ID); + ((WPTHDR *)HxWFile)->num = 0; + ((WPTHDR *)HxWFile)->next = 0; + + /* clear index list */ + for (sCount = 0; sCount < MAXWPT; sCount++) + ((WPTHDR *)HxWFile)->idx[sCount] = (signed short)-1; + for (sCount = 0; sCount < MAXWPT; sCount++) + ((WPTHDR *)HxWFile)->used[sCount] = 0; + + /* init the route area */ + le_write32(&((RTEHDR *)&HxWFile[ROUTESTART])->id, RTE_HDR_ID); + ((RTEHDR *)&HxWFile[ROUTESTART])->num = 0; + le_write16(&((RTEHDR *)&HxWFile[ROUTESTART])->next, 1); + ((RTEHDR *)&HxWFile[ROUTESTART])->rteno = (signed short)-1; + + /* clear index list */ + for (sCount = 0; sCount < MAXRTE; sCount++) + ((RTEHDR *)&HxWFile[ROUTESTART])->idx[sCount] = (signed short)-1; + for (sCount = 0; sCount < MAXRTE; sCount++) + ((RTEHDR *)&HxWFile[ROUTESTART])->used[sCount] = 0; + + waypt_disp_all(holux_disp); + + iWritten = gbfwrite (HxWFile, 1, GM100_WPO_FILE_SIZE,file_out); + if (iWritten == 0) + { + fatal(MYNAME ": Error writing data to %s.\n", file_out->name); + } + xfree(HxWFile); +} + + + + +ff_vecs_t holux_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/holux.h b/holux.h new file mode 100644 index 000000000..cab9e077c --- /dev/null +++ b/holux.h @@ -0,0 +1,117 @@ +/* + holux.h + Copyright (C) 2002 Jochen Becker, jb@bepo.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + /* header file for the holux gm-100 wpo format */ + +#ifndef BYTE +#define BYTE unsigned char +#endif + +#ifndef WORD +#define WORD unsigned short +#endif + +#ifndef DWORD +#define DWORD unsigned int +#endif + + +/* #define GM100_WPO_FILE_SIZE 25512 */ /* size of a holux gm-100 wpo file used by mapShow 1.4*/ +#define GM100_WPO_FILE_SIZE 25600 /* size of a holux gm-100 wpo file used by the GM-100*/ + +#define ROUTESTART 23600 /* Offset for start of route */ +#define MAXWPT 500 /* max number of waypoint */ +#define MAXRTE 20 /* max number of routes */ +#define MAXWPTINRTE 30 + +#define WPT_HDR_ID 0x5C38A631 /* waypoint header */ +#define RTE_HDR_ID 0xD87F59F0 /* route header */ + + + /* Offsets */ +#define OFFS_WPT 0x05E4 /* offet for waypoint table */ + + +typedef struct tagWPTHDR +{ + DWORD id; /* WPT_HDR_ID */ + short num; /* Current wpt number */ + short next; /* next wpt number */ + short idx[MAXWPT]; /* saving wpt index here for each wpt, default was -1*/ + BYTE used[MAXWPT]; /* Have the match wpt been used (0xFF), Default was 0 */ +}WPTHDR; + + + + +typedef struct tagPOINT +{ + signed int iLongitude; + signed int iLatitude; +}POINT; + + + + +typedef struct tagDATE +{ + BYTE day; + BYTE month; + short year; +}HX_DATE; + + +typedef struct tagWPT +{ + char name[8]; /* wpt name */ + char comment[12]; /* comment string */ + POINT pt; /* waypoint location */ + short vocidx; /* voice index, not used */ + short usecount; /* counter: times used by routes */ + HX_DATE date; /* date */ + unsigned time; /* time */ + char checked; /* Active or not */ + BYTE dummy[3]; /* fill bytes */ +}WPT; + + + +typedef struct tagRTEHDR +{ + DWORD id; /* RTE_HDR_ID */ + short num; /* Current route number */ + short next; /* next route number */ + signed short idx[MAXRTE]; /* saving route index here for each route, default was -1 */ + BYTE used[MAXRTE]; /* Have the wpt been used (0xFF), Default was 0 */ + signed short rteno; /* Saving navigationroute number here */ +}RTEHDR; + + +typedef struct tagRTE +{ + char name[8]; /* route name */ + char comment[12]; /* comment string */ + short wptnum; /* the total waypoint number */ + short wptidx[MAXWPTINRTE]; /* the waypoint index in this route */ + short reserved; + int date; /* date */ + int time; /* time */ +}RTE; + diff --git a/hsa_ndv.c b/hsa_ndv.c new file mode 100644 index 000000000..527bcba63 --- /dev/null +++ b/hsa_ndv.c @@ -0,0 +1,563 @@ +/* + Copyright (C) 2004 HSA Systems, Sven Dowideit + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "cet_util.h" +#if HAVE_LIBEXPAT +#include +static XML_Parser psr; +#endif + +static char *cdatastr; +static int in_Route = 0; +static int in_ChartWork = 0; +static int in_Object = 0; + +static waypoint *wpt_tmp; +static char *routeName = "ROUTENAME"; + +#define REPLACEMENT_SIRIUS_ATTR_SEPARATOR ';' +#define ATTR_USRMRK "usrmrk" +#define ATTR_OBJECTNAME "OBJNAM" +#define ATTR_SHIPNAME "shpnam" + +static void readVersion4(gbfile* pFile); +static void getAttr(const char *data, const char *attr, char **val, char seperator); + +static gbfile *fd; +static gbfile *ofd; + +static +arglist_t hsa_ndv_args[] = { + ARG_TERMINATOR +}; + +#define MYNAME "HsaNdv" +#define MY_CBUF 4096 + +#define TRUE 1 +#define FALSE 0 + + +#if ! HAVE_LIBEXPAT +static void +hsa_ndv_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded HSA Endeavour support because expat was not installed.\n"); +} + +static void +hsa_ndv_read(void) +{ +} +#else + +static void +hsa_ndv_start(void *data, const XML_Char *xml_el, const XML_Char **attr) +{ + const char *el = xml_convert_to_char_string(xml_el); + +// printf("<%s>\n", el); + if (strcmp(el, "Export") == 0) + {//should only be one + } + else if (strcmp(el, "Route") == 0) + { + in_Route++; + } + else if (strcmp(el, "Chartwork") == 0) + { + in_ChartWork++; + } + else if (strcmp(el, "Object") == 0) + { + wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1); + wpt_tmp->altitude = unknown_alt; + in_Object++; + } + //reset data :) + memset(cdatastr,0, MY_CBUF); + xml_free_converted_string(el); +} + +static void +hsa_ndv_end(void *data, const XML_Char *xml_el) +{ + const char *el = xml_convert_to_char_string(xml_el); + if (in_Route) + { + if (strcmp(el, "Version") == 0) + {//don't really care + } + else if (strcmp(el, "Name") == 0) + { + routeName = xstrdup(cdatastr); + } + else if (strcmp(el, "LastModified") == 0) + {//don't really care + } + if (in_Object) + { + if (strcmp(el, "ClassName") == 0) + { + } + else if (strcmp(el, "Attr") == 0) + { + getAttr(cdatastr, ATTR_OBJECTNAME, &wpt_tmp->shortname, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + getAttr(cdatastr, ATTR_USRMRK, &wpt_tmp->description, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + } + else if (strcmp(el, "LegAttr") == 0) + { + } + else if (strcmp(el, "NumberOfVertexs") == 0) + { + } + else if (strcmp(el, "Latitude") == 0) + { + wpt_tmp->latitude = atof(cdatastr); + } + else if (strcmp(el, "Longitude") == 0) + { + wpt_tmp->longitude = atof(cdatastr); + } + } + } + + if (in_ChartWork) + { + if (strcmp(el, "Version") == 0) + {//don't really care + } + if (in_Object) + { + if (strcmp(el, "ClassName") == 0) + { +// className = xstrdup(cdatastr); + } + else if (strcmp(el, "Attr") == 0) + { + //getAttr(cdatastr, ATTR_OBJECTNAME, &wpt_tmp->shortname, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + //getAttr(cdatastr, ATTR_SHIPNAME, &wpt_tmp->description, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + } + else if (strcmp(el, "NumberOfVertexs") == 0) + { + } + else if (strcmp(el, "Latitude") == 0) + { + wpt_tmp->latitude = atof(cdatastr); + } + else if (strcmp(el, "Longitude") == 0) + { + wpt_tmp->longitude = atof(cdatastr); + } + else if (strcmp(el, "Time") == 0) + { + wpt_tmp->creation_time = atoi(cdatastr); + } + } + } + + //ignore everything else for now.. + memset(cdatastr,0, MY_CBUF); + + if (strcmp(el, "Object") == 0) + { + if (in_Route) + { + waypt_add(wpt_tmp); + } + else if (in_ChartWork) + { + //TODO: not sure how i want to handle this.. + } + in_Object--; + } + else if (strcmp(el, "Route") == 0) + { + in_Route--; + } + else if (strcmp(el, "Chartwork") == 0) + { + in_ChartWork--; + } + xml_free_converted_string(el); +} + +static void +hsa_ndv_cdata(void *dta, const XML_Char *s, int len) +{ + char *estr; + estr = cdatastr + strlen(cdatastr); + memcpy(estr, s, len); +} + +static void +hsa_ndv_rd_init(const char *fname) +{ + fd = gbfopen(fname, "r", MYNAME); + + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ":Cannot create XML parser\n"); + } + + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, hsa_ndv_start, hsa_ndv_end); + cdatastr = xcalloc(MY_CBUF,1); + XML_SetCharacterDataHandler(psr, hsa_ndv_cdata); +} + +static void +hsa_ndv_read(void) +{ + int len; + char buf[MY_CBUF + 1]; + + while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) + { + char *bad; + + buf[len] = '\0'; + if (NULL != strstr(buf, "nver=1")) + {//its the older format, not xml + gbfseek(fd, 0, SEEK_SET); + readVersion4(fd); + break; + } + //grumble - have to remove \x1f's from sirius attributes + bad = buf; + while (NULL != (bad = strchr(bad, '\x1f'))) + { + *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; + } + if (!XML_Parse(psr, buf, len, gbfeof(fd))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + + XML_ParserFree(psr); +} + +#endif + +static void getAttr(const char *data, const char *attr, char **val, char seperator) +{ + char *start; + if ((start = strstr(data, attr)) != NULL) + { + char *end; + int len; + + end = strchr(start, seperator); + if (end == NULL) + { + end = start + strlen(start);//assume we are teh last attr + } + + len = end-start - strlen(attr); + + *val = xcalloc(len+1, 1); + memcpy(*val, start+strlen(attr), len); + (*val)[len] = '\0'; + } + else + { + *val = xcalloc(1, 1); + (*val)[0] = '\0'; + } +} +static void +hsa_ndv_rd_deinit(void) +{ + if ( cdatastr ) { + xfree(cdatastr); + } + gbfclose(fd); +} + +static void +hsa_ndv_wr_init(const char *fname) +{ + ofd = gbfopen(fname, "w", MYNAME); +} + +static void +hsa_ndv_wr_deinit(void) +{ + gbfclose(ofd); +} + +static int legNum = 0; + +static void +hsa_ndv_waypt_pr(const waypoint *waypointp) +{ + + gbfprintf(ofd, "\t\t\n"); + + gbfprintf(ofd, "\t\t\twaypnt\n"); +//ignore these for now, they are s57 specific +// fprintf(ofd, "\t\t\t0\n"); +// fprintf(ofd, "\t\t\t1\n"); +// fprintf(ofd, "\t\t\t1089009023\n"); + gbfprintf(ofd, "\t\t\t\n", routeName, waypointp->shortname, legNum, waypointp->description); + gbfprintf(ofd, "\t\t\t\n", routeName); + gbfprintf(ofd, "\t\t\t1\n"); + gbfprintf(ofd, "\t\t\t%lf\n", waypointp->latitude); + gbfprintf(ofd, "\t\t\t%lf\n", waypointp->longitude); + + gbfprintf(ofd, "\t\t\n"); + + legNum++; +} + +static void +hsa_ndv_write(void) +{ + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\t\n"); + gbfprintf(ofd, "\t\t1.0000000\n"); + gbfprintf(ofd, "\t\tROUTENAME\n"); /*TODO: used filename? */ + gbfprintf(ofd, "\t\t0\n"); + waypt_disp_all(hsa_ndv_waypt_pr); + gbfprintf(ofd, "\t\n"); + +//later we'll import past tracks and chart objects? +// fprintf(ofd, "\t\n"); +// fprintf(ofd, "\t\t1.0000000\n"); +// track_disp_all(hsa_ndv_track_pr); +// fprintf(ofd, "\t\n"); + + + gbfprintf(ofd, "\n"); +} + +ff_vecs_t HsaEndeavourNavigator_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + hsa_ndv_rd_init, + hsa_ndv_wr_init, + hsa_ndv_rd_deinit, + hsa_ndv_wr_deinit, + hsa_ndv_read, + hsa_ndv_write, + NULL, + hsa_ndv_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; + +////////////////////////////////////////////////////////////////////////// +// older style Endeavour route export file +//read DEC2000 NDV export files + +#define EF_RECORD_DELIMTER 0 +#define ED_REC_NAME_SIZE 5 +#define EF_NVER_REC "nver=" +#define EF_LAT_REC "lati=" +#define EF_LONG_REC "long=" +#define EF_TIME_REC "time=" +#define EF_ATTR_REC "attr=" +#define EF_CLNM_REC "clnm=" +#define INVALID_TIME -1L +#define SOUNDARRAY_CHAR 'S' + +static int readRecord(gbfile* pFile, const char* pRecName, char *recData); +static int readPositionRecord(gbfile* pFile, double* lat, double* lng, long* timeStamp); + +static void readVersion4(gbfile* pFile) +{ + while( TRUE ) + { + char recData[256] = {0}; + // get the position + double lat2, lng2 = 0; + + // set the pointer to the time stamp depending + // on whether we have a sounding array or not + long ts1, ts2; + long* pts1 = 0; + long* pts2 = 0; + + int soundArray = FALSE; + int numberOfVerticies = 0; + char className[256]; + char attr[1024]; + int Vertex; + + memset(attr, 0, sizeof(attr)); + + wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1); + wpt_tmp->altitude = unknown_alt; + + // read the first record + if( !readRecord( pFile, EF_NVER_REC, recData) ) + // no first record then finished + break; + + // get the type + sscanf( (const char*)recData, "%d", &numberOfVerticies); + + // do we have a sounding array + if( *((const char *)recData + strlen(recData) - 1) == SOUNDARRAY_CHAR ) + { + soundArray = TRUE; + } + + if( soundArray ) + { + pts1 = &ts1; + pts2 = &ts2; + } + + // go through the vertices + for( Vertex = 0; Vertex < numberOfVerticies; Vertex++) + { + // read vertex position + if( !readPositionRecord( pFile, &lat2, &lng2, pts2) ) { + xfree(wpt_tmp); + return; + } + + wpt_tmp->longitude = lng2; + wpt_tmp->latitude = lat2; + break;//TODO: ignore more points for now + } + + + // read the class name + if( !readRecord( pFile, EF_CLNM_REC, className) ) { + xfree( wpt_tmp ); + return; + } + + // read the attributes name + if( !readRecord( pFile, EF_ATTR_REC, attr) ) { + xfree( wpt_tmp ); + return; + } + getAttr(attr, ATTR_OBJECTNAME, &wpt_tmp->shortname, '\x1f'); + getAttr(attr, ATTR_USRMRK, &wpt_tmp->description, '\x1f'); + + { + char *bad; + //remove \n and \x1f from description data + while (NULL != (bad = strchr(wpt_tmp->description, '\x1f'))) + { + *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; + } + while (NULL != (bad = strchr(wpt_tmp->description, '\n'))) + { + *bad = ' '; + } + while (NULL != (bad = strchr(wpt_tmp->description, '\r'))) + { + *bad = ' '; + } + } + + waypt_add(wpt_tmp); + } + + gbfclose(pFile); + return; +} + +// read a record to a file +static int readRecord(gbfile* pFile, const char* pRecName, char *recData) +{ + // get the rec name + int len; + char recName[ED_REC_NAME_SIZE+1]; + char arrRecData[256]; + + for( len = 0; len < ED_REC_NAME_SIZE; len++) + { + int c = gbfgetc(pFile); + + // if we hit EOF failed + if( c == EOF ) + return FALSE; + + recName[len] = c; + } + + // if the record name is not the reqiured type then error + if( strncmp( recName, pRecName, ED_REC_NAME_SIZE) != 0 ) + return FALSE; + + // get the rec data + for( len = 0; TRUE; len++) + { + int c = gbfgetc( pFile); + + // if we hit EOF failed + if( c == EOF ) + return FALSE; + + // hit end of line + if( c == EF_RECORD_DELIMTER ) + break; + + arrRecData[len] = c; + } + + // get the rec data to a string + strncpy(recData, arrRecData, len); + + return TRUE; +} + +// read position +static int readPositionRecord(gbfile* pFile, double* lat, double* lng, + long* timeStamp) +{ + // read the lat record + char recData[256] = {0}; + + if( !readRecord( pFile, EF_LAT_REC, recData) ) + // no lat record then finished + return FALSE; + + // read the latitude + sscanf( (const char*)recData, "%lf", lat); + + // read the lng record + if( !readRecord( pFile, EF_LONG_REC, recData) ) + // no first record then finished + return FALSE; + + // read the latitude + sscanf( (const char*)recData, "%lf", lng); + + // if we are to read a time record + if( timeStamp ) + { + // read the lng record + if( !readRecord( pFile, EF_TIME_REC, recData) ) + // no first record then finished + return FALSE; + + // read the latitude + sscanf( (const char*)recData, "%ld", timeStamp); + } + + return TRUE; +} diff --git a/html.c b/html.c new file mode 100644 index 000000000..3b2ac1329 --- /dev/null +++ b/html.c @@ -0,0 +1,295 @@ +/* + Output only format for Human Readable formats. + + Copyright (C) 2004 Scott Brynen, scott (at) brynen.com + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include "defs.h" +#include "jeeps/gpsmath.h" +#include + +static gbfile *file_out; +static short_handle mkshort_handle; + +static char *stylesheet = NULL; +static char *html_encrypt = NULL; +static char *includelogs = NULL; +static char *degformat = NULL; +static char *altunits = NULL; + +#define MYNAME "HTML" + +static +arglist_t html_args[] = { + { "stylesheet", &stylesheet, + "Path to HTML style sheet", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "encrypt", &html_encrypt, + "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + { "logs", &includelogs, + "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + { "degformat", °format, + "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX }, + { "altunits", &altunits, + "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + + + +static void +wr_init(const char *fname) +{ + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); +} + +static void +html_disp(const waypoint *wpt) +{ + char tbuf[1024]; + char *cout; + time_t tm = wpt->creation_time; + gbint32 utmz; + double utme, utmn; + char utmzc; + fs_xml *fs_gpx = NULL; + + + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + + if (tm == 0) + tm = time(NULL); + strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); + + + gbfprintf(file_out, "\n
\n", wpt->shortname); + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + + gbfprintf (file_out, "\n"); + + + gbfprintf(file_out, "

%s - ",(global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname); + cout = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 1); + gbfprintf(file_out, "%s (%d%c %6.0f %7.0f)", cout, utmz, utmzc, utme, utmn); + xfree (cout); + if (wpt->altitude != unknown_alt) + gbfprintf (file_out, " alt:%d", (int) ( (altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude) ); + gbfprintf (file_out, "
\n"); + if (strcmp(wpt->description, wpt->shortname)) { + if (wpt->url) { + char *d = html_entitize(wpt->description); + gbfprintf(file_out, "%s", wpt->url, d); + xfree(d); + } + else { + gbfprintf(file_out, "%s", wpt->description); + } + if (wpt->gc_data.placer) { + gbfprintf(file_out, " by %s", wpt->gc_data.placer); + } + } + gbfprintf(file_out, "

"); + if (wpt->gc_data.terr) { + gbfprintf (file_out, "

%d%s / %d%s
\n", + (int)(wpt->gc_data.diff / 10), (wpt->gc_data.diff%10)?"½":"", + (int)(wpt->gc_data.terr / 10), (wpt->gc_data.terr%10)?"½":"" ); + gbfprintf(file_out, "%s / %s

", + gs_get_cachetype(wpt->gc_data.type), + gs_get_container(wpt->gc_data.container)); + } + gbfprintf(file_out, "
"); + if (wpt->gc_data.desc_short.utfstring) { + char *tmpstr = strip_nastyhtml(wpt->gc_data.desc_short.utfstring); + gbfprintf (file_out, "

%s

\n", tmpstr ); + xfree( tmpstr ); + } + if (wpt->gc_data.desc_long.utfstring) { + char *tmpstr = strip_nastyhtml(wpt->gc_data.desc_long.utfstring); + gbfprintf (file_out, "

%s

\n", tmpstr ); + xfree( tmpstr ); + } + if (wpt->gc_data.hint) { + char *hint = NULL; + if ( html_encrypt ) + hint = rot13( wpt->gc_data.hint ); + else + hint = xstrdup( wpt->gc_data.hint ); + gbfprintf (file_out, "

Hint: %s

\n", hint); + xfree( hint ); + } + else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { + gbfprintf (file_out, "

%s

\n", wpt->notes); + } + + fs_gpx = NULL; + if ( includelogs ) { + fs_gpx = (fs_xml *)fs_chain_find( wpt->fs, FS_GPX); + } + + if ( fs_gpx && fs_gpx->tag ) { + xml_tag *root = fs_gpx->tag; + xml_tag *curlog = NULL; + xml_tag *logpart = NULL; + curlog = xml_findfirst( root, "groundspeak:log" ); + while ( curlog ) { + time_t logtime = 0; + struct tm *logtm = NULL; + gbfprintf( file_out, "

\n" ); + + logpart = xml_findfirst( curlog, "groundspeak:type" ); + if ( logpart ) { + gbfprintf( file_out, "%s by ", logpart->cdata ); + } + + logpart = xml_findfirst( curlog, "groundspeak:finder" ); + if ( logpart ) { + char *f = html_entitize( logpart->cdata ); + gbfprintf( file_out, "%s on ", f ); + xfree( f ); + } + + logpart = xml_findfirst( curlog, "groundspeak:date" ); + if ( logpart ) { + logtime = xml_parse_time( logpart->cdata, NULL); + logtm = localtime( &logtime ); + if ( logtm ) { + gbfprintf( file_out, + "%04d-%02d-%02d
\n", + logtm->tm_year+1900, + logtm->tm_mon+1, + logtm->tm_mday ); + } + } + + logpart = xml_findfirst( curlog, "groundspeak:log_wpt" ); + if ( logpart ) { + char *coordstr = NULL; + float lat = 0; + float lon = 0; + coordstr = xml_attribute( logpart, "lat" ); + if ( coordstr ) { + lat = atof( coordstr ); + } + coordstr = xml_attribute( logpart, "lon" ); + if ( coordstr ) { + lon = atof( coordstr ); + } + coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 1); + gbfprintf( file_out, + "%s
\n", + coordstr ); + xfree(coordstr); + } + + logpart = xml_findfirst( curlog, "groundspeak:text" ); + if ( logpart ) { + char *encstr = NULL; + char *s = NULL; + char *t = NULL; + int encoded = 0; + encstr = xml_attribute( logpart, "encoded" ); + encoded = (encstr[0] != 'F'); + + if ( html_encrypt && encoded ) { + s = rot13( logpart->cdata ); + } + else { + s = xstrdup( logpart->cdata ); + } + + t = html_entitize( s ); + gbfprintf( file_out, "%s", t ); + xfree( t ); + xfree( s ); + } + + gbfprintf( file_out, "

\n" ); + curlog = xml_findnext( root, curlog, "groundspeak:log" ); + } + } + gbfprintf(file_out, "
\n"); +} + +static void +html_index(const waypoint *wpt) +{ + char *sn = html_entitize(wpt->shortname); + char *d = html_entitize(wpt->description); + + gbfprintf(file_out, "%s - %s
\n", sn, sn, d); + + xfree(sn); + xfree(d); +} + +static void +data_write(void) +{ + setshort_length(mkshort_handle, 6); + + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + gbfprintf(file_out, " \n"); + gbfprintf(file_out, " \n", gpsbabel_version); + gbfprintf(file_out, " GPSBabel HTML Output\n"); + if (stylesheet) + gbfprintf(file_out, " \n", stylesheet); + else { + gbfprintf(file_out, " \n"); + } + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + + gbfprintf(file_out, "

\n"); + waypt_disp_all(html_index); + gbfprintf(file_out, "

\n"); + + waypt_disp_all(html_disp); + + gbfprintf(file_out, ""); + gbfprintf(file_out, ""); + +} + + +ff_vecs_t html_vecs = { + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none }, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + html_args, + CET_CHARSET_UTF8, 0 /* CET-REVIEW */ +}; diff --git a/igc.c b/igc.c new file mode 100644 index 000000000..94d50d0d7 --- /dev/null +++ b/igc.c @@ -0,0 +1,908 @@ +/* + * FAI/IGC data format translation. + * + * Refer to Appendix 1 of + * http://www.fai.org:81/gliding/gnss/tech_spec_gnss.asp for the + * specification of the IGC data format. This translation code was + * written when the latest ammendment list for the specification was AL6. + * + * Copyright (C) 2004 Chris Jones + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include "defs.h" +#include + +static gbfile *file_in, *file_out; +static char manufacturer[4]; +static const route_head *head; +static char *timeadj = NULL; + +#define MYNAME "IGC" +#define MAXRECLEN 79 // Includes null terminator and CR/LF +#define MAXDESCLEN 1024 +#define PRESTRKNAME "PRESALTTRK" +#define GNSSTRKNAME "GNSSALTTRK" +#define HDRMAGIC "IGCHDRS" +#define HDRDELIM "~" +#define DATEMAGIC "IGCDATE" + +/* + * IGC record types. + * These appear as the first char in each record. + */ +typedef enum { + rec_manuf_id = 'A', // FR manufacturer and identification + rec_fix = 'B', // Fix + rec_task = 'C', // Task/declaration + rec_diff_gps = 'D', // Differential GPS + rec_event = 'E', // Event + rec_constel = 'F', // Constellation + rec_security = 'G', // Security + rec_header = 'H', // File header + rec_fix_defn = 'I', // List of extension data included at end of each fix (B) record + rec_extn_defn = 'J', // List of data included in each extension (K) record + rec_extn_data = 'K', // Extension data + rec_log_book = 'L', // Logbook/comments + + // M..Z are spare + + rec_none = 0, // No record + rec_bad = 1, // Bad record +} igc_rec_type_t; + +/* + * See if two lat/lon pairs are approximately equal. + * @param lat1 The latitude of coordinate pair 1 + * @param lon1 The longitude of coordinate pair 1 + * @param lat2 The latitude of coordinate pair 2 + * @param lon2 The longitude of coordinate pair 2 + * @retval 1 The coordinates are approximately equal + * @retval 0 The coordinates are significantly different + */ +static unsigned char coords_match(double lat1, double lon1, double lat2, double lon2) +{ + return (fabs(lat1 - lat2) < 0.0001 && fabs(lon1 - lon2) < 0.0001) ? 1 : 0; +} + +/************************************************************************************************* + * Input file processing + */ + +/* + * Get an IGC record from the input file + * @param rec Caller allocated storage for the record. At least MAXRECLEN chars must be allocated. + * @return the record type. rec_none on EOF, rec_bad on fgets() or parse error. + */ +static igc_rec_type_t get_record(char **rec) +{ + size_t len; + char *c; +retry: + *rec = c = gbfgetstr(file_in); + if (c == NULL) return rec_none; + + len = strlen(c); + + /* Trackwiev writes (bogus) blank links between each record */ + if (len == 0) goto retry; + + if (len < 3 || c[0] < 'A' || c[0] > 'Z') { + warning(MYNAME " bad input record: '%s'\n", c); + return rec_bad; + } + return (igc_rec_type_t) c[0]; +} + +static void rd_init(const char *fname) +{ + char *ibuf; + + file_in = gbfopen(fname, "r", MYNAME); + + // File must begin with a manufacturer/ID record + if (get_record(&ibuf) != rec_manuf_id || sscanf(ibuf, "A%3[A-Z]", manufacturer) != 1) { + fatal(MYNAME ": %s is not an IGC file\n", fname); + } +} + +static void rd_deinit(void) +{ + gbfclose(file_in); +} + +/** + * Handle pre- or post-flight task declarations. + * A route is created for each set of waypoints in a task declaration. + * @param rec A single task record + */ +static void igc_task_rec(const char *rec) +{ + static char flight_date[7]; + static unsigned int num_tp, tp_ct; + static route_head *rte_head; + static time_t creation; + + char task_num[5]; + char task_desc[MAXRECLEN]; + waypoint *wpt; + unsigned int lat_deg, lat_min, lat_frac; + unsigned int lon_deg, lon_min, lon_frac; + char lat_hemi[2], lon_hemi[2]; + char short_name[8]; + char tmp_str[MAXRECLEN]; + struct tm tm; + + static enum { id, takeoff, start, turnpoint, finish, landing } state = id; + + // First task record identifies the task to follow + if (id == state) { + task_desc[0] = '\0'; + if (sscanf(rec, "C%2u%2u%2u%2u%2u%2u%6[0-9]%4c%2u%[^\r]\r\n", + &tm.tm_mday, &tm.tm_mon, &tm.tm_year, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec, + flight_date, task_num, &num_tp, task_desc) < 9) { + fatal(MYNAME ": task id (C) record parse error\n'%s'", rec); + } + task_num[4] = '\0'; + tm.tm_mon -= 1; + if (tm.tm_year < 70) { + tm.tm_year += 100; + } + tm.tm_isdst = 0; + creation = mkgmtime(&tm); + + // Create a route to store the task data in. + rte_head = route_head_alloc(); + rte_head->rte_name = xstrdup(task_num); + sprintf(tmp_str, DATEMAGIC "%s: %s", flight_date, task_desc); + rte_head->rte_desc = xstrdup(tmp_str); + route_add_head(rte_head); + state++; + return; + } + // Get the waypoint + tmp_str[0] = '\0'; + if (sscanf(rec, "C%2u%2u%3u%1[NS]%3u%2u%3u%1[WE]%[^\r]\r\n", + &lat_deg, &lat_min, &lat_frac, lat_hemi, + &lon_deg, &lon_min, &lon_frac, lon_hemi, tmp_str) < 8) { + fatal(MYNAME ": task waypoint (C) record parse error\n%s", rec); + } + + wpt = waypt_new(); + wpt->latitude = ('N' == lat_hemi[0] ? 1 : -1) * + (lat_deg + (lat_min * 1000 + lat_frac) / 1000.0 / 60); + + wpt->longitude = ('E' == lon_hemi[0] ? 1 : -1) * + (lon_deg + (lon_min * 1000 + lon_frac) / 1000.0 / 60); + + wpt->creation_time = creation; + wpt->description = xstrdup(tmp_str); + + // Name the waypoint according to the order of the task record + switch (state) { + case takeoff: + snprintf(short_name, 8, "TAKEOFF"); + state++; + break; + + case start: + snprintf(short_name, 8, "START"); + tp_ct = 0; + state++; + break; + + case turnpoint: + if (++tp_ct == num_tp) { + state++; + } + snprintf(short_name, 8, "TURN%02u", tp_ct); + break; + + case finish: + snprintf(short_name, 8, "FINISH"); + state++; + break; + + case landing: + snprintf(short_name, 8, "LANDING"); + state = id; + break; + + default: + fatal(MYNAME ": task id (C) record internal error\n%s", rec); + break; + } + + // Zero lat and lon indicates an unknown waypoint + if (coords_match(wpt->latitude, wpt->longitude, 0.0, 0.0)) { + waypt_free(wpt); + return; + } + wpt->shortname = xstrdup(short_name); + route_add_wpt(rte_head, wpt); +} + +static void data_read(void) +{ + char *ibuf; + igc_rec_type_t rec_type; + unsigned int hours, mins, secs; + unsigned int lat_deg, lat_min, lat_frac; + unsigned int lon_deg, lon_min, lon_frac; + char lat_hemi[2], lon_hemi[2]; + char validity; + route_head *pres_head = NULL; + route_head *gnss_head = NULL; + int pres_alt, gnss_alt; + char pres_valid = 0; + char gnss_valid = 0; + waypoint *pres_wpt = NULL; + waypoint *gnss_wpt = NULL; + time_t date = 0; + time_t prev_tod = 0; + time_t tod; + struct tm tm; + char tmp_str[20]; + char *hdr_data; + size_t remain; + char trk_desc[MAXDESCLEN + 1]; + + strcpy(trk_desc, HDRMAGIC HDRDELIM); + + while (1) { + rec_type = get_record(&ibuf); + switch (rec_type) { + case rec_manuf_id: + // Manufacturer/ID record already found in rd_init(). + warning(MYNAME ": duplicate manufacturer/ID record\n"); + break; + + case rec_header: + // Get the header sub type + if (sscanf(ibuf, "H%*1[FOP]%3s", tmp_str) != 1) { + fatal(MYNAME ": header (H) record parse error\n%s\n%s\n", ibuf, tmp_str); + } + // Optional long name of record sub type is followed by a + // colon. Actual header data follows that. + if (NULL == (hdr_data = strchr(ibuf, ':'))) { + hdr_data = ibuf + 5; + } else { + hdr_data++; + } + + // Date sub type + if (strcmp(tmp_str, "DTE") == 0) { + if (sscanf(hdr_data, "%2u%2u%2u", &tm.tm_mday, &tm.tm_mon, &tm.tm_year) != 3) { + fatal(MYNAME ": date (H) record parse error\n'%s'\n", ibuf); + } + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + tm.tm_mon -= 1; + if (tm.tm_year < 70) { + tm.tm_year += 100; + } + tm.tm_isdst = 0; + date = mkgmtime(&tm); + } else { + // Store other header data in the track descriptions + if (strlen(trk_desc) < MAXDESCLEN) { + strcat(ibuf, HDRDELIM); + remain = MAXDESCLEN - strlen(trk_desc); + strncat(trk_desc, ibuf, remain); + } + } + break; + + case rec_fix: + // Date must appear in file before the first fix record + if (date < 1000000L) { + fatal(MYNAME ": bad date %d\n", (int)date); + } + // Create a track for pressure altitude waypoints + if (!pres_head) { + pres_head = route_head_alloc(); + pres_head->rte_name = xstrdup(PRESTRKNAME); + pres_head->rte_desc = xstrdup(trk_desc); + track_add_head(pres_head); + } + // Create a second track for GNSS altitude waypoints + if (!gnss_head) { + gnss_head = route_head_alloc(); + gnss_head->rte_name = xstrdup(GNSSTRKNAME); + gnss_head->rte_desc = xstrdup(trk_desc); + track_add_head(gnss_head); + } + // Create a waypoint from the fix record data + if (sscanf(ibuf, + "B%2u%2u%2u%2u%2u%3u%1[NS]%3u%2u%3u%1[WE]%c%5d%5d", + &hours, &mins, &secs, &lat_deg, &lat_min, &lat_frac, + lat_hemi, &lon_deg, &lon_min, &lon_frac, lon_hemi, + &validity, &pres_alt, &gnss_alt) != 14) { + fatal(MYNAME ": fix (B) record parse error\n%s\n", ibuf); + } + pres_wpt = waypt_new(); + + pres_wpt->latitude = ('N' == lat_hemi[0] ? 1 : -1) * + (lat_deg + (lat_min * 1000 + lat_frac) / 1000.0 / 60); + + pres_wpt->longitude = ('E' == lon_hemi[0] ? 1 : -1) * + (lon_deg + (lon_min * 1000 + lon_frac) / 1000.0 / 60); + + // Increment date if we pass midnight UTC + tod = (hours * 60 + mins) * 60 + secs; + if (tod < prev_tod) { + date += 24 * 60 * 60; + } + prev_tod = tod; + pres_wpt->creation_time = date + tod; + + // Add the waypoint to the pressure altitude track + if (pres_alt) { + pres_valid = 1; + pres_wpt->altitude = pres_alt; + } else { + pres_wpt->altitude = unknown_alt; + } + track_add_wpt(pres_head, pres_wpt); + + // Add the same waypoint with GNSS altitude to the second + // track + gnss_wpt = waypt_dupe(pres_wpt); + + if (gnss_alt) { + gnss_valid = 1; + gnss_wpt->altitude = gnss_alt; + } else { + gnss_wpt->altitude = unknown_alt; + } + track_add_wpt(gnss_head, gnss_wpt); + break; + + case rec_task: + // Create a route for each pre-flight declaration + igc_task_rec(ibuf); + break; + + case rec_log_book: + // Get the log book sub type + if (sscanf(ibuf, "L%3s", tmp_str) != 1) { + fatal(MYNAME ": log book (L) record parse error\n'%s'\n", ibuf); + } + + if (strcmp(tmp_str, "PFC") == 0) { + // Create a route for each post-flight declaration + igc_task_rec(ibuf + 4); + break; + } else if (global_opts.debug_level) { + if (strcmp(tmp_str, "OOI") == 0) { + fputs(MYNAME ": Observer Input> ", stdout); + } else if (strcmp(tmp_str, "PLT") == 0) { + fputs(MYNAME ": Pilot Input> ", stdout); + } else if (strcmp(tmp_str, manufacturer) == 0) { + fputs(MYNAME ": Manufacturer Input> ", stdout); + } else { + fputs(MYNAME ": Anonymous Input> ", stdout); + fputs(ibuf + 1, stdout); + break; + } + fputs(ibuf + 4, stdout); + putchar('\n'); + } + break; + + // These record types are discarded + case rec_diff_gps: + case rec_event: + case rec_constel: + case rec_security: + case rec_fix_defn: + case rec_extn_defn: + case rec_extn_data: + break; + + // No more records + case rec_none: + + // Include pressure altitude track only if it has useful + // altitude data or if it is the only track available. + if (pres_head && !pres_valid && gnss_head) { + track_del_head(pres_head); + pres_head = NULL; + } + // Include GNSS altitude track only if it has useful altitude + // data or if it is the only track available. + if (gnss_head && !gnss_valid && pres_head) { + track_del_head(gnss_head); + } + return; // All done so bail + + default: + case rec_bad: + fatal(MYNAME ": failure reading file\n"); + break; + } + } +} + +/************************************************************************************************* + * Output file processing + */ + +/************************************************* + * Callbacks used to scan for specific track types + */ + +static void detect_pres_track(const route_head * rh) +{ + if (rh->rte_name && strncmp(rh->rte_name, PRESTRKNAME, 6) == 0) { + head = rh; + } +} + +static void detect_gnss_track(const route_head * rh) +{ + if (rh->rte_name && strncmp(rh->rte_name, GNSSTRKNAME, 6) == 0) { + head = rh; + } +} + +static void detect_other_track(const route_head * rh) +{ + static int max_waypt_ct; + + if (!head) { + max_waypt_ct = 0; + } + // Find other track with the most waypoints + if (rh->rte_waypt_ct > max_waypt_ct && + (!rh->rte_name || + (strncmp(rh->rte_name, PRESTRKNAME, 6) != 0 && + strncmp(rh->rte_name, GNSSTRKNAME, 6) != 0))) { + head = rh; + max_waypt_ct = rh->rte_waypt_ct; + } +} + +/* + * Identify the pressure altitude and GNSS altitude tracks. + * @param pres_track Set by the function to the pressure altitude track + * head. NULL if not found. + * @param gnss_track Set by the function to the GNSS altitude track + * head. NULL if not found. + */ +static void get_tracks(const route_head ** pres_track, const route_head ** gnss_track) +{ + head = NULL; + track_disp_all(detect_pres_track, NULL, NULL); + *pres_track = head; + + head = NULL; + track_disp_all(detect_gnss_track, NULL, NULL); + *gnss_track = head; + + head = NULL; + track_disp_all(detect_other_track, NULL, NULL); + + if (!*pres_track && *gnss_track && head) { + *pres_track = head; + } + + if (!*gnss_track && head) { + *gnss_track = head; + } +} + +/************************************************* + * IGC string formatting functions + */ + +static char *latlon2str(const waypoint * wpt) +{ + static char str[18] = ""; + char lat_hemi = wpt->latitude < 0 ? 'S' : 'N'; + char lon_hemi = wpt->longitude < 0 ? 'W' : 'E'; + unsigned char lat_deg = fabs(wpt->latitude); + unsigned char lon_deg = fabs(wpt->longitude); + unsigned int lat_min = (fabs(wpt->latitude) - lat_deg) * 60000 + 0.500000000001; + unsigned int lon_min = (fabs(wpt->longitude) - lon_deg) * 60000 + 0.500000000001; + + if (snprintf(str, 18, "%02u%05u%c%03u%05u%c", + lat_deg, lat_min, lat_hemi, lon_deg, lon_min, lon_hemi) != 17) { + fatal(MYNAME ": Bad waypoint format '%s'\n", str); + } + return str; +} + +static char *date2str(struct tm *dt) +{ + static char str[7] = ""; + + if (snprintf(str, 7, "%02u%02u%02u", dt->tm_mday, dt->tm_mon + 1, dt->tm_year % 100) != 6) { + fatal(MYNAME ": Bad date format '%s'\n", str); + } + return str; +} + +static char *tod2str(struct tm *tod) +{ + static char str[7] = ""; + + if (snprintf(str, 7, "%02u%02u%02u", tod->tm_hour, tod->tm_min, tod->tm_sec) != 6) { + fatal(MYNAME ": Bad time of day format '%s'\n", str); + } + return str; +} + +/* + * Write header records + */ +static void wr_header(void) +{ + const route_head *pres_track; + const route_head *track; + struct tm *tm; + time_t date; + static const char dflt_str[] = "Unknown"; + const char *str; + waypoint *wpt; + + get_tracks(&pres_track, &track); + if (!track && pres_track) { + track = pres_track; + } + // Date in header record is that of the first fix record + date = !track ? current_time() : + ((waypoint *) QUEUE_FIRST(&track->waypoint_list))->creation_time; + + if (NULL == (tm = gmtime(&date))) { + fatal(MYNAME ": Bad track timestamp\n"); + } + gbfprintf(file_out, "HFDTE%s\r\n", date2str(tm)); + + // Other header data may have been stored in track description + if (track && track->rte_desc && strncmp(track->rte_desc, HDRMAGIC, strlen(HDRMAGIC)) == 0) { + for (str = strtok(track->rte_desc + strlen(HDRMAGIC) + strlen(HDRDELIM), HDRDELIM); + str; str = strtok(NULL, HDRDELIM)) { + gbfprintf(file_out, "%s\r\n", str); + } + } else { + // IGC header info not found so synthesise it. + // If a waypoint is supplied with a short name of "PILOT", use + // its description as the pilot's name in the header. + str = dflt_str; + if (NULL != (wpt = find_waypt_by_name("PILOT")) && wpt->description) { + str = wpt->description; + } + gbfprintf(file_out, "HFPLTPILOT:%s\r\n", str); + } +} + +/************************************************* + * Generation of IGC task declaration records + */ + +static void wr_task_wpt_name(const waypoint * wpt, const char *alt_name) +{ + gbfprintf(file_out, "C%s%s\r\n", latlon2str(wpt), + wpt->description ? wpt->description : wpt->shortname ? wpt->shortname : alt_name); +} + +static void wr_task_hdr(const route_head * rte) +{ + unsigned char have_takeoff = 0; + const waypoint *wpt; + char flight_date[7] = "000000"; + char task_desc[MAXRECLEN] = ""; + int num_tps = rte->rte_waypt_ct - 2; + struct tm *tm; + time_t rte_time; + static unsigned int task_num = 1; + + if (num_tps < 0) { + fatal(MYNAME ": Empty task route\n"); + } + // See if the takeoff and landing waypoints are there or if we need to + // generate them. + wpt = (waypoint *) QUEUE_LAST(&rte->waypoint_list); + if (wpt->shortname && strncmp(wpt->shortname, "LANDING", 6) == 0) { + num_tps--; + } + wpt = (waypoint *) QUEUE_FIRST(&rte->waypoint_list); + if (wpt->shortname && strncmp(wpt->shortname, "TAKEOFF", 6) == 0) { + have_takeoff = 1; + num_tps--; + } + if (num_tps < 0) { + fatal(MYNAME ": Too few waypoints in task route\n"); + } + else if (num_tps > 99) { + fatal(MYNAME ": Too much waypoints (more than 99) in task route.\n"); + } + // Gather data to write to the task identification (first) record + rte_time = wpt->creation_time ? wpt->creation_time : current_time(); + if (NULL == (tm = gmtime(&rte_time))) { + fatal(MYNAME ": Bad task route timestamp\n"); + } + + if (rte->rte_desc) { + sscanf(rte->rte_desc, DATEMAGIC "%6[0-9]: %s", flight_date, task_desc); + } + + gbfprintf(file_out, "C%s%s%s%04u%02u%s\r\n", date2str(tm), + tod2str(tm), flight_date, task_num++, num_tps, task_desc); + + if (!have_takeoff) { + // Generate the takeoff waypoint + wr_task_wpt_name(wpt, "TAKEOFF"); + } +} + +static void wr_task_wpt(const waypoint * wpt) +{ + wr_task_wpt_name(wpt, ""); +} + +static void wr_task_tlr(const route_head * rte) +{ + // If the landing waypoint is not supplied we need to generate it. + const waypoint *wpt = (waypoint *) QUEUE_LAST(&rte->waypoint_list); + if (!wpt->shortname || strncmp(wpt->shortname, "LANDIN", 6) != 0) { + wr_task_wpt_name(wpt, "LANDING"); + } +} + +static void wr_tasks(void) +{ + route_disp_all(wr_task_hdr, wr_task_tlr, wr_task_wpt); +} + +/* + * Write a single fix record + */ +static void wr_fix_record(const waypoint * wpt, int pres_alt, int gnss_alt) +{ + struct tm *tm; + + if (NULL == (tm = gmtime(&wpt->creation_time))) { + fatal(MYNAME ": bad track timestamp\n"); + } + + if (unknown_alt == pres_alt) { + pres_alt = 0; + } + if (unknown_alt == gnss_alt) { + gnss_alt = 0; + } + gbfprintf(file_out, "B%02u%02u%02u%sA%05d%05d\r\n", tm->tm_hour, + tm->tm_min, tm->tm_sec, latlon2str(wpt), pres_alt, gnss_alt); +} + +/** + * Attempt to align the pressure and GNSS tracks in time. + * This is useful when trying to merge a track (lat/lon/time) recorded by a + * GPS with a barograph (alt/time) recorded by a seperate instrument with + * independent clocks which are not closely synchronised. + * @return The number of seconds to add to the GNSS track in order to align + * it with the pressure track. + */ +static int correlate_tracks(const route_head * pres_track, const route_head * gnss_track) +{ + const queue *elem; + double last_alt, alt_diff; + double speed; + time_t pres_time, gnss_time; + int time_diff; + const waypoint *wpt; + + // Deduce the landing time from the pressure altitude track based on + // when we last descended to within 10m of the final track altitude. + elem = QUEUE_LAST(&pres_track->waypoint_list); + last_alt = ((waypoint *) elem)->altitude; + do { + elem = elem->prev; + if (&pres_track->waypoint_list == elem) { + // No track left + return 0; + } + alt_diff = last_alt - ((waypoint *) elem)->altitude; + if (alt_diff > 10.0) { + // Last part of track was ascending + return 0; + } + } while (alt_diff > -10.0); + pres_time = ((waypoint *) elem->next)->creation_time; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": pressure landing time %s", ctime(&pres_time)); + } + // Deduce the landing time from the GNSS altitude track based on + // when the groundspeed last dropped below a certain level. + elem = QUEUE_LAST(&gnss_track->waypoint_list); + last_alt = ((waypoint *) elem)->altitude; + do { + wpt = (waypoint *) elem; + elem = elem->prev; + if (&gnss_track->waypoint_list == elem) { + // No track left + return 0; + } + // Get a crude indication of groundspeed from the change in lat/lon + time_diff = wpt->creation_time - ((waypoint *) elem)->creation_time; + speed = !time_diff ? 0 : + (fabs(wpt->latitude - ((waypoint *) elem)->latitude) + + fabs(wpt->longitude - ((waypoint *) elem)->longitude)) / time_diff; + if (global_opts.debug_level >= 2) { + printf(MYNAME ": speed=%f\n", speed); + } + } while (speed < 0.00003); + gnss_time = ((waypoint *) elem->next)->creation_time; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": gnss landing time %s", ctime(&gnss_time)); + } + // Time adjustment is difference between the two estimated landing times + if (15 * 60 < abs(time_diff = pres_time - gnss_time)) { + warning(MYNAME ": excessive time adjustment %ds\n", time_diff); + } + return time_diff; +} + +/** + * Interpolate altitude from a track at a given time. + * @param track The track containing altitude data. + * @param time The time that we are interested in. + * @return The altitude interpolated from the track. + */ +static double interpolate_alt(const route_head * track, time_t time) +{ + static const queue *prev_elem = NULL; + static const queue *curr_elem = NULL; + const waypoint *prev_wpt; + const waypoint *curr_wpt; + int time_diff; + double alt_diff; + + // Start search at the beginning of the track + if (!prev_elem) { + curr_elem = prev_elem = QUEUE_FIRST(&track->waypoint_list); + } + // Find the track points either side of the requested time + while (((waypoint *) curr_elem)->creation_time < time) { + if (QUEUE_LAST(&track->waypoint_list) == curr_elem) { + // Requested time later than all track points, we can't interpolate + return unknown_alt; + } + prev_elem = curr_elem; + curr_elem = QUEUE_NEXT(prev_elem); + } + + prev_wpt = (waypoint *) prev_elem; + curr_wpt = (waypoint *) curr_elem; + + if (QUEUE_FIRST(&track->waypoint_list) == curr_elem) { + if (curr_wpt->creation_time == time) { + // First point's creation time is an exact match so use it's altitude + return curr_wpt->altitude; + } else { + // Requested time is prior to any track points, we can't interpolate + return unknown_alt; + } + } + // Interpolate + if (0 == (time_diff = curr_wpt->creation_time - prev_wpt->creation_time)) { + // Avoid divide by zero + return curr_wpt->altitude; + } + alt_diff = curr_wpt->altitude - prev_wpt->altitude; + return prev_wpt->altitude + (alt_diff / time_diff) * (time - prev_wpt->creation_time); +} + +/* + * Pressure altitude and GNSS altitude may be provided in two seperate + * tracks. This function attempts to merge them into one. + */ +static void wr_track(void) +{ + const route_head *pres_track; + const route_head *gnss_track; + const waypoint *wpt; + const queue *elem; + const queue *tmp; + int time_adj; + double pres_alt; + + // Find pressure altitude and GNSS altitude tracks + get_tracks(&pres_track, &gnss_track); + + // If both found, attempt to merge them + if (pres_track && gnss_track) { + if (timeadj) { + if (strcmp(timeadj, "auto") == 0) { + time_adj = correlate_tracks(pres_track, gnss_track); + } else if (sscanf(timeadj, "%d", &time_adj) != 1) { + fatal(MYNAME ": bad timeadj argument '%s'\n", timeadj); + } + } else { + time_adj = 0; + } + if (global_opts.debug_level >= 1) { + printf(MYNAME ": adjusting time by %ds\n", time_adj); + } + // Iterate through waypoints in both tracks simultaneously + QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) { + wpt = (waypoint *) elem; + pres_alt = interpolate_alt(pres_track, wpt->creation_time + time_adj); + wr_fix_record(wpt, (int) pres_alt, (int) wpt->altitude); + } + } else { + if (pres_track) { + // Only the pressure altitude track was found so generate fix + // records from it alone. + QUEUE_FOR_EACH(&pres_track->waypoint_list, elem, tmp) { + wr_fix_record((waypoint *) elem, (int) ((waypoint *) elem)->altitude, (int) unknown_alt); + } + } else if (gnss_track) { + // Only the GNSS altitude track was found so generate fix + // records from it alone. + QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) { + wr_fix_record((waypoint *) elem, (int) unknown_alt, (int) ((waypoint *) elem)->altitude); + } + } else { + // No tracks found so nothing to do + return; + } + } +} + +static void wr_init(const char *fname) +{ + file_out = gbfopen(fname, "wb", MYNAME); +} + +static void wr_deinit(void) +{ + gbfclose(file_out); +} + +static void data_write(void) +{ + gbfputs("AXXXZZZGPSBabel\r\n", file_out); + wr_header(); + wr_tasks(); + wr_track(); + gbfprintf(file_out, "LXXXGenerated by GPSBabel Version %s\r\n", gpsbabel_version); + gbfputs("GGPSBabelSecurityRecordGuaranteedToFailVALIChecks\r\n", file_out); +} + + +static arglist_t igc_args[] = { + {"timeadj", &timeadj, + "(integer sec or 'auto') Barograph to GPS time diff", + NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +ff_vecs_t igc_vecs = { + ff_type_file, + { ff_cap_none , ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + igc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/ignrando.c b/ignrando.c new file mode 100644 index 000000000..7a76b57bb --- /dev/null +++ b/ignrando.c @@ -0,0 +1,286 @@ +/* + + Support for IGN Rando track files. + + Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include +#include +#include +#include + +#include "defs.h" +#include "xmlgeneric.h" + +#if HAVE_LIBEXPAT +#include +#endif + +#define MYNAME "IGNRando" + +static gbfile *fout; + +static route_head *track; +static waypoint *wpt; +static int track_index; /* index of track we'll write */ +static int track_num; /* current index of track within track_disp_all */ + +static int xmlpoints; + +/* options */ +static char *index_opt = NULL; + +static arglist_t ignr_args[] = +{ + {"index", &index_opt, "Index of track to write (if more the one in source)", NULL, ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + +#if ! HAVE_LIBEXPAT + +static void +ignr_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded \"" MYNAME "\" input support because expat was not installed.\n"); +} + +static void +ignr_read(void) +{ +} + +static void +ignr_rd_deinit(void) +{ +} + +#else + + +static xg_callback ignr_start; +static xg_callback ignr_nb_etapes, ignr_descr; +static xg_callback ignr_etape_begin, ignr_etape_end; +static xg_callback ignr_etape_pos, ignr_etape_alt; + +static +xg_tag_mapping ignr_xml_map[] = +{ + { ignr_start, cb_start, "/RANDONNEE" }, + { ignr_nb_etapes, cb_cdata, "/RANDONNEE/INFORMATIONS/NB_ETAPES" }, + { ignr_descr, cb_cdata, "/RANDONNEE/INFORMATIONS/DESCRIPTION" }, + { ignr_etape_begin, cb_start, "/RANDONNEE/ETAPE" }, + { ignr_etape_end, cb_end, "/RANDONNEE/ETAPE" }, + { ignr_etape_pos, cb_cdata, "/RANDONNEE/ETAPE/POSITION" }, + { ignr_etape_alt, cb_cdata, "/RANDONNEE/ETAPE/ALTITUDE" }, + { NULL, 0, NULL } +}; + +static void +ignr_xml_error(int condition) +{ + if (condition != 0) + fatal(MYNAME ": Error in XML structure!\n"); +} + +/* xmlgeneric callbacks */ + +static xg_callback ignr_start; +static xg_callback ignr_nb_etapes, ignr_descr; +static xg_callback ignr_etape_begin, ignr_etape_end; + +static void +ignr_start(const char *args, const char **attrv) +{ + ignr_xml_error((track != NULL)); + + track = route_head_alloc(); + track_add_head(track); +} + +static void +ignr_nb_etapes(const char *args, const char **attrv) +{ + xmlpoints = atoi(args); +} + +static void +ignr_descr(const char *args, const char **attrv) +{ + ignr_xml_error((track == NULL)); + + if ((args != NULL) && (strlen(args) > 0)) + track->rte_desc = xstrdup(args); +} + +static void +ignr_etape_begin(const char *args, const char **attrv) +{ + ignr_xml_error((wpt != NULL)); + + wpt = waypt_new(); +} + +static void +ignr_etape_end(const char *args, const char **attrv) +{ + ignr_xml_error((track == NULL) || (wpt == NULL)); + + track_add_wpt(track, wpt); + wpt = NULL; +} + +static void +ignr_etape_pos(const char *args, const char **attrv) +{ + ignr_xml_error((wpt == NULL) || (args == NULL)); + + if (2 != sscanf(args, "%lf,%lf", &wpt->latitude, &wpt->longitude)) + fatal(MYNAME ": Invalid coordinates \"%s\"!\n", args); +} + +static void +ignr_etape_alt(const char *args, const char **attrv) +{ + ignr_xml_error((wpt == NULL)); + if (args == NULL) return; + + if (1 != sscanf(args, "%lf", &wpt->altitude)) + fatal(MYNAME ": Invalid altitude \"%s\"!\n", args); +} + +/* callbacks registered in ignr_vecs */ + +static void +ignr_rd_init(const char *fname) +{ + xml_init(fname, ignr_xml_map, NULL); + wpt = NULL; + track = NULL; +} + +static void +ignr_rd_deinit(void) +{ + xml_deinit(); +} + +static void +ignr_read(void) +{ + xml_read(); +} + +#endif + +/* write support */ + +/* callbacks registered in ignr_vecs */ + +static void +ignr_rw_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); +} + +static void +ignr_rw_deinit(void) +{ + gbfclose(fout); +} + +static void +ignr_write_track_hdr(const route_head *track) +{ + track_num++; + + if (track_num != track_index) return; + + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t%d\n", track->rte_waypt_ct); + if (track->rte_desc != NULL) + gbfprintf(fout, "\t\t%s\n", track->rte_desc); + gbfprintf(fout, "\t\n"); +} + +static void +ignr_write_track_trl(const route_head *track) +{ +} + +static void +ignr_write_waypt(const waypoint *wpt) +{ + if (track_num != track_index) return; + + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t%3.6f,%3.6f\n", wpt->latitude, wpt->longitude); + if (wpt->altitude != unknown_alt) + gbfprintf(fout, "\t\t%3.6f\n", wpt->altitude); + gbfprintf(fout, "\t\n"); +} + +static void +ignr_write(void) +{ + time_t now; + struct tm tm; + char buff[32]; + + if (index_opt != NULL) + { + track_index = atoi(index_opt); + if ((track_index < 1) || (track_index > (int) track_count())) + fatal(MYNAME ": Invalid track index %d (we have currently %d track(s))!\n", + track_index, track_count()); + } + else + track_index = 1; + track_num = 0; + + now = current_time(); + tm = *localtime(&now); + + gbfprintf(fout, "\n"); + gbfprintf(fout, "\n"); + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t1.1\n"); + gbfprintf(fout, "\t\tIHA03AA\n"); + + strftime(buff, sizeof(buff), "%d/%m/%Y", &tm); + gbfprintf(fout, "\t\t%s\n", buff); + strftime(buff, sizeof(buff), "%H:%M:%S", &tm); + gbfprintf(fout, "\t\t%s\n", buff); + + gbfprintf(fout, "\t\n"); + track_disp_all(ignr_write_track_hdr, ignr_write_track_trl, ignr_write_waypt); + gbfprintf(fout, "\n"); +} + +ff_vecs_t ignr_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, + ignr_rd_init, + ignr_rw_init, + ignr_rd_deinit, + ignr_rw_deinit, + ignr_read, + ignr_write, + NULL, + ignr_args, + CET_CHARSET_MS_ANSI, 1 +}; diff --git a/ik3d.c b/ik3d.c new file mode 100644 index 000000000..8685886d4 --- /dev/null +++ b/ik3d.c @@ -0,0 +1,196 @@ +/* + + Support for "MagicMaps" project files (.ikt) + + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#include "defs.h" +#include "xmlgeneric.h" + +static arglist_t ikt_args[] = +{ + ARG_TERMINATOR +}; + +#define MYNAME "ikt" + +#if ! HAVE_LIBEXPAT +void +ikt_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded \" MYNAME \" support because expat was not installed.\n"); +} + +void +ikt_read(void) +{ +} + +#else + +static route_head *track; +static waypoint *waypt; +static char *name, *text; + +static xg_callback iktobj_waypt, iktobj_type, iktobj_name, iktobj_trkpt, iktobj_text; + +#define IKTOBJ "/Root/Content/MMGeoObjects/MMGeoObject" + +/* Here we are working with wildcards in the tag list. + Please ensure that the longest entries comes first */ + +static +xg_tag_mapping ikt_map[] = { + { iktobj_trkpt, cb_start, IKTOBJ "_*/PathPoints/Point_*/GeoPosition" }, + { iktobj_type, cb_cdata, IKTOBJ "_*/GeoObjectType" }, + { iktobj_waypt, cb_start, IKTOBJ "_*/GeoPosition" }, + { iktobj_name, cb_cdata, IKTOBJ "_*/Name" }, + { iktobj_text, cb_cdata, IKTOBJ "_*/POIDrawable2D/Text" }, + { NULL, 0, NULL } +}; + +static void +ikt_object_end(void) +{ + if (track) { + track->rte_name = name; + track_add_head(track); + name = NULL; + } + else if (waypt) { + waypt->shortname = name; + waypt->description = text; + waypt_add(waypt); + name = NULL; + text = NULL; + } + if (name) { + xfree(name); + name = NULL; + } + if (text) { + xfree(text); + text = NULL; + } + track = NULL; + waypt = NULL; +} + +static void +iktobj_waypt(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "X") == 0) waypt->longitude = atof(avp[1]); + else if (strcmp(avp[0], "Y") == 0) waypt->latitude = atof(avp[1]); + avp+=2; + } +} + +static void +iktobj_trkpt(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + waypt = waypt_new(); + while (*avp) { + if (strcmp(avp[0], "X") == 0) waypt->longitude = atof(avp[1]); + else if (strcmp(avp[0], "Y") == 0) waypt->latitude = atof(avp[1]); + avp+=2; + } + track_add_wpt(track, waypt); + waypt = NULL; +} + +static void +iktobj_name(const char *args, const char **unused) +{ + name = xstrdup(args); +} + +static void +iktobj_text(const char *args, const char **unused) +{ + text = xstrdup(args); +} + +static void +iktobj_type(const char *args, const char **unused) +{ + ikt_object_end(); + + switch(atoi(args)) { + case 0: + waypt = waypt_new(); + break; + case 1: + track = route_head_alloc(); + break; + default: + fatal(MYNAME ": Unknown object type %s!\n", args); + } +} + +static void +ikt_rd_init(const char *fname) +{ + xml_init(fname, ikt_map, NULL); + + track = NULL; + waypt = NULL; + name = NULL; + text = NULL; +} + +static void +ikt_read(void) +{ + xml_read(); +} + +#endif + +static void +ikt_rd_deinit(void) +{ + ikt_object_end(); + if (name) xfree(name); + if (text) xfree(text); + + xml_deinit(); +} + +ff_vecs_t ik3d_vecs = { + ff_type_file, + { + ff_cap_read, /* waypoints */ + ff_cap_read, /* tracks */ + ff_cap_none /* routes */ + }, + ikt_rd_init, + NULL, + ikt_rd_deinit, + NULL, + ikt_read, + NULL, + NULL, + ikt_args, + CET_CHARSET_UTF8, 1 +}; diff --git a/inifile.c b/inifile.c new file mode 100644 index 000000000..84ef67a79 --- /dev/null +++ b/inifile.c @@ -0,0 +1,361 @@ +/* + Library for inifile like data files. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include +#include +#include +#include + +#include "defs.h" +#include "inifile.h" + +#define MYNAME "inifile" + +typedef struct inifile_entry_s +{ + queue Q; + char *key; + char *val; +} inifile_entry_t; + +typedef struct inifile_section_s +{ + queue Q; + char *name; + int ientries; + queue entries; +} inifile_section_t; + +/* internal procedures */ + +#define START_BUFSIZE 257 +#define DELTA_BUFSIZE 128 + +#define GPSBABEL_INIFILE "gpsbabel.ini" + +/* Remember the filename we used so we can include it in errors. */ +char *gbinipathname; + +static char * +find_gpsbabel_inifile(const char *path) /* can be empty or NULL */ +{ + FILE *test; + char *buff; + int len; + + if (path == NULL) return NULL; + + len = strlen(path); + buff = xmalloc(len + 1 + strlen(GPSBABEL_INIFILE) + 1); + strcpy(buff, path); + if (len > 0) { + char test = buff[len - 1]; +#ifdef __WIN32__ + if ((test != '\\') && (test != ':')) + strcat(buff, "\\"); +#else + if (test != '/') + strcat(buff, "/"); +#endif + } + strcat(buff, GPSBABEL_INIFILE); + test = fopen(buff, "rb"); + if (test) { + fclose(test); + return buff; + } + xfree(buff); + return NULL; +} + +static gbfile * +open_gpsbabel_inifile(void) +{ + char *name; + char *envstr; + gbfile *res = NULL; + + envstr = getenv("GPSBABELINI"); + if (envstr != NULL) { + FILE *test; + + test = fopen(envstr, "r"); + if (test != NULL) { + fclose(test); + return gbfopen(envstr, "r", "GPSBabel"); + } + warning("WARNING: GPSBabel-inifile, defined in environment, NOT found!\n"); + return NULL; + } + name = find_gpsbabel_inifile(""); /* PWD */ + if (name == NULL) { +#ifdef __WIN32__ + name = find_gpsbabel_inifile(getenv("APPDATA")); + if (name == NULL) name = find_gpsbabel_inifile(getenv("WINDIR")); + if (name == NULL) name = find_gpsbabel_inifile(getenv("SYSTEMROOT")); +#else + if ((envstr = getenv("HOME")) != NULL) { + char *path; + + path = xmalloc(strlen(envstr) + 11); + strcpy(path, envstr); + strcat(path, "/.gpsbabel"); + name = find_gpsbabel_inifile(path); + xfree(path); + } + if (name == NULL) name = find_gpsbabel_inifile("/usr/local/etc"); + if (name == NULL) name = find_gpsbabel_inifile("/etc"); +#endif + } + if (name != NULL) { + res = gbfopen(name, "r", "GPSBabel"); + if (gbinipathname) { + xfree(gbinipathname); + } + gbinipathname = name; + } + return res; +} + +static void +inifile_load_file(gbfile *fin, inifile_t *inifile, const char *myname) +{ + char *buf; + inifile_section_t *sec = NULL; + + while ((buf = gbfgetstr(fin))) + { + char *cin = lrtrim(buf); + + if (*cin == '\0') continue; /* skip empty lines */ + if ((*cin == '#') || (*cin == ';')) continue; /* skip comments */ + + if (*cin == '[') + { + + char *cend = strchr(++cin, ']'); + + if (cend != NULL) + { + *cend = '\0'; + cin = lrtrim(cin); + } + if ((*cin == '\0') || (cend == NULL)) + fatal("%s: invalid section header '%s' in '%s'.\n", myname, cin, gbinipathname); + + sec = xcalloc(1, sizeof(*sec)); + + sec->name = xstrdup(cin); + QUEUE_INIT(&sec->entries); + ENQUEUE_TAIL(&inifile->secs, &sec->Q); + inifile->isecs++; + } + else + { + char *cx; + inifile_entry_t *entry; + + if (sec == NULL) + fatal("%s: missing section header in '%s'.\n", myname,gbinipathname); + + entry = xcalloc(1, sizeof(*entry)); + ENQUEUE_TAIL(&sec->entries, &entry->Q); + sec->ientries++; + + cx = strchr(cin, '='); + if (cx != NULL) + { + *cx = '\0'; + cin = lrtrim(cin); + } + + entry->key = xstrdup(cin); + + if (cx != NULL) + { + cx = lrtrim(++cx); + entry->val = xstrdup(cx); + } + else + entry->val = xstrdup(""); + } + } +} + +static char * +inifile_find_value(const inifile_t *inifile, const char *sec_name, const char *key) +{ + queue *elem, *tmp; + + if (inifile == NULL) return NULL; + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) + { + inifile_section_t *sec = (inifile_section_t *) elem; + + if (case_ignore_strcmp(sec->name, sec_name) == 0) + { + queue *elem, *tmp; + + QUEUE_FOR_EACH(&sec->entries, elem, tmp) + { + inifile_entry_t *entry = (inifile_entry_t *) elem; + + if (case_ignore_strcmp(entry->key, key) == 0) + { + return entry->val; + } + } + } + } + return NULL; +} + +/* public procedures */ + +/* + inifile_init: + reads inifile filename into memory + myname represents the calling module + + filename == NULL: try to open global gpsbabel.ini + */ +inifile_t * +inifile_init(const char *filename, const char *myname) +{ + inifile_t *result; + gbfile *fin = NULL; + + if (filename == NULL) { + fin = open_gpsbabel_inifile(); + if (fin == NULL) return NULL; + } + else fin = gbfopen(filename, "rb", myname); + + result = xcalloc(1, sizeof(*result)); + QUEUE_INIT(&result->secs); + inifile_load_file(fin, result, myname); + + gbfclose(fin); + return result; +} + +void +inifile_done(inifile_t *inifile) +{ + if (inifile == NULL) return; + + if (inifile->isecs > 0) + { + queue *elem, *tmp; + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) { + inifile_section_t *sec = (inifile_section_t *) elem; + + if (sec->ientries > 0) { + queue *elem, *tmp; + + QUEUE_FOR_EACH(&sec->entries, elem, tmp) { + inifile_entry_t *entry = (inifile_entry_t *) elem; + + if (entry->key) xfree(entry->key); + if (entry->val) xfree(entry->val); + dequeue(elem); + xfree(entry); + } + } + dequeue(elem); + if (sec->name) xfree(sec->name); + xfree(sec); + } + xfree(inifile); + } + if (gbinipathname) { + xfree(gbinipathname); + gbinipathname = NULL; + } +} + +int +inifile_has_section(const inifile_t *inifile, const char *section) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) + { + inifile_section_t *sec = (inifile_section_t *) elem; + if (case_ignore_strcmp(sec->name, section) == 0) + return 1; + } + return 0; +} + +/* + inifile_readstr: + returns NULL if not found, otherwise a pointer to the value of key ... + all key values are valid entities until "inifile_done" + */ + +char * +inifile_readstr(const inifile_t *inifile, const char *section, const char *key) +{ + return inifile_find_value(inifile, section, key); +} + +/* + inifile_readint: + on success the value is stored into "*value" and "inifile_readint" returns 1, + otherwise inifile_readint returns 0 + */ + +int +inifile_readint(const inifile_t *inifile, const char *section, const char *key, int *value) +{ + char *str; + + str = inifile_find_value(inifile, section, key); + + if (str == NULL) { + return 0; + } + + if (value != NULL) { + *value = atoi(str); + } + return 1; +} + +/* + inifile_readint_def: + if found inifile_readint_def returns value of key, otherwise a default value "def" + */ + +int +inifile_readint_def(const inifile_t *inifile, const char *section, const char *key, const int def) +{ + int result; + + if (inifile_readint(inifile, section, key, &result) == 0) { + return def; + } + else { + return result; + } +} diff --git a/inifile.h b/inifile.h new file mode 100644 index 000000000..560727732 --- /dev/null +++ b/inifile.h @@ -0,0 +1,62 @@ +/* + Library for inifile like data files. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#ifndef HAVE_INIFILE_H +#define HAVE_INIFILE_H + +#include "defs.h" + +typedef struct inifile_s +{ + int isecs; /* number of sections */ + queue secs; /* sections */ +} inifile_t; + +/* + inifile_init: + reads inifile filename into memory + myname represents the calling module + */ +inifile_t * inifile_init(const char *filename, const char *myname); +void inifile_done(inifile_t *inifile); + +int inifile_has_section(const inifile_t *inifile, const char *section); + +/* + inifile_readstr: + returns NULL if not found, otherwise a pointer to the value of key ... + all key values are valid entities until "inifile_done" + */ +char *inifile_readstr(const inifile_t *inifile, const char *section, const char *key); + +/* + inifile_readint: + on success the value is stored into "*value" and "inifile_readint" returns 1, + otherwise inifile_readint returns 0 + */ +int inifile_readint(const inifile_t *inifile, const char *section, const char *key, int *value); + +/* + inifile_readint_def: + if found inifile_readint_def returns value of key, otherwise a default value "def" + */ +int inifile_readint_def(const inifile_t *inifile, const char *section, const char *key, const int def); + +#endif diff --git a/install-sh b/install-sh new file mode 100755 index 000000000..4d4a9519e --- /dev/null +++ b/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/intdoc/BraunigerIQformat b/intdoc/BraunigerIQformat new file mode 100644 index 000000000..8dd5d2853 --- /dev/null +++ b/intdoc/BraunigerIQformat @@ -0,0 +1,55 @@ +The following description was provided courtesy of the guys at Brauniger, +translated from German by Google: + + + +IQ-GPS PC data communication +============================ +Description of the sequence for the transmission of barograms IQ-GPS over the +serial interface (9600 Baud, 8, NO parity): + +All values are binary coded, with exception of the Pilot names. + +* 48, 49, 50, 51, 52, 53 (to the synchronisation) +* 1 byte flight number +* high and low - byte of the number of still following bytes +* high and low - byte of the serial number +* 25 byte pilot name (ASCII) +* high and low - byte of the starting date (e.g. 1309 for 13.09) +* high and low - byte of the starting year (e.g. 1995) +* high and low - byte of the maximum height 1 +* high and low - byte of the maximum height 2 +* high and low - byte of the maximum rise +* high and low - byte of the flying time in minutes +* 1 byte for the logging period (e.g. 5 for 5 seconds) +* high and low - byte of the starting time (e.g. 1105 for 11:05) +* high and low - byte of the stop time (e.g. 1305 for 13:05) + * for future extensions: 2 polar coordinates follow: + * Sinking value 1 (e.g. 10 = -1.0m/s) + * Speed value 1 (km/h) + * Sinking value 2 + * Speed value 2 + * 12 GPS coordinate values, binary coded as 4 byte long variable, follow + negative value mean W (S), positive value mean E (N). 0x00000000 if no + marking set was set, for 0xFFFFFFFF if marking, but no valid position. + * 4 byte Longitude 1 (MSB first) + * 4 byte Latitude 1 (MSB first) + ... + * 4 byte Longitude 12 (MSB first) + * 4 byte Latitude 12 (MSB first) +* now all heights and velocity values in the order: 2 byte for the height, 1 + byte for speed. Markings are coded in the height with an offset of 20.000 m. + + +Leimkuhler 18.02.99 + + + +I'm not sure about the "future extensions" part. My IQ-Competition/GPS doesn't +spit out those values and I believe that it has the most recent firmware. + +Also, curiously the final height/speed pair consistently omits the speed part. + + +Chris Jones +Aug 2004 diff --git a/intdoc/GPSBabel Windows GUI 2.00.00 Project Plan.pdf b/intdoc/GPSBabel Windows GUI 2.00.00 Project Plan.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2dc786566372ae79af9dc35ff3c8f1ac87732762 GIT binary patch literal 68640 zcma&NQZ5Ei&+~un~0bg z*%_Pg@xeGbJDM2Sz_@4Us7^TIup`xIzoT;?Ab`pniO14y(4C=Z6dVOnL((P_qqn3d zN>A*av6?~v)f8MyRZy}8=;G_LV}FanMGp7-Exo>9U#v(Xsl`=wQ_1bh4&GQkn}`ub=he>?1YOpas1D^zy16BKyD7lkMm^E6ipN!Wp`k-D z%%l=T#l5;TD6EX6RDKF;;BH=TnA&X(j#_Sg7~{Jp!ntPK_3xt9XIZ-aG>2cd->ugx zpLc5o_9XfI%dL!)t`I)%>09lq*{xP1P&L9Y`&xQ^kSBFqZdU`|6fFV3oJGSp{jm0f z1TmUQjQ6STej+9O2CR95-88{lMPG8n&8kYkCmI?Wx`&&C1)!mlh>O63VTjlzI!=HN zgByMW3ic^It!d@}$b9Eu#;0&HT;L=wID@=Zvj?;0? zY+hV~%Go%xq|;JjTxz+~6p+p1rr+SClj~!)Y_t#O-@n!NgD_DiIHa$yH7fa(BUl(FNX{7J4DV_%*uss6Ozs#kBBi&`h8`_ zF{0wdg9Tpl%|X)L_b8hu?M!a{#e!z=lmvvG3u0FMJuI(2D!Vn5d&>`nc+9piWsmI; zm?+P#`bVrZ*wvTmNOPQpu4fl5TwGK|N5MxyGnd(%a47F(X?}3_f0e1&QJz`Wh&xC< ziA@w2jR5#SE0EhA#?RqY^!Q?|CeB(+KbHYlUp+EEq+Z#*UgcCZX=;$i4W`Z_80~cu zy>zFC-DD+{+HAY2PVUc#%`~mkd$g83c>Q1Xm?aTDN{d_WR`dKlgoN~MjM&qNN;}2N zRP2B+TSE;IL!+Cse^>3BjA=-ourXxL%C;xHGtQx>?Xo|0Q@&b+26U_21?D$@pN0_7 z!SL~tqBm~;YKBl=`J2t0HwgM9%XLWb5m~s)cfUX^7jD--GIop*ay2~a%7)&zw%XT56`LN6*{K-*w-mMc#e+?KTVo1^&I## zi_ghZYmER09g^5GwZpl3XK74}5taK7+D7j$Q=H(5HCACiYd)+Sj9;=*(Iw+N_(2?x ziPHiMRnur|NkgIG&|GotSs1a9kARZ~$o2uHJY`2T_>b}$Ls=Df1MG0bjG{aAjy_KD zia}l>0yP6>_=)yhHk62!8n|V}2~caC5ePFz8j{yxD}Gs#0TU*+#{UyD|M~q_H2qf~ z{nyLL$jA=!KQpHPom))*Pr-G~yXCq)nsECS>9L7-b>IJwd!J_{b+xK`&6SkvGyZC# zKq4|xIDtiU@@3Bs-T$WYhHg5fun?C*91$d-S6OYXr_#$;)1^k!<<0Kr_vw1!Y;Ne{ za0mIPM0Kt&m%x@j)|X4sXldnZ?|f?|ZERi}zN!FkJAd%vZDoNaRArP^F8F!wPSwq3t*$Opw!Q{$uwIvyh|=9`O+IS|$Oz6- zJ+I$wWno$RsJzE6=lL?qL-BUiE;HtOb3iN0^m^w5 z7yGSssO|2b^%ekQwe7B4bB8mh6KkexpnXzsIDcrS<%C^~?`X!;lL_h9^`;CdS9)7~3GJ@4~lmlO;k z^N4uR0B<@Rw7lS2==Kl@#&aNxXdNu!MB0;8n8$W&eGgdh$@ijfb>==!9H)#G4qH_K zxW;jar4e6Tb#lvvf{)A7+H6=O1fGWmSv#yQ}B=Xp6xLNdo3jhbrh+C_{DNOHHfo z;U)q0S|@%Ql=3P>U5}tAeE--g5ye>Akr`y6e(^!aoQ;u|U5r9CQNC1*52ojfb8c^L zNf|o)BPp=M4iKLY;_;k+yS&dX8_Y{X(_=UZ2N*kOG<>flLu14F2%k%dfmTA&dV6o0uhe6236wc>;rxCm=;3NUMnOOKKIp-yH~3tE~LU7x#4+H z!+);GL-in`co1Wf1DgCWwy2s*m%hZ{q}JvZ5NOW893w+|QX2Zn{c|RC@N6WzAjbi`AJ!*K61h3q4a(!)CW_J-U-Kasp^douwB#d~9(yA-u zgj=3^r0KbTIA13CK&#wTwfM*nfx|&K`aly&_5Eb}bCvp*xRGmbQSq@-p>otv*7J2h z5}k05REmW4u77>0a9iE7VAKfFyaix@RDc@49?wdT@Ni)gcV`cMSy=(2%Wu;xi59f~ ze2uliLDV79&~UuLRvee65zCD><+P3j_QvqfVp>uqyV=F_A^jD0V1nI%B)gdOo#60i zP}sq4)!NR)>k#%KOh~Q$yV*D*2trq1nE7#w4()W#KAtZj1X=S*_E>bbgm2}T%hlSC z5vmCgr=+Voi%Tgi-qmEkXxutQJwb-b)NloF$8-@0GtO@PpJq#M#juJ8J-(pJeaA=3 z&ee`Gx%Ofjo5gV?8+OZ1b<62oO{~f5bY9{7t{|QyDf!a-SG}R zk#t)pv1CXSyBuuh35AE?x^s-p!EWu~NT3s;d9wG3eP&1HY4yr(&sa>sG#!HT=3loK zein4%#v_k^Lj6r)yXC(ruHKpnavE44?ECuvT?dr1rUSpCI4=sowP#@0FJ*-Pvn;n* z^q7CNB)yuAcayiP%QP$nQS@-j3-V-I`HEl#Bts)3z-rxzWK|ickROHtfxlpnnwdPl1G;1&t~L( z@Ez=VNf^|=;}7`ZKiGN(Edh97u1lzfxp9N}1fGeClyJLA6Az`yutoo{f|4*H#%J=@ z^Cp_o&QI#}OJfX3z=dKnYmyCa7fa3g1RgtQ$EVRJYT z$FrN&SV%!*ko<&LJk{9nAlpw}+nj!YF<*lsQB35W`H>f7ISh2~M&R`7nem@70lP6x z+nt8v8GqR}#q;1yAdvwOaH$P1xiSo%fGl%%lV)Msx%M7~Go0g+!!rzoX4{F#gzR5T;c11MW zmYwo`@7y>kp@#Hj;teJXlDaC-J8<=L2s!Ii4j9~ z!~uPB%uMn@LZxjbCooNZj3HHm7{L<6(KD&_Eqh1XGw}Gh7Qgu|O5v2RIj6*5XcKPP(*W@OB9)`*_PkJKfB7CXX6ci;GBWcO&p!onAS|W6`HSv1l;@x?xVT~qv#)Qo$USyffvYAYBx{?sd*`toB&*SVQk1J^=vlc75i@!C?v57Ee=wb zRc*O#5AjclqRozP;~#|?&QUl15Mq9FbYwfZDA=fa2L+v zsdi&3saX4m+$tRe+4ZmuKa;VQrgs6cZ2?IYVz^JSm6sdFD|l-{`>Af#mYY^aTM zkG45b6-+7X!~#+YHcSSo9>}1a-LPF{T3Io0+{{yUAwYHD`5Wf*Qn75n070~{~OJm zsAS}Yy;862tgxee+0^x$wFk|okk>F=RJ33=JF}v?1~QMVE?*LrVId0~gn`AZ#gr&u za}|(0G^MyZ6R{B9p9%c%fx>i+-+XqXbj2x51sfUx2&8sM z8Pa6s_|k{b9qA!+rTl>AO=|l9gJS)cgb;fku=dN=Xl>& z`lu10*bDM#kOY7bOHQ-=TSBFcS0 zXCc~_I{i}BOuivk6$RS`aQtIN>*oHXq;bx25N6Hp;T4&3tZcV=Iz3B>Ps^Ofp@6 zCTOd9Ydf3{L6vY$@6IMJKCxkBk-!mOmBX_>TeAUXAg=3?HEPjEet`dv=O>e>kOuC3 z2_|#LFsh28KHMpsdPuz4^a~?cuhHE%JM7B?WuT34n;u$$A4{d_?(rvDGpa{oAXo}_ zU&vu?X5g{Y;-)EnBAM#^Oro{h75CGSjOh>WGu1#CK3gz&zNd#lO z;C_g!nruDPcLBBrbwJu+(MA}`tD*O={$XxQ*lptj%|^Is2*fd*szWwY`xJJ4IzwGv zO1ZzRG)lJQjLt-GC1qjqsz^z*9Yvz+9+pTxrRep0leemG{}bI3xW{-sl>7Kt*co2E z^m4k#Y~nhZfr~=>5;N;q(&)5PT96iZk+dUbFe_nL&Ou7N3xG*sHp@kD6R)BiW@O}# zazl_o`7-gzX%&xw%ABM#b0~Q_9W&mOLfFHnAyx1Blm9w9|z69-Fb=rj6sTKpqpjQ&YugvjI^ zDnP=Cx@c(kRHjIqLXcSQw3KqIN70dsBbHu#WrMr9h&mNA^(JpiPD~ zfei7e)%$Jh@PsrZkyXA??|>9AA142n&f@r(q}&^@Zr9#=7sM*2)>k zt9ZIjh2}*RMx}JDs70eS+T`ubO)$5i@hQ8|mKy#XC}V6HH2krYds3gknyy>!L@RN2 zwfk#)#8t13wsh6T*Lbd2qg2sJ#{?3a8Pc0n=Ot-M#cXl8l^97Gjmv%(K{!BPmp!{} zl+WiV^xL#St*Y%5k@0RaqapUMLzh{y?plhIDN%2Fi6?fLWGHl_%TZf8*_V4rsPQB# z1x1uy%6UB;IaMGdhf*r1k!O}(k(V9kpBotDbKP}sL$mfnwJQYA2}BC~WTetVBI9Zz z8Ma%OGNM9l6d*H5@;byGnq(+AyBW!e<+zwxCRscgt7KHL>hCv^Ae`!A`#(*yXx(JS zZqfspXTq*vZfWoyx;6sIYd6CKIII3U3N=84%iopOWZT;8G?btWbWjX~F?!Rrel&-0 zkEUKJ_UIWGDxbceR;;@D0pWbT5+xq_Eakcv*~zTvjO+%-Xq1L87E?S8Dg>7C)i~`A zddMKRlbJ}EAa{(hC};RN?=j8jlv%qfm>|ZRbQACJ`yDiCV3VT7Z&B%zGsLN~^V~f~ zRr{YdcpVK^U5paeNOwH_QiEgM?nX%f_$MQQ5rGLbfr1eril~KESFN;^Lk0KSxfqFm z7nO0=sFd5Ttl=ywb*Ox|tnP>ntY~2Et8_vCq-s`vJzaNpuS=iN=1>bVT{Hu)%meb@ zsBnPr9KpF)X1MOoB8*dZ1%h3^)Y(?-xe#0HV3)Jann`D%l~^9WhXt??p`F0pu|aP> zWKEM*J+i7vm^)4e{87r&ql-rM+|oUaf zO%^@uSl3jiGiOEuU)9q_gqsupD5I6SH0%`t=#yi6QM(SkDRQX z8|y1KYYqmyEhh`_41FHQw4&jl1pZZ#Ux*{Qw*r|6a!Z`xI zRhyDzl~c_+{&C|EU3vWorb74zjQCgC^9gc|y!Wskf@738JAHBg)$F>gi1C&iYt`<3MrA9r5dp+uApNWdU;E%;6GoWG?SmlP8o~LHPu^06N*a!T81Z z%`goH8&Q{rOzOc1UQ~_>1G-U1rtpRi-<*c6YyTgj`mdtS;lSnDnPsoZoc0LgjKXf9 zh6TVkQ@}pn_0M!fs~cWn^<))WAT|o1aSXGa&Q2`NZG92CkvH-g{M!T%*C#P_iBxN}oLt>6zK0p~O5$!+$DF>_Ly?^Jw80v_h8&*WR_AbyO+|L^?iUi8c{S zF}t3sl`)b{^JLy)EKS=%JMl7y`F)5c0ipuL7vEj8<(imO6tdn;iXYf-`%c-}mo%8Ly8Xb3Y`kULkyVI3FmSw=MEX>W~>URHS zZCSR_;!+Z}dQ;tyqT=ax|8aHu`5E?DYC*kJ@trl~VMev0+4UQ8Q`uSh`TcybojD2T zx_*nW%H}+GMSwdCX=!90`fc>lQ_84`U z`Mt7jv38?}KP#&PpTk(N*1My(2&$vf)#bdAS!t`;)mJc8s_0TRXr(!^R=!ipYFhsB z-L_m;i7nl9UkAW3mB#zE=UD5sbeYm|9{K_3eVmsI%80XkTH*_BaeB_*s#;-3mr~a} z`{{h0Oh2_&J_}sh-$$48^=&;{NsyTT7s_wI`g0PV&?-Ixm(B`#A+ZSCU^eM zbLg-!`l@9Z-kY^swnp#E!EKjPD0Usok#D&v*t*S^$O!zAEDym6_5pFZ!qg4`Nz2C90?6JBV7};=Z zdP-Q9!;n_Aa_ccdsVP~eLea7c%TduOk>QrSE)v#i>B%B?&@ka%u^6jMJzj5?OZ=X> zKTA~}7$17%W`|UA5xW%QktnvT+(qbV?}Y2)gH_|UJ@v&L&H`O%x{UZ9A>0jf(paML92r;t@NPgSCpr-whAyl z5#ztOEF~eoqwj@Q>%&dH>>+sJzjY^MA^$xsnjcm3R^q7?QbPaL4a;iz+UP_5mMPT5 zF)_}HMHogSeP?YTMSKZkSeN#_J?G}AwFAWiPf5>SGha8>sWvj(8+{CF?9uZ}w4<$g z=qTM|sWCKjSphHu@Dyu}uaXz8%T*-YSXscYF)b`fTdyiD!+clOSv(alEZBRFh)cQ^ zKOYU2pNoU@WO*%c=yb}sZ=Rs{e6CK7y;h!#k6lclh&j5n)Qnr4m$(29eO4rUzw8v% z-}B3;JwBjy2nRP?9#Ao*6N$Mv*UCyQGxJw;y?kA7XH2~FJEa0-AWX7bRb*7iL@D@z z$RCppkO%3zw9U8Ycyq6&Upbyx);Bz1{P&>DSZEo0W?%g#gi9hLzVXFf2Xf#RBUDht zx#k($Z^K}_roya6fpAACcuYa1-D}6`_ON^>>hTVTbxpFUh<8cjHt1~xtTe&1QB#l*fR69Cn>4Pzx!dLUuW^j ziU>1oB#Dc1#26u1J1P`Lx&Sv3yT<935aPtVLe23P3zZIm@IKPE4WL+aN*nK)Cw7g(E z391(RrndDAn7w(A<)FNvx2~hSJLN*NShiNu`9;ea2IGKL@0UGL6`3j<);SB%fGy3B zU`t+-l?Hq(L5Z>Ag9(7qFL=VJ*K4ScJLm?R5bK@sP+E3ZgcoV@kzM0FlC3PnF*bs* znee!~SO@P-TGTVK`yyB1QULQ2FL^3mjrUuR`)d*NK{wrsq+i?C zPFcv`J5ygD2HOO8krdUb#ozXN^vbg0k-qC^z zf3^fuXVT0?!ak!aXBwc>C1-ao2g#EVb8f79R09u+8QV&`uB?y4-HT?Jk-c{lYK77> zQ`w0df+dEL#6#;$wsot$cNpKz5*wUMw^2}k%Q0e~z?VNv`zAo`4mcp@u3hT1)2sfjOyLB?PADqF`CEPDI8 z(PPw2-YmC|fBGx2@Dy%eq}FuO(~=TsnH58OyefWX520ve5t(kvKz=Y7UPLLw(vbvB zpATd=S9YEluf+R)XK4VXLV-Eg#gX*wFA#k>K06Il)uhQch@K%*b`)??ML($MIir)h z+s!^Z+UB_PCCYE2D|}}ja(?py3B73x zDy4;So+kZ;=o}^fK|OM#3J8z-66VdemIAO`Q_l9V%va6UqDW4N}x7h8S#!jms`&UT5e> z8C+)NPPrmvLrRzG>Jd=G+PQW$Mo!&H~6yIdSCa(uQDsc1~I{ z!e7AKqe|`1wK6V}#`y4!<1}Ma$-L6zC1^Cta6tVE59!6tX(?D^jn&0PzX*Im!{~x7 z>Q@^DNgw+ODRCmzn)kcBZ2(II{ND;&8ao45kipxuzadb`BZE&&DjyaI&~b!%Mh6F@ z0?ZHg!iA*kjmnI(Q#az14GmVR)EsYioHR{iJ^X7-r|)o!42ss_)(qtk2&}U z@!lk(ueZbzgEBkqoyna$U|QFBT{z;yaJ7F)1;)kkJL5!kSX|~(5GCa2dxFv9)oE1#oYHI}1*|H)8ON7oAoy<5fZJ?JY6g8g9#Pmlb^d~m8gkS;c9w`r32H)0XZ zNNkv~9NM$t@CRI_4^bg+Y6yl#&P7K|3RhwbF&t{>6Ah9a=#OV|#!+JY`clm;xGoAI zj3)$Um@bnc8vGl=6Oci^zwRNO8`!?P%i`VRLTlc__@gS30GsQZnFF_X+Hrk>PV z)@1qL$TY8~K_(7?$y=j3L47sGKe__+o6!#i*Xgy97Cj*{Q=YhUBs&syJ^ zC5EJ>7l8@Z#fun_#SS@1%dL#AyZ&~Sjk#a zW}=*c-zG$1)2lTPN`A{0ERr|Sj)kE!c1a_nRKpt=;P&VKCV$_u>%vlO^+QTB&_ zv0WTzg|tb5sSY^++&<9uhDt-dn{=XT=lNHm&tjy>a zt0)6ojZ@xDuZgKgz;v>?HRF7kq&Zj45`)d_ySA^4wM8Io9JnG&79g8c3&8;g7BIVa zsxe%+burc@8_l=TAmIqoVC1lgDV-l`tqL(I`dyTcz z&PaWMjL0EyqVMsEGB)EFk=aetM+KtL@Pn!d0n6m1g1Pd?FeTm$IC1c{z0erD>5hl9 zxy1(Z?>Y!lS8bENsbFQ}HuG^nOIce&|I!M3RHjM$KZdxgDf=yvf{#}xAF6m`>^8hg z&96Fv>R0H7Fmy(Yhfdw`N+H`*EjSwk}ed~Sv=Dwvt0481L{fY^ zpHmu9HSsKMhilaczo`}sNprp^TaHQt)*KbV_R?Kq4O(c9O|vcs0;y!t!GO%^1zIye zh)W_43L+`OkB`iuF?6fGeJnvgkT_8~<7i=VAJ4+0xksOpSNG|=s2956i*1Vp zh%%%QIH9B4*g3i%b5ocQS~1Xhfw|FRB6&l%{TaJ7%G%YS#9gQa^8>maBqb4xx(YQD zIs?GJRFSF%uu;Bhm@#Zwlf63n7awv_0GfNlcQru>q=j3dl=Ba=5i}1L!p9z60D}a) zRab37Lx+lI*0pW1U(b}Q@;P>6iWLm;CY>Jwhj)-c+}C@sqSIzYEp-E=5S-{kbD`Hv z10&q@(unCcyPaguG_kFqxt z!Y8w>Ubs+eg)5ks2jGQ#8)IUnxh3LwnXs2GV*T2Bx-qz5-BOOdCd#uUn|LlrnC{X8 z{em?$Sx$pDvYR$eY1uVAFiO6uCA;}h*0zUL_6{{k3grcgKZunY>w#*H(Xp4ePQ4u- zVXmS7eZuwYA$REP$Gyra5Lv~HO$B8rde~-X9sbi7g*LQE$-GVErlgiAT!hL1nql`N zJhl%&CV~_mGRBX0AUEhET?LLVkC5-Gk5?p9eSyHu3`9@j70}imp7~+~Q^su40Va;5 zD@aCWLY<^mCbkeknx3N^KjBn&5t%&L;NBhF9T(^CL&Ek^a+qGqBr3b6sqJye*Q3(M zutjx_l^6xMJBT!dAL^`D4HpP$ktGU&#*g8z?>FPz=CE{Oi6Z~umu5rA_hFlI(s9wD zno|l^1bZ2Bh$)vN<*K)~=t~=SG?*cLft^0$Vu~-mVT*r?=^xVwP-3*{+sPg@o=F@_ z31^zj--Rcrvq9obIB;}x>SjfM2P)OVvjXrnqgV}2tUor8Qi-aQW`bwgou`1&HCwBr$lxSL_g^8CLnd$60}FPCM0cg@cQ|v< zQ{YX=BdpRB-BErGnQK}8dos!=z`uYMVR6@&0O+7Zj#w!rd}eWiSn!Flha?~0pW76O zHdXVp@a~G$9k^9{adc#?{SNtXj^*OO?m*yf=xlMe<9Gc8k$mi;=id<9v>|Q95jA{P z4kWbpxFdZm#H%M8zZYnd2oK>*gF&I>HCr-pp#o>4HM%Y~6Kdac?8p=0@+q5qOH5>p z-7zk0^qP!LM40t?vO#U5zy*~mkg{wz8gko#KEOni<`)-na91nLf{;jJzdDs0{t3Dr zd0I|Qwo^q)l@kEz4!QnI7#e~e7TzRP&fnuv%*Ehm4Zr5;oL8d*;&O(m0X;#0Oro{_ zdnE$rJ#E6XEH9~STIpwW$8sOpU_^;&2Hb43MU`jRN}3h>3MBf>uq23Ni)aY@hLMt!rz;x`P7|~hRcn>o9Ix##1%V~zM}I83tx3tpHPb{z(eU!X1UL?U^6vm z8He~#(pK$GwENyS1T->_{@0Bz zy-W07eqcO*46bv$M7`Zaq6&9Ua(*i`ZkOvwr*EpiMKf;sh-@Kz)eE+ZZu)+ZN)5* z*^bWEP{QjK457!nJs>*G8``)f4(=YWtgT4^D3S$CI{e8f)W+kur$Bi2c$l+iI-0{w z!DURA-{nx@$^HBdtTBU~E`{>rNb;MLLijVyCkFxj9FE%gj_@uDhZK~oUbA;0W8d&K zay0NeCi>w-NkBl#O2B9PH<8VC=w6NZ0UrE*!7b{|$HW(IZ-`xWN#YlM+4+lG%hN9R znQ(;wA*nXkj}(#ORh~}8aCk&%jq(qY4bn@574km}s>g6^KLoFds@0U*xZQR|9-1c> z?6^mPK|-Tj`}xguvA4Zyffw8V$f9;vxNyCWK+9 z;v?3aDOM?U9y=Vv>C`8DhM|7>^3#o#Xe6@D%p8<otKF3rnpokdL${@15Vvz6b%~GA1Xm@q0 zfHZe98AARwzJ+}N*qkMS380^aBOG`#;W-g($A;>>jw9tsPV-(MGo?wPaopnyalpRD>GHHR{r;um-54V1BSuwXV|q7hYWD#XmGe`eGyafq0M;XaGFK?o8yjiRtg!uk7JLpq zzO*eIb$0scX)Q8Nd?6w3T6y02l1V0b65yere}A1v-s?QT8fCGv)Pi5IaJ3E9WOod` zMff?b8WNZ`ZGJdbT9!@lCQT(xxfer`_AYpN9op>XTxa}y8C#_0va&kLC39k%sXF0? z&#}XWg!q)(Ybo>jk##$`UYI6f06(1BxKK4;mR|gpb50I`f%5r{VEhb> zRa7wytiNmbC*fm(P-T$R2-WX}#x0Q}W3ig(5oW+JB1~)>)ec${mM2<&Zuh+tp7j`EBGTJlKlf zD7)L$r5$^`>W%}!>a0|ZUztJGdDelLi><{TV;Ktw2cGHf4=e~oYFSO<{R1<*i zbDl-Q)|+6iVTt8oL#KWH+1vwV?<`K(qv7oOXee7`?C>{bfNN;?;hY$UQM9dgau}zs zqeRw2vq$Wwhp>m_IHBpRkrJ=S^-}fUi%Tb#ekAJ2c)7oi1N6T9ew?~3vKwkVc6JoL zruc|3&6K*Eb5dfU79_!MQmg73Hc`zl zZD5nPL_BKyNvX^puRvZ;esY?s&1HgTK$NPU~;kQDC>HUU{h>0p0#Qo&QZ$+ z$@cD&U~)x*i0f6|1~%H;ea2BF%*{jUYJBl@|NVWxk>xjc_?b%lhc7R(fA=xiIRAeE#lrYM<&6I;pjepx-vpGT+qPI@@1xqXP338a z{xO34F7D=0$xhY|(+S`7B`8^9B2A>SbfL*_%+ClaG$AuFGf4o5hP8CAFCV55QQNqB zuR7Cvoa|P(?B#FPf2tTO6J>GRryEIA$rXPDtYFTsg2Tlui zAEoR)_E}3)Neu)Ij5bA{M{IIkqmnJ0J}wV^TlB78L^4G++q+jUs_cs#Z9a&0CR@!r zFP?2~oeMpeZCN=^AiL++XvxdXR_4LL4bZCyR**j3JLJ{b5Vb}JQPlo2(> zw=GRE3$CBm*vpyMQ9HVAvUV-8MXsh^zy#~1&vpk3|4PwEZT9+$%#E##txHL5AiiOW zT=tx|ZuPY{pdhQDXNse$LIV7@uTw0enK**4+vM*VX~bWQIg7WdEMP`GJ^OFv0O`?z z6eY`h^1t?l+-uF1VLlwZkd^W_Hf6-XUXm8brv>oQ|G1HSmO5vH5zv|g*?X28#4_p5 z9W(FiZG^o*;TAR;zEyAJ{CGBS00l~IzzF8S=VQ4i^G!&qc3LkB`$o*jaMi#9@=I0@iZ8iqdc-w0Z6`w#fj8`u1XkJ2p(mW8NaWLXd-JT@+sXNa z9>qCm1s=g^@v05i9I2E-MG9f->@yC94M_`D$;0RH9F-*J_6T=ks?OC5iJ7+9-uS}Kl@NEdG|3B%BCM)?IFDY!ia&l03Inj> zSg4DH{S>o^?cCqSEl+hxV-fiDX=0}Nx3DI9dLF{mJT1Lo&%ghrr=U8&1rM#wG3LUU zy)n?t`c3g!cY!k=4fYpBC@7zUo(Sg0A_OD;{G6EYJ%h`A86g!d_XmRivmi%pd~wcq zer*s0H8_<0{`_0+W1-9U(=`Y+fHNdD&WK=dU;3dUT8H(`3rDZ@>1>|-9ZRHVMRAFb z7tbFc@SvqHnSB-K(1@{qbI$FmyC=$pLPf+`*I^Ol;*gsoOpwNX-dX=kxEHB;(i6Cc zc2(HYPq!K^H5Q0%qgj!H)eQ5G4p(E8XKn$#WqF<8)x^&zxLDE!*29>E44>gHux$qH>0gHq_WFj!aABYo40@$MR4 zKSB&u)FJdRcqU0KsV92T5pzF)bq)wWUfxc>r`vi*f^=mOVsxo$2^>#Jamb1A2q2?- zu8TKL9T@tZy%g*cYcQi77A4Y5~vi2*z#k5(^sIA7bimsag~%{ z+V9gEb2=TN6$)q&=nibUH!W+4KPUUg%m-ubiq;)y(Am+}&fv4;g2eN40Ow!CVUn@L z!a_@uif*joq6-KOS$wz49iSj)tr)e8C+?Cr>Os}E!`a6g4Exk$8yRhp^YkH@4962^ z>{z_>b(Qvo)e=qMvF`q?%DFs(+ixReZ;VZc-~_6Eb^K25GLZoCA}J#Kpfo{HuW6=q z_Dj(>Hp(*~i){i~|F>xXJb^Y{p$4Q5sS-uCWAFuB=?xk?d-AC@rgM#)mv=-w-QwQ` zmty2RZp5Dv3;KZ~CC|HONtm% zu)jnr=DvN{*%_3(vCVoVXZ;6gv$IXB~g;<%0=4h>O69 zoIOq)%I$|{t!f}waql{=DR!UGh`T)yKa@FLX?;?${%{7Zn-}K%=MWd)y5T}S>N`)T z6p11R>kW%D>z^F)-#L5FxrhniwF33N3uaO0xaUiwnqRBN4L_o}xC!P3G&Rn6Y(B!l zfYFc4rFjf<{Rm*fCu3Hg_Z&FUXjX+NvR-Mj}o+-!U0ODuDdQP|xGEZ#&+rPAP z<@R$tVBkB4N8H;*Zp`iM0fjDK9g6gR{;5m>i3idwc|7KwLd2=jP&KoTOYweE`Kzp9 z1RgXgZ!Ejfm^Bq1y|dSTrdi?T4p0+sP~i%Y6N0i^eC4=EWeGG$-_EY|5}$jI+aj)y ztSaqM+jV@NH+q8+B4OJRhaz=Ii+`-JOmir2vCh1eccYgCe8mwhP+RYp#HC7`L%)$K z7A`+#FOb&n2k&`Z-{0R>Gm#GO>GSe&G2mFIJ(x;|9*vkr*@+lZoBYoOUz}w$@6vf4 zU=Z&)p^aaiazd^&6+|6oC5ClDidrExWppKcrDvCQLP){r?4!aP2&IVGw;4V#ctbhVIIH?p=!tWc)niC0 zTSzCD8cW}4L=zP9|3pV!qi7zb@gRA0ZMnf)XEiAmBLv_YUU`H1o%-Wno+ZuW$$Tp9LEEXiyqt=fCq#5@A2o zclwh&ddUf^89E7p4U0|Lfh9aO$cmkDg7@$_we6H7ED^ea(Kz^;uraP1|J+j@u{$h7 zv&$tE9!T=(F$fwUK+^ZZyJOJkKWFF;_^~o*Y{^EC{=VD zyyg{6fOEGx&djkQO?v(NTaHRkpQ1dK3y)*ESvW=^dY(K=g9)n2FrfD(BM_vX+LOjsIk%~$>Zc>4;ls|n5o*jQe3B5`qAo241hOAVvk-Mb zypkza>P1Tv_?8V-E`7XbDfqMzA`el#@cdr31=B=hZR8|Jr{EKWGsVz}icenE*Z^gG zoCT>VghVW5Z>9d&gopqrU(pd9CH@$o)LWlXx}D{Uo%shm8&MeIqZ}X30$wNt?(`uod^D?UfAtI;6+CqA!`V z{KO1J?W|t)iy#VogQaCn=@{XbYD*qg^9;s|we7pS5`QQ3cCsT&#%4%Rzsi{^Y6?F9 z;P$L-Ewo%AB$jeAL65$tGdqJk0~`S!a2Yd&NU%ow6y!=6#O0$RxO-V!y26ay(ZT`fIh4?^_XCx4C*!2m zv5obh=U&$_kBi=ug0FLSKECFFBnm{=lj40{L2F6+cF&7CQaqNA?5;T!iKp@mSmv+8eNucissHKm<$BSv+LvXXq4nH(uKP)|5c@|Lm(d*v0 zUU6h}bYy!*wL^d0(Y*)0Nj`XCArKF1#6_>T#&NBr&rznhOT?_q%BpQOj6HCz!yE&x zkW!>$Gx>UtKhcL)O-4Up=!+Ipie02(x^(03MY`GrR2I_jSQn>Pk!w?*oO^SIUanvH zr^`P_m#=E*Cl|&!fu4oH4vALpJsC65cxkMF#)qVoFIT)=K(Bbzsk*I#YtQx=yZ3=} zBCboF8;_!n#3ZDl>+C$L_;qawTMq)lVhAJNRF-(b0(J#n8d4x2+>lSFO+g)DpDVV& z?mP$}VMa(-lI9<)LwmiZ-e5W8)~Ps(e_tjuBF@1deLIhgi35`hDbnU(K*{SVjo3^~ z8Qu1SOGTYv326e-`IJ_setsxOY1qcL^*s52>M35cHQs#*OVL&P}>Q zQ>IH9Oe}}6*|mqhr9|_40J`n@-#?66x+lzRfr-XZ+DFQwEfgr7a4);3Av(zmmU^l0 zJi0Vy)?HCHAhlwEL2}qRUbBPidUtO*t}db7`>PlRK8;t&0s8v6uGKdTF$A|^#@W6o zXM8F(JlU5vJypf-&W_qO{Xxc>F>0Ms2=CtIkmTMUJ{3qb-i2z-jR`VRl>h7>M7?XZ z^`_!3r&`kx<(U3s!P)j;r?jno4v0MU8Ua8SeqO3Y0;zRV@-{=%Fc8kJe?zIE=x#_aC47l+)Su4Ku5&kZVEcafy(ssU;zBE3zLk4ekm!e@nZcOr zPN-Tv6)Q}W^{a|s(D*bHzbJ=@4eFG&WRel5pxcfekco4)(7mCM9!qxj-w1-qF@Sdjs`5lvVv!f zIT@O+5WM1~`k0W!xe?hX(};DKXu=91{4q%8cy7+9NBe%-*$z~FZ`tP#Q+&Dg)E`I> zG0u$ow?d>uK14VFaC&IoQ$P5U#bnjl(S-w**@U291if$Mh#SXWqtf<9g_ zd;#}D<_7~7THCZljmn}n3V7jFUVhy3*`+G*eep+a4Ev^6 zv`^ueYS(Q{LJEAUBl0i_7!(S1hNBztwT3<{YSj;N6x4ez+^r?tBaDdZ;}{7s->0H$ z@nqh}K0S#%2p6tT4))nDH+U;Ke#VB8)zuz2jyQz7t$X0u2Lm%QRLO}t^@6d|rnk4= z>uWIEM_cAqZJVprhb$aK3j%E?@Y}^qvL1^PnYN_aaC~Jgq@tZK_$TjC@AEuCBH6-6 z`2ag%YVFU1ZL}H}s`=>Ji96ZwS-STn3v8e&0Ld{MF~Y~<#rE<#W3`89_v3s#j2RsE zt;3A#2;rej-_;Q_QvV*yqpxVDcP-XpY_02^qIH$s=)**P*S=Z>%TkF3m? zsw2f?%~amu7~GDou)J<-2#$hpD??y3?nanB(R!P8uqJK)R+nlky#Cr>_}N!j^O<+$ zDY>cV=+TS%h>Y)-dxKt+U zHMJUbWyF5>bh$Do!)n4K$D?O0I{?jKoXzHyJ}5;|`k z!EcV&Bl+~W6|k-4vVxjMOFm$89nb27RH*gsI+rZYjf+@dG`81AN>vghk1j}#uv8nW0=W-KTq>Gia zrNW0NJW`iRwdU@~+S4YpOYSn8y0z$rAbX<*mUg91+N`S7-C>U}I($zb4H;Q=K~v)7 z_)WOuYL=~8plm6TRGI6gbE~-SLnuB>d3l+1^eDHjb`lVdwyOlKzId#qWTIu;Sh6!@ ze5qV#Sz&>FH>f&cce1^-2eMfHt{`C!-Yx zS5=wtYp-Wx)fvN*clx7ml};+-o*!m(h(6nv$W(XWp~TiNUwg#GMSfni$F!OhxNO6; zlIPS)M9Z}gq#sTT#+Dyf=^xt89^ie=cT#aj7o+zzpKfO6CDzr2Kuydf@?S#H;1DzT zSqKhJt{=}ru>JK}2)2LsEQIEO13^9d;t`!m!eFkGeiPB`ta10J_}v+n4Ehy%>abiR z#aw9xg=1s&uj}uS^?YGqlA0XimGUI>0^1-)&DdlG{4NH%Qj)o@2ClPO_|8{D(->`{ z_5sWf&qz6K7@vD{W7u!RU-LfYe(HkMDVhw4ND0SDkVQnnW5AMLq_?nIV<=m^`SsJ- z`}L8e474C~y7g^iQ}(!?hBF4QgmilWT?XEQ6con6@s)I6TMzH19mr8Q(m|?GK=R4d zQ2oHLn@Pf#qs6&+t^qpA_|j@}g_A^F>-F%aLiVF@;{t9(mF=ox&Ldo;iinS@W_Uxd znQU78^7Ufz)$?g23Lv!gYfuJ9-gh*{!o$8%FOX1mK}5W+*@-t0OKA*1J~Fp1n~(9c z3XX0bq`x12=<8j8$&~XVFaEsuAS6dUdcpW)J(|`3ckdg)PT3x)=EyVk+z7d`4ZgC^wB=tmu0QA2H{}q zQBtpy-{vJG(+5ISu< zJRsV}?T|qu=0f{EfLX{()s378$k|6jHKQHqQ?}T0D2AGAnV4%^jKh|vxG9l{*`i#Q zc~gid5pRi^^4Mp5Tj{BRapn|-Pp3A_42dYqeVE6mj99$pPNNJ1 zl`SKu2g&k1c^I@BSQXkB(yt43&+L2`ys#=9{k}?BazgmUz6g*t)n&>CY&0lJ7rzL9 zbLJGv2x;eCZ@2brnSYg%9&ZsVWS)-j(X61|hR3>UD9tM*0v_cnxL4ba5G>1@Z0*t- zc4nMz251^?g1wn9D>9Ng9%H{K5`?l9#Hl@KkDkh*Ep5638|AJ*rOhBdaX*S{&#hhE zR#HGc)b8Y^%|Vm*Q&kgm1vqp}s@EOsd07=z2`asGD-%p8Cda!~3Oq$GiM1xRn+wBr z@{m`i!_j?2?ii^W`3;<(@QC5W=G;@I(+X08FY=&AEz<~YDb~_OX^^byIok}-va`qw ztDb>u!E9LUyEBJchecr^f)@FiLxnxvuP3l) ze0|9g*U4l0iAqq=yGg3ZMdJg`0QCng-Da(+aXPNOZl>&lHg{XQy8nDTKb5P&MF1)==|BF zp?$Ilx$dLoYSo{z^E`oDEPWYvc~r%yTUlw3Z$C1!N7N9*|D1frOFPX~_@N|AZ>d4+ zAZH2xqGjRXfzpesCZ)}_I9kfhlAMnM575wdc(bD*+IxMM4IkN=Jz6H8dc7n-d>{7X zHPKWI*TM9_BW8Tz*)QcTEYHd~<0?HZDPuexTAt8-J2*pEyK1sR*%hdGPBfkuHFc2V z>~-xVK^q;C1gp{e)Wt5DQQ}E>mUiQ@49!|bu19)29@}FcHJU=DF$Wbmh)p@h*N>6& zFew6>%R(;UGaDvJ5gL{5J|W{P6?)O_tVDZ8KG!h3LAt7F%ZFN!TXUoue*B_ufzmuT zsv(OvvS)z>>aYi4p>dEQ9Vs!)zhG!i7rQviW(!3#1^&5mv4XgOEN>SA?d%6_ni8Ev zQWI>VDaO+<)CYIJ!Y}4h$oiLC6t}%C87(x4W$mmD=VWQ{mR#d|?yMEq{WY%9E%uIg z6I~N~T$>4uoSEeD%TfsrchT^=l7&KOSbuY~EwqZSJn<}U_UgW8?x@n~y2h7jfQN`B>Xm>p-txV3Yn*Y_ZB|Ti^V=VqO&O?Zf);L_>PCJsOiNCrx{v z_T{DKr9y!`no1c)gO?v2wPGKw<=51ek()J$k#cR;AU(|HcUcWjwdmt8;wciVcM`yl z&{P-GeaeF5DE>kTE;RG7n=dzFAY%_%PKbnB2nrUGT|AuFnL4fdTFMGZL#u->NW3 zLzNib#cZZDoz54I!-Zhf9X?j)>oJM_q`Y|2O(}HZR6ri@$@FBx5!jRAZF+1vE7h<+0R^ce@Ye z*cLaa1Mnh?DBP~s3-?F4&N$dRV?GXUjUtoY|2(g6$sK}?YTR%_TU7~ZI*YJ^C0gmf zn43?_Cp-S81hS*;2=>rQXqn_AZ&S(rf|P*HrKCLk#7YUWb8+g3da2TpnQN;-&;B^E zZHzSKsG#HWf>ITChxz1p%tg}!zU`_{<&h;K=`aaY^-z_Z)ATgFAO?e4KR3aT?T&4K zJ|J1S;)_*Nk_AP*Z*GBOWVBWT<%&GK~#u zyopurwieX1h)z8ov<_%@<~wlPeAs9QehMfgl@_eHpAIHf`?;Pgss$KaA~`N7x%QZr zvb02XK%hqnTmCz-!W!E(I zK||&al08mc;OjLp(h$8cl5cBdbq3h zickA>j^r?gIi;Ox%%|T!)NKED#way&?;*K-#Is;sF_MvR8H@35beam6+6V7U^tV-- z$}6E_L>?AylDhAxNtICCR^l^G<9c?Xx zpMG`Gqi%Htq@_#}zo8*ZiTF5li|s%H(&J367l9x8?=VkI5~2&J>^hk49C>@E#$^c>^N9d?p*p>V0R2ba&}|fFL}sKS0$r;FXxnA@VyL zg3P7EKrbTRvRMB3zSHbB7&2AOoKPN2pVf&8Bn|*>c{r3Lk_eNSRnp4=D z0&O|3gnKCtD24IFjgQz&s;|Xc7OKc-=j!3VNlABTUz|JTi4;Hg95N&HX!}z6`7@S< zT1QfsWxqxsk<#-}+}6@5`X`rdjFTFjr3s$JXGU$;ZFw$I#wW9>qL8`#6HD<;)Cv!9 z28BD601z;)NG;X-Q~D3z60HoCqDIqBQoxgPGO}^JiKk4+(6MUrDi&TPf5laO41D@a zqLp2C$Kvba0D#orLQryZBaW)EPqk73%?kKR04@~T>*6(4yO^pFE#zyA)Lbh(inoPiC z4rUf&PHq-$1b~9A6YwR{#7w|k4#qZ4#H^qNLcq($j<(JYhQ^M-wL@|awuXwp_xl2X zZ>J^(C>gss0n3THIXzYc7i9sjDMA2<*#e8R+>{5tjv62gJO|e3NDO)%tO5e?5|Dfl ztt@Q+y9Ba+?-Q6nR#4+$YJL$2eqrrx3R!Qx!S;WHg{)jRT)&}^`>zy&-z9LHLN<^T zLCgfo=YNAjw%a^p`x_pD7n}V?;r}uZ*}?II?=WP)Vd!r#1jit5QwZwP4GV#&1}X|M zSW_H{0aE5hj>MV>H@yU-RRIAE2?Yc&-+{XuOluPZLF5dCJ^L?3`i1jb%kOTg7uI*u zx3V?;(auj*`K}i~boqx!f2tS);E9|JF*85^4+R2g+;`zCa3X*^{;OHA3jRn1zLl97 zoDNXnMgRi~puo%wd|fjLW57dh1m^EoS(p)6eq3cmUk>dcSS|3K?t zHTY5gUs?z2#gEkgKDfMR54MqvMr9Cj82_V2P|XGdTMBL|?s#)ZHJ79-&ABnrmo zce;i29gRUo5TL3gBqA?NC+J|VZ^a-1R2y?c871%#BVz1m=wNQ=Wa~i8d_w@({((vX zmEYXK(Mi}$-+`Ew1t6{e{g|1B8K7!z0<%5zy+l0dn&lj8!AEhKv!>S z1l9l=lWl;Xf-tu+CFZ!1m!h+Q6UYGoF$icqevH51)b9)j^X^AE0EqoRPgKoq1Z^D6 zf1Zn&o0u2_eFUIWpb6Aa0HckqlaaBB_OFU>Dc?^)swl}wDJ$Oy@~;xSLB)SBKxXcL zB|xSd_5pzhV$3i0{K0k*)4;6c-~ic1pgRQK1BC`W{#^h}2!G@Oi<}#*>A%$qtna&! zi2o{1Pzp$tpbglK1k z#!lvj`V2z0Rz^1-$c+a619@O;^Jgte=GMlJ;2Lf;{9n`q9yu>cYD zSD>-nXvBYuG$5{TS&HA-e`DhQp?{p9)c*wg!N%p!4l60hs|v}{f%zwE?5bdEt#2cz zc#D&NWdQRHdj6IH92~c7B@@>V4t!UO8<^i%GFC1SAAkN3e%QVn2>-BlKhtk=f>Z-! z;eZ?H$M%Qv00DoC&%nliH#`5paIo9*Ctn0b73C#m=rr{0On`#`&{8?LGk_*O&eq=n z2Eyp=0p$O}{xCCr@5dj#{LU3-F5s|mEIW8Oy!mGZAO9=^ z^g3^jSwU?8=Wv|F>^CFU_qM<11lGt3%n909z&SzxEFg-&xmkepgQ+A29Rc$JQ-LX9 zI#@tufH^@MD2<(i^OkIY772LmpG^=b^*^BlU{B;vS>G5BF!cY0-2i(qe_zGFwmqC6 zu79uN<`Yb}zrgh46HUzQZ2bH`zs02eyb|RZ6Poa;SNAuF(V_%2MD6<;$`(GvS`Xs= zq%b>1TLBW;!mwFRRSd1gL}kxji%gPvc$3CB8<1kRiorxCrx&h?^w`g}I=D{>Du0s+ zp62zfyHje>0{;a@YBZwI*xzEi(el+UX4j>tL?!HFJ-o%me*y`LB7E6UvdFE|9^7miHNL>$YVMsB~cb3QD#;qE+;0Y zKfN#(5Kt5VO18>2=Ache5rg>zyZ~}N{&dTjZ&{k3c7~JtH}8e>#xwn?_zup-pt^qf z8Q=`xNd>p^(?|LD4h%EE(ALh~!Q9l$$x+|N@s<|@p8EXB2yr1rc@42YE$-i#*&7Y{ z+rIzilCp99=sp5S>3;n{UI;T6P%VMVdZVyFl?16X@Eok3K-cnzIsNbUAYbCUKfwWF zD#+^r8EKGD1KPmHz!3&yzCp*J?WWBiDO^B<|2^fqR|P5u$`3OAKg#^o9|BSaYzt)S zK{VdpgX;f5_Ye9&=b&Ry-@m8*>?0^YXxIUz|0oA)_s8)s&i!zwZ(X^?*PGshYhz{o z&8XeXQhvhicW0Rsl=}aOwZCpabll=E+V`2ISwB6>_ zKcVc`(EWqwKlZmu1Emc@#EnDn13f<`J~x=U$qn|WzdH_~+@QLCA(#r zvfDp4a4&%Zx?LKahaJ2Eh@Bf`G1-}b&;dt5f6E6nSU0(VId0|V1P=hWTLBvzU`wFZ z*nqAscn>@V)%N30e+49F+MJE5AVU#K6kj-uWg_@O{YshdzQsI{#SFzn}yh2>P=E zMR#ihTdRLj8VsU8OG}7psEhsmZ0N58G|P<${{`}I#f*L%ph5AN->?Td`)P1~n5%!< z-!_FmhT|La2Qr$VdT+uIzghra|86kB10N8tU?U11et+fre)Pj+f;0g%{C?kq+6B`D zJO>#|P;SuvXLJcTV1x4h%nvf0pfaFqKofmK9q{NkeYlxF{R39Ot$Y_2nBV^wZra}t zo#43N?TUY&)`1Z$t8Z=mUqlgwfVaYccfuH0n1L(+Y6mA9vo^?^H+3XtLjVXm8iMYH z0WSh?W9i$88-v`$n^Vy25tIfhi2%5nI|$mCS^;mNApjJejIC9OnOQgy05ax|j=)eH zIG6xpG_WFISQ2;}jT+z%umKnXYyn09W55%D2*3p301yKx0Gt5M0A+v`z#3rYZf9m} zLj&#zaHe4l6azSZ@yi7UpMPh;U*{q~N^Xb#gn!OWI5}=lPL!39??U`9f zjAK-ivrcPZJ&egzD}?&=NMv<{`U6rc1f&E!$)m5x#PKy)OZUx0p*x;*L56iHyh0F) zC)B9Dq_y+yfQN1F|De^(I)a!-hoez@PCjavG5T@9hV3R|S z{=rBQ-^aM(VHs8OKK2d<{g?Z%fDfnYin=tsd4u@TL6=lWS3QVSf?{Ei&!{iHXbUq% z@+f9BnEREH1{x)en?lx<_&;OQyIvwO2V}ev;lH4NhuBIhB*D?G6RLy&^-$ zdenPIPS>Ha27<5+`DoIs3r1c8U#V=TT2M4$Gh5ZbCjF?2p!h`vgaa2|& zhqCR9wIi|W%BbdGX?p>Tk5E>v$(cpo<02O_g1xATN3MR~K2kJnu#P4?rPa$)QgE|;$X)AcRfm}nELB8zrZacUsQ+KzR+jDl)>#4J~3|(4U&IxJ0gob$c zK~Fh>GvXvnK>#b&w|nGadXM+i2DEgweFl)*>&X^z&aYKb&!R|^BrXr;j9leNM&wjy zwe9a}e3c@)3hcS6pc=j|R5a2fmGOrSU?*sZcayi5@kER!xa3(1VhU;}7qE{Ns5lin z9ZWqg=(oIklGC)7)q7Fk_w5Di%EuKJ?IM-7N)EI9A|Kh0BT0phQuO^+L!ZW=t>Qdh zH+;q%M|tF^?;38Zs^r>LV}XsWUuWFrKXuLKw{WMSqjMrOSyp0XNd-rb=x7;P*r%8~ zUsUHFMD}uQlk$$^+mFu*tzB z%`x)Jp9*r_6ISTY&6*>j1bUiTg%t$T+)pCacsEdA%_Be+mMlcoW- zObHO4#BYQzqlpyUJ*#TSZ^Z3^gOe`wfx#MF-XKr?l&vdHDSa)ZAqOD{ucDKPDDJTy zj%g61mGVBI(M0Yn;^9drYb(XBz|tDOpl&t^AuS1Pi$vTi!N@tEV%yWi1O7*cVsEE$ zaI0oQi0M)ho+Pog;qs^R%d6TLIA$rKW;Lm|qL*Q%lFl<`Fsn@B16*s6+8=&tMRgvx z@EvrdcwS`#FRj{^znnhV1B&ki%7 z8pSMRC+>1A7tgW*&#L4|1_P zm|}jN9w{O{gy2_(^V$%FaTkBZsf0V19fms8t5KcCGE)3Rl$jAdFEFg;DLezLo`8rk z5t4rSt_oYQQx2EMa~L-#_>?_irnzOaRBA;s1Pdf9(gJVR>-i!CUS6aNz`ccMNPi7; zfjpLf<2wA!eJilfzyNd@z+MA4@Rq{=SFeGU`@i%WJd7P|!H$Cv*mZDnwFTG#9S9SE z96%K4KsW--0FQw#ggHPFU;&T-xBy)VSD-VY4|FFC0IC2xV+V6vquVY82gn6f_~lZ7 z&;Q3R1q&-T=dF0BvNF7qqAH#@$!fD|iCUk?g7`}{Xrp_zA#k+e5Xd3Ka_Tj3`ZN+R z(5C$JCK>GnU%}EDYWlyW+=VMF?518;nSU7~3R?kztoLkjXJ+_%19`lmefan|Jw5$; z@$~cc^{M97Kn^_vHDOe*&7h=|T#yxK@9=^UVf|bG>Q6X&C$=S2h|qQMmpPBCN2U2w z&DGzS_0U>=^+54r!gtVp@s&@|CSECWf`o-{&i>3{T|iaE&D~wX73Xp< zlI>AUM&irFxj16g?7_E6G!uBXMFM9UMbg0c98e>&C|2jeOGt!~AJr8?=aFhR(#WJF zrliEsIq$p1d%S*AZb#xnm~CFX$UXZm1lqYyi4j>fca{2H)m4?ae7su5Mp8_CkvIzC zV83jF`8!e_NU9j?q0Tc%9Sz4C(9PE+*?iLzrs)9dom~l}0(_`d0$VmW!OrypR{c z)&ZvHukm8`6%~izYFIn2d~`QG-KrnTGxoHiIx6&3oP{-ypd{!vskxcNSFS9LBiRi@ zHJLzVNd;5AbOj`MrB27cjN?2b!3MZ=CeENyvlQ z*eVBV1F;-9)1J7z*Y<5Zu? z33~?8ra?n^ls1SQsW$Y)$ZJS^Vz)`fCM|`}bg8db!q-=3=e-uRI$m^0JR`=Mppsbu}AZ5u+Vjn|PlUq+@Q9yzp28hn#c1-kcKH(M;lAarjo8qZ;t|Z4cZTN%?LB>puuW>f;gvw16 zwItEPgm|M&(+7Af_e9jGG{@+8j=!A%9;209E7Ub&CL|_EmcB?4e=>!Lc;TMY>GjpO z&?X_1zv$cR-BE8P6^53fRU&E{fJmwBWf?L?)FbsQ8k^*BRwk3|i8kDaN?Yzx5lmkm z60PnB!Xa#wY+ODrkj>=PUi7o6)O+J{2Y~hQGfhIw8n%WIg$T2ucIDENd?lezp>-=^ z*h!N;8Btvu6nedytp-we`kN&s=Dd{}k2oUhyQmUr-Z{|A^U!+u`rFpk4^s!f6dH~; zTP$u;s<^#rY5e@n^3x7f{%ZqWcla=oH{*s+)%3SN3NXCW_pJ|+;&4=XS>@AL_CXz5 zu*BJcs{9MNn;-@5V5^E&S~%vBp@GiHd{H4!BHfbX@ovsuO%>fHl$**PM+Jq_F#e`H z%j@k@?ToHB8eg){?^|T}e6Vuddxd@S1>u0m<_d4h(*0>?*We{TX*JCx6LZyU4>GbX zmU(wCBC2V&(U+8r$DfjP7hWq?Q-~o^!BtG+H8;V?Ze|PGJ{^9$J9h7t?B`_>Qm;wG zszWoNZ6t2Hz#J)6Q2dltFhSr{Q52QmDX06oDk<0F&K<7M4X%Yp0eP9k1O6n@KUes(+aJ6~4! z?^4rn%BSQEhXde+x8;nSEj-t#Y}4rlo+MMF7SBxr9cYeNNH3#Dt~CSB7I z?Z>krY{!P~p_KAvF1Z=EFA^@IwtW%dP70SOS9|K}Fy>VKGywZu$)+b|W5xcbQ#4ut zCM*;1dD28>5*MLqm&YvJ;eOBq>{3CS=5f+6X6^zq`y^q}n=E;$FG6$kqlTZ=HK2`5 z!fBc9=pD8z3 zII+ZuVteL;D(4K`cDn)OPPZ0CjL=~<#zJ1hGLLr0@M=@MBX*NG@R409iDj{8tVL{s z0v{H<*&E>V;h9h8cspQC6-FE-Ma_s6a{(1ujzkqUoR6?@z0Ve?cw+XwHZ}KNx?&gW z3TOcQ@FV11(8H$&9Ag!_XH#s8C39xc&qr0QWuApJPiIyN$9BG$Sa`YI>?S7P{$|rt zs5;(Wya(YZ!`9~8iHWN9sq?{w{K@R%2APubm|aK&Wpt=q&r%1yOsd1_Hgm{gsoCeo zg*h%23fzZ>2Yx-YQx=DxughD|-?Cj>1vHwQgw&oy?5FwYw2WPJONd6_f0BYT7{#d( z>pv8g&cKR3yLmr38XucXMMr{*QP_|Asy4$xrSQ$brSqCAsxVbbzv$w)PLpdm`j*fW z*P;s?f42wF%djmaKJ5nANvxf*)}S~l4di&@0!i<{F^md6Sj8z6`>t6V$30!9eYKCYAPw9zV>3ctL z@h^3cv44gQ@h^Pd8#Q!#m&I-uif`C5ePow2M0#W_VVd8ZUF*Eab17;u={!`o%v4v_ zOv)_$iVN=5Bf(7x&1y`FH4}t;1TE9YIz>^;VFyP_eM!$g91zm2(y=3&=ZbiZVIWG2_ zZwkJ#b;~!s6#@VE;Vu?d;HtNux8eQT6VTQ+_*QL0 zMNLgu5(6`H^P*@a_&9kx35H?m5k)yDmVO1tLqrF~Bgs;%biZOp2bMUjcaF4(EMZs} ziV6yfkLEfs92Kgu7FZlv5D^XsFxk@Cu_BO=kevMjVsuSx6wE7y>0%QRc&kvofxP;3PkYJEKza;5B}~-`58( z{P{N^`L~OTZl*!N+n1oJ5GOFi%)!n512(^6r@)K1fdfAM0Ucn$e*h0NaBcD*p;O?h z)nB1gA>fQh4mi(I1kP|kp;CQ-!EdkuMbK|gX+Y=y<0%br1qbUb+!!l)%4sU&wUVHf zB?isi$1fd5O#tKbTz#S6n(9vk2 zj-2SZY)tfc0-~AEja%{O8q){tpG(UZXZK8ohs)|+9$ecE52moLUksmKc(=ai4i@g} zMSp-|s-0adSvC+iO)#O9pt4RRx%f(c;LBuUu`-n-qAi7$$&^F##Y(dCf}~+7vkS34 zLFM&ASORruc1#P0!zjcDHeGapJM*qyLXDS=9-zs#nR<*mmR{f1%2^5Nvr+Fv`-UOIWpe&!u!8= ztmhM0A8qN}ddK4bm8>#YoQeZ&K2)a5P=v8E?JcEB1ugnP7u(}O+^~79Q(RX>&i-$@ zUfP!e*%?IhVg7S)M}{K6_ktKb+QN1-i`2u4W{$Dz_~d*t*NhT%mpxliwply;?D`=+ zh7-pFOEY>KlG;#63i|zJ?vPe^*Y`@&Wkh*4$H5mp!4mCIo$ZceQm0oRLsj=xDqq}# zb&n3arfgcnGlx$W_j72Q(bV<^(2nk^(wb=)(+K7^wV1YzuUVhUS0vgayrF7*LmKkx zxIlk$X&tGX%97eSqrasjVU_hPks^rbgHy-D=o5CFr9c6=sJ*cbDRg%sAN>!~Y2{>( zzR@x9?)N7gh+mWAQLRf-9_~Z!ylqRtmAVjUtzpQcWx;t$IJ7J3{OI zrO2ZHvxSpd20g+HVlCWfeQ?3@Z61u|6{*J!9@-gzAWhHI7>JaNM(l^OChX>1?~EQ= zkkvBXljfUPS{5al*d^TMs=m|x65jMWTsS0v>Z%$^LSRRu4Kpx@??rV$<`JB;lZU4V z&pA3bQ5m%yht!ZoF=cDh7hEH;sqy@Aasd^a^nh^T{Uzvi3h|FU&)W)s-%kIa?c&nl zp|K!akHwyYR}i|SaX~I58$7FI5<_x$pJHT4q}O#;pKDV06X$8g zaQD6P%=C3xfn^I>;K(3;ufe6gw%$op1%^s{KfC`YjvTvyY2F?C(;S;sOM;rA)Seyr z#MaetRQ<{KdDG0-__VJ1_IG6Bq{gJAh-9!n@OrI8vkEd1+%*@%DxWp0!<|W#CeT2o zQTxm*=xQ-#u=EA#!DH90H_{W2HuGYqrECcA3p~#ix1DC+v^4HNCw0P#G;uy;@eCpknfI8GC=B;wgy+SQOiSgbo{?|5%1$Yb{LpwY1U9 zSbR9`+eqE@w$zcb;I)EoL&bHRjz?P0JmfJ&GCxmyi1P;sBA+5YS;I%76q(z}ENdyN zY*D3gi-za3ptYGbf0BLAQ}&HKEUEC7qF6Y0y$zriF>BJ49gA2yj5IgAg&p_mRJY43 zfAUVBmI*3cfN@}CByva%@4}Ma>A<=`{uP4CU@iVp+WIjd;}H!Pu5Cvk7sK{prR!3Y z!@<00KdmJ@8LK+K!c%(_ldU6QY|oc75Q?!CeT-T+@ZKu7lRcIUSyjF_)8*F2X%hbn zv9-sYBsdop8Vos=uhDvu`s7et?QOe0qYref#y((;Yr{VvACiRr=y&sZz za7Oe|i<8ZJ=0KZ0=7XgD1J*>+i#kObxd;GU@VDA`Ug!FvjCnl7idm0x$KGw9W?tmd z37tqIx9k!TX+%UskjCob=%K(ayZPcY-iuWUSdfr_K42BB+VK3V^93CIevU0a?!`aQM?d@PTF1-R0Ii;0_{-QHRu;yzE?Z zGz@WZVw3=enY&hPFneiMvx&xiRYvOb**cjp;ekfNy{Gd(HN$=|y9q z$jh0pf)bT-Dz#5Eh%vAkhCWO3b;|O+p+C^VXig8>D`n4P{1xyv*(-qxIR4%v*Xea`pPll987U$XK=QBSEPgc%L48>eIY@G04S&3cA zYc<9Sk)%~Tg%cI3e4Wql{B&$YL3gocGa+)Yw?w*Y!e=efgXx55Ht&k8`C6dYpb~mg zbZ;uYNj0@nQ$gjlMaeDKKsR4YDO&mKVZN%)V$&yfY`TmS!tJ{%FqWv>y``t>@2 zgcZSwuhdj3cWfmT2OL$Knma~jM;hY2=+6i#dp=*iSb;r?N+ASzT@Fir=ofh9@G4dN z+p&dOr{+B`gU)*grb(#fva30qqziX*1ua`E6o=Xzd8GrwsEhKsA!kcWDA*pw3Gb>( zi`hPZpK5=)Eb!2(ZtKoC?zikhPbLRNJCx?TcWef2?TVCHnrkAS2-HvV&NyK4@zswR zkLD+=?XKWk3Ve2!)1hn`7oXs4BAF$RwyDRHMh?PTvN*Oy#fih9p$@$GGFF-@+19`1 zIh=*+^?;koEG^RcREP>1Kixg)BiAQrD!G~0rEj#d*{2f@Tr;hd`VcHxw(C1!X8>;k z2jPD`~!-qmRm!Kc!9%?YY3)haE4DXHM z!)E`5Wg*C0xtv^qD7L{N-6uIY^;uNqc1rUxo;O+Vcx&?|yYus{_~cU)mk%~GNDgWJ z>drp*r?V)&q50vDRc^M&%!n@+8{#~L0K9OeF$Qchi4e2a53SuL(hI-$i71|JO~L}& zKwkbMeDtH*r#X9Xg0qJ=$aV-DyP6-JzZ!y}|1^@3nz+?p@FAD2ps7w$BX5MfaxxT$ zi1Fo0H@OIvcRPbW)FiGutb>ED@5xNI+kw@SsB*_xfl1aGtj`Y`xb_Jax)>8P`&Ni} z`v^8^WdUY9lzrF}4;b$y+)+{E<%_D|HT%Q>q3ChKhcEM9R+7&z^W*1*EJekR(vp@* zG}hqcCJ!o)^OuOGfahYc`jET~;fVuyG8QzgB9xfZ(+TMq?*{aE6UTIUn(a(?!U11v zHWY2PbtzjPz?M#ym-3R7NiLG9eR~QcGOPPgTn;s^#RDPFZj|GG<%rm4SApcS{mbLY zY=O?!j-jfQ(~Cp0-iLsO`|)|o)|Nc^Z!r$*2pJX-HM9NRy|y4i`q*p9t;W?!&P32+=M_tt;h zaK0|A9+Ki|gFwOyDjExD4u0y&T=_x&-MZmIM+a6tS0Uog{-=PF<`< zG2)wJW*xEZNqiodpT{({=9?}ycN67@jJ_XxynwmM7hAruo*QCi_$_`r1-0FJW6AX! zkBvFir6i8FevkIp;tBp+VdP*(cd9TWQ9C3Hg2T1L`E~nmzT7a{`)7F&$E6?P7&;Rq zo6jpHKb`J0&wT%LP-Tl>yX*rSvG0h*_%W=iL2q*0bc85dACLG}F z-K}lPNOgIjugi80YvswIno*WSi)R!ov#4E21b^36p25}EkOg0cQYvra z#q{)MNp1I*RYRlf!MUL5Oa*j++j{55S>0IS9*W}oJJ2-w*sd6*j#kIOuT`nW_O!0X zdc@u#OMI{DT<61gpKuw_6`Ze+5QLmbRuH%=gC3%Pu+-xAxTG#WgNO(kPHZ&;xdpFn zY4Npj7PXSA7=1FW>$aeOLIy2$A`R3oPfK?9oKR0Kv_6X_T-;JFrvcL2X#MC&LeJ#* zuaLN}<%f-)#C*f4OY(CSukjbptkSK>$m!p}Iq-k!bU@SQlF@j{z!PLwLzMSCQ$@Y5Rcj)#vwaS$7wf+5hC$902Y)h8J=DG9}8Ki1HCg4YhIMzHSlI&cC{ zT#iG%l(M=#z}bP4dpDh4qr)x%t|TJy@tkeM;+5-_h0&w@fXsRP>e&@$!?xARxk!ju zQc@LI*7U*8sSMcFDNI`-d5=8S=vYgWHP@`I%DZf?oY_y;dtc?^F}-Skzg7KMYuDdg zX$v0$b&Z7^sXrntXCC;9`alROGE2Uw&O&+3RHfj%RGVxj3>c-u(=!Wm1Q8>LWDq9M z&9dbK>ju6jhcwsz(_=U(5tzPa`q zGoyawsd{Qujrwv-8niYw7sp3VD5!moqx zuW*DCna1UG#XC^g+7eQBQ?wBgjo98MEsNE*1JVKoY4oWyqz$W+^VpSzeMa;emC_z9 zlXSKfCswW<=^rb)E$>yq*eoxj^jdz^+xNk?J#`&Nv1V|KjHuU!Hh~Fd#QIDh+*=wO zyY_1uot@FS6PI9<2aH&Y&dieS;Wv(9FC1vg1S6e-(LTW#9=o6vaM_`_wP;j`q^qa zjodyK;}T8{TL|N3kX7SofTg_oleLebpZ}7Tp5`5`o$0qsrS?x{`1sGDUu|)B)45z2 zzk-3arD{O(g70H>u7QM(lvZe{`|e~}DNstNDEDDU%I?mlH{2WsJ?m3mQ117WnAeM;iRW2krz@+g263R zM3Rs^>FYhuTryxTRk~H2(}ux-MYTqde)kTE;uX}gLGEMDV4+E&XDZBH22TgwG_qw3 zB9mL9_xKdLSG0YmPN|1pUCtZDTq$3CKaIT|Wx zM!(FOyoesQAYB9sde0OYH36yY(gfekBWU^3u1Jb#M&A^14GK_vb>~Tho5#e1k+s-2 zHCm%U31GPp3|=hA)_w?@<#;j6zBm3VEfn;Q8<@z9NkST4m&~lrObXgCB>QR3U>~w` z+=3+ZN2X_D7HQO8!kTaeaJBq=t^hRYBo?q~Iz;cFi$M#QEi?~YGc)^*c}7Y@^QFnj zhGApv*(7FOAnGMVWaHA3ZHBb*;B(n9g?8ht4bBmv*#p-47C^tIA)G}+kaEO;u?8n7 zmgJAKo9W?YK9C1pRnS7uAUH3D}^;x75M^>s}e8OP#z=47CKC^j%B8q+dRIxHSEW1z+uluI}tjz)l&-G z>v8@(Z|~o4qJZNk(xK+Ps9crp!@wA?i0Ql2FRg8oOStmE`9iGfp?FizS@1!xL7IoC-O!~wyAoCpIfj!<~7HRdo zajgT=ffr=;u31u4MQyc+1?ohim);LA=LO=Qqg^_UNIp>?rYA$+D=z_E36q<4re4vh zw$Q}jlp%us4wR?2aw2jMtd~JHVy2~}XwxPFBXxbR7nFxP2w4ZzCrMuLBU#2z&a3ko zwPE3O3WSbA(XQ7uGJkmXvaLE;;(XNax#qc198;ysEIyT8%gFX(x;%l} zg-%)8+JC;+VB2d0npZKSrw*c3IiCb4uUp-}qTUZ1%r(Yy`Ot2k7|2KoSdMzBzGM-C z;Mpngjx0lrghvCf!-6qfOX=m_H}m*AT|vTY1hPM~>B?lC@nDAysBex07vSUkwm?9; zov^?f$EZb494r1v?0wisHi0m73=~p4+6@jBZod_Q?9m}d?8y>wJW-}pegv1S5O18U zk)+n;?oC}<&BJh&;w&|lVLk?J#N&y`KD9lK3jvApNox4>@?y+Qvc_{9^T5MHd(Jak zSchftf)zNd*NmpLXA%)2cg7%oo3?kL{T{Nk~uI;ps z-m&FgRoTbVnqcn-J{uBYWn{DK0n1wPdkq-_rm@4yMr+I9f&LZIxe=VNzdut(CX9)@ zAwO;bpzj&jFMy=)I;x4*C9kk~YbCHx9Q4PcN(BUN9@#w?>z?y&I+XkkHsA1&V1&3l z3K8Nml3_F{ZwFlg?(()8aU%YN1-K z#%8ixF|4)qUZ(H)-3Z@(wbq!y2U~daTj9S?t^SfV|C2Q6|7m{yHL3cxIB358qi_C= zfR&Bye;8A-eNUqPHm3T=<^Pxde9x@@$LR3i(;wD<45|J>_y2=}|MnLD(w6=f3;yH! zf5~^GjBQMv%)T8nc1HI9%fK@+aIpSuh;+ebX@`8&bmY}RRi&%O>N8qnHniqo{Q?Wv zV=>YE6Ax-wPl$L_sNRYmFaU7GUr;d=23EOOehsEk9NSDnXNHwZ(LvY-Xu9HJQu=ag zs_Vc-VGTMc!^q(*+5FB7YVOgCO2{t##EJ7`Htmq>b=p;DEBh|%%4@3{0FVH9nBOmZ zsH+K9uW{8dC^>WqJT$?}g#w^CL_{=kJcaI@xQ_xrT#KdC;{)88&X)L<`C)SLthriZ z?YBq#`4>Gi29DbSI2$a`{srmI`wt`|6=+xB!fdi`C$o>yWOH9Wa6S0ybp$9<_X)uC z9z$=t33}v0GJrV;vC=3 zy(5=F7V%r~UqA`hRCWUZ^yGsVxyM@}8{2-K+W^er!LRbIfSXB7Kj0s=W`Z(p@vXC^fex!uc2OE5m2?Fe>}FG(&~&^Krx49CE?wU%qCe4veZpR)}d^ z|C8lF_{sEv^&xZ{2j}wZQA7<|)9i402mAZ@;FIFjC1r=V%Z{&E3tKZ#^?$lU*1xSm+TqlB0v;GXVGOl~HF5RsHQHaeV99`iGdw!0pl28{G zkcv`=5J*-etD-*_g{T+7qU5gJp1=8FvI{7^;~t+zt~oo!&)!HfgJZT0CE#>*Y1ito z&M10x2Q48~W_Y7^U2q2My~1vBh6+Fu+`nW)28?Ue8HOKHwM%RhE#JdQh zOEn^^>|pg#{UNVJu|X6G>gs0;wuOv=cneOYr+8O0GH6&KvO&5+B-$<5o!^xm{6dly zcUFi%A)P5Kn7f->FSb&QGtVwtMq$d>ue#-O0E+IFC4ds$QG|8P11-1)_7X)1W_YB$ zt7CRSat-_PKWGH5f|z6f1J_dkA$bkk3}A~Q*cx!#0<5|t@f>q;nEPRlhwJrR9P`*L z)|e@Rb&cio4&P+@_g#5CJEk)K1hp1998F3>hv(l@n3<(HZNEJiFk zs2Gr+v=s`}d&xc|2j&ROpMz3v5v7vb;0BQhHT zD$xhh4#A#UC`yB68^`L#X_XCEkq&Vkp`O9FD~2xx?#u8>N4R&ySC_dxTe|IWntp|p zg#UecyWv^XEC%6OX^Ao&GVnyX=1GxPnU)eWT^%&kSxXkdujN*}Kmm}L`c_CcR zcT5|7$nSQtLv9p;Y1-I2TH;#D_-_DKj~B zoEjg1%sor1nq^KmpQS{xqH>?a;4+`52xA@Q^YpZQ7UN7Vlm-emk@q<757@_4Q=(5t zmhH7S1NuF3K@`mmi96_P1Zl7G*}WxoFH1rSbK69#$$9+Y?Y*Bw(mT=imPuRsdF%T` zY~iTniYczlf56jGBOD&b7K44G|JlPM1ytJ zLFRAQrpk)iEM6r&E};)Q_dsh^%fJh~)20Q{@FSOlP)aN8akk2>>qXe7U(f_}F}^9L zW7Qbl50mwoiJ6I@aTwWlENMi)Gl)bd;}#D`{Wu&7IO=C`(rlv_Qi)_73ny_XSdKxHvPN+!zcsWXh^O&CWx7(N;&#*h;Y>#zHW9jLJygY74KNAZQyX3=X|HLn?MZA+Gp z?}sN}6|DW|E7CkwUh~8DeBv#vRAKUdqYGt4xS-u+TwoBKay_9)$N2DhG>sv+y`f$V z=&*#8HKxU{g=;jUcY0^3jAC22G@G^ zh2doA+vwmG(ov)B;0i-o_w_pmW5DNgRN}JE^PP!1+R>TqiG7+U+A(IM+Ge1@RN9uz z!_!M1lk>xgKk5cTQnIKD3T5>p%RPCA)o@GWe5vDCHY#9F5OaIY+{s3YKvqRLS2kkee5ITji2z!j!Z8Lq$fQ+daRN$ag)WqRzP zUh)#3<50}zHMCUICV#|>8;JQSC7>XIsH7U82|<852!GGUt=)T^8yyKpm_FHC8o5`!qsXLaeI^HN}+|1Iq8u z+g@IRPgpUgo714M4&m0_&89D((4~h;+Ia#mTN>&!L@cYC23us*i*vopd9sbg>eDS~ z6qBDhCfd&5i(lKTtE#8R(~-Ci*Qu<(9e?KEV#xn;l%dd4*4Fx^ zekes|QizyNbHMonACg2dYHa7S<0>R$7RUv(9)?;=pkQ@J?kLs4@%E5)Qa9F?vCI)i z^>+qe%MaPLEC}LFVu)QICj=a|%vL`8A2%a|AFYVe_az2~yL>`J0}(c!dcXCyqP=o% zKWMhRPLf8N`3CVy)B(9;Gly~nhcl4&m|p}9aM<*jTS|^*KEb;iEQI?WJ-6IGi@sI| zUAuQ2pF4VodJyBUdiOOML#H8pAyE|A5bdw$zs5hu(jgpSsBhmhMYVf^UNVs5Uj#;r z-)~$?AQ=H(U%6qkvR~VrqllcHhu=_$=5?`rr4vl+k9InFh3G$6h`PZl_^xuEd=qUn zpz`)NZqTu6v{}LAFHTHtr>s8sX~ogro~pg8gJY1{-k&hFWgEw?M$HF{waXv)05$&j zJpcRQ>^uGcuj9=BiWK~>Z8ZNx3BLQ_{;4T_gLDq&fhqJ^fypo?`-R2{0|}8%J`q=v%Ryv)nAZ-44u$lBGW%n zgMawY_TN&|zvBiXe<@Cm=5F7n^gqD^M`IUbn{O0Q?Ax2Rp!>_wrc?S$eX^vpG5`MH ze=-TqHb%w{j)t}l#^1Q0p{h;vNHZ|{x+aT z)+zI!)2yr*;lsS6hNkZ>DBCU)Rt^^v1Vc zrft1P#7&7w7px&ouUY$|!Yhi%I$g4d89duJSdS6Idzp8gR3?^GSX88_wX)25-@(bKb3*euhFL$8U4S@JR{g3TRu>l?-FtzAQ6?QB=^P0S zj~1q7;}9Q>EYf)u5f?oxmO#eQ-E*CbwnDX9s|n^yqib`BNtsv*iOxAZIwmYSMkcO3 zXehMf92t^mKk{05vf; zWUjEJLBjsf74b^KO+v45?LmY7m=)1sV5 zQlzVLKe@N+S*2)Ho9}&2`p2}Qw{OMTT<8YtU;Yf7E%Gu7PQkPN-egt`xb>KEx za@aAIGR4R7wfb&e;w~eZ36*)t{xR&l9padCqjQv&MRCM3JpheHXQxe|A=j{NTI!nn zqgEn%wnrV;H_gd_YzBXz3MWl2jxa?y_)T0JuqmQRS$&QsSD3ifkd=?JxUy7JaC1Hl zMURW+Lb%?u&n4K)l9lAg&BaD#f?Y+|fD%Y;e=p$c1J-b2Pm-fp4Xen8Q1HF84JUN4 ztm&nIt+5Hn(G4;Es03I^h6d&Rp+SNkNVgt5O{G5xDrCsd+--m2v|+xS_+AAE4ag`Q zv3@kMJTy;mPV^z!IWig;4XHQB86b{|0!At#GToF4)XoSEL`X@eLmXuCBY%qs{nFU_ zTq3A?iV_KB%0TMG-;0*i`N_TGVgyHk?!Q8%3dN+7$o=4qP|G7oz|`Ylz*U{J3>@DI36OVPUqFPHQ|t|>a{ux4*aOi zS2b`BdQ71Ayag8Htm~*K-aHT+C0j+MtQ{JrsueDCnrf<(fao#e0dckP?C{{Uhz?B9 zQ(MDdrnHbLeJ;IiEL&QUldS8&KBMjeo}RIJU|;KZ71DLg_K!Qq;}}BI5wqbv-GO;5 z3C5QWPr{o$2UCj8uM`3RKeww}y;{Z^r+(K*Bc=nd+1$o&m-6dVZkegj#HiZhzhjds zErEBOc~6o=z^8fsq&bGb^?l{q7b-#J%XbGVO1<0PMY_kT=WBFybo(jfo6hgWxo4V|1# zE&xdms$`q?8U|2B9E=NjAPN{fdN7LD<$t)L3v8NoRlzY!vLYlHf;(fuv`A_05zmPy zSM8J2&oSe3zZu9>0R92m3ai{?f!!X>>a>OJVt`*_jv87`)<vCs$q1eSJ-lH--0A z<{8@WaXTe$B8I~J0qtpnP__3CpqnN1?OkNA8!%S9Z)0l!eLEkzWIp=wj>~|?;7l}8 z8uq7hy~Xi{0GF0S=NHH~@@6nGalFiK3<@R(R!STAnybh8%P1xQm@+9PIzG;dW3t-B znpQ43umVL(*ky#d6dVv#_Z@DnPxw0NLbvA(JH3%liC*9o>ZwGS;=_ph`O-vY{Utlj zvmgT@I8`8{1^52Md~e<3jy3Yi&j>zH2TGfxF9UAm3Xpf(&hj19Jg1rIiV>8qfq8kc zN*p&oJ9Z7200AcvssJ8O+z#9ZWp_&(dJO+cH)xOmpC?F?;{d+HgD!9)SHMa`NFM{0 z=ic{$zMUXq6GC0;`8S0s+^uj;elWR_`p9_0W`KQ6%{Qpj0UuN&h>me9`Ht?B0)p4F z{6O7@(|`>~G?%^7AaF4O-~s7I;aZ44DiKdoRQOXEH~uvc!LF3E{G(TF(zdlYx~NF($B!TFjr1vnI30r|!w} z8peyr3wJaKl%vhBYhi#&CsddrObq8V#J?>AGoZ zdDTElT}|!XWR2!qI$uGtKLrd*Nf~{44$$5(+sA-3mDAR(`fciCZ9J4YT4nn(X8fIU zf9n}mo`o7Vdwg<2GFd%%fx-9b%P8t7`yjhPOk;&&(K_F2fwA@G=F{ap9ABp=8@K+7 zkxvS8mNirgv|hM(L8_cDWi!u#z7O?i!}JoIHFs%c1QTM?vOC!BckKc~Osgg*m)hZT zebHfOw(9|_zDVF^dn0}YZ}lfK0VUkEWAs3lgRCS#P^n}wI=dSeKm`TVlJNnfmPnvd zhCiU7zKFwVlgLX9X92Gxpa~VHZmujUEKGw(ueDoW8mmx|kD`8*qxG8iX$Q4^-1@QO zOBfJ&X*{)n{`tzZ*N0r}?{b*>U<``tXF)vyfl9yw3DmU4lh*2{0o|rZ*Wd?@B1OU# zGMp|sUcY$oE+O1D4N?jwsVr%#A?>8*^~*DMn~OT{vn)=64$_tsN6SwYTYs`{7i}at zW{)p)oh&^gYb7i?uPxIMd(5fw=Sj$df=vKJ9y=mBI_*}yb&+VpwMZmCVbZwMD#OjV zQ!LyZB_sG81*-#JECTY*ckXdN@&=y)CVTg`R>8@S-|Apz7lCIl(fS!IZk&s>;N-%V zl6-)D`_P+iI!*`JmAf^!`DfMO1k5m(r9)>{;KxNHQ;FhRnGK5EmJ20O7h5pV+f%1z z=oxHr9|IsZ+Q1bDx@NoRT82@+gpae5Fa$)2*It3(W3cvD_*bT2$`>8+S8jqn7`V_+ zlj@Z5WkWkOeLIa`)-#>2zJhn>U%_B^qslDvBdmDV)cqp9DFHWjh%XpQV^qAoYvYQ` z#tU;57KzT$CDr^bG4@{rn%AVEUCiL!7BvP32gc@ica8wE;0wX!27fM#%F2Ypp?U8i zR}RR1(x6&l=aa|MeVK&fv-c*@GzSuj-8v)7 zCMWfc7I|Ac+mSd)DkY$+1T6%zIigttrs`*FaJo1bmh2m2s>vlJV+&<|=s#?`Dg8!# zh;HIBjw=!(@o(bSt<FED=8 z#>cagqiznm<>cdiEA>s~kwHEE1}z4{NzO!*yI zVo#u|MAoh*uIb3MH1yP_aN`ftv(WsH#*GjkjNng5J04?U#Uv#9%lLA z8FK+sX6c3PiXFwTyCn`Rs3z>GPE-o%S34W-sUg*KWi(<;(3UyRgIR?|JZ2$GI`gB?qulF)i;oW=Bx@yC?ngWI>g3g*mOmqBo*fmW^0gAi99BCsti$| z|DQkBtdhzaqxS&?!R)k7ce&t@+B3Y~GWs_9)x0UHMQ++jG@MGI{h&I(u1t z$mUkyfNsR8^^BjakY5~=g+H|W025G?axm@f_mOV%su@wKixKd|Tr7ey^Mkf|>@)ni zAS}e#e_YHwuI0awF?oF~3@_tBzKDgsv?mEJi#HzBVgG@^eCn{p-D87Ej`D-dAe~lv zL94FMJfFjA;s@JrH&X7WOdQk(S2Q9506>OcNWzxEu!|BpFtU{iE;s2BFo;bQQ_a`A zT%XA_oMZwbf?rTcbV1#za2XqW?No5q2GH{J*;fgZKqXlrlaNN0c2k*g=n!r^xfpd%p`Vhjl)QIOJ5=7EEdD3bxhgqNJp&^p z^oe|;Imi+DE4bDGFk_xasFle%en}f_beHbMGgSA>O85uQg?k{8qLImjJ+Rr-08rTa zyOT>r=Z~hN+C^y7v~Xk10B!|~xif4F%hO-C5qGcwo%Qbudb#Obr>~+Jdrx;f;*DN4 zQjTh3bv?4usy|2AJz+w1@bF4`ywh~OayhL5oOV*KE(>O$GSl|z8|J<}=iN$Xe&O(r z5D;OtOK^|viGhX5Fph`%B!(vR-&f>P{hTS9RX_%@dD5dOc|-G3v>HG?Q7=Cg;in`N-mqkjU4thG3AKn29)+KCev#PuV`@D@5 zFSfSaYF{e3#0~+21*xWggHgtsa~WW@#Dhbj3@81L1v+h;0r%Kw*HQPVNHrBkyLI<$ z)4-_p=7p)N-R1W%{zIP*4&0hEu)1{EJRS{{4O*3)VC^n~dl@!4xlq_@rCqF)R$aRD z3%p3X7i5xDNE5JlUfvyZ6^t_J0^FA$x-BgD&ri{XwN$Na9NPNW-AMz*@IHfbMD75` zZed#Cc0t^k8$YECWJ5=9s?9OW5=_|~e)x6xd5NArh7(EaP+4hX%swC`1EQoqZ1@S3 zV}h^f;}d-hP%a6%wF_qS%uDdf&cGI}v{0tRh}p?Xl=vBz#cE~OFLThdQ*Q#~2vk}; zrEi7J^!!Lww+ZY0t?hw6CzN}S$f=*G$g~-2y<@a631nt)l zQmXOx-^L(RTY?>$7xMJ#{eXe&)o89$ch5#0GEWJ9v^76m7-r|lMQ`4#NcTX_leE2(af*kVbgh*_#rxTwcm(7a(&UaXlYs;&QDCWm8OaH+9GUS13B=BDedesuNVIx;!Bnb<~R zL32KrQ*w}Svg#@<8I+Tg>t{m&lJi6D`B@TPZ!TF&&OkWmExlmi zrvnhS@iwg*0Tz&Pq%Uw!6#&zz5VfmDjR+&Y`I4=(2T6RR3Dh1b=P1 z&9%O&%yoY{Wuph^8OZOBFuRM*ec#An!#{cw=CTBDN}eVI+a<{sDB^ov=rV|GT`0Lj z2AdB57l+4(Z_|OA{ooyq&{svI;mqib--~J;`Pt4NU5@<1!Pe*D!llRJ;ibnxQpE0R zZF#N-4OrmEy_WSM!8zZ{+Mc0)Y87T_4ps&%pMc^VD~|r8J@9@bMET8b!JpHeTm{Ho zcKt1E_e!_y?4Tj#9_=H)9|WL!Qz$T+k-DQZpWDJS$wuOMkO=ilC)S$szWjFRPuY!l zQ70i_fJOG|;nv|?U8)*YV^N0=goT3_L&^!Q4w{T_)%-8?SVa=z<4Arh?1!v!b}kC~ zsKx4okWsv1`c!E5%&xPCe2#+~r|?tN$S7pRQ^yq>scn{N1d|m{*ge7?dj$%#%-?a$ zgLa$%p*b{reui3u!ymtT!aQFnlG23K*e4Dl@{U&u`Gqo5KmTz0dVMp5?-kmt!I$bh zaV2;#1L0%Uz@u`knL2#@`ZI5jEhkI+T)B==@3mn8xaQw^!DMclVK+CQg0r(B+TS5_ z&SZ!Ap6Q6VaKvIHf4)XlHsa;NUUTq!oQ(U+-$sniAJHPI!@@|jkNEIYx+<@pMAH?0@lvfhYbvt1%OBK-h z!>v@bkeiW0oB%2OfGffDR-VS|466%Jh>NkWaPPXeGwc!0I4@&<^U+feU4svBSvKBm znFVgHJ{RrN=#38e9G&oH5p&Z-zh%=BVZ4~X;~Bphjo*79&c(HVy6`8sPgc++4{8(-Tm zc)Ovpxn!(}+~)c&7)?N*%;My3&lrKL5k}4_1NXck<@7ww#bQT4aA9f`=8vuqXSB$4 zj{zSOOGP-E=p%fq9`K=-4?Om|o)97C@R0@GX(#wihfk~ZqM@*xzUm}=^}R2(K2zT) zh?a%ctm!M>HOPyd^Kk4Q*`G1_DLp%q=nlLbGk(F5ug5caF|44GzV1~vcJCm*PCzwH z9^4N5op;YS{uM1Dg09bD@GlTAt8D=L`)ke6i{JH6&;=J_dPj9O~uN_6{IR ziWZ93-p_NvV2yZA2&Yw@CG$f$Be7B2B+T)c+|$b^cd;D*pH2 zRR6Dx)ZjZa{ZBH^zji464bA=A)`b5&<78oA=J*?&Yn<|(aUL~~$Vx$$sK|>Gg|Fe* zSXViVXjUvea%!TY%4gc?K?Nc}1jWWp-lYV=L_)^;O%iMaK>W(j)e$}Q%eQWVTio2N zUf$e%^a*{NecSA-ZrSuaBe5hg&HApwT6ybv`n1M+9A=LcDX@1bx^eHf=C*f2@s3{JvYEsXj}*hqVB%au7e8@Xg61ak8fO?1AN$WMO)P2uyl0$xA6SmPkv**O1z9z3=g!&?cGJ4Hw*tWA<^} zuQ@Es0K@$IENZci@^x39FnR3k^_7>mlT?p9)&VbRlq8iyh}vOx={4{M&lN9Ojx39B z#`kGTEP-pf_d{akPg&z3X0USlGfkbICu}RV<;C+q0Agg$I`6E{B0eX63hj;kLI$XL zJXI2jm@Oo^mx#bKv(IDuGSlwWUH2|^=1LFjpQUaz+YHv;g4ee4unXog85VKN!%Su! z_s-kb2)lUUhC7u^!!zwJUv ztaDUTRl%Y7mCEMCT-Eu6;Tr4zD zV>?;xBP1>_aZ7#a-J}S#{NTt31D&moEl%stKb`isns)fUorZc8s!1cKm9o(~j{AWF z8R7dIotf-@_@ibW>Xr4*8BW94kS2w1*+U`BobwUgOy0pF%53DoU??+PWHabPwb z3eJMRg2`!jPK#jN5nQT67aBMMz#~sMG7(c?eE#V`Df?=VXZ&U~Bj)qOiIXkpfzf~~ zgPYdhZjn1k^Zi&jdbhQo$fLsOhWuP*{`0k$1;`G^j}tn9u&3JSACZn>Cy5gAVw^N_ z#>?Ria8H>LY^r!l*eBsv>vlgp93{W5dTk2yo?F=3yr8b^6O3^O^qZ{4Pxn3!xkAt~ zJA{E`->ETy#E>|!lTeeyZUxE;)DDwlP-j36C)PE>8`3Xu<=7A<{IH74{&+3x(q+_3 zfLdfjU~+!^XPZp}VhT7D$xN>rUqFL~1*rK1YrZR+2=XeSzXZfJv%KN&8F#TB`vfx! zi!!s^d?41mL4cQ1Oo?){<3R9z(U{{ZBla_{;rLnO{A;3)T|m(yM|4grxX=W0yHzMZ zXn3)SyW9P_KaDB^%Mt5efJCzPSN)y>vBP#O;6EZ~0f^SF?twcSXG+;LX-tUp=QJYu zWsAt&m7R@+l|3CkK0n0sfhn|n;-3k8X}e=@MANU#LPvDC245vHl9Ej1KQU%f%mr9S z*$yb+^KJ@q>WbDMLY4zso&$)Wqu}gd5?3OAt-b2ObPUT`a)5RNwv2OSc&ua7224C} zsXXLiY8e^!I&-N_UIAAlxqjRuZ?_KT=u&+zNdVS!yzCoT#jGdZP$2;3%*X}6UzdXB z_QpYLlFQKd;Xo1;J}mVg_wo%BvKC{J(2Wp6tD27q52S|ZhDsUd0dF=k9SP?ctB*=o z2H2vY=G4&oqj;A|enDwP!MSN+UZ3oT-0UG#H*DT$S@vLrRwTdARu7&hsL`ug&O*&- zuSBqsZqWsKw>oKCp)~~hF|Yr#!l7fXymmayFPKsd2f@$Px417{@%O;*39b(O#`|Tq zBw%#A^h~UnNyG0SG_NziOdM%+9F-ho^{1ehK_WK;U+@O_i^&^S(New0P#h?}Gp8T+ zwsH}cIWNF%)F70TMh*?4URj?@O#!I0iThzVXFUZwId{D zG|Ek>mRQWQ*Jn26CqFA<5;-dH4>=E|q?ZOZ#bxjtST^{NN#jrK5Z<=;a}BHIPOM!! z`(}7Ids}DgvJJROxatuF6B-cqyQdW2kJr54=WNg6I$&5Lbn2{nEo)V9mT{}5gK1x% z7h;}EedY{YNPJ)Sy*Fo~+6UbdHsijCTymdD)w;*LG^7`LkA)aFJ-&4=_R0mv z>KGL7x)_sRIhbD_9QKaG3p)$@A#+Y63!3))!{>EJ8?(eGwug3%_ZB~jS>c^3tMk$j z*ClL%M`)fLbOI9>tfWcoilJSJA67{uPv=@R@8jVYpie*0u zvriFN5G|(=U;-1S1rH0z22ZjpoZ0$d?c`_NW>PMu9r3E^8_M>7hOo_Vt2>~cDT;j1 zvA(G#?Y2(A74%sxVz!EVwp>asA0FR>jpM24)urA17}ij-oz<8!p%I-}E&{@(g&I9; z*F5d%8CGt85*h)VpK1&eO`XV&V&Tm2uHPY~UE5*5A!5k&E(pGU*V=j#gzl;flfNhavkI zj@_}2odaWcH_Alq&z_Q_leR3Usja;gt4W1X0Wi08-z#P}k%}{rJwWlhKb6LaGHu*o znjO+G&;j$sU84X(ZqsGo!_Gu9k9;GI!TazO7Jt}{smAIDR8!H*K|GXrT7T8qs%|>$ z?zJ+PYo$7x`w@7|l%b>J&?A9~5f+jH$aXa??XBY4W4cAtf>Qk@r_j6;#``%YOnaOs z;Vuc{je;iF^zJgJ3`{c{MKGX^ax~dgw>eDa=+ij$=S;Nz^NUcqRQwIfkE_+n(G*}U zTL;t*fYMG$deE5dm)yljvqm{OzE+dB&JWLd!0I_PcWA#X#(T-<91{z+i`j7$??$}e z@VqiZE_t)Y_7-KSvzU&J=3~d&%}!aouwplfP~vA<-O%)4V2(@!2iW|0(>1ZIk4kU8 zIQt>JC3=x*W++|h-jQZ4Yr^ufMO}rpm@LIB*a5iF1buG8w(Z6*FRvXjrLs+J*N=If08WphHG(ay z?3E{&R^oK(1ywD(lP`!lSTvMNe=pAYo}_JMj}d7SF+Exo;L+=)`BCx8D(bzsD-TGS zKPi#0M$C-MknT5}Umsc5Kf2DlHm1*+*egz5mHt{jw?_g+Av`PMTDLC0dymW-I%VE4 z(6$fUJd0Vhe^PL-6qI>$c3@J`S4lF%Rls7>Bn%vxndo4D_p%hyv#}lB_oD6~fm-zr znI#plrv??=SGs(|lvqPFv+eN4wVmU+P1!GR)UXcy0Qbn+wOSdy*klT}tD`sz)CfwW zpE_Nl(x4PI2H@B<`g)oiZv!L2gZ0|s`==@|`P#l-38i~0s^ zr}lugHmcIjLuy1MiAT#2lSuj|KmQ>z-eFOYEx`i%9r&UT;C2{)x=V(dwE;SLG&YoqZx_6+f(!+mioU2-|#2mmu&l;nvDmlHq=Im)h8PiI|O;Wb^?Pi@EC>OBRb z^j_KxO-fs^5rKz$LBHNH=);24@!0x%B*3lafz`63i2~dZQ*I4oHKF; z2#VZB#g2o2|XId;E4RO2}7^)7n-#7q%KXC2OoiK>?3DDGr4P5G!Y=J{&J zihRFtKt|1lBB(rVUdCLx_h@3R zmtYrrLnI6E@~N`mDVgDyFZrdu8=K-jn`ZqH>wCqty=qE>KzxaJSf#}r=cVOsGh>36 zU@(sAA7_v79*AFY1{MtJYnk$%F(<|b#fmq}?m_84${&Lm8c%2D2ihhNi-W2*858TY zooha@&Qta%rKR*}q9!%kbzV1QQprPHGvXcL#tZbiCst)1nl0U&VW)suj(~ z1Y_i(uCtnBixcwd7FW3{3-lqOg#>)p+{sPsS1O1+1V1@82nqFb@M{&jf>>yli`hz z!Jq?F2kFF+zpJNLx?vm~TukYy2MuW`j7sos?7T+Sep8?DO$WRfuA3j0GC4X8gojNz z+x+yGg;~nX+8MH%tXp)GTUB(T58e2@Pzf#6OE(MVu;U9C={rx$bVf>in_0cf?&|=j z0s@Ezu71{~PpOML^ss*F_Drhd+BShVh59z+`Z?BH%&$@UKZ!aeAP-dN@+)Io*@9JH z%9_^)UF;Zp4O$#-ATM*qkc5XdbODJ`!O7Ut~Zz1lq?0K?nR7-shiHFTZMDel@}V z3-a?<<%-LnsGq;+f&aN0a*W7f?(*P!{U)j9Va?zK}mogT~wAYo^j3uO~e%94_+=TJ5= zT({3kvk7AVc-DiluRKL+NXA0m6Wc85NBw#kFxh+0y&hkO{Je>X_Yrnwrrs%;kXWQE z`V%ELVb1_|Zh9&1XAI^YIIwEi_2tr!&CPoDt)V$kCYMMbU7mjLqZ+nZd*Y zrNvP*v$}gmb}yS~=oRx`NRKf{PUw%DO&|B@Y9$Wn4y`fe6c{r#8V?*fbWs;))!`;? zNw3&Bx@7}3$+KhzUMQL{DPJ6kSh;0G_c>2m*71LnzkwSpRKD z`)0d_$iq@U3_6wjEUkgIbYesXL70BnT&S?Pk~W%q-x)`eSQ)7!f++S+3AM`P%XHOq zw%%(Me$zfDbIs)yz4klEj?7~l6WtKsm_OpHi%A&BO^`N5xA&{V7-(#?5cNyvi{2v1$|Pj>$(%!sUZ6??o(w9a#qvux80R0g?G+!vp< zH%dLVGY|Q{JPnTXLz-hvgHo9bQzkC7s@&Z89k4AANA+h#%S0^Ld&MH zI#kFlNjKrk3xS7+qV_wFxf|}$HY0QQc~5x?&?a&u4yq?!y?2H^ncDs#Z!ERkq% z4A{$fTfH6Qj5l&<9mZm%aZa8>9)A72El-XAd5|WX6Af-0a@!q4h7H{8heDCveh-#3#I?v5ydE*F~eB_o=gAyrW(lmRYE6?qN72q_jdLok$M$ z2R(|RGk z<_*e@%hOnIkUKU@`}3WrZsHPp`*_}Z{MyXxBb7*f)iurIk*wB3g+B^JO0a`#CnoWvujxCTr_KlEEPR2aqz|&Khu7%W z55D`E3VNAaP-bTI2=&6oDDv$Ftm>K6{J(C1*htbI*09VP$ko7;47?(1G6jyFV$WY= zn>Z~U@KfKr0Xwod)fDQd&>(>OEqp!GpX4=a&)5N&OW?Bf|@jJ~51 z&WRz=#wX2dZ84Lb{eGeE?QpA?F1i~DsX`q>=7Yf_p=|*@HKea$*^kUN+(x2a@)tzn z^OAdd^wKOYy^XUdcsXrxMCeZJ1;--AaFqcPlZVE%?<@H>`XNtch0j$56H}vJ{Ahl0 zKdTo{@yWx$q1%^DRHdNY&1hi51(vnkFHm)@0C)b^&)`peu3Gy2T8fWyII#jB5AvZDCIcAEQ z60=8-d#M@lx>e+R>tTnxekl%Kl1pfR#`RSw(YCYu{x)f=1iBMaF6tv9nL4lA)>nL}4sr0_C_- zUjyHVZ>V`pa_k`daYyfp-&dS;e@0Pkxyj4Mx8I*>Xi0xBcHqQcanjpv+Q8KiEM^dg z-nc_Lid!fYn)EbTg0}eQr_XI;yIv?d{_!GGq_kPGLQ(4j->9A9PUSdNz&*;*rzNKk zhc$M@&vD#;F8K4K8U%#7+>i?>pbY{&1;xymbWg8^lJ#EkSozbjUhuj|(AA*C=I1+k z*J{<%NY=B>@9{;5t^Bmq^3_ZD0&Q}A{o`|y6bUSe*iu_5kE>uROZx1?$A*fEk7|>O zeGWsY^>ZB4%$%q*y`j9CIn=CX38WNpd%56`ILv3T8M))pey+?#Kfy}FTeQQ+%Fej@f}0Y}|KU+v&-}3D`RSO> z+AxWkk5rpJ5$DqG&=zB_xq10Zt&j48-jaz#Q3jDf+DI38M#hwkECkHjHu}X4v8#{Q z{ZW`I2gd9>&zi@orTbg;VLoq>M14B~{9Vsne~Oswo8V~%c*V|VF7(sj4&a56T~o*q zH^&ZU42d*EFRoZ(&8C^}k#FV8?NMQRp*#uv>ef2FrU|HTe($}uJ8QWD8;NKj65d^i z#11U0CBy3A|3+_AKi2i z<4--qPO%^kyDx7Ls@ zPACA52(O{sz<;x?fgAYuP#7`hw`~p3{}c)X5##>*wuXPOvJo2_e(|z@HKqT(Ui`Oe z@n50xKU&k9{-4_%ln{8#KP$xl9z3i3Ny_~HrQg35aR13U|69oXx8DE%d&mrias7RB zLyDT28nH>$C(?D6m=7a)0wGRB;slvuVeX+)?YJcOMC3}RC{3%Z>!#we%~Y-?olQS_ zTMJAX5)nWacm%_^D8i!R4g274#Y`f}*9MqZm%6Sb(|DbCQoK%OpB+1-@EoVu&mE?o zR=g=o7R0=V{FGX>P;-e!_C%!Y=&0eg=`uR8npC!OAi;mKV(XfQpdQ*yuzTG#iCpk6eMlyz`eCy?J!lga&y?b zA(I5<4)}O|(*7z(Gczd2-hlxoaX^;EqVg!NWNJ7@t*f0$h>BKULHRvJ*Fp)WE7?t= zjcq7`zFGZPEM0*)>YEib+g zOy=iZd9TuYIPq0uJWM=la(IM@el#))zG50?Waeg=ghAU~$2ai57HU;{wsp!-D~vtf zAai^-E#azApBpo#-xD$|!!18I_Q)LK7&I+)E@wSP(c{k}y`A}0p=pe#CxS<)R`F>r zZZ!IeRBSFZhqQ%sUc)ACtY-S~x$P36=O^mMf_F$%u6 zS*vZ|yULfg29q_huqvpe^1GjuXKSe9{5clMx_Ve;3|86OM~cxV=XNL`?+?)|XjBLq zAI&^CEeBp6>%W)8^{&Vrly;A082bQKQZ=(~n&s5Rf7_bMR!PY8o-j`?68iMu9_>c2 z_;gglvRD>F@n_ma2b%TCHMzYf>?LK3Sg$xQ!=G?s;&9IRNGEfLu7ZoKa3A%j(tJhc{xIhA z!oj>k7NHJN`jL#X44_g^@>epF#eA1qOU{j#gFmKMjV0_0UX`43v#!il+VHAseN%6p zv?cn|UIfB=^oE!YQ2FNhwLl=a_5EzVC2`*Z7X|9tI?7Qf+JUr#i@FNRhQa6OnIpl7 zwnVWiidIkb-6)jNT)T*tJmi57B=W$|5$LCs`mPUzk=O}E! zj%^5eV9=eWrMr_^kb?h7N`eRUw3aQUedWFyt`zHs=n$jQFGhsgZ@f+q^-EArI-cB5 zS}IeGk0I?SnMm^36T9>*ON%o(U|hg?DjOzyA4Zg*T05nx7xC7`&KuW*!E>Z+ZL`lP ziXK`DDa#hTY#!&Wt52DZy* zAqQonWfk3+5_KZ&XZc?Ek9B8kGa~500dzKks2x_cksl@zd05^FF?x9M2RJO5@iZNVSS2r^rN-kdT z1HD#8!j#dsc(na>kAGgmH%zgakdodP4$eK8vE`{d!-)pWuhivTC6@#6jyl7-WDMuT zn>h*Gu#FK60NZ>IHQ>Xq6yx<_T-cZ{l`K3Ug&ZkCw`lo9wf>-;MBXclOR5rn?cn(? zLHNB`T@#E(=giXG;EIB*4!GM}bP_!404voR^@)tIDtw8H3Ez;E_5Eh=f<*L*BTNea z<@GCj4E^auvxrDAZC%^v`Xm1(t7*daH!HB>&!Q}Dm?PW#2H1l^_ln6RN<&3Slmn)D z45Tcqu=P7-&`YUO3yzM$gDtiP0hLF64fyCkb**yV*ax^;u9wD-0f+;>zo0+Pc3N?G zFl+QdI{x%^r<#M;*qgp};U1WcFSb+Xz&yKeZ3KtYvwF4;+>$Uhq)kQN2lD9VlEtCS zQp_r()Ox^m*z9m`YVoenI^Km^SLv*wXqn(iftNOEqsNi!?b7T&q!<6)=!NH4asCG3MF;?(a4cQ(tzu1frTOw0TJzE z)Q+Eb3pGWsD)$PE0A!mG96X8Qm&SnwQN%&7B5Gw4+tN2fl6<#^uN5d=go1PzG0vQ^ zcD#=$Ce>z_zLuV0hWR+Cmw70pzaVNXfESQ{GhP_Lr?qGaXc`$BanEOf6@1`?acE== zG7Y6$GGxn)j+#JEzwJGoE}4)e%8jHGTMhW&80!3CC;%n0Zggl4Th(3S#FJ*<17l`e zq;cpERdrjY4Q6ug;~M*A#iJm?B6Q<(6PI$4u@LHff1Ty=oJ_603UoFs@tx`ACD+j0 zY67FQq4%L}_{JBR=8=9J5h30WWXh83bSiy@qm(K{VLt|`&oj86mlfj$We5GMkV(u- zJT^B$a^#qmbUc?6wCa`Mx?Gj43enMzR8rT^Nm#@^nU<9{itdRW;eSJV9nE9dG$D*i z(~ExtzMc@@Sxce&>6aAsglE8^0!LC@Hk`)ZH9}r`HlnH$Po_`YSKTCL58$z%OiTQ9)V zRX50y51cZrUC?yOGf)?zpRXA$ub8CsMr$Q&cLwR3XWW-0qC)g#v9YC$yrQ7H;;j-6 z%Sb4hJbR;6HcTB!Cz+m0X#*UE^skU8=i(@*=CYd(CJs3QR=bj-yqX?Bx9ncjtyPSK zy2bC{*?Vc!v*(G9Bx^=Z6Py_{$f#4II(sEa=<#x0nEI_9lW;TnC44%&8Tc4<-wK64 zDp-4vZhp^@gTH&zDIlG_ru`Izfk}7T25nVQ^frc)nDv%#mf&1$+kg``dHQl@aD7dq zX`)5yXWM_$XLRvGsh1~A0IH9YOvRl}NK=cwz@r-Zjl);Z>+zjh;Du#Gjma!; z1WB9au+x@d>qC0Rgs48VWSQFXeXrwG><1S2I)RH>Z7Am*`PqrvOVXvLP^O@m@)OhcyewRsc>*5Cdr*q zJQAhQv{OC%Fd=-5u}efe)@VG_)A+%uER+cdgnxKyZul|B-B4|qvYkjz5+=Ud(>Xw# zxs8DVz&DNpzG6;}^q*AYf$=dihWX_@ktn2FBo7yl>!sTB3DYRuPTWV~oY8P&ypV0l zc3Ebed(Em_Fd=^^S}QUhH3L2&$rt@> zcAmaNs_D{}b2yYeh;i`Pi_eXn{<82R;|PJtY?pAXJqXkK25s`eOQ)I^CAWJ0GN0#x zpY>ZGx8X<|Bm^`m$tC&wka@(02TP7H6B0%0U5a4w>&fCii&o5AgQ$`>u13x~FEs{8 zOJ_fDL;8=tqGX)-#E(4=PsW%-q?J)bY`;MmVv>+G3i_+jeX0kZQ_o+U!Ma*~V zGR?%K`U&G^dbE9y`0?$f$hFxa2%Hcy`|-{CfX~sal4`@?H7!P;6_0#)Pe*QgU8|;M zC`$-SNW9l*YKN$S6b_AuyLN>QQR~ZrQnQa`W#uB$7wciW%=~lJzG9QAa#6nbveKeTm@T9^v346-(qzVCw9=-N6WWlgyPX*Hvu*;E3x$G*9_MS3N4=y9lC&IxENZf zns8`%ZCot;8vO&5h_4f2t)r17{x+XUm80iG0vNh6*XGPD81^1`laak6sBQ0<(=RW_ z#zqj~XkQsy#|UB_ADzxHl!S?l1r}9NO+C_Az{hopciTAJD8o^B?MTy2K02$n-Z+ZwQ_tjsNJIQ&hoW4+hyBm zYirhAY*?F^FifA}>8bwHJSG$={nKrH6-RAA*fHQrwZ_aRnZ1SXd9N-5>-D&g`)4a% z$WhpAum^FVkYZ+o<~}f}?55cJkanHn@bk70sA_I!Ut8DeXu%p&yJB+>slrG7@))ng zV^4i1XI|2C*9rOx*)ijqXOvl3E2V|k(6n6klZ;~45AbtV@r`WZ(_#;015;{i>Qa8k zx+?wnH%X~@t@({>k*Bnr=dUzsmA!$rSC5Wj$;_6N0^K=;@SCu%!voL6Bd5}MvnAbgoyTWF!b z34j^dvVW>eZcLvh8(97YWD=sC6(Th#Ezma{O(|k4%!1pS_(`Y6)S*ktW%pyw7Uq@9 zn-EkFLCqx~Ye{fUfh3ERWbjNuKZ#=y*96_8xEJN%>FDHDyU1bNa+#z2?-ghn%Qa8I zyZ73YpJJeLB4M+_AtEIdddU_lsYJu`y=SFAuP5-`cRv)j-^^Z+WQSicii=3Lwnmcl zY)c20*q0SA0VxE(F|!d?O2kOEKJjMe8}16Xe2c@-^O_{;bI}TaBqn>6EopMK@6ZeI zs}xY#RhmPI6HSqa^g0ltGa8 z$6}vGnDD$P_K7SRE@UtU)<6MEZdnr971KkCp{C!z3XJ}sJWO-(_`Y0rwXUBwfoUGV zt=m$>AOZ9tYMxXnoBh;Zv8Hkfo!hE9Sg_-&@_7u@P0{5_7y{$DqWAg(0;Mi>khvFH zi~e~3rf_vleVrK3_X`$3aZ}*Uf&Gr$-1F?SJiAuPTCPB36ny$z^FcpJpE~``?}S8z z#oQRdJ6P$MQC*>tSV)M?i5f5t7$3Pq*ZOdsoulU?Vid~>l-}a(1Y>nH!9w**!P2{bufdLy$@5aYXU6? zMoi`j%&5RW&T2)DRzgx+(lrj#tm}hK3b6v*dxO^)O?3e__0a2 z(sMAgu@=#DFk%wnL7*ccoFE{W3qeW-LJ*(J*ckq&kCe}`x40ID{2 zh5$BzxSXPpp1zSK0FksXv~jivh$~9~fb5){h!+51kGYY713=DF&zjxN!T6sR*w``2 z{bd-tp`|521<|7sVH5zu{>w%|M+Z~H06{}5Gix&h0$b0)#*Uef&j@jPeRC`qJ0oK( z!~=b9ECl5I9|r&mfq)~!1^CDDB?im`hJrELEOLCpSNUOzc|~! z$q;W4h=f}*1a=eAvBIJpspYQLQi$_3%Pv%cJ5*lisk zFdTYY286)5Z|jAC?&<&{(&@LyA$C*%Z?7*x2Du{xfe}4jf47+v#&u_nxDd3|+w%+r zgCKX-7lBp1BLhLWZ(j>sAnrT9i(qL$ZrcI`ga3_Q$elF@f?$x_bB{RRop}a=IN^8Z zfcvfw0ioP?)*J|dAy6g1&lSQWIq&*2@UC7c_g!Cu!0%rB+#vAn-vNX}A-Crb2!`I( z3xv82nf0}ryvL?_nq%TpuZR?zxgu=21S&m{w_nf8vORWAk4et8xRl} za@&UxE`CQZlnZ`GFA&0Y=UM))*9Z$6H=iy*i&c38Z;01ibnHzUOT1HhqRW8(loObS2&z#(C6Yy&_T z4^Tin<`MyD@Is(Mh!x<5h=RpHLLy=?VNOA~AQTJ~<`M!6a|uHE{`&|mEX0E*dj~`> U+&^zxP=p&ovFPbVWyP@mAFusXegFUf literal 0 HcmV?d00001 diff --git a/intdoc/MPSformat b/intdoc/MPSformat new file mode 100644 index 000000000..cc1100fa9 --- /dev/null +++ b/intdoc/MPSformat @@ -0,0 +1,382 @@ +// An EBNF+ format. + +// This is a comment +// "xxx" is the literal three characters x, x and x +// 0xA8 means a byte of hexadecimal value A8 +// ::= 0x00 +// FunctionName() means the result of FunctionName when executed on parameter +// FunctionName ::= defines the result format in a text description +// [] means is optional +// | means either or +// { } is grouping of two or more entities together; mainly for use with the | or operator +// Entity names might be long winded but are intended to convey some meaning without explicit/additional comments + +// Version history +// V2.5 - 2004/01/12 20:49 GMT mrcb.mps.fmt@osps.net +// Updates to record signatures for MapSource V5.3 & 5.4 +// Update to incorporate the sketchiest of subclass details +// V2.4 - 2003/10/18 18:42 BST (GMT+1) mrcb.mps.fmt@osps.net +// Updates to route formats to include interlink steps (my name for them) +// V2.3 - 2003/10/03 17:49 BST (GMT+1) mrcb.mps.fmt@osps.net +// I must type really badly as there were more typoes to sort out. +// V2.2 - 2003/09/27 23:33 BST (GMT+1) mrcb.mps.fmt@osps.net +// Corrected typoes +// Corrected NULL terminated string length counts for records with strings +// V2.1 - 2003/09/12 18:23 BST (GMT+1) mrcb.mps.fmt@osps.net +// Changed some of the expressions covering the sections so that the LengthOf(x) was a less ambiguous x +// Corrected some typoes +// Added definitions of MapSource V5.0 (this creates data files of format 1.05, apparently) +// +// V2.0 - 2003/07/15 21:34 BST (GMT+1) mrcb.mps.fmt@osps.net +// Complete definitions as far as possible (in my ability, anyway) for V3.02 formats. +// Some typoes cleaned up. +// Replaced "unknown" by "UNKNOWN" in entity names where the meaning is not known to this author +// (as opposed to, for example, where the meaning is known but the value happens to be "unknown", +// as in the colour unknown). +// Added definitions for V5.03beta of MapSource - no seeming significant changes from v4 - woopee. +// +// V1.0 - 2003/06/30 21:00 BST mrcb.mps.fmt@osps.net +// First "release". Coverage for version 4.xx (to 4.13) is good although some unknowns still +// Coverage for V3.x is less good since it seems a little needless to document a format no longer +// in use, so why start to? Good question. Perhaps I'll finish it off when my MapSource 3 machine +// is fixed. + + +// Start of MapSource definition ================================================== + ::=
[] [] [] [] + +
::= + + ::= "MsRc" + + ::= + + ::= "d" + + ::= LengthOf() + + ::= "D" + + ::= | + | + | + | + | + | + + + ::= "d" + ::= "g" + ::= "h" + ::= "i" + ::= "i" + ::= "i" + ::= "i" + + ::= LengthOf() + + ::= "A" + + ::= | + | + | + | + | + | + + +// Perhaps this is software build number + ::= 0x2E 0x01 + ::= 0x96 0x01 + ::= 0x9D 0x01 + ::= 0xF4 0x01 + ::= 0xF4 0x01 + ::= 0xF7 0x01 + ::= 0xF8 0x01 + +// SQA might be Software Quality Assurance; buell appears in the beta, so is presumably the programmer's id + ::= "SQA" | "buell" + + ::= | + | + | + | + | + | + + + ::= "Oct 20 1999" "12:50:03" + ::= "Oct 22 2001" "15:45:05" + ::= "Mar 7 2003" "15:12:28" + ::= "Jun 27 2003" "10:12:10" + ::= "Jul 3 2003" "08:35:39" + ::= "Sep 24 2003" "11:44:25" + ::= "Nov 6 2003" "16:01:32" + + ::= LengthOf() + + ::= "V" ASCII-Map-Set-Name-can-be-blank + + ::= | + ::= 0x00 + ::= 0x01 + +// ............................ + ::= + + ::= LengthOf() [] + + ::= | | + + ::= "W" + + + + + ::= x-character-short-name + + ::= Long(class) +// Class classification - cf D154_Wpt_Type +// 0 = user waypoint, editable +// 1 = Airport, not user editable +// 2 = Aviation Intersection, not user editable +// 3 = NDB (whatever that is), not user editable +// 4 = VOR, not user editable +// 5 = Runway Threshold, not user editable +// 6 = Airport Intersection, not user editable +// 7 = Airport NDM, not user editable +// 8 = Map Point, not user editable +// 9 = Map Area, not user editable +// A = Map Intersection, not user editable +// B = Map Address, not user editable +// C = Map Line, not user editable + +// Valid for waypoint class types 1 to 8 + ::= country-string + +// Perhaps some waypoint subclass definition? +// The following almost certainly contains - this is the case for the V4 formatted file +// Vwip - added 0x00 at the end of this + ::= 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 + + ::= ASCII-Character-string + + ::= + + ::= | | + + ::= Long(0x00) + ::= Long(0x01) + ::= Long(0x02) + + ::= + + ::= Long() + +// Next three only valid for waypoint classes 1 to 8 + ::= city-string + ::= USA-state-for-waypoint-city-string + ::= facility-string + + ::= + + ::= 2-bytes-unknown + + ::= "W" + + + + + +// Values depend on . If class is zero, then +// subclass = 0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF +// (last two octects may be zero depending on whether the waypoint was originally created +// in MapSource V3) +// If class is non-zero, then values are unknown + ::= 18-bytes-unknown + + ::= 0xFF 0xFF 0xFF 0xFF + +// Perhaps the 2 bytes of plus Field-defined-flag plus a Long value + ::= 7-bytes-unknown + + ::= + +// ............................ + ::= + + ::= LengthOf() [] + + ::= | | + +// Note: for each waypoint that appears in a route, there must also be a "normal" waypoint defined + ::= "R" ASCII-Route-Name-string + Long(Number-of-Waypoints-in-Route) + +// Note: for each waypoint that appears in a route, there must also be a "normal" waypoint defined + ::= "R" ASCII-Route-Name-string + Long(Number-of-Waypoints-in-Route) + + ::= + + ::= | + ::= Word(0x00) + ::= Word(0x01) + +// Max values taken from all waypoints in the route to form a virtual "upper right" point + ::= + +// Part of the route bounding a 3D co-ordinate + ::= + +// Min values taken from all waypoints in the route to form a virtual "lower left" point + ::= + +// Part of the route bounding a 3D co-ordinate + ::= + + ::= Long(0x00) 0x01 + + ::= [] + + ::= + + ::= ASCII-name + +// The first zero seems to be a string terminator + ::= 0x00 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 + + ::= Long(0x00) 0x01 + + ::= [] + + ::= + + + ::= empty-if-class-is-zero | 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF + +// The first zero seems to be a string terminator + ::= 0x00 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0x00 + + ::= Long(0x02 + Num-of-Interlink-steps) [] + + +// These are optional additional steps between the two ends of the link +// Why MapSource creates these is unknown + ::= + + ::= + + ::= + +// Virtual "Upper right top" co-ordinate + ::= + +// Virtual "lower left bottom" co-ordinate + ::= + + ::= + +// ............................ + ::= + + ::= LengthOf() [] + + ::= | | + + ::= "T" ASCII-Tracklog-Name-string + Long(Number-of-datapoints-in-tracklog) + + ::= + + ::= + + ::= | + ::= 0x01 + ::= 0x00 + + ::= + + ::= [] [] + + ::== + +// ............................ + ::= + + ::= LengthOf() [] + + ::= | | + +// Map segments are portions of the overall map +// What is stored in the MPS file is not the map detail but references to the detail +// Area name refers to an area larger than the segment, perhaps by way of locating the segment within the World + ::= "L" Long(Map-CD-ID) Long(Segment-ID) ASCII-CD-Name ASCII-Segment-Name ASCII-Area-Name Long(0x00) + + ::= + + ::= + +// Common definitions -------------------------------------------------------------- + + ::= | | | colour dark green> | | | + | | | | | + | | | | + ::= Long(0x00) + ::= Long(0x01) + ::= Long(0x02) + ::= Long(0x03) + ::= Long(0x04) + ::= Long(0x05) + ::= Long(0x06) + ::= Long(0x07) + ::= Long(0x08) + ::= Long(0x09) + ::= Long(0x0A) + ::= Long(0x0B) + ::= Long(0x0C) + ::= Long(0x0D) + ::= Long(0x0E) + ::= Long(0x0F) + ::= Long(0x10) + + ::= + + ::= Double(Value in metres) + + ::= + + ::= Long(date-time-seconds-since-00:00:00-01/01/1970) + + ::= + +// Depth is not negative altitude - GPS not being overly useful on a submarine - but the "thickness" of a GPS point (e.g. airspace) +// Assumed to be calculated below the GPS datapoint height. If so, then the object being referenced extends from +// (Altitude - depth) to (Altitude) upwards + ::= Double(value in metres) + + ::= + + ::= Double(Value in metres) + + ::= | + ::= 0x01 + ::= 0x00 + +// Check out the values in the Garmin Protocol description document and elsewhere on the web + ::= Too-many-to-list-here-! + + ::= Long(latitude * 2^31 / 180) + ::= Long(longitude * 2^31 / 180) + +// Start of function definitions --------------------------------------------------- +Word ::= 2 bytes, little endian +Long ::= 4 bytes, little endian +Double ::= 8 byte, little endian, IEEE format +LengthOf ::= 4 bytes, little endian - zero value means "1 element long" +// End of function definitions + +// End of MapSource defintion + diff --git a/intdoc/SA2003_an1_dump.pl b/intdoc/SA2003_an1_dump.pl new file mode 100644 index 000000000..2145c48aa --- /dev/null +++ b/intdoc/SA2003_an1_dump.pl @@ -0,0 +1,267 @@ +#!/usr/bin/perl + +=pod + + This script reads a DeLorme Street Atlas 2003 .an1 (drawing) file + and prints various pertinent data from it. Anything with a variable + name starting with "unk" or "magic" or "zero" is probably something + we don't yet understand. Suggestions as to what some of these fields + mean are welcome. The author disclaims any liability arising from + the use of any information contained within this script. + + Copyright (C) 2005 Ronald L. Parker (babelan1perl@parkrrrr.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +=cut + +# Convert a longword to a latitude or longitude +sub decode { + my $foo = shift; + + my $intermed = 0x80000000-$foo; + my $deg = $intermed/(0x800000); + sprintf( "%8.8x %8.8x %d %06.3f", $foo, $intermed, $deg, 60*($deg-int($deg))); +} + + +# read a data structure from the input file. +sub shiftunpack { + + my $pattern = shift; + my @result = unpack( $pattern, $file ); + my $str = pack( $pattern, @result ); + $file = substr( $file, length( $str )); + @result; +} + +sub skip_bytes { + my $count = shift; + $file = substr( $file, $count ); +} + +sub decodeGuid { + ($a, $b, $c, $d, $e, $f, $g, $h, $i, $j) = unpack( 'LSSSCCCCCC', shift ); + sprintf( '%8.8x-%4.4x-%4.4x-%4.4x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x',$a, $b, $c, $d, $e, $f, $g, $h, $i, $j); +} + +# read file +undef $/; +$file = <>; + +@filetypes = qw( drawing road trail waypoint track ); + +# read file header +($magic, $filetype ) = shiftunpack( 'ss' ); + +print <bitmap$filecount.bmp"; + binmode BMP; + print BMP 'BM'; + $head = pack('lssl', ($fhsize, $res_0_1, $res_0_2, $bitoffset)); + print BMP $head; + $head = pack('lllssllllll', ($bmisize, $width, $height, $planes, $bpp, + $compression, $size, $xppm, $yppm, $colused, $colimprt)); + print BMP $head; + print BMP substr($file, 0, $palettesize+$size); + close BMP; + $filecount++; + + skip_bytes( $palettesize ); + # image + skip_bytes( $size ); + } + else { + # image information - the 'type' we read was actually the low word of the hotspot X coord. + ($hotspotxhi, $hotspoty, $unk1, $guid, $name ) = shiftunpack( 'slla[16]C/a*' ); + + # fix the hotspot X coord + $hotspotx = $rec_type + 0x10000*$hotspotxhi; + + printf( "Image: %2d %2d %s %x $name\n", $hotspotx, $hotspoty, decodeGuid( $guid ), $unk1 ); + $imagenames{$guid} = $name; + $bitmapcount--; + } +} + +# waypoint information + +($magic, $wptcount) = shiftunpack( 'sl' ); + +@types = qw(none marker line polygon text circle mapnote highlight + unknown8 arc spline rectangle unknown12 unknown13 road + trail track waypoint photo); + +print( "$wptcount waypoints\n" ); +while ( $wptcount ) { + + ($magic, $unk1, $lon, $lat, $type, $height, $width, $unk2, $unk3, $serial, + $unk4, $create_zoom, $visible_zoom, $unk5, $circle_radius, $name, $font, + $guid, $fontcolor, $fontstyle, $fontsize, $outlineweight, $outlinecolor, + $outlineflags, $fillcolor, $unk6, $fillflags ) = + shiftunpack( 'slllsllssssCCsds/a*s/a*a[16]lllllllll' ); + + # fontcolor is BGR (i.e. pure blue is 0xff00000, pure red is 0x0000ff) + # fontstyle is 0x10-bold, 0x20-italic, 0x80-underline + + # width/height are in pixels for mapnotes and represent the offset of the + # mapnote from the point (i.e. the dimensions of the tail.) + # width/height are in degrees times 0x800000 for rectangles + + # circle_radius is in kilometers. + + # Note that type appears to be shared with lines. + # type desc + # 1 marker (flag, dot, etc.) + # 4 text + # 5 circle + # 6 mapnote + # 11 rectangle + # 17 waypoint + # 18 photo + + + + $lat = decode( $lat ); + $lon = decode( $lon ); + + $rect_height = $height/0x800000; + $rect_width = $width/0x800000; + + printf ( "$magic -- %x %x %x %x %x %x %x %x %x -- $type $types[$type] $lat $lon %s $imagenames{$guid} '$name'\n", + $unk1, $unk2, $unk3, $unk4, $unk5, $unk6, decodeGuid( $guid ) ); + + printf (" %d height %d width %x fill %x outline %x fillstyle font %s\n", $height, $width, $fillcolor, $outlinecolor, $fillflags, $font); + + $wptcount--; +} + +# line information +($magic, $linecount ) = shiftunpack( 'sl' ); +print ( "$linecount lines\n" ); +while ( $linecount ) { + ($magic, $unk1, $serial, $unk2, $unk3, $type, $unk4, $name, $lineweight, $linestyle, + $linecolor, $unk5, $polyfillcolor, $unk6, $unk7, $unk8, $pointcount ) = + shiftunpack( 'ssslssls/a*sllllllsl' ); + + # arcs are 4-point (3-segment) lines: start, third point, end, center (yes, that's overdetermined.) + + # Note that type appears to be shared with points. + # type desc + # 2 line + # 3 polygon + # 7 highlight + # 9 arc + # 10 spline + # 14 routable road + # 15 trail + # 16 track + + printf ("--- start line --- %.4x %x %x %x %x %x %x %x %x -- $type $types[$type] '$name'\n", $magic, + $unk1, $unk2, $unk3, $unk4, $unk5, $unk6, $unk7, $unk8 ); + while ( $pointcount ) { + ($magic, $unk0, $lon, $lat, $unk0s ) = shiftunpack( 'sllls' ); + $lat = decode( $lat ); + $lon = decode( $lon ); + printf (" $magic $lat $lon %x %x\n", $unk0, $unk0s); + $pointcount--; + } + print "--- end line ---\n"; + $linecount--; +} + diff --git a/intdoc/SA2003_annotations.txt b/intdoc/SA2003_annotations.txt new file mode 100644 index 000000000..2a6bd437a --- /dev/null +++ b/intdoc/SA2003_annotations.txt @@ -0,0 +1,419 @@ +This is an annotated hex dump of a Street Atlas 2003 .anr file. +I've also added notes to indicate where SA 2005 puts extra data + + 2D 32 magic + 07 00 version + 02 00 00 00 unknown + 01 00 00 00 unknown (version 7+ only) + 01 00 00 00 unknown (version 7+ only) + +-- end of header -- + + 0A 00 record type? + 44 00 00 00 record size - strlen + 20 04 0F 11 ??? + 01 00 00 00 ??? + 01 00 00 00 ??? + 01 00 00 00 ??? + 00 00 00 00 ??? + 00 00 ??? + 14 40 00 00 ??? + 15 00 strlen of route name + 68 6F 6D 65 20 74 6F 20 77 6F 72 6B 20 62 61 63 6B 20 77 61 79 + route name (home to work back way) + 00 00 ??? + 29 5C 8F C2 F5 28 05 40 = 2.645000 (distance in km) + 6B 01 00 00 = 363 = 6:03 (total time) + 07 A8 35 6F 7B 03 69 40 = 200.108818 (overall heading) + 79 29 0F 3F ??? = 0.559227 + 98 38 0F 3F ??? = 0.559457 + 20 00 00 00 ??? + 01 00 ??? + +-- end of routefile header -- + + 03 00 00 00 count of control points + + 01 00 type? + 64 00 00 00 size + E9 F0 6B 55 lon 85.1567105054855 (actual point) + 84 43 6C 6B lat 41.1542053222656 + 11 04 82 08 + 30 04 0F 11 + 13 00 00 00 (19) + 16 00 strlen of address + 38 30 32 35 20 53 69 6C 76 65 72 20 53 70 72 69 6E 67 73 20 50 6C address (8025 Silver Springs Pl) + 16 00 strlen of comment + 38 30 32 35 20 53 69 6C 76 65 72 20 53 70 72 69 6E 67 73 20 50 6C comment (8025 Silver Springs Pl) + 02 00 START? + 9B FF FF FF (-101) + 9B FF FF FF (-101) + 01 00 + 7B F4 6B 55 lon 85.1566015481949 (point on closest road) + B3 43 6C 6B lat 41.1541839838028 + 14 00 00 00 (20) + 14 00 00 00 (20) + 00 00 00 00 +------------ + 00 00 00 00 + 00 00 00 00 +------------ + 01 00 type? + 4E 00 00 00 size + 8A B7 6B 55 lon 85.1584613323212 (actual point) + 9D 65 6C 6B lat 41.1531490087509 + 13 04 82 08 + 30 04 0F 11 + 1D 00 00 00 (29) + 0B 00 strlen of address + 4D 61 79 66 69 65 6C 64 20 50 6C address (Mayfield Pl) + 0B 00 strlen of comment + 4D 61 79 66 69 65 6C 64 20 50 6C comment (Mayfield Pl) + 01 00 VIA? + 9B FF FF FF + 9B FF FF FF + 01 00 + 93 B7 6B 55 lon 85.1584602594376 (point on closest road) + 46 65 6C 6B lat 41.1531593799591 + 14 00 00 00 + 14 00 00 00 + 00 00 00 00 +------------ + 00 00 00 00 + 00 00 00 00 +------------ +SA 2005 contains something like this here: + 00 00 00 00 + 00 00 + F0 BF 00 00 + 00 00 00 00 + F0 BF 00 00 +------------ + 01 00 type? + 72 00 00 00 size + F3 72 6B 55 lon 85.1605545282364 (actual point) + E2 4D 6D 6B lat 41.1460607051849 / + 15 04 82 08 + 30 04 0F 11 + 18 00 00 00 ??? (24) + 1D 00 strlen of address + 37 32 35 20 41 69 72 70 6F 72 74 20 4E 6F 72 74 68 20 4F 66 66 69 63 65 20 50 61 72 6B + address (725 Airport North Office Park) + 1D 00 strlen of comment + 37 32 35 20 41 69 72 70 6F 72 74 20 4E 6F 72 74 68 20 4F 66 66 69 63 65 20 50 61 72 6B + comment (725 Airport North Office Park) + 03 00 STOP? + 9B FF FF FF ??? (-101) + 9B FF FF FF ??? (-101) + 01 00 Is this a count of latlon points to follow? Should I worry? + D2 71 6B 55 lon 85.1605889797211 (point on closest road) + 71 50 6D 6B lat 41.1459826231003 / + 14 00 00 00 ??? (20) + 14 00 00 00 ??? (20) + 00 00 00 00 ??? (0) +------------ + 00 00 00 00 + 00 00 00 00 +------------ +SA 2005 contains something like this here: + 00 00 00 00 + 00 00 + F0 BF 00 00 + 00 00 00 00 + F0 BF 00 00 +------------ beginning of route coordinates + 01 00 00 00 route leg count +------------ beginning of leg 1 + 0A 00 type? + 32 00 00 00 size + 00 00 00 00 ??? + 1F 00 00 00 ??? + 00 00 ??? + 06 00 00 00 ??? + 04 00 00 00 ??? + 29 5C 8F C2 F5 28 05 40 2.645000 (distance in km) + 6B 01 00 00 363 = 6:03 (total time) + 07 A8 35 6F 7B 03 69 40 200.108818 (overall heading) + 00 00 00 00 ??? always? 0 + 00 00 00 00 ??? always? 0 + 00 00 00 00 ??? always? 0 +------------ + 0B 00 00 00 leg segment count +------------ 1 SS Pl + 0A 00 type? + 61 00 00 00 size + 11 00 strlen of street + 53 69 6C 76 65 72 20 53 70 72 69 6E 67 73 20 50 6C street (Silver Springs Pl) + 09 00 00 00 road type (local road) + 01 00 00 00 ??? seems to be 0 or 1 + DB F9 7E 6A BC 74 93 3F = .019 length (km) + 02 00 00 00 end time + 06 00 00 00 ??? + 56 F3 93 DD A6 FD 66 40 = 183.927 heading (degrees) + 00 00 00 00 ??? always? 0 + 00 00 00 00 ??? always? 0 + 00 00 00 00 ??? always? 0 + 00 00 00 00 ??? usually -1, but on first record it seems to be 0 + 00 00 00 00 transit time + 00 00 00 00 00 00 00 00 = 0.00 distance at start (km) + 02 00 coord pair count + B3 43 6C 6B \ + 7B F4 6B 55 \ coord + 50 49 6C 6B / pairs + F8 F3 6B 55 / +------------ +SA 2005 contains something like this here (and at the end of every leg; I haven't pasted them anywhere else): + 07 00 00 00 + 00 00 00 00 +------------ 2 SS Ct + 0A 00 + 61 00 00 00 + 11 00 + 53 69 6C 76 65 72 20 53 70 72 69 6E 67 73 20 43 74 + 09 00 00 00 road type (local road) + 01 00 00 00 + FC A9 F1 D2 4D 62 B0 3F = .064 length (km) + 09 00 00 00 end time + 00 00 00 00 + 29 C8 2B 53 7B 9C 70 40 = 265.780 heading (degrees) + 00 00 00 00 + 00 00 00 00 + 00 00 00 00 + FF FF FF FF + 02 00 00 00 transit time + DB F9 7E 6A BC 74 93 3F = 0.019 distance at start (km) + 02 00 + 50 49 6C 6B + F8 F3 6B 55 + B8 4A 6C 6B + A8 DA 6B 55 +------------ 3 SS Run + 0A 00 + 62 00 00 00 + 12 00 + 53 69 6C 76 65 72 20 53 70 72 69 6E 67 73 20 52 75 6E + 09 00 00 00 road type (local road) + 01 00 00 00 + 11 58 39 B4 C8 76 BE 3F = .119 length (km) + 11 00 00 00 end time + 02 00 00 00 + 7B D1 CA 13 65 7C C5 3E = 0.000003 heading (degrees) + 00 00 00 00 + 00 00 00 00 + 00 00 00 00 + FF FF FF FF + 0B 00 00 00 transit time + 73 68 91 ED 7C 3F B5 3F = .083 distance at start (km) + 02 00 + B8 4A 6C 6B + A8 DA 6B 55 + 90 27 6C 6B + A8 DA 6B 55 +------------ 4 Oak Bay Run + 0A 00 + 63 00 00 00 + 0B 00 + 4F 61 6B 20 42 61 79 20 52 75 6E + 09 00 00 00 road type (local road) + 01 00 00 00 + 06 81 95 43 8B 6C D7 3F = 0.366000 length (km) + 36 00 00 00 end time + 00 00 00 00 + EC 69 A6 26 E4 F7 70 40 = 271.493201 heading (degrees) + 00 00 00 00 + 00 00 00 00 + 00 00 00 00 + FF FF FF FF + 1C 00 00 00 transit time + 42 60 E5 D0 22 DB C9 3F = 0.202000 distance at start (km) + 03 00 + 90 27 6C 6B + A8 DA 6B 55 + 90 27 6C 6B + C8 C9 6B 55 + C0 24 6C 6B + 38 4B 6B 55 +------------ 5 Northland + 0A 00 + 66 00 00 00 + 0E 00 + 4E 6F 72 74 68 6C 61 6E 64 20 42 6C 76 64 + 09 00 00 00 road type (local road) + 01 00 00 00 + 83 C0 CA A1 45 B6 D3 3F + 2D 00 00 00 + 00 00 00 00 + 64 6E 6C F9 04 E0 70 40 + 00 00 00 00 + 00 00 00 00 + 00 00 00 00 + FF FF FF FF + 52 00 00 00 + 94 18 04 56 0E 2D E2 3F + 03 00 + C0 24 6C 6B + 38 4B 6B 55 + C0 24 6C 6B + 98 45 6B 55 + C0 24 6C 6B + 48 D2 6A 55 +------------ 6 SR 3 + 0A 00 + 5E 00 00 00 + 0E 00 + 53 52 20 33 20 28 4C 69 6D 61 20 52 64 29 + 03 00 00 00 road type (primary state/prov rte) + 00 00 00 00 + 23 DB F9 7E 6A BC C4 3F + 08 00 00 00 + 06 00 00 00 + C4 97 99 D0 11 7F 66 40 + 00 00 00 00 + 00 00 00 00 + 00 00 00 00 + FF FF FF FF + 7F 00 00 00 + D6 78 E9 26 31 08 EC 3F + 02 00 + C0 24 6C 6B + 48 D2 6A 55 + 90 54 6C 6B + 48 D2 6A 55 +------------ 7 N Mayfield Pl + 0A 00 + 65 00 00 00 + 0D 00 + 4E 20 4D 61 79 66 69 65 6C 64 20 50 6C + 09 00 00 00 + 01 00 00 00 + 17 D9 CE F7 53 E3 C5 3F + 19 00 00 00 + 04 00 00 00 + 59 EC C0 84 35 5B 59 40 + 00 00 00 00 + 00 00 00 00 + 00 00 00 00 + FF FF FF FF + 87 00 00 00 + CF F7 53 E3 A5 9B F0 3F + 03 00 + 90 54 6C 6B + 48 D2 6A 55 + 90 54 6C 6B + A0 F2 6A 55 + 68 5E 6C 6B + F8 12 6B 55 +------------ 8 Mayfield Pl + 0A 00 + 73 00 00 00 + 0B 00 + 4D 61 79 66 69 65 6C 64 20 50 6C + 09 00 00 00 + 01 00 00 00 + 87 16 D9 CE F7 53 DB 3F + 3F 00 00 00 + 04 00 00 00 + 13 45 4F 28 4E 4C 57 40 + 00 00 00 00 + 00 00 00 00 + 00 00 00 00 + FF FF FF FF + A0 00 00 00 + F2 D2 4D 62 10 58 F3 3F + 05 00 + 68 5E 6C 6B + F8 12 6B 55 + 68 5E 6C 6B + 30 44 6B 55 + 46 65 6C 6B + 93 B7 6B 55 + 46 65 6C 6B + 93 B7 6B 55 + 70 65 6C 6B + 50 BA 6B 55 +------------ 9 Woodbine Ave + 0A 00 + 64 00 00 00 + 0C 00 + 57 6F 6F 64 62 69 6E 65 20 41 76 65 + 09 00 00 00 + 01 00 00 00 + 8D 97 6E 12 83 C0 E6 3F + 6A 00 00 00 + 06 00 00 00 + 8A C6 FD 0A AE 51 66 40 + 00 00 00 00 + 00 00 00 00 + 00 00 00 00 + FF FF FF FF + DF 00 00 00 + 94 18 04 56 0E 2D FA 3F + 03 00 + 70 65 6C 6B + 50 BA 6B 55 + 00 8A 6C 6B + 50 BA 6B 55 + F8 36 6D 6B + 58 C1 6B 55 +------------ a W Cook Rd + 0A 00 + 59 00 00 00 + 09 00 + 57 20 43 6F 6F 6B 20 52 64 + 09 00 00 00 + 00 00 00 00 + CF F7 53 E3 A5 9B C4 3F + 0E 00 00 00 + 00 00 00 00 + 5B 80 08 FA F6 C4 70 40 + 00 00 00 00 + 00 00 00 00 + 00 00 00 00 + FF FF FF FF + 49 01 00 00 + 2D B2 9D EF A7 C6 02 40 + 02 00 + F8 36 6D 6B + 58 C1 6B 55 + 60 38 6D 6B + 10 82 6B 55 +------------ b Airport North Office Park + 0A 00 + 79 00 00 00 + 19 00 + 41 69 72 70 6F 72 74 20 4E 6F 72 74 68 20 4F 66 66 69 63 65 20 50 61 72 6B + 09 00 00 00 + 01 00 00 00 + F0 A7 C6 4B 37 89 C1 3F + 14 00 00 00 + 07 00 00 00 + 7C E9 DD FE 17 DE 69 40 + 00 00 00 00 + 00 00 00 00 + 00 00 00 00 + FF FF FF FF + 57 01 00 00 + AA F1 D2 4D 62 10 04 40 + 04 00 + 60 38 6D 6B + 10 82 6B 55 + 70 46 6D 6B + 10 82 6B 55 + 80 54 6D 6B + 10 82 6B 55 + 71 50 6D 6B + D2 71 6B 55 +------------ end of leg, end of route + 4C 00 00 00 record size + 42 60 E5 D0 22 9B 23 40 = 9.803000 + 00 00 00 00 00 00 E0 3F = 0.500000 + 9F AB AD D8 5F B6 46 40 = 45.424800 + 00 00 00 00 00 00 D0 3F = 0.250000 + 04 00 00 00 + 00 00 00 00 + 00 00 00 00 + 80 70 00 00 + 08 07 00 00 + 4C 37 89 41 60 25 89 40 = 804.672000 + 3D 2C D4 9A E6 1D 54 40 = 80.467200 + 02 00 00 00 diff --git a/intdoc/SA2005_dump.pl b/intdoc/SA2005_dump.pl new file mode 100644 index 000000000..e1c6fe765 --- /dev/null +++ b/intdoc/SA2005_dump.pl @@ -0,0 +1,156 @@ +#!/usr/bin/perl + +=pod + + This script reads a DeLorme Street Atlas 2003-2005 .anr (route) file + and prints various pertinent data from it. Anything with a variable + name starting with "unk" or "magic" or "zero" is probably something + we don't yet understand. Suggestions as to what some of these fields + mean are welcome. The author disclaims any liability arising from + the use of any information contained within this script. + + Copyright (C) 2004 Ronald L. Parker (babelanrperl@parkrrrr.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +=cut + +# Convert a longword to a latitude or longitude +sub decode { + my $foo = shift; + + my $deg = (0x80000000-$foo)/(0x800000); + sprintf( "%d %06.3f", $deg, 60*($deg-int($deg))); +} + + +# read a data structure from the input file. +sub shiftunpack { + + my $pattern = shift; + my @result = unpack( $pattern, $file ); + my $str = pack( $pattern, @result ); + $file = substr( $file, length( $str )); + @result; +} + +# read file +undef $/; +$file = <>; + +# read file header +($magic, $version, $unk1, $unk2, $unk3) = shiftunpack( 'sslll' ); + +print < 10); + + print "$addr ($comment)\n ". + decode($actual_lat).' '.decode($actual_lon)."\n ". + decode($closest_lat).' '.decode($closest_lon)."\n"; + +} + +($routelegcount) = shiftunpack('l'); + +for ( 1..$routelegcount ) { + + # read leg header + ($type, $size, $unk1, $unk2, $unk3, $unk4, $unk5, + $distance, $time, $heading, $unk6, $unk7, $unk8) = + shiftunpack( 'slllslldldlll' ); + print "leg length $distance ($time seconds, $heading°)\n"; + + # read segment count + ($segcount)=shiftunpack('l'); + # read segments + for (1..$segcount) { + ($type, $size, $street, $roadtype, $unk1, + $distance, $transittime, $unk2, + $heading, $unk3, $unk4, $unk5, $unk6, + $starttime, $startdist, $coords) = + shiftunpack( 'sls/A*lldlldlllllds' ); + print "$street ($roadtype) distance $distance heading $heading\n starting $startdist [$starttime $transittime]\n"; + @coordpairs = shiftunpack( "(ll)[$coords]" ); + + for $c (0..$coords-1) { + print ' '.decode($coordpairs[$c*2]).' '.decode($coordpairs[$c*2+1])."\n"; + } + @SA2005Extras = shiftunpack('ll') if ($version > 10) ; + } +} + +# read footer +($size,$f1,$f2,$f3,$f4,$unk1,$unk2, $unk3,$unk4,$unk5,$f5,$f6,$unk6)= + shiftunpack('lddddlllllddl'); +printf( "%12.6f %12.6f %12.6f %12.6f %12.6f %12.6f\n", $f1, $f2, $f3, $f4, $f5, $f6); diff --git a/intdoc/an1_road_types.txt b/intdoc/an1_road_types.txt new file mode 100644 index 000000000..fe3cb23b6 --- /dev/null +++ b/intdoc/an1_road_types.txt @@ -0,0 +1,52 @@ + +04xx Limited Access +08xx Primary +0Cxx Secondary +10xx Local Road + +Axes: + Toll/Limited/Primary/Secondary/Connecting/Local/- + Interstate/US/State/County/Farm/Indian/Urban/Forest/Ranch/Ferry/Exit/Minor/- + Unimproved/Under Construction/Approximation/- + +1107 .... + +0410 Primary Limited Access Limited - - +0420 Primary Limited Access Toll Toll - - +0430 Interstate Limited Interstate - +0440 Interstate Toll Toll Interstate - +0450 Interstate Under Construction Limited Interstate Const +0460 State Route Primary Limited Access Limited State - +0470 State Route Toll Toll State - +0480 US Route Primary Limited Access Limited US - +0490 US Route Toll Toll US - + +0810 Primary Non Limited Access Primary - - +0820 Interstate Business Route Primary Interstate - +0830 Primary Under Construction Primary - Const +0840 State Route - State - +0850 State Route Under Construction - State Const +0860 State Route Primary Primary State - +0870 US Route Primary US - +0880 US Route Under Construction Primary US Const + +0C10 Secondary State Secondary State - +0C20 Secondary Secondary - - +0C30 Connecting Road Connecting - - +0C40 County Route Connecting Road Connecting County - +0C50 Farm Route Connecting Road Connecting Farm - +0C60 Indian Route Connecting Road Connecting Indian - +0C70 Urban Connecting Road Connecting Urban - +0C80 Forest Connecting Road Connecting Forest - +0C90 Ranch Route Connecting Road Connecting Ranch - +0CA0 Ferry Crossing Connecting Road Connecting Ferry - +0CB0 Exit COnnecting Road Connecting Exit - +0CC0 Minor Connecting Road Connecting Minor - +0CD0 Unimproved Connecting Road Connecting - Unimproved +0CE0 Forest Secondary Road Secondary Forest - + +1010 Local or Rural Road Local - - +1020 Local Road Approximation Local - Approx +1030 Ferry Crossing Local Road Local Ferry - +1040 Unimproved Local Road Local - Unimproved + diff --git a/intdoc/jeeps-device.odg b/intdoc/jeeps-device.odg new file mode 100644 index 0000000000000000000000000000000000000000..c14bc30b72066cd772a5516a17cfac2048826206 GIT binary patch literal 9852 zcma)C1zeQN*QQ0Jkq{&Wq`RfNYY9n#r4|1B&DUhkw!rzMH=buZX^UGq~u%h zdiDBw|G#_o_r5#(&N{N_b-edD4*CTA1PKs|y`|*@A2>U~cvn zruOz=5YQ9`g4nS;+nKXLOrans8^qqi&Kv@CvbC^-u~|8q+FOHwQ1yQR!ZH39Qg})V zVrL1ma&o+ef^xA#VWu!AsF|rF`*%BZc(GTG{A~nJ-2a1}DG+D@wt&Mx9NB?Rj*eFz zxY~k|5!97#Tse+_bajKvzq>;M&;8vUOEAO~X7R(BEBoJ_`BNqAA@)x8@J4X@s}g^* zyZeXI>>VLijuy~gs{bd;Klyo8*w04$uU0S!1pL3PDF5Ik$kx=#0?IB4g4vqdL;puV z-GUnfA$G98`eH`ECv1uj_x&*=CL-&kFN4w>aM#RCy4X61n6V5i(Lh3}LPZ)MRr6by z(!u!g=1Z9TMSLY)Qtj)cmbe*v0jVC(bIXo})tw%C6?f()REvrFmCW}e_w-uK5_>)u zyF5L&3@_%#nVWt+5h81jUv8ZcRaAB_mTn6vj z5gh^}kIeVliqfxDLV9A}*cnBrnA)&79fS9V&$|@$-h~MoCy^={A!zfbaRQb?<+tu2 z4-efXKKSrLMY0^{cr=q?KWM3F>~X~r-V(GOtGQpJJhWLOD~{bQvtqG>`er00LD&n! zyipYeAC-%jH8n~TTq*c=m{@GP10}1;=;}W9beugzgSJOs-zJikKj!`HEvRo|*Ug<% zr$#8omlsUAS;@#oM1J^uT_$<8%`|qhMg&;opiLV6v1I!2 z^uh-a#=Cu}aLAj7x{&A&(-dh^7^dnSq64Nl|Ke z>h2jvMBDnn!rgcxH-W*vQc5W>C>(YJV@pa?$1(SfNj@f0kRux-?(gL`-F1ztNyuHky1yig?F*(}a> zsu)rP-M!C*AopTkOJJ6;S%LFXTwuK5%^|@W*p|F+{4r_Qr$M7^2ex>Y+c%Qm`5oF!G)ZmBR`h+t+D4Y8mpd9i5)AKDUdOTBbBP+EL!E@NO)iQh0c$`03?ItplLC z{PO~)^K1#ShkweG*<3*EFf}_W;=cHX-jpJ@*-c-WTkmOgfNbk>yH2>Ch0h+W?A&^` z*Nd9Pn(3DfmJYl3F!}?dIPGRY6qyZu3`-NB45VrHFlu2_s-uBKl5O7(Kcf*9k93Y! zvauC+zki+{kJK2G`jUR{juCbmS@F=)3u>OK0U>f@+>EKBA-hX6T+~Op8Kb#{x5|em znso>OM35wjks{IQd^_37B8x`=jDvcmd7x@dBDs$3!~fBk3s z#LIEyow^1~Qmj5nZs~7&=EAozc}xr`PdYoYi|n5Py>o?fxCE-i_Z#yqQO(7twg{9>=LB_i!JhF`;!WaPFO)^82&@DI#k?3!GBdIo+M z*8+GE`*MVrEh^lsx4CvL4NJ)$@S2d~zJ2(^*v7y;zTNur`F9`c9V`|Oo5}se=c^ge z$xKD7)yfyHxc>Z`07j(>K{*y6N4+=e0VKgIP{EcSf+~y_jue%n#mhjret} zu>tgBFe3N`ur!nsgk%!;x~M)CXr}F%KcEUVF1StMwT$f~koaP?i)1KKY9TIGN)F|O zN1$fHK|(;$$FplvBugREoeFxC+Ls)5DfM-i@@l1)m3Wa&g@%CeoZ-hx{ih8827F;Q`qgh zP{M@+n?Nr!YCkoeOcT`j_T>byqRT@n6gOWiu>y$3l~#*xRI& z#=GOiewIpumfyB>{N@bdjBb(E208RgHQ!p>yM$1MqcBQ4#L<`@gwUa6Xw03(9oo(&V&e#8w1^sP1OEc$nVJ6T5 zoBaTNMHuNVMge$Xi=iq1HTU@<0!DHx8eJOA?MN~`bbAaXGFO_l$|%|u^zj+Xn60J~ z|F?P=tf>RYZ{960i#9&b6PD$+Q;?6AMGY47d7dryRAPW$DO5}W#cb)89%&zc?Hqyc?u_qKlXM}bnR8|trj+vA z0vy9p9Wplaw!A~gaPwH16j3pb6tP03tTj0py!PMrXfs)J1}QZf*78M_<;xr$! zpw{rR>ghYN=G#t=2E|B?m=)~OihR&o&c$p&O!qkvA74px;*Z|zLw-ITyoMWsM7UuS zcxFjeiPau%(_EeOZM{P*H^bs~3G>`r#l{K4K)wx89QN1Mh4BTPyW^X9#KU|GxTc2s z>S57|Y;o@?{Re#ra07kwTYvdtXk&jzW~D`r5q{Wh^t93het zRGD&Q6|SnP)aBSt_cmLA%&$2%2JxPrEOvfjkOghrA3<0pyRFkaO5aSvC56{2Fh`+$ zs1eEHF#j;=^5QIfBIfN*UN+hLc>Z>4sWL(Oto*y>Rj&8F>eXiO+FWt&WQj;~D|B}B zv`vaXiSj`@I7Wgg1gV2f%NDqD)G#tHL}+-#?nv%*d%Q$vRSoQ4Ns?Y)G)H$UZ-pl= zKH?@eD0qq{W2f;a=CP~!_b-O7ZmitIb5C-cbW%kdXg!X3#q0QlqO!I#ZT1ODTGH5E z1Jg30gSGqLJj(=j$K01@0-aaKTI!xRvuCio z68md9>ZK1FBi*2KU|OlnULEnK4MQO;^I-Xn+km{g6QH-gso`}HQ7LB zZm#QfL9#G^Eg{ghRaKD(^q)7YG8UK6WZM=M2}LS3)ebvP#X;Uo4%(~>Lq$j#-E z5YJKLwT`2CL2|b|ijCoWDel=;zWvwVfN+edTv;$tCh?7_2E(O7xS`5IKrZRp^(~m2>3zHEXsyHUSYA0okR30i-P54V*d(`9lxm z)>amZH;u0Asrj*D2J1wuy34pr5<6mq1L)6qve@xT-K}i4EM66KX&5=%#1tAmE6ApB z&~15q3v@PnR(T?~r&;K#JN6Dk5^;)X-)mc*O9%NPyf18`X=qL1;#gGH;`}=L-DGswZ3h!{nGv$%_|hkze5D)cvlI3?kapat)JZ1A)4g*Ee4eYz zBAQ(w@Z4jQCk+z2+`FOF5m&bE8=5|eaOte1&^BXqvgzM1zI71(zJ-uBG+Riqcru(B zg+WCCJGNtN#I{u@HUjqu;YD)6*Pg(0J}5H~fuw>YiuKW6Rqt0@G_Y!*c&GWPpw8!^ zFZW+iJD?YdZkCP}5)zlc9V%=kZOYoA&7CO{?bD2&rw9|yf03f;IB~qKp1$0M;rh5_ zH_4s9TJf8ws3^P83_>@PBso2DhoRx#2jR2B|@XECCe&6 zBPNO=46(EX0WE}nkQA(NHp7$(ZfXY=`kp013bWLXn*_ql}K!spHpFCmSdG58W#d|Ep71y1%+)4<{4gfY;p0f5rIK=2t8T1oF4jSMBk=xvpL3 z;^5$6|Ni@j*HBv!_`jBTrOOJ0*xJMWGy_}wTBxZV$o9X&T1Uj_d5_@BDw ze^GLx>ROz9DqMna;OpA`F#0?HyO|Tz!jaY7!V+X>VNP|ec=hs#&?wkhLZ~=t*#Bzm z|Eb3H-_*GOn;OsGYJb1%SKJ~93IhSZdk8VR>PGm;bFzcMrwslpgTIEc&{Y+F{`wo? z`tiRLlUK}~mbH_unVl&J3}uJ?NV3`6S;c691g36~j1f3w(}e}}+RD68cN&fi*soGd zF`{E)0PwtEHi&4ME|Axv&63xafADftPaE%>zOA*0tu&?qk2Z8nkXUChIFwijHuZfR=D?F$>F_?BrajRZz1 zysAsGtm5s%BJiXOR2=1wi5sxzsmU;Bk-zVGq0u0CQZXh3@&Z4$8WS`vm!XQu#)#@g zJKdob4^{2B#Ccc|-;B-8UYsN?OE3UD_9cT5J{86t5Czz+4z4WfAS^<0+7=}=M$;=7PtK`&BmVbD+3%%+8!SjK?g>SC?b@|h`SWM))mtg=hb9vI$5DkNW9|1!Ua)!-(ts7BwndK}~y z6ru++$H!|?>`teX{^!MPT4*|{NBH3Lw6-eVzqI!hYzFczwM0$n5uCtZ;vUP*2A*~*sYKoK<$E+z7ZQx7P& zS#6TT#)I}k?zfc9B;M=OiffHv=tOt0wv)ZhRcxmgj=njXr5I0 zK%n%aK=*1+M`NmVVa{GE#?v-(@M&)y<4|xV{^0A_TuY=XVy4_sD(Q6tW|Ee5x0_6o zDj7yjy2Qe_{6C9-fMMctf4JYQ#dt<_;?gEc~ubM?Ttqv zsn0&)#n31&j|Yiy?PBQ1iaI+;9^ueAYTZxYm0Bfn5#u*z+na)=jwW?Q(PVXbGBJ&4 zx?V)_xL2fD+DzK!7*~?7(^D7dJp+ZMXAQoxmoH)Hx>q4bWEr>I39}xpdg`A#<4HQE ziV@!SWtGCx?PH_!Y2Nvc@?krOdu8o}EEVE@jBCyh2n4W%qcCwG;)O&-yRBu%CVWz{ z#F)xc=c}K7J}~r2Ry5{5Jr!?tGQk<8_j`kqRetog{ZPI0yC3K|Y^fjU)A5y+tGtI^ zz$U6BW?hw43UqT$y~u@8dq|-Rh_eIrhhM%_nO%gLNRA9ASOv6<<}WEbN+GpV?s)Na z59xK0RI2i^7=U=aMbz^zMc2JBGNHGH$3phzz1>Vnw7{q(N+SYiK{zM+XVn1Z z>q0RS`PG3(2`#n6Em*Gn^?ZHeY!y!w?c+^2VC0cop}1tn!YjAGp3Yb2xOw0-ZX=g{nETawqkB>!z%;BaKOEmk07yt}15hzn!SwxcxDR)UV%|Jgg!m@bh)z@J5W=dM*K*F~?(b0CW-|0L*OXt_A}o*2 zODbg^q7&YPpI+QR*AYto6o-m{&;Y;weR9WyPwr3)*wspUO*_r#PdP3M;CjuK%J0?4 zfIBRZVmK_Q=xIOL2kg=tAVqgX=|(M;J!*L4qbI4{G(IpoydUAsnj-4uP*}TgdR8c> zYK%)9Kaga&Fx;I&^@%HRW09Vpbn>Kd`nZ#F3@qBt#w4|hMv=+I9uaL5B%m>s&rk}P zTSijt!bE53yzMFZ!k%h$n>$O5 zBf5+B>*9*r0vGo=dD9CEnv2B|?Tzz?=XE#Eg>!N1X{y+7`F-pSK7KX6PzWT+D!X}X zjqy>Nc9}`T@b;iyW+Nv!I8@|lp1chmiAOg9nMR$+Gl{zfvQ#P#2}VTy79pdF-Ka!i zF8%o#stxk{4_fO4_!qXO!PvoHk+?7HQzMvdOW17U1}#2O4`wOHp)6vn%SV*SqwA11 z^J5qt=Jqz4rBm=aj*D#En~ycY0Z?hgMQVd9V{532R$*2G;NPlHG+ewXLa>TPnm{l9OX^m66`t z5^3FPoW((3OrsFk*vm4!Nbg;^cBT`zER5=i}KOlz}tCa zcU{Y%yTTEjgx;U!ERzQT{(VF>&C3snpQ75`7G{xW2?N9?U0#MQC#{Ap(|C~^1HEs- zBD^xbvgWK@qKb8kkku43E%~;v_i>TXNs4w05x}&tDJv@zDubsapPFoTk8^H=?(gE> zh;s1CO&GfVl5J{x5L#E+;$5UX2Q(3JSChAv`F%{3bdXavU zcL+~gqN#NT^f6;92~l|;$!B>ltMbs#yM3jtw0oLm?tWpUcpWzF*Hgz=!8w{R62GQb zb3z7^sj1vk=iz6;e9fq)iV7Xn0ML=%C{SMIU6nze zw_X<1s(W8y7IubT|EYE(e#GbDCpt6$z7!M}H@^zY+_5KS1&oGU7@%3Y_yV@P;|=4j zHBaCx7Nb&S^+DW58;Sv7*#v8_$gUW~b+r>_o&d!Y28>%R%vA5Yxed`3&{8FLLkebwOsjjDv zy#?RElWcE2zRiWp7Kgc&!x_ ztyA76@H|u||6nM)li-N{HZ)K47m%!?A#mxfX3) zdB$9-${C(Z&ZJ5wL=%mTN?vVgyEath<*+$+T~e zoot)yi)s!vM5hdzQ#~!^BOA)*P7a%;iTXB-hDQ) zYn}(G{5gRHA_9Ucoa<3nLPWZa@b8f)@Q(OJe#D{tZuN@_!c}C(PtkxUe~<3?HQ3~P z>A#*f{fHR33OD&FLGa}7IR6rS^1qzB`m6X;=HbcTL4Ssx{Ig+xS|R*aMIv}p{*Ll% zD9XR%Tm_^26xBcB{3A5w-;w@VufRVb{R~z4uPE>TfbuhR<=;`Rf>(aZ!5>imUnt9W zupgt~*VD+WV3wc42_GE5pP?;3disaquLS1RVdYN=hO?GGk1l`MUFBZ|7X40d{t)r9#| d4ygWR`czj!g`e^wAmG41JIDwKt~6J_{tq!GNB;l- literal 0 HcmV?d00001 diff --git a/internal_styles.c b/internal_styles.c new file mode 100644 index 000000000..b370c6e90 --- /dev/null +++ b/internal_styles.c @@ -0,0 +1,1112 @@ +/* This file is machine-generated from the contents of style/ */ +/* by mkstyle.sh. Editing it by hand is an exeedingly bad idea. */ + +#include "defs.h" +#if CSVFMTS_ENABLED +static char arc[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: GPSBabel arc filter format\n" +"# Author: Ron Parker\n" +"# Date: 17 July 2003\n" +"#\n" + +"DESCRIPTION GPSBabel arc filter file\n" +"EXTENSION txt\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER TAB\n" +"RECORD_DELIMITER NEWLINE\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" +"IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" + +"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +; +static char cambridge[] = +"DESCRIPTION Cambridge/Winpilot glider software\n" +"SHORTLEN 8\n" +"EXTENSION dat\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" + +"IFIELD INDEX,\"1\",\"%d\"\n" +"IFIELD LAT_HUMAN_READABLE,\"\",\"%d:%06.3f%c\"\n" +"IFIELD LON_HUMAN_READABLE,\"\",\"%03d:%06.3f%c\"\n" +"IFIELD ALT_METERS,\"\",\"%3.0fM\"\n" +"IFIELD CONSTANT,\"\",\"T\"\n" +"IFIELD SHORTNAME,\"\",\"%s\"\n" +"IFIELD DESCRIPTION,\"\",\"%s\"\n" +; +static char csv[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: DeLorme SA 9.0 CSV\n" +"# Author: Alex Mottram\n" +"# Date: 12/09/2002\n" +"#\n" +"# \n" +"DESCRIPTION Comma separated values\n" +"SHORTLEN 8\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMASPACE\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" +"IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" + +"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD DESCRIPTION, \"\", \"%s\"\n" +; +static char cup[] = +"#\n" +"# (c) 2006, Robert Lipe, based on sample files by Krzysztof Wojtas\n" +"# Reference info: http://www.seeyou.ws/thankyou.php?fname=cup_format.pdf\n" +"#\n" + +"DESCRIPTION See You flight analysis data\n" +"SHORTLEN 8\n" +"EXTENSION cup\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS ,\"\n" +"PROLOGUE name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc\n" +"EPILOGUE -----Related Tasks-----\n" + + +"IFIELD SHORTNAME,\"\", \"\"%s\"\"\n" +"IFIELD SHORTNAME,\"\", \"%s\"\n" +"IFIELD CONSTANT,\"\", \"\"\n" +"IFIELD LAT_NMEA, \"%f\", \"%08.3f\", \"absolute\"\n" +"IFIELD LON_NMEA, \"%f\", \"%09.3f\", \"absolute\"\n" +"IFIELD ALT_METERS,\"\", \"%dm\"\n" +"IFIELD CONSTANT,\"\", \"1\"\n" +"IFIELD CONSTANT,\"\", \"\"\n" +"IFIELD CONSTANT,\"\", \"\"\n" +"IFIELD CONSTANT,\"\", \"\"\n" +"IFIELD DESCRIPTION,\"\", \"\"%s\"\"\n" + +"OFIELD SHORTNAME,\"\", \"\"%s\"\"\n" +"OFIELD SHORTNAME,\"\", \"%s\"\n" +"OFIELD CONSTANT,\"\", \"\"\n" +"OFIELD LAT_NMEA, \"%f\", \"%08.3f\", \"absolute\"\n" +"OFIELD LAT_DIR, \"\", \"%c\", \"no_delim_before\"\n" +"OFIELD LON_NMEA, \"%f\", \"%09.3f\", \"absolute\"\n" +"OFIELD LON_DIR, \"\", \"%c\", \"no_delim_before\"\n" +"OFIELD ALT_METERS,\"\", \"%3.1fm\"\n" +"OFIELD CONSTANT,\"\", \"1\"\n" +"OFIELD CONSTANT,\"\", \"\"\n" +"OFIELD CONSTANT,\"\", \"\"\n" +"OFIELD CONSTANT,\"\", \"\"\n" +"OFIELD DESCRIPTION,\"\", \"\"%s\"\"\n" + + +; +static char custom[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Custom \"Everything\" Style\n" +"# Author: Alex Mottram\n" +"# Date: 11/24/2002\n" +"#\n" +"#\n" + +"DESCRIPTION Custom \"Everything\" Style\n" + +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" +"FORMAT_TYPE INTERNAL\n" + +"#\n" +"# HEADER STUFF:\n" +"#\n" +"PROLOGUE Prologue Line 1 __FILE__\n" +"PROLOGUE Prologue Line 2\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS:\n" +"#\n" +"IFIELD CONSTANT, \"CONSTANT\", \"%s\"\n" +"IFIELD INDEX, \"\", \"%d\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" +"IFIELD LAT_DIR, \"\", \"%c\"\n" +"IFIELD LON_DECIMAL, \"\", \"%f\"\n" +"IFIELD LON_DIR, \"\", \"%c\"\n" +"IFIELD ICON_DESCR, \"\", \"%s\"\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" +"IFIELD NOTES, \"\", \"%s\"\n" +"IFIELD URL, \"\", \"%s\" \n" +"IFIELD URL_LINK_TEXT, \"\", \"%s\"\n" +"IFIELD ALT_METERS, \"\", \"%fM\"\n" +"IFIELD ALT_FEET, \"\", \"%fF\"\n" +"IFIELD LAT_DECIMALDIR, \"\", \"%f/%c\"\n" +"IFIELD LON_DECIMALDIR, \"\", \"%f/%c\"\n" +"IFIELD LAT_DIRDECIMAL, \"\", \"%c/%f\"\n" +"IFIELD LON_DIRDECIMAL, \"\", \"%c/%f\"\n" +"IFIELD LAT_INT32DEG, \"\", \"%ld\"\n" +"IFIELD LON_INT32DEG, \"\", \"%ld\"\n" +"IFIELD TIMET_TIME, \"\", \"%ld\"\n" +"IFIELD EXCEL_TIME, \"\", \"%f\"\n" + +"# EPILOGUE: \n" +"EPILOGUE Epilogue Line 1\n" +"EPILOGUE Epilogue Line 2\n" +; +static char dna[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: DNA Marker Format\n" +"# Author: Alex Mottram\n" +"# Date: 12/09/2002\n" +"#\n" +"# \n" +"# As defined in dna.c\n" +"#\n" +"#\n" + +"DESCRIPTION Navitrak DNA marker format\n" +"EXTENSION dna\n" + +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD INDEX, \"\", \"%d\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" + +; +static char fugawi[] = +"# fugawi XCSV style file\n" +"#\n" +"# Format: Fugawi\n" +"# Author: Robert Lipe, Patrick Ohly\n" +"# Date: 07/24/2005\n" +"#\n" +"# \n" + +"DESCRIPTION Fugawi\n" +"EXTENSION txt\n" +"SHORTLEN 10\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" + +"PROLOGUE \\# Latitude, Longitude and UTM coordinates are in WGS84 datum\n" +"PROLOGUE \\#\n" +"PROLOGUE \\# Every set of data contains the following:\n" +"PROLOGUE \\#\n" +"PROLOGUE \\# Waypoint name\n" +"PROLOGUE \\# Waypoint comment\n" +"PROLOGUE \\# Waypoint description\n" +"PROLOGUE \\# Latitude in Degree and decimals (soutern hemisphere has neg. degrees)\n" +"PROLOGUE \\# Longitude in degree and decimals (neg. numbers: west of Greenwich)\n" +"PROLOGUE \\# Height in meters [optional when importing, always present when exporting: Date (GMT) as ISO YYYYMMDD, Time of the day relative to the date as HHMMSS\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" +"IFIELD NOTES, \"\", \"%s\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%-.7f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%-.7f\"\n" +"IFIELD ALT_METERS, \"\", \"%-7.1f\"\n" +"IFIELD GMT_TIME, \"\", \"%Y%m%d\"\n" +"IFIELD HMSG_TIME, \"\", \"%02d%02d%02d\"\n" +; +static char garmin301[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Garmin 301 Position + Heartrate data\n" +"# Author: Jeff Kalikstein\n" +"# Date: 08/29/2005\n" +"#\n" + +"DESCRIPTION Garmin 301 Custom position and heartrate\n" + +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" +"#FORMAT_TYPE INTERNAL\n" + +"#\n" +"# HEADER STUFF:\n" +"#\n" +"PROLOGUE Garmin 301 data __FILE__ \n" +"PROLOGUE Timestamp,Latitude, Longitude, Altitude(ft), heart rate\n" +"#\n" +"# INDIVIDUAL DATA FIELDS:\n" +"#\n" +"IFIELD TIMET_TIME,\"\",\"%ld\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%f\"\n" +"IFIELD ALT_FEET, \"\", \"%fF\"\n" +"IFIELD HEART_RATE,\"\",\" %d\" # beats per minute\n" + + +"# EPILOGUE: \n" +"#EPILOGUE Epilogue Line 1\n" +"#EPILOGUE Epilogue Line 2\n" +; +static char garmin_poi[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Garmin POI\n" +"# Author: Robert Lipe\n" +"# Date: 10/07/2005\n" +"# Reference: http://forums.groundspeak.com/GC/index.php?showtopic=110641&st=0&#entry1752204\n" +"#\n" +"DESCRIPTION Garmin POI database\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" +"SHORTLEN 24\n" +"# PROLOGUE Longitude,Latitude,Name, comment\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" +"IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" + +"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD SHORTNAME, \"\", \"%-.24s\"\n" +"OFIELD GEOCACHE_TYPE, \"\", \" %-.4s\", \"no_delim_before,optional\"\n" +"OFIELD GEOCACHE_CONTAINER, \"\", \"/%-.4s \", \"no_delim_before,optional\"\n" +"OFIELD GEOCACHE_DIFF, \"\", \"(%3.1f\", \"no_delim_before,optional\"\n" +"OFIELD GEOCACHE_TERR, \"\", \"/%3.1f)\", \"no_delim_before,optional\"\n" +"OFIELD DESCRIPTION, \"\", \"%-.50s\"\n" +; +static char geonet[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: GEOnet Names Server (GNS) (http://earth-info.nga.mil/gns/html/cntry_files.html)\n" +"# Author: Olaf Klein\n" +"# Date: 08/20/2002\n" +"#\n" + +"DESCRIPTION GEOnet Names Server (GNS)\n" +"EXTENSION txt\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" + +"FIELD_DELIMITER TAB\n" +"RECORD_DELIMITER CRNEWLINE\n" +"BADCHARS TAB\n" +"ENCODING UTF-8\n" + +"PROLOGUE RC UFI UNI LAT LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD IGNORE, \"\", \"%s\" # RC ( http://earth-info.nga.mil/gns/html/gis_contryfiles.html )\n" +"IFIELD IGNORE, \"\", \"%s\" # UFI\n" +"IFIELD IGNORE, \"\", \"%s\" # UNI\n" +"IFIELD LAT_DECIMAL, \"\", \"%03.7f\" # LAT\n" +"IFIELD LON_DECIMAL, \"\", \"%03.7f\" # LONG\n" +"IFIELD IGNORE, \"\", \"%s\" # DMS_LAT\n" +"IFIELD IGNORE, \"\", \"%s\" # DMS_LONG\n" +"IFIELD IGNORE, \"\", \"%s\" # UTM\n" +"IFIELD IGNORE, \"\", \"%s\" # JOG\n" +"IFIELD IGNORE, \"\", \"%s\" # FC\n" +"IFIELD IGNORE, \"\", \"%s\" # DSG\n" +"IFIELD IGNORE, \"\", \"%s\" # PC\n" +"IFIELD IGNORE, \"\", \"%s\" # CC1\n" +"IFIELD IGNORE, \"\", \"%s\" # ADM1\n" +"IFIELD IGNORE, \"\", \"%s\" # ADM2\n" +"IFIELD IGNORE, \"\", \"%s\" # DIM\n" +"IFIELD IGNORE, \"\", \"%s\" # CC2\n" +"IFIELD IGNORE, \"\", \"%s\" # NT\n" +"IFIELD IGNORE, \"\", \"%s\" # LC\n" +"IFIELD IGNORE, \"\", \"%s\" # SHORT_FORM\n" +"IFIELD IGNORE, \"\", \"%s\" # GENERIC\n" +"IFIELD SHORTNAME, \"\", \"%s\" # SHORT_NAME\n" +"IFIELD DESCRIPTION, \"\", \"%s\" # FULL_NAME\n" +"IFIELD IGNORE, \"\", \"%s\" # FULL_NAME_ND\n" +"IFIELD IGNORE, \"\", \"%s\" # MOD_DATE\n" +; +static char gpsdrive[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: GPSDrive\n" +"# Author: Alex Mottram\n" +"# Date: 12/11/2002\n" +"#\n" +"# \n" +"#\n" + +"DESCRIPTION GpsDrive Format\n" + +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER WHITESPACE\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS ,'\"\n" + +"SHORTLEN 20\n" +"SHORTWHITE 0\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + +"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +"IFIELD ICON_DESCR, \"\", \"%s\"\n" + +"OFIELD ANYNAME, \"\", \"%s\"\n" +"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD ICON_DESCR, \"\", \"%s\"\n" +; +static char gpsdrivetrack[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: GPSDriveTrack\n" +"# Author: Tobias Minich\n" +"# Date: 12/07/2005\n" +"#\n" +"# \n" +"#\n" + +"DESCRIPTION GpsDrive Format for Tracks\n" + +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER WHITESPACE\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS ,'\"\n" + +"SHORTLEN 20\n" +"SHORTWHITE 0\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + +"IFIELD LAT_DECIMAL, \"\", \"%10.6f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%10.6f\"\n" +"IFIELD ALT_METERS, \"\", \"%10.0f\"\n" +"# Reports are that this format stores in local time, not GMT as \n" +"# originally thought.\n" +"# IFIELD GMT_TIME, \"\", \"%a %b %d %H:%M:%S %Y\"\n" +"IFIELD LOCAL_TIME, \"\", \"%a %b %d %H:%M:%S %Y\"\n" +; +static char gpsman[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: GPSMAN Format\n" +"# Author: Alex Mottram\n" +"# Date: 12/09/2002\n" +"#\n" +"# \n" +"# As defined in gpsman.c\n" +"#\n" +"#\n" + +"DESCRIPTION GPSman\n" +"SHORTLEN 8\n" +"SHORTWHITE 0\n" + +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER TAB\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS TAB\n" + +"PROLOGUE !Format: DDD 1 WGS 84\n" +"PROLOGUE !W:\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD SHORTNAME, \"\", \"%-8.8s\"\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" +"IFIELD LAT_DIRDECIMAL, \"\", \"%c%f\"\n" +"IFIELD LON_DIRDECIMAL, \"\", \"%c%f\"\n" +"IFIELD IGNORE, \"\", \"%s\"\n" + +"# gpsman.c likes mkshort len = 8, whitespace = 0.\n" +; +static char kompass_tk[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Kompass / Deutscher Alpenverein (DAV) Waypoints\n" +"# Author: Olaf Klein\n" +"# Date: 01/10/2007\n" +"#\n" +"# \n" +"DESCRIPTION Kompass (DAV) Track (.tk)\n" +"DATATYPE TRACK\n" +"EXTENSION wp\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS ,\"\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LAT_DECIMAL, \"\", \"%.7f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%.7f\"\n" +; +static char kompass_wp[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Kompass / Deutscher Alpenverein (DAV) Waypoints\n" +"# Author: Olaf Klein\n" +"# Date: 01/10/2007\n" +"#\n" +"# \n" +"DESCRIPTION Kompass (DAV) Waypoints (.wp)\n" +"DATATYPE WAYPOINT\n" +"EXTENSION wp\n" +"ENCODING UTF-8\n" +"FIELD_DELIMITER SEMICOLON\n" +"RECORD_DELIMITER CRNEWLINE\n" +"BADCHARS ,\"\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD LON_DECIMAL, \"\", \"%.7f\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%.7f\"\n" +"IFIELD ALT_METERS, \"\", \"%.0f\"\n" +"IFIELD LOCAL_TIME,\"\",\"%d.%m.%Y %H:%M:%S\"\n" +"IFIELD CONSTANT, \"Icons\\Wegpunkt grün.bmp\", \"%s\"\n" +"IFIELD IGNORE, \"\", \"%s\"\n" +"IFIELD CONSTANT, \"1\", \"%s\" # unknown\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" +; +static char ktf2[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Kartex KTF 2.0 Degrees with decimals\n" +"# Author: Harald Nordius\n" +"# Date: 4/13 2006\n" +"#\n" +"# \n" +"DESCRIPTION Kartex 5 Track File\n" +"EXTENSION ktf\n" +"DATATYPE TRACK\n" +"SHORTLEN 10\n" +"SHORTWHITE 1\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER CRNEWLINE\n" +"#\n" +"#\n" +"# FILE HEADER\n" +"#\n" +"PROLOGUE //Kartex Track File created by GPSBabel\n" +"PROLOGUE &KTF 2.0,sweref 99 lat long,0\n" +"#\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD CONSTANT, %, \"%s\"\n" +"IFIELD INDEX, \"\", \"%d\"\n" +"IFIELD LATLON_HUMAN_READABLE, \"\", \"%c%f°\"\n" +"IFIELD ALT_METERS, \"\", \"%.2f\"\n" +"IFIELD GMT_TIME, \"\", \"%Y-%m-%d %H:%M:%S\"\n" +"IFIELD IGNORE, \"\", \"%s\" #Empty field\n" +"IFIELD IGNORE, \"\", \"%s\" #Empty field\n" +"IFIELD CONSTANT, \"$\", \"%s\"\n" +; +static char kwf2[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Kartex KWF 2.0 Degrees with decimals\n" +"# Author: Harald Nordius\n" +"# Date: 12/08 2004\n" +"#\n" +"# \n" +"DESCRIPTION Kartex 5 Waypoint File\n" +"EXTENSION kwf\n" +"SHORTLEN 10\n" +"SHORTWHITE 1\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER CRNEWLINE\n" +"ENCODING CP1252\n" +"#\n" +"#\n" +"# FILE HEADER\n" +"#\n" +"PROLOGUE //Kartex Waypoint File created by GPSBabel\n" +"PROLOGUE &KWF 2.0,sweref 99 lat long,0\n" +"#\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD CONSTANT, \\#, \"%s\"\n" +"IFIELD INDEX,\"\",\"%d\"\n" +"IFIELD SHORTNAME,\"\",\"%s\"\n" +"IFIELD LATLON_HUMAN_READABLE,\"\",\"%c%f°\"\n" +"IFIELD ALT_METERS,\"\",\"%.2f\"\n" +"IFIELD IGNORE, \"\",\"%s\" #Empty field\n" +"IFIELD IGNORE, \"\",\"%s\" #Empty field\n" +"IFIELD CONSTANT, \"0\",\"%s\" #Waypoint symbol code\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" +"IFIELD CONSTANT, \"$\", \"%s\"\n" +; +static char mapconverter[] = +"# Format: Mapopolis.com Mapconverter\n" +"# Author: Gary Paulson\n" +"# Date: 01/13/2003\n" +"# Requires unsupported mapconverter.exe from mapopolis.com.\n" +"#\n" +"# Modifications by Alex Mottram documented 6/30/2003\n" +"# Change %-40.40s on description output to %-.40s to stop padding.\n" +"# Add QUOTE as badchars, remove COMMA.\n" +"# Removed Mapconverter.exe's README information from style file.\n" +"# Changed OFIELD to IFIELD in case you ever want to read one of these things.\n" +"#\n" +"#\n" +"DESCRIPTION Mapopolis.com Mapconverter CSV\n" +"EXTENSION txt\n" + +"# FILE LAYOUT DEFINITIIONS:\n" + +"FIELD_DELIMITER COMMASPACE\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS \",\n" + +"# Map Info Record (header):\n" +"PROLOGUE M, \"Geocaches\", \"GPSBabel\", Geocaches, __FILE__\n" +"#\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"# L Records:\n" +"IFIELD CONSTANT, \"L\", \"%s\" # [L]ANDMARK\n" +"IFIELD CONSTANT, \"Geocaches\", \"%s\" # Category for Landmark Searches\n" +"IFIELD DESCRIPTION, \"\", \"%-.40s\" # Name\n" +"IFIELD CONSTANT, \"1\", \"%s\" # View at Zoom Level 1 (1-4)\n" +"IFIELD LON_DECIMAL, \"\", \"%08.5f\" # Longitude\n" +"IFIELD LAT_DECIMAL, \"\", \"%08.5f\" # Latitude\n" +; +static char mxf[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Ozi Explorer\n" +"# Author: Alex Mottram\n" +"# Date: 12/09/2002\n" +"#\n" +"# \n" +"# As used in mxf.c\n" +"#\n" +"#\n" + +"DESCRIPTION MapTech Exchange Format\n" +"EXTENSION mxf\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMASPACE\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS ,\"\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +"IFIELD DESCRIPTION, \"\", \"\"%s\"\"\n" +"IFIELD SHORTNAME, \"\", \"\"%s\"\"\n" +"IFIELD IGNORE, \"\", \"%s\"\n" +"IFIELD CONSTANT, \"ff0000\", \"%s\" # COLOR\n" +"IFIELD CONSTANT, \"47\", \"%s\" # ICON\n" + +"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD DESCRIPTION, \"\", \"\"%s\"\"\n" +"OFIELD SHORTNAME, \"\", \"\"%s\"\"\n" +"OFIELD DESCRIPTION, \"\", \"\"%s\"\"\n" +"OFIELD CONSTANT, \"ff0000\", \"%s\" # COLOR\n" +"OFIELD CONSTANT, \"47\", \"%s\" # ICON\n" +; +static char nima[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: NIMA/GNIS Geographic Names File\n" +"# Author: Alex Mottram\n" +"# Date: 11/24/2002\n" +"#\n" + +"DESCRIPTION NIMA/GNIS Geographic Names File\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER TAB\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS TAB\n" +"PROLOGUE RC UFI UNI DD_LAT DD_LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD IGNORE, \"\", \"%s\" # RC\n" +"IFIELD IGNORE, \"\", \"%s\" # UFI\n" +"IFIELD IGNORE, \"\", \"%s\" # UNI\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\" # DD_LAT\n" +"IFIELD LON_DECIMAL, \"\", \"%f\" # DD_LON\n" +"IFIELD IGNORE, \"\", \"%s\" # DMS_LAT\n" +"IFIELD IGNORE, \"\", \"%s\" # DMS_LON\n" +"IFIELD IGNORE, \"\", \"%s\" # UTM\n" +"IFIELD IGNORE, \"\", \"%s\" # JOG\n" +"IFIELD IGNORE, \"\", \"%s\" # FC\n" +"IFIELD IGNORE, \"\", \"%s\" # DSG\n" +"IFIELD IGNORE, \"\", \"%s\" # PC\n" +"IFIELD IGNORE, \"\", \"%s\" # CC1\n" +"IFIELD IGNORE, \"\", \"%s\" # ADM1\n" +"IFIELD IGNORE, \"\", \"%s\" # ADM2\n" +"IFIELD IGNORE, \"\", \"%s\" # DIM\n" +"IFIELD IGNORE, \"\", \"%s\" # CC2\n" +"IFIELD IGNORE, \"\", \"%s\" # NT\n" +"IFIELD IGNORE, \"\", \"%s\" # LC\n" +"IFIELD IGNORE, \"\", \"%s\" # SHORT_FORM\n" +"IFIELD IGNORE, \"\", \"%s\" # GENERIC\n" +"IFIELD SHORTNAME, \"\", \"%s\" # SORT_NAME \n" +"IFIELD IGNORE, \"\", \"%s\" # FULL_NAME (unicoded!)\n" +"IFIELD DESCRIPTION, \"\", \"%s\" # FULL_NAME_ND\n" +"IFIELD IGNORE, \"\", \"%s\" # MODIFY_DATE\n" +; +static char openoffice[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Tab delimited useful for OpenOffice, Ploticus etc.\n" +"# Author: Tobias Minich\n" +"# Date: 07/18/2005\n" +"#\n" +"#\n" + +"DESCRIPTION Tab delimited fields useful for OpenOffice, Ploticus etc.\n" + +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER TAB\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS TAB\n" + +"#\n" +"# HEADER STUFF:\n" +"#\n" +"PROLOGUE Index Lat Lon Icon Name Description Notes URL Link Text Altitude (m) Distance (km) Speed (m/s) Course (°) Time HDOP VDOP PDOP Satellites Fix\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS:\n" +"#\n" +"IFIELD INDEX, \"\", \"%d\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" +"IFIELD LAT_DIR, \"\", \"%c\"\n" +"IFIELD LAT_HUMAN_READABLE, \"\", \"%d° %f' %c\"\n" +"IFIELD LON_DECIMAL, \"\", \"%f\"\n" +"IFIELD LON_DIR, \"\", \"%c\"\n" +"IFIELD LON_HUMAN_READABLE, \"\", \"%d° %f' %c\"\n" +"IFIELD ICON_DESCR, \"\", \"%s\"\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" +"IFIELD NOTES, \"\", \"%s\"\n" +"IFIELD URL, \"\", \"%s\" \n" +"IFIELD URL_LINK_TEXT, \"\", \"%s\"\n" +"IFIELD ALT_METERS, \"\", \"%f\"\n" +"IFIELD PATH_DISTANCE_KM, \"\", \"%f\"\n" +"IFIELD PATH_SPEED, \"\", \"%f\"\n" +"IFIELD PATH_COURSE, \"\", \"%f\"\n" +"IFIELD EXCEL_TIME, \"\", \"%f\"\n" +"IFIELD GPS_HDOP, \"\", \"%f\"\n" +"IFIELD GPS_VDOP, \"\", \"%f\"\n" +"IFIELD GPS_PDOP, \"\", \"%f\"\n" +"IFIELD GPS_SAT, \"\", \"%d\"\n" +"IFIELD GPS_FIX, \"\", \"%s\"\n" +; +static char s_and_t[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: MS S&T 2002/2003\n" +"# Author: Alex Mottram\n" +"# Date: 12/09/2002\n" +"#\n" +"# \n" +"# As requested by Noel Shrum on the gpsbabel-code mailing list.\n" +"# Name,Latitude,Longitude,Name 2,URL,Type\n" +"# GCCBF,44.479133,-85.56515,High Rollaway by rjlint,http://www.geocaching.com/seek/cache_details.aspx?ID=3263,Traditional Cache\n" +"# GC110D,44.6522,-85.492483,Brown Bridge Pond Peek-a-Boo Cache by Big Bird,http://www.geocaching.com/seek/cache_details.aspx?ID=4365,Traditional Cache\n" +"# GC171C,44.70605,-85.62265,The Michigan Frog by RealDcoy & LRB,http://www.geocaching.com/seek/cache_details.aspx?ID=5916,Traditional Cache\n" +"#\n" + +"DESCRIPTION Microsoft Streets and Trips 2002-2007\n" +"EXTENSION txt\n" + + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER TAB\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS ,\"\n" + +"PROLOGUE Name Latitude Longitude Description URL Type Container Diff Terr\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"# NOTE: MS S&T ONLY IMPORTS DATA, IT DOESN'T EXPORT THIS ANYWHERE SO WE CAN\n" +"# HAVE OUR WAY WITH THE FORMATTING. \n" +"#\n" +"IFIELD SHORTNAME, \"\", \"%s\" # Name\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\" # Latitude\n" +"IFIELD LON_DECIMAL, \"\", \"%f\" # Longitude\n" +"IFIELD DESCRIPTION, \"\", \"%s\" # Name 2 (Big Description)\n" +"IFIELD URL, \"\", \"%s\" # URL\n" +"IFIELD GEOCACHE_TYPE, \"\", \"%s\" # Geocache Type\n" +"IFIELD GEOCACHE_CONTAINER, \"\", \"%s\" # Geocache Type\n" +"IFIELD GEOCACHE_DIFF, \"\", \"%3.1f\" # Geocache Type\n" +"IFIELD GEOCACHE_TERR, \"\", \"%3.1f\" # Geocache Type\n" +; +static char saplus[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: \n" +"# Author: Jim Bensman\n" +"# Date: 02/22/04\n" +"#\n" + +"DESCRIPTION DeLorme Street Atlas Plus\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS ,\"\n" + +"PROLOGUE Name 2,Name,Latitude,Longitude,URL,Type\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD DESCRIPTION, \"\", \"%s\" # Name 2 (Big Description)\n" +"IFIELD SHORTNAME, \"\", \"%s\" # Name\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\" # Latitude\n" +"IFIELD LON_DECIMAL, \"\", \"%f\" # Longitude\n" +"IFIELD URL, \"\", \"%s\" # URL\n" +"IFIELD IGNORE, \"\", \"\" # Holder for Geocache Type\n" + +; +static char sportsim[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Sportsim track files\n" +"# Author: Olaf Klein\n" +"# Date: 07/05/2006\n" +"#\n" +"DESCRIPTION Sportsim track files (part of zipped .ssz files) \n" +"EXTENSION txt\n" +"DATATYPE TRACK\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER SEMICOLON\n" +"RECORD_DELIMITER CRNEWLINE\n" +"BADCHARS TAB\n" + +"#\n" +"# FILE HEADER\n" +"#\n" +"PROLOGUE SportsimVersion:01\n" +"PROLOGUE \\#Sportsim TrackFile\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS:\n" +"#\n" +"IFIELD INDEX, \"\", \"%05d\"\n" +"IFIELD CONSTANT, \"0\", \"%s\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%f\"\n" +"IFIELD ALT_FEET, \"\", \"%.f\"\n" +"IFIELD TIMET_TIME, \"\", \"%ld\"\n" +"IFIELD CONSTANT, \";\", \"%s\"\n" +; +static char tabsep[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Dumps all fields in a traditional Unix tab separated style\n" +"#\n" +"# The order of the fields (with the exception of LAT_DIR/LON_DIR) was\n" +"# the same as documented in README.style when this format was created.\n" +"# LAT_DIR/LON_DIR were undocumented, so I stuck them at the end of the\n" +"# other lat/lon fields.\n" +"#\n" +"# However, please add any new gpsbabel fields to the end (to avoid\n" +"# upsetting existing applications) regardless of where they land in\n" +"# the README.style documentation.\n" +"#\n" + +"DESCRIPTION All database fields on one tab-separated line\n" + +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER TAB\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS TAB\n" +"FORMAT_TYPE INTERNAL\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS:\n" +"#\n" +"IFIELD INDEX, \"\", \"%d\"\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" +"IFIELD NOTES, \"\", \"%s\"\n" +"IFIELD URL, \"\", \"%s\" \n" +"IFIELD URL_LINK_TEXT, \"\", \"%s\"\n" +"IFIELD ICON_DESCR, \"\", \"%s\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%f\"\n" +"IFIELD LAT_INT32DEG, \"\", \"%ld\"\n" +"IFIELD LON_INT32DEG, \"\", \"%ld\"\n" +"IFIELD LAT_DECIMALDIR, \"\", \"%f%c\"\n" +"IFIELD LON_DECIMALDIR, \"\", \"%f%c\"\n" +"IFIELD LAT_DIRDECIMAL, \"\", \"%c%f\"\n" +"IFIELD LON_DIRDECIMAL, \"\", \"%c%f\"\n" +"IFIELD LAT_DIR, \"\", \"%c\"\n" +"IFIELD LON_DIR, \"\", \"%c\"\n" +"IFIELD ALT_FEET, \"\", \"%fF\"\n" +"IFIELD ALT_METERS, \"\", \"%fM\"\n" +"IFIELD EXCEL_TIME, \"\", \"%f\"\n" +"IFIELD TIMET_TIME, \"\", \"%ld\"\n" +"IFIELD GEOCACHE_DIFF,\"\",\"%3.1f\"\n" +"IFIELD GEOCACHE_TERR,\"\",\"%3.1f\"\n" +"IFIELD GEOCACHE_CONTAINER,\"\",\"%s\"\n" +"IFIELD GEOCACHE_TYPE,\"\",\"%s\"\n" +"IFIELD PATH_DISTANCE_MILES,\"\",\"%f\"\n" +"IFIELD PATH_DISTANCE_KM, \"\", \"%f\"\n" +"IFIELD GEOCACHE_PLACER,\"\",\"%s\"\n" +"IFIELD YYYYMMDD_TIME,\"\",\"%ld\"\n" +"IFIELD GEOCACHE_HINT, \"\", \"%s\"\n" +"IFIELD GEOCACHE_LAST_FOUND, \"\", \"%d\"\n" +; +static char tomtom_asc[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: TomTom Navigator Places of Interest\n" +"# Author: Olaf Klein\n" +"# Date: 04/17/2007\n" +"#\n" +"DESCRIPTION TomTom POI file (.asc)\n" +"EXTENSION asc\n" +"DATATYPE WAYPOINT\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER CRNEWLINE\n" +"BADCHARS ,\"\n" +"ENCODING MS-ANSI\n" +"#\n" +"PROLOGUE TomTom Navigator Places of Interest\n" +"PROLOGUE GPSBabel-__VERSION__ ASCII Export\n" +"PROLOGUE Points\n" +"PROLOGUE Created at: __DATE_AND_TIME__\n" +"# #\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LON_DECIMAL, \"\", \"%.6f\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%.6f\"\n" +"IFIELD SHORTNAME, \"\", \"\"%s\"\"\n" +; +static char tomtom_itn[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: TomTom Navigator Itineraries (Routes)\n" +"# Author: Olaf Klein\n" +"# Date: 04/17/2007\n" +"#\n" +"DESCRIPTION TomTom Itineraries (.itn)\n" +"EXTENSION itn\n" +"DATATYPE ROUTE\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER PIPE\n" +"RECORD_DELIMITER CRNEWLINE\n" +"BADCHARS ,|\n" +"ENCODING MS-ANSI\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LON_10E5, \"\", \"%.f\"\n" +"IFIELD LAT_10E5, \"\", \"%.f\"\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD CONSTANT, \"0\", \"%s\"\n" +; +static char xmap[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: DeLorme Xmap Conduit\n" +"# Author: Alex Mottram\n" +"# Date: 12/09/2002\n" +"#\n" +"# \n" +"# As defined in csv.c/xmap\n" +"#\n" + +"DESCRIPTION DeLorme XMap HH Native .WPT\n" +"EXTENSION wpt\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMASPACE\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" + +"PROLOGUE BEGIN SYMBOL\n" +"EPILOGUE END\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" +"IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" + +"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD DESCRIPTION, \"\", \"%s\"\n" +; +static char xmap2006[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: DeLorme Xmap/Street Atlas Handheld 2006 Conduit\n" +"# Author: Pasha Phares\n" +"# Date: 5/5/2006\n" +"#\n" +"# Amazingly, 2006 won't read the \"COMMASPACE\" that we used in \n" +"# in Xmap prior to this and versions before 2006 won't read files\n" +"# separated by only a comma.\n" +"# \n" + +"DESCRIPTION DeLorme XMap/SAHH 2006 Native .TXT\n" +"EXTENSION txt\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" + +"PROLOGUE BEGIN SYMBOL\n" +"EPILOGUE END\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LAT_HUMAN_READABLE, \"\", \"%.12g\"\n" +"IFIELD LON_HUMAN_READABLE, \"\", \"%.12g\"\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" + +"OFIELD LAT_DECIMAL, \"\", \"%.12g\"\n" +"OFIELD LON_DECIMAL, \"\", \"%.12g\"\n" +"OFIELD SHORTNAME, \"\", \"%s\"\n" + + + + +; +static char xmapwpt[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: DeLorme Xmap HH Street Atlas USA .WPT (PocketPC)\n" +"# Author: Alex Mottram\n" +"# Date: 12/09/2002\n" +"#\n" +"# \n" +"DESCRIPTION DeLorme XMat HH Street Atlas USA .WPT (PPC)\n" +"SHORTLEN 32\n" +"SHORTWHITE 0\n" + +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COLON\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COLON\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD CONSTANT, \"1296126539\", \"%s\"\n" +"IFIELD CONSTANT, \"1481466224\", \"%s\"\n" +"IFIELD LAT_INT32DEG, \"\", \"%d\"\n" +"IFIELD LON_INT32DEG, \"\", \"%d\"\n" +"IFIELD CONSTANT, \"3137157\", \"%s\"\n" +"IFIELD SHORTNAME, \"\", \"%-.31s\"\n" +"IFIELD IGNORE, \"\", \"%-.31s\"\n" +"IFIELD DESCRIPTION, \"\", \"%-.78s\"\n" +; +style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap2006", xmap2006 } , { "xmap", xmap } , { "tomtom_itn", tomtom_itn } , { "tomtom_asc", tomtom_asc } , { "tabsep", tabsep } , { "sportsim", sportsim } , { "saplus", saplus } , { "s_and_t", s_and_t } , { "openoffice", openoffice } , { "nima", nima } , { "mxf", mxf } , { "mapconverter", mapconverter } , { "kwf2", kwf2 } , { "ktf2", ktf2 } , { "kompass_wp", kompass_wp } , { "kompass_tk", kompass_tk } , { "gpsman", gpsman } , { "gpsdrivetrack", gpsdrivetrack } , { "gpsdrive", gpsdrive } , { "geonet", geonet } , { "garmin_poi", garmin_poi } , { "garmin301", garmin301 } , { "fugawi", fugawi } , { "dna", dna } , { "custom", custom } , { "cup", cup } , { "csv", csv } , { "cambridge", cambridge } , { "arc", arc } , {0,0}}; +size_t nstyles = 30; +#else /* CSVFMTS_ENABLED */ +style_vecs_t style_list[] = {{0,0}}; +size_t nstyles = 0; +#endif /* CSVFMTS_ENABLED */ diff --git a/interpolate.c b/interpolate.c new file mode 100644 index 000000000..776513cc7 --- /dev/null +++ b/interpolate.c @@ -0,0 +1,194 @@ +/* + Interpolate filter + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" +#include "grtcirc.h" + +#if FILTERS_ENABLED +#define MYNAME "Interpolate filter" + +static char *opt_interval = NULL; +int interval = 0; +static char *opt_dist = NULL; +double dist = 0; +static char *opt_route = NULL; + +static +arglist_t interpfilt_args[] = { + {"time", &opt_interval, "Time interval in seconds", NULL, + ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_INT, + "0", NULL }, + {"distance", &opt_dist, "Distance interval in miles or kilometers", + NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_STRING, + ARG_NOMINMAX }, + {"route", &opt_route, "Interpolate routes instead", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +void +interpfilt_process(void) +{ + queue *backuproute = NULL; + queue *elem, *tmp, *elem2, *tmp2; + route_head *rte_new; + int count = 0; + int first = 0; + double lat1 = 0, lon1 = 0; + int time1 = 0; + int timen; + double distn; + double curdist; + double rt1, rn1, rt2, rn2; + + if ( opt_route ) { + route_backup( &count, &backuproute ); + route_flush_all_routes(); + } + else { + track_backup( &count, &backuproute ); + route_flush_all_tracks(); + } + QUEUE_FOR_EACH( backuproute, elem, tmp ) + { + route_head *rte_old = (route_head *)elem; + + rte_new = route_head_alloc(); + rte_new->rte_name = xstrdup( rte_old->rte_name ); + rte_new->rte_desc = xstrdup( rte_old->rte_desc ); + rte_new->fs = fs_chain_copy( rte_old->fs ); + rte_new->rte_num = rte_old->rte_num; + if ( opt_route ) { + route_add_head( rte_new ); + } + else { + track_add_head( rte_new ); + } + first = 1; + QUEUE_FOR_EACH( &rte_old->waypoint_list, elem2, tmp2 ) + { + waypoint *wpt = (waypoint *)elem2; + if ( first ) { + first = 0; + } + else { + if ( opt_interval && + wpt->creation_time - time1 > interval ) { + for ( timen = time1+interval; + timen < wpt->creation_time; + timen += interval ) { + waypoint *wpt_new = waypt_dupe(wpt); + wpt_new->creation_time = timen; + if (wpt_new->shortname) xfree(wpt_new->shortname); + if (wpt_new->description) xfree(wpt_new->description); + wpt_new->shortname = wpt_new->description = NULL; + linepart( lat1, lon1, + wpt->latitude, wpt->longitude, + (double)(timen-time1)/ + (double)(wpt->creation_time-time1), + &wpt_new->latitude, + &wpt_new->longitude ); + if (opt_route) + route_add_wpt( rte_new, wpt_new); + else + track_add_wpt( rte_new, wpt_new); + } + } + else if ( opt_dist ) { + rt1 = RAD(lat1); + rn1 = RAD(lon1); + rt2 = RAD(wpt->latitude); + rn2 = RAD(wpt->longitude); + curdist = gcdist( rt1, rn1, rt2, rn2 ); + curdist = radtomiles(curdist); + if ( curdist > dist ) { + for ( distn = dist; + distn < curdist; + distn += dist ) { + waypoint *wpt_new = waypt_dupe(wpt); + wpt_new->creation_time = distn/curdist* + (wpt->creation_time - time1) + time1; + if (wpt_new->shortname) xfree(wpt_new->shortname); + if (wpt_new->description) xfree(wpt_new->description); + wpt_new->shortname = wpt_new->description = NULL; + linepart( lat1, lon1, + wpt->latitude, wpt->longitude, + distn/curdist, + &wpt_new->latitude, + &wpt_new->longitude ); + if (opt_route) + route_add_wpt( rte_new, wpt_new ); + else + track_add_wpt( rte_new, wpt_new); + } + } + } + } + if ( opt_route ) { + route_add_wpt( rte_new, waypt_dupe(wpt)); + } + else { + track_add_wpt( rte_new, waypt_dupe(wpt)); + } + + lat1 = wpt->latitude; + lon1 = wpt->longitude; + time1 = wpt->creation_time; + } + } + route_flush( backuproute ); + xfree( backuproute ); +} + +void +interpfilt_init(const char *args) { + + char *fm; + if ( opt_interval && opt_dist ) { + fatal( MYNAME ": Can't interpolate on both time and distance.\n"); + } + else if (opt_interval && opt_route ) { + fatal( MYNAME ": Can't interpolate routes on time.\n" ); + } + else if ( opt_interval ) { + interval = atoi(opt_interval); + } + else if ( opt_dist ) { + dist = strtod(opt_dist, &fm); + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to miles */ + dist *= .6214; + } + } + else { + fatal( MYNAME ": No interval specified.\n"); + } +} + +filter_vecs_t interpolatefilt_vecs = { + interpfilt_init, + interpfilt_process, + NULL, + NULL, + interpfilt_args +}; +#endif // FILTERS_ENABLED diff --git a/jeeps/.cvsignore b/jeeps/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/jeeps/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/jeeps/Makefile.in b/jeeps/Makefile.in new file mode 100644 index 000000000..e69de29bb diff --git a/jeeps/README b/jeeps/README new file mode 100644 index 000000000..f626fc4c5 --- /dev/null +++ b/jeeps/README @@ -0,0 +1 @@ +This is from jeeps-0.1.3. This code is under GPL. diff --git a/jeeps/garminusb.h b/jeeps/garminusb.h new file mode 100644 index 000000000..a05f9c15d --- /dev/null +++ b/jeeps/garminusb.h @@ -0,0 +1,67 @@ +/* + Definitions for Garmin USB protocol and implementation. + + Copyright (C) 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include + +/* This structure is a bit funny looking to avoid variable length + * arrays which aren't present in C89. This contains the visible + * fields in the USB packets of the Garmin USB receivers (60C, 76C, etc.) + * All data are little endian. + */ +typedef +union { + struct { + unsigned char type; + unsigned char reserved1; + unsigned char reserved2; + unsigned char reserved3; + unsigned char pkt_id[2]; + unsigned char reserved6; + unsigned char reserved7; + unsigned char datasz[4]; + unsigned char databuf[1]; /* actually an variable length array... */ + } gusb_pkt; + unsigned char dbuf[1024]; +} garmin_usb_packet; + +/* + * Internal interfaces that are common regardless of underlying + * OS implementation. + */ +#define GUSB_MAX_UNITS 20 +struct garmin_unit_info { + unsigned long serial_number; + unsigned long unit_id; + unsigned long unit_version; + char *os_identifier; /* In case the OS has another name for it. */ + char *product_identifier; /* From the hardware itself. */ +} garmin_unit_info[GUSB_MAX_UNITS]; + +int gusb_cmd_send(const garmin_usb_packet *obuf, size_t sz); +int gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz); +int gusb_init(const char *portname, gpsdevh **dh); +int gusb_close(gpsdevh *); + +/* + * New packet types in USB. + */ +#define GUSB_SESSION_START 5 /* We request units attention */ +#define GUSB_SESSION_ACK 6 /* Unit responds that we have its attention */ +#define GUSB_REQUEST_BULK 2 /* Unit requests we read from bulk pipe */ diff --git a/jeeps/gps.h b/jeeps/gps.h new file mode 100644 index 000000000..42018a6a2 --- /dev/null +++ b/jeeps/gps.h @@ -0,0 +1,234 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gps_h +#define gps_h + +#include "../defs.h" +#include "gpsport.h" +#include + +#define FRAMING_ERROR -1 +#define PROTOCOL_ERROR -2 +#define HARDWARE_ERROR -3 +#define SERIAL_ERROR -4 +#define MEMORY_ERROR -5 +#define GPS_UNSUPPORTED -6 +#define INPUT_ERROR -7 + +#define MAX_GPS_PACKET_SIZE 1024 +#define GPS_TIME_OUT 5 + +#define gpsTrue 1 +#define gpsFalse 0 + +#define DLE 0x10 +#define ETX 0x03 + + +extern int32 gps_errno; +extern int32 gps_warning; +extern int32 gps_error; +extern int32 gps_user; +extern int32 gps_show_bytes; +extern char gps_categories[16][17]; + + +typedef struct GPS_SPacket +{ + UC dle; + UC type; + UC n; + UC *data; + UC chk; + UC edle; + UC etx; + UC bytes; /* Actual number of bytes (for sending) */ +} GPS_OPacket, *GPS_PPacket; + + + +typedef struct GPS_SProduct_Data_Type +{ + int16 id; + int16 version; + char desc[MAX_GPS_PACKET_SIZE]; +} GPS_OProduct_Data_Type, *GPS_PProduct_Data_Type; + + + + +typedef struct GPS_SPvt_Data_Type +{ + float alt; + float epe; + float eph; + float epv; + int16 fix; + double tow; + double lat; + double lon; + float east; + float north; + float up; + float msl_hght; + int16 leap_scnds; + int32 wn_days; +} GPS_OPvt_Data, *GPS_PPvt_Data; + + + +typedef struct GPS_STrack +{ + double lat; /* Degrees */ + double lon; /* Degrees */ + time_t Time; /* Unix time */ + float alt; /* Altitude */ + float dpth; /* Depth */ + float temperature; /* Temperature. Degrees Celsius. */ + int temperature_populated; /* True if above is valid. */ + unsigned char heartrate; /* Heartrate as in Garmin 301 */ + unsigned char cadence; /* Crank cadence as in Edge 305 */ + unsigned int tnew:1; /* New track? */ + unsigned int ishdr:1; /* Track header? */ + unsigned int no_latlon:1; /* True if no valid lat/lon found. */ + int32 dspl; /* Display on map? */ + int32 colour; /* Colour */ + float distance; /* distance traveled in meters.*/ + char trk_ident[256]; /* Track identifier */ +} +GPS_OTrack, *GPS_PTrack; + + + +typedef struct GPS_SAlmanac +{ + UC svid; + int16 wn; + float toa; + float af0; + float af1; + float e; + float sqrta; + float m0; + float w; + float omg0; + float odot; + float i; + UC hlth; +} GPS_OAlmanac, *GPS_PAlmanac; + + +typedef struct GPS_SWay +{ + char ident[256]; + double lat; + double lon; + char cmnt[256]; + float dst; + int32 smbl; + int32 dspl; + char wpt_ident[256]; + char lnk_ident[256]; + UC subclass[18]; + int32 colour; + char cc[2]; + UC wpt_class; + UC alt_is_unknown; + float alt; + char city[24]; + char state[2]; + char name[30]; + char facility[32]; + char addr[52]; + char cross_road[52]; + int32 attr; + float dpth; + int32 idx; + int32 prot; + int32 isrte; + int32 rte_prot; + UC rte_num; + char rte_cmnt[20]; + char rte_ident[256]; + int32 islink; + int32 rte_link_class; + char rte_link_subclass[18]; + char rte_link_ident[256]; + + char time_populated; /* 1 if true */ + time_t time; /* Unix time */ + char temperature_populated; + float temperature; /* Degrees celsius. */ + uint16 category; + +} GPS_OWay, *GPS_PWay; + +/* + * Forerunner/Edge Lap data. + */ +typedef struct GPS_SLap { + uint32 index; /* unique index in device or -1 */ + time_t start_time; + uint32 total_time; /* Hundredths of a second */ + float total_distance; /* In meters */ + double begin_lat; + double begin_lon; + double end_lat; + double end_lon; + int16 calories; + uint32 track_index; /* ref to track or -1 */ + float max_speed; /* In meters per second */ + unsigned char avg_heart_rate; /* In beats-per-minute, 0 if invalid */ + unsigned char max_heart_rate; /* In beats-per-minute, 0 if invalid */ + unsigned char intensity; /* Same as D1001 */ + unsigned char avg_cadence; /* In revolutions-per-minute, 0xFF if invalid */ + unsigned char trigger_method; + /*Some D1015 unknown */ + /* unsigned char unk1015_1; + int16 unk1015_2; + int16 unk1015_3; + */ +} GPS_OLap, *GPS_PLap; + +typedef int (*pcb_fn) (int, struct GPS_SWay **); + +#include "gpsdevice.h" +#include "gpssend.h" +#include "gpsread.h" +#include "gpsutil.h" +#include "gpsapp.h" +#include "gpsprot.h" +#include "gpscom.h" +#include "gpsfmt.h" +#include "gpsmath.h" +#include "gpsmem.h" +#include "gpsrqst.h" +#include "gpsinput.h" +#include "gpsproj.h" + +time_t gps_save_time; +double gps_save_lat; +double gps_save_lon; +extern int32 gps_save_id; +extern double gps_save_version; +extern char gps_save_string[GPS_ARB_LEN]; +extern int gps_is_usb; + +extern struct COMMANDDATA COMMAND_ID[2]; +extern struct LINKDATA LINK_ID[3]; +extern struct GPS_MODEL_PROTOCOL GPS_MP[]; + +extern char *gps_marine_sym[]; +extern char *gps_land_sym[]; +extern char *gps_aviation_sym[]; +extern char *gps_16_sym[]; + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsapp.c b/jeeps/gpsapp.c new file mode 100644 index 000000000..651ed61e3 --- /dev/null +++ b/jeeps/gpsapp.c @@ -0,0 +1,6327 @@ +/******************************************************************** +** @source JEEPS application and data functions +** +** @author Copyright (C) 1999 Alan Bleasby +** @version 1.0 +** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2004, 2005, 2006 Robert Lipe +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include +#include +#include +#include +#include + +/* + * This violates the layering design, but is needed for device discovery. + * See the use of gps_is_usb and GPS_Packet_Read_usb below. + */ +#include "garminusb.h" +#include "gpsusbint.h" + +#define XMIN(a,b) (a < b? a : b) + +static int32 GPS_A000(const char *port); +static void GPS_A001(GPS_PPacket packet); + + +static void GPS_A500_Translate(UC *s, GPS_PAlmanac *alm); +static void GPS_A500_Encode(UC *s, GPS_PAlmanac alm); +static void GPS_A300_Translate(UC *s, GPS_PTrack *trk); +static void GPS_A300_Encode(UC *s, GPS_PTrack trk); + + +static void GPS_D100_Get(GPS_PWay *way, UC *s); +static void GPS_D101_Get(GPS_PWay *way, UC *s); +static void GPS_D102_Get(GPS_PWay *way, UC *s); +static void GPS_D103_Get(GPS_PWay *way, UC *s); +static void GPS_D104_Get(GPS_PWay *way, UC *s); +static void GPS_D105_Get(GPS_PWay *way, UC *s); +static void GPS_D106_Get(GPS_PWay *way, UC *s); +static void GPS_D107_Get(GPS_PWay *way, UC *s); +static void GPS_D108_Get(GPS_PWay *way, UC *s); +static void GPS_D109_Get(GPS_PWay *way, UC *s, int proto); +static void GPS_D150_Get(GPS_PWay *way, UC *s); +static void GPS_D151_Get(GPS_PWay *way, UC *s); +static void GPS_D152_Get(GPS_PWay *way, UC *s); +static void GPS_D154_Get(GPS_PWay *way, UC *s); +static void GPS_D155_Get(GPS_PWay *way, UC *s); + +static void GPS_D100_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D101_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D102_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D103_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D104_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D105_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D106_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D107_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int proto); +static void GPS_D150_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D151_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D152_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D154_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len); + +static void GPS_D120_Get(int n, char *data); + +static void GPS_D200_Get(GPS_PWay *way, UC *s); +static void GPS_D201_Get(GPS_PWay *way, UC *s); +static void GPS_D202_Get(GPS_PWay *way, UC *s); +static void GPS_D210_Get(GPS_PWay *way, UC *s); +static void GPS_D200_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D201_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D202_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D210_Send(UC *data, GPS_PWay way, int32 *len); + +static void GPS_D400_Get(GPS_PWay *way, UC *s); +static void GPS_D403_Get(GPS_PWay *way, UC *s); +static void GPS_D450_Get(GPS_PWay *way, UC *s); +static void GPS_D400_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D403_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len); + +static void GPS_D500_Send(UC *data, GPS_PAlmanac alm); +static void GPS_D501_Send(UC *data, GPS_PAlmanac alm); +static void GPS_D550_Send(UC *data, GPS_PAlmanac alm); +static void GPS_D551_Send(UC *data, GPS_PAlmanac alm); + + +int32 gps_save_id; +int gps_is_usb; +double gps_save_version; +char gps_save_string[GPS_ARB_LEN]; + +/* + * Internal function to copy what Garmin describes as a "Character Array". + * Dest buffer is padded with spaces and must not contain nulls. Optionally + * we uppercase the string because some models (III's and 12's) react + * violently to lower case data. + */ +typedef enum { UpperNo = 0, UpperYes = 1 } copycase; + +static +void copy_char_array(UC **dst, char* src, int count, copycase mustupper) +{ + UC *d = *dst; + int ocount = count; + do { + UC sc = *src++; + if (!isalnum(sc)) continue; + if (sc == 0) { + while (count--) + *d++ = ' '; + break; + } + else *d++ = mustupper == UpperYes ? toupper(sc) : sc; + } while (--count) ; + *dst += ocount; +} + + +/* @func GPS_Init ****************************************************** +** +** Initialise GPS communication +** Get capabilities and store time lat/lon in case GPS requests +** it later. +** Find endian nature of hardware and store +** +** @param [r] port [const char *] serial port +** +** @return [int32] 1 if success -ve if error +************************************************************************/ +int32 GPS_Init(const char *port) +{ + int32 ret; + + (void) GPS_Util_Little(); + + ret = GPS_A000(port); + if(ret<0) return ret; + gps_save_time = GPS_Command_Get_Time(port); + + /* + * Some units may be unable to return time, such as a C320 when in + * charging mode. Only consider it fatal if the unit returns an error, + * not just absence of returning a time. + */ + if(gps_save_time < 0) { + return FRAMING_ERROR; + } + + if (0 == strncmp(gps_save_string, "GPilotS", 7)) { + return 1; + } + + return GPS_Command_Get_Position(port,&gps_save_lat,&gps_save_lon); +} + + +/* @funcstatic GPS_A000 ************************************************ +** +** Return product ID, version and description. Turn off PVT transfer +** +** @param [r] port [const char *] serial port +** +** @return [int32] 1 if success -ve if error +************************************************************************/ +static int32 GPS_A000(const char *port) +{ + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int16 version; + int16 id; + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!GPS_Device_Flush(fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Make_Packet(&tra, LINK_ID[0].Pid_Product_Rqst,NULL,0); + if(!GPS_Write_Packet(fd,tra)) + return SERIAL_ERROR; + + if(!GPS_Get_Ack(fd, &tra, &rec)) + return SERIAL_ERROR; + + GPS_Packet_Read(fd, &rec); + GPS_Send_Ack(fd, &tra, &rec); + + id = GPS_Util_Get_Short(rec->data); + version = GPS_Util_Get_Short((rec->data)+2); + + (void) strcpy(gps_save_string,(char *)rec->data+4); + gps_save_id = id; + gps_save_version = (double)((double)version/(double)100.); + + GPS_User("Unit:\t%s\nID:\t%d\nVersion:\t%.2f", + gps_save_string, gps_save_id, gps_save_version); + +#if 0 + gps_date_time_transfer = pA600; + gps_date_time_type = pD600; /* All models so far */ + gps_position_transfer = pA700; + gps_position_type = pD700; /* All models so far */ +#else + gps_date_time_transfer = -1; + gps_date_time_type = -1; + gps_position_transfer = -1; + gps_position_type = -1; +#endif + gps_pvt_transfer = -1; + gps_pvt_type = -1; + gps_trk_transfer = -1; + gps_trk_type = -1; + gps_trk_hdr_type = -1; + gps_rte_link_type = -1; + + gps_prx_waypt_transfer = -1; + gps_prx_waypt_type = -1; + gps_almanac_transfer = -1; + gps_almanac_type = -1; + gps_lap_transfer = -1; + gps_lap_type = -1; + + if(!GPS_Device_Wait(fd)) + { + GPS_Warning("A001 protocol not supported"); + id = GPS_Protocol_Version_Change(id,version); + if(GPS_Protocol_Table_Set(id)<0) + return GPS_UNSUPPORTED; + } + else + { + int i; + /* + * The unit may return more than one packet, so read and + * discard all but the product inquiry response. We have + * no way of knowing how many we'll get, so we have to keep + * reading until we incur a timeout. + * Worse still, the serial layer assumes a read timeout is a + * fatal error, while the USB layer (correctly) returns that error + * to the caller. So we call GPS_Device_Wait which spins into + * a delay/select for the serial system and a NOP for USB. + * + * Worse _yet_, this is the one place in all of Garmin Protocolsville + * where we don't know a priori how many packets will be sent in + * response. Since we want the lower levels of the USB handler + * to handle the ugliness of the "return to interrupt" packets, we + * reach behind that automation here and hand that ourselves. + */ + for (i = 0; i < 25; i++) { + rec->type = 0; + + if (gps_is_usb) { + GPS_Packet_Read_usb(fd, &rec, 0); + } else { + if(!GPS_Device_Wait(fd)) + goto carry_on; + + if (GPS_Packet_Read(fd, &rec) <= 0) { + goto carry_on; + } + + GPS_Send_Ack(fd, &tra, &rec); + } + + if (rec->type == 0xfd) { + GPS_A001(rec); + goto carry_on; + } + + /* + * If a 296 has previously been interrupted, it's going to + * ignore the session request (grrrr) and continue to send + * us left over packets. So if we see anything that isn't + * part of our A000 discovery cycle, reset the counter and + * continue to loop. + * + * Garmin acknowledges this is a firmware defect. + */ + if (rec->type < 0xf8) { + i = 0; + } + } + fatal("Failed to find a product inquiry response.\n"); + } + +carry_on: + /* Make sure PVT is off as some GPS' have it on by default */ + if(gps_pvt_transfer != -1) + GPS_A800_Off(port,&fd); + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; +} + + + + +/* @funcstatic GPS_A001 ************************************************ +** +** Extract protocol capabilities +** This routine could do with re-writing. It's too long and obtuse. +** +** @param [r] packet [GPS_PPacket] A001 protocol packet +** +** @return [void] +************************************************************************/ +static void GPS_A001(GPS_PPacket packet) +{ + int32 entries; + int32 i; + UC *p; + US tag; + US data; + US lasta=0; + + gps_link_type = -1; + gps_device_command = -1; + gps_waypt_transfer = -1; + gps_waypt_type = -1; + gps_route_transfer = -1; + gps_rte_hdr_type = -1; + gps_rte_type = -1; + gps_trk_transfer = -1; + gps_trk_type = -1; + gps_prx_waypt_transfer = -1; + gps_prx_waypt_type = -1; + gps_almanac_transfer = -1; + gps_almanac_type = -1; + gps_lap_transfer = -1; + gps_lap_type = -1; + + entries = packet->n / 3; + p = packet->data; + + for(i=0;i=200 && data <=202) + { + gps_rte_hdr_type = data; + continue; + } + if(data==210) + { + gps_rte_link_type = data; + continue; + } + + if(data<=110 && data>=100) + { + gps_rte_type = data; + continue; + } + if(data<153 && data>=150) + { + gps_rte_type = data; + continue; + } + if(data<156 && data>=154) + { + gps_rte_type = data; + continue; + } + if(data<451) + { + if(data==400) + gps_rte_type = pD400; + else if(data==403) + gps_rte_type = pD403; + else if(data==450) + gps_rte_type = pD450; + else + GPS_Protocol_Error(tag,data); + continue; + } + } + + else if(lasta<400) + { + switch (data) { + case 300: gps_trk_type = pD300; break; + case 301: gps_trk_type = pD301; break; + case 302: gps_trk_type = pD302; break; + case 303: gps_trk_type = pD303; break; + case 304: gps_trk_type = pD304; break; + case 310: gps_trk_hdr_type = pD310; break; + case 311: gps_trk_hdr_type = pD311; break; + case 312: gps_trk_hdr_type = pD312; break; + default: GPS_Protocol_Error(tag,data); break; + } + continue; + } + + else if(lasta<500) + { + if((data<=110 && data>=100) || + (data<153 && data>=150) || + (data<156 && data>=154)) { + gps_prx_waypt_type = data; + } + else if(data==400) + gps_prx_waypt_type = pD400; + else if(data==403) + gps_prx_waypt_type = pD403; + else if(data==450) + gps_prx_waypt_type = pD450; + else + GPS_Protocol_Error(tag,data); + continue; + } + + else if(lasta<600) + { + if(data==500) + gps_almanac_type = pD500; + else if(data==501) + gps_almanac_type = pD501; + else if(data==550) + gps_almanac_type = pD550; + else if(data==551) + gps_almanac_type = pD551; + else + GPS_Protocol_Error(tag,data); + continue; + } + + else if(lasta<650) + { + if (data == 600) { + gps_date_time_type = pD600; + } else { + /* Stupid undocumented 60 D601 packets */ + /* GPS_Protocol_Error(tag,data); */ + continue; + } + continue; + } + + else if(lasta<651) + { + /* FlightBook Transfer Protocol, not handled */ + continue; + } + + else if(lasta<800) + { + if(data!=700) + GPS_Protocol_Error(tag,data); + else + gps_position_type = pD700; + continue; + } + + else if(lasta<900) + { + if (data == 800) + gps_pvt_type = pD800; + /* + * Stupid, undocumented Vista 3.60 D802 packets + else + GPS_Protocol_Error(tag,data); + */ + continue; + } + + else if (lasta < 1000) + { + if (data == 906) + gps_lap_type = pD906; + else if (data == 1001) + gps_lap_type = pD1001; + else if (data == 1011) + gps_lap_type = pD1011; + else if (data == 1015) + gps_lap_type = pD1015; + continue; + } + + else if (lasta < 1002) + { + if (data == 1000) + gps_run_type = pD1000; + else if (data == 1009) + gps_run_type = pD1009; + else if (data == 1010) + gps_run_type = pD1010; + continue; + } + + else if (lasta < 1003) + { + if (data == 1002) + gps_workout_type = pD1002; + else if (data == 1008) + gps_workout_type = pD1008; + continue; + } + + else if (lasta < 1004) + { + if (data == 1003) + gps_workout_occurrence_type = pD1003; + continue; + } + + else if (lasta < 1005) + { + if (data == 1004) + gps_user_profile_type = pD1004; + continue; + } + + else if (lasta < 1006) + { + if (data == 1005) + gps_workout_limits_type = pD1005; + continue; + } + + else if (lasta < 1007) + { + if (data == 1006) + gps_course_type = pD1006; + continue; + } + + else if (lasta < 1008) + { + if (data == 1007) + gps_course_lap_type = pD1007; + continue; + } + + else if (lasta < 1009) + { + if (data == 1012) + gps_course_point_type = pD1012; + continue; + } + + else if (lasta < 1010) + { + if (data == 1013) + gps_course_limits_type = pD1013; + continue; + } + } + } + + GPS_User("\nLink_type %d Device_command %d\n", + gps_link_type, gps_device_command); + GPS_User("Waypoint: Transfer %d Type %d\n", + gps_waypt_transfer, gps_waypt_type); + GPS_User("Route: Transfer %d Header %d Type %d\n", + gps_route_transfer, gps_rte_hdr_type, gps_rte_type); + GPS_User("Track: Transfer %d Type %d\n", + gps_trk_transfer, gps_trk_type); + + return; +} + + + + +/* @func GPS_A100_Get ****************************************************** +** +** Get waypoint data from GPS +** +** @param [r] port [const char *] serial port +** @param [w] way [GPS_PWay **] waypoint array +** +** @return [int32] number of waypoint entries +************************************************************************/ +int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + + if(!GPS_Device_On(port,&fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + + if(!GPS_Write_Packet(fd,tra)) + { + GPS_Error("A100_Get: Cannot write packet"); + return FRAMING_ERROR; + } + + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A100_Get: No acknowledge"); + return FRAMING_ERROR; + } + + GPS_Packet_Read(fd, &rec); + GPS_Send_Ack(fd, &tra, &rec); + + n = GPS_Util_Get_Short(rec->data); + + if(n) + if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) + { + GPS_Error("A100_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + for(i=0;idata); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD103: + GPS_D103_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data, 109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data, 110); + break; + case pD150: + GPS_D150_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A100_GET: Unknown waypoint protocol: %d", gps_waypt_type); + return PROTOCOL_ERROR; + } + /* Issue callback for status updates. */ + if (cb) { + cb(n, &((*way)[i])); + } + } + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) + { + GPS_Error("A100_GET: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); + return FRAMING_ERROR; + } + + if(i != n) + { + GPS_Error("A100_GET: Waypoint entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return n; +} + + + + + +/* @func GPS_A100_Send ************************************************** +** +** Send waypoints to GPS +** +** @param [r] port [const char *] serial port +** @param [r] trk [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** +** @return [int32] success +************************************************************************/ +int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay *)) +{ + UC data[GPS_ARB_LEN]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + + if(!GPS_Device_On(port,&fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, (short) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("Waypoint start data not acknowledged"); + return gps_errno; + } + + + for(i=0;idata); + for (i = 0; i < n; ++i) { + if(!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if(!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + switch(gps_category_type) { + case pD120: + GPS_D120_Get(i,(char *) rec->data); + break; + } + } + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) + { + GPS_Error("A101_Get: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); + return FRAMING_ERROR; + } + + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; + +} + +/* @funcstatic GPS_D100_Get ********************************************* +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D100_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 100; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + return; +} + + + +/* @funcstatic GPS_D101_Get ********************************************* +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D101_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 101; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*way)->smbl = *p; + + return; +} + + + +/* @funcstatic GPS_D102_Get ******************************************** +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D102_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 102; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*way)->smbl = GPS_Util_Get_Short(p); + + + return; +} + + + +/* @funcstatic GPS_D103_Get ********************************************* +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D103_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 103; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->smbl = *p++; + (*way)->dspl = *p; + + + return; +} + + + +/* @funcstatic GPS_D104_Get ******************************************** +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D104_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 104; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + (*way)->dspl = *p; + + return; +} + + + +/* @funcstatic GPS_D105_Get ******************************************** +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D105_Get(GPS_PWay *way, UC *s) +{ + UC *p; + UC *q; + + p=s; + + (*way)->prot = 105; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + q = (UC *) (*way)->wpt_ident; + while((*q++ = *p++)); + + return; +} + + + +/* @funcstatic GPS_D106_Get ******************************************** +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +void GPS_D106_Get(GPS_PWay *way, UC *s) +{ + UC *p; + UC *q; + int32 i; + + p=s; + + (*way)->prot = 106; + + (*way)->wpt_class = *p++; + + for(i=0;i<13;++i) (*way)->subclass[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + q = (UC *) (*way)->wpt_ident; + while((*q++ = *p++)); + q = (UC *) (*way)->lnk_ident; + while((*q++ = *p++)); + + return; +} + + + +/* @funcstatic GPS_D107_Get ******************************************** +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D107_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 107; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->smbl = *p++; + (*way)->dspl = *p++; + + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*way)->colour = *p++; + + return; +} + + + +/* @funcstatic GPS_D108_Get ******************************************** +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D108_Get(GPS_PWay *way, UC *s) +{ + UC *p; + UC *q; + + int32 i; + + p=s; + + (*way)->prot = 108; + + (*way)->wpt_class = *p++; + (*way)->colour = *p++; + (*way)->dspl = *p++; + (*way)->attr = *p++; + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); + for(i=0;i<18;++i) (*way)->subclass[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + for(i=0;i<2;++i) (*way)->state[i] = *p++; + for(i=0;i<2;++i) (*way)->cc[i] = *p++; + + q = (UC *) (*way)->ident; + while((*q++ = *p++)); + + q = (UC *) (*way)->cmnt; + while((*q++ = *p++)); + + q = (UC *) (*way)->facility; + while((*q++ = *p++)); + + q = (UC *) (*way)->city; + while((*q++ = *p++)); + + q = (UC *) (*way)->addr; + while((*q++ = *p++)); + + q = (UC *) (*way)->cross_road; + while((*q++ = *p++)); + + return; +} + +/* @funcstatic GPS_D109_Get ******************************************** +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +** Quest uses D110's which are just like D109's but with the addition +** of temp, time, and wpt_cat stuck between ete and ident. Rather than +** duplicating the function, we just handle this at runtime. +************************************************************************/ +static void GPS_D109_Get(GPS_PWay *way, UC *s, int protoid) +{ + UC *p; + UC *q; + + int32 i; + + p=s; + + (*way)->prot = protoid; + + p++; /* data packet type */ + (*way)->wpt_class = *p++; + (*way)->colour = *p & 0x1f; + (*way)->dspl = (*p++ >> 5) & 3; + (*way)->attr = *p++; + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); + for(i=0;i<18;++i) (*way)->subclass[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + for(i=0;i<2;++i) (*way)->state[i] = *p++; + for(i=0;i<2;++i) (*way)->cc[i] = *p++; + + p += 4; /* Skip over "outbound link ete in seconds */ + if (protoid == 110) { + float gps_temp; + int gps_time; + gps_temp = GPS_Util_Get_Float(p); + p+=4; + if (gps_temp <= 1.0e24) { + (*way)->temperature_populated = 1; + (*way)->temperature = gps_temp; + } + + gps_time = GPS_Util_Get_Uint(p); + p+=4; + /* The spec says that 0xffffffff is unknown, but the 60CSX with + * firmware 2.5.0 writes zero. + */ + if (gps_time != 0xffffffff && gps_time != 0) { + (*way)->time_populated = 1; + (*way)->time = GPS_Math_Gtime_To_Utime(gps_time); + } + (*way)->category = GPS_Util_Get_Short(p); + p += 2; + } + + q = (UC *) (*way)->ident; + while((*q++ = *p++)); + + q = (UC *) (*way)->cmnt; + while((*q++ = *p++)); + + q = (UC *) (*way)->facility; + while((*q++ = *p++)); + + q = (UC *) (*way)->city; + while((*q++ = *p++)); + + q = (UC *) (*way)->addr; + while((*q++ = *p++)); + + q = (UC *) (*way)->cross_road; + while((*q++ = *p++)); + + return; +} + + +/* @funcstatic GPS_D150_Get ******************************************** +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D150_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 150; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + for(i=0;i<2;++i) (*way)->cc[i] = *p++; + (*way)->wpt_class = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + for(i=0;i<24;++i) (*way)->city[i] = *p++; + for(i=0;i<2;++i) (*way)->state[i] = *p++; + for(i=0;i<30;++i) (*way)->name[i] = *p++; + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + return; +} + + + +/* @funcstatic GPS_D151_Get ********************************************* +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D151_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 151; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + for(i=0;i<30;++i) (*way)->name[i] = *p++; + for(i=0;i<24;++i) (*way)->city[i] = *p++; + for(i=0;i<2;++i) (*way)->state[i] = *p++; + + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + for(i=0;i<2;++i) (*way)->cc[i] = *p++; + + ++p; + + (*way)->wpt_class = *p; + + return; +} + + + +/* @funcstatic GPS_D152_Get ******************************************** +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D152_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 152; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + for(i=0;i<30;++i) (*way)->name[i] = *p++; + for(i=0;i<24;++i) (*way)->city[i] = *p++; + for(i=0;i<2;++i) (*way)->state[i] = *p++; + + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + for(i=0;i<2;++i) (*way)->cc[i] = *p++; + + ++p; + + (*way)->wpt_class = *p; + + return; +} + + +/* @funcstatic GPS_D154_Get ******************************************** +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D154_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 154; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + for(i=0;i<30;++i) (*way)->name[i] = *p++; + for(i=0;i<24;++i) (*way)->city[i] = *p++; + for(i=0;i<2;++i) (*way)->state[i] = *p++; + + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + for(i=0;i<2;++i) (*way)->cc[i] = *p++; + + ++p; + + (*way)->wpt_class = *p++; + + (*way)->smbl = GPS_Util_Get_Short(p); + + return; +} + + +/* @funcstatic GPS_D155_Get ********************************************* +** +** Get waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D155_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 155; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + for(i=0;i<30;++i) (*way)->name[i] = *p++; + for(i=0;i<24;++i) (*way)->city[i] = *p++; + for(i=0;i<2;++i) (*way)->state[i] = *p++; + + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + for(i=0;i<2;++i) (*way)->cc[i] = *p++; + + ++p; + + (*way)->wpt_class = *p++; + + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + (*way)->dspl = *p; + + return; +} + +/* + * We'll cheat for now. We know there are no more than 16 categories + * as of this writing for no data type exposes more than 16 bits in the + * bitmask of categories. + */ +char gps_categories[16][17]; +/* + * Read descriptor s into category number N; + */ +static +void GPS_D120_Get(int cat_num, char *s) +{ + /* we're guaranteed to have no more than 16 chars plus a + * null terminator. + * + * If the unit returned no string, the user has not configured one, + * so mimic the behaviour of the 276/296. + */ + + if (*s) { + strncpy(gps_categories[cat_num], s, sizeof (gps_categories[0])); + } else { + snprintf(gps_categories[cat_num], sizeof (gps_categories[0]), + "Category %d", cat_num+1); + } +} + + +/* @funcstatic GPS_D100_Send ******************************************* +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D100_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + + *len = 58; + + return; +} + + +/* @funcstatic GPS_D101_Send ******************************************** +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D101_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + + + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); + + *p = way->smbl; + + *len = 63; + + return; +} + + +/* @funcstatic GPS_D102_Send ******************************************** +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D102_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); + + GPS_Util_Put_Short(p,(US) way->smbl); + + *len = 64; + + return; +} + + +/* @funcstatic GPS_D103_Send ******************************************* +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D103_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + + *p++ = (UC) way->smbl; + *p = (UC) way->dspl; + + *len = 60; + + return; +} + + +/* @funcstatic GPS_D104_Send ******************************************** +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D104_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + /* byonke confirms that sending lower case comment data to a III+ + * results in the comment being truncated there. So we uppercase + * the entire comment. + */ + copy_char_array(&p, way->cmnt, 40, UpperYes); + + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); + + GPS_Util_Put_Short(p, (int16) way->smbl); + p+=sizeof(int16); + + *p = 3; /* display symbol with waypoint name */ + + *len = 65; + + return; +} + + +/* @funcstatic GPS_D105_Send ******************************************* +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D105_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + UC *q; + + p = data; + + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + + GPS_Util_Put_Short(p, (int16) way->smbl); + p+=sizeof(int16); + + q = (UC *) way->wpt_ident; + while((*p++ = *q++)); + + + *len = p-data; + + return; +} + + +/* @funcstatic GPS_D106_Send ******************************************** +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D106_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + UC *q; + int32 i; + + p = data; + + *p++ = way->wpt_class; + for(i=0;i<13;++i) *p++ = way->subclass[i]; + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + + GPS_Util_Put_Short(p, (int16) way->smbl); + p+=sizeof(int16); + + q = (UC *) way->wpt_ident; + while((*p++ = *q++)); + q = (UC *) way->lnk_ident; + while((*p++ = *q++)); + + *len = p-data; + + return; +} + + +/* @funcstatic GPS_D107_Send ******************************************** +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D107_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + + *p++ = way->smbl; + *p++ = way->dspl; + + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); + + *p = way->colour; + + *len = 65; + + return; +} + + + +/* @funcstatic GPS_D108_Send ******************************************** +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + UC *q; + + int32 i; + + p = data; + + *p++ = way->wpt_class; + *p++ = way->colour; + *p++ = way->dspl; + *p++ = 0x60; + GPS_Util_Put_Short(p,(US) way->smbl); + p+=sizeof(int16); + for(i=0;i<18;++i) *p++ = way->subclass[i]; + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + + if (way->alt_is_unknown) { + GPS_Util_Put_Float(p,(const float) 1.0e25); + } else { + GPS_Util_Put_Float(p,way->alt); + } + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dpth); + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); + + for(i=0;i<2;++i) *p++ = way->state[i]; + for(i=0;i<2;++i) *p++ = way->cc[i]; + + + q = (UC *) way->ident; + i = XMIN(51, sizeof(way->ident)); + while((*p++ = *q++) && i--); + q = (UC *) way->cmnt; + i = XMIN(51, sizeof(way->cmnt)); + while((*p++ = *q++) && i--); + q = (UC *) way->facility; + i = XMIN(31, sizeof(way->facility)); + while((*p++ = *q++) && i--); + q = (UC *) way->city; + i = XMIN(25, sizeof(way->city)); + while((*p++ = *q++) && i--); + q = (UC *) way->addr; + i = XMIN(51, sizeof(way->addr)); + while((*p++ = *q++) && i--); + q = (UC *) way->cross_road; + i = XMIN(51, sizeof(way->cross_road)); + while((*p++ = *q++) && i--); + + *len = p-data; + + return; +} + + +/* @funcstatic GPS_D109_Send ******************************************** +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +** D109's and D110's are so simlar, we handle themw with the same code. +************************************************************************/ +static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int protoid) +{ + UC *p; + UC *q; + + int32 i; + + p = data; + + *p++ = 1; /* data packet type; must be 1 for D109 and D110 */ + *p++ = 0; // way->wpt_class; + + *p++ = ((way->dspl & 3) << 5) | 0x1f; /* colour & display */ + + if (protoid == 109) { /* attr */ + *p++ = 0x70; + } else if (protoid == 110) { + *p++ = 0x80; + } else { + GPS_Warning("Unknown protoid in GPS_D109_Send."); + } + GPS_Util_Put_Short(p,(US) way->smbl); + p+=sizeof(int16); + for(i=0;i<18;++i) *p++ = way->subclass[i]; + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + if (way->alt_is_unknown) { + GPS_Util_Put_Float(p,(const float) 1.0e25); + } else { + GPS_Util_Put_Float(p,way->alt); + } + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dpth); + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); + + for(i=0;i<2;++i) *p++ = way->state[i]; + for(i=0;i<2;++i) *p++ = way->cc[i]; + for(i=0;i<4;++i) *p++ = 0xff; /* D109 silliness for ETE */ + if (protoid == 110) { + float temp = 1.0e25f; + + GPS_Util_Put_Float(p, temp); + p += 4; + + if (way->time_populated) { + GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(way->time)); + p+=sizeof(uint32); + } else { + for(i=0;i<4;++i) *p++ = 0xff; /* unknown time*/ + } + + GPS_Util_Put_Short(p, (US) way->category);; /* D110 category */ + p += 2; + } + + q = (UC *) way->ident; + i = XMIN(51, sizeof(way->ident)); + while((*p++ = *q++) && i--); + q = (UC *) way->cmnt; + i = XMIN(51, sizeof(way->cmnt)); + while((*p++ = *q++) && i--); + q = (UC *) way->facility; + i = XMIN(31, sizeof(way->facility)); + while((*p++ = *q++) && i--); + q = (UC *) way->city; + i = XMIN(25, sizeof(way->city)); + while((*p++ = *q++) && i--); + q = (UC *) way->addr; + i = XMIN(51, sizeof(way->addr)); + while((*p++ = *q++) && i--); + q = (UC *) way->cross_road; + i = XMIN(51, sizeof(way->cross_road)); + while((*p++ = *q++) && i--); + *len = p-data; + return; +} + + +/* @funcstatic GPS_D150_Send ******************************************** +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D150_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + int32 i; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + for(i=0;i<2;++i) *p++ = way->cc[i]; + + if(way->wpt_class == 7) way->wpt_class = 0; + *p++ = way->wpt_class; + + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); + + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->cmnt, 40, UpperYes); + + *len = 115; + + return; +} + + +/* @funcstatic GPS_D151_Send ******************************************** +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D151_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + int32 i; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); + + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); + + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); + + for(i=0;i<2;++i) *p++ = way->cc[i]; + *p++ = 0; + + if(way->wpt_class == 3) way->wpt_class = 0; + *p = way->wpt_class; + + *len = 124; + + return; +} + + + +/* @funcstatic GPS_D152_Send ******************************************** +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D152_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + int32 i; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); + + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); + + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); + + for(i=0;i<2;++i) *p++ = way->cc[i]; + *p++ = 0; + + if(way->wpt_class == 5) way->wpt_class = 0; + *p = way->wpt_class; + + *len = 124; + + return; +} + + +/* @funcstatic GPS_D154_Send ******************************************* +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D154_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + int32 i; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); + + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); + + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); + + for(i=0;i<2;++i) *p++ = way->cc[i]; + *p++ = 0; + + if(way->wpt_class == 9) way->wpt_class = 0; + *p++ = way->wpt_class; + + GPS_Util_Put_Short(p,(int16)way->smbl); + + *len = 126; + + return; +} + + + +/* @funcstatic GPS_D155_Send ******************************************* +** +** Form waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + + p = data; + + copy_char_array(&p, way->ident, 6, UpperYes); + + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); + + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); + + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); + + copy_char_array(&p, way->cc, 2, UpperYes); + *p++ = 0; + + /* Ignore wpt_class; our D155 points are always user type which is "4". */ + *p++ = 4; + + GPS_Util_Put_Short(p,(int16)way->smbl); + p+=sizeof(int16); + + *p = way->dspl; + + *len = 127; + + return; +} + + + +/* @func GPS_A200_Get ****************************************************** +** +** Get route data from GPS +** +** @param [r] port [const char *] serial port +** @param [w] way [GPS_PWay **] waypoint array +** +** @return [int32] number of waypoint entries +************************************************************************/ +int32 GPS_A200_Get(const char *port, GPS_PWay **way) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + + if(!GPS_Device_On(port,&fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Rte); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_errno; + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + n = GPS_Util_Get_Short(rec->data); + + if(n) + if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) + { + GPS_Error("A200_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + + for(i=0;itype == LINK_ID[gps_link_type].Pid_Rte_Hdr) + { + switch(gps_rte_hdr_type) + { + case pD200: + GPS_D200_Get(&((*way)[i]),rec->data); + break; + case pD201: + GPS_D201_Get(&((*way)[i]),rec->data); + break; + case pD202: + GPS_D202_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A200_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + continue; + } + + if(rec->type != LINK_ID[gps_link_type].Pid_Rte_Wpt_Data) + { + GPS_Error("A200_GET: Non Pid_rte_Wpt_Data"); + return FRAMING_ERROR; + } + + (*way)[i]->isrte = 0; + (*way)[i]->islink = 0; + + switch(gps_rte_type) + { + case pD100: + GPS_D100_Get(&((*way)[i]),rec->data); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD103: + GPS_D103_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data,109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data,110); + break; + case pD150: + GPS_D150_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A200_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i-1]->prot = (*way)[i]->prot; + } + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) + { + GPS_Error("A200_GET: Error transferring routes"); + return FRAMING_ERROR; + } + + if(i != n) + { + GPS_Error("A200_GET: Route entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return n; +} + + + +/* @func GPS_A201_Get ****************************************************** +** +** Get route data from GPS +** +** @param [r] port [const char *] serial port +** @param [w] way [GPS_PWay **] waypoint array +** +** @return [int32] number of waypoint entries +************************************************************************/ +int32 GPS_A201_Get(const char *port, GPS_PWay **way) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + + if(!GPS_Device_On(port,&fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Rte); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_errno; + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + n = GPS_Util_Get_Short(rec->data); + + if(n) + if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) + { + GPS_Error("A201_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + + for(i=0;itype == LINK_ID[gps_link_type].Pid_Rte_Hdr) + { + switch(gps_rte_hdr_type) + { + case pD200: + GPS_D200_Get(&((*way)[i]),rec->data); + break; + case pD201: + GPS_D201_Get(&((*way)[i]),rec->data); + break; + case pD202: + GPS_D202_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A201_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i]->islink = 0; + continue; + } + + + if(rec->type == LINK_ID[gps_link_type].Pid_Rte_Link_Data) + { + switch(gps_rte_link_type) + { + case pD210: + GPS_D210_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A201_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i]->isrte = 0; + (*way)[i]->islink = 1; + continue; + } + + if(rec->type != LINK_ID[gps_link_type].Pid_Rte_Wpt_Data) + { + GPS_Error("A200_GET: Non Pid_rte_Wpt_Data"); + return FRAMING_ERROR; + } + + (*way)[i]->isrte = 0; + (*way)[i]->islink = 0; + + switch(gps_rte_type) + { + case pD100: + GPS_D100_Get(&((*way)[i]),rec->data); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD103: + GPS_D103_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data,109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data,110); + break; + case pD150: + GPS_D150_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A200_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i-1]->prot = (*way)[i]->prot; + } + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) + { + GPS_Error("A200_GET: Error transferring routes"); + return FRAMING_ERROR; + } + + if(i != n) + { + GPS_Error("A200_GET: Route entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return n; +} + + + +/* @func GPS_A200_Send ************************************************** +** +** Send routes to GPS +** +** @param [r] port [const char *] serial port +** @param [r] trk [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** +** @return [int32] success +************************************************************************/ +int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n) +{ + UC data[GPS_ARB_LEN]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + UC method; + + if(!GPS_Device_On(port,&fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A200_Send: Route start data not acknowledged"); + return FRAMING_ERROR; + } + + + for(i=0;iisrte) + { + method = LINK_ID[gps_link_type].Pid_Rte_Hdr; + + switch(gps_rte_hdr_type) + { + case pD200: + GPS_D200_Send(data,way[i],&len); + break; + case pD201: + GPS_D201_Send(data,way[i],&len); + break; + case pD202: + GPS_D202_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } + else + { + method = LINK_ID[gps_link_type].Pid_Rte_Wpt_Data; + + switch(gps_rte_type) + { + case pD100: + GPS_D100_Send(data,way[i],&len); + break; + case pD101: + GPS_D101_Send(data,way[i],&len); + break; + case pD102: + GPS_D102_Send(data,way[i],&len); + break; + case pD103: + GPS_D103_Send(data,way[i],&len); + break; + case pD104: + GPS_D104_Send(data,way[i],&len); + break; + case pD105: + GPS_D105_Send(data,way[i],&len); + break; + case pD106: + GPS_D106_Send(data,way[i],&len); + break; + case pD107: + GPS_D107_Send(data,way[i],&len); + break; + case pD108: + GPS_D108_Send(data,way[i],&len); + break; + case pD150: + GPS_D150_Send(data,way[i],&len); + break; + case pD151: + GPS_D151_Send(data,way[i],&len); + break; + case pD152: + GPS_D152_Send(data,way[i],&len); + break; + case pD154: + GPS_D154_Send(data,way[i],&len); + break; + case pD155: + GPS_D155_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } + + + GPS_Make_Packet(&tra, method, data,(US) len); + + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A200_Send: Route packet not acknowledged"); + return FRAMING_ERROR; + } + } + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A200_Send: Route complete data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; +} + + + +/* @func GPS_A201_Send ************************************************** +** +** Send routes to GPS +** +** @param [r] port [const char *] serial port +** @param [r] trk [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** +** @return [int32] success +************************************************************************/ +int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n) +{ + UC data[GPS_ARB_LEN]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + UC method; + + if(!GPS_Device_On(port,&fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A200_Send: Route start data not acknowledged"); + return FRAMING_ERROR; + } + + + for(i=0;iisrte) + { + method = LINK_ID[gps_link_type].Pid_Rte_Hdr; + + switch(gps_rte_hdr_type) + { + case pD200: + GPS_D200_Send(data,way[i],&len); + break; + case pD201: + GPS_D201_Send(data,way[i],&len); + break; + case pD202: + GPS_D202_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } + else if(way[i]->islink) + { + method = LINK_ID[gps_link_type].Pid_Rte_Link_Data; + + switch(gps_rte_link_type) + { + case pD210: + GPS_D210_Send(data,way[i],&len); + break; + default: + GPS_Error("A201_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } + else + { + method = LINK_ID[gps_link_type].Pid_Rte_Wpt_Data; + + switch(gps_rte_type) + { + case pD100: + GPS_D100_Send(data,way[i],&len); + break; + case pD101: + GPS_D101_Send(data,way[i],&len); + break; + case pD102: + GPS_D102_Send(data,way[i],&len); + break; + case pD103: + GPS_D103_Send(data,way[i],&len); + break; + case pD104: + GPS_D104_Send(data,way[i],&len); + break; + case pD105: + GPS_D105_Send(data,way[i],&len); + break; + case pD106: + GPS_D106_Send(data,way[i],&len); + break; + case pD107: + GPS_D107_Send(data,way[i],&len); + break; + case pD108: + GPS_D108_Send(data,way[i],&len); + break; + case pD109: + GPS_D109_Send(data,way[i],&len, 109); + break; + case pD110: + GPS_D109_Send(data,way[i],&len, 110); + break; + case pD150: + GPS_D150_Send(data,way[i],&len); + break; + case pD151: + GPS_D151_Send(data,way[i],&len); + break; + case pD152: + GPS_D152_Send(data,way[i],&len); + break; + case pD154: + GPS_D154_Send(data,way[i],&len); + break; + case pD155: + GPS_D155_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } + + + GPS_Make_Packet(&tra, method, data,(US) len); + + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A200_Send: Route packet not acknowledged"); + return FRAMING_ERROR; + } + } + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A200_Send: Route complete data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; +} + + + + + +/* @funcstatic GPS_D200_Get ******************************************** +** +** Get route header data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D200_Get(GPS_PWay *way, UC *s) +{ + (*way)->rte_prot = 200; + (*way)->rte_num = *s; + (*way)->isrte = 1; + + return; +} + + + +/* @funcstatic GPS_D201_Get ******************************************* +** +** Get route header data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D201_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->rte_prot = 201; + (*way)->rte_num = *p++; + (*way)->isrte = 1; + for(i=0;i<20;++i) (*way)->rte_cmnt[i] = *p++; + + return; +} + + + +/* @funcstatic GPS_D202_Get ******************************************** +** +** Get route header data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D202_Get(GPS_PWay *way, UC *s) +{ + UC *p; + UC *q; + + p=s; + + (*way)->rte_prot = 202; +#if 0 + /* D202 has only a null terminated string for rte_ident */ + (*way)->rte_num = *p++; +#endif + (*way)->isrte = 1; + q = (UC *) (*way)->rte_ident; + while((*q++=*p++)); + + return; +} + + + +/* @funcstatic GPS_D210_Get ******************************************** +** +** Get route link data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D210_Get(GPS_PWay *way, UC *s) +{ + UC *p; + UC *q; + int32 i; + + p=s; + + (*way)->rte_link_class = GPS_Util_Get_Short(p); + p+=sizeof(int16); + for(i=0;i<18;++i) (*way)->rte_link_subclass[i] = *p++; + q = (UC *) (*way)->rte_link_ident; + while((*q++=*p++)); + + return; +} + + + +/* @funcstatic GPS_D200_Send ******************************************* +** +** Form route header data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D200_Send(UC *data, GPS_PWay way, int32 *len) +{ + + *data = way->rte_num; + *len = 1; + + return; +} + + + +/* @funcstatic GPS_D201_Send ******************************************* +** +** Form route header data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D201_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + int32 i; + + p = data; + + *p++ = way->rte_num; + for(i=0;i<20;++i) *p++ = way->rte_cmnt[i]; + *len = 21; + + return; +} + + + +/* @funcstatic GPS_D202_Send ******************************************** +** +** Form route header data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D202_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + UC *q; + + p = data; + q = (UC *) way->rte_ident; + + while((*p++ = *q++)); + + *len = p-data; + + return; +} + + + +/* @funcstatic GPS_D210_Send ******************************************** +** +** Form route link data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D210_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + UC *q; + int32 i; + + p = data; + + GPS_Util_Put_Short(p,(US) way->rte_link_class); + p+=sizeof(int16); + for(i=0;i<18;++i) *p++ = way->rte_link_subclass[i]; + + q = (UC *) way->rte_link_ident; + while((*p++ = *q++)); + + *len = p-data; + + return; +} + + + +/* @func GPS_A300_Get ****************************************************** +** +** Get track data from GPS +** +** @param [r] port [const char *] serial port +** @param [w] trk [GPS_PTrack **] track array +** +** @return [int32] number of track entries +************************************************************************/ +int32 GPS_A300_Get(const char *port, GPS_PTrack **trk, pcb_fn cb) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + int32 ret; + + + if(gps_trk_transfer == -1) + return GPS_UNSUPPORTED; + + /* Only those GPS' with L001 can send track data */ + if(!LINK_ID[gps_link_type].Pid_Trk_Data) + { + GPS_Warning("A300 protocol unsupported"); + return GPS_UNSUPPORTED; + } + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_errno; + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + + n = GPS_Util_Get_Short(rec->data); + + if(n) + if(!((*trk)=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack)))) + { + GPS_Error("A300_Get: Insufficient memory"); + return MEMORY_ERROR; + } + for(i=0;itype == LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + break; + } + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + return 0; +} + +/* @func GPS_A301_Get ****************************************************** +** +** Get track data from GPS +** +** @param [r] port [const char *] serial port +** @param [w] trk [GPS_PTrack **] track array +** +** @return [int32] number of track entries +************************************************************************/ +int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + if(gps_trk_transfer == -1) + return GPS_UNSUPPORTED; + + /* Only those GPS' with L001 can send track data */ + if(!LINK_ID[gps_link_type].Pid_Trk_Data) + { + GPS_Warning("A301 protocol unsupported"); + return GPS_UNSUPPORTED; + } + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if ((gps_trk_type == pD304) && gps_run_transfer) { + drain_run_cmd(fd); + } + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_errno; + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + + n = GPS_Util_Get_Short(rec->data); + + if(n) + if(!((*trk)=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack)))) + { + GPS_Error("A301_Get: Insufficient memory"); + return MEMORY_ERROR; + } + for(i=0;itype == LINK_ID[gps_link_type].Pid_Trk_Hdr) + { + switch(gps_trk_hdr_type) + { + case pD310: + case pD312: + GPS_D310_Get(&((*trk)[i]),rec->data); + break; + case pD311: + GPS_D311_Get(&((*trk)[i]),rec->data); + break; + default: + GPS_Error("A301_Get: Unknown track protocol"); + return PROTOCOL_ERROR; + } + (*trk)[i]->ishdr = 1; + continue; + } + + if(rec->type != LINK_ID[gps_link_type].Pid_Trk_Data) + { + GPS_Error("A301_Get: Non-Pid_Trk_Data"); + return FRAMING_ERROR; + } + + (*trk)[i]->ishdr = 0; + + switch(gps_trk_type) + { + case pD300: + GPS_D300b_Get(&((*trk)[i]),rec->data); + break; + case pD301: + GPS_D301b_Get(&((*trk)[i]),rec->data); + break; + case pD302: + GPS_D302b_Get(&((*trk)[i]),rec->data); + break; + case pD303: + case pD304: + GPS_D303b_Get(&((*trk)[i]),rec->data); + break; + default: + GPS_Error("A301_GET: Unknown track protocol"); + return PROTOCOL_ERROR; + } + /* Cheat and don't _really_ pass the trkpt back */ + cb(n, NULL); + } + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) + { + GPS_Error("A301_Get: Error transferring tracks"); + return FRAMING_ERROR; + } + + if(i != n) + { + GPS_Error("A301_GET: Track entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return n; +} + + + + + +/* @func GPS_A300_Send ************************************************** +** +** Send track log to GPS +** +** @param [r] port [const char *] serial port +** @param [r] trk [GPS_PTrack *] track array +** @param [r] n [int32] number of track entries +** +** @return [int32] success +************************************************************************/ +int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n) +{ + UC data[GPS_ARB_LEN]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + + if(gps_trk_transfer == -1) + return GPS_UNSUPPORTED; + + /* Only those GPS' with L001 can send track data */ + if(!LINK_ID[gps_link_type].Pid_Trk_Data) + { + GPS_Warning("A300 protocol unsupported"); + return GPS_UNSUPPORTED; + } + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A300_Send: Track start data not acknowledged"); + return FRAMING_ERROR; + } + + for(i=0;iishdr) + { + method = LINK_ID[gps_link_type].Pid_Trk_Hdr; + + switch(gps_trk_hdr_type) + { + case pD310: + case pD312: + GPS_D310_Send(data,trk[i],&len); + break; + default: + GPS_Error("A301_Send: Unknown track protocol"); + return PROTOCOL_ERROR; + } + } + else + { + method = LINK_ID[gps_link_type].Pid_Trk_Data; + + switch(gps_trk_type) + { + case pD300: + GPS_D300_Send(data,trk[i]); + len = 13; + break; + case pD301: + case pD302: + GPS_D301_Send(data,trk[i]); + len = 21; + break; + case pD304: + GPS_D304_Send(data,trk[i]); + len = 26; + break; + default: + GPS_Error("A301_Send: Unknown track protocol"); + return PROTOCOL_ERROR; + } + } + + + GPS_Make_Packet(&tra, method, data,(US) len); + + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A301_Send: Track packet not acknowledgedn"); + return FRAMING_ERROR; + } + } + + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A301_Send: Track complete data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; +} + + + +/* @func GPS_D300_Get ****************************************************** +** +** Get track data +** +** @param [w] trk [GPS_PTrack *] track array +** @param [r] entries [int32] number of packets to receive +** @param [r] fd [int32] file descriptor +** +** @return [int32] number of entries read +************************************************************************/ +int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *fd) +{ + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + for(i=0;idata, &trk[i]); + } + + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + + if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) + { + GPS_Error("D300_GET: Error transferring track log"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + return i; +} + + + +/* @func GPS_D300b_Get ****************************************************** +** +** Get track data (A301 protocol) +** +** @param [w] trk [GPS_PTrack *] track +** @param [r] data [UC *] packet data +** +** @return [void] +************************************************************************/ +void GPS_D300b_Get(GPS_PTrack *trk, UC *data) +{ + + GPS_A300_Translate(data, trk); + return; +} + + + +/* @func GPS_D301b_Get ****************************************************** +** +** Get track data (A301 protocol) +** +** @param [w] trk [GPS_PTrack *] track +** @param [r] data [UC *] packet data +** +** @return [void] +************************************************************************/ +void GPS_D301b_Get(GPS_PTrack *trk, UC *data) +{ + UC *p; + uint32 t; + + p=data; + + (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + t = GPS_Util_Get_Uint(p); + if(!t || t==0x7fffffff || t==0xffffffff) + (*trk)->Time=0; + else + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + p+=sizeof(uint32); + + (*trk)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*trk)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*trk)->tnew = *p; + + return; +} + +/* @func GPS_D302b_Get ****************************************************** +** +** Get track data (A301 protocol) +** +** @param [w] trk [GPS_PTrack *] track +** @param [r] data [UC *] packet data +** +** @return [void] +************************************************************************/ +void GPS_D302b_Get(GPS_PTrack *trk, UC *data) +{ + UC *p; + uint32 t; + double gps_temp; + + p=data; + + (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + t = GPS_Util_Get_Uint(p); + if(!t || t==0x7fffffff || t==0xffffffff) + (*trk)->Time=0; + else + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + p+=sizeof(uint32); + + (*trk)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*trk)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); + + /* The only difference between 302 and 301 is the presence of temp + * in the middle. Nice planning, eh? + */ + gps_temp = GPS_Util_Get_Float(p); + if (gps_temp <= 1.0e24) { + (*trk)->temperature_populated = 1; + (*trk)->temperature = gps_temp; + } + + p+=sizeof(float); + + (*trk)->tnew = *p; + + return; +} + + +/* @func GPS_D303b_Get ****************************************************** +** +** Get track data (A302 protocol) -- used in Forerunner 301 +** +** @param [w] trk [GPS_PTrack *] track +** @param [r] data [UC *] packet data +** +** @return [void] +************************************************************************/ +void GPS_D303b_Get(GPS_PTrack *trk, UC *data) +{ + UC *p; + uint32 t; + uint32 raw_lat, raw_lon; + int lat_undefined, lon_undefined; + p=data; + + /* Latitude and longitude are sometimes invalid (0x7fffffff or + * maybe 0xffffffff?) I guess this makes sense if the device is + * reporting heart rate and time anyway. I presume that latitude + * and longitude are defined or left undefined together? + */ + raw_lat = GPS_Util_Get_Int(p); + lat_undefined = !raw_lat || raw_lat==0x7fffffff || raw_lat==0xffffffff; + if (lat_undefined) + (*trk)->lat=0; + else + (*trk)->lat = GPS_Math_Semi_To_Deg(raw_lat); + p+=sizeof(int32); + + raw_lon = GPS_Util_Get_Int(p); + lon_undefined = !raw_lon || raw_lon==0x7fffffff || raw_lon==0xffffffff; + if (lon_undefined) + (*trk)->lon=0; + else + (*trk)->lon = GPS_Math_Semi_To_Deg(raw_lon); + p+=sizeof(int32); + + /* + * Let the caller decide if it wants to toss trackpionts with only + * hear and/or time data. + */ + if (lat_undefined || lon_undefined) { + (*trk)->no_latlon = 1; + } + + if (lat_undefined != lon_undefined) + GPS_Warning("GPS_D303b_Get: assumption (lat_undefined == lon_undefined) violated"); + + t = GPS_Util_Get_Uint(p); + + if(!t || t==0x7fffffff || t==0xffffffff) + (*trk)->Time=0; + else + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + p+=sizeof(uint32); + + /* When latitude and longitude are undefined, this field seems to be + * a constant on my receiver (51 59 04 69) */ + (*trk)->alt = GPS_Util_Get_Float(p); + if (lat_undefined || lon_undefined) (*trk)->alt = 0.0f; + p+=sizeof(float); + + /* Heartrate is reported as 0 if there is no signal from + * a heartrate monitor. + * 305 and 304 are identical until now. + */ + switch (gps_trk_type) { + case pD304: + (*trk)->distance = GPS_Util_Get_Float(p); + p+=sizeof(float); /* A float indicating number of meters travelled. */ + + (*trk)->heartrate = (*p++); + /* crank cadence, RPM, 0xff if invalid. */ + if (*p != 0xff) { + (*trk)->cadence = (*p); + } + + /* sensor present. Boolean */ + p++; + + break; + case pD303: + (*trk)->heartrate = *p++; + break; + } + + /* There doesn't seem to be a trk_seg bool, or at least I've not + * observed it yet. One possibility is to start a new segment + * each time latitude and longitude are undefined? (Ie data from + * the heartrate monitor but none from the GPS. */ + (*trk)->tnew = 0; + + return; +} + + +/* @func GPS_D310_Get ****************************************************** +** +** Get track header data (A301 protocol) +** +** @param [w] trk [GPS_PTrack *] track +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +void GPS_D310_Get(GPS_PTrack *trk, UC *s) +{ + UC *p; + UC *q; + + p=s; + + (*trk)->dspl = *p++; + (*trk)->colour = *p++; + + q = (UC *) (*trk)->trk_ident; + + while((*q++ = *p++)); + + return; +} + +/* @func GPS_D311_Get ****************************************************** +** +** Get track header data (A301 protocol) +** +** @param [w] trk [GPS_PTrack *] track +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +void GPS_D311_Get(GPS_PTrack *trk, UC *s) +{ + UC *p; + short identifier; + + p=s; + + /* Forerunner */ + identifier = GPS_Util_Get_Short(s); + sprintf((*trk)->trk_ident, "%d", identifier); + (*trk)->tnew = 1; + + return; +} + + +/* @func GPS_D300_Send ************************************************** +** +** Form track data string +** +** @param [w] data [UC *] string to write to +** @param [r] trk [GPS_PTrack] track data +** +** @return [void] +************************************************************************/ +void GPS_D300_Send(UC *data, GPS_PTrack trk) +{ + UC *p; + + p = data; + GPS_A300_Encode(p,trk); + + return; +} + + + +/* @func GPS_D301_Send ************************************************** +** +** Form track data string +** +** @param [w] data [UC *] string to write to +** @param [r] trk [GPS_PTrack] track data +** +** @return [void] +************************************************************************/ +void GPS_D301_Send(UC *data, GPS_PTrack trk) +{ + UC *p; + + p = data; + GPS_A300_Encode(p,trk); + p = data+12; + + GPS_Util_Put_Float(p,trk->alt); + p+=sizeof(float); + GPS_Util_Put_Float(p,trk->dpth); + p+=sizeof(float); + + *p = trk->tnew; + + return; +} + +void GPS_D304_Send(UC *data, GPS_PTrack trk) +{ + UC *p; + + p = data; + GPS_A300_Encode(p,trk); + p = data+12; + + GPS_Util_Put_Float(p,trk->alt); + p+=sizeof(float); + + GPS_Util_Put_Float(p, (const float) 1.0e25); + p+=sizeof(float); + + /* Not really clear if the members below makes sense to write or not */ + + *p = trk->heartrate; + p+=sizeof(char); + + *p = trk->cadence; + p+=sizeof(char); + + *p = trk->cadence > 0 ? trk->cadence : 0xff; + p+=sizeof(char); + + *p = trk->tnew; + + return; +} + + + +/* @func GPS_D310_Send ************************************************** +** +** Form track header data string +** +** @param [w] data [UC *] string to write to +** @param [r] trk [GPS_PTrack] track data +** @param [w] len [int32 *] length of data +** +** @return [void] +************************************************************************/ +void GPS_D310_Send(UC *data, GPS_PTrack trk, int32 *len) +{ + UC *p; + UC *q; + + p = data; + + *p++ = trk->dspl; + *p++ = trk->colour; + + q = (UC *) trk->trk_ident; + while((*p++ = *q++)); + + *len = p-data; + + return; +} + + +/* @funcstatic GPS_A300_Translate *************************************** +** +** Translate track packet to track structure +** +** @param [r] s [const UC *] track packet data +** @param [w] trk [GPS_PTrack *] track entry pointer +** +** @return [void] +************************************************************************/ +static void GPS_A300_Translate(UC *s, GPS_PTrack *trk) +{ + UC *p; + uint32 t; + + p=s; + + (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + t = GPS_Util_Get_Uint(p); + if(!t || t==0x7fffffff || t==0xffffffff) + (*trk)->Time=0; + else + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + p+=sizeof(uint32); + + (*trk)->tnew = *p; + + return; +} + + + +/* @funcstatic GPS_A300_Encode *************************************** +** +** Encode track structure to track packet +** +** @param [w] s [UC *] string to write to +** @param [r] trk [GPS_PTrack] track entry +** +** @return [void] +************************************************************************/ +static void GPS_A300_Encode(UC *s, GPS_PTrack trk) +{ + UC *p; + + p=s; + + GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(trk->lat)); + p+=sizeof(int32); + + GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(trk->lon)); + p+=sizeof(int32); + + GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(trk->Time)); + p+=sizeof(uint32); + + *p = (UC) trk->tnew; + + return; +} + + + +/* @func GPS_A400_Get ************************************************** +** +** Get proximity waypoint data from GPS +** +** @param [r] port [const char *] serial port +** @param [w] way [GPS_PWay **] waypoint array +** +** @return [int32] number of waypoint entries +************************************************************************/ +int32 GPS_A400_Get(const char *port, GPS_PWay **way) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + if(gps_prx_waypt_transfer == -1) + return GPS_UNSUPPORTED; + + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Prx); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_errno; + + if(!GPS_Device_Chars_Ready(fd)) + { + GPS_Warning("A400 (ppx) protocol not supported"); + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return GPS_UNSUPPORTED; + } + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + n = GPS_Util_Get_Short(rec->data); + + if(n) + if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) + { + GPS_Error("A400_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + + for(i=0;idata); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD403: + GPS_D403_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data,109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data,110); + break; + case pD450: + GPS_D450_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A400_GET: Unknown prx waypoint protocol"); + return PROTOCOL_ERROR; + } + } + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) + { + GPS_Error("A400_GET: Error transferring prx waypoints"); + return FRAMING_ERROR; + } + + if(i != n) + { + GPS_Error("A400_GET: Prx waypoint entry number mismatch"); + return FRAMING_ERROR; + } + + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return n; +} + + + +/* @func GPS_A400_Send ************************************************** +** +** Send proximity waypoints to GPS +** +** @param [r] port [const char *] serial port +** @param [r] trk [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** +** @return [int32] success +************************************************************************/ +int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n) +{ + UC data[GPS_ARB_LEN]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + + if(gps_prx_waypt_transfer == -1) + return GPS_UNSUPPORTED; + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A400_Send: Prx start data not acknowledgedn"); + return FRAMING_ERROR; + } + + + for(i=0;iprot = 400; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->dst=GPS_Util_Get_Float(p); + + + return; +} + + +/* @funcstatic GPS_D403_Get ******************************************** +** +** Get proximity waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D403_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 403; + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + p+=sizeof(int32); + + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->smbl = *p++; + (*way)->dspl = *p++; + + (*way)->dst=GPS_Util_Get_Float(p); + + return; +} + + +/* @funcstatic GPS_D450_Get ******************************************** +** +** Get proximity waypoint data +** +** @param [w] way [GPS_PWay *] waypoint array +** @param [r] s [UC *] packet data +** +** @return [void] +************************************************************************/ +static void GPS_D450_Get(GPS_PWay *way, UC *s) +{ + UC *p; + int32 i; + + p=s; + + (*way)->prot = 450; + + (*way)->idx = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + for(i=0;i<6;++i) (*way)->ident[i] = *p++; + for(i=0;i<2;++i) (*way)->cc[i] = *p++; + (*way)->wpt_class = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + for(i=0;i<24;++i) (*way)->city[i] = *p++; + for(i=0;i<2;++i) (*way)->state[i] = *p++; + for(i=0;i<30;++i) (*way)->name[i] = *p++; + for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + + (*way)->dst=GPS_Util_Get_Float(p); + + return; +} + + +/* @funcstatic GPS_D400_Send ******************************************** +** +** Form proximity waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D400_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + int32 i; + + p = data; + + for(i=0;i<6;++i) *p++ = way->ident[i]; + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + for(i=0;i<40;++i) *p++ = way->cmnt[i]; + + GPS_Util_Put_Float(p,way->dst); + + *len = 62; + + return; +} + + +/* @funcstatic GPS_D403_Send ******************************************* +** +** Form proximity waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D403_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + int32 i; + + p = data; + + for(i=0;i<6;++i) *p++ = way->ident[i]; + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + for(i=0;i<40;++i) *p++ = way->cmnt[i]; + + *p++ = way->smbl; + *p = way->dspl; + + GPS_Util_Put_Float(p,way->dst); + + *len = 64; + + return; +} + + +/* @funcstatic GPS_D450_Send ******************************************* +** +** Form proximity waypoint data string +** +** @param [w] data [UC *] string to write to +** @param [r] way [GPS_PWay] waypoint data +** @param [w] len [int32 *] packet length +** +** @return [void] +************************************************************************/ +static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len) +{ + UC *p; + int32 i; + + p = data; + + GPS_Util_Put_Short(p,(US) way->idx); + p+=sizeof(int16); + + for(i=0;i<6;++i) *p++ = way->ident[i]; + for(i=0;i<2;++i) *p++ = way->cc[i]; + *p++ = way->wpt_class; + + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); + + for(i=0;i<24;++i) *p++ = way->city[i]; + for(i=0;i<2;++i) *p++ = way->state[i]; + for(i=0;i<30;++i) *p++ = way->name[i]; + for(i=0;i<40;++i) *p++ = way->cmnt[i]; + + GPS_Util_Put_Float(p,way->dst); + + + *len = 121; + + return; +} + + + +/* @func GPS_A500_Get ****************************************************** +** +** Get almanac from GPS +** +** @param [r] port [const char *] serial port +** @param [w] alm [GPS_PAlmanac **] almanac array +** +** @return [int32] number of almanac entries +************************************************************************/ +int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_almanac_transfer == -1) + return GPS_UNSUPPORTED; + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Alm); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,trapkt)) + return gps_errno; + if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) + return gps_errno; + if(!GPS_Packet_Read(fd, &recpkt)) + return gps_errno; + if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) + return gps_errno; + + n = GPS_Util_Get_Short(recpkt->data); + + if(n) + if(!((*alm)=(GPS_PAlmanac *)malloc(n*sizeof(GPS_PAlmanac)))) + { + GPS_Error("A500_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + for(i=0;idata, &((*alm)[i])); + break; + case pD501: + GPS_A500_Translate(recpkt->data, &((*alm)[i])); + (*alm)[i]->hlth=recpkt->data[42]; + break; + case pD550: + (*alm)[i]->svid = recpkt->data[0]; + GPS_A500_Translate(recpkt->data+1, &((*alm)[i])); + break; + case pD551: + (*alm)[i]->svid = recpkt->data[0]; + GPS_A500_Translate(recpkt->data+1, &((*alm)[i])); + (*alm)[i]->hlth = recpkt->data[43]; + break; + default: + GPS_Error("A500_GET: Unknown almanac protocol"); + return PROTOCOL_ERROR; + } + /* Cheat and don't _really_ pass the trkpt back */ +/* cb(n, NULL);*/ + } + + if(!GPS_Packet_Read(fd, &recpkt)) + return gps_errno; + if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) + return gps_errno; + if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A500_Get: Error transferring almanac"); + return FRAMING_ERROR; + } + + if(i != n) { + GPS_Error("A500_GET: Almanac entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return n; +} + + +/* @func GPS_A500_Send ************************************************** +** +** Send almanac to GPS +** +** @param [r] port [const char *] serial port +** @param [r] alm [GPS_PAlmanac *] almanac array +** @param [r] n [int32] number of almanac entries +** +** @return [int32] success +************************************************************************/ +int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) +{ + UC data[GPS_ARB_LEN]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + int32 timesent; + int32 posnsent; + int32 ret; + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A500_Send: Almanac start data not acknowledged"); + return FRAMING_ERROR; + } + + + for(i=0;itype == LINK_ID[gps_link_type].Pid_Command_Data && + GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. + Cmnd_Transfer_Time) + { + GPS_User("INFO: GPS time request. Sending...."); + ret = GPS_Rqst_Send_Time(fd,gps_save_time); + if(ret < 0) return ret; + timesent=1; + } + } + + + + /* + * Allow GPS a little while to decide whether it wants to ask for + * the position. Note that the posn sent is held in gps_save_lat + * and gps_save_lon global! + */ + if(GPS_Device_Wait(fd)) + { + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + if(rec->type == LINK_ID[gps_link_type].Pid_Command_Data && + GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. + Cmnd_Transfer_Posn) + { + GPS_User("INFO: GPS position request. Sending...."); + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if(ret < 0) return ret; + posnsent=1; + } + } + + if(!timesent) + { + ret = GPS_Rqst_Send_Time(fd,gps_save_time); + if(ret < 0) return ret; + } + + + if(!posnsent) + { + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if(ret < 0) return ret; + } + + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; +} + +/* @funcstatic GPS_A500_Translate *************************************** +** +** Translate almanac packet to almanac structure +** +** @param [r] s [const UC *] almanac packet data +** @param [w] alm [GPS_PAlmanac *] almanac entry pointer +** +** @return [void] +************************************************************************/ +static void GPS_A500_Translate(UC *s, GPS_PAlmanac *alm) +{ + UC *p; + + p=s; + + (*alm)->wn = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + (*alm)->toa = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*alm)->af0 = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*alm)->af1 = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*alm)->e = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*alm)->sqrta = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*alm)->m0 = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*alm)->w = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*alm)->omg0 = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*alm)->odot = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*alm)->i = GPS_Util_Get_Float(p); + p+=sizeof(float); + + return; +} + + +/* @funcstatic GPS_D500_Send ******************************************* +** +** Form almanac data string +** +** @param [w] data [UC *] string to write to +** @param [r] alm [GPS_PAlmanac] almanac data +** +** @return [void] +************************************************************************/ +static void GPS_D500_Send(UC *data, GPS_PAlmanac alm) +{ + UC *p; + + p = data; + GPS_A500_Encode(p,alm); + + return; +} + + + +/* @funcstatic GPS_D501_Send ******************************************** +** +** Form almanac data string +** +** @param [w] data [UC *] string to write to +** @param [r] alm [GPS_PAlmanac] almanac data +** +** @return [void] +************************************************************************/ +static void GPS_D501_Send(UC *data, GPS_PAlmanac alm) +{ + UC *p; + + p=data; + p[42] = alm->hlth; + GPS_A500_Encode(p,alm); + + return; +} + + + +/* @funcstatic GPS_D550_Send ******************************************** +** +** Form almanac data string +** +** @param [w] data [UC *] string to write to +** @param [r] alm [GPS_PAlmanac] almanac data +** +** @return [void] +************************************************************************/ +static void GPS_D550_Send(UC *data, GPS_PAlmanac alm) +{ + UC *p; + + p = data; + *p = alm->svid; + GPS_A500_Encode(p+1,alm); + + return; +} + + + +/* @funcstatic GPS_D551_Send ******************************************** +** +** Form almanac data string +** +** @param [w] data [UC *] string to write to +** @param [r] alm [GPS_PAlmanac] almanac data +** +** @return [void] +************************************************************************/ +static void GPS_D551_Send(UC *data, GPS_PAlmanac alm) +{ + UC *p; + + p = data; + *p = alm->svid; + GPS_A500_Encode(p+1,alm); + p[43] = alm->hlth; + + return; +} + + + +/* @funcstatic GPS_A500_Encode *************************************** +** +** Encode almanac structure to almanac packet +** +** @param [w] s [UC *] string to write to +** @param [r] alm [GPS_PAlmanac] almanac entry +** +** @return [void] +************************************************************************/ +static void GPS_A500_Encode(UC *s, GPS_PAlmanac alm) +{ + UC *p; + + p=s; + + GPS_Util_Put_Short(p,alm->wn); + p+=sizeof(int16); + + GPS_Util_Put_Float(p,alm->toa); + p+=sizeof(float); + + GPS_Util_Put_Float(p,alm->af0); + p+=sizeof(float); + + GPS_Util_Put_Float(p,alm->af1); + p+=sizeof(float); + + GPS_Util_Put_Float(p,alm->e); + p+=sizeof(float); + + GPS_Util_Put_Float(p,alm->sqrta); + p+=sizeof(float); + + GPS_Util_Put_Float(p,alm->m0); + p+=sizeof(float); + + GPS_Util_Put_Float(p,alm->w); + p+=sizeof(float); + + GPS_Util_Put_Float(p,alm->omg0); + p+=sizeof(float); + + GPS_Util_Put_Float(p,alm->odot); + p+=sizeof(float); + + GPS_Util_Put_Float(p,alm->i); + + return; +} + + +/* @func GPS_A600_Get ****************************************************** +** +** Get time from GPS +** +** @param [r] port [const char *] serial port +** +** @return [time_t] GPS time as unix system time, -ve if error +************************************************************************/ +time_t GPS_A600_Get(const char *port) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + time_t ret; + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Time); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_errno; + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + switch(gps_date_time_type) + { + case pD600: + ret = GPS_D600_Get(rec); + break; + default: + GPS_Error("A600_Get: Unknown data/time protocol"); + return PROTOCOL_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return ret; +} + + + + + +/* @func GPS_A600_Send ************************************************** +** +** Send time to GPS +** +** @param [r] port [const char *] serial port +** @param [r] Time [time_t] unix-style time +** +** @return [int32] success +************************************************************************/ +int32 GPS_A600_Send(const char *port, time_t Time) +{ + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 posnsent=0; + int32 ret=0; + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + switch(gps_date_time_type) + { + case pD600: + GPS_D600_Send(&tra,Time); + break; + default: + GPS_Error("A600_Send: Unknown data/time protocol"); + return PROTOCOL_ERROR; + } + + if(!GPS_Write_Packet(fd,tra)) + return gps_error; + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_error; + + + /* + * Allow GPS a little while to decide whether it wants to ask for + * the position. Note that the posn sent is held in gps_save_lat + * and gps_save_lon globals! + */ + if(GPS_Device_Wait(fd)) + { + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + if(rec->type == LINK_ID[gps_link_type].Pid_Command_Data && + GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. + Cmnd_Transfer_Posn) + { + GPS_User("INFO: GPS position request. Sending...."); + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if(ret < 0) return ret; + posnsent=1; + } + } + + + if(!posnsent) + { + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if(ret < 0) return ret; + } + + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; +} + + + + + +/* @func GPS_D600_Get ****************************************************** +** +** Convert date/time packet to ints +** +** @param [r] packet [GPS_PPacket] packet +** +** @return [time_t] gps time as unix system time +************************************************************************/ +time_t GPS_D600_Get(GPS_PPacket packet) +{ + UC *p; + static struct tm ts; + + p = packet->data; + + ts.tm_mon = *p++ - 1; + ts.tm_mday = *p++; + ts.tm_year = (int32) GPS_Util_Get_Short(p) - 1900; + p+=2; + ts.tm_hour = (int32) GPS_Util_Get_Short(p); + p+=2; + ts.tm_min = *p++; + ts.tm_sec = *p++; + + return mktime(&ts); +} + + +/* @func GPS_D600_Send ****************************************************** +** +** make a time packet for sending to the GPS +** +** @param [w] packet [GPS_PPacket *] packet +** @param [r] Time [time_t] unix-style time +** +** @return [void] +************************************************************************/ +void GPS_D600_Send(GPS_PPacket *packet, time_t Time) +{ + UC data[10]; + UC *p; + struct tm *ts; + + p = data; + + ts = localtime(&Time); + *p++ = ts->tm_mon+1; + *p++ = ts->tm_mday; + + GPS_Util_Put_Short(p,(US) (ts->tm_year+1900)); + p+=2; + GPS_Util_Put_Short(p,(US) ts->tm_hour); + p+=2; + + *p++ = ts->tm_min; + *p = ts->tm_sec; + + GPS_Make_Packet(packet, LINK_ID[gps_link_type].Pid_Date_Time_Data, + data,8); + + return; +} + + + + +/* @func GPS_A700_Get ****************************************************** +** +** Get position from GPS +** +** @param [r] port [const char *] serial port +** @param [w] lat [double *] latitude (deg) +** @param [w] lon [double *] longitude (deg) +** +** @return [int32] success +************************************************************************/ +int32 GPS_A700_Get(const char *port, double *lat, double *lon) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Posn); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_errno; + + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + switch(gps_position_type) + { + case pD700: + GPS_D700_Get(rec, lat, lon); + break; + default: + GPS_Error("A700_Get: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; +} + + + +/* @func GPS_A700_Send ****************************************************** +** +** Send position to GPS +** +** @param [r] port [const char *] serial port +** @param [r] lat [double] latitude (deg) +** @param [r] lon [double] longitute (deg) +** +** @return [int32] success +************************************************************************/ +int32 GPS_A700_Send(const char *port, double lat, double lon) +{ + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + switch(gps_position_type) + { + case pD700: + GPS_D700_Send(&tra,lat,lon); + break; + default: + GPS_Error("A700_Send: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + if(!GPS_Write_Packet(fd,tra)) + return 0; + if(!GPS_Get_Ack(fd, &tra, &rec)) + return 0; + + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; +} + + + +/* @func GPS_D700_Get ****************************************************** +** +** Convert position packet to lat/long in degrees +** +** @param [r] packet [GPS_PPacket] packet +** @param [w] lat [double *] latitude (deg) +** @param [w] lon [double *] longitude (deg) +** +** @return [void] +************************************************************************/ +void GPS_D700_Get(GPS_PPacket packet, double *lat, double *lon) +{ + UC *p; + double t; + + p = packet->data; + + t = GPS_Util_Get_Double(p); + *lat = GPS_Math_Rad_To_Deg(t); + + p += sizeof(double); + + t = GPS_Util_Get_Double(p); + *lon = GPS_Math_Rad_To_Deg(t); + + + return; +} + + +/* @func GPS_D700_Send ****************************************************** +** +** make a position packet for sending to the GPS +** +** @param [w] packet [GPS_PPacket *] packet +** @param [r] lat [double] latitude (deg) +** @param [r] lon [double] longitude (deg) +** +** @return [void] +************************************************************************/ +void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon) +{ + UC data[16]; + UC *p; + + lat = GPS_Math_Deg_To_Rad(lat); + lon = GPS_Math_Deg_To_Rad(lon); + + p = data; + + GPS_Util_Put_Double(p,lat); + p+=sizeof(double); + GPS_Util_Put_Double(p,lon); + + GPS_Make_Packet(packet, LINK_ID[gps_link_type].Pid_Position_Data, + data,16); + + return; +} + + + +/* @func GPS_A800_On ****************************************************** +** +** Turn on GPS PVT +** +** @param [r] port [const char *] serial port +** @param [w] fd [int32 *] file descriptor +** +** @return [int32] success +************************************************************************/ +int32 GPS_A800_On(const char *port, gpsdevh **fd) +{ + static UC data[2]; + GPS_PPacket tra; + GPS_PPacket rec; + + if(!GPS_Device_On(port, fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Start_Pvt_Data); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(*fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(*fd, &tra, &rec)) + { + GPS_Error("A800_on: Pvt start data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + + return 1; +} + + + +/* @func GPS_A800_Off ****************************************************** +** +** Turn off GPS PVT +** +** @param [r] port [const char *] port +** @param [w] fd [int32 *] file descriptor +** +** @return [int32] success +************************************************************************/ +int32 GPS_A800_Off(const char *port, gpsdevh **fd) +{ + static UC data[2]; + GPS_PPacket tra; + GPS_PPacket rec; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Stop_Pvt_Data); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(*fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(*fd, &tra, &rec)) + { + GPS_Error("A800_Off: Not acknowledged"); + return FRAMING_ERROR; + } + + + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + +// if(!GPS_Device_Off(*fd)) +// return gps_errno; + + return 1; +} + + +/* @func GPS_A800_Get ************************************************** +** +** make a position packet for sending to the GPS +** +** @param [r] fd [int32 *] file descriptor +** @param [w] packet [GPS_PPvt_Data *] packet +** +** @return [int32] success +************************************************************************/ +int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet) +{ + GPS_PPacket tra; + GPS_PPacket rec; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + if(!GPS_Packet_Read(*fd, &rec)) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + return gps_errno; + } + + if(!GPS_Send_Ack(*fd, &tra, &rec)) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + return gps_errno; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Pvt_Data) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + return 0; + } + + switch(gps_pvt_type) + { + case pD800: + GPS_D800_Get(rec,packet); + break; + default: + GPS_Error("A800_GET: Unknown pvt protocol"); + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + return PROTOCOL_ERROR; + } + + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + + return 1; +} + + + +/* @func GPS_D800_Get ****************************************************** +** +** Convert packet to pvt structure +** +** @param [r] packet [GPS_PPacket] packet +** @param [w] pvt [GPS_PPvt_Data *] pvt structure +** +** @return [void] +************************************************************************/ +void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt) +{ + UC *p; + + p = packet->data; + + (*pvt)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*pvt)->epe = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*pvt)->eph = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*pvt)->epv = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*pvt)->fix = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + (*pvt)->tow = GPS_Util_Get_Double(p); + p+=sizeof(double); + + (*pvt)->lat = GPS_Math_Rad_To_Deg(GPS_Util_Get_Double(p)); + p+=sizeof(double); + + (*pvt)->lon = GPS_Math_Rad_To_Deg(GPS_Util_Get_Double(p)); + p+=sizeof(double); + + (*pvt)->east = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*pvt)->north = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*pvt)->up = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*pvt)->msl_hght = GPS_Util_Get_Float(p); + p+=sizeof(float); + + (*pvt)->leap_scnds = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + (*pvt)->wn_days = GPS_Util_Get_Int(p); + + return; +} + +/* @func GPS_A906_Get ****************************************************** +** +** Get lap data from GPS +** +** @param [r] port [const char *] serial port +** @param [w] trk [GPS_PLap **] lap array +** +** @return [int32] number of lap entries +************************************************************************/ + +int32 GPS_A906_Get(const char *port, GPS_PLap **lap, pcb_fn cb) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_lap_transfer == -1) + return GPS_UNSUPPORTED; + + if (!GPS_Device_On(port, &fd)) + return gps_errno; + + if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Lap); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,trapkt)) + return gps_errno; + if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) + return gps_errno; + if(!GPS_Packet_Read(fd, &recpkt)) + return gps_errno; + if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) + return gps_errno; + + n = GPS_Util_Get_Short(recpkt->data); + + if(n) + if(!((*lap)=(GPS_PLap *)malloc(n*sizeof(GPS_PLap)))) + { + GPS_Error("A906_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + for(i=0;idata); + break; + default: + GPS_Error("A906_Get: Unknown Lap protocol %d\n", gps_lap_type); + return PROTOCOL_ERROR; + } + + /* Cheat and don't _really_ pass the trkpt back */ + cb(n, NULL); + } + + if(!GPS_Packet_Read(fd, &recpkt)) + return gps_errno; + if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) + return gps_errno; + if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A906_Get: Error transferring laps"); + return FRAMING_ERROR; + } + + if(i != n) { + GPS_Error("A906_GET: Lap entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) + return gps_errno; + return n; +} + +/* @func GPS_D1011b_Get ****************************************************** +** +** Convert packet D906, D1001, D1011, D1015 to lap structure +** +** @param [r] packet [GPS_PPacket] packet +** @param [w] pvt [GPS_PLap *] lap structure +** +** @return [void] +************************************************************************/ +void GPS_D1011b_Get(GPS_PLap *Lap, UC *p) +{ + uint32 t; + + /* Lap index (not in D906) */ + switch(gps_lap_type) { + case pD906: + (*Lap)->index = -1; + break; + case pD1001: + (*Lap)->index = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); + break; + case pD1011: + case pD1015: + (*Lap)->index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); + p+=sizeof(uint16); /*unused*/ + break; + default: + break; + } + + t = GPS_Util_Get_Uint(p); + (*Lap)->start_time = GPS_Math_Gtime_To_Utime((time_t)t); + p+=sizeof(uint32); + + (*Lap)->total_time = GPS_Util_Get_Int(p); + p+=sizeof(int32); + + (*Lap)->total_distance = GPS_Util_Get_Float(p); + p+=sizeof(float); + if(gps_lap_type != pD906){ + (*Lap)->max_speed = GPS_Util_Get_Float(p); + p+=sizeof(float); + } + + (*Lap)->begin_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->begin_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->end_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->end_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*Lap)->calories = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + /* Track index, only in D906*/ + if(gps_lap_type == pD906){ + (*Lap)->track_index = *p++; + p++; /*Unused*/ + + /*Last field, no more to do */ + return; + } else { + (*Lap)->track_index = -1; + } + + (*Lap)->avg_heart_rate = *p++; + (*Lap)->max_heart_rate = *p++; + (*Lap)->intensity = *p++; + + switch(gps_lap_type) { + case pD1001: + /*No more fields */ + return; + case pD1011: + case pD1015: + (*Lap)->avg_cadence = *p++; + (*Lap)->trigger_method = *p++; + break; + default: + /*pD906 already returned*/ + break; + } + + if (gps_lap_type==pD1015) { + /*some unknown fields like 04 dc 44 ff ff */ + /* (*Lap)->unk1015_1 = *p++; normally 4? + (*Lap)->unk1015_2 = GPS_Util_Get_Short(p);wkt related , ffff otherwise + p+=sizeof(int16); + (*Lap)->unk1015_3 = GPS_Util_Get_Short(p);ffff ? + p+=sizeof(int16); + */ + } + + return; +} + + +/* + * It's unfortunate that these aren't constant and therefore switchable, + * but they really are runtime variable. Sigh. + */ +const char * +Get_Pkt_Type(unsigned char p, unsigned short d0, const char **xinfo) +{ + *xinfo = NULL; +#define LT LINK_ID[gps_link_type] + if (p == LT.Pid_Ack_Byte) + return "ACK"; + if (p == LT.Pid_Command_Data) { + switch (d0) { + case 0: *xinfo = "Abort"; break; + case 1: *xinfo = "Xfer Alm"; break; + case 2: *xinfo = "Xfer Posn"; break; + case 3: *xinfo = "Xfer Prx"; break; + case 4: *xinfo = "Xfer Rte"; break; + case 5: *xinfo = "Xfer Time"; break; + case 6: *xinfo = "Xfer Trk"; break; + case 7: *xinfo = "Xfer Wpt"; break; + case 8: *xinfo = "Power Down"; break; + case 49: *xinfo = "Xfer PVT Start"; break; + case 50: *xinfo = "Xfer PVT Stop"; break; + case 92: *xinfo = "Flight Records"; break; + case 117: *xinfo = "Xfer Laps"; break; + case 121: *xinfo = "Xfer Categories"; break; + case 450: *xinfo = "Xfer Runs"; break; + case 451: *xinfo = "Xfer Workouts"; break; + case 452: *xinfo = "Xfer Wkt Occurrences"; break; + case 453: *xinfo = "Xfer User Profile "; break; + case 454: *xinfo = "Xfer Wkt Limits"; break; + case 561: *xinfo = "Xfer Courses"; break; + case 562: *xinfo = "Xfer Course Laps"; break; + case 563: *xinfo = "Xfer Course Point"; break; + case 564: *xinfo = "Xfer Course Tracks"; break; + case 565: *xinfo = "Xfer Course Limits"; break; + + default: *xinfo = "Unknown"; + } + return "CMDDAT"; + } + if (p == LT.Pid_Protocol_Array) + return "PRTARR"; + if (p == LT.Pid_Product_Rqst) + return "PRDREQ"; + if (p == LT.Pid_Product_Data) + return "PRDDAT"; + if (p == LT.Pid_Ext_Product_Data) + return "PRDEDA"; + + if (p == LT.Pid_Xfer_Cmplt) + return "XFRCMP"; + if (p == LT.Pid_Date_Time_Data) + return "DATTIM"; + if (p == LT.Pid_Position_Data) + return "POS"; + if (p == LT.Pid_Prx_Wpt_Data) + return "WPT"; + if (p == LT.Pid_Nak_Byte) + return "NAK"; + if (p == LT.Pid_Records) + return "RECORD"; + if (p == LT.Pid_Rte_Hdr) + return "RTEHDR"; + if (p == LT.Pid_Rte_Wpt_Data) + return "RTEWPT"; + if (p == LT.Pid_Almanac_Data) + return "RALMAN"; + if (p == LT.Pid_Trk_Data) + return "TRKDAT"; + if (p == LT.Pid_Wpt_Data) + return "WPTDAT"; + if (p == LT.Pid_Pvt_Data) + return "PVTDAT"; + if (p == LT.Pid_Rte_Link_Data) + return "LNKDAT"; + if (p == LT.Pid_Trk_Hdr) + return "TRKHDR"; + + if (p == LT.Pid_FlightBook_Record) + return "FLIBOO"; + if (p == LT.Pid_Lap) + return "LAPDAT"; + if (p == LT.Pid_Wpt_Cat_Data) + return "WPTCAT"; + if (p == LT.Pid_Run) + return "RUNDAT"; + if (p == LT.Pid_Workout) + return "WKTDAT"; + if (p == LT.Pid_Workout_Occurrence) + return "WKTOCC"; + if (p == LT.Pid_Fitness_User_Profile) + return "UPROFI"; + if (p == LT.Pid_Workout_Limits) + return "WKTLIM"; + if (p == LT.Pid_Course) + return "CRSDAT"; + if (p == LT.Pid_Course_Lap) + return "CRSLAP"; + if (p == LT.Pid_Course_Point) + return "CRSPOI"; + if (p == LT.Pid_Course_Trk_Hdr) + return "CRSTHD"; + if (p == LT.Pid_Course_Trk_Data) + return "CRSTDA"; + if (p == LT.Pid_Course_Limits) + return "CRSLIM"; + if (p == LT.Pid_Trk2_Hdr) + return "TRKHD2"; + + if (p == GUSB_REQUEST_BULK) + return "REQBLK"; + if (p == GUSB_SESSION_START) + return "SESREQ"; + if (p == GUSB_SESSION_ACK) + return "SESACK"; + + return "UNKNOWN"; +} diff --git a/jeeps/gpsapp.h b/jeeps/gpsapp.h new file mode 100644 index 000000000..677b448d9 --- /dev/null +++ b/jeeps/gpsapp.h @@ -0,0 +1,105 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsapp_h +#define gpsapp_h + + +#include "gps.h" + +int32 GPS_Init(const char *port); + +int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int ct, GPS_PWay *)); +int32 GPS_A101_Get(const char *port); +int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay *)); + +int32 GPS_A200_Get(const char *port, GPS_PWay **way); +int32 GPS_A201_Get(const char *port, GPS_PWay **way); +int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n); +int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n); + +int32 GPS_A300_Get(const char *port, GPS_PTrack **trk, pcb_fn cb); +int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb); +int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n); +int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n); /*A302*/ + +int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *h); +void GPS_D300b_Get(GPS_PTrack *trk, UC *data); +void GPS_D301b_Get(GPS_PTrack *trk, UC *data); +void GPS_D302b_Get(GPS_PTrack *trk, UC *data); +void GPS_D303b_Get(GPS_PTrack *trk, UC *data); /*D304*/ +void GPS_D310_Get(GPS_PTrack *trk, UC *s); +void GPS_D311_Get(GPS_PTrack *trk, UC *s); +void GPS_D300_Send(UC *data, GPS_PTrack trk); +void GPS_D301_Send(UC *data, GPS_PTrack trk); +void GPS_D304_Send(UC *data, GPS_PTrack trk); +void GPS_D310_Send(UC *data, GPS_PTrack trk, int32 *len); + +int32 GPS_A400_Get(const char *port, GPS_PWay **way); +int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n); + +int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm); +int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n); + +time_t GPS_A600_Get(const char *port); +time_t GPS_D600_Get(GPS_PPacket packet); +int32 GPS_A600_Send(const char *port, time_t Time); +void GPS_D600_Send(GPS_PPacket *packet, time_t Time); + +int32 GPS_A700_Get(const char *port, double *lat, double *lon); +int32 GPS_A700_Send(const char *port, double lat, double lon); +void GPS_D700_Get(GPS_PPacket packet, double *lat, double *lon); +void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon); + +int32 GPS_A800_On(const char *port, gpsdevh **fd); +int32 GPS_A800_Off(const char *port, gpsdevh **fd); +int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet); +void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt); + +int32 GPS_A906_Get(const char *port, GPS_PLap **lap, pcb_fn cb); +void GPS_D1011b_Get(GPS_PLap *Lap,UC *data); /*D906 D1001 D1015*/ + +/* Unhandled documented protocols, as of: + Garmin Device Interface Specification, May 19, 2006, Drawing Number: 001-00063-00 Rev. C +A650 – FlightBook Transfer Protocol +A1000 – Run Transfer Protocol + Capability A1000: D1009 + D1000 D1010 +A1002 – Workout Transfer Protocol + Capability A1002: D1008 + D1002 + Capability A1003: D1003 +A1004 – Fitness User Profile Transfer Protocol + Capability A1004: D1004 +A1005 – Workout Limits Transfer Protocol + Capability A1005: D1005 +A1006 – Course Transfer Protocol + Capability A1006: D1006 + Capability A1007: D1007 + Capability A1008: D1012 +A1009 – Course Limits Transfer Protocol + Capability A1009: D1013 +*/ +/* Unimplemted and Undocumented, as listed from the following device/sw: + GF305 3.70 + +Capability A601: D601 +Capability A801: D801 + +Capability A902: +Capability A903: +Capability A907: D907 D908 D909 D910 +Capability A918: D918 +Capability A1013: D1014 +*/ + +const char * Get_Pkt_Type(unsigned char p, unsigned short d0, const char **xinfo); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpscom.c b/jeeps/gpscom.c new file mode 100644 index 000000000..3063b510a --- /dev/null +++ b/jeeps/gpscom.c @@ -0,0 +1,690 @@ +/******************************************************************** +** @source JEEPS command functions +** +** @author Copyright (C) 1999 Alan Bleasby +** @version 1.0 +** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2005, 2006 Robert Lipe +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include + + +/* @func GPS_Command_Off *********************************************** +** +** Turn off power on GPS +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Command_Off(const char *port) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + + GPS_Util_Little(); + + if(!GPS_Device_On(port, &fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Turn_Off_Pwr); + + /* robertl - LINK_ID isn't set yet. Hardcode it to Garmin spec value */ + GPS_Make_Packet(&tra, 10, /* LINK_ID[gps_link_type].Pid_Command_Data, */ + data,2); + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + + if(!GPS_Device_Chars_Ready(fd)) + { + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_errno; + GPS_User("Power off command acknowledged"); + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; +} + + +/* @func GPS_Command_Get_Waypoint *************************************** +** +** Get waypoint from GPS +** +** @param [r] port [const char *] serial port +** @param [w] way [GPS_PWay **] pointer to waypoint array +** +** @return [int32] number of waypoint entries +************************************************************************/ + +int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way, pcb_fn cb) +{ + int32 ret=0; + + /* + * It's a bit tacky to do this up front without ticking the + * progress meter, but this come in pretty quickly... + */ + if (gps_category_transfer) { + ret = GPS_A101_Get(port); + if (!ret) { +fatal("blah"); + return PROTOCOL_ERROR; + } + + } + + switch(gps_waypt_transfer) + { + case pA100: + ret = GPS_A100_Get(port,way, cb); + break; + default: + GPS_Error("Get_Waypoint: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + + +/* @func GPS_Command_Send_Waypoint ****************************************** +** +** Send waypoints to GPS +** +** @param [r] port [const char *] serial port +** @param [r] way [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)(struct GPS_SWay **)) +{ + int32 ret=0; + + switch(gps_waypt_transfer) + { + case pA100: + ret = GPS_A100_Send(port, way, n, cb); + break; + default: + GPS_Error("Send_Waypoint: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + +/* @func GPS_Command_Get_Route ************************************** +** +** Get Route(s) from GPS +** +** @param [r] port [const char *] serial port +** @param [w] way [GPS_PWay **] pointer to waypoint array +** +** @return [int32] number of waypoint entries +************************************************************************/ + +int32 GPS_Command_Get_Route(const char *port, GPS_PWay **way) +{ + int32 ret=0; + + switch(gps_route_transfer) + { + case pA200: + ret = GPS_A200_Get(port,way); + break; + case pA201: + ret = GPS_A201_Get(port,way); + break; + default: + GPS_Error("Get_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + + +/* @func GPS_Command_Send_Route **************************************** +** +** Send route(s) to GPS +** +** @param [r] port [const char *] serial port +** @param [r] way [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Command_Send_Route(const char *port, GPS_PWay *way, int32 n) +{ + int32 ret=0; + + + switch(gps_route_transfer) + { + case pA200: + ret = GPS_A200_Send(port, way, n); + break; + case pA201: + ret = GPS_A201_Send(port, way, n); + break; + default: + GPS_Error("Send_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + +/* @func GPS_Command_Get_Track *************************************** +** +** Get track log from GPS +** +** @param [r] port [const char *] serial port +** @param [w] trk [GPS_PTrack **] pointer to track array +** +** @return [int32] number of track entries +************************************************************************/ + +int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, pcb_fn cb) +{ + int32 ret=0; + + if(gps_trk_transfer == -1) + return GPS_UNSUPPORTED; + + switch(gps_trk_transfer) + { + case pA300: + ret = GPS_A300_Get(port,trk,cb); + break; + case pA301: + case pA302: + ret = GPS_A301_Get(port,trk,cb); + break; + default: + GPS_Error("Get_Track: Unknown track protocol %d\n", gps_trk_transfer); + return PROTOCOL_ERROR; + } + + return ret; +} + + + +/* @func GPS_Command_Send_Track ****************************************** +** +** Send track log to GPS +** +** @param [r] port [const char *] serial port +** @param [r] trk [GPS_PTrack *] track array +** @param [r] n [int32] number of track entries +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n) +{ + int32 ret=0; + + if(gps_trk_transfer == -1) + return GPS_UNSUPPORTED; + + switch(gps_trk_transfer) + { + case pA300: + ret = GPS_A300_Send(port, trk, n); + break; + case pA301: + ret = GPS_A301_Send(port, trk, n); + break; + default: + GPS_Error("Send_Track: Unknown track protocol"); + break; + } + + return ret; +} + + +/* @func GPS_Command_Get_Proximity ************************************** +** +** Get proximitywaypoint from GPS +** +** @param [r] port [const char *] serial port +** @param [w] way [GPS_PWay **] pointer to waypoint array +** +** @return [int32] number of waypoint entries +************************************************************************/ + +int32 GPS_Command_Get_Proximity(const char *port, GPS_PWay **way) +{ + int32 ret=0; + + if(gps_prx_waypt_transfer == -1) + return GPS_UNSUPPORTED; + + switch(gps_prx_waypt_transfer) + { + case pA400: + ret = GPS_A400_Get(port,way); + break; + default: + GPS_Error("Get_Proximity: Unknown proximity protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + + +/* @func GPS_Command_Send_Proximity ****************************************** +** +** Send proximity waypoints to GPS +** +** @param [r] port [const char *] serial port +** @param [r] way [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Command_Send_Proximity(const char *port, GPS_PWay *way, int32 n) +{ + int32 ret=0; + + + if(gps_prx_waypt_transfer == -1) + return GPS_UNSUPPORTED; + + + switch(gps_prx_waypt_transfer) + { + case pA400: + ret = GPS_A400_Send(port, way, n); + break; + default: + GPS_Error("Send_Proximity: Unknown proximity protocol"); + break; + } + + return ret; +} + + + +/* @func GPS_Command_Get_Almanac *************************************** +** +** Get almanac from GPS +** +** @param [r] port [const char *] serial port +** @param [w] alm [GPS_PAlmanac **] pointer to almanac array +** +** @return [int32] number of almanac entries +************************************************************************/ + +int32 GPS_Command_Get_Almanac(const char *port, GPS_PAlmanac **alm) +{ + int32 ret=0; + + if(gps_almanac_transfer == -1) + return GPS_UNSUPPORTED; + + switch(gps_almanac_transfer) + { + case pA500: + ret = GPS_A500_Get(port,alm); + break; + default: + GPS_Error("Get_Almanac: Unknown almanac protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + + +/* @func GPS_Command_Send_Almanac ****************************************** +** +** Send almanac to GPS +** +** @param [r] port [const char *] serial port +** @param [r] alm [GPS_PAlmanac *] almanac array +** @param [r] n [int32] number of almanac entries +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n) +{ + int32 ret=0; + + if(gps_almanac_transfer == -1) + return GPS_UNSUPPORTED; + + switch(gps_almanac_transfer) + { + case pA500: + ret = GPS_A500_Send(port, alm, n); + break; + default: + GPS_Error("Send_Almanac: Unknown almanac protocol"); + break; + } + + return ret; +} + + + +/* @func GPS_Command_Get_Time ****************************************** +** +** Get time from GPS +** +** @param [r] port [const char *] serial port +** +** @return [time_t] unix-style time +************************************************************************/ + +time_t GPS_Command_Get_Time(const char *port) +{ + time_t ret=0; + + switch(gps_date_time_transfer) + { + case pA600: + ret = GPS_A600_Get(port); + break; + /* + * If the unit doesn't support it (i.e. a C320 in charging mode), + * but don't treat as error; return as zero. + */ + case -1: + return 0; + default: + GPS_Error("Get_Time: Unknown date/time protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + + +/* @func GPS_Command_Send_Time ****************************************** +** +** Set GPS time +** +** @param [r] port [const char *] serial port +** @param [r] Time [time_t] unix-style time +** +** @return [int32] true if OK +************************************************************************/ + +int32 GPS_Command_Send_Time(const char *port, time_t Time) +{ + time_t ret=0; + + switch(gps_date_time_transfer) + { + case pA600: + ret = GPS_A600_Send(port, Time); + break; + default: + GPS_Error("Send_Time: Unknown date/time protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + + + +/* @func GPS_Command_Get_Position *************************************** +** +** Get position from GPS +** +** @param [r] port [const char *] serial port +** @param [w] lat [double *] latitude (deg) +** @param [w] lon [double *] longitude (deg) +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon) +{ + int32 ret=0; + + switch(gps_position_transfer) + { + case pA700: + ret = GPS_A700_Get(port,lat,lon); + break; + /* + * If the unit doesn't support it (i.e. a C320 in charging mode), + * zero lat/lon, but don't treat as error. + */ + case -1: + *lat = *lon = 0.0; + break; + default: + GPS_Error("Get_Position: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + + +/* @func GPS_Command_Send_Position ****************************************** +** +** Set GPS position +** +** @param [r] port [const char *] serial port +** @param [r] lat [double] latitude (deg) +** @param [r] lon [double] longitude (deg) +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Command_Send_Position(const char *port, double lat, double lon) +{ + int32 ret=0; + + switch(gps_position_transfer) + { + case pA700: + ret = GPS_A700_Send(port, lat, lon); + break; + default: + GPS_Error("Send_Position: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + +/* @func GPS_Command_Pvt_On ******************************************** +** +** Instruct GPS to start sending Pvt data every second +** +** @param [r] port [const char *] serial port +** @param [w] fd [int32 *] file descriptor +** +** @return [int32] success if supported and GPS starts sending +************************************************************************/ + +int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd) +{ + int32 ret=0; + + + if(gps_pvt_transfer == -1) + return GPS_UNSUPPORTED; + + + switch(gps_pvt_transfer) + { + case pA800: + ret = GPS_A800_On(port,fd); + break; + default: + GPS_Error("Pvt_On: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + + return ret; +} + + + +/* @func GPS_Command_Pvt_Off ******************************************** +** +** Instruct GPS to stop sending Pvt data every second +** +** @param [r] port [const char *] serial port +** @param [w] fd [int32 *] file descriptor +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd) +{ + int32 ret=0; + + + if(gps_pvt_transfer == -1) + return GPS_UNSUPPORTED; + + switch(gps_pvt_transfer) + { + case pA800: + ret = GPS_A800_Off(port,fd); + break; + default: + GPS_Error("Pvt_Off: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + + +/* @func GPS_Command_Pvt_Get ******************************************** +** +** Get a single PVT info entry +** +** @param [w] fd [int32 *] file descriptor +** @param [w] pvt [GPS_PPvt_Data *] pvt data structure to fill +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt) +{ + int32 ret=0; + + if(gps_pvt_transfer == -1) + return GPS_UNSUPPORTED; + + (*pvt)->fix = 0; + + switch(gps_pvt_transfer) + { + case pA800: + ret = GPS_A800_Get(fd,pvt); + break; + default: + GPS_Error("Pvt_Get: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + +/* @func GPS_Command_Get_Lap *************************************** +** +** Get lap from GPS +** +** @param [r] port [const char *] serial port +** @param [w] way [GPS_PLap **] pointer to lap array +** +** @return [int32] number of lap entries +************************************************************************/ + +int32 GPS_Command_Get_Lap(const char *port, GPS_PLap **lap, pcb_fn cb) +{ + int32 ret=0; + + if(gps_lap_transfer == -1) + return GPS_UNSUPPORTED; + + switch(gps_lap_transfer) + { + case pA906: + ret = GPS_A906_Get(port,lap, cb); + break; + default: + GPS_Error("Get_Lap: Unknown lap protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + /*Stubs for unimplemented stuff*/ +int32 GPS_Command_Get_Workout(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)){ + return 0; +} +int32 GPS_Command_Get_Fitness_User_Profile(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)){ + return 0; +} +int32 GPS_Command_Get_Workout_Limits(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)){ + return 0; +} +int32 GPS_Command_Get_Course(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)){ + return 0; +} +int32 GPS_Command_Get_Course_Limits(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)){ + return 0; +} + diff --git a/jeeps/gpscom.h b/jeeps/gpscom.h new file mode 100644 index 000000000..4c490cd42 --- /dev/null +++ b/jeeps/gpscom.h @@ -0,0 +1,51 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpscom_h +#define gpscom_h + + +#include "gps.h" +#include + +int32 GPS_Command_Off(const char *port); + +time_t GPS_Command_Get_Time(const char *port); +int32 GPS_Command_Send_Time(const char *port, time_t Time); + +int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon); +int32 GPS_Command_Send_Position(const char *port, double lat, double lon); + +int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd); +int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd); +int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt); + +int32 GPS_Command_Get_Almanac(const char *port, GPS_PAlmanac **alm); +int32 GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n); + +int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, int (*cb)(int, struct GPS_SWay **)); +int32 GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n); + +int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way,int (*cb)(int, struct GPS_SWay **)); +int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)(struct GPS_SWay **)); + +int32 GPS_Command_Get_Proximity(const char *port, GPS_PWay **way); +int32 GPS_Command_Send_Proximity(const char *port, GPS_PWay *way, int32 n); + +int32 GPS_Command_Get_Route(const char *port, GPS_PWay **way); +int32 GPS_Command_Send_Route(const char *port, GPS_PWay *way, int32 n); + +int32 GPS_Command_Get_Lap(const char *port, GPS_PLap **lap, int (*cb)(int, struct GPS_SWay **)); + +int32 GPS_Command_Get_Workout(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); +int32 GPS_Command_Get_Fitness_User_Profile(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); +int32 GPS_Command_Get_Workout_Limits(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); +int32 GPS_Command_Get_Course(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); +int32 GPS_Command_Get_Course_Limits(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsdatum.h b/jeeps/gpsdatum.h new file mode 100644 index 000000000..005aeb0a7 --- /dev/null +++ b/jeeps/gpsdatum.h @@ -0,0 +1,246 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsdatum_h +#define gpsdatum_h + + + +typedef struct GPS_SEllipse +{ + char *name; + double a; + double invf; +} GPS_OEllipse, *GPS_PEllipse; + +GPS_OEllipse GPS_Ellipse[]= +{ + { "Airy 1830", 6377563.396, 299.3249646 }, + { "Airy 1830 Modified", 6377340.189, 299.3249646 }, + { "Australian National", 6378160.000, 298.25 }, + { "Bessel 1841 (Namibia)", 6377483.865, 299.1528128 }, + { "Bessel 1841", 6377397.155, 299.1528128 }, + { "Clarke 1866", 6378206.400, 294.9786982 }, + { "Clarke 1880", 6378249.145, 293.465 }, + { "Everest (India 1830)", 6377276.345, 300.8017 }, + { "Everest (Sabah Sarawak)", 6377298.556, 300.8017 }, + { "Everest (India 1956)", 6377301.243, 300.8017 }, + { "Everest (Malaysia 1969)", 6377295.664, 300.8017 }, + { "Everest (Malay & Sing)", 6377304.063, 300.8017 }, + { "Everest (Pakistan)", 6377309.613, 300.8017 }, + { "Modified Fischer 1960", 6378155.000, 298.3 }, + { "Helmert 1906", 6378200.000, 298.3 }, + { "Hough 1960", 6378270.000, 297.0 }, + { "Indonesian 1974", 6378160.000, 298.247 }, + { "International 1924", 6378388.000, 297.0 }, + { "Krassovsky 1940", 6378245.000, 298.3 }, + { "GRS67", 6378160.000, 6356774.516 }, + { "GRS75", 6378140.000, 6356755.288 }, + { "GRS80", 6378137.000, 298.257222101 }, + { "S. American 1969", 6378160.000, 298.25 }, + { "WGS60", 6378165.000, 298.3 }, + { "WGS66", 6378145.000, 298.25 }, + { "WGS72", 6378135.000, 298.26 }, + { "WGS84", 6378137.000, 298.257223563 }, +}; + + + +typedef struct GPS_SDatum +{ + char *name; + int ellipse; + double dx; + double dy; + double dz; +} GPS_ODatum, *GPS_PDatum; + +GPS_ODatum GPS_Datum[]= +{ +/* 000 */ { "Adindan", 6, -166, -15, 204 }, +/* 001 */ { "AFG", 18, -43, -163, 45 }, +/* 002 */ { "Ain-El-Abd", 17, -150, -251, -2 }, +/* 003 */ { "Alaska-NAD27", 5, -5, 135, 172 }, +/* 004 */ { "Alaska-Canada", 6, -9, 151, 185 }, +/* 005 */ { "Anna-1-Astro", 2, -491, -22, 435 }, +/* 006 */ { "ARC 1950 Mean", 6, -143, -90, -294 }, +/* 007 */ { "ARC 1960 Mean", 6, -160, -8, -300 }, +/* 008 */ { "Asc Island 58", 17, -207, 107, 52 }, +/* 009 */ { "Astro B4", 17, 114, -116, -333 }, +/* 010 */ { "Astro Beacon E", 17, 145, 75, -272 }, +/* 011 */ { "Astro pos 71/4", 17, -320, 550, -494 }, +/* 012 */ { "Astro stn 52", 17, 124, -234, -25 }, +/* 013 */ { "Australia Geo 1984", 2, -134, -48, 149 }, +/* 014 */ { "Bahamas NAD27", 6, -4, 154, 178 }, +/* 015 */ { "Bellevue IGN", 17, -127, -769, 472 }, +/* 016 */ { "Bermuda 1957", 6, -73, 213, 296 }, +/* 017 */ { "Bukit Rimpah", 4, -384, 664, -48 }, +/* 018 */ { "Camp_Area_Astro", 17, -104, -129, 239 }, +/* 019 */ { "Campo_Inchauspe", 17, -148, 136, 90 }, +/* 020 */ { "Canada_Mean(NAD27)", 5, -10, 158, 187 }, +/* 021 */ { "Canal_Zone_(NAD27)", 5, 0, 125, 201 }, +/* 022 */ { "Canton_Island_1966", 17, 298, -304, -375 }, +/* 023 */ { "Cape", 6, -136, -108, -292 }, +/* 024 */ { "Cape_Canaveral_mean", 5, -2, 150, 181 }, +/* 025 */ { "Carribean NAD27", 5, -7, 152, 178 }, +/* 026 */ { "Carthage", 6, -263, 6, 431 }, +/* 027 */ { "Cent America NAD27", 5 , 0, 125, 194 }, +/* 028 */ { "Chatham 1971", 17, 175, -38, 113 }, +/* 029 */ { "Chua Astro", 17, -134, 229, -29 }, +/* 030 */ { "Corrego Alegre", 17, -206, 172, -6 }, +/* 031 */ { "Cuba NAD27", 5, -9, 152, 178 }, +/* 032 */ { "Cyprus", 17, -104, -101, -140 }, +/* 033 */ { "Djakarta(Batavia)", 4, -377, 681, -50 }, +/* 034 */ { "DOS 1968", 17, 230, -199, -752 }, +/* 035 */ { "Easter lsland 1967", 17, 211, 147, 111 }, +/* 036 */ { "Egypt", 17, -130, -117, -151 }, +/* 037 */ { "European 1950", 17, -87, -96, -120 }, +/* 038 */ { "European 1950 mean", 17, -87, -98, -121 }, +/* 039 */ { "European 1979 mean", 17, -86, -98, -119 }, +/* 040 */ { "Finnish Nautical", 17, -78, -231, -97 }, +/* 041 */ { "Gandajika Base", 17, -133, -321, 50 }, +/* 042 */ { "Geodetic Datum 49", 17, 84, -22, 209 }, +/* 043 */ { "Ghana", 26, 0, 0, 0 }, +/* 044 */ { "Greenland NAD27", 5, 11, 114, 195 }, +/* 045 */ { "Guam 1963", 5, -100, -248, 259 }, +/* 046 */ { "Gunung Segara", 4, -403, 684, 41 }, +/* 047 */ { "Gunung Serindung 1962", 26, 0, 0, 0 }, +/* 048 */ { "GUX1 Astro", 17, 252, -209, -751 }, +/* 049 */ { "Herat North", 17, -333, -222, 114 }, +/* 050 */ { "Hjorsey 1955", 17, -73, 46, 86 }, +/* 051 */ { "Hong Kong 1963", 17, -156, -271, -189 }, +/* 052 */ { "Hu-Tzu-Shan", 17, -634, -549, -201 }, +/* 053 */ { "Indian", 9, 289, 734, 257 }, +/* 054 */ { "Iran", 17, -117, -132, -164 }, +/* 055 */ { "Ireland 1965", 1, 506, -122, 611 }, +/* 056 */ { "ISTS 073 Astro 69", 17, 208, -435, -229 }, +/* 057 */ { "Johnston Island 61", 17, 191, -77, -204 }, +/* 058 */ { "Kandawala", 7, -97, 787, 86 }, +/* 059 */ { "Kerguelen Island", 17, 145, -187, 103 }, +/* 060 */ { "Kertau 48", 11, -11, 851, 5 }, +/* 061 */ { "L.C. 5 Astro", 5, 42, 124, 147 }, +/* 062 */ { "La Reunion", 17, 94, -948, -1262 }, +/* 063 */ { "Liberia 1964", 6, -90, 40, 88 }, +/* 064 */ { "Luzon", 5, -133, -77, -51 }, +/* 065 */ { "Mahe 1971", 6, 41, -220, -134 }, +/* 066 */ { "Marco Astro", 17, -289, -124, 60 }, +/* 067 */ { "Masirah Is. Nahrwan", 6, -247, -148, 369 }, +/* 068 */ { "Massawa", 4, 639, 405, 60 }, +/* 069 */ { "Merchich", 6, 31, 146, 47 }, +/* 070 */ { "Mexico NAD27", 5, -12, 130, 190 }, +/* 071 */ { "Midway Astro 61", 17, 912, -58, 1227 }, +/* 072 */ { "Mindanao", 5, -133, -79, -72 }, +/* 073 */ { "Minna", 6, -92, -93, 122 }, +/* 074 */ { "Montjong Lowe", 26, 0, 0, 0 }, +/* 075 */ { "Nahrwan", 6, -231, -196, 482 }, +/* 076 */ { "Naparima BWI", 17, -2, 374, 172 }, +/* 077 */ { "North America 83", 21, 0, 0, 0 }, +/* 078 */ { "N. America 1927 mean", 5, -8, 160, 176 }, +/* 079 */ { "Observatorio 1966", 17, -425, -169, 81 }, +/* 080 */ { "Old Egyptian", 14, -130, 110, -13 }, +/* 081 */ { "Old Hawaiian_mean", 5, 89, -279, -183 }, +/* 082 */ { "Old Hawaiian Kauai", 5, 45, -290, -172 }, +/* 083 */ { "Old Hawaiian Maui", 5, 65, -290, -190 }, +/* 084 */ { "Old Hawaiian Oahu", 5, 56, -284, -181 }, +/* 085 */ { "Oman", 6, -346, -1, 224 }, +/* 086 */ { "OSGB36", 0, 375, -111, 431 }, +/* 087 */ { "Pico De Las Nieves", 17, -307, -92, 127 }, +/* 088 */ { "Pitcairn Astro 67", 17, 185, 165, 42 }, +/* 089 */ { "S. Am. 1956 mean(P)", 17, -288, 175, -376 }, +/* 090 */ { "S. Chilean 1963 (P)", 17, 16, 196, 93 }, +/* 091 */ { "Puerto Rico", 5, 11, 72, -101 }, +/* 092 */ { "Pulkovo 1942", 18, 28, -130, -95 }, +/* 093 */ { "Qornoq", 17, 164, 138, -189 }, +/* 094 */ { "Quatar National", 17, -128, -283, 22 }, +/* 095 */ { "Rome 1940", 17, -225, -65, 9 }, +/* 096 */ { "S-42(Pulkovo1942)", 18, 28, -121, -77 }, +/* 097 */ { "S.E.Asia_(Indian)", 7, 173, 750, 264 }, +/* 098 */ { "SAD-69/Brazil", 22, -60, -2, -41 }, +/* 099 */ { "Santa Braz", 17, -203, 141, 53 }, +/* 100 */ { "Santo (DOS)", 17, 170, 42, 84 }, +/* 101 */ { "Sapper Hill 43", 17, -355, 16, 74 }, +/* 102 */ { "Schwarzeck", 3, 616, 97, -251 }, +/* 103 */ { "Sicily", 17, -97, -88, -135 }, +/* 104 */ { "Sierra Leone 1960", 26, 0, 0, 0 }, +/* 105 */ { "S. Am. 1969 mean", 22, -57, 1, -41 }, +/* 106 */ { "South Asia", 13, 7, -10, -26 }, +/* 107 */ { "Southeast Base", 17, -499, -249, 314 }, +/* 108 */ { "Southwest Base", 17, -104, 167, -38 }, +/* 109 */ { "Tananarive Obs 25", 17, -189, -242, -91 }, +/* 110 */ { "Thai/Viet (Indian)", 7, 214, 836, 303 }, +/* 111 */ { "Timbalai 1948", 7, -689, 691, -45 }, +/* 112 */ { "Tokyo mean", 4, -128, 481, 664 }, +/* 113 */ { "Tristan Astro 1968", 17, -632, 438, -609 }, +/* 114 */ { "United Arab Emirates", 6, -249, -156, 381 }, +/* 115 */ { "Viti Levu 1916", 6, 51, 391, -36 }, +/* 116 */ { "Wake Eniwetok 60", 15, 101, 52, -39 }, +/* 117 */ { "WGS 72", 25, 0, 0, 5 }, +/* 118 */ { "WGS 84", 26, 0, 0, 0 }, +/* 119 */ { "Yacare", 17, -155, 171, 37 }, +/* 120 */ { "Zanderij", 17, -265, 120, -358 }, +/* 121 */ { "Sweden", 4, 424.3, -80.5, 613.1 }, +/* 122 */ { "GDA 94", 21, 0, 0, 0 }, +/* 123 */ { "CH-1903", 4, 674, 15, 405 }, + { NULL, 0, 0, 0, 0 } +}; + + +typedef struct GPS_SDatum_Alias +{ + char *alias; + const int datum; +} GPS_ODatum_Alias, *GPS_PDatum_Alias; + +GPS_ODatum_Alias GPS_DatumAlias[] = +{ + { "Australian GDA94", 122 }, + { "GDA94", 122 }, + { "GDA-94", 122 }, + { "CH1903", 123 }, + { "CH 1903", 123 }, + { "Geodetic Datum 1949", 42 }, + { "NAD27 Alaska", 3 }, + { "NAD27 Bahamas", 14 }, + { "NAD27 Canada", 4 }, + { "NAD27 Canal Zone", 21 }, + { "NAD27 Caribbean", 25 }, + { "NAD27 Central", 27 }, + { "NAD27 CONUS", 78 }, + { "NAD27 Cuba", 31 }, + { "NAD27 Greenland", 44 }, + { "NAD27 Mexico", 70 }, + { "NAD83", 77 }, + { "NAD 83", 77 }, + { "NAD-83", 77 }, + { "OSGB 36", 86 }, + { "OSGB-36", 86 }, + { "Wake-Eniwetok 1960", 116 }, + { "WGS72", 117 }, + { "WGS-72", 117 }, + { "WGS84", 118 }, + { "WGS-84", 118 }, + { NULL, -1 } +}; + + +/* UK Ordnance Survey Nation Grid Map Codes */ +static char *UKNG[]= +{ + "SV","SW","SX","SY","SZ","TV","TW","SQ","SR","SS","ST","SU","TQ","TR", + "SL","SM","SN","SO","SP","TL","TM","SF","SG","SH","SJ","SK","TF","TG", + "SA","SB","SC","SD","SE","TA","TB","NV","NW","NX","NY","NZ","OV","OW", + "NQ","NR","NS","NT","NU","OQ","OR","NL","NM","NN","NO","NP","OL","OM", + "NF","NG","NH","NJ","NK","OF","OG","NA","NB","NC","ND","NE","OA","OB", + "HV","HW","HX","HY","HZ","JV","JW","HQ","HR","HS","HT","HU","JQ","JR", + "HL","HM","HN","HO","HP","JL","JM","" +}; + + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsdevice.c b/jeeps/gpsdevice.c new file mode 100644 index 000000000..90c841f1b --- /dev/null +++ b/jeeps/gpsdevice.c @@ -0,0 +1,86 @@ +/* + Abstraction of underlying device types, serial or USB. OS agnostic.. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software{} you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation{} either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY{} without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program{} if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "gps.h" +#include "gpsdevice.h" +#include "gpsserial.h" + +extern gps_device_ops gps_serial_ops; +extern gps_device_ops gps_usb_ops; +gps_device_ops *ops = NULL; + +int32 GPS_Device_On(const char *port, gpsdevh **fd) +{ + gps_is_usb = (0 == case_ignore_strncmp(port, "usb:", 4)); + + if (gps_is_usb) { + ops = &gps_usb_ops; + } else { + ops = &gps_serial_ops; + } + + return (ops->Device_On)(port, fd); +} + +int32 GPS_Device_Off(gpsdevh * fd) +{ + return (ops->Device_Off)(fd); +} + +int32 GPS_Device_Wait(gpsdevh * fd) +{ + return (ops->Device_Wait)(fd); +} + +int32 GPS_Device_Chars_Ready(gpsdevh * fd) +{ + return (ops->Device_Chars_Ready)(fd); +} + +int32 GPS_Device_Flush(gpsdevh * fd) +{ + return (ops->Device_Flush)(fd); +} + +int32 GPS_Write_Packet(gpsdevh * fd, GPS_PPacket packet) +{ + return (ops->Write_Packet)(fd, packet); +} + +int32 GPS_Packet_Read(gpsdevh * fd, GPS_PPacket *packet) +{ + return (ops->Read_Packet)(fd, packet); +} + +int32 GPS_Send_Ack(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec) +{ + return (ops->Send_Ack)(fd, tra, rec); +} + +int32 GPS_Get_Ack(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec) +{ + return (ops->Get_Ack)(fd, tra, rec); +} + +void GPS_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n) +{ + (ops->Make_Packet)(packet, type, data, n); +} diff --git a/jeeps/gpsdevice.h b/jeeps/gpsdevice.h new file mode 100644 index 000000000..eb5d53d96 --- /dev/null +++ b/jeeps/gpsdevice.h @@ -0,0 +1,73 @@ +/* + Abstraction of underlying device types. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsdevice_h +#define gpsdevice_h + +typedef struct gpsdevh gpsdevh; + +#include "gps.h" + +#define usecDELAY 180000 /* Microseconds before GPS sends A001 */ + + +int32 GPS_Device_Chars_Ready(gpsdevh *fd); +int32 GPS_Device_On(const char *port, gpsdevh **fd); +int32 GPS_Device_Off(gpsdevh *fd); +int32 GPS_Device_Wait(gpsdevh * fd); +int32 GPS_Device_Flush(gpsdevh * fd); +int32 GPS_Device_Read(int32 ignored, void *ibuf, int size); +int32 GPS_Device_Write(int32 ignored, const void *obuf, int size); +void GPS_Device_Error(char *hdr, ...); +int32 GPS_Write_Packet(gpsdevh *fd, GPS_PPacket packet); +int32 GPS_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); +int32 GPS_Packet_Read(gpsdevh *fd, GPS_PPacket *packet); +int32 GPS_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + +typedef int32 (*gps_device_op)(gpsdevh *); +typedef int32 (*gps_device_op5)(const char *, gpsdevh **fd); +typedef int32 (*gps_device_op10)(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec); +typedef int32 (*gps_device_op12)(gpsdevh * fd, GPS_PPacket packet); +typedef int32 (*gps_device_op13)(gpsdevh * fd, GPS_PPacket *packet); +typedef void (*gps_device_op14)(GPS_PPacket *packet, UC type, UC *data, int16 n); +typedef struct { + gps_device_op5 Device_On; + gps_device_op Device_Off; + gps_device_op Device_Chars_Ready; + gps_device_op Device_Wait; + gps_device_op Device_Flush; + gps_device_op10 Send_Ack; + gps_device_op10 Get_Ack; + gps_device_op13 Read_Packet; + gps_device_op14 Make_Packet; + gps_device_op12 Write_Packet; +} gps_device_ops; + +#endif /* gpsdevice.h */ + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsdevice_ser.c b/jeeps/gpsdevice_ser.c new file mode 100644 index 000000000..29ff476e6 --- /dev/null +++ b/jeeps/gpsdevice_ser.c @@ -0,0 +1,37 @@ +/* + Serial operations. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "gpsdevice.h" +#include "gpsserial.h" +#include "gpsread.h" + +gps_device_ops gps_serial_ops = { + GPS_Serial_On, + GPS_Serial_Off, + GPS_Serial_Chars_Ready, + GPS_Serial_Wait, + GPS_Serial_Flush, + GPS_Serial_Send_Ack, + GPS_Serial_Get_Ack, + GPS_Serial_Packet_Read, + GPS_Serial_Make_Packet, + GPS_Serial_Write_Packet, +}; diff --git a/jeeps/gpsdevice_usb.c b/jeeps/gpsdevice_usb.c new file mode 100644 index 000000000..dd578c829 --- /dev/null +++ b/jeeps/gpsdevice_usb.c @@ -0,0 +1,59 @@ +/* + USB operations. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "gpsdevice.h" +#include "garminusb.h" +#include "gpsusbint.h" +#include "gpsusbcommon.h" + +static int32 success_stub(void) +{ + return 1; +} + +static int32 gdu_on(const char *port, gpsdevh **fd) +{ + return gusb_init(port, fd); +} + +static int32 gdu_off(gpsdevh *dh) +{ + return gusb_close(dh); +} + +static int32 gdu_read(gpsdevh *fd, GPS_PPacket *packet) +{ + /* Default is to eat bulk request packets. */ + return GPS_Packet_Read_usb(fd, packet, 1); +} + +gps_device_ops gps_usb_ops = { + gdu_on, + gdu_off, + (gps_device_op) success_stub, + (gps_device_op) success_stub, + (gps_device_op) success_stub, + (gps_device_op10) success_stub, + (gps_device_op10) success_stub, + gdu_read, + GPS_Make_Packet_usb, + GPS_Write_Packet_usb +}; diff --git a/jeeps/gpsfmt.c b/jeeps/gpsfmt.c new file mode 100644 index 000000000..f4919a092 --- /dev/null +++ b/jeeps/gpsfmt.c @@ -0,0 +1,1562 @@ +/******************************************************************** +** @source JEEPS output functions +** +** @author Copyright (C) 1999 Alan Bleasby +** @version 1.0 +** @modified Dec 28 1999 Alan Bleasby. First version +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include +#include + + +static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE *outf); +static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE *outf); + +static void GPS_Fmt_Print_Track301(GPS_PTrack *trk, int32 n, FILE *outf); +static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE *outf); +static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE *outf); + +static int32 GPS_Fmt_Print_Route201(GPS_PWay *way, int32 n, FILE *outf); + + +char *gps_marine_sym[]= +{ + "Anchor","Bell","Diamond-grn","Diamond_red","Dive1","Dive2","Dollar", + "Fish","Fuel","Horn","House","Knife","Light","Mug","Skull", + "Square_grn","Square_red","Wbuoy","Wpt_dot","Wreck","Null","Mob", + + "Buoy_amber","Buoy_blck","Buoy_blue","Buoy_grn","Buoy_grn_red", + "Buoy_grn_wht","Buoy_orng","Buoy_red","Buoy_red_grn","Buoy_red_wht", + "Buoy_violet","Buoy_wht","Buoy_wht_grn","Buoy_wht_red","Dot","Rbcn", + + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","", + + "Boat_ramp","Camp","Toilets","Showers","Drinking_wtr","Phone", + "1st_aid","Info","Parking","Park","Picnic","Scenic","Skiing", + "Swimming","Dam","Controlled","Danger","Restricted","Null_2","Ball", + "Car","Deer","Shpng_trolley","Lodging","Mine","Trail_head", + "Lorry_stop","User_exit","Flag","Circle-x" +}; + + + +char *gps_land_sym[]= +{ + "Is_hwy","Us_hwy","St_hwy","Mi_mrkr","Trcbck","Golf","Sml_cty", + "Med_cty","Lrg_cty","Freeway","Ntl_hwy","Cap_cty","Amuse_pk", + "Bowling","Car_rental","Car_repair","Fastfood","Fitness","Film", + "Museum","Chemist","Pizza","Post_ofc","Rv_park","School", + "Stadium","Shop","Zoo","Petrol_plus","Theatre","Ramp_int", + "St_int","","","Weigh_stn","Toll_booth","Elev_pt","Ex_no_srvc", + "Geo_place_mm","Geo_place_wtr","Geo_place_lnd","Bridge","Building", + "Cemetery","Church","Civil_loc","Crossing","Hist_town","River_Embankment", + "Military_loc","Oil_field","Tunnel","Beach","Forest","Summit", + "Lrg_ramp_int","Lrg_exit_no_srvc","Official_badge","Gambling", + "Snow_ski","Ice_ski","Tow_truck","Border" +}; + + +char *gps_aviation_sym[]= +{ + "Airport","Int","Ndb","Vor","Heliport","Private","Soft_fld", + "Tall_tower","Short_tower","Glider","Ultralight","Parachute", + "Vortac","Vordme","Faf","Lom","Map","Tacan","Seaplane" +}; + + +char *gps_16_sym[]= +{ + "Dot","House","Fuel","Car","Fish","Boat","Anchor","Wreck", + "Exit","Skull","Flag","Camp","Circle-x","Deer","1st_aid","Back_track" +}; + + + + + +/* @func GPS_Fmt_Print_Time ******************************************** +** +** Output Date/time +** +** @param [r] Time [time_t] unix-style time +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +void GPS_Fmt_Print_Time(time_t Time, FILE *outf) +{ + (void) fprintf(outf,"%s",ctime(&Time)); + fflush(outf); + + return; +} + + + +/* @func GPS_Fmt_Print_Position ******************************************** +** +** Output position +** +** @param [r] lat [double] latitude (deg) +** @param [r] lon [double] longitude (deg) +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +void GPS_Fmt_Print_Position(double lat, double lon, FILE *outf) +{ + (void) fprintf(outf,"Latitude: %f Longitude %f\n",lat,lon); + fflush(outf); + + return; +} + + + +/* @func GPS_Fmt_Print_Pvt ******************************************** +** +** Output pvt +** +** @param [r] pvt [GPS_PPvt_Data] pvt +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE *outf) +{ + + (void) fprintf(outf,"Fix: "); + switch(pvt->fix) + { + case 0: + (void) fprintf(outf,"UNUSABLE\n\n"); + break; + case 1: + (void) fprintf(outf,"INVALID \n\n"); + break; + case 2: + (void) fprintf(outf,"2D \n\n"); + break; + case 3: + (void) fprintf(outf,"3D \n\n"); + break; + case 4: + (void) fprintf(outf,"2D-diff \n\n"); + break; + case 5: + (void) fprintf(outf,"2D-diff \n\n"); + break; + default: + (void) fprintf(stderr,"PVT: Unsupported Fix type\n"); + break; + } + + (void) fprintf(outf,"Altitude (WGS 84): %-20f \n",pvt->alt); + (void) fprintf(outf,"EPE: %-20f \n",pvt->epe); + (void) fprintf(outf,"EPE (hor only): %-20f \n",pvt->eph); + (void) fprintf(outf,"EPE (ver only): %-20f \n",pvt->epv); + (void) fprintf(outf,"Time of week: %-20d \n",(int)pvt->tow); + (void) fprintf(outf,"Latitude: %-20f \n",pvt->lat); + (void) fprintf(outf,"Longitude: %-20f \n",pvt->lon); + (void) fprintf(outf,"East velocity: %-20f \n",pvt->east); + (void) fprintf(outf,"North velocity: %-20f \n",pvt->north); + (void) fprintf(outf,"Upward velocity %-20f \n",pvt->up); + (void) fprintf(outf,"Height above MSL: %-20f \n",pvt->msl_hght+pvt->alt); + (void) fprintf(outf,"Leap seconds: %-20d \n",pvt->leap_scnds); + (void) fprintf(outf,"Week number days: %-20d \n",(int)pvt->wn_days); + + fflush(outf); + + return; +} + + + +/* @func GPS_Fmt_Print_Almanac ******************************************** +** +** Output almanac +** +** @param [r] alm [GPS_PAlmanac *] almanac array +** @param [r] n [int32] number of almanac entries +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +void GPS_Fmt_Print_Almanac(GPS_PAlmanac *alm, int32 n, FILE *outf) +{ + int32 i; + int32 t; + int32 s; + + /* Type 0 models require all 32 satellites to be sent */ + t=32; + s=0; + if(n && alm[0]->svid!=0xff) + { + s=1; + t=n; + } + (void) fprintf(outf,"Almanac %d %d\n",(int)t,(int)s); + + + for(i=0;iwn<0) continue; + + if(alm[i]->svid == 0xff) + alm[i]->svid = i; + (void) fprintf(outf,"#\n#\n"); + (void) fprintf(outf,"\tID: %d\n", + alm[i]->svid+1); + (void) fprintf(outf,"\tWeek number: %d\n", + alm[i]->wn); + (void) fprintf(outf,"\tAlmanac Data Reference Time: %f\n", + alm[i]->toa); + (void) fprintf(outf,"\tClock Correction Coeff (s): %f\n", + alm[i]->af0); + (void) fprintf(outf,"\tClock Correction Coeff (s/s): %f\n", + alm[i]->af1); + (void) fprintf(outf,"\tEccentricity: %f\n", + alm[i]->e); + (void) fprintf(outf,"\tSqrt of semi-major axis: %f\n", + alm[i]->sqrta); + (void) fprintf(outf,"\tMean Anomaly at Ref. Time: %f\n", + alm[i]->m0); + (void) fprintf(outf,"\tArgument of perigee: %f\n", + alm[i]->w); + (void) fprintf(outf,"\tRight ascension: %f\n", + alm[i]->omg0); + (void) fprintf(outf,"\tRate of right ascension: %f\n", + alm[i]->odot); + (void) fprintf(outf,"\tInclination angle: %f\n", + alm[i]->i); + (void) fprintf(outf,"\tHealth: %d\n", + alm[i]->hlth); + } + + + fflush(outf); + + return; +} + + + +/* @func GPS_Fmt_Print_Track ******************************************** +** +** Output track log +** +** @param [r] trk [GPS_PTrack *] track array +** @param [r] n [int32] number of track entries +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +void GPS_Fmt_Print_Track(GPS_PTrack *trk, int32 n, FILE *outf) +{ + int32 i; + + + switch(gps_trk_transfer) + { + case pA300: + break; + case pA301: + GPS_Fmt_Print_Track301(trk,n,outf); + return; + default: + GPS_Error("GPS_Fmt_Print_Track: Unknown protocol"); + return; + } + + + (void) fprintf(outf,"Track log 300 %d\n#\n",(int)gps_trk_type); + (void) fprintf(outf,"Start\n#\n"); + + for(i=0;itnew) + (void) fprintf(outf,"#\nNew track\n#\n"); + + switch(gps_trk_type) + { + case pD300: + GPS_Fmt_Print_D300(trk[i],outf); + break; + case pD301: + GPS_Fmt_Print_D301(trk[i],outf); + break; + default: + break; + } + } + + (void) fprintf(outf,"End\n#\n"); + fflush(outf); + + return; +} + + + +/* @funcstatic GPS_Fmt_Print_Track301 *********************************** +** +** Output track log +** +** @param [r] trk [GPS_PTrack *] track array +** @param [r] n [int32] number of track entries +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Track301(GPS_PTrack *trk, int32 n, FILE *outf) +{ + int32 i; + + if(!n) + return; + + (void) fprintf(outf,"Track log 301 %d\n#\n",(int)gps_trk_type); + (void) fprintf(outf,"Start\n#\n"); + + for(i=0;iishdr) + { + (void) fprintf(outf,"Header\n"); + (void) fprintf(outf,"\tIdent: %s\n",trk[i]->trk_ident); + (void) fprintf(outf,"\tDisplay: %d\n",(int)trk[i]->dspl); + (void) fprintf(outf,"\tColour: %d\n#\n", + (int)trk[i]->colour); + continue; + } + + if(trk[i]->tnew) + (void) fprintf(outf,"#\nNew track\n#\n"); + + switch(gps_trk_type) + { + case pD300: + GPS_Fmt_Print_D300(trk[i],outf); + break; + case pD301: + GPS_Fmt_Print_D301(trk[i],outf); + break; + default: + break; + } + } + + (void) fprintf(outf,"End\n#\n"); + fflush(outf); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_D300 **************************************** +** +** Output track log +** +** @param [r] trk [GPS_PTrack *] track array +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE *outf) +{ + (void) fprintf(outf,"\tLatitude: %f\n",trk->lat); + (void) fprintf(outf,"\tLongitude: %f\n",trk->lon); + if(trk->Time) + (void) fprintf(outf,"\tTime: %s\n",ctime(&trk->Time)); + else + (void) fprintf(outf,"\tTime: Computer\n\n"); + + return; +} + + + +/* @funcstatic GPS_Fmt_Print_D301 **************************************** +** +** Output track log +** +** @param [r] trk [GPS_PTrack *] track array +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE *outf) +{ + (void) fprintf(outf,"\tLatitude: %f\n",trk->lat); + (void) fprintf(outf,"\tLongitude: %f\n",trk->lon); + if(trk->Time) + (void) fprintf(outf,"\tTime: %s",ctime(&trk->Time)); + else + (void) fprintf(outf,"\tTime: Computer\n"); + (void) fprintf(outf,"\tAltitude: %f\n",trk->alt); + (void) fprintf(outf,"\tDepth: %f\n\n",trk->dpth); + + return; +} + + + + +/* @func GPS_Fmt_Print_Waypoint ***************************************** +** +** Output waypoints +** +** @param [r] way [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** @param [w] outf [FILE *] output stream +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Fmt_Print_Waypoint(GPS_PWay *way, int32 n, FILE *outf) +{ + int32 i; + + + if(!n) + return 1; + + (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n", + (int)way[0]->prot); + + + for(i=0;iprot) + { + case 100: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 103: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 150: + GPS_Fmt_Print_Way150(way[i],outf); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Waypoint: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n#\n"); + + return 1; +} + + + +/* @func GPS_Fmt_Print_Proximity ***************************************** +** +** Output proximity +** +** @param [r] way [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** @param [w] outf [FILE *] output stream +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Fmt_Print_Proximity(GPS_PWay *way, int32 n, FILE *outf) +{ + int32 i; + + + if(!n) + return 1; + + (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n", + (int)way[0]->prot); + + + for(i=0;iprot) + { + case 400: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 403: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 450: + GPS_Fmt_Print_Way150(way[i],outf); + (void) fprintf(outf,"\tPindex: %d\n",(int)way[i]->idx); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Proximity: Unknown proximity protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"\tDistance: %f\n",way[i]->dst); + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n#\n"); + + return 1; +} + + + + +/* @funcstatic GPS_Fmt_Print_Way100 ************************************* +** +** Output waypoint D100 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE *outf) +{ + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_Way101 ************************************ +** +** Output waypoint D101 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE *outf) +{ + + if(way->smbl > 176) way->smbl=36; + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %d [%s]\n",(int)way->smbl, + gps_marine_sym[way->smbl]); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_Way102 ************************************* +** +** Output waypoint D102 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE *outf) +{ + char **p; + int32 x; + + if(way->smbl < 8192) + { + p = gps_marine_sym; + x = 0; + } + else if(way->smbl < 16384) + { + p = gps_land_sym; + x = 8192; + } + else + { + p = gps_aviation_sym; + x = 16384; + } + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_Way103 ************************************ +** +** Output waypoint D103 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE *outf) +{ + static char *dspl[]= + { + "SW","S","SC" + }; + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + gps_16_sym[way->smbl]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_Way104 ************************************* +** +** Output waypoint D104 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE *outf) +{ + static char *dspl[]= + { + "S","S","","SW","","SC" + }; + char **p; + int32 x; + + if(way->smbl < 8192) + { + p = gps_marine_sym; + x = 0; + } + else if(way->smbl < 16384) + { + p = gps_land_sym; + x = 8192; + } + else + { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_Way105 ************************************ +** +** Output waypoint D105 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE *outf) +{ + char **p; + int32 x; + + if(way->smbl < 8192) + { + p = gps_marine_sym; + x = 0; + } + else if(way->smbl < 16384) + { + p = gps_land_sym; + x = 8192; + } + else + { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tWpt_ident %s\n",way->wpt_ident); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_Way106 ************************************* +** +** Output waypoint D106 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE *outf) +{ + char **p; + int32 x; + + if(way->smbl < 8192) + { + p = gps_marine_sym; + x = 0; + } + else if(way->smbl < 16384) + { + p = gps_land_sym; + x = 8192; + } + else + { + p = gps_aviation_sym; + x = 16384; + } + + if(!way->wpt_class) + { + (void) fprintf(outf,"\tClass: %d [User]\n",way->wpt_class); + (void) fprintf(outf,"\tSubclass: %d [%-13.13s]\n", + way->wpt_class,way->subclass); + (void) fprintf(outf,"\tSubclass:\n"); + } + else + { + (void) fprintf(outf,"\tClass: %d [Non-user]\n", + way->wpt_class); + (void) fprintf(outf,"\tSubclass: %d [%13.13s]\n", + way->wpt_class, + way->subclass); + } + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tWpt_ident %s\n",way->wpt_ident); + (void) fprintf(outf,"\tLnk_ident %s\n",way->lnk_ident); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_Way107 ************************************ +** +** Output waypoint D107 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE *outf) +{ + static char *dspl[]= + { + "SW","S","SC" + }; + static char *col[]= + { + "Default","Red","Green","Blue" + }; + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + gps_16_sym[way->smbl]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, + col[way->colour]); + + return; +} + + + +/* @funcstatic GPS_Fmt_Print_Way108 ************************************ +** +** Output waypoint D108 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE *outf) +{ + char **p; + int32 x; + + static char *dspl[]= + { + "SW","S","SC" + }; + + static char *col[]= + { + "Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue", + "Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green", + "Yellow","Blue","Magenta","Cyan","White" + }; + + + if(way->smbl < 8192) + { + p = gps_marine_sym; + x = 0; + } + else if(way->smbl < 16384) + { + p = gps_land_sym; + x = 8192; + } + else + { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tIdent: %s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + if(way->colour==0xff) + (void) fprintf(outf,"\tColour: 255 [Default]\n"); + else + (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, + col[way->colour]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + (void) fprintf(outf,"\tDepth: %f\n",way->dpth); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if(way->wpt_class>=0x80 && way->wpt_class<=0x85) + (void) fprintf(outf,"\tSubclass: %18.18s\n",way->subclass); + if(!way->wpt_class) + (void) fprintf(outf,"\tComment: %s\n",way->cmnt); + if(way->wpt_class>=0x40 && way->wpt_class<=0x46) + { + (void) fprintf(outf,"\tFacility: %s\n",way->facility); + (void) fprintf(outf,"\tCity: %s\n",way->city); + } + if(way->wpt_class==0x83) + (void) fprintf(outf,"\tAddress: %s\n",way->addr); + if(way->wpt_class==0x82) + (void) fprintf(outf,"\tCross Road: %s\n",way->cross_road); + + + return; +} + +/* @funcstatic GPS_Fmt_Print_Way109 ************************************ +** +** Output waypoint D109 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE *outf) +{ + char **p; + int32 x; + + static char *dspl[]= + { + "SW","S","SC" + }; + + static char *col[]= + { + "Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue", + "Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green", + "Yellow","Blue","Magenta","Cyan","White" + }; + + + if(way->smbl < 8192) + { + p = gps_marine_sym; + x = 0; + } + else if(way->smbl < 16384) + { + p = gps_land_sym; + x = 8192; + } + else + { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tIdent: %s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + if(way->colour==0xff) + (void) fprintf(outf,"\tColour: 255 [Default]\n"); + else + (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, + col[way->colour]); +#if 0 + /* avoid bounds violation in D109. Probably masking a bug elswhere...*/ + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); +#endif + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + (void) fprintf(outf,"\tDepth: %f\n",way->dpth); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if(way->wpt_class>=0x80 && way->wpt_class<=0x85) + (void) fprintf(outf,"\tSubclass: %18.18s\n",way->subclass); + if(!way->wpt_class) + (void) fprintf(outf,"\tComment: %s\n",way->cmnt); + if(way->wpt_class>=0x40 && way->wpt_class<=0x46) + { + (void) fprintf(outf,"\tFacility: %s\n",way->facility); + (void) fprintf(outf,"\tCity: %s\n",way->city); + } + if(way->wpt_class==0x83) + (void) fprintf(outf,"\tAddress: %s\n",way->addr); + if(way->wpt_class==0x82) + (void) fprintf(outf,"\tCross Road: %s\n",way->cross_road); + + + return; +} + +/* @funcstatic GPS_Fmt_Print_Way150 ************************************* +** +** Output waypoint D150 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE *outf) +{ + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if(way->wpt_class!=4) + { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if(!way->wpt_class) + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_Way151 ************************************ +** +** Output waypoint D151 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE *outf) +{ + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if(way->wpt_class!=2) + { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if(!way->wpt_class) + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + + return; +} + + + +/* @funcstatic GPS_Fmt_Print_Way152 ************************************ +** +** Output waypoint D152 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE *outf) +{ + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if(way->wpt_class!=4) + { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if(!way->wpt_class) + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_Way154 ************************************ +** +** Output waypoint D154 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE *outf) +{ + char **p; + int32 x; + + if(way->smbl < 8192) + { + p = gps_marine_sym; + x = 0; + } + else if(way->smbl < 16384) + { + p = gps_land_sym; + x = 8192; + } + else + { + p = gps_aviation_sym; + x = 16384; + } + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if(way->wpt_class!=4 && way->wpt_class!=8) + { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if(!way->wpt_class) + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + + return; +} + + +/* @funcstatic GPS_Fmt_Print_Way155 ************************************* +** +** Output waypoint D155 +** +** @param [r] way [GPS_PWay] waypoint +** @param [w] outf [FILE *] output stream +** +** @return [void] +************************************************************************/ + +static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE *outf) +{ + static char *dspl[]= + { + "","S","","SW","","SC" + }; + + char **p; + int32 x; + + if(way->smbl < 8192) + { + p = gps_marine_sym; + x = 0; + } + else if(way->smbl < 16384) + { + p = gps_land_sym; + x = 8192; + } + else + { + p = gps_aviation_sym; + x = 16384; + } + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if(way->wpt_class!=4 && way->wpt_class!=8) + { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if(!way->wpt_class) + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + + return; +} + + + +/* @func GPS_Fmt_Print_Route ***************************************** +** +** Output route(s) +** +** @param [r] way [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** @param [w] outf [FILE *] output stream +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Fmt_Print_Route(GPS_PWay *way, int32 n, FILE *outf) +{ + int32 i; + int32 first; + + if(!n) + return 1; + + + switch(gps_route_transfer) + { + case pA200: + break; + case pA201: + return GPS_Fmt_Print_Route201(way,n,outf); + default: + GPS_Error("GPS_Fmt_Print_Route: Unknown protocol"); + return PROTOCOL_ERROR; + } + + + (void) fprintf(outf,"Route log 200 %d\n#\n",(int)gps_rte_type); + (void) fprintf(outf,"Start\n#\n"); + + + + first = 1; + + for(i=0;iisrte) + { + if(!first) + (void) fprintf(outf,"End\n#\n"); + (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot); + first=0; + + switch(way[i]->rte_prot) + { + case 200: + (void) fprintf(outf,"Number: %d",way[i]->rte_num); + break; + case 201: + (void) fprintf(outf,"Number: %d Comment: %-20.20s", + way[i]->rte_num,way[i]->rte_cmnt); + break; + case 202: + (void) fprintf(outf,"Comment: %s",way[i]->rte_ident); + break; + default: + GPS_Error("Print_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"\n#\n"); + (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n" + ,(int)way[i]->prot); + continue; + } + + switch(way[i]->prot) + { + case 100: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 103: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 150: + GPS_Fmt_Print_Way150(way[i],outf); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Route: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n#\n"); + + return 1; +} + + + +/* @funcstatic GPS_Fmt_Print_Route201 *********************************** +** +** Output route(s) +** +** @param [r] way [GPS_PWay *] waypoint array +** @param [r] n [int32] number of waypoint entries +** @param [w] outf [FILE *] output stream +** +** @return [int32] success +************************************************************************/ + +static int32 GPS_Fmt_Print_Route201(GPS_PWay *way, int32 n, FILE *outf) +{ + int32 i; + int32 first; + + if(!n) + return 1; + + + (void) fprintf(outf,"Route log 201 %d\n#\n",(int)gps_rte_link_type); + (void) fprintf(outf,"Start\n#\n"); + + + first = 1; + + for(i=0;iisrte) + { + if(!first) + (void) fprintf(outf,"End\n#\n"); + (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot); + first=0; + + switch(way[i]->rte_prot) + { + case 200: + (void) fprintf(outf,"Number: %d",way[i]->rte_num); + break; + case 201: + (void) fprintf(outf,"Number: %d Comment: %-20.20s", + way[i]->rte_num,way[i]->rte_cmnt); + break; + case 202: + (void) fprintf(outf,"Comment: %s",way[i]->rte_ident); + break; + default: + GPS_Error("Print_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"\n#\n"); + (void) fprintf(outf,"Waypoints Type: %d\n#\n" + ,(int)way[i]->prot); + continue; + } + + + if(way[i]->islink) + { + (void) fprintf(outf,"\tLink Class: %d\n", + (int)way[i]->rte_link_class); + if(!(way[i]->rte_link_class==3 || way[i]->rte_link_class==0xff)) + (void) fprintf(outf,"\tLink Subclass: %-18.18s\n", + way[i]->rte_link_subclass); + (void) fprintf(outf,"\tLink Ident: %s\n#\n", + way[i]->rte_link_ident); + continue; + } + + + switch(way[i]->prot) + { + case 100: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 103: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 150: + GPS_Fmt_Print_Way150(way[i],outf); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Route: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n"); + + return 1; +} diff --git a/jeeps/gpsfmt.h b/jeeps/gpsfmt.h new file mode 100644 index 000000000..f9eaae32c --- /dev/null +++ b/jeeps/gpsfmt.h @@ -0,0 +1,27 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsfmt_h +#define gpsfmt_h + + +#include "gps.h" +#include +#include + +void GPS_Fmt_Print_Time(time_t Time, FILE *outf); +void GPS_Fmt_Print_Position(double lat, double lon, FILE *outf); +void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE *outf); +void GPS_Fmt_Print_Almanac(GPS_PAlmanac *alm, int32 n, FILE *outf); +void GPS_Fmt_Print_Track(GPS_PTrack *trk, int32 n, FILE *outf); +int32 GPS_Fmt_Print_Waypoint(GPS_PWay *way, int32 n, FILE *outf); +int32 GPS_Fmt_Print_Proximity(GPS_PWay *way, int32 n, FILE *outf); +int32 GPS_Fmt_Print_Route(GPS_PWay *way, int32 n, FILE *outf); + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsinput.c b/jeeps/gpsinput.c new file mode 100644 index 000000000..9cdf84741 --- /dev/null +++ b/jeeps/gpsinput.c @@ -0,0 +1,2262 @@ +/******************************************************************** +** @source JEEPS input functions +** +** @author Copyright (C) 1999 Alan Bleasby +** @version 1.0 +** @modified Dec 28 1999 Alan Bleasby. First version +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include +#include +#include +#include + + +static int32 GPS_Input_Load_String(char *t, int32 n, char *s); +static int32 GPS_Input_Load_Strnull(char *t, char *s); +static int32 GPS_Input_Read_Line(char *s, FILE *inf); + +static int32 GPS_Input_Get_D100(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D101(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D102(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D103(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D104(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D105(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D106(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D107(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D108(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf, int protonum); +static int32 GPS_Input_Get_D150(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D151(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D152(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D154(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D155(GPS_PWay *way, FILE *inf); + +static int32 GPS_Input_Get_Track301(GPS_PTrack **trk, FILE *inf, int32 type, + int32 n); +static int32 GPS_Input_Get_D300(GPS_PTrack *trk, FILE *inf, char *s); +static int32 GPS_Input_Get_D301(GPS_PTrack *trk, FILE *inf, char *s); + +static int32 GPS_Input_Get_Route201(GPS_PWay **way, FILE *inf); + + +/* @funcstatic GPS_Input_Load_String *********************************** +** +** Load a GPS char type from an input line +** Remove trailing newline +** +** @param [w] t [char *] string to load +** @param [r] n [int32] maximum type length +** @param [r] s [char *] source line +** +** @return [int32] success +************************************************************************/ +static int32 GPS_Input_Load_String(char *t, int32 n, char *s) +{ + char *p; + char *q; + + int32 len; + int32 i; + + gps_errno = INPUT_ERROR; + + p=s; + if(!(p=strchr(p,':'))) + return gps_errno; + ++p; + while(*p && (*p==' ' || *p=='\t')) ++p; + if(!*p) + return 0; + + len = strlen(p); + q = p+len-1; + while(*q==' ' || *q=='\t') --q; + len = q-p+1; + + if(q-p+1 > n) + { + len = n; + p[n]='\0'; + } + for(i=0;isvid = i; + (*alm)[i]->wn = -1; + } + } + else + { + if(!(*alm = (GPS_PAlmanac *) malloc(n*sizeof(GPS_PAlmanac *)))) + return MEMORY_ERROR; + for(i=0;i<32;++i) + if(!((*alm)[i] = GPS_Almanac_New())) + return MEMORY_ERROR; + } + + for(i=0;isvid!=d) ++i; + (*alm)[i]->svid=d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*alm)[i]->wn = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%f",&f)!=1) + return gps_errno; + (*alm)[i]->toa = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%f",&f)!=1) + return gps_errno; + (*alm)[i]->af0 = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%f",&f)!=1) + return gps_errno; + (*alm)[i]->af1 = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%f",&f)!=1) + return gps_errno; + (*alm)[i]->e = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%f",&f)!=1) + return gps_errno; + (*alm)[i]->sqrta = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%f",&f)!=1) + return gps_errno; + (*alm)[i]->m0 = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%f",&f)!=1) + return gps_errno; + (*alm)[i]->w = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%f",&f)!=1) + return gps_errno; + (*alm)[i]->omg0 = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%f",&f)!=1) + return gps_errno; + (*alm)[i]->odot = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%f",&f)!=1) + return gps_errno; + (*alm)[i]->i = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*alm)[i]->hlth=d; + } + + if(!type) + n = 32; + + return n; +} + + + +/* @func GPS_Input_Get_Waypoint ***************************************** +** +** Construct a waypoint array from a file +** +** @param [w] way [GPS_PWay **] pointer to waypoint array +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ + +int32 GPS_Input_Get_Waypoint(GPS_PWay **way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 i; + long pos; + int32 ret; + + gps_errno = INPUT_ERROR; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) + return gps_errno; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(strncmp(s,"Start",5)) + return gps_errno; + + pos = ftell(inf); + n = 0; + while(strncmp(s,"End",3)) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(strstr(s,"Latitude")) + ++n; + } + fseek(inf,pos,0); + + if(!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) + return MEMORY_ERROR; + for(i=0;iprot = type; + } + + + for(i=0;iprot = type; + } + + for(i=0;idst = f; + } + + return n; +} + + + +/* @funcstatic GPS_Input_Get_D100 ************************************ +** +** Get a D100 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D100(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + + double f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->ident,6,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cmnt,40,s); + + return 1; +} + + + +/* @funcstatic GPS_Input_Get_D101 ************************************ +** +** Get a D101 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D101(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->ident,6,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cmnt,40,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->smbl = d; + + return 1; +} + + + +/* @funcstatic GPS_Input_Get_D102 ************************************ +** +** Get a D102 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D102(GPS_PWay *way, FILE *inf) +{ + return GPS_Input_Get_D101(way,inf); +} + + + +/* @funcstatic GPS_Input_Get_D103 ************************************ +** +** Get a D103 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D103(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->ident,6,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cmnt,40,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->smbl = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->dspl = d; + + return 1; +} + + + +/* @funcstatic GPS_Input_Get_D104 ************************************ +** +** Get a D104 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D104(GPS_PWay *way, FILE *inf) +{ + return GPS_Input_Get_D103(way,inf); +} + + + +/* @funcstatic GPS_Input_Get_D105 ************************************ +** +** Get a D105 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D105(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->smbl = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->wpt_ident,s); + + return 1; +} + + + +/* @funcstatic GPS_Input_Get_D106 ************************************ +** +** Get a D106 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D106(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->wpt_class = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((char *)(*way)->subclass,13,s); + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->ident,6,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->smbl = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->wpt_ident,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->lnk_ident,s); + + return 1; +} + + + +/* @funcstatic GPS_Input_Get_D107 ************************************ +** +** Get a D107 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D107(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + + int32 d; + int32 ret; + + if((ret=GPS_Input_Get_D103(way,inf))<0) + return ret; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->colour = d; + + return 1; +} + + + +/* @funcstatic GPS_Input_Get_D108 ************************************ +** +** Get a D108 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D108(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + double f; + int32 d; + int32 xc; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->ident,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->colour = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->dspl = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->smbl = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->alt = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->dpth = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->state,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cc,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->wpt_class = d; + xc = d; + + if(xc>=0x80 && xc<=0x85) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((char *)(*way)->subclass,18,s); + } + else + { + GPS_Util_Put_Short((*way)->subclass,0); + GPS_Util_Put_Int((*way)->subclass+2,0); + GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff); + } + + if(!xc) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->cmnt,s); + } + + if(xc>=0x40 && xc<=0x46) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->facility,s); + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->city,s); + } + + if(xc==0x83) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->addr,s); + } + + if(xc==0x82) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->cross_road,s); + } + + return 1; +} + + + +/* @funcstatic GPS_Input_Get_D109 ************************************ +** +** Get a D109 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +** D109's and D110's are so similar, we handle both with the same function. +************************************************************************/ +static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf, int protonum) +{ + char s[GPS_ARB_LEN]; + char *p; + double f; + int32 d; + int32 xc; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->ident,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->colour = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->dspl = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->smbl = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->alt = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->dpth = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->state,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cc,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->wpt_class = d; + xc = d; + + if(xc>=0x80 && xc<=0x85) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((char *)(*way)->subclass,18,s); + } + else + { + GPS_Util_Put_Short((*way)->subclass,0); + GPS_Util_Put_Int((*way)->subclass+2,0); + GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff); + } + + if(!xc) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->cmnt,s); + } + + if(xc>=0x40 && xc<=0x46) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->facility,s); + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->city,s); + } + + if(xc==0x83) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->addr,s); + } + + if(xc==0x82) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)->cross_road,s); + } + + return 1; +} + + +/* @funcstatic GPS_Input_Get_D150 ************************************ +** +** Get a D150 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D150(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + int32 cl=0; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->ident,6,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cmnt,40,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->wpt_class = cl = d; + + if(cl != 4) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cc,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->city,24,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->state,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->name,30,s); + } + + if(!cl) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->alt = d; + } + + return 1; +} + + + +/* @funcstatic GPS_Input_Get_D151 ************************************ +** +** Get a D151 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D151(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + int32 cl=0; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->ident,6,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cmnt,40,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->wpt_class = cl = d; + + if(cl != 2) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cc,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->city,24,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->state,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->name,30,s); + } + + if(!cl) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->alt = d; + } + + return 1; +} + + +/* @funcstatic GPS_Input_Get_D152 ************************************ +** +** Get a D152 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D152(GPS_PWay *way, FILE *inf) +{ + return GPS_Input_Get_D150(way,inf); +} + + + +/* @funcstatic GPS_Input_Get_D154 ************************************ +** +** Get a D154 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D154(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + int32 cl=0; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->ident,6,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cmnt,40,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->smbl = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->wpt_class = cl = d; + + if(cl != 4 && cl != 8) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cc,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->city,24,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->state,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->name,30,s); + } + + if(!cl) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->alt = d; + } + + return 1; +} + + + +/* @funcstatic GPS_Input_Get_D155 ************************************ +** +** Get a D155 Entry +** +** @param [w] way [GPS_PWay *] pointer to waypoint entry +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ +static int32 GPS_Input_Get_D155(GPS_PWay *way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + int32 cl=0; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->ident,6,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*way)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cmnt,40,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->smbl = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->dspl = d; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->wpt_class = cl = d; + + if(cl != 4 && cl != 8) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->cc,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->city,24,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->state,2,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)->name,30,s); + } + + if(!cl) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_errno; + (*way)->alt = d; + } + + return 1; +} + + + +/* @func GPS_Input_Get_Track ******************************************* +** +** Construct a travk array from a file +** +** @param [w] trk [GPS_PTrack **] pointer to track array +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ + +int32 GPS_Input_Get_Track(GPS_PTrack **trk, FILE *inf) +{ + char s[GPS_ARB_LEN]; + int32 n; + int32 i; + long pos; + int32 a; + int32 d; + + gps_errno = INPUT_ERROR; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(strncmp(s,"Track log",9)) + return gps_errno; + + if(sscanf(s,"Track log %d%d",(int *)&a,(int *)&d)!=2) + return INPUT_ERROR; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(strncmp(s,"Start",5)) + return gps_errno; + + pos = ftell(inf); + n = 0; + while(strncmp(s,"End",3)) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(strstr(s,"Latitude")) + ++n; + if(strstr(s,"Header")) + ++n; + } + fseek(inf,pos,0); + + + if(!(*trk=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack *)))) + return MEMORY_ERROR; + for(i=0;itnew=1; + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + } + else + (*trk)[i]->tnew=0; + + switch(d) + { + case pD300: + GPS_Input_Get_D300(&((*trk)[i]),inf,s); + break; + case pD301: + GPS_Input_Get_D301(&((*trk)[i]),inf,s); + break; + default: + return PROTOCOL_ERROR; + } + } + + return n; +} + + + +/* @funcstatic GPS_Input_Get_Track301 ********************************** +** +** Construct a travk array from a file +** +** @param [w] trk [GPS_PTrack **] pointer to track array +** @param [r] inf [FILE *] stream +** @param [r] type [int32] data type +** @param [r] n [int32] number of tracks +** +** @return [int32] number of entries +************************************************************************/ + +static int32 GPS_Input_Get_Track301(GPS_PTrack **trk, FILE *inf, int32 type, + int32 n) +{ + char s[GPS_ARB_LEN]; + int32 i; + char *p; + int32 x; + + for(i=0;iishdr = 1; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*trk)[i]->trk_ident,s); + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&x)!=1) + return INPUT_ERROR; + (*trk)[i]->dspl = x; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&x)!=1) + return INPUT_ERROR; + (*trk)[i]->colour = x; + + continue; + } + + (*trk)[i]->ishdr = 0; + + if(!strcmp(s,"New track")) + { + (*trk)[i]->tnew=1; + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + } + else + (*trk)[i]->tnew=0; + + switch(type) + { + case pD300: + GPS_Input_Get_D300(&((*trk)[i]),inf,s); + break; + case pD301: + GPS_Input_Get_D301(&((*trk)[i]),inf,s); + break; + default: + return PROTOCOL_ERROR; + } + } + + return n; +} + + + +/* @funcstatic GPS_Input_Get_D300 ********************************** +** +** Construct a track from a file +** +** @param [w] trk [GPS_PTrack *] pointer to track +** @param [r] inf [FILE *] stream +** @param [w] s [char *] input line +** +** @return [int32] number of entries +************************************************************************/ + +static int32 GPS_Input_Get_D300(GPS_PTrack *trk, FILE *inf, char *s) +{ + char *p; + double f; + + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*trk)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*trk)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + (*trk)->Time = 0; + + return 1; +} + + + +/* @funcstatic GPS_Input_Get_D301 ********************************** +** +** Construct a track from a file +** +** @param [w] trk [GPS_PTrack *] pointer to track +** @param [r] inf [FILE *] stream +** @param [w] s [char *] input line +** +** @return [int32] number of entries +************************************************************************/ + +static int32 GPS_Input_Get_D301(GPS_PTrack *trk, FILE *inf, char *s) +{ + char *p; + double f; + + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*trk)->lat = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*trk)->lon = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + (*trk)->Time = 0; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*trk)->alt = f; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + p=strchr(s,':'); + if(sscanf(p+1,"%lf",&f)!=1) + return gps_errno; + (*trk)->dpth = f; + + return 1; +} + + + +/* @func GPS_Input_Get_Route ******************************************* +** +** Construct a route array from a file +** +** @param [w] way [GPS_PWay **] pointer to waypoint array +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ + +int32 GPS_Input_Get_Route(GPS_PWay **way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 rtype=0; + int32 atype=0; + int32 i; + long pos; + int32 ret; + char *p; + int32 d; + + gps_errno = INPUT_ERROR; + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(sscanf(s,"Route log %d",(int *)&atype)!=1) + return gps_errno; + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + + switch(atype) + { + case pA200: + break; + case pA201: + return GPS_Input_Get_Route201(way,inf); + default: + GPS_Error("GPS_Input_Get_Route: Unknown protocol"); + return PROTOCOL_ERROR; + } + + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(sscanf(s,"Route Type: %d",(int *)&rtype)!=1) + return gps_errno; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) + return gps_errno; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(strncmp(s,"Start",5)) + return gps_errno; + + pos = ftell(inf); + n = 1; + while(strncmp(s,"End",3)) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(strstr(s,"Latitude") || strstr(s,"Route")) + ++n; + } + fseek(inf,0L,0); + + + if(!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) + return MEMORY_ERROR; + for(i=0;iprot = type; + } + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + + for(i=0;irte_prot = rtype; + (*way)[i]->islink = 0; + if(strstr(s,"Route")) + { + (*way)[i]->isrte = 1; + switch(rtype) + { + case 200: + p = strchr(s,':'); + p = strchr(p+1,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_error; + (*way)[i]->rte_num=d; + break; + case 201: + p = strchr(s,':'); + p = strchr(p+1,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_error; + (*way)[i]->rte_num=d; + ++p; + GPS_Input_Load_String((*way)[i]->rte_cmnt,20,p+2); + break; + case 202: + p = strchr(s,':'); + p = strchr(p+1,':'); + GPS_Input_Load_Strnull((*way)[i]->rte_ident,p+1); + break; + } + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + continue; + } + else + (*way)[i]->isrte=0; + + if(strstr(s,"End")) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + + continue; + } + + + switch(type) + { + case 100: + ret = GPS_Input_Get_D100(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 101: + ret = GPS_Input_Get_D101(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 102: + ret = GPS_Input_Get_D102(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 103: + ret = GPS_Input_Get_D103(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 104: + ret = GPS_Input_Get_D104(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 105: + ret = GPS_Input_Get_D105(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 106: + ret = GPS_Input_Get_D106(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 107: + ret = GPS_Input_Get_D107(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 108: + ret = GPS_Input_Get_D108(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 150: + ret = GPS_Input_Get_D150(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 151: + ret = GPS_Input_Get_D151(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 152: + ret = GPS_Input_Get_D152(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 154: + ret = GPS_Input_Get_D154(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 155: + ret = GPS_Input_Get_D155(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + default: + GPS_Error("Input_Get_Waypoints: Unknown protocol"); + return PROTOCOL_ERROR; + } + + } + + return n; +} + + + +/* @funcstatic GPS_Input_Get_Route201 *********************************** +** +** Construct a route array from a file +** +** @param [w] way [GPS_PWay **] pointer to waypoint array +** @param [r] inf [FILE *] stream +** +** @return [int32] number of entries +************************************************************************/ + +static int32 GPS_Input_Get_Route201(GPS_PWay **way, FILE *inf) +{ + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 rtype; + int32 i; + long pos; + int32 ret; + char *p; + int32 d; + + gps_errno = INPUT_ERROR; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(sscanf(s,"Route Type: %d",(int *)&rtype)!=1) + return gps_errno; + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) + return gps_errno; + + + pos = ftell(inf); + n = 1; + while(strncmp(s,"End",3)) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(strstr(s,"Latitude") || strstr(s,"Route") || strstr(s,"Link Class")) + ++n; + } + fseek(inf,0L,0); + + if(!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) + return MEMORY_ERROR; + for(i=0;iprot = type; + } + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + + for(i=0;irte_prot = rtype; + (*way)[i]->islink = 0; + if(strstr(s,"Route")) + { + (*way)[i]->isrte = 1; + switch(rtype) + { + case 200: + p = strchr(s,':'); + p = strchr(p+1,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_error; + (*way)[i]->rte_num=d; + break; + case 201: + p = strchr(s,':'); + p = strchr(p+1,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_error; + (*way)[i]->rte_num=d; + p = strchr(p+1,':'); + GPS_Input_Load_String((*way)[i]->rte_cmnt,20,p+1); + break; + case 202: + p = strchr(s,':'); + p = strchr(p+1,':'); + GPS_Input_Load_Strnull((*way)[i]->rte_ident,p+1); + break; + } + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + continue; + } + else + (*way)[i]->isrte=0; + + + + if(strstr(s,"Link Class")) + { + (*way)[i]->islink = 1; + + p = strchr(s,':'); + if(sscanf(p+1,"%d",(int *)&d)!=1) + return gps_error; + (*way)[i]->rte_link_class=d; + + if(!((*way)[i]->rte_link_class==3 || (*way)[i]->rte_link_class + ==0xff)) + { + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_String((*way)[i]->rte_link_subclass,18,s); + } + else + { + GPS_Util_Put_Short((UC *)(*way)[i]->rte_link_subclass,0); + GPS_Util_Put_Int((UC *)(*way)[i]->rte_link_subclass+2,0); + GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+6, + 0xffffffff); + GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+10, + 0xffffffff); + GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+14, + 0xffffffff); + } + + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + GPS_Input_Load_Strnull((*way)[i]->rte_link_ident,s); + + continue; + } + else + (*way)[i]->islink=0; + + + if(strstr(s,"End")) + { + GPS_Error("Get_Route201: Unexpected End"); + return INPUT_ERROR; + } + + + switch(type) + { + case 100: + ret = GPS_Input_Get_D100(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 101: + ret = GPS_Input_Get_D101(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 102: + ret = GPS_Input_Get_D102(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 103: + ret = GPS_Input_Get_D103(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 104: + ret = GPS_Input_Get_D104(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 105: + ret = GPS_Input_Get_D105(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 106: + ret = GPS_Input_Get_D106(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 107: + ret = GPS_Input_Get_D107(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 108: + ret = GPS_Input_Get_D108(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 150: + ret = GPS_Input_Get_D150(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 151: + ret = GPS_Input_Get_D151(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 152: + ret = GPS_Input_Get_D152(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 154: + ret = GPS_Input_Get_D154(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + case 155: + ret = GPS_Input_Get_D155(&((*way)[i]),inf); + if(ret<0) return gps_errno; + break; + default: + GPS_Error("Input_Get_Waypoints: Unknown protocol"); + return PROTOCOL_ERROR; + } + if(!GPS_Input_Read_Line(s,inf)) + return gps_errno; + } + + return n; +} diff --git a/jeeps/gpsinput.h b/jeeps/gpsinput.h new file mode 100644 index 000000000..5b0e41615 --- /dev/null +++ b/jeeps/gpsinput.h @@ -0,0 +1,23 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsinput_h +#define gpsinput_h + + +#include "gps.h" + +int32 GPS_Input_Get_Almanac(GPS_PAlmanac **alm, FILE *inf); +int32 GPS_Input_Get_Waypoint(GPS_PWay **way, FILE *inf); +int32 GPS_Input_Get_Proximity(GPS_PWay **way, FILE *inf); +int32 GPS_Input_Get_Track(GPS_PTrack **trk, FILE *inf); +int32 GPS_Input_Get_Route(GPS_PWay **way, FILE *inf); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpslibusb.c b/jeeps/gpslibusb.c new file mode 100644 index 000000000..efc84db73 --- /dev/null +++ b/jeeps/gpslibusb.c @@ -0,0 +1,358 @@ +/* + Physical/OS USB layer to talk to libusb. + + Copyright (C) 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +#include +#include +#include "config.h" +#if HAVE_LIBUSB +#include +#include "gps.h" +#include "garminusb.h" +#include "gpsusbcommon.h" + +#define GARMIN_VID 0x91e + +/* This is very sensitive to timing; libusb and/or the unit is kind of + * sloppy about not obeying packet boundries. If this is too high, the + * multiple packets responding to the device inquriy will be glommed into + * one packet and we'll misparse them. If it's too low, we'll get partially + * satisfied reads. It turns out this isn't terrible becuase we still end + * up with DLE boundings and the upper layers (which are used to doing frame + * coalescion into packets anyway becuase of their serial background) will + * compensate. + */ +#define TMOUT_I 3000 /* Milliseconds to timeout intr pipe access. */ +#define TMOUT_B 3000 /* Milliseconds to timeout bulk pipe access. */ + +typedef struct { + struct usb_bus *busses; +} libusb_unit_data; + +/* + * TODO: this should all be moved into libusbdata in gpslibusb.h, + * allocated once here in gusb_start, and deallocated at the end. + */ +static int gusb_intr_in_ep; +static int gusb_bulk_out_ep; +static int gusb_bulk_in_ep; +static gusb_llops_t libusb_llops; + +static usb_dev_handle *udev; +static void garmin_usb_scan(libusb_unit_data *, int); + +static int +gusb_libusb_send(const garmin_usb_packet *opkt, size_t sz) +{ + int r; + r = usb_bulk_write(udev, gusb_bulk_out_ep, (char *)(void *)opkt->dbuf, sz, TMOUT_B); + + if (r != (int) sz) { + fprintf(stderr, "Bad cmdsend r %d sz %ld\n", r, (unsigned long) sz); + if (r < 0) { + fatal("usb_bulk_write failed. '%s'\n", + usb_strerror()); + } + } + + return r; +} + +static int +gusb_libusb_get(garmin_usb_packet *ibuf, size_t sz) +{ + unsigned char *buf = &ibuf->dbuf[0]; + int r = -1; + + r = usb_interrupt_read(udev, gusb_intr_in_ep, (char *) buf, sz, TMOUT_I); + return r; +} + +static int +gusb_libusb_get_bulk(garmin_usb_packet *ibuf, size_t sz) +{ + int r; + unsigned char *buf = &ibuf->dbuf[0]; + + r = usb_bulk_read(udev, gusb_bulk_in_ep, (char *) buf, sz, TMOUT_B); + + return r; +} + + +static int +gusb_teardown(gpsdevh *dh) +{ + if (udev) { + usb_release_interface(udev, 0); + usb_close(udev); + /* In the worst case, we leak a little bit of memory + * when called via the atexit handler. That's not too + * terrible. + */ + if (NULL != dh) { + xfree(dh); + } + udev = NULL; + } + return 0; +} + +static void +gusb_atexit_teardown(void) +{ + gusb_teardown(NULL); +} + + +/* + * This is a function of great joy to discover. + * + * It turns out that as of 5/2006, every Garmin USB product has a problem + * where the device does not reset the data toggles after a configuration + * set. After a reset, the toggles both match. So we tear through the + * conversation and life is good. Unfortunately, the second time through, + * if we had an odd number of transactions in the previous conversation, + * we send a configuration set and reset the toggle on the HCI but the + * toggle on the device's end of the pipe is now out of whack which means + * that the subsequent transaction will hang. + * + * This isn't a problem in Windows since the configuration set is done only + * once there. + * + * This code has been tested in loops of 1000 cycles on Linux and OS/X and + * it seems to cure this at a mere cost of complexity and startup time. I'll + * be delighted when all the firmware gets revved and updated and we can + * remove this. + * + */ +static void +gusb_reset_toggles(void) +{ + static const char oinit[12] = + {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; + static const char oid[12] = + {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int t; + + /* Start off with three session starts. + * #1 resets the bulk out toggle. It may not make it to the device. + * #2 resets the the intr in toggle. It will make it to the device + * since #1 reset the the bulk out toggle. The device will + * respond on the intr in pipe which will clear its toggle. + * #3 actually starts the session now that the above are both clear. + */ + + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + + t = 10; + while(1) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_get(&iresp, sizeof(iresp)); + + if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && + (le_read32(iresp.gusb_pkt.datasz) == 4)) { + break; + } + if (t-- <= 0) { + fatal("Could not start session in a reasonable number of tries.\n"); + } + } + + /* + * Now that the bulk out and intr in packets are good, we send + * a product ID. On devices that respond totally on the intr + * pipe, this does nothing interesting, but on devices that respon + * on the bulk pipe this will reset the toggles on the bulk in. + */ + t = 10; + gusb_cmd_send((const garmin_usb_packet *) oid, sizeof(oid)); + while(1) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_get(&iresp, sizeof(iresp)); + + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) return; + if (t-- <= 0) { + fatal("Could not start session in a reasonable number of tries.\n"); + } + } +} + +void +garmin_usb_start(struct usb_device *dev) +{ + int i; + + if (udev) return; + + udev = usb_open(dev); + atexit(gusb_atexit_teardown); + + if (!udev) { fatal("usb_open failed: %s\n", usb_strerror()); } + /* + * Hrmph. No iManufacturer or iProduct headers.... + */ + if (usb_set_configuration(udev, 1) < 0) { +#if __linux__ + char drvnm[128]; + drvnm[0] = 0; + /* + * Most Linux distributions ship a slightly broken + * kernel driver that bonds with the hardware. + */ + usb_get_driver_np(udev, 0, drvnm, sizeof(drvnm)-1); + fatal("usb_set_configuration failed, probably because kernel driver '%s'\n is blocking our access to the USB device.\n" + "For more information see http://www.gpsbabel.org/os/Linux_Hotplug.html\n", drvnm); +#else + + fatal("usb_set_configuration failed: %s\n", usb_strerror()); +#endif + } + + if (usb_claim_interface(udev, 0) < 0) { + fatal("Claim interfaced failed: %s\n", usb_strerror()); + } + + libusb_llops.max_tx_size = dev->descriptor.bMaxPacketSize0; + + for (i = 0; i < dev->config->interface->altsetting->bNumEndpoints; i++) { + struct usb_endpoint_descriptor * ep; + ep = &dev->config->interface->altsetting->endpoint[i]; + + switch (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) { +#define EA(x) x & USB_ENDPOINT_ADDRESS_MASK + case USB_ENDPOINT_TYPE_BULK: + if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + gusb_bulk_in_ep = EA(ep->bEndpointAddress); + else + gusb_bulk_out_ep = EA(ep->bEndpointAddress); + break; + case USB_ENDPOINT_TYPE_INTERRUPT: + if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + gusb_intr_in_ep = EA(ep->bEndpointAddress); + break; + } + } + + /* + * Zero is the configuration endpoint, so if we made it through + * that loop without non-zero values for all three, we're hosed. + */ + if (gusb_intr_in_ep && gusb_bulk_in_ep && gusb_bulk_out_ep) { + gusb_reset_toggles(); + gusb_syncup(); + return; + } + + fatal("Could not identify endpoints on USB device.\n" + "Found endpoints Intr In 0x%x Bulk Out 0x%x Bulk In %0xx\n", + gusb_intr_in_ep, gusb_bulk_out_ep, gusb_bulk_in_ep); +} + +static +void garmin_usb_scan(libusb_unit_data *lud, int req_unit_number) +{ + int found_devices = 0; + struct usb_bus *bus; + + for (bus = lud->busses; bus; bus = bus->next) { + struct usb_device *dev; + + for (dev = bus->devices; dev; dev = dev->next) { + /* Probably too promiscious of a match, but since + * Garmin doesn't document the _proper_ matching, + * we just take the easy way out for now. + */ + if (dev->descriptor.idVendor == GARMIN_VID) { + /* Nuvi */ + if (dev->descriptor.idProduct == 0x19) + continue; + if (req_unit_number < 0) { + garmin_usb_start(dev); + /* + * It's important to call _close + * here since the bulk/intr models + * may have a "dangling" packet that + * needs to be drained. + */ + gusb_close(NULL); + } else + if (req_unit_number == found_devices) + garmin_usb_start(dev); + found_devices++; + } + } + } + + if (req_unit_number < 0) { + gusb_list_units(); + exit (0); + } + if (0 == found_devices) { + fatal("Found no Garmin USB devices.\n"); + } +} + +static gusb_llops_t libusb_llops = { + gusb_libusb_get, + gusb_libusb_get_bulk, + gusb_libusb_send, + gusb_teardown +}; + +int +gusb_init(const char *portname, gpsdevh **dh) +{ + int req_unit_number = 0; + libusb_unit_data *lud = xcalloc(sizeof (libusb_unit_data), 1); + *dh = (gpsdevh*) lud; + +// usb_set_debug(99); + usb_init(); + gusb_register_ll(&libusb_llops); + + /* if "usb:N", read "N" to be the unit number. */ + if (strlen(portname) > 4) { + if (0 == strcmp(portname+4, "list")) { + req_unit_number = -1; + } else { + req_unit_number = atoi(portname + 4); + } + } + + usb_find_busses(); + usb_find_devices(); + lud->busses = usb_get_busses(); + garmin_usb_scan(lud, req_unit_number); + + return 1; +} + +#endif /* HAVE_LIBUSB */ diff --git a/jeeps/gpsmath.c b/jeeps/gpsmath.c new file mode 100644 index 000000000..a8d40d927 --- /dev/null +++ b/jeeps/gpsmath.c @@ -0,0 +1,2251 @@ +/******************************************************************** +** @source JEEPS arithmetic/conversion functions +** +** @author Copyright (C) 1999 Alan Bleasby +** @version 1.0 +** @modified Dec 28 1999 Alan Bleasby. First version +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include +#include +#include +#include "gpsdatum.h" + + +static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32 *zone, + char *zc, double *Mc, double *E0, + double *N0, double *F0); +static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double *Mc, + double *E0, double *N0, double *F0); + + + +/* @func GPS_Math_Deg_To_Rad ******************************************* +** +** Convert degrees to radians +** +** @param [r] v [double] degrees +** +** @return [double] radians +************************************************************************/ + +double GPS_Math_Deg_To_Rad(double v) +{ + return v*(double)((double)GPS_PI/(double)180.); +} + + + +/* @func GPS_Math_Rad_To_Deg ******************************************* +** +** Convert radians to degrees +** +** @param [r] v [double] radians +** +** @return [double] degrees +************************************************************************/ + +double GPS_Math_Rad_To_Deg(double v) +{ + return v*(double)((double)180./(double)GPS_PI); +} + + + +/* @func GPS_Math_Deg_To_DegMin ***************************************** +** +** Convert degrees to degrees and minutes +** +** @param [r] v [double] degrees +** @param [w] d [int32 *] whole degrees +** @param [w] m [double *] minutes +** +** @return [void] +************************************************************************/ + +void GPS_Math_Deg_To_DegMin(double v, int32 *d, double *m) +{ + int32 sign; + + if(v<(double)0.) + { + v *= (double)-1.; + sign = 1; + } + else + sign = 0; + + *d = (int32)v; + *m = (v-(double)*d) * (double)60.0; + if(*m>(double)59.999) + { + ++*d; + *m = (double)0.0; + } + + if(sign) + *d = -*d; + + return; +} + + + +/* @func GPS_Math_DegMin_To_Deg ***************************************** +** +** Convert degrees and minutes to degrees +** +** @param [r] d [int32] whole degrees +** @param [r] m [double] minutes +** @param [w] deg [double *] degrees +** +** @return [void] +************************************************************************/ + +void GPS_Math_DegMin_To_Deg(int32 d, double m, double *deg) +{ + + *deg = ((double)abs(d)) + m / (double)60.0; + if(d<0) + *deg = -*deg; + + return; +} + + + +/* @func GPS_Math_Deg_To_DegMinSec ************************************* +** +** Convert degrees to degrees, minutes and seconds +** +** @param [r] v [double] degrees +** @param [w] d [int32 *] whole degrees +** @param [w] m [int32 *] whole minutes +** @param [w] s [double *] seconds +** +** @return [void] +************************************************************************/ + +void GPS_Math_Deg_To_DegMinSec(double v, int32 *d, int32 *m, double *s) +{ + int32 sign; + double t; + + if(v<(double)0.) + { + v *= (double)-1.; + sign = 1; + } + else + sign = 0; + + *d = (int32)v; + t = (v -(double)*d) * (double)60.0; + *m = (v-(double)*d) * (double)60.0; + *s = (t - (int32)t) * (double)60.0; + + if(*s>(double)59.999) + { + ++t; + *s = (double)0.0; + } + + + if(t>(double)59.999) + { + ++*d; + t = 0; + } + + *m = (int32)t; + + if(sign) + *d = -*d; + + return; +} + + + +/* @func GPS_Math_DegMinSec_To_Deg ***************************************** +** +** Convert degrees, minutes and seconds to degrees +** +** @param [r] d [int32] whole degrees +** @param [r] m [int32] whole minutes +** @param [r] s [double] seconds +** @param [w] deg [double *] degrees +** +** @return [void] +************************************************************************/ + +void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg) +{ + + *deg = ((double)abs(d)) + ((double)m + s / (double)60.0) / (double)60.0; + if(d<0) + *deg = -*deg; + + return; +} + + + +/* @func GPS_Math_Metres_To_Feet ******************************************* +** +** Convert metres to feet +** +** @param [r] v [double] metres +** +** @return [double] feet +************************************************************************/ + +double GPS_Math_Metres_To_Feet(double v) +{ + return v/0.3048; +} + + + +/* @func GPS_Math_Feet_To_Metres ******************************************* +** +** Convert feet to metres +** +** @param [r] v [double] feet +** +** @return [double] metres +************************************************************************/ + +double GPS_Math_Feet_To_Metres(double v) +{ + return v * 0.3048; +} + + + +/* @func GPS_Math_Deg_To_Semi ******************************************* +** +** Convert degrees to semi-circles +** +** @param [r] v [double] degrees +** +** @return [int32] semicircles +************************************************************************/ + +int32 GPS_Math_Deg_To_Semi(double v) +{ + return ( (double)(1U<<31) / (double)180) * v; +} + + + +/* @func GPS_Math_Semi_To_Deg ******************************************* +** +** Convert semi-circles to degrees +** +** @param [r] v [int32] semi-circles +** +** @return [double] degrees +************************************************************************/ + +double GPS_Math_Semi_To_Deg(int32 v) +{ + return (double) (((double)v / (double)(1U<<31)) * (double)180); +} + + + +/* @func GPS_Math_Utime_To_Gtime ******************************************* +** +** Convert Unix time (1970) to GPS time (1990) +** +** @param [r] v [time_t] Unix time +** +** @return [time_t] GPS time +************************************************************************/ + +time_t GPS_Math_Utime_To_Gtime(time_t v) +{ + return v-631065600; +} + + + +/* @func GPS_Math_Gtime_To_Utime ******************************************* +** +** Convert GPS time (1990) to Unix time (1970) +** +** @param [r] v [time_t] GPS time +** +** @return [time_t] Unix time +************************************************************************/ + +time_t GPS_Math_Gtime_To_Utime(time_t v) +{ + return v+631065600; +} + + + + +/* @func GPS_Math_LatLonH_To_XYZ ********************************** +** +** Convert latitude and longitude and ellipsoidal height to +** X, Y & Z coordinates +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [r] H [double] ellipsoidal height (metres) +** @param [w] x [double *] X +** @param [w] y [double *] Y +** @param [w] z [double *] Z +** @param [r] a [double] semi-major axis (metres) +** @param [r] b [double] semi-minor axis (metres) +** +** @return [void] +************************************************************************/ +void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H, + double *x, double *y, double *z, + double a, double b) +{ + double esq; + double nu; + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + + + esq = ((a*a)-(b*b)) / (a*a); + + nu = a / pow(((double)1.0-esq*sin(phi)*sin(phi)),(double)0.5); + *x = (nu+H) * cos(phi) * cos(lambda); + *y = (nu+H) * cos(phi) * sin(lambda); + *z = (((double)1.0-esq)*nu+H) * sin(phi); + + return; +} + + + + +/* @func GPS_Math_XYX_To_LatLonH *************************************** +** +** Convert XYZ coordinates to latitude and longitude and ellipsoidal height +** +** @param [w] phi [double] latitude (deg) +** @param [w] lambda [double] longitude (deg) +** @param [w] H [double] ellipsoidal height (metres) +** @param [r] x [double *] X +** @param [r] y [double *] Y +** @param [r] z [double *] Z +** @param [r] a [double] semi-major axis (metres) +** @param [r] b [double] semi-minor axis (metres) +** +** @return [void] +************************************************************************/ +void GPS_Math_XYZ_To_LatLonH(double *phi, double *lambda, double *H, + double x, double y, double z, + double a, double b) +{ + double esq; + double nu=0.0; + double phix; + double nphi; + double rho; + int32 t1=0; + int32 t2=0; + + if(x<(double)0 && y>=(double)0) t1=1; + if(x<(double)0 && y<(double)0) t2=1; + + rho = pow(((x*x)+(y*y)),(double)0.5); + esq = ((a*a)-(b*b)) / (a*a); + phix = atan(z/(((double)1.0 - esq) * rho)); + nphi = (double)1e20; + + while(fabs(phix-nphi)>(double)0.00000000001) + { + nphi = phix; + nu = a / pow(((double)1.0-esq*sin(nphi)*sin(nphi)),(double)0.5); + phix = atan((z+esq*nu*sin(nphi))/rho); + } + + *phi = GPS_Math_Rad_To_Deg(phix); + *H = (rho / cos(phix)) - nu; + *lambda = GPS_Math_Rad_To_Deg(atan(y/x)); + + if(t1) *lambda += (double)180.0; + if(t2) *lambda -= (double)180.0; + + return; +} + + + +/* @func GPS_Math_Airy1830LatLonH_To_XYZ ********************************** +** +** Convert Airy 1830 latitude and longitude and ellipsoidal height to +** X, Y & Z coordinates +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [r] H [double] ellipsoidal height (metres) +** @param [w] x [double *] X +** @param [w] y [double *] Y +** @param [w] z [double *] Z +** +** @return [void] +************************************************************************/ +void GPS_Math_Airy1830LatLonH_To_XYZ(double phi, double lambda, double H, + double *x, double *y, double *z) +{ + double a = 6377563.396; + double b = 6356256.910; + + GPS_Math_LatLonH_To_XYZ(phi,lambda,H,x,y,z,a,b); + + return; +} + + + +/* @func GPS_Math_WGS84LatLonH_To_XYZ ********************************** +** +** Convert WGS84 latitude and longitude and ellipsoidal height to +** X, Y & Z coordinates +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [r] H [double] ellipsoidal height (metres) +** @param [w] x [double *] X +** @param [w] y [double *] Y +** @param [w] z [double *] Z +** +** @return [void] +************************************************************************/ +void GPS_Math_WGS84LatLonH_To_XYZ(double phi, double lambda, double H, + double *x, double *y, double *z) +{ + double a = 6378137.000; + double b = 6356752.3141; + + GPS_Math_LatLonH_To_XYZ(phi,lambda,H,x,y,z,a,b); + + return; +} + + + + +/* @func GPS_Math_XYZ_To_Airy1830LatLonH ********************************** +** +** Convert XYZ to Airy 1830 latitude and longitude and ellipsoidal height +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [r] H [double] ellipsoidal height (metres) +** @param [w] x [double *] X +** @param [w] y [double *] Y +** @param [w] z [double *] Z +** +** @return [void] +************************************************************************/ +void GPS_Math_XYZ_To_Airy1830LatLonH(double *phi, double *lambda, double *H, + double x, double y, double z) +{ + double a = 6377563.396; + double b = 6356256.910; + + GPS_Math_XYZ_To_LatLonH(phi,lambda,H,x,y,z,a,b); + + return; +} + + + +/* @func GPS_Math_XYZ_To_WGS84LatLonH ********************************** +** +** Convert XYZ to WGS84 latitude and longitude and ellipsoidal height +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [r] H [double] ellipsoidal height (metres) +** @param [w] x [double *] X +** @param [w] y [double *] Y +** @param [w] z [double *] Z +** +** @return [void] +************************************************************************/ +void GPS_Math_XYZ_To_WGS84LatLonH(double *phi, double *lambda, double *H, + double x, double y, double z) +{ + double a = 6378137.000; + double b = 66356752.3141; + + GPS_Math_XYZ_To_LatLonH(phi,lambda,H,x,y,z,a,b); + + return; +} + + +/* @func GPS_Math_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to eastings and northings +** Standard Gauss-Kruger Transverse Mercator +** +** @param [w] E [double *] easting (metres) +** @param [w] N [double *] northing (metres) +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [r] N0 [double] true northing origin (metres) +** @param [r] E0 [double] true easting origin (metres) +** @param [r] phi0 [double] true latitude origin (deg) +** @param [r] lambda0 [double] true longitude origin (deg) +** @param [r] F0 [double] scale factor on central meridian +** @param [r] a [double] semi-major axis (metres) +** @param [r] b [double] semi-minor axis (metres) +** +** @return [void] +************************************************************************/ +void GPS_Math_LatLon_To_EN(double *E, double *N, double phi, + double lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b) +{ + double esq; + double n; + double etasq; + double nu; + double rho; + double M; + double I; + double II; + double III; + double IIIA; + double IV; + double V; + double VI; + + double tmp; + double tmp2; + double fdf; + double fde; + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + + esq = ((a*a)-(b*b)) / (a*a); + n = (a-b) / (a+b); + + tmp = (double)1.0 - (esq * sin(phi) * sin(phi)); + nu = a * F0 * pow(tmp,(double)-0.5); + rho = a * F0 * ((double)1.0 - esq) * pow(tmp,(double)-1.5); + etasq = (nu / rho) - (double)1.0; + + fdf = (double)5.0 / (double)4.0; + tmp = (double)1.0 + n + (fdf * n * n) + (fdf * n * n * n); + tmp *= (phi - phi0); + tmp2 = (double)3.0*n + (double)3.0*n*n + ((double)21./(double)8.)*n*n*n; + tmp2 *= (sin(phi-phi0) * cos(phi+phi0)); + tmp -= tmp2; + + fde = ((double)15.0 / (double)8.0); + tmp2 = ((fde*n*n) + (fde*n*n*n)) * sin((double)2.0 * (phi-phi0)); + tmp2 *= cos((double)2.0 * (phi+phi0)); + tmp += tmp2; + + tmp2 = ((double)35.0/(double)24.0) * n * n * n; + tmp2 *= sin((double)3.0 * (phi-phi0)); + tmp2 *= cos((double)3.0 * (phi+phi0)); + tmp -= tmp2; + + M = b * F0 * tmp; + I = M + N0; + II = (nu / (double)2.0) * sin(phi) * cos(phi); + III = (nu / (double)24.0) * sin(phi) * cos(phi) * cos(phi) * cos(phi); + III *= ((double)5.0 - (tan(phi) * tan(phi)) + ((double)9.0 * etasq)); + IIIA = (nu / (double)720.0) * sin(phi) * pow(cos(phi),(double)5.0); + IIIA *= ((double)61.0 - ((double)58.0*tan(phi)*tan(phi)) + + pow(tan(phi),(double)4.0)); + IV = nu * cos(phi); + + tmp = pow(cos(phi),(double)3.0); + tmp *= ((nu/rho) - tan(phi) * tan(phi)); + V = (nu/(double)6.0) * tmp; + + tmp = (double)5.0 - ((double)18.0 * tan(phi) * tan(phi)); + tmp += tan(phi)*tan(phi)*tan(phi)*tan(phi) + ((double)14.0 * etasq); + tmp -= ((double)58.0 * tan(phi) * tan(phi) * etasq); + tmp2 = cos(phi)*cos(phi)*cos(phi)*cos(phi)*cos(phi) * tmp; + VI = (nu / (double)120.0) * tmp2; + + *N = I + II*(lambda-lambda0)*(lambda-lambda0) + + III*pow((lambda-lambda0),(double)4.0) + + IIIA*pow((lambda-lambda0),(double)6.0); + + *E = E0 + IV*(lambda-lambda0) + V*pow((lambda-lambda0),(double)3.0) + + VI * pow((lambda-lambda0),(double)5.0); + + return; +} + + + +/* @func GPS_Math_Airy1830MLatLonToINGEN ************************************ +** +** Convert Modified Airy 1830 datum latitude and longitude to Irish +** National Grid Eastings and Northings +** +** @param [r] phi [double] modified Airy latitude (deg) +** @param [r] lambda [double] modified Airy longitude (deg) +** @param [w] E [double *] NG easting (metres) +** @param [w] N [double *] NG northing (metres) +** +** @return [void] +************************************************************************/ +void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double *E, + double *N) +{ + double N0 = 250000; + double E0 = 200000; + double F0 = 1.000035; + double phi0 = 53.5; + double lambda0 = -8.; + double a = 6377340.189; + double b = 6356034.447; + + GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; +} + + + + +/* @func GPS_Math_Airy1830LatLonToNGEN ************************************** +** +** Convert Airy 1830 datum latitude and longitude to UK Ordnance Survey +** National Grid Eastings and Northings +** +** @param [r] phi [double] WGS84 latitude (deg) +** @param [r] lambda [double] WGS84 longitude (deg) +** @param [w] E [double *] NG easting (metres) +** @param [w] N [double *] NG northing (metres) +** +** @return [void] +************************************************************************/ +void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double *E, + double *N) +{ + double N0 = -100000; + double E0 = 400000; + double F0 = 0.9996012717; + double phi0 = 49.; + double lambda0 = -2.; + double a = 6377563.396; + double b = 6356256.910; + + GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; +} + + +/* @func GPS_Math_WGS84_To_CH1903_NGEN ********************************* +** +** Convert WGS84 latitude and longitude to +** Swiss CH-1903 National Grid Eastings and Northings +** ( Oblique Mercator Projection ) +** +** @param [r] phi [double] WGS84 latitude (deg) +** @param [r] lambda [double] WGS84 longitude (deg) +** @param [w] E [double *] Swiss-NG easting (metres) +** @param [w] N [double *] Swiss-NG northing (metres) +** +** @return [void] +************************************************************************/ + +int32 GPS_Math_WGS84_To_CH1903_NGEN(double lat, double lon, double *E, + double *N) +{ +#if 1 + double alat, alon, aht; + + GPS_Math_WGS84_To_Known_Datum_M(lat, lon, 0, &alat, &alon, &aht, 123); + return GPS_Math_LatLon_To_OM_EN(alat, alon, E, N, + 46.95240555555556, /* phiC, center of projection */ + 7.439583333333333, /* lambdaC, center of projection */ + 90, /* azimuth true (initial line) */ + 90, /* Angle from Rectified to Skew Grid */ + 1, /* const double kC, */ + 600000, /* false easting */ + 200000, /* false northing */ + GPS_Ellipse[4].a, + GPS_Ellipse[4].invf, + 0, /* const char hotine, */ + 1 /* const char degrees */ ); +#else + + /* short-hand method, only good for swiss area */ + /* reference: http://www.swisstopo.ch/pub/down/basics/geo/system/ch1903_wgs84_en.pdf */ + /* reference: */ + + double phi = ((lat * 3600) - 169028.66) / 10000; + double lambda = ((lon * 3600) - 26782.5) / 10000; + + if ((lat < 0) || (lon < 0)) return 0; + + *E = (double)600072.37 + + ((double)211455.93 * lambda) - + ((double)10938.51 * lambda * phi) - + ((double)0.36 * lambda * (phi * phi)) - + ((double)44.54 * (lambda * lambda * lambda)); + + *N = (double)200147.07 + + ((double)308807.95 * phi) + + ((double)3745.25 * (lambda * lambda)) + + ((double)76.63 * (phi * phi)) - + ((double)194.56 * (lambda * lambda * phi)) + + ((double)119.79 * (phi * phi * phi)); + + return ((*E >= 0) && (*N >=0)) ? 1 : 0; +#endif +} + + +/* @func GPS_Math_CH1903_NGEN_To_WGS84 ********************************* +** +** Convert WGS84 latitude and longitude to +** Swiss CH-1903 National Grid Eastings and Northings +** +** @param [r] E [double] Swiss-NG easting (metres) +** @param [r] N [double] Swiss-NG northing (metres) +** @param [w] lat [double *] WGS84 latitude (deg) +** @param [w] lon [double *] WGS84 longitude (deg) +** +** @return [void] +************************************************************************/ + +void GPS_Math_CH1903_NGEN_To_WGS84(double E, double N, double *lat, double *lon) +{ +#if 0 + double alat, alon, aht; + GPS_Math_OM_EN_To_LatLon(E, N, &alat, &alon, + 46.95240555555556, /* phiC, center of projection */ + 7.439583333333333, /* lambdaC, center of projection */ + 90, /* azimuth true (initial line) */ + 90, /* ??? Angle from Rectified to Skew Grid */ + 1, /* const double kC, */ + 600000, /* false easting */ + 200000, /* false northing */ + GPS_Ellipse[4].a, + GPS_Ellipse[4].invf, + 0, /* const char hotine, */ + 1 /* const char degrees */ ); + GPS_Math_Known_Datum_To_WGS84_M(alat, alon, 0, lat, lon, &aht, 123); +#else + /* short-hand method 1 (only good for swiss area) */ + + double y = (E - 600000) / 1000000; + double x = (N - 200000) / 1000000; + + *lon = (double)2.6779094 + + ((double)4.728982 * y) + + ((double)0.791484 * y * x) + + ((double)0.1306 * y * x * x) - + ((double)0.0436 * y * y * y); + + *lat = (double)16.9023892 + + ((double)3.238272 * x) - + ((double)0.270978 * y * y) - + ((double)0.002528 * x * x) - + ((double)0.0447 * y * y * x) - + ((double)0.0140 * x * x * x); + + *lat *= ((double)100 / 36); + *lon *= ((double)100 / 36); +#endif +} + +#define SIGN(a) (((a) < 0) ? -1 : (((a) > 0) ? +1 : 0)) + +/* @func GPS_Math_LatLon_To_OM_EN ********************************* +** +** Convert latitude and longitude to Oblique Mercator or Hotine Oblique +** Mercator projection easting and northing +** +** status: OKAY +** reference: +** +** @param [r] phi [double] latitude +** @param [r] lambda [double] latitude +** @param [w] E [double *] easting +** @param [w] N [double *] northing +** @param [r] phiC [double] center of projection +** @param [r] lamdaC [double] center of projection +** @param [r] azmC [double] azimuth true (initial line) +** @param [r] gammaC [double] angle from Rectified to Skew Grid +** @param [r] kC [double] skaling factor +** @param [r] FE [double] false easting / E0 for Hotine OM +** @param [r] FN [double] false northing / N0 for Hotine OM +** @param [r] a [double] semi-major axis (meter) +** @param [r] invf [double] flattening (inv.) +** @param [r] hotine [int] use Hotine Hotine Oblique Mercator projection +** @param [r] degrees [int] 1 = parameters in degrees, otherwise radians +** +** @return [int32] result 1 = success +************************************************************************/ + +int32 GPS_Math_LatLon_To_OM_EN( + double phi, double lambda, double *E, double *N, + double phiC, double lambdaC, double azmC, double gammaC, const double kC, + const double FE, const double FN, const double a, const double invf, + const char hotine, const char degrees) +{ + double e, e2, f; + double A, B, t0, D, F, G, H, t, Q, S, T, V, U, v, u; + double lambda0, gamma0, uC; + double cos4, D2; + + /* prepare parameter */ + + if (degrees) { + phi = phi * M_PI / 180.0; + lambda = lambda * M_PI / 180.0; + phiC = phiC * M_PI / 180.0; + lambdaC = lambdaC * M_PI / 180.0; + azmC = azmC * M_PI / 180.0; + gammaC = gammaC * M_PI / 180.0; + } + f = 1 / invf; + e2 = 2 * f - f * f; + e = sqrt(e2); + + cos4 = cos(phiC); + cos4 *= cos4; + cos4 *= cos4; + + B = sqrt(1 + (e2 * cos4) / (1 - e2)); + A = a * B * kC * sqrt(1 - e2) / (1 - e2 * sin(phiC) * sin(phiC)); + t0 = tan((M_PI/4) - (phiC/2)) / pow((1 - e * sin(phiC)) / (1 + e * sin(phiC)), e/2); + D = B * sqrt(1 - e2) / (cos(phiC) * sqrt(1 - e2 * sin(phiC) * sin(phiC))); + D2 = (D < 1) ? 1 : (D * D); + F = D + sqrt(D2 - 1) * SIGN(phiC); + + H = F * pow(t0, B); + G = (F - (1 / F)) / 2; + gamma0 = asin(sin(azmC) / D); + lambda0 = lambdaC - asin(G * tan(gamma0)) / B; + + if (azmC == (M_PI / 2)) { + uC = A * (lambdaC - lambda0); + } + else { + uC = (A / B) * atan(sqrt(D2 - 1) / cos(azmC)) * SIGN(phiC); + } + + /* now calculate from LatLon to EN */ + + t = tan(M_PI/4 - phi/2) / pow((1 - e * sin(phi)) / (1 + e * sin(phi)), e/2); + + Q = H / pow(t, B); + S = (Q - 1.0 / Q) / 2; + T = (Q + 1.0 / Q) / 2; + V = sin(B * (lambda - lambda0)); + U = ((-1.0 * V * cos(gamma0)) + (S * sin(gamma0))) / T; + v = A * log((1.0 - U) / (1.0 + U)) / (2.0 * B); + if (hotine) { + u = A * atan((S * cos(gamma0) + V * sin(gamma0)) / cos(B * (lambda - lambda0))) / B; + } + else { + double tmp = fabs(uC) * SIGN(phiC); + u = (A * atan((S * cos(gamma0) + V * sin(gamma0)) / cos(B * (lambda - lambda0))) / B); + if (u < 0) u = u + tmp; + else u = u - tmp; + } + + *E = (v * cos(gammaC)) + (u * sin(gammaC)) + FE; + *N = (u * cos(gammaC)) - (v * sin(gammaC)) + FN; +#if 0 + printf("B = %.9f\t\tF = %.9f\n", B, F); + printf("A = %.3f\t\tH = %.9f\n", A, H); + printf("t0 = %.9f\t\tgam0= %.9f\n", t0, gamma0); + printf("D = %.9f\t\tlam0= %.9f\n", D, lambda0); + printf("D2 = %.9f\n", D2); + printf("uC = %.2f\t\t\tvC = %.2f\n", uC, (double)0); + printf("\nt = %.9f\t\tQ = %.9f\n", t, Q); + printf("S = %.9f\t\tT = %.9f\n", S, T); + printf("V = %.9f\t\tU = %.9f\n", V, U); + printf("v = %.3f\t\tu = %.3f\n", v, u); +#endif + if ((*E >= 0) && (&N >= 0)) return 1; + else return 0; +} + + +/* @func GPS_Math_OM_EN_To_LatLon ********************************* +** +** Convert Oblique Mercator or Hotine Oblique Mercator projection +** easting and northing to latitude and longitude +** +** status: not really tested, BUT unusable for 'Swiss Grid' +** reference: +** +** @param [r] E [double] easting +** @param [r] N [double] northing +** @param [w] phi [double *] latitude +** @param [w] lambda [double *] latitude +** @param [r] phiC [double] center of projection +** @param [r] lamdaC [double] center of projection +** @param [r] azmC [double] azimuth true (initial line) +** @param [r] gammaC [double] angle from Rectified to Skew Grid +** @param [r] kC [double] skaling factor +** @param [r] FE [double] false easting / E0 for Hotine OM +** @param [r] FN [double] false northing / N0 for Hotine OM +** @param [r] a [double] semi-major axis (meter) +** @param [r] invf [double] flattening (inv.) +** @param [r] hotine [int] use Hotine Hotine Oblique Mercator projection +** @param [r] degrees [int] 1 = parameters in degrees, otherwise radians +** +** @return [void] +************************************************************************/ + +void GPS_Math_OM_EN_To_LatLon( + const double E, const double N, double *phi, double *lambda, + double phiC, double lambdaC, double azmC, double gammaC, const double kC, + const double FE, const double FN, const double a, const double invf, + const char hotine, const char degrees) +{ + double e, e2, e4, e6, e8, f; + double A, B, t0, D, F, G, H; + double v, u, Q, S, T, V, U, t, chi; + double lambda0, gamma0, uC; + double cos4, D2; + + /* prepare parameter */ + + f = 1 / invf; + e2 = 2 * f - f * f; + e4 = e2 * e2; + e6 = e4 * e2; + e8 = e4 * e4; + e = sqrt(e2); + + if (degrees) { + phiC = phiC * M_PI / 180.0; + lambdaC = lambdaC * M_PI / 180.0; + azmC = azmC * M_PI / 180.0; + gammaC = gammaC * M_PI / 180.0; + } + + cos4 = cos(phiC); + cos4 *= cos4; + cos4 *= cos4; + + B = sqrt((double)1 + (e2 * cos4) / (1 - e2)); + A = a * B * kC * sqrt((double)1 - e2) / (1 - e2 * sin(phiC) * sin(phiC)); + t0 = tan((M_PI/4) - (phiC/2)) / pow((1 - e * sin(phiC)) / ((double)1 + e * sin(phiC)), e/2); + D = B * sqrt(1 - e2) / (cos(phiC) * sqrt((double)1 - e2 * sin(phiC) * sin(phiC))); + D2 = (D < 1) ? 1 : (D * D); + F = D + sqrt(D2 - 1) * SIGN(phiC); + + H = F * pow(t0, B); + G = (F - ((double)1 / F)) / 2; + gamma0 = asin(sin(azmC) / D); + lambda0 = lambdaC - asin(G * tan(gamma0)) / B; + + if (azmC == (M_PI / 2)) { + uC = A * (lambdaC - lambda0); + } + else { + uC = (A / B) * atan(sqrt(D2 - 1) / cos(azmC)) * SIGN(phiC); + } + + /* now calculate from LatLon to EN */ + + if (hotine) { + v = (E - FE) * cos(gammaC) - (N - FN) * sin(gammaC); + u = (N - FN) * cos(gammaC) + (E - FE) * sin(gammaC); + } + else { + v = (E - FE) * cos(gammaC) - (N - FN) * sin(gammaC); + u = (N - FN) * cos(gammaC) + (E - FE) * sin(gammaC) + uC; + } + + Q = exp(-1.0 * (B * v / A)); + S = (Q - 1/Q) / 2; + T = (Q + 1/Q) / 2; + V = sin(B * u / A); + U = (V * cos(gamma0) + S * sin(gamma0)) / T; + t = pow(H / sqrt((1.0 + U) / (1.0 - U)), 1.0 / B); + chi = (M_PI / 2) - (atan(t) * 2); + + *phi = chi + sin(chi*2) * (e2 / 2 + 5*e4 / 24 + e6 / 12 + e8 / 360) + + sin(chi*4) * (7 * e4 / 48 + 29 * e6 / 240 + 811*e8 / 11520) + + sin(chi*6) * (7 * e6 /120 + 81 * e8 / 1120) + + sin(chi*8) * (4279 * e8 / 161280); + +// *lambda = lambda0 - atan2((S * cos(gammaC) - V * sin(gammaC)), cos(B * u / A)) / B; + *lambda = lambda0 - atan((S * cos(gammaC) - V * sin(gammaC)) / cos(B * u / A)) / B; + + /* finalize results */ + if (degrees) { + *phi = *phi * 180.0 / M_PI; + *lambda = *lambda * 180.0 / M_PI; + } + +#if 0 + printf("\nE = %11.3f\t\tN = %11.3f\n", E, N); + printf("\nB = %.9f\t\tF = %.9f\n", B, F); + printf("A = %.3f\t\tH = %.9f\n", A, H); + printf("t0 = %.9f\t\tgam0= %.9f\n", t0, gamma0); + printf("D = %.9f\t\tlam0= %.9f\n", D, lambda0); + printf("D2 = %.9f\n", D2); + printf("uC = %.2f\n", uC); + printf("cosG= %11.9f\t\tsinG = %11.9f\n", cos(gammaC), sin(gammaC)); + printf("BuA = %11.9f\t\tcosBuA=%9.9f\n", B * u / A, cos(B * u / A)); + printf("S * cos(gammaC) = %11.9f\n", S * cos(gammaC)); + printf("V * sin(gammaC) = %11.9f\n", V * sin(gammaC)); + printf("base= %11.9f\t\tatan = %11.9f\n", + (S * cos(gammaC) - V * sin(gammaC)) / cos(B * u / A), + atan((S * cos(gammaC) - V * sin(gammaC)) / cos(B * u / A)) + ); + + printf("v' = %11.3f\t\tu' = %.3f\n", v, u); + printf("Q' = %.9f\n", Q); + printf("S' = %11.9f\t\tT' = %.9f\n", S, T); + printf("V' = %11.9f\t\tU' = %.9f\n", V, U); + printf("t' = %11.9f\t\tchi'= %0.9f\n", t, chi); +#endif +} + +/* @func GPS_Math_EN_To_LatLon ************************************** +** +** Convert Eastings and Northings to latitude and longitude +** +** @param [w] E [double] NG easting (metres) +** @param [w] N [double] NG northing (metres) +** @param [r] phi [double *] Airy latitude (deg) +** @param [r] lambda [double *] Airy longitude (deg) +** @param [r] N0 [double] true northing origin (metres) +** @param [r] E0 [double] true easting origin (metres) +** @param [r] phi0 [double] true latitude origin (deg) +** @param [r] lambda0 [double] true longitude origin (deg) +** @param [r] F0 [double] scale factor on central meridian +** @param [r] a [double] semi-major axis (metres) +** @param [r] b [double] semi-minor axis (metres) +** +** @return [void] +************************************************************************/ +void GPS_Math_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b) +{ + double esq; + double n; + double etasq; + double nu; + double rho; + double M; + double VII; + double VIII; + double IX; + double X; + double XI; + double XII; + double XIIA; + double phix; + double nphi=0.0; + + double tmp; + double tmp2; + double fdf; + double fde; + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + n = (a-b) / (a+b); + fdf = (double)5.0 / (double)4.0; + fde = ((double)15.0 / (double)8.0); + + esq = ((a*a)-(b*b)) / (a*a); + + + phix = ((N-N0)/(a*F0)) + phi0; + + tmp = (double)1.0 - (esq * sin(phix) * sin(phix)); + nu = a * F0 * pow(tmp,(double)-0.5); + rho = a * F0 * ((double)1.0 - esq) * pow(tmp,(double)-1.5); + etasq = (nu / rho) - (double)1.0; + + M = (double)-1e20; + + while(N-N0-M > (double)0.000001) + { + nphi = phix; + + tmp = (double)1.0 + n + (fdf * n * n) + (fdf * n * n * n); + tmp *= (nphi - phi0); + tmp2 = (double)3.0*n + (double)3.0*n*n + + ((double)21./(double)8.)*n*n*n; + tmp2 *= (sin(nphi-phi0) * cos(nphi+phi0)); + tmp -= tmp2; + + + tmp2 = ((fde*n*n) + (fde*n*n*n)) * sin((double)2.0 * (nphi-phi0)); + tmp2 *= cos((double)2.0 * (nphi+phi0)); + tmp += tmp2; + + tmp2 = ((double)35.0/(double)24.0) * n * n * n; + tmp2 *= sin((double)3.0 * (nphi-phi0)); + tmp2 *= cos((double)3.0 * (nphi+phi0)); + tmp -= tmp2; + + M = b * F0 * tmp; + + if(N-N0-M > (double)0.000001) + phix = ((N-N0-M)/(a*F0)) + nphi; + } + + + VII = tan(nphi) / ((double)2.0 * rho * nu); + + tmp = (double)5.0 + (double)3.0 * tan(nphi) * tan(nphi) + etasq; + tmp -= (double)9.0 * tan(nphi) * tan(nphi) * etasq; + VIII = (tan(nphi)*tmp) / ((double)24.0 * rho * nu*nu*nu); + + tmp = (double)61.0 + (double)90.0 * tan(nphi) * tan(nphi); + tmp += (double)45.0 * pow(tan(nphi),(double)4.0); + IX = tan(nphi) / ((double)720.0 * rho * pow(nu,(double)5.0)) * tmp; + + X = (double)1.0 / (cos(nphi) * nu); + + tmp = (nu / rho) + (double)2.0 * tan(nphi) * tan(nphi); + XI = ((double)1.0 / (cos(nphi) * (double)6.0 * nu*nu*nu)) * tmp; + + tmp = (double)5.0 + (double)28.0 * tan(nphi)*tan(nphi); + tmp += (double)24.0 * pow(tan(nphi),(double)4.0); + XII = ((double)1.0 / ((double)120.0 * pow(nu,(double)5.0) * cos(nphi))) + * tmp; + + tmp = (double)61.0 + (double)662.0 * tan(nphi) * tan(nphi); + tmp += (double)1320.0 * pow(tan(nphi),(double)4.0); + tmp += (double)720.0 * pow(tan(nphi),(double)6.0); + XIIA = ((double)1.0 / (cos(nphi) * (double)5040.0 * pow(nu,(double)7.0))) + * tmp; + + *phi = nphi - VII*pow((E-E0),(double)2.0) + VIII*pow((E-E0),(double)4.0) - + IX*pow((E-E0),(double)6.0); + + *lambda = lambda0 + X*(E-E0) - XI*pow((E-E0),(double)3.0) + + XII*pow((E-E0),(double)5.0) - XIIA*pow((E-E0),(double)7.0); + + *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + + return; +} + + + + +/* @func GPS_Math_NGENToAiry1830LatLon ************************************** +** +** Convert to UK Ordnance Survey National Grid Eastings and Northings to +** Airy 1830 datum latitude and longitude +** +** @param [r] E [double] NG easting (metres) +** @param [r] N [double] NG northing (metres) +** @param [w] phi [double *] Airy latitude (deg) +** @param [w] lambda [double *] Airy longitude (deg) +** +** @return [void] +************************************************************************/ +void GPS_Math_NGENToAiry1830LatLon(double E, double N, double *phi, + double *lambda) +{ + double N0 = -100000; + double E0 = 400000; + double F0 = 0.9996012717; + double phi0 = 49.; + double lambda0 = -2.; + double a = 6377563.396; + double b = 6356256.910; + + GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; +} + + + +/* @func GPS_Math_INGENToAiry1830MLatLon ************************************** +** +** Convert Irish National Grid Eastings and Northings to modified +** Airy 1830 datum latitude and longitude +** +** @param [r] E [double] ING easting (metres) +** @param [r] N [double] ING northing (metres) +** @param [w] phi [double *] modified Airy latitude (deg) +** @param [w] lambda [double *] modified Airy longitude (deg) +** +** @return [void] +************************************************************************/ +void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double *phi, + double *lambda) +{ + double N0 = 250000; + double E0 = 200000; + double F0 = 1.000035; + double phi0 = 53.5; + double lambda0 = -8.; + double a = 6377340.189; + double b = 6356034.447; + + GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; +} + + + +/* @func GPS_Math_EN_To_UKOSNG_Map ************************************* +** +** Convert Airy 1830 eastings and northings to Ordnance Survey map +** two letter code plus modified eastings and northings +** +** @param [r] E [double] NG easting (metres) +** @param [r] N [double] NG northing (metres) +** @param [w] mE [double *] modified easting (metres) +** @param [w] mN [double *] modified northing (metres) +** @param [w] map [char *] map code +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double *mE, + double *mN, char *map) +{ + int32 t; + int32 idx; + + if(E>=(double)700000. || E<(double)0.0 || N<(double)0.0 || + N>=(double)1300000.0) + return 0; + + idx = ((int32)N/100000)*7 + (int32)E/100000; + (void) strcpy(map,UKNG[idx]); + + t = ((int32)E / 100000) * 100000; + *mE = E - (double)t; + + t = ((int32)N / 100000) * 100000; + *mN = N - (double)t; + + return 1; +} + + + +/* @func GPS_Math_UKOSNG_Map_To_EN ************************************* +** +** Convert Ordnance Survey map eastings and northings plus +** two letter code to Airy 1830 eastings and northings +** +** @param [w] map [char *] map code +** @param [r] mapE [double] easting (metres) +** @param [r] mapN [double] northing (metres) +** @param [w] E [double *] full Airy easting (metres) +** @param [w] N [double *] full Airy northing (metres) + +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_UKOSNG_Map_To_EN(char *map, double mapE, double mapN, double *E, + double *N) +{ + int32 t; + int32 idx; + + if(mapE>=(double)100000.0 || mapE<(double)0.0 || mapN<(double)0.0 || + mapN>(double)100000.0) + return 0; + + idx=0; + while(*UKNG[idx]) + { + if(!strcmp(UKNG[idx],map)) break; + ++idx; + } + if(!*UKNG[idx]) + return 0; + + + t = (idx / 7) * 100000; + *N = mapN + (double)t; + + t = (idx % 7) * 100000; + *E = mapE + (double)t; + + return 1; +} + + + +/* @func GPS_Math_Molodensky ******************************************* +** +** Transform one datum to another +** +** @param [r] Sphi [double] source latitude (deg) +** @param [r] Slam [double] source longitude (deg) +** @param [r] SH [double] source height (metres) +** @param [r] Sa [double] source semi-major axis (metres) +** @param [r] Sif [double] source inverse flattening +** @param [w] Dphi [double *] dest latitude (deg) +** @param [w] Dlam [double *] dest longitude (deg) +** @param [w] DH [double *] dest height (metres) +** @param [r] Da [double] dest semi-major axis (metres) +** @param [r] Dif [double] dest inverse flattening +** @param [r] dx [double] dx +** @param [r] dy [double] dy +** @param [r] dz [double] dz +** +** @return [void] +************************************************************************/ +void GPS_Math_Molodensky(double Sphi, double Slam, double SH, double Sa, + double Sif, double *Dphi, double *Dlam, + double *DH, double Da, double Dif, double dx, + double dy, double dz) +{ + double Sf; + double Df; + double esq; + double bda; + double da; + double df; + double N; + double M; + double tmp; + double tmp2; + double dphi; + double dlambda; + double dheight; + double phis; + double phic; + double lams; + double lamc; + + Sf = (double)1.0 / Sif; + Df = (double)1.0 / Dif; + + esq = (double)2.0*Sf - pow(Sf,(double)2.0); + bda = (double)1.0 - Sf; + Sphi = GPS_Math_Deg_To_Rad(Sphi); + Slam = GPS_Math_Deg_To_Rad(Slam); + + da = Da - Sa; + df = Df - Sf; + + phis = sin(Sphi); + phic = cos(Sphi); + lams = sin(Slam); + lamc = cos(Slam); + + N = Sa / sqrt((double)1.0 - esq*pow(phis,(double)2.0)); + + tmp = ((double)1.0-esq) /pow(((double)1.0-esq*pow(phis,(double)2.0)),1.5); + M = Sa * tmp; + + tmp = df * ((M/bda)+N*bda) * phis * phic; + tmp2 = da * N * esq * phis * phic / Sa; + tmp2 += ((-dx*phis*lamc-dy*phis*lams) + dz*phic); + dphi = (tmp2 + tmp) / (M + SH); + + dlambda = (-dx*lams+dy*lamc) / ((N+SH)*phic); + + dheight = dx*phic*lamc + dy*phic*lams + dz*phis - da*(Sa/N) + + df*bda*N*phis*phis; + + *Dphi = Sphi + dphi; + *Dlam = Slam + dlambda; + *DH = SH + dheight; + + *Dphi = GPS_Math_Rad_To_Deg(*Dphi); + *Dlam = GPS_Math_Rad_To_Deg(*Dlam); + + return; +} + + + +/* @func GPS_Math_Known_Datum_To_WGS84_M ********************************** +** +** Transform datum to WGS84 using Molodensky +** +** @param [r] Sphi [double] source latitude (deg) +** @param [r] Slam [double] source longitude (deg) +** @param [r] SH [double] source height (metres) +** @param [w] Dphi [double *] dest latitude (deg) +** @param [w] Dlam [double *] dest longitude (deg) +** @param [w] DH [double *] dest height (metres) +** @param [r] n [int32] datum number from GPS_Datum structure +** +** @return [void] +************************************************************************/ +void GPS_Math_Known_Datum_To_WGS84_M(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n) +{ + double Sa; + double Sif; + double Da; + double Dif; + double x; + double y; + double z; + int32 idx; + + Da = (double) 6378137.0; + Dif = (double) 298.257223563; + + idx = GPS_Datum[n].ellipse; + Sa = GPS_Ellipse[idx].a; + Sif = GPS_Ellipse[idx].invf; + x = GPS_Datum[n].dx; + y = GPS_Datum[n].dy; + z = GPS_Datum[n].dz; + + GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); + + return; +} + + + +/* @func GPS_Math_WGS84_To_Known_Datum_M ******************************** +** +** Transform WGS84 to other datum using Molodensky +** +** @param [r] Sphi [double] source latitude (deg) +** @param [r] Slam [double] source longitude (deg) +** @param [r] SH [double] source height (metres) +** @param [w] Dphi [double *] dest latitude (deg) +** @param [w] Dlam [double *] dest longitude (deg) +** @param [w] DH [double *] dest height (metres) +** @param [r] n [int32] datum number from GPS_Datum structure +** +** @return [void] +************************************************************************/ +void GPS_Math_WGS84_To_Known_Datum_M(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n) +{ + double Sa; + double Sif; + double Da; + double Dif; + double x; + double y; + double z; + int32 idx; + + Sa = (double) 6378137.0; + Sif = (double) 298.257223563; + + idx = GPS_Datum[n].ellipse; + Da = GPS_Ellipse[idx].a; + Dif = GPS_Ellipse[idx].invf; + x = -GPS_Datum[n].dx; + y = -GPS_Datum[n].dy; + z = -GPS_Datum[n].dz; + + GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); + + return; +} + + + +/* @func GPS_Math_Known_Datum_To_WGS84_C ********************************** +** +** Transform datum to WGS84 using Cartesian coordinates +** +** @param [r] Sphi [double] source latitude (deg) +** @param [r] Slam [double] source longitude (deg) +** @param [r] SH [double] source height (metres) +** @param [w] Dphi [double *] dest latitude (deg) +** @param [w] Dlam [double *] dest longitude (deg) +** @param [w] DH [double *] dest height (metres) +** @param [r] n [int32] datum number from GPS_Datum structure +** +** @return [void] +************************************************************************/ +void GPS_Math_Known_Datum_To_WGS84_C(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n) +{ + double Sa; + double Sif; + double Sb; + double Da; + double Dif; + double Db; + double x; + double y; + double z; + int32 idx; + double sx; + double sy; + double sz; + + Da = (double) 6378137.0; + Dif = (double) 298.257223563; + Db = Da - (Da / Dif); + + idx = GPS_Datum[n].ellipse; + Sa = GPS_Ellipse[idx].a; + Sif = GPS_Ellipse[idx].invf; + Sb = Sa - (Sa / Sif); + + x = GPS_Datum[n].dx; + y = GPS_Datum[n].dy; + z = GPS_Datum[n].dz; + + GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&sx,&sy,&sz,Sa,Sb); + sx += x; + sy += y; + sz += z; + + GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,sx,sy,sz,Da,Db); + + return; +} + + + +/* @func GPS_Math_WGS84_To_Known_Datum_C ******************************** +** +** Transform WGS84 to other datum using Cartesian coordinates +** +** @param [r] Sphi [double] source latitude (deg) +** @param [r] Slam [double] source longitude (deg) +** @param [r] SH [double] source height (metres) +** @param [w] Dphi [double *] dest latitude (deg) +** @param [w] Dlam [double *] dest longitude (deg) +** @param [w] DH [double *] dest height (metres) +** @param [r] n [int32] datum number from GPS_Datum structure +** +** @return [void] +************************************************************************/ +void GPS_Math_WGS84_To_Known_Datum_C(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n) +{ + double Sa; + double Sif; + double Da; + double Dif; + double x; + double y; + double z; + int32 idx; + double Sb; + double Db; + double dx; + double dy; + double dz; + + Sa = (double) 6378137.0; + Sif = (double) 298.257223563; + Sb = Sa - (Sa / Sif); + + idx = GPS_Datum[n].ellipse; + Da = GPS_Ellipse[idx].a; + Dif = GPS_Ellipse[idx].invf; + Db = Da - (Da / Dif); + + x = -GPS_Datum[n].dx; + y = -GPS_Datum[n].dy; + z = -GPS_Datum[n].dz; + + GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&dx,&dy,&dz,Sa,Sb); + dx += x; + dy += y; + dz += z; + + GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,dx,dy,dz,Da,Db); + + return; +} + + + +/* @func GPS_Math_Known_Datum_To_Known_Datum_M ************************* +** +** Transform WGS84 to other datum using Molodensky +** +** @param [r] Sphi [double] source latitude (deg) +** @param [r] Slam [double] source longitude (deg) +** @param [r] SH [double] source height (metres) +** @param [w] Dphi [double *] dest latitude (deg) +** @param [w] Dlam [double *] dest longitude (deg) +** @param [w] DH [double *] dest height (metres) +** @param [r] n1 [int32] source datum number from GPS_Datum structure +** @param [r] n2 [int32] dest datum number from GPS_Datum structure +** +** @return [void] +************************************************************************/ +void GPS_Math_Known_Datum_To_Known_Datum_M(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, + double *DH, int32 n1, int32 n2) +{ + double Sa; + double Sif; + double Da; + double Dif; + double x1; + double y1; + double z1; + double x2; + double y2; + double z2; + double x; + double y; + double z; + + int32 idx1; + int32 idx2; + + + idx1 = GPS_Datum[n1].ellipse; + Sa = GPS_Ellipse[idx1].a; + Sif = GPS_Ellipse[idx1].invf; + x1 = GPS_Datum[n1].dx; + y1 = GPS_Datum[n1].dy; + z1 = GPS_Datum[n1].dz; + + idx2 = GPS_Datum[n2].ellipse; + Da = GPS_Ellipse[idx2].a; + Dif = GPS_Ellipse[idx2].invf; + x2 = GPS_Datum[n2].dx; + y2 = GPS_Datum[n2].dy; + z2 = GPS_Datum[n2].dz; + + x = -(x2-x1); + y = -(y2-y1); + z = -(z2-z1); + + GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); + + return; +} + + + +/* @func GPS_Math_Known_Datum_To_Known_Datum_C ************************* +** +** Transform known datum to other datum using Cartesian coordinates +** +** @param [r] Sphi [double] source latitude (deg) +** @param [r] Slam [double] source longitude (deg) +** @param [r] SH [double] source height (metres) +** @param [w] Dphi [double *] dest latitude (deg) +** @param [w] Dlam [double *] dest longitude (deg) +** @param [w] DH [double *] dest height (metres) +** @param [r] n1 [int32] source datum number from GPS_Datum structure +** @param [r] n2 [int32] dest datum number from GPS_Datum structure +** +** @return [void] +************************************************************************/ +void GPS_Math_Known_Datum_To_Known_Datum_C(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, + double *DH, int32 n1, int32 n2) +{ + double Sa; + double Sif; + double Da; + double Dif; + double x1; + double y1; + double z1; + double x2; + double y2; + double z2; + + int32 idx1; + int32 idx2; + + double Sb; + double Db; + double dx; + double dy; + double dz; + + idx1 = GPS_Datum[n1].ellipse; + Sa = GPS_Ellipse[idx1].a; + Sif = GPS_Ellipse[idx1].invf; + Sb = Sa - (Sa / Sif); + + x1 = GPS_Datum[n1].dx; + y1 = GPS_Datum[n1].dy; + z1 = GPS_Datum[n1].dz; + + idx2 = GPS_Datum[n2].ellipse; + Da = GPS_Ellipse[idx2].a; + Dif = GPS_Ellipse[idx2].invf; + Db = Da - (Da / Dif); + + x2 = GPS_Datum[n2].dx; + y2 = GPS_Datum[n2].dy; + z2 = GPS_Datum[n2].dz; + + GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&dx,&dy,&dz,Sa,Sb); + dx += -(x2-x1); + dy += -(y2-y1); + dz += -(z2-z1); + + GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,dx,dy,dz,Da,Db); + + return; +} + + + +/* @func GPS_Math_WGS84_To_UKOSMap_M *********************************** +** +** Convert WGS84 lat/lon to Ordnance survey map code and easting and +** northing. Uses Molodensky +** +** @param [r] lat [double] WGS84 latitude (deg) +** @param [r] lon [double] WGS84 longitude (deg) +** @param [w] mE [double *] map easting (metres) +** @param [w] mN [double *] map northing (metres) +** @param [w] map [char *] map two letter code +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double *mE, + double *mN, char *map) +{ + double alat; + double alon; + double aht; + double aE; + double aN; + + + GPS_Math_WGS84_To_Known_Datum_M(lat,lon,30,&alat,&alon,&aht,86); + + GPS_Math_Airy1830LatLonToNGEN(alat,alon,&aE,&aN); + + if(!GPS_Math_EN_To_UKOSNG_Map(aE,aN,mE,mN,map)) + return 0; + + return 1; +} + + + +/* @func GPS_Math_UKOSMap_To_WGS84_M *********************************** +** +** Transform UK Ordnance survey map position to WGS84 lat/lon +** Uses Molodensky transformation +** +** @param [r] map [char *] map two letter code +** @param [r] mE [double] map easting (metres) +** @param [r] mN [double] map northing (metres) +** @param [w] lat [double *] WGS84 latitude (deg) +** @param [w] lon [double *] WGS84 longitude (deg) +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_UKOSMap_To_WGS84_M(char *map, double mE, double mN, + double *lat, double *lon) +{ + double E; + double N; + double alat; + double alon; + double ht; + + if(!GPS_Math_UKOSNG_Map_To_EN(map,mE,mN,&E,&N)) + return 0; + + GPS_Math_NGENToAiry1830LatLon(E,N,&alat,&alon); + + GPS_Math_Known_Datum_To_WGS84_M(alat,alon,0,lat,lon,&ht,86); + + return 1; +} + + + +/* @func GPS_Math_WGS84_To_UKOSMap_C *********************************** +** +** Convert WGS84 lat/lon to Ordnance survey map code and easting and +** northing. Uses cartesian transformation +** +** @param [r] lat [double] WGS84 latitude (deg) +** @param [r] lon [double] WGS84 longitude (deg) +** @param [w] mE [double *] map easting (metres) +** @param [w] mN [double *] map northing (metres) +** @param [w] map [char *] map two letter code +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double *mE, + double *mN, char *map) +{ + double alat; + double alon; + double aht; + double aE; + double aN; + + + GPS_Math_WGS84_To_Known_Datum_C(lat,lon,30,&alat,&alon,&aht,86); + + GPS_Math_Airy1830LatLonToNGEN(alat,alon,&aE,&aN); + + if(!GPS_Math_EN_To_UKOSNG_Map(aE,aN,mE,mN,map)) + return 0; + + return 1; +} + + + +/* @func GPS_Math_UKOSMap_To_WGS84_C *********************************** +** +** Transform UK Ordnance survey map position to WGS84 lat/lon +** Uses cartesian transformation +** +** @param [r] map [char *] map two letter code +** @param [r] mE [double] map easting (metres) +** @param [r] mN [double] map northing (metres) +** @param [w] lat [double *] WGS84 latitude (deg) +** @param [w] lon [double *] WGS84 longitude (deg) +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_UKOSMap_To_WGS84_C(char *map, double mE, double mN, + double *lat, double *lon) +{ + double E; + double N; + double alat; + double alon; + double ht; + + if(!GPS_Math_UKOSNG_Map_To_EN(map,mE,mN,&E,&N)) + return 0; + + GPS_Math_NGENToAiry1830LatLon(E,N,&alat,&alon); + + GPS_Math_Known_Datum_To_WGS84_C(alat,alon,0,lat,lon,&ht,86); + + return 1; +} + + +/* @funcstatic GPS_Math_LatLon_To_UTM_Param ***************************** +** +** Transform NAD33 +** +** @param [r] lat [double] NAD latitude (deg) +** @param [r] lon [double] NAD longitude (deg) +** @param [w] zone [int32 *] zone number +** @param [w] zc [char *] zone character +** @param [w] Mc [double *] central meridian +** @param [w] E0 [double *] false easting +** @param [w] N0 [double *] false northing +** @param [w] F0 [double *] scale factor +** +** @return [int32] success +************************************************************************/ +static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32 *zone, + char *zc, double *Mc, double *E0, + double *N0, double *F0) +{ + int32 ilon; + int32 ilat; + int32 psign; + int32 lsign; + + if(lat >= (double)84.0 || lat < (double)-80.0) + return 0; + + psign = lsign = 0; + if(lon < (double)0.0) + lsign=1; + if(lat < (double)0.0) + psign=1; + + ilon = abs((int32)lon); + ilat = abs((int32)lat); + + if(!lsign) + { + *zone = 31 + (ilon / 6); + *Mc = (double)((ilon / 6) * 6 + 3); + } + else + { + *zone = 30 - (ilon / 6); + *Mc = -(double)((ilon / 6) * 6 + 3); + } + + if(!psign) + { + *zc = 'N' + ilat / 8; + if(*zc > 'N') ++*zc; + } + else + { + *zc = 'M' - (ilat / 8); + if(*zc <= 'I') --*zc; + } + + + if(lat>=(double)56.0 && lat<(double)64.0 && lon>=(double)3.0 && + lon<(double)12.0) + { + *zone = 32; + *zc = 'V'; + *Mc = (double)9.0; + } + + if(*zc=='X' && lon>=(double)0.0 && lon<(double)42.0) + { + if(lon<(double)9.0) + { + *zone = 31; + *Mc = (double)3.0; + } + else if(lon<(double)21.0) + { + *zone = 33; + *Mc = (double)15.0; + } + else if(lon<(double)33.0) + { + *zone = 35; + *Mc = (double)27.0; + } + else + { + *zone = 37; + *Mc = (double)39.0; + } + } + + if(!psign) + *N0 = (double)0.0; + else + *N0 = (double)10000000; + + *E0 = (double)500000; + *F0 = (double)0.9996; + + return 1; +} + + + +/* @func GPS_Math_NAD83_To_UTM_EN ************************************** +** +** Transform NAD33 lat/lon to UTM zone, easting and northing +** +** @param [r] lat [double] NAD latitude (deg) +** @param [r] lon [double] NAD longitude (deg) +** @param [w] E [double *] easting (metres) +** @param [w] N [double *] northing (metres) +** @param [w] zone [int32 *] zone number +** @param [w] zc [char *] zone character +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double *E, + double *N, int32 *zone, char *zc) +{ + double phi0; + double lambda0; + double N0; + double E0; + double F0; + double a; + double b; + + if(!GPS_Math_LatLon_To_UTM_Param(lat,lon,zone,zc,&lambda0,&E0, + &N0,&F0)) + return 0; + + phi0 = (double)0.0; + + a = (double) GPS_Ellipse[21].a; + b = a - (a/GPS_Ellipse[21].invf); + + GPS_Math_LatLon_To_EN(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); + + return 1; +} + + + +/* @func GPS_Math_WGS84_To_UTM_EN ************************************** +** +** Transform WGS84 lat/lon to UTM zone, easting and northing +** +** @param [r] lat [double] WGS84 latitude (deg) +** @param [r] lon [double] WGS84 longitude (deg) +** @param [w] E [double *] easting (metres) +** @param [w] N [double *] northing (metres) +** @param [w] zone [int32 *] zone number +** @param [w] zc [char *] zone character +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double *E, + double *N, int32 *zone, char *zc) +{ + double phi; + double lambda; + double H; + + GPS_Math_WGS84_To_Known_Datum_M(lat,lon,0,&phi,&lambda,&H,77); + if(!GPS_Math_NAD83_To_UTM_EN(phi,lambda,E,N,zone,zc)) + return 0; + + return 1; +} + + + +/* @funcstatic GPS_Math_UTM_Param_To_Mc ******************************** +** +** Convert UTM zone and zone character to central meridian value. +** Also return false eastings, northings and scale factor +** +** @param [w] zone [int32] zone number +** @param [w] zc [char] zone character +** @param [w] Mc [double *] central meridian +** @param [w] E0 [double *] false easting +** @param [w] N0 [double *] false northing +** @param [w] F0 [double *] scale factor +** +** @return [int32] success +************************************************************************/ +static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double *Mc, + double *E0, double *N0, double *F0) +{ + + if(zone>60 || zone<0 || zc<'C' || zc>'X') + return 0; + + if(zone > 30) + *Mc = (double)((zone-31)*6) + (double)3.0; + else + *Mc = (double) -(((30-zone)*6)+3); + + if(zone==32 && zc=='V') + *Mc = (double)9.0; + + if(zone==31 && zc=='X') + *Mc = (double)3.0; + if(zone==33 && zc=='X') + *Mc = (double)15.0; + if(zone==35 && zc=='X') + *Mc = (double)27.0; + if(zone==37 && zc=='X') + *Mc = (double)39.0; + + if(zc>'M') + *N0 = (double)0.0; + else + *N0 = (double)10000000; + + *E0 = (double)500000; + *F0 = (double)0.9996; + + return 1; +} + + + +/* @func GPS_Math_UTM_EN_To_NAD83 ************************************** +** +** Transform UTM zone, easting and northing to NAD83 lat/lon +** +** @param [r] lat [double *] NAD latitude (deg) +** @param [r] lon [double *] NAD longitude (deg) +** @param [w] E [double] easting (metres) +** @param [w] N [double] northing (metres) +** @param [w] zone [int32] zone number +** @param [w] zc [char] zone character +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_UTM_EN_To_NAD83(double *lat, double *lon, double E, + double N, int32 zone, char zc) +{ + return GPS_Math_UTM_EN_To_Known_Datum(lat, lon, E, N, zone, zc, 77); +} + + + +/* @func GPS_Math_UTM_EN_To_WGS84 ************************************** +** +** Transform UTM zone, easting and northing to WGS84 lat/lon +** +** @param [w] lat [double *] WGS84 latitude (deg) +** @param [r] lon [double *] WGS84 longitude (deg) +** @param [w] E [double] easting (metres) +** @param [w] N [double] northing (metres) +** @param [w] zone [int32] zone number +** @param [w] zc [char] zone character +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, + double N, int32 zone, char zc) +{ + return GPS_Math_UTM_EN_To_Known_Datum(lat, lon, E, N, zone, zc, 118); +} + + +/* @func GPS_Math_Known_Datum_To_UTM_EN ********************************* +** +** Transform known datum lat/lon to UTM zone, easting and northing +** +** @param [r] lat [double] WGS84 latitude (deg) +** @param [r] lon [double] WGS84 longitude (deg) +** @param [w] E [double *] easting (metres) +** @param [w] N [double *] northing (metres) +** @param [w] zone [int32 *] zone number +** @param [w] zc [char *] zone character +** @param [r] n [int32] datum number from GPS_Datum structure +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double *E, + double *N, int32 *zone, char *zc, const int n) +{ + double phi0; + double lambda0; + double N0; + double E0; + double F0; + double a; + double b; + int32 idx; + + if(!GPS_Math_LatLon_To_UTM_Param(lat,lon,zone,zc,&lambda0,&E0, + &N0,&F0)) + return 0; + + phi0 = (double)0.0; + + idx = GPS_Datum[n].ellipse; + a = (double) GPS_Ellipse[idx].a; + b = a - (a/GPS_Ellipse[idx].invf); + + GPS_Math_LatLon_To_EN(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); + + return 1; +} + +/* @func GPS_Math_UTM_EN_To_Known_Datum ********************************* +** +** Transform UTM zone, easting and northing to known datum lat/lon +** +** @param [w] lat [double *] WGS84 latitude (deg) +** @param [r] lon [double *] WGS84 longitude (deg) +** @param [w] E [double] easting (metres) +** @param [w] N [double] northing (metres) +** @param [w] zone [int32] zone number +** @param [w] zc [char] zone character +** @param [r] n [int32] datum number from GPS_Datum structure +** +** @return [int32] success +************************************************************************/ +int32 GPS_Math_UTM_EN_To_Known_Datum(double *lat, double *lon, double E, + double N, int32 zone, char zc, const int n) +{ + double phi0; + double lambda0; + double N0; + double E0; + double F0; + double a; + double b; + int32 idx; + char southern; + + if(!GPS_Math_UTM_Param_To_Mc(zone,zc,&lambda0,&E0,&N0,&F0)) + return 0; + + if (N0 > N) { + southern = 1; + N = N0 - N; + N0 = 0; + } + else southern = 0; + + phi0 = (double)0.0; + + idx = GPS_Datum[n].ellipse; + a = (double) GPS_Ellipse[idx].a; + b = a - (a/GPS_Ellipse[idx].invf); + + GPS_Math_EN_To_LatLon(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); + + if (southern) *lat = -(*lat); + + return 1; +} + + +int32 GPS_Lookup_Datum_Index(const char *n) +{ + GPS_PDatum dp; + GPS_PDatum_Alias al; + + for (al = GPS_DatumAlias; al->alias; al++) { + if (case_ignore_strcmp(al->alias, n) == 0) { + return al->datum; + } + } + + for (dp = GPS_Datum; dp->name; dp++) { + if (0 == case_ignore_strcmp(dp->name, n)) { + return dp - GPS_Datum; + } + } + + return -1; +} + +char * +GPS_Math_Get_Datum_Name(const int datum_index) +{ + return GPS_Datum[datum_index].name; +} diff --git a/jeeps/gpsmath.h b/jeeps/gpsmath.h new file mode 100644 index 000000000..51b14dae6 --- /dev/null +++ b/jeeps/gpsmath.h @@ -0,0 +1,145 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsmath_h +#define gpsmath_h + + +#include "gps.h" + +#define GPS_PI 3.141592653589 +#define GPS_FLTMIN 1.75494351E-38 +#define GPS_FLTMAX 3.402823466E+38 + + +double GPS_Math_Deg_To_Rad(double v); +double GPS_Math_Rad_To_Deg(double v); + +double GPS_Math_Metres_To_Feet(double v); +double GPS_Math_Feet_To_Metres(double v); + +int32 GPS_Math_Deg_To_Semi(double v); +double GPS_Math_Semi_To_Deg(int32 v); + +time_t GPS_Math_Utime_To_Gtime(time_t v); +time_t GPS_Math_Gtime_To_Utime(time_t v); + +void GPS_Math_Deg_To_DegMin(double v, int32 *d, double *m); +void GPS_Math_DegMin_To_Deg(int32 d, double m, double *deg); +void GPS_Math_Deg_To_DegMinSec(double v, int32 *d, int32 *m, double *s); +void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg); + + +void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double *E, + double *N); +void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double *E, + double *N); +int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double *mE, + double *mN, char *map); +int32 GPS_Math_UKOSNG_Map_To_EN(char *map, double mapE, double mapN, + double *E, double *N); + +void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H, + double *x, double *y, double *z, + double a, double b); +void GPS_Math_XYZ_To_LatLonH(double *phi, double *lambda, double *H, + double x, double y, double z, + double a, double b); + +void GPS_Math_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b); +void GPS_Math_LatLon_To_EN(double *E, double *N, double phi, + double lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b); + +void GPS_Math_NGENToAiry1830LatLon(double E, double N, double *phi, + double *lambda); +void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double *phi, + double *lambda); + + +void GPS_Math_Airy1830LatLonH_To_XYZ(double phi, double lambda, double H, + double *x, double *y, double *z); +void GPS_Math_WGS84LatLonH_To_XYZ(double phi, double lambda, double H, + double *x, double *y, double *z); +void GPS_Math_XYZ_To_Airy1830LatLonH(double *phi, double *lambda, double *H, + double x, double y, double z); +void GPS_Math_XYZ_To_WGS84LatLonH(double *phi, double *lambda, double *H, + double x, double y, double z); + +void GPS_Math_Molodensky(double Sphi, double Slam, double SH, double Sa, + double Sif, double *Dphi, double *Dlam, + double *DH, double Da, double Dif, double dx, + double dy, double dz); +void GPS_Math_Known_Datum_To_WGS84_M(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n); +void GPS_Math_WGS84_To_Known_Datum_M(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n); +void GPS_Math_Known_Datum_To_WGS84_C(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n); +void GPS_Math_WGS84_To_Known_Datum_C(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n); + +void GPS_Math_Known_Datum_To_Known_Datum_M(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, + double *DH, int32 n1, int32 n2); +void GPS_Math_Known_Datum_To_Known_Datum_C(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, + double *DH, int32 n1, int32 n2); + +int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double *mE, + double *mN, char *map); +int32 GPS_Math_UKOSMap_To_WGS84_M(char *map, double mE, double mN, + double *lat, double *lon); +int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double *mE, + double *mN, char *map); +int32 GPS_Math_UKOSMap_To_WGS84_C(char *map, double mE, double mN, + double *lat, double *lon); + + +int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double *E, + double *N, int32 *zone, char *zc); +int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double *E, + double *N, int32 *zone, char *zc); + +int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, + double N, int32 zone, char zc); +int32 GPS_Math_UTM_EN_To_NAD83(double *lat, double *lon, double E, + double N, int32 zone, char zc); + +int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double *E, + double *N, int32 *zone, char *zc, const int n); +int32 GPS_Math_UTM_EN_To_Known_Datum(double *lat, double *lon, double E, + double N, int32 zone, char zc, const int n); + +int32 GPS_Math_WGS84_To_CH1903_NGEN(double phi, double lambda, double *E, double *N); +void GPS_Math_CH1903_NGEN_To_WGS84(double E, double N, double *lat, double *lon); + +int32 GPS_Math_LatLon_To_OM_EN(double phi, double lambda, double *E, double *N, + double phiC, double lambdaC, double azmC, double gammaC, + const double kC, const double FE, const double FN, + const double a, const double invf, + const char hotine, const char degrees); +void GPS_Math_OM_EN_To_LatLon(const double E, const double N, double *phi, double *lambda, + double phiC, double lambdaC, double azmC, double gammaC, + const double kC, const double FE, const double FN, + const double a, const double invf, + const char hotine, const char degrees); + +int32 GPS_Lookup_Datum_Index(const char *n); +char *GPS_Math_Get_Datum_Name(const int datum_index); + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsmem.c b/jeeps/gpsmem.c new file mode 100644 index 000000000..47b3be329 --- /dev/null +++ b/jeeps/gpsmem.c @@ -0,0 +1,341 @@ +/******************************************************************** +** @source JEEPS constructor and deconstructor functions +** +** @author Copyright (C) 1999,2000 Alan Bleasby +** @version 1.0 +** @modified December 28th 1999 Alan Bleasby. First version +** @modified June 29th 2000 Alan Bleasby. NMEA additions +** @modified Copyright (C) 2006 Robert Lipe +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include +#include +#include +#include + +/* @func GPS_Packet_New *********************************************** +** +** Packet constructor +** +** @return [GPS_PPacket] virgin packet +**********************************************************************/ + +GPS_PPacket GPS_Packet_New(void) +{ + GPS_PPacket ret; + int hdr_size = sizeof(GPS_OPacket) ; + if(!(ret=(GPS_PPacket )calloc(1, hdr_size))) + + { + perror("malloc"); + fprintf(stderr,"GPS_Packet_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + if(!(ret->data = (UC *)calloc(1, MAX_GPS_PACKET_SIZE*sizeof(UC)))) + { + perror("malloc"); + fprintf(stderr,"GPS_Packet_New: Insufficient data memory"); + fflush(stderr); + return NULL; + } + + ret->dle = ret->edle = DLE; + ret->etx = ETX; + + return ret; +} + + +/* @func GPS_Packet_Del *********************************************** +** +** Packet destructor +** +** @param [w] thys [GPS_PPacket *] packet to delete +** +** @return [void] +**********************************************************************/ + +void GPS_Packet_Del(GPS_PPacket *thys) +{ + free((void *)(*thys)->data); + free((void *)*thys); + + return; +} + + + +/* @func GPS_Pvt_New *********************************************** +** +** Pvt constructor +** +** @return [GPS_PPvt_Data] virgin pvt +**********************************************************************/ + +GPS_PPvt_Data GPS_Pvt_New(void) +{ + GPS_PPvt_Data ret; + + if(!(ret=(GPS_PPvt_Data)calloc(1, sizeof(GPS_OPvt_Data)))) + { + perror("malloc"); + fprintf(stderr,"GPS_Pvt_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + return ret; +} + + + +/* @func GPS_Pvt_Del *********************************************** +** +** Pvt destructor +** +** @param [w] thys [GPS_PPvt_Data *] pvt to delete +** +** @return [void] +**********************************************************************/ + +void GPS_Pvt_Del(GPS_PPvt_Data *thys) +{ + free((void *)*thys); + + return; +} + + + +/* @func GPS_Almanac_New *********************************************** +** +** Almanac constructor +** +** @return [GPS_PAlmanac] virgin almanac +**********************************************************************/ + +GPS_PAlmanac GPS_Almanac_New(void) +{ + GPS_PAlmanac ret; + + if(!(ret=(GPS_PAlmanac)calloc(1, sizeof(GPS_OAlmanac)))) + { + perror("malloc"); + fprintf(stderr,"GPS_Almanac_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + ret->svid=0xff; + ret->wn = -1; + ret->hlth=0xff; + + return ret; +} + + + +/* @func GPS_Almanac_Del *********************************************** +** +** Almanac destructor +** +** @param [w] thys [GPS_PAlmanac *] almanac to delete +** +** @return [void] +**********************************************************************/ + +void GPS_Almanac_Del(GPS_PAlmanac *thys) +{ + free((void *)*thys); + + return; +} + + + +/* @func GPS_Track_New *********************************************** +** +** Track constructor +** +** @return [GPS_PTrack] virgin track +**********************************************************************/ + +GPS_PTrack GPS_Track_New(void) +{ + GPS_PTrack ret; + + if(!(ret=(GPS_PTrack)calloc(1,sizeof(GPS_OTrack)))) + { + perror("malloc"); + fprintf(stderr,"GPS_Track_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + return ret; +} + + + +/* @func GPS_Track_Del *********************************************** +** +** Track destructor +** +** @param [w] thys [GPS_PTrack *] track to delete +** +** @return [void] +**********************************************************************/ + +void GPS_Track_Del(GPS_PTrack *thys) +{ + free((void *)*thys); + + return; +} + + + +/* @func GPS_Way_New *********************************************** +** +** Waypoint constructor +** +** @return [GPS_PWay] virgin waypoint +**********************************************************************/ + +GPS_PWay GPS_Way_New(void) +{ + GPS_PWay ret; + int32 i; + + if(!(ret=(GPS_PWay)xcalloc(sizeof(GPS_OWay),1))) + { + perror("malloc"); + fprintf(stderr,"GPS_Way_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + /* + * It turns out that the Way struct, initialized with zeros (not the + * random stuff that we got with malloc, but REALLY initialized with + * zeros from the calloc above actually does use C strings and it's + * up to the various way_blah_send functions to zero/string pad things + * as it goes. So neutralize this. + */ +#if 0 + + /* + * Mark all as "unused". These appear in the same order as in the struct. + */ +#define BLANK(x) memset(x, ' ',sizeof(x)) + BLANK(ret->ident); + BLANK(ret->cmnt); + BLANK(ret->wpt_ident); + BLANK(ret->lnk_ident); + BLANK(ret->subclass); + BLANK(ret->name); + BLANK(ret->facility); + BLANK(ret->addr); + BLANK(ret->cross_road); + BLANK(ret->city); + BLANK(ret->rte_cmnt); + BLANK(ret->rte_ident); + BLANK(ret->rte_link_subclass); + BLANK(ret->rte_link_ident); + BLANK(ret->state); + BLANK(ret->cc); + + ret->facility[0] = 0; + ret->addr[0] = 0; + ret->wpt_ident[0] = 0; +#endif + + ret->lat = ret->lon = GPS_FLTMAX; + ret->dst = 0; + ret->smbl = ret->dspl = ret->colour = ret->alt = ret->prot = INT_MAX; + + if(gps_waypt_type==pD108) + { + ret->dst = 0; + ret->attr = 0x60; + for(i=0;i<7;++i) ret->subclass[i] = 0; + for(i=6;i<18;++i) ret->subclass[i] = 0xff; + } + + return ret; +} + + + +/* @func GPS_Way_Del *********************************************** +** +** Waypoint destructor +** +** @param [w] thys [GPS_Pway *] waypoint to delete +** +** @return [void] +**********************************************************************/ + +void GPS_Way_Del(GPS_PWay *thys) +{ + xfree((void *)*thys); + + return; +} + +/* @func GPS_Lap_New *********************************************** +** +** Lap constructor +** +** @return [GPS_PLap] virgin track +**********************************************************************/ + +GPS_PLap GPS_Lap_New(void) +{ + GPS_PLap ret; + + if(!(ret=(GPS_PLap)calloc(1,sizeof(GPS_OLap)))) + { + perror("malloc"); + fprintf(stderr,"GPS_Lap_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + return ret; +} + + + +/* @func GPS_Lap_Del *********************************************** +** +** Lap destructor +** +** @param [w] thys [GPS_PLap *] track to delete +** +** @return [void] +**********************************************************************/ + +void GPS_Lap_Del(GPS_PLap *thys) +{ + free((void *)*thys); + + return; +} diff --git a/jeeps/gpsmem.h b/jeeps/gpsmem.h new file mode 100644 index 000000000..2f5bbc2ce --- /dev/null +++ b/jeeps/gpsmem.h @@ -0,0 +1,29 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsmem_h +#define gpsmem_h + + +#include "gps.h" + +GPS_PPacket GPS_Packet_New(void); +void GPS_Packet_Del(GPS_PPacket *thys); +GPS_PPvt_Data GPS_Pvt_New(void); +void GPS_Pvt_Del(GPS_PPvt_Data *thys); +GPS_PAlmanac GPS_Almanac_New(void); +void GPS_Almanac_Del(GPS_PAlmanac *thys); +GPS_PTrack GPS_Track_New(void); +void GPS_Track_Del(GPS_PTrack *thys); +GPS_PWay GPS_Way_New(void); +void GPS_Way_Del(GPS_PWay *thys); +GPS_PLap GPS_Lap_New(void); +void GPS_Lap_Del(GPS_PLap *thys); + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsport.h b/jeeps/gpsport.h new file mode 100644 index 000000000..dd23cc401 --- /dev/null +++ b/jeeps/gpsport.h @@ -0,0 +1,15 @@ +/* + * For portability any '32' type must be 32 bits + * and '16' type must be 16 bits + */ + +/* Since GPSBabel already has an integer size abstraction layer and + * defs.h includes gbtypes.h before this file, just use that. + */ + +typedef unsigned char UC; +typedef gbuint16 US; +typedef gbuint16 uint16; +typedef gbint16 int16; +typedef gbuint32 uint32; +typedef gbint32 int32; diff --git a/jeeps/gpsproj.c b/jeeps/gpsproj.c new file mode 100644 index 000000000..c2634b370 --- /dev/null +++ b/jeeps/gpsproj.c @@ -0,0 +1,4485 @@ +/******************************************************************** +** @source JEEPS projection functions +** +** @author Copyright (C) 1999 Alan Bleasby +** @version 1.0 +** @modified Feb 04 2000 Alan Bleasby. First version +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include +#include + + +/* @func GPS_Math_Albers_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Albers projection easting and +** northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi1 [double] standard latitude (parallel) 1 (deg) +** @param [r] phi2 [double] standard latitude (parallel) 2 (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Albers_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b) + +{ + double dlambda; + double phis; + double phic; + double e; + double esq; + double esqs; + double omesqs2; + + double a2; + double b2; + double q; + double q0; + double q1; + double q2; + double m1; + double m2; + double n; + double phi0s; + double phi1s; + double phi1c; + double phi2s; + double phi2c; + double ess; + double om0; + double m1sq; + double C; + double nq; + double nq0; + double rho; + double rho0; + double theta; + + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi1 = GPS_Math_Deg_To_Rad(phi1); + phi2 = GPS_Math_Deg_To_Rad(phi2); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + dlambda = lambda - M0; + if(dlambda > GPS_PI) + dlambda -= ((double)2.0 * GPS_PI); + if(dlambda < -GPS_PI) + dlambda += ((double)2.0 * GPS_PI); + + phis = sin(phi); + phic = cos(phi); + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + + phi0s = sin(phi0); + ess = e * phi0s; + om0 = ((double)1.0 - ess*ess); + q0 = ((double)1.0 - esq) * (phi0s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + om0 = ((double)1.0 - ess*ess); + m1 = phi1c/pow(om0,(double)0.5); + q1 = ((double)1.0 - esq) * (phi1s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + + m1sq = m1*m1; + if(fabs(phi1-phi2)>1.0e-10) + { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + om0 = ((double)1.0 - ess*ess); + m2 = phi2c/pow(om0,(double)0.5); + q2 = ((double)1.0 - esq) * (phi2s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + n = (m1sq - m2*m2) / (q2-q1); + } + else + n = phi1s; + + C = m1sq + n*q1; + nq0 = n * q0; + if(C < nq0) + rho0 = (double)0.; + else + rho0 = (a/n) * pow(C-nq0,(double)0.5); + + + esqs = e * phis; + omesqs2 = ((double)1.0 - esqs*esqs); + q = ((double)1.0 - esq) * (phis / omesqs2-((double)1.0/(e+e)) * + log(((double)1.0-esqs)/((double)1.0+esqs))); + nq = n*q; + if(C1.0e-10) + { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + om0 = ((double)1.0 - ess*ess); + m2 = phi2c/pow(om0,(double)0.5); + q2 = ((double)1.0 - esq) * (phi2s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + n = (m1sq - m2*m2) / (q2-q1); + } + else + n = phi1s; + + C = m1sq + n*q1; + nq0 = n * q0; + if(C < nq0) + rho0 = (double)0.; + else + rho0 = (a/n) * pow(C-nq0,(double)0.5); + + + dphi = (double) 1.0; + theta = (double) 0.0; + tol = (double) 4.85e-10; + po2 = (double)GPS_PI / (double)2.0; + + dy = N-N0; + dx = E-E0; + rhom = rho0-dy; + rho = pow(dx*dx+rhom*rhom,(double)0.5); + + if(n<0.0) + { + rho *= (double)-1.0; + dx *= (double)-1.0; + dy *= (double)-1.0; + rhom *= (double)-1.0; + } + + if(rho) + theta = atan2(dx,rhom); + rhon = rho*n; + q = (C - (rhon*rhon) / a2) / n; + qc = (double)1.0 - ((double)1.0 / (e+e)) * + log(((double)1.0-e)/((double)1.0+e)); + if(fabs(fabs(qc)-fabs(q))>1.9e-6) + { + qd2 = q/(double)2.0; + if(qd2>1.0) + *phi = po2; + else if(qd2<-1.0) + *phi = -po2; + else + { + lat = asin(qd2); + if(e<1.0e-10) + *phi = lat; + else + { + while(fabs(dphi)>tol) + { + phis = sin(lat); + ess = e*phis; + om0 = ((double)1.0 - ess*ess); + dphi = (om0*om0) / ((double)2.0*cos(lat))* + (q/((double)1.0-esq) - phis / om0 + + (log(((double)1.0-ess)/((double)1.0+ess)) / + (e+e))); + lat += dphi; + } + *phi = lat; + } + + if(*phi > po2) + *phi = po2; + else if(*phi<-po2) + *phi = -po2; + } + } + else + { + if(q>=0.0) + *phi = po2; + else + *phi = -po2; + } + + *lambda = M0 + theta / n; + if(*lambda > GPS_PI) + *lambda -= GPS_PI * (double)2.0; + if(*lambda < -GPS_PI) + *lambda += GPS_PI * (double)2.0; + if(*lambda>GPS_PI) + *lambda = GPS_PI; + else if(*lambda<-GPS_PI) + *lambda = -GPS_PI; + + *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + + return; +} + + + +/* @func GPS_Math_LambertCC_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Lambert Conformal Conic projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi1 [double] standard latitude (parallel) 1 (deg) +** @param [r] phi2 [double] standard latitude (parallel) 2 (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b) + +{ + double po2; + double po4; + double a2; + double b2; + double phi0s; + double e; + double esq; + double ed2; + double ess; + double t0; + double t1; + double t2; + double m1; + double m2; + double phi1s; + double phi1c; + double phi2s; + double phi2c; + double n; + double F; + double Fa; + double rho; + double rho0; + double phis; + double t; + double theta; + double dphi; + + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi1 = GPS_Math_Deg_To_Rad(phi1); + phi2 = GPS_Math_Deg_To_Rad(phi2); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + + po2 = (double)GPS_PI / (double)2.0; + po4 = (double)GPS_PI / (double)4.0; + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + ed2 = e / (double)2.0; + + phi0s = sin(phi0); + ess = e * phi0s; + t0 = tan(po4-phi0/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + m1 = phi1c / pow(((double)1.0-ess*ess),(double)0.5); + t1 = tan(po4-phi1/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + if(fabs(phi1-phi2)>1.0e-10) + { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + m2 = phi2c / pow(((double)1.0-ess*ess),(double)0.5); + t2 = tan(po4-phi2/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + n = log(m1/m2) / log(t1/t2); + } + else + n = phi1s; + + F = m1 / (n*pow(t1,n)); + Fa = F*a; + + rho0 = pow(t0,n) * Fa; + + if(fabs(fabs(phi)-po2)>1.0e-10) + { + phis = sin(phi); + ess = e * phis; + t = tan(po4-phi/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + rho = pow(t,n) * Fa; + } + else + { + if((phi*n)<=(double)0.0) + return; + rho = (double)0.0; + } + + dphi = lambda - M0; + if(dphi>GPS_PI) + dphi -= (double)GPS_PI * (double)2.0; + if(dphi<-GPS_PI) + dphi += (double)GPS_PI * (double)2.0; + theta = dphi*n; + + *E = rho * sin(theta) + E0; + *N = rho0 - rho * cos(theta) + N0; + + return; +} + + + + +/* @func GPS_Math_LambertCC_EN_To_LatLon ********************************** +** +** Convert Lambert Conformal Conic easting and northing to latitude and +** longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi1 [double] standard latitude (parallel) 1 (deg) +** @param [r] phi2 [double] standard latitude (parallel) 2 (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b) +{ + double po2; + double po4; + double a2; + double b2; + double phi0s; + double e; + double esq; + double ed2; + double ess; + double t0; + double t1; + double t2; + double m1; + double m2; + double phi1s; + double phi1c; + double phi2s; + double phi2c; + double n; + double F; + double Fa; + double rho; + double rho0; + double phis; + double t; + double theta; + + double dx; + double dy; + double rhom; + double lat; + double tlat; + double tol; + + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi1 = GPS_Math_Deg_To_Rad(phi1); + phi2 = GPS_Math_Deg_To_Rad(phi2); + M0 = GPS_Math_Deg_To_Rad(M0); + + + po2 = (double)GPS_PI / (double)2.0; + po4 = (double)GPS_PI / (double)4.0; + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + ed2 = e / (double)2.0; + + phi0s = sin(phi0); + ess = e * phi0s; + t0 = tan(po4-phi0/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + m1 = phi1c / pow(((double)1.0-ess*ess),(double)0.5); + t1 = tan(po4-phi1/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + if(fabs(phi1-phi2)>1.0e-10) + { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + m2 = phi2c / pow(((double)1.0-ess*ess),(double)0.5); + t2 = tan(po4-phi2/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + n = log(m1/m2) / log(t1/t2); + } + else + n = phi1s; + + F = m1 / (n*pow(t1,n)); + Fa = F*a; + + rho0 = pow(t0,n) * Fa; + + tlat = theta = (double)0.0; + tol = (double)4.85e-10; + + dx = E - E0; + dy = N - N0; + rhom = rho0 - dy; + rho = pow(dx*dx + rhom*rhom,(double)0.5); + + if(n<0.0) + { + rhom *= (double)-1.0; + dy *= (double)-1.0; + dx *= (double)-1.0; + rho *= (double)-1.0; + } + + if(rho) + { + theta = atan2(dx,rhom); + t = pow(rho/Fa,(double)1.0/n); + lat = po2 - (double)2.0*atan(t); + while(fabs(lat-tlat)>tol) + { + tlat = lat; + phis = sin(lat); + ess = e * phis; + lat = po2 - (double)2.0 * atan(t*pow(((double)1.0-ess) / + ((double)1.0+ess), + e / (double)2.0)); + } + *phi = lat; + *lambda = theta/n + M0; + + if(*phi>po2) + *phi=po2; + else if(*phi<-po2) + *phi=-po2; + if(*lambda>GPS_PI) + *lambda -= (double)GPS_PI * (double)2.0; + if(*lambda<-GPS_PI) + *lambda += (double)GPS_PI * (double)2.0; + + if(*lambda>GPS_PI) + *lambda = GPS_PI; + else if(*lambda<-GPS_PI) + *lambda = -GPS_PI; + } + else + { + if(n>0.0) + *phi = po2; + else + *phi = -po2; + *lambda = M0; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_Miller_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Miller Cylindrical projection easting and +** northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b) +{ + double a2; + double b2; + double R; + double e2; + double e4; + double e6; + double p2; + double po2; + double phis; + double dlam; + + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + R = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + + if(M0>GPS_PI) + M0 -= p2; + + phis = sin((double)0.8 * phi); + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam-=p2; + if(dlam<-GPS_PI) + dlam+=p2; + + *E = R*dlam+E0; + *N = (R/(double)1.6) * log(((double)1.0+phis) / ((double)1.0-phis)) + N0; + + return; +} + + + + +/* @func GPS_Math_Miller_EN_To_LatLon ********************************** +** +** Convert latitude and longitude to Miller Cylindrical projection easting and +** northing +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Miller_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b) +{ + double a2; + double b2; + double R; + double e; + double e2; + double e4; + double e6; + double p2; + double po2; + double dx; + double dy; + + dx = E - E0; + dy = N - N0; + + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + e = pow(e2,(double)0.5); + + R = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + if(M0>GPS_PI) + M0 -= p2; + + *phi = atan(sinh((double)0.8*dy/R)) / (double)0.8; + *lambda = M0+dx/R; + + if(*phi>po2) + *phi=po2; + else if (*phi<-po2) + *phi=-po2; + + if(*lambda>GPS_PI) + *lambda-=p2; + if(*lambda<-GPS_PI) + *lambda+=p2; + + if(*lambda>GPS_PI) + *lambda=GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_Bonne_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Bonne pseudoconic equal area projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Bonne_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, double E0, + double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double M1; + double m1; + double c0; + double c1; + double c2; + double c3; + double j; + double te4; + double E1; + double E2; + double E3; + double E4; + double x; + double phi0s; + double lat; + double phi0c; + double phi0s2; + double phi0s4; + double phi0s6; + double as; + + double phis; + double phic; + double phis2; + double phis4; + double phis6; + double dlam; + double mm; + double MM; + double rho; + double EE; + double tol; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + phi0s = sin(phi0); + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(M0>GPS_PI) + M0 -= p2; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + phi0c = cos(phi0); + m1 = phi0c/ pow(((double)1.0-e2*phi0s*phi0s),(double)0.5); + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + M1 = a*(lat-phi0s2+phi0s4-phi0s6); + + x = pow((double)1.0-e2,(double)0.5); + E1 = ((double)1.0-x) / ((double)1.0+x); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + + if(!phi0s) + as = (double)0.0; + else + as = a*m1/phi0s; + + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + + phis = sin(phi); + phic = cos(phi); + + tol = (double)0.0001; + if(!(phi-phi0) && (((po2-tol)GPS_PI) + M0 -= p2; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + phi0c = cos(phi0); + m1 = phi0c/ pow(((double)1.0-e2*phi0s*phi0s),(double)0.5); + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + M1 = a*(lat-phi0s2+phi0s4-phi0s6); + + x = pow((double)1.0-e2,(double)0.5); + E1 = ((double)1.0-x) / ((double)1.0+x); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + A0 = (double)3.0*E1/(double)2.0-(double)27.0*E3/(double)32.0; + A1 = (double)21.0*E2/(double)16.0-(double)55.0*E4/(double)32.0; + A2 = (double)151.0*E3/(double)96.0; + A3 = (double)1097.0*E4/(double)512.0; + if(!phi0s) + as = (double)0.0; + else + as = a*m1/phi0s; + + + dx = E - E0; + dy = N - N0; + asdy = as - dy; + rho = pow(dx*dx+asdy*asdy,(double)0.5); + if(phi0<(double)0.0) + rho=-rho; + MM = as+M1-rho; + + mu = MM / (a*c0); + smu2 = A0 * sin((double)2.0*mu); + smu4 = A1 * sin((double)4.0*mu); + smu6 = A2 * sin((double)6.0*mu); + smu8 = A3 * sin((double)8.0*mu); + *phi = mu+smu2+smu4+smu6+smu8; + + tol = (double)0.00001; + if(((po2-tol)po2) + *phi = po2; + else if(*phi<-po2) + *phi = -po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda = GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_Cassini_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Cassini transverse cylindrical projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, + double E0, double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double AM0; + double c0; + double c1; + double c2; + double c3; + double om0; + double A0; + double A1; + double A2; + double A3; + double j; + double te4; + double phi0s2; + double phi0s4; + double phi0s6; + double lat; + double x; + double E1; + double E2; + double E3; + double E4; + + double phis; + double phic; + double phit; + double phis2; + double phis4; + double phis6; + double RD; + double dlam; + double NN; + double TT; + double WW; + double WW2; + double WW3; + double WW4; + double WW5; + double CC; + double MM; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + te4 = (double)3.0 * e4; + j = (double)45. * e6 / (double)1024.; + c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; + c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + + lat = c0*phi0; + phi0s2 = c1 * sin((double)2.*phi0); + phi0s4 = c2 * sin((double)4.*phi0); + phi0s6 = c3 * sin((double)6.*phi0); + AM0 = a * (lat-phi0s2+phi0s4-phi0s6); + + om0 = (double)1.0 - e2; + x = pow(om0,(double)0.5); + E1 = ((double)1.0 - x) / ((double)1.0 + x); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + + phis = sin(phi); + phic = cos(phi); + phit = tan(phi); + RD = pow((double)1.-e2*phis*phis,(double).5); + NN = a/RD; + TT = phit*phit; + WW = dlam*phic; + WW2 = WW*WW; + WW3 = WW*WW2; + WW4 = WW*WW3; + WW5 = WW*WW4; + CC = e2*phic*phic/om0; + lat = c0*phi; + phis2 = c1 * sin((double)2.*phi); + phis4 = c2 * sin((double)4.*phi); + phis6 = c3 * sin((double)6.*phi); + MM = a * (lat-phis2+phis4-phis6); + + *E = NN*(WW-(TT*WW3/(double)6.)-((double)8.-TT+(double)8.*CC)* + (TT*WW5/(double)120.)) + E0; + *N = MM-AM0+NN*phit*((WW2/(double)2.)+((double)5.-TT+(double)6.*CC) * + WW4/(double)24.) + N0; + return; +} + + + + +/* @func GPS_Math_Cassini_EN_To_LatLon ********************************** +** +** Convert Cassini transverse cylindrical easting and northing projection +** to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) + +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double AM0; + double c0; + double c1; + double c2; + double c3; + double om0; + double A0; + double A1; + double A2; + double A3; + double j; + double te4; + double phi0s2; + double phi0s4; + double phi0s6; + double lat; + double x; + double E1; + double E2; + double E3; + double E4; + + double dx; + double dy; + double mu; + double mus2; + double mus4; + double mus6; + double mus8; + double M1; + double phi1; + double phi1s; + double phi1c; + double phi1t; + double T; + double T1; + double N1; + double R1; + double RD; + double DD; + double D2; + double D3; + double D4; + double D5; + double tol; + + M0 = GPS_Math_Deg_To_Rad(M0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + te4 = (double)3.0 * e4; + j = (double)45. * e6 / (double)1024.; + c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; + c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + + lat = c0*phi0; + phi0s2 = c1 * sin((double)2.*phi0); + phi0s4 = c2 * sin((double)4.*phi0); + phi0s6 = c3 * sin((double)6.*phi0); + AM0 = a * (lat-phi0s2+phi0s4-phi0s6); + + om0 = (double)1.0 - e2; + x = pow(om0,(double)0.5); + E1 = ((double)1.0 - x) / ((double)1.0 + x); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + + + tol = (double)1.e-5; + + dx = E - E0; + dy = N - N0; + M1 = AM0 + dy; + mu = M1 / (a*c0); + mus2 = A0 * sin((double)2.*mu); + mus4 = A1 * sin((double)4.*mu); + mus6 = A2 * sin((double)6.*mu); + mus8 = A3 * sin((double)8.*mu); + phi1 = mu + mus2 + mus4 + mus6 + mus8; + + if((((po2-tol)po2) + *phi=po2; + else if(*phi<-po2) + *phi=-po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda=GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_Cylea_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Cylindrical equal area projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, + double E0, double N0, double a, double b) +{ + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double k0; + double ak0; + double k2; + double c0; + double c1; + double c2; + double p2; + double po2; + double phi0s; + double phi0c; + + double dlam; + double qq; + double x; + double phis; + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if(M0>GPS_PI) + M0-=p2; + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + c0 = e2/(double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + c1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + c2 = (double)761.*e6/(double)45360.; + + phi0s = sin(phi0); + phi0c = cos(phi0); + k0 = phi0c / pow((double)1.-e2*phi0s*phi0s,(double).5); + ak0 = a*k0; + k2 = k0 * (double)2.; + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam-=p2; + if(dlam<-GPS_PI) + dlam+=p2; + + phis = sin(phi); + x = e * phis; + qq = ((double)1.-e2)*(phis/((double)1.-x*x)-((double)1./((double)2.*e))* + log(((double)1.-x)/((double)1.+x))); + *E = ak0 * dlam + E0; + *N = a * qq / k2 + N0; + + return; +} + + + + +/* @func GPS_Math_Cylea_EN_To_LatLon ********************************** +** +** Convert Cylindrical equal area easting and northing projection +** to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) + +{ + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double k0; + double ak0; + double k2; + double c0; + double c1; + double c2; + double p2; + double po2; + double phi0s; + double phi0c; + + double dx; + double dy; + double qp; + double bt; + double phis; + double i; + double x; + double bs2; + double bs4; + double bs6; + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if(M0>GPS_PI) + M0-=p2; + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + c0 = e2/(double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + c1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + c2 = (double)761.*e6/(double)45360.; + + phi0s = sin(phi0); + phi0c = cos(phi0); + k0 = phi0c / pow((double)1.-e2*phi0s*phi0s,(double).5); + ak0 = a*k0; + k2 = k0 * (double)2.; + + dx = E - E0; + dy = N - N0; + phis = sin(po2); + x = e*phis; + qp = ((double)1.-e2)*(phis/((double)1.-x*x)-((double)1./((double)2.*e))* + log(((double)1.-x)/((double)1.+x))); + i = k2*dy/(a*qp); + if(i>(double)1.) + i=(double)1.; + else if(i<(double)-1.) + i=(double)-1.; + bt = asin(i); + bs2 = c0 * sin((double)2.*bt); + bs4 = c1 * sin((double)4.*bt); + bs6 = c2 * sin((double)6.*bt); + + *phi = bt+bs2+bs4+bs6; + *lambda = M0 + dx/ak0; + + if(*phi>po2) + *phi=po2; + else if(*phi<-po2) + *phi=-po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda=GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_EckertIV_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Eckert IV equal area elliptical +** pseudocylindrical projection easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, double N0, + double a, double b) +{ + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra0; + double Ra1; + double po2; + double p2; + + double Ra; + + double phis; + double theta; + double dtheta; + double thetas; + double thetac; + double n; + double dlam; + double tol; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if(M0>GPS_PI) + M0-=p2; + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Ra0 = Ra * (double)0.4222382; + Ra1 = Ra * (double)1.3265004; + + theta = phi / (double)2.; + dtheta = (double)1.; + tol = (double)4.85e-10; + phis = sin(phi); + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + + while(fabs(dtheta)>tol) + { + thetas = sin(theta); + thetac = cos(theta); + n = theta+thetas*thetac+(double)2.*thetas; + dtheta = -(n-((double)2.+po2)*phis) / + ((double)2.*thetac*((double)1.+thetac)); + theta += dtheta; + } + + *E = Ra0*dlam*((double)1.+cos(theta))+E0; + *N = Ra1*sin(theta)+N0; + + return; +} + + + + +/* @func GPS_Math_EckertIV_EN_To_LatLon ********************************** +** +** Convert Eckert IV equal area elliptical pseudocylindrical projection +** easting and northing to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b) +{ + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra0; + double Ra1; + double po2; + double p2; + + double Ra; + double theta; + double thetas; + double thetac; + double n; + double dx; + double dy; + double i; + + + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if(M0>GPS_PI) + M0-=p2; + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Ra0 = Ra * (double)0.4222382; + Ra1 = Ra * (double)1.3265004; + + dx = E - E0; + dy = N - N0; + i = dy/Ra1; + if(i>(double)1.) + i=(double)1.; + else if(i<(double)-1.) + i=(double)-1.; + + theta = asin(i); + thetas = sin(theta); + thetac = cos(theta); + n = theta+thetas*thetac+(double)2.*thetas; + + *phi = asin(n/((double)2. + po2)); + *lambda = M0 + dx / (Ra0*((double)1.+thetac)); + + if(*phi>po2) + *phi=po2; + else if(*phi<-po2) + *phi=-po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda=GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + + +/* @func GPS_Math_EckertVI_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Eckert VI equal area +** pseudocylindrical projection easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, double N0, + double a, double b) +{ + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double Rsq; + double IRa; + double po2; + double p2; + + double phis; + double theta; + double dtheta; + double dlam; + double tol; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if(M0>GPS_PI) + M0-=p2; + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Rsq = Ra/pow((double)2.+GPS_PI,(double).5); + IRa = (double)1./Rsq; + + phis = sin(phi); + theta = phi; + dtheta = (double)1.; + tol = (double)4.85e-10; + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + + while(fabs(dtheta)>tol) + { + dtheta = -(theta+sin(theta)-((double)1.+po2)*phis) / + ((double)1.+cos(theta)); + theta += dtheta; + } + + *E = Rsq*dlam*((double)1.+cos(theta))+E0; + *N = (double)2.*Rsq*theta+N0; + + return; +} + + + + +/* @func GPS_Math_EckertVI_EN_To_LatLon ********************************** +** +** Convert Eckert VI equal area pseudocylindrical projection +** easting and northing to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b) +{ + double a2; + double b2; + double e2; + double e4; + double e6; + double Rsq; + double IRa; + double po2; + double p2; + + double Ra; + double theta; + double dx; + double dy; + double i; + + + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if(M0>GPS_PI) + M0-=p2; + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Rsq = Ra/pow((double)2.+GPS_PI,(double).5); + IRa = (double)1./Rsq; + + + dx = E - E0; + dy = N - N0; + theta = IRa * dy / (double)2.; + i = (theta+sin(theta)) / ((double)1.+po2); + if(i>(double)1.) + *phi = po2; + else if(i<(double)-1.) + *phi = -po2; + else + *phi= asin(i); + *lambda = M0 + IRa * dx / ((double)1.+cos(theta)); + + if(*phi>po2) + *phi=po2; + else if(*phi<-po2) + *phi=-po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda=GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + + +/* @func GPS_Math_Cyled_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to cylindrical equidistant projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, double E0, + double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double Rac; + double phi0c; + + double dlam; + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(M0>GPS_PI) + M0 -= p2; + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + phi0c = cos(phi0); + Rac = Ra * phi0c; + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + + *E = Rac * dlam + E0; + *N = Ra * phi + N0; + + return; +} + + + + +/* @func GPS_Math_Cyled_EN_To_LatLon ********************************** +** +** Convert cylindrical equidistant easting and northing projection +** to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double Rac; + double phi0c; + + double dx; + double dy; + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(M0>GPS_PI) + M0 -= p2; + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + phi0c = cos(phi0); + Rac = Ra * phi0c; + + dx = E - E0; + dy = N - N0; + + if(!Rac) + *lambda = (double)0.; + else + *lambda = M0 + dx / Rac; + + *phi = dy/Ra; + + if(*phi>po2) + *phi = po2; + else if(*phi<-po2) + *phi = -po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda = GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_VderGrinten_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Van der Grinten polyconic projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b) +{ + double po2; + double p2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double pRa; + + double gg; + double pp; + double pp2; + double gm0; + double ppa; + double thetai; + double theta; + double thetas; + double thetac; + double qq; + double tol; + double aa; + double aa2; + double dlam; + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(M0>GPS_PI) + M0 -= p2; + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + pRa = (double)GPS_PI * Ra; + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + + tol = (double)1.0e-5; + + if(!phi) + { + *N = (double)0.0; + *E = Ra*dlam+E0; + } + else if(!dlam || (((po2-tol)(double)1.) + thetai=(double)1.; + else if(thetai<(double)-1.) + thetai=(double)-1.; + + theta = asin(thetai); + *E = 0; + *N = pRa * tan(theta/(double)2.) * N0; + if(phi<(double)0.0) + *N *= (double)-1.; + } + else + { + aa = (double).5*fabs((double)GPS_PI/dlam - dlam/(double)GPS_PI); + thetai = fabs(((double)2./(double)GPS_PI) * phi); + if(thetai>(double)1.) + thetai=(double)1.; + else if(thetai<(double)-1.) + thetai=(double)-1.; + + theta = asin(thetai); + thetas = sin(theta); + thetac = cos(theta); + gg = thetac/(thetas+thetac-(double)1.); + pp = gg*((double)2./thetas-(double)1.); + aa2 = aa*aa; + pp2 = pp*pp; + gm0 = gg-pp2; + ppa = pp2+aa2; + qq = aa2+gg; + *E = pRa*(aa*gm0+pow(aa2*gm0*gm0-ppa*(gg*gg-pp2),(double).5))/ppa+E0; + if(dlam<(double)0.0) + *E *= (double)-1.; + *N = pRa*(pp*qq-aa*pow((aa2+(double)1.)*ppa-qq*qq,(double).5))/ppa+N0; + if(phi<(double)0.0) + *N *= (double)-1.; + } + + return; +} + + + + +/* @func GPS_Math_VderGrinten_EN_To_LatLon ********************************** +** +** Convert Van der Grinten polyconic easting and northing projection +** to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b) +{ + double po2; + double p2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double pRa; + + double dx; + double dy; + double xx; + double xx2; + double yy; + double yy2; + double tyy2; + double xpy; + double c1; + double c2; + double c3; + double c3c3; + double co; + double dd; + double a1; + double m1; + double i; + double theta; + + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(M0>GPS_PI) + M0 -= p2; + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + pRa = (double)GPS_PI * Ra; + + + dx = E - E0; + dy = N - N0; + xx = dx/pRa; + yy = dy/pRa; + xx2 = xx*xx; + yy2 = yy*yy; + xpy = xx2+yy2; + tyy2 = yy2*(double)2.; + + if(!N) + *phi=(double)0.0; + else + { + c1 = -fabs(yy)*((double)1.+xpy); + c2 = c1-tyy2+xx2; + c3 = (double)-2.*c1+(double)1.+tyy2+xpy*xpy; + co = c2/((double)3.*c3); + c3c3 = c3*c3; + dd = yy2/c3+(((double)2.*c2*c2*c2)/(c3c3*c3)-((double)9.*c1*c2)/ + c3c3)/(double)27.; + a1 = (c1-c2*co)/c3; + m1 = (double)2.* pow(-((double)1./(double)3.)*a1,(double).5); + i = (double)3.*dd/(a1*m1); + if((i>(double)1.)||(i<(double)-1.)) + *phi=po2; + else + { + theta = ((double)1./(double)3.)*acos((double)3.*dd/(a1*m1)); + *phi = (double)GPS_PI*(-m1*cos(theta+(double)GPS_PI/(double)3.)- + co); + } + } + + if(N<(double)0.0) + *phi *= (double)-1.0; + + if(!xx) + *lambda = M0; + else + *lambda = (double)GPS_PI * (xpy-(double)1.+ + pow((double)1.+((double)2.*xx2-tyy2)+xpy*xpy,(double).5)) / + ((double)2.*xx) + M0; + if(*phi>po2) + *phi = po2; + else if(*phi<-po2) + *phi = -po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda = GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_Bonne_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Bonne pseudoconic equal area projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi1 [double] latitude of true scale (deg) +** @param [r] lambda1 [double] longitude from pole (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi1, double lambda1, + double E0, double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4=(double)0.; + double e; + double eo2; + double sh; + double mc; + double tc=(double)0.; + double amc=(double)0.; + double ta; + double phi1s; + double phi1c; + double es; + double op; + double om; + double pe; + double polat; + double polon; + + double dlam; + double phis; + double t; + double rho; + + + lambda1 = GPS_Math_Deg_To_Rad(lambda1); + phi1 = GPS_Math_Deg_To_Rad(phi1); + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + + ta = a * (double)2.0; + if(lambda1>GPS_PI) + lambda1 -= p2; + if(phi1<(double)0.0) + { + sh=(double)1.0; + polat = -phi1; + polon = -lambda1; + } + else + { + sh=(double)0.0; + polat = phi1; + polon = lambda1; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e = pow(e2,(double).5); + eo2 = e/(double)2.; + + if(fabs(fabs(polat)-po2)>(double)1.0e-10) + { + phi1s = sin(polat); + phi1c = cos(polat); + es = e*phi1s; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + mc = phi1c / pow((double)1.-es*es,(double).5); + amc = mc * a; + tc = tan(((double)GPS_PI/(double)4.)-polat/(double)2.) / pe; + } + else + { + op = (double)1. + e; + om = (double)1. - e; + e4 = pow(pow(op,op)*pow(om,om),(double).5); + } + + + + if(fabs(fabs(phi)-po2)<(double)1.0e-10) + *E = *N = (double)0.0; + else + { + if(sh) + { + phi *= (double)-1.0; + lambda *= (double)-1.0; + } + + dlam = lambda - polon; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + phis = sin(phi); + es = e * phis; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + t = tan(((double)GPS_PI/(double)4.)-phi/(double)2.) / pe; + + if(fabs(fabs(polat)-po2)>(double)1.0e-10) + rho = amc * t / tc; + else + rho = ta * t / e4; + *E = rho * sin(dlam) + E0; + + if(sh) + { + *E *= (double)-1.; + *N = rho * cos(dlam) + N0; + } + else + *N = -rho * cos(dlam) + N0; + } + + return; +} + + + + +/* @func GPS_Math_PolarSt_EN_To_LatLon ********************************** +** +** Convert Polar Stereographic easting and northing projection +** to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi1 [double] latitude of true scale (deg) +** @param [r] lambda1 [double] longitude from pole (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi1, double lambda1, + double E0, double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4=(double)0.; + double e; + double eo2; + double sh; + double mc; + double tc=(double)0.; + double amc=(double)0.; + double ta; + double phi1s; + double phi1c; + double es; + double op; + double om; + double pe; + double polat; + double polon; + + double dx; + double dy; + double t; + double rho; + double PHI; + double PHIS; + double TPHI; + + + lambda1 = GPS_Math_Deg_To_Rad(lambda1); + phi1 = GPS_Math_Deg_To_Rad(phi1); + + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + + ta = a * (double)2.0; + if(lambda1>GPS_PI) + lambda1 -= p2; + if(phi1<(double)0.0) + { + sh=(double)1.0; + polat = -phi1; + polon = -lambda1; + } + else + { + sh=(double)0.0; + polat = phi1; + polon = lambda1; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e = pow(e2,(double).5); + eo2 = e/(double)2.; + + if(fabs(fabs(polat)-po2)>(double)1.0e-10) + { + phi1s = sin(polat); + phi1c = cos(polat); + es = e*phi1s; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + mc = phi1c / pow((double)1.-es*es,(double).5); + amc = mc * a; + tc = tan(((double)GPS_PI/(double)4.)-polat/(double)2.) / pe; + } + else + { + op = (double)1. + e; + om = (double)1. - e; + e4 = pow(pow(op,op)*pow(om,om),(double).5); + } + + + dx = E - E0; + dy = N - N0; + if(!dx && !dy) + { + *phi = po2; + *lambda = polon; + } + else + { + if(sh) + { + dx *= (double)-1.; + dy *= (double)-1.; + } + rho = pow(dx*dx+dy*dy,(double).5); + if(fabs(fabs(polat)-po2)>(double)1.0e-10) + t = rho * tc / amc; + else + t = rho * e4 / ta; + TPHI = (double)0.0; + PHI = po2 - (double)2.*atan(t); + while(fabs(PHI-TPHI)>(double)1.0e-10) + { + TPHI=PHI; + PHIS = sin(PHI); + es = e * PHIS; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + PHI = po2 - (double)2. * atan(t*pe); + } + *phi = PHI; + *lambda = polon + atan2(dx,-dy); + + if(*phi>po2) + *phi = po2; + else if(*phi<-po2) + *phi = -po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda = GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + } + if(sh) + { + *phi *= (double)-1.; + *lambda *= (double)1.; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_Mollweide_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Mollweide projection easting and +** northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b) +{ + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double Ra; + double sRa2; + double sRa8; + + double ps; + double dlam; + double theta; + double thetap; + double d; + double tol; + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + Ra = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + sRa2 = pow((double)2.,(double).5) * Ra; + sRa8 = pow((double)8.,(double).5) * Ra; + + if(M0>GPS_PI) + M0 -= p2; + + ps = sin(phi) * (double)GPS_PI; + d = (double)0.1745329; + tol = (double)4.85e-10; + thetap = phi; + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam-=p2; + if(dlam<-GPS_PI) + dlam+=p2; + + while(fabs(d)>tol) + { + d = -(thetap+sin(thetap)-ps)/((double)1.+cos(thetap)); + thetap += d; + } + theta = thetap / (double)2.; + *E = (sRa8/(double)GPS_PI) * dlam * cos(theta) + E0; + *N = sRa2 * sin(theta) + N0; + + return; +} + + + + +/* @func GPS_Math_Mollweide_EN_To_LatLon ********************************** +** +** Convert latitude and longitude to Mollweide projection easting and +** northing +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b) +{ + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double Ra; + double sRa2; + double sRa8; + + double dx; + double dy; + double theta=(double)0.; + double tt; + double i; + + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + Ra = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + sRa2 = pow((double)2.,(double).5) * Ra; + sRa8 = pow((double)8.,(double).5) * Ra; + + if(M0>GPS_PI) + M0 -= p2; + + dx = E - E0; + dy = N - N0; + i = dy/sRa2; + if(fabs(i)>(double)1.) + { + *phi = po2; + if(N<(double)0.0) + *phi *= (double)-1.; + } + else + { + theta = asin(i); + tt = theta * (double)2.; + *phi = asin((tt+sin(tt))/(double)GPS_PI); + if(*phi>po2) + *phi=po2; + else if (*phi<-po2) + *phi=-po2; + } + + if(fabs(fabs(*phi)-po2)<(double)1.0e-10) + *lambda = M0; + else + *lambda = M0 + (double)GPS_PI * dx / (sRa8 * cos(theta)); + + + if(*lambda>GPS_PI) + *lambda-=p2; + if(*lambda<-GPS_PI) + *lambda+=p2; + + if(*lambda>GPS_PI) + *lambda=GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_Orthog_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to orthographic projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] lambda0 [double] longitude of origin (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double lambda0, + double E0, double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double phi0s; + double phi0c; + + double phis; + double phic; + double dlam; + double clc; + double cc; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(lambda0>GPS_PI) + lambda0 -= p2; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a * ((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + phi0s = sin(phi0); + phi0c = cos(phi0); + + dlam = lambda - lambda0; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + + + phis = sin(phi); + phic = cos(phi); + clc = phic * cos(dlam); + cc = phi0s * phis + phi0c * clc; + + *E = Ra * phic * sin(dlam) + E0; + *N = Ra * (phi0c * phis - phi0s * clc) + N0; + + return; +} + + + + +/* @func GPS_Math_Orthog_EN_To_LatLon ********************************** +** +** Convert Orthogonal easting and northing projection +** to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] lambda0 [double] longitude of origin (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double lambda0, + double E0, double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double phi0s; + double phi0c; + + double dx; + double dy; + double rho; + double adod; + double ror; + double cc; + double ccs; + double ccc; + + + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(lambda0>GPS_PI) + lambda0 -= p2; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a * ((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + phi0s = sin(phi0); + phi0c = cos(phi0); + + + dx = E - E0; + dy = N - N0; + adod = atan(dx/dy); + rho = pow(dx*dx+dy*dy,(double).5); + if(!rho) + { + *phi = phi0; + *lambda = lambda0; + } + else + { + ror = rho/Ra; + if(ror>(double)1.) + ror=(double)1.; + else if(ror<(double)-1.) + ror=(double)-1.; + cc = asin(ror); + ccs = sin(cc); + ccc = cos(cc); + *phi = asin(ccc*phi0s+(dy*ccs*phi0c/rho)); + if(phi0==po2) + *lambda = lambda0 - adod; + else if(phi0==-po2) + *lambda = lambda0 + adod; + else + *lambda = lambda0+atan(dx*ccs/(rho*phi0c*ccc-dy*phi0s*ccs)); + } + + if(*phi>po2) + *phi = po2; + else if(*phi<-po2) + *phi = -po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda = GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_Polycon_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Polyconic projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, + double E0, double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double AM0; + double c0; + double c1; + double c2; + double c3; + double j; + double te4; + double phi0s2; + double phi0s4; + double phi0s6; + + double phis; + double phis2; + double phis4; + double phis6; + double dlam; + double NN; + double NNot; + double MM; + double EE; + double lat; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(M0>GPS_PI) + M0 -= p2; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + + phis = sin(phi); + + if(!phi) + { + *E = a * dlam + E0; + *N = -AM0 + N0; + } + else + { + NN = a / pow((double)1.-e2*phis*phis,(double).5); + NNot = NN / tan(phi); + lat = c0 * phi; + phis2 = c1 * sin((double)2.0*phi); + phis4 = c2 * sin((double)4.0*phi); + phis6 = c3 * sin((double)6.0*phi); + MM = a*(lat-phis2+phis4-phis6); + EE = dlam *phis; + *E = NNot * sin(EE) + E0; + *N = MM - AM0 + NNot * ((double)1.-cos(EE)) + N0; + } + + return; +} + + + + +/* @func GPS_Math_Polycon_EN_To_LatLon ********************************** +** +** Convert Polyconic easting and northing projection +** to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double AM0; + double c0; + double c1; + double c2; + double c3; + double j; + double te4; + double phi0s2; + double phi0s4; + double phi0s6; + + double dx; + double dy; + double dxoa; + double AA; + double BB; + double CC=(double)0.; + double PHIn; + double PHId; + double PHIs; + double PHI; + double PHIs2; + double PHIs4; + double PHIs6; + double Mn; + double Mnp; + double Ma; + double AAMa; + double mpb; + double AAmin; + double tol; + double lat; + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(M0>GPS_PI) + M0 -= p2; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + tol = (double)1.0e-12; + + dx = E - E0; + dy = N - N0; + dxoa = dx/a; + if((((-AM0-(double)1.)tol) + { + PHIs = sin(PHIn); + CC = pow((double)1.-e2*PHIs*PHIs,(double).5) * tan(PHIn); + PHI = PHIn * c0; + PHIs2 = c1 * sin((double)2.0*PHIn); + PHIs4 = c2 * sin((double)4.0*PHIn); + PHIs6 = c3 * sin((double)6.0*PHIn); + Mn = a*(PHI-PHIs2+PHIs4-PHIs6); + Mnp = c0 - (double)2.*c1*cos((double)2.*PHIn)+(double)4.*c2* + cos((double)4.*PHIn)-(double)6.*c3*cos((double)6.*PHIn); + Ma = Mn / a; + AAMa = AA * Ma; + mpb = Ma*Ma+BB; + AAmin = AA - Ma; + PHId = (AAMa*CC+AAmin-(double).5*mpb*CC)/ + (e2*PHIs2*(mpb-(double)2.*AAMa) / + (double)4.*CC+AAmin*(CC*Mnp-(double)2./PHIs2)-Mnp); + PHIn -= PHId; + } + *phi = PHIn; + + if(*phi>po2) + *phi = po2; + else if(*phi<-po2) + *phi = -po2; + + if((((po2-(double).00001)GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda = GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_Sinusoid_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to Sinusoidal projection easting and +** northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b) +{ + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double c0; + double c1; + double c2; + double c3; + double A1; + double A0; + double A2; + double A3; + double E1; + double E2; + double E3; + double E4; + double j; + double om0; + double som0; + + double phis; + double phis2; + double phis4; + double phis6; + double mm; + double MM; + double dlam; + + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + j = (double)45.*e6/(double)1024.; + c0 = (double)1.-e2/(double)4.-(double)3.*e4/(double)64.-(double)5.* + e6/(double)256.; + c1 = (double)3.*e2/(double)8.+(double)3.*e4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + om0 = (double)1. - e2; + som0 = pow(om0,(double).5); + E1 = ((double)1.-som0)/((double)1.+som0); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + if(M0>GPS_PI) + M0 -= p2; + + phis = sin(phi); + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam-=p2; + if(dlam<-GPS_PI) + dlam+=p2; + + mm = pow((double)1.-e2*phis*phis,(double).5); + phis2 = c1 * sin((double)2.*phi); + phis4 = c2 * sin((double)4.*phi); + phis6 = c3 * sin((double)6.*phi); + MM = a * (c0*phi-phis2+phis4-phis6); + + + + *E = a*dlam*cos(phi)/mm+E0; + *N = MM + N0; + + return; +} + + + + +/* @func GPS_Math_Sinusoid_EN_To_LatLon ********************************** +** +** Convert latitude and longitude to Sinusoidal projection easting and +** northing +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b) +{ + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double c0; + double c1; + double c2; + double c3; + double A1; + double A0; + double A2; + double A3; + double E1; + double E2; + double E3; + double E4; + double j; + double om0; + double som0; + + double dx; + double dy; + double mu; + double mu2s; + double mu4s; + double mu6s; + double mu8s; + double phis; + + + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + j = (double)45.*e6/(double)1024.; + c0 = (double)1.-e2/(double)4.-(double)3.*e4/(double)64.-(double)5.* + e6/(double)256.; + c1 = (double)3.*e2/(double)8.+(double)3.*e4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + om0 = (double)1. - e2; + som0 = pow(om0,(double).5); + E1 = ((double)1.-som0)/((double)1.+som0); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + + dx = E - E0; + dy = N - N0; + + mu = dy/(c0*a); + mu2s = A0 * sin((double)2.*mu); + mu4s = A1 * sin((double)4.*mu); + mu6s = A2 * sin((double)6.*mu); + mu8s = A3 * sin((double)8.*mu); + *phi = mu + mu2s + mu4s + mu6s + mu8s; + + if(*phi>po2) + *phi=po2; + else if (*phi<-po2) + *phi=-po2; + + if((((po2-(double)1.0e-8)GPS_PI) + *lambda-=p2; + if(*lambda<-GPS_PI) + *lambda+=p2; + + if(*lambda>GPS_PI) + *lambda=GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_TCylEA_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to transverse cylindrical equal area +** projection easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, double E0, + double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double AM0; + double qp; + double om; + double oo; + double c0; + double c1; + double c2; + double c3; + double b0; + double b1; + double B2; + double b3; + double A0; + double A1; + double A2; + double sf; + double x; + double som; + double phis; + double j; + double te4; + double lat; + double phi0s2; + double phi0s4; + double phi0s6; + double E1; + double E2; + double E3; + double E4; + + double dlam; + double qq; + double qqo; + double bt; + double btc; + double PHI; + double PHIs2; + double PHIs4; + double PHIs6; + double bts2; + double bts4; + double bts6; + double PHIc; + double PHIcs; + double Mc; + + + + sf = (double)1.0; /* scale factor */ + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(M0>GPS_PI) + M0 -= p2; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + om = (double)1.-e2; + som = pow(om,(double).5); + oo = (double)1./((double)2.*e); + + phis = sin(po2); + x = e * phis; + qp = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + + A0 = e2 / (double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + A1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + A2 = (double)761.*e6/(double)45360.; + + E1 = ((double)1.0-som) / ((double)1.0+som); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + + b0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + b1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + B2 = (double)151.*E3/(double)96.; + b3 = (double)1097.*E4/(double)512.; + + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + + dlam = lambda - M0; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + + phis = sin(phi); + + if(phi==po2) + { + qq = qp; + qqo = (double)1.; + } + else + { + x = e * phis; + qq = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + qqo = qq/qp; + } + + if(qqo>(double)1.) + qqo = (double)1.; + else if(qqo<(double)-1.) + qqo = (double)-1.; + + bt = asin(qqo); + btc = atan(tan(bt)/cos(dlam)); + + if((fabs(btc)-po2)>(double)1.0e-8) + PHIc = btc; + else + { + bts2 = A0 * sin((double)2.0*btc); + bts4 = A1 * sin((double)4.0*btc); + bts6 = A2 * sin((double)6.0*btc); + PHIc = btc + bts2 + bts4 + bts6; + } + + PHIcs = sin(PHIc); + *E = a*cos(bt)*cos(PHIc)*sin(dlam)/(sf*cos(btc)* + pow((double)1.-e2*PHIcs*PHIcs, + (double).5)) + E0; + PHI = c0 * PHIc; + PHIs2 = c1 * sin((double)2.0*PHIc); + PHIs4 = c2 * sin((double)4.0*PHIc); + PHIs6 = c3 * sin((double)6.0*PHIc); + Mc = a*(PHI-PHIs2+PHIs4-PHIs6); + + *N = sf * (Mc-AM0) + N0; + + return; +} + + + + +/* @func GPS_Math_TCylEA_EN_To_LatLon ********************************** +** +** Convert transverse cylindrical equal area easting and northing projection +** to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] M0 [double] central meridian (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double AM0; + double qp; + double om; + double oo; + double c0; + double c1; + double c2; + double c3; + double b0; + double b1; + double B2; + double b3; + double A0; + double A1; + double A2; + double sf; + double x; + double som; + double phis; + double j; + double te4; + double lat; + double phi0s2; + double phi0s4; + double phi0s6; + double E1; + double E2; + double E3; + double E4; + + double dx; + double dy; + double bt; + double btc; + double btp; + double btcc; + double Mc; + double Muc; + double mus2; + double mus4; + double mus6; + double mus8; + double bts2; + double bts4; + double bts6; + double PHIc; + double Qc; + double Qco; + double t; + + + sf = (double)1.0; /* scale factor */ + + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(M0>GPS_PI) + M0 -= p2; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + om = (double)1.-e2; + som = pow(om,(double).5); + oo = (double)1./((double)2.*e); + + phis = sin(po2); + x = e * phis; + qp = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + + A0 = e2 / (double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + A1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + A2 = (double)761.*e6/(double)45360.; + + E1 = ((double)1.0-som) / ((double)1.0+som); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + + b0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + b1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + B2 = (double)151.*E3/(double)96.; + b3 = (double)1097.*E4/(double)512.; + + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + + + dx = E - E0; + dy = N - N0; + Mc = AM0 + dy/sf; + Muc = Mc / (c0*a); + + mus2 = b0 * sin((double)2.0*Muc); + mus4 = b1 * sin((double)4.0*Muc); + mus6 = B2 * sin((double)6.0*Muc); + mus8 = b3 * sin((double)6.0*Muc); + PHIc = Muc + mus2 + mus4 + mus6 + mus8; + + phis = sin(PHIc); + x = e * phis; + Qc = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + Qco = Qc/qp; + + if(Qco>(double)1.) + Qco = (double)1.; + else if(Qco<(double)-1.) + Qco = (double)-1.; + + btc = asin(Qco); + btcc = cos(btc); + t = sf*dx*btcc*pow((double)1.-e2*phis*phis,(double).5)/(a*cos(PHIc)); + if(t>(double)1.) + t=(double)1.; + else if(t<(double)-1.) + t=(double)-1.; + btp = -asin(t); + bt = asin(cos(btp)*sin(btc)); + + bts2 = A0 * sin((double)2.0*bt); + bts4 = A1 * sin((double)4.0*bt); + bts6 = A2 * sin((double)6.0*bt); + *phi = bt + bts2 + bts4 + bts6; + *lambda = M0 - atan(tan(btp)/btcc); + + if(*phi>po2) + *phi = po2; + else if(*phi<-po2) + *phi = -po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda = GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_Mercator_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to standard Mercator projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] lambda0 [double] longitude of origin (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double lambda0, + double E0, double N0, double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e3; + double e; + double es; + double ab; + double bb; + double cb; + double db; + double ml; + double phi0s; + double sf; + + double dlam; + double ct; + double ex; + double tt; + double pt; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + ml = ((double)GPS_PI*(double)89.5)/(double)180.; + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(lambda0>GPS_PI) + lambda0 -= p2; + a2 = a*a; + b2 = b*b; + es = (a2-b2)/a2; + e2 = es*es; + e3 = e2*es; + e4 = e3*es; + + e = pow(es,(double).5); + phi0s = sin(phi0); + sf = (double)1. / (pow((double)1.-es*phi0s*phi0s,(double).5)/cos(phi0)); + + ab = es/(double)2.+(double)5.*e2/(double)24.+e3/(double)12.+(double)13.* + e4/(double)360.; + bb = (double)7.*e2/(double)48.+(double)29.*e3/(double)240.+ + (double)811.*e4/(double)11520.; + cb = (double)7.*e3/(double)120.+(double)81.*e4/(double)1120.; + db = (double)4279.*e4/(double)161280.; + + + + if(lambda>(double)GPS_PI) + lambda -= p2; + + dlam = lambda - lambda0; + if(dlam>GPS_PI) + dlam -= p2; + if(dlam<-GPS_PI) + dlam += p2; + + + ex = e * sin(phi); + tt = tan((double)GPS_PI/(double)4.+phi/(double)2.); + pt = pow((((double)1.-ex)/((double)1.+ex)),(e/(double)2.)); + + ct = tt * pt; + *N = sf * a * log(ct) + N0; + *E = sf * a * dlam + E0; + + return; +} + + + + +/* @func GPS_Math_Mercator_EN_To_LatLon ********************************** +** +** Convert standard Mercator easting and northing projection +** to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] lambda0 [double] longitude of origin (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, + double lambda0, double E0, double N0, + double a, double b) +{ + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e3; + double e; + double es; + double ab; + double bb; + double cb; + double db; + double ml; + double phi0s; + double sf; + + double dx; + double dy; + double x; + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + ml = ((double)GPS_PI*(double)89.5)/(double)180.; + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if(lambda0>GPS_PI) + lambda0 -= p2; + a2 = a*a; + b2 = b*b; + es = (a2-b2)/a2; + e2 = es*es; + e3 = e2*es; + e4 = e3*es; + + e = pow(es,(double).5); + phi0s = sin(phi0); + sf = (double)1. / (pow((double)1.-es*phi0s*phi0s,(double).5)/cos(phi0)); + + ab = es/(double)2.+(double)5.*e2/(double)24.+e3/(double)12.+(double)13.* + e4/(double)360.; + bb = (double)7.*e2/(double)48.+(double)29.*e3/(double)240.+ + (double)811.*e4/(double)11520.; + cb = (double)7.*e3/(double)120.+(double)81.*e4/(double)1120.; + db = (double)4279.*e4/(double)161280.; + + dx = E - E0; + dy = N - N0; + *lambda = lambda0 + dx / (sf*a); + x = (double)GPS_PI / (double)2. - + (double)2.*atan((double)1./exp(dy/(sf*a))); + *phi = x+ab*sin((double)2.*x)+bb*sin((double)4.*x)+cb*sin((double)6.*x) + + db*sin((double)8.*x); + + if(*phi>po2) + *phi = po2; + else if(*phi<-po2) + *phi = -po2; + + if(*lambda>GPS_PI) + *lambda -= p2; + if(*lambda<-GPS_PI) + *lambda += p2; + + if(*lambda>GPS_PI) + *lambda = GPS_PI; + else if(*lambda<-GPS_PI) + *lambda=-GPS_PI; + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; +} + + + + +/* @func GPS_Math_TMerc_LatLon_To_EN ********************************** +** +** Convert latitude and longitude to transverse Mercator projection +** easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] lambda0 [double] longitude of origin (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] F0 [double] scale factor +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b) +{ + GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; +} + + + + +/* @func GPS_Math_TMerc_EN_To_LatLon ********************************** +** +** Convert transverse Mercator easting and northing projection +** to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi0 [double] latitude of origin (deg) +** @param [r] lambda0 [double] longitude of origin (deg) +** @param [r] E0 [double] false easting +** @param [r] N0 [double] false northing +** @param [r] F0 [double] scale factor +** @param [r] a [double] semi-major axis +** @param [r] b [double] semi-minor axis +** +** @return [void] +************************************************************************/ +void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b) +{ + GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; +} + + + + +/* @func GPS_Math_Swiss_LatLon_To_EN *********************************** +** +** Convert latitude and longitude to Swiss grid easting and northing +** +** @param [r] phi [double] latitude (deg) +** @param [r] lambda [double] longitude (deg) +** @param [w] E [double *] easting (metre) +** @param [w] N [double *] northing (metre) +** @param [r] phi0 [double] latitude origin (deg) [normally 46.95240556] +** @param [r] lambda0 [double] longitude origin (deg) [normally 7.43958333] +** @param [r] E0 [double] false easting (metre) [normally 600000.0] +** @param [r] N0 [double] false northing (metre) [normally 200000.0] +** @param [r] a [double] semi-major axis [normally 6377397.000] +** @param [r] b [double] semi-minor axis [normally 6356078.823] +** +** @return [void] +***************************************************************************/ +void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, + double *N,double phi0,double lambda0, + double E0, double N0, double a, double b) + +{ + double a2; + double b2; + double esq; + double e; + double c; + double ephi0p; + double phip; + double sphip; + double phid; + double slambda2; + double lambda1; + double lambda2; + double K; + double po4; + double w; + double R; + + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + + po4=GPS_PI/(double)4.0; + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + c = sqrt(1+((esq*pow(cos(phi0),(double)4.))/((double)1.-esq))); + + ephi0p = asin(sin(phi0)/c); + + K = log(tan(po4+ephi0p/(double)2.)) - c*(log(tan(po4+phi0/(double)2.)) - + e/(double)2. * log(((double)1.+e*sin(phi0)) / + ((double)1.-e*sin(phi0)))); + lambda1 = c*(lambda-lambda0); + w = c*(log(tan(po4+phi/(double)2.)) - e/(double)2. * + log(((double)1.+e*sin(phi)) / ((double)1.-e*sin(phi)))) + K; + + + phip = (double)2. * (atan(exp(w)) - po4); + + sphip = cos(ephi0p) * sin(phip) - sin(ephi0p) * cos(phip) * cos(lambda1); + phid = asin(sphip); + + slambda2 = cos(phip)*sin(lambda1) / cos(phid); + lambda2 = asin(slambda2); + + R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); + + *N = R*log(tan(po4 + phid/(double)2.)) + N0; + *E = R*lambda2 + E0; + return; +} + + + + +/* @func GPS_Math_Swiss_EN_To_LatLon ************************************ +** +** Convert Swiss Grid easting and northing to latitude and longitude +** +** @param [r] E [double] easting (metre) +** @param [r] N [double] northing (metre) +** @param [w] phi [double *] latitude (deg) +** @param [w] lambda [double *] longitude (deg) +** @param [r] phi0 [double] latitude origin (deg) [normally 46.95240556] +** @param [r] lambda0 [double] longitude origin (deg) [normally 7.43958333] +** @param [r] E0 [double] false easting (metre) [normally 600000.0] +** @param [r] N0 [double] false northing (metre) [normally 200000.0] +** @param [r] a [double] semi-major axis [normally 6377397.000] +** @param [r] b [double] semi-minor axis [normally 6356078.823] +** +** @return [void] +*************************************************************************/ + +void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double lambda0, + double E0, double N0, double a, double b) +{ + double a2; + double b2; + double esq; + double e; + double R; + double c; + double po4; + double phid; + double phi1; + double lambdad; + double lambda1; + double slambda1; + double ephi0p; + double sphip; + double tol; + double cr; + double C; + double K; + + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + + po4=GPS_PI/(double)4.0; + tol=(double)0.00001; + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); + + phid = (double)2.*(atan(exp((N - N0)/R)) - po4); + lambdad = (E - E0)/R; + + c = sqrt((double)1.+((esq * pow(cos(phi0), (double)4.)) / + ((double)1.-esq))); + ephi0p = asin(sin(phi0) / c); + + sphip = cos(ephi0p)*sin(phid) + sin(ephi0p)*cos(phid)*cos(lambdad); + phi1 = asin(sphip); + + slambda1 = cos(phid)*sin(lambdad)/cos(phi1); + lambda1 = asin(slambda1); + + *lambda = GPS_Math_Rad_To_Deg((lambda1/c + lambda0)); + + K = log(tan(po4 + ephi0p/(double)2.)) -c*(log(tan(po4 + phi0/(double)2.)) + - e/(double)2. * log(((double)1.+e*sin(phi0)) / + ((double)1.-e*sin(phi0)))); + C = (K - log(tan(po4 + phi1/(double)2.)))/c; + + do + { + cr = (C + log(tan(po4 + phi1/(double)2.)) - e/(double)2. * + log(((double)1.+e*sin(phi1)) / ((double)1.-e*sin(phi1)))) * + ((((double)1.-esq*sin(phi1)*sin(phi1)) * cos(phi1)) / + ((double)1.-esq)); + phi1 -= cr; + } + while (fabs(cr) > tol); + + *phi = GPS_Math_Rad_To_Deg(phi1); + + return; +} diff --git a/jeeps/gpsproj.h b/jeeps/gpsproj.h new file mode 100644 index 000000000..6922a47e0 --- /dev/null +++ b/jeeps/gpsproj.h @@ -0,0 +1,157 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsproj_h +#define gpsproj_h + + +#include "gps.h" + +void GPS_Math_Albers_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); +void GPS_Math_Albers_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); + + +void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); +void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); + +void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b); +void GPS_Math_Miller_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + +void GPS_Math_Bonne_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, double E0, + double N0, double a, double b); +void GPS_Math_Bonne_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + +void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, + double E0, double N0, double a, double b); +void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + +void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, + double E0, double N0, double a, double b); +void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + +void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, double N0, + double a, double b); +void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + +void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, double N0, + double a, double b); +void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + +void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, double E0, + double N0, double a, double b); +void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + +void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b); +void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + +void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi1, double lambda1, + double E0, double N0, double a, double b); +void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi1, double lambda1, + double E0, double N0, double a, double b); + +void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b); +void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + +void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double lambda0, + double E0, double N0, double a, double b); +void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double lambda0, + double E0, double N0, double a, double b); + +void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, + double E0, double N0, double a, double b); +void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + +void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b); +void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + +void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, double E0, + double N0, double a, double b); +void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + +void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double lambda0, + double E0, double N0, double a, double b); +void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, + double lambda0, double E0, double N0, + double a, double b); + +void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b); +void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b); + +void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, + double *N,double phi0,double lambda0, + double E0, double N0, double a, double b); +void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double lambda0, + double E0, double N0, double a, double b); + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsprot.c b/jeeps/gpsprot.c new file mode 100644 index 000000000..58e8a1182 --- /dev/null +++ b/jeeps/gpsprot.c @@ -0,0 +1,374 @@ +/******************************************************************** +** @source JEEPS protocol table lookup functions (GPS' without A001) +** +** @author Copyright (C) 1999 Alan Bleasby +** @version 1.0 +** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2006 Robert Lipe +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include + +#define GPS_TAGUNK 20 + +/* Storage for any unknown tags */ +static int32 gps_tag_unknown[GPS_TAGUNK]; +static int32 gps_tag_data_unknown[GPS_TAGUNK]; +static int32 gps_n_tag_unknown = 0; + + + +struct COMMANDDATA COMMAND_ID[2]= +{ + { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x31,0x32,92,117,121,450,451,452,453,454,561,562,563,564,564 + } + , + { + 0x00,0x04,0x00,0x00,0x08,0x14,0x00,0x15,0x1a,0x00,0x00 + } +}; + +struct LINKDATA LINK_ID[3]= +{ + { + 0xfd,0xfe,0xff,248, + 0x06,0,0,0,0,0,0x15,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + , + { + 0xfd,0xfe,0xff,248, + 0x06,0x0a,0x0c,0x0e,0x11,0x13,0x15,0x1b,0x1d,0x1e,0x1f, + 0x22,0x23,0x33,0x62,0x63, + 134,149,152,990,991,992,993,994,1061,1062,1063,1064,1065,1066,222 + } + , + { + 0xfd,0xfe,0xff,248, + 0x06,0x0b,0x0c,0x14,0x18,0,0x15,0x23,0x25,0x27,0x04, + 0,0x2b,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } +}; + +struct GPS_MODEL_PROTOCOL GPS_MP[]= +{ + { 7,pL001,pA010,pA100,pD100,pA200,pD200,-1,-1,-1,-1,-1, + pA500,pD500 + }, + { 13,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { 14,pL001,pA010,pA100,pD100,pA200,pD200,pD100,-1,-1,pA400,pD400, + pA500,pD500 + }, + { 15,pL001,pA010,pA100,pD151,pA200,pD200,pD151,-1,-1,pA400,pD151, + pA500,pD500 + }, + { 18,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { 20,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { 22,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,pA400,pD152, + pA500,pD500 + }, + { 23,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { 24,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { 25,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { 29,pL001,pA010,pA100,pD101,pA200,pD201,pD101,pA300,pD300,pA400,pD101, + pA500,pD500 + }, + { 929,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD500 + }, + { 31,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 33,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { 34,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { 35,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { 36,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,pA400,pD152, + pA500,pD500 + }, + { 936,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 39,pL001,pA010,pA100,pD151,pA200,pD201,pD151,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 41,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 42,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { 44,pL001,pA010,pA100,pD101,pA200,pD201,pD101,pA300,pD300,pA400,pD101, + pA500,pD500 + }, + { 45,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 47,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 48,pL001,pA010,pA100,pD154,pA200,pD201,pD154,pA300,pD300,-1,-1, + pA500,pD501 + }, + { 49,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD501 + }, + { 50,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD501 + }, + { 52,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { 53,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD501 + }, + { 55,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 56,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 59,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 61,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 62,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 64,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD551 + }, + { 71,pL001,pA010,pA100,pD155,pA200,pD201,pD155,pA300,pD300,-1,-1, + pA500,pD501 + }, + { 72,pL001,pA010,pA100,pD104,pA200,pD201,pD104,pA300,pD300,-1,-1, + pA500,pD501 + }, + { 73,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, + pA500,pD501 + }, + { 74,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { 76,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD501 + }, + { 77,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,pA400,pD400, + pA500,pD501 + }, + { 777,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { 877,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, + pA500,pD501 + }, + { 977,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { 87,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { 88,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD501 + }, + { 95,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { 96,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { 97,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, + pA500,pD501 + }, + { 98,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD551 + }, + { 100,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { 105,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { 106,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { 112,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD501 + }, + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } +}; + + +/* @func GPS_Protocol_Version_Change ************************************ +** +** Alters/recalculates ID, if necessary, for indexing the GPS_MP +** structure in order to find available protocols. +** +** @param [r] id [US] Garmin id +** @param [r] version [UD] Garmin version +** +** @return [void] +************************************************************************/ + +US GPS_Protocol_Version_Change(US id, US version) +{ + if(id==29) + if(version>=400) + id = 929; + + if(id==36) + if(version>=300) + id = 936; + + if(id==77) + { + if(version>=301 && version<350) + id = 777; + else if(version>=350 && version<361) + id = 877; + else if(version>=361) + id = 977; + } + + return id; +} + + + +/* @func GPS_Protocol_Table_Set ************************************ +** +** Set protocol capabilities based on table look-up +** For those units without the A001 protocol +** +** @param [r] id [const US] id +** +** @return [int32] Success +************************************************************************/ + +int32 GPS_Protocol_Table_Set(US id) +{ + int32 i; + US v; + char s[GPS_ARB_LEN]; + + i=0; + while((v=GPS_MP[i].id)) + { + if(v==id) + { + gps_link_type = GPS_MP[i].link; + gps_device_command = GPS_MP[i].command-10; + gps_waypt_transfer = GPS_MP[i].wayptt; + gps_waypt_type = GPS_MP[i].wayptd; + gps_route_transfer = GPS_MP[i].rtea; + gps_rte_hdr_type = GPS_MP[i].rted0; + gps_rte_type = GPS_MP[i].rted1; + gps_trk_transfer = GPS_MP[i].trka; + gps_trk_type = GPS_MP[i].trkd; + gps_prx_waypt_transfer = GPS_MP[i].prxa; + gps_prx_waypt_type = GPS_MP[i].prxd; + gps_almanac_transfer = GPS_MP[i].alma; + gps_almanac_type = GPS_MP[i].almd; + return 1; + } + ++i; + } + + + (void)sprintf(s,"INIT: No table entry for ID %d\n",id); + GPS_Error(s); + + return GPS_UNSUPPORTED; +} + + +/* @func GPS_Protocol_Error ******************************************* +** +** Called if an unrecognised/illegal protocol is met +** For those units with the A001 protocol +** +** @param [r] tag [const US] tag +** @param [r] data [const US] data +** +** @return [void] +************************************************************************/ + +void GPS_Protocol_Error(US tag, US data) +{ + char s[GPS_ARB_LEN]; + + (void) sprintf(s,"PROTOCOL ERROR: Unknown tag/data [%c/%d]\n",tag,data); + GPS_Error(s); + + if(gps_n_tag_unknown < GPS_TAGUNK) + { + gps_tag_unknown[gps_n_tag_unknown] = tag; + gps_tag_data_unknown[gps_n_tag_unknown++] = data; + } + + return; +} + + + +/* @func GPS_Unknown_Protocol_Print ******************************************* +** +** Diagnostic routine for printing out any unknown protocols +** For those units with the A001 protocol +** +** @return [void] +************************************************************************/ + +void GPS_Unknown_Protocol_Print(void) +{ + int32 i; + + (void) fprintf(stdout,"\nUnknown protocols: "); + if(!gps_n_tag_unknown) + (void) fprintf(stdout,"None"); + (void) fprintf(stdout,"\n"); + + for(i=0; i +#include +#include +#include + + +/* @func GPS_Time_Now *********************************************** +** +** Get current time +** +** @return [time_t] number of bytes read +**********************************************************************/ + +time_t GPS_Time_Now(void) +{ + time_t secs; + + if(time(&secs)==-1) + { + perror("time"); + GPS_Error("GPS_Time_Now: Error reading time"); + gps_errno = HARDWARE_ERROR; + return 0; + } + + return secs; +} + + + + + + + +/* @func GPS_Serial_Packet_Read *********************************************** +** +** Read a packet +** +** @param [r] fd [int32] file descriptor +** @param [w] packet [GPS_PPacket *] packet string +** +** @return [int32] number of bytes read +**********************************************************************/ + +int32 GPS_Serial_Packet_Read(gpsdevh *fd, GPS_PPacket *packet) +{ + time_t start; + int32 n; + int32 len; + UC u; + int32 isDLE; + UC *p; + int32 i; + UC chk=0; + const char *m1; + const char *m2; + + len = 0; + isDLE = gpsFalse; + p = (*packet)->data; + + start = GPS_Time_Now(); + GPS_Diag("Rx Data:"); + while(GPS_Time_Now() < start+GPS_TIME_OUT) + { + if((n=GPS_Serial_Chars_Ready(fd))) + { + if(GPS_Serial_Read(fd,&u,1)==-1) + { + perror("read"); + GPS_Error("GPS_Packet_Read: Read error"); + gps_errno = FRAMING_ERROR; + return 0; + } + + GPS_Diag("%02x ", u); + + if(!len) + { + (*packet)->dle = u; + if(u != DLE) + { + (void) fprintf(stderr,"GPS_Packet_Read: No DLE. Data received, but probably not a garmin packet.\n"); + (void) fflush(stderr); + return 0; + } + ++len; + continue; + } + + if(len==1) + { + (*packet)->type = u; + ++len; + continue; + } + + if(u == DLE) + { + if(isDLE) + { + isDLE = gpsFalse; + continue; + } + isDLE = gpsTrue; + } + + if(len == 2) + { + (*packet)->n = u; + len = -1; + continue; + } + + if(u == ETX) + if(isDLE) + { + (*packet)->edle = DLE; + (*packet)->etx = ETX; + if(p-(*packet)->data-2 != (*packet)->n) + { + GPS_Error("GPS_Packet_Read: Bad count"); + gps_errno = FRAMING_ERROR; + return 0; + } + (*packet)->chk = *(p-2); + + for(i=0,p=(*packet)->data;i<(*packet)->n;++i) + chk -= *p++; + chk -= (*packet)->type; + chk -= (*packet)->n; + if(chk != (*packet)->chk) + { + GPS_Error("CHECKSUM: Read error\n"); + gps_errno = FRAMING_ERROR; + return 0; + } + + m1 = Get_Pkt_Type((*packet)->type, (*packet)->data[0], &m2); + if (gps_show_bytes) { + GPS_Diag(" "); + for (i = 0; i < (*packet)->n; i++) { + char c = (*packet)->data[i]; + GPS_Diag("%c", isalnum(c) ? c : '.'); + } + GPS_Diag(" "); + } + GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); + return (*packet)->n; + } + + *p++ = u; + } + } + + + GPS_Error("GPS_Packet_Read: Timeout. No data received."); + gps_errno = SERIAL_ERROR; + + return 0; +} + + + +/* @func GPS_Get_Ack ************************************************* +** +** Check that returned packet is an ack for the packet sent +** +** @param [r] fd [int32] file descriptor +** @param [r] tra [GPS_PPacket *] packet just transmitted +** @param [r] rec [GPS_PPacket *] packet to receive +** +** @return [int32] true if ACK +**********************************************************************/ + +int32 GPS_Serial_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec) +{ + if(!GPS_Serial_Packet_Read(fd, rec)) + return 0; + + if(LINK_ID[0].Pid_Ack_Byte != (*rec)->type) + { + gps_error = FRAMING_ERROR; +/* rjl return 0; */ + } + + if(*(*rec)->data != (*tra)->type) + { + gps_error = FRAMING_ERROR; + return 0; + } + + return 1; +} diff --git a/jeeps/gpsread.h b/jeeps/gpsread.h new file mode 100644 index 000000000..17f3bd852 --- /dev/null +++ b/jeeps/gpsread.h @@ -0,0 +1,20 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsread_h +#define gpsread_h + + +#include "gps.h" + +time_t GPS_Time_Now(void); +int32 GPS_Serial_Packet_Read(gpsdevh *fd, GPS_PPacket *packet); +int32 GPS_Serial_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsrqst.c b/jeeps/gpsrqst.c new file mode 100644 index 000000000..7203313c6 --- /dev/null +++ b/jeeps/gpsrqst.c @@ -0,0 +1,176 @@ +/******************************************************************** +** @source JEEPS time/position request from GPS functions +** +** @author Copyright (C) 1999 Alan Bleasby +** @version 1.0 +** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2006 Robert Lipe +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" + + +static int32 GPS_A600_Rqst(gpsdevh *fd, time_t Time); +static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon); + + + +/* @func GPS_Rqst_Send_Time ****************************************** +** +** Set GPS time on request of GPS +** +** @param [r] fd [int32] file descriptor +** @param [r] Time [time_t] unix-style time +** +** @return [int32] true if OK +************************************************************************/ + +int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time) +{ + time_t ret=0; + + switch(gps_date_time_transfer) + { + case pA600: + ret = GPS_A600_Rqst(fd, Time); + break; + default: + GPS_Error("Rqst_Send_Time: Unknown date/time protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + + +/* @funcstatic GPS_A600_Rqst ******************************************* +** +** Send time to GPS +** +** @param [r] fd [int32] file descriptor +** @param [r] Time [time_t] unix-style time +** +** @return [int32] success +************************************************************************/ +static int32 GPS_A600_Rqst(gpsdevh *fd, time_t Time) +{ + GPS_PPacket tra; + GPS_PPacket rec; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + switch(gps_date_time_type) + { + case pD600: + GPS_D600_Send(&tra,Time); + break; + default: + GPS_Error("A600_Rqst: Unknown data/time protocol"); + return PROTOCOL_ERROR; + } + + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_errno; + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + return 1; +} + + + +/* @func GPS_Rqst_Send_Position ****************************************** +** +** Set GPS position +** +** @param [r] fd [int32] filedescriptor +** @param [r] lat [double] latitude (deg) +** @param [r] lon [double] longitude (deg) +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon) +{ + int32 ret=0; + + switch(gps_position_transfer) + { + case pA700: + ret = GPS_A700_Rqst(fd, lat, lon); + break; + default: + GPS_Error("Rqst_Send_Position: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} + + + +/* @funcstatic GPS_A700_Rqst ******************************************* +** +** Send position to GPS +** +** @param [r] fd [int32] file descriptor +** @param [r] lat [double] latitude (deg) +** @param [r] lon [double] longitute (deg) +** +** @return [int32] success +************************************************************************/ +static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon) +{ + GPS_PPacket tra; + GPS_PPacket rec; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + + switch(gps_position_type) + { + case pD700: + GPS_D700_Send(&tra,lat,lon); + break; + default: + GPS_Error("A700_Rqst: Unknown position protocol"); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + return PROTOCOL_ERROR; + } + + if(!GPS_Write_Packet(fd,tra)) + return gps_errno; + + if(!GPS_Get_Ack(fd, &tra, &rec)) + return gps_errno; + + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + return 1; +} + diff --git a/jeeps/gpsrqst.h b/jeeps/gpsrqst.h new file mode 100644 index 000000000..ec0169586 --- /dev/null +++ b/jeeps/gpsrqst.h @@ -0,0 +1,20 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsrqst_h +#define gpsrqst_h + + +#include "gps.h" + +int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time); +int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpssend.c b/jeeps/gpssend.c new file mode 100644 index 000000000..d863683d9 --- /dev/null +++ b/jeeps/gpssend.c @@ -0,0 +1,213 @@ +/******************************************************************** +** @source JEEPS packet construction, sending and ack functions +** +** @author Copyright (C) 1999 Alan Bleasby +** @version 1.0 +** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2006 Robert Lipe +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include "gpsserial.h" + +#include +#include +#include + + +/* @func GPS_Make_Packet *********************************************** +** +** Forms a complete packet to send +** +** @param [w] packet [GPS_PPacket *] packet string +** @param [r] type [UC] packet type +** @param [r] data [UC *] data string +** @param [r] n [int16] number of bytes in data string +** +** @return [void] +************************************************************************/ + +void GPS_Serial_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n) +{ + UC *p; + UC *q; + + int32 i; + UC chk=0; + + + p = data; + q = (*packet)->data; + + (*packet)->dle = DLE; + (*packet)->edle = DLE; + (*packet)->etx = ETX; + (*packet)->n = (UC) n; + (*packet)->type = type; + (*packet)->bytes = 0; + + chk -= type; + + if(n == DLE) + { + ++(*packet)->bytes; + *q++ = DLE; + } + + + chk -= (UC) n; + + for(i=0;ibytes; + *q++ = DLE; + } + chk -= *p; + *q++ = *p++; + ++(*packet)->bytes; + } + + if(chk == DLE) + { + *q++ = DLE; + ++(*packet)->bytes; + } + + (*packet)->chk = chk; + + return; +} + + +void +Diag(void *buf, size_t sz) +{ + unsigned char *cbuf = (unsigned char *) buf; + while (sz--) { + GPS_Diag("%02x ", *cbuf++); + } +} + +void +DiagS(void *buf, size_t sz) +{ + unsigned char *cbuf = (unsigned char *) buf; + + while (sz--) { + unsigned char c = *cbuf++; + GPS_Diag("%c", isalnum(c) ? c : '.'); + } +} + +/* @func GPS_Write_Packet *********************************************** +** +** Forms a complete packet to send +** +** @param [w] fd [int32] file descriptor +** @param [r] packet [GPS_PPacket] packet +** +** @return [int32] number of bytes in the packet +************************************************************************/ + +int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet) +{ + size_t ret; + const char *m1, *m2; + + + GPS_Diag("Tx Data:"); + Diag(&packet->dle, 3); + if((ret=GPS_Serial_Write(fd,(const void *) &packet->dle,(size_t)3)) == -1) + { + perror("write"); + GPS_Error("SEND: Write to GPS failed"); + return 0; + } + if(ret!=3) + { + GPS_Error("SEND: Incomplete write to GPS"); + return 0; + } + + Diag(packet->data, packet->bytes); + if((ret=GPS_Serial_Write(fd,(const void *)packet->data,(size_t)packet->bytes)) == -1) + { + perror("write"); + GPS_Error("SEND: Write to GPS failed"); + return 0; + } + if(ret!=packet->bytes) + { + GPS_Error("SEND: Incomplete write to GPS"); + return 0; + } + + + Diag(&packet->chk, 3); + + GPS_Diag(": "); + DiagS(packet->data, packet->bytes); + DiagS(&packet->chk, 3); + m1 = Get_Pkt_Type(packet->type, packet->data[0], &m2); + GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); + + if((ret=GPS_Serial_Write(fd,(const void *)&packet->chk,(size_t)3)) == -1) + { + perror("write"); + GPS_Error("SEND: Write to GPS failed"); + return 0; + } + if(ret!=3) + { + GPS_Error("SEND: Incomplete write to GPS"); + return 0; + } + + + return 1; +} + + +/* @func GPS_Send_Ack *********************************************** +** +** Send an acknowledge packet +** +** @param [w] fd [int32] file descriptor +** @param [r] tra [GPS_PPacket *] packet to transmit +** @param [r] rec [GPS_PPacket *] last packet received +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec) +{ + UC data[2]; + + GPS_Util_Put_Short(data,(US)(*rec)->type); + GPS_Make_Packet(tra,LINK_ID[0].Pid_Ack_Byte,data,2); + if(!GPS_Write_Packet(fd,*tra)) + { + GPS_Error("Error acknowledging packet"); + gps_errno = SERIAL_ERROR; + return 0; + } + + return 1; +} diff --git a/jeeps/gpssend.h b/jeeps/gpssend.h new file mode 100644 index 000000000..edd3f5b0d --- /dev/null +++ b/jeeps/gpssend.h @@ -0,0 +1,25 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpssend_h +#define gpssend_h + + +#include "gps.h" + +#define GPS_ARB_LEN 1024 + +void GPS_Serial_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n); +int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet); +int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + +void GPS_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsserial.c b/jeeps/gpsserial.c new file mode 100644 index 000000000..4e90f0939 --- /dev/null +++ b/jeeps/gpsserial.c @@ -0,0 +1,529 @@ +/******************************************************************** +** @source JEEPS serial port low level functions +** +** @author Copyright (C) 1999,2000 Alan Bleasby +** @version 1.0 +** @modified December 28th 1999 Alan Bleasby. First version +** @modified June 29th 2000 Alan Bleasby. NMEA additions +** @modified Copyright (C) 2006 Robert Lipe +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include "gpsserial.h" +#include "../gbser.h" +#include +#include +#include +#include +#include +#include + +#if 0 +#define GARMULATOR 1 +char *rxdata[] = { + "10 06 02 fe 00 fa 10 03", + "10 ff 7d 97 00 0e 01 53 74 72 65 65 74 50 69 6c 6f 74 20 33 20 53 6f 66 74 77 61 72 65 20 56 65 72 73 69 6f 6e 20 32 2e 37 30 00 56 45 52 42 4d 41 50 20 41 6d 65 72 69 63 61 73 20 41 75 74 6f 72 6f 75 74 65 20 31 2e 30 30 00 56 45 52 41 55 44 20 45 6e 67 6c 69 73 68 20 33 2e 30 31 00 56 45 52 53 50 4c 53 43 52 4e 20 53 70 6c 61 73 68 20 53 63 72 65 65 6e 20 4d 69 73 73 69 6e 67 00 f1 10 03", + "10 f8 0e 56 45 52 53 4d 41 50 31 20 4e 6f 6e 65 00 fb 10 03", + + /* Guessing from here down */ + "10 06 02 fe 00 fa 10 03", /* Ack the unknown packet */ + "10 fd 24 50 00 00 4c 01 00 41 0a 00 41 64 00 44 6d 00 41 c9 00 44 ca 00 44 6d 00 44 d2 00 41 2d 01 44 36 01 44 2d 01 66 10 03", /* PTR Array */ + "10 06 02 0a 00 ee 10 03", /* Ack */ + "10 0e 08 06 04 d4 07 00 17 3a 30 84 10 03", /* DATTIME */ + "10 06 02 0a 00 ee 10 03", /* Ack */ + "10 1b 02 09 00 da 10 03", /* RECORD */ + "10 06 02 0a 00 ee 10 03", /* Ack */ + "10 23 5f 01 00 ff 70 3f 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a6 1b aa 19 6e 78 5c c2 00 00 00 00 51 59 04 69 00 00 00 00 00 00 00 00 ff ff ff ff 47 43 31 41 33 37 00 54 68 65 20 54 72 6f 6c 6c 20 62 79 20 61 31 38 32 70 69 6c 6f 74 20 26 20 46 61 6d 69 6c 79 00 00 00 00 00 59 10 03" + "10 0c 02 07 00 eb 10 03" /* XFERCMP */ +}; +#endif +/* + * termio on Cygwin is apparently broken, so we revert to Windows serial. + */ +#if defined (__WIN32__) || defined (__CYGWIN__) + +#include + +typedef struct { + HANDLE comport; +} win_serial_data; + +/* + * Display an error from the serial subsystem. + */ +void GPS_Serial_Error(const char *mb, ...) +{ + va_list ap; + char msg[200]; + char *s; + int b; + + va_start(ap, mb); + b = vsnprintf(msg, sizeof(msg), mb, ap); + s = msg + b; + *s++ = ':'; + *s++ = ' '; + + FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, + GetLastError(), 0, s, sizeof(msg) - b - 2, 0 ); + GPS_Error(msg); +} + +int32 GPS_Serial_On(const char *port, gpsdevh **dh) +{ + DCB tio; + COMMTIMEOUTS timeout; + HANDLE comport; + const char *xname = fix_win_serial_name(port); + win_serial_data *wsd = xcalloc(sizeof (win_serial_data), 1); + *dh = (gpsdevh*) wsd; + GPS_Diag("Opening %s\n", xname); + comport = CreateFile(xname, GENERIC_READ|GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, 0, NULL); + + if (comport == INVALID_HANDLE_VALUE) { + GPS_Serial_Error("CreateFile on '%s' failed", xname); + gps_errno = SERIAL_ERROR; + return 0; + } + + tio.DCBlength = sizeof(DCB); + GetCommState (comport, &tio); + tio.BaudRate = CBR_9600; + tio.fBinary = TRUE; + tio.fParity = TRUE; + tio.fOutxCtsFlow = FALSE; + tio.fOutxDsrFlow = FALSE; + tio.fDtrControl = DTR_CONTROL_ENABLE; + tio.fDsrSensitivity = FALSE; + tio.fTXContinueOnXoff = TRUE; + tio.fOutX = FALSE; + tio.fInX = FALSE; + tio.fErrorChar = FALSE; + tio.fNull = FALSE; + tio.fRtsControl = RTS_CONTROL_ENABLE; + tio.fAbortOnError = FALSE; + tio.ByteSize = 8; + tio.Parity = NOPARITY; + tio.StopBits = ONESTOPBIT; + + if (!SetCommState (comport, &tio)) { + GPS_Serial_Error("SetCommState on port '%s' failed", port); + CloseHandle(comport); + comport = INVALID_HANDLE_VALUE; + gps_errno = SERIAL_ERROR; + return 0; + } + + /* + * The timeouts are kind of fictional as we always end up doing + * single byte reads. At 9600bps (the default) the individual + * character time is 104Millisecs, so these are mostly "dead-man" + * (i.e. cable unplugged, unit not turned on) values. + */ + GetCommTimeouts (comport, &timeout); + + timeout.ReadIntervalTimeout = 1000; /*like vtime. In MS. */ + timeout.ReadTotalTimeoutMultiplier = 1000; + timeout.ReadTotalTimeoutConstant = 1000; + timeout.WriteTotalTimeoutMultiplier = 1000; + timeout.WriteTotalTimeoutConstant = 1000; + if (!SetCommTimeouts (comport, &timeout)) { + GPS_Serial_Error("SetCommTimeouts"); + CloseHandle (comport); + comport = INVALID_HANDLE_VALUE; + gps_errno = SERIAL_ERROR; + return 0; + } + wsd->comport = comport; + return 1; +} + +int32 GPS_Serial_Off(gpsdevh *dh) +{ + win_serial_data *wsd = (win_serial_data*)dh; + CloseHandle(wsd->comport); + wsd->comport = INVALID_HANDLE_VALUE; + xfree(wsd); + return 1; +} + +int32 GPS_Serial_Chars_Ready(gpsdevh *dh) +{ + COMSTAT lpStat; + DWORD lpErrors; + win_serial_data *wsd = (win_serial_data*)dh; + + ClearCommError(wsd->comport, &lpErrors, &lpStat); + return (lpStat.cbInQue > 0); +} + +int32 GPS_Serial_Wait(gpsdevh *fd) +{ + /* Wait a short time before testing if data is ready. + * The GPS II, in particular, has a noticable time responding + * with a response to the device inquiry and if we give up on this + * too soon, we fail to read the response to the A001 packet and + * blow our state machines when it starts streaming the capabiilties + * response packet. + */ + Sleep(usecDELAY / 1000); + return GPS_Serial_Chars_Ready(fd); +} + +int32 GPS_Serial_Flush(gpsdevh *fd) +{ + return 1; +} + +int32 GPS_Serial_Write(gpsdevh *dh, const void *obuf, int size) +{ + win_serial_data *wsd = (win_serial_data*)dh; + DWORD len; + + /* + * Unbelievably, the Keyspan PDA serial driver 3.2, a "Windows + * Certified driver", will crash the OS on a write of zero bytes. + * We get such writes from upstream when there are zero payload + * bytes. SO we trap those here to stop Keyspan & Windows from + * nuking the system. + */ + if (size == 0) { + return 0; + } + WriteFile (wsd->comport, obuf, size, &len, NULL); + if (len != (DWORD) size) { + fatal ("Write error. Wrote %d of %d bytes.\n", len, size); + } + return len; +} + +int32 GPS_Serial_Read(gpsdevh * dh, void *ibuf, int size) +{ + DWORD cnt = 0; + win_serial_data *wsd = (win_serial_data*)dh; + + ReadFile(wsd->comport, ibuf, size, &cnt, NULL); + return cnt; +} + +#else + +#include +#include +#include +#include + +typedef struct { + int fd; /* File descriptor */ + struct termios gps_ttysave; +} posix_serial_data; + +/* @func GPS_Serial_Open *********************************************** +** +** Open a serial port 8bits 1 stop bit 9600 baud +** +** @param [w] fd [int32 *] file descriptor +** @param [r] port [const char *] port e.g. ttyS1 +** +** @return [int32] false upon error +************************************************************************/ + +int32 GPS_Serial_Open(gpsdevh *dh, const char *port) +{ + struct termios tty; + posix_serial_data *psd = (posix_serial_data *)dh; + + /* + * This originally had O_NDELAY | O_NOCTTY in here, but this + * causes problems with Linux USB ttys (observed on PL2303 and MCT) + * and the rest of the code doesn't _REALLY_ handle the partial + * write/retry case anyway. - robertl + */ + if((psd->fd = open(port, O_RDWR))==-1) + { + GPS_Serial_Error("XSERIAL: Cannot open serial port '%s'", port); + gps_errno = SERIAL_ERROR; + return 0; + } + + if(tcgetattr(psd->fd,&psd->gps_ttysave)==-1) + { + gps_errno = HARDWARE_ERROR; + GPS_Serial_Error("SERIAL: tcgetattr error"); + return 0; + } + tty = psd->gps_ttysave; + + tty.c_cflag &= ~(CSIZE); + tty.c_cflag |= (CREAD | CS8 | CLOCAL); + cfsetospeed(&tty,B9600); + cfsetispeed(&tty,B9600); + + tty.c_lflag &= 0x0; + tty.c_iflag &= 0x0; + tty.c_oflag &= 0x0; + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + + if(tcsetattr(psd->fd,TCSANOW,&tty)==-1) + { + GPS_Serial_Error("SERIAL: tcsetattr error"); + return 0; + } + + return 1; +} + +/* + * Display an error from the serial subsystem. + */ +void GPS_Serial_Error(const char *mb, ...) +{ + va_list ap; + char msg[200]; + char *s; + int b; + + va_start(ap, mb); + b = vsnprintf(msg, sizeof(msg), mb, ap); + s = msg + b; + *s++ = ':'; + *s++ = ' '; + *s++ = '\0'; + +// FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, +// GetLastError(), 0, s, sizeof(msg) - b - 2, 0 ); + strcat(msg, strerror(errno)); + GPS_Error(msg); +} + +int32 GPS_Serial_Read(gpsdevh *dh, void *ibuf, int size) +{ + posix_serial_data *psd = (posix_serial_data *)dh; +#if GARMULATOR + static int l; + static char *rp; + char **rxp = &rxdata[l]; + char *hex; + char *rx = *rxp; + char *ib = ibuf; + + if (!rp) rp = rxdata[0]; + + /* Skip over nulls in our pasted strings */ + if (*rp == 0) { + rp = rxdata[++l]; + } + + *ib = strtoul(rp, &rp, 16); + if (*rp) rp++; + fprintf(stderr, "."); + return 1; + +#else + return read(psd->fd, ibuf, size); +#endif +} + +int32 GPS_Serial_Write(gpsdevh *dh, const void *obuf, int size) +{ + posix_serial_data *psd = (posix_serial_data *)dh; + return write(psd->fd, obuf, size); +} + + +/* @func GPS_Serial_Flush *********************************************** +** +** Flush the serial lines +** +** @param [w] fd [int32] file descriptor +** +** @return [int32] false upon error +************************************************************************/ +int32 GPS_Serial_Flush(gpsdevh *fd) +{ + posix_serial_data *psd = (posix_serial_data *)fd; + + if(tcflush(psd->fd,TCIOFLUSH)) + { + GPS_Serial_Error("SERIAL: tcflush error"); + gps_errno = SERIAL_ERROR; + return 0; + } + + return 1; +} + + + +/* @func GPS_Serial_Close *********************************************** +** +** Close serial port +** +** @param [r] fd [int32 ] file descriptor +** @param [r] port [const char *] port e.g. ttyS1 +** +** @return [int32] false upon error +************************************************************************/ + +int32 GPS_Serial_Close(gpsdevh *fd) +{ + posix_serial_data *psd = (posix_serial_data *)fd; + + if(tcsetattr(psd->fd, TCSAFLUSH, &psd->gps_ttysave)==-1) + { + gps_errno = HARDWARE_ERROR; + GPS_Serial_Error("SERIAL: tcsetattr error"); + return 0; + } + + if(close(psd->fd)==-1) + { + GPS_Serial_Error("SERIAL: Error closing serial port"); + gps_errno = SERIAL_ERROR; + return 0; + } + + return 1; +} + + +/* @func GPS_Serial_Chars_Ready ***************************************** +** +** Query port to see if characters are waiting to be read +** +** @param [r] fd [int32 ] file descriptor +** +** @return [int32] true if chars waiting +************************************************************************/ + +int32 GPS_Serial_Chars_Ready(gpsdevh *dh) +{ + fd_set rec; + struct timeval t; + posix_serial_data *psd = (posix_serial_data *)dh; + int32 fd = psd->fd; + +#if GARMULATOR + static foo; + /* Return sporadic reads just to torment the rest of the code. */ + if ((foo++ & 0xf) == 0) + return 1; + else + return 0; +#endif + + FD_ZERO(&rec); + FD_SET(fd,&rec); + + t.tv_sec = 0; + t.tv_usec = 1000; + (void) select(fd+1,&rec,NULL,NULL,&t); + if(FD_ISSET(fd,&rec)) + return 1; + + return 0; +} + + + +/* @func GPS_Serial_Wait *********************************************** +** +** Wait 80 milliseconds before testing for input. The GPS delay +** appears to be around 40-50 milliseconds. Doubling the value is to +** allow some leeway. +** +** @param [r] fd [int32 ] file descriptor +** +** @return [int32] true if serial chars waiting +************************************************************************/ + +int32 GPS_Serial_Wait(gpsdevh *dh) +{ + fd_set rec; + struct timeval t; + posix_serial_data *psd = (posix_serial_data *)dh; + + FD_ZERO(&rec); + FD_SET(psd->fd,&rec); + + t.tv_sec = 0; + t.tv_usec = 180000; /* Microseconds before GPS sends A001 */ + + (void) select(psd->fd+1,&rec,NULL,NULL,&t); + if(FD_ISSET(psd->fd,&rec)) + return 1; + + return 0; +} + + + +/* @func GPS_Serial_On ***************************************** +** +** Set up port +** +** @param [r] port [const char *] port +** @param [w] fd [int32 *] file descriptor +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Serial_On(const char *port, gpsdevh **dh) +{ + posix_serial_data *psd = xcalloc(sizeof (posix_serial_data), 1); + *dh = (gpsdevh*) psd; + + if(!GPS_Serial_Open((gpsdevh *) psd,port)) + { + GPS_Error("Cannot open serial port '%s'", port); + gps_errno = SERIAL_ERROR; + return 0; + } + + return 1; +} + + + +/* @func GPS_Serial_Off *********************************************** +** +** Done with port +** +** @param [r] port [const char *] port +** @param [r] fd [int32 ] file descriptor +** +** @return [int32] success +************************************************************************/ + +int32 GPS_Serial_Off(gpsdevh *dh) +{ + + if(!GPS_Serial_Close(dh)) + { + GPS_Error("Error Closing port"); + gps_errno = HARDWARE_ERROR; + return 0; + } + dh = NULL; + + return 1; +} + +#endif /* __WIN32__ */ diff --git a/jeeps/gpsserial.h b/jeeps/gpsserial.h new file mode 100644 index 000000000..bf245105e --- /dev/null +++ b/jeeps/gpsserial.h @@ -0,0 +1,36 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsserial_h +#define gpsserial_h + + +#include "gps.h" + +#define usecDELAY 180000 /* Microseconds before GPS sends A001 */ + +int32 GPS_Serial_Chars_Ready(gpsdevh * fd); +// int32 GPS_Serial_Close(int32 fd, const char *port); +// int32 GPS_Serial_Open(int32 *fd, const char *port); +// int32 GPS_Serial_Open_NMEA(int32 *fd, const char *port); +// int32 GPS_Serial_Restoretty(const char *port); +// int32 GPS_Serial_Savetty(const char *port); +int32 GPS_Serial_On(const char *port, gpsdevh **fd); +int32 GPS_Serial_Off(gpsdevh *fd); +int32 GPS_Serial_Wait(gpsdevh *fd); +int32 GPS_Serial_Flush(gpsdevh *fd); +// int32 GPS_Serial_On_NMEA(const char *port, gpsdevh **fd); +int32 GPS_Serial_Read(gpsdevh *fd, void *ibuf, int size); +int32 GPS_Serial_Write(gpsdevh *fd, const void *obuf, int size); +int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet); +int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); +void GPS_Serial_Error(const char *hdr, ...); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsusbcommon.c b/jeeps/gpsusbcommon.c new file mode 100644 index 000000000..35ac8d684 --- /dev/null +++ b/jeeps/gpsusbcommon.c @@ -0,0 +1,268 @@ +/* + Garmin USB layer - OS independent component. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "gps.h" +#include "garminusb.h" +#include "gpsusbcommon.h" + +/* + * This receive logic is a little convoluted as we go to some efforts here + * to hide most of the differences between the bulk only and bulk-interrupt + * protocols as exhibited in the handhelds and dashtops. + */ + +enum { + rs_fromintr, + rs_frombulk +} receive_state; + +static gusb_llops_t *gusb_llops; + +/* Decide when to truncate packets for debug output */ +#define DEBUG_THRESH ((global_opts.debug_level < 5) && (i > 10)) + +/* Called from OS layer to register its low-level entry points. */ +void +gusb_register_ll(gusb_llops_t *p) +{ + gusb_llops = p; +} + +int +gusb_close(gpsdevh *dh) +{ + garmin_usb_packet scratch; + + memset(&scratch, 0, sizeof(scratch)); + + switch (receive_state) { + case rs_frombulk: + gusb_cmd_get(&scratch, sizeof(scratch)); + break; + default: + break; + } + + gusb_llops->llop_close(dh); + return 1; + +#if BOOGER + garmin_usb_packet scratch = {0}; +abort(); + switch (receive_state) { + case rs_frombulk: + gusb_cmd_get(dh, &scratch, sizeof(scratch)); + break; + } + + return 1; +#endif +} + + +int +gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz) +{ + int rv; + unsigned char *buf = (unsigned char *) &ibuf->dbuf; + int orig_receive_state; +top: + orig_receive_state = receive_state; + switch (receive_state) { + case rs_fromintr: + rv = gusb_llops->llop_get_intr(ibuf, sz); + break; + case rs_frombulk: + rv = gusb_llops->llop_get_bulk(ibuf, sz); + break; + default: + fatal("Unknown receiver state %d\n", receive_state); + } + + if (gps_show_bytes) { + int i; + const char *m1, *m2; + unsigned short pkttype = le_read16(&ibuf->gusb_pkt.databuf[0]); + + GPS_Diag("RX (%s) [%d]:", + receive_state == rs_fromintr ? "intr" : "bulk", rv); + + for(i=0;igusb_pkt.pkt_id[0], pkttype, &m2); +if ((rv == 0) && (receive_state == rs_frombulk) ) {m1= "RET2INTR";m2=NULL;}; + GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); + } + + /* Adjust internal state and retry the read */ + if ((rv > 0) && (ibuf->gusb_pkt.pkt_id[0] == GUSB_REQUEST_BULK)) { + receive_state = rs_frombulk; + goto top; + } + /* + * If we were reading from the bulk pipe and we just got + * a zero request, adjust our internal state. + * It's tempting to retry the read here to hide this "stray" + * packet from our callers, but that only works when you know + * there's another packet coming. That works in every case + * except the A000 discovery sequence. + */ + if ((receive_state == rs_frombulk) && (rv <= 0)) { + receive_state = rs_fromintr; + } + + return rv; +} + +int +gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz) +{ + unsigned int rv, i; + + unsigned char *obuf = (unsigned char *) &opkt->dbuf; + const char *m1, *m2; + + rv = gusb_llops->llop_send(opkt, sz); + + if (gps_show_bytes) { + const unsigned short pkttype = le_read16(&opkt->gusb_pkt.databuf[0]); + GPS_Diag("TX [%d]:", sz); + + for(i=0;igusb_pkt.pkt_id[0], pkttype, &m2); + + GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); + } + /* + * Recursion, when used in a disciplined way, can be our friend. + * + * The Garmin protocol requires that packets that are exactly + * a multiple of the max tx size be followed by a zero length + * packet. Do that here so we can see it in debugging traces. + */ + + if (sz && !(sz % gusb_llops->max_tx_size)) { + gusb_cmd_send(opkt, 0); + } + + return (rv); +} + +void +gusb_list_units() +{ + int i; + + for (i = 0; i < GUSB_MAX_UNITS; i++) { + if (garmin_unit_info[i].serial_number) { + printf("%d %lu %lu %s\n", i, + garmin_unit_info[i].serial_number, + garmin_unit_info[i].unit_id, + garmin_unit_info[i].product_identifier + ); + } + } +} + +void +gusb_id_unit(struct garmin_unit_info *gu) +{ + static const char oid[12] = + {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int i; + + gusb_cmd_send((garmin_usb_packet *)oid, sizeof(oid)); + + for (i = 0; i < 25; i++) { + iresp.gusb_pkt.type = 0; + if (gusb_cmd_get(&iresp, sizeof(iresp)) < 0) { + return; + } + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { + gu->product_identifier = xstrdup((char *) iresp.gusb_pkt.databuf+4); + gu->unit_id = le_read16(iresp.gusb_pkt.databuf+0); + gu->unit_version = le_read16(iresp.gusb_pkt.databuf+2); + } + /* + * My goodnesss, this is fragile. During command syncup, + * we need to know if we're at the end. The 0xfd packet + * is promised by Garmin engineering to be the last. + */ + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) return; + } + fatal("Unable to sync with Garmin USB device in %d attempts.", i); +} + +void +gusb_syncup(void) +{ + static int unit_number; + static const char oinit[12] = + {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int i; + + /* + * This is our first communication with the unit. + */ + receive_state = rs_fromintr; + + for(i = 0; i < 25; i++) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + gusb_cmd_get(&iresp, sizeof(iresp)); + + if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && + (le_read32(iresp.gusb_pkt.datasz) == 4)) { + unsigned serial_number = le_read32(iresp.gusb_pkt.databuf); + garmin_unit_info[unit_number].serial_number = serial_number; + gusb_id_unit(&garmin_unit_info[unit_number]); + + unit_number++; + + return; + } + } + fatal("Unable to establish USB syncup\n"); +} diff --git a/jeeps/gpsusbcommon.h b/jeeps/gpsusbcommon.h new file mode 100644 index 000000000..b0865f5f0 --- /dev/null +++ b/jeeps/gpsusbcommon.h @@ -0,0 +1,45 @@ +/* + Garmin USB layer - OS independent component. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +/* + * The 'low level ops' are registered by the OS layer (win32, libusb, etc.) + * to provide gruntwork features for the common USB layer. + */ +typedef int (*gusb_llop_get)(garmin_usb_packet *ibuf, size_t sz); +typedef int (*gusb_llop_send)(const garmin_usb_packet *opkt, size_t sz); +typedef int (*gusb_llop_close) (gpsdevh *dh); + +typedef struct gusb_llops { + gusb_llop_get llop_get_intr; + gusb_llop_get llop_get_bulk; + gusb_llop_send llop_send; + gusb_llop_close llop_close; + int max_tx_size; +} gusb_llops_t; + +/* Provided by the common code. */ +void gusb_syncup(void); +void gusb_register_ll(struct gusb_llops *); +void gusb_list_units(void); + +/* Provided by the OS layers */ +// int gusb_init(const char *portname, gpsdev **dh); + diff --git a/jeeps/gpsusbint.h b/jeeps/gpsusbint.h new file mode 100644 index 000000000..8d91da24a --- /dev/null +++ b/jeeps/gpsusbint.h @@ -0,0 +1,27 @@ +/* + Definitions for internal functions of Garmin USB implementation. + These symbols should not be publicly used. They're "friend" functions + of USB details internal to jeeps. + + Copyright (C) 2005, 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +int32 GPS_Packet_Read_usb(gpsdevh *fd, GPS_PPacket *packet, int eatbulk); +void GPS_Make_Packet_usb(GPS_PPacket *packet, UC type, UC *data, int16 n); +int32 GPS_Write_Packet_usb(gpsdevh *fd, GPS_PPacket packet); + diff --git a/jeeps/gpsusbread.c b/jeeps/gpsusbread.c new file mode 100644 index 000000000..e266011dd --- /dev/null +++ b/jeeps/gpsusbread.c @@ -0,0 +1,78 @@ +/* + Decompose an incoming USB packet to make it look like a serial one. + + Copyright (C) 2004, 2006, 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include +#include "gps.h" +#include "garminusb.h" +#include "gpsusbint.h" + +/* + * Return values are: + * Negative on error. + * 1 if read success - even if empty packet. + */ +int32 GPS_Packet_Read_usb(gpsdevh *dh, GPS_PPacket *packet, int eat_bulk) +{ + int32 n; + int32 payload_size; + + garmin_usb_packet pkt; + + memset(&pkt, 0, sizeof(pkt)); +do_over: + n = gusb_cmd_get(&pkt, sizeof(pkt)); + + if ( n < 0 ) { + /* + * We (probably) used to have a GPS and it went away + * while we were speaking with it. Perhaps batteries + * died or it was unplugged or something. + */ + gps_errno = PROTOCOL_ERROR; + return n; + } + + /* + * This is a horrible hack for 276/296. This family sometimes + * switches between bulk and interrupt on EVERY packet. Rather + * than bother all the callers with that bit of unpleasantness, + * silently consume zero byte "switch back to intr" packets here. + * + * The one caller that doesn't want this hidden is device discovery + * in the A000 handler. + */ + if ((n == 0) && eat_bulk) { + goto do_over; + } + + /* + * Populate members of serial packet from USB packet. The + * copy here seems wasteful, but teaching all the callers about + * a structure with the "data" member being in a different place + * (Since the protocol packets was badly exposed in the core + * design of jeeps) is even more painful. + */ + (*packet)->type = le_read16(&pkt.gusb_pkt.pkt_id); + payload_size = le_read32(&pkt.gusb_pkt.datasz); + (*packet)->n = (UC) payload_size; + memcpy((*packet)->data, &pkt.gusb_pkt.databuf, payload_size); + + return 1; +} diff --git a/jeeps/gpsusbsend.c b/jeeps/gpsusbsend.c new file mode 100644 index 000000000..bd376b7e0 --- /dev/null +++ b/jeeps/gpsusbsend.c @@ -0,0 +1,62 @@ +/* + Form GarminUSB packets to send. + + Copyright (C) 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "gps.h" +#include +#include +#include "garminusb.h" +#include "gpsusbint.h" + +void +GPS_Make_Packet_usb(GPS_PPacket *packet, UC type, UC *data, int16 n) +{ + /* + * For the USB case, it's a little tacky that we just copy + * the params into *packet, but we really don't have any manipulations + * to do here. They're done in send_packet in order to keep the + * contents of *packet identical for the serial and USB cases. + */ + + (*packet)->type = type; + memcpy((*packet)->data, data, n); + (*packet)->n = (UC) n; + + return; +} + +int32 +GPS_Write_Packet_usb(gpsdevh *dh, GPS_PPacket packet) +{ + garmin_usb_packet gp; + memset(&gp, 0, sizeof(gp)); + + + /* + * Take the "portable" GPS_Packet data and put them into + * the USB packet that we will put on the wire. + */ + gp.gusb_pkt.type = 0x14; + le_write16(&gp.gusb_pkt.pkt_id, packet->type); + le_write32(&gp.gusb_pkt.datasz, packet->n ); + memcpy(&gp.gusb_pkt.databuf, packet->data, packet->n); + + return gusb_cmd_send(&gp, packet->n + 12); +} diff --git a/jeeps/gpsusbstub.c b/jeeps/gpsusbstub.c new file mode 100644 index 000000000..060bab422 --- /dev/null +++ b/jeeps/gpsusbstub.c @@ -0,0 +1,36 @@ +/* + Stubs to keep build happy when USB just isn't available to us. + + Copyright (C) 2004, 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +#include "config.h" +#include "../defs.h" +#if !HAVE_LIBUSB + +const char no_usb[] = "USB support is not available in this build.\n"; + +int +gusb_init(const char *portname) +{ + fatal(no_usb); + return 0; +} + +#endif /* defined(HAVE_LIBUSB) */ diff --git a/jeeps/gpsusbwin.c b/jeeps/gpsusbwin.c new file mode 100644 index 000000000..fd7a5cec5 --- /dev/null +++ b/jeeps/gpsusbwin.c @@ -0,0 +1,258 @@ +/* + Windows layer of Garmin/USB protocol. + + Copyright (C) 2004, 2006, 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "gps.h" +#include "gpsapp.h" +#include "garminusb.h" +#include "gpsusbcommon.h" + +/* Constants from Garmin doc. */ + +// {2C9C45C2-8E7D-4C08-A12D-816BBAE722C0} +DEFINE_GUID(GARMIN_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81, 0x6b, 0xba, 0xe7, 0x22, 0xc0); + +#define GARMIN_USB_API_VERSION 1 +#define GARMIN_USB_MAX_BUFFER_SIZE 4096 +#define GARMIN_USB_INTERRUPT_DATA_SIZE 64 + +#define IOCTL_GARMIN_USB_API_VERSION CTL_CODE \ + (FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_GARMIN_USB_INTERRUPT_IN CTL_CODE \ + (FILE_DEVICE_UNKNOWN, 0x850, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE CTL_CODE \ + (FILE_DEVICE_UNKNOWN, 0x851, METHOD_BUFFERED, FILE_ANY_ACCESS) + +typedef struct { + int booger; +} winusb_unit_data; + +static HANDLE *usb_handle = INVALID_HANDLE_VALUE; +static int usb_tx_packet_size ; + +static int +gusb_win_close(gpsdevh *handle) +{ + if (usb_handle != INVALID_HANDLE_VALUE) { + CloseHandle(usb_handle); + usb_handle = INVALID_HANDLE_VALUE; + } + + return 0; +} + +static int +gusb_win_get(garmin_usb_packet *ibuf, size_t sz) +{ + DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE; + unsigned char *buf = (unsigned char *) &ibuf->dbuf; + int tsz=0; + + while (sz) { + /* The driver wrongly (IMO) rejects reads smaller than + * GARMIN_USB_INTERRUPT_DATA_SIZE + */ + if(!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0, + buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) { + GPS_Serial_Error("Ioctl"); + fatal("ioctl\n"); + } + buf += rxed; + sz -= rxed; + tsz += rxed; + if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE) { + break; + } + } + return tsz; +} + +static int +gusb_win_get_bulk(garmin_usb_packet *ibuf, size_t sz) +{ + int n; + DWORD rsz; + unsigned char *buf = (unsigned char *) &ibuf->dbuf; + + n = ReadFile(usb_handle, buf, sz, &rsz, NULL); + + return rsz; +} + +static int +gusb_win_send(const garmin_usb_packet *opkt, size_t sz) +{ + DWORD rsz; + unsigned char *obuf = (unsigned char *) &opkt->dbuf; + + /* The spec warns us about making writes an exact multiple + * of the packet size, but isn't clear whether we can issue + * data in a single call to WriteFile if it spans buffers. + */ + WriteFile(usb_handle, obuf, sz, &rsz, NULL); + + if (rsz != sz) { + fatal ("Error sending %d bytes. Successfully sent %ld\n", sz, rsz); + } + + return rsz; +} + +static gusb_llops_t win_llops = { + gusb_win_get, + gusb_win_get_bulk, + gusb_win_send, + gusb_win_close +}; + +static +HANDLE * garmin_usb_start(HDEVINFO* hdevinfo, SP_DEVICE_INTERFACE_DATA *infodata) +{ + DWORD size; + PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL; + SP_DEVINFO_DATA devinfo; + + SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, + NULL, 0, &size, NULL); + + pdd = xmalloc(size); + pdd->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); + + devinfo.cbSize = sizeof(SP_DEVINFO_DATA); + if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, + pdd, size, NULL, &devinfo)) { + GPS_Serial_Error("SetupDiGetDeviceInterfaceDetail"); + return NULL; + } + + /* Whew. All that just to get something we can open... */ + GPS_Diag("Windows GUID for interface is \n\t%s\n", + pdd->DevicePath); + + if (usb_handle != INVALID_HANDLE_VALUE) { + fatal("garmin_usb_start called while device already started.\n"); + } + + usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ|GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL ); + if (usb_handle == INVALID_HANDLE_VALUE) { + if (GetLastError() == ERROR_ACCESS_DENIED) { + warning( +"Exclusive access is denied. It's likely that something else such as\n" +"Nroute, Spanner, Google Earth, or GPSGate already has control of the device\n"); + } + GPS_Serial_Error("(usb) CreateFile on '%s' failed", pdd->DevicePath); + return NULL; + } + + if(!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE, + NULL, 0, &usb_tx_packet_size, GARMIN_USB_INTERRUPT_DATA_SIZE, + &size, NULL)) { + fatal("Couldn't get USB packet size.\n"); + } + win_llops.max_tx_size = usb_tx_packet_size; + + gusb_syncup(); + + return usb_handle; +} + +/* + * Main entry point from the upper layer. Walk the device tree, find our + * device, and light it up. + */ +int +gusb_init(const char *pname, gpsdevh **dh) +{ + int req_unit_number = 0; + int un = 0; + int match; + + HDEVINFO hdevinfo; + SP_DEVICE_INTERFACE_DATA devinterface; + + winusb_unit_data *wud = xcalloc(sizeof (winusb_unit_data), 1); + *dh = (gpsdevh*) wud; + + gusb_register_ll(&win_llops); + + if (strlen(pname) > 4) { + if (0 == strcmp(pname+4, "list")) { + req_unit_number = -1; + } else { + req_unit_number = atoi(pname+4); + } + } + + hdevinfo = SetupDiGetClassDevs( (GUID *) &GARMIN_GUID, NULL, NULL, + DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); + + if (hdevinfo == INVALID_HANDLE_VALUE) { + GPS_Serial_Error("SetupDiGetClassDevs failed"); + warning("Is the Garmin USB driver installed?"); + return 0; + } + + devinterface.cbSize = sizeof(devinterface); + + if (req_unit_number >= 0) { + if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, + (GUID *) &GARMIN_GUID, + req_unit_number, &devinterface)) { + GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); + warning("Is the Garmin USB unit number %d powered up and connected?\nIs it really a USB unit? If it's serial, don't choose USB, choose serial.", un); + return 0; + } + /* We've matched. Now start the specific unit. */ + garmin_usb_start(hdevinfo, &devinterface); + return 1; + } + + /* + * Out unit nunber is less than zero, so loop over all units + * and display them. + */ + for(match = 0;;match++) { + if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, + (GUID *) &GARMIN_GUID, match, &devinterface)) { + if (GetLastError() == ERROR_NO_MORE_ITEMS) { + break; + } else { + GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); + warning("Is the Garmin USB unit number %d powered up and connected?", un); + return 0; + } + } + /* We've matched. Now start the specific unit. */ + garmin_usb_start(hdevinfo, &devinterface); + gusb_close(NULL); + } + gusb_list_units(); + exit (0); +} + diff --git a/jeeps/gpsutil.c b/jeeps/gpsutil.c new file mode 100644 index 000000000..4078e2e5e --- /dev/null +++ b/jeeps/gpsutil.c @@ -0,0 +1,699 @@ +/******************************************************************** +** @source JEEPS utility functions +** +** @author Copyright (C) 1999 Alan Bleasby +** @version 1.0 +** @modified Dec 28 1999 Alan Bleasby. First version +** @@ +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. +** +** You should have received a copy of the GNU Library General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +********************************************************************/ +#include "gps.h" +#include +#include +#include + +static int32 gps_endian_called=0; +static int32 GPS_Little=0; + +int32 gps_warning = 0; +int32 gps_error = 0; +int32 gps_user = 0; +int32 gps_show_bytes = 0; +int32 gps_errno = 0; + +/* @func GPS_Util_Little *********************************************** +** +** Determine endian nature of host +** +** @return [int32] true if little-endian +************************************************************************/ + +int32 GPS_Util_Little(void) +{ + static union lb + { + char chars[sizeof(int32)]; + int32 i; + } + data; + + if(!gps_endian_called) + { + gps_endian_called = 1; + data.i = 0; + *data.chars = '\1'; + if(data.i == 1) + GPS_Little = 1; + else + GPS_Little = 0; + } + + return GPS_Little; +} + + +/* @func GPS_Util_Get_Short ******************************************** +** +** Get a short from a string +** +** @return [US] value +************************************************************************/ + +US GPS_Util_Get_Short(const UC *s) +{ + static US ret; + UC *p; + + p = (UC *)&ret; + + if(!GPS_Little) + { + *p++ = *(s+1); + *p = *s; + } + else + { + *p++ = *s; + *p = *(s+1); + } + + return ret; +} + + + +/* @func GPS_Util_Put_Short ******************************************** +** +** Put a short to a string +** +** @param [w] s [UC *] string to write to +** @param [r] v [const US] short to write +** +** @return [void] +************************************************************************/ + +void GPS_Util_Put_Short(UC *s, const US v) +{ + UC *p; + + p = (UC *)&v; + + if(!GPS_Little) + { + *s++ = *(p+1); + *s = *p; + } + else + { + *s++ = *p; + *s = *(p+1); + } + + return; +} + + + +/* @func GPS_Util_Get_Double ******************************************** +** +** Get a double from a string +** +** @return [double] value +************************************************************************/ + +double GPS_Util_Get_Double(const UC *s) +{ + double ret; + UC *p; + int32 i; + + p = (UC *)&ret; + + + if(!GPS_Little) + for(i=sizeof(double)-1;i>-1;--i) + *p++ = s[i]; + else + for(i=0;i<(int32)sizeof(double);++i) + *p++ = s[i]; + + return ret; +} + + + +/* @func GPS_Util_Put_Double ******************************************** +** +** Put a double to a string +** +** @param [w] s [UC *] string to write to +** @param [r] v [const double] double to write +** +** @return [void] +************************************************************************/ + +void GPS_Util_Put_Double(UC *s, const double v) +{ + UC *p; + int32 i; + + p = (UC *)&v; + + if(!GPS_Little) + for(i=sizeof(double)-1;i>-1;--i) + s[i] = *p++; + else + for(i=0;i<(int32)sizeof(double);++i) + s[i] = *p++; + + return; +} + + + + +/* @func GPS_Util_Get_Int ******************************************** +** +** Get an int from a string +** +** @return [int32] value +************************************************************************/ + +int32 GPS_Util_Get_Int(const UC *s) +{ + int32 ret; + UC *p; + int32 i; + + p = (UC *)&ret; + + + if(!GPS_Little) + for(i=sizeof(int32)-1;i>-1;--i) + *p++ = s[i]; + else + for(i=0;i<(int32)sizeof(int32);++i) + *p++ = s[i]; + + return ret; +} + + + +/* @func GPS_Util_Put_Int ******************************************** +** +** Put a int to a string +** +** @param [w] s [UC *] string to write to +** @param [r] v [const int32] int to write +** +** @return [void] +************************************************************************/ + +void GPS_Util_Put_Int(UC *s, const int32 v) +{ + UC *p; + int32 i; + + p = (UC *)&v; + + if(!GPS_Little) + for(i=sizeof(int32)-1;i>-1;--i) + s[i] = *p++; + else + for(i=0;i<(int32)sizeof(int32);++i) + s[i] = *p++; + + return; +} + + + +/* @func GPS_Util_Get_Uint ******************************************** +** +** Get an unsigned int from a string +** +** @return [uint32] value +************************************************************************/ + +uint32 GPS_Util_Get_Uint(const UC *s) +{ + uint32 ret; + UC *p; + int32 i; + + p = (UC *)&ret; + + + if(!GPS_Little) + for(i=sizeof(uint32)-1;i>-1;--i) + *p++ = s[i]; + else + for(i=0;i<(int32)sizeof(uint32);++i) + *p++ = s[i]; + + return ret; +} + + + +/* @func GPS_Util_Put_Uint ******************************************** +** +** Put an unisgned int to a string +** +** @param [w] s [UC *] string to write to +** @param [r] v [const uint32] unsigned int to write +** +** @return [void] +************************************************************************/ + +void GPS_Util_Put_Uint(UC *s, const uint32 v) +{ + UC *p; + int32 i; + + p = (UC *)&v; + + if(!GPS_Little) + for(i=sizeof(uint32)-1;i>-1;--i) + s[i] = *p++; + else + for(i=0;i<(int32)sizeof(uint32);++i) + s[i] = *p++; + + return; +} + + + +/* @func GPS_Util_Get_Float ******************************************** +** +** Get a float from a string +** +** @return [float] value +************************************************************************/ + +float GPS_Util_Get_Float(const UC *s) +{ + float ret; + UC *p; + int32 i; + + p = (UC *)&ret; + + + if(!GPS_Little) + for(i=sizeof(float)-1;i>-1;--i) + *p++ = s[i]; + else + for(i=0;i<(int32)sizeof(float);++i) + *p++ = s[i]; + + return ret; +} + + + +/* @func GPS_Util_Put_Float ******************************************** +** +** Put a float to a string +** +** @param [w] s [UC *] string to write to +** @param [r] v [const float] float to write +** +** @return [void] +************************************************************************/ + +void GPS_Util_Put_Float(UC *s, const float v) +{ + UC *p; + int32 i; + + p = (UC *)&v; + + if(!GPS_Little) + for(i=sizeof(float)-1;i>-1;--i) + s[i] = *p++; + else + for(i=0;i<(int32)sizeof(float);++i) + s[i] = *p++; + + return; +} + +#if 0 +/* @func GPS_Util_Canon **************************************************** +** +** Sets or unsets canonical mode +** NB: Must have called this with True before calling with False +** NB: Remember to trun it off (false) eventually +** +** @param [r] state [int32] state=true->raw state=false->normal +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Util_Canon(int32 state) +{ + static struct termios tty; + static struct termios sv; + + + if(state) + { + tcgetattr(1,&sv); + tcgetattr(1, &tty); + tty.c_cc[VMIN]='\1'; + tty.c_cc[VTIME]='\0'; + tcsetattr(1,TCSANOW,&tty); + tty.c_lflag &= ~(ICANON | ECHO); + tcsetattr(1, TCSANOW, &tty); + } + else + tcsetattr(1, TCSANOW, &sv); + + return; +} +#endif + +#if 0 +/* @func GPS_Util_Block **************************************************** +** +** Sets or unsets blocking +** @modified 13-01-2000 to return an int +** +** @param [r] fd [int32] file descriptor +** @param [r] state [int32] state=true->block state=false->non-block +** +** @return [int32] success +** @@ +****************************************************************************/ + +int32 GPS_Util_Block(int32 fd, int32 state) +{ + static int32 notcalled=1; + static int32 block; + static int32 noblock; + int32 f; + + gps_errno = HARDWARE_ERROR; + + if(notcalled) + { + notcalled = 0; + if((f=fcntl(fd,F_GETFL,0))==-1) + { + GPS_Error("Util_Block: FCNTL error"); + return 0; + } + block = f & ~O_NDELAY; + noblock = f | O_NDELAY; + } + + if(state) + { + if(fcntl(fd,F_SETFL,block)==-1) + { + GPS_Error("Util_Block: Error blocking"); + return 0; + } + } + else + { + if(fcntl(fd,F_SETFL,noblock)==-1) + { + GPS_Error("Util_Block: Error unblocking"); + return 0; + } + } + + return 1; +} +#endif + + +/* @func GPS_Warning ******************************************************** +** +** Prints warning if gps_warning is true +** +** @param [r] s [char *] warning +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Warning(char *s) +{ + if(!gps_warning) + return; + + fprintf(stderr,"[WARNING] %s\n",s); + fflush(stderr); + + return; +} + + +/* @func GPS_Fatal ******************************************************** +** +** Always prints error and exits program +** Bad thing for a library so the library doesn't call it. +** +** @param [r] s [char *] fatal error +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Fatal(char *s) +{ + + fprintf(stderr,"[FATAL] %s\n",s); + exit(0); + return; +} + + + +/* @func GPS_Error ********************************************************** +** +** Prints Error if gps_error is true +** +** @param [r] s [char *] error +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Error(char *fmt, ...) +{ + va_list argp; + va_start(argp, fmt); + + if(!gps_error) + return; + + + fprintf(stderr, "[ERROR] "); + vfprintf(stderr, fmt, argp); + fprintf(stderr, "\n"); + + va_end(argp); + return; +} + + +/* @func GPS_Enable_Error *************************************************** +** +** Enable error message printing +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Enable_Error(void) +{ + gps_error = 1; + return; +} + + + +/* @func GPS_Enable_Warning *************************************************** +** +** Enable warning message printing +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Enable_Warning(void) +{ + gps_warning = 1; + return; +} + + + +/* @func GPS_Disable_Error *************************************************** +** +** Disable error message printing +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Disable_Error(void) +{ + gps_error = 0; + return; +} + + + +/* @func GPS_Disable_Warning *********************************************** +** +** Disable warning message printing +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Disable_Warning(void) +{ + gps_warning = 0; + return; +} + + + +/* @func GPS_User ******************************************************** +** +** Prints a message if gps_user is true +** +** @param [r] s [char *] message +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_User(const char *fmt, ...) +{ + va_list argp; + va_start (argp, fmt); + + if (gps_user) { + vfprintf(stdout, fmt, argp); + fflush(stdout); + } + + va_end(argp); +} + +/* @func GPS_Disable_User *********************************************** +** +** Disable message printing +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Disable_User(void) +{ + gps_user = 0; + return; +} + + +/* @func GPS_Enable_User *********************************************** +** +** Disable warning message printing +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Enable_User(void) +{ + gps_user = 1; + return; +} + + +/* @func GPS_Diagnose ******************************************************** +** +** Prints bytes read from gps if gps_show_bytes is set +** +** @param [r] cs [int32] byte read +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Diagnose(int32 c) +{ + if(!gps_show_bytes) + return; + + fprintf(stdout,"%d\n",(int)c); + fflush(stdout); + + return; +} + +void GPS_Diag(const char *fmt, ...) +{ + va_list argp; + va_start(argp, fmt); + + if(gps_show_bytes) { + vfprintf(stdout, fmt, argp); + } + va_end(argp); + return; + +} + +/* @func GPS_Enable_Diagnose *********************************************** +** +** Enable diagnosis mode +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Enable_Diagnose(void) +{ + gps_show_bytes = 1; + return; +} + + + +/* @func GPS_Disble_Diagnose *********************************************** +** +** Disable diagnosis mode +** +** @return [void] +** @@ +****************************************************************************/ + +void GPS_Disable_Diagnose(void) +{ + gps_show_bytes = 0; + return; +} diff --git a/jeeps/gpsutil.h b/jeeps/gpsutil.h new file mode 100644 index 000000000..faf1e0f06 --- /dev/null +++ b/jeeps/gpsutil.h @@ -0,0 +1,49 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsutil_h +#define gpsutil_h + + +#include "gps.h" + +int32 GPS_Util_Little(void); + +US GPS_Util_Get_Short(const UC *s); +void GPS_Util_Put_Short(UC *s, const US v); +int32 GPS_Util_Get_Int(const UC *s); +void GPS_Util_Put_Int(UC *s, const int32 v); +double GPS_Util_Get_Double(const UC *s); +void GPS_Util_Put_Double(UC *s, const double v); +float GPS_Util_Get_Float(const UC *s); +void GPS_Util_Put_Float(UC *s, const float v); +void GPS_Util_Canon(int32 state); +int32 GPS_Util_Block(int32 fd, int32 state); +void GPS_Util_Put_Uint(UC *s, const uint32 v); +uint32 GPS_Util_Get_Uint(const UC *s); + +void GPS_Warning(char *s); +void GPS_Error(char *fmt, ...); +void GPS_Serial_Error(const char *hdr, ...); +void GPS_Fatal(char *s); +void GPS_Enable_Error(void); +void GPS_Enable_Warning(void); +void GPS_Disable_Error(void); +void GPS_Disable_Warning(void); +void GPS_User(const char *fmt, ...); +void GPS_Disable_User(void); +void GPS_Enable_User(void); +void GPS_Diagnose(int32 c); +void GPS_Diag(const char *fmt, ...); + +void GPS_Enable_Diagnose(void); +void GPS_Disable_Diagnose(void); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/main.c b/jeeps/main.c new file mode 100644 index 000000000..a8488248b --- /dev/null +++ b/jeeps/main.c @@ -0,0 +1,31 @@ +#include "gps.h" +// #include "jeeps.h" + +main() +{ + int n; + GPS_PWay *way; + GPS_PWay *array; + + if (GPS_Init("/dev/ttyS0") < 0) { + fprintf(stderr, "Can't init\n"); + } + + if((n=GPS_Command_Get_Waypoint("/dev/ttyS0", &way))<0) { + fprintf(stderr, "can't get\n"); + return; + } +// fprintf(stdout," Done\n"); + + GPS_Fmt_Print_Waypoint(way, n, stdout); + + array = (GPS_PWay *) calloc(1, sizeof(GPS_PWay)); + array[0] = GPS_Way_New(); + strcpy(array[0]->ident,"lower @#$%^&* rocks"); + strcpy(array[0]->cmnt,"COMMENTCOMMENTCOMMENTCOMMENTCOMMENT"); + array[0]->wpt_class = 0; + array[0]->lat = 1.234; + array[0]->lon = 1.234; +GPS_Command_Send_Waypoint("/dev/ttyS0", array, 1); + +} diff --git a/kml.c b/kml.c new file mode 100644 index 000000000..3f99db5c6 --- /dev/null +++ b/kml.c @@ -0,0 +1,1256 @@ +/* + Support for Google Earth & Keyhole "kml" format. + + Copyright (C) 2005, 2006, 2007 Robert Lipe, robertlipe@usa.net + Updates by Andrew Kirmse, akirmse at google.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "xmlgeneric.h" +#include "grtcirc.h" + +#ifdef __WIN32__ +# include +#endif + +// options +static char *opt_deficon = NULL; +static char *opt_export_lines = NULL; +static char *opt_export_points = NULL; +static char *opt_line_width = NULL; +static char *opt_line_color = NULL; +static char *opt_floating = NULL; +static char *opt_extrude = NULL; +static char *opt_trackdata = NULL; +static char *opt_trackdirection = NULL; +static char *opt_units = NULL; +static char *opt_labels = NULL; +static char *opt_max_position_points = NULL; + +static int export_lines; +static int export_points; +static int floating; +static int extrude; +static int trackdata; +static int trackdirection; +static int max_position_points; + +static int indent_level; + +static waypoint *wpt_tmp; +static int wpt_tmp_queued; +static const char *posnfilename; +static char *posnfilenametmp; + +static gbfile *ofd; + +typedef struct { + double latitude; + double longitude; + double altitude; +} point3d; + +typedef enum { + kmlpt_unknown, + kmlpt_waypoint, + kmlpt_track, + kmlpt_route, + kmlpt_other +} kml_point_type; + +static int point3d_list_len; +static point3d *point3d_list; +static int realtime_positioning; +static int do_indentation = 1; + +#define TD(FMT,DATA) kml_write_xml(0, "" FMT " \n", DATA) +#define TD2(FMT,DATA, DATA2) kml_write_xml(0, "" FMT " \n", DATA, DATA2) + +// Icons provided and hosted by Google. Used with permission. +#define ICON_BASE "http://earth.google.com/images/kml-icons/" + +static const char kml22_hdr[] = + "\n"; +// No "baked in" schemaLocation, per Google recommendation. +// "\txsi:schemaLocation=\"http://earth.google.com/kml/2.2 \n" +// "\thttp://code.google.com/apis/kml/schema/kml22beta.xsd\">\n"; + +static const char kml21_hdr[] = + "\n"; +// No "baked in" schemaLocation, per Google recommendation. +// "\txsi:schemaLocation=\"http://earth.google.com/kml/2.1 \n" +// "\thttp://code.google.com/apis/kml/schema/kml21.xsd\">\n"; + +static +arglist_t kml_args[] = { + {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"lines", &opt_export_lines, + "Export linestrings for tracks and routes", + "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"points", &opt_export_points, + "Export placemarks for tracks and routes", + "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"line_width", &opt_line_width, + "Width of lines, in pixels", + "6", ARGTYPE_INT, ARG_NOMINMAX }, + {"line_color", &opt_line_color, + "Line color, specified in hex AABBGGRR", + "99ffac59", ARGTYPE_STRING, ARG_NOMINMAX }, + {"floating", &opt_floating, + "Altitudes are absolute and not clamped to ground", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"extrude", &opt_extrude, + "Draw extrusion line from trackpoint to ground", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"trackdata", &opt_trackdata, + "Include extended data for trackpoints (default = 1)", + "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"trackdirection", &opt_trackdirection, + "Indicate direction of travel in track icons (default = 0)", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"units", &opt_units, + "Units used when writing comments ('s'tatute or 'm'etric)", + "s", ARGTYPE_STRING, ARG_NOMINMAX }, + {"labels", &opt_labels, + "Display labels on track and routepoints (default = 1)", + "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"max_position_points", &opt_max_position_points, + "Retain at most this number of position points (0 = unlimited)", + "0", ARGTYPE_INT, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static +struct { + int freshness; + char *icon; +} kml_tracking_icons[] = { + { 60, ICON_BASE "youarehere-60.png" }, // Red + { 30, ICON_BASE "youarehere-30.png" }, // Yellow + { 0, ICON_BASE "youarehere-0.png" }, // Green +}; + +#define ICON_NOSAT ICON_BASE "youarehere-warning.png"; +#define ICON_WPT "http://maps.google.com/mapfiles/kml/pal4/icon61.png" +#define ICON_TRK ICON_BASE "track-directional/track-none.png" +#define ICON_RTE ICON_BASE "track-directional/track-none.png" +#define ICON_DIR ICON_BASE "track-directional/track-%d.png" // format string where next arg is rotational degrees. + +#define MYNAME "kml" + +#if ! HAVE_LIBEXPAT +static void +kml_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded KML support because expat was not installed.\n"); +} + +static void +kml_read(void) +{ +} +#else + +static xg_callback wpt_s, wpt_e; +static xg_callback wpt_name, wpt_desc, wpt_coord, wpt_icon, trk_coord, wpt_time; + +static +xg_tag_mapping kml_map[] = { + { wpt_s, cb_start, "/Placemark" }, + { wpt_e, cb_end, "/Placemark" }, + { wpt_name, cb_cdata, "/Placemark/name" }, + { wpt_desc, cb_cdata, "/Placemark/description" }, + { wpt_time, cb_cdata, "/Placemark/TimeStamp/when" }, + { wpt_coord, cb_cdata, "/Placemark/Point/coordinates" }, + { wpt_icon, cb_cdata, "/Placemark/Style/Icon/href" }, + { trk_coord, cb_cdata, "/Placemark/MultiGeometry/LineString/coordinates" }, + { trk_coord, cb_cdata, "/Placemark/GeometryCollection/LineString/coordinates" }, + { trk_coord, cb_cdata, "/Placemark/Polygon/outerBoundaryIs/LinearRing/coordinates" }, + { trk_coord, cb_cdata, "/Placemark/LineString/coordinates" }, + { NULL, 0, NULL } +}; + +static +const char * kml_tags_to_ignore[] = { + "kml", + "Document", + "Folder", + NULL, +}; + +void wpt_s(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); + wpt_tmp_queued = 0; +} + +void wpt_e(const char *args, const char **unused) +{ + if (wpt_tmp_queued) { + waypt_add(wpt_tmp); + } + wpt_tmp_queued = 0; +} + +void wpt_name(const char *args, const char **unused) +{ + if (args) wpt_tmp->shortname = xstrdup(args); +} + +void wpt_desc(const char *args, const char **unused) +{ + if (args) { + char *tmp, *c; + + tmp = xstrdup((char *)args); + c = lrtrim(tmp); + if (*c) { + wpt_tmp->description = xstrappend(wpt_tmp->description, c); + } + xfree(tmp); + } +} + +void wpt_time(const char *args, const char **unused) +{ + wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); +} + +void wpt_coord(const char *args, const char **attrv) +{ + sscanf(args, "%lf,%lf,%lf", &wpt_tmp->longitude, &wpt_tmp->latitude, &wpt_tmp->altitude); + wpt_tmp_queued = 1; +} + +void wpt_icon(const char *args, const char **unused) +{ + if (wpt_tmp) { + wpt_tmp->icon_descr = xstrdup(args); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + } +} + +void trk_coord(const char *args, const char **attrv) +{ + int consumed = 0; + double lat, lon, alt; + waypoint *trkpt; + + route_head *trk_head = route_head_alloc(); + if (wpt_tmp->shortname) { + trk_head->rte_name = xstrdup(wpt_tmp->shortname); + } + track_add_head(trk_head); + + while (3 == sscanf(args, "%lf,%lf,%lf %n", &lon, &lat, &alt, &consumed)){ + trkpt = waypt_new(); + trkpt->latitude = lat; + trkpt->longitude = lon; + trkpt->altitude = alt; + + track_add_wpt(trk_head, trkpt); + + args += consumed; + } +} + +static +void +kml_rd_init(const char *fname) +{ + xml_init(fname, kml_map, NULL); + xml_ignore_tags(kml_tags_to_ignore); +} + +static +void +kml_read(void) +{ + xml_read(); +} +#endif + +static void +kml_rd_deinit(void) +{ + xml_deinit(); +} + +static void +kml_wr_init(const char *fname) +{ + char u = 's'; + + if (opt_units) { + u = tolower(opt_units[0]); + } + + switch(u) { + case 's': fmt_setunits(units_statute); break; + case 'm': fmt_setunits(units_metric); break; + default: fatal("Units argument '%s' should be 's' for statute units or 'm' for metric.", opt_units); break; + } + /* + * Reduce race conditions with network read link. + */ + ofd = gbfopen(fname, "w", MYNAME); +} + +/* + * The magic here is to try to ensure that posnfilename is atomically + * updated. + */ +static void +kml_wr_position_init(const char *fname) +{ + posnfilename = fname;; + posnfilenametmp = xstrappend(xstrdup(fname), "-"); + realtime_positioning = 1; + + /* + * 30% of our output file is whitespace. Since parse time + * matters in this mode, turn the pretty formatting off. + */ + do_indentation = 0; + + max_position_points = atoi(opt_max_position_points); +} + +static void +kml_wr_deinit(void) +{ + gbfclose(ofd); + + if (posnfilenametmp) { +#if __WIN32__ + MoveFileEx(posnfilenametmp, posnfilename, + MOVEFILE_REPLACE_EXISTING); +#endif + rename(posnfilenametmp, posnfilename); + } + ofd = NULL; +} + +static void +kml_wr_position_deinit(void) +{ +// kml_wr_deinit(); + if (posnfilenametmp) { + xfree(posnfilenametmp); + posnfilenametmp = NULL; + } +} + +/* + * Indent is a direction to change indention level. + * If positive, increase one level after printing this line. + * If zero, just print this line at the current indent leve. + * If negative, descrease the indent level. + */ +static void +kml_write_xml(int indent, const char *fmt, ...) +{ + va_list args; + int i; + va_start(args, fmt); + + if (indent < 0) indent_level--; + + if (fmt[1] != '!' && do_indentation) { + for (i = 0; i < indent_level; i++) { + gbfputs(" ", ofd); + } + } + + gbvfprintf(ofd, fmt, args); + + if (indent > 0) indent_level++; + + va_end(args); +} + +/* + * Write an optional tag with a value that may need to be entity escaped. + * Never changes indention leve, but does honour it. + */ +static void +kml_write_xmle(const char *tag, const char *v) +{ + int i; + if (v && *v) { + char *tmp_ent = xml_entitize(v); + for (i = 0; i < indent_level; i++) { + gbfputs(" ", ofd); + } + gbfprintf(ofd, "<%s>%s\n",tag, tmp_ent, tag); + xfree(tmp_ent); + } +} + +#define hovertag(h) h ? 'h' : 'n' +static void kml_write_bitmap_style_(const char *style, const char * bitmap, + int highlighted, int force_heading) +{ + kml_write_xml(0, "\n", + highlighted ? "Highlighted" : "Normal", style); + kml_write_xml(1, "\n"); +} + +/* A wrapper for the above function to emit both a highlighted + * and non-highlighted version of the style to allow the icons + * to magnify slightly on a rollover. + */ +static void kml_write_bitmap_style(kml_point_type pt_type, const char *bitmap, + const char *customstyle) +{ + int force_heading = 0; + const char *style; + switch (pt_type) { + case kmlpt_track: style = "track"; break; + case kmlpt_route: style = "route"; break; + case kmlpt_waypoint: style = "waypoint"; break; + case kmlpt_other: style = customstyle; force_heading = 1; break; + default: fatal("kml_output_point: unknown point type"); break; + } + + kml_write_bitmap_style_(style, bitmap, 0, force_heading); + kml_write_bitmap_style_(style, bitmap, 1, force_heading); + + kml_write_xml(1, "\n", style); + kml_write_xml(1, "\n"); + kml_write_xml(0, "normal\n"); + kml_write_xml(0, "#%s_%c\n",style, hovertag(0)); + kml_write_xml(-1, "\n"); + kml_write_xml(1, "\n"); + kml_write_xml(0, "highlight\n"); + kml_write_xml(0, "#%s_%c\n",style, hovertag(1)); + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); +} + +static void kml_output_timestamp(const waypoint *waypointp) +{ + char time_string[64]; + if (waypointp->creation_time) { + xml_fill_in_time(time_string, waypointp->creation_time, waypointp->microseconds, XML_LONG_TIME); + if (time_string[0]) { + kml_write_xml(0, "%s\n", + time_string); + } + } +} + +/* + * Output the track summary. + */ +static +void kml_output_trkdescription(const route_head *header, computed_trkdata *td) +{ + char *max_alt_units; + double max_alt; + char *min_alt_units; + double min_alt; + char *distance_units; + double distance; + + if (!td || !trackdata) { + return; + } + + max_alt = fmt_distance(td->max_alt, &max_alt_units); + min_alt = fmt_distance(td->min_alt, &min_alt_units); + distance = fmt_distance(td->distance_meters, &distance_units); + + kml_write_xml(0, "\n"); + + kml_write_xml(1, "\n"); + kml_write_xml(1, "\n"); + + if (header->rte_desc) { + TD("Description %s", header->rte_desc); + } + TD2("Distance %.1f %s", distance, distance_units); + if (min_alt != unknown_alt) { + TD2("Min Alt %.3f %s", min_alt, min_alt_units); + } + if (max_alt != unknown_alt) { + TD2("Max Alt %.3f %s", max_alt, max_alt_units); + } + if (td->min_spd) { + char *spd_units; + double spd = fmt_speed(td->min_spd, &spd_units); + TD2("Min Speed %.1f %s", spd, spd_units); + } + if (td->max_spd) { + char *spd_units; + double spd = fmt_speed(td->max_spd, &spd_units); + TD2("Max Speed %.1f %s", spd, spd_units); + } + if (td->max_spd && td->start && td->end) { + char *spd_units; + time_t elapsed = td->end - td->start; + double spd = fmt_speed(td->distance_meters / elapsed, &spd_units); + if (spd > 1.0) { + TD2("Avg Speed %.1f %s", spd, spd_units); + } + } + if (td->avg_hrt) { + TD("Avg Heart Rate %.1f bpm", td->avg_hrt); + } + if (td->min_hrt < td->max_hrt) { + TD("Min Heart Rate %d bpm", td->min_hrt); + } + if (td->max_hrt) { + TD("Max Heart Rate %d bpm", td->max_hrt); + } + if (td->avg_cad) { + TD("Avg Cadence %.1f rpm", td->avg_cad); + } + if (td->max_cad) { + TD("Max Cadence %d rpm", td->max_cad); + } + if (td->start && td->end) { + char time_string[64]; + + xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); + TD("Start Time %s ", time_string); + xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); + TD("End Time %s ", time_string); + } + + kml_write_xml(-1, "]]>\n"); + kml_write_xml(-1, "\n"); + + /* We won't always have times. Garmin saved tracks, for example... */ + if (td->start && td->end) { + char time_string[64]; + kml_write_xml(1, "\n"); + xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); + kml_write_xml(0, "%s\n", time_string); + xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); + kml_write_xml(0, "%s\n", time_string); + kml_write_xml(-1, "\n"); + } +} + + +static +void kml_output_header(const route_head *header, computed_trkdata*td) +{ + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + } + kml_write_xmle("name", header->rte_name); + kml_output_trkdescription(header, td); + + if (export_points && header->rte_waypt_ct > 0) { + // Put the points in a subfolder + kml_write_xml(1, "\n"); + kml_write_xml(0, "Points\n"); + } + + // Create an array for holding waypoint coordinates so that we + // can produce a LineString at the end. + point3d_list = (point3d *) xmalloc(header->rte_waypt_ct * sizeof(point3d)); + point3d_list_len = 0; +} + +/* Rather than a default "top down" view, view from the side to highlight + * topo features. + */ +static void kml_output_lookat(const waypoint *waypointp) +{ + kml_write_xml(1, "\n"); + kml_write_xml(0, "%f\n", waypointp->longitude); + kml_write_xml(0, "%f\n", waypointp->latitude); + kml_write_xml(0, "66\n"); + kml_write_xml(-1, "\n"); +} + +/* Output something interesing when we can for route and trackpoints */ +static void kml_output_description(const waypoint *pt) +{ + char *alt_units; + double alt; + + if (!trackdata) { + return; + } + + alt = fmt_distance(pt->altitude, &alt_units); + + kml_write_xml(1, "\n"); + + TD("Longitude: %f", pt->longitude); + TD("Latitude: %f", pt->latitude); + if (pt->altitude != unknown_alt) TD2("Altitude: %.3f %s", alt, alt_units); + if (pt->heartrate) TD("Heart rate: %d", pt->heartrate); + if (pt->cadence) TD("Cadence: %d", pt->cadence); + if WAYPT_HAS(pt, temperature) TD("Temperature: %.1f", pt->temperature); + if WAYPT_HAS(pt, speed) { + char *spd_units; + double spd = fmt_speed(pt->speed, &spd_units); + TD2("Speed: %.1f %s", spd, spd_units); + } + if WAYPT_HAS(pt, course) TD("Heading: %.1f", pt->course); + /* This really shouldn't be here, but as of this writing, + * Earth can't edit/display the TimeStamp. + */ + if (pt->creation_time) { + char time_string[64]; + + xml_fill_in_time(time_string, pt->creation_time, + pt->microseconds, XML_LONG_TIME); + if (time_string[0]) { + TD("Time: %s", time_string); + } + } + + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "]]>\n"); +} + +static void kml_output_point(const waypoint *waypointp, kml_point_type pt_type) +{ + char *style; + // Save off this point for later use + point3d *pt = &point3d_list[point3d_list_len]; + point3d_list_len++; + + switch (pt_type) { + case kmlpt_track: style = "#track"; break; + case kmlpt_route: style = "#route"; break; + default: fatal("kml_output_point: unknown point type"); break; + } + + switch (pt_type) { + case kmlpt_track: style = "#track"; break; + case kmlpt_route: style = "#route"; break; + default: fatal("kml_output_point: unknown point type"); break; + } + + pt->longitude = waypointp->longitude; + pt->latitude = waypointp->latitude; + pt->altitude = waypointp->altitude == unknown_alt ? 0.0 : waypointp->altitude; + + if (export_points) { + kml_write_xml(1, "\n"); + if (atoi(opt_labels)) { + kml_write_xmle("name", waypointp->shortname); + } + kml_write_xml(0, "\n"); + kml_output_description(waypointp); + kml_output_lookat(waypointp); + kml_output_timestamp(waypointp); + + if (trackdirection && (pt_type == kmlpt_track)) { + char buf[100]; + if (waypointp->speed < 1) + snprintf(buf, sizeof(buf), "%s-none", style); + else + snprintf(buf, sizeof(buf), "%s-%d", style, + (int) (waypointp->course / 22.5 + .5) % 16); + kml_write_xml(0, "%s\n", buf); + } else { + kml_write_xml(0, "%s\n", style); + } + + kml_write_xml(1, "\n"); + if (floating) { + kml_write_xml(0, "absolute\n"); + } + if (extrude) { + kml_write_xml(0, "1\n"); + } + kml_write_xml(0, "%f,%f,%f\n", + pt->longitude, pt->latitude, pt->altitude); + kml_write_xml(-1, "\n"); + + + kml_write_xml(-1, "\n"); + } +} + + +static void kml_output_tailer(const route_head *header) +{ + int i; + + if (export_points && point3d_list_len > 0) { + kml_write_xml(-1, "\n"); + } + + // Add a linestring for this track? + if (export_lines && point3d_list_len > 0) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Path\n"); + kml_write_xml(0, "#lineStyle\n"); + kml_write_xml(1, "\n"); + if (floating) { + kml_write_xml(0, "absolute\n"); + } + if (extrude) { + kml_write_xml(0, "1\n"); + } + kml_write_xml(0, "1\n"); + kml_write_xml(1, "\n"); + for (i = 0; i < point3d_list_len; ++i) + kml_write_xml(0, "%f,%f,%f\n", + point3d_list[i].longitude, + point3d_list[i].latitude, + point3d_list[i].altitude); + + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); + } + + xfree(point3d_list); + point3d_list = NULL; + + if (!realtime_positioning) { + kml_write_xml(-1, "\n"); + } +} + +/* + * Completely different writer for geocaches. + */ +static +void kml_gc_make_ballonstyle(void) +{ + // BalloonStyle for Geocaches. + kml_write_xml(1, "\n"); +} + +static +char * +kml_lookup_gc_icon(const waypoint *waypointp) +{ + const char *icon; + char *rb; + + /* This could be done so much better in C99 with designated + * initializers... + */ + switch (waypointp->gc_data.type) { + case gt_traditional: icon = "2.png"; break; + case gt_multi: icon = "3.png"; break; + case gt_virtual: icon = "4.png"; break; + case gt_letterbox: icon = "5.png"; break; + case gt_event: icon = "6.png"; break; + case gt_ape: icon = "7.png"; break; + case gt_locationless: icon = "8.png"; break; // No unique icon. + case gt_suprise: icon = "8.png"; break; + case gt_webcam: icon = "11.png"; break; + case gt_cito: icon = "13.png"; break; + case gt_earth: icon = "earthcache.png"; break; + case gt_mega: icon = "6.png"; break; // No unique icon yet. + default: icon = "8.png"; break; + } + + xasprintf(&rb, "http://www.geocaching.com/images/kml/%s", icon); + return rb; +} + +static +char * +kml_lookup_gc_container(const waypoint *waypointp) +{ + char *cont; + + switch (waypointp->gc_data.container) { + case gc_micro: cont="micro"; break; + case gc_regular: cont="regular"; break; + case gc_large: cont="large"; break; + case gc_small: cont="small"; break; + case gc_virtual: cont="virtual"; break; + case gc_other: cont="other"; break; + default: cont="not_chosen"; break; + } + + return cont; +} + +// Not thread safe. Return strings are small and it's silly to xasprintf/free +// them so we use a static buffer. + +char * kml_gc_mkstar(int rating) +{ + static char tmp[40]; + if (0 == rating % 10) { + snprintf(tmp, sizeof(tmp), "stars%d", rating / 10); + } else { + snprintf(tmp, sizeof(tmp), "stars%d_%d", rating / 10, rating % 10); + } + + return tmp; +} + +static void kml_geocache_pr(const waypoint *waypointp) +{ + char *p, *is; + double lat = waypointp->latitude; + double lng = waypointp->longitude; +// optionally "fuzz" lat/lng here. + + kml_write_xml(1, "\n"); + + kml_write_xml(1, "\n"); + kml_write_xml(0, "\n", waypointp->url_link_text); + kml_write_xml(-1, "\n"); + + // Timestamp + kml_output_timestamp(waypointp); + + kml_write_xml(0, "#geocache\n"); + is = kml_lookup_gc_icon(waypointp); + kml_write_xml(1, "\n"); + + kml_write_xml(1, "\n"); + kml_write_xml(0, "%s\n", waypointp->shortname); + + if(waypointp->url_link_text) { + p = xml_entitize(waypointp->url_link_text); + kml_write_xml(0, "%s\n", p); + xfree(p); + } + + if (waypointp->gc_data.placer) { + p = xml_entitize(waypointp->gc_data.placer); + kml_write_xml(0, "%s\n", p); + xfree(p); + } + + kml_write_xml(0, "%d\n", waypointp->gc_data.placer_id); + + kml_write_xml(0, "%s\n", kml_gc_mkstar(waypointp->gc_data.diff)); + kml_write_xml(0, "%s\n", kml_gc_mkstar(waypointp->gc_data.terr)); + + kml_write_xml(0, "%s\n", kml_lookup_gc_container(waypointp)); + + // Highlight any issues with the cache, such as temp unavail + // or archived. + kml_write_xml(0, ""); + if (waypointp->gc_data.is_archived == status_true) { + kml_write_xml(0, "<font color=\"red\">This cache has been archived.</font>
\n"); + } else if (waypointp->gc_data.is_available == status_false) { + kml_write_xml(0, "<font color=\"red\">This cache is temporarily unavailable.</font>
\n"); + } + kml_write_xml(0, "
\n"); + + kml_write_xml(0, "%s\n", gs_get_cachetype(waypointp->gc_data.type)); + kml_write_xml(0, "\n", waypointp->gc_data.desc_short.utfstring ? waypointp->gc_data.desc_short.utfstring : ""); + kml_write_xml(0, "\n", waypointp->gc_data.desc_long.utfstring ? waypointp->gc_data.desc_long.utfstring : ""); + + kml_write_xml(-1, "
\n"); + + // Location + kml_write_xml(1, "\n"); + kml_write_xml(0, "%f,%f,%f\n", + lng, lat, + waypointp->altitude == unknown_alt ? 0.0 : waypointp->altitude); + + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "
\n"); + + xfree(is); +} + +/* + * WAYPOINTS + */ + +static void kml_waypt_pr(const waypoint *waypointp) +{ + const char *icon; + +#if 0 // Experimental + if(realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "%f\n", waypointp->longitude); + kml_write_xml(0, "%f\n", waypointp->latitude); + kml_write_xml(0, "1000\n"); + kml_write_xml(-1, "\n"); + } +#endif + + if (waypointp->gc_data.diff && waypointp->gc_data.terr) { + kml_geocache_pr(waypointp); + return; + } + + kml_write_xml(1, "\n"); + + kml_write_xmle("name", waypointp->shortname); + + // Description + if (waypointp->url && waypointp->url[0]) { + char * odesc = xml_entitize(waypointp->url); + kml_write_xml(0, "\n"); + kml_write_xml(0, "\n"); + if (waypointp->url_link_text && waypointp->url_link_text[0]) { + char *olink = xml_entitize(waypointp->url_link_text); + kml_write_xml(0, "%s
]]>", odesc, olink); + xfree(olink); + } else { + gbfputs(odesc, ofd); + } + + kml_write_xml(0, "\n"); + xfree(odesc); + } + + // Timestamp + kml_output_timestamp(waypointp); + + // Icon - but only if it looks like a URL. + icon = opt_deficon ? opt_deficon : waypointp->icon_descr; + if (icon && strstr(icon, "://")) { + kml_write_xml(1, "\n"); + } else { + kml_write_xml(0, "#waypoint\n"); + } + + // Location + kml_write_xml(1, "\n"); + + if (extrude) { + kml_write_xml(0, "1\n"); + } + + if (floating) { + kml_write_xml(0, "absolute\n"); + } + + kml_write_xml(0, "%f,%f,%f\n", + waypointp->longitude, waypointp->latitude, + waypointp->altitude == unknown_alt ? 0.0 : waypointp->altitude); + kml_write_xml(-1, "\n"); + + kml_write_xml(-1, "\n"); +} + +/* + * TRACKPOINTS + */ + +static void kml_track_hdr(const route_head *header) +{ + computed_trkdata *td; + track_recompute(header, &td); + kml_output_header(header, td); + xfree(td); +} + +static void kml_track_disp(const waypoint *waypointp) +{ + kml_output_point(waypointp, kmlpt_track); +} + +static void kml_track_tlr(const route_head *header) +{ + kml_output_tailer(header); +} + +/* + * ROUTES + */ + +static void kml_route_hdr(const route_head *header) +{ + kml_output_header(header, NULL); +} + +static void kml_route_disp(const waypoint *waypointp) +{ + kml_output_point(waypointp, kmlpt_route); +} + +static void kml_route_tlr(const route_head *header) +{ + kml_output_tailer(header); +} + +void kml_write(void) +{ + char import_time[100]; + time_t now; + + // Parse options + export_lines = (0 == strcmp("1", opt_export_lines)); + export_points = (0 == strcmp("1", opt_export_points)); + floating = (!! strcmp("0", opt_floating)); + extrude = (!! strcmp("0", opt_extrude)); + trackdata = (!! strcmp("0", opt_trackdata)); + trackdirection = (!! strcmp("0", opt_trackdirection)); + + kml_write_xml(0, "\n"); + + /* + * This is a bit cowardly. Our geocache writer takes advantage + * of KML 2.2 features present only in Earth 4.2 and newer. The + * output is actually compatible with Earth versions back to 4.0 + * for the non-geocaching case, so we'll be conservative and not + * output the new namespace if we don't need it. + */ + if (geocaches_present) { + kml_write_xml(1, kml22_hdr); + } else { + kml_write_xml(1, kml21_hdr); + } + + kml_write_xml(1, "\n"); + + now = current_time(); + strftime(import_time, sizeof(import_time), "%c", localtime(&now)); + if (realtime_positioning) + kml_write_xml(0, "GPS position\n"); + else + kml_write_xml(0, "GPS device\n"); + + if (now) { + kml_write_xml(0, "Created %s\n", import_time); + } + + // Style settings for bitmaps + if (route_waypt_count()) { + kml_write_bitmap_style(kmlpt_route, ICON_RTE, NULL); + } + + if (track_waypt_count()) { + if (trackdirection) { + int i; + kml_write_bitmap_style(kmlpt_other, ICON_TRK, "track-none"); + for (i = 0; i < 16; i++) { + char buf1[100]; + char buf2[100]; + + sprintf(buf1, "track-%d", i); + sprintf(buf2, ICON_DIR, i); + kml_write_bitmap_style(kmlpt_other, buf2, buf1); + } + } else { + kml_write_bitmap_style(kmlpt_track, ICON_TRK, NULL); + } + } + + kml_write_bitmap_style(kmlpt_waypoint, ICON_WPT, NULL); + + if (track_waypt_count() || route_waypt_count()) { + // Style settings for line strings + kml_write_xml(1, "\n"); + } + + if (geocaches_present) { + kml_gc_make_ballonstyle(); + } + + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Waypoints\n"); + } + + waypt_disp_all(kml_waypt_pr); + + if (!realtime_positioning) { + kml_write_xml(-1, "\n"); + } + + // Output trackpoints + if (track_waypt_count()) { + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Tracks\n"); + } + + track_disp_all(kml_track_hdr, kml_track_tlr, kml_track_disp); + + if (!realtime_positioning) { + kml_write_xml(-1, "\n"); + } + } + + // Output routes + if (route_waypt_count()) { + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Routes\n"); + + route_disp_all(kml_route_hdr, + kml_route_tlr, kml_route_disp); + kml_write_xml(-1, "\n"); + } + } + + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); +} + +/* + * This depends on the table being sorted correctly. + */ +static +char * +kml_get_posn_icon(int freshness) +{ + int i; + for (i = 0; i < sizeof(kml_tracking_icons) / sizeof(kml_tracking_icons[0]); i++) { + if (freshness >= kml_tracking_icons[i].freshness) + return kml_tracking_icons[i].icon; + } + return ICON_NOSAT; +} + + +static route_head *posn_trk_head = NULL; + +static void +kml_wr_position(waypoint *wpt) +{ + static time_t last_valid_fix; + + kml_wr_init(posnfilenametmp); + + if (!posn_trk_head) { + posn_trk_head = route_head_alloc(); + track_add_head(posn_trk_head); + } + + if (last_valid_fix == 0) last_valid_fix = current_time(); + + /* We want our waypoint to have a name, but not our trackpoint */ + if (!wpt->shortname) { + if (wpt->fix == fix_none) { + wpt->shortname = xstrdup("ESTIMATED Position"); + } else { + wpt->shortname = xstrdup("Position"); + } + } + + switch (wpt->fix) { + case fix_none: + if (wpt->shortname) { + xfree (wpt->shortname); + } + wpt->shortname = xstrdup("ESTIMATED Position"); + break; + case fix_unknown: + break; + default: + last_valid_fix = wpt->creation_time; + } + + wpt->icon_descr = kml_get_posn_icon(wpt->creation_time - last_valid_fix); + + + /* In order to avoid clutter while we're sitting still, don't add + track points if we've not moved a minimum distance from the + beginnning of our accumulated track. */ + { + waypoint *newest_posn= (waypoint *) QUEUE_LAST(&posn_trk_head->waypoint_list); + + if(radtometers(gcdist(RAD(wpt->latitude), RAD(wpt->longitude), + RAD(newest_posn->latitude), RAD(newest_posn->longitude))) > 50) { + track_add_wpt(posn_trk_head, waypt_dupe(wpt)); + } else { + /* If we haven't move more than our threshold, pretend + * we didn't move at all to prevent Earth from jittering + * the zoom levels on us. + */ + wpt->latitude = newest_posn->latitude; + wpt->longitude = newest_posn->longitude; + } + } + + waypt_add(wpt); + kml_write(); + waypt_del(wpt); + + /* + * If we are keeping only a recent subset of the trail, trim the + * head here. + */ + while (max_position_points && + (posn_trk_head->rte_waypt_ct >= max_position_points)) { + waypoint *tonuke = (waypoint *) QUEUE_FIRST(&posn_trk_head->waypoint_list); + track_del_wpt(posn_trk_head, tonuke); + } + + kml_wr_deinit(); +} + +ff_vecs_t kml_vecs = { + ff_type_file, + FF_CAP_RW_ALL, /* Format can do RW_ALL */ + kml_rd_init, + kml_wr_init, + kml_rd_deinit, + kml_wr_deinit, + kml_read, + kml_write, + NULL, + kml_args, + CET_CHARSET_UTF8, 1, /* CET-REVIEW */ + { NULL, NULL, NULL, kml_wr_position_init, kml_wr_position, kml_wr_position_deinit } +}; diff --git a/lmx.c b/lmx.c new file mode 100644 index 000000000..5082a0cc0 --- /dev/null +++ b/lmx.c @@ -0,0 +1,246 @@ +/* + Access Nokia Landmark Exchange files. + + Copyright (C) 2007 Robert Lipe, robertlipe@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +/* + * Nokia's Landmark Exchange (LMX) format is a straight-forward XML + * format. Though they do support a compact binary representation, + * we don't implement that at this time in GPSBabel. + */ + +#include "defs.h" +#include "xmlgeneric.h" + +static gbfile *ofd; +static waypoint *wpt_tmp; +char *link, *linkt; + +#define MYNAME "lmx" + +static +arglist_t lmx_args[] = { + ARG_TERMINATOR +}; + +/* + * Writer + */ + + +static void +lmx_wr_init(const char *fname) +{ + ofd = gbfopen(fname, "w", MYNAME); +} + +static void +lmx_wr_deinit(void) +{ + gbfclose(ofd); +} + +static void +lmx_write_xml(int indent_level, const char *tag, const char *data) +{ + int i; + char *tmp_ent = xml_entitize(data); + + for (i = 0; i < indent_level; i++) { + gbfputs(" ", ofd); + } + + gbfprintf(ofd, "<%s>%s\n", tag, tmp_ent, tag); + + xfree(tmp_ent); +} + +static void +lmx_print(const waypoint *wpt) +{ + gbfprintf(ofd, " \n"); + if (wpt->shortname) { + lmx_write_xml(4, "lm:name", wpt->shortname); + } + if (wpt->description) { + lmx_write_xml(4, "lm:description", wpt->description); + } + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " %f\n", wpt->latitude); + gbfprintf(ofd, " %f\n",wpt->longitude); + if (wpt->altitude && (wpt->altitude != unknown_alt)) { + gbfprintf(ofd, " %f\n",wpt->altitude); + } + gbfprintf(ofd, " \n"); + + if (wpt->url && wpt->url[0]) { + gbfprintf(ofd, " \n"); + if (wpt->url_link_text) + lmx_write_xml(5,"lm:name", wpt->url_link_text); + gbfprintf(ofd, " %s\n", wpt->url); + gbfprintf(ofd, " \n"); + } + + gbfprintf(ofd, " \n"); +} + + +static void +lmx_write(void) +{ + gbfprintf(ofd, "\n"); + gbfprintf(ofd, ""); + + gbfprintf(ofd, " \n"); + waypt_disp_all(lmx_print); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, "\n"); +} + +/* + * Reader + */ + +static xg_callback lmx_lm_start, lmx_lm_end; +static xg_callback lmx_lm_name,lmx_lm_desc; +static xg_callback lmx_lm_lat, lmx_lm_lon, lmx_lm_alt; +static xg_callback lmx_lm_mlink_s, lmx_lm_mlink_e; +static xg_callback lmx_lm_link, lmx_lm_linkt; + +static xg_tag_mapping gl_map[] = { +#define LM "/lm:lmx/lm:landmarkCollection/lm:landmark" + { lmx_lm_start, cb_start, LM }, + { lmx_lm_end, cb_end, LM }, + { lmx_lm_name, cb_cdata, LM "/lm:name" }, + { lmx_lm_desc, cb_cdata, LM "/lm:description" }, + { lmx_lm_lat, cb_cdata, LM "/lm:coordinates/lm:latitude" }, + { lmx_lm_lon, cb_cdata, LM "/lm:coordinates/lm:longitude" }, + { lmx_lm_alt, cb_cdata, LM "/lm:coordinates/lm:altitude" }, + { lmx_lm_mlink_s, cb_start, LM "/lm:mediaLink" }, + { lmx_lm_link, cb_cdata, LM "/lm:mediaLink/lm:url" }, + { lmx_lm_linkt, cb_cdata, LM "/lm:mediaLink/lm:name" }, + { lmx_lm_mlink_e, cb_end, LM "/lm:mediaLink" }, + { NULL, 0, NULL} +}; + +static void +lmx_rd_init(const char *fname) +{ + xml_init(fname, gl_map, NULL); +} + +static void +lmx_read(void) +{ + xml_read(); +} + +static void +lmx_rd_deinit(void) +{ + xml_deinit(); +} + + + +static void +lmx_lm_start(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); +} + +static void +lmx_lm_end(const char *args, const char **unused) +{ + waypt_add(wpt_tmp); +} + +static void +lmx_lm_lat(const char *args, const char **unused) +{ + wpt_tmp->latitude = atof(args); +} + +static void +lmx_lm_lon(const char *args, const char **unused) +{ + wpt_tmp->longitude = atof(args); +} + +static void +lmx_lm_alt(const char *args, const char **unused) +{ + wpt_tmp->altitude = atof(args); +} + +static void +lmx_lm_name(const char *args, const char **unused) +{ + wpt_tmp->shortname = xstrdup(args); +} + +static void +lmx_lm_desc(const char *args, const char **unused) +{ + wpt_tmp->description = xstrdup(args); +} + +static void +lmx_lm_mlink_s(const char *args, const char **unused) +{ + link = linkt = NULL; +} + +static void +lmx_lm_link(const char *args, const char **unused) +{ + link = xstrdup(args); +} + +static void +lmx_lm_linkt(const char *args, const char **unused) +{ + linkt = xstrdup(args); +} + +static void +lmx_lm_mlink_e(const char *args, const char **unused) +{ + waypt_add_url(wpt_tmp, link, linkt); +} + + +ff_vecs_t lmx_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write, /* waypoints */ + ff_cap_none, /* tracks */ + ff_cap_none /* routes */ + }, + lmx_rd_init, + lmx_wr_init, + lmx_rd_deinit, + lmx_wr_deinit, + lmx_read, + lmx_write, + NULL, + lmx_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/lowranceusr.c b/lowranceusr.c new file mode 100644 index 000000000..93edd8ce5 --- /dev/null +++ b/lowranceusr.c @@ -0,0 +1,1042 @@ +/* + Access to Lowrance USR files. + Contributed to gpsbabel by Jason Rust (jrust at rustyparts.com) + + Copyright (C) 2005, 2006, 2007, 2008 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + HISTORY: + + 6/21/05 - Ling Nero (rnlnero@yahoo.com) + - Added Routes, Icons, & Tracks support + - Fixed waypoint date/time stamp conversion + 02/09/08 - oliskoli + - gbfile API + - check for buffer overflows when reading names or comments + 02/25/2008 - Alan Porter (alan@kr4jb.net) + - Added new icons for Lowrance iFinder Expedition C + - Categorized geocaching waypoints using different icons +*/ + + +#include "defs.h" +#include +#include /* for lat/lon conversion */ + +typedef struct lowranceusr_icon_mapping { + const int value; + const char *icon; +} lowranceusr_icon_mapping_t; + +#define DEF_ICON 10001 + +/* Taken from iFinder 1.8 */ +const lowranceusr_icon_mapping_t lowranceusr_icon_value_table[] = { + { 10000, "diamond 1" }, + { 10001, "diamond 2" }, + { 10002, "diamond 3" }, + { 10003, "x 1" }, + { 10004, "x 2" }, + { 10005, "x 3" }, + { 10006, "cross" }, + { 10007, "house" }, + { 10008, "car" }, + { 10009, "store" }, + { 10010, "gas station" }, + { 10011, "fork and spoon" }, + { 10012, "telephone" }, + { 10013, "airplane" }, + { 10014, "exit sign" }, + { 10015, "stop sign" }, + { 10016, "exclamation" }, + { 10017, "traffic light" }, + { 10018, "american flag" }, + { 10019, "person" }, + { 10020, "restrooms" }, + { 10021, "tree" }, + { 10022, "mountains" }, + { 10023, "campsite" }, + { 10024, "picnic table" }, + { 10025, "deer" }, + { 10026, "deer tracks" }, + { 10027, "turkey tracks" }, + { 10028, "tree stand" }, + { 10029, "bridge" }, + { 10030, "skull and crossbones" }, + { 10031, "fish" }, + { 10032, "two fish" }, + { 10033, "dive flag" }, + { 10034, "wreck" }, + { 10035, "anchor" }, + { 10036, "boat" }, + { 10037, "boat ramp" }, + { 10038, "flag buoy" }, + { 10039, "dam" }, + { 10040, "swimmer" }, + { 10041, "pier"}, + +/* The following list is from TopoFusion */ + + { 10000, "Waypoint" }, /* diamond 1 */ + { DEF_ICON, "Text Label (No Dot)" }, + { 10018, "Trailhead" }, /* american flag */ + { 10023, "Campground" }, /* campsite */ + { 10022, "Summit" }, /* mountains */ + { DEF_ICON, "Tall Tower" }, + { DEF_ICON, "Short Tower" }, + { 10021, "Forest" }, /* tree */ + { DEF_ICON, "Mine" }, +// { 10038, "Geocache" }, /* flag buoy */ +// { 10016, "Geocache Found" }, /* exclamation */ + { DEF_ICON, "Skiing Area" }, + { 10029, "Crossing" }, /* bridge */ + { 10007, "House" }, /* house */ + { 10003, "Dot" }, /* x 1 */ + { 10025, "Hunting Area" }, /* deer */ + { 10031, "Fishing Area" }, /* fish */ + { 10040, "Swimming Area" }, /* swimmer */ + { 10012, "Telephone" }, /* telephone */ + { 10024, "Rest Area" }, /* picnic table */ + { 10021, "Park" }, /* tree */ + { 10007, "Information" }, /* house */ + { 10022, "Scenic Area" }, /* mountains */ + { DEF_ICON, "Bank/Dollar" }, + { 10009, "Hotel" }, /* store */ + { 10011, "Restaurant" }, /* fork and spoon */ + { 10030, "Danger Area" }, /* skull and crossbones */ + { 10035, "Anchor" }, /* anchor */ + { 10002, "City (Large)" }, /* diamond 3 */ + { 10001, "City (Medium)" }, /* diamond 2 */ + { 10000, "City (Small)" }, /* diamond 1 */ + { DEF_ICON, "Drinking Water" }, + { 10008, "Parking Area" }, /* car */ + { 10023, "RV Park" }, /* campsite */ + { 10020, "Rest Room" }, /* restroom */ + { 10019, "Shower" }, /* person */ + { DEF_ICON, "Tunnel" }, + + /* This list comes from 'wifinder' from ifinder H20 Color */ + + { 10062, "Interesting Land Feature" }, + { 10063, "Global Location" }, + { 10064, "Note" }, + { 10065, "Ghost" }, + { 10066, "Letter" }, + { 10067, "Multi-Treasure" }, + { 10068, "Mystery Or Puzzle" }, + { 10069, "Treasure" }, + { 10070, "Webmail" }, + { 10071, "Sun" }, + { 10072, "Musical Note" }, + { 10073, "Camera/Movie Theater" }, + { 10074, "Star" }, + { 10075, "Coffee Mug" }, + { 10076, "Books" }, + { 10077, "Historical Marker" }, + { 10078, "Tools/Repair" }, + { 10079, "Favorite" }, + { 10080, "Arena" }, + { 10081, "Golf Course" }, + { 10082, "Money/Atm" }, + + /* This list comes from Alan Porter , using an iFinder Expedition C */ + + { 10042, "icon42" }, // black box with red X + { 10043, "icon43" }, // small red dot + { 10044, "icon44" }, // 4-wheeler + { 10045, "icon45" }, // hiding hunter + { 10046, "icon46" }, // tree (yellow base) + { 10047, "icon47" }, // windmill + { 10048, "icon48" }, // camera + { 10049, "icon49" }, // tree (something in front of base) + { 10050, "icon50" }, // tree (something hanging from left side) + { 10051, "icon51" }, // 4 dots in rhombus shape + { 10052, "icon52" }, // bare winter tree + { 10053, "icon53" }, // hiding deer head peeking over bushes + { 10054, "icon54" }, // piston? over a pile of salt? + { 10055, "icon55" }, // corn + { 10056, "icon56" }, // turkey + { 10057, "icon57" }, // duck + { 10058, "icon58" }, // hen + { 10059, "icon59" }, // rabbit + { 10060, "icon60" }, // paw print + { 10061, "icon61" }, // 2 red flames? + + /* These are the icons that gpsbabel will use */ + + { 10038, "Geocache" }, // flag buoy + { 10016, "Geocache Found" }, // exclamation + { 10043, "Micro-Cache" }, // small red dot + { 10065, "Virtual cache" }, // ghost + { 10051, "Multi-Cache" }, // 4 dots in rhombus shape + { 10068, "Unknown Cache" }, // ? mark + { 10045, "Locationless (Reverse) Cache" }, // hiding hunter + { 10066, "Post Office" }, // letter + { 10019, "Event Cache" }, // person + { 10070, "Webcam Cache" }, // webcam + { 10042, "Disabled Cache" }, // black box with red X + + { -1, NULL } +}; + +static gbfile *file_in; +static gbfile *file_out; +static short_handle mkshort_handle; + +static unsigned short waypt_out_count; +static unsigned int trail_count, lowrance_route_count; +static int trail_point_count; +static char continuous = 1; +static short num_section_points; +static route_head *trk_head; +static route_head *rte_head; +static char *ignoreicons; +static char *writeasicons; +static char *merge; +static char *seg_break; +static int reading_version; + +#define MYNAME "Lowrance USR" + +#define MAXUSRSTRINGSIZE 256 +#define SEMIMINOR 6356752.3142 +#define DEGREESTORADIANS 0.017453292 +#define SECSTO2000 946713600 +#define MAX_TRAIL_POINTS 9999 +#define UNKNOWN_USR_ALTITUDE METERS_TO_FEET(-10000) /* -10000ft is how the unit stores unknown */ + +/* Jan 1, 2000 00:00:00 */ +const time_t base_time_secs = 946706400; + +static int +lowranceusr_readstr(char *buf, const int maxlen, gbfile *file) +{ + int org, len; + + org = len = gbfgetint32(file); + if (len < 0) fatal(MYNAME ": Invalid item length (%d)!\n", len); + else if (len) { + if (len > maxlen) len = maxlen; + (void) gbfread(buf, 1, len, file); + if (org > maxlen) (void) gbfseek(file, org - maxlen, SEEK_CUR); + } + + return len; +} + +const char * +lowranceusr_find_desc_from_icon_number(const int icon) +{ + const lowranceusr_icon_mapping_t *i; + + for (i = lowranceusr_icon_value_table; i->icon; i++) { + if (icon == i->value) { + return i->icon; + } + } + + return ""; +} + +int +lowranceusr_find_icon_number_from_desc(const char *desc) +{ + const lowranceusr_icon_mapping_t *i; + int n; + + if (!desc) { + return DEF_ICON; + } + + /* + * If we were given a numeric icon number as a description + * (i.e. 8255), just return that. + */ + n = atoi(desc); + if (n) { + return n; + } + + + for (i = lowranceusr_icon_value_table; i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + return i->value; + } + } + + return DEF_ICON; +} + +static +arglist_t lowranceusr_args[] = { + {"ignoreicons", &ignoreicons, "Ignore event marker icons on read", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"writeasicons", &writeasicons, "Treat waypoints as icons on write", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"merge", &merge, "(USR output) Merge into one segmented track", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"break", &seg_break, "(USR input) Break segments into separate tracks", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static void +rd_init(const char *fname) +{ + file_in = gbfopen_le(fname, "rb", MYNAME); +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); + waypt_out_count = 0; +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); +} + +/** + * Latitude and longitude for USR coords are in the lowrance mercator meter + * format in WGS84. The below code converts them to degrees. + */ +static double +lon_mm_to_deg(double x) { + return x / (DEGREESTORADIANS * SEMIMINOR); +} + +static long +lon_deg_to_mm(double x) { + return (long)(x * SEMIMINOR * DEGREESTORADIANS); +} + +static double +lat_mm_to_deg(double x) { + return (2 * atan(exp(x / SEMIMINOR)) - M_PI / 2) / DEGREESTORADIANS; +} + +static long +lat_deg_to_mm(double x) { + return (long)(SEMIMINOR * log(tan((x * DEGREESTORADIANS + M_PI / 2) / 2))); +} + +static void +lowranceusr_parse_waypt(waypoint *wpt_tmp) +{ + char buff[MAXUSRSTRINGSIZE + 1]; + int text_len; + time_t waypt_time; + short waypt_type; + + wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->altitude = FEET_TO_METERS(gbfgetint32(file_in)); + if (wpt_tmp->altitude <= UNKNOWN_USR_ALTITUDE) { + wpt_tmp->altitude = unknown_alt; + } + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + if (text_len) { + buff[text_len] = '\0'; + wpt_tmp->shortname = xstrdup(buff); + } + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_waypt: Waypt name = %s Lat = %f Lon = %f alt = %f\n",wpt_tmp->shortname, wpt_tmp->latitude, + wpt_tmp->longitude, wpt_tmp->altitude); + + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + if (text_len) { + buff[text_len] = '\0'; + wpt_tmp->description = xstrdup(buff); + } + /* Time is number of seconds since Jan. 1, 2000 */ + waypt_time = gbfgetint32(file_in); + if (waypt_time) + wpt_tmp->creation_time = base_time_secs + waypt_time; + + if (global_opts.debug_level >= 2) + { + printf(MYNAME " parse_waypt: creation time %d\n", + (int)wpt_tmp->creation_time); + printf(MYNAME " parse_waypt: base_time %d\n", (int)base_time_secs); + printf(MYNAME " parse_waypt: waypt time %d\n", (int)waypt_time); + } + + /* Symbol ID */ + wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in)); + if (!wpt_tmp->icon_descr[0]) { + char nbuf[10]; + snprintf(nbuf, sizeof(nbuf), "%d", le_read32(buff)); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + wpt_tmp->icon_descr = xstrdup(nbuf); + } + + /* Waypoint Type (USER, TEMPORARY, POINT_OF_INTEREST) */ + waypt_type = gbfgetint16(file_in); + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_waypt: waypt_type = %d\n",waypt_type); + + // Version 3 has an extra word in here that we don't know about. + if (reading_version >= 3) { + int junkword = gbfgetint32(file_in); + (void)junkword; + } +} + + + +static void +lowranceusr_parse_routes(void) +{ + char buff[MAXUSRSTRINGSIZE + 1]; + short int num_routes, num_legs; + int i,j; + int text_len; + waypoint *wpt_tmp; + + num_routes = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_routes: Num Routes = %d\n", num_routes); + + for (i=0; i < num_routes; i++) + { + rte_head = route_head_alloc(); + route_add_head(rte_head); + rte_head->rte_num = i+1; + + /* route name */ + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + if (text_len) + { + buff[text_len] = '\0'; + rte_head->rte_name = xstrdup(buff); + } + rte_head->rte_desc = '\0'; /* ???????? */ + + /* num Legs */ + num_legs = gbfgetint16(file_in); + + /* route reversed */ + (void) gbfread(&buff[0], 1, 1, file_in); + + /* waypoints */ + for (j=0; j < num_legs; j++) + { + wpt_tmp = waypt_new(); + lowranceusr_parse_waypt(wpt_tmp); + route_add_wpt(rte_head, wpt_tmp); + } + } +} + +/* + * Icons are automatically converted to waypoints unless + * option of ignoreicons is used + */ +static void +lowranceusr_parse_icons(void) +{ + char buff[MAXUSRSTRINGSIZE + 1]; + short int num_icons; + int i; + + num_icons = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_icons: num Icons = %d\n", num_icons); + + for (i=0; i < num_icons; i++) + { + if (ignoreicons) + { + /* position coord lat & long */ + (void) gbfread(&buff[0], 4, 2, file_in); + /* symbol */ + (void) gbfread(&buff[0], 4, 1, file_in); + } + else + { + waypoint *wpt_tmp; + wpt_tmp = waypt_new(); + + /* position coord lat & long */ + wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->altitude = 0; + snprintf(buff, sizeof(buff), "Icon %d", i+1); + wpt_tmp->shortname = xstrdup(buff); + /* symbol */ + wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in)); + waypt_add(wpt_tmp); + } + } + +} + +static void +lowranceusr_parse_trails(void) +{ + char buff[MAXUSRSTRINGSIZE + 1]; + short int num_trails, num_trail_points, num_section_points; + int i,j, trk_num, itmp; + int text_len; + waypoint *wpt_tmp; + route_head *trk_tmp; + + /* num trails */ + num_trails = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_trails: num trails = %d\n", num_trails); + + for (i=trk_num=0; i < num_trails; i++) + { + trk_head = route_head_alloc(); + trk_head->rte_num = ++trk_num; + track_add_head(trk_head); + + /* trail name */ + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_trails: name text len = %d\n", text_len); + + if (text_len) { + buff[text_len] = '\0'; + trk_head->rte_name = xstrdup(buff); + } + trk_head->rte_desc = '\0'; + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_trails: trail name = %s\n", trk_head->rte_name); + + /* visible */ + (void) gbfread(&buff[0], 1, 1, file_in); + /* num trail points */ + num_trail_points = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_trails: num trail points = %d\n", num_trail_points); + + /* max trail size */ + itmp = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_trails: max trail size = %d\n", itmp); + + if (num_trail_points) + { + + while (num_trail_points) + { + /* num section points */ + num_section_points = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_trails: num section points = %d\n", num_section_points); + + for (j=0; j < num_section_points; j++, num_trail_points--) + { + wpt_tmp = waypt_new(); + wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); + /* continuous */ + (void) gbfread(&buff[0], 1, 1, file_in); + if (!buff[0] && seg_break && j) + { + trk_tmp = route_head_alloc(); + trk_tmp->rte_num = ++trk_num; + trk_tmp->rte_name = xstrdup(trk_head->rte_name); + trk_tmp->rte_desc = '\0'; + track_add_head(trk_tmp); + trk_head = trk_tmp; + } + track_add_wpt(trk_head, wpt_tmp); + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_trails: Trail pt lat %f lon %f\n", wpt_tmp->latitude, wpt_tmp->longitude); + } + } + } + /* remove the trail since it's empty */ + else track_del_head(trk_head); + } +} + +static void +data_read(void) +{ + short int NumWaypoints, MajorVersion, MinorVersion, object_num; + int i; + + MajorVersion = gbfgetint16(file_in); + reading_version = MajorVersion; + MinorVersion = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) + printf(MYNAME " data_read: Major Version %d Minor Version %d\n", MajorVersion, MinorVersion); + + if (MajorVersion < 2) { + fatal(MYNAME ": input file is from an old version of the USR file and is not supported\n"); + } + + NumWaypoints = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) + printf(MYNAME " data_read: Num waypoints %d\n", NumWaypoints); + + for (i = 0; i < NumWaypoints; i++) { + waypoint *wpt_tmp; + + wpt_tmp = waypt_new(); + + /* Object num */ + object_num = gbfgetint16(file_in); + if (global_opts.debug_level >= 1) + printf(MYNAME " data_read: object_num = %d\n", object_num); + + /* waypoint */ + lowranceusr_parse_waypt(wpt_tmp); + + waypt_add(wpt_tmp); + } + + lowranceusr_parse_routes(); + lowranceusr_parse_icons(); + lowranceusr_parse_trails(); +} + +static void +lowranceusr_waypt_disp(const waypoint *wpt) +{ + int text_len, Lat, Lon, Time, SymbolId; + short int WayptType; + char *name; + char *comment; + int alt = METERS_TO_FEET(wpt->altitude); + + if (wpt->altitude == unknown_alt) { + alt = UNKNOWN_USR_ALTITUDE; + } + + Lat = lat_deg_to_mm(wpt->latitude); + Lon = lon_deg_to_mm(wpt->longitude); + gbfputint32(Lat, file_out); + gbfputint32(Lon, file_out); + gbfputint32(alt, file_out); + + if (global_opts.debug_level >= 1) { + /* print lat/lon/alt on one easily greppable line */ + printf(MYNAME " waypt_disp: Lat = %d Lon = %d Alt = %d\n",Lat, Lon, alt); + } + + /* Try and make sure we have a name */ + if ((! wpt->shortname) || global_opts.synthesize_shortnames) { + if (wpt->description && global_opts.synthesize_shortnames) { + name = mkshort_from_wpt(mkshort_handle, wpt); + } else if (wpt->shortname) { + name = xstrdup(wpt->shortname); + } else if (wpt->description) { + name = xstrdup(wpt->description); + } else { + name = xstrdup(""); + } + } else { + name = xstrdup(wpt->shortname); + } + + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; + gbfputint32(text_len, file_out); + gbfwrite(name, 1, text_len, file_out); + + if (global_opts.debug_level >= 1) + printf(MYNAME " waypt_disp: Waypt name = %s\n",name); + + xfree(name); + + /** + * Comments are now used by the iFinder (Expedition C supports them) + */ + if (wpt->description && strcmp(wpt->description, wpt->shortname) != 0) { + comment = xstrdup(wpt->description); + text_len = strlen(comment); + if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; + gbfputint32(text_len, file_out); + gbfwrite(comment, 1, text_len, file_out); + xfree(comment); + } else { + text_len = 0; + gbfputint32(text_len, file_out); + } + + if (wpt->creation_time > base_time_secs) { + Time = wpt->creation_time - base_time_secs; + } else { + Time = 0; + } + + if (global_opts.debug_level >= 2) + { + time_t wpt_time = Time; + printf(MYNAME " waypt_disp: base_time : %d\n", (int)base_time_secs); + printf(MYNAME " waypt_disp: creation time : %d\n", (int)wpt->creation_time); + printf(MYNAME " waypt_disp: waypt time : %d\n", (int)wpt_time); + printf(MYNAME " waypt_disp: waypt time (local): %s\n", ctime(&wpt_time)); + } + + gbfputint32(Time, file_out); + + if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { + SymbolId = lowranceusr_find_icon_number_from_desc(get_cache_icon(wpt)); + } else { + SymbolId = lowranceusr_find_icon_number_from_desc(wpt->icon_descr); + } + /* If the waypoint is archived or disabled, use a "disabled" icon instead. */ + if ( (wpt->gc_data.is_archived==status_true) || (wpt->gc_data.is_available==status_false) ) { + SymbolId = lowranceusr_find_icon_number_from_desc("Disabled Cache"); + } + + gbfputint32(SymbolId, file_out); + + /* USER waypoint type */ + WayptType = 0; + gbfputint16(WayptType, file_out); +} + +static void +lowranceusr_waypt_pr(const waypoint *wpt) +{ + + /* our personal waypoint counter */ + gbfputint16(waypt_out_count, file_out); + + if (global_opts.debug_level >= 1) + printf(MYNAME " waypt_pr: waypoint #%d ",waypt_out_count); + + waypt_out_count++; + + lowranceusr_waypt_disp(wpt); +} + +/* + * In Lowrance parlance, an "Icon" is a waypoint but without any + * kind of a name. The header count of icons has already been written + * before we get here, so it's just a matter of spitting out + * 4 bytes lat + * 4 bytes long + * 4 bytes symbol + */ +static void +lowranceusr_write_icon(const waypoint *wpt) +{ + int latmm = lat_deg_to_mm(wpt->latitude); + int lonmm = lon_deg_to_mm(wpt->longitude); + int icon = wpt->icon_descr ? + lowranceusr_find_icon_number_from_desc(wpt->icon_descr) : + 10003; + + gbfputint32(latmm, file_out); + gbfputint32(lonmm, file_out); + gbfputint32(icon, file_out); +} + +/* + * Header format: + * short num_trails, + * int trail_name text length, + * char *trail_name, + * boolean visible, + * short num_trail_points, + * short max_trail_size, + * short num_section_points + * == don't know how many max points per section so + * == use num_trail_points for now + * == Once this is known then the waypoints ought to be + * == broken up into sections + */ + +static void +lowranceusr_track_hdr(const route_head *trk) +{ + int text_len; + char *name, tmp_name[20]; + short num_trail_points, max_trail_size; + char visible=1; + + ++trail_count; + if (trk->rte_name) { + name = xstrdup(trk->rte_name); + } else if (trk->rte_desc) { + name = xstrdup(trk->rte_desc); + } else + { + tmp_name[0]='\0'; + snprintf(tmp_name, sizeof(tmp_name), "Babel %d", trail_count); + name = xstrdup(tmp_name); + } + + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; + if (global_opts.debug_level >= 1) + printf(MYNAME " track_hdr: trail name text len = %d\n", text_len); + gbfputint32(text_len, file_out); + + if (global_opts.debug_level >= 1) + printf(MYNAME " track_hdr: trail name = %s\n", name); + + gbfwrite(name, 1, text_len, file_out); + + num_trail_points = (short) trk->rte_waypt_ct; + max_trail_size = MAX_TRAIL_POINTS; + if (num_trail_points > max_trail_size) + num_trail_points = max_trail_size; + num_section_points = num_trail_points; + + if (global_opts.debug_level >= 1) + printf(MYNAME " track_hdr: num_trail_points = %d\nmax_trail_size = %d\nnum_section_points = %d\n", + num_trail_points, max_trail_size, num_section_points); + + gbfwrite(&visible, 1, 1, file_out); + gbfputint16(num_trail_points, file_out); + gbfputint16(max_trail_size, file_out); + gbfputint16(num_section_points, file_out); + xfree(name); + trail_point_count=1; +} + +static void +lowranceusr_route_hdr(const route_head *rte) +{ + int text_len; + char *name, tmp_name[20]; + short num_legs; + char route_reversed=0; + + /* route name */ + if (rte->rte_name) { + name = xstrdup(rte->rte_name); + } else if (rte->rte_desc) { + name = xstrdup(rte->rte_desc); + } else + { + tmp_name[0]='\0'; + snprintf(tmp_name, sizeof(tmp_name), "Babel R%d", ++lowrance_route_count); + name = xstrdup(tmp_name); + } + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; + gbfputint32(text_len, file_out); + gbfwrite(name, 1, text_len, file_out); + xfree(name); + + /* num legs */ + num_legs = (short) rte->rte_waypt_ct; + gbfputint16(num_legs, file_out); + gbfwrite(&route_reversed, 1, 1, file_out); + + if (global_opts.debug_level >= 1) + printf(MYNAME " route_hdr: route name \"%s\" num_legs = %d\n", + rte->rte_name, num_legs); + +} + +static void +lowranceusr_track_disp(const waypoint *wpt) +{ + int lat, lon; + + if (++trail_point_count <= MAX_TRAIL_POINTS) + { + lat = lat_deg_to_mm(wpt->latitude); + lon = lon_deg_to_mm(wpt->longitude); + + if (global_opts.debug_level >= 1) + printf(MYNAME " track_disp: Trail point #%d lat = %d long = %d\n",trail_point_count, lat, lon); + + gbfputint32(lat, file_out); + gbfputint32(lon, file_out); + gbfwrite(&continuous, 1, 1, file_out); + if (!continuous) + continuous = 1; + } +} + +static void +lowranceusr_merge_track_hdr(const route_head *trk) +{ + int text_len; + char *name, tmp_name[20]; + + if (++trail_count == 1) + { + if (trk->rte_name) { + name = xstrdup(trk->rte_name); + } else if (trk->rte_desc) { + name = xstrdup(trk->rte_desc); + } else + { + tmp_name[0]='\0'; + snprintf(tmp_name, sizeof(tmp_name), "Babel %d", trail_count); + name = xstrdup(tmp_name); + } + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; + gbfputint32(text_len, file_out); + + if (global_opts.debug_level >= 1) + printf(MYNAME " track_hdr: trail name = %s\n", name); + + gbfwrite(name, 1, text_len, file_out); + } + + trail_point_count += (short) trk->rte_waypt_ct; +} + +static void +lowranceusr_merge_track_tlr(const route_head *trk) +{ + short num_trail_points, max_trail_size; + char visible=1; + + if (trail_count == track_count()) /* last trail */ + { + num_trail_points = trail_point_count; + max_trail_size = MAX_TRAIL_POINTS; + if (num_trail_points > max_trail_size) + num_trail_points = max_trail_size; + num_section_points = num_trail_points; + + if (global_opts.debug_level >= 1) + printf(MYNAME " merge_track_tlr: num_trail_points = %d\nmax_trail_size = %d\nnum_section_points = %d\n", + num_trail_points, max_trail_size, num_section_points); + + gbfwrite(&visible, 1, 1, file_out); + gbfputint16(num_trail_points, file_out); + gbfputint16(max_trail_size, file_out); + gbfputint16(num_section_points, file_out); + } +} +static void + +lowranceusr_merge_track_hdr_2(const route_head *trk) +{ + continuous = 0; +} + +static void +data_write(void) +{ + short int NumWaypoints, MajorVersion, MinorVersion, NumRoutes, NumTrails, NumIcons; + setshort_length(mkshort_handle, 15); + MajorVersion = 2; + MinorVersion = 0; + + NumWaypoints = waypt_count(); + + gbfputint16(MajorVersion, file_out); + gbfputint16(MinorVersion, file_out); + + if (global_opts.debug_level >= 1) + printf(MYNAME " data_write: Num waypoints = %d\n", NumWaypoints); + + if (writeasicons) { + short zero = 0; + gbfputint16(zero, file_out); + } else { + gbfputint16(NumWaypoints, file_out); + waypt_disp_all(lowranceusr_waypt_pr); + } + + /* Route support added 6/21/05 */ + NumRoutes = route_count(); + gbfputint16(NumRoutes, file_out); + + if (global_opts.debug_level >= 1) + printf(MYNAME " data_write: Num routes = %d\n", NumRoutes); + + if (NumRoutes) + { + lowrance_route_count=0; + route_disp_all(lowranceusr_route_hdr, NULL, lowranceusr_waypt_disp); + } + + if (NumWaypoints && writeasicons) { + gbfputint16(NumWaypoints, file_out); + waypt_disp_all(lowranceusr_write_icon); + } else { + NumIcons = 0; + gbfputint16(NumIcons, file_out); + } + + /* Track support added 6/21/05 */ + NumTrails = track_count(); + + if (NumTrails && merge) + { + NumTrails = 1; + gbfputint16(NumTrails, file_out); + trail_point_count = 0; + trail_count = 0; + /* count the number of total track points */ + track_disp_all(lowranceusr_merge_track_hdr, lowranceusr_merge_track_tlr, NULL); + /* write out the new track header */ + trail_point_count = 0; + track_disp_all(lowranceusr_merge_track_hdr_2, NULL, lowranceusr_track_disp); + + } + else + { + + gbfputint16(NumTrails, file_out); + + if (global_opts.debug_level >= 1) + printf(MYNAME " data_write: Num tracks = %d\n", NumTrails); + + if (NumTrails) + { + trail_count=0; + track_disp_all(lowranceusr_track_hdr, NULL, lowranceusr_track_disp); + } + } +} + + +ff_vecs_t lowranceusr_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + lowranceusr_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/mac/dmg-contents/COPYING b/mac/dmg-contents/COPYING new file mode 100644 index 000000000..514d6c73f --- /dev/null +++ b/mac/dmg-contents/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/mac/dmg-contents/Credits.rtf b/mac/dmg-contents/Credits.rtf new file mode 100644 index 000000000..526285dc9 --- /dev/null +++ b/mac/dmg-contents/Credits.rtf @@ -0,0 +1,53 @@ +{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410 +{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\vieww9000\viewh8400\viewkind0 +\deftab720 +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardeftab720\ql\qnatural + +\f0\b\fs24 \cf0 GPSBabel +\f1\b0 is an open-source project created and administrated by +\f0\b Robert Lipe +\f1\b0 . +\f0\b \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardeftab720\ql\qnatural + +\f1\b0 \cf0 The original +\f0\b MacGPSBabel, +\f1\b0 designed by +\f0\b +\f1\b0 Jeremy Atherton was used for inspiration for GPSBabel+ +\f0\b . GPSBabel+ +\f1\b0 is a GUI front-end for GPSBabel designed by +\f0\b Karl Smith +\f1\b0 . +\f0\b \ + +\f1\b0 \ +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\ +\ +This program is distributed in the hope that it will be useful, but +\f0\b WITHOUT ANY WARRANTY +\f1\b0 ; without even the implied warranty of +\f0\b MERCHANTABILITY +\f1\b0 or +\f0\b FITNESS FOR A PARTICULAR PURPOSE +\f1\b0 . See the GNU General Public License for more details. +\f0\b \ + +\f1\b0 \ +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\ +\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardeftab720\ql\qnatural + +\f0\b \cf0 GPSBabel/MacGPSBabel/GPSBabel+ \'a9 2002 - 2007 +\f1\b0 +\f0\b Robert Lipe\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardeftab720\ql\qnatural + +\f1\b0 \cf0 \ +For questions or comments regarding GPSBabel+ please visit http://www.gpsbabel.org and use the gpsbabel-misc email list. Alternatively you can contact Karl Smith through the address posted at the sourceforge site.\ +\ +\pard\pardeftab720\ql\qnatural +\cf0 Thanks to the many people who have tested GPSBabel+ and given suggestions for improvement. If you would like to contribute your programming skills to either GPSBabel or GPSBabel+ please do. Join the gpsbabel-code email list and get involved.\ +} \ No newline at end of file diff --git a/mac/dmg-contents/GPSBabel+.app b/mac/dmg-contents/GPSBabel+.app new file mode 100755 index 0000000000000000000000000000000000000000..d161f33d3c85e682cc3de05b17ef38e1949d1010 GIT binary patch literal 2342908 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%0D{2A-TZ1w&1CgqKy#QC3` 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�u8VXR=_G~g0(}78$%!p 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 z zh_%OFBX*m!bcW40-*4X*d-Dr(PU7zG0Z*VS(N`V+m+{*GtOA+rfA$V3c()z~}NjKAjXkv!F&cThLf9)Gk) z+7iQ`xFwHUW}k<8Q{l_D`7G!7*Q{ATv+O}G`4jX#-hI}8o0-ogi&@M-|--b@VW7<)ti8k%LCTQD zm1z!|E7t2mqdQD}Yqj7S_q#WaXAUcKd$hiFLCS6!pChzmF8J0g)2iW%j4v zIu{JsxxnsopdI@A)?!1u0@{IzbLj9}X8gcahu@keb-+7q->)oFT=+xISB(8oE;0(g zMt|VK8)NXwdj;*G|H?VVRll!{yM>->FZAH?mHk>SV+{RQUQ}G>Ao`G4eCQ3i=H>wP zqcVwcb}!v487bFsa_nuCX~lI6500|9(I?~b%^Qj{ zCZgYi9g0t6{+c>;{`zJtWp@7h=3%Wjm40OYs=Iama`zyI&fGl6J;+|}LH6B#4|1cn zZJ2uy^ic;a2O5DjKr^rj7;?|?LeAU6H8XGV{}BIsfMY-(a0)mJTm-HF*O{Y|z)0q- z6u)Hv@!PKis(@;shBDp}_U8c$fF(dZz`VozH96ib$?<+oj`wSF{uW>d^<#c_^V`Ai zKH%UmIodI<_X7iO=Xn1h=U-)ip!ar;cMoz2_~8AyTmnAWqn=B^N1_J6M-G_rLC5?* z=!?$zU(0pl-~5{KDwtb$=-j%?&57nLq4cTw(w4c^+>30eVNJrGCA6ntZZ&$;xwVtI zwf%XYbGr)H@Z{{S^eMxK@pF6s)1&u4=DTvlNxlDh`=s`H$lm|lc|_;GK4R?PIXwKo z0$e9QO#&ld$TBur#wN?ykb?qMKsCUAbH*mi*kl=-EMt>pYoE z%HXG7hZwcO5c*Apb}F z^bBFiV{SOb^%HWP|9u-j>&cvQmUEOwFlS!0^TQ8JJE4KT7PD7AhZC=%Tbx+|J zU(0!Q>tFqwHI%(9b+zn@oP8i|bWX3Z--TVK=MefMk*)2qZuXepQ|7I2_dfC;_TTmX z{~r6P$>Yp^@~ONZRR&Z5l|U6x4b;34FopqR7%+wbV;K1L#GVTJf7IxbHcv&+Ud25U zc7VKf>+4_Oo8t4IfF<_AMt$=f`ftsA zLx0smGc5gG9WTFf{erUEuVuJ*kiKTqzI6Tx?W>x;8lh+6o%YrE6g0jTc#Z2HdPe#( z`G)odZJ)W}ZyxZqxAK1humq^Le0<|wsVBJfiG05Hx8SiNbm`0cZt$Gkhj z+lSW}o$>3RJL5I3`_WgC?;G0-`geUjo$pJ=?i;HG*W5t${f(?#Bi5--zVU?O=)|w5 zO-Av0=2zx&ug;F^H>|yPW7j#>p=0KP*jrAU2HKeUOZ#b{&2p>D;-u)Zx?S|V_=d{X z0KHALDb4f7StT*?BGz*@Q~Qk{=IQyX!qomf%Gau4=qI4RQ|YgQKKilsEe+0Ki-|?C zx5mzs`fXSNhG+Z-Tx#<1I|>v;J&!W!`Vx z!Lwyt7G7JHtn$;$MZPl(eYfYc*~5K``lRG zEri~#f55hvEED~0Blg>QC$a1Q%iIjzMsvPwYG0r-?KAhM&G;#M-M+Ac95V7d?0z@i zqxm7tzFBQX*?i!C3CvOFJ&vT(%B#g-4D|8hrOPN6Sj@bY%KCgW;(eR;Fu=)tsE zYw^MQEAli3+bq1L%^cSz^!x@Z_wYF&y3lpJL=F8_!%wNUC9Wo_!c?cR7s(yLE5VJv zz$?Kkz)x!Z3Tr!eRp!?_UtT9=yrbjFCR@LMd6{0X#DDAP)9_EdDy31S^=4_kYI}ZO zB9yp?t#N){qT1fWz432R-7@Bx$LFYic2oj0B-b$%`ivFobr;Wy)tcIcYHU#*lfn+yHbb6T$! zy|QMIxNYCc0oDpw^WMvv_dc`c{cqa8@|Q+F`oOmK9+y7(U(5fT{0~!qY53(DcKlan z{=&D{VRWI^f%N8{%V@ljq`!OdRTGMmGC)E@nQC_ z{AH<>Ssnl76s;$=FVBYCZd;epbIw0t|BAOQ_U7_DVKy?(R32+ZKR_K|)?`>~SL8l+3e=na%c0 z<(B4{_ovJ{>vxUa*uMVag6WH-h;dNbe{n*tfwyj4Quus%_xu8$-Tortj_g(Wi@1R2 zU0joKKP}hbNASJWG5Lq`ymxS{(K&Tr*1CI@_kFAn3-7WQX&1cjwY(pFQtD}+Mh;zP za((>2?7e?t+S7ifA!|}-8V-6SmT_z*RSvVvF2QB?X~wFYWZM)8tm2id*grY@{=B_C2xGB zo%8(WX{#e#dxgD1c#J+k8Mg&_z`R;z4hZvMVYcTE_Ja99z}(}0M}4_J66UCF zkFQ`pK$+$A<@(R-4D!J4`%m&_`U`FUrZX%|B?T%+LO+twxo4Q1PH!fSAbZb5b48fl;RvWS9 zQutl2`!hEF8iO70^Lp$nFHk$rcss#&H1a<71;H1y&xig=>qwhOTR8La6u;X^oz%rP zzTx8-dKKq4V(&rwhWn#_xYtpKxz0Bx#c-S70ry|~cmnq(aE}1@mKg3$!tM3UFH&ba z?d*)<-X8G$b=Iy?#@?fg9=247?)3G4eK^-=e1!6UwZq$}!f&R%UGV+YX1fM$*sPym zzv;ejSlq(CVbb<|)rQ-@^kCSmjTzoXcV8QB5Ad~}ae517i}-Kxq|VMJKHdQ?zI(GV zm)H}=M^Tl|>h0x>(gD(8(lOF0(mB#4(lySBl#p&=FGBD9PnOU>^WVSP;Qdn$8o&2f zD@7lG-V5#Wrj5P9f8Q26PxFo8Ru&mXdAk4m4fj7>w>Fq_=ayJG;XK?jA+G=2K>9yM zy;IbS>;Dwj(Erv*|EHw?b20s&3i|(cr2oUzxkfv2{a*{1wnq9l`T#aSxxaG#f%_8g zCo2i}e|cv-XB-)S_RjcAVSoQy$BiHAA-|mKFYFITGR#eO8CE#|$S^lfwD~#Y(J@D~ z;e*eP>7tEC!|U?HZVVgsJ1)oSqoa<~q9xysA^qBm>RWqY?AWP%(=qLLY!!XY>q|s8QXXIM^*N$72EIOB^d|Bd zM;!q_V*ncdzkXTyCO`Q9`f1VP|La3UOP*hk>Wlxc?^M3{|N2(Z1H9M%FMT|OIP;f# zLb+Feul;kx7+=c_7;A1M+H#4Se)H{zk@rjz_Z@Hk78cjqNbRH!(l*j|QYWd4)I&Oy zNp0R|xR6CPve>WxHT-wHWub@6h~v0Ue_Zvop?$5uEG*4lluk3ZQ~Q{XSRQn-w6rT!?RRmRrz z@SU5ZGOe1I**gWId2kcswl(;L7w)!l)M1}s(@Ae9#4@$L>7ZRBMzt2sgEvpM>x>nf z(?|2*cG~Hn9k&EIeV={RELk)zSuDC7E28NGiG+50@W<0+N3@1j&8PkTpEG!O0o z`?i4n`FU1OeL5eSQ$~IG`~vLT3g^L_Tz>FqC23G>&D@tw?P{}w~AK#U%M{4NBDbVbKhRequ#_!>T9kqm6^yjbhxqE>xQ{6 zHnuU$U%C@DTtAZESi_u2 zwV$=$m@ir^U({&)U@ws`s?7VM=ayL=#?O57M?N1b^hM3u1K@nco5xw`k2d(Y()iH1 zCjZ`5JJ|Oa4%vl`ckE)5`!8@Ajg4-Y5i8T$gM2klni%e>zkf0=hWpz7jR0)8-TPCU zW*fAzX{-3{(0JMw^Iz?Zr;ae5{$`GqqmE&#@P32;5|;LZcFp`3W$5dxk^OfR`m=WT zN8&m1XBKNask7hP?ehDx<|mA2w?B9=nsN43$15JX#BXKrXB&@Nead!;m!6nE>x7rC zz{{=;R!)6R_dWwJQ6Fi$1}|NO{_Lx}?7FZ={_GI#^n%OBzi{;i>>H<8dGHv0B9r>c zS???GcOv++jqax?b3&NU#Qa$=m`?=Eou{pC=<6#vZzo`m+Fotfz;Tz+Wvb{-Xyp8rsJ{6K`1{H|%8&XRF8YLcz7X?o7c7r@__y_! z?Z3*%zXkk^pK8j?rtQdo&4vd1SDL-;Znq_{uiqhB*w;J%)ED;kQGH=wAJrH3^@~(r z*w<%8+x@_P-@;fw#PWi_TR&dqF5vIVZd&U{{*E<2=gX?VspyTSB z&u=B>nr!fUecvVJ{|b0pMS9J1)Rf~J4X=G3jr&4(a4u{_CbjNX;|2K=Prj0}|C!WU zA8*K@T6?4oI^z|6=dC8}i~e8ptUPP+MR9+)F`ZZue4(G8cDy>{wTd%dZEKT!(=GVf z8hle-I6wV=x!o{^qVZ$zJhEq8{QHsk+Jko8apvb;vahujmM5Dw z8$+gF_3?y`&G(EzFXnrywWlb*v(xKQ#{3;?v9<1p#Mj|~=c|*gZOR;$Z`1QFYp?72 zv3`352SdFtuXapTzDHo~Glsvs)UL5dU>L2xQKAp)oT@$3a*D*eNs(EaZHILp z>C?~9aV;0M4^C{b?WKH~=$v-jo=_&z-I@iW%}$WX8n-v>OuVjf9MI^>`<)c^@gnzD zUJmQ*@|$^%o{8oei@tkG$2R&0nMIwv)nQ^HIa^{)E0|cWshiguQKt z$_sm&_>Zu+tx>+Pw>1aaHcbG5jywepSZjrkTO_&#Sj_OFm_ogRDLpYo{aB`|=RGMw!={ zkN%%WtQ>WiAFOuy%8y3<2m8RXTX3Igwa=@>XTSOAYWE-F!F)e_u5tSVpV9c( z)s9zXqWNf5n2)Y;e?-~WnU98ZBecgnY}G!O34$VqsgG4*{8&2$_nB6Yva-S+#Z%2k zS1t2)-0%4O)5h{Hy9S*fZ)0TVf{Xp=)>b)oOp3bCJ?zjGt3APmU z#ed?#lihZm{H6BmK5Y;CZo{KtPQo@+A*bcP4dw97`WFL)(Ah^2AP!MjtD8 zSbdc-ozUm%^LC9gv$bxTA6vK1Y|15Ohjr8c;dZ0G=6O58PNTNnj!5HSq zFD#}V_LNsv#PBq74SB4dB|Jti&!k$f$I2`Z^QE`#4t`(te^ zs>~K)emb^J-2~<>!aT{!g}%Oc)!Pa3R@+}ZZP&oOMeRSEpLg(Xicptz;}`dM-Qd3_ z2Ar*~KWtI+kXH9!&^8ajmcF>s+wP9+=8JBRK5} zb-d^;*z~i7^N|01-txk@{G!X7ex9wg=ji&sGlB8=>ihK9FSNaZamiY5DeX6r-t^uW zbuN&uFi)~MXep_TR8AT}8c7;Msw7pBGNf8k9jTr)m$Z=7Kx!hjlG;e^qz=+H(soiO zsf*M@Iz;Lv5o1=YH#s3+#>f{p=s)9k#WMTP?_~Rp&4cD^k8ZKnj@4Rg+>xIL{q<3+ zV`HB*(EWm?VO{!`vj0EI3|X~B@&SJvG%;w!0^=FFwWT6alfS32;%>W6nVQNb&WV&B z(3x%ai3dM$oT2CQtsukjECX$wl>FLQ$1rYI#K-$gbisSi6ElNtFTZSMHCBaXxz{%= z^vfJ*`Ab#?+Tt6rdwI8Li+{xSC0zXnHV3AMa+hS#gA95lgA?SN40?hLws^nrb%^UG1NsX1xpqclXGAzt-E!72aQ#A%L5usl zm<%rDW$?sxE2}*5^n};X^Yny|LumT8J*Fr22Oj@J`(W+kF}Xp^FGnF&>85RqBGEAptp)16O%z@ zOMwiUr&*c23=WP8cEC66@Y9k(RgeMSlY5$HQ*Qq&?-#ztNCwuIv6H2;0P+3GWf{ahy4dEZnL z-eDQ5}g!%6iV^y|O*t>*%7}&Riy)$6{y30NExy<pf5n*E&2i&6VO8fZN4*E4n0V8IrNB3s`0Yu5zu3xPm3M{jel!A zB02+I3%yTtEp$EfPSN$y4bWRfH$XQ*uNU0}-Ihr`7S(TqZikNQw?l7-j_PlRMjnqv z^^u3^_pudf?+|n^^b*m%8b9{l3BCIyLSj)*FwF^0vC8 z^~PgIMbD%SborRaAGH7|qA$Q}g8V6gj&%9hc+utLk05`P=n>FkpofYc1C1^p8!TG7{QOnXwdB`lQlCF7 zx*oa#`l#pz=qBj>qMM-Me`!>|4Z0mVs^1R19XhJN9U6Hojp`#0)8*1#YVQzqFZ5HQ zd)XI0Q@9>m>i#FpS(m!M#W$VdS&&!1Z#VEh$wKbcWteYNnJuvHnuJYnRNY^(dj7o@u)F_q+TL3@xH28$S>j>j=6LZ}R^HCTJsaMG zwREZXQHB3VQ!c^x!@v|_QJLvMCcefcE-ala+H5kD8T|W4)z3`DziRWrA?5}7!|QD7 zxxWU3oeeV#W2jGi4VT5Iy(4jE=(FLZ_mNA?7M|$6s`K+>D>2{7&_-1z_2=%#Rkn(2 z@Z7LjI3HF&E>GhP8axflls}s_!~8;B|M?=z3%dUEF#b8uM!kWbONrLs1HR|#`U&*C z3K=XHzI9;OMB>@r{CR6=*0yi_-BsA$2+~N>7*Zvvij*PMlIlqHq`9Ppqy|zGsg=}5 zYA1D&wvo1zI!Rrm9?~IFFX;pcpYXYHlJhELHs1bcQcGOk$Zfgq>)N|J>^!%>yQ8ux zexAGC<=#?op8InzSv%N5?EBCO#;EzM&)sc#k`?3B&QyLrYuAvW#q&~=6=Pz#?tLnj zw|hPA=h~TO+F5ek+rc<3mT{gtdS3|d%RtWfKa%}Fp?i|O)WauyZjRNneCQtNVE_D= zeP?9f;QHKE;fnHV!aC@4Zol9?)Uwp&aw2w5@=&>kk!B4UX0m`+eE=T$`+qCoc(mI__EmT zN!TyIm)V%h1=$&WC6ih_#OkZem7s&S^@e#~!xYP->=n(K5;42D(3Im{hyIMvR|Z=- z+PjcReRiL>7wkfPe0GOjL+4kR=Z&8*!2xk)`tMp5+hrdCG4C)Y0F0XXr>-#7VO)f;9C{WBCMb1{eb*gHsCX26Hl<9jcU zFaHsIB+FGdm&f~OvmCF>nfGH=(8l=0i2T0NpSe9twj;pH_j;1Gl5MTUfxK+jO%Z<< zH`gJLx=d=(b#K4R`L$;YP1YkM>-w<&k&NEcw@&zyYNyW5I0PO4*<`!cg3shThj)Qt z?&D2o?uGA#W{<{SCiQ2{-dEto-YdQ8@usu)hFG=8?G<^}fomaU@3ykg)VDdzqUoX= z`gr{Wyrz>);eE-;CToXyx$g1NFS5>F>vBW>vG0m4a=C)B0gPj8ZD;F9F#OkmVWInD ztz8=Ew=I)e=z0W4TfctW)o=72GWGlA(}t6N{k_sbHj75tHTrF%-}~sdL$cY1Y?cSv zEIeXm)VH1OTb`HA!WrVd4NTj>hkMU1;I>xlGEAjV#x>a;f%ga1- z$8#w`77K@mzOb_&MrVtnHP@dm^7ex*S{%WTefAl<23}~}r~cEau`;?Bx_GF{=w2xP z6ZsL>Y|YopxYF6YaG#fUdTD2nw-anpZ9nSzM~)|gk9+i_mBF9Mzdibr=qt2Qo=H90 z9cbTUs)ODkx{iEo_)oKRAXn1%u zEjq$KR`dz^x7b;~WOUYVIrRoxImH6Ir-Gax4f^Z$=axD%sReGw#K2DSt?%{Tc6Ssv zA6+5(P>|JvsQv}$E7TAA?@n9+YdN&)N3vR=`q6lQbX;gJ8t)6{h?cAtOcyO#Eto7? zvRV+;m#h}tt$fL9!4T1s)q+8yxtE*lceZf;F3St^*7;%lcPF`*%ljt!-!qDyBW%8L zVSszN3-PlPCFg2nSwreuqws%zCNoBlF^T<34LvaD|sYoAZp`xC3za@}GPc@=$mIbRzypP%pXk2S)>w7mrLxBCvP zALhHf`2R5N4uhWDSND0IXJ`gD*F(FH?C;B?9Wb*Fcx0ztqutrGJ6!F;-yX4 z!rLR~`|3UqAI+>|xUP2H{+$=vnb36O26@plsf%N4mc`Zv{Z6F4N#0(U#V=&y@_S^I zW9g1~e#HHQ$zE99{-JHnvbb=~@+W(&ZqWUooK!oDD=QLhH|ZXo+x^1lc~9@ny7%=; z8+^A)|Ev|l^E#|ocu(NX&&PA^80i%09O)A28gq~m(k-MrNW(~Xkw%m5BTXb>S8x1X zg_PYwdYbesX*X#v=>X|4=@{u0>0Bl?Z-w!Wyzo_KeK4^s$?^mslT?)$Y*mf*p1Z8QQzZZM|aeB5&1t zMeibi((AEac}DHrcw z!d&^bTCG=*$Dd3Qt|(9Il|OO+3*N(8ubhhJgiX1`;UJeU?X$Y-)8(o4O4P68Uzz2dppVf!Nj1>uy&c3a!ll@ep2+|NT&HXJJ*v^A&G7hw9HGasDr_mrL+^Evy$-9u=?j`I+_JUeHU_ zN3-LnzryvxXRg|HVUN}e_8rC1%qMRtoYSs!{WCwfL+b^*N8K7*FWjQ_!Y#4&LR(lb ztQ_zCgz~ZV!e^G+b>bF&@Q;t%{~(9tun*rDl!XObFWg1mMa$#=Fs&CxYrSw^STD3X z|0bK*dcp1~+InGPWE){l9nOu=R<+g()h$`-<<|=nwO*JQTQ3Y#-9<6HG5ZHs1#J|p z7yj7eg=8D87wlVyCR^VF%dZz&hl)Qt6W@+JW@b`z4%#)z!|p+wtfTe9Y^@h&o2;3O zw+DP*d`a#2b2?!j_{T%+8gt^AS})AkoO7|+W0-IL@igztZ6>)GIkx5Jn{y^x9&xK5PUihNR4f!|b=f!heu3&7`dSMmog=Buc zFuOa3uaSP&Wm2=BQNQc@^}9*^ZYu2eKku~i^t&$K@9e8~jegf@y|6{Hc^cWY2HDKs z8tdE6__XF_Gka8o0ZdPW$@Pe=sGocm+Q&civ$6HUZsFVA51;D^eE!b6pu5>Kgzs6c z7xoI@0khfsdSSNvr|?eiH1MYa7Y*FSPRW$%$@?-yU~&*R%%q)E6g<>xKQOV)C4w`2eGSj(p_ zb6kswpUR5f4Q(WuyAfk`LZ&PWj+9eP!2(J_e0$vdyATF$cd? zI1kH?v%D}5%euXxC*!MWpn14`E5Xlh4ScU)MEv<`=3i5gSuLrKR8N{qT1aXjHIZ6L zZKS?A8~?YHIy0&I1%``X$A|xm-dj}5T&R@!LY>DMf94>ZyI^iI#m08}iJ}v<@uvDK zoIlmOKJY6Oo4$}3X7jB~X@}mq$h(lfkg)hOEWhtn@A|OvvH8|QWH=Z6`-~6S-(2k9 zo+loi8T_7Un7FM8=2DI|#3y6%FTq;O>IQ#88Kb$M^vPYZwwg3w(zAYH{8F|ljJ3Y` zo9){*g?U1=;}kCU!(kt!4@1y@zP~BfAF^&@-cX+3XZ)nwqxg-^uXfNbe&Lg0{C4>| zA$s;3e&4Nl?qhCSCiMyTHrvh?S9m`(46o)B4Bu4oE-at8E;{PhleSYE@0{3`}9BSplItKK4!$+xn|hXUbj2KHfxdS2wPTkge@gH!j=?myc@Q$q9bfBKO4J@)2>4Q zGSlrL_?MYiRj-S6-ifCEYy9ZG)PV1Ac%>G7E*D>`@GWcT?q8rzAZs2C6$rNNh3%jNn=Qrq$*N|R7H+^A}mBBZy3BG9%YruiuCBgMx(h1TT(go5L`b&^XNoAyR(g@N>(il=Dsfv^# z)spH+^`yC^g`@^jQ=xC0Imj`0vv1eu+crL>F}3Yx-}awee~k6`y|2z-lmE%%yL4jj zO0c~^#`-&>{SF%&UC7DpC$ig6_meIcblL^olSzI2xZzS6-Jgo?n|#vkk+Oa7IG`WS z#!xpGz26|5yAZBv-c}gT!tn8Bc8&2F^|wHDPvM&AE^Vtf9iW5z}F84OON!R9WE~DxAAu?pLlgR5|m}_&t|0t)a^DYpBG9uts_8o;=>V zU_U`m7g{Q4qhJj+!{d=`FIq#5)Ea7JpPc<0aG!TO1=9$4T*bU+OeR$qiyz4`K2G=a zt)c9GlI^co+E~SwRt0>YUv2nkXH0&bQ0L>Fb;1~}Py9Vk`SnSi`#;@N7(?F~`o7iL zVa}TA!ync~wVMC?JtObe@1uNvi2BXM`W64ljMgW0n*Y~h7rLKO=XRpL>rH?8^~uMa zf5QN#`b_F$ONEL0N#erC=82vgTc0cxzJ*$!tP1P4rAvfwZXVyqcG)%LGFR)92H|Tm zd&sX(K9;p|TAwr(u1`Md;|)C!H_f+x)b$A66vpz$RyfAA$60*IM|X@Qo84tvg!tahNlV z@M*fCp6g#@(f0ngbIs+2Uzbms?)DEYUZx-QwuxVXmyZVh5f=h4)1&(0W%^U0e8kK2 z4Wct(N8i&`KjLNjQss-6>GMQ4u`XyWjN8+PTV9CU)6*)~%5(qQZ;IQ|bN>U!?J2BB{AsXdZ2e=itS-8j zZU52rSX)ti*FNXR#;WXV#P`LHGmN8;xE{225r#k7Y;EM@`yaUPyB z`&HumXLnj3Z!Erl*8Rr6F1~+us`Vqh!F~XV9tMc-)7&5R#mDEF6XiGy681>@#rHpR z{TIgf+NbjRd!zCF&z`Y5h4H=iqRS@4cRN#I{<8|12K=sud&ns$Mnk_#%ckzdA{}y+`J-AxO0bNC3wV70Hu-~*lQ&5*l{h{lV{5tmOMua&g zXX#n=bEc)fFg7nbDxPBJL~4hNCp#x%XE5d#?y3Ia0?XIDp$-fS>2ro%W4^GkPbXo{ z(x5p(L%)7Kt|QBZ`8mNKZdJbvHD_s(j9Re?%~}3%TCDHZ!a2)BMpvo$*jk`HJ&Xqxy>T zQ=JdmA47lG)6HLBkh_?bFQ<+lZ2 zleG7rMrXvgTb}8Xc1GF%!a2^=pug^j_o*&##f6?ss>a7Lw0NKD_5v;5YohuWz%qvN zLH~?RXn3Ex#Ibcpyic7Yx|V!+uURizyw|J{y^wr(uZil5_nN4F8~Nz6X1dC6V@|Za za86X?{vgbWYVJ|F?aYY|y}3EjjYNBMB8{*1GYjlxJOKZ!;s14erPS*p^^gu_QXd{? zxH73faDT&mCfYa6Xm6r6zc;ZUXJwhsJYeHD{X_}-1#f<@Hr{{XT;#(WtbKe*Y#;T> zC}!2&yw~vIc~SY;Tx2e`#$5Kp%Pdc}X6qd7qrPRZVqiVx7Q(mdU**ub)eYkjc^ln8 z8Ml9xX$bqMy!YPU0r}8Y>xZ%p+BHPCKp;<01?xyGG25 z`b&y#;68ae+$ZNuL6-e*_5w-mqz=+H{Cn*EoPXf{*yM*iqJ38E)b4BiLGa&Q#Di|` z+4RYy^s3~6ecQg`logIIlxq)lgFk^sqdO?$<6rXV2=WN;<7d3NJSp2Dd2G{OYCH1i z2=aKuafY_19Er&z!VvMV{xTOOj}FywJA{9g&%C7ksC;)+o^SY63FmhB?kupq9C9jn z&%%_UR>SRSn<=2Rg$~#__ zXFO!a#_-nD2IJoqXEzLX7y3#|vck+V2M)_+DCBZ-qa16UB(W z?~K#lToU`cuYVtnGT89s3d591RiCxrSWKu>Oz?BZVc+pHtE~(%!M_czdueZ~zrq+W z+3nfJV1B=O#dwXexi`mv$#WcI@OjaDMof>`=;WoACtFyUAG0Nc)Sl_T2|iu_D%TY1 zX51bbhel)1)eB;6wd!8l!yyJ_a+XKgR{6X(#egP!p59;l$Br|!U47Eq3S&0HaI0No z%&ETzg8f^Y1^3dbmsq)eK5857GRCS`db?fjX200$1CCexn$6nyJZ^R2 z!RQX!niOlRqX*l{l>XCMwbMbFPTFxlu68;@y$4-?w9_eBbjkm3M;3aPWscVi{XTHS z`w6m$@Fne<{25pt*dbc|e$eGdzV(ToA8`FaOO_w(R(Z+tgHe5r=LfRNxBjgCX|eW^ z&j*`Dn=Ih-gNsCWir1d}{1%@IR?2ZN?SoV7zsi{J0ow;Jd)@9nYX58eYnqykBRQrvmf`y@7EXlm-IOAufV@F9hF@VaIZc+ zC@LSDW15}KMHe22rSJT``qCR))!tmnHNfLoYeVH4Lfzm`7$-*KgQ|S|t4x#p%YDJW zRHv;zWnbf7{ihsfXuHboSNmPU@PVNJzWzS2+1fOJQ|Mo++#dV+7qi7SFpi4x(bnf* zN?(cgzuG9rc=~|j6)$GD)O}!?crbb!WroMv+Qv0(BKQ;d+$P_#UB06O-=TM@XT4r% z^8*{ajo>@f_xtzRHTY6L?+@dLHmQToJ}^i5lFR$oiBMV(ZcqA z=b!SzHYutvY?F4WJZsZLXQ6MHw7~L$Z8uz@qZ zGj*$`*|ofHm~b&xM!q3>7h2WbD*GC~VV2_*F1O!8-!LKQzt1;Jh~i&A-!Q@LabVvt z(e)sHW4_^+8^o_{bb{k8^bH@#iU-;4gk+3g`GyZnQkmEA4YRx+eBy5=Eb}%Be8c@u z*|ofHxIc`aKHo55it;u7?q4cezggu6@D1bL{(^59zeMF;+cyk+ zFRv_qz7H%l>|On<*Co{VJu7~DNhe5WNEb*~xX;DD#{by4mx1n;agBY0@ceitRXNyX zfqmh-fB(Au=Xam|#(dNOYow36-Q?FugAMbWS|d^Z|5M%z=TN`z{>c15evS6$y2p_i zV2$?s-7X`_$L3IGw+oTq5zCY9=htYZzlhHNnLlNI^uF`4a%SVyoiNI-*}Mq4l`{Kd zWwb_%_UZ0-eNpx`)@XH(Q@AF1Tfu)s7+jBx_o%-aRtCD2I@{o7uxRsH%!A%{Rdh#7 zI{tmb_wBIjl&P+4va_PgA|KhFDZM;T{<0&?0i$=${r&>0V{;?+f@)~n$GhZKgZ

tjbY{(GrE%dv%h^h3~7MIR!cHP8E;f6CjsBH9z~;+{u!{=H1& z&RU&3A76;xowps^=;FMPVd^2@-nX_roEz%9&)doM8m?PkYpfl3J5L62ScN0hu?eB%EV-_EZ8vb2;lr- zkU?@}kU_F6$Y8qn3t#0y2HuzB=bFA{9=&t!zD3qP*DHez-usf#c{|`-W1k(ocSSyr z^3KzHy*_#tPw&lI8EE>pGdu5{CVDP(J#<=hJ#+?otmsTk2DL2(GWfmYRwgC`t%&x+Ttv=X6B!l<*_~rWCAcNmKX#K@xFgGuQ-wWg4 zZN$$>!PD<~eRvj6zZb@Tv){XJCx5DVY=`GI=rI19lWouq(Dx|6Atr;SmI4`!J!)lQ zGB__gScnXoB!gDTU}2EKN4#J7YLE=9FUQZdHjM?nbME(i{BpfL$YAV#>n|n)yDy@# zFm_o!kMhpbSg(%^#M9Vl{0E*2-Z?k+R;yn)*R}h#N&NcQ3U9m1_Suph`E~F=`S%OJ z*Fm}Mnba8fAHffE4$A9>@kkk?J1H|H)>fyr+C!sGE_%1yA9=md=9o3! z2Eyh(xBC9wJ$4OR{rv7TqOFgG^c(cgf9R%6>UUR%{3y2luFDU3n!ez9%stAdeT#Kt zhKoif=3B?OyeMz&AELeM%0C3%3w>U6FZ3DcNLjw9>ppyycQs_OROQFl5pAlUS zJqCKS=rPch(5ppPLNksc{BGa%&k~Zz`Zg36C;QtTuXY}-M%k?J>0uP zbPf6F?%tf}h0slz)IBeWZh~%w?iSq&4c2=Xi3Y3b?%u5EZP12wn&?hwba!uB^dab8 z=&_=Eq0c~9h&}_a3FuUyBi%*#JqDG7=c4k9Qr?>@S5iwZ`eBssx(K-Fwd$b)sgB+b2F*`xY_#Q*W)#Fuqw_u zSfk-Z zf3R?N{Vw_6y71no(PyoFaM!gQ0|Pis4q&kFtJZ~kyHl50nb6jMylVfo*H9PcY5(!G zT?2oeuvF@IVSaqzlR_I+nbhxG_BPztCaTnK&f5SZ_!k!LYyHl8%M1GXon0!oka`2Z z+e|uozI&i=PyMQk_3MD|HiLJb)z7~xfOYMD=tKM-;g{$2U;TXn8@rQ3N$(;JCw|;T z8ciDTy#bWTk~f!MzHOac%rEaTFMQV-*EVx)3kgiG{r&**FH!#L+U_D^S5Yacj8sk< zK^jRKL#o`^T{MZ`YElj9VbV;}Y|?zvVp1b%IcXJX9cdE@3`I{bm)%bs`5JzgSaS<;CyBm?KS{Fp zbEKb0R8Q!j{~SI!mmJN!emT!**_`?=eNTLJ^jwqT;!OXhLe2Mhui1xI7>~>!?#ra^ z_Bb5kTJk>ZbyKGFN74K2?qlt;n=-drdBwin%rkiZSYmgGTX(s<^7WI<6My@>mB)Wi zbXzZY2jN{=%QN}r_t%oVb2rJ{@wa#8`$^jTk-q=KMZ3ltq=x%!_}b*d#w+*Q?ETR- zA&yV>dX!;KYR{zK<@4VV%l)}@F#U(4YG)=q?WN3k?+e8e-}knplQTK9x|jNfKVIM3 zG;Ho)k#Ei84CY2Au5Ze2OeeE?whey!>Ks;` z!NRxL#{J_Xu#@rcd1Yfoa)I_P%IqC4*v-p4u1{!^69dl6-5E`B;|uSeE%% zmibtg`B;|uSeE%%mibtg`B;|uSeE%%mibtg`B;|uSeE%%mibtg`B;|uSeE%%mibtg z`B;|uSeE%%mibtgxSVA^mSsMcWj>Z=K9*%ZmSsMcWj>Z=K9*%ZmSsMcExOc_#)j{= zH3Qfx66=t~)A*Zpjqg5_c)W@6vk5=jTy#FzYUw%Y`+o@@knyEV>OJmlx~g^tar7Ha=;zSMi%gQC!7u7Ada2-|MwA zp4H9}Z^!MisOHIZ(WIbn+ta>zj8lhL{H~K$$MOsP>984gUG^E_olTwj)Op7H33%rR zeZ0r@2j2P8$Kt#{Et((nG0E#uhL~K`2;Xl0e-zw@H3_{%agrZf!C&bI+6WoX56a2o?yT%o?mBlAK#u#{4 zGM;)BMSILQFpsu*RdQppXusxFdV$Ho!=n0-XPoILxl~x=mce)fBB#jlrh`9tTHFC`6|Y!_siVZ#whQk zEz&z_?{_}c*COvL$Tn)*$1$>{UB@%k%0Nf?lSErSeyIE&ZzJF>=Nf*f-0^|||7gCh ze81P}c0Y%Yx$~-M{ELnIJAJ%TekL^I=FX$a*ElG5d6C~pKI5Q#sq$ArV~=+}C0h1z z=LXT(hw*S{R9`&Y8P$gei>>9Oti0xmm#9PByK}nQAm$mLcTN^99`76{T0GwA;{}YB zls6uSC_mzHkZAGvj?1FOtcT89N;{P3!MT`G;j1w*X-*H;B_<-X8OR#ntM2sN_{GdDZ0Od2w}+*Ep|-yvC^= z$18bNBd>At{j47fWDd|&2&T=WPf{{e`IemxqZKv={9*7mfPLl&;fO9U*_%e^4M%&#`Yy{ zm;L)b2ma{x6`>8=E3ti#w~rHTZ9Gl>9MMlh6RU5ZE_yHYF=*$5wdpZveCF+!l`nsJ z``v-IHG=ue+lPpjzqoynXn3-iaQjZt@)xPoqQPe|A$3GF_$(%*_KBVk-AMfvnKO=4lS6$Q!=|UyIMLEk>Tc1} zQEG^2@SBbTe#IE+sLbsRnNFk(Iw}kEzwSs!sWqVu-;B7Bw9Ku%ZiqcQYq2WQCV8FbW}E0G(4J)$|^)lM`bUGZVWn#@H0Pk z9o=?O`I~}{ZaXPjI=U^YFCE?1t$gXI5C65GquX*JKhn`{YeY*&w>68Fj&55ddS)h3 zvOMVK*MIK?Ux9tT-R%!wF+aqc+fIkRE!Gsz&&QhEHrw?Gi(*aeo7uNbwfug*vjP5_ zGO4#Y|Ek**d{po!^lRs+S-Tat#(b3Chd9RT;X4*^|rfXcyxxncpGhP&!lc$8pE?a;7K`t@YuT&ExvUM4|`t4dROA_dOfw_ z<6rS*I~cl1JtX#@xDS`*K3taja9QrdWs5INsAArg_I)SYs~nlfdF!$mPQ81&xF@{( zqqwK=-Cp-zwX$IBg5PzG#TOEfcd&Q0hrO#@@mafH%=>Z=2vY$LFdu^NwAD9^+5;NN z`z-i2OmS}u>zlR7;$B;)+WXfYzvbKP{olJ%{T(tHAqQ(?wXU7=by7Y3KgQlO{DwYm z3Gu6n_R__N^u06eF2R_#`nT+{`m#}L@1W7fPner>&(i0nuQ2Aly!RKC*LWByUT>kj zNviL1Wp9&rrxag7e&uVMi?8TC9b3Ztx9`~%D?1{ugSWa|WkY(uT1g_bQIhD_#u94- zZ1}skUbO$hhR?Gx_}1Ze4f|pIneD&zR?*nK+1^{Oi^lGZzqdXk`cP=6q%?nCprq9D zko|J%1^e$puHB3i_bG1)_TTN_(0G=%vY{>8ldw74Tc?TM4NXjcYtVnU-@70ty>)EJ zkLC<-QT-?$y+!q-c=Xn!%FiUeJPoF({?pL3|CS2n?}a`Fof3U4#G|)#i&i`ud@;~b zJQ{pbbUE>W7(4hS(TYcJX%<~cehv9MMAtyigwBZupT(oWYeb_Pn=`y6ExHkURUUs7 zj|OLzzlnV241=eM#&&HTIXJ41ZQ43~@L1(59`)hBhHlHqPlfy_9t}>4Ry-=bD7u>R z;4eKX8vJHo5q@HZ+g53}@?~44J4DO2N^_!RTM>T7d#ot=q@p!64P0KTQOIZ?*=ns4#B1^${gCMJeBAKmBmZ-yFQQ>)z51)&Kp1d zPRf;-yx`bVlEe zg*H>P!19946uCd5TqE_&=XKmf%DJh67F4*T}E zJ?v*x{N2L8?RJAM=ac-KACDL8`zM;i`lZ-p`lfNVOp3pYD0$HFnNR9FbC76*2j+Uo z3d@t75tEItL9^@{xQuS4%$``8R^C5Rn<;%JdN!(+G98&z;%KZ)N2oVwh}!93eNqJ< z+gP92yPsGu(RMC+2hndGv2xS_Pr~IJ)&qV0PqKXE8TIA%0^PwLUF@E4;Q z%q#3%bz;2biO){1!Dq=5y9S>|cTvXis!W%3Ru!K6595)tUE-xjys*}yelF1!)_=b> z*xK|y%Wn915-*{TvKu=rAM9OVuQnZr?}a2r*>z#pci#Q`ti74C8_O(DxOxNj;$3zP zJVu|O%#2u>6O}kP_`6$Wbbp0sr-JQ%dbSLy4<#$4NK}Yqwpy~6K&B~AZTP^y8c#eIe zkN0H+tP`m>$NsC#MB1v3@MCMtPx;PT*$s~m(6gbz{>nvfyW4Hau)F<}A7OX?p(E^3 zePO>I)fe{bC)J*?Uw=t7-^@!CelxG^`U=Z)KUa4BDV5`!dC9Vyd|Y&1op0y8+M(E_`ibxoD)v0 z=WuJX4k_ySB`DLB2J}v)TT0&Bq%u zs3zu_Pi){EVI4NnB%fFl&Jw=+sFmkD=%V<&&yDHC3hm$AN1u)tpT_$$6RTQ=Cacya z`G#rmtu^?gy0G?tx7!V4C>lQ<^j$^Y+q53839D0 zA^soa_b}-g=@jW4=@RK0XIe@~w~+3*S?{t6-$NcAeqj^77c5RYfcbq@u zyMcbTNj|9TS8FU!Hf=VBOmFyjlJ6OTJk0l0<44W+$nOmIdXzDLcNqD*9}-`O1D+c@ zt!>I2mT$Ym&*qg~TcGR53in462SdGIUUy7Y$Up7vGlqY8)~-PtM*92J2GNH#XSzV% zDbhKTo$I;A-ka&~66McPexAyogFXfA{>$nJTe*!@`eT6zdCJgaQ$4% z44#3YkLXM&zU^E%*Eejbl?i?R^0NKset2SS(!cXYzrPIQH)(CZaKXlp^&cNY{$07U zU+!|elv7(_{L&6{qV}M#{J0p{CXyxex5(RJ4CTj0@)pKMo7qxi(_w79Ymb%Xyi`f1 zG&j5+T)h>^5sdk{>`ho(cRN2_@I!k(*DL#FDrz5`*x=Q4zD%UMtM`O5k?yV@7j1Te zOs=}UVQ1p?s^fr0SJv;(lcV$V#^h+LOFz|_vMXEdzii$7 zHM+h!O;~CI{wwZJ=-ccXySpO!^f+*4^7^@_Qp5kXAixIZ}v5K_QtsZ_8OY-&-N{8U(0OlPE3WDhec|5iG`ORx>v>>%E3d=f`9^Us#dpWtU%}On>41nM?zw%kF=nXTr<;LK$D4XKe);UtVqh zDL0>b1IswtA9w>cM?1BoI#PY6?9xlZj68mE#Qt;5`=hT~`0#wI6SKiOY_J|1^mh&7 zlQa3}-0mD|Z6H(X27b|p^*4|`&W*`#u5ci`OK!)7vb*ehpdFK);Tmt{g==o1>@MA7 zc|mrUrl}l0@>OIP+2?@k#~ZeG>>IDvAIW9M?_APCQUj@p)S4;#XZKI^g*-32zPUC@ zyw&l)TX^a+rQ=SU4@Xw$;h)`J_+J;k>5`bsJfM{O2znNKh}WatI^+%ip}d~2u4V7Q z=2EqOPpRymXIUT0tD{Z><%9fe-i7bc`x5Ls@O8xCR;y=vBu>_bZ-fkSxq*keKYzyB zV{9}qcN$2KZ81HziC6UabGN5LJqGz8E9vp)J0y=<|J?m$ z(DToIywGkN?bsOE{;G3m^vxXl7<1@T1Ni6q*O))oi5H%4<2%%47uSnd;?zHHu>V|h zxq&sB=gwxVw4$5&hSTOR@wnJiapOwx-ETi>^@-(mB$M%L#82P1iT2{6?>ZAdFV3+x zgi-PH=PA1eUV9Ho;dh(ME)KH1Ais;FRBmyIZv*VJAUERMG2+{)HyYpQw{N^;$}TuQ z^uyQ)`r=xJ_1n+4Wa7T1vV-SCJigt&$I4=pwWNXU@KyZDg{fAr&<-zL6~7kW`uUH4 zI&XPFE*B#Cy}tkWwb|7_Mg9W2x|lXBnX;cb-a@-dnw(z8u2L(l{{NU={nM@1MxkB( z(=NLGshR~D(EXyc7DJ0%Qbvuz;CwL&(132c9xG}Wz(&$ z*%@`a?f;vPVdsxpy+WJ&*$TS`4*9;HEfHnvK#o`;A_b4r;-21pPk=e{bb61>iwBKL!3V6_9NTN5YH9o&Mmd_ z;?ci<8rHdQ+h%K7{Xb#*!a%7ME61Jh27(W+OmG?^ZopER}6!yMw#5N7H7 zr;+|8zn_j*zReTh@u#Ci*WWyrelpzhf_#4B{uF(@x;;eqq29DTob~Z-x(Cln>oZe! z*88(-L8d?1A)F@9m_7Vto?VahW?1`dAa4)bf}Xx~u+ScUGAmZMpFR8}70Z*X&R!RW zxILVT*~1p~Ge`Z%9?o8lwbjoa&OQ~(lRf;z^q@hub_XsR>$ufl>PXkwTaKQ zdmfdXM;gXheE7-cMB2V_*mqv2?8p22l^a31nc@36zLwAUcaX}?B(0q6($>eBzV9HF z{dlM48I~urd<)}UhLQD4n!Y~{AJM&xvLCyB#xU9Q)b{QA|7v{o|(v~hTda>oDYx=llu1H zk;z5qE9^_zo*#P{um5dXo~!4+d2%Md1@AB6S|e#WiT(BDI?^W67837|Nb=s0WGAVM z)I&N%;$0m{-qn#jMLI{iMB;uxQ3>f561Gt^jC2>z7>(i=`z@*@Rgp3z)&@m&q7s?C2Ffnu7aTk<+g${XB5)LK;rdhjZYP1G2pmP=;5nu4B5)LeqX-;D;0W(7;rtpn ziosC~j$&{W-$fctx{oxGR86YkJtNcjt>bqVzq3j6NsCF1q~%;+$!{B}ozy|vMgm81 zCwY7L-Ag(^I!ro7Iz>81x82kRLU*WULiHkZPaY*+i{GLkK!}!q*A5+I2pTu2ia(!_-{aUo4yND~**#Dz3*Ax&IJ6Bp9Ng*0&?O>R! zVVF)VRXert_%vla9w^p4&AThmSK{eV_T_keYZGiQ@3Q)|SLM&ummQlYn)VYb}p$l(Wa_<g@#mncacshc180m_2Ud9a4-P-k-xefM{onpA|@5o2tInq2p)4bJ^P&0bdoo zJ0Xb-l8I--d4M1Id}@N{CD(;Mjvle{ysyP@z|YZrqT$7G{a}e`VLBS*moM*pP~XZU z-ycj?d28S5kBjP?{GR+F@0Mh36rQKyd6ryqM_99zJR9x>;isGN)6MwlX8d$Be!3Yy z-He}Z#!olnr$^UN7`sXtyux0icZd;MJ#WxbcJuIx)Z^?H5$f_Un6dxI8Fz1>y^T0Hgc z5be)e@s5OQ&1rARl=aTBJlVF+ASF*B3+9sFcl%S{HvdGQFFPKvpTo9G>En`YoAY_e zbHTQ+dOhAr!?Q}>&LZa_*!DTzNpn2-1Ll`mbeTn$*`iy*e71LxV}<6~j}kC=e^!RJ zu0fv;`N?Z}{q(M}Yhbz-^mAK%kbCdaaGko%CihuuR$C2mUDoeFt>lzq{y;JpbPp|3!C*|Ji~6???RGnJf7JzT=1gy8{1z zzu)lm*f`0v7xk;wqw#|4xBL3a>d!dhnHhsKfvqz%(*sIygk)6uNUd*13 zY!wFSQ*T6hi^1c-0{k`kDzA#|_-g(i)Zo~dPmsbqCom-I4|6bC{%2tHsyIvox!t&kY zRt6d@W((gvD7q3FTluc@Prm5~Tl(%Z$~Rj={@>j!+IUAl-(4-*WP|>`yG*pn4&J}J zK(zITY`!~7wBbQ^-<>L&z09GfVq-(|!+-}lE$=rrmW8n~_>%Z#-p0Bq$GR!Ux+%xH zDaX1g$GR!Ux+%xHDaX1g$GR!Ux+%xHDaX1g$GR!Ux+%xHDaX1g$GR!Ux+%xHDaX1g z$GR!Ux+%xHDaX1g$GRz3Y~$|Vv_IxJ_N>|_#oPSz$z_L*oBX2d;rZI4b*yhjGq+i1 z{ul?QKx^DZI%qjjZ@_+VzMEu&{ zdc5qLQ#i(GPW88=tghxg5f-n{oFc+9$gy-6fu)G}eQ=!UYc0|THdVqi^d(PRK_4fJ zOH3d1z3B_*o!X8A4|a>Tcl{#MgB3>SWy%<=h-7-;NIuW>ZCDO?efIT*CE$k!i|PA7&gvj@ zlQH&iAm~5n0DC#mtbEfEI(X6fr@ZkFZwIm=-`ey3rir%xkj;U#==<{XTzrP^Wk{yO zRi=hI)zrCFbT#xu`n)cBVqSg+p0aDmZ=&Sa5#$%}bG+K?g62|40Wf zihmym=-@lz-^VOE_|826L!^W692X|(;5!FJO9$WCBid{Nd4A^^(Zc+l&7y_*JF7(- z=1r7eX0$MG3ViH$`C|v-;X59O@^lPx;rtgdKfnsQQd}7%W;m z?7u2nJnTO!T0HDODq1}3-!B>+1o>Ee)cY=o^@&X%zHy~B@VDRjFXXRB^&|fFFAeQQ zI_krJjyBNI{u#;_e?2Qji@*Kjg-87DA0;~CZ>Z>qzrmu#U(Z$1;;-kdXz8fuXrPIs zZf8BJAK~xWrTkOmGtPUS5-t2a8$=8L|Fd7T@b@eYbTrO;=7|>mo*ANrzh{c*2>*D| z5&lu4Ych%3x?*!g?F9xrjN93TbHw6Vg>yuEk5BPpQX^?ObGeoLwvpON9i(j}=8Wud z=h)-U74Ib-ARQ(hBb_3hBV8h0TbpB#JI5Y(jy>)id)&E_yGWxq=Gf!Tl~hvZ-?YD1 zpCkVFT_(T6Ib!kRFh?w2Y`!T!M?B+k6Isr`d5%~zws4M!9J9zViyX7aF^e3t$T5o? zv&b=v9J9zViyX7aF^e3t$T5o?v&b=v9J9zViyX7aF^e3t$T5o?vn6ILjhV9l9{d;o z3+IT%%k@s2<%M&^A1^Up!QY4v-$H%&N6>ABbHw76q5XaC|H2%xxG_IRgqL6AeGmF- z&y?-WxgDo@A5ukpj#%6g=7_}|g>%Gzd`i5u=jSAQ&)c<@ZrboUBJV@;Ibw0A=`qX^ z|Iy^&Z>ad%t9X1Z#N&NQT|W@w@!pG~4~KZX z*W+bhJa&xHd}goD|3Y4b<=bAL`Gc^0`=n#(HY~-*GG*URi9XgMeQ1t&N^`_hg>%Hy z5pI8WFw7CZJe9Pr0JsfLd41g>6KbLXI zEzrULA$RgipdE+lA}`Z#`}(7ee95#u$n@LKSYKSfCCK#K9>1XP2r~WFb<5Aolrh*h zNBq`~e4gpsuzbtwbLK)=0)A+)n7+TY%<3R>lQH)2t)Ty)1MKBnvy^Z4f)2W!f65#0 z@b;}qA>Z2b{_YWN{UMug4Htb!evXLG=*DMsmy8ZF?Y^oqqp5QjeVi427xXabqoRl9 z<@c=>b`7}<3-Y@y5#$%}bKUknjUUGkZF6q;?cQVc`s9}@8J(Xab}!23nLl$ZUf=Kv z%hU*quuqC;m5=zh@}uc*xbkVwd`g$sm)*Aq9dwERNC#cw-^T$u=o0@vPS8Qu;Lv8I zgRWibLptbsO0;y)wL!Gm1oG@!DH?eik6lYe3v<^z(T2H^{24|Ib7SD+1(!c|5b@w~ zC~rqycZW9mcyRwkzU=6Q$;y`MB5iia0Yixv+r91$%ZUf3sEJiM?|w0L-7t7vo( zFD{LfhLZ+o$XQm2>Mk1L<|4(OGFF* zo~@#V|M}^Gj>h@(lSN1P$BB;c-z_@AKSXqde~@UNza6wGHb>kW#&N*IxUDXnBbH3k z9{X%f(bz^hMlyKIQ zdsVTv!ab5bZvR|oPqc(R(>+rhJN-e|L5~+*m-kOW{`6BP|5OtC-*eE)a^3c}(ZilS zqUQ$xw8!yUJg*ept3rO=$gjJkDfqbEfq!V~7>>X{WuVz3-W~YwE@6*2+E?0r+S-NBh2p<7 z@V`6a-}Z9gKj5caQ{aDh;NR~@!9P08`{(BZ|DG3Nc`oqZhvm7zKUf0x=K}wZ&9FZg z_z&fqpacJbH+1>j0>d4AK?(XaeLolRFPS|T@o)A3|Ifwv_dZ6sO!IvV72T9c6m3`A zuX}zn;QyQBs@p?fU751KarvQ}F6d6^i2qLL?a&eb+o88XNBnPt?tqT??|^QHj`(kf zZi9CIX}=A+6?&HXZ_VrWxxsb~okibH_vb_?dr{Zh(B;$6K7XTJd$57GZ3#B;H~Uqt zgL2POZkOn7D%YuUKL4ivcD1)gfkok+&JynbHByJlE>(30`4DWWCgUE@Vd#=Ay|mW+1|6)hR>8Z25e?z}3xHR!za zY(xj0bRLbBM`xY;MO%C5v~!ne>kplGJ|)`lU=y7iL>pdgrgNoe;|H7STq@dZst0p$4UQz#%i?`N8v}&qJR{e?ko%7{e5P zroC_tBWP%UpSAWndCwa{>vjA+&z(Qk^SF)$ozkJF6yT? zf9N@-LdsM*9&*-6&Mh4>|F373YDo{v*OJ}{w)w+v1h;_Ie{k-g1>6aK-uQKbX~R#C z8Kw=gpZwE?i+px?$!&*~k0oM8o-D^!1aghS8Vocci1&o$Tfu##@3izj@Ja9%!zaQ0;B|)k!2^`v zV|aiukw*G5hr{^i;9|q+q|^Tg7aFGjCB{BD+i)hB_8**XnEp@81y3|g`z40xxoVjH zlsPAqU*~oDv*&qBr$1%R={aVY{**bV=b&NwGp!!H$8bG(D|n~jt>9+x7Q@Y8(bqb| z=u3P`PnF?z@LupT!+XKq;Khc!!H2*L4Ics@1!-7xjrBS? zul~=-BL3#bnx5)!e*C;EANrdgPc%HAGKE3>>8pkd!KLunW4IJtOL|zo7TgFvX6cRK z7V@t%+yd?dR~haE)4m@sGfex$-~4#7VcIAD=En;S9|xZT&o+Dtd>TC6@M$pP=jpKg z5O^da{|Ms;dwcqV%OCoiP<}n5guR9GhyLd2gO(qA6Mysc9>dt1_?xG98qNoczP1=f zU*d0`US~J}qra!C45L5sH%~7!yc}EsUTnAmyb8R~@G5W(c(&mh@Otoc!|TCq;E9IY zz=wkPfw24`@F4htr4NG9*Ma8^qc8C{2aXvY2BW|3tA^2^_?rWJ91i`>ft`jKZ{lwb zY%!b%EHTmUWxR~aq_mw=ZUE&H+&M@51wea zA3Q+$g@y+hFKOTl4u}4x`+39Zq|^W1#|%#cXMztJ&IHr`?mdR-fAKfnI}Ou*@i*OD z4AYGY@go9<o8^|28Z?5Zv+3 zDz@Tz*GbwS*I$-={2w4zq+kASieQTs`?>#MAHnN)vEtuq{Asb`0M8!vyY+Q1opRb9 z>Kf*M#DAp?r{??Hv%;TPx<9|(^MX6xbHHR7a z>AGSVo0U0aRQ^-o)8OYU{WO^Nc7^4oy(8cQmOg?{Oapf~9L^!3{NWrD${)@lU282r zK1Ak_u7u$na6Wjc;e2o*xX5rJH~=p&9Dqx~*@n@d%pqM<4KD{*fPKRi;8j8VM^_B5 z0@r}g8?FJb2R~M3`T!H zJYX38$sF>dgu~$+@}s4Ob4kx5y~uDLxB$GsZ~?d&oNc%mTmqhIxCC4W_6^s8Td6-R z-wN&npSScr@JaA~j-xb3H_=GglI~)$@kRNV0oKE^Q(i;p<180KQ z8qNgM{vRd`)BkC?;H8FXzsw;&EHX@g${Z5PAI>2^%(is;Q|6E#PBlz_${g}T-!T0t zb4VzEIEU;zZ|Pe}ZzlaY!_8pywXfGO`jR|_AM}s&!3nsbHnKO0pfdSOPZTU_AYVx zCZ^|SPb?h!Zm7}k1C09)uvd>ZcX%bu4PJ3G&yL$XRfZ2Phbp0JsP>6oZv(&e5bI1H z&*}dD?~x|&W#}6B-pmKSoc)hOGlKXJw0-zmYDZkoH z|Cr^Mw5{j^yZwRA-|)jug%9l#e2P3#{hi_(ZP};&L7r2a-MhI@vqu}g zoBMcuhj+?7fAW7V5?-#Z&a3j@orMi~cb-?7g-`Td-0?jt~O7)Eo5qoF6K6S>@4}r0(r^52b!PwA~VR^A1`tZrHyy^1E zu>55w`;#XezfkTcpD`Ra-DM?XU_VRJ;9CIS?egFHy?|@j##3s)j2q^7vE8Rs-{5jE zZGUQ(@*W*mPfamwZGZBHVQc%7FB`VDKY7-$wf)JkytTa}EN^Y^2+LdBJHqnT_Ks&A zzp(8cM-0b#=WJH$oYkTI>E^7Cot7^vKb!d2_tNSzu4M5$sczDQ@Bck>)$6>6uZH>R zmhY_$;_cc$=qo_SDlgZxKIWD1U9%Npt96xkudmzkuJydHa*O%IQr=I@8Fz1$%{T77 zk@AkdsqWkb<90bT-aDXblKsp#KwLi;QujXjZ~a{8b(d$?8TLZ1`l1`I>3ECuEir??JQ6bmE>7rOA^BSqUR5+kc%mqb54=2N*Z6=rNuGnP z=l$!4cKEzQ)Wsgo7UbJ&Q+svXAV)Lx>-e|+ZB{u_-rf7(7fHSN*yy`^ZM=T(aY?hX zGG@hQl^-@H-;&5eroH&j@ZG)b&fg!^a^z{IOivL1?-P{|MohbVoLo;HkZa_zJ!@hn z-nT{G)pq@`>Y>7YBhJ19v)`57?dHEi_!Vg#_|@HR{wvZso;ts${)_Y;cWy3Lz<=Hg zfL#<}7e&}bQR;iqc@CNP0`LxSCOMw{O{1=1_^7>;cNoll$@f%W;FI7!@LZ7>+-GxR z_`Y;>^}T1UEn!;Rwefog?Yi*jM|Pe6+&MqiE;4yXz>M&m|L$FqcTE2flgpYw+sl$> z{WHil>g-T?(CeV}&rqa)23`OBOv{m{pE4uVU!{Cp|BN`9I;NV8g5}Jc zr}6AI?>q3*Bky`2cF%ABO#7d5=x_IA<(;KAYdUPx{=l&6o{b{aPQK5;CS-xFbZ;fIWERhBOD3IAn=M*?p`n$xd8 zjWPa5^A*g^(}MUD+7IxJyoc4#w0F?wgyY)z2Y2p*=Yi#HTm@y--mUK|c<+JOV1;|9 z!4um4P;TnVBY%Uosn^c~=Yn;+h+CQkNovP{JZ-i^{wYx4cA=%g;)d3Imq%lE&ejp+Bg*%3KR$KRbI*PM<;H@kHFfK4yE z!v04u(w1FkEx)y6*RzIeHW%@($s(QC>&T1k>^fj+)4=r4u8v4u$g@lJM_nQd`rH-v zztknNg#9nFpo3kBur9F3vefW;v$1^Z)9z#(;de_ObW9x4s^u-O#Sy!#{rcWjY_`?f z?^RHy89dL`5&G~})i-mB%r!lvTl;m+V4SxevHapE80W3~4cj>Xj_FVR+F%g>PFUW? zdFw{YKTLVXdFvX(_z}@*>q>_iW2)2E2Mseuq>o$gGi*8y<=1_FbQ;R9{fkapr&xaM zP;~m88-{tOw%?r^SN*pulIG&7?@YIR-N;E?;{}&xCTI zTqqAJfQq3Ks0=C}C+=Fs^;)P7YJ{4g7N`yCgu0*};;^Iqo`m|L0ca2!f`*|Hp3_N# z(tpt#o561mlndoS1yC_m0+m7KP$l_@?_za9eCGn`1N2`^zb&-?C0tkk7Q|c5%QfPu za4m>;^J`oezMH?;`R$+TxFfDxIwr2Ga_c_ceDqZf)mmIv%{lMx9e#36Nx!Kx^{0!p zzFu8>D3)`9?u_@&4bkgv-$TFIhW~0&`?oRK=-RSN=VSbq;3o1!{HNFC?vZz`6Q1O0 zB8DhLHhHg%tVzhTXpP+0H@P_CCwn9xe55Wn{&Akfcp+~$e&9o%HuAXf!+-AcC3frN zJ@|3vaeM!ZSFG>ApZXImNBwQ0GuO_R?bgmVYvW;LDoMWcqh+nhQo>y31-I>)C4L+p zJ;Y9jDZ?2_jW614ZmX79jJEV_>f+rHQxBf8^2oVE=MQ_2e;cyni&}~#oi)E6FurGp z)(1YhIYFO1r0waq_6*1wMs#KEIk-{EBFo8Sdv^57HDo(!?YYRa63gLtSCclg9~$e{A;{Y1|ZlRxtO=?>rIA93;%!|cXx8+?7{^k(^c)J{!S9Z$9f zG~&*Cemh&`K{kA40rE{1Y;#Tl*K&gR_RxRkB*&ef%NlH)b(lPhmu%ein4SAMNu7UN z?P@c=$Yhpp1@Ik6zhr!!|M-||w_gz9p?u*{U_8oG?Qr`gDT9v94%=2cJM_!&9WP57 zanmZwms6heo_?*g*Ys7Z{jK)+<0X!d=wiFZPxdY$(?#j7U9z3qwLg%v&f3{#y6PNXS5NOU9xX{8&B_-ZEyklK zRaebwR}o!pFkN*q-g<=}y5f7~evj#jdERd^U9C^*>gidM*XiL~I*v_Ori*WBKcbsD z@(cy>Zyl8U;3057Sp68dKccGv)749(PFJz?R9$^*yKCd9U2Su^ilv4A>U4H&2G4`1J6*}UcKji$yDq7# z?kkRu=;53D<-h65bn#8?N6`iQgvI39CV68d`dD|ha~>EZDPDd%(*>f&+jN704zQ?bTmY#eJe85qBh zFV?b0@v-W%a~%!G_5s^oro

Ig!jRh;z;+053c9)dT$d3>;6t~kK^O&Y{2u;YVsJv1!jOCn zw0pgc$X~~4=XP*($=ZraIt>ipbq#18g#t)Z#DiS zmCX8qaat*DRU7#EYpVv0uy77S{1KJhL$eR z<^M>(SIV~N9MtDKE{(UTHn@+->oVe61aGVJ->GT+oxCrdpN|{F+a^Z(Z_b^u|4BX; z^(VD)Y&Y*qHt(ckS^qc2{ok5=+QU7&W#pgf3F*Wk;P7T9M4d+b$o;b~nZ6A*v z%ioJXk43$xn9n3kWpS9O9q0j5Ty7G-smk_N#h0}J&kdkhQCsltEdHMSPVN11wF)Dz zAC{=E64&07EjsR4^naA!d5xX?Sic`r0FL-i)G-yjP4<&*|C!?i%18VU)rh{}daij@>tZQOKj)tDody9!x`IgrFcs(;eWWS~-&l?~e za(hj0xY6f;c4deA#Js)&twC~ZJD-p2xL<>0??-9MjorJ>P{u%IXMw`A zfbdLIcHFK(Vq0S)%Ul~nTaV-z#Gg32UXNsa_kd9fo3-9*+@2%`mc2+8m zD~-r8sDHxac0CevEs8ao&a7c9WRtGP{w#~PRc)y2u|JFOcT|6TJ$6lOo&IzK|0eqQ zQ^cS4Ta!>5J+4I|*YMt&#`d`#p;sb(nX2)?S`(y~w*O}Tv_CMSE&u5V-d6RSd>_Zw zhZd}Fg1k5*WR zX*n>3@;;d{eau*ca(rc?W3f7-gYFLxc0j>QLoNws;VHa)SkGC-n!SrLa zFDlkksMfvq%N>082J+pX?|wW;!wLNlGAB9C;)8+kAAhF&QTH3X-p%J`{6=J85pRZB2(~sa^Q-6Eyvss+^`53)%zLR2> z%ja^*S_P?`UuMI~vc9EUOC* zFd~N{zm~Vt^E}E!W0uo*g9n5{i#F2pLq7b;_m_T1_c)VnH4iu3T<@6XBd0E&LC@OA zrT1$nmehxfe?E%bXF_@~lAafGINMmXn(Vfa-4?9TIzx@A2lH>THvOU5jFpcmyDoG% zYh+nHaY!qPbWEsqsX&WPDP&e>?^@z`YPTxnQe?qe3RMD z+r9cG@w{IT_uyxuevC+F2HWR)RPh-;{@V}Dwas~)!Sif1MmQAh3u&v{`8spXC+^y} z?zJOvN?9J@^N2;@`w42cy0?#-yF`<3NvdKGMEsB7e!IIkuvlJ`VLD z`MQbmx*U&{Ri}k!Ccd`*>>#$Id_PyaRy3Et zr&!L7y|&(W7k{rfX5d(<-?@av>$UYBaJ960#5LK%)ff4qe4h-i`PJE>xz0XoLA@!T zEzo?nfH9EI7R352+H7Hqwt<)UYytT!;XD!MhZ6Ub^C?I7jUmkO9KE}G?uQYP^^xga z{7X2@zO<3{Xiwp?{*VxaiM>`!i0d>F@~NR<#pUe}?*4PnEM> zfBL##p@nn5Y7J-dZ9%N>7-u@{Zp2v6h41>Hp2c^4x;0FJ_)ghf%XTS0%<&$@cmw#e zKaEJA9RA&VyW3}?#x=osFAaPoNBd+e3_kiy??~+JHpw# z40c5?;+`AJ`WMsh3U`mvFcoN+g7O_{?_-FkKi_>R(jB^C|yRO-;N()n0BaW4L2Iae78IdN$)1U9Y?$B^b`xk89G0q|0eE0Q4 z3)9y{DexVwnfq`X+x6$W|E;xf{!iM&V136pMekkb-TyK*Ov6&(yGkSS5ZZ5lzWeVS z3+I2Kp8?k_;}pGj?YlkOElhj5QsBEk8j(iC)1UA5pq`|Ew@2E;VDpY}J}7$c+IL^o zTE6?LB}m`#7)EhLJhd^+eDY@+pG*4vd-m|Q=ka6stF6GRxY8U)?DGo4UxE+DG~q9y zm%jS_v14`O@L-{K{@%yx;V-rLe;E^hnsVB$*X}}{j-~0Vk;eVqZBoF@Gu5s~kKUG7-BZgtTzrrB+B^P~QSl8qY z!{^vvFnlig;2*;bj~F!l`y6_q`VPtXA?ChD);r<0yNfZI`X~RBzYp~<`nS7;fA_9` zyX!Ts@$+Zl-QXkox7)q`CBDWIb1xEcnP7xJgPzg5=r`Y=RY&(#m4_xQ{vdQU?K4Kr zJ>b5dMX%DcYoiC{Xqe;LC#uhpWN(YM&q&hsDKXax!k@uk!t1j--j~jmc)ruTPT-o; zzjm`dBmA#sey4NmoaQIybfDyo)V~9#f9>g+)4$g8@51R{;2$8TEaCLejs%=$C+3t< zs^N9wl&$TPAWr|>#=i@ve}aFKoXV(9dcD49g#S5|&u4^XeNwLDeb@0qrw+;w*{x4vuAzl@ zq5b2yQGU*jt&LsKKk@mlaz2*!n@#Om{B>xvHe9Uvq52npG{WD*zQ6v(ryCfTXyd2t z;776Id(;BzUl7i2=&Sqw#i!6Eg=w6IsptNM3*V9d`G0<8MkEBCV9lpja`(-J|50lB z?jQ9U&Y=3WW#;t=<-54rr*gXcYn{daQ=N( z3VgTFh^!t3yBl3zD-G{#v@q?2UIyhmRkJr4;cuW9{%Uq-M8i2q^IcFiOY>8AL%-eE z>?cJQrcY`#OulPY`L5CkcNMZ-f4=*8i-l9x-!x+!klxY!)Lqao_rCjhn1*Ru3Ve5? z5&jzS^yj;emRUGIYSM59m3M^me`t@~`>vx)!!%IC6ja_VF~a{vf61TkIwo543*j{X|X5gN{*e8)J^9=Z43-^wjae_N|z z3d(mCM))hl)1U7?Y_o8F*sb9V%6E(t?U8%meK=ObG)Kea+jrbYk$&TcnQWIoldg}Z zKHpL!{OLgcj{7Y}xV@UUy^r(TkilDs^#{eTf7Rn3m|vCcdd8~N8~OUS3=_W*{%baGd#|^c^#>EotF@sXq~89D`gT=s z)?D;D+JCs}`#H@;uOs{&jNj#4bX66N%c`_%6h@>5`K@##?tgsbm)JFI!)@@F__hst zsrspj|EJgUwV>52%R{+ToAe*H70?5PgV)(RI1~zJhNv`De2mz8l-{f5?*+$uExfI8 zB(r{MS#4UVAn|?vD~e!SbS-ZFh5R$yhAU0Om80QGJipS5f0S>KKgu^Qt{uEvYGHV{ zUc->ge6_lMu^i(Q_ZZ%h{OA7|hTj$ZqMLp&NdHt~;ldB^V1LPxcaSeCN0P%(Zm#pU zT#rZZYkr2e@3!LcPNo)*WY+xD)*iie6Ksh;+~AmH;n-doAdXSqaJ=2F;Xu8pxFq8b zUi&hibZsi>+9dkVzCkrJTIK0%iT&Gkd_K}s{y)UN^(M=>|3k+bk?KbNosOGrgx^Md zxUN}$Nr%k!KFu{w=4;wCpN}J(eB21$HqT4_ulccau5az)-=#fx8|@F-pRe>ie%`fb zU9hb?S*_=zi@CVBW&jIn^R05=mfB2weWYhBN*}5`>cg9D7KS&wH4Mqrro;NDRmgW0 zlejevD8{ktpN8KYt6`d>VVX(pt89K-{HKU;(MIpYY^W_rj82lPSg#}4a}lvHL~qQ8oE%^(1m<1 z^2cZ+{MsJPXQL^X7RGAmYis#;@yBahc$@4mR2mxpf54u7lFxlB<@+(@2dwWx@2>t2 zNc&w&=PsjnnrGMwf6+Veaa(3yQyl+odHjC^!`q<$oaEP+Afc($vhfw~!F-+NU``^IfNT)Ev;O&=az0&H>Fg!XHD=C?{zSXe;ni`{ZpMlJKj=8qWk{ z(pP3#yk0T+CqLfSbd%;V=)S_r9PRvZx=wsdy*yg_Wq;WYJm`n~r3=TdmTSD^>wxYn ze8r5P>1*n%eKds6CBA-jC~tfB^(*PXyAjv$68L%x_(%@@WgzcM@eaz@vyI4&yR`GW z@b#8CyubK;%Q74rxUaWBzqP!cYlL^S^0~y;Xd4KWs=4>1rxUXN{qIjBlJ(K!@s3-CD%j5WW@4kMy2zVXy`epDD zU%xz7VF)U(XBv?T{roO`{Zch!5MRI44D12UGbfZyn8W=_g9!kX_yj^t9l+o$K4Z3zDqMA*Y9Dw z{(ScW>Pc|EAo(Hn5tQ#3XQ?;eJ>PEm?uE1z_^yu;DMvj0`R@5)7S89VX*h%O9plV} zUDtWnT5n-$MSE)MNDzG{%DerH2t9_!cizeRR+4wE15@BT#u@SEyN$Cf-)*eaF!`=o ztF2gs`1orpo@=piKG&h+46dzMGzfNGw-wJ}e~IUF6E#e}+X~Bf*CC(%`R>_r%XiPN z)o>=;&cERORk0q^`i78z&Mu{`uE*4wHD52 zP%owq23I2s(f+D=0~hNiJQL9{NqtFM8=&tNR{Qte(=#lbPorK^;JYk7hkM^WwZ+2p z)NULbxbLoQX1o4s_Ni#0{y)3~^} z*P*$R_ZKeBjT)Dpucs!y&R0fx+3U3tBm5ZRN$>m4x9_^g-tXJbbAfNyjBo*FAv3$uBAR!1mA7Mysr8$)nhaGJBoFJ z|581c$-haBJvL13m-t>E^LiA`1-N-8h|Hf{iT2swIQG#(V8lH8qt(2v+WX|kv9{|P z3TuRI`@{MO;wgFj2=Xg6Sc_3FKCvR771j}{^J{U2f4?@(VH<+AX<6#9EYkOFW|HFFx{a}FJxySI3*8V@74j-<@^*$dME|>gp9gBwwtXMo$ z5fBFPr)vz2$RDZ2htdMVAo}AT1Ns+&p|La=3`L^Xt}#5g-HOG7T>)W`_RT$p$r^^@ zfG~`L9oHBh*lJ;TpwlM?+r5GF_4;tpM}Ht!!!k?5(sQ5KNvq1uduHeBdgbC?)%!PC zIPMp{T@9^B<{nY@iT&PCc@}y2{&GGKwH4eK+IMfL5t$EtqIPVm5pL+_eMnQMa+^Y0 zYriKn@w3Ro_vgTWk_Yk6A`dr6{$qXD2IN24Pxe{l+%A~+y&6VjUJ0L@zT^906Jd5S zpVa_;7mZNs*GLTbnlrEKnjd#ROwZT3>=+~dF|I?s3&wTL@V7sVG4s6?4_X8CGUz+` z(Z@B+`*txlg)>9L8CV~jaQ0XJ^n+8Y|NHd%PabE2+A|`BwF>K0hy0AIDXPEx*#BDG zTVwh3Ug(ADS0!6R33Y<74)l+8trq`#_4p@?RrLesHZeB$eXz9!me1B!;8>{_AAPX7 zGrVC~13i~oSeq6Q2I#eWKdhN%`C(0|Zw&j|xl8qUxM=6@*=FImXOD&>nRZV5Z^)(K zr~Kgt$2bi~VSqR!zS0J|!13o+3&)>#y2jx&k7d&yx_*~Onm(OgbidS}bJ)HSuHVh? zG=FN|?>v+4cP``ol-}Uk6TBu@8QGKjoL?;GV`wfbkM473n~B=kx!Sl4&xPSW2Ax;x zUwp#%InRx~|Fph^ZOfceeFtxo{kf{mjsG7)Z}UppJSlM<%Jz)#>Mnj)`4QJIq;t_+ zSiR`K;7o82em&Y7g>!_$*>gY9IZhMkzdK{7EimUDr?CGCC;UwB$WQW>`JV~C2mdD8 z$GoRB!9DnLpNZla_x}&!DE8Gp%+Yoa{%ZJ3IIhl99A{GB$2ks(IaX=h#t?2=8}073 zY>(biZyGn}wb3Ha>pJHUx4RqJuExo>Hrn0LYvFV^{L6kMPVx7knYrbf(_PRrBYama zW3X|WPvfkc)R!^6$dwF7OYIQ(ZUPHo|qA_}#{-Dlw;x z1sYx_P7!UN1f1%c`FG(|2mS$a8pO7Z@SUCfZsW8vF{kI2X?Ptt)uCRTbMH>*nc@Wg zNphO6*AwY_um9g5uE;YZybAH;zM^@(!bls}m>;rVuef^_^Yw7Og04|i)hRpLHHy0j zDm$L8QCQbKt{bInYX8}|Ym2h!_CFiub&myFn}p|Xi4LwR(PFEvd#nO~&IQVk1+i_^ zsx01L;<#!QZ_|DYNJE_ehm&}YAa1-R{lZlZ%BFdLGhN@iXeWP1ai?phcLFbs2`15b z6ScilHJ-Sylz7r{t0uDzm7fXjCBGw=e-~bNnEd^WefG6$a*gC7{rqt?M10KlOwHTY zHUST=-PCRe_SKjNNvzjBkG~y!eTNx8&DRCc8}aq33_h=SU)LgD&c0p=KH}?@U3?CT zW%9n(u1Q(%LISdzN^XBFpb5rQVRk4?)Qys*PriJlvp@d)M+>a^xf}=!LDoH zEr%XT`?exo!xWV79yY@3I@qp1-z`UbAUKy7XgGuN9pjwi&3Csp@cx47)~y<*pnONy zg6~_)cK!M8)-(-gj)pTR-!V?KNABB->Ou=sb+v}cx9_OE=5=dn9ij%bN8Deam#h95 z^(SJV_a3g=WZ|sZrQuAzPoT|x0B7WPO|UC9>!SZvHB`ftr(p`D|3#SAP%WT6^5?rh zRa!Xz1pQQPMNqz5V??H*K2+Yh@ZBwYG)!4R`cCyxZZpF7bh2H4HG9iM3+F9GI?jOl zcZ?J5k^7omw!y-*tX;$8yJoHa-P8!%_2;`~nHo-M52Zg4l-^O__=08N@4B5`T54fh zT90D|Q-Hqv?H0D{&v!R(w{YIvrQr{j=8xp%p$tS6&pxPGl-IO`re0Ni=h3Tdi94nZ7 zx6773P6Ku?4B-DK#O`##N*of@We-d31= z`%aBRs1_y{v0ZJP$d91f z7Rz@N_W1W*X@`b0k{aJlD1}|68NK&uN+(*FN{cj1zT0KZcUf%LU*0W*o=V;=gr1sh zU~qXiK1OeQ_uWG1qrxQhE;SpV@5ZA);?H;2&aq;A?J_OK0nRo23i{=~X0O?9VY&wG zXYe)qs{;Rdcg+wD=j7D*Zk*`7>zXa8wJ?>mXqW=byKxn4*I(XU-KpX1ui*?Z@5W`o zu4~_2J;TCub-9KqK;Ib+Y}cRfu4=Y$Ue%`I4A6JRP}p_tyQ{J_Ok*`n0s8LTt!&qy z@2)Jda9&xb;SA7s=jOq#Yu^>`)G(!Mn0))r8i!n2#CBuHA?LL7cQOvSDwnstk3+7^ z0$#;6ejHK^J~9p|hF%6c4moF>c77M*kOf-&7sSLrxbgB>#M9qg!xh_@m-HX5*aMEM zaer5UU!tmp0;_F7N&WPLHf>WTjuv?yRmIcZase|ZOeS;CaM zXU;05B$y~DD662LU{GL7F1njgvjPRhCM48uLP5eEbi;ka*F|;(5^kY;2`EUh-GYLG zf&_zPaaW}v#aI=S5@k~qR0;}A6y*2*Jj~8@&Y812=ge^b{+QQ1UGur#pU3NSJ2FS~E; z@nrX{;|9*CWCxssjxb$`F#+uETLTSD;|xrZ$WC#nDH#!1X6p=-k1B-TgvyiH{J zxZ`>0eZFrpKf>EL*-~IBWx>_?nt6**b!pO zz@v0cWIdsgjO^*)SNIzsv9`Qy&4oL-2Ku zXNrT{OVvj%-(~Rm@9wAC8gdEn-`(uLds=;8IJ?VrHu6{_EOfzz>%B1__p(9%ZaYr_R#kz zoV)>5bWPfx@(FaDecMwe@w;B$pG$A&zsCGX+w(QnPsp|>!?(D;#`;s*#<#fov%P~y ze2c4$`2~+zev9jCX8Y#zEv~PYknDuVuTG(3;K=pcJZaw%!uV6Elh=O$(Z$$PDR}Yg zX9lqMakY$--v=JIlaAdukmJ}>2CSdl79Q)^lLpq#=MXE~Z#cP*75%eZ$Flw-kZbe1 z-%j2qb~FFtV*zs6J6Zk`PwqTm$S%S@(Vg>&ZgM>N1pBwdlRNY1e)jR?PL3Cu`wd@V ze#F=Aj46iP`}#(#q;Xy+uU{R}ggu0K=ld%IiH6AkE92-`?IG9s!=!ib73YxfIL8?6 z-x!XcQQ{=qP#LiQCfiD1u1{>`D@TZz>}_RC1IspJ+cSC--4|OKy^oH8Ay->5zK_+n zmr-wk_I)&$7g>xR&d*AokxTn-;P`lBb~x@Z;{P3H{11y`R+c!}9z-5@42n=5`Pt$4 zvSI&UHtj#8JZ?1ObpZSLa$CYJ^7yjEzcBVe-`~o+afTs_0R6X8j^~1*be*A-T>5Vr z@`4*X5Z!QX?I?-=+}4(I{EwimP0J~rygthbE9H$D@~r^hm>kuQXoyTll^Qb5JvTJk zD~hMU*;R3dcz60s3q71)+F;4+vzrXxAORNv3tPE-6ze02oJzvO)7 z`ZcaiIEfK#AKB+CBSx|vWXxAausut@GNK2S4Uw;8@WJcbDIX!?+85ZKMOI&!%{)na zmAk#vrhjAG$?L`Kb2!_U_dNvb=Nr!<){f!j`gzemw{4$i{i}UPEZ3eZ!($!J?U~4R z_^gQJYV>(~3jg9O0s6edb`l1`Gwg_gCz3v|lXo4{4;R0N7#MSnU-}*A>!f`V zSp~@ThO+)eRzvFy9J%FszA<#@1frW9L$BrdO)_*6w;!VW*~ieK9KSM;58TfDNDRH5 z>kAP>jlR~kZ0}lcfSmqzZtq0Kw~KxxM&{DD@Qvj{yX1_@nQX`y_w2Ecu2bxE5+&@P zkad>ho+Y(JLwWWY_blP|Ok`a$LvchLt9lG_`2a6|fR6@ z>*rXXiZwqHtoSZuwJ|^Lvp z9$m4-3@o|D`D84dZ>YTo!6Nq0?e%Bb{@wAjoYwNC>FJt&hHL`pX$ae&$Yuz~SGR8* z4W6qTv&6&r6;G+5tK94+O+Hso%MQ=rS}HGi2JbuvcsgW>hs!IT0ip3E*>e6C14{r~ zzHL607c94}GqB|5S82M+7ySp0IiERc;OT7O$<20>WYg^w(-SNKWb+v#{(Z)be-X*1 z+e!mZ06#C@@5!c^+lx?so-7+~Z-d9c;^77s@keP}Ba+Qk2eOk*QJsgUsEMByJUQ9T ziUwSN#;Y2X>1Q%p|M)m8ZhmH>8qs}cWhHRE3{ zx=Q-@w3BzG&=a2u@Xo=l9X+|+I?#|yF7IokVqt$(8xDZwmW3XcTQ-Eml9JzC*^cQ2 zjx~eM7+6HVA^a)be!B{Pf+v9e4w~ZO8MMTZO-}afgJ-xQp8$9YIUYzmH7FK6o-RkT z#KZUnPoWwAa*|JVTD#e0v4JN*+iu4P?8>coSIa8C&ng)D{?S8aR_Z?<231ix%x4AtCw0NlvkO-#9pfJlgE;pJ z@&5}UuUYta(Jc2r6HcsKxzedrI(X-(uw3!nlR{^{L1#Yb%vU=6p9z=d&@&%ds5BQT z%|)QuPHEnsLUV~ha|viJG3abkIxCdU3MX+hw^!hCX$qZH2Ax%)v&zHPYt3vWK8H&F8{fXZzi>+ z^8KbxtbeUPKn%KR1LNU7`b~{=thsV7IZx6$9FnbIx{UpWis_bMZ>lX!6zosZ<=f%5AxV;J&@A|R)6(`eE z+2tPZQs$w=_CCh>a5$`eCwcbRm;EI)R-+%UIENT|4$!WBe4mHugPu=yV10(O(>@KJP4qd$GOmgGdoUfw8M+G~yFPskOd}0Uk;qQ$w9hu8 zOR_}V)o;SLXa2=bZ(K;T5b=-?yhBjQJlH^NOBIb$jQ54jUl@L?clXNJlS1a!p}5?XAD`+j{?ECk ztk(gC+<8m3i}g-k+oMMP0qmlCJ1Q?S>CW-e_4BZKyvC#Zoy5SlR7bdYbj<`0=QW&9 zxi}+=NB28+Za!F z-Pk@{UkK~7p6t%sNp*yi-BsMai|nrAc&a!fl-+q^&k}C~#Jj7yda}EU+pFkhmv>Q;k9Bg^PDx2YRyWI?j+? zRC)hGCojS6QSf-zWsQfa%WeZxRC)jZU_6ZDT{ziYamK)zZ{UndcK_q#*&M%u%kGLv z9;Pc68<;}Nj^drz^A+5F)4Aq@h|6)dcZz{dq6^2v?DN4ZRxw`jF`u!<%b6b;!?~Q} zB``!7ALCiZ$IgcSFHh2cSReOfefdI?i6Lvu)%PoFJ)|F0Ptbuntm~P;<=rXn!!F1Uy15;G}S^V4h<5l5hcj*SAAviB>G;l^GJK+5A6w?hXyGuJ8 zmkB^s(WW2(wPg`^e^CR)`k{*g7cUh;5yYM_?;(d-E;q2mL+&+k` zJ~o?qs)=}>DRFv$A*%qf{NkNdUNBwE@iMA@h33Zip5%26R7be{?&7Wn&SK_KWEWL_ zM>tEEuG(4aV*wo&dYC$Jyj0nR&hJ!qYcZZTpXvxFyY@{6&OADHbsW(+3UHn><57Sy zsP@A>Ozk;dMl3swi}qlBhLhbzYdoA6?LG&x1J3tYKf(JI7j-Z&iNA|4gtj})zqZ2{ zxP1*5?>;)o!}-z0hU{{W&B^1&!1?ceOjmq1K)h?m@HmCVY;x6$)y#Jemn^`QXo@?WsW%60M9Hp$K-*{{b(G8aiKcK4jo*Yv7DZc7!v=bOX!I9_eASXBe2Gk{x{E@2t;ovWu_taK`r-IHQssa31CO z8{B8(9Suwa4NSSnPV=@H$2%txx}<9I0X zF2??X_ANwyX&s^ZoP@>xCK#-J28K*HI~Zkra9Z3R2u_RrrB$3>PQM*x3tGwP(NBwQ zAPm{%^l$GsaHsKx_Gz%bW7wTzxPA5%m6v#Kb>(Mkczi7vnfrb_%1OM<{tCa!{X2m6 zS42;L~*ZKhd zTJP9r*nYC}*CQo{YyC&+n?k2GeYv+cW$930!YIzb`89gWKZS2^jHr9SWkIHk~WxwBx zj)^wxc52x7!6koxlj(=bqwG`VjFH}@wokEq)y8tqqtfT7kcYm(@iH9N_gJ6e5AW?~ zUBCvG)`l2=NXLr2?-1t$A+fgg(ahxOm%Jgon&I!9O&PU7{_@L1pF z{8DV--F@c>Yo3#MZCwOd#sAs2-evzk2flTlllU9Ahv97CB>Shx_2lexB-itSmE&bN ztS8t%1?!2%bA+{xlW1BK-Ud#ve=61<=Ll_jKWCr}+EOXPF%PI2Oue7Z*R zbnJf)pyRB^mhI#1=(&tz%l1E*AISrcaecrLm8>y7dSJ0pe*ioEhoS#}nEG#7)<(X* zEdOj7WVWcF%!DX-`LNX=*J>FX#9pZA6POP~W5g`gW|zZObgnO1^gI8M@Xo5ATTo*GoSuZS2y1X9LwG zJiOBwh==mC?^Lvj|E!wq%d)P;J^_2`OZMbq!MY~?{v7!xwlZuJu}#G`6I&&=1=y;w zt-w};Z7sHqj{Wvg!hro2QwEOptzzO8bwF3s+;6E-?4fV6A>RC>Bb7)0yM(SmhMX^g z=HLfv@%_23{GGOUaPEr-&y=A~mwy_cW7#{_q}^ICzEL&xh#u27J55p@%#$MevA3P zxe~altQEMXGMKniX;cqA+rCbZYjD3BJk`LL1`<8UV8xuu!#CpDjdSKvOnR${uHTFY zmX=!^5wCFn$c@r|yd~{NxwSyz*IVq5C`a{H<5}h(=hZleUA#4bdBd^V*j8iR-d4It zcu}q$*I6(2j%%=mBd7RT*aFTW$0JAdd^FA>>m&R1oaD9u=ezZM0nUNt$TmGEERfR? z&X-_IgcaD1tknA(;a^+T*5o^O_L1RqPxN(UnwHy&n6)=;+yZ{ZanRqtigNWY$3D#X zurH_jfm!wXjiahd_|$*2(__P@-sbq{`PAV}ia!gVIy_sSF>LZ1Gqf)F)Rg6VZ1~h$ zte<3`I=qwUp!@_aKNEbYPs#iN%9BsEfnF-#_D*{9yz z{NYXUFPxK|lb?D1@TP13WOJ~wH(mQ* zq4r*5*n17tg>ta>H@niYmeFyvH`_AiW_y3*l%A`-zrpf_oYdam*su4s?l*Sp`3l%` zO|m_|!TJAeLXy+z??qqD! zu~lH3hieP5Z*JRgz6R&(v2DijHtcC^ei!(S5k|*;o#jn@QG4%Lca_3KsI9}lJHF+{ z+sU|3_C6VY+>4%rUrwNFpwn6PP=>Z{g394A>d1%*&sCt_CVj2~=UVsI_iNqLjW%~4 z?oUVE^I&fr&w#DMYfla_9+dB(&r)2hKzZ2l;Xzaf%2#W9SEKiwO2|`u^t>g?&q9$oRI-=U>k1EDdu;VeH znK7?(?7uNS$8I{Rd}^ChHcM>;eXDOa=`qEjQIIX!GTRqqI)<)+4%-jv8U@=PqkNvg z`9y4K`6Qm1if7tVopc}PZoM(BYa;5Mq{q~TOhmmiVOKNg8R&7UXV)^mhVlcoJjKVU zD32WB&;%`CsclZR-Wv?N9wv5eZ&TiZsfp>UEfX%}j!kTDu-%EGtEQ2R8|Op|_u2k& zf2zuTg<(G{ls4Lcrp|P%WvC5++?w*37UU*%9XzS$O8ej;J)a8uS&?i%2UpTP!E~@r z%dLRzY)rEqH*Q91JFgz0IvxAfO|%Do)!|nMsUBcE6V~XlVLPvNpz@yW9E>UUENti1 zJ^GAcJLBB^7q&CO{T{SoJAWHU&m`N`ofSKH zmFXwj&a3QSp6$HK_0hRLBl>UEc3wF^IFoJXmE9@>wVhYC>ABK=Wu2b;*v>2C=$_cl zD^*&qW!uR=`+9ntd#19w)>?-4b`j(>Pw_njS*^y_+?FB^J%+6g*Pg{HuM`~ zh<7o>o!C^|n}I#r``A2ei?A)j27IyAxVH}bjo7wgtH-tr+g@xh;obr4U&r@!Iu}!nR|Ey z+N;&r=)2%rrgVvxS&uTy=G=uc<<@3w%X)V~9$I5vdq>?xAL1M4+b9;GAKSC{6}Vo6 z>tDh3V(T$&C)?lL4Q*(?Rj2J+3^K06cfjjtjSikG^6DI2t93p_xGL6HC_h-=iv#cSCA0$5lpZnn}2eBQ- zb`0BlOKV{lwXlm?*hMYuq84^h3%jU=UDU!ZYGZ{o=Jvot)-bB8_`dkCoasO>bMHjn zQfwWZ`)TAY`PSh%cl~wdoZe5*#JiO2H;7~VHE*djF;Y3v`>lsmzQ?>a>#wWGMv%iC z)BNQ<^CdIo2P!U^RFy^msnq$K!eb5jvJ}3938R#j*GAV=Oop8SLNb zo(tCfTlBm;?22gD!qYAt*|NDji zD#E}tMly|h&}e9;F^HdOXr{q@KxQtDu6iH1@_76WG3Ng~c9AR|sDoc1c8HH(1s{(U zH~UGBv2<>;pTr#Tlh_E)Pu?Fxyu;pZYxWZ(PJ4b*=-TaQ&t_hlLC?ZwMyt(~!A}Zc zGZQ_VIdzK4(79v(nf0$WGg@rq&$TT3@)*W3Og|~rF^$;Np&y=ETxL;UE`~l<47pVn$(uynMJ63AlHL?o}ZNVQ@Zm|M=w2IhVt`J$1>R78hQrxF7kN( zGutD0UZgxfBz>mXYJ+Fa8-(W<8;FMTjJjj!|Gl_@vEW!_@FK^XrBp9teQ~kgU!;B# z^ZW#IvR|CSG%LwZVx#d4^4u3$k2pup#dVZ0jjCpv!haQTHz02Az_Ycnjf#D%hy6W% z4)(B4<+@0*qpycHxIDI(%1Z3~^g5MUy(ga+*&iXFdaYv@Y{CI9ehzv6BINeVxNn*G zH^)tp)4r9=69}S?dXdY%`6`Ec*hV)`Z(o|F^}aOp!w;tE@$2CGCFt#S$9`!zJqI2R zC=ah|3{A@y@XQIv-sk%N38RjVO7|Vq(N2#~qx?Il<23APA=LrfIN|ZWZvtHd?#gZw#Qd67q`PoEUk?fLT0@oGj4ZaXECvrlbfjC z>hgI1xp=0+K4ul;{n5(u_+VffNB1Zv!SjPT-rWOwcYCS$wKP9IjN~}yDU54y zesHo}>0$08j&}EXmao#dWG?6~EstMTrFd-2S((s!q0Q!{|)iMS}*!)?wCh>6qP4C#j|X0 zQpSQlsr`FyB;EJgzUPYN+->`w>!;`1_C1%c=iQ-S*wAww^jz)dxtN}-{WKoebG4tw zCOudCX>8PUwV%cYJy-i_+@$AfKaI6|4!b9LG%k^IR~C&`dXDvs@lnZr?8X6fPx?uX zW3(LRjN_GQeQflPcznixUZ4#9qd@a+j=h)hVbAqJ=Gw3RyqiZ39{SEZ_?b_3(y<-NXcVDr~_j8a9K5I1UbjM?;f2s3o&mE#V zz?(6zwwLt*pDPoa#dyDr`OTzQB);~~A@rQYroAybme|B~!$$sel(C~8iA{gvIF8&G zHbYqdv`6oksclwz_KSH1&?6pDZVl6B+sAx2&oli=^=}O(K2S#W-%NWN(12a(%>?w2i~|sSUs$PV7myhep=FXAjS= zRJ`WAPz(0(>?BtXMxEta5A5ND_5pY-L+xSjK6)nE9-iGq*HY{OdB0`Y!!hwQ&f)eP zr}D}6u%}u7Vh?*<{i{9fsbj3Ljh5|U&vK@nWDk2>{i{9farN)gE@#@l_OPcT-4lD* zGf>OrVh`=Bo2;_x2H*LMiRimefnQF?R)G!qr~LN~`xV$~aKCx(0_WRt-he&EGpxOi z{Y)|8!oDr-p-Y`ZxLxyKYvRxk|Ec*ek6Y7N>vZ@9>mT+r1lNkT~-^qtfq3{54zmN@z2mDc-}pU?gP7nGVteJZv3AP{;QL9wTtB=y4p2O zpQ~0~rOzk0y7HfgtpqNBo=wvMg= zYa#Oa0>bN#S={}Q6~ox1j$7~?6W2jyByZj|i0Xh23g^CJ6{sE@=$w3P1j$)+aD?Sn zfQqOr*6$SnUn4!s^1l~8R0KQuYO^n448d~e2Kisfgc;9peJX!igEl%@zP~?8G)2CD zU_XXTMk8-X&m&u&=QHNxf6w|w{m}LA#}R$(docET%JrKuXPBG+{X(NG`9INd{oer( zDRcF|@8$9Ed$t$SE1skI%FJ{1{&P;=JBjwrTA~X&=x6O*PRH0YKPu0(_Y_eUGT*t| zz^}R8&MkBexai#^9_PY;Pj!vYPL`MGVCP~jm+O0sqpKkwcb$P_KXriU0T=Sgr`Ue5 zXMa;3T>mXI?59khf&V^rhK{u?>4NASQH-O(OIfl#J++GN2`^7^yaCT;c#d>2H7yr) z=l^`?aL&^EXGK&u;^`1YuKMuqufR`>t@ zsFXPMB-^`BoTB!ELmYa7?O)6I#Gxl9cy{x|LX{20p>(;p>yiEC zGIeFlDz9#`#-d#wRSjQ*FAO&1bQgG?hz;Y04Q!v-bA2ty=`NKM^-uX(FP=X!g=LHw zZN&45i02a_r>WYm@|=Dp@E`{qyAb$9Zm;d9XH_OM4gZ@-*Cm!T%r?r9+-4^GTSFhZ zFE-UMl8%9KCgfI~=4&m>t@&L~*uK#=*0Vo5c0KE-1sS<*9_AWTZKRH~I?Wn%1Cy)AKl}Ao?)PfC_yLRB%kF$QTAHqCl_O)`gp;7L$o(?8mLzkAJ(F{?59+qnv2Nj?sSZ zD5YcUSwD&=!@IpZ*dJZY`uq%f9@u=|?cKrh6CQR9*K+>v_PXtjKMyq&Cmg$OonWn- zMtj9E*znK6bY1+j?toE-{4@F69(LVgx-Z!3HqkNh0RPNBFA;3*h=yZt-)GdD2^-tL zE5~$f+m9RAI)=hlB{3GbrVt&`+2c$f*H}M_BSX%#eYwGp=1e;{KC8}Ca;EJAJnY-Y zDE3@(CL?csjP(QT$TuHbLo~5xeiXZ#D`jZ^A8Ryt(7g4rI>qLbw>~zF?ul(Y#{7d< zHy_AsAHKQLhxKMV2Rg&BHLtTnOix;8it{RLb5UjiwrXrVUW5HwT;G8GX6$*bDfT;Y z{tWhw*weVmL2QSy9mBPg*q_FnaSZbyZLqa>?B7iyzQhK8H;#^Rt%qLYepDs=#IXj> zK=(%aQLDJmI}CkZT1PO7WFmdum$%S!bH|~dgY(=Rak9cuqa&z5=?hfG%VOym?gb%{9P7IqsEI zPaduFn2c>YwhFA>sKPcE#|yAkV_Si(2HRR(-+=vQ?6+ZGkNr;UpTWKn`oN|x^$dAd)YTqSvO;vwYKbMZW_lcjM| z%W7gMB0RFJU`~?J%}uxONiz)0p3nVQ#byw)WnXut`UEM8!%pEJA*VIAJ({-KCg^sgn=?GSO`jd*J^S08#C6?$l@RFrHm# zJX?xqpULoSqdr?|JUiTYwg}JCINL$T{_O<1uC{wnZTFzs?m)Un$MA!~%7$?N~Q%Aeza~ZsGRGd-mhoq~2J}eRct2j$`#5=kqMb3-8%}Iv!4Q zsjdvLM#<{OG*jy3_Sk#2GxLS@0_}}w+dJ0feW+f{y`s(7Eb*xxdTiiwu#qjrBsXer z@El~kncGWhck~&Ke_DPz?vJGMs)Olx1~GCo`x~C2abnQid^Ck7+mAt$y+FNe5426lU(8vwm0z5sUSaAR2j1p6&D@vhP}Mc+w!;qjgdBwxd032 z5!jD)?B6V*IUl|rpV|sk3yfh8`_1j-Wcc$ z+o(R^8HTOEXB=j{ryFZLm4%!UD}KZLs~r>p=lEnNl?b$K%-oW{E2c6~8U*^7()`R}uM&*B_$^VF(S7A*FavSKr5bvIk(DE7j1RL4@ z4eTj>fQ|hKuVCL;s@VPe04?h<1^chp5iQ65HT#?D4%pA04UYZSJBdbS?7yDjVgEJj zk$lCsU+7{FFsFgs)ffl-Rg>`XE9S@L!}M3=Vy^v7HlL+-9Al;hKDpp+I%ZnvtP4SyzkrCign*S$v!nPjlnUoAGu_}J^O*q%k_zbdD)YOm>j>&{pB_m@UgH(9Hz z8?1+_u_h0FC-Xgl^`N;K8_!omE>B|PJ`k?GfbC^$uVZ@$*N8w-%cWU1Qx^Y%;}eTQm?& z%xg@&ndNIe16nU2mtODnDSx@et;?(bm$h^a?cjRpdtJxvIoU2^9X-22! zy!6e$ic9Sl!&U*uzk6naX68dtYRd&ucOqTjV+P?EBm4zGMH~%;VNeeEj)*;)U7-u~)2L zZl2%Ax^~gWJUq+sMs1qbz7V|PmPBS-vMF&$$s_FaqoVU^?zy7q;?QzGMlyEaf+^qJl7 zhgPE9EyFeu+f>3YG3$a3qH`J7lku9L?WSj;7kAw!=I8KEo-scs^C`PnZq$YWQyx8| zF{w<(8rDdAT;9Bv5An}(*IXELc5Apk)rs~E*KoWAR_z$*dVeb&F2c z%%)?Mo9R2J=dO40*GUU~xz#&~u4Av}_y!EE_2m`;19BF$Y3K{W&W7Px_BXn2J})v~ z1tJxk=E_0vIm3yXnq$>B@6hCGEbnKt@Fz~q8Gt49WbfHm} z`mZVLU4F{`ELep;u#Nza)PF5Y^ILb$3;l@n_hipD+X!elLH7yVZeS0?Nz`0 z?txzyLP$Aqn7mv+ADC)wSW4~ z$pU(}1NJ2&!Nr*c#id< zWoTTRXmPv%9m26TIlkAn^JG)&+W%TSM{9xW(`?1HYkynGutuPU_2bwz9M6HFwXqJL zH3GHlACO0CAF=@QH2RQFuw5$uqYW7uV;(gn#Iu(1=|leblqZv#u5=999$CcR6$96xC7h%5y+fp2_zcO?ebRRZF>s(eR$MOd`zKSnAI6=#;_Ko9i8<)vXoAZ+& z)e#-X{?UBeQ+r-{FMZSVM;vFdKAFDn=hs$e$X$N4hv+CzKDo<}X48G);YZ9rcx^p* z@g2iETU1?}yuJ^#c+CU+=1y$91|R!LxQ=gbSor3K_f80ompS%I<{z?0{<(6K$YSLz z+S4^^%PKLp1$mUxwWavBDf-L9mf{-mAbpPWkE*SVBD-+c5}>{@Y6pGi&h}k@dS}Y| z({Y9!je{MH)8{L-P3`TCRjfQoc(i@!jlOhG=!x>xsoVco+$Sod%bk0VW@aV%aBTZHpsYleYm2566R>=j21+M}et75iB>kTKrB znV~kj%#}6dRXFz{@ZZH<&#;pHF$H@CXrVv5g6&_i&r|I46g$T!l;brVbLQh4UDo*n zN%newq=9Xo^y5|xQf%|Mz8y5)Xe~njkNP3Yyt$^|4L6>B$ne*P=sMNu*gs_dH~bYg z^TPv5e;CR@K0jpnf_Ih8581wOK2`Yp;f7{Bwbnz){{6#px+lKzL-t2J_mHoDyM6Ii z{rd-u&#`|X{tW+q;1#PE=w{*5KR89WGW+xo)_J&p;PT(PPiL6VSW#=0m}3dRs(q3l zu>Ku;Iolg-t%Pjr!R=Nr&9_I)y%Xa^#dtRp-!z^x?0LL1vvr1n-LHQEz5bxHQHJux zl>WtXZqGz7%a2l7U@C)N()$+foI|U6Sw4j5fR}c(hiy_ns(W^NSj+v6jv+eUo*4fXE)58^G)}=HjlEM%|#qp8ndR~_g>8U zeiPO^q5Qq?JO*7qx{&H~V~63x?syq=y{wN>hIE}W9=4SIMP#-tMrFYh#>3LTUG_W3 ziQlVkRo6?$5FN)}nooPxbtllx!Uva{cI?xxF6}|I1^3bt#r=Pv>+jDN-oDTF40*b` z?&PEEPJX(cGala~s)4?t>xw^oQom8Knd4?=U2k4R^|q|*?-v_oe005pCg_!H?fPE+IyJC;{ z=6xd##~25Y@pi|qW_h8FT!!ObBE$b>{g98QzTczo*{ziMjs)QejnT`ks#mhE;P<4v zp=ZChoN^5GsVH}-!L}CLMr>QL)nnU*Z7;Uwb)D#Y9mV+xY^O2Dfp2?27PXK?ZLE{7 zdD{ispgGjOl;g>mTD2P=_&RdB{&>CyGT8|G*+Q7q4mN6Dv{CY&?{nPq@~i*l_7Tr* z#dD_pY=taq^x3WY>~QAwWsF-vuXB<6BR1D-435dT)h3SP=u@o)=3O+8JEsVFBY)Q| z)L~Unu$^9-4>{$>E=0R9 z5BXwWgP*ppK1g0Fm%XU>AZ*2q0|%A2gIfPIdJg4Ya_sN1eX0CjLcWjypNI7uYKN&j z`qH~3XV}Pb1N^>3I%0k`PsUv9QO90<#NhQMsjHg#C%z|E6!~A-(S$tG@j3w~g67RWK0=hmS&&Cq^Y&qSZ%esb~@5Nf; z^4NvVyz@K8zveiuI9LuUGp+xBIo`l;6KG#)zKQU1{zO%U%EZ zy+d>j&m0sQ-`l6>O5=Mw<(%k!Zwwui?LkhoMw-?@?;3jcbUmJhZ+veh-FJNh*I@VG zo3He?DhAd+>eKb7-I+|3hILZx3v+7Vb9Lye)zR2atgG}LV*E{F=&?IC_-?E} zwnA*i`tb+Yo|0`X)*ZS+zjpCB!XdJY^;Uc7E%x#~_IuCP9;l+Sc&EI z5{qQrh+tn-%h-$HC&j>yvW~rIFVF4oU4sJz<6=4HoS0}-d7uYz%m_ZdGLZM^sM^2 zPaeFWE8SPz#dHk%t>;4-a(J^Z>e%-%E{ZXa2Hcaw+v zyKFB(WF5YL`CV>b9D9Bv^XBzAy7=@ty7=`usDC+U!e3`rd>4Jp=03;T5~i22f4R1o zA&+_f{mc1#j50obj`_3czS!q{*MCFyIp(o{I`+H<#xH)=Gdo?+?`Yum(e=EY9`1QZ z=s1Y3AJ2M>XI>wo?bvfq(%u;3>1mAd6eW-G{EYoleK5lq&%6OdPs@;AQpR}ZvcHI4 z=COT&zmQ`*bIX+%wj1@qZrSN&F564ycsG~jCAjB~r22yBCA<&bH(z+WZ#eBCPq*LS z&Bq73W%5B9X3lJ)wDRL9DDYDqDQiZkB!FpDL&tUbwyeE*uDAmTxPk?ZlwFd!|aoE48684cmH)o zmDRQBK1TM3tqeS{KZ^~|=Jvv|D~?m0>_hN1%tI2ddl<(7Yc%^0uFXAw_cX4A4<*m# zjnuikLT`L&b^|?2{)k-A{r1#otXZP9kY!$f=EucUPUSMu(Emim1N~Pd>0fYHu)M$z z+0evf->YEz5?NNPV;-<}({~P~wKYgSa+FwgPqVxn`yR%J{RZY)VimtLmmyYlC%iHa zSHb>Ba)Nzz8hZBs@%SI>fv!DlbproGSVlGI^WmLrjb)u$h-KZqessk^#?(xI*5Wd& z`9F*qV%>j_6Z zhU?VlaOZ^Zug3byug7;m1~IAwWs1;G;dcwUZ{pE;CIFphprdWA(4leW*6{2FooTJm zc_9Fu7eI&oFO9EE@u?hbTjHBLsc!X|!G_Nart7e!!8(_(-$tCp`jk29S!{1I_Rz}O zrj{`<|G_cLWPec%Y%ifOROvTB65s4>$Rh3CKFDHNvMgp!qVj@c=3;)9{0e>!9pusn z=5^>!;u{?AR2~6v{CAUqBQG=#wu^6YdmUUS|IPWL$l|}N3=D%?l!bp@M{Q2?x8Mi^ z;$$g&fah!-`@dK|*e|4d5VPsqleE5YJjU&&QaRNV=T8_P=Wl=Vzo`-{yV5gQQ^o7k z$gg1Ysq1+s8-6gE$|I%}p+1iPDii8!PEKws{%Z`CmDu%PoL_9f~1Cj`LqJql{0EGh>s7bH+Y82F{jqoXmPk%fCTObAuV|PmVpE?Gy5% z_asP9Wzf@1Dwm?C!IkhG(bEq(&OlEimDddI`3&)YZC}#c@97-hL?_daD6jtQx2q3- zUYpm<0ypOWs9!OCAko8~^gugz)u)RrE~D`kP*Cl=0Eue@gtrIxf`B z{G%>^{bkM5e@+md{<9D5Q+TTM=SkL?w9M0gn(@SsC-zIx(||MXQo+#E zgPY1Me!q}%e_gvf{ScLhU%BriwYGNG?aLbT16acg8lZ`MdfIY2R^3y6HyGEd=o-lt zvQ8PFpEiK*iA<)kK2Xm8n`f@=`sWVSZeLdG=C$^yoBbU$iRYq%O1wLn_*x^?iFwfx zj{P0Ri?)0O%J{{8zdRPtO*8Fx1o%qHTc?im_?qhSKN=V)7fsJy!BY$4;YqPyc^E|W zGx-?!;cw<(>_YRjZ|`9|{7%@nIbLXvO`X>%Q93(0xie{j5zT;@O6zZ6q0a~nx^>d9{0 zneeik!tI&jY{xv-aQ-H?_Wl!c5JHcqtDeS9+WBe84pD#Z|?kB=33N&NwQ=Wav)lautHQ_L}ZocI^t8QYQg zB)Mkr@w9jexx0Ct#-h86iH7Lz?g=bovC{};cPHy3czpcU1`pG>xP5TrPFUG_K7Qvw zsv}%{{8pZUvzH;e2z~r34NO<<-st;`pzG=Jandvo(DbkAbn$V_A*LHxb`u8}n8p~GLdQqX?#5IR-Egw|=3)=$H#wf31KG7@{sYVI8>b9R zUHMswBQ49$8`q;XpRJ9@z2w;6o&*@bnviec7-HaPc^u8ZpWe#Y(fIj9-?7IJ zr#;&EEXIz$%XR_3%3*ecHQb(0##q*Gk3Na-Slzo|49n!0#w*V;%eJENAT5KA|Ib+-NMuRcH*t z?dxd%n%%qpr^Wc_uH2ieQIe4N3nkF3j>ACYz0G%5>B z5z6|Di;eozd>Q<>KB77J*XpRe$mDD6Us1{$eT7Ai{TBNx$rYR5ctC)@!q++)I0rJ1 z(#A(6yG2f7BEi)o znIG}-vFwi#`gnzt_=4DfhW0w$$L}=sf9Dy-F1{0$onk%s8=N16v(r2K5jN4?ouvlO zsO)r}llXieLw5n<<5$>T1e5lMBa)r=%PJlF+baoExPIA~lb-Cp(%Fz*RO11aPGWez zA-e$MrDMuHOk=n`)wt7gzbrs}RM}NI_J53{I>O0r^fnLY=mX57>NukDfGQ_3^bpe( zpA8_p(LD@IB?hLbWOtuqPhowAlieM&J)C!NJazMjh-7!4lenGp2RDB;a`z15P+vY` zU}|>`WVg(*?`D05liin#J)B>jVBn0(XO}sN5{_TNWmn4ihQzy4Za<^)S!#!c?w1D= zuSUC!xwsOxcWIaJXiN9AZFx3;=11D)Q5-KLY?r}j1L; z;y%J4_V>k8tS61}Ey~&(BYYXQQlK#{(;C8;9s5glL>n}-7$f{Fw?FEm0mcZw$o`?c zNIoOH2TWZ$T&VSyR4g<0Y_{@yTsBWUAWnCH%bX~=Qb zo9H|MrV$(u6jPp|^C&Sb&JxpbDleEuOgl%IdS!>{3v7Ra=?e!!Vw$=n-F}}ie?sPDSA)l7C$G z8EpNwli6V!&gB(T=a86M(cx{(e{dZRXZZ@Y;j;~Fx#)1j?8-JbR$gcoR>!PGdR&0x zc}t3|3fSIs*xqE=-uP;a8CTchpQ%;+zm>tTt$7r~kryn&T3pP{e8!9?%M4pwMi^0k zS+Xq-RcU`THDGr_F;TbCNQQ9Z}^<1stNf|4562-fTez>uQ z+jn{xZ$CoEDzh*-O48b7*xG1d<#-RQqp|soeWtzN33=-O`P?;Ix3fQses3RSU@gnB zkCiso=p>5vg_mgww`YR0WVwMeSDDfrYLUhn2N=s0BfYEUC(8i+YG)785R8uazt|?t z1JIhhGQ9hd{C}yI?K1`Atw$rk$o{4n*?!bE!(c?byS0jSBKcE*Jo9t4o~%B{{-QW? z$upDIE&@vr151GX{c{}+ECcyj(c38KEYvzmCvgkM6ScDdSU$VZ!}8e;5o4Lc^h8Gi zunak4V9AdFi%$%@r7h777sG~>dN_y7GH~V^!{|S^`d-YSl}t}$7GPb$VAi+z*I@Qn zwd|X4&6ulg?EuY)72q(sCH4Mdj7$?6YBJ`1`IIXsQ{%bYLpvOXu zn}abX-~9dojdK-?m2S1pn6f*)QfRp6QBbx?|rqPU!^y*0@#BPU%!C z9n2}+#_c8K6ZBi-?)w~z47*xHSU|JTv2Wc;$Es_6pX1g|bPe`H?{h3lwzFF&&^;Od zyOrBZlv{+hx+X2Z%JO{Aw>&4M?;}#EWH)G?firj6`C}bKw8LR7-0xv6JaaCvioOPw z6K&YJyQTA&?-KP!z|MWTX z|NiU`;bb?^@c)75(Et073$Nz_!~YA;iT_Jn{bW-FSPlIbnEKD%pAG*(UZ(HpeR2X} z4L5)NsVbr&vF}rB=vdp&sOGN`KR

DJ4;S4M7FMt1!+gqPibwgyi2m*{2JZvgWjSa$tqc$oUH z}+emc7#qCe-@o;|fxPdeG_>z_{^c}-=MRoyl-cJrRFmb$h^%-5h z@bQyWM>yGiVu^?I6I+-^(Q$;b`}l088(4PzxIL3N@`-!{Q|SJJ*H(PIGtmtf@A{Pz z4Z+!OmWdPn%Us@t_j#ZD##*K;vI{U5(6_a>&)_A%SiRV{$hR-+OMNJpv3eSR!hAs=ZVxnf4T52sC(n;BH{_Ws2A=zY z9S#8&wjbEw5McA0`w1}adt;-A@5Yk`KKj>DPIEsis;pv>Rd2B$vAwjhIrRCQWIqShJQm)2G4mxj0?4FKorj}OlPQysI0j^igUgHk_8AirN7}fv(v1;a zw|`FGe{vExF#pspICk$Ux}Sajyf^!I=Kgta=12PHy*a)I>Yw|Mx%zx>=!V^d+p%xp z_6cKg?t5`9d~c}bb?`FgcLV#2^5yf+-wiA;;p>JqDqH_{#~tGf%+vMkpN@S!>nDXL zde_hA8%nayBvW5oc)I=!;mpj_^_-syPuDa5s4FU-@i4pY97!y_o+Td1~by+Fr#}k7M_0OMCE_#XGb^SJ5+w?>W3f+sowN=N;Of z2LC->{#$>C*56i12F+_@$d1rHjf6b)+h#oni41z?sSI3S4DfBU+gGX#TKTqF&w*6V zu;G+%lU~R6CHn5!j>-a`|5_l|Fa75>ljrR1>&l6iV_#>=JA+MLw>$-7%J+1yllG72 zp{|>x82$asU4P-PkED1AT{O=@Irg=i1n;%87)y;Yr}V-5!^^DHIi+4rR1P*6bWX{g zGfA5t6u-Qd+Y{@P@2a0 zboZllP1?Wf7;pCN-?gki<Th~|rfazU3fE`qo^Rk}e{pfbmLlpiUBmitb=Ug%+BKYCNT9B zkuZ^5vHA5$M;kW5-}#5!Q@(-KZ4l8Af9h7wJffY#`s4^@*DcHVc-1-&(^Y#6Of9$1 zS^4-?5yZ!RcERrTzu@h)5F>I$hnc-m9$1?p*@fe2^lgjiCwRMj1^bi4kuGc>QQ4i>wsff? zzLVRQuEXh?v@Kn^eapUW>C%gJt#*>$wp_vdNZWD+>kk+rjE`Nm8TAKfTP`>Be|eJr zqi9=1hgWn=ku}zI^=tBEeFe8~*~|L!I)hiAT)i{%BeL$y?OTMhu5=PtnDI1#tUGrl zydsm%#f)9r$Cle7Z;bwR;4jejAk!HA>yCYS9?^#WvKXVkob{nT8en|96Z?no(rJdl zOD^N%K5JGlXa7_@X?;@IO3HgWmo<2@y^QTiV}^g9)9r@`Xy++L2%ncNraI`H@=+Oc zy}T`5lbCT?J37wZjxQTP&$;n2J!V|W{D>W2#`OiVWB)ORR>r+9Eg>w9eQ5{gg~q+= zEdDo({D0*#j$h!B{#n=w|IDWRZY;ie-*+kgO+a#L{ujX_{PQzWu!QKKjVjHMS57wa zO5;BSm*yKX@fio}$o?!c>B#K`WRmMRSkkx)=-|8e9g9T{9a-Mc3H?vYkb}yn0oOe_ z42B#EActWjhdIpurybN7Aet1@GWcwOzTn0E7$c8MU0h1X8jo|&b&T;9@T==c zE;$k&YX{b+#P|;D&IMMbJ)CG0cIa5gGcFn9;&<%!Y@gY;AMH;v=6V^sNpC;euc7;5 zFYR|LhRF0FytSXEbPe73@4HJo2WB0J%=oooMwop#vi%G0simC$kacG`~ZKeL^-V}8U=+YO;Q z5Cmg{$Z|v|XgcZKcimRdOtB&-F>XxS)aR&R!1}9AV5E zW8noWnLnPZyP%Gaqt`?GJfcf{*UC@zv5?_eeW-eM70amtW!TOO&kzh@W zB^PyIx}w(rak%X!DleGY?lUk&5=+G2KHA*A<*w(pZ4I34zoGptO?Dq0ke%$>%_E1Ik^sow|D_+5tj=-*~jvC%)=FkW?j zKcel}=bfTG@j*Gc^oiTBzav%^-i-f^qCZ@Qe~yltQ+eb@S|=xE&Tr!9q)Zo-nTRrj zQ_65WQaasGW-9%=l*-J#7ypziw<_n}iT1GAn%Vnu{)clXvhM{|)|ffNo=0E1R}ZQ~ zd01fdH5Sly>1&*~+bBbQ%>~JQi}NJ@b9_9H<1zSO0GXzL69#f^;k#F|?$XX{~mm?sLnn@k{T;cT(>9EB<+xm(O~Vm`^k?CLwrW7qrH6ykjTMa2>VyCnV9t zv$)3b9OE+GQO<83FT;3Cg5#y?r%38cxcYbNTkP@#nWX#|GEq$TL^p{ETFxDhsZM)O z*8PvL|M(l(PLX5VbwmgI`LtJTt-LdCA2G`MyfbcdJQJKkANp(kopJvdLUzROjAKrw znCM`m_aS-x6!sGxJFfO0Zy;Qd8;v6++0xw)SuxmCvDj0L=HJukc(F$CQ;fj4Q+JIw zgdcsZ_)&xR5pyaJ--xlO5p(8Z9L|nUqkB|`#3Oqoo#VODxVOc4ZZt4D`s`?ZmfH{f zmw>R9Ar>7*ESgC7=1hjICc1A>T7+Q|(<Te^L^u`U1X z>ptJfD8pK5TD$GWkk3K?CD?}2+#F~&#}XV*c5Le;@qj(sGjLHn=}Fj(c=9=oCtV)E zx^VqJc>9}+U>n6&3FN{5Z>4%3z^3c3`zkFOm+WTH8mhF~-&}_0@$Wk0`QdnexIVwp zZPyVi#$p?fjeK?#u-3AUYOPU2&%RkzX33Zwu5Y93;CeGC$813h6 zXwz(~GhKsijM5m_(}|y5L)Q@FdS-}m(+&IKZ}EYrB0RT;>DQy~24DpbxW@dD&LGR_ zN%j&yJB7-#y~NKlA1FuTfRu-%kF~*8T4)bx{bBR>Xq@dEuNVmb!C zmfLUtxZ8J0%>SE=R5yHN61KasO(A_@tH4Iz%UgtP8McS8t;V+AiJuuG{GG|CJuuVS z&bZ-AlQd?MzsBa2S=Zii&s877r|u>nMJy#Bwcw*u)W>2}FMMo@`dESb*mUG_h0XCd zex{M@Lmbx_KK_)82m(U;M!2BR$WEf6&js$n=4+^*kdJ z&MJ$(6Neb~KF15}rxE=WtZD1^1nc`OFD*-0MGMkQ(=(J#(0L_yKFF_~g8iRLvVZ7dFs^l=I!LC_UrIam-cGtF{_vig|4fHJq~|s6 z{9vng_8!M)C;nbrq76T%`QF~B->*-R!S3E0N6%)qyZ5*~Q{3z?f$YvdC!1Q0ev$hf zHL4SF*n5{D{%`gdC;o44&mhBL6p!aVWc9A-deCy?`rY?%zBE$vul~TpxjdC!y4~tM zcPw&;V&s;eMy$iTZJY!5M(&d6Y_{VQjkq?EWB?sPum2uy$b;fq^1BZ4chAs$k;lKe zJwpBTu0y&W-CV;PBY6j9TN@*J2N>8sKr{H-5IZRzr?vgC4fp*e`DSYT-2u!8&HcsS z<@QzEz?R#3|9Dafy*B4fs@GERDt-0%$(2->6F*r_d&ty$Plv{E+;t+|NUqIm6P^LK z#APSx8Csiw_L^w=*|vXwIes!V{wMc`<0sjkMVBW_sUFaG`@@xK?Ud`6nPre<+n_ay zcyr<>l>ZYh|L!|F^dC7IzjEiNeEuVMDf6%XIo_~Y?>}-%U(1lqj!$koPLvRD!siLj z|4`?6*jI!+{%Z@>;l%$noA$t9@<`)zE%C^4vt=HIer6v3HNoTYUkmBDRUZB0YudY< zg_UhSQ#P-Cg=4>WoamyBAA!x!4%7Ms@Vn&o*YSUHd&c8W@qacEJ@va>`vBBuX|_89 z>kOui7)!D@>}C{Q2QF718V~--?U~|Ydr@4GjKvpLwvCs~D_Q^|}V1^{Ke>3|tY(u+4pC^SWW2``t-IJDd!U4ImnV^_Us|qq0NAdh%#? zGW-YYQ*iyG;T*{DiL!Zp=Q;LCw)b!{{5!`3#oE!p8kGzc>xp&Q$?)&2Pr>zfj>my~ z*~?RoA!f9eryO(Q|0pJ0+2twH{%9Nzkf$77Omzq^M>iQVJ_mWqJFHJ9{?0b4C%Zi5 zqT%#RZh6W(`I_~2t6EDh+>;N#`wA!4+6BYuW&pQT(2xKa7ENUw9zq$*Gq|Zxc1>d z1JMwy2ROb&+s3+BU)#@e2;4p#V0|jC;paexXk%&I?r&`G;bi!-5&vJVHLylyhc4Cu z*~##)tWS~Q%WVx@QQ6_&%H|b(*Rh-S5bba>{42);!TMK;zF&6sq4mc?(9V_ulU4X1>a2ANBX(|cWf$i zzS=@A_u_EE;KX0-$XJqdIa=qQc`n_4Zyi08TQ2va*&g`ha{DCy^SI`VZK)n$X+4+A zEQ1XFl6}hmK9_%UjJg_iy7QXpbLsZKng5n^cA=j+XMf=g@g_O@zI^4gMh;BouUw0@_OWUjosF~wFBqgT|13K3Ke2sc&-GFMr+UJg z(Afjatd#HF#-C$9hCH%Z6Z+^nrQ>~TB>vnwm21#7q3&AF3~T=WG=}J@jjH|qX^6^@ z>@Q^v;IpUbp4i`?*pDIW+`e~g*dJ)fH;m%X?$)}!_uuUo=hHRn_c-xqOXwJR$Ot^+ zXH#kGkYES&9NUlbnf@)V__O&QU(dSy=iaaM8o z?O}dIXL}|ohTM5G)?CSarsN|k+q8I|zTWDYEi7xE>w0EC9c%x|zfE#;M*rMCY0VnN zF<`>HQqv})OYsM?^|O;8INKRG`sBa$6(zIuk~2A16)2N{^k4NOtV z?tg%Z^%+ifyV;+mPqllSfpb(uvIEXnxczeDq0!It|JPf5cg&OB?j8oFsATtm6FH7kwo%pT|L>oCz z7Hj753dpXfXB zowc+#^55~A`?oOWaG3dmJ?F4~f2Zl6K4T6$IiHa>eJ95Y*vL5;b9hSmf6C?G9CK)S zp3r{N)T>{vU+BbzzWS2ST@C>e&2p$Bt4_} zGw>+%GxPZ58jr^(chhmJJO;>xKtprtr&tekju=ve{K#_br;k%Tl6UURqvPyz>L(A- zb8Z}jZ=}5M`@|l)FS>hz>jQ?U@=oGmoKb&(eC~-sjED2iC(8NRn&{TiNj!SO)t@2j zKOUmGMAlDoyvknIPq4pdmURR3BeHIoPxVDB>pz-y9zfRhjh?LQ*}tO7@yU+GhIb!z z<(eVKPwNXp?kVr2)b}!Q4yR+q8KIr-p22jbeG4GF$CrDU9^YnQimHDE-`U-P=!VO+ zcCh@#?jL7*u8t$hQ-O0A`-^M$t>>vb#(1*ZG24(`%ehv7c&dF%!o=}3ob2j0c{uC# z891ZLQ-Sjjbxc?6E`!8M+r>UKjz?#Azi-M;c8_s+ z#l-DtpniFCj&IYuYOUn>w&ldPbNiBAj{o~11}_0}{Kq7 zn!q^x`#e7LI9pjiPJHV&qK#b6&4Dxj*V6uLDdP|x(%LonBJ%sKr;IW_^Eg}A(S6BV zw(g;0_{Oi*Il3#r#AbZ~l84(-m0;h}FO4@`CBN%MDDS zW3`uGN&ZfGYwr2gqq_;4;Cz(xh3NCECt9>aNl{A#D@a3bDR5k^4&brkZ*`~u3qdZFos9gc^Dqq6A=cL>g=-XOF zz~{;rYZ^8!rhAYteNWSGjxsF|01Z61aRTEM`O@2_WR{iNfTznA5o zSJikq>-IB7y#Z|aS9_?u$l+Jq9%@^Wiw&DN)?|reh=F4gKPx)U4F~i{I>vaw5XatL zLiCVd()Tv~bQnNR8<-!F(}vw9zVJGGjQvY(G6JNBm+v*B2`8_^$C--!`2$>AwnZzg(CbZ@-lMPki2o zw_h?p!rL$BD~5<->hF3GJ(X*KnEH!-R9@`)7pM4H@wb-q>%e{0Uko9dPW%_`XdkSv z`pi1UA@WP(0e*(Q>Mw>HWqkUo>p1?2jDL|&Wnn-5Jh^>Uf1WB~3(ado5l1qtFTu%gME;Or^BS`cDo&MIscX!{{t=6UuQB`J|1~HbV~yE*mM`c;w8m`hNmH(nHNF?P zwn^pZv&L-ga=IsSUb{`pMYzUH4YrKR5e7{x+R`KNw@skItexNUqrY+Q$HMG(Vf~;ryBSF?<2v zzlc(HF{&fD?ACBTBQfr09r;GP-Vh!7x5>Iw(rkFT2x5(UQ&yWwU zsI^MmoKWm;i^QjT=mdR**5_zeZ}Bj#-fv(EJ$B{EZgT_C4JW(R?F^j#44e_p(QIb@ zxG|%3+5MFLN$l>YY#)K<8T@sbl%ILBd*o1f+5M!^lig1^p1R{i(b?T2V$Xr??k9r` zOy!0?L)#tMz4*c-ZHaEUcvrjJ!&%GipUN)xc$bo^3fA8&4v)3wh=G;;B{bIL^~GpI zek1W!^qiKvp`A_{->oV2Fx9ZXxVG2g7-aw-Aw7%l)wu1qvCd-?`=jI#wVMb-_Blk& zLVC`P2kC2Sek}ga@0$IX>jS39>_U0VBMihVe3jM_%D^p|*d;c}(J0j~JPs&Z!4;QyA z>;I3vH;(VBs{hB|_YE^BN$3*=CB;fg3{=u7C@51_7hwg(l;x%@S+ZgX%9JG&-m)nZ zC??F9vf30>{6Jr3U{IngS+S6E1ttRJ)cJt~Wyw+!-0%5%o#*AAy?5Vlw(<7&sK=u} z?&IFqJ?B2}>-l<}^E$6{?tR~PrSdVhuGIdLKwEzQ)!o>s0ruF0aG2 z8P}v88{EpFf@`(w`EK|Z$K;%`b>#^;?tGtJsr?~#pM6OA7+XK2@iKw7p6_;Bw^8lY zVOu|xBK3_;9?H~fJ7R198BP!AKb+%ujQ5ed^>D*02MBiOp5d(PZ*l3sGn@yte;6(g zn*MFLbZxy}pBbz*?a$b=13FYR`SyIUr)AHs=n$jrR_J)*wOzATzcyX&W!i3q_UF#G z-3sG>!!=-CsY3afwp-!#pHq)F!RsCY?;Wft6b^29g~qFnt>ye`zuMU7+%6wLyTn?~ ziilMwU@d2b75`Rv@h^Dp=B?#)DnD3JEBE*OW%8{jcFH;Wt4xkN@2?fw-ebp_pQt~L zzkX6g9Zv19Slrr=X&K!e4Wa*|1*zG$b5x9=`Z(a+fES?f64*{3pQt{J5hK7SYR<6S^8fNS{!c`%XZrtR+Wy6^*t)nD zwoK!t@!hgYh+Jr*=|*%^6#+iemu<5DMPO{{)}%se-3aa z;`MOqA8QV9rW;-c2i_+n!}({{U(Q(888c!{M)2W+zFu+*m>IzF*qchx2n@LWaz zM~`_E{(JV}!Ez6@vB@!VhACDaIYsKiUQ^nBGhmVSC!^=0JmqNYHKmL3XX(;5{;S@o zn5Hdtz<>8?eWTBPdn|q8`!9G-IUl;Tu^VEy_5WM(bqF3|&5i-|v=^|3Z(y_g=qzzem2A=HwTUJwZGt=Q!yTN{<}O@o8$c^iT~X2 z!W6lO8@~61?BQdZm&E(SiA$)NAA^lW;ore_7yt@&V{`7k>LIr!0Db6!|9&%08TN!8TR-= zOWzor?y=){0H=FQ{;$tY?os}y

z|}@_wzdSGVp(`Q?CP`TBjZd$KGN*AmaL}Bn3E9W36+n=tTwb{9di%@14N) zQBUCpz#i3CU|)X)n-xRA4j|rlzCsRH;M)4@G$3B5Ul)t4#9Uw30NubYU=TQ_W32P9 zYdid2Mq5o-L&v|}@`JH1zVPz`sI93+npA$u9@_~4M^;aq%$6(|} z;O?^C2CYCGe?PyH|JCPLk%+i{o<`pB9{PXv{3?R>e_6X3V`UF;5QshgoePLP{vGz? zO6>9Pu$NY1kAK$*#2)`HDRMaW_yoo|+zl)TVvkQW0ds+UK)gqPp9U-jRsc(ZnCI{c z;1Dn>t{*(W8ekc)9@q?Q1P%aO#PwsUe><=Q*a>U^CV;)bKHv;+P+XHmz!4z)JbVn; z1)KyT-ot0a^;51$Bn=n=+Ccab2?60pBp>U8c_KwX%o8aAHUi6m{lIFhOR9ez5OGFg zz$WA&EUpj3z%pQJT=e@tyPrq@|4;7cMZ~$EcM$R7_+P!BPvs|dKac(GJhyN>`1_x~ zGw^o?QW^OB{-h9D2;y4bM#;hbMFs15s28AK&w4THc<=oC{zUWf_x%a-fbU^^+5jAJ zxYj$tN7tzjgD3x6PtkSnPyRKD`Z$VSTkEwm&fCs0p%7^&b^z;Sy?;~#=gWHOX}~jN zJva7m>e_j3ClJTq*UtaD*Um@fiR-Vy|M#z*BVFQ}`ajq^ANaVcGVh<6&K)C0j1n|x z&;g?ajSw~JfYBY-sG&p&5+JM*1_%%!K-#A5v z=bxfWvSaF2Gq6_;m$bfX&8ynR)%!NmvN!n_n(5f!`FuG8lo(YrkoS z)o=jT!VGLMf&W(wqp%LP!UT-LA=m+DVYdk^mcl-WU0+VYPB;WdU>ee|zdUXNzs3G9 zPr*hw1H0fn9D_?H@Snz*GYeo1EQZ9N8G_@m!UTR7fMF={H4uBwtcR3yW)ob1Ehey3 z3EN>SOu&BF1*zAWy(aKq*n4I_Y=DDM${B&9a11WNNfY?*FwDRnVfiuNeU-xHisZTn?lrrGsJ{yhu)AZz{#IAQl) z&9(m3e9vOXdx9^q-Z_-@lMRzD&WbBL;AzHpi0F{Py|_v25KN{(ExTtS&Ie+AZyXU3}h|pltTUs*rESMJ7E{>fuk@9 zrMv;-1gqdMl=4O)YvSkxlzgU*^E&K~&ca5x0K1Jj+rV*Hh#vy51XjaJn1t1E64n~$ z^#!m2hG7&oQ(xBZFGL_~_ZONtUh>jwWW)31Bk%{|Rs9^AVf>4oNG{iP0nXGxP}rAv^BZ&`aWts#>;(9?z}$D{`Ye99Q%L0tPd(? z|NA*Q!anN}@BD*W*#AL}X3b)Ln4^c;|4~*4?3#Qct9_ZUaSmerW5cL27aupicNKBq zUB(xhg{K(b5gB-_@s-6OA^)6yAFs)~jq?Usi}pd*jAy4HYt6HVApPs?G?X>zxN!>U zKW9(DIyeJ6;5;0GOK_2oEfpB&jm%5u6vK8Hf=S}L-L)&_*tIL^wtK!y)7v#3=e?%Z zuF|LTA@70x%mewg6LVC4?R3Dbon-hqZ=BRo$n{IYIb827!))t~@2CMQeebJ)e&h0u z&|P1eb0XxizBT(__H|!XW^W24l99+u-2IK0x$uKAnDF4 zg`_*L+&FJ9gH@3H&Wk|GJ+BTu4{!bc&Q|tIb968Jp{#a4vyL6v z^keLo=jeI%E0*=Uu*v?8iQZqls|qbIPe<7g=jbl>t8?@a`;iU^IIUkKEK^K zN8q#b6HwC8myT$L^ra&@VLz1ggK*l-GiU1@S&ZU*&j&}6N3PG0Y(j@};yc*S@%fSB zlN_HPiA}jaKXM6O$xD6wZaG(c;OQFn!#TR0eX+rd?`1!dqes}6bG-Nr`^!Fe-Yw;w zupD0&V!tj&%enPg&5j9FL<9usD}?jOd~`uAY=jLk0izKAUC;{MGHiajao#I_E8(SeeQyK%r8zpr zeke!xvtO3g?)@y~>iO&#=e-jGg4Bg@L6@=zuAojCt9>89Zq9Rw500^iN#92v#9fdw z&QW1F1Y0$d{EteqU&2dmK5Cr(9Gj1ldWM$c%O!5vW~aOcy==2nE_qkvq!&AL`cwG` zx+*6=!#;N9*7<0p4Ivj7%qr(0bv|a&YTq$)kUCq^&c}$YgbSEgkH)5!0F1&SD0aBP zIeLtpoI00F+;W{Im2K|Yj*JP-Lu1QPPkL-y_Skd}7ZRN6QJ=?5)bAKt$Nxjs}#U*P&s(FD0ZRCL1; zDCzi|-3t+zaG!4w|B}x)Xj1!pgY#Y!@6Aac&4;`P{zx9kKgX!T^IUWC-_@`^@U{LP zkX=($a6PiYTbrtE;W}hKW_;mx$eQAKu2CJFyv_ZhZWIfiWL8zLRtfl3z>g+qJ|+6~_5+gf&Bl zaVlwp3%g+*m9nN7f(tNhoDcHs>cVl@0;gaOWeUhUtQr77+68B5kY zmI-BwpGR0;8`w3El%Gtx@vp{zmXOmQ<-6iL{$~kx4M zKk|PY*w4pQC3K|A+9@Yo)QsRgr7!hBo)7U`kai7prm)iZqV157UjyyqH4x8-s*=|A zFKf-h8Lx>o3-!paQEc<)H~YW?`87&@jdCEbQOrecTyIz#TogCXM+#skjKCfkgGo3D z2Ve#c8|R~S#=m;ltmr{Y@XfpQwin5Bn@zE8#XaLuLt#`#><_eN?uNY8sCHA9g1Mrvju?~QyW1i9vZrV;WU$!Dy7hS)CeiG3A6M zo^s@K$rn>jI0-2yJP9f1xB#S_<0>KL9LMvDiz(;0E=W1Yr6J`Uw*c|S@#PSI93O@F z<9O`9cnp$mhc;Vo>&};M833yFQ5@TYF#xCSe;Kfc|22Iw7W4*1p6*2g!t!@5{O-wltJ>jq|!K_qP$D0VJ)nM_ z9E4Fg16z&r=fyAvvHy||i2avzLrK>MXJLx|R|O}T3*$yY;063Hd=Y;VR(St;J6&OQV7g98JqUs6lyXdo zorD!1Y@?hh#xQmf0^W13dy^c;zS<&)-L;iAenn3oddaNl#Sa9hwn2#>2rGKr@>bj) zc6D!+rBmCZ98%(Uf>XQX@`R9O;6=6nMYaFMR*lEs1m}bn%Rp(;GV33;-yYn{8~2%X z34f`O;Wf*D2}USU^gORcHGCs9!Je;#_q~uH~zAKF_+Q4E5oYE|aT_R#Wa}P3W|0X-Dd_az-`wUlzyT|5Z)9CRWS-9|ZWMaHQsRW0QFx(Hi|FXvT> zZc$y0u0eOHu17bbhg3JCThY_1W9Wo&J|9rcd2KyttxsDLokBNhJo&VZpgUEMp(oJP z+uB3EZOmDppHMxIW;}iYDeVd5j`L5;6NH=x!2 zRZ(;c{jEUb+tKv5ld4pc&no)cNoxP9J~aL91oHFEl19hd2{Y`@Wwm`?b27(l7+2<^ z%J?p+;Q*fvzEskE!T2r{n?7iKtFci+{&~&5eO|LBYMd|957yAXzevAX6N7EA1EwJT z;ES~Jnm*&4QU;^$dr_pfpT8m9cAvkY3A5KW`Q2j9f2};%vHdf@$$MZQcp$qL$^Wl5 z--qVAk-uob>sB)bpG6I^&$W#Qid5?+?#!+Doyg+L-oo*n)5N%y*`}iu8S)$J+5!@iA-A zh7>vgr(qGtiy-;SeLi}-Ydx+Cyvq0a0iKmeaBA^C!Mjhl_xsql-F-K92K2r=AkP6L zeRY%NzS!jNuamf$Ib{`n=K#FF&R%ocqqe(cuSxBU!S*)eoR)C?(;i2&zCNvAwTz|S z<@?X}B%1rj)5bJ@2+h2AS|z%Rm(G!=HL%aQs!jVSY34~gVVu(|;52N7voHx4;F2+G z8BdLji?!TSHj>}k5;y|OAm^{GG|m}iup0846PwAGYlIvAQmI&5$Ib_g@A76?Y<%%? z$eelw<;wf>S4_en&%s?geH#-d``mnEC;QdJ^W1!6xADJyhJBuuZ|r3s`|Rz3E%Yp2lkm$fr+5$;*rnzaqI?EvYcQ0!{Oz9NYIGRG6YSLb-j zwa;>C;pMqp`VK9=!a;x(U+9y=SKDm_OI?OvQU@yPp5oCyW!F*nj5#^-b7QgMW7L=lT|o@5Zm| z+lf!^!;tgV)922jz1G*0PZ7ipna4RlJAZor zC-!Qt)v;^EhdOD$moblP`V}9Nez9*tem+m)=#m3=jqaR1?ACuhept^M>}X6s3}K7$Tx{49DNE%U3K&v`MK&*QF+6`+gIeX2`NL?%UDP*Yde4UFYB{q?o4I1iIp4Y9Lc*1*1`zHhFBdOgpDu*n~igBk?~)Y z;yw2=&X>S^vQywan(LY8<@rdb%;U_{o0{N>a1=66zn${1*LNMCd-0x?T*v2LIyfxz z_jTB~t7jz}`i#>;zWd9wl2{zSwBesln1nrW3MP%iZ{3?1^LKMS7!Qpw|ww=ooqdP8hR+K5;(jHWb2YSOVK&8N?48D&Y*QHV(g`Z8p?G+Hpez zlyp(p4_o0RjN!jR^50c^yX~B9_YEDSui?CID0a0`Ke3m3%XI<0SFa0(>w$hYW5@OU zPV4=a45{g1pQQg1yk|Jhg;ws9P5%0j#LtZH1N9k>xBlKR$e3ZwUs&$?W5cNJf6j%> z1>&C#GPb9PZ&NK}cn;m8deNATjQtCTUA>VpyRjHOtvZBe&hVZAZLCCxiC@xq#_Yzr z<@YHzHlUkW?~_i--`LEHIl=pk!A9najf`o2@4$`kL^I~S>le>d%tq!k@A|bdg&ssV zX?pD3m`2A{kD({feX6I>8S=+2TmBrHIqsqsS6>b;FF<#xE=HH42UM4%E7AB(&cD2x zR}Fezbv?S#I2RLVjgO=VGtC zY4nV7TCvmS&+*F_(OObuTo=xujHeKk)--&%R-Fn%5Y|THz#2!VKh|X<)>x zsH)&x3EeKdZG4WscNpJSr{PmYiMu7jNaNe7&o~zjB|{YMCupKMQFO z?&VGXI+w)5B?s(vE_)wzMLB(+dCa>`ToFbyk9pULD`bo?k9pULD;m*Jblmmd6)osC zbf0R*-W3VPRtDY0%e}8*$2fe(a5>2Fml>{Le!Pr1>WW?{<@CcrI0$DU^L<+hWKL{j zjPc%s)7A+ya0bp9htI{CE12h3G5=l}fJs;c$066NRZFnkIIAmR6>K*Co9AJV8Y^>U zPPkI$Ox`>0X@0 z-h}IqEAh*fDfGN*=DRDISH0`Qm80l!bXen=zpk7{H>sXMGv>YP!<7r@CA3~2t_m1) zRpIiw`Kn@c>GHbysxov1<;%P&FYmcn0sDhly~powdhd_!;d|o#CpwM8=UUt#<>iE{ zq|Wa%zB}t7>*l+Xkh#9E5;E8K^}?LFesj5PukTSWulZ?D!j8|t?7_Xf$bxc`|>IFSwDI0lbFH|+B7j^oOl?{!#21Clg3i|w|of$k64Bfk3wA?;&H``kb5YOj5^;IBO$H=f;Bhp}S@duohx zWeKc@b+8F`!WKB1Q$MYjSI<9CKWjLfo&0>|B1cQD{Zc3AD$36Fvt0+4W#i4&3DVFn zuI_@puoq6ie&ZxacJ&|>yGNkdJqE`i{q5=!^)vOf;a$pH9AbR^oJa6I5R$DDKR-af z6z%!>er(@UKWFXEU`IXnFn+0nxtjipjpiEqDKB$P5v+lwFhRUmPp^JneRp3^47Fh= ze_u1g@f?3&lR+QOOZ)Y;?3#CGwYjFsIM;@-CjuK`9mMWy8sRW(Hcki0uW5sf^K0U; z4R*p|*WZtG+=eox;u;xaZ^p0qk>GnUAzLNi33yQ2A;;ejwCuURvv&7k#~k*gjPn)B zzlM3^D^Zw+z0j+dS0Ar_yRR39*|3v;|G>Oqt{JCXY40iHTo-^duo}+8R=5Q5>$L@N z9x`8CUkO7nrv8j+>C$dH2L99gp;~*;_YmcX|15d#_0WW?z5e?kg*_4DfG)pPgt!$2E$^5cyy9AEaMb7Lnu#7oEfjrcO> zI_BIshAz*>n-2QnjdR9y&=0#f-a$X?ibDE9S2v^|bWKD0!A-@m9yY)x*ysBFF|-Y3 zN<~KtJM`DBi}rwTTMXiNOUD1UgsVNjZzcVn_SdZ4ZP+o1J#piFRqXTX;o0xir<3?v z;&)#kYbcwY{Cswpqd9*5Y62bN<@(ul^pgJ&`S(Nd=b&-EMtleT;%jw~e(|*)NWb{n z7|a-_I{@hy-LIkalNIb#5+#m5_RTr5bj^S~v_F;4J5R_4ewk^=B@2ZV3^;`}*68 zvDwM*JFd%ZJCL9H-LdO%>37=SZ)sq^d|BIes>o{d75d99?buC!xdlIcg?@1h_J5_v zIJcI-By5HQFbRj@3>-C155I*d_di3DpM;RzZolDuivjW@_#W<*t&(}>;ci!Z?KIH% zGTO3F%W$~d>v4%bB>?QmTk#BbL%8s`q$;ksr> zJ6uP-@92Zre+T{XI_&P{JtEr<($*5nTzFgg%$#|X@jcRJkN6%TUug$R=AB2x_MGwZ zaAwcj;krJ`k79>se+o@`*?M^Pd-d6UJut+Eo&39FzqkE7L|V^(LzFvCxoP8UE`Z}O z0;eGLzHSDNzBz=Zk_zuNFp>kRJWzd^eYe1jp`Dp_X?mb=>P$KN1+ zPv`CH)b8txv4ehjooByiw^xtd+m8V@?BusQ=Qv)!Zf$3mN~n@K;}x&D)r}mAN>a`cHCz^~9t2SDslvRtM>mj}1Y-^Lkh}6o0iX zKZ72u-Sso*D@u5eH?{w~-*`P^uCF8O6LURduTOlnr@rKTd0&vQ*PjjV;pgP7F?)HF ze>R-N!_3_W`ul*_cQRJGm){4xz89V3eY;}UKi4zXxyQ=B?{~e7E#^V*eZT9+&=csm zrk_G*(0!_B(ewJgo*eV$x<$q*b6ID=ICq!AB3KVgVTbW=8iSN&LsFTGcN*UlgB;+V z{hJcc-1cNSCA1NO~$z=jsJG9OnUKU z4Qzn*khxLvkvWdzdwY&^?wO~Yik$Csa=pPW?=x>S%w7-qxh;v0OAgq%E&E+cc}COO z&UbHQ9>E`-ab6w9xmV}5P8k!u%b&gO#BV&$$vu#HJ#2$?|6)Higj4VVf$kkuo<`L+Y@p7A7I%Sy**whMZVGJ_PH&M6bn7dwnOzJ4%JubZMrf&9_GryIwM||IIfvo>5d9M6zu{Gy@ z<6HH6zFyAS-D{lWBKGtf=RT>AR}asAuRepsGf!tzjQv(q~Iz9Eh>@9DM0 zxo?vFP>x<;zbvcGrb**$DW*KGQ}Vvjra4F(ZlbNWq>Q;C0Oujsr29GVhEf=X<*;A< zTSa~nj&|W~Z;<1xw?`uOh;L*9;!jKNt4F3>?cI-jd+=rWSM9z5f8IZdJ@~P|D5oB3 zzgM3d@OM9U+<;&E+u-i&Wp1E9^(V2<4LkYyY#9f;@pHe_b=l9(eG6#XU)#mp5GQ|* z-Oy>A2P$C?Y=KGG3kTo~95&8_lyk!NlGj6hun^+=8%y94EHh531~QMNVvzol8iMqf)S})`<7XSnl!_Z0*ujtA zakcL|ZS3GTOP)u3hx~H=_%!i*?8hDL_U!fSZ!*qS>i!4pcP)DfKW=RzD#wpo(ozWTHG%D^i0&o`<|g4 z#7~y^>6s~4dwxn2zsG*s!EVpqto;$}OZ-9mtzm3-^3%hNpO`O$A5DS|Dq z7PdqBQC9+rf4YqG4NmRqg*C7rcB`LAZ^JJ9^lYb%^*y@?@slNfdQJ|bJwH7|{GR%0 zC%Zj+J^Kf-Z|o1+Zw+I!lb@ukZ|A49aR%uRUE?qcr(iFffl|)AaULy(OR&zEn+hQP zi}!GxN2kA=2O%OZ+ri?rP6Z&k?`Je)afW`FDMu@*N|-w7^ns!~?N2=yL^JpcPEA@|1LmA-qH@r}ti&-typ z(c0zjAB;wKeQ(@e$8W$b?LW``Ho)unkIl9A;prasIL#_CW0aY7%zC0f_xy9fp$ssByj(ffF!>KPg|H6;NOMtN{OP z_gnt>=~ekHfBd-H-}uAt_A|7!L*PZ~N4t2>5WMe)XP;$sjvEO(e&*K8f7$*yO-FwF zDCD0-B=K~~f%`1t7h`Vy_ttL%ev3K8bn()Ag>Nme&-nH9xADE{$U= z%F(^(;v9{ye23;}Z1cT!SwB;Xep`;NMVI907@9O*dC&B-D{C?>|Cv#Cm+w`bXJ*iH zudeaWiv6J+U4=d(M~nSO=I9>uyK}Vorz}TH{^iU1Ieg=*$kCN(US9dnMcJjytd{)o zVOCGDTfMADi_wuBO`NYLM~l7qNYCHXb%{dm8Lv%FTR)ACwf%5&a*6!L2m@pVal zZL+u4CVwUKY!@$``~RwueVNld9cQ2UH>;EE%bck3?`AGDo0qk{m+i~Z^Xw;=^>>-8 zbJr^04Wni5)cn5N#Qs2zPOv|i)%JgEzANb^$Q-<5_^9zs7IKjPvH95u{G##wdbpGrFZSLvr!uoFtU9*D0Rl5iXjn82i@8-|kKC~ScfP|BT#({R=VekS%U zz*=KYW$yb~8!UvRJGBI6V3`U0ya-l8>cPEs;OFFbYAx)B4R9Dn;S6l$|7*%%Y~TKm zO*i+)-<_aaaeq7(fZQLCMIiUbV{yp+@mLyifBZfC!{i*qig3zZehIwkcZ?CQVtY-E0u_rQMOf&Bm8Ft^KEq>;I~k!!^-8dR5~nS*~3 zQ(cX&LHDVyM{~{ao-;IZZ6M_T_eTA9M!V~ee*7r@-B14aMvQX4H)L&-&#c+d-K$JO z-fNwfHfQxR&GnWwj7vU4FzuyFk;fF*tRdt4bummsu5B8ezn1yGgqN;={yNEiX^u{_ zAIi}g_PK_8>A%lz?)&#B=lc>b;W!uGwtI%X0^|ETw=TZFYei$Te4yJpKJR;b- z2uX8u08$^mx8Zz$9P<46`-_n0-{X{ZGuQWV>U1;L_i@dGoSpH0wmEehXAQvjhO@Sh zlZScxvi?Dc{pGs5_daq=ee;7F_9-u`TiBOA#xiBtITTW2c7I!<>(>y z!&%Laaego@AT+zUxlI{^d?x4brA$iv`+2t9_gfxheE-mEkDHqlRHH~JmZ}|Z?$Yzl#$j3+D*bOi!N^! z9AkVLv61_Yf1HCS8{aQxAom-;Y=wmU{l>n%-@xVee!;RyS|ESFV7-vv09lTOHb?k7W#_1sTbN8HMK z?x#ht4zgCcm1kx@r7XTv?8vjlTX|;o(=ix_3vOO7W9xpu9~*9^Y=Sdc##VF>uRc9i zYw51d*}XO8>RSgPpWFSFtbbS&|4P!c4zlF))&HA3B-}bozRhqHlIGS4C^obHnp|?z z9DrNrXBE_1d_Bi&!8kvwbG5jwrvTlmx)@FW_*s|ga&#qnKy@{`20gC29!)>_*_>*8 zPjKW}v6R=-rn*XXTy>-BPStW;(!1^G{5+{zDEZNbHeT!y?Ugs|>c8>I8zql%GfTOX8kDM;D3 z4H@T!2u#Bmq@FJf!YMcdXN>bAw%#@m8{iV`H|BQQSDp>uUTmD{G8lqQumbkNFr0+6 z>)#c@dRPaWUSBWVH);8?7AaqoPVmM;8zx$f5JxTTX*35JBG=tTlFY<-1ru;^Ph;b;ibyqUjE-| zh~=5izs*73+y6fS$nkmXm#{Kn0uR>1E*OWsupjnAe6n)T1Rmm?l_M|=$6za*gpw`; zC*Yh3q$J%U#Fi5S5c^Lof=S4;#nd<~hf9$6KekG`2$Xbnun+P~aVz=VF=Lz=^1EY- zI!;<<|L<#?wcL2xRrzhM2eR+6pGaGs*lq&bB1F@dPE7FXL`PNkp!?9Yy^T+yY4dGK z)g$OpG;L?&X`2(L&~vJ1(6s&63so-~Q^ysQ?=9H$bsVoNMsrZkuM6>_4}85%brrfA zP21b}T68^nRCN=&8BIAhp7ZKrCNMzXu(|_H-yJAd-HT45wLI@R+JMxrl$SnN8<6rs zIeLWsvK*aZU-ER*+p#tiMoXx4vE7#6H2J@S9ATdR_j<@!`}Zhhto=s}68878hKb&o z3g{TKcIP+Sc_2Tw_Qu$1QXjw6*kTO*nt4R7W4|7PjICdfLyrGO<^{t3KDO>)?J<+! zI<~me81u%QR3jg@_dtHEy}Dyfyz9)!bxMMcwcY|(_7*{|V~cXV;yU)*63AHlty~8g zYyTO6g#CT2VWKyt^4BrjVlTPLkF8gCY`JU13H7x%wq(ue1;)_txR;T!wG@Ypt)(u= z@&D>~6YZ~KYbEy(^4<8AEhg|l#@d=6V{Vh}Zkr!tukIKVUpq7N>hj#N<+TFOZhs%P z!uR_|$Y((;+53IeO~h{_I=|#v*UR&hUq&F$d4AardCv38l$%Dk&M&8Q@1@F;Jl%2Y zlF!Ik%{uk>a?p>X_BCasJtjGyb%DthYni1^M4( z6S3NF8sWicVF4Vo#|^*9==^gxWhCJg95BxR(s|2Gu}`+n|7xL}63QRpHHrgvYegVCN9(T3;#v{R*l`ZKv7t0R1N_9viI?k4Oy|;Id4GIV$yEU8D z51YeQ`+ee5W^T(jC>=OskMFHb_Bo3DZsq1$ep6_QqNHy1ym%gY_M+-2x@Gw{hvfGy zH^->!v>UH=_4Az}=U1*@vUMdzZt(kKR=T9FR#R91L~gQIeSh!NHLP}qUeaFwie`J< zC3Ur$x~`xv?!~Zo>gv{Im+cy$&k+2U)YX!@22y*mra8|7U!^`Q#yY=}IYL6M3;z4c zhRuC|@1;4_R{9;$%zc)xGyY(qJ#IGllLz(Q%zFsGnu5HC@V^-so5x@yoP^}LIRokU zn|Tl6UpRL&_woNipSm*u@%Np)hwv|?yOZ}2{)IksXE~g8%h-ooXRegeN+=)O2+o|; zUv!P?sA{(lICJ7ZiErZ7O!`69ZD{6=IqGcVJJ4O|1=YRiB>R-{ubgi~l~Qr%06TBQ z*J*pe|GIKWKeObz^g7oDbLS9wVCS7_DCLgBK{y2|@6H+H{96T_hhisl{l9e?b5{Wz zfyIz?cZH1ee<uePHgQugvqinFrB_=4lffLdsmQ?kJeH2mG%u zg~i6@K~T=)|DWI9(@I>|SKX07snrEQWh3I|{k4nv6_HO{|>-~=RoKM&da zg1cOwIRBo+VyWLOFZ%nxOTQ7l#Mk5l=s8#S6`@Ov^B={k%OE}LKf)-V0n)CP zwCfurKBrv|qJ6!5^X-bC{|N2c*GGFwA4$O$+iuQ6(lYy57*(ckn7u=czfjtdb;BEF z4&(dZmZGcCwC_9ULvp;ZihR@LI|`Z07Z%}^aegi3%|PjE^zC1#AanVz=lJ<>=JMZ= z@7>JhziH<94))z0;&>nN%h;Ei)&4g!9{3!FOR0a_9yfO<$vfljzk+S{zUS@%>>M)AZ;Q#L zg#9$HF`J|FTk)|3d@JGZN#!(rlkp$y+U`FXAMv>*m)L&rh^E8uzs0Y23R@0}F3nuuwB3IuB?xU?L$7*gJr5FCfJ+Z#D=OBmL`8c4od>fs1%f{SK% zA$TzMNbnWA+-}RuiWL9v~mp6&c*nW;4hYR%%_%I zD~dbqakFKDeA(YJ4as-QEX=rZyV+*H1G;4)n<`l3`L#5AYiHu6@oALRe5j-Ldoj1U98r(^v2BL1$Da(Tu^j zAZ_{~^a#34^%#0WB01*yX@~Z@U)t%N#{X9GCiveLXG>qQ#Ak2ovB%B*jN!N7-}@QE zZ|Q|gki7dD!-o_=#_%EZ+5QkDkABARA=uN;7(QeUGKPz>tDiAk+yt9oA8disu-ya? z4MFOAsKj?c%IWWgld#_e-&za@VLhatZ|#I*FbyZ+63m$3+rn@Tw!=j@Xv_lvh#e0U znP5pdEQKww9QMO1I0GXlco=rB&LLP*q|YJSX}q2yhAP@pdJMO+h%jfSjg%{ zd;Fy~!NUe}4*PQU_k1^aSSBa&E6n5Vg|9*$xqf-2c8K4-@JjRO_A-F4G>?&2ArH4d zxEZ}dJKjeBTp*ufajhF9v-Og4vC+&@YKuR zz3ff!aIv?9eCK&F-yUA)>IVZhFXso?BJmGW)`MIp4sTN(vhn6Y=HSDz??L9^!_$yC z`0zPcXM*n}&4Z0F3Y%eg8Rg7j1 zK0vP5H~=#+1LsWe zJ^1jUMOe$vUKBi=521#?9zPQLgo)oFr9mBJoaXY&jmm2mS8RJcsh77|kUknhy_Ln7#b zA?%g0Ye_#0b)p&5USE7yFXwpW43U2dO`khz4vw2(c_rMT{L~c3qa2@seQ+L5knjI2 z1dlEx1AM#{Y%MUsqpMZZ54O_Yo{zVdxdm;d4<8*Rjy`%c{@+>yM{Qj2=p{FeJR^~? zwL#egc?Nex$ZG!)jgYmurHohgk2h{Z!<Y)OaU6fWZ_MWZ zayG&DOKPcqFRx@yeQ6U7!S`!@tbPT3it~c+uhHCETyCX~61Jw<&_|A>%?bV^YuUb4 z$@{!VF52T}>lk^olAba9{y~^A!3sC(PiY&-L@-zUJ;!Uo1TrDj^qp-1>QwFOZAIu3 zbh~P|4T2R()%a^$nDa+fN6@vTPphWyZEHePj+D0zzi*=teSm$dAkIOX^t~Ck7~B@{-atU zZD}dTJM3|@jXCoe8Ivy^g2#As%~Uo)@E9HArZjtOd53G&QEpoQQL`MbL<^5K{-gE0 zZ8MbF#azPm`Iw32Q}cU&6b}TCEudWH^RK(b2al~%U1$#kkCi?o@w^DZW4R7kU8Z_e zHP;(L@YqGw(s$666{>4hH>u|OLkL#V7i@k}k?1sADX&!|dQNrB)gP38C-EJs>r{(f zr2n9#llVT>GM|Y~sh(Bs&U3*J5ohDmZv2P5{Ki!$pqxLYdO-DzYB?_P^RE7Iq3R{o zVOI}`pRw=5Evk!Ei=CW55K=v z$ho{vYRTvBJ|KA$9ER-Ho@ZxRg>;v?&FRVzsvbkyfWxU)wKP?3urCx5e`36fR^?k z{UgP^O3`DgY1>CC*{8jabNkIs*ThGvi7hw&V`4U)|JY&p0pl`c{2vV2iCT!NWR~oo}cW6(=Y;O zVFE6|Vfz!`!9Smag(moE@)<0FQIik*#sk4m_fk*^ey8sfvY$B_th74&p6g(kH1w5E zr#UX^>uh}X+0kHwt3N%X@ljXT6sd0IoOTnek?|wvCwS49YMNB{K!c8}PKx9=4d@d# zeTwvqg_=IqBNB~Hvz7elvxHzxhOKD&I3f6%Le&|L(f2+RR=t2;Lbtg3(E?*0WvqOr zQ*|l23_YOQ^+)hC8P(O0{6DMpd$d-ykn$gGP#sqtRXwB{e-MJ7ol+fhwf7w8(FA$m zpU*C7e2*Ldxsd9l>KfHzC;5G@MfI?1uRf#XH%@#?<0<#ijHVg0G$!Km(K#hPlJ)x4% zaczgki_z~f{*Q{LzkW>n!pCT5g8yR;mgezN+B##*tA>(poH|&9Fn1tBLql?k3!4kNG$*1=xb2+8l8%_ewy zF>HekFb=z5CzO18Ot6vizL|vdqi+ttHaHBEa1>IPZ%&xt838yA!;rQ;qXp8oXY`Q4 zu0!yQagD6nKGBopCu8}zj6Lo@ZWi*sttHo<6IjQ!1_vQN4 zX{G+Q4)|zz(iRjvGp+?v*PQ}m>5~igsQ=HT|9#oGY%=~&&AF+EGt|3}{N`ZBJ(l0* zJ@6X$K=3RXFET$Y*_sB=Vr~=tmj$Y2Op7j7%^0ydq*~@FiLY>VR3JL6S}0obWuA|= zsIFJttGY?`m}*HU=@(VEyZUS?NAgRkj;iib-J@Fa<@~d~{Q6aU`3<`I9525S)nbR_ zFXwUoIg+pFN!4l98PyA_=UjbmxoRng^Uu}%z9sXHXwC0iMXIG-^8Z$;>Uq_Y59yoB zR9C5PR2@;>t-4P2sA@?k=ZhVZf3vI4t5Dshx?4ZRi z(F3Zz{DxI~`H5YU-pfyjz97I>&YxE8wjDu;(JrKJk-i zDM#{4sqR!gq=h#a5Bd)$Iq1)-5CFjF+{Wea`(}DgmW#QPnBct*R$g$5e}tBz=d~vI(vZ>3+oJQ{Bp5 z$bDq3+fM#k@e|J|E%}`739kRlQ%UlucF)-h+w3#Irv_~9*=K-H4XKVosgrAG_8H() zVz1Osd?E1@s=HKAtCoBuepa;{7ro%>H33&YZKVmWsdP2I5&uXCu4%S(H}0{V1ADX^ zT%&&XK5O!Hv3uUrr4YZbtg+f}?~CbEmaMZ^PHMU`>=-oW=}Jf)o~|~*_5xT7t6>9d zhf#M``x@>!8UvU{WN{@=|TSMs-9f%>(j%$(l*E7 z+9}N$`y@O)u9P~x+4xTkL;Bi@Y4{G~uPcIwLbt69&&UIJ_43m(wUBdb8%&_D5Jn++ z*0w_GQX7NAu)_rICX3o`DDgZexH}GcHq7_7P3;hzhiMbIryP#MR>-s9d-~uE%)ogQ zxL4wrU<(;?2U#)V@`y^yz`aT3m~zf#QtH5+r+iPVZX^%H?W1avKpVB&_=xUKZ&P}PN40!OsMYG^oy!#8$#gz5L-!~5{afiTTRuPi0LjCifj z%1Vw?e!rAM`75hk{Xl{0TGdsq*10C|Kom`0xpU82%Co@+G1&ecx30l;ld6~P2(DYy zvq`s8z=o6D|LM31U& zQaz)(#nmxw=kK(uuF&{|YN@N_*QHw0iSAY1r&{_G<;Bu$CEoR0FgB}t1QNeN+DPKZ zR9C5%Hj{X^!41p%-gPh=xraN!jg(=7$J`U?yC;Y30sqP3 zSNew~{X^b!k&rGh!HuLz7sDtF!A={sKWu^<#sAbTU1`k;ZWMotu6Fh1rK)RHOFbpN zL3M}fsA@02R@F-yA9HnF@|E-DJlZI({U$B#DSCjd#P_Mzewj|W`ifGGA5txLN&2*E zFTZisa-PIbsh(CX`MM!^WwGv&Zl~}T<3B~pnC2v)!b7>1p&29Cgb6HFAsCP;mrX@U6XnRYk?6A*i!;W_Ws zWsv8*S4%lOm%UofAB0PA#00OYc5T`Zw!v%Kv7!XK+_nhJ)To}c)@A?K?3rn+gV!WA zepdCU>IL$^x7WyV@_V+xjlUM3SzW9e-&q|Z4fFD~TK=r^kQZgh1= zNOiMnwg1^Rt7Q}H@b0;jb?!lnJj`CJ0B#{FChj=&6M^ikdn33x~F1b6)H zxJI;*`*@SRhg_X8W;LH_*cQP8e6o6;*P?Oi$6YP=J!|;wn|i4)@oVH2;xiB0PHW0J zj)!KNHNMhn=Va2^^wm~pfAe6CoQE$?j&h_RF%`Ia%68 z%J$Be^c7j{%P{`GBKb=gb+O&{gT{Zlw8s&~e}<$x+4%n=1S7`Zl!Am)_-x0Ii;Zbu zP50w!SOnW)DIA35a0*tLz)wiu5P{gxPzUixLnEY&hGsYcSEA6$ef6PUujQ-@#^Ov5fX4kg_b zT!1qs@V6m259{F)>@eoE0yx4LnJ~fY%HaTQ7J>>W$1z0X^%_(;G#zTj4R!G1g6JS&ssXQ?UpNg+;mptH+c{I5j~LooaOOQoI;MIMJ&fkK&7X2kXRi9kwCX8z2JMwMhh}d5MWGwt z2pXBQeo>{m7+s3i@*2z0m1r%mu^L^2*76$b(T(UaJ--<;H~nHkbsO<9K7UxMx&z(C zwK=Z32i-?}M0E;1h?aax*dO6FipCFCPoSsJ1FET4;~bjfHh$5VGbn$H*6)l0bP@4t z&lzF|@iS`A8Rf)NKkwRqMzzLk`DfIs#%{^~HS*uNj{STg^^x%G^zz#1S^W9z96Ck> z@z3J7XZbxwZ|(D3z@8GkPW|&-k=4#g^eajKoV-GuFUMsc|2|iVu2daHN6-zb@$Yl> zeEwA1>$ygBl+PZIYJ3a2%{ZqeRL9T>bie9ObhmNpx>Wa~lgpo7elCTkKY9NZ_}nl$ z&G}=R9zI9kd2Wj9b&v6%$94KTv<>vl-0<8iir-f}TMlxses%`3ZayapkAYK=HTq%Q zE~Avat2Oi}Yq`#lF_%mk=hK{b$&7JoO5i-Kh4{RtgYygE5ac&7YbgKHka0f4d6!ne zMi_>acWDhAgZ0MwEWW(73D!V9U-sD;*u&% zy1ty{CHJD&(?;qSGs->b^$Cu1PkMbCa!-2wyghGM_W-+EpJdk;(-lTSV7g8jSEiKI zhY*;awG4JrUqZ06T`7M4L~H_d2c>iO8x*Oe#u2oIGque8GYE?aqW`4S`UiBE7 zdx=e)C-#g^^O`|pr`7Z5Mf8NLpQqgC3(rT4&ZVjSXYRw=eKm)hTbgq)#7QA6nKyb&myU+G{x%RSVxsZ8=;J;Aj5q{&zlF#E_UI_&P=S_ zIOmW)Rt0Ne1d>;*4i3Ubn1Rj4IhVEEdBc=3XY(?~^Oefylk9xh_%AMk{B}w!bC=9_ zmo&l?;RNJ4>f0$#e0fpK_&cON9J?sNKD&lzxEJ-Z-r`#GQqNR3^ckmRVE>sDV_Y-O zZNopEFbR9$6igbYxfl+>ddRi1xeJa$`cQ1bIOhf6G>ky69cIxn^a8|R8<=y?C*6iZ zNT1xmHR1erSO)RKhDtaCtBrF(2-ZT{aYF-?bWzw3TOsYWA%_17$$wYv?Y48a-8XcQ zzJ~Ky3$%z`)OQ!pvS00WY(Ssi?f4ul@L~o1g!S%=t(Hzp#&X3c-7(;O?!vL3BeYTb ze3QSHB=LF40edaUe)eg@AY+HIe_^@nj}4=?FJ{-R8)S@65#OfqGM4AiJ*pRt*~lDl z;jpVWGIlo>qo-Ae(99j)eg4KubeQ-hjc4p`tmC;(sp{)pX#6JUUtZ0t20gF39^Gi1i;1)G)bDcYcQNU#j-eCi zsA|f&ya(N(I*Cr9Q>us1Bj|C}V`%Dgu~*(Sdd4`d>YvLwe)%F=%ZmrNEht1|hm;?e zS7`Y;Oq}|}sn6#-H9m}vptZj7T68_% zyx2x~9^aYMjekuA2_qmGC&D(Yxd z+~OAhd-)aJ==%RY&sux0ea@US30}y|p z2_GOB6Qci__l~_>$2XuKns;gi=lBLqt8)7WbsdZm!Qas`Ry2old=c`ULw&sn*~~%j zr9**5z;a+IFa@OimbL-Wb18b9GtDcwxF4_vSPV=7(fgc*z$L&Xz;@trAbOs&(kr-R zBybIII*{^u$x`4ZAb1%%bGpu<<2hToZx{D>dj;>M+|1bpME-O30vC8*vL6uLCI?B7LujYCQa0Rdo2w%wxui$-!z^Op^r%n{SF9oFRy^pe$r0l(~3kY5R zJQ%nPSO#nZHUd`zR|3}o1#g2_@c#b5PN3jz2MT>VfkNLN;BLx;=M|JeUtJ*(`P2;s zLRZ}gAoV28S>!BUk-m9 z1rsVQgg=g84l@5Mr6#_-L}9^%Wfrcr5P5PGur5~NRlY*!vmpee?=Mpl0K4vO{}P~@o~h< zozK!ZnK(AQVy#WDCXQ{a*ly#k#24bj^t16L#Fr7b{4}-^UqyVHO(&nm^~4w3_$K0= z#Nk`%A>YOw#5-+#H}Sn*!8JrB{RW#^!%RDd}az*Vyz5 z;+4cL{WnY}Uc=aUf192nzJPd%jg!v}*!)SB{u@>h7uhrZvcxsCD`7i)Ap?!?B+eYz5_s15KF{0OkGSv${>H(C zp~Uyt_z2?6fqj0MjU)SwWyH&Eoabz;#jZf!a?%yj>(iiei{8th~hhJFCzr+h|e6@{pjU)aAk)Nca4~>hgBwlRdO9fBj z;|S$meCY%mpG4I8-e41f;Rz3ew!FOUM6_cf#kO-353T@ zt-vZPS1O^ zzZd@x@_Td$umtD>q3_WmAb5|K0=ELoz4-F}z{x1fM^I?(rRL=cKyp{72kvKZ>Mn>Z8oSzek@8JABF8ZboTIZxDH~s1YvcPo zZ*xE5+f95kbZwS7=rSAki8BZNeW8{6H$&rQ=AgT$+jtpq%J$d#5g$h|^u@m>ya@hO z!gTx~pLiL;r1!g9&dbAixc+!^4fu`ZH;uFjVS4;)i#V@{#Mf{>IgFb*?n)P*JeYG9 z%m(t(IqeTc;zHl`VLbjd;U8K9`d1WkF7zY!&6InN_=-}6=1=%I@FTuLo)H`eo5zA6 z1K>gAF?Y3B@R1>&H+LN{1>6Aa0^*PT8+^~*4lD!WU;dkOn6A&B z6a~I zd?ZNX_qHoE{S|vEU~@Zv?ALMIUWs{m+V5vgxI%2+(lvVB+q{W9y20P-#qWgQ&E3EW zz+FJ(uz4>K+{fsL+_?)l*o%MN2Mz;P0!IRu0!x5hz%noX4d{KW0$2f@3S0=R2CfCt zfB1&vv%rhD4FfI)3f?kcE3gf?8n_w=U5~Bv;@_lksl7AJT#aqzr78g0b0a&xE-J2)UEb>o$EW@zRCF#w|C|CC2m5N%{=dD=||mE z4L#@~Q_el~VD)oTBlr`Lb1pp?`8$1({}J**j`ge1WAix5CVtqCPW~lcuJObDPWZ9+ zG^o=e@1_k|-_rOxZBl5)I_;@| z4)PRx_#f4JG4DU%!5czcAm6cCZtnLw_K^p+_3{2*d?m7Yd*8Sh@%rFk69 zf8qG*V$g*Gm{P9rY&NqP+df9TuOZF~Vx@R!>7VjEv; zpRf*gyh{xe5)7#?qK4Bfn~s9 zz*gW$AkTQB#EY-$2P^|hI{xCS6cB%L6?AjNSM4(Jd*qYj2=^AWycyjL1KW;ecQ54J z596WipGfkolo$VA327r-`uC=DJ~9#)9Td5^%DOlbmo&-4JkNV#F?p^b?`6Opz&0;_ zH{WhZ;K$xQ0X#XD7?AeQyx3Q{Pu|!38gdeU<7<0?BfPv7jX>7t1!J;bC7)d5ut(ci z#1r^>ch?|?>~ir)KT_@gv9X7t$J+a*GTPq>tQ}cNokAW>l|WjrNgHf@I@fB5@3Qd} z@ddnBIoQUr2Z!Rl%)6JH{GMp1Zfv5Cthe#4#Idb+V>^VtCw3Bcd-3lV+W0=td$J#) zkZYyDp+M@_lOur4)rg(>zVIT)G6T~7u`}NwU$Haa=muhE+NJ}~0(Jo-cINBYqc@A4 zd6M?z``tO^;*oyL&hWnT-DT(){r`jPHFd0C(Q5TcozM3E_iAf5o-C(s;A5>GY4D$% zN_;wTu1k4%GD*N6T0Pyy7ZRt<4(!sCONlQheSuA1NqjY7E!WzB?Z7TzhZn!czNdK4 z1aRe8VnEtIcId7)u7JA|`z3a0 zhhFJ7OlbqI2a-YaCa<6pl;*9#Vj$zgm3-?cfj{&E^3=oHq0R{=+Bq5cZZB^YdCH#V z-x~qM4t=i!h(C0<*hX0oBalAuch|V_-0yD6ZIeUP;!MI;)x)#51@3|CpF2%gahZY+7q!tigJ+(#?@`LHf|(&%dy0O;JiO} z2QcDmtzMbit{rV-OE)rZUEi8hE}oah;lfLl}mID_8@l86H0CxlF6aR1+ zu;z%_n&91HBgiBBf6TVDA#m!-Th+%2#-Tg$6FOH@_A87$I@b|r4CseR8^^Ec#Mek| zz>lGxq&mF<_8az6jDK7YPHHC*S*G>?_jz6mzW!9(U;E)w@{nV-0l|M~H)o6w{kT7n zbvX|d1FdgTXjzxj(&`m_xB|K1M}Bw#a4B#Na0PHX5dZOC3xR8a@ZHi5#Ew}x_mF?67pte1 z4)C#ef&N;$h;QQl9l*Uno_~aVtH9p5@hr*@M`qtpFCO8)WA?BOi4T3t+QZPdnoC`q zJH+``bB7Th;e4yPMZ`;-Z#9=XIk(*TR&y(eR}ybG@|-&jNE!dY4jZo~J<0q{hmEHs znLc9~|Hyyt0s^*R;$j`D`!m=ly}$(O~`KPj}|Fn@3xp@zzH8Ulhv0yLAEab;P-Tr0m%k(NXkW zh@{4k*)z)X2g{HJ<(cv&;ZT2@=Gc5;tC8>i)*;?X8NC&sB3Orb>vH04*dyDQymb}v zHN;Czez&e8-cEd)jc+2}Nqm8gcMwz{=h=uIN(qq z_2MbkHLPJ>!;gx9{Q`-bdNL5q;ZCTj+eh z3Un#9)7VUn9O1uXK3^LWr(7ND15=0g-v? z5mu2d_DbT|ucy`%57M!JPl-((V$-{bi%l)HajEmWiBGffy`HzlBfh}IxAZ4Im^d~- z^4}uC=N#L6FZM$Z-+(Pb1ILyU{@7ppkur$^1+Tw_%!xj-Mz4EYusQcG0Uw(qV|`n& zIrnY_Vw>&*Wec|FKJwgx?YU3rdwoazKAxpKEGEyTv!lNA325dpTa%|bopWM4cqj?*50a<^qkZ*VYYKdO=w(NlZ4s(7K z|Hs$vg*xQ5We;JW7r%dqi9b#GeR?qQVjD*nPvallZ{_|p*PkvWp0era?db~E8i-8E z?`iO!o<{mI8?PbW$l8K78*e4Pko2`Sj@+JJMqK2}{Z_Ae8{53NjzMwBlV@=}z0$(f zKS*gKiYLz@HvqoI^8-%rI;u0pFXhOO4Qb`t-gtGMeZ`LxS8_Ak+(U?Kkq^) zWR7FAloyVz#pKZq9OuQ?4F+Nh*OdXWh3hCMTc-op3FaX=!g6fOr76cgd7HkIDaS&4 z5Qm27K1NzEN?rO-q>PtE;^R1<5Q$ShJt@C7zo4FOT>x*3y!cOANt^1@gL=DlDe1Ix zLA~ADMx1sosJC0!5MPIEc5(0Y@P1CnbD02+>H44khfW^r(o1&<_J!k}Rz0?E zAdhwA-wE6a-0sDHIt+MBCw_@3Sj_}{H{!$wfr|!H(`%B?^ zgl85~Hx_&GpZ7EJcxD;#6~v2dT~7~#c#VW0nOG4WC_9OHVnjQ9l7M_T+!;?(J1 zRM>b8@kZt|7ut9$@rCrKhS>OG;!BB_+W2zfZN#V9_$uOSh%d15b;R3=TmGKiM7-0C z&Hthi966R5@a%RAg%`foKNFR0&o1a*3!iEa~nM4f(iC6GG3trCbIwQW6+I^9(Q1~D7>0O=&JXWVE^UdhD8Cgu;gAye!!S}*%IX90~_4eCQZPRI&IKq8oo5yMV*q$AQ z$N||kl@TVq;qUNjo&Ke-y79c_25uW>;Rqmg`uSEMdkwxII;Kv)um(t--fndM=Bd;4 zeSTR^oh~|Jbvn*Gog8tQqf@wAVel@9Mvm~`v39%-iBkvPqJ0@t=R0kw3+ns?6W=x& zNS%Kv38c=yEVh6;|ME)U>0Vy9wGD5Yc6=&zk2Y)D)MIsC+nsLOon!CNztz5>9`^UQ z;h$|wn*MpaZNG!}t+tuA%G0)FHSO59 zZHteX4G6|CGvDo0xgFuZW9@w#5`XKq_u<&!wq?|T6}Il%y6!D9rE%LT3)cXt`@fa; zpML!BZ2SK^!NceO-9Cf&rm6eP$+a(s?{!D4?i&Fe+5cm8ybXcBb?dnL^zEB$p<80$ zHXGk2zCLyO_hmrZ^WX0V(w_f8+IQOXKkNi@ylLummltn`=51X^tWFkE{6X}i2W_1k+x8mRC4jpB$8kXF{vUS%sr!GD_MLZ`|3n^gyjkjg zSAQ@5V43FukJPyQv2_TPtz&insHpp)FW)tUIxx%&Z9&%v;*4tt^ZGL1)-}%BhE}cO zUhplUt_ddIH5rI)`0uGeY{UQb2VxukXE6}JfMGK|a@mHiYU<*qqi5|?7h`=7E{E?U zH`aH|FF0l!j+VK+_=D0nM;~1&!U8XE&^Ryt5OzTi3%jIl2S?1y`*Wp6^8P#x$Ty@F z@}AkBml>oxS^KlM+ngW7f5Go+xC@%@TuoT(75sIGjkgo$dm>7sp~387PI8xhHm5Au zgqFQ}miHF{(5Mg^|5B>gy~9kSJS6_mBJ(U=JIrZUn~8U=0t!tlfI`z&AZz6RvIEFF zCws;3;^<;c*h6i=^+0T9*CyZ|AZx)M9tP|NmIGN!^f3LhuD!tJdTadQ^%iz3JRE-o zyM)f6p7&g#W*^@mK;ja7FTP=fjThN;Xw~#m8?Ux;u0K}+{vsQns_F6<-ypJ*V}b$C z$vwe=p0%8@{(0|CE+Wgn7HeYOU&{>Ab4l{((DV2s{VlZgJR)rw&(L>!1e!7we`KA# z-eus%ein{U82!_-xY5$4-+|9pSJ=4abEC*-D0CZo;v4tcc&FmaU;I}A@4mVA+;#)?pZB5uw?@zM{&yj;A8~>3 z{=aQNj^}oeM+I;gUDFgpY9g(xY z_2VCTD}<)MjnnJi^UUdQBCqF5ftBXkLHx%zE#)rc_Po)5T;Fw(xXCjdUweL<<{sbF zY4MG$fhRd_*?r%0{K40zAhl|+5Ei}$npFlFaD@Jb14uy zo?iiM1+D_F0eG5410P4OqU+MBO6aC^Ch6$h^i?e^RIV|q>sV2I8IAq3H3mCfm4^UHqy3HmiWvH734&9q^rAzI~@BKem(j+ldPt?B(Yz zwRr7b{3-6;j=g+pIuLvL6#Cqby?hDAhG4oCc(=d78XmEC+4?PWIxw)9Af84Oj+5Hd`Bk$Yv{iyohYJqRSVN4e#Z6FD?fn zvlmwaC7(4wNnh{9S=;ZuxCvMT+zMO|?Dpc@VCBVKz!Fa097lW`Jcw>z+@}PGx_+sj zi3e@&ONAN_+t`-4PV}d4*Y+tJM;$3o| z;7_;dT-SKg##1)lYU6D-zR1QqY#beN#GjLY$xrB#c(IMIvhhkAU#sza5B)v2K+nzh zm^gi@-Npq_cJsGtJip&cAZ1q}Ww$_R<=EbStn3;|9MS({Wmn3sDd(>2N__|p%5L1$ zi~QrJbCI&E@FXw4ztlsHf0VNOlE|W6S$Z@4z17QZ{JFiTN$m6vRhQaf`ibU{Hi6@% z-3IDEWqH6fJ@kh1$WTgLxU{NH0f1Nwcl`3#$E zSq<#2Z{jaY{5&szh_SEvZ(mECva9fIUj8Y@5B`Vo8M=pf@t3!I-pj?*=Uu>YUi<}Q z@$v*3^*OQ0hsjSpnEU30w(|$0T%(60@ndo0QUk{dGQy=0oMYt11~d9^I{jU z!;8Np`7_4&QZ{X)Op%M~~D+q z#eY2%xEEOAd9U;XE&>h)@|;(O0e1jLdhs35@=6J?99RaVF1%6!B)?at0ymHk?aYqd z#B03xZ+t^TmjC!~D!IyYy_kmhZ&JWvk@#}X{Yad0?~RDWyEz{j#yJU(ccrF<=jJ4a zJQi^}kiejC%WIB$A`9oIK?+Ir(T~vZZ+x#5G6qT);hrgn@G3z)4ND zv#+nMuWp#fCCzt*q!ElwqY4e0KlP+OfyPj4svOu`vL`x!N0WGH$0na9!DfnmRz&{@a z)+ZaPs@>D%Ug|eCfPCcM*!i59JQo5*{&{jeZ`3GG^;uHKTzN}1wYd6l+FH__zOJZB zHiu>Tv`*68b2K~6Z)e)|(ZuvQzCed>3McgXQvcsZI7#R_DJaHN%=+5qnnbnSCi(hh zKu2d?ZSzb?F=^9)F0E>2YOW^feXVI}6E7V<#icDvORJk(>*}(iG(k9Pn{^f1s1;S)l=vv=O8^`yol=lMPPhr?7h7TbvJ>L&xi?Iddsn5U39ld48zpT6XU@i5SD&g)B@@*`*O(9|z5JVk!M$e)f|Ie3JHEw= zNoYF5C*8?ue9Ku*hG&c;&Cx3~P34O6dWM{(^E$qvalR&NzO9_Pd(R3J<(bRU(j?#U zdZVOC`FCYe=$%~EoC@pz8J(m{S&mDYVJS?IDEIE-x_hSN`ys9nDKV=#EI80MVlnB12`32MCrlA}W4N}t{qqMB;@tm-npDFrxdNj|Ol&qFV=)Jpv zClO8*IiE<1Ke1|Nlo5k>)=*$NFJrl)d7M=O%&za^5J$>?rcBEdGg@XVhRH|lU-~md zf+lS_(CJhBy2Pb38cfwhA7`y2eF))X;p1dY3I%npD>G+xgX8MqghaA2C>8pgvq_HB zZ%LOcCT$q-WWr#1#$ZVc1T~?d&b7y9OZk60fkE4t_qG7XZ>aZEH3|Rv#0=8pfbO#; z`*#se72H#!c?LeGdar`6_-#PZ#VLY+N|<*KWXZb&ymt`ZF1T+`&)fJUrXdyFy@E$b zr}D9&3YzEx}~vy0x1$}|6i z74syhgQM48drd`uQkIfVdq;i6E5@luznBC{D^8l;FM0_Mcp15Yh$}1CCT6Cp>Sret zT3{u82kA+|$Atcm>74^3Sh0n2Nh;o}Qlw&+2z9aNS!OLo?42>u*RYuPPxxnosMP4m zsSt$2FMOQNg_t+|;fEjg&XB*;6hSZMpHmIYLZ4J4ZpuGr5l~#Cl+c%wtDd8;#B=oh zTInlS`nr_90eztFPk;K8(nlvnPS21(q0c?TRBfTjN+CQiu7rOjOCj*d zWT4AL3aZp1$=jpcN_mY>nUCjCr(IV%P}+w-Q+Bcs4rnX#i8xztGn_xUsy-p5KK{<*>y-L_O8t#uA*6~?EMQ48RgzA$g*HmIA5-#rNJnoHSr&=@ zoxhgmPZ#YX&9zBWQdruVm5J7rRhis>-e7Rn67CgV?&Snq7sU)Y$;($x8npm@wnqUs zoWyjTWXOzURs9^lv1)e0A4vyFy5Q$HvFiYm=*NsgsD4K9+(19*gySsjd*X(?N2BNJ zzvwDM)Laohx+H~Q#s(Y*T2U;{KH%MiRl@5kPSSXdRF=GP%4@UoTAhQ}Jmqy@ZGB@) zYSb(lz!^@4c~YY&7;JQ`rI1S)6+RG6k!=tdJfT`wq~iPW@tuu z8!i0zCz!s;_!_(y*gK(G8l1TLqBp_v>P=@1-vC6_V2&&I9tw7hVOi851 zCz8oYGd>1;AOMP|dmPXp7u`9v5h43lix=ielAwD5G1QDrf zW0k7f(LGw&yr8`604N&uySlnWzdT^LoQhTl>!AK%ZE<@xGK!mDQU-K9xDuD)CJ!y56wAZ-EIjyRa+1l!ze<`NGjEVlK!vNIfJ%#0nC|Li;SAke zFjO%qG(zvda(p*eI3>MQo=q_QXvfJFwTWak*X0nr>A>d*+a#ZDoTTw>upQs8sP1l4 zzDrbhXJz4AOiWDt0Gt47+L@krnVld$M|21OSL%bJp3`|;38WyVXP|WBian2V=1bDJ z`iA<%KYLekjw2ZJF3^*+J@0Zo8L$84`k$*>3%?gm2IT~Tv*nX%CMD>-iX*4LB>Y@t z@^ihewmifP1rqza3gnAgJ99Z%`NHu?%_hy3pCz_j8fmrRbe;Vcd@sMY*`L`^Uyq?l zRQsuh*J;M(vG9G-1YkB_#K_U$h{ybG!d=4mU7V!(TNgNA#Ctx%_Q)LO+4v#_hrfvy z{z^r@J@uN_MweEA^E82%?PBsJV~$X-is|%vLWIHn>h+yhRyEbt)(@J91D(W`9>lO# zDlyZ){<6yS*4r12&uFTuua=fO)Oe`wL!;}9OJFRUt}j%URo53!Fb?zWe@C- z4{wk1@j2yVLylV6PtED6K{kGKT@?nXS)N_bvzrgVeWKwqR?T>l+08C|ymtdUxbk>a z{j3I~ENr_Tg0qve8wd@euLiw*d=xX}GPYj1)HaA3e+sB4^k{?nMf?XH1f#`}Rtb%m z9(tBmRdqA2k^BY_juSeL8_#V096Ot6(#2EyUdD;e?j!t2^7xTljrP$m za&;^39Ob1|HMX!K-=5=v`O-;jeiu+Gx_Or^YF(jw-P+WmGoN03HmYf?4oCn)_o+AU9eR3WO)18M{ zvHA@IF6I~|f8sbEgad(0{#o?z{CXLkN$U^&^BU4!`3NL&MQWl*hC}j@`Y+AvH$`UO zl&jwHQOrgQH9kG7Rq(pQsKPe=-1Nlriwu^dxPeW<_%2UCHep{$sPI{CZ$ zDeZwAf>R0HNZ25Big8M-pQWyTdfS!MB~oN#W-OBd_l(iN0=1}TO-wW~d^WFYeq#fz zf3x45Xsi;mUhU7A?0YYwbHAK2g$mvkTaUBb6T&)?<* z6J_+QSRq%j7nQ3|DOb5nX*@8cgC{bC)ja6x+9VUHhs&OpZ--ddz8b14s#4{(P0EMx zce$LcAbeH$lL0iuk%s9wTpQ6_QBJ+tzG(h6gQgtnMndS7_AeVxiP=iK@+9rwZwS8@ zo_?*@BRqlWc-o~rnbEIYKEnam&XW*wZK{Q(dew>9O$pX;$WZBd5E8VHqd3p*MC2d5 z`yjku(Mir(mVI1AbaXww$m@o{S9CgEBhH{FTy3ww+fB$vk@`c6DQK<8KOg4rxOkJgP33!Y$}*)8`G8*_CD=?@ZqDKe6QOuDlH zma7uiMVbpU4&T$aHO+i~Zua#V^c(0j(1h5b+tJr1>JoJ`5=}aUIkTmSHE}6FS(Q3J z$?Br2X1|8^li|#UrfQaD2bP5XU1({=cj?2FjPO;VegOEU|1q&@PK0quFCy({gr5lC zKj8$_5G#{$V+(p`e1P1Yo%3_1RLzC6!^W}jvkwMbeTaB#uFo~m2d5XmF0$gq`gMly zH`=e8D86}C-s}PZ_@5~Je~Zv2`fTHbq7sopbOFFTEzEu4Eq3>>sDnY0L;Ui1)M zq+s;Wm%hW{*Tdv-xp)%;$pLSZrvo!=MzoAY7bpBy%b4jYK9JMD_Q~*_lj@W6{W*z5 zV`M;JUTvxd-wpf8Atq3UU7RU>{mW{EpAQz3Z&rQUi5|hJ1m_2Y)l#okbCO=KA`?A% z?^mA9BBERa0H%=`WCs9D=S0~&Ohc2x=e0v2+Kr*>;7fT+V?{&suJe^5RIm~UFT?Lq?aa=HhBNT?joZp>E%D*I-FuqoaqSUzX`iVKH^wW7Sb?7(ZtS; zh-PN5q8X@j8JY75*X~z1ZW_WLnPRF;a*%~CyfT-hLNzB6^|EStenU%>&ns+)NK_(+ z${HB&S)TM|y~L%-qzXpxmSQ&Y2{Dn^YkD~>PY&A&?avXRnHlq*UY03O`SKVR5L?$u zp6b`uH?vll=`EQrta8PuIxJxRyjt*PB>W~VdDTUJeM8FsSWB~+Rc=l&xmfK>0c&oV z(VV!UMI5v++e22?u3LpDvf3Rx>4@yE>j0;n@C%XMFE~lJJCR98TMZX#HGHMlvUZx5 z)=(Z)J?yNL)Zv_tgr^U+!9=#UeyniEAvha=x!d|^^Vy=M#ju^Ltv@a(AqU#lUta+o zClk#30zoZLjBmhgpP3?o1A4FLGeq8V~mQ&loktX(TDf4%8!Y!HDp(tZ3Bci;b*J9t_KFXBuNJ|?UkgN{H z0S&-H|GzAR;H>r9PIwB=N^pKe_@VG96AS6}Iy&KLoY~$N>YB1L*!mNp=CgQChP14V z9^ll8=<35_<+JiysyrzU_TT$H;d{dC_w;(yUyMv1<-JdpIZtg^F5juYx)KAi@-ydL z(#ZP1!|6D|z5PnS}n2i2s{Sk7Gs)hsxte#Q*y# zVV#uKb#gV@e+Dz;5tn8N_x!u+aeWTMW6J8OvP#uiRQ$12gRi>HQb7;t+~&U(!T{}( z-77$!Da1tIP5n1f@s9~>h3B=LfS!)&m>#4|e@&Q<4eFKY)8rXNesx3r*(smZI*f+} zZHljZCS>&EGTrycN}#^E?@~tpO~ya6>e!8ueAEX={ELT#--kF!*KuSZAx+1B%fYUx zt7lAZXjHz$?F<+dAJi;2Kit}e_mA#{k--G>zOB( zpl4uaD*H#O?AvY{CQ_gv~h$I;H3q+H(3`j>mm`{@O5WK&1mM5#nvagmh zeC+|(`4$03%x=%DYEtG&hyNR!vA_ss2-WvnF9Eg3SdsJ0vK%{<&UgpJ%1{3 z4$Dxpl?V0D^nsBsu(rkr&3n~un8;e@twRmpGcZ-UeDg`+`$=It&8|fp>S&pdC2}xr zYnfA#63*KR zk$z@aF9K{QlxQo^l%t3kvpCk?oTZdVBVc--T1=$o%&KZhrp`H#nvrX1BD^R1!;kB` z=|e&dkH3sW4#AW5PyF$3NqP8|T=fR`z;?_Z@0vg_myc?F8{UEOwdh@v$U%CBnT-K>@-jD^gHRhif8n;R1|YiHH6 z4y>9oB7-@;+D$PjRZTMwO^;M{Kf4GqxiPFzDzYp}o~uGchO;XHbxrqDDEXEL2_ zw1IaA;XlNd{0ApgvrO#JlH^^iJlwsXTH}++VR)@mWS*4rPa9(U73RG-YInGqkl>_9 zUrmUN*`1JqnaR?IKCqPI{mh~IY#qsL*4JlgDv)4ee=S4y9t8B)Nu9{TWBAIW;7kSQ zvxLQ>x5b<(!VK+#+1^a)!QS?+N{Xb`~ zL&~l|Fr;YNtC#-IHo`N)!!vT#8Q`zh-E1U+5TAF8cCoaSEi-yr(W+LpQb zq(;$yM*lb3mPO~2wkf}6EcUTp`TZwTf+GF?Dw&aBYC_z#!`kVC@5bG^_;%y%H_#6B zHg*{uZ*Ne(&G_tvz4ATKSnW#!CL>b{hj8l;(d`Xep+8sq7@0S_LHfV95OTMVk*+?I z`^Y7>tk?FjFw&;KuJ*BMIdm~@X!oZwvYXtHoIksvKC_K%+5q02gs(}xl$Xr8E!!QT zwaU9ldHGVWjY^?*TMkn@+1v_|PDiFr2!CNiNjkc0ZUf#!_`dKa1L~OVOzcd)?&$+x zN2IZYSa?Xun40T*I_k9<94#yvyd^*hpA}xE@uZpUfgLhy3*@3mf$Z688YRYFf2#=} zEn@#&|IblInT)oZEtTNCKzL60c#acP-4oj}V%{sgLmA1{cAB@zj>@)kZaEBQo1?c) zr<8%YHQ?Mp$liB|G@UWi^ZU4#;aq)(sGT{W_fO~MwEv|L#{sSL#Qr}-h>Uwj+r7vf zB;9;5il*IrIfwl>W$<)U0wV36S+K^klSX6L4tLu(Zx=j8d_ES~O0jho2i{x7ul*9? zb}75Jb0R)p8fI8-^F}N4-|W@e3{oqa!`i3=n>o6*|JBMu=Q;?>>c6;o)>i5N^)d$; znP+8`TlBa|S;@6Al3`__$n5ZMj0BJKS3tkBo3v=*zDS}G5;+7<+P}vLkBZJ7m8+i2 z?x$miYKxuac#Y-SA8Al9w4(F;WcUW|kM!}C!VtmCRRyKdxdF)FPT% zXJCdBum#sF`OP)BWVC&p+;VQh`H=(OTsR&l*!z#B70JWwj{F)Y%1VMMgI~83NHhNi^?X}4K)jnq!$5K z6C&eQQLK>B*eCkTXxu)*aVdLS%6=<;N}s)77Wcba*{~?|?}GMp{;)l~G{j}$Z=s}R z(xXCFfT7Ir{?HlJXuR9X(+p$g(zD9M^}9aV51foXX2jne8(GJc zcdBaMY*_Hw9R9A6NukuAOROx^wLMHD9;(+*O8cLcPdg!i?mxK;oZSB4*vMo+-Vo)} zbV73Rd7_#swE&k?>(=I?%)`Vb^nXg~rt4>ke04|lnKQU9hv0Mqe@KY#JrTup#e1K! z_+_=m8*`}Au=q~ddT}o6gqfda2Y0>zGrNc_H|8dihkUA9cvvLvTOq;NVHItKJdI15 zz83ftA+kPYU<4~18lNkxv$bgHI~?Hm3tK zDFbs`PNh%izE#ScAc-4{BI^~65hn<@ET$iGvqDrIN{BUtF(XAL)u~} zR(2E*bf-I`R1F0H`$Dd8?L)%u};dLsawT{-#zfhS6t<{ zG$*RHQ9XdhLkQtO28#y+U74H0YgH-U517D*pFSSqlyH{O*BX?L8A<^eAcfd9Dh0C* z{J=;fnqy1-%(pAGZ9Gq(KT7}4=YNcBU&;SC&nxr137&UV%=Ve5xzJ`HaumPQq{H{@?0l?ZY_COkTGsuS3&I zb7aeVsb6mE{n0^>>~!(LWfLR!)-&HIo7o~SJm~sIRVr1{S0Ya5KVOT8^&Y%4^*Rm$ z$JzQnlK*~g^C{yj6loH|6iEiog~&754%9T5$mg@exF+Sn^}Cg8b^$N~5}Y#9GvuTF z?g*w6ka@%HAO%F@Ba0=Ch?;|$T#;I}FKRpD^7$MkFH*KDYU>lmsX{KF6H`2gP%Gu8 zmJ^Dg!7$>GTCq(>lP}Zq;%Rw#n`-wm8Es%sSKJA37$1xM-dYPrVWe8~^|9b16Pd!6 z2g&ohfUexjlS93JZVzeMXbT)5N87nQXggPFJNNa_wj|Yqwy|7Mx|b{keuVI^BDa5) zt440YOq9^}tjcXjgtj3nw;@W~5T)(e{m4yo<_}qYUi{y5S(RwAr1_l9Ca^#-<|Xv9 z>MoUeNHBJ_-p$ZA_oJw`2pJVl#h8Bv$Cb);pZD;P-^x_%##Q!cuG zzaKeeq3br0j`OuI$4X6Vsurv1eC^w${O>0GQRMbVPH^ecFr8H}d&lTkSNL#@^s}O` za0X3;bxX_}4<(mYS2r_qUZ0r9?iY1+^8O|5p%_oQgj`SGSo`^fX|Uqj7t6g`&#*3j zVIesGMfiir=?|RXf}~?QK|Q8z=>Z9VYiIHSY zUk-eg&@JV@n-f{G7kH?VK`P^4PgNZn|9av6{p*qB7PF4w=omht&nwc6-^z@;>3Q$>yh~$V zsiK*}VeGnIKrYLq{daPyXlPDd!MAure|*^*(gzTZ6S*8$-c&XFTJynNuF3tKK-Y&W zZ)lkzGn~N}Z4J(zG@S9K{RpM6IA0zLcsF5~Jm)oTfUGE{v&yOg8ZKF_q8f-@sNZ9X z=@*TH=F85Xz0XcwsGDyaE@`}~VdOkc&a3821DIypm`O{J)&tNh3F2|3wPsn{x6&kINW7pUqHbef8ujm?BLM^z;=e|LJX`@)>GDa8`f{ zUTm(@ftqQD>9n9ugwaA?e{mvWX9QY^j3ihs+$N9F7tM?cq));71;JJivuo!jXdD~D zj`b+rSe{L`c=3SO(;~{VugjY|Y>R5}K$`FKscGJkALUCql?tIUshQ|vxe!-KFk^C4*v@=>L$al=o=c+7 z3;HSe{+lL=;@3E%fGzxLWm*ZSipl?PY`Pujne z2qy}CCx&BMn-=D*Yd4bI-eGlF5*(CLK$j#|S~*d0G!EYvci*7t&utjA^g|}nh&|PB-xB&z6^iOYGGrSS+a}G z*$^|YiCxthU4y(TKUKvh(y8D%TIp+><(*@x(#eK-3Cx1@Cm3?6PSiKB17TH)$(k8_ zT1GIUw9aGqJ;^(Tseta@a~S38z#K@>E7$>5hHcr0V|Id_i)ONe)$CDFAmrA~=i992 zix)guqTx)EUxO>)59hPy$w0)i=L}yt5A4&~SB@V&W^BpXB0VdAd3~yZ4K(TyDofy@ z;+lzXWQpPw>m z^k7U2Wo$(aMd=Dcxh+HTWfrsFy-b?P79>cf8imiUhd4ErveQ%W{?`m%35PfBveY)o zC%9VSBLxw>G>q8%2J|C_7Q=2f^qI+mVkvD^&F;>CQ0Sygv2VDfYT-b+!Rur1n>ux> z%1NGP`jm!3m%B}FRx$99M5`2Pc@9m$EOv?K{X|R1`^L^XN9Oy?Hph|cqwCHw&5C`K zQTYFOqNzdeFY+ZjK4i_LBCUwqo+XspC~JP+ff#`lzW>nN+Guy>F_XN%qur zjfLVq7bP}^>u@g{GM@_LRlFF^7$SNdw#W8%1QAA7yk@`D_cav50Gvy2PR0Ojb zz9doNH8fKHLwBn|l?Prvca33+Y5tE`8$b^y_ zm?&Q4*4@QSmDO+Y1jgf>BH`eCV>7AD!Io`gCN`R?G_zJ_UPMe6ViRW8)>S3hjLaB( zYc1^LI;L%2gDW56#TntxXKU1XjuGppQCG>mVRpTkz#`j737x}LsKWzNhL7@n^9dK# zG`aG@b8#6l8^!@dp+@K01YLXi2d}&8+RMvF4H_iXuZNh$7{LR2mJLsd45tVUw>i)_ zXloTxu7$zmj;M~rHf5FqjIe%24H?U>vh^vPb|e=p`tdI<@-Ne$)Xwpy2C#}lmSO2F z>OkB3dfcY>Xp6!vT6v;EC=w&7+p1lvsu*wD9;stdG+PL4b+b0!w)r&3B3bK%Br(9l z#U3~77P+-eGh6Cx+klp?pk)s$aSwHgmSlKw_)N2PSKl-xv|_-_=FZlB*$oJ1HPtm7 z;+?kqe`#pJ4XYQA2WirJNbTV}>C#>Z^HNZU2f9O>x(ON8s(H9#LJq!AlPa#rpI0L) zmmM{wIg~PI`#IXKQVA&vNm_gHR1BZt&0!nAvI1N4Q-bb?qwNqcyX3Gm2hs@Xn?Xt= z4Lyuju~T6a-%%DC!*6?;HoZA9yAEr~;v3upI5e#4VjC%7c!091N*y}!ZKNcMw~8Ck zFtb*_CZZmh;hK7A#z>UV$2`YMU&v^#067&7sdo zSm=Vd6Gj#zw;~t8eB0dkw62E1XFCBel(l$3%mii?Wv7QN@fx}zFAg^`c&OYO8 znJk8P8WP$um8hXI+0ZZtamjZW#QEeAfeY7MRo9qITrz0T8O*QMRr%L8R8^lp<=V0A zfXF-eBK#{j@vpC%U!N%A1B}(RRrOVaN=AYg(W2ymip(FUNCC(g%^$~zNlpE z*lbA`jJ;@d>BSdlQpv@|V@tTz-gUv~3oaTvy3{0HR62G{=|w?O$we29E-o!LNf%x? zcJ!E%(e|#Av85%YC1Xrd$(W0ZOE132CXK!Df(yo!jy6f7FTP-`qi{@V>6p^u3kD5} zN=Bq>42_tIz#jUus~WNSreL6~QDH?48lL7BifNVLiHnH^6%9+RGDXzdN4YZmj2XD_ zbB6l~$|CBe&9g{yV~R=6Sz2mmN%Jp-!<7jwPjU&HX0lgTAgH!7F(PHu)(0%!Rpf2m zmxx;%nt5AdO!1@ZB%ds6NwTx0v|0gY^1Qk#Jnxpe&|P*mL7t~gS1^uJHFGBJ3J!@5 zpJe*E#-|!INbH!1y2q2!eXF4U+ny&M_q(iWMj|P^Xb&dCpeP~Y76sl^Sec!37Wn9C zEEsbp{o?Npqif$r_IaabCWpBN6D|5g#45vIsoQuuNu-J_XJwKK34b+Z2`&J6y!_<{7m=Fbd`Pi=FN zS{KY@t<>P)nWnv-g)K5JWKujDOL>r?mMHCAPe?Q+aN@}1h8Fn24EX*TFkqtoNZAHe z`k%@9vPp-&mrB;);>!NNf4S|~%msy0xEZuph+3iMMSVyh%QYPj#H1Vl> zMzIqz9Am~|q@SWCBru{_FY%-qS)rwsL}~xB=-Yd|seVbqj^{ zdd6mbMuH5xtf&izy3chy{{Z{P`ZXLnd3HYpA_KS_@bH6DV7{D78Z)qR$o0uUcaMl% zlQd0kcQTwZp8+dPmHQTx=Eh648*+&-BzH^tDxjO!F`bSO!QylPT^=-y!JeNseHYM; zbJ}$F%ans>{7~-AyuVrYnzZRfKsWc)l({d~4=d8rZGT*D=8*i8K*ztaKS5eH{$=%e zke-$Q0Kw+p0d(WNrrKW;46{i_974w)pc|{Vcy?cTi?c?`=Q{~QMZZHWj_W9Csjd=+ zILLF&1fUy}w)pnVeqQU>L-0hH?;yNg@_oC-6GQ84Z-~2sGslmvCl5y+%#5IUHsfEB zd4;rf=V4wuIV&WX`3uF-CBuRMU3^M3I(H=%(RULsGF>Ey9D-W{bn??mD;T3%>x@7I zXDT>@31;nFWo?Rfm^VAHimCZr)_fKK|B3J}k;S|4Xmt7KM;lp5^U?6(8P8q=zN=r- z$Z&x}o+9?GYp*`{-Wt-K%#7YA+xK227s+D@@B~7kJVU-5O@n)_etA$Z436-h znNN9S=SInAD>zQ}CZ9_p)lqQvg5%1T!MUboPJ-R=6OpoYpATM-a$TQ}NPhPT{~|wA zzD#~HOU5PP?LOh(>BiF39EwnJg#S$5t~E`&WTQC3e-GYl`yb$B<9~{{g0-`PvUguL z{x4B~(IT1Wt@VM zNuQ8NHfpk_mvZW8mGlpp_2LFaai($ZWFt6NP$%d#%j-cAyhWTl*;qWveo*y=o>kzu z=Uu^US<=6pR{@$L`E+pZ+NZ0oyk-(Zl9BXXY3adEjRt{d{J4Xir zV1L%oNclQ7jlYJg6?)AX-i*ri$0EY32v^E8uCxQ6X5U{N3^PieEn9WGo9v2rH=0ZD zCpF3^KRJYlPT)eqO_KjjvP-5na8gt4Y-V7qStue?uIjktm9RA0iepxa7lo+$SkZ8btc4M)IUwkEo-0qoR`%ybL2Om~d%go4R&1dlzKvj3nw%hOEbB`sv3>ul9XN0sv@_uJTaI8Ku zhw!nJQ>jDW5k9`7*R#I6>AlovCJx8Dn?1;f_MfcGLHo71!8BH30f~LL@3h-{S$1L< zNQCd5>R_o^lyU|S4wiO};5@Q511r5osua)B|I_%-M*B~vli=)@Y$tBs+c%|O>+DaZ z{EM#_`3CFpQOuA*&y=u_X$iYrYe00VFx7%wObN@esh8`?c>OQee^G95z}tG^-?eKYS8hWF(gjc2zaJ1*iwstC zLbIHS9SR}Vu7!7w>h>eO>eg;T=U4e6c3G@CT-U|flKgJF#?Fk$>rfbDE;2$Qqayoz z;W)x9Jp9~;=(`Bt6du0G38oyMgduxb-xPT@)|O5EmU+&tem%8*gH;Gh{2|^*MClXR z|GbM+=L3aOuf)AoB*EFo+0O`(?>RC|Y)i9ZhT36EjUix~FSYwQwPRPY9l1?Ig4Jun z^DjD}P<$BUgU_6yywGBENz-=$A16E}x_nHodIKX^nar-#qIh3UW_|8|=XK1!@rZB% zjTX0B5n`leJ0~oWX{a({sc(qOS{%J+e}yxP)eSyf4>8E#m*W4dBz#MF{1zu^bRZeI*V&Ze3NO6?8`tl)?V`8nZd!kZLaadecl z5HnMU%3kb13v5xP88*corM?7nDzvt!)y$ePu*Vpu?9-qs^C2Z@DA5t65Q}t%+Evp& z8ehcN7CXYG`g(97*sgt?Im7T{3oU8z{h;Vm^!kMG{RAiIG>VzY^zT%sKkK#NzAJ0N zH7rI-?tA)Ba?MSzqv*opL!y7zcNwqtI;E_t3?5p=`NM<Zf;uXHjO;n$Xdj zDgp?)ddx+#a!HmCs9b`{yyiqo<~IAzG(2w*y}GuEx=UZTIpRGC&T?=vd<7`-rhZj<7^f^e1@}ZIcL3u&JUndhzf_*{l1lPr&_7EkBI-{#t_uNhZS4W7m)r{ z!gA58Fid|k#B%IS(Wck5M!h?|al=Kx9lcWXy4=vKbXgCD*>9ddl;DmE)X?8k9P92=2`4qvMx#Clp&U3j)DR!#1KRvh1@zkdn)9aQwX73}J(v@X` zL5~y@1pzdxuXC@QNJmxjBF}ub&NE6gW6wJNkFC(H-$EQI|8DGDa5PEppOAKcP>ZEO za5$oW*KbmsDJ*2FO1hzR&1)HW&OU}UD9lXgT?dXEmo_+=nF(Guc&=TgwuZSV-M1N=GOm%ExdEZpqp19STa?Z zmoFo3c~cK;#O(ylD4d>@2OiglVK=2~I}djDDi~37bW8oeg^+FBEn2E|+$}a!_D+#tah?+PCDO-E{r@*FidTcT9$qPY`Yvx^7mwPGqd9o~i4ZtjwRCWRHZ{Lb)#X zVw5&*UsvkPu75qhxe&HuI>}BCbAR7lh{!>nqh+*XC-BRJ$a_V-j72O}x>g8X-hM_h zO_Qr`WQG%^Di>=Ns9fx5WC%?fi)^$$F7@B_g|zJ!TNG~8iku%8{VyflCUU-wlj!)8 z!3@P5GweLj2X=A{n;keS(D=kOhDN4I9;NBXwOOJH_>KO6K#$_A zjKS}d6`WI4+GgPJ$r77>1lHs^CO+MzSx?~ zf(LD#g%IOxy_UO58nAE&B*7^L=Pp8IJj@u55Yv%AM!lGKXt6WfZ{-}VmAen!HxDwH z6S}4TJ9`@P##PnJQ_}u-5H^cmv{m#5I4sB0tO!rJHipx|$dP3B&MT{$c!z9I@EX^k z$a{c{;Br_8T^C5sXp#XTmOIf(8$X?4%X-YF-O$MgKQJZIlJqjjkS+lDe@ghz(5-kK zQQdA4{b$u}h#ATuc6vk(`_Zl3eK>WyWdn3)=vJP|Rn_g59YC>{KNj8oSgu;#DwgBv zx(HAE)osQY=UFmj)W}n{&lqZuHR7QXSq*legGD{``1BfxzlD&^XNk6~rrm#=np5Mm zT#=*QKV)--TgCqMb*|8u`_X-9l8*RX;WPB~`ZibCDFw#s3lm3buJD=89JJf{K3CZ1 z_MLWn@8O;+e0B-6KSOw0>gm&*P_5luOVlIRPp5fTXz9+iHLIr$<593RYgmaRbDrB; zVQw|yZsGNAVKvHYv?d!L`DLvsy^rY~zImmP1?_;)o^+K$u-M&)g#L$wd@twR(bu)8 zDF?9w9g06U>ri~Hj%P7Q#|ZsFkHklq8l?=t*K>n8b7OW*wG5L7LtHSL|D5|D zzVFl9`iEFy?ea_keNC0Nw%399!I=Z`5l8L}Nn?$F;08F)AbrM2`jUZXARUfECU;~% zKzs}wg?eC=w!bhWYKt&= znp~5iW;4Xh%M7Yl-sV#+Ym?ax|}kMwybz3tsk1-@!J9Dg0ma)`l6%IZ&>3Py?O4AohPF zVT0&QDk%L6GgvCD3r&&k_qQEmu>-A`hjWfBROVQ_If?pl+r?f={WNQ84OhZZ;KaiJ zcHw^|Au|7I`42IjVoe7{KfL4Z$BC7@4}%jM==%u zJ13wwcZs6Eiv}Vlg-lcdtabR=!?Z$m23~DsFj1r!R>pAa4pojxE}1Dz_CYP`l!<*+cB}K6n?rZ zgaLwCBd(S-+IDs)Nt5o^TH$vsC!mH{A-6PKc-65_zRtFDgfX`{+Rg?Yr`@lW&1gJb zxqU_apA!gfzQE3@_cu%P0XpnmuV_> zHkNkMPR2&s)c43^n3Lu`?yRVOOC#@^-q2EOcFh%^A@CnY2$j}(I9vUPkwSRn6B^-) z6LkJ+8A(p(ldk6Vqf|pZ7da$-I`BclFGU8wesVWXi?}z4&p=w2Ymfn^zVF&U~ZvAQ6zmTXEzZR z2;WlCBV)b6-m!1vqM2LRD2k7DDdV$p^wYz+Yv)q*WuQ+Vt-AR2F3vwe$UQb6ojEXH z_tIHfJNWqCER@-%0!nn$tIuQeMp8=Gjz!QUvN%a(Wxte%x55N`+P8OhtOn;r!V7}; z0w>&JhTo&uVWINM)R62_*_t8c;w&8CTOMUY%4U{FW%HXhn9MGla99~(Q>xVyA!j>#wVNDK@TlQbo|>Ia-xcRCkuV{6HZ2JZs7-f{B|ig z8TKL@cBtgo5~t*YpQ;HK=!xB!WmcJpsW97VSexN`Bl|HEq4yf$|98TFU)LIZTv*C0 z)yCi;*Bbn;i|5@%h>X)`{{{oQ54)$m;cE?civHakd9eJd$GbH<*Mav0A+jdn#7t~g zNZzYuufIw(<68_F>nV<+Z!!GmimbBusPSD$lY=_*pBsQqW*HxoP%MKd_CH_lkvbUj zIn(RE?*~lxWy1C~#1SXJty7yKZ_eY}NfT@i==gmFrxHFO`G0_9vqOXIlqYY7SFsgq zWVlA&l5TSD$tZua?6D;EuT|gWPc^ZT!fbXR(nm=CV*iEKJjp+A($$;_|GyXh-C79V zvXph1GLF!~?gW-V!4v)?Hu8L;VWV0=M5Pn^vo2G(wAW<{{YBn1+2M;pVLlLK*C(j& z4_PO$_o8_%$bJCcw_C-?{;=TzeScU&?DK@r34fo{q|lZ`M+D8-{wQtNo=~6R8#!$E zDZCn~`{A8;nQowGEbi-Am$0iCvYf0ZCfEjON`f62W$&EJ<}1yjlU?Hfh`aZ5;YAkh z(#`9E9ad1g7`Z}OD(Kb!J4@L+DJYIHNVI`(4P^_wtIK%s!ygt1Tud)bF|5XGN z&l0u@Pg{j0uP}JMS_JJzR$}L=!MR!uju~0#{f&-T@J5IIVx4)TgV*HrDbC5#-IPOL zUCMT$thYfc3@-abW9G|411{zmC4Vv$c!B1EH-EXFjMx8i{ZAVlBo8^@^^Ze=-yqy6 zyxu8Sz2gI3uSiXdusU5?Rn_&<0P|X$n2_VIV0Xkp6ZwuuQ*-)YgKEhKCFqEt7MK(7 zEbBVzNX-CIY3=|HCfM;I_O-m44Xv)%m&*g3-JJZ05P6^Ngh}a`nWZwRT5RvNRK8R4 z(EYO_CDXjteyB^L^7b3$P@`l+Z& zl_zFLDA%vzVDD*9s3WKFe+X>FNj%2vL}xcn(GKo;WFFM7+{PpS;LL{9!T+Aj6U1D6 zP5AyAC)9a2hZkwZVn0@eEm5|6H~F!%#SCy@3Cz;Z@U2C)8d$iHt1~$-6m4SdFgWj# zJLH8qj%=n*X#SsmB>tYTQ)u2Ps1aT9y^e^kW+>4{SEiI5QeClFL|*Cai>?ZaWuGK{ zm%6_-^#^I|_Xz)AC#(?u#pz7bS!7Hg_MtxOEbpN;hfQhdY>(K#<%F*Y&0i6cBRVUu zZE`yE{wG3oQBEsvEkph_gQgrxV*suHuNvaS1&X}4bR4626WDVvLgumvnUy)o^vOqO z(e!TGNNNV8TMuD08w4flX4p3uf_FEPRjKpYDT!SU*&vHOeZ!Msi8hwSu*_W zzbsup=<-8cmj1E^T3;n}i`=_8apfLbv$QL#4sE+~az#VE-PH7mH7w|8?S-TR^)e&!4(AobA|G9mE$SAn= z1^S}1!|V(EP5KXu37;07eVUWVxP7E0#8xwE<~=8si_gr8)0S&}-AUngIKFP*#;#ch zF@ldg|F)W^{F?BJ&?e3$!#>&@<_Q&iJwRX2i?k@_ZNLIG08@HzQG(keq?IeR%pwJQ z2-^)2-6mkcZrNNa_xSZb~})3eq-%S-6gg; z!S^6&Yjtpo0m(xk0+`PKyV$?i2!9tD{9R=b>YmRVG5m6AGU)^nyIjhr6@;1l$hG!5 zUv6|Rgyh4@8#8RAyUa#DKTsVO2D8E74B1azzSF>F>N3Qq8+e3Wkz%2 zh88v~cG(`1a`Aub5kq7=PlOWsDv=h!)YaIzk-GZp9OGptGeDL&RAXhYiTyi)VCRT+ ztq(g<1>0wdUSC^C`n`lTqE~6$K{s<+7Sok&Q=PBU>TFC-E|vb1$stsh%mmYHqYl|h zHd4o5&(PRd+qn{du%9;p!ri!_c|MF@-a0ec!UjZo2wo%TF=DR?zfzzXvgv^x@*FcO zbPUfo^;(}#2(}9j_7w`9;*aRqOt4+-$N*3F*^;em^#cdt=BEd~T`(_sO20JdR*&Gk z_xbZk85QpNgByq(8}OUg#+iF>AuK66_#;S^sk{xq?+{jsOr)`3sv;dTlm`}3@St!nD%1VGU$(s{U1O$PRhh_WIDI1*-j^j+~YN*)e>e) z`fN@>4X|A8G-HC3ROTmWNjV`)OC6mKf#MM=dT2c}V<~X-`8#=F9bt|D{PKSN$3basnMTXw29>Gd=k@C~QYZSiQ#Fn!=yz1DKN0i|664KBPa62z7v_O z*RLbn#7W&BSPcylW=P$e!AV-(3%*z`<$k-C zlapRw-O~ribGLJrVe5Omyc^mcuSEG@AkU6{K1_;kKueZIA@B9&NJF#(%U=P zA;l`#|DU?|0kHBq>x7{p2}wyiO=zVpP2L0uljH&eAqgQ9GQ$i6ngOQF5J<%imzfK5 z%bmH?duR9)<0sXq>`E1P*%tlcE?-5Z-RPo=Yh2@sipuVyMU5KWsI;b<^+RP{T+uJz zy1(D^obx{Cy!X9#h_>IKH#xlT-1GdN^PF>@^PK3gO9Ln%igLPw;4U60iPBPeo!>{{+!wq0sp_f-Z7iHh!pbSJxB5W zNw}ad9Mq4YomeF?)mHpxTGo#rkj`IfRONKy^7z-GT66^*@p$hb;?Uae1a%|UZm>%F zt*^h`c`t{~VBOsP%&Ot;4EC(;X`2VS?}z&w_3m@{04xt-_UGFq9=~}5h5GAYf7&iU zz%Ri4DCK461m@M`%^Dz;^~w#%`gJ!z5EMG|z9V>N>jdVFt@2em_W!>N?mHOI@4!bC z&#bXh-TI|Kx4vG+3URoz55oKbT;uv|r)3#?^^|DL>muF%r|ngsNtyh(tBV-`cL(#s zjXGfDjuFPMl4p0Z?Q<6HCrLvCm)dYonU*4L`Onm&TK=@9WxH3^+Zv3{wk7GUMDL(G zhnlHf1baaKZLE!uzjF)lYu=U&=X36moc$RoUtiO<m&QMnD`M7{g2{(Gu%zo zlbezyb$Z~TALC4$`~muXAX#z{BbR!Aa$&@+@qE(LzD7E@xul&-T3vY*Qwm>_1#5zt z!}>eJx&>|)dCWq$MYyZqO8kBk>F768r3BFj`taLqxLf%9Epm-l2mU034~+76IL8k+ z`_f1K*yJ*P2h!i!{B+3_#pG&%He9KKUm<-8~7x7g;Z#d;FGp@ zG5IYn;PN4vIPnuVxB#%73iJS@5o?Qv#rU_w-B0}e$ZMHxnjQ{0Kg4uS;O-{&?iA~? zal&2Qrs0DOM6*7`_*?!I690QYK4!zI4d@)lJ#TBgAJc{zxrE^?;oWTGB`nj&{+haz zR=581a05;vc5m%*yK$D1g@nueXH$DQc`U~)>oh$2xAZ;t^p?#He3<{VG*jd=C1zI? zYi5Dbnz@z67T-`Q{QDvK_rr2KNE<-XR6|QTUH;#;4wqna(*(zV@G1eoqVKK;@yiuq z%*5aXEB}#}AAS)GP1pL0lUQS8cfZW~@G1EJ9o%)wO2J_o0xGNSf`Rs#vqbfNea44y zwG>MA%o!iSo(aKbhEJ(A?{X9H%V*9&ZPkHa?n3}FhkskT;O7omaoEvun|sfA7}uiw z{ftLv%y?|(jMc*B3H*E0j86G|t^C`AUuKAQ`3W*KHSn+(Dt%w9&@4bDX3XgFXSqK$ zV@CJP8C0+tGai?J*&J~X(rZ53QdTc)C>2Lawf>sy`4B47ypAucYY`ddP{4!9_^WWg z%ryOF@wnAfWfBzC9D7ZZlAz&oPoJQ6F+=_`eq3}T0fY&U2&WAR)ozpwBs|8f6CvJ+ ze>r(3i}-J3Wv8GJnOPrsjZiopi%0&&asS9Q_%+1cQCZxNOB?S0XK}y#QWW=RN{4!@ z2gdOmAEeFQSMj#8#)XB}^@aaEZSengxKC3rK8+8QwSdZ!=Yk~9gQ6OZ!);zQ65!E= ztk!W&#f{7m$ym_+vU=H+o^qWABg&?G8`RR!(DdW7IQ-1G-E$G|zk<6;*%?ugXDCg6 zwH0rP{PVP$${8$DA)Ml_>>lAgtFX8S{AHScLpAqEGyoUurBe1MjF}p3+a$h|E(`=DS#z+ znplqRZM^>y?$4QCe~u5Bl`OR-m@djTj4D`f0eYnFTvZ|p`FW$wOa9z)adHp1%I^z@@{%;Kf+q!bwzti;>+?ZG9zr4-i>KTD6@Ra|Y0&1m|N?*u+gPQi*N z{fI z+VRkj@i(6L?+yJJfAfR=P4ELA;wpGsxlBf?C>dNeRyxSdbNZ0(I6f_XJDK>R81!TQ zTlzxZyeEFA|D_Dpt0Voc#Mn@kiCr`Y{(-KGzgJfJ7h=3*P@v0;`eM8)h9e-p0{=ER zwc#5pmC|0^;wL8yCHPrnIEJ^y9d}p5-r^_mdl_#_Tg1FXAN9L{x1}w4CY#DwL@_x$ zx;h~d9?EbP?>TVVA6EXJ6a4R|d{!O@@t5H4Z;yWGPImph3-5(+_pzMZ*CThvGf#(c zH#lyLChMfS`;$1uRIfP(Ddo8TAl?=Zx$EzYzy1C|`uk~o&4$x5T%WAr)(Lu&7xmwC z0_(X-drLKX;-UYWc+Y~dA2id)-Ud?V_JH6)D;4R+0OXi zK^lhnZuIXW3JI^B@wfE8e-wXG-gYLh>D~dkkx`ZkIsc=0TiAMIBkl;ruZn*eZ_BSr zY0sp13GWN|yctf%&L-Wh&WdCF&CVStk4%b4#EF7g`i_>$dq;&U{pJH_dgV{q!H;<8 z--)-`3sm)ESmdhWivLddo4mDZ)#QDE`foC=PCd!@c*M7J87^+E`%0DmXW^f~X@A|y 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%0AKkJ_KDW=)lRG9yxb_H@^evm@>Cf^lXg{#PI^| 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 + +#ifndef XMLPARSEAPI +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#ifdef XML_STATIC +#define XMLPARSEAPI(type) type __cdecl +#else +#define XMLPARSEAPI(type) __declspec(dllimport) type __cdecl +#endif +#else +#define XMLPARSEAPI(type) type +#endif +#endif /* not defined XMLPARSEAPI */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* The XML_Status enum gives the possible return values for the + XML_Parse and XML_ParseBuffer functions. Though the return values + for these functions has always been described as a Boolean value, + the implementation, at least for the 1.95.x series, has always + returned exactly one of these values. The preprocessor #defines + are included so this stanza can be added to code that still needs + to support older versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1 +#define XML_STATUS_OK XML_STATUS_OK +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (*XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (*XML_AttlistDeclHandler) (void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (*XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + When a namespace is not declared, the name and prefix will be + passed through without expansion. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (*XML_StartElementHandler)(void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (*XML_EndElementHandler)(void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (*XML_CharacterDataHandler)(void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (*XML_ProcessingInstructionHandler)(void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data); + +typedef void (*XML_StartCdataSectionHandler)(void *userData); +typedef void (*XML_EndCdataSectionHandler)(void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (*XML_DefaultHandler)(void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (*XML_StartDoctypeDeclHandler)(void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (*XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (*XML_EntityDeclHandler) (void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (*XML_UnparsedEntityDeclHandler)(void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (*XML_NotationDeclHandler)(void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (*XML_StartNamespaceDeclHandler)(void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (*XML_EndNamespaceDeclHandler)(void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (*XML_NotStandaloneHandler)(void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (*XML_SkippedEntityHandler)(void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (*convert)(void *data, const char *s); + void (*release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of + the first of the sequence of characters that generated the event. + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(long) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 1 +#define XML_MINOR_VERSION 95 +#define XML_MICRO_VERSION 6 + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlParse_INCLUDED */ diff --git a/mac/lib/libexpat.a b/mac/lib/libexpat.a new file mode 100644 index 0000000000000000000000000000000000000000..bca49f699eea9f620c3ec79da4dd75c1e7e1d17a GIT binary patch literal 538508 zcmd444|G)5b?AMrG~fZt&e)6{*$6r|YAa#|crEYiqEP}#;QDM~_G+Ts`!ImRtc=(orh($biuN=#dt;6B=tmNuAq zzkSZRqdNoGZdc!0PitMByYKn8_dfgVv(G+%=DQcabx0|d!*e~4{FSJ{$Kr(Y?JAyJ z;5{n$>?!$nOGWdBmi9YlFSvd2he{&Tf4ATM(U1JrZ+*D*Lm!Pq%y;wu_L7p1mX<~$ zANoj%P2Mzn?b=26KX_Nwoga(bf6smOcUDoZ6y0vZ*+IgvQab!~8~&CJ@3P@K8xGnq zX~W;M;Q3lmKCF^ zUJhF6ay|y;n>Mu7c5Jkaq0$wtl|69g;Y~elnU${S>fY3&iHlFCzQ4PzrQ?x~w&_eh z67FhSCk!#w0o>Kx*}1+Y4c^!0gEcQrlz#Q|=u$rWzubMlFPm+RwRhd+|2U0>$#`Ge z#x_gC{cSza+X)A%+FClRo4Z;&J!TR$-E08MTbp~D?{91AK}fO_E^lw%(ARFUSA z$o1>iAraZ1tz^FQ=R1+iu2w?~I8?1~>3O`n?Q*!@+1VzwyhBuWO?P&+tZz;C0ZPBK ztM#3TB>J7|?`pLuTv|`--OcOTHg-3+Tpn}Xn=XrZ+~42sYkTC9qOXvka)a&JQ1y;= z-@U%){vJ5o+_}E1ExU9go29ichZ>U9ylz?#_}N&uVSP*6#*KVh(Y3K>!=}qh%zbTi zy{^0Ouiwzo-RYCY`#;&y-QCt|O3p?IR5!e%9O?w`&`3J|3eBYB-jP`=yFS^q{?lEa z++<_7va4G(qQ(7kOk0V*lpd0n=Z1Bim!u=n$JTFX>v*)Qs=mskydkoA%{n{!212c5-NlmCM+O%}r-W?iQw&H8S0 zXc8?)bW;BZo96zG&$Qk1NLGHGShGPRB^q~KCvemUB9xu$AEk{&uXl*{Ti2QO?aqwO zq}1i@zuQa8u=Ory|9#{`WgjAnzoyyob)8xm7OiKfw|^Jk`j7vQSI-8;&cW_fISHjA zk^(pfoA7df+xeI?s+5GxXCZ}?(b4gpwd-= zbfUFuyE|GoKECeZ^_?4gHa&d%rDc541wEc*KAC1Hbzq#Zgfg%*^RflbC7LjA7T^_1~ah%k>w z+C@V0balQ<87E0rNEyPkH2%ELT1b{O{(g6V(q#)D(J6s@lIX#l;HAS)28u|dMzHw78UUD zNp#GOFZ(?;qqjQeD-!SKI!70~N>%PsCBwPSG5a2__&E6FI{DFMJq1$tG+bW=9GZqV zlqA&k@o1B}`Szw%DpBKv7H?Lnc9)9qO^t4GzVFrjpR0G{?#z1cKbl$ZV+W+(+auJu zV!F1W< zg)3|rvtgAEpI5cyskYy|uvXwG?M+th=()H-?EjAof$gZaIJaL+KLPPtY8nR^!+i=LNoWD&iP8RQU#>{($)pE zb>YAQm7mz16HW|W9~K$jw!kTZ#|6+>NLW<)l*)@v>i!puzDip9d2eA&T>7`y-xnhz z$v&q5nThH2P09iHT69Cw-Q^TTf8q?ghg3dwmiqfF{W%}Gcam$IBGMPQ^PNb=TBW2f zM3>#zl$`Gr5|{7w(}89ccu8oZFZOm1MAGzH{gkaYpfBRKsDeapsIK3QsMwfOH*kl_ zALvuT=y*W&@2#%uU6Eh6cxON*hVBbj?o`447tmRsy)~S;nmj|u#7AK#QRq@0N_k|Nr{ybc*w){FYf;W8W&96($Q*}w;Brx=x>i=r!-q>apET^sqUJh3D z51ppG)Oph9i5~OwB9WN;IB7%3zXRQ(M|KN;5(PgGQ(i>$1bQby-e5w7>K3~J72B!8 zQ58^Skqb)dAWvRzL>)`a%ZvD6=cW^DCoS<#%!bA@8gkIuX0d)kW?Bt!mEh;Gaq@U<|WQ?|b{*pfM zJY|1Y<5@($>HfH!zUUj9g{SbbNVjPp{Z;rvnb8*Icw?g;qyKyB+3MBf)iE%r!im8J z@!l%liZ?Aa8_s`@1b(|R=(URls+~1yi;7hS_R5)fq(N=G4@S`^sD~D@5TGu-iSwEQBmO~ypM{l z<6cyZUD!d6N+xfnz1Cpw>>}T@DoXzeczjRnE~-nXn@74z>fa$_Z)%KsWjwBP2dJ}U z+P+HcF41{tr*6$Vq0`zfl3r-J3wy!^XWQ;!_caxuf1Pq)(0V-NzUmYLCrJ~jNnJdy z$17x2ZRO8Lykqii36n-1E#JBwD^sTvpGn(<E5hD{X=hN=-=X8;u!yh z2b9}NzC6k#QAd3pRVvg9@;$V zq7!6%V{DHiyW#Rzk=+)?&gD)-%kQhmFLFnHQQAZy#}(kGk`Ix;0DO^Uz)c}FY;8lJGJhKX}V}9p)IX@ zDk+CH?$`E3D$dvs9;s202Pt2dDf~cJ@x6AM7pdw?dGQ}xNK=A*%N(p^@u;@tW{M2j z_b@z+XgL&qAt}U#NdJDpL3n^(b9oPbOZtJoU;H$6QtSxP1=^-Ka9cd_Z{=FA4>K#K zPb94#kGMz`W#$;z8I}6Wf1+*DVEH8DZ^7BGo4C}O;hUW!w(WzGX7F21kIW^(vl?3S z`*&%bQ6f5{{0`c`7u|v0_uFowJ1RFj#Yy5umXc;3^QN1f9_no(pXd~A(|9sP|9+gg z#s!I!GW!=~mZxnU%Azk9kVemW{q<4qq|`I=V{AFW2RZD2?O)I}eVc@ygu1H7(iB3T zLWyPn93DlNkIYkfBfZGPT=1Kxg2RpQB4*O+x*l?x=+mQS3}P-sI_e6Jyrcr|`!!D$ z`2r(@FFmr!I}Y%Gx>k#+bW?Hwc({inyTZ%MoQ+S&6p zWZN+V3sk_`Tl*QiLW|8fU9xR~#>;VMAy4z63!4nRt)kf7Nyc$Ehi|)79`$w)U^kI2 zkf>^?6M2t~fdg<{^Y@Wt>I+1FqylkE7ESx-TfQU#)s?8UU7YLGT~A1G%js4x5iW zp+wc3cp^uS2YK$*D$v`S6W-RRn8P^{!B^K!erpSMM;YU+t*vRw5Q@`LLI0&tR1ML=+`ghbQ0 zf71M;{zQN=QsxwgbRTyT^We`K_)46W1L^OV_XRnrslv2}zx)SrnJXl3qK#ic*U=aKv}+xOJTUGpGUJ{T z^^JSGFCF(BN_Nm_>Kq|~I%8n@_W$yu4!Q-t@eN*R+qMe+FlVYso%>_WizeC~UeRt9 z$e-wi;>+mw9Au$@cr|h$L$~Yk&Fk|oN!$ASy!HEuP3X-Nx8L%sar%71^m!+*tjWQ+ zp{<_9hEb_hZwGRkvv3h|A6TYR=X)3Cenr~0x44EeArRwXTn&i5ectOsm50AN6p|5!-tAi=FB_3tkmoKuH|HrhW#C}WQ3nkJ27md%|#cgBWU zVR4C}W5wNj@FnX-i{k3Mn6mQf`5 zYd+IAhv%tT_C16iWPC!e4{92*BXnE0dt)ng2;cC-G0s$@A6NK%`N#!w8%8!tDZ_Px zDpWtl_{Fz^u}oc>9!GXDE)g#@F_wnwH%C5N?}nBven#w&P+jk>4~6@mdvMW6hYIds z9HeaFtuuTPjnWt2xoyQa$oP?MPcVOMLKhs+>jsDD_XY5v#W^he zt#1h}@ykCrAE?~r1Q>f2xKBXizW%{Tta41X^1j>3f|L;|7{UiY8D4%%`w`k;qFx0n zz_(E9iZT*r{zQx1nxliPXE!}|p9axzI zzRNz2e<^jLepXRwy$UVqjo{n-0N++%D{0#v+?HX7F1s(Bd>ENop~CVV9tV>h;FCky z9kkCZ@hQ@_S7ZNOt@3%oJhl&|Qd$p4|M#ukcz!Xhf5ex@{8j9~@+Qh5t@!)s>oR6k zV2`Q?c7bnSXp!Yxq1dQy)_RVl>+id6k=WAZW6bNv@GXy}4%e&meR>?AFJp`5C08RG z)In8B9?zGT)<2>j1)s?@F8d_izyjLR;8gm+cfjZ2Y7d{t#Uya&^9*uc7f3}G)ms1&{~Rdy@=2|I6Fncb?^@_cx@RkB5`Y z$viv;zoW~Ey5GWHJp3>5zBlnR%zQQ8|C`^7m%of2JNSVxZ5(DS`DMWx<~(zuby-fB zeEDLRq1SZVYq`9c{(hyogZRRpfQRDu`%&8GC$guh=Ugw}Y}Pp$ml$_mOgt|0I_CeY zoH0o&c2sheGfscUH$1Hq+>@$G`=8q8>UEU*KckL6JI4I_-!~=N%-k^X+->n;+R1AZ z`g$C_eGOrr=s?D(Q;C{6@v@kjJ$!XK-8Ily^z<^?`8MWQq|~ z174b8#w{5Wr0m|?YM>>xPk1e9Xp5NpgbHNOdC|uKt3N{MHa+*E+#>Xm*odNEWUdsD zdDXT%m~*X|6PNyiY@L>}h3DuwnF~l>JzpVT(CgdcL)T-q&%f#E7fB=bjW>3BHlx^u ziG#O^f2=!!&$o$swk%L*@Qc-^=i9~_Xe>mqmHVLR;mUU zJE*sFRb1vZ90rAtIdQWd&AI^f!dnO4 z7r1MjCV09TU;AIS!w;TK@0G?^0bpZpM4sBgPn&MDIidhYT5d)~t0TUj0Bg z+UM-4N&Q=y@hdp2FFE`1@LC9K`mE`CzyDM5CU z1GlLvbXS$wRU&urZVu%i+196$mUqX24+}rU9;w`gJ+l)Xw9DB;dC~X67wLaBseir2 z`dg-SpVT(uzkHEC8AyC`uJkDx1Ce28Pm*uci3~e?2#pN$P0MgarVK;N^;#d{KP8{y z3Gw7nR)RLKhW`=D=w6J^8QO%#)-uW!|3gNdz*48%XX{)J-}t8I*&WnLKMsmMqoCpV5G7wO_(ghrfK{Je%;+IMPbp8R_94{29vl*5^#7%O^fF z4trkf8S-Vv>9SODR{FE=kp6Ux}?sJB1Qk7HHjote-IYC}$7rn%MA;?B&VuI|;7ICnR6aP?Y`|9j8O7 zPuxU*i}kPgL0tC%e2%~od@~~d`74{Sdza0;gSn5BxEeoL)AeB)*AhASH#bY0rKYe) z0)xm_bQ%7GheOf&HK8Sp`{(+9{d;k#r&@LVF=i>gi6#T02|0%(pcWrkwpEw}6mVHt=g6D9J8N(CH zuIdrrB(i*R@fRd?hRZ&lO05LfMB=QrQK4o3;-__7E90}+dwF`D>X1{!duZkS{OHQ} z+bOgWl2n1%2`xiY8dT{gAI;GjAOK4A3Nd*yZC zcN&E5d}|}*^?m1$g!Z8DzJ3L?|PkdYSYn(nHb9rnKzx_!ON*KG10n*6W zqQ@(-H$L`*xY%MMhmw~0Z(~jBf3L9P{qFLm=>9%c6dgwnSesxU!#X>r4>QiGel08L z&o!zEd2f*NDWgenl4m&I^JO`W_y@!`mNB80cUePO$9s(TT;4l*FXdhIZ5QuFywBi$ zBk$r{nCY`u3;Di;zF$-xgQqtg`??n=WgrV@qx01$W2TIM`QTrH-}@?P2(qU3wPZr~ zZ)dbX%_9D=ltsSXVqXA9g@@8lV&aq0y8Q27vpR0O(3hBZ)&}yF>jN( zxXGL5{oik~c{Oi@_ZlB?@#lBhdjf9P32w|IWNd7beg}=>*KP!_g7Sy7Z7zDb5xW+C zo3#+FN5$7J^S>Z@oK7YykF1h~CJR^`j{LQ`Xud)hf4D;slm>+5}%qZY_K&_W0x<6U8qR8)rUf z@?2}nlsz@qj{HcM7hcS1G-R#_*@zHE*!Ph~e+n7>oRb`8O%1t>$T%fy>eBbB)x-Dd ze)(K#Px++CYEBb&bX4@M_N%iOsV4RFe-L?#9m=UCejFUD67yLbfgW3D;XsA0Ym3m5 zQ#d@!)CC@lcR67jZ~T%X$J*9C^@@?>oLY&O@lkw|$Y7(?fo>}iUdXzw_T}wje-~?W ziE*sbTwMpWMnB{1kv&(5LzJ)Q7(d@> z{9w-hL@WDD#?eW+uZq3(S~Q>apNE_S@GRc%PO&G!*$<7S?#=8|bu}&x=%>y09UIUo zmOjO|0r^H+8D|PSn062O(id2I&Y+v->-2|IjP$4EyVMiC*-7esA-mKhvcNi-u5*97 z&19WOx7izCBi|V16xe$A46+6*<1ppyaes_X{G84!b7#kW8#|A@dQZjhn{j-Y1&O~~ z5_X?ar_j&W>{zM_G*6yW)s(yE^8EhUKN)_jgv2N2ANjiYnZ*Ys?V4;v-|xZ>#xFJq z-_cEHkl(8*uYoY1u+GXi?W65y=^yVi{p0NdzR9|_d<$U{pRw=n=Y5KAA~)D)X&-9< z9p<{|uk5w?Z{yGEoxeQJo`Q$$&tBDT5m893Jxq4JFr@KmM{K-n$(m|kN(&vanwIsdVEXK7$|&|| z@asp-=P~ExlAp52ICH z6#Gcn3lt*j6c6jA@}BvSrkJNezT0=kp3F4=HCSzxwuAN~?3Fks?Fqj^BKy`((tH)( zqsNlk@0HeLfBQqL$C^An7S;2|e|{UiG%oyMEE>a?QuhVgQgnIcAyYPW3cm~70<-2- zx$Et7)Y)z1iT(;Bp81s;6q{V+0yzmGCwcA#=6IxIe?^bKeGDGzoXAWQ^mxzkTs3HE z%Hw_W=v?I*-SBojILtOs4=0$(dML;nH#{OQZf&`;LcKG!KSl$d`YQwOaU9WPL>uQC%5Nv~H3s0Q}9huOa)d$rZb4y`9^7Z0*F!ucn3Q;fJ`;ETXBflKsW z1AHak8Ya4NQ=(}ueM+yj2#tBN-wN7?prt#Jo2zNj``ztYWyXGY`6hF1-~Rr@E@0NV z#24z(Cp7!%a}&t8;9+SK8}>5v)o0MRO4E1LN8cp$VH2h4+vko^F7`+Nos5;*7ych# zf~HpJ7uu4@kNCwJ)B23GBInpax5Eb+BRZ)wByu|PhORFt@1jR^xgO5TQu*S0O*T6D z%*B4)^00*RuciEmsYqDJktkKvIhL_{1yA0@d5ctuU|?3(rboQ zmLFz5GCBA-{-<&9+;I$@jbDg)fPa3$JOcmG8w+h8nvnR!+|!rNP4H)d_ufo;6?jw)htD_gFvAxbQ|E_DMHIdxhSqubHuewU%DSNcN{;^U-E+{SY6d z?0u8@n-aSVnnLIuS<7pLf3nxI(X-e2#(eAIW5PRV(0li2Kkbjw<9n8m^N^F8)cr#C z3$Z^??99aX)9XNP;%s?b@Z7wd`4hHU`37*)bH}%q%GwQbxP6ctGs^!Ey9vD}`cTg? z)8px1Tl@E_YKdnL$n<&|x=~=U&5Zs{O|tJYv~8)`t5&(|DqWZ1!3hqy zPtNQw*~NYx+R~1-vBle&--odsV@ChQ4&pnZEWsTaED*ac@mx+Ae@mXrdaK!2k=n|h ziqo{8A#9UBY{0Z zdi=;=lz3_5M8`K5RqhI$cMF^`=o?370%pBK`(N~44f;q?;`M!t^tvN;_FXkd8OPr; z^#zWU&lew_l67kZ9XaLsDrdWg(F1x|uBVehO-^}xfl z!PVLxmp&OSi*R7n`0Vms^o_OI^RXRs;7hQ7v|7$Gou>Towh9NUQ|wCy`vS*(03Urh zvQZubk12ds<9`?~pVWFYIZy^~4^=Pf?PJaO&gpiie|Ngy10VV&^*6bnP4l62c!t@t z!uJB=g*$6AHoynM39E z?-&=mrF-!RdlK+>!aFV3i5zJYr?u}#;nQY=-T|>nZn2X(VQ@CRw6tV zUM~4J}>n|(#M3a#M( z_q4<375amD?Ss5;)^b(kYoD#6>$CYOU4Xo^ z-f-;eGOpS&;GD>#d>{EfvWF~4TPCkVFH7DWzTd0iU}C~}fWCVOSRioK41DDl1YST5&Rs|>HudzpJWifdBe z72Pg-IwCH6IyeuL6q~-_HI-Zc0($v{kB1X~)_|RIVg~6Hb2+g|&LuW4_6r7n%Ti}KYh=!E zuC{Xw&c!9M$Mqa)`J7AETJ-$7MZJ&x)$@}-b_&^>J~r()P^^Vs>Nij{)q8vnnsiPD z!+Hr%;d{&{<>QZ#dYquma|D@{HHazf3(r58FE}$+C&kYqzTKMCpMO!-`jP$p@KgNK zvL`^~e2;vm&kgfF>Muj*C$I6<{P|tNlLY>L%8p?7?$3;W;}-IVGrwKFKku-oAmCUr8MhTVKloYrBc$g6VzuzbudU zhL?*h#2{D6LtjkN?x*_QBDHye(*)h2@?0mf`2?5%*|tZ&jDwgSl5_=%v_)3JWA!xYxhL&VP9njefko4$vXu) zvYt`TbAgAELe?y1A`kKe`7Y0FYQJUz)C9e5+MRWetC4|gB_DpOYdhiNb=B(H6Jj^U zc3r#wDLMbLDt*SQNPOvxPqWdLa?UFn9mke5=e(kVHw71>`_i)GJ`0_!74&^&Z`{m3 zUb}a3Qe@}apgY$o?dLsq=vq1Ff&5(CWb3WaX?CWjs?{}9@Gqv@8|+C_p>0~Py}^^X zncx~EE&^|>7z0a$x58uU*XPf)@89LDyXXIJ!T*mujW(+&vJwI33S$>sqxXP$v_a35 zE)zPUkFkykEy!+6&X^m2|Ns9rW7}Ud-nZaMea-@&U?cs_4~MT)1Ma=5De)<@_a=F- zYNW0Z-#s6HWby9`FRsZOzA^2yFM^(Y=&m>N&KNgW>2mEDP|fz_G16P#eBOz{KfyP@ zQ`#%lcQ~cVxr8sNQ?kFz{Yw>a|CRj$`1|qozr5p5jIW&*d>5=M7W8 z_5WQxCH2TyBz0_F#r*VoY!FxDynEmYu>r9ipA>qq9iI@}@w-2?Hr@q^C;w9Mfy;h^ zZNSiZMDn}$sjEuy^}hsDK8J*Q{w3a(dWju6+CR?BK|ljpZx)amAitSobiib z0~FCFN_6j%S2*L^$XSEAPP^C!BRdGWD~Ts0p4TL1JiEk*Nk#0Gw7~zN@WiS zdy3`mrGVSWoYrC8Id;9Q2N!O;1^=gvpNIcQ`(nlRqMQoW5Q;n;qko@D*|D@j@^I%s zRQxRcuZQZ8p^A}{Dt}vrUMo`C4~K4#vJMfw0N$jP{SY#K)uhgB)4oQ%etFeF@F`+U z49OmNy|yfOVK4^DnMQBlwDC<|wKb9Z^KkEie+~Bdi8t>{$={TzPC-w zNVBS{+%=Omb96iW^k|^Xs-iz-uQBq;-t-R|AJ5E2cv~uIsoN1X-Hv90#6YKf#llr{qoZHza3y#paUu-j3<~ve((#E5&w?^d)vnCch6pO}kI?TKWyJ z=5>YE6Ysc(HY$A1+CNKP*|TBSS*dKYr%5N8Yf@e6wG3++Mn>$9)JjLU8UpCCR@R$$GTb4br|uQF#L1Ea!k>BG_{ zvJX!BF>N@(`j+gc2#L%B4_V$P=-;y6gflzZM`HHuv)@8=fZp3U?YBQo8E;WW*p^Xh z%P1B*K>93v&67~pekHGz;mz0KjoyS$FJ89omR;I* z&{d4zAz*c3&*j=q(ukZVR?pFGC+#M*vG#pj`l$35Jx}=D^US^e>0W$*qU-cpw%E9y zz7tu|I)5zZ+@RR(=sMQJyUVfP*b8Xe>yDlM^do7z{#tz4x=r7t9dppRo}Hf~dwv7R z>}<~tmcGVa4pHRlB)qA%ywBJAi?r`uZ@qZ0*wC7$wjFw2(D!+v>!p7ZT4juj9df2* zejHsEI)L0@3+Gguc|lI$G>$4hd{g?)h&pg8Mvf~)zQOsF@C*G?A$m&24Z+|2mAx+l zTOYrX+)<SM4A@nH#MmPn`GX?7@CVubXeMv z_iM}?$07b-3VisV@ZsM>8=dmgAngNwF=){Hm!QGix8u>^V1J|A$m7ux)%eabd%x3n zUXV`9kQhxY@@h@cinFP+P$9ac(9?PufPp$uhxy_`e z<;wNQc}3R!wI4(75#cO^cWy}5qwrzu>;F9GwFXotXUse0ek5e~G1{inTaV$4$WhzJ z3-#Kx-6zohIo3CqrH19MI^^hs!t=|-M@;<17la?ebN?Ai?`)H-<7*tn-wB=`j^cmw z_9=+`v(}Jw8RO)9h}Tz*u1lqm=~m<~k1#6h^n~qNcPQqv;;&*oJ-Y1TspLGyLi}`s ze{!{6Q-2KH8_?@!zanX)uFT)QyT#Zcs$!5hXxwjoTKUM(jFBHZ5uw?$pGDTNBlVag zalkX7`Lg~c?PvV&p&44$wa^+8nz8+4J-Jly?cbs2N3|Ben8q)m@oSK8LIe4PhLDBD zSEhZ{mW~ojV^M$K8*$yXmXG@WuVoi6_;^_Mjm;k{NFqu-l68y(Xe-{C5%jc-n`z`Aw&|{QcNlf5rT39y)-uqC+d6X3WO-1n+{e zX9}tp?-bc9VE-FuzjmfB@V))1XDRn(b&PR9F+VqZ-0^`Tb0_t0^YYOmAeN&B0lK%DdHP3A&&7q$P>aWJAwZZKjY1D;twiy9pA1a3=uz*vS#-1 zP{z#NJo|Wvn|XxiIL{Q%S@YaHOjy7*!^Fumi+6c$Cg1zf{O@nF&pED{rq28`AakA& z*ooj;Ce56az@@-Mg_kfE;-rvcQ0khw)BJdO=4%chF9!ChbK28AD&#K{RqfIwaW4%TtP;p z?RA?mAC>(FJRzPucvVG#8-}#-zw)qwd}e0&2CbI@S>YNE5;}GReU0^;}gTK6+7413{u~X!^ni*J4)T9 zyla0vv=@O#r^Qp>W2S9t>ywfGN#1&?Ph_054JPdkIxXj@PkQO`jkimE^dCR%2QEYV zZXfNVm(u>{Uo^Dea1?&EdbB22aIXD5(|g0{f1TbNTD1*;E=%wIUUs3dkGZJK&Daa{ zO0~Knp>>3$p&yww!V~(85`DEkb|_p&n!HQXy#B{l=QULB3ZD_*q2}!>XEpp4n?~Co z!n5eIvI+S{oveR^m9`hm_dR@HZNASrt-miT8z*mteIMn$#J-D9Oxv@RH^h6s{hr`m zpNr>vw=HXIT5rs$r;Ub8ThFOR?!5W0K38A9xvYu&5on1>|B*8J*6NkXd!zI_V9~$+ zy>NFUdFYbKt+2#P4JMCv%K$w(GKHztx{w zfA$>aV%qO}Qsh$Pk+B2b&8eTJ>-vOC`=Box&~2)}{f+qWOPq^)!&%LIK+kI`cll|* zz7`p*HhuQ`*l-Sd%lKuA=tr_1b+^z74~B@7vF;w;T zLh;L3zpu_?)9W+WHK~1nVbf3A^!nZgU;1&{Zd~XbIib`ihgD%Dh)+yahK0TX_OFw# zexTfG&|~ErPIYewbA5D>_8ru}X3*RIt#TS+VJW_){B(0}+uwomi)x+3>Ss>=N- zHlFPd!qc*w@DcxAv@Y?J53x@67ca6V$Q<%|*?-r#`ElmGlZOAI&-)(T5%=0f^46sO zMBnpNx$C+k({dOR9@w@B?SF^1aD8pjBYeAjTYN+BJ*AFT%iDKpi*MNVkLyY${WIUm zXt(Tk_zkZegtq@|J4l}b=Oq2$J&#GuWlxGONy~oL*i@}TwbO0(z8=pO@Y-zJ7C6c| zX(uZ4bURkLv{_v29Pzv2bBY7^ASY3|CztUk$hV%Pe4op>?CSBYLF7^JDU0yL%y=o~ z!i!;%#R0}LEsH-RKk_*IoSNr;hr1P#OY!}fu>?MNbyKH4?{(V10O7&`QF z_E&{RpJ#JU)AvVjNuNSb$FP;!;d9#lLhi$&%Y;_+;(q#844!#oWhrTo3w^ZDdl)z0 zS1|Yzw%1OR{?c)7@&$_rw%xT;+&>kbZl7xodU;tZ-ZsA_iJmIU$o-f1u zYqx`ED{U2`T^ebZCa+!CGf=@gdy}u8PSRTY@S1cw>a1rS{G@KfN!oD=emVH86!Sr; zOWKci99V|kVcTwi`UY;rr;L7)_VawpBA3*8Y`V_8^V78DozXV3rOS+?e|Q%(GX5iD=)r1d}ZL1FSxnS!H4f)6Uq9*&s13C3Lgh_d$O9> z?v;bxtwb+rTA|rbEBw{vd2|Zxlq2VN(q}-#CimNzW}k$y*U-^X=1>=gAH+5XFZ`wT zm(u>td(HY|-ZAm(+P(D=*1q%@XXXKU``L%%?XMS`xCtHF$ohzsKQ_%LCpz++3J;V! zQOv?H`GTw1Jc2KM3w&pv@$mIz3%L#R?g*~zYn?|M7`)*b{qBl* zQ`SK#U&^Lk#Ktsrt#WFq%dTzAHg+5HPfst@q`vWE+Yf6icU|28U&gd9tu!_SV_kqY zeh>4m9I=yX4L@g#TwG!P_lWSg-(W3E`O zt~$ZkAbzdu*xOLdyXZd}%t zqz!9Qdv=Npo3*82y|MY{ounV+Ge4We{yjYKgcIn0G7_sCQ`_ylS@eIXekjNqku#Yj zjlVri8wR8F>q+&&XR3jAI2VY@h! zf@31L;p^6iQA}R3t;TJCXct_OlO~J9fq@6r?)qimb(wn{6D#T#k)HK4y-$8dV%EKB zJoy%ux};8#SNJGe91kcSP)6Auz zCr73A)FrmXAG~Jt`^+kzerFBqPu~(fD|`Gz*TO^Z4$8Ex1m2=6iorKXeFMT5>b86T zW=4E_|LTzkWO8P)>*jU)2r`5w4)VEY$7 z#k`C&ADk_kWS?L_+l<^}CcI#6rP}WEYo!0wJ=LtAdSpTN`=3J36>qzRd(l{T8T?%p zAiushyZ_+N^*J}MKgiw>u_IVhJvG4fMc&!Z#G`ZLWf8_^Eu*K~o>QnQ=B)&Qw-z4xEvFha#ii1JAs(!G*#< zZyq3g{W<+9!xV2ty8i@7D2 z>ZLz_#rEZT_F%}FbVtT}a2OYTg)O>|XTQ-=zdQ{dw$J38l5#~ZEnm8UMK@-gSui>! zcmF51sD)CltmO+GCI7&gpsQAd_#F~?0z5&Uya;}5xob^yzLbxwYQLbSk3Q<@D)7`e z(jTgPIMs=6LDmnTUv`UL>0QXVF?`;fS-DUk_pRnUxM-jperP{M&N%rC@Qq794H7!O zvI1t`EB4DnjFqChH!FNZDmaLqHuCb-+l@|R4+Q$+*Z8d@>I%r(lc)E^K2GHPgXp&1 ziPhJKpJKjLllrr}3}14_p7Ri<1-B=a;v{C`$9}RbARbgYENPo`_Krd^&$6A z!2`jE(1*8Et9bzL;DOd-WefQch$;B}+fHa3{L%V0HYeVGKkGRw8Ww53EW0nfjkzLw zs`lIY&l%gU+u4`X1kdt%7b0T`{Gg3$kL=vkf z!h@*Gxi#*?Df=ikB7K>?RJHWi>iQh-u2O!hlho5_=tupJsX%g%un(44gmiY+wW%j4(qzq z*)Ho5vgYRLM$wDnJE%#$IZ6MO-v^OB4Xhtc?`Z(O5m=w27&)%xuDI`2eTSIrYmogA za+X2%Lxc%$5S`7t>}i~U7fpO^?l^r(}kXq{S5m2Kk^c# zZzTE6DP@0u>K1f&RG+!9>*S)pxF2B}0 zbmg_)ROyx0dcQsJU)krdYa8w6?Q^)?-i187cj0B~{qNelptAQaz}v?w*~e(t>CGJr zP3gS^LyJGpdXHJFkF%B(2EGW)IR|~GPb=@@3v1-upY*k2&QK-w`af-_+ZH`9{`w3# zq&>y<)otwgjOBjUWf!;iZ+TPiix3&$O#6%Jw$3_t{@&VpT(4z@N(<@hnlV|123P~HhaeYfQ#p@oc?0tJIV~}?B2cvZ%=~kiE*#=o2SCFTqmDB z2_^7c%Z!2lMs%0<_Z#@_s_fq$g$J(a{PL69FD`pXoRNd-H2K8Vkuj!@^KRzeePbuv zd-tE#`+ekYM2TlV`}FzyI}9v)`t3L-_t}QF-C@=R*k^iL>Y;AY5pv$}@^b8OHbHcR zoO$CO>2mO~I%1q`N}j>xPSch`@LwY1b54(}L&!QO^~#eK}_zCruXllrwyF7uc??1t(467Wscq(*Ny<)(%uUe4N<-3l$xj9qZ) zeF-| zfBAN48?lGvlJ@y>uPtkzpBMey0VXH$38(|r;;nCsPx=Tf-Bu$hxBca8td1cVS{N?RoWLd^dPo~ZOACY0- zxOYhI#9=NbcT+Bz!gme+-nb`t%Hwi}{9v2d``oWPmp#s-C&Wg{$97QV_)Cr4rOr^7 z*xb~ab2xExZd}f|XRY7aJ%GRa5kpJPsKgJ?$9|^W^<3M+8E3?~D}(d-`gfh^8?7?d z!{Z{M1yE1a>s4Gu?Ll3#Ax_q5q(sK*)%Wn$2d!4c-FLk=Q%(H{f0N+F%W4e#U z`@cM;q<_(u^PYN9pRZ}XLcMlf(3$uz)GKpj?qzs0p148tGi+#7dfij@vwQl(*c{un zFA^RgL;qMiKLF;9H`Pmr-wMH`)A8Pj+V@RagIc`A5fJXPc`;K}E`nx~dW($@1d@HFx?@wD=^ z^K|lbkBq4v!Z?r1GsH8@vz4cirwBaA?~tE$go6%sIk6oFokpJ3JjZyx&o}Zo$603p zFQURowB0QAmNO{FP;O?~Zbn_&r=Pb_!o^!xQ^;lTol+b)yZ^<57vGx7> zPXFf6&IONadq(c1_Wy>aIlDfN{TM^m6!%Y`$gl_X{Y1I)8-Ds639=iI-y)K`1;sy$ zY>ACoA^BKee8Jpjl%w}pEd3wIW*;)V?1rL&g*Q}49+8)AoH62CVUjyY2JX;4P6Zw8 zFLmV3LVoYXkvn~ZGT)VXuFQ`_UieMzA#_;*b__a~->Amt;`t*?yef_z;#|;tdnBMDy-j3-#uDJpE-GvhAk0ZOd-|&#OGZc5!C(HVrJ@`&;0k0mp z3tr!c#`rh7#yJ9fm}io_37+$#{0Lyaz}AfcG!(?F*#& zf=;hU8|EqEsVK{(&EI6-9k$rW9?}kzc9^uo{8rJR8XWmN@bB~e^L+cf&Oe0B<`TD= z{G&W$ypIze;MvWypJ#$+AI~1*259f5*yf7~)1Fy(xYM4xjeTt?>C$a%WrKadA}?YK zDr6%aUz7U1w~^Z_@6Hb0k7zs2A>YDp4V`LIrawt2cY=-1caD&ru_CWo;zbvUEXf=q zy_Y|0&inGSsr|CAKHm8cR3-#A(6~k#oRN!XCm3!fwJC zp~yrPVLM?pq5LLqEnyR({GLZ6VIyG!zaLOCa7Z-`{6w`5TvY9w=c~@mcc|{oYgBx5 zpGs_IzOng`8rpnO4G;1g7lU^=^>Su-a2N9Eun&;m;}~4S{sf0HWv|${y^>T{Ak- zSMmOxQ}SDirM&kLMhUwKD+oIYV}$L5RfMgC)r3uiwS#_9pwP zb5-Y43sm=0%T@fT7W!tcYJ6%?xlcW>hMszpKAwx-UVy%SUfb)1grdhHoZZ%Uk^1`_ zKHMbt?+5yKabGs`rIA&%4SX8q>^x!h$Q#blQO=w3UWd>6IH8Y*PzIY`%zffk{ zEvMR}Gi?`Iy0hC&&On=X!+##fr#G(hYf?L3;J#kwn>mX0L|L<#)QgmsB!e-Q3n_y=M3ng#In$i683 z4S5gRH7D6)74F-V6TZCs4_o<94S9S_+rF2R{{kcb$vM#Ykg3bfp)P2k{l)G-;C*M@ z3@+J@4?%ukYdi5{7vXoRQ0`HcJtg83=UnA$mglbCXA)=p`xE)Slz;k~{oX$OJ8E#t zN4b9$-}{zNsevuOqc(53QH^t-hV-)otWoVAZBT@b__Y})qO=P<@0BrC zaP-p3cO!$TCVehUegg}il(uJ?m-z4;7yq2hWlS6Ah6Z{a?YkeSp>NJ}ItOm!ciXSl zvMc*F1AOZd8*STCr^kP$VH@eT^*WusHTTEme6sAR9a!pg!{c|%hmUpow`JyKuEk+P zUl6?LTY8O-wCUfLDZ>}$Vh>8Z=qB)*KBvFbx4%?u##xu1(=S_%jjEvW=t=xmZjLt}#c#=+*L^sXPso7%J)-~lir^r3N;AF=)};RD zH^nbV_*K4fPs0Cvmau~G>9QxV0sQ=9?MUovXe=5i*XxF6f9{p|x61C-dnf+Q#Rl>C zSFYE9Oqo~UU-=}y`tM>dd{>7d!n~0;uzlaa_I-msKmD6Yvd=5yH+iBYEpyR&qo{U_>8gpj?360^U=k3cpRA&hazOyi5GCcZuKs zF7c!95}$aN_@;M>uX>mGqIZeUd*}GTSuZ}mu5)R7Pfz!f#fv}v=}#~E^oJL%-|*<- zhP!GP-(FT0UEI~Yu5Dv?a|@nRIv!7g=k9yzE9+O>bGN{E-&KE4&7F7O&#U*Y?!3Ex zMg599^*8o@g8);|(i*S2o`hR1<7KHk;S z9FMeZ*sy*Bpz2y5Y3poT*Vfe&d1U>ju2%D{C-UjG&dv`$vVOz5w$?~dN7tvCJ3Cq< zJ?lT&*0oS=>T2m+zmW(H^J8_*8+tmLJ0mUa%^R9qdfKGmbsZbmHTSf%ORDBaxzu}8 zcV|aSb5C2Oxu<7C$HSX?+SDgDb$v3@{0JE$t?OGhX(TK%s-v^B?NQ34Y*-~pK(V9e z@yLd@N7^>DbqVJ{x9yRRE~+qbg8PQHmQ5Qrc6_SsGU=NkzNLM``mXhxHhNjo#X(HO zqccrNq-)c~3r6c%%acPz$n^QF6yd zzP7C207rU+SGLWxa6~rpk?JW+1VOTQZ&=^bws9j>WaHpxxk@(_#S88r-qqUNxxP!c zM_U|>dccQf+en)cON)On(%sqCys?d1yILd7k%u=uN}1j3H-MMrl3|GyaCcn*i<28zT?5J-P`lfQRH-d;6lYk1YDAz#BV0)3*MRA}N14V!bfyTdnueBA|4_ zd+x5kv!QH3DxOsFj(1JC69@EM--CfzW2ZHhe09n{?LUNNDD_Zj$~ zPYF!A3ATDs-tZ`=xvPEYz*pcOfR9eM)zm*6w;}Zi-k-lM)Hk~EDWLhqC zJbVzj_?reB4<4R;>G*sLlW!BaZ8~D=*#td3g@!MiN+#4M_$TnibEJ{9qc&YasShW8 z>7ZBOLrpeawZVT=(4_A<&!~9Br0*%6P(9Eq@Wt(vU&^ETuvhg2rqgXaIH5LDug*vO z#)CYTPaDZ6eAyWHrLQ7=yM>2HTgB68@Yq;j!pCg>$D$Ut?bChI!0Qj&aH|Qs>P)!K zmeUEY(r%r$yiXhuc(3X>LtPU_K35)_P#vcYJdbi$9#g90gvr;T(<{~9YT!qEY#1=% zBlR|{Fk#ys8zxQIs_9m$WzxVc2?_VAmNkZ-;DUMKVGSa&zbTb z=DX0>Tx`Oo3pO0JA^es2wc|GIwqc$L*I53o0UyC@O#}55Pvfz{s)u z3E$RK8@LSq2;OU=z$L!;QUjMY*?9Q&zhb_4$`QB>yd?kX^T4&!@vEUz;4=88l=OW zIpP_I)A47CxALLWpHb=)j63Q0)8JR?gHMs)%A-y{#mpq^i$6)c58nq)5TECZKMsB8 zeef~r_vb&#Y{~V-AIX9b1N-rrg#N?6^aoiPs_?-Fvf%wntvT(B-K9i{`hw2AN9qzGRy4r!AX9-}{2Ze=$Yc!)i`vSC84 zq}?=3`jzl(Ww+5AE5T3n%}VOMzuly-?<9TLz!xu&uak#-qG#?uW76M$LaF;~`S-^s z)cr>ceDM@%;ymCZ<=zi}Jw1Bganivr4MW#`$4O`FzaKt$<>_?!79KX~?gJ00|GqIB zLZ61=w+_Ky!h4Yy9op~r78tmWb`*T>Nm7QD_hoq#>K@7wICOwjfIOw{NtpEaw3_g4 z=n*^o?%fs!PbvQ{%9ro8w)`5KuSV0Y)W;`Gx{pJLq_6I=VX+B+`0I6_@HfeK2N;WmpUFi?zZx+ z;j^Uo_#^qL|DGaW{?ow92cKfQZmSQTf+tqL=<-go%Hgl?L>7D;-kkR3Kb8d_1s|&) zba_XB_xREu2Hx+3;oow9eFuSueDMdsf6RmTs%7J}`vD6h56hY?JYnRaa?J3#5;>H1 ztZcVok>Pix;#-}`9~=ILiox$n%WnI}0Aqf@!ae{G(a$_AEG=1#iuQhk>m;#fJB)SPv^!!xsO*go<@qc!)4Se4$eR zgYj7OZcO4M7N(tJ0j2JseMFA#fDbyXHhScad=oB(f1+0^!Y01lrYmo>aFGd@K$qkf zJ6VVIHnj241_S?Aj}2}7Z{->Iqo-`>+OXD!r6&Bygbkrf%Ku1}2}^Z-dsXRHr9O1f z(D~ur6RI>};e6(?ySaMN;#+FV`>?J5L&}tMd!Y?AKHpF!$YIGz!`G5J;G>jh$4w0% z$$}4O!IN1qe9XvyAPe4~1tW(U>7hRZ-jfAGV@CXV7Ce>(!?%p|+p}QgFe6_0>!*L1 zRo*Ede};gq-q8G^9W&C?9*eD>)ba7G^gUVWyR+cVEVw-jZq0(5fNj6l_0j$xD)Hgl zkd+>JSUl#7ucQ5sd+=VarvkQmbul>Tb?-3sy%1WP? z)&4cb1wU&?NcjuT0NZg`!>6;-p8}uOY5W&X5r5u; z_o{_QxmwKXlZD+AYT;oEcN5A3z0x0wC`X5TY}jMM-`sD*Q5&|K@YhK%<5wa0>2TPD z3*eWOvmju?TcKazTcJ~jq}QRX@79wRZn9y64eM-JWkcFk@&4ZMl+=Z_Ij`Vl)0>3HxEcvDQ`m73RS%9~eY!UEDu`33g7 z+_ft3jh3z(_gT2zh7k$(svD%qEb%yR+c&ESR>=pl>t_-kt>~ zv*4{+u<+f_&!H^X&4LqIa6Aj{$%3U#{pBN%8E|_R+?oY9WxE8-T5ysNwpo^mSQqZ5CXe1y^Ok zF<^gv6~NWL`lG-VKDab1e~CZ+UX@pXJeQdCS0^S^Uf9C>xzilpUQKsk))Rk_HStOv_qF6HIA23`*?xiR9&FYCeSc=8K;U(m)wzpM|Zfgd{nJ&C=_fiACn9Y0~<`=LX}{~z|=20Y5^Iv3sF%t#vj05X`1!m6Y7_F&z(O4F~!7y9o9BG~_OPm-Y229pATKh_mW<5&HSleTYAS-$!+P2jY*Z z-$gFsI}m>mzbAEk9pdqizl(r3pRPmvZu~y10L9AH;7h=lawc#P_S; zMaPBs)EUGl@%y04|EVd&cdFk-XAwVz_(uHJ^Wjtb5MQr;7XyDjwGZ)C_^tW*PYol! zLj5krIDBdtShXAaJ_)$+OBd~uF7QygecJ8SF8W1=uh(w3c2Q3m-lg46?RIDv{Vn71 zE$OysH?Cc@LxwkK7wwS0>$Hpd%HJ{V)@Zj{yJ)A3uhcHuDSt<`8__Px-Gw?*tx~!u zSGp)yx+qt=C|9~DSGp)yx+qt=C|9~DSGp*YZb`?&Fuc%Rg8x4*bm-?_$&=dO2mh}r z|MM~UcPsz84*35-`JY2yl>E8!FG2lE{$BZ`2jTzj!XlRUI=)--1MMGx=~zgmDRbe! zLHW!3;lEA!7jB3D7nQ$~;U7@`#e?v7D1TKC{2P@2rv30gr~Ef#tfFb{KL!7Y^52q# z|F@OD`Y`-|sQgRn;r}!3XZYVK|5BF!ZRM}o2mg%nFW(8eyioaTWANXs{O>~BOYczr zmB?G#qWpI;%`a>J6#S1V|9kMQ(ifEfy(93yuKbPX;QylXzrPaxKh}QKq4cQo-{->r zb>;u1^YEWm{??1|e_#1Od=zU;vGV^i(v(%}@b&P=mH**B_&=ijNrn$e_hr2S@dW5PURm&|CfJW`Tx^d_%(jMz`S2m;V$~N{BM;1#RCG9 zY>~wIQj{sGwf{8yE0w>j2L5L4kHi1V%D=4+{$Ex8DB2=kQT|XA{@uzS8HfLOmA|9~ z{=?c|1^?eEf3yPrf7js?SYyhyAK}h2qPQI@k) z`!n!=PWwmT|9$1>+t1D)DS!9?{C}bRI|kwZ2kq~G|KF5<_$2s;kn-Pl6#m6J4ayJQ zuKZ#2Rp>tD-+3JVwaOnt{X zKdAiSDE$38d_Vl3R(|I!{J*8sFs~j{zG+kRmnvMGga0(pTvPXAdW?U$_MmRXt1N$; z<^QPVAGG|Ru>3Ih^~&6D`Txf9pRxRJz_0&`FZuqGB0o*Z0?U7s5U&7+0XqR{z^4G82D}K!0J!MA2KXf4YSVuLd8nNFDu89Y1jqok16~FIZ=u~L z6{RGqvYPP0%}=vK)aUTygB$z%w?5|m{P1S$x9m$5 zCB1D{9~Jhq9Rj-+*>*c@!v{ZT2l};8i9Wm;O8hFp!(jJH$q#NUl`aN zRM-2J>CGHb`Cq!<*nybR?|-Iuu0|qyuJ1q7tE*7>o!$=_8>PVN$=MVbqYYrxeEaa` z#|w&{B|+=6dS;`~=KS`Dwhlh*nVsa9j!0=)6I3-|(#EHKI^dBKe6Y(ie_8X)bA!)5 zFU@1}%l`0YSf4!ep@);tZh=LMkBtvMwPj#nbFV5nKNG6@?3{Qg6U;G4GJcj}l5ul( z);eWCWbh`xcI%!QAVt)559+jaFy!G3@$k9(>HdOrNc6zgXE$$o;u%=usFVm&Gq?3Q z{ZTc*Pxpgjts8tiz6LaxmQto_$Tn-7Bp6TkuX$$6U`}#7z)F+XXjw9o=7sAVvYNV8 zGN~P4(mcDhf9n(I?!nD0NF~b+yFUl7Wr~MkMfATtp7&K5!w!%w0jYgl65OXXWreBU zV^0r=4Ri-yknYo4{}YlS;5i~4)-Fktdtd19-SFJt^P4un9*wqP8~Qf)50DaWd78#{ zTYSpj3-hUGx4zJ((mf|O3~b$sL6m`FgRwb7vw^~Fo}LXb5%eMza_2?DXbioQ7bs22 ztP+%|m!_O-#&geYd}8xmjg5DI0Bu*x*>m{$-uDVL2UzssjlU*QT5RauYST8cVPkKv zZi8yVgU@dLHKtng#52gJ>Acv`CzphRZr_5I!A=ol;^PoIq7{>u^qT&MSpmalDDy&Z znG_qIL03Ke*v7{n-`d}c-ojwOh^#NUaZ~^1)i7~GcX_|P-re;47L3y~at&8q5lCzB zc}0ReMC{+X^{MB92v5l6PT5SZK{YqZ>Uy>M$j1KXfgQ5v0t3~^>13NF-IhPBA+kdA z1``;kNly}MSQktkw}7WXm8?+zvctS0RtN_6kOPi zsV>6eO}SwVit8X_y~{8lzRaqucp3739ir@c8S*|mgaM6S0DqxjvIuF<$pBVcQ=o^R z--L1F9AX42-@6sPg>e9BuxEC!$@f|Rsv*f5CJ z`dKz?pc$wCTl$>$b<6ztPdE?5|Nb=@5%Cgj*f6l=vFBcRdehc^lH|J!%8>by-1$JC zmkFK>gk<`6Y{LeiKG=Hm7hFcki@J=ENoTtoHgHn;AsaSmV{jAXv|v9jx`cDz8Mq;c z2gc!60ldG$dgPaJZymD4g!4;rWI`Fm2{g=%i7AKms}|vfkR4#Z7rqHS%JUgf4(I~# zkNZl(0s!}fSN+F3Og@wm@;-wd?bwvo3P;{|awhZz-g&TY?HezytNYf>x`!6I>sA)e zv^*&A{#NsV8|wZN{jg@j@AnN1J=M{W6xFyYv8~D#AC~tRxtqjYLyuMCy)a#VEz0jz z<>Ol+cS?U_z-QVwmcx5br14;#WVO$<cj?iM@EcH6omWkjU^3 zZoCii9)17JWapUR+bs_Jc^LgVkdSFIyek>^;C>(Xywo!M zT|W$L(q(paK>0P9D1HypOya(c1oEC@9^6TDlKD}O-$Ffbf0vi0#^4Xq{u|PrQE9Sg zz4}B%SeHLwvRwS!V5bi&mj1~5q{0H7oJ zaVE_*xfSlRb9~3ZN$hp-riRnYJDB(ui+#tOzB_3O_ke{k-UoD^5c(MJxj21u=SLacNS2DaF;l$7TF!qh{ zWg>(zSb)1zdH+|V%)j>>?kt*d<2~6d!ie)YIh66d+eP3mGp5DeF1Vjw-|h6}ygTD1 zF5vz|i3_}M{B!=jPA=Xh;2QwxKbkn=oQY#@q#^ACPM$+}Nc9QcQ^#CFJL}NK zmZnW?sH4L=;=Z#^q%A}LMG?>bE7^4q`@}hjybgck-ZlQ7a3ggFS9asRre5CP z)BH_|6LB2}oN!Wz>(g-@`x+gGv3J%Zu3yLDt)|>NQc*88J|CCgYedd2t@=tX*dCwz~AiC9>8vZiJx+ppVDm-UYqjY9nknchVsoh45KdDsUXIuG%m_oT}{m?cjI?^{G3;%D*e-(X*eI)nk|PZ5{T%ka<2 zaL^oy*SYwcch_eQ{_?K;FY7x#d5;u3$HmYj?p5o?U9=pV1|JVY z`w+e!;q3ov9|uDt2tYuw)^u$WH`t48^I~io)qSUo@b&LeHC)smPk56 z`i}lOgZ^?__l7EP|6|x~uj}F+>b%pJbyI!&ovPtB%(-o1G3ZwcYwBWHE%nAjavelo z80>Bbzaz3I)Yv+wlcD1K_#Hi0Z^b>l2azU}SAL6EzM9i4zZ!GXl#!dvy+Z6hH1h5ZV3idz7kU;;HfK1<~^J+IgpE#lBE@;;gF#w!9P>J>iE zBsD(QX#B+;{BoU4(3V^@2Nz;e;4CF`1&^$^MY=dOpNKPVfNL_ zVma20T6asyU`ry=ARF8xmiDwQ6t3uK0FE~$wt;U(=8jxmVnmOtqDlA$;x9{++}CcG z_nXEO*^5IRYCq1s7sjwdt}O{DY(XbZ``CW+a!te=i&OE0?2m34 zJ|^%69q!y!X%bDfK)6KqlH#XD7up7X+FPT2ej0tD>3%))wvNr5MY+Xlp9tXx*821( z@ZGVQ(<5KNeWHltTU#H}@(=QEuYWsx(e86IfB5DT`n?)`>zaPoecf;OHE7=@z4uJ` zv`?%L=x_9+6BDYhQ*bl-_cZ*+l;4S6A6M+t<8VNa1AlWI#&sXdH!|2i8StquvkxF! z!d<@&I=+u_YqJ;r0sQ&R?xv-D`(;p%8RilDRJ4Ouozdyzd1Kab1!Gn_%UDgAvBI9Q zi{oY2(Tts>eb!yT+$)-~bHDlCRC5Bzi+v-;FJuVH`ZHY6-4`z7zcpBZkGDO z)TI%%0L~ANW748?ct2wwUr->tep%bI?VXyNsIyHwanL)K^-x-TCx}%*0&7xZDW1g%wB->19c4@i$5rm z@{Q1feSiZR5jp_e;Kf7}Vj6BOqM5`nPi$c`vFkq zf7GU5t`lrWVvnd!;=NJKRcGi9yf^wu=dRH;q5^VA(D_i!Riwvy;GDgR^uTB5Fw-lU zr*puslQWUrf;yqWjAK3B2OdJ**4%~r^>H7%vmNP!s1q)>UEuD z`_cc{7rm!S^*Qc%M%_)`q25PuSM;UIFJo>PnvF6k0~7KdXUKs$FHqkQ=1ds$2=#Yd z^j~|^liB0oQQr?bUE6{RtW!K{d%&7{5>>bYa4_>`191jr1i)yg1H5Pk?{g4&8f#XI zGLzO_Bg;Cj^9(dSg*@dL%Tm1ExPy7{PF~Lg0~nKUp-jp-rh&s9a78C@igkcLtNk&I z5zd_M9B@}JHgXh`uBv4<-YRVqA;@B!4}OJv^=ww+1L*mxPsp{S18xMk+7FlbBXJnz z55mtg2k_|v%I@-A$tOOD?<1}sVJ-9%pI9E#A$%k1P8luNy{F+n4L@=24*VWqdhnUY znO2v#QO=)?_*JAmr1L!wKhGYxMs9_F9Dd4qSK#-cE@P)oJAin~u}s=QrbW8v5Z;G8 z?=rY=w2 z6#qQvD*8SBs-zo}tT*F^HkAzK#DgYbtj6tl@`FvAb$%6}0sRuhGvp1SY{>VpHnV)h z1E;Ekz6+lI1mfBmC(~xSNb_23xgFN}Wx&%q;%`f0)gpmBHyP6UhPqc00%3@*KM7b&Y|E3S(Je1=zlpwFw z(e%M>=oeMaw0AeZ-p^t@PhfwLFH!o8UXfNP+Q97pWkB9s@8APjLG#81X^k7>ezS2d_t@Lm(;4Arhpu^i-&vP|SR zWnwMHIzN`JXMeqfw!QQ?+E-TB<$f>TmCnQkj{c2qT?X6h# zYBrlVB5H}VJhMUBm#*QaN82KVe@z@vEtwi3Z{Jd`4BdL})^hKiRNV4reA8`d_ zT5XS|4xlWS+Z2^!QHkFIWjOd9Lcj7G73pF0`B*l#3vJ)ETnROLfGma|VV^K9={f2H z9v$?!wD`WEJ2B5+13klf_Y&~KEsIOJcqi~1xHQT7ty}rGMm zu3F#`AiYD?lQ@-rO}6U<$JWZ{FduQ?O7h8fx^d3hJei$zC+hOZdv|nVY(atUd=}W$Q5i!-((Cpnh&xo@4U& ze#DQ<_J2a|M|aEiZ$cf>c9bu1(T$pOPcgV|P31l7dj9qZ_H!8PwW+2$t`W^CSNtF~ ziVUMsiA(LoVV#e%+Lm=&kf-hDKapdT_%`-dGH=)w-^2JIKgwX<&-8)MMLE0fkmY1{ zq1~wCu*!c6zWv61O{@9MwW)Pm?)W3Tbtva|a_t>|B;EG337T%{7C=WCp?;1M0 z9zX#VFq-bf*zM%pxaFSY+P?+979Syg@Y_QxA7T3N(8}i2XKojvU8q0Prgz4GqceL( zP!FDqb4)Xcw*xXMZS9r`l0DUd=>dIp2>ecJA?Yy19u#*txb3G`w5)a z-k2f|v7IanxDg^Q<>1jP-JBm&{N`2Qg8)7_@8H8_@gW3!2>*=np#%6Z6Td$@1A6S? zgnR#uq|3w!0i1BI6(=ZfaX-Is!2P_lTl48Xnor-S`ScFW>jIA???fJ$JiFoF8GbeV zJ9&2EB>8v4%aea6Kh5xI`1uX;^~c~Z(&3ZvN8-6WKKXZ39{G2<&LKVd{q=Ck?++u~ zlVPYuNj`P8Y|_*5fT!+tzW8e-&X z;Ay0+4d11Hnd&pFnTgMe>K(OM|5xa7f-RgOIbt;QtnA@-W(x z#rRi3e~q%Z8LS(WA1}jM{2Ta9*<6R~%jJ6Akd({Cv|O$p-|QNS$vq$CbM5$EBf=UO zmJErz!P7S&EQ+uixpxI0gKsLiT_#X&7Xp72(tH}u-1I)+%J7_HNqpuWfn#j&oOsG` z;yKT#uXLYE93q}`Ou1(zp6hQ&Jm)tIo)ce~o_Jn_Z`gZT;<>Ja+@~6SihMjbWfRX? zw!w2#Hu0P|YVe%6$ZrzQOYqGV_-*64DUW#0@(iAv@`&fAJmR@7PvSXoel9#WeagO8 z`_GKGAG<0%mv1I##7UfCq=9dhO$OKt(b@znbVBv1Dgc)FF~ z=^!Ni3~>81D*Yb(7M7eP-UR*+c~2$DuWovLAi3r5CC@wb)WgXCF!P6zH#FJ~z60d| zSG!wsWi{>m9?CeE>_Zt_{*Qs=Q(rieeDd!l-!K%tQSz2U56QYjK7)QnIRa%mpJ|u- zoha+%hQsnaOSd(dS5MjI1F8)zdEc*-vKh29xuytp|Hweo%9GezOp8CL1%HitbAH+1 zi1(CuXJ|@OP+)b$CAY?v}x$}I?ako4$knH=`i^(Uc zPrPut3G)#9#V;{#=&7!Tcw2PZ=q>Z@)u9#8S?=qI^DJm6ygKkK==#)UL1#c+IRPm!)4;66CnR(X$GQ~4!#{o<;o zP3Vs>XxYn>t|XyTFp&B6+&+!JgsnpM(l79hMOPe$-i?&~^=2LgueVXeaSkGeR(_)j zJV2-0hIeG!vX@2>hw*?~XfB2KJGXS4TN`+gxBzd4}=; zjKM(0!TWsq?+8*Sj=FAaGv1h&ZHDfFdFK<~m1m~OwrGpn_MNKnO-@R;uLU|l0~t5B zeRykLBp-|1N1m4HDPtH~8LHx0E8d-FJLLH{>&-f&uAu|mSD>z{Z;!KYE7{gG_Pn5D z+dchL))jJR^1bO##)aFzG{rqKdUc{76h zjRDGoK*PR|ZzK`+ebAA1{N^{4a9gk*P?pX!&^2xX>(v)AzDI!v*kehYE?%8-JH=f* z+r)eKY|mM)k*#~OCm?@CeIXb4gmCb_@KJSs=8O(MfU&s)iUz2q>iTdE|s)hAg4;e7ZbFh9olrbRhOjf6>*0f@VztKn2s7H!*R&p+{ z4vF{!Qii&41PL+~q7u$=ro&o(i97)6PTe|F=gLec-nvJ->~^!QLu@zBwzvnkXasfS z^S(KAEbp5z=&X;5jhkR#938d*ZVe5(a=fcRs}YlvgP zaWx|*&iy^im#OzEosV(MTP-7VGnh-gOH(Y%Ee@yRkCk1(obO_Jd3l^U@*G8;n&3Lz z+-d3{Wz+h*s_s>jCNA$=bJY*;v0glImGz4vkDFh=4iV~vyw~tD#N#uR_fiJjv;y*m z9pYU)_r;lM%#s%do#SK4jj zG<8Duj65;ck9A9oT{=iQN}Pr}qg>Sv;vV+|_8h=Ez&)VeZ#m@6N$+7F;Y@Rn1pJiy zG1ed9K7Jxy9)4C^_&HEGemt+wfnof%;R1fo6Xf70@Wkl^UG!x3TIVV5x6cWfe_|g{ z0pL{oAa%{qYf`r?FV0SPwSIBX=)MB4$2)M(ov*JBeW-Sc*E@Y(b+H>^#OsvA>rd+Q zA@J5|C9mwqxN~pA^*9MX*ALprbTqAC8rphbjfb_MPE!d#)7*z}sWU?Po5VFGD_B6e zr~Hj?xb0Z4fp@@7%&T17G&t$$lz=yJcq&M~%O0J3E4fh!>&ytj2*WCPY@#|BVTXPy9a3H`16nmQt*!)r<3?YShj z`|XR27Pb#tNn`=^YM>wUNwfgE04Cmb%hfp#aF%krcKw??M;!Z2@*Fifj66pz!bqE= zQfBuW>Ez4+e&Zb9&`MEk&N$7Q?(vc2k+H|K=ww9_bs~*yN{~6aiuD^G)wWpy_6$xP z#?J<{+v7FqpQp8(-?eF_*bSV{U%#mb8~1fhoQ{C;U5|1IeP|2TaO%T~T0kQJJp(;w z%s0#>2W#$Ge4|4D#<)5nuGZXX9ma7zi!hFB&YVM7D7{Ud+aB`iEY6%Uw^88zkUlXIE6tOGoAMOnotzt<|0vQ4u_Q=Z8(sn?odU38fVtIRrGrqXeJ74ij? z3A$6;^pMtZMSX+UZ|Jo?px1cKXPUK~{H0mLTgM_1e8ZtGsM?=HzK$7W>#?E@XQ(I2 za6|Kl`XtRi=FdsdTR3LUZj6-$yxY+R-uF9iFuu;??ZeTgm{_K5hiFfA!Ecunpbrz; zhqd`2>JA(XO~XB=fc`51nI3JId9`cjBaRF9t%JJ`aQ6Y$qPCyxU$^BSUW9)J`or>m zg?QT!_bZv;Lsh6hl*A#UT-n_)#Jd$@-A%3AAVbSg&pr}u#9AJrozKm1 zE3OX?gbL_VHk%!>0r-IS+Awe9k9vSEc{t!iEF6ID8*Gm~-ZUJf|1*L72eR3jLvT-A zA&_QyX^|IrBu>z^L8sw*ZjJw&S2g~S2?;|F;jc2Z5dNs4zV zjPTEpW)xN6eo!0g@!Nv83cf_P=i*Cb(8re`nh~iHB2ouv1SGE<1n|qGC+|$ZaZR`k z%fpu+L2o3VUi>>`zPyKJHhK}JjgC5(JmOG2rKYKt^n?3LrxG+muU!t$kwbdFKzr$n zNQb?L+=re)T#>bxsKUM|B5kJ3SuN#fSSthME>i(=mxKDO_6+J)O!+R>Zt5xRK^Zn* zoY4D{0C`Smy0F~PQI?DF#VD& zyWid}c?_=UN``X;^2B!Xww?_czf}o70QTM?@}re{e!^}$M7uFXzj5XY*)R8g*I}&= zpS=89?HmN1w&1NY@0^OaSJfcTD3&sZY24y<$GScAwO?xUk_woF}sZZ(6J6 zKyt6j@91)+{U+n`=GAfHIOYL$>)r*vL9UC*QmGRjBu7MF+561U3Gg{@8BlZY!&3hl zG8)*XhH8EMaRS!)Pz3b{$o*rV^2^`d2tBk*tc<4m5}T<09-HTId#ez@3!I1}mD z$fG$shgRdf9&;Y{jP?hs$oVZ|m5_bLe|%yUQ@2 z246fQ!@r=?n*Eft+toIA?yG9P*}4drbC|zj-pAp|hwyv5J!c_1=)j)KtY>D= zrOuhKFYxb`$`sN&`%H=caCI)sGac_Sa-PtDrsLXXIn?8~%jqs`m&jm#B@{@xeML)08Tw~IE*IP)IW zb9qFj8FTt@7J6Q%mvUG&mnq+M`hgb#bNLEov1TrNI1-u&=u3MZ(?6aEllVPfaP4#X zNj;Yzmja<$GlwykEI#VuPHEGP`OUGk$B=W~$nDJigPfzFwO7w`J)z|z4|p=WAo)lq z)=C>L;I{?yJ6DsZ%v^P7>tW<0vR1mN{ah5s> zLlNk3M5XOVjOV!07VPtCPayTw$DG5Qhdi$xjzV^(<7n%ZmU?{7o*liAX<>X#{-$5Z z$?pyWd89oA%HbJqo}E}jK|WP(yUc_1{65#^w6qnw1lhJzhdlPa<*cOhsJ}<&i}G@5+TylV zH}K3n&_<4ObnvvEJ)4%R55w-k;(Mx;Etul(@J+Rb;)u}eTdAvoH58FrmL70FM!`8q z5;$zZy!9)`)7I74pF1zb9=}~qV*t)zKFWF757)g$U>QNc@&;jN$GeF7;lh4zhW32C z&uD#){T{}#sR!d`?DsH+*#C-7$SBSD;r!aOdJZN(wJw>le6A+ zpl}2gl=|bC^Gd$0&X)|HkQSJI4sBww?~=Th-s?b@G+*b%L9K1Dj2;3cZo}*);IWj5AO~@y}bJxm=5L3`x;QrL8iCEc<%sk zXx950th5V|e=sk{Fj#3kTp?p+lqhxyHY6-d{k(`lT1v#UU#Q?GZx zd&*aH*F4Nb$`g02khU^4)tAikFr)Vo%}jrH5hy_8eFTV83tX zgV5`HE%1CrpnVwUb-sPrcGN51J`DCZx%Od0uzzzy-Mp`6&oFHtR?jw)_t5F)v<;KzwXoj@->mM3z}&ZWLO}zllMDtfPv;Z+id;VTZKsor z`w-rCI?47p8l7Y(;B4%2I?1wcevUfH+BQz=B$I#7*Gab9W!9v8{CvCVB+L6cxDNmS zL?@a0OXR_m z4)`K293aoRBAsN(k67c zNd_H0IR_lGo4I;2SZBRG*E>4Np#;v!0dISqy+XgyHKAE$J9Jh_uwr27R;{>h^3F*Zs~wfAGy)eM-I>d zk$M#9HNIisR9zd0Y2*(8mWTVJhHp=y<7$j9vC%b7Lp}ywt3$R9a(tNMrQe%S`og0- z`YavfTF}?cO2LiOi~l{M*^{IXcMWv+5u# z96<%O4ziYKd%TsLgP`qBT-#b|9pvNGube{%8SQo~hz!6++yZd`pPVm{_xd!off|s zW*Md|J5GhI+ADP!lpZn0Z#F$*v;#VW;mB2_hi+Tw1kcw0k9XrjEqVFXyK!yQ#|y>eyK$<{ zRZ71Y_q!Fm8|NHi9P5BJWeWABUh)L%t=j8MYu)7I)J;zRIdqdh=IJIM#+|qYy2*S4 z4)Uj%)=##1PUIOx~gPhw+}? zn+;zE?UOnMMn5rEM_JLkjGSBfJnAg^U^#X<0sN`BfNEI~Lg_Zl8?Qkg$Fj?LOX(=v zb4csZ%&DX7&mW^h0|ZcdW{mjQ18gv)Q?R<=ffAO)>Qbri-`R-QT?3 zd$%}_ciP=QxRY8 z+Ya^Lv*n9>yzocAo@y3C+|%}@Jx%}mfA48V-S0UioO>ow-rr5#wQ3A^`-8sy;Yla; z**BFf#H!`!hfz_BxQnfOoYS%8xNkcl#Ap98oElv!IuEROuy1qt#wy=s=yX5!J5s+) z*V*W-SER=#xwo2Np3hzir#|s~GhPv$)UHE<{;!yYO8I)6P)q&}&Y46tZG5_t#*1g$D+A4hZ zo2Y*c+KT$1Jue`y>n`s8(y#p0w_ZfOoL~7%+!eN_qd}doeYlGEgSij$Zm>#aV<~v| zm#B9ab$>~wDGLRqS;DrV&NXbi``N#$O8?mpVBa2oVQqHrFS4&khr+2+0KL&oA`}H|L^&0>OU}sf?cf?UJjTanq`i%kaXolgP{t^g#DOFlOMa`xJ1P@aaMv_Fe5doA|;1@FaT zFP!sUtooh*UhFa2fKYBlI)S-x8h&%G$hTwn0S|Gnb2v4}`?15kqf_E5#)J2!HpQ}8 zUEVS4Z63ZWdnkbZUglld{|9ftU&Xt!z?%RZ(t1=9hlo$_;7|@vr|{^f#35~)AaTgt z-EgfqB=T^`*xp?u4*g-p)#A`sU&@|yU)1+GedSJXjmFv>Yko{sl_P6xg8n_!1cC+Q#Q;dV0A~!sQ@DSvXugN!(D!JZap6$nc+{ZPX z@9)IF^F{ZiC$L`QyYhQ$u{Y-Tzz6WnT=~7yymCuXF5+hW-VXge`Cf_qUd^guQH1wR zBY1}sYfyHic~ag9Qom|Ao5foul4n_m^)TM{#rE{q#9gQ(-)L#ae8fHn@6O&PPH~;% zI`U=qzka8M>j>{dZR zM;pw2WQo1uGYDUgaL7Qsd&+Q+ZumIDdk`M6-ch+ty{VHON7+Y*A7vkWN7|?QeGne^ z`ylYXAIf~j0Vg24$zc79Dxlwn5M?`gVJ1D>PCs26RC@3zv@yTvE}NG32BR$zyaCji ze)*qM>51=2KGwV)#rEJWhO@}S`wXUZ9^5S)I*vSe_h{BUhmeQ%?Yngz^jT;R@+9ZT zvz`1C^7OdN&#-P`@U=C=;AOQAQ#biSgs13&4=!*1M;_WZ!{qxgK2h?eNN;G>2a%3< z4Dubf6FS~OyxALeqHT=tNBlwBj-$*9%oEIA=K^Fl-uS_;X%Ws_YW%SaR~7O$&T)(t zKwPu{HIny6>&K#M2R-hj%?Ekf(2sJdMah z9A2;UU_6`(gzwz!ToviT@*RnrLdcESyZeH;_rg*bKt@Qc7Z-WP#ZEIJH0 z2Qpp(s8ex^T!bB9+38Pk%pwEotTdk%-H@`rb+qtXB8Bga0uG_v?%BZ^K$^3_?@VDD z(jVqEZf-fC$GlrWD4HBTO}gnWH}4VOAb_9U20uwpFh&U-51g+&g?QYb0UCsPLfV1& zn2ra2S56|n$BHispw-(uMCAa^67_wr;db;D?mPO9*$-C%=WBqkOA}*da!!I@2VHyo zE6CSNzg{bfKu5V>EJmNocf^}k{0{F%m%Ih(7uR@o|5AuNzvMNr|38I2R1~u3!>lLw z0=NV5H&J%9S=MQa^p|hc$vW|@+h0o-?f1tov^`+_xSs9?90We>yf)ytF|ToR%K?ss z)13E5csFe*>fUO`Zc)28cC~+<0-fgABy>E+Zc(i_b}GI|j-ASnv0KD7NsXO~FAf;H z;SRBIpG~LzzFA25iRLxJ;{knxc1hemCd5L_7Y9Ej^sCke+ zt*-&}ymf5BInYn8uZMhkzL4!#>uYeH!^p$+b-Pc`7jR8h>uYeHVdUZZ+LeBBx+{)* zJJNV_5dF^g+~iuvvp?W^IdHxaXIJICgB5Nm?v3GHa+G^bbDWUoCajaZFH($rmNarf zH|}{P-L3|G1N~pn!8HLghtpgmkPhR!pe~pvs<`NnRZ+luG4dR290LTNsNy7K-|H3N zs$lt>VK$T{bAK~E@t3?5T^m$B&<@n~P1om%Dz>CWu9)Av$H=>;$Ezh6Jtz%{6F-hP1{5eog`tQ;AfIQ?e zNmm;EIZ$>Cc|4jQkcT{G5!M`x_m6kN@3@ancQxV7&-XorJ<_&I?ZG%&*6rhH$+>_& zWnb(EOv6MM%Yaj%pkzY*W|$2n2XcQiJ^PYrjBBSai^umu#yE+!@^dkPy>Hyb9mk-% zd!V;G;^S>8+uuz-p6iL-e&pwvbo=;PIxhP+I4#Gb-pA8Y@}xbplpE3ep56{o+Q2>q zjX7v&O75EVraaeId%)6oKtB>U_W+J%ao-T;Ip%UGNxuR7#=8OjZ`-fZv;QOyPS*pI zj&uz5JM2abza1S#+a!Iq`%CS8q5~Q9b%!Xzz0@*2)~;wD(o5PLkUpW)N9&1^Y z^k35Dfb^9*eT|&oM}BgE^)qAKdgLbu@g`8f9RJC%kB?=UfPN%THUXH5r0kcZs^NP1AbqYbfT?to)@;Yq?T>v+ykFy`XBvSQjI)vo)_jRK4;~b^!v2< zH1f!K9+2m-mFFn)$TZt-Cx7K|?zAO-ydL^uUccgP(S=y^>eb!YKd$Gyt}O`><3#Rh zE5`n_qXB)4dvLOcK{q5W+}k5!O$n5NGop=8A&phOyW{p$TjIh6^NrWOCOYHGv*+*3 zKrXY_N!~feJGezvdJ=EQCd?f>IN#{uS{gpe`V$8@$6JqFAphs>MbkUT(>v9uD{Xb7 zJ|0vI=i@;(djYGl0*vEPz!^X-fNLV&D7nz%k6qCS`c(3``F)xgE9zyP(0?KJANFaz zIv>Wbs2lm@-ZLOyz0QYqFFWOrUr{ac$h~J_p2!8A2kTyz?+-YVhu{3o6y<$uvpoys zTiY+qoW#3($2&yiB-0>mpG>RiW9yMOQh9Ud4fI(>>)tmy{XSc8IKR)(FO3SE(QNjO z`g{ONfd2U5Ow0NX^-gzj4YBc{b=!~58yv``gFl+`>##5pPzTb%2>|Zj{}H~IJw(8_ ztJQCY`GD{``?pHV`TL`NC_}or@ju$9`s~LC{P7QS{AZcF;XbyJ>ksmQ@ARl9vSi2%Y3_)7Kuo9Q)yR@UT2f z!CwD|y>Yw;i8+O}EVLi{e)6GM1M$AaqolFC-|mM=Up5e`qig_az*B@=y&nT!J-Qda zQ`9#FZ;QL<`QAsU4|7t|56v@|LADU(J`(v$a4v^=9OAo!{ALOK_5Oa`Ijhfma94

f`uQzeUV>U|uoJY9&R`Dbfl3bk<05fH${^La9O3>3g!7{uU%YV!+Z4EsLoYs(lKbGXnL`YF{o^ve9r*Gl z;#-*Kb%_%wm;P_ac@dJ-|WeY$Jo%3{&;Sh2j9k>_1)2{Ek3 zSjnyM?dAA(ALUL>J;E8%cM0PjzxKh9laOv{LO>Tl(x~+3q>ctuBF(?6_gY2I(0$WgoS#E0 zr5qwURJ&HvS+pl%*9Co526@A2xRg7bgv&bz<(omQJNj`7^;o3nZnT?zH3y@ex-L#` z|2~pYbrE-{`4+9!zi&mG&NbD_dj5+V-)PjQ*SJFyG+Na^TjkShSr?Ai3gkZkcM04< zUFI$D?;-x7?PnAYmT-TBzE(IG-;#X;cY`m*m`!qCCgpqM;j@J_SI#reH3E9x1K0A~ z;rZ$8xO_j;a^Elvkl$ci(Uw~5mriQ`?eHJh{$GIqDB`PkeVn*mjPVz^|22DFxBDi< zPiX%Q@Q*^Ki8)A_=A~)7{l4s?IOEeLys2DZt0T`+Mo>S{n&O^o1MUf#*SNXmKyDS% zGR*}2p!1+VBa}tVA?J)x_6VMFrUm#| zh3~=5o`sw6`Kd?)$1yZ+Iuu;``WN$#T)&@OI))K)I|d_eku+Ir<|UXF8NwNgfpGQ*=?E8&Mw-jCbLP zk9X0*S@7;K@Z}uV_0xbe7Vx(L%u~;A!gN}Z0S?uo47fIU>6z}dE_W2}cI`jYd>>^9 zA)Eyn8BVBY?(qsWA`f~03Lp1E^~f{FScC-fU@RP*Wg1zIb7Ahjc8(zr`dZopEM`4{ zQ`94037&og;lt_Af&Lx2FpYlqOx0=3nB3|Eu_66V}+f4jki9+}5e3%b{vPjjx!TENxuYixBv8I2;sMo*2d04+9 z2&>g$jXG>O!YYaT>HGd#^X!*I`YQr*1QA2H z;nT_I7(P7;`axd2C;hwMoBiw;?=ny~hG)Lin`s>@-Ut3b>GDCxNZLO|@U|)5l{4!; zzNy|AM!30SZphfldFNL_ck?)yS2=(+z_H*hV-rx>W&Cjh6e z5%%eP#0avHgPgNa6;xKZdf40 zeB6+4PrrN(xPkZX{=0yD?9v&xM4g38d{BP!6%{%h?^}lZu>P)hBXR0F6=OeBBkxLw zE+O<+l&;e@rRxN|DQ|j0u3w$ppQ0S2>m-nu`=3*wHO5ZN)_a=LX&uCC9o+0e_=~ho z6?LFap$zKH?4jNazC|4<@T8$BOLv&^5oNzb{o)mP7juVr7vE3EoVN7(iYg1o&1nZd z+R%;PHjLo+JOS*NaDPAcy0Fs}2hdlimCV?a4M6WpSZ7v6L1%v{;1YrOX&?cA7oZoA zA7|3g-R_nvJZb$3?bsaHju?K@NyOJmUNEV{D9@`$75N#F~WE*E%-`9>#zd)VV`i=xaTwzJ>A! zu@2|!YZ-i;o&_H#1MqQwE7JH8?F7U2e?2jm3s(`A^0Hq=a@e=V5b zwbH-)W9h}F96oC4S-+n{0lIsolR}gp15Be|;m!t54>})fsskF8pN8ur!;EXk3$B%7 z-9yFqt=mFA>f^)f?!>$6D`9&T>iQDn;%(0lD?aL@Rg^)}4r}PCj)tKXu*K@>fGyTi zzDE;@pMp-qSPXnrQ6u=Gs-{}lN00H0rHFDjwPqbzasu)q++CQXmsg8*3o_IthxA!Z zar(dfAeH{Y_fl)KW33%x$vKo?>_*OUeJzLF;7}ZbAJ&a~n5Gr(6z8m3KbMeKcW4KY ztE;z!Z{>uv&EE;goTDf=qrVsNzxRVn3Zx<+E7w~c2xsF2X2LXEkImlKI7VDTo0VB z9wbf?U*#Df@F#DKH4k4vmpq=yyRR8|sCf9|0Nu?S2ZXSp8f~&+e#dy7Fg(*O<~`## z!4G18cT0~y#w7vte{n{L#XA9`FhNX!?x0-~+SPA{%>^=T3-Sa2^W~56uU{Qq+SJjM z_#H9YA#NTeZO}Y2##+pAr|Hf8;8WCFN?yO*+#SbaM!JKwsXFg0gZh;%;47(D4Bg6` z>q%oI4IImo&!J7iO^LCatH58K0q=n`m78ms2K$O(%HBbTpig;Yx2$9Cx_AxvSBi7t z{JB^OdSb&(7%v;%D)?7*t|@0-tUBf6U+Kw!b^%4Ct~~IrY7+9q;|eMV)o+H`P?^d7 z&Ge)#lFz4W0rUNo_$SxJsv0%c7tXGFg?qcI3Xc~$a_KzA{5tSLWfuzjhHqEea3jXt zhWQe73yuwVnZ`$qtksvV$9Np0QZIn<&?!BX6F(KD1y#!2Z4BG(-Xx+yMG*!~Eif zzZO-V&ZPyFCwyA4;7lQ2l%GetFr*duuks-7fImvW?>_!6go;5sOr<40Fs*Uzd_N^# zNLo3E^`AKQ?km(0{PA@f|3v}gUxu-_A=d^3RoXv~Fz%24!o2Zc zXpR4(fblQI_(L!+$}s*5F@_zfR5v7%0zN_&?iLj-WcKDKBF&Rj(kJ3aDGJ3Ldp!q8Qg`73TWkYXgou^BUJKCx6_pay^jqzM?w*3f6;3t_K&R z)B`3R@Wy@Yhi570GyExKV2~XO^aEsIPL+JK7_vVz-b(gVe$?-m#R2QT#AV{MfpPdP zD4&4%Z=L{pfid}JaU5<*2i_Xxo5f0Qo2}>&WoIC_#XD(g-=+1rDWis-b=fg&7Gji} z_Xy}|dpcb+`;qTJVc(t~vHKRhx_Se;pg+q7{r;@#D8w_bA7|-L+9}N!hy%?%vOg1W z*`IOKpRIdJ_aKb2)LPT0uWf?<`ck96F6!?59Q(C&Ft=Z)wXWO@p zg5KScAH>nG-ku6LTV?BK<9nu`y}dH&8um#Re|OV?tM6yY`%MCu=K~Dh#x&km^Sl9m z@2ze4m!)@1bB}o#_zInVVcB)w93cM@+tC&S>*3!Cs0B0v(2YD(Q2Zm#6nZ*D$!Yx? zXYwV}u-l+MO`i_KnL^1?gi&86Nt+I-YY#b^(zXB0r?jqpOJZBec*c=uou|l%pxo_D zk9;*UpSLFcdzU?b^f-HSlelK+Q{lTKB|K}$+e?>Ju#e)U(2>hff4^AT3noi>kHsyM z0r)d zl~=iTJj&_afl^q99kl}Y!hL)gZ&QD1-MjzcMOClj8OoU{ccz@#zW<9d=e61MuywHZ zRm!jSRmzWjRb(7z`3JSF0p%>%gE`U$N!uD&Yw-W<8^)O$WHsQ+BJ}I?sK|PpwMCGZ zx=u6N{hvU3=A{miwBeKMz9-lIO~{!e)zBqH z-C&DAx;hr2oZRLG^nHg)R^Eq2CYAu*4LQ(-bE0zY;jGx>4GL)N(tx`yF1MD=3vHbQ zP7n^DzaW>#8n4zeNn_#nXe|88`g&%0lU?Qs9n#}eGO~=cEp(85tok>U^2aLF1HXPN zFqFi2Lf+5u3?&h+&(}jO@awk%@$MVyG4iM^6Sh|8x>zp8ntS_7{hQ^5TK9%9=6J7F zrD0j1)7i63k8wL=ubo&c4DHEVE1g6B9IXkEe>n|8%=Lzhyc&8TqbJpe$ zur`)qZJhSox9o5L4Z?m!*Z_(lZBjsE<$1gpXRVRj@vVdY8Y%YabN2y%jTF1}x%+x~ z)-K0fWVk+HoG|}!HVys|e%g-2o9;AcSYkcGHD2H?-*Sx?M?@9zV%NQL!S3+S+pn7??}ko4!;ir^gEzPHK!y*pE1HM(ir`LC_}r(K8ESaMvx|h z^|A^OQ{Rx^!CWp*x)Zp6=3kmq@%^A_e*xaEN88R6hA*IA#M1DXr8oAl6N(J9 zXd9uP9Q&Y9MB4|QR`x-Wj;4ChfLC~q?M$KnB4)3S{!?d36(Z=}z4k)>7dB%;o+a_# zQq~FQ;O{o~)6mwa6LitDGa|j zl`2Mud>f@rHu?is3weG|eJUWiW4E4h9gf!>zJHP#1Vw0AlIm-bG_;3|73;88jQom1T7iEl01 zb)WoJKm8*!(%)m%FXY$nl@W|H`PncsV*HweD$su*>9!0;aB!lYV2T7b!kHP zCG4p#jW!`X{R-yD*ri_CkM>z`zmWqg`h~t!I#LKXy#LVS`RjJHv5;;@cM6dM=kVKt z`K8;*Nkg}zdHN<%OW&llqOe^hdxR+22RMlKR9_o#U&Oq|wadwu13$9AP)F(``{&k? z!u_8+IqzZ^;}G|Gv*?@Tjd8EVn-$3V%c=|e0?QMZC=a9_4%%hh`5j~bjHh^@Ddx!} zU>{f92mwxqI*3HwA zTYq)qFVBUGGHU&q;o%?l??r>4ojCi2{#1q38&_w<%CBS@$`4tF7)H8IS%*I8>8+uj z9&ixy5~Zh?P-W2% zMDG3R4|sR1oAj_Ri%gJ)?HVIJiyXZ^_**euIL^*t>{~6M&AAP475oiT9&BW4z+d}5 z*abndZQ|=R;52YJ1K4f>e;WXK_xvVIr?f0G?lu^fwMgR;SXCi6q9} z>~kMeHh_{|EhoKFGMW)dyI^mF`#1`028>)K*XB>%z3$umiCJv^gvW=yWAir!ygC6m zb&ar3=QFNdj*p+x=I^0oAsxFvsraw}I;PgZ>t*w2?&YVoEJUYTX z+<3?459>N*X^}YGX$AD#5bnwSZQ^8l;DpRe+^|4~`M4q1xV6`S8$V~8KXv{<8Neyt z#jW?wv)TOVw_BvmpOHab&gReDpN>6;ch2D9qdJp++u8it_aptUX!A!o4QUE({wPyY z_p|>zZ2o+FoSp?ACp)l7<{kt5zrjb^{8{)or_G<=Hf8^(WKBOmo4@`5o4;;t^H(@m zB0lZbHh&R+j~a9?vJ~r{4a>lD+OYIA;^zr+Z2mf6^B0FL1Llg-vr=brOKbi11={>o zqCEg<^9N^%3pfrq1;D<9akSG}((mcHj}>14euOQ(M!u!!-GL5#lItYWgv>gr`r6jL zZ~}Bb%Rv8as7c|N$AbCg@r@2vV$ag!P5wR+b~Q^U{XPx_=)9C3g00_C0Qz<5`0S8l z@0XX3Ya{a-*DlAGW$mbgP`0gYH|_i=&r zQAWPKpS)X#b@%Q4&O`39B*{ICw)g8`-ShBO)_=ze^(LQwpFT1>zD7n1_iiN@AcM2u z)+x*t3*IXDdTXpH2VZZk^zpT5AfR1Qw5tjb!;#jxYXjmb^BUJK=X&64btmyj+E?(t zPvDLecpzo#_fzsfWdU~{>i;p$sjQ8Th{&<%M+<9QjIT!B%-MI$f zcr%}I?K1rFz9t?>p6A?ffqX>#l(h4^cm;NTQyt=lGsF?O4jp-ux}px=GWYf!QjQcr z3#gm11L5%y?&`^iciFT+=}s>Qu=%m=Sm?i@Hy7S2xKYVBoXt53_~S}TXMVw{LRwIc zxm-RCIF0$g)7MR|Nbq+dRDeeK;aZOwxWO>uh99THdUrf2q;B#$NekL`^PG+P$>fO* zk4&8!p0ANtRyxYK6T`a?W04%^_~aGY`dtTJWKqEQmto9pScLJnVV=j|<3$$cjsHSx z{1*j`zqt#g6yv`TV;I6166iM&iTHjKW?ZJ7Z7pCLpEg`8FVebgfgFG6$Y@)?1=D8U zTeg0=>jCa!GJEk3vnPg(#H{~?d*aG~^*=fV@r(rvu>RXH&tvYb{}p-be}%RF-w?3= zmtek^V7yDP{#T4%8*t2-*SK~${+REmz1BT(`FYFEucE*PW$cINs8?+1M?sIQz|Jpk zyzTd&76+{V5|7a?&mD)~g7OUL!o8uVoGM2Xor_rJ8%>IVbJ>WS_nUox1=#zpmVV z&9U=qB#p|m^J_uB+WZOa{5+Xqhw%E@+oz~Ag&aG-iL38tX$vwb{@1kg+a1u}?P!aE z_3(3@0i~JM&TrDUVJJBWo4kBGzj1`kV(0h18!S6NH{+-~O?eg$JHMV;?EI4U{E@nw z*4)H68#}*H;Xb4i!QO^Ue;R)y{9{ zW!hnEZSv@XEo-h$7S_+fI%-34HR@x*TV-9vy|g*JbdjY~cWZrNyF>>4PFx&?{(i#e zrP-dML?K9fKrdX|`2nAq_lMHW%_Hsn9FD!et|~h}=xrRl&Nh4_kkjb%C27N_&d$cJ z$cB$LUplX};nR69XTx{*=V!6uv)6gr@JX6XIZ_`MkN_J#A0G>B_?Daw7&o&%8Fw6G zXu~9a&lmhWZ20t8NgF5_w%mewUei4JKzS$EH1Hs_;S&KieDyw0 zA85l@fp!6;4If--!-sa4VNEY{Ra~GApU%g;28#QUe*zFg-s1>IvBsre0@9c5M4AlN z!YV+_&mX~jz7`w4CG~kWeBSy3+GA|^^4E}Ke!skJZ1}K_UKblab7#7LMg)7FLf%#c zoDmh+@ZoIudfD(TnS@Qy)!6XaYml*@3pnelm@MScEB42QXTt}&o@2u|GBmpl-(a2% zpN)&A4gvdw%i8eCu_ccbV8ch73CK&z^?91H;VZvj*~nQod?)JjZ1|2h)l;wdvNn8b z{ZKZ1UVXqj%x=T?3Uv^2Z1{RnS7XE1ZPm}R;k!MqZNDyO!&ePkFteu7hEMZ41vY$U zO`{E;=5=7}5p2VERDV0jhHoFgXUV9lhC9i-0yiK}01Y-ad_m*;cDLc%$vrgAcF*hn zyPOSQu6$SbFKugCyUru1vql&R%Ap8a0!nL_=NImTbv@41wZ;!MZb?+s}Cy}>KA-|LY5Ehh=2l zJo`Q1Z-M=u!QTM87iGV9nEEKNzuSEU_Io3=^9!)w>qdB&w%^N8W@hQpX}#WD`iC@g ztZ|D1=wH50i*2_@|2*T5x5mwByLYy5Uf4PTwtM|oYrDsHeug^KJAEBOoNReW$(oxsEju-| z@}pIF2c#1`7T+`|g010x#;dm)L`T3Fv2SAla0yZ_-U+vXbRT8&y$HVN*$+1Yw>R?u zcnOis;?F*Zz}K``W6Te<%Ne3jvpzt<|2MKj`X7LJ;E{V{OU{DbMA{vQ?jjJ@!xX78&0w2 zmqZKBD=+eX%Q)QEUxNE>@#V~F(ZaX1-Od|RAId~-!x`AcH166$-7jQXkp}&9?=N9& zUj64()5`J#qapN9nbIL=|L~0%%GYEcmFM+EIr;)|v-Z(zx{qG-`e+|%w;Gch6E8iX zzAL}C7UBFJ#^q-@Ce4!)C+p3a$h8D-_{7_8tWAGS+=X$h%q)kjBO^i>!zA9vJeB^l zAE@^++5fm#%#6q7@$QC$Z(Y1AX=qwm(wmES7q5%J+l!@}wV{)#7zJx$4>^=!q&)z4_ zMdlxBM8AyxwEg0okaZ+2Tw{OVnUH-m&b}E(-#EL`H={XY5Y!L3W6+|EDlc zHQ~GIC%&0-6Yr@?fBt(Z&MVHBUC0aQ9BIYJF*#{9RO(Fc{QepAk)LFkzsTlIg+ycK9~JLm8!IsZZT@x77t zvR|U~^V=+!b(8ZLbv12SoBheZs`@x}xC^|KcSzzp)%*_T@j><}zE#0EQ^%p+M`U@r zo^|>4MBC11J|4~P8hkMo5eEluR@riSl z;AbSxVLly3`BPZm*q4?37TP*Bf_49;+r%;QGYGGLaYy(I{~vqz16BQ1-}!!@=OKAc zB1woPiY-Y_5>(pKd$B|BqEj5PrL*XiyDn>$nZ;UVO{t73Jo4sB6sOAHzki9w}`E$Zo9)T5G!N*$sk&;9H_C%?VlwRUy1%g!J43A~>D z+xxfo_xt_r^E>A`fPEa)T-RM}Ut@Y+J@>B3sbXutyJnwjcITg`YveU*w|iU^n_A3% z{_>+Av@ud#Y^>K6kA)~!_43?zh)?skiBG+cuhygZYD~Qjo9kB0n(bVpI0+ z%I3o5#{Mj*Pb0y^|P+Mpf&6v z1&!-|=913gYS-T*UOv(>)hG4_yB9=z!=FF*a@GF)Xty`$-g-*EQ`G*RaJM%MYp*!} zDSK})f7cKF%;a7F{O2dT?!J6^s_x?C)X(a=`aNA!v;W`Z-M9bMWasmLspYO0{-V9d zTG2eqZ_?WC{#PHjbL_G)x7WVrFs}Ce`|UZut2yX-z_*>l>EU;t!#Drt+s)yQJB@ke z3;w{#{O-2nxwBrnVTdS4Z9)2twu7&9M+a3(ZtH&pveP89`pWoMH54RteANy?O z;#ZzH{$kDDu2tjPb}iHMZ^uM4d)!>(=K36a%;P6de@o$-u|L$8H-|p%lMd4u7i;6h zO@HfayId{!Ip%Kt_tIZJ+^-{E`>g()X?tF&TVMap^!>Kar3<;die`;*kkN}^`-l8^{d+OfA9ZJ zU)yskB%j>U-+ZU~eU^uk$^{#P#cf;Y;7v@8z%Defi?$XWOqHahKms z&#^OnNcH&0$8G&i|K!^>8~OD|A9wZpldo48w^YB6eBIUWPyM-$zsDZ`bz8q%Klw)a zUe)jMy|#X*pM9S^t@?cAUR%Gz&;G1!myfNxW83E~WqRif`@BDGIKSGb7dhgx8aJA#==Y=Eh zUCh7!g&%wFFZ|5U{hV$8xnKCdeyp?eCw}tBo@LC>^gMUqxxe_gKbzc7SM^)VCrz$9 zZ*u=)(f@gNt9Q?!e)YVzho9ZicP7sIKmV%9yK7x{N-O$PG`XLc*5?KN(J@b%H|D<{ z=^2q8W}n@qS*#oLe-`u>y;HpuTCaC*&l&S?2J~minBP1%<{7ib{Gy(X{9Ap#b;Q4w z-Pr3O`?x_bs9lw@_SFpy^*_*j)5U9CDg4k6UjMWwKA!sI3)epBy5=VL@sw}#(b!zq z{FLv|-rUms5BYdXcJNc0f3R6Y+mCN^Ui(*n*WcF;f19sbK)QD5(=EQj?^ zbo%IHzYfZ!~eP;v|;#1s_*YZy#KqX z?|%}{cfL3K$=~-VnYDjEA20ur_LHmrA^XYyO!5A1_LJ|`{rC4K-hVs8{}lh`AF00o zLHqajCf?b8@%Mf8{oGH!oBI9^_k-Vuc>nkDc=;3EdOCh@Dfbfvll$SVci4Z4$aNf* zb3c*yK0UP7AH9xZkL%FugugWtjvFrLI%d3osYS;OmvaAXUavn6zQbP1x%QrN?w?J2 z>-#0;Qtro3<)N(o$2GR~6?z@hwXey;QG3z*ie}qxaz8%d=kY9ip0Vt>XW8?}SG4-$ zo~74y?0nm+`uoZ3xOT0_`ic&JT>F+ku1)iQX2q}TM~BL}Hl5GNHzRk-p^n_~%2#WD)ULR;_SUTPH_Pqb&#dbFjlsQIXSI}j zrsnsvJ6ZcPH9zYcE1|tX@tXDRPbrpj&(ylCZ>s7w^kOOZ4E6u1sQnoy-Yu?uHTR5T zlY7RA@BfTBS%3e`<;X{JM`U~6*oW`|yf4S&?V)`a?K|)`yajK<8}K^32HX0I=eGje zdW+kO@DjWTFUX-DTzu!{z9^n^a(B(j*QD~H>rWrbUpe=TaqsJtr>7K^pMH73w?BPd z?vq1(I`_h=-=w`8?t(kv4!9j|gInPixBxf9O>iUJ0N2BLxDHla<9Iy%96p0j;S*SS zNye+fM{or`gb(0-crU9joA0OZ!aMLbyd{Tvbp1Es4R}3vDfjfE$vu5NtIww|dS9nJ z+5M(P@rd^$yU)b?QH$0W??)|~zjbXtYO(X*_2aknt>#+n{A1hsk4Eiw{$W3M$J_bG z$J_buM8~h8y=-zV@$oA-ep&0&%-S~F>v6o;QkGOq74%fHqKach~%x4y!!F;CS zDR>f|kmsZMkE4AI9)(BbI6lMh5Il(f16pr;bpC$1C32tKRI}=*)5h7`?td-q-q$Ek zcK>T>kQ;sbZ4+|6T!@^9>tLJ5==j^t;WPLYK7o(nDtrW2;6wNT-iP<#U3drHhPU8N zcmrOC*I?x(iRTKu3>V=gcoANJ=d=2<`M+%ro`q-N>8u`I|0#G9o`_w_-8O7;w@qaA zdE20Oz4B!Dzgv~>cz?UK67O$nSN!7r@m9qz-XCvOJpOrfzjmwEYkiyQ%8lQK{;lZW zg!9+O=U>g;nm4&y!~TDZ?)Pr3%i`l~Qr~h8pQZiv?{rV>ueSd!Cul#G>wUajyVgAs$OdQtMi;3_SakHO1WDmP41SttbT79_r6+rvis{T{c^a!Ea?8?mOeS$ zUpn`~J#aVN1$V+7a68-vx56!O0d9ty;6}Isu7~q*9c)q;&fzoo6h48KmpJ}~DtrW2 z;6wNT-iP%<`r4_duDk4?rc)uto+68H=n`EUm@&Yw*Sq_Uvj+i zm$WN?NxSlwxB@GGN&5k;{3Y!+f6;nww)u-~^B3FZFShcRSour50V{t=`o%T+t+98esuGgJnq|X+LK4+smLSnFgyeg!UJ$W z+z0or`t_u;+RrQA)MCU?_bR-ZSmd*_uWTc0;6zBl#w_8Zq^#W%6y zdsAoBuK3;*o`1OG72o7|#rLMLpSX6#H?iUy`$ok#vErLp@lCAwCRThCE53;p-^7Y< zJl`7?-=tmfO|1APR(uoh!aH(X7Oxw((Y^)S{6z7(aYK&saih&w?6ugX+>J{ncjH=? z-y0XaFDXw?DVkifUQf>5YjQuN_h;JAKe%Q;ujZbn^E@r=n@?+&b)Kh%*BP93p2TH% z1zv`A?xerwnRpS_yp#5Mcn+S0XW(gg3Z8@~;Bj~i9)(BXVR#50ga_b$xDW1yd*E)k z3+~M7&gHuUZin08R@KzGuRGVj1unqNu}it9f*MB$g{BO;>PfLjXQo?ZiTYG==@d zolkYqv>2Vw*2PF<)kQMjRyo|Cy8fz*8eE1~ z;AOZ7FTsoO0z41T!L#rTJPl95lkfyQ4v)d3u;QA;Zx|ke2jKy@AMS&D;U2gf?t(kB zdU5&gfZO3VxHYS9*S`fWz|FB$pLxwE+86b$WZue?to|bbrjCkLuf7kx6 zr<%Xwe?xda)o9nJ_&+7wZ#pafi536Eihp9oKe6JUSn*G+_$O|H8{r1H9#;O6@#9~T>rOs=8o$7|@7EAnaNLs)f_wC}@v@GiUqZ^K*gCcFW!!)tIE zUV)e4BD@4I!VB;`JO|IhGw?J#1y8~g@HjjMkHRBaeYyM(!$a^OJfM0C_2~Nd!+mgX z>{70wL-Xm)>a(HEyJ^7Jr+$BQ?z(V2UZ;OIxNbi?zw;iv3-9QBeqYPE<5h39{m5DM zmRR+ccmrOC*ED{3-sZ+DW4aX)&8}7GV`#i?C^N7zk8@rUdc0&DUvw2@T z=KYkg?_b*?`#k2ZS=4;n!VPdeoQLaRr6HdGHRtddd7y@Fu(gugjfTzOPw>%kT=kEO$r!i|`V>7`v3aX2z)Q zviiJc%3IG{-Q!%n)?Xj)3+na$`V(vY ziM9U3T7P1#Kk))Q56{7~u;Q1DHw`PEN&6%`0guCD@F+Y255q(7AUpu~!+pws*gsvq zd*L3q8}5?BdI>FNl|>Aqxd>U z@pX>k>m0?`If}1y6kq2kzRpp6oul|VNAY!5d~5aLtoSBYd=o3ai51_(if>}YH?iWI zxD9TFTi^n${3PQw!OBFbdAJTXsjog){-?A2UwsCj!YA;t>>rH$=2^2<-dWOj57)sab^bi7N83Mt2A{$wu}iu9p~>Y>vii*LdpDf> z{V1<|hWEF*{U$$O} ze`3WyvErXt@z00X!CZgEKWT5&{uGa|_$TL&;_v!L@pq2m?;OS7`jX-wk9SG&e^R)A zaqXvQSNxOXkKt-M-%Ceu1;;CYwbupQ`3~f;A35*KVL!UGU&>wDGPz6pS-vlAcwblX z`;mUnSng8Tf37^&`WECBpC9LWcn+S0XW(gg3Z8@~;Bj~i9)(BXVR#50ga_b$xDW1y zd*E)k3+{wF;C8qTZiQRm0^AHYW%cFq-3T|p^>99`N7ug&HmR>Xk6p@LS=H;z=UIJT zS@FIu@AsoCmCtxTx>EVEuH7G9sd&ftNBaF{&b8OguT(s*4Exa)x_+-zJZsmZv*MXp z@l33ECRRLaubaF6if7WUcqZ+NXWfFop4{IxC*Zc#7wf3sHZ?Gj6{^@l1RM zpTZ~bvBnRtXW8>#p?t*iz2XQ~evdWQ35pIC%;e1w)u74eDQrDfwF6HW~s`qF=s;hWk z6ZWGz#Vg*A>J*=NKdRIE$9%yM|E0XU9-QQFK(>n>g@UkBHQ)Fw(EV~8KT3_6LQR|D_FP@?O6h48EVZ|pI{|HvRlJ-OR0N#i9;9YnJ-iEid-f(|t<9l&a zp3LHNaYG)fxsGhcl%17<--C6m#5MB>*Rz4CdABmNZ#LCBoaQ(Ud^=MZk7$mschZdMNWOU^U!G&}`Q!V~Z~ zJO+=#Bk(Xh1P{Uka6jA!_rg7JH{1nx!X0os+y=M8EpP#DhMV9dWOj57)sa zwK>n~(e^iI@F{!}yOcAB`Wfrd>qlnaTdzym{m5M2P4**mc_-PA%;k+_KQfog$$n%m zujuzx`0K-5?p-yPm!FuwcTwl_kMG_~@FKhb&%<-@tnBv-KmH8PKMha8lkfyQ4v)d3 z@CZDt`T6?~KffW&cMu*x|NbZP>HGJ|alCtFzaObx`Rq_WdY{;j%w@g5$@*WUD{`k1^rTgT|{{GfD>*sqVHmUVv?A4 zL-+vJzMCAs2k*i=up2PvYqMvGwqHbp1H%`U$UR`u@6p66^X&tm`Lp$vi%!-(KVIPwf4>d3?b8$|=7e zJyuQkqsJ=ge)QOW@_fxawv#+xGmj~MkA=tM$3|AoV_RCEe?DfMH{lI<9ajDxulLuB z>t9B@@|U#R{VzUW5nh59;RRUxUoxJ}Up&6eUu>Jd*fxK$mA}NwUt;AivEBdT{$o$v z@A`O-%Km=QTl-&lz9yHvg^%D0dw;(wOt`_-yy1 z^KtLGMO&ZxTJ@;+dz)_^=;u`KWp(_mJ?|dn!yfl7t=k>fneJcTYESpCZ?&ZR*SDI| z{p(we8mq~l=bP)R=35O}e4OjyJX{B>e!n%8jrYy-wEdfBXg@{!349D!Vb$+>xSs8N zzp48DR@m>I6|eKgXg-Q-ZGUm?`>^7iwC}<@@HV^!Z)W*-=i89O{^h(bkJaW^GT$s3 z^UZZ{TOZ$4U07exb)ol-n{TRqzB%RFA3c;Oa0Nb$T{4gE81v|1R-cb}eW_EEV#@`zlBJgo6|BM)i({>ZA&M{C!I9e)7l>yNGVsJ$3N5k>7#kgC)}SnYyV5EZ8`Rt_P@l+Ut;AivGSK#`Ae+)C070tD}RZV zzr+XdKD-BO|4aJsz}xT^ya{i>>+l*}hF9QaxCk%7i|_(G56@-wV)K1A3(vsQ@RY_2 z_3ipk!V~a#?22gif{i$%c}W?j{nAfWL*!5)jzTJ z>%`ix6ZgW}ufMSrjo&SY#~*k8E_otq*M9wta6j(ab$un{Yrjsc{W@{09G_47b>@=! zhW6WUwD|L#bd=3E^4?dR7<1CGYW}98-;8_Y+yACVK2&>%kMjY%5AVUd@D98UYky46 zw+U~+>+l*}hF9QaxCk%7i|_(G56{7~@C-Z+Pr;M$1UwFp!K3g9JS>O$arqvC2jKy@ zUk>%{`uD-Ta8K-#`I~mtU%38lef~|W_Z1DcK1=4bA-jLK?WgtLKdX7z_OG93uZP<9 zub+7TylY=IUq3ebJ73>l*YlaLSG6x}M?Nyc02C8u0b~Rju!<`@a3Fx?lRL z*7r5tPumY?tuL|Gmv{@-`o0!kpK$%PzT|kVFKJ&xdl_DVm*FD31lxGU>sf&3;W>B~ zo`I*~DR@#2k0&l36LNU{%z0dHtHrxyzB**%9_34Uvd(pde09j7|H-2A)h^c_udLhP zR=5Q&z|C+I+z27}pgH7s_bNCECg-_sPxC$S^75ET7fcN1&co*J*x8W^#6W)N= zv--06KUssz@Cv*vNA+@2gqPsO*d=o^qdHv7>hokOc*NFc$$VuX+mAkTST|^?*_OY&ck(bs7Ke|q<;7uK8sy4 z4<8xx@L5)$4-pNl znr~t|-*VP|Z0EZbS@VsLKR%V~qxKWDA8Y<`dlkpq_4Y^oE3jRE+%hOT+J+$v) zK0EL>=CcKF!W;0q;uG#SZ9I?H&|ZdD;AJ_=$8ix}f)~+$LF*ll);}+gM4poeYc84N zNn?)ZyzTyXJnpTZ+u-)U<9>O-w|`mB503lf@chuZ7w&<(;V!rn?tt6jHnHhZRLcG6~%$LIRMWsQ^z}xf||+JJG)b?Ycga z@!RA+A1^n4D~@kb`+U@1fSchaxDn&&`bfsBm*e&3aeN)Dywn~q?0mm?4xhoNu&$4! z|1n&JkJ9;lu>v2$s7UxaNJe=56mU zzc?>1`1b0lJSP_;&%!hCG&}`Q!V~Z~JO+=#Bk(Xh1P{Uka6jA!_rg7JH{1nx!X0os z+y=M8EpP#DhMV9S}~@2n$>6Z!24>=+wQMb z?0;44e^u>&wb$S5{#n)jXYKb-%}4pGhW+RZRayBvG5&nc%3osTFL5WV{8hvL<@zgs z$??ix(ysg^?aE(bJfa4bjh`9f6=&v(C2EtxOu8}o(m`hd;X7k0g`(!A|{^o6p#7V^^|ugIH`m*FD3 z1TVr1@H{*R&%!hCG&}`Q!V~Z~JO+=#Bk(Xh1P{Uka6jA!_rg7JH{1nx!X0os+!ocB z&3`N00vF)ss2*+qCb$u9h+Q(DKi7O3vi<1ur{4NG9j-nAIC14&m9=^xnqAmyZ?M{&-;?* z{h32!j`oe-N2%`kSK%YL0_)sKf6X(o z=9O6UPP_~6z}xT^ya{i>>+l*}hF9QaxCk%7i|_(G56{7~@C-Z+Pr;M$L{@h$|Kso& zJPMDfraGf~8HR`8!Pq79*FCDga9?lh_OH9V_4{L7-Trl*uhWX^;`8BtzS6yFDyoa4 z1Aks;)y0?lBX7g1i_Z;5?VIvIWYxvdR%F%1m-Zs7E|T$87hmp)+Eo{cmtob#mm8zw zm(Z@dNZM5wNAY}B7e_}?f7Qk3%aK(V$^2$u)kV^-_$F3eBvxHi!hYi7tGcM{N9VJ3 zQH-p*Nai~t_eSlii)8#E#W#+(>f%f5(eVTFO5}cxcM`b|GsFlx~sH!>-WdF$HUK_8uQt(FMd}0;%86P9`;4&W4H<*!4>!rK7jY(J$M)1fw$o; zcoW`$*Wop|46ne;a1maD7vTkX9-f0|;Td=uo`NUgiL72+zQ^G)coZJV>f7}nhKJz6 z*d_DX9@Ss8FMhTwSo5~eCq8|o&*A#`^rl>a58(s3-q*W3UiJ0qP~Xm~uTNK_cGcHs z3XxS`$@#Y7EqF6_$$VP%@#*kbNbV`78dPp7Q5AwChv+KQj?o@lUMy zCszCuEB=WU|HMPE;-9n+!2NI^+zTsz$#~sx7u*SV!0m7w+zPkA1-Kb*f*aumxE{{K zb+Ac&cn+V*p`LC24^QC}_!zFrp}t-JBe((|#x9w|9b*m;eZATGJlyhb)^WBz|7y*c zzuNZgf7K|Lcn+S0XW(gg3Z8@~;Bj~i9)(BXVR#50ga_b$ zxDW1yd*E)k3+{wF;C4COpSXOt!L4u$T#&>5=lVCpO>krElKCqmH)i$umuKETq~o^K z_LoccKDlH*wUzz5iml^Mt$V*r^|58tzLLGJ=-P|kzv|jo&8HTP`P7m>&!;-&1zjhx zRfmaHhlw>#V%6bC=A-eZ(LROtNn<`49+%wtCvd##Fd1KUn0QpNXo}9KI!xM!;URbs z9)MMce;MvG-TYLC$$WcZ)nRh}ZpHUBnqQY39(Ub%opRWRKGmswsg6F?>5q5$YW9Ab zj1)}L7GPptJP*7_4`{fV{y#9Du1tt)XEUV)e4 zBCPl&<1NC9XVN|o&%v|s3_J}_!ISU=JPwb+qwt9GANEg|?_qcd9)t(v6JKAhe?Qy@ z_r@-n{SLV|tIz#5??xSG>+|D^@5fhs`^WTt=8s45b&lfe9L3i;im!7NU*{;k&QW}w zqxd>U@pX>k>m0?`S@EsahqL0FSn*A)_$F3-6Dz)n72m{)TjCzL8}5QTVdW)ONne_u80>wB-)n7uwf{zKJOv!{61u0LnRdv88!SG*G|-ia0O#ESP` z*w5W~ig(i9s{Lsp8b6A+J3flHa};mqDBjMBcQSv)JF(*Z@o@j*j#nI$_Bz<4e&{@% z??Y#>@)eKw&`Fk0d%lO1zuJD}T$RIq^pM{F_RzjD4^^{#KeX$8osP5n(L-f9+}}T> z_b)xPB5#KHSuevycnMyF7vOn#4xWW);AwaYo`fghad-?Kg-76FcnBVZ2jG6V5AKC~ z;BL4J?u0wwcDOC7FPraHxCJi2%~3tt{!MTr+z`8DK60-4G-UPpkyG#Mbe!FfK7#$| zBiN5V61^YS?nfU9@5imZZvGL)^CMwDdQjKPM-oKOS3Hw;#VK(;oQLaRqw)K*@gGz^;`u&! z1}i`D`5rvU@@eP);ISO`8|SJV_M->2A3eBl%!AQ>^x&@dH9F4jM-P_eupd3BdU|k0 z4*QYwGF*h0;6-==o`>h)S$GDXhNs|3cmf`W$KX+T1RjQm;6Zo*?uYx}UbqMDhP&WS zxC3s7+oJli`EP|=-~!wn)uZj-1UJGBu}fz6T=R+cquo>QYjm95k9MQ)hqwF9Zuoxq z+WpaPclvy7SKkkBpTE`iqg}0cx5Hm=AKqIvyLP?vk?ne8+x5n_>y54T?oLMiwcey% z>rL9Vj-2!e)9pne)QpadD$QDJO|IhGw?J#1y8~g@HjjM zkHRDHFgyeg!UJ$W+z0oc)W%cO# zo74}S!)LKe=7A$)9*AB)df?DozbD!4M-PP8i!`iUHV+J?uOB@So}WF@uKme=KYZ=^ z+5?LJ1Kqx!@7Mc#9#H&ikMGWk{{!KAaaQ~jEB=WU|HO*_19Q>%1+**vwfhY>zT%&p z-^M>&&#v9ZKepmuyFYU6HvVzD;-6T7h<(4}pIC8Ce45=K+41i`N#}e2Fe2SEhx2e)Ab*g!+zvEB!~Uyz9HqaSNRyq@_k>o z_az-?_oMp?a*J>O(2U$Hw?|ezCRRNrZh%#fNqZhvoh9ui^@q;kGx!uffsf%Td<0kE zL-+vRhxg!Jcn98wx8O~9173&M;4-`dFT=&GzHI(Kv;;503-EkakFNh5JPXgnE}0LF z8}p%Xe`5EO4~=?XspIT^^g;dnR=fY$58M91vvfcDU^RWd_QCM;F>24(KB)YCFkBBG zoLn^@RQ_tuXPlM4#L8b{Jd*vemG7}pgH7t~bNCECg-_sP zxC$S^75ET7fcN1&co*J*x8W^#GpjF~@9hnE9bSXWSv|V`EATR0j9oI@bH;3k$7frg z+cVyEI!;qH+a1QeAN*eJJ6${3zI3ndo2;j_UVGfVTBm*A_`SX9{&lbZ{Xf2+x;MPO zq%LlMySFucz3JW-jn(SU^MUPEb8jJAue0j4c0D?)UK2OMs@HqRqVej{o=1Bf+BMI3 z{12#J6RTbmpDJcu+4(-8dcAi#^0C^({fC|Z2de0Q1Xp0yYjQr-YvO%a^_sNrX8CvL zSN>}Im$UL%+rK`rT{0g~y?tQY&)?R^2UfiGdt=@H^?_MAJYT*?-|zo{89ChVI#0t> z@FY9|kHcf|C_DlW!$a^OJOKB@eQ+<_19!t+a3|aWx5I64E8GGX;AXf9ZiE})dN`le zm&}A@Ko%Q*&0o{AVe>P^!pN02_{aL%L zy!X0vazV_H9 z^JmR+yB~j}yKMff(cAuhnT_sM^QXtg{OO5r|I>cCs`hYx=OefRAHoOlKD-C-!aMLb zyajK<8}K^32AAO#co{CjOYkDR0MEm7@GLw7Ps3C2Bs>9+!((!&AD8b@cmy7XhvZP- zuKyrB0Qbi(nLq7P{q<+{`KKM;_V>$dbeGI#b9Vo3>vyxs`>x*5p3hznwe9cM>lOCj zXI|&pSIzs+jQ-A#|Nce!)R;fti+p0tW_RRcxC$S^6^wU?_5*o58h;t94!jL- zDW2he!mV!;?Hlkqyatys-xYWn#~0N;9IbCj9*Dds_tso8@1IdV!u`0**Oa&Y{W5kx zdjF6d#(UqEtiOMMxZiOefcxP-Sap!}?}5AFF1Qo!fZO3VxD{@J3ve^s1UJGBa6O!d z>tK`medq8Qdm6^;XQaat4G&=2i}IaVwcSO%Er8J%h#)| z&-X2RUzqm$&HMDSLhbcX+y370`ek{_;E3fVK_5EJ0@4Xd2{(E)5 z^j@v+ec}GvS?f!z^(EH&5^H_$3(wzOf2}WR*ZPw7O|);o>+l+E;}g$!1-9{u+l%lL zya+GA^Y9!z3(v^m@x;YLd3#?^6z?gyv*wa{@2K)ImF4@r!`}Ay%h>(sz1?!?zp*Uq z@84T{yt3|uJK%P>4Q_>7-~!wXH^Gf?16&X1;X2r)-Z+QP;8XYnK8CCC5nO=};RARd z-h+4H9e5kw%IeGJe`6EgfY;$QIjWb9GQ0vW$1a(TdDUTfeZcM~8?(V9zCQn0`S_D_ zU%!96v}*oX`S_Eg$jZl`n8?aUV&x;T@{w5iNXAn>l6K`IX;(fHD<6rKkHpGHV&x;T z@{w5iNUVG$Rz4CdABmNZ#L7ovnXU0v?CQw7%YGexqm~!F-0{A`CY_dQh{e*{XVIAVgnF^{@t%3_D->s2AMe)Z z+J66T?f36iyb~+li52g}ig#kg`#s_D!HuVQC+&)N(yn+X?TU9|#XGU$omlZstav9@ zyb~+li52g}ig#kgJF()OSn*E00xxU5VLx;6D9WM!otNYWpRac>mCU zyH0U-`O3@f{`fVUuR7SsVL!0#Ys&At>$Bt6l;61jn)3VZuBcu4O|0`KuENT1(q4g; z-=tmnO|1MTR(=yJzsY=e(60O@$8W*PZ_=*(CRTpm-4v}~`AyoD-^44h@|(=B2rIu? zd&#WL8nYJVcWv7HqRX!_tBR-nxznqI{_`Ks_|Jc!IN6^={RaygugA~#59;K39b1h& zm+cp>UFWOqzs?$OZ7@3Cp1&{hl*S8>fA086^q+vojafg6`j5e*@Q8dE9Y2irA+#$F zt7Fme1M*qqe#K)bav$c`3-`d?a2MQZ%pa^p<9Enm|8? z%VEDNwaSWbV#PPH;#=DE=Xb{|zNN4}XT`S^Ue9w@d`lVO=XTas@tw58!=x&zO~}Kd&2a7wtP} z-V=gjlUF)zlixR!1L%or~boH|5-WY#l>ev z{X^bYW=dvdT%PgA+q|uedS9#hd25gI(=LbmniV6rMd!0_go%ipq zdDqYSJpE2fcKq`8s`(woy*7X6DDKWt+?}JiJ1g$L6V~S(#obwPPulBnKE*vg|MEF} z2A{$waFh>w{$=GO8DIHGtb8O^J`yV*iKBeD@uPe=D<8iTu1n_~dDQ2_d0P(G$+F(x zw5hUh%$q+UM(C(R|)DwQAlK&Bs~uc~^M;>8$xA)_f9cK8ZD-bjV>peW!jO_d5%6xZZ5O-r3}R>BQ&j9d`U-KVGr2YTlvo6Knj$ z8b5J6+-A%>dZO`K(cXe~%`X|R8PpKv?`gir(fFEga{e7y^H18hvg^x@zlrt@cpYAY%kWBeeYx?M zG2bGrxF+*k)cQxF^)1Nlk>?eU^O{TM?Nf5NU$Oam`-JxueLi3Ru}9;F>+5YttL8s; z!(BQ)?7yzP6YhZ9;WoGxZZYORhW*TqU%>gB;U>5dZh-6IJX{Bx)Nec2eEWSo?fl+$ zmd^KWr|=2-AFF*W>R*+^Z2aPO#V={M@r&DS{9@bqMP5?;5-Wa*6~DwbesO=r zFR|j6Sn*3-fe+yWcptX$5Bah2UD}n0viL07e00@ZGE3{mEbVyPd@Yr|FU;6{>Fa6x zJVeLo`yRTsqT{-~-#HbIYw^!letT5&3D@Iq=U2^dkHEw55IhJE81vg<|8?W_qrDI9 zy=d1OlKFJQU2vz?JnPr#&ex&wPb0UheKK+z`nST0OLG1K+zdCtjc|kJ6Y}8ZS1%W% z`Q+v4noH)br*hug=J&0~!Q1|Ne5*eHr@qjx*Nfk}B{xOh)cHgF-)h@8)V>|Hugfcu z*W|g#WqC02id>tI9dB9l*ooSUINwrit!GxpFNNdndZvR_H+FwnoG|A9ZS?Jno$|Qc z5qS(Ag-76FcnG%V4eN2|8!%?E5}mJKE=TT@L;bkpdof-Q+zof(e4VjNX0b)%clz_a zxut9to4qeK8uR9sRr8iZjd$+b-=gPxZ#jVXjd@F$ziZ!vci|m)8{=)Eebbo#XC^xT z2995cRZq!$RZodm;AOct8o!A4C3q2DfafvaId~Sw&!{~--n#fr%gxbzrWB8A%_Z}e zQF+SS=IbrP-nl`auQw|{wfcIqzTfrD%1>hDC$aLASouk;{Ji-voX?J@{3PwlPtvaZ zB<;#iV&x~X@{?HkNv!-NR(=vIKZ%u}#L7=%#hxn$lvB8ThO=IhNv!2|l-QZfridR#p4$N$zs*(~V$m#u%l$C%$*P`iF!)w3I- zcKtjU>)+RTZToLk^?tyxf7|}QRq=kuacEcno96%BR(<}5b+AeOrgQjAp3U;}rc?L?K8CCC5nPd@{J-fCK7jY(J$M)1 zfw$$bKfX!z{H85<6W)N=;WfAnufWT2F?PwkX-?N&F}oh$G!r~vuSc~vWY_B(^JVj< zdhb8#H|CAHKc4R}WHxB;$*^Kcz(Qom94 z8K3Wss?Wry@CkejSK%YL0;@ig^Qk@)@56iWF1!P8!&|WGGdZ8?Gx56IljY})Yj7D} zftTSTyd+2Yf8!#&0MEm7@GLw7Ps^RrdZyq>cmf`W$KX+T1RjQmVwcPtdv)Cnh56}v zd}DX;fW01#`AyY_eZKpfitGQT*F7#@Hs&{uWyST!Hft`M-&7oJ`#ZO7yR10c_IId$ z-0_$J!%n-fh}P{rKvydAs8^A2*)nZI6FPPw=2WzPMqnc^3RU=a#bX zSF-1wTg<*+z>YIF=i66R2hOv;{STdW{7m-!2d@8gwqLp9Cw%+w*ZPn9_6@r}d%i9l z--`A|w1@q$*8ex=qxR0S`3=q2-p{;O>-!BofBW?j-<)g@oN8)u@ z*HhA7hF4(aJvqJzD-KEfBCI+{+I2l8o`YxM8F(6=f+yh#Sl3f>e&sE(>N2tFGVw4x z1P{Uka6jA!_rj|8yrC^Xb}E6&OBC-5;`g^%D0dY8PaE_41>gQ_N2})bI{x)~+_N9fld$?H?c?wm zJPMD%!|)J12oJ#ha39 zzjh9v!Kd(vJQwvphO6*V?2`GlJzHnK|Le4W|JsiC#dTv|r~P|I$N%5GzI{foht5<~ zw~dhx;RARd*7=h0cG0f$C+*vsPuRcR`L}TVCcFV_9kcb(eAm!khF9Qa&1Wm>UzEe+ zk(I6*>#RHB4!9j|gInPixBxf9O>iUJ0N2BLxDGa{Uw00l!Kd&Ed<<9NBe((| z!Uym^ya(^XJMcEVmDP*Q_v<#{4R{@1%j(nhFT*SFa_o|M-MsdZ*&)`$|1U`nV@DW^r58(rNAKrs^ z;T?Dz-hwyb4R{@1gUj#=ybKrNC3sN|*Ne^nYZl;ncn+SGLp{3wGw?J#6}x0!Gpafa zk9W2{Uo#v$=eAij=O00M#R=g4`UWpa2#EMs9#VfJmm00mg ztav3>yb>#3i50KJidSOAEAb>e0guCDu;QJJHv%jENxSlpcn}_d`{6#g7w&<(;V#ud z-tR{)-<@y=+zz+NChFe`x4?ziB{N;G`4oKryXMPgy3YH8@_d(`kKV2E?k@WFSL^*q zcWb=645q`et#f*aumSo2B7%ggckG{3|q^{da}Gx!uffsf%Td<0kEL-+vRhxg=; zES|64mD?ik$m2Da%&XUpd3AXFv-x^;+1tLJWb^gvIeFe6f7gjTD=$T!fv4dqcoLp~ z$Kf$}6dr+x;URbs9)SDdKDZa|fxF=@SaD6_*8#V~ZE!2x0vF(BxCw5A8{qn^zFhwE za2;$?-*qmBfB&)l?>d7|;gi@UbJwBj@Fdim>hrGsVCC7?=Utl5UCq9IYE0IA?h5tp ztog*A(tHwYK8ZD-#F|gyW4H<*!4=r9Cz{{X0c_V7x9`Eb@D98UZ^4`J2D}ch!DV;_ zUWSYC61)g6!1M4NJS*2{`JbABr{O7hQVy^0*m{|ofXCsn*d;SHXw1}@KmRLt%4VwH z`-0-|O6BHN%BTJQ?N=!e_WSoV+aLcb-JjXt^K{p6WIO-ZcK)&L{A1hs$F}p2 zZRa1`&Oi1jJOU5HL$KDLj5h!)9!Yy2+za=>-Ef!USB>J;DW68}!13*BUyRz@4puE=42&WG>;ta?d~ z--CDI9e5kwf;Zs}cpYAY%kT=k3>V=gcoANJ=ixbc7M_8p;VF0$o`A>UF?bXn$?C`D zdl(*q2jKzLQ>a(hzaQ>{dt;Z(uXboYy;*(!YFn`4VC(ahUHaVb+b8w@saJN&VLxzI z|HSRE#!K2;;TE_6H^WVEBisPj!+E$4HmN7i;WPLYK7o(nDtrW2;6wNT-iP<#U3drH zhPU8NxjW1M0*n<*qhAcl-d{5BI^!f6~7P*1VGTF1Qo!fZO3V zxD{@J3ve^s1UJGBa6O!d>tK`m<>&Ajd+|L1;Bi}@CG#@9kG}SEa>tj;=4A)o+nV?Ivf6jD_rbaLO>g`ATF3S8 zLND7e=4G3H{FkZTUuMtO5qZs+mxlevwd?$eSKwv1i1C)tzKHe(cpjdU!@qmF`OKny z2A+ne;7ND_wsDT*F$RyqBk-^s_9HjnAvqt#cTn*^uUYx(kq5n9zPh~Yloyw;X1U z%2S+=i8Z(kufWT25njsb%jSDx5nh1j;W;_fqw7Bl&%o2MOJ-usn2G7EJ|{-JFDfr~ zzj^6Mx*xrCINgt4+Mm4-*Vgw-^?SnX&+Wed$k+EvyR|=r_bt4nvT9!1rSpgD&$$!s zfZO4=Y`<~+ThZQv_5#|Q;U*m)?ibv6jc9Lx>)||H2b-LUeM#H$nTfZO3VxD{@R z>dWT805`);aHCwSN87&vu7~rnOJ@93^9hfqc0UA5KXUDQU%vglCJ(vxRWq*njEDK%xh88q<1@a#oi(33!sE4b9c)tHc@CeY7y@Fu*W^^RuoymMXc!;#nI zftpL^&Lv~+T=Ta1x^uz%VzfnGa5LNlH^L2YJ)DQ@V3YcebNCEC&FahM`;HU%7_P!c zSv|V`75ET7h+Q&wY|95(ecrL@ePPt^H+Nt^x&!;s9omoV{gC~z^?ir-BkPYS&bGeq zP(1Gl_5I?qta#oL_9th>v$j7tE1ropZtNE;o{1ID+Wuqvzc`Agv*MYwE1vOuUL3{K z9j|yM<5ytCGig^m6Ys-&@GiUqD<8>tTbQrSPZZA=Z{YZKwTJ!5t!GW`VSjQi%VB?d zak*q(ylBje%US+jJnwDqmu&uCJT6a!_I-Iw4)@bz)~b`lBk(Xh1P{Uka6jA!_rg7J zH>`Cf^X-H?;C8qTZiQRm0^AHY!HsYOTo32rI@qKhJBQEUQ}`sSFPrbNW4H<*!Ii8Y zUH?P)0N#&XGGkk+!~Lv2$2NjTe0{#C+n5(k`SuqTR?Ul)-xr1YckYx!y*n$vFAC4s zoR!}f9Y+0?-?7ff%I}N9{^pKXev|VRVwcQ|l%E$BeE-`I%H~DNhjp&knA^3#|BBZC zD;3}VE8VizUpt?()}MF}-i3GIZP>;ytjCSN3EOza?d$LwT!vTRWw;10!He($JP*&o zv+xW&4Nt+7@B};#kHMqx2s{iAW%c6nF$fR9{cxWg>f812g?r%c*d_BTZK}WStUiCG zC0OgQ^?AGfycyb6pSNp0iM5`@TF>p_-{o(&$7?;ehwIT<>$yGL-#cqPNq?>9_T}h& zT2ErFCplj0$y_qGYdyDz^^B~P&Fxx`b)D*JWM$Qip3BCMKRPU*$>Ds?r|=1U3|HYJ zxB?%-2k<_;2k*i=@HV^!Z^9e!I=lv#;T3opF2YN&@{+`V0iK8F;8}PEo`$F7P|q&k zlkfyQ4v)#9zFq%Ocmy7fT{5G6#*7a8`m^;p+T(pud9d~Q?=-)E7sh{KMb`ZOUC|%! ztobF@{1R(^i8a5(nqOkgFYypO2oJ#hu-2E1*9&XCNqaZk1$V+7a68-vx56!O0d9ty z;6}Isu7~q*9c)s+@LZnG^8Lay_!K^YkL7TGV(aCFRrm<5#4ec^?i%yLN>-mQ-1fep zJlOhtp^eYBZ-2q5toXbzJRfjYd`9z8yN%CjWE-EO$TmLVe$Mq*d|p_H+7+MC#>_8J zd=e`@@%dh$_+&1b7ifJi2lJtzF2YOjBD?_4 z!*lQ~JOfX|Q}84_0guCD@F+Y255q(7AUpu~!^+DO`L*%yg?r#`xC`!tJK%P?ReHzHLVer%961YC9&CL+e^;MF`}1|b^86h+Jl}WThPU8N zcmrOC*Wfa|0x!cwcnMyF7vOn#4xWW);AuJJ)5T}XnCFM<-+59F`tK`mdFSvMd7y@Fu(gufuC_8D4>x;Uc^w zhkCX7ecmFx0MEm7s-IBbuKz4N15d{;ndgnE4yUvFeBMa#xUbJ)<^PwveEaa$su@0k zkL7SZxpw70@e!>2|8jdYp7Q_8&5@P=Uk>qb<0=2cXHoke#@mIJ|K$AJ|37>09~Rej z-Tm%?ku;LV(nuajV;RX~nLlg4GBqcJT}N; zI*^iECDBbtN}g9Y)h)E*>8qxsr3rSZMOxkzySxqeElo*6(@`NYNr*!nBJOwXy$*BE z5|Wa(_dfTJ%k!YMK41eXeq2rd>}BseTMUvQq_kl=*14>=o=0>=vw?Trmgc_@VKvm=!!Dcv|ojnB!aLPYRw8 zJZ|SMRWXD(Y+W->a@4{V8uX`Jb9X{pe5mc^jiY4sI0OAUG-u1-A%p z7911YD7ZmzRB)Z(TER7fs{~hK{5ih#c$W(<6I?1d0_OPA`HKY?2@c!2OMNg095(TG zxVu|@Fw1Z{{C>Fmk}5-c%7%^o$P5_mc`9mSw8z0{kAu-32ctcX^3WcKJzv=Kl==X# z*Sh|YNS`Yh{c)6+4d(lW&X4{%?3sdtf-_Km$kyKg+Q-i$x;(!q-v{RXn6`Tbdqnwe zl-Fr1Ux6!Ad}Pk)k0Z0r{6}WM#a8+*b!1GbBfOr__#Np3_p?0+?gbCo__E+0!QFx{ z3cet?Q*eji^McO_ZWr7txJ7WY;F#b>!3~0=g6jm=3a$}cCAd;>x!^LvrGg`Ziv<@6 z4hzl~oM(#{8vl^sT){blvu*K7`LhIP3J%&C@#sZ+f+pT*eL3Q0hTn+~4}cM`^nD15 z*Tbm)Ft104hQX-+FvquM)bFsPeg~s|2WJQl2=)v1f$jC7{SNjBMt>Z3<>W(if@cNK z2%Z)^B{(T~Lh!iYF~Or?exF1BJTwB%HRGds7`)*BE_J9+sYAT}m*S6z9lC6o&QUAv zK>l-JUY|>6!R_D+raaB9f?EVP3yukH6x<*7BLRe~!8mkTZvTq-ysxL9zJ z;IQC)!Fhs1f-w#bf9D9!7MvwGQ*cmlhTwo;e=5H8c>4r<1$zX$!5oh|zjAWvoZwkI zcd60|#3A30DLzZbn9EIkmcn19T>e4CYbpFyT4dr=GyLUX_{+iYmxJLi2g6?uhQAyP ze>oWbaxnbmVED_y@Rx((F9*Y4c0LGyIT-$O@QmPT!Bc{hg2~@D{~a6`O#ZjqM+J`v z9u_<#cu??w;C{h*rL?I4wFAJ*R2l5 z45uMqWbTrB@;o@x*q;o6&wIf4e5Ic3w)ry;%;TZ`9Rg2T_Ad2gCOBl6#_P!p!}R@U8m}kj zz{=R4s07b~y*8c^JS})ia8mGu;BmoYf=3092p$$ZBzREpfZ%??eS&)hUl!aWxLfc= z!50K~3hoemUhp}=?Sfkcw+L<)924A_iZ4C>4T7VB>jc-LJdQ`5zeaGC;7U7psV9n+ zdV-%1DL$VFGb10xX9V>}T1-41!1p&Js6TSv#;D)HsNca zM|nkp(I1CBUvQq_kl;}92A@(I3UxXt znEhz~0e)YyAMZo=Q~QTZe$CW=J5&4ZOzpQbwcpOvemhh9?M&^r^N8SK!9#)v1*89t z^7;kC9}au3;LC!01a}L*2>+GZ`~^QB;PpZKuT!M&fZc6Ne_pBmb2dIF(zgq4MSic9 zzDwk+4G~WB`47gL!4rbV1&;|H6+9w%I2AuM-X%kV z2L%rZ?oY+5&fh1vSMX&!cd3$2#Np*se3qPNj+yu@zNl1jpRpHvFR9`SU|tV2Bfo~yFrA~e7vEcW|8Oe(`*B};|B&E8!5BNMeL8)=;6A~y3;C8{Sf?EVP3yukH6x<*7BLRe~!8mkTZvTq-ysxL9zJ z;IQC)#1qH2j)y$KA;GzJMtla9dVj8oZylcjX82|AK$qHElsYFQjPDum#koXuuG){` z*RT(E{J(uV7leMa9e>Z0_~+VwN$t%Z0)DZxp>6N1MDj|mI7e`{;4HzJf`fuH1P28B1^Wbh1$$EQ zrN`SXSUGvmoZwk7$0Oz6Gb4Cf@RXgq)SgkL_DrSXbI-70I!BGxo5Eq|dQ>>%T#pKI zj-z!>2*r0{kKwl)Oneu1V}0l`Tq(F*aGBszFps}(e+10yk>+ABuSbQ& z7|#&=Q=A&_!W_f&UYypWLLb=A_9)m34%!&;>R`mHgAuQG4$ldm6^wXwq@NZ%B{(T~ zLh!iYF~OsPM+6TG9uhn#ctCK!;6A~y3;PzB}g)#o& zR>3WTn+3U?Q9F03a3$i9Iy&F9y9x+Uuyd$wF~Xp#qHab0Y-avO`G`EjP~s0`?cme!L@>G1f!jf^3Weg zdF8^6{yEZ@3XXvJJ*;j|v9K2j4hzl~oF_OWI9G6v;B3KJf-}+I5t~1Qun*Zd1Ke*h z#>)fFFs#Q5<3^m0c0WFLNfnGMRWM=f1!3?Qn8!==sNfO7!-9td4+ zgE*l0-U)y1JT7PtYn?E(fpAI|x>1dD5 zpE^DK=_numbTItsVEEI)`GWHVhXm&e#&|f&%NFg$_&D01DbfdF=k-bVCj)j~pEL)+ zyguy=V0_(3A4rXV{+wajFVXnrk13TuZtVH_;88H|r!|iV9u_<#cu??w;C{h3`2@VU+w{w@u&qjOlZSk4OjCNCeKGv<&V@YFwtQCy$eT?H@^93-+ zyJn26>#|4iG9u+(ycv$d|;K5Y9(0D&OAh=&}pWt3F$G6UZ zS#XcwZaa6WN6#Y;yHoM`XghO_iO)Rr=g}-<&qMq2&>sh*KMqEJ^5$&m(Vsk?k2*j4 zlgIme&FGIKKl<~i&z2wkaWMMhNRR%cxJ%`sKY84rkiT2yp+CfQj#|i%_M=~UwWjVc6f@cNK2%Z)^B{&J@c&72*F(G(d@R;CH#1F@}&Oah}Sn!aYyVQ+#|SK@I}EF1a}JV0CT+3c!$mlJ}0EqDsd<4OK`C<*5A(L4d>^-c3QIM2*~&0}Dje;*nZ zJR*1)Y_D&~&Ry!EUZoxyGUY$m*sUJwF-+&EJ=lo$AzmKh_3ptbaC54B&4?GPJ(?Q@ zHwcajt`l4;}92A@( zI3UvFB!AQn?s^2bUoo&nIoi_&Ycv7~`MYVJi>gpW9+%jDIfsLzjo~&#kiAG5(J7 zLxM5>4ttKM596Pzzf0u?z}cq!ZTNpFxjw^mj@q`lOX`87QV+0y9w-J+q{`PkE_h5Z z`Ir5p(~k%q7Ca<)Q1F1@e!+c$dj($>+#|SK@I}EF1a}JV5PV+nIl=9MTLrfWZWbI9 z+$gv~a8z)e;99{osd&-jS0%VoaJk?zFvqvfUn)2vxY*8J>VXjAkK>2p^MM>@}|{oCf_bhAoro$FFt(U1K#rkt(#I}}^T4QI5&J_Nd-coL2tq zo^F*r%lSu@%I@h>+3>&qo+9#V`Cz=-3`tv0R{_Hw~x zf)U4#@-XfWhTj}q1h&@~7EJB5+w%m61m_Bde;xVZUkAg#4u*dn925-yI_v?#e!)I) zqs^aQFyF^ElfN-On`kBOV+~ezEsIBsf{c5u z8@>a?NDEw=pd_l6=H!{3hb;qO4q zW{1BWoF&T7RBHXWEqxH&W8)04y*!MUqkVp~XUa<7rPj?MJ7X@Ds+$p$2@Oi=K1h=E@)3)}tf_Y!6+utJ6H^V+`OCJLd z+L(O7^GfG$5c#99vmdp+4xF^*uNCQQ?A)b%rAS}H={?=bSIk@qiGBDg_pC;F#PXe_6O(TDZPYw^{{%X^udKE~(q{Al=69#dG0pA;Gyy-Ii~&=LpUgoFzC@lou5C z3}Ful_6znQ|AehQUSanLb_-Tc_Ra~O6+9z&TJV(Mq~Hm(m)9NguXh~G_Z7`!;3BI( zUCKMCly}VV%4oOp_8WH9D77+*{P4H8gYARhEaacFG5qad^0(a%e>)idb};r(z$IRxhW#7g*o_>mcjsJCfec)~zd%+DBcd6yGVBQxl>+4p_rwymUZ_D~FDNh~B51RBI{Qocyjh~%q z{OpYJb1=rw!5BYJ)K(tG&tb>-IqYbM!%pL8uMgwr8Ml>3<7cxjeA7?ZZMChuJ5AY3nG1|ox9Z1R+Qgq z%6HFotEJ6`UC8I2yQG#hD77SM>`NlxD7e?gbx2=s<61DU-#UE_*l)8}A^)t6E5VI6 zE=PLypUz(<7=Cut7qN4fT9SwIBBng*&yrkbqtTiSHDO3!CTJ!#Wj%7xEO ztj|SU_&eBNW_R};wZ;rthrQWMCJWcvRT zK_R=Ee;8$* zKSA}AJ%{saJFXSOANi2vCz9xwme94#V;N$Zi}^w6a#&`w%wn0zGRQK6Wq_rhCEBmc z@v`)=bhAViWcMRKodx4Zel3w-OXSxQ`L#rTEs|VnZ+`bWsqeC%K%G1OCL)w zOAkvoOJyWIzfoLzXIaj$oMt)2GRbm+~|JW|_q@lVy-) z2Fn0TKT97=FG~+gH%n#Y@;R2XEN56wvz#*0GtP31Ik7X~* z%Pf0XcC)<5@&e0FBbU{&tYullvWjIT%W{@wEK6BNSQfJ^Vi{(c&oYl?h-EIz93z)1 zBbUsvoMkz~a+>87%OuMQmg6kPSdOwBVL8llh~*&50hawny4zW{vTR}5%reHZk!1tR zD9bvQwJd8`R~|}vCL(e!!p~*^dQR&mI0Q2mOhqV zmL8UFmdePqIhM05XIM_NoMM?|Il*$=NLLTbZk88WUSQeDvV-M$mgiWuvutJA!m^oV zjAbLs29{Blbw<+nKxo~>{>I1<%UqT@EVEf=vCL!{WSPM-z|zms$I{Ev!_v(XRa5=0 z_pVAO^}#aylgoNJ^gPxpq3>h87J3=$)UT>lC=E$R@z3w9T0(k3691erI{jaA*LkDo zQ~iHz^vBLa?=$+N)UP*IxhU^?^6iAy)z2rO&l)|1TGG}S{ZaTU?LMRLy$pS~(My8R zpD}u526~;*v(W#v-!pn?EA%fK{ctJtKViKC`qzy9$vNo%)9CMRf&NpYKh=!=;!2}G zgX`&c8U3Cr=y>(kJW8odgAPyeXVj}Jrtq|rZ81pUiK{}}p} z{#QnSf$I8OqyHBAmHu6$zl8Bk|B2CGhX2#A8NCU9aC?pZseI@`qi?B$zQgD(Sqx0@JjlOyo`jpYv)L`G6 zZuC1xp!gx(j|-n$7w!^hb@JRtcTk zd`~v?a&!Ie8R)gFqpqdD%X23N{T0?*pr14PBcy-H=sQU7Hgkl|pjrCY=6W7o|6A72 zLH{=E)VA-kei8bQSicPYSEii8LA?9$8huX)`g@E{XTmKj;JJ)8FDo(Ei!qMNo;LbE z)Vr+K=#MS$zissF3wV#T z)adWcfgWHTvEj)w`u&Ip&vv7~uNL|)qi;nVdJY#fi~!g@dSIP2)6=W|AX zunzhqqd$%@^$Zw2?1s+kKn42l`M$aSEM5PZ(QDC{<;#p-cOLpWqbIVVXBmG!>VuwV zuKz(Z^kSob+7JCH9wW4EImbzF4)l-l^+D*oc1>qO{~TXOJC}Fqa$N5jhyHb=Z=rJj zhtab`&`q0NIk^fGay6~7YAf=pyN$lB4thRczYM*cua`pqxYk`+7*mxn`h5}TUo>eF zW6-~1^iK{!A2w-nN1%U~bxJ>D(qwmFJzvE-+UDA9^!tjDMpcwOU%RI|dMNtb)`#|< zh*qCEakRGZ#IciA$4`9drpEmTZRXHTvR-H7oO@3kk2-3yU$CV)bmF&9oc!pC>ynD= zoFj7d)ah#UDO`Q5RyWXofzup3{_*Mq&x!mxv37&5soLU@h5L?FoH(f}AU;-oTFcYX zqbI74)}B0p#JF6&;5NWVs!yFhe)5D`xO$o@uRR()eq!swwTcrc=;-NV$B#QN)kmKT zIj=l>{6pKES89((qqWsHxL9}UWbMfhm7e@%y^`qo6DRfW1?&L-5?q3_j^lc$eU=To_kpN`Z&TYLQ2-m28K=t;yyNbuH&RD~WDo3Az7 z9c?a1FYBwWg*{ z>I;_pQb4{#fIWY-w!-E;zGC;EbxC@VuV3#&HZ0;rwn#tn<&-D+!u7ti87yyFnTSE%q1+5he~%>=twyFJZ?4x$D_|5twUVs z7DSGIh!$BI1y;q^!(@?_Ql|@4*8Vq0ocdE4FeEQ)~8dzWJF+ zZC%$Z^nyt{#bL4lZFR2Wyf|3))Z&r4vQVs^7>itYRJSl=P9HmZV%N#%pGPD+u3-su zaHRUwF`1_LIP%n+8!E+uUX^XEeVg@5;9P6oj zIQi@J{h^0)9#j>$v*5;JHcHe5o}*N81UIx@;hm*BD~b<3QE>kQIS)U;;joDHp@*?a zT)3AllHkFd+#KVyL*kxgZ-T0*qn%IWbaj2zN!%aJOQGTsQx2&B=KvH#ZpEx;+$vz)$6hhUaTB%GLLuq>Us0T>IfW--5c9 zk#@Rxt3mI2f^-Q?=Q}O-lZodG7xu3t)iVCY9v^$sifDC1lr-~GQBhi0MmuB2&%M|O zQ+}1E6umDn8;UrLKKzxhw7QmOqh6>RjReR+Ejryc$w9`^55e*Ai0C`$WsqbL2# z^Z=3fetdYCu6&^acT4-OR31uiOQ$%U*QC9-#-4V2=KRmT{-yaD%5z^FU;h2XoeeK0 z)4ts9Ql7@H`x+X*aBsu8yXSiv|K@>)#_#WF*!cxDm{)u0;gq&7A`RM#eCeTr^d98Rfu05#jBQrF_r>t= z_eIDrs0>`+f%N`R<@~(PQ!wAs{tWWojX&ZAU;Gt(M1Hr%<$cZg67BIj8|=PD{%l;o zgUW$iP4%MuY|2Ap0A3a<*xZ5oeaxOv!KRDtd(GIzmfPCYY}!=vMJw<8e5l}B#7axC zL3LPdpt`Ivr#!ITN$s$enT2`-TGzo^29N$RimH+VFbvEau(^tl_h zwYaXwCjX1`6C4v5i%t2kUtq>qWE6wXS+Ui40d*nfUo8BGhS2N5If^riF5 zd28Khgx>!f{`SIuv{syF>49``Y!iu=d|MZNB9AS=UaJxQr?@)&tC*@F+c4-UMYOMM)xnZ?$dgdW6ej{%zdID5XE&f<^>yD;h)u( zZx{FdY?fuWd~dB0$Sd1$v-`wtx4uvO{K9`xU8`<=pZIx5)U|dYrm#=B;eFzozE9Aa zNPTUEq&ij@%znu99sAcc9qr4}cisoxpw6&m=Q`I|`&PY2c)_+u;QO|y&=mg zSC1d+M>%Fa*85Q!znS6or}cgPM*GW~tsA$Rvp&mLi~I7Y3v2hUF@86z>(`jGKV8`S zab5op&e;vYTa3+3=In;RB6)8yXIIz#W^?wZfm_Vkwf21g;+6KS>mkiP4)X=^M02&6 z@BfImIl51a~j;*WDn0-3{_v&!Kno+E07O zcVYk86Wh4(ta5{O{>Q%d59)Q|M*IJDi^NR87Bl24d(5B>*Sg6E95Y}=`-?1VpLye$ zd28r5j2XH1+wU_$_@d5=iN)8cw~8$LBI}fl&kfXPYwyH;ww`yj->tG1uj@x+mYwVR z5BT+0rT;O%{wTVLUvIbeY}P!)b8Z&ezBa!@OFa*0uWswJzPBRH7Ch%p@m~F|Tl@Kk z@_w-P>#q56{rvrT?5i4VbMr4TH~%l5n{x~MD)Rj~)N9Sn^YFtk&6gdW_8={>ZWy1x6Qmu zT91AXSTT!o7I}v=CFjqt^R9r_iwxVlf_o4@3wtkHtli*U!DNTkCTkvD7ssaGndqnW ze&Ri-Gqg~rQtv@u?++C$i`n;u9MA8;dKI(k_%+%ipM`!MA5eSjK6n5=Sa?Tu>pK7a zyw$#&_@LYtBkvJ0LVME)#+24^@^dD=x1v~pU)~Ez?=|k%{vcl!ENxuePxA}++{NSL z-xu!L)K0t${&C}Pn|GRc7rfE7?u<}f{Qf3;k$1lI{^m0Ow%By*8ok%CbSc|mJCEPa zo20Sww4mSbp*V@{Qf}zkhy_>sKINus;0NHF0OW&^KFD15)kE4>1uier>UZn0l?!XZ z4dVD}qm|b34Xuap%LbcYW^dt_O7v-Tk>5evwHlkgSX%ov@)h~A1Hb*-gX%r#UkCXD zI>m*Tbk}2e?)r`-SP!8ht zSLfO{D>uClgsl|UZXC1ptXOc3KDWra(dQMWF7o-m1#j_=@i%?$qI-Hf)(yI+(|Xv6 zb_`h0!OnN%%P%i-Kc=-)mQ!hMVH3-)LHHP*Vq?_cHfmi@iS8u;LL ztbJAXb${_Se!^?DPu6MGhjFHU(!0ovg+0jER364I96P2wdcC#YK`-o0()InwtP4x# zV#jaw{^tAgp1A0~3GLAR=D1sfxQkHzyhd@q=WFc!UTAZwZRKb?@0*rH;VZx8gIkZ$ z_kC7c=`WOXt1+@a->kzLys-aTd~Ci~BkNjtCZ>1fc&EAOJ90b|Q(G`zJt)^aW2HXx zYDM207oVp~-HXgQ>)q8FtWD#{TekRoU9!mMUkmTZk(b|*+dfN8txeyZyT#nQ**v(} zGvr##zgf$Ni~IPyZp+T&d7CxQ;lq$M2WZamevID7K5XBQ?fjaexkr0-S_>7=&rR5q zjqA9?XUd_1@rC$ayd5d~B5@@@yOo~{*y9SHQzHIv`mS``5ySd3e*Qca_ue&)pR>gk z-kUb!^B4Vj>KH!br}r&ia9yOayYamj|EF5HT5#`#TeK{L4$qK&%ijjh6CwW>DOVLF z)*4qi`4+O&{+XP4r<2}6ahv*#|F`@vp83B0y^a;bcpvsdJbSvlF}&Mx#4*x`UQa*g zDChI{*uN`am4WBSpU$FVgEuIn_17o^_pV?1QAYC(%81>hjBGP+a41*7wRV(|55Lg& z9`g7)zRRHJn)4m==N5a%{4W>y9rL2^j<#niH}7fRZOsGBfjNrlo9y)mG1g=MMZY7z zK{?|$NlW|TZfZC7qS!M{RKj27*yDO>4~%s(JCrs*Pd4mt>2ts^?ipU|`yX^2*RU6! z8?o*s`R2JR12(a@{pWVMx5a$-+TX$HH39F~C>`qd?3=%K4r92T?qmB8l zi@yS1SW>vZRP8J+E#7;uR6*Zc`T;!n9V#f^i@XOvaImxx-yqt#{{yP9Btj+?(O+o8 zGfYY8fqjMe!W({AH~IG#>T7$$PZsWmrX|ws#W$5WtJ=M{tPrT4EPUe7-Y2!H_LfA7 z_d?yzUyItiXa9jG3z2XCuHr-CLKQx+tMmgATu_;1_$|dRKBvz_G55|whVYw%-%K#} z)^y(Xy#q?!Q}rb^KaXp@-RjZkJWCjW!eV{C^%@5K1hywY~~ zkNB5@_&oAN_OK(I1Ds zIA!0A^Ox>IyU6}sH{y5>`Ll8EImd^#XBxgXYwVjbURL>=-Q8+4#z*I$gWcVwHlzMc zEvEh2j`}q>v;7?IL#U5_v>n%pmst55Fdrst`Rfe-YMk?zA-%_zzsT@XYCr1Vl%$eP z{!Qm`PCoJxe-HlKbRKrJH)Gsp?`K9i+TLi=)BMc9_-u+A{yxSh1LLy^{-gUQ{b)P# z5!1O_+MbVbF1Fe845yc~JqXF;tMmJr(LTzbF+wGq_GMsvGlmR*ALE;W@y+P5)lYW# zSJw~!Y5N6R{bcXt`X|_q_FLuOIRksx@PrqBo*`!{6^((gv|7t{%JevC0>4+?YStB{T~=d{%phl z7DPM7ksp5A&~DnN?Pw42HIz&CJH~L%bTnnZW7zPo&ar(^sdYGii~L9V@8~x?H^p}N zD>K8iPun{UugoJm&gpN(x#YOt(9a#2;1;x-`=hy8a7=Kc;0D1_!F7Ub1=oPxw)Rw^ zU2`_B1kc#GT;wkkTq-ysxL9zJ;4tbNw$+y}?C_(*Um>JFZ%dEyci3}axBEL=*s}y@ zB0b`Pe(uObJorc&*5m16Mms590{xWI#KVS;ZWZV?oP-}YU_TQ$pNc1KM;uXnT^nV4 zLux)~JI0IVgS(IHms9}l31B^@pA9&VG!O*y`lUGooM*EKz&!u8-4E`x+0h>ddj+F^ z4!c`0+F`eEm=ioJct-HF;3;rUs(l-h!agB*9L(cG{o61m?C`6jeItU01rG@x1ZP?8 z=~5dmli!&!z8kukvuS)_Z-zs7{MR?b-e~wL$RU0$-I{TQzeAyfYP z9j|;|lIqVoO2agEGcx~YMNB&qpBpL)RJ=}kc_xf|p*=D@g*O>9A`@_01*eebHdnPgR7eQivF4*`++dS`T#oEW=CL zzOLVtr}JZfunz5~`1|+s$dCQSI<&`+cwMl!GFP&_IF;W&iu_^2lc>i(iu^&-9=fXS z0p=LnJ*oDQ-9Kk|8QcARl+)DjuYw)^B%bU*{;Do~RDd%EFWT%a%xH(U7p3yw-i!SC zhUufe+woq*pN0R1*J$!}f2Hki!(RA}^4|`BS?yoj ziofH~Z1{&!)YA$(#$naCsbAZ1op`R4?GZ@szqX^@nyvi#IKLkEdm0~Y4;jAJ!uf-E zUK=yJR;Bdq1;fM?6~o(e@t0zk+{sexzF{KNIEG z8vfB3?6}{qK{_AD#~QLDUNvJJwB3`+??Zg7Aw+xLLO*;MKOfrb%QF2VyKkHs{nK{L z6RUn-F6`}w-x`8F7x^h2>Zc!VuVF^JwY@UcKW#5FOz+*a-Ag%5{j2c&;X`~8|Ja9g zcs^K-ey+m(pT>vmt4Em8KW&HqGAm8}+KzIG*P&h7j(KGL9TROwe~8`4r|k_$Ut`N( zYj_>5YkM9T_0x~epKEv>*S`wwS!h4jw^c)if82=lxSy@MY^$H_Xdl(TB$Mq`w)_hA za>GA?Sf!93^?OIT|71t~#IzsM_H3Nboo}M=`_+|{(AHA zHRd3pM{CL)C%;|dcGz5 z3iO9~4cevcowocD*wH@n&(C^bk05^x=N4fLKXuPI;KN12=1-VcAFJo?dgw2OG7RsIE}FSg}JzcdFp zKgzMv=E50&?G zYF9b(x8lFC51RIQ$c}uPYuTQk%D)Wz0}tw@{Ii$`%do%jz@OIp7i~v-i8oTYWJi0g z_|SH*;Q;zcb~@|J>fcg4e=p1_C;~td!ON7w89>R9ralKUrKh2 zFY%oi2W?0FR{xgF!jAfh-|?Uwv&f&F%CGIHpYmta8vByrRDO3i&SxJo{7aPU?#B7; zose0kf7*VYxsmM+=+8ORKW&d1z6)`#^Hck3Z22RGe~Es&yK#Pf2<^DY`KQ6TVBRmg ziE{*_KMp(M#KGvFgM)%I1P28B1^Wbh1(Toc?RA4|ZT&%amxNR7o&)FEcovNDpdae5 zdj^d8yuj1oa*Ml^dyLXCW4zoW%wh5;?Cq43{T+h6#qci&VGqGxg|EKN+3e+pX+Ny( z=%1B89XA&@`a?X2cBOl9-aFcp)^75XJw3_X%=Tf7Kho2Ww)YzjTKO*{eWopcH#5dT zmwyiFJ+}NPmpBN&X?uftKfX|Yo#BjPw%4eI^+4BOX?RnDV-WB8eS|A%xeksN|%lKE@ z;Wy&+9=2!0-#nkSJiE;kElM&wz`;6de!RWsueNr&| z;joVjhJPIPQNi$+!#)fSvOlQ(Ltvkc2L%s+IX-oN`@#19_kjae{w}31!a;q^7!TFS z9EQYrsB%27b+bJTJK})&-Wu4$u;*ZWI@s=qJ(kIHSjSkZ4;wubs;XxlWvdwLs8_YHPVM{OSVue6 z7g(pvf6O}ir@q2^2>LfzC;xnl^} zdNcI9S#O1I&K*YVL+3L+QKEA3Ik4^y=zGmsnfGECTpu*LqPmV5-JJ#fd84~Jq4T-A zLA2j>)?B{}ZFaRAJq>8?A@iL^Le04hoO&~ zyvqim|GUxYZ$u-yT|A&gV6bmV=sJ? zmTRtiYoYU*v))nYeD?8eGtdv1H1zl8(mr7H+b=?AU#%L4&c5=&Z)xl+AEkN8q+jEQ zo?tx&{nJLLW0lhWP@iY2&k0I1XOH4N53c{YN#ietZq6aa`z`3-G}qTrfB%8?A?W{X z^!3!ve>3_9j78dyjUIq+)A$_TjSCx&{vx@cTPaxX!H#9EB#$Y-_!yYji|?1wKXeYMIU?*}6bCcXS)hwuD{QciD5bL|^_gx9 z-)y2Y<*ctZk#2pxNnbZ#aUzw!ZDAKJjMO9RvI&~6<`I$o$ zaY`7D&C(~h9;|=%bafOLj0LCNRh>K*{a9T!F0qC~$E*YBOlm7J&idmdIJJzm)HM`^ zL$RvpXi%um`fN62u#!=;^Z}e(7qsoxB^=RbY!9O!z| zC}_M<&_tu4LZhG(oc>sQ{B#txu!e@Qh6-6jjjW+~)=)lcsDL%pK#n_o{{!2$rAkC~ zY^P4uR?}&G)HEdM9Vt1PdvT!lVSd+%cT2+KVzkFkug{4C2qW%+k3f56g}ZpsU= z+`_Vm<#R0Y{Z3tPC(FNN`A;n8S!TFRy6r3vv8-eHX_kM&@^4vAvRt{uJ;XnxmHNa;z68&sL!xQ zqQZu{qtV0Gk<66Mer4~8=WwvIxoW??=#vvq?K)MB8y`!e&pk(HtTJ-b3O*J^-g>Kz$Ye9@JyBKNAam?GSzG`73F};AXKBSa*jQL} zuXmwY3+3!a%j-{77h^G8xVE=yr*%4{v(mjM>guDqa}BA~2kWYj9e?h4bt;ps3nkUh zlS53=fRdxNwI`1);FHxh*1j|*trpmPbiJSLSLkp}>bw0~MM;VMVyYD;(UaA<` z^=Z*`JD?N6i*R6ftu-_-rG^c#%XZ4JOt=eYOdmal;0WV1$LoydG*)?;BlG5$DGpEI ztZC{Y+7LFk>BZVwXzmX;G0B>&<4G4vFFa9ovrfW%v-)w~scFLX^;GGTQR|K#t6sEu z`u4x5#j%~k@vGMreS-u$Ptoc0#%DLJd;iHOHk5o!yDS|>eWP8hX^5nw&ll>JQ&24| zB^V^^Q;$`jrb~NqJm{%-82q$ zf}0GIw%=fwwC$$OI^;ZRU$*Yhi8?xCmd{gP%xQ;Cn;Eh&HhdDlqa-BSjnn0Ecz3uo zY*ONqnYlYpb5cFP6&1%H3O#f`PSmcbJ5~{`!O^_;KZ|8@vFpcZ`TYO?mO<(dHyolr z>7bVYTA`n>1uy(9gT)+p3&;Kk9?pKlT5fbUaqjlq;G$;}=Wc&El%qGR`fOqyoc6h@!wHKCQSQ88Q4PV1CS|~8JA-x@h1ha!yuP;`we}%)w;i{QP|4kZ1K*O1z1ehcGkF z^hfWA{pB#tk*KGw=}RY+nq1Y^v;_}$lS|v0mgC`W`^y2CSAV*{xj(wBcOz0xdRl(( z4P4vW|CBB_`7TrJVnx36epBR2Zx-t!U;49JN0Ig3M2YvzH&=i9WqK~u#i4L91B++nM9lvSn6 zs&S;Ka*)$j>#)@^Q4h}auMWQ!FNiu4G#Fx+G*V^lv#CyMf49fv1)Bf%V%o7}IWJ(& znhVKq&gqa{G`4>9+d5od`pElDY#sivBetUMt^Jd$$oVgi!1KKe-am5qVAE7a@&pxK zPkl@555zy21$+Fp^urnP!x^sKnTfAa+$Rcsm?KnBdfVjTa`{+^$54C$ZNPFPTcbFtO$DUz(?nx4w$Il3HE-_wkZx*Q@dA z`wFMFzxv|i+h3So-IhizxOQLtbfR!Ny)dbpT{z{MhT=}VFoi`b`M0=DQSFh8EkB9l zpSr-+A$0e?`iZ~P<%WOadVBkiUwjAtLFMyLc;i>#A3uD3MLP>Mpi5UjM=o;bV7|u- zg4D_<0`Oln{st1>x8L*9FQ~9jtkZ41QaGb9TvrN5=;Gvx_~6e+ww}5bPJ*3icy_r z-oe?QqIz)$S@xG$z2_%aBz9(P8BRQrx#hL^@WQNar)FVLe2JJ&-XC2`_Q|xZ{R;)X z#Fov8Cp<{H0i|GlOiS#{xNj$#>m${(kOQ|r3WUTbb*^tlbL3RP#JYZ-@VwBz)sw2J z-_G|)n_xOsJufT(cFa>>agacCU^<9^e^U@7J z5`R7Z?Rd#V?Bhjh^%>e>>}aP2qTb)8{TeSEYx@kj8UZ!AIuXkzwQ#Jd-yJU;Z$nfc z8fhz>h!>6~c4s5%6T5Q|O$fjdgo0jUX>B<)%7H(BBrkyoJv0u_AI`?!V#}}DSx}sj0v(BEyxJet-;Qxbo6Z zSZjOfJ654)_fduV66Q54*p?yK& zc;e8|)w?Ov?mX;$n!kpQzg{@D0_(X4S5;fd80`V9S%N7Chho;j$yfgm1bSkB9`?1( z6k@R#i&T9TWhfcc^SEEnDPM;8U!koX1STiW7p4Pn&>+U$D=PN zN`~XE$%}fJ$FW2^=kOa>pP?=KZp_@(%?C+!bolTu=jX5H(PgR*9q7e9R!u&xcYVv0jlic(ue)%ccpGa_EN`2_4y0r%_SHccTutAZPkc2B?aX}i z;T<0hd?J%}W4Qm*I;9_>Fej;VZlsCt!O}PrKN3jnaifU%OO$bP=M}g9f=}Ym)clir zN3y#4A5n7~_I@SPaZGGu*n@KFS78q5iSEDpXGnvsP<&4y{!u^GrEkLKR*swSS3d!B z$<*qve2N;{{AP3+(zKN3z?aGRGP+wI!SqVf^0)^ROn3ZFRF!zS66u$mN9o&NtzUj+ zC%GICT}T`Mn49h`Y4JVo_#-Gg@kAAZbPEbh6uHlQlRi*Ws|&HF>S#$~K_D+69qPbd z=S_^$5?)4f7Pc_@sWVaM#yZpdG73mUuvx9YC!Uj7ih8clc&Ws)Hau1y@x|XrFLK8Z zK=n=@NECVEgIk7o>~_C!FtIAJEWQ+vobe6u1Mb8DU(;)z#2(Lp*1KbaPw?8L)}fdg&3J=zf#i#1Vgd zu&H0)g=mlcq&vQh2KT>FE-b_mcVdIC*-<_Qsm+^)W>0>e8vH1Iu=e6A+Bm|sy?WcY z#MMs={SiME4p*&>zlsI>07VPRTo!l5SEJF1Bfjm!(M@f?<4H|8G$Z*feD?x2q`<=f z8Qa|Ooj3kb3b!`*dJOQ@O_)WrTX(GAdCBx?y?!4W!U{kO_%JWv8`{367jUzB^A=!a z(wq1it=?@1+_b?h9Hu}Tyh8H?>-Geky>QdVw5LU=aEQ7S@gm+*i}wAi&u&2}ShSmv zkrwSZ@JskTiC@x>G1ImGFaJJ{_UY9tdOMaJbQNn2mS?QhpQlX(ExUtQh3+BaGP8JL zWi%@lMfT+VaH6$_-II91i}x$b^tvPq355fdchjpjKZ z@o8Pu%k;QRgZHE^^Ru8to3{LpH~HkpjqM-fuO)QN@%CvXz{FjTk;bBc6=jSvzp2|X zS!c4wzB+|ec%zd@tomKOs3hJ-Nt9NHj=s;J9r`Ks4cf{?;kq%CIsVcNwE@0(X%0&K zQ?yaVlH!*&(hIPc2FNv*ujsMbm)!6}iuFV+3482oR!jcie|=21AgMi8Oj--#yhO1uxV_-y_9AYf%P&h$Lxh>68SX7D-j0)3;tzE;b0$$p(xuJeH|9ejeN^rjwu3nWJlP>2*X8wv)SQGiZw8r<8>kf72}`Z>|1H zp{J$rM_A@DmTols(Zol+Tfe#WO>Cd{_!I85rq{gKcdl;!5?s;rs%!g?8~-i#!jDuG z_cRZ>yavl)?BmN-J=SQ?WI8hM_^7YG1P`N|uI%yA>rUM5Dk1RvMR&VBeq_3D^657B zLs$UY+&!<3r;!`zWg=!1C8DkCqx!z-LvobZ=Kcs)$~O1QwB%xm!#gj$IXv`MOT^ub z$3`r-ujhMQO?$j96MWidsddlXaC+!2mw1KlS!lt%iL(P>svM(z#2aVB>Sp}c1Z?Q( zC-IqX{JZ@#J^1(3lZj7WfW%|QyW8CV6PkMUd-McKPxxMxpzrzLz~wi-Ot~gA&~5s{ z13T#Bcl+Dl73xD!FZ^EB*>834M{A;%@`0_~5JKOYjJb?fR9(XD;Ik zrrB=OgG9J}uFZdjl9@#HGp^SYhv}`)?QQN)>+9cJvgI{Aa>a|&0*T$^_4N3DZ+yS6 zX}8~XWlw<8T-igrCkUSrUJ{c_zDkP+?t2UO4n&;oncc+C>vTWE4|W2R^i1*UzojLX zCj86Lgms8G^JX})^oo0#PPO0NR5;_>UNUp)AKti%hFsZAv4Qo?K2E;)>s#j&9)zC% zt0-q>s+?6#SLlK0)DJKK%jq(F9>IGC>*ccbI2FeRCq^TUS;vluzwzpKmuz_zv6FaN zyWQ#X+*uYtp3WH79XZmqTU-{8r!bw ze}Ik9m3-~AEBV@mS84r7)f9H&4MUQqAl@^qC-pFPAu&W9c9yQRR6S9bm)*H_esX90 z7brNrNJl#2i|6}KuzV!f(6SCkQXRiXy=n9RIr%X@ZQ>y62{c{70y%>cc0|0VF5^j+ z>`p%i@jfp8?L;IWbN=o`T?88+EKYh=c?TJjfBzOg{#~U#LE@v~w%p%||0F&;e znekUsbxtKWAuna5ITC*rzQztVFZRxD(IxQzo!*9u%|JM4;m!nLCQ zwzk7*_!wXfUwTAE-SK~%{D;?FdTFNxgFJ|a@cV{*v@;QLqvOkQD^u|TH(of@PbF62 zL3Ir&Nau?0cgNp2^UeAnBC%NuczhQ|TRZjYDBlrMF^v08ZSoI)05@ET|6{zQ?@HkW zxnJIYM`(t{dZ);So8uomiI1JI#>)S+|~4T zdMWLyUvcFuDfE*#+lqf_IKD_kcX&J*6!rtubq4YQZD(oqNgmfKxhnY#)Y#XDp{mtq^y;Hy9B)D>kVbI14Y&D2$;9suAq`%L zoGW~*sozh#Gwj;yux3st3fyh(SFpToub+u-PAqMD9m5j+iGDzhPA2m84y7=O8_(oF zBU5rW;uLa8GYU^`*D#&jYA!bQXC>clsd>peEj5z-^Y7_gP5m{=KZY86;Vl)-Mo=YQ zHhYuka<~JlFsjj4X_ZGa99MC7``RB@x>Twqg&t$ z6L(*sjBDeEh9=*Wz`8OrxvCi-z%-%+WWYNlH1d)4(Mj@21zmj0)#m+cbV|{yg+oIL z_X_+vefD?AOcVY)InF9p0^KwlRMo;y9c_S+~Ur^8rN1odL1Wt&4- zu%;)!@}4yvO#H~DNUl%1p;VD$1tmxAyg`@|GdX*pRs0epq$KktX=F6mK}vmTklf`Sm_&(jjhr|gLczVbsbCoCa)g5wb(RFZ(*6QQEf&yWv?e}hT4 zZX2#|*~Q0lQ!u#CUJ&_&?J;|vHG2VitseG0!4q)xuT5BKj`XihTxMS6Uz=2E4)d=~ zt}=)C*Y;a(rh0Zw>W?YeMS0_WqdUFqw@lT>;^?mA9Ly1~kL-q1sBs%TAc;Yk85){1 zAXJq13om-Z0>?AV^X%d@dwOc_^fasy)91dP3{S8gwh$KRO811zmms?L5UHEn(y~5|%!k3e zA=9A;AlI~TGNuOXbhpAQa+vlx9OO zSe%wSJ;gl7IuQO_MD@Kb^pt2Fi5Z|fu4R^_M&2bVpro8W5k*k?&rtfgu?hEdXkO4Y zu8mbnCHaU>@|Jj#R=3bHf`R=+9%h=}19r{CQ0k39Vn2!w=-b#mfDyIyKzJ)uYeYaI z63BW1GX(F!@INWQb&y}LqX28Iqc97PKzm89H_aStuS)788ZQ`^#m{@nuk2Kslaz-N>HQ}N(mbCF@@M@XR%p`?VAb8@_Co`%=q z2)eKfAntmCFA#Dz%}e3)AWcLbmsEy>aDL7ZMZ?%wTwM?u(-VxqnpBk1Q8XN*6M9$O zOZL_y^sY-2eIQjaGF1Y0!i&H^5R!G97vXk{zNE)^n)H6hBs6`grbr8`)}>IRS{G6| zc*~j1iJ`&-W;ZDnLu9UbXmtn1(#WOAs|`EdjL0|fuZ{YN2$%SrS(*cZ0P7hNdmCA9 z^y^>b>!I(=FY=}I9KHUFe5rSho(o0e*-D+1+IA*g`iVL>uz#vk_w2p&cp9lSxU6`6%nC46OuSCx{ld?o%DyDwe#Q`-z zXyIMQVzsK`Ls3wD~>7Zbs4n1N?)tJ!4`*=^oDUF!`L6k~=BY^k6RaowpUi{gR<3 z0at^l{+yH=iJ)#aB6!<1U;GCggy*$|YZk_N-rH~m&m-4DYSUF}4evsr0Ak>0M4n>G z!2o3i4lM7(?1KCMqS&=8IzHOnUpvCQufx%PF5_>E(Lu;qQWNQu*!)ZlI6%fJ|w!UI-^16V_L}->z?g zk5#`N|H-VlZsT7w-0)r4n^Qw2BbV;6WJ6EnYlMm*>Un}6VIL4mXBX5EI!MTSpu-

yS|MIzRqHApzo# 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 literal 0 HcmV?d00001 diff --git a/macgpsbabel/English.lproj/MainMenu.nib/classes.nib b/macgpsbabel/English.lproj/MainMenu.nib/classes.nib new file mode 100644 index 000000000..b9b4b09f6 --- /dev/null +++ b/macgpsbabel/English.lproj/MainMenu.nib/classes.nib @@ -0,0 +1,4 @@ +{ + IBClasses = ({CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }); + IBVersion = 1; +} \ No newline at end of file diff --git a/macgpsbabel/English.lproj/MainMenu.nib/data.dependency b/macgpsbabel/English.lproj/MainMenu.nib/data.dependency new file mode 100644 index 000000000..82ceab424 --- /dev/null +++ b/macgpsbabel/English.lproj/MainMenu.nib/data.dependency @@ -0,0 +1,10 @@ + + + + + IBPaletteDependency + + ASKPalette + + + diff --git a/macgpsbabel/English.lproj/MainMenu.nib/info.nib b/macgpsbabel/English.lproj/MainMenu.nib/info.nib new file mode 100644 index 000000000..a2c81127d --- /dev/null +++ b/macgpsbabel/English.lproj/MainMenu.nib/info.nib @@ -0,0 +1,24 @@ + + + + + IBDocumentLocation + 116 209 356 240 0 0 1440 878 + IBEditorPositions + + 29 + 93 299 319 44 0 0 1440 878 + + IBFramework Version + 443.0 + IBOpenObjects + + 29 + 229 + 21 + 305 + + IBSystem Version + 8H14 + + diff --git a/macgpsbabel/English.lproj/MainMenu.nib/objects.nib b/macgpsbabel/English.lproj/MainMenu.nib/objects.nib new file mode 100644 index 0000000000000000000000000000000000000000..318ae06f4fbf6e06467de97d3940a455b623bc49 GIT binary patch literal 27700 zcmeHwd7MHd&8DQ8KLB*&?+#n#%!oWZz4h*7mWs5UN+#dFHpP6at>27*qAaI}7 z*wf~EpBl%p)p3o9Q6w6pxZ)P!VWLUgo<@xt%`@iOu6bUUTyErke^uw4uG7mf$oss% zo{4k%)cMt~etT8@YO!Kea#PF-CX#W>-z9wimgbG=bb9QHmgdDP+b*yI$tC`zU$D2+ z=@BbhR0-?tQy@*LL^9f?3TO1EjYg_EZbi%TRMOuTwpx<$P^5#)n)dJhG@m(UMa!aC zEF22>lc8uN)0;{2kYMj+QFqvimNP?E_l$IU)QXlftVApt30iU1-`6|9(xV&kPrLn( zBEW8FQ9SP7#M0^Ez$}0E4@@T#fuz;im|PmN!ofq+>8ceiP0>g)9u3d9zHeZlhh4y*BMzFzuYx*`+^G%^mf#FC4r$qI+Rn@*2LQvsr%-X}=P>DMAi zAr$KQ>H4o1^{~bYmaZV8dlhR-(fASl1IMH* XmIBytZY%2c!dM{hXQY^qiEXe%q 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 WzIky|G!XSKjU% + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + MacGPSBabel + CFBundleIconFile + mgb.icns + CFBundleIdentifier + com.gpsbabel.MacGPSBabel + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + mGPS + CFBundleVersion + 1.2.8-beta20060219 + NSAppleScriptEnabled + YES + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/macgpsbabel/MacGPSBabel.applescript b/macgpsbabel/MacGPSBabel.applescript new file mode 100644 index 000000000..a60412337 --- /dev/null +++ b/macgpsbabel/MacGPSBabel.applescript @@ -0,0 +1,1026 @@ +-- MacGPSBabel: MacGPSBabel.applescript + +-- File created by Jeremy Atherton on Sunday, September 28, 2003. +-- Last modified by Jeremy Atherton on Sunday, January 16, 2005. + +-- MacGPSBabel is part of the gpsbabel project: + +-- Copyright (C) 2003 - 2005 Robert Lipe + +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. + +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. + +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +-- see http://gpsbabel.sourceforge.net/ for more details + +-- PROPERTIES AND GLOBALS -- +property fileList : {} +property startIndex : 0 +property startState : false +global theFiles, inFormatList, outFormatList, inRWList, outRWList, inTypeList, outTypeList, extList, aFile + +-- EVENT HANDLERS -- + +-- Start up scripts + +-- make empty entries in user defaults +on will finish launching theObject + make new default entry at end of default entries of user defaults with properties {name:"theInputType", contents:startIndex} + make new default entry at end of default entries of user defaults with properties {name:"theOutputType", contents:startIndex} + make new default entry at end of default entries of user defaults with properties {name:"gpsIN", contents:startState} + make new default entry at end of default entries of user defaults with properties {name:"gpsOUT", contents:startState} + make new default entry at end of default entries of user defaults with properties {name:"gpsReceiver", contents:startIndex} + make new default entry at end of default entries of user defaults with properties {name:"filterNSSelect", contents:startIndex} + make new default entry at end of default entries of user defaults with properties {name:"filterEWSelect", contents:startIndex} + make new default entry at end of default entries of user defaults with properties {name:"filterNDeg", contents:0} + make new default entry at end of default entries of user defaults with properties {name:"filterNMin", contents:0.0} + make new default entry at end of default entries of user defaults with properties {name:"filterWDeg", contents:0} + make new default entry at end of default entries of user defaults with properties {name:"filterWMin", contents:0.0} +end will finish launching + +on awake from nib theObject + log "awake from nib - " & name of theObject + if theObject is window "MacGPSBabel" then + -- get supported file types from gpsbabel and use these to populate the file types popup list + my getFormats() + + -- deal with changes to MacGPSBabel window needed if any of the GPS check boxes are checked by default + if state of button "GPSswitchIN" of window "MacGPSBabel" is equal to 1 then + my gpsIN() + end if + if state of button "GPSswitchOUT" of window "MacGPSBabel" is equal to 1 then + my gpsOUT() + end if + end if +end awake from nib + +-- Deal with the opening and closing of windows + +on will open theObject + + log "will open - " & name of theObject + -- Main Window + if theObject is window "MacGPSBabel" then + -- set the progress indicator style + set p to progress indicator 1 of theObject + call method "setStyle:" of p with parameter 1 + call method "setDisplayedWhenStopped:" of p with parameters {false} + end if + + -- Select GPS Window + if theObject is window "SelectGPS" then + -- get the list of available serial ports + set popList to my getSerial() + -- use popList to populate the drop-down menu + delete every menu item of menu of popup button "serialPop" of window "SelectGPS" + repeat with i in popList + make new menu item at the end of menu items of menu of popup button "serialPop" of window "SelectGPS" with properties {title:i, enabled:true} + end repeat + make new menu item at the end of menu items of menu of popup button "serialPop" of window "SelectGPS" with properties {title:"Garmin USB", enabled:true} + + -- read user defaults for this window + tell user defaults + set defaultgpsReceiver to contents of default entry "gpsReceiver" + end tell + set state of popup button "gpsPop" of window "SelectGPS" to defaultgpsReceiver + + -- hide MacGPSBabel window + set visible of window "MacGPSBabel" to false + end if + +end will open + +-- to work around the NSReceiverEvaluationScriptError we need to use should close instead of will close +on should close theObject + log "will close - " & name of theObject + if theObject is window "SelectGPS" then + -- store user defaults for this window + set newReceiverIndex to contents of popup button "gpsPop" of window "SelectGPS" as integer + tell user defaults + set contents of default entry "gpsReceiver" to newReceiverIndex + end tell + + -- unhide MacGPSBabel window + set visible of window "MacGPSBabel" to true + end if + + if theObject is window "filterWindow" then + set the title of button "filterButton" of window "MacGPSBabel" to "Setup Filters" + end if + + -- workarund NSReceiverEvaluationScriptError bug + set visible of theObject to false + return false + +end should close + + +-- handler for the File>Open menu item +on choose menu item theObject + log "choose menu item - " & name of theObject + + -- mainMenu File>Open + if name of theObject is "open" then + if visible of window "MacGPSBabel" is true then + if contents of text field "inputFile" of window "MacGPSBabel" is equal to "" then + my selectFile() + return 0 + else if the title of current menu item of popup button "inPop" of window "MacGPSBabel" = "Select Input File Type" then + display dialog "Please select an input file type for the previous file before adding another file" buttons {"OK"} default button 1 + return 0 + else if item 1 of (the last item in fileList) is not equal to (contents of text field "inputFile" of window "MacGPSBabel") then + set the end of fileList to {contents of text field "inputFile" of window "MacGPSBabel", contents of popup button "inPop" of window "MacGPSBabel"} + end if + my addFile() + else + set visible of window "MacGPSBabel" to true + if contents of text field "inputFile" of window "MacGPSBabel" is equal to "" then + my selectFile() + return 0 + else if the title of current menu item of popup button "inPop" of window "MacGPSBabel" = "Select Input File Type" then + display dialog "Please select an input file type for the previous file before adding another file" buttons {"OK"} default button 1 + return 0 + else if item 1 of (the last item in fileList) is not equal to (contents of text field "inputFile" of window "MacGPSBabel") then + set the end of fileList to {contents of text field "inputFile" of window "MacGPSBabel", contents of popup button "inPop" of window "MacGPSBabel"} + end if + my addFile() + end if + end if + + if name of theObject is "modePop" then + my getFormats() + end if +end choose menu item + +-- HANDLERS FOR BUTTON CLICKS + +on clicked theObject + log "clicked - " & name of theObject + + -- MAIN WINDOW - Select File button + if theObject is the button "selectButton" of window "MacGPSBabel" then + if contents of text field "inputFile" of window "MacGPSBabel" is equal to "" then + my selectFile() + return 0 + else if the title of current menu item of popup button "inPop" of window "MacGPSBabel" = "Select Input File Type" then + display dialog "Please select an input file type for the previous file before adding another file" buttons {"OK"} default button 1 + return 0 + else if fileList is equal to {} or item 1 of (the last item in fileList) is not equal to (contents of text field "inputFile" of window "MacGPSBabel") then + set the end of fileList to {contents of text field "inputFile" of window "MacGPSBabel", contents of popup button "inPop" of window "MacGPSBabel"} + end if + my addFile() + end if + + -- MAIN WINDOW - Clear button + if theObject is the button "clearButton" of window "MacGPSBabel" then + my clearFiles() + end if + + -- MAIN WINDOW - Send button + if theObject is the button "sendButton" of window "MacGPSBabel" then + if state of button "GPSswitchIN" of window "MacGPSBabel" = 1 then + set fileList to {} + else if fileList is equal to {} or item 1 of (the last item in fileList) is not equal to (contents of text field "inputFile" of window "MacGPSBabel") then + set the end of fileList to {contents of text field "inputFile" of window "MacGPSBabel", contents of popup button "inPop" of window "MacGPSBabel"} + end if + my sendFile(fileList) + end if + + -- MAIN WINDOW - Use GPS radio buttons + if theObject is the button "GPSswitchIN" of window "MacGPSBabel" then + my GPSSwitchIN() + if (state of button "GPSswitchIN" of window "MacGPSBabel" = 1) and (state of button "GPSswitchOUT" of window "MacGPSBabel" = 1) then + set state of button "GPSswitchOUT" of window "MacGPSBabel" to 0 + my GPSswitchOUT() + end if + end if + if theObject is the button "GPSswitchOUT" of window "MacGPSBabel" then + my GPSswitchOUT() + if (state of button "GPSswitchOUT" of window "MacGPSBabel" = 1) and (state of button "GPSswitchIN" of window "MacGPSBabel" = 1) then + set state of button "GPSswitchIN" of window "MacGPSBabel" to 0 + my GPSSwitchIN() + end if + end if + + -- MAIN WINDOW - Filters button + if theObject is the button "filterButton" of window "MacGPSBabel" then + my showFilters() + end if + + -- MAIN WINDOW - Set As Defaults Button + if theObject is button "defaultsButton" of window "MacGPSBabel" then + set newInputIndex to contents of popup button "inPop" of window "MacGPSBabel" + set newOutputIndex to contents of popup button "outPop" of window "MacGPSBabel" + set newINstate to state of button "GPSswitchIN" of window "MacGPSBabel" as boolean + set newOUTstate to state of button "GPSswitchOUT" of window "MacGPSBabel" as boolean + tell user defaults + set contents of default entry "theInputType" to newInputIndex + set contents of default entry "theOutputType" to newOutputIndex + set contents of default entry "gpsIN" to newINstate + set contents of default entry "gpsOUT" to newOUTstate + end tell + end if + + -- GPS Receiver Window - Continue button + if theObject is the button "contButton" of window "SelectGPS" then + if the state of button "GPSswitchIN" of window "MacGPSBabel" = 1 then + my downloadFile() + else + my uploadFile(fileList) + end if + end if + + -- GPS Receiver Window - Cancel button + if theObject is the button "cancelButton" of window "SelectGPS" then + close window "SelectGPS" + end if + + -- Filter Window - Distance filter check box + if theObject is the button "distanceFilter" of window "filterWindow" then + if state of button "distanceFilter" of window "filterWindow" is equal to 1 then + set enabled of text field "dist1" of window "filterWindow" to true + set editable of text field "dist1" of window "filterWindow" to true + set enabled of popup button "dist1Select" of window "filterWindow" to true + tell window "filterWindow" + set first responder to text field "dist1" + end tell + else + set enabled of text field "dist1" of window "filterWindow" to false + set editable of text field "dist1" of window "filterWindow" to false + set enabled of popup button "dist1Select" of window "filterWindow" to false + end if + end if + + -- Filter Window - Radius Filter check box + if theObject is the button "radiusFilter" of window "filterWindow" then + if state of button "radiusFilter" of window "filterWindow" is equal to 1 then + set enabled of text field "dist2" of window "filterWindow" to true + set editable of text field "dist2" of window "filterWindow" to true + set enabled of popup button "dist2Select" of window "filterWindow" to true + set enabled of popup button "nsSelect" of window "filterWindow" to true + set enabled of popup button "ewSelect" of window "filterWindow" to true + set enabled of text field "nDeg" of window "filterWindow" to true + set editable of text field "nDeg" of window "filterWindow" to true + set enabled of text field "nMin" of window "filterWindow" to true + set editable of text field "nMin" of window "filterWindow" to true + set enabled of text field "wDeg" of window "filterWindow" to true + set editable of text field "wDeg" of window "filterWindow" to true + set enabled of text field "wMin" of window "filterWindow" to true + set editable of text field "wMin" of window "filterWindow" to true + set enabled of button "makeHomeButton" of window "filterWindow" to true + set enabled of button "useHomeButton" of window "filterWindow" to true + tell window "filterWindow" + set first responder to text field "dist2" + end tell + else + set enabled of text field "dist2" of window "filterWindow" to false + set editable of text field "dist2" of window "filterWindow" to false + set enabled of popup button "dist2Select" of window "filterWindow" to false + set enabled of popup button "nsSelect" of window "filterWindow" to false + set enabled of popup button "ewSelect" of window "filterWindow" to false + set enabled of text field "nDeg" of window "filterWindow" to false + set editable of text field "nDeg" of window "filterWindow" to false + set enabled of text field "nMin" of window "filterWindow" to false + set editable of text field "nMin" of window "filterWindow" to false + set enabled of text field "wDeg" of window "filterWindow" to false + set editable of text field "wDeg" of window "filterWindow" to false + set enabled of text field "wMin" of window "filterWindow" to false + set editable of text field "wMin" of window "filterWindow" to false + set enabled of button "makeHomeButton" of window "filterWindow" to false + set enabled of button "useHomeButton" of window "filterWindow" to false + end if + end if + + -- Filter Window - Make Home Button + if theObject is button "makeHomeButton" of window "filterWindow" then + set newNSIndex to contents of popup button "nsSelect" of window "filterWindow" + set newEWIndex to contents of popup button "ewSelect" of window "filterWindow" + set newNDeg to contents of text field "nDeg" of window "filterWindow" + set newNMin to contents of text field "nMin" of window "filterWindow" + set newWDeg to contents of text field "wDeg" of window "filterWindow" + set newWMin to contents of text field "wMin" of window "filterWindow" + tell user defaults + set contents of default entry "filterNSSelect" to newNSIndex as integer + set contents of default entry "filterEWSelect" to newEWIndex as integer + set contents of default entry "filterNDeg" to newNDeg as integer + set contents of default entry "filterNMin" to newNMin as number + set contents of default entry "filterWDeg" to newWDeg as integer + set contents of default entry "filterWMin" to newWMin as number + end tell + end if + + -- Filter Window - Use Home Button + if theObject is button "useHomeButton" of window "filterWindow" then + tell user defaults + set homeNSSelectIndex to contents of default entry "filterNSSelect" as integer + set homeEWSelectIndex to contents of default entry "filterEWSelect" as integer + set homeNDeg to contents of default entry "filterNDeg" as integer + set homeWDeg to contents of default entry "filterWDeg" as integer + set homeNMin to contents of default entry "filterNMin" as number + set homeWMin to contents of default entry "filterWMin" as number + end tell + set contents of popup button "nsSelect" of window "filterWindow" to homeNSSelectIndex + set contents of popup button "ewSelect" of window "filterWindow" to homeEWSelectIndex + set contents of text field "nDeg" of window "filterWindow" to homeNDeg + set contents of text field "wDeg" of window "filterWindow" to homeWDeg + set contents of text field "nMin" of window "filterWindow" to homeNMin + set contents of text field "wMin" of window "filterWindow" to homeWMin + end if + + -- Filter Window - Duplicate filter check boxes + if theObject is the button "locationFilter" of window "filterWindow" then + if state of button "locationFilter" of window "filterWindow" is equal to 1 then + set enabled of button "allSwitch" of window "filterWindow" to 1 + else if state of button "shortFilter" of window "filterWindow" is equal to 0 then + set enabled of button "allSwitch" of window "filterWindow" to 0 + end if + end if + + if theObject is the button "shortFilter" of window "filterWindow" then + if state of button "shortFilter" of window "filterWindow" is equal to 1 then + set enabled of button "allSwitch" of window "filterWindow" to 1 + else if state of button "locationFilter" of window "filterWindow" is equal to 0 then + set enabled of button "allSwitch" of window "filterWindow" to 0 + end if + end if + + -- Filter Window - Arc filter check box + if theObject is the button "arcSwitch" of window "filterWindow" then + if state of button "arcSwitch" of window "filterWindow" is equal to 1 then + try + set fFile to choose file with prompt "Select an arc filter file" + on error + set state of button "arcSwitch" of window "filterWindow" to 0 + return 0 + end try + set contents of text field "arcFile" of window "filterWindow" to POSIX path of fFile as string + set enabled of text field "arcDist" of window "filterWindow" to true + set editable of text field "arcDist" of window "filterWindow" to true + set enabled of popup button "arcUnits" of window "filterWindow" to true + set enabled of button "arcPointsSwitch" of window "filterWindow" to true + else + set contents of text field "arcFile" of window "filterWindow" to "" + set contents of text field "arcDist" of window "filterWindow" to "" + set enabled of text field "arcDist" of window "filterWindow" to false + set editable of text field "arcDist" of window "filterWindow" to false + set enabled of popup button "arcUnits" of window "filterWindow" to false + set enabled of button "arcPointsSwitch" of window "filterWindow" to false + end if + end if + + -- Filter Window - polygon filter check box + if theObject is the button "polySwitch" of window "filterWindow" then + if state of button "polySwitch" of window "filterWindow" is equal to 1 then + try + set pFile to choose file with prompt "Select a polygon filter file" + on error + set state of button "polySwitch" of window "filterWindow" to 0 + return 0 + end try + set contents of text field "polyFile" of window "filterWindow" to POSIX path of pFile as string + else + set contents of text field "polyFile" of window "filterWindow" to "" + end if + end if + + -- Filter Window - Smart names check box + if theObject is the button "smartSwitch" of window "filterWindow" then + if state of button "smartSwitch" of window "filterWindow" is equal to 1 then + set enabled of text field "smartLen" of window "filterWindow" to true + set editable of text field "smartLen" of window "filterWindow" to true + set contents of text field "smartLen" of window "filterWindow" to "" + else + set enabled of text field "smartLen" of window "filterWindow" to false + set editable of text field "smartLen" of window "filterWindow" to false + end if + end if + + --debug mode + if theObject is the button "debugButton" of window "MacGPSBabel" then + if (visible of window "debugWindow") is false then + set visible of window "debugWindow" to true + else + set visible of window "debugWindow" to false + end if + end if + if theObject is the button "executeButton" of window "debugWindow" then + set theScript to contents of text field "debugInput" of window "debugWindow" + if theScript starts with "gpsbabel" then + set thePath to quoted form of (POSIX path of (path to me) as string) & "Contents/Resources/" + set theScript to thePath & theScript + end if + set theOutput to do shell script theScript as string + set the contents of text view 1 of scroll view 1 of window "debugWindow" to "" + set the contents of text view 1 of scroll view 1 of window "debugWindow" to theOutput + end if + +end clicked + + +-- MY HANDLERS -- + + +-- SCRIPTS FOR CHOOSING THE INPUT FILE +-- select the first file +on selectFile() + -- Choose a file (using the open file dialog box) + set aFile to choose file with prompt "Select an input file" + set contents of text field "inputFile" of window "MacGPSBabel" to aFile + if contents of text field "inputFile" of window "MacGPSBabel" is not equal to "" then + set key equivalent of button "selectButton" of window "MacGPSBabel" to "" + set enabled of button "sendButton" of window "MacGPSBabel" to true + set enabled of button "clearButton" of window "MacGPSBabel" to true + set the title of button "selectButton" of window "MacGPSBabel" to "Add File" + end if +end selectFile +-- add another file +on addFile() + -- Choose a file (using the open file dialog box) + set aFile to choose file with prompt "Select another input file" + set contents of text field "inputFile" of window "MacGPSBabel" to aFile + set the contents of popup button "inPop" of window "MacGPSBabel" to 0 +end addFile + +-- SCRIPTS FOR CONTROLLING THE CONVERSION +-- work out which kind of conversion to do +on sendFile(fileList) + -- check for options selected + if state of button "GPSswitchIN" of window "MacGPSBabel" = 1 then + my GPSSend() + return 0 + else if state of button "GPSswitchOUT" of window "MacGPSBabel" = 1 then + set visible of window "SelectGPS" to true + return 0 + else if the title of current menu item of popup button "inPop" of window "MacGPSBabel" = "Select Input File Type" then + display dialog "Please select an input file type" buttons {"OK"} default button 1 + return 0 + else if the title of current menu item of popup button "outPop" of window "MacGPSBabel" = "Select Output File Type" then + display dialog "Please select an output file type" buttons {"OK"} default button 1 + return 0 + end if + + -- select where to save the file + my convertFile(fileList) +end sendFile + +-- this script handles conversions between file types +on convertFile(fileList) + -- create string for filters + if visible of window "filterWindow" is true then + set filterText to my applyFilters() + else + set filterText to "" + end if + + -- waypoint, routes or tracks + if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Tracks" then + set trackText to " -t" + else if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Routes" then + set trackText to " -r" + else + set trackText to "" + end if + + -- create string for input files + set fileText to "" + repeat with theItem in fileList + set currentInIndex to item 2 of theItem + set inType to item (currentInIndex) of inTypeList + set inputFile to quoted form of item 1 of theItem + set fileText to fileText & " -i " & inType & " -f " & inputFile + end repeat + + -- create strings for output file + set currentOutIndex to contents of popup button "outPop" of window "MacGPSBabel" + set outType to item (currentOutIndex) of outTypeList + if visible of window "filterWindow" is true then + if state of button "smartSwitch" of window "filterWindow" is equal to 1 then + set smartSwitch to " -s" + if contents of text field "smartLen" of window "filterWindow" is not equal to "" then + set outType to outType & ",snlen=" & ((contents of text field "smartLen" of window "filterWindow") as integer) & " " + end if + else + set smartSwitch to "" + end if + else + set smartSwitch to "" + end if + set OutExt to item (currentOutIndex) of extList + -- set outPath to directory of aFile + tell save panel + set title to "Save Output As" + set prompt to "Save" + set treat packages as directories to 0 + end tell + set oldDelimiters to AppleScript's text item delimiters + set AppleScript's text item delimiters to "/" + set TempFileName to last text item of inputFile + set AppleScript's text item delimiters to "." + set TempFileName to the first text item of TempFileName + set AppleScript's text item delimiters to oldDelimiters + if OutExt is not equal to "" then + set TempFileName to TempFileName & "." & OutExt + end if + set theResult to display save panel in directory aFile with file name TempFileName + if theResult is 1 then + set outputFile to (path name of save panel) as string + else + set outputFile to "" + display dialog "conversion cancelled" buttons {"OK"} default button 1 + return 0 + end if + -- do the script + set thePath to POSIX path of (path to me) as string + set theConvertScript to (quoted form of thePath & "Contents/Resources/gpsbabel" & smartSwitch & trackText & fileText & " " & filterText & "-o " & outType & " -F " & quoted form of outputFile) as string + if (my runBabel(theConvertScript)) then + display dialog "File conversion is complete" buttons {"OK"} default button 1 + else + display dialog "Sorry, the file conversion failed" buttons {"OK"} default button 1 + end if + my clearFiles() +end convertFile + +-- GPS RECEIVER HANDLERS +-- open the GPS receiver window +on GPSSend() + if the title of current menu item of popup button "outPop" of window "MacGPSBabel" = "Select Output File Type" then + display dialog "Please select an output file type" buttons {"OK"} default button 1 + else + set visible of window "SelectGPS" to true + end if +end GPSSend +-- deal with uploading files to GPS receiver +on uploadFile(fileList) + -- create string for filters + if visible of window "filterWindow" is true then + set filterText to my applyFilters() + else + set filterText to "" + end if + + -- waypoint, routes or tracks + if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Tracks" then + set trackText to " -t" + else if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Routes" then + set trackText to " -r" + else + set trackText to "" + end if + + -- create string for input files + set fileText to "" + repeat with theItem in fileList + set currentInIndex to item 2 of theItem + set inType to item (currentInIndex) of inTypeList + set inputFile to quoted form of item 1 of theItem + set fileText to fileText & " -i " & inType & " -f " & inputFile + end repeat + + -- create string for GPS unit + if the title of popup button "gpsPop" of window "selectGPS" is equal to "Garmin" then + set gpsRText to "garmin" + else + set gpsRText to "magellan" + end if + if visible of window "filterWindow" is true then + if state of button "smartSwitch" of window "filterWindow" is equal to 1 then + set smartSwitch to " -s" + if contents of text field "smartLen" of window "filterWindow" is not equal to "" then + set gpsText to gpsRText & ",snlen=" & ((contents of text field "smartLen" of window "filterWindow") as integer) + else + set gpsText to gpsRText + end if + else + set smartSwitch to "" + set gpsText to gpsRText + end if + else + set smartSwitch to "" + set gpsText to gpsRText + end if + + -- get the port + if the the title of popup button "serialPop" of window "selectGPS" is equal to "Garmin USB" then + set serialText to "usb:" + else + set serialText to quoted form of ("/dev/cu." & (the title of popup button "serialPop" of window "selectGPS")) + end if + + -- run the script + set thePath to POSIX path of (path to me) as string + set visible of window "SelectGPS" to false + set visible of window "MacGPSBabel" to true + + set theConvertScript to (quoted form of thePath & "Contents/Resources/gpsbabel" & smartSwitch & trackText & fileText & " " & filterText & "-o " & gpsText & " -F " & serialText) + if (my runBabel(theConvertScript)) then + display dialog "Upload to " & gpsRText & " GPS receiver is complete" buttons {"OK"} default button 1 + else + display dialog "Sorry, upload to " & gpsRText & " GPS receiver failed" buttons {"OK"} default button 1 + end if + my clearFiles() +end uploadFile +-- deal with downloading files from GPS receiver +on downloadFile() + set outName to "Waypoints." + if visible of window "filterWindow" is true then + set filterText to my applyFilters() + else + set filterText to "" + end if + + -- waypoint, routes or tracks + if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Tracks" then + set trackText to " -t" + set outName to "Tracks." + else if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Routes" then + set trackText to " -r" + set outName to "Routes." + else + set trackText to "" + end if + set thePath to POSIX path of (path to me) as string + + tell save panel + set title to "Save Output As" + set prompt to "Save" + set treat packages as directories to 0 + end tell + + set currentOutIndex to contents of popup button "outPop" of window "MacGPSBabel" + set outType to item (currentOutIndex) of outTypeList + if visible of window "filterWindow" is true then + if state of button "smartSwitch" of window "filterWindow" is equal to 1 then + set smartSwitch to " -s" + if contents of text field "smartLen" of window "filterWindow" is not equal to "" then + set outType to outType & ",snlen=" & ((contents of text field "smartLen" of window "filterWindow") as integer) & " " + end if + else + set smartSwitch to "" + end if + else + set smartSwitch to "" + end if + set OutExt to item (currentOutIndex) of extList + set TempFileName to outName & OutExt + set theResult to display save panel in directory "~/Desktop" with file name TempFileName + if theResult is 1 then + set outputFile to (path name of save panel) as string + if the title of popup button "gpsPop" of window "selectGPS" is equal to "Garmin" then + set gpsText to " garmin " + else + set gpsText to " magellan " + end if + -- get the port + if the the title of popup button "serialPop" of window "selectGPS" is equal to "Garmin USB" then + set serialText to "usb:" + else + set serialText to quoted form of ("/dev/cu." & (the title of popup button "serialPop" of window "selectGPS")) + end if + set visible of window "SelectGPS" to false + set visible of window "MacGPSBabel" to true + set theConvertScript to (quoted form of thePath & "Contents/Resources/gpsbabel" & smartSwitch & trackText & " -i" & gpsText & "-f " & serialText & filterText & " -o " & outType & " -F " & quoted form of outputFile) + if (my runBabel(theConvertScript)) then + display dialog "Download from" & gpsText & "GPS receiver is complete" buttons {"OK"} default button 1 + else + display dialog "Sorry, download from" & gpsText & "GPS receiver failed" buttons {"OK"} default button 1 + end if + else + set outputFile to "" + end if + my clearFiles() +end downloadFile + +-- Send the call to gpsbabel +on runBabel(theConvertScript) + log "Tried to execute: " & theConvertScript + set theConvertScript to theConvertScript & " 2>&1" + feedbackBusy(true) + try + set scriptOut to do shell script theConvertScript as string + set babelHappy to true + set convertYN to "ran successfully" + log "Success! gpsbabel returned: " & scriptOut + on error + set scriptOut to "gpsbabel encountered an error" + set babelHappy to false + set convertYN to "failed" + log "Error! gpsbabel returned: " & scriptOut + end try + feedbackBusy(false) + if visible of window "debugWindow" is true then + set the contents of text view 1 of scroll view 1 of window "debugWindow" to "" + set the contents of text view 1 of scroll view 1 of window "debugWindow" to "MacGPSBabel Report" & return & return & "The Shell Script:" & return & theConvertScript & return & return & convertYN & return & return & "Output From gpsbabel:" & return & scriptOut + end if + return babelHappy +end runBabel + + + + +-- FILTERING HANDLERS +-- show filters window +on showFilters() + if visible of window "filterWindow" is false then + set visible of window "filterWindow" to true + set the title of button "filterButton" of window "MacGPSBabel" to "Remove Filters" + else + set visible of window "filterWindow" to false + set the title of button "filterButton" of window "MacGPSBabel" to "Setup Filters" + end if +end showFilters + +-- create the filter code +on applyFilters() + set filterText to "" + if state of button "distanceFilter" of window "filterWindow" is equal to 1 then + set distanceText to "-x position" + if contents of text field "dist1" of window "filterWindow" is not equal to "" then + set distanceText to distanceText & ",distance=" & (contents of text field "dist1" of window "filterWindow") + if title of popup button "dist1Select" of window "filterWindow" is equal to "Feet" then + set distanceText to distanceText & "f " + else + set distanceText to distanceText & "m " + end if + end if + else + set distanceText to "" + end if + if state of button "radiusFilter" of window "filterWindow" is equal to 1 then + set radiusText to "-x radius" + if contents of text field "dist2" of window "filterWindow" is not equal to "" then + set radiusText to radiusText & ",distance=" & (contents of text field "dist2" of window "filterWindow") + if title of popup button "dist2Select" of window "filterWindow" is equal to "Miles" then + set radiusText to radiusText & "M" + else + set radiusText to radiusText & "K" + end if + if the title of current menu item of popup button "nsSelect" of window "filterWindow" = "N" then + set lat to 1 + else + set lat to -1 + end if + if the title of current menu item of popup button "ewSelect" of window "filterWindow" = "W" then + set lon to -1 + else + set lon to 1 + end if + set latDeg to lat * (((the contents of text field "nDeg" of window "filterWindow") as number) + (((the contents of text field "nMin" of window "filterWindow") as number) / 60)) as string + set lonDeg to lon * ((the contents of text field "wDeg" of window "filterWindow") + ((the contents of text field "wMin" of window "filterWindow") / 60)) as string + set radiusText to radiusText & ",lat=" & latDeg & ",lon=" & lonDeg & " " + end if + else + set radiusText to "" + end if + if state of button "locationFilter" of window "filterWindow" is equal to 1 then + set duplicateText to "-x duplicate,location" + if state of button "shortFilter" of window "filterWindow" is not equal to 1 then + set duplicateText to duplicateText & " " + end if + else + set duplicateText to "" + end if + if state of button "shortFilter" of window "filterWindow" is equal to 1 then + if duplicateText is not equal to "" then + set duplicateText to duplicateText & ",shortname " + else + set duplicateText to "-x duplicate,shortname " + end if + end if + if state of button "arcSwitch" of window "filterWindow" is equal to 1 then + if (contents of text field "arcDist" of window "filterWindow" is not equal to "") then + if title of popup button "arcUnits" of window "filterWindow" is equal to "Miles" then + set aUnit to "M" + else + set aUnit to "K" + end if + set arcDistance to (contents of text field "arcDist" of window "filterWindow") & aUnit + set arcText to "-x arc,file='" & (contents of text field "arcFile" of window "filterWindow") & "',distance=" & arcDistance + if the state of button "arcPointsSwitch" of window "filterWindow" is equal to 1 then + set arcText to arcText & ",points" + end if + set arcText to arcText & " " + else + display dialog "Please input a distance for the arc filter" buttons ["OK"] default button 1 + set arcText to "" + break + end if + else + set arcText to "" + end if + if state of button "polySwitch" of window "filterWindow" is equal to 1 then + set polyText to "-x polygon,file='" & (contents of text field "polyFile" of window "filterWindow") & "'" + else + set polyText to "" + end if + set filterText to distanceText & radiusText & duplicateText & arcText & polyText + return filterText +end applyFilters + +-- handlers to deal with the GPS receiver checkboxes +on GPSSwitchIN() + if state of button "GPSswitchIN" of window "MacGPSBabel" = 1 then + set enabled of button "selectButton" of window "MacGPSBabel" to false + set enabled of button "clearButton" of window "MacGPSBabel" to false + set enabled of button "sendButton" of window "MacGPSBabel" to true + set contents of text field "inputFile" of window "MacGPSBabel" to "" + set enabled of text field "inputFile" of window "MacGPSBabel" to false + set enabled of popup button "inPop" of window "MacGPSBabel" to false + set title of button "sendButton" of window "MacGPSBabel" to "Download..." + else + set enabled of button "selectButton" of window "MacGPSBabel" to true + set enabled of button "sendButton" of window "MacGPSBabel" to false + set enabled of text field "inputFile" of window "MacGPSBabel" to true + set enabled of popup button "inPop" of window "MacGPSBabel" to true + end if + if state of button "GPSswitchIN" of window "MacGPSBabel" = 0 and state of button "GPSswitchOUT" of window "MacGPSBabel" = 0 then + set title of button "sendButton" of window "MacGPSBabel" to "Convert" + end if +end GPSSwitchIN +on GPSswitchOUT() + if state of button "GPSswitchOUT" of window "MacGPSBabel" = 1 then + set enabled of popup button "outPop" of window "MacGPSBabel" to false + set title of button "sendButton" of window "MacGPSBabel" to "Upload..." + else + set enabled of popup button "outPop" of window "MacGPSBabel" to true + end if + if state of button "GPSswitchIN" of window "MacGPSBabel" = 0 and state of button "GPSswitchOUT" of window "MacGPSBabel" = 0 then + set title of button "sendButton" of window "MacGPSBabel" to "Convert" + end if +end GPSswitchOUT + +-- start/stop the Main window's progress indicator +on feedbackBusy(yn) + tell window "MacGPSBabel" + if yn then + start progress indicator 1 + else + stop progress indicator 1 + end if + end tell +end feedbackBusy + +on clearFiles() + set contents of text field "inputFile" of window "MacGPSBabel" to "" + set fileList to {} + set title of button "selectButton" of window "MacGPSBabel" to "Select File" + set enabled of button "sendButton" of window "MacGPSBabel" to false + set key equivalent of button "selectButton" of window "MacGPSBabel" to return + set enabled of button "clearButton" of window "MacGPSBabel" to false + + -- reset controls to user defaults + -- read current user defaults and set window controls as needed + if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Waypoints" then + my readSettings() + end if + + -- deal with changes to MacGPSBabel window needed if any of the GPS check boxes are checked by default + my gpsIN() + my gpsOUT() +end clearFiles + + +-- read user defaults +on readSettings() + tell user defaults + set defaultInputIndex to contents of default entry "theInputType" as integer + set defaultOutputIndex to contents of default entry "theOutputType" as integer + set defaultgpsIN to contents of default entry "gpsIN" as boolean + set defaultgpsOUT to contents of default entry "gpsOUT" as boolean + end tell + set contents of popup button "inPop" of window "MacGPSBabel" to defaultInputIndex + set contents of popup button "outPop" of window "MacGPSBabel" to defaultOutputIndex + set state of button "GPSswitchIN" of window "MacGPSBabel" to defaultgpsIN + set state of button "GPSswitchOUT" of window "MacGPSBabel" to defaultgpsOUT +end readSettings + +-- scripts for dealing with GPS checkboxes on MacGPSBabel window +on gpsIN() + if state of button "GPSswitchIN" of window "MacGPSBabel" = 1 then + set enabled of button "selectButton" of window "MacGPSBabel" to false + set enabled of button "clearButton" of window "MacGPSBabel" to false + set enabled of button "sendButton" of window "MacGPSBabel" to true + set contents of text field "inputFile" of window "MacGPSBabel" to "" + set enabled of text field "inputFile" of window "MacGPSBabel" to false + set enabled of popup button "inPop" of window "MacGPSBabel" to false + else + set enabled of button "selectButton" of window "MacGPSBabel" to true + set enabled of button "sendButton" of window "MacGPSBabel" to false + set enabled of text field "inputFile" of window "MacGPSBabel" to true + set enabled of popup button "inPop" of window "MacGPSBabel" to true + end if +end gpsIN +on gpsOUT() + if state of button "GPSswitchOUT" of window "MacGPSBabel" = 1 then + set enabled of popup button "outPop" of window "MacGPSBabel" to false + else + set enabled of popup button "outPop" of window "MacGPSBabel" to true + end if +end gpsOUT + +-- List Populating Handlers + +-- find the serial ports +on getSerial() + set myList to {} + set theScript to "cd /dev; ls | grep cu\\." + set scriptOut to (do shell script theScript) as string + set theCount to count of paragraphs in scriptOut + set i to 0 + set defaultDelimiters to AppleScript's text item delimiters + set AppleScript's text item delimiters to {"."} + repeat until i = theCount + set i to i + 1 + set theWords to the count of text items in paragraph i of scriptOut + set z to 2 + set the end of myList to (text items z thru theWords of paragraph i of scriptOut) as string + end repeat + set AppleScript's text item delimiters to defaultDelimiters + return myList +end getSerial + +-- handler (called at startup) to check with GPS Babel which file formats it can handle. +-- Populates global lists with file types and capabilities +on getFormats() + set inFormatList to {} + set outFormatList to {} + set inTypeList to {} + set outTypeList to {} + set extList to {} + set thePath to POSIX path of (path to me) as string + set scriptOut to (do shell script quoted form of thePath & "Contents/Resources/gpsbabel -^2") as string + set theCount to count of paragraphs in scriptOut + set defaultDelimiters to AppleScript's text item delimiters + set AppleScript's text item delimiters to tab + repeat with i from 1 to theCount + set theLine to paragraph i of scriptOut + if (first text item of theLine) is equal to "file" then + if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Waypoints" then + if the first character of the second text item of theLine is equal to "r" then + set the end of inTypeList to the third text item of theLine + set the end of inFormatList to the last text item of theLine + end if + if the second character of the second text item of theLine is equal to "w" then + set the end of extList to the 4th text item of theLine + set the end of outTypeList to the third text item of theLine + set the end of outFormatList to the last text item of theLine + end if + end if + if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Tracks" then + if the third character of the second text item of theLine is equal to "r" then + set the end of inTypeList to the third text item of theLine + set the end of inFormatList to the last text item of theLine + end if + if the 4th character of the second text item of theLine is equal to "w" then + set the end of extList to the 4th text item of theLine + set the end of outTypeList to the third text item of theLine + set the end of outFormatList to the last text item of theLine + end if + end if + if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Routes" then + if the 5th character of the second text item of theLine is equal to "r" then + set the end of inTypeList to the third text item of theLine + set the end of inFormatList to the last text item of theLine + end if + if the 6th character of the second text item of theLine is equal to "w" then + set the end of extList to the 4th text item of theLine + set the end of outTypeList to the third text item of theLine + set the end of outFormatList to the last text item of theLine + end if + end if + end if + end repeat + set AppleScript's text item delimiters to defaultDelimiters + + -- set current menu item of popup button "inPop" of window "MacGPSBabel" to menu item 1 of menu of popup button "inPop" of window "MacGPSBabel" + -- set current menu item of popup button "outPop" of window "MacGPSBabel" to menu item 1 of menu of popup button "outPop" of window "MacGPSBabel" + + tell window "MacGPSBabel" + if (count of menu items of popup button "inPop") is greater than 0 then + delete every menu item of menu of popup button "inPop" + make new menu item at the end of menu items of menu of popup button "inPop" with properties {title:"Select Input File Type", enabled:true} + delete every menu item of menu of popup button "outPop" + make new menu item at the end of menu items of menu of popup button "outPop" with properties {title:"Select Output File Type", enabled:true} + end if + repeat with i in inFormatList + make new menu item at the end of menu items of menu of popup button "inPop" with properties {title:i, enabled:true} + end repeat + repeat with i in outFormatList + make new menu item at the end of menu items of menu of popup button "outPop" with properties {title:i, enabled:true} + end repeat + end tell + + if the title of popup button "modePop" of window "MacGPSBabel" is equal to "Waypoints" then + my readSettings() + end if + +end getFormats \ No newline at end of file diff --git a/macgpsbabel/MacGPSBabel.pbproj/default.pbxuser b/macgpsbabel/MacGPSBabel.pbproj/default.pbxuser new file mode 100644 index 000000000..b9c3ff46f --- /dev/null +++ b/macgpsbabel/MacGPSBabel.pbproj/default.pbxuser @@ -0,0 +1,26 @@ +// !$*UTF8*$! +{ + 29B97326FDCFA39411CA2CEA = { + activeExec = 0; + targetExecs = { + macosx = ( + DA206CF0015C4D9F03C91932, + ); + }; + }; + DA206CF0015C4D9F03C91932 = { + activeArgIndex = 2147483647; + argumentStrings = ( + ); + debuggerPlugin = ASKDebugger; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + isa = PBXExecutable; + shlibInfoDictList = ( + ); + sourceDirectories = ( + ); + }; +} diff --git a/macgpsbabel/MacGPSBabel.pbproj/jeremya.pbxuser b/macgpsbabel/MacGPSBabel.pbproj/jeremya.pbxuser new file mode 100644 index 000000000..3964792fb --- /dev/null +++ b/macgpsbabel/MacGPSBabel.pbproj/jeremya.pbxuser @@ -0,0 +1,1034 @@ +// !$*UTF8*$! +{ + 089C165DFE840E0CC02AAC07 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 428}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{19, 183}, {750, 558}}"; + }; + }; + 29B97313FDCFA39411CA2CEA = { + activeBuildStyle = 4A9504CCFFE6A4B311CA0CBA; + activeExecutable = DA206CF0015C4D9F03C91932; + activeTarget = 29B97326FDCFA39411CA2CEA; + addToTargets = ( + 29B97326FDCFA39411CA2CEA, + ); + breakpoints = ( + ); + codeSenseManager = 3F8AAF0906E7E5D400E74F19; + executables = ( + DA206CF0015C4D9F03C91932, + ); + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 604, + 20, + 108, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXSymbolsDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXSymbolsDataSource_SymbolNameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 16, + 132.8008, + 161.0356, + 138.2085, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXSymbolsDataSource_SymbolTypeIconID, + PBXSymbolsDataSource_SymbolNameID, + PBXSymbolsDataSource_SymbolTypeID, + PBXSymbolsDataSource_ReferenceNameID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.XCSCMDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 20, + 226, + 20, + 40, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_SCM_ColumnID, + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 210, + 50, + 20, + 50, + 43, + 43, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXTargetDataSource_PrimaryAttribute, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 116907658; + PBXPrepackagedSmartGroups_v2 = ( + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + activationKey = OldTargetSmartGroup; + clz = PBXTargetSmartGroup; + description = "Displays all targets of the project."; + globalID = 1C37FABC04509CD000000102; + name = Targets; + preferences = { + image = Targets; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXTargetSmartGroup2; + description = "Displays all targets of the project as well as nested build phases."; + globalID = 1C37FBAC04509CD000000102; + name = Targets; + preferences = { + image = Targets; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXExecutablesSmartGroup; + description = "Displays all executables of the project."; + globalID = 1C37FAAC04509CD000000102; + name = Executables; + preferences = { + image = Executable; + }; + }, + { + " PBXTransientLocationAtTop " = bottom; + absolutePathToBundle = ""; + clz = PBXErrorsWarningsSmartGroup; + description = "Displays files with errors or warnings."; + globalID = 1C08E77C0454961000C914BD; + name = "Errors and Warnings"; + preferences = { + fnmatch = ""; + image = WarningsErrors; + recursive = 1; + regex = ""; + root = ""; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXFilenameSmartGroup; + description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter."; + globalID = 1CC0EA4004350EF90044410B; + name = "Implementation Files"; + preferences = { + canSave = 1; + fnmatch = ""; + image = SmartFolder; + isLeaf = 0; + recursive = 1; + regex = "?*\\.[mcMC]"; + root = ""; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXFilenameSmartGroup; + description = "This group displays Interface Builder NIB Files."; + globalID = 1CC0EA4004350EF90041110B; + name = "NIB Files"; + preferences = { + canSave = 1; + fnmatch = "*.nib"; + image = SmartFolder; + isLeaf = 0; + recursive = 1; + regex = ""; + root = ""; + }; + }, + { + PBXTransientLocationAtTop = no; + absolutePathToBundle = ""; + clz = PBXFindSmartGroup; + description = "Displays Find Results."; + globalID = 1C37FABC05509CD000000102; + name = "Find Results"; + preferences = { + image = spyglass; + }; + }, + { + PBXTransientLocationAtTop = no; + absolutePathToBundle = ""; + clz = PBXBookmarksSmartGroup; + description = "Displays Project Bookmarks."; + globalID = 1C37FABC05539CD112110102; + name = Bookmarks; + preferences = { + image = Bookmarks; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = XCSCMSmartGroup; + description = "Displays files with interesting SCM status."; + globalID = E2644B35053B69B200211256; + name = SCM; + preferences = { + image = PBXRepository; + isLeaf = 0; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXSymbolsSmartGroup; + description = "Displays all symbols for the project."; + globalID = 1C37FABC04509CD000100104; + name = "Project Symbols"; + preferences = { + image = ProjectSymbols; + isLeaf = 1; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXFilenameSmartGroup; + description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter."; + globalID = PBXTemplateMarker; + name = "Simple Filter SmartGroup"; + preferences = { + canSave = 1; + fnmatch = "*.nib"; + image = SmartFolder; + isLeaf = 0; + recursive = 1; + regex = ""; + root = ""; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXFilenameSmartGroup; + description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter."; + globalID = PBXTemplateMarker; + name = "Simple Regular Expression SmartGroup"; + preferences = { + canSave = 1; + fnmatch = ""; + image = SmartFolder; + isLeaf = 0; + recursive = 1; + regex = "?*\\.[mcMC]"; + root = ""; + }; + }, + { + PBXTransientLocationAtTop = bottom; + clz = XDDesignSmartGroup; + description = "Displays Xdesign models"; + globalID = 2E4A936305E6979E00701470; + name = Design; + preferences = { + image = Design; + isLeaf = 0; + }; + }, + ); + PBXWorkspaceContents = ( + { + LeftSlideOut = { + Split0 = { + Split0 = { + NavContent0 = { + bookmark = 3F89A6FF06D5B1F6007C6F9A; + history = ( + F5E2D67E05CDA550017C67C1, + F5E2D67F05CDA550017C67C1, + F5E2D68005CDA550017C67C1, + F5EAB15305FF78D401A80065, + 3F7037A606B335A800A80064, + 3F7037A706B335A800A80064, + 3F89A6F906D5B1F6007C6F9A, + 3F89A6FA06D5B1F6007C6F9A, + 3F89A6FB06D5B1F6007C6F9A, + ); + prevStack = ( + F5F16EF80527D1B401A80064, + F54D1E350548BAC0017C67C1, + F54D1E360548BAC0017C67C1, + F54D1E370548BAC0017C67C1, + F52E6CB905995A8001A80064, + F52E6CBA05995A8001A80064, + F52E6CBB05995A8001A80064, + F52E6CBC05995A8001A80064, + F52E6CBD05995A8001A80064, + F52E6CBE05995A8001A80064, + F508F40305A7AE8A01A80064, + F508F40405A7AE8A01A80064, + F508F40505A7AE8A01A80064, + F52B871705A8A05001A80064, + F52B871905A8A05001A80064, + F52B871B05A8A05001A80064, + F554DF6805AE715801A80064, + F554DF6905AE715801A80064, + F554DF6A05AE715801A80064, + F554DF6B05AE715801A80064, + F51CF6B405AF9E8901A80064, + F51C069F05C4C5B4017C67C1, + F51C06A005C4C5B4017C67C1, + F51C06A105C4C5B4017C67C1, + F557060805C8B0C0017C67C1, + F557060905C8B0C0017C67C1, + F557060A05C8B0C0017C67C1, + F557060B05C8B0C0017C67C1, + F557060C05C8B0C0017C67C1, + F50EB4AF05CB231C017C67C1, + F523D7AD05CB3DB9017C67C1, + F523D7AE05CB3DB9017C67C1, + F586ED0705CC1ED5017C67C1, + F586ED0805CC1ED5017C67C1, + F586ED0905CC1ED5017C67C1, + F586ED0A05CC1ED5017C67C1, + F586ED0B05CC1ED5017C67C1, + F586ED0C05CC1ED5017C67C1, + F586ED0D05CC1ED5017C67C1, + F586ED0E05CC1ED5017C67C1, + F586ED0F05CC1ED5017C67C1, + F586ED1005CC1ED5017C67C1, + F586ED1105CC1ED5017C67C1, + F586ED1205CC1ED5017C67C1, + F586ED1305CC1ED5017C67C1, + F586ED1405CC1ED5017C67C1, + F5CCE1EA05CCCE05017C67C1, + F5CCE1EB05CCCE05017C67C1, + F5E2D68205CDA550017C67C1, + F5E2D68305CDA550017C67C1, + F5E2D68405CDA550017C67C1, + F5E2D68505CDA550017C67C1, + F5E2D68605CDA550017C67C1, + F58F331C05CF5079017C67C1, + F58F331D05CF5079017C67C1, + F58F331E05CF5079017C67C1, + F58F331F05CF5079017C67C1, + F58F332005CF5079017C67C1, + F58F332105CF5079017C67C1, + F58F332205CF5079017C67C1, + F58F332305CF5079017C67C1, + F58F332405CF5079017C67C1, + F58F332505CF5079017C67C1, + F5D9F70F05CF63CD017C67C1, + F5DC7AAE05D47E10017C67C1, + F5DC7AB305D49339017C67C1, + F5DC7AB405D49339017C67C1, + F5DC7AB805D495EE017C67C1, + F588B18805DF3294017C67C1, + F5E67E8505DFEBAB017C67C1, + F5E67E8605DFEBAB017C67C1, + F5516AA205E1AD5A017C67C1, + F5516AA305E1AD5A017C67C1, + F5516AA405E1AD5A017C67C1, + F5516AA505E1AD5A017C67C1, + F5516AA605E1AD5A017C67C1, + F5516AA705E1AD5A017C67C1, + F5516AA805E1AD5A017C67C1, + F5516AA905E1AD5A017C67C1, + F5516AAA05E1AD5A017C67C1, + F5516AAB05E1AD5A017C67C1, + F5516AAC05E1AD5A017C67C1, + F5F2761005EDB91901A80065, + F5F411C805EEF803017C67C1, + F5EAB15505FF78D401A80065, + F5EAB15605FF78D401A80065, + F505F8000617AE8001A80065, + F505F8010617AE8001A80065, + F505F8020617AE8001A80065, + F53C482A061A912901A80065, + F53C482B061A912901A80065, + 3F0A602B062B681C007C67C1, + 3F0A602C062B681C007C67C1, + 3F0A602D062B681C007C67C1, + 3F579AB40645EEDF007C6F93, + 3F579AB50645EEDF007C6F93, + 3FB94844069C744B00A80064, + 3FB94845069C744B00A80064, + 3FB94846069C744B00A80064, + 3FB94847069C744B00A80064, + 3FB94848069C744B00A80064, + 3FB94849069C744B00A80064, + 3F9319E906AF4FA500A80064, + 3F9319EA06AF4FA500A80064, + 3F9319EB06AF4FA500A80064, + 3F0BDAD706AF6C1F00A80064, + 3F7037A806B335A800A80064, + 3F7037A906B335A800A80064, + 3F7037AA06B335A800A80064, + 3F7037AB06B335A800A80064, + 3F2FDB0806B4943500A80064, + 3F5F093C06B4953400A80064, + 3F10FD0806CC4D6D00A80064, + 3F10FD0906CC4D6D00A80064, + 3F10FD0A06CC4D6D00A80064, + 3F10FD0B06CC4D6D00A80064, + 3F10FD0C06CC4D6D00A80064, + 3FC9F73A06CEA744007C6F9A, + 3F89A6FC06D5B1F6007C6F9A, + 3F89A6FD06D5B1F6007C6F9A, + 3F89A6FE06D5B1F6007C6F9A, + ); + }; + NavCount = 1; + NavGeometry0 = { + Frame = "{{0, 0}, {864, 661}}"; + NavBarVisible = YES; + }; + NavSplitVertical = NO; + }; + SplitCount = 1; + Tab1 = { + Debugger = { + Split0 = { + SplitCount = 2; + }; + SplitCount = 1; + TabCount = 2; + }; + LauncherConfigVersion = 7; + }; + Tab2 = { + LauncherConfigVersion = 3; + Runner = { + }; + }; + TabCount = 5; + }; + SplitCount = 1; + Tab1 = { + OptionsSetName = "Hierarchy, all classes"; + }; + TabCount = 5; + }; + }, + { + LeftSlideOut = { + Split0 = { + Split0 = { + NavCount = 1; + NavGeometry0 = { + Frame = "{{0, 0}, {685, 150}}"; + NavBarVisible = YES; + }; + NavSplitVertical = NO; + }; + SplitCount = 1; + Tab1 = { + Debugger = { + Split0 = { + SplitCount = 2; + }; + SplitCount = 1; + TabCount = 2; + }; + LauncherConfigVersion = 7; + }; + Tab2 = { + LauncherConfigVersion = 3; + Runner = { + }; + }; + TabCount = 5; + }; + SplitCount = 1; + Tab1 = { + OptionsSetName = "Hierarchy, all classes"; + }; + TabCount = 5; + }; + }, + { + LeftSlideOut = { + Split0 = { + Split0 = { + NavCount = 1; + NavGeometry0 = { + Frame = "{{0, 0}, {594, 150}}"; + NavBarVisible = YES; + }; + NavSplitVertical = NO; + }; + SplitCount = 1; + Tab1 = { + Debugger = { + Split0 = { + SplitCount = 2; + }; + SplitCount = 1; + TabCount = 2; + }; + LauncherConfigVersion = 7; + }; + Tab2 = { + LauncherConfigVersion = 3; + Runner = { + }; + }; + TabCount = 5; + }; + SplitCount = 1; + Tab1 = { + OptionsSetName = "Hierarchy, all classes"; + }; + TabCount = 5; + }; + }, + ); + PBXWorkspaceGeometries = ( + { + ContentSize = "{1148, 684}"; + LeftSlideOut = { + ActiveTab = 0; + ActiveTabName = PBXGroupTreeModule; + Collapsed = NO; + Frame = "{{0, 23}, {1148, 661}}"; + Split0 = { + Collapsed = NO; + Frame = "{{284, 0}, {864, 661}}"; + Split0 = { + Frame = "{{0, 0}, {864, 661}}"; + }; + SplitCount = 1; + Tab0 = { + Frame = "{{0, 0}, {681, 289}}"; + }; + Tab1 = { + Debugger = { + Collapsed = NO; + Frame = "{{0, 0}, {681, 150}}"; + Split0 = { + Frame = "{{0, 24}, {681, 126}}"; + Split0 = { + Frame = "{{0, 0}, {333, 126}}"; + }; + Split1 = { + DebugVariablesTableConfiguration = ( + Name, + 123, + Value, + 85, + Summary, + 105.123, + ); + Frame = "{{342, 0}, {339, 126}}"; + }; + SplitCount = 2; + }; + SplitCount = 1; + Tab0 = { + Frame = "{{0, 0}, {100, 50}}"; + }; + Tab1 = { + Frame = "{{0, 0}, {100, 50}}"; + }; + TabCount = 2; + TabsVisible = YES; + }; + Frame = "{{0, 0}, {681, 120}}"; + LauncherConfigVersion = 7; + }; + Tab2 = { + Frame = "{{0, 0}, {681, 234}}"; + LauncherConfigVersion = 3; + Runner = { + Frame = "{{0, 0}, {681, 234}}"; + }; + }; + Tab3 = { + BuildMessageFrame = "{{0, 0}, {683, 205}}"; + BuildTranscriptFrame = "{{0, 214}, {683, 2}}"; + BuildTranscriptFrameExpanded = YES; + Frame = "{{0, 0}, {681, 238}}"; + }; + Tab4 = { + Frame = "{{0, 0}, {612, 295}}"; + }; + TabCount = 5; + TabsVisible = NO; + }; + SplitCount = 1; + Tab0 = { + Frame = "{{0, 0}, {260, 661}}"; + GroupTreeTableConfiguration = ( + SCMStatusColumn, + 22, + TargetStatusColumn, + 18, + MainColumn, + 205, + ); + }; + Tab1 = { + ClassesFrame = "{{0, 0}, {250, 333}}"; + ClassesTreeTableConfiguration = ( + PBXBookColumnIdentifier, + 20, + PBXClassColumnIdentifier, + 207, + ); + Frame = "{{0, 0}, {248, 554}}"; + MembersFrame = "{{0, 342}, {250, 212}}"; + MembersTreeTableConfiguration = ( + PBXBookColumnIdentifier, + 20, + PBXMethodColumnIdentifier, + 206, + ); + }; + Tab2 = { + Frame = "{{0, 0}, {217, 554}}"; + }; + Tab3 = { + Frame = "{{0, 0}, {239, 661}}"; + TargetTableConfiguration = ( + ActiveObject, + 16, + ObjectNames, + 206.296, + ); + }; + Tab4 = { + BreakpointsTreeTableConfiguration = ( + breakpointColumn, + 197, + enabledColumn, + 31, + ); + Frame = "{{0, 0}, {250, 661}}"; + }; + TabCount = 5; + TabsVisible = YES; + }; + NavBarShownByDefault = YES; + StatusViewVisible = YES; + Template = 64ABBB4501FA494900185B06; + ToolbarVisible = YES; + WindowLocation = "{3, 0}"; + }, + { + ContentSize = "{685, 434}"; + LeftSlideOut = { + Collapsed = NO; + Frame = "{{0, 23}, {685, 411}}"; + Split0 = { + ActiveTab = 2; + ActiveTabName = PBXBuildResultsModule; + Collapsed = NO; + Frame = "{{0, 0}, {685, 411}}"; + Split0 = { + Frame = "{{0, 301}, {685, 110}}"; + }; + SplitCount = 1; + Tab0 = { + Frame = "{{0, 0}, {952, 321}}"; + }; + Tab1 = { + Debugger = { + Collapsed = NO; + Frame = "{{0, 0}, {781, 452}}"; + Split0 = { + Frame = "{{0, 24}, {781, 428}}"; + Split0 = { + Frame = "{{0, 0}, {383, 428}}"; + }; + Split1 = { + DebugVariablesTableConfiguration = ( + Name, + 123, + Value, + 85, + Summary, + 155.123, + ); + Frame = "{{392, 0}, {389, 428}}"; + }; + SplitCount = 2; + }; + SplitCount = 1; + Tab0 = { + Frame = "{{0, 0}, {100, 50}}"; + }; + Tab1 = { + Frame = "{{0, 0}, {100, 50}}"; + }; + TabCount = 2; + TabsVisible = YES; + }; + Frame = "{{0, 0}, {781, 452}}"; + LauncherConfigVersion = 7; + }; + Tab2 = { + Frame = "{{0, 0}, {685, 215}}"; + LauncherConfigVersion = 3; + Runner = { + Frame = "{{0, 0}, {685, 215}}"; + }; + }; + Tab3 = { + BuildMessageFrame = "{{0, 0}, {687, 262}}"; + BuildTranscriptFrame = "{{0, 271}, {687, 2}}"; + BuildTranscriptFrameExpanded = YES; + Frame = "{{0, 0}, {685, 295}}"; + }; + Tab4 = { + Frame = "{{0, 0}, {612, 295}}"; + }; + TabCount = 5; + TabsVisible = NO; + }; + SplitCount = 1; + Tab0 = { + Frame = "{{0, 0}, {300, 533}}"; + GroupTreeTableConfiguration = ( + TargetStatusColumn, + 18, + MainColumn, + 267, + ); + }; + Tab1 = { + ClassesFrame = "{{0, 0}, {280, 398}}"; + ClassesTreeTableConfiguration = ( + PBXBookColumnIdentifier, + 20, + PBXClassColumnIdentifier, + 237, + ); + Frame = "{{0, 0}, {278, 659}}"; + MembersFrame = "{{0, 407}, {280, 252}}"; + MembersTreeTableConfiguration = ( + PBXBookColumnIdentifier, + 20, + PBXMethodColumnIdentifier, + 236, + ); + }; + Tab2 = { + Frame = "{{0, 0}, {200, 100}}"; + }; + Tab3 = { + Frame = "{{0, 0}, {200, 100}}"; + TargetTableConfiguration = ( + ActiveObject, + 16, + ObjectNames, + 202.296, + ); + }; + Tab4 = { + BreakpointsTreeTableConfiguration = ( + breakpointColumn, + 197, + enabledColumn, + 31, + ); + Frame = "{{0, 0}, {250, 100}}"; + }; + TabCount = 5; + TabsVisible = NO; + }; + NavBarShownByDefault = YES; + StatusViewVisible = YES; + Template = F5314676015831810DCA290F; + ToolbarVisible = YES; + WindowLocation = "{7, 250}"; + }, + { + ContentSize = "{594, 303}"; + LeftSlideOut = { + Collapsed = NO; + Frame = "{{0, 23}, {594, 280}}"; + Split0 = { + ActiveTab = 1; + ActiveTabName = PBXRunSessionModule; + Collapsed = YES; + Frame = "{{0, 0}, {594, 280}}"; + Split0 = { + Frame = "{{1e+06, 1e+06}, {594, 27}}"; + }; + SplitCount = 1; + Tab0 = { + Frame = "{{0, 0}, {804, 321}}"; + }; + Tab1 = { + Debugger = { + Collapsed = NO; + Frame = "{{0, 0}, {594, 274}}"; + Split0 = { + Frame = "{{0, 24}, {594, 250}}"; + Split0 = { + Frame = "{{0, 0}, {290, 250}}"; + }; + Split1 = { + DebugVariablesTableConfiguration = ( + Name, + 123, + Value, + 85, + Summary, + 62.123, + ); + Frame = "{{299, 0}, {295, 250}}"; + }; + SplitCount = 2; + }; + SplitCount = 1; + Tab0 = { + Frame = "{{0, 0}, {100, 50}}"; + }; + Tab1 = { + Frame = "{{0, 0}, {100, 50}}"; + }; + TabCount = 2; + TabsVisible = YES; + }; + Frame = "{{0, 0}, {594, 274}}"; + LauncherConfigVersion = 7; + }; + Tab2 = { + Frame = "{{0, 0}, {594, 274}}"; + LauncherConfigVersion = 3; + Runner = { + Frame = "{{0, 0}, {594, 274}}"; + }; + }; + Tab3 = { + BuildMessageFrame = "{{0, 0}, {614, 262}}"; + BuildTranscriptFrame = "{{0, 271}, {614, 2}}"; + BuildTranscriptFrameExpanded = YES; + Frame = "{{0, 0}, {612, 295}}"; + }; + Tab4 = { + Frame = "{{0, 0}, {612, 295}}"; + }; + TabCount = 5; + TabsVisible = NO; + }; + SplitCount = 1; + Tab0 = { + Frame = "{{0, 0}, {300, 533}}"; + GroupTreeTableConfiguration = ( + TargetStatusColumn, + 18, + MainColumn, + 267, + ); + }; + Tab1 = { + ClassesFrame = "{{0, 0}, {280, 398}}"; + ClassesTreeTableConfiguration = ( + PBXBookColumnIdentifier, + 20, + PBXClassColumnIdentifier, + 237, + ); + Frame = "{{0, 0}, {278, 659}}"; + MembersFrame = "{{0, 407}, {280, 252}}"; + MembersTreeTableConfiguration = ( + PBXBookColumnIdentifier, + 20, + PBXMethodColumnIdentifier, + 236, + ); + }; + Tab2 = { + Frame = "{{0, 0}, {200, 100}}"; + }; + Tab3 = { + Frame = "{{0, 0}, {200, 386}}"; + TargetTableConfiguration = ( + ActiveObject, + 16, + ObjectNames, + 202.296, + ); + }; + Tab4 = { + BreakpointsTreeTableConfiguration = ( + breakpointColumn, + 197, + enabledColumn, + 31, + ); + Frame = "{{0, 0}, {250, 386}}"; + }; + TabCount = 5; + TabsVisible = NO; + }; + NavBarShownByDefault = YES; + StatusViewVisible = YES; + Template = F5534CB2020F3F8A0DCA290F; + ToolbarVisible = YES; + WindowLocation = "{4, 381}"; + }, + ); + PBXWorkspaceStateSaveDate = 116907658; + }; + perUserProjectItems = { + 3F13581706F7DEF5001F6BE7 = 3F13581706F7DEF5001F6BE7; + 3F13583006F7EC6B001F6BE7 = 3F13583006F7EC6B001F6BE7; + 3FB41B8906EFB84A0017502D = 3FB41B8906EFB84A0017502D; + 3FB41B8B06EFB84A0017502D = 3FB41B8B06EFB84A0017502D; + 3FB41B8C06EFB84A0017502D = 3FB41B8C06EFB84A0017502D; + }; + sourceControlManager = 3F8AAF0806E7E5D400E74F19; + userBuildSettings = { + }; + }; + 29B97326FDCFA39411CA2CEA = { + activeExec = 0; + executables = ( + DA206CF0015C4D9F03C91932, + ); + }; + 3F13581706F7DEF5001F6BE7 = { + fRef = DA206CF3015C4E8B03C91932; + isa = PBXTextBookmark; + name = "MacGPSBabel.applescript: 815"; + rLen = 0; + rLoc = 35444; + rType = 0; + vrLen = 1617; + vrLoc = 22605; + }; + 3F13583006F7EC6B001F6BE7 = { + fRef = DA206CF3015C4E8B03C91932; + isa = PBXTextBookmark; + name = "MacGPSBabel.applescript: 839"; + rLen = 0; + rLoc = 35550; + rType = 0; + vrLen = 1415; + vrLoc = 23045; + }; + 3F8AAF0806E7E5D400E74F19 = { + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + isa = PBXSourceControlManager; + scmConfiguration = { + }; + scmType = ""; + }; + 3F8AAF0906E7E5D400E74F19 = { + indexTemplatePath = ""; + isa = PBXCodeSenseManager; + usesDefaults = 1; + wantsCodeCompletion = 1; + wantsCodeCompletionAutoSuggestions = 0; + wantsCodeCompletionCaseSensitivity = 1; + wantsCodeCompletionListAlways = 1; + wantsCodeCompletionOnlyMatchingItems = 1; + wantsCodeCompletionParametersIncluded = 1; + wantsCodeCompletionPlaceholdersInserted = 1; + wantsCodeCompletionTabCompletes = 1; + wantsIndex = 1; + }; + 3FB41B8906EFB84A0017502D = { + fRef = DA206CF4015C4E8B03C91932; + fallbackIsa = PBXBookmark; + isa = ASKDictionaryBookmark; + }; + 3FB41B8B06EFB84A0017502D = { + fRef = DA206CF3015C4E8B03C91932; + isa = PBXTextBookmark; + name = "MacGPSBabel.applescript: 815"; + rLen = 0; + rLoc = 35444; + rType = 0; + vrLen = 1617; + vrLoc = 22605; + }; + 3FB41B8C06EFB84A0017502D = { + fRef = DA206CF4015C4E8B03C91932; + fallbackIsa = PBXBookmark; + isa = ASKDictionaryBookmark; + }; + DA206CF0015C4D9F03C91932 = { + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + configStateDict = { + }; + cppStopOnCatchEnabled = 0; + cppStopOnThrowEnabled = 0; + customDataFormattersEnabled = 1; + debuggerPlugin = ASKDebugger; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + isa = PBXExecutable; + libgmallocEnabled = 0; + name = MacGPSBabel; + shlibInfoDictList = ( + ); + sourceDirectories = ( + ); + }; + DA206CF3015C4E8B03C91932 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1672, 12585}}"; + sepNavSelRange = "{35550, 0}"; + sepNavVisRect = "{{0, 8145}, {862, 533}}"; + }; + }; +} diff --git a/macgpsbabel/MacGPSBabel.pbproj/project.pbxproj b/macgpsbabel/MacGPSBabel.pbproj/project.pbxproj new file mode 100644 index 000000000..2d326e9a5 --- /dev/null +++ b/macgpsbabel/MacGPSBabel.pbproj/project.pbxproj @@ -0,0 +1,480 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 39; + objects = { + 080E96DDFE201D6D7F000001 = { + children = ( + DA206CF3015C4E8B03C91932, + ); + isa = PBXGroup; + name = Scripts; + refType = 4; + sourceTree = ""; + }; + 089C165CFE840E0CC02AAC07 = { + children = ( + 089C165DFE840E0CC02AAC07, + F508F3FF05A7A82F01A80064, + ); + isa = PBXVariantGroup; + name = InfoPlist.strings; + refType = 4; + sourceTree = ""; + }; + 089C165DFE840E0CC02AAC07 = { + fileEncoding = 10; + isa = PBXFileReference; + lastKnownFileType = text.plist.strings; + name = English; + path = English.lproj/InfoPlist.strings; + refType = 4; + sourceTree = ""; + }; + 089C165EFE840E0CC02AAC07 = { + fileRef = 089C165CFE840E0CC02AAC07; + isa = PBXBuildFile; + settings = { + }; + }; +//080 +//081 +//082 +//083 +//084 +//100 +//101 +//102 +//103 +//104 + 1058C7A0FEA54F0111CA2CBB = { + children = ( + 1058C7A1FEA54F0111CA2CBB, + DA206CF1015C4E2903C91932, + ); + isa = PBXGroup; + name = "Linked Frameworks"; + refType = 4; + sourceTree = ""; + }; + 1058C7A1FEA54F0111CA2CBB = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Cocoa.framework; + path = /System/Library/Frameworks/Cocoa.framework; + refType = 0; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB = { + children = ( + 29B97325FDCFA39411CA2CEA, + 29B97324FDCFA39411CA2CEA, + ); + isa = PBXGroup; + name = "Other Frameworks"; + refType = 4; + sourceTree = ""; + }; + 1058C7A3FEA54F0111CA2CBB = { + fileRef = 1058C7A1FEA54F0111CA2CBB; + isa = PBXBuildFile; + settings = { + }; + }; +//100 +//101 +//102 +//103 +//104 +//170 +//171 +//172 +//173 +//174 + 17587328FF379C6511CA2CBB = { + explicitFileType = wrapper.application; + isa = PBXFileReference; + path = MacGPSBabel.app; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; +//170 +//171 +//172 +//173 +//174 +//190 +//191 +//192 +//193 +//194 + 19C28FACFE9D520D11CA2CBB = { + children = ( + 17587328FF379C6511CA2CBB, + ); + isa = PBXGroup; + name = Products; + refType = 4; + sourceTree = ""; + }; +//190 +//191 +//192 +//193 +//194 +//290 +//291 +//292 +//293 +//294 + 29B97313FDCFA39411CA2CEA = { + buildSettings = { + }; + buildStyles = ( + 4A9504CCFFE6A4B311CA0CBA, + 4A9504CDFFE6A4B311CA0CBA, + ); + hasScannedForEncodings = 1; + isa = PBXProject; + mainGroup = 29B97314FDCFA39411CA2CEA; + projectDirPath = ""; + targets = ( + 29B97326FDCFA39411CA2CEA, + ); + }; + 29B97314FDCFA39411CA2CEA = { + children = ( + 080E96DDFE201D6D7F000001, + 29B97317FDCFA39411CA2CEA, + 29B97315FDCFA39411CA2CEA, + 29B97323FDCFA39411CA2CEA, + 19C28FACFE9D520D11CA2CBB, + ); + isa = PBXGroup; + name = Application; + path = ""; + refType = 4; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA = { + children = ( + 29B97316FDCFA39411CA2CEA, + ); + isa = PBXGroup; + name = "Other Sources"; + path = ""; + refType = 4; + sourceTree = ""; + }; + 29B97316FDCFA39411CA2CEA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = main.m; + refType = 4; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA = { + children = ( + 29B97319FDCFA39411CA2CEA, + 089C165CFE840E0CC02AAC07, + DA206CF4015C4E8B03C91932, + F52E6CB4059959B801A80064, + F514A08D05A6164F01A80064, + ); + isa = PBXGroup; + name = Resources; + path = ""; + refType = 4; + sourceTree = ""; + }; + 29B97319FDCFA39411CA2CEA = { + isa = PBXFileReference; + lastKnownFileType = wrapper.nib; + path = English.lproj/MainMenu.nib; + refType = 4; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA = { + children = ( + 1058C7A0FEA54F0111CA2CBB, + 1058C7A2FEA54F0111CA2CBB, + ); + isa = PBXGroup; + name = Frameworks; + path = ""; + refType = 4; + sourceTree = ""; + }; + 29B97324FDCFA39411CA2CEA = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = AppKit.framework; + path = /System/Library/Frameworks/AppKit.framework; + refType = 0; + sourceTree = ""; + }; + 29B97325FDCFA39411CA2CEA = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Foundation.framework; + path = /System/Library/Frameworks/Foundation.framework; + refType = 0; + sourceTree = ""; + }; + 29B97326FDCFA39411CA2CEA = { + buildPhases = ( + 29B97327FDCFA39411CA2CEA, + DA7CAE8F015CFCCA03C91932, + 29B97328FDCFA39411CA2CEA, + 29B9732BFDCFA39411CA2CEA, + 29B9732DFDCFA39411CA2CEA, + ); + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ""; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = /Users/jeremya/Dev/MacGPSBabel; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = MacGPSBabel; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + WRAPPER_EXTENSION = app; + }; + dependencies = ( + ); + isa = PBXApplicationTarget; + name = MacGPSBabel; + productInstallPath = "$(HOME)/Applications"; + productName = Application; + productReference = 17587328FF379C6511CA2CBB; + productSettingsXML = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + MacGPSBabel + CFBundleIconFile + mgb.icns + CFBundleIdentifier + com.gpsbabel.MacGPSBabel + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + mGPS + CFBundleVersion + 1.0.6 + NSAppleScriptEnabled + YES + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + +"; + }; + 29B97327FDCFA39411CA2CEA = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 29B97328FDCFA39411CA2CEA = { + buildActionMask = 2147483647; + files = ( + 3FC2F7BD06EE9EDE002083D3, + 089C165EFE840E0CC02AAC07, + F52E6CB5059959B801A80064, + F514A08E05A6164F01A80064, + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 29B9732BFDCFA39411CA2CEA = { + buildActionMask = 2147483647; + files = ( + 29B9732CFDCFA39411CA2CEA, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 29B9732CFDCFA39411CA2CEA = { + fileRef = 29B97316FDCFA39411CA2CEA; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + ); + }; + }; + 29B9732DFDCFA39411CA2CEA = { + buildActionMask = 2147483647; + files = ( + 1058C7A3FEA54F0111CA2CBB, + DA206CF2015C4E2903C91932, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; +//290 +//291 +//292 +//293 +//294 +//3F0 +//3F1 +//3F2 +//3F3 +//3F4 + 3FC2F7BD06EE9EDE002083D3 = { + fileRef = 29B97319FDCFA39411CA2CEA; + isa = PBXBuildFile; + settings = { + }; + }; +//3F0 +//3F1 +//3F2 +//3F3 +//3F4 +//4A0 +//4A1 +//4A2 +//4A3 +//4A4 + 4A9504CCFFE6A4B311CA0CBA = { + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OPTIMIZATION_CFLAGS = "-O0"; + ZERO_LINK = YES; + }; + isa = PBXBuildStyle; + name = Development; + }; + 4A9504CDFFE6A4B311CA0CBA = { + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + OTHER_OSAFLAGS = "-x"; + ZERO_LINK = NO; + }; + isa = PBXBuildStyle; + name = Deployment; + }; +//4A0 +//4A1 +//4A2 +//4A3 +//4A4 +//DA0 +//DA1 +//DA2 +//DA3 +//DA4 + DA206CF1015C4E2903C91932 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = AppleScriptKit.framework; + path = /System/Library/Frameworks/AppleScriptKit.framework; + refType = 0; + sourceTree = ""; + }; + DA206CF2015C4E2903C91932 = { + fileRef = DA206CF1015C4E2903C91932; + isa = PBXBuildFile; + settings = { + }; + }; + DA206CF3015C4E8B03C91932 = { + explicitFileType = sourcecode.applescript; + fileEncoding = 30; + isa = PBXFileReference; + path = MacGPSBabel.applescript; + refType = 4; + sourceTree = ""; + }; + DA206CF4015C4E8B03C91932 = { + isa = PBXFileReference; + lastKnownFileType = archive.asdictionary; + name = AppleScriptKit.asdictionary; + path = /System/Library/Frameworks/AppleScriptKit.framework/Versions/A/Resources/AppleScriptKit.asdictionary; + refType = 0; + sourceTree = ""; + }; + DA206CF5015C4E8B03C91932 = { + fileRef = DA206CF3015C4E8B03C91932; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Debug, + ); + }; + }; + DA7CAE8F015CFCCA03C91932 = { + buildActionMask = 2147483647; + contextName = ""; + files = ( + DA206CF5015C4E8B03C91932, + ); + isSharedContext = 0; + isa = PBXAppleScriptBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; +//DA0 +//DA1 +//DA2 +//DA3 +//DA4 +//F50 +//F51 +//F52 +//F53 +//F54 + F508F3FF05A7A82F01A80064 = { + isa = PBXFileReference; + lastKnownFileType = text.rtf; + path = Credits.rtf; + refType = 4; + sourceTree = ""; + }; + F514A08D05A6164F01A80064 = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + path = ../gpsbabel; + refType = 4; + sourceTree = ""; + }; + F514A08E05A6164F01A80064 = { + fileRef = F514A08D05A6164F01A80064; + isa = PBXBuildFile; + settings = { + }; + }; + F52E6CB4059959B801A80064 = { + isa = PBXFileReference; + lastKnownFileType = image.icns; + path = mgb.icns; + refType = 4; + sourceTree = ""; + }; + F52E6CB5059959B801A80064 = { + fileRef = F52E6CB4059959B801A80064; + isa = PBXBuildFile; + settings = { + }; + }; + }; + rootObject = 29B97313FDCFA39411CA2CEA; +} diff --git a/macgpsbabel/MacGPSBabel.xcodeproj/project.pbxproj b/macgpsbabel/MacGPSBabel.xcodeproj/project.pbxproj new file mode 100644 index 000000000..0d822aee1 --- /dev/null +++ b/macgpsbabel/MacGPSBabel.xcodeproj/project.pbxproj @@ -0,0 +1,354 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAppleScriptBuildPhase section */ + 6AC682D709C45A8F0081607C /* AppleScript */ = { + isa = PBXAppleScriptBuildPhase; + buildActionMask = 2147483647; + contextName = ""; + files = ( + 6AC682D809C45A8F0081607C /* MacGPSBabel.applescript in AppleScript */, + ); + isSharedContext = 0; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXAppleScriptBuildPhase section */ + +/* Begin PBXBuildFile section */ + 6AC682D809C45A8F0081607C /* MacGPSBabel.applescript in AppleScript */ = {isa = PBXBuildFile; fileRef = DA206CF3015C4E8B03C91932 /* MacGPSBabel.applescript */; settings = {ATTRIBUTES = (Debug, ); }; }; + 6AC682DA09C45A8F0081607C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; + 6AC682DB09C45A8F0081607C /* mgb.icns in Resources */ = {isa = PBXBuildFile; fileRef = F52E6CB4059959B801A80064 /* mgb.icns */; }; + 6AC682DC09C45A8F0081607C /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 6AC682C009C459350081607C /* MainMenu.nib */; }; + 6AC682DD09C45A8F0081607C /* gpsbabel in Resources */ = {isa = PBXBuildFile; fileRef = 6AC682C509C4596E0081607C /* gpsbabel */; }; + 6AC682DE09C45A8F0081607C /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 6AC682CB09C45A660081607C /* Credits.rtf */; }; + 6AC682E009C45A8F0081607C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; + 6AC682E209C45A8F0081607C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + 6AC682E309C45A8F0081607C /* AppleScriptKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA206CF1015C4E2903C91932 /* AppleScriptKit.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 6AC682C109C459350081607C /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; + 6AC682C509C4596E0081607C /* gpsbabel */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = gpsbabel; path = ../gpsbabel; sourceTree = SOURCE_ROOT; }; + 6AC682CB09C45A660081607C /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; }; + 6AC682E909C45A8F0081607C /* MacGPSBabel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MacGPSBabel.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6AC682EB09C45ACD0081607C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; + DA206CF1015C4E2903C91932 /* AppleScriptKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppleScriptKit.framework; path = /System/Library/Frameworks/AppleScriptKit.framework; sourceTree = ""; }; + DA206CF3015C4E8B03C91932 /* MacGPSBabel.applescript */ = {isa = PBXFileReference; explicitFileType = sourcecode.applescript; fileEncoding = 30; path = MacGPSBabel.applescript; sourceTree = ""; }; + DA206CF4015C4E8B03C91932 /* AppleScriptKit.sdef */ = {isa = PBXFileReference; lastKnownFileType = text.sdef; name = AppleScriptKit.sdef; path = /System/Library/Frameworks/AppleScriptKit.framework/Versions/A/Resources/AppleScriptKit.sdef; sourceTree = ""; }; + F52E6CB4059959B801A80064 /* mgb.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = mgb.icns; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6AC682E109C45A8F0081607C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6AC682E209C45A8F0081607C /* Cocoa.framework in Frameworks */, + 6AC682E309C45A8F0081607C /* AppleScriptKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Scripts */ = { + isa = PBXGroup; + children = ( + DA206CF3015C4E8B03C91932 /* MacGPSBabel.applescript */, + ); + name = Scripts; + sourceTree = ""; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, + DA206CF1015C4E2903C91932 /* AppleScriptKit.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97325FDCFA39411CA2CEA /* Foundation.framework */, + 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 6AC682E909C45A8F0081607C /* MacGPSBabel.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* Application */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Scripts */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = Application; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 6AC682EB09C45ACD0081607C /* Info.plist */, + 6AC682CB09C45A660081607C /* Credits.rtf */, + 6AC682C009C459350081607C /* MainMenu.nib */, + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + DA206CF4015C4E8B03C91932 /* AppleScriptKit.sdef */, + F52E6CB4059959B801A80064 /* mgb.icns */, + 6AC682C509C4596E0081607C /* gpsbabel */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 6AC682D609C45A8F0081607C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 6AC682D509C45A8F0081607C /* MacGPSBabel */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6AC682E409C45A8F0081607C /* Build configuration list for PBXNativeTarget "MacGPSBabel" */; + buildPhases = ( + 6AC682D609C45A8F0081607C /* Headers */, + 6AC682D709C45A8F0081607C /* AppleScript */, + 6AC682D909C45A8F0081607C /* Resources */, + 6AC682DF09C45A8F0081607C /* Sources */, + 6AC682E109C45A8F0081607C /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MacGPSBabel; + productInstallPath = "$(HOME)/Applications"; + productName = Application; + productReference = 6AC682E909C45A8F0081607C /* MacGPSBabel.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 6AC6829D09C44F090081607C /* Build configuration list for PBXProject "MacGPSBabel" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* Application */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6AC682D509C45A8F0081607C /* MacGPSBabel */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 6AC682D909C45A8F0081607C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6AC682DA09C45A8F0081607C /* InfoPlist.strings in Resources */, + 6AC682DB09C45A8F0081607C /* mgb.icns in Resources */, + 6AC682DC09C45A8F0081607C /* MainMenu.nib in Resources */, + 6AC682DD09C45A8F0081607C /* gpsbabel in Resources */, + 6AC682DE09C45A8F0081607C /* Credits.rtf in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 6AC682DF09C45A8F0081607C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6AC682E009C45A8F0081607C /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C165DFE840E0CC02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 6AC682C009C459350081607C /* MainMenu.nib */ = { + isa = PBXVariantGroup; + children = ( + 6AC682C109C459350081607C /* English */, + ); + name = MainMenu.nib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 6AC6829E09C44F090081607C /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Development; + }; + 6AC6829F09C44F090081607C /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Deployment; + }; + 6AC682A009C44F090081607C /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Default; + }; + 6AC682E509C45A8F0081607C /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = "$(SRCROOT)"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = MacGPSBabel; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Development; + }; + 6AC682E609C45A8F0081607C /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = "$(SRCROOT)"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_OSAFLAGS = "-x"; + PRODUCT_NAME = MacGPSBabel; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Deployment; + }; + 6AC682E709C45A8F0081607C /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = "$(SRCROOT)"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = MacGPSBabel; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + }; + name = Default; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 6AC6829D09C44F090081607C /* Build configuration list for PBXProject "MacGPSBabel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6AC6829E09C44F090081607C /* Development */, + 6AC6829F09C44F090081607C /* Deployment */, + 6AC682A009C44F090081607C /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 6AC682E409C45A8F0081607C /* Build configuration list for PBXNativeTarget "MacGPSBabel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6AC682E509C45A8F0081607C /* Development */, + 6AC682E609C45A8F0081607C /* Deployment */, + 6AC682E709C45A8F0081607C /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/macgpsbabel/README.macgpsbabel b/macgpsbabel/README.macgpsbabel new file mode 100644 index 000000000..e4d7ee848 --- /dev/null +++ b/macgpsbabel/README.macgpsbabel @@ -0,0 +1,8 @@ +MacGPSBabel is a Mac OS X GUI front-end for gpsbabel. The GUI was developed using Apple's 'Interface Builder' application and the code to link the GUI to gpsbabel is written in Applescript. + +Build instructions. + +MacGPSBabel can be built with Apple's developer tools in the same way that you would build any other application. As it is, the Project Builder will assume that you have added a build of gpsbabel into the same folder as the rest of the MacGPSBabel project files. This binary will then be embedded in the build of MacGPSBabel. If you do not do this then MacGPSBabel will not work, however, it is possible to place the gpsbabel binary into the Resources Folder in the MacGPSBabel package after building it. + +Debug (verbose) Mode +This can be activated by pressing command-option-v whilst the main MacGPSBabel window is the active window. When debug mode is active, using MacGPSBabel in the usual manner will result in a report for each file conversion being displayed in the debug window. Alternatively, commands can be typed directly in the debug window and run using the 'execute' button (the full path to any file needs to be specified). \ No newline at end of file diff --git a/macgpsbabel/main.m b/macgpsbabel/main.m new file mode 100644 index 000000000..6c4fdb11e --- /dev/null +++ b/macgpsbabel/main.m @@ -0,0 +1,9 @@ +extern void ASKInitialize(); +extern int NSApplicationMain(int argc, const char *argv[]); + +int main(int argc, const char *argv[]) +{ + ASKInitialize(); + + return NSApplicationMain(argc, argv); +} diff --git a/macgpsbabel/mgb.icns b/macgpsbabel/mgb.icns new file mode 100644 index 0000000000000000000000000000000000000000..01c5972d6b755952b4cee91f7a0689a396563b31 GIT binary patch literal 33545 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 Qg#FVB{Iml9@2tT80qY$aCIA2c literal 0 HcmV?d00001 diff --git a/macgpsbabel/preferences.applescript b/macgpsbabel/preferences.applescript new file mode 100644 index 000000000..2f7e62d58 --- /dev/null +++ b/macgpsbabel/preferences.applescript @@ -0,0 +1,185 @@ +-- MacGPSBabel: preferences.applescript +-- File Created by Jeremy Atherton on January 30, 2004 +-- Last modified by Jeremy Atherton on Monday, February 16, 2004 + +-- MacGPSBabel is part of the gpsbabel project and is Copyright (c) 2004 Robert Lipe. +-- see http://gpsbabel.sourceforge.net/ for more details + +-- This script (preferences.applescript) deals mostly with reading and saving user defaults. Along the way, it also deals with getting the list of available serial ports. + +-- PROPERTIES -- +property startIndex : 0 +property startState : false + +-- EVENT HANDLERS -- + +on will finish launching theObject + -- make empty entries in user defaults + make new default entry at end of default entries of user defaults with properties {name:"theInputType", contents:startIndex} + make new default entry at end of default entries of user defaults with properties {name:"theOutputType", contents:startIndex} + make new default entry at end of default entries of user defaults with properties {name:"gpsIN", contents:startState} + make new default entry at end of default entries of user defaults with properties {name:"gpsOUT", contents:startState} + make new default entry at end of default entries of user defaults with properties {name:"gpsReceiver", contents:startIndex} +end will finish launching + +on awake from nib theObject + if theObject is window "MacGPSBabel" then + tell window "MacGPSBabel" + set popList to my getFormats() + repeat with i in popList + make new menu item at the end of menu items of menu of popup button "inPop" with properties {title:i, enabled:true} + make new menu item at the end of menu items of menu of popup button "outPop" with properties {title:i, enabled:true} + end repeat + end tell + + -- read current user defaults + my readSettings() + + -- deal with changes to MacGPSBabel window needed if any of the GPS check boxes are checked by default + if state of button "GPSswitchIN" of window "MacGPSBabel" is equal to 1 then + my gpsIN() + end if + if state of button "GPSswitchOUT" of window "MacGPSBabel" is equal to 1 then + my gpsOUT() + end if + end if +end awake from nib + +on will open theObject + -- set the progress indicator style + if theObject is window "MacGPSBabel" then + set p to progress indicator 1 of theObject + call method "setStyle:" of p with parameter 1 + call method "setDisplayedWhenStopped:" of p with parameters {false} + end if + if theObject is window "SelectGPS" then + -- get the list of available serial ports + set popList to my getSerial() + -- use popList to populate the drop-down menu + delete every menu item of menu of popup button "serialPop" of window "SelectGPS" + repeat with i in popList + make new menu item at the end of menu items of menu of popup button "serialPop" of window "SelectGPS" with properties {title:i, enabled:true} + end repeat + + -- read user defaults for this window + tell user defaults + set defaultgpsReceiver to contents of default entry "gpsReceiver" + end tell + set state of popup button "gpsPop" of window "SelectGPS" to defaultgpsReceiver + + -- hide MacGPSBabel window + set visible of window "MacGPSBabel" to false + end if +end will open + +on will close theObject + if theObject is window "SelectGPS" then + -- store user defaults for this window + set newReceiverIndex to contents of popup button "gpsPop" of window "SelectGPS" + tell user defaults + set contents of default entry "gpsReceiver" to newReceiverIndex + end tell + + -- unhide MacGPSBabel window + set visible of window "MacGPSBabel" to true + end if +end will close + +-- store user defaults for MacGPSBabel window +on clicked theObject + if theObject is button "defaultsButton" of window "MacGPSBabel" then + set newInputIndex to contents of popup button "inPop" of window "MacGPSBabel" + set newOutputIndex to contents of popup button "outPop" of window "MacGPSBabel" + set newINstate to state of button "GPSswitchIN" of window "MacGPSBabel" as boolean + set newOUTstate to state of button "GPSswitchOUT" of window "MacGPSBabel" as boolean + tell user defaults + set contents of default entry "theInputType" to newInputIndex + set contents of default entry "theOutputType" to newOutputIndex + set contents of default entry "gpsIN" to newINstate + set contents of default entry "gpsOUT" to newOUTstate + end tell + end if +end clicked + +-- HANDLERS -- + +-- read user defaults +on readSettings() + tell user defaults + set defaultInputIndex to contents of default entry "theInputType" as integer + set defaultOutputIndex to contents of default entry "theOutputType" as integer + set defaultgpsIN to contents of default entry "gpsIN" as boolean + set defaultgpsOUT to contents of default entry "gpsOUT" as boolean + end tell + -- call method "setObjectValue:" of object (popup button "inPop" of window "MacGPSBabel") with parameter defaultInputIndex + -- call method "synchronizeTitleAndSelectedItem" of object (popup button "inPop" of window "MacGPSBabel") + set contents of popup button "inPop" of window "MacGPSBabel" to defaultInputIndex + set contents of popup button "outPop" of window "MacGPSBabel" to defaultOutputIndex + set state of button "GPSswitchIN" of window "MacGPSBabel" to defaultgpsIN + set state of button "GPSswitchOUT" of window "MacGPSBabel" to defaultgpsOUT +end readSettings + +-- scripts for dealing with GPS checkboxes on MacGPSBabel window +on gpsIN() + if state of button "GPSswitchIN" of window "MacGPSBabel" = 1 then + set enabled of button "selectButton" of window "MacGPSBabel" to false + set enabled of button "clearButton" of window "MacGPSBabel" to false + set enabled of button "sendButton" of window "MacGPSBabel" to true + set contents of text field "inputFile" of window "MacGPSBabel" to "" + set enabled of text field "inputFile" of window "MacGPSBabel" to false + set enabled of popup button "inPop" of window "MacGPSBabel" to false + else + set enabled of button "selectButton" of window "MacGPSBabel" to true + set enabled of button "sendButton" of window "MacGPSBabel" to false + set enabled of text field "inputFile" of window "MacGPSBabel" to true + set enabled of popup button "inPop" of window "MacGPSBabel" to true + end if +end gpsIN +on gpsOUT() + if state of button "GPSswitchOUT" of window "MacGPSBabel" = 1 then + set enabled of popup button "outPop" of window "MacGPSBabel" to false + else + set enabled of popup button "outPop" of window "MacGPSBabel" to true + end if +end gpsOUT + +-- find the serial ports +on getSerial() + set myList to {} + set theScript to "cd /dev; ls | grep cu\\." + set scriptOut to (do shell script theScript) as string + set theCount to count of paragraphs in scriptOut + set i to 0 + set defaultDelimiters to AppleScript's text item delimiters + set AppleScript's text item delimiters to {"."} + repeat until i = theCount + set i to i + 1 + set theWords to the count of text items in paragraph i of scriptOut + set z to 2 + set the end of myList to (text items z thru theWords of paragraph i of scriptOut) as string + end repeat + set AppleScript's text item delimiters to defaultDelimiters + return myList +end getSerial + +-- handler (called at startup) to check with GPS Babel which file formats it can handle. Return the result as a list +on getFormats() + set myList to {} + set typeList to {} + set extList to {} + set thePath to POSIX path of (path to me) as string + set scriptOut to (do shell script quoted form of thePath & "Contents/Resources/gpsbabel -^1") as string + set theCount to count of paragraphs in scriptOut + set defaultDelimiters to AppleScript's text item delimiters + set AppleScript's text item delimiters to tab + repeat with i from 1 to theCount + set theLine to paragraph i of scriptOut + if (first text item of theLine) is equal to "file" then + set the end of typeList to the second text item of theLine + set the end of extList to the third text item of theLine + set the end of myList to the last text item of theLine + end if + end repeat + set AppleScript's text item delimiters to defaultDelimiters + return myList +end getFormats \ No newline at end of file diff --git a/mag_pdb.c b/mag_pdb.c new file mode 100644 index 000000000..c9ebcca29 --- /dev/null +++ b/mag_pdb.c @@ -0,0 +1,233 @@ +/* + + Support of Palm/OS files from Map&Guide based products like + "PowerRoute" 5+6, "Motorrad Routenplaner" + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#include +#include + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "pdbfile.h" +#include "jeeps/gpsmath.h" + +#define MYNAME "mag_pdb" + +#define PROUTE_MAGIC 0x766d6170 /* vmap */ +#define PROUTE_ROUTE 0x49444154 /* IDAT */ + +static pdbfile *file_in; + +static arglist_t magpdb_args[] = +{ + ARG_TERMINATOR +}; + +static double +magpdb_to_degree(const int degx) +{ + int m, d, x; + double s, res; + + d = degx / 100000; + x = degx % 100000; + m = x / 1000; + x = x % 1000; + s = (double)(x) / 10; + + GPS_Math_DegMinSec_To_Deg(d, m, s, &res); + + return res; +} + +static void +magpdb_read_data(const char *data, const size_t data_len) +{ + route_head *route; + char *cin = (char *)data; + char *cend = cin + data_len; + + route = route_head_alloc(); + route_add_head(route); + + while (cin < cend) + { + char *lend; + int len; + + lend = strchr(cin, '\x0A'); + if (lend == NULL) break; + + len = (lend - cin); + if (len > 0) + { + double distance; + int hour, min; + *lend = '\0'; + + if (case_ignore_strncmp(cin, "Wegname=", 8) == 0) /* This only works with the german release */ + { /* test-data created with other releases are welcome */ + cin += 8; + if (*cin != '\0') + route->rte_name = xstrdup(cin); + } + else if (case_ignore_strncmp(cin, "Fahrzeit=", 9) == 0) + { + } + else if (case_ignore_strncmp(cin, "Kosten=", 7) == 0) + { + } + else if (case_ignore_strncmp(cin, "Entfernung=", 11) == 0) + { + } + /* check, if line starts with time and distance */ + else if (3 == sscanf(cin, "%d:%d %lf", &hour, &min, &distance)) + { + char *buff, *comma; + + /* detect time-format settings, 12,0 or 12.0 */ + + comma = strchr(cin, '.'); + buff = strchr(cin, ','); + if (comma == NULL) + comma = buff; + else + if ((buff != NULL) && (buff < comma)) + comma = buff; + if (comma != NULL) + { + char separator = *comma; + + /* now we are looking for a sequence like 0,1 NE (123456,654321) */ + + buff = xmalloc(strlen(cin) + 1); /* safe target space for sscanf( ... */ + + comma = cin; + while ((comma = strchr(comma, separator))) + { + int i, xlat, xlon; + waypoint *wpt; + char *cx; + + comma++; + + if (isdigit(*comma) == 0) continue; + if (isdigit(*(comma - 2)) == 0) continue; + + if (4 != sscanf(comma, "%d %s (%d,%d)", &i, buff, &xlon, &xlat)) continue; + if (strchr("NESW", *buff) == NULL) continue; /* north, east, ... */ + + cx = comma - 2; /* go left over delta distance */ + while (isdigit(*cx) != 0) *cx-- = '\0'; + cin = lrtrim(cin); + + for (i = 0; i < 2; i++) /* skip time and distance at start of line */ + { + cin = strchr(cin, ' '); + cin = lrtrim(cin); + } + + wpt = waypt_new(); + + wpt->latitude = magpdb_to_degree(xlat); + wpt->longitude = magpdb_to_degree(xlon); + wpt->description = xstrdup(cin); + + cx = strchr(comma, ')'); /* find tailing notes after the coordinates */ + if (cx != NULL) + { + char *tail = lrtrim(++cx); + if (*tail != '\0') + { + wpt->notes = xstrdup(tail); + } + } + /* generate some waypoints from our route-only format */ + if ((*cin != '-') && (case_ignore_strncmp(cin, "bei ", 4) != 0)) + waypt_add(waypt_dupe(wpt)); + + route_add_wpt(route, wpt); + break; + } + xfree(buff); + } + } + + } + cin = lend + 1; + } +} + +/* ============================================================================================ + * &&& gobal callbacks &&& + * ----------------------------------------------------------------------------------------- */ + +static void magpdb_rd_init(const char *fname) +{ + file_in = pdb_open(fname, MYNAME); +} + +static void magpdb_rd_deinit(void) +{ + pdb_close(file_in); +} + +static void magpdb_read(void) +{ + pdbrec_t *pdb_rec; + + is_fatal((file_in->creator != PROUTE_MAGIC), /* identify the database */ + MYNAME ": Not a Map&Guide pdb file (0x%08x).", file_in->creator); + + is_fatal((file_in->version != 0), /* only version "0" currently seen and tested */ + MYNAME ": This file is from an unsupported version (%d) of Map&Guide and is unsupported.", file_in->version + 5); + + is_fatal((file_in->type != PROUTE_ROUTE), + MYNAME ": Unknown pdb data type (0x%08x).", file_in->type); + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) + { + char *data = (char *)pdb_rec->data; + + if (be_read16(data) == 0) + { + int len = be_read16(data + 2); + magpdb_read_data(data + 4, len); + } + } +} + +/* ======================================================================================= */ + +ff_vecs_t magpdb_vecs = { + ff_type_file, + { ff_cap_read, ff_cap_none, ff_cap_read }, /* real route + emulated waypoints */ + magpdb_rd_init, + NULL, + magpdb_rd_deinit, + NULL, + magpdb_read, + NULL, + NULL, + magpdb_args, + CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ +}; +#endif diff --git a/magellan.h b/magellan.h new file mode 100644 index 000000000..062742634 --- /dev/null +++ b/magellan.h @@ -0,0 +1,54 @@ +/* + Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +/* + * Table of "interesting" Magellan models. + * Selfishly, if I haven't heard of it, it's not in the table. + * This doesn't mean I actually have TRIED all models listed below. + * (Donations welcome. :-) + */ +typedef enum { + mm_unknown = 0 , + mm_gps315320, + mm_map410, + mm_map330, + mm_gps310, + mm_meridian, + mm_sportrak +} meridian_model; + +typedef struct pid_to_model { + meridian_model model; + int pid; + const char *model_n; +} pid_to_model_t; + +typedef struct icon_mapping { + const char *token; + const char *icon; +} icon_mapping_t; + +const char * mag_find_descr_from_token(const char *token); +const char * mag_find_token_from_descr(const char *icon); + +unsigned int mag_checksum(const char *const buf); +char * m330_cleanse(char *istring); + +waypoint * mag_trkparse(char *trkmsg); +void mag_rteparse(char *rtemsg); diff --git a/maggeo.c b/maggeo.c new file mode 100644 index 000000000..57e4fb5df --- /dev/null +++ b/maggeo.c @@ -0,0 +1,247 @@ +/* + Magellan ".gs" files as they appear on USB of Explorist 400,500,600. + + Copyright (C) 2005, 2006 robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include "defs.h" +#include "xmlgeneric.h" +#include "magellan.h" + +#define MYNAME "maggeo" + +/* Turn this on (remove) after 5.2 becomes widespread. */ +#define FIRMWARE_DOES_88591 0 + +static gbfile *maggeofile_in; +static gbfile *maggeofile_out; +static short_handle desc_handle = NULL; + +static void +maggeo_writemsg(const char * const buf) +{ + unsigned int osum = mag_checksum(buf); + gbfprintf(maggeofile_out, "$%s*%02X\r\n",buf, osum); +} + +static void +maggeo_rd_init(const char *fname) +{ + maggeofile_in = gbfopen(fname, "rb", MYNAME); +} + +static void +maggeo_rd_deinit(void) +{ + gbfclose(maggeofile_in); +} + +static void +maggeo_wr_init(const char *fname) +{ + if (waypt_count() > 200) { + fatal(MYNAME ": eXplorist does not support more than 200 waypoints in one .gs file.\nDecrease the number of waypoints sent.\n"); + } + maggeofile_out = gbfopen(fname, "wb", MYNAME); + desc_handle = mkshort_new_handle(); + setshort_length(desc_handle, 20); + setshort_badchars(desc_handle, "\"$,"); +} + +static void +maggeo_wr_deinit(void) +{ + maggeo_writemsg("PMGNCMD,END"); + mkshort_del_handle(&desc_handle); + gbfclose(maggeofile_out); +} + +static void +maggeo_read(void) +{ + fatal(MYNAME ": Reading maggeo is not implemented yet.\n"); +} + +/* + * Note: returns allocated buffer that must be freed by caller. + */ +static +char * +maggeo_fmtdate(time_t t) +{ + #define SZ 16 + + char *cbuf = xmalloc(SZ); + struct tm *tm = NULL; + int date; + tm = gmtime(&t); + + if ( t && tm ) { + date = tm->tm_mday * 100000 + (1+tm->tm_mon) * 1000 + + tm->tm_year; + snprintf(cbuf, SZ, "%07d", date); + } else { + cbuf[0] = '\0'; + } + return cbuf; +} + +/* + * Append an optional UTF string to buf, prepending a comma, + * cleansing it of NMEA-isms and decomposing to ASCII as we go. + */ +static +void +append(char *buf, const char *str) +{ + char *cleansed1, *cleansed2; + + strcat(buf, ","); + + if (!str) { + return; + } + + cleansed1 = xstrdup(str); +#if FIRMWARE_DOES_88591 +/* Actually, this function needs needs refactored... */ + cleansed2 = xstrdup(cleansed1); +#else + cleansed2 = m330_cleanse(cleansed1); +#endif + + strcat(buf, cleansed2); + + xfree(cleansed1); + xfree(cleansed2); + +} + +static void +maggeo_waypt_pr(const waypoint *waypointp) +{ + char obuf[4096]; + double ilon, ilat; + double lon, lat; + int lon_deg, lat_deg; + char *shortname; + char *cname = NULL; + const char *ctype = NULL; + char *placer = NULL; + char *lfounddate = NULL; + char *placeddate = NULL; + + ilat = waypointp->latitude; + ilon = waypointp->longitude; + shortname = waypointp->shortname; + + lon = fabs(ilon); + lat = fabs(ilat); + + lon_deg = lon; + lat_deg = lat; + + lon = (lon - lon_deg) * 60.0; + lat = (lat - lat_deg) * 60.0; + + lon = (lon_deg * 100.0 + lon); + lat = (lat_deg * 100.0 + lat); + + /* + * For some reason, Magellan used exactly the GPX spellings of + * everything except this one... + */ + if (waypointp->gc_data.type == gt_suprise) { + ctype = "Mystery Cache"; + } else { + ctype = gs_get_cachetype(waypointp->gc_data.type); + } + placeddate = maggeo_fmtdate(waypointp->creation_time); + lfounddate = maggeo_fmtdate(waypointp->gc_data.last_found); + cname = mkshort(desc_handle, waypointp->notes ? waypointp->notes : waypointp->description); + placer = waypointp->gc_data.placer; + + /* + * As of this writing on 05/04, the firmware in the units will + * let you write fields of just about any width, but appears to + * only use the following: + * shortname - 8 chars + * cname - 20 chars (scrolls in some places, not others) + * placer - display limited by width + * hint - 50 chars + * cache type - appears to be parsed by f/w for icon matching. + * + * + */ + snprintf(obuf, sizeof(obuf), + "PMGNGEO,%4.3f,%c,%08.3f,%c,%04.0f,F", + lat, ilat < 0 ? 'S' : 'N', + lon, ilon < 0 ? 'W' : 'E', + waypointp->altitude == unknown_alt ? + 0 : waypointp->altitude); + append(obuf, shortname); + append(obuf, cname); + append(obuf, placer); + append(obuf, waypointp->gc_data.hint); + append(obuf, ctype); + append(obuf, placeddate); + append(obuf, lfounddate); + + if (waypointp->gc_data.diff/10.0) + sprintf(obuf + strlen(obuf), ",%3.1f", + waypointp->gc_data.diff/10.0); + else + strcat(obuf, ","); + + if (waypointp->gc_data.terr/10.0) + sprintf(obuf + strlen(obuf), ",%3.1f", + waypointp->gc_data.terr/10.0); + else + strcat(obuf, ","); + + if (lfounddate) xfree(lfounddate); + if (placeddate) xfree(placeddate); + if (cname) xfree(cname); + + maggeo_writemsg(obuf); +} + +static void +maggeo_write(void) +{ + waypt_disp_all(maggeo_waypt_pr); +} + +ff_vecs_t maggeo_vecs = { + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none }, + maggeo_rd_init, + maggeo_wr_init, + maggeo_rd_deinit, + maggeo_wr_deinit, + maggeo_read, + maggeo_write, + NULL, + NULL, +#if FIRMWARE_DOES_88591 + CET_CHARSET_LATIN1, 0 /* CET-REVIEW */ +#else + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +#endif +}; diff --git a/magnav.c b/magnav.c new file mode 100644 index 000000000..d1e91d3c9 --- /dev/null +++ b/magnav.c @@ -0,0 +1,253 @@ +/* + Read and write Magellan Navigator Companion files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "pdbfile.h" + +#define MYNAME "Companion Waypoints" +#define MYTYPE 0x54777074 /* Twpt */ +#define MYCREATOR 0x4d47747a /* MGtz */ + +struct record { + pdb_16 crt_sec; /* Big endian, creation time */ + pdb_16 crt_min; + pdb_16 crt_hour; + pdb_16 crt_mday; + pdb_16 crt_mon; /* 1 = Jan */ + pdb_16 crt_year; /* includes century. */ + pdb_16 unknown; + pdb_16 xx_sec; /* appears to be time, but we don't know what it is. */ + pdb_16 xx_min; + pdb_16 xx_hour; + pdb_16 xx_mday; + pdb_16 xx_mon; + pdb_16 xx_year; + pdb_16 unknown2; + pdb_32 latitude; /* lat * 1e5 */ + pdb_32 longitude; /* lon * 1e5 */ + pdb_32 elevation; /* meters */ + char plot; /* 1 = plot on map screen. default = 0 */ + char unknown3; /* always 'a' */ +}; + +static pdbfile *file_in; +static pdbfile *file_out; +static short_handle mkshort_handle; +static int ct; + +static void +rd_init(const char *fname) +{ + file_in = pdb_open(fname, MYNAME); +} + +static void +rd_deinit(void) +{ + pdb_close(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = pdb_create(fname, MYNAME); + mkshort_handle = mkshort_new_handle(); + setshort_length(mkshort_handle, 20); + ct = 0; +} + +static void +wr_deinit(void) +{ + pdb_close(file_out); + mkshort_del_handle(&mkshort_handle); +} + +static void +data_read(void) +{ + struct record *rec; + pdbrec_t *pdb_rec; + + if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { + fatal(MYNAME ": Not a Magellan Navigator file.\n"); + } + + for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint *wpt_tmp; + char *vdata; + struct tm tm; + + memset (&tm, 0, sizeof(tm)); + wpt_tmp = waypt_new(); + rec = (struct record *) pdb_rec->data; + wpt_tmp->altitude = be_read32(&rec->elevation); + + wpt_tmp->longitude = be_read32(&rec->longitude) / 1e5; + wpt_tmp->latitude = be_read32(&rec->latitude) / 1e5; + + vdata = (char *) pdb_rec->data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata += strlen (vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata += strlen (vdata) + 1; + + tm.tm_sec = be_read16(&rec->crt_sec); + tm.tm_min = be_read16(&rec->crt_min); + tm.tm_hour = be_read16(&rec->crt_hour); + tm.tm_mday = be_read16(&rec->crt_mday); + tm.tm_mon = be_read16(&rec->crt_mon) - 1; + tm.tm_year = be_read16(&rec->crt_year) - 1900; + wpt_tmp->creation_time = mktime(&tm); + + waypt_add(wpt_tmp); + + } +} + + +static void +my_writewpt(const waypoint *wpt) +{ + struct record *rec; + struct tm *tm; + char *vdata; + time_t tm_t; + const char *sn = global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, wpt) : + wpt->shortname; + + rec = xcalloc(sizeof(*rec)+56,1); + + tm = NULL; + if ( wpt->creation_time ) { + tm = gmtime( &wpt->creation_time); + } + if ( !tm ) { + tm_t = current_time(); + tm = gmtime( &tm_t ); + } + + be_write16( &rec->crt_sec, tm->tm_sec ); + be_write16( &rec->crt_min, tm->tm_min ); + be_write16( &rec->crt_hour, tm->tm_hour ); + be_write16( &rec->crt_mday, tm->tm_mday ); + be_write16( &rec->crt_mon, tm->tm_mon + 1 ); + be_write16( &rec->crt_year, tm->tm_year + 1900 ); + + be_write16( &rec->unknown, 0); + + be_write16( &rec->xx_sec, tm->tm_sec ); + be_write16( &rec->xx_min, tm->tm_min ); + be_write16( &rec->xx_hour, tm->tm_hour ); + be_write16( &rec->xx_mday, tm->tm_mday ); + be_write16( &rec->xx_mon, tm->tm_mon + 1 ); + be_write16( &rec->xx_year, tm->tm_year + 1900 ); + + be_write16( &rec->unknown2, 0); + + be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0)); + be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0)); + be_write32(&rec->elevation, (unsigned int) (wpt->altitude)); + + rec->plot = 0; + rec->unknown3 = 'a'; + + vdata = (char *)rec + sizeof(*rec); + if ( sn ) { + strncpy( vdata, sn, 21 ); + vdata[20] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + if ( wpt->description ) { + strncpy( vdata, wpt->description, 33 ); + vdata[32] = '\0'; + } + else { + vdata[0] = '\0'; + } + vdata += strlen( vdata ) + 1; + vdata[0] = '\0'; + vdata[1] = '\0'; + vdata += 2; + + pdb_write_rec(file_out, 0, 0, ct++, rec, (char *)vdata - (char *)rec); + + xfree(rec); +} + +static void +data_write(void) +{ + static char *appinfo = + "\0\x01" + "User\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\0\0"; + + strncpy(file_out->name, "Companion Waypoints", PDB_DBNAMELEN); + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + file_out->appinfo = (void *)appinfo; + file_out->appinfo_len = 276; + + waypt_disp_all(my_writewpt); +} + + +ff_vecs_t magnav_vec = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; +#endif diff --git a/magproto.c b/magproto.c new file mode 100644 index 000000000..ae4187b0d --- /dev/null +++ b/magproto.c @@ -0,0 +1,1555 @@ +/* + Communicate Thales/Magellan serial protocol. + + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include + +#include "defs.h" +#include "magellan.h" +#include "gbser.h" + +static int bitrate = 4800; +static int wptcmtcnt; +static int wptcmtcnt_max; +static int explorist; +static int broken_sportrak; +#define MYNAME "MAGPROTO" +#define MAXCMTCT 200 + +#define debug_serial (global_opts.debug_level > 1) + +static char *termread(char *ibuf, int size); +static void termwrite(char *obuf, int size); +static void mag_readmsg(gpsdata_type objective); +static void mag_handon(void); +static void mag_handoff(void); +static short_handle mkshort_handle = NULL; +static char *deficon = NULL; +static char *bs = NULL; +static char *cmts = NULL; +static char *noack = NULL; +static char *nukewpt = NULL; +static int route_out_count; +static int waypoint_read_count; +static int wpt_len = 8; +static const char *curfname; +static int extension_hint; + +/* + * Magellan's firmware is *horribly* slow to send the next packet after + * we turn around an ack while we are reading from the device. It's + * quite spiffy when we're writing to the device. Since we're *way* + * less likely to lose data while reading from it than it is to lose data + * when we write to it, we turn off the acks when we are predominatly + * reading. + */ +static int suppress_ack; + +typedef enum { + mrs_handoff = 0, + mrs_handon, + mrs_awaiting_ack +} mag_rxstate; + +/* + * An individual element of a route. + */ +typedef struct mag_rte_elem { + queue Q; /* My link pointers */ + char *wpt_name; + char *wpt_icon; +} mag_rte_elem; + +/* + * A header of a route. Related elements of a route belong to this. + */ +typedef struct mag_rte_head { + queue Q; /* Queue head for child rte_elems */ + char *rte_name; + int nelems; +} mag_rte_head; + +static queue rte_wpt_tmp; /* temporary PGMNWPL msgs for routes */ + +static gbfile *magfile_h; +static mag_rxstate magrxstate; +static int mag_error; +static unsigned int last_rx_csum; +static int found_done; +static int got_version; +static int is_file = 0; +static route_head *trk_head; +static int ignore_unable; + +static waypoint * mag_wptparse(char *); +typedef char * (cleanse_fn) (char *); +static cleanse_fn *mag_cleanse; + +static icon_mapping_t gps315_icon_table[] = { + { "a", "filled circle" }, + { "b", "box" }, + { "c", "red buoy" }, + { "d", "green buoy" }, + { "e", "buoy" }, + { "f", "rocks" }, + { "g", "red daymark" }, + { "h", "green daymark" }, + { "i", "bell" }, + { "j", "danger" }, + { "k", "diver down" }, + { "l", "fish" }, + { "m", "house" }, + { "n", "mark" }, + { "o", "car" }, + { "p", "tent" }, + { "q", "boat" }, + { "r", "food" }, + { "s", "fuel" }, + { "t", "tree" }, + { NULL, NULL } +}; + +static icon_mapping_t map330_icon_table[] = { + { "a", "crossed square" }, + { "b", "box" }, + { "c", "house" }, + { "d", "aerial" }, + { "e", "airport" }, + { "f", "amusement park" }, + { "g", "ATM" }, + { "g", "Bank" }, + { "h", "auto repair" }, + { "i", "boating" }, + { "j", "camping" }, + { "k", "exit ramp" }, + { "l", "first aid" }, + { "m", "nav aid" }, + { "n", "buoy" }, + { "o", "fuel" }, + { "p", "garden" }, + { "q", "golf" }, + { "r", "hotel" }, + { "s", "hunting/fishing" }, + { "t", "large city" }, + { "u", "lighthouse" }, + { "v", "major city" }, + { "w", "marina" }, + { "x", "medium city" }, + { "y", "museum" }, + { "z", "obstruction" }, + { "aa", "park" }, + { "ab", "resort" }, + { "ac", "restaurant" }, + { "ad", "rock" }, + { "ae", "scuba" }, + { "af", "RV service" }, + { "ag", "shooting" }, + { "ah", "sight seeing" }, + { "ai", "small city" }, + { "aj", "sounding" }, + { "ak", "sports arena" }, + { "al", "tourist info" }, + { "am", "truck service" }, + { "an", "winery" }, + { "ao", "wreck" }, + { "ap", "zoo" }, + { "ah", "Virtual cache"}, /* Binos: because you "see" them. */ + { "ak", "Micro-Cache" }, /* Looks like a film canister. */ + { "an", "Multi-Cache"}, /* Winery: grapes 'coz they "bunch" */ + { "s", "Unknown Cache"}, /* 'Suprise' cache: use a target. */ + { "ac", "Event Cache"}, /* Event caches. May be food. */ + { NULL, NULL } +}; + +pid_to_model_t pid_to_model[] = +{ + { mm_gps315320, 19, "ColorTrak" }, + { mm_gps315320, 24, "GPS 315/320" }, + { mm_map410, 25, "Map 410" }, + { mm_map330, 30, "Map 330" }, + { mm_gps310, 31, "GPS 310" }, + { mm_meridian, 33, "Meridian" }, + { mm_meridian, 35, "ProMark 2" }, + { mm_sportrak, 36, "SporTrak Map/Pro" }, + { mm_sportrak, 37, "SporTrak" }, + { mm_meridian, 38, "FX324 Plotter" }, + { mm_meridian, 39, "Meridian Color" }, + { mm_meridian, 40, "FX324C Plotter" }, + { mm_sportrak, 41, "Sportrak Color" }, + { mm_sportrak, 42, "Sportrak Marine" }, + { mm_meridian, 43, "Meridian Marine" }, + { mm_sportrak, 44, "Sportrak Topo" }, + { mm_sportrak, 45, "Mystic" }, + { mm_meridian, 46, "MobileMapper" }, + { mm_meridian, 110, "Explorist 100" }, + { mm_meridian, 111, "Explorist 200" }, + { mm_unknown, 0, NULL } +}; + +static icon_mapping_t *icon_mapping = map330_icon_table; + +/* + * For each receiver type, return a "cleansed" version of the string + * that's valid for a waypoint name or comment. The string should be + * freed when you're done with it. + */ +static char * +m315_cleanse(char *istring) +{ + char *rstring = xmalloc(strlen(istring)+1); + char *i,*o; + static char m315_valid_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"; + for (o=rstring,i=istring; *i; i++) { + if (strchr(m315_valid_chars, toupper(*i))) { + *o++ = toupper(*i); + } + } + *o = 0; + return rstring; +} + +/* + * Do same for 330, Meridian, and SportTrak. + */ +char * +m330_cleanse(char *istring) +{ + static char m330_valid_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + "abcdefghijklmnopqrstuvwxyz" + "0123456789+-.'/!@#<%^&>()=:\\"; + char *rstring = xmalloc(strlen(istring)+1); + char *o, *i; + + for (o=rstring,i=istring; *i;i++) { + if (strchr(m330_valid_chars, *i)) { + *o++ = *i; + } + } + *o = 0; + return rstring; +} + +/* + * Given a protocol message, compute the checksum as needed by + * the Magellan protocol. + */ +unsigned int +mag_checksum(const char * const buf) +{ + int csum = 0; + const char *p; + + for(p = buf; *p; p++) { + csum ^= *p; + } + + return csum; +} +static unsigned int +mag_pchecksum(const char * const buf, int len) +{ + int csum = 0; + const char *p = buf; + for (; len ; len--) { + csum ^= *p++; + } + return csum; +} + +static void +mag_writemsg(const char * const buf) +{ + unsigned int osum = mag_checksum(buf); + int retry_cnt = 5; + int i; + char obuf[1000]; + + if (debug_serial) { + warning("WRITE: $%s*%02X\r\n",buf, osum); + } + + retry: + + i = sprintf(obuf, "$%s*%02X\r\n",buf, osum); + termwrite(obuf, i); + if (magrxstate == mrs_handon || magrxstate == mrs_awaiting_ack) { + magrxstate = mrs_awaiting_ack; + mag_readmsg(trkdata); + if (last_rx_csum != osum) { + if (debug_serial) { + warning("COMM ERROR: Expected %02x, got %02x", + osum, last_rx_csum); + } + if (retry_cnt--) + goto retry; + else { + mag_handoff(); + fatal(MYNAME + ": Too many communication errors.\n"); + } + } + } +} + +static void +mag_writeack(int osum) +{ + char obuf[200]; + char nbuf[200]; + int i; + unsigned int nsum; + + if (is_file) { + return; + } + + i = sprintf(nbuf, "PMGNCSM,%02X", osum); + nsum = mag_checksum(nbuf); + i = sprintf(obuf, "$%s*%02X\r\n",nbuf, nsum); + + if (debug_serial) { + warning("ACK WRITE: %s",obuf); + } + /* + * Don't call mag_writemsg here so we don't get into ack feedback + * loops. + */ + termwrite(obuf, i); +} + +static void +mag_handon(void) +{ + if (!is_file) { + mag_writemsg("PMGNCMD,HANDON"); + } + magrxstate = mrs_handon; + +} + +static void +mag_handoff(void) +{ + if (!is_file) { + mag_writemsg("PMGNCMD,HANDOFF"); + } + magrxstate = mrs_handoff; +} + +void +mag_verparse(char *ibuf) +{ + int prodid = mm_unknown; + char version[1024]; + pid_to_model_t *pp = pid_to_model; + + got_version = 1; + sscanf(ibuf,"$PMGNVER,%d,%[^,]", &prodid, version); + + for (pp = pid_to_model; pp->model != mm_unknown; pp++) { + if (pp->pid == prodid) { + break; + } + } + + if (prodid == 37) { + broken_sportrak = 1; + } + + switch (pp->model) { + case mm_gps315320: + case mm_map410: + icon_mapping = gps315_icon_table; + setshort_length(mkshort_handle, 6); + setshort_mustupper(mkshort_handle, 1); + mag_cleanse = m315_cleanse; + break; + case mm_map330: + case mm_meridian: + case mm_sportrak: + icon_mapping = map330_icon_table; + setshort_length(mkshort_handle, wpt_len); + setshort_mustupper(mkshort_handle, 0); + mag_cleanse = m330_cleanse; + break; + default: + fatal(MYNAME ": Unknown receiver type %d, model version '%s'.\n", prodid, version); + } +} + +#define IS_TKN(x) (strncmp(ibuf,x, sizeof(x)-1) == 0) + +static void +mag_readmsg(gpsdata_type objective) +{ + char ibuf[512]; /* oliskoli: corrupted data (I've seen descr with a lot + of escaped FFFFFFFF) may need more size */ + int isz; + unsigned int isum; + char *isump; + char *gr; + int retrycnt = 20; + +retry: + gr = termread(ibuf, sizeof(ibuf)); + + if (!gr) { + if (!got_version) { + /* + * The 315 can take up to six seconds to respond to + * a VERSION command. Since this is on startup, + * we'll be fairly persistent in retrying. + */ + if (retrycnt--) { + goto retry; + } else { + fatal(MYNAME ": No data received from GPS.\n"); + } + } else { + if (is_file) { + found_done = 1; + } + return; + } + } + + /* If column zero isn't a dollar sign, it's not for us */ + if (ibuf[0] != '$') { + fatal(MYNAME ": line doesn't start with '$'.\n"); + } + + + isz = strlen(ibuf); + + if (isz < 5) { + if (debug_serial) + warning( "SHORT READ %d\n", isz); + return; + } + mag_error = 0; + while (!isprint(ibuf[isz])) + isz--; + isump = &ibuf[isz-1]; + isum = strtoul(isump, NULL,16); + if (isum != mag_pchecksum(&ibuf[1], isz-3)) { + if (debug_serial) + warning( "RXERR %02x/%02x: '%s'\n", isum, mag_pchecksum(&ibuf[1],isz-5), ibuf); + /* Special case receive errors early on. */ + if (!got_version) { + fatal(MYNAME ": bad communication. Check bit rate.\n"); + } + } + if (debug_serial) { + warning( "READ: %s\n", ibuf); + } + if (IS_TKN("$PMGNCSM,")) { + last_rx_csum = strtoul(&ibuf[9], NULL, 16); + magrxstate = mrs_handon; + return; + } + if (strncmp(ibuf, "$PMGNWPL,", 7) == 0) { + waypoint *wpt = mag_wptparse(ibuf); + waypoint_read_count++; + if (global_opts.verbose_status) { + waypt_status_disp(waypoint_read_count, + waypoint_read_count); + } + + if (extension_hint) { + if (extension_hint == WPTDATAMASK) { + waypt_add(wpt); + } else if (extension_hint == RTEDATAMASK) { + ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); + } + } else { + switch (objective) { + case wptdata: + waypt_add(wpt); + break; + case rtedata: + ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); + break; + default: + break; + } + } + } + if (strncmp(ibuf, "$PMGNTRK,", 7) == 0) { + waypoint *wpt = mag_trkparse(ibuf); + /* + * Allow lazy allocation of track head. + */ + if (trk_head == NULL) { + /* These tracks don't have names, so derive one + * from input filename. + */ + char *e; + const char *s = get_filename(curfname); + + trk_head = route_head_alloc(); + + /* Whack trailing extension if present. */ + trk_head->rte_name = xstrdup(s); + e = strrchr(trk_head->rte_name, '.'); + if (e) { + *e = '\0'; + } + + track_add_head(trk_head); + } + + track_add_wpt(trk_head, wpt); + } + if (strncmp(ibuf, "$PMGNRTE,", 7) == 0) { + mag_rteparse(ibuf); + } + if (IS_TKN("$PMGNVER,")) { + mag_verparse(ibuf); + } + mag_error = 0; + if (!ignore_unable && IS_TKN("$PMGNCMD,UNABLE")) { + warning( "Unable to send\n"); + found_done = 1; + mag_error = 1; + ignore_unable = 0; + return; + } + if (IS_TKN("$PMGNCMD,END") || (is_file && (gbfeof(magfile_h)))) { + found_done = 1; + return; + } + + if (magrxstate != mrs_handoff) { + mag_writeack(isum); + } +} + +static void *serial_handle = NULL; + +static int +terminit(const char *portname, int create_ok) +{ + if (gbser_is_serial(portname)) { + if (serial_handle = gbser_init(portname), NULL != serial_handle) { + int rc; + if (rc = gbser_set_port(serial_handle, bitrate, 8, 0, 1), gbser_OK != rc) { + fatal(MYNAME ": Can't configure port\n"); + } + } + is_file = 0; + if (serial_handle == NULL) { + fatal(MYNAME ": Could not open serial port %s\n", portname); + } + return 1; + } else { + /* Does this check for an error? */ + magfile_h = gbfopen(portname, create_ok ? "w+b" : "rb", MYNAME); + is_file = 1; + icon_mapping = map330_icon_table; + mag_cleanse = m330_cleanse; + got_version = 1; + return 0; + } +} + +static char *termread(char *ibuf, int size) +{ + if (is_file) { + return gbfgets(ibuf, size, magfile_h); + } else { + int rc; + rc = gbser_read_line(serial_handle, ibuf, size, 2000, 0x0a, 0x0d); + if (rc != gbser_OK) { + fatal(MYNAME ": Read error\n"); + } + return ibuf; + } +} + +/* Though not documented in the protocol spec, if the unit itself + * wants to create a field containing a comma, it will encode it + * as 2C. We extrapolate that any 2 digit hex encoding may + * be valid. We don't do this in termread() since we need to do it + * after the scanf. This means we have to do it field-by-field + * basis. + * + * The buffer is modified in place and shortened by copying the remaining + * string including the terminator. + */ +static +void +mag_dequote(char *ibuf) +{ + char *esc = NULL; + + while ((esc = strchr (ibuf, 0x1b))) { + int nremains = strlen(esc); + if (nremains >= 3) { + static const char hex[16] = "0123456789ABCDEF"; + char *c1 = strchr(hex, esc[1]); + char *c2 = strchr(hex, esc[2]); + if (c1 && c2) { + int escv = (c1 - hex) * 16 + (c2 - hex); + if (escv == 255) { /* corrupted data */ + char *tmp = esc + 1; + while (*tmp == 'F') tmp++; + memmove(esc, tmp, strlen(tmp) + 1); + } + else { + *esc++ = (isprint(escv)) ? escv : '$'; + /* buffers overlap */ + memmove(esc, esc+2, nremains - 2); + } + } + } + else { + *esc = '\0'; /* trim corrupted data, + otherwise we get an endless loop */ + } + } +} + +static void +termwrite(char *obuf, int size) +{ + if (is_file) { + size_t nw; + if (nw = gbfwrite(obuf, 1, size, magfile_h), nw < (size_t) size) { + fatal(MYNAME ": Write error"); + } + } else { + int rc; + if (rc = gbser_write(serial_handle, obuf, size), rc < 0) { + fatal(MYNAME ": Write error"); + } + } +} + +static void termdeinit() +{ + if (is_file) { + gbfclose(magfile_h); + magfile_h = NULL; + } else { + gbser_deinit(serial_handle); + serial_handle = NULL; + } +} + +/* + * Arg tables are doubled up so that -? can output appropriate help + */ +static +arglist_t mag_sargs[] = { + {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX }, + {"maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", + "200", ARGTYPE_INT, ARG_NOMINMAX }, + {"baud", &bs, "Numeric value of bitrate (baud=4800)", "4800", + ARGTYPE_INT, ARG_NOMINMAX }, + {"noack", &noack, "Suppress use of handshaking in name of speed", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static +arglist_t mag_fargs[] = { + {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX }, + {"maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", + NULL, ARGTYPE_INT, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +/* + * The part of the serial init that's common to read and write. + */ +static void +mag_serial_init_common(const char *portname) +{ + time_t now, later; + + if (is_file) { + return; + } + + mag_handoff(); + if (!noack && !suppress_ack) + mag_handon(); + + now = current_time(); + /* + * The 315 can take up to 4.25 seconds to respond to initialization + * commands. Time out on the side of caution. + */ + later = now + 6; + got_version = 0; + mag_writemsg("PMGNCMD,VERSION"); + + while (!got_version) { + mag_readmsg(trkdata); + if (current_time() > later) { + fatal(MYNAME ": No acknowledgment from GPS on %s\n", + portname); + } + } + + if ((icon_mapping != gps315_icon_table)) { + /* + * The 315 can't handle this command, so we set a global + * to ignore the NAK on it. + */ + ignore_unable = 1; + mag_writemsg("PMGNCMD,NMEAOFF"); + ignore_unable = 0; + } + + if (nukewpt) { + /* The unit will send us an "end" message upon completion */ + mag_writemsg("PMGNCMD,DELETE,WAYPOINT"); + mag_readmsg(trkdata); + if (!found_done) { + fatal(MYNAME ": Unexpected response to waypoint delete command.\n"); + } + found_done = 0; + } + +} +static void +mag_rd_init_common(const char *portname) +{ + char *ext; + waypoint_read_count = 0; + + if (bs) { + bitrate=atoi(bs); + } + + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } + + terminit(portname, 0); + mag_serial_init_common(portname); + + QUEUE_INIT(&rte_wpt_tmp); + + /* find the location of the tail of the path name, + * make a copy of it, then lop off the file extension + */ + + curfname = get_filename(portname); + + /* + * I'd rather not derive behaviour from filenames but since + * we can't otherwise tell if we should put a WPT on the route + * queue or the WPT queue in the presence of (-w -r -t) we + * divine a hint from the filename extension when we can. + */ + ext = strrchr(curfname, '.'); + if (ext) { + ext++; + if (0 == case_ignore_strcmp(ext, "upt")) { + extension_hint = WPTDATAMASK; + } else if (0 == case_ignore_strcmp(ext, "log")) { + extension_hint = TRKDATAMASK; + } else if (0 == case_ignore_strcmp(ext, "rte")) { + extension_hint = RTEDATAMASK; + } + } + + return; +} + +static void +mag_rd_init(const char *portname) +{ + explorist = 0; + suppress_ack = 1; + mag_rd_init_common(portname); +} + +static void +magX_rd_init(const char *portname) +{ + explorist = 1; + mag_rd_init_common(portname); +} + +static void +mag_wr_init_common(const char *portname) +{ + suppress_ack = 0; + if (bs) { + bitrate=atoi(bs); + } + + if (waypt_count() > 500) { + fatal(MYNAME ": Meridian/Explorist does not support more than 500 waypoints in one file. Only\n200 waypoints may have comments.\nDecrease the number of waypoints sent.\n"); + } + + if (cmts) { + wptcmtcnt_max = atoi(cmts); + } else { + wptcmtcnt_max = MAXCMTCT ; + } + + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } + + terminit(portname, 1); + mag_serial_init_common(portname); + + QUEUE_INIT(&rte_wpt_tmp); +} + +/* + * Entry point for extended (explorist) points. + */ +static void +magX_wr_init(const char *portname) +{ + wpt_len = 20; + explorist = 1; + mag_wr_init_common(portname); + setshort_length(mkshort_handle, wpt_len); + setshort_whitespace_ok(mkshort_handle, 1); +} + +static void +mag_wr_init(const char *portname) +{ + explorist = 0; + wpt_len = 8; + mag_wr_init_common(portname); + /* + * Whitespace is actually legal, but since waypoint name length is + * only 8 bytes, we'll conserve them. + */ + + setshort_whitespace_ok(mkshort_handle, 0); +} + +static void +mag_deinit(void) +{ + mag_handoff(); + termdeinit(); + if(mkshort_handle) + mkshort_del_handle(&mkshort_handle); + + waypt_flush(&rte_wpt_tmp); + + trk_head = NULL; +} + +/* + * I'm tired of arguing with scanf about optional fields . Detokenize + * an incoming string that may contain empty fields. + * + * Probably should be cleaned up and moved to common code, but + * making it deal with an arbitrary number of fields of arbitrary + * size is icky. We don't have to solve the general case here... + */ + +static char ifield[20][100]; +static +void parse_istring(char *istring) +{ + int f = 0; + int n,x; + while (istring[0]) { + char *fp = ifield[f]; + x = sscanf(istring, "%[^,]%n", fp, &n); + f++; + if (x) { + istring += n; + /* IF more in this string, skip delim */ + if (istring[0]) istring++; + } else { + istring ++; + } + } +} + +/* + * Given an incoming track messages of the form: + * $PMGNTRK,3605.259,N,08644.389,W,00151,M,201444.61,A,,020302*66 + * create and return a populated waypoint. + */ +waypoint * +mag_trkparse(char *trkmsg) +{ + double latdeg, lngdeg; + int alt; + char altunits; + char lngdir, latdir; + int dmy; + int hms; + int fracsecs; + struct tm tm; + waypoint *waypt; + + waypt = waypt_new(); + + memset(&tm, 0, sizeof(tm)); + + /* + * As some of the fields are optional, sscanf works badly + * for us. + */ + parse_istring(trkmsg); + latdeg = atof(ifield[1]); + latdir = ifield[2][0]; + lngdeg = atof(ifield[3]); + lngdir = ifield[4][0]; + alt = atof(ifield[5]); + altunits = ifield[6][0]; + sscanf(ifield[7], "%d.%d", &hms, &fracsecs); + /* Field 8 is constant */ + /* Field nine is optional track name */ + dmy = atoi(ifield[10]); + + tm.tm_sec = hms % 100; + hms = hms / 100; + tm.tm_min = hms % 100; + hms = hms / 100; + tm.tm_hour = hms % 100; + + tm.tm_year = 100 + dmy % 100; + dmy = dmy / 100; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy % 100; + + waypt->creation_time = mkgmtime(&tm); + waypt->microseconds = CENTI_TO_MICRO(fracsecs); + + if (latdir == 'S') latdeg = -latdeg; + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') lngdeg = -lngdeg; + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->altitude = alt; + + return waypt; + +} + +/* + * Given an incoming route messages of the form: + * $PMGNRTE,4,1,c,1,DAD,a,Anna,a*61 + * generate a route. + */ +void +mag_rteparse(char *rtemsg) +{ + char descr[100]; + int n; + int frags,frag,rtenum; + char xbuf[100],next_stop[100],abuf[100]; + char *currtemsg; + static mag_rte_head *mag_rte_head; + mag_rte_elem *rte_elem; + char *p; + char *rte_name = NULL; + + descr[0] = 0; +#if 0 + sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", + &frags,&frag,xbuf,&rtenum,&n); +#else + sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", + &frags,&frag,xbuf,&rtenum,&n); + + /* Explorist has a route name here */ + if (explorist) { + char *ca, *ce; + + ca = rtemsg + n; + is_fatal(*ca++ != ',', MYNAME ": Incorrectly formatted route line '%s'", rtemsg); + + ce = strchr(ca, ','); + is_fatal(ce == NULL, MYNAME ": Incorrectly formatted route line '%s'", rtemsg); + + if (ca == ce) + xasprintf(&rte_name, "Route%d", rtenum); + else + rte_name = xstrndup(ca, ce - ca); + + n += ((ce - ca) + 1); + } + +#endif + + /* + * This is the first component of a route. Allocate a new + * queue head. + */ + if (frag == 1) { + mag_rte_head = xcalloc(sizeof (*mag_rte_head),1); + QUEUE_INIT(&mag_rte_head->Q); + mag_rte_head->nelems = frags; + } + + currtemsg = rtemsg + n; + + /* + * The individual line may contain several route elements. + * loop and pick those up. + */ + while (sscanf(currtemsg,",%[^,],%[^,]%n",next_stop, abuf,&n)) { + if ((next_stop[0] == 0) || (next_stop[0] == '*')) { + break; + } + + /* trim CRC from waypoint icon string */ + if ((p = strchr(abuf, '*')) != NULL) + *p = '\0'; + + rte_elem = xcalloc(sizeof (*rte_elem),1); + QUEUE_INIT(&rte_elem->Q); + + rte_elem->wpt_name = xstrdup(next_stop); + rte_elem->wpt_icon = xstrdup(abuf); + + ENQUEUE_TAIL(&mag_rte_head->Q, &rte_elem->Q); + + /* Sportrak (the non-mapping unit) creates malformed + * RTE sentence with no icon info after the routepoint + * name. So if we saw an "icon" treat that as new + * routepoint. + */ + if (broken_sportrak && abuf[0]) { + rte_elem = xcalloc(sizeof (*rte_elem),1); + QUEUE_INIT(&rte_elem->Q); + rte_elem->wpt_name = xstrdup(abuf); + + ENQUEUE_TAIL(&mag_rte_head->Q, &rte_elem->Q); + } + + next_stop[0] = 0; + currtemsg += n; + } + + /* + * If this was the last fragment of the route, add it to the + * gpsbabel internal structs now. + */ + if (frag == mag_rte_head->nelems) { + queue *elem, *tmp; + route_head *rte_head; + + rte_head = route_head_alloc(); + route_add_head(rte_head); + rte_head->rte_num = rtenum; + rte_head->rte_name = xstrdup(rte_name); + + /* + * It is quite feasible that we have 200 waypoints, + * 3 of which are used in the route. We'll need to find + * those in the queue for SD routes... + */ + + QUEUE_FOR_EACH(&mag_rte_head->Q, elem, tmp) { + mag_rte_elem *re = (mag_rte_elem *) elem; + waypoint *waypt; + queue *welem, *wtmp; + + /* + * Copy route points from temp wpt queue. + */ + QUEUE_FOR_EACH(&rte_wpt_tmp, welem, wtmp) { + waypt = (waypoint *)welem; + if (strcmp(waypt->shortname, re->wpt_name) == 0) { + waypoint * wpt = waypt_dupe(waypt); + route_add_wpt(rte_head, wpt); + break; + } + } + + dequeue(&re->Q); + xfree(re->wpt_name); + xfree(re->wpt_icon); + xfree(re); + } + xfree(mag_rte_head); + } + if (rte_name) xfree(rte_name); +} + +const char * +mag_find_descr_from_token(const char *token) +{ + icon_mapping_t *i = icon_mapping; + + if (icon_mapping == NULL) { + return "unknown"; + } + + for (i = icon_mapping; i->token; i++) { + if (token[0] == 0) break; + if (case_ignore_strcmp(token, i->token) == 0) + return i->icon; + } + return icon_mapping[0].icon; +} + +const char * +mag_find_token_from_descr(const char *icon) +{ + icon_mapping_t *i = icon_mapping; + + if (i == NULL || icon == NULL) { + return "a"; + } + + for (i = icon_mapping; i->token; i++) { + if (case_ignore_strcmp(icon, i->icon) == 0) + return i->token; + } + return icon_mapping[0].token; +} + +/* + * Given an incoming waypoint messages of the form: + * $PMGNWPL,3549.499,N,08650.827,W,0000257,M,HOME,HOME,c*4D + * create and return a populated waypoint. + */ +static waypoint * +mag_wptparse(char *trkmsg) +{ + double latdeg, lngdeg; + char latdir; + char lngdir; + int alt; + char altunits; + char shortname[100]; + char descr[256]; + char icon_token[100]; + waypoint *waypt; + char *icons; + char *icone; + char *blah; + int i = 0; + + descr[0] = 0; + icon_token[0] = 0; + + waypt = waypt_new(); + + sscanf(trkmsg,"$PMGNWPL,%lf,%c,%lf,%c,%d,%c,%[^,],%[^,]", + &latdeg,&latdir, + &lngdeg,&lngdir, + &alt,&altunits,shortname,descr); + icone = strrchr(trkmsg, '*'); + icons = strrchr(trkmsg, ',')+1; + + mag_dequote(descr); + + for (blah = icons ; blah < icone; blah++) + icon_token[i++] = *blah; + icon_token[i++] = '\0'; + + if (latdir == 'S') latdeg = -latdeg; + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') lngdeg = -lngdeg; + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->altitude = alt; + waypt->shortname = xstrdup(shortname); + waypt->description = xstrdup(descr); + waypt->icon_descr = mag_find_descr_from_token(icon_token); + + return waypt; +} + +static void +mag_read(void) +{ + found_done = 0; + if (global_opts.masked_objective & TRKDATAMASK) { + magrxstate = mrs_handoff; + if (!is_file) + mag_writemsg("PMGNCMD,TRACK,2"); + + while (!found_done) { + mag_readmsg(trkdata); + } + } + + found_done = 0; + if (global_opts.masked_objective & WPTDATAMASK) { + magrxstate = mrs_handoff; + if (!is_file) + mag_writemsg("PMGNCMD,WAYPOINT"); + + while (!found_done) { + mag_readmsg(wptdata); + } + } + + found_done = 0; + if (global_opts.masked_objective & RTEDATAMASK) { + magrxstate = mrs_handoff; + if (!is_file) { + /* + * serial routes require waypoint & routes + * messages commands. + */ + mag_writemsg("PMGNCMD,WAYPOINT"); + + while (!found_done) { + mag_readmsg(rtedata); + } + + mag_writemsg("PMGNCMD,ROUTE"); + + found_done = 0; + while (!found_done) { + mag_readmsg(rtedata); + } + } else { + /* + * SD routes are a stream of PMGNWPL and + * PMGNRTE messages, in that order. + */ + while (!found_done) { + mag_readmsg(rtedata); + } + } + } +} + +static +void +mag_waypt_pr(const waypoint *waypointp) +{ + double lon, lat; + double ilon, ilat; + int lon_deg, lat_deg; + char obuf[200]; + char ofmtdesc[200]; + const char *icon_token=NULL; + char *owpt; + char *odesc; + char *isrc = NULL; + + ilat = waypointp->latitude; + ilon = waypointp->longitude; + + lon = fabs(ilon); + lat = fabs(ilat); + + lon_deg = lon; + lat_deg = lat; + + lon = (lon - lon_deg) * 60.0; + lat = (lat - lat_deg) * 60.0; + + lon = (lon_deg * 100.0 + lon); + lat = (lat_deg * 100.0 + lat); + + if (deficon) { + icon_token = mag_find_token_from_descr(deficon); + } else { + icon_token = mag_find_token_from_descr(waypointp->icon_descr); + } + + if (get_cache_icon(waypointp)) { + icon_token = mag_find_token_from_descr(get_cache_icon(waypointp)); + } + + isrc = waypointp->notes ? waypointp->notes : waypointp->description; + owpt = global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, waypointp) : waypointp->shortname; + odesc = isrc ? isrc : ""; + owpt = mag_cleanse(owpt); + + if (global_opts.smart_icons && + waypointp->gc_data.diff && waypointp->gc_data.terr) { + sprintf(ofmtdesc, "%d/%d %s", waypointp->gc_data.diff, + waypointp->gc_data.terr, odesc); + odesc = mag_cleanse(ofmtdesc); + } else { + odesc = mag_cleanse(odesc); + } + + /* + * For the benefit of DirectRoute (which uses waypoint comments + * to deliver turn-by-turn popups for street routing) allow a + * cap on the comments delivered so we leave space for it to route. + */ + if (odesc && /* !is_file && */ (wptcmtcnt++ >= wptcmtcnt_max)) + odesc[0] = 0; + + sprintf(obuf, "PMGNWPL,%4.3f,%c,%09.3f,%c,%07.0f,M,%-.*s,%-.46s,%s", + lat, ilat < 0 ? 'S' : 'N', + lon, ilon < 0 ? 'W' : 'E', + waypointp->altitude == unknown_alt ? + 0 : waypointp->altitude, + wpt_len, + owpt, + odesc, + icon_token); + mag_writemsg(obuf); + xfree(owpt); + xfree(odesc); + + if (!is_file) { + if (mag_error) { + warning( "Protocol error Writing '%s'\n", obuf); + } + } +} + +static +void mag_track_nop(const route_head *rte) +{ + return; +} + +static +void mag_track_disp(const waypoint *waypointp) +{ + double ilon, ilat; + double lon, lat; + int lon_deg, lat_deg; + char obuf[200]; + int hms=0; + int fracsec=0; + int date=0; + struct tm *tm = NULL; + + ilat = waypointp->latitude; + ilon = waypointp->longitude; + tm = NULL; + if (waypointp->creation_time) { + tm = gmtime(&waypointp->creation_time); + if ( tm ) { + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + + tm->tm_sec; + date = tm->tm_mday * 10000 + tm->tm_mon * 100 + + tm->tm_year; + fracsec = MICRO_TO_CENTI(waypointp->microseconds); + } + } + if (!tm) { + date = 0; + fracsec = 0; + } + + lon = fabs(ilon); + lat = fabs(ilat); + + lon_deg = lon; + lat_deg = lat; + + lon = (lon - lon_deg) * 60.0; + lat = (lat - lat_deg) * 60.0; + + lon = (lon_deg * 100.0 + lon); + lat = (lat_deg * 100.0 + lat); + + sprintf(obuf,"PMGNTRK,%4.3f,%c,%09.3f,%c,%05.0f,%c,%06d.%02d,A,,%06d", + lat, ilat < 0 ? 'S' : 'N', + lon, ilon < 0 ? 'W' : 'E', + waypointp->altitude == unknown_alt ? + 0 : waypointp->altitude, + 'M',hms,fracsec,date); + mag_writemsg(obuf); +} + +static +void mag_track_pr() +{ + track_disp_all(mag_track_nop, mag_track_nop, mag_track_disp); +} + +/* +The spec says to stack points: + $PMGNRTE,2,1,c,1,FOO,POINT1,b,POINT2,c,POINT3,d*6C + +Meridian SD card and serial (at least) writes in pairs: + $PMGNRTE,4,1,c,1,HOME,c,I49X73,a*15 + ... + $PMGNRTE,4,4,c,1,RON273,a,MYCF93,a*7B + +The spec also says that some units don't like single-legged pairs, +and to replace the 2nd name with "<<>>", but I haven't seen one of those. +*/ + +static void +mag_route_trl(const route_head * rte) +{ + queue *elem, *tmp; + waypoint *waypointp; + char obuff[256]; + char buff1[64], buff2[64]; + char *pbuff, *owpt; + const char * icon_token; + int i, numlines, thisline; + + /* count waypoints for this route */ + i = rte->rte_waypt_ct; + + /* number of output PMGNRTE messages at 2 points per line */ + numlines = (i / 2) + (i % 2); + + /* increment the route counter. */ + route_out_count++; + + thisline = i = 0; + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + waypointp = (waypoint *) elem; + i++; + + if (deficon) + icon_token = mag_find_token_from_descr(deficon); + else + icon_token = mag_find_token_from_descr(waypointp->icon_descr); + + if (i == 1) + pbuff = buff1; + else + pbuff = buff2; + + owpt = waypointp->shortname; + if (strlen(owpt) > sizeof(buff1) - 3) { + owpt[sizeof(buff1) - 3] = 0; + } + owpt = mag_cleanse(owpt); + + sprintf(pbuff, "%s,%s", owpt, icon_token); + + xfree(owpt); + + if ((tmp == &rte->waypoint_list) || ((i % 2) == 0)) { + char expbuf[1024]; + thisline++; + expbuf[0] = 0; + if (explorist) { + snprintf(expbuf, sizeof(expbuf), "%s,", + rte->rte_name ? rte->rte_name : ""); + } + sprintf(obuff, "PMGNRTE,%d,%d,c,%d,%s%s,%s", + numlines, thisline, + rte->rte_num ? rte->rte_num : route_out_count, + expbuf, + buff1, buff2); + + mag_writemsg(obuff); + buff1[0] = '\0'; + buff2[0] = '\0'; + i = 0; + } + } +} + +static void +mag_route_hdr(const route_head *rh) +{ +} + +static void +mag_route_pr() +{ + route_out_count = 0; + route_disp_all(mag_route_hdr, mag_route_trl, mag_waypt_pr); + +} + +static void +mag_write(void) +{ + + wptcmtcnt = 0; + + switch (global_opts.objective) + { + case trkdata: + mag_track_pr(); + break; + case wptdata: + waypt_disp_all(mag_waypt_pr); + break; + case rtedata: + mag_route_pr(); + break; + default: + fatal(MYNAME ": Unknown objective.\n"); + } +} + +/* + * This is repeated just so it shows up as separate menu options + * for the benefit of GUI wrappers. + */ +ff_vecs_t mag_svecs = { + ff_type_serial, + FF_CAP_RW_ALL, + mag_rd_init, + mag_wr_init, + mag_deinit, + mag_deinit, + mag_read, + mag_write, + NULL, + mag_sargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; + +ff_vecs_t mag_fvecs = { + ff_type_file, + FF_CAP_RW_ALL, + mag_rd_init, + mag_wr_init, + mag_deinit, + mag_deinit, + mag_read, + mag_write, + NULL, + mag_fargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; + +/* + * Extended (Explorist) entry tables. + */ +ff_vecs_t magX_fvecs = { + ff_type_file, + FF_CAP_RW_ALL, + magX_rd_init, + magX_wr_init, + mag_deinit, + mag_deinit, + mag_read, + mag_write, + NULL, + mag_fargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/main.c b/main.c new file mode 100644 index 000000000..6e338ce07 --- /dev/null +++ b/main.c @@ -0,0 +1,698 @@ +/* + Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +#include "defs.h" +#include "filterdefs.h" +#include "cet.h" +#include "cet_util.h" +#include "csv_util.h" +#include "inifile.h" +#include +#include + +#define MYNAME "main" + +void signal_handler(int sig); + +typedef struct arg_stack_s { + int argn; + int argc; + char **argv; + struct arg_stack_s *prev; +} arg_stack_t; + +static arg_stack_t +*push_args(arg_stack_t *stack, const int argn, const int argc, char *argv[]) +{ + arg_stack_t *res = xmalloc(sizeof(*res)); + + res->prev = stack; + res->argn = argn; + res->argc = argc; + res->argv = (char **)argv; + + return res; +} + +static arg_stack_t +*pop_args(arg_stack_t *stack, int *argn, int *argc, char **argv[]) +{ + arg_stack_t *res; + char **argv2 = *argv; + int i; + + if (stack == NULL) fatal("main: Invalid point in time to call 'pop_args'\n"); + + for (i = 0; i < *argc; i++) + xfree(argv2[i]); + xfree(*argv); + + *argn = stack->argn; + *argc = stack->argc; + *argv = stack->argv; + + res = stack->prev; + xfree(stack); + + return res; +} + +static void +load_args(const char *filename, int *argc, char **argv[]) +{ + gbfile *fin; + char *str, *line = NULL; + int argc2; + char **argv2; + + fin = gbfopen(filename, "r", "main"); + while ((str = gbfgetstr(fin))) { + str = lrtrim(str); + if ((*str == '\0') || (*str == '#')) continue; + + if (line == NULL) line = xstrdup(str); + else { + char *tmp; + xasprintf(&tmp, "%s %s", line, str); + xfree(line); + line = tmp; + } + } + gbfclose(fin); + + argv2 = xmalloc(2 * sizeof(*argv2)); + argv2[0] = xstrdup(*argv[0]); + argc2 = 1; + + str = csv_lineparse(line, " ", "\"", 0); + while (str != NULL) { + argv2 = xrealloc(argv2, (argc2 + 2) * sizeof(*argv2)); + argv2[argc2] = xstrdup(str); + argc2++; + str = csv_lineparse(NULL, " ", "\"", 0); + } + xfree(line); + + argv2[argc2] = NULL; + + *argc = argc2; + *argv = argv2; +} + +static void +usage(const char *pname, int shorter ) +{ + printf("GPSBabel Version %s. http://www.gpsbabel.org\n\n", + gpsbabel_version ); + printf( +"Usage:\n" +" %s [options] -i INTYPE -f INFILE [filter] -o OUTTYPE -F OUTFILE\n" +" %s [options] -i INTYPE -o OUTTYPE INFILE [filter] OUTFILE\n" +"\n" +" Converts GPS route and waypoint data from one format type to another.\n" +" The input type and filename are specified with the -i INTYPE\n" +" and -f INFILE options. The output type and filename are specified\n" +" with the -o OUTTYPE and -F OUTFILE options.\n" +" If '-' is used for INFILE or OUTFILE, stdin or stdout will be used.\n" +"\n" +" In the second form of the command, INFILE and OUTFILE are the\n" +" first and second positional (non-option) arguments.\n" +"\n" +" INTYPE and OUTTYPE must be one of the supported file types and\n" +" may include options valid for that file type. For example:\n" +" 'gpx', 'gpx,snlen=10' and 'ozi,snlen=10,snwhite=1'\n" +" (without the quotes) are all valid file type specifications.\n" +"\n" +"Options:\n" +" -p Preferences file (gpsbabel.ini)\n" +" -s Synthesize shortnames\n" +" -r Process route information\n" +" -t Process track information\n" +" -T Process realtime tracking information\n" +" -w Process waypoint information [default]\n" +" -b Process command file (batch mode)\n" +" -c Character set for next operation\n" +" -N No smart icons on output\n" +" -x filtername Invoke filter (placed between inputs and output) \n" +" -D level Set debug level [%d]\n" +" -l Print GPSBabel builtin character sets and exit\n" +" -h, -? Print detailed help and exit\n" +" -V Print GPSBabel version and exit\n" +"\n" + , pname + , pname + , global_opts.debug_level + ); + if ( shorter ) { + printf( "\n\n[Press enter]" ); + fgetc(stdin); + } + else { + printf("File Types (-i and -o options):\n"); + disp_vecs(); + printf("\nSupported data filters:\n"); + disp_filter_vecs(); + } +} + +static void +spec_usage( const char *vec ) { + printf( "\n" ); + disp_vec( vec ); + disp_filter_vec ( vec ); + printf( "\n" ); +} + +static void +print_extended_info(void) +{ + printf( + +#if !ZLIB_INHIBITED /* Note polarity inverted here */ + "ZLIB_ENABLED " +#endif + +#if FILTERS_ENABLED + "FILTERS_ENABLED " +#endif + +#if CSVFMTS_ENABLED + "CSVFMTS_ENABLED " +#endif + +#if PDBFMTS_ENABLED + "PDBFMTS_ENABLED " +#endif + +#if SHAPELIB_ENABLED + "SHAPELIB_ENABLED " +#endif +#if HAVE_LIBEXPAT + "HAVE_LIBEXPAT " +#if XML_UNICODE + "XML_UNICODE " +#endif +#endif + +#if defined CET_WANTED + "CET_ENABLED " +#endif + "\n"); +} + +int +main(int argc, char *argv[]) +{ + int c; + int argn; + ff_vecs_t *ivecs = NULL; + ff_vecs_t *ovecs = NULL; + filter_vecs_t *fvecs = NULL; + char *fname = NULL; + char *ofname = NULL; + char *ivec_opts = NULL; + char *ovec_opts = NULL; + char *fvec_opts = NULL; + int opt_version = 0; + int did_something = 0; + const char *prog_name = argv[0]; /* argv is modified during processing */ + queue *wpt_head_bak, *rte_head_bak, *trk_head_bak; /* #ifdef UTF8_SUPPORT */ + signed int wpt_ct_bak, rte_ct_bak, trk_ct_bak; /* #ifdef UTF8_SUPPORT */ + arg_stack_t *arg_stack = NULL; + + global_opts.objective = wptdata; + global_opts.masked_objective = NOTHINGMASK; /* this makes the default mask behaviour slightly different */ + global_opts.charset = NULL; + global_opts.charset_name = NULL; + global_opts.inifile = NULL; + + gpsbabel_now = time(NULL); /* gpsbabel startup-time */ + gpsbabel_time = current_time(); /* same like gpsbabel_now, but freezed to zero during testo */ + +#ifdef DEBUG_MEM + debug_mem_open(); + debug_mem_output( "command line: " ); + for ( argn = 1; argn < argc; argn++ ) { + debug_mem_output( "%s ", argv[argn] ); + } + debug_mem_output( "\n" ); +#endif + + if (gpsbabel_time != 0) { /* within testo ? */ + global_opts.inifile = inifile_init(NULL, MYNAME); + } + + cet_register(); + waypt_init(); + route_init(); + + if ( argc < 2 ) { + usage(argv[0],1); + exit(0); + } + + /* + * Open-code getopts since POSIX-impaired OSes don't have one. + */ + argn = 1; + while (argn < argc) { + char *optarg; + + if (argv[argn][0] != '-') { + break; + } + if (argv[argn][1] == '-') { + break; + } + + if (argv[argn][1] == 'V' ) { + printf("\nGPSBabel Version %s\n\n", gpsbabel_version ); + if (argv[argn][2] == 'V') { + print_extended_info(); + } + exit(0); + } + + if (argv[argn][1] == '?' || argv[argn][1] == 'h') { + if ( argn < argc-1 ) { + spec_usage( argv[argn+1] ); + } + else { + usage(argv[0],0); + } + exit(0); + } + + c = argv[argn][1]; + + if (argv[argn][2]) { + opt_version = atoi(&argv[argn][2]); + } + + switch (c) { + case 'c': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + cet_convert_init(optarg, 1); + break; + case 'i': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + ivecs = find_vec(optarg, &ivec_opts); + break; + case 'o': + if (ivecs == NULL) { + warning ("-o appeared before -i. This is probably not what you want to do.\n"); + } + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + ovecs = find_vec(optarg, &ovec_opts); + if (ovecs == NULL) { + fatal ("Output type '%s' not recognized\n", optarg); + } + break; + case 'f': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + fname = optarg; + if (fname == NULL) { + fatal ("No file or device name specified.\n"); + } + if (ivecs == NULL) { + fatal ("No valid input type specified\n"); + } + if (ivecs->rd_init == NULL) { + fatal ("Format does not support reading.\n"); + } + if (global_opts.masked_objective & POSNDATAMASK) { + did_something = 1; + break; + } + /* simulates the default behaviour of waypoints */ + if (doing_nothing) global_opts.masked_objective |= WPTDATAMASK; + + cet_convert_init(ivecs->encode, ivecs->fixed_encode); /* init by module vec */ + + ivecs->rd_init(fname); + ivecs->read(); + ivecs->rd_deinit(); + + cet_convert_strings(global_opts.charset, NULL, NULL); + cet_convert_deinit(); + + did_something = 1; + break; + case 'F': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + ofname = optarg; + if (ofname == NULL) { + fatal ("No output file or device name specified.\n"); + } + if (ovecs && (!(global_opts.masked_objective & POSNDATAMASK))) { + /* simulates the default behaviour of waypoints */ + if (doing_nothing) + global_opts.masked_objective |= WPTDATAMASK; + if (ovecs->wr_init == NULL) { + fatal ("Format does not support writing.\n"); + } + + cet_convert_init(ovecs->encode, ovecs->fixed_encode); + + wpt_ct_bak = -1; + rte_ct_bak = -1; + trk_ct_bak = -1; + rte_head_bak = trk_head_bak = NULL; + + ovecs->wr_init(ofname); + + if (global_opts.charset != &cet_cs_vec_utf8) + { + /* + * Push and pop verbose_status so + * we don't get dual progress bars + * when doing characterset + * transformation. + */ + int saved_status = global_opts.verbose_status; + global_opts.verbose_status = 0; + waypt_backup(&wpt_ct_bak, &wpt_head_bak); + route_backup(&rte_ct_bak, &rte_head_bak); + track_backup(&trk_ct_bak, &trk_head_bak); + + cet_convert_strings(NULL, global_opts.charset, NULL); + global_opts.verbose_status = saved_status; + } + + ovecs->write(); + ovecs->wr_deinit(); + + cet_convert_deinit(); + + if (wpt_ct_bak != -1) waypt_restore(wpt_ct_bak, wpt_head_bak); + if (rte_ct_bak != -1) { + route_restore( rte_head_bak); + xfree( rte_head_bak ); + } + if (trk_ct_bak != -1) { + track_restore( trk_head_bak); + xfree( trk_head_bak ); + } + } + break; + case 's': + global_opts.synthesize_shortnames = 1; + break; + case 't': + global_opts.objective = trkdata; + global_opts.masked_objective |= TRKDATAMASK; + break; + case 'w': + global_opts.objective = wptdata; + global_opts.masked_objective |= WPTDATAMASK; + break; + case 'r': + global_opts.objective = rtedata; + global_opts.masked_objective |= RTEDATAMASK; + break; + case 'T': + global_opts.objective = posndata; + global_opts.masked_objective |= POSNDATAMASK; + break; + case 'N': +#if 0 +/* This option is silently eaten for compatibilty. -N is now the + * default. If you want the old behaviour, -S allows you to individually + * turn them on. The -N option will be removed in 2008. + */ + + switch(argv[argn][2]) { + case 'i': + global_opts.no_smart_icons = 1; + break; + case 'n': + global_opts.no_smart_names = 1; + break; + default: + global_opts.no_smart_names = 1; + global_opts.no_smart_icons = 1; + break; + } +#endif + + break; + case 'S': + switch(argv[argn][2]) { + case 'i': + global_opts.smart_icons = 1; + break; + case 'n': + global_opts.smart_names = 1; + break; + default: + global_opts.smart_icons = 1; + global_opts.smart_names = 1; + break; + } + break; + case 'x': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + fvecs = find_filter_vec(optarg, &fvec_opts); + + if (fvecs) { + if (fvecs->f_init) fvecs->f_init(fvec_opts); + fvecs->f_process(); + if (fvecs->f_deinit) fvecs->f_deinit(); + free_filter_vec(fvecs); + } else { + fatal("Unknown filter '%s'\n",optarg); + } + break; + case 'D': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + global_opts.debug_level = atoi(optarg); + /* + * When debugging, announce version. + */ + if (global_opts.debug_level > 0) { + warning("GPSBabel Version: %s \n", gpsbabel_version ); + } + + break; + /* + * Undocumented '-vs' option for GUI wrappers. + */ + case 'v': + switch(argv[argn][2]) { + case 's': global_opts.verbose_status = 1; break; + case 'S': global_opts.verbose_status = 2; break; + } + break; + + /* + * DOS-derived systems will need to escape + * this as -^^. + */ + case '^': + disp_formats(opt_version); + exit(0); + case '%': + disp_filters(opt_version); + exit(0); + case 'h': + case '?': + usage(argv[0],0); + exit(0); + case 'l': + cet_disp_character_set_names(stdout); + exit(0); + case 'p': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + inifile_done(global_opts.inifile); + if (!optarg || strcmp(optarg, "") == 0) /* from GUI to preserve inconsistent options */ + global_opts.inifile = NULL; + else + global_opts.inifile = inifile_init(optarg, MYNAME); + break; + case 'b': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + arg_stack = push_args(arg_stack, argn, argc, argv); + load_args(optarg, &argc, &argv); + if (argc == 0) + arg_stack = pop_args(arg_stack, &argn, &argc, &argv); + else + argn = 0; + break; + + default: + fatal("Unknown option '%s'.\n", argv[argn]); + break; + } + + if ((argn+1 >= argc) && (arg_stack != NULL)) + arg_stack = pop_args(arg_stack, &argn, &argc, &argv); + argn++; + } + + /* + * Allow input and output files to be specified positionally + * as well. This is the typical command line format. + */ + argc -= argn; + argv += argn; + if (argc > 2) { + fatal ("Extra arguments on command line\n"); + } + else if (argc && ivecs) { + did_something = 1; + /* simulates the default behaviour of waypoints */ + if (doing_nothing) global_opts.masked_objective |= WPTDATAMASK; + + cet_convert_init(ivecs->encode, 1); + + ivecs->rd_init(argv[0]); + ivecs->read(); + ivecs->rd_deinit(); + + cet_convert_strings(global_opts.charset, NULL, NULL); + cet_convert_deinit(); + + if (argc == 2 && ovecs) + { + cet_convert_init(ovecs->encode, 1); + cet_convert_strings(NULL, global_opts.charset, NULL); + + ovecs->wr_init(argv[1]); + ovecs->write(); + ovecs->wr_deinit(); + + cet_convert_deinit(); + } + } + else if (argc) { + usage(prog_name,0); + exit(0); + } + if (ovecs == NULL) + { + /* + * Push and pop verbose_status so we don't get dual + * progress bars when doing characterset transformation. + */ + int saved_status = global_opts.verbose_status; + global_opts.verbose_status = 0; + cet_convert_init(CET_CHARSET_ASCII, 1); + cet_convert_strings(NULL, global_opts.charset, NULL); + waypt_disp_all(waypt_disp); + global_opts.verbose_status = saved_status; + } + + /* + * This is very unlike the rest of our command sequence. + * If we're doing realtime position tracking, we enforce that + * we're not doing anything else and we just bounce between + * the special "read position" and "write position" vectors + * in our most recent vecs. + */ + if (global_opts.masked_objective & POSNDATAMASK) { + + if (!ivecs->position_ops.rd_position) { + fatal("Realtime tracking (-T) is not suppored by this input type.\n"); + } + + + if (ivecs->position_ops.rd_init) { + ivecs->position_ops.rd_init(fname); + } + + if (global_opts.masked_objective & ~POSNDATAMASK) { + fatal("Realtime tracking (-T) is exclusive of other modes.\n"); + } + + if (ovecs) { + if ( !ovecs->position_ops.wr_position ) { + fatal ("This output format does not support output of realtime positioning.\n"); + } + } + + if (signal(SIGINT, signal_handler) == SIG_ERR) { + fatal ("Couldn't install the exit signal handler.\n"); + } + + if (ovecs && ovecs->position_ops.wr_init) { + ovecs->position_ops.wr_init(ofname); + } + + tracking_status.request_terminate = 0; + while (!tracking_status.request_terminate) { + waypoint *wpt; + + wpt = ivecs->position_ops.rd_position(&tracking_status); + + if (tracking_status.request_terminate) { + if (wpt) { + waypt_free(wpt); + } + break; + } + if (wpt) { + if (ovecs) { +// ovecs->position_ops.wr_init(ofname); + ovecs->position_ops.wr_position(wpt); +// ovecs->position_ops.wr_deinit(); + } else { + /* Just print to screen */ + waypt_disp(wpt); + } + waypt_free(wpt); + } + } + if (ivecs->position_ops.rd_deinit) { + ivecs->position_ops.rd_deinit(); + } + if (ovecs->position_ops.wr_deinit) { + ovecs->position_ops.wr_deinit(); + } + exit(0); + } + + + if (!did_something) + fatal ("Nothing to do! Use '%s -h' for command-line options.\n", prog_name); + + cet_deregister(); + waypt_flush_all(); + route_flush_all(); + exit_vecs(); + exit_filter_vecs(); + inifile_done(global_opts.inifile); + +#ifdef DEBUG_MEM + debug_mem_close(); +#endif + exit(0); +} + +void signal_handler(int sig) +{ + tracking_status.request_terminate = 1; +} + diff --git a/make-an1sym.pl b/make-an1sym.pl new file mode 100755 index 000000000..276699b2a --- /dev/null +++ b/make-an1sym.pl @@ -0,0 +1,361 @@ +#!/usr/bin/perl + +=pod + + This script reads the DeLorme Stock Symbols .dim file and writes code + to be included in the .an1 format handler. + + You MUST have a copy of the DeLorme .dim file; you can download it + from the support section of DeLorme's Web site. You want the one + that contains all of the symbols. + + To use this script: + + perl make-an1sym.pl an1sym.h + + Copyright (C) 2005 Ronald L. Parker (babelan1perl@parkrrrr.com) + and Robert Lipe + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +=cut + +# read a data structure from the input file. +sub shiftunpack { + my $pattern = shift; + my @result = unpack( $pattern, $file ); + my $str = pack( $pattern, @result ); + $file = substr( $file, length( $str )); + @result; +} + +sub skip_bytes { + my $count = shift; + $file = substr( $file, $count ); +} + +sub decodeGuid { + @guid = unpack( 'LSSSCCCCCC', shift ); + my $sub = undef; + my $guid2 = sprintf( '{0x%8.8x,{0x%4.4x, 0x%4.4x, 0x%4.4x},'. + ' {0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x}}', + @guid ); + $sub = $substitutions{ sprintf('%8.8x', @guid)}; + ($guid2, $sub); +} + +sub DoImage { + # image information - the 'type' we read was actually the low word of the hotspot X coord. + ($hotspotxhi, $hotspoty, $unk1, $guid, $name ) = + shiftunpack( 'slla[16]C/a*' ); + $hotspotx = $rec_type + 0x10000*$hotspotxhi; + + ($guid2,$sub) = decodeGuid( $guid ); + $name = $sub if ( $sub ); + print qq( {$guid2,\n "$name"},\n); +} + +%substitutions = ( + # everything up to and including "mud" is defined + "012dfac2", "Tractor", + "012dfac3", "Combine Harvester", + "012dfac7", "Front-End Loader", + "fd163780", "Power Shovel", + "fd163781", "Road Grader", + "fd163784", "Road Roller", + "fd163787", "Dump Truck", + "5673d712", "Skid-Steer Loader", # Bobcat is a registered trademark + "b86045ac", "Highway Sign", + "1e129e95", "Orange Cone", + "adee7d54", "Barricade", + "a170000f", "Flagger", + "a425f90e", "Construction Sign", + "0805b240", "Construction Flasher", + "56721a6c", "Transit", + # this group of 8 arrows is defined + "83f91421", "Small Arrow Left", + "83f91422", "Small Arrow Right", + "83f91423", "Small Arrow Up", + "83f91424", "Small Arrow Down", + "83f91425", "Small Arrow Up Left", + "83f91426", "Small Arrow Up Right", + "83f91427", "Small Arrow Down Left", + "83f91428", "Small Arrow Down Right", + "83f91429", "Large Arrow Left", + "83f9142a", "Large Arrow Right", + "83f9142b", "Large Arrow Up", + "83f9142c", "Large Arrow Down", + "83f9142d", "Large Arrow Down Right", + "83f9142e", "Large Arrow Down Left", + "83f9142f", "Large Arrow Up Left", + "83f91430", "Large Arrow Up Right", + "8ff0aad1", "Accommodation", + "af7bf199", "Australia", + "6bbcc9d1", "Blue Dome Cross", + "fff920fe", "Green Dome Cross", + "57e75924", "Business", + "b09ef4a7", "Airplane", + "f2833c22", "Amusement Recreation", # tent? on a green background + "6f0317d6", "Green Square", + "18a6d3c0", "Red Triangle", + "86e68ea7", "Red Triangle and Green Square", + "6afd74bf", "City 4", + "49dfeb74", "White Square", + "3eed62c6", "White Triangle", + "6b521940", "Red Black Diamond Flag", + "bb8ebaa3", "Yellow Diamond Flag", + "8e118862", "Small Pink Square", + "d0ef64c2", "Store", + "a22b08fb", "Camping", + "27f57c69", "Green Diamond Flag", + "e07abb38", "Red Diamond Flag", + "3a124ac9", "Red Green Diamond Flag", + "64ed669b", "White Globe", + "3cb10adc", "Yellow Globe", + "2779347d", "", #??? + "3ad63f7b", "Black Cross", + "3e89481e", "Church", + "68622c10", "Small Dark Green Square", + "42c6a873", "Small Black Square", + "50e3b06e", "Danger", + "369d0b22", "Construction Business", + "10603b6c", "Airport", + "8328aab7", "City 5", + "96411287", "USA", + "b2f98627", "Diver Down", + "3fce26d0", "Light Yellow Square", + "b4b68597", "Education Technology", + "35d2e6a8", "Computer", + "4ddc4e96", "Amusement Recreation Red", + "79f58929", "Telephone Red", + "0083b377", "Exit", + "0c232891", "Exit with Services", + "af63e7c2", "Pizza", + "d419c693", "Financial Services", + "70740a81", "City 3", + "9a582ff6", "Food Store", + "3cd31689", "", #??? + "952557a6", "", #??? white/black circle + "03dc278c", "Driving Range", + "acd28bab", "Golf Municipal", + "984e7139", "Golf Private", + "ec5828ab", "Golf Public", + "b0120d99", "Golf Resort", + "2ce7685a", "Golf Semi Private", + "10397049", "Medical Service", + "2fc28df6", "Home Furnishings", + "910313db", "Industrial", + "9e442c6e", "", #??? + "37e2fe4a", "", #??? + "3c756e09", "", #??? + "a1245b1c", "Manufacturing", + "5bddbd7a", "Note", + "cb6777e1", "City", + "bc168c08", "Air Base", + "a8857b0f", "Battlefield", + "06db55c1", "Mining", + "cc61b277", "Mountain", + "fde13186", "Capital", + "b14d90d1", "Route", + "7eabc63f", "Overnight", + "ac39d8b9", "Route End Active", + "e1b9d86b", "Route End Inactive", + "98712315", "Fuel Stop", + "e5ea5b38", "Route Start Active", + "18fd0d49", "Route Start Inactive", + "2f52144b", "Route Stop Active", + "faf8d826", "Route Stop Inactive", + "ff44cae2", "Route Via", + "5a50d59b", "Radiation Green", + "19556023", "Radiation Red", + "a54be251", "Electricity", + "d793ff0c", "Personal Furnishings", + "00f90733", "Personal Services", + "ea677f24", "Telephone Black", + "2d8a05b5", "Government Light", + "40c64dfc", "Airport Red Square", + "f27adb5d", "Propeller Aircraft", + "5a718e13", "Jet Aircraft", + "0a471039", "Government", + "4a59da2f", "USA Regional", + "f16500a9", "House 2", + "7b05524d", "Picnic", + "b88ad7a1", "Restaurant", + "dc48a20a", "Store 2", + "6b5ab040", "", # ??? + "153b2cff", "Blue Star", + "f276f6b3", "", # ??? + "91d242c8", "Running", + "8b0078db", "Transportation", + "0599f6c9", "Fishing 2", + "7389128c", "Automotive", + "0362b593", "Cloudy", + "f0717a94", "Partly Cloudy", + "14486bbc", "Mostly Cloudy", + "7a258c70", "Hurricane", + "eff260d4", "Lightning", + "c3d70220", "Rain", + # everything else is defined + # They defined two red flags. Ooops. + "f2dfbc95", "Red Flag 2" +); + +sub print_header { +print <<'END'; +/* + + + + + + + + + + THIS FILE IS AUTOMATICALLY GENERATED + + + Please change make-an1sym.pl and + regenerate it rather than changing + this file directly. + + + + + + + + + + + + + + + + + + + + + + + +*/ + +/* + Read DeLorme drawing files (.an1) - supplemental (included by an1.c) + + Copyright (C) 2005 Ron Parker and Robert Lipe. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +struct defguid { + GUID guid; + char *name; +} default_guids[] = { +END +} + +sub print_footer { +print <<'END'; +}; + +int FindIconByName( const char *name, GUID *guid ) { + int i = 0; + for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ ) + { + if ( !case_ignore_strcmp(name, default_guids[i].name)) { + memcpy( guid, &(default_guids[i].guid), sizeof(GUID)); + return 1; + } + } + return 0; +} + +int FindIconByGuid( GUID *guid, char **name ) { + int i = 0; + for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ ) + { + if ( !memcmp(guid, &default_guids[i].guid, sizeof(GUID))) { + *name = default_guids[i].name; + return 1; + } + } + return 0; +} +END +} + + +# read file +undef $/; +$file = <>; + +# read file header +($magic, $unk1 ) = shiftunpack( 'ss' ); + +# read bitmap info +($unk2) = shiftunpack( 'l' ); + +print_header; + +while ( length($file) ) { + ($rec_type) = shiftunpack( 's' ); + if ( $rec_type == 0x4c49 ) { # 'IL' + # I don't know what this structure is, but it appears twice in my test files. + ($unk10101, $unke, $unkc, $unk18_1, $unk18_2, $unkneg1_1, + $unk20, $unkneg1_2, $unkneg1_3) = shiftunpack( 'lsssslsll'); + } + elsif ( $rec_type == 0x4d42 ) { # 'BM' + # This is a standard BMP file, documented in MSDN. + # BITMAPFILEHEADER + ($fhsize, $res_0_1, $res_0_2, $bitoffset) = shiftunpack( 'lssl' ); + # BITMAPINFOHEADER + ($bmisize, $width, $height, $planes, $bpp, $compression, + $size, $xppm, $yppm, $colused, $colimprt ) = shiftunpack( 'lllssllllll'); + # palette + $palettesize = $bitoffset - $bmisize - 14; # 14 bytes in BMFH, including the 'BM' + skip_bytes( $palettesize ); + # image + skip_bytes( $size ); + } + elsif ($rec_type == 0 ) { # crap + ($a, $b, $c, $d, $e, $f) = shiftunpack( 'llllll' ); + if ( $c ) { + $file = pack( 'llllll', ($a, $b, $c, $d, $e, $f)) . $file; + DoImage; + } + } + else { + DoImage; + } +} + +print_footer; diff --git a/mapopolis.c b/mapopolis.c new file mode 100644 index 000000000..0e5001c0f --- /dev/null +++ b/mapopolis.c @@ -0,0 +1,298 @@ +/* + Read and write Mapopolis files. + + Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "pdbfile.h" + +#define MYNAME "Companion Waypoints" +#define MYTYPE 0x64617461 /* Platdata */ +#define MYCREATOR 0x5061746c /* Plat */ + +#define LONDIV (85116.044444) +#define LATDIV (1000000.0/9) +#define LONDIV2 (85116.044444/2) +#define LATDIV2 (1000000.0/(9*2)) + + +struct record0 +{ + char unk[6]; + pdb_32 lon1; + pdb_32 lat1; + pdb_32 lon2; + pdb_32 lat2; + pdb_32 lonD; + pdb_32 latD; + char name[31+1]; + char unk2[35]; + char demo; + char unk3[4]; + unsigned char expcode[4]; + /* ... more stuff ... */ +}; + +double Lat1, Lon1; +double Lat2, Lon2; +double LatD, LonD; + +struct record { + char unknown[10]; + pdb_16 unk1; + pdb_16 unk2; + pdb_16 lon1d; + pdb_16 lat1d; + pdb_16 lon2d; + pdb_16 lat2d; +}; + +static pdbfile *file_in, *file_out; +static short_handle mkshort_handle; + +static void +rd_init(const char *fname) +{ + file_in = pdb_open(fname, MYNAME); +} + +static void +rd_deinit(void) +{ + pdb_close(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = pdb_create(fname, MYNAME); + mkshort_handle = mkshort_new_handle(); + setshort_length(mkshort_handle, 20); +} + +static void +wr_deinit(void) +{ + pdb_close(file_out); + mkshort_del_handle(&mkshort_handle); +} + +convert_rec0(struct record0 *rec0) +{ + Lon1 = be_read32(&rec0->lon1) / LONDIV; + Lat1 = be_read32(&rec0->lat1) / LATDIV; + Lon2 = be_read32(&rec0->lon2) / LONDIV; + Lat2 = be_read32(&rec0->lat2) / LATDIV; + LonD = be_read32(&rec0->lonD) / LONDIV2; + LatD = be_read32(&rec0->latD) / LATDIV2; + +// printf("%s: %.5f %.5f %.5f %.5f %.5f %.5f\n", +// rec0->name, Lat1, Lon1, Lat2, Lon2, LatD, LonD); + + +} + +/* + * * Decode the information field + * */ +void +decode(char *buf) +{ + int i; + + for (i = 0; buf[i]; ++i) { + buf[i] = buf[i] ^ ((i % 96) & 0xf); + } +} + +static void +data_read(void) +{ + struct record *rec; + pdbrec_t *pdb_rec; + + if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { + fatal(MYNAME ": Not a Magellan Navigator file.\n"); + } + + pdb_rec = file_in->rec_list; + convert_rec0((struct record0*) pdb_rec->data); + +// for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) { + for(pdb_rec = pdb_rec->next; pdb_rec; pdb_rec=pdb_rec->next) { + waypoint *wpt_tmp; + char *vdata = 0; + char *edata; + struct tm tm = {0}; + + rec = (struct record *) pdb_rec->data; + edata = (char *) rec + pdb_rec->size; + + for (; vdata < edata; rec = (struct record *) vdata) { + wpt_tmp = waypt_new(); + wpt_tmp->latitude = Lat1 + + be_read16(&rec->lat1d) / LATDIV2; + wpt_tmp->longitude = Lon1 + + be_read16(&rec->lon1d) / LONDIV2; + + vdata = (char *) rec + sizeof(*rec); + wpt_tmp->description = xstrdup(vdata); + vdata += strlen(wpt_tmp->description) + 1 + 6; + + while (*vdata == 0x40) + vdata++; + decode(vdata); + wpt_tmp->notes = xstrdup(vdata); + vdata += strlen(wpt_tmp->notes) + 1; + + waypt_add(wpt_tmp); + } + } +} + + +static void +my_writewpt(const waypoint *wpt) +{ +#if 0 + struct record *rec; + static int ct; + struct tm *tm; + char *vdata; + time_t tm_t; + const char *sn = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, wpt->description) : + wpt->shortname; + + rec = xcalloc(sizeof(*rec)+56,1); + + tm = NULL; + if ( wpt->creation_time ) { + tm = gmtime( &wpt->creation_time); + } + if ( !tm ) { + tm_t = current_time(); + tm = gmtime( &tm_t ); + } + + be_write16( &rec->crt_sec, tm->tm_sec ); + be_write16( &rec->crt_min, tm->tm_min ); + be_write16( &rec->crt_hour, tm->tm_hour ); + be_write16( &rec->crt_mday, tm->tm_mday ); + be_write16( &rec->crt_mon, tm->tm_mon + 1 ); + be_write16( &rec->crt_year, tm->tm_mon + 1900 ); + + be_write16( &rec->unknown, 0); + + be_write16( &rec->xx_sec, tm->tm_sec ); + be_write16( &rec->xx_min, tm->tm_min ); + be_write16( &rec->xx_hour, tm->tm_hour ); + be_write16( &rec->xx_mday, tm->tm_mday ); + be_write16( &rec->xx_mon, tm->tm_mon + 1 ); + be_write16( &rec->xx_year, tm->tm_mon + 1900 ); + + be_write16( &rec->unknown2, 0); + + be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0)); + be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0)); + be_write32(&rec->elevation, wpt->altitude); + + rec->plot = 0; + rec->unknown3 = 'a'; + + vdata = (char *)rec + sizeof(*rec); + if ( sn ) { + strncpy( vdata, sn, 21 ); + vdata[20] = '\0'; + } + else { + vdata[0] ='\0'; + } + vdata += strlen( vdata ) + 1; + if ( wpt->description ) { + strncpy( vdata, wpt->description, 33 ); + vdata[32] = '\0'; + } + else { + vdata[0] = '\0'; + } + vdata += strlen( vdata ) + 1; + vdata[0] = '\0'; + vdata[1] = '\0'; + vdata += 2; + + pdb_write(file_out, 0, rec, (char *)vdata - (char *)rec); + + xfree(rec); +#endif +} + +static void +data_write(void) +{ + static char *appinfo = + "\0\x01" + "User\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\0\0"; + + strncpy(file_out->name, "Companion Waypoints", PDB_DBNAMELEN); + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + file_out->appinfo = (void *)appinfo; + file_out->appinfo_len = 276; + + waypt_disp_all(my_writewpt); +} + + +ff_vecs_t mapopolis_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; +#endif diff --git a/mapsend.c b/mapsend.c new file mode 100644 index 000000000..ab91003a6 --- /dev/null +++ b/mapsend.c @@ -0,0 +1,552 @@ +/* + Access Magellan Mapsend files. + + Copyright (C) 2002-2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include +#include + +#include "defs.h" +#include "mapsend.h" +#include "magellan.h" + +static gbfile *mapsend_file_in; +static gbfile *mapsend_file_out; +static short_handle mkshort_handle; +static short_handle wpt_handle; + +static int route_wp_count; +static int mapsend_infile_version; +static int trk_version = 30; + +#define MYNAME "mapsend" + +static char *mapsend_opt_trkver = NULL; +#define MAPSEND_TRKVER_MIN 3 +#define MAPSEND_TRKVER_MAX 4 + +static +arglist_t mapsend_args[] = { + {"trkver", &mapsend_opt_trkver, + "MapSend version TRK file to generate (3,4)", + "4", ARGTYPE_INT, "3", "4" }, + ARG_TERMINATOR +}; + +static void +mapsend_init_opts(const char isReading) { /* 1=read, 2=write */ + int opt_trkver; + + /* read & write options here */ + + if (isReading) { + /* reading-only options here */ + } else { + /* writing-only options here */ + + // TRK MapSend version + opt_trkver = atoi(mapsend_opt_trkver); + if ((opt_trkver < MAPSEND_TRKVER_MIN) || (opt_trkver > MAPSEND_TRKVER_MAX)) + fatal(MYNAME ": Unsupported MapSend TRK version \"%s\"!\n", mapsend_opt_trkver); + trk_version = opt_trkver * 10; + } +} + +static void +mapsend_rd_init(const char *fname) +{ + mapsend_init_opts(1); + mapsend_file_in = gbfopen_le(fname, "rb", MYNAME); +} + +static void +mapsend_rd_deinit(void) +{ + gbfclose(mapsend_file_in); +} + +static void +mapsend_wr_init(const char *fname) +{ + mapsend_init_opts(0); + mapsend_file_out = gbfopen(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); + + wpt_handle = mkshort_new_handle(); + setshort_whitespace_ok(wpt_handle, 1); + setshort_length(wpt_handle, 8); + + route_wp_count = 0; +} + +static void +mapsend_wr_deinit(void) +{ + gbfclose(mapsend_file_out); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&wpt_handle); +} + +static void +mapsend_wpt_read(void) +{ + char tbuf[256]; + int wpt_count, rte_count, rte_num; + int wpt_number; + char wpt_icon; + char wpt_status; + waypoint *wpt_tmp; + route_head *rte_head; + + wpt_count = gbfgetint32(mapsend_file_in); + + while (wpt_count--) { + wpt_tmp = waypt_new(); + + wpt_tmp->shortname = gbfgetpstr(mapsend_file_in); + wpt_tmp->description = gbfgetpstr(mapsend_file_in); + + wpt_number = gbfgetint32(mapsend_file_in); + wpt_icon = gbfgetc(mapsend_file_in); + wpt_status = gbfgetc(mapsend_file_in); + + wpt_tmp->altitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); + + if (wpt_icon < 26) + sprintf(tbuf, "%c", wpt_icon + 'a'); + else + sprintf(tbuf, "a%c", wpt_icon - 26 + 'a'); + wpt_tmp->icon_descr = mag_find_descr_from_token(tbuf); + + waypt_add(wpt_tmp); + } + + /* now read the routes... */ + rte_count = gbfgetint32(mapsend_file_in); + + while (rte_count--) { + rte_head = route_head_alloc(); + route_add_head(rte_head); + + /* route name */ + rte_head->rte_name = gbfgetpstr(mapsend_file_in); + + /* route # */ + rte_num = gbfgetint32(mapsend_file_in); + rte_head->rte_num = rte_num; + + /* points this route */ + wpt_count = gbfgetint32(mapsend_file_in); + + while (wpt_count--) { + wpt_tmp = waypt_new(); + + /* waypoint name */ + wpt_tmp->shortname = gbfgetpstr(mapsend_file_in); + + /* waypoint # */ + wpt_number = gbfgetint32(mapsend_file_in); + wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); + + gbfread(&wpt_icon, 1, sizeof(wpt_icon), mapsend_file_in); + + if (wpt_icon < 26) + sprintf(tbuf, "%c", wpt_icon + 'a'); + else + sprintf(tbuf, "a%c", wpt_icon - 26 + 'a'); + wpt_tmp->icon_descr = mag_find_descr_from_token(tbuf); + + route_add_wpt(rte_head, wpt_tmp); + } + } +} + +static void +mapsend_track_read(void) +{ + unsigned int trk_count; + int valid; + unsigned char centisecs; + route_head *track_head; + waypoint *wpt_tmp; + + track_head = route_head_alloc(); + track_head->rte_name = gbfgetpstr(mapsend_file_in); + track_add_head(track_head); + + trk_count = gbfgetuint32(mapsend_file_in); + + while (trk_count--) { + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); + + if (mapsend_infile_version < 36) { /* < version 4.0 */ + wpt_tmp->altitude = gbfgetint32(mapsend_file_in); + } else { + wpt_tmp->altitude = gbfgetflt(mapsend_file_in); + } + if (wpt_tmp->altitude < unknown_alt + 1) + wpt_tmp->altitude = unknown_alt; + wpt_tmp->creation_time = gbfgetint32(mapsend_file_in); + valid = gbfgetint32(mapsend_file_in); + + /* centiseconds only in >= version 3.0 */ + if (mapsend_infile_version >= 34) { + gbfread(¢isecs, 1, 1, mapsend_file_in); + } else { + centisecs = 0; + } + wpt_tmp->microseconds = CENTI_TO_MICRO(centisecs); + + track_add_wpt(track_head, wpt_tmp); + } +} + +static void +mapsend_read(void) +{ + mapsend_hdr hdr; + int type, len; + char buf[3]; + + /* + * Because of the silly struct packing and the goofy variable-length + * strings, each member has to be read in one at a time. Grrr. + */ + + len = gbfread(&hdr, 1, sizeof(hdr), mapsend_file_in); + is_fatal(len < sizeof(hdr), MYNAME ": No mapsend or empty file!"); + + type = le_read16(&hdr.ms_type); + strncpy(buf, hdr.ms_version, 2); + buf[2] = '\0'; + + mapsend_infile_version = atoi(buf); + + switch(type) { + case ms_type_wpt: + mapsend_wpt_read(); + break; + case ms_type_track: + mapsend_track_read(); + break; + case ms_type_log: + fatal(MYNAME ", GPS logs not supported.\n"); + case ms_type_rgn: + fatal(MYNAME ", GPS regions not supported.\n"); + default: + fatal(MYNAME ", unknown file type %d\n", type); + } +} + + +static void +mapsend_waypt_pr(const waypoint *waypointp) +{ + unsigned char c; + double falt; + static int cnt = 0; + const char *iconp = NULL; + const char *sn = global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, waypointp) : + waypointp->shortname; + char *tmp; + + /* + * The format spec doesn't call out the character set of waypoint + * name and description. Empirically, we can see that it's 8859-1, + * but if we create mapsend files containing those, Mapsend becomes + * grumpy uploading the resulting waypoints and being unable to deal + * with the resulting comm errors. + * + * Ironically, our own Magellan serial module strips the "naughty" + * characters, keeping it more in definition with their own serial + * spec. :-) + * + * So we just decompose the utf8 strings to ascii before stuffing + * them into the Mapsend file. + */ + + + tmp = mkshort(wpt_handle, sn); + gbfputpstr(tmp, mapsend_file_out); + if (tmp) xfree(tmp); + + tmp = waypointp->description; + if (tmp) + c = strlen(tmp); + else + c = 0; + + if (c > 30) c = 30; + gbfputc(c, mapsend_file_out); + gbfwrite(tmp, c, 1, mapsend_file_out); + + /* #, icon, status */ + gbfputint32(++cnt, mapsend_file_out); + + if (waypointp->icon_descr) { + iconp = mag_find_token_from_descr(waypointp->icon_descr); + if (1 == strlen(iconp)) { + c = iconp[0] - 'a'; + } else { + c = iconp[1] - 'a' + 26; + } + } else { + c = 0; + } + if (get_cache_icon(waypointp)) { + iconp = mag_find_token_from_descr(get_cache_icon(waypointp)); + if (1 == strlen(iconp)) { + c = iconp[0] - 'a'; + } else { + c = iconp[1] - 'a' + 26; + } + } + + gbfwrite(&c, 1, 1, mapsend_file_out); + gbfputc(1, mapsend_file_out); + + falt = waypointp->altitude; + if (falt == unknown_alt) + falt = 0; + gbfputdbl(falt, mapsend_file_out); + + gbfputdbl(waypointp->longitude, mapsend_file_out); + gbfputdbl(-waypointp->latitude, mapsend_file_out); +} + +static void +mapsend_route_hdr(const route_head *rte) +{ + char * rname; + + /* route name -- mapsend really seems to want something here.. */ + if (!rte->rte_name) + rname = xstrdup("Route"); + else + rname = xstrdup(rte->rte_name); + gbfputpstr(rname, mapsend_file_out); + + xfree(rname); + + /* route # */ + gbfputint32(rte->rte_num, mapsend_file_out); + + /* # of waypoints to follow... */ + gbfputint32(rte->rte_waypt_ct, mapsend_file_out); +} + +static void +mapsend_noop(const route_head *wp) +{ + /* no-op */ +} + +static void +mapsend_route_disp(const waypoint *waypointp) +{ + unsigned char c; + const char *iconp; + + route_wp_count++; + + /* waypoint name */ + c = waypointp->shortname ? strlen(waypointp->shortname) : 0; + gbfwrite(&c, 1, 1, mapsend_file_out); + gbfwrite(waypointp->shortname, c, 1, mapsend_file_out); + + /* waypoint number */ + gbfputint32(route_wp_count, mapsend_file_out); + + gbfputdbl(waypointp->longitude, mapsend_file_out); + gbfputdbl(-waypointp->latitude, mapsend_file_out); + + if (waypointp->icon_descr) { + iconp = mag_find_token_from_descr(waypointp->icon_descr); + if (1 == strlen(iconp)) { + c = iconp[0] - 'a'; + } else { + c = iconp[1] - 'a' + 26; + } + } else { + c = 0; + } + gbfwrite(&c, 1, 1, mapsend_file_out); +} + +void mapsend_track_hdr(const route_head * trk) +{ + /* + * we write mapsend v3.0 tracks as mapsend v2.0 tracks get + * tremendously out of whack time/date wise. + */ + char *verstring = "30"; + queue *elem, *tmp; + char *tname; + int i; + mapsend_hdr hdr = {13, "4D533334 MS", "30", ms_type_track, {0, 0, 0}}; + + switch (trk_version) { + case 20: verstring = "30"; break; + case 30: verstring = "34"; break; + case 40: + /* the signature seems to change with the versions, even though it + * shouldn't have according to the document. MapSend V4 doesn't + * like the old version. + */ + hdr.ms_signature[7] = '6'; + verstring = "36"; + break; + default: fatal("Unknown track version.\n"); break; + } + + hdr.ms_version[0] = verstring[0]; + hdr.ms_version[1] = verstring[1]; + + gbfwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); + + /* track name */ + if (!trk->rte_name) + tname = xstrdup("Track"); + else + tname = xstrdup(trk->rte_name); + gbfputpstr(tname, mapsend_file_out); + + xfree(tname); + + /* total nodes (waypoints) this track */ + i = 0; + QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { + i++; + } + + gbfputint32(i, mapsend_file_out); + +} + +void mapsend_track_disp(const waypoint * wpt) +{ + unsigned char c; + int t; + static int last_time; + + /* + * Firmware Ver 4.06 (at least) has a defect when it's set for .01km + * tracking that will sometimes result in timestamps in the track + * going BACKWARDS. When mapsend sees this, it (stupidly) advances + * the date by one, ignoring the date on the TRK lines. This looks + * for time travel and just uses the previous time - it's better to + * be thought to be standing still than to be time-travelling! + * + * This is rumoured (but yet unconfirmed) to be fixed in f/w 5.12. + */ + t = wpt->creation_time; + if (t < last_time) { + t = last_time; + } + + /* x = longitude */ + gbfputdbl(wpt->longitude, mapsend_file_out); + + /* x = latitude */ + gbfputdbl(-wpt->latitude, mapsend_file_out); + + /* altitude + * in V4.0+ this field is a float, it was previously an int + */ + if (trk_version < 40) { + gbfputint32((int) wpt->altitude, mapsend_file_out); + } else { + gbfputflt((float) wpt->altitude, mapsend_file_out); + } + + /* time */ + gbfputint32(t, mapsend_file_out); + last_time = t; + + /* validity */ + gbfputint32(1, mapsend_file_out); + + /* 0 centiseconds */ + if (trk_version >= 30) { + c = MICRO_TO_CENTI(wpt->microseconds); + gbfwrite(&c, 1, 1, mapsend_file_out); + } +} + +void +mapsend_track_write(void) +{ + track_disp_all(mapsend_track_hdr, mapsend_noop, mapsend_track_disp); +} + +static void +mapsend_wpt_write(void) +{ + mapsend_hdr hdr = {13, {"4D533330 MS"}, {"30"}, ms_type_wpt, {0, 0, 0}}; + int n = 0; + int wpt_count = waypt_count(); + + if (global_opts.objective == trkdata) { + mapsend_track_write(); + } else { + gbfwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); + + if (global_opts.objective == wptdata) { + gbfputint32(wpt_count, mapsend_file_out); + waypt_disp_all(mapsend_waypt_pr); + } else + if (global_opts.objective == rtedata) { + + /* # of points - all routes */ + gbfputint32(route_waypt_count(), mapsend_file_out); + + /* write points - all routes */ + route_disp_all(mapsend_noop, mapsend_noop, mapsend_waypt_pr); + } + + n = route_count(); + + gbfputint32(n, mapsend_file_out); + + if (n) + route_disp_all(mapsend_route_hdr, mapsend_noop, mapsend_route_disp); + } +} + + + +ff_vecs_t mapsend_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + mapsend_rd_init, + mapsend_wr_init, + mapsend_rd_deinit, + mapsend_wr_deinit, + mapsend_read, + mapsend_wpt_write, + NULL, + mapsend_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/mapsend.h b/mapsend.h new file mode 100644 index 000000000..2d1ef9448 --- /dev/null +++ b/mapsend.h @@ -0,0 +1,44 @@ +/* + Access to MapSend files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + * + * Information from: + * Mapsend File Format Description Revision 1.1, March 6, 2002 from Thales. + * + * Note this file format was clearly NOT designed for cross-architecture + * portability. In fact, because of the pascal nature of the 'string' + * data type described in that document, it's impractical to describe + * a 'struct waypoint' in C. + * + */ + +typedef struct { + char ms_length; + char ms_signature[11]; + char ms_version[2]; + char ms_type; + char _ms_type[3]; +} mapsend_hdr; + +typedef enum { + ms_type_rgn = 0, + ms_type_wpt = 1, + ms_type_track = 2, + ms_type_log = 3 +} ms_type; diff --git a/mapsource.c b/mapsource.c new file mode 100644 index 000000000..182456a92 --- /dev/null +++ b/mapsource.c @@ -0,0 +1,2020 @@ +/* + Access to Garmin MapSource files. + Based on information provided by Ian Cowley & Mark Bradley + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +/* #define MPS_DEBUG 0 */ + +#include +#include + +#include "defs.h" +#include "garmin_tables.h" +#include "jeeps/gpsmath.h" +#include + +static gbfile *mps_file_in; +static gbfile *mps_file_out; +static gbfile *mps_file_temp; +static short_handle mkshort_handle; + +static int mps_ver_in = 0; +static int mps_ver_out = 0; +static int mps_ver_temp = 0; + +/* Temporary pathname used when merging gpsbabel output with an existing file */ +static char *tempname; +static char *fin_name; + +static const waypoint *prevRouteWpt; +/* Private queues of written out waypoints */ +static queue written_wpt_head; +static queue written_route_wpt_head; +static short_handle written_wpt_mkshort_handle; + +/* Private queue of read in waypoints assumed to be used only for routes */ +static queue read_route_wpt_head; +static short_handle read_route_wpt_mkshort_handle; + +#define MPSDEFAULTWPTCLASS 0 +#define MPSHIDDENROUTEWPTCLASS 8 + +#define MYNAME "MAPSOURCE" +#define ISME 0 +#define NOTME 1 + +#define DEFAULTICONDESCR "Waypoint" +#define DEFAULTICONVALUE 18 + +#define MPSNAMEBUFFERLEN 1024 +#define MPSNOTESBUFFERLEN 4096 +#define MPSDESCBUFFERLEN 4096 + + +char *snlen = NULL; +char *snwhiteopt = NULL; +char *mpsverout = NULL; +char *mpsmergeouts = NULL; +int mpsmergeout; +char *mpsusedepth = NULL; +char *mpsuseprox = NULL; + +static +arglist_t mps_args[] = { + {"snlen", &snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, + { "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"mpsverout", &mpsverout, + "Version of mapsource file to generate (3,4,5)", NULL, + ARGTYPE_INT, ARG_NOMINMAX }, + {"mpsmergeout", &mpsmergeouts, "Merge output with existing file", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"mpsusedepth", &mpsusedepth, + "Use depth values on output (default is ignore)", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX }, + {"mpsuseprox", &mpsuseprox, + "Use proximity values on output (default is ignore)", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static void +mps_noop(const route_head *wp) +{ + /* no-op */ +} + +void +mps_wpt_q_init(queue *whichQueue) +{ + QUEUE_INIT(whichQueue); +} + +void +mps_wpt_q_deinit(queue *whichQueue) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(whichQueue, elem, tmp) { + waypoint *q = (waypoint *) dequeue(elem); + waypt_free(q); + } +} + +/* + * Find a waypoint that we've already written out + * + */ +waypoint * +mps_find_wpt_q_by_name(const queue *whichQueue, const char *name) +{ + queue *elem, *tmp; + waypoint *waypointp; + + QUEUE_FOR_EACH(whichQueue, elem, tmp) { + waypointp = (waypoint *) elem; + if (0 == strcmp(waypointp->shortname, name)) { + return waypointp; + } + } + return NULL; +} + +/* + * Add a waypoint that we've already written out to our list + * + */ +void +mps_wpt_q_add(const queue *whichQueue, const waypoint *wpt) +{ + waypoint *written_wpt = waypt_dupe(wpt); + ENQUEUE_TAIL(whichQueue, &written_wpt->Q); +} + +static int +mps_converted_icon_number(const int icon_num, const int mpsver, garmin_formats_e garmin_format) +{ + int def_icon = DEFAULTICONVALUE; + + switch (garmin_format) { + case MAPSOURCE: + if (mpsver == 5) return icon_num; + if (mpsver == 4) { + /* Water hydrant */ + if (icon_num == 139) return def_icon; + else return icon_num; + } + else { + /* the Contact icons - V3 doesn't have anything like this */ + if ((icon_num >= 119) && (icon_num <= 138)) return def_icon; + /* the Geocache icons - V3 use the Circle with X */ + if ((icon_num >= 117) && (icon_num <= 118)) return 65; + /* Water hydrant */ + if (icon_num == 139) return def_icon; + return icon_num; + } + + case PCX: + case GARMIN_SERIAL: + if (mpsver == 5) return icon_num; + if (mpsver == 4) { + /* Water hydrant */ + if (icon_num == 8282) return def_icon; + else return icon_num; + } + /* the Contact icons - V3 doesn't have anything like this */ + if ((icon_num >= 8257) && (icon_num <= 8276)) return def_icon; + /* the Geocache icons - V3 use the Circle with X */ + if ((icon_num >= 8255) && (icon_num <= 8256)) return 179; + /* Water hydrant */ + if (icon_num == 8282) return def_icon; + return icon_num; + + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + return def_icon; +} + +static void +mps_rd_init(const char *fname) +{ + mps_file_in = gbfopen_le(fname, "rb", MYNAME); + + read_route_wpt_mkshort_handle = mkshort_new_handle(); + /* initialise the "private" queue of waypoints read for routes */ + mps_wpt_q_init(&read_route_wpt_head); +} + +static void +mps_rd_deinit(void) +{ + gbfclose(mps_file_in); + if ( read_route_wpt_mkshort_handle ) { + mkshort_del_handle( &read_route_wpt_mkshort_handle ); + } + /* flush the "private" queue of waypoints read for routes */ + mps_wpt_q_deinit(&read_route_wpt_head); +} + +static void +mps_wr_init(const char *fname) +{ + fin_name = xstrdup(fname); + if (mpsmergeouts) { + mpsmergeout = atoi(mpsmergeouts); + } + + if (mpsmergeout) { + mps_file_out = gbfopen_le(fname, "rb", MYNAME); + if (mps_file_out == NULL) { + mpsmergeout = 0; + } + else { + gbfclose(mps_file_out); + srand((unsigned) current_time()); + + for (;;) { + /* create a temporary name based on a random char and the existing name */ + /* then test if it already exists, if so try again with another rand num */ + /* yeah, yeah, so there's probably a library function for this */ + xasprintf(&tempname, "%s.%08x", fname, rand()); + mps_file_temp = gbfopen_le(tempname, "rb", MYNAME); + if (mps_file_temp == NULL) break; + gbfclose(mps_file_temp); + } + rename(fname, tempname); + mps_file_temp = gbfopen_le(tempname, "rb", MYNAME); + } + } + + mps_file_out = gbfopen_le(fname, "wb", MYNAME); + + written_wpt_mkshort_handle = mkshort_new_handle(); + /* initialise the "private" queue of waypoints written */ + mps_wpt_q_init(&written_wpt_head); + mps_wpt_q_init(&written_route_wpt_head); +} + +static void +mps_wr_deinit(void) +{ + gbfclose(mps_file_out); + + if (mpsmergeout) { + gbfclose(mps_file_temp); + remove(tempname); + xfree(tempname); + } + + if ( written_wpt_mkshort_handle ) { + mkshort_del_handle( &written_wpt_mkshort_handle ); + } + /* flush the "private" queue of waypoints written */ + mps_wpt_q_deinit(&written_wpt_head); + mps_wpt_q_deinit(&written_route_wpt_head); + xfree(fin_name); +} + +/* + * get characters until and including terminating NULL from mps_file_in + * and write into buf. + */ +static void +mps_readstr(gbfile *mps_file, char *buf, size_t sz) +{ + int c; + while (sz-- && (c = gbfgetc (mps_file)) != EOF) { + *buf++ = c; + if (c == 0) { + return; + } + } +} + +/* + * read in from file to check a) valid format b) version of data formating + * MRCB + */ +static void +mps_fileHeader_r(gbfile *mps_file, int *mps_ver) +{ + char hdr[100]; + int reclen; + + mps_readstr(mps_file, hdr, sizeof(hdr)); + if ( strcmp( hdr, "MsRcd" )) { + fatal(MYNAME ": This doesn't look like a mapsource file.\n"); + } + /* Read record length of "format details" section */ + reclen = gbfgetint32(mps_file); + /* Read the "format details" in plus the trailing null */ + gbfread( hdr, 3, 1, mps_file); + if (hdr[0] != 'D') { + /* No flag for the "data" section */ + fatal(MYNAME ": This doesn't look like a mapsource file.\n"); + } + if (hdr[1] == 'd') { + *mps_ver = 3; + } + else if ((hdr[1] > 'd') && (hdr[1] <= 'h')) { + *mps_ver = 4; + } + else if ((hdr[1] > 'h') && (hdr[1] <= 'i')) { + *mps_ver = 5; + } + else { + fatal(MYNAME ": Unsuppported version of mapsource file.\n"); + } + /* Skip reliably over the "format details" section */ + gbfseek( mps_file, reclen+1-3, SEEK_CUR); + /* Read record length of "program signature" section */ + reclen = gbfgetint32(mps_file); + /* Skip reliably over the "program signature" section */ + if (reclen >= 0) gbfseek(mps_file, reclen+1, SEEK_CUR); +} + +/* + * write out to file + * MRCB + */ +static void +mps_fileHeader_w(gbfile *mps_file, int mps_ver) +{ + char hdr[100]; + int reclen; + + strcpy (hdr, "MsRc"); + gbfwrite(hdr, 4, 1, mps_file); + + /* Between versions 3 & 5 this value is 'd', but might change in the future */ + strcpy(hdr, "d"); + gbfwrite(hdr, 2, 1, mps_file); /* include trailing NULL char */ + + /* Start of a "Data" section */ + hdr[0] = 'D'; + /* if (mps_ver == 3) */ + hdr[1] = 'd'; /* equates to V3.02 */ + if (mps_ver == 4) hdr[1] = 'g'; /* equates to V4.06 */ + if (mps_ver == 5) hdr[1] = 'i'; /* equates to V5.0 */ + hdr[2] = 0; + + reclen = 2; /* this is 3 byte record */ + gbfputint32(reclen, mps_file); + gbfwrite(hdr, 3, 1, mps_file); /* reclen + 1 */ + + hdr[0] = 'A'; + /* if (mps_ver == 3) */ + hdr[1] = 0x2E; hdr[2] = 0x01; /* equates to V3.02 */ + hdr[3] = 'S'; + hdr[4] = 'Q'; + hdr[5] = 'A'; + hdr[6] = 0; + strcpy(hdr+7,"Oct 20 1999"); + strcpy(hdr+19,"12:50:33"); + if (mps_ver == 4) { + hdr[1] = (char) 0x96; /* equates to V4.06 */ + strcpy(hdr+7,"Oct 22 2001"); + strcpy(hdr+19,"15:45:33"); + } + if (mps_ver == 5) { + hdr[1] = (char) 0xF4; /* equates to V5.0 */ + strcpy(hdr+7,"Jul 3 2003"); + strcpy(hdr+19,"08:35:33"); + } + + reclen = 27; /* pre measured! */ + gbfputint32(reclen, mps_file); + gbfwrite(hdr, 28, 1, mps_file); /* reclen + 1 - can't use this as reclen may be wrongendian now */ +} + +/* + * read in from file a map segment record + * MRCB + */ +static void +mps_mapsegment_r(gbfile *mps_file, int mps_ver) +{ + int reclen; + +#if 0 + /* At the moment we're not doing anything with map segments, but here's the template code as if we were */ + char hdr[100]; + gbfread(&CDid, 4, 1, mps_file); + reclen = le_read32(&CDid); + + gbfread(&CDSegmentid, 4, 1, mps_file); + reclen = le_read32(&CDSegmentid); + + mps_readstr(mps_file, CDName, sizeof(CDName)); + mps_readstr(mps_file, CDSegmentName, sizeof(CDSegmentName)); + mps_readstr(mps_file, CDAreaName, sizeof(CDAreaName)); + + gbfread(hdr, 4, 1, mps_file); /* trailing long value */ +#endif + + gbfseek(mps_file, -5, SEEK_CUR); + reclen = gbfgetint32(mps_file); + if (reclen >= 0) gbfseek( mps_file, reclen+1, SEEK_CUR); + return; +} + + +/* + * read in from file a mapsetname record + * there should always be one of these at the end of the file + * MRCB + */ +static void +mps_mapsetname_r(gbfile *mps_file, int mps_ver) +{ + int reclen; + + /* At the moment we're not doing anything with mapsetnames, but here's the template code as if we were + char hdr[100]; + mps_readstr(mps_file, hdr, sizeof(hdr)); + char mapsetnamename[very large number?]; + strcpy(mapsetnamename,hdr); + char mapsetnameAutonameFlag; + gbfread(&mapsetnameAutonameFlag, 1, 1, mps_file); */ + + gbfseek(mps_file, -5, SEEK_CUR); + reclen = gbfgetint32(mps_file); + gbfseek( mps_file, reclen+1, SEEK_CUR); + return; +} + + +/* + * write out to file a mapsetname record + * there should always be one of these at the end of the file + * MRCB + */ +static void +mps_mapsetname_w(gbfile *mps_file, int mps_ver) +{ + char hdr[100]; + int reclen; + + hdr[0] = 'V'; /* mapsetname start of record indicator */ + hdr[1] = 0; /* zero length null terminated string */ + hdr[2] = 1; /* mapsetname autoname flag set to DO autoname */ + reclen = 2; /* three bytes of the V record */ + gbfputint32(reclen, mps_file); + gbfwrite(hdr, 3, 1, mps_file); /* reclen + 1 */ +} + + +/* + * read in from file a waypoint record + * MRCB + */ +static void +mps_waypoint_r(gbfile *mps_file, int mps_ver, waypoint **wpt, unsigned int *mpsclass) +{ + char tbuf[100]; + char wptname[MPSNAMEBUFFERLEN]; + char *wptdesc = NULL; + char *wptnotes = NULL; + int lat; + int lon; + int icon; + int dynamic; + + waypoint *thisWaypoint = NULL; + double mps_altitude = unknown_alt; + double mps_proximity = unknown_alt; + double mps_depth = unknown_alt; + + thisWaypoint = waypt_new(); + *wpt = thisWaypoint; + + mps_readstr(mps_file, wptname, sizeof(wptname)); + + (*mpsclass) = gbfgetint32(mps_file); /* class */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ + + gbfread(tbuf,17, 1, mps_file); /* subclass data (17) */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 5, 1, mps_file); /* additional subclass data (1) & terminator? (4) */ + } + + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } + else { + mps_altitude = unknown_alt; + gbfseek( mps_file, 8, SEEK_CUR ); + } + + wptdesc = gbfgetcstr(mps_file); + + if (gbfgetc(mps_file) == 1) { /* proximity validity */ + mps_proximity = gbfgetdbl(mps_file); + } + else { + mps_proximity = unknown_alt; + gbfseek( mps_file, 8, SEEK_CUR ); + } + + (void) gbfgetint32(mps_file); /* display flag */ + (void) gbfgetint32(mps_file); /* colour */ + icon = gbfgetint32(mps_file); /* display symbol */ + + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* city */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* state */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /*facility */ + + gbfread(tbuf, 1, 1, mps_file); /* unknown */ + + if (gbfgetc(mps_file) == 1) { /* depth validity */ + mps_depth = gbfgetdbl( mps_file ); + } + else { + mps_depth = unknown_alt; + (void) gbfseek( mps_file, 8, SEEK_CUR ); + } + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 6, 1, mps_file); /* unknown */ + wptnotes = gbfgetcstr(mps_file); + } + else { + gbfread(tbuf, 2, 1, mps_file); /* unknown */ + } + + thisWaypoint->shortname = xstrdup(wptname); + thisWaypoint->description = wptdesc; + thisWaypoint->notes = wptnotes; + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->altitude = mps_altitude; + if (mps_proximity != unknown_alt) WAYPT_SET(thisWaypoint, proximity, mps_proximity); + if (mps_depth != unknown_alt) WAYPT_SET(thisWaypoint, depth, mps_depth); + + /* might need to change this to handle version dependent icon handling */ + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(icon, MAPSOURCE, &dynamic); + thisWaypoint->wpt_flags.icon_descr_is_dynamic = dynamic; + + /* The following Now done elsewhere since it can be useful to read in and + perhaps not add to the list */ + /* waypt_add(thisWaypoint); */ + + return; +} + +/* + * write out to file a waypoint record + * MRCB + */ +static void +mps_waypoint_w(gbfile *mps_file, int mps_ver, const waypoint *wpt, const int isRouteWpt) +{ + int reclen; + int lat, lon; + int icon; + char *src = ""; /* default to empty string */ + char *ident; + char *ascii_description; + char zbuf[25]; + char ffbuf[25]; + int display = 1; + int colour = 0; /* (unknown colour) black is 1, white is 16 */ + + double mps_altitude = wpt->altitude; + double mps_proximity = (mpsuseprox ? WAYPT_GET(wpt, proximity, unknown_alt) : unknown_alt); + double mps_depth = unknown_alt; + + lat = GPS_Math_Deg_To_Semi(wpt->latitude); + lon = GPS_Math_Deg_To_Semi(wpt->longitude); + if (WAYPT_HAS(wpt, depth) && mpsusedepth) mps_depth = wpt->depth; + + if(wpt->description) src = wpt->description; + if(wpt->notes) src = wpt->notes; + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + wpt->shortname; + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xff, sizeof(ffbuf)); + + /* might need to change this to handle version dependent icon handling */ + icon = gt_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); + + if (get_cache_icon(wpt) /* && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)*/) { + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), MAPSOURCE); + } + + icon = mps_converted_icon_number(icon, mps_ver, MAPSOURCE); + + /* two NULL (0x0) bytes at end of each string */ + ascii_description = wpt->description ? xstrdup(wpt->description) : xstrdup(""); + reclen = strlen(ident) + strlen(ascii_description) + 2; + if ((mps_ver == 4) || (mps_ver == 5)) { + /* v4.06 & V5.0*/ + reclen += 85; /* "W" (1) + strlen(name) + NULL (1) + class(4) + country(sz) + + subclass(18) + unknown(4) + lat(4) + lon(4) + alt(9) + strlen(desc) + + NULL (1) + prox(9) + display(4) + colour(4) + symbol(4) + city(sz) + + state(sz) + facility(sz) + unknown2(1) + depth(9) + unknown3(7) */ + /* -1 as reclen is interpreted from zero meaning a reclength of one */ + if (wpt->notes) reclen += strlen(wpt->notes); + } + else { + /* v3.02 */ + reclen += 75; /* "W" (1) + strlen(name) + NULL (1) + + class(4) + country(sz) + + subclass(17) + lat(4) + lon(4) + alt(9) + strlen(desc) + + NULL (1) + prox(9) + display(4) + + colour(4) + symbol(4) + city(sz) + state(sz) + facility(sz) + + unknown2(1) + depth(9) + unknown3(2) */ + /* -1 as reclen is interpreted from zero meaning a reclength of one */ + } + + gbfputint32(reclen, mps_file); + gbfwrite("W", 1, 1, mps_file); + gbfputs(ident, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination to ident */ + + if (isRouteWpt) zbuf[0] = (char)MPSHIDDENROUTEWPTCLASS; + else zbuf[0] = (char)MPSDEFAULTWPTCLASS; + gbfwrite(zbuf, 4, 1, mps_file); /* class */ + + zbuf[0]=0; + gbfwrite(zbuf, 1, 1, mps_file); /* country empty string */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfwrite(zbuf, 4, 1, mps_file); /* subclass part 1 */ + gbfwrite(ffbuf, 12, 1, mps_file); /* subclass part 2 */ + gbfwrite(zbuf, 2, 1, mps_file); /* subclass part 3 */ + gbfwrite(ffbuf, 4, 1, mps_file); /* unknown */ + } + else { + gbfwrite(zbuf, 8, 1, mps_file); + gbfwrite(ffbuf, 8, 1, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); + } + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + if (wpt->description) gbfputs(ascii_description, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination */ + xfree(ascii_description); + ascii_description = NULL; + + if (mps_proximity == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl( mps_proximity, mps_file ); + } + + gbfputint32(display, mps_file); /* Show waypoint w/ name */ + gbfputint32(colour, mps_file); + gbfputint32(icon, mps_file); + + gbfwrite(zbuf, 3, 1, mps_file); /* city, state, facility */ + + gbfwrite(zbuf, 1, 1, mps_file); /* unknown */ + + if (mps_depth == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl(mps_depth, mps_file); + } + + gbfwrite(zbuf, 2, 1, mps_file); /* unknown */ + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfwrite(zbuf, 4, 1, mps_file); /* unknown */ + if (wpt->notes) gbfputs(wpt->notes, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); /* string termination */ + } +} + +/* + * wrapper to include the mps_ver_out information + * A waypoint is only written if it hasn't been written before + * based on it shortname alone + * + */ +static void +mps_waypoint_w_unique_wrapper(const waypoint *wpt) +{ + waypoint *wptfound = NULL; + + /* Search for this waypoint in the ones already written */ + wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); + /* is the next line necessary? Assumes we know who's called us and in what order */ + if (wptfound == NULL) + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); + + /* if this waypoint hasn't been written then it is okay to do so */ + if (wptfound == NULL) { + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); + + /* ensure we record in our "private" queue what has been + written so that we don't write it again */ + mps_wpt_q_add(&written_wpt_head, wpt); + } +} + +/* + * wrapper to include the mps_ver_out information + * A waypoint is only written if it hasn't been written before + * based on it shortname alone + * Provided as a separate function from above in case we find + * have to do other things + * + */ +static void +mps_route_wpt_w_unique_wrapper(const waypoint *wpt) +{ + waypoint *wptfound = NULL; + + /* Search for this waypoint in the ones already written */ + wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); + if (wptfound == NULL) + /* so, not a real wpt, so must check route wpts already written as reals */ + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); + + /* if this waypoint hasn't been written then it is okay to do so + but assume it is only required for the route + */ + if (wptfound == NULL) { + /* Although we haven't written one out, this might still be a "real" waypoint + If so, we need to write it out now accordingly */ + wptfound = find_waypt_by_name (wpt->shortname); + + if (wptfound == NULL) { + /* well, we tried to find: it wasn't written and isn't a real waypoint */ + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==1)); + mps_wpt_q_add(&written_route_wpt_head, wpt); + } + else { + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); + /* Simulated real user waypoint */ + mps_wpt_q_add(&written_wpt_head, wpt); + } + } +} +#if 0 +/* + * wrapper to include the mps_ver_out information + * This one always writes a waypoint. If it has been written before + * then generate a unique name before writing + * + */ +static void +mps_waypoint_w_uniqloc_wrapper(waypoint *wpt) +{ + waypoint *wptfound = NULL; + char *newName; + + /* Search for this waypoint in the ones already written */ + wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); + /* is the next line necessary? Assumes we know who's called us and in what order */ + if (wptfound == NULL) + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); + + if (wptfound != NULL) { + /* check if this is the same waypoint by looking at the lat lon + not ideal, but better then having two same named waypoints + that kills MapSource. If it is the same then don't bother + adding it in. If it isn't, then rename it + */ + if (((wpt->latitude - wptfound->latitude) != 0) || + ((wpt->longitude - wptfound->longitude) != 0)) { + /* Not the same lat lon, so rename and add */ + newName = mkshort(written_wpt_mkshort_handle, wpt->shortname); + wptfound = waypt_dupe(wpt); + xfree(wptfound->shortname); + wptfound->shortname = newName; + mps_waypoint_w(mps_file_out, mps_ver_out, wptfound, (1==0)); + mps_wpt_q_add(&written_wpt_head, wpt); + } + } + else { + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); + /* ensure we record in out "private" queue what has been + written so that we don't write it again */ + mps_wpt_q_add(&written_wpt_head, wpt); + } +} +#endif + +/* + * read in from file a route record + * MRCB + */ +static void +mps_route_r(gbfile *mps_file, int mps_ver, route_head **rte) +{ + char tbuf[100]; + char *rtename; + char wptname[MPSNAMEBUFFERLEN]; + int lat = 0; + int lon = 0; + char rte_autoname; + int interlinkStepCount; + int thisInterlinkStep; + unsigned int mpsclass; + + route_head *rte_head; + int rte_count; + + waypoint *thisWaypoint; + waypoint *tempWpt; + + double mps_altitude = unknown_alt; + double mps_depth = unknown_alt; + + rtename = gbfgetcstr(mps_file); +#ifdef MPS_DEBUG + fprintf(stderr, "mps_route_r: reading route %s\n", rtename); +#endif + + gbfread(&rte_autoname, 1, 1, mps_file); /* autoname flag */ + + gbfread(tbuf, 1, 1, mps_file); /* skip min/max values */ + if (tbuf[0] == 0) { + + lat = gbfgetint32(mps_file); /* max lat of whole route */ + lon = gbfgetint32(mps_file); /* max lon of whole route */ + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } + else { + mps_altitude = unknown_alt; + gbfseek( mps_file, 8, SEEK_CUR ); + } + + lat = gbfgetint32(mps_file); /* min lat of whole route */ + lon = gbfgetint32(mps_file); /* min lon of whole route */ + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } + else { + mps_altitude = unknown_alt; + gbfseek( mps_file, 8, SEEK_CUR ); + } + } + + rte_count = gbfgetint32(mps_file); /* number of waypoints in route */ + + /* This might be rather presumptuous, but is it valid in any format to have route with no points? */ + /* Let's assume not, so if the route count is zero or less, let's get out of here and allow the */ + /* caller to do any file resync */ + if (rte_count < 0) return; + +#ifdef MPS_DEBUG + fprintf(stderr, "mps_route_r: route contains %d waypoints\n", rte_count); +#endif + + rte_head = route_head_alloc(); + rte_head->rte_name = rtename; + route_add_head(rte_head); + *rte = rte_head; + + rte_count--; /* need to loop round for one less than the number of waypoints */ + + while (rte_count--) { + + mps_readstr(mps_file, wptname, sizeof(wptname)); +#ifdef MPS_DEBUG + fprintf(stderr, "mps_route_r: reading route waypoint %s\n", wptname); +#endif + + mpsclass = gbfgetint32(mps_file); /* class */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 22, 1, mps_file); /* subclass data */ + + /* This is a bit unpleasant. Routes have a variable length of + data (min 22 bytes) terminated by a zero */ + do { + gbfread(tbuf, 1, 1, mps_file); + } while (tbuf[0]); + + /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ + gbfread(tbuf, 18, 1, mps_file); + } + else { + gbfread(tbuf, 17, 1, mps_file); /* subclass data */ + gbfread(tbuf, 18, 1, mps_file); /* unknown 0x00 0x03 0x00 .. 0x00 */ + } + + /* link details */ + interlinkStepCount = gbfgetint32(mps_file); /* NOT always 2, but will assume > 0 */ + +#ifdef MPS_DEBUG + fprintf(stderr, "mps_route_r: interlink steps are %d\n", interlinkStepCount); +#endif + + /* Basically we're knackered if the step count is less than one since we hard code reading of the */ + /* first, so if there isn't one, we'd lose sync on the file and read junk */ + /* Given we've already done some route head allocation, do we return or do we die? It'd be good */ + /* do some clean up before returning. */ + if (interlinkStepCount < 1) { + /* For RJL - are the following lines correct ? */ + /* route_free(rte_head); + route_del_head(rte_head); */ + return; + } + + /* first end of link */ + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } + else { + mps_altitude = unknown_alt; + gbfseek( mps_file, 8, SEEK_CUR ); + } + + /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there + if found. With MapSource, one should consider the real waypoint list as definitive */ + tempWpt = find_waypt_by_name(wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } + else { + tempWpt = mps_find_wpt_q_by_name(&read_route_wpt_head, wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } + else { + /* should never reach here, but we do need a fallback position */ +#ifdef MPS_DEBUG + fprintf(stderr, "mps_route_r: reached the point we never should\n"); +#endif + thisWaypoint = waypt_new(); + thisWaypoint->shortname = xstrdup(wptname); + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->altitude = mps_altitude; + if (mps_depth != unknown_alt) WAYPT_SET(thisWaypoint, depth, mps_depth); + } + } + + route_add_wpt(rte_head, thisWaypoint); + + /* take two off the count since we separately read the start and end parts of the link */ + /* MRCB 2004/09/15 - NOPE, sorry, this needs to one, since interlink steps can be > 0 */ + for (thisInterlinkStep = interlinkStepCount - 1; thisInterlinkStep > 0; thisInterlinkStep--) { + /* Could do this by doing a calculation on length of each co-ordinate and just doing one read + but doing it this way makes it easier in the future to make use of this data */ + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl( mps_file ); + } + else { + mps_altitude = unknown_alt; + gbfseek( mps_file, 8, SEEK_CUR ); + } + } + + gbfread(tbuf, 1, 1, mps_file); /* NULL */ + + gbfread(tbuf, 4, 1, mps_file); /* link max lat */ + gbfread(tbuf, 4, 1, mps_file); /* link max lon */ + gbfread(tbuf, 9, 1, mps_file); /* link max alt validity + alt */ + + gbfread(tbuf, 4, 1, mps_file); /* link min lat */ + gbfread(tbuf, 4, 1, mps_file); /* link min lon */ + gbfread(tbuf, 9, 1, mps_file); /* link min alt validity + alt */ + + } /* while (trk_count--) */ + + /* when the loop is done, there's still one waypoint to read with a small trailer */ + /* all we want is the waypoint name; lat, lon and alt are already set from above */ + mps_readstr(mps_file, wptname, sizeof(wptname)); +#ifdef MPS_DEBUG + fprintf(stderr, "mps_route_r: reading final route waypoint %s\n", wptname); +#endif + + + mpsclass = gbfgetint32(mps_file); /* class */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 22, 1, mps_file); /* subclass data */ + + /* This is a bit unpleasant. Routes have a variable length of + data (min 22 bytes) terminated by a zero */ + do { + gbfread(tbuf, 1, 1, mps_file); + } while (tbuf[0]); + + /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ + gbfread(tbuf, 18, 1, mps_file); + } + else { + gbfread(tbuf, 17, 1, mps_file); /* subclass data */ + gbfread(tbuf, 18, 1, mps_file); /* unknown 0x00 0x03 0x00 .. 0x00 */ + } + + gbfread(tbuf, 5, 1, mps_file); /* 5 byte trailer */ + /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there + if found because there is more info held in a real waypoint than in its route counterpart, + e.g. the display symbol (aka icon) + */ + tempWpt = find_waypt_by_name(wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } + else { + tempWpt = mps_find_wpt_q_by_name(&read_route_wpt_head, wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } + else { + /* should never reach here, but we do need a fallback position */ + thisWaypoint = waypt_new(); + thisWaypoint->shortname = xstrdup(wptname); + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->altitude = mps_altitude; + } + } + + route_add_wpt(rte_head, thisWaypoint); + + return; +} + +/* + * write out to file a route header + * MRCB + */ +static void +mps_routehdr_w(gbfile *mps_file, int mps_ver, const route_head *rte) +{ + unsigned int reclen; + unsigned int rte_datapoints; + int rname_len; + char *rname; + char hdr[20]; + char zbuf[20]; + char *src = ""; + char *ident; + + waypoint *testwpt; + time_t uniqueValue = 0; + int allWptNameLengths; + + double maxlat=-90.0; + double maxlon=-180.0; + double minlat=90.0; + double minlon=180.0; + double maxalt=unknown_alt; + double minalt=unknown_alt; + + int lat; + int lon; + + queue *elem, *tmp; + + prevRouteWpt = NULL; /* clear the stateful flag used to know when the start of route wpts happens */ + + memset(zbuf, 0, sizeof(zbuf)); + + /* total nodes (waypoints) this route */ + rte_datapoints = 0; + allWptNameLengths = 0; + + if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + testwpt = (waypoint *)elem; + if (rte_datapoints == 0) { + uniqueValue = testwpt->creation_time; + } + if (testwpt->latitude > maxlat) maxlat = testwpt->latitude; + if (testwpt->latitude < minlat) minlat = testwpt->latitude; + if (testwpt->longitude > maxlon) maxlon = testwpt->longitude; + if (testwpt->longitude < minlon) minlon = testwpt->longitude; + if (testwpt->altitude != unknown_alt) { + if ((testwpt->altitude > maxalt) || + (maxalt == unknown_alt)) maxalt = testwpt->altitude; + if ((testwpt->altitude < minalt) || + (minalt == unknown_alt)) minalt = testwpt->altitude; + } + + if(testwpt->description) src = testwpt->description; + if(testwpt->notes) src = testwpt->notes; + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + testwpt->shortname; + allWptNameLengths += strlen(ident) + 1; + + rte_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* route name */ + if (!rte->rte_name) { + sprintf(hdr, "Route%04x", (unsigned) uniqueValue); + rname = xstrdup(hdr); + } + else + rname = xstrdup(rte->rte_name); + + rname_len = strlen(rname); + reclen = rname_len + 42; /* "T" (1) + strlen(tname) + NULL (1) + autoname flag (2) + + route lat lon max (2x4) + route max alt (9) + + route lat lon min (2x4) + route min alt (9) + + num route datapoints value (4) */ + + /* V3 - each waypoint: waypoint name + NULL (1) + class (4) + country + NULL (1) + + subclass (17) + unknown (18) */ + /* V4,5 - each waypoint: waypoint name + NULL (1) + class (4) + country + NULL (1) + + subclass (18) + unknown (4) + unknown (19) */ + /* V* - each route link: 0x00000002 (4) + end 1 lat (4) + end 1 lon (4) + end 1 alt (9) + + end 2 lat (4) + end 2 lon (4) + end 2 alt (9) + NULL (1) + + link max lat (4) + link max lon (4) + link max alt (9) + + link min lat (4) + link min lon (4) + link min alt (9) */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + reclen += allWptNameLengths + rte_datapoints * 46 + + (rte_datapoints - 1) * 73 + 4; /* link details plus overall trailing bytes */ + } + else { + reclen += allWptNameLengths + rte_datapoints * 40 + + (rte_datapoints - 1) * 73 + 4; /* link details plus overall trailing bytes */ + } + + gbfputint32(reclen, mps_file); + gbfputc('R', mps_file); + gbfwrite(rname, rname_len, 1, mps_file); + + xfree(rname); + + hdr[0] = 0; /* NULL of string termination */ + hdr[1] = 0; /* don't autoname */ + hdr[2] = 0; /* MSB of don't autoname */ + gbfwrite(hdr, 3, 1, mps_file); /* NULL string terminator + route autoname flag */ + + lat = GPS_Math_Deg_To_Semi(maxlat); + lon = GPS_Math_Deg_To_Semi(maxlon); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (maxalt == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl(maxalt, mps_file); + } + + lat = GPS_Math_Deg_To_Semi(minlat); + lon = GPS_Math_Deg_To_Semi(minlon); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (minalt == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl(minalt, mps_file); + } + + gbfputint32(rte_datapoints, mps_file); + } +} + +static void +mps_routehdr_w_wrapper(const route_head *rte) +{ + mps_routehdr_w(mps_file_out, mps_ver_out, rte); +} + + +/* + * write out to file a route datapoint + * MRCB + */ +static void +mps_routedatapoint_w(gbfile *mps_file, int mps_ver, const waypoint *rtewpt) +{ + int lat; + int lon; + char zbuf[20]; + char ffbuf[20]; + char *src = ""; + char *ident; + int reclen; + + int maxlat; + int maxlon; + int minlat; + int minlon; + double maxalt=unknown_alt; + double minalt=unknown_alt; + + double mps_altitude; + waypoint *wptfound; + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xff, sizeof(ffbuf)); + + if (prevRouteWpt != NULL) { + /* output the route link details */ + reclen = 2; + gbfputint32(reclen, mps_file); + + /* output end point 1 */ + lat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); + lon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + mps_altitude = prevRouteWpt->altitude; + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file ); + } + + /* output end point 2 */ + lat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + lon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + mps_altitude = rtewpt->altitude; + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + + if (rtewpt->latitude > prevRouteWpt->latitude) { + maxlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + minlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); + } + else { + minlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + maxlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); + } + + if (rtewpt->longitude > prevRouteWpt->longitude) { + maxlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + minlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); + } + else { + minlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + maxlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); + } + + if (rtewpt->altitude != unknown_alt) maxalt = rtewpt->altitude; + if (rtewpt->altitude != unknown_alt) minalt = rtewpt->altitude; + if (prevRouteWpt->altitude != unknown_alt) { + if ((prevRouteWpt->altitude > maxalt) || + (maxalt == unknown_alt)) maxalt = prevRouteWpt->altitude; + if ((prevRouteWpt->altitude < minalt) || + (minalt == unknown_alt)) minalt = prevRouteWpt->altitude; + } + + gbfwrite (zbuf, 1, 1, mps_file); + + /* output max coords of the link */ + gbfputint32(maxlat, mps_file); + gbfputint32(maxlon, mps_file); + + if (maxalt == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl(maxalt, mps_file); + } + + /* output min coords of the link */ + gbfputint32(minlat, mps_file); + gbfputint32(minlon, mps_file); + + if (minalt == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl(minalt, mps_file ); + } + + } + + if(rtewpt->description) src = rtewpt->description; + if(rtewpt->notes) src = rtewpt->notes; + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + rtewpt->shortname; + + gbfputs(ident, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination to ident */ + + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, ident); + if (wptfound != NULL) zbuf[0] = (char)MPSHIDDENROUTEWPTCLASS; + else zbuf[0] = (char)MPSDEFAULTWPTCLASS; + gbfwrite(zbuf, 4, 1, mps_file); /* class */ + + zbuf[0]=0; + gbfwrite(zbuf, 1, 1, mps_file); /* country - i.e. empty string */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfwrite(zbuf, 4, 1, mps_file); /* subclass part 1 */ + gbfwrite(ffbuf, 12, 1, mps_file); /* subclass part 2 */ + gbfwrite(zbuf, 2, 1, mps_file); /* subclass part 3 */ + gbfwrite(ffbuf, 4, 1, mps_file); /* unknown */ + + gbfwrite(zbuf, 1, 1, mps_file); + gbfputc(3, mps_file); + gbfwrite(zbuf, 17, 1, mps_file); + } + else { + gbfwrite(zbuf, 8, 1, mps_file); /* subclass part 1 */ + gbfwrite(ffbuf, 8, 1, mps_file); /* subclass part 2 */ + gbfwrite(zbuf, 1, 1, mps_file); /* subclass part 3 */ + + /* unknown */ + gbfwrite(zbuf, 1, 1, mps_file); + gbfputc(3, mps_file); + gbfwrite(zbuf, 16, 1, mps_file); + } + + prevRouteWpt = rtewpt; +} + +static void +mps_routedatapoint_w_wrapper(const waypoint *rte) +{ + mps_routedatapoint_w(mps_file_out, mps_ver_out, rte); +} + + +/* + * write out to file a route trailer + * MRCB + */ +static void +mps_routetrlr_w(gbfile *mps_file, int mps_ver, const route_head *rte) +{ + char hdr[2]; + int value = 0; + + hdr[0] = 1; + + if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ + gbfwrite(&value, 4, 1, mps_file); + gbfwrite(hdr, 1, 1, mps_file); + } +} + +static void +mps_routetrlr_w_wrapper(const route_head *rte) +{ + mps_routetrlr_w(mps_file_out, mps_ver_out, rte); +} + + +/* + * read in from file a track record + * MRCB + */ +static void +mps_track_r(gbfile *mps_file, int mps_ver, route_head **trk) +{ + char *trkname; + int lat; + int lon; + + int dateTime = 0; + route_head *track_head; + int trk_count; + + waypoint *thisWaypoint; + double mps_altitude = unknown_alt; + double mps_depth = unknown_alt; + + trkname = gbfgetcstr(mps_file); +#ifdef MPS_DEBUG + fprintf(stderr, "mps_track_r: reading track %s\n", trkname); +#endif + + (void) gbfgetc(mps_file); /* display flag */ + (void) gbfgetint32(mps_file); /* colour */ + + trk_count = gbfgetint32(mps_file); /* number of datapoints in tracklog */ + + /* I don't know, but perhaps it's valid to have a track with no waypoints */ + /* Seems dumb, but truth is stranger than fiction. Of course, it could be */ + /* that there are more than MAXINT / 2 waypoints, yeah sure */ + /* Allow the caller the perform the file resync caused by bombing out early */ + if (trk_count < 0) return; +#ifdef MPS_DEBUG + fprintf(stderr, "mps_track_r: there are %d track waypoints %d\n", trk_count); +#endif + + track_head = route_head_alloc(); + track_head->rte_name = trkname; + track_add_head(track_head); + *trk = track_head; + + while (trk_count--) { + + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl( mps_file ); + } + else { + mps_altitude = unknown_alt; + gbfseek( mps_file, 8, SEEK_CUR ); + } + + if (gbfgetc(mps_file) == 1) { /* date/time validity */ + dateTime = gbfgetint32(mps_file); + } + else { + (void) gbfgetint32(mps_file); + } + + if (gbfgetc(mps_file) == 1) { /* depth validity */ + mps_depth = gbfgetdbl(mps_file ); + } + else { + mps_depth = unknown_alt; + gbfseek( mps_file, 8, SEEK_CUR ); + } + + thisWaypoint = waypt_new(); + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->creation_time = dateTime; + thisWaypoint->microseconds = 0; + thisWaypoint->altitude = mps_altitude; + if (mps_depth != unknown_alt) WAYPT_SET(thisWaypoint, depth, mps_depth); + track_add_wpt(track_head, thisWaypoint); + + } /* while (trk_count--) */ + + return; + +} + +/* + * write out to file a tracklog header + * MRCB + */ +static void +mps_trackhdr_w(gbfile *mps_file, int mps_ver, const route_head *trk) +{ + unsigned int reclen; + unsigned int trk_datapoints; + unsigned int colour = 0; /* unknown colour */ + int tname_len; + char *tname; + char hdr[20]; + waypoint *testwpt; + time_t uniqueValue = 0; + + queue *elem, *tmp; + + /* total nodes (waypoints) this track */ + trk_datapoints = 0; + if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */ + QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { + if (trk_datapoints == 0) { + testwpt = (waypoint *)elem; + uniqueValue = testwpt->creation_time; + } + trk_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* track name */ + if (!trk->rte_name) { + sprintf(hdr, "Track%04x", (unsigned) uniqueValue); + tname = xstrdup(hdr); + } + else + tname = xstrdup(trk->rte_name); + + tname_len = strlen(tname); + reclen = tname_len + 11; /* "T" (1) + strlen(tname) + NULL (1) + display flag (1) + colour (4) + + num track datapoints value (4) */ + + reclen += (trk_datapoints * 31) - 1; /* lat (4) + lon (4) + alt (9) + date (5) + depth (9) ;*/ + /* -1 is because reclen starts from 0 which means a length of 1 */ + gbfputint32(reclen, mps_file); + gbfputc('T', mps_file); + gbfwrite(tname, tname_len, 1, mps_file); + + xfree(tname); + + hdr[0] = 0; + hdr[1] = 1; + gbfwrite(hdr, 2, 1, mps_file); /* NULL string terminator + display flag */ + + gbfputint32(colour, mps_file); + + gbfputint32(trk_datapoints, mps_file); + } + +} + +static void +mps_trackhdr_w_wrapper(const route_head *trk) +{ + mps_trackhdr_w(mps_file_out, mps_ver_out, trk); +} + + +/* + * write out to file a tracklog datapoint + * MRCB + */ +static void +mps_trackdatapoint_w(gbfile *mps_file, int mps_ver, const waypoint *wpt) +{ + int lat, lon; + time_t t = wpt->creation_time; + char zbuf[10]; + + double mps_altitude = wpt->altitude; + double mps_depth = unknown_alt; + + lat = GPS_Math_Deg_To_Semi(wpt->latitude); + lon = GPS_Math_Deg_To_Semi(wpt->longitude); + if (WAYPT_HAS(wpt, depth) && mpsusedepth) mps_depth = wpt->depth; + + memset(zbuf, 0, sizeof(zbuf)); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + + if (t > 0) { /* a valid time is assumed to > 0 */ + gbfputc(1, mps_file); + gbfputint32(t, mps_file); + } + else { + gbfwrite(zbuf, 5, 1, mps_file); + } + + if (mps_depth == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } + else { + gbfputc(1, mps_file); + gbfputdbl(mps_depth, mps_file ); + } +} + +static void +mps_trackdatapoint_w_wrapper(const waypoint *wpt) +{ + mps_trackdatapoint_w(mps_file_out, mps_ver_out, wpt); +} + + +static void +mps_read(void) +{ + waypoint *wpt; + route_head *rte; + route_head *trk; + + char recType; + int reclen; + int morework; + unsigned int mpsWptClass; + long mpsFileInPos; + + mps_ver_in = 0; /* although initialised at declaration, what happens if there are two mapsource + input files? */ + mps_fileHeader_r(mps_file_in, &mps_ver_in); + +#ifdef DUMP_ICON_TABLE + printf("static icon_mapping_t garmin_icon_table[] = {\n"); +#endif + + morework = 1; + while (morework && !gbfeof(mps_file_in)) { + + /* Read record length of next section */ + reclen = gbfgetint32(mps_file_in); + + if (reclen < 0) fatal (MYNAME ": a record length read from the input file is invalid. \nEither the file is corrupt or unsupported.\n"); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_in); + mpsFileInPos = gbftell(mps_file_in); + switch (recType) { + case 'W': + /* Waypoint record */ + /* With routes, we need the waypoint info that reveals, for example, the symbol type */ + mps_waypoint_r(mps_file_in, mps_ver_in, &wpt, &mpsWptClass); + +#ifdef MPS_DEBUG + fprintf(stderr,"Read a waypoint - %s\n", wpt->shortname); +#endif + + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ +#ifdef MPS_DEBUG + fprintf(stderr,"Lost sync with the file reading waypoint - %s\n", wpt->shortname); +#endif + gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); + waypt_free( wpt ); + } + else { + /* only add to the "real" list if a "user" waypoint otherwise add to the private list */ + if (mpsWptClass == MPSDEFAULTWPTCLASS) waypt_add(wpt); + else { + mps_wpt_q_add(&read_route_wpt_head, wpt); + waypt_free( wpt ); + } +#ifdef DUMP_ICON_TABLE + printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname); +#endif + } + break; + + case 'R': + /* Route record */ + mps_route_r(mps_file_in, mps_ver_in, &rte); + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ +#ifdef MPS_DEBUG + fprintf(stderr,"Lost sync with the file reading route - %s\n", rte->rte_name); +#endif + gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); + } + break; + + case 'T': + /* Track record */ + mps_track_r(mps_file_in, mps_ver_in, &trk); + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ +#ifdef MPS_DEBUG + fprintf(stderr,"Lost sync with the file reading track - %s\n", trk->rte_name); +#endif + gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); + } + break; + + case 'L': + /* Map segment record */ + mps_mapsegment_r(mps_file_in, mps_ver_in); + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ + gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); + } + break; + + case 'V': + /* Mapset record */ + mps_mapsetname_r(mps_file_in, mps_ver_in); + /* Last record in the file */ + morework = 0; + break; + default: + /* Unknown record type. Skip over it. */ + gbfseek(mps_file_in, reclen, SEEK_CUR); + } + + } /* while (!gbfeof(mps_file_in)) */ + +#ifdef DUMP_ICON_TABLE + printf("\t{ -1, NULL },\n"); + printf("};\n"); +#endif + + return ; + +} + +void +mps_write(void) +{ + int short_length; + waypoint *wpt; + route_head *rte; + route_head *trk; + + char recType; + int reclen; + /* TODO: This kills a compiler warning but I'm not sure it's right */ + int reclen2 = 0; + unsigned int tocopy; + unsigned int block; + + long tempFilePos; + unsigned int mpsWptClass; + + unsigned char copybuf[8192]; + + short_length = atoi(snlen); + + if (mpsmergeout) { + /* need to skip over the merging header and test merge version */ + mps_fileHeader_r(mps_file_temp, &mps_ver_temp); + + if (mpsverout) { + if (mps_ver_temp != atoi(mpsverout)) { + /* Need to clean up after a junk version specified */ + /* close the real output file + renamed original output file */ + /* then delete the "real" file and rename the temporarily renamed file back */ + gbfclose(mps_file_temp); + gbfclose(mps_file_out); + remove(fin_name); + rename(tempname, fin_name); + fatal (MYNAME ": merge source version is %d, requested out version is %d\n", mps_ver_temp, atoi(mpsverout)); + } + } + else { + mpsverout = xmalloc(10); + sprintf(mpsverout,"%d", mps_ver_temp); + } + } + + if (mpsverout) + mps_ver_out = atoi(mpsverout); + else + mps_ver_out = 5; + + mkshort_handle = mkshort_new_handle(); + + setshort_length(mkshort_handle, short_length); + + if (snwhiteopt) + setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + else + setshort_whitespace_ok(mkshort_handle, 0); + + mps_fileHeader_w(mps_file_out, mps_ver_out); + + /* .mps file order is wpts, rtes, trks then mapsets. If we've not been asked to write + wpts, but we are merging, then read in the waypoints from the original file and + write them out, prior to doing rtes. + */ + /* if ((mpsmergeout) && (global_opts.objective != wptdata)) { */ + if ((mpsmergeout) && (! doing_wpts)) { + while (!gbfeof(mps_file_temp)) { + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + if (recType == 'W') { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + tempFilePos = gbftell(mps_file_temp); + /* need to read in the waypoint info only because later we may need to check for uniqueness + since we're here because the user didn't request waypoints, this should be acceptable */ + mps_waypoint_r(mps_file_temp, mps_ver_temp, &wpt, &mpsWptClass); + mps_wpt_q_add(&written_wpt_head, wpt); + waypt_free( wpt ); + /* now return to the start of the waypoint data to do a "clean" copy */ + gbfseek(mps_file_temp, tempFilePos, SEEK_SET); + + /* copy the data using a "reasonably" sized buffer */ + for(tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + } + else break; + } /* while (!gbfeof(mps_file_temp)) */ + } /* if (mpsmergeout) */ + + /* irrespective of merging, now write out any waypoints */ + /* if (global_opts.objective == wptdata) { */ + if (doing_wpts) { + + if (mpsmergeout) { + /* since we're processing waypoints, we should read in from whatever version and write out */ + /* in the selected version */ + while (!gbfeof(mps_file_temp)) { + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + if (recType == 'W') { + /* need to be careful that we aren't duplicating a wpt defined from elsewhere */ + mps_waypoint_r(mps_file_temp, mps_ver_temp, &wpt, &mpsWptClass); + if (mpsWptClass == MPSDEFAULTWPTCLASS) waypt_add(wpt);else waypt_free(wpt); + } + else break; + } + } + waypt_disp_all(mps_waypoint_w_unique_wrapper); + } + + /* prior to writing any tracks as requested, if we're doing a merge, read in the rtes + from the original file and then write them out, ready for tracks to follow + */ + + /* if ((mpsmergeout) && (global_opts.objective != rtedata)) { */ + if ((mpsmergeout) && (! doing_rtes)) { + while (!gbfeof(mps_file_temp)) { + + /* this might all fail if the relevant waypoints haven't been written */ + if (recType == 'R') { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + /* copy the data using a "reasonably" sized buffer */ + for(tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + } + else break; + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + } /* while (!gbfeof(mps_file_temp)) */ + } /* if (mpsmergeout) */ + + /* routes are next in the wpts, rtes, trks, mapset sequence */ + /* if (global_opts.objective == rtedata) { */ + if (doing_rtes) { + + if (mpsmergeout) { + /* since we're processing routes, we should read in from whatever version and write out */ + /* in the selected version */ + while (!gbfeof(mps_file_temp)) { + + if (recType == 'R') { + mps_route_r(mps_file_temp, mps_ver_temp, &rte); + } + else break; + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + } + } + /* need to make sure there is a "real" waypoint for each route waypoint + Need to be careful about creating duplicate wpts as MapSource chokes on these + so, if the user requested waypoints to be output too, then write the route + waypoints only if unique in the total list of waypoints ("real" and route derived) + If the user didn't request waypoints to be output, then output the route derived + waypoints without consideration for uniqueness for "real" waypoints that haven't + been output (phew!) + */ + route_disp_all(mps_noop, mps_noop, mps_route_wpt_w_unique_wrapper); + + route_disp_all(mps_routehdr_w_wrapper, mps_routetrlr_w_wrapper, mps_routedatapoint_w_wrapper); + } + + /* If merging but we haven't been requested to write out tracks, then read in tracks from + the original file and write these out prior to any mapset writes later on + */ + /* if ((mpsmergeout) && (global_opts.objective != trkdata)) { */ + if ((mpsmergeout) && (! doing_trks)) { + while (!gbfeof(mps_file_temp)) { + + if (recType == 'T') { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + /* copy the data using a "reasonably" sized buffer */ + for(tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + } + else break; + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + } /* while (!gbfeof(mps_file_temp)) */ + } /* if (mpsmergeout) */ + + /* tracks are next in the wpts, rte, trks, mapset sequence in .mps files */ + /* if (global_opts.objective == trkdata) { */ + if (doing_trks) { + if (mpsmergeout) { + /* since we're processing tracks, we should read in from whatever version and write out + in the selected version */ + while (!gbfeof(mps_file_temp)) { + + if (recType == 'T') { + mps_track_r(mps_file_temp, mps_ver_temp, &trk); + } + else break; + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + } + } + track_disp_all(mps_trackhdr_w_wrapper, mps_noop, mps_trackdatapoint_w_wrapper); + } + + if (mpsmergeout) { + /* should now be reading a either a map segment or a mapset - since we would write out an empty one, + let's use the one from the merge file which may well have decent data in */ + for (;;) { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + /* copy the data using a "reasonably" sized buffer */ + for(tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + + if (recType != 'V') { + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + } + else break; + } + + } + else mps_mapsetname_w(mps_file_out, mps_ver_out); + + mkshort_del_handle(&mkshort_handle); + +} + +ff_vecs_t mps_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + mps_rd_init, + mps_wr_init, + mps_rd_deinit, + mps_wr_deinit, + mps_read, + mps_write, + NULL, + mps_args, + CET_CHARSET_MS_ANSI /* CET-REVIEW */ +}; diff --git a/mingw/Makefile b/mingw/Makefile new file mode 100644 index 000000000..32837c31c --- /dev/null +++ b/mingw/Makefile @@ -0,0 +1,41 @@ +CC=/usr/local/cross-tools/bin/i386-mingw32msvc-gcc +VPATH=..:../shapelib + +FILES=gpsbabel.exe libexpat.dll ../win32/GPSBabelGUI.exe ../win32/gui-2/README.gui \ + ../README* ../style/README.style ../COPYING ../readme.html + +gpsbabel.exe: wintesto.cmd + +include ../Makefile +CFLAGS=-Iinclude -I../coldsync -O $(INHIBIT_USB) $(EXTRA_CFLAGS) +# +# Must define empty (don't comment out the whole line) if you want to +# override INHIBIT_USB from the parent Makefile. +# +INHIBIT_USB=#-DNO_USB +OSJEEPS=jeeps/gpsusbwin.o + +gpsbabel.exe: $(OBJS) + $(CC) -static $(CFLAGS) $(OBJS) lib/libexpat.a -o gpsbabel.exe -lsetupapi + zip -j /tmp/gpsbabel-$(VERSIOND).zip $(FILES) + cp gpsbabel.exe /tmp + +mkwintesto: mkwintesto.c + /usr/bin/cc mkwintesto.c -o mkwintesto + +wintesto.cmd: mkwintesto + ./mkwintesto ../testo + +# The "usbfree" target is useful for generating an executable that +# works on NT 3.5 or 4.0 since it doesn't have USB support and tanks +# on our libsetupapi references. + +usbfree: + $(MAKE) INHIBIT_USB=-DNO_USB gpsbabel-usbfree.exe + +gpsbabel-usbfree.exe: $(OBJS) + $(CC) -static $(CFLAGS) $(OBJS) lib/libexpat.a -o gpsbabel-usbfree.exe + zip -j /tmp/gpsbabel-nousb-$(VERSIOND).zip gpsbabel-usbfree.exe + + + diff --git a/mingw/README.expat b/mingw/README.expat new file mode 100644 index 000000000..ae51d66ca --- /dev/null +++ b/mingw/README.expat @@ -0,0 +1 @@ +This expat library comes from http://sourceforge.net/projects/mingwrep/ diff --git a/mingw/coldsync/.ignore b/mingw/coldsync/.ignore new file mode 100644 index 000000000..e69de29bb diff --git a/mingw/include/expat.h b/mingw/include/expat.h new file mode 100644 index 000000000..99678856d --- /dev/null +++ b/mingw/include/expat.h @@ -0,0 +1,1001 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef XmlParse_INCLUDED +#define XmlParse_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(XML_USE_MSC_EXTENSIONS) +#define XMLCALL __cdecl +#elif defined(__GNUC__) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1 +#define XML_STATUS_OK XML_STATUS_OK +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + XML_ERROR_UNBOUND_PREFIX +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( + void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(XMLCALL *malloc_fcn)(size_t size); + void *(XMLCALL *realloc_fcn)(void *ptr, size_t size); + void (XMLCALL *free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + When a namespace is not declared, the name and prefix will be + passed through without expansion. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( + void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, + const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( + void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( + void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( + XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (XMLCALL *convert)(void *data, const char *s); + void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( + void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(long) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 1 +#define XML_MINOR_VERSION 95 +#define XML_MICRO_VERSION 7 + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlParse_INCLUDED */ diff --git a/mingw/includew/expat.h b/mingw/includew/expat.h new file mode 100644 index 000000000..c6a4b3b6c --- /dev/null +++ b/mingw/includew/expat.h @@ -0,0 +1,1013 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_INCLUDED +#define Expat_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include +#include "expat_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + /* Added in 1.95.7. */ + XML_ERROR_UNBOUND_PREFIX, + /* Added in 1.95.8. */ + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE, + /* Added in 2.0. */ + XML_ERROR_RESERVED_PREFIX_XML, + XML_ERROR_RESERVED_PREFIX_XMLNS, + XML_ERROR_RESERVED_NAMESPACE_URI +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( + void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( + void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, + const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( + void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( + void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( + XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (XMLCALL *convert)(void *data, const char *s); + void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( + void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, + XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, + XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, + void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { + XML_INITIALIZED, + XML_PARSING, + XML_FINISHED, + XML_SUSPENDED +}; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR, + XML_FEATURE_NS + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 2 +#define XML_MINOR_VERSION 0 +#define XML_MICRO_VERSION 0 + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_INCLUDED */ diff --git a/mingw/includew/expat_external.h b/mingw/includew/expat_external.h new file mode 100644 index 000000000..4cd16923c --- /dev/null +++ b/mingw/includew/expat_external.h @@ -0,0 +1,115 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(XML_USE_MSC_EXTENSIONS) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ +#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +typedef __int64 XML_Index; +typedef unsigned __int64 XML_Size; +#else +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#endif +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ diff --git a/mingw/jeeps/.ignore b/mingw/jeeps/.ignore new file mode 100644 index 000000000..e69de29bb diff --git a/mingw/lib/README b/mingw/lib/README new file mode 100644 index 000000000..f267f5b1c --- /dev/null +++ b/mingw/lib/README @@ -0,0 +1,2 @@ +files created with pexport/dlltool using libexpat.dll +version 1.95.8 from http://sourceforge.net/projects/expat diff --git a/mingw/lib/libexpat.a b/mingw/lib/libexpat.a new file mode 100644 index 0000000000000000000000000000000000000000..97656d9a2fb538ce63ba77a967f564b58ff6dc79 GIT binary patch literal 48984 zcmeI5>5m*o6~N15=Q7UiTuws9jvaEb+1u-2EN2fVj&_aZwIeGES}m__WAzVK-y! z4aRQ&A!B#l&)7Zi6~lcWiLfta48y}CB0TaJ#xNZCK!ihYGlt>uRS}*7ISeB=iZJ?j z#xP9$QiSQ4F$_n}ig0uvV;GM8Lxks`TnzJXitzk8V;EjMF2d3-#xQ*0Zz7!e31b+} zZHaJxmN5)3|5Jo7{){mU7rG*>jWdP;isWJA_l#k1 zjA8idpGA1%b!a{aUmp?S8-HaC!`p9(@U4A}Vfgl+MEGu-F$~{pi12-o#qjPsBK+VC zV;FvPqX<9#4PzL7`kDyu!EeLx^IanR;v>c|yuTsBuOJ_WU;j~r58h=A!*5TC@VkF8 zhT#wIVOUw|c2=XyTdj1ZwbF@On-N=C*@#+gBc83CUs_x_*N;xOl75st*MFfEx4ZBm zxd_6Y&8?Lp0h#wiFNr!AWtXG${APDPTI_FPO0$ugGHR+65AR_|}M)}s7h zQy^!Sw9t($Q zHzlJ>ATKz#2vR63Lnu18-KGB1?OddU@@gpZ$SpxERQPsBUMG2_9(RyppRSI(f z{s-f>Q@?pqgv?)hvlBGYFrrl0IwK~U=rUWprFeuJMeOpOe(OT|A5?Mb(h>2J&HJ3!KG+J3&GJmlU zHIiKUQ_FecnBq$3$r_TggZ1?&@dQ*)j=A~^#-x^zgZ-OXMyyS@zx-n>&0nw+0AMvDS3Um zlW{w`Y*rMD^O9x06VShdBw7UGoGey~lwL@ZUNYBfTjW6TM!b}q8ze~-r;D99IyKl_ zwL1@T5b1W#xn6g$85iZXCG6a@SJH@T2YFf}+0RFHmyu5<%X|t!eT72hRHTw|u6UH- zQJ9YG@P3ZdC1}{L*$aLe=CJ>p&5O~@TO=h)fnmx^5tvfF_+-4^v-7%XZjL-@alLUI zmVtiTO0%M|MEP$Z8`mt;Nn!1Dq-T!G^G4)jqodQ)FczOWd{_?QFYI320RuSL9@+up za{lQCHo~tf{v~(Ugdy$-s`^|Bk#L-`4@Xw}{UKuPD#~@Rz=M-Y7KWW{7yK@BJFexX zR6NSvoG*7+$=v}T_7HL^U5!si+FcmI!<@o;ryI${e}Bx_#U1OdODaOfn{9Q~_ylrlPqyibjX``##Bf5a7RMjB4Gi;E#^1Da z2evb|t=<9{=B+CjcH2#qr(*Gl*B)c{^1awK*c0%9n1(Xuq~u)H?sk6^^ygRx`!Fp# zJtgKrn@!ZRH}Mm`1D_}%~cp`A@~QFq16u*21$uE}@0BhE*||MHR#AioZedjrnoIvkMj< z;olj<>rliTmoa!~urshPn(@?z72P&I*@EKH@)WDddxPSyK?R0Ud{*`>9-7-o@vFvp z;nW|Ry#?PnDM;}KE$303&~h2Yd!fv-6dzR-8xzr0rWY*&+%&zTB7*N5Y!;4+UZcv! z@E)kO5?prxr*-N`d0HoC4BJ9n{a2v}htYc8=;h`%(zY~2bIFN+*Q#0x_ee%HwNJ|!JT%xb*ehzYD%-po(KM-t%aeN8C-pm^cZTWM zwxOGv+o)q>SQ?OR z4R!%OXXNHKfrD~^9L@H0dA6s0w!aDeJ&f%O1{2L~Wcy3Td7&wD*-mLWkL@>Txr}Y7 zTWPjuG~49Dger6WD6|7^n(G%t1m8E<%W%|Olht>j&Jm)Co+?jtt*v>VNU+rvk`W!E ztq&`r^Vi5+H`+SC32d;7=5f?A|snxY+Y@t_j^>&TU5VfQcYFgA(|GU zX%6u7O-_3A&$YK&)4UIQsjU4mu4s1G|3ev7wxiKwkDJ!d&x#1XZ!px>%IZSmnY(vj&_8VE&h!H}w{hk!$FJy1A(rzqiel<6Jvd91NpA91GIjK_OjX}e&9n$jbAW$v#-Dqx$Ao%LBVNSyonQp2Ku=+o`&%oBecBH%|n345$6kVZDAs+ZRpX zyR7B>8G~VB8Cj({#t{T=+Qv8`BKW?+&cjjL7;U2Z9?PT*&2xZnu)cSN_eh>jZbE8V zo*y%KrdE$t+0F>LcLnSWs`?(#v=B{nfS<6wC$^C2kb7beX`7iVb1AO>&;^G7;kO^R3`|mQ7p1 zAtSj*9dga5lvbJEkQGIeUbE_swLm?8m$noFJbm@LxI+CKLh%7bF)>QHUMME2Zc|JO z&=d#w^6J$Wg%pRZCEA}+Og&V)+P3e0-b&_-ME+VL`kCU^TA~~gn&triU2PK=(i~zF zH))zHJ+BsG6WfS7<2WyoCO5!qSCf0q$bCeS>%4BD%9cb3xlXlhE5b{p$qn$!)fPk{ zxgi$Br!#V?H)32r76kpa56gnc5g}zHf$>pji&^&W-u=Z1}{%VfUw=mhLP(G`I2o)R&F(!l~7Bv%LFL&8IpV za^C%^IZt8C?%czt+?VyvJ)~IXFAAwPyZB6h+_ZODtpmc?2EztY-sRkvBhmhg@c>U- zJ%5JH%_Q`S_KePu`LhQVoy4oCs;p&0W`T*S+m}E~GfbU%Zb~EZ(0a z-kMfzJzLseY*yJ|){dr04e+{+`_@4Hv~TTo3nBFZgH-;mIk*O@tY`P~YuL01o|G|o zXt1NO=N5rLQoLSI567%nn$rNk+Jyg9psVmFIm~LkUf!p0FZ4xOtMz_^Q~i3#YP0$P zA_<$eUNgfVVjB!sN*b){YI~a1Orog`@S{!m&jPBc)!H?L+WS0e;Vq@SZ>#(KO!U0q zrl}nl5q#fZ=uPveEq-ll&Il~PTQ=@%+S($}%;LXdSxtMd$85E=EMBj;XBwEZ*{Yvjrj6>phxP`C{B^vl=$eQttwG%-1ZMCN;nx zHtJgf_%4iL_UoeTT0Atjan|)E0ms4GJ{M>e`5Aku;$JeyiH6%KIWulZJRz?^J}!Nz^K9(b8U3Ak>{e)loE^ z0sg4^=^ur39)Q%c`tuG>=krmzycMl=);m!fT!=|$b&y7Ly+NGfiKb!dzvROM3-?QmfiF zz)liPZGbOp(tlfAeW#LRbc67PoSeMoG1qE&WtGVAij?%`TNr zGaTUYs_&U8WH{swu-y*BbG`0hGgcH=o8u;LB~$m#${0Kt_snRHt?H8`I}#+zqXB-h zdc?;2Bu^iQjM#2*Sf0I-M%UYjP3l`+brNDTnI<^EgH{uK%?Q4kAXrWPR(ZB8WX{1L zSX4ciV3kZ09O7ZCeZYuto(>N20pFwumg}3UOl@f&FxU^-a<1$)TQia-G{DPN`+y5| zY={r|#*ENbA0`(n?S&}q14bCJy0$KrQ8b+)zB1qIa21rvuoZ~c%N;Z!PeHnY(~16i z?k9`WC71&1R-00^;c?S*VA*sF#5ULqu;(5Jui6H#L>kR)fVZq(yMW!2`@eqx(#p=; z?&93quS&9(34eZ$#}h2 zZI(;xFU(cqmOON%RJ2UeTe(tb3n$~nB|-QO@8;76^fliVojpSnn8LgmSBFE0n%Jj5~H^l}%KQmdLr2aWueNR^KUJNGfWUvQ{qR cq{@e}%85!WyvnqeUQy#z+W^)}aV>%W00!-^l>h($ literal 0 HcmV?d00001 diff --git a/mingw/lib/libexpat.def b/mingw/lib/libexpat.def new file mode 100755 index 000000000..ed41244c3 --- /dev/null +++ b/mingw/lib/libexpat.def @@ -0,0 +1,64 @@ +LIBRARY LIBEXPAT.dll +EXPORTS +XML_DefaultCurrent +XML_ErrorString +XML_ExpatVersion +XML_ExpatVersionInfo +XML_ExternalEntityParserCreate +XML_FreeContentModel +XML_GetBase +XML_GetBuffer +XML_GetCurrentByteCount +XML_GetCurrentByteIndex +XML_GetCurrentColumnNumber +XML_GetCurrentLineNumber +XML_GetErrorCode +XML_GetFeatureList +XML_GetIdAttributeIndex +XML_GetInputContext +XML_GetSpecifiedAttributeCount +XML_MemFree +XML_MemMalloc +XML_MemRealloc +XML_Parse +XML_ParseBuffer +XML_ParserCreate +XML_ParserCreateNS +XML_ParserCreate_MM +XML_ParserFree +XML_ParserReset +XML_SetAttlistDeclHandler +XML_SetBase +XML_SetCdataSectionHandler +XML_SetCharacterDataHandler +XML_SetCommentHandler +XML_SetDefaultHandler +XML_SetDefaultHandlerExpand +XML_SetDoctypeDeclHandler +XML_SetElementDeclHandler +XML_SetElementHandler +XML_SetEncoding +XML_SetEndCdataSectionHandler +XML_SetEndDoctypeDeclHandler +XML_SetEndElementHandler +XML_SetEndNamespaceDeclHandler +XML_SetEntityDeclHandler +XML_SetExternalEntityRefHandler +XML_SetExternalEntityRefHandlerArg +XML_SetNamespaceDeclHandler +XML_SetNotStandaloneHandler +XML_SetNotationDeclHandler +XML_SetParamEntityParsing +XML_SetProcessingInstructionHandler +XML_SetReturnNSTriplet +XML_SetSkippedEntityHandler +XML_SetStartCdataSectionHandler +XML_SetStartDoctypeDeclHandler +XML_SetStartElementHandler +XML_SetStartNamespaceDeclHandler +XML_SetUnknownEncodingHandler +XML_SetUnparsedEntityDeclHandler +XML_SetUserData +XML_SetXmlDeclHandler +XML_UseForeignDTD +XML_UseParserAsHandlerArg diff --git a/mingw/libexpat.dll b/mingw/libexpat.dll new file mode 100644 index 0000000000000000000000000000000000000000..4c925de3579d7bc74ea0c85f4d096d0070e09da1 GIT binary patch literal 143360 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

o`}M#~TH!R_w*#*Mmjd$$ zBmS;@F=EVTE1s`+zWn<1&GYy3_v_a$zkeV&AV2@8fepJ!^GV6%hSi>Vku-qA=JY;k)Shj7LoopF4IJM_Gb1;GY@g&GB@h(}AreLCVE z3kOkUWPwQOLb03;Qa|Z88GRq2m2ebfun*vL<@xV?TZMZjFcG*0NLMdJLQSv~1v4ez zBrLi^`j>vR2V1KDXZkNQzE^uX-lP4%&z<^zR#1lq)?GuhrDP4yY|$ja`QIGjs{<$g z^%1@r-eu2~Sz3m@g34w|soI2;qw5vaYD+x*TUJoRgIiWu@(DRoC~`#Y8$cydb2Vu( zrR*d+h!rz+!Bei_Ex>;RcYyL#+-HD$d8X~;c``PJY~HliPd#R80N+moW&<|@{Q!w~ zEgs15aEtJ+Z0tBasKzX1EDTr-WIwt5j4u4AMUU_DcxUl zTOu^4r;yp#`+4jzlPcUn_iJ-UaJwqUCsGcJJAToj>s39H?!YF=JkWPK=o2HP$I5IZ z3atM+9$BgayOXU6;qag|cP!nI?_`b*2Xw1+_F~BJtKr@s1G|7LfQLa;pes2l;#AgN zPUrhv;5y*@KrtY3OyX-E$}o}e5Wl=!k1WXNc_6s8$B5+udViTbmsJ9hB1(~Ir1tab zFJ#9WJB<2OT_?=2;%P<1i*RHjZH*M(F~Yx9RY-bPy?Tj!PY>*k^Bj|C>}%oMw`|S9 zm}u!LeOO+3Dtx|7J_}2LS?vwbE8VCZ)5Xfz7u`WboMS0M`uh>-d$U3x>aA1n=x{_A z4J~$tJy1b|9#pkk1}Sx_Z1D&VxozM+22sXSeRy91?=%1p0o#C`fOCG>>orre2p0s1 zX3J^ElkV@dNeYu;GBv(Ib_a3|6bm(GYj$_l9z8s;>Np5~#~*emf;ZqWrDX#Bp#+w0SS8?A`@|^)2?`=P8WDK&SWxx?Z$guI zfg~`I_ff!d;Gob--%yq7xTV3qo;f|EK(9nLy*`f~K1S1P|1*kSn{hhP zYb*51Mw1f1ujwTU#m#%u^y0&dnGg5M_1xQ{366mbstXjC3~z#FPZjE`295!0f$M?UKoQ{Th3?lY`}7NIAA6oUA0}Vj zlt6?2cx#!qh_mi1VP()f!sw(CPG`TuNVN^s7g#4tscaj(@HtDR-_AR?SKaAo)X(E( z^_$C-S}#4Zgh@B-Ky8f*qXr~pN~d3Ig~>GV)m8%^K?DCdP;(anB9n$0gY>IRh(#t{ zV&tX3TY1%%!-rP0uWS}Crj;fwHukH>OIcCk>?{?Sjj9u7Fi9CqZj+{;Sum7ltmH$- zWhSS%P)k@kk~T9^_Z3MGUfFyqWD)q~v+Pp>-T)>8-vDBOd_(n8Ki#&aHBXxz`sX5! zR_Ew0HvPU}Zqs{_>Mtx&6W*wlM^_D%#_fAvF>5QSOz0ghO#0b%?3*wm?43|*94%`B zjn<_Y`m#7Fn7Uw28nf;ykxx5`y%E?9Yy(7(gqZTf@{<3Yw1CJXtXCAd`nOZy=++z> zaVA2G^aLu7UPTOsHgyrlgN$^FWKE|MeP@;RcpayD7-mlJ0T zYEF)xGdR6eOjlKo%O%=jw;@I-MPs(}MH0JE`Q`*_)&2+}5tku^UJJyfG1gc3IdJLb z&>C-e_=FU0qg(VpjI<_bNZ+PWQ9su`J#sh{o*dY?J%0VpX!}`J zC(#VQ|HKQb89s#5w9ngjOH!P8nQwctmwx!=M3-xTYjvrWfbo~|#BDdrlm{ooHA{;B zkQBX`mug8MCPY82>smEzg}$1DlZJH z)~8uCYsm>OJ3oBE`NkSqn7%wbJaYJY;|9GLZ5UVUhwF^XA~(9j#>HwXvRQksU@cp% zSzl+I$Jdp{1Z@Wv8GpHPhW>J`F_JGUj1xA|9zCdq%+ zA~Y4Q*8}~G@AsO!Dm2@v{q0(+#BVqfZ7-;*lsXB&sOsc0ocbZtOV4@QxVC;sy-z(| zk$$R7Kg~`0>W7q0KWCRQRVVKhS32QU57Yw%saffr651N8^ctI3zgXIA4mc0JEH)tQ zhYo4QmcYrEsH;yY(-A2bDfR=719AaJag;tP(vfkrkFw=kUFRP2z2aBRvx`3n{dLXJ zW>fJN&!*6}l}FW=ry_4PMm~!exidmdRR=@c!q^;5t{Xg!JCQymegP+;o(+4cu}eX$ zkM)wtk-Q`y#%N}r3c0PAUO!ONS9&oTxe^@%*UC-TheSH&vYu8K`>oy%IjgEVwH0 z=rLEtjy4BGH|21~aKRLFcdQ`vvhg>4wj;Q3{hS)#m_8P$)HxPXGV=_!3J&I|#G~p4 z!?r{nJ}^{-BCOy)Gc<&C@@F#p+SH@A;b;PWDHdSb!)rS8b~R`a9!A(6K|jc?}k z*-`%*PGd5!&klH~uD>~QYUJsN`D{$-tei&cn;i2cOEZ{ys?Vz@&p>0+8`-h1?l|Zd zd3s-Lbp5MR%WtWqcIynKo~d6+0n!(NcIa@R_DK{ejw_dnR-=PLxuRK~C%wwuzQA>W z3#!>8{jR#`|1bNAdZA<;%;Z;Xs1PPMzh-_`{J9Ji%)dte-d_A_=x=NK*Dp>*-foQ? z*<*O3@8^V`4WDFA3VjwXGU?>&Z*tcUy()IRc^sxsvE$6~(ARuEHa_&M+U1mephb`T zJOq8}i}|_iuZo|?;{0F4&&O+aUgZA2kDvR$j@=<}F0d2$|M?kyZcp>`Q|%r2xum|* z{bl)Cj_bAipU}ry_M6ScTOM?WgVBBMnQ8cV;pqBlZjt6Fdi|aAG)aH`V6HqYWZW6u z%n=xv9mFXQf(qhFYl`21vuuFK8PtUMS(6U_?nbTp<3mKdd~>;n8Yq40qlmM z;%4asEJI1Plp~7(&6SF3i{}eSM>}MCdxfT=OvLJPJ5w@K2ma;?3LLiJ z&>PGv@%#kvA|T(&f$sxrKuzEr3*>nma3OFxV1F0a))=Wuue#78SD6B~o?LZ`jA<@> zQ)FVi3`fu2s-42kTv_Cs(0)U&38^Y&qc3}Gnj20a)JWiKz(fE~B@(`%FH;A3^|1el z9USocpe%mZH_kIi5r$P8yRvMWlfnA_oa}J2D1GQeHscS|jNkUQ-bh5vDU0SHM2|Xb zZSYt2&ofk;QS%I9pO9_qtaD~Opm#0x5ssETWmkjFPjj@YX_>IiY@{JAUD@KTY?SS! zwJEet`evD~G#vRlKOQCRufwX>2RX@Uwt4h9j@Hq62aL3iV@$QtCd(34T8A`4F6BKTL=a>O*eY?8%+ctEv6zN2a=&gERmr((zIQzd=|*7LCCe0V z_4&FfScb@Fz$)K2n~V7CG;f*>c2#B^;Nr#3O{Y7OG|NCT();yQ)nV;J|&`>nq&#Nc{R+ z3+yvJPW(qy95cx9 zGfQOR=Ly7r($UYm`hj#9)zSPOHcca4b-f_`Esbz_Cxq=oQ@TPpP;&tpTg><@NVLr7 zU8A=C8$3$G*7MjlcI)Sex2%$=y4K!|FD?;pN9mPFkY1%XrC}t9yyYud$=1cht-`M& z4K9&0lKk&b_rO@79ryt5eiV3wXIUf7{8$#X*V&2p0N*zPF98RD9{}G3wgXx5I;^wX zJd?#Qff|{U)irfOWYUd>GTf&a!E&&cLm7UYLAs_<%b8VobDSsKbwktQjcL6rLX&+rJc^PKro-wZ{Hn zSxAF*YDhh3S&y>RmuCLJy7g9z4IWS}_CWG0wb<;PYLH;eUJ=aSq*u~}7-lzG)Tv=s z107118QHH|HMiHe^2r!Dq8ZlR_>w{>H>GxZGZWxqqtR3De5*|)cbK%0)|Wx ztL;A7RnSw(yV$`W&Oh*cK+v?NVV|n2@HC4zKZ3=`3}GM>g+zkENOf`wDO$qfM3pyMTM~TL!$-qGYs~ z8}sXIE4_*DuK^zcqeZ%wwuB)2gq_|3JyTw)Z;@m7cKKUWQ1gSwp11i(W__t0B^BWUPi&;fr+p+Ab#3 z{^X_%-zwC?CHiw015#NgwT4o*EXWc7HVzH%g5PC86;K1*0ek~+?$OCqhX_WG@yI>8`EnVnMp#Lxpr}C!~AsLF7y!3s>o_TITX@O%aP3b++(U z2(Di${xXuXm3W0?VEskn?-brxP8ZCpShO%9T`!`5%^h2z@{Pq&8`fV%?2(ur?QgKzM-6f|s!wVM%iF43`L*)UqkTJ0_%vNFO$gEO#N^{? zWd8Y@ z?CX#zxA6T3z;A)AK$yzB4)LcArK}-|q4a(juzN%4EPee;j_>L|a5SmFx^b|qu-%29 zsAe?*=gZ52K+UJZM4}UgZ`Ev8Za06%bmdANSS=gN;2zoX*lG0C#n{f43|1T^2X-sd zNNZ49b*&)Wpb=it3E`gPK$sZ-rNHe1p_Z8-r8SoImC~j=VYgn!s?mN`-PlXP!OQ4LXH%SRL=n_1HqY@CkOz*-bM|_sbQFtkNHX!)1E4T&s`@j=C_tfs9eE%WvJ760yimX@SP6vJt=yun&?R0O#4gpji1hjw7 zJpqu)-k?>;xZ#yR&F3t;O2@=@fb_5{NAKlhy6hYJ z3j2{ToW6=2G)lUr`l#7qjnFqcBlH4E2ts8Vp;K`>A|%Rl_Xyn~2py#n30XM2#cOvs zyp0uvO_WwKlWxV(`B;hH+Gow5+5Q`-4e*wHn3G^P<=81Uq*K%bYE9@5lSe5+-=0a6 z8c5++D_7M^Ok%-mVhCa)Z*D)CfsDz;8~f3Ii>81XsfTP znJKx;pb~~~Y{X_6_BBcJ*UbJs%@GuV^)h6OZen1g127_z?QGFa-sF1epU8UNqWKFG z6I7#77SZ?d9f}mF)88Crz8nAUnd?U_89IvLA;!|8Xi8mvPuFD)jw3lSeCs~BSi9QcP^aW$}kraq$-g1b=d4w26OC z^-Z0^daA$CDV#U?vJO5o>r)zy@N8ZFM|hp<&3 z&o_aCKo0NnZ5{3(aZNzs(81o>iMKPX;P5hWGkE`x?49*`Lx=UX32J=}Q>e7;w9aj_ zI+Z7|+*NW@8%H-VDi+or>2k~Z$%`rHii4O(-_8Ed=w{12TB=dcK4Kt!tK*CAjJg|9 zr+c(>?aXyU*l1;bsm^>Bj*?(%^t>Q3*)bYcOl3`cj_P1L9o^ENZ9Sc1ZQakZo>nM^ zC)k~B+I|(f$a2X2SWXCCv_*CQC>GU4$zJgaBxQJrF5YIv{j%>ySyEd=whmU+1XX6= zBUm#@5AikK^u)zUiv6YC5!7j0tus+(K-#)mqdG>GSH2dXCWXonSS>#kIBc!GUu0{o za?4m-J95+Z*4+`t)E9F`EhFru$aVIXHLO>4cIS;!XU^h{$S&S+UiBU(t7eyOI8nSh ztZ;}qHuTg}CzdgGI*4Gds6N1%wwUQBK5$T3t7UOHk0c{p#FK&J>76{if%x~3M46Dv z+?lMBUso2-@^n#Jtu^1{JnJ`)x0WhsFmYML;EeOQe_L&STuwF@18r^Zoh(uTP%7hI zzFG>#N#rIW22u!_9{pUp4YexRS@Rq6c1GdGw(EL=N+W$yx045P(wM0Qm7et1K+Tyt z=j2gjF9y;>G6vFuNSM!R%elP#h&3{>QkK!(NRXS~${<%zwLuW`yOs3#S<&QY}W(s!y_KLUaYLmrdWo9+`o)o)w)S{_vk-5Y?~YkMc00D}Q@dG_XFmV{$6b zp3Sep^otF!C6MCPveB0PU$+gj9b>Iw zQoAzNf)5zrUSK!yj=jxUb`HueZ-ofd29jsDZv;n0P7m$0=ufZ2D#?$?VD~dSyH(d3 zoIfwI{|yUgm100z<-;n)_=6VS!k5Z^TjOglNy3@wu_|*jchZ#S5#xaluK2CN?=0N? zxE}#ic}}wogm>C=OLz(E+!k){yK-&{&#oUC_cJtL+z;h?SaJUJuNfJHiFYqcK;Gk3 za;OF;TR`@>PSMqhvzruk<#n~<`~#{vJwsu2F+c3+*J;IhvIFS?JtMJ4Bm6`sgnO3g z=@sYjrRqQ^OL$%_f~NC~gsew9Ygs}wBv>lmju{DwsbrjG<1IS6ZQ-pJI5__uPaeAU&`s1ItSU+jc* zPaG4Ts^w8-i|jnGxMi`_e`jvFS-c%G!QvLRgQWwvq%FRMRV;h&`*YpFM&L!@J3s|c z4YFOyYMJa6`|c@xzZke4r~}Rh`U2koG(QPL=-(IFcfSu2nLR2%cqsdBT|F|nq0GEl z<=td$x_abQRsNBp^<(%gcOEp1^(i4-h$F+}@sLes(LXetv*^{soC`tu9TtL`!$Xto zIIvePXkk5BX=9;n>3~)jaf-bQVj$?LftnKN8wI;r8oM$a$v~TK^Q2lSbbPp%J9sq^ z0ph?9f&T!U^W0*?-HQYsRsI=?oOx2+X8JFC{U~dHC$@m*2O0V*i(AK5hxvP~0x;4X zh$Se@yScY+aX7NIOST#6eOwt^=GeWd|Uf;xy6&TGRIn-3}PL} zFpO3i!}O+XEztJ`U>oo(a2kGtftvvF@5vtgU#It5FI)8fT-G%ez03M4dXK>QQuKbL z1HJ#Dcu>=u@(&l9L(h3q7gN}+fwlPNAO_=y_AFg;OylC=O?nLHyo7^jcV-O`^g4bc{k8V}@UgR7mh$cpVa{<^daz|(R%wf$l@w9nBY15Sa3ar- z;l2pG1IV`y{kMe=qfR*yQnbAe!o;z)EB8fO>IVqt2bh)W zzdO^WF+?A4O}Obb2X)1r;KQ(;|vw_rZ0_9ip5?lxRB_KvoxCTuTFea#J0yRjO5SY@l5b-^b!5CmXB?<~f~2Kvfw)M?`l)`_x@)98 zhgN&TGj%0S32f{YZ7niF_0v7VQq-$2u(40{a8Y<9&qt|gela;JsGntROzuN1kK6^a zn|&eZ!}Z}{p!26Dbzxqk#0J7jR}ttt_%B^zHjBO2 z5cnwApH*bwYM?dX4vxj|Zk~?-7xP}iyQ??z0=<<@x^=69&)wTCH!NiCSe31leni)p z?Td7aTO#{FE978<{CXEdd))PHd40L9v~aGKuq_I(~J z^*6ooS#GgXR}a5jdsxiWtADM{%ylMKszq6;`eX4~Gj{6Wt9Oxo@`ZVcCqgnWD;Di$ zDoL3>0*(MVWJqONKYJQPnKD~1T{wC{Gp#Gh17x<&GykvRO}kp7iJU;qK2n_#sQIOG zYQ;p6tM_E9#3wukHoBv&mxnKmwqDONn)>EpC0{D2nk&qkp zbb#rRl536g(y!x5(HNr*M0Is` zwYk^xoN6R`lX=x#=>Z-dsCt0Aaq4^351u~loSnwEu$Ax6)6>S+v4hX!smZt~{dG?A zC!B~Bm^Pj7=V9Q}i>D@Ie6mirU%eN3h@9AW&L%*?L@%{Mww*P*Qc{26CCj}z+Nov*07 z9!J^^Q(B(nM$yZ=0YtY7-Y<(VF*-!27nZvDN?Eki~ z8kfeZ%fXg4(D*-KPbXW9l|C<+c1^+9cAJ9Apsuh$Df144I@zRTo5}r~4eA;uP*(!y zTQFm=J9rrI^FG4*_EX;91)k?!z_dV~zXSXncm%M&i<{=RZ2JMV{3s{3!RS5OvkAEd zQf@J{n#PgT`i{=zfciOZG@6QSdTvS0t-yFin(>}F+PT6zFA?Z+g?CQ!+@zqNogmwthO(H@DjL^e7o{5z;-#7Yc69@WQ}LB5x~H0UL@qgoNZ0+q_Azy_LNw(X>+zK zAxKA_r=zmlfEtyPjq+?3mW{0BOw}{9@w=(G^hB`uv4SmAVOf4z%L_`Y~hH`v&I*T zHykF@GomWNG78oBvaRn%}={+F_6>j$B=WI~Cw8tU|BtD$yj(Kbe9&^0Ia zvtwqPv_0ElX(o%dSte~x{b*76y81lJoGp``(gH2U|H&o`(Squ$#WGC}I>(@Gd6H{APDnRe6q*yP1}axgX6DSa?lm_XE7@!*a%ALig_R2@8>^mMfdt zn58Y+o+bMZwWM@jt74yO%%V@8g~_EFld?{j^hBSuNn0g(w!DXcuw+A!chxP})AE*Z zc!wZaeS!G10x8zA>2ATXdE<{=`P-W}(k5+k$d4*Q zh>4C`I?1kto{HXqHKeelrEIr`ceZIeNI5brp$q+$ZQ7J(E@m5|dVFbhk!qeyfd>CuT$Gd}%## zAn_^zD^9oeCr-SlI`WP4d?8@t{Y5ry)=^f>lI3%KWdJiS##}P^Qr2v1+?caHtDClb zl|yOON+u`5cWB*CedX^@ShZ@|v+Wj-T=A84awr^tqFZ==gMg!A< z3xUglae#BZGP^=@z1j53vS-uEGV8u@y;hbLjRt60-27*R&84UxnS%<-U~!QQn@?8c zdI;ysi-JH+uCx##Mxf>$9##D;Om_|Fa|??eZql8C> zFA{%SwHFy~8H+7Q$gR`}1nvaQzGv9VSgkdF{`*N^ILhhsxW(LJ?IvsVs=Rj=;;5~D zFCiOAQ#1JQZT3 z)D%)ig>_~Fu4=L;;;*IhF+v4|9+W5`q`oz@`PV19gFAqI!0o_N;Cm-2*_6%J4m-C> zzF!Z-fO~<040?Y&k10C9vb9-D*_HI{4#=DFw0~=?! zyEAu_6(-ExN_Cj7?cJ;}g@KKwOmu&t!5b9J+y|PmcZ-y`jNzQ2Sbx{Dr?bu7-hnH- zH+TCN$A5p)EN6}X&VrMrrOhZ-Ep0T;SCJEkgp+7(hr(->jF{(?5%ZMp)U&}`=doWP z{xc;YY=bvF{(IDcwccM=qcOg+6UIHt2HWCIjvP?eCMg^(E7s0ChGZ~HC8T!|TH4(b z@pg>;6bS+~H&fKJOzj%w z4!#e#PjLtTgu4#-4bQZrZrh;2_w~Siz~ew6d4B`91o#1<+hEr=Z*6?bKf>8EuvOK1TWmv7Lv+J2on=f;?z5b{uT;!1c=Xf+v`bI0B+SwyYl)>9!8BP3>KN(FN5aq3d!P_{Myp?pBa+6()lQSvXMsJ&#jlT#&rH$V9 zN}3O)jozM-3^989aoXrjOc2EA&2$>Q4ape2-OqP;tf1u@nqS&ND^T-e{5zLAjoZ&3 z$&k{rdXv*mr9Ri|`mDxrq^GRjy64!1&h)a)-Wqj!cjJ5&{>UyaOBp#D6vZzrwv0P&jn3dvoIL3@bQ13uN%_-tMi#c}AVrBRbo=$y~0OyJe=d zoMWRMzqNWrZSeM8q^)pu;n_-VZaa&{mmb}U!P~FcqSCd&+Z~QCx+}`qV`Y!GGacG& zJ9pg%8m-*Rb?&7&j@-LBFJ?ia*T+(Z%)ZC3V(~W7>TEmDO8)LQnle3@ys1kC_1?Mw zP01S9bz|~2td~&E!cv-pZ3}Z!I;!fghw`fTcxoy-Ox{EjAA?H0*f_0&#hd7&3^zUL z%SHd^25-8~I@9I9er<6KN(k4EUXE0kaYsbe*`42#I&+q8M0V+hr%Pwm?7!FI?SO;G zS}luT1A>{cqIfc@Jfo8*qss5o31mWcYw;$l1pfw$w~^9SIV|2%(gk(bP)0mt5uJvD z$=eNtm1eq4H(He;rVg=F5vq@U@34r?`53~Un zkoM1jQ+Pfd_zb*P^L`Pq7@+^|(dI3mFsA}zfX&4J9xwqQUZ*~s0;Fx;vevIM=ezX0 z-ub|T7JF-hw>KaPis^+VO47+7OC2~lIVqu#?~Zl6VOrYR25+;v?QF{IER;FJN)f0v zq>sg07)N&m_Q z2%(0M5<+2|Z1MOfs;;~B-7b$<%^^iqd0nnZ%Qa?MtIzZ>osM1YydpjK7f!LM&fwXm zF@C5M#v6LTI8c*bk;dX}VMcT=;}J2|aWz`jtC5^vG$SD~;k@*%rrlY*U3U%~3j6^0 z28hqY9SR)9Gwrckd$(SEKMoiN%mR)OX9qBfXNi~ob+Z=zFYjM?<$ed<1MBShtA{2k zZuuV0m*2OG|p5s2&fw^VzwqIkttrONgaZJYIO?D<& z9pt55bIVO#bBo-1N;jLeccCkbH#2qT1b6Uvz*9gKFdg_0(CtcAi|`hkw{d)*1zZ8# z42%LkC*C4l%~RdmygB!`z{6aRA{!v}{ibq0VwU}zC|sh{yug}B{e{Z@&Dx~(yPv7X zlWhQZu9C@xIN1hpe{xK$|Czg918afXfFA+Z0nYhvv487L^gk*8jC9UCIjP(6{K>5SnA-l$rmx<4>D(DH z?_LZ4i~-!XQq=1~6Mps|kD@kSsg4&3iQ}tNet4fbI z7$R8KX?S;G0GF+Um!xN3@3}`KY};AcI;M5W0f~JX3pnnQrFic_^j25?IOx5x2Lre>|EC6UYMMRUG%>p= zU;t+|g*>ZhcFoABpa%;$J@}NGOMr7t%_5BVzHJsh`WD^k}rYvva~@L+l@s25jVaAhoLgAI-`5QbhF&> zKh*9GAA3Q|H+jztn5BWG4O$_!N+DHjS0&*5~b8 z7%?Q3VeeERyYo+9qyDer%I38VfhA4w~l__Sg!;vD5rbxZRW0E7~B`>gX zn%iLxH&8r>i)UwRxESTMRHy74SuJb0#d3z{CFF7vFb0?b{2T4zdQs>B;2`F3b7h02 z*u(YXk&VTl|0vVOF^H2Hcj*@zrmJpi8IBmloq%_ishjlU+NdgH5ch-bE!?JeG>8*D zv-{vWW&Xvo%C?~!C#>`p4B~Pnyf%otLfRCbelP}BC#=D8lKdGHUxwg-#2J<6)BEA%$1FFjer-ED>FXc1R~zikm` zrbfX^!=^Hh2W|%X@IDRrHP8NO?%*}R1-yTeO`IO@joFUyS|n|5DXkKFINJInA=SKt z^-J96yk;B3HD?>d?XCZ5c!sd{kFUh((I9U1WYSDNl%1+&5ND;DWe_K)K_z$3OZ4zQQ=uwu+M_ zvJ)dWdBVo=68mUf!0wIWME`Nx!)5mX&V`MSzOUMd(;#m1Ow|KCjFUEblM7|FLEIH- zgSg7{*SX0brw!t!qz&RqlI!Y43hTYh+_ESJah3%Bc2>5^A}*n_y>lN<2a7l}H382v zfsw#`U>U&prdyl1pYr|Z62>`+BHV_D_}S~|cK?Y8QTB0}`(%e=9(SD3dg%DcZbOcd zwXEa*-qpRbnfVy8kISaEQ<<;1(@AY*AlG<-rZ$eWrA?w?qJwyo8*BqP`pNI}^+&)x zz|R57p50({xzaXr4*R(7kva4|jZ9|)xu-iC$T|0ahc9>7$7QGP+$;QFR_e0*MH|TN zpQZKZFEEh%RYwE4Q#ugTnadcv4EneY+d}Sl(Cl`yy9rnW$n(#DC?Iu?Jn@>_nhyKc za>JO*b<5Ff56eRJ>XBTSelnYU8!-{sZXC-Fk><6BQ+zQ7Ol-#u_nMf(!7_+1HuG5N z)iws!-$&4i5lKmjt2(zb{BNG<^5Jz1V>6$*v+1+E5$AGwsy|XUpl-5z16qcQ5HRKH zQFaJFcW`o9r-bDiPYE6&_~e|rdF~A!D?FEMpKXUfikn7tct7C@O~6jEJ$3VP)cqCN zcTGz%Hr&W)&ru-myML@4BG|_cY+NC|{np~=>+{`p!O}U#A*Kq7#x$BQYhpzX7l!>c z+rz#RZd8Atu%+xSP=u&{BYyjhc*G?9`!N)Z_@8d12%?#o1<@lZWAK);(`UJ_+UicF zw&c0DOmn+h@`+HpclB}6BW;28KjGyO&ndg>E z34%dm*cbY1p!OPq)R8Lb)$XlZ;x=;G^yqS36&uijoXm}!fSgR7 zuxC@A>?Q#kzH<39>jaB=sRluV5bQ|h7!A2a&)hj?d(&sW3Z+VGq6o+4M&Ifc&wrXT zVIZ~lPB{~E_q)TlWSi?s`~9lv%Ut%qDSabYo_PF-#X;5TN` zIrzNEGh%~{55WfH3PU@Mh*Y0dV;W!SHS!mk{kea8saQYDeloKcY&#;fDLk7I(txYX znuXGuuL8&6X058*^3f^Keex7tsj`cT(ToubP1ClA68w*JC z#xEUtEBUkHNp~>KJ^K6u>^~tHtu)%2G8D(m8sV**EZb;&Tip!{V8qGZoeRYoyAOVh zO`a9=X?ZLBA^o{r{N*d3H-A~f#b5{DjTgIEvnsX$l3|E1xx^rNo}m#50m7T zFG!rKa`sWmfi$$~YuoSPOEou2>pg>TzD+sJ@#N!GeJ(ra`kyy#!sXR@6K=jG$Gb0b z`0{FBvI3$4nGMtxubxh-uW`(N7*ID>V0q4zM?kZm%NOS7(o? z|4hV?`6_fTTKl#{>$`)_le7Z2@03Jpe!@QoX-q&Mtyp{b&*UDc-H0EF8pV*XAh2=f z`L){vHA(S2>oEtgpu}X5Q#1a8MGry%)r%+Ho?|d%B$OWnJReT#ML-8Ey zB;TA7REfm`ihCgwg$$ob-~uT@A1OiP=JRvIr-Mkod44cCt{%FeNE|1L4b{H+$>Vvj zav3ENM@YoL#`))~0RB59(^z1BMfto`{x4xzl^frzvgJtG@||VV{6GlJ?-u{KE&kc5 z`npd1Gm`L% z)j$t7U%cY^zPSHZ(mnOi9(t;g@d@X}%Wy6n;V+-hQ=#mXFQ30?UPWR&GBCQi5H+eM zf=&cha{hizSe~KhvhrtHGb^u1RbYG}_5jBV-h@yiFLD?yG1xhmqxvGhY&sgtg*bUc z_H$!-*@*Ex(J_W|Vm=Y5z1@p@Vhd+>+!hxxyS)@oXQXD|vrqYva3+!xV zlchD6rN0Xwfx@zjKy-cv(Ll{_g*IRzIcy>psWCdO=0J*@*Yt_DPOe@PZN2!Gn}|F? zf@u`#9ZH!#93(hE*y5e@=T)S5CUVT9Xh={&zd-74bfydkRSwWm&5Q_Dqzn$KDB@*d zu8ZoIqGpJfPqM*fS5laAa<-@*sF6{#O@gQ7*~Sk~|FRX?We*4OEu%o=wu-LeN}fid zBh4jc#PS#KSQeH#ou5uUEZZj~c-~e5t9(W-Dz8Y$D7!o%eyZxjClG9;SyATM#8))2 zv59L`2)VaFGshbeBD6J7lh1^h&VBH3XB$H@#2hJRl~M+ z)6g&vatG;n2avhqRO-PsZ@x68d}X>)o+_W9Ug$j82N>FfK-re6Yz}NBVx{n=SDl4E zq-u~%x;|8?27&kE=pGCO=|{ZW3&;>Qy{;rN!YBN2+tZr7bu$h_we~oub10!-(~`FqbdB ze#AN+7nx6tkZlw2mkc@33*t2+#Ihg8PgP7XYevXisc_iVa9=39WbI~2NlfHL$oZGu zB@J?m+m)z1B(;S~6CMyVa-@6>-~^gAm&{hbQGPhrt1{8#PoMlYtn%Rek6 zIkox!K>a-S&o8Q<=_*85^&{oZsvk(wkv`lHt}c9|K{4EndB%VTFCG_hw=u^xoZ8Kt1_l36HkYjEsUyw3h zPn=LB^B1#7k`zhcTAmmkl&pT;xB&d}mb;h4435qVMBhEgL&YMS7(R%hlO5hgvOA~~ z(%+LfR;8D(NPIEKmaN{xxqycZ4+&>dU64-JtCKYaVODdXL&?M|13AG!&F^@wNX(SV z7A@_s2-TJ!;RhiViJ{T-WBDkY5U8Eb7syw2ROrwuHZ%zONzd}26vig($C|LeD`x(>N6JI;V+^5gH))U#u}Ad0p*CUh6NWmn9iaz2~F&n zkgCAT9m$-nlSvM&Sdigbi=wIqPNEcww8mAMtl=dUi9@os~nSR zM$3Vaa*uPS(kilRj9Xv^Sqb*5Nc=)4Xl!9ZFT1&<#z|eK!XtbMv~yZ>Gpm2zeN`vm z*V{i!)J1oJxiHk`~{N6x=(Ty$9U1Rgp*z6``OhLZrh7njN3)hrq8?D`v zED!4@v|kYgu>w&<%3RwbVvL~e5>$zli>Xt-_~I)ZEJVt}2~}Ss=nWFoVjpu$Q^H%G z_~#(JkXtHskrgU+Q6n>Eo)u6*nBgAz1vOfKV_`fB;yMgZk>wy}e8VCd50?e}8 z_Q%R@-;bNXP2e8DJ%D=<7p3U7PjElMZN+WHZNqJgdqwScc@BD7ZAzr1z&nB0frFCv zRNs=N+nXDtw9aQ;a?1xCv#0?n?6C3h8Ex_Ek~WL}BQo^w_xZ;^ZzJFGtH>pF=vAof z;*qrM`Z%oXqgd+WqHn1BkiZSgc&-B;1~{;E_^!I?o;f5uS19+WBU!=A`ktwy4`dgM zqOl`ngCiW+Q#z}zK9G$qgbv&)XCygdkhT|O{6IcX2#f$u1;zr?0q9%^ojLCHwgOzn zwYTNtGIqEvh%4XyxZG=T8>;8+jG%Ax;(D{|Mbqap(pv`H2&|X1?RuH!q4bV=Q16u1 zQ3sTbFxoGx-bAm9wz>ngvOy;`C`cn)?!NC^2&6=c-WMqoo^Y?cGJ@)NE$)da0ydo{ zUcvjq{Kxv;$bZv5pQq`*6+9)*R?^Anoj8UjHKs9nLu!zpWbb=|4mt6}aF^@81O0ir z8yTIrY#4t(E8_2M1Zyfc!I$KuG225;#;GO!*yPw33+(at@6URuD6UZp> zC|D*LA9;*k^AZn=kVSTE^1F}*3+OsTAS^Ohv)6>#sELxGD|r$p^m43pJ6jL#Z3HPq zS#PeWO6}yqFLzbR#qJD=ydXbE-b+SEzv+%m^&4mr#@UPL3!5d(r;?1vI7tFMq9b{R zP4!1t`(5DycG^CbHj&M#42LgS4088=0wRz-+>hk?M<=%O$^uH_WvHVhd>%P26H2EB z?c2|>C#YP^8~c{Kq9@^%4>_+|JAU@X3_@p2U}CYKr>TC%(RKanOOL6W=3XM5!iH0i zf;!tqqVUzqo|pyYTa_!P5v2wdkpiVXI{KuXES_Twh(7r(9&&H+LA@5)VIHr25mVJ= z4GfLTmlZrm(;HN%BI)Ttro`hCVEm8eKRmGB&3vqn`B?9%MRo4UlBs`E??#% zdgAkwmGVG=efmrC{CMq^5N(-kD?srYR6zRUe=J_{xcqmMs(dQfNuY0&YGoxu$Vtmj zEl*U^m-A8?9$ji~8($FaA1MhL-nyYol7rDl%ln|rwL@dHK@_4eLrhP&K>H z;x1B-tZvJzJf@N9O*Gjtjmurq?=F)YmpH4nJT+*fBEo&5{D#j;e3uv`a-S&cM!#jP z9%%jy6s}A%=agd2Kw(CmNyr%mqI z>^6NLteJmCyzq?J!cWYKw%Ec}bKxhSZgR&K`;9eCpLu6SKRb7oXZg7on-_RP7x;`> z(a(xj9`|Q3jF?aFPR3{Dcn|F!cIk$)_TI)wFc>y8IV?VNp9+xveD{XUL?A?-gsAkI zv)jzY{-j6T1wQif;|Y-tt{xem$6zl+Qfh8=Iq_z2^D8*c=~Zr#PZ| zf8s)Ed@WG3mQ2vU%u9E9NMMdPMgnuZp*cR|vU| zFnWKT)UHm~EDg5Ln4$yB2u5z2;-Vk9%-gPfqBk;Vxmt!5EBvXKl~-y-rp>9bvEq7j zkTjRLm-VR}bDIiSye&R!z=3)38To9Yo6M{O9XMhs)lXVUC|Am~${W4bm#>G+nOG_*-nTZ{<*$h#49_yLEVb-{+0K(dPWn;x<0q z@ONC}CiAt>9tk!mD_AbUlJAE07?lKCIUxFNAN+$KA(QV*yp!yB{nR%V{sY4IPsp7K z=APQU1P$jeNW8{trFlV+rI;zf==hY;YfNK{T#Ot$R$)0MXa=L7rD6-)!ujU<2B|Z% zx}nU*_iR&pttcD5uywfciAehM0HM5I!}vjgQeLuh~Alr0*-?7IR^n z`Sh4n2LbbmIg50kV_H;av%H8*mey{s&fWFq^yDFP_9y0rhrMQ>Vw%T?vDvLn?cO=j z_H)-DW|oNEYCpu3Inx`O=`${mrixY<>jv=r?j!;uUOgU(6I*;>_@#AaF`zwQjHl(9 zvkwgGn>-^v*Oon2*!X(Io(QR-?E#`O$*2Qgzzsd}IMZj|?2WE&b;WM-lB;>MFLskp zpN}b+R)0wQ{V;a3H#XB3n(o;TV~`|Z1WRC`lobzfHVeYQEf6_urLtWRv#fHskt zt)_9%vnxKwEna7~Q9ow?+U@b1+_6c<(V=67*|~Xmc3VibZKIdf-{8X{(|KGFKu@ik zKtJhiDi$%d)MT()6Dy~^mFu1`Ychp-pUb1VYf>GV6N%-3`Xau1%>v zFSIo_Ef_v!xp$eX$m)w1r3Q^g&d3+Pk)K+{^@)yIF|@}a(K)_UY*K8EHnt5%r1|-6F&L_zzqwm3ySD$yjs8?)MJ8Fs$5XvWrE}56ar+ zY^H{SQhxSvy%JwBqUW9Km~aAs?Z%oHMRr{DzQ=Lkg?`$v&7ZS;b+_@!fLq(L+)5p;MU>qMnm@+mXS zfm*f3Z?suLPM+enzj2qJ$@pT~>rB$yTk+gR%l3 z=UAJkiEzotn^Fn+lG!RVuX5kWaxX0EruEZSnR$FkRG{DDzd_Ot9b`kqM0s)gUQ3_IO}1huJ~=T92T3FAD>nbo8ynIA(U^-`;W=2 zI~$Nb4+eg`Y3A@eLN2>uAvd+^SYF&9u(#zSKo)dmeU2)0K*s~D0>l#+2i z<{b?m1-MV1tR#wfH~W(g`x5d*OP%3$O6Mib(SE8z)M%M|(o98#MbR}u=&R1`6@_7A zu*l{5v+LlwuC?b1=0=IxtdvR5w4kEAHF9Dsb$m3CO7&}FC~r=a#RhL^>ncxdjUOc= zHQN{Nw>Bw-j{d{PuFFS6M3~Q+tGwY;qc;_#jFXnT25NMbUp~SLQa@ z)0e6YDI~eTdbN)oKXL-3;w@%zypIdvD$J)tlY^^rLzDAw@R_|sPlwM=e(+$xIKw>n zxNHts`)&&H9{T8pBBm4kY#a--hPCagwQsr(7B|KE7jIh9)as3w`Fsq0xp#+TWs$RZ zMzHCyKVG&?Hc0vdj}E|WX_#y6cp=EvQm?RuF(j2MMUPID{~~5|gNgeY99PO*#5_e_ zshdS+h3IU7nx7KKT;q%1R#3zP_ZLJH1x>AgS4^+vZ^DX0!h#k*mf)`F%nCJDyZ6rj|GS{XsD9AowhHCGRn z#PS!g*wvO;o=)y0(po!}yOK$Nt1q;=^@bO8DrbchbA<=BOo7%h^)l-C*cxAp9GRk8 zn%Nq?g=zV`=q-L1W7Tt+ZmxNS(j^n-Qoksj=Eq!5cPRQnK~uY@>0Q64Di{r=m~mO% z7F^wzs)j$P_V7O_65aYf-KVqVVrr|UUTo1juW0>7YenKj)-zC3g$^&6JJyVj({2~G zMe05w&s4nJ8!K;nTq=gPIe^W3QaOq`(I#JNcAN2XY@$>|e4P+Jv~8t7T9RTGtI3!A zD75XE#^Ft|=}c7l>ZbW(OMRm}qo#4CQ=TvW9pRo>|K!-jST;z)-J{s4RaeRS_fVf| zb+G{|*W%silz~Tgk18*Sua!7Swtv{Yz9>BALi&70uZzr*_q;>L$mYa)msZz9c50?XCoKDPeaw6X+3&-Ip{rSxU^Ww! zFK=Jwlbr#narnBdodJ9)GB5I(EBw*+RQPLL>oFocGCp>d>Hj^O{d}<*{%G~@y)NUZ zWo%($pVaStiBe*xF8sYO*?i^gxsnvZ0%VZsSDI2N*V>!Bk`Wt^(7EUPOXm5ET!mZn zf_Z-ydMEo>542d(oThkV*Z3=Eezx zVqd;Yt8Vu4m5KE?)C*f2S1sqd#M^y|%c(WfdwXn(pSV6E@W~u|d-C25QnqBFDoJvX zB)&YgAn_9&f3fnmD`lbdYvw3(a$&hSxu868lNE>(-g_Af4KQjzX5wX0pfc>0`C8^B z|1Il{BiEvAb+O)98i994#K-el)*GMTwV|B9YTzCqy@uG+dZQ%Hx>P!>wT9JUy-`AS zz20cWKb`=7zzejI_b0#sU_bCWz&h2xVZBjNA|(Yb1!e)40dUg)@_J+At>mKD8&~iM zz3lpMt~YK27wSO*H|*iL6)57xUMK9d-Y6kS%l_WOdZS9y5$=oE8?Cg%WKj*&0PBJ8 z0e1uU1AhXjmw&^0qhw~LcJjXmNC0i(W7o_7WWDj;?=cNRc zWnOu8$?INT**(&XNOjW){RuYkhzw)dM5Jtjv4(nGln^zNS&5Q~56a@;00R3`gUXT1 zsO7V8*h%4ci6KIMY@)0m)*X9~1e|bhgGS>7v)_82D&p6-g$~{@P<2qC7X82*8Ye+k zzQ1Hyf#8)dcugU<%F1O$;!!9bXDW}{z5h>pUjr9amHvMR1{@J(G&C~INztr)x$}PK z<<5YBLV-?#fU5~8gFp!EaL1R{5(Ntx*{t=~y1VYCX`7|H>$YZARw%4e*@k9CYDSye zjyrB)no^PT|33H5@a9YX{=2`=?(etU`8;#p-=6cF=RD^*=iED27~sX$Ba_=mHCQXw z#y>m>707KY8SGt%6K-?J^0H_VS25t@k(GnH3dCK+zhk!aZpEuA{KMx_)jRxK+rWwi zbBRzQ^F9Q|?P;I0=HeXT_AI}iLj1#X5D&lyHXJUm{x@o-=Hrz*xfq|dE7daPDUi4|eV3ne39!04lPEf*N)Gt_^Q0kc$ zhvp4%cpF-g+B1z#mc#X&?(1!YlD5j;o@|LPX zIa58vUtOqR4o(Y;*h2BD55|R2xbIYb@?NxZ1rSkK{lMRtz;W;7v$TLehaYCxj8N!ynV{LOa1Xl2 zKb%2Tfx)p@upZq1RakY~XisE4wW(g-P%mEvO_FEeT1DNUS||gOJLS_7Etgj8)}HVT zmg1bKwyyF+kLpfebK>AM`6_o<$;BLBgr_m(QY-DWehF*{L>3*@*z~;-L=q@4Qao(1 z)<*l5;Z-x_@jiTHGSnRbtHLM8e^p{NZr%LUuP4;_hgTpIQ9MPjy-H<^!^`OD5D^bu z#I5yMlKrR?S4^?pOk$}gy!w#TE!B;2mJZjSA$exL2jOEpPDPRMNg1!$OTv@5MOzCe z^fzJN)mSP*V}P};7O$i<>La3Po^s$u3#QrG-jg_g481zF<7@`WL4kFK!r!DVCfD6 z=9)ErL9y0YeMr9cfygRuj612$A&am2dW>*;%~4@o)SjakSLfdlqLd4fei;s8gx4u+ zM@)+s?eB_q-=9Q>ylOl%jWU=P?@JVY!o=V@Wqj10;}@%YW)fBxQ+vxal%f&_qLhJE zUk`L2#@(aP6dw-e3i7H#KU3|DVX&x@z7<@jq_|-e4~wjGqJJ}5+_UnY+0p)xL&@|a zKt_9_iks(_$3x3cRhkIhwR@b_Z+aj`7+keXHm2SobIU#W)-rwk`T>08)-*dNYQurG zvty3~8n@Iwk6PSM>ui42A`&VnpiE)dPW{z?xqceJGPUm%M-6h<+qwY~}d;p@bKZTTjuh9-F_3_BalnMd#^o;+Fw z3uq`(N*`5o0PaH5EuMqIkofpQQ;hp7$@t>VgC4#X*&XS~$cWF#aAaj<(7hD@`yQ{w zCunASpTo$dA%nG)Fg7D&wgaNWZ@h{dE? zzCkUzYAjf}(Vjy>L_8Pc{)YZ8-gzkAUHAhj^K%(TZ=l;SZ@sew(JJdaN<;yjQr$FSQ6D|tIlo%Ha)Wy z+Sm6gF>_h4NQTxSL7c``oXf(C`acb|JWfGTYhn>KSXfkz7kQxVg98OhnyFP^Q>jrk zq&cWxGY=~t=?D&HK#>n1!3_a_#Sw^7-dR|?&Y2^5WjpF$p(Nf(1E4CNQ{7=*a=R1) zJ_j%G3^B`Uucah3w4+Fl9J0L(xFRIF`ZaX%rO4Ytxprb{DtTl(y#6jn(P=UCGkEy- zM59eo9EbNLe2SDRSs+o-J~7^K@htVkT;KTmWJSH00Jl29DC?=xu#{YoW*1B{8_+lN zUx!#pq!5IFG^r#$iEXKjYG(&Sn^KCp(e+DZYu%mI{I)@$=La!l8cP%o?-EF2bLRM> zJcBn51jhF?*2xp9+vq@SSluntd@WVqOhPJmcy)Soh%c<_n>*d%@P`-H!=X)*QD2ucnzsWzcT^(MxXSYoW+o63&HWX1q1nfF?;GQI@CpvtCa3+t&+*&T6rR=f7 zub+xf*w$~0L(WWnK^*qO>Y%sD@U-HrBeXY)O9x1KgF|W&Q@Ia>BX~2zJ(8FE?}J*i z@!o<@lv#sXJrS?@FJFET$B{2--^4lFud2`atK0qBx3vfH`UWW8WwKT7*l}bC?~oyL zD^`7qjH}#D^K<7y>EM~#$+ZdwTx$NDJ1N{&b6WW8eyhD_&E7c@w<{oh2pv&%4#kOGjSFSS3mKAb*@Fsa!_43StIaP znJ?$h#eFAy$9Edn?)KF`=&#EUL17c>!f}F`YjZb=-;x(%>I(h1ch0p5ANhWdjf1(l zbqCJ8113>F-46%8PfY(9UpNVgJzU($C}OpTZTr>I~T@(cc=G=wEsE&Sp>38ky%~kHQl# zcQhVGAJGL`IVR2NQr~5JzN-FO?wWMzgX)h%1;w35Y6nbDb$^YQl+fu_GL$gh!0B+P zO@#3CJCGEIo~Pf1IOuvb1REmM4&38Wfv;Wf9uG)9lI~UD8XPVPMB}@Z=X+cgKnSJ? zoOEduud{4Ne|MeIPw+f&+QN(1S5`n!9FKQ7&%tJQwl@k(5FDXz6OYhCf@4hgwh8n7 z?$f>$2;1&RME(Iq7SHG>1dijI;QI-wJA)cr={SDjr#8G6Gv$!(zDlh6XEggok%b0KuuC_QvUfB0lqlt-TS_ zrdWcC@5(dnPO3g*4`+QN1v3DHU=EIjkSSLYG0uE zXsLPe!RBFR!_0ZzHfqquIH`>{bhj}<#M+(v8|xD;Q~sju+b$b5nf%15jV_p#+~j@F zi;jYd`oAzicv|OJM#T?<;DPNIoUgigrUJhB%ur1hOzqLV+<*|JDMk>g8`!D*1O?VY z=jxNabXa#Ir~%iNEZCg76>&@AtH%{!#f8f;4X@=vE;qTo=XX52R?I!>As^aT^}uHk zI`+X(3+#tc6HRA1V4mP%YmqeH&CovQ6P`^eMUPUCGo-h>UFcu@7VvT{Mq_n zrJz#Sn(@3TOvHD_&@EUE$fEXqZ8@|w8arckkFkiLSWo%HV-NPrgamrW)G^v;Ys7)Z zPPuD8W|~7`^U!cqopEd>6nJTWseX?YXM2hjPAHLy8AHrz$BrF79P-`^0gn-)ytEPJeFcAK)`3OhJRUmb z$-iQ_kXi)GB4RStL0fmSg-E*wzuad(X-PXwWSRayQ7OaP1=S5 zC5)-|%7q)Ny@Q3w6!Fb4d*xV~HtroJ{>vd+H0~Wr_Uvwqqx%945b?8>nj~Tb?Gd^8 zsD` z$37Q!%Pjksj>3`1ePYyvy(&DO55R@b@9?|{W_|wIsZ;Bw`Y|Q7o$a)rB?{8&!cXSy?7u*P)b263PRq#PpURkAQPXE00g||OATNJ z_ncif;hyu-=wM#WRr^)7wPH@AaUa@+YtQ#D9TLp0x$2C{*A~nSS-lELwwk9UJ@$S| zzV*hSv^j^u$b)D_(pT&QK|o(IwWtWwm4EnlP>QF+@{O>_qu&O5(L9pQ{qNyCH^mej zMQM^p5l80M26+14+u8(U3)vwmjqtb78BJlx7V?Eh7%onDS|Lrx1OeQEawDY)&cJm9 z=Wp<$$ZVYayB|Wp2lN)4O9zS9lQiNUfUb6z`)-A#L36S&4&-sW6z=wkgy6oX`jb#$ zuoMBIQ?U5ONKryWXq0Xi3BxF9R81W+4cs;QOiEgcfVi(6P)n3)y#;jMZpq6Z`On0Gw zOrtosJp4}Bg&|q~_e*Z@jvz&9iEJ*dU%a=V0&7l4E8YkM{(u5~p@>Q4QV)Rj-&4&~ zc}#|T6!;zrj9T|Qq(h-mkNlb}Ue%dj!NhTkRo~EvePBXx9S~U(lHpy0upVoM97y93 z!R1&s-{%=l>j-*Bmm+FU^TnjQWL3Cy;f!EvafIOBfh8fnfmP0dOzpjNucSU5hoPXr z$7@5eR>QRrahOrnyg#LCG^s#N&wzd49k_dvJAH%k|83MBoaJj%4B9U#jP5}T@Y)@` z;Rf|w8W~uFy&zBU&GIy3SDLDWSI$N4IdU;6OI9_XYIB*XP4BEt{#L5Zx2PK(%BoL~ zkhT-3Hl4&b@=+h@#UvrGH%7gX95FUIGI*Q03gh9b;vU}5lD*dHg${@JQm0PK&PL~C z6fHvnk^PZ6eINP{ZBwirMR9y%va>Ua1Vo^)y<%8Y%@{Q3P#A@y8n_Z1je|%yRO(iG z>EAoxXZp-|FP;5v4!-;HBK6pj-^bbD6J=*%fXB;DtFN6Z8Val}bsZL%sG_i8D+ zCpk`3yS6FfaSBG|AHEwE@Zco(Y0F1ZHJgx(&W+1&#toRbPVd7PaO}nD^)%t$F3Fv~ z8)z%kLk*@Y!|?Ikdm0y`g+jV`E0usvn_#|ZbUGR<21&IfRCsV}x)mSU)Lcv+EEnQU z55z{*&_`x1?%0*LNKNaTgd|MT7=aNxoBPO=!F$SbgH-2tpp2n9pCs{`>O8Eg&iK3_ zRT-s!B_jI4Cp~9O`pX_Y6JUiPLE>$Kgqew-xO06OV6!cs;)lFX|@*F%v_oiq$ zhyjPCMppe@eyH*|Mo`3i&ZT0z;5;1j-C=jq(!p~euzJ{dEpj3u4Rzmg7CntML!;YP zpL`m`IX_FJDDZ_QkzNEjluV;2EK8y!Fx>_*B&vo4nUav4t&|5*OPnV;7CD7&p`q53 zW}p(GG-sYb0+DD)05jbi(?v8f(4C0{=1ErdAetD7Xz12_qp%QblX@$5P$lGNeIX(L z!dmx9tTw$%;KpLYHz?Q#&=*o4KvQ@-78_Yo{zNi?T#+SJ60hDMqNdi8GOgZuxKFRs z`c6EZ7Fcv!Jt1b9dvZjBFy5RGt!l(+VHDQM=7bRUP4FCQ&JT6tzJnaA?ugUwqaHsN zw(DO7LQe=j7YOg8@O^{wejR!5$AZ_l zE;zT52~L}(ZEyr0I!}we;1Hx4Fg0q2JkEC>_nfO=_peW=3n$NMQCsD4m0x)FgYRJ~ z|9(N8i+^C+{vXOA)j&`u(iT=kZW=ePIbSpeVuEHs`&+SdlBQ-AGLZttd~AGvlhlx zT6V6lOS{sFdVyUi>OCR)V{17q!Um|~M{+oRi9|0o6vALwU7~qUfVTy0Tf~N1Brxm`D zFyHYdc$#Ua8{-1!0OBH#oH=sh$ls2%4tm{v;nI0e`=tWBwXPW<(U(3AJ>nW-LA<33 z*8mIRE|Ja99`ziYKlgwVCw!zQgQ5nC6EhTxgUEuy4rq`19Aa_w?jl@Yj#Kn0t{KHe zKZ-wPpsYxgH3VfTmMHFoY;rT+Km*`UfKz~WK<7I$W(dkw0nC6*KnY+qU=v_FU^n1Zz#D**fU^Mk z`zRBj0ZawV0u%s(&$7j(e32kjn5Rrxx^(H}rP|5mu0>OF($l7>O(t$iS^i>YWkvo% zC&eENNK8t|On{l1L@+CPnrMfa!7#})GE+0>1kBWA_%O_j^vs!eC(j6)lHbhCgv`{L zGbSK>1%S+i8FQF~%*?dZjLfbwl4d4m&T%9&$!W>y$eT${cTo0HIf49xWll@YNk)~f zTCddUGiJ_8Mp(KdEfuj+XC$W0PD*BG1ln@FIwDKP5ooky_SCf0M24A_e9!FESz>Wa z#+;1IWI9Co9S`XxuJ;6z%dy?{FaT$+qz9*Ekc@zy^D8gY_E)!uKML2H{C+jIiAY&P z54i)6jG=cIUG<57-|zp1qODw+`7N%GUjB$2^j!W3fBw)wK2O{P$J_QmHmI3@Wr+CS zl`FgkNY$l!Uly$tLwr{FS59H_5Lc|G-#->s93ZESaPu@zF8-T(IQ2&dC5y`DVKM=$!WLcS}JA%Q;-m8^kBq+bcy zK`$zkd>X!ket#6G@wMsqvL6)o@(7C8gMMk~`GM`g1Ny~lGL7bN8_nn7L%=`x6_A`lo&%b8Di}kwVzjgi*Q^T%CxX()T+jxkt zVyY-yqSwZc_&i1o?{>#`yZw!CBR;wNJ`(-<2LP2K!X*0jTXOAP)Eep!-F!fz-^>1w zqF%e~w_he@_;)=1(G+Pj;IiM=gJwn-cGHr7X-KF%EPMct91M&Y6ghZElyYd#Y=_;z zME7(v%$xd(WU2LV;sAPJ|A;vKxjgBX5YkC3LWe@|#Bvy{YTDaahQZK~b?W;xpnZ zPjsw2cEokUW8-3DV-^44L*E*|-qZE{`G92rJzdR|$yA#eWd%S9XaT6UNcJk2o5@Z% z{@`&$dT?YHAQQMtL((`HUhNXt!0 zPH^OAU~4illXe1gbJH`j5@%)h^r!M%?lPfxu~X%AxyoHCh8YZ1W@g&Vj10+#oJ>aQ zjOjg`Ow!Esgwz?`KC=w0h8r9)N#!ofUr_2)3FWHdvSOh)zqI&%r>e-AUm<40P&^~W zD=QaN&a!g%q9T>Jd8;Z!*`?)6i+d!@7l8KebcSoDs}u^ZlTJ_RD%>uoYDuw6aOan* z3f*N3DR0%n{L)gf0IHYnn)&CVpO+O2Q}P8eR01`zt6pjorR#2Yd4&@hmzPzR0}lnx zCB+MS#0}ucxvavuP;eHAnCZqM_H7NUTEveVB?jUwc9#mpLXpdvUjPg(ysvNkYvU!5 zs32d+M|B5B5D6eo=Fbw=8cXn}ELHSZ9-C0?gzsNbYd|3kH zu5`Mzn#l#FrIcIuLu2>-O)}*P0NFjilqnwpkUi=Nneqleih1#3b7dt{fM=pA9gm7E z%kePjQwpZQU>w-9PXHu27djU&aJs038Rbj5>@yb%<>Z~=tPp~p3GPMiN`YbSa+ivD zx(jqf=@Kej#Z=AoeAmJvnA4mKT)%L4JD#1l#ME&Ca4hVh3cV}s4VJ?s-p$e5Iii-qXeHNbe?2aw>#)BnmB{< zf91T)6S5TW+G#E)di_b!KFgU<3a-KYOms>1H;Aqi%NH-kB$ifO=1gGl3NfdU6`1Il z@#IP`FL0MSQxK&T5tz7cziGv#&KVd}@Eu6L$=z%rE8kU2+!3RrM~=xDEx#1YPjXfY zuJYx~FGN=&c$$Ekz7~=tab~gNF9%&xWtnGXsa;b^q6?D>xON8EC(X&TF*-_}g0ruG zA(LDN=GNDn*)L0T<}bM-I`aUN49*S?vJeBDnG!NfD4kul6l0$GRY+!lNjihU%q0IgB`` zvqz_82rh8s$^_;Q*9ggGj)r6x7dR7(@?Dwb=`23pr2`4 zbQWOTyPP!V&`|H;pIX-Ce_Ga6`^@rSlbF|JX^H9i6%rnhYeP>rYMnv#kU|Nkh>_LX z2XXFBo;4#m?P~J@@tAX4H`vLHJC4u2!^AWs!d~#DU9C79_koPbyA|~Yv;f)w6q@CU>L z)&q6{S^#YbZ$o%nH1dEO$C?-=%siM3@~ncn9>4-B04f41i_+c%KbY;54&Xpo13(Fg zN1jT=t3aIg8&Dqkk3oKLJ8nfD02V-YHE@yy$OJe6_XB|8<;miQMb8{dQ!3<(JytZsGGlbz83u9%X(5XY2VGJEmF)+iK5zLKD z4097R5=f6lC*8t~W>n0rcoo%HCXN}$jAw4cdBxkAJD59}iHs3%E1JwqVOU1ZXc#S{ zV@!;mNlTrYoa0Ey6r~p&rOZuo7UpAICrV6>Auo{~NmMVnmsR9<%@JaR9vY z%koRXe~X3Xj(iuSqyV3%U}8OqndGJHOpD)lq!yi1x+kPo54v-rRhZK2848V5bTMx zq6kdEeWKA6k&mT~D+y8hhC$*$zxVMCP~LTYlR;^iiwQ|6KB;`605*J;N+y?z{Que^ zeM(6VF6jd~Czlmmr)>zmPSIrrfzq!iqkx1Zag}?uiizXoY5~i74y0Mm!oK-lBRs*i zD2S-*l{=#xGg?rI(I;z!iEF~E)Cx3{zqosBlR6}TyMQ1BpVYES!Q~bOv_2Wna$;1K z&B(}f6<0uP3ntCDuehSZSs-QGCkZO)x*oxa;n(gKG5G2oBL-a$MYE+PV~|MtRBU!x z1u?fkt*?Tr+2DLM3WBZ7SzOvT7NSfmcR7m}l_g~+iSghg4a;PD$vK(1Q|Dxg2l&a4 z&{qjnQ+eS8a;6a*x*h3y_yxTfci936&IM3{I17uHG0ejJGSXlyEXpri>r8QvqgM(-dcHu7 z1g6Rh`_>J34%CgbiG3@M8srD3W3f+q#9aWDmTP$st-bRpE?WYfWC8WIG*79@BoTpO z@++5@Ei8h5tK3}~OpMk*p#gnRz@sO^Ktmv)G9WC_fv87uX{mD&DcJgSZqIZjK#nTE zkb1tW`>===7cK?vic+j^(d*r8@B-vbiq-BW^z1vK{5~hBlyJM$ zSz0;?YSqO^I3d_>G5mIfs{%zr@rs5Z3kJ;>@|Q{4MRJ$B#co;bTwE?H-9VlBLautU zNk7?0;RU}3UjS?a>;$X_)BuhFP6C#_1vg+lU?X5NU?;%Q0AA1t|ChjH-jpEbV8Hz< z_JsC>PrQhIq&Fnk-XyuHOnRnPgZIFs?~V~Lf02OnYxJ}uj9xL^|MX*^9|Qdu=*K`m z2Kq73kAZ#+^kbkO1N|82$3Q;@`Z3Utfqo41W1t@c{TS%SKtBfhG0=~Jehl(I5pk<&>07E zi6&jn`;Le1)^2FQnJkz^FzGdAR+yAD1|}iq?AtQ&b#VJ&4ug9mOdQ*0N@3Cq=5#Qr z5|J=*w3|8hCm9_RXEwpa(QZb7iKA3Z0nFtvGhyBjGYMuV%y^hoX%=P}j)~(lzT$%; z;tjzgUXS;%*TYWrrRT>z?D!N@m;d@6_D6fzAM0WNNe?@nFQfBjRL`DhlZDWC2yyQM z5%N|qUyUQ_;`8f|By-DClDX=MHfjnJ|6rA9Zb$t6TaRy5Nx@hAuevOG#Rtsizi0e} zK>R(3|MruopB%~j)K}WD-s(jQTbhM)^`&GU;8L zlt0lM`3(gStr3tv;hp^T0e3>cofvRCU{ab{0soAEiOUya{&Qeb*>um1@>vW}0V)7Q zqb>l|mD)k|sRB@)R|U+~Fe$tmK;bn2$_KQC)AS7UtAKk8OselT0G0PNfa1LXp!(5g zuqga}0ENc@DTJRV@rgJBs#V|L1f1BHetko(=1u_)ulK7#-TVG}$6tk32Y+-U<@@}4 z=CGRS{)M2m-{%)huL3Uq(;pcSFd0B5(Ko@r`uTUL1L2@KQktuqj^ZpJU>{&FU^ieF zU?*T3U=v^ipcb$KAOMO01%N!jJU|X06W{=(0a5@-fOvovzyVl593U1D4WRgu06C!Z z2;MaW@B&T(S^$Ru&432LPQW$*)tma0o@IkWltn|o8&(FMD#VvkO8-@0SVR}?=lp&L z-ZlP@JdUJ)Ed62BEpmudzo6U^tWRHePybusumFAlp!xQvfad|n0OtWi(Lfe31F#rC zc~KfOfcW@Qz~g}3fOi020O+NCQvm6JQb7N64Ge&qbO^eSZDaq+e#WlWJfREK-=H6> z|Ij#+d(!lr>3}K3Jj^`CJe8ltFW^t|ui6-uG)Fe5kElmzZq}$YIhtn8a;-&gvokEi zq#?gZ7O&)DW7t?$#m2D{*oiF5>R67ovhi#Zo5H5C4mOirZP{eWwH8`aY-u)!Ez_1` zn`g_j?Y6yayTv}v&crjg-3D1eGeWah6Q$K^c^#wwvEh$~5nQF|LGz>LUz(pWKX2Y| ze#`uUd7MRSF;F%_&mOV zFXBu23SQus@hkW$zJ{;m*YWH54g5xa6Tg|?#&73$^1Jxm{9b+^-@q$u9@}HKXnTx3 z)~>S0*{kil?Jv_U&pd`nfpMDkvS-|5+HHcTCIV#OVt%>LEVTe zh@&+IO|m9evt8rW+^%J{%e24K9@M_8{anlGDs?aE-qoGdjnc>Kr|W0y=jqGzwfc4X z_4*C^KkLH{afT^|RKo(pX2a8l7Yr?iV}@44BqL|6G;TNk-PmE|I0skGJ;?o>dxkr} z#hC6jZ8W`LIs*J$HYJ{}@-53O zkMzLOU~7ss*IH$L*t*^NiuEl}T5sw~;_n9C)POdc_!E3PFSjXdkv63*+7@GrwW(~m zwk5XJwoSHAZ4>Ns?0NQ|+xOZ(BpTTa{tm;==CVI$UuHjNqtth)?^Ey5{7t(|w?bE? ztI^f!*6G&kHt06$Ht9C&w&}L(cItNNcI)=)_URgQO}b{?VO_X>g<+mC&sbnAGL{-E zjDm5QafPwUSYxa;t~0JTZZK{%ZZd8*ZUcsP8g~Ileq#f7h^sIOre&rTrYcj7sn)dJ zw9~Z9wA-}Tw9nLFBAR*6@}cEX>qe`A=lKR(ldaiy*w$h@W^1*bw6)n7yWFm@N7|M4 zZt736r`Xf%4tu6O$G*(I!d_*svDezy+1J}Q*f-jlT^J8&Zv;D(ZDtR%EufE9_9Sal zC#wf(hH2i>9M?2!4{KYr$F!~5liE&PRF&%#x=5W;7p;rYaXPCmUYDdx(WU8px*UD3 zKGrbS@S>r?z!>F5g)!2oG)5bBparWj-k4-eF{T+E0el=ZzGa-xIl0xQndU5WwYkpR z3CfpS71l_r(i&}z!6>j=olvwT45D18djj!Ypk`_b=LLP4Zy@E>t^fjD>#pt zPXKS&%7@w`>`Vj0#A9CC0{UO5E>Y)b=4tXY1)3sFsis0BXqIVKXsR?d-~sD2>oprR z8#S9Wn>E`o5?VCJG_9JGnoeBMm1`B+NbN+744szKTD9@oByEZ|P3zERVyvvtR%vUr zwc2&sPqeq`ChPKai>^r{tr$sWeS$v3Fwn5eu-mZLun+iZGBg{!hO>rt!v#Z!p%eJa zG3FXo+-+O~*Tgk*hq)H+7HaIlC8tmDN@r4a8IU1k`?x; z8`MqeX7yopi~5+lRee(3rarAUYZ5d&HM=ysF>m|{{320z7g}GSE7FzfDnuN_>F?C% zfM?|C3-m?$FZ2?3O);by90sk)Y?A6-VGgxMSc7xGc^inbjoxm7buqh{-G;u~$?jrz zvwPWnYy;cWi(1>*(_K9MM)fV~Bz1~9P3=&hRo`_5#m4GXx;Whg-9#O$)AgcXhi-@N zIb9=qXP$ncUeMR;V+^qd6}a03ab|EBG7UL~d4@bgfuYE7FIT|1xgT?1a9?o|rm?0U znO2*Ag7I2tUTm&6|Jr=k(r&q6>9BOu^h7Ib)mgb~()2d)vYpmlJ*as$=D$v!u?4x; zO4~!WpW1fWbao5Iw3GN1m=(!i(d^B=aMBT&*%aXQN_Dhar{>gFb-aj~VH%I-G0j%Z zK8;nI2|XR?~&O?jpQQxT}OH-B4aT5sCchs!mYvN2yCGoLWmS|732 z^8dv@!~X$T2nFw+Wcx4h?BCc9+K$;h?<9OcLe~Kw3@c|9 zY;Va(l7n*CW$X&JimhR5uR&86y5s_d`hN8Xpz=F4nrm{5?V$cq+BmIVJ3~wK|Ebom z?L9|y&k8NNW4gP6!G-!2dd4uo5Mxkd&fI3$ZrCYu0-85Z8rlq}MNTl^=rnd3L%CQ^ z#l>+GxQQIgC2=X-E8qv4ufW?Rv(6l6nP8a+sX}MrELKar<#~(5AA3?(1V6M(jtaw^ z2wZ`HF2Klyj4+SQV++_Kwv?@41z?IKRT@c|>Kt{X_6F^0?ON?7?Pl#Z?RM=>ab76V z{jh63%+xpNoAk~4!}=EeF@2I@wXxlJ0drfYk>TW=f{WyoTr?Nct3^7Fn=Vs7S6`}MqaS9t$#91u(GX%BD9-u2jeCvz zj19&%<7uPUc(w~yJ^Nb*S)kgq0g~lpv)(+-oNGP@Y;^ZWGS^&SOiE&D=bw3 zey_CNXuZRlXnoT93}o_mtw(v6ZMp4$?RCfrU)uVN8Z7wo0%Inw$NJ$)Y6y;-O;>Q_ z6!lE?LG@ee`?agI_v;?k{X+MY?sMHm-2lBxzZP=h7X3^5X2aotY}ifX-Lsv%OInEO zk`%fnr=GG>5N}Pruy!B!CU=xmnQk*>nsQ9@uEKFPnKqk-n1`Fko9&P^4}r?gnS)rX zvD8}Db;;oSEDe?>ixv3Gv@W)OVg1S)!H?~=-e~3z^DX=_z7?yqHa^!@XuE6+3#>OL z*eBXqJIP(I+W$yA3Bm`hm#>_|Cad-837Ux-R-@B!8mlH=lcYJQk;c|8?QZQ}?LK@~ zyh(erZcLZdIYK{5e>Iu%9L8AzSHzWa72GIu9M&1XFz+(&Ht#j>Lu+X?c`T0w))@ON z?p~|1(R>_M5^vjnU@x*iVE5R+z`73Kq(hwtVohnnI`T308TJcyp!!kG0nO_e9qpPM zwQB9t+P~_xkYMgL-oee`YPt2MpNf3xZJ)ztb6tpSfNijCq|IpKZ7H^NTb6CE z?LONNZO_}V;)dcJ?tHY1m;<8;xjH3RWm3Se@LD70J(yPa1!3JY&3Q%mNLa<1TSZ z(;=*7KQSd?b@n&&N7lbs|8D)#`mJ>!KZGC2kKym&HCU@Vuujjz8vRFnHCEwoV!ib- ze}UKAer4Nh+i!c(&Q!@n`8x)B2_tI{=p@|iFWBd=kmbgxC#WZ?S;#9tS3d=L^H4zA zJg2@{ldj2x_G4a;nfN75kYA6`-l`oB*<254W;tZ>_1ed^zXW|YXq&ZfX+O}O(te|r z=`6ZL-MzYnkZ$UAKhr&db=yAO0o@xqukJIQUpE50%B25={tx;WA>EwO4>F84+yjYk zvEd2BGoXr(pb?m4v|v5wGOonh?T^M|#!rmHxp5eE0#>(=ahti{aL;jjxf@I)O$$s< zo9fJ4!DZUeCWlC#(I;}-=&|Uzh7Sk zUb{oTNB^?EQGZdz)*+N+cHA4WjnD zq1$-XeAN7@`8G?T#cg@Za@2Cpa@jJ-I@~(idK+fw479cu5-!7!;8Q{E@A0v=TS4Cr zTehtjw7m*Co2P8A*gmvr?a6j#vrPQ9SMgdqOH`f!906R zYtYfV18LJwWr{ORfHtOE;!HB7n9@v+uGyf}TwxY4CRd0nq}ncB%qH_@^EUH#^UfaJ zvdP>mN+KtrjX7=cTCSAkgX>dOKugmt*{A(~Xs-6z8m?H&pN1~ytgYR4p=&MHdu5MC zH^`V2@J$D_d)J<;*Rku_tF7C-SRJ*iFQ_}fV;K#5l~rwycAhp*Tc9n{mTD`s+pnVK z=$3I#V+{3PE$O=SXwpiL_-pM|bsydHd9$(S>Q-rrHpQ4?O}+c}yL<7w`>X++wv|5( zy%1Jcc;T8%+)teVu2Z9~Rj*fX!0fYG&9vd$stAs}iZ=E7_};*7WH({Wx(ocRnUz+; zLa!Cocj=D^vu(iXSzWvC0x6BLlSg`1g+5xZ(8vcj0u~*Z>?&8xho~gF|Pd^6wG0=~Jehl?V(>A@|PST|GhUKX5GQG%rOvU>IzHrhkJ+=Q zb*idVRRtBQM1?9LRY*uk2&odNs-UV6NEN6E^?^s85Dz>c{sNv5<@@HcbKkR5g3-!5 z((KwZ-|X(p{`NcH%r~>U=TIYAS~}X_mUJ*GC5@hFOV= zI|(7L6S8ZZkel8kynT@njCb9{;yu411Y>=j#ryXWg7JYGix2*p5R8xflEs17 z2*Eh?9E+n9gkU_dgT;fN5Q6d0`z${75+N8TpJs9Tc0w?o_y>z8|3nDJxp!GSy+#Pe z`I9W3-$e+<3x8wr*$)W8`1~S^je7~fxb$}xmw!PB#?~t=wjU=1WBgARzx4+~Fs5&_ z_~Ixb7_a<`#h2kaFn;?yi%?a9@%0Z`{BBGL#_!$D;+uaY1mpKFviO6YgkXFdt^wl@ zPqFyUgM?uG5!3_YkKbYOC(jdt@u$04{Mqja!T9bQEdCs>1LJ#lviSaA3BmZQ*I4{; zFCiFz{TCL0`vD;sKY}*I`1^ZV{P+_>KK^83q1{@H*4G;8iwli~R@_*P$il)()M%<1 zWZ}Zx?83Qjbh?prqvUA!=|~l1uHGPL- zIu6g(=ZSaZiz|qm?)pjRd~fa>tWMyI>~9Ql->X5;f9jVQx-6H4{~`O!-su zK5@)3rG2uBS}i&oD>jdr`Uqzb61cm()=&Lt!gxs2IxP)xSk zi71_4iJobC$t!8(Y6pH=CEG6Ny1`00p3Tb%Xywxn zl@p0V#?U4xL6a~aX`}Z!PUoOu+v;7g^RR^eyRSaJYS}y~b`{^t&7M$-!#q4Mx&^2u;}Q8U4R2iam_`n1rUM;y#6TS_7#ryE2k>XaE5S03KzDRtvD@tC9J3fYb7X#|p?evtdLj%JQAq1QB9gzAcI2@Y>7)B*WxC~Fi-AAA9$K6|R;Z}qr z1b+|R-U$183*i{r#CmvOusj#-rBrv%5!PXVFA%NDhg7lA?O{iHue6e27w82oFG8V36#>G@dNfNCW;BIyYxZ zi0qhwZ!AyFNB2Z=y2ow0-+(*bkM4^K74;3I`2^-jDYG?kKePh|N%qq$fo^N$S=dXmoz*vVv}Y=lJ*$lM;l>UWXS&kZ^saEU#WRvI z9ip)h3a06NFXz0KO{1~>O`xNlC+E}HCDy3EgK0~`NAp;5n#b)?jLN!}H1CDGRMfgYpwaA@r$+C4 zdHo&uyM;m8ASYP@-PXuAV6PGFXaWb-PAMPR0Uo>q_DFI?_Gcq|TqD~xxv<>2dOzn_ zl0B=DyB_qk?C1Wegmn%=R?SIKd!wG%OFyLXFJ9-@^JZ ztFB{g=lTc^@CHuU<9Khu06@QSJaryJeFMkw68E^9HD3t5LKyf?jAdBkc;9i$Wd!5M zY*9OUL=c?2Fss}&KSWzqrTHvR!Cj49f~}xAw;6P_`-u8D5AYmT^Wx}zGMcaElz`Fu7{H;}!n)}5m;Nf^Qz^hn|;^lH2VnGiHj$Nx*sWvO`m`9zq zlB%cuqj;|B>+0Dp;iEagi&*ssuNuvR3e7MsYplC2x7D%7qS@acbgwDbbhAgq$8&%O zvEuov@%&iEv+F$on}}yu^$qpx7V+^M;4_@C$D*s=p&YLZ=^YLTp7lkb`gVm`J5yosZ>$E8{iC^dMTn!EVh@{y4rYJa5nQf4e*&fsX-7B?xb52J? zJcyNkMznoohv?^r6|#*fXQd`OOg}e`s+;=R&iCo(059UW-A}CMbx13t4uluApdV5w zc1$rVHObhMz#uJ+<1B%0YvgONmzGA;QGJVMr;Ly20Dob%zJ=ZspI)v*Zc(BiRET!X zEGx6M5wgAotPNN7Eu`H-9;QbEe23NQ*<7YW-cj&H$uxf-X}PWDkkzx|UDM_`M)nF; zpItl>;2EsmQjp7P$Xf~?$XM0iiCbp98}gQde1lkT6Ysl=Mnb%Rwl!Rhxk+m{q))fs zU{`&+Z<+ZGnQO%PRjY2;46gT9`|O1P?_V`%E>{PKaJ)}&?C7s-7LFZN*Ex0y_&5&m z?^Uxhaybr}Gk1T+vFnBO<+g$M&{k4MC;YRF-0$PpW*K=zd^`vE^eWppm*)`Mc(0r1 zQjfBQ*v2}fMvu>8izD6>5g!md$m-IlO2ee4GK>MA=Tm)#IM zqMotq`lih0u_N5y%hBuzkBE=w0IyxOmgK7Od|$@1;~PhCmNM()I&CG@E}rBmxYOSV zbH{hGWK`Hub=?AX3V8JFaDZnHKL$;M{K81}4rb}y*bR&q z)w6d~jNts64u z;Vw!m`?ekX24=Y}gTiwj)G8~m>d8J<1N?2nwgp>hR;gJ-SiMtWm3})Eo`N!KR{T}L zAT{g5EP-y7Z-_7`+2>N_FoKrqBQ?OIHe%ZVuY!u{*Vnqh)e!FL8`#&{=x>PN?_g0I z;0}dU`N7|E(|QM`Ql&NPu0l?YoPaI00~nXG+Lm@zvwYl!c+Tv%T~*vl4I9Gk?H0H2 zO?v0`tPwDQlFmz&nG9+&uHyJ5y=$v##CJYa*iJ%C?; z>1W5za#e)8`Ucvu=auuqsf8xAdl# z>}&L@4Nzx|LANzB0()r#SgI5fd|U?jvZ|2)+S(jr!Fk4Ihz{LNxtxnu&qR%OyR(D` z-V`GNN|lvvm6qxubtu5AHDr$jR9;uvquK?u71f|O3sUD8sAZ<~X8Qc9T2#Cniamc% zz>aEB;E`8Xhcrv{F&f~ps%8ezyW!KOAu|JR5{&Xe)iN_$cxC`FY7VH%Bp;svKC0^N zHo1K6h1{Y#^hV0(i71_4i;R9}i2cpES3wQ+>tAgaKS9V!g<;-wRMKgJRiB0hpWwv0K*orMh0GR%VoFcR=6`ob@B~@+?jZ-mrix! zG+IYRTxLC7*uw?nYSq@kHL`r%26(teZH-&4J(vBlkS`KlpK&XVh?%$&}=}H~6))eGCWqyGHC$*~)5=42S66F9?Q@M_?`_(QK<*dKbXTa5+Bcg3fZL;7yl8Z=K{Nu$lycjG!&R^5rQn(bpaz}HqWeAO7<;b2%eG0Hr4 z7Bc>zFwCm%WmshU7!L5qRdX7084j7#uw5|BXYG}l+ro1iz>3HwDQ2%eP!oNO26)!0 zISsjthRkXBT*hdl3j+PcaRv(Y zoyF-K42ZSM&1qrJuT^aYSVx|Z+yD<+H5(^av+jl5qT{&RD7pFv?z9CbCD*ovXXE5F zfx>gHl#lEXzgne}5pCc2LWoY@%E?}9q~{};kJE`~;^odJ(aF>6MzuADtvnyOm2Yju zJ?sLTW)F#`_@!yRkPPf_t6^QTdP(;qMG&U*^t#cTNthA2A+p` zyzwPCZkfjr3a@~q?p|JHRlO=L;azDq7~nyx=Gx@4irS^9wM!_g{H57^;1UmBW?l== OwK1x#AZz8=8umYS0vyEv literal 0 HcmV?d00001 diff --git a/mingw/mkwintesto.c b/mingw/mkwintesto.c new file mode 100644 index 000000000..cd87679db --- /dev/null +++ b/mingw/mkwintesto.c @@ -0,0 +1,475 @@ +/* + File for "converting" GPSBabel's testo shell script into + MS Windows NT/2000/XP command script. + + It is limited to: + - testo using the shell variable PNAME for the executable program being tested + - testo using ${TMPDIR} for the temporary directory in which test files are created + - testo using compare as the name of a shell function for comparing test results + - no other shell script conversion is performed apart from whole line comments; + unconverted script is discarded, not even included as comments in the output + + Copyright (C) 2003 Mark Bradley, mrcb.sf.gpsb@osps.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + + +#include +#include +#include + +#define LINELENGTH 256 +#define MYNAME "MkWinTesto" + +/* ------------------------------------------------------------------------------------ */ +int f_outputLine ( + FILE *pfWhere, + char *pcWhat) +{ + int iLength; + int iThisChar; + + /* =========================== + Return 0 = output has new line + Return 1 = line ended on \ for continuation and no new line + */ + + iLength = strlen(pcWhat); + if (iLength > 2) { + if ((*(pcWhat+iLength-3) == '\\') && + (*(pcWhat+iLength-2) == '\r') && + (*(pcWhat+iLength-1) == '\n')) { + + for (iThisChar=0; iThisChar < iLength-3; iThisChar++) + fputc(*(pcWhat+iThisChar), pfWhere); + return 1; + } + } + if (iLength > 1) { + if ((*(pcWhat+iLength-2) == '\\') && + (*(pcWhat+iLength-1) == '\n')) { + + for (iThisChar=0; iThisChar < iLength-2; iThisChar++) + fputc(*(pcWhat+iThisChar), pfWhere); + return 1; + } + } + if (iLength > 0) { + if (*(pcWhat+iLength-1) == '\\') { + + for (iThisChar=0; iThisChar < iLength-1; iThisChar++) + fputc(*(pcWhat+iThisChar), pfWhere); + return 1; + } + } + + fputs(pcWhat, pfWhere); + fputs("\r\n", pfWhere); + return 0; +} + +/* ------------------------------------------------------------------------------------ */ +void +fatal(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + +/* ------------------------------------------------------------------------------------ */ +int main( +int argc, + char *argv[]) +{ + char acLineIn[LINELENGTH]; + char acLineOut[LINELENGTH]; + char *pcTerm; + + int iThisChar; + int iStart; + int iTarget; + int iTranslateQuotes; + int iQuoteCount; + int iPrevLineContinues = 0; + int iEchoLevel = 0; + + FILE *pfTestoIn; + FILE *pfTestoOut; + + /* =========================== */ + + if (argc < 2) { + fatal(MYNAME ": needs a single parameter, the (testo) file to convert\n"); + } + pfTestoIn = fopen(argv[1], "rb"); + + if (pfTestoIn == NULL) { + fatal(MYNAME ": %s for reading\n",argv[1]); + } + else { + pfTestoOut = fopen ("wintesto.cmd", "wb"); + if (pfTestoOut == NULL) { + fatal (MYNAME ": wintesto.cmd for writing\n"); + } + else { + + /* Output the .CMD preamble */ + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "REM"); + f_outputLine(pfTestoOut, "REM Simple Windows NT/2000/XP .cmd version of GPSBabel testo script"); + f_outputLine(pfTestoOut, "REM"); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, "SET GPSBABEL_FREEZE_TIME=y"); + f_outputLine(pfTestoOut, "SET TMPDIR=%TEMP%\\WINTESTO"); + f_outputLine(pfTestoOut, "MKDIR %TMPDIR% 2>NUL:"); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, "GOTO :REALSTART"); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, "REM =================================="); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, ":CommonCOMPARE"); + f_outputLine(pfTestoOut, "SET PARAM1=%2"); + f_outputLine(pfTestoOut, "SET PARAM2=%3"); + f_outputLine(pfTestoOut, "REM Test if param3 was a dir rather than a file, if so add a \\* to make fc work"); + f_outputLine(pfTestoOut, "FOR %%A IN (%3) DO IF \"d--------\"==\"%%~aA\" SET PARAM2=%3\\*"); + f_outputLine(pfTestoOut, "FOR /f \"delims=\" %%a IN ('fc %PARAM1% %PARAM2%') DO IF \"x%%a\"==\"xFC: no differences encountered\" GOTO :EOF"); + f_outputLine(pfTestoOut, "REM Show the first 5 lines of difference"); + f_outputLine(pfTestoOut, "fc %1 /LB5 %PARAM1% %PARAM2%"); + f_outputLine(pfTestoOut, "if errorlevel 1 ECHO %* are not the same (first 5 differences above) - pausing. ^C to quit if required"); + f_outputLine(pfTestoOut, "if errorlevel 1 PAUSE"); + f_outputLine(pfTestoOut, "GOTO :EOF"); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, "REM =================================="); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, ":COMPARE"); + f_outputLine(pfTestoOut, "CALL :CommonCOMPARE /L %1 %2"); + f_outputLine(pfTestoOut, "GOTO :EOF"); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, "REM =================================="); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, ":BINCOMPARE"); + f_outputLine(pfTestoOut, "CALL :CommonCOMPARE /B %1 %2"); + f_outputLine(pfTestoOut, "GOTO :EOF"); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, "REM =================================="); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, ":SORTandCOMPARE"); + f_outputLine(pfTestoOut, "SORT <%1 >%TMPDIR%\\s1"); + f_outputLine(pfTestoOut, "SORT <%2 >%TMPDIR%\\s2"); + f_outputLine(pfTestoOut, "CALL :COMPARE %TMPDIR%\\s1 %TMPDIR%\\s2"); + f_outputLine(pfTestoOut, "GOTO :EOF"); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, "REM =================================="); + f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, ":REALSTART"); + f_outputLine(pfTestoOut, ""); + + + + while (! feof(pfTestoIn)) { + /* Read in the next line or stop if done */ + fgets(acLineIn, LINELENGTH-1, pfTestoIn); + if (acLineIn == NULL) break; + + /* Is the whole line a comment? Replace the hash with REM and output the rest */ + if (acLineIn[0] == '#') { + acLineOut[0]='\0'; + strcat (acLineOut,"REM"); + iTarget = 3; + + /* Add a space after the REM if the next char in the source isn't space */ + /* We're trying to preserve the original as much as possible */ + if (acLineIn[1] != ' ') { + strcat (acLineOut, " "); + iTarget++; + } + + /* Strip out any ending new lines */ + for (iThisChar=1; iThisChar 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + iPrevLineContinues = f_outputLine(pfTestoOut, acLineOut); + } /* Is the whole line a comment? */ + + /* Are we near the top of testo where the program variable is defined? */ + else if (strncmp("PNAME=${PNAME:-",acLineIn,15) == 0) { + acLineOut[0]='\0'; + strcat (acLineOut,"SET PNAME="); + /* Copy the rest of the PNAME assignment stopping at a close } or EOL */ + for (iThisChar=15; iThisChar 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + iPrevLineContinues = f_outputLine(pfTestoOut, acLineOut); + if (iPrevLineContinues == 1) f_outputLine(pfTestoOut, ""); + iPrevLineContinues = f_outputLine(pfTestoOut, "IF NOT EXIST %PNAME%.EXE ECHO Can't find %PNAME%&& GOTO :EOF"); + /* fputs("\r\n"); */ + } /* Are we near the top of testo where the program variable is defined? */ + + else { + /* Every other line.... */ + iStart = 0; + iTarget = 0; + iTranslateQuotes = 0; + iQuoteCount = 0; + acLineOut[0] = '\0'; + + /* Is this one of the test sequences mostly (all?) starting with a cleanup? */ + if (strncmp("rm -f ",acLineIn,6) == 0) { + if (iEchoLevel > 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + iStart = 6; + strcat(acLineOut, "DEL "); + iTarget = 4; + } + /* Is this one of the test sequences where the program is run? */ + if (strncmp("${PNAME} ",acLineIn,9) == 0) { + iStart = 9; + iEchoLevel++; + strcat(acLineOut, "%PNAME% "); + iTarget = 8; + } + /* Is this one of the test sequences where we compare the rest? */ + if (strncmp("compare ",acLineIn,8) == 0) { + if (iEchoLevel > 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + iStart = 8; + strcat(acLineOut, "CALL :COMPARE "); + iTarget = 14; + } + /* Is this one of the test sequences where we compare the rest? */ + if (strncmp("bincompare ",acLineIn,11) == 0) { + if (iEchoLevel > 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + iStart = 11; + strcat(acLineOut, "CALL :BINCOMPARE "); + iTarget = 17; + } + /* Is this one of the test sequences where we compare the rest? */ + if (strncmp("sort_and_compare ",acLineIn,17) == 0) { + if (iEchoLevel > 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + iStart = 17; + strcat(acLineOut, "CALL :SORTandCOMPARE "); + iTarget = 21; + } + /* Is this one of the test sequences where we prepare some data? */ + if (strncmp("echo \"",acLineIn,6) == 0) { + if (iEchoLevel > 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + iStart = 6; + strcat(acLineOut, "ECHO "); + iTarget = 5; + iTranslateQuotes = 1; + iQuoteCount = 1; + } + /* Is this one of the test sequences where we prepare some data? */ + if (strncmp("cat ",acLineIn,4) == 0) { + if (iEchoLevel > 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + iStart = 4; + strcat(acLineOut, "TYPE "); + iTarget = 5; + } + /* Is this one of the test sequences where we prepare some data by using sed? */ + /* we only cater for sed that removes lines - this is only windows after all */ + if (strncmp("sed '/",acLineIn,6) == 0) { + pcTerm = strstr(acLineIn+6,"/d'"); + + /* Did we find a terminator in the string? */ + if ((pcTerm != NULL) && ((pcTerm - acLineIn) < LINELENGTH)) { + if (iEchoLevel > 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + iStart = 6; + strcat(acLineOut, "FINDSTR /V /R /C:\""); + iTarget = 18; + for (iThisChar=6; iThisChar<(pcTerm - acLineIn); iThisChar++) { + acLineOut[iTarget++] = acLineIn[iStart++]; + } + acLineOut[iTarget++] = (char)0; + strcat(acLineOut, "\""); + iStart += 3; /* skip over the terminator of the sed command */ + } /* Did we find a terminator in the string? */ + } + if ((iStart > 0) || + (iPrevLineContinues == 1)) { + + if (iStart == 0) { + /* Didn't match, so can only possibly be a continued line + Skip spaces, then process the rest of line as "normal" */ + for (iThisChar=0; iThisChar 0) ? 0 : 1; + iTarget--; + continue; + } + if (acLineIn[iThisChar] == '%') { + if (iQuoteCount == 1) { + /* Need to double up the number of %s */ + acLineOut[iTarget+iThisChar-iStart] = '%'; + iTarget++; + } + /* This also caters for where we're not in quotes, + so must just copy the % once */ + acLineOut[iTarget+iThisChar-iStart] = '%'; + continue; + } + if (acLineIn[iThisChar] == '>') { + if (acLineIn[iThisChar-1] == ' ') { + /* Need to remove any spaces between echo and redirection + as NT/2000/XP adds this to the output and mostly this is NOT wanted */ + iTarget--; + } + acLineOut[iTarget+iThisChar-iStart] = '>'; + continue; + } + if (strncmp("${TMPDIR}",acLineIn+iThisChar,9) == 0) { + strcpy(acLineOut+iTarget+iThisChar-iStart,"%TMPDIR%"); + /* %TMPDIR% is one char shorter than ${TMPDIR} */ + iTarget--; + /* skip forward to the end of the string matched + (less one as the loop will add one) */ + iThisChar += 8; + } else if (strncmp("${PNAME} ",acLineIn+iThisChar,9) == 0) { + strcpy(acLineOut+iTarget+iThisChar-iStart,"%PNAME% "); + /* one char shorter */ + iTarget--; + /* skip forward to the end of the string matched + (less one as the loop will add one) */ + iThisChar += 8; + } else if (acLineIn[iThisChar] == '/') { + acLineOut[iTarget+iThisChar-iStart] = '\\'; + } else { + /* part of a literal, so copy the text */ + acLineOut[iTarget+iThisChar-iStart] = acLineIn[iThisChar]; + } + } /* for */ + if ((iEchoLevel == 1) && (iPrevLineContinues != 1)) { + f_outputLine(pfTestoOut, "@echo on"); + f_outputLine(pfTestoOut, "@echo Testing..."); + } + iPrevLineContinues = f_outputLine(pfTestoOut, acLineOut); + /* fputs("\r\n"); */ + } + else { + /* We didn't match the start of the line, so + - if blank, print it + */ + if (iEchoLevel > 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + if ((acLineIn[0] == '\n') || + (acLineIn[0] == '\0') || + ((acLineIn[0] == '\r') && (acLineIn[1] == '\n') && (acLineIn[2] == '\0'))) { + iPrevLineContinues = f_outputLine(pfTestoOut, ""); + } + + } /* else... didn't match a start of line - so check rest of line */ + + } /* else ... catchall to mathing things on the start of the line */ + + } /* while */ + + /* We're done */ + fclose(pfTestoIn); + fclose(pfTestoOut); + } + } +} diff --git a/mingw/shapelib/.ignore b/mingw/shapelib/.ignore new file mode 100644 index 000000000..e69de29bb diff --git a/mingw/testo b/mingw/testo new file mode 100755 index 000000000..cce08aa19 --- /dev/null +++ b/mingw/testo @@ -0,0 +1,5 @@ +export PNAME="wine -- mingw/gpsbabel" + +cd .. +exec ./testo + diff --git a/mingw/wintesto.cmd b/mingw/wintesto.cmd new file mode 100644 index 000000000..1d575898f --- /dev/null +++ b/mingw/wintesto.cmd @@ -0,0 +1,1600 @@ +@echo off +REM +REM Simple Windows NT/2000/XP .cmd version of GPSBabel testo script +REM + +SET GPSBABEL_FREEZE_TIME=y +SET TMPDIR=%TEMP%\WINTESTO +MKDIR %TMPDIR% 2>NUL: + +GOTO :REALSTART + +REM ================================== + +:CommonCOMPARE +SET PARAM1=%2 +SET PARAM2=%3 +REM Test if param3 was a dir rather than a file, if so add a \* to make fc work +FOR %%A IN (%3) DO IF "d--------"=="%%~aA" SET PARAM2=%3\* +FOR /f "delims=" %%a IN ('fc %PARAM1% %PARAM2%') DO IF "x%%a"=="xFC: no differences encountered" GOTO :EOF +REM Show the first 5 lines of difference +fc %1 /LB5 %PARAM1% %PARAM2% +if errorlevel 1 ECHO %* are not the same (first 5 differences above) - pausing. ^C to quit if required +if errorlevel 1 PAUSE +GOTO :EOF + +REM ================================== + +:COMPARE +CALL :CommonCOMPARE /L %1 %2 +GOTO :EOF + +REM ================================== + +:BINCOMPARE +CALL :CommonCOMPARE /B %1 %2 +GOTO :EOF + +REM ================================== + +:SORTandCOMPARE +SORT <%1 >%TMPDIR%\s1 +SORT <%2 >%TMPDIR%\s2 +CALL :COMPARE %TMPDIR%\s1 %TMPDIR%\s2 +GOTO :EOF + +REM ================================== + +:REALSTART + + +REM Turn on GNU libc instrumentation. + +SET PNAME=.\gpsbabel +IF NOT EXIST %PNAME%.EXE ECHO Can't find %PNAME%&& GOTO :EOF + + + + + +REM Some formats are just too boring to test. The ones that +REM are xcsv include +REM garmin301 +REM garmin_poi +REM gpsdrivetrack +REM nima +REM mapconverter +REM geonet +REM saplus +REM s_and_t +REM Geocaching .loc +DEL %TMPDIR%\gl.loc +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o geo -F %TMPDIR%\gl.loc +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gl.loc reference + +REM GPSUtil +DEL %TMPDIR%\gu.wpt %TMPDIR%\1.gpx %TMPDIR%\2.gpx +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o gpsutil -F %TMPDIR%\gu.wpt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gu.wpt reference +@echo on +@echo Testing... +%PNAME% -i gpsutil -f %TMPDIR%\gu.wpt -o gpx -F %TMPDIR%\1.gpx +%PNAME% -i gpsutil -f reference\gu.wpt -o gpx -F %TMPDIR%\2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\1.gpx %TMPDIR%\2.gpx + +REM GPSman +DEL %TMPDIR%\gm.gm %TMPDIR%\gm.gm+ +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o gpsman -F %TMPDIR%\gm.gm +%PNAME% -i gpsman -f %TMPDIR%\gm.gm -o gpsutil -F %TMPDIR%\gm.gm+ +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gm.gm+ %TMPDIR%\gu.wpt + +REM GPX +DEL %TMPDIR%\gl.gpx %TMPDIR%\gpx.gpx +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o gpx -F %TMPDIR%\gl.gpx +%PNAME% -i gpx -f %TMPDIR%\gl.gpx -o gpsutil -F %TMPDIR%\gpx.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gpx.gpx %TMPDIR%\gu.wpt + +REM GTM +DEL %TMPDIR%\gl.gpx %TMPDIR%\gpx.gpx +@echo on +@echo Testing... +%PNAME% -i gtm -f reference\sample.gtm -o gpx -F %TMPDIR%\gtm1.gpx +%PNAME% -i gpx -f %TMPDIR%\gtm1.gpx -o gtm -F %TMPDIR%\gtm.gtm +%PNAME% -i gtm -f %TMPDIR%\gtm.gtm -o gpx -F %TMPDIR%\gtm2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gtm1.gpx %TMPDIR%\gtm2.gpx +CALL :COMPARE %TMPDIR%\gtm.gtm reference\sample.gtm + +REM Magellan Mapsend +DEL %TMPDIR%\mm.mapsend %TMPDIR%\mm.gps +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o mapsend -F %TMPDIR%\mm.mapsend +%PNAME% -i mapsend -f %TMPDIR%\mm.mapsend -o gpsutil -F %TMPDIR%\mm.gps +@echo off +@echo. +CALL :COMPARE %TMPDIR%\mm.gps %TMPDIR%\gu.wpt + +REM Magellan serial +REM TODO + +REM Tiger +REM This one is a little tacky, becuase it's a very lossy format. +REM so we simply test we can write it, and then read it and write it and +REM get an identical file back. +DEL %TMPDIR%\tiger +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o tiger -F %TMPDIR%\tiger +%PNAME% -i tiger -f %TMPDIR%\tiger -o tiger -F %TMPDIR%\tiger2 +@echo off +@echo. +CALL :COMPARE %TMPDIR%\tiger %TMPDIR%\tiger2 + +REM +REM Lowrance USR. Binary, and also slightly lossy because of the math to +REM convert lat/long. It also doesn't support description, which makes it +REM awkward to test. +REM +DEL %TMPDIR%\lowrance1.usr +DEL %TMPDIR%\enchilada1.usr +DEL %TMPDIR%\enchilada.gpx +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o lowranceusr -F %TMPDIR%\lowrance1.usr +@echo off +@echo. +CALL :BINCOMPARE %TMPDIR%\lowrance1.usr reference\lowrance.usr +@echo on +@echo Testing... +%PNAME% -i lowranceusr -f %TMPDIR%\lowrance1.usr -o lowranceusr -F %TMPDIR%\lowrance1.usr +@echo off +@echo. +REM And because of the FP rounding, we can't even read our file, write it back +REM and get the same data. Sigh. +REM bincompare reference/lowrance.usr ${TMPDIR}/lowrance1.usr +@echo on +@echo Testing... +%PNAME% -i lowranceusr -f reference\all.usr -o gpx -F %TMPDIR%\enchilada.gpx +%PNAME% -i gpx -f %TMPDIR%\enchilada.gpx -o lowranceusr -F %TMPDIR%\enchilada1.usr +@echo off +@echo. +CALL :BINCOMPARE %TMPDIR%\enchilada1.usr reference\enchilada.usr +REM Don't convert icons as waypts +@echo on +@echo Testing... +%PNAME% -i lowranceusr,ignoreicons -f reference\all.usr -o gpx -F %TMPDIR%\enchilada.gpx +%PNAME% -i gpx -f %TMPDIR%\enchilada.gpx -o lowranceusr -F %TMPDIR%\enchilada1.usr +@echo off +@echo. +CALL :BINCOMPARE %TMPDIR%\enchilada1.usr reference\ignoreicons.usr + +REM CSV (Comma separated value) data. + +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o csv -F %TMPDIR%\csv.csv +%PNAME% -i csv -f %TMPDIR%\csv.csv -o csv -F %TMPDIR%\csv2.csv +@echo off +@echo. +CALL :COMPARE %TMPDIR%\csv2.csv %TMPDIR%\csv.csv + +REM +REM Delorme TopoUSA 4 is a CSV strain. +REM +DEL %TMPDIR%\xmap-1.gpx %TMPDIR%\xmap-2.gpx %TMPDIR%\xmap +@echo on +@echo Testing... +%PNAME% -i xmap -f reference\xmap -o xmap -F %TMPDIR%\xmap +%PNAME% -i xmap -f reference\xmap -o gpx -F %TMPDIR%\xmap-1.gpx +%PNAME% -i xmap -f %TMPDIR%\xmap -o gpx -F %TMPDIR%\xmap-2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\xmap-1.gpx %TMPDIR%\xmap-2.gpx +CALL :COMPARE reference\xmap %TMPDIR%\xmap + +REM PCX (Garmin mapsource import) file format +DEL %TMPDIR%\mm.pcx %TMPDIR%\pcx.gps +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o pcx -F %TMPDIR%\mm.pcx +%PNAME% -i pcx -f %TMPDIR%\mm.pcx -o gpsutil -F %TMPDIR%\pcx.gps +@echo off +@echo. +CALL :COMPARE %TMPDIR%\mm.gps %TMPDIR%\gu.wpt +@echo on +@echo Testing... +%PNAME% -t -i gpx -f reference\track\tracks.gpx -o pcx -F %TMPDIR%\pcx.trk +%PNAME% -t -i pcx -f reference\track\pcx.trk -o pcx -F %TMPDIR%\pcx2.trk +@echo off +@echo. +CALL :COMPARE %TMPDIR%\pcx.trk %TMPDIR%\pcx2.trk + +REM +REM Magellan file format +REM +@echo on +@echo Testing... +%PNAME% -i magellan -f reference\magfile -o magellan -F %TMPDIR%\magfile +@echo off +@echo. +CALL :COMPARE %TMPDIR%\magfile reference\magfile + +REM +REM Magellanx is just like, but with longer names. (which this admittedly +REM doesn't actually exercise...) +REM +@echo on +@echo Testing... +%PNAME% -i magellan -f reference\magfile -o magellanx -F %TMPDIR%\magfile2 +@echo off +@echo. +CALL :COMPARE %TMPDIR%\magfile2 reference\magfile + +REM Navitrak DNA marker format +@echo on +@echo Testing... +%PNAME% -i dna -f reference\dnatest.txt -o dna -F %TMPDIR%\dnatest.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\dnatest.txt reference\dnatest.txt + +REM PSP (PocketStreets 2002 Pushpin (.PSP)) file format. Use mxf as an +REM intermediate format to avoid binary FP anomalies on compareerent platforms. +DEL %TMPDIR%\psp.mxf %TMPDIR%\mxf.psp +@echo on +@echo Testing... +%PNAME% -i psp -f reference\ps.psp -o mxf -F %TMPDIR%\psp.mxf +%PNAME% -i geo -f geocaching.loc -o mxf -F %TMPDIR%\mxf.psp +@echo off +@echo. +CALL :COMPARE %TMPDIR%\psp.mxf %TMPDIR%\mxf.psp +@echo on +@echo Testing... +%PNAME% -i psp -f reference\ps.psp -o gpx -F %TMPDIR%\psp1.gpx +%PNAME% -i psp -f reference\ps.psp -o psp -F %TMPDIR%\xxx.psp +%PNAME% -i psp -f %TMPDIR%\xxx.psp -o gpx -F %TMPDIR%\psp2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\psp1.gpx %TMPDIR%\psp2.gpx + +REM MXF (Maptech Exchange Format) file format +DEL %TMPDIR%\mx.mxf %TMPDIR%\mxf.mxf +@echo on +@echo Testing... +%PNAME% -i mxf -f reference\mxf.mxf -o mxf -F %TMPDIR%\mx.mxf +%PNAME% -i mxf -f %TMPDIR%\mx.mxf -o mxf -F %TMPDIR%\mxf.mxf +@echo off +@echo. +CALL :COMPARE %TMPDIR%\mxf.mxf reference + +REM tmpro (TopoMapPro Places) file format +DEL %TMPDIR%\topomappro.txt %TMPDIR%\mxf.mxf +@echo on +@echo Testing... +%PNAME% -i tmpro -f reference\topomappro.txt -o tmpro -F %TMPDIR%\tmp.txt +%PNAME% -i tmpro -f %TMPDIR%\tmp.txt -o tmpro -F %TMPDIR%\topomappro.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\topomappro.txt reference + +REM TPG (NG Topo!) file format +REM This is hard to test as the datum conversions create minute +REM inconsistencies in the coordinates. So.. we test our i/o +REM against a format that rounds higher than we care to compare +REM for binary data. +DEL %TMPDIR%\topo.mxf %TMPDIR%\tpg.mxf %TMPDIR%\geo.tpg +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o tpg -F %TMPDIR%\geo.tpg +%PNAME% -i tpg -f %TMPDIR%\geo.tpg -o mxf -F %TMPDIR%\tpg.mxf +%PNAME% -i tpg -f reference\tpg.tpg -o mxf -F %TMPDIR%\topo.mxf +@echo off +@echo. +CALL :COMPARE %TMPDIR%\tpg.mxf %TMPDIR%\topo.mxf + +REM TPO (NG Topo!) file format +REM This is hard to test as the datum conversions create minute +REM inconsistencies in the coordinates. We have four reference files: +REM tpo-sample1.tpo, tpo-sample1.gpx, tpo-sample2.gpx, and +REM tpo-sample2.tpo. These are used to check the conversion to/from +REM TPO format. +DEL %TMPDIR%\tpo-sample1.gpx %TMPDIR%\tpo-sample2.tpo +@echo on +@echo Testing... +%PNAME% -t -i tpo -f reference\track\tpo-sample1.tpo -o gpx -F %TMPDIR%\tpo-sample1.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\tpo-sample1.gpx reference\track\tpo-sample1.gpx +REM ${PNAME} -t -i gpx -f reference/track/tpo-sample2.gpx -o tpo -F ${TMPDIR}/tpo-sample2.tpo +REM bincompare ${TMPDIR}/tpo-sample2.tpo reference/track/tpo-sample2.tpo + +REM OZI (OziExplorer 1.1) file format +DEL %TMPDIR%\oz.wpt %TMPDIR%\ozi.wpt +@echo on +@echo Testing... +%PNAME% -i ozi -f reference\ozi.wpt -o ozi -F %TMPDIR%\oz.wpt +%PNAME% -i ozi -f %TMPDIR%\oz.wpt -o ozi -F %TMPDIR%\ozi.wpt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\ozi.wpt reference + +REM Holux support is a little funky to test. Becuase it loses precision, +REM if we convert it to another format, we lose accuracy (rounding) in the +REM coords, so converting it so something else and comparing it never works. +REM So we verify that we can read the reference and write it and get an +REM identical reference. +@echo on +@echo Testing... +%PNAME% -i holux -f reference\paris.wpo -o holux -F %TMPDIR%\paris.wpo +@echo off +@echo. +REM compare reference/paris.wpo ${TMPDIR}/paris.wpo + +REM Magellan NAV Companion for PalmOS +REM This format is hard to test, because each record and the database itself +REM contains the time of creation, so two otherwise identical files won't +REM compare accurately. In any case, the files are binary so compare wouldn't +REM like them. So, we convert the reference file to gpsutil and the converted +REM file to gpsutil and make sure they're the same, and that they're the same +REM as one converted on a known-working installation. Unfortunately, this does +REM not verify that the appinfo block was written correctly. However, it does +REM successfully test for some endianness errors that might otherwise go +REM unnoticed. +DEL %TMPDIR%\magnav.pdb %TMPDIR%\magnav.gpu %TMPDIR%\magnavt.gpu +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o magnav -F %TMPDIR%\magnav.pdb +%PNAME% -i magnav -f %TMPDIR%\magnav.pdb -o gpsutil -F %TMPDIR%\magnav.gpu +%PNAME% -i magnav -f reference\magnav.pdb -o gpsutil -F %TMPDIR%\magnavt.gpu +@echo off +@echo. +CALL :COMPARE %TMPDIR%\magnavt.gpu %TMPDIR%\magnav.gpu +CALL :COMPARE reference\gu.wpt %TMPDIR%\magnav.gpu + +DEL %TMPDIR%\magnav.pdb +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o magnav -F %TMPDIR%\magnav.pdb +@echo off +@echo. +CALL :BINCOMPARE %TMPDIR%\magnav.pdb reference\magnav.pdb + + + +REM GPSPilot Tracker for PalmOS +REM This test is eerily similar to the NAV Companion test. In fact, the +REM converted reference file (magnavr.gpu) is identical. +DEL %TMPDIR%\gpspilot.pdb %TMPDIR%\gpspilot.gpu %TMPDIR%\gpspil_t.gpu +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o gpspilot -F %TMPDIR%\gpspilot.pdb +%PNAME% -i gpspilot -f %TMPDIR%\gpspilot.pdb -o gpsutil -F %TMPDIR%\gpspilot.gpu +%PNAME% -i gpspilot -f reference\gpspilot.pdb -o gpsutil -F %TMPDIR%\gpspil_t.gpu +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gpspil_t.gpu %TMPDIR%\gpspilot.gpu +CALL :COMPARE reference\gu.wpt %TMPDIR%\gpspilot.gpu + +REM Cetus GPS for PalmOS +REM This test is also similar to the NAV Companion test. +DEL %TMPDIR%\cetus.pdb %TMPDIR%\cetus.gpu %TMPDIR%\cetust.gpu +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o cetus -F %TMPDIR%\cetus.pdb +%PNAME% -i cetus -f %TMPDIR%\cetus.pdb -o gpsutil -F %TMPDIR%\cetus.gpu +%PNAME% -i cetus -f reference\cetus.pdb -o gpsutil -F %TMPDIR%\cetust.gpu +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cetust.gpu %TMPDIR%\cetus.gpu +CALL :COMPARE reference\cetus.gpu %TMPDIR%\cetus.gpu + +REM QuoVadis GPS for PalmOS +REM This test is derived from the Cetus test above. +DEL %TMPDIR%\quovadis.pdb %TMPDIR%\quovadis.gpu %TMPDIR%\quovadist.gpu +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o quovadis -F %TMPDIR%\quovadis.pdb +%PNAME% -i quovadis -f %TMPDIR%\quovadis.pdb -o gpsutil -F %TMPDIR%\quovadis.gpu +%PNAME% -i quovadis -f reference\quovadis.pdb -o gpsutil -F %TMPDIR%\quovadist.gpu +@echo off +@echo. +CALL :COMPARE %TMPDIR%\quovadist.gpu %TMPDIR%\quovadis.gpu +CALL :COMPARE reference\quovadis.gpu %TMPDIR%\quovadis.gpu + +REM GpsDrive +DEL %TMPDIR%\gpsdrive.txt +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o gpsdrive -F %TMPDIR%\gpsdrive.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gpsdrive.txt reference +@echo on +@echo Testing... +%PNAME% -i gpsdrive -f reference\gpsdrive.txt -o gpsdrive -F %TMPDIR%\gpsdrive2.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gpsdrive2.txt reference\gpsdrive.txt + +REM XMapHH Street Atlas USA file format +DEL %TMPDIR%\xmapwpt.wpt %TMPDIR%\xmapwpt.xmapwpt +@echo on +@echo Testing... +%PNAME% -i xmapwpt -f reference\xmapwpt.wpt -o xmapwpt -F %TMPDIR%\xmapwpt.xmapwpt +%PNAME% -i xmapwpt -f %TMPDIR%\xmapwpt.xmapwpt -o xmapwpt -F %TMPDIR%\xmapwpt.wpt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\xmapwpt.wpt reference + +REM XCSV +REM Test that we can parse a style file, and read and write data in the +REM same xcsv format (a complete test is virtually impossible). +ECHO RECORD_DELIMITER NEWLINE> %TMPDIR%\testo.style +ECHO FIELD_DELIMITER COMMA>> %TMPDIR%\testo.style +ECHO BADCHARS COMMA>> %TMPDIR%\testo.style +ECHO PROLOGUE Header>> %TMPDIR%\testo.style +ECHO EPILOGUE Footer>> %TMPDIR%\testo.style +ECHO IFIELD SHORTNAME,,%%s>> %TMPDIR%\testo.style +ECHO IFIELD LAT_DIRDECIMAL,,%%c%%lf>> %TMPDIR%\testo.style +ECHO IFIELD LON_DECIMALDIR,,%%lf%%c>> %TMPDIR%\testo.style +DEL %TMPDIR%\xcsv.geo %TMPDIR%\xcsv.xcsv +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o xcsv,style=%TMPDIR%\testo.style -F %TMPDIR%\xcsv.geo +%PNAME% -i xcsv,style=%TMPDIR%\testo.style -f %TMPDIR%\xcsv.geo -o xcsv,style=%TMPDIR%\testo.style -F %TMPDIR%\xcsv.xcsv +@echo off +@echo. +CALL :COMPARE %TMPDIR%\xcsv.geo %TMPDIR%\xcsv.xcsv + +REM Garmin Mapsource This is a binary format with some undocumented +REM fields. This test is therefore intentionally vague. We read a file, +REM convert it to GPX, then write a file as MPS, then read it back and +REM write it as GPX and compare them. Since we're writing both GPX files +REM ourselves from the same version, we're immune to changes in our own +REM GPX output. + +@echo on +@echo Testing... +%PNAME% -i mapsource -f reference\mapsource.mps -o gpx -F %TMPDIR%\ms1.gpx +%PNAME% -i mapsource -f reference\mapsource.mps -o mapsource -F %TMPDIR%\ms.mps +%PNAME% -i mapsource -f %TMPDIR%\ms.mps -o gpx -F %TMPDIR%\ms2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\ms1.gpx %TMPDIR%\ms2.gpx + +REM +REM MRCB mapsource track test +REM +DEL %TMPDIR%\mps-track.mps +@echo on +@echo Testing... +%PNAME% -t -i mapsource -f reference\track\mps-track.mps -o mapsource,mpsverout=3 -F %TMPDIR%\mps-track.mps +@echo off +@echo. +CALL :COMPARE %TMPDIR%\mps-track.mps reference\track +REM Now do a test of reading waypoints from a track-only file - should have an empty result +DEL %TMPDIR%\mps-track.mps +@echo on +@echo Testing... +%PNAME% -i mapsource -f reference\track\mps-track.mps -o mapsource,mpsverout=3 -F %TMPDIR%\mps-track.mps +@echo off +@echo. +CALL :COMPARE %TMPDIR%\mps-track.mps reference\mps-empty.mps + +REM +REM MRCB mapsource route test +REM +DEL %TMPDIR%\mps-route.mps +@echo on +@echo Testing... +%PNAME% -r -i mapsource -f reference\route\route.mps -o mapsource,mpsverout=4 -F %TMPDIR%\mps-route.mps +@echo off +@echo. +CALL :COMPARE %TMPDIR%\mps-route.mps reference\route\route.mps + +REM Now do a test of reading tracks from a route-only file - should have an empty result +DEL %TMPDIR%\mps-route.mps +@echo on +@echo Testing... +%PNAME% -t -i mapsource -f reference\route\route.mps -o mapsource,mpsverout=3 -F %TMPDIR%\mps-route.mps +@echo off +@echo. +CALL :COMPARE %TMPDIR%\mps-route.mps reference\mps-empty.mps + +REM +REM Geocaching Database is a binary Palm format that, like the GPX variants +REM has a zillion "equivalent" encodings of any given record set. So we +REM read the reference file, spin it to GPX and back to GCDB and then spin +REM that one to GPX. +REM + +@echo on +@echo Testing... +%PNAME% -i gcdb -f reference\GeocachingDB.PDB -o gpx -F %TMPDIR%\gcdb1.gpx -o gcdb -F %TMPDIR%\gcdb1.pdb +%PNAME% -i gpx -f %TMPDIR%\gcdb1.gpx -o gpx -F %TMPDIR%\gcdb2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gcdb1.gpx %TMPDIR%\gcdb1.gpx + +REM +REM Duplicate filter - Since filters have no format of their own, we use csv +REM as an intermediate format for testing the filter. +REM +DEL %TMPDIR%\filterdupe.csv1 %TMPDIR%\filterdupe.csv2 +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o csv -F %TMPDIR%\filterdupe.csv1 +%PNAME% -i geo -f geocaching.loc -f geocaching.loc -x duplicate,shortname -o csv -F %TMPDIR%\filterdupe.csv2 +@echo off +@echo. +CALL :SORTandCOMPARE %TMPDIR%\filterdupe.csv1 %TMPDIR%\filterdupe.csv2 + +REM +REM Position filter - Since very small distances are essentialy a duplicate +REM position filter, we can test very similarly to the duplicate filter. +REM +DEL %TMPDIR%\filterpos.csv1 %TMPDIR%\filterpos.csv2 +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o csv -F %TMPDIR%\filterpos.csv1 +%PNAME% -i geo -f geocaching.loc -f geocaching.loc -x position,distance=5f -o csv -F %TMPDIR%\filterpos.csv2 +@echo off +@echo. +CALL :SORTandCOMPARE %TMPDIR%\filterpos.csv1 %TMPDIR%\filterpos.csv2 + +REM +REM Radius filter +REM +DEL %TMPDIR%\radius.csv +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -x radius,lat=35.9720,lon=-87.1347,distance=14.7 -o csv -F %TMPDIR%\radius.csv +@echo off +@echo. +CALL :COMPARE %TMPDIR%\radius.csv reference +REM +REM magellan SD card waypoint / route format +REM +DEL %TMPDIR%\magellan.rte +@echo on +@echo Testing... +%PNAME% -r -i magellan -f reference\route\magellan.rte -o magellan -F %TMPDIR%\magellan.rte +@echo off +@echo. +CALL :COMPARE %TMPDIR%\magellan.rte reference\route\magellan.rte + + +REM +REM GPX routes -- since GPX contains a date stamp, tests will always +REM fail, so we use magellan as an interim format... +REM +DEL %TMPDIR%\gpxroute.gpx %TMPDIR%\maggpx.rte +@echo on +@echo Testing... +%PNAME% -r -i gpx -f reference\route\route.gpx -o gpx -F %TMPDIR%\gpxroute.gpx +%PNAME% -r -i gpx -f %TMPDIR%\gpxroute.gpx -o magellan -F %TMPDIR%\maggpx.rte +@echo off +@echo. +CALL :COMPARE %TMPDIR%\maggpx.rte reference\route\magellan.rte + +REM +REM GPX tracks -- since GPX contains a date stamp, tests will always +REM fail, so we use magellan as an interim format... +REM +DEL %TMPDIR%\gpxtrack.gpx %TMPDIR%\maggpx.trk +@echo on +@echo Testing... +%PNAME% -t -i gpx -f reference\track\tracks.gpx -o gpx -F %TMPDIR%\gpxtrack.gpx +%PNAME% -t -i magellan -f reference\track\meridian.trk -o gpx -F %TMPDIR%\maggpx.trk +@echo off +@echo. +CALL :COMPARE %TMPDIR%\maggpx.trk %TMPDIR%\gpxtrack.gpx + +REM +REM MAPSEND waypoint / route format +REM +DEL %TMPDIR%\route.mapsend +@echo on +@echo Testing... +%PNAME% -r -i mapsend -f reference\route\route.mapsend -o mapsend -F %TMPDIR%\route.mapsend +@echo off +@echo. +CALL :BINCOMPARE %TMPDIR%\route.mapsend reference\route\route.mapsend + +REM +REM MAPSEND track format +REM +DEL %TMPDIR%\mapsend.trk +@echo on +@echo Testing... +%PNAME% -t -i mapsend -f reference\track\mapsend.trk -o mapsend -F %TMPDIR%\mapsend.trk +@echo off +@echo. +CALL :COMPARE %TMPDIR%\mapsend.trk reference\track +REM +REM copilot +REM +DEL %TMPDIR%\copilot.pdb +@echo on +@echo Testing... +%PNAME% -i copilot -f reference\UKultralight.pdb -o copilot -F %TMPDIR%\cop.pdb +%PNAME% -i copilot -f reference\UKultralight.pdb -o gpx -F %TMPDIR%\cop1.gpx +%PNAME% -i copilot -f %TMPDIR%\cop.pdb -o gpx -F %TMPDIR%\cop2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cop1.gpx %TMPDIR%\cop2.gpx + +REM +REM EasyGPS. Another binary format. +REM +DEL %TMPDIR%\easy.loc +@echo on +@echo Testing... +%PNAME% -i easygps -f reference\easygps.loc -o easygps -F %TMPDIR%\ez.loc +%PNAME% -i easygps -f reference\easygps.loc -o gpx -F %TMPDIR%\ez1.gpx +%PNAME% -i easygps -f %TMPDIR%\ez.loc -o gpx -F %TMPDIR%\ez2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\ez1.gpx %TMPDIR%\ez2.gpx + +REM +REM GPilotS. A Palm format. Another binary format that +REM +REM rm -f ${TMPDIR/gpilots.l +REM ${PNAME} -i easygps -f reference/gpilots.pdb -o gpx -F ${TMPDIR}/gp.gpx +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o gpilots -F %TMPDIR%\blah.pdb +%PNAME% -i gpilots -f %TMPDIR%\blah.pdb -o gpx -F %TMPDIR%\1.gpx +%PNAME% -i gpilots -f reference\gpilots.pdb -o gpx -F %TMPDIR%\2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\1.gpx %TMPDIR%\2.gpx +REM ${PNAME} -i easygps -f reference/gpilots.pdb -o gpx -F ${TMPDIR}/gp.gpx + +REM +REM Navicache. +@echo on +@echo Testing... +%PNAME% -i navicache -f reference\navicache.xml -o gpsutil -F %TMPDIR%\navi.wpt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\navi.wpt reference\navicache.ref +REM + +REM +REM CoastalExplorer.. +@echo on +@echo Testing... +%PNAME% -r -i coastexp -f reference\coastexp.nob -o gpx -F %TMPDIR%\coastexp.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\coastexp.gpx reference\coastexp.ref +@echo on +@echo Testing... +%PNAME% -r -i gpx -f %TMPDIR%\coastexp.gpx -o coastexp -F %TMPDIR%\coastexp.nob +@echo off +@echo. +CALL :COMPARE %TMPDIR%\coastexp.nob reference\coastexp.ref2 +@echo on +@echo Testing... +%PNAME% -w -i coastexp -f reference\coastexp.nob -o gpx -F %TMPDIR%\coastexp.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\coastexp.gpx reference\coastexp.ref3 +@echo on +@echo Testing... +%PNAME% -w -i gpx -f %TMPDIR%\coastexp.gpx -o coastexp -F %TMPDIR%\coastexp.nob +@echo off +@echo. +CALL :COMPARE %TMPDIR%\coastexp.nob reference\coastexp.ref4 +REM + +REM PsiTrex. A text format that can't be handled by XCSV due to context of +REM data based on other data values in the file +REM Waypoints first +DEL %TMPDIR%\psit-ww.txt %TMPDIR%\psit-ww.mps +@echo on +@echo Testing... +%PNAME% -i psitrex -f reference\psitwpts.txt -o mapsource -F %TMPDIR%\psit-ww.mps +%PNAME% -i mapsource -f %TMPDIR%\psit-ww.mps -o psitrex -F %TMPDIR%\psit-ww.txt +@echo off +@echo. +CALL :COMPARE reference\psitwpts.txt %TMPDIR%\psit-ww.txt + +REM Now test correct "empty" handling - ask for routes when there aren't any +REM Uses mapsource as the empty handling for this has already happened above +DEL %TMPDIR%\psit-wr.mps +@echo on +@echo Testing... +%PNAME% -r -i psitrex -f reference\psitwpts.txt -o mapsource,mpsverout=3 -F %TMPDIR%\psit-wr.mps +@echo off +@echo. +CALL :COMPARE reference\mps-empty.mps %TMPDIR%\psit-wr.mps + +REM Routes next +DEL %TMPDIR%\psit-rr.txt %TMPDIR%\psit-rr.mps +@echo on +@echo Testing... +%PNAME% -r -i psitrex -f reference\route\psitrtes.txt -o mapsource -F %TMPDIR%\psit-rr.mps +%PNAME% -r -i mapsource -f %TMPDIR%\psit-rr.mps -o psitrex -F %TMPDIR%\psit-rr.txt +@echo off +@echo. +CALL :COMPARE reference\route\psitrtes.txt %TMPDIR%\psit-rr.txt + +REM Now test correct "empty" handling - ask for tracks when there aren't any +REM Uses mapsource as the empty handling for this has already happened above +DEL %TMPDIR%\psit-rt.mps +@echo on +@echo Testing... +%PNAME% -t -i psitrex -f reference\route\psitrtes.txt -o mapsource,mpsverout=3 -F %TMPDIR%\psit-rt.mps +@echo off +@echo. +CALL :COMPARE reference\mps-empty.mps %TMPDIR%\psit-rt.mps + +REM Tracks last +DEL %TMPDIR%\psit-tt.txt %TMPDIR%\psit-tt.mps +@echo on +@echo Testing... +%PNAME% -t -i psitrex -f reference\track\psittrks.txt -o mapsource -F %TMPDIR%\psit-tt.mps +%PNAME% -t -i mapsource -f %TMPDIR%\psit-tt.mps -o psitrex -F %TMPDIR%\psit-tt.txt +@echo off +@echo. +CALL :COMPARE reference\track\psittrks.txt %TMPDIR%\psit-tt.txt + +REM Now test correct "empty" handling - ask for waypoints when there aren't any +REM Uses mapsource as the empty handling for this has already happened above +DEL %TMPDIR%\psit-tw.mps +@echo on +@echo Testing... +%PNAME% -i psitrex -f reference\track\psittrks.txt -o mapsource,mpsverout=3 -F %TMPDIR%\psit-tw.mps +@echo off +@echo. +CALL :COMPARE reference\mps-empty.mps %TMPDIR%\psit-tw.mps + +REM +REM Arc Distance filter +REM +DEL %TMPDIR%\arcdist.txt +@echo on +@echo Testing... +%PNAME% -i xmap -f reference\arcdist_input.txt -x arc,file=reference\arcdist_arc.txt,distance=1 -o xmap -F %TMPDIR%\arcdist.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\arcdist.txt reference\arcdist_output.txt + +REM +REM Polygon filter +REM +DEL %TMPDIR%\polygon.txt +@echo on +@echo Testing... +%PNAME% -i xmap -f reference\arcdist_input.txt -x polygon,file=reference\polygon_allencty.txt -o xmap -F %TMPDIR%\polygon.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\polygon.txt reference\polygon_output.txt + +REM +REM Simplify filter +REM +DEL %TMPDIR%\simplify.txt +@echo on +@echo Testing... +%PNAME% -r -i gpx -f reference\route\route.gpx -x simplify,count=10 -o arc -F %TMPDIR%\simplify.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\simplify.txt reference\simplify_output.txt + +REM +REM Route reversal filter. Do it twice and be sure we get what we +REM started with. +REM +DEL %TMPDIR%\reverse1.arc %TMPDIR%\reverse2.arc %TMPDIR%\reference.arc +@echo on +@echo Testing... +%PNAME% -r -i gpx -f reference\route\route.gpx -o arc -F %TMPDIR%\reference.arc +%PNAME% -r -i gpx -f reference\route\route.gpx -x reverse -o arc -F %TMPDIR%\reverse1.arc +%PNAME% -r -i gpx -f reference\route\route.gpx -x reverse -x reverse -o arc -F %TMPDIR%\reverse2.arc +@echo off +@echo. +REM Verify the first and last are the same +CALL :COMPARE %TMPDIR%\reference.arc %TMPDIR%\reverse2.arc +REM Verify the first and second are different. +REM ${DIFF} ${TMPDIR}/reverse1.arc ${TMPDIR}/reverse2.arc > /dev/null && { +REM echo ERROR Failed reversal test. +REM exit 1 +REM } + +REM parkrrrr: This isn't a straightforward compare; we *want* it to fail. +REM Obviously this test should just be rewritten with a new reference. +REM compare ${TMPDIR}/reverse1.arc ${TMPDIR}/reverse2.arc + +REM +REM Geoniche: No reference file was available, so we created one and just +REM test it against itself. +REM +DEL %TMPDIR%\gn.pdb %TMPDIR%\1.gpx %TMPDIR%\2.gpx +@echo on +@echo Testing... +%PNAME% -i geoniche -f reference\geoniche.pdb -o geoniche -F %TMPDIR%\gn.pdb +%PNAME% -i geoniche -f reference\geoniche.pdb -o gpx -F %TMPDIR%\1.gpx +%PNAME% -i geoniche -f %TMPDIR%\gn.pdb -o gpx -F %TMPDIR%\2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\1.gpx %TMPDIR%\2.gpx +REM +@echo on +@echo Testing... +%PNAME% -i geoniche -f reference\gn-targets.pdb -o gpx -F %TMPDIR%\gn-targets.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gn-targets.gpx reference\gn-targets.gpx + +REM +REM saroute covers *.anr, *.rte, and *.rtd, but I only have an .anr for testing. +REM Unfortunately for us, this is a read-only format for now. +REM +@echo on +@echo Testing... +%PNAME% -t -i saroute -f reference\track\i65.anr -o gpx -F %TMPDIR%\gpl1.gpx +%PNAME% -t -i gpx -f reference\track\i65.anr.gpx -o gpx -F %TMPDIR%\gpl2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gpl1.gpx %TMPDIR%\gpl2.gpx + +REM +REM Delorme GPL file. This is sort of a track format. +REM +DEL %TMPDIR%\gpl1.gpx %TMPDIR%\gpl2.gpx %TMPDIR%\gpl1.gpl +@echo on +@echo Testing... +%PNAME% -t -i gpl -f reference\track\webpark1.gpl -o gpx -F %TMPDIR%\gpl1.gpx +%PNAME% -t -i gpl -f reference\track\webpark1.gpl -o gpl -F %TMPDIR%\gpl1.gpl +%PNAME% -t -i gpl -f %TMPDIR%\gpl1.gpl -o gpx -F %TMPDIR%\gpl2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gpl1.gpx %TMPDIR%\gpl2.gpx + +REM +REM NetStumbler Summary File (read-only) +REM +DEL %TMPDIR%\netstumbler.mps +@echo on +@echo Testing... +%PNAME% -i netstumbler -f reference\netstumbler.txt -o mapsource -F %TMPDIR%\netstumbler.mps +@echo off +@echo. +CALL :BINCOMPARE %TMPDIR%\netstumbler.mps reference\netstumbler.mps + +REM +REM IGC tests +REM +DEL %TMPDIR%\igc*out +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\igc1.gpx -o igc -F %TMPDIR%\igc.out +@echo off +@echo. +FINDSTR /V /R /C:"^LXXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out +CALL :COMPARE %TMPDIR%\igc_sed.out reference\igc1_igc.out + +@echo on +@echo Testing... +%PNAME% -i igc -f %TMPDIR%\igc.out -o gpx -F %TMPDIR%\igc.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\igc.gpx reference\igc1_gpx.out + +@echo on +@echo Testing... +%PNAME% -i gpx -f %TMPDIR%\igc.gpx -o igc -F %TMPDIR%\igc.out +@echo off +@echo. +FINDSTR /V /R /C:"^LXXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out +CALL :COMPARE %TMPDIR%\igc_sed.out reference\igc1_igc.out + +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\igc1_baro.gpx -i igc -f reference\igc1_igc.out -o igc,timeadj=auto -F %TMPDIR%\igc.out +@echo off +@echo. +FINDSTR /V /R /C:"^LXXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out +CALL :COMPARE %TMPDIR%\igc_sed.out reference\igc1_3d.out + + +@echo on +@echo Testing... +%PNAME% -i igc -f reference\igc2.igc -o gpx -F %TMPDIR%\igc.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\igc.gpx reference\igc2_gpx.out + +@echo on +@echo Testing... +%PNAME% -i gpx -f %TMPDIR%\igc.gpx -o igc -F %TMPDIR%\igc.out +@echo off +@echo. +FINDSTR /V /R /C:"^LXXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out +CALL :COMPARE %TMPDIR%\igc_sed.out reference\igc2_igc.out + +@echo on +@echo Testing... +%PNAME% -i igc -f %TMPDIR%\igc.out -o gpx -F %TMPDIR%\igc.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\igc.gpx reference\igc2_gpx.out + +REM +REM Google Maps XML test +REM +DEL %TMPDIR%\google.out +@echo on +@echo Testing... +%PNAME% -i google -f reference\google.xml -o csv -F %TMPDIR%\google.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\google.out reference\google.csv + +DEL %TMPDIR%\google.out +@echo on +@echo Testing... +%PNAME% -i google -f reference\google.js -o csv -F %TMPDIR%\google.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\google.out reference\google.csv + +DEL %TMPDIR%\google.out +@echo on +@echo Testing... +%PNAME% -i google -f reference\google_jan_06.html -o csv -F %TMPDIR%\google.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\google.out reference\google_jan_06.csv + +REM +REM DeLorme .an1 tests +REM +DEL %TMPDIR%\an1.out +@echo on +@echo Testing... +%PNAME% -i an1 -f reference\foo.an1 -o csv -F %TMPDIR%\an1.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\an1.out reference\an1-in.ref + +DEL %TMPDIR%\an1.out +@echo on +@echo Testing... +%PNAME% -i an1 -f reference\foo.an1 -o an1 -F %TMPDIR%\an1.out +@echo off +@echo. +CALL :BINCOMPARE %TMPDIR%\an1.out reference\an1-an1.ref + +DEL %TMPDIR%\an1.out +@echo on +@echo Testing... +%PNAME% -i xmap -f reference\xmap -o an1 -F %TMPDIR%\an1.out +@echo off +@echo. +CALL :BINCOMPARE %TMPDIR%\an1.out reference\an1-out.ref + +DEL %TMPDIR%\an1.out +@echo on +@echo Testing... +%PNAME% -i google -f reference\google.js -o an1 -F %TMPDIR%\an1.out +@echo off +@echo. +CALL :BINCOMPARE %TMPDIR%\an1.out reference\an1-line-out.ref + +REM +REM TomTom .ov2 tests +REM + +DEL %TMPDIR%\ov2.out +@echo on +@echo Testing... +%PNAME% -i arc -f reference\google.arc -o tomtom -F %TMPDIR%\ov2.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\ov2.out reference\ov2-arc-out.ref + +DEL %TMPDIR%\ov2.out +@echo on +@echo Testing... +%PNAME% -i geo -f reference\gl.loc -o tomtom -F %TMPDIR%\ov2.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\ov2.out reference\ov2-geo-out.ref + +DEL %TMPDIR%\ov2.out +@echo on +@echo Testing... +%PNAME% -i tomtom -f reference\ov2-geo-out.ref -o gpsutil -F %TMPDIR%\ov2.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\ov2.out reference\ov2-in.ref + +REM +REM XCSV "human readable" tests +REM +DEL %TMPDIR%\humanread.out +@echo on +@echo Testing... +%PNAME% -i xcsv,style=reference\humanread.style -f reference\human.in -o arc -F %TMPDIR%\humanread.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\humanread.out reference\humanread.out + +DEL %TMPDIR%\humanwrite.out +@echo on +@echo Testing... +%PNAME% -i xcsv,style=reference\humanread.style -f reference\human.in -o xcsv,style=reference\humanwrite.style -F %TMPDIR%\humanwrite.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\humanwrite.out reference\humanwrite.out + +REM +REM XCSV "path distance" test +REM +DEL %TMPDIR%\pathdist.out +@echo on +@echo Testing... +%PNAME% -i magellan -f reference\dusky.trk -o xcsv,style=reference\gnuplot.style -F %TMPDIR%\pathdist.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\pathdist.out reference\dusky.gnuplot + +REM hsandv +DEL %TMPDIR%\hsandv.exp %TMPDIR%\1.exp %TMPDIR%\1.exp %TMPDIR%\Glad_5.exp +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o hsandv -F %TMPDIR%\hsandv.exp +@echo off +@echo. +CALL :COMPARE %TMPDIR%\hsandv.exp reference +REM the hsandv format is too lossy to do this test :( +REM ${PNAME} -i hsandv -f ${TMPDIR}/hsandv.exp -o geo -F ${TMPDIR}/1.exp +REM ${PNAME} -i hsandv -f reference/hsandv.exp -o geo -F ${TMPDIR}/2.exp +REM compare ${TMPDIR}/1.exp ${TMPDIR}/2.exp +REM test conversion from v4 to v5 files +@echo on +@echo Testing... +%PNAME% -i hsandv -f reference\Glad_4.exp -o hsandv -F %TMPDIR%\Glad_5.exp +@echo off +@echo. +REM FIXME: Can't compare directly because of potential FP rounding. +REM FIXME: compare ${TMPDIR}/Glad_5.exp reference + +REM +REM stack filter tests +REM These don't actually test for proper behavior, for now, but they do +REM exercise all of the currently-extant filter code. +REM + +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -x stack,push,copy,nowarn -x stack,push,copy -x stack,push -x stack,pop,replace -x stack,pop,append -x stack,push,copy -x stack,pop,discard -x stack,swap,depth=1 -o arc -F %TMPDIR%\stackfilt.txt +@echo off +@echo. + +REM +REM 'tabsep' isn't really tested in any non-trivial way, but we do exercise +REM it. +REM + +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o tabsep -F %TMPDIR%\tabsep.in +%PNAME% -i tabsep -f %TMPDIR%\tabsep.in -o geo -F %TMPDIR%\tabsep.out +%PNAME% -i geo -f geocaching.loc -o geo -F %TMPDIR%\geotabsep.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\tabsep.out %TMPDIR%\geotabsep.out + +REM +REM Now do the same for custom - it has the same issues. +REM + +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o custom -F %TMPDIR%\custom.in +%PNAME% -i custom -f %TMPDIR%\custom.in -o geo -F %TMPDIR%\custom.out +%PNAME% -i geo -f geocaching.loc -o geo -F %TMPDIR%\geocustom.out +@echo off +@echo. + +REM +REM Write something to the various output-only formats +REM +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o text -F %TMPDIR%\text.out -o html -F %TMPDIR%\html.out -o vcard -F %TMPDIR%\vcard.out #-o palmdoc -F %TMPDIR%\pd.out +@echo off +@echo. + +REM +REM tef "TourExchangeFormat" read test +REM +DEL %TMPDIR%\tef_xml* +@echo on +@echo Testing... +%PNAME% -r -i tef -f reference\route\tef_xml.sample.xml -o gpx -F %TMPDIR%\tef_xml.sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\tef_xml.sample.gpx reference\route\tef_xml.sample.gpx + +REM +REM PathAway Palm Database .pdb tests +REM +DEL %TMPDIR%\pathaway* +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o pathaway,dbname=pathaway-geo -F %TMPDIR%\pathaway-geo.pdb +%PNAME% -i pathaway -f %TMPDIR%\pathaway-geo.pdb -o geo -F %TMPDIR%\pathaway-geo.loc +@echo off +@echo. +CALL :COMPARE %TMPDIR%\pathaway-geo.loc reference\pathaway-geo.loc +DEL %TMPDIR%\pathaway* +@echo on +@echo Testing... +%PNAME% -t -i pathaway -f reference\track\pathaway.pdb -o gpx -F %TMPDIR%\pathaway.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\pathaway.gpx reference\track\pathaway.gpx + +REM +REM Garmin GPS Database .gdb tests +REM +DEL %TMPDIR%\gdb-* +@echo on +@echo Testing... +%PNAME% -i gdb,via -f reference\gdb-sample.gdb -o gpx -F %TMPDIR%\gdb-sample.gpx +@echo off +@echo. +CALL :COMPARE reference\gdb-sample.gpx %TMPDIR%\gdb-sample.gpx +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\gdb-sample.gpx -o gdb,ver=1 -F %TMPDIR%\gdb-sample.gdb +%PNAME% -i gdb -f %TMPDIR%\gdb-sample.gdb -o gpx -F %TMPDIR%\gdb-sample.gpx +@echo off +@echo. +REM +REM Because of Garmin coordinates storage gpx is not good for this test +REM compare reference/gdb-sample.gpx ${TMPDIR}/gdb-sample.gpx +REM +REM compare ${TMPDIR}/gdb-sample.gpx reference/gdb-sample.gpx + +REM +REM Vito Navigator II .smt tests +REM +DEL %TMPDIR%\vitosmt* +@echo on +@echo Testing... +%PNAME% -i vitosmt -f reference\vitosmt.smt -o gpx -F %TMPDIR%\vitosmt.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\vitosmt.gpx reference\vitosmt.gpx +@echo on +@echo Testing... +%PNAME% -t -i vitosmt -f reference\vitosmt.smt -o gpx -F %TMPDIR%\vitosmt_t.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\vitosmt_t.gpx reference\track\vitosmt_t.gpx + +REM +REM tracks filter tests +REM + +DEL %TMPDIR%\trackfilter* + +@echo on +@echo Testing... +%PNAME% -t -i gpx -f reference\track\trackfilter.gpx -x track,pack,split,title=LOG-%%Y%%m%%d -o gpx -F %TMPDIR%\trackfilter.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\trackfilter.gpx reference\track\trackfilter.gpx + +REM +REM Map&Guide Motorrad Routenplaner .bcr files test +REM +DEL %TMPDIR%\bcr* +@echo on +@echo Testing... +%PNAME% -r -i bcr -f reference\route\bcr-sample.bcr -o gpx -F %TMPDIR%\bcr-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\bcr-sample.gpx reference\route\bcr-sample.gpx +@echo on +@echo Testing... +%PNAME% -r -i gpx -f reference\route\bcr-sample.gpx -o bcr -F %TMPDIR%\bcr-sample2.bcr +@echo off +@echo. +CALL :COMPARE reference\route\bcr-sample2.bcr %TMPDIR%\bcr-sample2.bcr +@echo on +@echo Testing... +%PNAME% -r -i bcr -f %TMPDIR%\bcr-sample2.bcr -o gpx -F %TMPDIR%\bcr-sample2.gpx +@echo off +@echo. + +REM +REM cet - Character encoding transformation tests +REM +DEL %TMPDIR%\cet-sample* +@echo on +@echo Testing... +%PNAME% -w -i gdb -f reference\cet\cet-sample.gdb -o gpx -F %TMPDIR%\cet-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cet-sample.gpx reference\cet\cet-sample.gpx +@echo on +@echo Testing... +%PNAME% -w -i gpx -f %TMPDIR%\cet-sample.gpx -o tmpro -c Latin1 -F %TMPDIR%\cet-sample.latin1.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cet-sample.latin1.txt reference\cet\cet-sample.latin1.txt +@echo on +@echo Testing... +%PNAME% -w -i gdb -f reference\cet\cet-sample.gdb -o tmpro -c Latin2 -F %TMPDIR%\cet-sample.latin2.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cet-sample.latin2.txt reference\cet\cet-sample.latin2.txt +@echo on +@echo Testing... +%PNAME% -w -i gdb -f reference\cet\cet-sample.gdb -o tmpro -c cp1250 -F %TMPDIR%\cet-sample.cp1250.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cet-sample.cp1250.txt reference\cet\cet-sample.cp1250.txt +@echo on +@echo Testing... +%PNAME% -w -i gdb -f reference\cet\cet-sample.gdb -o tmpro -c macroman -F %TMPDIR%\cet-sample.macroman.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cet-sample.macroman.txt reference\cet\cet-sample.macroman.txt + +REM +REM Garmin logbook. This format has an extra section (lap data with things +REM like heartbeat and calories burned) that we don't know what to do with, +REM so we convert it to gpx, convert it to itself, convert THAT to gpx, and +REM compare those. +REM +DEL %TMPDIR%\glogbook* +@echo on +@echo Testing... +%PNAME% -i glogbook -f reference\track\garmin_logbook.xml -o gpx -F %TMPDIR%\glog1.gpx +%PNAME% -i glogbook -f reference\track\garmin_logbook.xml -o glogbook -F %TMPDIR%\glog.xml +%PNAME% -i glogbook -f %TMPDIR%\glog.xml -o gpx -F %TMPDIR%\glog2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\glog1.gpx %TMPDIR%\glog2.gpx + +REM +REM Dop filter test +REM +DEL %TMPDIR%\dop* +FINDSTR /V /R /C:"50" reference\dop-test.gpx | %PNAME% -i gpx -f - -o openoffice -F - | sed 's\RPT...\\g'> %TMPDIR%\dop-hdop.ref +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\dop-test.gpx -x discard,hdop=50 -o openoffice -F - | sed 's\RPT...\\g'> %TMPDIR%\dop-hdop.fil +@echo off +@echo. +CALL :COMPARE %TMPDIR%\dop-hdop.ref %TMPDIR%\dop-hdop.fil +FINDSTR /V /R /C:"50" reference\dop-test.gpx | %PNAME% -i gpx -f - -o openoffice -F - | sed 's\RPT...\\g'> %TMPDIR%\dop-vdop.ref +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\dop-test.gpx -x discard,vdop=50 -o openoffice -F - | sed 's\RPT...\\g'> %TMPDIR%\dop-vdop.fil +@echo off +@echo. +CALL :COMPARE %TMPDIR%\dop-vdop.ref %TMPDIR%\dop-vdop.fil + +REM +REM cotoGPS tests +REM +DEL %TMPDIR%\coto* +REM Track reading +@echo on +@echo Testing... +%PNAME% -i coto -f reference\cototesttrack.pdb -o xcsv,style=reference\cototest.style -F %TMPDIR%\cototrack.csv +@echo off +@echo. +CALL :COMPARE reference\cototesttrack.csv %TMPDIR%\cototrack.csv +REM Marker read +@echo on +@echo Testing... +%PNAME% -i coto -f reference\cototestmarker.pdb -o gpx -F %TMPDIR%\cotomarker.gpx +@echo off +@echo. +CALL :COMPARE reference\cototestmarker.gpx %TMPDIR%\cotomarker.gpx +REM Marker write +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\cototestmarker.gpx -o coto -F %TMPDIR%\cotomarker.pdb +@echo off +@echo. +REM bincompare reference/cototestmarker.pdb ${TMPDIR}/cotomarker.pdb +@echo on +@echo Testing... +%PNAME% -i coto -f %TMPDIR%\cotomarker.pdb -o gpx -F %TMPDIR%\cotomarker.gpx +@echo off +@echo. +CALL :COMPARE reference\cototestmarker.gpx %TMPDIR%\cotomarker.gpx + +REM +REM Fugawi test cases +DEL %TMPDIR%\fugawi* +@echo on +@echo Testing... +%PNAME% -i fugawi -f reference\fugawi.notime.txt -o fugawi -F %TMPDIR%\fugawi1.txt +@echo off +@echo. +CALL :COMPARE reference\fugawi.ref.txt %TMPDIR%\fugawi1.txt +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o fugawi -F %TMPDIR%\fugawi2.txt +@echo off +@echo. +CALL :COMPARE reference\fugawi.ref.txt %TMPDIR%\fugawi2.txt +@echo on +@echo Testing... +%PNAME% -i fugawi -f %TMPDIR%\fugawi2.txt -o fugawi -F %TMPDIR%\fugawi3.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\fugawi2.txt %TMPDIR%\fugawi3.txt +@echo on +@echo Testing... +%PNAME% -i fugawi -f reference\fugawi.time.txt -o fugawi -F %TMPDIR%\fugawi4.txt +@echo off +@echo. +CALL :COMPARE reference\fugawi.time.ref.txt %TMPDIR%\fugawi4.txt +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\track\tracks.gpx -o fugawi -F %TMPDIR%\fugawi5.txt +@echo off +@echo. +CALL :COMPARE reference\track\fugawi.txt %TMPDIR%\fugawi5.txt + +REM +REM Magellan Explorist geocaching format (write-only). +REM +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\gc\GC7FA4.gpx -f reference\gc\GCGCA8.gpx -o maggeo -F %TMPDIR%\maggeo.gs +@echo off +@echo. +CALL :COMPARE reference\gc\maggeo.gs %TMPDIR%\maggeo.gs + +REM +REM IGN Rando tests +REM +@echo on +@echo Testing... +%PNAME% -i ignrando -f reference\track\ignrando-sample.rdn -o ignrando -F %TMPDIR%\ignrando-sample.rdn +%PNAME% -i ignrando -f %TMPDIR%\ignrando-sample.rdn -o gpx -F %TMPDIR%\ignrando-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\ignrando-sample.gpx reference\track\ignrando-sample.gpx + +REM +REM STMwpp "Suunto Trek Manager" WaypointPlus format tests +REM +DEL %TMPDIR%\stmwpp-* +@echo on +@echo Testing... +%PNAME% -i stmwpp -f reference\track\stmwpp-track.txt -o gpx -F %TMPDIR%\stmwpp-track.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\stmwpp-track.gpx reference\track\stmwpp-track.gpx +@echo on +@echo Testing... +%PNAME% -i stmwpp -f reference\route\stmwpp-route.txt -o gpx -F %TMPDIR%\stmwpp-route.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\stmwpp-route.gpx reference\route\stmwpp-route.gpx +@echo on +@echo Testing... +%PNAME% -i stmwpp -f reference\route\stmwpp-route.txt -o stmwpp -F %TMPDIR%\stmwpp-route.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\stmwpp-route.txt reference\route\stmwpp-route.txt + +REM +REM Microsoft AutoRoute 2002 test (read-only) +REM +@echo on +@echo Testing... +%PNAME% -i msroute -f reference\route\msroute-sample.axe -o gpx -F %TMPDIR%\msroute-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\msroute-sample.gpx reference\route\msroute-sample.gpx + +REM +REM CarteSurTable read test +REM +DEL %TMPDIR%\cst-* +@echo on +@echo Testing... +%PNAME% -i cst -f reference\route\cst-sample.cst -o gpx -F %TMPDIR%\cst-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cst-sample.gpx reference\route\cst-sample.gpx + +REM +REM Navigon Mobile Navigator .rte tests +REM +DEL %TMPDIR%\nmn4-sample* +@echo on +@echo Testing... +%PNAME% -i nmn4 -f reference\route\nmn4-sample.rte -o gpx -F %TMPDIR%\nmn4-sample.gpx +@echo off +@echo. +CALL :COMPARE reference\route\nmn4-sample.gpx %TMPDIR%\nmn4-sample.gpx +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\route\nmn4-sample.gpx -o nmn4 -F %TMPDIR%\nmn4-sample-out.rte +@echo off +@echo. +CALL :COMPARE reference\route\nmn4-sample-out.rte %TMPDIR%\nmn4-sample-out.rte + +REM +REM Map&Guide Palm/OS .pdb files (read-only) +REM +DEL %TMPDIR%\mag_pdb-* +@echo on +@echo Testing... +%PNAME% -i mag_pdb -f reference\route\mag_pdb-sample.pdb -o gpx -F %TMPDIR%\mag_pdb-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\mag_pdb-sample.gpx reference\route\mag_pdb-sample.gpx + +REM +REM CompeGPS I/O tests +REM +DEL %TMPDIR%\compegps* +REM read (CompeGPS) +@echo on +@echo Testing... +%PNAME% -i compegps -f reference\compegps.wpt -o gpx -F %TMPDIR%\compegps-wpt.gpx +@echo off +@echo. +CALL :COMPARE reference\compegps-wpt.gpx %TMPDIR%\compegps-wpt.gpx +@echo on +@echo Testing... +%PNAME% -i compegps -f reference\route\compegps.rte -o gpx -F %TMPDIR%\compegps-rte.gpx +@echo off +@echo. +CALL :COMPARE reference\route\compegps-rte.gpx %TMPDIR%\compegps-rte.gpx +@echo on +@echo Testing... +%PNAME% -i compegps -f reference\track\compegps.trk -o gpx -F %TMPDIR%\compegps-trk.gpx +@echo off +@echo. +CALL :COMPARE reference\track\compegps-trk.gpx %TMPDIR%\compegps-trk.gpx +REM write (CompeGPS) +@echo on +@echo Testing... +%PNAME% -i compegps -f reference\compegps.wpt -o compegps -F %TMPDIR%\compegps.wpt +%PNAME% -i compegps -f %TMPDIR%\compegps.wpt -o gpx -F %TMPDIR%\compegps-wpt2.gpx +@echo off +@echo. +CALL :COMPARE reference\compegps-wpt.gpx %TMPDIR%\compegps-wpt2.gpx +@echo on +@echo Testing... +%PNAME% -t -i compegps -f reference\track\compegps.trk -o compegps -F %TMPDIR%\compegps.trk +%PNAME% -i compegps -f %TMPDIR%\compegps.trk -o gpx -F %TMPDIR%\compegps-trk2.gpx +@echo off +@echo. +CALL :COMPARE reference\track\compegps-trk.gpx %TMPDIR%\compegps-trk2.gpx +@echo on +@echo Testing... +%PNAME% -r -i compegps -f reference\route\compegps.rte -o compegps -F %TMPDIR%\compegps.rte +%PNAME% -i compegps -f %TMPDIR%\compegps.rte -o gpx -F %TMPDIR%\compegps-rte2.gpx +@echo off +@echo. +CALL :COMPARE reference\route\compegps-rte.gpx %TMPDIR%\compegps-rte2.gpx + +REM +REM Testing the 'nuketypes' filter is funky. +REM Convert a GPX file to GPX to eliminate jitter. +REM Then nuke the all but the three individual types, merge the result together +REM and verify we got the original back. +REM +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\gdb-sample.gpx -o gpx -F %TMPDIR%\alltypes.gpx +%PNAME% -i gpx -f %TMPDIR%\alltypes.gpx -x nuketypes,tracks,routes -o gpx -F %TMPDIR%\wpts.gpx +%PNAME% -i gpx -f %TMPDIR%\alltypes.gpx -x nuketypes,waypoints,routes -o gpx -F %TMPDIR%\trks.gpx +%PNAME% -i gpx -f %TMPDIR%\alltypes.gpx -x nuketypes,waypoints,tracks -o gpx -F %TMPDIR%\rtes.gpx +%PNAME% -i gpx -f %TMPDIR%\wpts.gpx -f %TMPDIR%\trks.gpx -f %TMPDIR%\rtes.gpx -o gpx -F %TMPDIR%\merged.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\alltypes.gpx %TMPDIR%\merged.gpx + +REM +REM Interpolate filter +REM + +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\track\simpletrack.gpx -x interpolate,distance=50m -o gpx -F %TMPDIR%\interp.gpx +@echo off +@echo. +CALL :COMPARE reference\track\interptrack.gpx %TMPDIR%\interp.gpx +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\track\simpletrack.gpx -x interpolate,time=1 -o gpx -F %TMPDIR%\tinterp.gpx +@echo off +@echo. +CALL :COMPARE reference\track\tinterptrack.gpx %TMPDIR%\tinterp.gpx + +REM +REM Universal CSV - unicsv +REM +ECHO lat,lon,descr,name,notes,unk,unk> %TMPDIR%\unicsv.txt +TYPE reference\mxf.mxf>> %TMPDIR%\unicsv.txt +@echo on +@echo Testing... +%PNAME% -i unicsv -f %TMPDIR%\unicsv.txt -o gpx -F %TMPDIR%\unicsv.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\unicsv.gpx reference\unicsv.gpx + +REM +REM Basic NMEA tests +REM +@echo on +@echo Testing... +%PNAME% -i nmea -f reference\track\nmea -o gpx -F %TMPDIR%\nmea.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\nmea.gpx reference\track\nmea.gpx + +REM +REM Wfff. +REM +@echo on +@echo Testing... +%PNAME% -i wfff -f reference\wfff.xml -o gpsutil -F %TMPDIR%\wfff.gpu +@echo off +@echo. +CALL :COMPARE %TMPDIR%\wfff.gpu reference\wfff.gpu + +REM +REM Garmin MapSource tab delimited text files - garmin_txt +REM +DEL %TMPDIR%\garmin_txt* +REM +REM !!! garmin_txt timestamps are stored in localtime !!! +REM +@echo on +@echo Testing... +%PNAME% -i gdb -f reference\gdb-sample2.gdb -o garmin_txt,utc,prec=9 -F %TMPDIR%\garmin_txt.txt +@echo off +@echo. +CALL :COMPARE reference\garmin_txt.txt %TMPDIR%\garmin_txt.txt +@echo on +@echo Testing... +%PNAME% -i garmin_txt -f reference\garmin_txt.txt -o garmin_txt,prec=9 -F %TMPDIR%\garmin_txt-2.txt +%PNAME% -i garmin_txt -f %TMPDIR%\garmin_txt-2.txt -o garmin_txt,prec=9 -F %TMPDIR%\garmin_txt-3.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\garmin_txt-2.txt %TMPDIR%\garmin_txt-3.txt + diff --git a/mkicondoc.c b/mkicondoc.c new file mode 100644 index 000000000..ac4d30b8f --- /dev/null +++ b/mkicondoc.c @@ -0,0 +1,67 @@ +#include +#include +#include "fatal.c" +#include "util.c" +#include "cet.c" +#define VERSION "1" +#include "globals.c" + + + +tbl_ent(int n, ...) +{ + int i; + char *t; + va_list args; + va_start(args, n); +#if 0 + for (i = 0; i < n; i++) { + t = va_arg(args, char *); +printf("%s%s", i > 0 ? "," : "", t); + + } +#else + t = va_arg(args, char*); + printf("%s", t); +#endif +printf("\n"); + va_end(args); + + +} + +#include "garmin_tables.c" +sort_garmin(const void *a, const void *b) +{ + const icon_mapping_t *ap = a; + const icon_mapping_t *bp = b; + return (case_ignore_strcmp((ap)->icon, (bp)->icon)); +} + +garmin() +{ + icon_mapping_t *i; + int n = 0; + char pbuf[100]; + char mbuf[100]; + + for (i = garmin_icon_table; i->icon; i++) { + n++; + } + + qsort(garmin_icon_table, + n, + sizeof(garmin_icon_table[0]), + sort_garmin); + + for (i = garmin_icon_table; i->icon; i++) { + snprintf(pbuf, sizeof(pbuf), "%d", i->pcxsymnum); + snprintf(mbuf, sizeof(mbuf), "%d", i->mpssymnum); + tbl_ent(3, i->icon, pbuf, mbuf); + } +} + +main() +{ + garmin(); +} diff --git a/mkshort.c b/mkshort.c new file mode 100644 index 000000000..e1e1b96fa --- /dev/null +++ b/mkshort.c @@ -0,0 +1,754 @@ +/* + Generate unique short names. + + Copyright (C) 2003, 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include + +#include "defs.h" + +static const char vowels[] = "aeiouAEIOU"; + +#define DEFAULT_TARGET_LEN 8 +static const char *DEFAULT_BADCHARS = "\"$.,'!-"; + +/* + * Hash table tunings. The reality is that our hash doesn't have to be + * terribly complex; our strings are short (typically 8-20 bytes) and the + * string hash mixes things up enough that strcmp can generally bail on the + * first byte or two for a mismatch. + */ +#define PRIME 37 + +typedef struct { + unsigned int target_len; + char *badchars; + char *goodchars; + char *defname; + queue namelist[PRIME]; + + /* Various internal flags at end to allow alignment flexibility. */ + unsigned int mustupper:1; + unsigned int whitespaceok:1; + unsigned int repeating_whitespaceok:1; + unsigned int must_uniq:1; +} mkshort_handle; + +typedef struct { + queue list; + char *orig_shortname; + int conflictctr; +} uniq_shortname; + +static struct replacements { + const char *orig; + const char *replacement; +} replacements[] = { + {"zero", "0"}, + {"one", "1"}, + {"two", "2"}, + {"three", "3"}, + {"four", "4"}, + {"five", "5"}, + {"six", "6"}, + {"seven", "7"}, + {"eight", "8"}, + {"nine", "9"}, + {NULL, NULL} +}; + +/* + * We hash all strings as upper case. + */ +unsigned int hash_string(const char *key) +{ + unsigned int hash = 0; + while (*key) { + hash = ((hash<<5) ^ (hash>>27)) ^ toupper(*key++); + } + hash = hash % PRIME; + return hash; +} + +void * +#ifdef DEBUG_MEM +MKSHORT_NEW_HANDLE(DEBUG_PARAMS) +#else +mkshort_new_handle() +#endif +{ + int i; + mkshort_handle *h = xxcalloc(sizeof *h, 1, file, line); + + for (i = 0; i < PRIME; i++) + QUEUE_INIT(&h->namelist[i]); + + h->whitespaceok = 1; + h->badchars = xstrdup(DEFAULT_BADCHARS); + h->target_len = DEFAULT_TARGET_LEN; + h->must_uniq = 1; + h->defname = xstrdup("WPT"); + + return h; +} + +static +uniq_shortname * +is_unique(mkshort_handle *h, char *name) +{ + queue *e, *t; + int hash; + + hash = hash_string(name); + QUEUE_FOR_EACH(&h->namelist[hash], e, t) { + uniq_shortname *z = (uniq_shortname *) e; + if (0 == case_ignore_strcmp(z->orig_shortname, name)) { + return z; + } + } + return (uniq_shortname *) NULL; +} + +static +void +add_to_hashlist(mkshort_handle *h, char *name) +{ + int hash = hash_string(name); + uniq_shortname *s = xcalloc(1, sizeof (uniq_shortname)); + + s->orig_shortname = xstrdup(name); + ENQUEUE_TAIL(&h->namelist[hash], &s->list); +} + +char * +mkshort_add_to_list(mkshort_handle *h, char *name) +{ + uniq_shortname *s; + + while ((s = is_unique(h, name))) { + int dl; + char tbuf[10]; + size_t l = strlen(name); + + s->conflictctr++; + + dl = sprintf(tbuf, ".%d", s->conflictctr); + + if (l + dl < h->target_len) { + name = xrealloc(name, l + dl + 1); + strcat(name, tbuf); + } + else { + strcpy(&name[l-dl], tbuf); + } + } + + add_to_hashlist(h, name); + return name; +} + +void +mkshort_del_handle(short_handle *h) +{ + mkshort_handle *hdr = (mkshort_handle*) *h; + int i; + + if (!h || !hdr) + return; + + for (i = 0; i < PRIME; i++) { + queue *e, *t; + QUEUE_FOR_EACH(&hdr->namelist[i], e, t) { + uniq_shortname *s = (uniq_shortname *) e; +#if 0 + if (global_opts.verbose_status >= 2 && s->conflictctr) { + fprintf(stderr, "%d Output name conflicts: '%s'\n", + s->conflictctr, s->orig_shortname); + } +#endif + dequeue(e); + xfree(s->orig_shortname); + xfree(s); + } + } + /* setshort_badchars(*h, NULL); ! currently setshort_badchars() always allocates something ! */ + if (hdr->badchars != NULL) { + xfree(hdr->badchars); + } + setshort_goodchars(*h, NULL); + if (hdr->defname) { + xfree(hdr->defname); + } + + xfree(hdr); + *h = NULL; +} + +/* + * This is the stuff that makes me ashamed to be a C programmer... + */ + +static +char * +delete_last_vowel(int start, char *istring, int *replaced) +{ + int l; + + /* + * Basically impelement strrchr. + */ + *replaced = 0; + for (l = strlen(istring); l > start; l--) { + if (strchr(vowels, istring[l-1])) { + char *ostring; + /* If vowel is the first letter of a word, keep it.*/ + if (istring[l-2] == ' ') continue; + ostring = xstrdup(istring); + strncpy(&ostring[l-1], &istring[l], 1+strlen(istring)-l); + ostring[strlen(istring)-1] = 0; + *replaced = 1; + strcpy( istring, ostring ); + xfree(ostring); + break; + } + } + return istring; +} + +/* + * Open the slippery slope of literal replacement. Right now, replacements + * are made only at the end of the string. + */ +void +replace_constants(char *s) +{ + struct replacements *r; + int origslen = strlen(s); + + for (r = replacements; r->orig; r++) { + int rl = strlen(r->orig); + /* + * If word is in replacement list and preceeded by a + * space, replace it. + */ + if ((origslen - rl > 1) && + (0 == case_ignore_strcmp(r->orig, &s[origslen - rl])) && + (s[origslen - rl - 1] == ' ')) { + strcpy(&s[origslen - rl], r->replacement); + return ; +} + } +} + + +/* + * Externally callable function to set the max length of the + * strings returned by mkshort(). 0 resets to default. + */ +void +setshort_length(short_handle h, int l) +{ + mkshort_handle *hdl = (mkshort_handle *) h; + if (l == 0) { + hdl->target_len = DEFAULT_TARGET_LEN; + } else { + hdl->target_len = l; + } +} + +/* + * Call with L nonzero if whitespace in the generated shortname is wanted. + */ + +void +setshort_whitespace_ok(short_handle h, int l) +{ + mkshort_handle *hdl = (mkshort_handle *) h; + hdl->whitespaceok = l; +} + +/* + * Call with L nonzero if multiple consecutive whitespace in the + * generated shortname is wanted. + */ + +void +setshort_repeating_whitespace_ok(short_handle h, int l) +{ + mkshort_handle *hdl = (mkshort_handle *) h; + hdl->repeating_whitespaceok = l; +} + +/* + * Set default name given to a waypoint if no valid is possible + * becuase it was filtered by charsets or null or whatever. + */ +void +setshort_defname(short_handle h, const char *s) +{ + mkshort_handle *hdl = (mkshort_handle *) h; + if (s == NULL) { + fatal("setshort_defname called without a valid name."); + } + if (hdl->defname != NULL) + xfree(hdl->defname); + hdl->defname = xstrdup(s); +} + +/* + * Externally callable function to set the string of characters + * that must never appear in a string returned by mkshort. NULL + * resets to default. + */ +void +setshort_badchars(short_handle h, const char *s) +{ + mkshort_handle *hdl = (mkshort_handle *) h; + + if ((hdl->badchars != NULL)) + xfree(hdl->badchars); + hdl->badchars = xstrdup (s ? s : DEFAULT_BADCHARS); +} + +/* + * Only characters that appear in *s are "whitelisted" to appear + * in generated names. + */ +void +setshort_goodchars(short_handle h, const char *s) +{ + mkshort_handle *hdl = (mkshort_handle *) h; + + if (hdl->goodchars != NULL) + xfree(hdl->goodchars); + if (s != NULL) + hdl->goodchars = xstrdup(s); + else + hdl->goodchars = NULL; +} + +/* + * Call with i non-zero if generated names must be uppercase only. + */ +void +setshort_mustupper(short_handle h, int i) +{ + mkshort_handle *hdl = (mkshort_handle *) h; + hdl->mustupper = i; +} + + +/* + * Call with i zero if the generated names don't have to be unique. + * (By default, they are.) + */ +void +setshort_mustuniq(short_handle h, int i) +{ + mkshort_handle *hdl = (mkshort_handle *) h; + hdl->must_uniq = i; +} + +char * +#ifdef DEBUG_MEM +MKSHORT(short_handle h, const char *istring, DEBUG_PARAMS ) +#else +mkshort(short_handle h, const char *istring) +#endif +{ + char *ostring = xxstrdup(istring, file, line); + char *nstring; + char *tstring; + char *cp; + char *np; + int i, l, nlen, replaced; + mkshort_handle *hdl = (mkshort_handle *) h; + + + /* + * A rather horrible special case hack. + * If the target length is "6" and the source length is "7" and + * the first two characters are "GC", we'll assume it's one of the + * the new seven digit geocache numbers and special case whacking + * the 'G' off the front. + */ + if ((hdl->target_len == 6) && (strlen(ostring) == 7) && + (ostring[0] == 'G') && (ostring[1] == 'C')) { + memmove(&ostring[0], &ostring[1], strlen(ostring)); + } + + /* + * Whack leading "[Tt]he", + */ + if (( strlen(ostring) > hdl->target_len + 4) && + (strncmp(ostring, "The ", 4) == 0 || + strncmp(ostring, "the ", 4) == 0)) { + nstring = xxstrdup(ostring + 4, file, line); + xfree(ostring); + ostring = nstring; + } + + /* Eliminate leading whitespace in all cases */ + while (ostring[0] && isspace(ostring[0])) { + /* If orig string has N bytes, we want to copy N-1 bytes + * of the string itself plus the string terminator (which + * matters if the string consists of nothing but spaces) + */ + memmove(&ostring[0], &ostring[1], strlen(ostring)); + } + + if (!hdl->whitespaceok) { + /* + * Eliminate Whitespace + */ + tstring = xxstrdup(ostring, file, line); + l = strlen (tstring); + cp = ostring; + for (i=0;imustupper) { + for (tstring = ostring; *tstring; tstring++) { + *tstring = toupper(*tstring); + } + } + + /* Before we do any of the vowel or character removal, look for + * constants to replace. + */ + + replace_constants(ostring); + + /* + * Eliminate chars on the blacklist. + */ + tstring = xxstrdup(ostring, file, line); + l = strlen (tstring); + cp = ostring; + for (i=0;ibadchars, tstring[i])) + continue; + if (hdl->goodchars && (!strchr(hdl->goodchars, tstring[i]))) + continue; + *cp++ = tstring[i]; + } + *cp = 0; + xfree(tstring); + + /* + * Eliminate repeated whitespace. This can only shorten the string + * so we do it in place. + */ + if (!hdl->repeating_whitespaceok) { + for (i = 0; i < l-1; i++) { + if (ostring[i] == ' ' && ostring[i+1] == ' ') { + memmove(&ostring[i], &ostring[i+1], l-i); + } + } + } + + /* + * Toss vowels to approach target length, but don't toss them + * if we don't have to. We always keep the leading two letters + * to preserve leading vowels and some semblance of pronouncability. + * + * FIXME: There's a boundary case here where we're too aggressive. + * If the target length is "6" we will shorten "Trolley" to "Trlly", + * when we really don't have to. We should throw away one vowel, not + * both. + */ + + /* + * Delete vowels starting from the end. If it fits, quit stomping + * them. If we run out of string, give up. + * + * Skip this test is our target length is arbitrarily considered + * "long" as it turns out a truncated string of full words is easier + * to read than a full string of vowelless words. + * + * It also helps units with speech synthesis. + */ + if ( hdl->target_len < 15) { + replaced = 1; + } else { + replaced = 0; + } + + while (replaced && strlen(ostring) > hdl->target_len) { + ostring = delete_last_vowel(2, ostring, &replaced); + } + + /* + * Next to last thing, we look for trailing numbers and try to + * preserve those. This ensures that. + * Walk in the Woods 1. + * Walk in the Woods 2. + */ + + np = ostring + strlen(ostring); + while ((np != ostring) && *(np-1) && isdigit(*(np-1) )) { + np--; + } + if (np) { + nlen = strlen(np); + } + + /* + * Now brutally truncate the resulting string, preserve trailing + * numeric data. + * If the numeric component alone is longer than our target string + * length, use only what'll fit. + */ + if ((/*i = */strlen(ostring)) > hdl->target_len) { + char *dp = &ostring[hdl->target_len] - strlen(np); + if (dp < ostring) dp = ostring; + memmove(dp, np, strlen(np)); + dp[strlen(np)] = 0; + rtrim(ostring); + } + + /* + * If, after all that, we have an empty string, punt and + * let the must_uniq code handle it. + */ + if (ostring[0] == '\0') { + xfree(ostring); + ostring = xstrdup(hdl->defname); + } + + if (hdl->must_uniq) { + return mkshort_add_to_list(hdl, ostring); + } + return ostring; +} + +/* + * As above, but arg list is a waypoint so we can centralize + * the code that considers the alternate sources. + */ +char * +mkshort_from_wpt(short_handle h, const waypoint *wpt) +{ + /* This probably came from a Groundspeak Pocket Query + * so use the 'cache name' instead of the description field + * which contains placer name, diff, terr, and generally way + * more stuff than should be in any one field... + */ + if (wpt->gc_data.diff && wpt->gc_data.terr && + wpt->notes && wpt->notes[0]) { + return mkshort(h, wpt->notes); + } + + if (wpt->description) { + return mkshort(h, wpt->description); + } + + if (wpt->notes) { + return mkshort(h, wpt->notes); + } + + /* Should probably never actually happen... */ + return NULL; +} + + +#if 0 +char *foo[] = { +"VwthPst# 3700.706N 08627.588W 0000000m View the Past #2 ", +"PilotRoc 3655.270N 08717.173W 0000000m Pilot Rock by CacheAdvance ", +"MrCycsNg 3652.407N 08728.890W 0000000m Mr. Cayces Neighborhood by Ca", +"SOLDIER 3640.691N 08726.660W 0000000m SOLDIER’S TRIBUTE ", +"ZOOMZOOM 3636.659N 08721.793W 0000000m ZOOM ZOOM ZOOM by Feros Family", +"SOCLOSEB 3636.494N 08722.086W 0000000m SO CLOSE BUT YET by Kyle of Fe", +"InSrchfS 3636.363N 08636.363W 0000000m In Search of Steam by BigHank ", +"RdBlngSp 3632.119N 08550.956W 0000000m Red Boiling Springs by Firedog", +"HelngWtr 3631.729N 08550.481W 0000000m Healing Waters by FiredogPotte", +"AHHtheVi 3629.020N 08533.891W 0000000m ogPotter ", +"LstCrkCc 3628.167N 08801.656W 0000000m Lost Creek Cache by Paul Kathy", +"DlvrncTr 3626.412N 08729.249W 0000000m Deliverance Train by Team Skay", +"FrQrtrRn 3438.502N 08646.926W 0000000m Four Quarter Rendezvous by Zay", +"Jstlttlc 3620.647N 08814.298W 0000000m Just a little cache by Paul Ka", +"BrryPtch 3618.786N 08616.344W 0000000m Berry Patch Cache by White Dog", +"AStrllDw 3342.752N 08630.829W 0000000m A Stroll Down Memory Lane by t", +"QunfTnns 3606.413N 08651.962W 0000000m Queen of Tennessee by A182pilo", +"GoneFish 3618.199N 08655.171W 0000000m Gone Fishin' by White Dog Pack", +"GrnwysFn 3610.942N 08642.061W 0000000m Greenways Fence by Ukulele And", +"AStnsThr 3611.240N 08638.324W 0000000m A Stone's Throw by Murrcat & S", +"Nashvlls 3617.112N 08642.359W 0000000m Nashville's Zoo by White Dog P", +"BltzMcr4 3517.127N 08622.211W 0000000m Blitz Micro Number 4 by IHTFP ", +"NkdnthWn 3437.145N 08651.693W 0000000m Naked in the Wind by Zaybex ", +"ANcPlctR 3603.389N 08654.418W 0000000m A Nice Place to Rest by JoGPS ", +"welcomtT 3638.155N 08720.130W 0000000m welcome to TN by Raf of the se", +"welcomtK 3638.956N 08721.011W 0000000m welcome to KY by raf of the se", +"BltzMcr5 3506.191N 08634.277W 0000000m Blitz Micro Number 5 by IHTFP ", +"JmsFmlyG 3615.887N 08649.846W 0000000m James Family Grocery by White ", +"seekngrf 3629.262N 08742.333W 0000000m seekeing refuge by raf of the ", +"SecrtFll 3614.927N 08534.180W 0000000m Secret Falls ", +"ApstlcTh 3613.870N 08645.108W 0000000m Apostolic Thistle Walk by Jame", +"WllIllBD 3609.258N 08637.268W 0000000m Well....I'll Be \"Dammed\" byi", +"BettysBt 3608.857N 08550.564W 0000000m Betty's Booty by White Dog Pac", +"SmthngSm 3439.748N 08643.522W 0000000m Something Smells Fishy by Zayb", +"RckyRd(C 3605.315N 08549.326W 0000000m Rocky Road (Center Hill Lake) ", +"Brdwtchr 3436.605N 08651.243W 0000000m Birdwatcher's Dream by Zaybex ", +"JcksnsHl 3605.185N 08619.439W 0000000m Jackson's Halls by White Dog P", +"FrgttnP2 3509.599N 08633.282W 0000000m Forgotten Park 2 by mdawg & mu", +"SOLDIERS 3640.691N 08726.660W 0000000m SOLDIERS TRIBUTE by Feros Fami", +"EndofRop 3433.820N 08650.460W 0000000m End of Rope by Big Rock ", +"VwthPst1 3659.263N 08627.114W 0000000m View the Past #1 by wkgraham ", +"VwthPst2 3700.706N 08627.588W 0000000m View the Past #2 by wkgraham ", +"Trash#8 3603.102N 08655.144W 0000000m Cache In Trash Out # 8 ", +"SlwwwwCc 3602.543N 08535.953W 0000000m Sloowwww Cache by Tntcacher ", +"Leavttbv 3602.514N 08638.686W 0000000m Leave it to beaver by A182pilo", +"WhrrthHr 3436.594N 08654.759W 0000000m Where are the Horses? by Zaybe", +"ButtonCc 3433.401N 08645.294W 0000000m Button Cache by Zaybex ", +"MrcsLbrr 3436.842N 08655.972W 0000000m Marco's Library by Marco ", +"Octopus 3526.743N 08534.757W 0000000m Octopus by White Dog Pack ", +"WtrFllsV 3544.140N 08527.861W 0000000m Water Falls Valley by Cave Rat", +"DeddrpPn 3448.126N 08719.696W 0000000m Dead-drop Pink by Marco ", +"JWhlrRvr 3448.157N 08719.914W 0000000m Joe Wheeler River Walk by Marc", +"CvSprngs 3432.797N 08651.084W 0000000m Cave Springs Cache by Marco.. ", +"CnyFrkOv 3550.876N 08518.446W 0000000m Fork Overlook ", +"SheepsCa 3550.527N 08519.480W 0000000m Sheep's Cave ", +"VrgnFlls 3550.308N 08519.904W 0000000m Virgin Falls Cache ", +"ShrtctVr 3550.170N 08519.590W 0000000m Shortcut Virtual ", +"KlylFlls 3549.105N 08539.814W 0000000m Klaylee Falls Cache by pattytr", +"FshngfrB 3548.923N 08538.558W 0000000m BADGER by M&Mk ", +"TpfthHll 3548.808N 08601.722W 0000000m Top of the Hill Pet Cache by M", +"TwnFllsC 3548.560N 08537.996W 0000000m Twin Falls Cache by SLCREW a", +"WtchsCst 3548.197N 08537.673W 0000000m Witch's Castle Keys by SLCREW ", +"ThatCave 3544.901N 08522.854W 0000000m That Cave by JaDan150 and AprJ", +"BssltwnW 3541.174N 08801.489W 0000000m Busseltown Wildlife Refuge by ", +"Riverfrn 3540.968N 08546.995W 0000000m Riverfront by SLCREW and M&M", +"Basement 3540.086N 08521.304W 0000000m The Basement ", +"EfflTwrC 3617.132N 08818.371W 0000000m Eiffel Tower Cache by Dick Wan", +"KeyholeC 3544.562N 08524.098W 0000000m Keyhole Cave by Cave Rat ", +"(MC^2)Mn 3444.990N 08630.218W 0000000m (MC^2) Monte Sano Cuts Cache b", +"WildctCc 3636.823N 08808.087W 0000000m Wildcat Cache by The Storm ", +"NAlbm/Tn 3444.365N 08632.688W 0000000m N. Alabama / Tennessee Valley ", +"CalebsCa 3444.215N 08633.103W 0000000m Caleb's Cave by Papaw and Cale", +"MntSnPrs 3444.201N 08632.591W 0000000m Monte Sano Preserve by Evan & ", +"FltRckFl 3444.475N 08629.958W 0000000m Flat Rock Falls Cache by Jason", +"PanormCc 3443.961N 08631.638W 0000000m The Panorama Cache by IHTFP an", +"TnnssScv 3602.861N 08652.751W 0000000m Tennessee Scavenger Hunt Cache", +"Geocache 3435.209N 08655.968W 0000000m Geocache by Papaw & Caleb ", +"Skellig 3444.100N 08656.566W 0000000m Skellig by Zaybex ", +"Deceptio 3433.450N 08655.711W 0000000m Deception by Papaw and Caleb ", +"AwlknthD 3433.310N 08655.635W 0000000m A walk in the Desert by Papa", +"MiniMsQs 3558.934N 08650.674W 0000000m Mini Me's Quest by CrotalusRex", +"BakrsBlf 3541.891N 08717.300W 0000000m Bakers Bluff by Flower Child &", +"GoFlyAKi 3435.664N 08659.267W 0000000m Go Fly A Kite by Marco.. ", +"FlntCrkA 3432.028N 08656.806W 0000000m Flint Creek Adventure by Marco", +"HonordMn 3534.680N 08612.557W 0000000m Honored Mount by Southpaw ", +"SafariZo 3440.697N 08700.774W 0000000m Safari Zone by Zaybex ", +"JckDnlsC 3517.077N 08622.260W 0000000m Jack Daniels Cache by Rmearse ", +"FrgttnPr 3509.599N 08633.282W 0000000m Forgotten Park by mdawg & muff", +"DntOvrlk 3513.326N 08616.031W 0000000m Dont Overlook Me Cache ", +"ArYStmpd 3513.039N 08615.110W 0000000m Are You Stumped Yet? cache ", +"CchtthBn 3512.532N 08614.691W 0000000m Cache at the Bend ", +"Thtsnkng 3609.009N 08530.314W 0000000m That sinking feeling by Tntcac", +"GamersCc 3449.136N 08635.836W 0000000m mer's Cache by avoral ", +"CchMIfYC 3452.455N 08620.648W 0000000m Cache Me If You Can! by Glen H", +"SavageVs 3526.915N 08535.136W 0000000m Savage Vista by White Dog Pack", +"PrtrnG15 3555.479N 08653.274W 0000000m Praetorian Guards Hail Caesar #15!", +"WtrlnAmp 3443.722N 08632.535W 0000000m Waterline Amphitheater by Fath", +"BysLttlC 3447.569N 08638.448W 0000000m Boys' Little Cache by Zaybex ", +"DrgnsBrt 3443.779N 08635.188W 0000000m Dragon's Breath by Zaybex ", +"CryBbyHl 3430.733N 08657.362W 0000000m Cry Baby Hollow Cache by La Pa", +"Parmer 3606.218N 08651.590W 0000000m Parmer by A182pilot & Family ", +"JnnfrndJ 3438.141N 08632.991W 0000000m Jennifer and Jonathans Cliff C", +"ALDRIDGE 3435.305N 08632.868W 0000000m ALDRIDGE CREEK LOTTA LOOT!! by", +"RcktCtyS 3440.032N 08631.352W 0000000m Rocket City Stash by David Upt", +"TrgcAccd 3608.561N 08648.381W 0000000m Tragic Accident by Campaholics", +"FALLENTR 3439.210N 08631.104W 0000000m FALLEN TREE 4 MILE POST by zac", +"TrshOt15 3558.964N 08646.064W 0000000m Cache In Trash Out # 15 by Jo", +"TrshOt13 3602.214N 08650.428W 0000000m Cache In Trash Out #13 by JoGP", +"PrcysDrp 3604.312N 08653.465W 0000000m Percys Dripping Springs by KLi", +"TrshOt14 3605.292N 08648.560W 0000000m Cache In Trash Out # 14 by JoG", +"PrtrnGr5 3557.621N 08640.278W 0000000m Praetorian Guards Hail Caesar #5!", +"PrtrnGr4 3557.370N 08640.201W 0000000m Praetorian Guards Hail Caesar #4!", +"PrtrnGr3 3557.250N 08640.047W 0000000m Praetorian Guards Hail Caesar #3!", +"GrnMntnC 3439.120N 08631.100W 0000000m Green Mountain Cache by Steve ", +"TrshOt12 3605.330N 08635.817W 0000000m Cache In Trash Out #12 by JoGP", +"BlncngAc 3608.579N 08648.120W 0000000m Balancing Act by Campaholics ", +"DittoCac 3434.652N 08633.310W 0000000m Ditto Cache by mookey ", +"EraserCc 3431.888N 08633.024W 0000000m Eraser Cache by Zaybex ", +"FrMlPstE 3439.440N 08630.180W 0000000m Four Mile Post Extension Cache", +"MllrdFxC 3439.578N 08706.552W 0000000m Mallard-Fox Creek Cache by bam", +"FireCach 3443.908N 08630.318W 0000000m he by Glen Pam Chase M ", +"FlntRvrC 3443.170N 08625.990W 0000000m Flint River Canoe Cache by Ran", +"ArabinCc 3419.104N 08628.765W 0000000m The Arabian Cache by WesNSpace", +"CvrdBrdg 3412.406N 08659.392W 0000000m Covered Bridge Cache by pmarkh", +"MilesTCc 3424.470N 08611.720W 0000000m Miles Too Cache by Rmearse ", +"MbryOvrl 3423.803N 08611.922W 0000000m Mabrey Overlook Me by DDVaughn", +"LwEnfrcm 3423.218N 08612.258W 0000000m Law Enforcement Cache by DDVau", +"GrndDddy 3423.128N 08612.025W 0000000m Grand Daddys Home by Rmearse ", +"BamaCach 3421.459N 08611.686W 0000000m The Bama Cache by DDVaughn & T", +"Canyons 3440.085N 08600.910W 0000000m The Canyons by Aubrey and Josh", +"ADamGodV 3511.677N 08616.587W 0000000m A Dam Good View by mdawg & muf", +"UNDERTHE 3446.918N 08739.790W 0000000m UNDER THE ROCK by RUNNINGWILD ", +"SQUIRREL 3448.712N 08741.681W 0000000m SQUIRREL'S NEST by RUNNINGWILD", +"WlknthPr 3448.273N 08741.844W 0000000m Walk in the Park by Runningwil", +"NetsClue 3448.494N 08741.977W 0000000m Net's Clues by Runningwild Adv", +"NatrlBrd 3405.583N 08736.909W 0000000m Natural Bridge by Southeast Xt", +"TrnglPrk 3341.448N 08640.980W 0000000m Triangle Park Cache by Charles", +"LttlRvrI 3421.855N 08539.597W 0000000m Little River Initiative by spa", +"GimmShlt 3430.087N 08536.834W 0000000m Gimme Shelter by Big Rock & Po", +"GnomeTrs 3433.081N 08535.849W 0000000m Gnome Treasure by Big Rock ", +"FlyingTr 3608.594N 08648.179W 0000000m Flying Torso by Campaholics ", +"CultivtC 3608.582N 08648.064W 0000000m Cultivate a Cure by Campahol" +} +; + +main() +{ + char **foop = foo; + int r; + + printf("%s\n", mkshort("The Troll")); + printf("%s\n", mkshort("EFI")); + printf("%s\n", mkshort("the Troll")); + printf("%s\n", mkshort("the Trolley")); + printf("%s\n", mkshort("The Troll Lives Under The Bridge")); + printf("%s\n", mkshort("The \"Troll\" Lives Under $$ The Bridge!")); + printf("%s\n", mkshort("The Trolley Goes Round")); + printf("%s\n", mkshort("Cache In / Trash Out #1")); + printf("%s\n", mkshort("Cache In / Trash Out #2")); + printf("%s\n", mkshort("Cache In / Trash Out #137")); + + while (0 && *foop) { + printf("%s %s\n", mkshort(*foop+39), *foop+39); + foop++; + } + +printf("%s\n", delete_last_vowel(0, "the quick brown foo", &r)); +printf("%s\n", delete_last_vowel(0, "the quick brown fox", &r)); +printf("%s\n", delete_last_vowel(0, "xxx", &r)); +printf("%s\n", delete_last_vowel(0, "ixxx", &r)); +printf("%s\n", delete_last_vowel(0, "aexxx", &r)); + +} +#endif diff --git a/mkstyle.sh b/mkstyle.sh new file mode 100755 index 000000000..19db383a3 --- /dev/null +++ b/mkstyle.sh @@ -0,0 +1,26 @@ + +echo "/* This file is machine-generated from the contents of style/ */" +echo "/* by mkstyle.sh. Editing it by hand is an exeedingly bad idea. */" +echo + +echo "#include \"defs.h\"" +echo "#if CSVFMTS_ENABLED" +nstyles="0" +for i in style/*.style +do + A=`basename $i | sed "s/.style$//"` + [ $A = "README" ] && continue + [ $A = "custom.style" ] && continue + ALIST="{ \"$A\", $A } , $ALIST" + echo "static char $A[] = " + sed 's/\\/\\\\/;s/"/\\"/g;s/\(^.\)/"\1/g;s/\(.$\)/\1\\n"/g' $i + echo ";" + nstyles=`expr $nstyles + 1`; +done +echo "style_vecs_t style_list[] = {$ALIST {0,0}};" +echo "size_t nstyles = $nstyles;" +echo "#else /* CSVFMTS_ENABLED */" +echo "style_vecs_t style_list[] = {{0,0}};" +echo "size_t nstyles = 0;" +echo "#endif /* CSVFMTS_ENABLED */" + diff --git a/msroute.c b/msroute.c new file mode 100644 index 000000000..c3fb767c4 --- /dev/null +++ b/msroute.c @@ -0,0 +1,683 @@ +/* + + Support for Microsoft AutoRoute 2002 ".axe" files, + + Copyright (C) 2005,2007,2008 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#include "defs.h" +#include "jeeps/gpsmath.h" +#include + +#define MYNAME "msroute" + +#undef OLE_DEBUG + +static gbfile *fin; + +static arglist_t msroute_args[] = +{ + ARG_TERMINATOR +}; + +/* MS-AutoRoute structures */ + +typedef struct msroute_head_s +{ + gbuint32 U1; /* 58/02/00/00 */ + char masm[4]; /* "MASM " */ + gbuint32 U2; + gbuint32 U3; + gbint32 waypts; + gbuint32 U5; + gbuint32 U6; + gbuint32 U7; + gbuint32 U8; + gbuint32 U9; + gbuint32 U10; + gbuint32 U11; + gbuint32 U12; + gbuint32 U13; + gbuint32 U14; + gbuint32 U15; + gbuint32 U16; +// short U17; +// char U18; +} msroute_head_t; + +#define MSROUTE_OBJ_NAME "Journey" + +/* simple ole file reader */ + +#define OLE_MAX_NAME_LENGTH 32 +#define OLE_HEAD_FAT1_CT (512-0x4c)/4 + +#define BLOCKS(a, b) (((a) + (b) - 1) / (b)) + +static const unsigned char ole_magic[8] = +{ + 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 +}; + +/* + The ole implementation looks like a FAT filesystem. + Thatswhy i use in code fat1 as item for the "big blocks" or bbd + and fat2 for "small blocks" (sbd). + + Remarks: + + * in the moment ole_size1 and sector_sz represents the same value + * in OLE_DEBUG mode: successfully tested with 64MB++ standard MS doc's (PowerPoint, Word) +*/ + +typedef struct ole_head_s +{ + char magic[8]; + char clsid[16]; + gbuint16 rev; /* offset 0x18 */ + gbuint16 ver; /* offset 0x1a */ + gbint16 byte_order; /* offset 0x1c */ + gbuint16 fat1_size_shift; /* offset 0x1e */ + gbuint16 fat2_size_shift; /* offset 0x20 */ + gbuint16 U7; /* offset 0x22 */ + gbuint32 U8; /* offset 0x24 */ + gbuint32 U9; /* offset 0x28 */ + gbint32 fat1_blocks; /* offset 0x2c */ + gbint32 prop_start; /* offset 0x30 */ + gbuint32 U12; /* offset 0x34 */ + gbuint32 fat1_min_size; /* offset 0x38 */ + gbint32 fat2_start; /* offset 0x3c */ + gbint32 fat2_blocks; /* offset 0x40 */ + gbint32 fat1_extra_start; /* offset 0x44 */ + gbint32 fat1_extra_ct; /* offset 0x48 */ + gbint32 fat1[OLE_HEAD_FAT1_CT]; /* offset 0x4c */ +} ole_head_t; + +typedef struct ole_prop_s +{ + gbuint16 name[32]; + gbuint16 name_sz; /* offset 0x40 */ + char ole_typ; /* offset 0x42 */ + char U1; /* offset 0x43 */ + gbuint32 previous; /* offset 0x44 */ + gbuint32 next; /* offset 0x48 */ + gbuint32 dir; /* offset 0x4c */ + gbuint32 U5; /* offset 0x50 */ + gbuint32 U6; /* offset 0x54 */ + gbuint32 U7; /* offset 0x58 */ + gbuint32 U8; /* offset 0x5c */ + gbuint32 U9; /* offset 0x60 */ + gbuint32 U10; /* offset 0x64 */ + gbuint32 U11; /* offset 0x68 */ + gbuint32 U12; /* offset 0x6c */ + gbuint32 U13; /* offset 0x70 */ + gbint32 first_sector; /* offset 0x74 */ + gbint32 data_sz; /* offset 0x78 */ + gbuint32 U16; /* offset 0x7c */ +} ole_prop_t; + +#define DIR_ITEM_SIZE sizeof(ole_prop_t) + +static int sector_sz = 512; + +#ifndef min +#define min(a,b) ((a) < (b)) ? (a) : (b) +#endif +#ifndef max +#define max(a,b) ((a) > (b)) ? (a) : (b) +#endif + +static gbint32 *ole_fat1 = NULL; +static gbint32 *ole_fat2 = NULL; +static int ole_fat1_ct; +static int ole_fat2_ct; +static int ole_size1; +static int ole_size2; +static int ole_size1_min = 4096; +static ole_prop_t *ole_dir = NULL; +static int ole_dir_ct; +static ole_prop_t *ole_root = NULL; +static char **ole_root_sec = NULL; +static int ole_root_sec_ct; + +/* local helpers */ + +static void +le_read32_buff(int *buff, const int count) +{ + int i; + for (i = 0; i < count; i++) + buff[i] = le_read32(&buff[i]); +} + +/* simple OLE file reader */ + +static void +ole_read_sector(const int sector, void *target, const char full) +{ + int res; + + res = gbfseek(fin, (sector + 1) * sector_sz, SEEK_SET); + is_fatal((res != 0), MYNAME ": Could not seek file to sector %d!", sector + 1); + res = gbfread(target, 1, sector_sz, fin); + is_fatal( + ((res < 0) || (full && (res < sector_sz))), + MYNAME ": Read error (%d, sector %d) on file \"%s\"!", res, sector, fin->name); +} + +static ole_prop_t * +ole_find_property(const char *property) +{ + int i; + + for (i = 0; i < ole_dir_ct; i++) + { + int len, test; + char *str; + ole_prop_t *item; + + item = &ole_dir[i]; + if ((item->ole_typ != 1) && (item->ole_typ != 2) && (item->ole_typ != 5)) continue; + if ((item->data_sz <= 0) || (item->name_sz <= 0)) continue; + + len = min(OLE_MAX_NAME_LENGTH, item->name_sz / 2); + str = cet_str_uni_to_utf8((short *)&item->name, len); + test = case_ignore_strcmp(str, property); + xfree(str); + + if (test == 0) return item; + } + is_fatal((1), MYNAME ": \"%s\" not in property catalog!", property); + return 0; +} + +static char * +ole_read_stream(const ole_prop_t *property) +{ + const char *action = "ole_read_stream"; + int len, sector, big, blocksize, offs, left; + int i; + int *fat; + char *buff; + + len = property->data_sz; + + if (len >= ole_size1_min) + { + big = 1; + blocksize = ole_size1; + fat = ole_fat1; + } + else + { + big = 0; + blocksize = ole_size2; + fat = ole_fat2; + } + + offs = 0; + left = len; + sector = property->first_sector; + + i = ((len + blocksize - 1) / blocksize) * blocksize; + buff = xmalloc(i); /* blocksize aligned */ + + if (big != 0) + { + while (left > 0) + { + int bytes = (left <= blocksize) ? left : blocksize; + ole_read_sector(sector, buff + offs, (bytes >= sector_sz)); + left -= bytes; + offs += bytes; + if (left > 0) + { + sector = fat[sector]; + is_fatal((sector < 0), MYNAME ": Broken stream (%s)!", action); + } + } + } + else + { + int chain = sector; + int blocks = (len + blocksize - 1) / blocksize; + int blocks_per_sector = sector_sz / blocksize; + + offs = 0; + + while (blocks-- > 0) + { + char *temp; + int block_offs; + + is_fatal((chain < 0), MYNAME ": Broken stream (%s)!", action); + + sector = chain / blocks_per_sector; + is_fatal((sector >= ole_root_sec_ct), MYNAME ": Broken stream (%s)!", action); + + temp = ole_root_sec[sector]; + is_fatal((temp == NULL), MYNAME ": Broken stream (%s)!", action); + + block_offs = (chain % blocks_per_sector) * blocksize; + + memcpy(buff + offs, temp + block_offs, blocksize); + + offs += blocksize; + chain = fat[chain]; + } + } + return buff; +} + + +static char * +ole_read_property_stream(const char *property_name, int *data_sz) +{ + ole_prop_t *property; + char *result; + + if ((property = ole_find_property(property_name)) == NULL) return NULL; + + result = ole_read_stream(property); + if ((result != NULL) && (data_sz != NULL)) + *data_sz = property->data_sz; + + return result; +} + +#ifdef OLE_DEBUG + +static void +ole_test_properties() +{ + int i; + + for (i = 0; i < ole_dir_ct; i++) + { + char *temp; + char name[OLE_MAX_NAME_LENGTH + 1]; + ole_prop_t *p = &ole_dir[i]; + + if ((p->ole_typ != 1) && (p->ole_typ != 2) && (p->ole_typ != 5)) continue; + if ((p->data_sz <= 0) || (p->name_sz <= 0)) continue; + + temp = cet_str_uni_to_utf8(&p->name, min(p->name_sz / 2, OLE_MAX_NAME_LENGTH)); + strncpy(name, temp, sizeof(name)); + xfree(temp); + + printf(MYNAME ": ole_test_properties for \"%s\" (%d bytes):", name, p->data_sz); + + if ((case_ignore_strcmp(name, "Root Entry") == 0) || + (p->data_sz < ole_size1_min)) + { + printf(" skipped...\n"); + continue; + } + else + { + int sector = p->first_sector; + int data_sz = p->data_sz; + int block_size = ole_size1; /* sector_sz */ + + printf("\n"); + + while ((data_sz > 0) && (sector >= 0)) + { + int bytes = (data_sz > block_size) ? block_size : data_sz; + int prev = sector; + + data_sz -= bytes; + sector = ole_fat1[sector]; + if (sector == -3) + { + printf(MYNAME ": special block at %d\n", prev); + if ((prev + 2) < ole_fat1_ct) + sector = ole_fat1[prev + 1]; + printf(MYNAME "-new sector: %d\n", sector); + } + } + is_fatal((data_sz != 0), MYNAME ": Error in fat1 chain, sector = %d, %d bytes (=%d blocks) left!", + sector, data_sz, BLOCKS(data_sz, block_size)); + } + } +} +#endif + +static void +ole_init(void) +{ + ole_head_t head; + int i, i_offs, sector, count, left; + int fat1_extra[128]; + + ole_fat1 = NULL; + ole_fat2 = NULL; + + sector_sz = 512; /* fixed for the moment */ + + is_fatal((sizeof(head) != sector_sz), + MYNAME ": (!) internal error - invalid header size (%lu)!", + (unsigned long) sizeof(head)); + + memset(&head, 0, sizeof(head)); + gbfread(&head, sizeof(head), 1, fin); + + is_fatal((strncmp(head.magic, (char *) ole_magic, sizeof(ole_magic)) != 0), MYNAME ": No MS document."); + + head.rev = le_read16(&head.rev); + head.ver = le_read16(&head.ver); + head.byte_order = le_read16(&head.byte_order); + head.fat1_size_shift = le_read16(&head.fat1_size_shift); + head.fat2_size_shift = le_read16(&head.fat2_size_shift); + head.fat1_blocks = le_read32(&head.fat1_blocks); + head.prop_start = le_read32(&head.prop_start); + head.fat1_min_size = le_read32(&head.fat1_min_size); + head.fat2_start = le_read32(&head.fat2_start); + head.fat2_blocks = le_read32(&head.fat2_blocks); + head.fat1_extra_start = le_read32(&head.fat1_extra_start); + head.fat1_extra_ct = le_read32(&head.fat1_extra_ct); + le_read32_buff(&head.fat1[0], OLE_HEAD_FAT1_CT); + + ole_size1 = (1 << head.fat1_size_shift); + ole_size2 = (1 << head.fat2_size_shift); + ole_size1_min = head.fat1_min_size; + +#ifdef OLE_DEBUG + printf(MYNAME "-head: (version.revision) = %d.%d\n", head.ver, head.rev); + printf(MYNAME "-head: byte-order = %d\n", head.byte_order); + printf(MYNAME "-head: big fat start sector = %d (0x%x)\n", head.fat1[0], (head.fat1[0] + 1) * 512); + printf(MYNAME "-head: big fat blocks = %d\n", head.fat1_blocks); + printf(MYNAME "-head: big fat block size = %d\n", (1 << head.fat1_size_shift)); + printf(MYNAME "-head: small fat start sector = %d\n", head.fat2_start); + printf(MYNAME "-head: small fat blocks = %d\n", head.fat2_blocks); + printf(MYNAME "-head: small fat block size = %d\n", (1 << head.fat2_size_shift)); + printf(MYNAME "-head: big fat minimum length = %d\n", head.fat1_min_size); + printf(MYNAME "-head: property catalog start sector = %d\n", head.prop_start); + printf(MYNAME "-head: additional big fat blocks = %d\n", head.fat1_extra_ct); + printf(MYNAME "-head: additional big fat start sector = %d (0x%x)\n", head.fat1_extra_start, (head.fat1_extra_start + 1) * 512); +#endif + + is_fatal((head.byte_order != -2), MYNAME ": Unsupported byte-order %d", head.byte_order); +#if 0 + sector_sz = ole_size1; /* i'll implement this, if i get an MS-doc (ole) */ + /* with "sector_sz" other than 512 */ +#else + is_fatal((ole_size1 != 512), MYNAME ": Unsupported sector size %d", ole_size1); +#endif + ole_fat1 = xmalloc(head.fat1_blocks * sector_sz); + ole_fat1_ct = (head.fat1_blocks * sector_sz) / sizeof(gbint32); + +#ifdef OLE_DEBUG + printf(MYNAME "-big fat: %d maximum sectors, size in memory %d, max. datasize %d bytes\n", + ole_fat1_ct, head.fat1_blocks * sector_sz, head.fat1_blocks * sector_sz * sector_sz / sizeof(gbint32)); +#endif + + i_offs = 0; /* load "big fat" into memory */ + left = head.fat1_blocks; + count = (left > OLE_HEAD_FAT1_CT) ? OLE_HEAD_FAT1_CT : left; + + for (i = 0; i < count; i++) + { + sector = head.fat1[i]; + ole_read_sector(sector, &ole_fat1[i_offs], 1); + i_offs += ole_size1 / 4; + } + + left -= count; + + if (left > 0) + { + sector = head.fat1_extra_start; + + while ((left > 0) && (sector >= 0)) + { + ole_read_sector(sector, &fat1_extra, 1); + le_read32_buff(&fat1_extra[0], 128); + + count = (left < 127) ? left : 127; + for (i = 0; i < count; i++) + { + ole_read_sector(fat1_extra[i], &ole_fat1[i_offs], 1); + i_offs += ole_size1 / 4; + } + left -= count; + if (left > 0) + sector = fat1_extra[127]; + } + is_fatal((left > 0), MYNAME ": Broken stream!"); + } + if (ole_fat1_ct > 0) + le_read32_buff(&ole_fat1[0], ole_fat1_ct); + + + /* load fat2 "small fat" into memory */ + + sector = head.fat2_start; + if (sector >= 0) + { + count = 0; + do + { + if (ole_fat2 == NULL) + ole_fat2 = (int *)xmalloc((count + 1) * sector_sz); + else + ole_fat2 = (int *)xrealloc(ole_fat2, (count + 1) * sector_sz); + + ole_read_sector(sector, (char *)ole_fat2 + (count * sector_sz), 1); + sector = ole_fat1[sector]; + + count++; + } + while (sector >= 0); + + ole_fat2_ct = (count * sector_sz) / sizeof(gbint32); + if (ole_fat2_ct > 0) + le_read32_buff(&ole_fat2[0], ole_fat2_ct); + } + + /* load directory (property catalog) */ + + sector = head.prop_start; + is_fatal((sector < 0), MYNAME ": Invalid file (no property catalog)!"); + + count = 0; + while (sector >= 0) + { + if (ole_dir == NULL) + ole_dir = (void *)xmalloc((count + 1) * sector_sz); + else + ole_dir = (void *)xrealloc(ole_dir, (count + 1) * sector_sz); + + ole_read_sector(sector, (char *)ole_dir + (count * sector_sz), 1); + sector = ole_fat1[sector]; + + count++; + } + ole_dir_ct = (count * sector_sz) / sizeof(ole_prop_t); + + /* fix endianess of property catalog */ + + for (i = 0; i < ole_dir_ct; i++) + { + ole_prop_t *item = &ole_dir[i]; + + item->first_sector = le_read32(&item->first_sector); + item->data_sz = le_read32(&item->data_sz); + } + + ole_root = ole_find_property("Root Entry"); + + /* read fat2 data sectors given by "Root Entry" */ + + ole_root_sec_ct = (ole_root->data_sz + (sector_sz - 1)) / sector_sz; + ole_root_sec = xcalloc(ole_root_sec_ct + 1, sizeof(char *)); + + i = 0; + sector = ole_root->first_sector; + while (sector >= 0) + { + char *temp; + + temp = ole_root_sec[i++] = xmalloc(sector_sz); + + ole_read_sector(sector, temp, 1); + sector = ole_fat1[sector]; + } +#ifdef OLE_DEBUG + ole_test_properties(); +#endif +} + +static void +ole_deinit(void) +{ + if (ole_root_sec != NULL) + { + int i; + for (i = 0; i < ole_root_sec_ct; i++) + { + char *c; + if ((c = ole_root_sec[i])) xfree(c); + } + xfree(ole_root_sec); + } + if (ole_fat1 != NULL) xfree(ole_fat1); + if (ole_fat2 != NULL) xfree(ole_fat2); + if (ole_dir != NULL) xfree(ole_dir); +} + +/* global MS AutoRoute functions */ + +static void +msroute_read_journey(void) +{ + int bufsz; + char *buff; + + buff = ole_read_property_stream(MSROUTE_OBJ_NAME, &bufsz); + + if ((buff != NULL) && (bufsz > 0)) + { + msroute_head_t *head = (msroute_head_t *)buff; + unsigned char *cin, *cend; + int count = 0; + route_head *route; + waypoint *wpt; + char version; + + is_fatal((strncmp(head->masm, "MASM", 4) != 0), MYNAME ": Invalid or unknown data!"); + + version = buff[0x14]; + is_fatal((version < 1) || (version > 7), MYNAME ": Unsupported version %d!", version); + + cin = (unsigned char *)buff + 71; // (at least?) sizeof(msroute_head_t); + cend = (unsigned char *)buff + bufsz; + + route = route_head_alloc(); + route_add_head(route); + + head->waypts = le_read32(&head->waypts); + + while (count < head->waypts) + { + int len; + + /* after version 6 we've seen data with different header length */ + /* now we try to find the next pair of names in buff */ + + while (1) { + len = *cin; + if ((cin + 120) > cend) { + cin = NULL; + break; + } + if ((cin + len < cend) && /* within buff ? */ + (cin[len + 3] == 0xff) && /* 0xff before next length byte ? */ + (cin[len + 4] == len) && /* wide string of same length ? */ + (le_read16(cin + len + 1) == 0xfeff)) { + break; + } + cin++; + } + if (cin == NULL) break; + + wpt = waypt_new(); + + len = *cin++; /* length of shortname */ + cin += len; + cin += 3; /* 0xfffeff */ + + len = *cin++; + wpt->shortname = cet_str_uni_to_utf8((const short *)cin, len); + cin += (len * 2); /* seek over wide string */ + cin += (5 * sizeof(gbint32)); /* five unknown DWORDs */ + + /* offs 12 !!!! Latitude int32 LE */ + /* offs 16 !!!! Longitude int32 LE */ + wpt->latitude = GPS_Math_Semi_To_Deg(le_read32(cin+12)); + wpt->longitude = GPS_Math_Semi_To_Deg(le_read32(cin+16)); + + cin += (23 * sizeof(gbint32)); + cin += 3; + +#ifdef OLE_DEBUG + waypt_add(waypt_dupe(wpt)); /* put to wpt-list to see results if no output is specified */ +#endif + route_add_wpt(route, wpt); + count++; + } + } + + if (buff != NULL) + xfree(buff); +} + +/* registered callbacks */ + +static void msroute_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); + + ole_init(); +} + +static void msroute_rd_deinit(void) +{ + ole_deinit(); + + gbfclose(fin); +} + +static void msroute_read(void) +{ + msroute_read_journey(); +} + +ff_vecs_t msroute_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read }, + msroute_rd_init, + NULL, + msroute_rd_deinit, + NULL, + msroute_read, + NULL, + NULL, + msroute_args, + CET_CHARSET_UTF8, 1 /* CET-REVIEW */ +}; diff --git a/msvc/Debug.empty b/msvc/Debug.empty new file mode 100644 index 000000000..e69de29bb diff --git a/msvc/Expat/expat.h b/msvc/Expat/expat.h new file mode 100644 index 000000000..455e5b8fe --- /dev/null +++ b/msvc/Expat/expat.h @@ -0,0 +1,1001 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef XmlParse_INCLUDED +#define XmlParse_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(XML_USE_MSC_EXTENSIONS) +#define XMLCALL __cdecl +#elif defined(__GNUC__) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1 +#define XML_STATUS_OK XML_STATUS_OK +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + XML_ERROR_UNBOUND_PREFIX +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( + void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(XMLCALL *malloc_fcn)(size_t size); + void *(XMLCALL *realloc_fcn)(void *ptr, size_t size); + void (XMLCALL *free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + When a namespace is not declared, the name and prefix will be + passed through without expansion. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( + void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, + const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( + void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( + void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( + XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (XMLCALL *convert)(void *data, const char *s); + void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( + void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(long) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 1 +#define XML_MINOR_VERSION 95 +#define XML_MICRO_VERSION 7 + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlParse_INCLUDED */ diff --git a/msvc/Expat/libexpat.dll b/msvc/Expat/libexpat.dll new file mode 100755 index 0000000000000000000000000000000000000000..4c925de3579d7bc74ea0c85f4d096d0070e09da1 GIT binary patch literal 143360 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

o`}M#~TH!R_w*#*Mmjd$$ zBmS;@F=EVTE1s`+zWn<1&GYy3_v_a$zkeV&AV2@8fepJ!^GV6%hSi>Vku-qA=JY;k)Shj7LoopF4IJM_Gb1;GY@g&GB@h(}AreLCVE z3kOkUWPwQOLb03;Qa|Z88GRq2m2ebfun*vL<@xV?TZMZjFcG*0NLMdJLQSv~1v4ez zBrLi^`j>vR2V1KDXZkNQzE^uX-lP4%&z<^zR#1lq)?GuhrDP4yY|$ja`QIGjs{<$g z^%1@r-eu2~Sz3m@g34w|soI2;qw5vaYD+x*TUJoRgIiWu@(DRoC~`#Y8$cydb2Vu( zrR*d+h!rz+!Bei_Ex>;RcYyL#+-HD$d8X~;c``PJY~HliPd#R80N+moW&<|@{Q!w~ zEgs15aEtJ+Z0tBasKzX1EDTr-WIwt5j4u4AMUU_DcxUl zTOu^4r;yp#`+4jzlPcUn_iJ-UaJwqUCsGcJJAToj>s39H?!YF=JkWPK=o2HP$I5IZ z3atM+9$BgayOXU6;qag|cP!nI?_`b*2Xw1+_F~BJtKr@s1G|7LfQLa;pes2l;#AgN zPUrhv;5y*@KrtY3OyX-E$}o}e5Wl=!k1WXNc_6s8$B5+udViTbmsJ9hB1(~Ir1tab zFJ#9WJB<2OT_?=2;%P<1i*RHjZH*M(F~Yx9RY-bPy?Tj!PY>*k^Bj|C>}%oMw`|S9 zm}u!LeOO+3Dtx|7J_}2LS?vwbE8VCZ)5Xfz7u`WboMS0M`uh>-d$U3x>aA1n=x{_A z4J~$tJy1b|9#pkk1}Sx_Z1D&VxozM+22sXSeRy91?=%1p0o#C`fOCG>>orre2p0s1 zX3J^ElkV@dNeYu;GBv(Ib_a3|6bm(GYj$_l9z8s;>Np5~#~*emf;ZqWrDX#Bp#+w0SS8?A`@|^)2?`=P8WDK&SWxx?Z$guI zfg~`I_ff!d;Gob--%yq7xTV3qo;f|EK(9nLy*`f~K1S1P|1*kSn{hhP zYb*51Mw1f1ujwTU#m#%u^y0&dnGg5M_1xQ{366mbstXjC3~z#FPZjE`295!0f$M?UKoQ{Th3?lY`}7NIAA6oUA0}Vj zlt6?2cx#!qh_mi1VP()f!sw(CPG`TuNVN^s7g#4tscaj(@HtDR-_AR?SKaAo)X(E( z^_$C-S}#4Zgh@B-Ky8f*qXr~pN~d3Ig~>GV)m8%^K?DCdP;(anB9n$0gY>IRh(#t{ zV&tX3TY1%%!-rP0uWS}Crj;fwHukH>OIcCk>?{?Sjj9u7Fi9CqZj+{;Sum7ltmH$- zWhSS%P)k@kk~T9^_Z3MGUfFyqWD)q~v+Pp>-T)>8-vDBOd_(n8Ki#&aHBXxz`sX5! zR_Ew0HvPU}Zqs{_>Mtx&6W*wlM^_D%#_fAvF>5QSOz0ghO#0b%?3*wm?43|*94%`B zjn<_Y`m#7Fn7Uw28nf;ykxx5`y%E?9Yy(7(gqZTf@{<3Yw1CJXtXCAd`nOZy=++z> zaVA2G^aLu7UPTOsHgyrlgN$^FWKE|MeP@;RcpayD7-mlJ0T zYEF)xGdR6eOjlKo%O%=jw;@I-MPs(}MH0JE`Q`*_)&2+}5tku^UJJyfG1gc3IdJLb z&>C-e_=FU0qg(VpjI<_bNZ+PWQ9su`J#sh{o*dY?J%0VpX!}`J zC(#VQ|HKQb89s#5w9ngjOH!P8nQwctmwx!=M3-xTYjvrWfbo~|#BDdrlm{ooHA{;B zkQBX`mug8MCPY82>smEzg}$1DlZJH z)~8uCYsm>OJ3oBE`NkSqn7%wbJaYJY;|9GLZ5UVUhwF^XA~(9j#>HwXvRQksU@cp% zSzl+I$Jdp{1Z@Wv8GpHPhW>J`F_JGUj1xA|9zCdq%+ zA~Y4Q*8}~G@AsO!Dm2@v{q0(+#BVqfZ7-;*lsXB&sOsc0ocbZtOV4@QxVC;sy-z(| zk$$R7Kg~`0>W7q0KWCRQRVVKhS32QU57Yw%saffr651N8^ctI3zgXIA4mc0JEH)tQ zhYo4QmcYrEsH;yY(-A2bDfR=719AaJag;tP(vfkrkFw=kUFRP2z2aBRvx`3n{dLXJ zW>fJN&!*6}l}FW=ry_4PMm~!exidmdRR=@c!q^;5t{Xg!JCQymegP+;o(+4cu}eX$ zkM)wtk-Q`y#%N}r3c0PAUO!ONS9&oTxe^@%*UC-TheSH&vYu8K`>oy%IjgEVwH0 z=rLEtjy4BGH|21~aKRLFcdQ`vvhg>4wj;Q3{hS)#m_8P$)HxPXGV=_!3J&I|#G~p4 z!?r{nJ}^{-BCOy)Gc<&C@@F#p+SH@A;b;PWDHdSb!)rS8b~R`a9!A(6K|jc?}k z*-`%*PGd5!&klH~uD>~QYUJsN`D{$-tei&cn;i2cOEZ{ys?Vz@&p>0+8`-h1?l|Zd zd3s-Lbp5MR%WtWqcIynKo~d6+0n!(NcIa@R_DK{ejw_dnR-=PLxuRK~C%wwuzQA>W z3#!>8{jR#`|1bNAdZA<;%;Z;Xs1PPMzh-_`{J9Ji%)dte-d_A_=x=NK*Dp>*-foQ? z*<*O3@8^V`4WDFA3VjwXGU?>&Z*tcUy()IRc^sxsvE$6~(ARuEHa_&M+U1mephb`T zJOq8}i}|_iuZo|?;{0F4&&O+aUgZA2kDvR$j@=<}F0d2$|M?kyZcp>`Q|%r2xum|* z{bl)Cj_bAipU}ry_M6ScTOM?WgVBBMnQ8cV;pqBlZjt6Fdi|aAG)aH`V6HqYWZW6u z%n=xv9mFXQf(qhFYl`21vuuFK8PtUMS(6U_?nbTp<3mKdd~>;n8Yq40qlmM z;%4asEJI1Plp~7(&6SF3i{}eSM>}MCdxfT=OvLJPJ5w@K2ma;?3LLiJ z&>PGv@%#kvA|T(&f$sxrKuzEr3*>nma3OFxV1F0a))=Wuue#78SD6B~o?LZ`jA<@> zQ)FVi3`fu2s-42kTv_Cs(0)U&38^Y&qc3}Gnj20a)JWiKz(fE~B@(`%FH;A3^|1el z9USocpe%mZH_kIi5r$P8yRvMWlfnA_oa}J2D1GQeHscS|jNkUQ-bh5vDU0SHM2|Xb zZSYt2&ofk;QS%I9pO9_qtaD~Opm#0x5ssETWmkjFPjj@YX_>IiY@{JAUD@KTY?SS! zwJEet`evD~G#vRlKOQCRufwX>2RX@Uwt4h9j@Hq62aL3iV@$QtCd(34T8A`4F6BKTL=a>O*eY?8%+ctEv6zN2a=&gERmr((zIQzd=|*7LCCe0V z_4&FfScb@Fz$)K2n~V7CG;f*>c2#B^;Nr#3O{Y7OG|NCT();yQ)nV;J|&`>nq&#Nc{R+ z3+yvJPW(qy95cx9 zGfQOR=Ly7r($UYm`hj#9)zSPOHcca4b-f_`Esbz_Cxq=oQ@TPpP;&tpTg><@NVLr7 zU8A=C8$3$G*7MjlcI)Sex2%$=y4K!|FD?;pN9mPFkY1%XrC}t9yyYud$=1cht-`M& z4K9&0lKk&b_rO@79ryt5eiV3wXIUf7{8$#X*V&2p0N*zPF98RD9{}G3wgXx5I;^wX zJd?#Qff|{U)irfOWYUd>GTf&a!E&&cLm7UYLAs_<%b8VobDSsKbwktQjcL6rLX&+rJc^PKro-wZ{Hn zSxAF*YDhh3S&y>RmuCLJy7g9z4IWS}_CWG0wb<;PYLH;eUJ=aSq*u~}7-lzG)Tv=s z107118QHH|HMiHe^2r!Dq8ZlR_>w{>H>GxZGZWxqqtR3De5*|)cbK%0)|Wx ztL;A7RnSw(yV$`W&Oh*cK+v?NVV|n2@HC4zKZ3=`3}GM>g+zkENOf`wDO$qfM3pyMTM~TL!$-qGYs~ z8}sXIE4_*DuK^zcqeZ%wwuB)2gq_|3JyTw)Z;@m7cKKUWQ1gSwp11i(W__t0B^BWUPi&;fr+p+Ab#3 z{^X_%-zwC?CHiw015#NgwT4o*EXWc7HVzH%g5PC86;K1*0ek~+?$OCqhX_WG@yI>8`EnVnMp#Lxpr}C!~AsLF7y!3s>o_TITX@O%aP3b++(U z2(Di${xXuXm3W0?VEskn?-brxP8ZCpShO%9T`!`5%^h2z@{Pq&8`fV%?2(ur?QgKzM-6f|s!wVM%iF43`L*)UqkTJ0_%vNFO$gEO#N^{? zWd8Y@ z?CX#zxA6T3z;A)AK$yzB4)LcArK}-|q4a(juzN%4EPee;j_>L|a5SmFx^b|qu-%29 zsAe?*=gZ52K+UJZM4}UgZ`Ev8Za06%bmdANSS=gN;2zoX*lG0C#n{f43|1T^2X-sd zNNZ49b*&)Wpb=it3E`gPK$sZ-rNHe1p_Z8-r8SoImC~j=VYgn!s?mN`-PlXP!OQ4LXH%SRL=n_1HqY@CkOz*-bM|_sbQFtkNHX!)1E4T&s`@j=C_tfs9eE%WvJ760yimX@SP6vJt=yun&?R0O#4gpji1hjw7 zJpqu)-k?>;xZ#yR&F3t;O2@=@fb_5{NAKlhy6hYJ z3j2{ToW6=2G)lUr`l#7qjnFqcBlH4E2ts8Vp;K`>A|%Rl_Xyn~2py#n30XM2#cOvs zyp0uvO_WwKlWxV(`B;hH+Gow5+5Q`-4e*wHn3G^P<=81Uq*K%bYE9@5lSe5+-=0a6 z8c5++D_7M^Ok%-mVhCa)Z*D)CfsDz;8~f3Ii>81XsfTP znJKx;pb~~~Y{X_6_BBcJ*UbJs%@GuV^)h6OZen1g127_z?QGFa-sF1epU8UNqWKFG z6I7#77SZ?d9f}mF)88Crz8nAUnd?U_89IvLA;!|8Xi8mvPuFD)jw3lSeCs~BSi9QcP^aW$}kraq$-g1b=d4w26OC z^-Z0^daA$CDV#U?vJO5o>r)zy@N8ZFM|hp<&3 z&o_aCKo0NnZ5{3(aZNzs(81o>iMKPX;P5hWGkE`x?49*`Lx=UX32J=}Q>e7;w9aj_ zI+Z7|+*NW@8%H-VDi+or>2k~Z$%`rHii4O(-_8Ed=w{12TB=dcK4Kt!tK*CAjJg|9 zr+c(>?aXyU*l1;bsm^>Bj*?(%^t>Q3*)bYcOl3`cj_P1L9o^ENZ9Sc1ZQakZo>nM^ zC)k~B+I|(f$a2X2SWXCCv_*CQC>GU4$zJgaBxQJrF5YIv{j%>ySyEd=whmU+1XX6= zBUm#@5AikK^u)zUiv6YC5!7j0tus+(K-#)mqdG>GSH2dXCWXonSS>#kIBc!GUu0{o za?4m-J95+Z*4+`t)E9F`EhFru$aVIXHLO>4cIS;!XU^h{$S&S+UiBU(t7eyOI8nSh ztZ;}qHuTg}CzdgGI*4Gds6N1%wwUQBK5$T3t7UOHk0c{p#FK&J>76{if%x~3M46Dv z+?lMBUso2-@^n#Jtu^1{JnJ`)x0WhsFmYML;EeOQe_L&STuwF@18r^Zoh(uTP%7hI zzFG>#N#rIW22u!_9{pUp4YexRS@Rq6c1GdGw(EL=N+W$yx045P(wM0Qm7et1K+Tyt z=j2gjF9y;>G6vFuNSM!R%elP#h&3{>QkK!(NRXS~${<%zwLuW`yOs3#S<&QY}W(s!y_KLUaYLmrdWo9+`o)o)w)S{_vk-5Y?~YkMc00D}Q@dG_XFmV{$6b zp3Sep^otF!C6MCPveB0PU$+gj9b>Iw zQoAzNf)5zrUSK!yj=jxUb`HueZ-ofd29jsDZv;n0P7m$0=ufZ2D#?$?VD~dSyH(d3 zoIfwI{|yUgm100z<-;n)_=6VS!k5Z^TjOglNy3@wu_|*jchZ#S5#xaluK2CN?=0N? zxE}#ic}}wogm>C=OLz(E+!k){yK-&{&#oUC_cJtL+z;h?SaJUJuNfJHiFYqcK;Gk3 za;OF;TR`@>PSMqhvzruk<#n~<`~#{vJwsu2F+c3+*J;IhvIFS?JtMJ4Bm6`sgnO3g z=@sYjrRqQ^OL$%_f~NC~gsew9Ygs}wBv>lmju{DwsbrjG<1IS6ZQ-pJI5__uPaeAU&`s1ItSU+jc* zPaG4Ts^w8-i|jnGxMi`_e`jvFS-c%G!QvLRgQWwvq%FRMRV;h&`*YpFM&L!@J3s|c z4YFOyYMJa6`|c@xzZke4r~}Rh`U2koG(QPL=-(IFcfSu2nLR2%cqsdBT|F|nq0GEl z<=td$x_abQRsNBp^<(%gcOEp1^(i4-h$F+}@sLes(LXetv*^{soC`tu9TtL`!$Xto zIIvePXkk5BX=9;n>3~)jaf-bQVj$?LftnKN8wI;r8oM$a$v~TK^Q2lSbbPp%J9sq^ z0ph?9f&T!U^W0*?-HQYsRsI=?oOx2+X8JFC{U~dHC$@m*2O0V*i(AK5hxvP~0x;4X zh$Se@yScY+aX7NIOST#6eOwt^=GeWd|Uf;xy6&TGRIn-3}PL} zFpO3i!}O+XEztJ`U>oo(a2kGtftvvF@5vtgU#It5FI)8fT-G%ez03M4dXK>QQuKbL z1HJ#Dcu>=u@(&l9L(h3q7gN}+fwlPNAO_=y_AFg;OylC=O?nLHyo7^jcV-O`^g4bc{k8V}@UgR7mh$cpVa{<^daz|(R%wf$l@w9nBY15Sa3ar- z;l2pG1IV`y{kMe=qfR*yQnbAe!o;z)EB8fO>IVqt2bh)W zzdO^WF+?A4O}Obb2X)1r;KQ(;|vw_rZ0_9ip5?lxRB_KvoxCTuTFea#J0yRjO5SY@l5b-^b!5CmXB?<~f~2Kvfw)M?`l)`_x@)98 zhgN&TGj%0S32f{YZ7niF_0v7VQq-$2u(40{a8Y<9&qt|gela;JsGntROzuN1kK6^a zn|&eZ!}Z}{p!26Dbzxqk#0J7jR}ttt_%B^zHjBO2 z5cnwApH*bwYM?dX4vxj|Zk~?-7xP}iyQ??z0=<<@x^=69&)wTCH!NiCSe31leni)p z?Td7aTO#{FE978<{CXEdd))PHd40L9v~aGKuq_I(~J z^*6ooS#GgXR}a5jdsxiWtADM{%ylMKszq6;`eX4~Gj{6Wt9Oxo@`ZVcCqgnWD;Di$ zDoL3>0*(MVWJqONKYJQPnKD~1T{wC{Gp#Gh17x<&GykvRO}kp7iJU;qK2n_#sQIOG zYQ;p6tM_E9#3wukHoBv&mxnKmwqDONn)>EpC0{D2nk&qkp zbb#rRl536g(y!x5(HNr*M0Is` zwYk^xoN6R`lX=x#=>Z-dsCt0Aaq4^351u~loSnwEu$Ax6)6>S+v4hX!smZt~{dG?A zC!B~Bm^Pj7=V9Q}i>D@Ie6mirU%eN3h@9AW&L%*?L@%{Mww*P*Qc{26CCj}z+Nov*07 z9!J^^Q(B(nM$yZ=0YtY7-Y<(VF*-!27nZvDN?Eki~ z8kfeZ%fXg4(D*-KPbXW9l|C<+c1^+9cAJ9Apsuh$Df144I@zRTo5}r~4eA;uP*(!y zTQFm=J9rrI^FG4*_EX;91)k?!z_dV~zXSXncm%M&i<{=RZ2JMV{3s{3!RS5OvkAEd zQf@J{n#PgT`i{=zfciOZG@6QSdTvS0t-yFin(>}F+PT6zFA?Z+g?CQ!+@zqNogmwthO(H@DjL^e7o{5z;-#7Yc69@WQ}LB5x~H0UL@qgoNZ0+q_Azy_LNw(X>+zK zAxKA_r=zmlfEtyPjq+?3mW{0BOw}{9@w=(G^hB`uv4SmAVOf4z%L_`Y~hH`v&I*T zHykF@GomWNG78oBvaRn%}={+F_6>j$B=WI~Cw8tU|BtD$yj(Kbe9&^0Ia zvtwqPv_0ElX(o%dSte~x{b*76y81lJoGp``(gH2U|H&o`(Squ$#WGC}I>(@Gd6H{APDnRe6q*yP1}axgX6DSa?lm_XE7@!*a%ALig_R2@8>^mMfdt zn58Y+o+bMZwWM@jt74yO%%V@8g~_EFld?{j^hBSuNn0g(w!DXcuw+A!chxP})AE*Z zc!wZaeS!G10x8zA>2ATXdE<{=`P-W}(k5+k$d4*Q zh>4C`I?1kto{HXqHKeelrEIr`ceZIeNI5brp$q+$ZQ7J(E@m5|dVFbhk!qeyfd>CuT$Gd}%## zAn_^zD^9oeCr-SlI`WP4d?8@t{Y5ry)=^f>lI3%KWdJiS##}P^Qr2v1+?caHtDClb zl|yOON+u`5cWB*CedX^@ShZ@|v+Wj-T=A84awr^tqFZ==gMg!A< z3xUglae#BZGP^=@z1j53vS-uEGV8u@y;hbLjRt60-27*R&84UxnS%<-U~!QQn@?8c zdI;ysi-JH+uCx##Mxf>$9##D;Om_|Fa|??eZql8C> zFA{%SwHFy~8H+7Q$gR`}1nvaQzGv9VSgkdF{`*N^ILhhsxW(LJ?IvsVs=Rj=;;5~D zFCiOAQ#1JQZT3 z)D%)ig>_~Fu4=L;;;*IhF+v4|9+W5`q`oz@`PV19gFAqI!0o_N;Cm-2*_6%J4m-C> zzF!Z-fO~<040?Y&k10C9vb9-D*_HI{4#=DFw0~=?! zyEAu_6(-ExN_Cj7?cJ;}g@KKwOmu&t!5b9J+y|PmcZ-y`jNzQ2Sbx{Dr?bu7-hnH- zH+TCN$A5p)EN6}X&VrMrrOhZ-Ep0T;SCJEkgp+7(hr(->jF{(?5%ZMp)U&}`=doWP z{xc;YY=bvF{(IDcwccM=qcOg+6UIHt2HWCIjvP?eCMg^(E7s0ChGZ~HC8T!|TH4(b z@pg>;6bS+~H&fKJOzj%w z4!#e#PjLtTgu4#-4bQZrZrh;2_w~Siz~ew6d4B`91o#1<+hEr=Z*6?bKf>8EuvOK1TWmv7Lv+J2on=f;?z5b{uT;!1c=Xf+v`bI0B+SwyYl)>9!8BP3>KN(FN5aq3d!P_{Myp?pBa+6()lQSvXMsJ&#jlT#&rH$V9 zN}3O)jozM-3^989aoXrjOc2EA&2$>Q4ape2-OqP;tf1u@nqS&ND^T-e{5zLAjoZ&3 z$&k{rdXv*mr9Ri|`mDxrq^GRjy64!1&h)a)-Wqj!cjJ5&{>UyaOBp#D6vZzrwv0P&jn3dvoIL3@bQ13uN%_-tMi#c}AVrBRbo=$y~0OyJe=d zoMWRMzqNWrZSeM8q^)pu;n_-VZaa&{mmb}U!P~FcqSCd&+Z~QCx+}`qV`Y!GGacG& zJ9pg%8m-*Rb?&7&j@-LBFJ?ia*T+(Z%)ZC3V(~W7>TEmDO8)LQnle3@ys1kC_1?Mw zP01S9bz|~2td~&E!cv-pZ3}Z!I;!fghw`fTcxoy-Ox{EjAA?H0*f_0&#hd7&3^zUL z%SHd^25-8~I@9I9er<6KN(k4EUXE0kaYsbe*`42#I&+q8M0V+hr%Pwm?7!FI?SO;G zS}luT1A>{cqIfc@Jfo8*qss5o31mWcYw;$l1pfw$w~^9SIV|2%(gk(bP)0mt5uJvD z$=eNtm1eq4H(He;rVg=F5vq@U@34r?`53~Un zkoM1jQ+Pfd_zb*P^L`Pq7@+^|(dI3mFsA}zfX&4J9xwqQUZ*~s0;Fx;vevIM=ezX0 z-ub|T7JF-hw>KaPis^+VO47+7OC2~lIVqu#?~Zl6VOrYR25+;v?QF{IER;FJN)f0v zq>sg07)N&m_Q z2%(0M5<+2|Z1MOfs;;~B-7b$<%^^iqd0nnZ%Qa?MtIzZ>osM1YydpjK7f!LM&fwXm zF@C5M#v6LTI8c*bk;dX}VMcT=;}J2|aWz`jtC5^vG$SD~;k@*%rrlY*U3U%~3j6^0 z28hqY9SR)9Gwrckd$(SEKMoiN%mR)OX9qBfXNi~ob+Z=zFYjM?<$ed<1MBShtA{2k zZuuV0m*2OG|p5s2&fw^VzwqIkttrONgaZJYIO?D<& z9pt55bIVO#bBo-1N;jLeccCkbH#2qT1b6Uvz*9gKFdg_0(CtcAi|`hkw{d)*1zZ8# z42%LkC*C4l%~RdmygB!`z{6aRA{!v}{ibq0VwU}zC|sh{yug}B{e{Z@&Dx~(yPv7X zlWhQZu9C@xIN1hpe{xK$|Czg918afXfFA+Z0nYhvv487L^gk*8jC9UCIjP(6{K>5SnA-l$rmx<4>D(DH z?_LZ4i~-!XQq=1~6Mps|kD@kSsg4&3iQ}tNet4fbI z7$R8KX?S;G0GF+Um!xN3@3}`KY};AcI;M5W0f~JX3pnnQrFic_^j25?IOx5x2Lre>|EC6UYMMRUG%>p= zU;t+|g*>ZhcFoABpa%;$J@}NGOMr7t%_5BVzHJsh`WD^k}rYvva~@L+l@s25jVaAhoLgAI-`5QbhF&> zKh*9GAA3Q|H+jztn5BWG4O$_!N+DHjS0&*5~b8 z7%?Q3VeeERyYo+9qyDer%I38VfhA4w~l__Sg!;vD5rbxZRW0E7~B`>gX zn%iLxH&8r>i)UwRxESTMRHy74SuJb0#d3z{CFF7vFb0?b{2T4zdQs>B;2`F3b7h02 z*u(YXk&VTl|0vVOF^H2Hcj*@zrmJpi8IBmloq%_ishjlU+NdgH5ch-bE!?JeG>8*D zv-{vWW&Xvo%C?~!C#>`p4B~Pnyf%otLfRCbelP}BC#=D8lKdGHUxwg-#2J<6)BEA%$1FFjer-ED>FXc1R~zikm` zrbfX^!=^Hh2W|%X@IDRrHP8NO?%*}R1-yTeO`IO@joFUyS|n|5DXkKFINJInA=SKt z^-J96yk;B3HD?>d?XCZ5c!sd{kFUh((I9U1WYSDNl%1+&5ND;DWe_K)K_z$3OZ4zQQ=uwu+M_ zvJ)dWdBVo=68mUf!0wIWME`Nx!)5mX&V`MSzOUMd(;#m1Ow|KCjFUEblM7|FLEIH- zgSg7{*SX0brw!t!qz&RqlI!Y43hTYh+_ESJah3%Bc2>5^A}*n_y>lN<2a7l}H382v zfsw#`U>U&prdyl1pYr|Z62>`+BHV_D_}S~|cK?Y8QTB0}`(%e=9(SD3dg%DcZbOcd zwXEa*-qpRbnfVy8kISaEQ<<;1(@AY*AlG<-rZ$eWrA?w?qJwyo8*BqP`pNI}^+&)x zz|R57p50({xzaXr4*R(7kva4|jZ9|)xu-iC$T|0ahc9>7$7QGP+$;QFR_e0*MH|TN zpQZKZFEEh%RYwE4Q#ugTnadcv4EneY+d}Sl(Cl`yy9rnW$n(#DC?Iu?Jn@>_nhyKc za>JO*b<5Ff56eRJ>XBTSelnYU8!-{sZXC-Fk><6BQ+zQ7Ol-#u_nMf(!7_+1HuG5N z)iws!-$&4i5lKmjt2(zb{BNG<^5Jz1V>6$*v+1+E5$AGwsy|XUpl-5z16qcQ5HRKH zQFaJFcW`o9r-bDiPYE6&_~e|rdF~A!D?FEMpKXUfikn7tct7C@O~6jEJ$3VP)cqCN zcTGz%Hr&W)&ru-myML@4BG|_cY+NC|{np~=>+{`p!O}U#A*Kq7#x$BQYhpzX7l!>c z+rz#RZd8Atu%+xSP=u&{BYyjhc*G?9`!N)Z_@8d12%?#o1<@lZWAK);(`UJ_+UicF zw&c0DOmn+h@`+HpclB}6BW;28KjGyO&ndg>E z34%dm*cbY1p!OPq)R8Lb)$XlZ;x=;G^yqS36&uijoXm}!fSgR7 zuxC@A>?Q#kzH<39>jaB=sRluV5bQ|h7!A2a&)hj?d(&sW3Z+VGq6o+4M&Ifc&wrXT zVIZ~lPB{~E_q)TlWSi?s`~9lv%Ut%qDSabYo_PF-#X;5TN` zIrzNEGh%~{55WfH3PU@Mh*Y0dV;W!SHS!mk{kea8saQYDeloKcY&#;fDLk7I(txYX znuXGuuL8&6X058*^3f^Keex7tsj`cT(ToubP1ClA68w*JC z#xEUtEBUkHNp~>KJ^K6u>^~tHtu)%2G8D(m8sV**EZb;&Tip!{V8qGZoeRYoyAOVh zO`a9=X?ZLBA^o{r{N*d3H-A~f#b5{DjTgIEvnsX$l3|E1xx^rNo}m#50m7T zFG!rKa`sWmfi$$~YuoSPOEou2>pg>TzD+sJ@#N!GeJ(ra`kyy#!sXR@6K=jG$Gb0b z`0{FBvI3$4nGMtxubxh-uW`(N7*ID>V0q4zM?kZm%NOS7(o? z|4hV?`6_fTTKl#{>$`)_le7Z2@03Jpe!@QoX-q&Mtyp{b&*UDc-H0EF8pV*XAh2=f z`L){vHA(S2>oEtgpu}X5Q#1a8MGry%)r%+Ho?|d%B$OWnJReT#ML-8Ey zB;TA7REfm`ihCgwg$$ob-~uT@A1OiP=JRvIr-Mkod44cCt{%FeNE|1L4b{H+$>Vvj zav3ENM@YoL#`))~0RB59(^z1BMfto`{x4xzl^frzvgJtG@||VV{6GlJ?-u{KE&kc5 z`npd1Gm`L% z)j$t7U%cY^zPSHZ(mnOi9(t;g@d@X}%Wy6n;V+-hQ=#mXFQ30?UPWR&GBCQi5H+eM zf=&cha{hizSe~KhvhrtHGb^u1RbYG}_5jBV-h@yiFLD?yG1xhmqxvGhY&sgtg*bUc z_H$!-*@*Ex(J_W|Vm=Y5z1@p@Vhd+>+!hxxyS)@oXQXD|vrqYva3+!xV zlchD6rN0Xwfx@zjKy-cv(Ll{_g*IRzIcy>psWCdO=0J*@*Yt_DPOe@PZN2!Gn}|F? zf@u`#9ZH!#93(hE*y5e@=T)S5CUVT9Xh={&zd-74bfydkRSwWm&5Q_Dqzn$KDB@*d zu8ZoIqGpJfPqM*fS5laAa<-@*sF6{#O@gQ7*~Sk~|FRX?We*4OEu%o=wu-LeN}fid zBh4jc#PS#KSQeH#ou5uUEZZj~c-~e5t9(W-Dz8Y$D7!o%eyZxjClG9;SyATM#8))2 zv59L`2)VaFGshbeBD6J7lh1^h&VBH3XB$H@#2hJRl~M+ z)6g&vatG;n2avhqRO-PsZ@x68d}X>)o+_W9Ug$j82N>FfK-re6Yz}NBVx{n=SDl4E zq-u~%x;|8?27&kE=pGCO=|{ZW3&;>Qy{;rN!YBN2+tZr7bu$h_we~oub10!-(~`FqbdB ze#AN+7nx6tkZlw2mkc@33*t2+#Ihg8PgP7XYevXisc_iVa9=39WbI~2NlfHL$oZGu zB@J?m+m)z1B(;S~6CMyVa-@6>-~^gAm&{hbQGPhrt1{8#PoMlYtn%Rek6 zIkox!K>a-S&o8Q<=_*85^&{oZsvk(wkv`lHt}c9|K{4EndB%VTFCG_hw=u^xoZ8Kt1_l36HkYjEsUyw3h zPn=LB^B1#7k`zhcTAmmkl&pT;xB&d}mb;h4435qVMBhEgL&YMS7(R%hlO5hgvOA~~ z(%+LfR;8D(NPIEKmaN{xxqycZ4+&>dU64-JtCKYaVODdXL&?M|13AG!&F^@wNX(SV z7A@_s2-TJ!;RhiViJ{T-WBDkY5U8Eb7syw2ROrwuHZ%zONzd}26vig($C|LeD`x(>N6JI;V+^5gH))U#u}Ad0p*CUh6NWmn9iaz2~F&n zkgCAT9m$-nlSvM&Sdigbi=wIqPNEcww8mAMtl=dUi9@os~nSR zM$3Vaa*uPS(kilRj9Xv^Sqb*5Nc=)4Xl!9ZFT1&<#z|eK!XtbMv~yZ>Gpm2zeN`vm z*V{i!)J1oJxiHk`~{N6x=(Ty$9U1Rgp*z6``OhLZrh7njN3)hrq8?D`v zED!4@v|kYgu>w&<%3RwbVvL~e5>$zli>Xt-_~I)ZEJVt}2~}Ss=nWFoVjpu$Q^H%G z_~#(JkXtHskrgU+Q6n>Eo)u6*nBgAz1vOfKV_`fB;yMgZk>wy}e8VCd50?e}8 z_Q%R@-;bNXP2e8DJ%D=<7p3U7PjElMZN+WHZNqJgdqwScc@BD7ZAzr1z&nB0frFCv zRNs=N+nXDtw9aQ;a?1xCv#0?n?6C3h8Ex_Ek~WL}BQo^w_xZ;^ZzJFGtH>pF=vAof z;*qrM`Z%oXqgd+WqHn1BkiZSgc&-B;1~{;E_^!I?o;f5uS19+WBU!=A`ktwy4`dgM zqOl`ngCiW+Q#z}zK9G$qgbv&)XCygdkhT|O{6IcX2#f$u1;zr?0q9%^ojLCHwgOzn zwYTNtGIqEvh%4XyxZG=T8>;8+jG%Ax;(D{|Mbqap(pv`H2&|X1?RuH!q4bV=Q16u1 zQ3sTbFxoGx-bAm9wz>ngvOy;`C`cn)?!NC^2&6=c-WMqoo^Y?cGJ@)NE$)da0ydo{ zUcvjq{Kxv;$bZv5pQq`*6+9)*R?^Anoj8UjHKs9nLu!zpWbb=|4mt6}aF^@81O0ir z8yTIrY#4t(E8_2M1Zyfc!I$KuG225;#;GO!*yPw33+(at@6URuD6UZp> zC|D*LA9;*k^AZn=kVSTE^1F}*3+OsTAS^Ohv)6>#sELxGD|r$p^m43pJ6jL#Z3HPq zS#PeWO6}yqFLzbR#qJD=ydXbE-b+SEzv+%m^&4mr#@UPL3!5d(r;?1vI7tFMq9b{R zP4!1t`(5DycG^CbHj&M#42LgS4088=0wRz-+>hk?M<=%O$^uH_WvHVhd>%P26H2EB z?c2|>C#YP^8~c{Kq9@^%4>_+|JAU@X3_@p2U}CYKr>TC%(RKanOOL6W=3XM5!iH0i zf;!tqqVUzqo|pyYTa_!P5v2wdkpiVXI{KuXES_Twh(7r(9&&H+LA@5)VIHr25mVJ= z4GfLTmlZrm(;HN%BI)Ttro`hCVEm8eKRmGB&3vqn`B?9%MRo4UlBs`E??#% zdgAkwmGVG=efmrC{CMq^5N(-kD?srYR6zRUe=J_{xcqmMs(dQfNuY0&YGoxu$Vtmj zEl*U^m-A8?9$ji~8($FaA1MhL-nyYol7rDl%ln|rwL@dHK@_4eLrhP&K>H z;x1B-tZvJzJf@N9O*Gjtjmurq?=F)YmpH4nJT+*fBEo&5{D#j;e3uv`a-S&cM!#jP z9%%jy6s}A%=agd2Kw(CmNyr%mqI z>^6NLteJmCyzq?J!cWYKw%Ec}bKxhSZgR&K`;9eCpLu6SKRb7oXZg7on-_RP7x;`> z(a(xj9`|Q3jF?aFPR3{Dcn|F!cIk$)_TI)wFc>y8IV?VNp9+xveD{XUL?A?-gsAkI zv)jzY{-j6T1wQif;|Y-tt{xem$6zl+Qfh8=Iq_z2^D8*c=~Zr#PZ| zf8s)Ed@WG3mQ2vU%u9E9NMMdPMgnuZp*cR|vU| zFnWKT)UHm~EDg5Ln4$yB2u5z2;-Vk9%-gPfqBk;Vxmt!5EBvXKl~-y-rp>9bvEq7j zkTjRLm-VR}bDIiSye&R!z=3)38To9Yo6M{O9XMhs)lXVUC|Am~${W4bm#>G+nOG_*-nTZ{<*$h#49_yLEVb-{+0K(dPWn;x<0q z@ONC}CiAt>9tk!mD_AbUlJAE07?lKCIUxFNAN+$KA(QV*yp!yB{nR%V{sY4IPsp7K z=APQU1P$jeNW8{trFlV+rI;zf==hY;YfNK{T#Ot$R$)0MXa=L7rD6-)!ujU<2B|Z% zx}nU*_iR&pttcD5uywfciAehM0HM5I!}vjgQeLuh~Alr0*-?7IR^n z`Sh4n2LbbmIg50kV_H;av%H8*mey{s&fWFq^yDFP_9y0rhrMQ>Vw%T?vDvLn?cO=j z_H)-DW|oNEYCpu3Inx`O=`${mrixY<>jv=r?j!;uUOgU(6I*;>_@#AaF`zwQjHl(9 zvkwgGn>-^v*Oon2*!X(Io(QR-?E#`O$*2Qgzzsd}IMZj|?2WE&b;WM-lB;>MFLskp zpN}b+R)0wQ{V;a3H#XB3n(o;TV~`|Z1WRC`lobzfHVeYQEf6_urLtWRv#fHskt zt)_9%vnxKwEna7~Q9ow?+U@b1+_6c<(V=67*|~Xmc3VibZKIdf-{8X{(|KGFKu@ik zKtJhiDi$%d)MT()6Dy~^mFu1`Ychp-pUb1VYf>GV6N%-3`Xau1%>v zFSIo_Ef_v!xp$eX$m)w1r3Q^g&d3+Pk)K+{^@)yIF|@}a(K)_UY*K8EHnt5%r1|-6F&L_zzqwm3ySD$yjs8?)MJ8Fs$5XvWrE}56ar+ zY^H{SQhxSvy%JwBqUW9Km~aAs?Z%oHMRr{DzQ=Lkg?`$v&7ZS;b+_@!fLq(L+)5p;MU>qMnm@+mXS zfm*f3Z?suLPM+enzj2qJ$@pT~>rB$yTk+gR%l3 z=UAJkiEzotn^Fn+lG!RVuX5kWaxX0EruEZSnR$FkRG{DDzd_Ot9b`kqM0s)gUQ3_IO}1huJ~=T92T3FAD>nbo8ynIA(U^-`;W=2 zI~$Nb4+eg`Y3A@eLN2>uAvd+^SYF&9u(#zSKo)dmeU2)0K*s~D0>l#+2i z<{b?m1-MV1tR#wfH~W(g`x5d*OP%3$O6Mib(SE8z)M%M|(o98#MbR}u=&R1`6@_7A zu*l{5v+LlwuC?b1=0=IxtdvR5w4kEAHF9Dsb$m3CO7&}FC~r=a#RhL^>ncxdjUOc= zHQN{Nw>Bw-j{d{PuFFS6M3~Q+tGwY;qc;_#jFXnT25NMbUp~SLQa@ z)0e6YDI~eTdbN)oKXL-3;w@%zypIdvD$J)tlY^^rLzDAw@R_|sPlwM=e(+$xIKw>n zxNHts`)&&H9{T8pBBm4kY#a--hPCagwQsr(7B|KE7jIh9)as3w`Fsq0xp#+TWs$RZ zMzHCyKVG&?Hc0vdj}E|WX_#y6cp=EvQm?RuF(j2MMUPID{~~5|gNgeY99PO*#5_e_ zshdS+h3IU7nx7KKT;q%1R#3zP_ZLJH1x>AgS4^+vZ^DX0!h#k*mf)`F%nCJDyZ6rj|GS{XsD9AowhHCGRn z#PS!g*wvO;o=)y0(po!}yOK$Nt1q;=^@bO8DrbchbA<=BOo7%h^)l-C*cxAp9GRk8 zn%Nq?g=zV`=q-L1W7Tt+ZmxNS(j^n-Qoksj=Eq!5cPRQnK~uY@>0Q64Di{r=m~mO% z7F^wzs)j$P_V7O_65aYf-KVqVVrr|UUTo1juW0>7YenKj)-zC3g$^&6JJyVj({2~G zMe05w&s4nJ8!K;nTq=gPIe^W3QaOq`(I#JNcAN2XY@$>|e4P+Jv~8t7T9RTGtI3!A zD75XE#^Ft|=}c7l>ZbW(OMRm}qo#4CQ=TvW9pRo>|K!-jST;z)-J{s4RaeRS_fVf| zb+G{|*W%silz~Tgk18*Sua!7Swtv{Yz9>BALi&70uZzr*_q;>L$mYa)msZz9c50?XCoKDPeaw6X+3&-Ip{rSxU^Ww! zFK=Jwlbr#narnBdodJ9)GB5I(EBw*+RQPLL>oFocGCp>d>Hj^O{d}<*{%G~@y)NUZ zWo%($pVaStiBe*xF8sYO*?i^gxsnvZ0%VZsSDI2N*V>!Bk`Wt^(7EUPOXm5ET!mZn zf_Z-ydMEo>542d(oThkV*Z3=Eezx zVqd;Yt8Vu4m5KE?)C*f2S1sqd#M^y|%c(WfdwXn(pSV6E@W~u|d-C25QnqBFDoJvX zB)&YgAn_9&f3fnmD`lbdYvw3(a$&hSxu868lNE>(-g_Af4KQjzX5wX0pfc>0`C8^B z|1Il{BiEvAb+O)98i994#K-el)*GMTwV|B9YTzCqy@uG+dZQ%Hx>P!>wT9JUy-`AS zz20cWKb`=7zzejI_b0#sU_bCWz&h2xVZBjNA|(Yb1!e)40dUg)@_J+At>mKD8&~iM zz3lpMt~YK27wSO*H|*iL6)57xUMK9d-Y6kS%l_WOdZS9y5$=oE8?Cg%WKj*&0PBJ8 z0e1uU1AhXjmw&^0qhw~LcJjXmNC0i(W7o_7WWDj;?=cNRc zWnOu8$?INT**(&XNOjW){RuYkhzw)dM5Jtjv4(nGln^zNS&5Q~56a@;00R3`gUXT1 zsO7V8*h%4ci6KIMY@)0m)*X9~1e|bhgGS>7v)_82D&p6-g$~{@P<2qC7X82*8Ye+k zzQ1Hyf#8)dcugU<%F1O$;!!9bXDW}{z5h>pUjr9amHvMR1{@J(G&C~INztr)x$}PK z<<5YBLV-?#fU5~8gFp!EaL1R{5(Ntx*{t=~y1VYCX`7|H>$YZARw%4e*@k9CYDSye zjyrB)no^PT|33H5@a9YX{=2`=?(etU`8;#p-=6cF=RD^*=iED27~sX$Ba_=mHCQXw z#y>m>707KY8SGt%6K-?J^0H_VS25t@k(GnH3dCK+zhk!aZpEuA{KMx_)jRxK+rWwi zbBRzQ^F9Q|?P;I0=HeXT_AI}iLj1#X5D&lyHXJUm{x@o-=Hrz*xfq|dE7daPDUi4|eV3ne39!04lPEf*N)Gt_^Q0kc$ zhvp4%cpF-g+B1z#mc#X&?(1!YlD5j;o@|LPX zIa58vUtOqR4o(Y;*h2BD55|R2xbIYb@?NxZ1rSkK{lMRtz;W;7v$TLehaYCxj8N!ynV{LOa1Xl2 zKb%2Tfx)p@upZq1RakY~XisE4wW(g-P%mEvO_FEeT1DNUS||gOJLS_7Etgj8)}HVT zmg1bKwyyF+kLpfebK>AM`6_o<$;BLBgr_m(QY-DWehF*{L>3*@*z~;-L=q@4Qao(1 z)<*l5;Z-x_@jiTHGSnRbtHLM8e^p{NZr%LUuP4;_hgTpIQ9MPjy-H<^!^`OD5D^bu z#I5yMlKrR?S4^?pOk$}gy!w#TE!B;2mJZjSA$exL2jOEpPDPRMNg1!$OTv@5MOzCe z^fzJN)mSP*V}P};7O$i<>La3Po^s$u3#QrG-jg_g481zF<7@`WL4kFK!r!DVCfD6 z=9)ErL9y0YeMr9cfygRuj612$A&am2dW>*;%~4@o)SjakSLfdlqLd4fei;s8gx4u+ zM@)+s?eB_q-=9Q>ylOl%jWU=P?@JVY!o=V@Wqj10;}@%YW)fBxQ+vxal%f&_qLhJE zUk`L2#@(aP6dw-e3i7H#KU3|DVX&x@z7<@jq_|-e4~wjGqJJ}5+_UnY+0p)xL&@|a zKt_9_iks(_$3x3cRhkIhwR@b_Z+aj`7+keXHm2SobIU#W)-rwk`T>08)-*dNYQurG zvty3~8n@Iwk6PSM>ui42A`&VnpiE)dPW{z?xqceJGPUm%M-6h<+qwY~}d;p@bKZTTjuh9-F_3_BalnMd#^o;+Fw z3uq`(N*`5o0PaH5EuMqIkofpQQ;hp7$@t>VgC4#X*&XS~$cWF#aAaj<(7hD@`yQ{w zCunASpTo$dA%nG)Fg7D&wgaNWZ@h{dE? zzCkUzYAjf}(Vjy>L_8Pc{)YZ8-gzkAUHAhj^K%(TZ=l;SZ@sew(JJdaN<;yjQr$FSQ6D|tIlo%Ha)Wy z+Sm6gF>_h4NQTxSL7c``oXf(C`acb|JWfGTYhn>KSXfkz7kQxVg98OhnyFP^Q>jrk zq&cWxGY=~t=?D&HK#>n1!3_a_#Sw^7-dR|?&Y2^5WjpF$p(Nf(1E4CNQ{7=*a=R1) zJ_j%G3^B`Uucah3w4+Fl9J0L(xFRIF`ZaX%rO4Ytxprb{DtTl(y#6jn(P=UCGkEy- zM59eo9EbNLe2SDRSs+o-J~7^K@htVkT;KTmWJSH00Jl29DC?=xu#{YoW*1B{8_+lN zUx!#pq!5IFG^r#$iEXKjYG(&Sn^KCp(e+DZYu%mI{I)@$=La!l8cP%o?-EF2bLRM> zJcBn51jhF?*2xp9+vq@SSluntd@WVqOhPJmcy)Soh%c<_n>*d%@P`-H!=X)*QD2ucnzsWzcT^(MxXSYoW+o63&HWX1q1nfF?;GQI@CpvtCa3+t&+*&T6rR=f7 zub+xf*w$~0L(WWnK^*qO>Y%sD@U-HrBeXY)O9x1KgF|W&Q@Ia>BX~2zJ(8FE?}J*i z@!o<@lv#sXJrS?@FJFET$B{2--^4lFud2`atK0qBx3vfH`UWW8WwKT7*l}bC?~oyL zD^`7qjH}#D^K<7y>EM~#$+ZdwTx$NDJ1N{&b6WW8eyhD_&E7c@w<{oh2pv&%4#kOGjSFSS3mKAb*@Fsa!_43StIaP znJ?$h#eFAy$9Edn?)KF`=&#EUL17c>!f}F`YjZb=-;x(%>I(h1ch0p5ANhWdjf1(l zbqCJ8113>F-46%8PfY(9UpNVgJzU($C}OpTZTr>I~T@(cc=G=wEsE&Sp>38ky%~kHQl# zcQhVGAJGL`IVR2NQr~5JzN-FO?wWMzgX)h%1;w35Y6nbDb$^YQl+fu_GL$gh!0B+P zO@#3CJCGEIo~Pf1IOuvb1REmM4&38Wfv;Wf9uG)9lI~UD8XPVPMB}@Z=X+cgKnSJ? zoOEduud{4Ne|MeIPw+f&+QN(1S5`n!9FKQ7&%tJQwl@k(5FDXz6OYhCf@4hgwh8n7 z?$f>$2;1&RME(Iq7SHG>1dijI;QI-wJA)cr={SDjr#8G6Gv$!(zDlh6XEggok%b0KuuC_QvUfB0lqlt-TS_ zrdWcC@5(dnPO3g*4`+QN1v3DHU=EIjkSSLYG0uE zXsLPe!RBFR!_0ZzHfqquIH`>{bhj}<#M+(v8|xD;Q~sju+b$b5nf%15jV_p#+~j@F zi;jYd`oAzicv|OJM#T?<;DPNIoUgigrUJhB%ur1hOzqLV+<*|JDMk>g8`!D*1O?VY z=jxNabXa#Ir~%iNEZCg76>&@AtH%{!#f8f;4X@=vE;qTo=XX52R?I!>As^aT^}uHk zI`+X(3+#tc6HRA1V4mP%YmqeH&CovQ6P`^eMUPUCGo-h>UFcu@7VvT{Mq_n zrJz#Sn(@3TOvHD_&@EUE$fEXqZ8@|w8arckkFkiLSWo%HV-NPrgamrW)G^v;Ys7)Z zPPuD8W|~7`^U!cqopEd>6nJTWseX?YXM2hjPAHLy8AHrz$BrF79P-`^0gn-)ytEPJeFcAK)`3OhJRUmb z$-iQ_kXi)GB4RStL0fmSg-E*wzuad(X-PXwWSRayQ7OaP1=S5 zC5)-|%7q)Ny@Q3w6!Fb4d*xV~HtroJ{>vd+H0~Wr_Uvwqqx%945b?8>nj~Tb?Gd^8 zsD` z$37Q!%Pjksj>3`1ePYyvy(&DO55R@b@9?|{W_|wIsZ;Bw`Y|Q7o$a)rB?{8&!cXSy?7u*P)b263PRq#PpURkAQPXE00g||OATNJ z_ncif;hyu-=wM#WRr^)7wPH@AaUa@+YtQ#D9TLp0x$2C{*A~nSS-lELwwk9UJ@$S| zzV*hSv^j^u$b)D_(pT&QK|o(IwWtWwm4EnlP>QF+@{O>_qu&O5(L9pQ{qNyCH^mej zMQM^p5l80M26+14+u8(U3)vwmjqtb78BJlx7V?Eh7%onDS|Lrx1OeQEawDY)&cJm9 z=Wp<$$ZVYayB|Wp2lN)4O9zS9lQiNUfUb6z`)-A#L36S&4&-sW6z=wkgy6oX`jb#$ zuoMBIQ?U5ONKryWXq0Xi3BxF9R81W+4cs;QOiEgcfVi(6P)n3)y#;jMZpq6Z`On0Gw zOrtosJp4}Bg&|q~_e*Z@jvz&9iEJ*dU%a=V0&7l4E8YkM{(u5~p@>Q4QV)Rj-&4&~ zc}#|T6!;zrj9T|Qq(h-mkNlb}Ue%dj!NhTkRo~EvePBXx9S~U(lHpy0upVoM97y93 z!R1&s-{%=l>j-*Bmm+FU^TnjQWL3Cy;f!EvafIOBfh8fnfmP0dOzpjNucSU5hoPXr z$7@5eR>QRrahOrnyg#LCG^s#N&wzd49k_dvJAH%k|83MBoaJj%4B9U#jP5}T@Y)@` z;Rf|w8W~uFy&zBU&GIy3SDLDWSI$N4IdU;6OI9_XYIB*XP4BEt{#L5Zx2PK(%BoL~ zkhT-3Hl4&b@=+h@#UvrGH%7gX95FUIGI*Q03gh9b;vU}5lD*dHg${@JQm0PK&PL~C z6fHvnk^PZ6eINP{ZBwirMR9y%va>Ua1Vo^)y<%8Y%@{Q3P#A@y8n_Z1je|%yRO(iG z>EAoxXZp-|FP;5v4!-;HBK6pj-^bbD6J=*%fXB;DtFN6Z8Val}bsZL%sG_i8D+ zCpk`3yS6FfaSBG|AHEwE@Zco(Y0F1ZHJgx(&W+1&#toRbPVd7PaO}nD^)%t$F3Fv~ z8)z%kLk*@Y!|?Ikdm0y`g+jV`E0usvn_#|ZbUGR<21&IfRCsV}x)mSU)Lcv+EEnQU z55z{*&_`x1?%0*LNKNaTgd|MT7=aNxoBPO=!F$SbgH-2tpp2n9pCs{`>O8Eg&iK3_ zRT-s!B_jI4Cp~9O`pX_Y6JUiPLE>$Kgqew-xO06OV6!cs;)lFX|@*F%v_oiq$ zhyjPCMppe@eyH*|Mo`3i&ZT0z;5;1j-C=jq(!p~euzJ{dEpj3u4Rzmg7CntML!;YP zpL`m`IX_FJDDZ_QkzNEjluV;2EK8y!Fx>_*B&vo4nUav4t&|5*OPnV;7CD7&p`q53 zW}p(GG-sYb0+DD)05jbi(?v8f(4C0{=1ErdAetD7Xz12_qp%QblX@$5P$lGNeIX(L z!dmx9tTw$%;KpLYHz?Q#&=*o4KvQ@-78_Yo{zNi?T#+SJ60hDMqNdi8GOgZuxKFRs z`c6EZ7Fcv!Jt1b9dvZjBFy5RGt!l(+VHDQM=7bRUP4FCQ&JT6tzJnaA?ugUwqaHsN zw(DO7LQe=j7YOg8@O^{wejR!5$AZ_l zE;zT52~L}(ZEyr0I!}we;1Hx4Fg0q2JkEC>_nfO=_peW=3n$NMQCsD4m0x)FgYRJ~ z|9(N8i+^C+{vXOA)j&`u(iT=kZW=ePIbSpeVuEHs`&+SdlBQ-AGLZttd~AGvlhlx zT6V6lOS{sFdVyUi>OCR)V{17q!Um|~M{+oRi9|0o6vALwU7~qUfVTy0Tf~N1Brxm`D zFyHYdc$#Ua8{-1!0OBH#oH=sh$ls2%4tm{v;nI0e`=tWBwXPW<(U(3AJ>nW-LA<33 z*8mIRE|Ja99`ziYKlgwVCw!zQgQ5nC6EhTxgUEuy4rq`19Aa_w?jl@Yj#Kn0t{KHe zKZ-wPpsYxgH3VfTmMHFoY;rT+Km*`UfKz~WK<7I$W(dkw0nC6*KnY+qU=v_FU^n1Zz#D**fU^Mk z`zRBj0ZawV0u%s(&$7j(e32kjn5Rrxx^(H}rP|5mu0>OF($l7>O(t$iS^i>YWkvo% zC&eENNK8t|On{l1L@+CPnrMfa!7#})GE+0>1kBWA_%O_j^vs!eC(j6)lHbhCgv`{L zGbSK>1%S+i8FQF~%*?dZjLfbwl4d4m&T%9&$!W>y$eT${cTo0HIf49xWll@YNk)~f zTCddUGiJ_8Mp(KdEfuj+XC$W0PD*BG1ln@FIwDKP5ooky_SCf0M24A_e9!FESz>Wa z#+;1IWI9Co9S`XxuJ;6z%dy?{FaT$+qz9*Ekc@zy^D8gY_E)!uKML2H{C+jIiAY&P z54i)6jG=cIUG<57-|zp1qODw+`7N%GUjB$2^j!W3fBw)wK2O{P$J_QmHmI3@Wr+CS zl`FgkNY$l!Uly$tLwr{FS59H_5Lc|G-#->s93ZESaPu@zF8-T(IQ2&dC5y`DVKM=$!WLcS}JA%Q;-m8^kBq+bcy zK`$zkd>X!ket#6G@wMsqvL6)o@(7C8gMMk~`GM`g1Ny~lGL7bN8_nn7L%=`x6_A`lo&%b8Di}kwVzjgi*Q^T%CxX()T+jxkt zVyY-yqSwZc_&i1o?{>#`yZw!CBR;wNJ`(-<2LP2K!X*0jTXOAP)Eep!-F!fz-^>1w zqF%e~w_he@_;)=1(G+Pj;IiM=gJwn-cGHr7X-KF%EPMct91M&Y6ghZElyYd#Y=_;z zME7(v%$xd(WU2LV;sAPJ|A;vKxjgBX5YkC3LWe@|#Bvy{YTDaahQZK~b?W;xpnZ zPjsw2cEokUW8-3DV-^44L*E*|-qZE{`G92rJzdR|$yA#eWd%S9XaT6UNcJk2o5@Z% z{@`&$dT?YHAQQMtL((`HUhNXt!0 zPH^OAU~4illXe1gbJH`j5@%)h^r!M%?lPfxu~X%AxyoHCh8YZ1W@g&Vj10+#oJ>aQ zjOjg`Ow!Esgwz?`KC=w0h8r9)N#!ofUr_2)3FWHdvSOh)zqI&%r>e-AUm<40P&^~W zD=QaN&a!g%q9T>Jd8;Z!*`?)6i+d!@7l8KebcSoDs}u^ZlTJ_RD%>uoYDuw6aOan* z3f*N3DR0%n{L)gf0IHYnn)&CVpO+O2Q}P8eR01`zt6pjorR#2Yd4&@hmzPzR0}lnx zCB+MS#0}ucxvavuP;eHAnCZqM_H7NUTEveVB?jUwc9#mpLXpdvUjPg(ysvNkYvU!5 zs32d+M|B5B5D6eo=Fbw=8cXn}ELHSZ9-C0?gzsNbYd|3kH zu5`Mzn#l#FrIcIuLu2>-O)}*P0NFjilqnwpkUi=Nneqleih1#3b7dt{fM=pA9gm7E z%kePjQwpZQU>w-9PXHu27djU&aJs038Rbj5>@yb%<>Z~=tPp~p3GPMiN`YbSa+ivD zx(jqf=@Kej#Z=AoeAmJvnA4mKT)%L4JD#1l#ME&Ca4hVh3cV}s4VJ?s-p$e5Iii-qXeHNbe?2aw>#)BnmB{< zf91T)6S5TW+G#E)di_b!KFgU<3a-KYOms>1H;Aqi%NH-kB$ifO=1gGl3NfdU6`1Il z@#IP`FL0MSQxK&T5tz7cziGv#&KVd}@Eu6L$=z%rE8kU2+!3RrM~=xDEx#1YPjXfY zuJYx~FGN=&c$$Ekz7~=tab~gNF9%&xWtnGXsa;b^q6?D>xON8EC(X&TF*-_}g0ruG zA(LDN=GNDn*)L0T<}bM-I`aUN49*S?vJeBDnG!NfD4kul6l0$GRY+!lNjihU%q0IgB`` zvqz_82rh8s$^_;Q*9ggGj)r6x7dR7(@?Dwb=`23pr2`4 zbQWOTyPP!V&`|H;pIX-Ce_Ga6`^@rSlbF|JX^H9i6%rnhYeP>rYMnv#kU|Nkh>_LX z2XXFBo;4#m?P~J@@tAX4H`vLHJC4u2!^AWs!d~#DU9C79_koPbyA|~Yv;f)w6q@CU>L z)&q6{S^#YbZ$o%nH1dEO$C?-=%siM3@~ncn9>4-B04f41i_+c%KbY;54&Xpo13(Fg zN1jT=t3aIg8&Dqkk3oKLJ8nfD02V-YHE@yy$OJe6_XB|8<;miQMb8{dQ!3<(JytZsGGlbz83u9%X(5XY2VGJEmF)+iK5zLKD z4097R5=f6lC*8t~W>n0rcoo%HCXN}$jAw4cdBxkAJD59}iHs3%E1JwqVOU1ZXc#S{ zV@!;mNlTrYoa0Ey6r~p&rOZuo7UpAICrV6>Auo{~NmMVnmsR9<%@JaR9vY z%koRXe~X3Xj(iuSqyV3%U}8OqndGJHOpD)lq!yi1x+kPo54v-rRhZK2848V5bTMx zq6kdEeWKA6k&mT~D+y8hhC$*$zxVMCP~LTYlR;^iiwQ|6KB;`605*J;N+y?z{Que^ zeM(6VF6jd~Czlmmr)>zmPSIrrfzq!iqkx1Zag}?uiizXoY5~i74y0Mm!oK-lBRs*i zD2S-*l{=#xGg?rI(I;z!iEF~E)Cx3{zqosBlR6}TyMQ1BpVYES!Q~bOv_2Wna$;1K z&B(}f6<0uP3ntCDuehSZSs-QGCkZO)x*oxa;n(gKG5G2oBL-a$MYE+PV~|MtRBU!x z1u?fkt*?Tr+2DLM3WBZ7SzOvT7NSfmcR7m}l_g~+iSghg4a;PD$vK(1Q|Dxg2l&a4 z&{qjnQ+eS8a;6a*x*h3y_yxTfci936&IM3{I17uHG0ejJGSXlyEXpri>r8QvqgM(-dcHu7 z1g6Rh`_>J34%CgbiG3@M8srD3W3f+q#9aWDmTP$st-bRpE?WYfWC8WIG*79@BoTpO z@++5@Ei8h5tK3}~OpMk*p#gnRz@sO^Ktmv)G9WC_fv87uX{mD&DcJgSZqIZjK#nTE zkb1tW`>===7cK?vic+j^(d*r8@B-vbiq-BW^z1vK{5~hBlyJM$ zSz0;?YSqO^I3d_>G5mIfs{%zr@rs5Z3kJ;>@|Q{4MRJ$B#co;bTwE?H-9VlBLautU zNk7?0;RU}3UjS?a>;$X_)BuhFP6C#_1vg+lU?X5NU?;%Q0AA1t|ChjH-jpEbV8Hz< z_JsC>PrQhIq&Fnk-XyuHOnRnPgZIFs?~V~Lf02OnYxJ}uj9xL^|MX*^9|Qdu=*K`m z2Kq73kAZ#+^kbkO1N|82$3Q;@`Z3Utfqo41W1t@c{TS%SKtBfhG0=~Jehl(I5pk<&>07E zi6&jn`;Le1)^2FQnJkz^FzGdAR+yAD1|}iq?AtQ&b#VJ&4ug9mOdQ*0N@3Cq=5#Qr z5|J=*w3|8hCm9_RXEwpa(QZb7iKA3Z0nFtvGhyBjGYMuV%y^hoX%=P}j)~(lzT$%; z;tjzgUXS;%*TYWrrRT>z?D!N@m;d@6_D6fzAM0WNNe?@nFQfBjRL`DhlZDWC2yyQM z5%N|qUyUQ_;`8f|By-DClDX=MHfjnJ|6rA9Zb$t6TaRy5Nx@hAuevOG#Rtsizi0e} zK>R(3|MruopB%~j)K}WD-s(jQTbhM)^`&GU;8L zlt0lM`3(gStr3tv;hp^T0e3>cofvRCU{ab{0soAEiOUya{&Qeb*>um1@>vW}0V)7Q zqb>l|mD)k|sRB@)R|U+~Fe$tmK;bn2$_KQC)AS7UtAKk8OselT0G0PNfa1LXp!(5g zuqga}0ENc@DTJRV@rgJBs#V|L1f1BHetko(=1u_)ulK7#-TVG}$6tk32Y+-U<@@}4 z=CGRS{)M2m-{%)huL3Uq(;pcSFd0B5(Ko@r`uTUL1L2@KQktuqj^ZpJU>{&FU^ieF zU?*T3U=v^ipcb$KAOMO01%N!jJU|X06W{=(0a5@-fOvovzyVl593U1D4WRgu06C!Z z2;MaW@B&T(S^$Ru&432LPQW$*)tma0o@IkWltn|o8&(FMD#VvkO8-@0SVR}?=lp&L z-ZlP@JdUJ)Ed62BEpmudzo6U^tWRHePybusumFAlp!xQvfad|n0OtWi(Lfe31F#rC zc~KfOfcW@Qz~g}3fOi020O+NCQvm6JQb7N64Ge&qbO^eSZDaq+e#WlWJfREK-=H6> z|Ij#+d(!lr>3}K3Jj^`CJe8ltFW^t|ui6-uG)Fe5kElmzZq}$YIhtn8a;-&gvokEi zq#?gZ7O&)DW7t?$#m2D{*oiF5>R67ovhi#Zo5H5C4mOirZP{eWwH8`aY-u)!Ez_1` zn`g_j?Y6yayTv}v&crjg-3D1eGeWah6Q$K^c^#wwvEh$~5nQF|LGz>LUz(pWKX2Y| ze#`uUd7MRSF;F%_&mOV zFXBu23SQus@hkW$zJ{;m*YWH54g5xa6Tg|?#&73$^1Jxm{9b+^-@q$u9@}HKXnTx3 z)~>S0*{kil?Jv_U&pd`nfpMDkvS-|5+HHcTCIV#OVt%>LEVTe zh@&+IO|m9evt8rW+^%J{%e24K9@M_8{anlGDs?aE-qoGdjnc>Kr|W0y=jqGzwfc4X z_4*C^KkLH{afT^|RKo(pX2a8l7Yr?iV}@44BqL|6G;TNk-PmE|I0skGJ;?o>dxkr} z#hC6jZ8W`LIs*J$HYJ{}@-53O zkMzLOU~7ss*IH$L*t*^NiuEl}T5sw~;_n9C)POdc_!E3PFSjXdkv63*+7@GrwW(~m zwk5XJwoSHAZ4>Ns?0NQ|+xOZ(BpTTa{tm;==CVI$UuHjNqtth)?^Ey5{7t(|w?bE? ztI^f!*6G&kHt06$Ht9C&w&}L(cItNNcI)=)_URgQO}b{?VO_X>g<+mC&sbnAGL{-E zjDm5QafPwUSYxa;t~0JTZZK{%ZZd8*ZUcsP8g~Ileq#f7h^sIOre&rTrYcj7sn)dJ zw9~Z9wA-}Tw9nLFBAR*6@}cEX>qe`A=lKR(ldaiy*w$h@W^1*bw6)n7yWFm@N7|M4 zZt736r`Xf%4tu6O$G*(I!d_*svDezy+1J}Q*f-jlT^J8&Zv;D(ZDtR%EufE9_9Sal zC#wf(hH2i>9M?2!4{KYr$F!~5liE&PRF&%#x=5W;7p;rYaXPCmUYDdx(WU8px*UD3 zKGrbS@S>r?z!>F5g)!2oG)5bBparWj-k4-eF{T+E0el=ZzGa-xIl0xQndU5WwYkpR z3CfpS71l_r(i&}z!6>j=olvwT45D18djj!Ypk`_b=LLP4Zy@E>t^fjD>#pt zPXKS&%7@w`>`Vj0#A9CC0{UO5E>Y)b=4tXY1)3sFsis0BXqIVKXsR?d-~sD2>oprR z8#S9Wn>E`o5?VCJG_9JGnoeBMm1`B+NbN+744szKTD9@oByEZ|P3zERVyvvtR%vUr zwc2&sPqeq`ChPKai>^r{tr$sWeS$v3Fwn5eu-mZLun+iZGBg{!hO>rt!v#Z!p%eJa zG3FXo+-+O~*Tgk*hq)H+7HaIlC8tmDN@r4a8IU1k`?x; z8`MqeX7yopi~5+lRee(3rarAUYZ5d&HM=ysF>m|{{320z7g}GSE7FzfDnuN_>F?C% zfM?|C3-m?$FZ2?3O);by90sk)Y?A6-VGgxMSc7xGc^inbjoxm7buqh{-G;u~$?jrz zvwPWnYy;cWi(1>*(_K9MM)fV~Bz1~9P3=&hRo`_5#m4GXx;Whg-9#O$)AgcXhi-@N zIb9=qXP$ncUeMR;V+^qd6}a03ab|EBG7UL~d4@bgfuYE7FIT|1xgT?1a9?o|rm?0U znO2*Ag7I2tUTm&6|Jr=k(r&q6>9BOu^h7Ib)mgb~()2d)vYpmlJ*as$=D$v!u?4x; zO4~!WpW1fWbao5Iw3GN1m=(!i(d^B=aMBT&*%aXQN_Dhar{>gFb-aj~VH%I-G0j%Z zK8;nI2|XR?~&O?jpQQxT}OH-B4aT5sCchs!mYvN2yCGoLWmS|732 z^8dv@!~X$T2nFw+Wcx4h?BCc9+K$;h?<9OcLe~Kw3@c|9 zY;Va(l7n*CW$X&JimhR5uR&86y5s_d`hN8Xpz=F4nrm{5?V$cq+BmIVJ3~wK|Ebom z?L9|y&k8NNW4gP6!G-!2dd4uo5Mxkd&fI3$ZrCYu0-85Z8rlq}MNTl^=rnd3L%CQ^ z#l>+GxQQIgC2=X-E8qv4ufW?Rv(6l6nP8a+sX}MrELKar<#~(5AA3?(1V6M(jtaw^ z2wZ`HF2Klyj4+SQV++_Kwv?@41z?IKRT@c|>Kt{X_6F^0?ON?7?Pl#Z?RM=>ab76V z{jh63%+xpNoAk~4!}=EeF@2I@wXxlJ0drfYk>TW=f{WyoTr?Nct3^7Fn=Vs7S6`}MqaS9t$#91u(GX%BD9-u2jeCvz zj19&%<7uPUc(w~yJ^Nb*S)kgq0g~lpv)(+-oNGP@Y;^ZWGS^&SOiE&D=bw3 zey_CNXuZRlXnoT93}o_mtw(v6ZMp4$?RCfrU)uVN8Z7wo0%Inw$NJ$)Y6y;-O;>Q_ z6!lE?LG@ee`?agI_v;?k{X+MY?sMHm-2lBxzZP=h7X3^5X2aotY}ifX-Lsv%OInEO zk`%fnr=GG>5N}Pruy!B!CU=xmnQk*>nsQ9@uEKFPnKqk-n1`Fko9&P^4}r?gnS)rX zvD8}Db;;oSEDe?>ixv3Gv@W)OVg1S)!H?~=-e~3z^DX=_z7?yqHa^!@XuE6+3#>OL z*eBXqJIP(I+W$yA3Bm`hm#>_|Cad-837Ux-R-@B!8mlH=lcYJQk;c|8?QZQ}?LK@~ zyh(erZcLZdIYK{5e>Iu%9L8AzSHzWa72GIu9M&1XFz+(&Ht#j>Lu+X?c`T0w))@ON z?p~|1(R>_M5^vjnU@x*iVE5R+z`73Kq(hwtVohnnI`T308TJcyp!!kG0nO_e9qpPM zwQB9t+P~_xkYMgL-oee`YPt2MpNf3xZJ)ztb6tpSfNijCq|IpKZ7H^NTb6CE z?LONNZO_}V;)dcJ?tHY1m;<8;xjH3RWm3Se@LD70J(yPa1!3JY&3Q%mNLa<1TSZ z(;=*7KQSd?b@n&&N7lbs|8D)#`mJ>!KZGC2kKym&HCU@Vuujjz8vRFnHCEwoV!ib- ze}UKAer4Nh+i!c(&Q!@n`8x)B2_tI{=p@|iFWBd=kmbgxC#WZ?S;#9tS3d=L^H4zA zJg2@{ldj2x_G4a;nfN75kYA6`-l`oB*<254W;tZ>_1ed^zXW|YXq&ZfX+O}O(te|r z=`6ZL-MzYnkZ$UAKhr&db=yAO0o@xqukJIQUpE50%B25={tx;WA>EwO4>F84+yjYk zvEd2BGoXr(pb?m4v|v5wGOonh?T^M|#!rmHxp5eE0#>(=ahti{aL;jjxf@I)O$$s< zo9fJ4!DZUeCWlC#(I;}-=&|Uzh7Sk zUb{oTNB^?EQGZdz)*+N+cHA4WjnD zq1$-XeAN7@`8G?T#cg@Za@2Cpa@jJ-I@~(idK+fw479cu5-!7!;8Q{E@A0v=TS4Cr zTehtjw7m*Co2P8A*gmvr?a6j#vrPQ9SMgdqOH`f!906R zYtYfV18LJwWr{ORfHtOE;!HB7n9@v+uGyf}TwxY4CRd0nq}ncB%qH_@^EUH#^UfaJ zvdP>mN+KtrjX7=cTCSAkgX>dOKugmt*{A(~Xs-6z8m?H&pN1~ytgYR4p=&MHdu5MC zH^`V2@J$D_d)J<;*Rku_tF7C-SRJ*iFQ_}fV;K#5l~rwycAhp*Tc9n{mTD`s+pnVK z=$3I#V+{3PE$O=SXwpiL_-pM|bsydHd9$(S>Q-rrHpQ4?O}+c}yL<7w`>X++wv|5( zy%1Jcc;T8%+)teVu2Z9~Rj*fX!0fYG&9vd$stAs}iZ=E7_};*7WH({Wx(ocRnUz+; zLa!Cocj=D^vu(iXSzWvC0x6BLlSg`1g+5xZ(8vcj0u~*Z>?&8xho~gF|Pd^6wG0=~Jehl7)R7JhaDEDnV57ufIM*JS>%`aE-PY$X2o`2iw&ooN5NL5&sW*e6ON+kb<7T7)SIbQqcLGiZG7n zK~DyXen1Mk@S-BL_X6nRnxgNJg2vHarirsL4S$aD0G)p|rW3$p8b@E4j-r01$7U6M ziWGG6Tc(wjnYo2$7nfJ2rk5rcXBL*9U0j)+xitOU!o)JItju4Yoy~L5>zXBISbqBQ z{4*<46U!5{^4#3)%9OX(*lLH9TS4IYA*yMuZ>(5Ln0q=1I>AyHwEQb3tH_S{u5C2J z-+IAjtK$nsk)P$9@z**o?zk+L2))2>w5R>B6~4022sXW7GVmIqCuQAST+45~@KR$_ zh$LCMd~0pZ3(QKHLuD!+HEx$)3BAeAmK;EE=Zo`lGk(*%mO(M(RI!ws?6kMm{rRo+ z7jg|$qLM>O&$fK8NY*S@lF#5Ypvy_aJC6>a&axu+A&97Wh7;KveQiwap>%X&$9mHy3BIUFXdoW z9bA&-UYVP7u}4KI|5Je{W+-k&oXcEGUWnOgw>HBmZ?*k&!*90b0&*}Y+3b!1cbuil zC!3A1vE;3W*!K3ytsGkVY9nZ@V%tuk7KgZ%May^A*Kvk9Br}CdMjd~4nQWm|W*SGD z-!$h3qar0Wi#3EHU&S^CEgN)Jz0FO?%=nvOuvKuREflh<`WC%#EAZ!+ zmV?$t+Y<^7bCD}mQW(4-?7pwuY-T;SeIv#)s>a4;){@;n`5LkurnG&v>?v5@TY)zVo5CD|Y>Dd8 zQ=PzTUGb-ur%Yz_#4KQ5wpk);&=2QecD7CSd>Kp3dFykHcDu7`vKpC+XVJ4UCAo?# zYe=D`g4lch1T-{8^bzO~ywvwW`_3T+?R}i+9nioNL~nw2o<|!&!IMNkfL^?SdO>R! z(QeT4IJ|6h@^iG~Rqzd{8D9;AopVcJiF^avfGgLH@v(-AsK z$LKgcN+;+fJw`)xiiYV4I!z;VhDNDIbsD3y^dz05KI;F!;_t9~-n{al zido9OWw1$8`<*|!Ik#LD_^P?5QmELuRJ`I)QF$djN5x&}`03pod0GWW1lJXvnTAhh zj!}G`>fl4d-OZIt8RKIn{Z=P7XTU75xoWB?oi^}UEd<3lS;b>gGSYjA`wkeHUBanR z)hUBOXg^t$s2!bM*1bshn+0|YtagV@vJHD)BRZ_-WU#hxUMqy^hOrXFqRg4Sx@cRb zsuFfv0azQ`H$ipnZ0b6uDXM&1CZVdliWR3s92QyDOmWy?`8aHeNNqvvHMNk1hA^@X ztzg^4pX~`awAYF z@`a`mC3$@#i$zdU6ghQI%9Us!k!7`C6Vo(hRXQn?p*2$`yGwA=9g4Ju9b=7^g~)jt z4(*l7fx!|@v}!UTWY=esB@^lsg;I%`Tg9p2q`W0ICm3wn&c=}FJXx4%zD%|~a+YPX zX~8T{_K?k%+Yj0dSC=@KQ#;CP9Bdgs7ZX#WO?G`L@W7G}76}fU?vxCL8dR|6f;ytq zu1zINh3HS$iH~$>;nWvsSbkM18yZZpMEFzdb1HXV2ID+YuFk zk$L$~lqQK=@PAM;)bw81x^ieqLrvnJHu`V=#%a%`p%z~P9YX9O{@sJ*&*1y3;^jV$ z)9@FH5Alciw;Rd73_i{sr@=2UWQYRX%Aa(bIcdk}?mf34GafWTIDzQ;;9YaA)u6N4 zSqle`Egm17otb}zC3C;qki(K(Lp&+BM5BFElxO0g8LOT34Yc?A;7+=JT_fs=D)Q;4* z_u*W5HP-aujMa!^0Go8Sk56dcN__CxUbL7qN7WJa6Riv)cZ}yULNvWK0cU=c*=;qw zXfkN~fy9SPjAl4{WFl;%cgcG+Ii3fB#VaU>7de-`Vb&d(2pc0>oM1Yg*51%-4s`A@ zg5PnEbIx#Yn4@)d6l7*~AMjY6MWd{pYyo9{lvzKcXYEK20)>%oE=M;dxUtvmK5u5ECukwX=)vIKDT^XHs>Mvnq@S0332 zjP!`>=rNx}Y*guSP6IAI;uW0ixTH$(%s@_$hz0BSb^|dNAQG_VN2y&iYM;*oKxErk zkE?hLXM$ATr$y)O9R{K+oF%|3uiv7x50{E@e|4BlK$#z9Mz-ke!!>1sq@r(T^_9nT z)Uhksgv6C;f~A9c0<8KNI@ZknKw{T1S~GF5Pym@9Wk#@8VC&o|a8wM^1gJcQMYhge z0!@cD1zhD(EV3Q%w&5XU+9RT4-gvLG|C7#}>LG_>1*G{=W(JGa<-HOyitw8CZ^L>l zSTA^JVD>ML91A$}qfFoG4m3QWz{>%JW)Dc4P-1|~;1-==_ZhfRoVzEaA}fRUdbD29 zLtFS<09W1{b?xM5EL1#4!D|cy*>=q=pv{jmqg!*>#)p8)_Hoi@8SOV=D$i&U<^u+1 z<`SVN%%Txy>sotR`FKBwh zbc`|gbI`=p_dY$L)g5{TkFJO#AxRH?>vd9Z*bX}#kHGLsOJH|fP?b-qn#1a1Ux@v8 zqu-e;5YgqzxJ4E;pHl{|^#-dq^rBwlS)qZRy{+pFx9&KZ@e~p7@C;nX^`1DE#YY*v zPV0U!BT;~SBU`R+1+e*1rpIFrT)x=i^EAONx)C-(E01|?%pMWoz0EOE z-Gb~zvjD9=-UVw6kAo9b>jk!eHb2UYc+t7SXN&Hy^R1Z)Sb4OI&T>4imgqNJgB4l$ z!&&qjtHT_tjQh-Isu=a|M_TpuR$#O6UeoxFX9vB_c|qU#LNdj6y=D;bmHS>4SK$l0 z1Yf_B5OC&4nf+B{|ME4WM$0_DFkve1s^pS5<3A1pk1w?&O!=mxC%mFq0N=!GJj+uN Gf%{*geonRk literal 0 HcmV?d00001 diff --git a/msvc/Expatw/expat.h b/msvc/Expatw/expat.h new file mode 100644 index 000000000..c6a4b3b6c --- /dev/null +++ b/msvc/Expatw/expat.h @@ -0,0 +1,1013 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_INCLUDED +#define Expat_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include +#include "expat_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + /* Added in 1.95.7. */ + XML_ERROR_UNBOUND_PREFIX, + /* Added in 1.95.8. */ + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE, + /* Added in 2.0. */ + XML_ERROR_RESERVED_PREFIX_XML, + XML_ERROR_RESERVED_PREFIX_XMLNS, + XML_ERROR_RESERVED_NAMESPACE_URI +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( + void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( + void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, + const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( + void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( + void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( + XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (XMLCALL *convert)(void *data, const char *s); + void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( + void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, + XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, + XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, + void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { + XML_INITIALIZED, + XML_PARSING, + XML_FINISHED, + XML_SUSPENDED +}; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR, + XML_FEATURE_NS + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 2 +#define XML_MINOR_VERSION 0 +#define XML_MICRO_VERSION 0 + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_INCLUDED */ diff --git a/msvc/Expatw/expat_external.h b/msvc/Expatw/expat_external.h new file mode 100644 index 000000000..4cd16923c --- /dev/null +++ b/msvc/Expatw/expat_external.h @@ -0,0 +1,115 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(XML_USE_MSC_EXTENSIONS) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ +#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +typedef __int64 XML_Index; +typedef unsigned __int64 XML_Size; +#else +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#endif +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ diff --git a/msvc/Expatw/libexpatw.dll b/msvc/Expatw/libexpatw.dll new file mode 100644 index 0000000000000000000000000000000000000000..9aaa5a826f4bafaeef0061096e140710d5374a63 GIT binary patch literal 151552 zcmeFaeSB2awLX3(Gr)+0bHFK#n(ClqjV9Gds0Ai!0(ny)OcFAKB_y=PG$JaM8Ko^^ zaArczY$wvHXzy*&di&z-?e(IqZEULzL^GhR0$y8N+KTqYlSW(AR$dhHeV)C~nVIn7 z?fv~e_df&Y%sKmI?X}ikd+oK?emM(2wMlbon&!eaI;v^?_~l=fynpb`MD%Ir{P;BO z2dDgEdcR}AFQzZ^#`MS?`5yr_d4%ceh0*6ccRL9fv>@@qd)25&57_Vs$I&i7bvv0<; zj_0lT`}xD)4>|B52R`J$ zhaC8j10QnWLk@h%fe$(GAqPI>z=s_8zvY0a3A$ElE48r6fnVZj&)}vpe`0aa)rmyz z%z~i1)4)U1O0C%(XD3FKM<9ynA^_9WY|ciU*q?Y>PrVzvFx~S8UXuf{bGmkIb?6cE z`c*8(og9cyikOc~;EStbpnXsbwX^7!R9;?u{mceKgavKGI_meulJF7N*>@4I+!UuSGNh)kW? zo|o}HUF+RK7WQs=laRLDDN}C3y?4t!xSP*@0iZYc<1yN7K8Y8xE*OkP%&#DM;%R^A zy;$SyEhb*#brJJ&csoECu&o$aIv6#N+#ugcIZ^bcqNAguB2v~2+K#2tV^g^ry;QxLy{rpFRr%ZtdN$7hy^{F9#%rO$B+Ai^_m_w@975O zH9=p+URe>bDT-U+CiBcM5=Hk&QN@7KLpm~>H{srr>A43#&0%9p7oeDHSkl=>yUS>w zX|&HW+AEFrDxr#GUE89|akaVxv81w3irLmhg2;o4i-bdzHM`$a{mlFOc`J zyn|1uwB_>tX@)q^-i&IOv87nX2jo2{?-oU+m>6jMI>Tru5=12|1Tr&BQsd7AJ8r))+a2T^w1IA_s#9tSi ziFR|uycIb`5AkLj5FLLF*gSj-GA{`F zfXja!fv~E!74bBO&A(l*X_lICbrEDh>Xbr-MpXtRr%Sq{;;FTOnQ3t4QDs2<^$t6u z#UJuAanKP9B@Q}cmr?1Zpum(o5-qKLFr4WjvSIT&APWwuNR&0fN!tq)aakE)bi$fhoe4h(5|T5-k>+rK~Rq zE*Fh11hk3GOF)Hqis}GKyF_CQ!7I|6DTSharnnfPt3;mFF@cd zV^IwP%Z+FQ0%sca%Mn;(ED9sA(ulSpu*#@kg}|_}XaxcrjA$1E7Z~;H5ZGocT8+TP zMszI#mlzw#Fobs*cXjg#tTXN-)regYGL4Rz#$A%T_mPptCGiR38Kd4c;xuk|A=|3Z zP|Ru6$I^EOnLQ2GAau3yBQ`$ zUzYJI^FHY3d}gJ;EB3N8rq*gj8=|%dy%*PoR0Zf7f~s>9e-l@V+MsOX3(F!+=HF0m ztL$3!k>|xzR2V8B^#k(xj4gZ;S#i6Yxq#!y@5Sb|2#YkEk0Q6|iSZ?DeiJXMi)b=u zt--VG0h`S-Jg0j|2l~D_gYol}eh3XhFFisQXBs`BktXjw+aXmylS;yq@90F|E+lE9 zQi`}`A6Qo=(eJy{4&O|*rMgF@w)~;Nj%8!jmSsLr)mnPyC~TpRwurW%Pt@z;7FT$* z#TUf|Js}VmA6{x{98|5#sB-0WG{nm#HrVQC3f0e~G;~<+2CDRmfx-SWfln^^rm^XL zOz#Cu=sfSe1HBt4P5H!7j4V$;|LLJ;;}enDZMcmF*C1rsZRkkJyb&m|i`Y+u6*Ch9 z;jo#wSqd4{U{O1)hb~~#j|+;BP}E~~1B3aOD^r%&&0rOz-n)-^PmX<8_NB*Ym}!J( zZbF6jl1M)gb?k$+bS^Y4|%#8(~jUZdX0k6d{TMtFe?&UGPqcn!zoR|zFOWMe~k zsGF@gPrAa_f}e|b90Pw$`HPM4l4Ig250c)+$CR%U=J9JgCVshk9|M1d5$-w}{1wOK zR|)g*R~-|-+J?{m)y;H9b&NV1@*K+*lFz@^PG7+9b;c%|zPZ$pKbzhS-7+HoPL(@Y z5KpyS_)Z;cz31A`N7x>8$-fO$s8UP^(TZ~Q%Qosp2c3{j&MfjK{Ycl~O*-&{p@}~$ zV_31NH@&IH@C$Iose#_a9}yTorG1$Mx^z&?FBbFsnKgbRQG%FAQ@F*LUov_(;h`fl z5>%gPK2}+&fpzm>VXU7C6yvkSRFR;Sn-TXTRg(||(cBas4bK!)nfq=A^mFEsBNT;{ zdb5j91dyWLNCfedO|aCem6|T?{?-~IWGPVui)Y{3`L(W z8jD4HP}KP|>;2AWoxh2~rUvH&P2q^~2s0TyB+zIqHX2KMw~)1?n{CeZD9*(`Dtbtx z8b**fqld%-Q{tiu2V1>l>nF+9aZi#(Vw&iYyp{HRljtkpErx-*v6%tl8A)+!Z|sGv zB!gKIWU)6Zk(jQ+SeyzVE3ERBNR5%FXo3QTfeKkMgN4ish&9Dx2gcPt@ZMkgd}y1u zPiM@R{G!EOdLUCaUSvzRiya#daqfBjxF`7I95x_|5Jz9>UuNU!_KMIBZ{}qbUb@Zs zmN*#6xaNeL%}W|FB$i@`3M_r0G;7Q+?r1mW`Im`pU=ZrP^gw*vQ-sLUo$rSBuR9zW zZSf?Yb`d2=r?b>Pmi}eK5rx{563~~5#V<;qFa3w} z1<2EGOPU}|?|f6tL$BWABWWm2v@qcdD9X9RnCEuxcA6c=_5OCFrFfaxF53@-5$6Zm zVjeI@`8GP!i4OU02axkJAlH<0`u4}N)_W;drO(C|U6qD@j+Md;ot5r25s0Tr*=`Ee z`2YfKknLt#E{l-0J(y20T_rF!F@cIyIaxgQh_a8OKS8vXcuIna=}I=vMNmh(6wNx= z_7r_%3sXeHO_AfJyI5=vAhJNZH!JBLBiyHj2G?IEW&0=p3)u$OmJX(S*sNeBK3gE* zVsPvL5jCasv!vLVEV`KqgH}sr%6Q2;6(IHVmx*|4Pi&H?4o1Z1OG<~@o!bW!J4S7N zOhTY~CJ95P+!=G0Zc}Pl!t1p{r;D%~V9qRkR@x&IMME({@N4PtLi!B$R~t!8Q%eNZ=t7pn z!K1P369-3Q)ro_r#m}Z{3%wJcn%<~HJnlhh#U1eE%z$_UgJNr7bUu7fEf_Mjs*+{1 z$mdz0@?45M#*fIvj`sd>NQt(SPgDRnmk3@qBpQRi2dL{&&;Wmj!aW)`;Hfj7B4AJf zo&*&oMjxxqo5Uy#PKVLh4T*!E_ytYTm5zwHKr&K?IiJcPI@iO-u55^vN$9{wu{8WK zO>b_Ag2A%@4*xZ?oe-baNhXnFubr`jLjM$?-m@ArW7KJPsPVb(i3TPcL$Cekv1JRH;)V^BXOVot^@WF$Et^=b_M z0?3r~2YVoKUta|Z&>PO2s7d;Oe9 z(`YN(612=>G2bIvf*9a9jd>n1Uq_SiiroNGx_kHGj3;c&*E7CyV_wi`DRE}Se79KR zLj1wPzRQ^B5@)6M#y6lB+Ug)bmdyay;LoX~h%TVpx&dgWRsc=(oy8(WN<%Nlr({yB z;mqT#RK(~blSGOwm(Q8itoJrl+;WI@z;J_0ZE%V#X^z5Ngp*;k#RUd-B?iVx*_dKX z^=>>0ulZ;&_464Rn9r+W{?c8}ZO!49(Ux*_^vD+M1l<8qTM0Qyehy`cg)Tr1u5>g@ z$C_t&H(;pDO8~#Ebcb_$6RRkQ!Cgz(eCAqJHSo81li^eFg0`>{dec0$126lLvIIq? zdpEES!^@L9jc^;h{k?bKJ-IV}4#u<>i`um;|8*u=2(4ii9YN8lcfH9+-59FZots3G z@5{#k9#fCwQPjbp_NIO$AE7j2(R7MqDNGv7lt5#ri_=6aCN7$q=_m9I7m=LWFpE0? zQ3QHR$d_=_@bB@uQj4^j4_!g=g5S=YdJY5)zrb|0s{#G0)}gw9!<-(L@`q>iP2S|E zSb7AOs@^OjKB!eu8w-!Nu1-7+yU3fofYF()tjEmva38*1!jmY(_=rjzUdo5ZS0ftZ z|B2!>Bg5yB(v{_-tsc&ixX6h8Kz?NaA$T|Hf`tA{1SJLnMqNp!uB>7wsSbQxqDh zINSueSRQSL>{N-mAedHOx&uve_aW((ga0t}LhQ4mv7~gz?pK?_2n6c7Y*^mpC&_g< zDuHyy$8ODUL`pKg2C1dd>`@SlSsV<9n+l5nFmSQ3i1^pRFIYq#0~`k$aCBmV2Wq4_ z+L;A0sL&PRmR9oya9veEYCJ2Tb|&iY0+H!unrTg9q018ROy)rZHJLwOE-Q8TRob`| zkeH7(19)v{Fs!&bPC$Rw2V$q-6*kbYz|+Xt3Hj6ppk+ z&98ojApGDikntwZWu4zkk;ovQaW6%LaKMzA=n8>MX73XFvY}1N+y&9ona9K zZ)E{VGX_RnaQ%eE!dcK@K}9<|HabCdQDivqjP~JzZPPjnRWx!AjJvaJs_FIx8WMw{ z21#|){7<%KXe-$_$EwA`F0miLrwC2x3es*w2LOytqI=g8QCZC{<8i)-@sKPyjF8BW z&i!X1MbRT0O3+abUk@7^g)UaXq3zz}5r#xIR5BPAvJG=OO{WP1@UH5pe} z>c9Y4jZ%OE21lv=teJHfKKxSbfCv3%*E`?#ruH&0!=gp)tgA5NAfLU-6lyJxOtS! zUm}@b1{==^mx&CyZopNq*guu*zuG19#|QG<|1Q`({3iK5i61i?!_Krk>tp_iDj9PK@f79NKG9Wc9^ zqy}AV0h{`Pz~Vm{S*$p*a3q8x+M1idi_g!Kydago2Z1A(=D4)6CKvNGV{A5(VyVU6 zRS5u!ZCnSPZ5SV=_93x!IlKgG9WIA|S0pTlc^nx2%7M{QsFN;E6OaJ}24m2{L3HBj z%0c4_X+Oly6w-F+qV0exj^(O2j|OB6>b=#x$wH$hxERV{5^SV?RF@{f&6b)WCIctg zfhcnYO-Q@U0(>|vvjQ>3L<=9J1=RK5Re-$72Fz5mghF7jY?m2&KjcLfnu7;e=`71jPVq{a5R&P`H1}z8Exgf22-PUR05I;@|Lsy zAWp63_?fc8kw^kS9EVGORFA%_A6-Ts?rDWDw4haq*_0p9yRX#r<9T}mUMP*wsv6Q+ zD2@&3bn&ZWn$pPCY)7r-5c@93SXVP!(~77PeKd;2!F2^Ws7V5OAp!f5vemqLuB1&> zCklbQN-5zuLy>EV3g^XiDIEoMjPfufnQbSPV;1}6FPCb1U%93qy+qR|;Q9A>eh$}X zE>zc9rJBy`Gi93o#KoHa30%u?{p7Vjy&oRwt0C^7efNA!L*|tYVR2mUvdoED}Bkp4kJ1 zX;|U8ArfvizXmeNPq-YtNwyd`d)he<7ZHqS+Uk5%W|hwtGUbXx6FSLR-6 zkv5yxEs+htm_SYcCp6hH24Ee>J6EO~PXWr)k+T72Z8JG>2im=5HC~AV=O_N=8evn_ z=YiZR@KgtDz>gwr#Kj;)RRLQ$A6}K%u7|d<22c~TymxjV#dJEv6Y<3m-C4%hyUE&H z+^|A!5|?!*)*sbkofQMAz3W$sXJ=m;Ylg{_*apc3pE$Crw1&4km^(gImL+Q&QX^cD zpa9^ZUG~FBr%DQ9z>K8jIi(jIG*U^V8JU=szfk6*fZ|6FQ-v%vA^T)^g)s^mJR~DC z^Q){k=Uks~i^-jdFCNw6pAl=_sZmJqtXNch!Ic_~UDo}DQ?%GQ0L97vS>fiUXscNd z^=+}v#WG7lf!>*&3tm-2kLe>|+*}HhJ2B*%CnnD`BJabyXpF}zl2!p4*Aw`w69b;m zv&cbqS9Vt`s|-!kf0?RqVLa zGL=(a9DVW6pd%La$G#}ue(`8}$I)%Q8RkHR=wkbe2XpTO@%`P0oNFcwNr29@OeLYc z_-AqNoybBk8P6@-UM<4txK*zhrOL_1&tP@1)WYhJ&qj*bMmYUjSuq-VAs$HV91R_a zosn_fvTa|Hf|@Wrjaiq@dWye!Rp=FxVMx-veMKY_ItEm zCbpMEnyE57jrB*(Y$JlJ;J5SO9?BwHi8pzOX&bNrEcC+qRe(~WnuTc6Mdo4P7uwb- zDnAvUW)IcwfX@ycDcuJTs`7(s*md2&yt!VQtRlg+-+H#2*6B{31i76k4b3ym!F( zjAw&zgtA`cM!LoozeK4R@db=P+?^pW4Bdkqg-q%c4MiN0ggg^sf9*`n(!9w#-X9%J z?uoPO@@Kv4`0w*BSoeA z6=pz1RBj+P5c$wSZ*nyxAf4jy2tCo~Y_jF(2vrT9Hyp+AWmX~Q3fcA?x;U%axPrmX z?@eSm1XI<8ic;0oDWXTosmCl?Q2rJ*QiiNCJ-J65W5G(us)3F~HG;Mxj8|oISWrZ- zn%;mq*JGt4E{Y%ms2nM+v#8p(V{D0ds>i@>msN}oe}YTPmoin?R~YI64ViiX{rJjFso#<9}z!$k_l>F7E#ttL_ze=?IuPCxeJe zvAtr?tb18Ycx#AVC@REdXwuU=XJ7GSBvhfNQxL@!bEQ0v0xXhZYDcW`8K2jg!)U^j zn==G1v$^>-0s{a=KEnn+>}}E&$upw)!;!z1Jzl_8!7YI z^~~D+s@P_%@ryOOIINtlJJdv>bO)dxJe_=8qlcb{>o)8W=oR8`iWVJejnk#DFI~nw zT>w~%P65cct_BCHoIBy`B35H(AJLbhxt!N29)B6cICpj$G5x5h$W-cLo49OD`CL6W zUpFQ~Wy;Y4Alfr*V2QXVj4x1W2oZ9Y%O*w^=vWg@)|CMDHf-o z)SAx3?6vVLIulJB zv%#DOVLiGG>E0NrTUkv1=*y^IxZDd(I9NDcLFx zGBvE~TS60|1eG$|_>#*w1FI4it^nAn0#iELf#009=e%Dw3+2s0ho>ZpGkNOInlA z|9KSMzMSaE$LLjvp_Z{?xSm_hQrXySvgSMgiTN8XVruAB3+8W{WSPgz-*Eh)t3@F` z;b6pcnMe;kcgJLQ^sGNDz0!IdY2FQpWe|U4|2tq0{**^;!^vPI#-EqoYxJ zn#&RcYTmERSg3h7eiq3p_M|uY=V|(A@ZR_5VrrxgPAb$!gbpgd<)8}Yycff-6Kgmi|qqE)#X-P@R7GlrV^+ z*S9GQG^>DSIcOk;qOQyu8P~xr6`^mb9MK#hhqlE&3tA)pf1$*GjNt(3iD8-z71)G5 z0KcChD;uxHP>8y5YHq&Jn`FNMpU_5nHR zfWl4%gXJWQ3qyTXykaGa@5mP~8y4(5V?={e6nvA@%y$HzTUwalSo#W`D2X7fF`(_0LYM2)~<*1qBCZiHdsfytz3@Pqofqv|?0k)`6L>CkJp3;3~$&L79(+fB&Y>vGD!}mpdpcKIo^J^rQxP z^Yd1PY0z1GD9gw-6U|m*hp1C18=%Nq=^rkE;?`4dcC@4Z(W{(|afoj)^=AA+B=Sj3 z4x6!9^ik>dZny(Ph`u-QjL`AMBYYA)T;Rtc^tTxcL4X>(+L~LZ69G&5(Gs1zGJS*x zhp=Q87E2E|ApJpV($O&v4d0;H{4|mpn|BaC+6*AhP}v}wGfTrYaG==R5dMu&&_n6y zp(aySk%vPoK!MgK8E6!6PRPHtbW6u}KATa=MC!q`%9@X50tUt65Mh>dhmfZOS zRw}c#4J>i!;vSj08NWVMkg zI;6mZ$!^P-Sl$4zvyf7PJ#m_?S0N1>>M=!266E?Fxu=hq$n`r>OZHk?!{P|mF_svQ z&;%IO0iJF{Oy9``Fzc_vx)*P93rokMo++W{;-}eb*1X9-BUk}KMfjUruzKN;A$87i zfNuX$y6=xD0cP=JS?_3DXh9|H5C*w&2y1RfW9K7kn$;{@(JZHYOj3lVEmwP}?nm}Y za@IgT$=+rVD|67?9y=^eE>uw@*UQFcH^j~dSpl}Krk1ebu=u+AYVd5o;;SqHte1)G zjw;{%v0Dtl1;)Y1Qf$t$)y| z3x9G;eDI(MBipCJWV4nmWoT8jM8mQOwY&$k6({#_HwCctbCHBpMMz{3D&_KkBosVX z_5i@NwCNfjw{!`eErtM!CKj6FnaxL=@@A(g8d0_K|ev_?ld1`0bj!m}H#; zf+qt~tJxU*XY0^zZ~p{;bCj3mC@&d9xj8}7TTXftZ%F5Z>SO&;C0}ZH6^0R0RWF&5 zD?4GK`CvxsBa=lRZD77`1+7=(k@8gJ>2EA~)Bg ze;1}rrq-1>=(=?RmI(d#XJ7}TRUP;pfYBBW;H|v5N$tNx17ubDP(oQ%;^5`pjeeL3 z$YwGd3TbYkVE-Bug|bS#sjp788y)flhTU}8)nQgHHji)#zX|&?9|ZE~J~mWK<{Ld# zcxOlbQA~n~zVG3U*lR`~S3G2U8gS=dwx`B=8t%n|1dJ(sK5k|j(Z_g9LyFCWNIRU1 zJ=7k-tSp6Kn$4HxN+195bfNH?2(92@W7V9a5cdOGjbDGS3kzc%|ku( zO=;%Yb4Y^6=&8gjN%$1_JG5~F;v97lU&O3=Pw0kpupnWbtZxe|q> zH+BOdh`?fDAqqo?N(Uv2>Kd!?`Y}+Rx^DmOC^CU^*X6>&>#RxtbLVn9zwYwl{mdS4l+uk}*O`43I>> zzzU-;co1l(A7BmH_0&UikzD=;0!7_wK5oY2*eW+?pqrBhv^N<;Pn_B-5q(_% zU^MuKHnPveayP$dz!HWq);GnPnz8A9G_o4ah;Y|1r%VQx1=Aa8xnkAYMWSvMTFH43 zS!Hc7?K-3#(Q`D6?^ReU(GzuYxx?+8sIdoF!}s$|@jno5K_B(|xt1U;u}J(erhtbZ zCX%dsw9#hx1`OZNCE>grw?z#595|k z@TD;cZjf)p9gLmO-$1yWF)m9S4D`>$TWnna0{mnic@SwZfA)|R988#cllSOSGA)IL z$-K)#l0l4H%eWqDCPQ*&_`ESlybI5Ix{r)XZzlgl4|$4{53sbAmB8JYe%b4AYA|_` zgk}@<1TqT=m2v-pH@fl@he~1}!M)L&qOF7J&7wu#)ZKU#o2e{C&%?Nfc46wl+F`s= zk|L)*c4C!*(iw7Z3l_^=XlLtVHs?!XyCK1#yP2kRWwTkA2hd9ZJuF8pUXqW_XAJo( zq!Kdv$Yw(_1r3_>{5nSOhl2D?8E3B4hUX(bUr~EtY*PPZqG6f^Gjlp9Ek%xFo|oW5 zKr03tQnh5!P0PiiwurH4xy4nmc(PQ(JmTjJ=QM?_)(|^tL zbkhg$v_gu2gFKd<}&0#u|`X!0rLS_AB816Q=4V zWCwx?oJDK7elHpm^=nIasi@tD4NQD5iW!U6+WkO`{g}>^LRM-(R`xSWF=CFp37*pC ziakx~@N_I3M7Iq8nA}&McseK*^~iV;U28;RG*Px=!Ork^u%FxNWNkGq?TER@VXb5y zUDphpD*~JiOXqu&&ttXCapnYd3%d?><2m(vuCV$59Ni%m@#LINWkY<2fUKS~UW#sE zBRMQBfv|ZNI^{7YKoqI7Req!>5cyvnq!h9fCBU70JC^+!*#WOYFJt$%x={`F&rIk~ zQaioL_p!1_Y?i$ZI+yx3Y*im#16cWry>(1E*U2~4QG1h1RjH^Xn1~8&uBU3M*qLsa zj=lcKG}rz#+}Emx1_ZDv1YtN>>?a3#)ji%Dw(ah9lxx;Cidi$OSTR11M( z(cni{sY673%~(@f=R%i08fio0AKnRz%$6_cf4-eOFOHqzKM8`3fK)@ghLb9r?CfY* zgv(_o9`j};2CSyxYNW~Yu$BzZb&r`vSPp2ubQ!{IyC@DP@ycLp)I6sguDqRqhsi++ z&6~UiakEQelSOnnjt(%S-8B5_yFgv>K(fZT8lD{TXsBvBB&&OgvKPm=JK8})4keEv0Ja7+bO{OmA#7K3V|hqIF2 zyRG!NG9sV{mp49l|YH%ToVCJQ&kg-ZHr#{}9Sy01w zBV((%36`rWjh62t5@Ffl4PQb~7U0-zqHZ|^`eQQ@O_Y=rZzjOz z@JK*NUI0Xef>bsp0c2Y4o)>-O0u&Rh>e0w@7?eXCCE0zxQ|ckt@C|cSz=bDh;&#Fdm{2Ae z39JlcC71v**p4}ZAReReIjG`94^bF$6`@@`h?F$z*S|A58Zpn70s}Xg_s(5Re%B8W zE$(CahAS-|P_N&_YsT{o?%KT49fl0WiZEmVtGjV$aUTc3;dvPycES|jG4rRZXE!<(9l6vKDDH9Csff@f8Ey>k4kZ2wAcss)jvZY_yy;A5j} zrK3d-yF9}Y8HXWYti>M9)%wLkU9|ebL$v`6>I+A72$8b#br-qH!Jn)WB6=T&V(Ggi z)9)hFhu`1NK1K#ebcTP90J|=|$*1_1(|~BN=RuUIxVbK`ha(5IH^Pu2ZQQk$g>8Hg zcgOHIBxpXfCBzEg#ul#hp&b#9i>mo2POy(Njt#EFVJ>sjjRtJbz{weU*n7{mY8>tX z+l{3`7O*50lM~$li`tWfsRFg(Q^pkNWPuxH)4Gc-P1J07KjV|l3kKsxN^{n=2_@%5 z7ru|bp@|IRRFbh#ON#3MH-kBlRZ1r7UKNQ5briDVAEF~uWZpdFxcDxF&cFH>>E zEP*J3Kvd|RzbQh~E|X;=S#hbU%HQ^MzWy_xU-yL^7Jcg*le+5xK618*Wbh#jA#3T2?j*NR^ zEK$3V(yn{E9V-q>UDaTy7uOxf@X=VX$)#9LQNIIFl=mfmal~xSaUm)7G&-3u>@0O$ zQ=>~1(dh05!mLdxIa+oj3EQ*D^@1fYJNVJ{)^C1AhgeNH9_KrA;F-@aI~YfN`%R0W6W$12&4; zK76hl`NQv|7Z{loC&V+>Q{spRi(Q`SNSMX#2e43RS@7V}#K1(mzTjz6C8$lw`#!5- z_EN2?Qnicbm}f2q6Zsc^;R{AxDu%U7L4}~md4CpEunhpa=YPCh(_h1U*ni^pL0lPJ zbK%my7{6yMz#RXlHN6tg)p-8WVoi51)bxMB^TtL^eaR3vkWBRfnq?S39nixNgDq4eRR0@1scn zu_kq0-K^=n&h6k<4NZU8y3T0V^iw~DJqie~!ZjOLJ+8}_YI+f_<%qu?*9u%W<9Y*e zlYrYk(D69%`XSQr`d_Rsf_{NUfKLYNM&Z;(A6c-fNY3NDl3!J1uN^{459dtW)*PRZ zK9=&(a5V1A{3L)Tl@USQIhkR65?h~t!giX$kpZ;o(fW)}W>GGJYB2rN6oLPo=ONI& zTw*Wrx!9QO-AFeMSNN>DR<7__f*&!DW-yz(KODiCHv8eqf=WYn?so74M6knf7)9dy z`%or4R#=jpTW&&S<2NR-5wP39zIUhrIBh4fbe*Hh~bKz-Hiq1;)f> zg9g6kAqhw*+UuFG(Z zqJkd4ujbDEIow4~SMJR{&OP2eLCu$Qn%onu*sD&_485l|v5I<}Cs__6C=Y%b1+-R; zWtN?7EOHz2I6dPgkJvm5>5Qn}TkkW@F*;mgnM*8mr)#HYJoB-x2k6J(Sp6gL#>}}7 zTMs!K1F1%}1f?IFQF5lKQcg0={sT3C`ABG`AGRh}&bWY9>Sk3vWGqgT$ic&LjgTCo zAQ!j%_9&^6MkPhV0lS zfqY$d%#uZ}#|6iHSX4m8g0%xRL0v5wl?@TA%9eP<^)B%xoc!Q+9?7g)sHNvm$KdSJ z9M1k`2&3dd33yNf9)NmD5W=xO=QTzDN5y7xMpSVXgCD6{qgW?l9)8lI(3|=#qoGzp zX6y``LN06VDBXrrmpp0#8WQM3^FX0I6;;4KSF^ogtA^9_rb7)ip`{0)SBrB^2J_%8 zR*R=H9@Xs$e(-gsH3MIkn}_DAPxJOyCFYP+td3JlCs@&93*9}6=X#Zf#a_TEfbjwS z1p#ZxR+zhgnwp_70cfhCQ30~2%H=O|xJQGhSmbU$TsWL9C)4kS0aL%ZW2iI@+ZYmw|t zW{?m(#JN$}qtdD+p22Pjc(Fa0kf_K0x`=1p5U492{x5)GZE_`r*%4rVIqF%6{KMRQ zhXW&=SrQB-5`=#Oi_$z|J!{|vRRiAS^+?7|b^&j4Idj;RFgapQ%475%qhv({_^T>n z_!3nF1qu5|vN-fEcPNREhmuqj()Y9JIr{#S`6xS}4+k0K;Jv~og+op-Cd52;7L({H z>T(=Wa<0rQiCfLg(D^)n+*}Dqn7DTbgLs}@F@{6Ny-(vc(-025wu|kkq7*%~*kZOQT`zqV(^*74o#3fY$VZM)lUMO^ z5rr-o8LAIBGM)x3O-d=9+G?)CY$C)TG4w2?7BV#k?5r|KNPu#IHVmfe5K(MR$w?#; z9_FN{LJSJ*G#htsvJ(Oa%+{vs;ZTXKAO4io&9;>t`Z|p=46#v2erKKwVbYYhqQ@Ig z(p*Cu&yT*2k3y%LH_(wh|8io}Jy$jqtC6t_$QkpwXqbD(y>>M0xG|^^^O8K~`Z3WK z=5k#!RTM`Azqvuv-@0DYooKax#PfgS`7o}j^!;%Jn8^QbEXu zQi6sugod*5K@^XMatOm$OACB~iDX0Buq}yfXf7dilj6RuNGi828~1$=kKAng4t~>h zQqm7Iwhm1#wp!G$PO-btV~f=iLd^H!aC8`wz9yccgIPm0HjQ#ggngC{K7L0r*VA_- zP%8arQcrAG65QL{jnLs@7P#pSJoavq0jJ7hT~LRFjB{nsEpKE)3P;TtbS#JhtAnWl z7K39VkbL-8hz5lvO%ZH0@4$4YMfvTF{4pb2YMj5s;G;y;y2V1w?8GNy{$H{PeTz34 zVWA7rzc?ns6DieNt!J3{uv*F>TWGg;`jJXnPhoT7>nwyCUC#I)MaqhIv3`wv<9)EU zuwh;n1dZNm{sJ;1J27waO(KI#viYMxF@+kvRe6-0yXy=LgrFImyF>edZrQqiyp^*d z0B#9NV_#1}fy`9qg{9|3s0bw!SSc+JErX;6X$yfZ92W)K4S9_8(vD@|jdidY)4<27 zjr@jnTUae4J1l5i*IQ=X$2Q8;Y{Dbo;}abZBM1*+OH?IH2^I=@2pV#ys-K6O+;de~ic8x!- zMJsDtoiE4pUguRsVWWOr4k;~<4YZ|X8I~bpN~Xp9GLQ$yWZR{h;Q^Xl=#8^vYBFWj ztvK~LAP!~{Y&Ny`Fs$rWO5gR*zG8?q>T!u7Gj3Y;<)syZ4puz-Eon2-ZWn zGe2SWFpi{~%e?z3zVBLjG5-M`;pDSOYcq~(ikg2zwW5_#Wg`>J@J*XgefVC7n;S!G zv8H5FetT$YXZ){&Vh6SnVyo+S zH9n#C(?xv^*i|Cx!%zy>qfnkDM^W~1i;md|Z1SuEr)c`eu*K;CQit^*8DCZD+eq%m zNu_sS*_^rfj6AhivW|n~%u89>i(EL#En3rJIwh?bALK|?_&|4h)VUQrS&+MQ&SYuo z7#D_MA6D~dI1Dpj>7X1d=+V#?*&$BJ$n#<|a``cpHrx}B&>Cb-;}BfDm~ z;0=vFXdPvRW(fG4DW6G;Wy}VjFmT}J9&Y^sbFlsThqC%vKfac$kQwWB6i%3a zm<0xIYLyc9S1WUhA|U4A==V=x^?+zx0(I=mG@@JjrmSwMk=Y~Qs|WbFi1SD%yg89J z=S!jYj7VGjInmgLg>qnmo{8Z2jGOFC7(Ugtt#qqFLIi-9J6}SEOr#Rur@0FD1Ec|h zTZ#yre7-vlI@*lJ<=D*!fI!KZi$>%sb^eYft7mutBoQp+BI7(KCAso^O6rgAOG3(I zf=|1A1y+&RMa1{ecNVAXiWtqF1D{ph@(!b}tz8|QD``n5Fw$UGo4g!#z%R30zE+EO zbtZ1d4%AQM2Rl$dg`e>^##``%?WYSm#Ugne)~Qe&bK;jnhs1pwhVBQL4&!E5`?8_A zr#N^rZzAhiiIWm4u?yq~oiHSWI~&2ZT$+kEWtDGZ-Mzs5^f6zjsKyx*MYV{CW9N^= zwPJ7T&GoZ#Z1aH;Ve?`1D3WbBe49F;5p_RJ?hi*ZXamRQg?#b6kTbSKi5w|KL12IjbV&I?OSqT$%@g zxZKJimG4t8BNt}ZWmh2xR$S+cITm81_~!bnLUKJ|elgz{@*s~;up}PV(!mBDa{L9h z8VL;0>qAEr;B`MD0glZ4N*Xd~7nj0S4=-$S*sRAByDbkVYFCqioRak>ah$Y}VXaN%u?W_uT1Mo&k|gjZVk66yQ-5fU9_!tSF9wh}%myNjCT_!c^GYpt)yaTv z&I9FG+FGwDyw3M{W`N|O^F_7Hk$~bqI@!v}g?T``NteCK5A3&~bS5nB%XhI|w7SHn z!2J1O{@(RLMGd+EUXYkEyxO+!)$x>B7&CGOg3%7b_P;t{r0@d`=9P|fE}ay-P| z>2iFhskHvUhs!TV7bP7gs+6aswU+ae#82Ju3^n6$2DhA0SZ&~S*~7>-py$LD zD)X62MS!Fis?bn`%QZ(h^=m6!-MMD>E23J9+G4rTAl#bn3n#Xtn{z`LIO3?4+U5}^ zv=%J0O?8TSMVT+*3=@wQYhnM@cnp7YO|>eI=5-Q?%5ERUv4yXR!6HLG$R5O_#sBkU zP3vuml_dHsLX)&*)F+>m7PcEgVZC7<6YD#^{S-%Yuvfe(>F}|Z9ZP&>Pl!38{OP+B zuM9s|G#3HJsl~@|hYJ7_L zC{_cZaH}B$%tKi6!J9YV^pgYmJ9&TKWtrR{@w011Wr19A8@?fI^sf?=c6#D4YtwRhs<)w#~-kE7VH z0^d%iu?wgFF2fVLeXhsJM0~JHe#@u25+vHgr^ZSo+QBEeN;%rxyM-fu^Kk?vo}OiF zVVg0wuuJRR@}PX~m-lbV`w!&(d-A?j-noEbsHYouNAH#m`03qp2k!iuoMc_%4epQD z?EO`l^*-WD1TY?HGH=5ZB&UpIdGHaS!0aVD4&n{_aD<2(x&?Xh@wuqP4&VQa?~9me zw8D)1W|qRe$y|$&sChHPBPBS$iw|{`VRJbjXspWeB3;d9JB#a46p>PVoGwo)N)&yH zPNu-wpuhm1O8Q@t4zZCQE+sKG{b~|Kk>5qUFn(z=*W(F&4ZIc<&vWH6V~hM2i+oSm zT!K_o#{==-N6hCif>7i)nLopG)O>;=Bz!9$Ncea7K*FD5NhJJnJfI(%m3W$ah46t5 zQizW|SQIzm2^tHZmSCxsC;kiU`YVnSe3OC?GaTPDL`kT>5=Fq3ncKpG-ko#Eh z6q-6TZ<|=CMk5Q6d@95qFlbFPTC}!h7KW8lXl;W#skKc^VEK}f5-qMWLKg+&y|n}? z`z6|XFB7-D-sG1Mm#%mB&U1@;a6ML$UUUkL=-&CKh}&Howo`I&G=@8q;uE$5da?Gd zl|z?4fB_I3My>>R3sg_8E9HTh7-R=BjXqM2tgl z;m*`zjgHxeq#}y*Gd+fDDh?eIi*Qt5IgUy=&BeExau$Dn7^H>G*GTdreqqa~In9k+ zqGqb3^L;Y)R8jBC*6<8zq(Yfuk*6v##D(5?S+`O05uyVBC?riN&n-3IRr z&Zk92;6dvD1CL7IWl~8z1nwQZ8UCaxy`+c&NZ)g0b%&vTyTP?ci)qe7+W!b z0}wc0X#Ro%FMBGn|LXJJ9zLJ%a5{y}@AK(4c$PtoYmqnr<^;~$KVxq%)V**$3gVYw zuLP1}v>QcQkPOdJM9#UQqQol)UOeyD>4mPVUK|lG;P9(+f8G6@LuQ6+`TS8}5!%1z z6qJqGgtz5!a4<$)TS3{w7KJ#DRtXX)T&Q)RP>Y6iExyX@N$F3bx&po1$7jS6k?ur4P)b$_Y zS)LU3UGSWTF49})?fEkD(`0t_g8Eyryw#M4RdW{5Ck_DOdGE~F!z1q!m0L9|&fXJ0 z3z!7Oi#QeUS3p)gM?UPf&&7l5ULhHJYYk5r_2b)0`|+!T8*dRr{7KMFvs`$-YNd=AA@VDP&A*z77uw$8aN6_p%5f*!6#=ziK`!jb)i<5AybJx#MM>T@WkT;~Rz!8u1 zK*e9rS;e$#+&G#>`af?8;HX#lJ$+BWqw5yq!MLo8S`HeDC0~E*R zpEf3c9kn5|4a?vrz(hbkFDXQQyDE0V>uD{d=GjwNQJwq54PQwUzI0n8u5xEwz3_tN zut$ExMQ}>JD8hF?CyR-~k=Ta*&zKk=k5ldbCcg=*IH~TcJoynulp>dITSclvR3yKv z0YNz8R<3{6?T1>9C1qc{|O)v-m zpGT_s!>#CGf>=&A8mR)6$hLuU6p@Fl>cd_? zSqI|cr$Zj0iapl`9(-LGjmlZhrwW zcEQ#_Fi(#h|IIF>YEus6M-OF(3f2_rwZ2_iMrSCAP_CAuYS%+Ey3I@mD@ zE)3zvJ99-~eaFY`B6waEqQE@mK(!fHH|BJig84HS=Fhyzdy!v$VJChO&NPFS2~!nc zXamy_e(JJJwVMb1;Zp{X7f*Pr1Lx~ub_gH3+l?)xyAOwU-xd+43w(MMRw535H0Hbb zIi7>1&nL3(-G^{qMPHL3;|C{`@&l+7gOP}9;sG~izxWSF@PUGl4e9{L8Y%a@q zs_inIsO%*`EfaR*OF)hIVo>Q@I5~3n(cOQ}EWXT*Erm@`#BKxWq-&icbOT@KK>;{C z&{_II$L>RfkMll30*c7ER%20@TaMu==4tX zZbWtP31ekDD|{=+vinu|Iq*9Y=<0UDz_E(SrOHb10i-abISW4uo-<)Aka-3VSm(!g zv6)6Lc12aDMIUWhlz)ZzAyE|z`rgmX`~{x0(zi06$3*NgJ@ih@+nOo+hYb9yQS)7V z*|5nMdJ!{Z)tfxje&#C*FM7@!-`<{&NXBpRK+K`+KWj4;9@#sg3;*j9l3y|C$=yTb@7=JIGG1U zCTEMz-B!%(5a!Av%P|$$(Jlr#gvvt`#`Ug6s|8 zFu088Y96wWwQbPh@ar%W8Xce%?UPVcIpOc39N7Li2oUAq1KiJlgf-wszi>NnyAjtW zTq|)c$Mp?dzr^)AF3o`j%Ht*!{Ee42Q$X*npChe5M|oHs`2+lrLPgA=B7xLUto#!B zW+09LoK61!4f)A7@?n$}#kBxeJFdHNeG`{9&QVn499Qt?qWriM2feWiQ9&{6>bWrH zB@^9YbGuLSf~;}L6>nKb;9k^#WMs|^kTR!Za9sOV;^0K@#=F2xlKlpfa#1LLNF-zi z9^w1IZg?Fu$Q5dhVVbrXVU%u!*(-YCL+Nt=z=74IFmkLq~wf(@EYh@ISOf|*# z){D6}U^zhJ0M!Nf!NPf2o2oKNk}Ip_MT#vRL#!{UVh1xBdq}kP2_pgN0yNuUQAHm{RSMb&6R5kT?cxUS4nr7uN2%pfM;f z_unt&WgUJ{L!7sV;@~Hbizyaey{KprsflJ>Shsxwq0qhxp@0*TVic+AT1>e(S=#ak zkal`5?Wzw-yZYad_JUm6eaEM*%L(SDuOls{s|%Ml_PkZcc({9n98IPm=k! zo+Q8Qf5Z?QY&k1@ZbSSMG6!;?cRda9rFO?>#B-hFWVBZF!2AByA`F8Xs2r@#+YUq% z>(P-9DpHTmeE(NU`L?^hEO?C4EtOs*aOtt;r$fE{TLLKry%Hsf< z$yj+jRpBnXIn)UGeO&+XI@}$SK6dR&9$DfT!c=oTasKZV=2!Aqb+Y_9{c~xd{<*dQ zf;fq6od}&meDd`*tpHj-#}!$}E{PAd@yYea$Du#sOa2G5L+Xc3TU320?fwD!A&i7p zA3(DQ`r%8cL-6_o>m#btDE$B{j`#!6poBCQf4e>*uX%f5nw?*oAeOumS9t{T7%=(% zU?J!uXcHEzZTyb6CvUc)Q|Qi>M6O0pJSe;3 z9FfE?Qw>}4%v&pIZ@r8pP#rt)bF%W;m0LJ#4}$&Nvpr~8Uq{r8r??m;1l@@KVOD3fhfS`--ka_1ChfK~+q zn5?71(4Nv^&5F~o7Y|3rD}y#3f_&)se$w0xN6Qh5C5!sH-*(Z!C`g6l9vASlcFVGk zP2T|Gb{QBYpl}uotNI}gJF}*7+|AhoL}7k%oT8gjmmgb`q5}S&PyQAIEcmP2&@Dz* z@%@|vM*aXs0#(KcsC^5U0|~UEA_qnkC-`&ZcnF-N{;5bD{0Qv_e@@AM#)8Odm4v~F z04dUb$QF^SGBhU{3ZxB>wU7fftpF5E;T$cb*D4=H=k>+wFjh&7EII%xVg0b^6BKCY zKOX;w3W2a<#^65&i5xfJ59DN+9-;l>O@0fx5=VU4?s?=aZ|WO(LvfZJLpePkA;%cP zKY)OU#+s<}IXa4SgCpCbWQ$T?1;Eg~rt5vAb`DBsaW1KC%E+WaRRT=rO-%YCj}p#9 zmAbDSCU8!^$ub{~)%up2T%>%Btst9U;CEg>-KtV6et!%_!u|oGAH?tD^~a1tASDvW zR-iU0&GQ@*WBB_JQqe{XCXS%VZopffzu%;t$kB(^UxpjlTsZuUfg6PbOMXahjDg89 zLH|WEV^{c}N_?Rz1#mDJy>^_GK*>Kcm*6BPE&l-(pm*c95z4{Ql5feu(JcJPl(5NA z;XujX^#;ne9S6>53+%cZki^|z3J7p|bR#EQHcYQ77abm1ZR@uIjFem9+UoBhph5;f z2lszM=5#QWrMdfO%77vjAVH}tm)Tihm-V?MS)3&RfB%3BhdJrb;rctSalm3Kt_yH! z6DBw&6it}mR2~%9xbe0tC9gZ!Y;yYQBeyQ3zIq>dp|4E*fF2CEt=>-7$Hyfq#|2-U z4-SxOrnNhW-@=nXRq!GJ?!@)4xE{mxYh0QeHWt>tOV&Obsa5$dS^3#q-P`G9)muI7-4H7>5`K>7K;~<>cH?>*R}sKW z!F4V!j9VQXrmAm;;Nv0V>_Mxl_ZH8`4SvSZfMJ6xKItSP02)se zpOb}?#9v~|%1PqO?RcvN&5-Zx!Y;*A*1={ayD%*7;euzf9M?Z^ zeFR~jz=gJeKgR^N2m6nVVU-r>vzWA3o5$#>pB|%nCZl>Wp4Bi4hFYN;rR#ggC9!*e zDx{L07G=s62I;+BpVcHV^uq~mP4esVo$|DOS;LCc3_Rcu5EuQO1w4!3o`dP)BjTbV|4esxBX>Y#&v(B#P2^j2ZuEsczNX1 z;6TOR$^q{^gJLi>urxj;UG3;Tyf3a-K6vwZf{T|ZSb*_v_u)6=6CZtG&W>ExJJ@*LX0|)(& z;FKmLr!tV!pWRn1^QJUJ9us;+Y<%Oe2~I-p0(Bkzw9C}dKVuTIobGl01ry^A`bz^H zavDG#A!Oy8kjp8aDILOjHMemYPCq8%fh)Ea-_1EKr~u68@Cc$n?g%0*=pMOFyj1$j z#9`;LdAbVn!0pvxlq;o}7;=t$Li_^L=7(Iz=2=yc2Snx0GQwDG!~v>eF>$2yDBD>2 zv~2-+D6ee2UBiiM)_yZXzak9?6(9@ofeW5gX~c$3?JapuONOuM6$pJnvHN}9@cT(lr@=>M_zF5ppB zSL63gW)cPnoIwHvMGX=aMO&1r-~a{)SGfd`Aj(CnuSL|iROb+}2@XzDGIKJDZ?(0p zR;{+xx3;y`D&CL~uHprxA{E=>rJ6Ws@k%0*`F?Bfb7s!urnc|<|Nh_ee3NHopR>=t ztiATyYp;D-d((<#a)QOTZBQMKH0op=R9==^n=Xw}a|>RYGud~;;&<{p@TXCChaECq z2BW4%g%m!GHu$2OeaSJxt>Y!VG}h(_&8^V}e{{3Hc6(50Z+J!|w8-qiX+NcrD$m&P zHzv)RFfoLgvr#jdx{<1Pvuv7J&h0u|a?)N(O;Lg)!}4pZALeWxVA}6lp9LNP8i7Ih zmD%4`@P02~2?x61Y@Rm|<~^XmW!eEQEB+O5;<& zFUHn{u$<^gw_QRC18Bq;lJl|UsPMo@%RsXS-ewbhupaYsO`}#K3QCBj*2-MUAB;j`J!fQ_+J+NZPIQCKvOnV*`9yEHuir#$a!3Xo*bVe-4#CnK= zUoehyBr_R(-S+T1MzO+2#ZM?c^59Hr65;cu?V+b?54tz|imhRs44LWL|E1QzWNjgM zc{t*Po~Ywi;pK~zW~nYsiIiqm({aMfB4@YrkkvSh>fcGPrZj-2L&69mWW^e!O*=V3 z1rs6Lv{MD6seIoK=4vXd@oIXI091^ercyJDc%mQ(@_YmNpWuwx03YSqYMtGnCy76( z->Ffr#!)!;!(Wg|3nHUh%oFWKJxL+_At_53m*Cl>!YJ)UH|!VeFlmWnRLkK_x?hln zE!tz#gS2jRD5Lr#g1dAm8%fDokbGSuxlZVd_Or)PL;v?!hwDuLRo0R2dA5k9d(@=6 zt=EXKQu?OaV03XqmOdOAJJ!CzMyt(Cn{}u*Z`Ug3=z{RcqmMx~aOolo~hZTP@9jbSS~zW^pui-0UYT?|5F-NS|KwZwj11J z=|$y)E7vgLa=Ql|CW_bD@-3ryona3X43PriK7!gXJ!UX!D(G09mXjGvWib(mhhK*q zDUZ9_B@BJ9EbVFmymsJ|p5Q#-dq4ts5O@sm$U-|yX&tP$`-P0Gd9mP8C$#JuW5!esp&^xiF3eBCTMDyK z7iP2+W>)gs!UR8)%1oZA%Kj7y~&q|~MKxY4MaYllhq6U-y4v7^XY z*^$|_ln{_b&gC35yPTt%wurP-``g4D(eP{%C)9jVbOT2b-x!D7EkwJ4~9fIr#vuEasjfeA>@p?j@8d!$-2omeo%r zt{h9OmO}My-Q`%c?UmfrPSBwug){7@#PDJA5uUN*%elqGCqZY1VS&tP-$Jw9415U0 zfH$7@1P?ujN?lsTc)|GIzZfuZAJ28b=I&;w#s9+e9cTabvC}bn{o&f zURbXrLkZ6R=J;y3G?af;qwIWqRq?Wv;Wk}{Fpda=U$zkjk3u__8dh1;Mi87v3$Po} zNvaWDiid)vB>b^o=bYGFxlRWsWC-_$&uz|DSaZkk^L7MP>rp?HctKEEuFl&Hc1Fr!m5Pk=) z#1+u(Mzw+_; zV>?-YINHK!ey1M2+GY(%qL-dJ#KC?6;vvG}U9(OVJduW$2OIR3h{VZRRG-?6}W`Uea1xv?WmS8na*zyNM$s zG$};7uQFa=|6fWG8SX|hz<0bM;;F2;*9Wj?czIZ z@g7Mu{fu=75f(@inZ-bIAW9Gx>~GRHRYl9ruP zu|Da!LS9r#Hl@PfiHsCQHwy(KmXIJjI~-@nsGV@KA#>vW-}Ty42kQlG*Pk{Vi8h~LtSO);kq+p<^NMZnz!64~rGvT4@*DT5 zy^gXM2Nt3BCUG?A+-1EQ8(jV})t{cJmDSaF|9I)q)1$URZX)rKsI^5eNDhf0j@0rb zmLcXg9wz(j0kZg>#cgJ3UvizfL|uBLCngh}9MB1Dn**5J)mA0#t z8_*(-G1erNV2;<8X)=#?$h>4-u_U4{2vIewOFqP%&57x3RC8S?Gjkd30zCR<1;C?E zCWON+jd!!Cn69;#WVNsJ`S)-y2=I(-9&UP;e{FQJ@svfrV|e3fx|@I2R#~L%d}^Lk zsJ8f2a>?u3=xrlZT0WIlvb>`OA#}KOFDnW8bwa1MQSRahe)%X!C41>Gx#~?V5^dx& zJUPf}VYxE95gc!jZBYK zVbsX&aFjf3+Pf zjeNL7Bi=NRAkx^ESete8jDFF#&H9RbhAE3k*BwN<9%qHe#rm?*mTu#VzG1oMSR%?n z#+u*BWbvXydu^FOWOeV(+CR~$uiwVFayxSUIZyCXpqTd%@C*EE_oaL;4_I_%QPkBf`vYK?405gH*z^OVsODF893DN`kZ+G3J^TQVy5H>4&DX;hU?%Z*#CZ|;6p%Co*QGqu zZ)N&Td7|&+m#ZeL=&-1jfI9Pm!xuQhK(B{j!YT_hFq=I(I1p{=W~iI}=s$M8NdJKv zQ!-m_L)nqEdkPsC6)IIiZ!0bdZ4IB*PPgkDz zlAZs%BYZjS>fadQtKnVtT$!z9I4h{7x*S7s5U?GspjO)ANv8b%?G@B;|EA@(d_s;4 z5;@}B)TQQXGO9*@zO@l6R?32ro(0|mc0u|Y+QqS8cjp)g$Q+Y^-p|58CJx#nNMCHWC?i z-^L?LRbY3rJs}+Km*$Qo>k8b=vF?Cwm5$mcqbOwfgRt#ifj%!Ye}j7vSD+&~D&kbu zUcSrsTY%pKdw{C|iL-Bs|0~FV`mv@_9Z8ZtpQ-xq#kZCeLM+fJKA?rO0fc z_VeNwuw#uKM!hP&E6nilpA|FQfg=-XtEBL*5&li8LX-xen%H9bo*vkn<89)}BpUl# z_?8~an`3NUr3cF^o5NFO@>y6y?#a>jd+F_Q_@$?dmGLjSgNQiSQiP0li(|tXw+LlJ zAL^}B|Ip!xE*e_w3}>K%2Hme>w+vFYsj?+D;1G8mH+D#)O-82L`Ddha=1KQ=+9ZX^Fm*+o><;86I2LNG=Irk3NVKJI#c>e))=yqh1mB6n zoKmu9bb~LM$0Zv{FJoZrGQm7a#td`EYMDYUs9TBj-#8wFt)fRC~jU&iqWzagz=wt(&&VGfVY8z_6SR+fRY#Y37 zudUK==bfuBZ+A87m+-Rt&814Mm!4R{q#L%O4x6+acd63pSKDDS4ZO;3;KelXkB#a( z2oM=N*zBiYWkM`6_F^+H1>VZ5rVKu$uB0zr&>&t+D~(-bzO5b?vZBOUTq-adRYy-@ zk}{awCQU!HU?|O4$%nSfOm1ixj_Ll$!8Hr98S~pfv6&e^Jaj5@&Sx@StQq zyN&~+i^KlWCFaqx767NI0V4)jxVa`c?R$t7aCs&ZT=(OSG*6hR^*w(~_2yFmHo7&U5t zgpi2C{X?%A32BV+^8D(T!#9Lh`NKm-7n#RPOeFm0Md1Qnv&`L6_4Ggn_VD`|JTn~41p?iBbeExN_bmQatc}$TOcXa{w_tgE zmUnWbB@`ZKtlysa-p=Tevnx)b8UCnMaqsO1aO(H_du~aJlPC>rPj=G}503G8`gp2J z>;%kbIsf+tnevb$8YRVlN{XD)RXT2`4%*KN`c7HnW$B>ySaYg}`#FPk!0o`D0QF=4 zWQfd9kM#6&NB{L=TUL2tShYUQqFGZ;cd*-!zG1@e*)DPb^ zFNs|54VxFKsmKQHxtz6ZwPyWYb39+KGe>JXu*k?u%`^0uYs{g1S#F-NPNqT|R2u!` zp3&b4_h2X;v~2A5b#+++F5GoxEFI>4aDOI&Q>+=k5xh zs^zgT{3-TSb%ku|uHCCLP3**>3lQy5dJvI>Sd0$CcQ7yz7zbPipku2^mGnPdSAHM* z&&_9=SU~QnU#ImK-zz#*E|aIqH*IniR(_RKtx|)do-O)Fuw3i)%6^Xex6%#9P4bA`*kt6K+KoyElP2BYhdh3|Ag4U5^I5f zLTGDjf#2N7`o)q4tIv4!vRI#RK6FScwggVTLS3CrN+F;Gm;o#XCIYVFD1B6-d4f~6A&ae+ce_eI7RX=QtZ)0fNbw|a^Qjs?|L_Uw0xl=;*6$eAx!q^;* ztL;CDJEA@#ejz8To&$TSu}fjBhy9Ytk-Q`y#%NZLa%=ef5WT)pt!^S@gqB#9!~Xta zquK{Q#l7u1==X9t3mrC_7QT8~xbGFl`VCja@>k)ZzZ{+#cuZWemUJ;wz%4xF6 zd8AcrNNy2HD~G3-iL8*rX%L6C}#<9Ym491mM^}Rq~o%^vpuHC0t|! zDfCI;e^cI<3c-Pz0GG;ewx44nXDW# zKcAL*iqfRO%<2<*HGGU!c!lxUF>>NzAI=lzxYfc5*6vtgXpi}KefA^Ra$T1i-&g?_ zsMI+YQZnldwhH#Qg7Kqj`@^H3^6~8Ja@3^kMdzC3_5h!E6mUsb+Ye^*I@J=pO(8+Uj2J{ z_3z~L+%w*KE%K(X{%}rY$HB;R&9#e&8vo104auAhZ~7x|8P=ygc5|B>1s)%H!xsz2 zmv|%Fo2`%H10rwvHoTG3V@LcooDIpm9y{Qn+TPaCiIL|b)(bJEv)1;p0^?$VWJv~7 zU*-5Xc^Vs%{>YB~wZ}of$aDK+!{dLET7FX{wOeN>^-TRr3Xr}Cv_maM%`+%c9EUCy ztwslfVk7nQs<%AB9|6AyN}!rEzVE1u{{OO{s257s!A$w84Gn_Ht#4SL5Bov}3f5nv z?;aWUm(br=^^Pw}Mc!(T9NugCqVMN~UI?FLjSYPsF0$z4<14-Kfmg(iw~mv`ZjQ4? zLSO5p*vQZeYL`>?ffilz^8oazFX!j#cNIT}asDsj=i@ay&-eb{$Imn0!R`>a5eP!H z|DT`X=Obx;-h8ADKaYwp@P1W(mg9V#{wMTtmi=bKuq_XG!@=nOBbm(;i9y5Tle{9$ zQS^Gd=V_Ap@%~($Fo;n1 zlTs-PR^&sy{G^)msw^b|?1rJ@Cc)M=lvGPOvIuaNJ+Jk5nY8AzNwvlEWu&7MGQGV* zQ;}^WGH=`_B`b9rl_fCBhI5*jR{~mr0{h!qp7#Ljc^A0B26;At+kkrk=exL$#zeOmiEhWa+dTN6+4>ox%-VkrWtx{4Ed~A) zr~>d*BH>H=GIfww7xv2R;DF!zW%0Xj3sV7u7^Dcps*PP)HqFUkyf-I1oGeNoI+4Tp zgEixi{y=XeqUMxEbFj@`9sHI3^Ay!))I5XOCuG|?>zo-6=v_-agrg--+123YXjRjS zebY5fTDr2uTiGZ(No!MRo%9VdU1_@Vb$>ic+FzShuMcvPlN|Htb6u^Y{SFvu9miN| zqfOQVnY0dRhGM!b)3k~I^d}bQIE~^c>C-8#I*B026tG?5dYPlq4Py}vV=2^?)t!pu zEH&R-M?$(0*mlV>#alU5HwD`e`3%@k43RI3&-7JqH~Wh{av$uG=f)@HQoni1Ect9O zqorv(XlCaLY(N}IMtMyk0n<(aO5thSaq7K{akA7JkS@D$MPefC`dX9Du=68s(j zPUYDR&+`3d;CA34!2Qi>TjDBRUtixyWjjaCQ_~{n-7;H_c(8@zQkE=)u=YZ=4Bn(o zh7YPXc_9wmw>@6&jU(~nHw|~r^pLYc{2T4VM`{Yx;UlKZ?$~p{Hp>~+DRNjyKZ6H8!j(1B%#USJXPuonfp__S z1n5Vc(|}ib{x#5@=d5^b*4Z7N$>JBITIOVRO`Q-Kd%Y>goXJh)!7{LxLm8Bzjz+qA zgRqpDmP|)Gl4;=Qb~_yymTNT9R8lk!pQ)2i>kckH+}~nHJSu!VTR+U+Du(%@edR)j zr0wC5)-I6JXJmSbyAI}uuMx&)vc}E$BQuQuT_?lB%B5s@<7JZJ$Ki9@py-M*#)+X0 zKOV5EuS8RLer#_4N_e^{BJI^4`-7#NpW)V!y3n#7W2rCA{KlF(yTz7$rdsT2IA5d1 zwmk_TXT&}c%-^9`(u5f7G+NZD!FB^3NR}DduUh2bY^3x)e7bgx)Ya{f>bg~mC391R z+7&y9AL3Fs+7bfX=q0YSY7M>xDB{%Y#SK6A!S=kbpGeaWAzXvyE(xr zgD!Kz0_%*Yl%5oHpGcjgRT4MT%dkKuHqbkann#5;j%v;(ZCf?hMaqta9BQlc-}6Az6jto%P<~5$zp~5z=QJO|Nyo)YNT;Y+;eLiKc{>SVqz-WVDzY^J{M_ox}H|fir>SK#2G=fsaV@T3`(DH1EjyPHm;95%1f; zm4L+Cl8GbRb22}d&43&4Ke+O3;duk#;QeK`(jt=UPv9Q zA<}DPtcF$L3w8V2E+*6Y$&DGlRj7qW>CYVuNM)JS9!fc~AWHx^IIKMh{O+M;J`QXG zb^*Tx+scACV z)$}IoNmyHfb4JeMiB@+nl*-UmJpEPoXFOCdvJZ=ibk|mKksy7cMtWpBq`U4x{V;cU6qRJvY70h>Fv+Ijs} zSh&j(ezQ6VP>u<$D3tQm>GFkfL?N#G3u2GN^k{#b!#-+|vtE5tTk79Z-O6v3haT-a zal)tTdZ|ZFj0>9_^M&LPsxSiTQOWI2ae*<6vcLGa+ zHtj}j*``+8+CS&n_RmXM8D`LTsj;5Z8nJ_pwzq?3Q$`L!#;PC~L`T~hL{G7U9Am8a zM4P9FyGNTlH;zXBLAH#2bbiJ@dbXGAG*1vS>2+I_nRNdW){w+d`fV7nb3^GYef=wr z?`l7AH7R4wS+K0I-EBvdEU3i!>axJ7{!ExibfWN0n$60b=Fga}OsNA^vat;Aku8ty zMo%4#?HtKq$5C=%w=#{i2c;F)2*Nux!VkAYxGOmjW(GhhaJxXLX&OjrjiqjZwCQ%( z)yY_u8c2^?v?`+|gKKPOCt69OnhI(C11jjL&^}HHlo9ntDM7O?!2ukVfaqm<7dAQK zvqas#!~B6JT*gNRk86v*UyASTZ&XX@d?tL#U@aQX^z&?xDe>Y-+bHA3HMkI>5`AqcT@EeKuR0YWlt=p3P2 z1)-xfA|V@xH+k(0hqthTaEQ_@X41_VIv*?Xn|rK!itWEfjlo;;VNQbGnB%0lHl3m# zP-{Yem^?}m`j$+Z+|YbPY^aZj4fPR{{!luuBRy6<5Wzpt9MFUfE_dq2K;n;{xFZP-w`CDfHp5q7#qfUlw(TxmjbO1&~vYjou z(Vwi7{)wz-&!01|akOeQ^ryzn_wgNy6sptTTxGr!|IV4~XH6M8is2!~(xPZeUH)0u z}5gYVG6#e#IJZe@)g1pYO_C^xdYHnSUFGjXP9Q<|8sG?-(wN zKeS2^PAMSx(=r%#;h$5vQYkU+u)fOwXcx|(+@pg}%lec?BRoTw|B=YKW6j@67(QV+ z6igdIyS*S6>TX7B>(tzN?c+J#;Dx|);7pGv6l1ckl{Am6s)eu}#TP&l-)cXs3L4l6kHcjA17v!c}a zCwqQJ**nP&aRj_xZ)mf=Hd?K(VG5O&o%XqHcBk?*mb*%BYUAj&w(0WH9*P$WaFh^H z16VPSzLWi*(M`5_v>t#f!|7g)H@Uv(&Zx5yb-G78&&gajg!Ojjck0aRvNLZS=Nb(w zrm`nKPibR29o=#y+j=_3-nyS!y4v78XPXp8FJQ7o#9lHC&J zNXqa4UA#?-`(@vavZS_$Y;CNn398J#i&-;C5AikK^u)zUiv6YC5!7v4tus*-tgWjx zsv~51rR#-5Fu5w{3>eM%YV`>+CIC`@E{N z+t*2*xrpjl1e&cw1se-;BA&VHC zah}NER#T9Wlg-7hTHAXki&OxV%7mYEphF?e#3ep935ZyeM(f#<}fnuk%Uw9rD->v;Zm(k62uHYk3sfQo=O zSP4u9w)1{J@E|~c+@lbi*lN;L|uCQ?c0uFwri|4n4oH*4nAOjd%n}a+x9kRJ2@!3yyYTLcal82 zeK+8!$myY-7X9g!SS9%p8SH*$XSeEFgL7s#zWuk1nC@3$NUJ=kQcN`3cne=D`)!S{ zv?R5p=o+gsH}eW@_*P=P+r|~Y_4uv8Ee6g6YJfD$KzO%3w}h9l?rq`DzAN{p@a*{r z8TT_ZK)Zo*U932N_ScLI!o<6qEg<*zRswPpPPQECYK5l56=&JMt}Cyj73UvQ&FL8m zyNmg0TfcTI&f{E27wQ>_LPH_k+798aC3pOKLDXynhA%}7X0 zCF5)xZ_&~9+=4xAp)SIMc~a|pd4n$l?*M-U^?Pua0+;Yio9xu4dmi7f2BN@EfvLbi zpaPJ1>0c*n&Hrk9-nK8pEgZt;%wIJJ74i4ue06Sd&0iVSd1)^Bx^r0Vxy4Ax+IX6) z)Et)KLj3rOE2U8n@1u||z{y6sD~<_I)beOSlk7aOxn)tu+;T(5+@f}{xaO}EpE(xa z!Ya1C_uFtZt5(4RU<=Pb0-ol%BUvqzy<*=T<@-;8KLFc+3gCR;mw@IcVF>;EGW+iL zAtJL!g$NI2->n<5Ol~MMZ&rCX+MBK(`HN~TLq+Sy@LTRYSQ|b{sC)ZD92p*uglsa4 z{-NofMXwy}UI;2^vk=q}9++gufwOXfa?+KRHWu2p4rq4~r#ibJ`huPssHrYuyiN{cYu4ITWq)|lfY-nKO>PdPtwXVzwGs+to@zX z0$Lwr=&LMlU0WUI?6nKPNV6}NpfIn$K)1NQ(#QFdvdvKMnd3L6WHt~ z;Ci46=tlVu;ywY0e^>V9F8W(+*B$Zx1K#=Jyy7FiE!JLHV9rP6XIAGr+iF<;ip@)b z3gk)6-u_CS7-NUV++g!*=S%no z?fV-sE&tWTDH)k_;qc9Y~}%%0V@H~d-)>2F73}buUuI_4Wd&jX6k)wj#_z$ zQQE}h9N8QkpDgPfGVLadxrS)x~bc6YCbb+2IC!C zSX@-q4Rf9?6Z5@N1ae|AQfJ0%@{XF%%%ieGsc#Z=atVP26(We!B#LC`!F9@QqMS{X z=n*b})>%lhv58_!K4?AId3-b=tjUAS8H%a(pr$+t&(6AhqvqSvq!`1G_$;)y>f0)2 zRbWDNb5Libg1^du-JLwTYHUXPfPx4rti|JrGd0(tb%nb*%N&b43yw~g} z-$s1q%6PHP*r<7$q@`>|LZoDTVm@o#)zY3rRsQfaU5OKn_1&V)MP?{I*(WSTy#|c+ zJ)$i|;h{VqrIw_`-!~`8*U}!6Pkn zqiUgv>vu*|+DiS$cOIiyyAG%R4S&yGk@b4BNP? zIogA}e#kW|59OP!;Vv98by? zht4eKrN7k|45>L9U7a0m?)AN>8j0RyUNK90fP=@X9^iGHc(-`}$&=3AX&8r=7s66Gm}5(L?mOWd(^>a3a|MYVWG%M_WPVCtv-fLhn6goeHF4AG#;M;;Zr)# zWS*Ugt+LuFCLdY*yW_pVJAk_Yd9DY30XQXc>7N{Llr`S!%$_dK-o}UOK)p@!+IuB> zVQ|4_i5<`B;>vBDat} z8Jz4E{hu+YTU$ApIddRpLoK{Iis$LT<$!$qJANnO8ek@{gJ%JG-h%rN;3NCp36tix zFI!*k#GXya)t71#L#s&~Nv-ebO!kS-^rF#}Z__i8YHkI_E7FXYf1-PNd3K}G;R^5U z#>uFR&f=+XlzlHKDvONYHBZSP5sRWy4BC3>OyAh*)RX3^4u**&rbmi;6zWR*uu5B) z{03I!3; z$r)-di1hh-rixoOv1v8PA{H7X|?<;4_Dhof}ns}2-T!D}buD-yG(~&GdhT?)9HMdvPJt;?-c&mQFw3tO;uy zw8@xXdc@L`mA)|)N6o$VhwtFRf5D*5gn+7YC#Gd1D>)PO%xvOLDlR<{Y%ed!R9Kc@ z*7Aaq^lxl(VXZCNDmBKJw8QvG8lqeS-myj7G|*H0kEIObpQhQo+q1@Y)vLt>Sw7O} z)y)u&XurmAk$A&l(&$80f@$;`Lx&b^5n)(u9Jcn@lf1z*fQdj*N&$0k1vc?6bHbTl zwmsVueBTMY3mgF+1Xcq3fUJ0(tTANqi%~5%->QllLd*Y3_H4ai4K0~aBJGAcxxsFz z9a^-FP#JX0iM^bd*(Pl-v{{Y$1x3=ZPK=YJe%G_K-jV& z$h+zmoN0MmIQ)YkS$%={vnf%mWswf;HgEi?BY$V}M%tuJ4*5|f?nu9USQ+>S@Cbe@f#y?{oYp379oV$J!uR)qT;fjv4C0;uY{st?Fo3nZBkMc0 zX*-s9X91%DiT9ICoKEde+<4cx@_m8l+W-geFSBX0kFsKxtbpq)jcQr1R8_33*;aWm zXL~_6ZTTvP(yEnAPK0mMy50K9yHDG-YTL6Fe^ZIQd>l~-Cs22?jQOegl*95eLOD$< zhe>76cDz;#la4*xr{Qu@hIhbqV$SB;uPcq`)9^_7+R=DWreIY^pE>6|tL-}&zzd&z zgT1}L8sIkIUcdz0>y_CRlIzc=UzR+}*vb*{7!A%;=?4<1$h%u9C-=yUUieGvU3>xP(Y>Bv|1CjK3QxugW1 z>`j!p!i=XbftM1vu$TEh!M;ReUxbq_$hzuH*hH=|9|q=4<3zs`T#Y(8j<^FX>tu;2 zs~#mhGJL-HyJfg-EH<}MZly*b)Gz^%717REtu=n}$FW~J%IWc>&D>(`CTsMnytgmJ zfw_&kSCEaQsTur_4tuE)(39$u%i2w@i?$j4WhYK}n6Prg$i?39=;YIKx7wWY`Ewg( zDpsLyR1czz3hT@UT-9Vx#9vG0V}uF_Jt$E~NPTN)!~3+qp2NMtBH$&S?*{(NGqNe0 ztzC9*KjHfyfbGB=z&$W!40jRmDL~v#?c5~o8H8U7tOVjfInbs(DLXf3hy>Q1*}GjC z8R;=EH`Y(_c4qD-D@>TXmFO@X+q>Ce1{v#1nCSjegEuJHk-b}Fl*b&x8H({cBF|@= zyZr;^>fGGzUmX8Eu363=|D6pdOG~RgOUa4lIN2?&D{aZBJ|vt(YdaKPtz^V(w~Uyr zbcL=B-rA4-jKnXLfN%`n^!V>F7uI@z*(Qzg{p~RBQZ_giZ*t^-x;9DcGun!^{r)l; z%u)$$_m?deZ`asQk-(_FfkfM=ZHP)+O+C&j0?WMl74<^&1G)(Naa0PTw&`tYWGQW} zE0Z@X)#qE@;OW3P;Lr%hkiZ8#chv^}#P{ccw}8)qh2;H9+?BwqfNp~w+q{h?>@+~- zK|tr{%z;CwHui2ltRR%Vn=Fs%VHs9y>g;-^)8@z=Znr-v3KzMg|GBI_3wfrTt9Y^) zN3Sl%r+L4U!CQ-rCLZLUj3y3<^47-S?J9DJ3rl{R|Y zCuu&EHhOzrGQ{ZZuC&pcm>`JJo8>lo8;~)2yPxmySYgvuG{3ZkmQj5d{)&)UrB37a z%SSS#w5{Icv{R|i=XHHPjpIsBS-o}6vGd&NWt+WuLW*Nw|C;=fW%ed|anp{B*_%w7 zDy_wB%7%6#n`)GHl5O^OeY>!}%FEk@OPjq-&H9ukLU?-QT#xx^H8SIpfq zQ(Eq^(T?BSy`naF`ytX+xO(9@#f1SJnu|TU6@$0mutlX~gST5tZ?9R6RtmGelrzz8g$(y=TSFe~D zG$ngn*NMs7U=~%-3wxR{}8pAsFSoX{SD}W0|dxKX2gL(cT-+v2yi|5brvv6+*?gn1s z{R-l)1m5MjH+}<3=-L$|1*y2$f-4Qq=yEYbYo=o5F)3^1?aM8!O=%2r~@m7f{qqnzJqKVgS+@ zH`&M|LTKkiB_1Ee$reISbRix)GslD4|zApw$pbiKDJ%K9$iI@I$vKFn@Z#%YM?V4L&z28N5V~sO^ zbzrih{hx8ZI=8syuM7;6Z7%uRb6D-UrOhF|dXD>87v{FbTk#ZybpR(D>#jH^WAP?C z6YLIhVaMFEvSV(MTTkg`v-U2e?>Kc?yjiJN;OP&6TnPI(?i%2CJa;6kW#U(C-b}vN z0rvq<0#^cKfFA>zr#iQJbLMWvg@?HwMVLh2Zz|^_X4$`q!X--0%d#`@0%iYZZ_@h1 zFI3~nHh`Nd#J+tYj;tJI4B#GjO|1V98^C4j;TXW#yC(X8pPKPf()}6fGU_yX)i|QZ z9z$WJCiF7y+7Dro{|4%T7lD1i?*aGxx7fc;CHf)dpOMa)CpUH5oX0B1LaJiBO4&B&;r3kx{p%TM97D6kS(1q2|$hqzAy;@_1GoVx|M)?2O3*u(A1 z*uyo-%BL)X%8k@YcM$f-tiHOpDo*^l&05+Z?(G?1A&Ymiv_Ti#es$WYt5%=Vi+7b3 z_QIWG5J%>6l9pP$W6EH#`HYiL_&V|Y9iA7P4@^kjo%X+2{C}k87uKddCyD23JlS1Q zfy~z*YW9VXJ-_KYyk`c?(!kP#vGfS6jUgPgf11(>OaS@;tWv+_s&$zz70o;G@K%J506L=m6tqY z{Uoo;9Imf;4iV4x)^IV(X{%1zH?rE+aEs&&&!3UY6~J{sEg(8ESj+F4&+>^q+^JNuh>Jq%ce0O~c6K(;@=?wGe+sr;Sj6pBR&5=jw_bhe$|CMgJ49QH zxN7_zi#RKFC9HJmEJjhllfX3Ie*nDC^Yk)r@Hc?P`G9r(?Fg^=(&m=XDzS&7 ztv?b{%{v%h>^=82#~`jD+aPXV{O(8R2y5SUKTekhaaH3;Gx<<+Isy$Gj`MVytY z1ea@prNDmy4*-mBI<<-WJKz5yVce4_ZEWJ4zEfO8h_a8%+$TE_^SI-L)&ob5^O|yu ztZg0lZb$dZX69qWJ}#TuZe_mub~m+^ft;sYQ=4K-TiPfZCOU{exy~_=qo3Tv*L}c# z;2!{Gw;Pe|P*8qp8#$MKT<6Ffx=ka~-aziTwgz(U{omnBUG{O=sk`?I|HMvRcE4x? zx#Ia!L|^ht4CH>()uiqGTn)ciPy(30uPM1x4t}za?(D9*>xWe?Nu-lX(1kNF-GW%~S{pNJ< z6+|j zh)0DVMhgZT!hz6Vjhd?nQcJ3&SF^8nvDeIHQ>74LV3Twna~qX*unCr^IvPX<2?iwW z$zX7^N?#%ww;W4q)(&+lB!)Cr!|pfhn*%6;L93y@IhSoA1tOm4{P%Z@$JMo0c)5;@ z>?X%n)RHQ3ng#;f& zuTeA+IVbm&ZSk-Eg4*^7NjYbt$f%QTj}o4cLu)p~ZjmD&V{4@5!V}kdE@p?}n(4}` zO#Q!r|LZPM-g0YAY|TRT{}S=upu8_v9!u5#tNFim@@UUOHdjq9c^Jpq%9!b5kdvty zOjG2^)!qVS;1aNE1&i6KwSopA*zw9S9db*bwR6Pw`p*O9N>$fHkrt5~eY0Dl;5p8m zfz09?+n?JZ4NB$;p?U^bLIa->6^i_#)}S%aE5~_)s=&k&fR{%FJFzRgB%Mo z&lB2dR0~H@f5p;pu+Aw+`sEG1I44oJMp}fizFN8C*h^btsoI+}JN08B9NSfgvJi4M zd0PFM85;IlsNu#E>l#KyBlfXHs3<U- zR{!ziro{T2AA$|Y4GQfvBT{{KjcI(PS1Ooq_2z!>C1PDI`_-&&ux)W@V|WH5us&B< z)$^n^UjdFotQu9fWvSZ*N2~XUm#JVb%Iyz$u zByT?G%3FA5U2q4&-{Bs89|HEJkPI3}n^UIZnCZp-+HtZ?C$QB!d@+nT&cFN;alRE< z1b2^{9t&uBF8m?-f?O;XD4RWJ=>t!DgN@(0Nvcd`qxG-(HTz6io56O03C0nr^*djJ zN%G3(HlC((4p7RzG_=X9k2Lb7k{he_o8&gb#pqjQ8u`Xx z_@tWc;crG;Mu$&rk~QaJAJh(KiEBAz*kpnLQSuTd@Xg9=o%;41s>BldAM zcX9l45kuBrpnK8kwXxU--KbfQABmd7AYq}g ze%jQU?FRRI;@RRis^3%(T>t(T_2AQ2|0Jg5P_T4aBBP!)YSs}z1Ru#1L^t?iUTb_H z#&Md9*7fF#TFWeqPn{ZR@rQFGEk3&>H%TlJ;L{44YIF*P@!3C*hGZgniCJGrolfZ>if*w+W$PH6-!`}pv0&8k8c~%^{pr{-ti4D}g1d zc~k>Q+ye1R6a*6aH<9jXhxXD_4NZ(5pD4w-pg6y54o`z*Cw|$S`LoL#M#xT3AJXMZyhu9k&FL)C|jqJ!_xWr&*UXJRE@?}%gx43X8 zkI4Dlh+bMek|#RGa84{B0+rnJ=alg@h^N9iWrD+_WTtRnYHB(u5{wl4(6_1dB-=tK zTiL{E&z0%#!bhO6bUBF5$slS}|6XVV7Lvn8Vv!o7-%1X=xM5X~X!E$rRng{)Zd^&^ z(GpCfNbgX>^khH50m2U3IcIixif1Cne2Rty74!?G?uKW|a8Ts{9o5W>P({k%qKYD3 z7UsIB`BKyj@d`*bxU`bOl##Pdb)#BF+Yp7~2_v&$Y1;#*3A&e|%viYIwG zi4L_Eml7*~*p8)jQm1p$sfT5IrUcL1N??`G(D`NMjWUWaYZO0K_2Cl;Hqj{R6)4k~vQ*h<^+M;#KEu#P1j@G5f(Bzf5f=z=`lGS~ zcR)oynbe(rxf*1a;^-a>1u4YKI6#KT>2)i8R*@PhXRu-YN``y|y8mVYNBFP^v7xD` zQbYoxbZ|;pV+j-~Ym@^(H8HQUW|hwKeaM%S)R#+~FXlTWrS?sdR4m6yhNMX*HoWnW z%n=GJr@|*ko5zH|S=Lyr;-VFqr&{w#^&?Wr>+qhT76J~uodUy=?StF}LXJTelN*Z$dHnq}_j-|F&5$hLDtni@px0!Z|KXATD ziYIU>)8Uhi8g-oRWMRmmzJpS*GaHX1oUwi%WeYX1#OyRx3OP<1?M17OjW!RLr%`gV z=QqN=qs^zw6;Dfynqwe)?v~yc4#upFKc}FGYO&8t*oT{HKK>40}Iyc z?%CdfzV@q30`2v+?{YN3*UjLzpZTmYFe!s$^UHGrt-|Ym` z#)1|h$!QJ$2kPgEPrs~wCaVw~)sK`rt9~G1M*r3HM zU_q1Er&wk_M~mdoRq|{>(=NOmIv6#hz&=*>di2PCW6g);1vWhdn^;xr+{U{>6|(G= z?&y9#hRzCtUd8nCxn+%YToge$DP(SJ(d)^P<&B%sR|)+(4f<4TLhF>+#QmWy*XCGT z%I2ob*BehLlKG42BuR=Sa1BprccZFaH_r#Zyk*|SF_WYDjOaTDc_^Rn5F-FFbh1M_ zNOlKxLi&3fk5%avC=y=;vZJc@a_-eY`u_o*v z1`#REFn@+&wlQM6eSjjQ)f}tZS(7rV|637y;W0VE>lRvnt55nt+5B_L+}1dP{Uo~Q z3s@5akR&;BZsSKp7phYcry7rStKaXBO?=*_JNzY-e}D>g(paT(E2JFJDp+u?i|K4S zlhBy938@Oa)RoLRI+EU)`j0C z;jK@~$7qxP+WhE#pKlwRc9;LB(ifNVc`f(O9pH6sgnthKJAom);(4{**b7!W*&Cmf zL$bA#bC}zYZdHjtpH7^4_;gqm%F7~$taO9IuhOB`>M)ZCFH6Vo(HW5CfHBmXL)uw-OhW@?2`1qHt z*xJk}na>XF+`^o@Mqv% z06GtX&KxIub0IF{+M5e-89Uq@#Fg*)xY&)~jOuv{Bj}s`xc=;V(e&|rkG)4gA#fVt z&=hIgYQ{y>GI+@)YkD*D8*pR$7)i0l9?;Avi z-1zhmkLSM866{W7bmJw1`S*(={=J1@P34Z{OLFXp?V)<}v{Aj}ZPha=<&Nt032$a@ zV>1C8kC7-RkWu4fV3}lm|AK)J`7q0~+H@&fm`6gO~dCq+L!UhTR znIz*gPm(~7=t#c76Z4~0`JQkeC+&bro5{h!w<7X8kLKAH-2%lQXVL9Kz~V2P1IZt(U!`#1r)D-g`_|7F7ZkvJ2EO{`fCR=Ne)IIE$e|YcLW-v4WbZ* z8Djdvg;EcF6BAp@8t)+GNL6dzf@3x?y@@6}V#6|z^t(&Boz=rxuw|)!LlqJ36XiF2 zcH<9;K_d5wvTpWT+U$eo&qLt_N#>k#%)-VzI#P;kI2vLx(do6Ja)auY%ZWYTykhQ% zeWQ*IkjOmibkV3+mE4=pn>FS%UJ}dmmwHNI2oGqa&Q86$)DxjcR*$I_{&W}lN_0!X zgpf+6^2O9yl0fF$qKlJ^tzr3RN5W9nA#0K_KyN!K3MM&OXQR;k!;LFv#4atNe$ol` zlYY2n!+nyv>6J0CKYF5{7f{*M{n^ zlSMuMu(JHspG(oM?H1iokZjaSP4oc0J!kbwhdz#7eMh2OT8FL7um7iEy>#VvKdnAd z=Pd=Z*o=c#@2Q{Fdt)Tvh+Me_HhO z^H%tlop+ISzCUz+z?>fayy&{)o&v*&_1x}cVtS7M(C)zt*OeaWZVm;5!2^?n6Vvvq z0O`+nuG>TeLgYz^1%7KrtFT7wv?!-uy;W2xs=?hlf2d3W=rRz$&7bZ_pfr1$_OQ;2Y-k+3`?S3y& ztq|`{pVu18i7``d_Pf24@?Pu=n z)E@m^MX}TFUKUWVcFdAs^!{3@U7fB~5NLqBqf|A_L5UeBQAN*Pux z&rj`9Ua94oHmAnMitDX@(p(aL)~9l;Z7SffZHei94$MwWDPWV{IA$H_z!6KSUeZcJ zxl*PT{^&J<0@YkplOjZHj1=!a`RWX{qX!CHdCV;*m-&g&H%Z{C*2I(n(Kim#MCx1o zQ`sz7)jRrPYWD}x8O^Df`AISut>4d->4?vEH}V>r*nF=vU9RW&du&nQx`8wiD>P(A z^N=GwUov|}8wx^;TKRD8ySU~`>$T8c3Dz$wST4bm?}YZ63kY;wpXm1k@DF~3OujGi zPIBV)Qr}eg4+!78QSM~0_SWnpXt-c*<7>Pwu+9&%6f+?h9how_jo8p67ca+-Raj04 zTEXb&so1>MaDi2~R_e^ETwChkdyb{OmX{8h*F41hM5a#?Q%Za8vCL1*0oJY6gilRu zglP)$L#qm#EMui?*3=@Q2G&kx>wegCco(l*efw}zY0Le?~7PWJguc{F`vpuoW8yjmL9XeK+otuqkw1!mM zHoMvV4L&R~jpqUadTQMSdP#3nKA)+jdXv?fSQ+iDO!tIYlPS#mTpHC~lj_Lq*wRRs zZW>2#7oZjCZZPq!)hX5Ig|@~f1;eK<^Dp%j*?sYRv@_(4e91QpQY(V#Or#G-dmIp* z8A!#(##Z@LxzeubbfbZk+E|8)HXAV~b79{LTH{#LXPZOruKg3>r-o(cUAaNJxQi0i z!&M)L*eeOdN?6YbOoKd!m-*}8HGC`43+P)_A8z9!>J=@zNrv}{AA6QF6ZUz<=)~k; zbV_q7T6@5N=@YfBI9p3v58^<=+SY%jQn4xit&v7N#4}ftO-wl$dTzy5L~deMer_{7 zyv)0VV6kz5#I*d_lt65pKYIDkOFglte=dzLK50UH+mZU}4TzrFnG;N3_v`&i##%de zzjx^6!DRu9T`YQjP}VkQFf|mE^0QCu)x`1v!)8lQ&xAt#dxrH~yCyiRb!v#l6|@$P zQp3sEqE_SPC1CYg1H+eDJox^?wL-T{c#*(I<&PhhvL^XbKX4Q82b35JT85@W;*%@ISO5 zU@nYL@8(BZ)XwNDeQ7uUb%P^SebarZ5+3xWiPE*Dn#wOF>1+uQbc+ntk5((p@pihr zAexCZ&eAh!Lb2&yX@>Li6O+8L@k|Sx+1w;Eg-F{8I7Z@Jq3ELgQ%IRMdVXtS;RqUO z5RFO%9UjO!QK=Sx#tgGjqt^J%R$BeL_)q|HOtJa+-I`P4~u$f{j^nP9$yg^==b=q zle9wz*$^>Co;+smed0#Pj8<=h?h`lJFP3+&Jj5pXV`s^O#l!Ff>tQ9H#LcoC7MoO% zm{b^>nIBt4sKAK#pO9I1HXwZwH166sZOE=^6JtT-0WyhQa(<7e@-0-M`Hj^_s{t0W z&esrXzV4XFEzQJBB_^|1guST;d0D+xkWRjCZAqSNk3f)LqO+|&BDjVP*JQ7jrD}tQ z8U#C|pA`&ACCaF?E@a-(3{Zgk98*$Pqfr2erI4KDK2h^_EHt1M$6p8 zW+^JnkFE+rUv(z1C=Ba^MIO&no`dIkR-Y%Bo1?4-rA+!J1r_D(krQL7_ z!0H})E__b%g9i-r4C~;NvN>S&J1N9_=%Z_km`=!N<5-wAtZi4Ue#3KcSbePbu#JoB zoBfH>K!Bky_xg~mEOHK;60C2@Pn2$x4U+lBV|_4-8thp;QV6oO#4l`N4oKxn(W7JJ ze-Sgf!N&U;950Z$h}nv~QaAIha?#n0>br?!tqLS=E-d0<>#!}+#=`n$U;X}k-^Nf& zY+~zm=dzz|Q6RLV^5{`Z{44s+MNNK!5~zh7)0Bb05`T27or3DHRJ?1qX)S0HW0GKE zRUt}ksF@Mebt9~9p@zzVl32l97Q0#-m!*?CiL_QvY*qEMH4v(5zV>CE%Gn{sT;YCA z6QFfWy_|AA<+Z|vQm~1$v_fA5|cYDmL)hrlMGYSzSPpUR6)>ErIl7nsZtFjg`im3 z)F@PbUmF{8>HDHybR}5S~Yf@LXF>l*{PHD%L)k?=!CL#^#Cp8m3{PN>-mHYbcc6 z9)5coJ{c7$^E^!4(=gJf^=ffI65M?|PHNT9#{TzMnb7MRMhT@(J`SBSdiU|$?Qx#9 zl*WhSAHh+d6drdj#(d0P^W8?zPf0LvpJATjK1lP52_EV7_1AMPHA5t$Zl5Xj4RsYs z8Bda|K?31%_RokM-i4b#JT~e)S~+*VCb=;V2j-OMI|Y*Y^qmE1a+bXe^diVKoAqS_d`j4ImWL#IxYL9dbmny4SDx9-VM2_<% z1(f40$%(!$PrRJNOlRoi&l<*3rXpew$Qo4ja9;nXsNJnu8YKGCN>DO%tm~{cOSTN_eK)tiDi22e2c(^0MIFr|2qD1_}wU;On zf8*Lql!(7>?IlXY54Zc@^6R~S?tt*11K5`o@nQ0nt$rQFLXcP#Ov;7al*<1W7OEg= zz`1!Y^ExVw@n{9pY0WQ-^Zw)vX4u`c*I}QrY?OE9N5~u|KAq!tS((}S&SCyos!)T~ z7wOHWq7ga*l$~9O1-Do;4H)wR1^C5${jrJgo!4?0#X^hCEyM6!vbi2aamu_}EJV%& zrQCnTy-zHWbtOq7k(+QPg{O16GOT>baoz_DhD-}7!8lA{FS}H-9T^n+b?{{ZCj$_o za2LqjRZ*@>e*P|eHY95`{`euX_kZKzu>HhamT)b~hyVxND-^ z-LNsv9{uf z1cr9;%x!UZ{yLmNGB%XL}zP(~Ad!f{l_( zZw6qwCRX}uQflHbXGW1Abw))n>}I~u_| z37&QY(|+SzGCScH4@)ATcMtJe`;C-2_N98`2KKN9>^D-ZEAKZ3(!Y!dI{@1Nn*bXC z>j8Cul>qEheFyuE0ww%Z;SRt#0J9!>|BvrCF7TifalcUxE9ez$kI?Ud_Vg4f}@=hFulHt$$5&CV3l$;DXPr`}QBP|fA z5_G~SFAngK48yhwNm(!E8iF(5OKK!mC5)DC^jYU9M3(tu?K`nC?2pZafs+(b3|&Ns zX|T}#Vg0yHifG=_DWY++d&D_fGV(mo!*y0)Ck#+P&Gm_t(@~U~kLQ=f5neHbS29YQ zJ-b9f9`WR%7ChFSoWl?CV(XD9Y#|I91Z@1VDLZjutfg#(cOg!=%_hr>f<>6cK#oV% zjOZ;8cO5^*XzAUGS7G>L=OU%6+rL!_QOujl_%ez2VF+$_=j?SCXY;q``E?ZHk1aqv z5Hl{%t0heQu{o4*y3}7LX^1SCFDUWe707Z6#Yc|(NDyWLMH(UGAgK5U6YZS{KA0GT z0ffPj?T;--6tNIDw9pc`XkO~H38;L9J*@yLw+=)lHqZM@)F1?vhDaYx28MnBU*ud& zdC{i_gD6GU{Sc)JG(ia?fM2jUzTBObfa(pgdz;&l+MPxx%i;R1=u(QVZK8`6U5|;b zMA20*x>7{fgQClBq3TjbrR0(4y^jo#Vt{c9E2Ejr6+~$(RFa5yQ4nJlBDQ2nzST>q*^% zTCM~k7P(e^!~~9er=Ft;`~l?SW<3Qs0l;DK+{4I_WB1B1cel|(<*dqk=?pRxaoT^9 zRB`OkyF?rsB0cp23j1o}YZm|oncuYlC?rMBkAkYD|O3ZEL?|qSOAz#hK zb^g_vQ19F_*B5?#rYL;7gja8uIfu{m$1Vq|px{JISP$&`BEr=%-W}zkI(ekc9_d=F zB)Nw+$Qp;&V=*ALN1B$*b*| z%y|>~#;rINMam~-ymAjIPr??h7f!6-M0g*JydLQvNmALpH@qY84!(4$YbWtT$DO`7O&o2Z9N6)^F*o0P3g@rf-r1?OHVc1q zuJ^BaVGg#k8zP11uTb=SV0T~`@&{_O!@p+7I}gqC3rKjMc!L;n9A(#VQ{nuB5odrY zb>}&O2{>&q_hR3QMSz!j5LeiH$I%C2?|loM&}h(k;qShL-E%M#=8N=Xcb6h4Z%_ zh9Ry4yR+gjZ^_PcO~8>wtPZS-67MiztXb#hWeo<`L21LPs9N@BXG)`8l34rY&HU|k z$M{>KcOSd>(7xNl_U$Wp6Ap|$d z6Qg&(bI}!=Nkn5@{Y_~oMZph6DMM?&9O^ubyGP;aJ{-*DrL~LvjLQ+nU{WQ1i?~rv zaU&=mCRv{f{%xpnDDv*y7=PHoRC>`Mqd8g2&UH!?vC2;swk$brbYX@1GQ&hw3O;CYX0 zRUCtE0aR>2g*Vai5PugUjt!||q(~o;Hqjvj3vES0-)L?D06JI!sIv7DQsJ6aI{@C?G z$L79@uA@O-48zU_bM{gE2`7)%!U7(O64OW5?T34j@h0~Heq>_eB4eEM3(@#&@&UJ{ z9@!o3&dyHE&bH@eXVbkD|66V^=i}A6-ru6UZMjj^K%(2_-$KtTzsSTcjWw zPMivwk)M2tO2YEl+H>1LO?R$Lb7;>3j9eTh$yjwr5{9vrpXT9103U{Pk5N$cx_Cql z78YISMINa8h(Lkj%GBB~snqB?S~>8nn~Rx`cmxL{pdbg3;JSc+)p4j&-dUKt&YmrL z<=Z`fq$J)uhhV9AwyWE`^mZ`>at>aQ8A6sWFIN^G-d$3T9P+&kq#`sr&pNvJQeqc! z?ZMPk^vJh+{k@KoOd<3Wc=&f0qfTNRyZ01)O5_SjAW=zz5HD6ZOFgB~cdI8=<`EK< zF?I+_4X8kIr2`Nz7P@|VMrXG7|R0P5J&5+|7UL>SGbRKE|-@V(VFCoer=Z)JXPOGaUj32rdTiOg$yKE@Y?sWFm+%*_bG8Z6E=_%Kn4NeH_L)uO9C`~cP=kaYwKZU{%zFdn;(-MA-7 z%M;zc;W(2=eXfBGtWt)|@I6!UiCoXN1mw(kiW9IO)`)eRYl?7}E|IKt#@|8)f1C`7Q?~X)WL)cPonJTyiw^FoJ#0I#$ED`Kv#0pm>dx?g+vkZoc+}R^Smctt($vO;gt@(WZ9Nc%pcY@Q{PN&ba+TU0dhQcN_M&blB+u>{#zE#i1 zH7@ew-Z|UBpZ5I*8wYa=8~2|*4k6*0=7*!jeUSdqzi<)~d!!%SiVMsb-?}u-pZ&V) z?eJIKmvG$Z{L_tTe$64%H2*RwFU`p4I_lmxhYlVGn`EYi*5`5aPgWhX_AJ@&q`!3% z!N2C*II{5j1=NVr*lx=4eB7ct}3up9`0>|-<@cn?6JA*5@;&J>%ABN=9S5UyJmFo52cg$ZN_nQXMrD|=l%0JWCXFcPKoa78x=(4 zC>7b_PVKn*k$w8Oyv$b?=wWWUK`PDf+9!0X=tfBrxSJE5c%y>k1?olNN2u%U$AO(+ z3LVDlPU=CliQvf_=&ctFKaxK8=I6tFuX$GZeIq<8F8O4h6<_c`3XZCT`(&f>wVLUhQbo{k1;^F+h=p*nkGT}9M8L&l~XOtZ^B&YQ%|aw4(o0NH{iMwhs~)8h+CHEx}_B}E?kajez_TXxzXu8 z|LijjLhjKI`%u5yRi8lV*bAE{>+g-D>W+!q)zQ0?{7^=@{n3wXpjh>SLZ0aRgmym4 z5`+19w6o4XyYEBkGoHsc0x4|GxL@U`;5%k$7R&}D(YwFo4lawq&RFA*Y7s%!MEN9Q z5BBqz-aK?&AC~}3M)Q=(lX?}@z0PE`_&Y_}-xaoDF zG4-

&S)I>G6i_d{6Fq>~mqajN7+t9F9cp6{05XQQ&dE4Jmy7S@)|D*5{v@I<;}C zA4AfS!Z~Ho0MC7iw$M@gh(+7sg>3WeSStG|G(RB@t_F*tdA-3{ucAcWTTxjdPS53W zN*Ji#fq0idJy+{oO|!>CMJ{rW!dYT|jK~A>#tjkY=oLau&D8Ai7x#zpaxq9jLCD+p zLG5M=WD=8-K!BHh83C%`o^$nB+;d(Q6U?ivcAuiYUdU-Y?n77O+Vg|UMh3HMt39jm zbp$g*Rxd%5by;XikG-F=uf1_7ZT7(k@*rLj*DIpH5LmC6T5<%#l|ObnIK|z~eZ?$bsO(hBc<|C@B48!>r%$u7~OWHXstq#4N4nb2pD}587Y0#L= z-vaiyT?}{n1V(VqbbS!cj}Rju^lnUk(NpA55n9BXMf_+=8eP|jOapg~J`t0aBj8@= zmviQeVp@>%8T@misE-Va`Y~8l5r>s`AycM6)ZY{k^--dzcOGcC-WRtPOMg(UulJ3F z4Mo8w)f^M@)HG-C!?2e+1mj2sRN@c9o$G=)dY{6Gh*_K1E(*{Gua1CHK{wwqi+XTP zj?1f<(~|endT>iVW~MvQKE`qNaJelzVCP5X`QIwL&O3${Qp+TBX#V282?(q^Db9F@ zA@F+?=nF?oDwkRSqJO5#Lgg{p&T)`?C@^~cb4Z6mqaS^mEMCRg$6?~Q#oDi^$F7@QnbjhN3w_QxRM^cMR7mi^}J&q8}8(J3T z8(Qla%GA%JdnKMM9EQRIK3+?TxtcxD%?LH`PY8`x1=#7A5FdEQ?(Wnc-w6DF9laZ8 z`8s67_lXNeGf@M)b_Z{`0iMgE0&}q6OOt%F+-=yECUo#hyXf6VFQ(*4YUdL+mzesj zp8C|UMQpwXZgeQilQm4-P9SW0NNyCN+lwzI2|Lsh{rl8m6H}vtx0$`@4_8$8@P3y3 z28S1GI2M)~H7!3Mjgwu{fdqp1qviCyXg}0V)-aCZ_-@Y6&n`KI2o$zQ2#c<}85KGh zLE%6HSAt`35DAA$opLX|oNYD~znCo)N-Gt(jveoJ;@A*{yCJ4)}9kN86f>HQmcL4!6PI8~&PDj^mLNYoxF1-;qU=n(~ zk6gg97l+r~ihH}HclxfQtxz{rn63=N$35>1E=Kc<=;Ezd0yb@e`J&QUsH_kqVo9WM zo=)N8_dbT7{Md?BHX(ogfdNZUO#05u@I3HapaJEi&gzDN<7yzCMM4GB~$T7bej z7fyB4SC8BW&eFXpnhv7FVXBemxyO&CJeJ{QiSAD`uw8H-j`_}r$uxCv?+?r#m=jlF zCsNXY`xY}=8gqsgr`3~s2Fy7>Pv9uXg;s%IcqtZ{#!*tcWOLxir7M3EtF@lBtmJl?^3uineYt{wgJ`)sSU7FcsnK=d1C&=GJ#x?B_WAd zZxB;cZD}#h<2XE^)oFewoK6c&y3Ot|lf-$~ux9>NQxR5Ghn?ZaVV-PC3UiKy=O|NA zxD)psq?mONJL5d&_G4n(bYt_;j>H!11=A~o7(S*kY$`H2n}h@%UHhpc^4k}=!|*vm zcproBE0p&k6QUf=rQ*hVHKZJwst9(d?HE%t)LkY>o#=x3z~zVo=}>^kIcN@|QG z&$Q^R(uA7N-1{K+FqD70^g_~MV$$=TG*DJd8z`UV*EoZ=O6G}(qsCv3%NN{EzuS)j z@50d8c-u6#mH%u?lKF-k4%NP=2-_!3dbp#X6O;I3H#EoN-7L+%<(>Wr8jf5R8itrP zxN7E$?evczKMXeOF&{lBO(4qcp^;E?vI*tfM&*p3hV_Zh=p}EUp}XDHD)rtB8%(x^ ze+QdB?Rfo6!SH71&_H&0xx{teO~?>Y+%3YqAM_O03x*$xt~-nTK|idChg5C)?~|VY z-fjia`PN})8i()`Q2w~IX>3n*BztOESlEYbH*D>&9bj9XBQl(CX%4Zi(RDvVZht_( z^+!L{1Z&sZXB%K#p|)cK=(*n}^swC)sIU7~dIN!jf))s!KP-=Bp*W3LnKT^p5=g6O`|LTB+j{uY5*c{%W1)9+* zOyMn9Sn2!J-45RDT5i+^-fp2>m7y)4^>y7xQYr( zQuO*~&_2+XqaWQumS)9S;W*zs*~_E{lu5YL^H<$s)X_ri>ftyubPVsafyy#0u*_L7 z@jyUhaa>7bi6)JuEKJl{3VKx*_W_(9CZ#2yu;lx7g0k|F@Uk3IR(_3Bbyw0=g7Y{T zT1q~=jWl29P>@sF^&aY&-SwW(YBC~GIJKXw>%H*fRDJ&~=@59R;^6a*6exaE!c+lP z0~!IF0M7tk0-OMR0=NW-dP~CG0GI?|0XcwjKpkKc;2FSfz$<`v0T%#a?Gk1rAPz7I zpa-M@3IHX5rGR?ClYqT|V}OqU(zhjy91st<6`%&B0CE83fI7f`1D*lA05}W?KFgUU zOgUr0fqovpD#pazjo&iicNhLO%w0?+Q_U=fZvm6VWWrQ2M*LXVDwraqcQ7?bS;Q=a zE%;pc65nG3>;mwB9Doua2YA1b$aext04abdz?p8Gbpk8^L;-em;S3N!0qDGlvtWR^ zfD4}^43GlwUXaM!02=`502!e5JdTM2<^q%eIpEx9hy%FrDbA4rdO9U?%+{H9m^9jA z1BuxcuoGoA!488axt z%nasU_)JHv{_bF$8A7R)*9^p%gm^0fWF}3Y%_QaIWM*XNFv%%NIfPrvjO3iz_EaV{ zGc_x9dJdDCWzQiDV9&_ONEI>_?C?y>C`hH6WZ*9&Wmc+C4>A!eW7_l?vr=JZ*)uZ` zD`R?cW^M}b43slHD`&>NsneN&DdanSMov;r#tfi!fK7mHfO^16z+u1%0OfP7hxCDKJ%O}REHga{1~a0X^r} zT%u*CJ`aC1juZR+DlE^Cl0*-=1CNBEcLrSXNqo!i|B9lmS(EcMu5Da8O%8f4oyMO( zJdn>5W8rw+7RUye`PYOA|Gl}wYlw(0;eAQ4QVii)>0fgzj0rAL56tD^ZYnYGU z5eQ?K*i{cbd*2iaPGk<%elGaRBw+%z`v2j=Pwx|soNVO6|1)He-S0nLcxwFX(f;wL z1T+(At0nM=EfRELE;B%kJQ;NR~DFupqfUh;#(UK~U5Lim@uo*&c>Jm6nk zU$ywdKM_67`)xP*Uk9q6JVE^Wr{hl;Yj?g5hBzbg@9{^B%=~81_7jnR&%ey!g*LtM zUpxP(v3X|;+~-98Z8>PEWojv0i?=iv-1Ihf}Cl)6$hW5I8EwS>b>*8+;A0d$Z#v4YB z?R~Bv9X4`!bbOrfjJd)S6EBS)bB*x$g!uS)*+2QvH$<=X^nO=1U>QPBZ|x+K1jsGp^J!X*J|15vw4Tb}sLH_<9?+qW=pReTpXXN*HNAK^3zx#;z zO}77?^zIDd?|wY~FXHbj@zcMX-#^3O-yOZb8~*-xqwSUO3F_fWDejZ{plf@fSI1%< zb~M&lW3Wy-4(p{i;T^mHW<1thugCq^8vr-rEI!-}+{zCadDCARVa-%ndn6}y2!d!}G-dL4Urfb9VKqS78fD}cU{oBk*GQ3^0ef|bJ^uba|MK!a`;sMn_Cv52 z7Ea5YF*PZ(Fg-QNUYL!o(BvH2c`Pi<%Faukl@sbuK6L1B#IQRR&WfV@${h;6Qc+q_%9j?Emp8hO74#m>aYTj8?u2|%(SV(y*78aG43k48f+NF%42c_{kz;w4Vm+~dm zj-p~vXyN?><6oUFfkeecd=bzcF|6pmipuIGAV5`h<>Kn1B?{hAy`;3FKb@6AeXiI( zjtWq)vSNv&f=7P9RVmcxigAmo7dt6pO_07yHPLBNc_oUgSgfe3EUn-LHh@pDqgbS8 zR_Vg(%9_eWydtl(hMFpQ@?^!V0E1?h-d9~zy@Ggl7??8Xol1N=Vc0OcSSb@&n7Qk& zyBKq@mK8tl}OjEa%r!9#zMZ5 zyt5rue9$w=x!765Gt52Ca)D0wfR89$QdM;+p_x@wy|4skn&ZA|XMmRX6jcaTltcM5 z$d~eDkQe0xs6e_Eln14!v<%WP*+smwx)=eJUv;Tq%PDbI*983X9mN%nfFs8#+OjGk zhLIxM88C}@O3NS}gZK>MF^EIq1hB#f0SHGll!&rWHc$X2KnQpNJzxoBfiqA?4X7e` zHonofqVg`CTiV&@rtskNf9YJ-6Oweu+O%p1TK!4EKFg6*4ynQXRB(y*SBS5ZE0-+6 zpqN=&;YeceDi8;s7Z^C1TgjDGS?nx#q$5f>A}|SkercuUj_K%A@EuCNseNK0uc*3| zq$7GqNRFxKEk75^PjS@n)s-ulp9!vH$TS|9z8sb(N@fA^7lSSlS>_o@M(x^QCc`7WYye1o@Eh-0RKS{1Yt+tX~ zsP6+|h(MA@5M&IqjY6n7gfur09YaEwP;9YPk}Dw?AqOc&HeW1yVriV*)J8cgsvL}6 z3@yUQSCvt*s4|K9Eqa{85z=Vcd^IF;O%n6`RYLNaV`2HF#g62XqUxN=EE@ zQr?$m#K^AfpU*I-!}8IB4#JLkS)iDmkYfHo_M~Jx!>B0jjMOZ$TggrYPAV?0riNkm zOENK91O@`|-><+MXlEK09mVMP)eahSsH=zgXH@k1pON%ppHmsE67#YoGdZiMN~8mF zZ4Pw<>ukb93?-T(MqYm(#JM+h*7VfOf#bpV3R{y&&OCWaA}o6$sc?oa?j4-D#K(da z@ZUKRo(T-204M=fSTCr;JBb&Jhj}x`0e}K=j=)R=G$E`BW-UxP4(Qo&M1U@qD*%ZA zB~BRZjE9@TZ^XGKm<&uipbF3g*o^Sa@K>O$M7Wy)N5~ETW-`C#G&&URj}Jpr_FG0MjfgEwE(hrC=fOQWuh)SL5CK= zaljeC7l63GNSHeTM!+;cAz&HcM}TJmdjYQl{s#C8Ab(fF+zsFW8Gr)7eSm6!3-B1= z8NeR^hXC&YE&!O*66QvL0gwe)2v`I7Dd2g)A;8;!EW;~-{CNMWM z6Tw=yFt;+d;mqXi%pJ^RW(s4#n+Wd0`A#LHV$?XNt7WV>m8)YiGp42%*pqVd1*N7S zE3+`gv8V{$Jz11>40#DsO6&}xdwEq+@6aJc2=Nd)x9Ev(T2WLEv0TcpuoqQBc?yVs z3MPq^T#2q+LF102T*w)nZfa4Dqu1_SvgC6Ys;9K75=qoUZcd_er<%5vwD zis?>4q3WN6M#BC9LRFK2PcV}-j8~XQWR^n53M9@bPU0ay?{o5we&uCUR5>xmqDsqq z<5IODX|s9cQWMM|8)|;(qEbg+K7IAcax4*s2r3KqtRi7354dJI`kVqmg&YOj)IL&O zM(R+H>Dhg00?kpFl@;RGTe_HPmZQcY)&@4H_oA;5AEOcoQ4Y#L43~>zk=R%W>1{^X zlW95<7{3QZqw%E(^P=h$L>U+cbp_lpz&F63*Yr&VKVl#!s-gIl%7r{+_!W>$Ef)rl ztA`9IB{jId5Xd>TqWBthL+CY%t|$(aepwmCq-hCLC=6jX! zr0T^%LS3ue>6I7`gDWZnvPPINp}YcCV3(pLeG-7yW&*SeXi@OVsHowqoq~2ZAmdpM z^u3Dd**VpvRnYl@Nwe=St*UYqi`foH0wk-i#c)FS)tf~KzH-9|LDwQtt~lQeGRXkM zax1Dx1O~9a0;zH#AE_4vYgw?Q{IXblWmQNAM2fV^YDekfij?2MT!g|WeQ>zGWoElGfB9=U5J={>H5dR zxe2C}c@TH=E15-DKMdxciPR;ywO@@D#jC{$je&Jv#C0H#Qrs_B;NHIzIrFepAZIe~ zLn!@MBBX*ThMk990l+y9!CWNxl?X1%s|HZbEX6;?zWi+hp?)~ya9N7}7)=Vf_kKI_ zyBdbY$Y&wmdO&p-OQts*C<0jb4+Ckwb-C9nQ=~}$yooYY?&TCK3ec1&MKP{L83uKs z_`z1F5!$5+DaAG@g{gpRIa-5qqrA%DLvL)T2GIK(#1M*A0edL`+q;1n#61;w|ARtk z`3ksdz&AuUdc<7%;uHzBsTOji7{TyhJw#6FkK@3+#JE?EQwrS6QTpOQEfxlNnBG1i z)?yOyqm~fsT?J~~hZLmI z9IR`QTX~^WqQad*D77lpK1eaKHx?o6K44D$iRci-pXgGIx-3K(aT#Gwb)uU0^=vAG z@}V9qN>xfn7*q>%2vUJslky@8_qE35GN3<&ME;=M$X|S$3)P)uWu;IPs(0U8L_|&? ziirJ2#6{%m;$H5ccf%0fN(K25O8IZ#R=vw zO4)DU>xp})ZbWU8WF)6)fC;xQV<`^OMD zoO*UBM~Q7ml9x0I>RE)R64aqaklVaKFR?bnIpQL{h&S~Ran!w>`XW90_c79&?iXl6d=~8g zS00TN(CG%YabJ4U?I=A_IJAZ&af5mql_9n`;Z3?7QAw026h`s-dI3qNCGaCYWMB`< z+d}L@--X?1g1+Z{e8Y{DWcp4pfjt0pj*gyAgwZEK2A@F+3{qf_0)rG7q`)8r1}QK| zfk6rkQecn*gA^E~z#s(%DKJQZK?)2~V2}cX6d0tyAO!{~Fi3$x3Jg+UkOG4g7^J`; z1^)L_fX)Ws+P(1D@s;;$)u?tr_{IV5k^$~(<@H^MDI)%h-kQ++&>07E2qwLR>l>ah zg!df7x2#|ufk~e?*anl5*1{yhU+9gGu4C35;O#U_}91P>Fha$w9b z>9r10n0S=~bLxmhz8vOZm~@6?FU$vF?ts|?b305zdLzsTydGjW?DXI@70pu7$~+cg z_rOm0(({85J3gJ->)#Y&|6z#zM=M95g|M1rM!wXaYI# zJbhX;w>%}9YoF+#sxXPGYXx&V;_ut~&Q^sOeA)lnOQKg|!2I2}jGq*UzZ>yifAY+e zH!y#F();9`tLMLZi;!X_2s`tg`R^#0!gtEvQC}Yac>B8@U*JtDtAm({QK*a1Cqjr% z2vDqGQoB&wBU`*>f???UX2d&0!zcg|jZE?*lW0m|)V9Ge%9qlTN#E$9{E6SlkNAyv zjez`#?&PlvxRV0zH*3NoCXftjK=}Kmn)%5RX;^2v@2H z;ZqABoYw}-hhS2;3qav@0LllvC7fq}JmB5}lknXJpz?kJpm@Ir5PtO8S_*#)K;dy9 z3eo2?eA1bKup0QAgcDcdZ(zuk-07gt6aegi z6aWj*0+fJBfEYj&fbgdFq^Aw|@4;7#zX{d^o+E+!im4%&Ah3upIzRRM?f8b_Kl9jA z{<-w=31RZN0Ky@tcLebn=nnP22@VeMJphfjKLPv>Z~|~1FbWk^0;U6&04Og?V*-#I zUj}##unTY;@EL$U_Hj2L3s4RidJ2Y-L3Ay3p}M7nI=jj*TiUkZ+Xpf+VZhwl=YbHoDB()n1%7W z@=ay`n7`5N(cGogX~!FGHMAMVv&rl-;{wyWT&#JNMQUU0!YgT+2}-RpQJJYMP!=nz zlq;2O$mcK0cI}O{c(VZOfiPC864X`S0=GC#yhfo(&`i=y(I_=q4XZJ05;ZBBbWNtl zuF269Xy$4bXo@u@nsQB*hSx0Dtkl$M>NNG5^_nKl2F*szCe3EeHqCa;4$V%@F5tgc z)2wOLv}q1&j%ZG3+BK&%leE9l?$H+L=IR#cighKr7TpEiSGsgVronE=F%%f)8WtFe z4JC&4?C*?>X(D$A*KR#!?XaG)dadWIoz@H1ZtD))^EO&cqPE(l-lN{DZdSLd+tgwU zz_SVKUYM6m(&Pf;MH;8Z4a}a=9M$|q)2->j>r|y$nKnu**T!g*wCUQ#+8=2DTe}N* z?bSAGTeWT45js|9(`5q3<+>l~9@qU&*RDII>(HIid3AFA^?Ic~Q*YPj=nM37_1pDc z{oMu|aIQ2wV)%t&x8b+wHZ7MI^3*G19wy^ z8jna(+bXxp!TjaxDDG3t%frODSIQUWK-C5Hj}lpIcxztmtDX< z!R}`Fv!~cwjU~pP8aEr?F?Jirnbw$|Fuh~?%5*n3gKOlTuB z)+5#v*2_7j$I95GHkmETmPT~h$uQk8_9{22HmkO&wySoicB*!%_Nex%npLf;Hq~L( z5!DG*yXusxLv;oeI;ZMXv1%K7@{j?X?bV#qbZRaH_$pmDLpMf0PJdM2u3u_cWnhd_ zqs$m(lpAA=amIL~!kB1GF{T?cjdo*>vA{UjxWHI!tTWad*BhIR8;l!`dyIRH&Bj(^ zoAI#mi1CE6-FS~_rb)&{adL1-92d{6=GJldnrE4>v)o{jS);6SYm7C{8gDgQ6Rj!M zbZe&7Zq2b4fIC)NYpr$Gdh2@YWZOpD6E>!qVWxl|<|-E|zrd@76ICgybXBIxuF6sI z;Dwc{T2-B@UbSA;6re|>dW8CM^;7Eonn$&dX-G93 z{Z9QZ{T}^Zw0f()O@CN_M1KO5IHm8_&DI zyP4g_ZfAF}JK0_AdG5gEuzWHruw@wo|=3uvY{_jj^OwS*NU5u2(iG zYcvmPM9g<;llAxLdBbwUN<*zdV|>8WVLF4>J7?-NT`+ZjG=BwZvL(t+Mj{IJn8`vwmg`NBeBDZME&Py+*ip zit?>MIaj#=60Ss9jxn%Fxk0&6xk#xSwXCTkc={rL>`p1S%1~Z%3E5Tl753p~s zoh)zsKKk`j#vIceQz%VX&deopDO@__y`9V9cy2kjlB*RcGt2y{`Iz|wbB}qY#RdNT zmBngJ4e7~EXt!PcB;Gk;R4lYDvaPWF$ku7=0%asjBKr9-HVc&q%{+Nw4#+c$v z@g{{S!8FM<#iTT8O{~dmN;IXI(oLBryD0~w-(1rIQ?Y5ismZhfBjFy?UQ@HF)zo$s zj?!{{w0nUY3m(7UTzyrE;RWx{vlLsLmLFJ%`){?{28%0F9gRDupURkOPmao>H0B$?Cc41?pmTiMkwmR-L+D{k2-E z>CgOR+r@-dXF?lH_X>@n;$G-Gs3#h6Hx*<{*m+Gg5r z+F{yh+66i(xZ8wYw1L~mWm>W=`z?norz{J9S=9y7zMs(0G?o! zQl(58rIagU(7X4mlxi(Tf3rGKouW=xXR7V$9Cbmz`tZ;VR;p`Judmf}v{5>_E=Cup zi`OZ13A#zTDLSQ2dzn5^An12{q1~O(eXOg{JM|Ak7no$2Vo>&K0Sg2@uiQ{&AZb!z zbQ&KvK4FxahJ$BxrXQGoYThIqHNUCBne0`bTrGH<47UN>9VKn<&_77~BaVWF|o$>M>Q*0_Rm7A(eylMFrxFOhU zPF*IA>$yj{Nb?Bu3zmJB7pw=ZC#`?A-fh#{rr8$Q4na?R&-SH_ghe{)FH=RSM9r{| z!}~_MK3$=pS5Mf{t2c#eNEE-%pVqCb*69%eP+5gSG!2N272ZYaG9!? zYOT69-Qix{vPZ}0rI64r{RaK7^lF3AaF1c3;e??b8bt>*O0Pl2MzL}>hK*z6Sp{^- zr&+5pHK1>m7|V@Sg4T7(7;%NstAcZKCFXK-m6f|law^Mx!rY+A z@_Wls%QP#HSRfI`@kf-$l{u=fRj;VOP*2h*wFYepW;~6M+VAN{8^%Jrm}XdJXffQu zRzlx?kv+}U3jJ`K@o&cQCXeaAK%b9HmrV8C=iFDE-fTAKnjeFf_O$sGbChM2px4;@H$}4a(VBwgTH+a9*+P726xaSk*)0con|$0fS`I z1m(TTRlRyga3uezR|m^c%~6%9s#U90E>(l-zf{kH17Coy{=VuX=;#`Cs(K6NgRiRp zrv6fG*4(doK$!O})vm%E<~i-}wEMJ2we8x|+P^}Q#ewdV&|7Ed=IDxa59pTZR_olD z@BO!Kv+il#Z*+gq4P~!q$FT<1%-+k+WQ*8xb~XD$Xkt&YzhHmGzJO8wFRT}1-9`2* zcDQkrG1vH&(aW6&rA9&vyThz98_Y@OY35Am>-S--S|`x%In3ahT8SWbexv-O^04xl z@_pr4)kM`~l}cq)O;z2iI;wgLb@HmD>S5{_^$n2HCiPVHOm&0$G4(~YT=PTCPcRc% zj1k49J)<@18g*+7>kJ;lj}1RJ{L=7i!wZJ}hF1*7&=Wch-3Er0VU9Hsv#a~r@3U($ z6MX~yp}<&VoQ<*Mi0LiU=|De-vo69ZWin$W5oU0PFll@#9cbGfEo#0I7RPzG! z;y~~Cq4`Dg$AWg*WA2mC-xFkU2{iKEkU9q}M=WnxMp(yM6;`EHZ?#ybfm2GXOROub ztF1q?Zh=ht!1^_GyBOP@HlxjE%LI?yXDhSS+kSvq%WhkVs#hB86wiG&s%vCK=6{|{A<*4Pr+2;n#t2SM6ZhjcE@-yh^ zJt`Ucg&Zq5aoTvT0_zl$v{STw+M%df7hJ~4b>@2WdUKO`gL&h(o@@3={LuNf!kS>6 zWSs(@)}qel0kiL7TZygQR%PRD%WW&MI#UO3UT%Jk?L@?3;aFZG;we&putP9$eC--k{#7-lX0vj6CgFeY;#ImG-WL#c9(6 zt2v_fHc(To)79&mFPqng>a8@tSF&1`g}m&W4dn#ZbBfs#$j>TvvvHeoyKx8Bz;<0> zwd0hr!zd4|bcD_v`?u^jw_$f+jJ|q{9l;t|yX};%!*<5z#ae8q?Sie_CX7c%z`N+H zG#&+Y7)R7Jg0wEP;gZ7ye;F{+Gn@-#7{RvpqH&gKaF^VbNZkiKk5l#yz8P51U9x z%ViOVJ#prMI3NxjB2EbHA%`4LPAjxRd*Fa_LL5+zxn;lCUDaK$yQ!5(r0*r{z!_h;K_75qSxLh3h5S}pd&XTI(nLj zsefNY$9^MX8dy>Uz5&o6@Iv|uPtefw5e;7^3JGlvgGS~Q{eUN^JgMk=JVB!aioU@U zbR6Fw(ieDwPN450eS#X#pwkUSzv2lxb4d~O zdj@p&VnpW_h(h`iPte%BqMLYv#@|$gzKnw=&MW#3PtfGfh=x9eK0s%Gis%U1WvYB0 z(V=fKUZ7*(59uR3LH%DwROtsFXbAmdI(m(1d3kzv{_TaO<;khV%EI*g(%TEmGt(1O z@6L}e{h5}R=Pu05WLfBMF;B#?bpFEJTg#KmU5M5qqFAEb=EFrK2V8D4kvtCJtBV1|L(h4)m73Xwq zJir9G)CoLW&$888&Tn;sO4AR#D`FZ#i_@Y?@h`T#mHKMkOW~!ntE=UKPZ3 zda#p45pw9_n9nl*=GV;efmWoXX3_G^mEda2bC1BJg+a+qH9YR4Th_)P zW$k@ca&e`W@mHF)l(k3yrsCq5uVx+EWaWfXcBZ5aThG%?*m#l_()~zFr|T2Rx$2s? z-m0$T49t{Yvvb9*uuIAroX};7dM$aybXN=BYCI6K15UOL+8J*Phs}fGXe#7Xt=T&( zzR1p^<(t7`fYniLG=0zBqd6-}B41@&A~Yu9n?aUCNyGS6*ODk9JBw`$TDIL>@z&QN zGwrVj?M{wKo6luc?Jamgr|r)zF172eh9?{x#v)Uzq@cWZu<^QbvzhJK){W3**o=+K zY$d&ZvMr=JOlkXU$+ltVQ!QQaKk%D>^|cMM&np*G+(wH7$67Q!-1F;#@8r`hA^c>A zmGS@=;$p@3?pnhQldfbLw15eUX2#c57gLMa!N9VS;DWaDNGflYgCWkXturjd;a9oq{)n)m=(;+F-sT?`oS#1&W6dJtz(H< zZ*8{PXf#($R-;hyEO<7ixKwea11Yp)L{UMr6{*sMS~NCz+pz(sniPvm3A{R?RRAklTu$RT7H4ikL_;`G54 z&~4EBuMyn>-8h0B^iiUH*q#1%jA&^9WuTEkqOU;D4-s7+1}|t1S%M!xlVzgsK?9>i z-+&GrC;9@k`vlP^plv6KJ_g+ZefT=j?;!saa6ygJM8ASAoxwMQE}kV?I7jp&XnqWR z0lhg69MJg*qVGUE(aBHo9X~NIzW4JA(YNT=PJHi2pfB<5{V2Nwo@?j}k}b529-s&5 zA^HQIrH5%dJwlJt4%$hN(P`R6kJBVQLF06e#^_0Uik_z3^b9>quTzDdqvz=bdXZkD zm+2KM(H?r0_R>DuPY38A9iqcf<7;$;j#57zqX9ZagEU0LG(u$>rQ>vhCg=>Eq(0j6 zfAAGs?KuISqZ@4TLl$FmUu?V1Quf7+X`k#Y_+_JQw^~QtZJec0{K^kCnCg4T3`GKD1YYm|K~^T~}=?*jB>sI0kcL^Fg$3or879Folh8DyUVBcN2#y z5nD`|j!`Uumm{jork0CjpL5d5NzgA`i&1R26Eh;>Wvg?`*^IHdjh5yvX*uh1lDgRO z$Rb-R*zh&B)T2>tON3hUv;tIdm~Khb8@X3eE?ktT$vP@oE%L0QidE@~Po1tSX(4uC zqR1Mq$B}r#8jhnm1;PUD*iw8OHLy%*cF=#6bzQ6s?{9| zA-hwQEUApAsFa@2)UDG^N_k6)QZU$Dri~$XoU$@@pQ&Pd0x`{GbERpXw53kh+pTqq zYlC#3)5XeW9BirWJ_e@1H`$%8zynJ*XC^qXzA_G2GUU2p!J5f!iCVi$mMmQ)!8RQD z&=KbjeU7UZpXEw0rI=d9(oAu-NQkFhxKU{&8xvKg zlIXV+k6Q*GmyS{CI#h;?#KZhbJH((Jq9=DfgwjZBg!~54-O>}Y^_6yWy}25c4lNum z%}md|#iE(tqbOlXZXp_#heCBf5S9rb8e3_uweZ1rOWWw~U5%(mlD}{Z>3)wP(ZnT} zbxGJmM%t=NMwkZ$2~RmG;qq7cANAw5aLYrz@nZ|UgMaV+Z3)rm0xM#uJZ!9pE#Zpz zXZU^mmDFdOF}1KN`Nxo-tqR7xm;B!6<{^y3-%Fa4sP##%$JGWs#!zx9iH-fImP(dsL}&N0zl>$N0>+1>xs>e?beSNI}&dN)tXZ(F_sI?VkXk?t3_7$14GgZA^q` z>>p*1s*d(-gE3#_zRom1`#la9xdosvI&P5<~zg`?YE&-Ec zEUoDzm(wF&j*Z6wTa0JshjVC*BH-;)r9mJ_jV;#)h*s+@i}N+C&VL6LUQ-kW>OybY&BG zITr2-fu}RG5>UJq&}3c|`=kvI8DD`R--;kQ#*Qrw@5Yj`Q$6HNvV`n9R1e9dLI#cqm*8)!f1}3Uv#3Xdk#JJIByMw`5$%cY)Qf2M`ZTaTGy5%ryh~> z<`(BLQpox&t5;NqwPM7QiK-9Ddc+%b_%~dRqdfx8divHYx?{(Jt9xOlH`cLlyCEaN z#aj`(<%j`!SIFMoz)qbR2_(6!i{R$O^t_iaaIHsvJ)-CInyqGno<82}5!Yd>BfdXL{w zj{n|VX8d`zv31wqkUpcAu;Q(V&U0otE_}zR*0X;B*1gt8b8HM}OmvT(xBYs>&#~-m z=LG(Sp_2HRBAU-xX9H>Ud+X60GmTO4hXJzR1mc$2#9M)J&pT)1W6c;}Uo#N^-S;;yF6QG_jhDK=(krUNfAb#TT#TArjFE8S lt%yz?R*WNJ{E14`M|t5!Ky + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/GPSBabel.dsp b/msvc/GPSBabel.dsp new file mode 100644 index 000000000..225d705a8 --- /dev/null +++ b/msvc/GPSBabel.dsp @@ -0,0 +1,720 @@ +# Microsoft Developer Studio Project File - Name="GPSBabel" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=GPSBabel - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "GPSBabel.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "GPSBabel.mak" CFG="GPSBabel - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "GPSBabel - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "GPSBabel - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /WX /GX /O2 /I "expat" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__WIN32__" /D VERSION=\"1.2.6_beta06232005_msvc\" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setupapi.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /WX /Gm /GX /ZI /Od /I "expat" /D "WIN32" /D "__WIN32__" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D VERSION=\"1.2.6_beta06232005_msvc\" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setupapi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "GPSBabel - Win32 Release" +# Name "GPSBabel - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Group "Jeeps" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\jeeps\gpsapp.c + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP Intermediate_Dir "Release\Jeeps" + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP Intermediate_Dir "Debug\Jeeps" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpscom.c + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP Intermediate_Dir "Release\Jeeps" + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP Intermediate_Dir "Debug\Jeeps" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsmath.c + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP Intermediate_Dir "Release\Jeeps" + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP Intermediate_Dir "Debug\Jeeps" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsmem.c + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP Intermediate_Dir "Release\Jeeps" + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP Intermediate_Dir "Debug\Jeeps" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsprot.c + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP Intermediate_Dir "Release\Jeeps" + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP Intermediate_Dir "Debug\Jeeps" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsread.c + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP Intermediate_Dir "Release\Jeeps" + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP Intermediate_Dir "Debug\Jeeps" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsrqst.c + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP Intermediate_Dir "Release\Jeeps" + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP Intermediate_Dir "Debug\Jeeps" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpssend.c + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP Intermediate_Dir "Release\Jeeps" + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP Intermediate_Dir "Debug\Jeeps" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsserial.c + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP Intermediate_Dir "Release\Jeeps" + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP Intermediate_Dir "Debug\Jeeps" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsusbread.c +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsusbsend.c +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsusbstub.c +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsusbwin.c +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsutil.c + +!IF "$(CFG)" == "GPSBabel - Win32 Release" + +# PROP Intermediate_Dir "Release\Jeeps" + +!ELSEIF "$(CFG)" == "GPSBabel - Win32 Debug" + +# PROP Intermediate_Dir "Debug\Jeeps" + +!ENDIF + +# End Source File +# End Group +# Begin Group "ShapeLib" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\shapelib\dbfopen.c +# End Source File +# Begin Source File + +SOURCE=..\shapelib\shpopen.c +# End Source File +# End Group +# Begin Source File + +SOURCE=..\an1.c +# End Source File +# Begin Source File + +SOURCE=..\arcdist.c +# End Source File +# Begin Source File + +SOURCE=..\brauniger_iq.c +# End Source File +# Begin Source File + +SOURCE=..\wbt-200.c +# End Source File +# Begin Source File + +SOURCE=..\cetus.c +# End Source File +# Begin Source File + +SOURCE=..\coastexp.c +# End Source File +# Begin Source File + +SOURCE=..\copilot.c +# End Source File +# Begin Source File + +SOURCE=..\csv_util.c +# End Source File +# Begin Source File + +SOURCE=..\delgpl.c +# End Source File +# Begin Source File + +SOURCE=..\duplicate.c +# End Source File +# Begin Source File + +SOURCE=..\easygps.c +# End Source File +# Begin Source File + +SOURCE=..\filter_vecs.c +# End Source File +# Begin Source File + +SOURCE=..\garmin.c +# End Source File +# Begin Source File + +SOURCE=..\garmin_tables.c +# End Source File +# Begin Source File + +SOURCE=..\gcdb.c +# End Source File +# Begin Source File + +SOURCE=..\geo.c +# End Source File +# Begin Source File + +SOURCE=..\geoniche.c +# End Source File +# Begin Source File + +SOURCE=..\glogbook.c +# End Source File +# Begin Source File + +SOURCE=..\google.c +# End Source File +# Begin Source File + +SOURCE=..\gpilots.c +# End Source File +# Begin Source File + +SOURCE=..\gpspilot.c +# End Source File +# Begin Source File + +SOURCE=..\gpsutil.c +# End Source File +# Begin Source File + +SOURCE=..\gpx.c +# End Source File +# Begin Source File + +SOURCE=..\grtcirc.c +# End Source File +# Begin Source File + +SOURCE=..\hiketech.c +# End Source File +# Begin Source File + +SOURCE=..\holux.c +# End Source File +# Begin Source File + +SOURCE=..\hsa_ndv.c +# End Source File +# Begin Source File + +SOURCE=..\html.c +# End Source File +# Begin Source File + +SOURCE=..\igc.c +# End Source File +# Begin Source File + +SOURCE=..\internal_styles.c +# End Source File +# Begin Source File + +SOURCE=..\kml.c +# End Source File +# Begin Source File + +SOURCE=..\lowranceusr.c +# End Source File +# Begin Source File + +SOURCE=..\maggeo.c +# End Source File +# Begin Source File + +SOURCE=..\magnav.c +# End Source File +# Begin Source File + +SOURCE=..\magproto.c +# End Source File +# Begin Source File + +SOURCE=..\main.c +# End Source File +# Begin Source File + +SOURCE=..\mapopolis.c +# End Source File +# Begin Source File + +SOURCE=..\mapsend.c +# End Source File +# Begin Source File + +SOURCE=..\mapsource.c +# End Source File +# Begin Source File + +SOURCE=..\mkshort.c +# End Source File +# Begin Source File + +SOURCE=..\navicache.c +# End Source File +# Begin Source File + +SOURCE=..\netstumbler.c +# End Source File +# Begin Source File + +SOURCE=..\nmea.c +# End Source File +# Begin Source File + +SOURCE=..\overlay.c +# End Source File +# Begin Source File + +SOURCE=..\ozi.c +# End Source File +# Begin Source File + +SOURCE=..\palmdoc.c +# End Source File +# Begin Source File + +SOURCE=..\pathaway.c +# End Source File +# Begin Source File + +SOURCE=..\pcx.c +# End Source File +# Begin Source File + +SOURCE=..\polygon.c +# End Source File +# Begin Source File + +SOURCE=..\position.c +# End Source File +# Begin Source File + +SOURCE=..\psitrex.c +# End Source File +# Begin Source File + +SOURCE=..\psp.c +# End Source File +# Begin Source File + +SOURCE=..\queue.c +# End Source File +# Begin Source File + +SOURCE=..\quovadis.c +# End Source File +# Begin Source File + +SOURCE=..\reverse_route.c +# End Source File +# Begin Source File + +SOURCE=..\route.c +# End Source File +# Begin Source File + +SOURCE=..\saroute.c +# End Source File +# Begin Source File + +SOURCE=..\shape.c +# End Source File +# Begin Source File + +SOURCE=..\smplrout.c +# End Source File +# Begin Source File + +SOURCE=..\sort.c +# End Source File +# Begin Source File + +SOURCE=..\stackfilter.c +# End Source File +# Begin Source File + +SOURCE=..\tef_xml.c +# End Source File +# Begin Source File + +SOURCE=..\text.c +# End Source File +# Begin Source File + +SOURCE=..\tiger.c +# End Source File +# Begin Source File + +SOURCE=..\tmpro.c +# End Source File +# Begin Source File + +SOURCE=..\tomtom.c +# End Source File +# Begin Source File + +SOURCE=..\tpg.c +# End Source File +# Begin Source File + +SOURCE=..\util.c +# End Source File +# Begin Source File + +SOURCE=..\util_crc.c +# End Source File +# Begin Source File + +SOURCE=..\uuid.c +# End Source File +# Begin Source File + +SOURCE=..\vcf.c +# End Source File +# Begin Source File + +SOURCE=..\vecs.c +# End Source File +# Begin Source File + +SOURCE=..\vitosmt.c +# End Source File +# Begin Source File + +SOURCE=..\vmem.c +# End Source File +# Begin Source File + +SOURCE=..\waypt.c +# End Source File +# Begin Source File + +SOURCE=..\xcsv.c +# End Source File +# Begin Source File + +SOURCE=..\xmlgeneric.c +# End Source File +# Begin Source File + +SOURCE=.\Expat\libexpat.lib +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Group "Jeeps-Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\jeeps\gps.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsapp.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpscom.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsdatum.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsfmt.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsinput.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsmath.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsmem.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsnmea.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsnmeafmt.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsnmeaget.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsport.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsproj.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsprot.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsread.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsrqst.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpssend.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsserial.h +# End Source File +# Begin Source File + +SOURCE=..\jeeps\gpsutil.h +# End Source File +# End Group +# Begin Group "ShapeLib-Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\shapelib\shapefil.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\csv_util.h +# End Source File +# Begin Source File + +SOURCE=..\defs.h +# End Source File +# Begin Source File + +SOURCE=..\garmin_tables.h +# End Source File +# Begin Source File + +SOURCE=..\grtcirc.h +# End Source File +# Begin Source File + +SOURCE=..\holux.h +# End Source File +# Begin Source File + +SOURCE=..\magellan.h +# End Source File +# Begin Source File + +SOURCE=..\mapsend.h +# End Source File +# Begin Source File + +SOURCE=..\queue.h +# End Source File +# Begin Source File + +SOURCE=..\quovadis.h +# End Source File +# Begin Source File + +SOURCE=..\uuid.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/msvc/GPSBabel.dsw b/msvc/GPSBabel.dsw new file mode 100644 index 000000000..622d699e8 --- /dev/null +++ b/msvc/GPSBabel.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "GPSBabel"=.\GPSBabel.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/msvc/GPSBabel.sln b/msvc/GPSBabel.sln new file mode 100644 index 000000000..ce62adf0e --- /dev/null +++ b/msvc/GPSBabel.sln @@ -0,0 +1,22 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPSBabel", "GPSBabel.vcproj", "{EB2609DB-5800-45B2-BCB2-06D72F389DCA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Unicode|Win32 = Unicode|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EB2609DB-5800-45B2-BCB2-06D72F389DCA}.Debug|Win32.ActiveCfg = Debug|Win32 + {EB2609DB-5800-45B2-BCB2-06D72F389DCA}.Debug|Win32.Build.0 = Debug|Win32 + {EB2609DB-5800-45B2-BCB2-06D72F389DCA}.Release|Win32.ActiveCfg = Release|Win32 + {EB2609DB-5800-45B2-BCB2-06D72F389DCA}.Release|Win32.Build.0 = Release|Win32 + {EB2609DB-5800-45B2-BCB2-06D72F389DCA}.Unicode|Win32.ActiveCfg = Unicode|Win32 + {EB2609DB-5800-45B2-BCB2-06D72F389DCA}.Unicode|Win32.Build.0 = Unicode|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/msvc/GPSBabel.vcproj b/msvc/GPSBabel.vcproj new file mode 100644 index 000000000..ed82fee4e --- /dev/null +++ b/msvc/GPSBabel.vcproj @@ -0,0 +1,3331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/README.msvc b/msvc/README.msvc new file mode 100644 index 000000000..109648d1b --- /dev/null +++ b/msvc/README.msvc @@ -0,0 +1,31 @@ + +BUILDING GPSBABEL WITH Microsoft Visual C++: + +This directory contains the necessary files to build GPSBabel with +Microsoft Visual C++ version 6.0 and above. The project and workspace +files should just work, provided that the "msvc" directory is a direct +child of the directory that contains the GPSBabel source. (This is where +it should be, by default, so you shouldn't have to do anything other than +load the workspace and hit "build all.") If you load these files in to +Visual Studio .NET, you may be asked to convert them to the new format; +In that case, you should do so. + +Note that the "Microsoft Platform SDK" is required in addition to +the actual compiler package. If you're using the Express editions, +you must also reconfigure MSVC to use that as described at: + http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/ + +The "Expat" directory contains the import library and header file for the +Expat DLL. This may or may not be the latest build of Expat; you might +want to check http://expat.sourceforge.net to see if there is a more recent +version. + +To run GPSBabel, you must make sure that the libexpat.dll from the Expat +directory is in the DLL search path. The easiest way to do this, and to +avoid version conflicts with other programs that use expat, is to put +libexpat.dll in the same directory as gpsbabel.exe. + +If you experience any problems with this project file or with the build +process, please ask for assistance on the gpsbabel-code mailing list at +http://lists.sourceforge.net/lists/listinfo/gpsbabel-code . + diff --git a/msvc/Unicode.empty b/msvc/Unicode.empty new file mode 100644 index 000000000..e69de29bb diff --git a/msvc/build.bat b/msvc/build.bat new file mode 100644 index 000000000..12638a74d --- /dev/null +++ b/msvc/build.bat @@ -0,0 +1,8 @@ +setlocal +set include=%include%;expat;c:\tools\c +set SOURCEJEEPS=..\jeeps\gpsapp.c ..\jeeps\gpscom.c ..\jeeps\gpsmath.c ..\jeeps\gpsmem.c ..\jeeps\gpsprot.c ..\jeeps\gpsread.c ..\jeeps\gpsrqst.c ..\jeeps\gpssend.c ..\jeeps\gpsserial.c ..\jeeps\gpsusbread.c ..\jeeps\gpsusbsend.c ..\jeeps\gpsusbstub.c ..\jeeps\gpsusbwin.c ..\jeeps\gpsutil.c +set SOURCEMAG=..\maggeo.c ..\magnav.c ..\magproto.c +set SOURCE=..\xmltag.c ..\strptime.c ..\trackfilter.c ..\gdb.c ..\bcr.c ..\discard.c ..\formspec.c ..\an1.c ..\arcdist.c ..\brauniger_iq.c ..\wbt-200.c ..\cetus.c ..\coastexp.c ..\copilot.c ..\csv_util.c ..\delgpl.c ..\duplicate.c ..\easygps.c ..\filter_vecs.c ..\garmin.c ..\garmin_tables.c ..\gcdb.c ..\geo.c ..\geoniche.c ..\glogbook.c ..\google.c ..\gpilots.c ..\gpspilot.c ..\gpx.c ..\grtcirc.c ..\hiketech.c ..\holux.c ..\hsa_ndv.c ..\html.c ..\igc.c ..\internal_styles.c ..\kml.c ..\lowranceusr.c ..\main.c ..\mapopolis.c ..\mapsend.c ..\mapsource.c ..\mkshort.c ..\navicache.c ..\netstumbler.c ..\nmea.c ..\overlay.c ..\ozi.c ..\palmdoc.c ..\pathaway.c ..\pcx.c ..\polygon.c ..\position.c ..\psitrex.c ..\psp.c ..\queue.c ..\quovadis.c ..\reverse_route.c ..\route.c ..\saroute.c ..\shape.c ..\shapelib\dbfopen.c ..\shapelib\shpopen.c ..\smplrout.c ..\sort.c ..\stackfilter.c ..\tef_xml.c ..\text.c ..\tiger.c ..\tmpro.c ..\tomtom.c ..\tpg.c ..\util.c ..\util_crc.c ..\uuid.c ..\vcf.c ..\vecs.c ..\vitosmt.c ..\vmem.c ..\waypt.c ..\xcsv.c ..\xmlgeneric.c ..\fatal.c ..\globals.c ..\cet_util.c ..\cet.c ..\nmn5.c ..\nmn4.c ..\cst.c ..\msroute.c ..\stmwpp.c ..\ignrando.c ..\tpo.c +cl /c ..\gpsutil.c -Fogpsutil2.obj +cl /Fegpsbabel.exe %source% %sourcejeeps% %sourcemag% gpsutil2.obj -DVERSION=\"1\" -D__WIN32__ -DWIN32_LEAN_AND_MEAN -DNO_USB Expat\libexpat.lib +endlocal diff --git a/msvc/config.h b/msvc/config.h new file mode 100644 index 000000000..b8df41708 --- /dev/null +++ b/msvc/config.h @@ -0,0 +1,28 @@ +#define HAVE_LIBEXPAT 1 +#define __va_copy(ap1, ap2) ((ap1) = (ap2)) + +// This controls the capabilities of our Character Encoding Transformations. +// Undefne for minimal. +// Define to zero for the common UTF-8, ASCII and related sets. +// Define to one for everything we know. + +/* 0 for most-used, 1 for all character sets */ +#undef CET_WANTED + +/* 1 to enable as many formats as possible */ +#undef MAXIMAL_ENABLED + +/* 1 to enable the CSV formats support */ +#undef CSVFMTS_ENABLED + +/* 1 to enable all the filters. */ +#undef FILTERS_ENABLED + +/* 1 to enable Palm PDB support */ +#undef PDBFMTS_ENABLED + +/* 1 to enable shapefile support */ +#undef SHAPELIB_ENABLED + +/* 1 to inhibit our use of zlib. */ +#define ZLIB_INHIBITED 1 diff --git a/msvc/mkwintesto.dsp b/msvc/mkwintesto.dsp new file mode 100644 index 000000000..41a6b3e40 --- /dev/null +++ b/msvc/mkwintesto.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="mkwintesto" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=mkwintesto - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mkwintesto.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mkwintesto.mak" CFG="mkwintesto - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mkwintesto - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "mkwintesto - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mkwintesto - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x1009 /d "NDEBUG" +# ADD RSC /l 0x1009 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "mkwintesto - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x1009 /d "_DEBUG" +# ADD RSC /l 0x1009 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "mkwintesto - Win32 Release" +# Name "mkwintesto - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\mingw\mkwintesto.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/msvc/release.empty b/msvc/release.empty new file mode 100644 index 000000000..e69de29bb diff --git a/mtk_logger.c b/mtk_logger.c new file mode 100644 index 000000000..d1cb3fc0e --- /dev/null +++ b/mtk_logger.c @@ -0,0 +1,1149 @@ +/* + Download track data from GPS loggers based in MTK chipset. + + Copyright (C) 2007 Per Borgentun, e4borgen(at)yahoo.com + With lot of inspiration from wbt-200.c + Copyright (C) 2006 Andy Armstrong + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ +/* + -------------------------------------------------------------- + This module will download track data from a MTK chipset based GPS logger. + It will also convert the raw data.bin file to MTK compatible CSV and + gpsbabel output of your choice. + It has been tested with Transystem i-Blue 747 but other devices should + work as well (Qstarz BT-Q1000, iTrek Z1, ...) + + For more info and tweaks on MTK based loggers + + + For info about the used log format: + + + Example usage:: + + # Read from USB port, output trackpoints & waypoints in GPX format + ./gpsbabel -D 2 -t -w -i mtk -f /dev/ttyUSB0 -o gpx -F out.gpx + + # Parse an existing .bin file (data_2007_09_04.bin), output trackpoints as + # both CSV file and GPX + ./gpsbabel -D 2 -t -i mtk-bin,csv=data__2007_09_04.csv -f data_2007_09_04.bin -o gpx -F out.gpx + + Todo: + o .... + + */ + +#include "defs.h" +#include "gbser.h" +#include "gbfile.h" /* used for csv output */ +#include + +#define MYNAME "mtk_logger" + +/* MTK packet id's -- currently unused... */ +enum MTK_NMEA_PACKET { + PMTK_TEST = 0, + PMTK_ACK = 1, + PMTK_SYS_MSG = 10, + PMTK_CMD_HOT_START = 101, + PMTK_CMD_WARM_START = 102, + PMTK_CMD_COLD_START = 103, + PMTK_CMD_FULL_COLD_START = 104, + PMTK_CMD_LOG = 182, /* Data log commands */ + PMTK_SET_NMEA_BAUDRATE = 251, + PMTK_API_SET_DGPS_MODE = 301, + PMTK_API_SET_SBAS_ENABLED = 313, + PMTK_API_SET_NMEA_OUTPUT = 314, + PMTK_API_SET_PWR_SAV_MODE = 320, + PMTK_API_SET_DATUM = 330, + PMTK_API_SET_DATUM_ADVANCE = 331, + PMTK_API_SET_USER_OPTION = 390, + PMTK_API_Q_FIX_CTL = 400, + PMTK_API_Q_DGPS_MODE = 401, + PMTK_API_Q_SBAS_ENABLED = 413, + PMTK_API_Q_NMEA_OUTPUT = 414, + PMTK_API_Q_PWR_SAV_MODE = 420, + PMTK_API_Q_DATUM = 430, + PMTK_API_Q_DATUM_ADVANCE = 431, + PMTK_API_GET_USER_OPTION = 490, + PMTK_DT_FIX_CTL = 500, + PMTK_DT_DGPS_MODE = 501, + PMTK_DT_SBAS_ENABLED = 513, + PMTK_DT_NMEA_OUTPUT = 514, + PMTK_DT_PWR_SAV_MODE = 520, + PMTK_DT_DATUM = 530, + PMTK_DT_FLASH_USER_OPTION = 590, + PMTK_Q_VERSION = 604, + PMTK_Q_RELEASE = 605, + PMTK_DT_VERSION = 704, + PMTK_DT_RELEASE = 705 +}; + +static const unsigned char LOG_RST[16] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* start marker */ + 0x00, 0x00, 0x00, 0x00, 0x00, /* data */ + 0xbb, 0xbb, 0xbb, 0xbb }; /* end marker */ + +static const char *MTK_ACK[] = { /* Flags returned from PMTK001 ack packet */ + "Invalid packet", "Unsupported packet type", + "Valid packet but action failed", "Valid packet, action success" }; + +/* *************************************** */ + +/* Data id, type, sizes used by MTK chipset - don't touch.... */ +enum { + UTC = 0, + VALID, + LATITUDE, + LONGITUDE, + HEIGHT, + SPEED, + HEADING, + DSTA, + DAGE, + PDOP, + HDOP, + VDOP, + NSAT, + SID, + ELEVATION, + AZIMUTH, + SNR, + RCR, + MILLISECOND, + DISTANCE, +} DATA_TYPES; + +struct log_type { + int id; + int size; + const char *name; +} log_type[] = { + { 0, 4, "UTC" }, + { 1, 2, "VALID" }, + { 2, 8, "LATITUDE,N/S"}, + { 3, 8, "LONGITUDE,E/W"}, + { 4, 4, "HEIGHT" }, + { 5, 4, "SPEED" }, + { 6, 4, "HEADING" }, + { 7, 2, "DSTA" }, + { 8, 4, "DAGE" }, + { 9, 2, "PDOP" }, + { 10, 2, "HDOP"}, + { 11, 2, "VDOP"}, + { 12, 2, "NSAT (USED/VIEW)"}, + { 13, 4, "SID",}, + { 14, 2, "ELEVATION" }, + { 15, 2, "AZIMUTH" }, + { 16, 2, "SNR"}, + { 17, 2, "RCR"}, + { 18, 2, "MILLISECOND"}, + { 19, 8, "DISTANCE" } +}; + +struct sat_info { + char id, used; + short elevation, azimut, snr; +} sat_info; + +struct data_item { + time_t timestamp; + short valid; + double lat; + double lon; + float height; + float speed; + float heading; + short dsta; // differential station + float dage; // differential ... + float pdop, hdop, vdop; + char sat_used, sat_view; + short rcr; + unsigned short timestamp_ms; + double distance; + struct sat_info sat_data[32]; +} data_item; + +/* *************************************** */ + +#define TIMEOUT 1000 +#define MTK_BAUDRATE 115200 + +static void *fd; /* serial fd */ +static FILE *fl; /* bin.file fd */ +static char *port; /* serial port name */ +static char *erase; /* erase ? command option */ +static char *csv_file; /* csv ? command option */ +static unsigned int bmask = 0x000e0e7f; +static unsigned int mlog_period, mlog_distance, mlog_speed; /* in 10:ths of sec, m, km/h */ + + +const char LIVE_CHAR[4] = {'-', '\\','|','/'}; +const char TEMP_DATA_BIN[]= "data.bin"; + + +const char CMD_LOG_DISABLE[]= "$PMTK182,5*20\r\n"; +const char CMD_LOG_ENABLE[] = "$PMTK182,4*21\r\n"; +const char CMD_LOG_FORMAT[] = "$PMTK182,2,2*39\r\n"; +const char CMD_LOG_ERASE[] = "$PMTK182,6,1*3E\r\n"; + + +static void file_init(const char *fname); +static void file_deinit(void) ; +static void file_read(void); + + + +// Arguments for logg fetch 'mtk' command.. + +static arglist_t mtk_sargs[] = { + { "erase", &erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + { "csv", &csv_file, "MTK compatible CSV output file", + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static void dbg(int l, const char *msg, ...) { + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vprintf(msg, ap); + } + va_end(ap); +} +static int do_send_cmd(const char *cmd, int cmdLen) { + int rc; + + dbg(6, "Send %s ", cmd); + rc = gbser_print(fd, cmd); + if ( rc != gbser_OK ) + fatal(MYNAME ": Write error (%d)\n", rc); + + return cmdLen; +} + +static int do_cmd(const char *cmd, const char *expect, time_t timeout_sec) { + char line[256]; + int len, done, loops, cmd_erase; + int expect_len; + time_t tout; + + if ( expect ) + expect_len = strlen(expect); + else + expect_len = 0; + + time(&tout); + if ( timeout_sec > 0 ) + tout += timeout_sec; + else + tout += 1; + + cmd_erase = 0; + if ( strncmp(cmd, CMD_LOG_ERASE, 12) == 0 ){ + cmd_erase = 1; + if (global_opts.debug_level > 0 ) { + dbg(1, "Erasing "); + fflush(stdout); + } + } + // dbg(6, "## Send '%s' -- Expect '%s' in %d sec\n", cmd, expect, timeout_sec); + + do_send_cmd(cmd, strlen(cmd)); // success or fatal()... + + done = 0; + loops = 0; + memset(line, '\0', sizeof(line)); + do { + int rc; + rc = gbser_read_line(fd, line, sizeof(line)-1, TIMEOUT, 0x0A, 0x0D); + if ( rc != gbser_OK) { + if ( rc == gbser_TIMEOUT && time(NULL) > tout ){ + dbg(2, "NMEA command '%s' timeout !\n", cmd); + return -1; + // fatal(MYNAME "do_cmd(): Read error (%d)\n", rc); + } + len = -1; + } else { + len = strlen(line); + } + loops++; + dbg(8, "Read %d bytes: '%s'\n", len, line); + if ( cmd_erase && global_opts.debug_level > 0 && global_opts.debug_level <= 3 ){ + // erase cmd progress wheel -- only for debug level 1-3 + printf("\b%c", LIVE_CHAR[loops%4]); fflush(stdout); + } + if ( len > 5 && line[0] == '$' ){ + if ( expect_len > 0 && strncmp(&line[1], expect, expect_len) == 0 ){ + if ( cmd_erase && global_opts.debug_level > 0 ) printf("\n"); + dbg(6, "NMEA command success !\n"); + done = 1; + } else if ( strncmp(line, "$PMTK", 5) == 0 ){ + /* A quick parser for ACK packets */ + if ( !cmd_erase && strncmp(line, "$PMTK001,", 9) == 0 && line[9] != '\0' ){ + char *pType, *pRslt; + int pAck; + pType = &line[9]; + pRslt = strchr(&line[9], ',') + 1; + if ( memcmp(&cmd[5], pType, 3) == 0 && pRslt != NULL && *pRslt != '\0' ){ + pAck = *pRslt - '0'; + if ( pAck != 3 && pAck >= 0 && pAck < 4 ){ // Erase will return '2' + dbg(1, "NMEA command '%s' failed - %s\n", cmd, MTK_ACK[pAck]); + return -1; + } + } + + } + dbg(6, "RECV: '%s'\n", line); + } + + } + if ( !done && time(NULL) > tout ){ + dbg(1, "NMEA command '%s' timeout !\n", cmd); + return -1; + } + } while ( len != 0 && loops > 0 && !done ); + return done?0:1; +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void mtk_rd_init(const char *fname){ + int rc; + + port = xstrdup(fname); + + dbg(1, "Opening port %s...\n", fname); + if (fd = gbser_init(port), NULL == fd) { + fatal(MYNAME ": Can't initialise port \"%s\"\n", port); + } + + // verify that we have a MTK based logger... + dbg(1, "Verifying MTK based device...\n"); + + if ((rc = gbser_set_port(fd, MTK_BAUDRATE, 8, 0, 1))) { + dbg(1, "Set baud rate to %d failed (%d)\n", MTK_BAUDRATE, rc); + fatal(MYNAME ": Failed to set baudrate !\n"); + } + rc = do_cmd("$PMTK605*31\r\n", "PMTK705", 10); + if ( rc != 0 ) + fatal(MYNAME ": This is not a MTK based GPS ! (or is it turned off ?)\n"); + +} + +static void mtk_rd_deinit(void){ + dbg(3, "Closing port...\n"); + gbser_deinit(fd); + fd = NULL; + xfree(port); +} + +int mtk_erase(void){ + + dbg(1, "Start flash erase..\n"); + do_cmd(CMD_LOG_DISABLE, "PMTK001,182,5,3", 1); + gb_sleep(10*1000); + + do_cmd(CMD_LOG_FORMAT, "PMTK182,3,2", 2); + gb_sleep(10*1000); + + // Erase log.... + do_cmd(CMD_LOG_ERASE, "PMTK001,182,6", 30); + gb_sleep(100*1000); + + do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", 2); + + return 0; +} + +static void mtk_read(void){ + char cmd[256]; + char *line = NULL; + unsigned char crc, *data = NULL; + int cmdLen, j, bsize, i, len, ff_len, rc, init_scan; + unsigned int line_size, data_size, data_addr, addr, addr_max; + FILE *dout; + + dout = fopen(TEMP_DATA_BIN, "wb"); + if ( dout == NULL ){ + fatal(MYNAME ": Can't create temporary file %s", TEMP_DATA_BIN); + return; + } + dbg(1, "Download %s -> %s\n", port, TEMP_DATA_BIN); + + i = do_cmd(CMD_LOG_DISABLE, "PMTK001,182,5,3", 2); + dbg(3, " ---- LOG DISABLE ---- %s\n", i==0?"Success":"Fail"); + + addr_max = 0x200000-64*1024; // 16Mbit/2Mbyte/32x64kByte block. + init_scan = 1; + bsize = 0x0400; + addr = 0x0000; + + line_size = 2*bsize + 32; // logdata as nmea/hex. + data_size = bsize + 32; + if ( (line = xmalloc(line_size)) == NULL){ + fatal(MYNAME ": Can't allocate %u bytes for NMEA buffer\n", line_size); + } + if ( (data = xmalloc(data_size)) == NULL ){ + fatal(MYNAME ": Can't allocate %u bytes for data buffer\n", data_size); + } + memset(line, '\0', line_size); + memset(data, '\0', data_size); + + + while ( init_scan || addr < addr_max ) { + // generate - read address NMEA command, add crc. + crc = 0; + cmdLen = snprintf(cmd, sizeof(cmd), "$PMTK182,7,%.8x,%.8x", addr, bsize); + for (i=1;i 0 ) { + line[len] = '\0'; + if ( strncmp(line, "$PMTK182,8", 10) == 0 ){// $PMTK182,8,00005000,FFFFFFF + data_addr = strtoul(&line[11], NULL, 16); + fseek(dout, data_addr, SEEK_SET); + i = 20; + j = 0; + ff_len = 0; // number of 0xff bytes. + while ( i < (len-3) ){ + data[j] = (isdigit(line[i])?(line[i]-'0'):(line[i]-'A'+0xA))*0x10 + + (isdigit(line[i+1])?(line[i+1]-'0'):(line[i+1]-'A'+0xA)); + if ( data[j] == 0xff ) + ff_len++; + i += 2; + j++; + } + if ( init_scan ){ + if ( ff_len == j ){ // data in sector - we've found max sector.. + addr_max = addr; + dbg(3, "### Init scan complete - max block is 0x%6x!!! ###\n", addr_max); + } + len = 0; + } else { + if ( fwrite(data, 1, j, dout) != j ) + fatal(MYNAME ": Failed to write temp. binary file\n"); + if ( ff_len == j ){ // 0xff block - read complete... + len = ff_len; + addr_max = addr; + break; + } else { + len = 0; + } + } + } + } + } while ( len != 0 ); + if ( init_scan ){ + addr += 0x10000; + if ( addr >= addr_max ){ // initial scan complete... + init_scan = 0; + addr = 0x0000; + } + } else { + int perc; + addr += bsize; + perc = 100 - 100*(addr_max-addr)/addr_max; + if ( addr >= addr_max ) + perc = 100; + dbg(2, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bReading 0x%.6x %3d %%", addr, perc); fflush(stdout); + } + } + if ( dout != NULL ) + fclose(dout); + dbg(2, "\n"); + + i = do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", 2); + dbg(3, " ---- LOG ENABLE ----%s\n", i==0?"Success":"Fail"); + + if ( line != NULL ) + xfree(line); + if ( data != NULL ) + xfree(data); + + file_init(TEMP_DATA_BIN); + file_read(); + file_deinit(); + + /* fixme -- we're assuming all went well - erase flash.... */ + if ( *erase != '0' ) { + mtk_erase(); + } + + return; +} + + +static route_head *trk_head = NULL; +static int add_trackpoint(int idx, unsigned long bmask, struct data_item *itm){ + char wp_name[20]; + waypoint *trk = waypt_new(); + + if ( global_opts.masked_objective & TRKDATAMASK && trk_head == NULL ){ + trk_head = route_head_alloc(); + xasprintf(&trk_head->rte_desc, "Log every %.0f sec, %.0f m, %.0f km/h" + , mlog_period/10., mlog_distance/10., mlog_speed/10.); + track_add_head(trk_head); + } + + if ( bmask & (1<latitude = itm->lat; + trk->longitude = itm->lon; + } else { + return -1; // GPX requires lat/lon... + } + + if ( bmask & (1<altitude = itm->height; + // WAYPT_SET(trk, altitude, itm->height); + } + trk->creation_time = itm->timestamp; // in UTC.. + if ( bmask & (1<microseconds = MILLI_TO_MICRO(itm->timestamp_ms); + + if ( bmask & (1<pdop = itm->pdop; + if ( bmask & (1<hdop = itm->hdop; + if ( bmask & (1<vdop = itm->vdop; + + if ( bmask & (1<heading); + } + if ( bmask & (1<speed)); + } + if ( bmask & (1<valid){ + case 0x0040: trk->fix = fix_unknown;break; /* Estimated mode */ + case 0x0001: trk->fix = fix_none; break; /* "No Fix" */ + case 0x0002: trk->fix = fix_3d; break; /* "SPS" - 2d/3d ?*/ + case 0x0004: trk->fix = fix_dgps; break; + case 0x0008: trk->fix = fix_pps; break; /* Military GPS */ + + case 0x0010: /* "RTK" */ + case 0x0020: /* "FRTK" */ + case 0x0080: /* "Manual input mode" */ + case 0x0100: /* "Simulator";*/ + default: + trk->fix = fix_unknown; + break; + } + } + if ( bmask & (1<sat = itm->sat_used; + + // RCR is a bitmask of possibly several log reasons.. + if ( global_opts.masked_objective & WPTDATAMASK + && bmask & (1<rcr & 0x0008 ) + { + /* Button press -- create waypoint, start count at 1 */ + waypoint *w = waypt_dupe(trk); + + sprintf(wp_name, "WP%04d", waypt_count()+1); + w->shortname = xstrdup(wp_name); + waypt_add(w); + } + // In theory we would not add the waypoint to the list of + // trackpoints. But as the MTK logger restart the + // log session from the button press we would loose a + // trackpoint unless we include/duplicate it. + + if ( global_opts.masked_objective & TRKDATAMASK ){ + sprintf(wp_name, "TP%04d", idx); + trk->shortname = xstrdup(wp_name); + + track_add_wpt(trk_head, trk); + } + return 0; +} + + +/********************** MTK Logger -- CSV output *************************/ +static gbfile *cd; +static void mtk_csv_init(char *csv_fname, unsigned long bitmask){ + int i; + FILE *cf; + + dbg(1, "Opening csv output file %s...\n", csv_fname); + + // can't use gbfopen here - it will fatal() if file doesn't exist + if ( (cf = fopen(csv_fname, "r")) != NULL ) { + fclose(cf); + warning(MYNAME ": CSV file %s already exist ! Cowardly refusing to overwrite.\n", csv_fname); + return; + } + + if ( (cd = gbfopen(csv_fname, "w", MYNAME)) == NULL ) { + fatal(MYNAME ": Can't open csv file '%s'\n", csv_fname); + } + + /* Add the header line */ + gbfprintf(cd, "INDEX,%s%s", ((1<timestamp)); + strftime(ts_str, sizeof(ts_str)-1, "%Y/%m/%d,%H:%M:%S", ts_tm); + + if ( bmask & (1<valid){ + case 0x0001: fix_str = "No fix"; break; + case 0x0002: fix_str = "SPS"; break; + case 0x0004: fix_str = "DGPS"; break; + case 0x0008: fix_str = "PPS"; break; /* Military GPS */ + case 0x0010: fix_str = "RTK"; break; /* RealTime Kinematic */ + case 0x0020: fix_str = "FRTK"; break; + case 0x0040: fix_str = "Estimated mode"; break; + case 0x0080: fix_str = "Manual input mode"; break; + case 0x0100: fix_str = "Simulator"; break; + default: fix_str = "???"; break; + } + } + gbfprintf(csvFile, "%d,", idx); + + // RCR is a bitmask of possibly several log reasons.. + if ( bmask & (1<rcr&0x0001?"T":"",itm->rcr&0x0002?"S":"" + , itm->rcr&0x0004?"D":"",itm->rcr&0x0008?"B":""); + + if ( bmask & (1<timestamp_ms:0); + + if ( bmask & (1<lat), itm->lat>0?'N':'S', + fabs(itm->lon), itm->lon>0?'E':'W'); + + if ( bmask & (1<height); + + if ( bmask & (1<speed); + + if ( bmask & (1<heading); + + if ( bmask & (1<dsta); + if ( bmask & (1<dage); + + if ( bmask & (1<pdop); + if ( bmask & (1<hdop); // note bug in MTK appl. 1.02 is output as 1.2 ! + if ( bmask & (1<vdop); + if ( bmask & (1<sat_used, itm->sat_view); + + if ( bmask & (1<sat_data[l].id > 0 ){ + slen = 0; + slen += sprintf(&sstr[slen], "%s%.2d" + , itm->sat_data[l].used?"#":"" + , itm->sat_data[l].id); + if ( bmask & (1<sat_data[l].elevation); + if ( bmask & (1<sat_data[l].azimut); + if ( bmask & (1<sat_data[l].snr); + + gbfprintf(csvFile, "%s%s" , do_sc?";":"", sstr); + do_sc = 1; + } + } + gbfprintf(csvFile, ","); + } + + if ( bmask & (1<distance); + + gbfprintf(csvFile, "\n"); + return 0; +} + + +/********************* MTK Logger -- Parse functions *********************/ +int mtk_parse(unsigned char *data, int dataLen, unsigned int bmask){ + static int count = 0; + int i, k, sat_id; + unsigned char crc; + struct data_item itm; + + memset(&itm, 0, sizeof(itm)); + i = 0; + crc = 0; + for (k=0;k<32;k++){ + switch ( ((1< 0 ) + sat_count = le_read16(data + i + 2); + if ( sat_count > 32 ) + sat_count = 32; // this can't happen ? or... + + sid_size = log_type[SID].size; + if ( bmask & (1< 0 ){ + sat_id = data[i]; + itm.sat_data[sat_idx].id = sat_id; + itm.sat_data[sat_idx].used = data[i + 1]; + // get_word(&data[i+2], &smask); // assume - nr of satellites... + + if ( bmask & (1< 0 ) */ + } + continue; // dont do any more checksum calc.. + break; + case 1< 0 ) { + int j; + printf("Missing '*' !\n"); + for(j=0;j= 16 + && memcmp(&data[0], &LOG_RST[0], 6) == 0 + && memcmp(&data[12], &LOG_RST[12], 4) == 0 ) + { + + cmd = le_read16(data + 8); + switch ( data[7] ){ + case 0x02: + bm = le_read32(data + 8); + dbg(1, "# Log bitmask is: %.8x\n", bm); + if ( bmask != bm ) + dbg(1," ########## Bitmask Change %.8x -> %.8x ###########\n", bmask, bm); + bmask = bm; + break; + case 0x03: + dbg(1, "# Log period change %.0f sec\n", cmd/10.); + mlog_period = cmd; + break; + case 0x04: + dbg(1, "# Log distance change %.1f m\n", cmd/10.); + mlog_distance = cmd; + break; + case 0x05: + dbg(1, "# Log speed change %.1f km/h\n", cmd/10.); + mlog_speed = cmd; + break; + case 0x06: + dbg(1, "# Log policy change 0x%.4x\n", cmd); + if ( cmd == 0x01 ) + dbg(1, "# Log policy change to OVERWRITE\n"); + if ( cmd == 0x02 ) + dbg(1, "# Log policy change to STOP\n"); + break; + case 0x07: + if ( cmd == 0x0106 ) + dbg(5, "# GPS Logger# Turned On\n"); // Fixme - start new trk + if ( cmd == 0x0104 ) + dbg(5, "# GPS Logger# Log disabled\n"); + break; + default: + dbg(1, "## Unknown INFO 0x%.2x\n", data[7]); + break; + } + } else { + if ( global_opts.debug_level > 0 ){ + printf("#!! Invalid INFO block !! %d bytes\n >> ", dataLen); + for (bm=0;bm<16;bm++) printf("%.2x ", data[bm]); + printf("\n"); + } + return 0; + } + return 16; +} + +/********************** File-in interface ********************************/ + +static void file_init(const char *fname) { + dbg(4, "Opening file %s...\n", fname); + if (fl = fopen(fname, "rb"), NULL == fl) { + fatal(MYNAME ": Can't open file '%s'\n", fname); + } +} + +static void file_deinit(void) { + dbg(4, "Closing file...\n"); + fclose(fl); +} + + +static void file_read(void) { + long fsize, pos; + int i, j, k, logLen, bLen; + unsigned char buf[512]; + + memset(buf, '\0', sizeof(buf)); + + /* Get size of file to parse */ + fseek(fl, 0L, SEEK_END); + fsize = ftell(fl); + if ( fsize <= 0 ) + fatal(MYNAME ": File has size %ld\n", fsize); + + fseek(fl, 0L, SEEK_SET); + + /* Header: 20 bytes + 47 05 | 7f 1e 0e 00 | 04 01 | 32 00 00 00 e8 03 00 00 00 00 00 00 + + u16: Log count 'this 64kByte block' - ffff if not complete. + u32: Bitmask for logging. (default mask) + u16; ?? ?? Overwrite/Stop policy + u32: log period, sec*10 + u32: log distance , meters*10 + u32: log speed , km/h*10 + */ + + bLen = 0; + j = 0; + pos = 0; + + /* get default bitmask, log period/speed/distance */ + bLen = fread(buf, 1, 20, fl); + if ( bLen == 20 ){ + unsigned int mask, log_period, log_distance, log_speed; + + mask = le_read32(buf + 2); + // log_policy = le_read16(buf + 6); + log_period = le_read32(buf + 8); + log_distance = le_read32(buf + 12); + log_speed = le_read32(buf + 16); + + dbg(1, "Default Bitmask %.8x, Log every %.0f sec, %.0f m, %.0f km/h\n", + mask, log_period/10., log_distance/10., log_speed/10.); + bmask = mask; + dbg(3, "Using initial bitmask %.8x for parsing the .bin file\n", bmask); + + mlog_period = log_period; + mlog_distance = log_distance; + mlog_speed = log_speed; + } + + pos = 0x200; // skip header...first data position + fseek(fl, pos, SEEK_SET); + + /* read initial info blocks -- if any */ + do { + bLen = fread(buf, 1, 16, fl); + j = 0; + if ( buf[0] == 0xaa ){ // pre-validate to avoid error... + j = mtk_parse_info(buf, bLen); + pos += j; + } + } while ( j == 16 ); + j = bLen; + pos += j; + + /* calculate the length of a binary log item. */ + logLen = 2; // add '*' + crc + for (i=0;i<32;i++){ + if ( (1< 0 ){ + bLen += j; + i = 0; + while ( (bLen - i) >= logLen ){ + k = 0; + if ( (bLen - i) >= 16 && memcmp(&buf[i], &LOG_RST[0], 6) == 0 + && memcmp(&buf[i+12], &LOG_RST[12], 4) == 0 ) + { + mtk_parse_info(&buf[i], (bLen-i)); + k = 16; + } else if ( buf[i] == 0xff && buf[i+1] == 0xff && buf[i+2] == 0xff && buf[i+3] == 0xff + /* && (pos + 2*logLen) & 0xffff) < logLen */) + { + /* End of 64k block segment -- realign to next data area */ + + k = ((pos+logLen+1024)/0x10000) *0x10000 + 0x200; + i = sizeof(buf); + if ( k <= pos ) { + k += 0x10000; + } + dbg(3, "Jump %ld -> %d / 0x%.6x (fsize %ld) --- \n", pos, k, k, fsize); + if ( k > fsize ){ + dbg(3, "File parse complete !\n"); + pos = k; + break; + } else { + fseek(fl, k, SEEK_SET); + } + pos = k; + continue; + } else { + k = mtk_parse(&buf[i], logLen, bmask); + } + + i += k; + pos += k; + } + memmove(buf, &buf[i], sizeof(buf)-i); + j = sizeof(buf)-i; + } + mtk_csv_deinit(); + +} + + +/**************************************************************************/ +// GPS logger will only handle tracks - neither waypoints or tracks... + +ff_vecs_t mtk_vecs = { + ff_type_serial, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + mtk_rd_init, + NULL, + mtk_rd_deinit, + NULL, + mtk_read, + NULL, + NULL, + mtk_sargs, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ +}; + +/* used for mtk-bin */ + +static arglist_t mtk_fargs[] = { + { "csv", &csv_file, "MTK compatible CSV output file", + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +ff_vecs_t mtk_fvecs = { + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none }, + file_init, + NULL, + file_deinit, + NULL, + file_read, + NULL, + NULL, + mtk_fargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ +}; +/* End file: mtk_logger.c */ +/**************************************************************************/ diff --git a/navicache.c b/navicache.c new file mode 100644 index 000000000..3393a3323 --- /dev/null +++ b/navicache.c @@ -0,0 +1,278 @@ +/* + Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "cet_util.h" +#if HAVE_LIBEXPAT +#include +static XML_Parser psr; +#endif + +static waypoint *wpt_tmp; + +static gbfile *fin, *fout; + +static char *noretired = NULL; + +static +arglist_t nav_args[] = { + {"noretired", &noretired, "Suppress retired geocaches", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +#define MYNAME "navicache" +#define MY_CBUF 4096 + +#if ! HAVE_LIBEXPAT +static void +nav_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); +} + +static void +nav_read(void) +{ +} +#else + +static struct +nc_type_mapping{ + geocache_type type; + const char *name; +} nc_type_map[] = { + { gt_unknown, "unknown" }, + { gt_traditional, "normal" }, + { gt_multi, "Multi-part" }, + { gt_virtual, "Virtual" }, + { gt_event, "event" } +}; + +static struct +nc_container_mapping{ + geocache_container type; + const char *name; +} nc_container_map[] = { + { gc_other, "Unknown" }, + { gc_micro, "Micro" }, + { gc_regular, "Normal" }, + { gc_large, "Large" }, + { gc_virtual, "Virtual" } +}; + +static +geocache_type +nc_mktype(const char *t) +{ + int i; + int sz = sizeof(nc_type_map) / sizeof(nc_type_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, nc_type_map[i].name)) { + return nc_type_map[i].type; + } + } + return gt_unknown; +} + +static +geocache_container +nc_mkcont(const char *t) +{ + int i; + int sz = sizeof(nc_container_map) / sizeof(nc_container_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, nc_container_map[i].name)) { + return nc_container_map[i].type; + } + } + return gc_unknown; +} + +static void +nav_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) +{ + const char *el; + const char **attr; + + el = xml_convert_to_char_string(xml_el); + attr = xml_convert_attrs_to_char_string(xml_attr); + if (0 == strcmp(el, "CacheDetails")) { + const char **ap; + wpt_tmp = waypt_new(); + for (ap = attr; *ap; ap+=2) { + if (0 == strcmp(ap[0], "cache_id")) { + wpt_tmp->shortname = xstrdup(ap[1]); + } else + if (0 == strcmp(ap[0], "name")) { + wpt_tmp->description = xstrdup(ap[1]); + } else + if (0 == strcmp(ap[0], "latitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->latitude); + } else + if (0 == strcmp(ap[0], "longitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->longitude); + } else + if (0 == strcmp(ap[0], "longitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->longitude); + } else + if (0 == strcmp(ap[0], "difficulty")) { + float x; + sscanf(ap[1], "%f", &x); + wpt_tmp->gc_data.diff = x * 10; + } else + if (0 == strcmp(ap[0], "terrain")) { + float x; + sscanf(ap[1], "%f", &x); + wpt_tmp->gc_data.terr = x * 10; + } else + if (0 == strcmp(ap[0], "cache_type")) { + static char buf[512]; + + wpt_tmp->gc_data.type = nc_mktype(ap[1]); + if (!strcmp(ap[1], "normal")) + wpt_tmp->icon_descr = "Geocache-regular"; + else if (!strcmp(ap[1], "multi-part")) + wpt_tmp->icon_descr = "Geocache-multi"; + else if (!strcmp(ap[1], "moving_travelling")) + wpt_tmp->icon_descr = "Geocache-moving"; + else { + sprintf(buf, "Geocache-%-.20s", ap[1]); + wpt_tmp->icon_descr = xstrdup(buf); + } + } else + if (0 == strcmp(ap[0], "hidden_date")) { + struct tm tm; + + sscanf(ap[1], "%d-%d-%d", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + wpt_tmp->creation_time = mktime(&tm); + } else + if (0 == strcmp(ap[0], "retired")) { + if (!strcmp(ap[1], "yes") && noretired) { + xfree(wpt_tmp); + return; + } + } else + if (0 == strcmp(ap[0], "cache_size")) { + wpt_tmp->gc_data.container = nc_mkcont(ap[1]); + } else + if (0 == strcmp(ap[0], "description")) { + wpt_tmp->gc_data.desc_long.is_html = 1; + wpt_tmp->gc_data.desc_long.utfstring = xstrdup(ap[1]); + } else + if (0 == strcmp(ap[0], "comments")) { + wpt_tmp->gc_data.desc_short.is_html = 1; + wpt_tmp->gc_data.desc_short.utfstring = xstrdup(ap[1]); + } + } + waypt_add(wpt_tmp); + } + + xml_free_converted_attrs(attr); + xml_free_converted_string(el); +} + +static void +nav_end(void *data, const XML_Char *el) +{ +} + +static void +nav_rd_init(const char *fname) +{ + fin = gbfopen(fname, "r", MYNAME); + + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ":Cannot create XML parser\n"); + } + + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, nav_start, nav_end); +} + +static void +nav_read(void) +{ + int len; + char buf[MY_CBUF]; + + while ((len = gbfread(buf, 1, sizeof(buf), fin))) { + if (!XML_Parse(psr, buf, len, gbfeof(fin))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + + XML_ParserFree(psr); +} + +#endif + +static void +nav_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +nav_wr_init(const char *fname) +{ + fatal(MYNAME ": Does not support writing Navicache files.\n"); + fout = gbfopen(fname, "w", MYNAME); +} + +static void +nav_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +nav_write(void) +{ +} + +ff_vecs_t navicache_vecs = { + ff_type_file, + { ff_cap_read, ff_cap_none, ff_cap_none }, + nav_rd_init, + nav_wr_init, + nav_rd_deinit, + nav_wr_deinit, + nav_read, + nav_write, + NULL, + nav_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/navilink.c b/navilink.c new file mode 100644 index 000000000..a35ae8d1f --- /dev/null +++ b/navilink.c @@ -0,0 +1,970 @@ +/* + NaviGPS serial protocol. + + Copyright (C) 2007 Tom Hughes, tom@compton.nu + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +/* Based on description at http://wiki.splitbrain.org/navilink */ +#include "defs.h" +#include "gbser.h" +#include "jeeps/gpsmath.h" + +#define MYNAME "NAVILINK" + +static char *nuketrk = NULL; +static char *nukerte = NULL; +static char *nukewpt = NULL; +static char *poweroff = NULL; + +static void *serial_handle = NULL; +static gbfile *file_handle = NULL; + +static unsigned char *track_data; +static unsigned char *track_data_ptr; +static unsigned char *track_data_end; +static unsigned track_serial; +static waypoint **route_waypts; +static unsigned *route_ids; +static unsigned route_id_ptr; + +#define SERIAL_TIMEOUT 8000 + +#define MAX_WAYPOINTS 1000 +#define MAX_SUBROUTES 9 +#define MAX_SUBROUTE_LENGTH 14 +#define MAX_ROUTE_LENGTH (MAX_SUBROUTES * MAX_SUBROUTE_LENGTH - 1) +#define MAX_READ_TRACKPOINTS 512 +#define MAX_WRITE_TRACKPOINTS 127 + +#define PID_SYNC 0xd6 +#define PID_ACK 0x0c +#define PID_NAK 0x00 +#define PID_QRY_INFORMATION 0x20 +#define PID_QRY_FW_VERSION 0xfe +#define PID_DATA 0x03 +#define PID_ADD_A_WAYPOINT 0x3c +#define PID_QRY_WAYPOINTS 0x28 +#define PID_QRY_ROUTE 0x24 +#define PID_DEL_WAYPOINT 0x36 +#define PID_DEL_ALL_WAYPOINT 0x37 +#define PID_DEL_ROUTE 0x34 +#define PID_DEL_ALL_ROUTE 0x35 +#define PID_ADD_A_ROUTE 0x3d +#define PID_ERASE_TRACK 0x11 +#define PID_READ_TRACKPOINTS 0x14 +#define PID_WRITE_TRACKPOINTS 0x16 +#define PID_CMD_OK 0xf3 +#define PID_CMD_FAIL 0xf4 +#define PID_QUIT 0xf2 + +static +const char *const icon_table[] = { + "Star", + "Flag", + "House", + "Left Sign", + "Telegraph Pole", + "People", + "Fuel", + "Phone", + "Pole", + "Mountain", + "Water", + "Tree", + "Road Narrows", + "Crossroads", + "Road Fork", + "Turn Right", + "Turn Left", + "Bird", + "3D House", + "Trig Point", + "Tower", + "Cable Car", + "Church", + "Telegraph Pole", + "Skier", + "Anchor", + "Fish", + "Fishes", + "Rain", + "Fisherman", + "Tower", + "Boats", + "Boat", + "Bicycle", + "Railway Track", + "Dollar Sign", + "Bus", + "Camera", + "Fuel Pump", + "Cup", + "Merging Road", + "Plane", + "Red Cross", + "House", + "Parking" +}; + +static +arglist_t navilink_args[] = { + { "nuketrk", &nuketrk, "Delete all track points", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX }, + { "nukerte", &nukerte, "Delete all routes", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX }, + { "nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX }, + { "power_off", &poweroff, "Command unit to power itself down", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static void (*write_waypoint)(const waypoint *) = NULL; +static void (*write_track_start)(const route_head *track) = NULL; +static void (*write_track_point)(const waypoint *waypt) = NULL; +static void (*write_track_end)(const route_head *track) = NULL; +static void (*write_route_start)(const route_head *track) = NULL; +static void (*write_route_point)(const waypoint *waypt) = NULL; +static void (*write_route_end)(const route_head *track) = NULL; + +static int +find_icon_from_descr(const char *descr) +{ + int i; + + for (i = 0; i < sizeof(icon_table) / sizeof(const char *); i++) { + if (strcmp(descr, icon_table[i]) == 0) + return i; + } + + return 0; +} + +static void +free_waypoints(waypoint **waypts) +{ + waypoint **wayptp; + + for (wayptp = waypts; wayptp < waypts + MAX_WAYPOINTS; wayptp++) { + if (*wayptp) { + waypt_free(*wayptp); + } + } + + xfree(waypts); +} + +static unsigned +compare_waypoints(const waypoint *waypt1, const waypoint *waypt2) +{ + return waypt1->latitude == waypt2->latitude && + waypt1->longitude == waypt2->longitude && + waypt1->altitude == waypt2->altitude && + strcmp(waypt1->shortname, waypt2->shortname) == 0; +} + +static unsigned +checksum_packet(const unsigned char *packet, unsigned length) +{ + unsigned checksum = 0; + + while (length-- > 0) { + checksum += *packet++; + } + + return checksum & 0x7fff; +} + +#ifdef NAVILINK_DEBUG + +static void +dump_packet(char *prefix, unsigned char *packet, unsigned length) +{ + unsigned i; + + for (i = 0; i < length; i++ ) { + if ((i % 16) == 0) fprintf(stderr, "%s %08x :", prefix, i); + fprintf(stderr, " %02x", packet[i]); + if ((i % 16) == 15 || i == length - 1) fprintf(stderr, "\n"); + } + + fprintf(stderr, "\n"); +} + +#endif + +static void +write_packet(unsigned type, const void *payload, unsigned length) +{ + unsigned char *packet = xmalloc(length + 9); + + packet[0] = 0xa0; + packet[1] = 0xa2; + le_write16(packet + 2, length + 1); + packet[4] = type; + memcpy(packet + 5, payload, length); + le_write16(packet + length + 5, checksum_packet(packet + 4, length + 1)); + packet[length + 7] = 0xb0; + packet[length + 8] = 0xb3; + +#ifdef NAVILINK_DEBUG + dump_packet(">>>", packet + 4, length + 1); +#endif + + if (gbser_write(serial_handle, packet, length + 9) != gbser_OK) { + fatal(MYNAME ": Write error\n"); + } + + xfree(packet); +} + +static unsigned +read_word(void) +{ + unsigned char buffer[2]; + + if (gbser_read_wait(serial_handle, buffer, 2, SERIAL_TIMEOUT) != 2) { + fatal(MYNAME ": Read error\n"); + } + + return (buffer[1] << 8) | buffer[0]; +} + +static void +read_packet(unsigned type, void *payload, unsigned minlength, unsigned maxlength) +{ + unsigned size; + unsigned char *data; + unsigned checksum; + + if (read_word() != 0xa2a0) { + fatal(MYNAME ": Protocol error: Bad packet header\n"); + } + + if ((size = read_word()) <= minlength) { + fatal(MYNAME ": Protocol error: Packet too short\n"); + } + + data = xmalloc(size); + + if (gbser_read_wait(serial_handle, data, size, SERIAL_TIMEOUT) != size) { + fatal(MYNAME ": Read error reading %d byte payload\n", size); + } + +#ifdef NAVILINK_DEBUG + dump_packet("<<<", data, size); +#endif + + if (data[0] != type) { + fatal(MYNAME ": Protocol error: Bad packet type (expected 0x%02x but got 0x%02x)\n", type, data[0]); + } + + if ((checksum = read_word()) != checksum_packet(data, size)) { + fatal(MYNAME ": Checksum error - expected %x got %x\n", checksum_packet(data, size), checksum); + } + + if (read_word() != 0xb3b0) { + fatal(MYNAME ": Protocol error: Bad packet trailer\n"); + } + + if (size - 1 > maxlength) { + memcpy(payload, data + 1, maxlength); + } else { + memcpy(payload, data + 1, size - 1); + } + + xfree(data); + + return; +} + +static time_t +decode_datetime(const unsigned char *buffer) +{ + struct tm tm; + + tm.tm_sec = buffer[5]; + tm.tm_min = buffer[4]; + tm.tm_hour = buffer[3]; + tm.tm_mday = buffer[2]; + tm.tm_mon = buffer[1] - 1; + tm.tm_year = buffer[0] + 100; + + return mkgmtime(&tm); +} + +static void +encode_datetime(time_t datetime, unsigned char *buffer) +{ + struct tm *tm; + + if ((tm = gmtime(&datetime)) != NULL) { + buffer[0] = tm->tm_year - 100; + buffer[1] = tm->tm_mon + 1; + buffer[2] = tm->tm_mday; + buffer[3] = tm->tm_hour; + buffer[4] = tm->tm_min; + buffer[5] = tm->tm_sec; + } else { + memset(buffer, 0, 6); + } +} + +static void +decode_position(const unsigned char *buffer, waypoint *waypt) +{ + waypt->latitude = le_read32(buffer + 0) / 10000000.0; + waypt->longitude = le_read32(buffer + 4) / 10000000.0; + waypt->altitude = FEET_TO_METERS(le_read16(buffer + 8)); +} + +static void +encode_position(const waypoint *waypt, unsigned char *buffer) +{ + le_write32(buffer + 0, (int) (waypt->latitude * 10000000)); + le_write32(buffer + 4, (int) (waypt->longitude * 10000000)); + le_write16(buffer + 8, METERS_TO_FEET(waypt->altitude)); +} + +static unsigned +decode_waypoint_id(const unsigned char *buffer) +{ + unsigned id = le_read16(buffer + 2); + + if (id >= MAX_WAYPOINTS) { + fatal(MYNAME ": Invalid waypoint ID\n"); + } + + return id; +} + +static waypoint * +decode_waypoint(const unsigned char *buffer) +{ + waypoint *waypt = waypt_new(); + + decode_position(buffer + 12, waypt); + waypt->shortname = xstrdup((char *)buffer + 4); + waypt->icon_descr = icon_table[buffer[28]]; + waypt->creation_time = decode_datetime(buffer + 22); + + return waypt; +} + +static void +encode_waypoint(const waypoint *waypt, unsigned char *buffer) +{ + buffer[0] = 0x00; + buffer[1] = 0x40; + le_write16(buffer + 2, 0); + strncpy((char *)buffer + 4, waypt->shortname, 6); + buffer[10] = 0; + buffer[11] = 0; + encode_position(waypt, buffer + 12); + encode_datetime(waypt->creation_time, buffer + 22); + buffer[28] = find_icon_from_descr(waypt->icon_descr); + buffer[29] = 0; + buffer[30] = 0x00; + buffer[31] = 0x7e; +} + +static waypoint * +decode_trackpoint(const unsigned char *buffer) +{ + waypoint *waypt = waypt_new(); + + decode_position(buffer + 12, waypt); + waypt->creation_time = decode_datetime(buffer + 22); + WAYPT_SET(waypt, course, le_read16(buffer + 2)); + WAYPT_SET(waypt, speed, KPH_TO_MPS(buffer[29] * 2)); + + return waypt; +} + +static void +encode_trackpoint(const waypoint *waypt, unsigned serial, unsigned char *buffer) +{ + double x; + double y; + int32 z; + char zc; + + GPS_Math_WGS84_To_UTM_EN(waypt->latitude, waypt->longitude, &x, &y, &z, &zc); + + le_write16(buffer + 0, serial); + le_write16(buffer + 2, WAYPT_GET(waypt, course, 0)); + le_write32(buffer + 4, x); + le_write32(buffer + 8, y); + encode_position(waypt, buffer + 12); + encode_datetime(waypt->creation_time, buffer + 22); + buffer[28] = z; + buffer[29] = MPS_TO_KPH(WAYPT_GET(waypt, speed, 0) / 2); + buffer[30] = 0x5a; + buffer[31] = 0x7e; +} + +static waypoint ** +serial_read_waypoints(void) +{ + waypoint **waypts = NULL; + unsigned char information[32]; + unsigned short total; + unsigned short start; + + if (global_opts.masked_objective & RTEDATAMASK) { + waypts = xcalloc(MAX_WAYPOINTS, sizeof(waypoint *)); + } + + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, sizeof(information), sizeof(information)); + + total = le_read16(information + 0); + + for (start = 0; start < total; start += 32) { + unsigned short count = total - start; + unsigned char payload[7]; + unsigned char *waypoints; + unsigned char *w; + + if (count > 32) count = 32; + + le_write32(payload + 0, start); + le_write16(payload + 4, count); + payload[6] = 1; + + write_packet(PID_QRY_WAYPOINTS, payload, sizeof(payload)); + + waypoints = xmalloc(count * 32); + + read_packet(PID_DATA, waypoints, count * 32, count * 32); + + for (w = waypoints; w < waypoints + count * 32; w = w + 32) { + if (global_opts.masked_objective & WPTDATAMASK) { + waypt_add(decode_waypoint(w)); + } + if (global_opts.masked_objective & RTEDATAMASK) { + waypts[decode_waypoint_id(w)] = decode_waypoint(w); + } + } + + xfree(waypoints); + + if (global_opts.verbose_status) { + waypt_status_disp(total, start + count); + } + } + + return waypts; +} + +static void +serial_write_waypoint(const waypoint *waypt) +{ + unsigned char data[32]; + unsigned char id[2]; + + encode_waypoint(waypt, data); + write_packet(PID_ADD_A_WAYPOINT, data, sizeof(data)); + read_packet(PID_DATA, id, sizeof(id), sizeof(id)); +} + +static void +serial_read_track(void) +{ + unsigned char information[32]; + unsigned int address; + unsigned short total; + route_head *track; + + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, sizeof(information), sizeof(information)); + + address = le_read32(information + 4); + total = le_read16(information + 12); + + track = route_head_alloc(); + track_add_head(track); + + while (total > 0) { + unsigned short count = total < MAX_READ_TRACKPOINTS ? total : MAX_READ_TRACKPOINTS; + unsigned char payload[7]; + unsigned char *trackpoints; + unsigned char *t; + + le_write32(payload + 0, address); + le_write16(payload + 4, count * 32); + payload[6] = 0x00; + + write_packet(PID_READ_TRACKPOINTS, payload, sizeof(payload)); + + trackpoints = xmalloc(count * 32); + + read_packet(PID_DATA, trackpoints, count * 32, count * 32); + write_packet(PID_ACK, NULL, 0); + + for (t = trackpoints; t < trackpoints + count * 32; t = t + 32) { + track_add_wpt(track, decode_trackpoint(t)); + } + + xfree(trackpoints); + + address = address + count * 32; + total = total - count; + } +} + +static void +serial_write_track(void) +{ + unsigned char information[32]; + unsigned int address; + unsigned short total; + unsigned char data[7]; + + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, sizeof(information), sizeof(information)); + + address = le_read32(information + 4); + total = le_read16(information + 12); + + le_write32(data + 0, address + total * 32); + le_write16(data + 4, track_data_ptr - track_data); + data[6] = 0x00; + + write_packet(PID_WRITE_TRACKPOINTS, data, sizeof(data)); + gb_sleep(10000); + write_packet(PID_DATA, track_data, track_data_ptr - track_data); + read_packet(PID_CMD_OK, NULL, 0, 0); + + track_data_ptr = track_data; +} + +static void +serial_write_track_start(const route_head *track) +{ + track_data = xmalloc(MAX_WRITE_TRACKPOINTS * 32); + track_data_ptr = track_data; + track_data_end = track_data + MAX_WRITE_TRACKPOINTS * 32; +} + +static void +serial_write_track_point(const waypoint *waypt) +{ + if (track_data_ptr >= track_data_end) { + serial_write_track(); + } + + encode_trackpoint(waypt, 0, track_data_ptr); + + track_data_ptr += 32; +} + +static void +serial_write_track_end(const route_head *track) +{ + if (track_data_ptr > track_data) { + serial_write_track(); + } + + xfree(track_data); +} + +static void +serial_read_routes(waypoint **waypts) +{ + unsigned char information[32]; + unsigned char routec; + unsigned char r; + + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, sizeof(information), sizeof(information)); + + routec = information[2]; + + for (r = 0; r < routec; r++) { + unsigned char payload[7]; + unsigned char routedata[320]; + route_head *route; + int sr; + + le_write32(payload + 0, r); + le_write16(payload + 2, 0); + payload[6] = 0x01; + + write_packet(PID_QRY_ROUTE, payload, sizeof(payload)); + read_packet(PID_DATA, routedata, 64, sizeof(routedata)); + + route = route_head_alloc(); + route->rte_num = routedata[2]; + route->rte_name = xstrdup((char *)routedata + 4); + route_add_head(route); + + for (sr = 0; sr < MAX_SUBROUTES; sr++) { + int w; + + for (w = 0; w < MAX_SUBROUTE_LENGTH; w++) { + unsigned short id = le_read16(routedata + 34 + 32 * sr + 2 *w); + + if (id == 0xffffu) { + w = MAX_SUBROUTE_LENGTH; + sr = MAX_SUBROUTES; + } else if (id >= MAX_WAYPOINTS) { + fatal(MYNAME ": Invalid waypoint ID in route\n"); + } else if (waypts[id] == NULL) { + fatal(MYNAME ": Non-existent waypoint in route\n"); + } else { + route_add_wpt(route, waypt_dupe(waypts[id])); + } + } + } + } +} + +static void +serial_write_route_start(const route_head *route) +{ + route_ids = xmalloc(route->rte_waypt_ct * sizeof(unsigned)); + route_id_ptr = 0; +} + +static void +serial_write_route_point(const waypoint *waypt) +{ + unsigned w; + + for (w = 0; w < MAX_WAYPOINTS; w++) { + if (route_waypts[w] && compare_waypoints(waypt, route_waypts[w])) { + break; + } + } + + if (w == MAX_WAYPOINTS) { + unsigned char data[32]; + unsigned char id[2]; + + encode_waypoint(waypt, data); + write_packet(PID_ADD_A_WAYPOINT, data, sizeof(data)); + read_packet(PID_DATA, id, sizeof(id), sizeof(id)); + + w = le_read16(id); + + route_waypts[w] = waypt_dupe(waypt); + } + + route_ids[route_id_ptr++] = w; +} + +static void +serial_write_route_end(const route_head *route) +{ + unsigned char *data; + unsigned src; + unsigned sr; + unsigned char id[1]; + + if (route_id_ptr > MAX_ROUTE_LENGTH) { + fatal(MYNAME ": Route %s too long\n", route->rte_name); + } + + src = (route_id_ptr + MAX_SUBROUTE_LENGTH) / MAX_SUBROUTE_LENGTH; + data = xmalloc(32 + src * 32); + + le_write16(data + 0, 0x2000); + data[2] = 0; + data[3] = 0x20; + strncpy((char *)data + 4, route->rte_name, 6); + data[18] = 0; + data[19] = 0; + le_write32(data + 20, 0); + le_write32(data + 24, 0); + le_write16(data + 28, 0); + data[30] = 0x7b; + data[31] = 0x77; + + for (sr = 0; sr < src; sr++) { + unsigned char *srdata = data + 32 + 32 * sr; + unsigned pt_offset = MAX_SUBROUTE_LENGTH * sr; + unsigned pt; + + le_write16(srdata + 0, 0x2010); + + for (pt = 0; pt < MAX_SUBROUTE_LENGTH; pt++) { + if (pt_offset + pt < route_id_ptr) { + le_write16(srdata + 2 + 2 * pt, route_ids[pt_offset + pt]); + } else { + le_write16(srdata + 2 + 2 * pt, 0xffffu); + } + } + + srdata[30] = 0x7f; + srdata[31] = 0x77; + } + + write_packet(PID_ADD_A_ROUTE, data, 32 + src * 32); + read_packet(PID_DATA, id, sizeof(id), sizeof(id)); + + xfree(data); + xfree(route_ids); +} + +static void +file_read(void) +{ + unsigned char data[32]; + route_head *track = NULL; + + while (gbfread(data, sizeof(data), 1, file_handle) == 1) { + switch (le_read16(data)) { + case 0x2000: + fatal(MYNAME ": Route objects not supported in file sources\n"); + break; + case 0x2010: + fatal(MYNAME ": Subroute objects not supported in file sources\n"); + break; + case 0x4000: + if (global_opts.masked_objective & WPTDATAMASK) { + waypt_add(decode_waypoint(data)); + } + break; + default: + if (global_opts.masked_objective & TRKDATAMASK) { + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + } + + track_add_wpt(track, decode_trackpoint(data)); + } + break; + } + } +} + +static void +file_write_waypoint(const waypoint *waypt) +{ + unsigned char data[32]; + + encode_waypoint(waypt, data); + gbfwrite(data, sizeof(data), 1, file_handle); +} + +static void +file_write_track_start(const route_head *track) +{ + track_serial = 1; +} + +static void +file_write_track_point(const waypoint *waypt) +{ + unsigned char data[32]; + + encode_trackpoint(waypt, track_serial++, data); + gbfwrite(data, sizeof(data), 1, file_handle); +} + +static void +file_write_track_end(const route_head *track) +{ +} + +static void +file_write_route_start(const route_head *track) +{ + fatal(MYNAME ": Can't write routes to a file\n"); +} + +static void +file_write_route_point(const waypoint *waypt) +{ +} + +static void +file_write_route_end(const route_head *track) +{ +} + +static void +navilink_common_init(const char *name, const char *mode) +{ + if (gbser_is_serial(name)) { + if ((serial_handle = gbser_init(name)) == NULL) { + fatal(MYNAME ": Could not open serial port %s\n", name); + } + + if (gbser_set_port(serial_handle, 115200, 8, 0, 1) != gbser_OK) { + fatal(MYNAME ": Can't configure port\n"); + } + + write_packet(PID_SYNC, NULL, 0); + read_packet(PID_ACK, NULL, 0, 0); + + if (nuketrk) { + unsigned char information[32]; + unsigned char data[7]; + + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, sizeof(information), sizeof(information)); + + le_write32(data + 0, le_read32(information + 4)); + le_write16(data + 4, 0); + data[6] = 0; + + write_packet(PID_ERASE_TRACK, data, sizeof(data)); + read_packet(PID_CMD_OK, NULL, 0, 0); + } + + if (nukerte) { + unsigned char data[4]; + + le_write32(data, 0x00f00000); + write_packet(PID_DEL_ALL_ROUTE, data, sizeof(data)); + read_packet(PID_CMD_OK, NULL, 0, 0); + } + + if (nukewpt) { + unsigned char data[4]; + + le_write32(data, 0x00f00000); + write_packet(PID_DEL_ALL_WAYPOINT, data, sizeof(data)); + read_packet(PID_ACK, NULL, 0, 0); + } + + write_waypoint = serial_write_waypoint; + write_track_start = serial_write_track_start; + write_track_point = serial_write_track_point; + write_track_end = serial_write_track_end; + write_route_start = serial_write_route_start; + write_route_point = serial_write_route_point; + write_route_end = serial_write_route_end; + } else { + file_handle = gbfopen(name, mode, MYNAME); + + write_waypoint = file_write_waypoint; + write_track_start = file_write_track_start; + write_track_point = file_write_track_point; + write_track_end = file_write_track_end; + write_route_start = file_write_route_start; + write_route_point = file_write_route_point; + write_route_end = file_write_route_end; + } + + return; +} + +static void +navilink_rd_init(const char *name) +{ + navilink_common_init(name, "r"); +} + +static void +navilink_wr_init(const char *name) +{ + navilink_common_init(name, "w+"); +} + +static void +navilink_deinit(void) +{ + if (serial_handle) { + if (poweroff) { + write_packet(PID_QUIT, NULL, 0); + } + + gbser_deinit(serial_handle); + } + + if (file_handle) { + gbfclose(file_handle); + } + + return; +} + +static void +navilink_read(void) +{ + if (serial_handle) { + waypoint **waypts = NULL; + + if (global_opts.masked_objective & (WPTDATAMASK|RTEDATAMASK)) { + waypts = serial_read_waypoints(); + } + + if (global_opts.masked_objective & TRKDATAMASK) { + serial_read_track(); + } + + if (global_opts.masked_objective & RTEDATAMASK) { + serial_read_routes(waypts); + } + + if (waypts) { + free_waypoints(waypts); + } + } else if (file_handle) { + file_read(); + } +} + +static void +navilink_write(void) +{ + switch (global_opts.objective) + { + case trkdata: + track_disp_all(write_track_start, + write_track_end, + write_track_point); + break; + case wptdata: + waypt_disp_all(write_waypoint); + break; + case rtedata: + if (serial_handle) { + route_waypts = serial_read_waypoints(); + } + route_disp_all(write_route_start, + write_route_end, + write_route_point); + if (route_waypts) { + free_waypoints(route_waypts); + route_waypts = NULL; + } + break; + default: + fatal(MYNAME ": Unknown objective.\n"); + } +} + +ff_vecs_t navilink_vecs = { + ff_type_serial, + FF_CAP_RW_ALL, + navilink_rd_init, + navilink_wr_init, + navilink_deinit, + navilink_deinit, + navilink_read, + navilink_write, + NULL, + navilink_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/netstumbler.c b/netstumbler.c new file mode 100644 index 000000000..1667e5154 --- /dev/null +++ b/netstumbler.c @@ -0,0 +1,323 @@ +/* + Read Netstumbler data files. + + Copyright (C) 2004, 2005 Robert Lipe, robertlipe@usa.net and + John Temples; gpsns@xargs.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "csv_util.h" +#include + +static gbfile *file_in; +static char *nseicon = NULL; +static char *nsneicon = NULL; +static char *seicon = NULL; +static char *sneicon = NULL; +static char *snmac = NULL; +static int macstumbler; + +static void fix_netstumbler_dupes(void); + +#define MYNAME "NETSTUMBLER" + +static +arglist_t netstumbler_args[] = { + {"nseicon", &nseicon, "Non-stealth encrypted icon name", + "Red Square", ARGTYPE_STRING, ARG_NOMINMAX }, + {"nsneicon", &nsneicon, "Non-stealth non-encrypted icon name", + "Green Square", ARGTYPE_STRING, ARG_NOMINMAX }, + {"seicon", &seicon, "Stealth encrypted icon name", + "Red Diamond", ARGTYPE_STRING, ARG_NOMINMAX }, + {"sneicon", &sneicon, "Stealth non-encrypted icon name", + "Green Diamond", ARGTYPE_STRING, ARG_NOMINMAX }, + {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static void +rd_init(const char *fname) +{ + file_in = gbfopen(fname, "rb", MYNAME); + macstumbler = 0; +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +data_read(void) +{ + char *ibuf; + char ssid[2 + 32 + 2 + 1]; /* "( " + SSID + " )" + null */ + char mac[2 + 17 + 2 + 1]; /* "( " + MAC + " )" + null */ + char desc[sizeof ssid - 1 + 15 + 1]; /* room for channel/speed */ + double lat = 0, lon = 0; + waypoint *wpt_tmp; + int line_no = 0; + int stealth_num = 0, whitespace_num = 0; + long flags = 0; + int speed = 0, channel = 0; + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + while ((ibuf = gbfgetstr(file_in))) { + char *field; + int field_num, len, i, stealth = 0; + + ibuf = lrtrim(ibuf); + /* A sharp in column zero might be a comment. Or it might be + * something useful, like the date. + */ + + if (ibuf[0] == '#') { + if (strncmp(&ibuf[2], "$DateGMT:", 9) == 0) { + tm.tm_year = atoi(&ibuf[12]) - 1900; + tm.tm_mon = atoi(&ibuf[17]) - 1; + tm.tm_mday = atoi(&ibuf[20]); + } + + /* + * Mac stumbler files are the same, except + * use DDMM.mmm instad of DD.DDDD. + */ + if (strstr(ibuf, "Creator: MacStumbler")) { + macstumbler = 1; + } + + continue; + } + + field_num = 0; + line_no++; + field = csv_lineparse(ibuf, "\t", "", line_no); + + while (field) { + switch (field_num) { + case 0: /* lat */ + lat = atof(&field[2]); + if (field[0] == 'S') + lat = -lat; + if (macstumbler) { + lat = ddmm2degrees(lat); + } + break; + + case 1: /* long */ + lon = atof(&field[2]); + if (field[0] == 'W') + lon = -lon; + if (macstumbler) { + lon = ddmm2degrees(lon); + } + break; + + case 2: /* ( SSID ) */ + strcpy(ssid, &field[2]); /* zap "( " */ + len = strlen(ssid) - 2; + ssid[len] = 0; /* zap " )" */ + stealth = (len == 0); + /* don't alter SSID in snmac mode */ + if (!snmac) { + int found = 0; + /* check for all whitespace */ + for (i = 0; i < len && !found; i++) { + if (!isspace(ssid[i])) + found = 1; + } + + if (!stealth && !found) + snprintf(ssid, sizeof ssid, "Whitespace/%d", ++whitespace_num); + } + break; + + case 4: /* ( MAC address ) */ + strcpy(mac, &field[2]); /* zap "( " */ + mac[strlen(mac) - 2] = 0;/* zap " )" */ + break; + + case 5: /* time */ + tm.tm_hour = atoi(field); + tm.tm_min = atoi(&field[3]); + tm.tm_sec = atoi(&field[6]); + break; + + case 8: /* flags */ + flags = strtol(field, NULL, 16); + break; + + case 11: /* data rate */ + speed = atoi(field) / 10; + break; + + case 12: /* last channel */ + channel = atoi(field); + break; + + case 3: /* type */ + case 6: /* SNR/sig/noise */ + case 7: /* name */ + case 9: /* channel bits */ + case 10: /* beacon interval */ + default: + break; + } + + field_num++; + field = csv_lineparse(NULL, "\t", "", line_no); + } + + if (lat == 0 && lon == 0) /* skip records with no GPS data */ + continue; + + wpt_tmp = waypt_new(); + + if (stealth) { + if (!snmac) + snprintf(ssid, sizeof ssid, "Stealth/%d", ++stealth_num); + + if (flags & 0x0010) /* encrypted? */ + wpt_tmp->icon_descr = seicon; + else + wpt_tmp->icon_descr = sneicon; + } else { + if (flags & 0x0010) /* encrypted? */ + wpt_tmp->icon_descr = nseicon; + else + wpt_tmp->icon_descr = nsneicon; + } + + if (snmac) { + snprintf(desc, sizeof desc, "%s/%d Mbps/Ch %d", ssid, speed, channel); + wpt_tmp->shortname = xstrdup(mac); + } else { + snprintf(desc, sizeof desc, "%d Mbps/Ch %d/%s", speed, channel, mac); + wpt_tmp->shortname = xstrdup(ssid); + } + + wpt_tmp->description = xstrdup(desc); + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + wpt_tmp->creation_time = mktime(&tm); + + waypt_add(wpt_tmp); + } + fix_netstumbler_dupes(); +} + +typedef struct +{ + unsigned long crc; + waypoint *wpt; +} htable_t; + +static +int +compare(const void *a, const void *b) +{ + unsigned long crc_a = ((const htable_t *)a)->crc; + unsigned long crc_b = ((const htable_t *)b)->crc; + + /* we can't just return crc_a - crc_b because the return type is + * signed. + * */ + + if (crc_a < crc_b) + return -1; + else if (crc_a > crc_b) + return 1; + else { + /* CRCs are equal; we need to subsort on the description (which + * includes the MAC address) to guarantee the same ordering of + * the output for any qsort() implementation. this is strictly + * to make the testo script happy. + * */ + + waypoint *wpt_a = ((const htable_t *)a)->wpt; + waypoint *wpt_b = ((const htable_t *)b)->wpt; + + return strcmp(wpt_a->description, wpt_b->description); + } +} + +/* netstumbler data will have a lot of duplicate shortnames if the SSID + * is used as the shortname (the default). salvage the dupes by + * synthesizing a (hopefully) unique shortname. + * */ + +static +void +fix_netstumbler_dupes(void) +{ + int i, ct = waypt_count(), serial = 0; + htable_t *htable, *bh; + queue *elem, *tmp; + extern queue waypt_head; + const char *snptr; + char *tmp_sn; + unsigned long last_crc; + char ssid[32 + 5 + 1]; + + htable = (htable_t *) xmalloc(ct * sizeof *htable); + bh = htable; + + i = 0; + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + bh->wpt = (waypoint *) elem; + snptr = bh->wpt->shortname; + tmp_sn = strlower(xstrdup(snptr)); + bh->crc = get_crc32(tmp_sn, strlen(snptr)); + xfree(tmp_sn); + i ++; + bh ++; + } + + qsort(htable, ct, sizeof *htable, compare); + + last_crc = htable[0].crc + 1; /* force mismatch */ + + for (i = 0, bh = htable; i < ct; i++, bh++) { + if (last_crc == bh->crc) { + snprintf(ssid, sizeof ssid, "%s/%d", bh->wpt->shortname, ++serial); + xfree(bh->wpt->shortname); + bh->wpt->shortname = xstrdup(ssid); + } else + last_crc = bh->crc; + } + + xfree(htable); +} + +ff_vecs_t netstumbler_vecs = { + ff_type_file, + { ff_cap_read, ff_cap_none, ff_cap_none }, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + netstumbler_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/nmea.c b/nmea.c new file mode 100644 index 000000000..5324f7fab --- /dev/null +++ b/nmea.c @@ -0,0 +1,1377 @@ +/* + Read files containing selected NMEA 0183 sentences. + Based on information by Eino Uikkanenj + + Copyright (C) 2004-2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include + +#include "defs.h" +#include "gbser.h" +#include "strptime.h" +#include "jeeps/gpsmath.h" + +/********************************************************** + + ' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + ' $GPGGA - Global Positioning System Fix Data + ' $GPGGA,155537,6006.718,N,02426.290,E,1,05,2.4,50.5,M,19.7,M,,*79 + ' 2 123519 Fix taken at 12:35:19 UTC + ' 3,4 4807.038,N Latitude 48 deg 07.038' N + ' 5,6 01131.324,E Longitude 11 deg 31.324' E + ' 7 1 Fix quality: 0 = invalid + ' 1 = GPS fix + ' 2 = DGPS fix + ' 8 08 Number of satellites being tracked + ' 9 0.9 Horizontal dilution of position + ' 10,11 545.4,M Altitude, Metres, above mean sea level + ' 12,13 46.9,M Height of geoid (mean sea level) above WGS84 ellipsoid + ' 14 (empty field) time in seconds since last DGPS update + ' 15 (empty field) DGPS station ID number + + ' $GPWPL - waypoint location + ' $GPWPL,4917.16,N,12310.64,W,003*65 + ' 2,3 4917.16,N Latitude of waypoint + ' 4,5 12310.64,W Longitude of waypoint + ' 6 003 Waypoint ID + + ' $GPGLL - Geographic position, Latitude and Longitude + ' $GPGLL,4916.45,N,12311.12,W,225444,A + ' 2,3 4916.46,N Latitude 49 deg. 16.45 min. North + ' 4,5 12311.12,W Longitude 123 deg. 11.12 min. West + ' 6 225444 Fix taken at 22:54:44 UTC + ' 7 A Data valid + + ' $GPRMC - Recommended minimum specific GNSS Data + ' $GPRMC,085721.194,A,5917.7210,N,01103.9227,E,21.42,50.33,300504,,*07 + ' 2 085721 Fix taken at 08:57:21 UTC + ' 3 A Fix valid (this field reads V if fix is not valid) + ' 4,5 5917.7210,N Latitude 59 deg 17.7210' N + ' 6,7 01103.9227,E Longitude 11 deg 03.9227' E + ' 8 21.42 Speed over ground (knots) + ' 9 50.33 Course over ground (true) + ' 10 300504 Date 30/05-2004 + ' 11 Empty field Magnetic variation + + GSA - GPS DOP and active satellites + $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39 + A Auto selection of 2D or 3D fix (M = manual) + 3 3D fix + 04,05... PRNs of satellites used for fix (space for 12) + 2.5 PDOP (dilution of precision) + 1.3 Horizontal dilution of precision (HDOP) + 2.1 Vertical dilution of precision (VDOP) + DOP is an indication of the effect of satellite geometry on + the accuracy of the fix. + + VTG - Track made good and ground speed + $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K + 054.7,T True track made good + 034.4,M Magnetic track made good + 005.5,N Ground speed, knots + 010.2,K Ground speed, Kilometers per hour + + WPL - waypoint location + $GPWPL,4917.16,N,12310.64,W,003*65 + 4917.16,N Latitude of waypoint + 12310.64,W Longitude of waypoint + 003 Waypoint ID + When a route is active, this sentence is sent once for each + waypoint in the route, in sequence. When all waypoints have + been reported, GPR00 is sent in the next data set. In any + group of sentences, only one WPL sentence, or an R00 + sentence, will be sent. + + + ' The optional checksum field consists of a "*" and two hex digits repre- + ' senting the exclusive OR of all characters between, but not including, + ' the "$" and "*". A checksum is required on some sentences. + +****************************************/ + +/* + * An input file may have both GGA and GLL and RMC sentences for the exact + * same position fix. If we see a single GGA, start ignoring GLL's and RMC's. + * GLL's will also be ignored if RMC's are found and GGA's not found. + */ + +/* +Zmarties notes: + +In practice, all fields of the NMEA sentences should be treated as optional - +if the data is not available, then the field can be omitted (hence leading +to the output of two consecutive commas). + +An NMEA recording can start anywhere in the stream of data. It is therefore +necessary to discard sentences until sufficient data has been processed to +have all the necessary data to construct a waypoint. In practice, this means +discarding data until we have had the first sentence that provides the date. +(We could scan forwards in the stream of data to find the first date, and +then back apply it to all previous sentences, but that is probably more +complexity that is necessary - the lost of one waypoint at the start of the +stream can normally be tolerated.) + +If a sentence is received without a checksum, but previous sentences have +had checksums, it is best to discard that sentence. In practice, the only +time I have seen this is when the recording stops suddenly, where the last +sentence is truncated - and missing part of the line, including the checksum. +*/ + +typedef enum { + gp_unknown = 0, + gpgga, + gplgll, + gprmc +} preferred_posn_type; + +enum { + rm_unknown = 0, + rm_serial, + rm_file +} read_mode; + +static gbfile *file_in, *file_out; +static route_head *trk_head; +static short_handle mkshort_handle; +static preferred_posn_type posn_type; +static struct tm tm; +static waypoint *curr_waypt; +static waypoint *last_waypt; +static void * gbser_handle; +static const char *posn_fname; +static queue pcmpt_head; + +static int without_date; /* number of created trackpoints without a valid date */ +static struct tm opt_tm; /* converted "date" parameter */ + +#define MYNAME "nmea" + +static char *opt_gprmc; +static char *opt_gpgga; +static char *opt_gpvtg; +static char *opt_gpgsa; +static char *snlenopt; +static char *optdate; +static char *getposnarg; +static char *opt_sleep; +static char *opt_baud; +static char *opt_append; +static char *opt_gisteq; + +static long sleepus; +static int getposn; +static int append_output; + +static time_t last_time; +static double last_read_time; /* Last timestamp of GGA or PRMC */ +static int datum; + +static waypoint * nmea_rd_posn(posn_status *); +static void nmea_rd_posn_init(const char *fname); + +arglist_t nmea_args[] = { + {"snlen", &snlenopt, "Max length of waypoint name to write", "6", ARGTYPE_INT, "1", "64" }, + {"gprmc", &opt_gprmc, "Read/write GPRMC sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpgga", &opt_gpgga, "Read/write GPGGA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpvtg", &opt_gpvtg, "Read/write GPVTG sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpgsa", &opt_gpgsa, "Read/write GPGSA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + { "get_posn", &getposnarg, "Return current position as a waypoint", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"pause", &opt_sleep, "Decimal seconds to pause between groups of strings", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"append_positioning", &opt_append, "Append realtime positioning data to the output file instead of truncating", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"baud", &opt_baud, "Speed in bits per second of serial port (baud=4800)", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"gisteq", &opt_gisteq, "Write tracks for Gisteq Phototracker", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +#define CHECK_BOOL(a) if (a && (*a == '0')) a = NULL + +/* + * Slightly different than the Magellan checksum fn. + */ +int +nmea_cksum(const char *const buf) +{ + int x = 0 ; + const char *p; + + for (p = buf; *p; p++) { + x ^= *p; + } + return x; +} + +static void +nmea_add_wpt(waypoint *wpt, route_head *trk) +{ + if (datum != DATUM_WGS84) { + double lat, lon, alt; + GPS_Math_Known_Datum_To_WGS84_M( + wpt->latitude, wpt->longitude, 0, + &lat, &lon, &alt, datum); + wpt->latitude = lat; + wpt->longitude = lon; + } + if (trk != NULL) track_add_wpt(trk, wpt); + else waypt_add(wpt); +} + +static void +nmea_release_wpt(waypoint *wpt) +{ + if (wpt && ((wpt->Q.next == NULL) || (wpt->Q.next == &wpt->Q))) { + /* This waypoint isn't queued. + Release it, because we don't have any reference to this + waypoint (! memory leak !) */ + waypt_free(wpt); + } +} + +static void +nmea_rd_init(const char *fname) +{ + curr_waypt = NULL; + last_waypt = NULL; + last_time = -1; + datum = DATUM_WGS84; + + CHECK_BOOL(opt_gprmc); + CHECK_BOOL(opt_gpgga); + CHECK_BOOL(opt_gpvtg); + CHECK_BOOL(opt_gpgsa); + + QUEUE_INIT(&pcmpt_head); + + if (getposnarg) { + getposn = 1; + } + + /* A special case hack that gets our current position and returns + * it as one waypoint. + */ + if (getposn) { + waypoint *wpt; + posn_status st; + nmea_rd_posn_init(fname); + wpt = nmea_rd_posn(&st); + if (!wpt) { + return; + } + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup("Position"); + nmea_add_wpt(wpt, NULL); + return; + } + + read_mode = rm_file; + file_in = gbfopen(fname, "rb", MYNAME); +} + +static void +nmea_rd_deinit(void) +{ + switch(read_mode) { + case rm_serial: + gbser_deinit(gbser_handle); + break; + case rm_file: + gbfclose(file_in); + file_in = NULL; + break; + default: + fatal("nmea_rd_deinit: illegal read_mode.\n"); + break; + } +} + +static void +nmea_wr_init(const char *portname) +{ + CHECK_BOOL(opt_gprmc); + CHECK_BOOL(opt_gpgga); + CHECK_BOOL(opt_gpvtg); + CHECK_BOOL(opt_gpgsa); + + append_output = atoi(opt_append); + + file_out = gbfopen(portname, append_output ? "a+" : "w+", MYNAME); + + sleepus = -1; + if ( opt_sleep ) { + if ( *opt_sleep ) { + sleepus = 1e6 * atof(opt_sleep); + } + else { + sleepus = -1; + } + } + + mkshort_handle = mkshort_new_handle(); + setshort_length(mkshort_handle, atoi(snlenopt)); + + if (opt_gisteq) { + opt_gpgga = NULL; + opt_gpvtg = NULL; + opt_gpgsa = NULL; + } +} + +static void +nmea_wr_deinit(void) +{ + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); +} + +static void +nmea_set_waypoint_time(waypoint *wpt, struct tm *time, int microseconds) +{ + if (time->tm_year == 0) + { + wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use == 0) + { + wpt->wpt_flags.fmt_use = 1; + without_date++; + } + } + else + { + wpt->creation_time = mkgmtime(time); + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use != 0) + { + wpt->wpt_flags.fmt_use = 0; + without_date--; + } + } +} + +static void +gpgll_parse(char *ibuf) +{ + double latdeg, lngdeg, microseconds; + char lngdir, latdir; + double hmsd; + int hms; + char valid = 0; + waypoint *waypt; + + if (trk_head == NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + } + + sscanf(ibuf,"$GPGLL,%lf,%c,%lf,%c,%lf,%c,", + &latdeg,&latdir, + &lngdeg,&lngdir, + &hmsd,&valid); + + if (valid != 'A') + return; + + hms = (int) hmsd; + microseconds = MILLI_TO_MICRO(1000 * (hmsd - hms)); + + tm.tm_sec = hms % 100; + hms = hms / 100; + tm.tm_min = hms % 100; + hms = hms / 100; + tm.tm_hour = hms % 100; + + last_read_time = hms; + + waypt = waypt_new(); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') latdeg = -latdeg; + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') lngdeg = -lngdeg; + waypt->longitude = ddmm2degrees(lngdeg); + + nmea_release_wpt(curr_waypt); + curr_waypt = waypt; +} + +static void +gpgga_parse(char *ibuf) +{ + double latdeg, lngdeg; + char lngdir, latdir; + double hms; + double alt; + int fix = fix_unknown; + int nsats = 0; + double hdop; + char altunits; + waypoint *waypt; + double microseconds; + + if (trk_head == NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + } + + sscanf(ibuf,"$GPGGA,%lf,%lf,%c,%lf,%c,%d,%d,%lf,%lf,%c", + &hms, &latdeg,&latdir, + &lngdeg,&lngdir, + &fix,&nsats,&hdop,&alt,&altunits); + + /* + * In serial mode, allow the fix with an invalid position through + * as serial units will often spit a remembered position up and + * that is more comfortable than nothing at all... + */ + if ((fix == 0) && (read_mode != rm_serial)) { + return; + } + + last_read_time = hms; + microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + waypt = waypt_new(); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') latdeg = -latdeg; + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') lngdeg = -lngdeg; + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->altitude = alt; + + waypt->sat = nsats; + + waypt->hdop = hdop; + + switch (fix) { + case 0: + waypt->fix = fix_none; + break; + case 1: + waypt->fix = (nsats>3)?(fix_3d):(fix_2d); + break; + case 2: + waypt->fix = fix_dgps; + break; + case 3: + waypt->fix = fix_pps; + break; + } + + nmea_release_wpt(curr_waypt); + curr_waypt = waypt; +} + +static void +gprmc_parse(char *ibuf) +{ + double latdeg, lngdeg; + char lngdir, latdir; + double hms; + char fix; + unsigned int dmy; + double speed,course; + waypoint *waypt; + double microseconds; + + if (trk_head == NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + } + + sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf,%u", + &hms, &fix, &latdeg, &latdir, + &lngdeg, &lngdir, + &speed, &course, &dmy); + + if (fix != 'A') { + /* ignore this fix - it is invalid */ + return; + } + + last_read_time = hms; + microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + tm.tm_year = dmy % 100 + 100; + dmy = dmy / 100; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy; + + if (posn_type == gpgga) { + /* capture useful data update and exit */ + if (curr_waypt) { + if (! WAYPT_HAS(curr_waypt, speed)) + WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed)); + if (! WAYPT_HAS(curr_waypt, course)) + WAYPT_SET(curr_waypt, course, course); + /* The change of date wasn't recorded when + * going from 235959 to 000000. */ + nmea_set_waypoint_time(curr_waypt, &tm, microseconds); + } + return; + } + + waypt = waypt_new(); + + WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed)); + + WAYPT_SET(waypt, course, course); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') latdeg = -latdeg; + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') lngdeg = -lngdeg; + waypt->longitude = ddmm2degrees(lngdeg); + + nmea_release_wpt(curr_waypt); + curr_waypt = waypt; +} + +static void +gpwpl_parse(char *ibuf) +{ + waypoint *waypt; + double latdeg, lngdeg; + char latdir, lngdir; + char sname[99]; + + sscanf(ibuf,"$GPWPL,%lf,%c,%lf,%c,%[^*]", + &latdeg,&latdir, + &lngdeg,&lngdir, + sname); + + waypt = waypt_new(); + + if (latdir == 'S') latdeg = -latdeg; + waypt->latitude = ddmm2degrees(latdeg); + if (lngdir == 'W') lngdeg = -lngdeg; + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->shortname = xstrdup(sname); + + curr_waypt = NULL; /* waypoints won't be updated with GPS fixes */ + nmea_add_wpt(waypt, NULL); +} + +static void +gpzda_parse(char *ibuf) +{ + double hms; + int dd, mm, yy, lclhrs, lclmins; + + sscanf(ibuf,"$GPZDA,%lf,%d,%d,%d,%d,%d", + &hms, &dd, &mm, &yy, &lclhrs, &lclmins); + tm.tm_sec = (int) hms % 100; + tm.tm_min = (((int) hms - tm.tm_sec) / 100) % 100; + tm.tm_hour = (int) hms / 10000; + tm.tm_mday = dd; + tm.tm_mon = mm - 1; + tm.tm_year = yy - 1900; +} + +static void +gpgsa_parse(char *ibuf) +{ + char fixauto; + char fix; + int prn[12]; + int scn,cnt; + float pdop=0,hdop=0,vdop=0; + char* tok=0; + + memset(prn,0xff,sizeof(prn)); + + scn = sscanf(ibuf,"$GPGSA,%c,%c,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + &fixauto, &fix, + &prn[0],&prn[1],&prn[2],&prn[3],&prn[4],&prn[5], + &prn[6],&prn[7],&prn[8],&prn[9],&prn[10],&prn[11]); + + /* + sscanf has scanned all the leftmost elements + we'll rescan by skipping 15 commas to the dops + */ + tok = ibuf; + for (cnt=0;(tok)&&(cnt<15);cnt++) + { + tok = strchr(tok,','); + if (!tok) break; + tok++; + } + if (tok) sscanf(tok,"%f,%f,%f",&pdop,&hdop,&vdop); + + + if (curr_waypt) { + + if (curr_waypt->fix!=fix_dgps) { + if (fix=='3') curr_waypt->fix=fix_3d; + else if (fix=='2') curr_waypt->fix=fix_2d; + } + + curr_waypt->pdop = pdop; + curr_waypt->hdop = hdop; + curr_waypt->vdop = vdop; + + if (curr_waypt->sat <= 0) { + for (cnt=0;cnt<12;cnt++) + curr_waypt->sat += (prn[cnt]>0)?(1):(0); + } + } + +} + +static void +gpvtg_parse(char *ibuf) +{ + float course; + char ct; + float magcourse; + char cm; + double speed_n; + char cn; + double speed_k; + char ck; + + sscanf(ibuf,"$GPVTG,%f,%c,%f,%c,%lf,%c,%lf,%c", + &course,&ct,&magcourse,&cm,&speed_n,&cn,&speed_k,&ck); + + if (curr_waypt) { + WAYPT_SET(curr_waypt, course, course); + + if (speed_k>0) + WAYPT_SET(curr_waypt, speed, KPH_TO_MPS(speed_k)) + else + WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed_n)); + + } + +} + +/* + * AVMAP EKP-IV Tracks - a proprietary (and very weird) extended NMEA. + * https://sourceforge.net/tracker/?func=detail&atid=489478&aid=1640814&group_id=58972 + */ +static +double pcmpt_deg(int d) +{ + int deg; + double minutes; + + deg = d / 100000; + minutes = (((d / 100000.0) - deg) * 100) / 60.0; + return (double) deg + minutes; +} + +void +pcmpt_parse(char *ibuf) +{ + int i, j1, j2, j3, j4, j5, j6; + int lat, lon; + char altflag, u1, u2; + float alt, f1, f2; + char coords[20] = {0}; + int dmy, hms; + + dmy = hms = 0; + + sscanf(ibuf,"$PCMPT,%d,%d,%d,%c,%f,%d,%[^,],%d,%f,%d,%f,%c,%d,%c,%d", + &j1, &j2, &j3, &altflag, &alt, &j4, (char *) &coords, + &j5, &f1, &j6, &f2, &u1, &dmy, &u2, &hms); + + if (altflag == 'D' && curr_waypt && alt > 0) { + curr_waypt->altitude = alt /*+ 500*/; + return; + } + + /* + * There are a couple of different second line records, but we + * don't care about them. + */ + if (j2 != 1) { + return; + } + + sscanf(coords, "%d%n", &lat, &i); + if (coords[i] == 'S') lat = -lat; + sscanf(coords + i + 1, "%d%n", &lon, &i); + if (coords[i] == 'W') lon= -lon; + + if (lat || lon) { + curr_waypt = waypt_new(); + curr_waypt->longitude = pcmpt_deg(lon); + curr_waypt->latitude = pcmpt_deg(lat); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + tm.tm_year = dmy % 10000 - 1900; + dmy = dmy / 10000; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy; + nmea_set_waypoint_time(curr_waypt, &tm, 0); + ENQUEUE_HEAD(&pcmpt_head, &curr_waypt->Q); + } else { + queue *elem, *tmp; + route_head *trk_head; + + if (QUEUE_EMPTY(&pcmpt_head)) { + return; + } + + /* + * Since we oh-so-cleverly inserted points at the head, + * we can rip through the queue forward now to get our +` * handy-dandy reversing effect. + */ + trk_head = route_head_alloc(); + track_add_head(trk_head); + QUEUE_FOR_EACH(&pcmpt_head, elem, tmp) { + waypoint *wpt = (waypoint *) dequeue(elem); + nmea_add_wpt(wpt, trk_head); + } + } +} + +static void +nmea_fix_timestamps(route_head *track) +{ + if ((trk_head == NULL) || (without_date == 0)) return; + + if (tm.tm_year == 0) + { + queue *elem, *temp; + waypoint *prev = NULL; + time_t delta_tm; + + if (optdate == NULL) + { + warning(MYNAME ": No date found within track (all points dropped)!\n"); + warning(MYNAME ": Please use option \"date\" to preset a valid date for thoose tracks.\n"); + track_del_head(track); + return; + } + delta_tm = mkgmtime(&opt_tm); + + QUEUE_FOR_EACH(&track->waypoint_list, elem, temp) + { + waypoint *wpt = (waypoint *)elem; + + wpt->creation_time += delta_tm; + if ((prev != NULL) && (prev->creation_time > wpt->creation_time)) /* go over midnight ? */ + { + delta_tm += SECONDS_PER_DAY; + wpt->creation_time += SECONDS_PER_DAY; + } + prev = wpt; + } + } + else + { + time_t prev; + queue *elem; + + tm.tm_hour = 23; /* last date found */ + tm.tm_min = 59; + tm.tm_sec = 59; + + prev = mkgmtime(&tm); + + /* go backward through the track and complete timestamps */ + + for (elem = QUEUE_LAST(&track->waypoint_list); elem != &track->waypoint_list; elem=elem->prev) + { + waypoint *wpt = (waypoint *)elem; + + if (wpt->wpt_flags.fmt_use != 0) + { + time_t dt; + + wpt->wpt_flags.fmt_use = 0; /* reset flag */ + + dt = (prev / SECONDS_PER_DAY) * SECONDS_PER_DAY; + wpt->creation_time += dt; + if (wpt->creation_time > prev) + wpt->creation_time+=SECONDS_PER_DAY; + } + prev = wpt->creation_time; + } + } +} + +void +nmea_parse_one_line(char *ibuf) +{ + int had_checksum = 0; + char *ck; + int ckval, ckcmp; + char *tbuf = lrtrim(ibuf); + + /* + * GISTEQ PhotoTracker (stupidly) puts a bogus field in front + * of the line. Look for it and toss it. + */ + if (0 == strncmp(tbuf, "---,", 4)) tbuf += 4; + + if (*tbuf != '$') return; + + ck = strrchr(tbuf, '*'); + if (ck != NULL) { + *ck = '\0'; + ckval = nmea_cksum(&tbuf[1]); + *ck = '*'; + ck++; + sscanf(ck, "%2X", &ckcmp); + if (ckval != ckcmp) { +#if 0 + printf("ckval %X, %X, %s\n", ckval, ckcmp, ck); + printf("NMEA %s\n", tbuf); +#endif + return; + } + + had_checksum = 1; + } + else if (had_checksum) { + /* we have had a checksum on all previous sentences, but not on this + one, which probably indicates this line is truncated */ + had_checksum = 0; + return; + } + + /* @@@ zmarties: The parse routines all assume all fields are present, but + the NMEA format allows any field to be missed out if there is no data + for that field. Rather than change all the parse routines, we first + substitute a default value of zero for any missing field. + */ + if (strstr(tbuf, ",,")) + { + tbuf = gstrsub(tbuf, ",,", ",0,"); + } + + if (0 == strncmp(tbuf, "$GPWPL,", 7)) { + gpwpl_parse(tbuf); + } else + if (opt_gpgga && (0 == strncmp(tbuf, "$GPGGA,", 7))) { + posn_type = gpgga; + gpgga_parse(tbuf); + } else + if (opt_gprmc && (0 == strncmp(tbuf, "$GPRMC,", 7))) { + if (posn_type != gpgga) { + posn_type = gprmc; + } + /* + * Always call gprmc_parse() because like GPZDA + * it contains the full date. + */ + gprmc_parse(tbuf); + } else + if (0 == strncmp(tbuf, "$GPGLL,", 7)) { + if ((posn_type != gpgga) && (posn_type != gprmc)) { + gpgll_parse(tbuf); + } + } else + if (0 == strncmp(tbuf, "$GPZDA,",7)) { + gpzda_parse(tbuf); + } else + if (0 == strncmp(tbuf, "$PCMPT,", 7)) { + pcmpt_parse(tbuf); + } else + if (opt_gpvtg && (0 == strncmp(tbuf, "$GPVTG,",7))) { + gpvtg_parse(tbuf); /* speed and course */ + } else + if (opt_gpgsa && (0 == strncmp(tbuf, "$GPGSA,",7))) { + gpgsa_parse(tbuf); /* GPS fix */ + } + + if (tbuf != ibuf) { + /* clear up the dynamic buffer we used because substition was required */ + xfree(tbuf); + } +} + +static void +nmea_read(void) +{ + char *ibuf; + char *ck; + double lt = -1; + int line = -1; + + posn_type = gp_unknown; + trk_head = NULL; + without_date = 0; + memset(&tm, 0, sizeof(tm)); + opt_tm = tm; + + /* This was done in rd_init() */ + if (getposn) { + return; + } + + if (optdate) + { + memset(&opt_tm, 0, sizeof(opt_tm)); + + ck = (char *)strptime(optdate, "%Y%m%d", &opt_tm); + if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) + fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); + else if (opt_tm.tm_year < 70) + fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); + } + + curr_waypt = NULL; + + while ((ibuf = gbfgetstr(file_in))) { + char *sdatum, *cx; + + line++; + + if ((line == 0) && (case_ignore_strncmp(ibuf, "@SonyGPS/ver", 12) == 0)) { + /* special hack for Sony GPS-CS1 files: + they are fully (?) nmea compatible, but come with a header line like + "@Sonygps/ver1.0/wgs-84". */ + + /* Check the GPS datum */ + cx = strchr(&ibuf[12], '/'); + if (cx != NULL) { + sdatum = cx + 1; + datum = GPS_Lookup_Datum_Index(sdatum); + if (datum < 0) + fatal(MYNAME "/SonyGPS: Unsupported datum \"%s\" in source data!\n", sdatum); + } + continue; + } + + nmea_parse_one_line(ibuf); + if (lt != last_read_time && curr_waypt && trk_head) { + if (curr_waypt != last_waypt) { + nmea_add_wpt(curr_waypt, trk_head); + last_waypt = curr_waypt; + } + lt = last_read_time; + } + } + + /* try to complete date-less trackpoints */ + nmea_fix_timestamps(trk_head); +} + +void +nmea_rd_posn_init(const char *fname) +{ + if ((gbser_handle = gbser_init(fname)) != NULL) { + read_mode = rm_serial; + gbser_set_speed(gbser_handle, 4800); + } else { + fatal(MYNAME ": Could not open '%s' for position tracking.\n", fname); + } + + gbser_flush(gbser_handle); + + if (opt_baud) { + if (!gbser_set_speed(gbser_handle, atoi(opt_baud))) { + fatal(MYNAME ": Unable to set baud rate %s\n", opt_baud); + } + } + posn_fname = fname; +} + +static void +safe_print(int cnt, const char *b) +{ + int i; + for (i = 0; i < cnt; i++) { + char c = isprint(b[i]) ? b[i] : '.'; + fputc(c, stderr); + } +} + +static void reset_sirf_to_nmea(int br); + +static +int hunt_sirf(void) +{ + /* Try to place the common BR's first to speed searching */ + static int br[] = {38400, 9600, 57600, 115200, 19200, 4800, -1}; + static int *brp = &br[0]; + char ibuf[1024]; + + for (brp = br; *brp > 0; brp++) { + int rv; + if (global_opts.debug_level > 1) { + fprintf(stderr, "Trying %d\n", *brp); + } + + /* + * Cycle our port's data speed and spray the "change to NMEA + * mode to the device. + */ + gbser_set_speed(gbser_handle, *brp); + reset_sirf_to_nmea(*brp); + + rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), + 1000, 0x0a, 0x0d); + /* + * If we didn't get a read error but did get a string that + * started with a dollar sign, we're probably in NMEA mode + * now. + */ + if ((rv > -1) && (strlen(ibuf) > 0) && ibuf[0] == '$') { + return 1; + } + + /* + * If nothing was received, it's not a sirf part. Fast exit. + */ + if (rv < 0) { + return 0; + } + } + return 0; +} + +static waypoint * +nmea_rd_posn(posn_status *posn_status) +{ + char ibuf[1024]; + static double lt = -1; + int i; + int am_sirf = 0; + + /* + * Read a handful of sentences, collecting the best info we + * can. If the timestamp changes (indicating the sequence is + * about to restart and thus the one we're collecting isn't going + * to get any better than we now have) hand that back to the caller. + */ + + for (i = 0; i < 10; i++) { + int rv; + ibuf[0] = 0; + rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), 2000, 0x0a, 0x0d); + if (global_opts.debug_level > 1) { + safe_print(strlen(ibuf), ibuf); + } + if (rv < 0) { + if (am_sirf == 0) { + if (global_opts.debug_level > 1) { + warning(MYNAME ": Attempting sirf mode.\n"); + } + /* This is tacky, we have to change speed + * to 9600bps to tell it to speak NMEA at + * 4800. + */ + am_sirf = hunt_sirf(); + if (am_sirf) { + i = 0; + continue; + } + } + fatal(MYNAME ": No data received on %s.\n", posn_fname); + } + nmea_parse_one_line(ibuf); + if (lt != last_read_time) { + if (last_read_time) { + waypoint *w = curr_waypt; + + lt = last_read_time; + curr_waypt = NULL; + + return w; + } + } + } + return NULL; +} + +static void +nmea_wayptpr(const waypoint *wpt) +{ + char obuf[200]; + double lat,lon; + char *s; + int cksum; + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + if (global_opts.synthesize_shortnames) + s = mkshort_from_wpt(mkshort_handle, wpt); + else { + s = mkshort(mkshort_handle, wpt->shortname); + } + + snprintf(obuf, sizeof(obuf), "GPWPL,%08.3f,%c,%09.3f,%c,%s", + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', s + + ); + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + if (sleepus >= 0) { + gbfflush(file_out); + gb_sleep(sleepus); + } + + xfree(s); + +} + +void +nmea_track_init(const route_head *rte) +{ + last_time = -1; +} + +void +nmea_trackpt_pr(const waypoint *wpt) +{ + char obuf[200]; + char fix='0'; + double lat,lon; + int cksum; + struct tm *tm; + time_t hms; + time_t ymd; + + if ( opt_sleep ) { + gbfflush( file_out ); + if ( last_time > 0 ) { + if ( sleepus >= 0 ) { + gb_sleep( sleepus ); + } + else { + long wait_time = wpt->creation_time - last_time; + if ( wait_time > 0 ) { + gb_sleep( wait_time * 1000000 ); + } + } + } + last_time = wpt->creation_time; + } + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + + tm = gmtime(&wpt->creation_time); + if ( tm ) { + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; + ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; + } else { + hms = 0; + ymd = 0; + } + + switch (wpt->fix) + { + case fix_dgps: + fix='2'; + /* or */ + case fix_3d: + case fix_2d: + fix='1'; + break; + case fix_pps: + fix='3'; + break; + default: + fix='0'; + } + + if (opt_gprmc) { + snprintf(obuf, sizeof(obuf), "GPRMC,%010.3f,%c,%08.3f,%c,%09.3f,%c,%.2f,%.2f,%06d,,", + (double) hms + (wpt->microseconds / 1000000.0), + fix=='0' ? 'V' : 'A', + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0), + WAYPT_HAS(wpt, course) ? (wpt->course):(0), + (int) ymd); + cksum = nmea_cksum(obuf); + /* GISTeq doesn't care about the checksum */ + if (opt_gisteq) { + gbfprintf(file_out, "---,"); + } + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + if (opt_gpgga) { + snprintf(obuf, sizeof(obuf), "GPGGA,%010.3f,%08.3f,%c,%09.3f,%c,%c,%02d,%.1f,%.3f,M,0.0,M,,", + (double) hms + (wpt->microseconds / 1000000.0), + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + fix, + (wpt->sat>0)?(wpt->sat):(0), + (wpt->hdop>0)?(wpt->hdop):(0.0), + wpt->altitude == unknown_alt ? 0 : wpt->altitude); + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + if ((opt_gpvtg) && (WAYPT_HAS(wpt, course) || WAYPT_HAS(wpt, speed))) { + snprintf(obuf,sizeof(obuf),"GPVTG,%.3f,T,0,M,%.3f,N,%.3f,K", + WAYPT_HAS(wpt, course) ? (wpt->course):(0), + WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0), + WAYPT_HAS(wpt, speed) ? MPS_TO_KPH(wpt->speed):(0) ); + + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + + if ((opt_gpgsa) && (wpt->fix!=fix_unknown)) { + + switch (wpt->fix) + { + case fix_dgps: + /* or */ + case fix_3d: + fix='3'; + break; + case fix_2d: + fix='2'; + break; + default: + fix=0; + } + snprintf(obuf,sizeof(obuf),"GPGSA,A,%c,,,,,,,,,,,,,%.1f,%.1f,%.1f", + fix, + (wpt->pdop>0)?(wpt->pdop):(0), + (wpt->hdop>0)?(wpt->hdop):(0), + (wpt->vdop>0)?(wpt->vdop):(0) ); + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } +} + +static void +nmea_write(void) +{ + waypt_disp_all(nmea_wayptpr); + track_disp_all(nmea_track_init, NULL, nmea_trackpt_pr); +} + +static void +nmea_wr_posn_init(const char *fname) +{ + nmea_wr_init(fname); +} + +static void +nmea_wr_posn(waypoint *wpt) +{ + nmea_trackpt_pr(wpt); +} + +static void +nmea_wr_posn_deinit(void) +{ +// nmea_wr_deinit(); +} + + +ff_vecs_t nmea_vecs = { + ff_type_file, + { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_none}, + nmea_rd_init, + nmea_wr_init, + nmea_rd_deinit, + nmea_wr_deinit, + nmea_read, + nmea_write, + NULL, + nmea_args, + CET_CHARSET_ASCII, 0, /* CET-REVIEW */ + { nmea_rd_posn_init, nmea_rd_posn, nmea_rd_deinit, + nmea_wr_posn_init, nmea_wr_posn, nmea_wr_posn_deinit } +}; + +/* + * If we later decide to implement a "real" Sirf module, this code should + * go there. For now, we try a kind of heavy handed thing - if we don't + * see NMEA-isms from the device, we'll go on the premise that it MAY be + * a SiRF Star device and send it the "speak NMEA, please" command. + */ + +static void +sirf_write(unsigned char *buf) +{ + int i, chksum = 0; + int len = buf[2] << 8 | buf[3]; + + for (i = 0; i < len; i++) { + chksum += buf[4 + i]; + } + chksum &= 0x7fff; + + buf[len + 4] = chksum >> 8; + buf[len + 5] = chksum & 0xff; + + gbser_write(gbser_handle, buf, len + 8); /* 4 at front, 4 at back */ +} + +static +void reset_sirf_to_nmea(int br) +{ + static unsigned char pkt[] = {0xa0, 0xa2, 0x00, 0x18, + 0x81, 0x02, + 0x01, 0x01, /* GGA */ + 0x00, 0x00, /* suppress GLL */ + 0x01, 0x00, /* suppress GSA */ + 0x05, 0x00, /* suppress GSV */ + 0x01, 0x01, /* use RMC for date*/ + 0x00, 0x00, /* suppress VTG */ + 0x00, 0x01, /* output rate */ + 0x00, 0x01, /* unused recommended values */ + 0x00, 0x01, + 0x00, 0x01, /* ZDA */ + 0x12, 0xc0, /* 4800 bps */ + 0x00, 0x00, /* checksum */ + 0xb0, 0xb3}; /* packet end */ + /* repopulate bit rate */ + pkt[26] = br >> 8; + pkt[27] = br & 0xff; + + sirf_write(pkt); + gb_sleep(250 * 1000); + gbser_flush(gbser_handle); +} diff --git a/nmn4.c b/nmn4.c new file mode 100644 index 000000000..e608e373c --- /dev/null +++ b/nmn4.c @@ -0,0 +1,322 @@ + /* + + Support for Navigon Mobile Navigator .rte files. + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +/* + line structure, items delimited by '|' + +-|-|17|-|ZIP-Code|City|ZIP-Code2|Street|No.|-|-|longitude|latitude|-|-| + 0D0A + +*/ + +#include "defs.h" +#include "csv_util.h" +#include +#include +#include +#include + +static gbfile *fin, *fout; +static int curr_rte_num, target_rte_num; + +#define MYNAME "navigon" + +static char *index_opt; + +static +arglist_t nmn4_args[] = { + {"index", &index_opt, "Index of route to write (if more the one in source)", NULL, ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + + +/* helpers */ + +static char * +nmn4_concat(char *arg0, ...) +{ + va_list args; + char *src, *res; + + res = NULL; + va_start(args, arg0); + src = (char *)arg0; + + while (src != NULL) + { + char *c = lrtrim(src); + + if (*c != '\0') + { + if (res == NULL) + res = xstrdup(c); + else + { + res = xstrappend(res, " "); + res = xstrappend(res, c); + } + } + xfree(src); + src = va_arg(args, char *); + } + va_end(args); + + return res; +} + +static void +nmn4_check_line(char *line) +{ + char *c = line; + int i = 0; + while ((c = strchr(c, '|'))) + { + c++; + i++; + } + is_fatal((i != 15), + MYNAME ": Invalid or unknown structure!"); +} + +static void +nmn4_read_data(void) +{ + char *buff; + char *str, *c; + int column; + + char *zip1, *zip2, *city, *street, *number; + route_head *route; + waypoint *wpt; + + route = route_head_alloc(); + route_add_head(route); + + while ((buff = gbfgetstr(fin))) + { + str = buff = lrtrim(buff); + if (*buff == '\0') continue; + + nmn4_check_line(buff); + + /* for a quiet compiler */ + zip1 = zip2 = city = street = number = NULL; + + wpt = waypt_new(); + + column = -1; + c = csv_lineparse(str, "|", "", column++); + while (c != NULL) + { + switch(column) + { + case 0: /* "-" */ /* unknown fields for the moment */ + case 1: /* "-" */ + case 2: /* "-" */ + case 3: /* "-" */ + case 9: /* "-" */ + case 10: /* "-" */ + case 13: /* "-" */ + case 14: /* "-" */ + case 15: /* "" */ + break; + + case 4: /* ZIP Code */ + if (*c != '-') + zip1 = xstrdup(c); + else + zip1 = xstrdup(""); + break; + + case 5: /* City */ + if (*c != '-') + city = xstrdup(c); + else + city = xstrdup(""); + break; + + case 6: /* ZIP Code -2- */ + if (*c != '-') + zip2 = xstrdup(c); + else + zip2 = xstrdup(""); + break; + + case 7: /* Street */ + if (*c != '-') + street = xstrdup(c); + else + street = xstrdup(""); + break; + + case 8: /* Number */ + if (*c != '-') + number = xstrdup(c); + else + number = xstrdup(""); + + /* + This is our final index + All stuff for generating names or comments + is hold locally. + + We don't have fields for street, city or zip-code. + Instead we construct a description from that. + */ + + if (strcmp(zip1, zip2) == 0) *zip2 = '\0'; + if (*city != '\0') + { + /* + if any field following city has a value, add a comma to city + */ + if ((*street != '\0') || (*number != '\0') || (*zip2 != '\0')) + city = xstrappend(city, ","); + } + + /* concats all fields to one string and release */ + wpt->description = nmn4_concat(zip1, city, street, number, zip2, NULL); + break; + + case 11: /* longitude */ + sscanf(c, "%lf", &wpt->longitude); + break; + + case 12: /* latitude */ + sscanf(c, "%lf", &wpt->latitude); + break; + + } + c = csv_lineparse(NULL, "|", "", column++); + } + route_add_wpt(route, wpt); + } +} + +static void +nmn4_route_hdr(const route_head *route) +{ + curr_rte_num++; +} + +static void +nmn4_route_tlr(const route_head *rte) +{ +} + +static void +nmn4_write_waypt(const waypoint *wpt) +{ + char city[128], street[128], zipc[32], number[32]; + + if (curr_rte_num != target_rte_num) return; + + strncpy(city, "-", sizeof(city)); + strncpy(street, "-", sizeof(street)); + strncpy(zipc, "-", sizeof(zipc)); + strncpy(number, "-", sizeof(number)); + + /* + Population of specific data used by Navigon may come in the + future or it may be impossible. We currently output only the + coordinates in the output, but this is sufficient for Navigon. + + The coordinates are the only item we are about guaranteed to have + when converting to any from any format, so we leave the other + fields unpopulated. So i have to pay Navigon a compliment for + implementing a simple data exchange. + */ + + gbfprintf(fout, "-|-|-|-|%s|%s|%s|%s|%s|-|-|%.5f|%.5f|-|-|\r\n", + zipc, city, zipc, street, number, + wpt->longitude, wpt->latitude); +} + +static void +nmn4_write_data(void) +{ + + target_rte_num = 1; + + if (index_opt != NULL) + { + target_rte_num = atoi(index_opt); + is_fatal(((target_rte_num > (int) route_count()) || (target_rte_num < 1)), + MYNAME ": invalid route number %d (1..%d))!\n", target_rte_num, route_count()); + } + + curr_rte_num = 0; + route_disp_all(nmn4_route_hdr, nmn4_route_tlr, nmn4_write_waypt); +} + + +/* %%% global callbacks %%% */ + +static void +nmn4_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); +} + +static void +nmn4_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +nmn4_read(void) +{ + nmn4_read_data(); +} + +static void +nmn4_wr_init(const char *fname) +{ + fout = gbfopen(fname, "wb", MYNAME); +} + +static void +nmn4_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +nmn4_write(void) +{ + nmn4_write_data(); +} + +/* --------------------------------------------------------------------------- */ + +ff_vecs_t nmn4_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read | ff_cap_write}, + nmn4_rd_init, + nmn4_wr_init, + nmn4_rd_deinit, + nmn4_wr_deinit, + nmn4_read, + nmn4_write, + NULL, + nmn4_args, + CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ +}; diff --git a/nukedata.c b/nukedata.c new file mode 100644 index 000000000..6dc8fccbb --- /dev/null +++ b/nukedata.c @@ -0,0 +1,64 @@ +/* + + nukedata: remove all (waypoint|tracks|routes) from the stream. + + Copyright (C) 2005 Robert Lipe robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED +#define MYNAME "nukedata" + +static char *nukewpts, *nuketrks, *nukertes; + +static +arglist_t nuke_args[] = { + {"waypoints", &nukewpts, "Remove all waypoints from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX} , + {"tracks", &nuketrks, "Remove all tracks from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX} , + {"routes", &nukertes, "Remove all routes from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX} , + ARG_TERMINATOR +}; + +static void +nuke_process(void) +{ + if (*nukewpts != '0') { + waypt_flush_all(); + } + if (*nuketrks != '0') { + route_flush_all_tracks(); + } + if (*nukertes != '0') { + route_flush_all_routes(); + } +} + +filter_vecs_t nuke_vecs = { + NULL, + nuke_process, + NULL, + NULL, + nuke_args +}; + +#endif diff --git a/osm.c b/osm.c new file mode 100644 index 000000000..5c9ad7764 --- /dev/null +++ b/osm.c @@ -0,0 +1,926 @@ +/* + + Support for "OpenStreetMap" data files (.xml) + + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#include "defs.h" +#include "avltree.h" +#include "xmlgeneric.h" + +static char *opt_tag, *opt_tagnd; + +static arglist_t osm_args[] = +{ + { "tag", &opt_tag, "Write additional way tag key/value pairs", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "tagnd", &opt_tagnd, "Write additional node tag key/value pairs", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +#define MYNAME "osm" + +static avltree_t *waypoints; /* AVL tree */ + +static avltree_t *keys = NULL; +static avltree_t *values = NULL; +static avltree_t *icons = NULL; + +static gbfile *fout; +static int node_id; +static route_head *rte; +static int skip_rte; + +#if ! HAVE_LIBEXPAT + +void +osm_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded \" MYNAME \" support because expat was not installed.\n"); +} + +void +osm_read(void) +{ +} + +#else + +static waypoint *wpt; +static int wpt_loaded, rte_loaded; + +static xg_callback osm_node, osm_node_tag, osm_node_end; +static xg_callback osm_way, osm_way_nd, osm_way_tag, osm_way_end; + +static +xg_tag_mapping osm_map[] = { + { osm_node, cb_start, "/osm/node" }, + { osm_node_tag, cb_start, "/osm/node/tag" }, + { osm_node_end, cb_end, "/osm/node" }, + { osm_way, cb_start, "/osm/way" }, + { osm_way_nd, cb_start, "/osm/way/nd" }, + { osm_way_tag, cb_start, "/osm/way/tag" }, + { osm_way_end, cb_end, "/osm/way" }, + { NULL, 0, NULL } +}; + +static char *osm_features[] = { + "- dummy -", /* 0 */ + "aeroway", /* 1 */ + "amenity", /* 2 */ + "building", /* 3 */ + "cycleway", /* 4 */ + "railway", /* 5 */ + "highway", /* 6 */ + "historic", /* 7 */ + "landuse", /* 8 */ + "leisure", /* 9 */ + "man_made", /* 10 */ + "military", /* 11 */ + "natural", /* 12 */ + "place", /* 13 */ + "power", /* 14 */ + "shop", /* 15 */ + "sport", /* 16 */ + "tourism", /* 17 */ + "waterway", /* 18 */ + "aerialway", /* 19 */ + NULL +}; + +typedef struct osm_icon_mapping_s { + const int key; + const char *value; + const char *icon; +} osm_icon_mapping_t; + + +/* based on */ + +static osm_icon_mapping_t osm_icon_mappings[] = { + + /* cycleway ...*/ + + /* highway ...*/ + +// { 6, "mini_roundabout", "?" }, +// { 6, "stop", "?" }, +// { 6, "traffic_signals", "?" }, +// { 6, "crossing", "?" }, +// { 6, "gate", "?" }, +// { 6, "stile", "?" }, +// { 6, "cattle_grid", "?" }, +// { 6, "toll_booth", "?" }, +// { 6, "incline", "?" }, +// { 6, "incline_steep", "?" }, +// { 6, "viaduct", "?" }, +// { 6, "motorway_junction", "?" }, +// { 6, "services", "?" }, +// { 6, "ford", "?" }, +// { 6, "bus_stop", "?" }, +// { 6, "turning_circle", "?" }, +// { 6, "User Defined", "?" }, + + /* waterway ... */ + + { 18, "dock", "Dock" }, +// { 18, "lock_gate", "?" }, +// { 18, "turning_point", "?" }, +// { 18, "aqueduct", "?" }, +// { 18, "boatyard", "?" }, +// { 18, "water_point", "?" }, +// { 18, "waste_disposal", "?" }, +// { 18, "mooring", "?" }, +// { 18, "weir", "?" }, +// { 18, "User Defined", "?" }, + + /* railway ... */ + +// { 5, "station", "?" }, +// { 5, "halt", "?" }, +// { 5, "tram_stop", "?" }, +// { 5, "viaduct", "?" }, + { 5, "crossing", "Crossing" }, +// { 5, "level_crossing", "?" }, +// { 5, "subway_entrance", "?" }, +// { 5, "turntable", "?" }, +// { 5, "User Defined", "?" }, + + /* aeroway ... */ + + { 1, "aerodrome", "Airport" }, + { 1, "terminal", "Airport" }, + { 1, "helipad", "Heliport" }, +// { 1, "User Defined", "?" }, + + /* aerialway ... */ + +// { 19, "User Defined", "?" }, + + /* power ... */ + +// { 14, "tower", "?" }, +// { 14, "sub_station", "?" }, +// { 14, "generator", "?" }, + + /* man_made ... */ + +// { 10, "works", "?" }, +// { 10, "beacon", "?" }, +// { 10, "survey_point", "?" }, +// { 10, "power_wind", "?" }, +// { 10, "power_hydro", "?" }, +// { 10, "power_fossil", "?" }, +// { 10, "power_nuclear", "?" }, +// { 10, "tower", "?" }, +// { 10, "water_tower", "?" }, +// { 10, "gasometer", "?" }, +// { 10, "reservoir_covered", "?" }, +// { 10, "lighthouse", "?" }, +// { 10, "windmill", "?" }, +// { 10, "wastewater_plant", "?" }, +// { 10, "crane", "?" }, +// { 10, "User Defined", "?" }, + + /* building ... */ + + { 3, "yes", "Building" }, +// { 3, "User Defined", "?" }, + + /* leisure ... */ + +// { 9, "sports_centre", "?" }, + { 9, "golf_course", "Golf Course" }, + { 9, "stadium", "Stadium" }, +// { 9, "track", "?" }, +// { 9, "pitch", "?" }, +// { 9, "water_park", "?" }, + { 9, "marina", "Marina" }, +// { 9, "slipway", "?" }, + { 9, "fishing", "Fishing Area" }, +// { 9, "nature_reserve", "?" }, + { 9, "park", "Park" }, +// { 9, "playground", "?" }, +// { 9, "garden", "?" }, +// { 9, "common", "?" }, +// { 9, "User Defined", "?" }, + + /* amenity ... */ + + { 2, "pub", "Bar" }, +// { 2, "biergarten", "?" }, + { 2, "nightclub", "Bar" }, +// { 2, "cafe", "?" }, + { 2, "restaurant", "Restaurant" }, + { 2, "fast_food", "Fast Food" }, + { 2, "parking", "Parking Area" }, +// { 2, "bicycle_parking", "?" }, +// { 2, "bicycle_rental", "?" }, + { 2, "car_rental", "Car Rental" }, +// { 2, "car_sharing", "?" }, +// { 2, "taxi", "?" }, + { 2, "fuel", "Gas Station" }, + { 2, "telephone", "Telephone" }, + { 2, "toilets", "Restroom" }, +// { 2, "recycling", "?" }, +// { 2, "public_building", "?" }, + { 2, "townhall", "City Hall" }, +// { 2, "place_of_worship", "?" }, +// { 2, "grave_yard", "?" }, + { 2, "post_office", "Post Office" }, +// { 2, "post_box", "?" }, + { 2, "school", "School" }, +// { 2, "university", "?" }, +// { 2, "college", "?" }, + { 2, "pharmacy", "Pharmacy" }, + { 2, "hospital", "Medical Facility" }, +// { 2, "library", "?" }, + { 2, "police", "Police Station" }, +// { 2, "fire_station", "?" }, +// { 2, "bus_station", "?" }, +// { 2, "theatre", "?" }, +// { 2, "cinema", "?" }, +// { 2, "arts_centre", "?" }, +// { 2, "courthouse", "?" }, +// { 2, "prison", "?" }, + { 2, "bank", "Bank" }, +// { 2, "bureau_de_change", "?" }, +// { 2, "atm", "?" }, +// { 2, "fountain", "?" }, +// { 2, "User Defined", "?" }, + + /* shop ... */ + +// { 15, "supermarket", "?" }, + { 15, "convenience", "Convenience Store" }, +// { 15, "butcher", "?" }, +// { 15, "bicycle", "?" }, +// { 15, "doityourself", "?" }, +// { 15, "dry_cleaning", "?" }, +// { 15, "laundry", "?" }, +// { 15, "outdoor", "?" }, +// { 15, "kiosk", "?" }, +// { 15, "User Defined", "?" }, + + /* tourism ... */ + + { 17, "information", "Information" }, + { 17, "hotel", "Hotel" }, + { 17, "motel", "Lodging" }, + { 17, "guest_house", "Lodging" }, + { 17, "hostel", "Lodging" }, + { 17, "camp_site", "Campground" }, + { 17, "caravan_site", "RV Park" }, + { 17, "picnic_site", "Picnic Area" }, + { 17, "viewpoint", "Scenic Area" }, +// { 17, "theme_park", "?" }, +// { 17, "attraction", "?" }, + { 17, "zoo", "Zoo" }, +// { 17, "artwork", "?" }, + { 17, "museum", "Museum" }, +// { 17, "User Defined", "?" }, + + /* historic ... */ + +// { 7, "castle", "?" }, +// { 7, "monument", "?" }, +// { 7, "memorial", "?" }, +// { 7, "archaeological_site", "?" }, +// { 7, "ruins", "?" }, +// { 7, "battlefield", "?" }, +// { 7, "User Defined", "?" }, + + /* landuse ... */ + +// { 8, "farm", "?" }, +// { 8, "quarry", "?" }, +// { 8, "landfill", "?" }, +// { 8, "basin", "?" }, +// { 8, "reservoir", "?" }, + { 8, "forest", "Forest" }, +// { 8, "allotments", "?" }, +// { 8, "residential", "?" }, +// { 8, "retail", "?" }, +// { 8, "commercial", "?" }, +// { 8, "industrial", "?" }, +// { 8, "brownfield", "?" }, +// { 8, "greenfield", "?" }, +// { 8, "railway", "?" }, +// { 8, "construction", "?" }, + { 8, "military", "Military" }, + { 8, "cemetery", "Cemetery" }, +// { 8, "village_green", "?" }, +// { 8, "recreation_ground", "?" }, +// { 8, "User Defined", "?" }, + + /* military ... */ + +// { 11, "airfield", "?" }, +// { 11, "bunker", "?" }, +// { 11, "barracks", "?" }, +// { 11, "danger_area", "?" }, +// { 11, "range", "?" }, +// { 11, "naval_base", "?" }, +// { 11, "User Defined", "?" }, + + /* natural ... */ + +// { 12, "spring", "?" }, +// { 12, "peak", "?" }, +// { 12, "glacier", "?" }, +// { 12, "volcano", "?" }, +// { 12, "cliff", "?" }, +// { 12, "scree", "?" }, +// { 12, "scrub", "?" }, +// { 12, "fell", "?" }, +// { 12, "heath", "?" }, +// { 12, "wood", "?" }, +// { 12, "marsh", "?" }, +// { 12, "water", "?" }, +// { 12, "coastline", "?" }, +// { 12, "mud", "?" }, + { 12, "beach", "Beach" }, +// { 12, "bay", "?" }, +// { 12, "land", "?" }, +// { 12, "cave_entrance", "?" }, +// { 12, "User Defined", "?" }, + + /* sport ... */ + +// { 16, "10pin", "?" }, +// { 16, "athletics", "?" }, +// { 16, "australian_football", "?" }, +// { 16, "baseball", "?" }, +// { 16, "basketball", "?" }, +// { 16, "boules", "?" }, +// { 16, "bowls", "?" }, +// { 16, "climbing", "?" }, +// { 16, "cricket", "?" }, +// { 16, "cricket_nets", "?" }, +// { 16, "croquet", "?" }, +// { 16, "cycling", "?" }, +// { 16, "dog_racing", "?" }, +// { 16, "equestrian", "?" }, +// { 16, "football", "?" }, +// { 16, "golf", "?" }, +// { 16, "gymnastics", "?" }, +// { 16, "hockey", "?" }, +// { 16, "horse_racing", "?" }, +// { 16, "motor", "?" }, +// { 16, "multi", "?" }, +// { 16, "pelota", "?" }, +// { 16, "racquet", "?" }, +// { 16, "rugby", "?" }, +// { 16, "skating", "?" }, +// { 16, "skateboard", "?" }, +// { 16, "soccer", "?" }, + { 16, "swimming", "Swimming Area" }, + { 16, "skiing", "Skiing Area" }, +// { 16, "table_tennis", "?" }, +// { 16, "tennis", "?" }, +// { 16, "orienteering", "?" }, +// { 16, "User Defined", "?" }, + + /* place ... */ + +// { 13, "continent", "?" }, +// { 13, "country", "?" }, +// { 13, "state", "?" }, +// { 13, "region", "?" }, +// { 13, "county", "?" }, + { 13, "city", "City (Large)" }, + { 13, "town", "City (Medium)" }, + { 13, "village", "City (Small)" }, +// { 13, "hamlet", "?" }, +// { 13, "suburb", "?" }, +// { 13, "locality", "?" }, +// { 13, "island", "?" }, +// { 13, "User Defined", "?" }, + + { -1, NULL, NULL } +}; + +/*******************************************************************************/ +/* READER */ +/*-----------------------------------------------------------------------------*/ + +static void +osm_features_init(void) +{ + /* here we take a union because of warnings + "cast to pointer from integer of different size" + on 64-bit systems */ + union { + const void *p; + int i; + } x; + + keys = avltree_init(AVLTREE_STATIC_KEYS, MYNAME); + values = avltree_init(0, MYNAME); + + x.p = NULL; + + /* the first of osm_features is a place holder */ + for (x.i = 1; osm_features[x.i]; x.i++) + avltree_insert(keys, osm_features[x.i], x.p); + + for (x.i = 0; osm_icon_mappings[x.i].value; x.i++) { + char buff[128]; + + buff[0] = osm_icon_mappings[x.i].key; + strncpy(&buff[1], osm_icon_mappings[x.i].value, sizeof(buff) - 1); + avltree_insert(values, buff, (const void *)&osm_icon_mappings[x.i]); + } +} + + +static char +osm_feature_ikey(const char *key) +{ + int result; + union { + const void *p; + int i; + } x; + + if (avltree_find(keys, key, &x.p)) + result = x.i; + else + result = -1; + + return result; +} + + +static char * +osm_feature_symbol(const int ikey, const char *value) +{ + char *result; + char buff[128]; + osm_icon_mapping_t *data; + + buff[0] = ikey; + strncpy(&buff[1], value, sizeof(buff) - 1); + + if (avltree_find(values, buff, (void *)&data)) + result = xstrdup(data->icon); + else + xasprintf(&result, "%s:%s", osm_features[ikey], value); + + return result; +} + + +static char * +osm_strip_html(const char *str) +{ + utf_string utf; + utf.is_html = 1; + utf.utfstring = (char *)str; + + return strip_html(&utf); // util.c +} + + +static void +osm_node_end(const char *args, const char **unused) +{ + if (wpt) { + if (wpt->wpt_flags.fmt_use) + waypt_add(wpt); + else + waypt_free(wpt); + wpt = NULL; + } +} + + +static void +osm_node(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + wpt = waypt_new(); + + while (*avp) { + if (strcmp(avp[0], "id") == 0) { + xasprintf(&wpt->description, "osm-id %s", avp[1]); + if (! avltree_insert(waypoints, avp[1], (void *)wpt)) + warning(MYNAME ": Duplicate osm-id %s!\n", avp[1]); + else + wpt->wpt_flags.fmt_use = 1; + } + else if (strcmp(avp[0], "user") == 0) ; + else if (strcmp(avp[0], "lat") == 0) + wpt->latitude = atof(avp[1]); + else if (strcmp(avp[0], "lon") == 0) + wpt->longitude = atof(avp[1]); + else if (strcmp(avp[0], "timestamp") == 0) + wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds); + + avp += 2; + } +} + + +static void +osm_node_tag(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + const char *key = "", *value = ""; + char *str; + char ikey; + + while (*avp) { + if (strcmp(avp[0], "k") == 0) + key = avp[1]; + else if (strcmp(avp[0], "v") == 0) + value = avp[1]; + avp+=2; + } + + str = osm_strip_html(value); + + if (strcmp(key, "name") == 0) { + if (! wpt->shortname) + wpt->shortname = xstrdup(str); + } + else if (strcmp(key, "name:en") == 0) { + if (wpt->shortname) + xfree(wpt->shortname); + wpt->shortname = xstrdup(str); + } + else if ((ikey = osm_feature_ikey(key)) >= 0) { + wpt->icon_descr = osm_feature_symbol(ikey, value); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + } + else if (strcmp(key, "note") == 0) { + if (wpt->notes) { + char *tmp; + xasprintf(&tmp, "%s; %s", wpt->notes, str); + xfree(wpt->notes); + wpt->notes = tmp; + } + else + wpt->notes = xstrdup(str); + } + + xfree(str); +} + + +static void +osm_way(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + rte = route_head_alloc(); + + while (*avp) { + if (strcmp(avp[0], "id") == 0) { + xasprintf(&rte->rte_desc, "osm-id %s", avp[1]); + } + avp += 2; + } +} + +static void +osm_way_nd(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "ref") == 0) { + waypoint *tmp; + if (avltree_find(waypoints, avp[1], (void *)&tmp)) { + tmp = waypt_dupe(tmp); + route_add_wpt(rte, tmp); + } + else + warning(MYNAME ": Way reference id \"%s\" wasn't listed under nodes!\n", avp[1]); + } + avp += 2; + } +} + +static void +osm_way_tag(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + const char *key = "", *value = ""; + char *str; + + while (*avp) { + if (strcmp(avp[0], "k") == 0) + key = avp[1]; + else if (strcmp(avp[0], "v") == 0) + value = avp[1]; + avp += 2; + } + + str = osm_strip_html(value); + + if (strcmp(key, "name") == 0) { + if (! rte->rte_name) + rte->rte_name = xstrdup(str); + } + else if (strcmp(key, "name:en") == 0) { + if (rte->rte_name) + xfree(rte->rte_name); + rte->rte_name = xstrdup(str); + } + + xfree(str); +} + +static void +osm_way_end(const char *args, const char **unused) +{ + if (rte) { + route_add_head(rte); + rte = NULL; + } +} + +static void +osm_rd_init(const char *fname) +{ + wpt = NULL; + rte = NULL; + wpt_loaded = 0; + rte_loaded = 0; + + waypoints = avltree_init(0, MYNAME); + if (! keys) + osm_features_init(); + + xml_init(fname, osm_map, NULL); +} + +static void +osm_read(void) +{ + xml_read(); +} + +#endif + +static void +osm_rd_deinit(void) +{ + xml_deinit(); + avltree_done(waypoints); +} + +/*******************************************************************************/ +/* WRITER */ +/*-----------------------------------------------------------------------------*/ + +static void +osm_init_icons(void) +{ + union { + const void *p; + int i; + } x; + + if (icons) return; + + icons = avltree_init(AVLTREE_STATIC_KEYS, MYNAME); + + x.p = NULL; + for (x.i = 0; osm_icon_mappings[x.i].value; x.i++) + avltree_insert(icons, osm_icon_mappings[x.i].icon, (const void *)&osm_icon_mappings[x.i]); +} + +static void +osm_write_tag(const char *key, const char *value) +{ + if (value && *value) { + char *str = xml_entitize(value); + gbfprintf(fout, " \n", key, str); + xfree(str); + } +} + +static void +osm_disp_feature(const waypoint *wpt) +{ + osm_icon_mapping_t *map; + + if (avltree_find(icons, wpt->icon_descr, (void *) &map)) + osm_write_tag(osm_features[map->key], map->value); +} + +static void +osm_write_opt_tag(const char *atag) +{ + char *tag, *cin, *ce; + + if (!atag) return; + + tag = cin = xstrdup(atag); + ce = cin + strlen(cin); + + while (cin < ce) { + char *sc, *dp; + + if ((sc = strchr(cin, ';'))) *sc = '\0'; + + if ((dp = strchr(cin, ':'))) { + *dp++ = '\0'; + osm_write_tag(cin, dp); + } + cin += strlen(cin) + 1; + } + + xfree(tag); +} + +static void +osm_release_ids(const waypoint *wpt) +{ + if (wpt && wpt->extra_data) { + waypoint *tmp = (waypoint *)wpt; + xfree(tmp->extra_data); + tmp->extra_data = NULL; + } +} + +static void +osm_waypt_disp(const waypoint *wpt) +{ + char *buff; + + xasprintf(&buff, "%s\01%f\01%f", (wpt->shortname) ? wpt->shortname : "", + wpt->latitude, wpt->longitude); + + if (avltree_insert(waypoints, buff, (const void *) wpt)) { + int *id; + + id = xmalloc(sizeof(*id)); + *id = --node_id; + ((waypoint *)(wpt))->extra_data = id; + + gbfprintf(fout, " latitude, wpt->longitude); + if (wpt->creation_time) { + char time_string[64]; + xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); + gbfprintf(fout, " timestamp='%s'", time_string); + } + gbfprintf(fout, ">\n"); + + gbfprintf(fout, " \n"); + + osm_write_tag("name", wpt->shortname); + osm_write_tag("note", (wpt->notes) ? wpt->notes : wpt->description); + if (wpt->icon_descr) + osm_disp_feature(wpt); + + osm_write_opt_tag(opt_tagnd); + + gbfprintf(fout, " \n"); + } + + xfree(buff); +} + +static void +osm_rte_disp_head(const route_head *rte) +{ + skip_rte = (rte->rte_waypt_ct <= 0); + + if (skip_rte) return; + + gbfprintf(fout, " \n", --node_id); +} + +static void +osm_rtept_disp(const waypoint *wpt_ref) +{ + char *buff; + waypoint *wpt; + + if (skip_rte) return; + + xasprintf(&buff, "%s\01%f\01%f", (wpt_ref->shortname) ? wpt_ref->shortname : "", + wpt_ref->latitude, wpt_ref->longitude); + + if (avltree_find(waypoints, buff, (void *) &wpt)) { + int *id = wpt->extra_data; + gbfprintf(fout, " \n", *id); + } + + xfree(buff); +} + +static void +osm_rte_disp_trail(const route_head *rte) +{ + if (skip_rte) return; + + gbfprintf(fout, " \n"); + + osm_write_tag("name", rte->rte_name); + osm_write_tag("note", rte->rte_desc); + + if (opt_tag && (case_ignore_strncmp(opt_tag, "tagnd", 5) != 0)) + osm_write_opt_tag(opt_tag); + + gbfprintf(fout, " \n"); +} + +/*-----------------------------------------------------------------------------*/ + +static void +osm_wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); + + osm_init_icons(); + waypoints = avltree_init(0, MYNAME); + node_id = 0; +} + +static void +osm_write(void) +{ + gbfprintf(fout, "\n"); + gbfprintf(fout, "\n"); + + waypt_disp_all(osm_waypt_disp); + route_disp_all(NULL, NULL, osm_waypt_disp); + track_disp_all(NULL, NULL, osm_waypt_disp); + + route_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp); + track_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp); + + gbfprintf(fout, "\n"); +} + +static void +osm_wr_deinit(void) +{ + gbfclose(fout); + + waypt_disp_all(osm_release_ids); + route_disp_all(NULL, NULL, osm_release_ids); + track_disp_all(NULL, NULL, osm_release_ids); + + avltree_done(waypoints); +} + +static void +osm_exit(void) +{ + if (keys) + avltree_done(keys); + if (values) + avltree_done(values); + if (icons) + avltree_done(icons); +} + +/*-----------------------------------------------------------------------------*/ + +ff_vecs_t osm_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_write /* tracks */, + ff_cap_read | ff_cap_write /* routes */, + }, + osm_rd_init, + osm_wr_init, + osm_rd_deinit, + osm_wr_deinit, + osm_read, + osm_write, + osm_exit, + osm_args, + CET_CHARSET_UTF8, 0 +}; diff --git a/overlay.c b/overlay.c new file mode 100644 index 000000000..b0da23e9e --- /dev/null +++ b/overlay.c @@ -0,0 +1,704 @@ +/* + + Geogrid-Viewer overlay file Version 0.9.3 + + A detail description of the ASCII-overlay-fomat you can find in the + helpfile of Geogrid-Viewer. + + Latest changes at 11.01.2005 by Fredie Kern + + Copyright (C) 2005 Fredie Kern, f.kern@xdesy.de + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "grtcirc.h" + +static short_handle mkshort_handle; + +#define MYNAME "overlay" +#define PARAMETER_FILE "overlay.def" + +#undef MAPNAME +#define MAPNAME "Bundesrepublik 1:1 Mio" +#undef MAPNAME +#define MAPNAME "Top. Karte 1:50.000 Nieders." + +static gbfile *fpout; +static gbfile *fpin; +static int govl_cnt; +static double govl_sum_e=0.0; +static double govl_sum_n=0.0; +static double govl_sumcnt=0.0; +static int govl_symbol_cnt=0; +static int govl_group_cnt=0; +/* +static double govl_last_east=0.0; +static double govl_last_north=0.0; +*/ + +static int govl_col=1; +static char *govl_col_s = NULL; +static int govl_size=101; +static char *govl_size_s = NULL; +static double govl_dir=0.0; + +static char *govl_mapname = NULL; +static int govl_zoomfc = 100; +static char *govl_zoomfc_s = NULL; +static int govl_dimmfc = 100; +static char *govl_dimmfc_s = NULL; + + +static int govl_txtcol=1; +static int govl_txtsize=120; +static int govl_font=1; +static int govl_txttrans=0; + +static char *govl_txtcol_s = NULL; +static char *govl_txtsize_s = NULL; +static char *govl_font_s = NULL; +static char *govl_txttrans_s = NULL; + +static char *govl_file_s = NULL; + +static arglist_t ovl_args[] = { + { "col", &govl_col_s, "color index [1-9] for routes", + NULL, ARGTYPE_INT, "1", "9" }, + { "size", &govl_size_s, "size index [101-] for routes", + NULL, ARGTYPE_INT, "101", NULL }, + { "mapname", &govl_mapname, "name of map", + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "zoomfc", &govl_zoomfc_s, "zoom factor of map in %", + NULL, ARGTYPE_INT, ARG_NOMINMAX }, + { "dimmfc", &govl_dimmfc_s, "dimmer factor of map in %", + NULL, ARGTYPE_INT, ARG_NOMINMAX }, + { "txtcol", &govl_txtcol_s, "color index [1-9] for waypoint names", + NULL, ARGTYPE_INT, "1", "9" }, + { "txtsize", &govl_txtsize_s, "text size [101-] for waypoint names", + NULL, ARGTYPE_INT, "101", NULL }, + { "font", &govl_font_s, "font index [1-] for waypoint names", + NULL, ARGTYPE_INT, "1", NULL }, + { "txttrans", &govl_txttrans_s, "set text background to transparent", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + { "file", &govl_file_s, "use file of parameters (parameters on command line overwrites file parameters)", + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + + +static char *Keywords[]={ + "Typ", + "Group", + "Col", + "Zoom", + "Size", + "Art", + "Punkte", + "Path", + "Dir", + "Font", + "Area", + "Text", + "Width", + "Height", + "Trans", + "TransByte", + NULL + }; + +#define KEY_TYP 0 +#define KEY_GROUP 1 +#define KEY_COL 2 +#define KEY_ZOOM 3 +#define KEY_SIZE 4 +#define KEY_ART 5 +#define KEY_PUNKTE 6 +#define KEY_PATH 7 +#define KEY_DIR 8 +#define KEY_FONT 9 +#define KEY_AREA 10 +#define KEY_TEXT 11 +#define KEY_WIDTH 12 +#define KEY_HEIGHT 13 +#define KEY_TRANS 14 +#define KEY_TRANSBYTE 15 + +static int isKeyword(char *str,char **keys) +{ + int i; + + i = 0; + while(keys[i]!=NULL && strcmp(str,keys[i])) i++; + return(keys[i]==NULL ? -1 : i); +} + +/*----------------------------------------------*/ + +static +void ovl_rd_init(char const *fname) +{ + fpin = gbfopen(fname, "r", MYNAME); +} + +#define SECTION_NONE 0 +#define SECTION_SYMBOL 1 +#define SECTION_PUNKTE 2 +#define SECTION_OVERLAY 3 + +#define MAXLINE 512 + +static struct _group { + int group; + char *name; + } *groups; +static int groups_cnt; + +static void ovl_add_group(int aktgrp,char *akttxt) +{ + int i; + + i = 0; + while (irte_name); + i = 0; + while (irte_name = (char *) xrealloc(route->rte_name,(strlen(name)+1)*sizeof(char)); + strcpy(route->rte_name,name); +} + +static void ovl_read(void) +{ + char *line; + int isSection; + int aktTyp,aktCol,aktSize,aktArt,aktGroup; + int aktArea,aktWidth,aktHeight,aktTrans,aktTransByte,aktDir; + double aktX,aktY; + char *aktPath; + char *aktText; + char *pstr; + int keyw,i; + double rwert; + route_head *route_head = NULL; + waypoint *wpt; + int sym_cnt; + + groups = NULL; + groups_cnt = 0; + aktTyp = aktCol = aktSize = aktArt = aktGroup = -1; + aktArea = aktWidth = aktHeight = aktTrans = aktTransByte = aktDir = -1; + aktX = aktY = 0.0; + aktText = NULL; + aktPath = NULL; + sym_cnt = 0; + isSection = SECTION_NONE; + while ((line = gbfgetstr(fpin))) + { + line = lrtrim(line); + if( (pstr = strstr(line,"[Symbol "))!= NULL) + { + sym_cnt++; + isSection = SECTION_SYMBOL; + } + else if( (pstr = strstr(line,"[Overlay]"))!= NULL) + { + isSection = SECTION_OVERLAY; + } + else if (isSection==SECTION_SYMBOL) + { + pstr = strtok(line,"="); + if (pstr!=NULL) + { + keyw = isKeyword(pstr,Keywords); + pstr = strtok(NULL,"\n"); + if (pstr!=NULL) + { + switch(keyw) + { + case KEY_TYP : + aktTyp = atoi(pstr); + break; + case KEY_GROUP : + aktGroup = atoi(pstr); + ovl_add_group(aktGroup,"?"); /* 'Group' without relation to 'Text'-Symbol */ + switch(aktTyp) + { + case 3: // Linie + route_head = route_head_alloc(); + route_head->rte_num = sym_cnt; + route_head->rte_name = xstrdup(pstr); /* use group-number for the moment */ + route_add_head(route_head); + break; + } + break; + case KEY_COL : + aktCol = atoi(pstr); + break; + case KEY_ZOOM : + break; + case KEY_SIZE : + aktSize = atoi(pstr); + break; + case KEY_ART : + aktArt = atoi(pstr); + break; + case KEY_AREA : + aktArea = atoi(pstr); + if (aktTyp==5 || aktTyp==5 || aktTyp==7) isSection = SECTION_PUNKTE; // Rechteck, Kreis, Dreieck + break; + case KEY_PUNKTE : + isSection = SECTION_PUNKTE; // Linie, Fläche + break; +#ifdef WITH_BITMAP + case KEY_PATH : + aktPath = xstrdup(pstr); + isSection = SECTION_PUNKTE; // Bitmap + break; + case KEY_TRANS : + aktTrans = atoi(pstr); + break; + case KEY_TRANSBYTE : + aktTransByte = atoi(pstr); + break; +#endif + case KEY_TEXT : + aktText = xstrdup(pstr); + /* The last 'Text'-symbol wins as a information block for + waypoint/route description. + Infos from previous symbols get overwrited. + */ + ovl_add_group(aktGroup,aktText); + break; + case KEY_WIDTH : + aktWidth = atoi(pstr); + break; + case KEY_HEIGHT : + aktHeight = atoi(pstr); + break; + case KEY_DIR : + aktDir = atoi(pstr); + if (aktTyp==2) isSection = SECTION_PUNKTE; // Text + break; + } + } + } + } + else if (isSection==SECTION_PUNKTE) + { + pstr = strtok(line,"="); + if (strstr(pstr,"XKoord")!=NULL || strstr(pstr,"YKoord")!=NULL) + { + if ((pstr = strtok(NULL,"\n"))!=NULL) + { + rwert = atof(pstr); + if (line[0]=='X') + { + aktX = rwert; + } + else if (line[0]=='Y') + { + aktY = rwert; + switch(aktTyp) + { +#ifdef WITH_BITMAP + case 1: // Bitmap + wpt = waypt_new(); + wpt->latitude = aktY; + wpt->longitude = aktX; + wpt->altitude = 0.0; + wpt->shortname = strdup(aktPath); + waypt_add(wpt); + break; +#endif + case 2: // Text + isSection = SECTION_SYMBOL; + break; + case 3: // Linie + wpt = waypt_new(); + wpt->latitude = aktY; + wpt->longitude = aktX; + wpt->altitude = 0.0; + route_add_wpt(route_head, wpt); + break; + case 4: // Fläche + break; + case 5: // Rechteck + break; + case 6: // Kreis + break; + case 7: // Dreieck + break; + } + } + } + } + } + else if (isSection==SECTION_OVERLAY) + { + isSection = SECTION_NONE; + } + } + route_disp_all(route_add_name,NULL,NULL); + if (aktText!=NULL) xfree(aktText); + if (aktPath!=NULL) xfree(aktPath); + for (i=0;iargstring!=NULL) + { + if (strcmp(pstr,p->argstring)==0) + { + pstr = strtok(NULL,"\n"); + if (p->argtype==ARGTYPE_BOOL) + { + *(p->argval) = atoi(pstr) ? xstrdup(pstr) : NULL; + } + else + { + *(p->argval) = xstrdup(pstr); + } + break; + } + p++; + } + } + } + } + gbfclose(fpin); + } +} + +static void ovl_wr_init(const char *fname) +{ + fpout = gbfopen(fname, "w", MYNAME); + govl_sum_n = 0.0; + govl_sum_e = 0.0; + govl_sumcnt = 0.0; + govl_symbol_cnt = 0; + + + ovl_read_parameter(govl_file_s!=NULL ? govl_file_s : PARAMETER_FILE); + + if (govl_col_s!=NULL) + { + govl_col = atoi(govl_col_s); + } + if (govl_size_s!=NULL) + { + govl_size = atoi(govl_size_s); + } + if (govl_mapname==NULL) + { + govl_mapname = xstrdup(MAPNAME); + } + if (govl_zoomfc_s!=NULL) + { + govl_zoomfc = atoi(govl_zoomfc_s); + } + if (govl_dimmfc_s!=NULL) + { + govl_dimmfc = atoi(govl_dimmfc_s); + } + if (govl_txtcol_s!=NULL) + { + govl_txtcol = atoi(govl_txtcol_s); + } + if (govl_txtsize_s!=NULL) + { + govl_txtsize = atoi(govl_txtsize_s); + } + if (govl_font_s!=NULL) + { + govl_font = atoi(govl_font_s); + } + if (govl_txttrans_s!=NULL) + { + govl_txttrans = 1; + } +} + +static void ovl_wr_deinit(void) +{ + gbfprintf(fpout,"[Overlay]\n"); + gbfprintf(fpout,"Symbols=%d\n",govl_symbol_cnt); + gbfprintf(fpout,"[MapLage]\n"); + gbfprintf(fpout,"MapName=%s\n",govl_mapname); + gbfprintf(fpout,"DimmFc=%d\n",govl_dimmfc); + gbfprintf(fpout,"ZoomFc=%d\n",govl_zoomfc); + if (govl_symbol_cnt) + { + gbfprintf(fpout,"CenterLat=%.8lf\n",govl_sum_n/govl_sumcnt); // precision 8 = better than 1mm + gbfprintf(fpout,"CenterLong=%.8lf\n",govl_sum_e/govl_sumcnt); + } + else + { + gbfprintf(fpout,"CenterLong=10.52374295\n"); // Braunschweiger Löwe, Mittelpunkt der Welt :-) + gbfprintf(fpout,"CenterLat=52.26474445\n"); + } + gbfprintf(fpout,"RefOn=0\n"); + + gbfclose(fpout); +} + +static void symbol_init(const route_head *hd) +{ + gbfprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1); + gbfprintf(fpout,"Typ=3\n"); // Linie + gbfprintf(fpout,"Group=%d\n" ,govl_group_cnt+1+1); // group==1 : not a group + gbfprintf(fpout,"Col=%d\n" ,govl_col); + gbfprintf(fpout,"Zoom=2\n"); + gbfprintf(fpout,"Size=%d\n" ,govl_size); + gbfprintf(fpout,"Art=1\n"); + gbfprintf(fpout,"Punkte=%d\n" ,hd->rte_waypt_ct); + govl_cnt = 0; + govl_symbol_cnt++; + govl_group_cnt++; +} + +static void symbol_text(double east,double north,char *text,int group) +{ + gbfprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1); + gbfprintf(fpout,"Typ=2\n"); // Text + gbfprintf(fpout,"Group=%d\n",group+1); // group==1 : not a group + gbfprintf(fpout,"Col=%d\n",govl_txtcol); + gbfprintf(fpout,"Area=%d\n",govl_txttrans ? 1 : 2); // =2 opak =1 transparent + gbfprintf(fpout,"Zoom=%d\n",2); + gbfprintf(fpout,"Size=%d\n",govl_txtsize); + gbfprintf(fpout,"Font=%d\n",govl_font); + gbfprintf(fpout,"Dir=%d\n",100+((int) govl_dir)); + gbfprintf(fpout,"XKoord=%.8lf\n",east); // precision 8 = better than 1mm + gbfprintf(fpout,"YKoord=%.8lf\n",north); + gbfprintf(fpout,"Text=%s\n",text); + govl_symbol_cnt++; +} + +static void symbol_point(const waypoint *wpt) +{ + double east,north; + + east = wpt->longitude; + north = wpt->latitude; + gbfprintf(fpout,"XKoord%d=%.8lf\n",govl_cnt,east); // precision 8 = better than 1mm + gbfprintf(fpout,"YKoord%d=%.8lf\n",govl_cnt,north); + govl_cnt++; + govl_sum_e += east; + govl_sum_n += north; + govl_sumcnt += 1.0; +/* + govl_last_east = east; + govl_last_north = north; +*/ +} + + +static void symbol_deinit(const route_head *hd) +{ + queue *elem, *tmp; + waypoint *waypointp; + int i; + double lat1,lon1,lat2,lon2; + double lats,lons,late,lone; + double dist,d,dd; + + lat1 = lon1 = lat2 = lon2 = 0.0; + lats = lons = late = lone = 0.0; + dist = 0.0; + i = 0; + QUEUE_FOR_EACH(&(hd->waypoint_list), elem, tmp) + { + waypointp = (waypoint *) elem; + lat2 = RAD(waypointp->latitude); + lon2 = RAD(waypointp->longitude); + if (i) + { + d = gcdist(lat1, lon1, lat2, lon2 ); + dist += d; + } + else + { + lats = lat2; // start point + lons = lon2; + } + lat1 = lat2; + lon1 = lon2; + i++; + } + late = lat2; // end point + lone = lon2; + dd = 0; + i = 0; + elem = QUEUE_FIRST(&(hd->waypoint_list)); + while (elem!=&(hd->waypoint_list) && ddlatitude); + lon2 = RAD(waypointp->longitude); + if (i) + { + d = gcdist(lat1, lon1, lat2, lon2 ); + dd += d; + } + lat1 = lat2; + lon1 = lon2; + elem = QUEUE_NEXT(elem); + i++; + } + + d = gcdist(lats,lons,late,lone); +// d = acos( sin(lats)*sin(late)+cos(lats)*cos(late)*cos(lone-lons) ); + dd = acos( (sin(late) - sin(lats)*cos(d))/(cos(lats)*sin(d)) ); + if (lone 360.0 ? dd - 360.0 : dd; // normalizing + + /* name of route */ + /* plot text at the last point of route */ + govl_dir = dd; // approximated text rotation, correct value must be the azimuth in UTM + symbol_text(DEG(lon1),DEG(lat1),hd->rte_name,govl_group_cnt); + govl_dir = 0.0; // restore +} + +static void overlay_waypt_pr(const waypoint *waypointp) +{ + const char *oname; + char *odesc; + + /* + * Desparation time, try very hard to get a good shortname + */ + odesc = waypointp->notes; + if (!odesc) { + odesc = waypointp->description; + } + if (!odesc) { + odesc = waypointp->shortname; + } + oname = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, odesc) : + waypointp->shortname; + + gbfprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1); + gbfprintf(fpout,"Typ=1\n"); + gbfprintf(fpout,"Group=1\n"); + gbfprintf(fpout,"Width=100\n"); + gbfprintf(fpout,"Height=100\n"); + gbfprintf(fpout,"Dir=%d\n",100+((int) govl_dir)); + gbfprintf(fpout,"Zoom=2\n"); + gbfprintf(fpout,"Trans=2\n"); + gbfprintf(fpout,"TransByte=5\n"); + gbfprintf(fpout,"Path=%s\n","waypoint.bmp"); + gbfprintf(fpout,"XKoord=%.8lf\n",waypointp->longitude); + gbfprintf(fpout,"YKoord=%.8lf\n",waypointp->latitude); + govl_symbol_cnt++; + govl_sum_e += waypointp->longitude; + govl_sum_n += waypointp->latitude; + govl_sumcnt += 1.0; + +} + +static void ovl_write(void) +{ + waypt_disp_all(overlay_waypt_pr); + track_disp_all(symbol_init, symbol_deinit, symbol_point); + route_disp_all(symbol_init, symbol_deinit, symbol_point); +/* + switch(global_opts.objective) + { + case wptdata: + break; + case trkdata: + break; + } +*/ +} + + +ff_vecs_t overlay_vecs = { + ff_type_internal, + FF_CAP_RW_ALL, + ovl_rd_init, + ovl_wr_init, + ovl_rd_deinit, + ovl_wr_deinit, + ovl_read, + ovl_write, + NULL, + ovl_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/ozi.c b/ozi.c new file mode 100644 index 000000000..589822893 --- /dev/null +++ b/ozi.c @@ -0,0 +1,858 @@ +/* + OziExplorer Waypoints/Tracks/Routes + Comma Delimited + + As described in OziExplorer Help File + + Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "csv_util.h" +#include "jeeps/gpsmath.h" +#include +#include /* for floor */ + +#define MYNAME "OZI" +#define BADCHARS ",\r\n" +#define DAYS_SINCE_1990 25569 + +typedef struct { + format_specific_data fs; + int fgcolor; + int bgcolor; +} ozi_fsdata; + + +static gbfile *file_in, *file_out; +static short_handle mkshort_handle; +static route_head *trk_head; +static route_head *rte_head; + +static int track_out_count; +static int route_out_count; +static int route_wpt_count; +static int new_track; + +static char *snlenopt = NULL; +static char *snwhiteopt = NULL; +static char *snupperopt = NULL; +static char *snuniqueopt = NULL; +static char *wptfgcolor = NULL; +static char *wptbgcolor = NULL; +static char *pack_opt = NULL; +static int datum; +static char *proximityarg = NULL; +static int proximity; + +static +arglist_t ozi_args[] = { + {"pack", &pack_opt, "Write all tracks into one file", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"snlen", &snlenopt, "Max synthesized shortname length", + "32", ARGTYPE_INT, "1", NULL}, + {"snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"snupper", &snupperopt, "UPPERCASE synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"snunique", &snuniqueopt, "Make synth. shortnames unique", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"wptfgcolor", &wptfgcolor, "Waypoint foreground color", + "black", ARGTYPE_STRING, ARG_NOMINMAX}, + {"wptbgcolor", &wptbgcolor, "Waypoint background color", + "yellow", ARGTYPE_STRING, ARG_NOMINMAX}, + {"proximity", &proximityarg, "Proximity distance", + "0", ARGTYPE_INT, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +static gpsdata_type ozi_objective; + +static char *ozi_ofname = NULL; + +static void +ozi_copy_fsdata(ozi_fsdata **dest, ozi_fsdata *src) +{ + /* No strings to mess with. Straight forward copy. */ + *dest = (void *)xmalloc(sizeof(*src)); + **dest = *src; + (*dest)->fs.next = NULL; +} + +static void +ozi_free_fsdata(void *fsdata) +{ + xfree(fsdata); +} + +static +ozi_fsdata * +ozi_alloc_fsdata(void) +{ + ozi_fsdata *fsdata = xcalloc(sizeof(*fsdata), 1); + fsdata->fs.type = FS_OZI; + fsdata->fs.copy = (fs_copy) ozi_copy_fsdata; + fsdata->fs.destroy = ozi_free_fsdata; + fsdata->fs.convert = NULL; + + /* Provide defaults via command line defaults */ + fsdata->fgcolor = color_to_bbggrr(wptfgcolor); + fsdata->bgcolor = color_to_bbggrr(wptbgcolor); + + return fsdata; +} + +void +ozi_get_time_str(const waypoint *waypointp, char *buff, gbsize_t buffsz) +{ + if (waypointp->creation_time) { + double time = (waypt_time(waypointp) / SECONDS_PER_DAY) + DAYS_SINCE_1990; + snprintf(buff, buffsz, "%.7f", time); + } + else *buff = '\0'; +} + +void +ozi_set_time_str(const char *str, waypoint *waypointp) +{ + double ozi_time; + char *dot; + int len; + + ozi_time = atof(str); + waypointp->creation_time = (ozi_time - DAYS_SINCE_1990) * SECONDS_PER_DAY; + + dot = strchr(str, '.'); + /* get number of characters after dot */ + len = (dot) ? strlen(str) - (dot - str) - 1 : 0; + if (len >= 7) { + /* with default ozi time precision (%.7f) we can only handle tenths of second */ + ozi_time -= ((double)waypointp->creation_time / SECONDS_PER_DAY ) + DAYS_SINCE_1990; + ozi_time *= SECONDS_PER_DAY; + waypointp->microseconds = (ozi_time * 10) + 0.5; + if (waypointp->microseconds == 10) { + waypointp->creation_time++; + waypointp->microseconds = 0; + } + waypointp->microseconds *= 100000; + } +} + +static void +ozi_convert_datum(waypoint *wpt) +{ + if (datum != DATUM_WGS84) { + double lat, lon, alt; + GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, 0.0, + &lat, &lon, &alt, datum); + wpt->latitude = lat; + wpt->longitude = lon; + } +} + +static void +ozi_openfile(char *fname) { + char *c, *cx, *tmpname; + char *ozi_extensions[] = {0, "plt", "wpt", "rte"}; + char buff[32]; + + /* if we're doing multi-track output, sequence the filenames like: + * mytrack.plt, mytrack-1.plt...unless we're writing to stdout. + */ + + if (0 == strcmp(fname, "-")) { + if (! file_out) { + file_out = gbfopen(fname, "wb", MYNAME); + } + return; + } + + if ((track_out_count) && (ozi_objective == trkdata)) { + sprintf(buff, "-%d", track_out_count); + } else { + buff[0] = '\0'; + } + + /* remove extension and add buff + ozi's extension */ + c = strrchr(fname, '.'); + if (c && (cx = strrchr(fname, '/')) && (cx > c)) c = NULL; + if (c && (cx = strrchr(fname, '\\')) && (cx > c)) c = NULL; + if (c == NULL) c = fname + strlen(fname); + xasprintf(&tmpname, "%*.*s%s.%s", c - fname, c - fname, fname, buff, ozi_extensions[ozi_objective]); + + /* re-open file_out with the new filename */ + if (file_out) { + gbfclose(file_out); + file_out = NULL; + } + + file_out = gbfopen(tmpname, "wb", MYNAME); + + xfree(tmpname); + + return; +} + +static void +ozi_track_hdr(const route_head * rte) +{ + static char *ozi_trk_header = + "OziExplorer Track Point File Version 2.1\r\n" + "WGS 84\r\n" + "Altitude is in Feet\r\n" + "Reserved 3\r\n" + "0,2,255,%s,0,0,2,8421376\r\n" + "0\r\n"; + + if ((! pack_opt) || (track_out_count == 0)) { + ozi_openfile(ozi_ofname); + gbfprintf(file_out, ozi_trk_header, + rte->rte_name ? rte->rte_name : "ComplimentsOfGPSBabel"); + } + + track_out_count++; + new_track = 1; +} + +static void +ozi_track_disp(const waypoint * waypointp) +{ + double alt_feet; + char ozi_time[16]; + + ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); + + if (waypointp->altitude == unknown_alt) { + alt_feet = -777; + } else { + alt_feet = METERS_TO_FEET(waypointp->altitude); + } + + gbfprintf(file_out, "%.6f,%.6f,%d,%.0f,%s,,\r\n", + waypointp->latitude, waypointp->longitude, new_track, + alt_feet, ozi_time); + + new_track = 0; +} + +static void +ozi_track_tlr(const route_head * rte) +{ +} + +static void +ozi_track_pr() +{ + track_disp_all(ozi_track_hdr, ozi_track_tlr, ozi_track_disp); +} + +static void +ozi_route_hdr(const route_head * rte) +{ + static char *ozi_route_header = + "OziExplorer Route File Version 1.0\r\n" + "WGS 84\r\n" + "Reserved 1\r\n" + "Reserved 2\r\n"; + + /* prologue on 1st pass only */ + if (route_out_count == 0) { + gbfprintf(file_out, ozi_route_header); + } + + route_out_count++; + route_wpt_count = 0; + + /* + * Route Record + * Field 1 : R - indicating route details + * Field 2 : Number - this is the location in the array, must be unique, usually start at 0 for Garmins 1 for other and increment. + * Field 3 : Name - the waypoint name, use the correct length name to suit the GPS type. + * Field 4 : Description. + * Field 5 : Route Color as displayed on map (RGB). + * + * R, 0,R0 ,,255 + * R, 1, ICP GALHETA,, 16711680 + */ + + gbfprintf(file_out, "R,%d,%s,%s,\r\n", + route_out_count, + rte->rte_name ? rte->rte_name : "", + rte->rte_desc ? rte->rte_desc : ""); + +} + +static void +ozi_route_disp(const waypoint * waypointp) +{ + double alt_feet; + char ozi_time[16]; + + route_wpt_count++; + + ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); + + if (waypointp->altitude == unknown_alt) { + alt_feet = -777; + } else { + alt_feet = METERS_TO_FEET(waypointp->altitude); + } + +/* + * Field 1 : W - indicating route waypoint details. + * Field 2 : Route Number - location in array of routes + * Field 3 : Number - this is the location in the array of route waypoints, this field is now ignored. + * Field 4 : Wp Number - this is the number of the waypoint (the Wp number within the GPS for lowrances) + * Field 5 : Name - the waypoint name, use the correct length name to suit the GPS type. + * Field 6 : Latitude - decimal degrees. + * Field 7 : Longitude - decimal degrees. + * Field 8 : Date - see Date Format below, if blank a preset date will be used + * Field 9 : Symbol - 0 to number of symbols in GPS + * Field 10 : Status - always set to 1 + * Field 11 : Map Display Format + * Field 12 : Foreground Color (RGB value) + * Field 13 : Background Color (RGB value) + * Field 14 : Description (max 40), no commas + * Field 15 : Pointer Direction + * Field 16 : Garmin Display Format + * + * W,1,7,7,007,-25.581670,-48.316660,36564.54196,10,1,4,0,65535,TR ILHA GALHETA,0,0 + */ + + gbfprintf(file_out, "W,%d,%d,,%s,%.6f,%.6f,%s,0,1,3,0,65535,%s,0,0\r\n", + route_out_count, + route_wpt_count, + waypointp->shortname ? waypointp->shortname : "", + waypointp->latitude, + waypointp->longitude, + ozi_time, + waypointp->description ? waypointp->description : ""); + +} + +static void +ozi_route_tlr(const route_head * rte) +{ +} + +static void +ozi_route_pr() +{ + route_disp_all(ozi_route_hdr, ozi_route_tlr, ozi_route_disp); +} + +static void +rd_init(const char *fname) +{ + file_in = gbfopen(fname, "rb", MYNAME); + + mkshort_handle = mkshort_new_handle(); +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); + file_in = NULL; + mkshort_del_handle(&mkshort_handle); +} + +static void +wr_init(const char *fname) +{ + + /* At this point, we have no idea whether we'll be writing waypoint, + * route, or tracks. So we'll hold off opening any files until + * we're actually ready to write. + */ + + ozi_ofname = (char *)fname; + + mkshort_handle = mkshort_new_handle(); + + /* set mkshort options from the command line if applicable */ + if (global_opts.synthesize_shortnames) { + + setshort_length(mkshort_handle, atoi(snlenopt)); + + if (snwhiteopt) + setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + + if (snupperopt) + setshort_mustupper(mkshort_handle, atoi(snupperopt)); + + if (snuniqueopt) + setshort_mustuniq(mkshort_handle, atoi(snuniqueopt)); + + setshort_badchars(mkshort_handle, "\","); + } + + proximity = atoi(proximityarg); + + file_out = NULL; +} + +static void +wr_deinit(void) +{ + if (file_out != NULL) { + + gbfclose(file_out); + file_out = NULL; + } + ozi_ofname = NULL; + + mkshort_del_handle(&mkshort_handle); +} + +static void +ozi_parse_waypt(int field, char *str, waypoint * wpt_tmp, ozi_fsdata *fsdata) +{ + double alt; + + if (*str == '\0') return; + + switch (field) { + case 0: + /* sequence # */ + break; + case 1: + /* waypoint name */ + wpt_tmp->shortname = csv_stringtrim(str, "", 0); + break; + case 2: + /* degrees latitude */ + wpt_tmp->latitude = atof(str); + break; + case 3: + /* degrees longitude */ + wpt_tmp->longitude = atof(str); + break; + case 4: + /* DAYS since 1900 00:00:00 in days.days (5.5) */ + ozi_set_time_str(str, wpt_tmp); + break; + case 5: + /* icons 0-xx */ + break; + case 6: + /* unknown - always 1 */ + break; + case 7: + /* display format options 0-8 */ + break; + case 8: + /* foreground color (0=black) */ + fsdata->fgcolor = atoi(str); + break; + case 9: + /* background color (65535=yellow) */ + fsdata->bgcolor = atoi(str); + break; + case 10: + /* Description */ + wpt_tmp->description = csv_stringtrim(str, "", 0); + break; + case 11: + /* pointer direction 0,1,2,3 bottom,top,left,right */ + break; + case 12: + /* garmin gps display flags (0-name w/sym, 1-sym only, 2-comment w/symbol */ + break; + case 13: + /* proximity distance - meters */ + WAYPT_SET(wpt_tmp, proximity, atof(str)); + break; + case 14: + /* altitude in feet */ + alt = atof(str); + if (alt == -777) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = FEET_TO_METERS(alt); + } + break; + case 15: + /* waypoint text name size */ + break; + case 16: + /* bold checkbox (1=bold, default 0) */ + break; + case 17: + /* symbol size - 17 default */ + break; + /* + * Fields 18-23 were added around version 3.90.4g of + * Ozi, but aren't documented. We silently ignore + * these or any additional fields we don't need. + */ + default: + break; + } +} + +static void +ozi_parse_track(int field, char *str, waypoint * wpt_tmp) +{ + double alt; + + if (*str == '\0') return; + + switch (field) { + case 0: + /* latitude */ + wpt_tmp->latitude = atof(str); + break; + case 1: + /* longitude */ + wpt_tmp->longitude = atof(str); + break; + case 2: + /* new track flag */ + if ((atoi(str) == 1) && (trk_head->rte_waypt_ct > 0)) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + } + break; + case 3: + /* altitude in feet */ + alt = atof(str); + if (alt == -777) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = FEET_TO_METERS(alt); + } + break; + case 4: + /* DAYS since 1900 00:00:00 in days.days (5.5) */ + ozi_set_time_str(str, wpt_tmp); + break; + default: + break; + } +} + +static void +ozi_parse_routepoint(int field, char *str, waypoint * wpt_tmp) +{ + if (*str == '\0') return; + + switch (field) { + case 0: + /* W */ + break; + case 1: + /* route # */ + break; + case 2: + /* waypoint # -- ignored by ozi */ + break; + case 3: + /* waypoint # */ + break; + case 4: + /* waypoint name */ + wpt_tmp->shortname = csv_stringclean(str, ","); + break; + case 5: + /* latitude */ + wpt_tmp->latitude = atof(str); + break; + case 6: + /* longitude */ + wpt_tmp->longitude = atof(str); + break; + case 7: + /* DAYS since 1900 00:00:00 in days.days (5.5) */ + ozi_set_time_str(str, wpt_tmp); + break; + case 8: + /* symbol */ + break; + case 9: + /* status */ + break; + case 10: + /* map display format */ + break; + case 11: + /* foreground color (RGB) */ + break; + case 12: + /* background color (RGB) */ + break; + case 13: + /* description */ + wpt_tmp->description = csv_stringclean(str, ","); + break; + default: + break; + } +} + +static void +ozi_parse_routeheader(int field, char *str, waypoint * wpt_tmp) +{ + + switch (field) { + case 0: + /* R */ + rte_head = route_head_alloc(); + route_add_head(rte_head); + break; + case 1: + /* route # */ + rte_head->rte_num = atoi(str); + break; + case 2: + /* route name */ + rte_head->rte_name = csv_stringclean(str, ","); + break; + case 3: + /* route description */ + rte_head->rte_desc = csv_stringclean(str, ","); + break; + case 4: + /* route color */ + break; + default: + break; + } +} + +static void +data_read(void) +{ + char *buff; + char *s; + waypoint *wpt_tmp; + int i; + int linecount = 0; + + while ((buff = gbfgetstr(file_in))) { + linecount++; + + /* + * this is particularly nasty. use the first line of the file + * to attempt to divine the data type we are parsing + */ + if (linecount == 1) { + if (strstr(buff, "Track Point") != NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + ozi_objective = trkdata; + } else + if (strstr(buff, "Route File") != NULL) { + ozi_objective = rtedata; + } else { + ozi_objective = wptdata; + } + } + else if (linecount == 2) { + datum = GPS_Lookup_Datum_Index(buff); + if (datum < 0) { + fatal(MYNAME ": Unsupported datum '%s'.\n", buff); + } + } + + if ((strlen(buff)) && (strstr(buff, ",") != NULL)) { + ozi_fsdata *fsdata = ozi_alloc_fsdata(); + wpt_tmp = waypt_new(); + + /* data delimited by commas, possibly enclosed in quotes. */ + s = buff; + s = csv_lineparse(s, ",", "", linecount); + + i = 0; + while (s) { + switch (ozi_objective) { + case trkdata: + ozi_parse_track(i, s, wpt_tmp); + break; + case rtedata: + if (buff[0] == 'R') { + ozi_parse_routeheader(i, s, wpt_tmp); + } else { + ozi_parse_routepoint(i, s, wpt_tmp); + } + + break; + case wptdata: + ozi_parse_waypt(i, s, wpt_tmp, fsdata); + break; + case posndata: + fatal(MYNAME ": realtime positioning not supported.\n"); + break; + } + i++; + s = csv_lineparse(NULL, ",", "", linecount); + } + + switch (ozi_objective) { + case trkdata: + if (linecount > 6) {/* skipping over file header */ + ozi_convert_datum(wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); + } + else + waypt_free(wpt_tmp); + break; + case rtedata: + if (linecount > 5) {/* skipping over file header */ + ozi_convert_datum(wpt_tmp); + route_add_wpt(rte_head, wpt_tmp); + } + else + waypt_free(wpt_tmp); + break; + case wptdata: + if (linecount > 4) { /* skipping over file header */ + fs_chain_add(&(wpt_tmp->fs), + (format_specific_data *) fsdata); + ozi_convert_datum(wpt_tmp); + waypt_add(wpt_tmp); + } else { + waypt_free(wpt_tmp); + } + break; + case posndata: + fatal(MYNAME ": realtime positioning not supported.\n"); + break; + } + + } else { + /* empty line */ + } + + } +} + +static void +ozi_waypt_pr(const waypoint * wpt) +{ + static int index = 0; + double alt_feet; + char ozi_time[16]; + char *description; + char *shortname; + int faked_fsdata = 0; + ozi_fsdata *fs = NULL; + + fs = (ozi_fsdata *) fs_chain_find(wpt->fs, FS_OZI); + + if (!fs) { + fs = ozi_alloc_fsdata(); + faked_fsdata = 1; + } + + ozi_get_time_str(wpt, ozi_time, sizeof(ozi_time)); + + if (wpt->altitude == unknown_alt) { + alt_feet = -777; + } else { + alt_feet = METERS_TO_FEET(wpt->altitude); + } + + if ((!wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) + shortname = mkshort_from_wpt(mkshort_handle, wpt); + else + shortname = csv_stringclean(wpt->description, BADCHARS); + } else { + /* no description available */ + shortname = xstrdup(""); + } + } else { + shortname = csv_stringclean(wpt->shortname, BADCHARS); + } + + if (!wpt->description) { + if (shortname) { + description = csv_stringclean(shortname, BADCHARS); + } else { + description = xstrdup(""); + } + } else { + description = csv_stringclean(wpt->description, BADCHARS); + } + + index++; + + gbfprintf(file_out, + "%d,%s,%.6f,%.6f,%s,%d,%d,%d,%d,%d,%s,%d,%d,", + index, shortname, wpt->latitude, wpt->longitude, ozi_time, 0, + 1, 3, fs->fgcolor, fs->bgcolor, description, 0, 0); + if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) + gbfprintf(file_out, "%.1f,", wpt->proximity); + else + gbfprintf(file_out,"%d,", proximity); + gbfprintf(file_out, "%.0f,%d,%d,%d\r\n", alt_feet, 6, 0, 17); + + xfree(description); + xfree(shortname); + + if (faked_fsdata) { + xfree(fs); + } +} + +static void +data_write(void) +{ + static char *ozi_wpt_header = + "OziExplorer Waypoint File Version 1.1\r\n" + "WGS 84\r\n" + "Reserved 2\r\n" + "Reserved 3\r\n"; + + track_out_count = route_out_count = 0; + + if (waypt_count()) { + ozi_objective = wptdata; + ozi_openfile(ozi_ofname); + gbfprintf(file_out, ozi_wpt_header); + waypt_disp_all(ozi_waypt_pr); + } + + if (track_count()) { + ozi_objective = trkdata; + ozi_track_pr(); /* ozi_track_hdr handles filenames / file_out */ + } + + if (route_count()) { + ozi_objective = rtedata; + ozi_openfile(ozi_ofname); /* ozi routes go in one big file */ + ozi_route_pr(); + } + +} + +ff_vecs_t ozi_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + ozi_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/palmdoc.c b/palmdoc.c new file mode 100644 index 000000000..004e534e7 --- /dev/null +++ b/palmdoc.c @@ -0,0 +1,599 @@ +/* + Output only format for PalmDoc + + Copyright (C) 2004 Scott Brynen, scott (at) brynen.com + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + Copyright (C) 2004 Ronald L. Parker, ron@parkrrrr.com + Portions from txt2pdbdoc, Copyright (C) 1998 Paul J. Lucas + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "jeeps/gpsmath.h" +#include +#include "pdbfile.h" + +static pdbfile *file_out; +static short_handle mkshort_handle; +static short_handle mkshort_bookmark_handle; +static const char *out_fname; + +static char *suppresssep = NULL; +static char *dbname = NULL; +static char *bmid = NULL; +static char *includelogs = NULL; + +static int ct; +static int offset; + +static char *palm_encrypt; + +#define MYNAME "PALMDOC" + +/* constants */ +#define BUFFER_SIZE 4096 /* big enough for uncompressed record */ +#define COMPRESSED 2 +#define COUNT_BITS 3 /* why this value? I don't know */ +#define DISP_BITS 11 /* ditto */ + +#define DOC_CREATOR 0x52454164 /* "REAd" */ +#define DOC_TYPE 0x54455874 /* "TEXt" */ +#define UNCOMPRESSED 1 + +struct buffer { + unsigned char *data; + unsigned len; +}; + +#define NEW_BUFFER(b) (b)->data = (unsigned char *)xmalloc( ((b)->len = 0,BUFFER_SIZE) ) + +static +arglist_t palmdoc_args[] = { + { "nosep", &suppresssep, + "No separator lines between waypoints", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX }, + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"encrypt", &palm_encrypt, "Encrypt hints with ROT13", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX }, + { "logs", &includelogs, + "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + { "bookmarks_short", &bmid, "Include short name in bookmarks", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static struct buffer buf; + +struct doc_record0 /* 16 bytes total */ +{ + gbuint16 version; /* 1 = plain text, 2 = compressed */ + gbuint16 reserved1; + gbuint32 doc_size; /* in bytes, when uncompressed */ + gbuint16 num_records; /* PDB header numRecords - 1 */ + gbuint16 rec_size; /* usually RECORD_SIZE_MAX */ + gbuint32 reserved2; + gbuint16 recsizes[1]; +}; + +static struct recordsize { + int size; + struct recordsize *next; +} *recordsize_tail; + +static struct bookmark { + int offset; + char *text; + struct bookmark *next; +} *bookmark_tail; + +struct bookmark_record { + char text[16]; + gbuint32 offset; +}; + +static void put_byte(struct buffer *b, unsigned char c, int *space) +{ + if ( *space ) { + *space = 0; + /* + ** There is an outstanding space char: see if we can squeeze it + ** in with an ASCII char. + */ + if ( c >= 0x40 && c <= 0x7F ) { + b->data[ b->len++ ] = c ^ 0x80; + return; + } + b->data[ b->len++ ] = ' '; /* couldn't squeeze it in */ + } else if ( c == ' ' ) { + *space = 1; + return; + } + + if ( (c >= 1 && c <= 8) || c >= 0x80 ) + b->data[ b->len++ ] = '\1'; + + b->data[ b->len++ ] = c; +} + +static unsigned char * mem_find(unsigned char *t, int t_len, unsigned char *m, int m_len) +{ + register int i; + for ( i = t_len - m_len + 1; i > 0; --i, ++t ) + if ( *t == *m && !memcmp( t, m, m_len ) ) + return t; + return 0; +} + + +static void pd_compress( struct buffer *b ) +{ + + unsigned i, j; + int space = 0; + + unsigned char *buf_orig; + unsigned char *p; /* walking test hit; works up on successive matches */ + unsigned char *p_prev; + unsigned char *head; /* current test string */ + unsigned char *tail; /* 1 past the current test buffer */ + unsigned char *end; /* 1 past the end of the input buffer */ + + p = p_prev = head = buf_orig = b->data; + tail = head + 1; + end = b->data + b->len; + + NEW_BUFFER( b ); + b->len = 0; + + /* loop, absorbing one more char from the input buffer on each pass */ + while ( head != end ) { + /* establish where the scan can begin */ + if ( head - p_prev > (( 1 << DISP_BITS )-1) ) + p_prev = head - (( 1 << DISP_BITS )-1); + + /* scan in the previous data for a match */ + p = mem_find( p_prev, tail - p_prev, head, tail - head ); + + /* on a mismatch or end of buffer, issued codes */ + if ( !p || p == head || tail - head > ( 1 << COUNT_BITS ) + 2 + || tail == end + ) { + /* issued the codes */ + /* first, check for short runs */ + if ( tail - head < 4 ) { + put_byte( b, *head++, &space ); + } + else { + unsigned dist = head - p_prev; + unsigned compound = (dist << COUNT_BITS) + + tail - head - 4; + + /* for longer runs, issue a run-code */ + /* issue space char if required */ + if ( space ) { + b->data[ b->len++ ] = ' '; + space = 0; + } + + b->data[ b->len++ ] = 0x80 + ( compound >> 8 ); + b->data[ b->len++ ] = compound & 0xFF; + head = tail - 1;/* and start again */ + } + p_prev = buf_orig; /* start search again */ + } else + p_prev = p; /* got a match */ + + /* when we get to the end of the buffer, don't inc past the */ + /* end; this forces the residue chars out one at a time */ + if ( tail != end ) + ++tail; + } + xfree( buf_orig ); + + if ( space ) + b->data[ b->len++ ] = ' '; /* add left-over space */ + + /* final scan to merge consecutive high chars together */ + for ( i = j = 0; i < b->len; ++i, ++j ) { + b->data[ j ] = b->data[ i ]; + + /* skip run-length codes */ + if ( b->data[ j ] >= 0x80 && b->data[ j ] < 0xC0 ) + b->data[ ++j ] = b->data[ ++i ]; + + /* if we hit a high char marker, look ahead for another */ + else if ( b->data[ j ] == '\1' ) { + b->data[ j + 1 ] = b->data[ i + 1 ]; + while ( i + 2 < b->len && + b->data[ i + 2 ] == 1 && b->data[ j ] < 8 + ) { + b->data[ j ]++; + b->data[ j + b->data[ j ] ] = b->data[ i + 3 ]; + i += 2; + } + j += b->data[ j ]; + ++i; + } + } + b->len = j; +} + +static void write_header( void ) { + + int recs = ct-1; + struct doc_record0 *rec0; + --ct; + + rec0 = xcalloc( 1, sizeof(struct doc_record0)+(ct-1)*sizeof(short)); + be_write16( &rec0->version, COMPRESSED ); + be_write16( &rec0->reserved1, 0 ); + be_write32( &rec0->doc_size, offset ); + be_write16( &rec0->num_records, ct ); + be_write16( &rec0->rec_size, 4096 ); + be_write32( &rec0->reserved2, 0 ); + while ( recs ) { + struct recordsize *oldrec = recordsize_tail; + be_write16( &rec0->recsizes[recs], oldrec->size ); + recordsize_tail = oldrec->next; + xfree( oldrec ); + --recs; + } + + pdb_write_rec(file_out, 0, 0, 0, (void *)rec0, sizeof(struct doc_record0) + sizeof(short)*(ct-1)); + + xfree(rec0); +} + +static void write_bookmarks( void ) { + struct bookmark *oldmark = NULL; + struct bookmark_record rec; + + struct bookmark *newtail = NULL; + + /* reverse the bookmark list */ + while ( bookmark_tail ) { + oldmark = bookmark_tail; + bookmark_tail = oldmark->next; + oldmark->next = newtail; + newtail = oldmark; + } + bookmark_tail = newtail; + + ct++; + while ( bookmark_tail ) { + oldmark = bookmark_tail; + bookmark_tail = oldmark->next; + + be_write32( &rec.offset, oldmark->offset ); + memset( rec.text, 0, 16 ); + strncpy( rec.text, oldmark->text, 16 ); + + pdb_write_rec(file_out, 0, 0, ct++, (void *)&rec, sizeof(struct bookmark_record)); + + xfree( oldmark ); + } +} + +static void commit_buffer( void ) { + + struct recordsize *newrec = xcalloc( 1, sizeof(struct recordsize)); + newrec->next = recordsize_tail; + newrec->size = buf.len; + recordsize_tail = newrec; + + pd_compress( &buf ); + + pdb_write_rec(file_out, 0, 0, ct++, (void *)buf.data, buf.len); +} + +static void create_bookmark( char *bmtext ) { + struct bookmark *newmark = (struct bookmark *) xcalloc( 1, sizeof(struct bookmark)); + newmark->next = bookmark_tail; + newmark->offset = offset; + newmark->text = bmtext; + bookmark_tail = newmark; +} + +static void docprintf( int maxlen, char *format, ... ) { + + char *txt = NULL; + char *txt2 = NULL; + va_list list; + int newlen; + int partlen; + + txt = (char *) xmalloc( maxlen ); + + va_start( list, format ); + newlen = vsprintf( txt, format, list ); + + txt2 = txt; + offset += newlen; + while (txt2 && *txt2 ) { + /* append to buffer what we can */ + partlen = BUFFER_SIZE-1-buf.len; + if ( buf.len + newlen + 1 > BUFFER_SIZE ) + { + strncpy( (char *) buf.data+buf.len, txt2, partlen ); + buf.data[BUFFER_SIZE-1] = '\0'; + txt2 += partlen; + newlen -= partlen; + buf.len = BUFFER_SIZE-1; + commit_buffer(); + NEW_BUFFER( &buf ); + } + else { + strcpy( (char *) buf.data+buf.len, txt2 ); + buf.len += newlen; + txt2 = NULL; + } + } + + xfree( txt ); +} + +static void docfinish() { + commit_buffer(); + write_header(); + write_bookmarks(); +} + +static void +wr_init(const char *fname) +{ + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + + mkshort_handle = mkshort_new_handle(); + mkshort_bookmark_handle = mkshort_new_handle(); + ct = 1; + offset = 1; + recordsize_tail = NULL; + bookmark_tail = NULL; + NEW_BUFFER( &buf ); +} + +static void +wr_deinit(void) +{ + pdb_close(file_out); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_bookmark_handle); + + if ( dbname ) { + xfree(dbname); + dbname = NULL; + } +} + +static void +palmdoc_disp(const waypoint *wpt) +{ + int latint, lonint; + char tbuf[1024]; + time_t tm = wpt->creation_time; + int32 utmz; + double utme, utmn; + char utmzc; + char *bm; + fs_xml *fs_gpx = NULL; + + char bookmarktext[17]; + + if ( bmid ) { + char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt); + sprintf( bookmarktext, "%6s:%9s", + wpt->shortname?wpt->shortname:"",s); + xfree(s); + } + else { + char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt); + sprintf( bookmarktext, "%16s", s); + xfree(s); + } + + bm = xstrdup(bookmarktext); + create_bookmark(bm); + + lonint = abs((int) wpt->longitude); + latint = abs((int) wpt->latitude); + + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + + if (tm == 0) + tm = time(NULL); + strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); + + docprintf(300, "%-16s %c%d %06.3f %c%d %06.3f (%d%c %6.0f %7.0f)", + (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, + wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), + wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint), + utmz, utmzc, utme, utmn); + if (wpt->altitude != unknown_alt) + docprintf (100, " alt: %1.1f", wpt->altitude); + docprintf (10, "\n"); + if (strcmp(wpt->description, wpt->shortname)) { + docprintf(10+strlen(wpt->description), "%s\n", wpt->description); + } + if (wpt->gc_data.terr) { + + docprintf (100, "%s/%s\n", gs_get_cachetype(wpt->gc_data.type), + gs_get_container(wpt->gc_data.container)); + + if (wpt->gc_data.desc_short.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data.desc_short); + docprintf (10+strlen(stripped_html), "\n%s\n", stripped_html); + xfree(stripped_html); + } + if (wpt->gc_data.desc_long.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data.desc_long); + docprintf (10+strlen(stripped_html), "\n%s\n", stripped_html); + xfree(stripped_html); + } + if (wpt->gc_data.hint) { + char *hint = NULL; + if ( palm_encrypt ) + hint = rot13( wpt->gc_data.hint ); + else + hint = xstrdup( wpt->gc_data.hint ); + docprintf (10+strlen(hint), "\nHint: %s\n", hint); + xfree( hint ); + } + } + else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { + docprintf (10+strlen(wpt->notes), "%s\n", wpt->notes); + } + + fs_gpx = NULL; + if ( includelogs ) { + fs_gpx = (fs_xml *)fs_chain_find( wpt->fs, FS_GPX); + } + + if ( fs_gpx && fs_gpx->tag ) { + xml_tag *root = fs_gpx->tag; + xml_tag *curlog = NULL; + xml_tag *logpart = NULL; + curlog = xml_findfirst( root, "groundspeak:log" ); + while ( curlog ) { + time_t logtime = 0; + struct tm *logtm = NULL; + docprintf( 10, "\n" ); + + logpart = xml_findfirst( curlog, "groundspeak:type" ); + if ( logpart ) { + docprintf( 10+strlen(logpart->cdata), "%s by ", logpart->cdata ); + } + + logpart = xml_findfirst( curlog, "groundspeak:finder" ); + if ( logpart ) { + docprintf( 10+strlen(logpart->cdata), "%s on ", logpart->cdata ); + } + + logpart = xml_findfirst( curlog, "groundspeak:date" ); + if ( logpart ) { + logtime = xml_parse_time( logpart->cdata, NULL); + logtm = localtime( &logtime ); + if ( logtm ) { + docprintf( 15, + "%2.2d/%2.2d/%4.4d\n", + logtm->tm_mon+1, + logtm->tm_mday, + logtm->tm_year+1900 + ); + } + } + + logpart = xml_findfirst( curlog, "groundspeak:log_wpt" ); + if ( logpart ) { + char *coordstr = NULL; + float lat = 0; + int latdeg = 0; + float lon = 0; + int londeg = 0; + coordstr = xml_attribute( logpart, "lat" ); + if ( coordstr ) { + lat = atof( coordstr ); + } + coordstr = xml_attribute( logpart, "lon" ); + if ( coordstr ) { + lon = atof( coordstr ); + } + latdeg = abs(lat); + londeg = abs(lon); + + docprintf( 30, + "%c %d\xb0 %.3f' %c %d\xb0 %.3f'\n", + + lat < 0 ? 'S' : 'N', latdeg, 60.0 * (fabs(lat) - latdeg), + lon < 0 ? 'W' : 'E', londeg, 60.0 * (fabs(lon) - londeg) + ); + } + + logpart = xml_findfirst( curlog, "groundspeak:text" ); + if ( logpart ) { + char *encstr = NULL; + char *s = NULL; + int encoded = 0; + encstr = xml_attribute( logpart, "encoded" ); + encoded = (encstr[0] != 'F'); + + if ( palm_encrypt && encoded ) { + s = rot13( logpart->cdata ); + } + else { + s = xstrdup( logpart->cdata ); + } + + docprintf( 5+strlen(s), "%s", s ); + xfree( s ); + } + + docprintf( 10, "\n" ); + curlog = xml_findnext( root, curlog, "groundspeak:log" ); + } + } + if (! suppresssep) + docprintf(50, "---------------------------\n"); + else + docprintf(10, "\n"); +} + +static void +data_write(void) +{ + if ( dbname ) { + strncpy( file_out->name, dbname, PDB_DBNAMELEN ); + } + else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = DOC_TYPE; + file_out->creator = DOC_CREATOR; + file_out->version = 1; + + if (! suppresssep) + docprintf(50, "---------------------------\n"); + setshort_length(mkshort_handle, 20 ); + setshort_length(mkshort_bookmark_handle, 16-(bmid?7:0)); + setshort_whitespace_ok( mkshort_bookmark_handle, 0 ); + waypt_disp_all(palmdoc_disp); + + docfinish(); +} + + +ff_vecs_t palmdoc_vecs = { + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none}, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + palmdoc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; + + +#endif diff --git a/parse.c b/parse.c new file mode 100644 index 000000000..e6ee8b44a --- /dev/null +++ b/parse.c @@ -0,0 +1,237 @@ +/* + + Misc GPS (text to data) parsers. + + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "jeeps/gpsmath.h" +#include +#include +#include +#include +#include + +/* + * parse_distance: + * + * str: input string, i.e. "128.2 km" or "22mi" + * val: pointer to resulting value + * scale: scaling parameter for unit-less values + * module: calling module, i.e. "garmin_txt" + */ + +int +parse_distance(const char *str, double *val, double scale, const char *module) +{ + char *unit; + + if ((str == NULL) || (*str == '\0')) return 0; + + *val = strtod(str, &unit); + if (unit == NULL) + fatal("%s: Unconvertable numeric value (%s)!\n", module, str); + + if (fabs(*val) + 1 >= 1.0e25) { + return 0; /* not only Garmin uses this as 'unknown value' */ + } + + while (isspace(*unit)) unit++; + + if (*unit == '\0') { + *val *= scale; + return 1; + } + + if (case_ignore_strcmp(unit, "m") == 0) /* do nothing, that's our standard */; + else if (case_ignore_strcmp(unit, "ft") == 0) *val = FEET_TO_METERS(*val); + else if (case_ignore_strcmp(unit, "feet") == 0) *val = FEET_TO_METERS(*val); + else if (case_ignore_strcmp(unit, "km") == 0) *val *= 1000.0; + else if (case_ignore_strcmp(unit, "nm") == 0) *val = NMILES_TO_METERS(*val); + else if (case_ignore_strcmp(unit, "mi") == 0) *val = MILES_TO_METERS(*val); + else if (case_ignore_strcmp(unit, "fa") == 0) *val = FATHOMS_TO_METERS(*val); + else + fatal("%s: Unsupported distance unit in item '%s'!\n", module, str); + return 2; +} + +/* + * parse_speed: + * + * str: input string, i.e. "22.3 km/h" or "40mph" + * val: pointer to resulting value + * scale: scaling parameter for unit-less values + * module: calling module, i.e. "garmin_txt" + */ +int +parse_speed(const char *str, double *val, const double scale, const char *module) +{ + char *unit; + + if ((str == NULL) || (*str == '\0')) return 0; + + *val = strtod(str, &unit); + if (unit == NULL) + fatal("%s: Unconvertable numeric value (%s)!\n", module, str); + + while (isspace(*unit)) unit++; + + if (*unit == '\0') { + *val *= scale; + return 1; + } + + if (case_ignore_strcmp(unit, "m/s") == 0) ; + else if (case_ignore_strcmp(unit, "mps") == 0) ; + else if (case_ignore_strcmp(unit, "kph") == 0) *val = KPH_TO_MPS(*val); + else if (case_ignore_strcmp(unit, "km/h") == 0) *val = KPH_TO_MPS(*val); + else if (case_ignore_strcmp(unit, "kmh") == 0) *val = KPH_TO_MPS(*val); + else if (case_ignore_strcmp(unit, "kt") == 0) *val = KNOTS_TO_MPS(*val); + else if (case_ignore_strcmp(unit, "knot") == 0) *val = KNOTS_TO_MPS(*val); + else if (case_ignore_strcmp(unit, "mph") == 0) *val = MPH_TO_MPS(*val); + else if (case_ignore_strcmp(unit, "mi/h") == 0) *val = MPH_TO_MPS(*val); + else if (case_ignore_strcmp(unit, "mih") == 0) *val = MPH_TO_MPS(*val); + else + fatal("%s: Unsupported speed unit '%s' in item '%s'!\n", module, unit, str); + + return 2; +} + +/* + * Convert string 'str' into geodetic latitide & longitude values. The format + * will be interpreted depending on 'grid' parameter. + * + * return value: number of characters efective parsed + */ + +int +parse_coordinates(const char *str, int datum, const grid_type grid, + double *latitude, double *longitude, const char *module) +{ + double lat, lon; + unsigned char lathemi, lonhemi; + int deg_lat, deg_lon, min_lat, min_lon; + char map[3]; + int utmz; + double utme, utmn; + char utmc; + int valid, result, ct; + double lx, ly; + const char *format; + + valid = 1; + + switch(grid) { + + case grid_lat_lon_ddd: + format = "%c%lf %c%lf%n"; + ct = sscanf(str, format, + &lathemi, &lat, &lonhemi, &lon, &result); + valid = (ct == 4); + break; + + case grid_lat_lon_dmm: + format = "%c%d %lf %c%d %lf%n"; + ct = sscanf(str, format, + &lathemi, °_lat, &lat, &lonhemi, °_lon, &lon, &result); + valid = (ct == 6); + if (valid) { + lat = (double)deg_lat + (lat / (double)60); + lon = (double)deg_lon + (lon / (double)60); + } + break; + + case grid_lat_lon_dms: + format = "%c%d %d %lf %c%d %d %lf%n"; + ct = sscanf(str, format, + &lathemi, °_lat, &min_lat, &lat, &lonhemi, °_lon, &min_lon, &lon, + &result); + valid = (ct == 8); + if (valid) { + lat = (double)deg_lat + ((double)min_lat / (double)60) + (lat / (double)3600.0); + lon = (double)deg_lon + ((double)min_lon / (double)60) + (lon / (double)3600.0); + } + break; + + case grid_bng: + datum = DATUM_WGS84; /* fix */ + format = "%2s %lf %lf%n"; + ct = sscanf(str, format, + map, &lx, &ly, + &result); + valid = (ct == 3); + if (valid) { + if (! GPS_Math_UKOSMap_To_WGS84_M(map, lx, ly, &lat, &lon)) + fatal("%s: Unable to convert BNG coordinates (%s)!\n", + module, str); + } + lathemi = lonhemi = '\0'; + break; + + case grid_utm: + format = "%d %c %lf %lf%n"; + ct = sscanf(str, format, + &utmz, &utmc, &utme, &utmn, + &result); + valid = (ct == 4); + if (valid) { + if (! GPS_Math_UTM_EN_To_Known_Datum(&lat, &lon, utme, utmn, utmz, utmc, datum)) + fatal("%s: Unable to convert UTM coordinates (%s)!\n", + module, str); + } + lathemi = lonhemi = '\0'; + break; + + case grid_swiss: { + double east, north; + + datum = DATUM_WGS84; /* fix */ + format = "%lf %lf%n"; + ct = sscanf(str, format, + &east, &north, &result); + valid = (ct == 2); + GPS_Math_CH1903_NGEN_To_WGS84(east, north, &lat, &lon); + break; + } + default: + /* this should never happen in a release version */ + fatal("%s/util: Unknown grid in parse_coordinates (%d)!\n", + module, (int)grid); + } + + if (! valid) { + warning("%s: sscanf error using format \"%s\"!\n", module, format); + warning("%s: parsing has stopped at parameter number %d.\n", module, ct); + fatal("%s: could not convert coordinates \"%s\"!\n", module, str); + } + + if (lathemi == 'S') lat = -lat; + if (lonhemi == 'W') lon = -lon; + + if (datum != DATUM_WGS84) { + double alt; + GPS_Math_Known_Datum_To_WGS84_M(lat, lon, (double) 0.0, + &lat, &lon, &alt, datum); + } + + if (latitude) *latitude = lat; + if (longitude) *longitude = lon; + + return result; +} diff --git a/pathaway.c b/pathaway.c new file mode 100644 index 000000000..ee3705760 --- /dev/null +++ b/pathaway.c @@ -0,0 +1,712 @@ +/* + Support for PathAway Palm Database, + Copyright (C) 2005-2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +/* + remarks: + + The german release 3.0 of PathAway violates the PathAway standards: + * N.. .... O.. .... instead of N.. .... E.. .... + * date is formatted in DDMMYYYY instead of YYYYMMDD + + Release 4.x store only numeric coordinates and uses a six-number date. +*/ + +#include +#include "defs.h" +#if PDBFMTS_ENABLED +#include "csv_util.h" +#include "pdbfile.h" +#include "strptime.h" + +#define MYNAME "pathaway" + +#define PPDB_MAGIC_TRK 0x55735472 /* UsTr */ +#define PPDB_MAGIC_WPT 0x506f4c69 /* PoLi */ +#define PPDB_MAGIC 0x4b6e5772 /* KwNr */ + +static pdbfile *file_in, *file_out; +static char *fname_out; +static short_handle mkshort_handle; +static gpsdata_type ppdb_type; +static unsigned char german_release = 0; +static char *datefmt; +static int ct; + +typedef struct ppdb_appdata +{ + unsigned char reservedA[274]; /* all 0 */ + unsigned char dirtyFlag; + unsigned char dataBaseSubType; /* 0 = Track, 1 = Route */ + short int dbAttributes; /* 0 */ + char vehicleStr[100]; + unsigned char reservedB[100]; /* all 0 */ +} ppdb_appdata_t; + +#define PPDB_APPINFO_SIZE sizeof(struct ppdb_appdata) +static ppdb_appdata_t *appinfo; + +static char *opt_dbname = NULL; +static char *opt_deficon = NULL; +static char *opt_snlen = NULL; +static char *opt_date = NULL; + +static arglist_t ppdb_args[] = +{ + {"date", &opt_date, "Read/Write date format (i.e. DDMMYYYY)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"dbname", &opt_dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"snlen", &opt_snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + +/*#undef PPDB_DEBUG*/ +#define PPDB_DEBUG 1 + +#if PPDB_DEBUG +static void +internal_debug1(const char *filename, int fileline) +{ + static int ct=1; + printf("DBG(%d): file %s, line %d: ", ct++, filename, fileline); +} +static void +internal_debug2(const char *format, ... ) +{ + va_list args; + + va_start(args, format); + vprintf(format, args); + puts(""); + va_end(args); +} +#define DBG(args) internal_debug1(__FILE__, __LINE__);internal_debug2 args +#else +#define DBG(args) ; +#endif + + +#define CHECK_INP(i, j, k) is_fatal((i != j), "Error in data structure (%s).", (k)) + +/* + * utilities + */ + +static +char *ppdb_strcat(char *dest, char *src, char *def, int *size) +{ + int len; + char *res, *tmp; + + tmp = src; + if (tmp == NULL) + { + tmp = def; + if (tmp == NULL) return dest; + } + if (*tmp == '\0') return dest; + + len = strlen(dest) + strlen(tmp) + 1; + if (len > *size) + { + *size = len; + res = xrealloc(dest, *size); + } + else + res = dest; + strcat(res, tmp); + return res; +} + +#define STR_POOL_SIZE 16 /* !!! any power of 2 !!! */ + +static char *str_pool[STR_POOL_SIZE]; +static size_t str_pool_s[STR_POOL_SIZE]; +static int str_poolp = -1; + +static +void str_pool_init(void) +{ + int i; + for (i = 0; i < STR_POOL_SIZE; i++) + { + str_pool[i] = NULL; + str_pool_s[i] = 0; + } +} + +static +void str_pool_deinit(void) +{ + int i; + + for (i = 0; i < STR_POOL_SIZE; i++) + if ( str_pool_s[i] != 0 ) + { + xfree(str_pool[i]); + str_pool[i] = NULL; + str_pool_s[i] = 0; + } +} + +static +char *str_pool_get(size_t size) +{ + char *tmp; + + str_poolp = ((str_poolp + 1) & (STR_POOL_SIZE - 1)); + tmp = str_pool[str_poolp]; + + if (str_pool_s[str_poolp] == 0) + tmp = xmalloc(size); + else if (str_pool_s[str_poolp] < size) + tmp = xrealloc(tmp, size); + else + return tmp; + + str_pool[str_poolp] = tmp; + str_pool_s[str_poolp] = size; + + return tmp; +} + +static +char *str_pool_getcpy(char *src, char *def) +{ + char *res; + + if (src == NULL) + { + src = def; + if (src == NULL) src = ""; + } + res = str_pool_get(strlen(src) + 1); + strcpy(res, src); + + return res; +} + +/* + * decoding/formatting functions + */ + +static +char *ppdb_fmt_float(const double val) +{ + char *str = str_pool_get(32); + char *c; + snprintf(str, 32, "%.8f", val); + c = str + strlen(str) - 1; + while ((c > str) && (*c == '0')) + { + *c = '\0'; + c--; + if (*c == '.') + { + c++; + *c = '0'; + break; + } + } + return str; +} + +static +char *ppdb_fmt_degrees(char dir, double val) +{ + char *str = str_pool_get(32); + int deg = fabs(val); + double min = 60.0 * (fabs(val) - deg); + char *tmp; + + snprintf(str, 31, "%c%0*d %.8f", dir, (deg > 99) ? 3 : 2, deg, min); + + tmp = str + strlen(str) - 1; /* trim trailing nulls */ + while ((tmp > str) && (*tmp == '0')) + { + *tmp = '\0'; + tmp--; + if (*tmp == '.') + { + tmp++; + *tmp = '0'; + break; + } + } + return str; +} + +static +double ppdb_decode_coord(const char *str) +{ + double val; + int deg; + char dir; + + if (*str < 'A') /* only numeric */ + { + CHECK_INP(1, sscanf(str,"%lf", &val), "decode_coord(1)"); + return val; + } + else + { + char *tmp; + + if (*str == 'O') german_release = 1; + + tmp = strchr(str, ' '); + if ((tmp) && (tmp - str < 5)) + { + CHECK_INP(3, sscanf(str,"%c%d %lf", &dir, °, &val), "decode_coord(2)"); + val = deg + (val / 60.0); + } + else + { + CHECK_INP(2, sscanf(str,"%c%lf", &dir, &val), "decode_coord(3)"); + } + if ((dir == 'S') || (dir == 'W')) + val = -val; + } + return val; +} + +static +int ppdb_decode_tm(char *str, struct tm *tm) +{ + int msec, d1, d2, d3, d4; + int year; + char *cx; + + if (*str == '\0') return 0; /* empty date and time */ + + if (strchr(str, '.')) /* time in hhmmss.ms */ + { + CHECK_INP(4, sscanf(str, "%02d%02d%02d.%d", + &tm->tm_hour, &tm->tm_min, &tm->tm_sec, &msec), + "decode_tm(1)"); + } + else + { + CHECK_INP(3, sscanf(str, "%02d%02d%02d", + &tm->tm_hour, &tm->tm_min, &tm->tm_sec), + "decode_tm(2)"); + } + cx = strchr(str, ' '); + if (cx == NULL) return 0; /* no date */ + + while (*cx == ' ') cx++; + if (*cx == '\0') return 0; /* no date */ + + if (datefmt) + { + struct tm tm2; + + if (NULL == strptime(cx, datefmt, &tm2)) + { + fatal(MYNAME ": Unable to convert date '%s' using format '%s' (%s)!\n", cx, datefmt, opt_date); + } + + tm->tm_year = tm2.tm_year + 1900; + tm->tm_mon = tm2.tm_mon + 1; + tm->tm_mday = tm2.tm_mday; + } + else + { + time_t tnow; + struct tm now; + + if (strlen(cx) != 8) + { + printf(MYNAME ": Date from first record is %s.\n", cx); + printf(MYNAME ": Please use option 'date' to specify how this is formatted.\n"); + fatal(MYNAME ": (... -i pathaway,date=DDMMYY ...)\n"); + } + + CHECK_INP(4, sscanf(cx, "%02d%02d%02d%02d", &d1, &d2, &d3, &d4), "decode_tm(3)"); + + tnow = current_time(); + now = *localtime(&tnow); + now.tm_year += 1900; + now.tm_mon++; + + year = (d1 * 100) + d2; + + /* the coordinates comes before date and time in + the dataset, so the flag "german_release" is set yet. */ + + /* next code works for most, except for 19. and 20. of month */ + + if ((german_release != 0) || (year < 1980) || (year > now.tm_year)) /* YYYYMMDD or DDMMYYY ????? */ + { + tm->tm_year = (d3 * 100) + d4; + tm->tm_mon = d2; + tm->tm_mday = d1; + } + else + { + tm->tm_year = (d1 * 100) + d2; + tm->tm_mon = d3; + tm->tm_mday = d4; + } + } + return 1; +} + +static +int ppdb_read_wpt(route_head *head, int isRoute) +{ + char *data, *str; + double altfeet; + struct tm tm; + + while (pdb_read_rec(file_in, NULL, NULL, NULL, (void *)&data) >= 0) { + waypoint *wpt_tmp = waypt_new(); + int line = 0; + char *tmp = data; + + while ((str = csv_lineparse(tmp, ",", """", line++))) { + tmp = NULL; + switch(line) + { + case 1: + wpt_tmp->latitude = ppdb_decode_coord(str); + break; + case 2: + wpt_tmp->longitude = ppdb_decode_coord(str); + break; + case 3: + if (*str != '\0') + { + CHECK_INP(1, sscanf(str, "%lf", &altfeet), "altitude"); + if (altfeet != -9999) + wpt_tmp->altitude = FEET_TO_METERS(altfeet); + } + break; + case 4: + memset(&tm, 0, sizeof(tm)); + if (ppdb_decode_tm(str, &tm)) + { + tm.tm_year -= 1900; + tm.tm_mon--; + wpt_tmp->creation_time = mkgmtime(&tm); + } + break; + case 5: + if (*str != '\0') + wpt_tmp->shortname = xstrdup(str); + break; + case 6: /* icon, ignore */ + break; + case 7: + if (*str != '\0') + wpt_tmp->notes = xstrdup(str); + break; + + } + } + + if (head && isRoute ) + route_add_wpt(head, wpt_tmp); + else if (head) + track_add_wpt(head, wpt_tmp); + else + waypt_add(wpt_tmp); + + } + return 0; +} + +/* ============================================================================================ + * &&& gobal callbacks &&& + * ----------------------------------------------------------------------------------------- */ + +static void ppdb_rd_init(const char *fname) +{ + str_pool_init(); + file_in = pdb_open(fname, MYNAME); + ct = 0; + + if (opt_date) + datefmt = convert_human_date_format(opt_date); + else + datefmt = NULL; +} + +static void ppdb_rd_deinit(void) +{ + pdb_close(file_in); + str_pool_deinit(); + if (datefmt) xfree(datefmt); +} + +static void ppdb_read(void) +{ + ppdb_appdata_t *info = NULL; + route_head *track_head, *route_head; + const char *descr = NULL; + + if (file_in->creator != PPDB_MAGIC) /* identify the database */ + fatal(MYNAME ": Not a PathAway pdb file.\n"); + + if (file_in->version != 3) /* Currently we support only version 3 */ + fatal(MYNAME ": This file is from an untested version (%d) of PathAway and is unsupported.\n", file_in->version); + + if ((file_in->appinfo_len > 0) && (file_in->appinfo != NULL)) + { + info = (ppdb_appdata_t *) file_in->appinfo; + descr = info->vehicleStr; + } + switch(file_in->type) + { + case PPDB_MAGIC_TRK: + ppdb_type = trkdata; /* as default */ + if (info != NULL) + { + switch(info->dataBaseSubType) + { + case 0: + ppdb_type = trkdata; + break; + case 1: + ppdb_type = rtedata; + break; + default: + fatal(MYNAME": Invalid database subtype.\n"); + } + } + break; + + case PPDB_MAGIC_WPT: + ppdb_type = wptdata; + break; + + default: + fatal(MYNAME ": It looks like a PathAway pdb, but has no gps magic.\n"); + } + + switch(ppdb_type) + { + case trkdata: + track_head = route_head_alloc(); + track_add_head(track_head); + track_head->rte_name = xstrdup(file_in->name); + ppdb_read_wpt(track_head, 0); + break; + case rtedata: + route_head = route_head_alloc(); + route_add_head(route_head); + route_head->rte_name = xstrdup(file_in->name); + ppdb_read_wpt(route_head, 1); + break; + case wptdata: + ppdb_read_wpt(NULL, 0); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } +} + +/* ============================================================================================ + * PPDB: Write support + * -------------------------------------------------------------------------------------------*/ + +static void ppdb_wr_init(const char *fname) +{ + int len; + + fname_out = xstrdup(fname); + str_pool_init(); + file_out = pdb_create(fname, MYNAME); + mkshort_handle = mkshort_new_handle(); + ct = 0; + appinfo = NULL; + + if (global_opts.synthesize_shortnames != 0) + { + len = atoi(opt_snlen); + setshort_length(mkshort_handle, len); + setshort_mustupper(mkshort_handle, 1); + setshort_badchars(mkshort_handle, ","); + setshort_whitespace_ok(mkshort_handle, 0); + } + if (opt_date) + { + char *c = convert_human_date_format(opt_date); + xasprintf(&datefmt, "%s %s", "%H%M%S", c); + xfree(c); + } + else + datefmt = xstrdup("%H%M%S %Y%m%d"); +} + +static void ppdb_wr_deinit(void) +{ + mkshort_del_handle(&mkshort_handle); + pdb_close(file_out); + str_pool_deinit(); + xfree(fname_out); + if (datefmt) xfree(datefmt); + if (appinfo) xfree(appinfo); +} + +/* + * ppdb_write_wpt: callback for waypoint output + */ + +#define REC_SIZE 128 + +static void ppdb_write_wpt(const waypoint *wpt) +{ + char *buff, *tmp; + char latdir, longdir; + int len; + struct tm tm; + + buff = xcalloc(REC_SIZE, 1); + + if (wpt->latitude < 0) + latdir = 'S'; + else + latdir = 'N'; + if (wpt->longitude < 0) + longdir = 'W'; + else + longdir = 'E'; + + snprintf(buff, REC_SIZE, "%s,%s,", + ppdb_fmt_degrees(latdir, wpt->latitude), + ppdb_fmt_degrees(longdir, wpt->longitude) + ); + + len = REC_SIZE; /* we have coordinates in buff, now optional stuff */ + + if (fabs(wpt->altitude) < 9999.0) + { + tmp = str_pool_get(32); + snprintf(tmp, 32, ppdb_fmt_float(METERS_TO_FEET(wpt->altitude))); + buff = ppdb_strcat(buff, tmp, NULL, &len); + } + buff = ppdb_strcat(buff, ",", NULL, &len); + if ( wpt->creation_time != 0) + { + tmp = str_pool_get(20); + tm = *gmtime(&wpt->creation_time); + strftime(tmp, 20, datefmt, &tm); + buff = ppdb_strcat(buff, tmp, NULL, &len); + } + buff = ppdb_strcat(buff, ",", NULL, &len); + + if (global_opts.synthesize_shortnames != 0) + { + tmp = mkshort_from_wpt(mkshort_handle, wpt); + DBG(("shortname %s from %s", tmp, wpt->shortname)); + } + else + { + tmp = str_pool_getcpy(wpt->shortname, ""); + while (strchr(tmp, ',') != NULL) + *strchr(tmp, ',') = '.'; + } + buff = ppdb_strcat(buff, tmp, "", &len); + + buff = ppdb_strcat(buff, ",", NULL, &len); + buff = ppdb_strcat(buff, opt_deficon, "0", &len); + buff = ppdb_strcat(buff, ",", NULL, &len); + + tmp = str_pool_getcpy(wpt->description, ""); + if (strchr(tmp, ',') != NULL ) + { + buff = ppdb_strcat(buff, "\"", NULL, &len); + while (strchr(tmp, '"') != NULL) + *strchr(tmp, '"') = '\''; + buff = ppdb_strcat(buff, tmp, NULL, &len); + buff = ppdb_strcat(buff, "\"", NULL, &len); + } + else + buff = ppdb_strcat(buff, tmp, "", &len); + + len = strlen(buff) + 1; + pdb_write_rec(file_out, 0, 0, ct++, buff, len); + + xfree(buff); +} + +/* + * track and route write callbacks + */ + +static void ppdb_write(void) +{ + + if (opt_dbname) + strncpy(file_out->name, opt_dbname, PDB_DBNAMELEN); + + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->creator = PPDB_MAGIC; + file_out->version = 3; + + if (global_opts.objective != wptdata) /* Waypoint target do not need appinfo block */ + { + appinfo = xcalloc(1, sizeof(*appinfo)); + file_out->appinfo = (void *)appinfo; + file_out->appinfo_len = PPDB_APPINFO_SIZE; + } + + switch(global_opts.objective) /* Only one target is possible */ + { + case wptdata: + if (opt_dbname == NULL) strncpy(file_out->name, "PathAway Waypoints", PDB_DBNAMELEN); + file_out->type = PPDB_MAGIC_WPT; + waypt_disp_all(ppdb_write_wpt); + break; + case trkdata: + if (opt_dbname == NULL) strncpy(file_out->name, "PathAway Track", PDB_DBNAMELEN); + file_out->type = PPDB_MAGIC_TRK; + appinfo->dataBaseSubType = 0; + track_disp_all(NULL, NULL, ppdb_write_wpt); + break; + case rtedata: + if (opt_dbname == NULL) strncpy(file_out->name, "PathAway Route", PDB_DBNAMELEN); + file_out->type = PPDB_MAGIC_TRK; + appinfo->dataBaseSubType = 1; + route_disp_all(NULL, NULL, ppdb_write_wpt); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } +} + + +ff_vecs_t ppdb_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + ppdb_rd_init, + ppdb_wr_init, + ppdb_rd_deinit, + ppdb_wr_deinit, + ppdb_read, + ppdb_write, + NULL, + ppdb_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; +#endif diff --git a/pcx.c b/pcx.c new file mode 100644 index 000000000..d447ec76f --- /dev/null +++ b/pcx.c @@ -0,0 +1,454 @@ +/* + Access to Garmin PCX5 files. + Format described in: http://www.garmin.com/manuals/PCX5_OwnersManual.pdf + + Copyright (C) 2002-2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include "defs.h" +#include "garmin_tables.h" +#include "csv_util.h" +#include + +static gbfile *file_in, *file_out; +static short_handle mkshort_handle; +static short_handle mkshort_handle2; /* for track and route names */ +static char *deficon = NULL; +static char *cartoexploreur; +static int read_as_degrees; +static int read_gpsu; +static int route_ctr; +static int comment_col = 60; /* This has a default */ +static int sym_col; +static int lat_col; +static int lon_col; + +#define MYNAME "PCX" + +static +arglist_t pcx_args[] = { + {"deficon", &deficon, "Default icon name", "Waypoint", + ARGTYPE_STRING, ARG_NOMINMAX }, + {"cartoexploreur", &cartoexploreur, + "Write tracks compatible with Carto Exploreur", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static void +rd_init(const char *fname) +{ + file_in = gbfopen(fname, "rb", MYNAME); +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); + mkshort_handle2 = mkshort_new_handle(); +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_handle2); +} + +static void +data_read(void) +{ + char name[7], desc[41]; + double lat = 0, lon = 0; + long alt; + int symnum; + char date[10]; + char time[9]; + char month[4]; + waypoint *wpt_tmp; + char *buff; + struct tm tm; + route_head *track = NULL; + route_head *route = NULL; + int n; + char lathemi, lonhemi; + char tbuf[20]; + char nbuf[20]; + int points; + + read_as_degrees = 0; + points = 0; + + while ((buff = gbfgetstr(file_in))) + { + char *ibuf = lrtrim(buff); + char *cp; + + switch (ibuf[0]) { + case 'W': + time[0] = 0; + date[0] = 0; + desc[0] = 0; + alt = -9999; + sscanf(ibuf, "W %6c %s %s %s %s %ld", + name, tbuf, nbuf, date, time, &alt); + if (alt == -9999) { + alt = unknown_alt; + } + + if (comment_col) { + strncpy(desc, &ibuf[comment_col], sizeof(desc)-1); + } else { + desc[0] = 0; + } + + + symnum = 18; + if (sym_col) { + symnum = atoi(&ibuf[sym_col]); + } + + // If we have explicit columns for lat and lon, + // copy those entire words (warning: no spaces) + // into the respective coord buffers. + if (lat_col) { + sscanf(tbuf, "%s", ibuf + lat_col); + } + if (lon_col) { + sscanf(nbuf, "%s", ibuf + lon_col); + } + + name[sizeof(name)-1] = '\0'; + desc[sizeof(desc)-1] = '\0'; + + wpt_tmp = waypt_new(); + wpt_tmp->altitude = alt; + cp = lrtrim(name); + if (*cp != '\0') { + wpt_tmp->shortname = xstrdup(cp); + } + cp = lrtrim(desc); + if (*cp != '\0') { + wpt_tmp->description = xstrdup(cp); + } + wpt_tmp->icon_descr = gt_find_desc_from_icon_number(symnum, PCX, NULL); + + if (read_as_degrees || read_gpsu) { + human_to_dec(tbuf, &lat, &lon, 1); + human_to_dec(nbuf, &lat, &lon, 2); + + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + } else { + lat = atof(&tbuf[1]); + lon = atof(&nbuf[1]); + if (tbuf[0] == 'S') lat = -lat; + if (nbuf[0] == 'W') lon = -lon; + wpt_tmp->longitude = ddmm2degrees(lon); + wpt_tmp->latitude = ddmm2degrees(lat); + } + if (route != NULL) + route_add_wpt(route, waypt_dupe(wpt_tmp)); + waypt_add(wpt_tmp); + points++; + break; + case 'H': + /* Garmap2 has headers + "H(2 spaces)LATITUDE(some spaces)LONGTITUDE(etc... followed by);track + everything else is + H(2 chars)TN(tracknane\0) + */ + if (points > 0) { + track = NULL; + points = 0; + } + if (track == NULL) { + if (ibuf[3] == 'L' && ibuf[4] == 'A') { + track = route_head_alloc(); + track->rte_name = xstrdup("track"); + track_add_head(track); + } else if (ibuf[3] == 'T' && ibuf[4] == 'N') { + track = route_head_alloc(); + track->rte_name = xstrdup(&ibuf[6]); + track_add_head(track); + } + } + break; + case 'R': + n = 1; + while (ibuf[n] == ' ') n++; + route = route_head_alloc(); + route->rte_name = xstrdup(&ibuf[n]); + route_add_head(route); + break; + case 'T': + n = sscanf(ibuf, "T %lf %lf %s %s %ld", + &lat, &lon, date, time, &alt); + + if (n == 0) { + /* Attempt alternate PCX format used by + * www.radroutenplaner.nrw.de */ + n = sscanf(ibuf, "T %c%lf %c%lf %s %s %ld", + &lathemi, &lat, &lonhemi, &lon, date, + time, &alt); + if (lathemi == 'S') lat = -lat; + if (lonhemi == 'W') lon = -lon; + } else if (n == 0) { + fatal(MYNAME ":Unrecognized track line '%s'\n", + ibuf); + } + + memset(&tm, 0, sizeof(tm)); + tm.tm_hour = atoi(time); + tm.tm_min = atoi(time+3); + tm.tm_sec = atoi(time+6); + tm.tm_mday = atoi(date); + strncpy(month, date+3, 3); + month[3] = 0; + tm.tm_mon = month_lookup(month); + tm.tm_year = atoi(date + 7); + if (tm.tm_year < 70) tm.tm_year += 100; + wpt_tmp = waypt_new(); + wpt_tmp->creation_time = mkgmtime(&tm); + if (read_as_degrees) { + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + } else { + wpt_tmp->longitude = ddmm2degrees(lon); + wpt_tmp->latitude = ddmm2degrees(lat); + } + wpt_tmp->altitude = alt; + /* Did we get a track point before a track header? */ + if (track == NULL) { + track = route_head_alloc(); + track->rte_name = xstrdup("Default"); + track_add_head(track); + } + track_add_wpt(track, wpt_tmp); + points++; + break; + case 'U': + read_as_degrees = ! strncmp("LAT LON DEG", ibuf + 3, 11); + if (strstr(ibuf, "UTM")) { + fatal (MYNAME ": UTM is not supported.\n"); + } + break; + // GPSU is apparently PCX but with a different definition + // of "LAT LON DM" - unlike the other, it actually IS decimal + // minutes. + case 'I': + read_gpsu = ! (strstr(ibuf, "GPSU") == NULL) ; + break; + // This is a format specifier. Use this line to figure out + // where our other columns start. + case 'F': { + int col; + char *i = ibuf; + sym_col = 0; + + for (col = 0, i = ibuf; *i; col++, i++) { + if (0 == case_ignore_strncmp(i, "comment", 7)) { + comment_col = col; + } + if (0 == case_ignore_strncmp(i, "symbol", 6)) { + sym_col = col; + } + if (0 == case_ignore_strncmp(i, "latitude", 8)) { + lat_col = col; + } + if (0 == case_ignore_strncmp(i, "longitude", 9)) { + lon_col = col; + } + } + } + break; + default: + break; + ; + + } + } +} + +static void +gpsutil_disp(const waypoint *wpt) +{ + double lon,lat; + int icon_token = 0; + char tbuf[1024]; + time_t tm = wpt->creation_time; + + lon = degrees2ddmm(wpt->longitude); + lat = degrees2ddmm(wpt->latitude); + + if (tm == 0) + tm = current_time(); + strftime(tbuf, sizeof(tbuf), "%d-%b-%y %I:%M:%S", localtime(&tm)); + strupper(tbuf); + + if (deficon) { + icon_token = atoi(deficon); + } else { + icon_token = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + if (get_cache_icon(wpt)) { + icon_token = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + } + } + + + gbfprintf(file_out, "W %-6.6s %c%08.5f %c%011.5f %s %5.f %-40.40s %5e %d\n", + global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, wpt) : + wpt->shortname, + lat < 0.0 ? 'S' : 'N', + fabs(lat), + lon < 0.0 ? 'W' : 'E', + fabs(lon), + tbuf, + (wpt->altitude == unknown_alt) ? -9999 : wpt->altitude, + (wpt->description != NULL) ? wpt->description : "", + 0.0, + icon_token); +} + +static void +pcx_track_hdr(const route_head *trk) +{ + char *name; + char buff[20]; + + route_ctr++; + snprintf(buff, sizeof(buff)-1, "Trk%03d", route_ctr); + + name = mkshort(mkshort_handle2, (trk->rte_name != NULL) ? trk->rte_name : buff); + /* Carto Exploreur (popular in France) chokes on trackname headers, + * so provide option to supppress these. + */ + if (!cartoexploreur) { + gbfprintf(file_out, "\n\nH TN %s\n", name); + } + xfree(name); + gbfprintf(file_out, "H LATITUDE LONGITUDE DATE TIME ALT ;track\n"); +} + +static void +pcx_route_hdr(const route_head *rte) +{ + char *name; + char buff[20]; + + route_ctr++; + snprintf(buff, sizeof(buff)-1, "Rte%03d", route_ctr); + + name = mkshort(mkshort_handle2, (rte->rte_name != NULL) ? rte->rte_name : buff); + + /* see pcx_track_hdr */ + if (!cartoexploreur) { + gbfprintf(file_out, "\n\nR %s\n", name); + } + gbfprintf(file_out, "\n" +"H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); +} + +void +pcx_track_disp(const waypoint *wpt) +{ + double lon,lat; + char tbuf[100]; + struct tm *tm; + char *tp; + + lon = degrees2ddmm(wpt->longitude); + lat = degrees2ddmm(wpt->latitude); + + tm = gmtime(&wpt->creation_time); + + strftime(tbuf, sizeof(tbuf), "%d-%b-%y %H:%M:%S", tm); /* currently ...%T does nothing under Windows */ + for (tp = tbuf; *tp; tp++) { + *tp = toupper(*tp); + } + gbfprintf(file_out, "T %c%08.5f %c%011.5f %s %.f\n", + lat < 0.0 ? 'S' : 'N', + fabs(lat), + lon < 0.0 ? 'W' : 'E', + fabs(lon), + tbuf, wpt->altitude); +} + + +static void +data_write(void) +{ +gbfprintf(file_out, +"H SOFTWARE NAME & VERSION\n" +"I PCX5 2.09\n" +"\n" +"H R DATUM IDX DA DF DX DY DZ\n" +"M G WGS 84 121 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00\n" +"\n" +"H COORDINATE SYSTEM\n" +"U LAT LON DM\n"); + + setshort_length(mkshort_handle, 6); + + setshort_length(mkshort_handle2, 20); /* for track and route names */ + setshort_whitespace_ok(mkshort_handle2, 0); + setshort_mustuniq(mkshort_handle2, 0); + + if (global_opts.objective == wptdata) + { + gbfprintf(file_out, +"\n" +"H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); + + waypt_disp_all(gpsutil_disp); + } + else if (global_opts.objective == trkdata) + { + route_ctr = 0; + track_disp_all(pcx_track_hdr, NULL, pcx_track_disp); + } + else if (global_opts.objective == rtedata) + { + route_ctr = 0; + route_disp_all(pcx_route_hdr, NULL, gpsutil_disp); + } +} + + +ff_vecs_t pcx_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + pcx_args, + CET_CHARSET_ASCII, 1 /* CET-REVIEW */ +}; diff --git a/pdbfile.c b/pdbfile.c new file mode 100644 index 000000000..2f9c1638f --- /dev/null +++ b/pdbfile.c @@ -0,0 +1,431 @@ +/* + + Minimum support for Palm/OS database files + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org + + Written after study the Coldsync project + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +#if PDBFMTS_ENABLED + +#include "gbfile.h" +#include "pdbfile.h" +#include +#include + + +#define MYNAME "pdbfile" + +static void +pdb_invalid_file(const pdbfile *pdb_in, const char *fmt, ...) +{ + char buff[128]; + va_list args; + + va_start(args, fmt); + vsnprintf(buff, sizeof(buff), fmt, args); + buff[sizeof(buff)-1] = '0'; + + warning(MYNAME ": %s\n", buff); + fatal(MYNAME ": Invalid or unsupported file (%s).\n", pdb_in->file->name); +} + +/* try to read to EOF (avoid determining file-size) */ + +static void * +pdb_read_tail(gbfile *fin, gbuint32 *size) +{ + int count; + char buff[256]; + char *res = NULL; + int bytes = 0; + + while ((count = gbfread(buff, 1, sizeof(buff), fin))) { + + if (!res) { + res = xmalloc(count); + memcpy(res, buff, count); + } + else { + res = xrealloc(res, bytes + count); + memcpy(&res[bytes], buff, count); + } + bytes += count; + } + if (res) res = xrealloc(res, bytes + 1); + else res = xmalloc(1); + res[bytes] = '\0'; + + if (size) *size = bytes; + return (void *)res; +} + +static void +pdb_load_data(pdbfile *fin) +{ + gbuint16 i, ct; + pdbrec_t *last_rec; + gbuint32 offs; + pdbrec_t *rec; + + /* load the header */ + gbfread(fin->name, 1, PDB_DBNAMELEN, fin->file); + fin->name[PDB_DBNAMELEN] = '\0'; + + fin->attr = gbfgetuint16(fin->file); + fin->version = gbfgetuint16(fin->file); + fin->ctime = gbfgetuint32(fin->file); + fin->mtime = gbfgetuint32(fin->file); + fin->btime = gbfgetuint32(fin->file); + fin->revision = gbfgetuint32(fin->file); + fin->appinfo_offs = gbfgetint32(fin->file); + fin->index_offs = gbfgetuint32(fin->file); + fin->type = gbfgetuint32(fin->file); + fin->creator = gbfgetuint32(fin->file); + fin->uid = gbfgetuint32(fin->file); + + if (fin->appinfo_offs < 0) + pdb_invalid_file(fin, "Invalid application data offset (%0xh)", fin->appinfo_offs); + if (fin->index_offs < 0) + pdb_invalid_file(fin, "Invalid index offset (%0xh)", fin->index_offs); + +#if 0 + fprintf(stderr, "%s: dbname \"%s\"\n", MYNAME, fin->name); + fprintf(stderr, "%s: attr %-8x\n", MYNAME, fin->attr); + fprintf(stderr, "%s: creator %-8x\n", MYNAME, fin->creator); + fprintf(stderr, "%s: type %-8x\n", MYNAME, fin->type); + fprintf(stderr, "%s: ver %-8u\n", MYNAME, fin->version); + fprintf(stderr, "%s: app-ofs %-8u\n", MYNAME, fin->appinfo_offs); + fprintf(stderr, "%s: index-ofs %-8u\n", MYNAME, fin->index_offs); +#endif + /* ID = */ (void) gbfgetuint32(fin->file); + ct = fin->rec_ct = gbfgetint16(fin->file); + if (ct >= 0x7FFF) + warning(MYNAME ": Probably invalid number of records (%0d)\n", fin->rec_ct); + + offs = 78; + + last_rec = NULL; + for (i = 0; i < ct; i++) { + pdbrec_t *rec; + + rec = xcalloc(1, sizeof(*rec)); + if (fin->attr & PDB_FLAG_RESOURCE) { + (void) gbfgetuint32(fin->file); /* type */ + rec->id = gbfgetint16(fin->file); + rec->offs = gbfgetuint32(fin->file); + if ((gbint32)rec->offs < 0) + pdb_invalid_file(fin, "Invalid offset to record (%0d, id = %d)", rec->offs, rec->id); + } + else { + gbuint32 x; + + rec->offs = gbfgetint32(fin->file); + x = gbfgetuint32(fin->file); + rec->id = x & 0x0ffff; + rec->category = (x >> 24) & 0x0f; + rec->flags = (x >> 24) & 0xf0; + if ((gbint32)rec->offs < 0) + pdb_invalid_file(fin, "Invalid offset to resource record (%0d, id = %d)", rec->offs, rec->id); + } + + if (last_rec == NULL) + fin->rec_list = rec; + else + last_rec->next = rec; + last_rec = rec; + } + + offs += (ct * 8); + last_rec = fin->rec_list; + + if (fin->appinfo_offs != 0) { + gbuint32 top; + + /* seek to application info offset */ + while (offs < fin->appinfo_offs) { + (void)gbfgetc(fin->file); + offs++; + } + + /* determine the length of application info */ + if (fin->index_offs != 0) top = fin->index_offs; + else top = 0x7FFFFFFU; + if (last_rec && (last_rec->offs < top)) top = last_rec->offs; + + if (top != 0x7FFFFFFU) { + fin->appinfo = xmalloc(top - offs); + fin->appinfo_len = gbfread(fin->appinfo, 1, top - offs, fin->file); + offs += fin->appinfo_len; + } + else { + gbuint32 size; + fin->appinfo = pdb_read_tail(fin->file, &size); + fin->appinfo_len = size; + offs += size; + } + } + + for (rec = fin->rec_list; rec; rec = rec->next) { + /* seek to current record */ + while (offs < rec->offs) { + (void) gbfgetc(fin->file); + offs++; + } + if (rec->next) { + rec->size = (gbint32)rec->next->offs - (gbint32)offs; + if (rec->size > 0) { + rec->data = xmalloc(rec->size); + rec->size = gbfread(rec->data, 1, rec->size, fin->file); + offs += rec->size; + } + else if (rec->size < 0) + pdb_invalid_file(fin, "Wrong data size in record with id %d.\n", rec->id); + } + else { + rec->data = pdb_read_tail(fin->file, &rec->size); + offs += rec->size; + } + } +} + +pdbfile * +pdb_open(const char *filename, const char *module) +{ + pdbfile *res; + + res = xcalloc(1, sizeof(*res)); + res->file = gbfopen_be(filename, "rb", module); + res->mode = 1; + + pdb_load_data(res); + pdb_rewind(res); + + return res; +} + +int +pdb_read_rec_by_id(pdbfile *fin, const gbuint32 rec_id, gbuint8 *flags, gbuint8 *category, void **data) +{ + pdbrec_t *rec; + + for (rec = fin->rec_list; rec; rec = rec->next) { + if (rec->id == rec_id) { + if (data) *data = rec->data; + if (flags) *flags = rec->flags; + if (category) *category = rec->category; + return rec->size; + } + } + return -1; +} + +pdbfile * +pdb_create(const char *filename, const char *module) +{ + pdbfile *res; + + res = xcalloc(1, sizeof(*res)); + strncpy(res->name, "Palm/OS Database", PDB_DBNAMELEN); + res->file = gbfopen_be(filename, "wb", module);; + res->mode = 2; + + return res; +} + +void +pdb_write_rec(pdbfile *fout, const gbuint8 flags, const gbuint8 category, const gbuint32 rec_id, const void *data, const gbuint32 size) +{ + pdbrec_t *rec, *cur; + + rec = xcalloc(1, sizeof(*rec)); + rec->category = category; + rec->flags = category; + rec->id = rec_id; + rec->size = size; + if (size > 0) { + rec->data = xmalloc(size); + memcpy(rec->data, data, size); + } + + /* insert rec into rec_list sorted by id */ + cur = fout->rec_list; + if (cur == NULL) fout->rec_list = rec; + else { + pdbrec_t *prev = NULL; + + while (cur) { + if (rec_id < cur->id) { + rec->next = cur; + if (prev == NULL) fout->rec_list = rec; + else prev->next = rec; + break; + } + else if (rec_id == cur->id) { /* Overwrite record with id ... */ + rec->next = cur->next; + if (prev == NULL) fout->rec_list = rec; + else prev->next = rec; + if (cur->data) xfree(cur->data); + xfree(cur); + cur = rec; + break; + } + prev = cur; + cur = cur->next; + } + if (! cur) { + if (prev == NULL) fout->rec_list = rec; + else prev->next = rec; + } + } + fout->rec_ct++; +} + +/* all data was buffered, write now to file */ + +static void +pdb_flush(pdbfile *file) +{ + pdbrec_t *rec; + gbfile *fout = file->file; + int len, offs; + + offs = 78; + file->index_offs = 0; + offs += (file->rec_ct * 8); + + offs += 2; + + if (file->appinfo && (file->appinfo_len > 0)) { + file->appinfo_offs = offs; + offs += file->appinfo_len; + } + else + file->appinfo_offs = 0; + + rec = file->rec_list; + while (rec) { /* prepare data records */ + rec->offs = offs; + offs += rec->size; + rec = rec->next; + } + + len = strlen(file->name); + gbfwrite(file->name, 1, len, fout); + while (len++ < PDB_DBNAMELEN) gbfputc(0, fout); + + gbfputuint16(file->attr, fout); + gbfputuint16(file->version, fout); + gbfputuint32(file->ctime, fout); + gbfputuint32(file->mtime, fout); + gbfputuint32(file->btime, fout); + gbfputuint32(file->revision, fout); + gbfputuint32(file->appinfo_offs, fout); + gbfputuint32(file->index_offs, fout); + gbfputuint32(file->type, fout); + gbfputuint32(file->creator, fout); + gbfputuint32(file->uid, fout); + + gbfputuint32(0, fout); /* ? ID ? */ + gbfputuint16(file->rec_ct, fout); + + for (rec = file->rec_list; rec; rec = rec->next) { + gbuint32 attr; + + gbfputint32(rec->offs, fout); + attr = (rec->category & 0x0f) | (rec->flags & 0xf0); + gbfputint32((rec->id & 0x0ffffff) | (attr << 24), fout); + } + gbfputint16(0, fout); + + if (file->appinfo && (file->appinfo_len > 0)) { + gbfwrite(file->appinfo, 1, file->appinfo_len, fout); + } + + for (rec = file->rec_list; rec; rec = rec->next) { + if (rec->size > 0) + gbfwrite(rec->data, 1, rec->size, fout); + } +} + +void +pdb_close(pdbfile *file) +{ + pdbrec_t *rec; + + if (! file) return; + + if (file->mode & 2) { +#if 0 + /* this can be done later */ + if (gpsbabel_time == 0) { /* !!! We are in testo !!! */ + file->ctime = 0; /* (now we also can do a bincompare) */ + file->mtime = 0; + file->btime = 0; + } +#endif + pdb_flush(file); + } + + gbfclose(file->file); + + if ((file->mode & 1) && file->appinfo) xfree(file->appinfo); + + rec = file->rec_list; + while (rec) { + pdbrec_t *tmp = rec; + rec = rec->next; + + if (tmp->data) xfree(tmp->data); + xfree(tmp); + } + xfree(file); +} + +int +pdb_eof(pdbfile *fin) +{ + return (fin->rec_curr) ? 0 : 1; +} + +int +pdb_read_rec(pdbfile *fin, gbuint8 *flags, gbuint8 *category, gbuint32 *rec_id, void **data) +{ + if (pdb_eof(fin)) return -1; + else { + pdbrec_t *rec = fin->rec_curr; + fin->rec_curr = rec->next; + + if (data) *data = rec->data; + if (flags) *flags = rec->flags; + if (category) *category = rec->category; + if (rec_id) *rec_id = rec->id; + + return rec->size; + } +} + +void +pdb_rewind(pdbfile *fin) +{ + fin->rec_curr = fin->rec_list; +} + +#endif diff --git a/pdbfile.h b/pdbfile.h new file mode 100644 index 000000000..b1c652f04 --- /dev/null +++ b/pdbfile.h @@ -0,0 +1,84 @@ +/* + + Minimum support for Palm/OS database files + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org + + Written after study the Coldsync project + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifndef PDBFILE_H +#define PDBFILE_H + +#include "defs.h" + +#if PDBFMTS_ENABLED + +#include "gbfile.h" +#include "gbtypes.h" + +#include + +#define PDB_DBNAMELEN 32 +#define PDB_FLAG_RESOURCE 0x0001 +#define PDB_FLAG_BACKUP 0x0008 +#define EPOCH_1904 2082844800L + +typedef struct pdbrec_s { + gbuint32 offs; + gbuint32 size; + gbuint32 id; + gbuint8 category; + gbuint8 flags; + char *data; + struct pdbrec_s *next; +} pdbrec_t; + +typedef struct { + gbfile *file; + char mode; /* file-mode: 1 = read / 2 = write */ + char name[PDB_DBNAMELEN + 1]; /* database name */ + gbuint16 attr; /* attributes */ + gbuint16 version; /* version */ + time_t ctime; /* creation time */ + time_t mtime; /* modification time */ + time_t btime; /* backup time */ + gbuint32 revision; + gbuint32 appinfo_offs; /* offset to application info */ + gbuint32 index_offs; /* offset to sort-index info */ + gbuint32 creator; + gbuint32 type; + gbuint32 uid; + gbuint16 rec_ct; + struct pdbrec_s *rec_list; + struct pdbrec_s *rec_curr; + void *appinfo; + int appinfo_len; +} pdbfile; + + +pdbfile *pdb_open(const char *filename, const char *module); +pdbfile *pdb_create(const char *filename, const char *module); +void pdb_close(pdbfile *file); +int pdb_eof(pdbfile *fin); +void pdb_rewind(pdbfile *fin); +int pdb_read_rec(pdbfile *fin, gbuint8 *flags, gbuint8 *category, gbuint32 *rec_id, void **data); +int pdb_read_rec_by_id(pdbfile *fin, const gbuint32 rec_id, gbuint8 *flags, gbuint8 *category, void **data); +void pdb_write_rec(pdbfile *fout, const gbuint8 flags, const gbuint8 category, const gbuint32 rec_id, const void *data, const gbuint32 size); + +#endif +#endif diff --git a/polygon.c b/polygon.c new file mode 100644 index 000000000..5f2abce18 --- /dev/null +++ b/polygon.c @@ -0,0 +1,364 @@ +/* + Inside/Outside polygon filter + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED +#define MYNAME "Polygon filter" + +static char *polyfileopt = NULL; +static char *exclopt = NULL; + +/* + * This test for insideness is essentially an odd/even test. The + * traditional (simple) implementation of the odd/even test counts + * intersections along a test ray, and if it should happen to exactly hit + * a vertex of the polygon, it throws away the result and fires a different + * test ray. Since we're potentially testing hundreds of test points against + * a polygon with hundreds of sides, this seemed both wasteful and difficult + * to coordinate, so instead I added extra state to try to figure out what we + * would have seen if we had just missed the vertex. The result is the + * hodgepodge of "limbo" states explained below. On the credit side of the + * ledger, though, the tests for intersection are vastly simplified by always + * having a horizontal test ray. + * + * The general structure of this filter is: we loop over the points in the + * polygon. For each point, we update the state of each of the waypoints in + * the test set. Thus, the state of every waypoint is indeterminate until + * the end of the outer loop, at which point the state of every waypoint + * should theoretically be completely determined. + * + * The bits following this comment encode the current state of the test point + * as we go around the polygon. OUTSIDE clearly isn't a bit; it's just here + * for completeness. If it's not INSIDE, and it's not something else, it's + * clearly OUTSIDE. + * + * INSIDE is self-explanatory. What it means is that the last time we were + * certain of our state, we were inside of the polygon. + * + * LIMBO encodes a bit more state information, to handle the case where our + * test ray (a horizontal line) has intersected one of the vertices of the + * polygon exactly. If the two lines that meet at that vertex are on + * opposite sides of the test ray, it was an intersection. Otherwise, it just + * grazed a local minimum or maximum and so counted as either zero or two + * intersections - not a change in state. Horizontal lines encountered + * while in limbo don't change the limbo state. All other lines do. + * The rest of the bits talk about how we got into limbo, and thus what to do + * when we get out of limbo. + * + * LIMBO_UP means that the last line segment we saw going into limbo was + * headed upward. When we see another non-horizontal line segment, whether + * we flip the INSIDE bit or not depends on whether it also goes upward. If + * it does, we flip the INSIDE bit. Otherwise, we just clear our limbo state + * and go on as if nothing had happened. + * + * LIMBO_BEGIN means that the very first vertex in the polygon put us into a + * limbo state. We won't be able to resolve that limbo state until we get to + * the end of the cycle, and it can actually coexist with another more local + * limbo state. The next two bits talk about the beginning limbo state in + * more detail. + * + * BEGIN_UP means that the first non-horizontal line segment we encountered + * while in a LIMBO_BEGIN state went upward. As with LIMBO_UP, this is used + * to determine the final disposition of the limbo state when we get back + * around to the other end of the cycle. + * + * BEGIN_HOR is fairly temporary. It says that we've encountered one or more + * horizontal line segments at the beginning of the cycle, so we haven't yet + * been able to resolve the state of BEGIN_UP. It's a way of propagating the + * "firstness" forward until we can make a decision, without propagating it + * for every test point. + * + * UP is used to remember which way we were going in case we encounter a + * limbo state. + * + * -- RLP + */ + +#define OUTSIDE 0 +#define INSIDE 1 +#define LIMBO 2 +#define LIMBO_UP 4 +#define LIMBO_BEGIN 8 +#define BEGIN_UP 16 +#define BEGIN_HOR 32 +#define UP 64 + +typedef struct { + unsigned short state; + unsigned short override; +} extra_data; + +static +arglist_t polygon_args[] = { + {"file", &polyfileopt, "File containing vertices of polygon", + NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX }, + {"exclude", &exclopt, "Exclude points inside the polygon", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static void polytest ( double lat1, double lon1, + double lat2, double lon2, + double wlat, double wlon, + unsigned short *state, int first, int last ) { + + if ( lat1 == wlat ) { + if ( lat2 < wlat ) { + /* going down */ + if (*state & LIMBO) { + if ( *state & LIMBO_UP ) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO &~LIMBO_UP; + } + else if (*state & LIMBO_BEGIN) { + if ( *state & BEGIN_HOR ) { + *state = *state & ~BEGIN_HOR; + } + else if ( last ) { + if ( *state & BEGIN_UP ) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } + } + else if ( first && (lon1 > wlon)) { + *state |= LIMBO_BEGIN; + } + } + else if ( lat2 == wlat ) { + if ( first & (lon1 > wlon || lon2 > wlon)) { + *state |= LIMBO_BEGIN | BEGIN_HOR; + } + else if (last && (*state & LIMBO_BEGIN) && (*state & LIMBO)) { + if ( (!!(*state & LIMBO_UP)) != (!!(*state & BEGIN_UP))) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO & ~LIMBO_UP & + ~LIMBO_BEGIN & ~BEGIN_UP; + } + else if ( *state & LIMBO ) { + /* do nothing */ + } + else { + if ( lon1 <= wlon && lon2 > wlon ) { + if ( *state & UP ) { + *state &= ~UP; + *state |= LIMBO_UP; + } + *state = *state | LIMBO; + } + } + } + else { + /* going up */ + if (*state & LIMBO) { + if ( !(*state & LIMBO_UP) ) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO & ~LIMBO_UP; + } + else if (*state & LIMBO_BEGIN) { + if ( *state & BEGIN_HOR ) { + *state &= ~BEGIN_HOR; + *state |= BEGIN_UP; + } + else if ( last ) { + if ( !(*state & BEGIN_UP) ) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } + } + else if ( first && (lon1 > wlon)) { + *state |= LIMBO_BEGIN | BEGIN_UP; + } + } + *state = *state & ~UP; + } + else if ( lat2 == wlat ) { + if ( lat1 < wlat ) { + if ( last ) { + if ( *state & BEGIN_UP ) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } + else if ( lon2 > wlon ) { + *state |= LIMBO; + } + } + /* no case for lat1==wlat; that's above */ + else { + if ( last ) { + if ( !(*state & BEGIN_UP) ) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } + else if ( lon2 > wlon ) { + *state |= LIMBO | LIMBO_UP; + } + else { + *state |= UP; + } + } + } + else { + if ( (lat1 > wlat && lat2 < wlat) || + (lat1 < wlat && lat2 > wlat)) { + /* we only care if the lines might intersect */ + if ( lon1 > wlon && lon2 > wlon ) { + *state = *state ^ INSIDE; + } + else if (!(lon1 <= wlon && lon2 <= wlon)) { + /* we're inside the bbox of a diagonal line. math time. */ + double loni = lon1+(lon2-lon1)/(lat2-lat1)*(wlat-lat1); + if ( loni > wlon ) { + *state = *state ^ INSIDE; + } + } + } + } + +} + +#define BADVAL 999999 + +void +polygon_process(void) +{ + queue * elem, * tmp; + waypoint * waypointp; + extra_data *ed; + double lat1, lon1, lat2, lon2; + double olat, olon; + int fileline = 0; + int first = 1; + int last = 0; + char *line; + gbfile *file_in; + + file_in = gbfopen(polyfileopt, "r", MYNAME); + + olat = olon = lat1 = lon1 = lat2 = lon2 = BADVAL; + while ((line = gbfgetstr(file_in))) { + char *pound = NULL; + int argsfound = 0; + + fileline++; + + pound = strchr( line, '#' ); + if ( pound ) *pound = '\0'; + + lat2 = lon2 = BADVAL; + argsfound = sscanf( line, "%lf %lf", &lat2, &lon2 ); + + if ( argsfound != 2 && strspn(line, " \t\n") < strlen(line)) { + warning(MYNAME + ": Warning: Polygon file contains unusable vertex on line %d.\n", + fileline ); + } + else if ( lat1 != BADVAL && lon1 != BADVAL && + lat2 != BADVAL && lon2 != BADVAL ) { + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + + waypointp = (waypoint *)elem; + if ( waypointp->extra_data ) { + ed = (extra_data *) waypointp->extra_data; + } + else { + ed = (extra_data *) xcalloc(1, sizeof(*ed)); + ed->state = OUTSIDE; + ed->override = 0; + waypointp->extra_data = (extra_data *) ed; + } + if ( lat2 == waypointp->latitude && + lon2 == waypointp->longitude ) { + ed->override = 1; + } + if ( olat != BADVAL && olon != BADVAL && + olat == lat2 && olon == lon2 ) { + last = 1; + } + polytest( lat1, lon1, lat2, lon2, + waypointp->latitude, + waypointp->longitude, + &ed->state, first, last ); + first = 0; + last = 0; + } + } + if ( olat != BADVAL && olon != BADVAL && + olat == lat2 && olon == lon2 ) { + olat = BADVAL; + olon = BADVAL; + lat1 = BADVAL; + lon1 = BADVAL; + first = 1; + } + else if ( lat1 == BADVAL || lon1 == BADVAL ) { + olat = lat2; + olon = lon2; + lat1 = lat2; + lon1 = lon2; + } + else { + lat1 = lat2; + lon1 = lon2; + } + } + gbfclose(file_in); + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wp = (waypoint *) elem; + ed = (extra_data *) wp->extra_data; + wp->extra_data = NULL; + if ( ed ) { + if ( ed->override ) ed->state = INSIDE; + if (((ed->state & INSIDE) == OUTSIDE ) == (exclopt == NULL)) { + waypt_del(wp); + waypt_free(wp); + } + xfree( ed ); + } + } +} + +void +polygon_init(const char *args) { + /* do nothing */ +} + +void +polygon_deinit(void) { + /* do nothing */ +} + +filter_vecs_t polygon_vecs = { + polygon_init, + polygon_process, + polygon_deinit, + NULL, + polygon_args +}; +#endif // FILTERS_ENABLED diff --git a/position.c b/position.c new file mode 100644 index 000000000..42247d249 --- /dev/null +++ b/position.c @@ -0,0 +1,203 @@ +/* + Distance Between Points Filter(s) + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "filterdefs.h" +#include "grtcirc.h" + +#if FILTERS_ENABLED + +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +static route_head *cur_rte = NULL; + +static double pos_dist; +static char *distopt = NULL; +static char *purge_duplicates = NULL; + +typedef struct { + double distance; +} extra_data; + +static +arglist_t position_args[] = { + {"distance", &distopt, "Maximum positional distance", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, + {"all", &purge_duplicates, + "Suppress all points close to other points", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static double +gc_distance(double lat1, double lon1, double lat2, double lon2) +{ + return gcdist( + RAD(lat1), + RAD(lon1), + RAD(lat2), + RAD(lon2) + ); +} + +/* tear through a waypoint queue, processing points by distance */ +static void +position_runqueue(queue *q, int nelems, int qtype) +{ + queue * elem, * tmp; + waypoint ** comp; + int * qlist; + double dist; + int i = 0, j, anyitem; + + comp = (waypoint **) xcalloc(nelems, sizeof(*comp)); + qlist = (int *) xcalloc(nelems, sizeof(*qlist)); + + QUEUE_FOR_EACH(q, elem, tmp) { + comp[i] = (waypoint *)elem; + qlist[i] = 0; + i++; + } + + for (i = 0 ; i < nelems ; i++) { + anyitem = 0; + + if (!qlist[i]) { + for (j = i + 1 ; j < nelems ; j++) { + if (!qlist[j]) { + dist = gc_distance(comp[j]->latitude, + comp[j]->longitude, + comp[i]->latitude, + comp[i]->longitude); + + /* convert radians to integer feet */ + dist = (int)(5280*radtomiles(dist)); + + if (dist <= pos_dist) { + qlist[j] = 1; + switch (qtype) { + case wptdata: + waypt_del(comp[j]); + waypt_free(comp[j]); + break; + case trkdata: + track_del_wpt(cur_rte, comp[j]); + break; + case rtedata: + route_del_wpt(cur_rte, comp[j]); + break; + default: + break; + } + anyitem = 1; + } + } + } + + if (anyitem && !!purge_duplicates) { + switch (qtype) { + case wptdata: + waypt_del(comp[i]); + break; + case trkdata: + track_del_wpt(cur_rte, comp[i]); + break; + case rtedata: + route_del_wpt(cur_rte, comp[i]); + break; + default: + break; + } + waypt_free(comp[i]); + } + } + } + + if (comp) + xfree(comp); + + if (qlist) + xfree(qlist); +} + +static void +position_process_route(const route_head * rh) { + int i = rh->rte_waypt_ct; + + if (i) { + cur_rte = (route_head *)rh; + position_runqueue((queue *)&rh->waypoint_list, i, rtedata); + cur_rte = NULL; + } + +} + +static void +position_noop_w(const waypoint *w) +{ +} + +static void +position_noop_t(const route_head *h) +{ +} + +void position_process(void) +{ + int i = waypt_count(); + + if (i) + position_runqueue(&waypt_head, i, wptdata); + + route_disp_all(position_process_route, position_noop_t, position_noop_w); + track_disp_all(position_process_route, position_noop_t, position_noop_w); +} + +void +position_init(const char *args) { + char *fm; + + pos_dist = 0; + + if (distopt) { + pos_dist = strtod(distopt, &fm); + + if ((*fm == 'm') || (*fm == 'M')) { + /* distance is meters */ + pos_dist *= 3.2802; + } + } +} + +void +position_deinit(void) { +} + +filter_vecs_t position_vecs = { + position_init, + position_process, + position_deinit, + NULL, + position_args +}; + +#endif // FILTERS_ENABLED diff --git a/psitrex.c b/psitrex.c new file mode 100755 index 000000000..739fec4c9 --- /dev/null +++ b/psitrex.c @@ -0,0 +1,808 @@ +/* + Access to PsiTrex text files. + Based on information provided by Ian Cowley. + + Copyright (C) 2003 Mark Bradley, mrcb.gpsb@osps.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include +#include + +#include "defs.h" +#include "garmin_tables.h" +#include + +#define MYNAME "PSITREX" + +typedef enum { + ltrimEOL = 1 , /* skip spaces & tabs to start; ends on EOL */ + EOL, /* don't skip spaces and tabs to start; end on EOL */ + comma, /* skip spaces & tabs to start; ends on comma or EOL */ + whitespace, /* skip spaces & tabs to start; ends on white space or EOL */ + wscomma /* skip spaces & tabs to start; ends on white space, comma or EOL */ +} psit_tokenSep_type; + +typedef struct psit_icon_mapping { + const int value; + const char *icon; +} psit_icon_mapping_t; + +static gbfile *psit_file_in; +static gbfile *psit_file_out; +static short_handle mkshort_handle; + +/* 2 = not written any tracks out + 1 = change of track to write out track header + 0 = in the middle of writing out track datapoints, so don't write a header */ +static int psit_track_state = 2; + +static char psit_current_token[256]; + +char *snlen; + +static +arglist_t psit_args[] = { +/* {"snlen", &snlen, "Length of generated shortnames", + NULL, ARGTYPE_INT, "1", NULL }, */ + ARG_TERMINATOR +}; + +/* Taken from PsiTrex 1.13 */ +static +const psit_icon_mapping_t psit_icon_value_table[] = { + { 0x00, "anchor" }, + { 0x06, "dollar" }, + { 0x07, "fish" }, + { 0x08, "fuel" }, + { 0x0a, "house" }, + { 0x0b, "knife" }, + { 0x0d, "mug" }, + { 0x0e, "skull" }, + { 0x12, "wpt_dot" }, + { 0x13, "wreck" }, + { 0x15, "mob" }, + { 0x0096, "boat_ramp" }, + { 0x0097, "camp" }, + { 0x0098, "restrooms" }, + { 0x0099, "showers" }, + { 0x009a, "drinking_wtr" }, + { 0x009b, "phone" }, + { 0x009c, "1st_aid" }, + { 0x009d, "info" }, + { 0x009e, "parking" }, + { 0x009f, "park" }, + { 0x00a0, "picnic" }, + { 0x00a1, "scenic" }, + { 0x00a2, "skiing" }, + { 0x00a3, "swimming" }, + { 0x00a4, "dam" }, + { 0x00a6, "danger" }, + { 0x00a9, "ball" }, + { 0x00aa, "car" }, + { 0x00ab, "deer" }, + { 0x00ac, "shpng_cart" }, + { 0x00ad, "lodging" }, + { 0x00ae, "mine" }, + { 0x00af, "trail_head" }, + { 0x00b0, "truck_stop" }, + { 0x00b2, "flag" }, + { 0x2005, "golf" }, + { 0x2006, "sml_cty" }, + { 0x2007, "med_cty" }, + { 0x2008, "lrg_cty" }, + { 0x200c, "amuse_pk" }, + { 0x200d, "bowling" }, + { 0x200e, "car_rental" }, + { 0x200f, "car_repair" }, + { 0x2010, "fastfood" }, + { 0x2011, "fitness" }, + { 0x2012, "movie" }, + { 0x2013, "museum" }, + { 0x2014, "pharmacy" }, + { 0x2015, "pizza" }, /* how specific does this really need to be? C'mon! */ + { 0x2016, "post_ofc" }, + { 0x2017, "rv_park" }, + { 0x2018, "school" }, + { 0x2019, "stadium" }, + { 0x201a, "store" }, + { 0x201b, "zoo" }, + { 0x201c, "gas_plus" }, + { 0x201d, "faces" }, + { 0x2022, "weigh_sttn" }, + { 0x2023, "toll_booth" }, + { 0x2029, "bridge" }, + { 0x202a, "building" }, + { 0x202b, "cemetery" }, + { 0x202c, "church" }, + { 0x202e, "crossing" }, + { 0x2032, "oil_field" }, + { 0x2033, "tunnel" }, + { 0x2035, "forest" }, + { 0x2036, "summit" }, + { 0x203f, "geocache" }, + { 0x2040, "geocache_fnd" }, + { 0x4000, "airport" }, + { 0x4007, "tall_tower" }, + { 0x4008, "short_tower" }, + { 0x4009, "glider" }, + { 0x400a, "ultralight" }, + { 0x400b, "parachute" }, + { 0x4012, "seaplane" }, + { -1, NULL } +}; + +static const char * +psit_find_desc_from_icon_number(const int icon) +{ + const psit_icon_mapping_t *i; + + for (i = psit_icon_value_table; i->icon; i++) { + if (icon == i->value) { + return i->icon; + } + } + return ""; +} + +static int +psit_find_icon_number_from_desc(const char *desc) +{ + const psit_icon_mapping_t *i; + int def_icon = 18; + + if (!desc) { + return def_icon; + } + + for (i = psit_icon_value_table; i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + return i->value; + } + } + if (atoi(desc) > 0) return atoi(desc); + return def_icon; +} + +static void +psit_rd_init(const char *fname) +{ + psit_file_in = gbfopen(fname, "r", MYNAME); +} + +static void +psit_rd_deinit(void) +{ + gbfclose(psit_file_in); +} + +static void +psit_wr_init(const char *fname) +{ + psit_file_out = gbfopen(fname, "w", MYNAME); +} + +static void +psit_wr_deinit(void) +{ + gbfclose(psit_file_out); +} + +/* + * get characters until and including terminating NULL from psit_file_in + * and write into buf. + */ +static void +psit_getToken(gbfile *psit_file, char *buf, size_t sz, psit_tokenSep_type delimType) +{ + int c = -1; + + *buf = 0; + + if (delimType != EOL) { + while ((c = gbfgetc(psit_file)) != EOF) { + if (!isspace(c)) break; + } + } + + if (gbfeof(psit_file)) return; + + if (delimType == EOL) { + c = gbfgetc(psit_file); + } + + if (c == '#') { + if (gbfgets(buf, sz, psit_file) == NULL) { + *buf = 0; + return; + } + /* use recursion to skip multiple comment lines or just to return the next token */ + psit_getToken(psit_file, buf, sz, delimType); + return; + } + + if ((delimType == EOL) || (delimType == ltrimEOL)) { + *buf = c; + buf++; + gbfgets(buf, sz-1, psit_file); + return; + } + + while (sz--) { + *buf++ = c; + if ((c = gbfgetc (psit_file)) == EOF) { + *buf = 0; + return; + } + if (((c == 0) || isspace(c)) && + ((delimType == whitespace) || (delimType == wscomma)) ) { + *buf = 0; + return; + } + if (((delimType == comma) || (delimType == wscomma)) && + (c == ',')) { + *buf = 0; + return; + } + } +} + + +/* + * test if a token is known + * + */ +static int +psit_isKnownToken(char *buf) +{ + if (strcmp(buf, "Track:") == 0) return 0; + if (strcmp(buf, "Route:") == 0) return 0; + if (strcmp(buf, "Waypoint:") == 0) return 0; + if (strcmp(buf, "Map:") == 0) return 0; + return 1; +} + +/* + * read in from file a waypoint record + * MRCB + */ +static void +psit_waypoint_r(gbfile *psit_file, waypoint **wpt) +{ + int garmin_icon_num; + + waypoint *thisWaypoint; + + if (strlen(psit_current_token) > 0) { + thisWaypoint = waypt_new(); + + thisWaypoint->latitude = atof(psit_current_token); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + thisWaypoint->longitude = atof(psit_current_token); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + if (psit_current_token[0] == '*') { + thisWaypoint->altitude = unknown_alt; + } + else { + thisWaypoint->altitude = atof(psit_current_token); + } + + /* the name */ + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + rtrim(psit_current_token); + thisWaypoint->shortname = xstrdup(psit_current_token); + thisWaypoint->description = xstrdup(""); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + rtrim(psit_current_token); + /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ + /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ + garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); + + waypt_add(thisWaypoint); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + } +} + +/* + * write out to file a waypoint record + * MRCB + */ +static void +psit_waypoint_w(gbfile *psit_file, const waypoint *wpt) +{ + int icon; + const char *ident; + char *src = 0; /* BUGBUG Passed to mkshort */ + + gbfprintf(psit_file, "%11.6f,%11.6f,", + wpt->latitude, + wpt->longitude); + + if (wpt->altitude == unknown_alt) + gbfprintf(psit_file, "********,"); + else + gbfprintf(psit_file, "%8.2f,", + wpt->altitude); + + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + wpt->shortname; + + gbfprintf(psit_file, " %-6s, ", ident); + icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + + if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + } + + ident = psit_find_desc_from_icon_number(icon); + if (strlen(ident) == 0) + gbfprintf(psit_file, "%1d\n", icon); + else + gbfprintf(psit_file, "%s\n", ident); + +} + +static void +psit_waypoint_w_wrapper(const waypoint *wpt) +{ + psit_waypoint_w(psit_file_out, wpt); +} + +/* + * read in from file a route record + * MRCB + */ +static void +psit_route_r(gbfile *psit_file, route_head **rte) +{ + char rtename[256]; + unsigned int rte_num; + + int garmin_icon_num; + + route_head *rte_head; + unsigned int rte_count; + + waypoint *thisWaypoint; + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + + if (strlen(psit_current_token) == 0) { + strcpy(rtename, "ROUTE"); + } + else { + strcpy(rtename, psit_current_token); + } + + rtrim(rtename); + + rte_head = route_head_alloc(); + rte_head->rte_name = xstrdup(rtename); + route_add_head(rte_head); + *rte = rte_head; + + rte_num = 0; + + rte_count = 0; + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + + while (psit_isKnownToken(psit_current_token) != 0) { + if (strlen(psit_current_token) > 0) { + thisWaypoint = waypt_new(); + + thisWaypoint->latitude = atof(psit_current_token); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + thisWaypoint->longitude = atof(psit_current_token); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + if (psit_current_token[0] == '*') { + thisWaypoint->altitude = unknown_alt; + } + else { + thisWaypoint->altitude = atof(psit_current_token); + } + + /* the name */ + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + rtrim(psit_current_token); + thisWaypoint->shortname = xstrdup(psit_current_token); + thisWaypoint->description = xstrdup(""); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + rtrim(psit_current_token); + /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ + /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ + garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); + + route_add_wpt(rte_head, thisWaypoint); + + if (gbfeof(psit_file)) break; + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + } + else break; + } +} + +/* + * write out to file a route header + * MRCB + */ +static void +psit_routehdr_w(gbfile *psit_file, const route_head *rte) +{ + char hdr[20]; + unsigned int rte_datapoints; + char *rname; + + waypoint *testwpt; + time_t uniqueValue = 0; + int allWptNameLengths; + + queue *elem, *tmp; + + /* total nodes (waypoints) this route */ + rte_datapoints = 0; + allWptNameLengths = 0; + + if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ + char *c; + + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + testwpt = (waypoint *)elem; + if (rte_datapoints == 0) { + uniqueValue = testwpt->creation_time; + } + rte_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* route name */ + if (!rte->rte_name) { + sprintf(hdr, "Route%04x", (unsigned) uniqueValue); + rname = xstrdup(hdr); + } + else + rname = xstrdup(rte->rte_name); + + /* check for psitrex comment sign; replace with '$' */ + while ((c = strchr(rname, '#'))) *c = '$'; + + gbfprintf(psit_file, "Route: %s\n", rname); + xfree(rname); + } +} + +static void +psit_routehdr_w_wrapper(const route_head *rte) +{ + psit_routehdr_w(psit_file_out, rte); +} + + +/* + * read in from file a track record + * MRCB + */ +static void +psit_track_r(gbfile *psit_file, route_head **trk) +{ + char tbuf[100]; + char trkname[256]; + unsigned int trk_num; + + struct tm tmTime; + time_t dateTime = 0; + route_head *track_head = NULL; + unsigned int trk_count; + + waypoint *thisWaypoint; + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + if (strlen(psit_current_token) == 0) { + strcpy(trkname, "TRACK"); + } + else { + strcpy(trkname, psit_current_token); + } + + rtrim(trkname); + + trk_num = 0; + + trk_count = 0; + + track_head = NULL; + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + + while (psit_isKnownToken(psit_current_token) != 0) { + if (strlen(psit_current_token) > 0) { + thisWaypoint = waypt_new(); + + thisWaypoint->latitude = atof(psit_current_token); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + thisWaypoint->longitude = atof(psit_current_token); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + if (psit_current_token[0] == '*') { + thisWaypoint->altitude = unknown_alt; + } + else { + thisWaypoint->altitude = atof(psit_current_token); + } + + /* date portion of the date time DD/MM/YY */ + psit_getToken(psit_file, psit_current_token, + sizeof(psit_current_token), whitespace); + sscanf(psit_current_token, "%02d/%02d/%02d", + &(tmTime.tm_mday) , &(tmTime.tm_mon), + &(tmTime.tm_year)); + + /* years are less 1900 in the tm struct */ + tmTime.tm_year += (tmTime.tm_year > 50 ? 0 : 100); + /* months are 0 to 11 in the tm struct */ + tmTime.tm_mon--; + /* time portion of the date time hh:mm:ss */ + psit_getToken(psit_file,psit_current_token, + sizeof(psit_current_token), wscomma); + sscanf(psit_current_token, "%02d:%02d:%02d", + &(tmTime.tm_hour) , &(tmTime.tm_min), + &(tmTime.tm_sec)); + + tmTime.tm_isdst = 0; + dateTime = mkgmtime(&tmTime); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), whitespace); + + if ((strcmp(psit_current_token, "1") == 0) || (track_head == NULL)) { + track_head = route_head_alloc(); + /* Add a number to the track name. With Garmins, the "first" tracklog is usually ACTIVE LOG + the second is ACTIVE LOG001 and so on */ + if (trk_num > 0) { + sprintf(tbuf, "%s%03d", trkname, trk_num); + track_head->rte_name = xstrdup(tbuf); + } + else { + track_head->rte_name = xstrdup(trkname); + } + trk_num++; + track_add_head(track_head); + } + + thisWaypoint->creation_time = dateTime; + track_add_wpt(track_head, thisWaypoint); + + if (gbfeof(psit_file)) break; + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + } + else break; + } +} + +/* + * write out to file a tracklog header + * MRCB + */ +static void +psit_trackhdr_w(gbfile *psit_file, const route_head *trk) +{ + char hdr[30]; + unsigned int trk_datapoints; + char *tname; + waypoint *testwpt; + time_t uniqueValue = 0; + + queue *elem, *tmp; + + if (psit_track_state == 2) { + /* total nodes (waypoints) this track */ + trk_datapoints = 0; + if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */ + char *c; + + QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { + if (trk_datapoints == 0) { + testwpt = (waypoint *)elem; + uniqueValue = testwpt->creation_time; + } + trk_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* track name */ + if (!trk->rte_name) { + sprintf(hdr, "Track%04x", (unsigned) uniqueValue); + tname = xstrdup(hdr); + } + else + tname = xstrdup(trk->rte_name); + + /* check for psitrex comment sign; replace with '$' */ + while ((c = strchr(tname, '#'))) *c = '$'; + + gbfprintf (psit_file, "Track: %s\n", tname); + + xfree(tname); + } + } + psit_track_state = 1; +} + +static void +psit_trackhdr_w_wrapper(const route_head *trk) +{ + psit_trackhdr_w(psit_file_out, trk); +} + + +/* + * write out to file a tracklog datapoint + * MRCB + */ +static void +psit_trackdatapoint_w(gbfile *psit_file, const waypoint *wpt) +{ + time_t t = wpt->creation_time; + struct tm *tmTime = gmtime(&t); + + gbfprintf(psit_file, "%11.6f,%11.6f,", + wpt->latitude, + wpt->longitude); + + if (wpt->altitude == unknown_alt) + gbfprintf(psit_file, "********, "); + else + gbfprintf(psit_file, "%8.2f, ", + wpt->altitude); + + /* Following date time format is fixed and reveals the origin of PsiTrex (i.e. the UK) */ + gbfprintf(psit_file, "%02d/%02d/%02d %02d:%02d:%02d,", + tmTime->tm_mday, + tmTime->tm_mon+1, + tmTime->tm_year % 100, + tmTime->tm_hour, + tmTime->tm_min, + tmTime->tm_sec); + + gbfprintf(psit_file," %d\n", psit_track_state); + psit_track_state = 0; +} + +static void +psit_trackdatapoint_w_wrapper(const waypoint *wpt) +{ + psit_trackdatapoint_w(psit_file_out, wpt); +} + + +static void +psit_read(void) +{ + waypoint *wpt; + route_head *rte; + route_head *trk; + +#ifdef DUMP_ICON_TABLE + printf("static icon_mapping_t icon_table[] = {\n"); +#endif + + psit_getToken(psit_file_in, psit_current_token, sizeof(psit_current_token), whitespace); + + do { + if (strlen(psit_current_token) == 0) break; + + if (strcmp(psit_current_token, "Track:") == 0) { + if (global_opts.objective == trkdata) { + psit_track_r(psit_file_in, &trk); + } + else break; /* psitrex files only have one format in; */ + /* if this is a track file and we don't want them, them bail out */ + } + else if (strcmp(psit_current_token, "Route:") == 0) { + if (global_opts.objective == rtedata) { + psit_route_r(psit_file_in, &rte); + } + else break; /* ditto, but for routes */ + } + else { + /* Must be waypoints in this file */ + if (global_opts.objective == wptdata) { + psit_waypoint_r(psit_file_in, &wpt); +#ifdef DUMP_ICON_TABLE + printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname); +#endif + + } + else break; + } + } while (!gbfeof(psit_file_in)); + + return; + +#ifdef DUMP_ICON_TABLE + printf("\t{ -1, NULL },\n"); + printf("};\n"); +#endif +} + +static void +psit_noop(const route_head *wp) +{ + /* no-op */ +} + +void +psit_write(void) +{ + int short_length; + + if (snlen) + short_length = atoi(snlen); + else + short_length = 10; + + mkshort_handle = mkshort_new_handle(); + + setshort_length(mkshort_handle, short_length); + setshort_whitespace_ok(mkshort_handle, 0); + + psit_track_state = 2; + + if (global_opts.objective == wptdata) { + waypt_disp_all(psit_waypoint_w_wrapper); + } + if (global_opts.objective == rtedata) { + route_disp_all(psit_routehdr_w_wrapper, psit_noop, psit_waypoint_w_wrapper); + } + if (global_opts.objective == trkdata) { + track_disp_all(psit_trackhdr_w_wrapper, psit_noop, psit_trackdatapoint_w_wrapper); + } + + mkshort_del_handle(&mkshort_handle); + +} + +ff_vecs_t psit_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + psit_rd_init, + psit_wr_init, + psit_rd_deinit, + psit_wr_deinit, + psit_read, + psit_write, + NULL, + psit_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/psp.c b/psp.c new file mode 100644 index 000000000..387536b86 --- /dev/null +++ b/psp.c @@ -0,0 +1,412 @@ +/* + PocketStreets 2002 Pushpin Files + Contributed to gpsbabel by Alex Mottram (geo_alexm at cox-internet.com) + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "cet.h" +#include "cet_util.h" +#include +#include "grtcirc.h" + +#define MYNAME "PSP" + +#define MAXPSPSTRINGSIZE 256 +#define MAXPSPOUTPUTPINS 8192 /* Any more points than this is ludicrous */ + +static gbfile *psp_file_in; +static gbfile *psp_file_out; +static short_handle mkshort_handle; + +#define psp_fread(b,s,m,f) gbfread((b),(s),(m),f) +#define psp_fread_double(f) gbfgetdbl(f) +#define psp_fwrite_double(v,f) gbfputdbl((v),f) + +/* ToDo: move the code inside to CET library */ +static void +psp_write_str(const char *str) +{ + if (str && *str) { + const char *cin = str; + gbint16 *tmp, *res; + int len = 0; + + /* convert UTF-8 string into a unicode sequence */ + /* not perfect, but enough for us */ + + res = tmp = xmalloc(strlen(str) << 1); + while (*cin) { + int bytes, value; + + if (cet_utf8_to_ucs4(cin, &bytes, &value) != CET_SUCCESS) + value = CET_NOT_CONVERTABLE_DEFAULT; + *tmp++ = value; + cin += bytes; + len++; + if (len == (MAXPSPSTRINGSIZE >> 1)) break; + } + gbfputc(len, psp_file_out); + tmp = res; + while (len--) + /* ! we need LE values, don't use gbfwrite ! */ + gbfputint16(*tmp++, psp_file_out); + xfree(res); + } + else + gbfputc(0, psp_file_out); +} + +/* ToDo: move the code inside to CET library */ +static char * +psp_read_str(gbfile *fin) +{ + int i, len; + gbint16 *buff; + char *res; + + len = (unsigned char)gbfgetc(fin); + if (len == 0) return NULL; + + buff = xmalloc(len * 2); + for (i = 0; i < len; i++) + buff[i] = gbfgetint16(fin); + res = cet_str_uni_to_utf8(buff, len); + xfree(buff); + return res; +} + +/* Implement the grid in ascii art... This makes a bit of sense if you stand + on a point over the north pole and look down on the earth. + +-180 -90 0 90 180 +------------------------------------ /\ +| 0x03 U|S 0x02 U|k 0x00 | 0x01 | 90 +|--------|--------|--------|--------| 0 +| 0x07 | 0x06 | 0x04 | 0x05 | -90 +------------------------------------ \/ +*/ +static +char grid_byte(double lat, double lon) +{ + char c = 0x00; + + if ((lon >= 0.0) && (lon < 90.0)) { + if (lat >= 0.0) { + c = 0x00; + } else { + c = 0x04; + } + } else + if (lon >= 90.0) { + if (lat >= 0.0) { + c = 0x01; + } else { + c = 0x05; + } + } else + if ((lon < 0.0) && (lon >= -90.0)) { + if (lat >= 0.0) { + c = 0x02; + } else { + c = 0x06; + } + } else + if (lon < -90.0) { + if (lat >= 0.0) { + c = 0x03; + } else { + c = 0x07; + } + } + + return (c); +} + +void decode_psp_coordinates(double * lat, double * lon, const char lonbyte) +{ + /* This is some sort of 1/2 Polar, 1/2 Cartesian coordinate mess in */ + /* the pin file. I really shouldn't have to do this. Zones 02 and 03 */ + /* work properly. The other zones are assumptions based on 02 and 03 */ + + if ((lonbyte == 0x02) || (lonbyte == 0x06)) { + /* one step west of zero longitude */ + if (*lon > 0.0) + *lon *= -1.0; + } else + if ((lonbyte == 0x03) || (lonbyte == 0x07)) { + /* two steps west of zero longitude */ + if (*lon > 0.0) + *lon -= 180.0; + } else + if ((lonbyte == 0x00) || (lonbyte == 0x04)) { + /* one step east of zero longitude */ + if (*lon < 0.0) + *lon *= -1.0; + } else + if ((lonbyte == 0x01) || (lonbyte == 0x05)) { + /* two steps east of zero longitude */ + if (*lon < 0.0) + *lon += 180.0; + } +} + +static int +valid_psp_header(char * header) +{ + char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50 }; /* 1niP */ + + return (memcmp(header_bytes, header, 4)); + +} + +static void +psp_rd_init(const char *fname) +{ + psp_file_in = gbfopen_le(fname, "rb", MYNAME); +} + +static void +psp_rd_deinit(void) +{ + gbfclose(psp_file_in); +} + +static void +psp_wr_init(const char *fname) +{ + psp_file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); +} + +static void +psp_wr_deinit(void) +{ + mkshort_del_handle(&mkshort_handle); + gbfclose(psp_file_out); +} + +static void +psp_read(void) +{ + char buff[MAXPSPSTRINGSIZE + 1]; + double radians; + double lat, lon; + waypoint *wpt_tmp; + short int pincount; + short int pindex; + char gridbyte = 0x00; + char *tmp; + + /* 32 bytes - file header */ + psp_fread(&buff[0], 1, 32, psp_file_in); + + if (valid_psp_header(buff) != 0) { + fatal(MYNAME ": input file does not appear to be a valid .PSP file.\n"); + } + + pincount = le_read16(&buff[12]); + + while (pincount--) { + wpt_tmp = waypt_new(); + + wpt_tmp->altitude = unknown_alt; + + /* offset 0x20 - 0x21 pin index */ + psp_fread(&pindex, 1, 2, psp_file_in); + + /* offset 0x22 - 0x23 */ + psp_fread(&buff[0], 1, 2, psp_file_in); + + /* offset 0x24 */ + /* 1 byte, the grid byte - needed for sign corrections later*/ + psp_fread(&gridbyte, 1, 1, psp_file_in); + + /* 8 bytes - latitude in radians */ + radians = psp_fread_double(psp_file_in); + lat = DEG(radians); + + /* 8 bytes - longitude in radians */ + radians = psp_fread_double(psp_file_in); + lon = DEG(radians); + + /* since we don't know the origin of this PSP file, we use */ + /* the grid byte adjust longitude, if necessary, mimicing */ + /* the behavior of pocketstreets correcting the data. This */ + /* does not correct the fact that points in eastern US are */ + /* written with the wrong coordinates by S&T. (MS bug) */ + + decode_psp_coordinates(&lat, &lon, gridbyte); + + wpt_tmp->latitude = lat; + wpt_tmp->longitude = lon; + + /* 1 byte - pin display properties */ + psp_fread(&buff[0], 1, 1, psp_file_in); + + /* 3 bytes - unknown */ + psp_fread(&buff[0], 1, 3, psp_file_in); + + /* 1 bytes - icon (values: 0x00 - 0x27) */ + psp_fread(&buff[0], 1, 1, psp_file_in); + + /* 3 bytes - unknown */ + psp_fread(&buff[0], 1, 3, psp_file_in); + + wpt_tmp->shortname = psp_read_str(psp_file_in); + wpt_tmp->description = psp_read_str(psp_file_in); + tmp = psp_read_str(psp_file_in); /* (address?) */ + if (tmp) xfree(tmp); + + waypt_add(wpt_tmp); + } +} + +static void +psp_waypt_pr(const waypoint *wpt) +{ + double lon, lat; + char tbuf[64]; + char c; + static short int pindex = 0; + char *shortname; + char *description; + + if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) + shortname = mkshort_from_wpt(mkshort_handle, wpt); + else + shortname = xstrdup(wpt->description); + } else { + /* no description available */ + shortname = xstrdup(""); + } + } else{ + shortname = xstrdup(wpt->shortname); + } + + if (! wpt->description) { + if (shortname) { + description = xstrdup(shortname); + } else { + description = xstrdup(""); + } + } else{ + description = xstrdup(wpt->description); + } + + /* convert lat/long back to radians */ + lat = RAD(wpt->latitude); + lon = RAD(wpt->longitude); + + pindex++; + /* 2 bytes - pin index */ + gbfputint16(pindex, psp_file_out); + + /* 2 bytes - null bytes */ + gbfputint16(0, psp_file_out); + + + /* set the grid byte */ + c = grid_byte(wpt->latitude, + wpt->longitude); + + /* since the grid byte matches with what pocketstreets does to */ + /* input files, our output appears identical to a pin file that */ + /* has already been processed and corrected by pocketstreets. */ + /* Due to the grid and signs, it'll look different than one that */ + /* comes straight from S&T. */ + + /* the grid byte */ + gbfwrite(&c, 1, 1, psp_file_out); + + /* 8 bytes - latitude/radians */ + psp_fwrite_double(lat, psp_file_out); + + /* 8 bytes - longitude/radians */ + psp_fwrite_double(lon, psp_file_out); + + /* 1 byte - pin properties */ + c = 0x14; /* display pin name on, display notes on. 0x04 = no notes */ + gbfwrite(&c, 1, 1, psp_file_out); + + memset(tbuf, '\0', sizeof(tbuf)); + + /* 3 unknown bytes */ + gbfwrite(tbuf, 1, 3, psp_file_out); + + /* 1 icon byte 0x00 = PIN */ + gbfwrite(tbuf, 1, 1, psp_file_out); + + /* 3 unknown bytes */ + gbfwrite(tbuf, 1, 3, psp_file_out); /* 3 junk */ + + psp_write_str(shortname); + psp_write_str(description); + + /* just for the hell of it, we'll scrap the third string. */ + psp_write_str(""); + + xfree(shortname); + xfree(description); +} + +static void +psp_write(void) +{ + short int s; + unsigned char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + /* the header: */ + /* 31 6E 69 50 20 00 00 00 08 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 */ + /* offset 0x0C - 0x0D = 2 byte pin count */ + + s = waypt_count(); + + if (global_opts.synthesize_shortnames) { + setshort_length(mkshort_handle, 32); + setshort_whitespace_ok(mkshort_handle, 1); + } + + if (s > MAXPSPOUTPUTPINS) { + fatal(MYNAME ": attempt to output too many pushpins (%d). The max is %d. Sorry.\n", s, MAXPSPOUTPUTPINS); + } + + /* insert waypoint count into header */ + le_write16(&header_bytes[12], s); + + gbfwrite(header_bytes, 1, 32, psp_file_out); + + waypt_disp_all(psp_waypt_pr); +} + +ff_vecs_t psp_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + psp_rd_init, + psp_wr_init, + psp_rd_deinit, + psp_wr_deinit, + psp_read, + psp_write, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* Fixed because of unicode strings in psp files (see psp_read_str / psp_write_str) */ +}; diff --git a/queue.c b/queue.c new file mode 100644 index 000000000..3e8181159 --- /dev/null +++ b/queue.c @@ -0,0 +1,203 @@ +/* + Generic queue utilities. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "queue.h" +#include "stddef.h" + +void +enqueue(queue *new_el, queue *old) +{ + new_el->next = old->next; + new_el->prev = old; + old->next->prev = new_el; + old->next = new_el; +} + +queue * +dequeue(queue *element) +{ + queue *prev = element->prev; + queue *next = element->next; + + next->prev = prev; + prev->next = next; + + QUEUE_INIT(element); + return element; +} + +/* + * The following sorting code was derived from linked-list mergesort + * sample code by Simon Tatham, code obtained from: + * http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html + * Modified for use with gpsbabel's queues by Paul Fox, October 2006. + * + * Original description and copyright messages follow... + */ + +/* + * Demonstration code for sorting a linked list. + * + * The algorithm used is Mergesort, because that works really well + * on linked lists, without requiring the O(N) extra space it needs + * when you do it on arrays. + * + * ... + */ + +/* + * This file is copyright 2001 Simon Tatham. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +void +sortqueue (queue *qh, int (*cmp)(const queue *, const queue *)) +{ + + queue *p, *q, *e, *tail, *oldhead, *list; + int insize, nmerges, psize, qsize, i; + + /* + * Special case: if `list' is empty, we're done. + */ + if (QUEUE_EMPTY(qh)) + return; + + /* + * The algorithm doesn't really want the extra list head + * element. So remove the list head for now. Put it back later. + */ + + list = QUEUE_FIRST(qh); + dequeue(qh); + + insize = 1; + + while (1) { + p = list; + oldhead = list; /* only used for circular linkage */ + list = NULL; + tail = NULL; + + nmerges = 0; /* count number of merges we do in this pass */ + + while (p) { + nmerges++; /* there exists a merge to be done */ + /* step `insize' places along from p */ + q = p; + psize = 0; + for (i = 0; i < insize; i++) { + psize++; + q = (q->next == oldhead ? NULL : q->next); + if (!q) break; + } + + /* if q hasn't fallen off end, we have + * two lists to merge */ + qsize = insize; + + /* now we have two lists; merge them */ + while (psize > 0 || (qsize > 0 && q)) { + + /* decide whether next element of + * merge comes from p or q + */ + if (psize == 0) { + /* p is empty; e must come from q. */ + e = q; q = q->next; qsize--; + if (q == oldhead) q = NULL; + } else if (qsize == 0 || !q) { + /* q is empty; e must come from p. */ + e = p; p = p->next; psize--; + if (p == oldhead) p = NULL; + } else if (cmp(p,q) <= 0) { + /* First element of p is + * lower (or same); e must + * come from p. + */ + e = p; p = p->next; psize--; + if (p == oldhead) p = NULL; + } else { + /* First element of q is + * lower; e must come from + * q. + */ + e = q; q = q->next; qsize--; + if (q == oldhead) q = NULL; + } + + /* add the next element to the merged list */ + if (tail) { + tail->next = e; + } else { + list = e; + } + + /* Maintain reverse pointers in a + * doubly linked list. */ + e->prev = tail; + + tail = e; + } + + /* now p has stepped `insize' places + * along, and q has too */ + p = q; + } + tail->next = list; + list->prev = tail; + + /* If we have done only one merge, we're finished. + * Allow for nmerges==0, the empty list case. + */ + if (nmerges <= 1) { + + /* Put the list head back at the start of the list */ + ENQUEUE_TAIL(list, qh); + return; + + } + + /* Otherwise repeat, merging lists twice the size */ + insize *= 2; + } +} diff --git a/queue.h b/queue.h new file mode 100644 index 000000000..51250d1d8 --- /dev/null +++ b/queue.h @@ -0,0 +1,58 @@ +/* + Generic queueing utilities. + + Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +typedef struct queue { + struct queue *next; + struct queue *prev; +} queue; + +void enqueue(queue *new_el, queue *old); +queue * dequeue(queue *element); + +void sortqueue (queue *qh, int (*cmp)(const queue *, const queue *)); + +#define QUEUE_INIT(head) (head)->next = ((head)->prev = head) +#define QUEUE_FIRST(head) ((head)->next) +#define QUEUE_NEXT(element) ((element)->next) +#define QUEUE_LAST(head) ((head)->prev) +#define QUEUE_EMPTY(head) ((head)->next == (head)) +#define QUEUE_MOVE(newhead,oldhead) \ + if ( (oldhead)->next == (oldhead) ) {\ + (newhead)->next = (newhead)->prev = (newhead); \ + } \ + else { \ + (newhead)->next = (oldhead)->next; \ + (newhead)->prev = (oldhead)->prev; \ + (newhead)->next->prev = (newhead); \ + (newhead)->prev->next = (newhead); \ + } \ + (oldhead)->next = (oldhead)->prev = (oldhead) + +#define ENQUEUE_TAIL(listhead, element) \ + enqueue(element, (listhead)->prev) +#define ENQUEUE_HEAD(listhead, element) \ + enqueue(element, listhead) + +#define QUEUE_FOR_EACH(listhead, element, tmp) \ + for ((element) = QUEUE_FIRST(listhead); \ + (tmp) = QUEUE_NEXT(element), \ + (element) != (listhead); \ + (element) = (tmp)) diff --git a/quovadis.c b/quovadis.c new file mode 100644 index 000000000..007dbb67f --- /dev/null +++ b/quovadis.c @@ -0,0 +1,269 @@ +/* + Read and write QuoVadis files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "quovadis.h" + +#if PDBFMTS_ENABLED +static pdbfile *file_in, *file_out; + +static gbuint8* rec_ptr = NULL; +static gbuint8* current_rec = NULL; +static int rec_index = 0; +static int ct; +static char *dbname = NULL; + +static +arglist_t quovadis_args[] = { + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +static struct qv_icon_mapping mapping[] = { + { gt_unknown, QUESTION_ICON }, + { gt_traditional, HOSPITAL_ICON }, + { gt_multi, DOCUMENT_ICON }, + { gt_virtual, CAMERA_ICON }, + { gt_letterbox, MAILBOX_ICON }, + { gt_event, MEETING_ICON }, + { gt_suprise, GIFTSHOP_ICON }, +}; + +#define num_mappings (sizeof(mapping) / sizeof(struct qv_icon_mapping)) + +static geocache_type icon_to_wpt(int icon_bitmap) { + unsigned int i; + + for (i = 0; i < num_mappings; i++) { + if (icon_bitmap == mapping[i].bitmap_id) { + return mapping[i].gc_type; + } + } + return gt_unknown; +} + +static int wpt_to_icon(geocache_type type) { + unsigned int i; + + for (i = 0; i < num_mappings; i++) { + if (type == mapping[i].gc_type) { + return mapping[i].bitmap_id; + } + } + return QUESTION_ICON; +} + +static void +rd_init(const char *fname) +{ + file_in = pdb_open(fname, MYNAME); +} + +static void +rd_deinit(void) +{ + pdb_close(file_in); + if ( dbname ) { + xfree(dbname); + dbname = NULL; + } +} + +static void +wr_init(const char *fname) +{ + file_out = pdb_create(fname, MYNAME); + ct = 0; +} + +static void +wr_deinit(void) +{ + pdb_close(file_out); + if ( dbname ) { + xfree(dbname); + dbname = NULL; + } +} + +static void +data_read(void) +{ + struct record *rec; + pdbrec_t *pdb_rec; + int i; + + if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { + fatal(MYNAME ": Not a QuoVadis file.\n"); + } + + /* Ignore the first record, it contains one zero byte */ + for(pdb_rec = file_in->rec_list->next; pdb_rec; pdb_rec = pdb_rec->next) { + int num_recs = pdb_rec->size / sizeof(struct record); + for (i = 0; i < num_recs; i++) { + waypoint *wpt_tmp; + + wpt_tmp = waypt_new(); + + rec = (struct record *) + &(pdb_rec->data[i * sizeof(struct record)]); + + wpt_tmp->longitude = + (be_read32(&rec->longitude) / 1000000.0) - 180.0; + wpt_tmp->latitude = + 90.0 - (be_read32(&rec->latitude) / 1000000.0); + wpt_tmp->shortname = xstrdup(rec->name); + + wpt_tmp->gc_data.type = + icon_to_wpt(be_read16(&rec->icon_bitmap)); + + waypt_add(wpt_tmp); + } + } +} + + +static void +quovadis_writewpt(waypoint *wpt) +{ + struct record *rec; + int i; + + if (current_rec == NULL) { + gbuint8 dummy = 0; + + pdb_write_rec(file_out, 0, 0, ct++, &dummy, 1); + + current_rec = (gbuint8 *) xcalloc(MAXCHUNKSIZE, 1); + rec_index = 0; + rec_ptr = current_rec; + } + + rec = (struct record *) xcalloc(sizeof(*rec),1); + + be_write32(&rec->longitude, (unsigned int) ((wpt->longitude + + 180.0) * 1000000.0)); + be_write32(&rec->latitude, (unsigned int) ((90.0 - wpt->latitude) * 1000000.0)); + if ( wpt->shortname ) { + strncpy(rec->name, wpt->shortname, 32 ); + rec->name[31] = '\0'; + } + else { + rec->name[0] = '\0'; + } + be_write16(&rec->icon_bitmap, wpt_to_icon(wpt->gc_data.type)); + be_write32(&rec->note_id, 0); + rec->name_scale = DEFAULT_NAME_SCALE; + rec->icon_scale = DEFAULT_ICON_SCALE; + for (i = 0; i < 7; i++) { + rec->reserved[i] = 0; + } + + memcpy(rec_ptr, rec, sizeof(*rec)); + rec_ptr += sizeof(*rec); + rec_index += 1; + xfree(rec); + + if (rec_index == MAXRECORDS) { + fatal(MYNAME ": cannot store more than %lu records at this time.\n", + (unsigned long) MAXRECORDS); + } +} + +struct hdr{ + char *wpt_name; + waypoint *wpt; +}; + +static +int +compare(const void *a, const void *b) +{ + const struct hdr *wa = (const struct hdr *) a; + const struct hdr *wb = (const struct hdr *) b; + + return strcmp(wa->wpt->shortname, wb->wpt->shortname); +} + +static void +data_write(void) +{ + int i, ct = waypt_count(); + struct hdr *htable, *bh; + queue *elem, *tmp; + extern queue waypt_head; + waypoint *waypointp; + + if ( dbname ) { + strncpy( file_out->name, dbname, PDB_DBNAMELEN ); + } + else { + strncpy(file_out->name, "QuoVadisMarkerDB", PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + + /* + * All this is to sort by waypoint names before going to QuoVadis. + * Turns out plain old strcmp will do the trick... + */ + + htable = (struct hdr *) xmalloc(ct * sizeof(*htable)); + bh = htable; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + bh->wpt = waypointp; + bh->wpt_name = waypointp->shortname; + bh ++; + } + qsort(htable, ct, sizeof(*bh), compare); + + for (i=0;i + 18.12 miles, 26 => 46 feet */ + char icon_scale; /* As above. */ + unsigned char reserved[8]; +}; + +struct qv_icon_mapping { + const geocache_type gc_type; + const int bitmap_id; +}; + +/* Icon Types */ +#define QUESTION_ICON 0 +#define RESTARAUNT_ICON 1 +#define BAR_ICON 2 +#define HOTEL_ICON 3 +#define PHONE_ICON 4 +#define HOSPITAL_ICON 5 +#define CHURCH_ICON 6 +#define AIRPORT_ICON 7 +#define TRAIN_ICON 8 +#define BUS_ICON 9 +#define CAR_ICON 10 +#define WRENCH_ICON 11 +#define GASOLINE_ICON 12 +#define PARKING_ICON 13 +#define MAIL_ICON 14 +#define MAILBOX_ICON 15 +#define CLOCK_ICON 16 +#define FLAG_ICON 17 +#define LIBRARY_ICON 18 +#define BUILDINGS_ICON 19 +#define RELIGION_ICON 20 +#define DOCUMENT_ICON 21 +#define ANIMAL_ICON 22 +#define CAMERA_ICON 23 +#define MOVIE_ICON 24 +#define MUSIC_ICON 25 +#define MEETING_ICON 26 +#define RESTROOM_ICON 27 +#define FAMILY_ICON 28 +#define TELEVISION_ICON 29 +#define SAILING_ICON 30 +#define GOLF_ICON 31 +#define WORKOUT_ICON 32 +#define CYCLING_ICON 33 +#define JOGGING_ICON 34 +#define CAMPING_ICON 35 +#define WATER_ICON 36 +#define FOREST_ICON 37 +#define GIFTSHOP_ICON 38 +#define BABY_ICON 39 +#define LOVE_ICON 40 +#define CEMETARY_ICON 41 +#define COMPUTER_ICON 42 +#define MONEY_ICON 43 +#define LEFT_ARROW_ICON 44 +#define RIGHT_ARROW_ICON 45 +#define DOWN_ARROW_ICON 46 +#define UP_ARROW_ICON 47 + +/* Scale Values */ +#define SCALE_18_12MI 15 +#define SCALE_9_06MI 16 +#define SCALE_4_53MI 17 +#define SCALE_2_26MI 18 +#define SCALE_1_13MI 19 +#define SCALE_0_56MI 20 +#define SCALE_0_28MU 21 +#define SCALE_747FT 22 +#define SCALE_373FT 23 +#define SCALE_186FT 24 +#define SCALE_93FT 25 +#define SCALE_46FT 26 + +#define MAXRECORDS (MAXCHUNKSIZE / sizeof(struct record)) +/*#define MAXRECORDS 100*/ +#define DEFAULT_ICON_BITMAP QUESTION_ICON +#define DEFAULT_NAME_SCALE SCALE_2_26MI +#define DEFAULT_ICON_SCALE SCALE_18_12MI + +#endif diff --git a/radius.c b/radius.c new file mode 100644 index 000000000..831c4a8f4 --- /dev/null +++ b/radius.c @@ -0,0 +1,223 @@ +/* + Radius Filter + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "filterdefs.h" +#include "grtcirc.h" + +#if FILTERS_ENABLED + +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +static double pos_dist; +static char *distopt = NULL; +static char *latopt = NULL; +static char *lonopt = NULL; +static char *exclopt = NULL; +static char *nosort = NULL; +static char *maxctarg = NULL; +static char *routename = NULL; +static int maxct; + +static waypoint * home_pos; + +typedef struct { + double distance; +} extra_data; + +static +arglist_t radius_args[] = { + {"lat", &latopt, "Latitude for center point (D.DDDDD)", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, + {"lon", &lonopt, "Longitude for center point (D.DDDDD)", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, + {"distance", &distopt, "Maximum distance from center", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, + {"exclude", &exclopt, "Exclude points close to center", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"nosort", &nosort, "Inhibit sort by distance to center", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"maxcount", &maxctarg,"Output no more than this number of points", + NULL, ARGTYPE_INT, "1", NULL }, + {"asroute", &routename,"Put resulting waypoints in route of this name", + NULL, ARGTYPE_STRING, NULL, NULL }, + ARG_TERMINATOR +}; + +static double +gc_distance(double lat1, double lon1, double lat2, double lon2) +{ + return gcdist( + RAD(lat1), + RAD(lon1), + RAD(lat2), + RAD(lon2) + ); +} + +static int +dist_comp(const void * a, const void * b) +{ + const waypoint *x1 = *(waypoint **)a; + const waypoint *x2 = *(waypoint **)b; + extra_data *x1e = (extra_data *) x1->extra_data; + extra_data *x2e = (extra_data *) x2->extra_data; + + if (x1e->distance > x2e->distance) + return 1; + if (x1e->distance < x2e->distance) + return -1; + return 0; + +} + +void +radius_process(void) +{ + queue * elem, * tmp; + waypoint * waypointp; + double dist; + waypoint ** comp; + int i, wc; + queue temp_head; + route_head *rte_head = NULL; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + extra_data *ed; + + waypointp = (waypoint *)elem; + dist = gc_distance(waypointp->latitude, + waypointp->longitude, + home_pos->latitude, + home_pos->longitude); + + /* convert radians to float point statute miles */ + dist = radtomiles(dist); + + if ((dist >= pos_dist) == (exclopt == NULL)) { + waypt_del(waypointp); + waypt_free(waypointp); + continue; + } + + ed = (extra_data *) xcalloc(1, sizeof(*ed)); + ed->distance = dist; + waypointp->extra_data = ed; + } + + wc = waypt_count(); + QUEUE_INIT(&temp_head); + + comp = (waypoint **) xcalloc(wc, sizeof(*comp)); + + i = 0; + + /* + * Create an array of remaining waypoints, popping them off the + * master queue as we go. This gives us something reasonable + * for qsort. + */ + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wp = (waypoint *) elem; + comp[i] = wp; + waypt_del(wp); + i++; + } + + if (!nosort) { + qsort(comp, wc, sizeof(waypoint *), dist_comp); + } + + if (routename) { + rte_head = route_head_alloc(); + rte_head->rte_name = xstrdup(routename); + route_add_head(rte_head); + } + + /* + * The comp array is now sorted by distance. As we run through it, + * we push them back onto the master wp list, letting us pass them + * on through in the modified order. + */ + for (i = 0; i < wc; i++) { + waypoint * wp = comp[i]; + + xfree(wp->extra_data); + wp->extra_data = NULL; + + if (maxctarg && i >= maxct) { + continue; + } + if (routename) { + route_add_wpt(rte_head, wp); + } else { + waypt_add(wp); + } + } + + xfree(comp); +} + +void +radius_init(const char *args) { + char *fm; + + pos_dist = 0; + + if (distopt) { + pos_dist = strtod(distopt, &fm); + + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to feet */ + pos_dist *= .6214; + } + } + + if (maxctarg) { + maxct = atoi(maxctarg); + } else { + maxct = 0; + } + + home_pos = (waypoint *) xcalloc(sizeof(*home_pos), 1); + + if (latopt) + home_pos->latitude = atof(latopt); + if (lonopt) + home_pos->longitude = atof(lonopt); +} + +void +radius_deinit(void) { + if (home_pos) + xfree(home_pos); +} + +filter_vecs_t radius_vecs = { + radius_init, + radius_process, + radius_deinit, + NULL, + radius_args +}; +#endif // FILTERS_ENABLED diff --git a/random.c b/random.c new file mode 100644 index 000000000..199aa5b4c --- /dev/null +++ b/random.c @@ -0,0 +1,208 @@ +/* + random - GPS data generator + + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include "defs.h" +#include "garmin_fs.h" +#include "jeeps/gpsmath.h" +#include + +#define MYNAME "random" + +static char *opt_points, *opt_seed; + +static arglist_t random_args[] = { + { "points", &opt_points, "Generate # points", NULL, + ARGTYPE_INT, "1", NULL }, + { "seed", &opt_seed, "Starting seed of the internal number generator", NULL, + ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + + +static double +rand_dbl(const double max) +{ + return max * rand() / (((double)RAND_MAX) + 1); +} + +static int +rand_int(const int max) +{ + return (int)((double)max * rand() / (((double)RAND_MAX) + 1)); +} + +/* rand_str always returns a valid string with len >= 0 */ + +static char * +rand_str(const int maxlen, const char *fmt) +{ + char *res; + int i, len; + + len = rand_int(maxlen) + 1; + + res = xmalloc(len + 1); + res[len] = '\0'; + + for (i = 0; i < len; i++) { + int c = rand_int(26 + 26 + 10); + if ( c < 26 ) + c += 'a'; + else if (c < 52) + c = (c - 26) + 'A'; + else + c = (c - 52) + '0'; + res[i] = c; + } + if (fmt) { + char *tmp; + xasprintf(&tmp, fmt, res); + xfree(res); + return tmp; + } + else + return res; +} + +static void +random_rd_init(const char *fname) +{ +} + +static void +random_rd_deinit(void) +{ +} + +static void +random_read(void) +{ +#define RND(a) (rand_int(a) > 0) + + int i, points; + route_head *head; + waypoint *prev = NULL; + time_t time = gpsbabel_time; + + if (opt_seed) + srand(atoi(opt_seed)); + else + srand(gpsbabel_now); + + + points = (opt_points) ? atoi(opt_points) : rand_int(128) + 1; + if (doing_trks || doing_rtes) { + head = route_head_alloc(); + if (doing_trks) { + head->rte_name = rand_str(8, "Trk_%s"); + track_add_head(head); + } + else { + head->rte_name = rand_str(8, "Rte_%s"); + route_add_head(head); + } + head->rte_desc = rand_str(16, NULL); + } + else head = NULL; + + for (i = 0; i < points; i++) { + + waypoint *wpt; + garmin_fs_t *gmsd; + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + do { + wpt->shortname = rand_str(8, "Wpt_%s"); + } while (wpt->shortname == NULL); + + wpt->latitude = rand_dbl(180) - 90; + wpt->longitude = rand_dbl(360) - 180; + + /* !!! "if RND(3) ..." produces some leaks in generated data !!! */ + + if RND(3) wpt->altitude = rand_int(1000) / 10; + if RND(3) WAYPT_SET(wpt, temperature, rand_int(320) / 10.0); + if RND(3) WAYPT_SET(wpt, proximity, rand_int(10000) / 10.0); + if RND(3) WAYPT_SET(wpt, depth, rand_int(10000) / 10.0); + + wpt->creation_time = time; + if RND(3) wpt->microseconds = rand_int(1000) * 1000; + time += rand_int(10) + 1; + + if (doing_trks) { + if (i > 0) { + wpt->latitude = prev->latitude + (rand_dbl(1) / 1000); + wpt->longitude = prev->longitude + (rand_dbl(1) / 1000); + WAYPT_SET(wpt, course, waypt_course(prev, wpt)); + WAYPT_SET(wpt, speed, waypt_speed(prev, wpt)); + } + wpt->sat = rand_int(12 + 1); + wpt->hdop = (rand_int(500)) / 10.0; + wpt->vdop = (rand_int(500)) / 10.0; + wpt->pdop = (rand_int(500)) / 10.0; + wpt->fix = rand_int(6) - 1; + if RND(3) wpt->cadence = rand_int(255); + if RND(3) wpt->heartrate = rand_int(255); + } + else { + if (doing_rtes && (i > 0)) { + wpt->latitude = prev->latitude + (rand_dbl(1) / 100); + wpt->longitude = prev->longitude + (rand_dbl(1) / 100); + } + if RND(3) wpt->description = rand_str(16, "Des_%s"); + if RND(3) wpt->notes = rand_str(16, "Nts_%s"); + if RND(3) GMSD_SET(addr, rand_str(8, "Adr_%s")); + if RND(3) GMSD_SET(city, rand_str(8, "Cty_%s")); + if RND(3) GMSD_SET(facility, rand_str(8, "Fac_%s")); + if RND(3) GMSD_SET(country, rand_str(8, "Ctr_%s")); + if RND(3) GMSD_SET(state, rand_str(8, "Sta_%s")); + if RND(3) GMSD_SET(phone_nr, rand_str(8, "Pnr_%s")); + if RND(3) GMSD_SET(postal_code, rand_str(8, "Pcd_%s")); + } + + if (doing_trks) track_add_wpt(head, wpt); + else if (doing_rtes) route_add_wpt(head, wpt); + else waypt_add(wpt); + + prev = wpt; + } +} + + +ff_vecs_t random_vecs = { + ff_type_internal, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_read /* routes */ + }, + random_rd_init, + NULL, /* wr_init */ + random_rd_deinit, + NULL, /* wr_deinit */ + random_read, + NULL, /* write */ + NULL, /* exit */ + random_args, + CET_CHARSET_ASCII, 1 /* fixed */ +}; diff --git a/raymarine.c b/raymarine.c new file mode 100644 index 000000000..adc4e38d4 --- /dev/null +++ b/raymarine.c @@ -0,0 +1,509 @@ + /* + + Support for Raymarine Waypoint File (.rwf). + + Copyright (C) 2006,2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +/* + Known format limits: + + Waypoint name: max. 16 characters + Route name: max. 16 characters + Routes: max. 50 waypoints per route + ???: the character set may be only a subset of std. ASCII + + History: + + 2006/10/30: Initial release (not yet in GPSBabel source tree) + 2006/11/08: + 2007/03/17: Remove GUIDs from writer (not really valid) + Fix "PredictedTwa" output + Initialize location with "My Waypoints" + Change default value for RcCount and RelSet (now 0) + 2007/04/18: Limit route names also to 16 characters + Bug-fix - add missing comma (write_route_wpt_cb/items) + Change line feeds to fixed CRLF + Sort waypoints by name (not really needed, but nice) + Add some MapSource icon names to icon mappings + Remove unused id from icon table +*/ + +#include "defs.h" +#include "inifile.h" +#include "csv_util.h" + +#include +#include +#include + +typedef unsigned long long guid_t; + +static inifile_t *fin; +static gbfile *fout; +static waypoint **waypt_table; +static short_handle hshort_wpt, hshort_rte; +static int waypt_table_sz, waypt_table_ct; +static int rte_index, rte_wpt_index; +static char *opt_location; + +#define MYNAME "raymarine" + +static +arglist_t raymarine_args[] = +{ + { "location", &opt_location, "Default location", "My Waypoints", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +/* from csv_util.c: convert excel time (days since 1900) to time_t and back again */ + +#define EXCEL_TO_TIMET(a) ((a - 25569.0) * 86400.0) +#define TIMET_TO_EXCEL(a) ((a / 86400.0) + 25569.0) + +#define LINE_FEED "\r\n" + +/* Bitmaps */ + +typedef struct { + char *name; + char *mps_name; +} raymarine_symbol_mapping_t; + +static raymarine_symbol_mapping_t raymarine_symbols[] = { + { /* 0 */ "Unknown Symbol 0" }, + { /* 1 */ "Unknown Symbol 1" }, + { /* 2 */ "Unknown Symbol 2" }, + { /* 3 */ "Red Square" }, + { /* 4 */ "Big Fish" }, + { /* 5 */ "Anchor" }, + { /* 6 */ "Smiley", "Contact, Smiley" }, + { /* 7 */ "Sad" }, + { /* 8 */ "Red Button", "Navaid, Red" }, + { /* 9 */ "Sailfish" }, + { /* 10 */ "Danger", "Skull and Crossbones" }, + { /* 11 */ "Attention" }, + { /* 12 */ "Black Square" }, + { /* 13 */ "Intl. Dive Flag", "Diver Down Flag 2" }, + { /* 14 */ "Vessel", "Marina" }, + { /* 15 */ "Lobster" }, + { /* 16 */ "Buoy", "Buoy, White" }, + { /* 17 */ "Exclamation" }, + { /* 18 */ "Red X" }, + { /* 19 */ "Check Mark" }, + { /* 20 */ "Black Plus" }, + { /* 21 */ "Black Cross" }, + { /* 22 */ "MOB" }, + { /* 23 */ "Billfish" }, + { /* 24 */ "Bottom Mark" }, + { /* 25 */ "Circle", "Circle, Red" }, + { /* 26 */ "Diamond", "Block, Red" }, + { /* 27 */ "Diamond Quarters", "Diamond, Red" }, + { /* 28 */ "U.S. Dive Flag", "Diver Down Flag 1" }, + { /* 29 */ "Dolphin" }, + { /* 30 */ "Few Fish" }, + { /* 31 */ "Multiple Fish" }, + { /* 32 */ "Many Fish" }, + { /* 33 */ "Single Fish" }, + { /* 34 */ "Small Fish" }, + { /* 35 */ "Marker" }, + { /* 36 */ "Cocktails", "Bar" }, + { /* 37 */ "Red Box Marker" }, + { /* 38 */ "Reef" }, + { /* 39 */ "Rocks" }, + { /* 40 */ "Fish School" }, + { /* 41 */ "Seaweed", "Weed Bed" }, + { /* 42 */ "Shark" }, + { /* 43 */ "Sportfisher" }, + { /* 44 */ "Swimmer", "Swimming Area" }, + { /* 45 */ "Top Mark" }, + { /* 46 */ "Trawler" }, + { /* 47 */ "Tree" }, + { /* 48 */ "Triangle", "Triangle, Red" }, + { /* 49 */ "Wreck", "Shipwreck" } +}; + +#define RAYMARINE_SYMBOL_CT sizeof(raymarine_symbols) / sizeof(raymarine_symbol_mapping_t) +#define RAYMARINE_STD_SYMBOL 3 + +static int +find_symbol_num(const char *descr) +{ + if ((descr != NULL) && (*descr)) { + + int i; + raymarine_symbol_mapping_t *a; + + a = &raymarine_symbols[0]; + + for (i = 0; i < RAYMARINE_SYMBOL_CT; i++, a++) { + if (case_ignore_strcmp(descr, a->name) == 0) return i; + if (a->mps_name && (case_ignore_strcmp(descr, a->mps_name) == 0)) return i; + } + } + + return RAYMARINE_STD_SYMBOL; +} + +/* ============================================= */ +/* %%% R A Y M A R I N E R E A D E R %%% */ +/* ============================================= */ + +static void +raymarine_rd_init(const char *fname) +{ + fin = inifile_init(fname, MYNAME); +} + +static void +raymarine_rd_done(void) +{ + inifile_done(fin); +} + +static void +raymarine_read(void) +{ + waypoint *wpt; + int ix, rx; + + /* Read all waypoints */ + + for (ix = 0; ix < 0x3FFF; ix++) { + char sect[10]; + char *str, *name, *lat, *lon; + + /* built section identifier */ + snprintf(sect, sizeof(sect), "Wp%d", ix); + + /* try to read our most expected values */ + if (NULL == (name = inifile_readstr(fin, sect, "Name"))) break; + if (NULL == (lat = inifile_readstr(fin, sect, "Lat"))) break; + if (NULL == (lon = inifile_readstr(fin, sect, "Long"))) break; + + wpt = waypt_new(); + wpt->shortname = xstrdup(name); + wpt->latitude = atof(lat); + wpt->longitude = atof(lon); + waypt_add(wpt); + + /* try to read optional values */ + if (((str = inifile_readstr(fin, sect, "Notes"))) && *str) wpt->notes = xstrdup(str); + if (((str = inifile_readstr(fin, sect, "Time"))) && *str) wpt->creation_time = EXCEL_TO_TIMET(atof(str)); + if (((str = inifile_readstr(fin, sect, "Bmp"))) && *str) { + int symbol = atoi(str); + + if ((symbol < 3) && (symbol >= RAYMARINE_SYMBOL_CT)) + symbol = RAYMARINE_STD_SYMBOL; + wpt->icon_descr = raymarine_symbols[symbol].name; + } + } + + /* Read all routes */ + + for (rx = 0; rx < 0x3FFF; rx++) { + char sect[10]; + char *name; + route_head *rte; + int wx; + + snprintf(sect, sizeof(sect), "Rt%d", rx); + if (NULL == (name = inifile_readstr(fin, sect, "Name"))) break; + + rte = route_head_alloc(); + rte->rte_name = xstrdup(name); + route_add_head(rte); + + for (wx = 0; wx < 0x3FFF; wx++) { + char buff[32]; + char *str; + waypoint * wpt; + + snprintf(buff, sizeof(buff), "Mk%d", wx); + str = inifile_readstr(fin, sect, buff); + if ((str == NULL) || (*str == '\0')) break; + + wpt = find_waypt_by_name(str); + if (wpt == NULL) + fatal(MYNAME ": No associated waypoint for route point %s (Route %s)!\n", + str, rte->rte_name); + + route_add_wpt(rte, waypt_dupe(wpt)); + } + } +} + +/* ============================================= */ +/* %%% R A Y M A R I N E W R I T E R %%% */ +/* ============================================= */ + +/* make waypoint shortnames unique */ + +static char +same_points(const waypoint *A, const waypoint *B) +{ + return ( /* !!! We are case-sensitive !!! */ + (strcmp(A->shortname, B->shortname) == 0) && + (A->latitude == B->latitude) && + (A->longitude == B->longitude)); +} + +static void +register_waypt(const waypoint *ref, const char is_rtept) +{ + int i; + waypoint *wpt = (waypoint *) ref; + + for (i = 0; i < waypt_table_ct; i++) { + waypoint *cmp = waypt_table[i]; + + if (same_points(wpt, cmp)) { + wpt->extra_data = cmp->extra_data; + return; + } + } + + if (waypt_table_ct >= waypt_table_sz) { + waypt_table_sz += 32; + if (waypt_table) + waypt_table = (void *) xrealloc(waypt_table, waypt_table_sz * sizeof(wpt)); + else + waypt_table = (void *) xmalloc(waypt_table_sz * sizeof(wpt)); + } + + wpt->extra_data = (void *)mkshort(hshort_wpt, wpt->shortname); + + waypt_table[waypt_table_ct] = (waypoint *)wpt; + waypt_table_ct++; +} + +static void +enum_waypt_cb(const waypoint *wpt) +{ + register_waypt((waypoint *) wpt, 0); +} + +static void +enum_rtept_cb(const waypoint *wpt) +{ + register_waypt((waypoint *) wpt, 1); +} + +static int +qsort_cb(const void *a, const void *b) +{ + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; + + return strcmp(wa->shortname, wb->shortname); +} + +static void +write_waypoint(gbfile *fout, const waypoint *wpt, const int waypt_no, const char *location) +{ + char *notes; + char *name; + double time; + + notes = wpt->notes; + if (notes == NULL) { + notes = wpt->description; + if (notes == NULL) notes = ""; + } + notes = csv_stringclean(notes, LINE_FEED); + time = (wpt->creation_time > 0) ? TIMET_TO_EXCEL(wpt->creation_time) : TIMET_TO_EXCEL(gpsbabel_time); + name = (char *)wpt->extra_data; + + gbfprintf(fout, "[Wp%d]" LINE_FEED + "Loc=%s" LINE_FEED + "Name=%s" LINE_FEED + "Lat=%.15f" LINE_FEED + "Long=%.15f" LINE_FEED, + waypt_no, location, name, wpt->latitude, wpt->longitude + ); + gbfprintf(fout, "Rng=%.15f" LINE_FEED + "Bear=%.15f" LINE_FEED + "Bmp=%d" LINE_FEED + "Fixed=1" LINE_FEED + "Locked=0" LINE_FEED + "Notes=%s" LINE_FEED, + 0.0, 0.0, + find_symbol_num(wpt->icon_descr), + notes + ); + gbfprintf(fout, "Rel=" LINE_FEED + "RelSet=0" LINE_FEED + "RcCount=0" LINE_FEED + "RcRadius=%.15f" LINE_FEED + "Show=1" LINE_FEED + "RcShow=0" LINE_FEED + "SeaTemp=%.15f" LINE_FEED + "Depth=%.15f" LINE_FEED + "Time=%.10f00000" LINE_FEED, + 0.0, -32678.0, 65535.0, time + ); + xfree(notes); +} + +static void +write_route_head_cb(const route_head *rte) +{ + char buff[32]; + char *name; + + name = rte->rte_name; + if ((name == NULL) || (*name == '\0')) { + snprintf(buff, sizeof(buff), "Route%d", rte_index); + name = buff; + } + name = mkshort(hshort_rte, name); + gbfprintf(fout, "[Rt%d]" LINE_FEED + "Name=%s" LINE_FEED + "Visible=1" LINE_FEED, + rte_index, + name + ); + xfree(name); + + rte_index++; + rte_wpt_index = 0; +} + +static void +write_route_wpt_cb(const waypoint *wpt) +{ + int i; + static char *items[] = { + "Cog", + "Eta", + "Length", + "PredictedDrift", + "PredictedSet", + "PredictedSog", + "PredictedTime", + "PredictedTwa", + "PredictedTwd", + "PredictedTws" }; + + gbfprintf(fout, "Mk%d=%s" LINE_FEED, rte_wpt_index, (char *)wpt->extra_data); + for (i = 0; i < sizeof(items) / sizeof(char *); i++) + gbfprintf(fout, "%s%d=%.15f" LINE_FEED, items[i], rte_wpt_index, 0.0); + + rte_wpt_index++; + return; +} + +static void +enum_route_hdr_cb(const route_head *rte) +{ + is_fatal(rte->rte_waypt_ct > 50, + MYNAME ": Routes with more than 50 points are not supported by Waymarine!"); +} + +static short_handle +raymarine_new_short_handle(void) +{ + short_handle res; + + res = mkshort_new_handle(); + + setshort_length(res, 16); + setshort_badchars(res, ","); + setshort_mustupper(res, 0); + setshort_mustuniq(res, 1); + setshort_whitespace_ok(res, 1); + setshort_repeating_whitespace_ok(res, 1); + + return res; +} + +static void +raymarine_wr_init(const char *fname) +{ + fout = gbfopen(fname, "wb", MYNAME); + + hshort_wpt = raymarine_new_short_handle(); + hshort_rte = raymarine_new_short_handle(); +} + +static void +raymarine_wr_done(void) +{ + mkshort_del_handle(&hshort_wpt); + mkshort_del_handle(&hshort_rte); + + gbfclose(fout); +} + +static void +raymarine_write(void) +{ + int i; + waypoint *wpt; + + waypt_table_sz = 0; + waypt_table_ct = 0; + waypt_table = NULL; + + /* enumerate all possible waypoints */ + waypt_disp_all(enum_waypt_cb); + route_disp_all(enum_route_hdr_cb, NULL, enum_rtept_cb); + + if (waypt_table_ct == 0) return; + + qsort(waypt_table, waypt_table_ct, sizeof(*waypt_table), qsort_cb); + + /* write out waypoint summary */ + for (i = 0; i < waypt_table_ct; i++) { + waypoint *wpt = waypt_table[i]; + write_waypoint(fout, wpt, i, opt_location); + } + + /* write out all routes with their waypoints */ + rte_index = 0; + route_disp_all(write_route_head_cb, NULL, write_route_wpt_cb); + + /* release local used data */ + for (i = 0; i < waypt_table_ct; i++) { + wpt = waypt_table[i]; + xfree(wpt->extra_data); + wpt->extra_data = NULL; + } + xfree(waypt_table); +} + +/* ================================================== */ +/* %%% M O D U L E R E G I S T R A T I O N %%% */ +/* ================================================== */ + +ff_vecs_t raymarine_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_read | ff_cap_write /* routes */, + }, + raymarine_rd_init, + raymarine_wr_init, + raymarine_rd_done, + raymarine_wr_done, + raymarine_read, + raymarine_write, + NULL, + raymarine_args, + CET_CHARSET_ASCII, 0 /* should we force this to 1 ? */ +}; diff --git a/reference/GeocachingDB.PDB b/reference/GeocachingDB.PDB new file mode 100644 index 0000000000000000000000000000000000000000..4f6c38b6ba2ec34822bf548f5317cfdc146d595d GIT binary patch literal 5822 zcmeHL%TC)s6urF4qm{a7)g_v4T99C{XZ(oOhvb+fg_eLqppQ*8Nemc_Eg1(IRCV1S z=)T`ksZv)}KdOt~aU2|~AhpFv70L*6CSzliGv}PSGZi;%isqgd>@F8!P@960FPmRK z$?Nyq%XZx^Mj}2NpTXYe(d6SufH(p$`VkR-#(v6Q02AL3#{njPAWi_x+(WzpaO*qb zB*1NnQvi2n5vTE0GrP?|AU@h{dM(6BU&IRHD58ouhR6_S{4nT_hk+a)$Io*7X3N{z zL7a}=D3VxRd9_}BxJl~IN@TrSx=$J%@}a)xl2y?;S|IgEw7l301K|?~nQ_USO7$hY z<^d`W<4zf%3fuzFRm!<)6%=?0i>3~X8lwg`z2 zv$@i81usjPF6PCwlw3Uuk6j{Sf;I|Tof9u`|3Z$aMoTroN;xl3OIIbusT#RPnUTm7 znNHQHupax8p}8xd>A!wu-g8)V#jzWa)HG<6noJCTfz-U_0eL`{@%F$-VHhcR&10f) zt!($^P**5tyx%vR>UuJOGndU_FI$jonQ_B*2?kP47C_!1Nh z|MUtNNOeV1UER2B-QpF4c0=l@X=BE`4c-U)VsN%BF{vlUdACks8mA^EMy4iB$JJPo zF~hU^<*sYvVtk1*HKM?Uip`zltb+uV> zjG|_zb+x8z)Jih$tdhYenJ)F(SIL~y>&A7StKoOcpMkvfUlOMsvex!vZ&B{2lQMqI zjm2q0w6G9d^$rg^$&H2dsdR72WLTsAHPyylYqI)lxQ#5Zb9v3FqA?lZS^eJELw4Te z&(QFVLk9kwfz(f>yw;PgBX_6mla<&#Jjzy+3mi4z%qH;_RzbSToV2QD=qs~pquzN9 z`btTv>OMDR6%l@WdEzu|Lk6x51F27+=H=7UyEqd6Y|zA?y}Hkl$EV#x!pxrr?t1Y^ Li=Mf%uLtl8M3dT< literal 0 HcmV?d00001 diff --git a/reference/Glad_4.exp b/reference/Glad_4.exp new file mode 100644 index 0000000000000000000000000000000000000000..17d1fc56bdfb35a9eb2e00f74f43b47842348fce GIT binary patch literal 19994 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 XdQ6Lv{?#xtjOZ~THX^ZeZfyJ?B-RD% literal 0 HcmV?d00001 diff --git a/reference/Glad_5.exp b/reference/Glad_5.exp new file mode 100644 index 000000000..f2397b966 --- /dev/null +++ b/reference/Glad_5.exp @@ -0,0 +1,536 @@ + + + + 1.0000000 + ROUTENAME + 0 + + waypnt + + + 1 + -20.226667 + 149.205000 + + + waypnt + + + 1 + -20.850000 + 149.641667 + + + waypnt + + + 1 + -21.680097 + 150.176053 + + + waypnt + + + 1 + -22.318424 + 150.747716 + + + waypnt + + + 1 + -23.448417 + 151.322716 + + + waypnt + + + 1 + -23.890914 + 151.516050 + + + waypnt + + + 1 + -21.951659 + 150.754996 + + + waypnt + + + 1 + -20.988434 + 149.929385 + + + waypnt + + + 1 + -20.081093 + 149.064390 + + + waypnt + + + 1 + -19.375083 + 147.819367 + + + waypnt + + + 1 + -18.433464 + 146.549413 + + + waypnt + + + 1 + -18.213466 + 146.409414 + + + waypnt + + + 1 + -16.913473 + 146.059410 + + + waypnt + + + 1 + -16.731975 + 145.889412 + + + waypnt + + + 1 + -16.465144 + 145.637746 + + + waypnt + + + 1 + -15.921814 + 145.481079 + + + waypnt + + + 1 + -15.708466 + 145.382746 + + + waypnt + + + 1 + -15.110152 + 145.402742 + + + waypnt + + + 1 + -14.673488 + 145.417740 + + + waypnt + + + 1 + -14.626822 + 145.251075 + + + waypnt + + + 1 + -14.546823 + 145.061077 + + + waypnt + + + 1 + -14.483491 + 144.979411 + + + waypnt + + + 1 + -14.483491 + 144.932745 + + + waypnt + + + 1 + -14.451825 + 144.902745 + + + waypnt + + + 1 + -14.361826 + 144.686081 + + + waypnt + + + 1 + -14.195161 + 144.604414 + + + waypnt + + + 1 + -14.138495 + 144.511082 + + + waypnt + + + 1 + -14.060163 + 144.331083 + + + waypnt + + + 1 + -14.101829 + 144.244418 + + + waypnt + + + 1 + -14.101831 + 143.977754 + + + waypnt + + + 1 + -14.065164 + 143.917755 + + + waypnt + + + 1 + -13.981832 + 143.834422 + + + waypnt + + + 1 + -13.915166 + 143.812755 + + + waypnt + + + 1 + -13.815167 + 143.734423 + + + waypnt + + + 1 + -13.656834 + 143.704422 + + + waypnt + + + 1 + -13.475169 + 143.671088 + + + waypnt + + + 1 + -13.341836 + 143.671088 + + + waypnt + + + 1 + -13.096838 + 143.611087 + + + waypnt + + + 1 + -12.886839 + 143.594420 + + + waypnt + + + 1 + -12.818506 + 143.586087 + + + waypnt + + + 1 + -12.415159 + 143.362754 + + + waypnt + + + 1 + -12.236844 + 143.247755 + + + waypnt + + + 1 + -12.085178 + 143.239421 + + + waypnt + + + 1 + -11.963512 + 143.317753 + + + waypnt + + + 1 + -11.586849 + 142.981088 + + + waypnt + + + 1 + -11.378517 + 142.986088 + + + waypnt + + + 1 + -11.231851 + 142.954421 + + + waypnt + + + 1 + -10.806855 + 142.804421 + + + waypnt + + + 1 + -10.741855 + 142.676089 + + + waypnt + + + 1 + -10.601857 + 142.552756 + + + waypnt + + + 1 + -10.501858 + 142.377758 + + + waypnt + + + 1 + -10.480192 + 142.334425 + + + waypnt + + + 1 + -10.495192 + 142.282759 + + + waypnt + + + 1 + -10.508525 + 142.251093 + + + waypnt + + + 1 + -10.510192 + 142.202760 + + + waypnt + + + 1 + -10.561859 + 142.126094 + + + waypnt + + + 1 + -10.568517 + 141.909433 + + + waypnt + + + 1 + -10.829182 + 141.659173 + + + waypnt + + + 1 + -12.568516 + 141.501109 + + + waypnt + + + 1 + -12.705000 + 141.661667 + + + waypnt + + + 1 + -12.700000 + 141.688333 + + + waypnt + + + 1 + -10.590757 + 141.875120 + + + waypnt + + + 1 + -10.575158 + 141.891066 + + + waypnt + + + 1 + -14.965864 + 145.407427 + + + waypnt + + + 1 + -14.632647 + 145.189250 + + + waypnt + + + 1 + -14.517175 + 144.911974 + + + diff --git a/reference/IMG_2065.JPG b/reference/IMG_2065.JPG new file mode 100644 index 0000000000000000000000000000000000000000..0578f1f13c68fb07276eba72e294c49f64c49c5c GIT binary patch literal 18399 zcmeFYbyOTtvoAV>4H}%_HiHv_yA#}kI|O%kw?MGq5(tvug9LX81i~P}3GNUG5D4z_ zh9u{n@11qmdhfo!-|n@$eqCL=YS-4D>gk8shgATMf{eTj00;yEhrew|4aZON|JDr^jwZzI6*W3Sf3G2%bm4#!AvObh4tKB|CYc!dF|kAnYX z2;dkGj>+L1ayZ8S$Jc~o6u4GuINuPCL2&%oa{+LS3fBsR<0KtC0NOv9R5%~!A0Gf< z0Aj)QJld^?^B!0W{cWCscW`TiXIaK!W2l$kLv*NPbma=8$W7zY-$yFMu0DMk5h9BE(u?2 z|L~>Z*GT{Pzu4=*3TfS}Y1X&G5Lc?AtkEo~iL zJ$-WvODk&|TRV3TPcLsDU%&9z5s`1AqGOU%Qq$5i-eqRx7Zes1my|-wYU}D78k?G1 zTEF!4e(i(x4-8IBPJN%AnVp+oTi@9Hv94w0okYINlB0UQLNhnH7d3rmWBdWSHe01h-)KjFJxm{b+-s|oXa||#xepZao zwUD)9CSF}d5Ddn-)}dj8;>|0v)=Ie48TwAja;0gzCIgK*#UVIC`?n64DSfROQT2*- z1d6t`dltn!LcJCNWx8Jd4)=uH85dmNjw(L%ni+-qZcN>&YUsL^|1^9rvZSn3sD=Da zb4YMT%5>0Jo!OE{!kUnIM8uAaB6jyXb4?iw{}~kdOR!&2e?ZZhyE;pretwhu-I_W^ zb6YiZi;BrtS)sVDa|v+Iq5kX?a<`_KnUFe$Qm9>~=!tvJbGs|ul28|uXG0z_W+!f! z*kV#CZ1jO2Or@c$CGl&{SHDO@6M50RoblFnWuE9Kr*XZO`C_I<;9DHq^*SA`CK0r9 z+!e_?w8{-*3cZvPy0Hf3Wd0vUwY1Hrrdcn$;=(nn&I}v{#W=nA&q*p7)NvEIbHm~c zbCO~|U24eY4$3C-v;y>Ea!Y1%RjaE+rabqYv6q#t^9?KXJ&tIHIm2{0C}azss3031 zHN`!t!kCl5i+$m;F8O3#_5tvznfhednOplPA{sYm&U^_RIyz-O6E9{W>Pf@oAGwS5 z+-I<@1=}A#vweeg*U3K~yu?7AWsYX!j(r0Au7SM=uVBKATGN13kN{;CRzy@}|a(8GWm~DP(A@+jX z4J1(Ogl!fqs9N6ytq6to1&5j3tWIXUeA~u<{jtQhLv&UuE*q2PduEp@i~FMr323j_kJQf>U-|7^gGU9#erFkWN`203<{=4g zU&#?R`4${CO+B?rKsw0UW~O9z!$gpI+nIr$77QOi@G#UL#k`}6S--D;|X8R7Ne6q)ZA zagZA87*qj}^Lvgj+Y3`SIs#>T7flM3>${pw9F2y3Pn(EMsz^TB8+PUN!4xqXe;1D+BwpUkcQpx&*xrjJA^;l@s=Q}y!~@s)=pjt`a4dy zY9DP$rDk^=^yPsv*)qUB7x^>(9YdvlhNO8s$!(0b&p-4sz(3~OlP(fEJS4L?+-(96 zDt3^+zm1D;)KF|M_jD1os*Q=xSOIuIdnMj6y#fVzmL8ZN|FE3ZhSb`?b+8 ze}5xfgKb6X>bsU*nn7-6WhPw_)6ZbRRL4`X9Bpl=1R0 z6I-C*#zZ0UX{lxv6snamHNk}U_VW@|j$B)C+e?<`P^f0y1AvHGMuGPM;Gr3#a}!oz zm>ct*xxo71zCOf<96h7?z?`OCcNRWq#39hD+Deif($LBX!@*?gLw0Z|?N9HqBU}l(&o1Ht)A!A|g!d z4pi@{^tCC5pYz98T~Bmuy8Jq^L^t}v$N&{Veu>w#)csYCw*`>4k%;;;&`zJ!s%+qL zDw+`t&MUGi{1|jDP64AW)|1M9&M-z!I-EbrW1g5OKow!q1gTB-5k?#~mjxpb2Xw{X z*&FwY-j~g7AiYWmn06!ump6#D68CX@SCQsDyo%Gg^KbIgL5Po&r zJfiH~bW@P@Jm7d(wmZSIY{1=>SqYNj>OCU99T#N8u`=KMo5Ub6({%h7wR$yC&Y*x9 z*JRV>%%>#*x2|v);jrDgBd3uvYZa&O3t6Xj%$uYEflsJ59s@Q$DYIhplq9a(OjOLb za||myW)A?#Ha*KEwFyEJP6gicowIYopRGh;S@L`-*r$mxr0hOgyQ(cCzR-3F595K= z_>tANqvH?>%F9v0*7uwZN&V5NqlmLxMe;Mw&#u2i+?Jjm(HAau`v&-9-*=cKm#U{RlP;SPUZ?m-P$9Z&OI$DxlIM_i zKy8o1`_07AUEiX}bAgX|G7E{P{Of6N+*Jgw`jb=}chf8#l9EQJOCj(3VoPS| zlmV5(^aI|Ozu|0Iau(h6i%F7a32jbLo~@w3)^D6Lk9GJuGEouVOdWsqJ8Rm?VVwaL zWafTn&s+J?HY2t6D4AenLR=gXkCeDC($WSMI(@HGXMSG$)vqC-XNRU}VK3H4&&Vov-FL>2t z!(d)M(WuYNBA4ctZ9y-%uLbFIy09$7*oNGZe0yiP>D04+s@ieO-#<h3Qxch+_BlnOm9CTQVHMxUK4j7E%GZWWET`7TU-Yahy$I(uKRLbiO0MY2;59Q&RWr%jp=vxRoy?Cj7&xKqPc?h ztwlc@?jS|VQ$tEJ;LOjJ4c!?XK2H7jx<;+Rm78(}d28f17TQxO?1n!Qf-);&J5*IU z)_ zL!Vc2pj#F%D|(QY*5<3+hOl`Xh7Tk=F{MB0^+LmbY&1K=72qk!1a&r8@?hz&+$rsD zkYBx55lzduOZNum*1s*5Ly_Xqu#Glce9l&9F~Ep^)adqxL~KnnX4DxcDzV!a61O_V z%K>2bQ|ZeGCIC!+bYeOfvT)UHi7PG!UU?@1ry&|+IaUTc#(x=Sx?4%RZ$8n4!F_F3Yl zinWLrOIEg#f&%Sh>c8X3O0c9fiD2t5#2hMR9=9KG^bb(I<(`UFntSHttA51iw0h5d z#C^!*5+pIecqfJqi{Gcc2@O5?Fce| zsL^-qL)hXpG5@Xh#U3jd6TRBm#!#qbjibTv(Qx9KJzA$;^IXQ9)9YWrFTsgq7Hya%)C z$!>-GvWpJ|pZj!UK#xsGe;qB=xjfa&;OkR{Z^H!jV>7n2$Dw?xG-rkn0Jesw^DpU% zwtYn2t-`m@4^6iB4bJAGnTTfu+@H2x7E+eXiN)UPM?Xu4v_w;Fr4~?r;}?5tw%0gm zCzmKo>|ohG))le8qeHq`mX=INvJskS*VzmD7S%Ks9JQmJgt>~@BP7mGp~8rleOq#W z&0_?CBmxpA2fV1*cNTc2Ua44)4zBok41ATV#qAal8#*rgqFx3tnW^L`&PiZuqJTe8 z>H`|UNquMFG0b57H?E^v*H)QZ!<0cv{-n0PWLsZq_H!ADFB0>)!@pcg(wLoRvC&@x&xRHC<9cZ=gEI{nitT))oRudW2fF!p zq=y$%4AIaq;&Z3QnZZsD&EU_KinvYIHf{Pc9$Loj8&}h1!t5W8>D_v*!;kMh2gv$f zJuMb=|EiLaT3B z{AIzm4kyX}HHE2#p|z(OTu3)_T0c4D3HBN3;?Z_Sn8Q_u`#{Fcg^S+STQDc)j@&Ro z5#g^GzR9LhV2r8l=~gml+8;5o6J4bCC*(l&#``urCMSVd(H>vNFG?dt4Ylb zI%oEsy^5cIW-|ar*m{NHCW9s7$w-I%Eg6}jF$}a}s03_sW& z`^!`$+{z3I5if#yImMv?$35F-1=UzuFV;{F`FB*183d@~u3e2dGF%mgmxx}>ZN8!U z%@(Y0BJ4r-X6??dcq`5{u{HjV>BTsCq>RL#wsNeDrBpN`$Lk43+b0Sq_X7_Aba8!3L*KWe>cO#u#y&kzp{IAN?g~~m{Lk1XXQ*)%iqZV| zH4Zq$Nw&t5vLpc;h|BruYf*h(2@(_ap9)^Y@ve&*PD}Mo;Aooj2vrja)MZ#=io+%< zWNl_}gnzjJfAW_lV2GnpPfa)J1_Ts{xV03|m?qeer$)bg>I5=Zq-(E6%ns?$;pe_` zLUM{g7b@*?l3}hmQQCG-UsUx=b0Oz#cCbj~ia!&GCHmqb<@&a{)NvoHZ=E;{M355g z9$nY`L^Sm}rZ*a54vARw6`&A9cjrj4A@Kr*bf#&ctt9jRbX_jO+(rLLCf6sol_E}Q zj{P&zc-GJ+H6n2!OAD39E0hTLIN?gLIFKNMSVg^fJ;F6f1LhC-MSv5QU4KjgTJ{z z_!FM`ub3ME5eWfaM<4(d9=nqI8*&4pAR?n6qM*P-t^XZzL&2w&P&0K6O(Nj@SThci zRPSCpBm{Foq|DsHkBBrh!;({8Xt~3ckiz3ca1;N_z@rkl6=W3nJyv+^>oKSYPmeFH z9up8ARDwtJknkmF)l89HLkYl~TuC+KYY+dokkc+v@(TdaRkg6RAddXzyOQ=%9v{^W zv_6b#J!MaK5%;5VI>!=1&>oI3wBOpiE4n%uy)1^mkNvlD?~MzQq$rO;Lf5VdU9Q3z z^>)^wkjE%NV#@Rj?icTT(_nr1Mg4RRuFAN|tSQ}Fr@d|qc^4l7q$zBSSUK@!v_%_G zQt|!&LpbjQVvkc&r)-n(8y-;6n;EBWLILj}4URpFAu0)Kbp?fUAt)-R!XgXGyG5|5p@TG3rOwirHfR1EAIG<$~&TX|RpApJ3zrqLuUH-!dJan{no1b&eGFyD*!n zt9s3sQ=k>ijs76~NpPtBQ{`fb1%E{>nPnq`dcS08tP~jw-;YCi80LV+LroVS%KTCu zj5ZbuF8T3>SPC7riPI~rZ$$3js^27~Db>_~lkk6dg${8YvrB_-wDu$4l%D5r)Co#1 z1m-jlWd*t}mS+yJ?U=KCDMc424^Ix{7;cl8_y1f^A^PRu0E>;zA_meTRLCl<-rtot z()*(ZmLbmauI6*#17OFYxZ+L^r>ht*U53EJ)QFFUJ5DAL`g%UtRkc^W|4V!v6M5nQ zH-$RaG~`-Mn^;vBHW*eZBc;_CxyY=)khf%dQcT;}NYxD67MGHd5v_mw+K%x91^Cvs zf5mJ~oX{{X(57_xH2$4qg43vea&?hf$Ir4UPrOL2(z2=6>U@-=^v z+(%e4zn?mJi#Q+Kz|w+A1xkJe>k5|GEsrWaop<2##JX-_c(>>!185WjP_L%*&SCQ%g4-`A7Hat>X7%;v zV2~k96#811uQEm`vMYcHhz{dETY3KO(-S*KhZzl#)*MNL*!W)qZZH@tGdpZFe0yLc zG>oh0qw~pqti8XP5wxaey3Mpyx{&qDgkJT#208Oa*Jjjr2dL#C@(w3)*VD|q%lhIqft#wy5um6FG%Y`xW~Lsue| zM~$uDA!E$X^4>77w&0!L_=M#Nk7S1NsaC6KLs7AyOeno!;I5#`=edeqqda|1qY3Ul zZYKV-g2IjIx>*0;FANR@;jBVi^;ZEucNj|j@?fQ4`-~;uQh)urx@an;c4A7(~c6aHeb&OJpjm?#XiRz+MT52o*aF= zw!N}A5Z_UB#o?!quZ8~fxt!rn(9aI;C^nzjR=ckR?;QJ>Gj->X7+MoZCt}~s2pf+N zKLE09qUUX8wTHposgAlMk#*F&HnEafXp4okFZ*WiQ-$<0Lhk3r z@pi$3IV(UJ`NZpls82RIWtl;H_Xvecr7f;AN5zVqhcY#v8C2ta-rRh>9v7W+%Jb7A z91=Ui8VW%S-E|#+euWNhKcf*7v`k_3E(CX@`3ja98{mg>Zg0ry6;R{sN?d%hwGV)m zQ&k$yuB^t}R6#c*C&UBM?X4U`K}7*_6v`U zj%Ysyz;%jzBWC)(B-(s>{-?Q243x~G1(V%M z_j{$37Z%8RUQuz%tHOEgDynMnZaL6t9%9z*Uwa+dW01Bc86xF)@kJ>0-O}7oxzWsB zf7xHZ&%HaBc(B~$KgdukTa>>123)FDS5eruo#)7Q-?UG^AFrry+@G4!<~=sB;d^?w z;!{Sby2R-n;L^#)4^y(L>N#i0)_?nsC>fVb_B?1`k;ds*85SDm3R8E#w1O6TCadd- zlSLn5_mEVIIUn3`1kZ;py>G}JQZlNkaQHd^)85Vv0`@(zNR{b7FPm~-vy5cPc#Ty9FTgpT|g^;SoT$+{>%W~$KIz7 z?s6oe;su{I1~VIv`A0?>lV0q<-P3FQ4mP>)2CX69ry*7{J^+rKvG4FT>Q&ZCZwzoR z%17>6o$bCo0Nz&JCm%il#(6gE! z(|28(?+eFE8UvtL{Wg=q0cSU{W9;%JAs6@b~nV_&;b6$2bi27#weR#uD zlMW>7Rk@0~xIFqO1(xs+(yT>wX;-e=yp#Qf?t<@Hw3T2^`4YbSWU*pK=Hobv|#6M}M2 zgMEBVlSY;SeF1g4{?Ck+#dPYYkX+j42gzl2QC~gr?Wg|U-rAW-6f08EDsB(+w8;ME z7Eb<2`1;<+RTInlJgVnML9U)KHIB^UWiu#@lmGnMuKO*Wj6K z*bO^~+rg{DFmz;=1SQN{H@~dy*1i^~$^62cq2be}rcrmQWQ)y7zPud_xlG+sdYyhi zb_z^tlESW}?Mt$WlMGk3Su3$Au}j<)r~L8YmG_$`#BV@hCBzrR`GrGu4iO3IjuSvAjy}byuv#W8vX!RRQO)Q8D5crCN$G@GW&2Fh1aN+t}Mgm*B z!sqNm@kZZdo*;ANJ<%;AC$bvguJ3wW>(xEc^%$YNn75c9#7;#(?WD+@`e#irMxdQ3 zwZI_$$;S$FB$B710cvTW`&SQu4Y|G-=@?Se($ zl!giyF6yc|>yygg0An3D$q`if`y@l$V-&>ZMlF^2#=GY(pR-w8y|PG4Bg<8NO;M)H zftdZueBr|md!Y*Y0#9=6K?z1fo(;9 zhV)fgJZZ|W8jA;WBuSx`h*r9*o4K6gpQQai?8drP51>a5IvDMRRiI%t`?!V}!|Lw|HtdPdcU(X*f7Z8Rmy@HQ+N7;NiOprzCTPu#Aj(N!5`?7S1;o*;CD{ z&-QNOE|qSkcOzNgC#rrp{bc|CD<8pIeWDkcm+#f<{pBpQEx4pOBE{o~Q3m=@8CEkyZPTbG5StbcTFm!5mVl$GtNEqe0Q#ON3 z2w(4mY(14Fk0;KrH%CRPwcb+FX-b14=06~?Bin>KI#^}BtZ}5B82+SaXSI&u{ZisB zBCj_vr$XkpsPHHWh4?Rz@@LMUeVow^7Baki&2?{@r>yzOxp4c&!g;X2~h-Rj@IKSj-@2?1QI z;rXNiXdQ#S4~3iILfLr+$@>}k7p zmvTuz`cjbYCLz2zZXS=DsJkIBVwYo)f<#0U5N}g6(9u|jAhGQ%R>UHu=M}l6N~5za z8*lGPPIwM*)ifQKW#yPUK!_&qT8-=)?N#UIObW_SD;;H+eTM4{qGqAW6|1!JxYO=C zK0h9r&`MV1)oez0uda=x2u#@4wq>BiYQ8&gje+*o$Tb_xapZ*fx!8;?jx45=pME*I z{La(9yZwbQZ?0CF1F3K*u9p3tRZE2~$@14zJiLM+S>q0-8-X6hw>Q-R@99gQWg`?t z!>SCmz9urclFAv_v!m}ugj{T#9hcEj4B^i%{InTDV@2&B44*=;ExV(O4)szb9~k4z z?d<%VBML+4U{FeRg~W^MxH}AcwO-HnjcgtKNHcGWF7z7VM-*|7xh=VoxGOwQsQ1bc zbc{j$6|Vq$xpm8$BY;rlmXx>w1Re z&AGp$Z7C$rKB+Qo5z2Nnw3G%^(^L30+vBx1z`DdW3WDC(Is9CY-7gapP@b#QzNquQ z`?z3DQ5jp-FEb{={4~Ex;1F{gdci+vhu3OCcgsbTszBF6v{>=Pm-_is5aDvLlbey0 zEtTcz`}bDK_pUuX@H(+?3+R4uu!ot?^av-rBzYB#>trAoVmk+$Y=9?lrc;5sT!nacrgVGE> z&30GFT4D7@onNppU+5W2Kf|&rmD6-v-IyUE{F#A>DKV=0^sMaER?CeF%rC$%HWGVY z1TqKp{}dla$4V%dd7V@vzl#Fo;Ynw|dLnVQcgKX}wt<_;4(kt%$=%kb`96C40(xts z##*n3;Q|x(5Ds3BCHTQ!`wD*sp$y!j<%ubW_;G3Suo%*+6#w!H@2gLd4X+++%ZonegV-Q0u8WhGMR8#;R7I8K_4sKN}8E`GtL81 zERB@Oon)K;o>~G18!0RBCFRjZ2ky$!WgE>+L)>`^jlB*m_iayLt@*OhD9&br!E1(#9k_K zq>DGJ!s<$7Tm@kUS88`dim@@PE~0+(9<2Hug#>ZGMErR3LehkGbu}*ly)r)2&XPP` zo1dRfCvQ5lKCxc5^_{|poPj)?OFybgooB6|=4f(XB#<1oP|X%=Z}Id_a3^-MTVOQf zYRNUSHr3_4cd(<2k+`*+y;>ztNHh7lr8@?hzEP~U$px*+i{1tqPFoFq){R(1Bb;KK z^^V#Qpe!I3BcHCSsa>$+D@z>2G^g%^^}Yioh3`*UUug*%W+@Jsr?FVAD3WRRG2oYl zD4s%Y+o5x=^_$k@F{;W32bOpo{HV}HV3`XJ|LL<3R~e|!;ix+-Y^~d zOMS17Q?DdAp`I_6dG_!Mu}ffQUynk*x9FWyoWKC_D&{uH&JP{I9$H!j%6U^>$^E_T ztE6G;s$61?mgu!*mHl1$y?72o)>^lm93@w^=&XI@;YC+p2m* zSopkXYk$)=S7#A#B^C4W_G8DLSz{!V4S}iSPRX?r8@e(H!^WT0-;eIRQEX|JY*dpm z_KiaBCKuv3StMHv-Pg;T*Df#Yj5|MXecK+*7b9mDrDFM0f+70}@B&7ezy0#NP)5UN zjv;Rcd@OHtC+)bqyFs)*^zb}0j$uu&F&phh7O3IQdDiQSZ(5Ly42X~1vs}>~hzDr? zQ)P@v_i#9vVomR4`!n^Ooy`Ma%SW4z!nGa#b3zT0C6%^{e-UzT6|XHBJd&5d@zpbP zlv3X6H`h`h@MH-#QFLDJ`-HII`P46A_$#g|4M)tY`S%G_J}G(IvU=e}>gL*KfID_3 z8+%rbeazM1^zyjy=IohCRZ<_i#QHaJEQIvs+OpA6xTB)Kmv<5zj+A@HU$dIp3{Y@# z1_`f6;F$4AtDCu#F2nyO+|q|#qNL6dOS~yW1(B+^%(DVs^mFU}rfR{i*^CaM z=_fXg?`*!F=4zaF+arZcR|_nnzUuFeK0mwH(t<7xSQgvrd;T~bM(D2Qm5oR>2T>Y{ zrkW-ggnzuVw~0j|DB)E_Qxp%%)MvSR>*U*%>Z&a4^QI+KE) zYJ1oA(DyWIAw9`8{)`@6CsJ2U+CSN_nQQ72#`H;TPM4hGLusE3sz%;h@^|F&KG|zChbQUf(Lpnmv~Y4SNLDvFlg|1}2V6=+lWq7)N48(_pFzx^(+BI{ zry(tJI8Xd=6GEtp{E4a%OpTWoTn9|?B1A9y;4w^0N4d`0PR5&sR!`3_t*wdfr(&T6 z&Zu3rGL>=R1dd%7$7ROX6I*ob9eKBE{h~YPt4T@*3;Gs3<jc^!TM?w z_ViYfKVqz@wtC(cjP`=In2RfF1bMWdwnjvJss8}Fn^SWk6T=_4Khk$ZxRB1hvhJMB zWOEPaR;(}iNa=e_ZPhZ8S7kS?xLWfxk%=aY2M-FGai%iVk^VL4WnNz+C6djlyV95G zvu|lL`^u*svLV_-o6>l2&N^N8b}22sz}6ewT~@S+6=I&I$bP&_Mis$PHNb3p++Fj9 zy~~3-+jo;PH#g9Rh)6?R+(=tqSU|2&8Y?uOUA$`}kwbEZwj;OiMN`x7LtV}~q{Scx zZ`G*Esg3B;l6$4>Vcu_^x5E_k^M?Jjav4#LaizkmuZ{y%#YjuCHt{4P^nCj`7i3$6 zv(ArCz6{jLK}e7Yo-|)9q+Na29AyHza}{%SvVI)>>V7%HB(s!*@-uq^PvI*K@rj}9 zF?XJ?D;1V2L9TA1qgXnVeJm6=)Mra6=zggyKyL49tgSEQ8Fh@*6d{OV(=X8eg_*V6 z)9uVuwbv_;p3qKiNwdDYxK4q1bSQNhAm7_>=Y5I(o1?0Ge)STc=*J zt*4JzA~k_Ryv#+v>30a7U_wrNnOf9F5iVo1yzloUNb z1MWQ;!*c5DvxJDIz=QQvfk}P5{@b5KIQ0A-71fg$pGB7L76=?{GA~|P3u^>6pxD1? zjQ^?7U3*2H?Vrd(&RX)e3Cx+aRYK^+r|>QzMcE!{$b~-lw?>%MKo*0w`Kdth1E8;A z!EKnRk~IYP>u@t&*IEC-^|Y~2hc+eA+GriXHnh_2DE@`xak&T<;*{O~O<=j)0P;wN zU5!h{I15(ir2y0`E_fY-*lB;0-TT$smbLzE?;a5GxoAT|p8k}TWHRj&5iHvq0jOO< ziL4_6EToh6ryHn>^81U4_#GmKfEc|YUu(-Hl`!cPW~uP{CwcnOQ(zpq+82bggj#X0 zN=08^eQzv_B&JXP={?y7#6-mLZmpD(tkm_5H3Gw zztGze^PO_dQI29g`ibEa@vci>zZunr!11WnrkJS^go-ls)6>1vukQN{#uN2FP#Dc^ zfpfJy+FB;+em9%A(-jB)a!F72yCRh$acVObQTqiLM1-M+>$$&!2h3&{7COtxaDoQ+ zveQ5b0oIhA^&3Xg?e8O78yHFx5lKV?Jb7LxnAon$gaf}fUfA&gg80Qk@9ZTUp@tX^ zhHsk8r=``Fw#VKu#TMF=$jj3wy^&ZdRl1WK_M85|5NPQW$#s*n#eca` z^#xii7%G0WEWupe{}ShbvRQ!m(yYW$kOZw|!IY20>5vd|g&QUlcp}sBZd#A-^t{CN zsn=jH)OGvtSWLfZqD^|~8=gUg2P7C8vXVfU(>z^R7p9}P#u*2w9j+JS?<33hT@5Iw z@c)F;Zo6(<85V&I2>>}S&jX0bpKxqzS|l6rnA=Tm{=eKkvOk}<=g+Tco^-x= z1&aUW<11|0&rcy-bF`<`Gy~hSeKc*Mg`Exfy1XZpXWM+9>F1NXnF< z*XHi-7)UWFWYMl}K^YM9MC@{7`Hd&?Sl?csE%vQKWkO7LpmwQ6OGEH^wEy(U5?QM2 zPuFhn_HkAE@kG#beOprz2uC^MDG3$PXkU(W%w}v6>DyL(x*kI|{%`*80$`vWg;APp zLauge;WyDCqn{J6zbjQ);`Tnhz=XdTiq8}c4F%k>EFY7laqtW(!&qD?XRfHGb6!-| z?C5V%FJyG6jTe9sH(d=^&g1d5J8<+QSephYr(K=&QiPpYv0r1;jEbgJCQsX2a@sbz zWl;ICFRfA;=P9T!ADg?Z`}^zB2RPx$4EDwgZXA~rIFzY&!}3))Ajzk@!+AZG^1Nl( z=TKbTLy`7o?!uHtq0)6?;Y)1&i%!GfLPSrxjHF`<`(kreLUYF=OEXpAKtC005FrUE zv8B-rl7gQld&!PGnCrBe(;{$0_Tr>Ud&A`*tu5PAo0y80BL+y7DqH}eP2kmLN*HO! z4V)4xUKlyg@LGw~IlY`XO2SX9h*bFy9W0m~0WlhNW&T_m@O(o&goiO{7HfA8#sIy# znlS6eaD0Jep4efV;eLVV4Ze(vQQeq`Y+j8{n)Nus{-G3wZX|4ufw(PdAUov=<$3L2 z+uz@*2OB9ST(pu->;56PSQbq6Lt%a|{mZ$5z_-L!ftO!Lutlv0i>eEKMP75HI~{YS zM07C-6mfS*^0hQi&W}fODs|;OH~lStp1&)925Ai4!uiApD2x=9U9RB9uy4jZ;gGhE z`_0P7D|~f%qR79fZ(;aLL0N&=l9rdfmn#Iu>H|{^4pxoOQTDc@$47Z0E6oxr)fr*6PH%RUgJ1HlGndV9nsaci7--d)*-xh_HN`&V9 z9x4)`FTQ9}hEzq)OK^Mwo_C#Jx#~5qd*5`?0)Vh*@h#;Tx|LrSCEbQ_P1BKxsHR^Z zy%5Uq63ppOLwLozUqFW zgrc1b5}tA@d!mw?c8g;tfrW2_(sFH0(-K@`wMf>Y95(Ks-@J44-!b0|HaFPYQl2 z!YJUXkQ84Eh(6oV^PhO@GDJ{xt9uyV`Hq;vE_&)m9g&8;*~Gkew49YZN&Kq&ln=6?#QwnUpMKX|HQZV@qyl+7kgLJGFy5d6Cp~oU}CYheO3LTdzFzBTLBRuQm|-h zZMVYRS9Pn#nfi++q5K=A8FUL!B6%{`UUir-Ig*iA{|!Ys&c(tf@;mkIq5RdI^sC7Rl|WBbdhAb^Y?VCaOz(cR@_t(s zel~U!@0##ChG)1VwUps0E)-m$GS~(GETEq!Y|67z5S6y2QRKLpZawce4dt$k-#tO0 z{#|PI-N$DKl_ln5ifdq!odgAnZvn+Dd6CYsh6R!C`1?PF!*ZcG52M$> z!}|tg`s*w?OjpNq*16GsUrpp?IZ@#AbaHr9hWUMeubGymh*yR0(&>%~$yh<3(}zj+T)2pX_HN4@F@}f}aY;9bao-@` zTxt>vd8jwq0IQvceQrs^}bu4d3FGqi2pRdliFhVgqX+*RT{rh}i zefGB>Q}=t)b%?XsK^_egftBcAY0yiM4n|bFvY0C(O_ZnE9O$(?@np9uCx7f1IEty& zeE)EeuJS8sUEF1bdBBd>0KOWAZt^Y*P7vYLy9tqyC~UMbyXNJ{e>Xt)aD@N&g0ODE zUQl1Mg_A@1+mi6fzLvLsmcfq9mwDNi#gM12AqDYbMZWG8a*YZ0@b_^(3(FfR*SB`* zim8bfZ7d-OtLCC<%Ft)&z17oA`0PIE#``8HlER}!q;nr+++8%|2$eQdU>Q{Cx{@_r zwL_xAi>u`Omoa)bJLa}pDeU;?*kTioSYeCd%zU4I9f)R+KjV@AVCjj(h-4XZ zwO)pYPh0M63>-NKc@^YIY?-9$vzJEhK6X9fW!7(NKIKH0s`&I8B(k2d!Ep3p#V%?C zjpl7lQWN=i$tCX4Wk&XJXg4*sALg+l^%F_9@tttZPw9f6Ld{K_FuOldL;egS`3fLX}w5(H7GZaM(rVb zrlMq9`6biq8tVUpkqm@vG@GJEJAp*8G33$+XpsMmWsR?={ z1Ig$+o>neb)&ZWB#I4_-En@>>H+eq3!FxJP^qQ+PG`+_MTk4%b{N4E#UlZSLS$aCjsR#yqCe`90d;1L%vOg-_ z1zXdIKVV4Vtr+axw|Q5}u!?O`iG#_xf@1>zB!dK1_V}kw^=<-sgs+=;mkzRv2tV;x z+T(QAq;d(`Tq$aeJI1lX(UD1pTM5FGBkHX;i{V9ut%+p*rPu<@Ms>$x(;q$49aQZ` zWHEQW<8H3P<&CJ{VgyE*fcna57gyipG6<=Rx-AxHRc9d@3=xJsn1#-KF^{L2abu~0cH9i1N6K0(j^!hu$rtjrjS z7NKAcg-nBvmF%N<8QVE?-*Got5_FIu`jy9yQ1zN3f)BttK_kXe?lnTRZt7A~vTQE@ z&Yr%IyQ64wQn$09A@y8~xGIsLTTn3bpvtinb(a8QrBJakRxj5`%LWI0nQ{-Gew{x* z%QUuCf@E(`hV-mu!8|mqYc)GQ+kJ96H@8Q*sYd20QifrFCTvY^d0Cb~g7v_{tin)0 zIK-!$ic79->D$s~&gRenrkeze;c%;5L0KzeoMn#oMm&99k{!_B)hB2U@HP8LF(}L_ z%~G4v56DQ*x7o_JU@bZ!~DLE$|b$_a*qafL8;&CG7 idaC{%J*ulvj@~g5frAHQ{#Y1c(}F%VAr&47fB)IBf9FsD literal 0 HcmV?d00001 diff --git a/reference/UKultralight.pdb b/reference/UKultralight.pdb new file mode 100644 index 0000000000000000000000000000000000000000..9112b55a8bd3205784c60da7df8d1b59cd41ad93 GIT binary patch literal 26248 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 literal 0 HcmV?d00001 diff --git a/reference/alantrl.gpx b/reference/alantrl.gpx new file mode 100644 index 000000000..d7a618268 --- /dev/null +++ b/reference/alantrl.gpx @@ -0,0 +1,2448 @@ + + + + + + FH-DRIVE + + + -4542.400000 + + + 654.800000 + 0.000000 + + + 656.000000 + 0.527778 + + + 657.000000 + 0.000000 + + + 658.400000 + 0.000000 + + + 658.800000 + 0.000000 + + + 661.200000 + 0.000000 + + + 659.600000 + 0.000000 + + + 660.200000 + 0.000000 + + + 656.600000 + 0.000000 + + + 657.800000 + 0.000000 + + + 656.600000 + 0.000000 + + + 655.200000 + 0.000000 + + + 658.200000 + 0.000000 + + + 657.800000 + 0.000000 + + + 656.600000 + 0.000000 + + + 659.800000 + 0.000000 + + + 658.600000 + 0.000000 + + + 660.600000 + 0.000000 + + + 661.200000 + 0.000000 + + + 660.200000 + 0.000000 + + + 657.400000 + 0.000000 + + + 656.000000 + 0.000000 + + + 657.200000 + 0.000000 + + + 656.400000 + 0.000000 + + + 656.400000 + 0.000000 + + + 658.400000 + 0.000000 + + + 657.600000 + 0.000000 + + + 661.600000 + 0.000000 + + + 659.200000 + 0.000000 + + + 654.800000 + 2.000000 + + + 650.200000 + 2.388889 + + + 645.800000 + 1.888889 + + + 642.600000 + 2.861111 + + + 645.000000 + 3.194444 + + + 647.400000 + 4.083333 + + + 647.800000 + 3.805556 + + + 646.600000 + 2.833333 + + + 642.200000 + 3.055556 + + + 637.800000 + 2.722222 + + + 631.000000 + 2.944444 + + + 625.000000 + 2.666667 + + + 621.800000 + 3.333333 + + + 618.200000 + 0.000000 + + + 615.600000 + 0.888889 + + + + + 30-12-05 + PIRATENBUCH +1 + + + -4542.400000 + + + 653.000000 + 1.111111 + + + 651.000000 + 1.250000 + + + 654.200000 + 1.138889 + + + 650.200000 + 0.000000 + + + 648.200000 + 0.000000 + + + 651.200000 + 0.000000 + + + 649.800000 + 0.861111 + + + 644.400000 + 1.500000 + + + 645.000000 + 1.388889 + + + 647.000000 + 0.972222 + + + 645.600000 + 0.805556 + + + 643.400000 + 1.138889 + + + 639.800000 + 0.861111 + + + 639.600000 + 1.055556 + + + 640.400000 + 0.666667 + + + 647.200000 + 0.000000 + + + 649.400000 + 0.722222 + + + 648.800000 + 1.722222 + + + 646.200000 + 0.722222 + + + 642.800000 + 0.555556 + + + 639.000000 + 0.000000 + + + 635.400000 + 0.777778 + + + 631.400000 + 0.972222 + + + 625.400000 + 1.111111 + + + 623.600000 + 1.055556 + + + 624.600000 + 0.000000 + + + 624.400000 + 0.000000 + + + 625.600000 + 0.000000 + + + 625.200000 + 0.000000 + + + 623.800000 + 0.694444 + + + 626.000000 + 1.027778 + + + 625.800000 + 1.333333 + + + 629.000000 + 1.250000 + + + 628.200000 + 1.194444 + + + 626.000000 + 0.000000 + + + 625.800000 + 0.777778 + + + 624.800000 + 1.250000 + + + 622.600000 + 0.555556 + + + 621.400000 + 0.694444 + + + 623.200000 + 0.666667 + + + 623.000000 + 0.916667 + + + 621.200000 + 1.194444 + + + 619.400000 + 0.944444 + + + 621.000000 + 0.694444 + + + 621.000000 + 0.000000 + + + 622.200000 + 1.583333 + + + 622.200000 + 1.583333 + + + 625.400000 + 0.722222 + + + 618.400000 + 0.638889 + + + 617.200000 + 0.777778 + + + 615.200000 + 0.888889 + + + 616.200000 + 1.111111 + + + 616.000000 + 0.777778 + + + 613.600000 + 0.000000 + + + 609.200000 + 0.944444 + + + 607.600000 + 1.277778 + + + 604.800000 + 0.805556 + + + 606.400000 + 1.000000 + + + 609.600000 + 0.833333 + + + 614.200000 + 0.750000 + + + 618.800000 + 1.000000 + + + 619.400000 + 1.055556 + + + 621.800000 + 1.138889 + + + 623.800000 + 0.000000 + + + 625.800000 + 0.000000 + + + 629.600000 + 1.194444 + + + 628.600000 + 0.555556 + + + 624.200000 + 0.916667 + + + 625.600000 + 0.000000 + + + 623.800000 + 0.583333 + + + 607.400000 + 0.000000 + + + 597.800000 + 0.000000 + + + 613.200000 + 0.000000 + + + 621.400000 + 0.777778 + + + 618.600000 + 0.861111 + + + 618.200000 + 0.805556 + + + 615.800000 + 0.638889 + + + 615.600000 + 0.833333 + + + 614.800000 + 0.000000 + + + 623.000000 + 1.111111 + + + 630.000000 + 0.000000 + + + 626.600000 + 0.000000 + + + 624.400000 + 0.000000 + + + 627.400000 + 0.000000 + + + 627.000000 + 1.027778 + + + 625.200000 + 1.083333 + + + 624.400000 + 0.972222 + + + 624.600000 + 0.000000 + + + 623.400000 + 0.000000 + + + 621.800000 + 0.000000 + + + 618.200000 + 0.000000 + + + 614.800000 + 0.000000 + + + 618.000000 + 0.000000 + + + 621.200000 + 1.250000 + + + 624.000000 + 1.305556 + + + 623.800000 + 0.000000 + + + 626.600000 + 1.305556 + + + 627.600000 + 1.333333 + + + 626.200000 + 0.916667 + + + 626.000000 + 1.388889 + + + 628.800000 + 1.277778 + + + 629.200000 + 1.222222 + + + 629.200000 + 1.055556 + + + 628.200000 + 1.055556 + + + 627.400000 + 1.194444 + + + 626.600000 + 0.750000 + + + 626.800000 + 1.361111 + + + 626.600000 + 1.194444 + + + 628.000000 + 1.361111 + + + 629.600000 + 1.305556 + + + 629.600000 + 1.333333 + + + 629.400000 + 1.333333 + + + 627.600000 + 1.333333 + + + 627.200000 + 1.361111 + + + 626.400000 + 1.333333 + + + 625.600000 + 1.361111 + + + 625.200000 + 1.111111 + + + 621.600000 + 0.000000 + + + 613.200000 + 0.000000 + + + 618.200000 + 0.000000 + + + 623.000000 + 0.000000 + + + 619.600000 + 0.000000 + + + 606.200000 + 1.444444 + + + 596.000000 + 1.277778 + + + 595.400000 + 1.111111 + + + 596.000000 + 0.000000 + + + 591.200000 + 1.388889 + + + 572.800000 + 0.000000 + + + 555.200000 + 0.611111 + + + 550.800000 + 0.861111 + + + 542.800000 + 0.805556 + + + 545.000000 + 0.777778 + + + 532.200000 + 0.694444 + + + 521.400000 + 0.000000 + + + 513.600000 + 1.055556 + + + 504.800000 + 1.166667 + + + 503.400000 + 1.555556 + + + 501.000000 + 1.388889 + + + 501.000000 + 1.388889 + + + 495.400000 + 1.500000 + + + 487.000000 + 1.611111 + + + 481.800000 + 1.472222 + + + 475.200000 + 1.500000 + + + 475.200000 + 1.222222 + + + 467.800000 + 1.194444 + + + 458.400000 + 1.305556 + + + 457.000000 + 1.305556 + + + 448.600000 + 1.333333 + + + 442.800000 + 1.333333 + + + 433.400000 + 1.111111 + + + 429.400000 + 0.000000 + + + 424.800000 + 1.138889 + + + 411.600000 + 1.055556 + + + 404.000000 + 1.166667 + + + 395.800000 + 1.416667 + + + 390.400000 + 1.388889 + + + 386.400000 + 1.361111 + + + 385.400000 + 1.305556 + + + 391.400000 + 1.388889 + + + 377.800000 + 1.527778 + + + 370.600000 + 1.333333 + + + 371.000000 + 1.333333 + + + 363.800000 + 1.361111 + + + 356.200000 + 1.444444 + + + 349.000000 + 1.388889 + + + 344.800000 + 1.305556 + + + 341.800000 + 0.777778 + + + 336.000000 + 0.916667 + + + 320.600000 + 1.250000 + + + 310.800000 + 1.083333 + + + 299.200000 + 1.055556 + + + 290.400000 + 1.166667 + + + 284.800000 + 0.000000 + + + 283.600000 + 0.000000 + + + 283.400000 + 0.000000 + + + 281.200000 + 0.000000 + + + 276.400000 + 0.000000 + + + 277.800000 + 0.000000 + + + 292.000000 + 0.000000 + + + 278.600000 + 1.416667 + + + 270.800000 + 0.000000 + + + 252.200000 + 0.805556 + + + 246.000000 + 0.000000 + + + 223.400000 + 0.916667 + + + 209.200000 + 0.555556 + + + 177.000000 + 0.000000 + + + 193.800000 + 0.638889 + + + 181.400000 + 0.000000 + + + 175.000000 + 0.000000 + + + 179.400000 + 0.000000 + + + 168.000000 + 0.000000 + + + 155.400000 + 0.000000 + + + 124.800000 + 0.694444 + + + 126.400000 + 0.000000 + + + 123.800000 + 0.000000 + + + 125.200000 + 0.000000 + + + 90.800000 + 1.000000 + + + 101.600000 + 0.000000 + + + 109.600000 + 1.055556 + + + 73.800000 + 0.000000 + + + 66.200000 + 0.000000 + + + 56.200000 + 0.000000 + + + 44.800000 + 0.888889 + + + 44.200000 + 0.000000 + + + 22.800000 + 1.638889 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 24.400000 + 0.000000 + + + 117.800000 + 0.000000 + + + 54.000000 + 0.000000 + + + 41.000000 + 0.916667 + + + 45.800000 + 0.000000 + + + 40.800000 + 0.000000 + + + 45.600000 + 0.000000 + + + 43.400000 + 0.916667 + + + 49.800000 + 0.000000 + + + 69.800000 + 0.750000 + + + 101.800000 + 0.694444 + + + 115.200000 + 0.694444 + + + 125.600000 + 0.000000 + + + 148.800000 + 0.555556 + + + 164.800000 + 0.722222 + + + 177.000000 + 0.888889 + + + 173.200000 + 0.000000 + + + 166.200000 + 1.166667 + + + 144.400000 + 1.361111 + + + 130.000000 + 1.222222 + + + 131.600000 + 1.194444 + + + 112.600000 + 1.111111 + + + 101.200000 + 0.638889 + + + 90.200000 + 0.805556 + + + 72.600000 + 0.805556 + + + 59.400000 + 1.138889 + + + 41.000000 + 0.000000 + + + 14.800000 + 0.000000 + + + 8.800000 + 2.305556 + + + + + 1-1-06 + TORRE TIME +2 + + + -4542.400000 + + + 653.400000 + 0.000000 + + + 657.600000 + 0.000000 + + + 654.400000 + 0.000000 + + + 653.600000 + 0.000000 + + + 647.400000 + 1.111111 + + + 646.400000 + 1.361111 + + + 643.400000 + 1.388889 + + + 636.800000 + 0.833333 + + + 621.800000 + 1.361111 + + + 619.800000 + 1.444444 + + + 618.800000 + 0.638889 + + + 618.600000 + 1.055556 + + + 615.200000 + 1.333333 + + + 615.000000 + 0.722222 + + + 624.000000 + 0.611111 + + + 623.400000 + 0.861111 + + + 640.000000 + 1.194444 + + + 644.400000 + 0.944444 + + + 652.000000 + 0.833333 + + + 656.800000 + 0.000000 + + + 655.400000 + 0.805556 + + + 665.200000 + 0.888889 + + + 677.800000 + 1.138889 + + + 684.400000 + 1.333333 + + + 692.200000 + 1.166667 + + + 696.200000 + 1.416667 + + + 701.600000 + 1.194444 + + + 712.400000 + 1.027778 + + + 717.400000 + 1.361111 + + + 718.400000 + 1.444444 + + + 725.800000 + 0.694444 + + + 752.000000 + 0.527778 + + + 745.200000 + 0.000000 + + + 735.000000 + 1.388889 + + + 727.600000 + 1.222222 + + + 726.400000 + 1.444444 + + + 710.600000 + 0.500000 + + + 727.400000 + 1.111111 + + + 738.800000 + 0.000000 + + + 735.600000 + 0.000000 + + + 738.800000 + 1.027778 + + + 748.200000 + 1.305556 + + + 754.800000 + 1.388889 + + + 767.000000 + 0.972222 + + + 774.000000 + 1.194444 + + + 780.600000 + 0.694444 + + + 802.400000 + 0.000000 + + + 802.400000 + 0.000000 + + + 814.200000 + 1.055556 + + + 817.400000 + 1.000000 + + + 826.600000 + 0.833333 + + + 835.000000 + 1.277778 + + + 841.400000 + 1.305556 + + + 846.200000 + 2.250000 + + + 855.600000 + 1.416667 + + + 857.600000 + 1.055556 + + + 862.800000 + 1.222222 + + + 871.000000 + 1.166667 + + + 883.800000 + 0.916667 + + + 890.400000 + 0.722222 + + + 902.800000 + 0.944444 + + + 906.600000 + 1.333333 + + + 918.600000 + 1.000000 + + + 928.200000 + 0.916667 + + + 942.800000 + 1.000000 + + + 947.800000 + 0.972222 + + + 955.200000 + 0.916667 + + + 970.800000 + 0.916667 + + + 981.800000 + 0.861111 + + + 988.800000 + 0.944444 + + + 1001.400000 + 1.527778 + + + 1009.600000 + 1.083333 + + + 1013.200000 + 1.944444 + + + 1017.200000 + 0.638889 + + + 1010.600000 + 1.027778 + + + 1006.000000 + 1.472222 + + + 1006.000000 + 1.333333 + + + 1009.200000 + 1.166667 + + + 1002.400000 + 1.305556 + + + 996.200000 + 0.583333 + + + 992.000000 + 1.416667 + + + 978.400000 + 1.333333 + + + 974.800000 + 1.666667 + + + 974.800000 + 0.944444 + + + 974.400000 + 1.277778 + + + 971.000000 + 1.527778 + + + 969.400000 + 1.250000 + + + 966.200000 + 0.000000 + + + 971.400000 + 0.000000 + + + 967.600000 + 0.000000 + + + 964.800000 + 0.666667 + + + 952.800000 + 1.222222 + + + 1045.400000 + 0.000000 + + + 952.800000 + 0.000000 + + + 829.000000 + 0.000000 + + + 892.200000 + 0.000000 + + + 1031.000000 + 0.000000 + + + 938.400000 + 0.000000 + + + 868.800000 + 0.000000 + + + 955.000000 + 0.000000 + + + 1050.800000 + 0.000000 + + + 948.800000 + 0.000000 + + + 1025.600000 + 0.000000 + + + 957.200000 + 0.000000 + + + 952.800000 + 0.000000 + + + 942.000000 + 0.000000 + + + 943.800000 + 1.083333 + + + 938.800000 + 1.472222 + + + 939.200000 + 0.000000 + + + 945.000000 + 1.805556 + + + 950.000000 + 0.777778 + + + 961.200000 + 1.333333 + + + 968.800000 + 1.250000 + + + 971.200000 + 1.500000 + + + 967.400000 + 0.972222 + + + 966.600000 + 1.250000 + + + 961.400000 + 0.722222 + + + 968.800000 + 0.750000 + + + 968.000000 + 0.638889 + + + 967.600000 + 0.000000 + + + 967.600000 + 0.000000 + + + 937.800000 + 0.000000 + + + 1009.200000 + 1.500000 + + + 1010.000000 + 0.888889 + + + 1009.800000 + 0.000000 + + + 996.800000 + 1.388889 + + + 1000.600000 + 1.444444 + + + 1013.000000 + 1.555556 + + + 1013.400000 + 1.388889 + + + 1018.200000 + 0.555556 + + + 1017.600000 + 0.000000 + + + 1029.000000 + 0.888889 + + + 1028.600000 + 0.638889 + + + 1028.600000 + 1.722222 + + + 1034.400000 + 1.250000 + + + 1034.400000 + 1.583333 + + + 1034.200000 + 1.500000 + + + 1037.000000 + 1.583333 + + + 1032.000000 + 1.527778 + + + 1024.800000 + 1.472222 + + + 1025.000000 + 1.416667 + + + 1022.600000 + 1.000000 + + + 1023.000000 + 1.222222 + + + 1039.800000 + 0.833333 + + + 1056.600000 + 0.805556 + + + 1061.800000 + 0.000000 + + + 1065.200000 + 0.000000 + + + 1056.200000 + 0.000000 + + + 1060.600000 + 0.000000 + + + 1057.800000 + 0.000000 + + + 1058.600000 + 0.000000 + + + 1047.800000 + 0.666667 + + + 1045.200000 + 0.527778 + + + 1049.600000 + 0.000000 + + + 1030.600000 + 1.416667 + + + 1027.600000 + 1.638889 + + + 1033.800000 + 1.250000 + + + 1035.600000 + 1.277778 + + + 1030.400000 + 1.361111 + + + 1029.600000 + 0.861111 + + + 1029.400000 + 1.111111 + + + 1029.600000 + 1.222222 + + + 1030.200000 + 1.361111 + + + 1024.200000 + 1.416667 + + + 1016.600000 + 1.138889 + + + 1016.600000 + 1.555556 + + + 1016.200000 + 0.000000 + + + 1020.800000 + 0.805556 + + + 1019.400000 + 1.000000 + + + 1019.400000 + 1.416667 + + + 1018.600000 + 0.000000 + + + 1018.600000 + 0.000000 + + + 1018.600000 + 0.000000 + + + 1000.200000 + 1.527778 + + + 1004.000000 + 1.305556 + + + 1005.600000 + 1.166667 + + + 1004.800000 + 0.805556 + + + 987.400000 + 1.111111 + + + 977.200000 + 0.000000 + + + 977.600000 + 1.138889 + + + 962.400000 + 1.361111 + + + 962.600000 + 1.416667 + + + 962.600000 + 1.333333 + + + 966.800000 + 1.555556 + + + 968.600000 + 1.166667 + + + 962.200000 + 1.000000 + + + 954.400000 + 0.666667 + + + 941.200000 + 0.944444 + + + 946.000000 + 1.055556 + + + 933.800000 + 1.194444 + + + 933.600000 + 1.194444 + + + 937.600000 + 1.638889 + + + 930.800000 + 1.361111 + + + 933.200000 + 0.000000 + + + 937.000000 + 0.000000 + + + 943.400000 + 0.000000 + + + 928.800000 + 0.611111 + + + 944.800000 + 0.000000 + + + 959.000000 + 0.000000 + + + 957.000000 + 0.638889 + + + 963.800000 + 0.000000 + + + 967.800000 + 1.472222 + + + 961.400000 + 1.416667 + + + 960.800000 + 1.527778 + + + 964.000000 + 1.472222 + + + 964.800000 + 0.944444 + + + 967.800000 + 1.166667 + + + 975.400000 + 1.277778 + + + 971.000000 + 1.361111 + + + 961.800000 + 1.500000 + + + 958.400000 + 1.666667 + + + 952.800000 + 1.000000 + + + 945.400000 + 1.083333 + + + 940.800000 + 1.250000 + + + 938.800000 + 1.555556 + + + 911.000000 + 1.166667 + + + 918.800000 + 1.361111 + + + 920.400000 + 1.388889 + + + 914.800000 + 1.388889 + + + 911.200000 + 1.333333 + + + 900.200000 + 1.500000 + + + 896.000000 + 1.472222 + + + 891.600000 + 1.388889 + + + 884.400000 + 0.000000 + + + 882.200000 + 1.388889 + + + 883.000000 + 1.472222 + + + 879.600000 + 1.388889 + + + 880.000000 + 1.388889 + + + 883.600000 + 0.000000 + + + 885.200000 + 1.416667 + + + 870.200000 + 1.250000 + + + 860.400000 + 1.472222 + + + 863.200000 + 1.277778 + + + 856.400000 + 1.305556 + + + 843.400000 + 1.555556 + + + 839.000000 + 1.527778 + + + 833.200000 + 1.083333 + + + 828.600000 + 1.416667 + + + 828.600000 + 1.611111 + + + 827.400000 + 1.194444 + + + 820.600000 + 1.361111 + + + 806.600000 + 1.500000 + + + 810.800000 + 1.333333 + + + 806.200000 + 1.055556 + + + 805.000000 + 1.500000 + + + 802.200000 + 1.138889 + + + 797.200000 + 1.416667 + + + 793.600000 + 1.416667 + + + 785.800000 + 1.361111 + + + 777.400000 + 1.305556 + + + 778.000000 + 1.305556 + + + 776.200000 + 1.361111 + + + 780.200000 + 1.666667 + + + 785.400000 + 1.111111 + + + 782.200000 + 1.472222 + + + 773.600000 + 1.444444 + + + 772.000000 + 1.500000 + + + 777.800000 + 1.472222 + + + 759.600000 + 1.444444 + + + 753.600000 + 1.388889 + + + 754.800000 + 1.444444 + + + 742.600000 + 1.555556 + + + 735.800000 + 1.277778 + + + 727.000000 + 1.277778 + + + 722.600000 + 1.333333 + + + 719.400000 + 1.194444 + + + 710.400000 + 1.500000 + + + 688.800000 + 1.166667 + + + 677.400000 + 1.166667 + + + 671.600000 + 0.861111 + + + 664.200000 + 1.027778 + + + 655.200000 + 1.138889 + + + 648.600000 + 1.055556 + + + 622.600000 + 0.000000 + + + 615.600000 + 1.055556 + + + 620.000000 + 0.000000 + + + 618.000000 + 1.555556 + + + 620.800000 + 1.277778 + + + 624.400000 + 1.083333 + + + 626.200000 + 0.972222 + + + 634.400000 + 1.000000 + + + + + 2-1-06 + TAZACORTE +3 + + + -4542.400000 + + + 518.600000 + 0.000000 + + + 525.800000 + 0.000000 + + + 530.400000 + 0.000000 + + + 530.800000 + 1.111111 + + + 507.000000 + 1.361111 + + + 509.200000 + 1.361111 + + + 507.800000 + 2.638889 + + + 495.200000 + 1.083333 + + + 492.200000 + 1.333333 + + + 486.200000 + 1.194444 + + + 478.800000 + 1.638889 + + + 464.400000 + 0.944444 + + + 454.200000 + 1.027778 + + + 457.800000 + 0.000000 + + + 432.400000 + 0.777778 + + + 415.000000 + 0.000000 + + + 406.000000 + 1.250000 + + + 392.600000 + 1.083333 + + + 390.200000 + 1.416667 + + + 377.000000 + 1.277778 + + + 368.800000 + 1.138889 + + + 351.400000 + 1.416667 + + + 341.000000 + 1.222222 + + + 331.400000 + 1.083333 + + + 328.000000 + 1.500000 + + + 327.800000 + 0.000000 + + + + diff --git a/reference/alantrl.trl b/reference/alantrl.trl new file mode 100644 index 0000000000000000000000000000000000000000..c0f94ab2c6b1d4797f4dc7bf9e56a7cc50936eaf GIT binary patch literal 266240 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 G2L1v7=x*Hr literal 0 HcmV?d00001 diff --git a/reference/alanwpr.gpx b/reference/alanwpr.gpx new file mode 100644 index 000000000..321d05986 --- /dev/null +++ b/reference/alanwpr.gpx @@ -0,0 +1,381 @@ + + + + + + + Home + Sweet_Home + Sweet_Home + + + + Airport + Santa_Cruz + Santa_Cruz + + + + GAS001 + Barlovento + Barlovento + + + + GAS002 + Puntagorda + Puntagorda + + + + Police + Puntagorda + Puntagorda + + + + SMrkt01 + Santa_Cruz + Santa_Cruz + + + + SMrkt02 + El_Paso + El_Paso + + + + PARK01 + SmallParking + SmallParking + + + + PARK02 + Tilos_Trail + Tilos_Trail + + + + PARK03 + Las_Tricia + Las_Tricia + + + + Barloven + Barlovento + Barlovento + + + + Bejenado + Bejenado + Bejenado + + + + Cumbreci + Cumbrecita + Cumbrecita + + + + Durazner + Duraznero + Duraznero + + + + El_Pilar + El_Pilar + El_Pilar + + + + El_Rodeo + El_Rodeo + El_Rodeo + + + + FaroFuen + Fuencaliente + Fuencaliente + + + + F.Olen + Fuente_Olen + Fuente_Olen + + + + HoyoNegr + Hoyo_Negro + Hoyo_Negro + + + + Muchacho + Rq.Muchachos + Rq.Muchachos + + + + M.Birigo + M_Birigoyo + M_Birigoyo + + + + S.Isidro + San_Isidro + San_Isidro + + + + S.Maria + Santa_Maria + Santa_Maria + + + + Tazacort + Tazacorte + Tazacorte + + + + T.d.Time + Tor_del_Time + Tor_del_Time + + + + Zarza + La_Zarza + La_Zarza + + + + Zarzita + La_Zarzita + La_Zarzita + + + + SRVCENTR + Servicecentr + Servicecentr + + + + TGR130 + Trailhead + Trailhead + + + + TGR131 + Trailhead + Trailhead + + + + TPRLP14 + Trailhead + Trailhead + + + + TPRLP15 + Trailhead + Trailhead + + + + TPRLP16 + Trailhead + Trailhead + + + + TSLEP103 + Trailhead + Trailhead + + + + TSLEP107 + Trailhead + Trailhead + + + + TSLEP107 + Trailhead + Trailhead + + + + TSLFU110 + Trailhead + Trailhead + + + + TSLFU111 + Trailhead + Trailhead + + + + TSLSAS30 + Trailhead + Trailhead + + + + TSLTJ71 + Trailhead + Trailhead + + + + TSLTJ71a + Trailhead + Trailhead + + + + GC7CF + Geocache + Geocache + + + + GCN1TQ + Geocache + Geocache + + + + GCNXY8 + Geocache + Geocache + + + + GCHT8C + Geocache + Geocache + + + + GCNQXK + Geocache + Geocache + + + + GCD098 + Geocache + Geocache + + + + GCM6N0 + Geocache + Geocache + + + + GC405B + Geocache + Geocache + + + + GCD096 + Geocache + Geocache + + + + GCNXKV + Geocache + Geocache + + + + GCNXMD + Geocache + Geocache + + + + GCHND9 + Geocache + Geocache + + + + GC405C + Geocache + Geocache + + + + FH-HAUS + + + + FH-DRIVE + + + + GCHND9-1 + + + + GCHND9-2 + + + + GCHND9-3 + + + + PL VETA + PLAYA VETA + PLAYA VETA + + + GCHND9 + + + GCHND9 + Geocache + Geocache + + + + GCHND9-1 + + + + GCHND9-2 + + + + GCHND9-3 + + + diff --git a/reference/alanwpr.wpr b/reference/alanwpr.wpr new file mode 100644 index 0000000000000000000000000000000000000000..ecada54705d2a6fa77d550e8e87c4cb2c5e5be37 GIT binary patch literal 65536 zcmeI)TWl0n9LMp01*}356fY=32dE%Qm)+jW#oBJ$E%w6FU1~w&I&3FpW!u4N3sMq| zF^GvKnn1uyLZUICCcYRFA54g7OnmY|0x>=rO|8y&gYynGf&8=hNm~nW)UfoTV#&Rm3eZjl*(;#yUdpbQYH)K4p}6N;GU&vr(QlsP>bsPi^n&z z#r2MCnJrgkwB<8Nb3_NH?NFub{m~N4C7XLY{duH@%zQp+I(u`&gO}F1-on@{Ih{v3 zm$yeUX~)dvjlXohu?@52stu#d^i#QPPUq{cbiJ>l!Q7PF)YbQ^(0cpUhjP|)*04EX zw_LsY^H>~ly%nMP#>a+sJ61L~bsg1yC!((R)aGEl)-lH%AGVySt1ol7+Vz%o2Xnq# zE^j(hSHIsgnk(&?k?XYwEL(GvS3fszgX^6Ljj!Ew?DjEh*#DC?^Eury)^}B|ci@>| zz4pkqyfthXes0vtO#X1C&h@^p59T`TgLaQK==j%+f1?w5N5^-lE12sZ%kD9=d+grl zBU85{f3A1Ep_))G(vov>gLZeOa6PE?TD0D|(0o&ots}Vs$JYIqDcl*x30=1Z?ZJAf zNVng_U}ab0@df0?OU>qPV~mAqk2C4ld;D#2XqW)bbWt&a+aK)x8mI2Yh3Tc&^*$~-mYY< zCXhR-^(I2jgrgHcuaCFu+9xbKtLJX=opV;_@mgp- z67il`dV4UpNXPfVj$pr<>)+WB%+1mLcP8YQhG73FiA>HT-YnE&8)7HtiN7D#OQAhsq&qS7W6@e8dQq!tAXDOH3P?24;hcDqfNZKO~I zTP0ZPB`p$#-~}&~OB%q&f^rds6^t}!6hlmmXfT!lLQq5ktk3^VX1@@jADaC7&YW}R z%*-=;0-om$(qGGc<=+0w&8c2FQ-9Nf@kluKjO2CoPaZsMH1fSo_m+E?FEyt&>c8vs z_h5ZILQD5?*C*h8u0HRjnp0;~&(PoWL_8F%qgT%f*UPtuRMa;nLixpk0X}{pHx76^ z^!TLSq)0<@OC$i%(@2cvk2IF`)<43Y$QUunx=+J^+)1RbYb92}*?5z&*mtpio!}3WO!#W?>=7 z5fUIii2Y(9Fz#qb7a8xJ-KM8k%AB8)>Az>uw6K(?gg)FdF z$OK;q9$@CrYaadW!rx%4a0YA;E`iO0UA09R%vB!?!@;M*2*BFh3U&%M44THeN(tbh zW#B7e3iw8-00)ICSD6bAs1gBmwi)9so}-c!UUE&Zy2?thPfc$-d<4E!r5i9XTinlt z9aP+YvbX4?(yOK)K(}xdtP_3*?+E?iP2nWy5YB?-!g;VnNPz`{ub}vGAp_J2S>P#Q zD5w^OgU5ssV5X4onu%iTfEiAV1CF*)RJ zCrIb6UKLxKu<$>*dq_=|y9b00E+==k`s8jIl_J45#wcMi6>`@E$lZL9&RwP|mOD?l zR_^-sb`Nv;uYzr6a#u`++}#eY%pH3;izc?EC5YXaB2#;We*m-n7hwKR16JfBNav2q z5bi@-1K?}ng1gEpSIH)8WZ7hmY^W@#9U4@|b3+C;5s)%FVXl%*o^IKsv&|}R+RWvo z^+k7|S6t-{Kx{3Wz_Q74WZ7gGwgK2zmQBWNyM>{$e=M8d1G4!G=n^cO?+Vw-<_qd$ z*(4@cW^)KzH>9R)Fk2V~W(c`pmXPO~ESpcNGLURma@9h0wg9#Y7D=*cNhF)I=(Ad| z{Jt;LP+{FefW2X0x6GrmTWA2xm}L`KHkmrhCbMeUq_bs{$y~uz9M0AUv{K>Di@-Kv zKKMkibASo2rShR*2g@44-lD^yO|UU@_!t%m_BsuMO+rL?g!_brGB8)LW35K8$*dL% zX__gFau^9%lpJ@JEz>+zZluB^t_SJGWf&LPB+GY4*xe3e0E=4ydW2g5@0A01Q#+anQ3jRug8kg{C73>uPI1Vv zZB7E7ehx4&JI5HaoowFM$qD(!-8oBsgZ1@#L6 literal 0 HcmV?d00001 diff --git a/reference/an1-an1.ref b/reference/an1-an1.ref new file mode 100644 index 0000000000000000000000000000000000000000..27ccc13efaf6b366b761189b2f637c27f948b1ac GIT binary patch literal 3556 zcmbW(OGs2<6bJBcZe!-;Cy|`kM-iH2OS?_M|v;Q?f2SIEshB2n1>w;yO}0S+Oa_#4WMHI zc06cfn(^v<)QBSrIzGXU(GzR);S)zA=vagu_fImNn$_#FQ5;R6<1_3SKE`yjs2#Q9 zh=GnG>}c<08mrRz@QY(J==cIV?%iUVo7Vl9Z(I&!eX&Bvjg zx*v_=a6m^Mc08(PN@TR7NgU0fqX0V`hiPe*BPNa(&@uk7@Vt0U^6~B8^I^F!JM$Y3 CR+51L literal 0 HcmV?d00001 diff --git a/reference/an1-in.ref b/reference/an1-in.ref new file mode 100644 index 000000000..a374b9984 --- /dev/null +++ b/reference/an1-in.ref @@ -0,0 +1,26 @@ +41.11111, -85.16351, +41.11048, -85.16341, +41.10986, -85.16348, +41.10908, -85.16357, +41.11138, -85.16216, +41.11058, -85.16223, +41.10990, -85.16239, +41.10923, -85.16255, +41.11138, -85.16130, +41.11068, -85.16127, +41.11000, -85.16139, +41.10920, -85.16155, +41.11142, -85.16002, +41.11075, -85.16030, +41.11005, -85.16050, +41.10964, -85.16062, +41.10824, -85.16373, +41.10821, -85.16300, +41.10817, -85.16216, +41.10846, -85.16123, +41.10768, -85.16409, +41.10756, -85.16300, +41.10768, -85.16210, +41.10778, -85.16123, +41.10684, -85.16383, +41.10681, -85.16287, diff --git a/reference/an1-line-out.ref b/reference/an1-line-out.ref new file mode 100644 index 0000000000000000000000000000000000000000..95182803e6e5889cd9f89b057d4577a3668d1232 GIT binary patch literal 1848 zcmaLXZA?#590%~*)4xOyBt%0|UbyGn@d67?Y?U@;`o2j`*{l~b50j_;EBYI?dO?|o zYE5IJJQSl@X0|q?NHtS7sWwj|+AIo5&cAWL``fO2x8FUVeRt0Jo%7;G2yOgv|5M%6 zH&{CqAGko%0@c`Ez0SurUdL4R7$32?YdaL2^E55SAyJYSkoDJ}@+BtkarKj(beYOu zXVF6kC62_==al;v)75zrXF~t)niC4K6-~G-0ocYio?V)_3mrl)*sBfk- z>=LOBt`523>SMKZotht1Wo_sFb1RuU?`u&R-FsOgIggI4b9MJUSNp$kb*Zo6GXGz{ zRe8vMuJ5#Cx2sFjtUcgkz-BOa+CG&Y^fvJEho5=h!!`r{ee`+d@~8BOmw~SP^d;qQ zwX~)jTtZ**G*Gmc_Eb(zqtiSLyo;i5xf`espeMT-@Ov}K>~H&+#Ev_3%cw->aXMVN zB$KxPl&D=tcYl`%2&9*NlX%uP(Om!iki>>6y6me&^CoL2e34iynO7=ri?sGhwSL4r z=7p-CqjTw*>U_&*Tl?2%i3%U)wwDr%-};*U$32la+e#-iN;t04rKcp8?y`1Mu|)f3 z=C5{26fC3L5+#a9Cz$&M>FWQ`L_eP*ajKlo@RnFrKtCQ3h)t(^J_z`w(Cc3dtVpEi zbPG75>5Nu^)sb}YBLOX(p4ceR;YEiw2)uHmPh1nI8SyduZ>Sc?9Hx^_3$*pphl>R| zTj~TAAnE)^W3*jxW-2H=B+=pd&P$-nCKX uQFL~!4o8@^#Tp&`q0H+dbgUeUhvaZyi~PwkB(znXbb=p8p1zvQcsX literal 0 HcmV?d00001 diff --git a/reference/an1-out.ref b/reference/an1-out.ref new file mode 100644 index 0000000000000000000000000000000000000000..fb40144402ecf89bce435a5c230a3749374949c0 GIT binary patch literal 326 zcmY$@WdH*v1|}fQ2xfDX_lGQa`ZJf2;oSfK|3!de%nXel0_s2p7X!oQ$!Rm{XCARP zWe7>l%S$aTPEAz^PEIUK%}Y-$Qt&9vD^YMxOwLG!8U{8IiC|@LEXqvGc_3$(q`v;L z;2uqe02ZdNMlcmX3sAs+D32LPLtJ->VO7YkY}Pzf*9oGzPMaaPBtI`TsVF}`Ti3lP QwXzt*rM{a$p~k=f0R4MEp#T5? literal 0 HcmV?d00001 diff --git a/reference/arcdist_arc.txt b/reference/arcdist_arc.txt new file mode 100644 index 000000000..c79e1866f --- /dev/null +++ b/reference/arcdist_arc.txt @@ -0,0 +1,115 @@ +41.150064468 -85.166207433 +41.150064468 -85.165371895 +41.149034500 -85.165157318 +41.147832870 -85.164771080 +41.146631241 -85.164384842 +41.144270897 -85.163655281 +41.141953468 -85.162882805 +41.139550209 -85.162281990 +41.137833595 -85.161852837 +41.136546135 -85.161681175 +41.132812500 -85.160608292 +41.132340431 -85.160479546 +41.131739616 -85.160050392 +41.131138802 -85.159664154 +41.130237579 -85.158977509 +41.129765511 -85.158634186 +41.129636765 -85.158548355 +41.129379272 -85.158419609 +41.129207611 -85.158333778 +41.128950119 -85.158162117 +41.128821373 -85.158033371 +41.128478050 -85.157775879 +41.126074791 -85.155844688 +41.125044823 -85.154857635 +41.122341156 -85.152668953 +41.119766235 -85.150566101 +41.118135452 -85.149278641 +41.117362976 -85.148591995 +41.114530563 -85.146059990 +41.112856865 -85.144772530 +41.112256050 -85.144085884 +41.111955643 -85.143871307 +41.110539436 -85.142970085 +41.108264923 -85.141167641 +41.107234955 -85.140352249 +41.106162071 -85.139665604 +41.105132103 -85.138678551 +41.104745865 -85.138163567 +41.104145050 -85.138163567 +41.103029251 -85.138163567 +41.102042198 -85.138077736 +41.101140976 -85.138077736 +41.099338531 -85.137948990 +41.099038124 -85.137948990 +41.098566055 -85.137391090 +41.096849442 -85.136961937 +41.096334457 -85.136575699 +41.094231606 -85.135588646 +41.093759537 -85.134687424 +41.093158722 -85.134387016 +41.092128754 -85.134258270 +41.091527939 -85.134172440 +41.091141701 -85.134172440 +41.090455055 -85.134172440 +41.089339256 -85.134172440 +41.088523865 -85.134301186 +41.088137627 -85.134387016 +41.087751389 -85.134558678 +41.086850166 -85.135159492 +41.085863113 -85.135459900 +41.084446907 -85.135760307 +41.083846092 -85.135459900 +41.083159447 -85.135374069 +41.082558632 -85.135159492 +41.082043648 -85.135073662 +41.081056595 -85.134773254 +41.079940796 -85.134472847 +41.079039574 -85.134172440 +41.077966690 -85.133872032 +41.076936722 -85.133571625 +41.075863838 -85.133271217 +41.075134277 -85.132970810 +41.075134277 -85.133271217 +41.074147224 -85.133271217 +41.073632240 -85.133271217 +41.073160172 -85.133271217 +41.071443558 -85.133271217 +41.070327759 -85.133228302 +41.069641113 -85.133185387 +41.069340706 -85.133056641 +41.068739891 -85.133056641 +41.068353653 -85.133056641 +41.067967415 -85.133013725 +41.067452431 -85.132970810 +41.066765785 -85.132884979 +41.066336632 -85.132884979 +41.065864563 -85.132884979 +41.065349579 -85.132884979 +41.064362526 -85.132884979 +41.063246727 -85.132884979 +41.062345505 -85.132756233 +41.061229706 -85.132756233 +41.060628891 -85.132756233 +41.059641838 -85.132670403 +41.058654785 -85.132584572 +41.058139801 -85.132584572 +41.057753563 -85.132541656 +41.057066917 -85.132455826 +41.056551933 -85.132455826 +41.055951118 -85.132455826 +41.055564880 -85.132455826 +41.054663658 -85.132369995 +41.053762436 -85.132284164 +41.053247452 -85.132284164 +41.052260399 -85.132284164 +41.051745415 -85.132284164 +41.050758362 -85.132155418 +41.049942970 -85.132069588 +41.049127579 -85.132069588 +41.047539711 -85.131983757 +41.046037674 -85.131855011 +41.045737267 -85.131983757 +41.045050621 -85.133056641 +41.044921875 -85.133056641 +41.044343591 -85.132979512 diff --git a/reference/arcdist_input.txt b/reference/arcdist_input.txt new file mode 100644 index 000000000..e3f361027 --- /dev/null +++ b/reference/arcdist_input.txt @@ -0,0 +1,103 @@ + +BEGIN SYMBOL +41.14703, -85.11092, N.E.R.D. by Enos Shenk Unknown Cache (3/3) +41.13940, -85.10142, Fallen Timbers by TeamMJ Traditional Cache (2/2) +41.14415, -85.14415, Historic Iron Bridges by Genoist (1/2 of TeamSJ1) Locationless (Reverse) Cache (1/1) +41.12890, -85.11163, Mastadon Trek 2 by Genoist and Dogvetusa Traditional Cache (2/2) +41.16413, -85.14688, NYC Trail by VistaAL Traditional Cache (1/1.5) +41.15900, -85.15418, Craftily Concealed Containers by Warm Fuzzies Multi-Cache (4/2) +41.12210, -85.11097, Land of Lost Auto Parts by Genoist and The Zymurgist Traditional Cache (1/5) +41.17732, -85.15117, The Farm by AParks1569 Traditional Cache (1.5/1.5) +41.10757, -85.13087, Swonderful by Genoist and The Zymurgist Traditional Cache (2/5) +41.12733, -85.06728, Dr. Mengerson I Preserve by Genoist Traditional Cache (2/2) +41.10417, -85.15167, Clue by Warm Fuzzies Multi-Cache (3.5/2) +41.10823, -85.16212, Son of Pez by Enos Shenk Traditional Cache (1.5/1.5) +41.09278, -85.14073, Urbana #3: Dodgy Deals by Enos Shenk Traditional Cache (2.5/1.5) +41.09258, -85.09258, Secret Squirrels by Enos Shenk & Panic! Unknown Cache (4/1) +41.08748, -85.13762, A King's Ransom by Team ABC and The GeoStars Team Traditional Cache (1.5/1) +41.08427, -85.13597, Urbana #4: The City She Loves Me by Enos Shenk & Athena Traditional Cache (3.5/2) +41.08582, -85.07230, Caribbean Cache by Genoist and Dogvetusa Traditional Cache (3/2) +41.08190, -85.17180, Earthling Vector Luna- 2nd Phase by Earthling and Heavenbound Traditional Cache (1/1.5) +41.08400, -85.05387, Earthling Vector Sol by Earthling & Heavenbound Traditional Cache (1.5/1.5) +41.20673, -85.03985, The Sarsaparilla Cache by Cashconnect Traditional Cache (2/1.5) +41.06353, -85.13400, Sky High by Enos Shenk Virtual Cache (1/3) +41.09880, -85.21725, We Support Our Troops by Genoist and The Zymurgist Traditional Cache (2/2.5) +41.06950, -85.19750, Shortwave by Warm Fuzzies Unknown Cache (4/2.5) +41.06255, -85.04757, Starfall by Enos Shenk Traditional Cache (2/2.5) +41.07482, -85.01957, Fly Like an Eagle by Team SJ1 Traditional Cache (2/2) +41.04714, -85.16617, Perfectly Perplexing Puzzles by Warm Fuzzies Multi-Cache (5/3.5) +41.07197, -85.01863, Arrow Haven (2/4) by Genoist Traditional Cache (2/2.5) +41.07183, -85.01850, Heat Death (3/4) by Genoist Traditional Cache (2/3) +41.06827, -85.01655, Abbadon by Genoist Traditional Cache (1.5/4) +41.01503, -85.13290, Earthling Vector Pluto by Earthling & Heavenbound Traditional Cache (1/1.5) +41.26535, -84.98950, Outstanding In Its Field Cache by kwbach Traditional Cache (2/2) +41.00470, -85.05742, Earthling Vector Perelandra by Earthling & Heavenbound Multi-Cache (4/1.5) +41.04247, -85.27570, KWAANTINAKAANI by Northmill Jo-Jo Beans and E-Bone Letterbox Hybrid (2/1) +41.01760, -85.25190, Earthling Vector Terra by Earthling & Heavenbound Traditional Cache (1.5/2.5) +40.97610, -85.22277, 47520 Feet by kidCraZy Traditional Cache (1/1.5) +41.35740, -85.05117, A.C.D. Cache by 1MARKYMARK1 Traditional Cache (2/2.5) +41.03592, -84.80323, EV-Castor & Pollux by Starhenge Multi-Cache (1/1.5) +41.30855, -84.82960, Earthling Vector Malacandra by Earthling and Heavenbound Traditional Cache (1/1.5) +41.33727, -85.39282, One Lost Ten Found by The GeoStars Team and Team ABC Traditional Cache (3/5) +41.33552, -85.40885, The Leprechaun's Pot of Gold by Pete and Maureen Traditional Cache (1/1) +41.08543, -84.72823, Payne Train by rlong3 (Long Clan) Traditional Cache (1.5/1) +41.44473, -85.24797, Straight Flush by The GeoStars Team and Team ABC Multi-Cache (4/5) +40.89088, -85.47038, 'Clare' up There by Zig & Zag Traditional Cache (2/3) +40.82507, -85.35552, Jeanette's Journey by kidCraZy Multi-Cache (2.5/1.5) +40.84245, -85.42245, Pine Sol by Indiana Herring Traditional Cache (1.5/2) +40.84662, -85.43382, Kil--So--Quah by Good Dog Traditional Cache (1.5/2) +40.80862, -85.35608, Stuck in the middle by The Hoosier River Rats Traditional Cache (2/2.5) +40.80768, -85.36637, Rock Creek by The Hoosier River Rats Traditional Cache (2/2) +40.87892, -85.50570, Sunken Treasure by Smokey and Family Traditional Cache (2/1) +40.83560, -85.45415, Clue Two by geoprime Traditional Cache (2/3) +41.53267, -84.94377, Robb Hidden Canyon by VM's Traditional Cache (2/3) +41.53553, -84.93188, Fish Creek Trail by VM's Multi-Cache (3.5/1) +40.87942, -85.54058, All Locked Up by Zig & Zag Traditional Cache (1/1) +40.71773, -85.10702, OUABACHE CACHE by ZoneRanger Traditional Cache (1/1) +41.34498, -85.68462, Wy-Tri Cache by capt zigzag & echoes Traditional Cache (2/2) +41.54878, -85.45370, Delt Church Dino Cache by GeoStars Traditional Cache (1.5/2.5) +41.56537, -85.46163, Clearspring Cache by capt zigzag & echoes Traditional Cache (1.5/1.5) +41.56282, -85.46893, Ace-in-the-Hole by The GeoStars Team and Team ABC Multi-Cache (2/2) +41.62350, -85.33873, Geocache by Maple Wood Nature Center Traditional Cache (1/1) +41.20898, -84.45685, Aqueduct by coinhound Traditional Cache (2/1.5) +41.66538, -85.17465, Gannon Cache by capt zigzag & echoes Traditional Cache (2/1.5) +41.22390, -84.42585, 5 Mile Creek Access by coinhound Traditional Cache (1/1) +40.76567, -85.59953, Missing Dental Work by Indiana Herring Traditional Cache (2/3.5) +40.75487, -85.59022, Salamonie Reservoir Trail Cache by Indy Diver Traditional Cache (1/1.5) +40.78918, -85.65105, Dead End Cache by JollyBGood Traditional Cache (1.5/1.5) +41.34360, -84.44365, Oxbow lake AKA ( wabit twacks) by coinhound Traditional Cache (1/1.5) +40.81153, -85.68533, In 'Hominy' with nature by Zig & Zag Traditional Cache (1/2.5) +40.80997, -85.68650, Myrna's Treasure by Myrna's Mountaineers Traditional Cache (2/1) +40.82988, -85.70725, Just Hanging Around by Zig & Zag Traditional Cache (4.5/3.5) +40.63288, -85.36448, 13 graves and A Ghost by RedNeck Tracking INC. Traditional Cache (1/1) +40.61557, -84.94355, 1861 Covered Cache by RedNeck Tracking INC. Traditional Cache (2/1) +40.61378, -84.94383, Trailsend 1860 by RedNeck Tracking INC. Traditional Cache (1/1) +41.69980, -85.03385, Nature's Back Yard by Cat E Wampus Traditional Cache (2/1.5) +41.69567, -85.30143, Center Field by therealmongo Traditional Cache (2/2.5) +41.70473, -84.99397, Back to our Beloved Sport by Max's Pets with Birddog Traditional Cache (2/2) +41.69323, -85.33213, Pigion River Cache by Bonnie & Clyde Traditional Cache (2.5/2) +41.71252, -85.02377, Artesian by Good Dog Traditional Cache (1.5/1.5) +41.71708, -85.02897, P.S.P. by The Wolfe Clan Traditional Cache (1/1.5) +41.71720, -85.01957, Earthling Vector Mercury by Earthling & Heavenbound Traditional Cache (1.5/2) +41.71535, -84.98552, Marsh Lake High Ground by VirtualMoore Traditional Cache (3/2) +41.55555, -84.57783, Bible Park Stash by DwFlatP8 and Luckyfriend Traditional Cache (1.5/1.5) +41.23113, -84.36397, Taylor Made by Team WolfPack Traditional Cache (1/1.5) +41.71960, -84.96467, The Crane Waterfall by VM's Traditional Cache (2/2.5) +40.63232, -85.47248, Serenity by Indiana and Marion Traditional Cache (1.5/1) +41.24542, -84.35613, "Tanks" For The Memories by Team WolfPack Traditional Cache (1/1) +41.29958, -84.36582, Lets Make A "Diehl" by Team WolfPack Traditional Cache (1/1) +41.72573, -84.96353, 80/90 Westbound Cache by Good Dog Traditional Cache (1/1) +41.28945, -84.35925, Confluence Cache by Team WolfPack Multi-Cache (2/1) +41.71007, -85.37105, Lane Lake Cache by capt zigzag and echoes Traditional Cache (2/2) +41.69660, -84.80602, tristate marker by Hillsdale Historical Society Virtual Cache (1/1) +41.51000, -85.78042, School Daze by Lobo Valiente Virtual Cache (1/1) +41.55730, -84.50957, Cemetery Hill by DwFlatP8 and Luckyfriend Traditional Cache (1.5/1.5) +40.53373, -85.14770, Balbec Cabin Keychains by RedNeck Tracking INC. Traditional Cache (1/1) +40.93718, -84.33907, Big Green by tex4711 Traditional Cache (1.5/1) +41.38972, -85.89556, Island Cache by Bonnie & Clyde Traditional Cache (1.5/1) +41.69122, -84.67567, glacial trailing by Mark Robinette Traditional Cache (2.5/2) +40.51967, -84.98795, Liberty Cache by RedNeck Tracking INC. Traditional Cache (1/1) +41.51870, -85.81747, Five Medals by kam Traditional Cache (2/2) +41.01977, -84.28587, The Book Worm by Team Ace Traditional Cache (1/1) +41.29335, -84.28538, Bushwacker by Panther2 Traditional Cache (2/3) +END diff --git a/reference/arcdist_output.txt b/reference/arcdist_output.txt new file mode 100644 index 000000000..693773cbc --- /dev/null +++ b/reference/arcdist_output.txt @@ -0,0 +1,11 @@ +BEGIN SYMBOL +41.14415, -85.14415, Historic Iron Bridges by Genoist (1/2 of TeamSJ1) Locationless (Reverse) Cache (1/1) +41.15900, -85.15418, Craftily Concealed Containers by Warm Fuzzies Multi-Cache (4/2) +41.10757, -85.13087, Swonderful by Genoist and The Zymurgist Traditional Cache (2/5) +41.10417, -85.15167, Clue by Warm Fuzzies Multi-Cache (3.5/2) +41.10823, -85.16212, Son of Pez by Enos Shenk Traditional Cache (1.5/1.5) +41.09278, -85.14073, Urbana #3: Dodgy Deals by Enos Shenk Traditional Cache (2.5/1.5) +41.08748, -85.13762, A King's Ransom by Team ABC and The GeoStars Team Traditional Cache (1.5/1) +41.08427, -85.13597, Urbana #4: The City She Loves Me by Enos Shenk & Athena Traditional Cache (3.5/2) +41.06353, -85.13400, Sky High by Enos Shenk Virtual Cache (1/3) +END diff --git a/reference/cet/cet-sample.cp1250.txt b/reference/cet/cet-sample.cp1250.txt new file mode 100644 index 000000000..1645bac37 --- /dev/null +++ b/reference/cet/cet-sample.cp1250.txt @@ -0,0 +1,17 @@ +Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink +new 01 Hohndorf 50.738297 12.683029 -99999999.00 255 1 +new 0x9E ž - latin small letter z with caron 50.497971 13.027725 -99999999.00 255 1 +new 0xC9 É - latin capital letter e with circumflex 50.497971 13.027725 -99999999.00 255 1 +new 0xF0 ð - latin small letter eth (icelandic) 50.497971 13.027725 -99999999.00 255 1 +new CS Ovládací Prohlížení lokální síte 50.514406 13.638634 -99999999.00 255 1 +new DA Tåning netværkssøgning áâãäåæéë 56.011734 9.847870 -99999999.00 255 1 +new DE Himmelmühle äöüÄÖÜß 50.625865 13.060611 -99999999.00 255 1 +new EO Trasercado de la loka ret 50.495281 13.027645 -99999999.00 255 1 +new ES Matalascañas Navegación Táliga 37.007446 -6.558838 -99999999.00 255 1 +new FR Boissière-École Contrôle réseau Mâle 48.679047 1.652069 -99999999.00 255 1 +new HR Pregledavanje lokalne mreže 50.477937 12.510391 -99999999.00 255 1 +new HU Hõgyész Vezérlõközpont Hálózat 46.491394 18.424072 -99999999.00 255 1 +new IS Borgarfjörður 65.522461 -13.823547 -99999999.00 255 1 +new SK Ovládacie centrum 50.724214 13.524871 -99999999.00 255 1 +new X1 žðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× 50.497971 13.027725 -99999999.00 255 1 +new X2 žðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× 50.497971 13.027725 -99999999.00 255 1 diff --git a/reference/cet/cet-sample.gdb b/reference/cet/cet-sample.gdb new file mode 100644 index 0000000000000000000000000000000000000000..dab0140a03fc048a3bea5f80a5befab97a746b8f GIT binary patch literal 1919 zcmbuAO>7%Q6vy9INRR`nRB`HQAdzsymO93*h%Z*`q&T4TDr*Vjh5+y3Niii~6uGb%Fv4g}MW@cw+ z-*4aly?HZbpJy331OVd#2o7T(9x^%AxXkJBZqXzpLL%Yt2^fjS!qHgdZJ45kX{#t1 zhx52S9Uj3xXnS1^z{{$hq=^d zGFs3b+NSb=s!LWhGJ;<|0R6>9HzAwoQ{n%F-fpA!xy#Ylkj}WErlzyu1F%zwEqmDH zbU*0MZySSI_xb>wDT%5^*``X)N-HNe7r41egq5!f9PLeqcX&rS2EAFFB+H!TbV@?3 zJWTwT%FQu1k;iFze9T|)yMK{;@u%0J0x!Z$&D71TN=)vQ)@0tcpJtm2)s;u9wYB<2 zPkfWN7j+W_pVv2~&V^v;v#XPstGZ!uVeIAvSIMf{PvPRWef*dY1OY`i>}-NRYXwyebg1 z=iP(Km#;xZRUl#Mwym#Aer$Vn4=dI@K4; zVzt3}S$hf2N}d&5qa|w2p{gjUFgY)U%he;?W zgAkt#2a>1WZz<3$PAwgRQg!9@_-0`{w7>`qk)pkER~tLhTJYKj?p-w9EeXQoXYL!}_m(eY + + + + + + 01 + Hohndorf + Hohndorf + City (Small) + + + + 0x9E + ž - latin small letter z with caron + ž - latin small letter z with caron + City (Small) + + + + 0xC9 + É - latin capital letter e with circumflex + É - latin capital letter e with circumflex + City (Small) + + + + 0xF0 + ð - latin small letter eth (icelandic) + ð - latin small letter eth (icelandic) + City (Small) + + + + CS + Ovládací, Prohlížení lokální síte + Ovládací, Prohlížení lokální síte + Waypoint + + + + DA + TÃ¥ning, netværkssøgning, áâãäåæéë + TÃ¥ning, netværkssøgning, áâãäåæéë + Waypoint + + + + DE + Himmelmühle, ä,ö,ü,Ä,Ö,Ü,ß + Himmelmühle, ä,ö,ü,Ä,Ö,Ü,ß + Waypoint + + + + EO + Trasercado de la loka ret + Trasercado de la loka ret + Waypoint + + + + ES + Matalascañas, Navegación, Táliga + Matalascañas, Navegación, Táliga + Waypoint + + + + FR + Boissière-École, Contrôle, réseau, Mâle + Boissière-École, Contrôle, réseau, Mâle + Waypoint + + + + HR + Pregledavanje lokalne mreže + Pregledavanje lokalne mreže + Waypoint + + + + HU + Hõgyész, Vezérlõközpont, Hálózat + Hõgyész, Vezérlõközpont, Hálózat + City (Small) + + + + IS + Borgarfjörður + Borgarfjörður + Waypoint + + + + SK + Ovládacie centrum + Ovládacie centrum + Waypoint + + + + X1 + žðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× + žðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× + Block, Blue + + + + X2 + žðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× + žðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× + Block, Blue + + diff --git a/reference/cet/cet-sample.latin1.txt b/reference/cet/cet-sample.latin1.txt new file mode 100644 index 000000000..477ca12be --- /dev/null +++ b/reference/cet/cet-sample.latin1.txt @@ -0,0 +1,17 @@ +Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink +new 01 Hohndorf 50.738297 12.683029 -99999999.00 255 1 +new 0x9E z - latin small letter z with caron 50.497971 13.027725 -99999999.00 255 1 +new 0xC9 É - latin capital letter e with circumflex 50.497971 13.027725 -99999999.00 255 1 +new 0xF0 ð - latin small letter eth (icelandic) 50.497971 13.027725 -99999999.00 255 1 +new CS Ovládací Prohlízení lokální síte 50.514406 13.638634 -99999999.00 255 1 +new DA Tåning netværkssøgning áâãäåæéë 56.011734 9.847870 -99999999.00 255 1 +new DE Himmelmühle äöüÄÖÜß 50.625865 13.060611 -99999999.00 255 1 +new EO Trasercado de la loka ret 50.495281 13.027645 -99999999.00 255 1 +new ES Matalascañas Navegación Táliga 37.007446 -6.558838 -99999999.00 255 1 +new FR Boissière-École Contrôle réseau Mâle 48.679047 1.652069 -99999999.00 255 1 +new HR Pregledavanje lokalne mreze 50.477937 12.510391 -99999999.00 255 1 +new HU Hõgyész Vezérlõközpont Hálózat 46.491394 18.424072 -99999999.00 255 1 +new IS Borgarfjörður 65.522461 -13.823547 -99999999.00 255 1 +new SK Ovládacie centrum 50.724214 13.524871 -99999999.00 255 1 +new X1 zðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× 50.497971 13.027725 -99999999.00 255 1 +new X2 zðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× 50.497971 13.027725 -99999999.00 255 1 diff --git a/reference/cet/cet-sample.latin2.txt b/reference/cet/cet-sample.latin2.txt new file mode 100644 index 000000000..0db84c227 --- /dev/null +++ b/reference/cet/cet-sample.latin2.txt @@ -0,0 +1,17 @@ +Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink +new 01 Hohndorf 50.738297 12.683029 -99999999.00 255 1 +new 0x9E ¾ - latin small letter z with caron 50.497971 13.027725 -99999999.00 255 1 +new 0xC9 É - latin capital letter e with circumflex 50.497971 13.027725 -99999999.00 255 1 +new 0xF0 ð - latin small letter eth (icelandic) 50.497971 13.027725 -99999999.00 255 1 +new CS Ovládací Prohlí¾ení lokální síte 50.514406 13.638634 -99999999.00 255 1 +new DA Tåning netværkssøgning áâãäåæéë 56.011734 9.847870 -99999999.00 255 1 +new DE Himmelmühle äöüÄÖÜß 50.625865 13.060611 -99999999.00 255 1 +new EO Trasercado de la loka ret 50.495281 13.027645 -99999999.00 255 1 +new ES Matalascañas Navegación Táliga 37.007446 -6.558838 -99999999.00 255 1 +new FR Boissière-École Contrôle réseau Mâle 48.679047 1.652069 -99999999.00 255 1 +new HR Pregledavanje lokalne mre¾e 50.477937 12.510391 -99999999.00 255 1 +new HU Hõgyész Vezérlõközpont Hálózat 46.491394 18.424072 -99999999.00 255 1 +new IS Borgarfjörður 65.522461 -13.823547 -99999999.00 255 1 +new SK Ovládacie centrum 50.724214 13.524871 -99999999.00 255 1 +new X1 ¾ðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× 50.497971 13.027725 -99999999.00 255 1 +new X2 ¾ðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× 50.497971 13.027725 -99999999.00 255 1 diff --git a/reference/cet/cet-sample.macroman.txt b/reference/cet/cet-sample.macroman.txt new file mode 100644 index 000000000..b41688788 --- /dev/null +++ b/reference/cet/cet-sample.macroman.txt @@ -0,0 +1,17 @@ +Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink +new 01 Hohndorf 50.738297 12.683029 -99999999.00 255 1 +new 0x9E $ - latin small letter z with caron 50.497971 13.027725 -99999999.00 255 1 +new 0xC9 ƒ - latin capital letter e with circumflex 50.497971 13.027725 -99999999.00 255 1 +new 0xF0 ð - latin small letter eth (icelandic) 50.497971 13.027725 -99999999.00 255 1 +new CS Ovl‡dac’ Prohl’$en’ lok‡ln’ s’te 50.514406 13.638634 -99999999.00 255 1 +new DA TŒning netv¾rkss¿gning ‡‰‹ŠŒ¾Ž‘ 56.011734 9.847870 -99999999.00 255 1 +new DE HimmelmŸhle ŠšŸ€…†§ 50.625865 13.060611 -99999999.00 255 1 +new EO Trasercado de la loka ret 50.495281 13.027645 -99999999.00 255 1 +new ES Matalasca–as Navegaci—n T‡liga 37.007446 -6.558838 -99999999.00 255 1 +new FR Boissire-ƒcole Contr™le rŽseau M‰le 48.679047 1.652069 -99999999.00 255 1 +new HR Pregledavanje lokalne mre$e 50.477937 12.510391 -99999999.00 255 1 +new HU H›gyŽsz VezŽrl›kšzpont H‡l—zat 46.491394 18.424072 -99999999.00 255 1 +new IS Borgarfjšrður 65.522461 -13.823547 -99999999.00 255 1 +new SK Ovl‡dacie centrum 50.724214 13.524871 -99999999.00 255 1 +new X1 $ðƒŽËˆéôå‰æë”€Šè‘…š†Ÿ®¾Œ¯¿‚„–²³½ƒ× 50.497971 13.027725 -99999999.00 255 1 +new X2 $ðƒŽËˆéôå‰æë”€Šè‘…š†Ÿ®¾Œ¯¿‚„–²³½ƒ× 50.497971 13.027725 -99999999.00 255 1 diff --git a/reference/cetus.gpu b/reference/cetus.gpu new file mode 100644 index 000000000..c701f7040 --- /dev/null +++ b/reference/cetus.gpu @@ -0,0 +1,9 @@ +GC1A37 3605.441N 08640.773W 0000000m The Troll by a182pilot & Famil a +GC1C2B 3559.776N 08637.207W 0000000m Dive Bomber by JoGPS & family a +GC25A9 3602.309N 08638.917W 0000000m FOSTER by JoGPS & Family a +GC2723 3606.731N 08644.506W 0000000m Logan Lighthouse by JoGps & Fa a +GC2B71 3603.845N 08647.431W 0000000m Ganier Cache by Susy1313 a +GC309F 3605.266N 08648.584W 0000000m Shy's Hill by FireFighterEng33 a +GC317A 3603.450N 08653.520W 0000000m GittyUp by JoGPS / Warner Park a +GC317D 3604.968N 08652.037W 0000000m Inlighting by JoGPS / Warner P a +GCEBB 3558.322N 08708.082W 0000000m Mountain Bike Heaven by susy13 a diff --git a/reference/cetus.pdb b/reference/cetus.pdb new file mode 100644 index 0000000000000000000000000000000000000000..a15ff2f51d04be3b3ceecc3a7498c04afe271057 GIT binary patch literal 1095 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%0A^M>ugv^`%+^!3~SUdCGUf=Y@$iQ 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 + + Navigation Objects + true + + 34.867273 N 120.589158 W + 98208.414698 + true + true + + + + {76e5356a-d5fc-4437-8649-026416c2b185} + {d5dbd16f-eeba-4f61-b38f-582b584e5db3} + {9816402a-51a6-4fd5-8c08-b680d23d7911} + {427ed2ff-bdbb-4d77-b859-1f1eff10c961} + {0ead9569-64f0-4fb8-9545-4fa3191bbab0} + {fbe5b26d-b111-4208-ac70-f22b169d9c3e} + {68cfe23d-2ebf-4075-9726-f743659c7df5} + {50740d73-e743-4197-a6a0-29ad3114107a} + {26ae0ba0-a73e-4600-b51a-546d7099c809} + {b7266cd5-817b-4674-862e-490230a2f925} + + + 5.0 kn + + + 5.0 kn + + + 5.0 kn + + + 5.0 kn + + + 5.0 kn + + + 5.0 kn + + + 5.0 kn + + + 5.0 kn + + + 5.0 kn + + + 5.0 kn + + true + 39.06 NM + 20050516T070000 + first-waypoint + Into The Bay + + + 37.763290 N 122.282580 W + Home + 0.05 NM + 0 NM + -51,-21 + 0,24 + SFBALBAY + + + 37.751613 N 122.339028 W + 0.05 NM + 0 NM + -58,4 + 0,24 + SFBAY001 + + + 37.817420 N 122.394305 W + 0.05 NM + 0 NM + -9,-19 + 0,24 + SFBAY002 + + + 37.819339 N 122.478302 W + 0.05 NM + 0 NM + -53,-21 + 0,24 + SFGGBRDG + + + 37.773033 N 122.605838 W + 0.05 NM + 0 NM + -92,-13 + 0,24 + SFCHNL01 + + + 37.518860 N 122.529914 W + 0.05 NM + 0 NM + -98,-4 + 0,24 + HMCOLREF + + + 37.482348 N 122.507704 W + 0.05 NM + 0 NM + -77,1 + 0,24 + HMPILL01 + + + 37.476448 N 122.475800 W + 0.05 NM + 0 NM + 13,-1 + 0,24 + HMPILL02 + + + 37.495102 N 122.483927 W + 0.05 NM + 0 NM + -91,-4 + 0,24 + HMPILL03 + + + 37.229349 N 122.441589 W + 0.05 NM + 0 NM + -95,-4 + 0,24 + PESCDR01 + + + 37.183397 N 122.411904 W + 0.05 NM + 0 NM + -90,-2 + 0,24 + PIGEON01 + + + 37.090736 N 122.348775 W + 0.05 NM + 0 NM + -89,0 + 0,24 + ANONUV01 + + + 36.929502 N 122.113725 W + 0.05 NM + 0 NM + -51,4 + 0,24 + SCRUZ01 + + + 36.934235 N 122.022130 W + 0.05 NM + 0 NM + 22,-8 + 0,24 + SCRUZ02 + + + 36.960666 N 122.024734 W + 0.05 NM + 0 NM + 22,-9 + 0,24 + SCRUZENT + + + 37.475062 N 122.488531 W + 0.05 NM + 0 NM + -44,5 + 0,24 + HMPILLPT + + + 36.581344 N 121.995411 W + 0.05 NM + 0 NM + -95,-7 + 0,24 + CYPRSSPT + + + 36.301110 N 121.919097 W + 0.05 NM + 0 NM + -67,-3 + 0,24 + PTSUR + + + 36.238177 N 121.855209 W + 0.05 NM + 0 NM + -72,3 + 0,24 + COOPERPT + + + 36.225175 N 121.801314 W + 0.05 NM + 0 NM + -91,-8 + 0,24 + PFEIFENT + + + 36.230449 N 121.797444 W + Anchor + 0.05 NM + 0 NM + -85,-14 + 0,24 + PFEIFANC + + + 35.879801 N 121.498947 W + 0.05 NM + 0 NM + 10,-15 + 0,24 + SANMRT01 + + + 35.652801 N 121.308485 W + 0.05 NM + 0 NM + -75,2 + 0,24 + PDRSBLNC + + + 35.623297 N 121.185920 W + 0.05 NM + 0 NM + -102,-6 + 0,24 + SNSMNENT + + + 35.640478 N 121.183772 W + Anchor + 0.05 NM + 0 NM + -105,-9 + 0,24 + SNSMNANC + + + 35.572353 N 121.152797 W + 0.05 NM + 0 NM + -80,-1 + 0,24 + CAMBRIA + + + 35.449214 N 121.020825 W + 0.05 NM + 0 NM + 14,-14 + 0,24 + PTESTERO + + + 35.216602 N 120.928391 W + 0.05 NM + 0 NM + -96,-3 + 0,24 + PTBUCHON + + + 34.883361 N 120.684631 W + 0.05 NM + 0 NM + -57,3 + 0,24 + PTSAL01 + + + 34.884641 N 120.652026 W + 0.05 NM + 0 NM + -96,-8 + 0,24 + PTSALENT + A description of the Point Sal Entrance mark + + + 34.896555 N 120.649124 W + Anchor + 0.05 NM + 0 NM + -96,-10 + 0,24 + PTSALANC + + + 34.758180 N 120.642516 W + 0.05 NM + 0 NM + 22,-8 + 0,24 + PURSMAPT + + + 34.572579 N 120.663636 W + 0.05 NM + 0 NM + -97,-7 + 0,24 + PTARGLLO + + + 34.113844 N 120.492630 W + 0.05 NM + 0 NM + 20,-11 + 0,24 + SANMGL01 + + + 34.029483 N 120.471409 W + 0.05 NM + 0 NM + -88,0 + 0,24 + SANMGL02 + + + 34.019184 N 120.444197 W + 0.05 NM + 0 NM + -32,5 + 0,24 + SANMGL03 + + + 34.023478 N 120.438209 W + 0.05 NM + 0 NM + 19,-4 + 0,24 + ADCOVENT + + + 34.028615 N 120.439696 W + Anchor + 0.05 NM + 0 NM + -102,-5 + 0,24 + ADCOVANC + + diff --git a/reference/coastexp.ref b/reference/coastexp.ref new file mode 100755 index 000000000..86bab53b1 --- /dev/null +++ b/reference/coastexp.ref @@ -0,0 +1,221 @@ + + + + + + + PESCDR01 + PESCDR01 + PESCDR01 + + + + PIGEON01 + PIGEON01 + PIGEON01 + + + + ANONUV01 + ANONUV01 + ANONUV01 + + + + SCRUZ01 + SCRUZ01 + SCRUZ01 + + + + SCRUZ02 + SCRUZ02 + SCRUZ02 + + + + SCRUZENT + SCRUZENT + SCRUZENT + + + + CYPRSSPT + CYPRSSPT + CYPRSSPT + + + + PTSUR + PTSUR + PTSUR + + + + COOPERPT + COOPERPT + COOPERPT + + + + PFEIFENT + PFEIFENT + PFEIFENT + + + + PFEIFANC + PFEIFANC + PFEIFANC + + + + SANMRT01 + SANMRT01 + SANMRT01 + + + + PDRSBLNC + PDRSBLNC + PDRSBLNC + + + + SNSMNENT + SNSMNENT + SNSMNENT + + + + SNSMNANC + SNSMNANC + SNSMNANC + + + + CAMBRIA + CAMBRIA + CAMBRIA + + + + PTESTERO + PTESTERO + PTESTERO + + + + PTBUCHON + PTBUCHON + PTBUCHON + + + + PTSAL01 + PTSAL01 + PTSAL01 + + + + PTSALENT + A description of the Point Sal Entrance mark + A description of the Point Sal Entrance mark + + + + PTSALANC + PTSALANC + PTSALANC + + + + PURSMAPT + PURSMAPT + PURSMAPT + + + + PTARGLLO + PTARGLLO + PTARGLLO + + + + SANMGL01 + SANMGL01 + SANMGL01 + + + + SANMGL02 + SANMGL02 + SANMGL02 + + + + SANMGL03 + SANMGL03 + SANMGL03 + + + + ADCOVENT + ADCOVENT + ADCOVENT + + + + ADCOVANC + ADCOVANC + ADCOVANC + + + Into The Bay + + + SFBALBAY + + + + SFBAY001 + + + + SFBAY002 + + + + SFGGBRDG + + + + SFCHNL01 + + + + HMCOLREF + + + + HMPILL01 + + + + HMPILLPT + + + + HMPILL02 + + + + HMPILL03 + + + diff --git a/reference/coastexp.ref2 b/reference/coastexp.ref2 new file mode 100644 index 000000000..b9385cbde --- /dev/null +++ b/reference/coastexp.ref2 @@ -0,0 +1,171 @@ + + + Navigation Objects + + + {10111213-1415-1617-1819-1a1b1c1d1e1f} + {20212223-2425-2627-2829-2a2b2c2d2e2f} + {30313233-3435-3637-3839-3a3b3c3d3e3f} + {40414243-4445-4647-4849-4a4b4c4d4e4f} + {50515253-5455-5657-5859-5a5b5c5d5e5f} + {60616263-6465-6667-6869-6a6b6c6d6e6f} + {70717273-7475-7677-7879-7a7b7c7d7e7f} + {80818283-8485-8687-8889-8a8b8c8d8e8f} + {90919293-9495-9697-9899-9a9b9c9d9e9f} + {a0a1a2a3-a4a5-a6a7-a8a9-aaabacadaeaf} + + Into The Bay + + + 37.763290 N 122.282580 W + SFBALBAY + + + 37.751613 N 122.339028 W + SFBAY001 + + + 37.817420 N 122.394305 W + SFBAY002 + + + 37.819339 N 122.478302 W + SFGGBRDG + + + 37.773033 N 122.605838 W + SFCHNL01 + + + 37.518860 N 122.529914 W + HMCOLREF + + + 37.482348 N 122.507704 W + HMPILL01 + + + 37.475062 N 122.488531 W + HMPILLPT + + + 37.476448 N 122.475800 W + HMPILL02 + + + 37.495102 N 122.483927 W + HMPILL03 + + + 37.229349 N 122.441589 W + PESCDR01 + + + 37.183397 N 122.411904 W + PIGEON01 + + + 37.090736 N 122.348775 W + ANONUV01 + + + 36.929502 N 122.113725 W + SCRUZ01 + + + 36.934235 N 122.022130 W + SCRUZ02 + + + 36.960666 N 122.024734 W + SCRUZENT + + + 36.581344 N 121.995411 W + CYPRSSPT + + + 36.301110 N 121.919097 W + PTSUR + + + 36.238177 N 121.855209 W + COOPERPT + + + 36.225175 N 121.801314 W + PFEIFENT + + + 36.230449 N 121.797444 W + PFEIFANC + + + 35.879801 N 121.498947 W + SANMRT01 + + + 35.652801 N 121.308485 W + PDRSBLNC + + + 35.623297 N 121.185920 W + SNSMNENT + + + 35.640478 N 121.183772 W + SNSMNANC + + + 35.572353 N 121.152797 W + CAMBRIA + + + 35.449214 N 121.020825 W + PTESTERO + + + 35.216602 N 120.928391 W + PTBUCHON + + + 34.883361 N 120.684631 W + PTSAL01 + + + 34.884641 N 120.652026 W + PTSALENT + + + 34.896555 N 120.649124 W + PTSALANC + + + 34.758180 N 120.642516 W + PURSMAPT + + + 34.572579 N 120.663636 W + PTARGLLO + + + 34.113844 N 120.492630 W + SANMGL01 + + + 34.029483 N 120.471409 W + SANMGL02 + + + 34.019184 N 120.444197 W + SANMGL03 + + + 34.023478 N 120.438209 W + ADCOVENT + + + 34.028615 N 120.439696 W + ADCOVANC + + diff --git a/reference/coastexp.ref3 b/reference/coastexp.ref3 new file mode 100644 index 000000000..86bab53b1 --- /dev/null +++ b/reference/coastexp.ref3 @@ -0,0 +1,221 @@ + + + + + + + PESCDR01 + PESCDR01 + PESCDR01 + + + + PIGEON01 + PIGEON01 + PIGEON01 + + + + ANONUV01 + ANONUV01 + ANONUV01 + + + + SCRUZ01 + SCRUZ01 + SCRUZ01 + + + + SCRUZ02 + SCRUZ02 + SCRUZ02 + + + + SCRUZENT + SCRUZENT + SCRUZENT + + + + CYPRSSPT + CYPRSSPT + CYPRSSPT + + + + PTSUR + PTSUR + PTSUR + + + + COOPERPT + COOPERPT + COOPERPT + + + + PFEIFENT + PFEIFENT + PFEIFENT + + + + PFEIFANC + PFEIFANC + PFEIFANC + + + + SANMRT01 + SANMRT01 + SANMRT01 + + + + PDRSBLNC + PDRSBLNC + PDRSBLNC + + + + SNSMNENT + SNSMNENT + SNSMNENT + + + + SNSMNANC + SNSMNANC + SNSMNANC + + + + CAMBRIA + CAMBRIA + CAMBRIA + + + + PTESTERO + PTESTERO + PTESTERO + + + + PTBUCHON + PTBUCHON + PTBUCHON + + + + PTSAL01 + PTSAL01 + PTSAL01 + + + + PTSALENT + A description of the Point Sal Entrance mark + A description of the Point Sal Entrance mark + + + + PTSALANC + PTSALANC + PTSALANC + + + + PURSMAPT + PURSMAPT + PURSMAPT + + + + PTARGLLO + PTARGLLO + PTARGLLO + + + + SANMGL01 + SANMGL01 + SANMGL01 + + + + SANMGL02 + SANMGL02 + SANMGL02 + + + + SANMGL03 + SANMGL03 + SANMGL03 + + + + ADCOVENT + ADCOVENT + ADCOVENT + + + + ADCOVANC + ADCOVANC + ADCOVANC + + + Into The Bay + + + SFBALBAY + + + + SFBAY001 + + + + SFBAY002 + + + + SFGGBRDG + + + + SFCHNL01 + + + + HMCOLREF + + + + HMPILL01 + + + + HMPILLPT + + + + HMPILL02 + + + + HMPILL03 + + + diff --git a/reference/coastexp.ref4 b/reference/coastexp.ref4 new file mode 100644 index 000000000..b9385cbde --- /dev/null +++ b/reference/coastexp.ref4 @@ -0,0 +1,171 @@ + + + Navigation Objects + + + {10111213-1415-1617-1819-1a1b1c1d1e1f} + {20212223-2425-2627-2829-2a2b2c2d2e2f} + {30313233-3435-3637-3839-3a3b3c3d3e3f} + {40414243-4445-4647-4849-4a4b4c4d4e4f} + {50515253-5455-5657-5859-5a5b5c5d5e5f} + {60616263-6465-6667-6869-6a6b6c6d6e6f} + {70717273-7475-7677-7879-7a7b7c7d7e7f} + {80818283-8485-8687-8889-8a8b8c8d8e8f} + {90919293-9495-9697-9899-9a9b9c9d9e9f} + {a0a1a2a3-a4a5-a6a7-a8a9-aaabacadaeaf} + + Into The Bay + + + 37.763290 N 122.282580 W + SFBALBAY + + + 37.751613 N 122.339028 W + SFBAY001 + + + 37.817420 N 122.394305 W + SFBAY002 + + + 37.819339 N 122.478302 W + SFGGBRDG + + + 37.773033 N 122.605838 W + SFCHNL01 + + + 37.518860 N 122.529914 W + HMCOLREF + + + 37.482348 N 122.507704 W + HMPILL01 + + + 37.475062 N 122.488531 W + HMPILLPT + + + 37.476448 N 122.475800 W + HMPILL02 + + + 37.495102 N 122.483927 W + HMPILL03 + + + 37.229349 N 122.441589 W + PESCDR01 + + + 37.183397 N 122.411904 W + PIGEON01 + + + 37.090736 N 122.348775 W + ANONUV01 + + + 36.929502 N 122.113725 W + SCRUZ01 + + + 36.934235 N 122.022130 W + SCRUZ02 + + + 36.960666 N 122.024734 W + SCRUZENT + + + 36.581344 N 121.995411 W + CYPRSSPT + + + 36.301110 N 121.919097 W + PTSUR + + + 36.238177 N 121.855209 W + COOPERPT + + + 36.225175 N 121.801314 W + PFEIFENT + + + 36.230449 N 121.797444 W + PFEIFANC + + + 35.879801 N 121.498947 W + SANMRT01 + + + 35.652801 N 121.308485 W + PDRSBLNC + + + 35.623297 N 121.185920 W + SNSMNENT + + + 35.640478 N 121.183772 W + SNSMNANC + + + 35.572353 N 121.152797 W + CAMBRIA + + + 35.449214 N 121.020825 W + PTESTERO + + + 35.216602 N 120.928391 W + PTBUCHON + + + 34.883361 N 120.684631 W + PTSAL01 + + + 34.884641 N 120.652026 W + PTSALENT + + + 34.896555 N 120.649124 W + PTSALANC + + + 34.758180 N 120.642516 W + PURSMAPT + + + 34.572579 N 120.663636 W + PTARGLLO + + + 34.113844 N 120.492630 W + SANMGL01 + + + 34.029483 N 120.471409 W + SANMGL02 + + + 34.019184 N 120.444197 W + SANMGL03 + + + 34.023478 N 120.438209 W + ADCOVENT + + + 34.028615 N 120.439696 W + ADCOVANC + + diff --git a/reference/compegps-wpt.gpx b/reference/compegps-wpt.gpx new file mode 100644 index 000000000..e1c1b37aa --- /dev/null +++ b/reference/compegps-wpt.gpx @@ -0,0 +1,178 @@ + + + + + + 1400.000000 + F01140 + DECOLLO MONTE AVENA + DECOLLO MONTE AVENA + Waypoint + + + 300.000000 + F02030 + AVIOSUPERFICE FELTRE + AVIOSUPERFICE FELTRE + Waypoint + + + 230.000000 + F03023 + ATTERRAGGIO VALENTINE + ATTERRAGGIO VALENTINE + Waypoint + + + 320.000000 + F04032 + ATTERRAG. BIRRERIA PEDAVENA + ATTERRAG. BIRRERIA PEDAVENA + Waypoint + + + 420.000000 + F06042 + DIGA DEL MIS + DIGA DEL MIS + Waypoint + + + 460.000000 + F07046 + SOSPIROLO CHIESA + SOSPIROLO CHIESA + Waypoint + + + 450.000000 + F08045 + CESIOMAGGIORE FABBRICA + CESIOMAGGIORE FABBRICA + Waypoint + + + 290.000000 + F09029 + CARTIERA SGIUSTINA + CARTIERA SGIUSTINA + Waypoint + + + 380.000000 + F10038 + SEREN DEL GRAPPA CHIESA + SEREN DEL GRAPPA CHIESA + Waypoint + + + 346.900000 + F11031 + ARTEN FELTRE + ARTEN FELTRE + Waypoint + + + 450.000000 + F12045 + NORCEN CAMPI DA TENNIS + NORCEN CAMPI DA TENNIS + Waypoint + + + 380.000000 + F13038 + SOSPIROLO CAVA + SOSPIROLO CAVA + Waypoint + + + 1010.000000 + F14101 + COL MELON RIF BELVEDERE + COL MELON RIF BELVEDERE + Waypoint + + + 310.000000 + F15031 + FONZASO SPORTFUL + FONZASO SPORTFUL + Waypoint + + + 252.300000 + F16025 + BUSCHE LATTERIA + BUSCHE LATTERIA + Waypoint + + + 605.000000 + F17063 + LAMON + LAMON + Waypoint + + + 509.400000 + F18051 + ARSIE' + ARSIE' + Waypoint + + + 271.200000 + F19027 + CASTELLO DI FELTRE + CASTELLO DI FELTRE + Waypoint + + + 300.000000 + F20030 + SANTA LUCIA CHIESETTA + SANTA LUCIA CHIESETTA + Waypoint + + + 1430.000000 + F21143 + MALGA CAMPON + MALGA CAMPON + Waypoint + + + 300.000000 + F22030 + ZANUSSI MEL + ZANUSSI MEL + Waypoint + + + 270.000000 + F23027 + FELTRE OSPEDALE + FELTRE OSPEDALE + Waypoint + + + 860.000000 + F24086 + BAILO CASTEL TESINO + BAILO CASTEL TESINO + Waypoint + + + 450.000000 + F25045 + CASA SCEICCO + CASA SCEICCO + Waypoint + + diff --git a/reference/compegps.wpt b/reference/compegps.wpt new file mode 100644 index 000000000..722547566 --- /dev/null +++ b/reference/compegps.wpt @@ -0,0 +1,52 @@ +G WGS 84 +U 1 +W F01140 A 46.0294899313ºN 11.8258790855ºE 27-MAR-62 00:00:00 1400.000000 DECOLLO MONTE AVENA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F02030 A 46.0086266116ºN 11.8609316981ºE 27-MAR-62 00:00:00 300.000000 AVIOSUPERFICE FELTRE +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F03023 A 46.0211500041ºN 11.8854800796ºE 27-MAR-62 00:00:00 230.000000 ATTERRAGGIO VALENTINE +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F04032 A 46.0335865765ºN 11.8823672293ºE 27-MAR-62 00:00:00 320.000000 ATTERRAG. BIRRERIA PEDAVENA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F06042 A 46.1598476455ºN 12.0832581003ºE 27-MAR-62 00:00:00 420.000000 DIGA DEL MIS +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F07046 A 46.1441766659ºN 12.0754755514ºE 27-MAR-62 00:00:00 460.000000 SOSPIROLO CHIESA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F08045 A 46.0812815292ºN 11.9856990105ºE 27-MAR-62 00:00:00 450.000000 CESIOMAGGIORE FABBRICA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F09029 A 46.0755574914ºN 12.0333107491ºE 27-MAR-62 00:00:00 290.000000 CARTIERA SGIUSTINA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F10038 A 45.9885384730ºN 11.8450206880ºE 27-MAR-62 00:00:00 380.000000 SEREN DEL GRAPPA CHIESA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F11031 A 46.0105131183ºN 11.8303758183ºE 27-MAR-62 00:00:00 346.900000 ARTEN FELTRE +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F12045 A 46.0478971020ºN 11.8738181282ºE 27-MAR-62 00:00:00 450.000000 NORCEN CAMPI DA TENNIS +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F13038 A 46.1529066825ºN 12.1211567478ºE 27-MAR-62 00:00:00 380.000000 SOSPIROLO CAVA +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F14101 A 46.0427458323ºN 11.8523925232ºE 27-MAR-62 00:00:00 1010.000000 COL MELON RIF BELVEDERE +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F15031 A 46.0108797603ºN 11.8137179459ºE 27-MAR-62 00:00:00 310.000000 FONZASO SPORTFUL +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F16025 A 46.0406235353ºN 11.9840491129ºE 27-MAR-62 00:00:00 252.300000 BUSCHE LATTERIA +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F17063 A 46.0469308434ºN 11.7485280506ºE 27-MAR-62 00:00:00 605.000000 LAMON +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F18051 A 45.9916739281ºN 11.7463576240ºE 27-MAR-62 00:00:00 509.400000 ARSIE' +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F19027 A 46.0189789055ºN 11.9110897654ºE 27-MAR-62 00:00:00 271.200000 CASTELLO DI FELTRE +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F20030 A 46.0114906453ºN 11.8334226329ºE 27-MAR-62 00:00:00 300.000000 SANTA LUCIA CHIESETTA +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F21143 A 46.0399765040ºN 11.8254835151ºE 27-MAR-62 00:00:00 1430.000000 MALGA CAMPON +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F22030 A 46.0508253483ºN 12.0619251800ºE 27-MAR-62 00:00:00 300.000000 ZANUSSI MEL +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F23027 A 46.0220149684ºN 11.9077995458ºE 27-MAR-62 00:00:00 270.000000 FELTRE OSPEDALE +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F24086 A 46.0632841167ºN 11.6096598449ºE 27-MAR-62 00:00:00 860.000000 BAILO CASTEL TESINO +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F25045 A 46.0571933560ºN 11.8888581427ºE 27-MAR-62 00:00:00 450.000000 CASA SCEICCO +w Waypoint,0,0.0,16777215,255,1,7,,0.0 + + diff --git a/reference/compegps.wpt.gz b/reference/compegps.wpt.gz new file mode 100644 index 0000000000000000000000000000000000000000..3f4566b93b4cc9102ff7032356f8c95961e55f3f GIT binary patch literal 967 zcmV;&133I2iwFo#4PZk617mM(aAjw3b1rvqbO4=}zmDTL495FBg}Q690V$FCbDiQS zSpkk6SWX7m?#gR!w>aRiueMLObYjN?+!!;S%pipkn?LLO_>m{2UQR`M+FX^w&5Ke; zKqOF6k==m~8s&m`) zNyS@g;^sf~^4HHF-~ayS-z{wAms_;XIgPy4%v;>L?H1+o14DzEFu+@FEutMUEC`bg z9^b|=Gex}Rwp=f%JLW2>W2*Zut-~;&&2$=wEDt3dF+7t8aKXNfq0NlZ_o?gR>6BY_ zi*;)H+^pmvFnZ)LhP`EHdE(HXHth5XS}GpQ8ArR_9#Sm3KgPEKh{aTFYT9@0c7jBQ2D-&+?@$m)y1D(duhX zW#tKYARhJbs6Da{`k_bgY(oHqg)Sj}B2=m5_I&q6C-#i{eV411AVIox1Q}l3QIL0k zoP{w4VYskh&@h93SjgL|mYrZ9&clhw}1cd1s`y zSVg~Ui>B==sb9tOC96YJ0@JK)5j3MBLx+mc)=GFkY=J|LStoe!D>Ao8ynRTBXMIAL zbRg}BB^D+fSeu~bYvCZ|#@Uyxq(iFPMs@k9_Nl(5L;9E|PZECZ2$^5b!bF0`p$jD8 z@%Bl~Ajh`(7E7zjrS1CTwO&PFK|f6aRvVVTDJux1KT$6b$T98AgJ6Fx)z_rzdxqzA zVmPqV5F;B5crx?=a3pegU|1Mp7I->>I?60xRaTyhV=4ssnW*k@Dr=2QFii`ozz}vc z^#GC>>m9P)}Jm>A?C&-FzXDrrFC zXAT+C+L|TJU#%}CHhom}waQ}{roLaLytFz^%9}8}xH#~+%#k;Yyf7W)#wW)))-tMx zJX+@f{c4G0kcx&LX)MFZqJ)50WN9wUr|>N{*HZEj1gnah*#-h4B3M7VK7ex}u%yzG z4d%wbORppdWl^fvd4Obb9RWmcPqM+f2Y_s_c37Nf!2^C?Q}!|6^LKEgOoEb|b`=EA p6Nw!LSsv}=0Qtx~lz4uBQHe!%gDT~!`f&Bl<~Mq?Bfwq^008|r-Om63 literal 0 HcmV?d00001 diff --git a/reference/cototest.style b/reference/cototest.style new file mode 100644 index 000000000..6d167f630 --- /dev/null +++ b/reference/cototest.style @@ -0,0 +1,33 @@ +# gpsbabel XCSV style file +# +# Format: Test-style for cotoGPS +# Author: Tobias Minich +# Date: 08/01/2005 +# +# + +DESCRIPTION Test-style for cotoGPS + +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE + + +# +# INDIVIDUAL DATA FIELDS: +# +IFIELD LAT_DECIMAL, "", "%f" +IFIELD LON_DECIMAL, "", "%f" +IFIELD ICON_DESCR, "", "%s" +IFIELD SHORTNAME, "", "%s" +IFIELD DESCRIPTION, "", "%s" +IFIELD NOTES, "", "%s" +IFIELD ALT_METERS, "", "%.0f" +IFIELD PATH_SPEED, "", "%10.1f" +IFIELD TIMET_TIME, "", "%ld" +IFIELD GPS_HDOP, "", "%10.1f" +IFIELD GPS_VDOP, "", "%10.1f" +IFIELD GPS_PDOP, "", "%10.1f" +IFIELD GPS_SAT, "", "%d" +IFIELD GPS_FIX, "", "%s" diff --git a/reference/cototestmarker.gpx b/reference/cototestmarker.gpx new file mode 100644 index 000000000..52843a39f --- /dev/null +++ b/reference/cototestmarker.gpx @@ -0,0 +1,22 @@ + + + + + + GC2663 + New Orleans Bon Chance (Good Luck) Cache-Cam by CrotalusRex and Mimichan + New Orleans Bon Chance (Good Luck) Cache-Cam by CrotalusRex and Mimichan + Geocache + + + GCMK1V + Randeck Maar Earthcache by Border + Randeck Maar Earthcache by Border + Earthcache + + diff --git a/reference/cototestmarker.pdb b/reference/cototestmarker.pdb new file mode 100644 index 0000000000000000000000000000000000000000..eb33c7b6bd85d9bdba5706cf1b14a61036e37e96 GIT binary patch literal 550 zcmYe!FUfZg2v+b-EXqzTa&cln2OQ`EV15FKba4!EOa|%(i+~6w1_s7rMlhH00f@uE zAkW~JU!vexT%4Jnmzn~Sa!<`qPE5{71uFv*u8Bn@87Lw!nPEaR0z(1`Fxmf9TeUJ= zcD4P3-I*T@7>wPWjm*r9kyHSgeyQaO{zW;diFw5ePWgEX&KZe$$*Bq&?)mvC3O=RD z*_sN@pg`1hPRvzEs#I_;$}dUGDJ>34tx!nJOHuI6%*{*&>S5S_)ICaBYj&0WYlXu7 nAGdsUclPx*3`4an2&f}9IUAS;5{ncN(E&2oDZeNswTJ-#`_oM^ literal 0 HcmV?d00001 diff --git a/reference/cototesttrack.csv b/reference/cototesttrack.csv new file mode 100644 index 000000000..d62e71c48 --- /dev/null +++ b/reference/cototesttrack.csv @@ -0,0 +1,135 @@ +48.557327,8.961583,,,,,395, 1.9,1122371309, 0.8, 1.2, 1.5,10,3d +48.557327,8.961585,,,,,395, 0.5,1122371311, 0.8, 1.2, 1.5,9,3d +48.557353,8.961542,,,,,395, 1.2,1122371313, 0.9, 1.3, 1.6,10,3d +48.557388,8.961457,,,,,395, 3.5,1122371315, 0.9, 1.3, 1.6,9,3d +48.557395,8.961412,,,,,395, 3.7,1122371316, 0.9, 1.3, 1.6,10,3d +48.557390,8.961370,,,,,395, 3.0,1122371317, 0.8, 1.2, 1.5,10,3d +48.557360,8.961295,,,,,395, 3.3,1122371319, 0.9, 1.4, 1.7,9,3d +48.557350,8.961223,,,,,395, 2.6,1122371321, 0.8, 1.2, 1.5,10,3d +48.557385,8.961148,,,,,396, 2.4,1122371324, 1.0, 1.6, 1.9,9,3d +48.557427,8.961158,,,,,395, 1.8,1122371326, 0.8, 1.2, 1.5,10,3d +48.557473,8.961232,,,,,396, 3.2,1122371328, 0.8, 1.2, 1.5,10,3d +48.557523,8.961327,,,,,396, 4.3,1122371330, 1.0, 1.6, 1.9,9,3d +48.557547,8.961410,,,,,396, 3.0,1122371332, 0.8, 1.2, 1.5,10,3d +48.557493,8.961597,,,,,396, 5.2,1122371335, 1.2, 2.0, 2.3,9,3d +48.557405,8.961743,,,,,396, 6.8,1122371337, 0.8, 1.2, 1.5,10,3d +48.557295,8.961937,,,,,395, 8.9,1122371339, 0.8, 1.2, 1.5,10,3d +48.557295,8.961937,,,,,395, 8.9,1122371339, 0.8, 1.2, 1.5,10,3d +48.557113,8.962262,,,,,395, 10.4,1122371342, 0.8, 1.2, 1.5,10,3d +48.557050,8.962375,,,,,395, 10.8,1122371343, 0.8, 1.2, 1.5,10,3d +48.556857,8.962722,,,,,395, 11.1,1122371346, 1.2, 1.5, 1.9,7,3d +48.556725,8.962953,,,,,395, 11.3,1122371348, 1.4, 2.3, 2.7,6,3d +48.556658,8.963070,,,,,395, 11.3,1122371349, 1.4, 2.3, 2.7,6,3d +48.556522,8.963310,,,,,395, 11.3,1122371351, 1.2, 2.2, 2.5,7,3d +48.556377,8.963557,,,,,394, 11.9,1122371353, 1.2, 2.0, 2.3,8,3d +48.556212,8.963793,,,,,394, 12.4,1122371355, 1.4, 2.0, 2.5,5,3d +48.556020,8.963990,,,,,393, 13.1,1122371357, 1.3, 2.3, 2.7,6,3d +48.555918,8.964075,,,,,393, 12.8,1122371358, 1.3, 2.0, 2.4,5,3d +48.555717,8.964222,,,,,393, 12.4,1122371360, 3.9, 6.4, 7.5,4,3d +48.555523,8.964363,,,,,392, 12.2,1122371362, 30.7, 41.0, 51.3,4,2d +48.555345,8.964542,,,,,392, 11.6,1122371364, 1.0, 1.6, 1.9,9,3d +48.555177,8.964760,,,,,392, 12.5,1122371366, 1.2, 1.9, 2.3,6,3d +48.555020,8.964978,,,,,392, 12.2,1122371368, 1.4, 2.3, 2.7,7,3d +48.554947,8.965077,,,,,392, 11.0,1122371369, 1.2, 2.2, 2.5,7,3d +48.554795,8.965253,,,,,392, 10.7,1122371371, 1.4, 2.4, 2.7,6,3d +48.554627,8.965418,,,,,391, 11.3,1122371373, 1.3, 2.8, 3.1,6,3d +48.554448,8.965578,,,,,391, 11.4,1122371375, 3.2, 3.5, 4.7,4,3d +48.554302,8.965727,,,,,390, 10.7,1122371377, 1.7, 2.3, 2.9,5,3d +48.554215,8.965882,,,,,391, 8.3,1122371379, 1.2, 2.2, 2.5,7,3d +48.554243,8.966045,,,,,391, 6.5,1122371381, 1.3, 2.0, 2.4,7,3d +48.554282,8.966232,,,,,391, 6.9,1122371383, 1.5, 4.1, 4.3,5,3d +48.554318,8.966453,,,,,391, 8.4,1122371385, 1.4, 2.4, 2.7,6,3d +48.554350,8.966680,,,,,392, 8.5,1122371387, 1.4, 2.5, 2.9,6,3d +48.554378,8.966915,,,,,392, 8.8,1122371389, 1.5, 4.1, 4.3,5,3d +48.554408,8.967123,,,,,393, 8.6,1122371391, 2.1, 2.3, 3.1,5,3d +48.554463,8.967297,,,,,394, 7.3,1122371393, 1.2, 1.8, 2.2,7,3d +48.554517,8.967438,,,,,395, 6.4,1122371395, 1.2, 1.9, 2.3,7,3d +48.554565,8.967590,,,,,395, 6.0,1122371397, 1.2, 1.9, 2.2,7,3d +48.554615,8.967743,,,,,395, 6.4,1122371399, 1.4, 2.3, 2.7,6,3d +48.554700,8.967838,,,,,396, 6.1,1122371401, 1.3, 2.3, 2.7,7,3d +48.554800,8.967820,,,,,397, 5.5,1122371403, 1.2, 2.0, 2.3,8,3d +48.554897,8.967800,,,,,396, 5.5,1122371405, 2.6, 3.1, 4.1,6,3d +48.555007,8.967795,,,,,396, 5.6,1122371407, 2.4, 3.1, 3.9,6,3d +48.555125,8.967822,,,,,396, 6.5,1122371409, 2.3, 2.2, 3.1,6,3d +48.555218,8.967930,,,,,397, 6.6,1122371411, 0.9, 1.3, 1.6,8,3d +48.555298,8.968085,,,,,399, 7.2,1122371413, 2.1, 2.3, 3.1,5,3d +48.555385,8.968235,,,,,400, 7.2,1122371415, 1.2, 1.8, 2.2,7,3d +48.555455,8.968420,,,,,401, 7.5,1122371417, 1.4, 2.3, 2.7,6,3d +48.555515,8.968630,,,,,402, 8.4,1122371419, 1.4, 2.3, 2.7,6,3d +48.555562,8.968847,,,,,403, 8.5,1122371421, 1.2, 1.8, 2.2,7,3d +48.555613,8.969055,,,,,403, 8.4,1122371423, 1.2, 1.8, 2.2,7,3d +48.555665,8.969248,,,,,403, 7.9,1122371425, 1.4, 2.3, 2.7,6,3d +48.555727,8.969428,,,,,403, 7.4,1122371427, 1.4, 2.3, 2.7,6,3d +48.555790,8.969582,,,,,403, 6.8,1122371429, 1.4, 2.3, 2.7,6,3d +48.555870,8.969733,,,,,404, 6.7,1122371431, 1.1, 1.6, 2.0,8,3d +48.555958,8.969892,,,,,404, 7.5,1122371433, 0.9, 1.3, 1.6,9,3d +48.556038,8.970065,,,,,404, 7.7,1122371435, 1.3, 1.8, 2.2,7,3d +48.556113,8.970243,,,,,404, 7.8,1122371437, 1.3, 1.8, 2.2,7,3d +48.556180,8.970410,,,,,404, 7.5,1122371439, 1.4, 2.3, 2.7,6,3d +48.556238,8.970570,,,,,404, 6.8,1122371441, 0.9, 1.4, 1.7,8,3d +48.556307,8.970727,,,,,404, 6.9,1122371443, 1.3, 1.8, 2.2,7,3d +48.556397,8.970867,,,,,404, 7.2,1122371445, 1.3, 2.3, 2.7,7,3d +48.556498,8.970997,,,,,404, 7.4,1122371447, 1.5, 4.1, 4.4,5,3d +48.556607,8.971127,,,,,403, 7.6,1122371449, 1.5, 2.3, 2.7,6,3d +48.556720,8.971252,,,,,403, 7.8,1122371451, 1.3, 2.8, 3.1,6,3d +48.556835,8.971373,,,,,404, 7.8,1122371453, 1.1, 1.7, 2.0,8,3d +48.556948,8.971477,,,,,404, 7.6,1122371455, 1.1, 1.6, 2.0,8,3d +48.557075,8.971538,,,,,406, 7.2,1122371457, 1.6, 1.8, 2.4,8,3d +48.557210,8.971575,,,,,407, 7.3,1122371459, 1.2, 2.0, 2.3,8,3d +48.557345,8.971608,,,,,407, 7.7,1122371461, 1.0, 1.6, 1.9,9,3d +48.557470,8.971637,,,,,407, 7.2,1122371463, 1.1, 1.7, 2.0,8,3d +48.557538,8.971660,,,,,406, 5.4,1122371465, 1.1, 1.7, 2.0,8,3d +48.557570,8.971673,,,,,406, 2.2,1122371467, 0.9, 1.4, 1.7,9,3d +48.557622,8.971690,,,,,406, 2.5,1122371469, 1.3, 2.8, 3.1,6,3d +48.557678,8.971717,,,,,405, 3.4,1122371471, 1.5, 2.3, 2.7,6,3d +48.557730,8.971812,,,,,406, 3.9,1122371473, 1.2, 1.8, 2.2,7,3d +48.557775,8.971957,,,,,407, 5.9,1122371475, 0.9, 1.3, 1.6,9,3d +48.557828,8.972137,,,,,409, 6.8,1122371477, 1.1, 1.6, 2.0,8,3d +48.557883,8.972347,,,,,409, 8.3,1122371479, 1.0, 1.5, 1.7,8,3d +48.557937,8.972573,,,,,409, 8.7,1122371481, 1.0, 1.5, 1.8,7,3d +48.558018,8.972813,,,,,411, 9.4,1122371483, 1.3, 1.8, 2.3,7,3d +48.558095,8.973078,,,,,413, 10.5,1122371485, 1.3, 1.8, 2.3,7,3d +48.558175,8.973340,,,,,414, 10.7,1122371487, 1.3, 1.8, 2.3,7,3d +48.558255,8.973603,,,,,416, 10.6,1122371489, 1.0, 1.5, 1.7,8,3d +48.558335,8.973867,,,,,416, 10.7,1122371491, 1.3, 1.8, 2.3,7,3d +48.558420,8.974128,,,,,417, 10.6,1122371493, 1.9, 2.0, 2.7,6,3d +48.558505,8.974393,,,,,418, 10.7,1122371495, 1.5, 2.3, 2.7,6,3d +48.558592,8.974660,,,,,419, 10.9,1122371497, 1.3, 1.8, 2.3,7,3d +48.558677,8.974927,,,,,420, 10.9,1122371499, 1.3, 1.8, 2.3,7,3d +48.558772,8.975185,,,,,422, 10.8,1122371501, 0.9, 1.3, 1.6,9,3d +48.558868,8.975437,,,,,423, 10.7,1122371503, 1.3, 1.9, 2.3,6,3d +48.558970,8.975678,,,,,424, 10.6,1122371505, 1.0, 1.5, 1.8,7,3d +48.559053,8.975923,,,,,426, 10.4,1122371507, 1.2, 1.8, 2.2,6,3d +48.559093,8.976192,,,,,427, 9.6,1122371509, 1.0, 1.6, 1.9,9,3d +48.559093,8.976475,,,,,429, 10.4,1122371511, 1.0, 1.6, 1.9,9,3d +48.559070,8.976762,,,,,432, 10.6,1122371513, 0.8, 1.2, 1.5,10,3d +48.559052,8.977048,,,,,434, 10.7,1122371515, 0.9, 1.4, 1.7,9,3d +48.559067,8.977337,,,,,436, 10.6,1122371517, 0.9, 1.4, 1.7,9,3d +48.559103,8.977623,,,,,437, 10.7,1122371519, 1.2, 1.8, 2.2,7,3d +48.559152,8.977908,,,,,439, 10.7,1122371521, 1.2, 1.8, 2.2,7,3d +48.559203,8.978187,,,,,440, 10.7,1122371523, 2.3, 2.1, 3.1,6,3d +48.559275,8.978455,,,,,442, 10.8,1122371525, 1.0, 1.6, 1.9,9,3d +48.559373,8.978698,,,,,444, 10.6,1122371527, 1.0, 1.6, 1.9,9,3d +48.559490,8.978930,,,,,446, 10.6,1122371529, 0.9, 1.3, 1.6,8,3d +48.559628,8.979135,,,,,448, 10.7,1122371531, 1.0, 1.6, 1.9,9,3d +48.559780,8.979312,,,,,449, 10.6,1122371533, 1.2, 2.0, 2.3,8,3d +48.559935,8.979483,,,,,451, 10.5,1122371535, 1.0, 1.6, 1.9,9,3d +48.560095,8.979653,,,,,453, 10.7,1122371537, 1.0, 1.6, 1.9,9,3d +48.560253,8.979823,,,,,455, 10.7,1122371539, 1.0, 1.6, 1.9,9,3d +48.560413,8.979993,,,,,456, 10.8,1122371541, 1.7, 1.8, 2.4,8,3d +48.560567,8.980157,,,,,458, 10.5,1122371543, 1.7, 1.8, 2.4,8,3d +48.560713,8.980332,,,,,460, 10.3,1122371545, 1.7, 1.8, 2.4,8,3d +48.560833,8.980553,,,,,462, 10.3,1122371547, 1.2, 2.0, 2.3,8,3d +48.560907,8.980828,,,,,463, 10.8,1122371549, 2.4, 3.1, 3.9,7,3d +48.560930,8.981137,,,,,465, 11.3,1122371551, 1.2, 2.0, 2.3,8,3d +48.560932,8.981452,,,,,467, 11.5,1122371553, 1.3, 2.3, 2.7,7,3d +48.560948,8.981762,,,,,469, 11.5,1122371555, 1.3, 2.3, 2.7,7,3d +48.560988,8.982068,,,,,471, 11.5,1122371557, 1.5, 4.1, 4.4,5,3d +48.561040,8.982372,,,,,473, 11.5,1122371559, 1.2, 1.8, 2.2,6,3d +48.561098,8.982663,,,,,474, 11.3,1122371561, 1.3, 1.9, 2.3,6,3d +48.561193,8.982927,,,,,475, 11.0,1122371563, 1.1, 1.6, 2.0,8,3d +48.561270,8.983170,,,,,476, 10.4,1122371565, 0.9, 1.3, 1.6,9,3d +48.561337,8.983385,,,,,477, 8.9,1122371567, 0.8, 1.3, 1.5,9,3d +48.561395,8.983598,,,,,477, 8.6,1122371569, 0.9, 1.3, 1.6,9,3d +48.561447,8.983807,,,,,477, 8.4,1122371571, 1.1, 1.6, 2.0,8,3d +48.561483,8.983955,,,,,477, 6.6,1122371573, 1.1, 1.8, 2.1,8,3d diff --git a/reference/cototesttrack.pdb b/reference/cototesttrack.pdb new file mode 100644 index 0000000000000000000000000000000000000000..41f34d7458a87321e335e06f3d98f04178b5a7c8 GIT binary patch literal 9800 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 literal 0 HcmV?d00001 diff --git a/reference/destinator_poi.dat b/reference/destinator_poi.dat new file mode 100644 index 0000000000000000000000000000000000000000..cd49276b92984bc58265697c3b57285e497f444b GIT binary patch literal 10492 zcmb7~33OD|8OLud7=fa}BAXNt3Y1N$2tYk6!2DCs4kO%|ytwAZKA@f{Ip3*_5{mz^i2o;{T3!i<*XS`7G&h(Y!bN53xrC zvu1;EQ(hpxuF2AJb=U{DzrP*4wV}O=?clLy8#7+e!|~}B+lsz%b@Nv_;6eoc~mDI-Z3LOGH6&tFl)9k=LO;GnkOw+ zM~|)_oNU7Q>dKCE{R?=k*~X0Lr*wY$D&1mR(cjjb$oL+-kM34RzX2X=wlU+`9>!C* z*jDtC*G$C_=-d3JnV;%QUTa&?^Qwtv@g@P@U%bD=Da|xYR)kR;B0EeeTZ(;X_?<4aEJP=tuF?bHQPLn zE32B0t#GyCK1BC_HrBQW+>jSvtt$kVHQShR12OAmtFzY1d1^8!+K+aXEOb z-Qn4lbN$gRwiVs*x;<(+csZZ0x>y4qYql{SpR76lYBa9S$tnV7HpeQ|@)Pb$baeDH zVIP2hXUMQ|GloY5vt}D}zODzv6Qk>itzFgda`3*XNX-5Nc&x4R0x(~s0#W$Wtsuj5 zI@A_ADh14iL#`k2!8Mb$yUb7(tI`}XcCsIR!hMOZ+qm=gSnxBu_qosqeAaAZ6l0;u ze2oJ;M1`Xg8v|3XeL3XGdI+nDhroAp?Ai)}^Un7jA6dqCZ7f)@)MTgMSsBKxh$J6s&ct-Pm{5v;e zPJowtcfr9d@K{^t`GO&P%K-e>Ew&Zy=QCk>EqI=xyWebsT7)&*7@t2U#hf?q!mi;L z!FwaOW3RU0v38FqwVmb}?M;$mo=TVTjjRt}^gej3-Qn4r=esY~7n%94j*7a0oeqIl z5SWlJdm+|rV-`<)^ZF?~qxtu3+BcOSgQteo6nDn>Si8rQ+EwCdT)U3S3wd4gvs1!| zbC++C84kb3NyU=~Uc@=#nw{>FvOs z+_3vr6}YU~#(bQzx6-wm<{Ibg!G@ZZ3f#WqtNZK&m$f@wXMG`i52N|fvmw;u@5rCl zITuf+fXCW8PtK$4o253?Ew&XsBRkytX^d~(Tbs(#{33!`vyE|FWlre%=xnjA=yw~7 zv(I9DZKLk>oP>IYHQSi+obxfrWImqv?fTnm;H@2XsncNaSX{g)oe8npXYMN&3aMLg8To3KVEAqH<#f2vSu@*@rys=MTAOk z-sg!o;zOn?Q2F>T_rb-xY}^&kQLjM9!nZsIH0za5y))@5{A%<3#)$(EC)R9cmGm3`Pp;D{4%l~!x@*m3` zkN2m2_+SIFgtb+^)ZTXdg<<>&Dg`fvb}k}67cZR`+?Uqb=NDJWzN%tJX`|HTtl7#a z0+J8%%)osQo}bcxe=Edb_JC_E4j?00TlF9u_aTzi%b2$bju|6QhZJ%_&kdQ+vmNtB z=B>;b$At@7phjjY!0@=JPjT}fV zo$a5ydLLxgZ1Z@s)WDC%Z2VOB(0Q-!#URHW3g4fPXtQ>gZ2JLMl&j<9lk29+c>QCF z8~fra$C_;(H{Ks+wNXxgb>+dn2cUXQNWA0=Dr>7$eQ!1p*VP2XSgH%D^`zFcR%N8r zgq)Gxz$;;m>q2lnV{O$B{d)wvipRPVk98#x?+UF9N3A&r?{n2OtT40imj~~X;ibOX zTJv*ieOTweVm_pQJ^J78VfA5c-A`XsgMo-vD58}LFT-G(peDn=Ja{z4QNMF*JD5ed3 z@v!ZkxdZvbnyrj{(a-69K~IA>iO3%9OFn#<!5kJq9jowld?&y%DS2!5OoDvjN;gw(gr`Ln79W1U1&-m*j-(t3%<}e7wspA{VR4YiOsUB`Zoc zci*hN=1)@cWUz;=->2ho?pU*#an9&kTGlgpsvm-9zY?=N@MTXk3%*!eWzYQTdI$L( zg{oWJrVQ79*490eI?^9Lq`{Xs?EF(59_7Oq`Hi5_J&?C2j;{O%_~RaQSn7dQp0zuC r`E`t}@A24qDy${C!j+XZ7400uvywEVchNEU5TCJiQ4#W(HT&>C-Is<; literal 0 HcmV?d00001 diff --git a/reference/destinator_poi.txt b/reference/destinator_poi.txt new file mode 100644 index 000000000..1c12781de --- /dev/null +++ b/reference/destinator_poi.txt @@ -0,0 +1,87 @@ +No,Latitude,Longitude,Name,Description +1,42.438878,-71.119277,"5066","5066" +2,42.439227,-71.119689,"5067","5067" +3,42.438917,-71.116146,"5096","5096" +4,42.443904,-71.122044,"5142","5142" +5,42.447298,-71.121447,"5156","5156" +6,42.454873,-71.125094,"5224","5224" +7,42.459079,-71.124988,"5229","5229" +8,42.456979,-71.124474,"5237","5237" +9,42.454401,-71.120990,"5254","5254" +10,42.451442,-71.121746,"5258","5258" +11,42.454404,-71.120660,"5264","5264" +12,42.457761,-71.121045,"526708","526708" +13,42.457089,-71.120313,"526750","526750" +14,42.456592,-71.119676,"527614","527614" +15,42.456252,-71.119356,"527631","527631" +16,42.458148,-71.119135,"5278","5278" +17,42.459377,-71.117693,"5289","5289" +18,42.464183,-71.119828,"5374FIRE","5374FIRE" +19,42.465650,-71.119399,"5376","5376" +20,42.439018,-71.114456,"6006","600698" +21,42.438594,-71.114803,"6006BLUE","6006BLUE" +22,42.436757,-71.113223,"6014MEADOW","6014MEADOW" +23,42.441754,-71.113220,"6029","6029" +24,42.436243,-71.109075,"6053","6053" +25,42.439250,-71.107500,"6066","6066" +26,42.439764,-71.107582,"6067","6067" +27,42.434766,-71.105874,"6071","6071" +28,42.433304,-71.106599,"6073","6073" +29,42.437338,-71.104772,"6084","6084" +30,42.442196,-71.110975,"6130","6130" +31,42.442981,-71.111441,"6131","6131" +32,42.444773,-71.108882,"6153","6153" +33,42.443592,-71.106301,"6171","6171" +34,42.447804,-71.106624,"6176","6176" +35,42.448448,-71.106158,"6177","6177" +36,42.453415,-71.106783,"6272","6272" +37,42.453434,-71.107253,"6272","6272" +38,42.458298,-71.106771,"6278","6278" +39,42.451430,-71.105413,"6280","6280" +40,42.453845,-71.105206,"6283","6283" +41,42.459986,-71.106170,"6289","6289" +42,42.457616,-71.105116,"6297","6297" +43,42.467110,-71.113574,"6328","6328" +44,42.464202,-71.109863,"6354","6354" +45,42.466459,-71.110067,"635722","635722" +46,42.466557,-71.109410,"635783","635783" +47,42.463495,-71.107117,"6373","6373" +48,42.401051,-71.110241,"6634","6634" +49,42.432621,-71.106532,"6979","6979" +50,42.431033,-71.107883,"6997","6997" +51,42.465687,-71.107360,"BEAR HILL","Bear Hill Tower" +52,42.430950,-71.107628,"BELLEVUE","Bellevue Parking Lot" +53,42.438666,-71.114079,"6016","Bike Loop Connector" +54,42.456469,-71.124651,"5236BRIDGE","Bridge" +55,42.465759,-71.119815,"5376BRIDGE","Bridge" +56,42.442993,-71.105878,"6181CROSS","Crossing" +57,42.435472,-71.109664,"6042CROSS","Crossing" +58,42.458516,-71.103646,"DARKHOLLPO","Dark Hollow Pond" +59,42.443109,-71.112675,"6121DEAD","Dead End" +60,42.449866,-71.119298,"5179DEAD","Dead End" +61,42.459629,-71.116524,"5299DEAD","Dead End" +62,42.465485,-71.119148,"5376DEAD","Dead End" +63,42.462776,-71.109986,"6353DEAD","Dead End" +64,42.446793,-71.108784,"6155DEAD","Dead End" +65,42.451204,-71.126602,"GATE14","Gate 14" +66,42.458499,-71.122078,"GATE16","Gate 16" +67,42.459376,-71.119238,"GATE17","Gate 17" +68,42.466353,-71.119240,"GATE19","Gate 19" +69,42.468655,-71.107697,"GATE21","Gate 21" +70,42.456718,-71.102973,"GATE24","Gate 24" +71,42.430847,-71.107690,"GATE5","Gate 5" +72,42.431240,-71.109236,"GATE6","Gate 6" +73,42.439502,-71.106556,"6077LOGS","Log Crossing" +74,42.449765,-71.122320,"5148NANEPA","Nanepashemet Road Crossing" +75,42.457388,-71.119845,"5267OBSTAC","Obstacle" +76,42.434980,-71.109942,"PANTHRCAVE","Panther Cave" +77,42.453256,-71.121211,"5252PURPLE","Purple Rock Hill" +78,42.457734,-71.117481,"5287WATER","Reservoir" +79,42.459278,-71.124574,"5239ROAD","Road" +80,42.458782,-71.118991,"5278ROAD","Road" +81,42.439993,-71.120925,"5058ROAD","Road Crossing" +82,42.453415,-71.106782,"SHEEPFOLD","Sheepfold Parking Lot" +83,42.455956,-71.107483,"SOAPBOX","Soap Box Derby Track" +84,42.465913,-71.119328,"5376STREAM","Stream Crossing" +85,42.445359,-71.122845,"5144SUMMIT","Summit" +86,42.441727,-71.121676,"5150TANK","Water Tank" diff --git a/reference/dnatest.txt b/reference/dnatest.txt new file mode 100644 index 000000000..49bdf221c --- /dev/null +++ b/reference/dnatest.txt @@ -0,0 +1,16 @@ +0,27.85049,-82.49305,MACDILL +1,27.84906,-82.49258,MACDILL PK NAIL +2,27.84604,-82.48745,BEAVER +3,27.85049,-82.49305,CARTER +4,27.87861,-82.58639,188 FLHD +5,27.81962,-82.60658,BRIGHTWATER E +6,27.82113,-82.60179,BRIGHTWATER D +7,27.82098,-82.60052,BRIGHTWATER C +8,27.81919,-82.59823,BRIGHTWATER B AZ MK 2 +9,27.81850,-82.59673,BRIGHTWATER B +10,27.93168,-82.42910,BRIDGE 2 +11,27.93139,-82.42889,BRIDGE 2 RM 3 +12,27.87694,-82.58806,GANDY RM 2 +13,27.87694,-82.58806,GANDY RM 4 +14,27.93139,-82.42889,BRIDGE 2 RM 4 +15,27.93169,-82.42927,H 261 RESET diff --git a/reference/dop-test.gpx b/reference/dop-test.gpx new file mode 100644 index 000000000..e4ec10f98 --- /dev/null +++ b/reference/dop-test.gpx @@ -0,0 +1,17 @@ + + + + + Testcase + +374.0000000.0000003d850.5000006.8000007.600000 +374.0000001.1000003d86.90000050.5000006.900000 +374.0000001.1000002d82.0000002.0000002.000000 + + + diff --git a/reference/dusky.gnuplot b/reference/dusky.gnuplot new file mode 100644 index 000000000..952cfebe1 --- /dev/null +++ b/reference/dusky.gnuplot @@ -0,0 +1,65 @@ +plot "-" with lines +0.0000 623.359581 +2.9718 711.942258 +3.2850 715.223098 +3.6167 715.223098 +5.5243 705.380579 +9.4129 659.448820 +23.4703 606.955382 +25.0162 610.236221 +30.9820 623.359581 +32.4677 616.797901 +34.3415 629.921261 +39.1519 639.763781 +40.1487 643.044620 +43.8551 639.763781 +45.1980 639.763781 +50.2415 643.044620 +50.7511 613.517061 +52.4188 652.887140 +59.6859 662.729660 +61.2516 698.818899 +71.6546 738.188978 +72.5283 764.435697 +87.9457 721.784778 +88.7923 725.065618 +91.6167 764.435697 +99.6578 902.230973 +99.8003 905.511812 +99.9720 905.511812 +100.1892 902.230973 +100.5724 882.545933 +102.0104 882.545933 +102.8041 875.984253 +103.0804 872.703413 +107.3975 921.916012 +107.9219 915.354332 +111.8075 977.690290 +112.3607 974.409450 +113.7989 1003.937009 +115.6245 967.847771 +119.3377 1082.677167 +120.3016 1040.026248 +122.6318 1030.183729 +125.0204 1056.430448 +125.1988 1089.238847 +127.7871 1076.115487 +129.8891 997.375330 +130.3262 974.409450 +130.9400 971.128610 +131.4143 1020.341209 +142.6996 935.039372 +147.6842 905.511812 +154.3627 902.230973 +155.0489 889.107613 +155.6592 872.703413 +156.1879 846.456694 +156.8340 869.422573 +157.3818 875.984253 +159.8910 846.456694 +159.9999 856.299214 +163.1963 866.141734 +164.7320 869.422573 +164.9323 859.580054 +165.1204 849.737534 +e diff --git a/reference/dusky.trk b/reference/dusky.trk new file mode 100755 index 000000000..26d099c65 --- /dev/null +++ b/reference/dusky.trk @@ -0,0 +1,63 @@ +$PMGNTRK,4122.991,N,08244.336,W,00190,M,030730.19,A,,170804*67 +$PMGNTRK,4120.566,N,08245.501,W,00217,M,031055.19,A,,170804*6B +$PMGNTRK,4120.585,N,08245.862,W,00218,M,031137.19,A,,170804*64 +$PMGNTRK,4120.513,N,08246.233,W,00218,M,031200.20,A,,170804*6B +$PMGNTRK,4120.853,N,08248.390,W,00215,M,031334.19,A,,170804*65 +$PMGNTRK,4121.287,N,08252.846,W,00201,M,031645.20,A,,170804*60 +$PMGNTRK,4124.603,N,08308.485,W,00185,M,032817.22,A,,170804*67 +$PMGNTRK,4125.265,N,08310.040,W,00186,M,032933.22,A,,170804*62 +$PMGNTRK,4127.211,N,08316.436,W,00190,M,033426.23,A,,170804*6E +$PMGNTRK,4127.905,N,08317.885,W,00188,M,033539.23,A,,170804*63 +$PMGNTRK,4128.434,N,08319.936,W,00192,M,033711.23,A,,170804*67 +$PMGNTRK,4130.583,N,08324.711,W,00195,M,034107.24,A,,170804*60 +$PMGNTRK,4130.816,N,08325.823,W,00196,M,034156.24,A,,170804*69 +$PMGNTRK,4132.270,N,08329.653,W,00195,M,034458.24,A,,170804*6C +$PMGNTRK,4132.495,N,08331.180,W,00195,M,034604.24,A,,170804*6A +$PMGNTRK,4134.715,N,08336.218,W,00196,M,035012.25,A,,170804*60 +$PMGNTRK,4134.982,N,08336.689,W,00187,M,035037.26,A,,170804*68 +$PMGNTRK,4135.439,N,08338.524,W,00199,M,035159.25,A,,170804*6B +$PMGNTRK,4135.725,N,08346.944,W,00202,M,035757.27,A,,170804*6D +$PMGNTRK,4136.163,N,08348.663,W,00213,M,035914.28,A,,170804*68 +$PMGNTRK,4135.898,N,08400.725,W,00225,M,040751.28,A,,170804*66 +$PMGNTRK,4135.563,N,08401.634,W,00233,M,040834.28,A,,170804*64 +$PMGNTRK,4135.463,N,08419.515,W,00220,M,042119.30,A,,170804*63 +$PMGNTRK,4135.256,N,08420.457,W,00221,M,042200.30,A,,170804*64 +$PMGNTRK,4136.223,N,08423.467,W,00233,M,042419.30,A,,170804*68 +$PMGNTRK,4136.841,N,08432.759,W,00275,M,043059.32,A,,170804*69 +$PMGNTRK,4136.921,N,08432.885,W,00276,M,043110.32,A,,170804*6F +$PMGNTRK,4136.784,N,08432.963,W,00276,M,043129.32,A,,170804*6D +$PMGNTRK,4136.784,N,08433.215,W,00275,M,043213.32,A,,170804*6F +$PMGNTRK,4137.115,N,08433.174,W,00269,M,043246.33,A,,170804*68 +$PMGNTRK,4138.362,N,08433.212,W,00269,M,043425.32,A,,170804*64 +$PMGNTRK,4138.607,N,08434.073,W,00267,M,043521.32,A,,170804*6B +$PMGNTRK,4138.623,N,08434.393,W,00266,M,043541.33,A,,170804*66 +$PMGNTRK,4138.600,N,08439.404,W,00281,M,044011.33,A,,170804*6D +$PMGNTRK,4138.462,N,08439.984,W,00279,M,044042.34,A,,170804*68 +$PMGNTRK,4138.239,N,08444.484,W,00298,M,044508.34,A,,170804*63 +$PMGNTRK,4138.120,N,08445.106,W,00297,M,044555.33,A,,170804*66 +$PMGNTRK,4138.074,N,08446.774,W,00306,M,044739.34,A,,170804*60 +$PMGNTRK,4137.843,N,08448.870,W,00295,M,044931.35,A,,170804*6A +$PMGNTRK,4137.764,N,08453.178,W,00330,M,045258.34,A,,170804*61 +$PMGNTRK,4137.955,N,08454.267,W,00317,M,045357.35,A,,170804*6D +$PMGNTRK,4137.894,N,08456.970,W,00314,M,045620.36,A,,170804*6B +$PMGNTRK,4138.096,N,08459.729,W,00322,M,045913.35,A,,170804*6A +$PMGNTRK,4138.095,N,08459.936,W,00332,M,045934.37,A,,170804*6F +$PMGNTRK,4138.097,N,08502.940,W,00328,M,050333.36,A,,170804*60 +$PMGNTRK,4136.276,N,08502.817,W,00304,M,050534.38,A,,170804*61 +$PMGNTRK,4135.918,N,08502.984,W,00297,M,050557.38,A,,170804*64 +$PMGNTRK,4135.492,N,08503.411,W,00296,M,050629.37,A,,170804*6F +$PMGNTRK,4135.093,N,08503.545,W,00311,M,050654.38,A,,170804*61 +$PMGNTRK,4125.307,N,08503.218,W,00285,M,051640.39,A,,170804*68 +$PMGNTRK,4121.266,N,08505.268,W,00276,M,052059.39,A,,170804*6A +$PMGNTRK,4115.473,N,08505.236,W,00275,M,052641.40,A,,170804*66 +$PMGNTRK,4114.916,N,08505.515,W,00271,M,052716.41,A,,170804*69 +$PMGNTRK,4114.388,N,08505.566,W,00266,M,052747.41,A,,170804*62 +$PMGNTRK,4113.962,N,08505.792,W,00258,M,052814.41,A,,170804*66 +$PMGNTRK,4113.476,N,08506.163,W,00265,M,052847.41,A,,170804*6D +$PMGNTRK,4113.012,N,08506.299,W,00267,M,052915.40,A,,170804*68 +$PMGNTRK,4110.836,N,08506.233,W,00258,M,053124.41,A,,170804*63 +$PMGNTRK,4110.746,N,08506.271,W,00261,M,053135.41,A,,170804*67 +$PMGNTRK,4110.661,N,08509.953,W,00264,M,053607.41,A,,170804*64 +$PMGNTRK,4109.329,N,08509.927,W,00265,M,053802.42,A,,170804*6F +$PMGNTRK,4109.315,N,08509.697,W,00262,M,053828.41,A,,170804*68 +$PMGNTRK,4109.278,N,08509.486,W,00259,M,053858.41,A,,170804*6F diff --git a/reference/earth-expertgps.kml b/reference/earth-expertgps.kml new file mode 100644 index 000000000..456a26b19 --- /dev/null +++ b/reference/earth-expertgps.kml @@ -0,0 +1,3441 @@ + + + + GPS device + + + + + + + normal + #route_n + + + highlight + #route_h + + + + + + + + + normal + #track_n + + + highlight + #track_h + + + + + + + + + normal + #waypoint_n + + + highlight + #waypoint_h + + + + + Waypoints + + 5066 + 2001-11-28T21:05:28Z + #waypoint + + -71.119277,42.438878,44.586548 + + + + 5067 + 2001-06-02T03:26:55Z + #waypoint + + -71.119689,42.439227,57.607200 + + + + 5096 + 2001-11-16T23:03:38Z + #waypoint + + -71.116146,42.438917,44.826904 + + + + 5142 + 2001-11-28T21:05:28Z + #waypoint + + -71.122044,42.443904,50.594727 + + + + 5156 + 2001-06-02T03:26:58Z + #waypoint + + -71.121447,42.447298,127.711200 + + + + 5224 + 2001-06-02T03:26:59Z + #waypoint + + -71.125094,42.454873,96.926400 + + + + 5229 + 2001-06-02T03:26:59Z + #waypoint + + -71.124988,42.459079,82.600800 + + + + 5237 + 2001-06-02T03:26:59Z + #waypoint + + -71.124474,42.456979,82.905600 + + + + 5254 + 2001-11-28T21:05:28Z + #waypoint + + -71.120990,42.454401,66.696655 + + + + 5258 + 2001-11-07T23:53:41Z + #waypoint + + -71.121746,42.451442,74.627442 + + + + 5264 + 2001-11-28T21:05:28Z + #waypoint + + -71.120660,42.454404,65.254761 + + + + 526708 + 2001-06-02T03:27:00Z + #waypoint + + -71.121045,42.457761,77.419200 + + + + 526750 + 2001-06-02T03:27:00Z + #waypoint + + -71.120313,42.457089,74.676000 + + + + 527614 + 2001-11-07T23:53:41Z + #waypoint + + -71.119676,42.456592,78.713135 + + + + 527631 + 2001-11-07T23:53:41Z + #waypoint + + -71.119356,42.456252,78.713135 + + + + 5278 + 2001-06-02T03:27:00Z + #waypoint + + -71.119135,42.458148,68.275200 + + + + 5289 + 2001-06-02T03:27:01Z + #waypoint + + -71.117693,42.459377,64.008000 + + + + 5374FIRE + 2001-11-28T21:05:28Z + #waypoint + + -71.119828,42.464183,52.997925 + + + + 5376 + 2001-06-02T03:27:02Z + #waypoint + + -71.119399,42.465650,56.388000 + + + + 6006 + 2001-06-02T03:26:55Z + #waypoint + + -71.114456,42.439018,56.388000 + + + + 6006BLUE + 2001-11-28T21:05:28Z + #waypoint + + -71.114803,42.438594,46.028564 + + + + 6014MEADOW + 2001-11-28T21:05:28Z + #waypoint + + -71.113223,42.436757,37.616943 + + + + 6029 + 2001-06-02T03:26:55Z + #waypoint + + -71.113220,42.441754,56.388000 + + + + 6053 + 2001-06-02T03:27:05Z + #waypoint + + -71.109075,42.436243,50.292000 + + + + 6066 + 2001-06-02T03:26:57Z + #waypoint + + -71.107500,42.439250,25.603200 + + + + 6067 + 2001-06-02T03:26:57Z + #waypoint + + -71.107582,42.439764,34.442400 + + + + 6071 + 2001-06-02T03:26:57Z + #waypoint + + -71.105874,42.434766,30.480000 + + + + 6073 + 2001-06-02T03:26:56Z + #waypoint + + -71.106599,42.433304,15.240000 + + + + 6084 + 2001-06-02T03:26:57Z + #waypoint + + -71.104772,42.437338,37.795200 + + + + 6130 + 2001-06-02T03:26:55Z + #waypoint + + -71.110975,42.442196,64.008000 + + + + 6131 + 2001-06-02T03:26:58Z + #waypoint + + -71.111441,42.442981,64.008000 + + + + 6153 + 2001-06-02T03:27:05Z + #waypoint + + -71.108882,42.444773,62.788800 + + + + 6171 + 2001-06-02T03:27:05Z + #waypoint + + -71.106301,42.443592,55.473600 + + + + 6176 + 2001-06-02T03:27:04Z + #waypoint + + -71.106624,42.447804,62.484000 + + + + 6177 + 2001-06-02T03:27:04Z + #waypoint + + -71.106158,42.448448,62.179200 + + + + 6272 + 2001-06-02T03:26:55Z + #waypoint + + -71.106783,42.453415,69.799200 + + + + 6272 + 2001-06-02T03:26:56Z + #waypoint + + -71.107253,42.453434,73.152000 + + + + 6278 + 2001-06-02T03:27:04Z + #waypoint + + -71.106771,42.458298,70.104000 + + + + 6280 + 2001-11-16T23:03:38Z + #waypoint + + -71.105413,42.451430,57.564209 + + + + 6283 + 2001-11-16T23:03:38Z + #waypoint + + -71.105206,42.453845,66.696655 + + + + 6289 + 2001-11-16T23:03:38Z + #waypoint + + -71.106170,42.459986,72.945191 + + + + 6297 + 2001-06-02T03:27:04Z + #waypoint + + -71.105116,42.457616,72.847200 + + + + 6328 + 2001-06-02T03:27:02Z + #waypoint + + -71.113574,42.467110,53.644800 + + + + 6354 + 2001-06-02T03:27:03Z + #waypoint + + -71.109863,42.464202,43.891200 + + + + 635722 + 2001-06-02T03:27:02Z + #waypoint + + -71.110067,42.466459,48.768000 + + + + 635783 + 2001-06-02T03:27:02Z + #waypoint + + -71.109410,42.466557,49.072800 + + + + 6373 + 2001-06-02T03:27:03Z + #waypoint + + -71.107117,42.463495,62.484000 + + + + 6634 + 2001-06-02T03:26:56Z + #waypoint + + -71.110241,42.401051,3.962400 + + + + 6979 + 2001-06-02T03:26:56Z + #waypoint + + -71.106532,42.432621,13.411200 + + + + 6997 + 2001-11-16T23:03:38Z + #waypoint + + -71.107883,42.431033,34.012085 + + + + BEAR HILL + 2001-06-02T03:27:03Z + #waypoint + + -71.107360,42.465687,87.782400 + + + + BELLEVUE + 2001-06-02T00:18:15Z + #waypoint + + -71.107628,42.430950,23.469600 + + + + 6016 + 2001-11-28T21:05:28Z + #waypoint + + -71.114079,42.438666,43.384766 + + + + 5236BRIDGE + 2001-06-02T03:26:59Z + #waypoint + + -71.124651,42.456469,89.916000 + + + + 5376BRIDGE + 2001-06-02T03:27:01Z + #waypoint + + -71.119815,42.465759,55.473600 + + + + 6181CROSS + 2001-06-02T03:27:05Z + #waypoint + + -71.105878,42.442993,52.730400 + + + + 6042CROSS + 2001-06-02T03:27:05Z + #waypoint + + -71.109664,42.435472,45.110400 + + + + DARKHOLLPO + #waypoint + + -71.103646,42.458516,0.000000 + + + + 6121DEAD + 2001-06-02T03:26:57Z + #waypoint + + -71.112675,42.443109,56.083200 + + + + 5179DEAD + 2001-06-02T03:26:59Z + #waypoint + + -71.119298,42.449866,117.043200 + + + + 5299DEAD + 2001-06-02T03:27:01Z + #waypoint + + -71.116524,42.459629,69.494400 + + + + 5376DEAD + 2001-06-02T03:27:02Z + #waypoint + + -71.119148,42.465485,56.997600 + + + + 6353DEAD + 2001-06-02T03:27:03Z + #waypoint + + -71.109986,42.462776,46.939200 + + + + 6155DEAD + 2001-06-02T03:27:04Z + #waypoint + + -71.108784,42.446793,61.264800 + + + + GATE14 + 2001-06-02T03:26:59Z + #waypoint + + -71.126602,42.451204,110.947200 + + + + GATE16 + 2001-06-02T03:27:00Z + #waypoint + + -71.122078,42.458499,77.724000 + + + + GATE17 + 2001-06-02T03:27:01Z + #waypoint + + -71.119238,42.459376,65.836800 + + + + GATE19 + 2001-06-02T03:27:02Z + #waypoint + + -71.119240,42.466353,57.302400 + + + + GATE21 + 2001-06-02T03:27:03Z + #waypoint + + -71.107697,42.468655,49.377600 + + + + GATE24 + 2001-06-02T03:27:03Z + #waypoint + + -71.102973,42.456718,81.076800 + + + + GATE5 + 2001-11-28T21:05:28Z + #waypoint + + -71.107690,42.430847,21.515015 + + + + GATE6 + 2001-11-07T23:53:41Z + #waypoint + + -71.109236,42.431240,26.561890 + + + + 6077LOGS + 2001-06-02T00:18:16Z + #waypoint + + -71.106556,42.439502,32.004000 + + + + 5148NANEPA + 2001-11-07T23:53:41Z + #waypoint + + -71.122320,42.449765,119.809082 + + + + 5267OBSTAC + 2001-06-02T03:27:00Z + #waypoint + + -71.119845,42.457388,73.761600 + + + + PANTHRCAVE + 2001-11-07T23:53:41Z + #waypoint + + -71.109942,42.434980,45.307495 + + + + 5252PURPLE + 2001-11-07T23:53:41Z + #waypoint + + -71.121211,42.453256,77.992066 + + + + 5287WATER + 2001-06-02T03:27:01Z + #waypoint + + -71.117481,42.457734,67.970400 + + + + 5239ROAD + 2001-06-02T03:27:00Z + #waypoint + + -71.124574,42.459278,81.076800 + + + + 5278ROAD + 2001-06-02T03:27:01Z + #waypoint + + -71.118991,42.458782,67.360800 + + + + 5058ROAD + 2001-06-02T00:18:14Z + #waypoint + + -71.120925,42.439993,53.949600 + + + + SHEEPFOLD + 2001-06-02T00:18:13Z + #waypoint + + -71.106782,42.453415,69.799200 + + + + SOAPBOX + 2001-06-02T03:27:04Z + #waypoint + + -71.107483,42.455956,64.008000 + + + + 5376STREAM + 2001-11-07T23:53:41Z + #waypoint + + -71.119328,42.465913,64.533692 + + + + 5144SUMMIT + 2001-11-28T21:05:28Z + #waypoint + + -71.122845,42.445359,61.649902 + + + + 5150TANK + 2001-06-02T00:18:16Z + #waypoint + + -71.121676,42.441727,67.360800 + + + + + Tracks + + + + + Distance 4.8 mi + Min Alt 3.281 ft + Max Alt 22.966 ft + Max Speed 25.5 mph + Avg Speed 2.4 mph + Start Time 2002-05-25T17:06:21Z + End Time 2002-05-25T19:05:57Z + ]]> + + + 2002-05-25T17:06:21Z + 2002-05-25T19:05:57Z + + + Points + + -0 + + + Longitude: -91.610350 + Latitude: 30.062183 + Altitude: 3.281 ft + Speed: 0.0 mph + Heading: 300.1 + Time: 2002-05-25T17:06:21Z + + ]]> + + -91.610350 + 30.062183 + 66 + + 2002-05-25T17:06:21Z + #track + + -91.610350,30.062183,1.000000 + + + + -1 + + + Longitude: -91.610567 + Latitude: 30.062783 + Speed: 0.7 mph + Heading: 342.6 + Time: 2002-05-25T17:09:55Z + + ]]> + + -91.610567 + 30.062783 + 66 + + 2002-05-25T17:09:55Z + #track + + -91.610567,30.062783,0.000000 + + + + -2 + + + Longitude: -91.608267 + Latitude: 30.062700 + Speed: 4.0 mph + Heading: 92.4 + Time: 2002-05-25T17:12:00Z + + ]]> + + -91.608267 + 30.062700 + 66 + + 2002-05-25T17:12:00Z + #track + + -91.608267,30.062700,0.000000 + + + + -3 + + + Longitude: -91.607383 + Latitude: 30.062333 + Speed: 4.4 mph + Heading: 115.6 + Time: 2002-05-25T17:12:48Z + + ]]> + + -91.607383 + 30.062333 + 66 + + 2002-05-25T17:12:48Z + #track + + -91.607383,30.062333,0.000000 + + + + -4 + + + Longitude: -91.605283 + Latitude: 30.061533 + Speed: 4.4 mph + Heading: 113.8 + Time: 2002-05-25T17:14:41Z + + ]]> + + -91.605283 + 30.061533 + 66 + + 2002-05-25T17:14:41Z + #track + + -91.605283,30.061533,0.000000 + + + + -5 + + + Longitude: -91.599400 + Latitude: 30.059783 + Speed: 8.6 mph + Heading: 109.0 + Time: 2002-05-25T17:17:16Z + + ]]> + + -91.599400 + 30.059783 + 66 + + 2002-05-25T17:17:16Z + #track + + -91.599400,30.059783,0.000000 + + + + -6 + + + Longitude: -91.596683 + Latitude: 30.057800 + Speed: 25.5 mph + Heading: 130.1 + Time: 2002-05-25T17:17:46Z + + ]]> + + -91.596683 + 30.057800 + 66 + + 2002-05-25T17:17:46Z + #track + + -91.596683,30.057800,0.000000 + + + + -7 + + + Longitude: -91.594900 + Latitude: 30.055383 + Speed: 21.0 mph + Heading: 147.4 + Time: 2002-05-25T17:18:20Z + + ]]> + + -91.594900 + 30.055383 + 66 + + 2002-05-25T17:18:20Z + #track + + -91.594900,30.055383,0.000000 + + + + -8 + + + Longitude: -91.592617 + Latitude: 30.053883 + Speed: 15.1 mph + Heading: 127.2 + Time: 2002-05-25T17:19:01Z + + ]]> + + -91.592617 + 30.053883 + 66 + + 2002-05-25T17:19:01Z + #track + + -91.592617,30.053883,0.000000 + + + + -9 + + + Longitude: -91.589750 + Latitude: 30.049733 + Speed: 11.5 mph + Heading: 149.1 + Time: 2002-05-25T17:20:46Z + + ]]> + + -91.589750 + 30.049733 + 66 + + 2002-05-25T17:20:46Z + #track + + -91.589750,30.049733,0.000000 + + + + -10 + + + Longitude: -91.589883 + Latitude: 30.049017 + Speed: 7.5 mph + Heading: 189.1 + Time: 2002-05-25T17:21:10Z + + ]]> + + -91.589883 + 30.049017 + 66 + + 2002-05-25T17:21:10Z + #track + + -91.589883,30.049017,0.000000 + + + + -11 + + + Longitude: -91.592933 + Latitude: 30.048800 + Speed: 16.1 mph + Heading: 265.3 + Time: 2002-05-25T17:21:51Z + + ]]> + + -91.592933 + 30.048800 + 66 + + 2002-05-25T17:21:51Z + #track + + -91.592933,30.048800,0.000000 + + + + -12 + + + Longitude: -91.596450 + Latitude: 30.046233 + Speed: 22.5 mph + Heading: 229.9 + Time: 2002-05-25T17:22:35Z + + ]]> + + -91.596450 + 30.046233 + 66 + + 2002-05-25T17:22:35Z + #track + + -91.596450,30.046233,0.000000 + + + + -13 + + + Longitude: -91.598717 + Latitude: 30.045517 + Speed: 15.8 mph + Heading: 250.0 + Time: 2002-05-25T17:23:08Z + + ]]> + + -91.598717 + 30.045517 + 66 + + 2002-05-25T17:23:08Z + #track + + -91.598717,30.045517,0.000000 + + + + -14 + + + Longitude: -91.600267 + Latitude: 30.047300 + Speed: 0.2 mph + Heading: 323.0 + Time: 2002-05-25T18:04:23Z + + ]]> + + -91.600267 + 30.047300 + 66 + + 2002-05-25T18:04:23Z + #track + + -91.600267,30.047300,0.000000 + + + + -15 + + + Longitude: -91.599633 + Latitude: 30.047000 + Altitude: 6.562 ft + Speed: 1.5 mph + Heading: 118.7 + Time: 2002-05-25T18:06:04Z + + ]]> + + -91.599633 + 30.047000 + 66 + + 2002-05-25T18:06:04Z + #track + + -91.599633,30.047000,2.000000 + + + + -16 + + + Longitude: -91.599467 + Latitude: 30.046433 + Speed: 2.3 mph + Heading: 165.8 + Time: 2002-05-25T18:07:06Z + + ]]> + + -91.599467 + 30.046433 + 66 + + 2002-05-25T18:07:06Z + #track + + -91.599467,30.046433,0.000000 + + + + -17 + + + Longitude: -91.598950 + Latitude: 30.046200 + Altitude: 3.281 ft + Speed: 1.7 mph + Heading: 117.5 + Time: 2002-05-25T18:08:18Z + + ]]> + + -91.598950 + 30.046200 + 66 + + 2002-05-25T18:08:18Z + #track + + -91.598950,30.046200,1.000000 + + + + -18 + + + Longitude: -91.597733 + Latitude: 30.046367 + Speed: 2.2 mph + Heading: 81.0 + Time: 2002-05-25T18:10:20Z + + ]]> + + -91.597733 + 30.046367 + 66 + + 2002-05-25T18:10:20Z + #track + + -91.597733,30.046367,0.000000 + + + + -19 + + + Longitude: -91.597167 + Latitude: 30.046350 + Speed: 2.5 mph + Heading: 92.0 + Time: 2002-05-25T18:11:09Z + + ]]> + + -91.597167 + 30.046350 + 66 + + 2002-05-25T18:11:09Z + #track + + -91.597167,30.046350,0.000000 + + + + -20 + + + Longitude: -91.596333 + Latitude: 30.046783 + Speed: 3.0 mph + Heading: 59.0 + Time: 2002-05-25T18:12:18Z + + ]]> + + -91.596333 + 30.046783 + 66 + + 2002-05-25T18:12:18Z + #track + + -91.596333,30.046783,0.000000 + + + + -21 + + + Longitude: -91.595200 + Latitude: 30.047450 + Speed: 2.4 mph + Heading: 55.8 + Time: 2002-05-25T18:14:22Z + + ]]> + + -91.595200 + 30.047450 + 66 + + 2002-05-25T18:14:22Z + #track + + -91.595200,30.047450,0.000000 + + + + -22 + + + Longitude: -91.594767 + Latitude: 30.047800 + Altitude: 6.562 ft + Speed: 3.0 mph + Heading: 47.0 + Time: 2002-05-25T18:15:04Z + + ]]> + + -91.594767 + 30.047800 + 66 + + 2002-05-25T18:15:04Z + #track + + -91.594767,30.047800,2.000000 + + + + -23 + + + Longitude: -91.594083 + Latitude: 30.048250 + Altitude: 3.281 ft + Speed: 2.6 mph + Heading: 52.8 + Time: 2002-05-25T18:16:14Z + + ]]> + + -91.594083 + 30.048250 + 66 + + 2002-05-25T18:16:14Z + #track + + -91.594083,30.048250,1.000000 + + + + -24 + + + Longitude: -91.593800 + Latitude: 30.048683 + Altitude: 3.281 ft + Speed: 2.6 mph + Heading: 29.5 + Time: 2002-05-25T18:17:01Z + + ]]> + + -91.593800 + 30.048683 + 66 + + 2002-05-25T18:17:01Z + #track + + -91.593800,30.048683,1.000000 + + + + -25 + + + Longitude: -91.593850 + Latitude: 30.049350 + Speed: 2.5 mph + Heading: 356.3 + Time: 2002-05-25T18:18:07Z + + ]]> + + -91.593850 + 30.049350 + 66 + + 2002-05-25T18:18:07Z + #track + + -91.593850,30.049350,0.000000 + + + + -26 + + + Longitude: -91.593983 + Latitude: 30.050317 + Altitude: 6.562 ft + Speed: 2.3 mph + Heading: 353.2 + Time: 2002-05-25T18:19:51Z + + ]]> + + -91.593983 + 30.050317 + 66 + + 2002-05-25T18:19:51Z + #track + + -91.593983,30.050317,2.000000 + + + + -27 + + + Longitude: -91.594117 + Latitude: 30.050783 + Speed: 2.5 mph + Heading: 346.0 + Time: 2002-05-25T18:20:39Z + + ]]> + + -91.594117 + 30.050783 + 66 + + 2002-05-25T18:20:39Z + #track + + -91.594117,30.050783,0.000000 + + + + -28 + + + Longitude: -91.594367 + Latitude: 30.051233 + Speed: 2.8 mph + Heading: 334.3 + Time: 2002-05-25T18:21:24Z + + ]]> + + -91.594367 + 30.051233 + 66 + + 2002-05-25T18:21:24Z + #track + + -91.594367,30.051233,0.000000 + + + + -29 + + + Longitude: -91.594367 + Latitude: 30.051800 + Speed: 2.7 mph + Heading: 0.0 + Time: 2002-05-25T18:22:17Z + + ]]> + + -91.594367 + 30.051800 + 66 + + 2002-05-25T18:22:17Z + #track + + -91.594367,30.051800,0.000000 + + + + -30 + + + Longitude: -91.594667 + Latitude: 30.052217 + Speed: 2.0 mph + Heading: 328.1 + Time: 2002-05-25T18:23:18Z + + ]]> + + -91.594667 + 30.052217 + 66 + + 2002-05-25T18:23:18Z + #track + + -91.594667,30.052217,0.000000 + + + + -31 + + + Longitude: -91.594683 + Latitude: 30.053017 + Speed: 2.5 mph + Heading: 359.0 + Time: 2002-05-25T18:24:37Z + + ]]> + + -91.594683 + 30.053017 + 66 + + 2002-05-25T18:24:37Z + #track + + -91.594683,30.053017,0.000000 + + + + -32 + + + Longitude: -91.595200 + Latitude: 30.054867 + Altitude: 19.685 ft + Speed: 2.2 mph + Heading: 346.4 + Time: 2002-05-25T18:28:13Z + + ]]> + + -91.595200 + 30.054867 + 66 + + 2002-05-25T18:28:13Z + #track + + -91.595200,30.054867,6.000000 + + + + -33 + + + Longitude: -91.594933 + Latitude: 30.053733 + Altitude: 6.562 ft + Speed: 1.4 mph + Heading: 168.5 + Time: 2002-05-25T18:31:36Z + + ]]> + + -91.594933 + 30.053733 + 66 + + 2002-05-25T18:31:36Z + #track + + -91.594933,30.053733,2.000000 + + + + -34 + + + Longitude: -91.594783 + Latitude: 30.053183 + Speed: 1.8 mph + Heading: 166.7 + Time: 2002-05-25T18:32:56Z + + ]]> + + -91.594783 + 30.053183 + 66 + + 2002-05-25T18:32:56Z + #track + + -91.594783,30.053183,0.000000 + + + + -35 + + + Longitude: -91.594833 + Latitude: 30.052633 + Speed: 2.1 mph + Heading: 184.5 + Time: 2002-05-25T18:34:02Z + + ]]> + + -91.594833 + 30.052633 + 66 + + 2002-05-25T18:34:02Z + #track + + -91.594833,30.052633,0.000000 + + + + -36 + + + Longitude: -91.595433 + Latitude: 30.052450 + Speed: 1.1 mph + Heading: 250.6 + Time: 2002-05-25T18:36:03Z + + ]]> + + -91.595433 + 30.052450 + 66 + + 2002-05-25T18:36:03Z + #track + + -91.595433,30.052450,0.000000 + + + + -37 + + + Longitude: -91.595967 + Latitude: 30.052483 + Speed: 2.6 mph + Heading: 274.1 + Time: 2002-05-25T18:36:48Z + + ]]> + + -91.595967 + 30.052483 + 66 + + 2002-05-25T18:36:48Z + #track + + -91.595967,30.052483,0.000000 + + + + -38 + + + Longitude: -91.596783 + Latitude: 30.052650 + Altitude: 3.281 ft + Speed: 2.8 mph + Heading: 283.3 + Time: 2002-05-25T18:37:52Z + + ]]> + + -91.596783 + 30.052650 + 66 + + 2002-05-25T18:37:52Z + #track + + -91.596783,30.052650,1.000000 + + + + -39 + + + Longitude: -91.597850 + Latitude: 30.053133 + Speed: 3.0 mph + Heading: 297.6 + Time: 2002-05-25T18:39:18Z + + ]]> + + -91.597850 + 30.053133 + 66 + + 2002-05-25T18:39:18Z + #track + + -91.597850,30.053133,0.000000 + + + + -40 + + + Longitude: -91.597967 + Latitude: 30.053617 + Speed: 2.2 mph + Heading: 348.2 + Time: 2002-05-25T18:40:15Z + + ]]> + + -91.597967 + 30.053617 + 66 + + 2002-05-25T18:40:15Z + #track + + -91.597967,30.053617,0.000000 + + + + -41 + + + Longitude: -91.597767 + Latitude: 30.053967 + Altitude: 19.685 ft + Speed: 1.4 mph + Heading: 26.3 + Time: 2002-05-25T18:41:25Z + + ]]> + + -91.597767 + 30.053967 + 66 + + 2002-05-25T18:41:25Z + #track + + -91.597767,30.053967,6.000000 + + + + -42 + + + Longitude: -91.598083 + Latitude: 30.053617 + Speed: 1.5 mph + Heading: 218.0 + Time: 2002-05-25T18:42:37Z + + ]]> + + -91.598083 + 30.053617 + 66 + + 2002-05-25T18:42:37Z + #track + + -91.598083,30.053617,0.000000 + + + + -43 + + + Longitude: -91.597917 + Latitude: 30.053200 + Speed: 1.3 mph + Heading: 161.0 + Time: 2002-05-25T18:44:01Z + + ]]> + + -91.597917 + 30.053200 + 66 + + 2002-05-25T18:44:01Z + #track + + -91.597917,30.053200,0.000000 + + + + -44 + + + Longitude: -91.597517 + Latitude: 30.052817 + Speed: 1.1 mph + Heading: 137.9 + Time: 2002-05-25T18:45:53Z + + ]]> + + -91.597517 + 30.052817 + 66 + + 2002-05-25T18:45:53Z + #track + + -91.597517,30.052817,0.000000 + + + + -45 + + + Longitude: -91.596933 + Latitude: 30.052567 + Speed: 2.3 mph + Heading: 116.3 + Time: 2002-05-25T18:46:54Z + + ]]> + + -91.596933 + 30.052567 + 66 + + 2002-05-25T18:46:54Z + #track + + -91.596933,30.052567,0.000000 + + + + -46 + + + Longitude: -91.596433 + Latitude: 30.052333 + Speed: 2.6 mph + Heading: 118.4 + Time: 2002-05-25T18:47:42Z + + ]]> + + -91.596433 + 30.052333 + 66 + + 2002-05-25T18:47:42Z + #track + + -91.596433,30.052333,0.000000 + + + + -47 + + + Longitude: -91.595683 + Latitude: 30.052250 + Speed: 2.8 mph + Heading: 97.3 + Time: 2002-05-25T18:48:41Z + + ]]> + + -91.595683 + 30.052250 + 66 + + 2002-05-25T18:48:41Z + #track + + -91.595683,30.052250,0.000000 + + + + -48 + + + Longitude: -91.595017 + Latitude: 30.052217 + Speed: 2.0 mph + Heading: 93.3 + Time: 2002-05-25T18:49:52Z + + ]]> + + -91.595017 + 30.052217 + 66 + + 2002-05-25T18:49:52Z + #track + + -91.595017,30.052217,0.000000 + + + + -49 + + + Longitude: -91.594700 + Latitude: 30.051883 + Speed: 1.9 mph + Heading: 140.6 + Time: 2002-05-25T18:50:49Z + + ]]> + + -91.594700 + 30.051883 + 66 + + 2002-05-25T18:50:49Z + #track + + -91.594700,30.051883,0.000000 + + + + -50 + + + Longitude: -91.594400 + Latitude: 30.051050 + Speed: 2.6 mph + Heading: 162.7 + Time: 2002-05-25T18:52:14Z + + ]]> + + -91.594400 + 30.051050 + 66 + + 2002-05-25T18:52:14Z + #track + + -91.594400,30.051050,0.000000 + + + + -51 + + + Longitude: -91.594233 + Latitude: 30.050567 + Speed: 3.0 mph + Heading: 163.3 + Time: 2002-05-25T18:52:56Z + + ]]> + + -91.594233 + 30.050567 + 66 + + 2002-05-25T18:52:56Z + #track + + -91.594233,30.050567,0.000000 + + + + -52 + + + Longitude: -91.594100 + Latitude: 30.050183 + Speed: 2.4 mph + Heading: 163.3 + Time: 2002-05-25T18:53:38Z + + ]]> + + -91.594100 + 30.050183 + 66 + + 2002-05-25T18:53:38Z + #track + + -91.594100,30.050183,0.000000 + + + + -53 + + + Longitude: -91.593717 + Latitude: 30.049100 + Speed: 3.0 mph + Heading: 163.0 + Time: 2002-05-25T18:55:11Z + + ]]> + + -91.593717 + 30.049100 + 66 + + 2002-05-25T18:55:11Z + #track + + -91.593717,30.049100,0.000000 + + + + -54 + + + Longitude: -91.594250 + Latitude: 30.048450 + Speed: 2.5 mph + Heading: 215.4 + Time: 2002-05-25T18:56:32Z + + ]]> + + -91.594250 + 30.048450 + 66 + + 2002-05-25T18:56:32Z + #track + + -91.594250,30.048450,0.000000 + + + + -55 + + + Longitude: -91.594750 + Latitude: 30.048083 + Speed: 2.7 mph + Heading: 229.7 + Time: 2002-05-25T18:57:24Z + + ]]> + + -91.594750 + 30.048083 + 66 + + 2002-05-25T18:57:24Z + #track + + -91.594750,30.048083,0.000000 + + + + -56 + + + Longitude: -91.595450 + Latitude: 30.047500 + Altitude: 22.966 ft + Speed: 2.8 mph + Heading: 226.1 + Time: 2002-05-25T18:58:40Z + + ]]> + + -91.595450 + 30.047500 + 66 + + 2002-05-25T18:58:40Z + #track + + -91.595450,30.047500,7.000000 + + + + -57 + + + Longitude: -91.596000 + Latitude: 30.047067 + Speed: 3.3 mph + Heading: 227.7 + Time: 2002-05-25T18:59:28Z + + ]]> + + -91.596000 + 30.047067 + 66 + + 2002-05-25T18:59:28Z + #track + + -91.596000,30.047067,0.000000 + + + + -58 + + + Longitude: -91.596600 + Latitude: 30.046633 + Speed: 3.1 mph + Heading: 230.1 + Time: 2002-05-25T19:00:22Z + + ]]> + + -91.596600 + 30.046633 + 66 + + 2002-05-25T19:00:22Z + #track + + -91.596600,30.046633,0.000000 + + + + -59 + + + Longitude: -91.597650 + Latitude: 30.046400 + Speed: 3.0 mph + Heading: 255.6 + Time: 2002-05-25T19:01:41Z + + ]]> + + -91.597650 + 30.046400 + 66 + + 2002-05-25T19:01:41Z + #track + + -91.597650,30.046400,0.000000 + + + + -60 + + + Longitude: -91.598467 + Latitude: 30.046233 + Speed: 2.7 mph + Heading: 256.7 + Time: 2002-05-25T19:02:48Z + + ]]> + + -91.598467 + 30.046233 + 66 + + 2002-05-25T19:02:48Z + #track + + -91.598467,30.046233,0.000000 + + + + -61 + + + Longitude: -91.598967 + Latitude: 30.046317 + Speed: 2.0 mph + Heading: 281.0 + Time: 2002-05-25T19:03:43Z + + ]]> + + -91.598967 + 30.046317 + 66 + + 2002-05-25T19:03:43Z + #track + + -91.598967,30.046317,0.000000 + + + + -62 + + + Longitude: -91.599283 + Latitude: 30.046783 + Speed: 2.0 mph + Heading: 329.6 + Time: 2002-05-25T19:04:49Z + + ]]> + + -91.599283 + 30.046783 + 66 + + 2002-05-25T19:04:49Z + #track + + -91.599283,30.046783,0.000000 + + + + -63 + + + Longitude: -91.599667 + Latitude: 30.047133 + Speed: 1.8 mph + Heading: 316.5 + Time: 2002-05-25T19:05:57Z + + ]]> + + -91.599667 + 30.047133 + 66 + + 2002-05-25T19:05:57Z + #track + + -91.599667,30.047133,0.000000 + + + + + Path + #lineStyle + + 1 + + -91.610350,30.062183,1.000000 + -91.610567,30.062783,0.000000 + -91.608267,30.062700,0.000000 + -91.607383,30.062333,0.000000 + -91.605283,30.061533,0.000000 + -91.599400,30.059783,0.000000 + -91.596683,30.057800,0.000000 + -91.594900,30.055383,0.000000 + -91.592617,30.053883,0.000000 + -91.589750,30.049733,0.000000 + -91.589883,30.049017,0.000000 + -91.592933,30.048800,0.000000 + -91.596450,30.046233,0.000000 + -91.598717,30.045517,0.000000 + -91.600267,30.047300,0.000000 + -91.599633,30.047000,2.000000 + -91.599467,30.046433,0.000000 + -91.598950,30.046200,1.000000 + -91.597733,30.046367,0.000000 + -91.597167,30.046350,0.000000 + -91.596333,30.046783,0.000000 + -91.595200,30.047450,0.000000 + -91.594767,30.047800,2.000000 + -91.594083,30.048250,1.000000 + -91.593800,30.048683,1.000000 + -91.593850,30.049350,0.000000 + -91.593983,30.050317,2.000000 + -91.594117,30.050783,0.000000 + -91.594367,30.051233,0.000000 + -91.594367,30.051800,0.000000 + -91.594667,30.052217,0.000000 + -91.594683,30.053017,0.000000 + -91.595200,30.054867,6.000000 + -91.594933,30.053733,2.000000 + -91.594783,30.053183,0.000000 + -91.594833,30.052633,0.000000 + -91.595433,30.052450,0.000000 + -91.595967,30.052483,0.000000 + -91.596783,30.052650,1.000000 + -91.597850,30.053133,0.000000 + -91.597967,30.053617,0.000000 + -91.597767,30.053967,6.000000 + -91.598083,30.053617,0.000000 + -91.597917,30.053200,0.000000 + -91.597517,30.052817,0.000000 + -91.596933,30.052567,0.000000 + -91.596433,30.052333,0.000000 + -91.595683,30.052250,0.000000 + -91.595017,30.052217,0.000000 + -91.594700,30.051883,0.000000 + -91.594400,30.051050,0.000000 + -91.594233,30.050567,0.000000 + -91.594100,30.050183,0.000000 + -91.593717,30.049100,0.000000 + -91.594250,30.048450,0.000000 + -91.594750,30.048083,0.000000 + -91.595450,30.047500,7.000000 + -91.596000,30.047067,0.000000 + -91.596600,30.046633,0.000000 + -91.597650,30.046400,0.000000 + -91.598467,30.046233,0.000000 + -91.598967,30.046317,0.000000 + -91.599283,30.046783,0.000000 + -91.599667,30.047133,0.000000 + + + + + + + Routes + + BELLEVUE + + Points + + BELLEVUE + + + Longitude: -71.107628 + Latitude: 42.430950 + Altitude: 77.000 ft + Time: 2001-06-02T00:18:15Z + + ]]> + + -71.107628 + 42.430950 + 66 + + 2001-06-02T00:18:15Z + #route + + -71.107628,42.430950,23.469600 + + + + GATE6 + + + Longitude: -71.109236 + Latitude: 42.431240 + Altitude: 87.145 ft + Time: 2001-11-07T23:53:41Z + + ]]> + + -71.109236 + 42.431240 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.109236,42.431240,26.561890 + + + + PANTHRCAVE + + + Longitude: -71.109942 + Latitude: 42.434980 + Altitude: 148.647 ft + Time: 2001-11-07T23:53:41Z + + ]]> + + -71.109942 + 42.434980 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.109942,42.434980,45.307495 + + + + 6014MEADOW + + + Longitude: -71.113223 + Latitude: 42.436757 + Altitude: 123.415 ft + Time: 2001-11-28T21:05:28Z + + ]]> + + -71.113223 + 42.436757 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.113223,42.436757,37.616943 + + + + 6006 + + + Longitude: -71.114456 + Latitude: 42.439018 + Altitude: 185.000 ft + Time: 2001-06-02T03:26:55Z + + ]]> + + -71.114456 + 42.439018 + 66 + + 2001-06-02T03:26:55Z + #route + + -71.114456,42.439018,56.388000 + + + + 6006BLUE + + + Longitude: -71.114803 + Latitude: 42.438594 + Altitude: 151.012 ft + Time: 2001-11-28T21:05:28Z + + ]]> + + -71.114803 + 42.438594 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.114803,42.438594,46.028564 + + + + 5096 + + + Longitude: -71.116146 + Latitude: 42.438917 + Altitude: 147.070 ft + Time: 2001-11-16T23:03:38Z + + ]]> + + -71.116146 + 42.438917 + 66 + + 2001-11-16T23:03:38Z + #route + + -71.116146,42.438917,44.826904 + + + + 5066 + + + Longitude: -71.119277 + Latitude: 42.438878 + Altitude: 146.281 ft + Time: 2001-11-28T21:05:28Z + + ]]> + + -71.119277 + 42.438878 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.119277,42.438878,44.586548 + + + + 5067 + + + Longitude: -71.119689 + Latitude: 42.439227 + Altitude: 189.000 ft + Time: 2001-06-02T03:26:55Z + + ]]> + + -71.119689 + 42.439227 + 66 + + 2001-06-02T03:26:55Z + #route + + -71.119689,42.439227,57.607200 + + + + 5058ROAD + + + Longitude: -71.120925 + Latitude: 42.439993 + Altitude: 177.000 ft + Time: 2001-06-02T00:18:14Z + + ]]> + + -71.120925 + 42.439993 + 66 + + 2001-06-02T00:18:14Z + #route + + -71.120925,42.439993,53.949600 + + + + 5150TANK + + + Longitude: -71.121676 + Latitude: 42.441727 + Altitude: 221.000 ft + Time: 2001-06-02T00:18:16Z + + ]]> + + -71.121676 + 42.441727 + 66 + + 2001-06-02T00:18:16Z + #route + + -71.121676,42.441727,67.360800 + + + + 5142 + + + Longitude: -71.122044 + Latitude: 42.443904 + Altitude: 165.993 ft + Time: 2001-11-28T21:05:28Z + + ]]> + + -71.122044 + 42.443904 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.122044,42.443904,50.594727 + + + + 5144SUMMIT + + + Longitude: -71.122845 + Latitude: 42.445359 + Altitude: 202.263 ft + Time: 2001-11-28T21:05:28Z + + ]]> + + -71.122845 + 42.445359 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.122845,42.445359,61.649902 + + + + 5156 + + + Longitude: -71.121447 + Latitude: 42.447298 + Altitude: 419.000 ft + Time: 2001-06-02T03:26:58Z + + ]]> + + -71.121447 + 42.447298 + 66 + + 2001-06-02T03:26:58Z + #route + + -71.121447,42.447298,127.711200 + + + + 5148NANEPA + + + Longitude: -71.122320 + Latitude: 42.449765 + Altitude: 393.074 ft + Time: 2001-11-07T23:53:41Z + + ]]> + + -71.122320 + 42.449765 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.122320,42.449765,119.809082 + + + + 5258 + + + Longitude: -71.121746 + Latitude: 42.451442 + Altitude: 244.841 ft + Time: 2001-11-07T23:53:41Z + + ]]> + + -71.121746 + 42.451442 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.121746,42.451442,74.627442 + + + + 5252PURPLE + + + Longitude: -71.121211 + Latitude: 42.453256 + Altitude: 255.879 ft + Time: 2001-11-07T23:53:41Z + + ]]> + + -71.121211 + 42.453256 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.121211,42.453256,77.992066 + + + + 527631 + + + Longitude: -71.119356 + Latitude: 42.456252 + Altitude: 258.245 ft + Time: 2001-11-07T23:53:41Z + + ]]> + + -71.119356 + 42.456252 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.119356,42.456252,78.713135 + + + + 527614 + + + Longitude: -71.119676 + Latitude: 42.456592 + Altitude: 258.245 ft + Time: 2001-11-07T23:53:41Z + + ]]> + + -71.119676 + 42.456592 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.119676,42.456592,78.713135 + + + + 5267OBSTAC + + + Longitude: -71.119845 + Latitude: 42.457388 + Altitude: 242.000 ft + Time: 2001-06-02T03:27:00Z + + ]]> + + -71.119845 + 42.457388 + 66 + + 2001-06-02T03:27:00Z + #route + + -71.119845,42.457388,73.761600 + + + + 5278 + + + Longitude: -71.119135 + Latitude: 42.458148 + Altitude: 224.000 ft + Time: 2001-06-02T03:27:00Z + + ]]> + + -71.119135 + 42.458148 + 66 + + 2001-06-02T03:27:00Z + #route + + -71.119135,42.458148,68.275200 + + + + 5289 + + + Longitude: -71.117693 + Latitude: 42.459377 + Altitude: 210.000 ft + Time: 2001-06-02T03:27:01Z + + ]]> + + -71.117693 + 42.459377 + 66 + + 2001-06-02T03:27:01Z + #route + + -71.117693,42.459377,64.008000 + + + + 5374FIRE + + + Longitude: -71.119828 + Latitude: 42.464183 + Altitude: 173.878 ft + Time: 2001-11-28T21:05:28Z + + ]]> + + -71.119828 + 42.464183 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.119828,42.464183,52.997925 + + + + 5376 + + + Longitude: -71.119399 + Latitude: 42.465650 + Altitude: 185.000 ft + Time: 2001-06-02T03:27:02Z + + ]]> + + -71.119399 + 42.465650 + 66 + + 2001-06-02T03:27:02Z + #route + + -71.119399,42.465650,56.388000 + + + + 5376STREAM + + + Longitude: -71.119328 + Latitude: 42.465913 + Altitude: 211.725 ft + Time: 2001-11-07T23:53:41Z + + ]]> + + -71.119328 + 42.465913 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.119328,42.465913,64.533692 + + + + 6328 + + + Longitude: -71.113574 + Latitude: 42.467110 + Altitude: 176.000 ft + Time: 2001-06-02T03:27:02Z + + ]]> + + -71.113574 + 42.467110 + 66 + + 2001-06-02T03:27:02Z + #route + + -71.113574,42.467110,53.644800 + + + + 635722 + + + Longitude: -71.110067 + Latitude: 42.466459 + Altitude: 160.000 ft + Time: 2001-06-02T03:27:02Z + + ]]> + + -71.110067 + 42.466459 + 66 + + 2001-06-02T03:27:02Z + #route + + -71.110067,42.466459,48.768000 + + + + 635783 + + + Longitude: -71.109410 + Latitude: 42.466557 + Altitude: 161.000 ft + Time: 2001-06-02T03:27:02Z + + ]]> + + -71.109410 + 42.466557 + 66 + + 2001-06-02T03:27:02Z + #route + + -71.109410,42.466557,49.072800 + + + + 6373 + + + Longitude: -71.107117 + Latitude: 42.463495 + Altitude: 205.000 ft + Time: 2001-06-02T03:27:03Z + + ]]> + + -71.107117 + 42.463495 + 66 + + 2001-06-02T03:27:03Z + #route + + -71.107117,42.463495,62.484000 + + + + BEAR HILL + + + Longitude: -71.107360 + Latitude: 42.465687 + Altitude: 288.000 ft + Time: 2001-06-02T03:27:03Z + + ]]> + + -71.107360 + 42.465687 + 66 + + 2001-06-02T03:27:03Z + #route + + -71.107360,42.465687,87.782400 + + + + 6289 + + + Longitude: -71.106170 + Latitude: 42.459986 + Altitude: 239.321 ft + Time: 2001-11-16T23:03:38Z + + ]]> + + -71.106170 + 42.459986 + 66 + + 2001-11-16T23:03:38Z + #route + + -71.106170,42.459986,72.945191 + + + + 6297 + + + Longitude: -71.105116 + Latitude: 42.457616 + Altitude: 239.000 ft + Time: 2001-06-02T03:27:04Z + + ]]> + + -71.105116 + 42.457616 + 66 + + 2001-06-02T03:27:04Z + #route + + -71.105116,42.457616,72.847200 + + + + 6283 + + + Longitude: -71.105206 + Latitude: 42.453845 + Altitude: 218.821 ft + Time: 2001-11-16T23:03:38Z + + ]]> + + -71.105206 + 42.453845 + 66 + + 2001-11-16T23:03:38Z + #route + + -71.105206,42.453845,66.696655 + + + + 6280 + + + Longitude: -71.105413 + Latitude: 42.451430 + Altitude: 188.859 ft + Time: 2001-11-16T23:03:38Z + + ]]> + + -71.105413 + 42.451430 + 66 + + 2001-11-16T23:03:38Z + #route + + -71.105413,42.451430,57.564209 + + + + 6177 + + + Longitude: -71.106158 + Latitude: 42.448448 + Altitude: 204.000 ft + Time: 2001-06-02T03:27:04Z + + ]]> + + -71.106158 + 42.448448 + 66 + + 2001-06-02T03:27:04Z + #route + + -71.106158,42.448448,62.179200 + + + + 6176 + + + Longitude: -71.106624 + Latitude: 42.447804 + Altitude: 205.000 ft + Time: 2001-06-02T03:27:04Z + + ]]> + + -71.106624 + 42.447804 + 66 + + 2001-06-02T03:27:04Z + #route + + -71.106624,42.447804,62.484000 + + + + 6153 + + + Longitude: -71.108882 + Latitude: 42.444773 + Altitude: 206.000 ft + Time: 2001-06-02T03:27:05Z + + ]]> + + -71.108882 + 42.444773 + 66 + + 2001-06-02T03:27:05Z + #route + + -71.108882,42.444773,62.788800 + + + + 6171 + + + Longitude: -71.106301 + Latitude: 42.443592 + Altitude: 182.000 ft + Time: 2001-06-02T03:27:05Z + + ]]> + + -71.106301 + 42.443592 + 66 + + 2001-06-02T03:27:05Z + #route + + -71.106301,42.443592,55.473600 + + + + 6131 + + + Longitude: -71.111441 + Latitude: 42.442981 + Altitude: 210.000 ft + Time: 2001-06-02T03:26:58Z + + ]]> + + -71.111441 + 42.442981 + 66 + + 2001-06-02T03:26:58Z + #route + + -71.111441,42.442981,64.008000 + + + + 6130 + + + Longitude: -71.110975 + Latitude: 42.442196 + Altitude: 210.000 ft + Time: 2001-06-02T03:26:55Z + + ]]> + + -71.110975 + 42.442196 + 66 + + 2001-06-02T03:26:55Z + #route + + -71.110975,42.442196,64.008000 + + + + 6029 + + + Longitude: -71.113220 + Latitude: 42.441754 + Altitude: 185.000 ft + Time: 2001-06-02T03:26:55Z + + ]]> + + -71.113220 + 42.441754 + 66 + + 2001-06-02T03:26:55Z + #route + + -71.113220,42.441754,56.388000 + + + + 6006 + + + Longitude: -71.114456 + Latitude: 42.439018 + Altitude: 185.000 ft + Time: 2001-06-02T03:26:55Z + + ]]> + + -71.114456 + 42.439018 + 66 + + 2001-06-02T03:26:55Z + #route + + -71.114456,42.439018,56.388000 + + + + 6014MEADOW + + + Longitude: -71.113223 + Latitude: 42.436757 + Altitude: 123.415 ft + Time: 2001-11-28T21:05:28Z + + ]]> + + -71.113223 + 42.436757 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.113223,42.436757,37.616943 + + + + PANTHRCAVE + + + Longitude: -71.109942 + Latitude: 42.434980 + Altitude: 148.647 ft + Time: 2001-11-07T23:53:41Z + + ]]> + + -71.109942 + 42.434980 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.109942,42.434980,45.307495 + + + + GATE6 + + + Longitude: -71.109236 + Latitude: 42.431240 + Altitude: 87.145 ft + Time: 2001-11-07T23:53:41Z + + ]]> + + -71.109236 + 42.431240 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.109236,42.431240,26.561890 + + + + BELLEVUE + + + Longitude: -71.107628 + Latitude: 42.430950 + Altitude: 77.000 ft + Time: 2001-06-02T00:18:15Z + + ]]> + + -71.107628 + 42.430950 + 66 + + 2001-06-02T00:18:15Z + #route + + -71.107628,42.430950,23.469600 + + + + + Path + #lineStyle + + 1 + + -71.107628,42.430950,23.469600 + -71.109236,42.431240,26.561890 + -71.109942,42.434980,45.307495 + -71.113223,42.436757,37.616943 + -71.114456,42.439018,56.388000 + -71.114803,42.438594,46.028564 + -71.116146,42.438917,44.826904 + -71.119277,42.438878,44.586548 + -71.119689,42.439227,57.607200 + -71.120925,42.439993,53.949600 + -71.121676,42.441727,67.360800 + -71.122044,42.443904,50.594727 + -71.122845,42.445359,61.649902 + -71.121447,42.447298,127.711200 + -71.122320,42.449765,119.809082 + -71.121746,42.451442,74.627442 + -71.121211,42.453256,77.992066 + -71.119356,42.456252,78.713135 + -71.119676,42.456592,78.713135 + -71.119845,42.457388,73.761600 + -71.119135,42.458148,68.275200 + -71.117693,42.459377,64.008000 + -71.119828,42.464183,52.997925 + -71.119399,42.465650,56.388000 + -71.119328,42.465913,64.533692 + -71.113574,42.467110,53.644800 + -71.110067,42.466459,48.768000 + -71.109410,42.466557,49.072800 + -71.107117,42.463495,62.484000 + -71.107360,42.465687,87.782400 + -71.106170,42.459986,72.945191 + -71.105116,42.457616,72.847200 + -71.105206,42.453845,66.696655 + -71.105413,42.451430,57.564209 + -71.106158,42.448448,62.179200 + -71.106624,42.447804,62.484000 + -71.108882,42.444773,62.788800 + -71.106301,42.443592,55.473600 + -71.111441,42.442981,64.008000 + -71.110975,42.442196,64.008000 + -71.113220,42.441754,56.388000 + -71.114456,42.439018,56.388000 + -71.113223,42.436757,37.616943 + -71.109942,42.434980,45.307495 + -71.109236,42.431240,26.561890 + -71.107628,42.430950,23.469600 + + + + + + + diff --git a/reference/earth-gc.kml b/reference/earth-gc.kml new file mode 100644 index 000000000..8b1d8a2c2 --- /dev/null +++ b/reference/earth-gc.kml @@ -0,0 +1,159 @@ + + + + GPS device + + + + + + + normal + #waypoint_n + + + highlight + #waypoint_h + + + + + Waypoints + + + + + 2002-08-15T07:00:00Z + #geocache + + + GC7FA4 + Points géodésiques du Québec + Sverdrup2 + 6293 + stars1 + stars1 + virtual + + Locationless (Reverse) Cache + + +Pour inscrire votre découverte, vous devez prendre en note le NUMÉRO DU POINT(inscrit sur le point même ou au centre du panneau)LA COORDONNÉE(en format HDDD MM.MM WGS84 datum ET UTM NAD83 indiquer la zone SVP)et L'ALTITUDE RELATIVE. Si le points n'est pas visible (il se peut qu'il soit sous quelques centimètres de terre) vous pouvez prendre la coordonnée à l'emplacement du panneau SI LA PRÉCISION DE VOTRE GPS EST SUPÉRIEUR À LA DISTANCE INSCRITE SUR LE PANNEAU (ex : Précison du GPS de 5m et distance au point inscrite sur le panneau de 3m). +

+Une photo du point ou du panneau et une description générale des lieux serait aussi des informations importantes. +

+Enfin, il faudrait aussi prendre en note l'organisme propriétaire du point géodésique. Au Québec il en existe plusieurs: +

+Le Service de la géodésie du Québec, Ministère des Ressources naturelles, Québec +

+La Division des levés géodésiques, Géomatique Canada, Secteur des sciences de la terre Ressources naturelles Canada +

+Le Service hydrographique du Canada, Direction des sciences, Pêches et Océans Canada et la Garde côtière canadienne, Pêches et Océans Canada +

+Et tout les anciens noms de ministères et/ou organisme +

+Des photos de points de même que des panneaux suivront bientôt. +VOUS NE POUVEZ INSCRIRE QU'UN SEUL POINT GÉODÉSIQUE (UN POINT PAR GÉOCACHEUR) +Bonne chance! + +

+ +The goal of this virtual cache is to find the geodetic points of Québec’s territory. The geodetic points are easy to identify (Brass cap at ground level) Generally, there is an orange panel of on a post near the point. On this panel, the number of the point is identified. Also, the distance relating from the panel to the point is also indicated. In order to log your find, you must take in note THE NUMBER OF THE POINT(registered on the point or in the center of the panel) and THE COORDINATES(in format HDDD MM.MM WGS84 datum AND UTM NAD83 indicate the zone please)and THE ALTITUDE. If the point is not visible (it may be buried under few centimetres) you can take the coordinate at the panel IF THE ACCURACY OF YOUR GPS IS HIGHER Than the DISTANCE REGISTERED ON the PANEL. (Ex: accuracy of the GPS is 5m and the distance to the point registered on the panel is 3m). +

+A picture of the point or panel and a general description of the places would be also significant information. Finally, it would also be important to take in note the organization owner of the geodetic point. +In Quebec there are several: +

+The "Service de la géodésie du Québec, Ministère des Ressources naturelles Québec" +The Geodetic Survey Division, Geomatics Canada, Earth Sciences Sector, Natural Resources Canada +The Canadian Hydrographic Service, Sciences Directorate, Fisheries and Oceans Canada and the Canadian Coast Guard, Fisheries and Oceans Canada +And all old names of ministries and/or organization +

+ +PICTURES of points and of the panels will follow soon. YOU CAN ONLY LOG ONE POINT (ONE POINT PER GEOCACHER) +Good luck!]]> + + + -73.000000,46.133333,0.000000 + + + + + + + 2003-06-29T07:00:00Z + #geocache + + + GCGCA8 + Oozy rat in a sanitary zoo + robertlipe + 32733 + stars3 + stars2 + not_chosen + + Unknown Cache + + + +

  • Too bad I hid a boot +
  • Too hot to hoot +
  • Never odd or even +
  • Do geese see God? +
  • "Do nine men interpret?" "Nine men," I nod +
  • Rats live on no evil star +
  • Go hang a salami, I'm a lasagna hog + + +Now that it's intuitively obvious to even the most casual observer where the cache is, turn on your geo-mojo and go find it. +
    +Member of Middle Tennessee GeoCachers Club [www.mtgc.org]

    ]]> + + + -86.861667,35.921667,0.000000 + + + + + diff --git a/reference/easygps.loc b/reference/easygps.loc new file mode 100755 index 0000000000000000000000000000000000000000..011dd965370c8375164bd34576cc0955f1787d8b GIT binary patch literal 1378 zcmbu<&ui0Q7zgld{)$tF7dac=EL{-zR6+RMylsx zkfCMd5^4gC7#Jj}<=LcGcY!DfBFIsT>Ncv9GXsN#zBPI>t*ZQS+A>{4OrVkm2E!PQ zV-u7-;IteMN>Ji1-{Lr~+MbeKgBN)#al3YuTq)IxMBi6S*^UKcq+z14ZKgM4Z=7WOM10%P}kB`4oTKzqp#k zlX>vv+r-0=n7AAZibqsLiOetAb8SC$ee%-F K|8V`IPTWu3Homa{ literal 0 HcmV?d00001 diff --git a/reference/enchilada.usr b/reference/enchilada.usr new file mode 100644 index 0000000000000000000000000000000000000000..7df3252975dcc005fcb5a1d462a8b8d3596853b3 GIT binary patch literal 2977 zcma*pe`r-@9LMoq|MwqP=nT+FmT!Ys_3Wl7B}rn7aY%gwv(;@S}BtX7G* z8I>u5_EQ8GnTo$wmRM$+6=now_(zx^sidVvHcD@w_lM4b%Si6v!fW5>Ip;j*InU=g zClLfeo_-y7mj?$gwP$+d0{tFNHmB;F=1W2MscBaZFF|3jd185R>0*24J^eRWzbWbF z6fIj$M|~2(C+hP~raf~`^?dziv^3Wy8|k(4m#EjE;3M_w(*>#1>;AdvrlKr#v{I>rsn)jpaZ7ivJr`fn1SpZK*9POXPSfxePK062TQZ^`zE@hN6nrrZ5={ zD@g`RHC2Z-^6(jfTL`J_1B-+n&?M{vb;A3gTG#|07dC=&VI7zxtOgT=m%(_U6O0j- zgJPir+#s}p5kdI3kP&-v}eY z*TM*JP#6k66AHk7Aq325zaCZiq3|czE}R4J3apxNtKg%y2}3w)hj1;}BU}$y7&n8D z1rLL!aZzOg;G$DNpWwUrN~oZ6NT>o-=7BGShN!b=jJsG$rB_%MHF@T#tfg{5cq@V* z92eb6g@O6uGSt0PqQ&gHI80@?n!W>DgyUe7@H2Q*I1SbcXTYn%@1RTg3p^(T%22pS zNPvYx0ca40fw{ufph~y~%oMHzl|oU}bQ?&jG9Jtq?gE_WKF}yU1X_fdV6iXHrvT60U?rre>=m8{OjKKh7b0{4X7x2d=k$^HtbdI zdY!vNOb)sG9FRNDf1JCtDtS`OHtFnaGM;u0C)zJY=XoirtO117 z*#yoe+mW-$FtW4Bn7vvUs@G3eHji<_ZZ$cZZwonRlb8(5=2a}+d1`Vt=LpW`V?uT| zX>vAegq*Y4rp^xF^MWHuHl5Zuo9m+r*>rw+?zIezwPD2B+^0%2O#`#Z)H$2XsXgGpwSsM#hcF(ReXc&f!?4} z!gS74CwLQM4!x~a3!cm>VGMmLg;5c11k8LP;3z+)1;P+2Tp|y|50_zFWRWZvE`V1A zZ`W+#zfob?oB?d|CjfWqrNx9FrNSh93z(KK0du$?FwY+V=6M?+p51^Hya8D1s{uQ} z$_Ne!eH9De#v70~<#ZxE1hli@{FeCcu69 zlYl$*mO_Z~X##%T^R*c7NN3q(IHAGS{gJ@HypJ(v?`-UT!#U6QLLvA;@I`+VN~jzc zO2G-?4scTN{&Py0Oy#WL{pY;kZ-aiplfXt@Lm$4KJW+*$r*5RMn5NN!cmCT2&-0x^ zCrx~?`DAltitude/Depth units for this file +#Velocity units Statute miles per hour +C Category 1,Category 2,Category 3,Category 4,Category 5,Category 6,Category 7,Category 8,Category 9,Category 10,Category 11,Category 12,Category 13,Category 14,Category 15,Category 16 + +W 5058ROAD 19T 325561.6 4700804.1 Sat Jun 02 00:18:14 2001 ROAD CROSSING ^ 18^Black ^S+N^0 +cA 5058ROAD||||| +cB |||0|0|1.0e25 +cC 177.000001|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.415 S mi +cD 1.0e25|1.0e25|0 + +W 5058ROAD 19T 325561.6 4700804.1 Sat Jun 02 00:18:14 2001 ROAD CROSSING ^ 18^Black ^S+N^0 +cA 5058ROAD||||| +cB |||0|0|1.0e25 +cC 177.000001|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.415 S mi +cD 1.0e25|1.0e25|0 + +W 5066 19T 325694.0 4700676.9 Wed Nov 28 21:05:28 2001 5066 ^ 8238^Black ^S+N^0 +cA 5066||||| +cB |||0|0|1.0e25 +cC 146.281325|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.400 S mi +cD 1.0e25|1.0e25|0 + +W 5066 19T 325694.0 4700676.9 Wed Nov 28 21:05:28 2001 ^ 8238^Black ^S+N^0 +cA 5066||||| +cB |||0|0|1.0e25 +cC 146.281325|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.400 S mi +cD 1.0e25|1.0e25|0 + +W 5067 19T 325661.1 4700716.5 Sat Jun 02 03:26:55 2001 ^ 18^Black ^S+N^0 +cA 5067||||| +cB |||0|0|1.0e25 +cC 189.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.400 S mi +cD 1.0e25|1.0e25|0 + +W 5067 19T 325661.1 4700716.5 Sat Jun 02 03:26:55 2001 5067 ^ 18^Black ^S+N^0 +cA 5067||||| +cB |||0|0|1.0e25 +cC 189.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.400 S mi +cD 1.0e25|1.0e25|0 + +W 5096 19T 325951.7 4700674.8 Fri Nov 16 23:03:38 2001 5096 ^ 18^Black ^S+N^0 +cA 5096||||| +cB |||0|0|1.0e25 +cC 147.069896|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.276 S mi +cD 1.0e25|1.0e25|0 + +W 5096 19T 325951.7 4700674.8 Fri Nov 16 23:03:38 2001 ^ 18^Black ^S+N^0 +cA 5096||||| +cB |||0|0|1.0e25 +cC 147.069896|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.276 S mi +cD 1.0e25|1.0e25|0 + +W 5142 19T 325480.4 4701240.7 Wed Nov 28 21:05:28 2001 ^ 18^Black ^S+N^0 +cA 5142||||| +cB |||0|0|1.0e25 +cC 165.993197|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.285 S mi +cD 1.0e25|1.0e25|0 + +W 5142 19T 325480.4 4701240.7 Wed Nov 28 21:05:28 2001 5142 ^ 18^Black ^S+N^0 +cA 5142||||| +cB |||0|0|1.0e25 +cC 165.993197|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.285 S mi +cD 1.0e25|1.0e25|0 + +W 5144SUMMIT 19T 325418.6 4701403.9 Wed Nov 28 21:05:28 2001 ^ 8246^Black ^S+N^0 +cA 5144SUMMIT||||| +cB |||0|0|1.0e25 +cC 202.263459|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.252 S mi +cD 1.0e25|1.0e25|0 + +W 5144SUMMIT 19T 325418.6 4701403.9 Wed Nov 28 21:05:28 2001 Summit ^ 8246^Black ^S+N^0 +cA 5144SUMMIT||||| +cB |||0|0|1.0e25 +cC 202.263459|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.252 S mi +cD 1.0e25|1.0e25|0 + +W 5148NANEPA 19T 325474.0 4701892.1 Wed Nov 07 23:53:41 2001 Nanepashemet Road Crossing ^ 18^Black ^S+N^0 +cA 5148NANEPA||||| +cB |||0|0|1.0e25 +cC 393.074416|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.036 S mi +cD 1.0e25|1.0e25|0 + +W 5148NANEPA 19T 325474.0 4701892.1 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA 5148NANEPA||||| +cB |||0|0|1.0e25 +cC 393.074416|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.036 S mi +cD 1.0e25|1.0e25|0 + +W 5150TANK 19T 325504.6 4700998.2 Sat Jun 02 00:18:16 2001 WATER TANK ^ 8211^Black ^S+N^0 +cA 5150TANK||||| +cB |||0|0|1.0e25 +cC 221.000006|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.367 S mi +cD 1.0e25|1.0e25|0 + +W 5150TANK 19T 325504.6 4700998.2 Sat Jun 02 00:18:16 2001 WATER TANK ^ 8211^Black ^S+N^0 +cA 5150TANK||||| +cB |||0|0|1.0e25 +cC 221.000006|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.367 S mi +cD 1.0e25|1.0e25|0 + +W 5156 19T 325538.9 4701616.4 Sat Jun 02 03:26:58 2001 ^ 18^Black ^S+N^0 +cA 5156||||| +cB |||0|0|1.0e25 +cC 418.999990|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.111 S mi +cD 1.0e25|1.0e25|0 + +W 5156 19T 325538.9 4701616.4 Sat Jun 02 03:26:58 2001 5156 ^ 18^Black ^S+N^0 +cA 5156||||| +cB |||0|0|1.0e25 +cC 418.999990|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.111 S mi +cD 1.0e25|1.0e25|0 + +W 5179DEAD 19T 325722.8 4701897.1 Sat Jun 02 03:26:59 2001 Dead End ^ 166^Black ^S+N^0 +cA 5179DEAD||||| +cB |||0|0|1.0e25 +cC 383.999992|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.913 S mi +cD 1.0e25|1.0e25|0 + +W 5224 19T 325260.1 4702465.0 Sat Jun 02 03:26:59 2001 5224 ^ 18^Black ^S+N^0 +cA 5224||||| +cB |||0|0|1.0e25 +cC 317.999997|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.918 S mi +cD 1.0e25|1.0e25|0 + +W 5229 19T 325280.5 4702931.9 Sat Jun 02 03:26:59 2001 5229 ^ 18^Black ^S+N^0 +cA 5229||||| +cB |||0|0|1.0e25 +cC 270.999999|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.727 S mi +cD 1.0e25|1.0e25|0 + +W 5236BRIDGE 19T 325300.9 4702641.4 Sat Jun 02 03:26:59 2001 Bridge ^ 8233^Black ^S+N^0 +cA 5236BRIDGE||||| +cB |||0|0|1.0e25 +cC 295.000001|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.830 S mi +cD 1.0e25|1.0e25|0 + +W 5237 19T 325316.9 4702697.6 Sat Jun 02 03:26:59 2001 5237 ^ 18^Black ^S+N^0 +cA 5237||||| +cB |||0|0|1.0e25 +cC 272.000005|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.800 S mi +cD 1.0e25|1.0e25|0 + +W 5239ROAD 19T 325315.1 4702953.1 Sat Jun 02 03:27:00 2001 Road ^ 176^Black ^S+N^0 +cA 5239ROAD||||| +cB |||0|0|1.0e25 +cC 265.999992|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.702 S mi +cD 1.0e25|1.0e25|0 + +W 5252PURPLE 19T 325574.9 4702277.5 Wed Nov 07 23:53:41 2001 ^ 8246^Black ^S+N^0 +cA 5252PURPLE||||| +cB |||0|0|1.0e25 +cC 255.879480|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.838 S mi +cD 1.0e25|1.0e25|0 + +W 5252PURPLE 19T 325574.9 4702277.5 Wed Nov 07 23:53:41 2001 Purple Rock Hill ^ 8246^Black ^S+N^0 +cA 5252PURPLE||||| +cB |||0|0|1.0e25 +cC 255.879480|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.838 S mi +cD 1.0e25|1.0e25|0 + +W 5254 19T 325596.2 4702404.2 Wed Nov 28 21:05:28 2001 5254 ^ 18^Black ^S+N^0 +cA 5254||||| +cB |||0|0|1.0e25 +cC 218.821047|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.778 S mi +cD 1.0e25|1.0e25|0 + +W 5258 19T 325525.9 4702077.2 Wed Nov 07 23:53:41 2001 5258 ^ 18^Black ^S+N^0 +cA 5258||||| +cB |||0|0|1.0e25 +cC 244.840687|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.939 S mi +cD 1.0e25|1.0e25|0 + +W 5258 19T 325525.9 4702077.2 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA 5258||||| +cB |||0|0|1.0e25 +cC 244.840687|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.939 S mi +cD 1.0e25|1.0e25|0 + +W 5264 19T 325623.4 4702403.8 Wed Nov 28 21:05:28 2001 5264 ^ 18^Black ^S+N^0 +cA 5264||||| +cB |||0|0|1.0e25 +cC 214.090422|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.765 S mi +cD 1.0e25|1.0e25|0 + +W 526708 19T 325601.0 4702777.4 Sat Jun 02 03:27:00 2001 526708 ^ 18^Black ^S+N^0 +cA 526708||||| +cB |||0|0|1.0e25 +cC 253.999990|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.632 S mi +cD 1.0e25|1.0e25|0 + +W 526750 19T 325659.4 4702701.3 Sat Jun 02 03:27:00 2001 526750 ^ 18^Black ^S+N^0 +cA 526750||||| +cB |||0|0|1.0e25 +cC 245.000008|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.633 S mi +cD 1.0e25|1.0e25|0 + +W 5267OBSTAC 19T 325698.7 4702733.5 Sat Jun 02 03:27:00 2001 Obstacle ^ 8204^Black ^S+N^0 +cA 5267OBSTAC||||| +cB |||0|0|1.0e25 +cC 241.999989|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.601 S mi +cD 1.0e25|1.0e25|0 + +W 5267OBSTAC 19T 325698.7 4702733.5 Sat Jun 02 03:27:00 2001 ^ 8204^Black ^S+N^0 +cA 5267OBSTAC||||| +cB |||0|0|1.0e25 +cC 241.999989|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.601 S mi +cD 1.0e25|1.0e25|0 + +W 527614 19T 325710.4 4702644.8 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA 527614||||| +cB |||0|0|1.0e25 +cC 258.245193|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.630 S mi +cD 1.0e25|1.0e25|0 + +W 527614 19T 325710.4 4702644.8 Wed Nov 07 23:53:41 2001 527614 ^ 18^Black ^S+N^0 +cA 527614||||| +cB |||0|0|1.0e25 +cC 258.245193|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.630 S mi +cD 1.0e25|1.0e25|0 + +W 527631 19T 325735.7 4702606.4 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA 527631||||| +cB |||0|0|1.0e25 +cC 258.245193|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.632 S mi +cD 1.0e25|1.0e25|0 + +W 527631 19T 325735.7 4702606.4 Wed Nov 07 23:53:41 2001 527631 ^ 18^Black ^S+N^0 +cA 527631||||| +cB |||0|0|1.0e25 +cC 258.245193|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.632 S mi +cD 1.0e25|1.0e25|0 + +W 5278 19T 325759.2 4702816.5 Sat Jun 02 03:27:00 2001 ^ 18^Black ^S+N^0 +cA 5278||||| +cB |||0|0|1.0e25 +cC 224.000000|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.540 S mi +cD 1.0e25|1.0e25|0 + +W 5278 19T 325759.2 4702816.5 Sat Jun 02 03:27:00 2001 5278 ^ 18^Black ^S+N^0 +cA 5278||||| +cB |||0|0|1.0e25 +cC 224.000000|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.540 S mi +cD 1.0e25|1.0e25|0 + +W 5278ROAD 19T 325772.8 4702886.6 Sat Jun 02 03:27:01 2001 Road ^ 176^Black ^S+N^0 +cA 5278ROAD||||| +cB |||0|0|1.0e25 +cC 221.000006|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.506 S mi +cD 1.0e25|1.0e25|0 + +W 5287WATER 19T 325894.0 4702767.1 Sat Jun 02 03:27:01 2001 Reservoir ^ 163^Black ^S+N^0 +cA 5287WATER||||| +cB |||0|0|1.0e25 +cC 222.999993|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.493 S mi +cD 1.0e25|1.0e25|0 + +W 5289 19T 325881.1 4702950.0 Sat Jun 02 03:27:01 2001 5289 ^ 18^Black ^S+N^0 +cA 5289||||| +cB |||0|0|1.0e25 +cC 210.000011|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.429 S mi +cD 1.0e25|1.0e25|0 + +W 5289 19T 325881.1 4702950.0 Sat Jun 02 03:27:01 2001 ^ 18^Black ^S+N^0 +cA 5289||||| +cB |||0|0|1.0e25 +cC 210.000011|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.429 S mi +cD 1.0e25|1.0e25|0 + +W 5299DEAD 19T 325978.0 4702975.6 Sat Jun 02 03:27:01 2001 Dead End ^ 166^Black ^S+N^0 +cA 5299DEAD||||| +cB |||0|0|1.0e25 +cC 228.000000|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.372 S mi +cD 1.0e25|1.0e25|0 + +W 5374FIRE 19T 325718.9 4703488.0 Wed Nov 28 21:05:28 2001 5374FIRE ^ 18^Black ^S+N^0 +cA 5374FIRE||||| +cB |||0|0|1.0e25 +cC 173.877706|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.299 S mi +cD 1.0e25|1.0e25|0 + +W 5374FIRE 19T 325718.9 4703488.0 Wed Nov 28 21:05:28 2001 ^ 18^Black ^S+N^0 +cA 5374FIRE||||| +cB |||0|0|1.0e25 +cC 173.877706|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.299 S mi +cD 1.0e25|1.0e25|0 + +W 5376 19T 325758.3 4703650.1 Sat Jun 02 03:27:02 2001 5376 ^ 18^Black ^S+N^0 +cA 5376||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.217 S mi +cD 1.0e25|1.0e25|0 + +W 5376 19T 325758.3 4703650.1 Sat Jun 02 03:27:02 2001 ^ 18^Black ^S+N^0 +cA 5376||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.217 S mi +cD 1.0e25|1.0e25|0 + +W 5376BRIDGE 19T 325724.4 4703663.0 Sat Jun 02 03:27:01 2001 Bridge ^ 8233^Black ^S+N^0 +cA 5376BRIDGE||||| +cB |||0|0|1.0e25 +cC 181.999995|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.229 S mi +cD 1.0e25|1.0e25|0 + +W 5376DEAD 19T 325778.5 4703631.2 Sat Jun 02 03:27:02 2001 Dead End ^ 166^Black ^S+N^0 +cA 5376DEAD||||| +cB |||0|0|1.0e25 +cC 187.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.215 S mi +cD 1.0e25|1.0e25|0 + +W 5376STREAM 19T 325764.8 4703679.1 Wed Nov 07 23:53:41 2001 Stream Crossing ^ 8233^Black ^S+N^0 +cA 5376STREAM||||| +cB |||0|0|1.0e25 +cC 211.724709|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.203 S mi +cD 1.0e25|1.0e25|0 + +W 5376STREAM 19T 325764.8 4703679.1 Wed Nov 07 23:53:41 2001 ^ 8233^Black ^S+N^0 +cA 5376STREAM||||| +cB |||0|0|1.0e25 +cC 211.724709|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.203 S mi +cD 1.0e25|1.0e25|0 + +W 6006 19T 326091.0 4700682.6 Sat Jun 02 03:26:55 2001 ^ 18^Black ^S+N^0 +cA 6006||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.205 S mi +cD 1.0e25|1.0e25|0 + +W 6006 19T 326091.0 4700682.6 Sat Jun 02 03:26:55 2001 ^ 18^Black ^S+N^0 +cA 6006||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.205 S mi +cD 1.0e25|1.0e25|0 + +W 6006 19T 326091.0 4700682.6 Sat Jun 02 03:26:55 2001 600698 ^ 18^Black ^S+N^0 +cA 6006||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.205 S mi +cD 1.0e25|1.0e25|0 + +W 6006BLUE 19T 326061.3 4700636.2 Wed Nov 28 21:05:28 2001 ^ 18^Black ^S+N^0 +cA 6006BLUE||||| +cB |||0|0|1.0e25 +cC 151.012351|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.237 S mi +cD 1.0e25|1.0e25|0 + +W 6006BLUE 19T 326061.3 4700636.2 Wed Nov 28 21:05:28 2001 6006BLUE ^ 18^Black ^S+N^0 +cA 6006BLUE||||| +cB |||0|0|1.0e25 +cC 151.012351|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.237 S mi +cD 1.0e25|1.0e25|0 + +W 6014MEADOW 19T 326186.1 4700429.0 Wed Nov 28 21:05:28 2001 6014MEADOW ^ 18^Black ^S+N^0 +cA 6014MEADOW||||| +cB |||0|0|1.0e25 +cC 123.415169|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.257 S mi +cD 1.0e25|1.0e25|0 + +W 6014MEADOW 19T 326186.1 4700429.0 Wed Nov 28 21:05:28 2001 ^ 18^Black ^S+N^0 +cA 6014MEADOW||||| +cB |||0|0|1.0e25 +cC 123.415169|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.257 S mi +cD 1.0e25|1.0e25|0 + +W 6014MEADOW 19T 326186.1 4700429.0 Wed Nov 28 21:05:28 2001 ^ 18^Black ^S+N^0 +cA 6014MEADOW||||| +cB |||0|0|1.0e25 +cC 123.415169|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.257 S mi +cD 1.0e25|1.0e25|0 + +W 6016 19T 326121.0 4700642.7 Wed Nov 28 21:05:28 2001 Bike Loop Connector ^ 18^Black ^S+N^0 +cA 6016||||| +cB |||0|0|1.0e25 +cC 142.338470|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.206 S mi +cD 1.0e25|1.0e25|0 + +W 6029 19T 326200.2 4700983.9 Sat Jun 02 03:26:55 2001 6029 ^ 18^Black ^S+N^0 +cA 6029||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.035 S mi +cD 1.0e25|1.0e25|0 + +W 6029 19T 326200.2 4700983.9 Sat Jun 02 03:26:55 2001 ^ 18^Black ^S+N^0 +cA 6029||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.035 S mi +cD 1.0e25|1.0e25|0 + +W 6042CROSS 19T 326475.3 4700279.0 Sat Jun 02 03:27:05 2001 Crossing ^ 8238^Black ^S+N^0 +cA 6042CROSS||||| +cB |||0|0|1.0e25 +cC 148.000004|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.175 S mi +cD 1.0e25|1.0e25|0 + +W 6053 19T 326525.9 4700363.4 Sat Jun 02 03:27:05 2001 6053 ^ 18^Black ^S+N^0 +cA 6053||||| +cB |||0|0|1.0e25 +cC 164.999999|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.118 S mi +cD 1.0e25|1.0e25|0 + +W 6066 19T 326663.7 4700694.1 Sat Jun 02 03:26:57 2001 6066 ^ 18^Black ^S+N^0 +cA 6066||||| +cB |||0|0|1.0e25 +cC 84.000003|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.923 S mi +cD 1.0e25|1.0e25|0 + +W 6067 19T 326658.4 4700751.4 Sat Jun 02 03:26:57 2001 6067 ^ 18^Black ^S+N^0 +cA 6067||||| +cB |||0|0|1.0e25 +cC 113.000006|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.903 S mi +cD 1.0e25|1.0e25|0 + +W 6071 19T 326785.1 4700192.9 Sat Jun 02 03:26:57 2001 6071 ^ 18^Black ^S+N^0 +cA 6071||||| +cB |||0|0|1.0e25 +cC 99.999998|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.058 S mi +cD 1.0e25|1.0e25|0 + +W 6073 19T 326721.5 4700032.0 Sat Jun 02 03:26:56 2001 6073 ^ 18^Black ^S+N^0 +cA 6073||||| +cB |||0|0|1.0e25 +cC 49.999999|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.151 S mi +cD 1.0e25|1.0e25|0 + +W 6077LOGS 19T 326742.1 4700720.2 Sat Jun 02 00:18:16 2001 Log Crossing ^ 8204^Black ^S+N^0 +cA 6077LOGS||||| +cB |||0|0|1.0e25 +cC 105.000005|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.875 S mi +cD 1.0e25|1.0e25|0 + +W 6084 19T 326882.9 4700476.2 Sat Jun 02 03:26:57 2001 6084 ^ 18^Black ^S+N^0 +cA 6084||||| +cB |||0|0|1.0e25 +cC 124.000001|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.901 S mi +cD 1.0e25|1.0e25|0 + +W 6121DEAD 19T 326248.8 4701133.2 Sat Jun 02 03:26:57 2001 Dead End ^ 166^Black ^S+N^0 +cA 6121DEAD||||| +cB |||0|0|1.0e25 +cC 183.999995|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.954 S mi +cD 1.0e25|1.0e25|0 + +W 6130 19T 326386.1 4701028.3 Sat Jun 02 03:26:55 2001 6130 ^ 18^Black ^S+N^0 +cA 6130||||| +cB |||0|0|1.0e25 +cC 210.000011|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.928 S mi +cD 1.0e25|1.0e25|0 + +W 6130 19T 326386.1 4701028.3 Sat Jun 02 03:26:55 2001 ^ 18^Black ^S+N^0 +cA 6130||||| +cB |||0|0|1.0e25 +cC 210.000011|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.928 S mi +cD 1.0e25|1.0e25|0 + +W 6131 19T 326349.9 4701116.5 Sat Jun 02 03:26:58 2001 ^ 18^Black ^S+N^0 +cA 6131||||| +cB |||0|0|1.0e25 +cC 210.000011|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.911 S mi +cD 1.0e25|1.0e25|0 + +W 6131 19T 326349.9 4701116.5 Sat Jun 02 03:26:58 2001 6131 ^ 18^Black ^S+N^0 +cA 6131||||| +cB |||0|0|1.0e25 +cC 210.000011|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.911 S mi +cD 1.0e25|1.0e25|0 + +W 6153 19T 326565.3 4701310.2 Sat Jun 02 03:27:05 2001 6153 ^ 18^Black ^S+N^0 +cA 6153||||| +cB |||0|0|1.0e25 +cC 205.999998|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.732 S mi +cD 1.0e25|1.0e25|0 + +W 6153 19T 326565.3 4701310.2 Sat Jun 02 03:27:05 2001 ^ 18^Black ^S+N^0 +cA 6153||||| +cB |||0|0|1.0e25 +cC 205.999998|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.732 S mi +cD 1.0e25|1.0e25|0 + +W 6155DEAD 19T 326579.0 4701534.3 Sat Jun 02 03:27:04 2001 Dead End ^ 166^Black ^S+N^0 +cA 6155DEAD||||| +cB |||0|0|1.0e25 +cC 201.000003|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.638 S mi +cD 1.0e25|1.0e25|0 + +W 6171 19T 326774.3 4701173.8 Sat Jun 02 03:27:05 2001 6171 ^ 18^Black ^S+N^0 +cA 6171||||| +cB |||0|0|1.0e25 +cC 181.999995|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.683 S mi +cD 1.0e25|1.0e25|0 + +W 6171 19T 326774.3 4701173.8 Sat Jun 02 03:27:05 2001 ^ 18^Black ^S+N^0 +cA 6171||||| +cB |||0|0|1.0e25 +cC 181.999995|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.683 S mi +cD 1.0e25|1.0e25|0 + +W 6176 19T 326759.4 4701642.2 Sat Jun 02 03:27:04 2001 ^ 18^Black ^S+N^0 +cA 6176||||| +cB |||0|0|1.0e25 +cC 205.000004|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.509 S mi +cD 1.0e25|1.0e25|0 + +W 6176 19T 326759.4 4701642.2 Sat Jun 02 03:27:04 2001 6176 ^ 18^Black ^S+N^0 +cA 6176||||| +cB |||0|0|1.0e25 +cC 205.000004|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.509 S mi +cD 1.0e25|1.0e25|0 + +W 6177 19T 326799.5 4701712.8 Sat Jun 02 03:27:04 2001 6177 ^ 18^Black ^S+N^0 +cA 6177||||| +cB |||0|0|1.0e25 +cC 203.999997|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.462 S mi +cD 1.0e25|1.0e25|0 + +W 6177 19T 326799.5 4701712.8 Sat Jun 02 03:27:04 2001 ^ 18^Black ^S+N^0 +cA 6177||||| +cB |||0|0|1.0e25 +cC 203.999997|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.462 S mi +cD 1.0e25|1.0e25|0 + +W 6181CROSS 19T 326807.5 4701106.4 Sat Jun 02 03:27:05 2001 Crossing ^ 8238^Black ^S+N^0 +cA 6181CROSS||||| +cB |||0|0|1.0e25 +cC 173.000000|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.693 S mi +cD 1.0e25|1.0e25|0 + +W 6272 19T 326723.2 4702268.7 Sat Jun 02 03:26:56 2001 6272 ^ 18^Black ^S+N^0 +cA 6272||||| +cB |||0|0|1.0e25 +cC 240.000001|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.284 S mi +cD 1.0e25|1.0e25|0 + +W 6272 19T 326761.8 4702265.6 Sat Jun 02 03:26:55 2001 6272 ^ 18^Black ^S+N^0 +cA 6272||||| +cB |||0|0|1.0e25 +cC 229.000006|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.267 S mi +cD 1.0e25|1.0e25|0 + +W 6278 19T 326776.2 4702807.8 Sat Jun 02 03:27:04 2001 6278 ^ 18^Black ^S+N^0 +cA 6278||||| +cB |||0|0|1.0e25 +cC 229.999988|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.050 S mi +cD 1.0e25|1.0e25|0 + +W 6280 19T 326869.0 4702042.4 Fri Nov 16 23:03:38 2001 6280 ^ 18^Black ^S+N^0 +cA 6280||||| +cB |||0|0|1.0e25 +cC 188.858953|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.301 S mi +cD 1.0e25|1.0e25|0 + +W 6280 19T 326869.0 4702042.4 Fri Nov 16 23:03:38 2001 ^ 18^Black ^S+N^0 +cA 6280||||| +cB |||0|0|1.0e25 +cC 188.858953|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.301 S mi +cD 1.0e25|1.0e25|0 + +W 6283 19T 326892.6 4702310.1 Fri Nov 16 23:03:38 2001 6283 ^ 18^Black ^S+N^0 +cA 6283||||| +cB |||0|0|1.0e25 +cC 218.821047|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.186 S mi +cD 1.0e25|1.0e25|0 + +W 6283 19T 326892.6 4702310.1 Fri Nov 16 23:03:38 2001 ^ 18^Black ^S+N^0 +cA 6283||||| +cB |||0|0|1.0e25 +cC 218.821047|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.186 S mi +cD 1.0e25|1.0e25|0 + +W 6289 19T 326830.3 4702994.0 Fri Nov 16 23:03:38 2001 ^ 18^Black ^S+N^0 +cA 6289||||| +cB |||0|0|1.0e25 +cC 239.321491|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.951 S mi +cD 1.0e25|1.0e25|0 + +W 6289 19T 326830.3 4702994.0 Fri Nov 16 23:03:38 2001 6289 ^ 18^Black ^S+N^0 +cA 6289||||| +cB |||0|0|1.0e25 +cC 239.321491|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.951 S mi +cD 1.0e25|1.0e25|0 + +W 6297 19T 326910.4 4702728.7 Sat Jun 02 03:27:04 2001 6297 ^ 18^Black ^S+N^0 +cA 6297||||| +cB |||0|0|1.0e25 +cC 238.999995|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.015 S mi +cD 1.0e25|1.0e25|0 + +W 6297 19T 326910.4 4702728.7 Sat Jun 02 03:27:04 2001 ^ 18^Black ^S+N^0 +cA 6297||||| +cB |||0|0|1.0e25 +cC 238.999995|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.015 S mi +cD 1.0e25|1.0e25|0 + +W 6328 19T 326241.2 4703800.2 Sat Jun 02 03:27:02 2001 6328 ^ 18^Black ^S+N^0 +cA 6328||||| +cB |||0|0|1.0e25 +cC 175.999994|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.925 S mi +cD 1.0e25|1.0e25|0 + +W 6328 19T 326241.2 4703800.2 Sat Jun 02 03:27:02 2001 ^ 18^Black ^S+N^0 +cA 6328||||| +cB |||0|0|1.0e25 +cC 175.999994|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.925 S mi +cD 1.0e25|1.0e25|0 + +W 6353DEAD 19T 326524.2 4703311.6 Sat Jun 02 03:27:03 2001 Dead End ^ 166^Black ^S+N^0 +cA 6353DEAD||||| +cB |||0|0|1.0e25 +cC 154.000004|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.977 S mi +cD 1.0e25|1.0e25|0 + +W 6354 19T 326538.3 4703469.7 Sat Jun 02 03:27:03 2001 6354 ^ 18^Black ^S+N^0 +cA 6354||||| +cB |||0|0|1.0e25 +cC 144.000003|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.909 S mi +cD 1.0e25|1.0e25|0 + +W 635722 19T 326527.7 4703720.8 Sat Jun 02 03:27:02 2001 ^ 18^Black ^S+N^0 +cA 635722||||| +cB |||0|0|1.0e25 +cC 160.000005|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.817 S mi +cD 1.0e25|1.0e25|0 + +W 635722 19T 326527.7 4703720.8 Sat Jun 02 03:27:02 2001 635722 ^ 18^Black ^S+N^0 +cA 635722||||| +cB |||0|0|1.0e25 +cC 160.000005|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.817 S mi +cD 1.0e25|1.0e25|0 + +W 635783 19T 326582.0 4703730.3 Sat Jun 02 03:27:02 2001 635783 ^ 18^Black ^S+N^0 +cA 635783||||| +cB |||0|0|1.0e25 +cC 160.999999|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.787 S mi +cD 1.0e25|1.0e25|0 + +W 635783 19T 326582.0 4703730.3 Sat Jun 02 03:27:02 2001 ^ 18^Black ^S+N^0 +cA 635783||||| +cB |||0|0|1.0e25 +cC 160.999999|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.787 S mi +cD 1.0e25|1.0e25|0 + +W 6373 19T 326762.1 4703385.6 Sat Jun 02 03:27:03 2001 ^ 18^Black ^S+N^0 +cA 6373||||| +cB |||0|0|1.0e25 +cC 205.000004|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.833 S mi +cD 1.0e25|1.0e25|0 + +W 6373 19T 326762.1 4703385.6 Sat Jun 02 03:27:03 2001 6373 ^ 18^Black ^S+N^0 +cA 6373||||| +cB |||0|0|1.0e25 +cC 205.000004|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.833 S mi +cD 1.0e25|1.0e25|0 + +W 6634 19T 326332.9 4696457.9 Sat Jun 02 03:26:56 2001 6634 ^ 18^Black ^S+N^0 +cA 6634||||| +cB |||0|0|1.0e25 +cC 13.000000|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3790.724 S mi +cD 1.0e25|1.0e25|0 + +W 6979 19T 326725.1 4699956.0 Sat Jun 02 03:26:56 2001 6979 ^ 18^Black ^S+N^0 +cA 6979||||| +cB |||0|0|1.0e25 +cC 43.999999|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.179 S mi +cD 1.0e25|1.0e25|0 + +W 6997 19T 326609.6 4699782.4 Fri Nov 16 23:03:38 2001 6997 ^ 18^Black ^S+N^0 +cA 6997||||| +cB |||0|0|1.0e25 +cC 111.588205|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.302 S mi +cD 1.0e25|1.0e25|0 + +W BEAR HILL 19T 326748.2 4703629.5 Sat Jun 02 03:27:03 2001 BEAR HILL TOWER ^16391^Black ^S+N^0 +cA BEAR HILL||||| +cB |||0|0|1.0e25 +cC 288.000007|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.745 S mi +cD 1.0e25|1.0e25|0 + +W BEAR HILL 19T 326748.2 4703629.5 Sat Jun 02 03:27:03 2001 BEAR HILL TOWER ^16391^Black ^S+N^0 +cA BEAR HILL||||| +cB |||0|0|1.0e25 +cC 288.000007|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.745 S mi +cD 1.0e25|1.0e25|0 + +W BELLEVUE 19T 326630.3 4699772.7 Sat Jun 02 00:18:15 2001 BELLEVUE ^ 158^Black ^S+N^0 +cA BELLEVUE||||| +cB |||0|0|1.0e25 +cC 77.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.296 S mi +cD 1.0e25|1.0e25|0 + +W BELLEVUE 19T 326630.3 4699772.7 Sat Jun 02 00:18:15 2001 BELLEVUE ^ 158^Black ^S+N^0 +cA BELLEVUE||||| +cB |||0|0|1.0e25 +cC 77.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.296 S mi +cD 1.0e25|1.0e25|0 + +W BELLEVUE 19T 326630.3 4699772.7 Sat Jun 02 00:18:15 2001 BELLEVUE ^ 158^Black ^S+N^0 +cA BELLEVUE||||| +cB |||0|0|1.0e25 +cC 77.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.296 S mi +cD 1.0e25|1.0e25|0 + +W DARKHOLLPO 19T 327033.8 4702825.6 Sat Jul 16 20:53:40 2005 Dark Hollow Pond ^ 7^Black ^S+N^0 +cA DARKHOLLPO||||| +cB |||0|0|1.0e25 +cC 1e25|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.918 S mi +cD 1.0e25|1.0e25|0 + +W GATE14 19T 325125.9 4702060.7 Sat Jun 02 03:26:59 2001 Gate 14 ^ 176^Black ^S+N^0 +cA GATE14||||| +cB |||0|0|1.0e25 +cC 363.999990|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.140 S mi +cD 1.0e25|1.0e25|0 + +W GATE16 19T 325518.2 4702861.5 Sat Jun 02 03:27:00 2001 Gate 16 ^ 176^Black ^S+N^0 +cA GATE16||||| +cB |||0|0|1.0e25 +cC 254.999997|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.639 S mi +cD 1.0e25|1.0e25|0 + +W GATE17 19T 325754.1 4702953.0 Sat Jun 02 03:27:01 2001 Gate 17 ^ 176^Black ^S+N^0 +cA GATE17||||| +cB |||0|0|1.0e25 +cC 215.999999|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.489 S mi +cD 1.0e25|1.0e25|0 + +W GATE19 19T 325773.3 4703727.8 Sat Jun 02 03:27:02 2001 Gate 19 ^ 176^Black ^S+N^0 +cA GATE19||||| +cB |||0|0|1.0e25 +cC 187.999996|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.180 S mi +cD 1.0e25|1.0e25|0 + +W GATE21 19T 326728.7 4703959.8 Sat Jun 02 03:27:03 2001 Gate 21 ^ 176^Black ^S+N^0 +cA GATE21||||| +cB |||0|0|1.0e25 +cC 162.000005|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.627 S mi +cD 1.0e25|1.0e25|0 + +W GATE24 19T 327084.2 4702624.6 Sat Jun 02 03:27:03 2001 Gate 24 ^ 176^Black ^S+N^0 +cA GATE24||||| +cB |||0|0|1.0e25 +cC 265.999992|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3787.971 S mi +cD 1.0e25|1.0e25|0 + +W GATE5 19T 326624.9 4699761.4 Wed Nov 28 21:05:28 2001 Gate 5 ^ 176^Black ^S+N^0 +cA GATE5||||| +cB |||0|0|1.0e25 +cC 70.587318|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.303 S mi +cD 1.0e25|1.0e25|0 + +W GATE6 19T 326498.9 4699808.2 Wed Nov 07 23:53:41 2001 Gate 6 ^ 18^Black ^S+N^0 +cA GATE6||||| +cB |||0|0|1.0e25 +cC 87.145307|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.346 S mi +cD 1.0e25|1.0e25|0 + +W GATE6 19T 326498.9 4699808.2 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA GATE6||||| +cB |||0|0|1.0e25 +cC 87.145307|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.346 S mi +cD 1.0e25|1.0e25|0 + +W GATE6 19T 326498.9 4699808.2 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA GATE6||||| +cB |||0|0|1.0e25 +cC 87.145307|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.346 S mi +cD 1.0e25|1.0e25|0 + +W PANTHRCAVE 19T 326451.1 4700224.9 Wed Nov 07 23:53:41 2001 ^ 8243^Black ^S+N^0 +cA PANTHRCAVE||||| +cB |||0|0|1.0e25 +cC 148.646638|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.207 S mi +cD 1.0e25|1.0e25|0 + +W PANTHRCAVE 19T 326451.1 4700224.9 Wed Nov 07 23:53:41 2001 Panther Cave ^ 8243^Black ^S+N^0 +cA PANTHRCAVE||||| +cB |||0|0|1.0e25 +cC 148.646638|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.207 S mi +cD 1.0e25|1.0e25|0 + +W PANTHRCAVE 19T 326451.1 4700224.9 Wed Nov 07 23:53:41 2001 ^ 8243^Black ^S+N^0 +cA PANTHRCAVE||||| +cB |||0|0|1.0e25 +cC 148.646638|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3789.207 S mi +cD 1.0e25|1.0e25|0 + +W SHEEPFOLD 19T 326761.9 4702265.6 Sat Jun 02 00:18:13 2001 Sheepfold Parking Lot ^ 158^Black ^S+N^0 +cA SHEEPFOLD||||| +cB |||0|0|1.0e25 +cC 229.000006|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.267 S mi +cD 1.0e25|1.0e25|0 + +W SOAPBOX 19T 326711.2 4702549.2 Sat Jun 02 03:27:04 2001 Soap Box Derby Track ^ 8235^Black ^S+N^0 +cA SOAPBOX||||| +cB |||0|0|1.0e25 +cC 210.000011|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|3788.181 S mi +cD 1.0e25|1.0e25|0 + +N New Track Log Start - Trk from .gpx file,Black,1 +T 15R 633951.5 3326484.2 Sat May 25 17:06:21 2002 ;3.280840; 1e25; SM; 0.0000; 0.0000; 0.0000; INF; -;|1e25 +T 15R 633929.8 3326550.5 Sat May 25 17:09:55 2002 ; 1e25; 1e25; SM; 0.0434; 0.0434; 0.0434;0.730757; 214;|1e25 +T 15R 634151.6 3326544.0 Sat May 25 17:12:00 2002 ; 1e25; 1e25; SM; 0.1377; 0.1811; 0.1811;3.964510; 125;|1e25 +T 15R 634237.3 3326504.3 Sat May 25 17:12:48 2002 ; 1e25; 1e25; SM; 0.0586; 0.2397; 0.2397;4.397203; 48;|1e25 +T 15R 634440.8 3326418.2 Sat May 25 17:14:41 2002 ; 1e25; 1e25; SM; 0.1372; 0.3769; 0.3769;4.371133; 113;|1e25 +T 15R 635010.3 3326231.1 Sat May 25 17:17:16 2002 ; 1e25; 1e25; SM; 0.3720; 0.7489; 0.7489;8.640052; 155;|1e25 +T 15R 635275.0 3326014.6 Sat May 25 17:17:46 2002 ; 1e25; 1e25; SM; 0.2125; 0.9615; 0.9615;25.504435; 30;|1e25 +T 15R 635450.2 3325748.8 Sat May 25 17:18:20 2002 ; 1e25; 1e25; SM; 0.1981; 1.1596; 1.1596;20.979147; 34;|1e25 +T 15R 635672.3 3325585.3 Sat May 25 17:19:01 2002 ; 1e25; 1e25; SM; 0.1714; 1.3310; 1.3310;15.050832; 41;|1e25 +T 15R 635954.4 3325128.8 Sat May 25 17:20:46 2002 ; 1e25; 1e25; SM; 0.3341; 1.6651; 1.6651;11.454587; 105;|1e25 +T 15R 635942.5 3325049.3 Sat May 25 17:21:10 2002 ; 1e25; 1e25; SM; 0.0501; 1.7152; 1.7152;7.515936; 24;|1e25 +T 15R 635648.8 3325021.6 Sat May 25 17:21:51 2002 ; 1e25; 1e25; SM; 0.1830; 1.8982; 1.8982;16.070644; 41;|1e25 +T 15R 635313.2 3324732.9 Sat May 25 17:22:35 2002 ; 1e25; 1e25; SM; 0.2751; 2.1734; 2.1734;22.511499; 44;|1e25 +T 15R 635095.6 3324650.9 Sat May 25 17:23:08 2002 ; 1e25; 1e25; SM; 0.1443; 2.3177; 2.3177;15.745092; 33;|1e25 +T 15R 634943.7 3324846.7 Sat May 25 18:04:23 2002 ; 1e25; 1e25; SM; 0.1542; 2.4719; 2.4719;0.224257; 2475;|1e25 +T 15R 635005.2 3324814.2 Sat May 25 18:06:04 2002 ;6.561680; 1e25; SM; 0.0432; 2.5151; 2.5151;1.540302; 101;|1e25 +T 15R 635022.0 3324751.5 Sat May 25 18:07:06 2002 ; 1e25; 1e25; SM; 0.0404; 2.5555; 2.5555;2.346642; 62;|1e25 +T 15R 635072.2 3324726.3 Sat May 25 18:08:18 2002 ;3.280840; 1e25; SM; 0.0349; 2.5904; 2.5904;1.743045; 72;|1e25 +T 15R 635189.3 3324746.3 Sat May 25 18:10:20 2002 ; 1e25; 1e25; SM; 0.0737; 2.6641; 2.6641;2.174638; 122;|1e25 +T 15R 635243.9 3324745.1 Sat May 25 18:11:09 2002 ; 1e25; 1e25; SM; 0.0339; 2.6979; 2.6979;2.488559; 49;|1e25 +T 15R 635323.7 3324794.0 Sat May 25 18:12:18 2002 ; 1e25; 1e25; SM; 0.0582; 2.7561; 2.7561;3.034664; 69;|1e25 +T 15R 635432.0 3324869.3 Sat May 25 18:14:22 2002 ; 1e25; 1e25; SM; 0.0819; 2.8381; 2.8381;2.379163; 124;|1e25 +T 15R 635473.3 3324908.6 Sat May 25 18:15:04 2002 ;6.561680; 1e25; SM; 0.0354; 2.8735; 2.8735;3.037052; 42;|1e25 +T 15R 635538.6 3324959.3 Sat May 25 18:16:14 2002 ;3.280840; 1e25; SM; 0.0514; 2.9249; 2.9249;2.642554; 70;|1e25 +T 15R 635565.3 3325007.6 Sat May 25 18:17:01 2002 ;3.280840; 1e25; SM; 0.0344; 2.9593; 2.9593;2.632849; 47;|1e25 +T 15R 635559.6 3325081.5 Sat May 25 18:18:07 2002 ; 1e25; 1e25; SM; 0.0462; 3.0054; 3.0054;2.519028; 66;|1e25 +T 15R 635545.5 3325188.5 Sat May 25 18:19:51 2002 ;6.561680; 1e25; SM; 0.0673; 3.0727; 3.0727;2.329100; 104;|1e25 +T 15R 635531.9 3325240.0 Sat May 25 18:20:39 2002 ; 1e25; 1e25; SM; 0.0332; 3.1059; 3.1059;2.488490; 48;|1e25 +T 15R 635507.2 3325289.5 Sat May 25 18:21:24 2002 ; 1e25; 1e25; SM; 0.0345; 3.1404; 3.1404;2.760011; 45;|1e25 +T 15R 635506.4 3325352.4 Sat May 25 18:22:17 2002 ; 1e25; 1e25; SM; 0.0392; 3.1796; 3.1796;2.661007; 53;|1e25 +T 15R 635476.9 3325398.2 Sat May 25 18:23:18 2002 ; 1e25; 1e25; SM; 0.0339; 3.2135; 3.2135;2.003106; 61;|1e25 +T 15R 635474.3 3325486.9 Sat May 25 18:24:37 2002 ; 1e25; 1e25; SM; 0.0553; 3.2688; 3.2688;2.519224; 79;|1e25 +T 15R 635421.9 3325691.3 Sat May 25 18:28:13 2002 ;19.685039; 1e25; SM; 0.1315; 3.4003; 3.4003;2.191816; 216;|1e25 +T 15R 635449.2 3325565.9 Sat May 25 18:31:36 2002 ;6.561680; 1e25; SM; 0.0800; 3.4803; 3.4803;1.418052; 203;|1e25 +T 15R 635464.4 3325505.1 Sat May 25 18:32:56 2002 ; 1e25; 1e25; SM; 0.0390; 3.5193; 3.5193;1.757061; 80;|1e25 +T 15R 635460.4 3325444.1 Sat May 25 18:34:02 2002 ; 1e25; 1e25; SM; 0.0381; 3.5574; 3.5574;2.079208; 66;|1e25 +T 15R 635402.8 3325423.1 Sat May 25 18:36:03 2002 ; 1e25; 1e25; SM; 0.0380; 3.5955; 3.5955;1.131931; 121;|1e25 +T 15R 635351.2 3325426.2 Sat May 25 18:36:48 2002 ; 1e25; 1e25; SM; 0.0320; 3.6275; 3.6275;2.561370; 45;|1e25 +T 15R 635272.3 3325443.7 Sat May 25 18:37:52 2002 ;3.280840; 1e25; SM; 0.0501; 3.6776; 3.6776;2.820732; 64;|1e25 +T 15R 635168.8 3325496.0 Sat May 25 18:39:18 2002 ; 1e25; 1e25; SM; 0.0720; 3.7497; 3.7497;3.014423; 86;|1e25 +T 15R 635156.9 3325549.5 Sat May 25 18:40:15 2002 ; 1e25; 1e25; SM; 0.0342; 3.7838; 3.7838;2.157813; 57;|1e25 +T 15R 635175.7 3325588.5 Sat May 25 18:41:25 2002 ;19.685039; 1e25; SM; 0.0270; 3.8108; 3.8108;1.387488; 70;|1e25 +T 15R 635145.7 3325549.3 Sat May 25 18:42:37 2002 ; 1e25; 1e25; SM; 0.0307; 3.8415; 3.8415;1.534552; 72;|1e25 +T 15R 635162.3 3325503.3 Sat May 25 18:44:01 2002 ; 1e25; 1e25; SM; 0.0305; 3.8720; 3.8720;1.306042; 84;|1e25 +T 15R 635201.3 3325461.3 Sat May 25 18:45:53 2002 ; 1e25; 1e25; SM; 0.0357; 3.9076; 3.9076;1.146618; 112;|1e25 +T 15R 635258.0 3325434.3 Sat May 25 18:46:54 2002 ; 1e25; 1e25; SM; 0.0390; 3.9466; 3.9466;2.299515; 61;|1e25 +T 15R 635306.5 3325409.0 Sat May 25 18:47:42 2002 ; 1e25; 1e25; SM; 0.0340; 3.9806; 3.9806;2.549512; 48;|1e25 +T 15R 635378.9 3325400.7 Sat May 25 18:48:41 2002 ; 1e25; 1e25; SM; 0.0452; 4.0258; 4.0258;2.759120; 59;|1e25 +T 15R 635443.2 3325397.8 Sat May 25 18:49:52 2002 ; 1e25; 1e25; SM; 0.0399; 4.0657; 4.0657;2.022865; 71;|1e25 +T 15R 635474.2 3325361.2 Sat May 25 18:50:49 2002 ; 1e25; 1e25; SM; 0.0299; 4.0956; 4.0956;1.886267; 57;|1e25 +T 15R 635504.3 3325269.2 Sat May 25 18:52:14 2002 ; 1e25; 1e25; SM; 0.0603; 4.1559; 4.1559;2.553308; 85;|1e25 +T 15R 635521.0 3325215.9 Sat May 25 18:52:56 2002 ; 1e25; 1e25; SM; 0.0348; 4.1907; 4.1907;2.985822; 42;|1e25 +T 15R 635534.4 3325173.5 Sat May 25 18:53:38 2002 ; 1e25; 1e25; SM; 0.0277; 4.2184; 4.2184;2.374160; 42;|1e25 +T 15R 635572.8 3325053.9 Sat May 25 18:55:11 2002 ; 1e25; 1e25; SM; 0.0783; 4.2966; 4.2966;3.029246; 93;|1e25 +T 15R 635522.3 3324981.2 Sat May 25 18:56:32 2002 ; 1e25; 1e25; SM; 0.0551; 4.3517; 4.3517;2.447726; 81;|1e25 +T 15R 635474.6 3324940.0 Sat May 25 18:57:24 2002 ; 1e25; 1e25; SM; 0.0392; 4.3909; 4.3909;2.714362; 52;|1e25 +T 15R 635407.9 3324874.5 Sat May 25 18:58:40 2002 ;22.965879; 1e25; SM; 0.0581; 4.4490; 4.4490;2.751982; 76;|1e25 +T 15R 635355.4 3324825.9 Sat May 25 18:59:28 2002 ; 1e25; 1e25; SM; 0.0445; 4.4935; 4.4935;3.334841; 48;|1e25 +T 15R 635298.2 3324777.1 Sat May 25 19:00:22 2002 ; 1e25; 1e25; SM; 0.0468; 4.5403; 4.5403;3.117638; 54;|1e25 +T 15R 635197.2 3324750.0 Sat May 25 19:01:41 2002 ; 1e25; 1e25; SM; 0.0648; 4.6051; 4.6051;2.954261; 79;|1e25 +T 15R 635118.7 3324730.6 Sat May 25 19:02:48 2002 ; 1e25; 1e25; SM; 0.0502; 4.6553; 4.6553;2.697719; 67;|1e25 +T 15R 635070.4 3324739.3 Sat May 25 19:03:43 2002 ; 1e25; 1e25; SM; 0.0305; 4.6858; 4.6858;1.993899; 55;|1e25 +T 15R 635039.3 3324790.5 Sat May 25 19:04:49 2002 ; 1e25; 1e25; SM; 0.0373; 4.7231; 4.7231;2.036431; 66;|1e25 +T 15R 635001.8 3324828.9 Sat May 25 19:05:57 2002 ; 1e25; 1e25; SM; 0.0334; 4.7564; 4.7564;1.765615; 68;|1e25 +R 01 BELLEVUE +W BELLEVUE 19T 326630.3 4699772.7 Sat Jun 02 00:18:15 2001 BELLEVUE ^ 158^Black ^S+N^0 +cA BELLEVUE||||| +cB |||0|0|1.0e25 +cC 77.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W GATE6 19T 326498.9 4699808.2 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA GATE6||||| +cB |||0|0|1.0e25 +cC 87.145307|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W PANTHRCAVE 19T 326451.1 4700224.9 Wed Nov 07 23:53:41 2001 ^ 8243^Black ^S+N^0 +cA PANTHRCAVE||||| +cB |||0|0|1.0e25 +cC 148.646638|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6014MEADOW 19T 326186.1 4700429.0 Wed Nov 28 21:05:28 2001 ^ 18^Black ^S+N^0 +cA 6014MEADOW||||| +cB |||0|0|1.0e25 +cC 123.415169|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6006 19T 326091.0 4700682.6 Sat Jun 02 03:26:55 2001 ^ 18^Black ^S+N^0 +cA 6006||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6006BLUE 19T 326061.3 4700636.2 Wed Nov 28 21:05:28 2001 ^ 18^Black ^S+N^0 +cA 6006BLUE||||| +cB |||0|0|1.0e25 +cC 151.012351|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5096 19T 325951.7 4700674.8 Fri Nov 16 23:03:38 2001 ^ 18^Black ^S+N^0 +cA 5096||||| +cB |||0|0|1.0e25 +cC 147.069896|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5066 19T 325694.0 4700676.9 Wed Nov 28 21:05:28 2001 ^ 8238^Black ^S+N^0 +cA 5066||||| +cB |||0|0|1.0e25 +cC 146.281325|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5067 19T 325661.1 4700716.5 Sat Jun 02 03:26:55 2001 ^ 18^Black ^S+N^0 +cA 5067||||| +cB |||0|0|1.0e25 +cC 189.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5058ROAD 19T 325561.6 4700804.1 Sat Jun 02 00:18:14 2001 ROAD CROSSING ^ 18^Black ^S+N^0 +cA 5058ROAD||||| +cB |||0|0|1.0e25 +cC 177.000001|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5150TANK 19T 325504.6 4700998.2 Sat Jun 02 00:18:16 2001 WATER TANK ^ 8211^Black ^S+N^0 +cA 5150TANK||||| +cB |||0|0|1.0e25 +cC 221.000006|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5142 19T 325480.4 4701240.7 Wed Nov 28 21:05:28 2001 ^ 18^Black ^S+N^0 +cA 5142||||| +cB |||0|0|1.0e25 +cC 165.993197|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5144SUMMIT 19T 325418.6 4701403.9 Wed Nov 28 21:05:28 2001 ^ 8246^Black ^S+N^0 +cA 5144SUMMIT||||| +cB |||0|0|1.0e25 +cC 202.263459|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5156 19T 325538.9 4701616.4 Sat Jun 02 03:26:58 2001 ^ 18^Black ^S+N^0 +cA 5156||||| +cB |||0|0|1.0e25 +cC 418.999990|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5148NANEPA 19T 325474.0 4701892.1 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA 5148NANEPA||||| +cB |||0|0|1.0e25 +cC 393.074416|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5258 19T 325525.9 4702077.2 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA 5258||||| +cB |||0|0|1.0e25 +cC 244.840687|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5252PURPLE 19T 325574.9 4702277.5 Wed Nov 07 23:53:41 2001 ^ 8246^Black ^S+N^0 +cA 5252PURPLE||||| +cB |||0|0|1.0e25 +cC 255.879480|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 527631 19T 325735.7 4702606.4 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA 527631||||| +cB |||0|0|1.0e25 +cC 258.245193|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 527614 19T 325710.4 4702644.8 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA 527614||||| +cB |||0|0|1.0e25 +cC 258.245193|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5267OBSTAC 19T 325698.7 4702733.5 Sat Jun 02 03:27:00 2001 ^ 8204^Black ^S+N^0 +cA 5267OBSTAC||||| +cB |||0|0|1.0e25 +cC 241.999989|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5278 19T 325759.2 4702816.5 Sat Jun 02 03:27:00 2001 ^ 18^Black ^S+N^0 +cA 5278||||| +cB |||0|0|1.0e25 +cC 224.000000|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5289 19T 325881.1 4702950.0 Sat Jun 02 03:27:01 2001 ^ 18^Black ^S+N^0 +cA 5289||||| +cB |||0|0|1.0e25 +cC 210.000011|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5374FIRE 19T 325718.9 4703488.0 Wed Nov 28 21:05:28 2001 ^ 18^Black ^S+N^0 +cA 5374FIRE||||| +cB |||0|0|1.0e25 +cC 173.877706|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5376 19T 325758.3 4703650.1 Sat Jun 02 03:27:02 2001 ^ 18^Black ^S+N^0 +cA 5376||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 5376STREAM 19T 325764.8 4703679.1 Wed Nov 07 23:53:41 2001 ^ 8233^Black ^S+N^0 +cA 5376STREAM||||| +cB |||0|0|1.0e25 +cC 211.724709|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6328 19T 326241.2 4703800.2 Sat Jun 02 03:27:02 2001 ^ 18^Black ^S+N^0 +cA 6328||||| +cB |||0|0|1.0e25 +cC 175.999994|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 635722 19T 326527.7 4703720.8 Sat Jun 02 03:27:02 2001 ^ 18^Black ^S+N^0 +cA 635722||||| +cB |||0|0|1.0e25 +cC 160.000005|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 635783 19T 326582.0 4703730.3 Sat Jun 02 03:27:02 2001 ^ 18^Black ^S+N^0 +cA 635783||||| +cB |||0|0|1.0e25 +cC 160.999999|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6373 19T 326762.1 4703385.6 Sat Jun 02 03:27:03 2001 ^ 18^Black ^S+N^0 +cA 6373||||| +cB |||0|0|1.0e25 +cC 205.000004|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W BEAR HILL 19T 326748.2 4703629.5 Sat Jun 02 03:27:03 2001 BEAR HILL TOWER ^16391^Black ^S+N^0 +cA BEAR HILL||||| +cB |||0|0|1.0e25 +cC 288.000007|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6289 19T 326830.3 4702994.0 Fri Nov 16 23:03:38 2001 ^ 18^Black ^S+N^0 +cA 6289||||| +cB |||0|0|1.0e25 +cC 239.321491|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6297 19T 326910.4 4702728.7 Sat Jun 02 03:27:04 2001 ^ 18^Black ^S+N^0 +cA 6297||||| +cB |||0|0|1.0e25 +cC 238.999995|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6283 19T 326892.6 4702310.1 Fri Nov 16 23:03:38 2001 ^ 18^Black ^S+N^0 +cA 6283||||| +cB |||0|0|1.0e25 +cC 218.821047|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6280 19T 326869.0 4702042.4 Fri Nov 16 23:03:38 2001 ^ 18^Black ^S+N^0 +cA 6280||||| +cB |||0|0|1.0e25 +cC 188.858953|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6177 19T 326799.5 4701712.8 Sat Jun 02 03:27:04 2001 ^ 18^Black ^S+N^0 +cA 6177||||| +cB |||0|0|1.0e25 +cC 203.999997|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6176 19T 326759.4 4701642.2 Sat Jun 02 03:27:04 2001 ^ 18^Black ^S+N^0 +cA 6176||||| +cB |||0|0|1.0e25 +cC 205.000004|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6153 19T 326565.3 4701310.2 Sat Jun 02 03:27:05 2001 ^ 18^Black ^S+N^0 +cA 6153||||| +cB |||0|0|1.0e25 +cC 205.999998|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6171 19T 326774.3 4701173.8 Sat Jun 02 03:27:05 2001 ^ 18^Black ^S+N^0 +cA 6171||||| +cB |||0|0|1.0e25 +cC 181.999995|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6131 19T 326349.9 4701116.5 Sat Jun 02 03:26:58 2001 ^ 18^Black ^S+N^0 +cA 6131||||| +cB |||0|0|1.0e25 +cC 210.000011|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6130 19T 326386.1 4701028.3 Sat Jun 02 03:26:55 2001 ^ 18^Black ^S+N^0 +cA 6130||||| +cB |||0|0|1.0e25 +cC 210.000011|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6029 19T 326200.2 4700983.9 Sat Jun 02 03:26:55 2001 ^ 18^Black ^S+N^0 +cA 6029||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6006 19T 326091.0 4700682.6 Sat Jun 02 03:26:55 2001 ^ 18^Black ^S+N^0 +cA 6006||||| +cB |||0|0|1.0e25 +cC 185.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W 6014MEADOW 19T 326186.1 4700429.0 Wed Nov 28 21:05:28 2001 ^ 18^Black ^S+N^0 +cA 6014MEADOW||||| +cB |||0|0|1.0e25 +cC 123.415169|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W PANTHRCAVE 19T 326451.1 4700224.9 Wed Nov 07 23:53:41 2001 ^ 8243^Black ^S+N^0 +cA PANTHRCAVE||||| +cB |||0|0|1.0e25 +cC 148.646638|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W GATE6 19T 326498.9 4699808.2 Wed Nov 07 23:53:41 2001 ^ 18^Black ^S+N^0 +cA GATE6||||| +cB |||0|0|1.0e25 +cC 87.145307|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +W BELLEVUE 19T 326630.3 4699772.7 Sat Jun 02 00:18:15 2001 BELLEVUE ^ 158^Black ^S+N^0 +cA BELLEVUE||||| +cB |||0|0|1.0e25 +cC 77.000002|1e25|FF|00|00|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF +cD 1.0e25|1.0e25|0 + +E 01 diff --git a/reference/expertgps.gpx b/reference/expertgps.gpx new file mode 100755 index 000000000..b15667965 --- /dev/null +++ b/reference/expertgps.gpx @@ -0,0 +1,1131 @@ + + + + + + + + 44.586548 + 5066 + 5066 + 5066 + Crossing + Crossing + + + 57.607200 + 5067 + 5067 + 5067 + Dot + Intersection + + + 44.826904 + 5096 + 5096 + 5096 + Dot + Dot + + + 50.594727 + 5142 + 5142 + 5142 + Dot + Dot + + + 127.711200 + 5156 + 5156 + 5156 + Dot + Intersection + + + 96.926400 + 5224 + 5224 + 5224 + Dot + Intersection + + + 82.600800 + 5229 + 5229 + 5229 + Dot + Intersection + + + 82.905600 + 5237 + 5237 + 5237 + Dot + Intersection + + + 66.696655 + 5254 + 5254 + 5254 + Dot + Dot + + + 74.627442 + 5258 + 5258 + 5258 + Dot + Dot + + + 65.254761 + 5264 + 5264 + 5264 + Dot + Dot + + + 77.419200 + 526708 + 526708 + 526708 + Dot + Intersection + + + 74.676000 + 526750 + 526750 + 526750 + Dot + Intersection + + + 78.713135 + 527614 + 527614 + 527614 + Dot + Dot + + + 78.713135 + 527631 + 527631 + 527631 + Dot + Dot + + + 68.275200 + 5278 + 5278 + 5278 + Dot + Intersection + + + 64.008000 + 5289 + 5289 + 5289 + Dot + Intersection + + + 52.997925 + 5374FIRE + 5374FIRE + 5374FIRE + Dot + Dot + + + 56.388000 + 5376 + 5376 + 5376 + Dot + Intersection + + + 56.388000 + 6006 + 600698 + 600698 + Dot + Intersection + + + 46.028564 + 6006BLUE + 6006BLUE + 6006BLUE + Dot + Dot + + + 37.616943 + 6014MEADOW + 6014MEADOW + 6014MEADOW + Dot + Dot + + + 56.388000 + 6029 + 6029 + 6029 + Dot + Intersection + + + 50.292000 + 6053 + 6053 + 6053 + Dot + Intersection + + + 25.603200 + 6066 + 6066 + 6066 + Dot + Intersection + + + 34.442400 + 6067 + 6067 + 6067 + Dot + Intersection + + + 30.480000 + 6071 + 6071 + 6071 + Dot + Intersection + + + 15.240000 + 6073 + 6073 + 6073 + Dot + Intersection + + + 37.795200 + 6084 + 6084 + 6084 + Dot + Intersection + + + 64.008000 + 6130 + 6130 + 6130 + Dot + Intersection + + + 64.008000 + 6131 + 6131 + 6131 + Dot + Intersection + + + 62.788800 + 6153 + 6153 + 6153 + Dot + Intersection + + + 55.473600 + 6171 + 6171 + 6171 + Dot + Intersection + + + 62.484000 + 6176 + 6176 + 6176 + Dot + Intersection + + + 62.179200 + 6177 + 6177 + 6177 + Dot + Intersection + + + 69.799200 + 6272 + 6272 + 6272 + Dot + Intersection + + + 73.152000 + 6272 + 6272 + 6272 + Dot + Intersection + + + 70.104000 + 6278 + 6278 + 6278 + Dot + Intersection + + + 57.564209 + 6280 + 6280 + 6280 + Dot + Dot + + + 66.696655 + 6283 + 6283 + 6283 + Dot + Dot + + + 72.945191 + 6289 + 6289 + 6289 + Dot + Dot + + + 72.847200 + 6297 + 6297 + 6297 + Dot + Intersection + + + 53.644800 + 6328 + 6328 + 6328 + Dot + Intersection + + + 43.891200 + 6354 + 6354 + 6354 + Dot + Intersection + + + 48.768000 + 635722 + 635722 + 635722 + Dot + Intersection + + + 49.072800 + 635783 + 635783 + 635783 + Dot + Intersection + + + 62.484000 + 6373 + 6373 + 6373 + Dot + Intersection + + + 3.962400 + 6634 + 6634 + 6634 + Dot + Intersection + + + 13.411200 + 6979 + 6979 + 6979 + Dot + Intersection + + + 34.012085 + 6997 + 6997 + 6997 + Dot + Dot + + + 87.782400 + BEAR HILL + BEAR HILL TOWER + Bear Hill Tower + Tall Tower + Tower + + + 23.469600 + BELLEVUE + BELLEVUE + Bellevue Parking Lot + Parking Area + Parking + + + 43.384766 + 6016 + Bike Loop Connector + Bike Loop Connector + Waypoint + Intersection + + + 89.916000 + 5236BRIDGE + Bridge + Bridge + Bridge + Bridge + + + 55.473600 + 5376BRIDGE + Bridge + Bridge + Bridge + Bridge + + + 52.730400 + 6181CROSS + Crossing + Crossing + Crossing + Crossing + + + 45.110400 + 6042CROSS + Crossing + Crossing + Crossing + Crossing + + + DARKHOLLPO + Dark Hollow Pond + Dark Hollow Pond + Fishing Area + + + 56.083200 + 6121DEAD + Dead End + Dead End + Danger Area + Dead End + + + 117.043200 + 5179DEAD + Dead End + Dead End + Danger Area + Dead End + + + 69.494400 + 5299DEAD + Dead End + Dead End + Danger Area + Dead End + + + 56.997600 + 5376DEAD + Dead End + Dead End + Danger Area + Dead End + + + 46.939200 + 6353DEAD + Dead End + Dead End + Danger Area + Dead End + + + 61.264800 + 6155DEAD + Dead End + Dead End + Danger Area + Dead End + + + 110.947200 + GATE14 + Gate 14 + Gate 14 + Truck Stop + Road + + + 77.724000 + GATE16 + Gate 16 + Gate 16 + Truck Stop + Road + + + 65.836800 + GATE17 + Gate 17 + Gate 17 + Truck Stop + Road + + + 57.302400 + GATE19 + Gate 19 + Gate 19 + Truck Stop + Road + + + 49.377600 + GATE21 + Gate 21 + Gate 21 + Truck Stop + Road + + + 81.076800 + GATE24 + Gate 24 + Gate 24 + Truck Stop + Road + + + 21.515015 + GATE5 + Gate 5 + Gate 5 + Truck Stop + Truck Stop + + + 26.561890 + GATE6 + Gate 6 + Gate 6 + Waypoint + Trail Head + + + 32.004000 + 6077LOGS + Log Crossing + Log Crossing + Amusement Park + Obstacle + + + 119.809082 + 5148NANEPA + Nanepashemet Road Crossing + Nanepashemet Road Crossing + Waypoint + Trail Head + + + 73.761600 + 5267OBSTAC + Obstacle + Obstacle + Amusement Park + Obstacle + + + 45.307495 + PANTHRCAVE + Panther Cave + Panther Cave + Tunnel + Tunnel + + + 77.992066 + 5252PURPLE + Purple Rock Hill + Purple Rock Hill + Summit + Summit + + + 67.970400 + 5287WATER + Reservoir + Reservoir + Swimming Area + Reservoir + + + 81.076800 + 5239ROAD + Road + Road + Truck Stop + Road + + + 67.360800 + 5278ROAD + Road + Road + Truck Stop + Road + + + 53.949600 + 5058ROAD + ROAD CROSSING + Road Crossing + Dot + Road Crossing + + + 69.799200 + SHEEPFOLD + Sheepfold Parking Lot + Sheepfold Parking Lot + Parking Area + Parking + + + 64.008000 + SOAPBOX + Soap Box Derby Track + Soap Box Derby Track + Cemetery + Intersection + + + 64.533692 + 5376STREAM + Stream Crossing + Stream Crossing + Bridge + Bridge + + + 61.649902 + 5144SUMMIT + Summit + Summit + Summit + Summit + + + 67.360800 + 5150TANK + WATER TANK + Water Tank + Museum + Water Tank + + + BELLEVUE + Bike Loop Bellevue + 1 + + 23.469600 + BELLEVUE + BELLEVUE + Bellevue Parking Lot + Parking Area + + + 26.561890 + GATE6 + Gate 6 + Waypoint + + + 45.307495 + PANTHRCAVE + Panther Cave + Tunnel + + + 37.616943 + 6014MEADOW + 6014MEADOW + Dot + + + 56.388000 + 6006 + 600698 + Dot + + + 46.028564 + 6006BLUE + 6006BLUE + Dot + + + 44.826904 + 5096 + 5096 + Dot + + + 44.586548 + 5066 + 5066 + Crossing + + + 57.607200 + 5067 + 5067 + Dot + + + 53.949600 + 5058ROAD + ROAD CROSSING + Road Crossing + Dot + + + 67.360800 + 5150TANK + WATER TANK + Water Tank + Museum + + + 50.594727 + 5142 + 5142 + Dot + + + 61.649902 + 5144SUMMIT + Summit + Summit + + + 127.711200 + 5156 + 5156 + Dot + + + 119.809082 + 5148NANEPA + Nanepashemet Road Crossing + Waypoint + + + 74.627442 + 5258 + 5258 + Dot + + + 77.992066 + 5252PURPLE + Purple Rock Hill + Summit + + + 78.713135 + 527631 + 527631 + Dot + + + 78.713135 + 527614 + 527614 + Dot + + + 73.761600 + 5267OBSTAC + Obstacle + Amusement Park + + + 68.275200 + 5278 + 5278 + Dot + + + 64.008000 + 5289 + 5289 + Dot + + + 52.997925 + 5374FIRE + 5374FIRE + Dot + + + 56.388000 + 5376 + 5376 + Dot + + + 64.533692 + 5376STREAM + Stream Crossing + Bridge + + + 53.644800 + 6328 + 6328 + Dot + + + 48.768000 + 635722 + 635722 + Dot + + + 49.072800 + 635783 + 635783 + Dot + + + 62.484000 + 6373 + 6373 + Dot + + + 87.782400 + BEAR HILL + BEAR HILL TOWER + Bear Hill Tower + Tall Tower + + + 72.945191 + 6289 + 6289 + Dot + + + 72.847200 + 6297 + 6297 + Dot + + + 66.696655 + 6283 + 6283 + Dot + + + 57.564209 + 6280 + 6280 + Dot + + + 62.179200 + 6177 + 6177 + Dot + + + 62.484000 + 6176 + 6176 + Dot + + + 62.788800 + 6153 + 6153 + Dot + + + 55.473600 + 6171 + 6171 + Dot + + + 64.008000 + 6131 + 6131 + Dot + + + 64.008000 + 6130 + 6130 + Dot + + + 56.388000 + 6029 + 6029 + Dot + + + 56.388000 + 6006 + 600698 + Dot + + + 37.616943 + 6014MEADOW + 6014MEADOW + Dot + + + 45.307495 + PANTHRCAVE + Panther Cave + Tunnel + + + 26.561890 + GATE6 + Gate 6 + Waypoint + + + 23.469600 + BELLEVUE + BELLEVUE + Bellevue Parking Lot + Parking Area + + + + 1 + + + 1.000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2.000000 + + + + + 1.000000 + + + + + + + + + + + 2.000000 + + + 1.000000 + + + 1.000000 + + + + + 2.000000 + + + + + + + + + + + + + 6.000000 + + + 2.000000 + + + + + + + + + + + 1.000000 + + + + + + + 6.000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 7.000000 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/reference/expertgps.rwf b/reference/expertgps.rwf new file mode 100644 index 000000000..ef01ae1fe --- /dev/null +++ b/reference/expertgps.rwf @@ -0,0 +1,2229 @@ +[Wp0] +Loc=My Waypoints +Name=5058ROAD +Lat=42.439993000000001 +Long=-71.120925000000000 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Road Crossing +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.012662037000000 +[Wp1] +Loc=My Waypoints +Name=5066 +Lat=42.438878000000003 +Long=-71.119276999999997 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5066 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37223.878796296300000 +[Wp2] +Loc=My Waypoints +Name=5067 +Lat=42.439227000000002 +Long=-71.119688999999994 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5067 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143692129600000 +[Wp3] +Loc=My Waypoints +Name=5096 +Lat=42.438916999999996 +Long=-71.116146000000001 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5096 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37211.960856481500000 +[Wp4] +Loc=My Waypoints +Name=5142 +Lat=42.443904000000003 +Long=-71.122044000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5142 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37223.878796296300000 +[Wp5] +Loc=My Waypoints +Name=5144SUMMIT +Lat=42.445359000000003 +Long=-71.122844999999998 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Summit +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37223.878796296300000 +[Wp6] +Loc=My Waypoints +Name=5148NANEPA +Lat=42.449764999999999 +Long=-71.122320000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Nanepashemet Road Crossing +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37202.995613425900000 +[Wp7] +Loc=My Waypoints +Name=5150TANK +Lat=42.441727000000000 +Long=-71.121675999999994 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Water Tank +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.012685185200000 +[Wp8] +Loc=My Waypoints +Name=5156 +Lat=42.447298000000004 +Long=-71.121447000000003 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5156 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143726851800000 +[Wp9] +Loc=My Waypoints +Name=5179DEAD +Lat=42.449866000000000 +Long=-71.119298000000001 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Dead End +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143738425900000 +[Wp10] +Loc=My Waypoints +Name=5224 +Lat=42.454872999999999 +Long=-71.125094000000004 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5224 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143738425900000 +[Wp11] +Loc=My Waypoints +Name=5229 +Lat=42.459079000000003 +Long=-71.124988000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5229 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143738425900000 +[Wp12] +Loc=My Waypoints +Name=5236BRIDGE +Lat=42.456468999999998 +Long=-71.124651000000000 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Bridge +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143738425900000 +[Wp13] +Loc=My Waypoints +Name=5237 +Lat=42.456978999999997 +Long=-71.124474000000006 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5237 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143738425900000 +[Wp14] +Loc=My Waypoints +Name=5239ROAD +Lat=42.459277999999998 +Long=-71.124573999999996 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Road +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143750000000000 +[Wp15] +Loc=My Waypoints +Name=5252PURPLE +Lat=42.453256000000003 +Long=-71.121211000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Purple Rock Hill +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37202.995613425900000 +[Wp16] +Loc=My Waypoints +Name=5254 +Lat=42.454400999999997 +Long=-71.120990000000006 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5254 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37223.878796296300000 +[Wp17] +Loc=My Waypoints +Name=5258 +Lat=42.451442000000000 +Long=-71.121746000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5258 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37202.995613425900000 +[Wp18] +Loc=My Waypoints +Name=5264 +Lat=42.454403999999997 +Long=-71.120660000000001 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5264 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37223.878796296300000 +[Wp19] +Loc=My Waypoints +Name=526708 +Lat=42.457760999999998 +Long=-71.121044999999995 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=526708 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143750000000000 +[Wp20] +Loc=My Waypoints +Name=526750 +Lat=42.457089000000003 +Long=-71.120312999999996 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=526750 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143750000000000 +[Wp21] +Loc=My Waypoints +Name=5267OBSTAC +Lat=42.457388000000002 +Long=-71.119844999999998 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Obstacle +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143750000000000 +[Wp22] +Loc=My Waypoints +Name=527614 +Lat=42.456592000000001 +Long=-71.119675999999998 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=527614 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37202.995613425900000 +[Wp23] +Loc=My Waypoints +Name=527631 +Lat=42.456251999999999 +Long=-71.119355999999996 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=527631 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37202.995613425900000 +[Wp24] +Loc=My Waypoints +Name=5278 +Lat=42.458148000000001 +Long=-71.119135000000000 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5278 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143750000000000 +[Wp25] +Loc=My Waypoints +Name=5278ROAD +Lat=42.458781999999999 +Long=-71.118990999999994 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Road +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143761574100000 +[Wp26] +Loc=My Waypoints +Name=5287WATER +Lat=42.457734000000002 +Long=-71.117480999999998 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=44 +Fixed=1 +Locked=0 +Notes=Reservoir +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143761574100000 +[Wp27] +Loc=My Waypoints +Name=5289 +Lat=42.459377000000003 +Long=-71.117693000000003 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5289 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143761574100000 +[Wp28] +Loc=My Waypoints +Name=5299DEAD +Lat=42.459629000000000 +Long=-71.116523999999998 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Dead End +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143761574100000 +[Wp29] +Loc=My Waypoints +Name=5374FIRE +Lat=42.464182999999998 +Long=-71.119827999999998 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5374FIRE +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37223.878796296300000 +[Wp30] +Loc=My Waypoints +Name=5376 +Lat=42.465649999999997 +Long=-71.119399000000001 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=5376 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143773148100000 +[Wp31] +Loc=My Waypoints +Name=5376BRIDGE +Lat=42.465758999999998 +Long=-71.119815000000003 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Bridge +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143761574100000 +[Wp32] +Loc=My Waypoints +Name=5376DEAD +Lat=42.465485000000001 +Long=-71.119147999999996 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Dead End +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143773148100000 +[Wp33] +Loc=My Waypoints +Name=5376STREAM +Lat=42.465913000000000 +Long=-71.119327999999996 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Stream Crossing +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37202.995613425900000 +[Wp34] +Loc=My Waypoints +Name=6006 +Lat=42.439017999999997 +Long=-71.114456000000004 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=600698 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143692129600000 +[Wp35] +Loc=My Waypoints +Name=6006BLUE +Lat=42.438594000000002 +Long=-71.114802999999995 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6006BLUE +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37223.878796296300000 +[Wp36] +Loc=My Waypoints +Name=6014MEADOW +Lat=42.436757000000000 +Long=-71.113223000000005 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6014MEADOW +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37223.878796296300000 +[Wp37] +Loc=My Waypoints +Name=6016 +Lat=42.438665999999998 +Long=-71.114079000000004 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Bike Loop Connector +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37223.878796296300000 +[Wp38] +Loc=My Waypoints +Name=6029 +Lat=42.441754000000003 +Long=-71.113219999999998 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6029 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143692129600000 +[Wp39] +Loc=My Waypoints +Name=6042CROSS +Lat=42.435471999999997 +Long=-71.109663999999995 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Crossing +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143807870400000 +[Wp40] +Loc=My Waypoints +Name=6053 +Lat=42.436242999999997 +Long=-71.109075000000004 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6053 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143807870400000 +[Wp41] +Loc=My Waypoints +Name=6066 +Lat=42.439250000000001 +Long=-71.107500000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6066 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143715277800000 +[Wp42] +Loc=My Waypoints +Name=6067 +Lat=42.439763999999997 +Long=-71.107581999999994 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6067 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143715277800000 +[Wp43] +Loc=My Waypoints +Name=6071 +Lat=42.434766000000003 +Long=-71.105874000000000 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6071 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143715277800000 +[Wp44] +Loc=My Waypoints +Name=6073 +Lat=42.433304000000000 +Long=-71.106599000000003 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6073 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143703703700000 +[Wp45] +Loc=My Waypoints +Name=6077LOGS +Lat=42.439501999999997 +Long=-71.106555999999998 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Log Crossing +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.012685185200000 +[Wp46] +Loc=My Waypoints +Name=6084 +Lat=42.437337999999997 +Long=-71.104771999999997 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6084 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143715277800000 +[Wp47] +Loc=My Waypoints +Name=6121DEAD +Lat=42.443109000000000 +Long=-71.112674999999996 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Dead End +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143715277800000 +[Wp48] +Loc=My Waypoints +Name=6130 +Lat=42.442196000000003 +Long=-71.110974999999996 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6130 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143692129600000 +[Wp49] +Loc=My Waypoints +Name=6131 +Lat=42.442981000000003 +Long=-71.111440999999999 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6131 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143726851800000 +[Wp50] +Loc=My Waypoints +Name=6153 +Lat=42.444772999999998 +Long=-71.108881999999994 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6153 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143807870400000 +[Wp51] +Loc=My Waypoints +Name=6155DEAD +Lat=42.446793000000000 +Long=-71.108784000000000 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Dead End +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143796296300000 +[Wp52] +Loc=My Waypoints +Name=6171 +Lat=42.443592000000002 +Long=-71.106301000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6171 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143807870400000 +[Wp53] +Loc=My Waypoints +Name=6176 +Lat=42.447803999999998 +Long=-71.106623999999996 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6176 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143796296300000 +[Wp54] +Loc=My Waypoints +Name=6177 +Lat=42.448447999999999 +Long=-71.106157999999994 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6177 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143796296300000 +[Wp55] +Loc=My Waypoints +Name=6181CROSS +Lat=42.442993000000001 +Long=-71.105878000000004 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Crossing +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143807870400000 +[Wp56] +Loc=My Waypoints +Name=6272 +Lat=42.453415000000000 +Long=-71.106782999999993 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6272 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143692129600000 +[Wp57] +Loc=My Waypoints +Name=6272.1 +Lat=42.453434000000001 +Long=-71.107253000000000 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6272 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143703703700000 +[Wp58] +Loc=My Waypoints +Name=6278 +Lat=42.458297999999999 +Long=-71.106770999999995 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6278 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143796296300000 +[Wp59] +Loc=My Waypoints +Name=6280 +Lat=42.451430000000002 +Long=-71.105412999999999 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6280 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37211.960856481500000 +[Wp60] +Loc=My Waypoints +Name=6283 +Lat=42.453845000000001 +Long=-71.105205999999995 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6283 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37211.960856481500000 +[Wp61] +Loc=My Waypoints +Name=6289 +Lat=42.459986000000001 +Long=-71.106170000000006 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6289 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37211.960856481500000 +[Wp62] +Loc=My Waypoints +Name=6297 +Lat=42.457616000000002 +Long=-71.105115999999995 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6297 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143796296300000 +[Wp63] +Loc=My Waypoints +Name=6328 +Lat=42.467109999999998 +Long=-71.113574000000000 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6328 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143773148100000 +[Wp64] +Loc=My Waypoints +Name=6353DEAD +Lat=42.462775999999998 +Long=-71.109986000000006 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Dead End +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143784722200000 +[Wp65] +Loc=My Waypoints +Name=6354 +Lat=42.464202000000000 +Long=-71.109863000000004 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6354 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143784722200000 +[Wp66] +Loc=My Waypoints +Name=635722 +Lat=42.466459000000000 +Long=-71.110067000000001 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=635722 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143773148100000 +[Wp67] +Loc=My Waypoints +Name=635783 +Lat=42.466557000000002 +Long=-71.109409999999997 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=635783 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143773148100000 +[Wp68] +Loc=My Waypoints +Name=6373 +Lat=42.463495000000002 +Long=-71.107117000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6373 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143784722200000 +[Wp69] +Loc=My Waypoints +Name=6634 +Lat=42.401051000000002 +Long=-71.110241000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6634 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143703703700000 +[Wp70] +Loc=My Waypoints +Name=6979 +Lat=42.432620999999997 +Long=-71.106532000000001 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6979 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143703703700000 +[Wp71] +Loc=My Waypoints +Name=6997 +Lat=42.431032999999999 +Long=-71.107883000000001 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=6997 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37211.960856481500000 +[Wp72] +Loc=My Waypoints +Name=BEAR HILL +Lat=42.465687000000003 +Long=-71.107360000000000 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Bear Hill Tower +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143784722200000 +[Wp73] +Loc=My Waypoints +Name=BELLEVUE +Lat=42.430950000000003 +Long=-71.107628000000005 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Bellevue Parking Lot +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.012673611100000 +[Wp74] +Loc=My Waypoints +Name=DARKHOLLPO +Lat=42.458516000000003 +Long=-71.103645999999998 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Dark Hollow Pond +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=25569.000000000000000 +[Wp75] +Loc=My Waypoints +Name=GATE14 +Lat=42.451203999999997 +Long=-71.126602000000005 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Gate 14 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143738425900000 +[Wp76] +Loc=My Waypoints +Name=GATE16 +Lat=42.458499000000003 +Long=-71.122078000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Gate 16 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143750000000000 +[Wp77] +Loc=My Waypoints +Name=GATE17 +Lat=42.459375999999999 +Long=-71.119237999999996 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Gate 17 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143761574100000 +[Wp78] +Loc=My Waypoints +Name=GATE19 +Lat=42.466352999999998 +Long=-71.119240000000005 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Gate 19 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143773148100000 +[Wp79] +Loc=My Waypoints +Name=GATE21 +Lat=42.468654999999998 +Long=-71.107697000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Gate 21 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143784722200000 +[Wp80] +Loc=My Waypoints +Name=GATE24 +Lat=42.456718000000002 +Long=-71.102973000000006 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Gate 24 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143784722200000 +[Wp81] +Loc=My Waypoints +Name=GATE5 +Lat=42.430847000000000 +Long=-71.107690000000005 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Gate 5 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37223.878796296300000 +[Wp82] +Loc=My Waypoints +Name=GATE6 +Lat=42.431240000000003 +Long=-71.109235999999996 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Gate 6 +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37202.995613425900000 +[Wp83] +Loc=My Waypoints +Name=PANTHRCAVE +Lat=42.434980000000003 +Long=-71.109942000000004 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Panther Cave +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37202.995613425900000 +[Wp84] +Loc=My Waypoints +Name=SHEEPFOLD +Lat=42.453415000000000 +Long=-71.106781999999995 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Sheepfold Parking Lot +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.012650463000000 +[Wp85] +Loc=My Waypoints +Name=SOAPBOX +Lat=42.455956000000000 +Long=-71.107483000000002 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=Soap Box Derby Track +Rel= +RelSet=0 +RcCount=0 +RcRadius=0.000000000000000 +Show=1 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=37044.143796296300000 +[Rt0] +Name=BELLEVUE +Visible=1 +Mk0=BELLEVUE +Cog0=0.000000000000000 +Eta0=0.000000000000000 +Length0=0.000000000000000 +PredictedDrift0=0.000000000000000 +PredictedSet0=0.000000000000000 +PredictedSog0=0.000000000000000 +PredictedTime0=0.000000000000000 +PredictedTwa0=0.000000000000000 +PredictedTwd0=0.000000000000000 +PredictedTws0=0.000000000000000 +Mk1=GATE6 +Cog1=0.000000000000000 +Eta1=0.000000000000000 +Length1=0.000000000000000 +PredictedDrift1=0.000000000000000 +PredictedSet1=0.000000000000000 +PredictedSog1=0.000000000000000 +PredictedTime1=0.000000000000000 +PredictedTwa1=0.000000000000000 +PredictedTwd1=0.000000000000000 +PredictedTws1=0.000000000000000 +Mk2=PANTHRCAVE +Cog2=0.000000000000000 +Eta2=0.000000000000000 +Length2=0.000000000000000 +PredictedDrift2=0.000000000000000 +PredictedSet2=0.000000000000000 +PredictedSog2=0.000000000000000 +PredictedTime2=0.000000000000000 +PredictedTwa2=0.000000000000000 +PredictedTwd2=0.000000000000000 +PredictedTws2=0.000000000000000 +Mk3=6014MEADOW +Cog3=0.000000000000000 +Eta3=0.000000000000000 +Length3=0.000000000000000 +PredictedDrift3=0.000000000000000 +PredictedSet3=0.000000000000000 +PredictedSog3=0.000000000000000 +PredictedTime3=0.000000000000000 +PredictedTwa3=0.000000000000000 +PredictedTwd3=0.000000000000000 +PredictedTws3=0.000000000000000 +Mk4=6006 +Cog4=0.000000000000000 +Eta4=0.000000000000000 +Length4=0.000000000000000 +PredictedDrift4=0.000000000000000 +PredictedSet4=0.000000000000000 +PredictedSog4=0.000000000000000 +PredictedTime4=0.000000000000000 +PredictedTwa4=0.000000000000000 +PredictedTwd4=0.000000000000000 +PredictedTws4=0.000000000000000 +Mk5=6006BLUE +Cog5=0.000000000000000 +Eta5=0.000000000000000 +Length5=0.000000000000000 +PredictedDrift5=0.000000000000000 +PredictedSet5=0.000000000000000 +PredictedSog5=0.000000000000000 +PredictedTime5=0.000000000000000 +PredictedTwa5=0.000000000000000 +PredictedTwd5=0.000000000000000 +PredictedTws5=0.000000000000000 +Mk6=5096 +Cog6=0.000000000000000 +Eta6=0.000000000000000 +Length6=0.000000000000000 +PredictedDrift6=0.000000000000000 +PredictedSet6=0.000000000000000 +PredictedSog6=0.000000000000000 +PredictedTime6=0.000000000000000 +PredictedTwa6=0.000000000000000 +PredictedTwd6=0.000000000000000 +PredictedTws6=0.000000000000000 +Mk7=5066 +Cog7=0.000000000000000 +Eta7=0.000000000000000 +Length7=0.000000000000000 +PredictedDrift7=0.000000000000000 +PredictedSet7=0.000000000000000 +PredictedSog7=0.000000000000000 +PredictedTime7=0.000000000000000 +PredictedTwa7=0.000000000000000 +PredictedTwd7=0.000000000000000 +PredictedTws7=0.000000000000000 +Mk8=5067 +Cog8=0.000000000000000 +Eta8=0.000000000000000 +Length8=0.000000000000000 +PredictedDrift8=0.000000000000000 +PredictedSet8=0.000000000000000 +PredictedSog8=0.000000000000000 +PredictedTime8=0.000000000000000 +PredictedTwa8=0.000000000000000 +PredictedTwd8=0.000000000000000 +PredictedTws8=0.000000000000000 +Mk9=5058ROAD +Cog9=0.000000000000000 +Eta9=0.000000000000000 +Length9=0.000000000000000 +PredictedDrift9=0.000000000000000 +PredictedSet9=0.000000000000000 +PredictedSog9=0.000000000000000 +PredictedTime9=0.000000000000000 +PredictedTwa9=0.000000000000000 +PredictedTwd9=0.000000000000000 +PredictedTws9=0.000000000000000 +Mk10=5150TANK +Cog10=0.000000000000000 +Eta10=0.000000000000000 +Length10=0.000000000000000 +PredictedDrift10=0.000000000000000 +PredictedSet10=0.000000000000000 +PredictedSog10=0.000000000000000 +PredictedTime10=0.000000000000000 +PredictedTwa10=0.000000000000000 +PredictedTwd10=0.000000000000000 +PredictedTws10=0.000000000000000 +Mk11=5142 +Cog11=0.000000000000000 +Eta11=0.000000000000000 +Length11=0.000000000000000 +PredictedDrift11=0.000000000000000 +PredictedSet11=0.000000000000000 +PredictedSog11=0.000000000000000 +PredictedTime11=0.000000000000000 +PredictedTwa11=0.000000000000000 +PredictedTwd11=0.000000000000000 +PredictedTws11=0.000000000000000 +Mk12=5144SUMMIT +Cog12=0.000000000000000 +Eta12=0.000000000000000 +Length12=0.000000000000000 +PredictedDrift12=0.000000000000000 +PredictedSet12=0.000000000000000 +PredictedSog12=0.000000000000000 +PredictedTime12=0.000000000000000 +PredictedTwa12=0.000000000000000 +PredictedTwd12=0.000000000000000 +PredictedTws12=0.000000000000000 +Mk13=5156 +Cog13=0.000000000000000 +Eta13=0.000000000000000 +Length13=0.000000000000000 +PredictedDrift13=0.000000000000000 +PredictedSet13=0.000000000000000 +PredictedSog13=0.000000000000000 +PredictedTime13=0.000000000000000 +PredictedTwa13=0.000000000000000 +PredictedTwd13=0.000000000000000 +PredictedTws13=0.000000000000000 +Mk14=5148NANEPA +Cog14=0.000000000000000 +Eta14=0.000000000000000 +Length14=0.000000000000000 +PredictedDrift14=0.000000000000000 +PredictedSet14=0.000000000000000 +PredictedSog14=0.000000000000000 +PredictedTime14=0.000000000000000 +PredictedTwa14=0.000000000000000 +PredictedTwd14=0.000000000000000 +PredictedTws14=0.000000000000000 +Mk15=5258 +Cog15=0.000000000000000 +Eta15=0.000000000000000 +Length15=0.000000000000000 +PredictedDrift15=0.000000000000000 +PredictedSet15=0.000000000000000 +PredictedSog15=0.000000000000000 +PredictedTime15=0.000000000000000 +PredictedTwa15=0.000000000000000 +PredictedTwd15=0.000000000000000 +PredictedTws15=0.000000000000000 +Mk16=5252PURPLE +Cog16=0.000000000000000 +Eta16=0.000000000000000 +Length16=0.000000000000000 +PredictedDrift16=0.000000000000000 +PredictedSet16=0.000000000000000 +PredictedSog16=0.000000000000000 +PredictedTime16=0.000000000000000 +PredictedTwa16=0.000000000000000 +PredictedTwd16=0.000000000000000 +PredictedTws16=0.000000000000000 +Mk17=527631 +Cog17=0.000000000000000 +Eta17=0.000000000000000 +Length17=0.000000000000000 +PredictedDrift17=0.000000000000000 +PredictedSet17=0.000000000000000 +PredictedSog17=0.000000000000000 +PredictedTime17=0.000000000000000 +PredictedTwa17=0.000000000000000 +PredictedTwd17=0.000000000000000 +PredictedTws17=0.000000000000000 +Mk18=527614 +Cog18=0.000000000000000 +Eta18=0.000000000000000 +Length18=0.000000000000000 +PredictedDrift18=0.000000000000000 +PredictedSet18=0.000000000000000 +PredictedSog18=0.000000000000000 +PredictedTime18=0.000000000000000 +PredictedTwa18=0.000000000000000 +PredictedTwd18=0.000000000000000 +PredictedTws18=0.000000000000000 +Mk19=5267OBSTAC +Cog19=0.000000000000000 +Eta19=0.000000000000000 +Length19=0.000000000000000 +PredictedDrift19=0.000000000000000 +PredictedSet19=0.000000000000000 +PredictedSog19=0.000000000000000 +PredictedTime19=0.000000000000000 +PredictedTwa19=0.000000000000000 +PredictedTwd19=0.000000000000000 +PredictedTws19=0.000000000000000 +Mk20=5278 +Cog20=0.000000000000000 +Eta20=0.000000000000000 +Length20=0.000000000000000 +PredictedDrift20=0.000000000000000 +PredictedSet20=0.000000000000000 +PredictedSog20=0.000000000000000 +PredictedTime20=0.000000000000000 +PredictedTwa20=0.000000000000000 +PredictedTwd20=0.000000000000000 +PredictedTws20=0.000000000000000 +Mk21=5289 +Cog21=0.000000000000000 +Eta21=0.000000000000000 +Length21=0.000000000000000 +PredictedDrift21=0.000000000000000 +PredictedSet21=0.000000000000000 +PredictedSog21=0.000000000000000 +PredictedTime21=0.000000000000000 +PredictedTwa21=0.000000000000000 +PredictedTwd21=0.000000000000000 +PredictedTws21=0.000000000000000 +Mk22=5374FIRE +Cog22=0.000000000000000 +Eta22=0.000000000000000 +Length22=0.000000000000000 +PredictedDrift22=0.000000000000000 +PredictedSet22=0.000000000000000 +PredictedSog22=0.000000000000000 +PredictedTime22=0.000000000000000 +PredictedTwa22=0.000000000000000 +PredictedTwd22=0.000000000000000 +PredictedTws22=0.000000000000000 +Mk23=5376 +Cog23=0.000000000000000 +Eta23=0.000000000000000 +Length23=0.000000000000000 +PredictedDrift23=0.000000000000000 +PredictedSet23=0.000000000000000 +PredictedSog23=0.000000000000000 +PredictedTime23=0.000000000000000 +PredictedTwa23=0.000000000000000 +PredictedTwd23=0.000000000000000 +PredictedTws23=0.000000000000000 +Mk24=5376STREAM +Cog24=0.000000000000000 +Eta24=0.000000000000000 +Length24=0.000000000000000 +PredictedDrift24=0.000000000000000 +PredictedSet24=0.000000000000000 +PredictedSog24=0.000000000000000 +PredictedTime24=0.000000000000000 +PredictedTwa24=0.000000000000000 +PredictedTwd24=0.000000000000000 +PredictedTws24=0.000000000000000 +Mk25=6328 +Cog25=0.000000000000000 +Eta25=0.000000000000000 +Length25=0.000000000000000 +PredictedDrift25=0.000000000000000 +PredictedSet25=0.000000000000000 +PredictedSog25=0.000000000000000 +PredictedTime25=0.000000000000000 +PredictedTwa25=0.000000000000000 +PredictedTwd25=0.000000000000000 +PredictedTws25=0.000000000000000 +Mk26=635722 +Cog26=0.000000000000000 +Eta26=0.000000000000000 +Length26=0.000000000000000 +PredictedDrift26=0.000000000000000 +PredictedSet26=0.000000000000000 +PredictedSog26=0.000000000000000 +PredictedTime26=0.000000000000000 +PredictedTwa26=0.000000000000000 +PredictedTwd26=0.000000000000000 +PredictedTws26=0.000000000000000 +Mk27=635783 +Cog27=0.000000000000000 +Eta27=0.000000000000000 +Length27=0.000000000000000 +PredictedDrift27=0.000000000000000 +PredictedSet27=0.000000000000000 +PredictedSog27=0.000000000000000 +PredictedTime27=0.000000000000000 +PredictedTwa27=0.000000000000000 +PredictedTwd27=0.000000000000000 +PredictedTws27=0.000000000000000 +Mk28=6373 +Cog28=0.000000000000000 +Eta28=0.000000000000000 +Length28=0.000000000000000 +PredictedDrift28=0.000000000000000 +PredictedSet28=0.000000000000000 +PredictedSog28=0.000000000000000 +PredictedTime28=0.000000000000000 +PredictedTwa28=0.000000000000000 +PredictedTwd28=0.000000000000000 +PredictedTws28=0.000000000000000 +Mk29=BEAR HILL +Cog29=0.000000000000000 +Eta29=0.000000000000000 +Length29=0.000000000000000 +PredictedDrift29=0.000000000000000 +PredictedSet29=0.000000000000000 +PredictedSog29=0.000000000000000 +PredictedTime29=0.000000000000000 +PredictedTwa29=0.000000000000000 +PredictedTwd29=0.000000000000000 +PredictedTws29=0.000000000000000 +Mk30=6289 +Cog30=0.000000000000000 +Eta30=0.000000000000000 +Length30=0.000000000000000 +PredictedDrift30=0.000000000000000 +PredictedSet30=0.000000000000000 +PredictedSog30=0.000000000000000 +PredictedTime30=0.000000000000000 +PredictedTwa30=0.000000000000000 +PredictedTwd30=0.000000000000000 +PredictedTws30=0.000000000000000 +Mk31=6297 +Cog31=0.000000000000000 +Eta31=0.000000000000000 +Length31=0.000000000000000 +PredictedDrift31=0.000000000000000 +PredictedSet31=0.000000000000000 +PredictedSog31=0.000000000000000 +PredictedTime31=0.000000000000000 +PredictedTwa31=0.000000000000000 +PredictedTwd31=0.000000000000000 +PredictedTws31=0.000000000000000 +Mk32=6283 +Cog32=0.000000000000000 +Eta32=0.000000000000000 +Length32=0.000000000000000 +PredictedDrift32=0.000000000000000 +PredictedSet32=0.000000000000000 +PredictedSog32=0.000000000000000 +PredictedTime32=0.000000000000000 +PredictedTwa32=0.000000000000000 +PredictedTwd32=0.000000000000000 +PredictedTws32=0.000000000000000 +Mk33=6280 +Cog33=0.000000000000000 +Eta33=0.000000000000000 +Length33=0.000000000000000 +PredictedDrift33=0.000000000000000 +PredictedSet33=0.000000000000000 +PredictedSog33=0.000000000000000 +PredictedTime33=0.000000000000000 +PredictedTwa33=0.000000000000000 +PredictedTwd33=0.000000000000000 +PredictedTws33=0.000000000000000 +Mk34=6177 +Cog34=0.000000000000000 +Eta34=0.000000000000000 +Length34=0.000000000000000 +PredictedDrift34=0.000000000000000 +PredictedSet34=0.000000000000000 +PredictedSog34=0.000000000000000 +PredictedTime34=0.000000000000000 +PredictedTwa34=0.000000000000000 +PredictedTwd34=0.000000000000000 +PredictedTws34=0.000000000000000 +Mk35=6176 +Cog35=0.000000000000000 +Eta35=0.000000000000000 +Length35=0.000000000000000 +PredictedDrift35=0.000000000000000 +PredictedSet35=0.000000000000000 +PredictedSog35=0.000000000000000 +PredictedTime35=0.000000000000000 +PredictedTwa35=0.000000000000000 +PredictedTwd35=0.000000000000000 +PredictedTws35=0.000000000000000 +Mk36=6153 +Cog36=0.000000000000000 +Eta36=0.000000000000000 +Length36=0.000000000000000 +PredictedDrift36=0.000000000000000 +PredictedSet36=0.000000000000000 +PredictedSog36=0.000000000000000 +PredictedTime36=0.000000000000000 +PredictedTwa36=0.000000000000000 +PredictedTwd36=0.000000000000000 +PredictedTws36=0.000000000000000 +Mk37=6171 +Cog37=0.000000000000000 +Eta37=0.000000000000000 +Length37=0.000000000000000 +PredictedDrift37=0.000000000000000 +PredictedSet37=0.000000000000000 +PredictedSog37=0.000000000000000 +PredictedTime37=0.000000000000000 +PredictedTwa37=0.000000000000000 +PredictedTwd37=0.000000000000000 +PredictedTws37=0.000000000000000 +Mk38=6131 +Cog38=0.000000000000000 +Eta38=0.000000000000000 +Length38=0.000000000000000 +PredictedDrift38=0.000000000000000 +PredictedSet38=0.000000000000000 +PredictedSog38=0.000000000000000 +PredictedTime38=0.000000000000000 +PredictedTwa38=0.000000000000000 +PredictedTwd38=0.000000000000000 +PredictedTws38=0.000000000000000 +Mk39=6130 +Cog39=0.000000000000000 +Eta39=0.000000000000000 +Length39=0.000000000000000 +PredictedDrift39=0.000000000000000 +PredictedSet39=0.000000000000000 +PredictedSog39=0.000000000000000 +PredictedTime39=0.000000000000000 +PredictedTwa39=0.000000000000000 +PredictedTwd39=0.000000000000000 +PredictedTws39=0.000000000000000 +Mk40=6029 +Cog40=0.000000000000000 +Eta40=0.000000000000000 +Length40=0.000000000000000 +PredictedDrift40=0.000000000000000 +PredictedSet40=0.000000000000000 +PredictedSog40=0.000000000000000 +PredictedTime40=0.000000000000000 +PredictedTwa40=0.000000000000000 +PredictedTwd40=0.000000000000000 +PredictedTws40=0.000000000000000 +Mk41=6006 +Cog41=0.000000000000000 +Eta41=0.000000000000000 +Length41=0.000000000000000 +PredictedDrift41=0.000000000000000 +PredictedSet41=0.000000000000000 +PredictedSog41=0.000000000000000 +PredictedTime41=0.000000000000000 +PredictedTwa41=0.000000000000000 +PredictedTwd41=0.000000000000000 +PredictedTws41=0.000000000000000 +Mk42=6014MEADOW +Cog42=0.000000000000000 +Eta42=0.000000000000000 +Length42=0.000000000000000 +PredictedDrift42=0.000000000000000 +PredictedSet42=0.000000000000000 +PredictedSog42=0.000000000000000 +PredictedTime42=0.000000000000000 +PredictedTwa42=0.000000000000000 +PredictedTwd42=0.000000000000000 +PredictedTws42=0.000000000000000 +Mk43=PANTHRCAVE +Cog43=0.000000000000000 +Eta43=0.000000000000000 +Length43=0.000000000000000 +PredictedDrift43=0.000000000000000 +PredictedSet43=0.000000000000000 +PredictedSog43=0.000000000000000 +PredictedTime43=0.000000000000000 +PredictedTwa43=0.000000000000000 +PredictedTwd43=0.000000000000000 +PredictedTws43=0.000000000000000 +Mk44=GATE6 +Cog44=0.000000000000000 +Eta44=0.000000000000000 +Length44=0.000000000000000 +PredictedDrift44=0.000000000000000 +PredictedSet44=0.000000000000000 +PredictedSog44=0.000000000000000 +PredictedTime44=0.000000000000000 +PredictedTwa44=0.000000000000000 +PredictedTwd44=0.000000000000000 +PredictedTws44=0.000000000000000 +Mk45=BELLEVUE +Cog45=0.000000000000000 +Eta45=0.000000000000000 +Length45=0.000000000000000 +PredictedDrift45=0.000000000000000 +PredictedSet45=0.000000000000000 +PredictedSog45=0.000000000000000 +PredictedTime45=0.000000000000000 +PredictedTwa45=0.000000000000000 +PredictedTwd45=0.000000000000000 +PredictedTws45=0.000000000000000 diff --git a/reference/foo.an1 b/reference/foo.an1 new file mode 100755 index 0000000000000000000000000000000000000000..ae27a48004bbb61bd81e06eb5fef4137fedce326 GIT binary patch literal 135252 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 literal 0 HcmV?d00001 diff --git a/reference/fugawi.notime.txt b/reference/fugawi.notime.txt new file mode 100644 index 000000000..630eef703 --- /dev/null +++ b/reference/fugawi.notime.txt @@ -0,0 +1,19 @@ +# Latitude, Longitude and UTM coordinates are in WGS84 datum +# +# Every set of data contains the following: +# +# Waypoint name +# Waypoint comment +# Waypoint description +# Latitude in Degree and decimals (soutern hemisphere has neg. degrees) +# Longitude in degree and decimals (neg. numbers: west of Greenwich) +# Height in meters +GCEBB,Mountain Bike Heaven by susy1313,,35.9720333,-87.1347000,0.0 +GC1A37,The Troll by a182pilot & Family,,36.0906833,-86.6795500,0.0 +GC1C2B,Dive Bomber by JoGPS & family,,35.9962667,-86.6201167,0.0 +GC25A9,FOSTER by JoGPS & Family,,36.0384833,-86.6486167,0.0 +GC2723,Logan Lighthouse by JoGps & Family,,36.1121833,-86.7417667,0.0 +GC2B71,Ganier Cache by Susy1313,,36.0640833,-86.7905167,0.0 +GC309F,Shy's Hill by FireFighterEng33,,36.0877667,-86.8097333,0.0 +GC317A,GittyUp by JoGPS / Warner Parks,,36.0575000,-86.8920000,0.0 +GC317D,Inlighting by JoGPS / Warner Parks,,36.0828000,-86.8672833,0.0 diff --git a/reference/fugawi.ref b/reference/fugawi.ref new file mode 100644 index 000000000..e69de29bb diff --git a/reference/fugawi.ref.txt b/reference/fugawi.ref.txt new file mode 100644 index 000000000..7e07be768 --- /dev/null +++ b/reference/fugawi.ref.txt @@ -0,0 +1,19 @@ +# Latitude, Longitude and UTM coordinates are in WGS84 datum +# +# Every set of data contains the following: +# +# Waypoint name +# Waypoint comment +# Waypoint description +# Latitude in Degree and decimals (soutern hemisphere has neg. degrees) +# Longitude in degree and decimals (neg. numbers: west of Greenwich) +# Height in meters [optional when importing, always present when exporting: Date (GMT) as ISO YYYYMMDD, Time of the day relative to the date as HHMMSS +GCEBB,Mountain Bike Heaven by susy1313,,35.9720333,-87.1347000,0.0 ,19700101,000000 +GC1A37,The Troll by a182pilot & Family,,36.0906833,-86.6795500,0.0 ,19700101,000000 +GC1C2B,Dive Bomber by JoGPS & family,,35.9962667,-86.6201167,0.0 ,19700101,000000 +GC25A9,FOSTER by JoGPS & Family,,36.0384833,-86.6486167,0.0 ,19700101,000000 +GC2723,Logan Lighthouse by JoGps & Family,,36.1121833,-86.7417667,0.0 ,19700101,000000 +GC2B71,Ganier Cache by Susy1313,,36.0640833,-86.7905167,0.0 ,19700101,000000 +GC309F,Shy's Hill by FireFighterEng33,,36.0877667,-86.8097333,0.0 ,19700101,000000 +GC317A,GittyUp by JoGPS / Warner Parks,,36.0575000,-86.8920000,0.0 ,19700101,000000 +GC317D,Inlighting by JoGPS / Warner Parks,,36.0828000,-86.8672833,0.0 ,19700101,000000 diff --git a/reference/fugawi.time.ref.txt b/reference/fugawi.time.ref.txt new file mode 100644 index 000000000..4ad0e3b1c --- /dev/null +++ b/reference/fugawi.time.ref.txt @@ -0,0 +1,16 @@ +# Latitude, Longitude and UTM coordinates are in WGS84 datum +# +# Every set of data contains the following: +# +# Waypoint name +# Waypoint comment +# Waypoint description +# Latitude in Degree and decimals (soutern hemisphere has neg. degrees) +# Longitude in degree and decimals (neg. numbers: west of Greenwich) +# Height in meters [optional when importing, always present when exporting: Date (GMT) as ISO YYYYMMDD, Time of the day relative to the date as HHMMSS +GCEBB,Mountain Bike Heaven by susy1313,,35.9720333,-87.1347000,0.0 ,19700101,000000 +GC1A37,The Troll by a182pilot & Family,,36.0906833,-86.6795500,0.0 ,19700101,000000 +GC1C2B,Dive Bomber by JoGPS & family,,35.9962667,-86.6201167,0.0 ,19700101,110304 +GC25A9,FOSTER by JoGPS & Family,,36.0384833,-86.6486167,0.0 ,19700101,130405 +GC2723,Logan Lighthouse by JoGps & Family,,36.1121833,-86.7417667,0.0 ,20050102,000000 +GC2B71,Ganier Cache by Susy1313,,36.0640833,-86.7905167,0.0 ,20050102,000001 diff --git a/reference/fugawi.time.txt b/reference/fugawi.time.txt new file mode 100644 index 000000000..8981db7fe --- /dev/null +++ b/reference/fugawi.time.txt @@ -0,0 +1,16 @@ +# Latitude, Longitude and UTM coordinates are in WGS84 datum +# +# Every set of data contains the following: +# +# Waypoint name +# Waypoint comment +# Waypoint description +# Latitude in Degree and decimals (soutern hemisphere has neg. degrees) +# Longitude in degree and decimals (neg. numbers: west of Greenwich) +# Height in meters [optional when importing, always present when exporting: Date (GMT) as ISO YYYYMMDD, Time of the day relative to the date as HHMMSS +GCEBB,Mountain Bike Heaven by susy1313,,35.9720333,-87.1347000,0.0 +GC1A37,The Troll by a182pilot & Family,,36.0906833,-86.6795500,0.0 ,19700101 +GC1C2B,Dive Bomber by JoGPS & family,,35.9962667,-86.6201167,0.0 ,,110304 +GC25A9,FOSTER by JoGPS & Family,,36.0384833,-86.6486167,0.0 ,19700101,130405 +GC2723,Logan Lighthouse by JoGps & Family,,36.1121833,-86.7417667,0.0 ,20050102,000000 +GC2B71,Ganier Cache by Susy1313,,36.0640833,-86.7905167,0.0 ,20050102,000001 diff --git a/reference/garmin_gpi.gpi b/reference/garmin_gpi.gpi new file mode 100644 index 0000000000000000000000000000000000000000..290d8923243e421b83d12bfeb357cb4631309bf7 GIT binary patch literal 7776 zcmeHLd2m!k8vlYEAsnJngdokJh%981_uk~qfg8yrd6|SvX2MJk0%9@=W5_vSGC6?E zL=X$aDoPN6TGR!K6|1;KbSWsVz$y!Zuz_6_EkKF_1xr?0MA%}xdwB762Vdd-yF1tv z_V?BA{l2rmZUBJ6csV?I9wkE%+`jDwfZk9yE2*-fDh5mX{krY!T9R^rR08+78!|@t&EeT0;D8NAKgE)}IloW4aUS3WC3q$0@ zw~DJbc$@0#szL;465b&|fj!CS-Pd^_tIO_E^6f0p6IdN51O`d~m#^O6;A@=Wuk(it zo`7$VYD1By&tmdW9gFXd&3{I`z;j5xqT@0;n#-Ol;i?Tk8*!E`)^xgOC&);S4#=wu}@}Odnb~zoeVl;!gJ#*fUrlZSANQ!rUl zvT{6JHEXj)zN?`%Y3EuA{dE{?lF6di^RbiwsEzXYdI?p=Qh=_^#VYsTC{>gCu98sr zY1TIw=>89nEbL%XOSd*lXvm0ejJyRN#h%AToQyj0cqy(2!5a$teRa$kYr!I-viz_S zjqXveorcVUz&S}<3q)$8sjOOea)%M!y2e;Xl+vArIssEPh`;Ta2eHmvW<;x=ppR(B`oCtEL;m_O|UQxICpO%ay9S(x<0T_ACP1tVIOtYh}=O6ptc#aV6iye4lnCS zGBA*cD6anC3{)~zq&hTrjuC|pacr#IvBa8VrH7JQL%&~`gq|v-A?;!#O5*)@2$jj! zX-UYpj?E3x#2wfS6D-w+HfvrITECbF(2I=79*u`jC85i`SYL>`*@>luf$EDZreriH zj*W~c%fHJ)K(Wn3q!1WN;nb8wOjYj{u$>^*3Jb+%Eh!$EW zYSTE4qj6~o1?XxTqE-Aan#O_|0@_u{Qjsh=cSbXolCY4If=ravRRZdqL;=*fiKry$ zrN&(d)g42fc*vN+bI_TZ@CTT&xDTGIm#yajta{lkS()s9y-h&lxA6daZ9}p$t@FSi zMC9foD(THhW-Qg#*Q7)d)$HIH*z{6DvN5f*%?azGwPNhh1FjO@Nkb1>WFA~w!n-oYL3^VPX+-$egneS$) zX|MR1z97Ea2Wo2rEr$F+^ciM6rcSz9dyGJz8}TckntBfWa>QRHAH=Ht@KRiTz~Kw| z4bi)#iqcXjqHAw67i5aU9TDA8=rpCG6ym#A&XaV2X1H)op*srg3o1&u16SicP`DK8 zjzY6YMIq0zqf)7>wOk~w%XdSO=yax{wDiD@9zW`G-sPXUx}(sNuwsXkIDYI*L@iM+ zeQ6AO0r9TPMqFFiG(<8<9Tj6(X(Fn=PU}*O!3C%r28~Y!{wTSZR1Pqr`JEI)O}~7* zt03ExVK3sYIND(`-&Y@+;SU-ze9iO~BNs!FIwL3XN70j5tut@7qU2|}o!omi`8Y{d z#q}t7XZZaMF9d3*8}e~ln!+IyJgq_T21*glDYN29|_> zAGEZVm5p)FBsh@_Q&rVtPlOYn9y=~9`P^>v1SjPg89#2El91*ITkH=%^?X)VUb#2A z-#Bw-b-ZnuQl39P5}7mSxv4qP{gRlN-qU5*v!h48(603C`OsZ|Mt*I-EiUdse>gO= z4Lf1-0}qVr@_$`jz&N~OcBEI2@3hn+qf(5W};X-)jl~-WVqDAoP ztFOZ1#f#y!*It7qOP0XWrAuMivSskb8*jk!<;!8kiWRVOPMkOaCr_S)&dyFab?OwH zK7ATK`|LCL{PWM@i!Z)_GiT1gmtTGfXV0F6bLY;%`Sa)D>#x6t3l}cH#ful=(xppq z`SNA>=9_Qe+i$;xD_5?-)vH(GyYIe(@4x>Ze)!=B`0>Xd;rjLKaO1`e`01yg;O5Pn j@bk|wDl;P&m?aOV!`B6secE&t#BpYZ@r1N!?9Aa1MR literal 0 HcmV?d00001 diff --git a/reference/garmin_gpi.gpx b/reference/garmin_gpi.gpx new file mode 100644 index 000000000..2424b5d44 --- /dev/null +++ b/reference/garmin_gpi.gpx @@ -0,0 +1,526 @@ + + + + + + 5058ROAD + ROAD CROSSING + ROAD CROSSING + Waypoint + + + 5066 + 5066 + 5066 + Waypoint + + + 5067 + 5067 + 5067 + Waypoint + + + 5096 + 5096 + 5096 + Waypoint + + + 5142 + 5142 + 5142 + Waypoint + + + 5144SUMMIT + Summit + Summit + Waypoint + + + 5148NANEPA + Nanepashemet Road Crossing + Nanepashemet Road Crossing + Waypoint + + + 5150TANK + WATER TANK + WATER TANK + Waypoint + + + 5156 + 5156 + 5156 + Waypoint + + + 5179DEAD + Dead End + Dead End + Waypoint + + + 5224 + 5224 + 5224 + Waypoint + + + 5229 + 5229 + 5229 + Waypoint + + + 5236BRIDGE + Bridge + Bridge + Waypoint + + + 5237 + 5237 + 5237 + Waypoint + + + 5239ROAD + Road + Road + Waypoint + + + 5252PURPLE + Purple Rock Hill + Purple Rock Hill + Waypoint + + + 5254 + 5254 + 5254 + Waypoint + + + 5258 + 5258 + 5258 + Waypoint + + + 5264 + 5264 + 5264 + Waypoint + + + 526708 + 526708 + 526708 + Waypoint + + + 526750 + 526750 + 526750 + Waypoint + + + 5267OBSTAC + Obstacle + Obstacle + Waypoint + + + 527614 + 527614 + 527614 + Waypoint + + + 527631 + 527631 + 527631 + Waypoint + + + 5278 + 5278 + 5278 + Waypoint + + + 5278ROAD + Road + Road + Waypoint + + + 5287WATER + Reservoir + Reservoir + Waypoint + + + 5289 + 5289 + 5289 + Waypoint + + + 5299DEAD + Dead End + Dead End + Waypoint + + + 5374FIRE + 5374FIRE + 5374FIRE + Waypoint + + + 5376 + 5376 + 5376 + Waypoint + + + 5376BRIDGE + Bridge + Bridge + Waypoint + + + 5376DEAD + Dead End + Dead End + Waypoint + + + 5376STREAM + Stream Crossing + Stream Crossing + Waypoint + + + 6006 + 600698 + 600698 + Waypoint + + + 6006BLUE + 6006BLUE + 6006BLUE + Waypoint + + + 6014MEADOW + 6014MEADOW + 6014MEADOW + Waypoint + + + 6016 + Bike Loop Connector + Bike Loop Connector + Waypoint + + + 6029 + 6029 + 6029 + Waypoint + + + 6042CROSS + Crossing + Crossing + Waypoint + + + 6053 + 6053 + 6053 + Waypoint + + + 6066 + 6066 + 6066 + Waypoint + + + 6067 + 6067 + 6067 + Waypoint + + + 6071 + 6071 + 6071 + Waypoint + + + 6073 + 6073 + 6073 + Waypoint + + + 6077LOGS + Log Crossing + Log Crossing + Waypoint + + + 6084 + 6084 + 6084 + Waypoint + + + 6121DEAD + Dead End + Dead End + Waypoint + + + 6130 + 6130 + 6130 + Waypoint + + + 6131 + 6131 + 6131 + Waypoint + + + 6153 + 6153 + 6153 + Waypoint + + + 6155DEAD + Dead End + Dead End + Waypoint + + + 6171 + 6171 + 6171 + Waypoint + + + 6176 + 6176 + 6176 + Waypoint + + + 6177 + 6177 + 6177 + Waypoint + + + 6181CROSS + Crossing + Crossing + Waypoint + + + 6272 + 6272 + 6272 + Waypoint + + + 6272.1 + 6272 + 6272 + Waypoint + + + 6278 + 6278 + 6278 + Waypoint + + + 6280 + 6280 + 6280 + Waypoint + + + 6283 + 6283 + 6283 + Waypoint + + + 6289 + 6289 + 6289 + Waypoint + + + 6297 + 6297 + 6297 + Waypoint + + + 6328 + 6328 + 6328 + Waypoint + + + 6353DEAD + Dead End + Dead End + Waypoint + + + 6354 + 6354 + 6354 + Waypoint + + + 635722 + 635722 + 635722 + Waypoint + + + 635783 + 635783 + 635783 + Waypoint + + + 6373 + 6373 + 6373 + Waypoint + + + 6634 + 6634 + 6634 + Waypoint + + + 6979 + 6979 + 6979 + Waypoint + + + 6997 + 6997 + 6997 + Waypoint + + + BEAR HILL + BEAR HILL TOWER + BEAR HILL TOWER + Waypoint + + + BELLEVUE + BELLEVUE + BELLEVUE + Waypoint + + + DARKHOLLPO + Dark Hollow Pond + Dark Hollow Pond + Waypoint + + + GATE14 + Gate 14 + Gate 14 + Waypoint + + + GATE16 + Gate 16 + Gate 16 + Waypoint + + + GATE17 + Gate 17 + Gate 17 + Waypoint + + + GATE19 + Gate 19 + Gate 19 + Waypoint + + + GATE21 + Gate 21 + Gate 21 + Waypoint + + + GATE24 + Gate 24 + Gate 24 + Waypoint + + + GATE5 + Gate 5 + Gate 5 + Waypoint + + + GATE6 + Gate 6 + Gate 6 + Waypoint + + + PANTHRCAVE + Panther Cave + Panther Cave + Waypoint + + + SHEEPFOLD + Sheepfold Parking Lot + Sheepfold Parking Lot + Waypoint + + + SOAPBOX + Soap Box Derby Track + Soap Box Derby Track + Waypoint + + diff --git a/reference/garmin_gpi2.gpx b/reference/garmin_gpi2.gpx new file mode 100644 index 000000000..1c5718aa0 --- /dev/null +++ b/reference/garmin_gpi2.gpx @@ -0,0 +1,526 @@ + + + + + + 5058ROAD + ROAD CROSSING + ROAD CROSSING + Waypoint + + + 5066 + 5066 + 5066 + Waypoint + + + 5067 + 5067 + 5067 + Waypoint + + + 5096 + 5096 + 5096 + Waypoint + + + 5142 + 5142 + 5142 + Waypoint + + + 5144SUMMIT + Summit + Summit + Waypoint + + + 5148NANEPA + Nanepashemet Road Crossing + Nanepashemet Road Crossing + Waypoint + + + 5150TANK + WATER TANK + WATER TANK + Waypoint + + + 5156 + 5156 + 5156 + Waypoint + + + 5179DEAD + Dead End + Dead End + Waypoint + + + 5224 + 5224 + 5224 + Waypoint + + + 5229 + 5229 + 5229 + Waypoint + + + 5236BRIDGE + Bridge + Bridge + Waypoint + + + 5237 + 5237 + 5237 + Waypoint + + + 5239ROAD + Road + Road + Waypoint + + + 5252PURPLE + Purple Rock Hill + Purple Rock Hill + Waypoint + + + 5254 + 5254 + 5254 + Waypoint + + + 5258 + 5258 + 5258 + Waypoint + + + 5264 + 5264 + 5264 + Waypoint + + + 526708 + 526708 + 526708 + Waypoint + + + 526750 + 526750 + 526750 + Waypoint + + + 5267OBSTAC + Obstacle + Obstacle + Waypoint + + + 527614 + 527614 + 527614 + Waypoint + + + 527631 + 527631 + 527631 + Waypoint + + + 5278 + 5278 + 5278 + Waypoint + + + 5278ROAD + Road + Road + Waypoint + + + 5287WATER + Reservoir + Reservoir + Waypoint + + + 5289 + 5289 + 5289 + Waypoint + + + 5299DEAD + Dead End + Dead End + Waypoint + + + 5374FIRE + 5374FIRE + 5374FIRE + Waypoint + + + 5376 + 5376 + 5376 + Waypoint + + + 5376BRIDGE + Bridge + Bridge + Waypoint + + + 5376DEAD + Dead End + Dead End + Waypoint + + + 5376STREAM + Stream Crossing + Stream Crossing + Waypoint + + + 6006 + 600698 + 600698 + Waypoint + + + 6006BLUE + 6006BLUE + 6006BLUE + Waypoint + + + 6014MEADOW + 6014MEADOW + 6014MEADOW + Waypoint + + + 6016 + Bike Loop Connector + Bike Loop Connector + Waypoint + + + 6029 + 6029 + 6029 + Waypoint + + + 6042CROSS + Crossing + Crossing + Waypoint + + + 6053 + 6053 + 6053 + Waypoint + + + 6066 + 6066 + 6066 + Waypoint + + + 6067 + 6067 + 6067 + Waypoint + + + 6071 + 6071 + 6071 + Waypoint + + + 6073 + 6073 + 6073 + Waypoint + + + 6077LOGS + Log Crossing + Log Crossing + Waypoint + + + 6084 + 6084 + 6084 + Waypoint + + + 6121DEAD + Dead End + Dead End + Waypoint + + + 6130 + 6130 + 6130 + Waypoint + + + 6131 + 6131 + 6131 + Waypoint + + + 6153 + 6153 + 6153 + Waypoint + + + 6155DEAD + Dead End + Dead End + Waypoint + + + 6171 + 6171 + 6171 + Waypoint + + + 6176 + 6176 + 6176 + Waypoint + + + 6177 + 6177 + 6177 + Waypoint + + + 6181CROSS + Crossing + Crossing + Waypoint + + + 6272 + 6272 + 6272 + Waypoint + + + 6272.1 + 6272 + 6272 + Waypoint + + + 6278 + 6278 + 6278 + Waypoint + + + 6280 + 6280 + 6280 + Waypoint + + + 6283 + 6283 + 6283 + Waypoint + + + 6289 + 6289 + 6289 + Waypoint + + + 6297 + 6297 + 6297 + Waypoint + + + 6328 + 6328 + 6328 + Waypoint + + + 6353DEAD + Dead End + Dead End + Waypoint + + + 6354 + 6354 + 6354 + Waypoint + + + 635722 + 635722 + 635722 + Waypoint + + + 635783 + 635783 + 635783 + Waypoint + + + 6373 + 6373 + 6373 + Waypoint + + + 6634 + 6634 + 6634 + Waypoint + + + 6979 + 6979 + 6979 + Waypoint + + + 6997 + 6997 + 6997 + Waypoint + + + BEAR HILL + BEAR HILL TOWER + BEAR HILL TOWER + Waypoint + + + BELLEVUE + BELLEVUE + BELLEVUE + Waypoint + + + DARKHOLLPO + Dark Hollow Pond + Dark Hollow Pond + Waypoint + + + GATE14 + Gate 14 + Gate 14 + Waypoint + + + GATE16 + Gate 16 + Gate 16 + Waypoint + + + GATE17 + Gate 17 + Gate 17 + Waypoint + + + GATE19 + Gate 19 + Gate 19 + Waypoint + + + GATE21 + Gate 21 + Gate 21 + Waypoint + + + GATE24 + Gate 24 + Gate 24 + Waypoint + + + GATE5 + Gate 5 + Gate 5 + Waypoint + + + GATE6 + Gate 6 + Gate 6 + Waypoint + + + PANTHRCAVE + Panther Cave + Panther Cave + Waypoint + + + SHEEPFOLD + Sheepfold Parking Lot + Sheepfold Parking Lot + Waypoint + + + SOAPBOX + Soap Box Derby Track + Soap Box Derby Track + Waypoint + + diff --git a/reference/garmin_symbols.gpx b/reference/garmin_symbols.gpx new file mode 100644 index 000000000..e8c9ee089 --- /dev/null +++ b/reference/garmin_symbols.gpx @@ -0,0 +1,4620 @@ + + + + + + Garmin International + + + + + + + 107.0000000 + + Airport + MPS:0107, PCX:16384 + MPS:0107, PCX:16384 + Airport + + + 16384.0000000 + SymbolAndName + + Aviation + + + + + + + 73.0000000 + + Amusement Park + MPS:0073, PCX:08204 + MPS:0073, PCX:08204 + Amusement Park + + + 8204.0000000 + SymbolAndName + + Business + + + + + + + 0.0000000 + + Anchor + MPS:0000, PCX:00000 + MPS:0000, PCX:00000 + Anchor + + + SymbolAndName + + Marine + + + + + + + 155.0000000 + + Anchor Prohibited + MPS:0155, PCX:00184 + MPS:0155, PCX:00184 + Anchor Prohibited + + + 184.0000000 + SymbolAndName + + Marine + + + + + + + 242.0000000 + + Animal Tracks + MPS:0242, PCX:-0001 + MPS:0242, PCX:-0001 + Animal Tracks + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 232.0000000 + + ATV + MPS:0232, PCX:-0001 + MPS:0232, PCX:-0001 + ATV + + + -1.0000000 + SymbolAndName + + Outdoor + + + + + + + 163.0000000 + + Bait and Tackle + MPS:0163, PCX:00192 + MPS:0163, PCX:00192 + Bait and Tackle + + + 192.0000000 + SymbolAndName + + Marine + + + + + + + 55.0000000 + + Ball Park + MPS:0055, PCX:00169 + MPS:0055, PCX:00169 + Ball Park + + + 169.0000000 + SymbolAndName + + Outdoor + + + + + + + 6.0000000 + + Bank + MPS:0006, PCX:00006 + MPS:0006, PCX:00006 + Bank + + + 6.0000000 + SymbolAndName + + Business + + + + + + + 13.0000000 + + Bar + MPS:0013, PCX:00013 + MPS:0013, PCX:00013 + Bar + + + 13.0000000 + SymbolAndName + + Business + + + + + + + 104.0000000 + + Beach + MPS:0104, PCX:08244 + MPS:0104, PCX:08244 + Beach + + + 8244.0000000 + SymbolAndName + + Marine + + + + + + + 156.0000000 + + Beacon + MPS:0156, PCX:00185 + MPS:0156, PCX:00185 + Beacon + + + 185.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 1.0000000 + + Bell + MPS:0001, PCX:00001 + MPS:0001, PCX:00001 + Bell + + + 1.0000000 + SymbolAndName + + Civil + + + + + + + 233.0000000 + + Big Game + MPS:0233, PCX:-0001 + MPS:0233, PCX:-0001 + Big Game + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 149.0000000 + + Bike Trail + MPS:0149, PCX:08293 + MPS:0149, PCX:08293 + Bike Trail + + + 8293.0000000 + SymbolAndName + + Outdoor + + + + + + + 234.0000000 + + Blind + MPS:0234, PCX:-0001 + MPS:0234, PCX:-0001 + Blind + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 147.0000000 + + Block, Blue + MPS:0147, PCX:08290 + MPS:0147, PCX:08290 + Block, Blue + + + 8290.0000000 + SymbolAndName + + Marker + + + + + + + 148.0000000 + + Block, Green + MPS:0148, PCX:08291 + MPS:0148, PCX:08291 + Block, Green + + + 8291.0000000 + SymbolAndName + + Marker + + + + + + + 146.0000000 + + Block, Red + MPS:0146, PCX:08292 + MPS:0146, PCX:08292 + Block, Red + + + 8292.0000000 + SymbolAndName + + Marker + + + + + + + 235.0000000 + + Blood Trail + MPS:0235, PCX:-0001 + MPS:0235, PCX:-0001 + Blood Trail + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 37.0000000 + + Boat Ramp + MPS:0037, PCX:00150 + MPS:0037, PCX:00150 + Boat Ramp + + + 150.0000000 + SymbolAndName + + Marine + + + + + + + 74.0000000 + + Bowling + MPS:0074, PCX:08205 + MPS:0074, PCX:08205 + Bowling + + + 8205.0000000 + SymbolAndName + + Business + + + + + + + 93.0000000 + + Bridge + MPS:0093, PCX:08233 + MPS:0093, PCX:08233 + Bridge + + + 8233.0000000 + SymbolAndName + + Marine + + + + + + + 94.0000000 + + Building + MPS:0094, PCX:08234 + MPS:0094, PCX:08234 + Building + + + 8234.0000000 + SymbolAndName + + Civil + + + + + + + 17.0000000 + + Buoy, White + MPS:0017, PCX:00017 + MPS:0017, PCX:00017 + Buoy, White + + + 17.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 38.0000000 + + Campground + MPS:0038, PCX:00151 + MPS:0038, PCX:00151 + Campground + + + 151.0000000 + SymbolAndName + + Outdoor + + + + + + + 56.0000000 + + Car + MPS:0056, PCX:00170 + MPS:0056, PCX:00170 + Car + + + 170.0000000 + SymbolAndName + + Civil + + + + + + + 75.0000000 + + Car Rental + MPS:0075, PCX:08206 + MPS:0075, PCX:08206 + Car Rental + + + 8206.0000000 + SymbolAndName + + Transportation + + + + + + + 76.0000000 + + Car Repair + MPS:0076, PCX:08207 + MPS:0076, PCX:08207 + Car Repair + + + 8207.0000000 + SymbolAndName + + Transportation + + + + + + + 95.0000000 + + Cemetery + MPS:0095, PCX:08235 + MPS:0095, PCX:08235 + Cemetery + + + 8235.0000000 + SymbolAndName + + Outdoor + + + + + + + 96.0000000 + + Church + MPS:0096, PCX:08236 + MPS:0096, PCX:08236 + Church + + + 8236.0000000 + SymbolAndName + + Civil + + + + + + + 65.0000000 + + Circle with X + MPS:0065, PCX:00179 + MPS:0065, PCX:00179 + Circle with X + + + 179.0000000 + SymbolAndName + + Marker + + + + + + + 167.0000000 + + Circle, Blue + MPS:0167, PCX:08296 + MPS:0167, PCX:08296 + Circle, Blue + + + 8296.0000000 + SymbolAndName + + Marker + + + + + + + 166.0000000 + + Circle, Green + MPS:0166, PCX:08295 + MPS:0166, PCX:08295 + Circle, Green + + + 8295.0000000 + SymbolAndName + + Marker + + + + + + + 165.0000000 + + Circle, Red + MPS:0165, PCX:08294 + MPS:0165, PCX:08294 + Circle, Red + + + 8294.0000000 + SymbolAndName + + Marker + + + + + + + 72.0000000 + + City (Capitol) + MPS:0072, PCX:08203 + MPS:0072, PCX:08203 + City (Capitol) + + + 8203.0000000 + SymbolAndName + + Civil + + + + + + + 71.0000000 + + City (Large) + MPS:0071, PCX:08200 + MPS:0071, PCX:08200 + City (Large) + + + 8200.0000000 + SymbolAndName + + Civil + + + + + + + 70.0000000 + + City (Medium) + MPS:0070, PCX:08199 + MPS:0070, PCX:08199 + City (Medium) + + + 8199.0000000 + SymbolAndName + + Civil + + + + + + + 69.0000000 + + City (Small) + MPS:0069, PCX:08198 + MPS:0069, PCX:08198 + City (Small) + + + 8198.0000000 + SymbolAndName + + Civil + + + + + + + 230.0000000 + + City Hall + MPS:0230, PCX:-0001 + MPS:0230, PCX:-0001 + City Hall + + + -1.0000000 + SymbolAndName + + Civil + + + + + + + 97.0000000 + + Civil + MPS:0097, PCX:08237 + MPS:0097, PCX:08237 + Civil + + + 8237.0000000 + SymbolAndName + + Civil + + + + + + + 157.0000000 + + Coast Guard + MPS:0157, PCX:00186 + MPS:0157, PCX:00186 + Coast Guard + + + 186.0000000 + SymbolAndName + + Marine + + + + + + + 119.0000000 + + Contact, Afro + MPS:0119, PCX:08262 + MPS:0119, PCX:08262 + Contact, Afro + + + 8262.0000000 + SymbolAndName + + Contact + + + + + + + 120.0000000 + + Contact, Alien + MPS:0120, PCX:08272 + MPS:0120, PCX:08272 + Contact, Alien + + + 8272.0000000 + SymbolAndName + + Contact + + + + + + + 121.0000000 + + Contact, Ball Cap + MPS:0121, PCX:08258 + MPS:0121, PCX:08258 + Contact, Ball Cap + + + 8258.0000000 + SymbolAndName + + Contact + + + + + + + 122.0000000 + + Contact, Big Ears + MPS:0122, PCX:08259 + MPS:0122, PCX:08259 + Contact, Big Ears + + + 8259.0000000 + SymbolAndName + + Contact + + + + + + + 123.0000000 + + Contact, Biker + MPS:0123, PCX:08271 + MPS:0123, PCX:08271 + Contact, Biker + + + 8271.0000000 + SymbolAndName + + Contact + + + + + + + 221.0000000 + + Contact, Blonde + MPS:0221, PCX:-0001 + MPS:0221, PCX:-0001 + Contact, Blonde + + + -1.0000000 + SymbolAndName + + Contact + + + + + + + 124.0000000 + + Contact, Bug + MPS:0124, PCX:08273 + MPS:0124, PCX:08273 + Contact, Bug + + + 8273.0000000 + SymbolAndName + + Contact + + + + + + + 125.0000000 + + Contact, Cat + MPS:0125, PCX:08274 + MPS:0125, PCX:08274 + Contact, Cat + + + 8274.0000000 + SymbolAndName + + Contact + + + + + + + 222.0000000 + + Contact, Clown + MPS:0222, PCX:-0001 + MPS:0222, PCX:-0001 + Contact, Clown + + + -1.0000000 + SymbolAndName + + Contact + + + + + + + 126.0000000 + + Contact, Dog + MPS:0126, PCX:08275 + MPS:0126, PCX:08275 + Contact, Dog + + + 8275.0000000 + SymbolAndName + + Contact + + + + + + + 127.0000000 + + Contact, Dreadlocks + MPS:0127, PCX:08263 + MPS:0127, PCX:08263 + Contact, Dreadlocks + + + 8263.0000000 + SymbolAndName + + Contact + + + + + + + 128.0000000 + + Contact, Female1 + MPS:0128, PCX:08264 + MPS:0128, PCX:08264 + Contact, Female1 + + + 8264.0000000 + SymbolAndName + + Contact + + + + + + + 129.0000000 + + Contact, Female2 + MPS:0129, PCX:08265 + MPS:0129, PCX:08265 + Contact, Female2 + + + 8265.0000000 + SymbolAndName + + Contact + + + + + + + 130.0000000 + + Contact, Female3 + MPS:0130, PCX:08266 + MPS:0130, PCX:08266 + Contact, Female3 + + + 8266.0000000 + SymbolAndName + + Contact + + + + + + + 223.0000000 + + Contact, Glasses + MPS:0223, PCX:-0001 + MPS:0223, PCX:-0001 + Contact, Glasses + + + -1.0000000 + SymbolAndName + + Contact + + + + + + + 131.0000000 + + Contact, Goatee + MPS:0131, PCX:08261 + MPS:0131, PCX:08261 + Contact, Goatee + + + 8261.0000000 + SymbolAndName + + Contact + + + + + + + 132.0000000 + + Contact, Kung-Fu + MPS:0132, PCX:08268 + MPS:0132, PCX:08268 + Contact, Kung-Fu + + + 8268.0000000 + SymbolAndName + + Contact + + + + + + + 224.0000000 + + Contact, Panda + MPS:0224, PCX:-0001 + MPS:0224, PCX:-0001 + Contact, Panda + + + -1.0000000 + SymbolAndName + + Contact + + + + + + + 133.0000000 + + Contact, Pig + MPS:0133, PCX:08276 + MPS:0133, PCX:08276 + Contact, Pig + + + 8276.0000000 + SymbolAndName + + Contact + + + + + + + 134.0000000 + + Contact, Pirate + MPS:0134, PCX:08270 + MPS:0134, PCX:08270 + Contact, Pirate + + + 8270.0000000 + SymbolAndName + + Contact + + + + + + + 135.0000000 + + Contact, Ranger + MPS:0135, PCX:08267 + MPS:0135, PCX:08267 + Contact, Ranger + + + 8267.0000000 + SymbolAndName + + Contact + + + + + + + 136.0000000 + + Contact, Smiley + MPS:0136, PCX:08257 + MPS:0136, PCX:08257 + Contact, Smiley + + + 8257.0000000 + SymbolAndName + + Contact + + + + + + + 137.0000000 + + Contact, Spike + MPS:0137, PCX:08260 + MPS:0137, PCX:08260 + Contact, Spike + + + 8260.0000000 + SymbolAndName + + Contact + + + + + + + 138.0000000 + + Contact, Sumo + MPS:0138, PCX:08269 + MPS:0138, PCX:08269 + Contact, Sumo + + + 8269.0000000 + SymbolAndName + + Contact + + + + + + + 52.0000000 + + Controlled Area + MPS:0052, PCX:00165 + MPS:0052, PCX:00165 + Controlled Area + + + 165.0000000 + SymbolAndName + + Marine + + + + + + + 89.0000000 + + Convenience Store + MPS:0089, PCX:08220 + MPS:0089, PCX:08220 + Convenience Store + + + 8220.0000000 + SymbolAndName + + Transportation + + + + + + + 236.0000000 + + Cover + MPS:0236, PCX:-0001 + MPS:0236, PCX:-0001 + Cover + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 237.0000000 + + Covey + MPS:0237, PCX:-0001 + MPS:0237, PCX:-0001 + Covey + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 98.0000000 + + Crossing + MPS:0098, PCX:08238 + MPS:0098, PCX:08238 + Crossing + + + 8238.0000000 + SymbolAndName + + Transportation + + + + + + + 500.0000000 + + Custom 0 + MPS:0500, PCX:07680 + MPS:0500, PCX:07680 + Custom 0 + + + 7680.0000000 + SymbolAndName + + Custom + + + + + + + 501.0000000 + + Custom 1 + MPS:0501, PCX:07681 + MPS:0501, PCX:07681 + Custom 1 + + + 7681.0000000 + SymbolAndName + + Custom + + + + + + + 502.0000000 + + Custom 2 + MPS:0502, PCX:07682 + MPS:0502, PCX:07682 + Custom 2 + + + 7682.0000000 + SymbolAndName + + Custom + + + + + + + 503.0000000 + + Custom 3 + MPS:0503, PCX:07683 + MPS:0503, PCX:07683 + Custom 3 + + + 7683.0000000 + SymbolAndName + + Custom + + + + + + + 504.0000000 + + Custom 4 + MPS:0504, PCX:07684 + MPS:0504, PCX:07684 + Custom 4 + + + 7684.0000000 + SymbolAndName + + Custom + + + + + + + 505.0000000 + + Custom 5 + MPS:0505, PCX:07685 + MPS:0505, PCX:07685 + Custom 5 + + + 7685.0000000 + SymbolAndName + + Custom + + + + + + + 506.0000000 + + Custom 6 + MPS:0506, PCX:07686 + MPS:0506, PCX:07686 + Custom 6 + + + 7686.0000000 + SymbolAndName + + Custom + + + + + + + 507.0000000 + + Custom 7 + MPS:0507, PCX:07687 + MPS:0507, PCX:07687 + Custom 7 + + + 7687.0000000 + SymbolAndName + + Custom + + + + + + + 51.0000000 + + Dam + MPS:0051, PCX:00164 + MPS:0051, PCX:00164 + Dam + + + 164.0000000 + SymbolAndName + + Marine + + + + + + + 53.0000000 + + Danger Area + MPS:0053, PCX:00166 + MPS:0053, PCX:00166 + Danger Area + + + 166.0000000 + SymbolAndName + + Marine + + + + + + + 87.0000000 + + Department Store + MPS:0087, PCX:08218 + MPS:0087, PCX:08218 + Department Store + + + 8218.0000000 + SymbolAndName + + Business + + + + + + + 168.0000000 + + Diamond, Blue + MPS:0168, PCX:08299 + MPS:0168, PCX:08299 + Diamond, Blue + + + 8299.0000000 + SymbolAndName + + Marker + + + + + + + 2.0000000 + + Diamond, Green + MPS:0002, PCX:00002 + MPS:0002, PCX:00002 + Diamond, Green + + + 2.0000000 + SymbolAndName + + Marker + + + + + + + 3.0000000 + + Diamond, Red + MPS:0003, PCX:00003 + MPS:0003, PCX:00003 + Diamond, Red + + + 3.0000000 + SymbolAndName + + Marker + + + + + + + 4.0000000 + + Diver Down Flag 1 + MPS:0004, PCX:00004 + MPS:0004, PCX:00004 + Diver Down Flag 1 + + + 4.0000000 + SymbolAndName + + Marine + + + + + + + 5.0000000 + + Diver Down Flag 2 + MPS:0005, PCX:00005 + MPS:0005, PCX:00005 + Diver Down Flag 2 + + + 5.0000000 + SymbolAndName + + Marine + + + + + + + 161.0000000 + + Dock + MPS:0161, PCX:00190 + MPS:0161, PCX:00190 + Dock + + + 190.0000000 + SymbolAndName + + Marine + + + + + + + 35.0000000 + + Dot, White + MPS:0035, PCX:00036 + MPS:0035, PCX:00036 + Dot, White + + + 36.0000000 + SymbolAndName + + Marker + + + + + + + 160.0000000 + + Dropoff + MPS:0160, PCX:00189 + MPS:0160, PCX:00189 + Dropoff + + + 189.0000000 + SymbolAndName + + Marine + + + + + + + 63.0000000 + + Exit + MPS:0063, PCX:00177 + MPS:0063, PCX:00177 + Exit + + + 177.0000000 + SymbolAndName + + Transportation + + + + + + + 77.0000000 + + Fast Food + MPS:0077, PCX:08208 + MPS:0077, PCX:08208 + Fast Food + + + 8208.0000000 + SymbolAndName + + Business + + + + + + + 7.0000000 + + Fishing Area + MPS:0007, PCX:00007 + MPS:0007, PCX:00007 + Fishing Area + + + 7.0000000 + SymbolAndName + + Marine + + + + + + + 150.0000000 + + Fishing Hot Spot Facility + MPS:0150, PCX:00181 + MPS:0150, PCX:00181 + Fishing Hot Spot Facility + + + 181.0000000 + SymbolAndName + + Marine + + + + + + + 78.0000000 + + Fitness Center + MPS:0078, PCX:08209 + MPS:0078, PCX:08209 + Fitness Center + + + 8209.0000000 + SymbolAndName + + Business + + + + + + + 64.0000000 + + Flag + MPS:0064, PCX:00178 + MPS:0064, PCX:00178 + Flag + + + 178.0000000 + SymbolAndName + + Civil + + + + + + + 141.0000000 + + Flag, Blue + MPS:0141, PCX:08284 + MPS:0141, PCX:08284 + Flag, Blue + + + 8284.0000000 + SymbolAndName + + Marker + + + + + + + 142.0000000 + + Flag, Green + MPS:0142, PCX:08285 + MPS:0142, PCX:08285 + Flag, Green + + + 8285.0000000 + SymbolAndName + + Marker + + + + + + + 140.0000000 + + Flag, Red + MPS:0140, PCX:08286 + MPS:0140, PCX:08286 + Flag, Red + + + 8286.0000000 + SymbolAndName + + Marker + + + + + + + 238.0000000 + + Food Source + MPS:0238, PCX:-0001 + MPS:0238, PCX:-0001 + Food Source + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 105.0000000 + + Forest + MPS:0105, PCX:08245 + MPS:0105, PCX:08245 + Forest + + + 8245.0000000 + SymbolAndName + + Outdoor + + + + + + + 239.0000000 + + Furbearer + MPS:0239, PCX:-0001 + MPS:0239, PCX:-0001 + Furbearer + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 8.0000000 + + Gas Station + MPS:0008, PCX:00008 + MPS:0008, PCX:00008 + Gas Station + + + 8.0000000 + SymbolAndName + + Transportation + + + + + + + 117.0000000 + + Geocache + MPS:0117, PCX:08255 + MPS:0117, PCX:08255 + Geocache + + + 8255.0000000 + SymbolAndName + + Outdoor + + + + + + + 118.0000000 + + Geocache Found + MPS:0118, PCX:08256 + MPS:0118, PCX:08256 + Geocache Found + + + 8256.0000000 + SymbolAndName + + Outdoor + + + + + + + 99.0000000 + + Ghost Town + MPS:0099, PCX:08239 + MPS:0099, PCX:08239 + Ghost Town + + + 8239.0000000 + SymbolAndName + + Outdoor + + + + + + + 113.0000000 + + Glider Area + MPS:0113, PCX:16393 + MPS:0113, PCX:16393 + Glider Area + + + 16393.0000000 + SymbolAndName + + Aviation + + + + + + + 68.0000000 + + Golf Course + MPS:0068, PCX:08197 + MPS:0068, PCX:08197 + Golf Course + + + 8197.0000000 + SymbolAndName + + Outdoor + + + + + + + 229.0000000 + + Ground Transportation + MPS:0229, PCX:-0001 + MPS:0229, PCX:-0001 + Ground Transportation + + + -1.0000000 + SymbolAndName + + Transportation + + + + + + + 108.0000000 + + Heliport + MPS:0108, PCX:16388 + MPS:0108, PCX:16388 + Heliport + + + 16388.0000000 + SymbolAndName + + Aviation + + + + + + + 9.0000000 + + Horn + MPS:0009, PCX:00009 + MPS:0009, PCX:00009 + Horn + + + 9.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 57.0000000 + + Hunting Area + MPS:0057, PCX:00171 + MPS:0057, PCX:00171 + Hunting Area + + + 171.0000000 + SymbolAndName + + Outdoor + Hunting + + + + + + + 153.0000000 + + Ice Skating + MPS:0153, PCX:08252 + MPS:0153, PCX:08252 + Ice Skating + + + 8252.0000000 + SymbolAndName + + Outdoor + + + + + + + 44.0000000 + + Information + MPS:0044, PCX:00157 + MPS:0044, PCX:00157 + Information + + + 157.0000000 + SymbolAndName + + Transportation + + + + + + + 178.0000000 + + Letter A, Blue + MPS:0178, PCX:08317 + MPS:0178, PCX:08317 + Letter A, Blue + + + 8317.0000000 + SymbolAndName + + Letter + + + + + + + 177.0000000 + + Letter A, Green + MPS:0177, PCX:08313 + MPS:0177, PCX:08313 + Letter A, Green + + + 8313.0000000 + SymbolAndName + + Letter + + + + + + + 176.0000000 + + Letter A, Red + MPS:0176, PCX:08309 + MPS:0176, PCX:08309 + Letter A, Red + + + 8309.0000000 + SymbolAndName + + Letter + + + + + + + 181.0000000 + + Letter B, Blue + MPS:0181, PCX:08318 + MPS:0181, PCX:08318 + Letter B, Blue + + + 8318.0000000 + SymbolAndName + + Letter + + + + + + + 180.0000000 + + Letter B, Green + MPS:0180, PCX:08315 + MPS:0180, PCX:08315 + Letter B, Green + + + 8315.0000000 + SymbolAndName + + Letter + + + + + + + 179.0000000 + + Letter B, Red + MPS:0179, PCX:08310 + MPS:0179, PCX:08310 + Letter B, Red + + + 8310.0000000 + SymbolAndName + + Letter + + + + + + + 184.0000000 + + Letter C, Blue + MPS:0184, PCX:08319 + MPS:0184, PCX:08319 + Letter C, Blue + + + 8319.0000000 + SymbolAndName + + Letter + + + + + + + 183.0000000 + + Letter C, Green + MPS:0183, PCX:08314 + MPS:0183, PCX:08314 + Letter C, Green + + + 8314.0000000 + SymbolAndName + + Letter + + + + + + + 182.0000000 + + Letter C, Red + MPS:0182, PCX:08311 + MPS:0182, PCX:08311 + Letter C, Red + + + 8311.0000000 + SymbolAndName + + Letter + + + + + + + 187.0000000 + + Letter D, Blue + MPS:0187, PCX:08320 + MPS:0187, PCX:08320 + Letter D, Blue + + + 8320.0000000 + SymbolAndName + + Letter + + + + + + + 186.0000000 + + Letter D, Green + MPS:0186, PCX:08316 + MPS:0186, PCX:08316 + Letter D, Green + + + 8316.0000000 + SymbolAndName + + Letter + + + + + + + 185.0000000 + + Letter D, Red + MPS:0185, PCX:08312 + MPS:0185, PCX:08312 + Letter D, Red + + + 8312.0000000 + SymbolAndName + + Letter + + + + + + + 226.0000000 + + Letterbox Cache + MPS:0226, PCX:-0001 + MPS:0226, PCX:-0001 + Letterbox Cache + + + -1.0000000 + SymbolAndName + + Outdoor + + + + + + + 100.0000000 + + Levee + MPS:0100, PCX:08240 + MPS:0100, PCX:08240 + Levee + + + 8240.0000000 + SymbolAndName + + Marine + + + + + + + 228.0000000 + + Library + MPS:0228, PCX:-0001 + MPS:0228, PCX:-0001 + Library + + + -1.0000000 + SymbolAndName + + Civil + + + + + + + 12.0000000 + + Light + MPS:0012, PCX:00012 + MPS:0012, PCX:00012 + Light + + + 12.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 90.0000000 + + Live Theater + MPS:0090, PCX:08221 + MPS:0090, PCX:08221 + Live Theater + + + 8221.0000000 + SymbolAndName + + Business + + + + + + + 240.0000000 + + Lodge + MPS:0240, PCX:-0001 + MPS:0240, PCX:-0001 + Lodge + + + -1.0000000 + SymbolAndName + + Outdoor + + + + + + + 59.0000000 + + Lodging + MPS:0059, PCX:00173 + MPS:0059, PCX:00173 + Lodging + + + 173.0000000 + SymbolAndName + + Business + + + + + + + 20.0000000 + + Man Overboard + MPS:0020, PCX:00021 + MPS:0020, PCX:00021 + Man Overboard + + + 21.0000000 + SymbolAndName + + Marine + + + + + + + 162.0000000 + + Marina + MPS:0162, PCX:00191 + MPS:0162, PCX:00191 + Marina + + + 191.0000000 + SymbolAndName + + Marine + + + + + + + 43.0000000 + + Medical Facility + MPS:0043, PCX:00156 + MPS:0043, PCX:00156 + Medical Facility + + + 156.0000000 + SymbolAndName + + Civil + + + + + + + 66.0000000 + + Mile Marker + MPS:0066, PCX:08195 + MPS:0066, PCX:08195 + Mile Marker + + + 8195.0000000 + SymbolAndName + + Transportation + + + + + + + 101.0000000 + + Military + MPS:0101, PCX:08241 + MPS:0101, PCX:08241 + Military + + + 8241.0000000 + SymbolAndName + + Civil + + + + + + + 60.0000000 + + Mine + MPS:0060, PCX:00174 + MPS:0060, PCX:00174 + Mine + + + 174.0000000 + SymbolAndName + + Civil + + + + + + + 79.0000000 + + Movie Theater + MPS:0079, PCX:08210 + MPS:0079, PCX:08210 + Movie Theater + + + 8210.0000000 + SymbolAndName + + Business + + + + + + + 225.0000000 + + Multi-Cache + MPS:0225, PCX:08217 + MPS:0225, PCX:08217 + Stadium + + + 8217.0000000 + SymbolAndName + + Outdoor + + + + + + + 80.0000000 + + Museum + MPS:0080, PCX:08211 + MPS:0080, PCX:08211 + Museum + + + 8211.0000000 + SymbolAndName + + Business + + + + + + + 21.0000000 + + Navaid, Amber + MPS:0021, PCX:00022 + MPS:0021, PCX:00022 + Navaid, Amber + + + 22.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 22.0000000 + + Navaid, Black + MPS:0022, PCX:00023 + MPS:0022, PCX:00023 + Navaid, Black + + + 23.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 23.0000000 + + Navaid, Blue + MPS:0023, PCX:00024 + MPS:0023, PCX:00024 + Navaid, Blue + + + 24.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 24.0000000 + + Navaid, Green + MPS:0024, PCX:00025 + MPS:0024, PCX:00025 + Navaid, Green + + + 25.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 25.0000000 + + Navaid, Green/Red + MPS:0025, PCX:00026 + MPS:0025, PCX:00026 + Navaid, Green/Red + + + 26.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 26.0000000 + + Navaid, Green/White + MPS:0026, PCX:00027 + MPS:0026, PCX:00027 + Navaid, Green/White + + + 27.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 27.0000000 + + Navaid, Orange + MPS:0027, PCX:00028 + MPS:0027, PCX:00028 + Navaid, Orange + + + 28.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 28.0000000 + + Navaid, Red + MPS:0028, PCX:00029 + MPS:0028, PCX:00029 + Navaid, Red + + + 29.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 29.0000000 + + Navaid, Red/Green + MPS:0029, PCX:00030 + MPS:0029, PCX:00030 + Navaid, Red/Green + + + 30.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 30.0000000 + + Navaid, Red/White + MPS:0030, PCX:00031 + MPS:0030, PCX:00031 + Navaid, Red/White + + + 31.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 31.0000000 + + Navaid, Violet + MPS:0031, PCX:00032 + MPS:0031, PCX:00032 + Navaid, Violet + + + 32.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 32.0000000 + + Navaid, White + MPS:0032, PCX:00033 + MPS:0032, PCX:00033 + Navaid, White + + + 33.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 33.0000000 + + Navaid, White/Green + MPS:0033, PCX:00034 + MPS:0033, PCX:00034 + Navaid, White/Green + + + 34.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 34.0000000 + + Navaid, White/Red + MPS:0034, PCX:00035 + MPS:0034, PCX:00035 + Navaid, White/Red + + + 35.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 190.0000000 + + Number 0, Blue + MPS:0190, PCX:08341 + MPS:0190, PCX:08341 + Number 0, Blue + + + 8341.0000000 + SymbolAndName + + Number + + + + + + + 189.0000000 + + Number 0, Green + MPS:0189, PCX:08331 + MPS:0189, PCX:08331 + Number 0, Green + + + 8331.0000000 + SymbolAndName + + Number + + + + + + + 188.0000000 + + Number 0, Red + MPS:0188, PCX:08321 + MPS:0188, PCX:08321 + Number 0, Red + + + 8321.0000000 + SymbolAndName + + Number + + + + + + + 193.0000000 + + Number 1, Blue + MPS:0193, PCX:08342 + MPS:0193, PCX:08342 + Number 1, Blue + + + 8342.0000000 + SymbolAndName + + Number + + + + + + + 192.0000000 + + Number 1, Green + MPS:0192, PCX:08332 + MPS:0192, PCX:08332 + Number 1, Green + + + 8332.0000000 + SymbolAndName + + Number + + + + + + + 191.0000000 + + Number 1, Red + MPS:0191, PCX:08322 + MPS:0191, PCX:08322 + Number 1, Red + + + 8322.0000000 + SymbolAndName + + Number + + + + + + + 196.0000000 + + Number 2, Blue + MPS:0196, PCX:08343 + MPS:0196, PCX:08343 + Number 2, Blue + + + 8343.0000000 + SymbolAndName + + Number + + + + + + + 195.0000000 + + Number 2, Green + MPS:0195, PCX:08333 + MPS:0195, PCX:08333 + Number 2, Green + + + 8333.0000000 + SymbolAndName + + Number + + + + + + + 194.0000000 + + Number 2, Red + MPS:0194, PCX:08323 + MPS:0194, PCX:08323 + Number 2, Red + + + 8323.0000000 + SymbolAndName + + Number + + + + + + + 199.0000000 + + Number 3, Blue + MPS:0199, PCX:08344 + MPS:0199, PCX:08344 + Number 3, Blue + + + 8344.0000000 + SymbolAndName + + Number + + + + + + + 198.0000000 + + Number 3, Green + MPS:0198, PCX:08334 + MPS:0198, PCX:08334 + Number 3, Green + + + 8334.0000000 + SymbolAndName + + Number + + + + + + + 197.0000000 + + Number 3, Red + MPS:0197, PCX:08324 + MPS:0197, PCX:08324 + Number 3, Red + + + 8324.0000000 + SymbolAndName + + Number + + + + + + + 202.0000000 + + Number 4, Blue + MPS:0202, PCX:08345 + MPS:0202, PCX:08345 + Number 4, Blue + + + 8345.0000000 + SymbolAndName + + Number + + + + + + + 201.0000000 + + Number 4, Green + MPS:0201, PCX:08335 + MPS:0201, PCX:08335 + Number 4, Green + + + 8335.0000000 + SymbolAndName + + Number + + + + + + + 200.0000000 + + Number 4, Red + MPS:0200, PCX:08325 + MPS:0200, PCX:08325 + Number 4, Red + + + 8325.0000000 + SymbolAndName + + Number + + + + + + + 205.0000000 + + Number 5, Blue + MPS:0205, PCX:08346 + MPS:0205, PCX:08346 + Number 5, Blue + + + 8346.0000000 + SymbolAndName + + Number + + + + + + + 204.0000000 + + Number 5, Green + MPS:0204, PCX:08336 + MPS:0204, PCX:08336 + Number 5, Green + + + 8336.0000000 + SymbolAndName + + Number + + + + + + + 203.0000000 + + Number 5, Red + MPS:0203, PCX:08326 + MPS:0203, PCX:08326 + Number 5, Red + + + 8326.0000000 + SymbolAndName + + Number + + + + + + + 208.0000000 + + Number 6, Blue + MPS:0208, PCX:08347 + MPS:0208, PCX:08347 + Number 6, Blue + + + 8347.0000000 + SymbolAndName + + Number + + + + + + + 207.0000000 + + Number 6, Green + MPS:0207, PCX:08337 + MPS:0207, PCX:08337 + Number 6, Green + + + 8337.0000000 + SymbolAndName + + Number + + + + + + + 206.0000000 + + Number 6, Red + MPS:0206, PCX:08327 + MPS:0206, PCX:08327 + Number 6, Red + + + 8327.0000000 + SymbolAndName + + Number + + + + + + + 211.0000000 + + Number 7, Blue + MPS:0211, PCX:08348 + MPS:0211, PCX:08348 + Number 7, Blue + + + 8348.0000000 + SymbolAndName + + Number + + + + + + + 210.0000000 + + Number 7, Green + MPS:0210, PCX:08338 + MPS:0210, PCX:08338 + Number 7, Green + + + 8338.0000000 + SymbolAndName + + Number + + + + + + + 209.0000000 + + Number 7, Red + MPS:0209, PCX:08328 + MPS:0209, PCX:08328 + Number 7, Red + + + 8328.0000000 + SymbolAndName + + Number + + + + + + + 214.0000000 + + Number 8, Blue + MPS:0214, PCX:08349 + MPS:0214, PCX:08349 + Number 8, Blue + + + 8349.0000000 + SymbolAndName + + Number + + + + + + + 213.0000000 + + Number 8, Green + MPS:0213, PCX:08339 + MPS:0213, PCX:08339 + Number 8, Green + + + 8339.0000000 + SymbolAndName + + Number + + + + + + + 212.0000000 + + Number 8, Red + MPS:0212, PCX:08329 + MPS:0212, PCX:08329 + Number 8, Red + + + 8329.0000000 + SymbolAndName + + Number + + + + + + + 217.0000000 + + Number 9, Blue + MPS:0217, PCX:08350 + MPS:0217, PCX:08350 + Number 9, Blue + + + 8350.0000000 + SymbolAndName + + Number + + + + + + + 216.0000000 + + Number 9, Green + MPS:0216, PCX:08340 + MPS:0216, PCX:08340 + Number 9, Green + + + 8340.0000000 + SymbolAndName + + Number + + + + + + + 215.0000000 + + Number 9, Red + MPS:0215, PCX:08330 + MPS:0215, PCX:08330 + Number 9, Red + + + 8330.0000000 + SymbolAndName + + Number + + + + + + + 102.0000000 + + Oil Field + MPS:0102, PCX:08242 + MPS:0102, PCX:08242 + Oil Field + + + 8242.0000000 + SymbolAndName + + Civil + + + + + + + 171.0000000 + + Oval, Blue + MPS:0171, PCX:08302 + MPS:0171, PCX:08302 + Oval, Blue + + + 8302.0000000 + SymbolAndName + + Marker + + + + + + + 170.0000000 + + Oval, Green + MPS:0170, PCX:08301 + MPS:0170, PCX:08301 + Oval, Green + + + 8301.0000000 + SymbolAndName + + Marker + + + + + + + 169.0000000 + + Oval, Red + MPS:0169, PCX:08300 + MPS:0169, PCX:08300 + Oval, Red + + + 8300.0000000 + SymbolAndName + + Marker + + + + + + + 115.0000000 + + Parachute Area + MPS:0115, PCX:16395 + MPS:0115, PCX:16395 + Parachute Area + + + 16395.0000000 + SymbolAndName + + Aviation + + + + + + + 46.0000000 + + Park + MPS:0046, PCX:00159 + MPS:0046, PCX:00159 + Park + + + 159.0000000 + SymbolAndName + + Outdoor + + + + + + + 45.0000000 + + Parking Area + MPS:0045, PCX:00158 + MPS:0045, PCX:00158 + Parking Area + + + 158.0000000 + SymbolAndName + + Transportation + + + + + + + 81.0000000 + + Pharmacy + MPS:0081, PCX:08212 + MPS:0081, PCX:08212 + Pharmacy + + + 8212.0000000 + SymbolAndName + + Business + + + + + + + 47.0000000 + + Picnic Area + MPS:0047, PCX:00160 + MPS:0047, PCX:00160 + Picnic Area + + + 160.0000000 + SymbolAndName + + Outdoor + + + + + + + 144.0000000 + + Pin, Blue + MPS:0144, PCX:08287 + MPS:0144, PCX:08287 + Pin, Blue + + + 8287.0000000 + SymbolAndName + + Marker + + + + + + + 145.0000000 + + Pin, Green + MPS:0145, PCX:08288 + MPS:0145, PCX:08288 + Pin, Green + + + 8288.0000000 + SymbolAndName + + Marker + + + + + + + 143.0000000 + + Pin, Red + MPS:0143, PCX:08289 + MPS:0143, PCX:08289 + Pin, Red + + + 8289.0000000 + SymbolAndName + + Marker + + + + + + + 82.0000000 + + Pizza + MPS:0082, PCX:08213 + MPS:0082, PCX:08213 + Pizza + + + 8213.0000000 + SymbolAndName + + Business + + + + + + + 151.0000000 + + Police Station + MPS:0151, PCX:08249 + MPS:0151, PCX:08249 + Police Station + + + 8249.0000000 + SymbolAndName + + Civil + + + + + + + 83.0000000 + + Post Office + MPS:0083, PCX:08214 + MPS:0083, PCX:08214 + Post Office + + + 8214.0000000 + SymbolAndName + + Civil + + + + + + + 109.0000000 + + Private Field + MPS:0109, PCX:16389 + MPS:0109, PCX:16389 + Private Field + + + 16389.0000000 + SymbolAndName + + Aviation + + + + + + + 227.0000000 + + Puzzle Cache + MPS:0227, PCX:-0001 + MPS:0227, PCX:-0001 + Puzzle Cache + + + -1.0000000 + SymbolAndName + + Outdoor + + + + + + + 36.0000000 + + Radio Beacon + MPS:0036, PCX:00037 + MPS:0036, PCX:00037 + Radio Beacon + + + 37.0000000 + SymbolAndName + + Navigation Aid + + + + + + + 174.0000000 + + Rectangle, Blue + MPS:0174, PCX:08305 + MPS:0174, PCX:08305 + Rectangle, Blue + + + 8305.0000000 + SymbolAndName + + Marker + + + + + + + 173.0000000 + + Rectangle, Green + MPS:0173, PCX:08304 + MPS:0173, PCX:08304 + Rectangle, Green + + + 8304.0000000 + SymbolAndName + + Marker + + + + + + + 172.0000000 + + Rectangle, Red + MPS:0172, PCX:08303 + MPS:0172, PCX:08303 + Rectangle, Red + + + 8303.0000000 + SymbolAndName + + Marker + + + + + + + 158.0000000 + + Reef + MPS:0158, PCX:00187 + MPS:0158, PCX:00187 + Reef + + + 187.0000000 + SymbolAndName + + Marine + + + + + + + 10.0000000 + + Residence + MPS:0010, PCX:00010 + MPS:0010, PCX:00010 + Residence + + + 10.0000000 + SymbolAndName + + Civil + + + + + + + 11.0000000 + + Restaurant + MPS:0011, PCX:00011 + MPS:0011, PCX:00011 + Restaurant + + + 11.0000000 + SymbolAndName + + Business + + + + + + + 54.0000000 + + Restricted Area + MPS:0054, PCX:00167 + MPS:0054, PCX:00167 + Restricted Area + + + 167.0000000 + SymbolAndName + + Marine + + + + + + + 39.0000000 + + Restroom + MPS:0039, PCX:00152 + MPS:0039, PCX:00152 + Restroom + + + 152.0000000 + SymbolAndName + + Transportation + + + + + + + 84.0000000 + + RV Park + MPS:0084, PCX:08215 + MPS:0084, PCX:08215 + RV Park + + + 8215.0000000 + SymbolAndName + + Outdoor + + + + + + + 91.0000000 + + Scales + MPS:0091, PCX:08226 + MPS:0091, PCX:08226 + Scales + + + 8226.0000000 + SymbolAndName + + Transportation + + + + + + + 48.0000000 + + Scenic Area + MPS:0048, PCX:00161 + MPS:0048, PCX:00161 + Scenic Area + + + 161.0000000 + SymbolAndName + + Outdoor + + + + + + + 85.0000000 + + School + MPS:0085, PCX:08216 + MPS:0085, PCX:08216 + School + + + 8216.0000000 + SymbolAndName + + Civil + + + + + + + 116.0000000 + + Seaplane Base + MPS:0116, PCX:16402 + MPS:0116, PCX:16402 + Seaplane Base + + + 16402.0000000 + SymbolAndName + + Aviation + + + + + + + 19.0000000 + + Shipwreck + MPS:0019, PCX:00019 + MPS:0019, PCX:00019 + Shipwreck + + + 19.0000000 + SymbolAndName + + Marine + + + + + + + 58.0000000 + + Shopping Center + MPS:0058, PCX:00172 + MPS:0058, PCX:00172 + Shopping Center + + + 172.0000000 + SymbolAndName + + Business + + + + + + + 112.0000000 + + Short Tower + MPS:0112, PCX:16392 + MPS:0112, PCX:16392 + Short Tower + + + 16392.0000000 + SymbolAndName + + Civil + + + + + + + 40.0000000 + + Shower + MPS:0040, PCX:00153 + MPS:0040, PCX:00153 + Shower + + + 153.0000000 + SymbolAndName + + Outdoor + + + + + + + 152.0000000 + + Ski Resort + MPS:0152, PCX:08251 + MPS:0152, PCX:08251 + Ski Resort + + + 8251.0000000 + SymbolAndName + + Outdoor + + + + + + + 49.0000000 + + Skiing Area + MPS:0049, PCX:00162 + MPS:0049, PCX:00162 + Skiing Area + + + 162.0000000 + SymbolAndName + + Outdoor + + + + + + + 14.0000000 + + Skull and Crossbones + MPS:0014, PCX:00014 + MPS:0014, PCX:00014 + Skull and Crossbones + + + 14.0000000 + SymbolAndName + + Marine + + + + + + + 241.0000000 + + Small Game + MPS:0241, PCX:-0001 + MPS:0241, PCX:-0001 + Small Game + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 110.0000000 + + Soft Field + MPS:0110, PCX:16390 + MPS:0110, PCX:16390 + Soft Field + + + 16390.0000000 + SymbolAndName + + Aviation + + + + + + + 175.0000000 + + Square, Blue + MPS:0175, PCX:08308 + MPS:0175, PCX:08308 + Square, Blue + + + 8308.0000000 + SymbolAndName + + Marker + + + + + + + 15.0000000 + + Square, Green + MPS:0015, PCX:00015 + MPS:0015, PCX:00015 + Square, Green + + + 15.0000000 + SymbolAndName + + Marker + + + + + + + 16.0000000 + + Square, Red + MPS:0016, PCX:00016 + MPS:0016, PCX:00016 + Square, Red + + + 16.0000000 + SymbolAndName + + Marker + + + + + + + 86.0000000 + + Stadium + MPS:0086, PCX:08217 + MPS:0086, PCX:08217 + Stadium + + + 8217.0000000 + SymbolAndName + + Business + + + + + + + 164.0000000 + + Stump + MPS:0164, PCX:00193 + MPS:0164, PCX:00193 + Stump + + + 193.0000000 + SymbolAndName + + Marine + + + + + + + 106.0000000 + + Summit + MPS:0106, PCX:08246 + MPS:0106, PCX:08246 + Summit + + + 8246.0000000 + SymbolAndName + + Outdoor + + + + + + + 50.0000000 + + Swimming Area + MPS:0050, PCX:00163 + MPS:0050, PCX:00163 + Swimming Area + + + 163.0000000 + SymbolAndName + + Outdoor + + + + + + + 111.0000000 + + Tall Tower + MPS:0111, PCX:16391 + MPS:0111, PCX:16391 + Tall Tower + + + 16391.0000000 + SymbolAndName + + Civil + + + + + + + 42.0000000 + + Telephone + MPS:0042, PCX:00155 + MPS:0042, PCX:00155 + Telephone + + + 155.0000000 + SymbolAndName + + Transportation + + + + + + + 92.0000000 + + Toll Booth + MPS:0092, PCX:08227 + MPS:0092, PCX:08227 + Toll Booth + + + 8227.0000000 + SymbolAndName + + Transportation + + + + + + + 67.0000000 + + TracBack Point + MPS:0067, PCX:08196 + MPS:0067, PCX:08196 + TracBack Point + + + 8196.0000000 + SymbolAndName + + Outdoor + + + + + + + 61.0000000 + + Trail Head + MPS:0061, PCX:00175 + MPS:0061, PCX:00175 + Trail Head + + + 175.0000000 + SymbolAndName + + Outdoor + + + + + + + 244.0000000 + + Tree Stand + MPS:0244, PCX:-0001 + MPS:0244, PCX:-0001 + Tree Stand + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 243.0000000 + + Treed Quarry + MPS:0243, PCX:-0001 + MPS:0243, PCX:-0001 + Treed Quarry + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 218.0000000 + + Triangle, Blue + MPS:0218, PCX:08351 + MPS:0218, PCX:08351 + Triangle, Blue + + + 8351.0000000 + SymbolAndName + + Marker + + + + + + + 219.0000000 + + Triangle, Green + MPS:0219, PCX:08352 + MPS:0219, PCX:08352 + Triangle, Green + + + 8352.0000000 + SymbolAndName + + Marker + + + + + + + 220.0000000 + + Triangle, Red + MPS:0220, PCX:08353 + MPS:0220, PCX:08353 + Triangle, Red + + + 8353.0000000 + SymbolAndName + + Marker + + + + + + + 245.0000000 + + Truck + MPS:0245, PCX:-0001 + MPS:0245, PCX:-0001 + Truck + + + -1.0000000 + SymbolAndName + + Outdoor + + + + + + + 62.0000000 + + Truck Stop + MPS:0062, PCX:00176 + MPS:0062, PCX:00176 + Truck Stop + + + 176.0000000 + SymbolAndName + + Transportation + + + + + + + 103.0000000 + + Tunnel + MPS:0103, PCX:08243 + MPS:0103, PCX:08243 + Tunnel + + + 8243.0000000 + SymbolAndName + + Transportation + + + + + + + 114.0000000 + + Ultralight Area + MPS:0114, PCX:16394 + MPS:0114, PCX:16394 + Ultralight Area + + + 16394.0000000 + SymbolAndName + + Aviation + + + + + + + 246.0000000 + + Upland Game + MPS:0246, PCX:-0001 + MPS:0246, PCX:-0001 + Upland Game + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 139.0000000 + + Water Hydrant + MPS:0139, PCX:08282 + MPS:0139, PCX:08282 + Water Hydrant + + + 8282.0000000 + SymbolAndName + + Civil + + + + + + + 248.0000000 + + Water Source + MPS:0248, PCX:-0001 + MPS:0248, PCX:-0001 + Water Source + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 247.0000000 + + Waterfowl + MPS:0247, PCX:-0001 + MPS:0247, PCX:-0001 + Waterfowl + + + -1.0000000 + SymbolAndName + + Hunting + + + + + + + 18.0000000 + + Waypoint + MPS:0018, PCX:00018 + MPS:0018, PCX:00018 + Waypoint + + + 18.0000000 + SymbolAndName + + Marker + + + + + + + 159.0000000 + + Weed Bed + MPS:0159, PCX:00188 + MPS:0159, PCX:00188 + Weed Bed + + + 188.0000000 + SymbolAndName + + Marine + + + + + + + 231.0000000 + + Winery + MPS:0231, PCX:-0001 + MPS:0231, PCX:-0001 + Winery + + + -1.0000000 + SymbolAndName + + Business + + + + + + + 154.0000000 + + Wrecker + MPS:0154, PCX:08253 + MPS:0154, PCX:08253 + Wrecker + + + 8253.0000000 + SymbolAndName + + Transportation + + + + + + + 88.0000000 + + Zoo + MPS:0088, PCX:08219 + MPS:0088, PCX:08219 + Zoo + + + 8219.0000000 + SymbolAndName + + Business + + + + + + diff --git a/reference/garmin_txt-uni.csv b/reference/garmin_txt-uni.csv new file mode 100644 index 000000000..51ba3799b --- /dev/null +++ b/reference/garmin_txt-uni.csv @@ -0,0 +1,15 @@ +No,Latitude,Longitude,Name,Altitude,Description,Symbol,Date,Time,URL,Facility,City,Country +1,50.492603,12.105431,"001",,"001","Waypoint",2006/03/28,00:10:37,,,, +2,50.492603,12.105431,"002",,"002","Waypoint",2006/03/28,00:10:37,,,, +3,50.494277,12.105130,"003",,"003","Waypoint",2006/03/28,00:10:37,,,, +4,50.493834,12.106101,"004",,"004","Waypoint",2006/03/28,00:10:37,,,, +5,50.493834,12.106101,"005",,"005","Waypoint",2006/03/28,00:10:37,,,, +6,50.493376,12.107105,"006",,"006","Waypoint",2006/03/28,00:10:37,,,, +7,50.493660,12.107152,"007",,"007","Waypoint",2006/03/28,00:10:37,,,, +8,51.893799,12.977943,"ED_X",,"Dummy airport (Germany)","Airport",2006/03/28,01:38:07,,"FAC1","CITY1","Germany" +9,38.631995,-3.174055,"GC_X",,"Dummy airport (Spain)","Airport",2006/03/28,01:42:01,,"FAC2","CITY2","Canary Island" +10,50.493667,12.107150,"Jahnstrasse",,"Jahnstrasse 11","Flag, Red",2006/03/31,21:48:22,,,, +11,46.387606,3.498277,"LF_X",,"Dummy airport (France)","Airport",2006/03/28,01:40:32,,"FAC3","CITY3","France" +12,50.493834,12.106100,"Liebknechtstrasse",,"Liebknechtstrasse 90","Waypoint",2006/03/31,21:49:30,,,, +13,43.314550,12.161554,"LI_X",,"Dummy airport (Italy)","Heliport",2006/03/28,01:43:25,,"FAC4","CITY4","Italy" +14,50.492616,12.105448,"NARVA",391.0,"Start","Flag, Green",2006/03/31,21:49:26,"http://www.narva-light.de",,, diff --git a/reference/garmin_txt.txt b/reference/garmin_txt.txt new file mode 100644 index 000000000..dae88c25b --- /dev/null +++ b/reference/garmin_txt.txt @@ -0,0 +1,96 @@ +Grid Lat/Lon hddd°mm.mmm' +Datum WGS 84 + +Header Name Description Type Position Altitude Depth Proximity Temperature Display Mode Color Symbol Facility City State Country Date Modified Link Categories + +Waypoint 001 Map Line N50 29.556188732 E12 06.325848140 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 002 Map Intersection N50 29.556188732 E12 06.325848140 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 003 Map Intersection N50 29.656610638 E12 06.307823695 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 004 Map Line N50 29.630036652 E12 06.366030984 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 005 Map Line N50 29.630036652 E12 06.366030984 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 006 Map Intersection N50 29.602537304 E12 06.426270045 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 007 Map Line N50 29.619586095 E12 06.429106481 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint ED_X Dummy airport (Germany) Airport N51 53.627961650 E12 58.676564991 Symbol & Name Unknown Airport FAC1 CITY1 Germany 28/03/2006 01:38:07 +Waypoint GC_X Dummy airport (Spain) Airport N38 37.919719778 W3 10.443304181 Symbol & Name Unknown Airport FAC2 CITY2 Canary Island 28/03/2006 01:42:01 +Waypoint Jahnstrasse Jahnstrasse 11 User Waypoint N50 29.619998485 E12 06.429000869 Symbol & Description Unknown Flag, Red 31/03/2006 21:48:22 +Waypoint LF_X Dummy airport (France) Airport N46 23.256332763 E3 29.896638617 Symbol & Name Unknown Airport FAC3 CITY3 France 28/03/2006 01:40:32 +Waypoint Liebknechtstrasse Liebknechtstrasse 90 User Waypoint N50 29.630041681 E12 06.366015896 Symbol & Name Unknown Waypoint 31/03/2006 21:49:30 +Waypoint LI_X Dummy airport (Italy) Airport N43 18.873018846 E12 09.693240859 Symbol & Name Unknown Heliport FAC4 CITY4 Italy 28/03/2006 01:43:25 +Waypoint NARVA Start User Waypoint N50 29.556958191 E12 06.326884143 391 m Symbol Unknown Flag, Green 31/03/2006 21:49:26 http://www.narva-light.de Category 15 + + +Header Name Length Course Waypoints Link + +Route ED_X-LF_X 4087 km 232° true 4 waypoints + +Header Waypoint Name Distance Leg Length Course + +Route Waypoint ED_X 0 m +Route Waypoint GC_X 1936 km 1936 km 227° true +Route Waypoint LI_X 3323 km 1388 km 63° true +Route Waypoint LF_X 4087 km 764 km 300° true + +Route NARVA to Jahnstrasse 394 m 46° true 10 waypoints + +Header Waypoint Name Distance Leg Length Course + +Route Waypoint NARVA 0 m +Route Waypoint 001 2 m 2 m 221° true +Route Waypoint 002 2 m 0 m 0° true +Route Waypoint 003 189 m 188 m 353° true +Route Waypoint 004 274 m 85 m 126° true +Route Waypoint Liebknechtstrasse 274 m 0 m 298° true +Route Waypoint 005 274 m 0 m 118° true +Route Waypoint 006 361 m 88 m 126° true +Route Waypoint 007 393 m 32 m 6° true +Route Waypoint Jahnstrasse 394 m 1 m 351° true + + +Header Name Start Time Elapsed Time Length Average Speed Link + +Track ACTIVE LOG 006 01/05/2005 15:02:47 0:33:09 653 m 1.2 kph + +Header Position Time Altitude Depth Temperature Leg Length Leg Time Leg Speed Leg Course + +Trackpoint N51 18.776294924 E12 24.789910130 01/05/2005 15:02:47 161 m 0.0 m +Trackpoint N51 18.772960603 E12 24.794909097 01/05/2005 15:03:25 154 m 0.0 m 8 m 0:00:38 0.8 kph 137° true +Trackpoint N51 18.771295957 E12 24.794909097 01/05/2005 15:03:39 148 m 0.0 m 3 m 0:00:14 0.8 kph 180° true +Trackpoint N51 18.769626282 E12 24.798243418 01/05/2005 15:04:16 139 m 0.0 m 5 m 0:00:37 0.5 kph 129° true +Trackpoint N51 18.769626282 E12 24.796573743 01/05/2005 15:05:02 145 m 0.0 m 2 m 0:00:46 0.2 kph 270° true +Trackpoint N51 18.769626282 E12 24.798243418 01/05/2005 15:05:45 134 m 0.0 m 2 m 0:00:43 0.2 kph 90° true +Trackpoint N51 18.766296990 E12 24.799908064 01/05/2005 15:06:44 131 m 0.0 m 6 m 0:00:59 0.4 kph 163° true +Trackpoint N51 18.766296990 E12 24.799908064 01/05/2005 15:07:50 130 m 0.0 m 0 m 0:01:06 0 kph 0° true +Trackpoint N51 18.764627315 E12 24.799908064 01/05/2005 15:08:19 132 m 0.0 m 3 m 0:00:29 0.4 kph 180° true +Trackpoint N51 18.767961636 E12 24.798243418 01/05/2005 15:11:16 144 m 0.0 m 6 m 0:02:57 0.1 kph 343° true +Trackpoint N51 18.774630278 E12 24.806576706 01/05/2005 15:12:34 147 m 0.0 m 16 m 0:01:18 0.7 kph 38° true +Trackpoint N51 18.779629245 E12 24.828242250 01/05/2005 15:13:18 145 m 0.0 m 27 m 0:00:44 2 kph 70° true +Trackpoint N51 18.782963566 E12 24.828242250 01/05/2005 15:13:27 145 m 0.0 m 6 m 0:00:09 2 kph 0° true +Trackpoint N51 18.782963566 E12 24.829906896 01/05/2005 15:13:37 135 m 0.0 m 2 m 0:00:10 0.7 kph 90° true +Trackpoint N51 18.786292858 E12 24.829906896 01/05/2005 15:13:46 135 m 0.0 m 6 m 0:00:09 2 kph 0° true +Trackpoint N51 18.792961501 E12 24.833241217 01/05/2005 15:14:03 136 m 0.0 m 13 m 0:00:17 3 kph 17° true +Trackpoint N51 18.797960468 E12 24.838240184 01/05/2005 15:14:16 135 m 0.0 m 11 m 0:00:13 3 kph 32° true +Trackpoint N51 18.796295822 E12 24.843239151 01/05/2005 15:14:26 139 m 0.0 m 7 m 0:00:10 2 kph 118° true +Trackpoint N51 18.796295822 E12 24.846573472 01/05/2005 15:14:30 139 m 0.0 m 4 m 0:00:04 3 kph 90° true +Trackpoint N51 18.782963566 E12 24.876572303 01/05/2005 15:15:06 141 m 0.0 m 43 m 0:00:36 4 kph 125° true +Trackpoint N51 18.777959570 E12 24.889909588 01/05/2005 15:15:27 140 m 0.0 m 18 m 0:00:21 3 kph 121° true +Trackpoint N51 18.774630278 E12 24.896573201 01/05/2005 15:15:39 140 m 0.0 m 10 m 0:00:12 3 kph 129° true +Trackpoint N51 18.776294924 E12 24.898242876 01/05/2005 15:25:31 152 m 0.0 m 4 m 0:09:52 0.0 kph 32° true +Trackpoint N51 18.776294924 E12 24.898242876 01/05/2005 15:25:40 152 m 0.0 m 0 m 0:00:09 0 kph 0° true +Trackpoint N51 18.777959570 E12 24.896573201 01/05/2005 15:29:18 155 m 0.0 m 4 m 0:03:38 0.1 kph 328° true +Trackpoint N51 18.789627180 E12 24.874907658 01/05/2005 15:30:30 149 m 0.0 m 33 m 0:01:12 2 kph 311° true +Trackpoint N51 18.789627180 E12 24.873243012 01/05/2005 15:30:37 150 m 0.0 m 2 m 0:00:07 1.0 kph 270° true +Trackpoint N51 18.789627180 E12 24.866574369 01/05/2005 15:30:47 151 m 0.0 m 8 m 0:00:10 3 kph 270° true +Trackpoint N51 18.789627180 E12 24.863240048 01/05/2005 15:30:48 151 m 0.0 m 4 m 0:00:01 14 kph 270° true +Trackpoint N51 18.799630143 E12 24.834905863 01/05/2005 15:30:52 150 m 0.0 m 38 m 0:00:04 34 kph 299° true +Trackpoint N51 18.821295686 E12 24.799908064 01/05/2005 15:30:57 150 m 0.0 m 57 m 0:00:05 41 kph 315° true +Trackpoint N51 18.839626908 E12 24.771573879 01/05/2005 15:31:03 150 m 0.0 m 47 m 0:00:06 28 kph 316° true +Trackpoint N51 18.852959163 E12 24.749908336 01/05/2005 15:31:10 150 m 0.0 m 35 m 0:00:07 18 kph 315° true +Trackpoint N51 18.877959028 E12 24.573239610 01/05/2005 15:32:38 143 m 0.0 m 210 m 0:01:28 9 kph 283° true +Trackpoint N51 18.877959028 E12 24.569910318 01/05/2005 15:32:45 141 m 0.0 m 4 m 0:00:07 2 kph 270° true +Trackpoint N51 18.877959028 E12 24.569910318 01/05/2005 15:33:17 143 m 0.0 m 0 m 0:00:32 0 kph 0° true +Trackpoint N51 18.877959028 E12 24.566575997 01/05/2005 15:33:42 139 m 0.0 m 4 m 0:00:25 0.6 kph 270° true +Trackpoint N51 18.877959028 E12 24.561572000 01/05/2005 15:33:54 139 m 0.0 m 6 m 0:00:12 2 kph 270° true +Trackpoint N51 18.877959028 E12 24.561572000 01/05/2005 15:34:04 138 m 0.0 m 0 m 0:00:10 0 kph 0° true +Trackpoint N51 18.877959028 E12 24.561572000 01/05/2005 15:34:20 139 m 0.0 m 0 m 0:00:16 0 kph 0° true +Trackpoint N51 18.877959028 E12 24.561572000 01/05/2005 15:35:45 144 m 0.0 m 0 m 0:01:25 0 kph 0° true +Trackpoint N51 18.877959028 E12 24.561572000 01/05/2005 15:35:56 145 m 0.0 m 0 m 0:00:11 0 kph 0° true diff --git a/reference/gc/GC7FA4.gpx b/reference/gc/GC7FA4.gpx new file mode 100644 index 000000000..b079d390f --- /dev/null +++ b/reference/gc/GC7FA4.gpx @@ -0,0 +1,151 @@ + + + Cache Listing Generated from Geocaching.com + This is an individual cache generated from Geocaching.com + Account "Sverdrup2" From Geocaching.com + contact@geocaching.com + http://www.geocaching.com + Geocaching - High Tech Treasure Hunting + + cache, geocache + + + + GC7FA4 + Points géodésiques du Québec by Sverdrup2, Locationless (Reverse) Cache (1/1) + http://www.geocaching.com/seek/cache_details.aspx?guid=727f9d2c-f080-41f1-a2c9-a326ead462ed + Points géodésiques du Québec + Geocache + Geocache|Locationless (Reverse) Cache + + Points géodésiques du Québec + Sverdrup2 + Sverdrup2 + Locationless (Reverse) Cache + Virtual + 1 + 1 + Canada + Quebec + LES COORDONÉES PUBLIÉES NE REPRÉSENTENT PAS LA LOCALISATION D'UNE CACHE +PUBLISHED COORDINATES DO NOT REPRESENT THE LOCALIZATION OF A CACHE + Le but de cette cache virtuelle est de trouver les points géodésiques du territoire québécois. Les points géodésiques sont faciles à identifier (capuchons de laiton au niveau du sol). Généralement, il y a un panneau de couleur orange sur un poteau à proximité du point. Sur ce panneau, le numéro du point est identifié. Aussi, la distance relative du panneau au point est indiquée. +<P> +Pour inscrire votre découverte, vous devez prendre en note le NUMÉRO DU POINT(inscrit sur le point même ou au centre du panneau)LA COORDONNÉE(en format HDDD MM.MM WGS84 datum ET UTM NAD83 indiquer la zone SVP)et L'ALTITUDE RELATIVE. Si le points n'est pas visible (il se peut qu'il soit sous quelques centimètres de terre) vous pouvez prendre la coordonnée à l'emplacement du panneau SI LA PRÉCISION DE VOTRE GPS EST SUPÉRIEUR À LA DISTANCE INSCRITE SUR LE PANNEAU (ex : Précison du GPS de 5m et distance au point inscrite sur le panneau de 3m). +<P> +Une photo du point ou du panneau et une description générale des lieux serait aussi des informations importantes. +<P> +Enfin, il faudrait aussi prendre en note l'organisme propriétaire du point géodésique. Au Québec il en existe plusieurs: +<P> +Le Service de la géodésie du Québec, Ministère des Ressources naturelles, Québec +<P> +La Division des levés géodésiques, Géomatique Canada, Secteur des sciences de la terre Ressources naturelles Canada +<P> +Le Service hydrographique du Canada, Direction des sciences, Pêches et Océans Canada et la Garde côtière canadienne, Pêches et Océans Canada +<P> +Et tout les anciens noms de ministères et/ou organisme +<P> +Des photos de points de même que des panneaux suivront bientôt. +VOUS NE POUVEZ INSCRIRE QU'UN SEUL POINT GÉODÉSIQUE (UN POINT PAR GÉOCACHEUR) +Bonne chance! + +<P> + +The goal of this virtual cache is to find the geodetic points of Québec’s territory. The geodetic points are easy to identify (Brass cap at ground level) Generally, there is an orange panel of on a post near the point. On this panel, the number of the point is identified. Also, the distance relating from the panel to the point is also indicated. In order to log your find, you must take in note THE NUMBER OF THE POINT(registered on the point or in the center of the panel) and THE COORDINATES(in format HDDD MM.MM WGS84 datum AND UTM NAD83 indicate the zone please)and THE ALTITUDE. If the point is not visible (it may be buried under few centimetres) you can take the coordinate at the panel IF THE ACCURACY OF YOUR GPS IS HIGHER Than the DISTANCE REGISTERED ON the PANEL. (Ex: accuracy of the GPS is 5m and the distance to the point registered on the panel is 3m). + <P> +A picture of the point or panel and a general description of the places would be also significant information. Finally, it would also be important to take in note the organization owner of the geodetic point. +In Quebec there are several: +<P> +The "Service de la géodésie du Québec, Ministère des Ressources naturelles Québec" +The Geodetic Survey Division, Geomatics Canada, Earth Sciences Sector, Natural Resources Canada +The Canadian Hydrographic Service, Sciences Directorate, Fisheries and Oceans Canada and the Canadian Coast Guard, Fisheries and Oceans Canada +And all old names of ministries and/or organization +<P> + +PICTURES of points and of the panels will follow soon. YOU CAN ONLY LOG ONE POINT (ONE POINT PER GEOCACHER) +Good luck! + + + + + 2005-07-12T07:00:00 + Found it + Christopher R & Pooh B + This marker is not in Quebec but it is a Geodesic marker in Clarenville, Newfoundland, Canada! + +Found this one while hunting a traditional cache and thought of this cache right away! + +It is located on Bare Mountain in Clarenville - There are aactually two markers within 15 feet of one another on Bare Mountain... + +Smiles Pooh Bear + +Ce marqueur n'est pas au Québec mais c'est un marqueur géodésique dans Clarenville, Terre-Neuve, Canada! + +A trouvé celui-ci tandis que chasse une cachette traditionnelle et pensé à cette cachette tout de suite! Elle est située sur la montagne nue dans Clarenville - il y a aactually deux marqueurs à moins de 15 pieds d'un des autres sur la montagne nue... Ours De Pooh De Sourires + + + + + + + 2005-06-26T07:00:00 + Found it + TravelBen + [:D] 14h22 + +Marqueur du Service de la Géodégie (c'est bien un "g" pas un "s") du Québec. + +Position Average (100 échantillons): +N 45° 26.872 W 075° 56.410, 21 mètres d'altitude +UTM: 18T E 582877 N 5033250 + +Ce marqueur se trouve dans le ville de Senneville, sur un monument décrivant une page d'histoire du Québec, sur le bas côté avant droit. + +Près de la cache: Exo-07 La Jumelle de Loudiver (GCP3VE) + + + + 2005-06-03T07:00:00 + Found it + etasse + MRN marker 94K4731 in Gatineau, QC. corner of Du Rhone and Gatineau Ave. + +Position Average +N 45° 29.5247 W 075° 43.0049 59.49m +UTM 18T 0443995 5037866 + +Least Squares Average +N 45° 29.5257 W 075° 43.0043 55.74m +UTM 18T 0443996 5037868 + +This pole has everything: An underground cable warning, a geodesic mark, a bus stop and a garage sale sign. + +Judging by the coordinates it looks like the coords should be 45°29'31.5" -75°43'0" I placed the GPS antenna right against the marker, to no avail. + + + + + + 2005-06-03T07:00:00 + Found it + Katou + Un bo point géodésique a Lotbinière..en allant faire une nouvelle cache a l'île richelieu ;-) + + + + + + 2005-05-29T07:00:00 + Found it + Gps_Gulliver&DauphinBleu + Point Geodesique situe near Port de Plaisance de Longueuil +sur le bord du fleuve st-laurent. +Il y a des sentiers et une grande piste cyclable +Enjoy ! + + + + + + + diff --git a/reference/gc/GCGCA8.gpx b/reference/gc/GCGCA8.gpx new file mode 100644 index 000000000..c815350f9 --- /dev/null +++ b/reference/gc/GCGCA8.gpx @@ -0,0 +1,103 @@ + + + Cache Listing Generated from Geocaching.com + This is an individual cache generated from Geocaching.com + Account "robertlipe" From Geocaching.com + contact@geocaching.com + http://www.geocaching.com + Geocaching - High Tech Treasure Hunting + + cache, geocache + + + + GCGCA8 + Oozy rat in a sanitary zoo by robertlipe, Unknown Cache (3/2) + http://www.geocaching.com/seek/cache_details.aspx?guid=cda94cd6-d657-49bd-8e7e-0031ef1b2613 + Oozy rat in a sanitary zoo + Geocache + Geocache|Unknown Cache + + Oozy rat in a sanitary zoo + robertlipe + robertlipe + Unknown Cache + Not chosen + 3 + 2 + United States + Tennessee + The cache is not at the coordinates above. These coords will get you to the correct park and within 1/2 mile of the cache. The cache is within 35 feet of the trail. It is not handicapped accessible. It is a nice walk in the woods that is practical for all ages. There is no space in the container for trading items. You should bring a writing stick and bug spray is recommended. + So if the cache isn't at the above coordinates, where is it? + +<ul> + +<li>Too bad I hid a boot +<li>Too hot to hoot +<li>Never odd or even +<li>Do geese see God? +<li>"Do nine men interpret?" "Nine men," I nod +<li>Rats live on no evil star +<li>Go hang a salami, I'm a lasagna hog +</ul> + +Now that it's intuitively obvious to even the most casual observer where the cache is, turn on your geo-mojo and go find it. +<br> +<img SRC="http://www.mtgc.org/mtgc_member-banner.gif" WIDTH="500" HEIGHT="40" ALT="Member of Middle Tennessee GeoCachers Club [www.mtgc.org]" BORDER="0"></a></p> + + + + + 2005-07-03T07:00:00 + Found it + littlepod + Enjoyed the puzzle. We seemed to be about 50ft off though. TFTC. + + + 2005-04-29T07:00:00 + Write note + robertlipe + TB Drop to show he's hanging out in Nashville until we blast off for Geowoodstock in a few weeks. + + + 2005-04-18T07:00:00 + Found it + Big Bumblebee + Found it a while ago. Thanks. + + + 2005-03-27T08:00:00 + Write note + robertlipe + I had to renew my permit with the CDC and in doing so, I trolled out here verified that the infectious ooze is fully within specification and industry accepted tolerance. Ooze On! + + + 2004-12-27T08:00:00 + Found it + Virtual Babe + This was a great cache, however on this day I considered it a FIFM cache (Fun, Invigorating, Frustrating and Maddening), especially when the cache was not replaced in the proper spot by the previous cacher! Thanks anyway!! + + + + 2004-01-12T08:00:00 + Write note + robertlipe + I got a complaint from the CDC about oozy rat this weekend. I went out tonight in the dark and verified that the infectious ooze is fully within specification and industry accepted tolerance. (Although I realize now I did misstate the cache container to the reporting officer when confronted. It's, uuuuh, smaller than I said.) + + + 2003-10-04T07:00:00 + Write note + robertlipe + In the expectation that this cache will get some traffic in the next 48 hours, Ryan and I checked it earlier today. The Rat is Oozing just as we planned it. + + + 2003-07-03T07:00:00 + Write note + robertlipe + It won't earn him a smiley face, but I've confirmed that rickrich would have indeed sunk the battleship! Thanx for playing. You get a copy of the home game and some rice-a-roni... + + + + + + diff --git a/reference/gc/maggeo.gs b/reference/gc/maggeo.gs new file mode 100644 index 000000000..4ca564939 --- /dev/null +++ b/reference/gc/maggeo.gs @@ -0,0 +1,3 @@ +$PMGNGEO,4608.000,N,7300.000,W,0000,F,GC7FA4,Points geodesiques d,Sverdrup2,,Locationless (Reverse) Cache,1508102,1207105,1.0,1.0*3E +$PMGNGEO,3555.300,N,8651.700,W,0000,F,GCGCA8,Oozy rat in a sanita,robertlipe,,Mystery Cache,2906103,0307105,3.0,2.0*4A +$PMGNCMD,END*3D diff --git a/reference/gdb-sample-v3.gdb b/reference/gdb-sample-v3.gdb new file mode 100644 index 0000000000000000000000000000000000000000..929ad1e50e3c397081020188ecf6d2aa12c8d533 GIT binary patch literal 69073 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%0Av^mU@&-6C7fscGvQL{BW2t!62$ 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 + + + + + 3 + B93 + B93 + Exit + + + + Altenburg-Umgehung + Altenburg-Umgehung + Altenburg-Umgehung + Exit + + + + Elsterberg + Piehlerstrasse + Piehlerstrasse + Exit + + + + Gosel + Gosel + Gosel + Exit + + + + Greiz + August-Bebel-Strasse + August-Bebel-Strasse + Exit + + + + Jahnstrasse + Jahnstrasse 11 + Jahnstrasse 11 + Exit + + + + Liebknechtstrasse + Liebknechtstrasse 90 + Liebknechtstrasse 90 + Exit + + + 391.000000 + + NARVA + Start + Start + http://www.narva-light.de + Flag, Green + + + + Völkerschlachtdenkmal + P+R Am Völkerschlachtdenkmal + P+R Am Völkerschlachtdenkmal + http://www.leipzig.de + Flag, Red + + + NARVA-Leipzig + + 391.000000 + + NARVA + Start + Start + http://www.narva-light.de + Flag, Green + + + + Liebknechtstrasse + Liebknechtstrasse 90 + Liebknechtstrasse 90 + Exit + + + + Jahnstrasse + Jahnstrasse 11 + Jahnstrasse 11 + Exit + + + + Elsterberg + Piehlerstrasse + Piehlerstrasse + Exit + + + + Greiz + August-Bebel-Strasse + August-Bebel-Strasse + Exit + + + + Gosel + Gosel + Gosel + Exit + + + 3 + B93 + B93 + Exit + + + + Altenburg-Umgehung + Altenburg-Umgehung + Altenburg-Umgehung + Exit + + + + Völkerschlachtdenkmal + P+R Am Völkerschlachtdenkmal + P+R Am Völkerschlachtdenkmal + http://www.leipzig.de + Flag, Red + + + + ACTIVE LOG 001 + + + 146.257812 + + + + 145.777100 + + + + 146.738403 + + + + 141.931763 + + + + 141.931763 + + + + 141.451050 + + + + 141.931763 + + + + 142.412476 + + + + 141.931763 + + + + 142.893066 + + + + 142.412476 + + + + 134.241211 + + + + 135.683105 + + + + 136.163940 + + + + 136.644653 + + + + 139.047852 + + + + 142.412476 + + + + + + ACTIVE LOG 002 + + + 136.163940 + + + + 147.699707 + + + + 146.738403 + + + + 154.428955 + + + + 151.064209 + + + + 144.335205 + + + + 142.412476 + + + + 134.241211 + + + + 135.202515 + + + + 135.683105 + + + + 135.202515 + + + + + + ACTIVE LOG 003 + + + 149.622314 + + + + + + ACTIVE LOG 004 + + + 160.677490 + + + + + + ACTIVE LOG 005 + + + 161.158203 + + + + + + ACTIVE LOG 006 + + + 161.158203 + + + + 153.948364 + + + + 148.180420 + + + + 138.567261 + + + + 144.815796 + + + + 133.760498 + + + + 130.876709 + + + + 130.395996 + + + + 131.837891 + + + + 143.854370 + + + + 147.218994 + + + + 145.296387 + + + + 145.296387 + + + + 135.202515 + + + + 134.721924 + + + + 136.163940 + + + + 135.202515 + + + + 138.567261 + + + + 138.567261 + + + + 140.970459 + + + + 139.528442 + + + + 140.489868 + + + + 151.544922 + + + + 152.025757 + + + + 155.390259 + + + + 148.661011 + + + + 149.622314 + + + + 150.583618 + + + + 150.583618 + + + + 149.622314 + + + + 149.622314 + + + + 149.622314 + + + + 149.622314 + + + + 143.373657 + + + + 141.451050 + + + + 143.373657 + + + + 138.567261 + + + + 138.567261 + + + + 138.086548 + + + + 138.567261 + + + + 143.854370 + + + + 144.815796 + + + + + + ACTIVE LOG 007 + + + 150.583618 + + + + 152.025757 + + + + 136.644653 + + + + 133.760498 + + + + 133.760498 + + + + 135.202515 + + + + 131.837891 + + + + 136.644653 + + + + 136.163940 + + + + 134.721924 + + + + 133.760498 + + + + 133.279907 + + + + 131.837891 + + + + 128.954102 + + + + 127.511963 + + + + 126.550659 + + + + 125.589355 + + + + 124.628052 + + + + 123.666748 + + + + 123.186157 + + + + 123.186157 + + + + 120.782837 + + + + 121.263550 + + + + 120.302124 + + + + 118.379395 + + + + 116.937500 + + + + 115.014893 + + + + 114.053589 + + + + 113.092285 + + + + 112.611572 + + + + 112.130981 + + + + 112.611572 + + + + 112.611572 + + + + 113.092285 + + + + 113.572998 + + + + 113.092285 + + + + 112.611572 + + + + 112.611572 + + + + 115.014893 + + + + 115.014893 + + + + 114.053589 + + + + 115.976196 + + + + 115.976196 + + + + 115.976196 + + + + 115.014893 + + + + 114.534180 + + + + 112.130981 + + + + 112.130981 + + + + 109.727661 + + + + 109.727661 + + + + 108.766235 + + + + 110.208252 + + + + 110.208252 + + + + 110.208252 + + + + 111.169556 + + + + 111.650269 + + + + 112.611572 + + + + 112.130981 + + + + 112.130981 + + + + 111.650269 + + + + 110.208252 + + + + 108.766235 + + + + 107.324341 + + + + 106.843628 + + + + 107.324341 + + + + 107.805054 + + + + 107.805054 + + + + 107.324341 + + + + 109.727661 + + + + 110.208252 + + + + 111.169556 + + + + 111.650269 + + + + 113.092285 + + + + 115.014893 + + + + 115.976196 + + + + 114.534180 + + + + 113.092285 + + + + 112.130981 + + + + 112.130981 + + + + 112.611572 + + + + 111.169556 + + + + 109.727661 + + + + 109.246948 + + + + 109.246948 + + + + 110.208252 + + + + 110.208252 + + + + 110.688843 + + + + 111.650269 + + + + 112.130981 + + + + 112.130981 + + + + 112.130981 + + + + 112.611572 + + + + 112.611572 + + + + 113.092285 + + + + 113.092285 + + + + 113.092285 + + + + 113.092285 + + + + 113.092285 + + + + 113.092285 + + + + 113.092285 + + + + 114.053589 + + + + 114.534180 + + + + 115.976196 + + + + 117.418213 + + + + 116.456787 + + + + 116.937500 + + + + 116.937500 + + + + 116.456787 + + + + 116.937500 + + + + 116.937500 + + + + 116.937500 + + + + 117.418213 + + + + 118.379395 + + + + 119.821411 + + + + 120.302124 + + + + 120.302124 + + + + 122.705444 + + + + 122.224731 + + + + 122.224731 + + + + 122.224731 + + + + 122.705444 + + + + 122.705444 + + + + 123.666748 + + + + 124.628052 + + + + 123.186157 + + + + 121.744141 + + + + 121.744141 + + + + 122.705444 + + + + 120.782837 + + + + 121.744141 + + + + 122.705444 + + + + 119.821411 + + + + 122.705444 + + + + 128.473389 + + + + 133.760498 + + + + 138.567261 + + + + 142.893066 + + + + 143.373657 + + + + 142.893066 + + + + 141.451050 + + + + 137.605835 + + + + 136.644653 + + + + 136.644653 + + + + 135.683105 + + + + 135.683105 + + + + 136.644653 + + + + 137.605835 + + + + 138.567261 + + + + 139.528442 + + + + 140.489868 + + + + 141.451050 + + + + 142.412476 + + + + 142.412476 + + + + 142.412476 + + + + 142.412476 + + + + 142.412476 + + + + 143.373657 + + + + 144.335205 + + + + 145.296387 + + + + 145.777100 + + + + 145.777100 + + + + 146.257812 + + + + 146.257812 + + + + 147.218994 + + + + 148.661011 + + + + 149.622314 + + + + 151.544922 + + + + 153.467651 + + + + 154.909546 + + + + 155.870972 + + + + 156.832153 + + + + 158.274170 + + + + 159.716187 + + + + 159.235474 + + + + 158.754761 + + + + 158.274170 + + + + 156.351562 + + + + 156.351562 + + + + 154.909546 + + + + 154.428955 + + + + 153.948364 + + + + 152.986938 + + + + 152.025757 + + + + 151.544922 + + + + 152.025757 + + + + 151.064209 + + + + 149.622314 + + + + 147.218994 + + + + 144.815796 + + + + 143.854370 + + + + 143.373657 + + + + 143.373657 + + + + 143.373657 + + + + 142.412476 + + + + 141.451050 + + + + 139.047852 + + + + 135.202515 + + + + 133.279907 + + + + 133.760498 + + + + 134.241211 + + + + 137.125244 + + + + 140.489868 + + + + 142.893066 + + + + 144.815796 + + + + 146.738403 + + + + 148.180420 + + + + 149.141602 + + + + 150.583618 + + + + 151.064209 + + + + 151.064209 + + + + 151.064209 + + + + 150.103027 + + + + 149.622314 + + + + 150.103027 + + + + 150.583618 + + + + 151.064209 + + + + 151.544922 + + + + 152.025757 + + + + 152.986938 + + + + 154.428955 + + + + 154.428955 + + + + 154.428955 + + + + 154.909546 + + + + 147.699707 + + + + 141.931763 + + + + 139.047852 + + + + 137.125244 + + + + 132.799316 + + + + 130.876709 + + + + 129.915283 + + + + 129.915283 + + + + 129.915283 + + + + 129.915283 + + + + 131.357300 + + + + 132.318604 + + + + 132.799316 + + + + 133.760498 + + + + 134.721924 + + + + 135.683105 + + + + 135.202515 + + + + 135.202515 + + + + 132.318604 + + + + 133.760498 + + + + 135.683105 + + + + 137.125244 + + + + 139.528442 + + + + 140.009155 + + + + 140.970459 + + + + 140.970459 + + + + 141.931763 + + + + 142.412476 + + + + 142.412476 + + + + 142.893066 + + + + 143.373657 + + + + 143.373657 + + + + 143.373657 + + + + 143.854370 + + + + 144.815796 + + + + 147.699707 + + + + 146.738403 + + + + 146.257812 + + + + 145.777100 + + + + 145.296387 + + + + 146.738403 + + + + 147.699707 + + + + 148.661011 + + + + 150.103027 + + + + 152.506348 + + + + 154.909546 + + + + 156.832153 + + + + 157.312866 + + + + 157.793579 + + + + 157.793579 + + + + 158.274170 + + + + 158.274170 + + + + 159.235474 + + + + 162.119507 + + + + 164.042114 + + + + 165.003418 + + + + 165.003418 + + + + 164.042114 + + + + 163.080811 + + + + 162.119507 + + + + 162.600098 + + + + 163.561523 + + + + 162.600098 + + + + 161.638916 + + + + 160.196899 + + + + 156.832153 + + + + 152.506348 + + + + 155.390259 + + + + 156.351562 + + + + 155.870972 + + + + 152.025757 + + + + 149.622314 + + + + 147.699707 + + + + 146.738403 + + + + 146.738403 + + + + 146.257812 + + + + 145.777100 + + + + 144.815796 + + + + 144.335205 + + + + 144.335205 + + + + 144.335205 + + + + 144.335205 + + + + 143.854370 + + + + 144.335205 + + + + 144.335205 + + + + 144.335205 + + + + 144.815796 + + + + 145.296387 + + + + 145.777100 + + + + 146.257812 + + + + 146.738403 + + + + 146.738403 + + + + 146.257812 + + + + 146.738403 + + + + 146.738403 + + + + 146.257812 + + + + 145.777100 + + + + 147.218994 + + + + 147.218994 + + + + 147.218994 + + + + 147.218994 + + + + 147.218994 + + + + 148.180420 + + + + 147.699707 + + + + 148.180420 + + + + 149.622314 + + + + 150.103027 + + + + 150.103027 + + + + 149.622314 + + + + 148.180420 + + + + 148.180420 + + + + 148.661011 + + + + 149.141602 + + + + 149.141602 + + + + 149.141602 + + + + 148.180420 + + + + 149.622314 + + + + 152.986938 + + + + 154.909546 + + + + 156.351562 + + + + 158.274170 + + + + 161.638916 + + + + 164.522705 + + + + 164.042114 + + + + 161.638916 + + + + 159.716187 + + + + 158.754761 + + + + 160.196899 + + + + 161.158203 + + + + 161.638916 + + + + 162.119507 + + + + 162.600098 + + + + 164.042114 + + + + 165.003418 + + + + 165.964722 + + + + 166.926025 + + + + 166.926025 + + + + 165.484131 + + + + 166.926025 + + + + 168.368042 + + + + 170.771362 + + + + 172.213257 + + + + 173.655273 + + + + 176.058594 + + + + 180.384521 + + + + 186.152466 + + + + 189.516968 + + + + 192.401123 + + + + 194.323730 + + + + 194.804321 + + + + 193.843018 + + + + 190.478394 + + + + 187.113770 + + + + 186.633179 + + + + 185.671753 + + + + 184.710571 + + + + 182.787842 + + + + 181.826416 + + + + 179.903809 + + + + 177.500610 + + + + 174.616577 + + + + 172.693970 + + + + 171.732666 + + + + 172.213257 + + + + 174.135864 + + + + 177.020020 + + + + 183.749023 + + + + 189.516968 + + + + 193.843018 + + + + 197.688232 + + + + 200.091675 + + + + 200.572266 + + + + 199.130127 + + + + 197.207520 + + + + 195.284912 + + + + 193.362305 + + + + 191.439575 + + + + 191.439575 + + + + 193.362305 + + + + 197.207520 + + + + 202.014282 + + + + 207.301392 + + + + 214.030640 + + + + 217.395386 + + + + 219.798584 + + + + 222.201782 + + + + 224.124512 + + + + 222.682495 + + + + 221.721191 + + + + 220.759888 + + + + 220.279175 + + + + 220.759888 + + + + 222.201782 + + + + 224.605225 + + + + 226.527832 + + + + 227.008545 + + + + 227.008545 + + + + 226.527832 + + + + 226.527832 + + + + 226.047119 + + + + 225.566528 + + + + 226.047119 + + + + 227.008545 + + + + 227.489136 + + + + 227.969727 + + + + 226.047119 + + + + 222.682495 + + + + 221.240601 + + + + 218.356567 + + + + 216.914673 + + + + 215.472656 + + + + 217.875977 + + + + 220.759888 + + + + 224.605225 + + + + 226.527832 + + + + 229.892334 + + + + 232.295776 + + + + 231.814941 + + + + 231.334351 + + + + 228.931152 + + + + 224.605225 + + + + 220.759888 + + + + 216.914673 + + + + 213.069336 + + + + 206.820679 + + + + 202.494873 + + + + 199.130127 + + + + 196.246338 + + + + 194.323730 + + + + 193.843018 + + + + 193.843018 + + + + 193.362305 + + + + 191.920288 + + + + 189.516968 + + + + 187.113770 + + + + 184.710571 + + + + 182.307129 + + + + 182.307129 + + + + 182.307129 + + + + 182.787842 + + + + 182.787842 + + + + 182.307129 + + + + 182.307129 + + + + 182.787842 + + + + 183.268433 + + + + 184.229858 + + + + 183.749023 + + + + 183.749023 + + + + 183.749023 + + + + 183.749023 + + + + 183.268433 + + + + 183.268433 + + + + 183.268433 + + + + 183.268433 + + + + 183.268433 + + + + 183.749023 + + + + 183.268433 + + + + 183.749023 + + + + 183.749023 + + + + 184.229858 + + + + 184.229858 + + + + 183.749023 + + + + 183.749023 + + + + 184.710571 + + + + 185.191162 + + + + 185.191162 + + + + 185.671753 + + + + 185.191162 + + + + 185.191162 + + + + 185.671753 + + + + 185.671753 + + + + 186.633179 + + + + 186.633179 + + + + 187.113770 + + + + 187.113770 + + + + 188.075073 + + + + 189.516968 + + + + 188.075073 + + + + 188.555786 + + + + 188.555786 + + + + 189.516968 + + + + 189.516968 + + + + 189.997681 + + + + 189.997681 + + + + 189.516968 + + + + 189.997681 + + + + 191.439575 + + + + 192.881714 + + + + 194.323730 + + + + 195.765625 + + + + 195.284912 + + + + 194.804321 + + + + 193.362305 + + + + 192.881714 + + + + 192.881714 + + + + 193.362305 + + + + 192.881714 + + + + 190.958984 + + + + 189.516968 + + + + 189.516968 + + + + 188.555786 + + + + 188.555786 + + + + 188.555786 + + + + 188.555786 + + + + 189.516968 + + + + 190.958984 + + + + 189.516968 + + + + 189.036377 + + + + 188.555786 + + + + 188.555786 + + + + 188.075073 + + + + 188.075073 + + + + 188.555786 + + + + 189.516968 + + + + 189.997681 + + + + 190.478394 + + + + 189.516968 + + + + 189.997681 + + + + 190.478394 + + + + 191.920288 + + + + 191.920288 + + + + 191.920288 + + + + 191.439575 + + + + 191.439575 + + + + 191.439575 + + + + 190.958984 + + + + 191.439575 + + + + 191.439575 + + + + 191.920288 + + + + 192.401123 + + + + 192.401123 + + + + 192.401123 + + + + 191.920288 + + + + 191.439575 + + + + 191.920288 + + + + 193.362305 + + + + 195.284912 + + + + 197.688232 + + + + 198.168945 + + + + 199.130127 + + + + 199.610840 + + + + 199.130127 + + + + 197.688232 + + + + 197.207520 + + + + 197.688232 + + + + 198.168945 + + + + 198.649536 + + + + 198.168945 + + + + 198.168945 + + + + 198.168945 + + + + 197.207520 + + + + 197.207520 + + + + 197.207520 + + + + 197.207520 + + + + 198.168945 + + + + 197.688232 + + + + 197.688232 + + + + 199.130127 + + + + 200.091675 + + + + 201.052856 + + + + 201.052856 + + + + 201.533569 + + + + 200.091675 + + + + 201.052856 + + + + 200.091675 + + + + 199.610840 + + + + 196.726929 + + + + 196.246338 + + + + 195.284912 + + + + 194.804321 + + + + 194.804321 + + + + 195.284912 + + + + 197.688232 + + + + 198.168945 + + + + 197.688232 + + + + 197.688232 + + + + 198.168945 + + + + 198.649536 + + + + 198.649536 + + + + 199.130127 + + + + 199.610840 + + + + 200.091675 + + + + 201.052856 + + + + 201.052856 + + + + 202.494873 + + + + 204.417480 + + + + 206.340088 + + + + 207.782104 + + + + 210.666016 + + + + 213.069336 + + + + 214.511230 + + + + 214.030640 + + + + 213.550049 + + + + 214.511230 + + + + 215.953247 + + + + 217.395386 + + + + 220.759888 + + + + 221.240601 + + + + 221.240601 + + + + 221.240601 + + + + 220.279175 + + + + 219.317993 + + + + 217.875977 + + + + 217.875977 + + + + 218.356567 + + + + 218.356567 + + + + 217.395386 + + + + 218.356567 + + + + 222.682495 + + + + 227.008545 + + + + 231.334351 + + + + 238.544312 + + + + 234.699097 + + + + 231.334351 + + + + 229.892334 + + + + 228.931152 + + + + 228.450439 + + + + 227.969727 + + + + 226.047119 + + + + 222.201782 + + + + 221.240601 + + + + 215.953247 + + + + 214.030640 + + + + 212.108032 + + + + 212.588623 + + + + 211.627441 + + + + 207.782104 + + + + 206.340088 + + + + 204.417480 + + + + 204.417480 + + + + 204.417480 + + + + 204.898071 + + + + 205.859497 + + + + 206.340088 + + + + 207.301392 + + + + 207.782104 + + + + 206.820679 + + + + 206.340088 + + + + 205.378784 + + + + 205.859497 + + + + 207.782104 + + + + + + ACTIVE LOG 008 + + + 203.936890 + + + + 203.936890 + + + + 209.224121 + + + + 221.721191 + + + + + + ACTIVE LOG 009 + + + 218.837280 + + + + 198.649536 + + + + 217.395386 + + + + 209.704834 + + + + 208.262817 + + + + 208.262817 + + + + + diff --git a/reference/gdb-sample2.gdb b/reference/gdb-sample2.gdb new file mode 100644 index 0000000000000000000000000000000000000000..670d0c59ac821a62b1d5c313838b9b6be08b665a GIT binary patch literal 6314 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 B8D#(f literal 0 HcmV?d00001 diff --git a/reference/geocaching.gpx b/reference/geocaching.gpx new file mode 100644 index 000000000..aa06057c4 --- /dev/null +++ b/reference/geocaching.gpx @@ -0,0 +1,73 @@ + + + + + + GCEBB + Mountain Bike Heaven by susy1313 + http://www.geocaching.com/seek/cache_details.asp?ID=3771 + Cache Details + geocache + + + GC1A37 + The Troll by a182pilot & Family + http://www.geocaching.com/seek/cache_details.asp?ID=6711 + Cache Details + geocache + + + GC1C2B + Dive Bomber by JoGPS & family + http://www.geocaching.com/seek/cache_details.asp?ID=7211 + Cache Details + geocache + + + GC25A9 + FOSTER by JoGPS & Family + http://www.geocaching.com/seek/cache_details.asp?ID=9641 + Cache Details + geocache + + + GC2723 + Logan Lighthouse by JoGps & Family + http://www.geocaching.com/seek/cache_details.asp?ID=10019 + Cache Details + geocache + + + GC2B71 + Ganier Cache by Susy1313 + http://www.geocaching.com/seek/cache_details.asp?ID=11121 + Cache Details + geocache + + + GC309F + Shy's Hill by FireFighterEng33 + http://www.geocaching.com/seek/cache_details.asp?ID=12447 + Cache Details + geocache + + + GC317A + GittyUp by JoGPS / Warner Parks + http://www.geocaching.com/seek/cache_details.asp?ID=12666 + Cache Details + geocache + + + GC317D + Inlighting by JoGPS / Warner Parks + http://www.geocaching.com/seek/cache_details.asp?ID=12669 + Cache Details + geocache + + diff --git a/reference/geonet-sample.gpx b/reference/geonet-sample.gpx new file mode 100644 index 000000000..69914c9d0 --- /dev/null +++ b/reference/geonet-sample.gpx @@ -0,0 +1,55 @@ + + + + + + PLAUEN + Plauen + Plauen + + + PLAUEN + Plauen + Plauen + + + PLAUEN STADTKREIS + Stadtkreis Plauen + Stadtkreis Plauen + + + PLAUENERSTADTWALD + Plauener Stadtwald + Plauener Stadtwald + + + ZSCHOPAU + Zschopau + Zschopau + + + ZSCHOPAU + Zschopau + Zschopau + + + ZSCHOPEL + Zschöpel + Zschöpel + + + ZSCHOPENBERG + Zschopen-Berg + Zschopen-Berg + + + ZSCHOPENTHAL + Zschopenthal + Zschopenthal + + diff --git a/reference/geonet-sample.txt b/reference/geonet-sample.txt new file mode 100644 index 000000000..d6c89798e --- /dev/null +++ b/reference/geonet-sample.txt @@ -0,0 +1,10 @@ +RC UFI UNI LAT LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE +1 -1843626 -2549662 51.0166667 13.7166667 510100 134300 VS05 NM33-01 P PPLX GM 13 N PLAUEN Plauen Plauen 1994-01-08 +1 -1843625 -2549661 50.5 12.1333333 503000 120800 TR99 NM33-04 P PPL 3 GM 13 N PLAUEN Plauen Plauen 2002-05-02 +1 -1843628 -2549664 50.5 12.1333333 503000 120800 TR99 NM33-04 A ADM3 GM 13 Chemnitz V PLAUEN STADTKREIS Stadtkreis Plauen Stadtkreis Plauen 1998-04-28 +1 -1843629 -2549666 50.5333333 12.1333333 503200 120800 TS90 NM33-04 V FRST GM 13 N PLAUENERSTADTWALD Plauener Stadtwald Plauener Stadtwald 1998-05-12 +1 -1893314 -2603706 51.1333333 13.05 510800 130300 US66 NM33-01 H STM GM 13 N ZSCHOPAU Zschopau Zschopau 1994-01-08 +1 -1893313 -2603705 50.75 13.0666667 504500 130400 US62 NM33-04 P PPL 4 GM 13 N ZSCHOPAU Zschopau Zschopau 2002-05-02 +1 -1893316 -2603708 50.8666667 12.4166667 505200 122500 US13 NM33-04 P PPL GM 15 N ZSCHOPEL Zschöpel Zschopel 1998-05-15 +1 -1893317 -2603709 50.7333333 13.0666667 504400 130400 US62 NM33-04 T HLL GM 13 N ZSCHOPENBERG Zschopen-Berg Zschopen-Berg 1994-01-08 +1 -1893318 -2603710 50.7666667 13.1 504600 130600 US62 NM33-04 P PPL GM 13 N ZSCHOPENTHAL Zschopenthal Zschopenthal 1994-01-08 diff --git a/reference/geoniche.pdb b/reference/geoniche.pdb new file mode 100644 index 0000000000000000000000000000000000000000..0c8ba057677bb0d243b03a2e2c5c1e431a9d9726 GIT binary patch literal 1422 zcma)+&2rN)6op+VzfYkRY=kYzwq&s^O;VUP1QKA2QdC=0SI*c@XZ$woc?Fg%c?e#D z4J)paI0-+ktx0@rDRa-4qbryCLYLZ}>mb#IHRqZ37oX!`a18+ zdPB0P{JW|%czO1^_@l5}2SZEO*k(NY~xNjymRo?ou zC=z&@HBT#aV%DuXG^HN8d~`XmDV&n_*Z@T$TnMgF6Cwqy^~&S+`a2fRIUbq1Zr&|+ z4HBRasATAheS1+J$ G5AQdfnrKJ> literal 0 HcmV?d00001 diff --git a/reference/gl.loc b/reference/gl.loc new file mode 100644 index 000000000..192d169f2 --- /dev/null +++ b/reference/gl.loc @@ -0,0 +1,56 @@ + + + + +geocache +http://www.geocaching.com/seek/cache_details.asp?ID=3771 + + + + +geocache +http://www.geocaching.com/seek/cache_details.asp?ID=6711 + + + + +geocache +http://www.geocaching.com/seek/cache_details.asp?ID=7211 + + + + +geocache +http://www.geocaching.com/seek/cache_details.asp?ID=9641 + + + + +geocache +http://www.geocaching.com/seek/cache_details.asp?ID=10019 + + + + +geocache +http://www.geocaching.com/seek/cache_details.asp?ID=11121 + + + + +geocache +http://www.geocaching.com/seek/cache_details.asp?ID=12447 + + + + +geocache +http://www.geocaching.com/seek/cache_details.asp?ID=12666 + + + + +geocache +http://www.geocaching.com/seek/cache_details.asp?ID=12669 + + diff --git a/reference/gn-targets.gpx b/reference/gn-targets.gpx new file mode 100644 index 000000000..74c506329 --- /dev/null +++ b/reference/gn-targets.gpx @@ -0,0 +1,34 @@ + + + + + + 44.000000 + + 5066 + 5066 + 5066 + Scenic Area + + + 57.000000 + + 5067 + 5067 + 5067 + Traditional Cache + + + 44.000000 + + 5096 + 5096 + 5096 + Residence + + diff --git a/reference/gn-targets.pdb b/reference/gn-targets.pdb new file mode 100644 index 0000000000000000000000000000000000000000..188a5bd044db438346d263ae09e1f3fff539bf93 GIT binary patch literal 586 zcmZ=y&G*Yp&PY`VNi0fFEh%O|2OJEH`;WOK?LSucA0oxN9!O_^*e;GCj_yGH2Nen+ zQp^ktjCD>26{LamAs{Woz`(@jcu+wWC|w_#mzJ56ngUS?B;6B>6@p6=OEUBGz+%pc zKxe>Z85lhCN>Yo8QMi16da3E6QOFtGE>V7@-y>Fp#1Q}N@OmQNrQyR$i&RT z%Er#Y$;HjX%g4_Ta+W@Ggoy{E0;~Ol93W4JaXo_!11p0VkmP2+$N&saFkob0WG?`U zUw2?+`2W9yAuK@>D9)&7YG7stG9!HT7mykDH9%2Ipc&>2Qb5&A3~WF%*dRtQV45KX slwtA#nqdxhhbj-y4435Google Maps - 233 S. Wacker, Chicago, IL to 1060 W. Addison, Chicago, IL \ No newline at end of file diff --git a/reference/google.xml b/reference/google.xml new file mode 100644 index 000000000..33ff7f308 --- /dev/null +++ b/reference/google.xml @@ -0,0 +1 @@ +233 S. Wacker, Chicago, IL to 1060 W. Addison, Chicago, IL233 S. Wacker, Chicago, IL to 1060 W. Addison, Chicago, IL
    233 S Upper Wacker DrChicago, IL 60606
    1060 W Addison StChicago, IL 60613
    mnr~F`p{uOy@@Y?]@}EH}B@gCD??W?eBBwA@a@A{BDeCBuBDY?m@?_AG??QGWWcD_G?S?eB?eD?aH??e@A[?kC???uGJaD?{CDcDDkA@sABcD@}CBaD@_DBkEBgGBcGH}FHcGHaGBwCBwJNgKHaHFoKF??gHFo@A??SKOQMa@??cCnAqE~BuCxAcExBoJxE??}A`A{FbDgJnEeJrEuFxCuBdAsFtCe@VaAf@_Bp@sCxAYLkDfBWVe@l@Yn@oC|A_CfAaB|@w@`@cAXeAF??uDfCgDlCs@l@mClBQLaDdCyGbF}@p@??wDpCqDvCmJxGcCfB}EzDyCxB??[ReFrD_EbD_C|A??AkDB?????BB??????@??BB?@@???BB??BB?????@?????@?????@??BB?BB?@BB????@??@?@????@???@?@@@??@@A?@?????????@?@@?????BBBHead north from S Upper Wacker DrContinue on N Upper Wacker DrBear right at W Upper Wacker DrTurn left at N La Salle StContinue on N La Salle BlvdContinue on N La Salle DrBear right at W Eugenie StTurn left at N Clark StTurn right at W Addison St
    \ No newline at end of file diff --git a/reference/google_jan_06.csv b/reference/google_jan_06.csv new file mode 100644 index 000000000..e0141a6f9 --- /dev/null +++ b/reference/google_jan_06.csv @@ -0,0 +1,111 @@ +41.87895, -87.63665, S Upper Wacker Dr +41.87924, -87.63666, \00001 +41.87937, -87.63666, \00002 +41.87952, -87.63667, \00003 +41.88063, -87.63672, \00004 +41.88126, -87.63673, \00005 +41.88194, -87.63676, \00006 +41.88194, -87.63676, N Upper Wacker Dr +41.88206, -87.63676, \00008 +41.88257, -87.63678, \00009 +41.88301, -87.63679, \0000a +41.88318, -87.63678, \0000b +41.88380, -87.63681, \0000c +41.88447, -87.63683, \0000d +41.88506, -87.63686, \0000e +41.88519, -87.63686, \0000f +41.88542, -87.63686, \00010 +41.88574, -87.63682, \00011 +41.88574, -87.63682, W Upper Wacker Dr +41.88583, -87.63678, \00013 +41.88595, -87.63666, \00014 +41.88677, -87.63538, \00015 +41.88677, -87.63528, \00016 +41.88677, -87.63477, \00017 +41.88677, -87.63394, \00018 +41.88677, -87.63249, \00019 +41.88677, -87.63249, N La Salle St +41.88696, -87.63248, \0001b +41.88710, -87.63248, \0001c +41.88780, -87.63248, \0001d +41.88780, -87.63248, N La Salle Blvd +41.88919, -87.63254, \0001f +41.89000, -87.63254, \00020 +41.89078, -87.63257, \00021 +41.89160, -87.63260, \00022 +41.89198, -87.63261, \00023 +41.89240, -87.63263, \00024 +41.89322, -87.63264, \00025 +41.89401, -87.63266, \00026 +41.89482, -87.63267, \00027 +41.89562, -87.63269, \00028 +41.89664, -87.63271, \00029 +41.89796, -87.63273, \0002a +41.89926, -87.63278, \0002b +41.90053, -87.63283, \0002c +41.90183, -87.63288, \0002d +41.90312, -87.63290, \0002e +41.90388, -87.63292, \0002f +41.90576, -87.63300, \00030 +41.90772, -87.63305, \00031 +41.90917, -87.63309, \00032 +41.91117, -87.63313, \00033 +41.91117, -87.63313, N La Salle Dr +41.91265, -87.63317, \00035 +41.91289, -87.63316, \00036 +41.91289, -87.63316, W Eugenie St +41.91299, -87.63310, \00038 +41.91307, -87.63301, \00039 +41.91314, -87.63284, \0003a +41.91314, -87.63284, N Clark St +41.91380, -87.63324, \0003c +41.91485, -87.63388, \0003d +41.91560, -87.63433, \0003e +41.91658, -87.63494, \0003f +41.91842, -87.63603, \00040 +41.91842, -87.63603, \00041 +41.91889, -87.63636, \00042 +41.92015, -87.63718, \00043 +41.92195, -87.63822, \00044 +41.92374, -87.63928, \00045 +41.92497, -87.64005, \00046 +41.92556, -87.64040, \00047 +41.92678, -87.64115, \00048 +41.92697, -87.64127, \00049 +41.92730, -87.64147, \0004a +41.92778, -87.64172, \0004b +41.92852, -87.64217, \0004c +41.92865, -87.64224, \0004d +41.92951, -87.64276, \0004e +41.92963, -87.64288, \0004f +41.92982, -87.64311, \00050 +41.92995, -87.64335, \00051 +41.93067, -87.64382, \00052 +41.93131, -87.64418, \00053 +41.93180, -87.64449, \00054 +41.93208, -87.64466, \00055 +41.93242, -87.64479, \00056 +41.93277, -87.64483, \00057 +41.93277, -87.64483, \00058 +41.93368, -87.64551, \00059 +41.93452, -87.64622, \0005a +41.93478, -87.64645, \0005b +41.93549, -87.64700, \0005c +41.93558, -87.64707, \0005d +41.93639, -87.64774, \0005e +41.93780, -87.64888, \0005f +41.93811, -87.64913, \00060 +41.93811, -87.64913, \00061 +41.93903, -87.64986, \00062 +41.93992, -87.65062, \00063 +41.94175, -87.65203, \00064 +41.94241, -87.65255, \00065 +41.94352, -87.65349, \00066 +41.94429, -87.65410, \00067 +41.94429, -87.65410, \00068 +41.94443, -87.65420, \00069 +41.94558, -87.65510, \0006a +41.94654, -87.65592, \0006b +41.94718, -87.65639, \0006c +41.94718, -87.65639, W Addison St +41.94718, -87.65632, \0006e diff --git a/reference/google_jan_06.html b/reference/google_jan_06.html new file mode 100644 index 000000000..cff6176d9 --- /dev/null +++ b/reference/google_jan_06.html @@ -0,0 +1,2 @@ +Google Local \ No newline at end of file diff --git a/reference/googmap.sh b/reference/googmap.sh new file mode 100644 index 000000000..83a73d32c --- /dev/null +++ b/reference/googmap.sh @@ -0,0 +1,5 @@ + +FROM="233 S. Wacker, Chicago, IL" +TO="1060 W. Addison, Chicago, IL" +wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=xml" 2>/dev/null + diff --git a/reference/googmapjs.sh b/reference/googmapjs.sh new file mode 100644 index 000000000..486c4f560 --- /dev/null +++ b/reference/googmapjs.sh @@ -0,0 +1,5 @@ + +FROM="233 S. Upper Wacker Dr, Chicago, IL" +TO="1060 W. Addison St, Chicago, IL" +wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" 2>/dev/null + diff --git a/reference/gpi_ext-sample.csv b/reference/gpi_ext-sample.csv new file mode 100644 index 000000000..170bf4b0f --- /dev/null +++ b/reference/gpi_ext-sample.csv @@ -0,0 +1,10 @@ +No,Latitude,Longitude,Name,Description,Symbol,Address,City,PostalCode,State,Country,Phone +1,50.877341,12.433889,"3","! constructed waypoint !","Waypoint","Hauptstrasse -1",,,,,"03741-999999" +2,50.964955,12.435919,"Altenburg-Umgehung","! constructed waypoint !","Waypoint",,"Plauen",,,,"03741-999999" +3,50.610795,12.173802,"Elsterberg","! constructed waypoint !","Waypoint",,,,"Sachsen",,"03741-999999" +4,50.844126,12.408757,"Gosel","! constructed waypoint !","Waypoint",,,,,"Deutschland","03741-999999" +5,50.654763,12.204957,"Greiz","! constructed waypoint !","Waypoint",,,"08523",,,"03741-999999" +6,51.314521,12.409143,"HMMMM","No comment","Waypoint","Hauptstrasse -2","Plauen","08523","Sachsen","Deutschland","03741-999999" +7,50.493663,12.107153,"Jahnstrasse","! constructed waypoint !","Waypoint",,,"08523",,"Deutschland","03741-999999" +8,50.493837,12.106101,"Liebknechtstrasse","! constructed waypoint !","Waypoint",,,"08523",,"Deutschland","03741-999999" +9,50.492619,12.105449,"NARVA","Start","Waypoint",,,"08523",,"Deutschland","03741-999999" diff --git a/reference/gpi_ext-sample.gpi b/reference/gpi_ext-sample.gpi new file mode 100644 index 0000000000000000000000000000000000000000..62d6fa8aa2c53cce84cdeb684c4b55210c6ceb99 GIT binary patch literal 1507 zcmc(f%WD%+6vodaO`RltS8WBgQxb7wWSS^83&Eg6>my@G(UqG?ddUn;CSe{(6hRk0 zc5d8gb??TVEB^{np}KC-?xZ^rO8m}{Xd;D_xbVU^4ELUU&hMUk&Ltu`3@sJ&MeU-h zKA8TY5DinUdAicDB&>`;h3l8`Rn@H_qA1DqDnfxqF{|lO$~Top-LgGb#^QY}&R{`$ zbT9d7b3=aq^;_coyLA~;B#{(?$z%K;gm%8ClG%qFGU8wpTuGEc2ns>1a137sItpp} zEX^zBy6t+7U-rbRa@%MIF_rl^JRX4!@0y_LzR+HhT=q!vbCG|@Jaa40o% z?#x0e8w^HzinSBa=;rx=8c3WMO`oD%)f0BfcPgnHwTdu(yD}K#pYVJ#O&_L0)$oPg z5A6x8k3lVKH*xjUYtGhK;2=g?)%Ao^63&1~lkmf78=`pN@c^wDWz+4?#5Xt#g||*7 zcXvK8Q#9}pp{2Sjs)J?d5L_@$h{gkFak?aY&n=r(!(Q!|rn}g}NMmb}EJv8DbuXF3fBvvay%U-wAoeFuDJ@qk2!FzJL3vyqW7I<9D>v SJ}aK#1O@P~$!fLW72_A<{RwOU literal 0 HcmV?d00001 diff --git a/reference/gpilots.pdb b/reference/gpilots.pdb new file mode 100644 index 0000000000000000000000000000000000000000..a0bdef97405b6891b233a162020bee5095295883 GIT binary patch literal 2744 zcmYewNzBkINJ(PA1vnTOcU#}m17UO};RPkd?g5!OaB)r`YX*eJxC2NtGB7aR0Mbkh z49q`(G&2JOs|1i{VPIgh0Me`s4D1m=nvH>hqXI~?Gca(@0MZ;_B|ruPgS)eMk~FA@0f$dWMyf(cQGQMiC{Pj&EsP2>bMi|R)D+wjb2D=)i3=LA zs$mj7&PGmiU(b;I?U@b^AD7IsR0XH}+@#bZPzZVDy9WdVLnn>Y&|zR09^qqT>S)P3 zdx7Lh$s}<2xcLW%xCS8y4ao@yn#P7n_?R0R?_gagxlSbz96mnz>4|v?KAGtmB^mjp z#i`JcDkvs7iw%?TaWXfQbXh8S#Ki*~KJJNmnZT^&oR|zOh=3U^nB;O9RzwYt@G&;9 zbh|WprKHJG7jXClXH=>eD|lo=3TU^?qEt6fT1qW)%}X~Xq4pXs<&UwUxudt>5=r0F zrjYcLSyECNT7W2k^cBJri}HX;Dj=~ayBL-@h@gi_`Y|+jiCMEkQqS8896p|TIiU2C NnU_v!5Dn$<0RTDCxT637 literal 0 HcmV?d00001 diff --git a/reference/gpsdrive.txt b/reference/gpsdrive.txt new file mode 100644 index 000000000..901eb1c84 --- /dev/null +++ b/reference/gpsdrive.txt @@ -0,0 +1,9 @@ +GCEBB 35.97203 -87.13470 geocache +GC1A37 36.09068 -86.67955 geocache +GC1C2B 35.99627 -86.62012 geocache +GC25A9 36.03848 -86.64862 geocache +GC2723 36.11218 -86.74177 geocache +GC2B71 36.06408 -86.79052 geocache +GC309F 36.08777 -86.80973 geocache +GC317A 36.05750 -86.89200 geocache +GC317D 36.08280 -86.86728 geocache diff --git a/reference/gpspilot.pdb b/reference/gpspilot.pdb new file mode 100644 index 0000000000000000000000000000000000000000..b4c04f0ae539c339cd038eabca110a10b86a733e GIT binary patch literal 609 zcmaKoze~eF6vyMw)5*>GTogpqBuFa=+O$oov?#VBNI|c9O%CHFBxxa=i(5yL4({%{ zwD@aq6918y#^&c3J8iijb}_j37u-uJz;{m>V#7tQ(y73HsML{ZwE<|978fBT-0 zmY)~h{ZUvo`@cS)K>P3p#ia(X0nlC0LC`bMA7RIWs>WY=l8U`@cMu*&;EFn{JI4uR9>!OjVN$qn=I!R4- zB-|JfHKiwj5zptOy>*OCM$|bqyrT*akXrMsjUo`$E|JzS#aZr<>x&sA%=Ka^yZO`H zEw3%47Qwtf@k;KmPSKqAY$j=5*iPhlwUB>fe)zL1Eurav?L}pBJNB7jF)5&-G~0)f zpsiwWYRyQfVBW1#a#v1bM$w6 + + + + + 5066 + 5066 + 5066 + Crossing + + + 5067 + 5067 + 5067 + Dot + + + 5096 + 5096 + 5096 + Dot + + + 5142 + 5142 + 5142 + Dot + + + 5156 + 5156 + 5156 + Dot + + + 5224 + 5224 + 5224 + Dot + + + 5229 + 5229 + 5229 + Dot + + + 5237 + 5237 + 5237 + Dot + + + 5254 + 5254 + 5254 + Dot + + + 5258 + 5258 + 5258 + Dot + + + 5264 + 5264 + 5264 + Dot + + + 526708 + 526708 + 526708 + Dot + + + 526750 + 526750 + 526750 + Dot + + + 527614 + 527614 + 527614 + Dot + + + 527631 + 527631 + 527631 + Dot + + + 5278 + 5278 + 5278 + Dot + + + 5289 + 5289 + 5289 + Dot + + + 5374FIRE + 5374FIRE + 5374FIRE + Dot + + + 5376 + 5376 + 5376 + Dot + + + 6006 + 6006 + 6006 + Dot + + + 6006BLUE + 6006BLUE + 6006BLUE + Dot + + + 6014MEADOW + 6014MEADOW + 6014MEADOW + Dot + + + 6029 + 6029 + 6029 + Dot + + + 6053 + 6053 + 6053 + Dot + + + 6066 + 6066 + 6066 + Dot + + + 6067 + 6067 + 6067 + Dot + + + 6071 + 6071 + 6071 + Dot + + + 6073 + 6073 + 6073 + Dot + + + 6084 + 6084 + 6084 + Dot + + + 6130 + 6130 + 6130 + Dot + + + 6131 + 6131 + 6131 + Dot + + + 6153 + 6153 + 6153 + Dot + + + 6171 + 6171 + 6171 + Dot + + + 6176 + 6176 + 6176 + Dot + + + 6177 + 6177 + 6177 + Dot + + + 6272 + 6272 + 6272 + Dot + + + 6272 + 6272 + 6272 + Dot + + + 6278 + 6278 + 6278 + Dot + + + 6280 + 6280 + 6280 + Dot + + + 6283 + 6283 + 6283 + Dot + + + 6289 + 6289 + 6289 + Dot + + + 6297 + 6297 + 6297 + Dot + + + 6328 + 6328 + 6328 + Dot + + + 6354 + 6354 + 6354 + Dot + + + 635722 + 635722 + 635722 + Dot + + + 635783 + 635783 + 635783 + Dot + + + 6373 + 6373 + 6373 + Dot + + + 6634 + 6634 + 6634 + Dot + + + 6979 + 6979 + 6979 + Dot + + + 6997 + 6997 + 6997 + Dot + + + BEAR HILL + BEAR HILL + BEAR HILL + Tall Tower + + + BELLEVUE + BELLEVUE + BELLEVUE + Parking Area + + + 6016 + 6016 + 6016 + Waypoint + + + 5236BRIDGE + 5236BRIDGE + 5236BRIDGE + Bridge + + + 5376BRIDGE + 5376BRIDGE + 5376BRIDGE + Bridge + + + 6181CROSS + 6181CROSS + 6181CROSS + Crossing + + + 6042CROSS + 6042CROSS + 6042CROSS + Crossing + + + DARKHOLLPO + DARKHOLLPO + DARKHOLLPO + Fishing Area + + + 6121DEAD + 6121DEAD + 6121DEAD + Danger Area + + + 5179DEAD + 5179DEAD + 5179DEAD + Danger Area + + + 5299DEAD + 5299DEAD + 5299DEAD + Danger Area + + + 5376DEAD + 5376DEAD + 5376DEAD + Danger Area + + + 6353DEAD + 6353DEAD + 6353DEAD + Danger Area + + + 6155DEAD + 6155DEAD + 6155DEAD + Danger Area + + + GATE14 + GATE14 + GATE14 + Truck Stop + + + GATE16 + GATE16 + GATE16 + Truck Stop + + + GATE17 + GATE17 + GATE17 + Truck Stop + + + GATE19 + GATE19 + GATE19 + Truck Stop + + + GATE21 + GATE21 + GATE21 + Truck Stop + + + GATE24 + GATE24 + GATE24 + Truck Stop + + + GATE5 + GATE5 + GATE5 + Truck Stop + + + GATE6 + GATE6 + GATE6 + Waypoint + + + 6077LOGS + 6077LOGS + 6077LOGS + Amusement Park + + + 5148NANEPA + 5148NANEPA + 5148NANEPA + Waypoint + + + 5267OBSTAC + 5267OBSTAC + 5267OBSTAC + Amusement Park + + + PANTHRCAVE + PANTHRCAVE + PANTHRCAVE + Tunnel + + + 5252PURPLE + 5252PURPLE + 5252PURPLE + Summit + + + 5287WATER + 5287WATER + 5287WATER + Swimming Area + + + 5239ROAD + 5239ROAD + 5239ROAD + Truck Stop + + + 5278ROAD + 5278ROAD + 5278ROAD + Truck Stop + + + 5058ROAD + 5058ROAD + 5058ROAD + Dot + + + SHEEPFOLD + SHEEPFOLD + SHEEPFOLD + Parking Area + + + SOAPBOX + SOAPBOX + SOAPBOX + Cemetery + + + 5376STREAM + 5376STREAM + 5376STREAM + Bridge + + + 5144SUMMIT + 5144SUMMIT + 5144SUMMIT + Summit + + + 5150TANK + 5150TANK + 5150TANK + Museum + + + + + 1.000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2.000000 + + + + + + + 1.000000 + + + + + + + + + + + + + + + + 2.000000 + + + + 1.000000 + + + + 1.000000 + + + + + + + 2.000000 + + + + + + + + + + + + + + + + + + + 6.000000 + + + + 2.000000 + + + + + + + + + + + + + + + + 1.000000 + + + + + + + + + + 6.000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 7.000000 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/hiketech.ref b/reference/hiketech.ref new file mode 100644 index 000000000..7082a81ff --- /dev/null +++ b/reference/hiketech.ref @@ -0,0 +1,1530 @@ + + + + + 2002-05-25 05:06:21 + 30.062183 + -91.610350 + 1.000000 + + + 2002-05-25 05:09:55 + 30.062783 + -91.610567 + + + 2002-05-25 05:12:00 + 30.062700 + -91.608267 + + + 2002-05-25 05:12:48 + 30.062333 + -91.607383 + + + 2002-05-25 05:14:41 + 30.061533 + -91.605283 + + + 2002-05-25 05:17:16 + 30.059783 + -91.599400 + + + 2002-05-25 05:17:46 + 30.057800 + -91.596683 + + + 2002-05-25 05:18:20 + 30.055383 + -91.594900 + + + 2002-05-25 05:19:01 + 30.053883 + -91.592617 + + + 2002-05-25 05:20:46 + 30.049733 + -91.589750 + + + 2002-05-25 05:21:10 + 30.049017 + -91.589883 + + + 2002-05-25 05:21:51 + 30.048800 + -91.592933 + + + 2002-05-25 05:22:35 + 30.046233 + -91.596450 + + + 2002-05-25 05:23:08 + 30.045517 + -91.598717 + + + 2002-05-25 06:04:23 + 30.047300 + -91.600267 + + + 2002-05-25 06:06:04 + 30.047000 + -91.599633 + 2.000000 + + + 2002-05-25 06:07:06 + 30.046433 + -91.599467 + + + 2002-05-25 06:08:18 + 30.046200 + -91.598950 + 1.000000 + + + 2002-05-25 06:10:20 + 30.046367 + -91.597733 + + + 2002-05-25 06:11:09 + 30.046350 + -91.597167 + + + 2002-05-25 06:12:18 + 30.046783 + -91.596333 + + + 2002-05-25 06:14:22 + 30.047450 + -91.595200 + + + 2002-05-25 06:15:04 + 30.047800 + -91.594767 + 2.000000 + + + 2002-05-25 06:16:14 + 30.048250 + -91.594083 + 1.000000 + + + 2002-05-25 06:17:01 + 30.048683 + -91.593800 + 1.000000 + + + 2002-05-25 06:18:07 + 30.049350 + -91.593850 + + + 2002-05-25 06:19:51 + 30.050317 + -91.593983 + 2.000000 + + + 2002-05-25 06:20:39 + 30.050783 + -91.594117 + + + 2002-05-25 06:21:24 + 30.051233 + -91.594367 + + + 2002-05-25 06:22:17 + 30.051800 + -91.594367 + + + 2002-05-25 06:23:18 + 30.052217 + -91.594667 + + + 2002-05-25 06:24:37 + 30.053017 + -91.594683 + + + 2002-05-25 06:28:13 + 30.054867 + -91.595200 + 6.000000 + + + 2002-05-25 06:31:36 + 30.053733 + -91.594933 + 2.000000 + + + 2002-05-25 06:32:56 + 30.053183 + -91.594783 + + + 2002-05-25 06:34:02 + 30.052633 + -91.594833 + + + 2002-05-25 06:36:03 + 30.052450 + -91.595433 + + + 2002-05-25 06:36:48 + 30.052483 + -91.595967 + + + 2002-05-25 06:37:52 + 30.052650 + -91.596783 + 1.000000 + + + 2002-05-25 06:39:18 + 30.053133 + -91.597850 + + + 2002-05-25 06:40:15 + 30.053617 + -91.597967 + + + 2002-05-25 06:41:25 + 30.053967 + -91.597767 + 6.000000 + + + 2002-05-25 06:42:37 + 30.053617 + -91.598083 + + + 2002-05-25 06:44:01 + 30.053200 + -91.597917 + + + 2002-05-25 06:45:53 + 30.052817 + -91.597517 + + + 2002-05-25 06:46:54 + 30.052567 + -91.596933 + + + 2002-05-25 06:47:42 + 30.052333 + -91.596433 + + + 2002-05-25 06:48:41 + 30.052250 + -91.595683 + + + 2002-05-25 06:49:52 + 30.052217 + -91.595017 + + + 2002-05-25 06:50:49 + 30.051883 + -91.594700 + + + 2002-05-25 06:52:14 + 30.051050 + -91.594400 + + + 2002-05-25 06:52:56 + 30.050567 + -91.594233 + + + 2002-05-25 06:53:38 + 30.050183 + -91.594100 + + + 2002-05-25 06:55:11 + 30.049100 + -91.593717 + + + 2002-05-25 06:56:32 + 30.048450 + -91.594250 + + + 2002-05-25 06:57:24 + 30.048083 + -91.594750 + + + 2002-05-25 06:58:40 + 30.047500 + -91.595450 + 7.000000 + + + 2002-05-25 06:59:28 + 30.047067 + -91.596000 + + + 2002-05-25 07:00:22 + 30.046633 + -91.596600 + + + 2002-05-25 07:01:41 + 30.046400 + -91.597650 + + + 2002-05-25 07:02:48 + 30.046233 + -91.598467 + + + 2002-05-25 07:03:43 + 30.046317 + -91.598967 + + + 2002-05-25 07:04:49 + 30.046783 + -91.599283 + + + 2002-05-25 07:05:57 + 30.047133 + -91.599667 + + + + 2002-05-25 05:06:21 + 30.062183 + -91.610350 + 1.000000 + + + 2002-05-25 05:09:55 + 30.062783 + -91.610567 + + + 2002-05-25 05:12:00 + 30.062700 + -91.608267 + + + 2002-05-25 05:12:48 + 30.062333 + -91.607383 + + + 2002-05-25 05:14:41 + 30.061533 + -91.605283 + + + 2002-05-25 05:17:16 + 30.059783 + -91.599400 + + + 2002-05-25 05:17:46 + 30.057800 + -91.596683 + + + 2002-05-25 05:18:20 + 30.055383 + -91.594900 + + + 2002-05-25 05:19:01 + 30.053883 + -91.592617 + + + 2002-05-25 05:20:46 + 30.049733 + -91.589750 + + + 2002-05-25 05:21:10 + 30.049017 + -91.589883 + + + 2002-05-25 05:21:51 + 30.048800 + -91.592933 + + + 2002-05-25 05:22:35 + 30.046233 + -91.596450 + + + 2002-05-25 05:23:08 + 30.045517 + -91.598717 + + + 2002-05-25 06:04:23 + 30.047300 + -91.600267 + + + 2002-05-25 06:06:04 + 30.047000 + -91.599633 + 2.000000 + + + 2002-05-25 06:07:06 + 30.046433 + -91.599467 + + + 2002-05-25 06:08:18 + 30.046200 + -91.598950 + 1.000000 + + + 2002-05-25 06:10:20 + 30.046367 + -91.597733 + + + 2002-05-25 06:11:09 + 30.046350 + -91.597167 + + + 2002-05-25 06:12:18 + 30.046783 + -91.596333 + + + 2002-05-25 06:14:22 + 30.047450 + -91.595200 + + + 2002-05-25 06:15:04 + 30.047800 + -91.594767 + 2.000000 + + + 2002-05-25 06:16:14 + 30.048250 + -91.594083 + 1.000000 + + + 2002-05-25 06:17:01 + 30.048683 + -91.593800 + 1.000000 + + + 2002-05-25 06:18:07 + 30.049350 + -91.593850 + + + 2002-05-25 06:19:51 + 30.050317 + -91.593983 + 2.000000 + + + 2002-05-25 06:20:39 + 30.050783 + -91.594117 + + + 2002-05-25 06:21:24 + 30.051233 + -91.594367 + + + 2002-05-25 06:22:17 + 30.051800 + -91.594367 + + + 2002-05-25 06:23:18 + 30.052217 + -91.594667 + + + 2002-05-25 06:24:37 + 30.053017 + -91.594683 + + + 2002-05-25 06:28:13 + 30.054867 + -91.595200 + 6.000000 + + + 2002-05-25 06:31:36 + 30.053733 + -91.594933 + 2.000000 + + + 2002-05-25 06:32:56 + 30.053183 + -91.594783 + + + 2002-05-25 06:34:02 + 30.052633 + -91.594833 + + + 2002-05-25 06:36:03 + 30.052450 + -91.595433 + + + 2002-05-25 06:36:48 + 30.052483 + -91.595967 + + + 2002-05-25 06:37:52 + 30.052650 + -91.596783 + 1.000000 + + + 2002-05-25 06:39:18 + 30.053133 + -91.597850 + + + 2002-05-25 06:40:15 + 30.053617 + -91.597967 + + + 2002-05-25 06:41:25 + 30.053967 + -91.597767 + 6.000000 + + + 2002-05-25 06:42:37 + 30.053617 + -91.598083 + + + 2002-05-25 06:44:01 + 30.053200 + -91.597917 + + + 2002-05-25 06:45:53 + 30.052817 + -91.597517 + + + 2002-05-25 06:46:54 + 30.052567 + -91.596933 + + + 2002-05-25 06:47:42 + 30.052333 + -91.596433 + + + 2002-05-25 06:48:41 + 30.052250 + -91.595683 + + + 2002-05-25 06:49:52 + 30.052217 + -91.595017 + + + 2002-05-25 06:50:49 + 30.051883 + -91.594700 + + + 2002-05-25 06:52:14 + 30.051050 + -91.594400 + + + 2002-05-25 06:52:56 + 30.050567 + -91.594233 + + + 2002-05-25 06:53:38 + 30.050183 + -91.594100 + + + 2002-05-25 06:55:11 + 30.049100 + -91.593717 + + + 2002-05-25 06:56:32 + 30.048450 + -91.594250 + + + 2002-05-25 06:57:24 + 30.048083 + -91.594750 + + + 2002-05-25 06:58:40 + 30.047500 + -91.595450 + 7.000000 + + + 2002-05-25 06:59:28 + 30.047067 + -91.596000 + + + 2002-05-25 07:00:22 + 30.046633 + -91.596600 + + + 2002-05-25 07:01:41 + 30.046400 + -91.597650 + + + 2002-05-25 07:02:48 + 30.046233 + -91.598467 + + + 2002-05-25 07:03:43 + 30.046317 + -91.598967 + + + 2002-05-25 07:04:49 + 30.046783 + -91.599283 + + + 2002-05-25 07:05:57 + 30.047133 + -91.599667 + + + 5066 + Crossing + 42.438878 + -71.119277 + + FAFFB4 + FF8000 + + + + 5067 + Dot + 42.439227 + -71.119689 + + FAFFB4 + FF8000 + + + + 5096 + Dot + 42.438917 + -71.116146 + + FAFFB4 + FF8000 + + + + 5142 + Dot + 42.443904 + -71.122044 + + FAFFB4 + FF8000 + + + + 5156 + Dot + 42.447298 + -71.121447 + + FAFFB4 + FF8000 + + + + 5224 + Dot + 42.454873 + -71.125094 + + FAFFB4 + FF8000 + + + + 5229 + Dot + 42.459079 + -71.124988 + + FAFFB4 + FF8000 + + + + 5237 + Dot + 42.456979 + -71.124474 + + FAFFB4 + FF8000 + + + + 5254 + Dot + 42.454401 + -71.120990 + + FAFFB4 + FF8000 + + + + 5258 + Dot + 42.451442 + -71.121746 + + FAFFB4 + FF8000 + + + + 5264 + Dot + 42.454404 + -71.120660 + + FAFFB4 + FF8000 + + + + 526708 + Dot + 42.457761 + -71.121045 + + FAFFB4 + FF8000 + + + + 526750 + Dot + 42.457089 + -71.120313 + + FAFFB4 + FF8000 + + + + 527614 + Dot + 42.456592 + -71.119676 + + FAFFB4 + FF8000 + + + + 527631 + Dot + 42.456252 + -71.119356 + + FAFFB4 + FF8000 + + + + 5278 + Dot + 42.458148 + -71.119135 + + FAFFB4 + FF8000 + + + + 5289 + Dot + 42.459377 + -71.117693 + + FAFFB4 + FF8000 + + + + 5374FIRE + Dot + 42.464183 + -71.119828 + + FAFFB4 + FF8000 + + + + 5376 + Dot + 42.465650 + -71.119399 + + FAFFB4 + FF8000 + + + + 6006 + Dot + 42.439018 + -71.114456 + + FAFFB4 + FF8000 + + + + 6006BLUE + Dot + 42.438594 + -71.114803 + + FAFFB4 + FF8000 + + + + 6014MEADOW + Dot + 42.436757 + -71.113223 + + FAFFB4 + FF8000 + + + + 6029 + Dot + 42.441754 + -71.113220 + + FAFFB4 + FF8000 + + + + 6053 + Dot + 42.436243 + -71.109075 + + FAFFB4 + FF8000 + + + + 6066 + Dot + 42.439250 + -71.107500 + + FAFFB4 + FF8000 + + + + 6067 + Dot + 42.439764 + -71.107582 + + FAFFB4 + FF8000 + + + + 6071 + Dot + 42.434766 + -71.105874 + + FAFFB4 + FF8000 + + + + 6073 + Dot + 42.433304 + -71.106599 + + FAFFB4 + FF8000 + + + + 6084 + Dot + 42.437338 + -71.104772 + + FAFFB4 + FF8000 + + + + 6130 + Dot + 42.442196 + -71.110975 + + FAFFB4 + FF8000 + + + + 6131 + Dot + 42.442981 + -71.111441 + + FAFFB4 + FF8000 + + + + 6153 + Dot + 42.444773 + -71.108882 + + FAFFB4 + FF8000 + + + + 6171 + Dot + 42.443592 + -71.106301 + + FAFFB4 + FF8000 + + + + 6176 + Dot + 42.447804 + -71.106624 + + FAFFB4 + FF8000 + + + + 6177 + Dot + 42.448448 + -71.106158 + + FAFFB4 + FF8000 + + + + 6272 + Dot + 42.453415 + -71.106783 + + FAFFB4 + FF8000 + + + + 6272 + Dot + 42.453434 + -71.107253 + + FAFFB4 + FF8000 + + + + 6278 + Dot + 42.458298 + -71.106771 + + FAFFB4 + FF8000 + + + + 6280 + Dot + 42.451430 + -71.105413 + + FAFFB4 + FF8000 + + + + 6283 + Dot + 42.453845 + -71.105206 + + FAFFB4 + FF8000 + + + + 6289 + Dot + 42.459986 + -71.106170 + + FAFFB4 + FF8000 + + + + 6297 + Dot + 42.457616 + -71.105116 + + FAFFB4 + FF8000 + + + + 6328 + Dot + 42.467110 + -71.113574 + + FAFFB4 + FF8000 + + + + 6354 + Dot + 42.464202 + -71.109863 + + FAFFB4 + FF8000 + + + + 635722 + Dot + 42.466459 + -71.110067 + + FAFFB4 + FF8000 + + + + 635783 + Dot + 42.466557 + -71.109410 + + FAFFB4 + FF8000 + + + + 6373 + Dot + 42.463495 + -71.107117 + + FAFFB4 + FF8000 + + + + 6634 + Dot + 42.401051 + -71.110241 + + FAFFB4 + FF8000 + + + + 6979 + Dot + 42.432621 + -71.106532 + + FAFFB4 + FF8000 + + + + 6997 + Dot + 42.431033 + -71.107883 + + FAFFB4 + FF8000 + + + + BEAR HILL + Tall Tower + 42.465687 + -71.107360 + + FAFFB4 + FF8000 + + + + BELLEVUE + Parking Area + 42.430950 + -71.107628 + + FAFFB4 + FF8000 + + + + 6016 + Waypoint + 42.438666 + -71.114079 + + FAFFB4 + FF8000 + + + + 5236BRIDGE + Bridge + 42.456469 + -71.124651 + + FAFFB4 + FF8000 + + + + 5376BRIDGE + Bridge + 42.465759 + -71.119815 + + FAFFB4 + FF8000 + + + + 6181CROSS + Crossing + 42.442993 + -71.105878 + + FAFFB4 + FF8000 + + + + 6042CROSS + Crossing + 42.435472 + -71.109664 + + FAFFB4 + FF8000 + + + + DARKHOLLPO + Fishing Area + 42.458516 + -71.103646 + + FAFFB4 + FF8000 + + + + 6121DEAD + Danger Area + 42.443109 + -71.112675 + + FAFFB4 + FF8000 + + + + 5179DEAD + Danger Area + 42.449866 + -71.119298 + + FAFFB4 + FF8000 + + + + 5299DEAD + Danger Area + 42.459629 + -71.116524 + + FAFFB4 + FF8000 + + + + 5376DEAD + Danger Area + 42.465485 + -71.119148 + + FAFFB4 + FF8000 + + + + 6353DEAD + Danger Area + 42.462776 + -71.109986 + + FAFFB4 + FF8000 + + + + 6155DEAD + Danger Area + 42.446793 + -71.108784 + + FAFFB4 + FF8000 + + + + GATE14 + Truck Stop + 42.451204 + -71.126602 + + FAFFB4 + FF8000 + + + + GATE16 + Truck Stop + 42.458499 + -71.122078 + + FAFFB4 + FF8000 + + + + GATE17 + Truck Stop + 42.459376 + -71.119238 + + FAFFB4 + FF8000 + + + + GATE19 + Truck Stop + 42.466353 + -71.119240 + + FAFFB4 + FF8000 + + + + GATE21 + Truck Stop + 42.468655 + -71.107697 + + FAFFB4 + FF8000 + + + + GATE24 + Truck Stop + 42.456718 + -71.102973 + + FAFFB4 + FF8000 + + + + GATE5 + Truck Stop + 42.430847 + -71.107690 + + FAFFB4 + FF8000 + + + + GATE6 + Waypoint + 42.431240 + -71.109236 + + FAFFB4 + FF8000 + + + + 6077LOGS + Amusement Park + 42.439502 + -71.106556 + + FAFFB4 + FF8000 + + + + 5148NANEPA + Waypoint + 42.449765 + -71.122320 + + FAFFB4 + FF8000 + + + + 5267OBSTAC + Amusement Park + 42.457388 + -71.119845 + + FAFFB4 + FF8000 + + + + PANTHRCAVE + Tunnel + 42.434980 + -71.109942 + + FAFFB4 + FF8000 + + + + 5252PURPLE + Summit + 42.453256 + -71.121211 + + FAFFB4 + FF8000 + + + + 5287WATER + Swimming Area + 42.457734 + -71.117481 + + FAFFB4 + FF8000 + + + + 5239ROAD + Truck Stop + 42.459278 + -71.124574 + + FAFFB4 + FF8000 + + + + 5278ROAD + Truck Stop + 42.458782 + -71.118991 + + FAFFB4 + FF8000 + + + + 5058ROAD + Dot + 42.439993 + -71.120925 + + FAFFB4 + FF8000 + + + + SHEEPFOLD + Parking Area + 42.453415 + -71.106782 + + FAFFB4 + FF8000 + + + + SOAPBOX + Cemetery + 42.455956 + -71.107483 + + FAFFB4 + FF8000 + + + + 5376STREAM + Bridge + 42.465913 + -71.119328 + + FAFFB4 + FF8000 + + + + 5144SUMMIT + Summit + 42.445359 + -71.122845 + + FAFFB4 + FF8000 + + + + 5150TANK + Museum + 42.441727 + -71.121676 + + FAFFB4 + FF8000 + + + + diff --git a/reference/holux.gpx b/reference/holux.gpx new file mode 100644 index 000000000..46d27e76a --- /dev/null +++ b/reference/holux.gpx @@ -0,0 +1,46 @@ + + + +ACHNR1Waypoint +ACHNR2Waypoint +ACHNRSWaypoint +HWYB26HWY B265 (NE)HWY B265 (NE)Waypoint +HWYB59Waypoint +L100Waypoint +L1001Waypoint +LXMBR1Waypoint +LXMBR2Waypoint +LXMBRGWaypoint +MLTR10Waypoint +MLTRN1Waypoint +MLTRN2Waypoint +MLTRN3Waypoint +MLTRN4Waypoint +MLTRN5Waypoint +MLTRN6Waypoint +MLTRN7Waypoint +MLTRN8Waypoint +MLTRN9Waypoint +MLTRNGMILITARRINGSTRASSEMILITARRINGSTRASSEWaypoint +ROADWaypoint +UNVRS1Waypoint +UNVRS2Waypoint +UNVRSTWaypoint + +MLTRNG to HWYB26 +MLTRNGMILITARRINGSTRASSEMILITARRINGSTRASSEWaypoint +HWYB59Waypoint +MLTRN1Waypoint +MLTRN2Waypoint +MLTRN3Waypoint +MLTRN4Waypoint +MLTRN5Waypoint +MLTRN6Waypoint +MLTRN7Waypoint +MLTRN8Waypoint + + + diff --git a/reference/holux.wpo b/reference/holux.wpo new file mode 100644 index 0000000000000000000000000000000000000000..13f85ba971208bc8e31da430da2338c1e4c73d6d GIT binary patch literal 25512 zcmeI)yKWOf7{&3k9w*^qAY1~3$|YqSFqjSpqQsKDNNaP6#4FHKL_#Te6`p{K8VC(k zAZRF%5Fi>b1-An8?N&SM8AOAWi2q1dZ0l%r_BWrK6w|ubxw)uCNr`H5s%u8Gn$sTb z)jsW4LkDzFhcvIlI-;XGrUf0>37yo0g#ZG(O~8KXtp7`(duct*T2iyLzHK|bufLs? zB@+8kWS9MH=ZVwDSa#@VUq|*`zrL}ud`_~zO?%UBo=#W4K6AP_H{Bu6wlDbmP98aJ zX*%0)EiL8GP3LQGvTZ;c-aq;4*eU0m8w~+Z;`E-{V}`dcNklT)qumGKgwG6 zbmeDzZoZ!aXOU;q${EMZifpCtFY~<{@GY`u{0<1+x#{H`(912Wy8uD&)V#~jAbile9E#vV%d@Jux%Y~1+sZp76J$$fB*srAb6EBzSQ&o z!?O@T009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** s5I_I{1Q7Vw0-rbTyvpwi|J!SiLwzQ8>nwNCgk<;*0R#|000Cd%H$je|f&c&j literal 0 HcmV?d00001 diff --git a/reference/hsandv.exp b/reference/hsandv.exp new file mode 100644 index 000000000..0f3b43070 --- /dev/null +++ b/reference/hsandv.exp @@ -0,0 +1,80 @@ + + + + 1.0000000 + ROUTENAME + 0 + + waypnt + + + 1 + 35.972033 + -87.134700 + + + waypnt + + + 1 + 36.090683 + -86.679550 + + + waypnt + + + 1 + 35.996267 + -86.620117 + + + waypnt + + + 1 + 36.038483 + -86.648617 + + + waypnt + + + 1 + 36.112183 + -86.741767 + + + waypnt + + + 1 + 36.064083 + -86.790517 + + + waypnt + + + 1 + 36.087767 + -86.809733 + + + waypnt + + + 1 + 36.057500 + -86.892000 + + + waypnt + + + 1 + 36.082800 + -86.867283 + + + diff --git a/reference/human.in b/reference/human.in new file mode 100644 index 000000000..1d6653764 --- /dev/null +++ b/reference/human.in @@ -0,0 +1,7 @@ +W 5 10 15 20 25 30 N +1°23'45.678"S 1°23'45.678"E +12d 34.567m N 76d 54.321m E +N 12.345 W 67.890 +12.345N 67.890W +12.345N W67.890 + diff --git a/reference/humanread.out b/reference/humanread.out new file mode 100644 index 000000000..50093bff1 --- /dev/null +++ b/reference/humanread.out @@ -0,0 +1,6 @@ +20.42500 -5.17083 +-1.39602 01.39602 +12.57612 76.90535 +12.34500 -67.89000 +12.34500 -67.89000 +12.34500 -67.89000 diff --git a/reference/humanread.style b/reference/humanread.style new file mode 100644 index 000000000..28b50c54e --- /dev/null +++ b/reference/humanread.style @@ -0,0 +1,20 @@ +# gpsbabel XCSV style file +# +# Format: Human readable read test style +# Author: Ron Parker +# Date: 21 July 2004 +# + +DESCRIPTION Human readable read test style +EXTENSION txt + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER TAB +RECORD_DELIMITER NEWLINE + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LATLON_HUMAN_READABLE, "", "" diff --git a/reference/humanwrite.out b/reference/humanwrite.out new file mode 100644 index 000000000..8d47faba0 --- /dev/null +++ b/reference/humanwrite.out @@ -0,0 +1,6 @@ +N 20.425000 W 5.170833 N 020° 25.500' W 005° 10.250' 20.425000 N 5.170833 W N 20.425000 W 5.170833 N 20 25 30.000000 W 5 10 15.000000 N 20 25 30 W 5 10 15 N 20 W 5 20 degrees 5 degrees +S 1.396022 E 1.396022 S 001° 23.761' E 001° 23.761' 1.396022 S 1.396022 E S 1.396022 E 1.396022 S 1 23 45.678000 E 1 23 45.678000 S 1 23 45 E 1 23 45 S 1 E 1 1 degrees 1 degrees +N 12.576117 E 76.905350 N 012° 34.567' E 076° 54.321' 12.576117 N 76.905350 E N 12.576117 E 76.905350 N 12 34 34.020000 E 76 54 19.260000 N 12 34 34 E 76 54 19 N 12 E 76 12 degrees 76 degrees +N 12.345000 W 67.890000 N 012° 20.700' W 067° 53.400' 12.345000 N 67.890000 W N 12.345000 W 67.890000 N 12 20 42.000000 W 67 53 24.000000 N 12 20 42 W 67 53 24 N 12 W 67 12 degrees 67 degrees +N 12.345000 W 67.890000 N 012° 20.700' W 067° 53.400' 12.345000 N 67.890000 W N 12.345000 W 67.890000 N 12 20 42.000000 W 67 53 24.000000 N 12 20 42 W 67 53 24 N 12 W 67 12 degrees 67 degrees +N 12.345000 W 67.890000 N 012° 20.700' W 067° 53.400' 12.345000 N 67.890000 W N 12.345000 W 67.890000 N 12 20 42.000000 W 67 53 24.000000 N 12 20 42 W 67 53 24 N 12 W 67 12 degrees 67 degrees diff --git a/reference/humanwrite.style b/reference/humanwrite.style new file mode 100644 index 000000000..04bf783ef --- /dev/null +++ b/reference/humanwrite.style @@ -0,0 +1,28 @@ +# gpsbabel XCSV style file +# +# Format: Human readable write test style +# Author: Ron Parker +# Date: 21 July 2004 +# + +DESCRIPTION Human readable write test style +EXTENSION txt + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER TAB +RECORD_DELIMITER NEWLINE + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LATLON_HUMAN_READABLE, "", "%c %f" +IFIELD LATLON_HUMAN_READABLE, "", "%c %.3d° %6.3f'" +IFIELD LATLON_HUMAN_READABLE, "", "%f %c" +IFIELD LATLON_HUMAN_READABLE, "", "%c %f" +IFIELD LATLON_HUMAN_READABLE, "", "%c %d %d %f" +IFIELD LATLON_HUMAN_READABLE, "", "%c %d %d %d" +IFIELD LATLON_HUMAN_READABLE, "", "%c %d" +IFIELD LATLON_HUMAN_READABLE, "", "%d degrees" + diff --git a/reference/igc1.gpx b/reference/igc1.gpx new file mode 100644 index 000000000..cbb3c88d7 --- /dev/null +++ b/reference/igc1.gpx @@ -0,0 +1,549 @@ + + + + + + PALLMG + PALLMG + PALLMG + dot + + + PILOT + CHRIS JONES + CHRIS JONES + dot + + + PLUMTH + PLUMTHORPE LOC + PLUMTHORPE LOC + dot + + + AB1 + + 0.000000 + BORAH + + + 0.000000 + BALDWI + + + 0.000000 + MANAIR + + + + + +0.000000 + + + +0.000000 + + + + + + #2 +1 + + +0.000000 + + + +0.000000 + + + + + + #3 +2 + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + + + + #4 +3 + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + + + diff --git a/reference/igc1_3d.out b/reference/igc1_3d.out new file mode 100644 index 000000000..2ecdeb4e2 --- /dev/null +++ b/reference/igc1_3d.out @@ -0,0 +1,123 @@ +AXXXZZZGPSBabel +HFDTE240404 +HFPLTPILOT:CHRIS JONES +C010170000000000000000101 +C3040552S15036542EBORAH +C3040552S15036542EBORAH +C3043796S15038952EBALDWI +C3045821S15043392EMANAIR +C3045821S15043392EMANAIR +B0400193040579S15036384EA0090000000 +B0400493040614S15036317EA0093400000 +B0401193040699S15036326EA0097000000 +B0401503040629S15036431EA0099400000 +B0402203040628S15036565EA0100000000 +B0402513040689S15036431EA0098000000 +B0403223040555S15036270EA0095500000 +B0403523040720S15036356EA0091800000 +B0404233040884S15036452EA0090300000 +B0404543040658S15036419EA0088900000 +B0405243040811S15036507EA0087100000 +B0405553040688S15036378EA0084200000 +B0406263040714S15036409EA0087100000 +B0406573040686S15036391EA0089700000 +B0407283040728S15036419EA0090300000 +B0407583040656S15036366EA0090000000 +B0408293040785S15036447EA0092000000 +B0409003040822S15036433EA0097100000 +B0409313040795S15036535EA0102000000 +B0410013040809S15036573EA0100900000 +B0410323040819S15036444EA0095500000 +B0411023040785S15036304EA0095200000 +B0411323040816S15036327EA0096400000 +B0412033040846S15036397EA0097500000 +B0412343040813S15036503EA0099100000 +B0413043040760S15036508EA0096800000 +B0413353040694S15036319EA0092600000 +B0414063040538S15036152EA0091100000 +B0414373040695S15036308EA0089200000 +B0415073040758S15036421EA0091300000 +B0415383040766S15036490EA0094000000 +B0416083040753S15036493EA0094900000 +B0416393040739S15036494EA0098200000 +B0417103040750S15036527EA0096900000 +B0417413040819S15036393EA0094100000 +B0418113040806S15036352EA0091300000 +B0418413040569S15036344EA0089900000 +B0419123040526S15036253EA0090600000 +B0419433040646S15036334EA0090300000 +B0420133040794S15036367EA0089500000 +B0420443040707S15036367EA0090300000 +B0421143040679S15036423EA0092200000 +B0421443040658S15036414EA0091400000 +B0422153040772S15036358EA0091900000 +B0422453040722S15036423EA0096100000 +B0423153040717S15036457EA0098800000 +B0423453040700S15036444EA0101900000 +B0424163040689S15036457EA0104100000 +B0424473040753S15036486EA0101900000 +B0425183040750S15036329EA0099200000 +B0425483040794S15036240EA0101900000 +B0426193040688S15036353EA0108000000 +B0426493040679S15036400EA0111700000 +B0427203040754S15036332EA0113300000 +B0427513040693S15036316EA0113200000 +B0428213040918S15036288EA0108900000 +B0428513041173S15036316EA0105800000 +B0429223041467S15036406EA0100600000 +B0429523041752S15036547EA0093900000 +B0430233042022S15036681EA0089600000 +B0430543042288S15036906EA0085800000 +B0431243042359S15037048EA0087200000 +B0431553042430S15037151EA0091200000 +B0432263042348S15037228EA0094700000 +B0432573042410S15037256EA0096600000 +B0433273042612S15037247EA0094700000 +B0433583042857S15037346EA0089500000 +B0434293043064S15037635EA0085800000 +B0435003043168S15037848EA0088900000 +B0435303043193S15037985EA0092100000 +B0436013043182S15037825EA0095200000 +B0436313043184S15037915EA0099500000 +B0437023043122S15038026EA0101100000 +B0437333043136S15037990EA0103500000 +B0438033043131S15038063EA0105600000 +B0438333043209S15037994EA0104000000 +B0439043043449S15038115EA0101700000 +B0439353043669S15038384EA0099400000 +B0440053043786S15038748EA0097100000 +B0440353043743S15038849EA0097300000 +B0441053043773S15038844EA0101200000 +B0441353043804S15038931EA0103500000 +B0442053043778S15039051EA0100700000 +B0442363043815S15038859EA0098400000 +B0443073043844S15038931EA0097600000 +B0443383043886S15038927EA0099500000 +B0444093043845S15038947EA0099400000 +B0444403043904S15038862EA0099000000 +B0445113043934S15038756EA0098000000 +B0445423044092S15038774EA0095300000 +B0446133044150S15039144EA0094600000 +B0446443044370S15039248EA0094100000 +B0447153044594S15039415EA0092800000 +B0447463044804S15039714EA0089700000 +B0448163044963S15040024EA0086900000 +B0448473044982S15040431EA0083300000 +B0449183044991S15040573EA0083000000 +B0449483045154S15040808EA0081500000 +B0450193045342S15041095EA0078100000 +B0450493045484S15041383EA0075000000 +B0451193045595S15041771EA0065700000 +B0451503045744S15042205EA0055400000 +B0452213045844S15042642EA0052000000 +B0452513045936S15042952EA0051100000 +B0453213045839S15043315EA0047600000 +B0453523045915S15043559EA0045500000 +B0454233045918S15043429EA0043300000 +B0454533045933S15043539EA0037900000 +B0455243045817S15043457EA0032800000 +B0455543045823S15043438EA0033000000 +B0456253045831S15043422EA0032900000 +B0456563045845S15043414EA0033000000 +B0457193045848S15043404EA0000000000 +GGPSBabelSecurityRecordGuaranteedToFailVALIChecks diff --git a/reference/igc1_baro.gpx b/reference/igc1_baro.gpx new file mode 100644 index 000000000..2b208ced1 --- /dev/null +++ b/reference/igc1_baro.gpx @@ -0,0 +1,2563 @@ + + + + + PRESALTTRK + Brauniger-IQ Barograph + + +829.000000 + + + +830.000000 + + + +830.000000 + + + +830.000000 + + + +830.000000 + + + +839.000000 + + + +852.000000 + + + +862.000000 + + + +870.000000 + + + +884.000000 + + + +892.000000 + + + +898.000000 + + + +899.000000 + + + +894.000000 + + + +882.000000 + + + +868.000000 + + + +871.000000 + + + +877.000000 + + + +902.000000 + + + +928.000000 + + + +950.000000 + + + +969.000000 + + + +969.000000 + + + +977.000000 + + + +983.000000 + + + +1002.000000 + + + +1016.000000 + + + +1021.000000 + + + +1021.000000 + + + +1015.000000 + + + +1013.000000 + + + +1013.000000 + + + +1013.000000 + + + +1016.000000 + + + +1005.000000 + + + +984.000000 + + + +981.000000 + + + +967.000000 + + + +962.000000 + + + +956.000000 + + + +959.000000 + + + +962.000000 + + + +970.000000 + + + +978.000000 + + + +971.000000 + + + +966.000000 + + + +958.000000 + + + +970.000000 + + + +977.000000 + + + +991.000000 + + + +1003.000000 + + + +1013.000000 + + + +1020.000000 + + + +1010.000000 + + + +1004.000000 + + + +994.000000 + + + +963.000000 + + + +958.000000 + + + +961.000000 + + + +965.000000 + + + +969.000000 + + + +952.000000 + + + +940.000000 + + + +934.000000 + + + +928.000000 + + + +932.000000 + + + +936.000000 + + + +936.000000 + + + +955.000000 + + + +982.000000 + + + +1004.000000 + + + +1017.000000 + + + +1023.000000 + + + +1036.000000 + + + +1043.000000 + + + +1041.000000 + + + +1046.000000 + + + +1037.000000 + + + +1039.000000 + + + +1036.000000 + + + +1017.000000 + + + +1005.000000 + + + +994.000000 + + + +991.000000 + + + +980.000000 + + + +958.000000 + + + +953.000000 + + + +927.000000 + + + +924.000000 + + + +916.000000 + + + +913.000000 + + + +928.000000 + + + +957.000000 + + + +980.000000 + + + +990.000000 + + + +997.000000 + + + +1009.000000 + + + +1039.000000 + + + +1057.000000 + + + +1067.000000 + + + +1056.000000 + + + +1049.000000 + + + +1036.000000 + + + +1031.000000 + + + +1027.000000 + + + +1011.000000 + + + +994.000000 + + + +993.000000 + + + +983.000000 + + + +966.000000 + + + +961.000000 + + + +958.000000 + + + +947.000000 + + + +943.000000 + + + +951.000000 + + + +947.000000 + + + +922.000000 + + + +914.000000 + + + +913.000000 + + + +920.000000 + + + +905.000000 + + + +901.000000 + + + +904.000000 + + + +903.000000 + + + +904.000000 + + + +907.000000 + + + +902.000000 + + + +901.000000 + + + +899.000000 + + + +911.000000 + + + +914.000000 + + + +901.000000 + + + +898.000000 + + + +897.000000 + + + +901.000000 + + + +908.000000 + + + +919.000000 + + + +932.000000 + + + +943.000000 + + + +958.000000 + + + +968.000000 + + + +990.000000 + + + +1009.000000 + + + +1021.000000 + + + +1029.000000 + + + +1027.000000 + + + +1004.000000 + + + +989.000000 + + + +967.000000 + + + +967.000000 + + + +979.000000 + + + +995.000000 + + + +1008.000000 + + + +1030.000000 + + + +1050.000000 + + + +1060.000000 + + + +1042.000000 + + + +1041.000000 + + + +1022.000000 + + + +1008.000000 + + + +1000.000000 + + + +994.000000 + + + +994.000000 + + + +989.000000 + + + +983.000000 + + + +982.000000 + + + +975.000000 + + + +963.000000 + + + +983.000000 + + + +996.000000 + + + +1004.000000 + + + +1005.000000 + + + +990.000000 + + + +1004.000000 + + + +993.000000 + + + +993.000000 + + + +990.000000 + + + +987.000000 + + + +987.000000 + + + +986.000000 + + + +983.000000 + + + +987.000000 + + + +977.000000 + + + +978.000000 + + + +967.000000 + + + +958.000000 + + + +954.000000 + + + +952.000000 + + + +962.000000 + + + +975.000000 + + + +1006.000000 + + + +1036.000000 + + + +1067.000000 + + + +1091.000000 + + + +1097.000000 + + + +1090.000000 + + + +1035.000000 + + + +1037.000000 + + + +1010.000000 + + + +990.000000 + + + +983.000000 + + + +972.000000 + + + +966.000000 + + + +970.000000 + + + +985.000000 + + + +995.000000 + + + +1024.000000 + + + +1051.000000 + + + +1061.000000 + + + +1098.000000 + + + +1124.000000 + + + +1140.000000 + + + +1127.000000 + + + +1128.000000 + + + +1142.000000 + + + +1150.000000 + + + +1148.000000 + + + +1131.000000 + + + +1148.000000 + + + +1165.000000 + + + +1155.000000 + + + +1162.000000 + + + +1146.000000 + + + +1137.000000 + + + +1128.000000 + + + +1120.000000 + + + +1099.000000 + + + +1076.000000 + + + +1059.000000 + + + +1061.000000 + + + +1054.000000 + + + +1058.000000 + + + +1069.000000 + + + +1074.000000 + + + +1072.000000 + + + +1089.000000 + + + +1107.000000 + + + +1122.000000 + + + +1144.000000 + + + +1156.000000 + + + +1154.000000 + + + +1155.000000 + + + +1163.000000 + + + +1169.000000 + + + +1179.000000 + + + +1188.000000 + + + +1181.000000 + + + +1171.000000 + + + +1153.000000 + + + +1142.000000 + + + +1123.000000 + + + +1103.000000 + + + +1087.000000 + + + +1067.000000 + + + +1051.000000 + + + +1041.000000 + + + +1019.000000 + + + +1015.000000 + + + +995.000000 + + + +983.000000 + + + +963.000000 + + + +951.000000 + + + +939.000000 + + + +940.000000 + + + +944.000000 + + + +944.000000 + + + +937.000000 + + + +939.000000 + + + +940.000000 + + + +945.000000 + + + +943.000000 + + + +933.000000 + + + +926.000000 + + + +924.000000 + + + +912.000000 + + + +906.000000 + + + +907.000000 + + + +901.000000 + + + +893.000000 + + + +892.000000 + + + +888.000000 + + + +882.000000 + + + +889.000000 + + + +900.000000 + + + +896.000000 + + + +881.000000 + + + +878.000000 + + + +887.000000 + + + +890.000000 + + + +888.000000 + + + +892.000000 + + + +891.000000 + + + +892.000000 + + + +888.000000 + + + +893.000000 + + + +881.000000 + + + +889.000000 + + + +883.000000 + + + +889.000000 + + + +890.000000 + + + +895.000000 + + + +900.000000 + + + +901.000000 + + + +905.000000 + + + +904.000000 + + + +893.000000 + + + +888.000000 + + + +879.000000 + + + +868.000000 + + + +857.000000 + + + +855.000000 + + + +858.000000 + + + +858.000000 + + + +858.000000 + + + +852.000000 + + + +852.000000 + + + +865.000000 + + + +861.000000 + + + +848.000000 + + + +854.000000 + + + +860.000000 + + + +862.000000 + + + +859.000000 + + + +873.000000 + + + +904.000000 + + + +929.000000 + + + +941.000000 + + + +931.000000 + + + +938.000000 + + + +938.000000 + + + +934.000000 + + + +943.000000 + + + +941.000000 + + + +942.000000 + + + +922.000000 + + + +904.000000 + + + +896.000000 + + + +878.000000 + + + +869.000000 + + + +873.000000 + + + +872.000000 + + + +874.000000 + + + +864.000000 + + + +874.000000 + + + +896.000000 + + + +898.000000 + + + +891.000000 + + + +899.000000 + + + +881.000000 + + + +885.000000 + + + +917.000000 + + + +919.000000 + + + +917.000000 + + + +926.000000 + + + +926.000000 + + + +945.000000 + + + +962.000000 + + + +971.000000 + + + +981.000000 + + + +985.000000 + + + +987.000000 + + + +1003.000000 + + + +981.000000 + + + +960.000000 + + + +939.000000 + + + +929.000000 + + + +949.000000 + + + +947.000000 + + + +945.000000 + + + +939.000000 + + + +931.000000 + + + +915.000000 + + + +909.000000 + + + +909.000000 + + + +895.000000 + + + +882.000000 + + + +882.000000 + + + +900.000000 + + + +920.000000 + + + +933.000000 + + + +963.000000 + + + +969.000000 + + + +964.000000 + + + +944.000000 + + + +942.000000 + + + +928.000000 + + + +924.000000 + + + +916.000000 + + + +908.000000 + + + +889.000000 + + + +893.000000 + + + +891.000000 + + + +898.000000 + + + +896.000000 + + + +895.000000 + + + +885.000000 + + + +883.000000 + + + +890.000000 + + + +903.000000 + + + +904.000000 + + + +906.000000 + + + +915.000000 + + + +922.000000 + + + +919.000000 + + + +931.000000 + + + +920.000000 + + + +905.000000 + + + +889.000000 + + + +892.000000 + + + +904.000000 + + + +918.000000 + + + +943.000000 + + + +953.000000 + + + +979.000000 + + + +985.000000 + + + +998.000000 + + + +1005.000000 + + + +999.000000 + + + +980.000000 + + + +981.000000 + + + +964.000000 + + + +954.000000 + + + +931.000000 + + + +916.000000 + + + +907.000000 + + + +903.000000 + + + +893.000000 + + + +889.000000 + + + +876.000000 + + + +871.000000 + + + +848.000000 + + + +841.000000 + + + +858.000000 + + + +869.000000 + + + +886.000000 + + + +896.000000 + + + +901.000000 + + + +905.000000 + + + +901.000000 + + + +902.000000 + + + +898.000000 + + + +913.000000 + + + +935.000000 + + + +959.000000 + + + +990.000000 + + + +1013.000000 + + + +1030.000000 + + + +1027.000000 + + + +990.000000 + + + +958.000000 + + + +953.000000 + + + +957.000000 + + + +949.000000 + + + +960.000000 + + + +968.000000 + + + +971.000000 + + + +979.000000 + + + +991.000000 + + + +991.000000 + + + +989.000000 + + + +958.000000 + + + +935.000000 + + + +924.000000 + + + +919.000000 + + + +909.000000 + + + +891.000000 + + + +893.000000 + + + +907.000000 + + + +915.000000 + + + +925.000000 + + + +942.000000 + + + +955.000000 + + + +949.000000 + + + +971.000000 + + + +982.000000 + + + +985.000000 + + + +971.000000 + + + +955.000000 + + + +942.000000 + + + +936.000000 + + + +915.000000 + + + +905.000000 + + + +898.000000 + + + +908.000000 + + + +906.000000 + + + +906.000000 + + + +905.000000 + + + +900.000000 + + + +897.000000 + + + +892.000000 + + + +899.000000 + + + +911.000000 + + + +919.000000 + + + +930.000000 + + + +917.000000 + + + +910.000000 + + + +912.000000 + + + +930.000000 + + + +954.000000 + + + +973.000000 + + + +987.000000 + + + +991.000000 + + + +1013.000000 + + + +1029.000000 + + + +1038.000000 + + + +1046.000000 + + + +1032.000000 + + + +1008.000000 + + + +997.000000 + + + +989.000000 + + + +1006.000000 + + + +1028.000000 + + + +1068.000000 + + + +1086.000000 + + + +1109.000000 + + + +1122.000000 + + + +1131.000000 + + + +1134.000000 + + + +1143.000000 + + + +1130.000000 + + + +1112.000000 + + + +1084.000000 + + + +1068.000000 + + + +1056.000000 + + + +1032.000000 + + + +1002.000000 + + + +966.000000 + + + +935.000000 + + + +918.000000 + + + +895.000000 + + + +872.000000 + + + +858.000000 + + + +866.000000 + + + +872.000000 + + + +890.000000 + + + +911.000000 + + + +926.000000 + + + +946.000000 + + + +960.000000 + + + +968.000000 + + + +959.000000 + + + +952.000000 + + + +930.000000 + + + +901.000000 + + + +880.000000 + + + +861.000000 + + + +852.000000 + + + +880.000000 + + + +904.000000 + + + +920.000000 + + + +923.000000 + + + +941.000000 + + + +965.000000 + + + +987.000000 + + + +1006.000000 + + + +1012.000000 + + + +1011.000000 + + + +1031.000000 + + + +1039.000000 + + + +1054.000000 + + + +1058.000000 + + + +1046.000000 + + + +1037.000000 + + + +1023.000000 + + + +1015.000000 + + + +1003.000000 + + + +991.000000 + + + +978.000000 + + + +969.000000 + + + +972.000000 + + + +974.000000 + + + +989.000000 + + + +1021.000000 + + + +1022.000000 + + + +1040.000000 + + + +1027.000000 + + + +1000.000000 + + + +976.000000 + + + +986.000000 + + + +982.000000 + + + +976.000000 + + + +983.000000 + + + +996.000000 + + + +994.000000 + + + +994.000000 + + + +986.000000 + + + +991.000000 + + + +990.000000 + + + +983.000000 + + + +965.000000 + + + +953.000000 + + + +953.000000 + + + +945.000000 + + + +949.000000 + + + +943.000000 + + + +939.000000 + + + +931.000000 + + + +925.000000 + + + +899.000000 + + + +895.000000 + + + +876.000000 + + + +862.000000 + + + +840.000000 + + + +828.000000 + + + +829.000000 + + + +831.000000 + + + +830.000000 + + + +806.000000 + + + +796.000000 + + + +774.000000 + + + +767.000000 + + + +742.000000 + + + +705.000000 + + + +633.000000 + + + +577.000000 + + + +546.000000 + + + +516.000000 + + + +522.000000 + + + +512.000000 + + + +511.000000 + + + +499.000000 + + + +471.000000 + + + +457.000000 + + + +455.000000 + + + +455.000000 + + + +432.000000 + + + +400.000000 + + + +378.000000 + + + +342.000000 + + + +328.000000 + + + +329.000000 + + + +330.000000 + + + +330.000000 + + + +329.000000 + + + +330.000000 + + + +330.000000 + + + +330.000000 + + + + + diff --git a/reference/igc1_gpx.out b/reference/igc1_gpx.out new file mode 100644 index 000000000..35d55e160 --- /dev/null +++ b/reference/igc1_gpx.out @@ -0,0 +1,384 @@ + + + + + + 0001 + IGCDATE000000: + + TAKEOFF + BORAH + BORAH + + + START + BORAH + BORAH + + + TURN01 + BALDWI + BALDWI + + + FINISH + MANAIR + MANAIR + + + LANDING + MANAIR + MANAIR + + + + GNSSALTTRK + IGCHDRS~HFPLTPILOT:CHRIS JONES~ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/igc1_igc.out b/reference/igc1_igc.out new file mode 100644 index 000000000..9d3c0071e --- /dev/null +++ b/reference/igc1_igc.out @@ -0,0 +1,123 @@ +AXXXZZZGPSBabel +HFDTE240404 +HFPLTPILOT:CHRIS JONES +C010170000000000000000101 +C3040552S15036542EBORAH +C3040552S15036542EBORAH +C3043796S15038952EBALDWI +C3045821S15043392EMANAIR +C3045821S15043392EMANAIR +B0400193040579S15036384EA0000000000 +B0400493040614S15036317EA0000000000 +B0401193040699S15036326EA0000000000 +B0401503040629S15036431EA0000000000 +B0402203040628S15036565EA0000000000 +B0402513040689S15036431EA0000000000 +B0403223040555S15036270EA0000000000 +B0403523040720S15036356EA0000000000 +B0404233040884S15036452EA0000000000 +B0404543040658S15036419EA0000000000 +B0405243040811S15036507EA0000000000 +B0405553040688S15036378EA0000000000 +B0406263040714S15036409EA0000000000 +B0406573040686S15036391EA0000000000 +B0407283040728S15036419EA0000000000 +B0407583040656S15036366EA0000000000 +B0408293040785S15036447EA0000000000 +B0409003040822S15036433EA0000000000 +B0409313040795S15036535EA0000000000 +B0410013040809S15036573EA0000000000 +B0410323040819S15036444EA0000000000 +B0411023040785S15036304EA0000000000 +B0411323040816S15036327EA0000000000 +B0412033040846S15036397EA0000000000 +B0412343040813S15036503EA0000000000 +B0413043040760S15036508EA0000000000 +B0413353040694S15036319EA0000000000 +B0414063040538S15036152EA0000000000 +B0414373040695S15036308EA0000000000 +B0415073040758S15036421EA0000000000 +B0415383040766S15036490EA0000000000 +B0416083040753S15036493EA0000000000 +B0416393040739S15036494EA0000000000 +B0417103040750S15036527EA0000000000 +B0417413040819S15036393EA0000000000 +B0418113040806S15036352EA0000000000 +B0418413040569S15036344EA0000000000 +B0419123040526S15036253EA0000000000 +B0419433040646S15036334EA0000000000 +B0420133040794S15036367EA0000000000 +B0420443040707S15036367EA0000000000 +B0421143040679S15036423EA0000000000 +B0421443040658S15036414EA0000000000 +B0422153040772S15036358EA0000000000 +B0422453040722S15036423EA0000000000 +B0423153040717S15036457EA0000000000 +B0423453040700S15036444EA0000000000 +B0424163040689S15036457EA0000000000 +B0424473040753S15036486EA0000000000 +B0425183040750S15036329EA0000000000 +B0425483040794S15036240EA0000000000 +B0426193040688S15036353EA0000000000 +B0426493040679S15036400EA0000000000 +B0427203040754S15036332EA0000000000 +B0427513040693S15036316EA0000000000 +B0428213040918S15036288EA0000000000 +B0428513041173S15036316EA0000000000 +B0429223041467S15036406EA0000000000 +B0429523041752S15036547EA0000000000 +B0430233042022S15036681EA0000000000 +B0430543042288S15036906EA0000000000 +B0431243042359S15037048EA0000000000 +B0431553042430S15037151EA0000000000 +B0432263042348S15037228EA0000000000 +B0432573042410S15037256EA0000000000 +B0433273042612S15037247EA0000000000 +B0433583042857S15037346EA0000000000 +B0434293043064S15037635EA0000000000 +B0435003043168S15037848EA0000000000 +B0435303043193S15037985EA0000000000 +B0436013043182S15037825EA0000000000 +B0436313043184S15037915EA0000000000 +B0437023043122S15038026EA0000000000 +B0437333043136S15037990EA0000000000 +B0438033043131S15038063EA0000000000 +B0438333043209S15037994EA0000000000 +B0439043043449S15038115EA0000000000 +B0439353043669S15038384EA0000000000 +B0440053043786S15038748EA0000000000 +B0440353043743S15038849EA0000000000 +B0441053043773S15038844EA0000000000 +B0441353043804S15038931EA0000000000 +B0442053043778S15039051EA0000000000 +B0442363043815S15038859EA0000000000 +B0443073043844S15038931EA0000000000 +B0443383043886S15038927EA0000000000 +B0444093043845S15038947EA0000000000 +B0444403043904S15038862EA0000000000 +B0445113043934S15038756EA0000000000 +B0445423044092S15038774EA0000000000 +B0446133044150S15039144EA0000000000 +B0446443044370S15039248EA0000000000 +B0447153044594S15039415EA0000000000 +B0447463044804S15039714EA0000000000 +B0448163044963S15040024EA0000000000 +B0448473044982S15040431EA0000000000 +B0449183044991S15040573EA0000000000 +B0449483045154S15040808EA0000000000 +B0450193045342S15041095EA0000000000 +B0450493045484S15041383EA0000000000 +B0451193045595S15041771EA0000000000 +B0451503045744S15042205EA0000000000 +B0452213045844S15042642EA0000000000 +B0452513045936S15042952EA0000000000 +B0453213045839S15043315EA0000000000 +B0453523045915S15043559EA0000000000 +B0454233045918S15043429EA0000000000 +B0454533045933S15043539EA0000000000 +B0455243045817S15043457EA0000000000 +B0455543045823S15043438EA0000000000 +B0456253045831S15043422EA0000000000 +B0456563045845S15043414EA0000000000 +B0457193045848S15043404EA0000000000 +GGPSBabelSecurityRecordGuaranteedToFailVALIChecks diff --git a/reference/igc2.igc b/reference/igc2.igc new file mode 100644 index 000000000..b07594187 --- /dev/null +++ b/reference/igc2.igc @@ -0,0 +1,46 @@ +AXXXABCFLIGHT:1 +HFFXA035 +HFDTE160701 +HFPLTPILOT:Bill Bloggs +HFGTYGLIDERTYPE:Schleicher ASH-25 +HFGIDGLIDERID:ABCD-1234 +HFDTM100GPSDATUM:WGS-1984 +HFRFWFIRMWAREVERSION:6.4 +HFRHWHARDWAREVERSION:3.0 +HFFTYFRTYPE:Manufacturer Model +HFGPSMarconiCanada:Superstar 12ch max10000m +HFPRSPRESSALTSENSOR:Sensyn XYZ1111 max11000m +HFCIDCOMPETITIONID:XYZ-78910 +HFCCLCOMPETITIONCLASS:15mMotor Glider +HFSCMSECONDCREW:JohnSmith +I023638FXA3941ENL +J010812HDT +C150701213841160701000102500KTri +C5111359N00101899WLashamClubhouse +C5110179N00102644WLashamStart S Start +C5209092N00255227WSarnesfield TP1 +C5230147N00017612WNormanCross TP2 +C5110179N00102644WLashamStart S Finish +C5111359N00101899WLashamClubhouse +F160240040609123624221821 +B1602405407121N00249342WA0028000421020509950 +D20331 +E160245PEV +B1602455107126N00149300WA0028800429019509020 +B1602505107134N00149283WA0029000432021009015 +B1602555107140N00149221WA0029000430020009012 +F1603000609123624221821 +B1603005107150N00149202WA0029100432025608009 +E160305PEV +B1603055107180N00149185WA0029100435021008015 +B1603105107212N00149174WA0029300435019608024 +K160248090 +B1602485107220N00149150WA0049400436019008018 +B1602525107330N00149127WA0049600439019508015 +LXXXRURITANIANSTANDARD NATIONALS DAY 1 +LXXXFLIGHTTIME: 4:14:25 TASK SPEED:58.48KTS +GREJNGJERJKNJKRE31895478537H43982FJN9248F942389T433T +GJNJK1489IERGNV3089IVJE9GO398535J3894N358954983O0934 +GSKTO5427FGTNUT5621WKTC6714FT8957FGMKJ134527FGTR6751 +GK2489IERGNV3089IVJE39GO398535J3894N358954983FTGY546 +G12560DJUWT28719GTAOL5628FGWNIST78154INWTOLP7815FITN diff --git a/reference/igc2_gpx.out b/reference/igc2_gpx.out new file mode 100644 index 000000000..98dc11564 --- /dev/null +++ b/reference/igc2_gpx.out @@ -0,0 +1,134 @@ + + + + + + 0001 + IGCDATE160701: 500KTri + + + TAKEOFF + LashamClubhouse + LashamClubhouse + + + + START + LashamStart S Start + LashamStart S Start + + + + TURN01 + Sarnesfield TP1 + Sarnesfield TP1 + + + + TURN02 + NormanCross TP2 + NormanCross TP2 + + + + FINISH + LashamStart S Finish + LashamStart S Finish + + + + LANDING + LashamClubhouse + LashamClubhouse + + + + PRESALTTRK + IGCHDRS~HFFXA035~HFPLTPILOT:Bill Bloggs~HFGTYGLIDERTYPE:Schleicher ASH-25~HFGIDGLIDERID:ABCD-1234~HFDTM100GPSDATUM:WGS-1984~HFRFWFIRMWAREVERSION:6.4~HFRHWHARDWAREVERSION:3.0~HFFTYFRTYPE:Manufacturer Model~HFGPSMarconiCanada:Superstar 12ch max10000m~HFPRSPRESSALTSENSOR:Sensyn XYZ1111 max11000m~HFCIDCOMPETITIONID:XYZ-78910~HFCCLCOMPETITIONCLASS:15mMotor Glider~HFSCMSECONDCREW:JohnSmith~ + + + 280.000000 + + + + 288.000000 + + + + 290.000000 + + + + 290.000000 + + + + 291.000000 + + + + 291.000000 + + + + 293.000000 + + + + 494.000000 + + + + 496.000000 + + + + + + GNSSALTTRK + IGCHDRS~HFFXA035~HFPLTPILOT:Bill Bloggs~HFGTYGLIDERTYPE:Schleicher ASH-25~HFGIDGLIDERID:ABCD-1234~HFDTM100GPSDATUM:WGS-1984~HFRFWFIRMWAREVERSION:6.4~HFRHWHARDWAREVERSION:3.0~HFFTYFRTYPE:Manufacturer Model~HFGPSMarconiCanada:Superstar 12ch max10000m~HFPRSPRESSALTSENSOR:Sensyn XYZ1111 max11000m~HFCIDCOMPETITIONID:XYZ-78910~HFCCLCOMPETITIONCLASS:15mMotor Glider~HFSCMSECONDCREW:JohnSmith~ + + + 421.000000 + + + + 429.000000 + + + + 432.000000 + + + + 430.000000 + + + + 432.000000 + + + + 435.000000 + + + + 435.000000 + + + + 436.000000 + + + + 439.000000 + + + + + diff --git a/reference/igc2_igc.out b/reference/igc2_igc.out new file mode 100644 index 000000000..877a5bcba --- /dev/null +++ b/reference/igc2_igc.out @@ -0,0 +1,32 @@ +AXXXZZZGPSBabel +HFDTE160701 +HFFXA035 +HFPLTPILOT:Bill Bloggs +HFGTYGLIDERTYPE:Schleicher ASH-25 +HFGIDGLIDERID:ABCD-1234 +HFDTM100GPSDATUM:WGS-1984 +HFRFWFIRMWAREVERSION:6.4 +HFRHWHARDWAREVERSION:3.0 +HFFTYFRTYPE:Manufacturer Model +HFGPSMarconiCanada:Superstar 12ch max10000m +HFPRSPRESSALTSENSOR:Sensyn XYZ1111 max11000m +HFCIDCOMPETITIONID:XYZ-78910 +HFCCLCOMPETITIONCLASS:15mMotor Glider +HFSCMSECONDCREW:JohnSmith +C150701213841160701000102500KTri +C5111359N00101899WLashamClubhouse +C5110179N00102644WLashamStart S Start +C5209092N00255227WSarnesfield TP1 +C5230147N00017612WNormanCross TP2 +C5110179N00102644WLashamStart S Finish +C5111359N00101899WLashamClubhouse +B1602405407121N00249342WA0028000421 +B1602455107126N00149300WA0028800429 +B1602505107134N00149283WA0029000432 +B1602555107140N00149221WA0029000430 +B1603005107150N00149202WA0029100432 +B1603055107180N00149185WA0029100435 +B1603105107212N00149174WA0029300435 +B1602485107220N00149150WA0049400436 +B1602525107330N00149127WA0049600439 +GGPSBabelSecurityRecordGuaranteedToFailVALIChecks diff --git a/reference/ignoreicons.usr b/reference/ignoreicons.usr new file mode 100644 index 0000000000000000000000000000000000000000..f3724e4b313be9f9c62eee41c9f958a3d6b9efb4 GIT binary patch literal 2901 zcma*pe`u9e9LMqJx#kv0{wQ!pWDAs$q+zLlgc+DQ$ BtfuoWmz#G#aBYZlR;xtZ zipms0?S~?`$W;6_GsUvn)G#9`V}FDRl1f@yWTW)?1z-pH#Jrkj!oqF_*`xrMTzJ} zJ!*1OO-*4*Q(c^l1{EcvWqQ36dcF8Xp&L*+1QrXOpibBWs)Ub0xv&L1Eo=tG!a6Wn zSPdo$Z-Vhc8yGFD03(D}aJ$e9h6;^fpimF`3$-AvSz8Etg>rCNCPlB_;W8jo9 z3G@i}fs?{0@U1W$d?O46M}&dk3n3pI7Gl7R_G&rfPlUg~PT>;xP++Cw?Sik`Aq?QE zUBazkzi=D)RJaQq5IhW;#)Zm6z(c2kZozNywNOIkxKIYD%m+t>n$X!Z##=0-(j_bp zO`drwYpHxGydU6&O169$7a;TAAU7zRp(!q9XtNUAa(ED#<9+~*NcD?APw zg;`*UFbA{>^8f>z3swowf_0(KCZU1~tNc7*-3@j^ipoLZ1;9i#2fP~44w%(<0G-zZ z4uxsesmi!Zx$AQ7jx#yr?khmCN0DjHN>E?go8x#~ya>*p^NZyD?3sJ{PV4X8TW& zmAikla>p9^KBToD&*IMigsWV+PBvL1XOlJZP+3qP8dNgboWh++S1N?U?Y?}*!L;eilO}(|4@E$5m!gqjaIR==+!+?3-2bkv_fOvKQ zQt&QdtFH!}0Ivr)AoOu$$c{tAkD!0@sQ5>a%geZmq&x+9#0_fA0Ch%bZ9TIb^t@!PEVbz`%TtF=n4^oPI;N&ksTY z_)+jfe-etQoEFA_Gr|OLR`B_APMAXFqTuuAvfyunUcr;VL0v%~zMVW#1%jt;xUht# zQG!qY`vuSQ140{3e6aazVY=X-l9_@}q-TUp^hpU@!6IQN;74jd$b2sHq1;Vnx!|K| MrEro;yWnl}AAo1&&;S4c literal 0 HcmV?d00001 diff --git a/reference/ik3d-sample.gpx b/reference/ik3d-sample.gpx new file mode 100644 index 000000000..e4d8f728a --- /dev/null +++ b/reference/ik3d-sample.gpx @@ -0,0 +1,139 @@ + + + + + + Jahnstrasse + Jahnstrasse 11 + Jahnstrasse 11 + + + Liebknechtstrasse + Liebknechtstrasse 90 + Liebknechtstrasse 90 + + + NARVA + Start + Start + + + NARVA to Jahnstrasse + + + + + + + + + + + + + + + + + + + + + + + + + ACTIVE LOG 006 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/ik3d-sample.ikt b/reference/ik3d-sample.ikt new file mode 100644 index 000000000..441bb9a8b --- /dev/null +++ b/reference/ik3d-sample.ikt @@ -0,0 +1,433 @@ + + + + + Germany TK25 Demo + 1.1 + + German + +
    + Undefiniert + 5 + +
    + + + 5 + + 0 + Jahnstrasse + + + 0 + 132048172029964614 + False + + 1 + 1 + + Jahnstrasse 11 + + + 2 + True + 32.0000000000 + 1.0000000000 + + + 16.0000000000 + 1 + .\default.jpg + 0 + False + 0.0000000000 + 1 + 1.0000000000 + + + Jahnstrasse 11 + + + 2 + False + 99.0000000000 + 1.0000000000 + + + 180.0000000000 + 1 + .\default.jpg + False + -36.0000000000 + 1 + 0.2500000000 + + + + 0 + Liebknechtstrasse + + + 1 + 194043035650486614 + False + + 1 + 1 + + Liebknechtstrasse 90 + + + 2 + True + 32.0000000000 + 1.0000000000 + + + 16.0000000000 + 1 + .\default.jpg + 0 + False + 0.0000000000 + 1 + 1.0000000000 + + + Liebknechtstrasse 90 + + + 2 + False + 100.0000000000 + 1.0000000000 + + + 180.0000000000 + 1 + .\default.jpg + False + -36.0000000000 + 1 + 0.2500000000 + + + + 0 + NARVA + + + 2 + 319457729961128278 + False + + 1 + 1 + + Start + + + 2 + True + 32.0000000000 + 1.0000000000 + + + 16.0000000000 + 1 + .\default.jpg + 0 + False + 0.0000000000 + 1 + 1.0000000000 + + + Start + + + 2 + False + 99.0000000000 + 1.0000000000 + + + 180.0000000000 + 1 + .\default.jpg + False + -36.0000000000 + 1 + 0.2500000000 + + + + 1 + NARVA to Jahnstrasse + + + 3 + 232341224669180246 + False + 1.0000000000 + 5 + + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.0000000000 + False + 12 + + + + + + 1.0000000000 + False + + + + 1 + ACTIVE LOG 006 + + + 4 + 387926518045995350 + False + 1.0000000000 + 5 + + 42 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.0000000000 + False + 12 + + + + + + 1.0000000000 + False + + + + +
    diff --git a/reference/kartex-out.kwf b/reference/kartex-out.kwf new file mode 100644 index 000000000..4ca65b836 --- /dev/null +++ b/reference/kartex-out.kwf @@ -0,0 +1,13 @@ +//Kartex Waypoint File created by GPSBabel +&KWF 2.0,sweref 99 lat long,0 +#,0,GC1B51,N56.078617° E13.124417°,0.00,,,0,GC1B51,$ +#,1,GC1DE6,N56.391183° E12.896183°,0.00,,,0,GC1DE6,$ +#,2,GC1E56,N57.476533° E12.173367°,0.00,,,0,GC1E56,$ +#,3,GC2182,N56.227117° E14.356100°,0.00,,,0,GC2182,$ +#,4,GC23F6,N57.363950° E12.843100°,0.00,,,0,GC23F6,$ +#,5,GC28B4,N56.330150° E14.377283°,0.00,,,0,GC28B4,$ +#,6,GC2A45,N56.713300° E13.026650°,0.00,,,0,GC2A45,$ +#,7,GC2AFD,N56.191017° E14.271100°,0.00,,,0,GC2AFD,$ +#,8,GC2BC9,N56.142467° E14.564767°,0.00,,,0,GC2BC9,$ +#,9,GC2BCA,N56.301983° E13.060750°,0.00,,,0,GC2BCA,$ +#,10,GC2D31,N57.374733° E12.916517°,0.00,,,0,GC2D31,$ diff --git a/reference/kartex.txt b/reference/kartex.txt new file mode 100644 index 000000000..e8761b380 --- /dev/null +++ b/reference/kartex.txt @@ -0,0 +1,16 @@ +Grid Lat/Lon hddd°mm.mmm' +Datum WGS 84 + +Header Name Description Type Position Altitude Depth Proximity Temperature Display Mode Color Symbol Facility City State Country Date Modified Link Categories + +Waypoint GC1B51 User Waypoint N56 04.717 E13 07.465 0 m Symbol & Name Unknown Waypoint +Waypoint GC1DE6 User Waypoint N56 23.471 E12 53.771 0 m Symbol & Name Unknown Waypoint +Waypoint GC1E56 User Waypoint N57 28.592 E12 10.402 0 m Symbol & Name Unknown Waypoint +Waypoint GC2182 User Waypoint N56 13.627 E14 21.366 0 m Symbol & Name Unknown Waypoint +Waypoint GC23F6 User Waypoint N57 21.837 E12 50.586 0 m Symbol & Name Unknown Waypoint +Waypoint GC28B4 User Waypoint N56 19.809 E14 22.637 0 m Symbol & Name Unknown Waypoint +Waypoint GC2A45 User Waypoint N56 42.798 E13 01.599 0 m Symbol & Name Unknown Waypoint +Waypoint GC2AFD User Waypoint N56 11.461 E14 16.266 0 m Symbol & Name Unknown Waypoint +Waypoint GC2BC9 User Waypoint N56 08.548 E14 33.886 0 m Symbol & Name Unknown Waypoint +Waypoint GC2BCA User Waypoint N56 18.119 E13 03.645 0 m Symbol & Name Unknown Waypoint +Waypoint GC2D31 User Waypoint N57 22.484 E12 54.991 0 m Symbol & Name Unknown Waypoint diff --git a/reference/lowrance.usr b/reference/lowrance.usr new file mode 100644 index 0000000000000000000000000000000000000000..26350d0292457fd874791cdd7e32be69f2700ee3 GIT binary patch literal 622 zcmaix&r1S96vtnt_T%WOi#2t~W35Y>5X9{2u7#ncAw-w4Mjc#dWp@>p@L13}`f=~S z>HnyE*Dm%Zh17x$Gdza({mgscZv+6A@C<7d_6N=oONimI&Aed{ERNlt449C_5N%Eh zob|aR^^o{IKh$(h#}?R4se29{o+u2A&Nn2EFSe;sJ+p>YwZ%!*a~(%XnYNei3daq| zCb3vYIH8h{AQAYyqHu6A1u@e`5<7CD&xzr7>fBS9BiAlh5Yd=H%)|3Fg}2fqBE3Vi zD~Pa4m1_QUQaw9B6p}9#Zc|h0Oj_SSbWgMc96cWpmYJEFvt)jZp3R6BQh>@9=@VKQW;$B`h^@%(d z;Pr+=`+XGZC=XrBP?d)*f*?HW{ur@EYRr>3RGE2gA3Mf*EW-Ich4qgaNKV;tC>`~& Lkj?)&iU{xpG^LB5 literal 0 HcmV?d00001 diff --git a/reference/magfile b/reference/magfile new file mode 100644 index 000000000..26216d129 --- /dev/null +++ b/reference/magfile @@ -0,0 +1,18 @@ +$PMGNWPL,2805.200,N,08246.200,W,0000000,M,AL7394,872 6833 A TIDAL,a*43 +$PMGNWPL,2806.216,N,08246.733,W,0000000,M,AL7485,872 6853 TIDAL 1,a*33 +$PMGNWPL,2806.216,N,08246.733,W,0000000,M,AL7484,872 6853 TIDAL 2,a*31 +$PMGNWPL,2806.050,N,08246.367,W,0000000,M,AL7482,872 6853 TIDAL 4,a*34 +$PMGNWPL,2808.816,N,08245.483,W,0000000,M,AL7471,872 6892 TIDAL 1,a*3A +$PMGNWPL,2808.816,N,08245.483,W,0000000,M,AL7470,872 6892 TIDAL 2,a*38 +$PMGNWPL,2809.017,N,08246.283,W,0000000,M,AL7380,872 6899 TIDAL 1,a*35 +$PMGNWPL,2809.017,N,08246.283,W,0000000,M,AL7379,872 6899 TIDAL 2,a*30 +$PMGNWPL,2809.017,N,08246.283,W,0000000,M,AL7378,872 6899 TIDAL 3,a*30 +$PMGNWPL,2809.017,N,08246.283,W,0000000,M,AL7377,872 6899 TIDAL 4,a*38 +$PMGNWPL,2809.017,N,08246.283,W,0000000,M,AL7376,872 6899 TIDAL 5,a*38 +$PMGNWPL,2809.216,N,08248.033,W,0000000,M,AL7386,872 6904 TIDAL 1,a*32 +$PMGNWPL,2809.216,N,08248.033,W,0000000,M,AL7385,872 6904 TIDAL 2,a*32 +$PMGNWPL,2809.216,N,08248.033,W,0000000,M,AL7384,872 6904 TIDAL 3,a*32 +$PMGNWPL,2809.216,N,08248.017,W,0000000,M,AL7383,872 6904 TIDAL 4,a*34 +$PMGNWPL,2809.216,N,08248.017,W,0000000,M,AL7382,872 6904 TIDAL 5,a*34 +$PMGNWPL,2809.617,N,08245.933,W,0000000,M,AL6625,872 6905 TIDAL 5,a*3B +$PMGNWPL,2809.383,N,08244.666,W,0000000,M,AL7392,872 6906 TIDAL 2,a*31 diff --git a/reference/magnav.pdb b/reference/magnav.pdb new file mode 100644 index 0000000000000000000000000000000000000000..a922f66ab6d88e44e2990bbc8f8862f5b3a700c0 GIT binary patch literal 1160 zcmd^N%m=zAC!9OWzRds!R8F zWI)XP0WcsjFt9?`A_k;x)$t6(O;r%t`{eU?cRu~}z4zp^Mbjso3657u6{QW`2hZk*N z@l|OCIZM@Axzfq%&YU?~QStZflw}qTv>@t);{{f4$cAWz^q%U6_bJ~VzI{DX!yNeg zEK{as>d1v34sx~0IusK!u6Emxks}p?9@XW(m1W%4o&^Q@#nf8UhZ6mr1bEaXUPc@X(ox!*?CXS@fEFi7CeG4^!dr E4GGPz-Rgwl3F^6C(7(y~q6+(*gb8-}tDisn9EsP2>bMi|R)D+wj zb2D=);p*TFAvg<_Q3d3J9N=u^gpfe8|3Ab53t!KW{O*~KaDYo@S*n6ler{4~5y%N% z`R)P1K;w7wK#y^*P-B|hspXD^UEDw%|^-pxNa#5D-nW>P&~54G9c$QYl^TUggg zu2Km^*zA*^o|vcLlbN1Tl969poC ztl*IeNqBCVMX7F}kVq|Z%}X~X!G37EH#RhP#Am;^;1WsS)20af-7`x{Dnknp5wEWh zo>-Iz42*!pqU>UXSuhr^0Dwk6&;c$mrPu->X3YvoBX28&13dF`KpxJ_OQ+lo&_Hl? ya>C~XyQV3UE9Y<`oZy>ZnpcvTnWx~CnVqWOk(yYRng?=BG0CZb321K^10w)x$S3sx literal 0 HcmV?d00001 diff --git a/reference/mps-empty.mps b/reference/mps-empty.mps new file mode 100755 index 0000000000000000000000000000000000000000..154785e977422e6b591ec800a516e49ac5a376dc GIT binary patch literal 52 zcmeY*4oXg8U}9ika7kg122zfCjKP794F1U_3PuJBhL)C=42DKlrUq8V#$aV(42%H! C@CcIt literal 0 HcmV?d00001 diff --git a/reference/multiple-links.gpx b/reference/multiple-links.gpx new file mode 100644 index 000000000..448a465a3 --- /dev/null +++ b/reference/multiple-links.gpx @@ -0,0 +1,35 @@ + + + + + + + + + 001 + 3348 Martha St + 3348 Martha St + + one + + + two dots + + + + + three dots + + Waypoint + + + SymbolAndDescription + + + + diff --git a/reference/mxf.mxf b/reference/mxf.mxf new file mode 100644 index 000000000..98d93d1a0 --- /dev/null +++ b/reference/mxf.mxf @@ -0,0 +1,9 @@ +35.97203, -87.13470, "Mountain Bike Heaven by susy1313", "GCEBB", "Mountain Bike Heaven by susy1313", ff0000, 47 +36.09068, -86.67955, "The Troll by a182pilot & Family", "GC1A37", "The Troll by a182pilot & Family", ff0000, 47 +35.99627, -86.62012, "Dive Bomber by JoGPS & family", "GC1C2B", "Dive Bomber by JoGPS & family", ff0000, 47 +36.03848, -86.64862, "FOSTER by JoGPS & Family", "GC25A9", "FOSTER by JoGPS & Family", ff0000, 47 +36.11218, -86.74177, "Logan Lighthouse by JoGps & Family", "GC2723", "Logan Lighthouse by JoGps & Family", ff0000, 47 +36.06408, -86.79052, "Ganier Cache by Susy1313", "GC2B71", "Ganier Cache by Susy1313", ff0000, 47 +36.08777, -86.80973, "Shy's Hill by FireFighterEng33", "GC309F", "Shy's Hill by FireFighterEng33", ff0000, 47 +36.05750, -86.89200, "GittyUp by JoGPS / Warner Parks", "GC317A", "GittyUp by JoGPS / Warner Parks", ff0000, 47 +36.08280, -86.86728, "Inlighting by JoGPS / Warner Parks", "GC317D", "Inlighting by JoGPS / Warner Parks", ff0000, 47 diff --git a/reference/navicache.ref b/reference/navicache.ref new file mode 100644 index 000000000..b74e217a4 --- /dev/null +++ b/reference/navicache.ref @@ -0,0 +1,2 @@ +2343 3334.415N 11146.587W 0000000m Eagle's Nest a +2342 3431.053N 11146.178W 0000000m Clear Creek Cache a diff --git a/reference/navicache.xml b/reference/navicache.xml new file mode 100644 index 000000000..becb69879 --- /dev/null +++ b/reference/navicache.xml @@ -0,0 +1,91 @@ + + + + + + + + + diff --git a/reference/navilink_tracks.gpx b/reference/navilink_tracks.gpx new file mode 100644 index 000000000..b910421b1 --- /dev/null +++ b/reference/navilink_tracks.gpx @@ -0,0 +1,2084 @@ + + + + + + + + 0.000000 + + 0.000000 + 0.000000 + + + 0.000000 + + 0.000000 + 0.000000 + + + 0.000000 + + 0.000000 + 0.000000 + + + 32.004000 + + 0.000000 + 0.000000 + + + 32.918400 + + 0.000000 + 0.000000 + + + 32.918400 + + 0.000000 + 0.000000 + + + 37.490400 + + 0.000000 + 0.000000 + + + 34.137600 + + 0.000000 + 0.000000 + + + 33.223200 + + 23.000000 + 0.555556 + + + 32.918400 + + 41.000000 + 1.111111 + + + 32.613600 + + 47.000000 + 1.666667 + + + 32.308800 + + 57.000000 + 1.666667 + + + 32.613600 + + 47.000000 + 1.666667 + + + 32.613600 + + 57.000000 + 1.666667 + + + 32.918400 + + 63.000000 + 1.666667 + + + 33.528000 + + 61.000000 + 1.666667 + + + 33.832800 + + 63.000000 + 1.666667 + + + 34.137600 + + 63.000000 + 1.666667 + + + 34.747200 + + 64.000000 + 1.666667 + + + 35.052000 + + 69.000000 + 1.666667 + + + 35.356800 + + 71.000000 + 1.666667 + + + 35.966400 + + 71.000000 + 1.666667 + + + 36.576000 + + 78.000000 + 1.666667 + + + 36.576000 + + 76.000000 + 0.000000 + + + 36.576000 + + 78.000000 + 1.666667 + + + 36.271200 + + 84.000000 + 1.666667 + + + 36.271200 + + 79.000000 + 1.666667 + + + 36.271200 + + 78.000000 + 1.666667 + + + 36.271200 + + 80.000000 + 1.666667 + + + 35.661600 + + 83.000000 + 1.666667 + + + 35.661600 + + 81.000000 + 1.666667 + + + 35.966400 + + 78.000000 + 1.666667 + + + 36.271200 + + 86.000000 + 1.666667 + + + 36.271200 + + 82.000000 + 0.000000 + + + 36.880800 + + 80.000000 + 1.666667 + + + 36.880800 + + 82.000000 + 1.666667 + + + 37.185600 + + 82.000000 + 1.666667 + + + 37.490400 + + 82.000000 + 1.666667 + + + 37.185600 + + 84.000000 + 1.666667 + + + 37.185600 + + 84.000000 + 1.666667 + + + 37.185600 + + 84.000000 + 1.666667 + + + 37.185600 + + 83.000000 + 1.666667 + + + 38.404800 + + 84.000000 + 1.666667 + + + 38.404800 + + 86.000000 + 1.666667 + + + 38.404800 + + 86.000000 + 1.666667 + + + 38.404800 + + 84.000000 + 1.666667 + + + 38.404800 + + 84.000000 + 1.666667 + + + 38.404800 + + 83.000000 + 1.666667 + + + 38.404800 + + 81.000000 + 1.666667 + + + 38.100000 + + 85.000000 + 1.666667 + + + 38.100000 + + 85.000000 + 1.666667 + + + 38.100000 + + 78.000000 + 1.666667 + + + 38.100000 + + 82.000000 + 1.666667 + + + 37.795200 + + 79.000000 + 1.666667 + + + 37.490400 + + 80.000000 + 1.666667 + + + 37.185600 + + 84.000000 + 1.666667 + + + 36.880800 + + 75.000000 + 1.666667 + + + 36.880800 + + 79.000000 + 1.666667 + + + 37.185600 + + 78.000000 + 1.666667 + + + 37.185600 + + 86.000000 + 0.000000 + + + 37.185600 + + 86.000000 + 0.000000 + + + 35.966400 + + 94.000000 + 1.666667 + + + 35.966400 + + 94.000000 + 0.000000 + + + 35.966400 + + 94.000000 + 0.000000 + + + 35.052000 + + 57.000000 + 1.666667 + + + 35.052000 + + 57.000000 + 0.000000 + + + 35.052000 + + 55.000000 + 1.111111 + + + 35.966400 + + 68.000000 + 1.666667 + + + 35.966400 + + 59.000000 + 1.111111 + + + 35.966400 + + 50.000000 + 1.111111 + + + 35.966400 + + 50.000000 + 0.000000 + + + 36.880800 + + 59.000000 + 1.666667 + + + 36.576000 + + 64.000000 + 1.666667 + + + 36.880800 + + 70.000000 + 1.111111 + + + 37.185600 + + 68.000000 + 0.555556 + + + 37.490400 + + 56.000000 + 1.111111 + + + 37.185600 + + 51.000000 + 1.111111 + + + 37.490400 + + 63.000000 + 1.666667 + + + 37.185600 + + 64.000000 + 1.666667 + + + 37.185600 + + 64.000000 + 0.000000 + + + 37.185600 + + 64.000000 + 0.000000 + + + 35.966400 + + 64.000000 + 0.000000 + + + 35.661600 + + 64.000000 + 0.000000 + + + 36.271200 + + 64.000000 + 0.000000 + + + 36.271200 + + 64.000000 + 0.000000 + + + 35.052000 + + 64.000000 + 0.000000 + + + 36.576000 + + 57.000000 + 1.111111 + + + 36.880800 + + 53.000000 + 1.111111 + + + 36.576000 + + 57.000000 + 1.666667 + + + 36.576000 + + 53.000000 + 1.666667 + + + 36.576000 + + 52.000000 + 1.666667 + + + 36.576000 + + 50.000000 + 1.666667 + + + 36.880800 + + 50.000000 + 1.111111 + + + 37.185600 + + 48.000000 + 1.111111 + + + 37.490400 + + 50.000000 + 1.666667 + + + 37.795200 + + 45.000000 + 1.666667 + + + 37.490400 + + 46.000000 + 1.666667 + + + 36.880800 + + 47.000000 + 1.666667 + + + 36.576000 + + 56.000000 + 0.000000 + + + 35.356800 + + 56.000000 + 0.000000 + + + 35.356800 + + 56.000000 + 0.000000 + + + 35.661600 + + 107.000000 + 0.555556 + + + 35.966400 + + 126.000000 + 1.111111 + + + 35.966400 + + 103.000000 + 1.111111 + + + 34.747200 + + 104.000000 + 1.111111 + + + 34.442400 + + 81.000000 + 1.666667 + + + 33.832800 + + 18.000000 + 1.666667 + + + 33.528000 + + 23.000000 + 1.666667 + + + 32.918400 + + 20.000000 + 1.111111 + + + 32.918400 + + 20.000000 + 0.000000 + + + 32.918400 + + 20.000000 + 0.000000 + + + 32.004000 + + 18.000000 + 1.111111 + + + 32.004000 + + 18.000000 + 0.000000 + + + 31.699200 + + 18.000000 + 0.000000 + + + 31.699200 + + 18.000000 + 0.000000 + + + 31.699200 + + 18.000000 + 0.000000 + + + 31.394400 + + 18.000000 + 0.000000 + + + 31.699200 + + 18.000000 + 0.000000 + + + 31.699200 + + 18.000000 + 0.000000 + + + 31.699200 + + 18.000000 + 0.000000 + + + 31.394400 + + 18.000000 + 0.000000 + + + 31.394400 + + 18.000000 + 0.000000 + + + 31.394400 + + 18.000000 + 0.000000 + + + 31.699200 + + 18.000000 + 0.000000 + + + 31.699200 + + 18.000000 + 0.000000 + + + 31.699200 + + 18.000000 + 0.000000 + + + 31.699200 + + 18.000000 + 0.000000 + + + 29.565600 + + 18.000000 + 0.000000 + + + 33.223200 + + 15.000000 + 1.111111 + + + 32.308800 + + 16.000000 + 1.111111 + + + 32.308800 + + 16.000000 + 0.000000 + + + 32.308800 + + 16.000000 + 0.000000 + + + 34.442400 + + 17.000000 + 1.111111 + + + 34.747200 + + 14.000000 + 1.111111 + + + 35.052000 + + 16.000000 + 1.111111 + + + 34.747200 + + 18.000000 + 0.000000 + + + 34.747200 + + 18.000000 + 0.000000 + + + 32.918400 + + 38.000000 + 1.111111 + + + 32.918400 + + 61.000000 + 1.111111 + + + 32.308800 + + 62.000000 + 1.111111 + + + 32.004000 + + 40.000000 + 0.555556 + + + 37.490400 + + 0.000000 + 0.000000 + + + 38.709600 + + 0.000000 + 0.000000 + + + 39.928800 + + 0.000000 + 0.000000 + + + 39.319200 + + 0.000000 + 0.000000 + + + 37.490400 + + 0.000000 + 0.000000 + + + 38.100000 + + 0.000000 + 0.000000 + + + 41.148000 + + 0.000000 + 0.000000 + + + 42.062400 + + 0.000000 + 0.000000 + + + 43.586400 + + 0.000000 + 0.000000 + + + 45.110400 + + 0.000000 + 0.000000 + + + 45.110400 + + 0.000000 + 0.000000 + + + 45.110400 + + 0.000000 + 0.000000 + + + 44.805600 + + 0.000000 + 0.000000 + + + 43.586400 + + 0.000000 + 0.000000 + + + 42.976800 + + 0.000000 + 0.000000 + + + 42.062400 + + 35.000000 + 1.111111 + + + 42.367200 + + 28.000000 + 1.111111 + + + 42.672000 + + 16.000000 + 1.666667 + + + 42.367200 + + 17.000000 + 1.666667 + + + 41.452800 + + 21.000000 + 1.666667 + + + 41.757600 + + 22.000000 + 1.666667 + + + 41.757600 + + 29.000000 + 1.666667 + + + 41.452800 + + 34.000000 + 1.666667 + + + 41.148000 + + 36.000000 + 0.000000 + + + 40.843200 + + 65.000000 + 1.666667 + + + 41.148000 + + 65.000000 + 1.666667 + + + 40.843200 + + 68.000000 + 1.666667 + + + 40.843200 + + 71.000000 + 1.666667 + + + 40.843200 + + 78.000000 + 1.666667 + + + 41.148000 + + 80.000000 + 1.111111 + + + 41.452800 + + 82.000000 + 1.666667 + + + 41.452800 + + 85.000000 + 1.666667 + + + 41.148000 + + 53.000000 + 1.111111 + + + 41.148000 + + 37.000000 + 1.666667 + + + 40.538400 + + 5.000000 + 1.666667 + + + 40.538400 + + 4.000000 + 1.666667 + + + 41.452800 + + 288.000000 + 1.111111 + + + 41.452800 + + 290.000000 + 1.111111 + + + 41.757600 + + 279.000000 + 0.000000 + + + 42.062400 + + 279.000000 + 0.000000 + + + 42.367200 + + 295.000000 + 0.555556 + + + 42.672000 + + 299.000000 + 1.111111 + + + 42.672000 + + 300.000000 + 1.111111 + + + 43.281600 + + 308.000000 + 1.666667 + + + 43.281600 + + 308.000000 + 1.666667 + + + 43.586400 + + 316.000000 + 1.666667 + + + 43.586400 + + 323.000000 + 1.666667 + + + 43.281600 + + 327.000000 + 1.666667 + + + 43.281600 + + 320.000000 + 1.666667 + + + 43.586400 + + 327.000000 + 1.666667 + + + 43.586400 + + 331.000000 + 1.666667 + + + 43.891200 + + 324.000000 + 1.666667 + + + 44.196000 + + 327.000000 + 1.666667 + + + 44.500800 + + 342.000000 + 1.666667 + + + 44.196000 + + 353.000000 + 1.666667 + + + 44.196000 + + 3.000000 + 1.666667 + + + 43.281600 + + 15.000000 + 1.666667 + + + 42.672000 + + 19.000000 + 1.666667 + + + 42.062400 + + 20.000000 + 1.111111 + + + 42.062400 + + 20.000000 + 1.666667 + + + 41.757600 + + 25.000000 + 0.000000 + + + 41.757600 + + 26.000000 + 1.111111 + + + 42.062400 + + 26.000000 + 1.111111 + + + 42.367200 + + 29.000000 + 1.111111 + + + 42.062400 + + 23.000000 + 1.111111 + + + 42.367200 + + 22.000000 + 1.111111 + + + 42.062400 + + 22.000000 + 1.111111 + + + 41.148000 + + 29.000000 + 1.111111 + + + 40.233600 + + 29.000000 + 1.111111 + + + 40.233600 + + 29.000000 + 1.111111 + + + 40.233600 + + 21.000000 + 1.111111 + + + 40.538400 + + 23.000000 + 1.111111 + + + 40.843200 + + 23.000000 + 1.111111 + + + 41.452800 + + 27.000000 + 1.111111 + + + 40.843200 + + 27.000000 + 1.111111 + + + 39.319200 + + 30.000000 + 1.111111 + + + 38.709600 + + 31.000000 + 1.666667 + + + 38.100000 + + 40.000000 + 1.666667 + + + 37.795200 + + 45.000000 + 1.666667 + + + 36.880800 + + 64.000000 + 1.666667 + + + 36.880800 + + 73.000000 + 1.666667 + + + 37.795200 + + 77.000000 + 1.666667 + + + 38.100000 + + 77.000000 + 1.666667 + + + 38.709600 + + 74.000000 + 1.666667 + + + 37.490400 + + 69.000000 + 1.666667 + + + 37.185600 + + 69.000000 + 1.666667 + + + 36.576000 + + 56.000000 + 1.666667 + + + 36.271200 + + 58.000000 + 1.666667 + + + 35.966400 + + 48.000000 + 1.666667 + + + 35.966400 + + 49.000000 + 1.666667 + + + 35.356800 + + 32.000000 + 1.666667 + + + 35.052000 + + 34.000000 + 1.111111 + + + 35.356800 + + 24.000000 + 1.666667 + + + 35.052000 + + 20.000000 + 1.666667 + + + 34.747200 + + 17.000000 + 1.666667 + + + 35.356800 + + 13.000000 + 1.666667 + + + 36.271200 + + 359.000000 + 1.666667 + + + 36.576000 + + 1.000000 + 1.666667 + + + 37.795200 + + 357.000000 + 1.666667 + + + 38.404800 + + 353.000000 + 1.666667 + + + 38.404800 + + 353.000000 + 1.666667 + + + 38.100000 + + 0.000000 + 1.666667 + + + 38.100000 + + 10.000000 + 1.666667 + + + 37.795200 + + 92.000000 + 1.111111 + + + 37.795200 + + 46.000000 + 1.111111 + + + 38.404800 + + 186.000000 + 0.000000 + + + 38.709600 + + 186.000000 + 0.000000 + + + 38.709600 + + 186.000000 + 0.000000 + + + 38.709600 + + 186.000000 + 0.000000 + + + 37.490400 + + 186.000000 + 0.000000 + + + 36.576000 + + 186.000000 + 0.000000 + + + 33.832800 + + 186.000000 + 0.000000 + + + 33.528000 + + 186.000000 + 0.000000 + + + 33.223200 + + 326.000000 + 0.000000 + + + 34.137600 + + 309.000000 + 1.111111 + + + 34.137600 + + 312.000000 + 0.000000 + + + 33.832800 + + 29.000000 + 1.666667 + + + 33.832800 + + 29.000000 + 0.000000 + + + 33.223200 + + 64.000000 + 1.666667 + + + 33.223200 + + 68.000000 + 1.666667 + + + 33.528000 + + 59.000000 + 1.111111 + + + 33.528000 + + 59.000000 + 1.666667 + + + 34.442400 + + 61.000000 + 1.666667 + + + 34.747200 + + 60.000000 + 1.666667 + + + 35.661600 + + 64.000000 + 1.666667 + + + 35.661600 + + 66.000000 + 1.666667 + + + 36.880800 + + 69.000000 + 1.666667 + + + 37.490400 + + 74.000000 + 1.666667 + + + 39.014400 + + 66.000000 + 1.666667 + + + 39.624000 + + 67.000000 + 1.666667 + + + 39.624000 + + 67.000000 + 0.000000 + + + 41.452800 + + 58.000000 + 1.666667 + + + 41.148000 + + 46.000000 + 1.666667 + + + 40.538400 + + 45.000000 + 1.666667 + + + 40.538400 + + 44.000000 + 1.666667 + + + 39.624000 + + 40.000000 + 1.666667 + + + 39.319200 + + 43.000000 + 1.666667 + + + 38.100000 + + 42.000000 + 1.666667 + + + 37.795200 + + 46.000000 + 1.666667 + + + 37.490400 + + 19.000000 + 1.666667 + + + 37.795200 + + 13.000000 + 1.666667 + + + 38.404800 + + 11.000000 + 1.666667 + + + 38.404800 + + 15.000000 + 1.666667 + + + 38.100000 + + 48.000000 + 1.111111 + + + 38.100000 + + 36.000000 + 1.111111 + + + 38.404800 + + 24.000000 + 1.111111 + + + 39.014400 + + 20.000000 + 1.111111 + + + 39.319200 + + 20.000000 + 1.111111 + + + 39.928800 + + 20.000000 + 0.000000 + + + 40.538400 + + 36.000000 + 1.111111 + + + 40.538400 + + 44.000000 + 1.666667 + + + 40.538400 + + 43.000000 + 1.111111 + + + 40.233600 + + 48.000000 + 1.666667 + + + 39.928800 + + 51.000000 + 1.111111 + + + 39.624000 + + 47.000000 + 1.666667 + + + 39.624000 + + 48.000000 + 1.666667 + + + 39.014400 + + 49.000000 + 1.666667 + + + 39.014400 + + 48.000000 + 1.666667 + + + 38.100000 + + 48.000000 + 1.666667 + + + 37.795200 + + 45.000000 + 1.666667 + + + 37.490400 + + 46.000000 + 1.666667 + + + 37.185600 + + 52.000000 + 1.666667 + + + 37.185600 + + 54.000000 + 1.666667 + + + 36.576000 + + 54.000000 + 1.111111 + + + 36.576000 + + 58.000000 + 1.666667 + + + 36.880800 + + 51.000000 + 1.666667 + + + 36.880800 + + 55.000000 + 1.666667 + + + 36.576000 + + 56.000000 + 1.666667 + + + 36.271200 + + 54.000000 + 1.666667 + + + 36.880800 + + 55.000000 + 1.666667 + + + 36.880800 + + 51.000000 + 1.666667 + + + 35.966400 + + 56.000000 + 1.666667 + + + 35.661600 + + 60.000000 + 1.666667 + + + 35.661600 + + 55.000000 + 1.666667 + + + 35.356800 + + 55.000000 + 1.666667 + + + 35.661600 + + 61.000000 + 1.666667 + + + 36.271200 + + 62.000000 + 1.666667 + + + 36.271200 + + 59.000000 + 1.666667 + + + 36.576000 + + 60.000000 + 1.666667 + + + 37.185600 + + 57.000000 + 1.666667 + + + 39.319200 + + 60.000000 + 1.111111 + + + 39.624000 + + 61.000000 + 1.111111 + + + 39.928800 + + 55.000000 + 1.666667 + + + 39.928800 + + 59.000000 + 1.666667 + + + 39.624000 + + 54.000000 + 1.111111 + + + 39.319200 + + 56.000000 + 1.111111 + + + 38.404800 + + 62.000000 + 1.666667 + + + 37.795200 + + 61.000000 + 1.111111 + + + 36.576000 + + 35.000000 + 1.666667 + + + 35.966400 + + 11.000000 + 1.666667 + + + 35.966400 + + 346.000000 + 1.666667 + + + 36.880800 + + 341.000000 + 1.666667 + + + 37.490400 + + 334.000000 + 1.666667 + + + 38.709600 + + 335.000000 + 1.666667 + + + 39.014400 + + 335.000000 + 1.111111 + + + 39.624000 + + 349.000000 + 1.111111 + + + 39.928800 + + 11.000000 + 1.666667 + + + 41.452800 + + 2.000000 + 1.666667 + + + 42.062400 + + 5.000000 + 1.666667 + + + 42.672000 + + 1.000000 + 1.666667 + + + 42.672000 + + 354.000000 + 1.666667 + + + 42.976800 + + 348.000000 + 1.666667 + + + 42.976800 + + 175.000000 + 1.111111 + + + 43.586400 + + 45.000000 + 0.555556 + + + + diff --git a/reference/navilink_tracks.trk b/reference/navilink_tracks.trk new file mode 100755 index 0000000000000000000000000000000000000000..13ba97ffa0695831830a95b0105bcf6174938f77 GIT binary patch literal 11040 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 literal 0 HcmV?d00001 diff --git a/reference/navilink_tracks_gpx.trk b/reference/navilink_tracks_gpx.trk new file mode 100755 index 0000000000000000000000000000000000000000..e03359d89d15029917642617f41a7dae8cb00bd4 GIT binary patch literal 11040 zcmZ|Vd7RJH{=o6`nZ+>ko$oLh>l_TjF!p_nWo*g5WJ_6+knAnC>?$gusAwg1qpohZ zbR|?|3AvH*{aA}!EkY_w`F?({^ZqPT9>4kf`FNjmKIfeG*}h*(DYarpqIzplKQ;fO zh@O`fb(Bg-j4f)F&}zVpn1Vgccx=I5+ISrP66L?`m4CT<)VbF!zqaxCzxeaiZ+x`t zb&VG)*y|fl_=~Uc;-|Usjf@w*$>VB7o$;%e2nWk+8Qt;QB_y3 z;Ol7rgiR6MGdpNsuJI&QN3F!)#hY%9=$C6oo%RI&+sXD#}-lN z0oO|!Ps2aOx8uk0nysSFL#~%HUP^US+wmQE-e(bAv~|>(?0OmFrBxTT)AONtcALP< znei_}{9b$)@mKNA?E_CY@nuzS^(Fo}p1VDw=X8iVliczv7%!)~tAqG%dejmfWU{1`qPZ#OOKJnYtA&Wv9Z=3j06IKB$6 zHr<~ev68<{>7RO@zlVQ6BN#u)-yGFhHN;O4{~f+!mOnpZC4ZYye^bx1_C)k6a{`zA z&E@-Y@sq?)!&lD>%9s3Y&iJ;#PvI}(?>rKCHIqLr3ij&8TdF~-y;uK1+IM|{pTDt^ zzpV=PS|&cPV3+)D&HmDl^3T$~L0?4l=S%(dIku_k-!=t%GgE$B)kNJ%{13#xy)UBQ zc+QWHQ)Yi`r`oB(_)mDf|3-BG<$n9)Vodq%RjwL}pU0QshgSq1XX0;B_0=%^0-pV4 zM901ucp>8*3iiULeYaBnDB^!1K68IWKlF+}esPJW{*LTlWAMxPT0Co|zy8OCjCWGE zsPXu(c=!PQzbc3ioBBKReG~ED@S%AB)&BU#6*b;PHB}GdSMWplve*6j8JB9jt7@Po z;n(n|zT*7zMi5`ZcsKUnsrVmw`-80iZwB#crhVOM|8)EYZsU{I2Jxkh_rPc3Q9S)? z_OG`BFKhazXTe_HcrW}(;^P=-b{4`oD(p+ivpKxVt~a)imDQ^FqXLAigf{ z?w@gT{_9h)%lWS_zL5G8h%a}9?K`wm&SMCQ#bqVi;p+$8>H&0SMjp=m=h8G z!4`k~;uDMyCVmxO9xri{{pVwUe#FcEF+|l;t8tC*!Sg=#*Uxy_Kkibs)f;$4{Fze` z{nXYVUiOcnoKN4xGw@E|MD+P>LHlI?xSRRC7O#xIjKB6-@O{P1_zc6}#;f2l-$r!C z4*z@?U)=aT1$#;3!_|H2pTuVp--r0ehz4 z{c?Z0AO8$*h2Ox{!N7A&`yMFRbB#ZU?LP`vSn@I81Je87c> z{?`$|{6Y!FCl%~Pj887ulZ;Qn4^jRQ%J2DmME5=!)GznjsRg^-Z>JUPvc5iyAEo@^ zl;8JiL|^zOXuqtl(>))F>udDiw}ETZz8M93MdLFI_6*~*@N?9^g7OC^+WN5{qRw5? zzX`HG&Q>YvJiZ#goNVi7&-?e^ghVqx=BT3TC;T;hCZ2)2_t%7w@wo+i*wjC-U@vO? z5mik6O!@05zhN<3kNerruLRj2A5~%Tck#SbTW`hP`(=XckB?FQ1>)bsbBf!#$pwFZ zNJum7o6q+fUyrZDr{Z3`jNgKSUB>TmRaIRfejD+NOWV5huYP_eWSH`w;C_7_{|rBa zZ~QIrD#o8wE!Cg+cDzX$TW4Jf`cLwEp~_NGdQ5#FLhnkujl{b&AspUT+YACale1B(SPOhx?))f{Z2IpF)mnw{b9k>zTQ66R^Qc>Y zQPaME;K}&+_%eKs<@oV(e|?klc`E)R-n^=bEp!|wve!QbHRaN{Kymc1epAxv-U;m}z#ec{5SGRTP zqK@;3+kbNYcvr=#YQ$f~N7S%&^?aB6>%Ub+%hdlTelXkCt0~``AF@8Zr!uT6_zk>N zOPr3cm z*o@Ccyc8aTcdu>h#f-n_^8WOZYHpeN6OVVSW9t{0KW_dPX=dU#skWAxe}(WZc&U7s z`@?3{!77R;;x+3rzhnLK6D5DQs5~nLPr_H?srfGX`!Vq*KT>d~zO5%R|K0i%C4WCr zovkFi7(TB7^N0NLT=Mr*)y^u6m&7kOv~?FJ>MWM;Pn7)KO8F)~)9{gvY`r5Ib(Xj; z`MXW^wc_xy`2QN)`YrPJY1hN%`#)26iKpY2nz;Gz#Y_HfSFy^(SHR~twRL~uJ(v95 z!TH2^Wjv>ut&ihw|0hcR?o`EP{mI0);B{%AJN}81zq>deoAsv#KDfE9%kq8h{7Nis z#{YBNd|x(x2EQ}k<^5^5Dx*yQ)W$cru=OvvyZ$B0{<}w&6|alG(bCqF>0i&&P5FCq z)Bg?exI9~LXMDW+C4awQ{WRVfpMp1w@#lA9B@@4o`-55En&IbK+qxa&@5Rgc;=ioV zVLTTf)5g|oa5p~^Gfn)LxS2mK@eys=Us(UV_-e-YQ@`=ncwReOe~r8AZ=&Sy0lXOA z4j`W&OS#|DcPlGg&{}^G~AezqYC%J^;_|>aO4J`6^NJ_bBH#v;GXm z*LHK)H~0LLB>8)c`?to2;K|)>{Uz(0`+k`u`FouAjST#5yl@Y9eRki^lO%snsE(>K zJ`C@SUt)dsT=Ms%>Z+>a!|`wM6UBq_C4W!h*`62gY3u7H9PfOVB>DS|>ZI!8BZ*&w z*C_3H=f@<;-*5T-rU8C0{wIE;jN`q(CrSRE#v9?I@Y=m>eYULQz27HE{+{7}pM#Ia z&*DSU9q;#ro?|mpq^7kz7A1(3mct&qqcdO`lzyBo3{`)^w zPqo4);E&?J=DXzYIaN`$!5_r8_2K-I;ds9fh*|N6#%Rjdv83;3YBZGAr9<@cZ8)Scq5;?6KzSD<{aeUiVw^FC$bSK;&S z`I}4rUQrvR{?+)v;eTsiGjo2t`v16_ze)1`aIHWO#hCc(xT)WiKZEkk__*<*SmS@( zw5y;315%rjJEZJtia{`T-a)%y5k%0wqw};vK{aJE+qL|#A>d3 z;2+{|;!SJ%`5BV@O{D#O@Xh$vv9^w@<9P3nAvr%MS#4Bbd<&j7j`K;rOa6we_WUl$ z@8kFdd~JPy{SHa~CR?4Sm@(s<6-4TAY2`5UJEyYOxJH9Wns9_a)mHc6pX0~zBe;7$ z2uc1Hw`!?z_!oHD2gv^x{{9`3^K%KSrW%j$!>8jDTLv!Y=aN>Ix*tD)AA8W&jq-x_ z%lSFY%2p5HU*WADvh{A<-Je6U|CX|9s7d%?{NYKqUf0H7f0AYYElv9;<45pIc)Pa# z`jRaBZyBqνI8yHDYM*Us<%WZ8eqTFGh}eggjvPir5<%l=!=N)kVf@0w=oCvbOt zOqTt(yp^IJCjL8o+{27dzRUibZq-#Y@bB?W(``MdL(qQteMwtY)GYi*{QeoXo^os8 zlD`$K(rPw-9&bL=)<5H3{qlZR(JGdS$P`C4XyJ_0&>44i7y>|Md>~Px3dL_-FBW zd@!EfCveH%n)q_OFn;@d_OE`y_(}fOB7a`MlkiFlIREz#=9lDeZRYQbcnE(4-;cZd zOS0_0b*zT!6+8uB{J5=O8{nV6k|lrZT8-7Kcv1W`-sz6OC4cMTui>fqrYBe*2m1R{ zvh2V0Ssz}a=t3(NVr1^d%hygJ_G8C#ba7sRKU^HWQ!rP_{X z<0tVQ*TrYz z7jgIhH(}X-+YtXH-T;66S=P5n{`wG>{kJXcKY%yHPvFBQ`}q@={B6hgAHtj9JD=ly zV5*;=Vaeb2wEr;P6fgU{t%ptvT=w5v82_VqGyF0>d3sR3+ za{s-R{yT-Yz>nd5X8G%5Sn{_c?f(XEiC0)*>(FdJ|H5+r?POI}XYkf|;TPziIYIwP z{_?t_zQfz%m+*V$2J=Vqw~IBvGTs4Cf9Y>t*NkshtB+;M?}QI{nfXQe?)@$-`PYAbpF#NG2lSkBKq zt%24_ydS=6mD@k=`5`R#-(Gy5@&5Rr*K9qX{&Rmn2uuFnX2nSV4#Hc%?w0Sq|D{O& z_O{~12jhqE?$qzTKcqm6zTeR%3xTif}bWcIh)S$|FcjKjOXW$W40@4k + + + + + 67.970400 + + M000 + M000 + M000 + Star + + + 67.970400 + + M000 + M000 + M000 + Star + + + 0.000000 + + M001 + M001 + M001 + Star + + + 0.000000 + + M001 + M001 + M001 + Star + + + 36.271200 + + M002 + M002 + M002 + Star + + + 36.271200 + + M002 + M002 + M002 + Star + + + 35.356800 + + SUBWAY + SUBWAY + SUBWAY + Star + + + 35.356800 + + SUBWAY + SUBWAY + SUBWAY + Star + + diff --git a/reference/navilink_waypoints.wpt b/reference/navilink_waypoints.wpt new file mode 100755 index 0000000000000000000000000000000000000000..0dd8f06dccc80daf55d26c8a069ea8a08aa65017 GIT binary patch literal 256 zcmZQ@U|{eyFfd>Mg4wRO<&35=Fx+Qg=alAERRapuF*vYbljmXMg4wRO<&35=Fx+Qg=alAERRapuF<_VHVisgEMUpoJvKfSe@5q^K z2eH^WW%+cOfDD*^ba{0BMj%}~uHTe1*!=H*IRiTvvj7XoO)&kK@<{dvhdPBjMlvuk XJ-R8UbnM^%60m-D9+-Zt@=*N%8o)D! literal 0 HcmV?d00001 diff --git a/reference/netstumbler.mps b/reference/netstumbler.mps new file mode 100644 index 0000000000000000000000000000000000000000..c313182348d1eae58d4d4ff2e7046dd3296e030e GIT binary patch literal 4838 zcmb7IONbm*6s=JaC5wm%;s@=A5CVoCddeM&qAUc;BmB?Y-pt7t=9Hy=yHe3B8l}2I>!6#U>&ol=|IK!=em2|+ z`Q_+y8+{Zd`Lg(4OyKKd-=t3{s#;lgx?y#`Rk5nn2Wo+4LaheW1J(ckF=b|Sd05^W zyE@OmH9h9r{q~0Z2a11t2!LIP$=lx}0CZn`6HE_$8+;vfL#{L_{+mhslN-!#Z?vka zd@qaO@f^$;6c3(buL1liYas`3Ly;If!kRx1MuLF5xMmg0&kpPu}&Erp@0Z|2~EsLV!&4!=XA~ zpL9DLrR>js8$1p2U-F_bD*w*n}eb#6R#y)YzBT%#=&FfV{+&>6g{^V4Lz}> zh9_5=ln7ymUfAt+Hd#-;mQBL%PY%d@fBRpc0inuMN(aOLL#30DyWq=aE1q^8Kr zv4(bYAPB8aKV+{?7|ynT84x&;4?z>Y?DLrnsKW~p=oGamTGMDcs3P{VEIh=u@XP{& zfV40+ANXL`_?#jcJrE7)IRSZU7DGbAI?cy`3WB>ry#^|(tw|6>L97OD%kCi+X92wX z!+`v81OY%&u&M^HLJevjZ~zVkV+vEa!0Bo>gC1+MFf8}wcdib|%d-eWK_c`9*nC(< zNu9)knABG~J?{+atJ9K@9NERB&TMe_X)PxUMXn$k!$xOKN+%n9cP}Q}?;}r?ePN_R zVM!KEYaoSNYEs7N5|; zpmM1+_eI>Nr$p9n%a^iyzx)1}&>ciSijOKV`LTcx={fO>>{#^Wv;fKw+#AN^`ak&y agd6j7GC!p9Q+kb`RHi_X{IK<+GV>p=4wgOu literal 0 HcmV?d00001 diff --git a/reference/netstumbler.txt b/reference/netstumbler.txt new file mode 100644 index 000000000..712999c3b --- /dev/null +++ b/reference/netstumbler.txt @@ -0,0 +1,42 @@ +# $Creator: Network Stumbler Version 0.4.0 +# $Format: wi-scan summary with extensions +# Latitude Longitude ( SSID ) Type ( BSSID ) Time (GMT) [ SNR Sig Noise ] # ( Name ) Flags Channelbits BcnIntvl DataRate LastChannel +# $DateGMT: 2004-06-05 +N 47.7111183 W 91.0121750 ( linksys ) BSS ( 0f:06:25:77:0d:1f ) 01:22:09 (GMT) [ 24 73 49 ] # ( ) 0001 00000040 100 110 6 +N 47.7108850 W 91.0120617 ( default ) BSS ( 0f:05:5d:fa:f3:34 ) 01:22:18 (GMT) [ 26 75 49 ] # ( ) 0401 00000040 100 0 6 +N 47.7096033 W 91.0143300 ( ) BSS ( 0f:40:96:44:c0:cc ) 01:24:16 (GMT) [ 16 65 49 ] # ( ) 0011 00000040 100 110 6 +N 47.7088850 W 91.0146683 ( msu88 ) BSS ( 0f:0c:41:bc:2a:8c ) 01:24:31 (GMT) [ 36 85 49 ] # ( ) 0005 00000040 100 110 6 +N 47.7077150 W 91.0151333 ( linksys ) BSS ( 0f:06:25:a4:77:2e ) 01:24:53 (GMT) [ 25 74 49 ] # ( ) 0001 00000040 100 110 6 +N 47.7072867 W 91.0152633 ( default ) BSS ( 0f:0d:88:8d:16:4f ) 01:25:04 (GMT) [ 32 81 49 ] # ( ) 0421 00000040 100 540 6 +N 47.7069517 W 91.0153133 ( silicon ) BSS ( 0f:30:bd:c1:3b:16 ) 01:25:10 (GMT) [ 29 78 49 ] # ( ) 0011 00000040 100 110 6 +N 47.7066100 W 91.0153683 ( purnet ) BSS ( 0f:0c:41:ab:45:66 ) 01:25:19 (GMT) [ 20 69 49 ] # ( ) 0401 00000040 100 540 6 +N 47.7066783 W 91.0157867 ( Harvey ) BSS ( 0f:0d:88:1e:a5:6e ) 01:25:30 (GMT) [ 13 62 49 ] # ( ) 0001 00000100 100 110 8 +N 47.7066550 W 91.0136367 ( X6604 ) BSS ( 0f:a0:c5:69:65:10 ) 01:26:19 (GMT) [ 17 66 49 ] # ( ) 0001 00000040 100 110 6 +N 47.7067600 W 91.0133900 ( Scott ) BSS ( 0f:0d:93:88:3f:c1 ) 01:26:39 (GMT) [ 17 66 49 ] # ( ) 0411 00000400 100 540 10 +N 47.7070583 W 91.0128933 ( NETGEAR ) BSS ( 0f:09:5b:6e:59:90 ) 01:26:44 (GMT) [ 25 74 49 ] # ( ) 0005 00000800 100 110 11 +N 47.7069967 W 91.0129867 ( ) BSS ( 00:05:5d:fb:02:bf ) 01:26:49 (GMT) [ 15 64 49 ] # ( ) 0411 00000020 100 540 5 +N 47.7062300 W 91.0118067 ( cones ) BSS ( 0f:40:96:25:a2:b1 ) 01:38:14 (GMT) [ 15 64 49 ] # ( ) 0001 00000040 100 20 6 +N 47.7028750 W 91.0082767 ( default ) BSS ( 0f:0f:3d:00:d2:3f ) 01:39:23 (GMT) [ 25 74 49 ] # ( ) 0421 00000040 100 540 6 +N 47.7118350 W 91.0108833 ( McKee ) BSS ( 0f:0c:41:74:6b:96 ) 01:49:38 (GMT) [ 15 64 49 ] # ( ) 0431 00000008 100 540 3 +N 47.7117300 W 91.0109350 ( airport ) BSS ( 0f:0a:95:f2:aa:0e ) 02:22:33 (GMT) [ 16 65 49 ] # ( ) 0011 00000400 100 540 10 +N 47.7116383 W 91.0109933 ( merv ) BSS ( 0f:06:25:f0:e0:85 ) 02:22:36 (GMT) [ 26 75 49 ] # ( ) 0005 00000040 100 110 6 +N 47.7109717 W 91.0113083 ( home network ) BSS ( 0f:0f:66:2d:d0:bf ) 02:22:45 (GMT) [ 16 65 49 ] # ( ) 0001 00000040 100 540 6 +N 47.7108867 W 91.0113450 ( ) BSS ( 0f:02:2d:2b:81:cf ) 02:22:55 (GMT) [ 13 62 49 ] # ( ) 0011 00000002 100 110 1 +N 47.7107717 W 91.0115567 ( wifi ) BSS ( 0f:40:96:43:5b:9d ) 02:23:02 (GMT) [ 15 64 49 ] # ( ) 0001 00000040 100 20 6 +N 47.7144783 W 91.0139767 ( dsppower ) BSS ( 0f:06:25:f7:6c:c9 ) 02:32:40 (GMT) [ 22 71 49 ] # ( ) 0401 00000040 100 540 6 +N 47.7144567 W 91.0140100 ( linksys ) BSS ( 0f:0c:41:3e:1a:e8 ) 02:32:41 (GMT) [ 15 64 49 ] # ( ) 0005 00000040 100 110 6 +N 47.7182617 W 90.9985767 ( CAMELOT ) BSS ( 0f:06:25:05:24:3d ) 02:44:44 (GMT) [ 25 74 49 ] # ( ) 0011 00000040 100 110 6 +N 47.7181417 W 90.9975217 ( linksys ) BSS ( 0f:0c:41:b6:fe:62 ) 02:44:44 (GMT) [ 16 65 49 ] # ( ) 0005 00000040 100 110 6 +N 47.7182317 W 90.9979867 ( linksys ) BSS ( 0f:0c:41:74:d0:76 ) 02:44:48 (GMT) [ 21 70 49 ] # ( ) 0401 00000002 100 540 1 +N 47.7182467 W 90.9981417 ( house_net ) BSS ( 0f:0f:66:0b:cf:0f ) 02:44:49 (GMT) [ 18 67 49 ] # ( ) 0411 00000004 100 540 2 +N 47.7182600 W 90.9982917 ( NETGEAR ) BSS ( 0f:09:5b:6f:a7:88 ) 02:44:53 (GMT) [ 19 68 49 ] # ( ) 0005 00000800 100 110 11 +N 47.7182467 W 90.9987167 ( linksys ) BSS ( 0f:0c:41:43:87:14 ) 02:44:53 (GMT) [ 22 71 49 ] # ( ) 0005 00000040 100 110 6 +N 47.7178833 W 90.9989217 ( Richard ) ad-hoc ( 4a:e2:7d:43:b0:49 ) 02:45:06 (GMT) [ 20 69 49 ] # ( ) 0422 00000040 100 540 6 +N 47.7179900 W 90.9988900 ( Wireless ) BSS ( 0f:09:5b:39:ae:a2 ) 02:45:06 (GMT) [ 17 66 49 ] # ( ) 0001 00000800 100 110 11 +N 47.7178833 W 90.9989217 ( Nordge ) BSS ( 0f:0d:88:ea:b7:24 ) 02:45:08 (GMT) [ 21 70 49 ] # ( ) 0431 00000040 100 540 6 +# $DateGMT: 2004-06-06 +N 47.7133767 W 91.0131567 ( tom ) BSS ( 0f:06:25:60:6c:b1 ) 03:26:38 (GMT) [ 43 92 49 ] # ( ) 0001 00000800 50 20 11 +N 47.7133767 W 91.0131567 ( default ) BSS ( 0f:0d:88:86:cf:c9 ) 03:26:38 (GMT) [ 14 63 49 ] # ( ) 0041 00000040 100 220 6 +N 47.7133767 W 91.0131567 ( JJ ) BSS ( 0f:60:1d:f6:90:40 ) 03:26:38 (GMT) [ 14 63 49 ] # ( ) 0011 00000002 100 110 1 +N 47.7085167 W 91.0134633 ( purell ) BSS ( 0f:0c:41:bc:2b:00 ) 03:32:42 (GMT) [ 20 69 49 ] # ( ) 0005 00000040 100 110 6 +N 47.7105983 W 91.0111967 ( Wireless ) BSS ( 0f:30:ab:16:7e:50 ) 03:38:38 (GMT) [ 27 76 49 ] # ( ) 0001 00000002 100 110 1 diff --git a/reference/nokia.lmx b/reference/nokia.lmx new file mode 100644 index 000000000..1807707b9 --- /dev/null +++ b/reference/nokia.lmx @@ -0,0 +1,112 @@ + + + + GCEBB + Mountain Bike Heaven by susy1313 + + 35.972033 + -87.134700 + + + Cache Details + http://www.geocaching.com/seek/cache_details.asp?ID=3771 + + + + GC1A37 + The Troll by a182pilot & Family + + 36.090683 + -86.679550 + + + Cache Details + http://www.geocaching.com/seek/cache_details.asp?ID=6711 + + + + GC1C2B + Dive Bomber by JoGPS & family + + 35.996267 + -86.620117 + + + Cache Details + http://www.geocaching.com/seek/cache_details.asp?ID=7211 + + + + GC25A9 + FOSTER by JoGPS & Family + + 36.038483 + -86.648617 + + + Cache Details + http://www.geocaching.com/seek/cache_details.asp?ID=9641 + + + + GC2723 + Logan Lighthouse by JoGps & Family + + 36.112183 + -86.741767 + + + Cache Details + http://www.geocaching.com/seek/cache_details.asp?ID=10019 + + + + GC2B71 + Ganier Cache by Susy1313 + + 36.064083 + -86.790517 + + + Cache Details + http://www.geocaching.com/seek/cache_details.asp?ID=11121 + + + + GC309F + Shy's Hill by FireFighterEng33 + + 36.087767 + -86.809733 + + + Cache Details + http://www.geocaching.com/seek/cache_details.asp?ID=12447 + + + + GC317A + GittyUp by JoGPS / Warner Parks + + 36.057500 + -86.892000 + + + Cache Details + http://www.geocaching.com/seek/cache_details.asp?ID=12666 + + + + GC317D + Inlighting by JoGPS / Warner Parks + + 36.082800 + -86.867283 + + + Cache Details + http://www.geocaching.com/seek/cache_details.asp?ID=12669 + + + + diff --git a/reference/osm-data.gpx b/reference/osm-data.gpx new file mode 100644 index 000000000..ec340dbea --- /dev/null +++ b/reference/osm-data.gpx @@ -0,0 +1,400 @@ + + + + + + + osm-id 250870628 + osm-id 250870628 + osm-id 250870628 + + + + osm-id 21585826 + osm-id 21585826 + osm-id 21585826 + + + + osm-id 21585827 + osm-id 21585827 + osm-id 21585827 + + + + osm-id 21324374 + osm-id 21324374 + osm-id 21324374 + + + + osm-id 245339 + osm-id 245339 + osm-id 245339 + + + + osm-id 245353 + osm-id 245353 + osm-id 245353 + + + + osm-id 398692 + osm-id 398692 + osm-id 398692 + + + + osm-id 398694 + osm-id 398694 + osm-id 398694 + + + + osm-id 398704 + osm-id 398704 + osm-id 398704 + + + + osm-id 398705 + osm-id 398705 + osm-id 398705 + + + + osm-id 398710 + osm-id 398710 + osm-id 398710 + + + + osm-id 19404292 + osm-id 19404292 + osm-id 19404292 + + + + osm-id 21040287 + osm-id 21040287 + osm-id 21040287 + + + + osm-id 21040288 + osm-id 21040288 + osm-id 21040288 + + + + osm-id 21040289 + osm-id 21040289 + osm-id 21040289 + + + + osm-id 21040291 + osm-id 21040291 + osm-id 21040291 + + + + osm-id 21040296 + osm-id 21040296 + osm-id 21040296 + + + + osm-id 21324375 + osm-id 21324375 + osm-id 21324375 + + + + osm-id 21324376 + osm-id 21324376 + osm-id 21324376 + + + + osm-id 21324380 + osm-id 21324380 + osm-id 21324380 + + + + osm-id 21324381 + osm-id 21324381 + osm-id 21324381 + + + + osm-id 21324382 + osm-id 21324382 + osm-id 21324382 + + + + osm-id 21585828 + osm-id 21585828 + osm-id 21585828 + + + + osm-id 21632176 + osm-id 21632176 + osm-id 21632176 + + + + osm-id 21632177 + osm-id 21632177 + osm-id 21632177 + + + + osm-id 250870622 + osm-id 250870622 + osm-id 250870622 + + + + osm-id 250870624 + osm-id 250870624 + osm-id 250870624 + + + + osm-id 250870626 + osm-id 250870626 + osm-id 250870626 + + + Arnulfstraße + osm-id 4020271 + + + osm-id 21324374 + osm-id 21324374 + osm-id 21324374 + + + + osm-id 21324376 + osm-id 21324376 + osm-id 21324376 + + + + osm-id 398692 + osm-id 398692 + osm-id 398692 + + + + osm-id 21324380 + osm-id 21324380 + osm-id 21324380 + + + + osm-id 21324381 + osm-id 21324381 + osm-id 21324381 + + + + osm-id 21324382 + osm-id 21324382 + osm-id 21324382 + + + + osm-id 398710 + osm-id 398710 + osm-id 398710 + + + + osm-id 21040296 + osm-id 21040296 + osm-id 21040296 + + + + osm-id 245353 + osm-id 245353 + osm-id 245353 + + + + osm-id 245339 + osm-id 245339 + osm-id 245339 + + + + Arnulfstraße + osm-id 4020916 + + + osm-id 21324374 + osm-id 21324374 + osm-id 21324374 + + + + osm-id 19404292 + osm-id 19404292 + osm-id 19404292 + + + + osm-id 21324375 + osm-id 21324375 + osm-id 21324375 + + + + Helmholtzstraße + osm-id 4078867 + + + osm-id 398692 + osm-id 398692 + osm-id 398692 + + + + osm-id 21632176 + osm-id 21632176 + osm-id 21632176 + + + + osm-id 21585826 + osm-id 21585826 + osm-id 21585826 + + + + osm-id 21585827 + osm-id 21585827 + osm-id 21585827 + + + + Marlene-Dietrich-Straße + osm-id 4078868 + + + osm-id 21632177 + osm-id 21632177 + osm-id 21632177 + + + + osm-id 21585827 + osm-id 21585827 + osm-id 21585827 + + + + osm-id 21585828 + osm-id 21585828 + osm-id 21585828 + + + + Arnulfstraße + osm-id 4513917 + + + osm-id 21040288 + osm-id 21040288 + osm-id 21040288 + + + + osm-id 21040289 + osm-id 21040289 + osm-id 21040289 + + + + osm-id 21040287 + osm-id 21040287 + osm-id 21040287 + + + + osm-id 21040291 + osm-id 21040291 + osm-id 21040291 + + + + osm-id 398705 + osm-id 398705 + osm-id 398705 + + + + osm-id 398704 + osm-id 398704 + osm-id 398704 + + + + osm-id 398694 + osm-id 398694 + osm-id 398694 + + + + osm-id 21632176 + osm-id 21632176 + osm-id 21632176 + + + + osm-id 21324374 + osm-id 21324374 + osm-id 21324374 + + + + S7 + osm-id 23197114 + + + osm-id 250870622 + osm-id 250870622 + osm-id 250870622 + + + + osm-id 250870624 + osm-id 250870624 + osm-id 250870624 + + + + osm-id 250870626 + osm-id 250870626 + osm-id 250870626 + + + + osm-id 250870628 + osm-id 250870628 + osm-id 250870628 + + + diff --git a/reference/osm-data.xml b/reference/osm-data.xml new file mode 100644 index 000000000..ecbf0aaa3 --- /dev/null +++ b/reference/osm-data.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/reference/ov2-arc-out.ref b/reference/ov2-arc-out.ref new file mode 100644 index 0000000000000000000000000000000000000000..11d8ddd12fdd656d02706ddf1b33d7fff88b0762 GIT binary patch literal 2535 zcmZwITSydf7zOaz$cF+g$f6(+4T5em>)za6)-p?|KvYP|0wXcI83d72DMmpgf|z)6^?#$u*mnQC0L zShgBV5PPUWSi&?+7A6nLq}A=S>@+M|ERWZ#_ZqL)X|~j6fZ? zmhLwxE!p7EH+R1YIt^;A&I-8|#5U`y*{awXT8NL%XH49TxdokLVzJ^cZVMqMz6rad z#>6*Z<7!NN9hUKx=Q8m%SiTy!OcU&u8gn$l-m5W318gfwki22$xB|1(f~m5!K`G5C z%fg`ia872pORy7@G={qX8&zYtbFk_u&M{mqY)p;eYG5a)Imd9-ut#bPcNBJhhI0&8 z0SkY3Ey8f+u$O9lNF}hAS2=DfmNxo z!ai8J8mpd%tyJS9$tbey{$K7|VtjNtu%~LQCKq;3jXCOJ+trw(9X9im*JF+e*hMun zwFjjvDNP!5%90oLjN0?TezW8y5> zRW-KiGd__@%$YjJrk}xjZ0CstO*TCVYgFS}F7LAJz9r5v$7@)fYi68zrI*2-c;>a2BjW qjp3fd7WLi1_4$l}Utq3Z=lGD`z@Dfv#}KStjX7+X6ym&}!p1)@!`kWq literal 0 HcmV?d00001 diff --git a/reference/ov2-geo-out.ref b/reference/ov2-geo-out.ref new file mode 100644 index 0000000000000000000000000000000000000000..95d3bb5f2cb79d34df902ee35ee37db68f06bbb0 GIT binary patch literal 416 zcmZ|KKTE?v7zXgSQE@1Uu1+`A!N0MPI9HoisaTqb^Ht8|XnGfNNg>?gsH6A=9Q+u5 z09^#Z!M&?);wI-EjkSy83qPLcc`J7nfQ477daEwXRi(NeJ78@AOpjxpvkX&)8gxKV zo8S>)s9zwFi^8tkb+9(IetwYZeZ_?!A}C0C92NjvltIPYz105b>hB`EivWVw` zls*wN159duqf-}MXkkWm_dY(?v-JXh`qPG1pVv}7ExX`H#hO5EI(f>YDe+7LNt-OJ vm;b*|slMiQBF(bmH2E94jm~h&bV(Pd0|AzqTL`J%mRvYwu?eCq{MY{g06c{z literal 0 HcmV?d00001 diff --git a/reference/ov2-in.ref b/reference/ov2-in.ref new file mode 100644 index 000000000..8ce96c6f2 --- /dev/null +++ b/reference/ov2-in.ref @@ -0,0 +1,9 @@ +Mountain 3558.322N 08708.081W 0000000m Mountain Bike Heaven by susy13 a +The Trol 3605.441N 08640.772W 0000000m The Troll by a182pilot & Famil a +Dive Bom 3559.776N 08637.207W 0000000m Dive Bomber by JoGPS & family a +FOSTER b 3602.309N 08638.917W 0000000m FOSTER by JoGPS & Family a +Logan Li 3606.731N 08644.506W 0000000m Logan Lighthouse by JoGps & Fa a +Ganier C 3603.845N 08647.431W 0000000m Ganier Cache by Susy1313 a +Shy's Hi 3605.266N 08648.583W 0000000m Shy's Hill by FireFighterEng33 a +GittyUp 3603.450N 08653.519W 0000000m GittyUp by JoGPS / Warner Park a +Inlighti 3604.968N 08652.036W 0000000m Inlighting by JoGPS / Warner P a diff --git a/reference/ozi.wpt b/reference/ozi.wpt new file mode 100644 index 000000000..ffe172c0b --- /dev/null +++ b/reference/ozi.wpt @@ -0,0 +1,13 @@ +OziExplorer Waypoint File Version 1.1 +WGS 84 +Reserved 2 +Reserved 3 +1,GCEBB,35.972033,-87.134700,,0,1,3,0,65535,Mountain Bike Heaven by susy1313,0,0,0,0,6,0,17 +2,GC1A37,36.090683,-86.679550,,0,1,3,0,65535,The Troll by a182pilot & Family,0,0,0,0,6,0,17 +3,GC1C2B,35.996267,-86.620117,,0,1,3,0,65535,Dive Bomber by JoGPS & family,0,0,0,0,6,0,17 +4,GC25A9,36.038483,-86.648617,,0,1,3,0,65535,FOSTER by JoGPS & Family,0,0,0,0,6,0,17 +5,GC2723,36.112183,-86.741767,,0,1,3,0,65535,Logan Lighthouse by JoGps & Family,0,0,0,0,6,0,17 +6,GC2B71,36.064083,-86.790517,,0,1,3,0,65535,Ganier Cache by Susy1313,0,0,0,0,6,0,17 +7,GC309F,36.087767,-86.809733,,0,1,3,0,65535,Shy's Hill by FireFighterEng33,0,0,0,0,6,0,17 +8,GC317A,36.057500,-86.892000,,0,1,3,0,65535,GittyUp by JoGPS / Warner Parks,0,0,0,0,6,0,17 +9,GC317D,36.082800,-86.867283,,0,1,3,0,65535,Inlighting by JoGPS / Warner Parks,0,0,0,0,6,0,17 diff --git a/reference/paris.wpo b/reference/paris.wpo new file mode 100644 index 0000000000000000000000000000000000000000..d9f4252630887f6087828fdb26568ddfe242c889 GIT binary patch literal 25600 zcmeI4OKenS6vzJ;9~40;QXdqnR|`0WQaaO?7A)XA+L@L+x3}Nic9<4aG%?1wFm5$! z&=})_jffg0VPS~TAexAa8W&>X3!;gy7&jUcj0qtzF5H-?=h9NXW4|-QN?n}0=}q&S zlXHIOd}r>=V$w$jcJIZ#06Z+hWw;zy;7Tk;6PDmAEX6Whjcc$R%~*kJu@Wt~4%g!b z+=x|Z#cJGyHr$L`;Nw=@hIXvMTCBtENTCDku>qafh%RhGH`2(U2fgUSX7pnKTd);( zU=Z7|9XoI*vdAHi0){Y*B1#y+D0U)186n0HVH^e(#F)S&s@R1ZrZA1&*n_)pH}1h- zdZ__5@LwCCO`_NT%RsNc@H#i*A=Q6|rsZO;9^GbR6BjB$+J41L#GX!zY{q71h#kp@ zY>&-;Kx})D$g;FQBDN&Q?X%;)KwcGg55esk283non= zD6-n59OhV7+e*s!s3V6tmen>y>?1PEW~TwmW~V_8wcOZ5QYDpH3+u*>(%rVReSwEg z$DEz7ElQ_zV@cS^L?tu+81S+;Gk+hkDIqR-U`aerwf!O17FK8TPKDJD-(N*>e{uMY#!Ng^ zFzh{c5$*N29cMG5$FrQtvmDmY*?iw|Hs@F-;z45f%PbSIm)PfImYugQV(*jLn%(8q z#Lft8J}9!8^hfD=(y>dD+DyQA>dWMJ+R?W;mU&3#tW9Q_2eEInIWP|mShjZ>us%xc;9+c--*0HIzvAcxJ#U8eVXs7K&R>b&hg{C+ z*>t#Kit`}dyhXdO;L3M2EQMy6wc}uYmbK&Q`Ydb5;rc9VM}r*L*=)e(%*1SwIg_f2 z>{zy7`%3O#mwHSr6Gm(s_2Pb4FNkHri2Z^*tQA-$jMyKDZ4p=|jMyKEZFaG7A;{C9 z5i)=MX*|5=c+WC%Pzhp_p9ksYkl^9sw-I`$2GoEWPy=c}4X6P%pa#@{8c+jjKn + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/polygon_allencty.txt b/reference/polygon_allencty.txt new file mode 100644 index 000000000..b63e58e87 --- /dev/null +++ b/reference/polygon_allencty.txt @@ -0,0 +1,177 @@ +41.270000 -84.847384 +41.271057 -84.806490 +41.271079 -84.803581 +41.271079 -84.803581 +41.270942 -84.803580 +41.252531 -84.803492 +41.252531 -84.803492 +41.184959 -84.803475 +41.173889 -84.803472 +41.173203 -84.803594 +41.164649 -84.803413 +41.164169 -84.803420 +41.161573 -84.803460 +41.154117 -84.803573 +41.140520 -84.803780 +41.130773 -84.803501 +41.121414 -84.803234 +41.096783 -84.803341 +41.096783 -84.803341 +41.089302 -84.803374 +41.077432 -84.803367 +41.009551 -84.803325 +40.989209 -84.803313 +40.989209 -84.803313 +40.922377 -84.802935 +40.922377 -84.802935 +40.920577 -84.880807 +40.920577 -84.880807 +40.920311 -84.899804 +40.920311 -84.899804 +40.920237 -84.906200 +40.920237 -84.906200 +40.919632 -84.939126 +40.919632 -84.939638 +40.918588 -84.997291 +40.918588 -84.997291 +40.918447 -85.015168 +40.918447 -85.016068 +40.918447 -85.017668 +40.918047 -85.049068 +40.918047 -85.053468 +40.917847 -85.064268 +40.917847 -85.073868 +40.917847 -85.073868 +40.917447 -85.109669 +40.917447 -85.109669 +40.917247 -85.133662 +40.917247 -85.138269 +40.916547 -85.167070 +40.916947 -85.223371 +40.917047 -85.261571 +40.917047 -85.261571 +40.917047 -85.267360 +40.917047 -85.267360 +40.917032 -85.270180 +40.917023 -85.271123 +40.917011 -85.272372 +40.917011 -85.272372 +40.916994 -85.274150 +40.916994 -85.274150 +40.916947 -85.284172 +40.916947 -85.285948 +40.916947 -85.287972 +40.916947 -85.289672 +40.916947 -85.290204 +40.916947 -85.290204 +40.917046 -85.324973 +40.916946 -85.325373 +40.917046 -85.335973 +40.917046 -85.335973 +40.931446 -85.335873 +40.934746 -85.335973 +40.945846 -85.335573 +40.946246 -85.335673 +40.960346 -85.335673 +40.966746 -85.335573 +40.966746 -85.335573 +40.973192 -85.335418 +40.973192 -85.335418 +41.002047 -85.335374 +41.005347 -85.335274 +41.005347 -85.335274 +41.019947 -85.335574 +41.019947 -85.335574 +41.023138 -85.335574 +41.023138 -85.335574 +41.028400 -85.335626 +41.028400 -85.335626 +41.028680 -85.335631 +41.028680 -85.335631 +41.034047 -85.335774 +41.036347 -85.336074 +41.036347 -85.336074 +41.043516 -85.336249 +41.043516 -85.336249 +41.044447 -85.336274 +41.059047 -85.336574 +41.074947 -85.336974 +41.074947 -85.336974 +41.078620 -85.336974 +41.078620 -85.336974 +41.081370 -85.337035 +41.081370 -85.337035 +41.082627 -85.337075 +41.084247 -85.337075 +41.084247 -85.337075 +41.089647 -85.337275 +41.133759 -85.337800 +41.143299 -85.337827 +41.143299 -85.337827 +41.145540 -85.337834 +41.145540 -85.337834 +41.151009 -85.338178 +41.172790 -85.338402 +41.179120 -85.338552 +41.179260 -85.309842 +41.205086 -85.309537 +41.208912 -85.309716 +41.208912 -85.309716 +41.209609 -85.309724 +41.209609 -85.309724 +41.218262 -85.309657 +41.218720 -85.309808 +41.228211 -85.309910 +41.229675 -85.309950 +41.229675 -85.309950 +41.233139 -85.309660 +41.233139 -85.309660 +41.235062 -85.309506 +41.235192 -85.309502 +41.246997 -85.309775 +41.250047 -85.309586 +41.251009 -85.309143 +41.264071 -85.307748 +41.264071 -85.307748 +41.263809 -85.262791 +41.263851 -85.255698 +41.263851 -85.255698 +41.263850 -85.255648 +41.263850 -85.255648 +41.263805 -85.249531 +41.264283 -85.192097 +41.264283 -85.192097 +41.264449 -85.182307 +41.264449 -85.182307 +41.264820 -85.154950 +41.264820 -85.154950 +41.264961 -85.144213 +41.264961 -85.144213 +41.265046 -85.137394 +41.265046 -85.137394 +41.265091 -85.135030 +41.265829 -85.086692 +41.265562 -85.077749 +41.265562 -85.077749 +41.265756 -85.065254 +41.265756 -85.065254 +41.265822 -85.061017 +41.265822 -85.061017 +41.265860 -85.058621 +41.266469 -85.020092 +41.266557 -85.016245 +41.266557 -85.016245 +41.266740 -85.008277 +41.266740 -85.008277 +41.267781 -84.962627 +41.268149 -84.941620 +41.268218 -84.938770 +41.268218 -84.938164 +41.268368 -84.926845 +41.268627 -84.914822 +41.268963 -84.901055 +41.268963 -84.901055 +41.268974 -84.900612 +41.268974 -84.900612 +41.269170 -84.892632 +41.270000 -84.847384 diff --git a/reference/polygon_output.txt b/reference/polygon_output.txt new file mode 100644 index 000000000..3f589a727 --- /dev/null +++ b/reference/polygon_output.txt @@ -0,0 +1,37 @@ +BEGIN SYMBOL +41.14703, -85.11092, N.E.R.D. by Enos Shenk Unknown Cache (3/3) +41.13940, -85.10142, Fallen Timbers by TeamMJ Traditional Cache (2/2) +41.14415, -85.14415, Historic Iron Bridges by Genoist (1/2 of TeamSJ1) Locationless (Reverse) Cache (1/1) +41.12890, -85.11163, Mastadon Trek 2 by Genoist and Dogvetusa Traditional Cache (2/2) +41.16413, -85.14688, NYC Trail by VistaAL Traditional Cache (1/1.5) +41.15900, -85.15418, Craftily Concealed Containers by Warm Fuzzies Multi-Cache (4/2) +41.12210, -85.11097, Land of Lost Auto Parts by Genoist and The Zymurgist Traditional Cache (1/5) +41.17732, -85.15117, The Farm by AParks1569 Traditional Cache (1.5/1.5) +41.10757, -85.13087, Swonderful by Genoist and The Zymurgist Traditional Cache (2/5) +41.12733, -85.06728, Dr. Mengerson I Preserve by Genoist Traditional Cache (2/2) +41.10417, -85.15167, Clue by Warm Fuzzies Multi-Cache (3.5/2) +41.10823, -85.16212, Son of Pez by Enos Shenk Traditional Cache (1.5/1.5) +41.09278, -85.14073, Urbana #3: Dodgy Deals by Enos Shenk Traditional Cache (2.5/1.5) +41.09258, -85.09258, Secret Squirrels by Enos Shenk & Panic! Unknown Cache (4/1) +41.08748, -85.13762, A King's Ransom by Team ABC and The GeoStars Team Traditional Cache (1.5/1) +41.08427, -85.13597, Urbana #4: The City She Loves Me by Enos Shenk & Athena Traditional Cache (3.5/2) +41.08582, -85.07230, Caribbean Cache by Genoist and Dogvetusa Traditional Cache (3/2) +41.08190, -85.17180, Earthling Vector Luna- 2nd Phase by Earthling and Heavenbound Traditional Cache (1/1.5) +41.08400, -85.05387, Earthling Vector Sol by Earthling & Heavenbound Traditional Cache (1.5/1.5) +41.20673, -85.03985, The Sarsaparilla Cache by Cashconnect Traditional Cache (2/1.5) +41.06353, -85.13400, Sky High by Enos Shenk Virtual Cache (1/3) +41.09880, -85.21725, We Support Our Troops by Genoist and The Zymurgist Traditional Cache (2/2.5) +41.06950, -85.19750, Shortwave by Warm Fuzzies Unknown Cache (4/2.5) +41.06255, -85.04757, Starfall by Enos Shenk Traditional Cache (2/2.5) +41.07482, -85.01957, Fly Like an Eagle by Team SJ1 Traditional Cache (2/2) +41.04714, -85.16617, Perfectly Perplexing Puzzles by Warm Fuzzies Multi-Cache (5/3.5) +41.07197, -85.01863, Arrow Haven (2/4) by Genoist Traditional Cache (2/2.5) +41.07183, -85.01850, Heat Death (3/4) by Genoist Traditional Cache (2/3) +41.06827, -85.01655, Abbadon by Genoist Traditional Cache (1.5/4) +41.01503, -85.13290, Earthling Vector Pluto by Earthling & Heavenbound Traditional Cache (1/1.5) +41.26535, -84.98950, Outstanding In Its Field Cache by kwbach Traditional Cache (2/2) +41.00470, -85.05742, Earthling Vector Perelandra by Earthling & Heavenbound Multi-Cache (4/1.5) +41.04247, -85.27570, KWAANTINAKAANI by Northmill Jo-Jo Beans and E-Bone Letterbox Hybrid (2/1) +41.01760, -85.25190, Earthling Vector Terra by Earthling & Heavenbound Traditional Cache (1.5/2.5) +40.97610, -85.22277, 47520 Feet by kidCraZy Traditional Cache (1/1.5) +END diff --git a/reference/ps.psp b/reference/ps.psp new file mode 100644 index 0000000000000000000000000000000000000000..d37c83e719a33a3477a458b00bc02a2d558acf6a GIT binary patch literal 964 zcmb7@KTH!*9LK*_TV!b%Oxlo0FDTH&5V%%@O&~9{a90R~#+G2?R16-qN5QrjJHh0j zE1OB*s{)rL>GjulpWn7S;=|$hjR*Zrqy$CcxIV&f5W_#QGu_o;SI*6ikf_t>MFPZrXy0MtM3cIXUSvhm-;d)tO?2L^0 zByZ}z&!4^Nh@f>a^kT4y7iVR31Wm=t*YlL%)5ChTTu!>N?k!UL&Fb#YjUGpcz1puI zLk-$d^fOBaI?`0CqDSp9sj7KWd4ta-Qsv$CC@VEe-xkvlbx*h_@~J&Af5Q=hnXQ%m zL=#7+hhc{n3|7{zU_2`TjFPu SM$kFN@9pCq%m2o@IPV{1U$R{Q literal 0 HcmV?d00001 diff --git a/reference/psitwpts.txt b/reference/psitwpts.txt new file mode 100755 index 000000000..27465e721 --- /dev/null +++ b/reference/psitwpts.txt @@ -0,0 +1,17 @@ + 55.205241, -2.556468, 188.78, 001 , wpt_dot + 53.618556, -1.972446,********, 003 , wpt_dot + 53.451544, -1.373673, 166.19, 004 , wpt_dot + 43.621861, -79.378357, 91.21, 005 , wpt_dot + 49.191132,-123.114769, -12.37, 006 , wpt_dot + 49.191140,-123.114736, -0.11, 007 , wpt_dot + 51.285499,-116.946531, 769.42, 008 , wpt_dot + 52.034985, 1.124766,********, BB HOTEL, lodging + 53.895060, -2.611549, 134.71, FELL FOOT, parking + 49.171600,-122.956700,********, FRASERWAY, truck_stop + 51.094100,-114.010600,********, FRASERWYC, truck_stop + 46.538170, 12.124091, 1288.04, OLIMPIA, lodging + 53.900310, -2.618355, 414.45, PARLICK TO, glider + 53.859022, -2.335425, 436.80, PENDLE TO, glider + 51.047100,-114.081900,********, SANDMANC, lodging + 49.189300,-123.112200,********, SANDMANV, lodging + 54.601136, -3.137685,********, SICKWRNG, shpng_cart diff --git a/reference/quovadis.gpu b/reference/quovadis.gpu new file mode 100644 index 000000000..e4c2304fc --- /dev/null +++ b/reference/quovadis.gpu @@ -0,0 +1,9 @@ +GC1A37 3605.441N 08640.773W 0000000m GC1A37 a +GC1C2B 3559.776N 08637.207W 0000000m GC1C2B a +GC25A9 3602.309N 08638.917W 0000000m GC25A9 a +GC2723 3606.731N 08644.506W 0000000m GC2723 a +GC2B71 3603.845N 08647.431W 0000000m GC2B71 a +GC309F 3605.266N 08648.584W 0000000m GC309F a +GC317A 3603.450N 08653.520W 0000000m GC317A a +GC317D 3604.968N 08652.037W 0000000m GC317D a +GCEBB 3558.322N 08708.082W 0000000m GCEBB a diff --git a/reference/quovadis.pdb b/reference/quovadis.pdb new file mode 100644 index 0000000000000000000000000000000000000000..d0d3971b920a4be6c446869b31abac392f7cd6bf GIT binary patch literal 601 zcmWG6%@0dV$t?CwEXqzTa&cln2OJEHyH)#rK^R>sFw8e7Fw{Q`F3tpGB|v$JK$;VX z-JJ~`jm@EgSSZ&1uT0El(_J7^Li{i#Kz+_en9hMoGq6s$tIce|A&RNb$kfpit_*|0 zIwAKuvw5-(7JcSM#u&=s0<8UvKbg&(J+SC=GB<=P!(g!XId?Og{l{XTv4N!%|VC~tiz-%t@1gk!1C}U^>3b6KyuVFUZCV;8W)d^2D QFtBzqi!fWH?L*fG09dLqb^rhX literal 0 HcmV?d00001 diff --git a/reference/radius.csv b/reference/radius.csv new file mode 100644 index 000000000..4095cad3e --- /dev/null +++ b/reference/radius.csv @@ -0,0 +1 @@ +35.97203, -87.13470, Mountain Bike Heaven by susy1313 diff --git a/reference/raymarine-sample.gpx b/reference/raymarine-sample.gpx new file mode 100644 index 000000000..cb130d37b --- /dev/null +++ b/reference/raymarine-sample.gpx @@ -0,0 +1,83 @@ + + + + + + + Qr1-one + Qr1-one + notes-1 + Red Square + + + + Qr,2 + Qr,2 + notes-2 + Big Fish + + + + Qr3 + Qr3 + notes-3 + Anchor + + + + Qr4-four + Qr4-four + notes-4 + Smiley + + + + Qr5 + Qr5 + notes-5 + Sad + + + Qr + + + Qr1-one + Qr1-one + notes-1 + Red Square + + + + Qr,2 + Qr,2 + notes-2 + Big Fish + + + + Qr3 + Qr3 + notes-3 + Anchor + + + + Qr4-four + Qr4-four + notes-4 + Smiley + + + + Qr5 + Qr5 + notes-5 + Sad + + + diff --git a/reference/raymarine-sample.rwf b/reference/raymarine-sample.rwf new file mode 100644 index 000000000..5657d289d --- /dev/null +++ b/reference/raymarine-sample.rwf @@ -0,0 +1,164 @@ +[Wp0] +Loc=Qr +Name=Qr1-one +Lat=51.593568734471624 +Long=9.895914981396029 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=3 +Fixed=1 +Locked=0 +Notes=notes-1 +Rel= +RelSet=1 +RcCount=1 +RcRadius=0.000000000000000 +Show=0 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=39027.880335648151000 +GUID=41847-17743-33206-33476 +[Wp1] +Loc=Qr +Name=Qr,2 +Lat=50.833425047658316 +Long=10.364770733812209 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=4 +Fixed=1 +Locked=0 +Notes=notes-2 +Rel= +RelSet=1 +RcCount=1 +RcRadius=0.000000000000000 +Show=0 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=39027.880347222221000 +GUID=41847-17743-33462-33476 +[Wp2] +Loc=Qr +Name=Qr3 +Lat=50.184475273537196 +Long=10.557828984807108 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=5 +Fixed=1 +Locked=0 +Notes=notes-3 +Rel= +RelSet=1 +RcCount=1 +RcRadius=0.000000000000000 +Show=0 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=39027.880347222221000 +GUID=41847-17743-33718-33476 +[Wp3] +Loc=Qr +Name=Qr4-four +Lat=48.986577919201942 +Long=12.047135492482036 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=6 +Fixed=1 +Locked=0 +Notes=notes-4 +Rel= +RelSet=1 +RcCount=1 +RcRadius=0.000000000000000 +Show=0 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=39027.880347222221000 +GUID=41847-17743-33974-33476 +[Wp4] +Loc=Qr +Name=Qr5 +Lat=48.623286046917791 +Long=12.598730495324602 +Rng=0.000000000000000 +Bear=0.000000000000000 +Bmp=7 +Fixed=1 +Locked=0 +Notes=notes-5 +Rel= +RelSet=1 +RcCount=1 +RcRadius=0.000000000000000 +Show=0 +RcShow=0 +SeaTemp=-32678.000000000000000 +Depth=65535.000000000000000 +Time=39027.880358796298000 +GUID=41847-17743-34230-33476 +[Rt0] +Name=Qr +Visible=0 +Guid=41847-17743-32950-33476 +Mk0=Qr1-one +Cog0=0.000000000000000 +Eta0=0.000000000000000 +Length0=0.000000000000000 +PredictedDrift0=0.000000000000000 +PredictedSet0=0.000000000000000 +PredictedSog0=0.000000000000000 +PredictedTime0=0.000000000000000 +PredictedTwa0=0.000000000000000 +PredictedTwd0=0.000000000000000 +PredictedTws0=0.000000000000000 +Mk1=Qr,2 +Cog1=0.000000000000000 +Eta1=0.000000000000000 +Length1=0.000000000000000 +PredictedDrift1=0.000000000000000 +PredictedSet1=0.000000000000000 +PredictedSog1=0.000000000000000 +PredictedTime1=0.000000000000000 +PredictedTwa1=0.000000000000000 +PredictedTwd1=0.000000000000000 +PredictedTws1=0.000000000000000 +Mk2=Qr3 +Cog2=0.000000000000000 +Eta2=0.000000000000000 +Length2=0.000000000000000 +PredictedDrift2=0.000000000000000 +PredictedSet2=0.000000000000000 +PredictedSog2=0.000000000000000 +PredictedTime2=0.000000000000000 +PredictedTwa2=0.000000000000000 +PredictedTwd2=0.000000000000000 +PredictedTws2=0.000000000000000 +Mk3=Qr4-four +Cog3=0.000000000000000 +Eta3=0.000000000000000 +Length3=0.000000000000000 +PredictedDrift3=0.000000000000000 +PredictedSet3=0.000000000000000 +PredictedSog3=0.000000000000000 +PredictedTime3=0.000000000000000 +PredictedTwa3=0.000000000000000 +PredictedTwd3=0.000000000000000 +PredictedTws3=0.000000000000000 +Mk4=Qr5 +Cog4=0.000000000000000 +Eta4=0.000000000000000 +Length4=0.000000000000000 +PredictedDrift4=0.000000000000000 +PredictedSet4=0.000000000000000 +PredictedSog4=0.000000000000000 +PredictedTime4=0.000000000000000 +PredictedTwa4=0.000000000000000 +PredictedTwd4=0.000000000000000 +PredictedTws4=0.000000000000000 diff --git a/reference/route/bcr-sample.bcr b/reference/route/bcr-sample.bcr new file mode 100644 index 000000000..3cc8f0bb6 --- /dev/null +++ b/reference/route/bcr-sample.bcr @@ -0,0 +1,36 @@ +[CLIENT] +REQUEST=TRUE +ROUTENAME=DE_Plauen-Leipzig +DESCRIPTIONLINES=1 +DESCRIPTION1= +STATION1=Town,999999999 +STATION2=AdrMon VORTE,999999999 +STATION3=Standort,999999999 +STATION4=Standort,999999999 +STATION5=Standort,999999999 +STATION6=Standort,999999999 +STATION7=Standort,999999999 +STATION8=Standort,999999999 +STATION9=Town,999999999 +[COORDINATES] +STATION1=1346067,6524736 +STATION2=1346265,6524980 +STATION3=1346113,6525659 +STATION4=1370788,6559102 +STATION5=1382050,6589961 +STATION6=1384671,6608819 +STATION7=1389101,6644184 +STATION8=1377578,6656081 +STATION9=1379831,6669676 +[DESCRIPTION] +STATION1=bei D 08527,Neundorf,,0, +STATION2=bei D 08523,Plauen/Possig,,0, +STATION3=bei D 08523,Plauen/Westend,,0, +STATION4=bei D 08427,Fraureuth/Beiersdorf,,0, +STATION5=bei D 04639,Ponitz/Merlach,,0, +STATION6=bei D 04600,Altenburg/Paditz,,0, +STATION7=bei D 04552,Borna/Gestewitz,,0, +STATION8=bei D 04564,Boehlen/Grossdeuben,,0, +STATION9=bei D 04317,Leipzig/Thonberg,,0, +[ROUTE] +ROUTERECT=1346067,6669676,1389101,6524736 diff --git a/reference/route/bcr-sample.gpx b/reference/route/bcr-sample.gpx new file mode 100644 index 000000000..2fd339028 --- /dev/null +++ b/reference/route/bcr-sample.gpx @@ -0,0 +1,121 @@ + + + + + + Neundorf + Orte + bei D 08527 + City (Small) + + + Plauen/Possig + Ortsinformationen + bei D 08523 + Information + + + Plauen/Westend + Standort + bei D 08523 + Waypoint + + + Fraureuth/Beiersdorf + Standort + bei D 08427 + Waypoint + + + Ponitz/Merlach + Standort + bei D 04639 + Waypoint + + + Altenburg/Paditz + Standort + bei D 04600 + Waypoint + + + Borna/Gestewitz + Standort + bei D 04552 + Waypoint + + + Boehlen/Grossdeuben + Standort + bei D 04564 + Waypoint + + + Leipzig/Thonberg + Orte + bei D 04317 + City (Small) + + + DE_Plauen-Leipzig + + Neundorf + Orte + bei D 08527 + City (Small) + + + Plauen/Possig + Ortsinformationen + bei D 08523 + Information + + + Plauen/Westend + Standort + bei D 08523 + Waypoint + + + Fraureuth/Beiersdorf + Standort + bei D 08427 + Waypoint + + + Ponitz/Merlach + Standort + bei D 04639 + Waypoint + + + Altenburg/Paditz + Standort + bei D 04600 + Waypoint + + + Borna/Gestewitz + Standort + bei D 04552 + Waypoint + + + Boehlen/Grossdeuben + Standort + bei D 04564 + Waypoint + + + Leipzig/Thonberg + Orte + bei D 04317 + City (Small) + + + diff --git a/reference/route/bcr-sample2.bcr b/reference/route/bcr-sample2.bcr new file mode 100644 index 000000000..88f13cba2 --- /dev/null +++ b/reference/route/bcr-sample2.bcr @@ -0,0 +1,35 @@ +[CLIENT] +REQUEST=TRUE +ROUTENAME=DE_Plauen-Leipzig +DESCRIPTIONLINES=0 +STATION1=Town,999999999 +STATION2=AdrMon VORTE,999999999 +STATION3=Standort,999999999 +STATION4=Standort,999999999 +STATION5=Standort,999999999 +STATION6=Standort,999999999 +STATION7=Standort,999999999 +STATION8=Standort,999999999 +STATION9=Town,999999999 +[COORDINATES] +STATION1=1346067,6524736 +STATION2=1346265,6524980 +STATION3=1346113,6525659 +STATION4=1370788,6559102 +STATION5=1382050,6589961 +STATION6=1384671,6608819 +STATION7=1389101,6644184 +STATION8=1377578,6656081 +STATION9=1379831,6669676 +[DESCRIPTION] +STATION1=bei D 08527,Neundorf,@,0 +STATION2=bei D 08523,Plauen/Possig,@,0 +STATION3=bei D 08523,Plauen/Westend,@,0 +STATION4=bei D 08427,Fraureuth/Beiersdorf,@,0 +STATION5=bei D 04639,Ponitz/Merlach,@,0 +STATION6=bei D 04600,Altenburg/Paditz,@,0 +STATION7=bei D 04552,Borna/Gestewitz,@,0 +STATION8=bei D 04564,Boehlen/Grossdeuben,@,0 +STATION9=bei D 04317,Leipzig/Thonberg,@,0 +[ROUTE] +ROUTERECT=1346067,6669676,1389101,6524736 diff --git a/reference/route/compegps-rte.gpx b/reference/route/compegps-rte.gpx new file mode 100644 index 000000000..bc41c8b94 --- /dev/null +++ b/reference/route/compegps-rte.gpx @@ -0,0 +1,48 @@ + + + + + + test + + 0.000000 + V03087 + Waypoint + + + 0.000000 + V05027 + Waypoint + + + 0.000000 + V06080 + Waypoint + + + 0.000000 + V04041 + Waypoint + + + 0.000000 + V09058 + Waypoint + + + 0.000000 + V10025 + Waypoint + + + 0.000000 + V02023 + Waypoint + + + diff --git a/reference/route/compegps.rte b/reference/route/compegps.rte new file mode 100644 index 000000000..f07304ede --- /dev/null +++ b/reference/route/compegps.rte @@ -0,0 +1,20 @@ +G WGS 84 + U 1 + R 16711680 , test , 1 , -1 + W V03087__________ A 45.7893830000ºN 11.5535830000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V05027__________ A 45.7758000000ºN 11.4499670000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V06080__________ A 45.7848830000ºN 11.5444170000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V04041__________ A 45.7544670000ºN 11.4939500000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V09058__________ A 45.7830830000ºN 11.4590830000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V10025__________ A 45.7605830000ºN 11.4496170000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V02023__________ A 45.7659500000ºN 11.4806170000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + + + \ No newline at end of file diff --git a/reference/route/cst-sample.cst b/reference/route/cst-sample.cst new file mode 100644 index 000000000..4db803380 --- /dev/null +++ b/reference/route/cst-sample.cst @@ -0,0 +1,351 @@ +#CARTE SUR TABLE DATA FILE +; Saved 21/06/2005 00:08:38 +; USER : lilou COMPUTER : MAISON1 +; NAME : +; CarteSurTable version 4.0.0.7 +; date format : yyyy mm dd hh:nn:ss + +#VERSION +40 + +#NOTES +Très belle rando, mais trop tôt dans la saison. Le pic du midi était inaccessible car le parcours était complètement enneigé. La descente par le GR de pays, face sud est superbe. + +#REFERENCE +GRID 0 (UTM/UPS) +LEN 1000.0 3 (Mètres) +ORIGIN 10.000 246.220 266295 4757286 +X-AXIS 246.220 246.220 +Y-AXIS 10.000 10.000 +FEET 0 +ZONE 31 0 +DATUM 100 (WGS 84) +METHOD 0 +EQU DEGREE: 1 + +#ROUTE +; x y z interp [start] [NAME:name] [ ^ date] [ ¤ symb] +303 Points +271440 4756533 1266.2 0 1 ^ 2005 06 18 08:45:06 +271447 4756542 1268.1 0 ^ 2005 06 18 08:51:06 +271446 4756552 1267.6 0 ^ 2005 06 18 08:51:21 +271442 4756550 1268.1 0 ^ 2005 06 18 08:51:25 +271444 4756540 1268.6 0 ^ 2005 06 18 08:51:40 +271442 4756538 1270 0 ^ 2005 06 18 08:52:01 +271421 4756534 1271.5 0 ^ 2005 06 18 08:52:17 +271394 4756527 1274.4 0 ^ 2005 06 18 08:52:33 +271371 4756521 1273.4 0 ^ 2005 06 18 08:52:57 +271369 4756521 1272.9 0 NAME:1 ^ 2005 06 18 08:53:36 +;¤bitmap C:\Mesdoc\Mes images\pic midi\DSCF0446.JPG +;¤note +Vue de notre chemin du retour.., mais c'est par la route qu'on monte +;¤end +271368 4756521 1272.9 0 ^ 2005 06 18 08:53:42 +271365 4756512 1273.9 0 ^ 2005 06 18 08:53:46 +271316 4756459 1280.1 0 ^ 2005 06 18 08:54:13 +271262 4756420 1286.4 0 ^ 2005 06 18 08:54:37 +271253 4756411 1286.9 0 ^ 2005 06 18 08:54:42 +271258 4756391 1288.8 0 ^ 2005 06 18 08:54:49 +271294 4756318 1290.7 0 ^ 2005 06 18 08:55:21 +271341 4756191 1291.2 0 ^ 2005 06 18 08:56:19 +271432 4756247 1291.2 0 ^ 2005 06 18 08:56:35 +271489 4756174 1291.2 0 ^ 2005 06 18 08:56:59 +271500 4756169 1291.2 0 ^ 2005 06 18 08:57:04 +271527 4756201 1307 0 ^ 2005 06 18 08:57:15 +271532 4756191 1307 0 ^ 2005 06 18 08:57:17 +271540 4756184 1307.5 0 ^ 2005 06 18 08:57:21 +271582 4756175 1308.5 0 ^ 2005 06 18 08:57:42 +271656 4756187 1311.4 0 ^ 2005 06 18 08:58:30 +271682 4756172 1312.3 0 ^ 2005 06 18 08:58:51 +271769 4756160 1317.6 0 ^ 2005 06 18 08:59:38 +271859 4756104 1320 0 ^ 2005 06 18 09:00:37 +271865 4756097 1326.3 0 ^ 2005 06 18 09:02:27 +271901 4756057 1326.3 0 ^ 2005 06 18 09:02:51 +271957 4756001 1334.9 0 ^ 2005 06 18 09:03:28 +271984 4755933 1343.1 0 ^ 2005 06 18 09:04:01 +272032 4755848 1350.3 0 ^ 2005 06 18 09:04:47 +272056 4755771 1356.6 0 ^ 2005 06 18 09:05:25 +272120 4755637 1362.3 0 ^ 2005 06 18 09:06:34 +272166 4755543 1368.1 0 ^ 2005 06 18 09:07:24 +272154 4755498 1371.5 0 ^ 2005 06 18 09:07:48 +272193 4755446 1372.9 0 ^ 2005 06 18 09:08:19 +272234 4755385 1382.5 0 ^ 2005 06 18 09:08:54 +272220 4755379 1388.3 0 ^ 2005 06 18 09:09:03 +272203 4755384 1391.6 0 ^ 2005 06 18 09:09:12 +272163 4755438 1403.2 0 ^ 2005 06 18 09:09:45 +272111 4755518 1414.2 0 ^ 2005 06 18 09:10:30 +272064 4755587 1424.3 0 ^ 2005 06 18 09:11:10 +272013 4755648 1434.4 0 ^ 2005 06 18 09:11:50 +271937 4755713 1437.3 0 ^ 2005 06 18 09:12:37 +271912 4755754 1440.2 0 ^ 2005 06 18 09:13:01 +271844 4755837 1447.9 0 ^ 2005 06 18 09:13:51 +271777 4755909 1450.3 0 ^ 2005 06 18 09:14:37 +271741 4755929 1456.5 0 ^ 2005 06 18 09:14:59 +271668 4755955 1459.4 0 ^ 2005 06 18 09:15:36 +271577 4756006 1465.2 0 ^ 2005 06 18 09:16:28 +271512 4756013 1521.9 0 ^ 2005 06 18 09:17:00 +271434 4755982 1521.4 0 ^ 2005 06 18 09:17:42 +271352 4755942 1524.3 0 ^ 2005 06 18 09:18:30 +271355 4755940 1525.3 0 NAME:2 ^ 2005 06 18 09:18:44 +;¤bitmap C:\Mesdoc\Mes images\pic midi\DSCF0448.JPG +;¤note +Notre objectif. +;¤end +271355 4755942 1525.3 0 ^ 2005 06 18 09:19:08 +271385 4755953 1524.3 0 ^ 2005 06 18 09:19:16 +271384 4755955 1524.8 0 ^ 2005 06 18 09:19:20 +271378 4755951 1526.2 0 ^ 2005 06 18 09:19:39 +271348 4755930 1530.1 0 ^ 2005 06 18 09:20:01 +271350 4755930 1530.6 0 ^ 2005 06 18 09:20:17 +271333 4755914 1533 0 ^ 2005 06 18 09:22:06 +271271 4755878 1536.8 0 ^ 2005 06 18 09:22:39 +271190 4755833 1539.2 0 ^ 2005 06 18 09:23:21 +271101 4755779 1561.8 0 ^ 2005 06 18 09:26:01 +271058 4755756 1565.2 0 ^ 2005 06 18 09:26:27 +271021 4755743 1568 0 ^ 2005 06 18 09:26:46 +270977 4755735 1571.9 0 ^ 2005 06 18 09:27:06 +270973 4755733 1572.9 0 ^ 2005 06 18 09:27:22 +270966 4755733 1572.4 0 ^ 2005 06 18 09:28:54 +270954 4755726 1572.4 0 ^ 2005 06 18 09:29:00 +270878 4755726 1579.6 0 ^ 2005 06 18 09:29:35 +270813 4755714 1584.9 0 ^ 2005 06 18 09:30:08 +270736 4755674 1591.6 0 ^ 2005 06 18 09:30:53 +270712 4755641 1595.9 0 ^ 2005 06 18 09:31:14 +270666 4755578 1602.2 0 ^ 2005 06 18 09:31:55 +270614 4755525 1609.4 0 ^ 2005 06 18 09:32:35 +270561 4755467 1616.1 0 ^ 2005 06 18 09:33:16 +270513 4755402 1623.3 0 ^ 2005 06 18 09:34:00 +270499 4755396 1626.2 0 ^ 2005 06 18 09:34:08 +270478 4755360 1630.5 0 ^ 2005 06 18 09:34:30 +270439 4755343 1636.3 0 ^ 2005 06 18 09:34:55 +270401 4755287 1643 0 ^ 2005 06 18 09:35:34 +270400 4755225 1648.8 0 ^ 2005 06 18 09:36:09 +270376 4755187 1652.6 0 ^ 2005 06 18 09:36:36 +270353 4755133 1656 0 ^ 2005 06 18 09:37:10 +270353 4755121 1657.5 0 ^ 2005 06 18 09:37:18 +270313 4755042 1672.4 0 ^ 2005 06 18 09:38:24 +270297 4755035 1678.1 0 ^ 2005 06 18 09:38:33 +270253 4755017 1683.4 0 ^ 2005 06 18 09:39:01 +270180 4754972 1689.7 0 ^ 2005 06 18 09:39:49 +270152 4754925 1694.9 0 ^ 2005 06 18 09:40:20 +270132 4754857 1700.2 0 ^ 2005 06 18 09:41:02 +270083 4754811 1707 0 ^ 2005 06 18 09:41:46 +270021 4754784 1713.7 0 ^ 2005 06 18 09:42:25 +270001 4754768 1716.1 0 ^ 2005 06 18 09:42:41 +269999 4754773 1715.6 0 ^ 2005 06 18 09:42:45 +270003 4754768 1716.1 0 ^ 2005 06 18 09:42:54 +270003 4754773 1716.1 0 ^ 2005 06 18 09:42:57 +270008 4754780 1716.1 0 ^ 2005 06 18 09:43:11 +270008 4754777 1716.6 0 ^ 2005 06 18 09:43:17 +270003 4754778 1717.1 0 ^ 2005 06 18 09:43:22 +269972 4754750 1721.4 0 ^ 2005 06 18 09:43:46 +269929 4754723 1725.2 0 ^ 2005 06 18 09:44:18 +269874 4754706 1728.6 0 ^ 2005 06 18 09:44:53 +269846 4754702 1730.5 0 ^ 2005 06 18 09:45:12 +269835 4754690 1730 0 ^ 2005 06 18 09:45:38 +269837 4754690 1732.9 0 ^ 2005 06 18 09:46:32 +269833 4754690 1733.4 0 ^ 2005 06 18 09:46:51 +269821 4754691 1734.8 0 ^ 2005 06 18 09:46:57 +269816 4754691 1735.8 0 ^ 2005 06 18 09:47:01 +269811 4754693 1736.3 0 ^ 2005 06 18 09:47:04 +269779 4754694 1740.1 0 ^ 2005 06 18 09:47:22 +269738 4754712 1743 0 ^ 2005 06 18 09:47:48 +269724 4754763 1744 0 ^ 2005 06 18 09:48:14 +269706 4754802 1744.9 0 ^ 2005 06 18 09:48:37 +269654 4754818 1747.3 0 ^ 2005 06 18 09:49:09 +269601 4754817 1747.3 0 ^ 2005 06 18 09:49:39 +269571 4754814 1747.3 0 ^ 2005 06 18 09:49:56 +269555 4754750 1818 0 ^ 2005 06 18 09:50:15 +269518 4754746 1802.1 0 ^ 2005 06 18 09:50:35 +269472 4754736 1802.1 0 ^ 2005 06 18 09:51:03 +269397 4754741 1803.6 0 ^ 2005 06 18 09:51:45 +269339 4754738 1804.5 0 ^ 2005 06 18 09:52:19 +269280 4754725 1806 0 ^ 2005 06 18 09:52:53 +269215 4754718 1808.9 0 ^ 2005 06 18 09:53:31 +269140 4754725 1811.7 0 ^ 2005 06 18 09:54:15 +269065 4754730 1815.6 0 ^ 2005 06 18 09:55:02 +269035 4754734 1817.5 0 ^ 2005 06 18 09:55:19 +268955 4754736 1822.3 0 ^ 2005 06 18 09:56:06 +268903 4754714 1826.6 0 ^ 2005 06 18 09:56:40 +268834 4754688 1832.4 0 ^ 2005 06 18 09:57:23 +268773 4754657 1837.2 0 ^ 2005 06 18 09:58:03 +268696 4754654 1843 0 ^ 2005 06 18 09:58:47 +268668 4754655 1845.9 0 ^ 2005 06 18 09:59:03 +268597 4754677 1851.2 0 ^ 2005 06 18 09:59:46 +268543 4754686 1856 0 ^ 2005 06 18 10:00:17 +268541 4754686 1856 0 ^ 2005 06 18 10:00:18 +268536 4754689 1856.9 0 ^ 2005 06 18 10:00:22 +268506 4754687 1859.3 0 ^ 2005 06 18 10:00:42 +268490 4754681 1860.8 0 ^ 2005 06 18 10:00:55 +268483 4754676 1861.7 0 ^ 2005 06 18 10:01:02 +268440 4754673 1865.1 0 ^ 2005 06 18 10:01:30 +268378 4754646 1870.4 0 ^ 2005 06 18 10:02:12 +268337 4754626 1874.7 0 ^ 2005 06 18 10:02:42 +268284 4754606 1879.5 0 ^ 2005 06 18 10:03:17 +268273 4754604 1880.5 0 ^ 2005 06 18 10:03:24 +268271 4754602 1881 0 ^ 2005 06 18 10:03:27 +268263 4754600 1881.9 0 ^ 2005 06 18 10:03:33 +268208 4754585 1886.7 0 ^ 2005 06 18 10:04:11 +268150 4754575 1892 0 ^ 2005 06 18 10:04:49 +268110 4754557 1896.3 0 ^ 2005 06 18 10:05:14 +268069 4754525 1899.7 0 ^ 2005 06 18 10:05:46 +268033 4754491 1903.1 0 ^ 2005 06 18 10:06:18 +268018 4754484 1905.5 0 ^ 2005 06 18 10:06:30 +268008 4754482 1906.4 0 ^ 2005 06 18 10:06:36 +267947 4754441 1911.2 0 ^ 2005 06 18 10:07:21 +267904 4754407 1915.6 0 ^ 2005 06 18 10:07:54 +267879 4754396 1919.4 0 ^ 2005 06 18 10:08:12 +267845 4754385 1922.8 0 ^ 2005 06 18 10:08:33 +267774 4754368 1928.5 0 ^ 2005 06 18 10:09:16 +267713 4754366 1933.8 0 ^ 2005 06 18 10:09:53 +267664 4754372 1937.2 0 ^ 2005 06 18 10:10:23 +267668 4754379 1939.6 0 ^ 2005 06 18 10:10:30 +267676 4754381 1942 0 ^ 2005 06 18 10:10:44 +267677 4754386 1941.5 0 ^ 2005 06 18 10:11:39 +267680 4754386 1940.6 0 ^ 2005 06 18 10:21:10 +267682 4754391 1941 0 ^ 2005 06 18 10:21:14 +267684 4754390 1942 0 ^ 2005 06 18 10:21:29 +267684 4754388 1942.5 0 ^ 2005 06 18 10:21:54 +267724 4754384 1945.4 0 ^ 2005 06 18 10:22:15 +267758 4754409 1948.7 0 ^ 2005 06 18 10:22:40 +267805 4754458 1954.5 0 ^ 2005 06 18 10:23:22 +267821 4754493 1958.3 0 ^ 2005 06 18 10:23:47 +267859 4754528 1962.7 0 ^ 2005 06 18 10:24:18 +267856 4754561 1966.5 0 ^ 2005 06 18 10:24:38 +267871 4754596 1970.4 0 ^ 2005 06 18 10:25:03 +267866 4754654 1975.6 0 ^ 2005 06 18 10:25:39 +267851 4754714 1980.9 0 ^ 2005 06 18 10:26:19 +267871 4754747 1984.3 0 ^ 2005 06 18 10:26:42 +267849 4754767 1988.1 0 ^ 2005 06 18 10:27:01 +267815 4754749 1991 0 ^ 2005 06 18 10:27:23 +267782 4754702 1995.4 0 ^ 2005 06 18 10:27:58 +267750 4754675 1999.2 0 ^ 2005 06 18 10:28:23 +267728 4754654 2002.1 0 ^ 2005 06 18 10:28:42 +267726 4754647 2002.6 0 ^ 2005 06 18 10:28:46 +267709 4754604 2006.9 0 ^ 2005 06 18 10:29:14 +267655 4754580 2012.7 0 ^ 2005 06 18 10:29:49 +267611 4754584 2016 0 ^ 2005 06 18 10:30:17 +267548 4754622 2020.8 0 ^ 2005 06 18 10:30:59 +267511 4754632 2024.7 0 ^ 2005 06 18 10:31:22 +267456 4754653 2029.5 0 ^ 2005 06 18 10:32:00 +267408 4754643 2033.3 0 ^ 2005 06 18 10:32:30 +267353 4754614 2037.7 0 ^ 2005 06 18 10:33:06 +267295 4754616 2042.5 0 ^ 2005 06 18 10:33:42 +267261 4754608 2046.3 0 ^ 2005 06 18 10:34:06 +267257 4754541 2050.1 0 ^ 2005 06 18 10:34:39 +267242 4754494 2055.4 0 ^ 2005 06 18 10:35:09 +267232 4754456 2059.8 0 ^ 2005 06 18 10:35:35 +267196 4754385 2066.5 0 ^ 2005 06 18 10:36:25 +267204 4754347 2069.9 0 ^ 2005 06 18 10:36:48 +267207 4754337 2070.8 0 ^ 2005 06 18 10:36:54 +267197 4754323 2073.7 0 ^ 2005 06 18 10:37:07 +267187 4754326 2075.6 0 ^ 2005 06 18 10:37:14 +267174 4754358 2079.5 0 ^ 2005 06 18 10:37:32 +267161 4754430 2086.7 0 ^ 2005 06 18 10:38:15 +267149 4754485 2092.4 0 ^ 2005 06 18 10:38:48 +267145 4754487 2093.9 0 ^ 2005 06 18 10:38:52 +267127 4754512 2096.8 0 ^ 2005 06 18 10:39:12 +267112 4754534 2099.7 0 ^ 2005 06 18 10:39:30 +267076 4754571 2104.5 0 ^ 2005 06 18 10:40:05 +267076 4754573 2104.5 0 ^ 2005 06 18 10:40:06 +267070 4754583 2106.4 0 ^ 2005 06 18 10:40:15 +267041 4754613 2111.2 0 ^ 2005 06 18 10:40:43 +267036 4754618 2111.7 0 ^ 2005 06 18 10:40:48 +267013 4754628 2114.1 0 ^ 2005 06 18 10:41:06 +267010 4754626 2114.6 0 ^ 2005 06 18 10:41:09 +266999 4754626 2116 0 ^ 2005 06 18 10:41:17 +266961 4754601 2118.4 0 ^ 2005 06 18 10:41:44 +266960 4754599 2118.4 0 ^ 2005 06 18 10:41:47 +266952 4754594 2118.4 0 ^ 2005 06 18 10:41:52 +266933 4754590 2118.9 0 ^ 2005 06 18 10:42:06 +266931 4754593 2119.4 0 ^ 2005 06 18 10:42:25 +266928 4754595 2119.8 0 ^ 2005 06 18 10:42:29 +266919 4754598 2120.8 0 NAME:3 ^ 2005 06 18 10:42:43 +;¤bitmap C:\Mesdoc\Mes images\pic midi\DSCF0449.JPG +;¤note +Au col, fini la route, bonjour les touristes! +;¤end +266921 4754595 2119.8 0 ^ 2005 06 18 10:45:07 +266919 4754598 2120.8 0 ^ 2005 06 18 10:45:24 +266919 4754600 2120.8 0 ^ 2005 06 18 10:45:26 +266916 4754605 2121.3 0 ^ 2005 06 18 10:45:32 +266914 4754610 2121.8 0 ^ 2005 06 18 10:45:53 +266916 4754610 2121.3 0 ^ 2005 06 18 10:46:24 +266919 4754602 2120.8 0 ^ 2005 06 18 10:46:43 +266918 4754600 2120.8 0 ^ 2005 06 18 10:47:29 +266919 4754600 2120.8 0 ^ 2005 06 18 10:47:58 +266923 4754607 2120.8 0 ^ 2005 06 18 10:48:27 +266923 4754609 2120.8 0 ^ 2005 06 18 10:48:40 +266921 4754610 2120.8 0 ^ 2005 06 18 10:48:43 +266914 4754607 2121.3 0 ^ 2005 06 18 10:49:01 +266907 4754610 2121.8 0 ^ 2005 06 18 10:49:07 +266861 4754626 2124.7 0 ^ 2005 06 18 10:49:34 +266824 4754644 2127.5 0 ^ 2005 06 18 10:49:57 +266819 4754646 2128 0 ^ 2005 06 18 10:50:00 +266805 4754649 2129.5 0 ^ 2005 06 18 10:50:09 +266737 4754664 2134.3 0 ^ 2005 06 18 10:50:49 +266708 4754688 2137.1 0 ^ 2005 06 18 10:51:13 +266692 4754715 2139.1 0 ^ 2005 06 18 10:51:30 +266686 4754742 2142 0 ^ 2005 06 18 10:51:49 +266708 4754772 2145.8 0 ^ 2005 06 18 10:52:12 +266721 4754812 2150.1 0 ^ 2005 06 18 10:52:37 +266734 4754864 2153.5 0 ^ 2005 06 18 10:53:06 +266734 4754917 2157.8 0 ^ 2005 06 18 10:53:38 +266732 4754928 2159.3 0 ^ 2005 06 18 10:53:55 +266731 4754936 2160.2 0 ^ 2005 06 18 10:54:27 +266732 4754967 2163.6 0 ^ 2005 06 18 10:54:44 +266742 4754995 2166.5 0 ^ 2005 06 18 10:55:02 +266740 4755002 2166.9 0 ^ 2005 06 18 10:55:07 +266711 4755029 2167.9 0 ^ 2005 06 18 10:55:30 +266704 4755085 2170.3 0 ^ 2005 06 18 10:56:00 +266713 4755127 2174.6 0 ^ 2005 06 18 10:56:27 +266728 4755151 2177.5 0 ^ 2005 06 18 10:56:54 +266726 4755153 2178 0 ^ 2005 06 18 10:57:22 +266753 4755183 2181.4 0 ^ 2005 06 18 10:57:42 +266802 4755222 2185.7 0 ^ 2005 06 18 10:58:16 +266824 4755257 2188.6 0 ^ 2005 06 18 10:58:46 +266822 4755257 2187.1 0 NAME:4 ^ 2005 06 18 10:59:13 +;¤bitmap C:\Mesdoc\Mes images\pic midi\DSCF0458.JPG +;¤note +La piste semble bien enneigée... +;¤end +266822 4755255 2188.1 0 ^ 2005 06 18 10:59:51 +266855 4755289 2192.9 0 ^ 2005 06 18 11:01:09 +266881 4755329 2196.3 0 ^ 2005 06 18 11:01:31 +266899 4755386 2200.6 0 ^ 2005 06 18 11:02:02 +266889 4755427 2204.9 0 ^ 2005 06 18 11:02:24 +266829 4755462 2208.8 0 ^ 2005 06 18 11:03:02 +266824 4755465 2209.2 0 ^ 2005 06 18 11:03:06 +266823 4755472 2210.2 0 ^ 2005 06 18 11:03:13 +266819 4755474 2211.7 0 ^ 2005 06 18 11:03:27 +266806 4755487 2212.1 0 ^ 2005 06 18 11:03:48 +266800 4755492 2212.1 0 ^ 2005 06 18 11:04:00 +266765 4755517 2216.9 0 ^ 2005 06 18 11:04:25 +266732 4755544 2220.3 0 ^ 2005 06 18 11:04:51 +266701 4755571 2223.7 0 ^ 2005 06 18 11:05:17 +266661 4755566 2226.1 0 ^ 2005 06 18 11:05:39 +266604 4755539 2230.4 0 ^ 2005 06 18 11:06:14 +266577 4755530 2232.3 0 NAME:5 ^ 2005 06 18 11:06:30 +;¤bitmap C:\Mesdoc\Mes images\pic midi\DSCF0459.JPG +;¤note +Entrée du premier tunnel. Bien plein! +;¤end +266570 4755530 2232.8 0 ^ 2005 06 18 11:06:34 +266546 4755546 2237.1 0 ^ 2005 06 18 11:06:57 +266547 4755553 2237.6 0 ^ 2005 06 18 11:07:19 +266539 4755577 2239 0 1 ^ 2005 06 18 11:08:05 +266531 4755570 2244.3 0 ^ 2005 06 18 11:08:16 +266530 4755584 2244.8 0 ^ 2005 06 18 11:08:34 +266532 4755587 2244.8 0 ^ 2005 06 18 11:08:41 +266557 4755612 2247.7 0 ^ 2005 06 18 11:09:03 +266575 4755664 2249.1 0 ^ 2005 06 18 11:09:28 +266584 4755683 2249.6 0 ^ 2005 06 18 11:09:36 +266585 4755747 2251.5 0 ^ 2005 06 18 11:10:06 +266583 4755845 2253.5 0 ^ 2005 06 18 11:10:56 +266582 4755874 2254.9 0 ^ 2005 06 18 11:11:12 +266566 4755908 2258.3 0 ^ 2005 06 18 11:11:34 +266562 4755955 2260.7 0 ^ 2005 06 18 11:12:02 +266541 4756001 2263.6 0 ^ 2005 06 18 11:12:31 +266518 4756050 2266.4 0 ^ 2005 06 18 11:13:04 +266495 4756096 2270.8 0 ^ 2005 06 18 11:13:38 +266475 4756168 2274.6 0 ^ 2005 06 18 11:14:25 diff --git a/reference/route/cst-sample.cst.gz b/reference/route/cst-sample.cst.gz new file mode 100644 index 0000000000000000000000000000000000000000..c6c02b8d88ff2ffe8cef68da2246d71c92883536 GIT binary patch literal 4470 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 IPv$xR053)(Jpcdz literal 0 HcmV?d00001 diff --git a/reference/route/cst-sample.gpx b/reference/route/cst-sample.gpx new file mode 100644 index 000000000..4e0e41509 --- /dev/null +++ b/reference/route/cst-sample.gpx @@ -0,0 +1,1312 @@ + + + + + + 1272.900000 + + 1 + Vue de notre chemin du retour.., mais c'est par la route qu'on monte + Vue de notre chemin du retour.., mais c'est par la route qu'on monte + file://C:/Mesdoc/Mes%20images/pic%20midi/DSCF0446.JPG + + + 1525.300000 + + 2 + Notre objectif. + Notre objectif. + file://C:/Mesdoc/Mes%20images/pic%20midi/DSCF0448.JPG + + + 2120.800000 + + 3 + Au col, fini la route, bonjour les touristes! + Au col, fini la route, bonjour les touristes! + file://C:/Mesdoc/Mes%20images/pic%20midi/DSCF0449.JPG + + + 2187.100000 + + 4 + La piste semble bien enneigée... + La piste semble bien enneigée... + file://C:/Mesdoc/Mes%20images/pic%20midi/DSCF0458.JPG + + + 2232.300000 + + 5 + Entrée du premier tunnel. Bien plein! + Entrée du premier tunnel. Bien plein! + file://C:/Mesdoc/Mes%20images/pic%20midi/DSCF0459.JPG + + + + 1272.900000 + + 1 + Vue de notre chemin du retour.., mais c'est par la route qu'on monte + + + 1525.300000 + + 2 + Notre objectif. + + + 2120.800000 + + 3 + Au col, fini la route, bonjour les touristes! + + + 2187.100000 + + 4 + La piste semble bien enneigée... + + + 2232.300000 + + 5 + Entrée du premier tunnel. Bien plein! + + + + + + 1266.200000 + + + + 1268.100000 + + + + 1267.600000 + + + + 1268.100000 + + + + 1268.600000 + + + + 1270.000000 + + + + 1271.500000 + + + + 1274.400000 + + + + 1273.400000 + + + + 1272.900000 + + 1 + Vue de notre chemin du retour.., mais c'est par la route qu'on monte + + + 1272.900000 + + + + 1273.900000 + + + + 1280.100000 + + + + 1286.400000 + + + + 1286.900000 + + + + 1288.800000 + + + + 1290.700000 + + + + 1291.200000 + + + + 1291.200000 + + + + 1291.200000 + + + + 1291.200000 + + + + 1307.000000 + + + + 1307.000000 + + + + 1307.500000 + + + + 1308.500000 + + + + 1311.400000 + + + + 1312.300000 + + + + 1317.600000 + + + + 1320.000000 + + + + 1326.300000 + + + + 1326.300000 + + + + 1334.900000 + + + + 1343.100000 + + + + 1350.300000 + + + + 1356.600000 + + + + 1362.300000 + + + + 1368.100000 + + + + 1371.500000 + + + + 1372.900000 + + + + 1382.500000 + + + + 1388.300000 + + + + 1391.600000 + + + + 1403.200000 + + + + 1414.200000 + + + + 1424.300000 + + + + 1434.400000 + + + + 1437.300000 + + + + 1440.200000 + + + + 1447.900000 + + + + 1450.300000 + + + + 1456.500000 + + + + 1459.400000 + + + + 1465.200000 + + + + 1521.900000 + + + + 1521.400000 + + + + 1524.300000 + + + + 1525.300000 + + 2 + Notre objectif. + + + 1525.300000 + + + + 1524.300000 + + + + 1524.800000 + + + + 1526.200000 + + + + 1530.100000 + + + + 1530.600000 + + + + 1533.000000 + + + + 1536.800000 + + + + 1539.200000 + + + + 1561.800000 + + + + 1565.200000 + + + + 1568.000000 + + + + 1571.900000 + + + + 1572.900000 + + + + 1572.400000 + + + + 1572.400000 + + + + 1579.600000 + + + + 1584.900000 + + + + 1591.600000 + + + + 1595.900000 + + + + 1602.200000 + + + + 1609.400000 + + + + 1616.100000 + + + + 1623.300000 + + + + 1626.200000 + + + + 1630.500000 + + + + 1636.300000 + + + + 1643.000000 + + + + 1648.800000 + + + + 1652.600000 + + + + 1656.000000 + + + + 1657.500000 + + + + 1672.400000 + + + + 1678.100000 + + + + 1683.400000 + + + + 1689.700000 + + + + 1694.900000 + + + + 1700.200000 + + + + 1707.000000 + + + + 1713.700000 + + + + 1716.100000 + + + + 1715.600000 + + + + 1716.100000 + + + + 1716.100000 + + + + 1716.100000 + + + + 1716.600000 + + + + 1717.100000 + + + + 1721.400000 + + + + 1725.200000 + + + + 1728.600000 + + + + 1730.500000 + + + + 1730.000000 + + + + 1732.900000 + + + + 1733.400000 + + + + 1734.800000 + + + + 1735.800000 + + + + 1736.300000 + + + + 1740.100000 + + + + 1743.000000 + + + + 1744.000000 + + + + 1744.900000 + + + + 1747.300000 + + + + 1747.300000 + + + + 1747.300000 + + + + 1818.000000 + + + + 1802.100000 + + + + 1802.100000 + + + + 1803.600000 + + + + 1804.500000 + + + + 1806.000000 + + + + 1808.900000 + + + + 1811.700000 + + + + 1815.600000 + + + + 1817.500000 + + + + 1822.300000 + + + + 1826.600000 + + + + 1832.400000 + + + + 1837.200000 + + + + 1843.000000 + + + + 1845.900000 + + + + 1851.200000 + + + + 1856.000000 + + + + 1856.000000 + + + + 1856.900000 + + + + 1859.300000 + + + + 1860.800000 + + + + 1861.700000 + + + + 1865.100000 + + + + 1870.400000 + + + + 1874.700000 + + + + 1879.500000 + + + + 1880.500000 + + + + 1881.000000 + + + + 1881.900000 + + + + 1886.700000 + + + + 1892.000000 + + + + 1896.300000 + + + + 1899.700000 + + + + 1903.100000 + + + + 1905.500000 + + + + 1906.400000 + + + + 1911.200000 + + + + 1915.600000 + + + + 1919.400000 + + + + 1922.800000 + + + + 1928.500000 + + + + 1933.800000 + + + + 1937.200000 + + + + 1939.600000 + + + + 1942.000000 + + + + 1941.500000 + + + + 1940.600000 + + + + 1941.000000 + + + + 1942.000000 + + + + 1942.500000 + + + + 1945.400000 + + + + 1948.700000 + + + + 1954.500000 + + + + 1958.300000 + + + + 1962.700000 + + + + 1966.500000 + + + + 1970.400000 + + + + 1975.600000 + + + + 1980.900000 + + + + 1984.300000 + + + + 1988.100000 + + + + 1991.000000 + + + + 1995.400000 + + + + 1999.200000 + + + + 2002.100000 + + + + 2002.600000 + + + + 2006.900000 + + + + 2012.700000 + + + + 2016.000000 + + + + 2020.800000 + + + + 2024.700000 + + + + 2029.500000 + + + + 2033.300000 + + + + 2037.700000 + + + + 2042.500000 + + + + 2046.300000 + + + + 2050.100000 + + + + 2055.400000 + + + + 2059.800000 + + + + 2066.500000 + + + + 2069.900000 + + + + 2070.800000 + + + + 2073.700000 + + + + 2075.600000 + + + + 2079.500000 + + + + 2086.700000 + + + + 2092.400000 + + + + 2093.900000 + + + + 2096.800000 + + + + 2099.700000 + + + + 2104.500000 + + + + 2104.500000 + + + + 2106.400000 + + + + 2111.200000 + + + + 2111.700000 + + + + 2114.100000 + + + + 2114.600000 + + + + 2116.000000 + + + + 2118.400000 + + + + 2118.400000 + + + + 2118.400000 + + + + 2118.900000 + + + + 2119.400000 + + + + 2119.800000 + + + + 2120.800000 + + 3 + Au col, fini la route, bonjour les touristes! + + + 2119.800000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2121.300000 + + + + 2121.800000 + + + + 2121.300000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2121.300000 + + + + 2121.800000 + + + + 2124.700000 + + + + 2127.500000 + + + + 2128.000000 + + + + 2129.500000 + + + + 2134.300000 + + + + 2137.100000 + + + + 2139.100000 + + + + 2142.000000 + + + + 2145.800000 + + + + 2150.100000 + + + + 2153.500000 + + + + 2157.800000 + + + + 2159.300000 + + + + 2160.200000 + + + + 2163.600000 + + + + 2166.500000 + + + + 2166.900000 + + + + 2167.900000 + + + + 2170.300000 + + + + 2174.600000 + + + + 2177.500000 + + + + 2178.000000 + + + + 2181.400000 + + + + 2185.700000 + + + + 2188.600000 + + + + 2187.100000 + + 4 + La piste semble bien enneigée... + + + 2188.100000 + + + + 2192.900000 + + + + 2196.300000 + + + + 2200.600000 + + + + 2204.900000 + + + + 2208.800000 + + + + 2209.200000 + + + + 2210.200000 + + + + 2211.700000 + + + + 2212.100000 + + + + 2212.100000 + + + + 2216.900000 + + + + 2220.300000 + + + + 2223.700000 + + + + 2226.100000 + + + + 2230.400000 + + + + 2232.300000 + + 5 + Entrée du premier tunnel. Bien plein! + + + 2232.800000 + + + + 2237.100000 + + + + 2237.600000 + + + + + + + + 2239.000000 + + + + 2244.300000 + + + + 2244.800000 + + + + 2244.800000 + + + + 2247.700000 + + + + 2249.100000 + + + + 2249.600000 + + + + 2251.500000 + + + + 2253.500000 + + + + 2254.900000 + + + + 2258.300000 + + + + 2260.700000 + + + + 2263.600000 + + + + 2266.400000 + + + + 2270.800000 + + + + 2274.600000 + + + + + diff --git a/reference/route/destinator_itn.dat b/reference/route/destinator_itn.dat new file mode 100644 index 0000000000000000000000000000000000000000..3b5275bdc13386b3f9abcdbc819812bd67ef21d8 GIT binary patch literal 5752 zcmd6reN0tl9LFEFsF*8tZMw`Yi(Dh6csuuAAcT9bS6<@%RTfgdK$vBUYxVB@NVNi>A}j_jexP*0+1lm4DLbZ1Vfw`F%dW z^PJ!Fa*kUqRki936{+T^0z@^c0#~h4%B4Ii6PHI7t0Md>zf`E@xGL0YRfm6Ps9d!W zj%Db>t6qW5R4Yv{{_}rY(}SB{zIY_>P}pPJ%OmWb6xM8T2h1#0IaMJtvcZyy3~J3> zMEPsiF5KRG8{A0?a?izp%bGobxw+tGgPf-Fl^b!fIVv&+UgS`PENU{a}tTTx+pN7ySidPP{kLc$NS8@TUZ$|d-k9K%cShFoS)rG3l^*KuS{ldM8zO=pL z>U?BSF+IF592u}?Pv8s;+-tmf-@b_5q6aSSxaI{hwQ#rhSrA#X$C_vxBkG9VqTg*C zPHY3Qam`y#M}o+jJ;8`}7~~#pN+N&FG5eugyFuLQn$he4ku`g)i3aK?9~CWitq`rm zoLXYets2CuaOo9?d(}E_vhDf($mRZhy`6c;g*CgZa)~zYyU?8ZFThwbvfju{FEnTV zGVX3f=S4o*cnn!&FWlA8h%8vM%{q%X6$67|&UlIZwMS;PZ~g|vr_y$Pe;P#A>*=3!9F;eOB3<9n0J2Kmk z9R{(!=e>ze5Lu6p7>BycHlMWzdz%yHZ1WjcsA~LOWv=lnu(sFY>5sQ6m;C0Q`W-SY z{(auBn~^E&@njl<5s?+vKvn37-J(xT+xO{l5EDXg^!0$qnmtxeLpU)QlOo)Au6Zg@ z_*;h^ui88j=~?7?I1r;9=WCxWY+8nPL}=GN7jma5$#>S?y#(mhfZa+yaqCB_E?i;70$tF ztN^ppiSvenT7>GXMU5^tp9c4*b@wl2jUOY6mg8-m8<7QTc3Ed(AFDtev0LnZ$u`PzMAMsVa=Xk8OX|~$${2DV?uZ0P7tqm<}Q05MAqXcN@dAC zJF)i5y07007Gmv}^X;AN!QZ~rKUwCQy7YEfJ91)u=Q+vzjxlS^7qMHkYvAV-b3u$h z-QhY8B5U>p9(Umwc+xSr=t&#rWX%$hyH$qq1mWUaUt(FcZl zn-s`1%X-51g3Ovd)@1t_RY&X={rHe8g?i7PEC7);djb>X{nCjlll>wcJ4z<3 z@`fpIl)gPgPFX9}8uQ(X`_{T4zW&xv@_x6qYex$*V$H6=8QIJ_lQqT{v0HRQNny*e$wj(_n@? z$C{h<2P#2i&7NRHS)Xk^FU3ftjm%sLK+n%9RfvIVb^5>s+cXeEZI{n)1CjN3h*4N|^qMmov0HR(?xVwV pKuoI+uh(qy9!CmGl38t+_Y8R^3})@$S~Q%)9+{_iw1nE35zj literal 0 HcmV?d00001 diff --git a/reference/route/destinator_itn.txt b/reference/route/destinator_itn.txt new file mode 100644 index 000000000..0d8b15930 --- /dev/null +++ b/reference/route/destinator_itn.txt @@ -0,0 +1,47 @@ +No,Latitude,Longitude,Name,Notes +1,42.430950,-71.107628,"BELLEVUE","Bellevue Parking Lot" +2,42.431240,-71.109236,"GATE6","Gate 6" +3,42.434980,-71.109942,"PANTHRCAVE","Panther Cave" +4,42.436757,-71.113223,"6014MEADOW","6014MEADOW" +5,42.439018,-71.114456,"6006","600698" +6,42.438594,-71.114803,"6006BLUE","6006BLUE" +7,42.438917,-71.116146,"5096","5096" +8,42.438878,-71.119277,"5066","5066" +9,42.439227,-71.119689,"5067","5067" +10,42.439993,-71.120925,"5058ROAD","Road Crossing" +11,42.441727,-71.121676,"5150TANK","Water Tank" +12,42.443904,-71.122044,"5142","5142" +13,42.445359,-71.122845,"5144SUMMIT","Summit" +14,42.447298,-71.121447,"5156","5156" +15,42.449765,-71.122320,"5148NANEPA","Nanepashemet Road Crossing" +16,42.451442,-71.121746,"5258","5258" +17,42.453256,-71.121211,"5252PURPLE","Purple Rock Hill" +18,42.456252,-71.119356,"527631","527631" +19,42.456592,-71.119676,"527614","527614" +20,42.457388,-71.119845,"5267OBSTAC","Obstacle" +21,42.458148,-71.119135,"5278","5278" +22,42.459377,-71.117693,"5289","5289" +23,42.464183,-71.119828,"5374FIRE","5374FIRE" +24,42.465650,-71.119399,"5376","5376" +25,42.465913,-71.119328,"5376STREAM","Stream Crossing" +26,42.467110,-71.113574,"6328","6328" +27,42.466459,-71.110067,"635722","635722" +28,42.466557,-71.109410,"635783","635783" +29,42.463495,-71.107117,"6373","6373" +30,42.465687,-71.107360,"BEAR HILL","Bear Hill Tower" +31,42.459986,-71.106170,"6289","6289" +32,42.457616,-71.105116,"6297","6297" +33,42.453845,-71.105206,"6283","6283" +34,42.451430,-71.105413,"6280","6280" +35,42.448448,-71.106158,"6177","6177" +36,42.447804,-71.106624,"6176","6176" +37,42.444773,-71.108882,"6153","6153" +38,42.443592,-71.106301,"6171","6171" +39,42.442981,-71.111441,"6131","6131" +40,42.442196,-71.110975,"6130","6130" +41,42.441754,-71.113220,"6029","6029" +42,42.439018,-71.114456,"6006","600698" +43,42.436757,-71.113223,"6014MEADOW","6014MEADOW" +44,42.434980,-71.109942,"PANTHRCAVE","Panther Cave" +45,42.431240,-71.109236,"GATE6","Gate 6" +46,42.430950,-71.107628,"BELLEVUE","Bellevue Parking Lot" diff --git a/reference/route/mag_pdb-sample.gpx b/reference/route/mag_pdb-sample.gpx new file mode 100644 index 000000000..f2fef9010 --- /dev/null +++ b/reference/route/mag_pdb-sample.gpx @@ -0,0 +1,1034 @@ + + + + + + Jägersburg in Forchheim geradeaus weiter auf Eisenbahnstrasse + Jägersburg in Forchheim geradeaus weiter auf Eisenbahnstrasse + Eisenbahnstrasse + + + Rettern in Jägersburg halb rechts halten auf Fürstenweg (FO17) + Rettern in Jägersburg halb rechts halten auf Fürstenweg (FO17) + Fürstenweg (FO17) + + + Kauernhofen bei D 91330 Eggolsheim/Rettern + Kauernhofen bei D 91330 Eggolsheim/Rettern + FO11\Kanzelstrasse + + + Eggolsheim bei D 91330 Eggolsheim/Kauernhofen + Eggolsheim bei D 91330 Eggolsheim/Kauernhofen + FO11\Andreas-Knauer-Strasse + + + Weigelshofen in Eggolsheim rechts abbiegen auf FO5 + Weigelshofen in Eggolsheim rechts abbiegen auf FO5 + FO5 + + + Drosendorf a. Eggerbach rechts abbiegen auf Bachgasse + Drosendorf a. Eggerbach rechts abbiegen auf Bachgasse + Bachgasse + + + Ebermannstadt bei D 91320 Ebermannstadt/Feuerstein + Ebermannstadt bei D 91320 Ebermannstadt/Feuerstein + FO41 + + + Gasseldorf bei D91320 Ebermannstadt + Gasseldorf bei D91320 Ebermannstadt + ST2260\Breitenbacher Strasse + + + Streitberg bei D91320 Ebermannstadt/Gasseldorf + Streitberg bei D91320 Ebermannstadt/Gasseldorf + B470 + + + Unterleinleiter bei D 91346 Wiesenttal/Störnhof + Unterleinleiter bei D 91346 Wiesenttal/Störnhof + Unterleinleiter bei D 91346 Wiesenttal/Störnhof + + + Traindorf bei D 91364 Unterleinleiter + Traindorf bei D 91364 Unterleinleiter + ST2187 + + + Neumühle bei D 91332 Heiligenstadt + Neumühle bei D 91332 Heiligenstadt + ST2187\Hauptstrasse + + + Hohenpölz in Neumühle links abbiegen auf Neumühle + Hohenpölz in Neumühle links abbiegen auf Neumühle + Neumühle + + + Voitmannsdorf bei D 91332 Heiligenstadt/Hohenpölz + Voitmannsdorf bei D 91332 Heiligenstadt/Hohenpölz + BA11\Hohenpölz + + + Hollfeld bei D 96142 Hollfeld/Drosendorf a d Aufseß + Hollfeld bei D 96142 Hollfeld/Drosendorf a d Aufseß + ST2281\Drosendorf an der Aufsess + + + Stechendorf bei D96142 Hollfeld + Stechendorf bei D96142 Hollfeld + ST2191\Bahnhofstrasse + + + Nankendorf D 95515 Plankenfels + Nankendorf D 95515 Plankenfels + ST2191\Hauptstrasse + + + Waischenfeld halb links halten auf Gutenbiegen (ST2191) + Waischenfeld halb links halten auf Gutenbiegen (ST2191) + Gutenbiegen (ST2191) + + + Behringersmühle bei D 91327 Gößweinstein/Schweigelberg + Behringersmühle bei D 91327 Gößweinstein/Schweigelberg + ST2191 + + + Tüchersfeld links abbiegen auf B470 + Tüchersfeld links abbiegen auf B470 + B470 + + + Pottenstein bei D 91278 Pottenstein/Tüchersfeld + Pottenstein bei D 91278 Pottenstein/Tüchersfeld + B470 + + + Wannberg bei D 91278 Pottenstein + Wannberg bei D 91278 Pottenstein + B470\Pegnitzer Strasse + + + Bronn bei D91257 Pegnitz/Lüglas + Bronn bei D91257 Pegnitz/Lüglas + B470 + + + Kühlenfels in Bronn rechts abbiegen auf BT33 Kühlenfelser Strasse + Kühlenfels in Bronn rechts abbiegen auf BT33 Kühlenfelser Strasse + BT33 Kühlenfelser Strasse + + + Kirchenbirkig bei D 91278 Pottenstein/Kleinkirchenbirkig + Kirchenbirkig bei D 91278 Pottenstein/Kleinkirchenbirkig + BT33\Langhausenweg + + + Siegmannsbrunn in Kirchenbirkig rechts abbiegen auf Sankt-Johannes-Strasse (ST2163) + Siegmannsbrunn in Kirchenbirkig rechts abbiegen auf Sankt-Johannes-Strasse (ST2163) + Sankt-Johannes-Strasse (ST2163) + + + Gössweinstein bei D 91327 Gößweinstein/Hühnerloh + Gössweinstein bei D 91327 Gößweinstein/Hühnerloh + ST2685 + + + Kleingesee halb rechts halten auf ST2191 + Kleingesee halb rechts halten auf ST2191 + ST2191 + + + Bieberbach D 91327 Gößweinstein/Kleingesee + Bieberbach D 91327 Gößweinstein/Kleingesee + ST2191\Kleingesee + + + Wichsenstein bei D 91327 Gößweinstein/Wichsenstein + Wichsenstein bei D 91327 Gößweinstein/Wichsenstein + FO21 + + + Hardt in Wichsenstein links abbiegen auf Wichsenstein (FO37) + Hardt in Wichsenstein links abbiegen auf Wichsenstein (FO37) + Wichsenstein (FO37) + + + Wannbach in Sattelmannsburg halb links halten auf Sattelmannsburg (FO37) + Wannbach in Sattelmannsburg halb links halten auf Sattelmannsburg (FO37) + Sattelmannsburg (FO37) + + + Unterzaunsbach in Wannbach links abbiegen auf Wannbach (ST2260) + Unterzaunsbach in Wannbach links abbiegen auf Wannbach (ST2260) + Wannbach (ST2260) + + + Schweinthal bei D 91362 Pretzfeld/Unterzaunsbach + Schweinthal bei D 91362 Pretzfeld/Unterzaunsbach + ST2260\Unterzaunsbach + + + Egloffstein bei D 91349 Egloffstein + Egloffstein bei D 91349 Egloffstein + ST2260 + + + Thuisbrunn in Egloffstein rechts abbiegen auf Felsenkellerstrasse (ST2242) + Thuisbrunn in Egloffstein rechts abbiegen auf Felsenkellerstrasse (ST2242) + Felsenkellerstrasse (ST2242) + + + Hohenschwärz bei D 91322 Gräfenberg/Thuisbrunn + Hohenschwärz bei D 91322 Gräfenberg/Thuisbrunn + FO32 + + + Gräfenberg in Hohenschwärz halb links halten auf Hohenschwärz (FO32) + Gräfenberg in Hohenschwärz halb links halten auf Hohenschwärz (FO32) + Hohenschwärz (FO32) + + + Guttenberg bei D 91322 Gräfenberg/Guttenburg + Guttenberg bei D 91322 Gräfenberg/Guttenburg + FO28\Guttenburger Strasse + + + Walkersbrunn in Guttenberg rechts abbiegen auf Guttenberg (FO28) + Walkersbrunn in Guttenberg rechts abbiegen auf Guttenberg (FO28) + Guttenberg (FO28) + + + Weingarts bei D 91322 Gräfenberg/Schlichenreuth + Weingarts bei D 91322 Gräfenberg/Schlichenreuth + ST2236 + + + Kunreuth in Weingarts rechts abbiegen auf Weingarts (ST2236) + Kunreuth in Weingarts rechts abbiegen auf Weingarts (ST2236) + Weingarts (ST2236) + + + Gaiganz in Kunreuth links abbiegen auf Schlossstrasse (ST2242) + Gaiganz in Kunreuth links abbiegen auf Schlossstrasse (ST2242) + Schlossstrasse (ST2242) + + + Effeltrich bei D 91090 Effeltrich/Gaiganz + Effeltrich bei D 91090 Effeltrich/Gaiganz + ST2242\Gaiganzer Hauptstrasse + + + Honings bei D 91090 Effeltrich + Honings bei D 91090 Effeltrich + ST2242\Hauptstrasse + + + Dormitz bei D 91077 Neunkirchen + Dormitz bei D 91077 Neunkirchen + Friedhofstrasse + + + Neunhof bei D 90562 Kalchreuth + Neunhof bei D 90562 Kalchreuth + ST2243 + + + Kraftshof bei D 90427 Nürnberg/Neunhof + Kraftshof bei D 90427 Nürnberg/Neunhof + Obere Dorfstrasse + + + Buch in Kraftshof links abbiegen auf Kraftshofer Hauptstrasse + Buch in Kraftshof links abbiegen auf Kraftshofer Hauptstrasse + Kraftshofer Hauptstrasse + + + D 90403 Nürnberg/Sebald in Nürnberg links abbiegen auf B4R + D 90403 Nürnberg/Sebald in Nürnberg links abbiegen auf B4R + B4R + + + + + + RPT001 + bei D91301 Forchheim Jägersburg + Klosterstrasse + + + RPT002 + Jägersburg in Forchheim geradeaus weiter auf Eisenbahnstrasse + Eisenbahnstrasse + + + RPT003 + - links abbiegen auf B470 Theodor-Heuss-Allee + B470 Theodor-Heuss-Allee + + + RPT004 + - rechts abbiegen auf Untere Kellerstrasse (FO17) + Untere Kellerstrasse (FO17) + + + RPT005 + - halb links halten auf FO17 + FO17 + + + RPT006 + Rettern in Jägersburg halb rechts halten auf Fürstenweg (FO17) + Fürstenweg (FO17) + + + RPT007 + - halb links halten auf FO11 + FO11 + + + RPT008 + Kauernhofen bei D 91330 Eggolsheim/Rettern + FO11\Kanzelstrasse + + + RPT009 + bei D 91330 Eggolsheim/Kauernhofen in Kauernhofen links abbiegen auf Andreas-Knauer-Strasse (FO11) + Andreas-Knauer-Strasse (FO11) + + + RPT010 + Eggolsheim bei D 91330 Eggolsheim/Kauernhofen + FO11\Andreas-Knauer-Strasse + + + RPT011 + - halb rechts halten auf FO11 + FO11 + + + RPT012 + Weigelshofen in Eggolsheim rechts abbiegen auf FO5 + FO5 + + + RPT013 + Drosendorf a. Eggerbach rechts abbiegen auf Bachgasse + Bachgasse + + + RPT014 + bei D91330 Eggolsheim/Drosendorf in Drosendorf a. Eggerbach rechts abbiegen auf Feuersteinstrasse (FO41) + Feuersteinstrasse (FO41) + + + RPT015 + bei D 91320 Ebermannstadt/Feuerstein bei D91330 Eggolsheim/Drosendorf + FO41\Feuersteinstrasse + + + RPT016 + Ebermannstadt bei D 91320 Ebermannstadt/Feuerstein + FO41 + + + RPT017 + bei D91320 Ebermannstadt in Ebermannstadt links abbiegen auf Altweiherstrasse + Altweiherstrasse + + + RPT018 + - links abbiegen auf Altweiherstrasse + Altweiherstrasse + + + RPT019 + - rechts abbiegen auf Eschlipper Talstrasse (ST2260) + Eschlipper Talstrasse (ST2260) + + + RPT020 + Gasseldorf bei D91320 Ebermannstadt + ST2260\Breitenbacher Strasse + + + RPT021 + - links abbiegen auf B470 Breitenbacher Strasse + B470 Breitenbacher Strasse + + + RPT022 + Streitberg bei D91320 Ebermannstadt/Gasseldorf + B470 + + + RPT023 + bei D 91346 Wiesenttal/Streitberg in Streitberg links abbiegen auf Bahnhofstrasse (ST2186) + Bahnhofstrasse (ST2186) + + + RPT024 + bei D 91346 Wiesenttal/Störnhof bei D 91346 Wiesenttal/Streitberg + ST2186\Dorfplatz + + + RPT025 + - links abbiegen auf Hadergasse + Hadergasse + + + RPT026 + - geradeaus weiter auf Schauertal + Schauertal + + + RPT027 + - geradeaus auffahren + - geradeaus auffahren + + + RPT028 + - links abbiegen + - links abbiegen + + + RPT029 + Unterleinleiter bei D 91346 Wiesenttal/Störnhof + Unterleinleiter bei D 91346 Wiesenttal/Störnhof + + + RPT030 + bei D 91364 Unterleinleiter in Unterleinleiter rechts abbiegen auf Störnhofer Weg + Störnhofer Weg + + + RPT031 + - halb rechts halten auf Bahnhofstrasse + Bahnhofstrasse + + + RPT032 + - geradeaus weiter auf An der Leinleiter + An der Leinleiter + + + RPT033 + - rechts abbiegen auf ST2187 + ST2187 + + + RPT034 + Traindorf bei D 91364 Unterleinleiter + ST2187 + + + RPT035 + Neumühle bei D 91332 Heiligenstadt + ST2187\Hauptstrasse + + + RPT036 + - in Heiligenstadt in Oberfranken links abbiegen auf Hauptstrasse (ST2187) + Hauptstrasse (ST2187) + + + RPT037 + - rechts abbiegen auf ST2188 + ST2188 + + + RPT038 + Hohenpölz in Neumühle links abbiegen auf Neumühle + Neumühle + + + RPT039 + - geradeaus weiter auf BA11 + BA11 + + + RPT040 + - rechts abbiegen auf BA11 + BA11 + + + RPT041 + - rechts abbiegen auf BA11 + BA11 + + + RPT042 + - links abbiegen auf BA11 + BA11 + + + RPT043 + Voitmannsdorf bei D 91332 Heiligenstadt/Hohenpölz + BA11\Hohenpölz + + + RPT044 + - rechts abbiegen auf ST2281 + ST2281 + + + RPT045 + bei D 96142 Hollfeld/Drosendorf a d Aufseß in Drosendorf an der Aufsess halb links halten auf Drosendorf an der Aufsess (ST2281) + Drosendorf an der Aufsess (ST2281) + + + RPT046 + Hollfeld bei D 96142 Hollfeld/Drosendorf a d Aufseß + ST2281\Drosendorf an der Aufsess + + + RPT047 + - links halten auf Drosendorf an der Aufsess + Drosendorf an der Aufsess + + + RPT048 + - geradeaus weiter auf ST2281 + ST2281 + + + RPT049 + - links abbiegen auf ST2281 + ST2281 + + + RPT050 + bei D96142 Hollfeld in Hollfeld links abbiegen auf Forchheimer Strasse (ST2189) + Forchheimer Strasse (ST2189) + + + RPT051 + - rechts abbiegen auf Bahnhofstrasse (ST2191) + Bahnhofstrasse (ST2191) + + + RPT052 + Stechendorf bei D96142 Hollfeld + ST2191\Bahnhofstrasse + + + RPT053 + Nankendorf D 95515 Plankenfels + ST2191\Hauptstrasse + + + RPT054 + - rechts abbiegen auf Eichenmühle (ST2186/ST2191) + Eichenmühle (ST2186/ST2191) + + + RPT055 + - links abbiegen auf ST2191 + ST2191 + + + RPT056 + Waischenfeld halb links halten auf Gutenbiegen (ST2191) + Gutenbiegen (ST2191) + + + RPT057 + - links halten auf Gutenbiegen + Gutenbiegen + + + RPT058 + - halb rechts halten auf ST2191 + ST2191 + + + RPT059 + bei D 91327 Gößweinstein/Schweigelberg bei D 91344 Waischenfeld/Hammermühle + ST2191 + + + RPT060 + Behringersmühle bei D 91327 Gößweinstein/Schweigelberg + ST2191 + + + RPT061 + Tüchersfeld links abbiegen auf B470 + B470 + + + RPT062 + Pottenstein bei D 91278 Pottenstein/Tüchersfeld + B470 + + + RPT063 + - links abbiegen auf B470 + B470 + + + RPT064 + - halb links halten auf B470 + B470 + + + RPT065 + Wannberg bei D 91278 Pottenstein + B470\Pegnitzer Strasse + + + RPT066 + Bronn bei D91257 Pegnitz/Lüglas + B470 + + + RPT067 + - rechts abbiegen auf B2 + B2 + + + RPT068 + Kühlenfels in Bronn rechts abbiegen auf BT33 Kühlenfelser Strasse + BT33 Kühlenfelser Strasse + + + RPT069 + - halb links halten auf BT33 Kühlenfelser Strasse + BT33 Kühlenfelser Strasse + + + RPT070 + bei D 91278 Pottenstein/Kleinkirchenbirkig in Kühlenfels links abbiegen auf BT33 Kühlenfels + BT33 Kühlenfels + + + RPT071 + - halb links halten auf BT33 Langhausenweg + BT33 Langhausenweg + + + RPT072 + - halb rechts halten auf BT33 Langhausenweg + BT33 Langhausenweg + + + RPT073 + Kirchenbirkig bei D 91278 Pottenstein/Kleinkirchenbirkig + BT33\Langhausenweg + + + RPT074 + Siegmannsbrunn in Kirchenbirkig rechts abbiegen auf Sankt-Johannes-Strasse (ST2163) + Sankt-Johannes-Strasse (ST2163) + + + RPT075 + - halb links halten auf Sankt-Johannes-Strasse (ST2163) + Sankt-Johannes-Strasse (ST2163) + + + RPT076 + - links abbiegen auf ST2685 + ST2685 + + + RPT077 + bei D 91327 Gößweinstein/Hühnerloh halb links halten auf ST2685 + ST2685 + + + RPT078 + Gössweinstein bei D 91327 Gößweinstein/Hühnerloh + ST2685 + + + RPT079 + - links abbiegen auf ST2191 + ST2191 + + + RPT080 + Kleingesee halb rechts halten auf ST2191 + ST2191 + + + RPT081 + Bieberbach D 91327 Gößweinstein/Kleingesee + ST2191\Kleingesee + + + RPT082 + - in Kleingesee rechts abbiegen auf Kleingesee (ST2191) + Kleingesee (ST2191) + + + RPT083 + - halb rechts halten auf Kleingesee (FO43) + Kleingesee (FO43) + + + RPT084 + bei D 91327 Gößweinstein/Wichsenstein in Bieberbach rechts abbiegen auf Bieberbach (FO21) + Bieberbach (FO21) + + + RPT085 + Wichsenstein bei D 91327 Gößweinstein/Wichsenstein + FO21 + + + RPT086 + Hardt in Wichsenstein links abbiegen auf Wichsenstein (FO37) + Wichsenstein (FO37) + + + RPT087 + - rechts abbiegen auf FO37 + FO37 + + + RPT088 + Wannbach in Sattelmannsburg halb links halten auf Sattelmannsburg (FO37) + Sattelmannsburg (FO37) + + + RPT089 + - links abbiegen auf FO37 + FO37 + + + RPT090 + Unterzaunsbach in Wannbach links abbiegen auf Wannbach (ST2260) + Wannbach (ST2260) + + + RPT091 + Schweinthal bei D 91362 Pretzfeld/Unterzaunsbach + ST2260\Unterzaunsbach + + + RPT092 + Egloffstein bei D 91349 Egloffstein + ST2260 + + + RPT093 + Thuisbrunn in Egloffstein rechts abbiegen auf Felsenkellerstrasse (ST2242) + Felsenkellerstrasse (ST2242) + + + RPT094 + - geradeaus weiter auf FO32 + FO32 + + + RPT095 + bei D 91322 Gräfenberg/Thuisbrunn in Thuisbrunn links abbiegen auf Thuisbrunn (FO32) + Thuisbrunn (FO32) + + + RPT096 + Hohenschwärz bei D 91322 Gräfenberg/Thuisbrunn + FO32 + + + RPT097 + Gräfenberg in Hohenschwärz halb links halten auf Hohenschwärz (FO32) + Hohenschwärz (FO32) + + + RPT098 + - rechts abbiegen auf ST2191 + ST2191 + + + RPT099 + - rechts abbiegen auf FO14 + FO14 + + + RPT100 + bei D 91322 Gräfenberg/Guttenburg in Gräfenberg halb links halten auf Egloffsteiner Strasse (FO14) + Egloffsteiner Strasse (FO14) + + + RPT101 + - halb rechts halten auf Egloffsteiner Strasse (FO14) + Egloffsteiner Strasse (FO14) + + + RPT102 + - rechts abbiegen auf Kasberger Strasse (FO14) + Kasberger Strasse (FO14) + + + RPT103 + - links abbiegen auf Am Bach (FO28) + Am Bach (FO28) + + + RPT104 + - halb rechts halten auf Guttenburger Strasse (FO28) + Guttenburger Strasse (FO28) + + + RPT105 + Guttenberg bei D 91322 Gräfenberg/Guttenburg + FO28\Guttenburger Strasse + + + RPT106 + Walkersbrunn in Guttenberg rechts abbiegen auf Guttenberg (FO28) + Guttenberg (FO28) + + + RPT107 + - halb links halten auf Guttenberg (FO28) + Guttenberg (FO28) + + + RPT108 + - halb links halten auf Guttenberg (FO28) + Guttenberg (FO28) + + + RPT109 + bei D 91322 Gräfenberg/Walkersbrunn in Walkersbrunn rechts abbiegen auf Walkersbrunn (ST2236) + Walkersbrunn (ST2236) + + + RPT110 + bei D 91322 Gräfenberg/Schlichenreuth bei D 91322 Gräfenberg/Walkersbrunn + ST2236\Walkersbrunn + + + RPT111 + - links abbiegen auf Walkersbrunn (ST2236) + Walkersbrunn (ST2236) + + + RPT112 + - links abbiegen auf Walkersbrunn (ST2236) + Walkersbrunn (ST2236) + + + RPT113 + Weingarts bei D 91322 Gräfenberg/Schlichenreuth + ST2236 + + + RPT114 + Kunreuth in Weingarts rechts abbiegen auf Weingarts (ST2236) + Weingarts (ST2236) + + + RPT115 + Gaiganz in Kunreuth links abbiegen auf Schlossstrasse (ST2242) + Schlossstrasse (ST2242) + + + RPT116 + - geradeaus weiter auf Badanger + Badanger + + + RPT117 + - geradeaus weiter auf ST2242 + ST2242 + + + RPT118 + - links abbiegen auf ST2242 + ST2242 + + + RPT119 + bei D 91090 Effeltrich/Gaiganz in Gaiganz halb rechts halten auf Gaiganzer Hauptstrasse (ST2242) + Gaiganzer Hauptstrasse (ST2242) + + + RPT120 + Effeltrich bei D 91090 Effeltrich/Gaiganz + ST2242\Gaiganzer Hauptstrasse + + + RPT121 + - halb links halten auf ST2242 + ST2242 + + + RPT122 + bei D 91090 Effeltrich in Effeltrich rechts abbiegen auf Gaiganzer Strasse (ST2242) + Gaiganzer Strasse (ST2242) + + + RPT123 + Honings bei D 91090 Effeltrich + ST2242\Hauptstrasse + + + RPT124 + - links abbiegen auf Neunkirchener Strasse (ST2242/ST2243) + Neunkirchener Strasse (ST2242/ST2243) + + + RPT125 + - links abbiegen auf Neunkirchener Strasse (ST2243) + Neunkirchener Strasse (ST2243) + + + RPT126 + bei D 91077 Neunkirchen in Neunkirchen am Brand rechts abbiegen auf Friedhofstrasse + Friedhofstrasse + + + RPT127 + Dormitz bei D 91077 Neunkirchen + Friedhofstrasse + + + RPT128 + - geradeaus weiter auf Erleinhofer Strasse + Erleinhofer Strasse + + + RPT129 + - links abbiegen auf Henkerstegstrasse + Henkerstegstrasse + + + RPT130 + - geradeaus weiter auf Erlanger Strasse (ST2243) + Erlanger Strasse (ST2243) + + + RPT131 + - halb rechts halten auf Erlanger Strasse (ST2243) + Erlanger Strasse (ST2243) + + + RPT132 + - geradeaus weiter auf ST2240 + ST2240 + + + RPT133 + bei D 91080 Uttenreuth/Habernhofermühle links abbiegen auf ST2243 + ST2243 + + + RPT134 + bei D 90562 Kalchreuth bei D 91080 Uttenreuth/Habernhofermühle + ST2243 + + + RPT135 + Neunhof bei D 90562 Kalchreuth + ST2243 + + + RPT136 + - in Kalchreuth einfahren in Kreisverkehr + - in Kalchreuth einfahren in Kreisverkehr + + + RPT137 + - 1. Möglichkeit aus Kreisverkehr ausfahren auf Fürther Strasse (ERH6) + Fürther Strasse (ERH6) + + + RPT138 + - geradeaus weiter auf N3 Obere Dorfstrasse + N3 Obere Dorfstrasse + + + RPT139 + Kraftshof bei D 90427 Nürnberg/Neunhof + Obere Dorfstrasse + + + RPT140 + - geradeaus weiter auf Kraftshofer Hauptstrasse + Kraftshofer Hauptstrasse + + + RPT141 + Buch in Kraftshof links abbiegen auf Kraftshofer Hauptstrasse + Kraftshofer Hauptstrasse + + + RPT142 + - halb rechts halten auf Am Kressenstein + Am Kressenstein + + + RPT143 + - geradeaus weiter auf Kraftshofer Hauptstrasse + Kraftshofer Hauptstrasse + + + RPT144 + - links abbiegen auf B4 Erlanger Strasse + B4 Erlanger Strasse + + + RPT145 + D 90403 Nürnberg/Sebald in Nürnberg links abbiegen auf B4R + B4R + + + RPT146 + - halb rechts halten auf B4R Hintermayrstrasse + B4R Hintermayrstrasse + + + RPT147 + - rechts abbiegen auf Äussere Sulzbacher Strasse + Äussere Sulzbacher Strasse + + + RPT148 + - rechts halten auf Sulzbacher Strasse + Sulzbacher Strasse + + + RPT149 + - links abbiegen auf Bauvereinstrasse + Bauvereinstrasse + + + RPT150 + - geradeaus weiter auf Wöhrder Talübergang + Wöhrder Talübergang + + + RPT151 + - geradeaus weiter auf Dürrenhofstrasse + Dürrenhofstrasse + + + RPT152 + - links abbiegen auf Stephanstrasse + Stephanstrasse + + + RPT153 + - links abbiegen auf Hintere Cramergasse + Hintere Cramergasse + + + RPT154 + - rechts abbiegen auf Burgerstrasse + Burgerstrasse + + + diff --git a/reference/route/mag_pdb-sample.pdb b/reference/route/mag_pdb-sample.pdb new file mode 100644 index 0000000000000000000000000000000000000000..f1664e064dcf44e8bbd5791a867dc3c9e0115d74 GIT binary patch literal 16183 zcmb7L%WfP=b{%-BuZU#}u*i&8J_NL3arB^vJ?chNZEm=5NlKDsm5M@DaT?b5dE>8` zO@Dv^16pa}bMB4IjI7EeISr^KG9&N%eIx&RySsh1Yqz^U&Hwl3i~s#U{@FkAZ!cfG z``hQmm;U$vgn#|Vzv_?wnf}(F)lnmS>LU%f3!_;lES^|>A*%b&&+DM{aqXWn))bYAd5h)>OZFDc5}_@fdiZx*ZfiADSqniK{J z-he28S8hTj(1R`GQ=?B6PGiDRV}5OSpmI&E3<_4*iKiU+ckt1!e{Zi%;zJNAAJG+J z3n7#ZFdZBftihTRlD>y}+F+T8FRc|-#Dby$@m7s0I6x`Q+2RhQ-`rk-cQIN6tM!F> zb$xxi+R|)~JN6*(!d!?%Vr+!YXoXGyy*yj2zqYH++LX{}>Z587Y>t_t%YUA*x)jn^!n!r)Axhl zG)lX*LVHx(h;T^{pM1HwMHGRXUzx=bLARUtiw`%Go_c}@*AlbDozIg&hq5I3l`8@Q z!Ei=o5ldr3XCVi6mtm)UWIsMg%AQZay#8z_9qZJ09LQdg@+wVjql4AHNs))e zC5<#L)}j$xdqqf{1AJqg2U%U_+UL+v2V>k*Ub@;L3Ed2_nl`GKZQ)9ZL{$-i`NjT8 zp~4oVg6{D+;8AlLvS^`P6&_J;2DT;a3b3a<3ibk%GHQm@6Z_<(_vGVKlC!V0I)5{%}2OKF1mJ2oP0@K-LwtM4&2K zNLdgn=*qadGe_p6P@0Qni*U5tEmp@FM%rcei?e44_*{iM@7G#ptE!=kclUxNZA@$w}?@0ZnL_f>t=))WeB zr3o%iQ3P&M1f~(amGlI-UJ^(h3J5qqq};&mYpI1M%gFN&H%zw>xk^hs0KO&#WQ{Tf zqz*?ihz*DwAfh6@Lg9=WLv^1>OI2bW9jYB=(K+K;yd1Cy{3+vF7t{kAUm}pC_q_2I z(v;e7g}{$LtcClUW=>0dNy%}x5!-KkgItxsB3;rwdN5@;KtTiCM>`c^&Ub1Vpb8xZ z_~~_IeJPIKc#Dv-cTR-rgbr$6O4h@&Vb5eG>?&K(e*#`W%6sP&cu6K%?GGBuT8S5H z1Isc$4MNSKyGEhA8WqIh(G0;{+}Oco%;yBb$^-jzUl7+g)%?cL|^H>-9~HJ+Td%N6P?&GAN6rb)m?dR4?<@G9lt z@^o?cW!FU+Vcf$iYv}nIZDb4#zxWvu^J=qLe}Z33I&=n(iO4cCFcBr!F05!4L^KH2 zBkcWgB_ogwI@P3I5^@c|F|`a$l%fr+xlUNM%HIP}1BW@iy=m89zOBBJuU>K!JoL|K zGHQ=SVQDeZ*$Pzm2YNyYf5s9|UZ6Gxp-2VPLeWGi;RuSREl(8=EV`LZ^?J|&j|#GA z(5DMYPLfat2MwM@Ej}%{j+`nr)^!wLh~9a~Eh7iLR!|3<5RshY)1DY7#CSyR1VwlX z-h>E4{rB7DPU_B~kdU5j&svWM9iedpt0J*lhYc~fn)Nt1y&TRdn$lpJK^4r{imNTU z-ZJsr6ymEfddpmZY6*`8P;@3zcF99a3n`r5u2xqlfsXTH-h4DK?yk1&-=)ONpJ?Eb zhuiH;vp#=bYPVX7exJ%jhbn`LMs)NvxD+h((43jo77l$m(*Q z2*vG9r24vim`xJq-(+g(P*&n>(X&{ce?xHv;_`Femy|1kB0)zFA>#BDbN5_fm4wAA zV8Z0n$-q#SAO(rfP>h3OMrPEQSb-=pqh@49VlTZ?Ch+v5x2#gu$cS*!Pv8)Toam)2 zB5e5Hm%y8UUKAv0E}iXVSi#5moEbvpq|%6G!AfK9g$!4Xq5#ve)QeAwq69%I%Su~H zKxb5hENx>i_mC*;#*~49M^cc4la~h0VWatFCBK8OZW(Z+_CA?%-D`Fg` zt(lMKFVTQHzzw@y1hW8d$@F))!5i=!)axy(qI3rRB((SW65uTuo3 zkTt9GllEq_T%$DI?iFYckivJ<=%H~zs?-vdP3IEIALjKn3;cKA*-vjp*%OgO8dHa? zCutO#EoIzLdUobr*Xo~p%n}1~-Y>V92&;g4iMVR?`{NuVx}vhPOdEU}WzcHIu*=L! z4rlTbVl<#S7YZ4+l#=NLN@5r!a_~DhK2Drs&LrxAf2ibwM-0oTX-rLFSm4aEF&A!fAT8~g-Jd!1Ywx-$N?qs>DUB9bd4Pf*-S^T8J2bf+S{L zX@S*Avrs8-{j^wLV`70Z5f>~n;OQ`=&5C7~jE zb-P*J-k2E!?$M=A+4;grCWx`pqIkeYJFStv-+bF{`&|4e+;kzeR)_4X(U^PSgk71b z47zJ6;HJgGVu{(XPvJT=#*{Y8u8<1abs)h(i5J%x-?qy9p<~gSI;cut5uA*MvC5-0 z>2smaVn1aggnhDXk$hw)h02wauCdHBv@lZ?e_C=_D~94Fdn@3}?5N^^LIsD+ZnCFS zE|NXY>OjaRagrqMeFaHR9afYG3_!_o!%XzaU&XEnVquRZNNj`FNiqsj${2~B6ci}u z5Mp5hvu1jM>Kx%yiaUwvnT)4c&mLpP=75^5vQFJ9r||&!6r>)WRFdF>uAo)sm>)?W zBfPR-TAiVWLKkU{_McamR=^!ZTstqvzm>!<>HRWXmE*2nZPcJsrbJ zXB92X2WaPJZiJeT!lQ3e=CE)fd8%M=3QH?6$vTU>S1@qCKy|s&FpjGvbKzv~RHBaY zQY98#mpU4Tm+9j|1&U-8U+}ldZeFOB?pEQVOjEx_8pwIUJe5$q4$HqT?$+Cmqn^7d zb#$E5v(hfEE0zII=ehyvfHn?}D)}^l2)?yfS?}Oog9DV#{IY3xUs?Je|Hk_!18Ig# zryj!FAki4h2aR%|<#O-5pu_zPY+cx_U9WDhuy#VJG@uKpth3)sjgl}#NRA%t9QPs0 ztr{^#X9O8>?dEQ|?Q?eyXv#NVqgHJ(ULIYZAzZeNyse}0$zozDHtnqA0OY>6ltUQz zeH#N<1XiA1S#41kDfoi5t~^vQFmBH|!Qkx9yxIJLyC`fajx%Oy_SugUW|BRnrGr6U zqL3!Wq9+j5S=%5E9i9|wB0?jmsdc!G*8lfEHeVk@n)I1WEEfH<;wd<(9~edbjuj6K zaA1xM$>g;|G+q6Sj%0jw7K5QGEe2a}1m3B`${O!;%ulQ|1HvFMW>P*7um!9w85y$7 z8>xAnRZJS(&o)5rRc~0BPymo`91{bs>IAiCx%k15F{62mG&osdaHF6yu}zC9bA+tj zg1i__`|%YFQMTK-Y9S+~!3_^zQn|rEgKi^d67mCxF@O+(V#ve_$=CRUS=M6_&n+I# z7F#;VA=P~=0#<8U1~5hh#@QEgHi>P*v0i+Zdpo?X#&|wlgb1-rD0o3)@0bEc+kyQF z^Tv$)21SpVQB2*!H-t*esP+*7CQX-B*%m6FfE5WG>W-t$Y zP#5{W91doL4%j$0zgVn3VT9C2=M4LluVjyV(RPIs@UmG40bJ7@o*W~d>xd8Eqsyh` zp~uo)Q8a^0DXBz^qCnun=BnR2t9d||@J_iZd5A*#F)ajqlm-JlaFca-R8gRn2?64p z2?ZmmG8l}0F(ug10Vx`ICrD-i;*3tS9ijklL`iiQ_!rcWz3==TG66&I+At`{3z_?;2kzI0{!s@SmkRct<_LJ5Oc0dG+#g$CAi zcDGio&|-R2ljhPt?ZroLPHs}b0>D@(P&9$D!?TJOi2}<`M4ZL)8W&+{r#%G|S|e|_ z+iiDOKoC6uqosM~iNxFK$ssqCd%I2Wjq$lme4s8KM<7?J7{MU(VoFbg=oz)z(}dNJ8YABMBMTaTP~Fcg=)G0Wo%73)IjTbcH>TZj=o*TpfE~B)cC***X!fp6=hMW3Mg^c2pdDp7@L6Fq}mZy z{E|W&&jLtU++S6qR=~w7^2mzIu&r1ZXwwz$|TH*(O-)2$x& zwlb(>%mn%S00BRn7HtSffMj*tXhE&^zxMdSI;3)F+SwDfUu zo$`9KY(HjqEoJDY3c(F$+MLJLQl#DegE=jw!M(@N*b2?ll!da&Yi(VE_c^#oF``*2=KzuqRN5Ei6AEh;P5 z@PUCBt`3jp@L7w^F`;38>_Q{^#6V72!6XuW$Oc<}CWeDIa)jJV&xFx=07DO0RIU<7 zEIscZ&cC8Kk;`x=fgQsnlj3p+ue5maxC-M;Q4SW5$<4XHN+)9sgeEq5%mq{ENuhj?KdmWXB#Y1%P z+oa^rrFY^q+|2KxgH2;IkJSWx6{g#z9Jf5NR?G!EM_DEuNJ z;iqf(>}i+ZZU5obucydTjB;Hhk!ycogF2r%E;_-&*jBnUpERepUM^v_3^@J$aM{Hx zCV0NIxG0{%*W_u%1GBAoUHxpcxZ3e+oL(JpY4i5`MkiXGt{}TU7rR)B?4V(&n0G?Q z>nN?AGi!UEYJ#Z z_6=airzmi6Fw0hCCh%a`09(Y@6lqVv8IAg<3))m+N{?u>e@?+8FjP9jnly@8;)WW{ z;jWCx692egmf!~HYWm7#UN}LOxF3cY|C0Y>83R*U3og4s$0QjCcW@b?l^3UwpgS@D@M5ZTimHAre1=Q0Fzccgd{gDqA8k zOr2FED8q5%A=K?RRe6yRrS@$+5#1y>LT@uWMh z2%9oy!dgb8KR%{_kt+dsX11XQ+nPUb@X>erf~KF+;G=9W!UuGSX6me>fCu6WaVmGJ rCpy6>o8_N6L=Ih+wh#-yXda)+;W{(#+Keq~hJ_4a0E~h#PyY1()P&|Z literal 0 HcmV?d00001 diff --git a/reference/route/magellan.rte b/reference/route/magellan.rte new file mode 100644 index 000000000..6ded2831b --- /dev/null +++ b/reference/route/magellan.rte @@ -0,0 +1,22 @@ +$PMGNWPL,3042.000,N,09224.000,W,0000000,M,49B,,a*01 +$PMGNWPL,3012.000,N,09218.000,W,0000000,M,49A,,a*08 +$PMGNWPL,2924.000,N,09212.000,W,0000000,M,48B,,a*0D +$PMGNWPL,2900.000,N,09154.000,W,0000000,M,48A,,a*09 +$PMGNWPL,2824.000,N,09124.000,W,0000000,M,47B,,a*05 +$PMGNWPL,2748.000,N,09106.000,W,0000000,M,47A,,a*03 +$PMGNWPL,2636.000,N,09018.000,W,0000000,M,46A,,a*04 +$PMGNWPL,2424.000,N,08824.000,W,0000000,M,43A,,a*06 +$PMGNWPL,2336.000,N,08712.000,W,0000000,M,42A,,a*09 +$PMGNWPL,2300.000,N,08536.000,W,0000000,M,41A,,a*0B +$PMGNWPL,2218.000,N,08424.000,W,0000000,M,40A,,a*00 +$PMGNRTE,6,1,c,1,49B,a,49A,a*01 +$PMGNRTE,6,2,c,1,48B,a,48A,a*02 +$PMGNRTE,6,3,c,1,47B,a,47A,a*03 +$PMGNRTE,6,4,c,1,46A,a,43A,a*02 +$PMGNRTE,6,5,c,1,42A,a,41A,a*05 +$PMGNRTE,6,6,c,1,40A,a,*0D +$PMGNWPL,3016.831,N,09141.153,W,0000000,M,ATLAUN,Launch at Butte LaRose,i*15 +$PMGNWPL,3017.463,N,09137.630,W,0000000,M,ATWRNC,Canal to Warner Lake,k*38 +$PMGNWPL,3018.883,N,09138.767,W,0000000,M,ATWRNR,Warner Lake,a*78 +$PMGNRTE,2,1,c,2,ATLAUN,i,ATWRNC,k*19 +$PMGNRTE,2,2,c,2,ATWRNR,a,*47 diff --git a/reference/route/magexplorist.rte b/reference/route/magexplorist.rte new file mode 100644 index 000000000..0ca044eda --- /dev/null +++ b/reference/route/magexplorist.rte @@ -0,0 +1,6 @@ +$PMGNWPL,3408.881,N,11750.002,W,0000356,M,WPT006,,a*2D +$PMGNWPL,3403.376,N,11742.897,W,0000273,M,WPT007,,a*25 +$PMGNWPL,3401.816,N,11751.349,W,0000226,M,WPT008,,a*2F +$PMGNWPL,3405.686,N,11751.836,W,0000201,M,WPT009,,a*2B +$PMGNRTE,2,1,c,1,Route 1,WPT006,a,WPT007,a*63 +$PMGNRTE,2,2,c,1,Route 1,WPT008,a,WPT009,a*60 diff --git a/reference/route/msroute-sample.axe b/reference/route/msroute-sample.axe new file mode 100644 index 0000000000000000000000000000000000000000..299f8e15ed06ba665470ab4a67e9ba35eaaa7b08 GIT binary patch literal 9216 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 literal 0 HcmV?d00001 diff --git a/reference/route/msroute-sample.gpx b/reference/route/msroute-sample.gpx new file mode 100644 index 000000000..4498c4b28 --- /dev/null +++ b/reference/route/msroute-sample.gpx @@ -0,0 +1,90 @@ + + + + + + + Plauen + + + Treuen + + + Rodewisch + + + Stützengrün + + + Hundshübel + + + Zschorlau + + + Aue + + + Lauter + + + Schwarzenberg + + + Markersbach + + + Schlettau + + + Talstraße, 09456 Annaberg-Buchholz + + + Frohnau + + + Geyer + + + Zwönitz + + + Grünhain + + + Beierfeld + + + S274 + + + Sosa + + + Blauenthal + + + Schönheide + + + Schnarrtanne + + + K7820 + + + Rodewisch + + + Treuen + + + A72, 08233 Treuen + + + diff --git a/reference/route/nmn4-sample-out.rte b/reference/route/nmn4-sample-out.rte new file mode 100644 index 000000000..4f00f9ea1 --- /dev/null +++ b/reference/route/nmn4-sample-out.rte @@ -0,0 +1,10 @@ +-|-|-|-|-|-|-|-|-|-|-|12.10727|50.49425|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.01210|50.37575|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.07199|50.22467|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.67563|49.22528|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.55165|49.12409|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.26244|49.05546|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.22659|49.03302|-|-| +-|-|-|-|-|-|-|-|-|-|-|11.76592|49.04841|-|-| +-|-|-|-|-|-|-|-|-|-|-|11.61610|49.02190|-|-| +-|-|-|-|-|-|-|-|-|-|-|11.58767|49.03485|-|-| diff --git a/reference/route/nmn4-sample.gpx b/reference/route/nmn4-sample.gpx new file mode 100644 index 000000000..c9a826e2c --- /dev/null +++ b/reference/route/nmn4-sample.gpx @@ -0,0 +1,62 @@ + + + + + + + RPT001 + 08523 Plauen, Jahnstrasse 28 + 08523 Plauen, Jahnstrasse 28 + + + RPT002 + 08538 Burgstein, K7855 + 08538 Burgstein, K7855 + + + RPT003 + 95111 Rehau + 95111 Rehau + + + RPT004 + 93413 Cham, Further Strasse + 93413 Cham, Further Strasse + + + RPT005 + 93185 Michelsneukirchen, Hauptstrasse + 93185 Michelsneukirchen, Hauptstrasse + + + RPT006 + 93177 Altenthann + 93177 Altenthann + + + RPT007 + 93093 Donaustauf + 93093 Donaustauf + + + RPT008 + 93155 Hemau, Dietfurter Strasse + 93155 Hemau, Dietfurter Strasse + + + RPT009 + 92345 Mühlbach, Riedenburger Strasse + 92345 Mühlbach, Riedenburger Strasse + + + RPT010 + 92345 Dietfurt An Der Altmühl + 92345 Dietfurt An Der Altmühl + + + diff --git a/reference/route/nmn4-sample.rte b/reference/route/nmn4-sample.rte new file mode 100644 index 000000000..2a27a231d --- /dev/null +++ b/reference/route/nmn4-sample.rte @@ -0,0 +1,10 @@ +-|-|17|-|08523|Plauen|08523|Jahnstrasse|28|-|-|12.10727|50.49425|-|-| +-|-|17|-|08538|Burgstein|08538|K7855|-|-|-|12.01210|50.37575|-|-| +-|-|17|-|95111|Rehau|-|-|-|-|-|12.07199|50.22467|-|-| +-|-|17|-|93413|Cham|93413|Further Strasse|-|-|-|12.67563|49.22528|-|-| +-|-|17|-|93185|Michelsneukirchen|93185|Hauptstrasse|-|-|-|12.55165|49.12409|-|-| +-|-|17|-|93177|Altenthann|-|-|-|-|-|12.26244|49.05546|-|-| +-|-|17|-|93093|Donaustauf|-|-|-|-|-|12.22659|49.03302|-|-| +-|-|17|-|93155|Hemau|93155|Dietfurter Strasse|-|-|-|11.76592|49.04841|-|-| +-|-|17|-|92345|Mühlbach|92345|Riedenburger Strasse|-|-|-|11.61610|49.02190|-|-| +-|-|17|-|92345|Dietfurt An Der Altmühl|-|-|-|-|-|11.58767|49.03485|-|-| diff --git a/reference/route/psitrtes.txt b/reference/route/psitrtes.txt new file mode 100755 index 000000000..96c9fe42d --- /dev/null +++ b/reference/route/psitrtes.txt @@ -0,0 +1,8 @@ +Route: RTE 2 + 57.000000, 5.000000, 100.10, Y1 , wpt_dot + 57.001000, 5.000000, 104.91, Y2 , restrooms + 57.002000, 5.000000, 109.96, Y3 , wpt_dot + 57.003000, 5.001000, 115.00, Y4 , wpt_dot +Route: X1 + 57.000000, 5.000000, 7.10, X11 , wpt_dot + 57.001000, 5.000000, -0.11, X12 , wpt_dot diff --git a/reference/route/route.gpx b/reference/route/route.gpx new file mode 100644 index 000000000..8030ff529 --- /dev/null +++ b/reference/route/route.gpx @@ -0,0 +1,77 @@ + + + + +LILI PATH +Hurricane LILI + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + +0.000000 + + + + +ATCHAFALAYA +ROUTE1 +2 + +0.000000 + + + + +0.000000 + + + + +0.000000 + + + + + diff --git a/reference/route/route.mapsend b/reference/route/route.mapsend new file mode 100644 index 0000000000000000000000000000000000000000..bd65116929f26f0189e10880e9151875e3edb1b5 GIT binary patch literal 922 zcmZ9L%TB^T6o!xD1yI6SXyV;u<7n1Sd<-=V@yA|Pdt#xd6m!bBs_ zVO(Vm2-Adt==%4e(hYm7f|Qsh4MZ>ZI#jw^cSR7FDQO_lrvDmM1X*NC8A#M1h^v$Z zDKMoCB-(7CaFYm#!!(7txuaYVE!Qup32yov9MH5t$pLkG((k;yhwACe|Lkv9LA4qO zHOdH;9#HMeY-iy$RK@eVjf>qss-eXWJATZ~|Fqvi^>8-3cXe1*P?_>~{GI$EH|uht zSBMV*g`*cSv`^5FM{MU3R6IDhO(S5K)}{XWm7wgwuMYlMMZmCXyOf~BaA_Nqz-1V; zy-Bdh@MhbRpun(YJCeX*IEqRQ&CnD#YjxgYpWBRAgU!aeV9R!tj3vR5Z6+OM4g7Mp G5Bdd#XZxH0 literal 0 HcmV?d00001 diff --git a/reference/route/route.mps b/reference/route/route.mps new file mode 100755 index 0000000000000000000000000000000000000000..e3e78ba88f9412943cb14b13f7d1ac55d1c94dbc GIT binary patch literal 3182 zcma)-KWGzi6vy91Iyv-@ITVTz=;W4M5^IZ4epf9Gp3$bMp@6Q5!{?a92^|# zsFSm}h)Y%KPzSe)h`0!fC~j_2>+flQ-g|lQ@@~o9_kQ2s=iVjxeotO)b(f(40LNBf z)PK0OXnxMYsqVE>l9ZBixdN5?WUW3~twPt|@3?m67MlKS_t+r^0A4Izyd57p@Mb*< zOL{H;Z-fOspSzq+t2v$DA()+ioT<4x@vY5wl*287Go0_j&T>vG*CnU^@NT@ku+_sM zmcSXwcVTBs{;HGK$}U$WW&Zw$!S7doZG_E$8-m=2QBfI>2hI+C{9U39YA`YqmGN|H zbLjfB?U!LQKL<4gxz8L`m9hG1arn~lG0LC@Bjd2jcz^!e$o7TT&% + + + + + + NARVA + NARVA + NARVA + + + + Liebknechtstras + Liebknechtstras + Liebknechtstras + + + + Jahnstrasse11 + Jahnstrasse11 + Jahnstrasse11 + + + + Elsterberg + Elsterberg + Elsterberg + + + + Greiz + Greiz + Greiz + + + + Gosel + Gosel + Gosel + + + + 3 + 3 + 3 + + + + Altenburg-Umgehung + Altenburg-Umgehung + Altenburg-Umgehung + + + + Völkerschlachtdenkmal + Völkerschlachtdenkmal + Völkerschlachtdenkmal + + diff --git a/reference/route/stmwpp-route.txt b/reference/route/stmwpp-route.txt new file mode 100644 index 000000000..caea873f8 --- /dev/null +++ b/reference/route/stmwpp-route.txt @@ -0,0 +1,10 @@ +Datum,WGS 84,WGS 84,0,0,0,0,0 +WP,D,NARVA,50.4926189,12.1054487,09/03/2005,00:00:00.00, +WP,D,Liebknechtstras,50.4938369,12.106101,09/03/2005,00:00:00.00, +WP,D,Jahnstrasse11,50.4936628,12.1071524,09/03/2005,00:00:00.00, +WP,D,Elsterberg,50.6107952,12.1738022,09/03/2005,00:00:00.00, +WP,D,Greiz,50.654763,12.2049567,09/03/2005,00:00:00.00, +WP,D,Gosel,50.8441256,12.4087572,09/03/2005,00:00:00.00, +WP,D,3,50.8773405,12.4338887,09/03/2005,00:00:00.00, +WP,D,Altenburg-Umgehung,50.9649551,12.4359193,09/03/2005,00:00:00.00, +WP,D,Völkerschlachtdenkmal,51.3145207,12.4091433,09/03/2005,00:00:00.00, diff --git a/reference/route/tef_xml.sample.gpx b/reference/route/tef_xml.sample.gpx new file mode 100644 index 000000000..e34365079 --- /dev/null +++ b/reference/route/tef_xml.sample.gpx @@ -0,0 +1,1344 @@ + + + + + + B2 Schleizer Strasse + bei D 95030 Hof/Innenstadt + bei D 95030 Hof/Innenstadt + + + B2\Hofer Strasse + bei D 95183 Töpen + bei D 95183 Töpen + + + L1095\Strasse der Jugend + bei D 07356 Lobenstein + bei D 07356 Lobenstein + + + L1095 + bei D 07929 Saalburg-Ebersdorf/Saalburg + bei D 07929 Saalburg-Ebersdorf/Saalburg + + + K550 + bei D07907 Burgk/Burgkhammer + bei D07907 Burgk/Burgkhammer + + + Burgkhammer + bei D 07907 Burgk/Burgkhammer + bei D 07907 Burgk/Burgkhammer + + + L2357 + bei D 07907 Burgk + bei D 07907 Burgk + + + L2357 + bei D 07907 Schleiz/Möschlitz + bei D 07907 Schleiz/Möschlitz + + + L2350\Plothental + bei D 07924 Ziegenrück + bei D 07924 Ziegenrück + + + L2349\Hauptstrasse + bei D 07389 Knau + bei D 07389 Knau + + + L2349\Ortsstrasse + bei D 07907 Plothen + bei D 07907 Plothen + + + K304\Lössauer Strasse + bei D 07907 Schleiz/Langenbuch + bei D 07907 Schleiz/Langenbuch + + + S316\Am Mühlgraben + bei D 07952 Pausa/Oberreichenau + bei D 07952 Pausa/Oberreichenau + + + B282/E49\Hauptstrasse + bei D 08548 Syrau + bei D 08548 Syrau + + + Martin-Luther-Strasse + bei D 08525 Plauen/Preißelpöhl + bei D 08525 Plauen/Preißelpöhl + + + B173\Hauptstrasse + bei D 08541 Neuensalz + bei D 08541 Neuensalz + + + K7880\Helmsgrün-Dorfstrasse + bei D 08543 Pöhl/Helmsgrün + bei D 08543 Pöhl/Helmsgrün + + + K7811\Herlasgrün-Dorfstrasse + bei D 08543 Herlasgrün + bei D 08543 Herlasgrün + + + S296\Netzschkauer Strasse + bei D 07985 Elsterberg/Reuth + bei D 07985 Elsterberg/Reuth + + + S296\Elsterberger Strasse + bei D 08491 Netzschkau + bei D 08491 Netzschkau + + + B173\Netzschkauer Strasse + bei D 08499 Mylau/Obermylau + bei D 08499 Mylau/Obermylau + + + B173\Robert-Georgi-Weg + bei D 08499 Mylau/Obermylau + bei D 08499 Mylau/Obermylau + + + B173\Friedensstrasse + bei D 08468 Reichenbach + bei D 08468 Reichenbach + + + B173 + bei D 08496 Neumark/Unterneumark + bei D 08496 Neumark/Unterneumark + + + K9351\Zwickauer Strasse + D 08115 Schönfels + D 08115 Schönfels + + + B173\Reichenbacher Strasse + bei D 08056 Zwickau/Bahnhofsvorstadt + bei D 08056 Zwickau/Bahnhofsvorstadt + + + S255\Innere Zwickauer Strasse + bei D 09350 Lichtenstein + bei D 09350 Lichtenstein + + + S284\Bahnhofstrasse + bei D 08118 Hartenstein + bei D 08118 Hartenstein + + + B169\Lindenstrasse + bei D 08228 Rodewisch + bei D 08228 Rodewisch + + + B169\Göltzschtalstrasse + bei D 08209 Auerbach + bei D 08209 Auerbach + + + K7833\Rempesgrüner Strasse + bei D 08209 Auerbach/Beerheide + bei D 08209 Auerbach/Beerheide + + + S278\Hauptstrasse + D 08304 Schönheide + D 08304 Schönheide + + + B283\Schönheider Strasse + bei D 08262 Tannenbergsthal/Jägersgrün + bei D 08262 Tannenbergsthal/Jägersgrün + + + B283\Klingenthaler Strasse + bei D 08262 Tannenbergsthal + bei D 08262 Tannenbergsthal + + + S304\Falkensteiner Strasse + bei D 08248 Klingenthal/Brunndöbra + bei D 08248 Klingenthal/Brunndöbra + + + S302/S304 + bei D 08223 Grünbach-Muldenberg + bei D 08223 Grünbach-Muldenberg + + + S304\Bahnhofstrasse + bei D 08223 Grünbach + bei D 08223 Grünbach + + + S301 + bei D 08261 Schöneck + bei D 08261 Schöneck + + + B283 + bei D 08258 Markneukirchen/Friebus + bei D 08258 Markneukirchen/Friebus + + + K7844\Rauner Strasse + bei D 08258 Landwüst + bei D 08258 Landwüst + + + B92/E49 + bei D 08626 Adorf/Jugelsburg + bei D 08626 Adorf/Jugelsburg + + + B92/E49\Oelsnitzer Strasse + bei D 08626 Adorf + bei D 08626 Adorf + + + K7854\Oelsnitzer Strasse + bei D 08606 Planschwitz + bei D 08606 Planschwitz + + + S310\Bobenneukirchener Strasse + bei D 08538 Burgstein/Dröda + bei D 08538 Burgstein/Dröda + + + K7859 + bei D 08538 Burgstein/Pirk + bei D 08538 Burgstein/Pirk + + + K7859 + bei D 08538 Burgstein/Kemnitz + bei D 08538 Burgstein/Kemnitz + + + bei D95032 Hof + bei D95032 Hof + bei D95032 Hof + + + von bei D 95030 Hof/Innenstadt nach bei D95032 Hof + MOTORRAD Tourenplaner 2005/2006 9.50 + + B2 Schleizer Strasse + bei D 95030 Hof/Innenstadt + bei D 95030 Hof/Innenstadt + + + B2 Hofer Strasse + in Zedtwitz halb rechts halten auf B2 Hofer Strasse + + + B2 + rechts abbiegen auf B2 + + + B2\Hofer Strasse + bei D 95183 Töpen + bei D 95183 Töpen + + + B90 Friedensstrasse + in Gefell links abbiegen auf B90 Friedensstrasse + + + B90 Hirschberger Strasse + in Lobenstein halb rechts halten auf B90 Hirschberger Strasse + + + Strasse der Jugend (L1095) + geradeaus weiter auf Strasse der Jugend (L1095) + + + L1095\Strasse der Jugend + bei D 07356 Lobenstein + bei D 07356 Lobenstein + + + L1099 + links abbiegen auf L1099 + + + RPT010 + rechts abbiegen + + + Schönbrunn + in Schönbrunn links abbiegen auf Schönbrunn + + + Schönbrunn + links abbiegen auf Schönbrunn + + + Schönbrunn + halb rechts halten auf Schönbrunn + + + L1095 + geradeaus weiter auf L1095 + + + L1095 + halb links halten auf L1095 + + + L1095 + in Bellevue links abbiegen auf L1095 + + + L1095 + in Saalburg geradeaus weiter auf L1095 + + + L1095 + geradeaus weiter auf L1095 + + + L1095 + links abbiegen auf L1095 + + + Schleizer Strasse (L1095) + rechts abbiegen auf Schleizer Strasse (L1095) + + + L1095 + bei D 07929 Saalburg-Ebersdorf/Saalburg + bei D 07929 Saalburg-Ebersdorf/Saalburg + + + L1095 + geradeaus weiter auf L1095 + + + RPT023 + links abbiegen + + + K550 + bei D07907 Burgk/Burgkhammer + bei D07907 Burgk/Burgkhammer + + + L1101 + rechts abbiegen auf L1101 + + + Burgkhammer + geradeaus weiter auf Burgkhammer + + + Burgkhammer + bei D 07907 Burgk/Burgkhammer + bei D 07907 Burgk/Burgkhammer + + + L1101 + in Burgkhammer links abbiegen auf L1101 + + + RPT029 + links abbiegen + + + L1095 + links abbiegen auf L1095 + + + Burgker Chaussee (L1101) + links abbiegen auf Burgker Chaussee (L1101) + + + Burgker Strasse (L1101) + links abbiegen auf Burgker Strasse (L1101) + + + L2357 + halb rechts halten auf L2357 + + + L2357 + bei D 07907 Burgk + bei D 07907 Burgk + + + Burgker Strasse (L1101) + geradeaus weiter auf Burgker Strasse (L1101) + + + L2357 + geradeaus weiter auf L2357 + + + L2357 + bei D 07907 Schleiz/Möschlitz + bei D 07907 Schleiz/Möschlitz + + + RPT038 + links abbiegen + + + Mühlenstrasse + in Grochwitz halb rechts halten auf Mühlenstrasse + + + Sackgasse + geradeaus weiter auf Sackgasse + + + RPT041 + geradeaus weiter + + + L1103 + links abbiegen auf L1103 + + + L1103 + links abbiegen auf L1103 + + + Ortsstrasse (L1103) + in Crispendorf halb rechts halten auf Ortsstrasse (L1103) + + + Ortsstrasse (L1103) + halb rechts halten auf Ortsstrasse (L1103) + + + L1103 + halb rechts halten auf L1103 + + + Schleizer Strasse (L1103) + in Ziegenrück halb links halten auf Schleizer Strasse (L1103) + + + Plothental (L2350) + rechts abbiegen auf Plothental (L2350) + + + L2350\Plothental + bei D 07924 Ziegenrück + bei D 07924 Ziegenrück + + + Tausa (L2350) + in Tausa halb links halten auf Tausa (L2350) + + + Ortsstrasse (L2350) + in Bucha links abbiegen auf Ortsstrasse (L2350) + + + L2350 + rechts abbiegen auf L2350 + + + Hauptstrasse (L2349) + in Knau halb links halten auf Hauptstrasse (L2349) + + + L2349\Hauptstrasse + bei D 07389 Knau + bei D 07389 Knau + + + Hauptstrasse (L2349) + links abbiegen auf Hauptstrasse (L2349) + + + L2349\Ortsstrasse + bei D 07907 Plothen + bei D 07907 Plothen + + + L1077 + in Dittersdorf rechts abbiegen auf L1077 + + + Ziegelei + rechts abbiegen auf Ziegelei + + + B2 + halb rechts halten auf B2 + + + Löhmaer Weg (K301) + in Oettersdorf links abbiegen auf Löhmaer Weg (K301) + + + Löhmaer Weg (K301) + rechts abbiegen auf Löhmaer Weg (K301) + + + Löhmaer Weg (K301) + links abbiegen auf Löhmaer Weg (K301) + + + RPT063 + rechts abbiegen + + + Ortsstrasse + in Löhma links abbiegen auf Ortsstrasse + + + RPT065 + geradeaus weiter + + + Ortsstrasse + in Kirschkau geradeaus weiter auf Ortsstrasse + + + Ortsstrasse + rechts abbiegen auf Ortsstrasse + + + Ortsstrasse + rechts abbiegen auf Ortsstrasse + + + Ortsstrasse + links abbiegen auf Ortsstrasse + + + Ortsstrasse + rechts abbiegen auf Ortsstrasse + + + B94 + geradeaus weiter auf B94 + + + B94 + rechts abbiegen auf B94 + + + Dorfstrasse + links abbiegen auf Dorfstrasse + + + RPT074 + in Lössau links abbiegen + + + K304\Lössauer Strasse + bei D 07907 Schleiz/Langenbuch + bei D 07907 Schleiz/Langenbuch + + + Thierbacher Strasse (L2348) + in Langenbuch links abbiegen auf Thierbacher Strasse (L2348) + + + RPT077 + geradeaus weiter + + + RPT078 + in Pausa/Vogtl. rechts abbiegen + + + Plauensche Strasse (S316) + rechts abbiegen auf Plauensche Strasse (S316) + + + Am Mühlgraben (S316) + in Oberreichenau halb links halten auf Am Mühlgraben (S316) + + + S316\Am Mühlgraben + bei D 07952 Pausa/Oberreichenau + bei D 07952 Pausa/Oberreichenau + + + B282/E49 Hauptstrasse + in Syrau halb rechts halten auf B282/E49 Hauptstrasse + + + B282/E49\Hauptstrasse + bei D 08548 Syrau + bei D 08548 Syrau + + + Pausaer Strasse + rechts abbiegen auf Pausaer Strasse + + + B92/E49 Pausaer Strasse + rechts abbiegen auf B92/E49 Pausaer Strasse + + + Martin-Luther-Strasse + in Plauen links abbiegen auf Martin-Luther-Strasse + + + Martin-Luther-Strasse + bei D 08525 Plauen/Preißelpöhl + bei D 08525 Plauen/Preißelpöhl + + + Lessingstrasse + links abbiegen auf Lessingstrasse + + + B173 Hammerstrasse + links abbiegen auf B173 Hammerstrasse + + + Voigtsgrüner Weg (K6605) + links abbiegen auf Voigtsgrüner Weg (K6605) + + + Zum Plom + rechts abbiegen auf Zum Plom + + + RPT092 + rechts abbiegen + + + B169 + in Neuensalz links abbiegen auf B169 + + + B169 Alte Plauener Strasse + links abbiegen auf B169 Alte Plauener Strasse + + + B173 Hauptstrasse + geradeaus weiter auf B173 Hauptstrasse + + + B173\Hauptstrasse + bei D 08541 Neuensalz + bei D 08541 Neuensalz + + + B173 Hauptstrasse + in Thossfell geradeaus weiter auf B173 Hauptstrasse + + + B173 Hauptstrasse + geradeaus weiter auf B173 Hauptstrasse + + + Gansgrüner Strasse (K7880) + links abbiegen auf Gansgrüner Strasse (K7880) + + + Gansgrüner Strasse (K7880) + links abbiegen auf Gansgrüner Strasse (K7880) + + + Dorfstrasse + in Gansgrün links abbiegen auf Dorfstrasse + + + Dorfstrasse (K7880) + rechts abbiegen auf Dorfstrasse (K7880) + + + Dorfstrasse (K7880) + halb rechts halten auf Dorfstrasse (K7880) + + + RPT104 + halb links halten + + + K7880\Helmsgrün-Dorfstrasse + bei D 08543 Pöhl/Helmsgrün + bei D 08543 Pöhl/Helmsgrün + + + RPT106 + in Helmsgrün halb rechts halten + + + Herlasgrün-Dorfstrasse (K7811) + in Herlasgrün rechts abbiegen auf Herlasgrün-Dorfstrasse (K7811) + + + K7811\Herlasgrün-Dorfstrasse + bei D 08543 Herlasgrün + bei D 08543 Herlasgrün + + + Herlasgrün-Christgrüner Strasse + links abbiegen auf Herlasgrün-Christgrüner Strasse + + + Christgrüner Strasse + geradeaus weiter auf Christgrüner Strasse + + + Dreckschänke (S297) + rechts abbiegen auf Dreckschänke (S297) + + + S298 + links abbiegen auf S298 + + + RPT113 + in Reimersgrün links abbiegen + + + RPT114 + halb rechts halten + + + Friedensstrasse (K7887) + in Coschütz rechts abbiegen auf Friedensstrasse (K7887) + + + S298 + links abbiegen auf S298 + + + Netzschkauer Strasse (S296) + rechts abbiegen auf Netzschkauer Strasse (S296) + + + S296\Netzschkauer Strasse + bei D 07985 Elsterberg/Reuth + bei D 07985 Elsterberg/Reuth + + + S296\Elsterberger Strasse + bei D 08491 Netzschkau + bei D 08491 Netzschkau + + + Elsterberger Strasse (S296) + in Netzschkau links abbiegen auf Elsterberger Strasse (S296) + + + Strasse der Einheit (S296) + rechts abbiegen auf Strasse der Einheit (S296) + + + Strasse der Einheit (S296) + halb rechts halten auf Strasse der Einheit (S296) + + + B173 Plauener Strasse + links abbiegen auf B173 Plauener Strasse + + + B173\Netzschkauer Strasse + bei D 08499 Mylau/Obermylau + bei D 08499 Mylau/Obermylau + + + B173\Robert-Georgi-Weg + bei D 08499 Mylau/Obermylau + bei D 08499 Mylau/Obermylau + + + B173/B94 Klinkhardtstrasse + in Reichenbach im Vogtland links abbiegen auf B173/B94 Klinkhardtstrasse + + + B173/B94 Dr.-Külz-Strasse + links abbiegen auf B173/B94 Dr.-Külz-Strasse + + + B173 Friedensstrasse + rechts abbiegen auf B173 Friedensstrasse + + + B173\Friedensstrasse + bei D 08468 Reichenbach + bei D 08468 Reichenbach + + + B173 + in Neumark geradeaus weiter auf B173 + + + B173 + geradeaus weiter auf B173 + + + B173 + bei D 08496 Neumark/Unterneumark + bei D 08496 Neumark/Unterneumark + + + Stenner Strasse + in Schönfels links abbiegen auf Stenner Strasse + + + Zwickauer Strasse (K9351) + geradeaus weiter auf Zwickauer Strasse (K9351) + + + K9351\Zwickauer Strasse + D 08115 Schönfels + D 08115 Schönfels + + + Stenner Strasse + halb rechts halten auf Stenner Strasse + + + B173 Neumarker Strasse + links abbiegen auf B173 Neumarker Strasse + + + B173\Reichenbacher Strasse + bei D 08056 Zwickau/Bahnhofsvorstadt + bei D 08056 Zwickau/Bahnhofsvorstadt + + + B173 Humboldtstrasse + in Zwickau rechts abbiegen auf B173 Humboldtstrasse + + + B173 Am Schwanenteich + links abbiegen auf B173 Am Schwanenteich + + + B173 Dr.-Friedrichs-Ring + rechts halten auf B173 Dr.-Friedrichs-Ring + + + B173 Glück-Auf-Brücke/Äussere Dresdner Strasse + geradeaus weiter auf B173 Glück-Auf-Brücke/Äussere Dresdner Strasse + + + Dresdner Strasse + rechts abbiegen auf Dresdner Strasse + + + Äussere Zwickauer Strasse + geradeaus weiter auf Äussere Zwickauer Strasse + + + Innere Zwickauer Strasse + in Lichtenstein/Sa. geradeaus weiter auf Innere Zwickauer Strasse + + + S255\Innere Zwickauer Strasse + bei D 09350 Lichtenstein + bei D 09350 Lichtenstein + + + Hartensteiner Strasse (S255) + rechts abbiegen auf Hartensteiner Strasse (S255) + + + Hartensteiner Strasse (S255) + rechts abbiegen auf Hartensteiner Strasse (S255) + + + Hartensteiner Strasse (S255) + rechts abbiegen auf Hartensteiner Strasse (S255) + + + Hartensteiner Strasse (S255) + halb links halten auf Hartensteiner Strasse (S255) + + + S283 + geradeaus weiter auf S283 + + + S283 + rechts abbiegen auf S283 + + + August-Bebel-Strasse (S283) + in Hartenstein links abbiegen auf August-Bebel-Strasse (S283) + + + Bahnhofstrasse (S284) + geradeaus weiter auf Bahnhofstrasse (S284) + + + S284\Bahnhofstrasse + bei D 08118 Hartenstein + bei D 08118 Hartenstein + + + RPT156 + rechts abbiegen + + + RPT157 + links abbiegen + + + Langenbacher Strasse (K9309) + in Stein rechts abbiegen auf Langenbacher Strasse (K9309) + + + Wildbacher Strasse (K9309) + halb links halten auf Wildbacher Strasse (K9309) + + + RPT160 + geradeaus weiter + + + Hartensteiner Strasse (K9109) + halb rechts halten auf Hartensteiner Strasse (K9109) + + + Hartensteiner Strasse (K9109) + in Wildbach rechts abbiegen auf Hartensteiner Strasse (K9109) + + + Silberbachstrasse + links abbiegen auf Silberbachstrasse + + + Zechenplatz + geradeaus weiter auf Zechenplatz + + + Schneeberger Weg + in Schlema geradeaus weiter auf Schneeberger Weg + + + Zechenplatz + links abbiegen auf Zechenplatz + + + Friedensstrasse + rechts abbiegen auf Friedensstrasse + + + B169 Kobaltstrasse/Auer Strasse + rechts abbiegen auf B169 Kobaltstrasse/Auer Strasse + + + B169 Kobaltstrasse + in Schneeberg rechts abbiegen auf B169 Kobaltstrasse + + + B169 Hauptstrasse + in Hundshübel halb rechts halten auf B169 Hauptstrasse + + + B169 Auerbacher Strasse + in Stützengrün rechts abbiegen auf B169 Auerbacher Strasse + + + B169 Postplatz + in Rodewisch rechts abbiegen auf B169 Postplatz + + + B169 Postplatz + links abbiegen auf B169 Postplatz + + + B169\Lindenstrasse + bei D 08228 Rodewisch + bei D 08228 Rodewisch + + + B169\Göltzschtalstrasse + bei D 08209 Auerbach + bei D 08209 Auerbach + + + B169 Göltzschtalstrasse + in Auerbach/Vogtl. links abbiegen auf B169 Göltzschtalstrasse + + + Neuberg + in Ellefeld links abbiegen auf Neuberg + + + Neuberg + rechts abbiegen auf Neuberg + + + Beerheider Strasse (K7833) + rechts abbiegen auf Beerheider Strasse (K7833) + + + Beerheider Strasse (K7833) + rechts abbiegen auf Beerheider Strasse (K7833) + + + K7833\Rempesgrüner Strasse + bei D 08209 Auerbach/Beerheide + bei D 08209 Auerbach/Beerheide + + + Strasse des Friedens (K7826) + in Beerheide links abbiegen auf Strasse des Friedens (K7826) + + + Klingenthaler Strasse (S300) + in Hohengrün rechts abbiegen auf Klingenthaler Strasse (S300) + + + RPT184 + links abbiegen + + + Schallerbachstrasse (K7822) + links abbiegen auf Schallerbachstrasse (K7822) + + + Schönheider Strasse (S278) + in Brunn rechts abbiegen auf Schönheider Strasse (S278) + + + Hauptstrasse (S278) + in Schönheide halb rechts halten auf Hauptstrasse (S278) + + + S278\Hauptstrasse + D 08304 Schönheide + D 08304 Schönheide + + + Hauptstrasse (S278) + halb links halten auf Hauptstrasse (S278) + + + Eibenstocker Strasse (S277) + geradeaus weiter auf Eibenstocker Strasse (S277) + + + B283 Muldenstrasse + rechts abbiegen auf B283 Muldenstrasse + + + Am Filz + halb rechts halten auf Am Filz + + + B283 Schönheider Strasse + geradeaus weiter auf B283 Schönheider Strasse + + + B283\Schönheider Strasse + bei D 08262 Tannenbergsthal/Jägersgrün + bei D 08262 Tannenbergsthal/Jägersgrün + + + B283\Klingenthaler Strasse + bei D 08262 Tannenbergsthal + bei D 08262 Tannenbergsthal + + + B283 Auerbacher Strasse + in Klingenthal/Sa. links abbiegen auf B283 Auerbacher Strasse + + + Mittelbergstrasse + rechts abbiegen auf Mittelbergstrasse + + + Falkensteiner Strasse (S304) + rechts abbiegen auf Falkensteiner Strasse (S304) + + + S304\Falkensteiner Strasse + bei D 08248 Klingenthal/Brunndöbra + bei D 08248 Klingenthal/Brunndöbra + + + S302/S304 + bei D 08223 Grünbach-Muldenberg + bei D 08223 Grünbach-Muldenberg + + + S304 + halb links halten auf S304 + + + S304\Bahnhofstrasse + bei D 08223 Grünbach + bei D 08223 Grünbach + + + Neustädter Strasse (K7835) + in Grünbach links abbiegen auf Neustädter Strasse (K7835) + + + Siehdichfürer Strasse (K7835) + links abbiegen auf Siehdichfürer Strasse (K7835) + + + Schönecker Strasse (S301) + in Neudorf links abbiegen auf Schönecker Strasse (S301) + + + Schönecker Strasse (S301) + links abbiegen auf Schönecker Strasse (S301) + + + S301 + bei D 08261 Schöneck + bei D 08261 Schöneck + + + Falkensteiner Strasse (S301/S302) + in Schöneck/Vogtl. rechts abbiegen auf Falkensteiner Strasse (S301/S302) + + + Albertplatz/Falkensteiner Strasse (S301/S302) + links abbiegen auf Albertplatz/Falkensteiner Strasse (S301/S302) + + + Klingenthaler Strasse (S301) + rechts abbiegen auf Klingenthaler Strasse (S301) + + + RPT211 + einfahren in Kreisverkehr + + + Kärnerstrasse (S305) + 2. Möglichkeit aus Kreisverkehr ausfahren auf Kärnerstrasse (S305) + + + B283 + rechts abbiegen auf B283 + + + B283 + bei D 08258 Markneukirchen/Friebus + bei D 08258 Markneukirchen/Friebus + + + B283 + rechts abbiegen auf B283 + + + Am Bahnhof + in Siebenbrunn geradeaus weiter auf Am Bahnhof + + + Strässler Berg + links abbiegen auf Strässler Berg + + + Siebenbrunner Strasse + geradeaus weiter auf Siebenbrunner Strasse + + + Böhmische Strasse (K7846) + in Strässel links abbiegen auf Böhmische Strasse (K7846) + + + Markneukirchner Strasse (K7843) + in Schönlind rechts abbiegen auf Markneukirchner Strasse (K7843) + + + Landwüster Strasse (K7846) + links abbiegen auf Landwüster Strasse (K7846) + + + Schönlinder Strasse (K7844) + in Landwüst halb rechts halten auf Schönlinder Strasse (K7844) + + + Rauner Strasse (K7844) + rechts abbiegen auf Rauner Strasse (K7844) + + + K7844\Rauner Strasse + bei D 08258 Landwüst + bei D 08258 Landwüst + + + B92/E49 + geradeaus weiter auf B92/E49 + + + B92/E49 + bei D 08626 Adorf/Jugelsburg + bei D 08626 Adorf/Jugelsburg + + + B92/E49\Oelsnitzer Strasse + bei D 08626 Adorf + bei D 08626 Adorf + + + RPT228 + halb links halten + + + B92/E49 Adorfer Strasse + geradeaus weiter auf B92/E49 Adorfer Strasse + + + RPT230 + halb links halten + + + RPT231 + rechts abbiegen + + + B92/E49 Adorfer Strasse + links abbiegen auf B92/E49 Adorfer Strasse + + + Rosa-Luxemburg-Strasse (S311) + in Oelsnitz links abbiegen auf Rosa-Luxemburg-Strasse (S311) + + + Grabenstrasse (S311) + links abbiegen auf Grabenstrasse (S311) + + + Kirchplatz (S311) + links abbiegen auf Kirchplatz (S311) + + + Heppeplatz (S311) + rechts abbiegen auf Heppeplatz (S311) + + + Bahnhofstrasse (S307) + links abbiegen auf Bahnhofstrasse (S307) + + + Talsperrenstrasse (S310) + rechts abbiegen auf Talsperrenstrasse (S310) + + + Talsperrenstrasse (K7854) + rechts abbiegen auf Talsperrenstrasse (K7854) + + + K7854\Oelsnitzer Strasse + bei D 08606 Planschwitz + bei D 08606 Planschwitz + + + Talsperrenstrasse (K7854) + in Planschwitz links abbiegen auf Talsperrenstrasse (K7854) + + + RPT242 + links abbiegen + + + S310 + in Bösenbrunn rechts abbiegen auf S310 + + + S310 + links abbiegen auf S310 + + + Hauptstrasse/Bobenneukirchener Strasse (S310) + in Dröda rechts abbiegen auf Hauptstrasse/Bobenneukirchener Strasse (S310) + + + Bobenneukirchener Strasse (S310) + halb rechts halten auf Bobenneukirchener Strasse (S310) + + + S310\Bobenneukirchener Strasse + bei D 08538 Burgstein/Dröda + bei D 08538 Burgstein/Dröda + + + B173 Hofer Strasse + in Pirk rechts abbiegen auf B173 Hofer Strasse + + + Zur Pirkmühle (K7859) + links abbiegen auf Zur Pirkmühle (K7859) + + + K7859 + bei D 08538 Burgstein/Pirk + bei D 08538 Burgstein/Pirk + + + Winkel (K7859) + in Geilsdorf links abbiegen auf Winkel (K7859) + + + Weischlitzer Strasse (K7859) + in Schwand links abbiegen auf Weischlitzer Strasse (K7859) + + + Weischlitzer Strasse (K7859) + halb rechts halten auf Weischlitzer Strasse (K7859) + + + K7859 + bei D 08538 Burgstein/Kemnitz + bei D 08538 Burgstein/Kemnitz + + + Kemnitzer Strasse + links abbiegen auf Kemnitzer Strasse + + + Burgsteinstrasse (K7860) + in Krebes rechts abbiegen auf Burgsteinstrasse (K7860) + + + RPT257 + geradeaus weiter + + + RPT258 + links abbiegen + + + An der Kapelle (K7855) + in Heinersgrün halb links halten auf An der Kapelle (K7855) + + + RPT260 + rechts abbiegen + + + B173 + geradeaus weiter auf B173 + + + bei D95032 Hof + bei D95032 Hof + bei D95032 Hof + + + diff --git a/reference/route/tef_xml.sample.xml b/reference/route/tef_xml.sample.xml new file mode 100644 index 000000000..ddb466e4a --- /dev/null +++ b/reference/route/tef_xml.sample.xml @@ -0,0 +1,2 @@ + +
    diff --git a/reference/route/tomtom_itn.itn b/reference/route/tomtom_itn.itn new file mode 100644 index 000000000..86f254427 --- /dev/null +++ b/reference/route/tomtom_itn.itn @@ -0,0 +1,46 @@ +4243095|-7110763|BELLEVUE|0 +4243124|-7110924|GATE6|0 +4243498|-7110994|PANTHRCAVE|0 +4243676|-7111322|6014MEADOW|0 +4243902|-7111446|6006|0 +4243859|-7111480|6006BLUE|0 +4243892|-7111615|5096|0 +4243888|-7111928|5066|0 +4243923|-7111969|5067|0 +4243999|-7112092|5058ROAD|0 +4244173|-7112168|5150TANK|0 +4244390|-7112204|5142|0 +4244536|-7112284|5144SUMMIT|0 +4244730|-7112145|5156|0 +4244976|-7112232|5148NANEPA|0 +4245144|-7112175|5258|0 +4245326|-7112121|5252PURPLE|0 +4245625|-7111936|527631|0 +4245659|-7111968|527614|0 +4245739|-7111984|5267OBSTAC|0 +4245815|-7111914|5278|0 +4245938|-7111769|5289|0 +4246418|-7111983|5374FIRE|0 +4246565|-7111940|5376|0 +4246591|-7111933|5376STREAM|0 +4246711|-7111357|6328|0 +4246646|-7111007|635722|0 +4246656|-7110941|635783|0 +4246350|-7110712|6373|0 +4246569|-7110736|BEAR HILL|0 +4245999|-7110617|6289|0 +4245762|-7110512|6297|0 +4245384|-7110521|6283|0 +4245143|-7110541|6280|0 +4244845|-7110616|6177|0 +4244780|-7110662|6176|0 +4244477|-7110888|6153|0 +4244359|-7110630|6171|0 +4244298|-7111144|6131|0 +4244220|-7111098|6130|0 +4244175|-7111322|6029|0 +4243902|-7111446|6006|0 +4243676|-7111322|6014MEADOW|0 +4243498|-7110994|PANTHRCAVE|0 +4243124|-7110924|GATE6|0 +4243095|-7110763|BELLEVUE|0 diff --git a/reference/route/vieac.README b/reference/route/vieac.README new file mode 100644 index 000000000..b726df14b --- /dev/null +++ b/reference/route/vieac.README @@ -0,0 +1,14 @@ +From P.Roosen. + +'d like to contribute a small route definition file in Magellan format +as reference, with some mean properties. :-) + +1. Routes contain double entries: each route's last point is also the +starting point of the next route (to prevent active route lines from +being intermittent in the traffic situation). + +2. Route points contain different symbols (to give a hint to the status +of a given route point during in-traffic operation: decision point, +orientation help point, chaotic point, ...). + + diff --git a/reference/route/vieac.rte b/reference/route/vieac.rte new file mode 100644 index 000000000..5c3b20301 --- /dev/null +++ b/reference/route/vieac.rte @@ -0,0 +1,173 @@ +$PMGNWPL,5115.112,N,00623.005,E,0000,M,AU-aa,,t,*64 +$PMGNWPL,5114.982,N,00622.972,E,0000,M,WE-ab,,ai,*15 +$PMGNWPL,5114.818,N,00623.028,E,0000,M,RE-ac,,t,*68 +$PMGNWPL,5114.608,N,00622.947,E,0000,M,X-ad,,ag,*5C +$PMGNWPL,5114.522,N,00622.925,E,0000,M,WE-ae,,ai,*16 +$PMGNWPL,5114.268,N,00622.693,E,0000,M,RE-af,,t,*67 +$PMGNWPL,5113.787,N,00620.392,E,0000,M,X-ag,,ag,*5E +$PMGNWPL,5113.187,N,00618.393,E,0000,M,LI-ah,,t,*72 +$PMGNWPL,5113.173,N,00618.370,E,0000,M,HR-ai,,t,*6A +$PMGNWPL,5113.067,N,00617.335,E,0000,M,X-aj,,ag,*53 +$PMGNWPL,5113.045,N,00617.327,E,0000,M,WE-ak,,ai,*15 +$PMGNWPL,5112.917,N,00617.235,E,0000,M,WE-al,,ai,*1F +$PMGNWPL,5112.870,N,00617.198,E,0000,M,WE-am,,ai,*1A +$PMGNWPL,5112.662,N,00617.032,E,0000,M,WE-an,,ai,*15 +$PMGNWPL,5112.628,N,00617.003,E,0000,M,WE-ao,,ai,*18 +$PMGNWPL,5112.542,N,00616.905,E,0000,M,WE-ap,,ai,*06 +$PMGNWPL,5112.368,N,00615.640,E,0000,M,X-aq,,ag,*40 +$PMGNWPL,5112.280,N,00615.577,E,0000,M,X-ar,,ag,*43 +$PMGNWPL,5111.283,N,00614.125,E,0000,M,LI-as,,t,*6F +$PMGNWPL,5111.183,N,00614.437,E,0000,M,WE-at,,ai,*06 +$PMGNWPL,5110.443,N,00614.968,E,0000,M,RE-au,,t,*71 +$PMGNWPL,5108.635,N,00612.702,E,0000,M,LI-av,,t,*6E +$PMGNWPL,5107.747,N,00611.468,E,0000,M,WE-aw,,ai,*03 +$PMGNWPL,5107.455,N,00611.607,E,0000,M,GE-ax,,t,*6B +$PMGNWPL,5107.420,N,00611.650,E,0000,M,WE-ay,,ai,*06 +$PMGNWPL,5106.262,N,00610.493,E,0000,M,GE-az,,t,*64 +$PMGNWPL,5106.242,N,00610.458,E,0000,M,HR-ba,,t,*61 +$PMGNWPL,5106.062,N,00609.330,E,0000,M,RE-bb,,t,*6E +$PMGNWPL,5106.242,N,00609.325,E,0000,M,LI+bc,,t,*7F +$PMGNWPL,5106.152,N,00608.755,E,0000,M,RE-bd,,t,*6C +$PMGNWPL,5108.380,N,00607.150,E,0000,M,WE-be,,ai,*1B +$PMGNWPL,5108.392,N,00607.175,E,0000,M,WE-bf,,ai,*1C +$PMGNWPL,5108.415,N,00607.148,E,0000,M,GE-bg,,t,*77 +$PMGNWPL,5108.633,N,00606.197,E,0000,M,LI-bh,,t,*7A +$PMGNWPL,5108.313,N,00605.598,E,0000,M,GE-bi,,t,*73 +$PMGNWPL,5108.207,N,00605.248,E,0000,M,X-bj,,ag,*56 +$PMGNWPL,5107.903,N,00604.685,E,0000,M,X-bk,,ag,*53 +$PMGNWPL,5107.848,N,00604.392,E,0000,M,GE-bl,,t,*71 +$PMGNWPL,5107.343,N,00602.802,E,0000,M,RE-bm,,t,*61 +$PMGNWPL,5108.500,N,00600.513,E,0000,M,LI-bn,,t,*71 +$PMGNWPL,5108.542,N,00559.548,E,0000,M,LI-bo,,t,*77 +$PMGNWPL,5108.440,N,00559.298,E,0000,M,GE-bp,,t,*66 +$PMGNWPL,5107.772,N,00556.713,E,0000,M,X-bq,,ag,*4B +$PMGNWPL,5107.762,N,00556.712,E,0000,M,RE-br,,t,*75 +$PMGNWPL,5105.885,N,00553.252,E,0000,M,RE-bs,,t,*74 +$PMGNWPL,5105.882,N,00553.102,E,0000,M,X-bt,,ag,*4F +$PMGNWPL,5104.230,N,00551.097,E,0000,M,WE-bu,,ai,*07 +$PMGNWPL,5104.108,N,00550.925,E,0000,M,WE-bv,,ai,*0D +$PMGNWPL,5103.898,N,00550.732,E,0000,M,WE-bw,,ai,*03 +$PMGNWPL,5102.135,N,00550.940,E,0000,M,WE-bx,,ai,*08 +$PMGNWPL,5102.028,N,00551.003,E,0000,M,WE-by,,ai,*0B +$PMGNWPL,5101.533,N,00551.257,E,0000,M,WE-bz,,ai,*07 +$PMGNWPL,5101.102,N,00551.253,E,0000,M,WE-ca,,ai,*1F +$PMGNWPL,5059.670,N,00550.305,E,0000,M,X-cb,,ag,*55 +$PMGNWPL,5059.375,N,00550.313,E,0000,M,WE-cc,,ai,*17 +$PMGNWPL,5059.032,N,00550.783,E,0000,M,RE-cd,,t,*64 +$PMGNWPL,5058.713,N,00550.433,E,0000,M,LI-ce,,t,*7A +$PMGNWPL,5058.583,N,00550.770,E,0000,M,RE+cf,,t,*62 +$PMGNWPL,5058.398,N,00550.867,E,0000,M,WE-cg,,ai,*19 +$PMGNWPL,5058.260,N,00550.713,E,0000,M,LI-ch,,t,*77 +$PMGNWPL,5058.258,N,00550.738,E,0000,M,RE-ci,,t,*66 +$PMGNWPL,5057.330,N,00552.215,E,0000,M,GE-cj,,t,*78 +$PMGNWPL,5056.793,N,00552.668,E,0000,M,GE-ck,,t,*7B +$PMGNWPL,5056.548,N,00553.163,E,0000,M,RE-cl,,t,*60 +$PMGNWPL,5056.312,N,00552.743,E,0000,M,LI-cm,,t,*7F +$PMGNWPL,5056.280,N,00552.457,E,0000,M,LI-cn,,t,*70 +$PMGNWPL,5056.260,N,00552.423,E,0000,M,LI-co,,t,*7C +$PMGNWPL,5055.515,N,00553.242,E,0000,M,RE-cp,,t,*77 +$PMGNWPL,5055.385,N,00553.273,E,0000,M,LI-cq,,t,*69 +$PMGNWPL,5055.412,N,00553.420,E,0000,M,RE-cr,,t,*71 +$PMGNWPL,5055.252,N,00553.412,E,0000,M,X-cs,,ag,*4E +$PMGNWPL,5054.038,N,00551.160,E,0000,M,HL-ct,,t,*6A +$PMGNWPL,5053.527,N,00551.332,E,0000,M,WE-cu,,ai,*08 +$PMGNWPL,5053.483,N,00551.322,E,0000,M,WE-cv,,ai,*05 +$PMGNWPL,5053.130,N,00551.060,E,0000,M,X-cw,,ag,*48 +$PMGNWPL,5053.003,N,00551.033,E,0000,M,X-cx,,ag,*40 +$PMGNWPL,5052.840,N,00550.980,E,0000,M,RE-cy,,t,*72 +$PMGNWPL,5052.003,N,00549.953,E,0000,M,RE-cz,,t,*78 +$PMGNWPL,5052.030,N,00549.853,E,0000,M,LI-da,,t,*77 +$PMGNWPL,5051.917,N,00549.837,E,0000,M,RE-db,,t,*6B +$PMGNWPL,5051.805,N,00549.783,E,0000,M,HL-dc,,t,*7B +$PMGNWPL,5051.755,N,00549.775,E,0000,M,LI-dd,,t,*7E +$PMGNWPL,5050.828,N,00549.013,E,0000,M,LI-de,,t,*7C +$PMGNWPL,5050.327,N,00549.277,E,0000,M,WE-df,,ai,*10 +$PMGNWPL,5049.888,N,00549.202,E,0000,M,LI-dg,,t,*7E +$PMGNWPL,5049.097,N,00549.707,E,0000,M,LI-dh,,t,*77 +$PMGNWPL,5049.085,N,00549.750,E,0000,M,RE+di,,t,*63 +$PMGNWPL,5049.055,N,00549.738,E,0000,M,LI-dj,,t,*77 +$PMGNWPL,5048.915,N,00550.722,E,0000,M,RE-dk,,t,*6B +$PMGNWPL,5048.098,N,00550.012,E,0000,M,WE-dl,,ai,*1D +$PMGNWPL,5047.712,N,00549.953,E,0000,M,WE-dm,,ai,*12 +$PMGNWPL,5045.897,N,00550.705,E,0000,M,X-dn,,ag,*50 +$PMGNWPL,5045.920,N,00550.703,E,0000,M,WE-do,,ai,*1E +$PMGNWPL,5046.453,N,00550.478,E,0000,M,WE-dp,,ai,*04 +$PMGNWPL,5047.712,N,00549.953,E,0000,M,WE-dq,,ai,*0E +$PMGNWPL,5048.098,N,00550.012,E,0000,M,WE-dr,,ai,*03 +$PMGNWPL,5048.915,N,00550.722,E,0000,M,LI-ds,,t,*61 +$PMGNWPL,5049.055,N,00549.738,E,0000,M,RE-dt,,t,*7B +$PMGNWPL,5049.085,N,00549.750,E,0000,M,LI-du,,t,*6B +$PMGNWPL,5049.097,N,00549.707,E,0000,M,RE-dv,,t,*7B +$PMGNWPL,5049.462,N,00549.488,E,0000,M,LI-dw,,t,*62 +$PMGNWPL,5044.983,N,00551.568,E,0000,M,WE-dx,,ai,*0F +$PMGNWPL,5045.252,N,00552.272,E,0000,M,RE-dy,,t,*7E +$PMGNWPL,5044.995,N,00552.748,E,0000,M,HR-dz,,t,*7D +$PMGNWPL,5044.668,N,00553.183,E,0000,M,WE-ea,,ai,*1E +$PMGNWPL,5044.420,N,00553.200,E,0000,M,LI-eb,,t,*70 +$PMGNWPL,5043.297,N,00554.695,E,0000,M,LI-ec,,t,*73 +$PMGNWPL,5043.413,N,00555.183,E,0000,M,RE-ed,,t,*6D +$PMGNWPL,5043.350,N,00555.220,E,0000,M,X-ee,,ag,*5B +$PMGNWPL,5042.435,N,00557.727,E,0000,M,RE-ef,,t,*60 +$PMGNWPL,5041.915,N,00558.412,E,0000,M,LI-eg,,t,*75 +$PMGNWPL,5043.322,N,00601.587,E,0000,M,RE-eh,,t,*66 +$PMGNWPL,5044.280,N,00602.872,E,0000,M,X-ei,,ag,*50 +$PMGNWPL,5044.318,N,00602.778,E,0000,M,X-ej,,ag,*56 +$PMGNRTE,15,1,c,1,AU-aa,t,WE-ab,ai*49 +$PMGNRTE,15,2,c,1,RE-ac,t,X-ad,ag*09 +$PMGNRTE,15,3,c,1,WE-ae,ai,RE-af,t*48 +$PMGNRTE,15,4,c,1,X-ag,ag,LI-ah,t*15 +$PMGNRTE,15,5,c,1,HR-ai,t,X-aj,ag*07 +$PMGNRTE,15,6,c,1,WE-ak,ai,WE-al,ai*30 +$PMGNRTE,15,7,c,1,WE-am,ai,WE-an,ai*35 +$PMGNRTE,15,8,c,1,WE-ao,ai,WE-ap,ai*26 +$PMGNRTE,15,9,c,1,X-aq,ag,X-ar,ag*3B +$PMGNRTE,15,10,c,1,LI-as,t,WE-at,ai*6C +$PMGNRTE,15,11,c,1,RE-au,t,LI-av,t*10 +$PMGNRTE,15,12,c,1,WE-aw,ai,GE-ax,t*61 +$PMGNRTE,15,13,c,1,WE-ay,ai,GE-az,t*6C +$PMGNRTE,15,14,c,1,HR-ba,t,RE-bb,t*0A +$PMGNRTE,15,15,c,1,LI+bc,t,RE-bd,t*16 +$PMGNRTE,15,1,c,2,RE-bd,t,WE-be,ai*4B +$PMGNRTE,15,2,c,2,WE-bf,ai,GE-bg,t*5D +$PMGNRTE,15,3,c,2,LI-bh,t,GE-bi,t*37 +$PMGNRTE,15,4,c,2,X-bj,ag,X-bk,ag*37 +$PMGNRTE,15,5,c,2,GE-bl,t,RE-bm,t*23 +$PMGNRTE,15,6,c,2,LI-bn,t,LI-bo,t*35 +$PMGNRTE,15,7,c,2,GE-bp,t,X-bq,ag*1C +$PMGNRTE,15,8,c,2,RE-br,t,RE-bs,t*3B +$PMGNRTE,15,9,c,2,X-bt,ag,WE-bu,ai*7E +$PMGNRTE,15,10,c,2,WE-bv,ai,WE-bw,ai*02 +$PMGNRTE,15,11,c,2,WE-bx,ai,WE-by,ai*03 +$PMGNRTE,15,12,c,2,WE-bz,ai,WE-ca,ai*1B +$PMGNRTE,15,13,c,2,X-cb,ag,WE-cc,ai*45 +$PMGNRTE,15,14,c,2,RE-cd,t,LI-ce,t*14 +$PMGNRTE,15,15,c,2,RE+cf,t,WE-cg,ai*78 +$PMGNRTE,15,1,c,3,WE-cg,ai,LI-ch,t*56 +$PMGNRTE,15,2,c,3,RE-ci,t,GE-cj,t*27 +$PMGNRTE,15,3,c,3,GE-ck,t,RE-cl,t*22 +$PMGNRTE,15,4,c,3,LI-cm,t,LI-cn,t*34 +$PMGNRTE,15,5,c,3,LI-co,t,RE-cp,t*3B +$PMGNRTE,15,6,c,3,LI-cq,t,RE-cr,t*24 +$PMGNRTE,15,7,c,3,X-cs,ag,HL-ct,t*1D +$PMGNRTE,15,8,c,3,WE-cu,ai,WE-cv,ai*38 +$PMGNRTE,15,9,c,3,X-cw,ag,X-cx,ag*35 +$PMGNRTE,15,10,c,3,RE-cy,t,RE-cz,t*01 +$PMGNRTE,15,11,c,3,LI-da,t,RE-db,t*12 +$PMGNRTE,15,12,c,3,HL-dc,t,LI-dd,t*06 +$PMGNRTE,15,13,c,3,LI-de,t,WE-df,ai*69 +$PMGNRTE,15,14,c,3,LI-dg,t,LI-dh,t*09 +$PMGNRTE,15,15,c,3,RE+di,t,LI-dj,t*10 +$PMGNRTE,14,1,c,4,LI-dj,t,RE-dk,t*27 +$PMGNRTE,14,2,c,4,WE-dl,ai,WE-dm,ai*36 +$PMGNRTE,14,3,c,4,X-dn,ag,WE-do,ai*73 +$PMGNRTE,14,4,c,4,WE-dp,ai,WE-dq,ai*30 +$PMGNRTE,14,5,c,4,WE-dr,ai,LI-ds,t*5A +$PMGNRTE,14,6,c,4,RE-dt,t,LI-du,t*20 +$PMGNRTE,14,7,c,4,RE-dv,t,LI-dw,t*21 +$PMGNRTE,14,8,c,4,WE-dx,ai,RE-dy,t*45 +$PMGNRTE,14,9,c,4,HR-dz,t,WE-ea,ai*52 +$PMGNRTE,14,10,c,4,LI-eb,t,LI-ec,t*05 +$PMGNRTE,14,11,c,4,RE-ed,t,X-ee,ag*39 +$PMGNRTE,14,12,c,4,RE-ef,t,LI-eg,t*15 +$PMGNRTE,14,13,c,4,RE-eh,t,X-ei,ag*3B +$PMGNRTE,14,14,c,4,X-ej,ag,,*7C diff --git a/reference/sample.gtm b/reference/sample.gtm new file mode 100644 index 0000000000000000000000000000000000000000..3ba596fdb21ab124877af0307e95b979223b1daa GIT binary patch literal 90544 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 XbJTzSm4^GAGcxDq%t_0=M$Y7Kd~fl7 literal 0 HcmV?d00001 diff --git a/reference/sample.gtm.gz b/reference/sample.gtm.gz new file mode 100644 index 0000000000000000000000000000000000000000..cc3b4043608f0c073cdeab95fd00fd73956d7a83 GIT binary patch literal 56931 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

    U!4Q-x6{``SUyF(t!TvflvXjW=l`&! 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 WH?8*GtHoZHYmdmOFt$o-FzA0asiso^ literal 0 HcmV?d00001 diff --git a/reference/simplify_output.txt b/reference/simplify_output.txt new file mode 100644 index 000000000..b10c3d3c4 --- /dev/null +++ b/reference/simplify_output.txt @@ -0,0 +1,13 @@ +30.70000 -92.40000 +30.20000 -92.30000 +29.40000 -92.20000 +28.40000 -91.40000 +27.80000 -91.10000 +26.60000 -90.30000 +24.40000 -88.40000 +23.60000 -87.20000 +23.00000 -85.60000 +22.30000 -84.40000 +30.28052 -91.68588 +30.29105 -91.62717 +30.31472 -91.64612 diff --git a/reference/stmsdf.txt b/reference/stmsdf.txt new file mode 100644 index 000000000..e9981bec8 --- /dev/null +++ b/reference/stmsdf.txt @@ -0,0 +1,83 @@ +Grid Lat/Lon hddd°mm.mmm' +Datum WGS 84 + +Header Name Description Type Position Altitude Depth Proximity Temperature Display Mode Color Symbol Facility City State Country Date Modified Link Categories + +Waypoint 001 User Waypoint N50 29.56 E12 06.33 0 m Symbol & Name Unknown Waypoint +Waypoint 002 User Waypoint N50 29.56 E12 06.33 0 m Symbol & Name Unknown Waypoint +Waypoint 003 User Waypoint N50 29.66 E12 06.31 0 m Symbol & Name Unknown Waypoint +Waypoint 004 User Waypoint N50 29.63 E12 06.37 0 m Symbol & Name Unknown Waypoint +Waypoint 005 User Waypoint N50 29.63 E12 06.37 0 m Symbol & Name Unknown Waypoint +Waypoint 006 User Waypoint N50 29.60 E12 06.43 0 m Symbol & Name Unknown Waypoint +Waypoint 007 User Waypoint N50 29.62 E12 06.43 0 m Symbol & Name Unknown Waypoint +Waypoint Jahnstrasse User Waypoint N50 29.62 E12 06.43 0 m Symbol & Name Unknown Waypoint +Waypoint Liebknechtstrasse User Waypoint N50 29.63 E12 06.37 0 m Symbol & Name Unknown Waypoint +Waypoint NARVA User Waypoint N50 29.56 E12 06.33 391 m Symbol & Name Unknown Waypoint + + +Header Name Length Course Waypoints Link + +Route 394 m 46° true 10 waypoints + +Header Waypoint Name Distance Leg Length Course + +Route Waypoint NARVA 0 m +Route Waypoint 001 2 m 2 m 221° true +Route Waypoint 002 2 m 0 m 0° true +Route Waypoint 003 189 m 188 m 353° true +Route Waypoint 004 274 m 85 m 126° true +Route Waypoint Liebknechtstrasse 274 m 0 m 299° true +Route Waypoint 005 274 m 0 m 119° true +Route Waypoint 006 361 m 88 m 126° true +Route Waypoint 007 393 m 32 m 6° true +Route Waypoint Jahnstrasse 394 m 1 m 351° true + + +Header Name Start Time Elapsed Time Length Average Speed Link + +Track ACTIVE LOG 006 01/05/2005 15:02:47 0:33:09 653 m 1.2 kph + +Header Position Time Altitude Depth Temperature Leg Length Leg Time Leg Speed Leg Course + +Trackpoint N51 18.78 E12 24.79 01/05/2005 15:02:47 161 m +Trackpoint N51 18.77 E12 24.79 01/05/2005 15:03:25 154 m 8 m 0:00:38 0.8 kph 137° true +Trackpoint N51 18.77 E12 24.79 01/05/2005 15:03:39 148 m 3 m 0:00:14 0.8 kph 180° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:04:16 139 m 5 m 0:00:37 0.5 kph 129° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:05:02 145 m 2 m 0:00:46 0.2 kph 270° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:05:45 134 m 2 m 0:00:43 0.2 kph 90° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:06:44 131 m 6 m 0:00:59 0.4 kph 162° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:07:50 130 m 0 m 0:01:06 0 kph 0° true +Trackpoint N51 18.76 E12 24.80 01/05/2005 15:08:19 132 m 3 m 0:00:29 0.4 kph 180° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:11:16 144 m 6 m 0:02:57 0.1 kph 342° true +Trackpoint N51 18.77 E12 24.81 01/05/2005 15:12:34 147 m 16 m 0:01:18 0.7 kph 38° true +Trackpoint N51 18.78 E12 24.83 01/05/2005 15:13:18 145 m 27 m 0:00:44 2 kph 70° true +Trackpoint N51 18.78 E12 24.83 01/05/2005 15:13:27 145 m 6 m 0:00:09 2 kph 0° true +Trackpoint N51 18.78 E12 24.83 01/05/2005 15:13:37 135 m 2 m 0:00:10 0.7 kph 90° true +Trackpoint N51 18.79 E12 24.83 01/05/2005 15:13:46 135 m 6 m 0:00:09 2 kph 0° true +Trackpoint N51 18.79 E12 24.83 01/05/2005 15:14:03 136 m 13 m 0:00:17 3 kph 17° true +Trackpoint N51 18.80 E12 24.84 01/05/2005 15:14:16 135 m 11 m 0:00:13 3 kph 32° true +Trackpoint N51 18.80 E12 24.84 01/05/2005 15:14:26 139 m 7 m 0:00:10 2 kph 117° true +Trackpoint N51 18.80 E12 24.85 01/05/2005 15:14:30 139 m 4 m 0:00:04 4 kph 90° true +Trackpoint N51 18.78 E12 24.88 01/05/2005 15:15:06 141 m 43 m 0:00:36 4 kph 126° true +Trackpoint N51 18.78 E12 24.89 01/05/2005 15:15:27 140 m 18 m 0:00:21 3 kph 121° true +Trackpoint N51 18.77 E12 24.90 01/05/2005 15:15:39 140 m 10 m 0:00:12 3 kph 128° true +Trackpoint N51 18.78 E12 24.90 01/05/2005 15:25:31 152 m 4 m 0:09:52 0.0 kph 33° true +Trackpoint N51 18.78 E12 24.90 01/05/2005 15:25:40 152 m 0 m 0:00:09 0 kph 0° true +Trackpoint N51 18.78 E12 24.90 01/05/2005 15:29:18 155 m 4 m 0:03:38 0.1 kph 328° true +Trackpoint N51 18.79 E12 24.87 01/05/2005 15:30:30 149 m 33 m 0:01:12 2 kph 311° true +Trackpoint N51 18.79 E12 24.87 01/05/2005 15:30:37 150 m 2 m 0:00:07 1.0 kph 270° true +Trackpoint N51 18.79 E12 24.87 01/05/2005 15:30:47 151 m 8 m 0:00:10 3 kph 270° true +Trackpoint N51 18.79 E12 24.86 01/05/2005 15:30:48 151 m 4 m 0:00:01 14 kph 270° true +Trackpoint N51 18.80 E12 24.83 01/05/2005 15:30:52 150 m 38 m 0:00:04 34 kph 300° true +Trackpoint N51 18.82 E12 24.80 01/05/2005 15:30:57 150 m 57 m 0:00:05 41 kph 315° true +Trackpoint N51 18.84 E12 24.77 01/05/2005 15:31:03 150 m 47 m 0:00:06 28 kph 316° true +Trackpoint N51 18.85 E12 24.75 01/05/2005 15:31:10 150 m 35 m 0:00:07 18 kph 314° true +Trackpoint N51 18.88 E12 24.57 01/05/2005 15:32:38 143 m 210 m 0:01:28 9 kph 283° true +Trackpoint N51 18.88 E12 24.57 01/05/2005 15:32:45 141 m 4 m 0:00:07 2 kph 270° true +Trackpoint N51 18.88 E12 24.57 01/05/2005 15:33:17 143 m 0 m 0:00:32 0 kph 0° true +Trackpoint N51 18.88 E12 24.57 01/05/2005 15:33:42 139 m 4 m 0:00:25 0.6 kph 270° true +Trackpoint N51 18.88 E12 24.56 01/05/2005 15:33:54 139 m 6 m 0:00:12 2 kph 270° true +Trackpoint N51 18.88 E12 24.56 01/05/2005 15:34:04 138 m 0 m 0:00:10 0 kph 0° true +Trackpoint N51 18.88 E12 24.56 01/05/2005 15:34:20 139 m 0 m 0:00:16 0 kph 0° true +Trackpoint N51 18.88 E12 24.56 01/05/2005 15:35:45 144 m 0 m 0:01:25 0 kph 0° true +Trackpoint N51 18.88 E12 24.56 01/05/2005 15:35:56 145 m 0 m 0:00:11 0 kph 0° true diff --git a/reference/tomtom_poi.asc b/reference/tomtom_poi.asc new file mode 100644 index 000000000..fdadaa828 --- /dev/null +++ b/reference/tomtom_poi.asc @@ -0,0 +1,90 @@ + TomTom Navigator Places of Interest + GPSBabel- ASCII Export + Points + Created at: Thu Jan 01 00:00:00 1970 +-71.119277,42.438878,"5066" +-71.119689,42.439227,"5067" +-71.116146,42.438917,"5096" +-71.122044,42.443904,"5142" +-71.121447,42.447298,"5156" +-71.125094,42.454873,"5224" +-71.124988,42.459079,"5229" +-71.124474,42.456979,"5237" +-71.120990,42.454401,"5254" +-71.121746,42.451442,"5258" +-71.120660,42.454404,"5264" +-71.121045,42.457761,"526708" +-71.120313,42.457089,"526750" +-71.119676,42.456592,"527614" +-71.119356,42.456252,"527631" +-71.119135,42.458148,"5278" +-71.117693,42.459377,"5289" +-71.119828,42.464183,"5374FIRE" +-71.119399,42.465650,"5376" +-71.114456,42.439018,"6006" +-71.114803,42.438594,"6006BLUE" +-71.113223,42.436757,"6014MEADOW" +-71.113220,42.441754,"6029" +-71.109075,42.436243,"6053" +-71.107500,42.439250,"6066" +-71.107582,42.439764,"6067" +-71.105874,42.434766,"6071" +-71.106599,42.433304,"6073" +-71.104772,42.437338,"6084" +-71.110975,42.442196,"6130" +-71.111441,42.442981,"6131" +-71.108882,42.444773,"6153" +-71.106301,42.443592,"6171" +-71.106624,42.447804,"6176" +-71.106158,42.448448,"6177" +-71.106783,42.453415,"6272" +-71.107253,42.453434,"6272" +-71.106771,42.458298,"6278" +-71.105413,42.451430,"6280" +-71.105206,42.453845,"6283" +-71.106170,42.459986,"6289" +-71.105116,42.457616,"6297" +-71.113574,42.467110,"6328" +-71.109863,42.464202,"6354" +-71.110067,42.466459,"635722" +-71.109410,42.466557,"635783" +-71.107117,42.463495,"6373" +-71.110241,42.401051,"6634" +-71.106532,42.432621,"6979" +-71.107883,42.431033,"6997" +-71.107360,42.465687,"BEAR HILL" +-71.107628,42.430950,"BELLEVUE" +-71.114079,42.438666,"6016" +-71.124651,42.456469,"5236BRIDGE" +-71.119815,42.465759,"5376BRIDGE" +-71.105878,42.442993,"6181CROSS" +-71.109664,42.435472,"6042CROSS" +-71.103646,42.458516,"DARKHOLLPO" +-71.112675,42.443109,"6121DEAD" +-71.119298,42.449866,"5179DEAD" +-71.116524,42.459629,"5299DEAD" +-71.119148,42.465485,"5376DEAD" +-71.109986,42.462776,"6353DEAD" +-71.108784,42.446793,"6155DEAD" +-71.126602,42.451204,"GATE14" +-71.122078,42.458499,"GATE16" +-71.119238,42.459376,"GATE17" +-71.119240,42.466353,"GATE19" +-71.107697,42.468655,"GATE21" +-71.102973,42.456718,"GATE24" +-71.107690,42.430847,"GATE5" +-71.109236,42.431240,"GATE6" +-71.106556,42.439502,"6077LOGS" +-71.122320,42.449765,"5148NANEPA" +-71.119845,42.457388,"5267OBSTAC" +-71.109942,42.434980,"PANTHRCAVE" +-71.121211,42.453256,"5252PURPLE" +-71.117481,42.457734,"5287WATER" +-71.124574,42.459278,"5239ROAD" +-71.118991,42.458782,"5278ROAD" +-71.120925,42.439993,"5058ROAD" +-71.106782,42.453415,"SHEEPFOLD" +-71.107483,42.455956,"SOAPBOX" +-71.119328,42.465913,"5376STREAM" +-71.122845,42.445359,"5144SUMMIT" +-71.121676,42.441727,"5150TANK" diff --git a/reference/topomapexample.txt b/reference/topomapexample.txt new file mode 100644 index 000000000..02b35ef1d --- /dev/null +++ b/reference/topomapexample.txt @@ -0,0 +1,8 @@ +Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink +new HOME Close to Home -43.556459 172.644418 2481280 5738940 255 1 http://www.automata.co.nz +new Work The place I love to be :) -43.528788 172.604622 2478050 5742000 255 1 http://www.copyland.co.nz +new SQUARE -43.530962 172.636401 2480620 5741770 255 1 http://www.ccc.govt.nz +new MGD I have a cache near here -43.579588 172.673997 2483680 5736380 255 1 http://www.geocacghing.com/seek/cache_details.aspx?ID=19000 +new MAGOBS Magnetic Observatory -43.422331 172.352275 2457560 5753700 255 1 http://magobs.co.nz +new MAPA Farm -43.360444 172.549087 2473460 5760680 255 1 +new BOTTLE Bottle Lake -43.462214 172.672152 2483480 5749420 255 1 http://www.bottlelake.co.nz diff --git a/reference/topomappro.txt b/reference/topomappro.txt new file mode 100644 index 000000000..5837da3a5 --- /dev/null +++ b/reference/topomappro.txt @@ -0,0 +1,10 @@ +Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink +new GCEBB Mountain Bike Heaven by susy1313 35.972033 -87.134700 0.00 255 1 http://www.geocaching.com/seek/cache_details.asp?ID=3771 +new GC1A37 The Troll by a182pilot & Family 36.090683 -86.679550 0.00 255 1 http://www.geocaching.com/seek/cache_details.asp?ID=6711 +new GC1C2B Dive Bomber by JoGPS & family 35.996267 -86.620117 0.00 255 1 http://www.geocaching.com/seek/cache_details.asp?ID=7211 +new GC25A9 FOSTER by JoGPS & Family 36.038483 -86.648617 0.00 255 1 http://www.geocaching.com/seek/cache_details.asp?ID=9641 +new GC2723 Logan Lighthouse by JoGps & Family 36.112183 -86.741767 0.00 255 1 http://www.geocaching.com/seek/cache_details.asp?ID=10019 +new GC2B71 Ganier Cache by Susy1313 36.064083 -86.790517 0.00 255 1 http://www.geocaching.com/seek/cache_details.asp?ID=11121 +new GC309F Shy's Hill by FireFighterEng33 36.087767 -86.809733 0.00 255 1 http://www.geocaching.com/seek/cache_details.asp?ID=12447 +new GC317A GittyUp by JoGPS / Warner Parks 36.057500 -86.892000 0.00 255 1 http://www.geocaching.com/seek/cache_details.asp?ID=12666 +new GC317D Inlighting by JoGPS / Warner Parks 36.082800 -86.867283 0.00 255 1 http://www.geocaching.com/seek/cache_details.asp?ID=12669 diff --git a/reference/tpg.tpg b/reference/tpg.tpg new file mode 100644 index 0000000000000000000000000000000000000000..a9a01a292ecc85bab249a87221b79e28ca19faca GIT binary patch literal 577 zcmd;N`2U}gftSHKB)=d(Jh8GMKQpg{)!o_E$>|ff!rOT#LLL6{J}%4nQIN@ z>Rn|sxSgQ-?uXEDv=s zzQxwx^dDxutV?EDs)AE~Zc=Iy$N;Z=_kdua<}`$6BU499UO^fC=9QriC4zT9ykvpd zE#c-L9O4>;tPjajBXc8T3+ocU%JrcRZjOKdMDW4%Df#55C*~>mWTt17WaO6?r$S9A zC`NU*k(0UM#p$UGGd6`fEZSsx(SQSHf`ofwUMA4R&WXuD?*rW(j2v3V29|E$%!{vG z+8pZ8;BN5P0v=j&!5Nk6#R?vokl=F5EJ}3)xgxd5H80&564u6s=8hk_m6nU`40VY7 zDk>hy4zpF>J+q{wGPD5UVSR=0#G*W)Ljn?uvWvlC4b<*Z?4q`{aeJu4wd3!Vrg6cv QD|zPSfGo?*OUG>j0EY0qIRF3v literal 0 HcmV?d00001 diff --git a/reference/tpo-sample.tpo b/reference/tpo-sample.tpo new file mode 100644 index 0000000000000000000000000000000000000000..6c3751e1fd8537037ac773aeca3f299839c68f54 GIT binary patch literal 9293 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 + + + + 2428.000000 + 001 + 001 + 001 + + + 2439.000000 + 002 + 002 + 002 + + + 2462.000000 + 003 + WITH MESSAGE + WITH MESSAGE + + + 2559.000000 + GPSRTE0 + GPSRTE0 + GPSRTE0 + + + 2582.000000 + GPSRTE1 + GPSRTE1 + GPSRTE1 + + + 2586.000000 + GPSRTE2 + GPSRTE2 + GPSRTE2 + + + 2612.000000 + GPSRTE3 + GPSRTE3 + GPSRTE3 + + + 2606.000000 + GPSRTE4 + GPSRTE4 + GPSRTE4 + + + 2632.000000 + GPSRTE5 + GPSRTE5 + GPSRTE5 + + + 2627.000000 + GPSRTE6 + GPSRTE6 + GPSRTE6 + + + 2622.000000 + GPSRTE7 + GPSRTE7 + GPSRTE7 + + + 2639.000000 + GPSRTE8 + GPSRTE8 + GPSRTE8 + + + 2599.000000 + GPSRTE9 + GPSRTE9 + GPSRTE9 + + + NOTE 1 + This is a note that has a photo attached + This is a note that has a photo attached + w:\photo.jpg + + + NOTE 2 + 2nd note, with link to a web page + 2nd note, with link to a web page + http://www.defghi.org + + + NOTE 3 + 3rd note, with a link to a document + 3rd note, with a link to a document + c:document.txt + + + SYM 1 + SYM 1 + SYM 1 + + + SYM 2 + SYM 2 + SYM 2 + + + SYM 3 + SYM 3 + SYM 3 + + + SYM 4 + SYM 4 + SYM 4 + + + TXT 1 + test + test + + + TXT 2 + test2 with new style + test2 with new style + + + TXT 3 + 2.55 miles + 2.55 miles + + + RTE 1 + 1 + + 2559.000000 + GPSRTE0 + + + 2582.000000 + GPSRTE1 + + + 2586.000000 + GPSRTE2 + + + 2612.000000 + GPSRTE3 + + + 2606.000000 + GPSRTE4 + + + 2632.000000 + GPSRTE5 + + + 2627.000000 + GPSRTE6 + + + 2622.000000 + GPSRTE7 + + + 2639.000000 + GPSRTE8 + + + 2599.000000 + GPSRTE9 + + + + crazy route 4.49 miles long +1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TRK 2 +2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TRK 3 +3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/tpo-sample3.tpo b/reference/tpo-sample3.tpo new file mode 100644 index 0000000000000000000000000000000000000000..af5065a45f21e53e1351db458cf04177fc801f80 GIT binary patch literal 7442 zcmeI1eQXrR6~O1t_p!HoJA3xp2N*~enxq)f!yktM2SRK(J{;Rv_5lVVhqZ6k>z2t{hssA{XGv~s25QeyYb z?t+(t{?)(I-ipJ&dGF1e_c1$%hfsWL=hj8ic14Xy4UuT10hONrw+j5o{e{Wcg-%1T zk9#|Eno@wM1E|K2P#M}Yk0WotVu%v*Er};n1quGhQWmTvEh%eKQl{g4GN@0vp{CuYDDqH#V0d`?NZHKAnct#N>&7h`zc3Xk1zM`W|7Hc={5eM^kI{G9yQn^! zFyH27(ojlEO6gQ~pG03}X-Mgl^74REmDIF+)AHp*Lqm~-vUebvisaM*yD%?p4U(Q$ zO;2BHP;c@iJA5T_{eu}LtKt5p>lo37wd>V&qmX!=OFv5$C{>_Tfl>uZ6)07pRDn_j z{>ut%iFIrkYuR(iS4hfvrQl*&j6!!Uwi`w2Lhbuj1i zi{-XW(Ce+LvYGdKs=_wofFD=bEPzd=%^}lXR@K~)8Gq1cv76&q)@F!5$l2_1$Z7o7 z?R^e8#DBw{amWK46A)}aP^laKIffGgwmj&N^A3CLkP8m`5S6p4(yuDAmda&aK1K{V z#%?bYc8<%~KoC3h9>yzFImTXppxmkVm9f>FL+?kNT*$b=tK}iMIkhj99gxfjXT?H$ZZNCKsjSpu>aA+}(Y7#x zy#y=66LbmjR7NRC9my0Rm-LyE_G;!<04ORP=mj_+)X zRo)VCEktqfc9~eMDeuVj>P)d9uyG1udVYvP2Qm94p)*&V4vhH7(&v#MbB6S{#ufu8uR(wEb;*Kcj_Z0_#1 za(27zX9d%u0%PNSRdvY;Bv(a!Q4(0L5jyE2r*uzy$&9ROkvE#B_&v zP{kbjxA*FDj(pr{h{&rAa71kZa$h^jk&jjZ`I*&0^72|BrOS`n@ZRG*Su$>j)yC*io-BSI=JlTDiT*8ssSkK^_z1w*Wu6>51aNi@CI?i2 z$)_;c-v{vAc}yPe0$BVBCR!`NsVmsb%&7bgCTmuL351%T~-OltiA z?2mb}?8=B}9C#iA`YQm<=c(TVq~GDmuHOMrWXcb=nCBWVSPmY}cczYL5g0BIDTX@30 z1kiOiPnc0%eBq6;01G>0B#Nd3uCZ$Z>3wH*8@yobzaS8D8oK^;O@=i-`ldjnXQ1Ns zae*v24A9jem`#1dcyzU3b@iD(feh~g9T^v_9=`l*!Q7mgd8UVR3@C?t1!BVHpg`V3 zAo);&#U~-z*2e_0{e1wsxY?Mt%Qm$9N+2hHK`V32hVf>Bj2{Qdb}X13x@5e2hhR12 zt}emq!=Wbx(%1z?cvK+KR)C3b2qaPupnY8+yBCg#SO3Hso`OI+|DuckoPdhl5k~u} z7xLt@8h!S)pn_A4x)?UjuHebp4qa@Nm)0~rU}%FpIdU%yW83yDU0Rdb6OYCFcN_Gj zk-nmfJ2P@D))?zcHyN!DV{-ByU2Mwa;>NKbU@{TW#V^MYV$j<8^mX;0@8HPd3nStr z94=SjL%$CL^Z=mW$jE(ghBM1^5>)?y&t_1u@TsKgdh245p6uo~9C97s3w^n$i=W!w z7TVs}`pAkE)+qp|6M6#Hc0t-3m?i6TnY>(p|7f5mk5n6p)>1PVYf@dq%1CWAp$w>s zQgDyo&5_W^h`9JXM<)KI!;yp0)ddLgkVb879a{4sN1~7E;SC20B^2BJ+#YZQLbq&Zo%eLua@3mrG6wN)slgo9wIR9#~ zZUs90M>uI7(8V5)rzn<2^zIx?7A(}osJmFV65YQQlPA~fVjG<3H|MYlEqE4Q=`hUm k7wcA|Yd^tcvRN0`UAYm903D^xgNOBaeSRhY{|M**4ev-gNdN!< literal 0 HcmV?d00001 diff --git a/reference/track/TrkDB-GPil.pdb b/reference/track/TrkDB-GPil.pdb new file mode 100644 index 0000000000000000000000000000000000000000..00c0912334a2eedb12c4c1d1bd32a5d883c4d4e0 GIT binary patch literal 9544 zcmeI%d2m(L9S886gyoSvghU`9F@@|a5fIcQFZYB5Cxui3jKyja5+Fk$5GX3xs%fd3K#@c;9O?OAL?RDC1dJSZE}Kk0~mtn0l{O{2<~zzMX6s zpGQRc7!iXXH*9I9VVm+#^eke)H0!sp_S$1+bIe(fUe@P1!wkqfremAafaDproChhJ zO~u|r}hRpyEKE+TQ1 zgXYQBt&|MJBv1~Sr>jqkBvSrrp4k~lNk>c)<*<2ny%HHrsW#gV^b)b!e8jvk-MTtU z4Pnet^HQEKW6~g2-#<0KIG9X%6f&GKHRhE+JWqK9@-XF?dENU%kw+-C=2tf^b&`7X z>+rWbNuznw*BVvUW0i84w>+Cc) zVpT}C)#ir~!@ES?U1@dr>z+ z1ud|qRD;qrC(nk|Q}Xp3OU{OzqD58M=Y%52R>~%kks>?fS~xv3x!W}E7Qrr>d71LD2zF7k z2c<^&D#fec59vjz(=Cku0&+j)jE;$43E@f9ct_V0KOK?_Y4Vj)C6EkCpu|joa8#T6 zDc_SkVdFW5HI!uC(|9~GPlq@ZA-$34_JfZ7}`!{3@WunMM z2v>Jgk#0|1HH34uX_g53mH8^=WhpfgvVgKy`L;Kr&2e#%X_W0+VsApmQL6R2h;4%K zBx-UfzbC>`D)uiBe@dIk9!NLJMSX(AZZ>T8o0O{(^BRP6tm&4-EP|YaI6OqK^V^S8 zy522Zr;hG-3&+{vEj2GdDUP$lPhxNf?SG?$D!*%&*k;^8dmW{(@@wRI5&JU;=c;3X z#NaHje@2NG$%1f(JL062f>`Z|7r_&ny_GRZB6zxRNs98@%{@GJ1f+#AsUk^`2Fh^h z1?IE;1m#hY!5G#4l+hx*Uo$C_ygH$E-jvtUKrwnFZOvn9I8FF*%SI zAkALNKbg-7F#{kIDZRBsd|0Ucrqpv}RQIbS1Kon(&@*l&UHu^jyn=(}D z!3kpLlT7m{eNUs0LJm;I>-I$NgH%zT6!|lR=T7re`kqE(hTC^j3PfIoETqhqQi~zK zqRbU}2{Ml|U*t)M)r*xPoOMBr*`WM`K435KEShnVvQ64dIZyde1UpH_8OnJPJLDt< zYtWkW(P(7QCS!V;j&euJSDu6^%7K&he(s>R#7l~jO zb;T^zEsXjxgwGq!WfFrK<&qU5rpQVWj7EACOT8}j;8{IAg0fm-`a?V@oAiu|>WA-( z?UYIp%+)lWJI?n+`armkIk#(x#2%i;Q_p!w=9HIVq(+lbACiHIU!2o^$${Ka#SF(kAi=giqAYiy|LGxKf;-i)@4Zobt8u zzt9EuJ@Su`S(I;7KzE+_ky!6(<&c)HDq!Op%1lTFB~%4ITt*qC>uHHmK`Fnca16PR zwWO(_yc~)Tq>Pdy;s+_Fb&p?Z!ikZV~|{=HH&|4VLHu2F&gHsgDN)N{LXt?E+ec~?ER zE7!S1vNT0SMaKB7@Z2%kKZvBuJ$J&&(tPR8((rphtvgGDOa)FWcb3MTr9l<~&q(ep zjXO)@&eFKEH0~@7@(J!N4e|-@EDbUz?ko+m8SX3%ax(5L4e}E1EDdrF?ko*5IsfA< l&0U$C8r5Y-#&?;Vem%2FI%j(zll5N%b^Zr3#q}4%{{R9~D-8eu literal 0 HcmV?d00001 diff --git a/reference/track/axim-sample.gpb b/reference/track/axim-sample.gpb new file mode 100644 index 0000000000000000000000000000000000000000..ac40b00db7d73a095c06c4ef01c21dc504c6fede GIT binary patch literal 4128 zcmZQ%U|@(~WMH`epBczvV7SK4!obKN!NAF&#~=da>wH?W$)~{6p}pz;auC`v&N5d5uHsppYD6PQ4_3gWb6)M1REwt^jTVgO19!T7dTxZRkX}4}U{%|!m4hEM4vu0WjyK;aU;VJ

    oYS4Od8gfUA53l^?Kh-P%)PB@YZ&W8=+sJLC}M zE4FfAG+gnAs}xeW%KkLtmIa2Zd~3E{b;-oh^a>0c5Fn>~1+_VBW2fB#l>@D*KW|F` z!*z#TtKGK~h<4U2Nz8g{*37_RSH6PUS0DhQk?So`yAB(`S8svZi?DEge{uI3321sP z+)G@zGB8*Sn|h0y;VKIZ*S8H5UxCuA_}Q$jV!&{nHB-{A`pP7DIgqA?JH3vEEB5{t zsLuimSLYLw`$T}@su{x%>~A5p2Yg1umDF-T9;jjdlAa%+^lBWm^`8(lz1nikhNoAC R2F!3}U + + + + + + + 320.000000 + + + + 320.000000 + + + + 320.100006 + + + + 320.100006 + + + + 320.100006 + + + + 320.100006 + + + + 320.100006 + + + + 320.200012 + + + + 320.200012 + + + + 320.299988 + + + + 320.600006 + + + + 321.000000 + + + + + diff --git a/reference/track/chi-mapsend.trk b/reference/track/chi-mapsend.trk new file mode 100644 index 0000000000000000000000000000000000000000..1de24286192b3e42f6e78ac4a21ce576f73daa23 GIT binary patch literal 58030 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%0A^M>ugv^`%+^!3~SUdCGUf=Y@$iQ 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 + + + + + ACTIVE LOG 006 + + + 161.000000 + + + + 154.000000 + + + + 148.000000 + + + + 139.000000 + + + + 145.000000 + + + + 134.000000 + + + + 131.000000 + + + + 130.000000 + + + + 132.000000 + + + + 144.000000 + + + + 147.000000 + + + + 145.000000 + + + + 145.000000 + + + + 135.000000 + + + + 135.000000 + + + + 136.000000 + + + + 135.000000 + + + + 139.000000 + + + + 139.000000 + + + + 141.000000 + + + + 140.000000 + + + + 140.000000 + + + + 152.000000 + + + + 152.000000 + + + + 155.000000 + + + + 149.000000 + + + + 150.000000 + + + + 151.000000 + + + + 151.000000 + + + + 150.000000 + + + + 150.000000 + + + + 150.000000 + + + + 150.000000 + + + + 143.000000 + + + + 141.000000 + + + + 143.000000 + + + + 139.000000 + + + + 139.000000 + + + + 138.000000 + + + + 139.000000 + + + + 144.000000 + + + + 145.000000 + + + + + diff --git a/reference/track/compegps.trk b/reference/track/compegps.trk new file mode 100644 index 000000000..dc0c04f09 --- /dev/null +++ b/reference/track/compegps.trk @@ -0,0 +1,53 @@ +G WGS 84 +U 1 +N oliskoli +D Leipzig +C 119 119 0 2 -1.000000 +L 02:00:00 +V 0.0 0.0 0 0 0 0 0.0 +M No comment +E 0|1|00-NUL-00 00:00:00|00:00:00|0 +T A 51.3129500000ºN 12.4131666667ºE 01-MAY-05 13:02:47 N 161.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +t 4294967295|ACTIVE LOG 006|-1|-1 +T A 51.3128833333ºN 12.4132333333ºE 01-MAY-05 13:03:25 s 154.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3128666667ºN 12.4132333333ºE 01-MAY-05 13:03:39 s 148.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3128166667ºN 12.4133000000ºE 01-MAY-05 13:04:16 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3128333333ºN 12.4132666667ºE 01-MAY-05 13:05:02 s 145.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3128333333ºN 12.4133166667ºE 01-MAY-05 13:05:45 s 134.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3127833333ºN 12.4133500000ºE 01-MAY-05 13:06:44 s 131.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3127833333ºN 12.4133333333ºE 01-MAY-05 13:07:50 s 130.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3127500000ºN 12.4133333333ºE 01-MAY-05 13:08:19 s 132.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3128166667ºN 12.4133166667ºE 01-MAY-05 13:11:16 s 144.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129333333ºN 12.4134500000ºE 01-MAY-05 13:12:34 s 147.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3130000000ºN 12.4138000000ºE 01-MAY-05 13:13:18 s 145.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3130500000ºN 12.4138166667ºE 01-MAY-05 13:13:27 s 145.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3130500000ºN 12.4138500000ºE 01-MAY-05 13:13:37 s 135.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3131166667ºN 12.4138500000ºE 01-MAY-05 13:13:46 s 135.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3132166667ºN 12.4138833333ºE 01-MAY-05 13:14:03 s 136.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3133000000ºN 12.4139666667ºE 01-MAY-05 13:14:16 s 135.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3132833333ºN 12.4140500000ºE 01-MAY-05 13:14:26 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3132666667ºN 12.4141000000ºE 01-MAY-05 13:14:30 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3130500000ºN 12.4146166667ºE 01-MAY-05 13:15:06 s 141.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129833333ºN 12.4148333333ºE 01-MAY-05 13:15:27 s 140.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129333333ºN 12.4149333333ºE 01-MAY-05 13:15:39 s 140.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129500000ºN 12.4149666667ºE 01-MAY-05 13:25:31 s 152.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129333333ºN 12.4149833333ºE 01-MAY-05 13:25:40 s 152.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129666667ºN 12.4149500000ºE 01-MAY-05 13:29:18 s 155.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3131666667ºN 12.4146000000ºE 01-MAY-05 13:30:30 s 149.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3131666667ºN 12.4145666667ºE 01-MAY-05 13:30:37 s 150.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3131666667ºN 12.4144333333ºE 01-MAY-05 13:30:47 s 151.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3131500000ºN 12.4143833333ºE 01-MAY-05 13:30:48 s 151.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3133333333ºN 12.4139000000ºE 01-MAY-05 13:30:52 s 150.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3137000000ºN 12.4133166667ºE 01-MAY-05 13:30:57 s 150.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3139833333ºN 12.4128666667ºE 01-MAY-05 13:31:03 s 150.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3142166667ºN 12.4124833333ºE 01-MAY-05 13:31:10 s 150.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4095666667ºE 01-MAY-05 13:32:38 s 143.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4095000000ºE 01-MAY-05 13:32:45 s 141.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4095000000ºE 01-MAY-05 13:33:17 s 143.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4094500000ºE 01-MAY-05 13:33:42 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4093500000ºE 01-MAY-05 13:33:54 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4093500000ºE 01-MAY-05 13:34:04 s 138.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4093500000ºE 01-MAY-05 13:34:20 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4093500000ºE 01-MAY-05 13:35:45 s 144.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4093500000ºE 01-MAY-05 13:35:56 s 145.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +F 1234 diff --git a/reference/track/destinator_trl.dat b/reference/track/destinator_trl.dat new file mode 100644 index 0000000000000000000000000000000000000000..6d54aff034f95f783caf315b935c67ac081223b7 GIT binary patch literal 3952 zcmZ4WvNu;}x3Ytd*@62`$GsdFK;VEoga&g^2}U574ONIJp80GhhDqx-`ruL=5)pzT zl~Yl*6xm&AAn=Sf?%G6xyY$)9?;^X)7z94k#$6XFa2F&nJseO16^TPhJbs|SU1!e# z0S|55C9t0O^!0ISu&6Flx}P-@2qbCaE`1W*g`U2^>0XUC?#d;>UFhKjPWQ&NahKm9 zb=Mja+_go;!52AwfwP_iZNlp`3GPCVM{s^TLmPMT9U(tI($Zb8NC+>i@z_9{@Z#D) zet3b?*8$qN>%w8;-Gv@rw2a61B)AK`JprkQJROj#L=+|^^`kEZ>7JJHm_vfQ(CZ;u zx~qo_cioHJ{T9?-rDghBO@h17(-*isag#Rr@e~E_g0!P)<1UV)#FrE3;YG{*s6m3e nu%>$k+LROS6u1l0@1RXQrVUbewUOX1^z=o`@S1;&_;e2dPTgR{ literal 0 HcmV?d00001 diff --git a/reference/track/destinator_trl.txt b/reference/track/destinator_trl.txt new file mode 100644 index 000000000..39b0717f4 --- /dev/null +++ b/reference/track/destinator_trl.txt @@ -0,0 +1,27 @@ +No,Latitude,Longitude,Altitude,FIX,Satellites,Date,Time +1,53.556728,9.865573,47.5,"3d",6,2007/08/17,09:31:56.496 +2,53.556728,9.865575,47.8,"3d",6,2007/08/17,09:31:56.752 +3,53.556728,9.865577,47.9,"3d",6,2007/08/17,09:31:57 +4,53.556728,9.865577,48.0,"3d",6,2007/08/17,09:31:57.248 +5,53.556728,9.865577,48.1,"3d",6,2007/08/17,09:31:57.504 +6,53.556728,9.865578,48.2,"3d",6,2007/08/17,09:31:57.752 +7,53.556728,9.865577,48.3,"3d",6,2007/08/17,09:31:58.248 +8,53.556728,9.865578,48.4,"3d",6,2007/08/17,09:31:58 +9,53.556728,9.865578,48.4,"3d",6,2007/08/17,09:31:58.752 +10,53.556728,9.865580,48.5,"3d",6,2007/08/17,09:31:59 +11,53.556728,9.865578,49.6,"3d",6,2007/08/17,09:32:00.496 +12,53.556728,9.865578,49.6,"3d",6,2007/08/17,09:31:59.248 +13,53.556728,9.865580,49.0,"3d",6,2007/08/17,09:31:59.504 +14,53.556728,9.865578,49.5,"3d",6,2007/08/17,09:32:00 +15,53.556728,9.865580,49.6,"3d",6,2007/08/17,09:32:00.248 +16,53.556728,9.865575,50.1,"3d",6,2007/08/17,09:32:01 +17,53.556728,9.865578,49.5,"3d",6,2007/08/17,09:32:01.248 +18,53.556728,9.865577,49.5,"3d",6,2007/08/17,09:32:01.504 +19,53.556730,9.865577,49.6,"3d",6,2007/08/17,09:32:01.752 +20,53.556728,9.865575,49.7,"3d",6,2007/08/17,09:32:02 +21,53.556728,9.865575,49.8,"3d",6,2007/08/17,09:32:02.496 +22,53.556728,9.865575,50.1,"3d",6,2007/08/17,09:32:02.752 +23,53.556728,9.865577,50.0,"3d",6,2007/08/17,09:32:03 +24,53.556728,9.865577,49.9,"3d",6,2007/08/17,09:32:03.248 +25,53.556728,9.865577,49.9,"3d",6,2007/08/17,09:32:03.504 +26,53.556728,9.865575,49.9,"3d",6,2007/08/17,09:32:05.752 diff --git a/reference/track/dmtlog-sample.gpx b/reference/track/dmtlog-sample.gpx new file mode 100644 index 000000000..7bec3fc69 --- /dev/null +++ b/reference/track/dmtlog-sample.gpx @@ -0,0 +1,722 @@ + + + + + + 44.586548 + 5066 + 5066 + 5066 + + + 57.607200 + 5067 + 5067 + 5067 + + + 44.826904 + 5096 + 5096 + 5096 + + + 50.594727 + 5142 + 5142 + 5142 + + + 127.711200 + 5156 + 5156 + 5156 + + + 96.926400 + 5224 + 5224 + 5224 + + + 82.600800 + 5229 + 5229 + 5229 + + + 82.905600 + 5237 + 5237 + 5237 + + + 66.696655 + 5254 + 5254 + 5254 + + + 74.627442 + 5258 + 5258 + 5258 + + + 65.254761 + 5264 + 5264 + 5264 + + + 77.419200 + 526708 + 526708 + 526708 + + + 74.676000 + 526750 + 526750 + 526750 + + + 78.713135 + 527614 + 527614 + 527614 + + + 78.713135 + 527631 + 527631 + 527631 + + + 68.275200 + 5278 + 5278 + 5278 + + + 64.008000 + 5289 + 5289 + 5289 + + + 52.997925 + 5374FIRE + 5374FIRE + 5374FIRE + + + 56.388000 + 5376 + 5376 + 5376 + + + 56.388000 + 6006 + 600698 + 600698 + + + 46.028564 + 6006BLUE + 6006BLUE + 6006BLUE + + + 37.616943 + 6014MEADOW + 6014MEADOW + 6014MEADOW + + + 56.388000 + 6029 + 6029 + 6029 + + + 50.292000 + 6053 + 6053 + 6053 + + + 25.603200 + 6066 + 6066 + 6066 + + + 34.442400 + 6067 + 6067 + 6067 + + + 30.480000 + 6071 + 6071 + 6071 + + + 15.240000 + 6073 + 6073 + 6073 + + + 37.795200 + 6084 + 6084 + 6084 + + + 64.008000 + 6130 + 6130 + 6130 + + + 64.008000 + 6131 + 6131 + 6131 + + + 62.788800 + 6153 + 6153 + 6153 + + + 55.473600 + 6171 + 6171 + 6171 + + + 62.484000 + 6176 + 6176 + 6176 + + + 62.179200 + 6177 + 6177 + 6177 + + + 69.799200 + 6272 + 6272 + 6272 + + + 73.152000 + 6272 + 6272 + 6272 + + + 70.104000 + 6278 + 6278 + 6278 + + + 57.564209 + 6280 + 6280 + 6280 + + + 66.696655 + 6283 + 6283 + 6283 + + + 72.945191 + 6289 + 6289 + 6289 + + + 72.847200 + 6297 + 6297 + 6297 + + + 53.644800 + 6328 + 6328 + 6328 + + + 43.891200 + 6354 + 6354 + 6354 + + + 48.768000 + 635722 + 635722 + 635722 + + + 49.072800 + 635783 + 635783 + 635783 + + + 62.484000 + 6373 + 6373 + 6373 + + + 3.962400 + 6634 + 6634 + 6634 + + + 13.411200 + 6979 + 6979 + 6979 + + + 34.012085 + 6997 + 6997 + 6997 + + + 87.782400 + BEAR HILL + BEAR HILL TOWER + BEAR HILL TOWER + + + 23.469600 + BELLEVUE + BELLEVUE + BELLEVUE + + + 43.384766 + 6016 + Bike Loop Connector + Bike Loop Connector + + + 89.916000 + 5236BRIDGE + Bridge + Bridge + + + 55.473600 + 5376BRIDGE + Bridge + Bridge + + + 52.730400 + 6181CROSS + Crossing + Crossing + + + 45.110400 + 6042CROSS + Crossing + Crossing + + + 0.000000 + DARKHOLLPO + Dark Hollow Pond + Dark Hollow Pond + + + 56.083200 + 6121DEAD + Dead End + Dead End + + + 117.043200 + 5179DEAD + Dead End + Dead End + + + 69.494400 + 5299DEAD + Dead End + Dead End + + + 56.997600 + 5376DEAD + Dead End + Dead End + + + 46.939200 + 6353DEAD + Dead End + Dead End + + + 61.264800 + 6155DEAD + Dead End + Dead End + + + 110.947200 + GATE14 + Gate 14 + Gate 14 + + + 77.724000 + GATE16 + Gate 16 + Gate 16 + + + 65.836800 + GATE17 + Gate 17 + Gate 17 + + + 57.302400 + GATE19 + Gate 19 + Gate 19 + + + 49.377600 + GATE21 + Gate 21 + Gate 21 + + + 81.076800 + GATE24 + Gate 24 + Gate 24 + + + 21.515015 + GATE5 + Gate 5 + Gate 5 + + + 26.561890 + GATE6 + Gate 6 + Gate 6 + + + 32.004000 + 6077LOGS + Log Crossing + Log Crossing + + + 119.809082 + 5148NANEPA + Nanepashemet Road Crossing + Nanepashemet Road Crossing + + + 73.761600 + 5267OBSTAC + Obstacle + Obstacle + + + 45.307495 + PANTHRCAVE + Panther Cave + Panther Cave + + + 77.992066 + 5252PURPLE + Purple Rock Hill + Purple Rock Hill + + + 67.970400 + 5287WATER + Reservoir + Reservoir + + + 81.076800 + 5239ROAD + Road + Road + + + 67.360800 + 5278ROAD + Road + Road + + + 53.949600 + 5058ROAD + ROAD CROSSING + ROAD CROSSING + + + 69.799200 + SHEEPFOLD + Sheepfold Parking Lot + Sheepfold Parking Lot + + + 64.008000 + SOAPBOX + Soap Box Derby Track + Soap Box Derby Track + + + 64.533692 + 5376STREAM + Stream Crossing + Stream Crossing + + + 61.649902 + 5144SUMMIT + Summit + Summit + + + 67.360800 + 5150TANK + WATER TANK + WATER TANK + + + + + 1.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 2.000000 + + + 0.000000 + + + 1.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 2.000000 + + + 1.000000 + + + 1.000000 + + + 0.000000 + + + 2.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 6.000000 + + + 2.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 1.000000 + + + 0.000000 + + + 0.000000 + + + 6.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 7.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + diff --git a/reference/track/fugawi.txt b/reference/track/fugawi.txt new file mode 100644 index 000000000..ba8237891 --- /dev/null +++ b/reference/track/fugawi.txt @@ -0,0 +1,74 @@ +# Latitude, Longitude and UTM coordinates are in WGS84 datum +# +# Every set of data contains the following: +# +# Waypoint name +# Waypoint comment +# Waypoint description +# Latitude in Degree and decimals (soutern hemisphere has neg. degrees) +# Longitude in degree and decimals (neg. numbers: west of Greenwich) +# Height in meters [optional when importing, always present when exporting: Date (GMT) as ISO YYYYMMDD, Time of the day relative to the date as HHMMSS +,,,30.0621833,-91.6103500,1.0 ,20020525,170621 +,,,30.0627833,-91.6105667,0.0 ,20020525,170955 +,,,30.0627000,-91.6082667,0.0 ,20020525,171200 +,,,30.0623333,-91.6073833,0.0 ,20020525,171248 +,,,30.0615333,-91.6052833,0.0 ,20020525,171441 +,,,30.0597833,-91.5994000,0.0 ,20020525,171716 +,,,30.0578000,-91.5966833,0.0 ,20020525,171746 +,,,30.0553833,-91.5949000,0.0 ,20020525,171820 +,,,30.0538833,-91.5926167,0.0 ,20020525,171901 +,,,30.0497333,-91.5897500,0.0 ,20020525,172046 +,,,30.0490167,-91.5898833,0.0 ,20020525,172110 +,,,30.0488000,-91.5929333,0.0 ,20020525,172151 +,,,30.0462333,-91.5964500,0.0 ,20020525,172235 +,,,30.0455167,-91.5987167,0.0 ,20020525,172308 +,,,30.0473000,-91.6002667,0.0 ,20020525,180423 +,,,30.0470000,-91.5996333,2.0 ,20020525,180604 +,,,30.0464333,-91.5994667,0.0 ,20020525,180706 +,,,30.0462000,-91.5989500,1.0 ,20020525,180818 +,,,30.0463667,-91.5977333,0.0 ,20020525,181020 +,,,30.0463500,-91.5971667,0.0 ,20020525,181109 +,,,30.0467833,-91.5963333,0.0 ,20020525,181218 +,,,30.0474500,-91.5952000,0.0 ,20020525,181422 +,,,30.0478000,-91.5947667,2.0 ,20020525,181504 +,,,30.0482500,-91.5940833,1.0 ,20020525,181614 +,,,30.0486833,-91.5938000,1.0 ,20020525,181701 +,,,30.0493500,-91.5938500,0.0 ,20020525,181807 +,,,30.0503167,-91.5939833,2.0 ,20020525,181951 +,,,30.0507833,-91.5941167,0.0 ,20020525,182039 +,,,30.0512333,-91.5943667,0.0 ,20020525,182124 +,,,30.0518000,-91.5943667,0.0 ,20020525,182217 +,,,30.0522167,-91.5946667,0.0 ,20020525,182318 +,,,30.0530167,-91.5946833,0.0 ,20020525,182437 +,,,30.0548667,-91.5952000,6.0 ,20020525,182813 +,,,30.0537333,-91.5949333,2.0 ,20020525,183136 +,,,30.0531833,-91.5947833,0.0 ,20020525,183256 +,,,30.0526333,-91.5948333,0.0 ,20020525,183402 +,,,30.0524500,-91.5954333,0.0 ,20020525,183603 +,,,30.0524833,-91.5959667,0.0 ,20020525,183648 +,,,30.0526500,-91.5967833,1.0 ,20020525,183752 +,,,30.0531333,-91.5978500,0.0 ,20020525,183918 +,,,30.0536167,-91.5979667,0.0 ,20020525,184015 +,,,30.0539667,-91.5977667,6.0 ,20020525,184125 +,,,30.0536167,-91.5980833,0.0 ,20020525,184237 +,,,30.0532000,-91.5979167,0.0 ,20020525,184401 +,,,30.0528167,-91.5975167,0.0 ,20020525,184553 +,,,30.0525667,-91.5969333,0.0 ,20020525,184654 +,,,30.0523333,-91.5964333,0.0 ,20020525,184742 +,,,30.0522500,-91.5956833,0.0 ,20020525,184841 +,,,30.0522167,-91.5950167,0.0 ,20020525,184952 +,,,30.0518833,-91.5947000,0.0 ,20020525,185049 +,,,30.0510500,-91.5944000,0.0 ,20020525,185214 +,,,30.0505667,-91.5942333,0.0 ,20020525,185256 +,,,30.0501833,-91.5941000,0.0 ,20020525,185338 +,,,30.0491000,-91.5937167,0.0 ,20020525,185511 +,,,30.0484500,-91.5942500,0.0 ,20020525,185632 +,,,30.0480833,-91.5947500,0.0 ,20020525,185724 +,,,30.0475000,-91.5954500,7.0 ,20020525,185840 +,,,30.0470667,-91.5960000,0.0 ,20020525,185928 +,,,30.0466333,-91.5966000,0.0 ,20020525,190022 +,,,30.0464000,-91.5976500,0.0 ,20020525,190141 +,,,30.0462333,-91.5984667,0.0 ,20020525,190248 +,,,30.0463167,-91.5989667,0.0 ,20020525,190343 +,,,30.0467833,-91.5992833,0.0 ,20020525,190449 +,,,30.0471333,-91.5996667,0.0 ,20020525,190557 diff --git a/reference/track/garmin_logbook.xml b/reference/track/garmin_logbook.xml new file mode 100644 index 000000000..edab29b04 --- /dev/null +++ b/reference/track/garmin_logbook.xml @@ -0,0 +1,2047 @@ + + + + + + 2004-12-21T15:14:32Z + PT1259.400S + + 43.60257 + 3.85169 + + + 43.56778 + 3.83445 + + 6067.921 + 331 + + + 2004-12-21T15:35:31Z + PT3352.850S + + 43.56778 + 3.83445 + + 110755.828 + 793 + + + 2004-12-21T16:31:24Z + PT1680.720S + + 42.93887 + 2.97314 + + + 42.77292 + 2.98848 + + 28240.844 + 411 + + + + + 43.60261 + 3.85165 + 46.761 + + + + + + 43.60171 + 3.85249 + 41.955 + + + + + + 43.60115 + 3.85067 + 42.435 + + + + + + 43.60098 + 3.84931 + 41.955 + + + + + + 43.60017 + 3.84794 + 40.513 + + + + + + 43.59924 + 3.84674 + 40.032 + + + + + + 43.59665 + 3.84908 + 42.435 + + + + + + 43.59448 + 3.85026 + 45.319 + + + + + + 43.59289 + 3.85227 + 46.281 + + + + + + 43.59231 + 3.85257 + 45.800 + + + + + + 43.59308 + 3.85234 + 45.800 + + + + + + 43.59238 + 3.85292 + 44.358 + + + + + + 43.59055 + 3.85509 + 47.242 + + + + + + 43.58967 + 3.85592 + 45.800 + + + + + + 43.58948 + 3.85594 + 44.839 + + + + + + 43.58851 + 3.85500 + 44.839 + + + + + + 43.58736 + 3.85350 + 53.010 + + + + + + 43.58530 + 3.85142 + 50.607 + + + + + + 43.58416 + 3.84865 + 34.264 + + + + + + 43.58414 + 3.84794 + 28.977 + + + + + + 43.58394 + 3.84768 + 24.170 + + + + + + 43.58371 + 3.84762 + 26.093 + + + + + + 43.58321 + 3.84800 + 25.612 + + + + + + 43.58186 + 3.84794 + 27.535 + + + + + + 43.57394 + 3.84884 + 25.132 + + + + + + 43.57326 + 3.84882 + 25.132 + + + + + + 43.57382 + 3.84809 + 25.132 + + + + + + 43.57377 + 3.84792 + 25.612 + + + + + + 43.57317 + 3.84813 + 25.132 + + + + + + 43.57309 + 3.84841 + 29.458 + + + + + + 43.57264 + 3.84891 + 29.458 + + + + + + 43.57206 + 3.84891 + 28.016 + + + + + + 43.57152 + 3.84770 + 27.535 + + + + + + 43.57154 + 3.84734 + 25.612 + + + + + + 43.57163 + 3.84742 + 28.977 + + + + + + 43.57111 + 3.84642 + 21.767 + + + + + + 43.57034 + 3.84579 + 16.480 + + + + + + 43.56997 + 3.84519 + 16.480 + + + + + + 43.57049 + 3.84346 + 17.922 + + + + + + 43.56961 + 3.84262 + 19.844 + + + + + + 43.56942 + 3.84195 + 20.325 + + + + + + 43.56980 + 3.83914 + 26.093 + + + + + + 43.56997 + 3.83865 + 26.093 + + + + + + 43.57058 + 3.83865 + 26.093 + + + + + + 43.57032 + 3.83749 + 26.574 + + + + + + 43.56995 + 3.83715 + 28.977 + + + + + + 43.56927 + 3.83745 + 28.977 + + + + + + 43.56856 + 3.83524 + 23.209 + + + + + + 43.56830 + 3.83485 + 24.170 + + + + + + 43.56764 + 3.83434 + 30.900 + + + + + + 43.56704 + 3.83395 + 30.419 + + + + + + 43.56463 + 3.83384 + 31.861 + + + + + + 43.56418 + 3.83350 + 31.861 + + + + + + 43.56334 + 3.83107 + 32.822 + + + + + + 43.56216 + 3.82916 + 34.264 + + + + + + 43.55633 + 3.82350 + 26.093 + + + + + + 43.55476 + 3.82174 + 24.651 + + + + + + 43.55322 + 3.81912 + 21.286 + + + + + + 43.55251 + 3.81751 + 18.883 + + + + + + 43.55148 + 3.81410 + 19.364 + + + + + + 43.55075 + 3.80917 + 25.612 + + + + + + 43.55023 + 3.80236 + 28.496 + + + + + + 43.54946 + 3.79996 + 32.342 + + + + + + 43.54871 + 3.79827 + 35.706 + + + + + + 43.54633 + 3.79391 + 37.148 + + + + + + 43.54367 + 3.79082 + 37.148 + + + + + + 43.53822 + 3.78282 + 37.148 + + + + + + 43.53695 + 3.78153 + 37.148 + + + + + + 43.53453 + 3.77975 + 42.916 + + + + + + 43.53272 + 3.77747 + 42.916 + + + + + + 43.52672 + 3.76750 + 50.126 + + + + + + 43.52472 + 3.76380 + 50.607 + + + + + + 43.51985 + 3.75400 + 53.490 + + + + + + 43.51815 + 3.75114 + 59.258 + + + + + + 43.51556 + 3.74814 + 61.181 + + + + + + 43.50736 + 3.74052 + 61.181 + + + + + + 43.50474 + 3.73413 + 61.181 + + + + + + 43.50200 + 3.72932 + 66.949 + + + + + + 43.50067 + 3.72735 + 71.275 + + + + + + 43.49738 + 3.72321 + 72.717 + + + + + + 43.49090 + 3.71621 + 70.313 + + + + + + 43.48979 + 3.71441 + 65.988 + + + + + + 43.48841 + 3.71156 + 57.336 + + + + + + 43.48756 + 3.70950 + 50.607 + + + + + + 43.48689 + 3.70726 + 49.165 + + + + + + 43.48616 + 3.70400 + 48.203 + + + + + + 43.48475 + 3.69561 + 46.761 + + + + + + 43.48417 + 3.69325 + 47.242 + + + + + + 43.48080 + 3.68186 + 47.242 + + + + + + 43.47975 + 3.66527 + 48.203 + + + + + + 43.47944 + 3.66259 + 31.380 + + + + + + 43.47910 + 3.66038 + 35.225 + + + + + + 43.47839 + 3.65746 + 39.551 + + + + + + 43.47726 + 3.65413 + 43.877 + + + + + + 43.47537 + 3.64950 + 44.839 + + + + + + 43.47277 + 3.64463 + 49.645 + + + + + + 43.46530 + 3.63289 + 63.104 + + + + + + 43.46230 + 3.62718 + 63.104 + + + + + + 43.46181 + 3.62347 + 62.623 + + + + + + 43.46043 + 3.61755 + 53.010 + + + + + + 43.45876 + 3.61268 + 50.607 + + + + + + 43.45640 + 3.60789 + 49.165 + + + + + + 43.45451 + 3.60482 + 47.242 + + + + + + 43.45346 + 3.60264 + 40.032 + + + + + + 43.45209 + 3.59925 + 37.629 + + + + + + 43.45050 + 3.59412 + 37.629 + + + + + + 43.44996 + 3.58350 + 37.148 + + + + + + 43.44827 + 3.57886 + 34.745 + + + + + + 43.44672 + 3.57626 + 34.745 + + + + + + 43.44415 + 3.57403 + 33.303 + + + + + + 43.43353 + 3.56414 + 30.419 + + + + + + 43.43035 + 3.56191 + 22.248 + + + + + + 43.42372 + 3.54925 + 22.248 + + + + + + 43.42018 + 3.53071 + 31.861 + + + + + + 43.41915 + 3.52646 + 33.303 + + + + + + 43.40803 + 3.49606 + 33.303 + + + + + + 43.40181 + 3.47760 + 33.303 + + + + + + 43.39314 + 3.46365 + 18.883 + + + + + + 43.38902 + 3.45773 + 15.999 + + + + + + 43.38647 + 3.45436 + 15.518 + + + + + + 43.38198 + 3.44893 + 15.038 + + + + + + 43.38113 + 3.44769 + 15.038 + + + + + + 43.37317 + 3.40121 + 15.038 + + + + + + 43.36544 + 3.38523 + 14.557 + + + + + + 43.36435 + 3.38188 + 15.518 + + + + + + 43.36276 + 3.37540 + 23.209 + + + + + + 43.36209 + 3.36909 + 28.977 + + + + + + 43.36207 + 3.35684 + 46.281 + + + + + + 43.36177 + 3.35135 + 55.894 + + + + + + 43.36089 + 3.34677 + 53.971 + + + + + + 43.35902 + 3.34190 + 50.607 + + + + + + 43.35742 + 3.34025 + 43.877 + + + + + + 43.35430 + 3.33620 + 39.551 + + + + + + 43.34954 + 3.33085 + 36.667 + + + + + + 43.34819 + 3.32892 + 37.629 + + + + + + 43.34546 + 3.32437 + 38.109 + + + + + + 43.32637 + 3.27375 + 30.419 + + + + + + 43.31830 + 3.26253 + 15.038 + + + + + + 43.29984 + 3.20734 + 38.590 + + + + + + 43.29744 + 3.20161 + 46.281 + + + + + + 43.29433 + 3.19700 + 44.358 + + + + + + 43.29130 + 3.19318 + 44.358 + + + + + + 43.28092 + 3.18558 + 43.397 + + + + + + 43.26734 + 3.17717 + 44.358 + + + + + + 43.26380 + 3.17322 + 42.916 + + + + + + 43.26178 + 3.17056 + 43.397 + + + + + + 43.25622 + 3.16250 + 40.513 + + + + + + 43.25266 + 3.15799 + 40.513 + + + + + + 43.25171 + 3.15696 + 40.032 + + + + + + 43.24925 + 3.15496 + 34.745 + + + + + + 43.24002 + 3.14497 + 23.209 + + + + + + 43.23712 + 3.14123 + 23.690 + + + + + + 43.23169 + 3.13205 + 22.728 + + + + + + 43.22685 + 3.10171 + 21.286 + + + + + + 43.22324 + 3.09548 + 70.313 + + + + + + 43.22127 + 3.09441 + 49.165 + + + + + + 43.19736 + 3.07525 + 47.723 + + + + + + 43.19301 + 3.07016 + 45.319 + + + + + + 43.18998 + 3.06609 + 40.993 + + + + + + 43.18571 + 3.05911 + 41.474 + + + + + + 43.18509 + 3.05551 + 18.402 + + + + + + 43.18056 + 3.04332 + 4.463 + + + + + + 43.16492 + 2.99695 + 4.463 + + + + + + 43.16271 + 2.99287 + 6.386 + + + + + + 43.16204 + 2.99195 + 7.347 + + + + + + 43.15953 + 2.98867 + 7.347 + + + + + + 43.14003 + 2.97736 + 7.347 + + + + + + 43.13777 + 2.97526 + -2.266 + + + + + + 43.12911 + 2.96367 + 34.264 + + + + + + 43.12608 + 2.96036 + 40.032 + + + + + + 43.12299 + 2.95863 + 40.513 + + + + + + 43.11838 + 2.95702 + 40.513 + + + + + + 43.11505 + 2.95444 + 39.551 + + + + + + 43.11168 + 2.95152 + 39.551 + + + + + + 43.10997 + 2.95062 + 38.109 + + + + + + 43.10602 + 2.94745 + 38.109 + + + + + + 43.10276 + 2.94414 + 38.109 + + + + + + 43.09990 + 2.94161 + 38.109 + + + + + + 43.08029 + 2.93590 + 28.977 + + + + + + 43.06995 + 2.93676 + 35.706 + + + + + + 43.06196 + 2.93560 + 36.187 + + + + + + 43.06102 + 2.93595 + 36.667 + + + + + + 43.04527 + 2.94380 + 20.806 + + + + + + 43.00096 + 2.96461 + 40.993 + + + + + + 42.99924 + 2.96599 + 38.590 + + + + + + 42.97712 + 2.97403 + 41.474 + + + + + + 42.97555 + 2.97328 + 41.474 + + + + + + 42.97186 + 2.97062 + 40.993 + + + + + + 42.96901 + 2.96903 + 40.032 + + + + + + 42.96622 + 2.96794 + 39.551 + + + + + + 42.96234 + 2.96676 + 39.551 + + + + + + 42.95998 + 2.96923 + 39.551 + + + + + + 42.95626 + 2.97000 + 39.551 + + + + + + 42.94131 + 2.96985 + 44.358 + + + + + + 42.93809 + 2.96609 + 57.817 + + + + + + 42.93875 + 2.97498 + 30.419 + + + + + + 42.93828 + 2.98187 + 30.900 + + + + + + 42.93794 + 2.98414 + 29.458 + + + + + + 42.93612 + 2.99272 + 22.728 + + + + + + 42.93455 + 2.99957 + 15.038 + + + + + + 42.92891 + 3.02045 + 14.076 + + + + + + 42.92472 + 3.01991 + 14.076 + + + + + + 42.92150 + 3.01712 + 15.999 + + + + + + 42.91897 + 3.01749 + 15.999 + + + + + + 42.91798 + 3.02042 + 17.922 + + + + + + 42.91545 + 3.02259 + 17.922 + + + + + + 42.90590 + 3.04057 + 13.596 + + + + + + 42.90530 + 3.04529 + 11.673 + + + + + + 42.90135 + 3.05411 + 10.231 + + + + + + 42.88610 + 3.04768 + 11.673 + + + + + + 42.87893 + 3.04165 + 3.021 + + + + + + 42.86676 + 3.03083 + 3.021 + + + + + + 42.86548 + 3.03012 + 1.099 + + + + + + 42.86294 + 3.02922 + 0.137 + + + + + + 42.86058 + 3.02935 + 3.983 + + + + + + 42.85408 + 3.03195 + 4.944 + + + + + + 42.85337 + 3.03429 + 7.347 + + + + + + 42.84526 + 3.03972 + 8.789 + + + + + + 42.84239 + 3.04023 + 8.789 + + + + + + 42.83900 + 3.03999 + 8.789 + + + + + + 42.83741 + 3.03879 + 8.789 + + + + + + 42.82801 + 3.03439 + 8.789 + + + + + + 42.81561 + 3.02817 + 8.789 + + + + + + 42.81005 + 3.03096 + 8.789 + + + + + + 42.80838 + 3.03109 + 8.789 + + + + + + 42.78855 + 3.02161 + 8.309 + + + + + + 42.78771 + 3.01961 + 1.579 + + + + + + 42.78821 + 3.01688 + 0.618 + + + + + + 42.78821 + 3.01609 + 1.099 + + + + + + 42.78786 + 3.01482 + 1.579 + + + + + + 42.78728 + 3.01467 + 3.021 + + + + + + 42.78664 + 3.01431 + 3.502 + + + + + + 42.78520 + 3.01422 + 3.983 + + + + + + 42.78398 + 3.01440 + 2.541 + + + + + + 42.77808 + 3.01573 + 6.386 + + + + + + 42.77439 + 3.01639 + 6.386 + + + + + + 42.77390 + 3.01313 + 2.541 + + + + + + 42.77329 + 3.01070 + 2.541 + + + + + + 42.77329 + 3.00997 + 3.021 + + + + + + 42.77235 + 3.00796 + 4.463 + + + + + + 42.77207 + 3.00540 + 6.866 + + + + + + 42.77226 + 3.00371 + 8.309 + + + + + + 42.77413 + 2.99418 + 3.983 + + + + + + 42.77450 + 2.99109 + 3.502 + + + + + + 42.77302 + 2.98779 + 1.099 + + + + + + 42.77239 + 2.98753 + 2.060 + + + + + + 42.77244 + 2.98781 + 2.060 + + + + + + 42.77256 + 2.98809 + 3.502 + + + + + + 42.77347 + 2.98852 + 3.983 + + + + + + 42.77312 + 2.98854 + -1.785 + + + + + + + diff --git a/reference/track/ggv_log-sample.log b/reference/track/ggv_log-sample.log new file mode 100644 index 0000000000000000000000000000000000000000..9cbcba37e209082f7139ac8d7de8048f52569a53 GIT binary patch literal 31397 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 literal 0 HcmV?d00001 diff --git a/reference/track/i65.anr b/reference/track/i65.anr new file mode 100755 index 0000000000000000000000000000000000000000..fe28b9fb00109bc4b4f5d328be33b2788728201f GIT binary patch literal 14732 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 W^yI#^Su>RHy>V_)X)07&7XA;Asx}({ literal 0 HcmV?d00001 diff --git a/reference/track/i65.anr.gpx b/reference/track/i65.anr.gpx new file mode 100644 index 000000000..f6788b614 --- /dev/null +++ b/reference/track/i65.anr.gpx @@ -0,0 +1,4971 @@ + + + + + Home to 8520 Northwe + + Local Road + + + \00000 + + + \00001 + + + \00002 + + + \00003 + + + \00004 + + + I-65 N + + + \00005 + + + \00006 + + + \00007 + + + \00008 + + + \00009 + + + \0000a + + + \0000b + + + \0000c + + + \0000d + + + \0000e + + + \0000f + + + \00010 + + + \00011 + + + \00012 + + + \00013 + + + \00014 + + + \00015 + + + \00016 + + + \00017 + + + \00018 + + + \00019 + + + \0001a + + + \0001b + + + \0001c + + + \0001d + + + \0001e + + + \0001f + + + \00020 + + + \00021 + + + \00022 + + + \00023 + + + \00024 + + + \00025 + + + \00026 + + + \00027 + + + \00028 + + + \00029 + + + \0002a + + + \0002b + + + \0002c + + + \0002d + + + \0002e + + + \0002f + + + \00030 + + + \00031 + + + \00032 + + + \00033 + + + \00034 + + + \00035 + + + \00036 + + + \00037 + + + \00038 + + + \00039 + + + \0003a + + + \0003b + + + \0003c + + + \0003d + + + \0003e + + + \0003f + + + \00040 + + + \00041 + + + \00042 + + + \00043 + + + \00044 + + + \00045 + + + \00046 + + + \00047 + + + \00048 + + + \00049 + + + \0004a + + + \0004b + + + \0004c + + + \0004d + + + \0004e + + + \0004f + + + \00050 + + + \00051 + + + \00052 + + + \00053 + + + \00054 + + + \00055 + + + \00056 + + + \00057 + + + \00058 + + + \00059 + + + \0005a + + + \0005b + + + \0005c + + + \0005d + + + \0005e + + + \0005f + + + \00060 + + + \00061 + + + \00062 + + + \00063 + + + \00064 + + + \00065 + + + \00066 + + + \00067 + + + \00068 + + + \00069 + + + \0006a + + + \0006b + + + I-40 E (I-65 N) Ramp + + + \0006c + + + \0006d + + + \0006e + + + I-40 E (I-65 N) + + + \0006f + + + \00070 + + + \00071 + + + \00072 + + + \00073 + + + \00074 + + + \00075 + + + \00076 + + + \00077 + + + \00078 + + + I-24 W (I-65 N) Ramp + + + \00079 + + + \0007a + + + \0007b + + + \0007c + + + \0007d + + + I-24 W (I-65 N) + + + \0007e + + + \0007f + + + \00080 + + + \00081 + + + \00082 + + + \00083 + + + \00084 + + + \00085 + + + \00086 + + + \00087 + + + \00088 + + + \00089 + + + \0008a + + + \0008b + + + \0008c + + + \0008d + + + \0008e + + + \0008f + + + \00090 + + + \00091 + + + \00092 + + + \00093 + + + \00094 + + + \00095 + + + \00096 + + + \00097 + + + \00098 + + + \00099 + + + \0009a + + + \0009b + + + \0009c + + + \0009d + + + \0009e + + + \0009f + + + \000a0 + + + \000a1 + + + \000a2 + + + \000a3 + + + \000a4 + + + \000a5 + + + \000a6 + + + I-65 N + + + \000a7 + + + \000a8 + + + \000a9 + + + \000aa + + + \000ab + + + \000ac + + + \000ad + + + \000ae + + + \000af + + + \000b0 + + + \000b1 + + + \000b2 + + + \000b3 + + + \000b4 + + + \000b5 + + + \000b6 + + + \000b7 + + + \000b8 + + + \000b9 + + + \000ba + + + \000bb + + + \000bc + + + \000bd + + + \000be + + + \000bf + + + \000c0 + + + \000c1 + + + \000c2 + + + \000c3 + + + \000c4 + + + \000c5 + + + \000c6 + + + \000c7 + + + \000c8 + + + \000c9 + + + \000ca + + + \000cb + + + \000cc + + + \000cd + + + \000ce + + + \000cf + + + \000d0 + + + \000d1 + + + \000d2 + + + \000d3 + + + \000d4 + + + \000d5 + + + \000d6 + + + \000d7 + + + \000d8 + + + \000d9 + + + \000da + + + \000db + + + \000dc + + + \000dd + + + \000de + + + \000df + + + \000e0 + + + \000e1 + + + \000e2 + + + \000e3 + + + \000e4 + + + \000e5 + + + \000e6 + + + \000e7 + + + \000e8 + + + \000e9 + + + \000ea + + + \000eb + + + \000ec + + + \000ed + + + \000ee + + + \000ef + + + \000f0 + + + \000f1 + + + \000f2 + + + \000f3 + + + \000f4 + + + \000f5 + + + \000f6 + + + \000f7 + + + \000f8 + + + \000f9 + + + \000fa + + + \000fb + + + \000fc + + + \000fd + + + \000fe + + + \000ff + + + \00100 + + + \00101 + + + \00102 + + + \00103 + + + \00104 + + + \00105 + + + \00106 + + + \00107 + + + \00108 + + + \00109 + + + \0010a + + + \0010b + + + \0010c + + + \0010d + + + \0010e + + + \0010f + + + \00110 + + + \00111 + + + \00112 + + + \00113 + + + \00114 + + + \00115 + + + \00116 + + + \00117 + + + \00118 + + + \00119 + + + \0011a + + + \0011b + + + \0011c + + + \0011d + + + \0011e + + + \0011f + + + \00120 + + + \00121 + + + \00122 + + + \00123 + + + \00124 + + + \00125 + + + \00126 + + + \00127 + + + \00128 + + + \00129 + + + \0012a + + + \0012b + + + \0012c + + + \0012d + + + \0012e + + + \0012f + + + \00130 + + + \00131 + + + \00132 + + + \00133 + + + \00134 + + + \00135 + + + \00136 + + + \00137 + + + \00138 + + + \00139 + + + \0013a + + + \0013b + + + \0013c + + + \0013d + + + \0013e + + + \0013f + + + \00140 + + + \00141 + + + \00142 + + + \00143 + + + \00144 + + + \00145 + + + \00146 + + + \00147 + + + \00148 + + + \00149 + + + \0014a + + + \0014b + + + \0014c + + + \0014d + + + \0014e + + + \0014f + + + \00150 + + + \00151 + + + \00152 + + + \00153 + + + \00154 + + + \00155 + + + \00156 + + + \00157 + + + \00158 + + + \00159 + + + \0015a + + + \0015b + + + \0015c + + + \0015d + + + \0015e + + + \0015f + + + \00160 + + + \00161 + + + \00162 + + + \00163 + + + \00164 + + + \00165 + + + \00166 + + + \00167 + + + \00168 + + + \00169 + + + \0016a + + + \0016b + + + \0016c + + + \0016d + + + \0016e + + + \0016f + + + \00170 + + + \00171 + + + \00172 + + + \00173 + + + \00174 + + + \00175 + + + \00176 + + + \00177 + + + \00178 + + + \00179 + + + \0017a + + + \0017b + + + \0017c + + + \0017d + + + \0017e + + + \0017f + + + \00180 + + + \00181 + + + \00182 + + + \00183 + + + \00184 + + + \00185 + + + \00186 + + + \00187 + + + \00188 + + + \00189 + + + \0018a + + + \0018b + + + \0018c + + + \0018d + + + \0018e + + + \0018f + + + \00190 + + + \00191 + + + \00192 + + + \00193 + + + \00194 + + + \00195 + + + \00196 + + + \00197 + + + \00198 + + + \00199 + + + \0019a + + + \0019b + + + \0019c + + + \0019d + + + \0019e + + + \0019f + + + \001a0 + + + \001a1 + + + \001a2 + + + \001a3 + + + \001a4 + + + \001a5 + + + \001a6 + + + \001a7 + + + \001a8 + + + \001a9 + + + \001aa + + + \001ab + + + \001ac + + + \001ad + + + \001ae + + + \001af + + + \001b0 + + + \001b1 + + + \001b2 + + + \001b3 + + + \001b4 + + + \001b5 + + + \001b6 + + + \001b7 + + + \001b8 + + + \001b9 + + + \001ba + + + \001bb + + + \001bc + + + \001bd + + + \001be + + + \001bf + + + \001c0 + + + \001c1 + + + \001c2 + + + \001c3 + + + \001c4 + + + \001c5 + + + \001c6 + + + \001c7 + + + \001c8 + + + \001c9 + + + \001ca + + + \001cb + + + \001cc + + + \001cd + + + \001ce + + + \001cf + + + \001d0 + + + \001d1 + + + \001d2 + + + \001d3 + + + \001d4 + + + \001d5 + + + \001d6 + + + \001d7 + + + \001d8 + + + \001d9 + + + \001da + + + \001db + + + \001dc + + + \001dd + + + \001de + + + \001df + + + \001e0 + + + \001e1 + + + \001e2 + + + \001e3 + + + \001e4 + + + \001e5 + + + \001e6 + + + \001e7 + + + \001e8 + + + \001e9 + + + \001ea + + + \001eb + + + \001ec + + + \001ed + + + \001ee + + + \001ef + + + \001f0 + + + \001f1 + + + \001f2 + + + \001f3 + + + \001f4 + + + \001f5 + + + \001f6 + + + \001f7 + + + \001f8 + + + \001f9 + + + \001fa + + + \001fb + + + \001fc + + + \001fd + + + \001fe + + + \001ff + + + \00200 + + + \00201 + + + \00202 + + + \00203 + + + \00204 + + + \00205 + + + \00206 + + + \00207 + + + \00208 + + + \00209 + + + \0020a + + + \0020b + + + \0020c + + + \0020d + + + \0020e + + + \0020f + + + \00210 + + + \00211 + + + \00212 + + + \00213 + + + \00214 + + + \00215 + + + \00216 + + + \00217 + + + \00218 + + + \00219 + + + \0021a + + + \0021b + + + \0021c + + + \0021d + + + \0021e + + + \0021f + + + \00220 + + + \00221 + + + \00222 + + + \00223 + + + \00224 + + + \00225 + + + \00226 + + + \00227 + + + \00228 + + + \00229 + + + \0022a + + + \0022b + + + \0022c + + + \0022d + + + \0022e + + + \0022f + + + \00230 + + + \00231 + + + \00232 + + + \00233 + + + \00234 + + + \00235 + + + \00236 + + + \00237 + + + \00238 + + + \00239 + + + \0023a + + + \0023b + + + \0023c + + + \0023d + + + \0023e + + + \0023f + + + \00240 + + + \00241 + + + \00242 + + + \00243 + + + \00244 + + + \00245 + + + \00246 + + + \00247 + + + \00248 + + + \00249 + + + \0024a + + + \0024b + + + \0024c + + + \0024d + + + \0024e + + + \0024f + + + \00250 + + + \00251 + + + \00252 + + + \00253 + + + \00254 + + + \00255 + + + \00256 + + + \00257 + + + \00258 + + + \00259 + + + \0025a + + + \0025b + + + \0025c + + + \0025d + + + \0025e + + + \0025f + + + \00260 + + + \00261 + + + \00262 + + + \00263 + + + \00264 + + + \00265 + + + \00266 + + + \00267 + + + \00268 + + + \00269 + + + \0026a + + + \0026b + + + \0026c + + + \0026d + + + \0026e + + + \0026f + + + \00270 + + + \00271 + + + \00272 + + + \00273 + + + \00274 + + + \00275 + + + \00276 + + + \00277 + + + \00278 + + + \00279 + + + \0027a + + + \0027b + + + \0027c + + + \0027d + + + \0027e + + + \0027f + + + \00280 + + + \00281 + + + \00282 + + + \00283 + + + \00284 + + + \00285 + + + \00286 + + + \00287 + + + \00288 + + + \00289 + + + \0028a + + + \0028b + + + \0028c + + + \0028d + + + \0028e + + + \0028f + + + \00290 + + + \00291 + + + \00292 + + + \00293 + + + \00294 + + + \00295 + + + \00296 + + + \00297 + + + \00298 + + + \00299 + + + \0029a + + + \0029b + + + \0029c + + + \0029d + + + \0029e + + + \0029f + + + \002a0 + + + \002a1 + + + \002a2 + + + \002a3 + + + \002a4 + + + \002a5 + + + \002a6 + + + \002a7 + + + \002a8 + + + \002a9 + + + \002aa + + + \002ab + + + \002ac + + + \002ad + + + \002ae + + + \002af + + + \002b0 + + + \002b1 + + + \002b2 + + + \002b3 + + + \002b4 + + + \002b5 + + + \002b6 + + + \002b7 + + + \002b8 + + + \002b9 + + + \002ba + + + \002bb + + + \002bc + + + \002bd + + + \002be + + + \002bf + + + \002c0 + + + \002c1 + + + \002c2 + + + \002c3 + + + \002c4 + + + \002c5 + + + \002c6 + + + \002c7 + + + \002c8 + + + \002c9 + + + \002ca + + + \002cb + + + \002cc + + + \002cd + + + \002ce + + + \002cf + + + \002d0 + + + \002d1 + + + \002d2 + + + \002d3 + + + \002d4 + + + \002d5 + + + \002d6 + + + \002d7 + + + \002d8 + + + \002d9 + + + \002da + + + \002db + + + \002dc + + + \002dd + + + \002de + + + \002df + + + \002e0 + + + \002e1 + + + \002e2 + + + \002e3 + + + \002e4 + + + \002e5 + + + \002e6 + + + \002e7 + + + \002e8 + + + \002e9 + + + \002ea + + + \002eb + + + \002ec + + + \002ed + + + \002ee + + + \002ef + + + \002f0 + + + \002f1 + + + \002f2 + + + \002f3 + + + \002f4 + + + \002f5 + + + \002f6 + + + \002f7 + + + \002f8 + + + \002f9 + + + \002fa + + + \002fb + + + \002fc + + + \002fd + + + \002fe + + + \002ff + + + \00300 + + + \00301 + + + \00302 + + + \00303 + + + \00304 + + + \00305 + + + \00306 + + + \00307 + + + \00308 + + + \00309 + + + \0030a + + + \0030b + + + \0030c + + + \0030d + + + \0030e + + + \0030f + + + \00310 + + + \00311 + + + \00312 + + + \00313 + + + \00314 + + + \00315 + + + \00316 + + + \00317 + + + \00318 + + + \00319 + + + \0031a + + + \0031b + + + \0031c + + + \0031d + + + \0031e + + + \0031f + + + \00320 + + + \00321 + + + \00322 + + + \00323 + + + \00324 + + + \00325 + + + \00326 + + + \00327 + + + \00328 + + + \00329 + + + \0032a + + + \0032b + + + \0032c + + + \0032d + + + \0032e + + + \0032f + + + \00330 + + + \00331 + + + \00332 + + + \00333 + + + \00334 + + + \00335 + + + \00336 + + + \00337 + + + \00338 + + + \00339 + + + \0033a + + + \0033b + + + \0033c + + + \0033d + + + \0033e + + + \0033f + + + \00340 + + + \00341 + + + \00342 + + + \00343 + + + \00344 + + + \00345 + + + \00346 + + + \00347 + + + \00348 + + + \00349 + + + \0034a + + + \0034b + + + \0034c + + + \0034d + + + \0034e + + + \0034f + + + \00350 + + + \00351 + + + \00352 + + + \00353 + + + \00354 + + + \00355 + + + \00356 + + + \00357 + + + \00358 + + + \00359 + + + \0035a + + + \0035b + + + \0035c + + + \0035d + + + \0035e + + + \0035f + + + \00360 + + + \00361 + + + \00362 + + + \00363 + + + \00364 + + + \00365 + + + \00366 + + + \00367 + + + \00368 + + + \00369 + + + \0036a + + + \0036b + + + \0036c + + + \0036d + + + \0036e + + + \0036f + + + \00370 + + + \00371 + + + \00372 + + + \00373 + + + \00374 + + + \00375 + + + \00376 + + + \00377 + + + \00378 + + + \00379 + + + \0037a + + + \0037b + + + \0037c + + + \0037d + + + \0037e + + + \0037f + + + \00380 + + + \00381 + + + \00382 + + + \00383 + + + \00384 + + + \00385 + + + \00386 + + + \00387 + + + \00388 + + + \00389 + + + \0038a + + + \0038b + + + \0038c + + + \0038d + + + \0038e + + + \0038f + + + \00390 + + + \00391 + + + \00392 + + + \00393 + + + \00394 + + + \00395 + + + \00396 + + + \00397 + + + \00398 + + + \00399 + + + \0039a + + + \0039b + + + \0039c + + + \0039d + + + \0039e + + + \0039f + + + \003a0 + + + \003a1 + + + \003a2 + + + \003a3 + + + \003a4 + + + \003a5 + + + \003a6 + + + \003a7 + + + \003a8 + + + \003a9 + + + \003aa + + + \003ab + + + \003ac + + + \003ad + + + \003ae + + + \003af + + + \003b0 + + + \003b1 + + + \003b2 + + + \003b3 + + + \003b4 + + + \003b5 + + + \003b6 + + + \003b7 + + + \003b8 + + + \003b9 + + + \003ba + + + \003bb + + + \003bc + + + \003bd + + + \003be + + + \003bf + + + \003c0 + + + \003c1 + + + \003c2 + + + \003c3 + + + \003c4 + + + \003c5 + + + \003c6 + + + \003c7 + + + \003c8 + + + \003c9 + + + \003ca + + + \003cb + + + \003cc + + + \003cd + + + \003ce + + + \003cf + + + \003d0 + + + \003d1 + + + \003d2 + + + \003d3 + + + \003d4 + + + \003d5 + + + \003d6 + + + \003d7 + + + \003d8 + + + \003d9 + + + \003da + + + \003db + + + \003dc + + + \003dd + + + \003de + + + \003df + + + \003e0 + + + \003e1 + + + \003e2 + + + \003e3 + + + \003e4 + + + \003e5 + + + \003e6 + + + \003e7 + + + \003e8 + + + \003e9 + + + \003ea + + + \003eb + + + \003ec + + + \003ed + + + \003ee + + + \003ef + + + \003f0 + + + \003f1 + + + \003f2 + + + \003f3 + + + \003f4 + + + \003f5 + + + \003f6 + + + \003f7 + + + \003f8 + + + \003f9 + + + \003fa + + + \003fb + + + \003fc + + + \003fd + + + \003fe + + + \003ff + + + \00400 + + + \00401 + + + \00402 + + + \00403 + + + \00404 + + + \00405 + + + \00406 + + + \00407 + + + \00408 + + + \00409 + + + \0040a + + + \0040b + + + \0040c + + + \0040d + + + \0040e + + + \0040f + + + \00410 + + + \00411 + + + \00412 + + + \00413 + + + \00414 + + + \00415 + + + \00416 + + + \00417 + + + \00418 + + + \00419 + + + \0041a + + + \0041b + + + \0041c + + + \0041d + + + \0041e + + + \0041f + + + \00420 + + + \00421 + + + \00422 + + + \00423 + + + \00424 + + + \00425 + + + \00426 + + + \00427 + + + \00428 + + + \00429 + + + \0042a + + + \0042b + + + \0042c + + + \0042d + + + \0042e + + + \0042f + + + \00430 + + + \00431 + + + \00432 + + + \00433 + + + \00434 + + + \00435 + + + \00436 + + + \00437 + + + \00438 + + + \00439 + + + \0043a + + + \0043b + + + \0043c + + + \0043d + + + \0043e + + + \0043f + + + \00440 + + + \00441 + + + \00442 + + + \00443 + + + \00444 + + + \00445 + + + \00446 + + + \00447 + + + \00448 + + + \00449 + + + \0044a + + + \0044b + + + \0044c + + + \0044d + + + \0044e + + + \0044f + + + \00450 + + + \00451 + + + \00452 + + + \00453 + + + \00454 + + + \00455 + + + \00456 + + + \00457 + + + \00458 + + + \00459 + + + \0045a + + + \0045b + + + \0045c + + + \0045d + + + \0045e + + + \0045f + + + \00460 + + + \00461 + + + \00462 + + + \00463 + + + \00464 + + + \00465 + + + \00466 + + + \00467 + + + \00468 + + + \00469 + + + \0046a + + + \0046b + + + \0046c + + + \0046d + + + \0046e + + + \0046f + + + \00470 + + + \00471 + + + \00472 + + + \00473 + + + \00474 + + + \00475 + + + \00476 + + + \00477 + + + \00478 + + + \00479 + + + \0047a + + + \0047b + + + \0047c + + + \0047d + + + \0047e + + + \0047f + + + \00480 + + + \00481 + + + \00482 + + + \00483 + + + \00484 + + + \00485 + + + \00486 + + + \00487 + + + \00488 + + + \00489 + + + \0048a + + + \0048b + + + \0048c + + + \0048d + + + \0048e + + + \0048f + + + \00490 + + + \00491 + + + \00492 + + + \00493 + + + \00494 + + + \00495 + + + \00496 + + + \00497 + + + \00498 + + + \00499 + + + \0049a + + + \0049b + + + \0049c + + + \0049d + + + \0049e + + + \0049f + + + \004a0 + + + \004a1 + + + \004a2 + + + \004a3 + + + \004a4 + + + \004a5 + + + \004a6 + + + \004a7 + + + \004a8 + + + \004a9 + + + \004aa + + + \004ab + + + \004ac + + + \004ad + + + \004ae + + + \004af + + + \004b0 + + + \004b1 + + + \004b2 + + + \004b3 + + + \004b4 + + + \004b5 + + + \004b6 + + + \004b7 + + + \004b8 + + + \004b9 + + + \004ba + + + \004bb + + + \004bc + + + \004bd + + + \004be + + + \004bf + + + \004c0 + + + \004c1 + + + \004c2 + + + \004c3 + + + \004c4 + + + \004c5 + + + \004c6 + + + \004c7 + + + \004c8 + + + \004c9 + + + \004ca + + + \004cb + + + \004cc + + + \004cd + + + \004ce + + + \004cf + + + \004d0 + + + \004d1 + + + \004d2 + + + \004d3 + + + \004d4 + + + \004d5 + + + \004d6 + + + \004d7 + + + \004d8 + + + \004d9 + + + \004da + + + \004db + + + \004dc + + + \004dd + + + \004de + + + \004df + + + \004e0 + + + \004e1 + + + \004e2 + + + \004e3 + + + \004e4 + + + \004e5 + + + \004e6 + + + \004e7 + + + \004e8 + + + \004e9 + + + \004ea + + + \004eb + + + \004ec + + + \004ed + + + \004ee + + + \004ef + + + \004f0 + + + \004f1 + + + \004f2 + + + \004f3 + + + \004f4 + + + \004f5 + + + \004f6 + + + \004f7 + + + \004f8 + + + \004f9 + + + \004fa + + + \004fb + + + \004fc + + + \004fd + + + \004fe + + + \004ff + + + \00500 + + + \00501 + + + \00502 + + + \00503 + + + \00504 + + + \00505 + + + \00506 + + + \00507 + + + \00508 + + + \00509 + + + \0050a + + + \0050b + + + \0050c + + + \0050d + + + \0050e + + + \0050f + + + \00510 + + + \00511 + + + \00512 + + + \00513 + + + \00514 + + + \00515 + + + \00516 + + + \00517 + + + \00518 + + + \00519 + + + \0051a + + + \0051b + + + \0051c + + + \0051d + + + \0051e + + + \0051f + + + \00520 + + + \00521 + + + \00522 + + + \00523 + + + \00524 + + + \00525 + + + \00526 + + + \00527 + + + \00528 + + + \00529 + + + \0052a + + + \0052b + + + \0052c + + + \0052d + + + \0052e + + + \0052f + + + \00530 + + + \00531 + + + \00532 + + + \00533 + + + \00534 + + + \00535 + + + \00536 + + + \00537 + + + \00538 + + + \00539 + + + \0053a + + + \0053b + + + \0053c + + + \0053d + + + \0053e + + + \0053f + + + \00540 + + + \00541 + + + \00542 + + + \00543 + + + \00544 + + + \00545 + + + \00546 + + + \00547 + + + \00548 + + + \00549 + + + \0054a + + + \0054b + + + \0054c + + + \0054d + + + \0054e + + + \0054f + + + \00550 + + + \00551 + + + \00552 + + + \00553 + + + \00554 + + + \00555 + + + \00556 + + + \00557 + + + \00558 + + + \00559 + + + \0055a + + + \0055b + + + \0055c + + + \0055d + + + \0055e + + + \0055f + + + \00560 + + + \00561 + + + \00562 + + + \00563 + + + \00564 + + + \00565 + + + \00566 + + + \00567 + + + \00568 + + + \00569 + + + \0056a + + + \0056b + + + \0056c + + + \0056d + + + \0056e + + + \0056f + + + \00570 + + + \00571 + + + \00572 + + + \00573 + + + \00574 + + + \00575 + + + \00576 + + + \00577 + + + \00578 + + + \00579 + + + \0057a + + + \0057b + + + \0057c + + + \0057d + + + \0057e + + + \0057f + + + \00580 + + + \00581 + + + \00582 + + + \00583 + + + \00584 + + + \00585 + + + \00586 + + + \00587 + + + \00588 + + + \00589 + + + \0058a + + + \0058b + + + \0058c + + + \0058d + + + \0058e + + + \0058f + + + \00590 + + + \00591 + + + \00592 + + + \00593 + + + \00594 + + + \00595 + + + \00596 + + + \00597 + + + \00598 + + + \00599 + + + \0059a + + + \0059b + + + \0059c + + + \0059d + + + \0059e + + + \0059f + + + \005a0 + + + \005a1 + + + \005a2 + + + \005a3 + + + \005a4 + + + \005a5 + + + \005a6 + + + \005a7 + + + \005a8 + + + \005a9 + + + \005aa + + + \005ab + + + \005ac + + + \005ad + + + \005ae + + + \005af + + + \005b0 + + + \005b1 + + + \005b2 + + + \005b3 + + + \005b4 + + + \005b5 + + + \005b6 + + + \005b7 + + + \005b8 + + + \005b9 + + + \005ba + + + \005bb + + + \005bc + + + \005bd + + + \005be + + + \005bf + + + \005c0 + + + \005c1 + + + \005c2 + + + \005c3 + + + \005c4 + + + \005c5 + + + \005c6 + + + \005c7 + + + \005c8 + + + \005c9 + + + \005ca + + + \005cb + + + \005cc + + + \005cd + + + \005ce + + + \005cf + + + \005d0 + + + \005d1 + + + \005d2 + + + \005d3 + + + \005d4 + + + \005d5 + + + \005d6 + + + \005d7 + + + \005d8 + + + \005d9 + + + \005da + + + \005db + + + \005dc + + + \005dd + + + \005de + + + \005df + + + \005e0 + + + \005e1 + + + \005e2 + + + \005e3 + + + \005e4 + + + \005e5 + + + \005e6 + + + \005e7 + + + \005e8 + + + \005e9 + + + \005ea + + + \005eb + + + \005ec + + + \005ed + + + \005ee + + + \005ef + + + \005f0 + + + \005f1 + + + \005f2 + + + \005f3 + + + \005f4 + + + \005f5 + + + \005f6 + + + \005f7 + + + \005f8 + + + \005f9 + + + \005fa + + + \005fb + + + \005fc + + + \005fd + + + \005fe + + + \005ff + + + \00600 + + + \00601 + + + \00602 + + + \00603 + + + \00604 + + + \00605 + + + \00606 + + + \00607 + + + \00608 + + + \00609 + + + \0060a + + + \0060b + + + \0060c + + + \0060d + + + \0060e + + + \0060f + + + \00610 + + + \00611 + + + \00612 + + + \00613 + + + \00614 + + + \00615 + + + \00616 + + + \00617 + + + \00618 + + + \00619 + + + \0061a + + + \0061b + + + \0061c + + + \0061d + + + \0061e + + + \0061f + + + \00620 + + + \00621 + + + \00622 + + + \00623 + + + \00624 + + + \00625 + + + \00626 + + + \00627 + + + \00628 + + + \00629 + + + \0062a + + + \0062b + + + \0062c + + + \0062d + + + \0062e + + + \0062f + + + \00630 + + + \00631 + + + \00632 + + + \00633 + + + \00634 + + + \00635 + + + \00636 + + + \00637 + + + \00638 + + + \00639 + + + \0063a + + + \0063b + + + \0063c + + + \0063d + + + \0063e + + + \0063f + + + \00640 + + + \00641 + + + I-465 Ramp + + + \00642 + + + \00643 + + + \00644 + + + \00645 + + + I-465 + + + \00646 + + + \00647 + + + \00648 + + + \00649 + + + \0064a + + + \0064b + + + \0064c + + + \0064d + + + \0064e + + + \0064f + + + \00650 + + + \00651 + + + \00652 + + + \00653 + + + \00654 + + + \00655 + + + \00656 + + + \00657 + + + \00658 + + + \00659 + + + \0065a + + + \0065b + + + \0065c + + + \0065d + + + \0065e + + + \0065f + + + \00660 + + + \00661 + + + \00662 + + + \00663 + + + 86th St W Ramp + + + \00664 + + + \00665 + + + 86th St W + + + \00666 + + + \00667 + + + Northwest Blvd + + + \00668 + + + diff --git a/reference/track/ignrando-sample.gpx b/reference/track/ignrando-sample.gpx new file mode 100644 index 000000000..df34d2e86 --- /dev/null +++ b/reference/track/ignrando-sample.gpx @@ -0,0 +1,45 @@ + + + + + + 20050719 Mar Tamié ind 2 VTT Sem Europ + + + 331.000000 + + + 331.000000 + + + 333.000000 + + + 333.000000 + + + 333.000000 + + + 333.000000 + + + 333.000000 + + + 333.351990 + + + 334.760010 + + + 338.000000 + + + + diff --git a/reference/track/ignrando-sample.rdn b/reference/track/ignrando-sample.rdn new file mode 100644 index 000000000..93b40fd6f --- /dev/null +++ b/reference/track/ignrando-sample.rdn @@ -0,0 +1,76 @@ + + + + 1.1 + IFS0201 + 22/01/2005 + 13:45:56 + + + 10 + VTT + 30555.326809 + 13743.150894 + 1215.172668 + 1215.172668 + 0 + 0 + 20050719 Mar Tamié ind 2 VTT Sem Europ + 45.689877,6.300834,45.660805,6.394279 + 65280 + 5 + 0 + 65280 + 1 + 0 + + VTT rando + 2000.000000 + 15.000000 + 300.000000 + 0 + + 27054.002550 + 0 + + + 45.664261,6.372394 + 331.000000 + + + 45.664452,6.372383 + 331.000000 + + + 45.666973,6.371411 + 333.000000 + + + 45.667198,6.371414 + 333.000000 + + + 45.667271,6.371150 + 333.000000 + + + 45.667030,6.371043 + 333.000000 + + + 45.666859,6.370786 + 333.000000 + + + 45.660805,6.367349 + 333.351990 + + + 45.661282,6.366768 + 334.760010 + + + 45.662376,6.365717 + 338.000000 + + diff --git a/reference/track/interptrack.gpx b/reference/track/interptrack.gpx new file mode 100644 index 000000000..3769932dc --- /dev/null +++ b/reference/track/interptrack.gpx @@ -0,0 +1,154 @@ + + + + + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/kartex-out.ktf b/reference/track/kartex-out.ktf new file mode 100644 index 000000000..41e3b9d21 --- /dev/null +++ b/reference/track/kartex-out.ktf @@ -0,0 +1,179 @@ +//Kartex Track File created by GPSBabel +&KTF 2.0,sweref 99 lat long,0 +%,0,N56.151633° E13.760700°,54.00,2006-03-07 15:58:36,,,$ +%,1,N56.151683° E13.760700°,47.00,2006-03-07 15:58:38,,,$ +%,2,N56.151333° E13.760500°,47.00,2006-03-07 15:59:00,,,$ +%,3,N56.150933° E13.760317°,46.00,2006-03-07 15:59:29,,,$ +%,4,N56.150350° E13.759967°,46.00,2006-03-07 16:00:12,,,$ +%,5,N56.149733° E13.759650°,47.00,2006-03-07 16:00:58,,,$ +%,6,N56.149217° E13.759350°,48.00,2006-03-07 16:01:38,,,$ +%,7,N56.148833° E13.759117°,47.00,2006-03-07 16:02:06,,,$ +%,8,N56.148550° E13.759050°,47.00,2006-03-07 16:02:27,,,$ +%,9,N56.148033° E13.758850°,46.00,2006-03-07 16:03:04,,,$ +%,10,N56.147600° E13.758817°,46.00,2006-03-07 16:03:35,,,$ +%,11,N56.147300° E13.758767°,44.00,2006-03-07 16:04:02,,,$ +%,12,N56.147300° E13.758767°,45.00,2006-03-07 16:04:11,,,$ +%,13,N56.147283° E13.758633°,45.00,2006-03-07 16:04:16,,,$ +%,14,N56.147117° E13.758167°,46.00,2006-03-07 16:04:39,,,$ +%,15,N56.147000° E13.757750°,48.00,2006-03-07 16:04:59,,,$ +%,16,N56.146617° E13.757400°,47.00,2006-03-07 16:05:33,,,$ +%,17,N56.146217° E13.757183°,45.00,2006-03-07 16:06:04,,,$ +%,18,N56.145700° E13.756900°,43.00,2006-03-07 16:06:46,,,$ +%,19,N56.145450° E13.756900°,45.00,2006-03-07 16:07:07,,,$ +%,20,N56.145350° E13.757283°,45.00,2006-03-07 16:07:26,,,$ +%,21,N56.145300° E13.757450°,44.00,2006-03-07 16:07:35,,,$ +%,22,N56.144950° E13.757517°,45.00,2006-03-07 16:08:03,,,$ +%,23,N56.144667° E13.757800°,44.00,2006-03-07 16:08:28,,,$ +%,24,N56.144450° E13.758667°,41.00,2006-03-07 16:09:08,,,$ +%,25,N56.144517° E13.759000°,42.00,2006-03-07 16:09:23,,,$ +%,26,N56.144450° E13.759217°,43.00,2006-03-07 16:09:35,,,$ +%,27,N56.144133° E13.759150°,44.00,2006-03-07 16:09:58,,,$ +%,28,N56.143533° E13.759017°,45.00,2006-03-07 16:10:40,,,$ +%,29,N56.143117° E13.758550°,46.00,2006-03-07 16:11:14,,,$ +%,30,N56.142750° E13.758017°,48.00,2006-03-07 16:11:49,,,$ +%,31,N56.142183° E13.757550°,48.00,2006-03-07 16:12:34,,,$ +%,32,N56.142150° E13.757550°,48.00,2006-03-07 16:12:53,,,$ +%,33,N56.142133° E13.757500°,48.00,2006-03-07 16:13:21,,,$ +%,34,N56.141750° E13.757267°,50.00,2006-03-07 16:13:51,,,$ +%,35,N56.141450° E13.757117°,49.00,2006-03-07 16:14:17,,,$ +%,36,N56.141033° E13.756750°,46.00,2006-03-07 16:14:51,,,$ +%,37,N56.140733° E13.756350°,46.00,2006-03-07 16:15:19,,,$ +%,38,N56.140467° E13.756017°,46.00,2006-03-07 16:15:54,,,$ +%,39,N56.140400° E13.755933°,45.00,2006-03-07 16:16:13,,,$ +%,40,N56.140217° E13.755683°,44.00,2006-03-07 16:16:33,,,$ +%,41,N56.139750° E13.755200°,43.00,2006-03-07 16:17:11,,,$ +%,42,N56.139550° E13.754867°,44.00,2006-03-07 16:17:35,,,$ +%,43,N56.139500° E13.754800°,44.00,2006-03-07 16:17:41,,,$ +%,44,N56.139000° E13.755117°,43.00,2006-03-07 16:18:19,,,$ +%,45,N56.138767° E13.755167°,43.00,2006-03-07 16:18:35,,,$ +%,46,N56.138717° E13.755050°,44.00,2006-03-07 16:18:41,,,$ +%,47,N56.138617° E13.753750°,43.00,2006-03-07 16:19:36,,,$ +%,48,N56.138567° E13.753150°,44.00,2006-03-07 16:20:01,,,$ +%,49,N56.138333° E13.752767°,44.00,2006-03-07 16:20:25,,,$ +%,50,N56.137733° E13.752717°,44.00,2006-03-07 16:21:11,,,$ +%,51,N56.137067° E13.753167°,42.00,2006-03-07 16:22:05,,,$ +%,52,N56.136833° E13.753667°,43.00,2006-03-07 16:22:34,,,$ +%,53,N56.136633° E13.754150°,44.00,2006-03-07 16:23:01,,,$ +%,54,N56.136367° E13.754967°,44.00,2006-03-07 16:23:42,,,$ +%,55,N56.136300° E13.755183°,44.00,2006-03-07 16:24:03,,,$ +%,56,N56.136300° E13.755233°,44.00,2006-03-07 16:24:05,,,$ +%,57,N56.136217° E13.755283°,44.00,2006-03-07 16:24:11,,,$ +%,58,N56.135767° E13.754967°,44.00,2006-03-07 16:24:48,,,$ +%,59,N56.135350° E13.754650°,43.00,2006-03-07 16:25:22,,,$ +%,60,N56.134950° E13.754267°,44.00,2006-03-07 16:26:03,,,$ +%,61,N56.134767° E13.754067°,45.00,2006-03-07 16:26:35,,,$ +%,62,N56.134667° E13.753917°,44.00,2006-03-07 16:26:55,,,$ +%,63,N56.134167° E13.753183°,44.00,2006-03-07 16:27:42,,,$ +%,64,N56.133750° E13.752350°,44.00,2006-03-07 16:28:30,,,$ +%,65,N56.133700° E13.752250°,47.00,2006-03-07 16:28:55,,,$ +%,66,N56.133567° E13.751950°,48.00,2006-03-07 16:29:40,,,$ +%,67,N56.133250° E13.751100°,47.00,2006-03-07 16:30:23,,,$ +%,68,N56.132933° E13.750317°,47.00,2006-03-07 16:31:04,,,$ +%,69,N56.132633° E13.749517°,46.00,2006-03-07 16:31:45,,,$ +%,70,N56.132533° E13.748967°,43.00,2006-03-07 16:32:13,,,$ +%,71,N56.132500° E13.748850°,43.00,2006-03-07 16:32:27,,,$ +%,72,N56.132500° E13.748833°,43.00,2006-03-07 16:32:29,,,$ +%,73,N56.132050° E13.748367°,44.00,2006-03-07 16:33:09,,,$ +%,74,N56.131883° E13.748250°,45.00,2006-03-07 16:33:31,,,$ +%,75,N56.131367° E13.747767°,46.00,2006-03-07 16:34:15,,,$ +%,76,N56.131100° E13.747500°,47.00,2006-03-07 16:34:44,,,$ +%,77,N56.130667° E13.746983°,44.00,2006-03-07 16:35:22,,,$ +%,78,N56.130167° E13.746383°,43.00,2006-03-07 16:36:09,,,$ +%,79,N56.129683° E13.745833°,43.00,2006-03-07 16:36:52,,,$ +%,80,N56.129233° E13.745333°,44.00,2006-03-07 16:37:30,,,$ +%,81,N56.128717° E13.744783°,43.00,2006-03-07 16:38:15,,,$ +%,82,N56.128117° E13.744117°,43.00,2006-03-07 16:39:06,,,$ +%,83,N56.127600° E13.743550°,44.00,2006-03-07 16:39:52,,,$ +%,84,N56.127267° E13.743183°,44.00,2006-03-07 16:40:24,,,$ +%,85,N56.126783° E13.742767°,44.00,2006-03-07 16:41:05,,,$ +%,86,N56.126467° E13.742500°,44.00,2006-03-07 16:41:34,,,$ +%,87,N56.126233° E13.742317°,47.00,2006-03-07 16:42:03,,,$ +%,88,N56.126117° E13.742250°,46.00,2006-03-07 16:42:15,,,$ +%,89,N56.126083° E13.742200°,46.00,2006-03-07 16:42:37,,,$ +%,90,N56.125967° E13.742117°,46.00,2006-03-07 16:42:58,,,$ +%,91,N56.125783° E13.741983°,46.00,2006-03-07 16:43:16,,,$ +%,92,N56.125283° E13.741733°,47.00,2006-03-07 16:43:54,,,$ +%,93,N56.124767° E13.741467°,46.00,2006-03-07 16:44:36,,,$ +%,94,N56.124433° E13.741283°,44.00,2006-03-07 16:45:04,,,$ +%,95,N56.124000° E13.741000°,44.00,2006-03-07 16:45:38,,,$ +%,96,N56.123483° E13.740717°,44.00,2006-03-07 16:46:20,,,$ +%,97,N56.122933° E13.740550°,46.00,2006-03-07 16:47:02,,,$ +%,98,N56.122417° E13.740450°,49.00,2006-03-07 16:47:40,,,$ +%,99,N56.121817° E13.740283°,50.00,2006-03-07 16:48:25,,,$ +%,100,N56.121250° E13.740083°,51.00,2006-03-07 16:49:07,,,$ +%,101,N56.121133° E13.739983°,51.00,2006-03-07 16:49:31,,,$ +%,102,N56.121033° E13.739950°,52.00,2006-03-07 16:49:52,,,$ +%,103,N56.120983° E13.739950°,52.00,2006-03-07 16:50:18,,,$ +%,104,N56.120617° E13.739783°,52.00,2006-03-07 16:50:49,,,$ +%,105,N56.120267° E13.739600°,52.00,2006-03-07 16:51:23,,,$ +%,106,N56.120067° E13.739583°,53.00,2006-03-07 16:51:56,,,$ +%,107,N56.119800° E13.739500°,53.00,2006-03-07 16:52:26,,,$ +%,108,N56.119800° E13.739500°,52.00,2006-03-07 16:52:35,,,$ +%,109,N56.119233° E13.739567°,52.00,2006-03-07 16:53:17,,,$ +%,110,N56.118650° E13.739667°,51.00,2006-03-07 16:54:00,,,$ +%,111,N56.118050° E13.740033°,51.00,2006-03-07 16:54:47,,,$ +%,112,N56.117600° E13.740383°,50.00,2006-03-07 16:55:24,,,$ +%,113,N56.117067° E13.740550°,49.00,2006-03-07 16:56:05,,,$ +%,114,N56.116383° E13.740600°,50.00,2006-03-07 16:56:54,,,$ +%,115,N56.115950° E13.740617°,52.00,2006-03-07 16:57:27,,,$ +%,116,N56.115367° E13.740633°,52.00,2006-03-07 16:58:11,,,$ +%,117,N56.115033° E13.739867°,48.00,2006-03-07 16:58:52,,,$ +%,118,N56.114967° E13.739000°,46.00,2006-03-07 16:59:27,,,$ +%,119,N56.115017° E13.738233°,47.00,2006-03-07 16:59:57,,,$ +%,120,N56.115067° E13.737550°,46.00,2006-03-07 17:00:26,,,$ +%,121,N56.115367° E13.736733°,45.00,2006-03-07 17:01:07,,,$ +%,122,N56.115833° E13.736367°,44.00,2006-03-07 17:01:45,,,$ +%,123,N56.116317° E13.736017°,45.00,2006-03-07 17:02:25,,,$ +%,124,N56.116633° E13.735867°,44.00,2006-03-07 17:02:50,,,$ +%,125,N56.117217° E13.735650°,44.00,2006-03-07 17:03:32,,,$ +%,126,N56.117817° E13.735567°,45.00,2006-03-07 17:04:17,,,$ +%,127,N56.118400° E13.735417°,45.00,2006-03-07 17:04:59,,,$ +%,128,N56.118533° E13.735200°,45.00,2006-03-07 17:05:11,,,$ +%,129,N56.118933° E13.735167°,44.00,2006-03-07 17:05:43,,,$ +%,130,N56.119150° E13.735117°,44.00,2006-03-07 17:05:58,,,$ +%,131,N56.119267° E13.734750°,44.00,2006-03-07 17:06:16,,,$ +%,132,N56.119583° E13.734867°,44.00,2006-03-07 17:06:41,,,$ +%,133,N56.119833° E13.734333°,43.00,2006-03-07 17:07:15,,,$ +%,134,N56.120067° E13.734033°,43.00,2006-03-07 17:07:38,,,$ +%,135,N56.120283° E13.733883°,43.00,2006-03-07 17:07:59,,,$ +%,136,N56.120350° E13.733850°,43.00,2006-03-07 17:08:27,,,$ +%,137,N56.120350° E13.733850°,43.00,2006-03-07 17:08:35,,,$ +%,138,N56.120667° E13.733267°,41.00,2006-03-07 17:09:12,,,$ +%,139,N56.120933° E13.732717°,41.00,2006-03-07 17:09:45,,,$ +%,140,N56.121167° E13.732217°,40.00,2006-03-07 17:10:14,,,$ +%,141,N56.121450° E13.731583°,40.00,2006-03-07 17:10:51,,,$ +%,142,N56.121783° E13.730833°,41.00,2006-03-07 17:11:35,,,$ +%,143,N56.122033° E13.730100°,41.00,2006-03-07 17:12:14,,,$ +%,144,N56.122283° E13.729500°,40.00,2006-03-07 17:12:47,,,$ +%,145,N56.122583° E13.728817°,39.00,2006-03-07 17:13:27,,,$ +%,146,N56.122883° E13.728083°,40.00,2006-03-07 17:14:09,,,$ +%,147,N56.123167° E13.727433°,41.00,2006-03-07 17:14:48,,,$ +%,148,N56.123267° E13.727200°,41.00,2006-03-07 17:15:08,,,$ +%,149,N56.123450° E13.726867°,41.00,2006-03-07 17:15:32,,,$ +%,150,N56.123633° E13.726383°,40.00,2006-03-07 17:15:59,,,$ +%,151,N56.123900° E13.725867°,40.00,2006-03-07 17:16:30,,,$ +%,152,N56.124217° E13.725250°,39.00,2006-03-07 17:17:09,,,$ +%,153,N56.124467° E13.724750°,40.00,2006-03-07 17:17:41,,,$ +%,154,N56.124733° E13.724117°,39.00,2006-03-07 17:18:17,,,$ +%,155,N56.124833° E13.723750°,38.00,2006-03-07 17:18:45,,,$ +%,156,N56.124950° E13.723450°,38.00,2006-03-07 17:19:21,,,$ +%,157,N56.125200° E13.722850°,38.00,2006-03-07 17:19:54,,,$ +%,158,N56.125333° E13.722567°,38.00,2006-03-07 17:20:12,,,$ +%,159,N56.125400° E13.722317°,38.00,2006-03-07 17:20:29,,,$ +%,160,N56.125467° E13.722500°,39.00,2006-03-07 17:20:39,,,$ +%,161,N56.125783° E13.722650°,40.00,2006-03-07 17:21:06,,,$ +%,162,N56.125817° E13.722667°,40.00,2006-03-07 17:21:11,,,$ +%,163,N56.125883° E13.722650°,40.00,2006-03-07 17:21:16,,,$ +%,164,N56.125850° E13.722367°,41.00,2006-03-07 17:21:32,,,$ +%,165,N56.125867° E13.722133°,41.00,2006-03-07 17:21:56,,,$ +%,166,N56.125867° E13.722050°,42.00,2006-03-07 17:22:16,,,$ +%,167,N56.125850° E13.722050°,41.00,2006-03-07 17:22:52,,,$ +%,168,N56.125867° E13.721950°,41.00,2006-03-07 17:23:10,,,$ +%,169,N56.125917° E13.721967°,41.00,2006-03-07 17:23:30,,,$ +%,170,N56.125883° E13.721967°,41.00,2006-03-07 17:24:15,,,$ +%,171,N56.125867° E13.722167°,38.00,2006-03-07 17:33:44,,,$ +%,172,N56.125800° E13.722217°,38.00,2006-03-07 17:34:10,,,$ +%,173,N56.125783° E13.722250°,40.00,2006-03-07 17:34:40,,,$ +%,174,N56.125783° E13.722200°,40.00,2006-03-07 17:34:58,,,$ +%,175,N56.125817° E13.722317°,41.00,2006-03-07 17:35:12,,,$ +%,176,N56.125817° E13.722317°,40.00,2006-03-07 17:35:52,,,$ diff --git a/reference/track/kartex.txt b/reference/track/kartex.txt new file mode 100644 index 000000000..76d87bb6b --- /dev/null +++ b/reference/track/kartex.txt @@ -0,0 +1,182 @@ +Grid Lat/Lon hddd°mm.mmm' +Datum WGS 84 + +Header Name Description Type Position Altitude Depth Proximity Temperature Display Mode Color Symbol Facility City State Country Date Modified Link Categories + +Waypoint WPT001 User Waypoint N56 09.098 E13 45.642 54 m Symbol & Name Unknown Waypoint 07/03/2006 15:58:36 +Waypoint WPT002 User Waypoint N56 09.101 E13 45.642 47 m Symbol & Name Unknown Waypoint 07/03/2006 15:58:38 +Waypoint WPT003 User Waypoint N56 09.080 E13 45.630 47 m Symbol & Name Unknown Waypoint 07/03/2006 15:59:00 +Waypoint WPT004 User Waypoint N56 09.056 E13 45.619 46 m Symbol & Name Unknown Waypoint 07/03/2006 15:59:29 +Waypoint WPT005 User Waypoint N56 09.021 E13 45.598 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:00:12 +Waypoint WPT006 User Waypoint N56 08.984 E13 45.579 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:00:58 +Waypoint WPT007 User Waypoint N56 08.953 E13 45.561 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:01:38 +Waypoint WPT008 User Waypoint N56 08.930 E13 45.547 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:02:06 +Waypoint WPT009 User Waypoint N56 08.913 E13 45.543 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:02:27 +Waypoint WPT010 User Waypoint N56 08.882 E13 45.531 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:03:04 +Waypoint WPT011 User Waypoint N56 08.856 E13 45.529 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:03:35 +Waypoint WPT012 User Waypoint N56 08.838 E13 45.526 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:04:02 +Waypoint WPT013 User Waypoint N56 08.838 E13 45.526 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:04:11 +Waypoint WPT014 User Waypoint N56 08.837 E13 45.518 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:04:16 +Waypoint WPT015 User Waypoint N56 08.827 E13 45.490 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:04:39 +Waypoint WPT016 User Waypoint N56 08.820 E13 45.465 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:04:59 +Waypoint WPT017 User Waypoint N56 08.797 E13 45.444 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:05:33 +Waypoint WPT018 User Waypoint N56 08.773 E13 45.431 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:06:04 +Waypoint WPT019 User Waypoint N56 08.742 E13 45.414 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:06:46 +Waypoint WPT020 User Waypoint N56 08.727 E13 45.414 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:07:07 +Waypoint WPT021 User Waypoint N56 08.721 E13 45.437 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:07:26 +Waypoint WPT022 User Waypoint N56 08.718 E13 45.447 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:07:35 +Waypoint WPT023 User Waypoint N56 08.697 E13 45.451 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:08:03 +Waypoint WPT024 User Waypoint N56 08.680 E13 45.468 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:08:28 +Waypoint WPT025 User Waypoint N56 08.667 E13 45.520 41 m Symbol & Name Unknown Waypoint 07/03/2006 16:09:08 +Waypoint WPT026 User Waypoint N56 08.671 E13 45.540 42 m Symbol & Name Unknown Waypoint 07/03/2006 16:09:23 +Waypoint WPT027 User Waypoint N56 08.667 E13 45.553 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:09:35 +Waypoint WPT028 User Waypoint N56 08.648 E13 45.549 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:09:58 +Waypoint WPT029 User Waypoint N56 08.612 E13 45.541 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:10:40 +Waypoint WPT030 User Waypoint N56 08.587 E13 45.513 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:11:14 +Waypoint WPT031 User Waypoint N56 08.565 E13 45.481 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:11:49 +Waypoint WPT032 User Waypoint N56 08.531 E13 45.453 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:12:34 +Waypoint WPT033 User Waypoint N56 08.529 E13 45.453 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:12:53 +Waypoint WPT034 User Waypoint N56 08.528 E13 45.450 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:13:21 +Waypoint WPT035 User Waypoint N56 08.505 E13 45.436 50 m Symbol & Name Unknown Waypoint 07/03/2006 16:13:51 +Waypoint WPT036 User Waypoint N56 08.487 E13 45.427 49 m Symbol & Name Unknown Waypoint 07/03/2006 16:14:17 +Waypoint WPT037 User Waypoint N56 08.462 E13 45.405 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:14:51 +Waypoint WPT038 User Waypoint N56 08.444 E13 45.381 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:15:19 +Waypoint WPT039 User Waypoint N56 08.428 E13 45.361 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:15:54 +Waypoint WPT040 User Waypoint N56 08.424 E13 45.356 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:16:13 +Waypoint WPT041 User Waypoint N56 08.413 E13 45.341 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:16:33 +Waypoint WPT042 User Waypoint N56 08.385 E13 45.312 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:17:11 +Waypoint WPT043 User Waypoint N56 08.373 E13 45.292 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:17:35 +Waypoint WPT044 User Waypoint N56 08.370 E13 45.288 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:17:41 +Waypoint WPT045 User Waypoint N56 08.340 E13 45.307 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:18:19 +Waypoint WPT046 User Waypoint N56 08.326 E13 45.310 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:18:35 +Waypoint WPT047 User Waypoint N56 08.323 E13 45.303 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:18:41 +Waypoint WPT048 User Waypoint N56 08.317 E13 45.225 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:19:36 +Waypoint WPT049 User Waypoint N56 08.314 E13 45.189 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:20:01 +Waypoint WPT050 User Waypoint N56 08.300 E13 45.166 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:20:25 +Waypoint WPT051 User Waypoint N56 08.264 E13 45.163 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:21:11 +Waypoint WPT052 User Waypoint N56 08.224 E13 45.190 42 m Symbol & Name Unknown Waypoint 07/03/2006 16:22:05 +Waypoint WPT053 User Waypoint N56 08.210 E13 45.220 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:22:34 +Waypoint WPT054 User Waypoint N56 08.198 E13 45.249 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:23:01 +Waypoint WPT055 User Waypoint N56 08.182 E13 45.298 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:23:42 +Waypoint WPT056 User Waypoint N56 08.178 E13 45.311 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:24:03 +Waypoint WPT057 User Waypoint N56 08.178 E13 45.314 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:24:05 +Waypoint WPT058 User Waypoint N56 08.173 E13 45.317 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:24:11 +Waypoint WPT059 User Waypoint N56 08.146 E13 45.298 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:24:48 +Waypoint WPT060 User Waypoint N56 08.121 E13 45.279 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:25:22 +Waypoint WPT061 User Waypoint N56 08.097 E13 45.256 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:26:03 +Waypoint WPT062 User Waypoint N56 08.086 E13 45.244 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:26:35 +Waypoint WPT063 User Waypoint N56 08.080 E13 45.235 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:26:55 +Waypoint WPT064 User Waypoint N56 08.050 E13 45.191 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:27:42 +Waypoint WPT065 User Waypoint N56 08.025 E13 45.141 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:28:30 +Waypoint WPT066 User Waypoint N56 08.022 E13 45.135 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:28:55 +Waypoint WPT067 User Waypoint N56 08.014 E13 45.117 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:29:40 +Waypoint WPT068 User Waypoint N56 07.995 E13 45.066 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:30:23 +Waypoint WPT069 User Waypoint N56 07.976 E13 45.019 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:31:04 +Waypoint WPT070 User Waypoint N56 07.958 E13 44.971 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:31:45 +Waypoint WPT071 User Waypoint N56 07.952 E13 44.938 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:32:13 +Waypoint WPT072 User Waypoint N56 07.950 E13 44.931 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:32:27 +Waypoint WPT073 User Waypoint N56 07.950 E13 44.930 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:32:29 +Waypoint WPT074 User Waypoint N56 07.923 E13 44.902 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:33:09 +Waypoint WPT075 User Waypoint N56 07.913 E13 44.895 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:33:31 +Waypoint WPT076 User Waypoint N56 07.882 E13 44.866 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:34:15 +Waypoint WPT077 User Waypoint N56 07.866 E13 44.850 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:34:44 +Waypoint WPT078 User Waypoint N56 07.840 E13 44.819 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:35:22 +Waypoint WPT079 User Waypoint N56 07.810 E13 44.783 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:36:09 +Waypoint WPT080 User Waypoint N56 07.781 E13 44.750 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:36:52 +Waypoint WPT081 User Waypoint N56 07.754 E13 44.720 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:37:30 +Waypoint WPT082 User Waypoint N56 07.723 E13 44.687 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:38:15 +Waypoint WPT083 User Waypoint N56 07.687 E13 44.647 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:39:06 +Waypoint WPT084 User Waypoint N56 07.656 E13 44.613 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:39:52 +Waypoint WPT085 User Waypoint N56 07.636 E13 44.591 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:40:24 +Waypoint WPT086 User Waypoint N56 07.607 E13 44.566 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:41:05 +Waypoint WPT087 User Waypoint N56 07.588 E13 44.550 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:41:34 +Waypoint WPT088 User Waypoint N56 07.574 E13 44.539 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:42:03 +Waypoint WPT089 User Waypoint N56 07.567 E13 44.535 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:42:15 +Waypoint WPT090 User Waypoint N56 07.565 E13 44.532 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:42:37 +Waypoint WPT091 User Waypoint N56 07.558 E13 44.527 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:42:58 +Waypoint WPT092 User Waypoint N56 07.547 E13 44.519 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:43:16 +Waypoint WPT093 User Waypoint N56 07.517 E13 44.504 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:43:54 +Waypoint WPT094 User Waypoint N56 07.486 E13 44.488 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:44:36 +Waypoint WPT095 User Waypoint N56 07.466 E13 44.477 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:45:04 +Waypoint WPT096 User Waypoint N56 07.440 E13 44.460 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:45:38 +Waypoint WPT097 User Waypoint N56 07.409 E13 44.443 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:46:20 +Waypoint WPT098 User Waypoint N56 07.376 E13 44.433 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:47:02 +Waypoint WPT099 User Waypoint N56 07.345 E13 44.427 49 m Symbol & Name Unknown Waypoint 07/03/2006 16:47:40 +Waypoint WPT100 User Waypoint N56 07.309 E13 44.417 50 m Symbol & Name Unknown Waypoint 07/03/2006 16:48:25 +Waypoint WPT101 User Waypoint N56 07.275 E13 44.405 51 m Symbol & Name Unknown Waypoint 07/03/2006 16:49:07 +Waypoint WPT102 User Waypoint N56 07.268 E13 44.399 51 m Symbol & Name Unknown Waypoint 07/03/2006 16:49:31 +Waypoint WPT103 User Waypoint N56 07.262 E13 44.397 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:49:52 +Waypoint WPT104 User Waypoint N56 07.259 E13 44.397 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:50:18 +Waypoint WPT105 User Waypoint N56 07.237 E13 44.387 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:50:49 +Waypoint WPT106 User Waypoint N56 07.216 E13 44.376 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:51:23 +Waypoint WPT107 User Waypoint N56 07.204 E13 44.375 53 m Symbol & Name Unknown Waypoint 07/03/2006 16:51:56 +Waypoint WPT108 User Waypoint N56 07.188 E13 44.370 53 m Symbol & Name Unknown Waypoint 07/03/2006 16:52:26 +Waypoint WPT109 User Waypoint N56 07.188 E13 44.370 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:52:35 +Waypoint WPT110 User Waypoint N56 07.154 E13 44.374 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:53:17 +Waypoint WPT111 User Waypoint N56 07.119 E13 44.380 51 m Symbol & Name Unknown Waypoint 07/03/2006 16:54:00 +Waypoint WPT112 User Waypoint N56 07.083 E13 44.402 51 m Symbol & Name Unknown Waypoint 07/03/2006 16:54:47 +Waypoint WPT113 User Waypoint N56 07.056 E13 44.423 50 m Symbol & Name Unknown Waypoint 07/03/2006 16:55:24 +Waypoint WPT114 User Waypoint N56 07.024 E13 44.433 49 m Symbol & Name Unknown Waypoint 07/03/2006 16:56:05 +Waypoint WPT115 User Waypoint N56 06.983 E13 44.436 50 m Symbol & Name Unknown Waypoint 07/03/2006 16:56:54 +Waypoint WPT116 User Waypoint N56 06.957 E13 44.437 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:57:27 +Waypoint WPT117 User Waypoint N56 06.922 E13 44.438 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:58:11 +Waypoint WPT118 User Waypoint N56 06.902 E13 44.392 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:58:52 +Waypoint WPT119 User Waypoint N56 06.898 E13 44.340 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:59:27 +Waypoint WPT120 User Waypoint N56 06.901 E13 44.294 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:59:57 +Waypoint WPT121 User Waypoint N56 06.904 E13 44.253 46 m Symbol & Name Unknown Waypoint 07/03/2006 17:00:26 +Waypoint WPT122 User Waypoint N56 06.922 E13 44.204 45 m Symbol & Name Unknown Waypoint 07/03/2006 17:01:07 +Waypoint WPT123 User Waypoint N56 06.950 E13 44.182 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:01:45 +Waypoint WPT124 User Waypoint N56 06.979 E13 44.161 45 m Symbol & Name Unknown Waypoint 07/03/2006 17:02:25 +Waypoint WPT125 User Waypoint N56 06.998 E13 44.152 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:02:50 +Waypoint WPT126 User Waypoint N56 07.033 E13 44.139 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:03:32 +Waypoint WPT127 User Waypoint N56 07.069 E13 44.134 45 m Symbol & Name Unknown Waypoint 07/03/2006 17:04:17 +Waypoint WPT128 User Waypoint N56 07.104 E13 44.125 45 m Symbol & Name Unknown Waypoint 07/03/2006 17:04:59 +Waypoint WPT129 User Waypoint N56 07.112 E13 44.112 45 m Symbol & Name Unknown Waypoint 07/03/2006 17:05:11 +Waypoint WPT130 User Waypoint N56 07.136 E13 44.110 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:05:43 +Waypoint WPT131 User Waypoint N56 07.149 E13 44.107 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:05:58 +Waypoint WPT132 User Waypoint N56 07.156 E13 44.085 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:06:16 +Waypoint WPT133 User Waypoint N56 07.175 E13 44.092 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:06:41 +Waypoint WPT134 User Waypoint N56 07.190 E13 44.060 43 m Symbol & Name Unknown Waypoint 07/03/2006 17:07:15 +Waypoint WPT135 User Waypoint N56 07.204 E13 44.042 43 m Symbol & Name Unknown Waypoint 07/03/2006 17:07:38 +Waypoint WPT136 User Waypoint N56 07.217 E13 44.033 43 m Symbol & Name Unknown Waypoint 07/03/2006 17:07:59 +Waypoint WPT137 User Waypoint N56 07.221 E13 44.031 43 m Symbol & Name Unknown Waypoint 07/03/2006 17:08:27 +Waypoint WPT138 User Waypoint N56 07.221 E13 44.031 43 m Symbol & Name Unknown Waypoint 07/03/2006 17:08:35 +Waypoint WPT139 User Waypoint N56 07.240 E13 43.996 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:09:12 +Waypoint WPT140 User Waypoint N56 07.256 E13 43.963 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:09:45 +Waypoint WPT141 User Waypoint N56 07.270 E13 43.933 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:10:14 +Waypoint WPT142 User Waypoint N56 07.287 E13 43.895 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:10:51 +Waypoint WPT143 User Waypoint N56 07.307 E13 43.850 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:11:35 +Waypoint WPT144 User Waypoint N56 07.322 E13 43.806 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:12:14 +Waypoint WPT145 User Waypoint N56 07.337 E13 43.770 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:12:47 +Waypoint WPT146 User Waypoint N56 07.355 E13 43.729 39 m Symbol & Name Unknown Waypoint 07/03/2006 17:13:27 +Waypoint WPT147 User Waypoint N56 07.373 E13 43.685 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:14:09 +Waypoint WPT148 User Waypoint N56 07.390 E13 43.646 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:14:48 +Waypoint WPT149 User Waypoint N56 07.396 E13 43.632 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:15:08 +Waypoint WPT150 User Waypoint N56 07.407 E13 43.612 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:15:32 +Waypoint WPT151 User Waypoint N56 07.418 E13 43.583 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:15:59 +Waypoint WPT152 User Waypoint N56 07.434 E13 43.552 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:16:30 +Waypoint WPT153 User Waypoint N56 07.453 E13 43.515 39 m Symbol & Name Unknown Waypoint 07/03/2006 17:17:09 +Waypoint WPT154 User Waypoint N56 07.468 E13 43.485 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:17:41 +Waypoint WPT155 User Waypoint N56 07.484 E13 43.447 39 m Symbol & Name Unknown Waypoint 07/03/2006 17:18:17 +Waypoint WPT156 User Waypoint N56 07.490 E13 43.425 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:18:45 +Waypoint WPT157 User Waypoint N56 07.497 E13 43.407 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:19:21 +Waypoint WPT158 User Waypoint N56 07.512 E13 43.371 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:19:54 +Waypoint WPT159 User Waypoint N56 07.520 E13 43.354 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:20:12 +Waypoint WPT160 User Waypoint N56 07.524 E13 43.339 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:20:29 +Waypoint WPT161 User Waypoint N56 07.528 E13 43.350 39 m Symbol & Name Unknown Waypoint 07/03/2006 17:20:39 +Waypoint WPT162 User Waypoint N56 07.547 E13 43.359 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:21:06 +Waypoint WPT163 User Waypoint N56 07.549 E13 43.360 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:21:11 +Waypoint WPT164 User Waypoint N56 07.553 E13 43.359 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:21:16 +Waypoint WPT165 User Waypoint N56 07.551 E13 43.342 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:21:32 +Waypoint WPT166 User Waypoint N56 07.552 E13 43.328 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:21:56 +Waypoint WPT167 User Waypoint N56 07.552 E13 43.323 42 m Symbol & Name Unknown Waypoint 07/03/2006 17:22:16 +Waypoint WPT168 User Waypoint N56 07.551 E13 43.323 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:22:52 +Waypoint WPT169 User Waypoint N56 07.552 E13 43.317 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:23:10 +Waypoint WPT170 User Waypoint N56 07.555 E13 43.318 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:23:30 +Waypoint WPT171 User Waypoint N56 07.553 E13 43.318 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:24:15 +Waypoint WPT172 User Waypoint N56 07.552 E13 43.330 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:33:44 +Waypoint WPT173 User Waypoint N56 07.548 E13 43.333 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:34:10 +Waypoint WPT174 User Waypoint N56 07.547 E13 43.335 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:34:40 +Waypoint WPT175 User Waypoint N56 07.547 E13 43.332 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:34:58 +Waypoint WPT176 User Waypoint N56 07.549 E13 43.339 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:35:12 +Waypoint WPT177 User Waypoint N56 07.549 E13 43.339 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:35:52 diff --git a/reference/track/kompass.tk b/reference/track/kompass.tk new file mode 100644 index 000000000..747062dc8 --- /dev/null +++ b/reference/track/kompass.tk @@ -0,0 +1,64 @@ +30.0621830,-91.6103500 +30.0627830,-91.6105670 +30.0627000,-91.6082670 +30.0623330,-91.6073830 +30.0615330,-91.6052830 +30.0597830,-91.5994000 +30.0578000,-91.5966830 +30.0553830,-91.5949000 +30.0538830,-91.5926170 +30.0497330,-91.5897500 +30.0490170,-91.5898830 +30.0488000,-91.5929330 +30.0462330,-91.5964500 +30.0455170,-91.5987170 +30.0473000,-91.6002670 +30.0470000,-91.5996330 +30.0464330,-91.5994670 +30.0462000,-91.5989500 +30.0463670,-91.5977330 +30.0463500,-91.5971670 +30.0467830,-91.5963330 +30.0474500,-91.5952000 +30.0478000,-91.5947670 +30.0482500,-91.5940830 +30.0486830,-91.5938000 +30.0493500,-91.5938500 +30.0503170,-91.5939830 +30.0507830,-91.5941170 +30.0512330,-91.5943670 +30.0518000,-91.5943670 +30.0522170,-91.5946670 +30.0530170,-91.5946830 +30.0548670,-91.5952000 +30.0537330,-91.5949330 +30.0531830,-91.5947830 +30.0526330,-91.5948330 +30.0524500,-91.5954330 +30.0524830,-91.5959670 +30.0526500,-91.5967830 +30.0531330,-91.5978500 +30.0536170,-91.5979670 +30.0539670,-91.5977670 +30.0536170,-91.5980830 +30.0532000,-91.5979170 +30.0528170,-91.5975170 +30.0525670,-91.5969330 +30.0523330,-91.5964330 +30.0522500,-91.5956830 +30.0522170,-91.5950170 +30.0518830,-91.5947000 +30.0510500,-91.5944000 +30.0505670,-91.5942330 +30.0501830,-91.5941000 +30.0491000,-91.5937170 +30.0484500,-91.5942500 +30.0480830,-91.5947500 +30.0475000,-91.5954500 +30.0470670,-91.5960000 +30.0466330,-91.5966000 +30.0464000,-91.5976500 +30.0462330,-91.5984670 +30.0463170,-91.5989670 +30.0467830,-91.5992830 +30.0471330,-91.5996670 diff --git a/reference/track/mapsend.trk b/reference/track/mapsend.trk new file mode 100644 index 0000000000000000000000000000000000000000..6ce0351c876bacdf9c78a8e6e85af222c35b70b9 GIT binary patch literal 1884 zcmZA1doWyQ6aet0@v5+kN(3vZ5LzjVRjS)W9!OH_S=-c#M@b?|8c95&m^>=OM7q@y zBhjsiiP6?n^Qt^-vP6-H!J?J~yHz@AOC&8VG1BwJIWwmBpSyE^d(Qdp_nmu8gj>Bl z;S#P9M|cW#IUJ7Odk5naKJtTK{(%Q)xxY!28a?lge{eS_b>P|Q=Eov-=h(de=1B{{ z!ab*o&3PM?>{-H3h-)1~`zOXF%Foi%Y)lX}gc8r4F(ZIRcK0o&AuWsKwP0jpOz=zt zU{|1iwG#0dp(wb!I2zFF#MrbL(Y6&M4eNGr1%QXHT0UzxT}fBK9U(@F_@uV0M~1FUF#I#-RDLs)uR+nfy8xhibX z2GcsJu;!<{+{8G*>__X|4FTDK77-d*9r$J!;2v9^=_sbXM`)W9?-2>;XAys=2ap}I zc@L(IC=c1P3D9S{q;41^iwL>ng>&A3$u2WxLx>8(3ghh&uLG|BcE!RhqHZsyHM^i_ zTnRYmKK{KUzDgcpV!l@m5AcWEuvPdfHH7n1t1|Qe1%|b@QGjf$^FCV<+z) z&p_n&VaS*SZ<$tjp2wQ8gxi|FQ@sQ@(E_`SHCqX_k&krr0euJlvgcr%{6i?e zmt*}h;Eh)=SMm`Ze#V-F9g}zOY)1Tm@QS2$85bfiSG{WdZ~i3PTdmYT26fN6d{MIR$72^)s4U2+H9XP=Ul z4ftY;3}V{M>Lz7aPx&YZG^bt0R z!k!2GFOvTNYi?y1V4dTyC*+tmjWDn9)Q|4~?pjuvn2)F>Y+XC-Bm_)#57$jcw0nqY z#lH13E`R~fRrR|Og9)u3&eyI66nhtLibE_UTr=0Edy?N$y)(I^mqi=1) zNTVUFneP@<&ARX3bWMdBVho`HOm71~ZTaZqC)n`?ga@j08rX*<%lf)Yjd+RB`kdhK zbC_TqZ^Ph4rr4dBQ$ zgq7BAL#&5tc;{uyF_JfeHQPO!FS-K$U3~1dDV!z&ge&-W$2J0X7N~|bh^2&<{`P@l zz@_t6O(=8Sp2cQgPuaDk2N=oKU`?ykPimq7mrk%S!sPUzDK>BW*$0KIEhYR9HcXdG literal 0 HcmV?d00001 diff --git a/reference/track/meridian.trk b/reference/track/meridian.trk new file mode 100644 index 000000000..abcb1a40a --- /dev/null +++ b/reference/track/meridian.trk @@ -0,0 +1,64 @@ +$PMGNTRK,3003.731,N,09136.621,W,00001,M,170621.25,A,,250502*6A +$PMGNTRK,3003.767,N,09136.634,W,00000,M,170955.19,A,,250502*6F +$PMGNTRK,3003.762,N,09136.496,W,00000,M,171200.20,A,,250502*60 +$PMGNTRK,3003.740,N,09136.443,W,00000,M,171248.75,A,,250502*64 +$PMGNTRK,3003.692,N,09136.317,W,00000,M,171441.20,A,,250502*63 +$PMGNTRK,3003.587,N,09135.964,W,00000,M,171716.20,A,,250502*68 +$PMGNTRK,3003.468,N,09135.801,W,00000,M,171746.20,A,,250502*6F +$PMGNTRK,3003.323,N,09135.694,W,00000,M,171820.81,A,,250502*61 +$PMGNTRK,3003.233,N,09135.557,W,00000,M,171901.20,A,,250502*64 +$PMGNTRK,3002.984,N,09135.385,W,00000,M,172046.25,A,,250502*67 +$PMGNTRK,3002.941,N,09135.393,W,00000,M,172110.25,A,,250502*6B +$PMGNTRK,3002.928,N,09135.576,W,00000,M,172151.37,A,,250502*6F +$PMGNTRK,3002.774,N,09135.787,W,00000,M,172235.20,A,,250502*63 +$PMGNTRK,3002.731,N,09135.923,W,00000,M,172308.56,A,,250502*6C +$PMGNTRK,3002.838,N,09136.016,W,00000,M,180423.93,A,,250502*6C +$PMGNTRK,3002.820,N,09135.978,W,00002,M,180604.92,A,,250502*63 +$PMGNTRK,3002.786,N,09135.968,W,00000,M,180706.92,A,,250502*60 +$PMGNTRK,3002.772,N,09135.937,W,00001,M,180818.92,A,,250502*60 +$PMGNTRK,3002.782,N,09135.864,W,00000,M,181020.92,A,,250502*6B +$PMGNTRK,3002.781,N,09135.830,W,00000,M,181109.93,A,,250502*62 +$PMGNTRK,3002.807,N,09135.780,W,00000,M,181218.92,A,,250502*65 +$PMGNTRK,3002.847,N,09135.712,W,00000,M,181422.93,A,,250502*64 +$PMGNTRK,3002.868,N,09135.686,W,00002,M,181504.93,A,,250502*62 +$PMGNTRK,3002.895,N,09135.645,W,00001,M,181614.93,A,,250502*6E +$PMGNTRK,3002.921,N,09135.628,W,00001,M,181701.93,A,,250502*6E +$PMGNTRK,3002.961,N,09135.631,W,00000,M,181807.94,A,,250502*6D +$PMGNTRK,3003.019,N,09135.639,W,00002,M,181951.94,A,,250502*62 +$PMGNTRK,3003.047,N,09135.647,W,00000,M,182039.94,A,,250502*66 +$PMGNTRK,3003.074,N,09135.662,W,00000,M,182124.93,A,,250502*6B +$PMGNTRK,3003.108,N,09135.662,W,00000,M,182217.94,A,,250502*65 +$PMGNTRK,3003.133,N,09135.680,W,00000,M,182318.93,A,,250502*68 +$PMGNTRK,3003.181,N,09135.681,W,00000,M,182437.94,A,,250502*6D +$PMGNTRK,3003.292,N,09135.712,W,00006,M,182813.95,A,,250502*6A +$PMGNTRK,3003.224,N,09135.696,W,00002,M,183136.94,A,,250502*60 +$PMGNTRK,3003.191,N,09135.687,W,00000,M,183256.95,A,,250502*6B +$PMGNTRK,3003.158,N,09135.690,W,00000,M,183402.95,A,,250502*6F +$PMGNTRK,3003.147,N,09135.726,W,00000,M,183603.95,A,,250502*6E +$PMGNTRK,3003.149,N,09135.758,W,00000,M,183648.96,A,,250502*65 +$PMGNTRK,3003.159,N,09135.807,W,00001,M,183752.96,A,,250502*6A +$PMGNTRK,3003.188,N,09135.871,W,00000,M,183918.95,A,,250502*65 +$PMGNTRK,3003.217,N,09135.878,W,00000,M,184015.96,A,,250502*69 +$PMGNTRK,3003.238,N,09135.866,W,00006,M,184125.96,A,,250502*6F +$PMGNTRK,3003.217,N,09135.885,W,00000,M,184237.96,A,,250502*69 +$PMGNTRK,3003.192,N,09135.875,W,00000,M,184401.96,A,,250502*6B +$PMGNTRK,3003.169,N,09135.851,W,00000,M,184553.96,A,,250502*6F +$PMGNTRK,3003.154,N,09135.816,W,00000,M,184654.96,A,,250502*66 +$PMGNTRK,3003.140,N,09135.786,W,00000,M,184742.97,A,,250502*62 +$PMGNTRK,3003.135,N,09135.741,W,00000,M,184841.96,A,,250502*66 +$PMGNTRK,3003.133,N,09135.701,W,00000,M,184952.97,A,,250502*66 +$PMGNTRK,3003.113,N,09135.682,W,00000,M,185049.97,A,,250502*6C +$PMGNTRK,3003.063,N,09135.664,W,00000,M,185214.97,A,,250502*68 +$PMGNTRK,3003.034,N,09135.654,W,00000,M,185256.98,A,,250502*60 +$PMGNTRK,3003.011,N,09135.646,W,00000,M,185338.98,A,,250502*6D +$PMGNTRK,3002.946,N,09135.623,W,00000,M,185511.97,A,,250502*66 +$PMGNTRK,3002.907,N,09135.655,W,00000,M,185632.98,A,,250502*6F +$PMGNTRK,3002.885,N,09135.685,W,00000,M,185724.97,A,,250502*60 +$PMGNTRK,3002.850,N,09135.727,W,00007,M,185840.98,A,,250502*64 +$PMGNTRK,3002.824,N,09135.760,W,00000,M,185928.98,A,,250502*6C +$PMGNTRK,3002.798,N,09135.796,W,00000,M,190022.98,A,,250502*6A +$PMGNTRK,3002.784,N,09135.859,W,00000,M,190141.98,A,,250502*6F +$PMGNTRK,3002.774,N,09135.908,W,00000,M,190248.99,A,,250502*6E +$PMGNTRK,3002.779,N,09135.938,W,00000,M,190343.98,A,,250502*6B +$PMGNTRK,3002.807,N,09135.957,W,00000,M,190449.99,A,,250502*68 +$PMGNTRK,3002.828,N,09135.980,W,00000,M,190557.98,A,,250502*60 diff --git a/reference/track/mps-track.mps b/reference/track/mps-track.mps new file mode 100644 index 0000000000000000000000000000000000000000..9889d176a9e0d4a4a0da4960e88a8cd7714bb9f8 GIT binary patch literal 2056 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 Br=9=+ literal 0 HcmV?d00001 diff --git a/reference/track/mtk_logger.csv b/reference/track/mtk_logger.csv new file mode 100644 index 000000000..22e809aaf --- /dev/null +++ b/reference/track/mtk_logger.csv @@ -0,0 +1,818 @@ +INDEX,RCR,DATE,TIME,VALID,LATITUDE,N/S,LONGITUDE,E/W,HEIGHT,SPEED,HEADING,NSAT (USED/VIEW),DISTANCE, +1,T,2008/01/27,13:03:22.836,No fix,57.719581,N,12.016372,E,98.470 m,0.000 km/h,0.000000,0(7), 0.00 m, +2,B,2008/01/27,13:03:24.836,No fix,57.719581,N,12.016372,E,98.470 m,0.000 km/h,0.000000,0(9), 0.00 m, +3,T,2008/01/27,14:13:51.012,No fix,57.719581,N,12.016372,E,98.470 m,0.000 km/h,0.000000,0(0), 0.00 m, +4,T,2008/01/27,14:13:56.812,No fix,57.719581,N,12.016372,E,98.470 m,0.000 km/h,0.000000,0(5), 0.00 m, +5,T,2008/01/27,14:14:01.812,No fix,57.719581,N,12.016372,E,98.470 m,0.000 km/h,0.000000,0(10), 0.00 m, +6,T,2008/01/27,14:14:07.532,No fix,57.719581,N,12.016372,E,98.470 m,0.000 km/h,0.000000,0(9), 0.00 m, +7,T,2008/01/27,14:14:12.532,No fix,57.719581,N,12.016372,E,98.470 m,0.000 km/h,0.000000,0(9), 0.00 m, +8,T,2008/01/27,14:14:17.532,No fix,57.719581,N,12.016372,E,98.470 m,0.000 km/h,0.000000,0(10), 0.00 m, +9,T,2008/01/27,14:14:22.532,No fix,57.719581,N,12.016372,E,98.470 m,0.000 km/h,0.000000,0(10), 0.00 m, +10,T,2008/01/27,14:14:27.532,No fix,57.719581,N,12.016372,E,98.470 m,0.000 km/h,0.000000,0(9), 0.00 m, +11,D,2008/01/27,14:14:28.531,No fix,57.705089,N,11.996373,E,98.409 m,2.142 km/h,0.000000,2(9), 2006.55 m, +12,T,2008/01/27,14:14:34.000,No fix,57.704939,N,11.996336,E,98.469 m,1.093 km/h,0.000000,2(9), 16.80 m, +13,D,2008/01/27,14:14:35.000,SPS,57.707240,N,11.967281,E,22.480 m,4.329 km/h,0.000000,6(9), 1752.68 m, +14,T,2008/01/27,14:14:40.000,SPS,57.707220,N,11.967151,E,32.486 m,3.883 km/h,0.000000,6(9), 12.87 m, +15,T,2008/01/27,14:14:45.000,SPS,57.707209,N,11.967053,E,34.286 m,3.788 km/h,0.000000,8(9), 6.24 m, +16,T,2008/01/27,14:14:50.000,SPS,57.707201,N,11.966970,E,33.626 m,3.570 km/h,0.000000,8(9), 5.06 m, +17,T,2008/01/27,14:14:55.000,SPS,57.707198,N,11.966948,E,34.133 m,1.588 km/h,0.000000,8(9), 1.44 m, +18,T,2008/01/27,14:15:00.000,SPS,57.707199,N,11.966980,E,34.461 m,2.094 km/h,0.000000,8(9), 1.98 m, +19,T,2008/01/27,14:15:05.000,SPS,57.707202,N,11.966988,E,34.240 m,0.301 km/h,0.000000,9(9), 0.63 m, +20,B,2008/01/27,14:15:09.000,SPS,57.707192,N,11.967000,E,34.320 m,1.198 km/h,0.000000,8(9), 1.35 m, +21,T,2008/01/27,14:15:14.000,SPS,57.707180,N,11.967054,E,34.183 m,1.906 km/h,0.000000,8(9), 3.51 m, +22,T,2008/01/27,14:15:19.000,SPS,57.707141,N,11.967152,E,34.389 m,4.819 km/h,0.000000,9(9), 7.29 m, +23,T,2008/01/27,14:15:24.000,SPS,57.707082,N,11.967244,E,34.793 m,5.849 km/h,0.000000,9(9), 8.58 m, +24,T,2008/01/27,14:15:29.000,SPS,57.707028,N,11.967342,E,35.034 m,5.930 km/h,0.000000,9(9), 8.39 m, +25,T,2008/01/27,14:15:34.000,SPS,57.706993,N,11.967462,E,35.394 m,4.971 km/h,0.000000,9(9), 8.13 m, +26,T,2008/01/27,14:15:39.000,SPS,57.706920,N,11.967556,E,34.952 m,6.284 km/h,145.024078,9(9), 9.85 m, +27,T,2008/01/27,14:15:44.000,SPS,57.706865,N,11.967651,E,36.921 m,6.656 km/h,142.223740,8(9), 8.65 m, +28,T,2008/01/27,14:15:49.000,SPS,57.706812,N,11.967756,E,36.359 m,5.452 km/h,144.998688,8(9), 8.56 m, +29,T,2008/01/27,14:15:54.000,SPS,57.706746,N,11.967810,E,35.562 m,4.889 km/h,144.998688,9(9), 8.04 m, +30,T,2008/01/27,14:15:59.000,SPS,57.706677,N,11.967837,E,35.367 m,4.960 km/h,144.998688,9(9), 7.91 m, +31,T,2008/01/27,14:16:04.000,SPS,57.706618,N,11.967878,E,35.278 m,5.648 km/h,144.998688,9(9), 6.99 m, +32,T,2008/01/27,14:16:09.000,SPS,57.706547,N,11.967903,E,34.554 m,5.879 km/h,144.998688,9(9), 8.03 m, +33,T,2008/01/27,14:16:14.000,SPS,57.706513,N,11.967905,E,35.263 m,0.183 km/h,144.998688,9(9), 3.86 m, +34,T,2008/01/27,14:16:19.000,SPS,57.706515,N,11.967900,E,35.184 m,1.538 km/h,144.998688,8(9), 0.37 m, +35,T,2008/01/27,14:16:24.000,SPS,57.706515,N,11.967898,E,35.184 m,0.110 km/h,144.998688,8(9), 0.11 m, +36,T,2008/01/27,14:16:29.000,SPS,57.706514,N,11.967898,E,35.194 m,0.015 km/h,144.998688,8(9), 0.04 m, +37,T,2008/01/27,14:16:34.000,SPS,57.706514,N,11.967898,E,35.194 m,0.028 km/h,144.998688,9(9), 0.04 m, +38,T,2008/01/27,14:16:39.000,SPS,57.706513,N,11.967898,E,35.195 m,0.032 km/h,144.998688,8(9), 0.08 m, +39,T,2008/01/27,14:16:44.000,SPS,57.706493,N,11.967904,E,35.155 m,5.219 km/h,144.998688,8(9), 2.31 m, +40,T,2008/01/27,14:16:49.000,SPS,57.706432,N,11.967966,E,36.225 m,5.103 km/h,148.006943,7(9), 7.81 m, +41,T,2008/01/27,14:16:54.000,SPS,57.706373,N,11.968041,E,35.693 m,4.740 km/h,145.174026,9(9), 7.94 m, +42,T,2008/01/27,14:16:59.000,SPS,57.706330,N,11.968089,E,36.124 m,2.401 km/h,145.174026,9(9), 5.62 m, +43,T,2008/01/27,14:17:04.000,SPS,57.706291,N,11.968096,E,34.865 m,1.065 km/h,145.174026,8(9), 4.55 m, +44,T,2008/01/27,14:17:09.000,SPS,57.706252,N,11.968083,E,34.707 m,2.964 km/h,145.174026,9(9), 4.39 m, +45,T,2008/01/27,14:17:14.000,SPS,57.706197,N,11.968102,E,35.035 m,5.348 km/h,145.174026,8(9), 6.24 m, +46,T,2008/01/27,14:17:19.000,SPS,57.706132,N,11.968132,E,35.846 m,3.733 km/h,145.174026,9(9), 7.54 m, +47,T,2008/01/27,14:17:24.000,SPS,57.706048,N,11.968163,E,36.723 m,7.332 km/h,193.604065,9(9), 9.51 m, +48,T,2008/01/27,14:17:29.000,SPS,57.706021,N,11.968163,E,36.816 m,0.122 km/h,193.604065,9(9), 3.08 m, +49,T,2008/01/27,14:17:34.000,SPS,57.706023,N,11.968161,E,36.775 m,0.368 km/h,193.604065,9(9), 0.25 m, +50,T,2008/01/27,14:17:39.000,SPS,57.706017,N,11.968170,E,36.756 m,1.212 km/h,193.604065,8(9), 0.80 m, +51,T,2008/01/27,14:17:44.000,SPS,57.706005,N,11.968188,E,36.742 m,1.749 km/h,193.604065,9(9), 1.75 m, +52,T,2008/01/27,14:17:49.000,SPS,57.705990,N,11.968206,E,36.740 m,0.692 km/h,193.604065,9(9), 1.97 m, +53,T,2008/01/27,14:17:54.000,SPS,57.706007,N,11.968194,E,36.763 m,3.844 km/h,193.604065,7(9), 1.99 m, +54,T,2008/01/27,14:17:59.000,SPS,57.706115,N,11.968266,E,36.768 m,8.742 km/h,351.843750,8(9), 12.76 m, +55,T,2008/01/27,14:18:04.000,SPS,57.706186,N,11.968516,E,37.723 m,0.918 km/h,2.294798,7(9), 16.95 m, +56,T,2008/01/27,14:18:09.000,SPS,57.706125,N,11.968584,E,38.271 m,2.661 km/h,2.294798,9(9), 7.88 m, +57,T,2008/01/27,14:18:14.000,SPS,57.706084,N,11.968609,E,39.401 m,5.108 km/h,2.294798,9(9), 4.95 m, +58,T,2008/01/27,14:18:19.000,SPS,57.705972,N,11.968670,E,42.658 m,4.392 km/h,2.294798,9(9), 13.37 m, +59,T,2008/01/27,14:18:24.000,SPS,57.705860,N,11.968734,E,44.571 m,4.576 km/h,143.381439,9(9), 13.18 m, +60,T,2008/01/27,14:18:29.000,SPS,57.705777,N,11.968797,E,46.084 m,5.476 km/h,143.381439,9(9), 10.11 m, +61,T,2008/01/27,14:18:34.000,SPS,57.705688,N,11.968830,E,47.522 m,4.338 km/h,143.381439,9(9), 10.22 m, +62,T,2008/01/27,14:18:39.000,SPS,57.705562,N,11.968854,E,46.846 m,5.019 km/h,140.877411,9(9), 14.09 m, +63,T,2008/01/27,14:18:44.000,SPS,57.705429,N,11.968857,E,42.744 m,4.944 km/h,140.877411,9(9), 15.41 m, +64,T,2008/01/27,14:18:49.000,SPS,57.705335,N,11.968908,E,41.074 m,7.019 km/h,140.877411,7(9), 10.98 m, +65,T,2008/01/27,14:18:54.000,SPS,57.705285,N,11.968814,E,53.912 m,3.695 km/h,142.614777,9(9), 15.06 m, +66,T,2008/01/27,14:18:59.000,SPS,57.705250,N,11.968786,E,57.604 m,4.404 km/h,142.614777,9(9), 5.66 m, +67,T,2008/01/27,14:19:04.000,SPS,57.705181,N,11.968788,E,59.425 m,6.306 km/h,144.389893,9(9), 7.95 m, +68,T,2008/01/27,14:19:09.000,SPS,57.705107,N,11.968813,E,59.241 m,4.660 km/h,144.389893,8(9), 8.30 m, +69,T,2008/01/27,14:19:14.000,SPS,57.705027,N,11.968819,E,56.956 m,5.931 km/h,144.389893,7(9), 9.26 m, +70,T,2008/01/27,14:19:19.000,SPS,57.704951,N,11.968824,E,55.168 m,5.787 km/h,144.389893,8(9), 8.68 m, +71,T,2008/01/27,14:19:24.000,SPS,57.704891,N,11.968841,E,52.904 m,4.115 km/h,142.798004,8(9), 7.03 m, +72,T,2008/01/27,14:19:29.000,SPS,57.704841,N,11.968864,E,52.243 m,4.262 km/h,142.798004,9(9), 5.81 m, +73,T,2008/01/27,14:19:34.000,SPS,57.704798,N,11.968902,E,53.329 m,2.691 km/h,142.798004,9(9), 5.37 m, +74,T,2008/01/27,14:19:39.000,SPS,57.704765,N,11.968933,E,51.154 m,5.018 km/h,142.798004,9(9), 4.67 m, +75,T,2008/01/27,14:19:44.000,SPS,57.704710,N,11.969006,E,50.982 m,2.045 km/h,142.061447,9(9), 7.50 m, +76,T,2008/01/27,14:19:49.000,SPS,57.704649,N,11.969040,E,50.857 m,4.554 km/h,142.061447,7(9), 7.13 m, +77,T,2008/01/27,14:19:54.000,SPS,57.704526,N,11.969103,E,49.896 m,5.752 km/h,142.061447,8(9), 14.23 m, +78,T,2008/01/27,14:19:59.000,SPS,57.704421,N,11.969262,E,46.709 m,5.609 km/h,152.146713,8(9), 15.37 m, +79,T,2008/01/27,14:20:04.000,SPS,57.704347,N,11.969332,E,43.882 m,5.225 km/h,153.529343,8(9), 9.72 m, +80,T,2008/01/27,14:20:09.000,SPS,57.704288,N,11.969264,E,41.683 m,6.420 km/h,153.529343,8(9), 7.98 m, +81,T,2008/01/27,14:20:14.000,SPS,57.704252,N,11.969200,E,42.077 m,4.191 km/h,153.663147,9(9), 5.56 m, +82,T,2008/01/27,14:20:19.000,SPS,57.704213,N,11.969243,E,40.520 m,5.118 km/h,153.663147,8(9), 5.32 m, +83,T,2008/01/27,14:20:24.000,SPS,57.704157,N,11.969264,E,40.441 m,5.823 km/h,150.640991,9(9), 6.31 m, +84,T,2008/01/27,14:20:29.000,SPS,57.704116,N,11.969269,E,38.741 m,5.815 km/h,150.640991,8(9), 4.92 m, +85,T,2008/01/27,14:20:34.000,SPS,57.704060,N,11.969300,E,40.093 m,5.564 km/h,149.428802,8(9), 6.58 m, +86,T,2008/01/27,14:20:39.000,SPS,57.704002,N,11.969344,E,43.700 m,6.179 km/h,149.875687,9(9), 7.87 m, +87,T,2008/01/27,14:20:44.000,SPS,57.703946,N,11.969419,E,45.619 m,4.620 km/h,152.252014,9(9), 7.91 m, +88,T,2008/01/27,14:20:49.000,SPS,57.703873,N,11.969494,E,45.383 m,6.091 km/h,152.252014,8(9), 9.30 m, +89,T,2008/01/27,14:20:54.000,SPS,57.703825,N,11.969620,E,43.774 m,5.070 km/h,152.252014,8(9), 9.38 m, +90,T,2008/01/27,14:20:59.000,SPS,57.703769,N,11.969732,E,42.711 m,5.157 km/h,149.309753,8(9), 9.21 m, +91,T,2008/01/27,14:21:04.000,SPS,57.703739,N,11.969839,E,41.588 m,5.432 km/h,149.309753,9(9), 7.24 m, +92,T,2008/01/27,14:21:09.000,SPS,57.703712,N,11.969976,E,39.019 m,5.650 km/h,149.309753,9(9), 9.08 m, +93,T,2008/01/27,14:21:14.000,SPS,57.703658,N,11.970097,E,37.535 m,4.592 km/h,149.309753,8(9), 9.54 m, +94,T,2008/01/27,14:21:19.000,SPS,57.703608,N,11.970196,E,37.183 m,6.357 km/h,149.309753,9(9), 8.09 m, +95,T,2008/01/27,14:21:24.000,SPS,57.703553,N,11.970282,E,35.910 m,5.320 km/h,145.645874,9(9), 8.12 m, +96,T,2008/01/27,14:21:29.000,SPS,57.703497,N,11.970365,E,36.647 m,5.556 km/h,148.902954,9(9), 7.97 m, +97,T,2008/01/27,14:21:34.000,SPS,57.703448,N,11.970437,E,35.836 m,4.999 km/h,144.122391,9(9), 7.03 m, +98,T,2008/01/27,14:21:39.000,SPS,57.703386,N,11.970510,E,35.017 m,5.919 km/h,146.880249,9(9), 8.14 m, +99,T,2008/01/27,14:21:44.000,SPS,57.703320,N,11.970583,E,35.753 m,6.228 km/h,148.921082,9(9), 8.58 m, +100,T,2008/01/27,14:21:49.000,SPS,57.703252,N,11.970652,E,35.331 m,5.456 km/h,150.968842,9(9), 8.67 m, +101,T,2008/01/27,14:21:54.000,SPS,57.703203,N,11.970722,E,36.076 m,6.625 km/h,150.968842,9(9), 6.88 m, +102,T,2008/01/27,14:21:59.000,SPS,57.703141,N,11.970776,E,35.706 m,4.944 km/h,148.422119,9(9), 7.61 m, +103,T,2008/01/27,14:22:04.000,SPS,57.703072,N,11.970804,E,35.922 m,5.725 km/h,148.422119,9(9), 7.88 m, +104,T,2008/01/27,14:22:09.000,SPS,57.703020,N,11.970877,E,36.545 m,5.074 km/h,151.107529,9(9), 7.31 m, +105,T,2008/01/27,14:22:14.000,SPS,57.702966,N,11.970964,E,36.327 m,5.598 km/h,151.107529,9(9), 7.94 m, +106,T,2008/01/27,14:22:19.000,SPS,57.702906,N,11.971040,E,37.919 m,6.304 km/h,151.477859,9(9), 8.26 m, +107,T,2008/01/27,14:22:24.000,SPS,57.702841,N,11.971125,E,37.317 m,5.482 km/h,151.477859,8(9), 8.84 m, +108,T,2008/01/27,14:22:29.000,SPS,57.702774,N,11.971215,E,37.531 m,6.173 km/h,151.477859,9(9), 9.20 m, +109,T,2008/01/27,14:22:34.000,SPS,57.702716,N,11.971303,E,36.046 m,5.410 km/h,152.840408,9(9), 8.41 m, +110,T,2008/01/27,14:22:39.000,SPS,57.702654,N,11.971376,E,35.769 m,4.778 km/h,149.361832,9(9), 8.17 m, +111,T,2008/01/27,14:22:44.000,SPS,57.702598,N,11.971460,E,36.368 m,6.357 km/h,152.900650,9(9), 8.01 m, +112,T,2008/01/27,14:22:49.000,SPS,57.702544,N,11.971540,E,36.279 m,5.471 km/h,151.154800,9(9), 7.70 m, +113,T,2008/01/27,14:22:54.000,SPS,57.702491,N,11.971608,E,36.259 m,4.905 km/h,147.538422,9(9), 7.17 m, +114,T,2008/01/27,14:22:59.000,SPS,57.702441,N,11.971678,E,37.068 m,5.114 km/h,147.538422,9(9), 6.97 m, +115,T,2008/01/27,14:23:04.000,SPS,57.702397,N,11.971745,E,37.291 m,4.761 km/h,147.538422,9(9), 6.40 m, +116,T,2008/01/27,14:23:09.000,SPS,57.702389,N,11.971776,E,36.768 m,0.013 km/h,147.538422,9(9), 2.11 m, +117,T,2008/01/27,14:23:14.000,SPS,57.702389,N,11.971776,E,36.757 m,0.020 km/h,147.538422,9(9), 0.01 m, +118,T,2008/01/27,14:23:19.000,SPS,57.702387,N,11.971779,E,36.756 m,1.288 km/h,147.538422,9(9), 0.24 m, +119,T,2008/01/27,14:23:24.000,SPS,57.702382,N,11.971772,E,36.850 m,0.031 km/h,147.538422,9(9), 0.71 m, +120,T,2008/01/27,14:23:29.000,SPS,57.702360,N,11.971813,E,36.804 m,5.462 km/h,147.397430,9(9), 3.48 m, +121,T,2008/01/27,14:23:34.000,SPS,57.702310,N,11.971900,E,37.637 m,6.343 km/h,146.144302,9(9), 7.60 m, +122,T,2008/01/27,14:23:39.000,SPS,57.702262,N,11.971989,E,37.109 m,5.282 km/h,146.144302,9(9), 7.56 m, +123,T,2008/01/27,14:23:44.000,SPS,57.702205,N,11.972077,E,36.777 m,5.387 km/h,142.318588,9(9), 8.29 m, +124,T,2008/01/27,14:23:49.000,SPS,57.702167,N,11.972155,E,36.541 m,4.789 km/h,141.388947,9(9), 6.28 m, +125,T,2008/01/27,14:23:54.000,SPS,57.702114,N,11.972225,E,37.536 m,4.316 km/h,143.495270,9(9), 7.25 m, +126,T,2008/01/27,14:23:59.000,SPS,57.702075,N,11.972305,E,38.683 m,3.844 km/h,143.495270,9(9), 6.61 m, +127,T,2008/01/27,14:24:04.000,SPS,57.702031,N,11.972358,E,40.180 m,5.849 km/h,143.495270,8(9), 6.05 m, +128,T,2008/01/27,14:24:09.000,SPS,57.702005,N,11.972405,E,40.464 m,2.516 km/h,143.495270,8(9), 4.01 m, +129,T,2008/01/27,14:24:14.000,SPS,57.701941,N,11.972475,E,40.150 m,4.882 km/h,142.500504,8(9), 8.26 m, +130,T,2008/01/27,14:24:19.000,SPS,57.701902,N,11.972565,E,41.289 m,4.514 km/h,142.500504,9(9), 6.97 m, +131,T,2008/01/27,14:24:24.000,SPS,57.701854,N,11.972631,E,43.597 m,5.178 km/h,142.500504,8(9), 7.07 m, +132,T,2008/01/27,14:24:29.000,SPS,57.701806,N,11.972704,E,45.537 m,5.645 km/h,144.574066,9(9), 7.15 m, +133,T,2008/01/27,14:24:34.000,SPS,57.701765,N,11.972797,E,46.518 m,4.432 km/h,144.574066,9(9), 7.27 m, +134,T,2008/01/27,14:24:39.000,SPS,57.701719,N,11.972896,E,47.777 m,4.439 km/h,144.574066,9(9), 7.91 m, +135,T,2008/01/27,14:24:44.000,SPS,57.701652,N,11.972960,E,47.737 m,5.667 km/h,139.446564,9(9), 8.37 m, +136,T,2008/01/27,14:24:49.000,SPS,57.701602,N,11.973009,E,48.639 m,6.125 km/h,139.909683,7(9), 6.38 m, +137,T,2008/01/27,14:24:54.000,SPS,57.701564,N,11.973088,E,49.968 m,4.705 km/h,139.909683,8(9), 6.46 m, +138,T,2008/01/27,14:24:59.000,SPS,57.701515,N,11.973171,E,52.496 m,4.574 km/h,140.883011,8(9), 7.81 m, +139,T,2008/01/27,14:25:04.000,SPS,57.701465,N,11.973252,E,55.388 m,6.149 km/h,142.145920,8(9), 7.89 m, +140,T,2008/01/27,14:25:09.000,SPS,57.701428,N,11.973333,E,57.299 m,4.935 km/h,141.485916,8(9), 6.64 m, +141,T,2008/01/27,14:25:14.000,SPS,57.701378,N,11.973416,E,58.615 m,4.705 km/h,139.331635,8(9), 7.51 m, +142,T,2008/01/27,14:25:19.000,SPS,57.701333,N,11.973495,E,61.027 m,3.944 km/h,140.293564,8(9), 7.27 m, +143,T,2008/01/27,14:25:24.000,SPS,57.701295,N,11.973585,E,63.131 m,6.009 km/h,142.518753,8(9), 7.20 m, +144,T,2008/01/27,14:25:29.000,SPS,57.701252,N,11.973650,E,64.942 m,4.910 km/h,142.518753,8(9), 6.38 m, +145,T,2008/01/27,14:25:34.000,SPS,57.701196,N,11.973733,E,65.995 m,5.170 km/h,143.172440,8(9), 8.10 m, +146,T,2008/01/27,14:25:39.000,SPS,57.701145,N,11.973814,E,66.960 m,6.035 km/h,143.604630,8(9), 7.53 m, +147,T,2008/01/27,14:25:44.000,SPS,57.701097,N,11.973898,E,66.496 m,5.760 km/h,143.604630,8(9), 7.31 m, +148,T,2008/01/27,14:25:49.000,SPS,57.701038,N,11.973964,E,66.285 m,4.407 km/h,144.729324,8(9), 7.62 m, +149,T,2008/01/27,14:25:54.000,SPS,57.700892,N,11.974022,E,54.864 m,5.331 km/h,141.792358,8(9), 20.22 m, +150,T,2008/01/27,14:25:59.000,SPS,57.700807,N,11.974077,E,49.539 m,4.924 km/h,141.792358,8(9), 11.29 m, +151,T,2008/01/27,14:26:04.000,SPS,57.700763,N,11.974153,E,48.266 m,5.889 km/h,138.983597,8(9), 6.84 m, +152,T,2008/01/27,14:26:09.000,SPS,57.700702,N,11.974227,E,46.362 m,7.215 km/h,154.235672,8(9), 8.34 m, +153,T,2008/01/27,14:26:14.000,SPS,57.700652,N,11.974287,E,45.062 m,5.653 km/h,152.009735,7(9), 6.70 m, +154,T,2008/01/27,14:26:19.000,SPS,57.700596,N,11.974367,E,45.015 m,4.898 km/h,152.009735,8(9), 7.86 m, +155,T,2008/01/27,14:26:24.000,SPS,57.700539,N,11.974445,E,46.408 m,5.194 km/h,146.927551,8(9), 8.01 m, +156,T,2008/01/27,14:26:29.000,SPS,57.700501,N,11.974528,E,48.432 m,5.674 km/h,144.441391,8(9), 6.77 m, +157,T,2008/01/27,14:26:34.000,SPS,57.700449,N,11.974601,E,50.567 m,4.294 km/h,148.208267,8(9), 7.54 m, +158,T,2008/01/27,14:26:39.000,SPS,57.700399,N,11.974682,E,51.603 m,4.031 km/h,148.208267,8(9), 7.50 m, +159,T,2008/01/27,14:26:44.000,SPS,57.700365,N,11.974767,E,53.746 m,5.657 km/h,148.208267,8(9), 6.70 m, +160,T,2008/01/27,14:26:49.000,SPS,57.700316,N,11.974832,E,56.361 m,5.684 km/h,148.971863,8(9), 7.15 m, +161,T,2008/01/27,14:26:54.000,SPS,57.700283,N,11.974908,E,58.788 m,4.602 km/h,146.601395,8(9), 6.32 m, +162,T,2008/01/27,14:26:59.000,SPS,57.700240,N,11.975000,E,60.958 m,4.184 km/h,148.007050,9(9), 7.60 m, +163,T,2008/01/27,14:27:04.000,SPS,57.700172,N,11.975046,E,63.890 m,5.937 km/h,148.007050,9(9), 8.53 m, +164,T,2008/01/27,14:27:09.000,SPS,57.700144,N,11.975124,E,67.956 m,4.641 km/h,149.515228,8(9), 6.93 m, +165,T,2008/01/27,14:27:14.000,SPS,57.700103,N,11.975198,E,71.879 m,5.623 km/h,149.515228,9(9), 7.50 m, +166,T,2008/01/27,14:27:19.000,SPS,57.700063,N,11.975268,E,74.786 m,4.700 km/h,149.515228,9(9), 6.71 m, +167,T,2008/01/27,14:27:24.000,SPS,57.700010,N,11.975334,E,77.087 m,4.305 km/h,149.515228,8(9), 7.51 m, +168,T,2008/01/27,14:27:29.000,SPS,57.699976,N,11.975421,E,78.694 m,3.675 km/h,147.837906,8(9), 6.59 m, +169,T,2008/01/27,14:27:34.000,SPS,57.699933,N,11.975551,E,74.407 m,3.268 km/h,147.837906,9(9), 10.09 m, +170,T,2008/01/27,14:27:39.000,SPS,57.699861,N,11.975623,E,70.901 m,5.284 km/h,147.837906,7(9), 9.79 m, +171,T,2008/01/27,14:27:44.000,SPS,57.699766,N,11.975627,E,69.342 m,5.455 km/h,148.045532,7(9), 10.70 m, +172,T,2008/01/27,14:27:49.000,SPS,57.699714,N,11.975701,E,69.503 m,4.288 km/h,148.045532,9(9), 7.31 m, +173,T,2008/01/27,14:27:54.000,SPS,57.699677,N,11.975772,E,74.143 m,4.658 km/h,148.045532,8(9), 7.48 m, +174,T,2008/01/27,14:27:59.000,SPS,57.699630,N,11.975831,E,77.762 m,4.690 km/h,146.587997,8(9), 7.31 m, +175,T,2008/01/27,14:28:04.000,SPS,57.699587,N,11.975906,E,82.255 m,4.369 km/h,146.587997,9(9), 7.91 m, +176,T,2008/01/27,14:28:09.000,SPS,57.699523,N,11.975945,E,86.903 m,4.164 km/h,146.587997,9(9), 8.87 m, +177,T,2008/01/27,14:28:14.000,SPS,57.699489,N,11.976030,E,91.039 m,2.754 km/h,146.587997,9(9), 7.56 m, +178,T,2008/01/27,14:28:19.000,SPS,57.699445,N,11.976073,E,95.987 m,5.104 km/h,146.587997,8(9), 7.43 m, +179,T,2008/01/27,14:28:24.000,SPS,57.699389,N,11.976112,E,101.368 m,4.419 km/h,146.587997,8(9), 8.55 m, +180,T,2008/01/27,14:28:29.000,SPS,57.699329,N,11.976171,E,108.444 m,3.853 km/h,148.233871,9(9), 10.36 m, +181,T,2008/01/27,14:28:34.000,SPS,57.699294,N,11.976244,E,112.981 m,2.953 km/h,148.233871,8(9), 7.40 m, +182,T,2008/01/27,14:28:39.000,SPS,57.699264,N,11.976337,E,119.031 m,2.642 km/h,150.412949,8(9), 8.88 m, +183,T,2008/01/27,14:28:44.000,SPS,57.699210,N,11.976447,E,124.016 m,3.473 km/h,150.412949,8(9), 10.16 m, +184,T,2008/01/27,14:28:49.000,SPS,57.699173,N,11.976573,E,128.919 m,5.681 km/h,149.867859,9(9), 9.84 m, +185,T,2008/01/27,14:28:54.000,SPS,57.699139,N,11.976670,E,135.981 m,3.088 km/h,149.867859,9(9), 9.92 m, +186,T,2008/01/27,14:28:59.000,SPS,57.699093,N,11.976753,E,142.061 m,5.294 km/h,152.427673,9(9), 9.35 m, +187,T,2008/01/27,14:29:04.000,SPS,57.699046,N,11.976873,E,145.621 m,4.161 km/h,152.427673,8(9), 9.55 m, +188,T,2008/01/27,14:29:09.000,SPS,57.698989,N,11.976973,E,147.339 m,4.649 km/h,152.427673,9(9), 8.89 m, +189,T,2008/01/27,14:29:14.000,SPS,57.698959,N,11.977002,E,147.915 m,1.062 km/h,152.427673,8(9), 3.76 m, +190,T,2008/01/27,14:29:19.000,SPS,57.698952,N,11.977011,E,149.006 m,0.663 km/h,152.427673,8(9), 1.47 m, +191,T,2008/01/27,14:29:24.000,SPS,57.698945,N,11.977021,E,149.275 m,0.836 km/h,152.427673,8(9), 1.02 m, +192,T,2008/01/27,14:29:29.000,SPS,57.698937,N,11.977026,E,149.182 m,0.762 km/h,152.427673,8(9), 0.91 m, +193,T,2008/01/27,14:29:34.000,SPS,57.698931,N,11.977031,E,148.906 m,0.273 km/h,152.427673,8(9), 0.79 m, +194,T,2008/01/27,14:29:39.000,SPS,57.698925,N,11.977038,E,148.810 m,4.308 km/h,152.427673,8(9), 0.86 m, +195,T,2008/01/27,14:29:44.000,SPS,57.698786,N,11.977053,E,135.016 m,3.069 km/h,152.427673,8(9), 20.74 m, +196,T,2008/01/27,14:29:49.000,SPS,57.698688,N,11.977180,E,127.507 m,2.269 km/h,151.834854,8(9), 15.23 m, +197,T,2008/01/27,14:29:54.000,SPS,57.698672,N,11.977273,E,125.575 m,3.602 km/h,151.834854,8(10), 6.10 m, +198,T,2008/01/27,14:29:59.000,SPS,57.698642,N,11.977302,E,124.096 m,2.652 km/h,151.834854,9(10), 4.06 m, +199,T,2008/01/27,14:30:04.000,SPS,57.698615,N,11.977346,E,125.293 m,5.561 km/h,151.834854,8(10), 4.18 m, +200,T,2008/01/27,14:30:09.000,SPS,57.698579,N,11.977430,E,126.160 m,5.967 km/h,151.834854,9(10), 6.51 m, +201,T,2008/01/27,14:30:14.000,SPS,57.698531,N,11.977506,E,126.889 m,4.460 km/h,151.834854,8(10), 7.01 m, +202,T,2008/01/27,14:30:19.000,SPS,57.698481,N,11.977542,E,127.783 m,4.184 km/h,151.834854,8(10), 6.06 m, +203,T,2008/01/27,14:30:24.000,SPS,57.698439,N,11.977617,E,127.161 m,1.893 km/h,151.834854,8(9), 6.46 m, +204,T,2008/01/27,14:30:29.000,SPS,57.698406,N,11.977693,E,127.212 m,3.030 km/h,151.709610,8(10), 5.83 m, +205,T,2008/01/27,14:30:34.000,SPS,57.698369,N,11.977842,E,122.670 m,3.823 km/h,150.292557,9(10), 10.84 m, +206,T,2008/01/27,14:30:39.000,SPS,57.698332,N,11.977959,E,119.508 m,4.297 km/h,150.292557,9(10), 8.67 m, +207,T,2008/01/27,14:30:44.000,SPS,57.698291,N,11.978065,E,118.257 m,3.208 km/h,152.138992,8(10), 7.88 m, +208,T,2008/01/27,14:30:49.000,SPS,57.698251,N,11.978478,E,114.823 m,5.848 km/h,152.138992,9(10), 25.29 m, +209,T,2008/01/27,14:30:54.000,SPS,57.698180,N,11.978644,E,109.670 m,4.343 km/h,152.138992,8(10), 13.60 m, +210,T,2008/01/27,14:30:59.000,SPS,57.698129,N,11.978757,E,105.506 m,5.529 km/h,151.187805,8(10), 9.81 m, +211,T,2008/01/27,14:31:04.000,SPS,57.698061,N,11.978835,E,103.666 m,4.856 km/h,149.160706,9(10), 9.04 m, +212,T,2008/01/27,14:31:09.000,SPS,57.697995,N,11.978816,E,105.252 m,4.680 km/h,147.681824,8(10), 7.65 m, +213,T,2008/01/27,14:31:14.000,SPS,57.697933,N,11.978762,E,106.092 m,4.216 km/h,147.681824,8(9), 7.67 m, +214,T,2008/01/27,14:31:19.000,SPS,57.697842,N,11.978776,E,104.700 m,6.214 km/h,147.681824,8(10), 10.29 m, +215,T,2008/01/27,14:31:24.000,SPS,57.697784,N,11.978808,E,104.697 m,4.608 km/h,147.681824,9(10), 6.75 m, +216,T,2008/01/27,14:31:29.000,SPS,57.697712,N,11.978872,E,106.038 m,4.529 km/h,144.817627,7(10), 8.91 m, +217,T,2008/01/27,14:31:34.000,SPS,57.697683,N,11.978893,E,103.740 m,5.686 km/h,143.690689,8(10), 4.15 m, +218,T,2008/01/27,14:31:39.000,SPS,57.697665,N,11.978943,E,100.028 m,3.866 km/h,143.690689,8(10), 5.17 m, +219,T,2008/01/27,14:31:44.000,SPS,57.697600,N,11.979012,E,96.331 m,5.607 km/h,171.598877,8(10), 9.04 m, +220,T,2008/01/27,14:31:49.000,SPS,57.697474,N,11.978969,E,89.905 m,7.039 km/h,175.468765,7(10), 15.68 m, +221,T,2008/01/27,14:31:54.000,SPS,57.697367,N,11.979000,E,84.427 m,4.651 km/h,175.468765,8(10), 13.23 m, +222,T,2008/01/27,14:31:59.000,SPS,57.697308,N,11.979088,E,83.601 m,5.585 km/h,175.468765,8(10), 8.48 m, +223,T,2008/01/27,14:32:04.000,SPS,57.697291,N,11.979184,E,86.593 m,4.621 km/h,175.468765,9(10), 6.70 m, +224,T,2008/01/27,14:32:09.000,SPS,57.697274,N,11.979310,E,89.465 m,5.419 km/h,175.468765,9(10), 8.25 m, +225,T,2008/01/27,14:32:14.000,SPS,57.697219,N,11.979413,E,87.774 m,4.181 km/h,175.468765,9(10), 8.90 m, +226,T,2008/01/27,14:32:19.000,SPS,57.697166,N,11.979434,E,95.693 m,3.918 km/h,175.468765,9(10), 9.92 m, +227,T,2008/01/27,14:32:24.000,SPS,57.697098,N,11.979491,E,92.201 m,1.306 km/h,175.468765,9(10), 9.03 m, +228,T,2008/01/27,14:32:29.000,SPS,57.697098,N,11.979481,E,95.843 m,1.357 km/h,175.468765,9(10), 3.70 m, +229,B,2008/01/27,14:32:31.000,SPS,57.697093,N,11.979470,E,96.421 m,1.226 km/h,175.468765,8(10), 0.98 m, +230,T,2008/01/27,14:32:36.000,SPS,57.697089,N,11.979459,E,97.553 m,0.348 km/h,175.468765,9(10), 1.38 m, +231,T,2008/01/27,14:32:41.000,SPS,57.697088,N,11.979459,E,97.998 m,0.744 km/h,175.468765,9(10), 0.46 m, +232,T,2008/01/27,14:32:46.000,SPS,57.697104,N,11.979504,E,96.478 m,3.837 km/h,175.468765,9(10), 3.54 m, +233,T,2008/01/27,14:32:51.000,SPS,57.697152,N,11.979574,E,89.553 m,4.436 km/h,175.468765,8(10), 9.69 m, +234,T,2008/01/27,14:32:56.000,SPS,57.697205,N,11.979565,E,83.425 m,4.382 km/h,175.468765,9(10), 8.53 m, +235,T,2008/01/27,14:33:01.000,SPS,57.697266,N,11.979543,E,79.043 m,5.017 km/h,175.468765,9(10), 8.14 m, +236,T,2008/01/27,14:33:06.000,SPS,57.697335,N,11.979517,E,75.905 m,6.258 km/h,175.468765,9(10), 8.55 m, +237,T,2008/01/27,14:33:11.000,SPS,57.697396,N,11.979553,E,72.991 m,6.059 km/h,175.468765,9(10), 7.68 m, +238,T,2008/01/27,14:33:16.000,SPS,57.697457,N,11.979552,E,69.763 m,4.282 km/h,175.468765,8(10), 7.51 m, +239,T,2008/01/27,14:33:21.000,SPS,57.697530,N,11.979501,E,64.874 m,5.514 km/h,175.468765,8(10), 9.92 m, +240,T,2008/01/27,14:33:26.000,SPS,57.697577,N,11.979440,E,61.687 m,4.860 km/h,175.468765,9(10), 7.16 m, +241,T,2008/01/27,14:33:31.000,SPS,57.697611,N,11.979335,E,60.879 m,6.522 km/h,175.468765,9(10), 7.37 m, +242,T,2008/01/27,14:33:36.000,SPS,57.697651,N,11.979255,E,60.912 m,4.865 km/h,175.468765,8(10), 6.51 m, +243,T,2008/01/27,14:33:41.000,SPS,57.697683,N,11.979185,E,61.899 m,4.418 km/h,175.468765,9(10), 5.60 m, +244,T,2008/01/27,14:33:46.000,SPS,57.697710,N,11.979115,E,64.165 m,5.755 km/h,175.468765,9(10), 5.63 m, +245,T,2008/01/27,14:33:51.000,SPS,57.697735,N,11.979055,E,68.273 m,3.367 km/h,175.468765,9(10), 6.09 m, +246,T,2008/01/27,14:33:56.000,SPS,57.697783,N,11.978979,E,69.860 m,3.793 km/h,175.468765,9(10), 7.23 m, +247,T,2008/01/27,14:34:01.000,SPS,57.697852,N,11.978978,E,69.197 m,3.305 km/h,175.468765,9(10), 7.68 m, +248,T,2008/01/27,14:34:06.000,SPS,57.697931,N,11.978880,E,66.018 m,4.712 km/h,175.468765,8(10), 11.04 m, +249,T,2008/01/27,14:34:11.000,SPS,57.698014,N,11.978795,E,63.117 m,5.675 km/h,175.468765,8(10), 10.95 m, +250,T,2008/01/27,14:34:16.000,SPS,57.698069,N,11.978688,E,62.031 m,4.371 km/h,175.468765,8(10), 8.90 m, +251,T,2008/01/27,14:34:21.000,SPS,57.698117,N,11.978581,E,63.191 m,4.748 km/h,175.468765,8(10), 8.39 m, +252,T,2008/01/27,14:34:26.000,SPS,57.698160,N,11.978480,E,63.152 m,4.791 km/h,175.468765,8(10), 7.70 m, +253,T,2008/01/27,14:34:31.000,SPS,57.698224,N,11.978408,E,64.188 m,3.706 km/h,175.468765,8(10), 8.32 m, +254,T,2008/01/27,14:34:36.000,SPS,57.698269,N,11.978333,E,62.523 m,4.638 km/h,175.468765,9(10), 7.00 m, +255,T,2008/01/27,14:34:41.000,SPS,57.698344,N,11.978199,E,59.039 m,4.556 km/h,175.468765,8(10), 12.01 m, +256,T,2008/01/27,14:34:46.000,SPS,57.698394,N,11.978093,E,58.767 m,5.073 km/h,175.468765,9(10), 8.45 m, +257,T,2008/01/27,14:34:51.000,SPS,57.698437,N,11.978009,E,58.772 m,5.069 km/h,175.468765,8(10), 6.98 m, +258,T,2008/01/27,14:34:56.000,SPS,57.698484,N,11.977918,E,59.631 m,5.502 km/h,175.468765,8(10), 7.57 m, +259,T,2008/01/27,14:35:01.000,SPS,57.698542,N,11.977855,E,59.825 m,4.129 km/h,175.468765,8(10), 7.50 m, +260,T,2008/01/27,14:35:06.000,SPS,57.698616,N,11.977818,E,59.702 m,4.785 km/h,175.468765,9(10), 8.44 m, +261,T,2008/01/27,14:35:11.000,SPS,57.698663,N,11.977687,E,57.375 m,2.401 km/h,175.468765,8(10), 9.68 m, +262,T,2008/01/27,14:35:16.000,SPS,57.698660,N,11.977696,E,57.712 m,0.124 km/h,175.468765,9(10), 0.68 m, +263,T,2008/01/27,14:35:21.000,SPS,57.698660,N,11.977696,E,57.753 m,0.028 km/h,175.468765,8(10), 0.06 m, +264,T,2008/01/27,14:35:26.000,SPS,57.698660,N,11.977697,E,57.740 m,0.029 km/h,175.468765,8(10), 0.03 m, +265,T,2008/01/27,14:35:31.000,SPS,57.698666,N,11.977690,E,57.764 m,5.039 km/h,175.468765,9(10), 0.87 m, +266,T,2008/01/27,14:35:36.000,SPS,57.698734,N,11.977587,E,56.159 m,6.733 km/h,175.468765,8(10), 9.86 m, +267,T,2008/01/27,14:35:41.000,SPS,57.698815,N,11.977506,E,51.600 m,4.906 km/h,175.468765,9(10), 11.14 m, +268,T,2008/01/27,14:35:46.000,SPS,57.698893,N,11.977435,E,50.687 m,6.568 km/h,175.468765,8(10), 9.76 m, +269,T,2008/01/27,14:35:51.000,SPS,57.698960,N,11.977356,E,51.726 m,4.858 km/h,175.468765,8(10), 8.84 m, +270,T,2008/01/27,14:35:56.000,SPS,57.699004,N,11.977275,E,53.612 m,5.514 km/h,175.468765,9(10), 7.12 m, +271,T,2008/01/27,14:36:01.000,SPS,57.699043,N,11.977179,E,54.670 m,5.972 km/h,175.468765,8(10), 7.28 m, +272,T,2008/01/27,14:36:06.000,SPS,57.699088,N,11.977114,E,56.635 m,6.510 km/h,175.468765,8(10), 6.66 m, +273,T,2008/01/27,14:36:11.000,SPS,57.699135,N,11.977033,E,59.526 m,3.891 km/h,175.468765,9(10), 7.64 m, +274,T,2008/01/27,14:36:16.000,SPS,57.699140,N,11.976915,E,61.831 m,5.391 km/h,175.468765,9(10), 7.47 m, +275,T,2008/01/27,14:36:21.000,SPS,57.699183,N,11.976799,E,63.125 m,3.378 km/h,175.468765,8(10), 8.49 m, +276,T,2008/01/27,14:36:26.000,SPS,57.699238,N,11.976728,E,65.140 m,7.040 km/h,175.468765,8(10), 7.74 m, +277,T,2008/01/27,14:36:31.000,SPS,57.699323,N,11.976679,E,63.123 m,3.529 km/h,175.468765,8(10), 10.12 m, +278,T,2008/01/27,14:36:36.000,SPS,57.699357,N,11.976650,E,63.095 m,2.025 km/h,175.468765,9(10), 4.18 m, +279,T,2008/01/27,14:36:41.000,SPS,57.699361,N,11.976686,E,64.549 m,0.758 km/h,175.468765,9(10), 2.63 m, +280,T,2008/01/27,14:36:46.000,SPS,57.699357,N,11.976696,E,65.330 m,0.328 km/h,175.468765,9(10), 1.06 m, +281,T,2008/01/27,14:36:51.000,SPS,57.699353,N,11.976715,E,65.651 m,2.531 km/h,175.468765,8(10), 1.28 m, +282,T,2008/01/27,14:36:56.000,SPS,57.699354,N,11.976777,E,65.963 m,2.095 km/h,175.468765,8(10), 3.71 m, +283,T,2008/01/27,14:37:01.000,SPS,57.699353,N,11.976817,E,66.272 m,2.000 km/h,175.468765,8(10), 2.40 m, +284,T,2008/01/27,14:37:06.000,SPS,57.699339,N,11.976852,E,66.537 m,2.305 km/h,175.468765,8(10), 2.64 m, +285,T,2008/01/27,14:37:11.000,SPS,57.699336,N,11.976895,E,66.844 m,0.733 km/h,175.468765,8(10), 2.63 m, +286,T,2008/01/27,14:37:16.000,SPS,57.699336,N,11.976902,E,66.999 m,0.190 km/h,175.468765,9(10), 0.45 m, +287,T,2008/01/27,14:37:21.000,SPS,57.699337,N,11.976903,E,67.045 m,0.371 km/h,175.468765,8(10), 0.15 m, +288,T,2008/01/27,14:37:26.000,SPS,57.699343,N,11.976884,E,67.063 m,1.609 km/h,175.468765,9(10), 1.28 m, +289,T,2008/01/27,14:37:31.000,SPS,57.699353,N,11.976850,E,67.086 m,1.660 km/h,175.468765,9(10), 2.33 m, +290,T,2008/01/27,14:37:36.000,SPS,57.699359,N,11.976833,E,67.109 m,0.692 km/h,175.468765,9(10), 1.21 m, +291,T,2008/01/27,14:37:41.000,SPS,57.699364,N,11.976816,E,67.116 m,0.498 km/h,175.468765,9(10), 1.17 m, +292,T,2008/01/27,14:37:46.000,SPS,57.699367,N,11.976811,E,67.123 m,0.457 km/h,175.468765,9(10), 0.46 m, +293,T,2008/01/27,14:37:51.000,SPS,57.699376,N,11.976791,E,67.126 m,1.897 km/h,175.468765,9(10), 1.50 m, +294,T,2008/01/27,14:37:56.000,SPS,57.699404,N,11.976773,E,67.146 m,3.128 km/h,175.468765,8(10), 3.34 m, +295,T,2008/01/27,14:38:01.000,SPS,57.699441,N,11.976757,E,67.190 m,2.677 km/h,175.468765,8(10), 4.29 m, +296,T,2008/01/27,14:38:06.000,SPS,57.699470,N,11.976756,E,67.275 m,2.140 km/h,175.468765,7(10), 3.17 m, +297,T,2008/01/27,14:38:11.000,SPS,57.699496,N,11.976755,E,67.238 m,2.152 km/h,175.468765,7(10), 2.92 m, +298,T,2008/01/27,14:38:16.000,SPS,57.699523,N,11.976775,E,67.197 m,2.287 km/h,175.468765,7(10), 3.25 m, +299,T,2008/01/27,14:38:21.000,SPS,57.699554,N,11.976780,E,67.123 m,2.599 km/h,175.468765,8(10), 3.41 m, +300,T,2008/01/27,14:38:26.000,SPS,57.699579,N,11.976773,E,67.029 m,1.833 km/h,175.468765,7(10), 2.83 m, +301,T,2008/01/27,14:38:31.000,SPS,57.699588,N,11.976764,E,66.982 m,0.306 km/h,175.468765,7(10), 1.19 m, +302,T,2008/01/27,14:38:36.000,SPS,57.699594,N,11.976795,E,66.995 m,1.683 km/h,175.468765,7(10), 1.94 m, +303,T,2008/01/27,14:38:41.000,SPS,57.699594,N,11.976796,E,67.051 m,0.616 km/h,175.468765,8(10), 0.10 m, +304,T,2008/01/27,14:38:46.000,SPS,57.699594,N,11.976800,E,67.175 m,0.933 km/h,175.468765,8(10), 0.27 m, +305,T,2008/01/27,14:38:51.000,SPS,57.699596,N,11.976814,E,67.189 m,0.589 km/h,175.468765,8(10), 0.87 m, +306,T,2008/01/27,14:38:56.000,SPS,57.699576,N,11.976767,E,67.108 m,3.395 km/h,175.468765,8(10), 3.55 m, +307,T,2008/01/27,14:39:01.000,SPS,57.699566,N,11.976759,E,67.008 m,0.996 km/h,175.468765,8(10), 1.20 m, +308,T,2008/01/27,14:39:06.000,SPS,57.699570,N,11.976760,E,66.902 m,0.474 km/h,175.468765,7(10), 0.42 m, +309,T,2008/01/27,14:39:11.000,SPS,57.699573,N,11.976757,E,66.823 m,1.591 km/h,175.468765,8(10), 0.41 m, +310,T,2008/01/27,14:39:16.000,SPS,57.699566,N,11.976722,E,66.704 m,2.013 km/h,175.468765,8(10), 2.22 m, +311,T,2008/01/27,14:39:21.000,SPS,57.699556,N,11.976691,E,66.499 m,3.174 km/h,175.468765,8(10), 2.18 m, +312,T,2008/01/27,14:39:26.000,SPS,57.699556,N,11.976631,E,66.373 m,4.101 km/h,175.468765,9(10), 3.56 m, +313,T,2008/01/27,14:39:31.000,SPS,57.699554,N,11.976523,E,62.448 m,5.704 km/h,175.468765,9(10), 7.55 m, +314,T,2008/01/27,14:39:36.000,SPS,57.699557,N,11.976459,E,63.711 m,1.936 km/h,175.468765,9(10), 4.04 m, +315,T,2008/01/27,14:39:41.000,SPS,57.699589,N,11.976401,E,65.081 m,5.259 km/h,175.468765,8(10), 5.10 m, +316,T,2008/01/27,14:39:46.000,SPS,57.699618,N,11.976313,E,65.332 m,1.698 km/h,175.468765,9(10), 6.13 m, +317,T,2008/01/27,14:39:51.000,SPS,57.699658,N,11.976248,E,65.433 m,3.701 km/h,175.468765,9(10), 5.96 m, +318,T,2008/01/27,14:39:56.000,SPS,57.699713,N,11.976241,E,68.670 m,3.926 km/h,175.468765,8(10), 6.90 m, +319,T,2008/01/27,14:40:01.000,SPS,57.699776,N,11.976177,E,67.728 m,4.038 km/h,175.468765,8(10), 8.09 m, +320,T,2008/01/27,14:40:06.000,SPS,57.699825,N,11.976082,E,67.210 m,4.399 km/h,175.468765,9(10), 7.83 m, +321,T,2008/01/27,14:40:11.000,SPS,57.699890,N,11.975991,E,67.461 m,4.970 km/h,175.468765,9(10), 9.05 m, +322,T,2008/01/27,14:40:16.000,SPS,57.699933,N,11.975902,E,67.407 m,4.824 km/h,175.468765,8(10), 7.11 m, +323,T,2008/01/27,14:40:21.000,SPS,57.699982,N,11.975813,E,67.934 m,3.603 km/h,175.468765,9(10), 7.65 m, +324,T,2008/01/27,14:40:26.000,SPS,57.700013,N,11.975730,E,68.325 m,4.033 km/h,175.468765,8(10), 6.07 m, +325,T,2008/01/27,14:40:31.000,SPS,57.700051,N,11.975639,E,68.266 m,4.495 km/h,175.468765,8(11), 6.83 m, +326,T,2008/01/27,14:40:36.000,SPS,57.700111,N,11.975515,E,66.728 m,7.484 km/h,312.802246,9(11), 10.12 m, +327,T,2008/01/27,14:40:41.000,SPS,57.700148,N,11.975412,E,66.768 m,5.457 km/h,312.802246,9(10), 7.41 m, +328,T,2008/01/27,14:40:46.000,SPS,57.700209,N,11.975290,E,64.711 m,4.795 km/h,313.321777,8(11), 10.16 m, +329,T,2008/01/27,14:40:51.000,SPS,57.700288,N,11.975163,E,59.311 m,5.921 km/h,308.333649,8(11), 12.80 m, +330,T,2008/01/27,14:40:56.000,SPS,57.700373,N,11.975093,E,55.797 m,5.683 km/h,308.333649,9(11), 10.90 m, +331,T,2008/01/27,14:41:01.000,SPS,57.700438,N,11.975011,E,53.861 m,4.589 km/h,308.333649,8(11), 8.97 m, +332,T,2008/01/27,14:41:06.000,SPS,57.700497,N,11.974938,E,53.176 m,4.847 km/h,308.138123,9(11), 7.86 m, +333,T,2008/01/27,14:41:11.000,SPS,57.700559,N,11.974854,E,52.072 m,3.912 km/h,308.138123,8(11), 8.65 m, +334,T,2008/01/27,14:41:16.000,SPS,57.700677,N,11.974866,E,48.708 m,5.864 km/h,308.138123,8(11), 13.57 m, +335,T,2008/01/27,14:41:21.000,SPS,57.700746,N,11.974814,E,46.551 m,4.577 km/h,308.138123,8(11), 8.57 m, +336,T,2008/01/27,14:41:26.000,SPS,57.700808,N,11.974717,E,45.545 m,5.492 km/h,308.138123,8(11), 9.07 m, +337,T,2008/01/27,14:41:31.000,SPS,57.700870,N,11.974636,E,44.029 m,6.530 km/h,307.519714,8(11), 8.51 m, +338,T,2008/01/27,14:41:36.000,SPS,57.700937,N,11.974539,E,43.179 m,5.834 km/h,307.519714,9(11), 9.53 m, +339,T,2008/01/27,14:41:41.000,SPS,57.700976,N,11.974505,E,44.183 m,4.036 km/h,307.519714,9(11), 4.85 m, +340,T,2008/01/27,14:41:46.000,SPS,57.701024,N,11.974409,E,44.197 m,4.866 km/h,307.519714,9(11), 7.86 m, +341,T,2008/01/27,14:41:51.000,SPS,57.701062,N,11.974339,E,44.851 m,3.063 km/h,309.039703,9(10), 6.04 m, +342,T,2008/01/27,14:41:56.000,SPS,57.701103,N,11.974260,E,46.545 m,3.451 km/h,312.476257,9(11), 6.71 m, +343,T,2008/01/27,14:42:01.000,SPS,57.701145,N,11.974184,E,48.676 m,4.202 km/h,312.476257,9(11), 6.91 m, +344,T,2008/01/27,14:42:06.000,SPS,57.701185,N,11.974109,E,51.464 m,4.515 km/h,313.447083,9(11), 6.87 m, +345,T,2008/01/27,14:42:11.000,SPS,57.701257,N,11.974060,E,52.666 m,3.776 km/h,313.648682,9(11), 8.60 m, +346,T,2008/01/27,14:42:16.000,SPS,57.701289,N,11.973956,E,54.016 m,5.350 km/h,313.648682,9(11), 7.29 m, +347,T,2008/01/27,14:42:21.000,SPS,57.701320,N,11.973851,E,55.015 m,4.412 km/h,313.648682,9(11), 7.23 m, +348,T,2008/01/27,14:42:26.000,SPS,57.701396,N,11.973794,E,55.862 m,5.184 km/h,313.648682,8(11), 9.12 m, +349,T,2008/01/27,14:42:31.000,SPS,57.701411,N,11.973702,E,59.843 m,3.612 km/h,315.012482,10(11), 7.01 m, +350,T,2008/01/27,14:42:36.000,SPS,57.701435,N,11.973617,E,62.617 m,3.938 km/h,315.592804,9(11), 6.37 m, +351,T,2008/01/27,14:42:41.000,SPS,57.701444,N,11.973507,E,65.984 m,4.078 km/h,315.939636,9(11), 7.41 m, +352,T,2008/01/27,14:42:46.000,SPS,57.701460,N,11.973434,E,68.956 m,4.906 km/h,315.939636,9(11), 5.56 m, +353,T,2008/01/27,14:42:51.000,SPS,57.701617,N,11.973517,E,64.422 m,4.207 km/h,319.429626,9(11), 18.81 m, +354,T,2008/01/27,14:42:56.000,SPS,57.701706,N,11.973372,E,57.507 m,3.937 km/h,319.429626,9(11), 14.86 m, +355,T,2008/01/27,14:43:01.000,SPS,57.701753,N,11.973226,E,53.629 m,6.001 km/h,319.429626,9(11), 10.90 m, +356,T,2008/01/27,14:43:06.000,SPS,57.701804,N,11.973084,E,51.208 m,4.103 km/h,319.429626,8(10), 10.46 m, +357,T,2008/01/27,14:43:11.000,SPS,57.701858,N,11.972972,E,50.054 m,4.389 km/h,319.604919,8(11), 8.99 m, +358,T,2008/01/27,14:43:16.000,SPS,57.701902,N,11.972925,E,51.181 m,4.323 km/h,319.773590,9(11), 5.81 m, +359,T,2008/01/27,14:43:21.000,SPS,57.701974,N,11.972840,E,50.300 m,5.974 km/h,319.422302,9(11), 9.52 m, +360,T,2008/01/27,14:43:26.000,SPS,57.702049,N,11.972744,E,47.162 m,4.477 km/h,319.306824,9(11), 10.63 m, +361,T,2008/01/27,14:43:31.000,SPS,57.702130,N,11.972675,E,43.652 m,5.464 km/h,318.747681,9(11), 10.52 m, +362,T,2008/01/27,14:43:36.000,SPS,57.702183,N,11.972622,E,41.517 m,6.473 km/h,321.181732,9(11), 6.98 m, +363,T,2008/01/27,14:43:41.000,SPS,57.702257,N,11.972538,E,42.297 m,6.683 km/h,321.181732,8(11), 9.71 m, +364,T,2008/01/27,14:43:46.000,SPS,57.702325,N,11.972445,E,41.170 m,5.209 km/h,330.178528,9(11), 9.46 m, +365,T,2008/01/27,14:43:51.000,SPS,57.702383,N,11.972354,E,40.141 m,3.227 km/h,330.178528,9(11), 8.43 m, +366,T,2008/01/27,14:43:56.000,SPS,57.702412,N,11.972289,E,41.489 m,4.234 km/h,331.304474,8(11), 5.28 m, +367,T,2008/01/27,14:44:01.000,SPS,57.702438,N,11.972275,E,41.592 m,0.282 km/h,331.304474,9(11), 2.99 m, +368,T,2008/01/27,14:44:06.000,SPS,57.702440,N,11.972273,E,41.805 m,0.492 km/h,331.304474,9(10), 0.36 m, +369,T,2008/01/27,14:44:11.000,SPS,57.702441,N,11.972272,E,41.838 m,0.093 km/h,331.304474,8(11), 0.07 m, +370,T,2008/01/27,14:44:16.000,SPS,57.702454,N,11.972234,E,41.977 m,5.925 km/h,331.304474,8(10), 2.71 m, +371,T,2008/01/27,14:44:21.000,SPS,57.702500,N,11.972135,E,39.424 m,5.709 km/h,331.304474,9(11), 8.21 m, +372,T,2008/01/27,14:44:26.000,SPS,57.702562,N,11.972116,E,39.249 m,6.026 km/h,331.304474,9(11), 7.03 m, +373,T,2008/01/27,14:44:31.000,SPS,57.702616,N,11.972060,E,40.106 m,6.033 km/h,331.304474,9(11), 6.89 m, +374,T,2008/01/27,14:44:36.000,SPS,57.702666,N,11.972001,E,40.622 m,4.647 km/h,332.742340,9(11), 6.63 m, +375,T,2008/01/27,14:44:41.000,SPS,57.702736,N,11.971930,E,39.549 m,4.373 km/h,334.134705,9(11), 8.90 m, +376,T,2008/01/27,14:44:46.000,SPS,57.702782,N,11.971835,E,39.688 m,4.830 km/h,334.134705,9(11), 7.67 m, +377,T,2008/01/27,14:44:51.000,SPS,57.702843,N,11.971722,E,36.875 m,5.373 km/h,334.134705,9(11), 10.02 m, +378,T,2008/01/27,14:44:56.000,SPS,57.702910,N,11.971636,E,37.305 m,7.077 km/h,329.513885,9(11), 9.04 m, +379,T,2008/01/27,14:45:01.000,SPS,57.702970,N,11.971551,E,36.478 m,5.132 km/h,329.513885,9(11), 8.39 m, +380,T,2008/01/27,14:45:06.000,SPS,57.703017,N,11.971462,E,37.679 m,6.665 km/h,329.513885,9(11), 7.53 m, +381,T,2008/01/27,14:45:11.000,SPS,57.703071,N,11.971374,E,37.856 m,5.270 km/h,329.513885,9(11), 8.03 m, +382,T,2008/01/27,14:45:16.000,SPS,57.703134,N,11.971307,E,38.441 m,7.068 km/h,330.639191,9(11), 8.09 m, +383,T,2008/01/27,14:45:21.000,SPS,57.703188,N,11.971224,E,37.094 m,4.871 km/h,322.645264,9(11), 7.89 m, +384,T,2008/01/27,14:45:26.000,SPS,57.703244,N,11.971135,E,38.461 m,6.000 km/h,321.540863,9(11), 8.28 m, +385,T,2008/01/27,14:45:31.000,SPS,57.703298,N,11.971047,E,37.066 m,4.873 km/h,321.540863,9(11), 8.15 m, +386,T,2008/01/27,14:45:36.000,SPS,57.703351,N,11.970981,E,37.422 m,6.283 km/h,321.540863,9(11), 7.10 m, +387,T,2008/01/27,14:45:41.000,SPS,57.703404,N,11.970900,E,36.895 m,5.331 km/h,320.504150,9(11), 7.65 m, +388,T,2008/01/27,14:45:46.000,SPS,57.703467,N,11.970806,E,36.325 m,5.001 km/h,319.068939,9(11), 9.01 m, +389,T,2008/01/27,14:45:51.000,SPS,57.703511,N,11.970724,E,36.249 m,6.196 km/h,320.075500,9(11), 6.92 m, +390,T,2008/01/27,14:45:56.000,SPS,57.703565,N,11.970629,E,34.937 m,4.656 km/h,320.075500,9(11), 8.33 m, +391,T,2008/01/27,14:46:01.000,SPS,57.703616,N,11.970553,E,34.255 m,5.732 km/h,322.200470,9(11), 7.32 m, +392,T,2008/01/27,14:46:06.000,SPS,57.703669,N,11.970463,E,34.248 m,5.980 km/h,320.091583,9(11), 7.93 m, +393,T,2008/01/27,14:46:11.000,SPS,57.703734,N,11.970375,E,34.113 m,5.019 km/h,321.973114,9(11), 9.00 m, +394,T,2008/01/27,14:46:16.000,SPS,57.703800,N,11.970325,E,34.821 m,5.381 km/h,321.973114,9(11), 7.91 m, +395,T,2008/01/27,14:46:21.000,SPS,57.703856,N,11.970309,E,34.474 m,4.345 km/h,321.973114,9(11), 6.30 m, +396,T,2008/01/27,14:46:26.000,SPS,57.703895,N,11.970388,E,34.815 m,5.410 km/h,321.973114,9(11), 6.47 m, +397,T,2008/01/27,14:46:31.000,SPS,57.703939,N,11.970481,E,36.532 m,5.661 km/h,321.973114,8(11), 7.60 m, +398,T,2008/01/27,14:46:36.000,SPS,57.703984,N,11.970577,E,35.942 m,5.200 km/h,321.973114,8(11), 7.63 m, +399,T,2008/01/27,14:46:41.000,SPS,57.704017,N,11.970695,E,36.971 m,6.216 km/h,321.973114,8(11), 8.01 m, +400,T,2008/01/27,14:46:46.000,SPS,57.704067,N,11.970783,E,36.621 m,4.963 km/h,321.973114,8(11), 7.62 m, +401,T,2008/01/27,14:46:51.000,SPS,57.704115,N,11.970869,E,36.711 m,4.327 km/h,321.973114,8(11), 7.41 m, +402,T,2008/01/27,14:46:56.000,SPS,57.704112,N,11.970976,E,38.266 m,5.899 km/h,321.973114,9(11), 6.60 m, +403,T,2008/01/27,14:47:01.000,SPS,57.704100,N,11.971029,E,39.389 m,3.061 km/h,321.973114,8(11), 3.62 m, +404,T,2008/01/27,14:47:06.000,SPS,57.704082,N,11.971095,E,41.071 m,4.254 km/h,321.973114,8(11), 4.68 m, +405,T,2008/01/27,14:47:11.000,SPS,57.704055,N,11.971267,E,44.572 m,5.729 km/h,321.973114,8(11), 11.27 m, +406,T,2008/01/27,14:47:16.000,SPS,57.704055,N,11.971487,E,45.150 m,6.854 km/h,103.814293,8(11), 13.13 m, +407,T,2008/01/27,14:47:21.000,SPS,57.704049,N,11.971652,E,46.482 m,5.082 km/h,103.548470,8(11), 9.96 m, +408,T,2008/01/27,14:47:26.000,SPS,57.704046,N,11.971775,E,47.728 m,4.991 km/h,103.548470,8(10), 7.41 m, +409,T,2008/01/27,14:47:31.000,SPS,57.704030,N,11.971917,E,50.447 m,4.795 km/h,110.262627,8(10), 9.12 m, +410,T,2008/01/27,14:47:36.000,SPS,57.704067,N,11.972014,E,50.488 m,6.293 km/h,110.262627,8(10), 7.09 m, +411,T,2008/01/27,14:47:41.000,SPS,57.704103,N,11.972134,E,51.565 m,4.881 km/h,110.262627,8(10), 8.26 m, +412,T,2008/01/27,14:47:46.000,SPS,57.704207,N,11.972209,E,45.682 m,4.360 km/h,110.262627,8(10), 13.78 m, +413,T,2008/01/27,14:47:51.000,SPS,57.704288,N,11.972271,E,41.205 m,5.089 km/h,110.262627,8(10), 10.74 m, +414,T,2008/01/27,14:47:56.000,SPS,57.704330,N,11.972347,E,41.815 m,4.597 km/h,110.262627,8(11), 6.56 m, +415,T,2008/01/27,14:48:01.000,SPS,57.704373,N,11.972406,E,42.905 m,5.756 km/h,110.262627,8(10), 5.98 m, +416,T,2008/01/27,14:48:06.000,SPS,57.704441,N,11.972453,E,42.048 m,6.233 km/h,110.262627,8(10), 8.18 m, +417,T,2008/01/27,14:48:11.000,SPS,57.704514,N,11.972459,E,40.197 m,4.767 km/h,110.262627,7(10), 8.29 m, +418,T,2008/01/27,14:48:16.000,SPS,57.704577,N,11.972472,E,37.296 m,4.874 km/h,110.262627,7(11), 7.71 m, +419,T,2008/01/27,14:48:21.000,SPS,57.704643,N,11.972509,E,34.942 m,4.365 km/h,110.262627,7(10), 8.02 m, +420,T,2008/01/27,14:48:26.000,SPS,57.704711,N,11.972519,E,31.462 m,5.425 km/h,110.262627,7(10), 8.32 m, +421,T,2008/01/27,14:48:31.000,SPS,57.704789,N,11.972508,E,29.879 m,6.224 km/h,110.262627,8(10), 8.84 m, +422,T,2008/01/27,14:48:36.000,SPS,57.704843,N,11.972505,E,28.687 m,3.555 km/h,110.262627,7(10), 6.15 m, +423,T,2008/01/27,14:48:41.000,SPS,57.704922,N,11.972433,E,28.146 m,4.555 km/h,110.262627,8(10), 9.83 m, +424,T,2008/01/27,14:48:46.000,SPS,57.705012,N,11.972304,E,30.671 m,6.612 km/h,110.262627,8(10), 12.83 m, +425,T,2008/01/27,14:48:51.000,SPS,57.705060,N,11.972348,E,32.308 m,4.719 km/h,110.262627,7(10), 6.27 m, +426,T,2008/01/27,14:48:56.000,SPS,57.705128,N,11.972349,E,32.629 m,5.842 km/h,110.262627,8(10), 7.55 m, +427,T,2008/01/27,14:49:01.000,SPS,57.705203,N,11.972322,E,33.369 m,6.157 km/h,110.262627,8(10), 8.52 m, +428,T,2008/01/27,14:49:06.000,SPS,57.705254,N,11.972357,E,34.297 m,3.953 km/h,110.262627,8(10), 6.10 m, +429,T,2008/01/27,14:49:11.000,SPS,57.705307,N,11.972390,E,35.706 m,4.478 km/h,110.262627,8(10), 6.44 m, +430,T,2008/01/27,14:49:16.000,SPS,57.705365,N,11.972434,E,37.491 m,4.326 km/h,110.262627,8(11), 7.15 m, +431,T,2008/01/27,14:49:21.000,SPS,57.705435,N,11.972468,E,37.541 m,5.638 km/h,110.262627,7(10), 8.02 m, +432,T,2008/01/27,14:49:26.000,SPS,57.705496,N,11.972519,E,38.153 m,4.778 km/h,110.262627,7(10), 7.47 m, +433,T,2008/01/27,14:49:31.000,SPS,57.705556,N,11.972560,E,38.474 m,4.344 km/h,110.262627,8(10), 7.13 m, +434,T,2008/01/27,14:49:36.000,SPS,57.705625,N,11.972578,E,38.569 m,5.770 km/h,110.262627,8(10), 7.79 m, +435,T,2008/01/27,14:49:41.000,SPS,57.705683,N,11.972639,E,38.217 m,5.384 km/h,110.262627,8(10), 7.37 m, +436,T,2008/01/27,14:49:46.000,SPS,57.705730,N,11.972712,E,38.042 m,4.277 km/h,110.262627,7(10), 6.82 m, +437,T,2008/01/27,14:49:51.000,SPS,57.705797,N,11.972769,E,37.052 m,4.925 km/h,110.262627,7(10), 8.27 m, +438,T,2008/01/27,14:49:56.000,SPS,57.705858,N,11.972806,E,36.223 m,6.551 km/h,110.262627,8(10), 7.21 m, +439,T,2008/01/27,14:50:01.000,SPS,57.705898,N,11.972898,E,35.863 m,3.660 km/h,110.262627,10(10), 7.09 m, +440,T,2008/01/27,14:50:06.000,SPS,57.705933,N,11.972997,E,37.348 m,4.766 km/h,110.262627,8(10), 7.19 m, +441,T,2008/01/27,14:50:11.000,SPS,57.705968,N,11.973097,E,39.429 m,5.517 km/h,110.262627,8(10), 7.46 m, +442,T,2008/01/27,14:50:16.000,SPS,57.706018,N,11.973184,E,38.590 m,4.015 km/h,110.262627,8(11), 7.64 m, +443,T,2008/01/27,14:50:21.000,SPS,57.706065,N,11.973269,E,38.579 m,4.948 km/h,110.262627,8(10), 7.21 m, +444,T,2008/01/27,14:50:26.000,SPS,57.706064,N,11.973371,E,41.595 m,4.483 km/h,110.262627,8(10), 6.80 m, +445,T,2008/01/27,14:50:31.000,SPS,57.706097,N,11.973470,E,43.935 m,6.416 km/h,110.262627,8(10), 7.30 m, +446,T,2008/01/27,14:50:36.000,SPS,57.706130,N,11.973579,E,46.569 m,5.292 km/h,110.262627,7(10), 7.90 m, +447,T,2008/01/27,14:50:41.000,SPS,57.706154,N,11.973707,E,47.494 m,4.928 km/h,110.262627,7(10), 8.18 m, +448,T,2008/01/27,14:50:46.000,SPS,57.706197,N,11.973811,E,48.136 m,5.145 km/h,110.262627,8(10), 7.88 m, +449,T,2008/01/27,14:50:51.000,SPS,57.706239,N,11.973920,E,48.331 m,5.018 km/h,110.262627,7(10), 7.98 m, +450,T,2008/01/27,14:50:56.000,SPS,57.706289,N,11.974031,E,47.542 m,4.549 km/h,110.262627,8(11), 8.67 m, +451,T,2008/01/27,14:51:01.000,SPS,57.706375,N,11.974093,E,44.780 m,5.397 km/h,110.262627,8(10), 10.64 m, +452,T,2008/01/27,14:51:06.000,SPS,57.706427,N,11.974187,E,43.078 m,5.529 km/h,110.262627,7(10), 8.22 m, +453,T,2008/01/27,14:51:11.000,SPS,57.706508,N,11.974208,E,39.633 m,4.697 km/h,110.262627,7(10), 9.77 m, +454,T,2008/01/27,14:51:16.000,SPS,57.706592,N,11.974215,E,36.936 m,5.887 km/h,110.262627,7(10), 9.82 m, +455,T,2008/01/27,14:51:21.000,SPS,57.706672,N,11.974199,E,34.277 m,4.810 km/h,110.262627,7(10), 9.34 m, +456,T,2008/01/27,14:51:26.000,SPS,57.706728,N,11.974145,E,31.133 m,4.537 km/h,110.262627,8(10), 7.66 m, +457,T,2008/01/27,14:51:31.000,SPS,57.706804,N,11.974123,E,31.994 m,5.289 km/h,110.262627,8(11), 8.58 m, +458,T,2008/01/27,14:51:36.000,SPS,57.706868,N,11.974119,E,31.122 m,7.407 km/h,350.169159,7(10), 7.24 m, +459,T,2008/01/27,14:51:41.000,SPS,57.706938,N,11.974093,E,31.006 m,6.632 km/h,351.339142,7(10), 7.94 m, +460,T,2008/01/27,14:51:46.000,SPS,57.707009,N,11.974071,E,31.925 m,4.432 km/h,348.956848,7(10), 8.03 m, +461,T,2008/01/27,14:51:51.000,SPS,57.707066,N,11.974043,E,32.376 m,3.681 km/h,348.956848,7(10), 6.55 m, +462,T,2008/01/27,14:51:56.000,SPS,57.707099,N,11.974033,E,32.349 m,5.761 km/h,348.956848,7(10), 3.78 m, +463,T,2008/01/27,14:52:01.000,SPS,57.707190,N,11.974034,E,31.483 m,6.212 km/h,348.956848,7(10), 10.13 m, +464,T,2008/01/27,14:52:06.000,SPS,57.707236,N,11.974080,E,34.507 m,3.521 km/h,348.956848,8(11), 6.54 m, +465,T,2008/01/27,14:52:11.000,SPS,57.707303,N,11.974126,E,36.687 m,5.733 km/h,348.956848,8(10), 8.31 m, +466,T,2008/01/27,14:52:16.000,SPS,57.707354,N,11.974068,E,35.163 m,5.569 km/h,348.956848,8(10), 6.81 m, +467,T,2008/01/27,14:52:21.000,SPS,57.707403,N,11.974006,E,36.492 m,4.982 km/h,348.956848,8(10), 6.69 m, +468,T,2008/01/27,14:52:26.000,SPS,57.707466,N,11.973938,E,36.348 m,6.117 km/h,348.956848,8(10), 8.08 m, +469,T,2008/01/27,14:52:31.000,SPS,57.707508,N,11.973871,E,35.798 m,3.205 km/h,348.956848,8(10), 6.21 m, +470,T,2008/01/27,14:52:36.000,SPS,57.707566,N,11.973811,E,35.214 m,5.114 km/h,348.930817,8(10), 7.37 m, +471,T,2008/01/27,14:52:41.000,SPS,57.707633,N,11.973760,E,35.049 m,5.096 km/h,348.930817,8(10), 8.12 m, +472,T,2008/01/27,14:52:46.000,SPS,57.707654,N,11.973644,E,34.685 m,5.321 km/h,348.930817,8(10), 7.29 m, +473,T,2008/01/27,14:52:51.000,SPS,57.707663,N,11.973519,E,33.835 m,5.624 km/h,348.930817,8(10), 7.57 m, +474,T,2008/01/27,14:52:56.000,SPS,57.707672,N,11.973407,E,33.943 m,4.579 km/h,348.930817,8(10), 6.78 m, +475,T,2008/01/27,14:53:01.000,SPS,57.707657,N,11.973287,E,33.896 m,4.034 km/h,348.930817,8(10), 7.33 m, +476,T,2008/01/27,14:53:06.000,SPS,57.707661,N,11.973211,E,32.793 m,0.167 km/h,348.930817,8(11), 4.70 m, +477,T,2008/01/27,14:53:11.000,SPS,57.707662,N,11.973210,E,32.801 m,0.839 km/h,348.930817,8(10), 0.03 m, +478,T,2008/01/27,14:53:16.000,SPS,57.707658,N,11.973270,E,32.809 m,3.912 km/h,348.930817,7(10), 3.56 m, +479,T,2008/01/27,14:53:21.000,SPS,57.707666,N,11.973349,E,35.294 m,3.142 km/h,348.930817,7(10), 5.44 m, +480,T,2008/01/27,14:53:26.000,SPS,57.707670,N,11.973404,E,36.033 m,0.290 km/h,348.930817,8(10), 3.34 m, +481,T,2008/01/27,14:53:31.000,SPS,57.707672,N,11.973404,E,36.243 m,0.751 km/h,348.930817,8(10), 0.31 m, +482,T,2008/01/27,14:53:36.000,SPS,57.707680,N,11.973401,E,36.258 m,0.575 km/h,348.930817,8(10), 0.85 m, +483,T,2008/01/27,14:53:41.000,SPS,57.707684,N,11.973396,E,36.276 m,0.942 km/h,348.930817,8(10), 0.55 m, +484,T,2008/01/27,14:53:46.000,SPS,57.707695,N,11.973377,E,36.169 m,1.862 km/h,348.930817,7(10), 1.64 m, +485,T,2008/01/27,14:53:51.000,SPS,57.707701,N,11.973373,E,36.054 m,0.019 km/h,348.930817,8(10), 0.76 m, +486,T,2008/01/27,14:53:56.000,SPS,57.707701,N,11.973373,E,36.035 m,2.235 km/h,348.930817,8(10), 0.02 m, +487,T,2008/01/27,14:54:01.000,SPS,57.707701,N,11.973360,E,36.036 m,4.208 km/h,348.930817,8(10), 0.73 m, +488,T,2008/01/27,14:54:06.000,SPS,57.707707,N,11.973363,E,36.143 m,0.233 km/h,348.930817,8(10), 0.73 m, +489,T,2008/01/27,14:54:11.000,SPS,57.707716,N,11.973354,E,36.185 m,2.048 km/h,348.930817,7(10), 1.10 m, +490,T,2008/01/27,14:54:16.000,SPS,57.707700,N,11.973299,E,35.454 m,2.305 km/h,348.930817,7(10), 3.80 m, +491,T,2008/01/27,14:54:21.000,SPS,57.707700,N,11.973267,E,34.876 m,1.690 km/h,348.930817,6(10), 2.03 m, +492,T,2008/01/27,14:54:26.000,SPS,57.707697,N,11.973274,E,34.765 m,0.173 km/h,348.930817,8(10), 0.59 m, +493,T,2008/01/27,14:54:31.000,SPS,57.707696,N,11.973274,E,34.832 m,0.088 km/h,348.930817,8(10), 0.08 m, +494,T,2008/01/27,14:54:36.000,SPS,57.707695,N,11.973275,E,34.959 m,0.099 km/h,348.930817,8(10), 0.21 m, +495,T,2008/01/27,14:54:41.000,SPS,57.707695,N,11.973275,E,35.037 m,0.003 km/h,348.930817,7(10), 0.09 m, +496,T,2008/01/27,14:54:46.000,SPS,57.707695,N,11.973275,E,35.045 m,0.011 km/h,348.930817,8(10), 0.02 m, +497,T,2008/01/27,14:54:51.000,SPS,57.707695,N,11.973276,E,35.079 m,0.004 km/h,348.930817,8(10), 0.04 m, +498,T,2008/01/27,14:54:56.000,SPS,57.707695,N,11.973277,E,35.115 m,0.006 km/h,348.930817,8(10), 0.07 m, +499,T,2008/01/27,14:55:01.000,SPS,57.707695,N,11.973278,E,35.142 m,0.005 km/h,348.930817,7(10), 0.06 m, +500,T,2008/01/27,14:55:06.000,SPS,57.707695,N,11.973278,E,35.152 m,0.010 km/h,348.930817,8(10), 0.02 m, +501,T,2008/01/27,14:55:11.000,SPS,57.707695,N,11.973278,E,35.177 m,0.122 km/h,348.930817,7(10), 0.03 m, +502,T,2008/01/27,14:55:16.000,SPS,57.707696,N,11.973279,E,35.209 m,0.019 km/h,348.930817,7(11), 0.09 m, +503,T,2008/01/27,14:55:21.000,SPS,57.707693,N,11.973293,E,35.344 m,1.119 km/h,348.930817,6(10), 0.93 m, +504,T,2008/01/27,14:55:26.000,SPS,57.707691,N,11.973298,E,35.398 m,0.006 km/h,348.930817,9(10), 0.34 m, +505,T,2008/01/27,14:55:31.000,SPS,57.707691,N,11.973298,E,35.406 m,0.002 km/h,348.930817,8(11), 0.01 m, +506,T,2008/01/27,14:55:36.000,SPS,57.707691,N,11.973299,E,35.387 m,0.024 km/h,348.930817,8(10), 0.07 m, +507,T,2008/01/27,14:55:41.000,SPS,57.707691,N,11.973300,E,35.374 m,0.007 km/h,348.930817,8(10), 0.06 m, +508,T,2008/01/27,14:55:46.000,SPS,57.707691,N,11.973300,E,35.371 m,0.007 km/h,348.930817,8(10), 0.02 m, +509,T,2008/01/27,14:55:51.000,SPS,57.707690,N,11.973301,E,35.345 m,0.011 km/h,348.930817,9(10), 0.15 m, +510,T,2008/01/27,14:55:56.000,SPS,57.707688,N,11.973304,E,35.337 m,0.329 km/h,348.930817,8(10), 0.23 m, +511,T,2008/01/27,14:56:01.000,SPS,57.707684,N,11.973310,E,35.324 m,0.509 km/h,348.930817,7(10), 0.60 m, +512,T,2008/01/27,14:56:06.000,SPS,57.707675,N,11.973319,E,35.344 m,0.811 km/h,348.930817,8(10), 1.09 m, +513,T,2008/01/27,14:56:11.000,SPS,57.707666,N,11.973328,E,35.372 m,0.788 km/h,348.930817,8(11), 1.15 m, +514,T,2008/01/27,14:56:16.000,SPS,57.707659,N,11.973335,E,35.406 m,0.852 km/h,348.930817,8(10), 0.87 m, +515,T,2008/01/27,14:56:21.000,SPS,57.707650,N,11.973344,E,35.414 m,0.386 km/h,348.930817,7(10), 1.11 m, +516,T,2008/01/27,14:56:26.000,SPS,57.707644,N,11.973349,E,35.431 m,3.547 km/h,348.930817,8(10), 0.79 m, +517,T,2008/01/27,14:56:31.000,SPS,57.707609,N,11.973116,E,36.105 m,14.878 km/h,266.844727,8(10), 14.44 m, +518,T,2008/01/27,14:56:36.000,SPS,57.707578,N,11.972758,E,37.404 m,16.099 km/h,259.185059,8(10), 21.66 m, +519,T,2008/01/27,14:56:41.000,SPS,57.707540,N,11.972427,E,39.308 m,15.975 km/h,252.127563,7(11), 20.29 m, +520,T,2008/01/27,14:56:46.000,SPS,57.707556,N,11.972102,E,39.680 m,13.810 km/h,251.846802,7(10), 19.43 m, +521,T,2008/01/27,14:56:51.000,SPS,57.707435,N,11.971864,E,38.027 m,14.611 km/h,209.976074,8(10), 19.63 m, +522,T,2008/01/27,14:56:56.000,SPS,57.707240,N,11.971689,E,39.717 m,16.520 km/h,204.307907,8(11), 24.20 m, +523,T,2008/01/27,14:57:01.000,SPS,57.707070,N,11.971440,E,42.344 m,19.996 km/h,244.933319,9(10), 24.19 m, +524,T,2008/01/27,14:57:06.000,SPS,57.706994,N,11.970922,E,47.921 m,19.498 km/h,259.753479,8(10), 32.52 m, +525,T,2008/01/27,14:57:11.000,SPS,57.706961,N,11.970468,E,53.100 m,17.442 km/h,252.850159,8(10), 27.82 m, +526,T,2008/01/27,14:57:16.000,SPS,57.706822,N,11.970166,E,59.028 m,17.971 km/h,252.758423,8(10), 24.51 m, +527,T,2008/01/27,14:57:21.000,SPS,57.706789,N,11.969804,E,64.524 m,11.284 km/h,242.889435,9(10), 22.58 m, +528,T,2008/01/27,14:57:26.000,SPS,57.706770,N,11.969482,E,70.054 m,9.351 km/h,256.679993,9(10), 20.05 m, +529,T,2008/01/27,14:57:31.000,SPS,57.706723,N,11.969258,E,73.381 m,3.424 km/h,252.173355,9(10), 14.76 m, +530,T,2008/01/27,14:57:36.000,SPS,57.706723,N,11.969213,E,74.317 m,0.331 km/h,252.173355,8(10), 2.80 m, +531,T,2008/01/27,14:57:41.000,SPS,57.706723,N,11.969205,E,74.995 m,0.622 km/h,252.173355,9(10), 0.83 m, +532,T,2008/01/27,14:57:46.000,SPS,57.706724,N,11.969197,E,75.341 m,0.463 km/h,252.173355,9(11), 0.62 m, +533,T,2008/01/27,14:57:51.000,SPS,57.706725,N,11.969196,E,75.514 m,0.175 km/h,252.173355,8(10), 0.24 m, +534,T,2008/01/27,14:57:56.000,SPS,57.706726,N,11.969194,E,75.591 m,0.211 km/h,252.173355,8(10), 0.18 m, +535,T,2008/01/27,14:58:01.000,SPS,57.706726,N,11.969189,E,75.640 m,0.549 km/h,252.173355,9(10), 0.32 m, +536,T,2008/01/27,14:58:06.000,SPS,57.706727,N,11.969191,E,75.699 m,0.860 km/h,252.173355,9(10), 0.17 m, +537,T,2008/01/27,14:58:11.000,SPS,57.706729,N,11.969203,E,75.753 m,0.391 km/h,252.173355,8(10), 0.77 m, +538,T,2008/01/27,14:58:16.000,SPS,57.706729,N,11.969201,E,75.710 m,1.665 km/h,252.173355,9(10), 0.14 m, +539,T,2008/01/27,14:58:21.000,SPS,57.706703,N,11.969113,E,76.153 m,6.843 km/h,254.655457,8(10), 6.02 m, +540,T,2008/01/27,14:58:26.000,SPS,57.706634,N,11.969038,E,76.254 m,4.150 km/h,254.655457,9(10), 8.91 m, +541,T,2008/01/27,14:58:31.000,SPS,57.706621,N,11.968910,E,76.716 m,2.349 km/h,254.655457,9(10), 7.79 m, +542,T,2008/01/27,14:58:36.000,SPS,57.706612,N,11.968854,E,75.835 m,0.496 km/h,254.655457,8(11), 3.61 m, +543,T,2008/01/27,14:58:41.000,SPS,57.706611,N,11.968846,E,76.116 m,0.393 km/h,254.655457,8(10), 0.56 m, +544,T,2008/01/27,14:58:46.000,SPS,57.706609,N,11.968839,E,76.290 m,1.470 km/h,254.655457,9(10), 0.47 m, +545,T,2008/01/27,14:58:51.000,SPS,57.706582,N,11.968766,E,75.970 m,6.616 km/h,254.655457,9(10), 5.27 m, +546,T,2008/01/27,14:58:56.000,SPS,57.706521,N,11.968529,E,77.610 m,10.487 km/h,235.926590,9(10), 15.78 m, +547,T,2008/01/27,14:59:01.000,SPS,57.706388,N,11.968258,E,71.656 m,14.912 km/h,270.661957,8(10), 22.76 m, +548,T,2008/01/27,14:59:06.000,SPS,57.706369,N,11.967760,E,71.099 m,21.889 km/h,250.093170,8(10), 29.76 m, +549,T,2008/01/27,14:59:11.000,SPS,57.706290,N,11.967199,E,70.997 m,23.623 km/h,252.321228,9(10), 34.57 m, +550,T,2008/01/27,14:59:16.000,SPS,57.706286,N,11.966613,E,69.959 m,24.498 km/h,257.005981,8(10), 34.98 m, +551,T,2008/01/27,14:59:21.000,SPS,57.706224,N,11.966022,E,68.321 m,24.791 km/h,257.831085,8(10), 35.94 m, +552,T,2008/01/27,14:59:26.000,SPS,57.706154,N,11.965410,E,66.697 m,26.431 km/h,254.512512,7(10), 37.35 m, +553,T,2008/01/27,14:59:31.000,SPS,57.706046,N,11.964803,E,66.793 m,26.691 km/h,254.280838,8(10), 38.14 m, +554,T,2008/01/27,14:59:36.000,SPS,57.705964,N,11.964192,E,64.471 m,24.476 km/h,252.652267,8(10), 37.61 m, +555,T,2008/01/27,14:59:41.000,SPS,57.705943,N,11.963618,E,75.615 m,18.723 km/h,250.405945,8(10), 36.07 m, +556,T,2008/01/27,14:59:46.000,SPS,57.705915,N,11.963257,E,87.301 m,15.208 km/h,243.778580,8(10), 24.69 m, +557,T,2008/01/27,14:59:51.000,SPS,57.705843,N,11.962970,E,89.645 m,15.962 km/h,220.766418,8(10), 19.05 m, +558,T,2008/01/27,14:59:56.000,SPS,57.705678,N,11.962896,E,89.482 m,10.259 km/h,160.027557,8(10), 18.94 m, +559,T,2008/01/27,15:00:01.000,SPS,57.705521,N,11.963069,E,92.977 m,11.064 km/h,157.697861,8(10), 20.57 m, +560,T,2008/01/27,15:00:06.000,SPS,57.705355,N,11.963202,E,92.839 m,10.321 km/h,156.207596,8(10), 20.13 m, +561,T,2008/01/27,15:00:11.000,SPS,57.705197,N,11.963282,E,93.679 m,5.478 km/h,153.436081,8(10), 18.29 m, +562,T,2008/01/27,15:00:16.000,SPS,57.705104,N,11.963321,E,93.570 m,3.800 km/h,152.649536,8(10), 10.51 m, +563,T,2008/01/27,15:00:21.000,SPS,57.705001,N,11.963386,E,94.495 m,4.835 km/h,152.642792,8(10), 12.18 m, +564,T,2008/01/27,15:00:26.000,SPS,57.704889,N,11.963494,E,94.902 m,7.083 km/h,152.777771,7(10), 14.09 m, +565,T,2008/01/27,15:00:31.000,SPS,57.704679,N,11.963667,E,91.328 m,9.725 km/h,165.346649,8(10), 25.82 m, +566,T,2008/01/27,15:00:36.000,SPS,57.704587,N,11.963857,E,88.451 m,3.263 km/h,161.263718,9(10), 15.49 m, +567,T,2008/01/27,15:00:41.000,SPS,57.704618,N,11.963851,E,91.142 m,1.026 km/h,161.263718,8(10), 4.35 m, +568,T,2008/01/27,15:00:46.000,SPS,57.704624,N,11.963855,E,92.173 m,0.533 km/h,161.263718,8(10), 1.24 m, +569,T,2008/01/27,15:00:51.000,SPS,57.704618,N,11.963851,E,92.461 m,0.204 km/h,161.263718,8(10), 0.78 m, +570,T,2008/01/27,15:00:56.000,SPS,57.704619,N,11.963853,E,92.557 m,0.080 km/h,161.263718,8(10), 0.20 m, +571,T,2008/01/27,15:01:01.000,SPS,57.704615,N,11.963851,E,92.568 m,0.660 km/h,161.263718,8(10), 0.46 m, +572,T,2008/01/27,15:01:06.000,SPS,57.704505,N,11.963850,E,92.271 m,18.015 km/h,164.544937,8(10), 12.24 m, +573,T,2008/01/27,15:01:11.000,SPS,57.704211,N,11.963895,E,94.230 m,20.213 km/h,171.067032,8(9), 32.95 m, +574,T,2008/01/27,15:01:16.000,SPS,57.703962,N,11.964081,E,94.349 m,18.572 km/h,156.786514,8(9), 29.89 m, +575,T,2008/01/27,15:01:21.000,SPS,57.703689,N,11.964229,E,95.783 m,18.810 km/h,164.016251,8(9), 31.63 m, +576,T,2008/01/27,15:01:26.000,SPS,57.703505,N,11.964306,E,96.110 m,5.936 km/h,153.969543,8(9), 21.05 m, +577,T,2008/01/27,15:01:31.000,SPS,57.703375,N,11.964368,E,98.264 m,7.716 km/h,171.187561,8(9), 15.09 m, +578,T,2008/01/27,15:01:36.000,SPS,57.703183,N,11.964365,E,101.903 m,11.962 km/h,199.763306,8(9), 21.66 m, +579,T,2008/01/27,15:01:41.000,SPS,57.703022,N,11.964247,E,100.908 m,9.796 km/h,249.578110,8(9), 19.26 m, +580,T,2008/01/27,15:01:46.000,SPS,57.702874,N,11.963993,E,98.441 m,6.107 km/h,224.093170,8(9), 22.49 m, +581,T,2008/01/27,15:01:51.000,SPS,57.702809,N,11.963962,E,99.396 m,1.728 km/h,224.093170,8(9), 7.54 m, +582,T,2008/01/27,15:01:56.000,SPS,57.702789,N,11.963976,E,101.544 m,1.196 km/h,224.093170,8(9), 3.20 m, +583,T,2008/01/27,15:02:01.000,SPS,57.702774,N,11.963986,E,103.098 m,1.895 km/h,224.093170,8(9), 2.37 m, +584,T,2008/01/27,15:02:06.000,SPS,57.702750,N,11.964037,E,104.490 m,2.379 km/h,224.093170,8(9), 4.32 m, +585,T,2008/01/27,15:02:11.000,SPS,57.702526,N,11.963994,E,104.127 m,6.106 km/h,224.093170,8(9), 25.07 m, +586,T,2008/01/27,15:02:16.000,SPS,57.702073,N,11.964102,E,96.356 m,17.463 km/h,235.937607,8(9), 51.40 m, +587,T,2008/01/27,15:02:21.000,SPS,57.701924,N,11.963716,E,97.140 m,17.053 km/h,224.755081,8(9), 28.44 m, +588,T,2008/01/27,15:02:26.000,SPS,57.701700,N,11.963590,E,104.117 m,22.174 km/h,173.331863,8(9), 26.96 m, +589,T,2008/01/27,15:02:31.000,SPS,57.701395,N,11.963712,E,106.811 m,22.215 km/h,164.963943,8(9), 34.85 m, +590,T,2008/01/27,15:02:36.000,SPS,57.701177,N,11.963957,E,106.015 m,29.594 km/h,155.442062,8(9), 28.29 m, +591,T,2008/01/27,15:02:41.000,SPS,57.700984,N,11.964153,E,97.538 m,31.130 km/h,163.367905,7(9), 25.94 m, +592,T,2008/01/27,15:02:46.000,SPS,57.700625,N,11.964369,E,82.295 m,23.681 km/h,163.726883,7(9), 44.66 m, +593,T,2008/01/27,15:02:51.000,SPS,57.700461,N,11.964561,E,78.952 m,11.403 km/h,149.311813,8(9), 21.80 m, +594,T,2008/01/27,15:02:56.000,SPS,57.700303,N,11.964644,E,77.491 m,10.581 km/h,163.787460,8(9), 18.34 m, +595,T,2008/01/27,15:03:01.000,SPS,57.700128,N,11.964669,E,76.259 m,15.689 km/h,187.778702,8(9), 19.61 m, +596,T,2008/01/27,15:03:06.000,SPS,57.699922,N,11.964396,E,73.744 m,15.722 km/h,232.966171,9(9), 28.23 m, +597,T,2008/01/27,15:03:11.000,SPS,57.699828,N,11.964055,E,74.385 m,15.052 km/h,252.393066,8(9), 22.91 m, +598,T,2008/01/27,15:03:16.000,SPS,57.699731,N,11.963685,E,74.801 m,14.217 km/h,252.462280,8(9), 24.56 m, +599,T,2008/01/27,15:03:21.000,SPS,57.699674,N,11.963393,E,75.367 m,9.761 km/h,269.982666,8(9), 18.54 m, +600,T,2008/01/27,15:03:26.000,SPS,57.699590,N,11.963112,E,72.100 m,7.401 km/h,293.740234,8(9), 19.46 m, +601,T,2008/01/27,15:03:31.000,SPS,57.699510,N,11.962975,E,66.800 m,2.609 km/h,296.089447,8(9), 13.21 m, +602,T,2008/01/27,15:03:36.000,SPS,57.699515,N,11.962946,E,64.158 m,0.495 km/h,296.089447,8(9), 3.18 m, +603,T,2008/01/27,15:03:41.000,SPS,57.699518,N,11.962946,E,64.079 m,1.075 km/h,296.089447,8(9), 0.41 m, +604,T,2008/01/27,15:03:46.000,SPS,57.699552,N,11.962808,E,63.929 m,6.936 km/h,284.483185,8(9), 9.00 m, +605,T,2008/01/27,15:03:51.000,SPS,57.699558,N,11.962625,E,65.154 m,4.395 km/h,285.790466,8(9), 11.05 m, +606,T,2008/01/27,15:03:56.000,SPS,57.699567,N,11.962460,E,64.654 m,1.630 km/h,285.790466,8(9), 9.87 m, +607,T,2008/01/27,15:04:01.000,SPS,57.699556,N,11.962442,E,64.875 m,0.401 km/h,285.790466,8(9), 1.59 m, +608,T,2008/01/27,15:04:06.000,SPS,57.699559,N,11.962441,E,64.961 m,0.891 km/h,285.790466,8(9), 0.26 m, +609,T,2008/01/27,15:04:11.000,SPS,57.699568,N,11.962444,E,65.154 m,0.329 km/h,285.790466,8(9), 1.04 m, +610,T,2008/01/27,15:04:16.000,SPS,57.699571,N,11.962444,E,65.226 m,0.369 km/h,285.790466,8(9), 0.37 m, +611,T,2008/01/27,15:04:21.000,SPS,57.699574,N,11.962362,E,65.065 m,7.180 km/h,285.790466,8(9), 4.93 m, +612,T,2008/01/27,15:04:26.000,SPS,57.699596,N,11.962082,E,63.407 m,8.877 km/h,277.764008,8(9), 16.95 m, +613,T,2008/01/27,15:04:31.000,SPS,57.699492,N,11.961958,E,55.832 m,0.327 km/h,277.764008,8(9), 15.73 m, +614,T,2008/01/27,15:04:36.000,SPS,57.699486,N,11.961933,E,53.711 m,0.198 km/h,277.764008,8(9), 2.68 m, +615,T,2008/01/27,15:04:41.000,SPS,57.699490,N,11.961934,E,52.843 m,0.499 km/h,277.764008,8(9), 0.98 m, +616,T,2008/01/27,15:04:46.000,SPS,57.699494,N,11.961936,E,52.361 m,0.197 km/h,277.764008,9(9), 0.70 m, +617,T,2008/01/27,15:04:51.000,SPS,57.699494,N,11.961935,E,52.087 m,0.315 km/h,277.764008,9(9), 0.28 m, +618,T,2008/01/27,15:04:56.000,SPS,57.699494,N,11.961935,E,51.984 m,0.101 km/h,277.764008,8(9), 0.11 m, +619,T,2008/01/27,15:05:01.000,SPS,57.699493,N,11.961934,E,51.904 m,0.295 km/h,277.764008,8(9), 0.13 m, +620,T,2008/01/27,15:05:06.000,SPS,57.699496,N,11.961935,E,51.772 m,0.396 km/h,277.764008,9(9), 0.35 m, +621,T,2008/01/27,15:05:11.000,SPS,57.699502,N,11.961938,E,51.690 m,0.351 km/h,277.764008,9(9), 0.61 m, +622,T,2008/01/27,15:05:16.000,SPS,57.699501,N,11.961938,E,51.794 m,0.253 km/h,277.764008,9(9), 0.12 m, +623,T,2008/01/27,15:05:21.000,SPS,57.699517,N,11.961828,E,51.983 m,11.547 km/h,276.801270,8(9), 6.75 m, +624,T,2008/01/27,15:05:26.000,SPS,57.699560,N,11.961280,E,51.772 m,28.712 km/h,275.905151,8(9), 33.05 m, +625,T,2008/01/27,15:05:31.000,SPS,57.699546,N,11.960483,E,50.280 m,35.068 km/h,271.913940,8(9), 47.59 m, +626,T,2008/01/27,15:05:36.000,SPS,57.699593,N,11.959534,E,48.527 m,40.307 km/h,277.201416,6(9), 56.86 m, +627,T,2008/01/27,15:05:41.000,SPS,57.699642,N,11.958592,E,45.675 m,36.722 km/h,273.109436,8(9), 56.48 m, +628,T,2008/01/27,15:05:46.000,SPS,57.699673,N,11.957906,E,43.749 m,25.046 km/h,275.711426,5(9), 41.07 m, +629,T,2008/01/27,15:05:51.000,SPS,57.699676,N,11.957452,E,41.486 m,20.078 km/h,275.435974,8(9), 27.16 m, +630,T,2008/01/27,15:05:56.000,SPS,57.699712,N,11.956897,E,42.652 m,26.526 km/h,273.934418,8(9), 33.34 m, +631,T,2008/01/27,15:06:01.000,SPS,57.699719,N,11.956252,E,42.952 m,28.209 km/h,277.044312,8(9), 38.49 m, +632,T,2008/01/27,15:06:06.000,SPS,57.699766,N,11.955614,E,41.938 m,23.372 km/h,284.357452,8(9), 38.43 m, +633,T,2008/01/27,15:06:11.000,SPS,57.699812,N,11.955109,E,42.700 m,18.483 km/h,279.845184,7(9), 30.55 m, +634,T,2008/01/27,15:06:16.000,SPS,57.699837,N,11.954683,E,42.643 m,18.200 km/h,279.834869,8(9), 25.55 m, +635,T,2008/01/27,15:06:21.000,SPS,57.699884,N,11.954261,E,39.983 m,17.301 km/h,283.039490,8(9), 25.82 m, +636,T,2008/01/27,15:06:26.000,SPS,57.699908,N,11.953873,E,39.923 m,15.994 km/h,281.840302,6(9), 23.31 m, +637,T,2008/01/27,15:06:31.000,SPS,57.699890,N,11.953574,E,42.504 m,14.412 km/h,254.771011,8(9), 18.11 m, +638,T,2008/01/27,15:06:36.000,SPS,57.699854,N,11.953451,E,54.257 m,5.352 km/h,217.023911,8(9), 14.42 m, +639,T,2008/01/27,15:06:41.000,SPS,57.699876,N,11.953420,E,60.191 m,1.519 km/h,217.023911,9(9), 6.67 m, +640,T,2008/01/27,15:06:46.000,SPS,57.699912,N,11.953465,E,60.932 m,2.586 km/h,217.023911,8(9), 4.89 m, +641,T,2008/01/27,15:06:51.000,SPS,57.699927,N,11.953493,E,57.799 m,5.943 km/h,217.023911,8(9), 3.93 m, +642,T,2008/01/27,15:06:56.000,SPS,57.699944,N,11.953428,E,56.949 m,2.345 km/h,217.023911,7(9), 4.36 m, +643,T,2008/01/27,15:07:01.000,SPS,57.699939,N,11.953309,E,54.779 m,3.929 km/h,217.023911,8(9), 7.43 m, +644,T,2008/01/27,15:07:06.000,SPS,57.699934,N,11.953216,E,53.242 m,1.618 km/h,218.496490,7(9), 5.82 m, +645,T,2008/01/27,15:07:11.000,SPS,57.699944,N,11.953198,E,53.076 m,1.298 km/h,218.496490,8(9), 1.51 m, +646,T,2008/01/27,15:07:16.000,SPS,57.699935,N,11.953148,E,52.867 m,1.903 km/h,218.496490,8(9), 3.11 m, +647,T,2008/01/27,15:07:21.000,SPS,57.699927,N,11.953081,E,52.973 m,3.948 km/h,218.496490,8(9), 4.12 m, +648,T,2008/01/27,15:07:26.000,SPS,57.699943,N,11.952983,E,53.538 m,2.253 km/h,218.496490,8(9), 6.17 m, +649,T,2008/01/27,15:07:31.000,SPS,57.699942,N,11.952932,E,54.323 m,1.178 km/h,218.496490,7(9), 3.09 m, +650,T,2008/01/27,15:07:36.000,SPS,57.699937,N,11.952929,E,54.677 m,0.068 km/h,218.496490,8(9), 0.70 m, +651,T,2008/01/27,15:07:41.000,SPS,57.699936,N,11.952901,E,54.827 m,1.821 km/h,218.496490,8(9), 1.71 m, +652,T,2008/01/27,15:07:46.000,SPS,57.699919,N,11.952914,E,55.053 m,1.557 km/h,218.496490,7(9), 2.14 m, +653,T,2008/01/27,15:07:51.000,SPS,57.699920,N,11.952919,E,55.107 m,0.211 km/h,218.496490,7(9), 0.32 m, +654,T,2008/01/27,15:07:56.000,SPS,57.699920,N,11.952924,E,55.117 m,0.024 km/h,218.496490,7(9), 0.26 m, +655,T,2008/01/27,15:08:01.000,SPS,57.699920,N,11.952923,E,55.116 m,0.008 km/h,218.496490,7(9), 0.06 m, +656,T,2008/01/27,15:08:06.000,SPS,57.699921,N,11.952922,E,55.117 m,0.007 km/h,218.496490,7(9), 0.09 m, +657,T,2008/01/27,15:08:11.000,SPS,57.699921,N,11.952921,E,55.136 m,0.003 km/h,218.496490,7(9), 0.06 m, +658,T,2008/01/27,15:08:16.000,SPS,57.699921,N,11.952920,E,55.148 m,0.027 km/h,218.496490,7(9), 0.05 m, +659,T,2008/01/27,15:08:21.000,SPS,57.699921,N,11.952921,E,55.163 m,0.026 km/h,218.496490,7(9), 0.04 m, +660,T,2008/01/27,15:08:26.000,SPS,57.699922,N,11.952923,E,55.205 m,0.168 km/h,218.496490,8(9), 0.16 m, +661,T,2008/01/27,15:08:31.000,SPS,57.699922,N,11.952924,E,55.188 m,0.007 km/h,218.496490,8(9), 0.11 m, +662,T,2008/01/27,15:08:36.000,SPS,57.699923,N,11.952925,E,55.159 m,0.001 km/h,218.496490,7(9), 0.06 m, +663,T,2008/01/27,15:08:41.000,SPS,57.699923,N,11.952925,E,55.142 m,0.034 km/h,218.496490,6(9), 0.05 m, +664,T,2008/01/27,15:08:46.000,SPS,57.699923,N,11.952925,E,55.137 m,0.006 km/h,218.496490,8(9), 0.03 m, +665,T,2008/01/27,15:08:51.000,SPS,57.699924,N,11.952925,E,55.102 m,0.027 km/h,218.496490,7(9), 0.05 m, +666,T,2008/01/27,15:08:56.000,SPS,57.699928,N,11.952920,E,55.135 m,0.970 km/h,218.496490,8(9), 0.59 m, +667,T,2008/01/27,15:09:01.000,SPS,57.699939,N,11.952909,E,55.178 m,0.947 km/h,218.496490,7(9), 1.41 m, +668,T,2008/01/27,15:09:06.000,SPS,57.699945,N,11.952898,E,55.160 m,0.011 km/h,218.496490,8(9), 0.87 m, +669,T,2008/01/27,15:09:11.000,SPS,57.699945,N,11.952898,E,55.153 m,0.146 km/h,218.496490,8(9), 0.01 m, +670,T,2008/01/27,15:09:16.000,SPS,57.699945,N,11.952900,E,55.264 m,0.018 km/h,218.496490,7(9), 0.18 m, +671,T,2008/01/27,15:09:21.000,SPS,57.699945,N,11.952901,E,55.370 m,0.129 km/h,218.496490,7(9), 0.12 m, +672,T,2008/01/27,15:09:26.000,SPS,57.699945,N,11.952903,E,55.427 m,0.017 km/h,218.496490,7(9), 0.12 m, +673,T,2008/01/27,15:09:31.000,SPS,57.699946,N,11.952905,E,55.403 m,0.003 km/h,218.496490,7(9), 0.10 m, +674,T,2008/01/27,15:09:36.000,SPS,57.699948,N,11.952907,E,55.452 m,0.007 km/h,218.496490,6(9), 0.27 m, +675,T,2008/01/27,15:09:41.000,SPS,57.699949,N,11.952909,E,55.466 m,0.007 km/h,218.496490,7(9), 0.18 m, +676,T,2008/01/27,15:09:46.000,SPS,57.699949,N,11.952910,E,55.429 m,0.007 km/h,218.496490,7(9), 0.09 m, +677,T,2008/01/27,15:09:51.000,SPS,57.699949,N,11.952912,E,55.372 m,0.016 km/h,218.496490,8(9), 0.09 m, +678,T,2008/01/27,15:09:56.000,SPS,57.699950,N,11.952912,E,55.368 m,0.005 km/h,218.496490,7(9), 0.08 m, +679,T,2008/01/27,15:10:01.000,SPS,57.699950,N,11.952912,E,55.365 m,0.005 km/h,218.496490,7(9), 0.07 m, +680,T,2008/01/27,15:10:06.000,SPS,57.699951,N,11.952913,E,55.387 m,0.007 km/h,218.496490,7(9), 0.08 m, +681,T,2008/01/27,15:10:11.000,SPS,57.699951,N,11.952914,E,55.425 m,0.012 km/h,218.496490,7(9), 0.10 m, +682,T,2008/01/27,15:10:16.000,SPS,57.699952,N,11.952914,E,55.468 m,0.006 km/h,218.496490,7(9), 0.06 m, +683,T,2008/01/27,15:10:21.000,SPS,57.699952,N,11.952914,E,55.534 m,0.162 km/h,218.496490,8(9), 0.09 m, +684,T,2008/01/27,15:10:26.000,SPS,57.699953,N,11.952915,E,55.540 m,0.005 km/h,218.496490,7(9), 0.14 m, +685,T,2008/01/27,15:10:31.000,SPS,57.699954,N,11.952916,E,55.562 m,0.863 km/h,218.496490,7(9), 0.05 m, +686,T,2008/01/27,15:10:36.000,SPS,57.699957,N,11.952943,E,55.626 m,0.709 km/h,218.496490,7(9), 1.70 m, +687,T,2008/01/27,15:10:41.000,SPS,57.699957,N,11.952962,E,55.745 m,0.199 km/h,218.496490,8(9), 1.14 m, +688,T,2008/01/27,15:10:46.000,SPS,57.699957,N,11.952961,E,55.884 m,0.183 km/h,218.496490,8(9), 0.16 m, +689,T,2008/01/27,15:10:51.000,SPS,57.699956,N,11.952958,E,55.964 m,0.374 km/h,218.496490,6(9), 0.23 m, +690,T,2008/01/27,15:10:56.000,SPS,57.699962,N,11.952964,E,56.061 m,0.428 km/h,218.496490,6(9), 0.82 m, +691,T,2008/01/27,15:11:01.000,SPS,57.699963,N,11.952964,E,56.130 m,0.208 km/h,218.496490,6(9), 0.08 m, +692,T,2008/01/27,15:11:06.000,SPS,57.699962,N,11.952965,E,56.174 m,0.213 km/h,218.496490,6(9), 0.10 m, +693,T,2008/01/27,15:11:11.000,SPS,57.699963,N,11.952969,E,56.225 m,0.726 km/h,218.496490,8(9), 0.22 m, +694,T,2008/01/27,15:11:16.000,SPS,57.699962,N,11.952960,E,56.230 m,1.432 km/h,218.496490,7(9), 0.51 m, +695,T,2008/01/27,15:11:21.000,SPS,57.699956,N,11.952937,E,56.250 m,0.165 km/h,218.496490,7(9), 1.55 m, +696,T,2008/01/27,15:11:26.000,SPS,57.699957,N,11.952938,E,56.406 m,0.355 km/h,218.496490,7(9), 0.21 m, +697,T,2008/01/27,15:11:31.000,SPS,57.699957,N,11.952928,E,56.498 m,6.012 km/h,218.496490,7(9), 0.64 m, +698,T,2008/01/27,15:11:36.000,SPS,57.699972,N,11.952892,E,56.564 m,0.709 km/h,218.496490,7(9), 2.75 m, +699,T,2008/01/27,15:11:41.000,SPS,57.699970,N,11.952871,E,56.544 m,0.313 km/h,218.496490,8(9), 1.24 m, +700,T,2008/01/27,15:11:46.000,SPS,57.699971,N,11.952879,E,56.581 m,0.854 km/h,218.496490,8(9), 0.46 m, +701,T,2008/01/27,15:11:51.000,SPS,57.699974,N,11.952893,E,56.631 m,1.002 km/h,218.496490,8(9), 0.92 m, +702,T,2008/01/27,15:11:56.000,SPS,57.699977,N,11.952909,E,56.685 m,0.607 km/h,218.496490,8(9), 0.98 m, +703,T,2008/01/27,15:12:01.000,SPS,57.699976,N,11.952913,E,56.786 m,0.683 km/h,218.496490,7(9), 0.27 m, +704,T,2008/01/27,15:12:06.000,SPS,57.699973,N,11.952896,E,56.875 m,0.741 km/h,218.496490,7(9), 1.03 m, +705,T,2008/01/27,15:12:11.000,SPS,57.699971,N,11.952880,E,56.934 m,0.528 km/h,218.496490,7(9), 1.01 m, +706,T,2008/01/27,15:12:16.000,SPS,57.699969,N,11.952865,E,56.986 m,0.736 km/h,218.496490,7(9), 0.92 m, +707,T,2008/01/27,15:12:21.000,SPS,57.699968,N,11.952845,E,57.043 m,0.743 km/h,218.496490,7(9), 1.23 m, +708,T,2008/01/27,15:12:26.000,SPS,57.699969,N,11.952848,E,57.112 m,1.026 km/h,218.496490,8(9), 0.24 m, +709,T,2008/01/27,15:12:31.000,SPS,57.699974,N,11.952879,E,57.176 m,3.465 km/h,218.496490,8(9), 1.95 m, +710,T,2008/01/27,15:12:36.000,SPS,57.699849,N,11.953253,E,56.506 m,19.849 km/h,86.427399,8(9), 26.26 m, +711,T,2008/01/27,15:12:41.000,SPS,57.699865,N,11.953857,E,56.469 m,21.918 km/h,96.587524,8(9), 36.07 m, +712,T,2008/01/27,15:12:46.000,SPS,57.699947,N,11.954557,E,58.682 m,28.527 km/h,99.175896,7(9), 42.77 m, +713,T,2008/01/27,15:12:51.000,SPS,57.699934,N,11.955259,E,59.009 m,24.419 km/h,97.125023,8(9), 41.90 m, +714,T,2008/01/27,15:12:56.000,SPS,57.699900,N,11.955946,E,58.753 m,28.569 km/h,98.056587,6(9), 41.12 m, +715,T,2008/01/27,15:13:01.000,SPS,57.699845,N,11.956682,E,61.154 m,22.889 km/h,95.442360,7(9), 44.42 m, +716,T,2008/01/27,15:13:06.000,SPS,57.699756,N,11.957161,E,58.161 m,13.081 km/h,100.822197,8(9), 30.34 m, +717,T,2008/01/27,15:13:11.000,SPS,57.699721,N,11.957413,E,56.525 m,6.004 km/h,100.060211,7(9), 15.62 m, +718,T,2008/01/27,15:13:16.000,SPS,57.699653,N,11.957520,E,51.498 m,3.404 km/h,100.060211,7(9), 11.10 m, +719,T,2008/01/27,15:13:21.000,SPS,57.699639,N,11.957838,E,49.658 m,20.441 km/h,97.457619,6(9), 19.13 m, +720,T,2008/01/27,15:13:26.000,SPS,57.699576,N,11.958570,E,47.382 m,31.414 km/h,97.820015,7(9), 44.26 m, +721,T,2008/01/27,15:13:31.000,SPS,57.699543,N,11.959268,E,45.865 m,27.273 km/h,96.406525,6(9), 41.82 m, +722,T,2008/01/27,15:13:36.000,SPS,57.699506,N,11.959894,E,44.151 m,22.753 km/h,99.171577,7(9), 37.57 m, +723,T,2008/01/27,15:13:41.000,SPS,57.699466,N,11.960414,E,43.130 m,20.578 km/h,96.029564,6(9), 31.33 m, +724,T,2008/01/27,15:13:46.000,SPS,57.699564,N,11.960882,E,42.656 m,18.675 km/h,87.960152,7(9), 29.97 m, +725,T,2008/01/27,15:13:51.000,SPS,57.699614,N,11.961305,E,47.127 m,16.558 km/h,94.451820,7(9), 26.22 m, +726,T,2008/01/27,15:13:56.000,SPS,57.699580,N,11.961679,E,45.114 m,5.820 km/h,89.539085,7(9), 22.72 m, +727,T,2008/01/27,15:14:01.000,SPS,57.699556,N,11.961758,E,43.373 m,0.468 km/h,89.539085,8(9), 5.67 m, +728,T,2008/01/27,15:14:06.000,SPS,57.699557,N,11.961768,E,42.927 m,0.137 km/h,89.539085,7(9), 0.78 m, +729,T,2008/01/27,15:14:11.000,SPS,57.699557,N,11.961772,E,42.839 m,0.240 km/h,89.539085,6(9), 0.22 m, +730,T,2008/01/27,15:14:16.000,SPS,57.699556,N,11.961769,E,42.809 m,0.118 km/h,89.539085,6(9), 0.20 m, +731,T,2008/01/27,15:14:21.000,SPS,57.699546,N,11.961856,E,42.932 m,5.808 km/h,89.725197,7(10), 5.30 m, +732,T,2008/01/27,15:14:26.000,SPS,57.699521,N,11.962033,E,42.629 m,6.690 km/h,76.366776,7(10), 10.92 m, +733,T,2008/01/27,15:14:31.000,SPS,57.699462,N,11.962172,E,43.564 m,3.917 km/h,76.366776,6(9), 10.60 m, +734,T,2008/01/27,15:14:36.000,SPS,57.699441,N,11.962247,E,43.327 m,1.204 km/h,76.366776,6(10), 5.05 m, +735,T,2008/01/27,15:14:41.000,SPS,57.699439,N,11.962242,E,43.178 m,0.438 km/h,76.366776,6(10), 0.42 m, +736,T,2008/01/27,15:14:46.000,SPS,57.699439,N,11.962253,E,43.119 m,0.649 km/h,76.366776,6(10), 0.66 m, +737,T,2008/01/27,15:14:51.000,SPS,57.699438,N,11.962255,E,42.983 m,0.794 km/h,76.366776,6(10), 0.22 m, +738,T,2008/01/27,15:14:56.000,SPS,57.699437,N,11.962260,E,42.937 m,0.755 km/h,76.366776,6(10), 0.34 m, +739,T,2008/01/27,15:15:01.000,SPS,57.699437,N,11.962275,E,42.943 m,1.379 km/h,76.366776,6(10), 0.89 m, +740,T,2008/01/27,15:15:06.000,SPS,57.699440,N,11.962306,E,42.980 m,1.929 km/h,76.366776,7(10), 1.91 m, +741,T,2008/01/27,15:15:11.000,SPS,57.699436,N,11.962362,E,43.012 m,4.345 km/h,76.366776,7(10), 3.37 m, +742,T,2008/01/27,15:15:16.000,SPS,57.699433,N,11.962761,E,43.785 m,8.805 km/h,49.888649,7(10), 23.79 m, +743,T,2008/01/27,15:15:21.000,SPS,57.699514,N,11.963014,E,43.212 m,5.290 km/h,52.977341,7(10), 17.61 m, +744,T,2008/01/27,15:15:26.000,SPS,57.699556,N,11.963182,E,42.773 m,3.284 km/h,52.977341,6(10), 11.04 m, +745,T,2008/01/27,15:15:31.000,SPS,57.699584,N,11.963254,E,42.346 m,3.743 km/h,54.474190,7(9), 5.34 m, +746,T,2008/01/27,15:15:36.000,SPS,57.699627,N,11.963502,E,41.846 m,9.011 km/h,75.363075,7(10), 15.59 m, +747,T,2008/01/27,15:15:41.000,SPS,57.699844,N,11.964098,E,41.465 m,14.512 km/h,18.042631,7(10), 42.93 m, +748,T,2008/01/27,15:15:46.000,SPS,57.700103,N,11.964226,E,39.202 m,18.820 km/h,350.312469,7(10), 29.92 m, +749,T,2008/01/27,15:15:51.000,SPS,57.700418,N,11.964098,E,34.906 m,25.929 km/h,338.893219,7(9), 36.27 m, +750,T,2008/01/27,15:15:56.000,SPS,57.700756,N,11.963999,E,29.182 m,26.718 km/h,342.903381,7(10), 38.44 m, +751,T,2008/01/27,15:16:01.000,SPS,57.701148,N,11.963834,E,26.026 m,31.251 km/h,338.657623,7(10), 44.89 m, +752,T,2008/01/27,15:16:06.000,SPS,57.701490,N,11.963610,E,24.059 m,23.423 km/h,341.594208,7(10), 40.46 m, +753,T,2008/01/27,15:16:11.000,SPS,57.701792,N,11.963399,E,24.504 m,18.191 km/h,334.948120,7(9), 35.85 m, +754,T,2008/01/27,15:16:16.000,SPS,57.702045,N,11.963253,E,21.750 m,17.075 km/h,339.453552,7(10), 29.67 m, +755,T,2008/01/27,15:16:21.000,SPS,57.702263,N,11.963226,E,21.275 m,13.436 km/h,21.269533,7(10), 24.32 m, +756,T,2008/01/27,15:16:26.000,SPS,57.702456,N,11.963406,E,24.930 m,9.682 km/h,57.253983,7(10), 24.27 m, +757,T,2008/01/27,15:16:31.000,SPS,57.702516,N,11.963538,E,23.572 m,2.071 km/h,57.935402,7(10), 10.47 m, +758,T,2008/01/27,15:16:36.000,SPS,57.702541,N,11.963530,E,21.759 m,0.982 km/h,57.935402,7(10), 3.33 m, +759,T,2008/01/27,15:16:41.000,SPS,57.702547,N,11.963526,E,20.468 m,0.271 km/h,57.935402,7(10), 1.49 m, +760,T,2008/01/27,15:16:46.000,SPS,57.702546,N,11.963526,E,20.075 m,0.253 km/h,57.935402,7(10), 0.40 m, +761,T,2008/01/27,15:16:51.000,SPS,57.702555,N,11.963521,E,19.932 m,2.570 km/h,57.935402,7(9), 1.03 m, +762,T,2008/01/27,15:16:56.000,SPS,57.702602,N,11.963766,E,20.843 m,11.270 km/h,63.193348,7(10), 15.56 m, +763,T,2008/01/27,15:17:01.000,SPS,57.702688,N,11.964083,E,21.650 m,12.392 km/h,68.431618,7(10), 21.16 m, +764,T,2008/01/27,15:17:06.000,SPS,57.702856,N,11.964402,E,25.562 m,12.100 km/h,32.924171,7(10), 26.94 m, +765,T,2008/01/27,15:17:11.000,SPS,57.703016,N,11.964420,E,26.969 m,15.517 km/h,344.355225,7(10), 17.92 m, +766,T,2008/01/27,15:17:16.000,SPS,57.703240,N,11.964281,E,27.406 m,18.274 km/h,341.821838,7(10), 26.25 m, +767,T,2008/01/27,15:17:21.000,SPS,57.703472,N,11.964122,E,27.536 m,15.869 km/h,339.747223,7(10), 27.59 m, +768,T,2008/01/27,15:17:26.000,SPS,57.703719,N,11.964036,E,28.155 m,16.465 km/h,341.113464,7(9), 27.92 m, +769,T,2008/01/27,15:17:31.000,SPS,57.704018,N,11.963951,E,24.247 m,14.687 km/h,339.732819,7(10), 33.91 m, +770,T,2008/01/27,15:17:36.000,SPS,57.704236,N,11.963845,E,23.304 m,5.752 km/h,339.514862,7(10), 25.17 m, +771,T,2008/01/27,15:17:41.000,SPS,57.704273,N,11.963828,E,24.946 m,0.564 km/h,339.514862,7(10), 4.54 m, +772,T,2008/01/27,15:17:46.000,SPS,57.704274,N,11.963826,E,24.590 m,0.512 km/h,339.514862,7(10), 0.38 m, +773,T,2008/01/27,15:17:51.000,SPS,57.704285,N,11.963818,E,24.536 m,1.297 km/h,339.514862,7(10), 1.37 m, +774,T,2008/01/27,15:17:56.000,SPS,57.704305,N,11.963806,E,24.427 m,1.302 km/h,339.514862,7(10), 2.25 m, +775,T,2008/01/27,15:18:01.000,SPS,57.704318,N,11.963799,E,24.243 m,1.554 km/h,339.514862,7(10), 1.62 m, +776,T,2008/01/27,15:18:06.000,SPS,57.704341,N,11.963786,E,24.084 m,1.999 km/h,339.514862,7(10), 2.58 m, +777,T,2008/01/27,15:18:11.000,SPS,57.704430,N,11.963723,E,24.228 m,12.317 km/h,346.195099,7(10), 10.71 m, +778,T,2008/01/27,15:18:16.000,SPS,57.704655,N,11.963559,E,24.551 m,18.428 km/h,332.352997,7(10), 26.81 m, +779,T,2008/01/27,15:18:21.000,SPS,57.704830,N,11.963399,E,24.790 m,16.992 km/h,339.528839,7(10), 21.68 m, +780,T,2008/01/27,15:18:26.000,SPS,57.705047,N,11.963266,E,24.882 m,14.147 km/h,337.760681,7(10), 25.51 m, +781,T,2008/01/27,15:18:31.000,SPS,57.705213,N,11.963117,E,24.886 m,11.453 km/h,326.768158,7(9), 20.53 m, +782,T,2008/01/27,15:18:36.000,SPS,57.705493,N,11.963112,E,22.894 m,17.446 km/h,36.511124,7(9), 31.22 m, +783,T,2008/01/27,15:18:41.000,SPS,57.705665,N,11.963496,E,21.995 m,21.406 km/h,62.685516,7(10), 29.85 m, +784,T,2008/01/27,15:18:46.000,SPS,57.705844,N,11.963943,E,20.402 m,21.921 km/h,61.447033,7(10), 33.28 m, +785,T,2008/01/27,15:18:51.000,SPS,57.706063,N,11.964529,E,18.012 m,25.727 km/h,70.627136,7(10), 42.72 m, +786,T,2008/01/27,15:18:56.000,SPS,57.706222,N,11.964977,E,16.479 m,20.545 km/h,72.116966,7(10), 32.10 m, +787,T,2008/01/27,15:19:01.000,SPS,57.706334,N,11.965581,E,15.728 m,24.058 km/h,72.860649,6(10), 38.11 m, +788,T,2008/01/27,15:19:06.000,SPS,57.706398,N,11.966139,E,13.502 m,19.170 km/h,74.065750,6(10), 34.06 m, +789,T,2008/01/27,15:19:11.000,SPS,57.706418,N,11.966595,E,12.321 m,13.260 km/h,81.119461,6(10), 27.28 m, +790,T,2008/01/27,15:19:16.000,SPS,57.706455,N,11.966899,E,11.192 m,10.546 km/h,75.343231,6(9), 18.64 m, +791,T,2008/01/27,15:19:21.000,SPS,57.706396,N,11.967249,E,9.392 m,9.148 km/h,69.857574,6(8), 21.92 m, +792,T,2008/01/27,15:19:26.000,SPS,57.706404,N,11.967522,E,7.393 m,10.857 km/h,95.088768,7(9), 16.43 m, +793,T,2008/01/27,15:19:31.000,SPS,57.706431,N,11.967937,E,11.171 m,7.636 km/h,48.301205,7(9), 25.24 m, +794,T,2008/01/27,15:19:36.000,SPS,57.706615,N,11.968097,E,16.153 m,11.160 km/h,345.122620,7(9), 23.13 m, +795,T,2008/01/27,15:19:41.000,SPS,57.706757,N,11.968033,E,15.430 m,13.394 km/h,349.252014,6(9), 16.29 m, +796,T,2008/01/27,15:19:46.000,SPS,57.706944,N,11.968147,E,18.443 m,14.874 km/h,49.279705,7(9), 22.11 m, +797,T,2008/01/27,15:19:51.000,SPS,57.707026,N,11.968484,E,17.724 m,16.191 km/h,70.644554,7(8), 22.09 m, +798,T,2008/01/27,15:19:56.000,SPS,57.707104,N,11.968838,E,16.861 m,11.892 km/h,64.961960,7(9), 22.86 m, +799,T,2008/01/27,15:20:01.000,SPS,57.707146,N,11.968940,E,16.343 m,0.603 km/h,57.725773,7(9), 7.67 m, +800,T,2008/01/27,15:20:06.000,SPS,57.707140,N,11.968924,E,17.903 m,0.299 km/h,57.725773,7(8), 1.94 m, +801,T,2008/01/27,15:20:11.000,SPS,57.707141,N,11.968931,E,17.819 m,0.581 km/h,57.725773,7(9), 0.43 m, +802,T,2008/01/27,15:20:16.000,SPS,57.707144,N,11.968944,E,17.828 m,0.471 km/h,57.725773,7(9), 0.85 m, +803,T,2008/01/27,15:20:21.000,SPS,57.707147,N,11.968951,E,17.853 m,0.246 km/h,57.725773,7(9), 0.48 m, +804,T,2008/01/27,15:20:26.000,SPS,57.707150,N,11.968959,E,17.842 m,0.660 km/h,57.725773,7(9), 0.62 m, +805,T,2008/01/27,15:20:31.000,SPS,57.707154,N,11.968966,E,17.869 m,0.703 km/h,57.725773,6(9), 0.64 m, +806,T,2008/01/27,15:20:36.000,SPS,57.707162,N,11.968979,E,17.898 m,0.899 km/h,57.725773,6(9), 1.12 m, +807,T,2008/01/27,15:20:41.000,SPS,57.707166,N,11.968988,E,17.911 m,0.987 km/h,57.725773,6(9), 0.73 m, +808,T,2008/01/27,15:20:46.000,SPS,57.707168,N,11.968992,E,17.954 m,0.717 km/h,57.725773,6(9), 0.37 m, +809,T,2008/01/27,15:20:51.000,SPS,57.707169,N,11.968990,E,18.036 m,0.222 km/h,57.725773,6(9), 0.18 m, +810,T,2008/01/27,15:20:56.000,SPS,57.707171,N,11.968995,E,18.050 m,0.836 km/h,57.725773,6(9), 0.36 m, +811,T,2008/01/27,15:21:01.000,SPS,57.707206,N,11.969191,E,18.316 m,18.892 km/h,68.676346,6(9), 12.29 m, +812,T,2008/01/27,15:21:06.000,SPS,57.707278,N,11.969675,E,20.202 m,21.727 km/h,77.141609,6(9), 30.02 m, +813,T,2008/01/27,15:21:11.000,SPS,57.707349,N,11.970167,E,21.015 m,21.947 km/h,79.136803,7(9), 30.37 m, +814,T,2008/01/27,15:21:16.000,SPS,57.707424,N,11.970710,E,22.754 m,20.998 km/h,73.930702,7(9), 33.54 m, +815,B,2008/01/27,15:21:20.000,SPS,57.707448,N,11.971055,E,25.731 m,16.147 km/h,76.704651,7(9), 20.96 m, +816,T,2008/01/27,18:13:26.129,No fix,57.707409,N,11.971354,E,29.133 m,0.000 km/h,0.000000,0(0), 18.63 m, +817,T,2008/01/27,18:13:31.929,No fix,57.707409,N,11.971354,E,29.133 m,0.000 km/h,0.000000,0(4), 0.00 m, diff --git a/reference/track/mtk_logger.gpx b/reference/track/mtk_logger.gpx new file mode 100644 index 000000000..56fa96e3d --- /dev/null +++ b/reference/track/mtk_logger.gpx @@ -0,0 +1,7391 @@ + + + + + + 98.469612 + + WP0001 + WP0001 + WP0001 + none + + + 34.319580 + + WP0002 + WP0002 + WP0002 + 3d + 8 + + + 96.420593 + + WP0003 + WP0003 + WP0003 + 3d + 8 + + + 25.730627 + + WP0004 + WP0004 + WP0004 + 3d + 7 + + + Log every 5 sec, 100 m, 0 km/h + + + 98.469612 + + 0.000000 + 0.000000 + TP0001 + none + + + 98.469612 + + 0.000000 + 0.000000 + TP0002 + none + + + 98.469612 + + 0.000000 + 0.000000 + TP0003 + none + + + 98.469612 + + 0.000000 + 0.000000 + TP0004 + none + + + 98.469612 + + 0.000000 + 0.000000 + TP0005 + none + + + 98.469612 + + 0.000000 + 0.000000 + TP0006 + none + + + 98.469612 + + 0.000000 + 0.000000 + TP0007 + none + + + 98.469612 + + 0.000000 + 0.000000 + TP0008 + none + + + 98.469612 + + 0.000000 + 0.000000 + TP0009 + none + + + 98.469612 + + 0.000000 + 0.000000 + TP0010 + none + + + 98.408684 + + 0.000000 + 0.595044 + TP0011 + none + 2 + + + 98.469284 + + 0.000000 + 0.303619 + TP0012 + none + 2 + + + 22.479507 + + 0.000000 + 1.202394 + TP0013 + 3d + 6 + + + 32.486053 + + 0.000000 + 1.078671 + TP0014 + 3d + 6 + + + 34.286411 + + 0.000000 + 1.052290 + TP0015 + 3d + 8 + + + 33.625595 + + 0.000000 + 0.991739 + TP0016 + 3d + 8 + + + 34.133461 + + 0.000000 + 0.441197 + TP0017 + 3d + 8 + + + 34.461449 + + 0.000000 + 0.581685 + TP0018 + 3d + 8 + + + 34.240189 + + 0.000000 + 0.083656 + TP0019 + 3d + 9 + + + 34.319580 + + 0.000000 + 0.332716 + TP0020 + 3d + 8 + + + 34.183079 + + 0.000000 + 0.529361 + TP0021 + 3d + 8 + + + 34.388592 + + 0.000000 + 1.338508 + TP0022 + 3d + 9 + + + 34.792522 + + 0.000000 + 1.624839 + TP0023 + 3d + 9 + + + 35.034256 + + 0.000000 + 1.647150 + TP0024 + 3d + 9 + + + 35.393795 + + 0.000000 + 1.380853 + TP0025 + 3d + 9 + + + 34.952080 + + 145.024078 + 1.745507 + TP0026 + 3d + 9 + + + 36.920841 + + 142.223740 + 1.848763 + TP0027 + 3d + 8 + + + 36.358654 + + 144.998688 + 1.514581 + TP0028 + 3d + 8 + + + 35.561657 + + 144.998688 + 1.358067 + TP0029 + 3d + 9 + + + 35.367092 + + 144.998688 + 1.377709 + TP0030 + 3d + 9 + + + 35.278236 + + 144.998688 + 1.568756 + TP0031 + 3d + 9 + + + 34.554344 + + 144.998688 + 1.633001 + TP0032 + 3d + 9 + + + 35.263260 + + 144.998688 + 0.050764 + TP0033 + 3d + 9 + + + 35.184391 + + 144.998688 + 0.427177 + TP0034 + 3d + 8 + + + 35.184006 + + 144.998688 + 0.030582 + TP0035 + 3d + 8 + + + 35.194073 + + 144.998688 + 0.004273 + TP0036 + 3d + 8 + + + 35.194149 + + 144.998688 + 0.007845 + TP0037 + 3d + 9 + + + 35.195225 + + 144.998688 + 0.008956 + TP0038 + 3d + 8 + + + 35.154613 + + 144.998688 + 1.449671 + TP0039 + 3d + 8 + + + 36.225224 + + 148.006943 + 1.417506 + TP0040 + 3d + 7 + + + 35.693150 + + 145.174026 + 1.316705 + TP0041 + 3d + 9 + + + 36.124382 + + 145.174026 + 0.666859 + TP0042 + 3d + 9 + + + 34.864819 + + 145.174026 + 0.295886 + TP0043 + 3d + 8 + + + 34.707458 + + 145.174026 + 0.823240 + TP0044 + 3d + 9 + + + 35.034626 + + 145.174026 + 1.485445 + TP0045 + 3d + 8 + + + 35.846035 + + 145.174026 + 1.036942 + TP0046 + 3d + 9 + + + 36.722980 + + 193.604065 + 2.036720 + TP0047 + 3d + 9 + + + 36.815575 + + 193.604065 + 0.033974 + TP0048 + 3d + 9 + + + 36.775021 + + 193.604065 + 0.102273 + TP0049 + 3d + 9 + + + 36.755974 + + 193.604065 + 0.336602 + TP0050 + 3d + 8 + + + 36.742401 + + 193.604065 + 0.485956 + TP0051 + 3d + 9 + + + 36.739773 + + 193.604065 + 0.192314 + TP0052 + 3d + 9 + + + 36.762974 + + 193.604065 + 1.067858 + TP0053 + 3d + 7 + + + 36.767914 + + 351.843750 + 2.428406 + TP0054 + 3d + 8 + + + 37.722569 + + 2.294798 + 0.254981 + TP0055 + 3d + 7 + + + 38.270573 + + 2.294798 + 0.739139 + TP0056 + 3d + 9 + + + 39.400570 + + 2.294798 + 1.418809 + TP0057 + 3d + 9 + + + 42.657951 + + 2.294798 + 1.219950 + TP0058 + 3d + 9 + + + 44.570877 + + 143.381439 + 1.271205 + TP0059 + 3d + 9 + + + 46.084393 + + 143.381439 + 1.521001 + TP0060 + 3d + 9 + + + 47.521702 + + 143.381439 + 1.205074 + TP0061 + 3d + 9 + + + 46.846340 + + 140.877411 + 1.394174 + TP0062 + 3d + 9 + + + 42.743946 + + 140.877411 + 1.373265 + TP0063 + 3d + 9 + + + 41.074448 + + 140.877411 + 1.949689 + TP0064 + 3d + 7 + + + 53.912285 + + 142.614777 + 1.026324 + TP0065 + 3d + 9 + + + 57.604111 + + 142.614777 + 1.223418 + TP0066 + 3d + 9 + + + 59.425282 + + 144.389893 + 1.751635 + TP0067 + 3d + 9 + + + 59.241436 + + 144.389893 + 1.294486 + TP0068 + 3d + 8 + + + 56.955845 + + 144.389893 + 1.647364 + TP0069 + 3d + 7 + + + 55.168156 + + 144.389893 + 1.607520 + TP0070 + 3d + 8 + + + 52.903522 + + 142.798004 + 1.142946 + TP0071 + 3d + 8 + + + 52.243340 + + 142.798004 + 1.183903 + TP0072 + 3d + 9 + + + 53.329205 + + 142.798004 + 0.747410 + TP0073 + 3d + 9 + + + 51.154198 + + 142.798004 + 1.393951 + TP0074 + 3d + 9 + + + 50.982079 + + 142.061447 + 0.568036 + TP0075 + 3d + 9 + + + 50.856762 + + 142.061447 + 1.264928 + TP0076 + 3d + 7 + + + 49.895744 + + 142.061447 + 1.597790 + TP0077 + 3d + 8 + + + 46.709484 + + 152.146713 + 1.557961 + TP0078 + 3d + 8 + + + 43.882195 + + 153.529343 + 1.451341 + TP0079 + 3d + 8 + + + 41.683334 + + 153.529343 + 1.783310 + TP0080 + 3d + 8 + + + 42.076900 + + 153.663147 + 1.164113 + TP0081 + 3d + 9 + + + 40.519577 + + 153.663147 + 1.421694 + TP0082 + 3d + 8 + + + 40.441086 + + 150.640991 + 1.617561 + TP0083 + 3d + 9 + + + 38.741417 + + 150.640991 + 1.615349 + TP0084 + 3d + 8 + + + 40.093151 + + 149.428802 + 1.545561 + TP0085 + 3d + 8 + + + 43.699978 + + 149.875687 + 1.716336 + TP0086 + 3d + 9 + + + 45.618553 + + 152.252014 + 1.283200 + TP0087 + 3d + 9 + + + 45.382668 + + 152.252014 + 1.692029 + TP0088 + 3d + 8 + + + 43.774300 + + 152.252014 + 1.408383 + TP0089 + 3d + 8 + + + 42.711369 + + 149.309753 + 1.432592 + TP0090 + 3d + 8 + + + 41.587543 + + 149.309753 + 1.508936 + TP0091 + 3d + 9 + + + 39.019386 + + 149.309753 + 1.569397 + TP0092 + 3d + 9 + + + 37.535275 + + 149.309753 + 1.275553 + TP0093 + 3d + 8 + + + 37.183327 + + 149.309753 + 1.765915 + TP0094 + 3d + 9 + + + 35.909645 + + 145.645874 + 1.477868 + TP0095 + 3d + 9 + + + 36.647190 + + 148.902954 + 1.543354 + TP0096 + 3d + 9 + + + 35.835602 + + 144.122391 + 1.388543 + TP0097 + 3d + 9 + + + 35.017097 + + 146.880249 + 1.644109 + TP0098 + 3d + 9 + + + 35.753429 + + 148.921082 + 1.730035 + TP0099 + 3d + 9 + + + 35.330765 + + 150.968842 + 1.515581 + TP0100 + 3d + 9 + + + 36.076145 + + 150.968842 + 1.840335 + TP0101 + 3d + 9 + + + 35.706478 + + 148.422119 + 1.373394 + TP0102 + 3d + 9 + + + 35.922268 + + 148.422119 + 1.590267 + TP0103 + 3d + 9 + + + 36.544731 + + 151.107529 + 1.409475 + TP0104 + 3d + 9 + + + 36.327339 + + 151.107529 + 1.554864 + TP0105 + 3d + 9 + + + 37.919357 + + 151.477859 + 1.751008 + TP0106 + 3d + 9 + + + 37.317135 + + 151.477859 + 1.522876 + TP0107 + 3d + 8 + + + 37.531166 + + 151.477859 + 1.714622 + TP0108 + 3d + 9 + + + 36.046326 + + 152.840408 + 1.502839 + TP0109 + 3d + 9 + + + 35.769428 + + 149.361832 + 1.327224 + TP0110 + 3d + 9 + + + 36.368031 + + 152.900650 + 1.765702 + TP0111 + 3d + 9 + + + 36.278912 + + 151.154800 + 1.519747 + TP0112 + 3d + 9 + + + 36.259140 + + 147.538422 + 1.362496 + TP0113 + 3d + 9 + + + 37.068027 + + 147.538422 + 1.420440 + TP0114 + 3d + 9 + + + 37.290741 + + 147.538422 + 1.322631 + TP0115 + 3d + 9 + + + 36.767784 + + 147.538422 + 0.003731 + TP0116 + 3d + 9 + + + 36.756531 + + 147.538422 + 0.005525 + TP0117 + 3d + 9 + + + 36.756294 + + 147.538422 + 0.357651 + TP0118 + 3d + 9 + + + 36.850208 + + 147.538422 + 0.008619 + TP0119 + 3d + 9 + + + 36.804157 + + 147.397430 + 1.517090 + TP0120 + 3d + 9 + + + 37.637447 + + 146.144302 + 1.761965 + TP0121 + 3d + 9 + + + 37.108601 + + 146.144302 + 1.467335 + TP0122 + 3d + 9 + + + 36.777046 + + 142.318588 + 1.496280 + TP0123 + 3d + 9 + + + 36.541397 + + 141.388947 + 1.330305 + TP0124 + 3d + 9 + + + 37.536469 + + 143.495270 + 1.198822 + TP0125 + 3d + 9 + + + 38.682537 + + 143.495270 + 1.067729 + TP0126 + 3d + 9 + + + 40.179867 + + 143.495270 + 1.624703 + TP0127 + 3d + 8 + + + 40.463760 + + 143.495270 + 0.698972 + TP0128 + 3d + 8 + + + 40.150234 + + 142.500504 + 1.356076 + TP0129 + 3d + 8 + + + 41.289188 + + 142.500504 + 1.253808 + TP0130 + 3d + 9 + + + 43.596752 + + 142.500504 + 1.438421 + TP0131 + 3d + 8 + + + 45.536652 + + 144.574066 + 1.567921 + TP0132 + 3d + 9 + + + 46.517883 + + 144.574066 + 1.231057 + TP0133 + 3d + 9 + + + 47.777119 + + 144.574066 + 1.233039 + TP0134 + 3d + 9 + + + 47.737053 + + 139.446564 + 1.574051 + TP0135 + 3d + 9 + + + 48.639462 + + 139.909683 + 1.701256 + TP0136 + 3d + 7 + + + 49.968063 + + 139.909683 + 1.306830 + TP0137 + 3d + 8 + + + 52.496399 + + 140.883011 + 1.270463 + TP0138 + 3d + 8 + + + 55.388054 + + 142.145920 + 1.708128 + TP0139 + 3d + 8 + + + 57.298538 + + 141.485916 + 1.370716 + TP0140 + 3d + 8 + + + 58.614559 + + 139.331635 + 1.306925 + TP0141 + 3d + 8 + + + 61.026787 + + 140.293564 + 1.095566 + TP0142 + 3d + 8 + + + 63.130711 + + 142.518753 + 1.669077 + TP0143 + 3d + 8 + + + 64.941925 + + 142.518753 + 1.363789 + TP0144 + 3d + 8 + + + 65.995216 + + 143.172440 + 1.436229 + TP0145 + 3d + 8 + + + 66.960083 + + 143.604630 + 1.676285 + TP0146 + 3d + 8 + + + 66.496315 + + 143.604630 + 1.599863 + TP0147 + 3d + 8 + + + 66.284981 + + 144.729324 + 1.224165 + TP0148 + 3d + 8 + + + 54.863914 + + 141.792358 + 1.480727 + TP0149 + 3d + 8 + + + 49.538685 + + 141.792358 + 1.367680 + TP0150 + 3d + 8 + + + 48.265648 + + 138.983597 + 1.635845 + TP0151 + 3d + 8 + + + 46.361546 + + 154.235672 + 2.004167 + TP0152 + 3d + 8 + + + 45.062138 + + 152.009735 + 1.570184 + TP0153 + 3d + 7 + + + 45.015408 + + 152.009735 + 1.360496 + TP0154 + 3d + 8 + + + 46.407997 + + 146.927551 + 1.442805 + TP0155 + 3d + 8 + + + 48.431839 + + 144.441391 + 1.576182 + TP0156 + 3d + 8 + + + 50.567123 + + 148.208267 + 1.192787 + TP0157 + 3d + 8 + + + 51.602558 + + 148.208267 + 1.119605 + TP0158 + 3d + 8 + + + 53.745941 + + 148.208267 + 1.571468 + TP0159 + 3d + 8 + + + 56.361366 + + 148.971863 + 1.579011 + TP0160 + 3d + 8 + + + 58.787598 + + 146.601395 + 1.278249 + TP0161 + 3d + 8 + + + 60.957695 + + 148.007050 + 1.162211 + TP0162 + 3d + 9 + + + 63.889812 + + 148.007050 + 1.649157 + TP0163 + 3d + 9 + + + 67.956284 + + 149.515228 + 1.289196 + TP0164 + 3d + 8 + + + 71.878624 + + 149.515228 + 1.561889 + TP0165 + 3d + 9 + + + 74.785545 + + 149.515228 + 1.305686 + TP0166 + 3d + 9 + + + 77.086639 + + 149.515228 + 1.195862 + TP0167 + 3d + 8 + + + 78.694016 + + 147.837906 + 1.020726 + TP0168 + 3d + 8 + + + 74.406738 + + 147.837906 + 0.907884 + TP0169 + 3d + 9 + + + 70.901184 + + 147.837906 + 1.467844 + TP0170 + 3d + 7 + + + 69.342346 + + 148.045532 + 1.515221 + TP0171 + 3d + 7 + + + 69.502632 + + 148.045532 + 1.191063 + TP0172 + 3d + 9 + + + 74.142738 + + 148.045532 + 1.293753 + TP0173 + 3d + 8 + + + 77.762215 + + 146.587997 + 1.302800 + TP0174 + 3d + 8 + + + 82.254944 + + 146.587997 + 1.213632 + TP0175 + 3d + 9 + + + 86.902519 + + 146.587997 + 1.156784 + TP0176 + 3d + 9 + + + 91.039124 + + 146.587997 + 0.765005 + TP0177 + 3d + 9 + + + 95.986641 + + 146.587997 + 1.417850 + TP0178 + 3d + 8 + + + 101.368256 + + 146.587997 + 1.227613 + TP0179 + 3d + 8 + + + 108.444229 + + 148.233871 + 1.070183 + TP0180 + 3d + 9 + + + 112.981300 + + 148.233871 + 0.820349 + TP0181 + 3d + 8 + + + 119.031311 + + 150.412949 + 0.733967 + TP0182 + 3d + 8 + + + 124.015923 + + 150.412949 + 0.964730 + TP0183 + 3d + 8 + + + 128.919205 + + 149.867859 + 1.578155 + TP0184 + 3d + 9 + + + 135.981369 + + 149.867859 + 0.857911 + TP0185 + 3d + 9 + + + 142.060516 + + 152.427673 + 1.470509 + TP0186 + 3d + 9 + + + 145.621017 + + 152.427673 + 1.155793 + TP0187 + 3d + 8 + + + 147.339279 + + 152.427673 + 1.291424 + TP0188 + 3d + 9 + + + 147.914948 + + 152.427673 + 0.295060 + TP0189 + 3d + 8 + + + 149.005646 + + 152.427673 + 0.184193 + TP0190 + 3d + 8 + + + 149.274536 + + 152.427673 + 0.232211 + TP0191 + 3d + 8 + + + 149.182236 + + 152.427673 + 0.211573 + TP0192 + 3d + 8 + + + 148.905640 + + 152.427673 + 0.075801 + TP0193 + 3d + 8 + + + 148.809921 + + 152.427673 + 1.196584 + TP0194 + 3d + 8 + + + 135.016083 + + 152.427673 + 0.852625 + TP0195 + 3d + 8 + + + 127.506874 + + 151.834854 + 0.630221 + TP0196 + 3d + 8 + + + 125.575233 + + 151.834854 + 1.000494 + TP0197 + 3d + 8 + + + 124.096199 + + 151.834854 + 0.736805 + TP0198 + 3d + 9 + + + 125.293076 + + 151.834854 + 1.544690 + TP0199 + 3d + 8 + + + 126.160484 + + 151.834854 + 1.657514 + TP0200 + 3d + 9 + + + 126.888947 + + 151.834854 + 1.238977 + TP0201 + 3d + 8 + + + 127.783066 + + 151.834854 + 1.162266 + TP0202 + 3d + 8 + + + 127.161171 + + 151.834854 + 0.525801 + TP0203 + 3d + 8 + + + 127.212303 + + 151.709610 + 0.841543 + TP0204 + 3d + 8 + + + 122.669693 + + 150.292557 + 1.061839 + TP0205 + 3d + 9 + + + 119.508095 + + 150.292557 + 1.193486 + TP0206 + 3d + 9 + + + 118.256752 + + 152.138992 + 0.891211 + TP0207 + 3d + 8 + + + 114.822960 + + 152.138992 + 1.624389 + TP0208 + 3d + 9 + + + 109.670013 + + 152.138992 + 1.206295 + TP0209 + 3d + 8 + + + 105.505707 + + 151.187805 + 1.535839 + TP0210 + 3d + 8 + + + 103.665871 + + 149.160706 + 1.349027 + TP0211 + 3d + 9 + + + 105.252121 + + 147.681824 + 1.299929 + TP0212 + 3d + 8 + + + 106.092033 + + 147.681824 + 1.171165 + TP0213 + 3d + 8 + + + 104.699776 + + 147.681824 + 1.726084 + TP0214 + 3d + 8 + + + 104.697060 + + 147.681824 + 1.279907 + TP0215 + 3d + 9 + + + 106.037743 + + 144.817627 + 1.258147 + TP0216 + 3d + 7 + + + 103.740364 + + 143.690689 + 1.579578 + TP0217 + 3d + 8 + + + 100.027649 + + 143.690689 + 1.073990 + TP0218 + 3d + 8 + + + 96.331116 + + 171.598877 + 1.557547 + TP0219 + 3d + 8 + + + 89.904938 + + 175.468765 + 1.955361 + TP0220 + 3d + 7 + + + 84.426712 + + 175.468765 + 1.291836 + TP0221 + 3d + 8 + + + 83.600838 + + 175.468765 + 1.551400 + TP0222 + 3d + 8 + + + 86.592972 + + 175.468765 + 1.283579 + TP0223 + 3d + 9 + + + 89.464699 + + 175.468765 + 1.505165 + TP0224 + 3d + 9 + + + 87.773705 + + 175.468765 + 1.161298 + TP0225 + 3d + 9 + + + 95.692902 + + 175.468765 + 1.088356 + TP0226 + 3d + 9 + + + 92.201309 + + 175.468765 + 0.362650 + TP0227 + 3d + 9 + + + 95.842636 + + 175.468765 + 0.377014 + TP0228 + 3d + 9 + + + 96.420593 + + 175.468765 + 0.340517 + TP0229 + 3d + 8 + + + 97.553391 + + 175.468765 + 0.096594 + TP0230 + 3d + 9 + + + 97.997795 + + 175.468765 + 0.206676 + TP0231 + 3d + 9 + + + 96.477997 + + 175.468765 + 1.065818 + TP0232 + 3d + 9 + + + 89.552612 + + 175.468765 + 1.232277 + TP0233 + 3d + 8 + + + 83.425354 + + 175.468765 + 1.217340 + TP0234 + 3d + 9 + + + 79.042557 + + 175.468765 + 1.393529 + TP0235 + 3d + 9 + + + 75.905380 + + 175.468765 + 1.738409 + TP0236 + 3d + 9 + + + 72.990585 + + 175.468765 + 1.682981 + TP0237 + 3d + 9 + + + 69.762535 + + 175.468765 + 1.189377 + TP0238 + 3d + 8 + + + 64.873619 + + 175.468765 + 1.531558 + TP0239 + 3d + 8 + + + 61.687244 + + 175.468765 + 1.349966 + TP0240 + 3d + 9 + + + 60.878510 + + 175.468765 + 1.811747 + TP0241 + 3d + 9 + + + 60.912205 + + 175.468765 + 1.351255 + TP0242 + 3d + 8 + + + 61.898537 + + 175.468765 + 1.227153 + TP0243 + 3d + 9 + + + 64.165245 + + 175.468765 + 1.598597 + TP0244 + 3d + 9 + + + 68.273476 + + 175.468765 + 0.935148 + TP0245 + 3d + 9 + + + 69.860306 + + 175.468765 + 1.053721 + TP0246 + 3d + 9 + + + 69.197311 + + 175.468765 + 0.918024 + TP0247 + 3d + 9 + + + 66.017838 + + 175.468765 + 1.308921 + TP0248 + 3d + 8 + + + 63.116501 + + 175.468765 + 1.576381 + TP0249 + 3d + 8 + + + 62.031185 + + 175.468765 + 1.214055 + TP0250 + 3d + 8 + + + 63.191040 + + 175.468765 + 1.318986 + TP0251 + 3d + 8 + + + 63.152187 + + 175.468765 + 1.330799 + TP0252 + 3d + 8 + + + 64.187660 + + 175.468765 + 1.029365 + TP0253 + 3d + 8 + + + 62.522697 + + 175.468765 + 1.288271 + TP0254 + 3d + 9 + + + 59.038860 + + 175.468765 + 1.265553 + TP0255 + 3d + 8 + + + 58.767090 + + 175.468765 + 1.409092 + TP0256 + 3d + 9 + + + 58.772144 + + 175.468765 + 1.408163 + TP0257 + 3d + 8 + + + 59.631092 + + 175.468765 + 1.528380 + TP0258 + 3d + 8 + + + 59.825020 + + 175.468765 + 1.146875 + TP0259 + 3d + 8 + + + 59.702190 + + 175.468765 + 1.329110 + TP0260 + 3d + 9 + + + 57.374817 + + 175.468765 + 0.666853 + TP0261 + 3d + 8 + + + 57.712070 + + 175.468765 + 0.034337 + TP0262 + 3d + 9 + + + 57.753304 + + 175.468765 + 0.007648 + TP0263 + 3d + 8 + + + 57.740093 + + 175.468765 + 0.008052 + TP0264 + 3d + 8 + + + 57.764366 + + 175.468765 + 1.399782 + TP0265 + 3d + 9 + + + 56.159416 + + 175.468765 + 1.870218 + TP0266 + 3d + 8 + + + 51.599651 + + 175.468765 + 1.362844 + TP0267 + 3d + 9 + + + 50.687393 + + 175.468765 + 1.824428 + TP0268 + 3d + 8 + + + 51.726231 + + 175.468765 + 1.349397 + TP0269 + 3d + 8 + + + 53.611576 + + 175.468765 + 1.531711 + TP0270 + 3d + 9 + + + 54.669785 + + 175.468765 + 1.658979 + TP0271 + 3d + 8 + + + 56.635204 + + 175.468765 + 1.808275 + TP0272 + 3d + 8 + + + 59.525986 + + 175.468765 + 1.080695 + TP0273 + 3d + 9 + + + 61.831104 + + 175.468765 + 1.497532 + TP0274 + 3d + 9 + + + 63.125233 + + 175.468765 + 0.938251 + TP0275 + 3d + 8 + + + 65.140114 + + 175.468765 + 1.955553 + TP0276 + 3d + 8 + + + 63.122700 + + 175.468765 + 0.980393 + TP0277 + 3d + 8 + + + 63.094830 + + 175.468765 + 0.562485 + TP0278 + 3d + 9 + + + 64.548813 + + 175.468765 + 0.210463 + TP0279 + 3d + 9 + + + 65.330444 + + 175.468765 + 0.091049 + TP0280 + 3d + 9 + + + 65.650665 + + 175.468765 + 0.703038 + TP0281 + 3d + 8 + + + 65.962677 + + 175.468765 + 0.581965 + TP0282 + 3d + 8 + + + 66.271774 + + 175.468765 + 0.555606 + TP0283 + 3d + 8 + + + 66.537361 + + 175.468765 + 0.640316 + TP0284 + 3d + 8 + + + 66.843864 + + 175.468765 + 0.203543 + TP0285 + 3d + 8 + + + 66.999008 + + 175.468765 + 0.052765 + TP0286 + 3d + 9 + + + 67.045273 + + 175.468765 + 0.103190 + TP0287 + 3d + 8 + + + 67.063019 + + 175.468765 + 0.446828 + TP0288 + 3d + 9 + + + 67.085609 + + 175.468765 + 0.461187 + TP0289 + 3d + 9 + + + 67.109024 + + 175.468765 + 0.192227 + TP0290 + 3d + 9 + + + 67.115768 + + 175.468765 + 0.138321 + TP0291 + 3d + 9 + + + 67.122627 + + 175.468765 + 0.126840 + TP0292 + 3d + 9 + + + 67.126030 + + 175.468765 + 0.526896 + TP0293 + 3d + 9 + + + 67.145798 + + 175.468765 + 0.868801 + TP0294 + 3d + 8 + + + 67.190155 + + 175.468765 + 0.743607 + TP0295 + 3d + 8 + + + 67.274750 + + 175.468765 + 0.594341 + TP0296 + 3d + 7 + + + 67.238174 + + 175.468765 + 0.597670 + TP0297 + 3d + 7 + + + 67.196770 + + 175.468765 + 0.635388 + TP0298 + 3d + 7 + + + 67.123039 + + 175.468765 + 0.721896 + TP0299 + 3d + 8 + + + 67.029480 + + 175.468765 + 0.509246 + TP0300 + 3d + 7 + + + 66.982285 + + 175.468765 + 0.084961 + TP0301 + 3d + 7 + + + 66.994843 + + 175.468765 + 0.467561 + TP0302 + 3d + 7 + + + 67.050613 + + 175.468765 + 0.171006 + TP0303 + 3d + 8 + + + 67.175125 + + 175.468765 + 0.259222 + TP0304 + 3d + 8 + + + 67.189331 + + 175.468765 + 0.163483 + TP0305 + 3d + 8 + + + 67.107552 + + 175.468765 + 0.943069 + TP0306 + 3d + 8 + + + 67.007812 + + 175.468765 + 0.276720 + TP0307 + 3d + 8 + + + 66.901794 + + 175.468765 + 0.131728 + TP0308 + 3d + 7 + + + 66.823387 + + 175.468765 + 0.441979 + TP0309 + 3d + 8 + + + 66.704353 + + 175.468765 + 0.559136 + TP0310 + 3d + 8 + + + 66.499146 + + 175.468765 + 0.881640 + TP0311 + 3d + 8 + + + 66.373116 + + 175.468765 + 1.139266 + TP0312 + 3d + 9 + + + 62.448307 + + 175.468765 + 1.584432 + TP0313 + 3d + 9 + + + 63.711189 + + 175.468765 + 0.537779 + TP0314 + 3d + 9 + + + 65.081207 + + 175.468765 + 1.460763 + TP0315 + 3d + 8 + + + 65.331810 + + 175.468765 + 0.471566 + TP0316 + 3d + 9 + + + 65.433136 + + 175.468765 + 1.028151 + TP0317 + 3d + 9 + + + 68.669930 + + 175.468765 + 1.090684 + TP0318 + 3d + 8 + + + 67.727882 + + 175.468765 + 1.121583 + TP0319 + 3d + 8 + + + 67.210159 + + 175.468765 + 1.221953 + TP0320 + 3d + 9 + + + 67.460991 + + 175.468765 + 1.380647 + TP0321 + 3d + 9 + + + 67.406555 + + 175.468765 + 1.339889 + TP0322 + 3d + 8 + + + 67.934387 + + 175.468765 + 1.000727 + TP0323 + 3d + 9 + + + 68.325150 + + 175.468765 + 1.120354 + TP0324 + 3d + 8 + + + 68.265938 + + 175.468765 + 1.248476 + TP0325 + 3d + 8 + + + 66.727936 + + 312.802246 + 2.078804 + TP0326 + 3d + 9 + + + 66.767967 + + 312.802246 + 1.515785 + TP0327 + 3d + 9 + + + 64.711159 + + 313.321777 + 1.331840 + TP0328 + 3d + 8 + + + 59.310825 + + 308.333649 + 1.644789 + TP0329 + 3d + 8 + + + 55.797432 + + 308.333649 + 1.578672 + TP0330 + 3d + 9 + + + 53.861481 + + 308.333649 + 1.274700 + TP0331 + 3d + 8 + + + 53.175739 + + 308.138123 + 1.346282 + TP0332 + 3d + 9 + + + 52.071518 + + 308.138123 + 1.086786 + TP0333 + 3d + 8 + + + 48.707954 + + 308.138123 + 1.628884 + TP0334 + 3d + 8 + + + 46.551117 + + 308.138123 + 1.271425 + TP0335 + 3d + 8 + + + 45.544510 + + 308.138123 + 1.525444 + TP0336 + 3d + 8 + + + 44.028717 + + 307.519714 + 1.813896 + TP0337 + 3d + 8 + + + 43.179455 + + 307.519714 + 1.620501 + TP0338 + 3d + 9 + + + 44.183289 + + 307.519714 + 1.121122 + TP0339 + 3d + 9 + + + 44.197002 + + 307.519714 + 1.351534 + TP0340 + 3d + 9 + + + 44.851364 + + 309.039703 + 0.850725 + TP0341 + 3d + 9 + + + 46.545170 + + 312.476257 + 0.958556 + TP0342 + 3d + 9 + + + 48.676037 + + 312.476257 + 1.167243 + TP0343 + 3d + 9 + + + 51.464268 + + 313.447083 + 1.254220 + TP0344 + 3d + 9 + + + 52.665562 + + 313.648682 + 1.048820 + TP0345 + 3d + 9 + + + 54.015507 + + 313.648682 + 1.486100 + TP0346 + 3d + 9 + + + 55.014637 + + 313.648682 + 1.225496 + TP0347 + 3d + 9 + + + 55.862492 + + 313.648682 + 1.440006 + TP0348 + 3d + 8 + + + 59.842957 + + 315.012482 + 1.003200 + TP0349 + 3d + 10 + + + 62.616528 + + 315.592804 + 1.093873 + TP0350 + 3d + 9 + + + 65.984482 + + 315.939636 + 1.132645 + TP0351 + 3d + 9 + + + 68.956490 + + 315.939636 + 1.362898 + TP0352 + 3d + 9 + + + 64.422302 + + 319.429626 + 1.168481 + TP0353 + 3d + 9 + + + 57.506542 + + 319.429626 + 1.093485 + TP0354 + 3d + 9 + + + 53.629463 + + 319.429626 + 1.666819 + TP0355 + 3d + 9 + + + 51.207535 + + 319.429626 + 1.139789 + TP0356 + 3d + 8 + + + 50.054111 + + 319.604919 + 1.219204 + TP0357 + 3d + 8 + + + 51.180580 + + 319.773590 + 1.200754 + TP0358 + 3d + 9 + + + 50.299816 + + 319.422302 + 1.659349 + TP0359 + 3d + 9 + + + 47.162354 + + 319.306824 + 1.243625 + TP0360 + 3d + 9 + + + 43.651794 + + 318.747681 + 1.517840 + TP0361 + 3d + 9 + + + 41.516739 + + 321.181732 + 1.798075 + TP0362 + 3d + 9 + + + 42.297428 + + 321.181732 + 1.856496 + TP0363 + 3d + 8 + + + 41.169773 + + 330.178528 + 1.447083 + TP0364 + 3d + 9 + + + 40.141083 + + 330.178528 + 0.896336 + TP0365 + 3d + 9 + + + 41.489315 + + 331.304474 + 1.176047 + TP0366 + 3d + 8 + + + 41.591541 + + 331.304474 + 0.078315 + TP0367 + 3d + 9 + + + 41.805412 + + 331.304474 + 0.136545 + TP0368 + 3d + 9 + + + 41.838428 + + 331.304474 + 0.025752 + TP0369 + 3d + 8 + + + 41.977230 + + 331.304474 + 1.645710 + TP0370 + 3d + 8 + + + 39.424427 + + 331.304474 + 1.585729 + TP0371 + 3d + 9 + + + 39.248688 + + 331.304474 + 1.673960 + TP0372 + 3d + 9 + + + 40.105923 + + 331.304474 + 1.675777 + TP0373 + 3d + 9 + + + 40.622498 + + 332.742340 + 1.290782 + TP0374 + 3d + 9 + + + 39.549179 + + 334.134705 + 1.214838 + TP0375 + 3d + 9 + + + 39.688271 + + 334.134705 + 1.341584 + TP0376 + 3d + 9 + + + 36.874863 + + 334.134705 + 1.492571 + TP0377 + 3d + 9 + + + 37.305058 + + 329.513885 + 1.965910 + TP0378 + 3d + 9 + + + 36.478157 + + 329.513885 + 1.425542 + TP0379 + 3d + 9 + + + 37.679001 + + 329.513885 + 1.851270 + TP0380 + 3d + 9 + + + 37.855843 + + 329.513885 + 1.464016 + TP0381 + 3d + 9 + + + 38.440704 + + 330.639191 + 1.963235 + TP0382 + 3d + 9 + + + 37.094051 + + 322.645264 + 1.353058 + TP0383 + 3d + 9 + + + 38.460693 + + 321.540863 + 1.666589 + TP0384 + 3d + 9 + + + 37.066402 + + 321.540863 + 1.353564 + TP0385 + 3d + 9 + + + 37.422005 + + 321.540863 + 1.745178 + TP0386 + 3d + 9 + + + 36.895084 + + 320.504150 + 1.480854 + TP0387 + 3d + 9 + + + 36.325195 + + 319.068939 + 1.389258 + TP0388 + 3d + 9 + + + 36.249111 + + 320.075500 + 1.720982 + TP0389 + 3d + 9 + + + 34.936836 + + 320.075500 + 1.293412 + TP0390 + 3d + 9 + + + 34.254780 + + 322.200470 + 1.592284 + TP0391 + 3d + 9 + + + 34.248177 + + 320.091583 + 1.661003 + TP0392 + 3d + 9 + + + 34.113022 + + 321.973114 + 1.394113 + TP0393 + 3d + 9 + + + 34.821335 + + 321.973114 + 1.494689 + TP0394 + 3d + 9 + + + 34.473961 + + 321.973114 + 1.207032 + TP0395 + 3d + 9 + + + 34.814793 + + 321.973114 + 1.502668 + TP0396 + 3d + 9 + + + 36.531628 + + 321.973114 + 1.572504 + TP0397 + 3d + 8 + + + 35.942066 + + 321.973114 + 1.444465 + TP0398 + 3d + 8 + + + 36.970840 + + 321.973114 + 1.726603 + TP0399 + 3d + 8 + + + 36.620956 + + 321.973114 + 1.378629 + TP0400 + 3d + 8 + + + 36.710541 + + 321.973114 + 1.201835 + TP0401 + 3d + 8 + + + 38.266098 + + 321.973114 + 1.638500 + TP0402 + 3d + 9 + + + 39.388645 + + 321.973114 + 0.850153 + TP0403 + 3d + 8 + + + 41.071198 + + 321.973114 + 1.181594 + TP0404 + 3d + 8 + + + 44.571972 + + 321.973114 + 1.591521 + TP0405 + 3d + 8 + + + 45.149620 + + 103.814293 + 1.903993 + TP0406 + 3d + 8 + + + 46.482353 + + 103.548470 + 1.411737 + TP0407 + 3d + 8 + + + 47.727573 + + 103.548470 + 1.386361 + TP0408 + 3d + 8 + + + 50.446995 + + 110.262627 + 1.331973 + TP0409 + 3d + 8 + + + 50.487560 + + 110.262627 + 1.747993 + TP0410 + 3d + 8 + + + 51.564754 + + 110.262627 + 1.355807 + TP0411 + 3d + 8 + + + 45.682472 + + 110.262627 + 1.210973 + TP0412 + 3d + 8 + + + 41.204666 + + 110.262627 + 1.413509 + TP0413 + 3d + 8 + + + 41.814583 + + 110.262627 + 1.276915 + TP0414 + 3d + 8 + + + 42.905079 + + 110.262627 + 1.598764 + TP0415 + 3d + 8 + + + 42.048431 + + 110.262627 + 1.731465 + TP0416 + 3d + 8 + + + 40.197262 + + 110.262627 + 1.324286 + TP0417 + 3d + 7 + + + 37.296478 + + 110.262627 + 1.353854 + TP0418 + 3d + 7 + + + 34.941608 + + 110.262627 + 1.212386 + TP0419 + 3d + 7 + + + 31.461550 + + 110.262627 + 1.507033 + TP0420 + 3d + 7 + + + 29.878866 + + 110.262627 + 1.728915 + TP0421 + 3d + 8 + + + 28.686647 + + 110.262627 + 0.987423 + TP0422 + 3d + 7 + + + 28.145824 + + 110.262627 + 1.265162 + TP0423 + 3d + 8 + + + 30.670811 + + 110.262627 + 1.836553 + TP0424 + 3d + 8 + + + 32.307770 + + 110.262627 + 1.310898 + TP0425 + 3d + 7 + + + 32.628761 + + 110.262627 + 1.622816 + TP0426 + 3d + 8 + + + 33.369404 + + 110.262627 + 1.710149 + TP0427 + 3d + 8 + + + 34.297184 + + 110.262627 + 1.097964 + TP0428 + 3d + 8 + + + 35.706226 + + 110.262627 + 1.243773 + TP0429 + 3d + 8 + + + 37.490696 + + 110.262627 + 1.201586 + TP0430 + 3d + 8 + + + 37.541157 + + 110.262627 + 1.565976 + TP0431 + 3d + 7 + + + 38.153469 + + 110.262627 + 1.327252 + TP0432 + 3d + 7 + + + 38.474022 + + 110.262627 + 1.206724 + TP0433 + 3d + 8 + + + 38.568634 + + 110.262627 + 1.602677 + TP0434 + 3d + 8 + + + 38.217030 + + 110.262627 + 1.495651 + TP0435 + 3d + 8 + + + 38.042328 + + 110.262627 + 1.188114 + TP0436 + 3d + 7 + + + 37.052139 + + 110.262627 + 1.367975 + TP0437 + 3d + 7 + + + 36.222900 + + 110.262627 + 1.819672 + TP0438 + 3d + 8 + + + 35.862713 + + 110.262627 + 1.016674 + TP0439 + 3d + 10 + + + 37.347980 + + 110.262627 + 1.323934 + TP0440 + 3d + 8 + + + 39.428635 + + 110.262627 + 1.532402 + TP0441 + 3d + 8 + + + 38.590481 + + 110.262627 + 1.115400 + TP0442 + 3d + 8 + + + 38.579144 + + 110.262627 + 1.374582 + TP0443 + 3d + 8 + + + 41.594685 + + 110.262627 + 1.245201 + TP0444 + 3d + 8 + + + 43.934750 + + 110.262627 + 1.782246 + TP0445 + 3d + 8 + + + 46.569092 + + 110.262627 + 1.470096 + TP0446 + 3d + 7 + + + 47.493629 + + 110.262627 + 1.368854 + TP0447 + 3d + 7 + + + 48.136349 + + 110.262627 + 1.429163 + TP0448 + 3d + 8 + + + 48.331181 + + 110.262627 + 1.393897 + TP0449 + 3d + 7 + + + 47.542187 + + 110.262627 + 1.263732 + TP0450 + 3d + 8 + + + 44.780071 + + 110.262627 + 1.499232 + TP0451 + 3d + 8 + + + 43.078159 + + 110.262627 + 1.535867 + TP0452 + 3d + 7 + + + 39.632629 + + 110.262627 + 1.304739 + TP0453 + 3d + 7 + + + 36.935654 + + 110.262627 + 1.635283 + TP0454 + 3d + 7 + + + 34.277405 + + 110.262627 + 1.336167 + TP0455 + 3d + 7 + + + 31.132778 + + 110.262627 + 1.260236 + TP0456 + 3d + 8 + + + 31.994057 + + 110.262627 + 1.469296 + TP0457 + 3d + 8 + + + 31.122032 + + 350.169159 + 2.057511 + TP0458 + 3d + 7 + + + 31.005985 + + 351.339142 + 1.842231 + TP0459 + 3d + 7 + + + 31.925455 + + 348.956848 + 1.231063 + TP0460 + 3d + 7 + + + 32.375824 + + 348.956848 + 1.022590 + TP0461 + 3d + 7 + + + 32.349483 + + 348.956848 + 1.600391 + TP0462 + 3d + 7 + + + 31.482601 + + 348.956848 + 1.725673 + TP0463 + 3d + 7 + + + 34.507126 + + 348.956848 + 0.978169 + TP0464 + 3d + 8 + + + 36.687382 + + 348.956848 + 1.592462 + TP0465 + 3d + 8 + + + 35.163441 + + 348.956848 + 1.546907 + TP0466 + 3d + 8 + + + 36.491611 + + 348.956848 + 1.383988 + TP0467 + 3d + 8 + + + 36.348030 + + 348.956848 + 1.699179 + TP0468 + 3d + 8 + + + 35.798428 + + 348.956848 + 0.890414 + TP0469 + 3d + 8 + + + 35.214291 + + 348.930817 + 1.420595 + TP0470 + 3d + 8 + + + 35.049137 + + 348.930817 + 1.415599 + TP0471 + 3d + 8 + + + 34.685078 + + 348.930817 + 1.477946 + TP0472 + 3d + 8 + + + 33.834579 + + 348.930817 + 1.562345 + TP0473 + 3d + 8 + + + 33.943275 + + 348.930817 + 1.272014 + TP0474 + 3d + 8 + + + 33.895531 + + 348.930817 + 1.120622 + TP0475 + 3d + 8 + + + 32.792637 + + 348.930817 + 0.046271 + TP0476 + 3d + 8 + + + 32.800762 + + 348.930817 + 0.233082 + TP0477 + 3d + 8 + + + 32.808544 + + 348.930817 + 1.086615 + TP0478 + 3d + 7 + + + 35.294174 + + 348.930817 + 0.872653 + TP0479 + 3d + 7 + + + 36.032829 + + 348.930817 + 0.080512 + TP0480 + 3d + 8 + + + 36.242550 + + 348.930817 + 0.208565 + TP0481 + 3d + 8 + + + 36.257809 + + 348.930817 + 0.159674 + TP0482 + 3d + 8 + + + 36.275784 + + 348.930817 + 0.261805 + TP0483 + 3d + 8 + + + 36.169346 + + 348.930817 + 0.517310 + TP0484 + 3d + 7 + + + 36.053902 + + 348.930817 + 0.005382 + TP0485 + 3d + 8 + + + 36.035206 + + 348.930817 + 0.620699 + TP0486 + 3d + 8 + + + 36.035797 + + 348.930817 + 1.168755 + TP0487 + 3d + 8 + + + 36.142834 + + 348.930817 + 0.064666 + TP0488 + 3d + 8 + + + 36.185215 + + 348.930817 + 0.568796 + TP0489 + 3d + 7 + + + 35.453949 + + 348.930817 + 0.640305 + TP0490 + 3d + 7 + + + 34.875973 + + 348.930817 + 0.469342 + TP0491 + 3d + 6 + + + 34.764629 + + 348.930817 + 0.048115 + TP0492 + 3d + 8 + + + 34.832104 + + 348.930817 + 0.024468 + TP0493 + 3d + 8 + + + 34.959030 + + 348.930817 + 0.027468 + TP0494 + 3d + 8 + + + 35.036503 + + 348.930817 + 0.000968 + TP0495 + 3d + 7 + + + 35.044819 + + 348.930817 + 0.003053 + TP0496 + 3d + 8 + + + 35.079132 + + 348.930817 + 0.001238 + TP0497 + 3d + 8 + + + 35.114792 + + 348.930817 + 0.001593 + TP0498 + 3d + 8 + + + 35.142036 + + 348.930817 + 0.001471 + TP0499 + 3d + 7 + + + 35.151981 + + 348.930817 + 0.002685 + TP0500 + 3d + 8 + + + 35.177467 + + 348.930817 + 0.033977 + TP0501 + 3d + 7 + + + 35.209000 + + 348.930817 + 0.005408 + TP0502 + 3d + 7 + + + 35.344204 + + 348.930817 + 0.310761 + TP0503 + 3d + 6 + + + 35.398499 + + 348.930817 + 0.001647 + TP0504 + 3d + 9 + + + 35.406319 + + 348.930817 + 0.000534 + TP0505 + 3d + 8 + + + 35.386929 + + 348.930817 + 0.006597 + TP0506 + 3d + 8 + + + 35.373619 + + 348.930817 + 0.001887 + TP0507 + 3d + 8 + + + 35.371105 + + 348.930817 + 0.001814 + TP0508 + 3d + 8 + + + 35.344795 + + 348.930817 + 0.003021 + TP0509 + 3d + 9 + + + 35.337196 + + 348.930817 + 0.091405 + TP0510 + 3d + 8 + + + 35.323624 + + 348.930817 + 0.141361 + TP0511 + 3d + 7 + + + 35.344074 + + 348.930817 + 0.225306 + TP0512 + 3d + 8 + + + 35.372276 + + 348.930817 + 0.218948 + TP0513 + 3d + 8 + + + 35.406303 + + 348.930817 + 0.236625 + TP0514 + 3d + 8 + + + 35.413681 + + 348.930817 + 0.107134 + TP0515 + 3d + 7 + + + 35.430824 + + 348.930817 + 0.985265 + TP0516 + 3d + 8 + + + 36.105286 + + 266.844727 + 4.132751 + TP0517 + 3d + 8 + + + 37.403809 + + 259.185059 + 4.471956 + TP0518 + 3d + 8 + + + 39.307724 + + 252.127563 + 4.437634 + TP0519 + 3d + 7 + + + 39.680443 + + 251.846802 + 3.836235 + TP0520 + 3d + 7 + + + 38.027061 + + 209.976074 + 4.058580 + TP0521 + 3d + 8 + + + 39.716564 + + 204.307907 + 4.588913 + TP0522 + 3d + 8 + + + 42.343742 + + 244.933319 + 5.554557 + TP0523 + 3d + 9 + + + 47.920643 + + 259.753479 + 5.416070 + TP0524 + 3d + 8 + + + 53.100410 + + 252.850159 + 4.845081 + TP0525 + 3d + 8 + + + 59.027779 + + 252.758423 + 4.991862 + TP0526 + 3d + 8 + + + 64.524376 + + 242.889435 + 3.134435 + TP0527 + 3d + 9 + + + 70.053909 + + 256.679993 + 2.597404 + TP0528 + 3d + 9 + + + 73.381393 + + 252.173355 + 0.951098 + TP0529 + 3d + 9 + + + 74.317482 + + 252.173355 + 0.091881 + TP0530 + 3d + 8 + + + 74.994987 + + 252.173355 + 0.172823 + TP0531 + 3d + 9 + + + 75.340546 + + 252.173355 + 0.128724 + TP0532 + 3d + 9 + + + 75.514122 + + 252.173355 + 0.048526 + TP0533 + 3d + 8 + + + 75.590843 + + 252.173355 + 0.058741 + TP0534 + 3d + 8 + + + 75.640251 + + 252.173355 + 0.152493 + TP0535 + 3d + 9 + + + 75.699203 + + 252.173355 + 0.238902 + TP0536 + 3d + 9 + + + 75.752899 + + 252.173355 + 0.108655 + TP0537 + 3d + 8 + + + 75.710106 + + 252.173355 + 0.462379 + TP0538 + 3d + 9 + + + 76.153221 + + 254.655457 + 1.900736 + TP0539 + 3d + 8 + + + 76.254158 + + 254.655457 + 1.152747 + TP0540 + 3d + 9 + + + 76.716095 + + 254.655457 + 0.652538 + TP0541 + 3d + 9 + + + 75.835052 + + 254.655457 + 0.137812 + TP0542 + 3d + 8 + + + 76.115974 + + 254.655457 + 0.109070 + TP0543 + 3d + 8 + + + 76.290184 + + 254.655457 + 0.408361 + TP0544 + 3d + 9 + + + 75.969826 + + 254.655457 + 1.837645 + TP0545 + 3d + 9 + + + 77.609825 + + 235.926590 + 2.912988 + TP0546 + 3d + 9 + + + 71.655617 + + 270.661957 + 4.142350 + TP0547 + 3d + 8 + + + 71.099152 + + 250.093170 + 6.080375 + TP0548 + 3d + 8 + + + 70.996956 + + 252.321228 + 6.561866 + TP0549 + 3d + 9 + + + 69.959251 + + 257.005981 + 6.805053 + TP0550 + 3d + 8 + + + 68.321487 + + 257.831085 + 6.886487 + TP0551 + 3d + 8 + + + 66.696541 + + 254.512512 + 7.342045 + TP0552 + 3d + 7 + + + 66.792625 + + 254.280838 + 7.414184 + TP0553 + 3d + 8 + + + 64.470802 + + 252.652267 + 6.798974 + TP0554 + 3d + 8 + + + 75.614906 + + 250.405945 + 5.200852 + TP0555 + 3d + 8 + + + 87.300972 + + 243.778580 + 4.224462 + TP0556 + 3d + 8 + + + 89.645264 + + 220.766418 + 4.433956 + TP0557 + 3d + 8 + + + 89.481583 + + 160.027557 + 2.849619 + TP0558 + 3d + 8 + + + 92.977280 + + 157.697861 + 3.073200 + TP0559 + 3d + 8 + + + 92.839066 + + 156.207596 + 2.867080 + TP0560 + 3d + 8 + + + 93.679314 + + 153.436081 + 1.521562 + TP0561 + 3d + 8 + + + 93.570442 + + 152.649536 + 1.055535 + TP0562 + 3d + 8 + + + 94.494698 + + 152.642792 + 1.342988 + TP0563 + 3d + 8 + + + 94.901642 + + 152.777771 + 1.967363 + TP0564 + 3d + 7 + + + 91.328278 + + 165.346649 + 2.701397 + TP0565 + 3d + 8 + + + 88.451477 + + 161.263718 + 0.906314 + TP0566 + 3d + 9 + + + 91.141930 + + 161.263718 + 0.284965 + TP0567 + 3d + 8 + + + 92.172508 + + 161.263718 + 0.147965 + TP0568 + 3d + 8 + + + 92.461258 + + 161.263718 + 0.056669 + TP0569 + 3d + 8 + + + 92.556870 + + 161.263718 + 0.022265 + TP0570 + 3d + 8 + + + 92.568306 + + 161.263718 + 0.183284 + TP0571 + 3d + 8 + + + 92.270767 + + 164.544937 + 5.004238 + TP0572 + 3d + 8 + + + 94.230118 + + 171.067032 + 5.614787 + TP0573 + 3d + 8 + + + 94.349472 + + 156.786514 + 5.158871 + TP0574 + 3d + 8 + + + 95.782722 + + 164.016251 + 5.224937 + TP0575 + 3d + 8 + + + 96.110352 + + 153.969543 + 1.648952 + TP0576 + 3d + 8 + + + 98.264450 + + 171.187561 + 2.143247 + TP0577 + 3d + 8 + + + 101.903290 + + 199.763306 + 3.322761 + TP0578 + 3d + 8 + + + 100.908432 + + 249.578110 + 2.721004 + TP0579 + 3d + 8 + + + 98.441101 + + 224.093170 + 1.696266 + TP0580 + 3d + 8 + + + 99.395744 + + 224.093170 + 0.479865 + TP0581 + 3d + 8 + + + 101.543945 + + 224.093170 + 0.332091 + TP0582 + 3d + 8 + + + 103.097824 + + 224.093170 + 0.526310 + TP0583 + 3d + 8 + + + 104.490097 + + 224.093170 + 0.660789 + TP0584 + 3d + 8 + + + 104.127480 + + 224.093170 + 1.696152 + TP0585 + 3d + 8 + + + 96.356079 + + 235.937607 + 4.850880 + TP0586 + 3d + 8 + + + 97.139885 + + 224.755081 + 4.737071 + TP0587 + 3d + 8 + + + 104.117126 + + 173.331863 + 6.159349 + TP0588 + 3d + 8 + + + 106.810539 + + 164.963943 + 6.170879 + TP0589 + 3d + 8 + + + 106.014999 + + 155.442062 + 8.220444 + TP0590 + 3d + 8 + + + 97.538269 + + 163.367905 + 8.647255 + TP0591 + 3d + 7 + + + 82.294998 + + 163.726883 + 6.578135 + TP0592 + 3d + 7 + + + 78.952164 + + 149.311813 + 3.167568 + TP0593 + 3d + 8 + + + 77.490852 + + 163.787460 + 2.939131 + TP0594 + 3d + 8 + + + 76.258820 + + 187.778702 + 4.358074 + TP0595 + 3d + 8 + + + 73.744034 + + 232.966171 + 4.367199 + TP0596 + 3d + 9 + + + 74.384712 + + 252.393066 + 4.181055 + TP0597 + 3d + 8 + + + 74.801178 + + 252.462280 + 3.949225 + TP0598 + 3d + 8 + + + 75.366821 + + 269.982666 + 2.711499 + TP0599 + 3d + 8 + + + 72.100449 + + 293.740234 + 2.055697 + TP0600 + 3d + 8 + + + 66.799866 + + 296.089447 + 0.724753 + TP0601 + 3d + 8 + + + 64.158058 + + 296.089447 + 0.137567 + TP0602 + 3d + 8 + + + 64.078674 + + 296.089447 + 0.298599 + TP0603 + 3d + 8 + + + 63.929432 + + 284.483185 + 1.926650 + TP0604 + 3d + 8 + + + 65.153625 + + 285.790466 + 1.220710 + TP0605 + 3d + 8 + + + 64.653687 + + 285.790466 + 0.452739 + TP0606 + 3d + 8 + + + 64.874718 + + 285.790466 + 0.111421 + TP0607 + 3d + 8 + + + 64.960991 + + 285.790466 + 0.247384 + TP0608 + 3d + 8 + + + 65.153725 + + 285.790466 + 0.091423 + TP0609 + 3d + 8 + + + 65.226273 + + 285.790466 + 0.102427 + TP0610 + 3d + 8 + + + 65.064758 + + 285.790466 + 1.994403 + TP0611 + 3d + 8 + + + 63.407185 + + 277.764008 + 2.465961 + TP0612 + 3d + 8 + + + 55.832211 + + 277.764008 + 0.090825 + TP0613 + 3d + 8 + + + 53.711098 + + 277.764008 + 0.055088 + TP0614 + 3d + 8 + + + 52.842609 + + 277.764008 + 0.138732 + TP0615 + 3d + 8 + + + 52.360691 + + 277.764008 + 0.054629 + TP0616 + 3d + 9 + + + 52.087082 + + 277.764008 + 0.087364 + TP0617 + 3d + 9 + + + 51.983650 + + 277.764008 + 0.027993 + TP0618 + 3d + 8 + + + 51.904427 + + 277.764008 + 0.081911 + TP0619 + 3d + 8 + + + 51.771957 + + 277.764008 + 0.109910 + TP0620 + 3d + 9 + + + 51.689781 + + 277.764008 + 0.097580 + TP0621 + 3d + 9 + + + 51.793804 + + 277.764008 + 0.070407 + TP0622 + 3d + 9 + + + 51.982742 + + 276.801270 + 3.207483 + TP0623 + 3d + 8 + + + 51.772163 + + 275.905151 + 7.975478 + TP0624 + 3d + 8 + + + 50.279926 + + 271.913940 + 9.741137 + TP0625 + 3d + 8 + + + 48.527409 + + 277.201416 + 11.196484 + TP0626 + 3d + 6 + + + 45.675247 + + 273.109436 + 10.200502 + TP0627 + 3d + 8 + + + 43.748550 + + 275.711426 + 6.957187 + TP0628 + 3d + 5 + + + 41.485603 + + 275.435974 + 5.577154 + TP0629 + 3d + 8 + + + 42.652260 + + 273.934418 + 7.368284 + TP0630 + 3d + 8 + + + 42.952404 + + 277.044312 + 7.835956 + TP0631 + 3d + 8 + + + 41.938480 + + 284.357452 + 6.492126 + TP0632 + 3d + 8 + + + 42.699963 + + 279.845184 + 5.134217 + TP0633 + 3d + 7 + + + 42.642509 + + 279.834869 + 5.055449 + TP0634 + 3d + 8 + + + 39.983074 + + 283.039490 + 4.805838 + TP0635 + 3d + 8 + + + 39.922935 + + 281.840302 + 4.442781 + TP0636 + 3d + 6 + + + 42.504242 + + 254.771011 + 4.003201 + TP0637 + 3d + 8 + + + 54.257427 + + 217.023911 + 1.486765 + TP0638 + 3d + 8 + + + 60.191071 + + 217.023911 + 0.421906 + TP0639 + 3d + 9 + + + 60.932205 + + 217.023911 + 0.718218 + TP0640 + 3d + 8 + + + 57.798515 + + 217.023911 + 1.650865 + TP0641 + 3d + 8 + + + 56.948818 + + 217.023911 + 0.651361 + TP0642 + 3d + 7 + + + 54.779488 + + 217.023911 + 1.091384 + TP0643 + 3d + 8 + + + 53.241680 + + 218.496490 + 0.449520 + TP0644 + 3d + 7 + + + 53.076332 + + 218.496490 + 0.360533 + TP0645 + 3d + 8 + + + 52.866653 + + 218.496490 + 0.528669 + TP0646 + 3d + 8 + + + 52.972622 + + 218.496490 + 1.096580 + TP0647 + 3d + 8 + + + 53.538147 + + 218.496490 + 0.625899 + TP0648 + 3d + 8 + + + 54.323326 + + 218.496490 + 0.327272 + TP0649 + 3d + 7 + + + 54.677227 + + 218.496490 + 0.018773 + TP0650 + 3d + 8 + + + 54.826538 + + 218.496490 + 0.505743 + TP0651 + 3d + 8 + + + 55.053116 + + 218.496490 + 0.432382 + TP0652 + 3d + 7 + + + 55.106789 + + 218.496490 + 0.058583 + TP0653 + 3d + 7 + + + 55.116531 + + 218.496490 + 0.006754 + TP0654 + 3d + 7 + + + 55.115917 + + 218.496490 + 0.002260 + TP0655 + 3d + 7 + + + 55.117039 + + 218.496490 + 0.001856 + TP0656 + 3d + 7 + + + 55.136143 + + 218.496490 + 0.000805 + TP0657 + 3d + 7 + + + 55.148487 + + 218.496490 + 0.007480 + TP0658 + 3d + 7 + + + 55.162659 + + 218.496490 + 0.007337 + TP0659 + 3d + 7 + + + 55.205227 + + 218.496490 + 0.046721 + TP0660 + 3d + 8 + + + 55.188232 + + 218.496490 + 0.001944 + TP0661 + 3d + 8 + + + 55.159225 + + 218.496490 + 0.000416 + TP0662 + 3d + 7 + + + 55.142086 + + 218.496490 + 0.009314 + TP0663 + 3d + 6 + + + 55.137108 + + 218.496490 + 0.001668 + TP0664 + 3d + 8 + + + 55.102448 + + 218.496490 + 0.007567 + TP0665 + 3d + 7 + + + 55.135281 + + 218.496490 + 0.269319 + TP0666 + 3d + 8 + + + 55.178482 + + 218.496490 + 0.262931 + TP0667 + 3d + 7 + + + 55.160194 + + 218.496490 + 0.002955 + TP0668 + 3d + 8 + + + 55.152924 + + 218.496490 + 0.040493 + TP0669 + 3d + 8 + + + 55.263668 + + 218.496490 + 0.005129 + TP0670 + 3d + 7 + + + 55.369980 + + 218.496490 + 0.035897 + TP0671 + 3d + 7 + + + 55.426929 + + 218.496490 + 0.004630 + TP0672 + 3d + 7 + + + 55.402885 + + 218.496490 + 0.000865 + TP0673 + 3d + 7 + + + 55.452240 + + 218.496490 + 0.001837 + TP0674 + 3d + 6 + + + 55.465645 + + 218.496490 + 0.002016 + TP0675 + 3d + 7 + + + 55.428730 + + 218.496490 + 0.001942 + TP0676 + 3d + 7 + + + 55.371540 + + 218.496490 + 0.004365 + TP0677 + 3d + 8 + + + 55.368378 + + 218.496490 + 0.001333 + TP0678 + 3d + 7 + + + 55.364956 + + 218.496490 + 0.001297 + TP0679 + 3d + 7 + + + 55.386986 + + 218.496490 + 0.002019 + TP0680 + 3d + 7 + + + 55.424679 + + 218.496490 + 0.003237 + TP0681 + 3d + 7 + + + 55.468376 + + 218.496490 + 0.001680 + TP0682 + 3d + 7 + + + 55.533737 + + 218.496490 + 0.045060 + TP0683 + 3d + 8 + + + 55.539864 + + 218.496490 + 0.001506 + TP0684 + 3d + 7 + + + 55.562237 + + 218.496490 + 0.239861 + TP0685 + 3d + 7 + + + 55.626358 + + 218.496490 + 0.197063 + TP0686 + 3d + 7 + + + 55.744625 + + 218.496490 + 0.055380 + TP0687 + 3d + 8 + + + 55.884129 + + 218.496490 + 0.050798 + TP0688 + 3d + 8 + + + 55.963707 + + 218.496490 + 0.103979 + TP0689 + 3d + 6 + + + 56.060684 + + 218.496490 + 0.118978 + TP0690 + 3d + 6 + + + 56.129726 + + 218.496490 + 0.057695 + TP0691 + 3d + 6 + + + 56.174274 + + 218.496490 + 0.059240 + TP0692 + 3d + 6 + + + 56.225285 + + 218.496490 + 0.201704 + TP0693 + 3d + 8 + + + 56.230228 + + 218.496490 + 0.397796 + TP0694 + 3d + 7 + + + 56.249668 + + 218.496490 + 0.045781 + TP0695 + 3d + 7 + + + 56.405598 + + 218.496490 + 0.098648 + TP0696 + 3d + 7 + + + 56.498055 + + 218.496490 + 1.669990 + TP0697 + 3d + 7 + + + 56.564190 + + 218.496490 + 0.197046 + TP0698 + 3d + 7 + + + 56.543667 + + 218.496490 + 0.086945 + TP0699 + 3d + 8 + + + 56.581444 + + 218.496490 + 0.237207 + TP0700 + 3d + 8 + + + 56.630741 + + 218.496490 + 0.278322 + TP0701 + 3d + 8 + + + 56.684647 + + 218.496490 + 0.168554 + TP0702 + 3d + 8 + + + 56.785572 + + 218.496490 + 0.189623 + TP0703 + 3d + 7 + + + 56.875393 + + 218.496490 + 0.205831 + TP0704 + 3d + 7 + + + 56.934406 + + 218.496490 + 0.146626 + TP0705 + 3d + 7 + + + 56.986214 + + 218.496490 + 0.204477 + TP0706 + 3d + 7 + + + 57.043221 + + 218.496490 + 0.206466 + TP0707 + 3d + 7 + + + 57.112270 + + 218.496490 + 0.285062 + TP0708 + 3d + 8 + + + 57.175644 + + 218.496490 + 0.962515 + TP0709 + 3d + 8 + + + 56.505943 + + 86.427399 + 5.513577 + TP0710 + 3d + 8 + + + 56.468739 + + 96.587524 + 6.088407 + TP0711 + 3d + 8 + + + 58.681587 + + 99.175896 + 7.924136 + TP0712 + 3d + 7 + + + 59.009224 + + 97.125023 + 6.783049 + TP0713 + 3d + 8 + + + 58.753296 + + 98.056587 + 7.935850 + TP0714 + 3d + 6 + + + 61.154079 + + 95.442360 + 6.358071 + TP0715 + 3d + 7 + + + 58.161404 + + 100.822197 + 3.633513 + TP0716 + 3d + 8 + + + 56.524601 + + 100.060211 + 1.667719 + TP0717 + 3d + 7 + + + 51.497704 + + 100.060211 + 0.945564 + TP0718 + 3d + 7 + + + 49.657547 + + 97.457619 + 5.678153 + TP0719 + 3d + 6 + + + 47.381596 + + 97.820015 + 8.726044 + TP0720 + 3d + 7 + + + 45.864742 + + 96.406525 + 7.575697 + TP0721 + 3d + 6 + + + 44.151070 + + 99.171577 + 6.320168 + TP0722 + 3d + 7 + + + 43.129993 + + 96.029564 + 5.716181 + TP0723 + 3d + 6 + + + 42.655632 + + 87.960152 + 5.187541 + TP0724 + 3d + 7 + + + 47.126694 + + 94.451820 + 4.599480 + TP0725 + 3d + 7 + + + 45.114143 + + 89.539085 + 1.616679 + TP0726 + 3d + 7 + + + 43.373066 + + 89.539085 + 0.130123 + TP0727 + 3d + 8 + + + 42.926678 + + 89.539085 + 0.037990 + TP0728 + 3d + 7 + + + 42.838966 + + 89.539085 + 0.066600 + TP0729 + 3d + 6 + + + 42.808662 + + 89.539085 + 0.032890 + TP0730 + 3d + 6 + + + 42.931995 + + 89.725197 + 1.613370 + TP0731 + 3d + 7 + + + 42.628716 + + 76.366776 + 1.858435 + TP0732 + 3d + 7 + + + 43.564449 + + 76.366776 + 1.088116 + TP0733 + 3d + 6 + + + 43.326889 + + 76.366776 + 0.334308 + TP0734 + 3d + 6 + + + 43.177864 + + 76.366776 + 0.121621 + TP0735 + 3d + 6 + + + 43.118587 + + 76.366776 + 0.180330 + TP0736 + 3d + 6 + + + 42.983402 + + 76.366776 + 0.220678 + TP0737 + 3d + 6 + + + 42.937031 + + 76.366776 + 0.209586 + TP0738 + 3d + 6 + + + 42.942562 + + 76.366776 + 0.383057 + TP0739 + 3d + 6 + + + 42.979713 + + 76.366776 + 0.535772 + TP0740 + 3d + 7 + + + 43.011913 + + 76.366776 + 1.207049 + TP0741 + 3d + 7 + + + 43.784576 + + 49.888649 + 2.445696 + TP0742 + 3d + 7 + + + 43.211819 + + 52.977341 + 1.469321 + TP0743 + 3d + 7 + + + 42.772743 + + 52.977341 + 0.912314 + TP0744 + 3d + 6 + + + 42.345959 + + 54.474190 + 1.039766 + TP0745 + 3d + 7 + + + 41.845848 + + 75.363075 + 2.503152 + TP0746 + 3d + 7 + + + 41.465397 + + 18.042631 + 4.031073 + TP0747 + 3d + 7 + + + 39.201557 + + 350.312469 + 5.227849 + TP0748 + 3d + 7 + + + 34.905659 + + 338.893219 + 7.202540 + TP0749 + 3d + 7 + + + 29.181751 + + 342.903381 + 7.421690 + TP0750 + 3d + 7 + + + 26.025524 + + 338.657623 + 8.680714 + TP0751 + 3d + 7 + + + 24.058689 + + 341.594208 + 6.506355 + TP0752 + 3d + 7 + + + 24.503670 + + 334.948120 + 5.052996 + TP0753 + 3d + 7 + + + 21.750463 + + 339.453552 + 4.743180 + TP0754 + 3d + 7 + + + 21.274805 + + 21.269533 + 3.732276 + TP0755 + 3d + 7 + + + 24.930449 + + 57.253983 + 2.689401 + TP0756 + 3d + 7 + + + 23.571939 + + 57.935402 + 0.575326 + TP0757 + 3d + 7 + + + 21.758852 + + 57.935402 + 0.272819 + TP0758 + 3d + 7 + + + 20.467566 + + 57.935402 + 0.075399 + TP0759 + 3d + 7 + + + 20.074856 + + 57.935402 + 0.070384 + TP0760 + 3d + 7 + + + 19.931931 + + 57.935402 + 0.713890 + TP0761 + 3d + 7 + + + 20.842930 + + 63.193348 + 3.130648 + TP0762 + 3d + 7 + + + 21.649963 + + 68.431618 + 3.442213 + TP0763 + 3d + 7 + + + 25.562002 + + 32.924171 + 3.361054 + TP0764 + 3d + 7 + + + 26.968969 + + 344.355225 + 4.310341 + TP0765 + 3d + 7 + + + 27.406101 + + 341.821838 + 5.076190 + TP0766 + 3d + 7 + + + 27.535704 + + 339.747223 + 4.408119 + TP0767 + 3d + 7 + + + 28.154795 + + 341.113464 + 4.573566 + TP0768 + 3d + 7 + + + 24.246796 + + 339.732819 + 4.079585 + TP0769 + 3d + 7 + + + 23.303711 + + 339.514862 + 1.597809 + TP0770 + 3d + 7 + + + 24.946005 + + 339.514862 + 0.156533 + TP0771 + 3d + 7 + + + 24.590355 + + 339.514862 + 0.142250 + TP0772 + 3d + 7 + + + 24.535629 + + 339.514862 + 0.360152 + TP0773 + 3d + 7 + + + 24.427177 + + 339.514862 + 0.361612 + TP0774 + 3d + 7 + + + 24.243149 + + 339.514862 + 0.431612 + TP0775 + 3d + 7 + + + 24.084087 + + 339.514862 + 0.555251 + TP0776 + 3d + 7 + + + 24.227612 + + 346.195099 + 3.421367 + TP0777 + 3d + 7 + + + 24.550591 + + 332.352997 + 5.118948 + TP0778 + 3d + 7 + + + 24.790329 + + 339.528839 + 4.719919 + TP0779 + 3d + 7 + + + 24.882000 + + 337.760681 + 3.929679 + TP0780 + 3d + 7 + + + 24.885988 + + 326.768158 + 3.181422 + TP0781 + 3d + 7 + + + 22.894363 + + 36.511124 + 4.846198 + TP0782 + 3d + 7 + + + 21.994968 + + 62.685516 + 5.946139 + TP0783 + 3d + 7 + + + 20.402012 + + 61.447033 + 6.089304 + TP0784 + 3d + 7 + + + 18.011835 + + 70.627136 + 7.146325 + TP0785 + 3d + 7 + + + 16.479000 + + 72.116966 + 5.706940 + TP0786 + 3d + 7 + + + 15.727952 + + 72.860649 + 6.682722 + TP0787 + 3d + 6 + + + 13.501931 + + 74.065750 + 5.324975 + TP0788 + 3d + 6 + + + 12.321080 + + 81.119461 + 3.683437 + TP0789 + 3d + 6 + + + 11.192452 + + 75.343231 + 2.929381 + TP0790 + 3d + 6 + + + 9.391747 + + 69.857574 + 2.541023 + TP0791 + 3d + 6 + + + 7.392978 + + 95.088768 + 3.015811 + TP0792 + 3d + 7 + + + 11.171357 + + 48.301205 + 2.121240 + TP0793 + 3d + 7 + + + 16.152731 + + 345.122620 + 3.099985 + TP0794 + 3d + 7 + + + 15.429770 + + 349.252014 + 3.720629 + TP0795 + 3d + 6 + + + 18.443081 + + 49.279705 + 4.131574 + TP0796 + 3d + 7 + + + 17.724062 + + 70.644554 + 4.497624 + TP0797 + 3d + 7 + + + 16.861166 + + 64.961960 + 3.303369 + TP0798 + 3d + 7 + + + 16.343344 + + 57.725773 + 0.167609 + TP0799 + 3d + 7 + + + 17.903362 + + 57.725773 + 0.082964 + TP0800 + 3d + 7 + + + 17.818550 + + 57.725773 + 0.161319 + TP0801 + 3d + 7 + + + 17.827591 + + 57.725773 + 0.130852 + TP0802 + 3d + 7 + + + 17.853209 + + 57.725773 + 0.068195 + TP0803 + 3d + 7 + + + 17.841661 + + 57.725773 + 0.183443 + TP0804 + 3d + 7 + + + 17.868876 + + 57.725773 + 0.195327 + TP0805 + 3d + 6 + + + 17.897980 + + 57.725773 + 0.249844 + TP0806 + 3d + 6 + + + 17.911112 + + 57.725773 + 0.274289 + TP0807 + 3d + 6 + + + 17.954067 + + 57.725773 + 0.199295 + TP0808 + 3d + 6 + + + 18.035896 + + 57.725773 + 0.061631 + TP0809 + 3d + 6 + + + 18.049931 + + 57.725773 + 0.232345 + TP0810 + 3d + 6 + + + 18.316492 + + 68.676346 + 5.247779 + TP0811 + 3d + 6 + + + 20.202015 + + 77.141609 + 6.035380 + TP0812 + 3d + 6 + + + 21.015213 + + 79.136803 + 6.096270 + TP0813 + 3d + 7 + + + 22.754051 + + 73.930702 + 5.832743 + TP0814 + 3d + 7 + + + 25.730627 + + 76.704651 + 4.485237 + TP0815 + 3d + 7 + + + 29.132912 + + 0.000000 + 0.000000 + TP0816 + none + + + 29.132912 + + 0.000000 + 0.000000 + TP0817 + none + + + + diff --git a/reference/track/nmea b/reference/track/nmea new file mode 100644 index 000000000..be4c10525 --- /dev/null +++ b/reference/track/nmea @@ -0,0 +1,894 @@ +$GPZDA,032908,07,08,2004,00,00*41 +$GPGGA,032908.379,4231.8291,N,08807.3033,W,1,05,1.6,209.8,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.5*39 +$GPRMC,032908.379,A,4231.8291,N,08807.3033,W,0.17,138.92,070804,,*12 +$GPVTG,138.92,T,,M,0.17,N,0.3,K*64 +$GPZDA,032909,07,08,2004,00,00*40 +$GPGGA,032909.379,4231.8291,N,08807.3034,W,1,05,1.6,209.7,M,-34.2,M,0.0,0000*4F +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.5*39 +$GPRMC,032909.379,A,4231.8291,N,08807.3034,W,0.18,145.85,070804,,*17 +$GPVTG,145.85,T,,M,0.18,N,0.3,K*67 +$GPZDA,032910,07,08,2004,00,00*48 +$GPGGA,032910.379,4231.8292,N,08807.3036,W,1,05,1.6,209.7,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.5*39 +$GPGSV,3,1,09,28,64,316,40,08,60,189,42,11,50,085,46,07,37,246,45*7A +$GPGSV,3,2,09,27,36,171,36,31,18,058,41,26,17,291,00,29,17,282,*7D +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,032910.379,A,4231.8292,N,08807.3036,W,0.19,143.25,070804,,*13 +$GPVTG,143.25,T,,M,0.19,N,0.3,K*6A +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,032911,07,08,2004,00,00*49 +$GPGGA,032911.379,4231.8292,N,08807.3036,W,1,05,1.6,209.6,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032911.379,A,4231.8292,N,08807.3036,W,0.19,145.76,070804,,*12 +$GPVTG,145.76,T,,M,0.19,N,0.4,K*6D +$GPZDA,032912,07,08,2004,00,00*4A +$GPGGA,032912.379,4231.8292,N,08807.3037,W,1,05,1.6,209.6,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032912.379,A,4231.8292,N,08807.3037,W,0.17,141.44,070804,,*1B +$GPVTG,141.44,T,,M,0.17,N,0.3,K*61 +$GPZDA,032913,07,08,2004,00,00*4B +$GPGGA,032913.379,4231.8293,N,08807.3038,W,1,05,1.6,209.6,M,-34.2,M,0.0,0000*4B +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032913.379,A,4231.8293,N,08807.3038,W,0.18,140.40,070804,,*1E +$GPVTG,140.40,T,,M,0.18,N,0.3,K*6B +$GPZDA,032914,07,08,2004,00,00*4C +$GPGGA,032914.379,4231.8293,N,08807.3038,W,1,05,1.6,209.6,M,-34.2,M,0.0,0000*4C +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032914.379,A,4231.8293,N,08807.3038,W,0.18,142.51,070804,,*1B +$GPVTG,142.51,T,,M,0.18,N,0.3,K*69 +$GPZDA,032915,07,08,2004,00,00*4D +$GPGGA,032915.379,4231.8294,N,08807.3038,W,1,05,1.6,209.4,M,-34.2,M,0.0,0000*48 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPGSV,3,1,09,28,64,316,41,08,60,189,43,11,50,085,46,07,37,246,46*79 +$GPGSV,3,2,09,27,36,171,36,31,18,058,42,26,17,291,00,29,17,282,*7E +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,032915.379,A,4231.8294,N,08807.3038,W,0.20,144.06,070804,,*12 +$GPVTG,144.06,T,,M,0.20,N,0.4,K*61 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,032916,07,08,2004,00,00*4E +$GPGGA,032916.379,4231.8294,N,08807.3037,W,1,05,1.6,209.3,M,-34.2,M,0.0,0000*43 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032916.379,A,4231.8294,N,08807.3037,W,0.17,137.66,070804,,*18 +$GPVTG,137.66,T,,M,0.17,N,0.3,K*60 +$GPZDA,032917,07,08,2004,00,00*4F +$GPGGA,032917.379,4231.8295,N,08807.3037,W,1,05,1.6,209.1,M,-34.2,M,0.0,0000*41 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032917.379,A,4231.8295,N,08807.3037,W,0.19,144.23,070804,,*13 +$GPVTG,144.23,T,,M,0.19,N,0.4,K*6C +$GPZDA,032918,07,08,2004,00,00*40 +$GPGGA,032918.379,4231.8296,N,08807.3036,W,1,05,1.6,208.9,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032918.379,A,4231.8296,N,08807.3036,W,0.18,140.35,070804,,*1C +$GPVTG,140.35,T,,M,0.18,N,0.3,K*69 +$GPZDA,032919,07,08,2004,00,00*41 +$GPGGA,032919.379,4231.8298,N,08807.3035,W,1,05,1.6,208.8,M,-34.2,M,0.0,0000*48 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032919.379,A,4231.8298,N,08807.3035,W,0.19,143.06,070804,,*12 +$GPVTG,143.06,T,,M,0.19,N,0.4,K*6C +$GPZDA,032920,07,08,2004,00,00*4B +$GPGGA,032920.379,4231.8299,N,08807.3034,W,1,05,1.6,208.6,M,-34.2,M,0.0,0000*4C +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPGSV,3,1,09,28,64,317,40,08,60,188,43,11,50,085,46,07,37,246,45*7B +$GPGSV,3,2,09,27,35,171,37,31,18,058,42,26,17,291,00,29,17,282,*7C +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,032920.379,A,4231.8299,N,08807.3034,W,0.18,145.08,070804,,*11 +$GPVTG,145.08,T,,M,0.18,N,0.3,K*62 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,032921,07,08,2004,00,00*4A +$GPGGA,032921.379,4231.8301,N,08807.3033,W,1,05,1.6,208.5,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032921.379,A,4231.8301,N,08807.3033,W,0.18,141.56,070804,,*18 +$GPVTG,141.56,T,,M,0.18,N,0.3,K*6D +$GPZDA,032922,07,08,2004,00,00*49 +$GPGGA,032922.378,4231.8303,N,08807.3033,W,1,05,1.6,208.4,M,-34.2,M,0.0,0000*48 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032922.378,A,4231.8303,N,08807.3033,W,0.16,140.76,070804,,*15 +$GPVTG,140.76,T,,M,0.16,N,0.3,K*60 +$GPZDA,032923,07,08,2004,00,00*48 +$GPGGA,032923.378,4231.8305,N,08807.3034,W,1,05,1.6,208.4,M,-34.2,M,0.0,0000*48 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032923.378,A,4231.8305,N,08807.3034,W,0.19,143.92,070804,,*13 +$GPVTG,143.92,T,,M,0.19,N,0.3,K*66 +$GPZDA,032924,07,08,2004,00,00*4F +$GPGGA,032924.378,4231.8307,N,08807.3035,W,1,05,1.6,208.3,M,-34.2,M,0.0,0000*4B +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032924.378,A,4231.8307,N,08807.3035,W,0.18,140.85,070804,,*13 +$GPVTG,140.85,T,,M,0.18,N,0.3,K*62 +$GPZDA,032925,07,08,2004,00,00*4E +$GPGGA,032925.378,4231.8308,N,08807.3036,W,1,05,1.6,208.2,M,-34.2,M,0.0,0000*47 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPGSV,3,1,09,28,64,317,40,08,60,188,42,11,50,085,47,07,37,246,45*7B +$GPGSV,3,2,09,27,35,171,38,31,18,058,41,26,17,291,00,29,17,282,*70 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,032925.378,A,4231.8308,N,08807.3036,W,0.19,145.27,070804,,*12 +$GPVTG,145.27,T,,M,0.19,N,0.3,K*6E +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,032926,07,08,2004,00,00*4D +$GPGGA,032926.378,4231.8309,N,08807.3038,W,1,05,1.6,208.0,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032926.378,A,4231.8309,N,08807.3038,W,0.18,145.61,070804,,*1D +$GPVTG,145.61,T,,M,0.18,N,0.3,K*6D +$GPZDA,032927,07,08,2004,00,00*4C +$GPGGA,032927.378,4231.8310,N,08807.3040,W,1,05,1.6,207.9,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032927.378,A,4231.8310,N,08807.3040,W,0.18,145.14,070804,,*19 +$GPVTG,145.14,T,,M,0.18,N,0.3,K*6F +$GPZDA,032928,07,08,2004,00,00*43 +$GPGGA,032928.378,4231.8311,N,08807.3042,W,1,05,1.6,207.8,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032928.378,A,4231.8311,N,08807.3042,W,0.19,143.49,070804,,*1A +$GPVTG,143.49,T,,M,0.19,N,0.3,K*60 +$GPZDA,032929,07,08,2004,00,00*42 +$GPGGA,032929.378,4231.8311,N,08807.3043,W,1,05,1.6,207.7,M,-34.2,M,0.0,0000*4B +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032929.378,A,4231.8311,N,08807.3043,W,0.19,145.09,070804,,*18 +$GPVTG,145.09,T,,M,0.19,N,0.4,K*65 +$GPZDA,032930,07,08,2004,00,00*4A +$GPGGA,032930.378,4231.8311,N,08807.3044,W,1,05,1.6,207.8,M,-34.2,M,0.0,0000*4B +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPGSV,3,1,09,28,64,317,40,08,60,188,42,11,50,085,47,07,37,246,46*78 +$GPGSV,3,2,09,27,35,171,38,31,18,058,42,26,17,291,00,29,17,282,*73 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,032930.378,A,4231.8311,N,08807.3044,W,0.18,143.00,070804,,*19 +$GPVTG,143.00,T,,M,0.18,N,0.3,K*6C +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,032931,07,08,2004,00,00*4B +$GPGGA,032931.378,4231.8311,N,08807.3044,W,1,05,1.6,207.9,M,-34.2,M,0.0,0000*4B +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032931.378,A,4231.8311,N,08807.3044,W,0.18,144.10,070804,,*1E +$GPVTG,144.10,T,,M,0.18,N,0.3,K*6A +$GPZDA,032932,07,08,2004,00,00*48 +$GPGGA,032932.378,4231.8312,N,08807.3044,W,1,05,1.6,208.2,M,-34.2,M,0.0,0000*4F +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032932.378,A,4231.8312,N,08807.3044,W,0.20,142.36,070804,,*17 +$GPVTG,142.36,T,,M,0.20,N,0.4,K*64 +$GPZDA,032933,07,08,2004,00,00*49 +$GPGGA,032933.378,4231.8313,N,08807.3044,W,1,05,1.6,208.6,M,-34.2,M,0.0,0000*4B +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032933.378,A,4231.8313,N,08807.3044,W,0.18,139.90,070804,,*1C +$GPVTG,139.90,T,,M,0.18,N,0.3,K*68 +$GPZDA,032934,07,08,2004,00,00*4E +$GPGGA,032934.378,4231.8313,N,08807.3043,W,1,05,1.6,209.2,M,-34.2,M,0.0,0000*4E +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPRMC,032934.378,A,4231.8313,N,08807.3043,W,0.20,145.61,070804,,*12 +$GPVTG,145.61,T,,M,0.20,N,0.4,K*61 +$GPZDA,032935,07,08,2004,00,00*4F +$GPGGA,032935.378,4231.8314,N,08807.3043,W,1,05,1.6,209.8,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,,,,,,,,4.9,1.6,4.6*3A +$GPGSV,3,1,09,28,64,317,40,08,60,188,41,11,50,085,46,07,37,246,46*7A +$GPGSV,3,2,09,27,35,171,39,31,18,058,43,26,17,291,00,29,17,282,*73 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,032935.378,A,4231.8314,N,08807.3043,W,0.19,143.77,070804,,*1F +$GPVTG,143.77,T,,M,0.19,N,0.4,K*6A +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,032936,07,08,2004,00,00*4C +$GPGGA,032936.378,4231.8314,N,08807.3043,W,1,06,1.6,210.6,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032936.378,A,4231.8314,N,08807.3043,W,0.19,144.65,070804,,*18 +$GPVTG,144.65,T,,M,0.19,N,0.4,K*6E +$GPZDA,032937,07,08,2004,00,00*4D +$GPGGA,032937.378,4231.8313,N,08807.3043,W,1,06,1.6,211.4,M,-34.2,M,0.0,0000*41 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032937.378,A,4231.8313,N,08807.3043,W,0.19,144.57,070804,,*1F +$GPVTG,144.57,T,,M,0.19,N,0.4,K*6F +$GPZDA,032938,07,08,2004,00,00*42 +$GPGGA,032938.378,4231.8313,N,08807.3043,W,1,06,1.6,212.2,M,-34.2,M,0.0,0000*4B +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032938.378,A,4231.8313,N,08807.3043,W,0.19,144.35,070804,,*14 +$GPVTG,144.35,T,,M,0.19,N,0.3,K*6C +$GPZDA,032939,07,08,2004,00,00*43 +$GPGGA,032939.377,4231.8312,N,08807.3043,W,1,06,1.6,212.9,M,-34.2,M,0.0,0000*4F +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032939.377,A,4231.8312,N,08807.3043,W,0.21,141.22,070804,,*13 +$GPVTG,141.22,T,,M,0.21,N,0.4,K*63 +$GPZDA,032940,07,08,2004,00,00*4D +$GPGGA,032940.377,4231.8312,N,08807.3042,W,1,06,1.6,213.5,M,-34.2,M,0.0,0000*4D +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPGSV,3,1,09,28,64,317,41,08,60,188,41,31,56,251,42,11,50,085,46*7B +$GPGSV,3,2,09,07,38,246,46,27,35,171,39,26,17,291,00,29,17,282,*7C +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,032940.377,A,4231.8312,N,08807.3042,W,0.20,146.15,070804,,*1E +$GPVTG,146.15,T,,M,0.20,N,0.4,K*61 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,032941,07,08,2004,00,00*4C +$GPGGA,032941.377,4231.8312,N,08807.3041,W,1,06,1.6,213.9,M,-34.2,M,0.0,0000*43 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032941.377,A,4231.8312,N,08807.3041,W,0.19,142.42,070804,,*10 +$GPVTG,142.42,T,,M,0.19,N,0.3,K*6A +$GPZDA,032942,07,08,2004,00,00*4F +$GPGGA,032942.377,4231.8312,N,08807.3040,W,1,06,1.6,214.1,M,-34.2,M,0.0,0000*4E +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032942.377,A,4231.8312,N,08807.3040,W,0.18,141.13,070804,,*14 +$GPVTG,141.13,T,,M,0.18,N,0.3,K*6C +$GPZDA,032943,07,08,2004,00,00*4E +$GPGGA,032943.377,4231.8312,N,08807.3038,W,1,06,1.6,214.1,M,-34.2,M,0.0,0000*40 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032943.377,A,4231.8312,N,08807.3038,W,0.21,144.00,070804,,*17 +$GPVTG,144.00,T,,M,0.21,N,0.4,K*66 +$GPZDA,032944,07,08,2004,00,00*49 +$GPGGA,032944.377,4231.8312,N,08807.3037,W,1,06,1.6,213.8,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032944.377,A,4231.8312,N,08807.3037,W,0.18,142.18,070804,,*1A +$GPVTG,142.18,T,,M,0.18,N,0.3,K*64 +$GPZDA,032945,07,08,2004,00,00*48 +$GPGGA,032945.377,4231.8312,N,08807.3035,W,1,06,1.6,213.4,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPGSV,3,1,09,28,64,317,41,08,60,188,42,31,56,251,43,11,50,085,46*79 +$GPGSV,3,2,09,07,38,246,46,27,35,171,38,26,17,291,00,29,17,282,*7D +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,032945.377,A,4231.8312,N,08807.3035,W,0.21,145.29,070804,,*16 +$GPVTG,145.29,T,,M,0.21,N,0.4,K*6C +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,032946,07,08,2004,00,00*4B +$GPGGA,032946.377,4231.8312,N,08807.3034,W,1,06,1.6,213.0,M,-34.2,M,0.0,0000*4F +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032946.377,A,4231.8312,N,08807.3034,W,0.20,144.63,070804,,*1A +$GPVTG,144.63,T,,M,0.20,N,0.4,K*62 +$GPZDA,032947,07,08,2004,00,00*4A +$GPGGA,032947.377,4231.8312,N,08807.3033,W,1,06,1.6,212.6,M,-34.2,M,0.0,0000*4E +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032947.377,A,4231.8312,N,08807.3033,W,0.19,143.47,070804,,*17 +$GPVTG,143.47,T,,M,0.19,N,0.4,K*69 +$GPZDA,032948,07,08,2004,00,00*45 +$GPGGA,032948.377,4231.8312,N,08807.3032,W,1,06,1.6,212.4,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032948.377,A,4231.8312,N,08807.3032,W,0.19,142.35,070804,,*1D +$GPVTG,142.35,T,,M,0.19,N,0.4,K*6D +$GPZDA,032949,07,08,2004,00,00*44 +$GPGGA,032949.377,4231.8312,N,08807.3031,W,1,06,1.6,212.2,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032949.377,A,4231.8312,N,08807.3031,W,0.19,143.19,070804,,*10 +$GPVTG,143.19,T,,M,0.19,N,0.3,K*65 +$GPZDA,032950,07,08,2004,00,00*4C +$GPGGA,032950.377,4231.8311,N,08807.3031,W,1,06,1.6,212.1,M,-34.2,M,0.0,0000*4E +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPGSV,3,1,09,28,64,317,40,08,60,188,41,31,56,251,44,11,50,085,46*7C +$GPGSV,3,2,09,07,38,246,46,27,35,171,38,26,17,291,00,29,17,282,*7D +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,032950.377,A,4231.8311,N,08807.3031,W,0.20,143.64,070804,,*1B +$GPVTG,143.64,T,,M,0.20,N,0.4,K*62 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,032951,07,08,2004,00,00*4D +$GPGGA,032951.377,4231.8311,N,08807.3030,W,1,06,1.6,212.1,M,-34.2,M,0.0,0000*4E +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032951.377,A,4231.8311,N,08807.3030,W,0.19,140.80,070804,,*18 +$GPVTG,140.80,T,,M,0.19,N,0.4,K*61 +$GPZDA,032952,07,08,2004,00,00*4E +$GPGGA,032952.377,4231.8310,N,08807.3029,W,1,06,1.6,212.1,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032952.377,A,4231.8310,N,08807.3029,W,0.19,141.91,070804,,*13 +$GPVTG,141.91,T,,M,0.19,N,0.4,K*60 +$GPZDA,032953,07,08,2004,00,00*4F +$GPGGA,032953.377,4231.8309,N,08807.3029,W,1,06,1.6,212.2,M,-34.2,M,0.0,0000*4E +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032953.377,A,4231.8309,N,08807.3029,W,0.19,142.31,070804,,*13 +$GPVTG,142.31,T,,M,0.19,N,0.3,K*6E +$GPZDA,032954,07,08,2004,00,00*48 +$GPGGA,032954.377,4231.8309,N,08807.3030,W,1,06,1.6,212.4,M,-34.2,M,0.0,0000*47 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032954.377,A,4231.8309,N,08807.3030,W,0.20,140.73,070804,,*12 +$GPVTG,140.73,T,,M,0.20,N,0.4,K*67 +$GPZDA,032955,07,08,2004,00,00*49 +$GPGGA,032955.376,4231.8309,N,08807.3030,W,1,06,1.6,212.6,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPGSV,3,1,09,28,64,317,40,08,60,188,41,31,56,251,43,11,50,085,46*7B +$GPGSV,3,2,09,07,38,246,45,27,35,171,39,26,17,291,00,29,17,282,*7F +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,032955.376,A,4231.8309,N,08807.3030,W,0.19,141.19,070804,,*15 +$GPVTG,141.19,T,,M,0.19,N,0.4,K*60 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,032956,07,08,2004,00,00*4A +$GPGGA,032956.376,4231.8308,N,08807.3031,W,1,06,1.6,212.9,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032956.376,A,4231.8308,N,08807.3031,W,0.19,142.60,070804,,*1B +$GPVTG,142.60,T,,M,0.19,N,0.3,K*6A +$GPZDA,032957,07,08,2004,00,00*4B +$GPGGA,032957.376,4231.8308,N,08807.3033,W,1,06,1.6,213.4,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032957.376,A,4231.8308,N,08807.3033,W,0.19,142.81,070804,,*17 +$GPVTG,142.81,T,,M,0.19,N,0.4,K*62 +$GPZDA,032958,07,08,2004,00,00*44 +$GPGGA,032958.376,4231.8308,N,08807.3035,W,1,06,1.6,213.8,M,-34.2,M,0.0,0000*43 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032958.376,A,4231.8308,N,08807.3035,W,0.19,140.44,070804,,*15 +$GPVTG,140.44,T,,M,0.19,N,0.4,K*69 +$GPZDA,032959,07,08,2004,00,00*45 +$GPGGA,032959.376,4231.8309,N,08807.3037,W,1,06,1.6,214.2,M,-34.2,M,0.0,0000*4C +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,032959.376,A,4231.8309,N,08807.3037,W,0.21,142.37,070804,,*1A +$GPVTG,142.37,T,,M,0.21,N,0.4,K*64 +$GPZDA,033000,07,08,2004,00,00*41 +$GPGGA,033000.376,4231.8309,N,08807.3038,W,1,06,1.6,214.7,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPGSV,3,1,09,28,64,317,40,08,60,188,41,31,56,251,43,11,50,085,46*7B +$GPGSV,3,2,09,07,38,246,44,27,35,171,40,26,17,291,00,29,17,282,*70 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033000.376,A,4231.8309,N,08807.3038,W,0.20,139.39,070804,,*12 +$GPVTG,139.39,T,,M,0.20,N,0.4,K*67 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033001,07,08,2004,00,00*40 +$GPGGA,033001.376,4231.8310,N,08807.3040,W,1,06,1.6,215.0,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,033001.376,A,4231.8310,N,08807.3040,W,0.20,139.87,070804,,*11 +$GPVTG,139.87,T,,M,0.20,N,0.4,K*62 +$GPZDA,033002,07,08,2004,00,00*43 +$GPGGA,033002.376,4231.8310,N,08807.3040,W,1,06,1.6,215.2,M,-34.2,M,0.0,0000*43 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,033002.376,A,4231.8310,N,08807.3040,W,0.20,141.37,070804,,*16 +$GPVTG,141.37,T,,M,0.20,N,0.4,K*66 +$GPZDA,033003,07,08,2004,00,00*42 +$GPGGA,033003.376,4231.8310,N,08807.3040,W,1,06,1.6,215.2,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,033003.376,A,4231.8310,N,08807.3040,W,0.20,139.16,070804,,*1B +$GPVTG,139.16,T,,M,0.20,N,0.4,K*6A +$GPZDA,033004,07,08,2004,00,00*45 +$GPGGA,033004.376,4231.8310,N,08807.3040,W,1,06,1.6,215.2,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,033004.376,A,4231.8310,N,08807.3040,W,0.19,142.39,070804,,*17 +$GPVTG,142.39,T,,M,0.19,N,0.4,K*61 +$GPZDA,033005,07,08,2004,00,00*44 +$GPGGA,033005.376,4231.8309,N,08807.3038,W,1,06,1.6,215.2,M,-34.2,M,0.0,0000*43 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPGSV,3,1,09,28,64,317,41,08,60,188,40,31,56,251,44,11,50,085,45*7F +$GPGSV,3,2,09,07,38,246,44,27,35,171,39,26,17,291,00,29,17,282,*7E +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033005.376,A,4231.8309,N,08807.3038,W,0.21,140.45,070804,,*13 +$GPVTG,140.45,T,,M,0.21,N,0.4,K*63 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033006,07,08,2004,00,00*47 +$GPGGA,033006.376,4231.8309,N,08807.3036,W,1,06,1.6,215.1,M,-34.2,M,0.0,0000*4D +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,033006.376,A,4231.8309,N,08807.3036,W,0.19,141.09,070804,,*1C +$GPVTG,141.09,T,,M,0.19,N,0.3,K*66 +$GPZDA,033007,07,08,2004,00,00*46 +$GPGGA,033007.376,4231.8309,N,08807.3034,W,1,06,1.6,214.8,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,033007.376,A,4231.8309,N,08807.3034,W,0.21,140.73,070804,,*18 +$GPVTG,140.73,T,,M,0.21,N,0.4,K*66 +$GPZDA,033008,07,08,2004,00,00*49 +$GPGGA,033008.376,4231.8308,N,08807.3033,W,1,06,1.6,214.6,M,-34.2,M,0.0,0000*41 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,033008.376,A,4231.8308,N,08807.3033,W,0.20,137.97,070804,,*1A +$GPVTG,137.97,T,,M,0.20,N,0.4,K*6D +$GPZDA,033009,07,08,2004,00,00*48 +$GPGGA,033009.376,4231.8308,N,08807.3031,W,1,06,1.6,214.3,M,-34.2,M,0.0,0000*47 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPRMC,033009.376,A,4231.8308,N,08807.3031,W,0.19,144.87,070804,,*16 +$GPVTG,144.87,T,,M,0.19,N,0.4,K*62 +$GPZDA,033010,07,08,2004,00,00*40 +$GPGGA,033010.376,4231.8308,N,08807.3030,W,1,06,1.6,214.0,M,-34.2,M,0.0,0000*4D +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.3*33 +$GPGSV,3,1,09,28,64,317,41,08,60,188,41,31,56,251,43,11,50,085,45*79 +$GPGSV,3,2,09,07,38,246,45,27,35,171,40,26,17,291,00,29,17,282,*71 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033010.376,A,4231.8308,N,08807.3030,W,0.19,137.61,070804,,*13 +$GPVTG,137.61,T,,M,0.19,N,0.3,K*69 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033011,07,08,2004,00,00*41 +$GPGGA,033011.375,4231.8309,N,08807.3029,W,1,06,1.6,213.7,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033011.375,A,4231.8309,N,08807.3029,W,0.21,145.34,070804,,*16 +$GPVTG,145.34,T,,M,0.21,N,0.4,K*60 +$GPZDA,033012,07,08,2004,00,00*42 +$GPGGA,033012.375,4231.8309,N,08807.3028,W,1,06,1.6,213.4,M,-34.2,M,0.0,0000*47 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033012.375,A,4231.8309,N,08807.3028,W,0.18,136.35,070804,,*1B +$GPVTG,136.35,T,,M,0.18,N,0.3,K*68 +$GPZDA,033013,07,08,2004,00,00*43 +$GPGGA,033013.375,4231.8310,N,08807.3027,W,1,06,1.6,213.2,M,-34.2,M,0.0,0000*47 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033013.375,A,4231.8310,N,08807.3027,W,0.18,138.58,070804,,*18 +$GPVTG,138.58,T,,M,0.18,N,0.3,K*6D +$GPZDA,033014,07,08,2004,00,00*44 +$GPGGA,033014.375,4231.8311,N,08807.3025,W,1,06,1.6,213.0,M,-34.2,M,0.0,0000*41 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033014.375,A,4231.8311,N,08807.3025,W,0.19,140.11,070804,,*1F +$GPVTG,140.11,T,,M,0.19,N,0.4,K*69 +$GPZDA,033015,07,08,2004,00,00*45 +$GPGGA,033015.375,4231.8312,N,08807.3024,W,1,06,1.6,212.9,M,-34.2,M,0.0,0000*4A +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,41,08,60,188,41,31,56,251,43,11,50,085,45*79 +$GPGSV,3,2,09,07,38,246,45,27,35,171,40,26,17,291,00,29,17,282,*71 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033015.375,A,4231.8312,N,08807.3024,W,0.18,140.31,070804,,*1F +$GPVTG,140.31,T,,M,0.18,N,0.3,K*6D +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033016,07,08,2004,00,00*46 +$GPGGA,033016.375,4231.8314,N,08807.3024,W,1,06,1.6,212.9,M,-34.2,M,0.0,0000*4F +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033016.375,A,4231.8314,N,08807.3024,W,0.18,138.90,070804,,*1E +$GPVTG,138.90,T,,M,0.18,N,0.3,K*69 +$GPZDA,033017,07,08,2004,00,00*47 +$GPGGA,033017.375,4231.8314,N,08807.3024,W,1,06,1.6,213.0,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033017.375,A,4231.8314,N,08807.3024,W,0.19,142.90,070804,,*13 +$GPVTG,142.90,T,,M,0.19,N,0.4,K*62 +$GPZDA,033018,07,08,2004,00,00*48 +$GPGGA,033018.375,4231.8315,N,08807.3025,W,1,06,1.6,213.1,M,-34.2,M,0.0,0000*48 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033018.375,A,4231.8315,N,08807.3025,W,0.19,143.66,070804,,*14 +$GPVTG,143.66,T,,M,0.19,N,0.3,K*6D +$GPZDA,033019,07,08,2004,00,00*49 +$GPGGA,033019.375,4231.8315,N,08807.3026,W,1,06,1.6,213.3,M,-34.2,M,0.0,0000*48 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033019.375,A,4231.8315,N,08807.3026,W,0.19,140.87,070804,,*1A +$GPVTG,140.87,T,,M,0.19,N,0.3,K*61 +$GPZDA,033020,07,08,2004,00,00*43 +$GPGGA,033020.375,4231.8314,N,08807.3027,W,1,06,1.6,213.3,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,41,08,60,188,41,31,56,251,43,11,50,084,46*7B +$GPGSV,3,2,09,07,38,247,46,27,35,171,40,26,17,291,00,29,16,281,*71 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033020.375,A,4231.8314,N,08807.3027,W,0.20,146.14,070804,,*16 +$GPVTG,146.14,T,,M,0.20,N,0.4,K*60 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033021,07,08,2004,00,00*42 +$GPGGA,033021.375,4231.8314,N,08807.3029,W,1,06,1.6,213.3,M,-34.2,M,0.0,0000*4D +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033021.375,A,4231.8314,N,08807.3029,W,0.19,141.57,070804,,*13 +$GPVTG,141.57,T,,M,0.19,N,0.4,K*6A +$GPZDA,033022,07,08,2004,00,00*41 +$GPGGA,033022.375,4231.8313,N,08807.3030,W,1,06,1.6,213.2,M,-34.2,M,0.0,0000*40 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033022.375,A,4231.8313,N,08807.3030,W,0.19,143.95,070804,,*13 +$GPVTG,143.95,T,,M,0.19,N,0.4,K*66 +$GPZDA,033023,07,08,2004,00,00*40 +$GPGGA,033023.375,4231.8313,N,08807.3031,W,1,06,1.6,213.2,M,-34.2,M,0.0,0000*40 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033023.375,A,4231.8313,N,08807.3031,W,0.20,141.81,070804,,*1E +$GPVTG,141.81,T,,M,0.20,N,0.4,K*6B +$GPZDA,033024,07,08,2004,00,00*47 +$GPGGA,033024.375,4231.8313,N,08807.3032,W,1,06,1.6,213.1,M,-34.2,M,0.0,0000*47 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033024.375,A,4231.8313,N,08807.3032,W,0.18,142.07,070804,,*1C +$GPVTG,142.07,T,,M,0.18,N,0.3,K*6A +$GPZDA,033025,07,08,2004,00,00*46 +$GPGGA,033025.375,4231.8313,N,08807.3033,W,1,06,1.6,213.0,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,41,08,60,188,41,31,56,251,42,11,50,084,46*7A +$GPGSV,3,2,09,07,38,247,45,27,35,171,40,26,17,291,00,29,16,281,*72 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033025.375,A,4231.8313,N,08807.3033,W,0.18,140.21,070804,,*1A +$GPVTG,140.21,T,,M,0.18,N,0.3,K*6C +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033026,07,08,2004,00,00*45 +$GPGGA,033026.375,4231.8314,N,08807.3034,W,1,06,1.6,213.0,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033026.375,A,4231.8314,N,08807.3034,W,0.18,145.89,070804,,*1E +$GPVTG,145.89,T,,M,0.18,N,0.3,K*6B +$GPZDA,033027,07,08,2004,00,00*44 +$GPGGA,033027.375,4231.8315,N,08807.3036,W,1,06,1.6,213.0,M,-34.2,M,0.0,0000*47 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033027.375,A,4231.8315,N,08807.3036,W,0.19,139.51,070804,,*13 +$GPVTG,139.51,T,,M,0.19,N,0.4,K*63 +$GPZDA,033028,07,08,2004,00,00*4B +$GPGGA,033028.374,4231.8315,N,08807.3037,W,1,06,1.6,213.2,M,-34.2,M,0.0,0000*4A +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033028.374,A,4231.8315,N,08807.3037,W,0.20,144.06,070804,,*1E +$GPVTG,144.06,T,,M,0.20,N,0.4,K*61 +$GPZDA,033029,07,08,2004,00,00*4A +$GPGGA,033029.374,4231.8316,N,08807.3038,W,1,06,1.6,213.5,M,-34.2,M,0.0,0000*40 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033029.374,A,4231.8316,N,08807.3038,W,0.19,143.09,070804,,*11 +$GPVTG,143.09,T,,M,0.19,N,0.4,K*63 +$GPZDA,033030,07,08,2004,00,00*42 +$GPGGA,033030.374,4231.8316,N,08807.3039,W,1,06,1.6,213.9,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,41,08,60,188,40,31,56,251,43,11,50,084,46*7A +$GPGSV,3,2,09,07,38,247,45,27,35,171,41,26,17,291,00,29,16,281,*73 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033030.374,A,4231.8316,N,08807.3039,W,0.18,141.05,070804,,*17 +$GPVTG,141.05,T,,M,0.18,N,0.3,K*6B +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033031,07,08,2004,00,00*43 +$GPGGA,033031.374,4231.8317,N,08807.3040,W,1,06,1.6,214.3,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033031.374,A,4231.8317,N,08807.3040,W,0.19,143.82,070804,,*15 +$GPVTG,143.82,T,,M,0.19,N,0.4,K*60 +$GPZDA,033032,07,08,2004,00,00*40 +$GPGGA,033032.374,4231.8316,N,08807.3041,W,1,06,1.6,214.8,M,-34.2,M,0.0,0000*4E +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033032.374,A,4231.8316,N,08807.3041,W,0.20,143.53,070804,,*10 +$GPVTG,143.53,T,,M,0.20,N,0.4,K*66 +$GPZDA,033033,07,08,2004,00,00*41 +$GPGGA,033033.374,4231.8316,N,08807.3043,W,1,06,1.6,215.1,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033033.374,A,4231.8316,N,08807.3043,W,0.20,144.09,070804,,*1B +$GPVTG,144.09,T,,M,0.20,N,0.4,K*6E +$GPZDA,033034,07,08,2004,00,00*46 +$GPGGA,033034.374,4231.8315,N,08807.3044,W,1,06,1.6,215.6,M,-34.2,M,0.0,0000*41 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033034.374,A,4231.8315,N,08807.3044,W,0.20,142.95,070804,,*1B +$GPVTG,142.95,T,,M,0.20,N,0.4,K*6D +$GPZDA,033035,07,08,2004,00,00*47 +$GPGGA,033035.374,4231.8313,N,08807.3045,W,1,06,1.6,216.1,M,-34.2,M,0.0,0000*43 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,41,08,60,188,41,31,56,251,43,11,50,084,47*7A +$GPGSV,3,2,09,07,38,247,45,27,35,171,41,26,17,291,00,29,16,281,*73 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033035.374,A,4231.8313,N,08807.3045,W,0.20,142.28,070804,,*1B +$GPVTG,142.28,T,,M,0.20,N,0.4,K*6B +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033036,07,08,2004,00,00*44 +$GPGGA,033036.374,4231.8312,N,08807.3046,W,1,06,1.6,216.7,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033036.374,A,4231.8312,N,08807.3046,W,0.19,141.43,070804,,*1E +$GPVTG,141.43,T,,M,0.19,N,0.4,K*6F +$GPZDA,033037,07,08,2004,00,00*45 +$GPGGA,033037.374,4231.8310,N,08807.3047,W,1,06,1.6,217.3,M,-34.2,M,0.0,0000*43 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033037.374,A,4231.8310,N,08807.3047,W,0.19,142.06,070804,,*1E +$GPVTG,142.06,T,,M,0.19,N,0.4,K*6D +$GPZDA,033038,07,08,2004,00,00*4A +$GPGGA,033038.374,4231.8308,N,08807.3047,W,1,06,1.6,218.0,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033038.374,A,4231.8308,N,08807.3047,W,0.20,141.46,070804,,*15 +$GPVTG,141.46,T,,M,0.20,N,0.4,K*60 +$GPZDA,033039,07,08,2004,00,00*4B +$GPGGA,033039.374,4231.8307,N,08807.3047,W,1,06,1.6,218.8,M,-34.2,M,0.0,0000*4F +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033039.374,A,4231.8307,N,08807.3047,W,0.19,141.26,070804,,*17 +$GPVTG,141.26,T,,M,0.19,N,0.4,K*6C +$GPZDA,033040,07,08,2004,00,00*45 +$GPGGA,033040.374,4231.8306,N,08807.3047,W,1,06,1.6,219.7,M,-34.2,M,0.0,0000*4E +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,40,08,60,188,39,31,56,251,43,11,50,084,46*75 +$GPGSV,3,2,09,07,38,247,45,27,35,171,41,26,17,291,00,29,16,281,*73 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033040.374,A,4231.8306,N,08807.3047,W,0.20,145.54,070804,,*13 +$GPVTG,145.54,T,,M,0.20,N,0.4,K*67 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033041,07,08,2004,00,00*44 +$GPGGA,033041.374,4231.8306,N,08807.3047,W,1,06,1.6,220.6,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033041.374,A,4231.8306,N,08807.3047,W,0.18,134.63,070804,,*1B +$GPVTG,134.63,T,,M,0.18,N,0.3,K*69 +$GPZDA,033042,07,08,2004,00,00*47 +$GPGGA,033042.374,4231.8306,N,08807.3048,W,1,06,1.6,221.7,M,-34.2,M,0.0,0000*48 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033042.374,A,4231.8306,N,08807.3048,W,0.21,144.44,070804,,*1F +$GPVTG,144.44,T,,M,0.21,N,0.4,K*66 +$GPZDA,033043,07,08,2004,00,00*46 +$GPGGA,033043.374,4231.8306,N,08807.3048,W,1,06,1.6,222.7,M,-34.2,M,0.0,0000*4A +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033043.374,A,4231.8306,N,08807.3048,W,0.22,146.97,070804,,*11 +$GPVTG,146.97,T,,M,0.22,N,0.4,K*69 +$GPZDA,033044,07,08,2004,00,00*41 +$GPGGA,033044.373,4231.8306,N,08807.3049,W,1,06,1.6,223.8,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033044.373,A,4231.8306,N,08807.3049,W,0.21,142.24,070804,,*1F +$GPVTG,142.24,T,,M,0.21,N,0.4,K*66 +$GPZDA,033045,07,08,2004,00,00*40 +$GPGGA,033045.373,4231.8307,N,08807.3050,W,1,06,1.6,224.8,M,-34.2,M,0.0,0000*4A +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,40,08,59,188,39,31,56,251,42,11,50,084,46*7E +$GPGSV,3,2,09,07,38,247,45,27,35,171,42,26,17,290,00,29,16,281,*71 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033045.373,A,4231.8307,N,08807.3050,W,0.20,142.73,070804,,*14 +$GPVTG,142.73,T,,M,0.20,N,0.4,K*65 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033046,07,08,2004,00,00*43 +$GPGGA,033046.373,4231.8307,N,08807.3051,W,1,06,1.6,225.7,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033046.373,A,4231.8307,N,08807.3051,W,0.19,141.52,070804,,*1C +$GPVTG,141.52,T,,M,0.19,N,0.3,K*68 +$GPZDA,033047,07,08,2004,00,00*42 +$GPGGA,033047.373,4231.8307,N,08807.3052,W,1,06,1.6,226.4,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033047.373,A,4231.8307,N,08807.3052,W,0.20,141.43,070804,,*14 +$GPVTG,141.43,T,,M,0.20,N,0.4,K*65 +$GPZDA,033048,07,08,2004,00,00*4D +$GPGGA,033048.373,4231.8307,N,08807.3053,W,1,06,1.6,227.0,M,-34.2,M,0.0,0000*4F +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033048.373,A,4231.8307,N,08807.3053,W,0.19,137.69,070804,,*19 +$GPVTG,137.69,T,,M,0.19,N,0.4,K*66 +$GPZDA,033049,07,08,2004,00,00*4C +$GPGGA,033049.373,4231.8307,N,08807.3055,W,1,06,1.6,227.5,M,-34.2,M,0.0,0000*4D +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033049.373,A,4231.8307,N,08807.3055,W,0.19,144.58,070804,,*18 +$GPVTG,144.58,T,,M,0.19,N,0.3,K*67 +$GPZDA,033050,07,08,2004,00,00*44 +$GPGGA,033050.373,4231.8307,N,08807.3056,W,1,06,1.6,227.9,M,-34.2,M,0.0,0000*4A +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,41,08,59,188,40,31,56,251,43,11,50,084,46*70 +$GPGSV,3,2,09,07,38,247,44,27,35,171,42,26,17,290,00,29,16,281,*70 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033050.373,A,4231.8307,N,08807.3056,W,0.21,144.81,070804,,*1C +$GPVTG,144.81,T,,M,0.21,N,0.4,K*6F +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033051,07,08,2004,00,00*45 +$GPGGA,033051.373,4231.8306,N,08807.3057,W,1,06,1.6,228.2,M,-34.2,M,0.0,0000*4F +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033051.373,A,4231.8306,N,08807.3057,W,0.20,143.14,070804,,*17 +$GPVTG,143.14,T,,M,0.20,N,0.4,K*65 +$GPZDA,033052,07,08,2004,00,00*46 +$GPGGA,033052.373,4231.8306,N,08807.3058,W,1,06,1.6,228.3,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033052.373,A,4231.8306,N,08807.3058,W,0.20,143.27,070804,,*1B +$GPVTG,143.27,T,,M,0.20,N,0.4,K*65 +$GPZDA,033053,07,08,2004,00,00*47 +$GPGGA,033053.373,4231.8305,N,08807.3059,W,1,06,1.6,228.4,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033053.373,A,4231.8305,N,08807.3059,W,0.20,139.12,070804,,*13 +$GPVTG,139.12,T,,M,0.20,N,0.4,K*6E +$GPZDA,033054,07,08,2004,00,00*40 +$GPGGA,033054.373,4231.8305,N,08807.3060,W,1,06,1.6,228.3,M,-34.2,M,0.0,0000*4C +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033054.373,A,4231.8305,N,08807.3060,W,0.19,140.07,070804,,*1E +$GPVTG,140.07,T,,M,0.19,N,0.4,K*6E +$GPZDA,033055,07,08,2004,00,00*41 +$GPGGA,033055.373,4231.8305,N,08807.3060,W,1,06,1.6,228.1,M,-34.2,M,0.0,0000*4F +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,42,08,59,188,41,31,56,251,42,11,50,084,46*73 +$GPGSV,3,2,09,07,38,247,44,27,35,171,42,26,17,290,00,29,16,281,*70 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033055.373,A,4231.8305,N,08807.3060,W,0.20,144.72,070804,,*13 +$GPVTG,144.72,T,,M,0.20,N,0.4,K*62 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033056,07,08,2004,00,00*42 +$GPGGA,033056.373,4231.8306,N,08807.3060,W,1,06,1.6,227.8,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033056.373,A,4231.8306,N,08807.3060,W,0.21,140.80,070804,,*1B +$GPVTG,140.80,T,,M,0.21,N,0.4,K*6A +$GPZDA,033057,07,08,2004,00,00*43 +$GPGGA,033057.373,4231.8307,N,08807.3060,W,1,06,1.6,227.5,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033057.373,A,4231.8307,N,08807.3060,W,0.19,143.26,070804,,*1F +$GPVTG,143.26,T,,M,0.19,N,0.4,K*6E +$GPZDA,033058,07,08,2004,00,00*4C +$GPGGA,033058.373,4231.8308,N,08807.3059,W,1,06,1.6,227.2,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033058.373,A,4231.8308,N,08807.3059,W,0.20,138.81,070804,,*1E +$GPVTG,138.81,T,,M,0.20,N,0.4,K*65 +$GPZDA,033059,07,08,2004,00,00*4D +$GPGGA,033059.373,4231.8308,N,08807.3058,W,1,06,1.6,226.8,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033059.373,A,4231.8308,N,08807.3058,W,0.21,143.11,070804,,*1A +$GPVTG,143.11,T,,M,0.21,N,0.4,K*61 +$GPZDA,033100,07,08,2004,00,00*40 +$GPGGA,033100.372,4231.8309,N,08807.3057,W,1,06,1.6,226.4,M,-34.2,M,0.0,0000*4C +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,41,08,59,188,41,31,56,251,43,11,50,084,46*71 +$GPGSV,3,2,09,07,38,247,45,27,35,171,42,26,17,290,00,29,16,281,*71 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033100.372,A,4231.8309,N,08807.3057,W,0.20,140.10,070804,,*1B +$GPVTG,140.10,T,,M,0.20,N,0.4,K*62 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033101,07,08,2004,00,00*41 +$GPGGA,033101.372,4231.8309,N,08807.3056,W,1,06,1.6,226.1,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033101.372,A,4231.8309,N,08807.3056,W,0.20,143.55,070804,,*19 +$GPVTG,143.55,T,,M,0.20,N,0.4,K*60 +$GPZDA,033102,07,08,2004,00,00*42 +$GPGGA,033102.372,4231.8309,N,08807.3055,W,1,06,1.6,225.9,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033102.372,A,4231.8309,N,08807.3055,W,0.20,142.12,070804,,*1B +$GPVTG,142.12,T,,M,0.20,N,0.4,K*62 +$GPZDA,033103,07,08,2004,00,00*43 +$GPGGA,033103.372,4231.8309,N,08807.3054,W,1,06,1.6,225.7,M,-34.2,M,0.0,0000*4C +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033103.372,A,4231.8309,N,08807.3054,W,0.19,141.64,070804,,*13 +$GPVTG,141.64,T,,M,0.19,N,0.4,K*6A +$GPZDA,033104,07,08,2004,00,00*44 +$GPGGA,033104.372,4231.8308,N,08807.3054,W,1,06,1.6,225.6,M,-34.2,M,0.0,0000*4B +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033104.372,A,4231.8308,N,08807.3054,W,0.19,143.27,070804,,*10 +$GPVTG,143.27,T,,M,0.19,N,0.4,K*6F +$GPZDA,033105,07,08,2004,00,00*45 +$GPGGA,033105.372,4231.8307,N,08807.3055,W,1,06,1.6,225.6,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,42,08,59,188,40,31,56,251,43,11,50,084,47*72 +$GPGSV,3,2,09,07,38,247,44,27,35,171,41,26,17,290,00,29,16,281,*73 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033105.372,A,4231.8307,N,08807.3055,W,0.21,143.91,070804,,*19 +$GPVTG,143.91,T,,M,0.21,N,0.4,K*69 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033106,07,08,2004,00,00*46 +$GPGGA,033106.372,4231.8305,N,08807.3056,W,1,06,1.6,225.5,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033106.372,A,4231.8305,N,08807.3056,W,0.20,145.97,070804,,*1A +$GPVTG,145.97,T,,M,0.20,N,0.4,K*68 +$GPZDA,033107,07,08,2004,00,00*47 +$GPGGA,033107.372,4231.8303,N,08807.3057,W,1,06,1.6,225.4,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033107.372,A,4231.8303,N,08807.3057,W,0.18,144.00,070804,,*18 +$GPVTG,144.00,T,,M,0.18,N,0.3,K*6B +$GPZDA,033108,07,08,2004,00,00*48 +$GPGGA,033108.372,4231.8301,N,08807.3057,W,1,06,1.6,225.3,M,-34.2,M,0.0,0000*48 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033108.372,A,4231.8301,N,08807.3057,W,0.21,146.25,070804,,*1A +$GPVTG,146.25,T,,M,0.21,N,0.4,K*63 +$GPZDA,033109,07,08,2004,00,00*49 +$GPGGA,033109.372,4231.8300,N,08807.3058,W,1,06,1.6,225.3,M,-34.2,M,0.0,0000*47 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033109.372,A,4231.8300,N,08807.3058,W,0.19,138.98,070804,,*11 +$GPVTG,138.98,T,,M,0.19,N,0.4,K*67 +$GPZDA,033110,07,08,2004,00,00*41 +$GPGGA,033110.372,4231.8299,N,08807.3058,W,1,06,1.6,225.1,M,-34.2,M,0.0,0000*4C +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,317,42,08,59,188,41,31,56,251,42,11,50,084,46*73 +$GPGSV,3,2,09,07,38,247,44,27,35,171,42,26,17,290,00,29,16,281,*70 +$GPGSV,3,3,09,19,16,054,00*4E +$GPRMC,033110.372,A,4231.8299,N,08807.3058,W,0.19,143.10,070804,,*14 +$GPVTG,143.10,T,,M,0.19,N,0.4,K*6B +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033111,07,08,2004,00,00*40 +$GPGGA,033111.372,4231.8298,N,08807.3058,W,1,06,1.6,224.9,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033111.372,A,4231.8298,N,08807.3058,W,0.20,140.43,070804,,*1B +$GPVTG,140.43,T,,M,0.20,N,0.4,K*64 +$GPZDA,033112,07,08,2004,00,00*43 +$GPGGA,033112.372,4231.8297,N,08807.3058,W,1,06,1.6,224.7,M,-34.2,M,0.0,0000*47 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033112.372,A,4231.8297,N,08807.3058,W,0.19,141.44,070804,,*1B +$GPVTG,141.44,T,,M,0.19,N,0.4,K*68 +$GPZDA,033113,07,08,2004,00,00*42 +$GPGGA,033113.372,4231.8296,N,08807.3058,W,1,06,1.6,224.5,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033113.372,A,4231.8296,N,08807.3058,W,0.19,142.98,070804,,*19 +$GPVTG,142.98,T,,M,0.19,N,0.3,K*6D +$GPZDA,033114,07,08,2004,00,00*45 +$GPGGA,033114.372,4231.8296,N,08807.3058,W,1,06,1.6,224.3,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033114.372,A,4231.8296,N,08807.3058,W,0.19,145.03,070804,,*1B +$GPVTG,145.03,T,,M,0.19,N,0.4,K*6F +$GPZDA,033115,07,08,2004,00,00*44 +$GPGGA,033115.372,4231.8295,N,08807.3058,W,1,06,1.6,224.3,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,64,318,41,08,59,188,40,31,57,252,41,11,50,084,46*7F +$GPGSV,3,2,09,07,38,247,44,27,34,171,42,26,17,290,00,29,16,281,*71 +$GPGSV,3,3,09,19,15,054,00*4D +$GPRMC,033115.372,A,4231.8295,N,08807.3058,W,0.20,143.06,070804,,*10 +$GPVTG,143.06,T,,M,0.20,N,0.4,K*66 +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033116,07,08,2004,00,00*47 +$GPGGA,033116.372,4231.8294,N,08807.3059,W,1,06,1.6,224.3,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033116.372,A,4231.8294,N,08807.3059,W,0.20,145.49,070804,,*1E +$GPVTG,145.49,T,,M,0.20,N,0.4,K*6B +$GPZDA,033117,07,08,2004,00,00*46 +$GPGGA,033117.371,4231.8294,N,08807.3058,W,1,06,1.6,224.5,M,-34.2,M,0.0,0000*40 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033117.371,A,4231.8294,N,08807.3058,W,0.20,141.30,070804,,*17 +$GPVTG,141.30,T,,M,0.20,N,0.4,K*61 +$GPZDA,033118,07,08,2004,00,00*49 +$GPGGA,033118.371,4231.8293,N,08807.3058,W,1,06,1.6,224.7,M,-34.2,M,0.0,0000*4A +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033118.371,A,4231.8293,N,08807.3058,W,0.19,141.19,070804,,*1E +$GPVTG,141.19,T,,M,0.19,N,0.4,K*60 +$GPZDA,033119,07,08,2004,00,00*48 +$GPGGA,033119.371,4231.8293,N,08807.3056,W,1,06,1.6,225.0,M,-34.2,M,0.0,0000*43 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033119.371,A,4231.8293,N,08807.3056,W,0.20,143.01,070804,,*10 +$GPVTG,143.01,T,,M,0.20,N,0.4,K*61 +$GPZDA,033120,07,08,2004,00,00*42 +$GPGGA,033120.371,4231.8293,N,08807.3055,W,1,06,1.6,225.2,M,-34.2,M,0.0,0000*48 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,65,318,41,08,59,188,41,31,57,252,42,11,50,084,46*7C +$GPGSV,3,2,09,07,38,247,45,27,34,171,41,26,17,290,00,29,16,281,*73 +$GPGSV,3,3,09,19,15,054,00*4D +$GPRMC,033120.371,A,4231.8293,N,08807.3055,W,0.20,140.81,070804,,*12 +$GPVTG,140.81,T,,M,0.20,N,0.4,K*6A +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033121,07,08,2004,00,00*43 +$GPGGA,033121.371,4231.8294,N,08807.3053,W,1,06,1.6,225.3,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033121.371,A,4231.8294,N,08807.3053,W,0.20,140.79,070804,,*15 +$GPVTG,140.79,T,,M,0.20,N,0.4,K*6D +$GPZDA,033122,07,08,2004,00,00*40 +$GPGGA,033122.371,4231.8294,N,08807.3051,W,1,06,1.6,225.3,M,-34.2,M,0.0,0000*48 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033122.371,A,4231.8294,N,08807.3051,W,0.20,141.43,070804,,*1C +$GPVTG,141.43,T,,M,0.20,N,0.4,K*65 +$GPZDA,033123,07,08,2004,00,00*41 +$GPGGA,033123.371,4231.8295,N,08807.3050,W,1,06,1.6,225.3,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033123.371,A,4231.8295,N,08807.3050,W,0.20,142.30,070804,,*1A +$GPVTG,142.30,T,,M,0.20,N,0.4,K*62 +$GPZDA,033124,07,08,2004,00,00*46 +$GPGGA,033124.371,4231.8296,N,08807.3049,W,1,06,1.6,225.2,M,-34.2,M,0.0,0000*44 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033124.371,A,4231.8296,N,08807.3049,W,0.18,140.81,070804,,*15 +$GPVTG,140.81,T,,M,0.18,N,0.3,K*66 +$GPZDA,033125,07,08,2004,00,00*47 +$GPGGA,033125.371,4231.8296,N,08807.3050,W,1,06,1.6,225.2,M,-34.2,M,0.0,0000*4D +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,65,318,41,08,59,188,41,31,57,252,41,11,50,084,47*7E +$GPGSV,3,2,09,07,38,247,44,27,34,171,41,26,17,290,00,29,16,281,*72 +$GPGSV,3,3,09,19,15,054,00*4D +$GPRMC,033125.371,A,4231.8296,N,08807.3050,W,0.19,142.40,070804,,*12 +$GPVTG,142.40,T,,M,0.19,N,0.4,K*6F +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033126,07,08,2004,00,00*44 +$GPGGA,033126.371,4231.8297,N,08807.3051,W,1,06,1.6,225.2,M,-34.2,M,0.0,0000*4E +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033126.371,A,4231.8297,N,08807.3051,W,0.19,140.33,070804,,*17 +$GPVTG,140.33,T,,M,0.19,N,0.3,K*6E +$GPZDA,033127,07,08,2004,00,00*45 +$GPGGA,033127.371,4231.8298,N,08807.3052,W,1,06,1.6,225.1,M,-34.2,M,0.0,0000*40 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033127.371,A,4231.8298,N,08807.3052,W,0.17,137.77,070804,,*14 +$GPVTG,137.77,T,,M,0.17,N,0.3,K*60 +$GPZDA,033128,07,08,2004,00,00*4A +$GPGGA,033128.371,4231.8298,N,08807.3053,W,1,06,1.6,225.0,M,-34.2,M,0.0,0000*4F +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033128.371,A,4231.8298,N,08807.3053,W,0.21,142.29,070804,,*16 +$GPVTG,142.29,T,,M,0.21,N,0.4,K*6B +$GPZDA,033129,07,08,2004,00,00*4B +$GPGGA,033129.371,4231.8299,N,08807.3054,W,1,06,1.6,224.9,M,-34.2,M,0.0,0000*40 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033129.371,A,4231.8299,N,08807.3054,W,0.20,140.87,070804,,*16 +$GPVTG,140.87,T,,M,0.20,N,0.4,K*6C +$GPZDA,033130,07,08,2004,00,00*43 +$GPGGA,033130.371,4231.8300,N,08807.3055,W,1,06,1.6,224.7,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,65,318,41,08,59,188,41,31,57,252,42,11,50,084,47*7D +$GPGSV,3,2,09,07,38,247,45,27,34,171,41,26,17,290,00,29,16,281,*73 +$GPGSV,3,3,09,19,15,054,00*4D +$GPRMC,033130.371,A,4231.8300,N,08807.3055,W,0.19,141.70,070804,,*1D +$GPVTG,141.70,T,,M,0.19,N,0.4,K*6F +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033131,07,08,2004,00,00*42 +$GPGGA,033131.371,4231.8300,N,08807.3055,W,1,06,1.6,224.5,M,-34.2,M,0.0,0000*45 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033131.371,A,4231.8300,N,08807.3055,W,0.20,141.70,070804,,*16 +$GPVTG,141.70,T,,M,0.20,N,0.4,K*65 +$GPZDA,033132,07,08,2004,00,00*41 +$GPGGA,033132.371,4231.8301,N,08807.3056,W,1,06,1.6,224.3,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033132.371,A,4231.8301,N,08807.3056,W,0.19,140.33,070804,,*1B +$GPVTG,140.33,T,,M,0.19,N,0.4,K*69 +$GPZDA,033133,07,08,2004,00,00*40 +$GPGGA,033133.370,4231.8301,N,08807.3057,W,1,06,1.6,224.1,M,-34.2,M,0.0,0000*41 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033133.370,A,4231.8301,N,08807.3057,W,0.19,139.05,070804,,*11 +$GPVTG,139.05,T,,M,0.19,N,0.4,K*62 +$GPZDA,033134,07,08,2004,00,00*47 +$GPGGA,033134.370,4231.8302,N,08807.3057,W,1,06,1.6,223.9,M,-34.2,M,0.0,0000*4A +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033134.370,A,4231.8302,N,08807.3057,W,0.19,144.46,070804,,*18 +$GPVTG,144.46,T,,M,0.19,N,0.4,K*6F +$GPZDA,033135,07,08,2004,00,00*46 +$GPGGA,033135.370,4231.8303,N,08807.3058,W,1,06,1.6,223.7,M,-34.2,M,0.0,0000*4B +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,65,318,40,08,59,188,42,31,57,252,42,11,50,084,47*7F +$GPGSV,3,2,09,07,38,247,45,27,34,171,42,26,17,290,00,29,16,281,*70 +$GPGSV,3,3,09,19,15,054,00*4D +$GPRMC,033135.370,A,4231.8303,N,08807.3058,W,0.20,139.03,070804,,*16 +$GPVTG,139.03,T,,M,0.20,N,0.4,K*6E +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033136,07,08,2004,00,00*45 +$GPGGA,033136.370,4231.8304,N,08807.3058,W,1,06,1.6,223.4,M,-34.2,M,0.0,0000*4C +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033136.370,A,4231.8304,N,08807.3058,W,0.19,142.19,070804,,*1F +$GPVTG,142.19,T,,M,0.19,N,0.4,K*63 +$GPZDA,033137,07,08,2004,00,00*44 +$GPGGA,033137.370,4231.8305,N,08807.3058,W,1,06,1.6,223.1,M,-34.2,M,0.0,0000*49 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033137.370,A,4231.8305,N,08807.3058,W,0.19,141.35,070804,,*12 +$GPVTG,141.35,T,,M,0.19,N,0.4,K*6E +$GPZDA,033138,07,08,2004,00,00*4B +$GPGGA,033138.370,4231.8306,N,08807.3058,W,1,06,1.6,222.7,M,-34.2,M,0.0,0000*42 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033138.370,A,4231.8306,N,08807.3058,W,0.19,142.45,070804,,*1A +$GPVTG,142.45,T,,M,0.19,N,0.4,K*6A +$GPZDA,033139,07,08,2004,00,00*4A +$GPGGA,033139.370,4231.8308,N,08807.3057,W,1,06,1.6,222.3,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033139.370,A,4231.8308,N,08807.3057,W,0.19,142.00,070804,,*1B +$GPVTG,142.00,T,,M,0.19,N,0.4,K*6B +$GPZDA,033140,07,08,2004,00,00*44 +$GPGGA,033140.370,4231.8309,N,08807.3056,W,1,06,1.6,221.9,M,-34.2,M,0.0,0000*41 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPGSV,3,1,09,28,65,318,41,08,59,188,42,31,57,252,43,11,50,084,46*7E +$GPGSV,3,2,09,07,38,247,45,27,34,171,41,26,17,290,00,29,16,281,*73 +$GPGSV,3,3,09,19,15,054,00*4D +$GPRMC,033140.370,A,4231.8309,N,08807.3056,W,0.20,138.74,070804,,*11 +$GPVTG,138.74,T,,M,0.20,N,0.4,K*6F +$GPMSS,0,0,0.000000,0,*58 +$GPZDA,033141,07,08,2004,00,00*45 +$GPGGA,033141.370,4231.8310,N,08807.3055,W,1,06,1.6,221.4,M,-34.2,M,0.0,0000*46 +$GPGSA,A,3,28,08,11,27,07,31,,,,,,,4.7,1.6,4.4*34 +$GPRMC,033141.370,A,4231.8310,N,08807.3055,W,0.19,137.91,070804,,*15 +$GPVTG,137.91,T,,M,0.19,N,0.4,K*61 diff --git a/reference/track/nmea+ms.gpx b/reference/track/nmea+ms.gpx new file mode 100644 index 000000000..453ef1c4c --- /dev/null +++ b/reference/track/nmea+ms.gpx @@ -0,0 +1,290 @@ + + + + + + + + 47.500000 + + 171.410004 + 0.111111 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 47.800000 + + 169.850006 + 0.055556 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 47.900000 + + 167.320007 + 0.111111 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 48.000000 + + 165.429993 + 0.111111 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 48.100000 + + 164.399994 + 0.027778 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 48.200000 + + 168.419998 + 0.083333 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 48.300000 + + 181.889999 + 0.111111 + 3d + 6 + 1.700000 + + + 48.400000 + + 175.830002 + 0.138889 + 3d + 6 + 1.700000 + + + 48.400000 + + 179.449997 + 0.083333 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 48.500000 + + 176.820007 + 0.083333 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.600000 + + 202.580002 + 0.138889 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.600000 + + 174.279999 + 0.055556 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.000000 + + 177.330002 + 0.111111 + 3d + 6 + 1.700000 + + + 49.500000 + + 185.009995 + 0.027778 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.600000 + + 189.289993 + 0.083333 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 50.100000 + + 207.460007 + 0.222222 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.500000 + + 213.190002 + 0.138889 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.500000 + + 218.089996 + 0.277778 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.600000 + + 221.759995 + 0.250000 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.700000 + + 226.210007 + 0.222222 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.800000 + + 233.130005 + 0.138889 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 50.100000 + + 233.779999 + 0.055556 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 50.000000 + + 231.729996 + 0.055556 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.900000 + + 227.869995 + 0.055556 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.900000 + + 224.449997 + 0.083333 + 3d + 6 + 1.700000 + 2.700000 + 3.200000 + + + 49.900000 + + 3d + 6 + 1.700000 + + + + diff --git a/reference/track/nmea+ms.txt b/reference/track/nmea+ms.txt new file mode 100644 index 000000000..ca2fa3329 --- /dev/null +++ b/reference/track/nmea+ms.txt @@ -0,0 +1,125 @@ +$GPGGA,093156.000,5333.4037,N,00951.9344,E,1,06,1.7,47.5,M,46.0,M,,0000*61 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093156.500,A,5333.4037,N,00951.9345,E,0.20,171.41,170807,,,A*6A +$GPVTG,171.41,T,,M,0.20,N,0.4,K,A*09 +$GPGGA,093156.500,5333.4037,N,00951.9345,E,1,06,1.7,47.8,M,46.0,M,,0000*68 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093156.750,A,5333.4037,N,00951.9346,E,0.12,169.85,170807,,,A*6E +$GPVTG,169.85,T,,M,0.12,N,0.2,K,A*0F +$GPGGA,093156.750,5333.4037,N,00951.9346,E,1,06,1.7,47.9,M,46.0,M,,0000*6D +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093157.000,A,5333.4037,N,00951.9346,E,0.21,167.32,170807,,,A*6F +$GPVTG,167.32,T,,M,0.21,N,0.4,K,A*0B +$GPGGA,093157.000,5333.4037,N,00951.9346,E,1,06,1.7,48.0,M,46.0,M,,0000*68 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093157.250,A,5333.4037,N,00951.9346,E,0.19,165.43,170807,,,A*67 +$GPVTG,165.43,T,,M,0.19,N,0.4,K,A*04 +$GPGGA,093157.250,5333.4037,N,00951.9346,E,1,06,1.7,48.1,M,46.0,M,,0000*6E +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093157.500,A,5333.4037,N,00951.9347,E,0.06,164.40,170807,,,A*68 +$GPVTG,164.40,T,,M,0.06,N,0.1,K,A*0D +$GPGGA,093157.500,5333.4037,N,00951.9347,E,1,06,1.7,48.2,M,46.0,M,,0000*6E +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093157.750,A,5333.4037,N,00951.9346,E,0.15,168.42,170807,,,A*62 +$GPVTG,168.42,T,,M,0.15,N,0.3,K,A*03 +$GPGGA,093157.750,5333.4037,N,00951.9346,E,1,06,1.7,48.3,M,46.0,M,,0000*69 +$GPRMC,093158.250,A,5333.4037,N,00951.9347,E,0.24,181.89,170807,,,A*6B +$GPVTG,181.89,T,,M,0.24,N,0.4,K,A*06 +$GPGGA,093158.250,5333.4037,N,00951.9347,E,1,06,1.7,48.4,M,46.0,M,,0000*65 +$GPRMC,093158.500,A,5333.4037,N,00951.9347,E,0.09,180.87,170807,,,A*69 +$GPRMC,093158.000,A,5333.4037,N,00951.9346,E,0.28,175.83,170807,,,A*60 +$GPVTG,175.83,T,,M,0.28,N,0.5,K,A*0A +$GPGGA,093158.000,5333.4037,N,00951.9346,E,1,06,1.7,48.4,M,46.0,M,,0000*63 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPVTG,180.87,T,,M,0.09,N,0.2,K,A*00 +$GPGGA,093158.500,5333.4037,N,00951.9347,E,1,06,1.7,48.4,M,46.0,M,,0000*67 +$GPGSV,3,3,11,21,14,320,,03,07,025,,19,09,054,*4D +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093158.750,A,5333.4037,N,00951.9348,E,0.17,179.45,170807,,,A*66 +$GPVTG,179.45,T,,M,0.17,N,0.3,K,A*06 +$GPGGA,093158.750,5333.4037,N,00951.9348,E,1,06,1.7,48.5,M,46.0,M,,0000*6E +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093159.000,A,5333.4037,N,00951.9348,E,0.17,176.82,170807,,,A*61 +$GPVTG,176.82,T,,M,0.17,N,0.3,K,A*02 +$GPGGA,093159.000,5333.4037,N,00951.9348,E,1,06,1.7,48.7,M,46.0,M,,0000*6F +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPGSV,3,1,11,08,71,074,27,10,57,214,,29,52,291,24,27,44,067,34*74 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPGSV,3,1,11,08,71,074,27,10,57,214,,29,52,291,24,27,44,067,34*74 +$GPGGA,093200.500,5333.4037,N,00951.9347,E,1,06,1.7,49.6,M,46.0,M,,0000*6A +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPVTG,202.58,T,,M,0.30,N,0.5,K,A*06 +$GPGGA,093200.750,5333.4037,N,00951.9347,E,1,06,1.7,49.6,M,46.0,M,,0000*6D +$GPRMC,093159.750,A,5333.4037,N,00951.9347,E,0.06,181.63,170807,,,A*6B +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093159.250,A,5333.4037,N,00951.9348,E,0.09,174.28,170807,,,A*6B +$GPVTG,174.28,T,,M,0.09,N,0.2,K,A*0E +$GPGGA,093159.250,5333.4037,N,00951.9348,E,1,06,1.7,49.0,M,46.0,M,,0000*6E +$GPRMC,093159.500,A,5333.4037,N,00951.9347,E,0.19,177.33,170807,,,A*6E +$GPVTG,177.33,T,,M,0.19,N,0.4,K,A*00 +$GPGGA,093159.500,5333.4037,N,00951.9347,E,1,06,1.7,49.4,M,46.0,M,,0000*67 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPGSV,3,1,11,08,71,074,27,10,57,214,,29,52,291,24,27,44,067,34*74 +$GPVTG,181.63,T,,M,0.06,N,0.1,K,A*07 +$GPGGA,093159.750,5333.4037,N,00951.9347,E,1,06,1.7,49.5,M,46.0,M,,0000*61 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPVTG,229.91,T,,M,0.38,N,0.7,K,A*00 +$GPRMC,093200.000,A,5333.4037,N,00951.9348,E,0.05,185.01,170807,,,A*6A +$GPVTG,185.01,T,,M,0.05,N,0.1,K,A*04 +$GPGGA,093200.000,5333.4037,N,00951.9348,E,1,06,1.7,49.6,M,46.0,M,,0000*60 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093200.250,A,5333.4037,N,00951.9347,E,0.19,189.29,170807,,,A*69 +$GPVTG,189.29,T,,M,0.19,N,0.3,K,A*0D +$GPGGA,093202.250,5333.4037,N,00951.9345,E,1,06,1.7,50.1,M,46.0,M,,0000*67 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093200.500,A,5333.4037,N,00951.9347,E,0.25,196.46,170807,,,A*63 +$GPVTG,196.46,T,,M,0.25,N,0.5,K,A*03 +$GPRMC,093200.750,A,5333.4037,N,00951.9347,E,0.30,202.58,170807,,,A*61 +$GPRMC,093201.000,A,5333.4037,N,00951.9347,E,0.41,207.46,170807,,,A*6E +$GPVTG,207.46,T,,M,0.41,N,0.8,K,A*07 +$GPGGA,093201.000,5333.4037,N,00951.9347,E,1,06,1.7,49.5,M,46.0,M,,0000*6D +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093201.250,A,5333.4037,N,00951.9346,E,0.29,213.19,170807,,,A*69 +$GPVTG,213.19,T,,M,0.29,N,0.5,K,A*0B +$GPGGA,093201.250,5333.4037,N,00951.9346,E,1,06,1.7,49.5,M,46.0,M,,0000*6B +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093201.500,A,5333.4038,N,00951.9346,E,0.52,218.09,170807,,,A*62 +$GPVTG,218.09,T,,M,0.52,N,1.0,K,A*09 +$GPGGA,093201.500,5333.4038,N,00951.9346,E,1,06,1.7,49.6,M,46.0,M,,0000*65 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093201.750,A,5333.4037,N,00951.9345,E,0.49,221.76,170807,,,A*61 +$GPVTG,221.76,T,,M,0.49,N,0.9,K,A*09 +$GPGGA,093201.750,5333.4037,N,00951.9345,E,1,06,1.7,49.7,M,46.0,M,,0000*6F +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093202.000,A,5333.4037,N,00951.9345,E,0.41,226.21,170807,,,A*6D +$GPVTG,226.21,T,,M,0.41,N,0.8,K,A*05 +$GPGGA,093202.000,5333.4037,N,00951.9345,E,1,06,1.7,49.8,M,46.0,M,,0000*61 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093203.750,A,5333.4037,N,00951.9347,E,0.06,221.34,170807,,,A*6C +$GPRMC,093202.250,A,5333.4037,N,00951.9345,E,0.38,229.91,170807,,,A*60 +$GPRMC,093202.500,A,5333.4037,N,00951.9345,E,0.29,233.13,170807,,,A*63 +$GPVTG,233.13,T,,M,0.29,N,0.5,K,A*03 +$GPGGA,093202.500,5333.4037,N,00951.9345,E,1,06,1.7,50.1,M,46.0,M,,0000*65 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093202.750,A,5333.4037,N,00951.9346,E,0.12,233.78,170807,,,A*62 +$GPVTG,233.78,T,,M,0.12,N,0.2,K,A*01 +$GPGGA,093202.750,5333.4037,N,00951.9346,E,1,06,1.7,50.0,M,46.0,M,,0000*60 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093203.000,A,5333.4037,N,00951.9346,E,0.08,231.73,170807,,,A*63 +$GPVTG,231.73,T,,M,0.08,N,0.2,K,A*03 +$GPGGA,093203.000,5333.4037,N,00951.9346,E,1,06,1.7,49.9,M,46.0,M,,0000*62 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093203.250,A,5333.4037,N,00951.9346,E,0.10,227.87,170807,,,A*61 +$GPVTG,227.87,T,,M,0.10,N,0.2,K,A*06 +$GPGGA,093203.250,5333.4037,N,00951.9346,E,1,06,1.7,49.9,M,46.0,M,,0000*65 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPRMC,093203.500,A,5333.4037,N,00951.9347,E,0.17,224.45,170807,,,A*68 +$GPVTG,224.45,T,,M,0.17,N,0.3,K,A*0D +$GPGGA,093203.500,5333.4037,N,00951.9347,E,1,06,1.7,49.9,M,46.0,M,,0000*66 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPGSV,3,1,11,08,71,074,27,10,57,214,,29,52,291,25,27,44,067,34*75 +$GPVTG,221.34,T,,M,0.06,N,0.1,K,A*0C +$GPVTG,245.09,T,,M,0.24,N,0.4,K,A*05 +$GPGSA,A,3,08,29,27,28,26,24,,,,,,,3.2,1.7,2.7*3E +$GPGGA,093205.750,5333.4037,N,00951.9345,E,1,06,1.7,49.9,M,46.0,M,,0000*65 diff --git a/reference/track/nmea.gpx b/reference/track/nmea.gpx new file mode 100644 index 000000000..678db72ed --- /dev/null +++ b/reference/track/nmea.gpx @@ -0,0 +1,1708 @@ + + + + + + + + 209.800000 + + 138.919998 + 0.083333 + 3d + 5 + 1.600000 + 4.500000 + 4.900000 + + + 209.700000 + + 145.850006 + 0.083333 + 3d + 5 + 1.600000 + 4.500000 + 4.900000 + + + 209.700000 + + 143.250000 + 0.083333 + 3d + 5 + 1.600000 + 4.500000 + 4.900000 + + + 209.600000 + + 145.759995 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.600000 + + 141.440002 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.600000 + + 140.399994 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.600000 + + 142.509995 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.400000 + + 144.059998 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.300000 + + 137.660004 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.100000 + + 144.229996 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.900000 + + 140.350006 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.800000 + + 143.059998 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.600000 + + 145.080002 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.500000 + + 141.559998 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.400000 + + 140.759995 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.400000 + + 143.919998 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.300000 + + 140.850006 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.200000 + + 145.270004 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.000000 + + 145.610001 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 207.900000 + + 145.139999 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 207.800000 + + 143.490005 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 207.700000 + + 145.089996 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 207.800000 + + 143.000000 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 207.900000 + + 144.100006 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.200000 + + 142.360001 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.600000 + + 139.899994 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.200000 + + 145.610001 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.800000 + + 143.770004 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 210.600000 + + 144.649994 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 211.400000 + + 144.570007 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.200000 + + 144.350006 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.900000 + + 141.220001 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.500000 + + 146.149994 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.900000 + + 142.419998 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.100000 + + 141.130005 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.100000 + + 144.000000 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.800000 + + 142.179993 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.400000 + + 145.289993 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.000000 + + 144.630005 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.600000 + + 143.470001 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.400000 + + 142.350006 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.200000 + + 143.190002 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.100000 + + 143.639999 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.100000 + + 140.800003 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.100000 + + 141.910004 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.200000 + + 142.309998 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.400000 + + 140.729996 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.600000 + + 141.190002 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.900000 + + 142.600006 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.400000 + + 142.809998 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.800000 + + 140.440002 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.200000 + + 142.369995 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.700000 + + 139.389999 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.000000 + + 139.869995 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.200000 + + 141.369995 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.200000 + + 139.160004 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.200000 + + 142.389999 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.200000 + + 140.449997 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.100000 + + 141.089996 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.800000 + + 140.729996 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.600000 + + 137.970001 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.300000 + + 144.869995 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.000000 + + 137.610001 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.700000 + + 145.339996 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.400000 + + 136.350006 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.200000 + + 138.580002 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.000000 + + 140.110001 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 212.900000 + + 140.309998 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 212.900000 + + 138.899994 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.000000 + + 142.899994 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.100000 + + 143.660004 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.300000 + + 140.869995 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.300000 + + 146.139999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.300000 + + 141.570007 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.200000 + + 143.949997 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.200000 + + 141.809998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.100000 + + 142.070007 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.000000 + + 140.210007 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.000000 + + 145.889999 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.000000 + + 139.509995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.200000 + + 144.059998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.500000 + + 143.089996 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.900000 + + 141.050003 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 214.300000 + + 143.820007 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 214.800000 + + 143.529999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 215.100000 + + 144.089996 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 215.600000 + + 142.949997 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 216.100000 + + 142.279999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 216.700000 + + 141.429993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 217.300000 + + 142.059998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 218.000000 + + 141.460007 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 218.800000 + + 141.259995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 219.700000 + + 145.539993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 220.600000 + + 134.630005 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 221.700000 + + 144.440002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 222.700000 + + 146.970001 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 223.800000 + + 142.240005 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.800000 + + 142.729996 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.700000 + + 141.520004 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 226.400000 + + 141.429993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.000000 + + 137.690002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.500000 + + 144.580002 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.900000 + + 144.809998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 228.200000 + + 143.139999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 228.300000 + + 143.270004 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 228.400000 + + 139.119995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 228.300000 + + 140.070007 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 228.100000 + + 144.720001 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.800000 + + 140.800003 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.500000 + + 143.259995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.200000 + + 138.809998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 226.800000 + + 143.110001 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 226.400000 + + 140.100006 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 226.100000 + + 143.550003 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.900000 + + 142.119995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.700000 + + 141.639999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.600000 + + 143.270004 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.600000 + + 143.910004 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.500000 + + 145.970001 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.400000 + + 144.000000 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.300000 + + 146.250000 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.300000 + + 138.979996 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.100000 + + 143.100006 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.900000 + + 140.429993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.700000 + + 141.440002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.500000 + + 142.979996 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.300000 + + 145.029999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.300000 + + 143.059998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.300000 + + 145.490005 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.500000 + + 141.300003 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.700000 + + 141.190002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.000000 + + 143.009995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.200000 + + 140.809998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.300000 + + 140.789993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.300000 + + 141.429993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.300000 + + 142.300003 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.200000 + + 140.809998 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.200000 + + 142.399994 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.200000 + + 140.330002 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.100000 + + 137.770004 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.000000 + + 142.289993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.900000 + + 140.869995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.700000 + + 141.699997 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.500000 + + 141.699997 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.300000 + + 140.330002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.100000 + + 139.050003 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 223.900000 + + 144.460007 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 223.700000 + + 139.029999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 223.400000 + + 142.190002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 223.100000 + + 141.350006 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 222.700000 + + 142.449997 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 222.300000 + + 142.000000 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 221.900000 + + 138.740005 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 221.400000 + + 137.910004 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + + diff --git a/reference/track/pathaway.gpx b/reference/track/pathaway.gpx new file mode 100644 index 000000000..cd69d359f --- /dev/null +++ b/reference/track/pathaway.gpx @@ -0,0 +1,1999 @@ + + + + + + 20050116_Fahrradtour Gerd + + + 344.770031 + + + + 344.770031 + + + + 344.770031 + + + + 344.770031 + + + + 345.731334 + + + + 345.731334 + + + + 371.206311 + + + + 374.090100 + + + + 379.377454 + + + + 381.300061 + + + + 381.780652 + + + + 381.780652 + + + + 382.742078 + + + + 384.664807 + + + + 385.625989 + + + + 386.106702 + + + + 386.587415 + + + + 386.106702 + + + + 384.184094 + + + + 377.454846 + + + + 375.051526 + + + + 375.051526 + + + + 375.051526 + + + + 375.051526 + + + + 373.128918 + + + + 372.167492 + + + + 368.802990 + + + + 362.073742 + + + + 360.631725 + + + + 357.267101 + + + + 355.344494 + + + + 354.383190 + + + + 351.499157 + + + + 349.576549 + + + + 346.692638 + + + + 346.212047 + + + + 343.808605 + + + + 338.040782 + + + + 337.079479 + + + + 336.118175 + + + + 336.118175 + + + + 337.560069 + + + + 334.676158 + + + + 338.040782 + + + + 337.560069 + + + + 337.560069 + + + + 338.521495 + + + + 339.482677 + + + + 347.173229 + + + + 347.653942 + + + + 347.173229 + + + + 346.692638 + + + + 347.653942 + + + + 347.653942 + + + + 347.173229 + + + + 349.095836 + + + + 349.576549 + + + + 350.057262 + + + + 351.979870 + + + + 366.880261 + + + + 368.802990 + + + + 372.167492 + + + + 373.609509 + + + + 376.493542 + + + + 377.454846 + + + + 378.416150 + + + + 383.703259 + + + + 388.029309 + + + + 388.510022 + + + + 390.913221 + + + + 394.758558 + + + + 390.913221 + + + + 386.587415 + + + + 386.587415 + + + + 390.913221 + + + + 391.393811 + + + + 401.968519 + + + + 414.465467 + + + + 419.752821 + + + + 419.272230 + + + + 421.194838 + + + + 425.520766 + + + + 426.001356 + + + + 427.443373 + + + + 430.327284 + + + + 435.614516 + + + + 436.575942 + + + + 437.537123 + + + + 438.498549 + + + + 441.863173 + + + + 445.227675 + + + + 446.669692 + + + + 441.382460 + + + + 440.421279 + + + + 438.979140 + + + + 437.056533 + + + + 433.211318 + + + + 433.211318 + + + + 433.691908 + + + + 437.537123 + + + + 453.398940 + + + + 449.073012 + + + + 446.669692 + + + + 446.669692 + + + + 445.227675 + + + + 440.901870 + + + + 435.133925 + + + + 433.211318 + + + + 433.211318 + + + + 432.730727 + + + + 432.730727 + + + + 432.730727 + + + + 431.288588 + + + + 430.807997 + + + + 423.598036 + + + + 415.426893 + + + + 417.349623 + + + + 424.559462 + + + + 422.156019 + + + + 411.100965 + + + + 413.504286 + + + + 420.233412 + + + + 428.885390 + + + + 435.133925 + + + + 437.537123 + + + + 447.150283 + + + + 459.647598 + + + + 470.702652 + + + + 478.393204 + + + + 474.547989 + + + + 487.525650 + + + + 505.310197 + + + + 511.558732 + + + + 521.652605 + + + + 528.862566 + + + + 527.901018 + + + + 521.652605 + + + + 526.939836 + + + + 540.398333 + + + + 550.972674 + + + + 557.702166 + + + + 569.237811 + + + + 569.718524 + + + + 555.298602 + + + + 543.762835 + + + + 531.265764 + + + + 516.365251 + + + + 511.078019 + + + + 501.945573 + + + + 504.348893 + + + + 517.326677 + + + + 536.072405 + + + + 545.685564 + + + + 549.530779 + + + + 541.359514 + + + + 536.553118 + + + + 526.939836 + + + + 531.746355 + + + + 558.182879 + + + + 561.547381 + + + + 556.740740 + + + + 543.282122 + + + + 515.404069 + + + + 493.774308 + + + + 503.387467 + + + + 516.365251 + + + + 530.304460 + + + + 539.436907 + + + + 550.972674 + + + + 559.624774 + + + + 558.663348 + + + + 558.663348 + + + + 562.508563 + + + + 566.834491 + + + + 568.757098 + + + + 564.431170 + + + + 556.260028 + + + + 552.895281 + + + + 557.702166 + + + + 561.066668 + + + + 568.757098 + + + + 571.640887 + + + + 571.160419 + + + + 563.950458 + + + + 557.702166 + + + + 558.663348 + + + + 579.331561 + + + + 586.541523 + + + + 594.232197 + + + + 600.480732 + + + + 606.729267 + + + + 612.497090 + + + + 626.436299 + + + + 633.646016 + + + + 637.972188 + + + + 639.414083 + + + + 639.894796 + + + + 637.010763 + + + + 637.010763 + + + + 633.165303 + + + + 626.436299 + + + + 613.938984 + + + + 603.845234 + + + + 592.309589 + + + + 585.099628 + + + + 579.812274 + + + + 572.602557 + + + + 565.392596 + + + + 563.469989 + + + + 569.237811 + + + + 575.486347 + + + + 578.370380 + + + + 576.928485 + + + + 571.160419 + + + + 566.834491 + + + + 555.298602 + + + + 545.204851 + + + + 536.553118 + + + + 527.420427 + + + + 518.768571 + + + + 514.442643 + + + + 513.481462 + + + + 509.155412 + + + + 505.790910 + + + + 504.829484 + + + + 507.713517 + + + + 508.674699 + + + + 508.674699 + + + + 503.387467 + + + + 503.387467 + + + + 500.503556 + + + + 497.619645 + + + + 498.580949 + + + + 500.984147 + + + + 500.022965 + + + + 499.061539 + + + + 500.022965 + + + + 497.138932 + + + + 495.696915 + + + + 501.945573 + + + + 501.464860 + + + + 500.503556 + + + + 499.061539 + + + + 497.619645 + + + + 497.138932 + + + + 496.658341 + + + + 499.542252 + + + + 500.984147 + + + + 501.464860 + + + + 500.984147 + + + + 499.542252 + + + + 501.464860 + + + + 505.310197 + + + + 513.481462 + + + + 521.652605 + + + + 522.613908 + + + + 522.613908 + + + + 523.575212 + + + + 525.497820 + + + + 526.939836 + + + + 528.862566 + + + + 528.862566 + + + + 482.238541 + + + + 482.238541 + + + + 499.061539 + + + + 500.984147 + + + + 504.829484 + + + + 501.945573 + + + + 498.580949 + + + + 498.100358 + + + + 498.580949 + + + + 497.138932 + + + + 497.619645 + + + + 500.022965 + + + + 500.022965 + + + + 501.464860 + + + + 503.387467 + + + + 504.829484 + + + + 511.078019 + + + + 525.497820 + + + + 519.729875 + + + + 518.768571 + + + + 517.807268 + + + + 515.884660 + + + + 516.365251 + + + + 515.404069 + + + + 518.768571 + + + + 519.249284 + + + + 517.807268 + + + + 514.442643 + + + + 513.962053 + + + + 517.326677 + + + + 518.768571 + + + + 522.133195 + + + + 527.901018 + + + + 541.359514 + + + + 550.972674 + + + + 560.105243 + + + + 567.795672 + + + + 574.525165 + + + + 581.254413 + + + + 585.580097 + + + + 588.464374 + + + + 586.060810 + + + + 578.851093 + + + + 573.083270 + + + + 574.044452 + + + + 580.292987 + + + + 588.464374 + + + + 592.790302 + + + + 597.596699 + + + + 609.132588 + + + + 616.342305 + + + + 630.762227 + + + + 639.414083 + + + + 639.894796 + + + + 641.817403 + + + + 644.220724 + + + + 649.988546 + + + + 654.314718 + + + + 656.237082 + + + + 655.756613 + + + + 649.988546 + + + + 633.646016 + + + + 624.513692 + + + + 622.110371 + + + + 618.264912 + + + + 615.861836 + + + + 614.419697 + + + + 609.132588 + + + + 603.845234 + + + + 595.674091 + + + + 592.309589 + + + + 575.486347 + + + + 567.315204 + + + + 573.083270 + + + + 583.176776 + + + + 582.215595 + + + + 580.773700 + + + + 576.928485 + + + + 570.198993 + + + + 566.834491 + + + + 573.563983 + + + + 579.812274 + + + + 582.215595 + + + + 574.044452 + + + + 571.640887 + + + + 572.602557 + + + + 570.198993 + + + + 552.414568 + + + + 541.359514 + + + + 525.978410 + + + + 513.962053 + + + + 503.387467 + + + + 506.752091 + + + + 535.591570 + + + + 559.144061 + + + + 567.315204 + + + + 571.640887 + + + + 569.237811 + + + + 541.840227 + + + + 541.840227 + + + + 549.530779 + + + + 554.817889 + + + + 559.624774 + + + + 554.337420 + + + + 545.204851 + + + + 532.707781 + + + + 516.845964 + + + + 510.116716 + + + + 513.962053 + + + + 525.017229 + + + + 538.475725 + + + + 547.608172 + + + + 559.144061 + + + + 573.083270 + + + + 578.851093 + + + + 567.315204 + + + + 556.260028 + + + + 544.243670 + + + + 532.227068 + + + + 534.630388 + + + + 538.956316 + + + + 537.033709 + + + + 525.978410 + + + + 518.768571 + + + + 510.597306 + + + + 493.293595 + + + + 482.719254 + + + + 485.122452 + + + + 467.818741 + + + + 456.763564 + + + + 447.630996 + + + + 441.863173 + + + + 439.459731 + + + + 428.404677 + + + + 421.194838 + + + + 415.907484 + + + + 421.675429 + + + + 432.250014 + + + + 426.001356 + + + + 420.714125 + + + + 429.846571 + + + + 438.498549 + + + + 441.382460 + + + + 441.382460 + + + + 438.979140 + + + + 436.095229 + + + + 432.730727 + + + + 431.769179 + + + + 429.846571 + + + + 432.250014 + + + + 438.498549 + + + + 448.592422 + + + + 456.763564 + + + + 458.686172 + + + + 456.282974 + + + + 445.708388 + + + + 443.785781 + + + + 442.824477 + + + + 441.863173 + + + + 446.669692 + + + + 447.630996 + + + + 449.073012 + + + + 450.515029 + + + + 457.244277 + + + + 453.879653 + + + + 450.034438 + + + + 450.515029 + + + + 448.592422 + + + + 448.592422 + + + + 447.150283 + + + + 438.017836 + + + + 435.133925 + + + + 433.691908 + + + + 427.443373 + + + + 426.962782 + + + + 423.117445 + + + + 423.117445 + + + + 423.117445 + + + + 418.791517 + + + + 406.294325 + + + + 403.891126 + + + + 401.487806 + + + + 400.045911 + + + + 399.084363 + + + + 409.178358 + + + + 408.217054 + + + + 403.891126 + + + + 402.929700 + + + + 397.161756 + + + + 395.239148 + + + + 394.758558 + + + + 391.393811 + + + + 391.393811 + + + + 389.471204 + + + + 386.587415 + + + + 377.935437 + + + + 375.051526 + + + + 374.090100 + + + + 373.128918 + + + + 372.648205 + + + + 370.244885 + + + + 366.880261 + + + + 366.880261 + + + + 364.957653 + + + + 359.670422 + + + + 359.670422 + + + + 356.786388 + + + + 355.344494 + + + + 361.112438 + + + + 357.267101 + + + + 356.305798 + + + + 355.825207 + + + + 353.902599 + + + + 353.421886 + + + + 350.057262 + + + + 346.692638 + + + + 346.692638 + + + + 345.250621 + + + + 344.770031 + + + + 344.770031 + + + + 348.615246 + + + + 351.018444 + + + + 351.018444 + + + + 354.383190 + + + + 356.786388 + + + + 362.554333 + + + + 373.128918 + + + + 377.935437 + + + + 381.300061 + + + + 381.300061 + + + + 384.184094 + + + + 385.145398 + + + + 253.925423 + + + + 253.925423 + + + + + diff --git a/reference/track/pathaway.pdb b/reference/track/pathaway.pdb new file mode 100644 index 0000000000000000000000000000000000000000..5b86068d5ca420fb2b9e9428533f56f89f39934a GIT binary patch literal 44188 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 literal 0 HcmV?d00001 diff --git a/reference/track/pcx.trk b/reference/track/pcx.trk new file mode 100644 index 000000000..b6c46f36b --- /dev/null +++ b/reference/track/pcx.trk @@ -0,0 +1,76 @@ +H SOFTWARE NAME & VERSION +I PCX5 2.09 + +H R DATUM IDX DA DF DX DY DZ +M G WGS 84 121 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 + +H COORDINATE SYSTEM +U LAT LON DM + + +H TN meridian +H LATITUDE LONGITUDE DATE TIME ALT ;track +T N3003.73100 W09136.62100 25-MAY-02 17:06:21 1 +T N3003.76700 W09136.63400 25-MAY-02 17:09:55 0 +T N3003.76200 W09136.49600 25-MAY-02 17:12:00 0 +T N3003.74000 W09136.44300 25-MAY-02 17:12:48 0 +T N3003.69200 W09136.31700 25-MAY-02 17:14:41 0 +T N3003.58700 W09135.96400 25-MAY-02 17:17:16 0 +T N3003.46800 W09135.80100 25-MAY-02 17:17:46 0 +T N3003.32300 W09135.69400 25-MAY-02 17:18:20 0 +T N3003.23300 W09135.55700 25-MAY-02 17:19:01 0 +T N3002.98400 W09135.38500 25-MAY-02 17:20:46 0 +T N3002.94100 W09135.39300 25-MAY-02 17:21:10 0 +T N3002.92800 W09135.57600 25-MAY-02 17:21:51 0 +T N3002.77400 W09135.78700 25-MAY-02 17:22:35 0 +T N3002.73100 W09135.92300 25-MAY-02 17:23:08 0 +T N3002.83800 W09136.01600 25-MAY-02 18:04:23 0 +T N3002.82000 W09135.97800 25-MAY-02 18:06:04 2 +T N3002.78600 W09135.96800 25-MAY-02 18:07:06 0 +T N3002.77200 W09135.93700 25-MAY-02 18:08:18 1 +T N3002.78200 W09135.86400 25-MAY-02 18:10:20 0 +T N3002.78100 W09135.83000 25-MAY-02 18:11:09 0 +T N3002.80700 W09135.78000 25-MAY-02 18:12:18 0 +T N3002.84700 W09135.71200 25-MAY-02 18:14:22 0 +T N3002.86800 W09135.68600 25-MAY-02 18:15:04 2 +T N3002.89500 W09135.64500 25-MAY-02 18:16:14 1 +T N3002.92100 W09135.62800 25-MAY-02 18:17:01 1 +T N3002.96100 W09135.63100 25-MAY-02 18:18:07 0 +T N3003.01900 W09135.63900 25-MAY-02 18:19:51 2 +T N3003.04700 W09135.64700 25-MAY-02 18:20:39 0 +T N3003.07400 W09135.66200 25-MAY-02 18:21:24 0 +T N3003.10800 W09135.66200 25-MAY-02 18:22:17 0 +T N3003.13300 W09135.68000 25-MAY-02 18:23:18 0 +T N3003.18100 W09135.68100 25-MAY-02 18:24:37 0 +T N3003.29200 W09135.71200 25-MAY-02 18:28:13 6 +T N3003.22400 W09135.69600 25-MAY-02 18:31:36 2 +T N3003.19100 W09135.68700 25-MAY-02 18:32:56 0 +T N3003.15800 W09135.69000 25-MAY-02 18:34:02 0 +T N3003.14700 W09135.72600 25-MAY-02 18:36:03 0 +T N3003.14900 W09135.75800 25-MAY-02 18:36:48 0 +T N3003.15900 W09135.80700 25-MAY-02 18:37:52 1 +T N3003.18800 W09135.87100 25-MAY-02 18:39:18 0 +T N3003.21700 W09135.87800 25-MAY-02 18:40:15 0 +T N3003.23800 W09135.86600 25-MAY-02 18:41:25 6 +T N3003.21700 W09135.88500 25-MAY-02 18:42:37 0 +T N3003.19200 W09135.87500 25-MAY-02 18:44:01 0 +T N3003.16900 W09135.85100 25-MAY-02 18:45:53 0 +T N3003.15400 W09135.81600 25-MAY-02 18:46:54 0 +T N3003.14000 W09135.78600 25-MAY-02 18:47:42 0 +T N3003.13500 W09135.74100 25-MAY-02 18:48:41 0 +T N3003.13300 W09135.70100 25-MAY-02 18:49:52 0 +T N3003.11300 W09135.68200 25-MAY-02 18:50:49 0 +T N3003.06300 W09135.66400 25-MAY-02 18:52:14 0 +T N3003.03400 W09135.65400 25-MAY-02 18:52:56 0 +T N3003.01100 W09135.64600 25-MAY-02 18:53:38 0 +T N3002.94600 W09135.62300 25-MAY-02 18:55:11 0 +T N3002.90700 W09135.65500 25-MAY-02 18:56:32 0 +T N3002.88500 W09135.68500 25-MAY-02 18:57:24 0 +T N3002.85000 W09135.72700 25-MAY-02 18:58:40 7 +T N3002.82400 W09135.76000 25-MAY-02 18:59:28 0 +T N3002.79800 W09135.79600 25-MAY-02 19:00:22 0 +T N3002.78400 W09135.85900 25-MAY-02 19:01:41 0 +T N3002.77400 W09135.90800 25-MAY-02 19:02:48 0 +T N3002.77900 W09135.93800 25-MAY-02 19:03:43 0 +T N3002.80700 W09135.95700 25-MAY-02 19:04:49 0 +T N3002.82800 W09135.98000 25-MAY-02 19:05:57 0 diff --git a/reference/track/psittrks.txt b/reference/track/psittrks.txt new file mode 100755 index 000000000..e9eb75cb1 --- /dev/null +++ b/reference/track/psittrks.txt @@ -0,0 +1,1142 @@ +Track: ACTIVE LOG001 + 37.004356, -5.549169, 519.25, 09/05/03 14:34:08, 1 + 37.004528, -5.548804, 519.73, 09/05/03 14:34:26, 0 + 37.005494, -5.547044, 516.85, 09/05/03 14:36:15, 0 + 37.005494, -5.547023, 518.77, 09/05/03 14:38:44, 0 + 37.005494, -5.547044, 518.77, 09/05/03 14:39:33, 0 + 37.005494, -5.547044, 518.29, 09/05/03 14:40:33, 0 + 37.005537, -5.547109, 516.85, 09/05/03 14:40:53, 0 + 37.005558, -5.547044, 515.88, 09/05/03 14:41:07, 0 + 37.005579, -5.547023, 516.85, 09/05/03 14:41:24, 0 + 37.005601, -5.547001, 516.37, 09/05/03 14:41:44, 0 + 37.005601, -5.547001, 516.85, 09/05/03 14:42:01, 0 + 37.005622, -5.546980, 517.81, 09/05/03 14:44:20, 0 + 37.005622, -5.546980, 517.81, 09/05/03 14:45:56, 0 + 37.005601, -5.546980, 517.33, 09/05/03 14:46:34, 0 + 37.005601, -5.546980, 517.81, 09/05/03 14:47:52, 0 + 37.005601, -5.546980, 516.85, 09/05/03 14:50:17, 0 + 37.005601, -5.546980, 517.33, 09/05/03 14:51:24, 0 + 37.005579, -5.546980, 518.29, 09/05/03 14:52:13, 0 + 37.005665, -5.546894, 516.37, 09/05/03 14:52:17, 0 + 37.005730, -5.546830, 519.25, 09/05/03 14:52:19, 0 + 37.005837, -5.546851, 522.61, 09/05/03 14:52:22, 0 + 37.005987, -5.547109, 522.61, 09/05/03 14:52:25, 0 + 37.006116, -5.547366, 530.30, 09/05/03 14:52:28, 0 + 37.006223, -5.547516, 534.15, 09/05/03 14:52:31, 0 + 37.006352, -5.547709, 539.44, 09/05/03 14:52:35, 0 + 37.006395, -5.547731, 539.44, 09/05/03 14:52:36, 0 + 37.006524, -5.547817, 537.99, 09/05/03 14:52:39, 0 + 37.006888, -5.548224, 537.51, 09/05/03 14:52:47, 0 + 37.007360, -5.548589, 533.19, 09/05/03 14:52:57, 0 + 37.007425, -5.548632, 533.19, 09/05/03 14:52:58, 0 + 37.007639, -5.548847, 531.75, 09/05/03 14:53:02, 0 + 37.007811, -5.548804, 527.90, 09/05/03 14:53:07, 0 + 37.007747, -5.548718, 526.94, 09/05/03 14:53:09, 0 + 37.007532, -5.548654, 526.94, 09/05/03 14:53:12, 0 + 37.007275, -5.548482, 527.42, 09/05/03 14:53:17, 0 + 37.007146, -5.548418, 532.23, 09/05/03 14:53:20, 0 + 37.007060, -5.548246, 529.82, 09/05/03 14:53:25, 0 + 37.006910, -5.548031, 533.67, 09/05/03 14:53:30, 0 + 37.006481, -5.547774, 537.03, 09/05/03 14:53:36, 0 + 37.006094, -5.547280, 538.48, 09/05/03 14:53:45, 0 + 37.005987, -5.547152, 539.44, 09/05/03 14:53:47, 0 + 37.005944, -5.547001, 544.24, 09/05/03 14:53:50, 0 + 37.006009, -5.546873, 546.65, 09/05/03 14:53:53, 0 + 37.006180, -5.546894, 548.57, 09/05/03 14:53:56, 0 + 37.006438, -5.547130, 551.93, 09/05/03 14:54:00, 0 + 37.006481, -5.547216, 552.90, 09/05/03 14:54:01, 0 + 37.006717, -5.547452, 554.82, 09/05/03 14:54:06, 0 + 37.006695, -5.547216, 555.78, 09/05/03 14:54:11, 0 + 37.006459, -5.547130, 554.34, 09/05/03 14:54:14, 0 + 37.006202, -5.546851, 558.18, 09/05/03 14:54:20, 0 + 37.006459, -5.546851, 557.22, 09/05/03 14:54:25, 0 + 37.006609, -5.547152, 555.78, 09/05/03 14:54:28, 0 + 37.006738, -5.547495, 556.74, 09/05/03 14:54:31, 0 + 37.006867, -5.547667, 559.62, 09/05/03 14:54:33, 0 + 37.007039, -5.547667, 562.51, 09/05/03 14:54:36, 0 + 37.007017, -5.547452, 566.35, 09/05/03 14:54:40, 0 + 37.006717, -5.547473, 567.32, 09/05/03 14:54:43, 0 + 37.006545, -5.547688, 568.28, 09/05/03 14:54:45, 0 + 37.006502, -5.548267, 568.76, 09/05/03 14:54:49, 0 + 37.006738, -5.548460, 567.80, 09/05/03 14:54:55, 0 + 37.006781, -5.548353, 564.91, 09/05/03 14:54:58, 0 + 37.006695, -5.548160, 562.51, 09/05/03 14:55:01, 0 + 37.006631, -5.548117, 562.99, 09/05/03 14:55:02, 0 + 37.006502, -5.547795, 564.43, 09/05/03 14:55:07, 0 + 37.006159, -5.547237, 565.39, 09/05/03 14:55:16, 0 + 37.006223, -5.546873, 567.32, 09/05/03 14:55:24, 0 + 37.006330, -5.546958, 567.32, 09/05/03 14:55:26, 0 + 37.006438, -5.547087, 568.76, 09/05/03 14:55:28, 0 + 37.006545, -5.546894, 571.16, 09/05/03 14:55:35, 0 + 37.006159, -5.547023, 569.24, 09/05/03 14:55:39, 0 + 37.005966, -5.547280, 565.87, 09/05/03 14:55:41, 0 + 37.006116, -5.547709, 568.76, 09/05/03 14:55:46, 0 + 37.006266, -5.547838, 568.28, 09/05/03 14:55:48, 0 + 37.006459, -5.547967, 573.08, 09/05/03 14:55:51, 0 + 37.006652, -5.548117, 575.49, 09/05/03 14:55:54, 0 + 37.006781, -5.548139, 577.41, 09/05/03 14:55:57, 0 + 37.006760, -5.547924, 576.93, 09/05/03 14:56:02, 0 + 37.006738, -5.547774, 575.01, 09/05/03 14:56:07, 0 + 37.006931, -5.547967, 570.20, 09/05/03 14:56:11, 0 + 37.006974, -5.548053, 570.68, 09/05/03 14:56:12, 0 + 37.007060, -5.548224, 570.20, 09/05/03 14:56:14, 0 + 37.007167, -5.548182, 568.76, 09/05/03 14:56:20, 0 + 37.007124, -5.548117, 568.76, 09/05/03 14:56:21, 0 + 37.006996, -5.548031, 564.91, 09/05/03 14:56:23, 0 + 37.006652, -5.547752, 563.47, 09/05/03 14:56:28, 0 + 37.006524, -5.547645, 562.51, 09/05/03 14:56:30, 0 + 37.006395, -5.547366, 560.11, 09/05/03 14:56:34, 0 + 37.006502, -5.547237, 562.03, 09/05/03 14:56:39, 0 + 37.006609, -5.547388, 559.14, 09/05/03 14:56:42, 0 + 37.006652, -5.547624, 559.14, 09/05/03 14:56:44, 0 + 37.006888, -5.547924, 561.07, 09/05/03 14:56:50, 0 + 37.007146, -5.547860, 565.87, 09/05/03 14:56:56, 0 + 37.007082, -5.547645, 571.16, 09/05/03 14:56:59, 0 + 37.007017, -5.547602, 570.68, 09/05/03 14:57:00, 0 + 37.006910, -5.547602, 571.16, 09/05/03 14:57:01, 0 + 37.006738, -5.547345, 572.12, 09/05/03 14:57:07, 0 + 37.006910, -5.547388, 575.49, 09/05/03 14:57:10, 0 + 37.006974, -5.547624, 579.33, 09/05/03 14:57:12, 0 + 37.007039, -5.547795, 582.22, 09/05/03 14:57:14, 0 + 37.007253, -5.547731, 585.10, 09/05/03 14:57:18, 0 + 37.007232, -5.547667, 588.46, 09/05/03 14:57:19, 0 + 37.007210, -5.547602, 592.31, 09/05/03 14:57:20, 0 + 37.007039, -5.547538, 595.67, 09/05/03 14:57:22, 0 + 37.006674, -5.547945, 595.19, 09/05/03 14:57:26, 0 + 37.006738, -5.548182, 594.23, 09/05/03 14:57:28, 0 + 37.006931, -5.548139, 595.67, 09/05/03 14:57:31, 0 + 37.006910, -5.548074, 600.48, 09/05/03 14:57:33, 0 + 37.006888, -5.547924, 605.29, 09/05/03 14:57:36, 0 + 37.006888, -5.547817, 606.25, 09/05/03 14:57:38, 0 + 37.006738, -5.547645, 612.02, 09/05/03 14:57:41, 0 + 37.006609, -5.547667, 615.86, 09/05/03 14:57:42, 0 + 37.006288, -5.547903, 619.71, 09/05/03 14:57:45, 0 + 37.006180, -5.548031, 620.19, 09/05/03 14:57:46, 0 + 37.006116, -5.548160, 620.19, 09/05/03 14:57:47, 0 + 37.006180, -5.548739, 617.78, 09/05/03 14:57:52, 0 + 37.006309, -5.548847, 621.15, 09/05/03 14:57:55, 0 + 37.006352, -5.548868, 621.15, 09/05/03 14:57:56, 0 + 37.006373, -5.548868, 622.11, 09/05/03 14:57:57, 0 + 37.006652, -5.548396, 625.96, 09/05/03 14:58:02, 0 + 37.006695, -5.548160, 633.65, 09/05/03 14:58:05, 0 + 37.006695, -5.548310, 635.57, 09/05/03 14:58:07, 0 + 37.006738, -5.548246, 635.57, 09/05/03 14:58:08, 0 + 37.006845, -5.548010, 641.34, 09/05/03 14:58:12, 0 + 37.006910, -5.547881, 645.18, 09/05/03 14:58:15, 0 + 37.006953, -5.547838, 649.99, 09/05/03 14:58:16, 0 + 37.007017, -5.547752, 655.76, 09/05/03 14:58:18, 0 + 37.007017, -5.547709, 659.12, 09/05/03 14:58:19, 0 + 37.007017, -5.547667, 662.01, 09/05/03 14:58:20, 0 + 37.007017, -5.547602, 665.85, 09/05/03 14:58:21, 0 + 37.007039, -5.547559, 666.81, 09/05/03 14:58:22, 0 + 37.007060, -5.547366, 672.10, 09/05/03 14:58:25, 0 + 37.007060, -5.547323, 674.02, 09/05/03 14:58:26, 0 + 37.007103, -5.547237, 679.79, 09/05/03 14:58:28, 0 + 37.007124, -5.547216, 683.63, 09/05/03 14:58:29, 0 + 37.007146, -5.547194, 687.48, 09/05/03 14:58:30, 0 + 37.007232, -5.547194, 691.81, 09/05/03 14:58:32, 0 + 37.007318, -5.547452, 697.09, 09/05/03 14:58:35, 0 + 37.007318, -5.547709, 701.42, 09/05/03 14:58:37, 0 + 37.007253, -5.547967, 708.15, 09/05/03 14:58:39, 0 + 37.007232, -5.548096, 713.44, 09/05/03 14:58:40, 0 + 37.007339, -5.548289, 717.28, 09/05/03 14:58:44, 0 + 37.007232, -5.548074, 720.65, 09/05/03 14:58:47, 0 + 37.007146, -5.548053, 724.49, 09/05/03 14:58:48, 0 + 37.007060, -5.548031, 728.82, 09/05/03 14:58:49, 0 + 37.006845, -5.548053, 734.58, 09/05/03 14:58:51, 0 + 37.006609, -5.548224, 738.43, 09/05/03 14:58:53, 0 + 37.006481, -5.548482, 741.31, 09/05/03 14:58:55, 0 + 37.006609, -5.548632, 740.35, 09/05/03 14:58:58, 0 + 37.006609, -5.548525, 743.24, 09/05/03 14:59:00, 0 + 37.006588, -5.548482, 748.52, 09/05/03 14:59:01, 0 + 37.006524, -5.548482, 752.37, 09/05/03 14:59:02, 0 + 37.006438, -5.548482, 754.77, 09/05/03 14:59:03, 0 + 37.005901, -5.548761, 761.50, 09/05/03 14:59:08, 0 + 37.005837, -5.548933, 761.02, 09/05/03 14:59:09, 0 + 37.005880, -5.549254, 765.35, 09/05/03 14:59:12, 0 + 37.005944, -5.549405, 769.19, 09/05/03 14:59:14, 0 + 37.006116, -5.549598, 771.60, 09/05/03 14:59:19, 0 + 37.006288, -5.549662, 776.40, 09/05/03 14:59:23, 0 + 37.006373, -5.549662, 779.77, 09/05/03 14:59:25, 0 + 37.006416, -5.549662, 780.25, 09/05/03 14:59:26, 0 + 37.006567, -5.549448, 783.13, 09/05/03 14:59:32, 0 + 37.006567, -5.549383, 784.09, 09/05/03 14:59:33, 0 + 37.006588, -5.549190, 785.53, 09/05/03 14:59:36, 0 + 37.006588, -5.549018, 790.82, 09/05/03 14:59:39, 0 + 37.006567, -5.548868, 794.19, 09/05/03 14:59:41, 0 + 37.006567, -5.548761, 798.99, 09/05/03 14:59:43, 0 + 37.006545, -5.548675, 806.20, 09/05/03 14:59:45, 0 + 37.006524, -5.548611, 809.57, 09/05/03 14:59:46, 0 + 37.006524, -5.548568, 812.45, 09/05/03 14:59:47, 0 + 37.006524, -5.548460, 815.34, 09/05/03 14:59:49, 0 + 37.006545, -5.548353, 817.26, 09/05/03 14:59:51, 0 + 37.006588, -5.548267, 821.10, 09/05/03 14:59:53, 0 + 37.006609, -5.548224, 824.47, 09/05/03 14:59:54, 0 + 37.006609, -5.548224, 826.87, 09/05/03 14:59:55, 0 + 37.006631, -5.548160, 834.08, 09/05/03 14:59:58, 0 + 37.006524, -5.548074, 837.93, 09/05/03 15:00:00, 0 + 37.006459, -5.548031, 839.85, 09/05/03 15:00:01, 0 + 37.005816, -5.548289, 839.85, 09/05/03 15:00:07, 0 + 37.005751, -5.548739, 839.37, 09/05/03 15:00:10, 0 + 37.005858, -5.548890, 842.25, 09/05/03 15:00:12, 0 + 37.005987, -5.548954, 841.29, 09/05/03 15:00:15, 0 + 37.006116, -5.548975, 838.41, 09/05/03 15:00:17, 0 + 37.006223, -5.548954, 847.54, 09/05/03 15:00:20, 0 + 37.006266, -5.548911, 854.75, 09/05/03 15:00:22, 0 + 37.006330, -5.548847, 858.11, 09/05/03 15:00:24, 0 + 37.006416, -5.548761, 861.48, 09/05/03 15:00:27, 0 + 37.006567, -5.548611, 865.32, 09/05/03 15:00:32, 0 + 37.006631, -5.548546, 867.25, 09/05/03 15:00:34, 0 + 37.006588, -5.548460, 869.65, 09/05/03 15:00:36, 0 + 37.006245, -5.548289, 869.65, 09/05/03 15:00:41, 0 + 37.005622, -5.548589, 870.61, 09/05/03 15:00:46, 0 + 37.005558, -5.548761, 870.61, 09/05/03 15:00:47, 0 + 37.005687, -5.549448, 870.61, 09/05/03 15:00:54, 0 + 37.005794, -5.549426, 871.57, 09/05/03 15:00:57, 0 + 37.005880, -5.549362, 869.17, 09/05/03 15:01:00, 0 + 37.006180, -5.549319, 871.09, 09/05/03 15:01:10, 0 + 37.006266, -5.549319, 868.21, 09/05/03 15:01:13, 0 + 37.006373, -5.549276, 864.84, 09/05/03 15:01:16, 0 + 37.006438, -5.549254, 863.88, 09/05/03 15:01:18, 0 + 37.006459, -5.549190, 864.36, 09/05/03 15:01:21, 0 + 37.006438, -5.549018, 863.40, 09/05/03 15:01:25, 0 + 37.006524, -5.548933, 864.84, 09/05/03 15:01:29, 0 + 37.006803, -5.549233, 862.92, 09/05/03 15:01:35, 0 + 37.006867, -5.549769, 861.48, 09/05/03 15:01:39, 0 + 37.006910, -5.550284, 868.21, 09/05/03 15:01:43, 0 + 37.006996, -5.550499, 869.65, 09/05/03 15:01:45, 0 + 37.007017, -5.550606, 873.01, 09/05/03 15:01:46, 0 + 37.007167, -5.550692, 880.22, 09/05/03 15:01:49, 0 + 37.007210, -5.550714, 882.63, 09/05/03 15:01:50, 0 + 37.007360, -5.550649, 884.55, 09/05/03 15:01:53, 0 + 37.007360, -5.550520, 885.03, 09/05/03 15:01:55, 0 + 37.007382, -5.550327, 888.88, 09/05/03 15:01:58, 0 + 37.007124, -5.550199, 885.99, 09/05/03 15:02:01, 0 + 37.006996, -5.550220, 885.99, 09/05/03 15:02:02, 0 + 37.006631, -5.550392, 883.11, 09/05/03 15:02:05, 0 + 37.006223, -5.550950, 877.34, 09/05/03 15:02:09, 0 + 37.006180, -5.551143, 877.34, 09/05/03 15:02:10, 0 + 37.006330, -5.551529, 879.74, 09/05/03 15:02:14, 0 + 37.006395, -5.551572, 880.71, 09/05/03 15:02:16, 0 + 37.006459, -5.551615, 881.67, 09/05/03 15:02:18, 0 + 37.006524, -5.551550, 883.11, 09/05/03 15:02:22, 0 + 37.006567, -5.551422, 880.71, 09/05/03 15:02:25, 0 + 37.006545, -5.551229, 882.15, 09/05/03 15:02:29, 0 + 37.006545, -5.551078, 880.22, 09/05/03 15:02:32, 0 + 37.006459, -5.550756, 877.82, 09/05/03 15:02:39, 0 + 37.006438, -5.550692, 874.46, 09/05/03 15:02:40, 0 + 37.006438, -5.550649, 874.94, 09/05/03 15:02:41, 0 + 37.006416, -5.550606, 873.98, 09/05/03 15:02:42, 0 + 37.006416, -5.550435, 869.65, 09/05/03 15:02:45, 0 + 37.006416, -5.550392, 865.80, 09/05/03 15:02:46, 0 + 37.006373, -5.550177, 864.84, 09/05/03 15:02:51, 0 + 37.006395, -5.549984, 862.44, 09/05/03 15:02:55, 0 + 37.006373, -5.549855, 863.40, 09/05/03 15:02:58, 0 + 37.006352, -5.549748, 863.40, 09/05/03 15:03:00, 0 + 37.006288, -5.549619, 862.92, 09/05/03 15:03:03, 0 + 37.006266, -5.549533, 860.52, 09/05/03 15:03:05, 0 + 37.006245, -5.549426, 857.63, 09/05/03 15:03:08, 0 + 37.006180, -5.549104, 852.35, 09/05/03 15:03:16, 0 + 37.006180, -5.549061, 853.31, 09/05/03 15:03:17, 0 + 37.006223, -5.548890, 849.94, 09/05/03 15:03:22, 0 + 37.006266, -5.548782, 849.94, 09/05/03 15:03:27, 0 + 37.006288, -5.548675, 844.66, 09/05/03 15:03:31, 0 + 37.006266, -5.548589, 843.69, 09/05/03 15:03:33, 0 + 37.006223, -5.548503, 842.73, 09/05/03 15:03:36, 0 + 37.006266, -5.548418, 836.00, 09/05/03 15:03:39, 0 + 37.006288, -5.548396, 836.00, 09/05/03 15:03:40, 0 + 37.006245, -5.548267, 834.08, 09/05/03 15:03:43, 0 + 37.006223, -5.548224, 833.12, 09/05/03 15:03:44, 0 + 37.006116, -5.547988, 827.35, 09/05/03 15:03:48, 0 + 37.006052, -5.547881, 823.51, 09/05/03 15:03:50, 0 + 37.005987, -5.547688, 820.14, 09/05/03 15:03:53, 0 + 37.005923, -5.547516, 816.78, 09/05/03 15:03:56, 0 + 37.005901, -5.547366, 814.37, 09/05/03 15:03:59, 0 + 37.005858, -5.547280, 812.93, 09/05/03 15:04:01, 0 + 37.005794, -5.547087, 807.16, 09/05/03 15:04:05, 0 + 37.005773, -5.547044, 807.64, 09/05/03 15:04:06, 0 + 37.005708, -5.546958, 809.09, 09/05/03 15:04:08, 0 + 37.005687, -5.546851, 804.28, 09/05/03 15:04:10, 0 + 37.005687, -5.546744, 799.95, 09/05/03 15:04:12, 0 + 37.005665, -5.546701, 799.95, 09/05/03 15:04:13, 0 + 37.005687, -5.546443, 797.55, 09/05/03 15:04:19, 0 + 37.005730, -5.546315, 793.71, 09/05/03 15:04:22, 0 + 37.005858, -5.546336, 788.42, 09/05/03 15:04:25, 0 + 37.005966, -5.546443, 783.61, 09/05/03 15:04:27, 0 + 37.005987, -5.546551, 779.29, 09/05/03 15:04:28, 0 + 37.006052, -5.546744, 778.32, 09/05/03 15:04:30, 0 + 37.006159, -5.546894, 773.52, 09/05/03 15:04:32, 0 + 37.006266, -5.546980, 768.71, 09/05/03 15:04:34, 0 + 37.006395, -5.547044, 766.31, 09/05/03 15:04:36, 0 + 37.006438, -5.547044, 765.83, 09/05/03 15:04:37, 0 + 37.006631, -5.547109, 767.27, 09/05/03 15:04:40, 0 + 37.006717, -5.547023, 771.60, 09/05/03 15:04:44, 0 + 37.006803, -5.546787, 771.60, 09/05/03 15:04:51, 0 + 37.006867, -5.546765, 772.56, 09/05/03 15:04:52, 0 + 37.007082, -5.546787, 771.60, 09/05/03 15:04:57, 0 + 37.007489, -5.546658, 770.63, 09/05/03 15:05:05, 0 + 37.007682, -5.546637, 771.60, 09/05/03 15:05:09, 0 + 37.007918, -5.546765, 775.92, 09/05/03 15:05:13, 0 + 37.007983, -5.546808, 776.40, 09/05/03 15:05:14, 0 + 37.008154, -5.546851, 780.73, 09/05/03 15:05:17, 0 + 37.008262, -5.546594, 783.61, 09/05/03 15:05:22, 0 + 37.007854, -5.546486, 779.77, 09/05/03 15:05:26, 0 + 37.007554, -5.546787, 783.13, 09/05/03 15:05:29, 0 + 37.007468, -5.547216, 788.90, 09/05/03 15:05:32, 0 + 37.007511, -5.547409, 792.26, 09/05/03 15:05:34, 0 + 37.007682, -5.547559, 794.67, 09/05/03 15:05:37, 0 + 37.007811, -5.547581, 797.55, 09/05/03 15:05:39, 0 + 37.007918, -5.547538, 801.88, 09/05/03 15:05:42, 0 + 37.007961, -5.547473, 800.92, 09/05/03 15:05:43, 0 + 37.008026, -5.547345, 799.95, 09/05/03 15:05:45, 0 + 37.007596, -5.547237, 799.95, 09/05/03 15:05:50, 0 + 37.007275, -5.547516, 801.88, 09/05/03 15:05:53, 0 + 37.007146, -5.548182, 803.32, 09/05/03 15:05:58, 0 + 37.007253, -5.548353, 803.80, 09/05/03 15:06:00, 0 + 37.007468, -5.548353, 804.28, 09/05/03 15:06:05, 0 + 37.007575, -5.547988, 804.28, 09/05/03 15:06:13, 0 + 37.007618, -5.547903, 799.47, 09/05/03 15:06:15, 0 + 37.007682, -5.547838, 798.51, 09/05/03 15:06:17, 0 + 37.007768, -5.547581, 799.95, 09/05/03 15:06:22, 0 + 37.007747, -5.547409, 803.32, 09/05/03 15:06:24, 0 + 37.007661, -5.547237, 805.24, 09/05/03 15:06:26, 0 + 37.007489, -5.547109, 809.57, 09/05/03 15:06:28, 0 + 37.007275, -5.546851, 820.62, 09/05/03 15:06:32, 0 + 37.007253, -5.546787, 824.47, 09/05/03 15:06:33, 0 + 37.007318, -5.546722, 829.27, 09/05/03 15:06:35, 0 + 37.007403, -5.546722, 832.64, 09/05/03 15:06:37, 0 + 37.007468, -5.546744, 836.00, 09/05/03 15:06:38, 0 + 37.007554, -5.546937, 839.37, 09/05/03 15:06:40, 0 + 37.007596, -5.547323, 843.69, 09/05/03 15:06:43, 0 + 37.007446, -5.547559, 848.02, 09/05/03 15:06:45, 0 + 37.007232, -5.547667, 851.87, 09/05/03 15:06:47, 0 + 37.007039, -5.547624, 855.71, 09/05/03 15:06:49, 0 + 37.006974, -5.547559, 859.56, 09/05/03 15:06:50, 0 + 37.006953, -5.547495, 862.92, 09/05/03 15:06:51, 0 + 37.006910, -5.547431, 866.29, 09/05/03 15:06:52, 0 + 37.006888, -5.547366, 869.65, 09/05/03 15:06:53, 0 + 37.006867, -5.547259, 874.46, 09/05/03 15:06:55, 0 + 37.006931, -5.547194, 875.42, 09/05/03 15:06:57, 0 + 37.007189, -5.547452, 878.78, 09/05/03 15:07:01, 0 + 37.007253, -5.547709, 882.15, 09/05/03 15:07:03, 0 + 37.007210, -5.548010, 885.99, 09/05/03 15:07:05, 0 + 37.007124, -5.548267, 889.36, 09/05/03 15:07:07, 0 + 37.006953, -5.548482, 894.16, 09/05/03 15:07:09, 0 + 37.006631, -5.548482, 898.97, 09/05/03 15:07:12, 0 + 37.006545, -5.548353, 905.70, 09/05/03 15:07:14, 0 + 37.006545, -5.548310, 909.06, 09/05/03 15:07:15, 0 + 37.006631, -5.548267, 913.39, 09/05/03 15:07:17, 0 + 37.006824, -5.548353, 917.72, 09/05/03 15:07:20, 0 + 37.006931, -5.548546, 922.04, 09/05/03 15:07:22, 0 + 37.006953, -5.548825, 927.33, 09/05/03 15:07:24, 0 + 37.006888, -5.549126, 933.58, 09/05/03 15:07:26, 0 + 37.006824, -5.549233, 936.46, 09/05/03 15:07:27, 0 + 37.006652, -5.549426, 944.15, 09/05/03 15:07:29, 0 + 37.006373, -5.549684, 953.28, 09/05/03 15:07:32, 0 + 37.006137, -5.549769, 960.01, 09/05/03 15:07:34, 0 + 37.006030, -5.549705, 963.86, 09/05/03 15:07:35, 0 + 37.005923, -5.549576, 970.11, 09/05/03 15:07:37, 0 + 37.005858, -5.549490, 977.32, 09/05/03 15:07:39, 0 + 37.005837, -5.549426, 982.60, 09/05/03 15:07:40, 0 + 37.005880, -5.549362, 987.41, 09/05/03 15:07:42, 0 + 37.005987, -5.549254, 991.74, 09/05/03 15:07:45, 0 + 37.006094, -5.549276, 995.10, 09/05/03 15:07:47, 0 + 37.006159, -5.549297, 995.58, 09/05/03 15:07:48, 0 + 37.006395, -5.549684, 1000.87, 09/05/03 15:07:52, 0 + 37.006416, -5.549812, 1004.23, 09/05/03 15:07:53, 0 + 37.006438, -5.549941, 1008.08, 09/05/03 15:07:54, 0 + 37.006438, -5.550048, 1011.44, 09/05/03 15:07:55, 0 + 37.006438, -5.550177, 1015.77, 09/05/03 15:07:56, 0 + 37.006416, -5.550306, 1019.62, 09/05/03 15:07:57, 0 + 37.006245, -5.550649, 1025.38, 09/05/03 15:08:00, 0 + 37.006030, -5.550778, 1029.71, 09/05/03 15:08:02, 0 + 37.005837, -5.550821, 1035.48, 09/05/03 15:08:04, 0 + 37.005644, -5.550842, 1038.84, 09/05/03 15:08:06, 0 + 37.005451, -5.550756, 1049.42, 09/05/03 15:08:09, 0 + 37.005386, -5.550714, 1052.30, 09/05/03 15:08:10, 0 + 37.005386, -5.550478, 1057.11, 09/05/03 15:08:13, 0 + 37.005429, -5.550456, 1061.91, 09/05/03 15:08:14, 0 + 37.005537, -5.550456, 1068.16, 09/05/03 15:08:16, 0 + 37.005687, -5.550520, 1071.53, 09/05/03 15:08:18, 0 + 37.005816, -5.550692, 1074.89, 09/05/03 15:08:20, 0 + 37.005880, -5.550971, 1078.74, 09/05/03 15:08:22, 0 + 37.005901, -5.551100, 1081.62, 09/05/03 15:08:23, 0 + 37.005880, -5.551229, 1084.99, 09/05/03 15:08:24, 0 + 37.005858, -5.551336, 1090.75, 09/05/03 15:08:25, 0 + 37.005773, -5.551572, 1095.56, 09/05/03 15:08:27, 0 + 37.005622, -5.551744, 1100.37, 09/05/03 15:08:29, 0 + 37.005451, -5.551808, 1105.65, 09/05/03 15:08:31, 0 + 37.005365, -5.551829, 1107.58, 09/05/03 15:08:32, 0 + 37.005086, -5.551829, 1114.79, 09/05/03 15:08:35, 0 + 37.004850, -5.551701, 1120.07, 09/05/03 15:08:38, 0 + 37.004850, -5.551507, 1125.36, 09/05/03 15:08:40, 0 + 37.004914, -5.551400, 1130.17, 09/05/03 15:08:42, 0 + 37.004957, -5.551400, 1133.53, 09/05/03 15:08:43, 0 + 37.005043, -5.551357, 1137.86, 09/05/03 15:08:45, 0 + 37.005365, -5.551701, 1143.63, 09/05/03 15:08:50, 0 + 37.005365, -5.551829, 1146.99, 09/05/03 15:08:51, 0 + 37.005343, -5.552258, 1150.35, 09/05/03 15:08:54, 0 + 37.005236, -5.552495, 1156.60, 09/05/03 15:08:56, 0 + 37.005064, -5.552645, 1160.45, 09/05/03 15:08:58, 0 + 37.004807, -5.552838, 1170.06, 09/05/03 15:09:01, 0 + 37.004721, -5.552881, 1173.91, 09/05/03 15:09:02, 0 + 37.004442, -5.552924, 1179.19, 09/05/03 15:09:05, 0 + 37.004249, -5.552881, 1184.48, 09/05/03 15:09:07, 0 + 37.004120, -5.552773, 1187.85, 09/05/03 15:09:09, 0 + 37.004013, -5.552495, 1191.69, 09/05/03 15:09:12, 0 + 37.004035, -5.552409, 1195.06, 09/05/03 15:09:13, 0 + 37.004099, -5.552301, 1201.79, 09/05/03 15:09:15, 0 + 37.004185, -5.552280, 1206.11, 09/05/03 15:09:17, 0 + 37.004378, -5.552344, 1209.96, 09/05/03 15:09:20, 0 + 37.004592, -5.552709, 1213.32, 09/05/03 15:09:24, 0 + 37.004635, -5.553117, 1217.65, 09/05/03 15:09:27, 0 + 37.004592, -5.553396, 1221.01, 09/05/03 15:09:29, 0 + 37.004249, -5.553825, 1225.82, 09/05/03 15:09:33, 0 + 37.004035, -5.553868, 1231.59, 09/05/03 15:09:35, 0 + 37.003863, -5.553846, 1237.83, 09/05/03 15:09:37, 0 + 37.003734, -5.553739, 1242.16, 09/05/03 15:09:39, 0 + 37.003670, -5.553482, 1245.53, 09/05/03 15:09:42, 0 + 37.003734, -5.553310, 1250.81, 09/05/03 15:09:45, 0 + 37.003777, -5.553310, 1254.66, 09/05/03 15:09:46, 0 + 37.003820, -5.553310, 1257.06, 09/05/03 15:09:47, 0 + 37.003927, -5.553310, 1259.94, 09/05/03 15:09:49, 0 + 37.004120, -5.553610, 1263.79, 09/05/03 15:09:53, 0 + 37.004142, -5.553739, 1264.75, 09/05/03 15:09:54, 0 + 37.004142, -5.554018, 1268.12, 09/05/03 15:09:56, 0 + 37.003992, -5.554447, 1274.85, 09/05/03 15:09:59, 0 + 37.003820, -5.554662, 1278.21, 09/05/03 15:10:01, 0 + 37.003648, -5.554855, 1282.06, 09/05/03 15:10:03, 0 + 37.003155, -5.554941, 1289.27, 09/05/03 15:10:08, 0 + 37.003069, -5.554855, 1292.63, 09/05/03 15:10:10, 0 + 37.003026, -5.554726, 1296.48, 09/05/03 15:10:12, 0 + 37.003069, -5.554576, 1299.36, 09/05/03 15:10:15, 0 + 37.003262, -5.554662, 1304.65, 09/05/03 15:10:19, 0 + 37.003369, -5.554769, 1308.01, 09/05/03 15:10:21, 0 + 37.003520, -5.555027, 1311.38, 09/05/03 15:10:24, 0 + 37.003584, -5.555563, 1315.22, 09/05/03 15:10:28, 0 + 37.003584, -5.555885, 1318.59, 09/05/03 15:10:30, 0 + 37.003498, -5.556185, 1321.95, 09/05/03 15:10:32, 0 + 37.003455, -5.556314, 1324.83, 09/05/03 15:10:33, 0 + 37.003348, -5.556550, 1327.24, 09/05/03 15:10:35, 0 + 37.002983, -5.556936, 1331.08, 09/05/03 15:10:39, 0 + 37.002897, -5.556979, 1334.93, 09/05/03 15:10:40, 0 + 37.002833, -5.557001, 1338.77, 09/05/03 15:10:41, 0 + 37.002683, -5.557001, 1339.73, 09/05/03 15:10:43, 0 + 37.002361, -5.556829, 1345.02, 09/05/03 15:10:48, 0 + 37.002275, -5.556550, 1348.39, 09/05/03 15:10:53, 0 + 37.002361, -5.556464, 1352.71, 09/05/03 15:10:56, 0 + 37.002468, -5.556486, 1357.04, 09/05/03 15:10:58, 0 + 37.002640, -5.556614, 1362.33, 09/05/03 15:11:01, 0 + 37.002811, -5.556893, 1365.21, 09/05/03 15:11:04, 0 + 37.002876, -5.557301, 1369.54, 09/05/03 15:11:07, 0 + 37.002833, -5.557730, 1373.38, 09/05/03 15:11:10, 0 + 37.002790, -5.557880, 1376.26, 09/05/03 15:11:11, 0 + 37.002704, -5.558138, 1378.19, 09/05/03 15:11:13, 0 + 37.002296, -5.558674, 1386.36, 09/05/03 15:11:18, 0 + 37.002103, -5.558782, 1390.20, 09/05/03 15:11:20, 0 + 37.001803, -5.558867, 1395.49, 09/05/03 15:11:23, 0 + 37.001653, -5.558825, 1398.37, 09/05/03 15:11:25, 0 + 37.001588, -5.558803, 1399.82, 09/05/03 15:11:26, 0 + 37.001438, -5.558739, 1401.26, 09/05/03 15:11:28, 0 + 37.001395, -5.558395, 1405.10, 09/05/03 15:11:34, 0 + 37.001503, -5.558374, 1409.43, 09/05/03 15:11:36, 0 + 37.001674, -5.558460, 1413.76, 09/05/03 15:11:39, 0 + 37.001803, -5.558567, 1416.64, 09/05/03 15:11:41, 0 + 37.001932, -5.558867, 1420.00, 09/05/03 15:11:44, 0 + 37.001975, -5.559039, 1420.49, 09/05/03 15:11:45, 0 + 37.002039, -5.559490, 1425.29, 09/05/03 15:11:48, 0 + 37.001932, -5.560091, 1427.70, 09/05/03 15:11:52, 0 + 37.001717, -5.560648, 1433.46, 09/05/03 15:11:56, 0 + 37.001653, -5.560756, 1432.98, 09/05/03 15:11:57, 0 + 37.001503, -5.561013, 1434.91, 09/05/03 15:11:59, 0 + 37.001202, -5.561271, 1440.19, 09/05/03 15:12:02, 0 + 37.001009, -5.561335, 1444.52, 09/05/03 15:12:04, 0 + 37.000816, -5.561378, 1448.36, 09/05/03 15:12:06, 0 + 37.000558, -5.561314, 1453.17, 09/05/03 15:12:09, 0 + 37.000473, -5.560992, 1455.57, 09/05/03 15:12:15, 0 + 37.000515, -5.560970, 1455.57, 09/05/03 15:12:16, 0 + 37.000580, -5.560949, 1456.05, 09/05/03 15:12:17, 0 + 37.000666, -5.560906, 1457.98, 09/05/03 15:12:19, 0 + 37.001052, -5.561142, 1463.26, 09/05/03 15:12:25, 0 + 37.001224, -5.561464, 1465.67, 09/05/03 15:12:28, 0 + 37.001288, -5.561893, 1470.95, 09/05/03 15:12:31, 0 + 37.001288, -5.562043, 1471.44, 09/05/03 15:12:32, 0 + 37.001202, -5.562494, 1471.92, 09/05/03 15:12:35, 0 + 37.000880, -5.563030, 1473.36, 09/05/03 15:12:39, 0 + 37.000558, -5.563331, 1474.32, 09/05/03 15:12:42, 0 + 37.000129, -5.563502, 1479.13, 09/05/03 15:12:46, 0 + 36.999850, -5.563524, 1482.01, 09/05/03 15:12:49, 0 + 36.999464, -5.563331, 1485.37, 09/05/03 15:12:54, 0 + 36.999443, -5.563138, 1489.22, 09/05/03 15:12:57, 0 + 36.999464, -5.563052, 1490.66, 09/05/03 15:12:59, 0 + 36.999764, -5.563116, 1495.95, 09/05/03 15:13:05, 0 + 36.999829, -5.563202, 1495.95, 09/05/03 15:13:06, 0 + 37.000000, -5.563867, 1494.51, 09/05/03 15:13:11, 0 + 36.999915, -5.564296, 1498.83, 09/05/03 15:13:14, 0 + 36.999850, -5.564425, 1499.79, 09/05/03 15:13:15, 0 + 36.999722, -5.564725, 1500.27, 09/05/03 15:13:17, 0 + 36.999335, -5.565369, 1502.68, 09/05/03 15:13:22, 0 + 36.999056, -5.565777, 1503.64, 09/05/03 15:13:25, 0 + 36.998627, -5.566120, 1508.45, 09/05/03 15:13:29, 0 + 36.998498, -5.566185, 1509.41, 09/05/03 15:13:30, 0 + 36.998112, -5.566249, 1514.21, 09/05/03 15:13:34, 0 + 36.998048, -5.566249, 1513.73, 09/05/03 15:13:35, 0 + 36.997790, -5.565948, 1513.25, 09/05/03 15:13:41, 0 + 36.997812, -5.565798, 1516.62, 09/05/03 15:13:44, 0 + 36.997855, -5.565777, 1516.62, 09/05/03 15:13:45, 0 + 36.998026, -5.565820, 1516.62, 09/05/03 15:13:48, 0 + 36.998155, -5.565906, 1518.06, 09/05/03 15:13:50, 0 + 36.998413, -5.566528, 1520.46, 09/05/03 15:13:56, 0 + 36.998413, -5.567300, 1524.79, 09/05/03 15:14:01, 0 + 36.997919, -5.568759, 1526.23, 09/05/03 15:14:10, 0 + 36.997683, -5.569210, 1529.59, 09/05/03 15:14:13, 0 + 36.997511, -5.569489, 1530.56, 09/05/03 15:14:15, 0 + 36.997297, -5.569789, 1531.52, 09/05/03 15:14:17, 0 + 36.996717, -5.570197, 1532.00, 09/05/03 15:14:22, 0 + 36.996353, -5.570304, 1527.19, 09/05/03 15:14:25, 0 + 36.996117, -5.570326, 1526.23, 09/05/03 15:14:27, 0 + 36.995687, -5.570261, 1522.87, 09/05/03 15:14:31, 0 + 36.995215, -5.570047, 1520.94, 09/05/03 15:14:37, 0 + 36.995087, -5.569661, 1519.98, 09/05/03 15:14:44, 0 + 36.995387, -5.569704, 1520.46, 09/05/03 15:14:49, 0 + 36.995559, -5.569897, 1520.94, 09/05/03 15:14:52, 0 + 36.995752, -5.570369, 1517.10, 09/05/03 15:14:56, 0 + 36.995795, -5.570669, 1517.58, 09/05/03 15:14:58, 0 + 36.995773, -5.571291, 1514.21, 09/05/03 15:15:02, 0 + 36.995709, -5.571635, 1513.25, 09/05/03 15:15:04, 0 + 36.995430, -5.572772, 1509.89, 09/05/03 15:15:11, 0 + 36.995409, -5.572944, 1510.37, 09/05/03 15:15:12, 0 + 36.995108, -5.573866, 1506.52, 09/05/03 15:15:18, 0 + 36.995044, -5.574017, 1505.56, 09/05/03 15:15:19, 0 + 36.994829, -5.574446, 1501.24, 09/05/03 15:15:22, 0 + 36.994550, -5.574832, 1494.03, 09/05/03 15:15:25, 0 + 36.994314, -5.575111, 1488.74, 09/05/03 15:15:27, 0 + 36.993928, -5.575626, 1485.85, 09/05/03 15:15:31, 0 + 36.993692, -5.575862, 1483.93, 09/05/03 15:15:33, 0 + 36.993327, -5.576077, 1478.16, 09/05/03 15:15:36, 0 + 36.993070, -5.576119, 1474.32, 09/05/03 15:15:38, 0 + 36.992812, -5.576119, 1470.47, 09/05/03 15:15:40, 0 + 36.992705, -5.576098, 1467.11, 09/05/03 15:15:41, 0 + 36.992598, -5.576034, 1464.23, 09/05/03 15:15:42, 0 + 36.992447, -5.575883, 1460.86, 09/05/03 15:15:44, 0 + 36.992383, -5.575712, 1455.57, 09/05/03 15:15:46, 0 + 36.992362, -5.575604, 1452.21, 09/05/03 15:15:48, 0 + 36.992404, -5.575540, 1447.88, 09/05/03 15:15:50, 0 + 36.992555, -5.575669, 1444.04, 09/05/03 15:15:53, 0 + 36.992619, -5.575905, 1439.23, 09/05/03 15:15:55, 0 + 36.992598, -5.576162, 1438.75, 09/05/03 15:15:57, 0 + 36.992512, -5.576570, 1432.50, 09/05/03 15:16:00, 0 + 36.992469, -5.576720, 1429.62, 09/05/03 15:16:01, 0 + 36.992426, -5.576870, 1426.73, 09/05/03 15:16:02, 0 + 36.992426, -5.577321, 1422.89, 09/05/03 15:16:06, 0 + 36.992555, -5.577493, 1418.56, 09/05/03 15:16:09, 0 + 36.992598, -5.577428, 1414.72, 09/05/03 15:16:11, 0 + 36.992447, -5.577192, 1409.91, 09/05/03 15:16:15, 0 + 36.992254, -5.577064, 1402.22, 09/05/03 15:16:17, 0 + 36.992147, -5.577021, 1400.30, 09/05/03 15:16:18, 0 + 36.991932, -5.576935, 1398.86, 09/05/03 15:16:20, 0 + 36.991396, -5.576956, 1395.97, 09/05/03 15:16:24, 0 + 36.991267, -5.577021, 1395.49, 09/05/03 15:16:25, 0 + 36.991031, -5.577171, 1392.13, 09/05/03 15:16:27, 0 + 36.990817, -5.577407, 1386.84, 09/05/03 15:16:29, 0 + 36.990666, -5.577664, 1382.99, 09/05/03 15:16:31, 0 + 36.990581, -5.577943, 1380.11, 09/05/03 15:16:33, 0 + 36.990538, -5.578201, 1376.75, 09/05/03 15:16:35, 0 + 36.990538, -5.578308, 1373.38, 09/05/03 15:16:36, 0 + 36.990581, -5.578523, 1368.57, 09/05/03 15:16:38, 0 + 36.990731, -5.578673, 1364.25, 09/05/03 15:16:42, 0 + 36.990774, -5.578651, 1360.88, 09/05/03 15:16:43, 0 + 36.990817, -5.578544, 1357.04, 09/05/03 15:16:45, 0 + 36.990752, -5.578394, 1352.71, 09/05/03 15:16:47, 0 + 36.990602, -5.578244, 1349.35, 09/05/03 15:16:49, 0 + 36.990237, -5.578158, 1345.02, 09/05/03 15:16:52, 0 + 36.989980, -5.578179, 1341.18, 09/05/03 15:16:54, 0 + 36.989701, -5.578330, 1335.89, 09/05/03 15:16:56, 0 + 36.989594, -5.578415, 1333.49, 09/05/03 15:16:57, 0 + 36.989121, -5.578759, 1327.24, 09/05/03 15:17:01, 0 + 36.988885, -5.578973, 1322.91, 09/05/03 15:17:03, 0 + 36.988671, -5.579209, 1320.51, 09/05/03 15:17:05, 0 + 36.988456, -5.579617, 1314.74, 09/05/03 15:17:08, 0 + 36.988413, -5.579896, 1311.38, 09/05/03 15:17:10, 0 + 36.988413, -5.580282, 1305.61, 09/05/03 15:17:13, 0 + 36.988478, -5.580497, 1300.80, 09/05/03 15:17:15, 0 + 36.988628, -5.580668, 1295.99, 09/05/03 15:17:18, 0 + 36.988735, -5.580647, 1290.71, 09/05/03 15:17:21, 0 + 36.988778, -5.580540, 1286.86, 09/05/03 15:17:23, 0 + 36.988714, -5.580368, 1282.54, 09/05/03 15:17:25, 0 + 36.988585, -5.580239, 1277.73, 09/05/03 15:17:27, 0 + 36.988370, -5.580132, 1272.44, 09/05/03 15:17:29, 0 + 36.988156, -5.580089, 1267.64, 09/05/03 15:17:31, 0 + 36.988027, -5.580111, 1265.23, 09/05/03 15:17:32, 0 + 36.987770, -5.580132, 1258.50, 09/05/03 15:17:34, 0 + 36.987641, -5.580153, 1256.10, 09/05/03 15:17:35, 0 + 36.987276, -5.580325, 1249.85, 09/05/03 15:17:38, 0 + 36.987169, -5.580411, 1246.01, 09/05/03 15:17:39, 0 + 36.987062, -5.580497, 1242.64, 09/05/03 15:17:40, 0 + 36.986761, -5.580862, 1237.35, 09/05/03 15:17:43, 0 + 36.986482, -5.581205, 1233.51, 09/05/03 15:17:46, 0 + 36.986396, -5.581334, 1228.70, 09/05/03 15:17:47, 0 + 36.986139, -5.581720, 1224.86, 09/05/03 15:17:50, 0 + 36.985903, -5.582128, 1220.05, 09/05/03 15:17:53, 0 + 36.985817, -5.582256, 1216.69, 09/05/03 15:17:54, 0 + 36.985581, -5.582685, 1213.80, 09/05/03 15:17:57, 0 + 36.985409, -5.582943, 1210.44, 09/05/03 15:17:59, 0 + 36.985173, -5.583351, 1212.36, 09/05/03 15:18:02, 0 + 36.984572, -5.583565, 1213.32, 09/05/03 15:18:08, 0 + 36.984422, -5.583329, 1209.96, 09/05/03 15:18:13, 0 + 36.984551, -5.583351, 1207.07, 09/05/03 15:18:15, 0 + 36.984680, -5.583479, 1205.63, 09/05/03 15:18:17, 0 + 36.984766, -5.583780, 1204.67, 09/05/03 15:18:20, 0 + 36.984830, -5.584123, 1200.34, 09/05/03 15:18:23, 0 + 36.984851, -5.584252, 1196.98, 09/05/03 15:18:24, 0 + 36.984959, -5.584552, 1191.69, 09/05/03 15:18:27, 0 + 36.985044, -5.584681, 1185.44, 09/05/03 15:18:29, 0 + 36.985109, -5.584724, 1181.60, 09/05/03 15:18:30, 0 + 36.985173, -5.584745, 1178.71, 09/05/03 15:18:31, 0 + 36.985259, -5.584724, 1174.39, 09/05/03 15:18:33, 0 + 36.985259, -5.584617, 1168.14, 09/05/03 15:18:35, 0 + 36.985173, -5.584488, 1162.85, 09/05/03 15:18:37, 0 + 36.985087, -5.584445, 1159.49, 09/05/03 15:18:38, 0 + 36.984894, -5.584402, 1153.72, 09/05/03 15:18:40, 0 + 36.984658, -5.584466, 1149.39, 09/05/03 15:18:42, 0 + 36.984529, -5.584509, 1146.03, 09/05/03 15:18:43, 0 + 36.984444, -5.584617, 1143.63, 09/05/03 15:18:44, 0 + 36.984122, -5.584917, 1135.94, 09/05/03 15:18:47, 0 + 36.983800, -5.585496, 1129.21, 09/05/03 15:18:51, 0 + 36.983457, -5.586076, 1124.88, 09/05/03 15:18:55, 0 + 36.982770, -5.587149, 1120.07, 09/05/03 15:19:03, 0 + 36.982276, -5.587814, 1116.71, 09/05/03 15:19:08, 0 + 36.982105, -5.588071, 1112.38, 09/05/03 15:19:10, 0 + 36.982019, -5.588200, 1109.02, 09/05/03 15:19:11, 0 + 36.981912, -5.588307, 1103.25, 09/05/03 15:19:12, 0 + 36.981697, -5.588586, 1095.56, 09/05/03 15:19:14, 0 + 36.981504, -5.588844, 1090.75, 09/05/03 15:19:16, 0 + 36.981418, -5.588973, 1086.91, 09/05/03 15:19:17, 0 + 36.981204, -5.589230, 1082.58, 09/05/03 15:19:19, 0 + 36.981032, -5.589488, 1076.33, 09/05/03 15:19:21, 0 + 36.980839, -5.589767, 1071.05, 09/05/03 15:19:23, 0 + 36.980731, -5.589895, 1067.68, 09/05/03 15:19:24, 0 + 36.980560, -5.590153, 1061.43, 09/05/03 15:19:26, 0 + 36.980453, -5.590303, 1057.11, 09/05/03 15:19:27, 0 + 36.980281, -5.590582, 1051.82, 09/05/03 15:19:29, 0 + 36.980088, -5.590861, 1045.57, 09/05/03 15:19:31, 0 + 36.980002, -5.591011, 1041.25, 09/05/03 15:19:32, 0 + 36.979916, -5.591161, 1037.88, 09/05/03 15:19:33, 0 + 36.979744, -5.591440, 1032.11, 09/05/03 15:19:35, 0 + 36.979637, -5.591590, 1028.27, 09/05/03 15:19:36, 0 + 36.979551, -5.591719, 1024.42, 09/05/03 15:19:37, 0 + 36.979380, -5.591998, 1019.62, 09/05/03 15:19:39, 0 + 36.979272, -5.592127, 1016.73, 09/05/03 15:19:40, 0 + 36.979187, -5.592277, 1012.89, 09/05/03 15:19:41, 0 + 36.979079, -5.592406, 1009.52, 09/05/03 15:19:42, 0 + 36.978993, -5.592535, 1004.72, 09/05/03 15:19:43, 0 + 36.978779, -5.592813, 999.91, 09/05/03 15:19:45, 0 + 36.978693, -5.592942, 995.58, 09/05/03 15:19:46, 0 + 36.978607, -5.593071, 991.74, 09/05/03 15:19:47, 0 + 36.978521, -5.593200, 988.85, 09/05/03 15:19:48, 0 + 36.978414, -5.593328, 984.05, 09/05/03 15:19:49, 0 + 36.978328, -5.593479, 981.16, 09/05/03 15:19:50, 0 + 36.978242, -5.593629, 977.32, 09/05/03 15:19:51, 0 + 36.978092, -5.593886, 972.99, 09/05/03 15:19:53, 0 + 36.977813, -5.594294, 967.22, 09/05/03 15:19:56, 0 + 36.977706, -5.594423, 962.42, 09/05/03 15:19:57, 0 + 36.977491, -5.594659, 955.69, 09/05/03 15:19:59, 0 + 36.977384, -5.594788, 952.80, 09/05/03 15:20:00, 0 + 36.977277, -5.594916, 949.44, 09/05/03 15:20:01, 0 + 36.977062, -5.595152, 946.07, 09/05/03 15:20:03, 0 + 36.976826, -5.595367, 942.71, 09/05/03 15:20:05, 0 + 36.976719, -5.595474, 939.83, 09/05/03 15:20:06, 0 + 36.976483, -5.595646, 934.54, 09/05/03 15:20:08, 0 + 36.976225, -5.595796, 929.25, 09/05/03 15:20:10, 0 + 36.976097, -5.595882, 925.89, 09/05/03 15:20:11, 0 + 36.975968, -5.595946, 922.04, 09/05/03 15:20:12, 0 + 36.975710, -5.596097, 917.24, 09/05/03 15:20:14, 0 + 36.975474, -5.596225, 913.39, 09/05/03 15:20:16, 0 + 36.975346, -5.596290, 909.06, 09/05/03 15:20:17, 0 + 36.975217, -5.596354, 905.22, 09/05/03 15:20:18, 0 + 36.974981, -5.596483, 899.93, 09/05/03 15:20:20, 0 + 36.974852, -5.596547, 897.05, 09/05/03 15:20:21, 0 + 36.974595, -5.596654, 890.80, 09/05/03 15:20:23, 0 + 36.974359, -5.596762, 886.95, 09/05/03 15:20:25, 0 + 36.974101, -5.596890, 878.78, 09/05/03 15:20:27, 0 + 36.973972, -5.596933, 875.42, 09/05/03 15:20:28, 0 + 36.973844, -5.596998, 871.09, 09/05/03 15:20:29, 0 + 36.973715, -5.597041, 868.69, 09/05/03 15:20:30, 0 + 36.973307, -5.597105, 862.44, 09/05/03 15:20:33, 0 + 36.973178, -5.597148, 854.75, 09/05/03 15:20:34, 0 + 36.973050, -5.597169, 851.38, 09/05/03 15:20:35, 0 + 36.972921, -5.597191, 846.58, 09/05/03 15:20:36, 0 + 36.972771, -5.597191, 841.77, 09/05/03 15:20:37, 0 + 36.972642, -5.597212, 836.96, 09/05/03 15:20:38, 0 + 36.972384, -5.597234, 831.68, 09/05/03 15:20:40, 0 + 36.972234, -5.597234, 828.31, 09/05/03 15:20:41, 0 + 36.972106, -5.597255, 823.51, 09/05/03 15:20:42, 0 + 36.971977, -5.597277, 820.14, 09/05/03 15:20:43, 0 + 36.971698, -5.597277, 815.34, 09/05/03 15:20:45, 0 + 36.971462, -5.597277, 810.53, 09/05/03 15:20:47, 0 + 36.971226, -5.597255, 806.68, 09/05/03 15:20:49, 0 + 36.971097, -5.597255, 802.36, 09/05/03 15:20:50, 0 + 36.970861, -5.597234, 798.51, 09/05/03 15:20:52, 0 + 36.970732, -5.597234, 794.67, 09/05/03 15:20:53, 0 + 36.970625, -5.597212, 790.82, 09/05/03 15:20:54, 0 + 36.970282, -5.597126, 781.69, 09/05/03 15:20:57, 0 + 36.970046, -5.597062, 776.40, 09/05/03 15:20:59, 0 + 36.969831, -5.596998, 771.11, 09/05/03 15:21:01, 0 + 36.969702, -5.596955, 767.75, 09/05/03 15:21:02, 0 + 36.969466, -5.596912, 763.90, 09/05/03 15:21:04, 0 + 36.969230, -5.596869, 759.10, 09/05/03 15:21:06, 0 + 36.968865, -5.596805, 752.85, 09/05/03 15:21:09, 0 + 36.968479, -5.596783, 747.56, 09/05/03 15:21:12, 0 + 36.968222, -5.596762, 744.20, 09/05/03 15:21:14, 0 + 36.967986, -5.596740, 741.31, 09/05/03 15:21:16, 0 + 36.967535, -5.596676, 736.99, 09/05/03 15:21:20, 0 + 36.967320, -5.596611, 735.07, 09/05/03 15:21:22, 0 + 36.966934, -5.596504, 731.22, 09/05/03 15:21:26, 0 + 36.966419, -5.596611, 727.86, 09/05/03 15:21:30, 0 + 36.965969, -5.597212, 724.01, 09/05/03 15:21:35, 0 + 36.965969, -5.597491, 720.65, 09/05/03 15:21:37, 0 + 36.966076, -5.597663, 715.84, 09/05/03 15:21:40, 0 + 36.966140, -5.597641, 711.99, 09/05/03 15:21:42, 0 + 36.966119, -5.597491, 707.19, 09/05/03 15:21:45, 0 + 36.966012, -5.597363, 702.86, 09/05/03 15:21:47, 0 + 36.965840, -5.597298, 698.53, 09/05/03 15:21:49, 0 + 36.965518, -5.597191, 695.65, 09/05/03 15:21:52, 0 + 36.965411, -5.597148, 693.25, 09/05/03 15:21:53, 0 + 36.964316, -5.597041, 690.36, 09/05/03 15:22:03, 0 + 36.963565, -5.596762, 694.21, 09/05/03 15:22:11, 0 + 36.963394, -5.596569, 699.02, 09/05/03 15:22:14, 0 + 36.963372, -5.596504, 702.38, 09/05/03 15:22:15, 0 + 36.963372, -5.596461, 705.75, 09/05/03 15:22:16, 0 + 36.963458, -5.596461, 710.07, 09/05/03 15:22:18, 0 + 36.963501, -5.596483, 712.95, 09/05/03 15:22:19, 0 + 36.963522, -5.596547, 715.84, 09/05/03 15:22:20, 0 + 36.963544, -5.596976, 722.57, 09/05/03 15:22:24, 0 + 36.963265, -5.597298, 726.41, 09/05/03 15:22:27, 0 + 36.962943, -5.597320, 729.78, 09/05/03 15:22:30, 0 + 36.962814, -5.597234, 733.62, 09/05/03 15:22:32, 0 + 36.962771, -5.597126, 739.39, 09/05/03 15:22:34, 0 + 36.962771, -5.597105, 742.76, 09/05/03 15:22:35, 0 + 36.962771, -5.597105, 744.68, 09/05/03 15:22:36, 0 + 36.962965, -5.597577, 752.37, 09/05/03 15:22:42, 0 + 36.962857, -5.597856, 755.73, 09/05/03 15:22:44, 0 + 36.962686, -5.598092, 760.06, 09/05/03 15:22:46, 0 + 36.962342, -5.598242, 763.90, 09/05/03 15:22:49, 0 + 36.962235, -5.598242, 763.42, 09/05/03 15:22:50, 0 + 36.962020, -5.598071, 767.75, 09/05/03 15:22:53, 0 + 36.961999, -5.597985, 772.08, 09/05/03 15:22:55, 0 + 36.961999, -5.597942, 777.84, 09/05/03 15:22:57, 0 + 36.962106, -5.598006, 783.61, 09/05/03 15:23:01, 0 + 36.962256, -5.598457, 788.90, 09/05/03 15:23:05, 0 + 36.962171, -5.598736, 792.26, 09/05/03 15:23:07, 0 + 36.961999, -5.598972, 795.63, 09/05/03 15:23:09, 0 + 36.961677, -5.599208, 798.99, 09/05/03 15:23:12, 0 + 36.961269, -5.599122, 801.88, 09/05/03 15:23:16, 0 + 36.961184, -5.599036, 808.13, 09/05/03 15:23:18, 0 + 36.961205, -5.598993, 811.97, 09/05/03 15:23:20, 0 + 36.961226, -5.599015, 814.85, 09/05/03 15:23:21, 0 + 36.961269, -5.599036, 818.22, 09/05/03 15:23:23, 0 + 36.961377, -5.599165, 820.14, 09/05/03 15:23:25, 0 + 36.961312, -5.599744, 823.51, 09/05/03 15:23:29, 0 + 36.961141, -5.599937, 825.91, 09/05/03 15:23:31, 0 + 36.960819, -5.600173, 826.87, 09/05/03 15:23:34, 0 + 36.960433, -5.600066, 829.76, 09/05/03 15:23:38, 0 + 36.960390, -5.599980, 834.56, 09/05/03 15:23:40, 0 + 36.960411, -5.599959, 838.89, 09/05/03 15:23:42, 0 + 36.960475, -5.599959, 843.69, 09/05/03 15:23:45, 0 + 36.960518, -5.600002, 843.21, 09/05/03 15:23:46, 0 + 36.960626, -5.600173, 847.06, 09/05/03 15:23:48, 0 + 36.960583, -5.600624, 850.42, 09/05/03 15:23:51, 0 + 36.960411, -5.600882, 852.35, 09/05/03 15:23:53, 0 + 36.960089, -5.601118, 855.23, 09/05/03 15:23:56, 0 + 36.959960, -5.601139, 854.75, 09/05/03 15:23:57, 0 + 36.959617, -5.600989, 856.19, 09/05/03 15:24:01, 0 + 36.959574, -5.600860, 857.63, 09/05/03 15:24:03, 0 + 36.959574, -5.600817, 862.44, 09/05/03 15:24:05, 0 + 36.959660, -5.600817, 866.29, 09/05/03 15:24:08, 0 + 36.959724, -5.601053, 867.73, 09/05/03 15:24:11, 0 + 36.959703, -5.601311, 873.50, 09/05/03 15:24:13, 0 + 36.959660, -5.601439, 873.50, 09/05/03 15:24:14, 0 + 36.959231, -5.602083, 875.90, 09/05/03 15:24:19, 0 + 36.959124, -5.602148, 876.38, 09/05/03 15:24:20, 0 + 36.959016, -5.602212, 877.82, 09/05/03 15:24:21, 0 + 36.958780, -5.602276, 879.26, 09/05/03 15:24:23, 0 + 36.958265, -5.602212, 882.15, 09/05/03 15:24:28, 0 + 36.958179, -5.602019, 886.95, 09/05/03 15:24:32, 0 + 36.958308, -5.602105, 889.84, 09/05/03 15:24:36, 0 + 36.958437, -5.602641, 892.24, 09/05/03 15:24:41, 0 + 36.958308, -5.603092, 897.05, 09/05/03 15:24:44, 0 + 36.958115, -5.603306, 898.01, 09/05/03 15:24:46, 0 + 36.957536, -5.603499, 898.49, 09/05/03 15:24:51, 0 + 36.957257, -5.603285, 900.89, 09/05/03 15:24:56, 0 + 36.957386, -5.603242, 904.26, 09/05/03 15:25:01, 0 + 36.957450, -5.603371, 905.70, 09/05/03 15:25:03, 0 + 36.957364, -5.604036, 906.18, 09/05/03 15:25:08, 0 + 36.956871, -5.604272, 909.06, 09/05/03 15:25:12, 0 + 36.956570, -5.604208, 912.91, 09/05/03 15:25:15, 0 + 36.956463, -5.604079, 916.27, 09/05/03 15:25:18, 0 + 36.956463, -5.603993, 918.20, 09/05/03 15:25:20, 0 + 36.956635, -5.604315, 921.08, 09/05/03 15:25:25, 0 + 36.956527, -5.604851, 923.48, 09/05/03 15:25:29, 0 + 36.955969, -5.605302, 925.89, 09/05/03 15:25:34, 0 + 36.955369, -5.605195, 928.29, 09/05/03 15:25:40, 0 + 36.955347, -5.605066, 932.62, 09/05/03 15:25:43, 0 + 36.955411, -5.605044, 935.98, 09/05/03 15:25:45, 0 + 36.955540, -5.605259, 939.83, 09/05/03 15:25:49, 0 + 36.955540, -5.605388, 942.71, 09/05/03 15:25:50, 0 + 36.955411, -5.606031, 948.00, 09/05/03 15:25:55, 0 + 36.954854, -5.606461, 948.96, 09/05/03 15:26:00, 0 + 36.954231, -5.606332, 951.84, 09/05/03 15:26:06, 0 + 36.954124, -5.606139, 953.28, 09/05/03 15:26:09, 0 + 36.954253, -5.606182, 955.21, 09/05/03 15:26:14, 0 + 36.954274, -5.606267, 956.17, 09/05/03 15:26:15, 0 + 36.954081, -5.606997, 962.42, 09/05/03 15:26:21, 0 + 36.953716, -5.607169, 966.26, 09/05/03 15:26:24, 0 + 36.953502, -5.607147, 970.59, 09/05/03 15:26:26, 0 + 36.953266, -5.606997, 974.91, 09/05/03 15:26:29, 0 + 36.953201, -5.606782, 978.76, 09/05/03 15:26:33, 0 + 36.953351, -5.606847, 982.60, 09/05/03 15:26:37, 0 + 36.953394, -5.606933, 982.60, 09/05/03 15:26:38, 0 + 36.953416, -5.607405, 987.41, 09/05/03 15:26:42, 0 + 36.953287, -5.607791, 991.26, 09/05/03 15:26:45, 0 + 36.952794, -5.608134, 995.58, 09/05/03 15:26:49, 0 + 36.952472, -5.608091, 998.95, 09/05/03 15:26:52, 0 + 36.952236, -5.607877, 1002.31, 09/05/03 15:26:56, 0 + 36.952236, -5.607791, 1003.75, 09/05/03 15:26:58, 0 + 36.952386, -5.607855, 1007.12, 09/05/03 15:27:02, 0 + 36.952386, -5.608199, 1011.93, 09/05/03 15:27:05, 0 + 36.952300, -5.608456, 1015.29, 09/05/03 15:27:07, 0 + 36.952150, -5.608692, 1018.65, 09/05/03 15:27:09, 0 + 36.951892, -5.608864, 1022.02, 09/05/03 15:27:11, 0 + 36.951549, -5.608842, 1024.42, 09/05/03 15:27:14, 0 + 36.951377, -5.608735, 1026.34, 09/05/03 15:27:16, 0 + 36.951270, -5.608649, 1028.75, 09/05/03 15:27:18, 0 + 36.951206, -5.608456, 1030.19, 09/05/03 15:27:21, 0 + 36.951377, -5.608521, 1033.07, 09/05/03 15:27:25, 0 + 36.951420, -5.608606, 1033.07, 09/05/03 15:27:26, 0 + 36.951442, -5.608821, 1035.00, 09/05/03 15:27:28, 0 + 36.951141, -5.609508, 1040.28, 09/05/03 15:27:33, 0 + 36.950798, -5.609701, 1045.09, 09/05/03 15:27:36, 0 + 36.950433, -5.609701, 1046.53, 09/05/03 15:27:39, 0 + 36.950090, -5.609443, 1047.97, 09/05/03 15:27:44, 0 + 36.950154, -5.609357, 1050.38, 09/05/03 15:27:48, 0 + 36.950283, -5.609787, 1048.94, 09/05/03 15:27:53, 0 + 36.950219, -5.610065, 1052.30, 09/05/03 15:27:55, 0 + 36.950176, -5.610173, 1052.30, 09/05/03 15:27:56, 0 + 36.949639, -5.610645, 1052.78, 09/05/03 15:28:01, 0 + 36.949189, -5.610623, 1055.18, 09/05/03 15:28:05, 0 + 36.948888, -5.610323, 1057.59, 09/05/03 15:28:10, 0 + 36.948974, -5.610237, 1058.55, 09/05/03 15:28:14, 0 + 36.949081, -5.610452, 1057.11, 09/05/03 15:28:17, 0 + 36.949103, -5.610709, 1056.15, 09/05/03 15:28:19, 0 + 36.949081, -5.610859, 1053.74, 09/05/03 15:28:20, 0 + 36.949039, -5.611181, 1051.82, 09/05/03 15:28:22, 0 + 36.948888, -5.611589, 1056.63, 09/05/03 15:28:25, 0 + 36.948674, -5.611782, 1060.95, 09/05/03 15:28:27, 0 + 36.948051, -5.611911, 1060.47, 09/05/03 15:28:32, 0 + 36.947644, -5.611567, 1062.39, 09/05/03 15:28:38, 0 + 36.947751, -5.611460, 1063.84, 09/05/03 15:28:43, 0 + 36.947923, -5.611868, 1062.87, 09/05/03 15:28:48, 0 + 36.947880, -5.611997, 1062.39, 09/05/03 15:28:49, 0 + 36.947837, -5.612125, 1063.84, 09/05/03 15:28:50, 0 + 36.947730, -5.612404, 1063.84, 09/05/03 15:28:52, 0 + 36.947086, -5.613005, 1064.80, 09/05/03 15:28:58, 0 + 36.946549, -5.613070, 1066.72, 09/05/03 15:29:02, 0 + 36.946292, -5.612898, 1068.64, 09/05/03 15:29:05, 0 + 36.946228, -5.612555, 1070.08, 09/05/03 15:29:11, 0 + 36.946421, -5.612576, 1068.16, 09/05/03 15:29:16, 0 + 36.946635, -5.613134, 1066.24, 09/05/03 15:29:23, 0 + 36.946614, -5.613370, 1067.20, 09/05/03 15:29:25, 0 + 36.946571, -5.613627, 1069.60, 09/05/03 15:29:27, 0 + 36.945970, -5.614336, 1073.45, 09/05/03 15:29:33, 0 + 36.945584, -5.614443, 1076.81, 09/05/03 15:29:36, 0 + 36.945348, -5.614421, 1078.74, 09/05/03 15:29:38, 0 + 36.944983, -5.614121, 1082.10, 09/05/03 15:29:43, 0 + 36.944940, -5.614057, 1082.10, 09/05/03 15:29:44, 0 + 36.945026, -5.613971, 1084.02, 09/05/03 15:29:49, 0 + 36.945133, -5.614507, 1084.99, 09/05/03 15:29:55, 0 + 36.945112, -5.614636, 1085.47, 09/05/03 15:29:56, 0 + 36.945026, -5.615087, 1084.99, 09/05/03 15:29:59, 0 + 36.944876, -5.615559, 1092.20, 09/05/03 15:30:02, 0 + 36.944790, -5.615838, 1095.56, 09/05/03 15:30:04, 0 + 36.944532, -5.616245, 1102.77, 09/05/03 15:30:07, 0 + 36.944318, -5.616438, 1106.61, 09/05/03 15:30:09, 0 + 36.943932, -5.616567, 1109.98, 09/05/03 15:30:12, 0 + 36.943696, -5.616567, 1113.82, 09/05/03 15:30:14, 0 + 36.943502, -5.616524, 1117.19, 09/05/03 15:30:16, 0 + 36.943288, -5.616331, 1121.03, 09/05/03 15:30:20, 0 + 36.943223, -5.616181, 1124.40, 09/05/03 15:30:23, 0 + 36.943266, -5.616117, 1127.76, 09/05/03 15:30:26, 0 + 36.943331, -5.616159, 1129.21, 09/05/03 15:30:28, 0 + 36.943524, -5.616653, 1132.57, 09/05/03 15:30:34, 0 + 36.943524, -5.616932, 1136.42, 09/05/03 15:30:36, 0 + 36.943438, -5.617232, 1140.26, 09/05/03 15:30:38, 0 + 36.943331, -5.617511, 1144.11, 09/05/03 15:30:40, 0 + 36.943138, -5.617769, 1147.47, 09/05/03 15:30:42, 0 + 36.942923, -5.617962, 1150.84, 09/05/03 15:30:44, 0 + 36.942558, -5.618176, 1155.64, 09/05/03 15:30:47, 0 + 36.942279, -5.618155, 1158.05, 09/05/03 15:30:49, 0 + 36.942065, -5.618048, 1159.49, 09/05/03 15:30:51, 0 + 36.941829, -5.617919, 1166.70, 09/05/03 15:30:54, 0 + 36.941679, -5.617704, 1171.98, 09/05/03 15:30:58, 0 + 36.941614, -5.617533, 1176.79, 09/05/03 15:31:01, 0 + 36.941721, -5.617361, 1177.27, 09/05/03 15:31:10, 0 + 36.941786, -5.617855, 1180.16, 09/05/03 15:31:15, 0 + 36.941700, -5.618091, 1183.52, 09/05/03 15:31:17, 0 + 36.941056, -5.618756, 1184.96, 09/05/03 15:31:23, 0 + 36.940928, -5.618777, 1184.96, 09/05/03 15:31:24, 0 + 36.940799, -5.618799, 1186.40, 09/05/03 15:31:25, 0 + 36.940413, -5.618842, 1188.81, 09/05/03 15:31:28, 0 + 36.939962, -5.618563, 1193.61, 09/05/03 15:31:33, 0 + 36.939898, -5.618284, 1197.46, 09/05/03 15:31:37, 0 + 36.940112, -5.618176, 1195.06, 09/05/03 15:31:44, 0 + 36.940284, -5.618520, 1198.42, 09/05/03 15:31:49, 0 + 36.940305, -5.618734, 1200.82, 09/05/03 15:31:51, 0 + 36.940284, -5.618992, 1205.15, 09/05/03 15:31:53, 0 + 36.940112, -5.619357, 1206.59, 09/05/03 15:31:56, 0 + 36.939898, -5.619700, 1209.00, 09/05/03 15:31:59, 0 + 36.939211, -5.620151, 1213.32, 09/05/03 15:32:05, 0 + 36.938503, -5.619957, 1217.65, 09/05/03 15:32:12, 0 + 36.938353, -5.619721, 1222.45, 09/05/03 15:32:15, 0 + 36.938331, -5.619314, 1224.38, 09/05/03 15:32:22, 0 + 36.938567, -5.619507, 1226.30, 09/05/03 15:32:28, 0 + 36.938610, -5.619872, 1230.14, 09/05/03 15:32:31, 0 + 36.938610, -5.620108, 1233.99, 09/05/03 15:32:33, 0 + 36.938567, -5.620494, 1237.35, 09/05/03 15:32:36, 0 + 36.938267, -5.621052, 1240.24, 09/05/03 15:32:40, 0 + 36.938052, -5.621181, 1241.68, 09/05/03 15:32:42, 0 + 36.937795, -5.621309, 1243.12, 09/05/03 15:32:44, 0 + 36.937344, -5.621223, 1242.64, 09/05/03 15:32:48, 0 + 36.937172, -5.621138, 1243.60, 09/05/03 15:32:50, 0 + 36.937044, -5.620751, 1243.60, 09/05/03 15:32:56, 0 + 36.937280, -5.620837, 1243.12, 09/05/03 15:33:03, 0 + 36.937215, -5.621567, 1245.53, 09/05/03 15:33:09, 0 + 36.936915, -5.622039, 1248.89, 09/05/03 15:33:13, 0 + 36.936271, -5.622489, 1248.41, 09/05/03 15:33:19, 0 + 36.935670, -5.623176, 1243.60, 09/05/03 15:33:26, 0 + 36.935692, -5.623519, 1240.72, 09/05/03 15:33:29, 0 + 36.935778, -5.623648, 1245.53, 09/05/03 15:33:32, 0 + 36.935778, -5.623519, 1248.41, 09/05/03 15:33:36, 0 + 36.935434, -5.623240, 1248.41, 09/05/03 15:33:41, 0 + 36.934876, -5.623498, 1250.33, 09/05/03 15:33:46, 0 + 36.934791, -5.623605, 1250.33, 09/05/03 15:33:47, 0 + 36.934597, -5.624421, 1250.81, 09/05/03 15:33:53, 0 + 36.934705, -5.624700, 1253.70, 09/05/03 15:33:56, 0 + 36.934769, -5.624785, 1258.02, 09/05/03 15:33:58, 0 + 36.934812, -5.624785, 1258.02, 09/05/03 15:33:59, 0 + 36.934834, -5.624571, 1260.91, 09/05/03 15:34:04, 0 + 36.934597, -5.624442, 1264.27, 09/05/03 15:34:07, 0 + 36.934254, -5.624421, 1268.12, 09/05/03 15:34:10, 0 + 36.933825, -5.624785, 1271.48, 09/05/03 15:34:14, 0 + 36.933610, -5.625193, 1273.88, 09/05/03 15:34:17, 0 + 36.933632, -5.625730, 1274.36, 09/05/03 15:34:21, 0 + 36.933782, -5.625858, 1279.65, 09/05/03 15:34:24, 0 + 36.933804, -5.625858, 1284.94, 09/05/03 15:34:25, 0 + 36.933868, -5.625815, 1288.30, 09/05/03 15:34:27, 0 + 36.933868, -5.625730, 1291.67, 09/05/03 15:34:29, 0 + 36.933696, -5.625558, 1295.03, 09/05/03 15:34:32, 0 + 36.933374, -5.625494, 1299.36, 09/05/03 15:34:35, 0 + 36.933031, -5.625665, 1302.72, 09/05/03 15:34:38, 0 + 36.932623, -5.626073, 1307.05, 09/05/03 15:34:42, 0 + 36.932538, -5.626202, 1307.53, 09/05/03 15:34:43, 0 + 36.932409, -5.626459, 1308.97, 09/05/03 15:34:45, 0 + 36.932387, -5.627296, 1311.38, 09/05/03 15:34:51, 0 + 36.932473, -5.627489, 1316.18, 09/05/03 15:34:53, 0 + 36.932559, -5.627575, 1319.55, 09/05/03 15:34:55, 0 + 36.932645, -5.627575, 1323.39, 09/05/03 15:34:57, 0 + 36.932623, -5.627403, 1327.72, 09/05/03 15:35:00, 0 + 36.932516, -5.627317, 1330.12, 09/05/03 15:35:02, 0 + 36.932259, -5.627189, 1332.52, 09/05/03 15:35:05, 0 + 36.931658, -5.627317, 1337.81, 09/05/03 15:35:10, 0 + 36.931529, -5.627382, 1337.81, 09/05/03 15:35:11, 0 + 36.931314, -5.627596, 1340.22, 09/05/03 15:35:13, 0 + 36.931143, -5.628176, 1342.62, 09/05/03 15:35:17, 0 + 36.931314, -5.628755, 1346.94, 09/05/03 15:35:22, 0 + 36.931422, -5.628841, 1350.79, 09/05/03 15:35:24, 0 + 36.931508, -5.628884, 1354.63, 09/05/03 15:35:26, 0 + 36.931572, -5.628884, 1359.44, 09/05/03 15:35:28, 0 + 36.931551, -5.628755, 1360.88, 09/05/03 15:35:31, 0 + 36.931121, -5.628455, 1360.40, 09/05/03 15:35:36, 0 + 36.930735, -5.628476, 1366.17, 09/05/03 15:35:39, 0 + 36.930392, -5.628734, 1368.09, 09/05/03 15:35:42, 0 + 36.930070, -5.629570, 1370.02, 09/05/03 15:35:48, 0 + 36.930177, -5.629914, 1373.38, 09/05/03 15:35:51, 0 + 36.930306, -5.630128, 1377.71, 09/05/03 15:35:54, 0 + 36.930456, -5.630085, 1380.59, 09/05/03 15:36:00, 0 + 36.930478, -5.630043, 1380.59, 09/05/03 15:36:01, 0 + 36.930499, -5.629935, 1382.03, 09/05/03 15:36:03, 0 + 36.930285, -5.629785, 1385.40, 09/05/03 15:36:06, 0 + 36.929963, -5.629871, 1389.72, 09/05/03 15:36:09, 0 + 36.929491, -5.630407, 1392.13, 09/05/03 15:36:14, 0 + 36.929491, -5.631094, 1395.49, 09/05/03 15:36:19, 0 + 36.929641, -5.631287, 1398.86, 09/05/03 15:36:22, 0 + 36.929748, -5.631287, 1403.18, 09/05/03 15:36:24, 0 + 36.929770, -5.631201, 1406.55, 09/05/03 15:36:26, 0 + 36.929748, -5.631073, 1411.35, 09/05/03 15:36:28, 0 + 36.929512, -5.630858, 1414.72, 09/05/03 15:36:32, 0 + 36.929233, -5.630815, 1419.52, 09/05/03 15:36:35, 0 + 36.928890, -5.630879, 1422.41, 09/05/03 15:36:38, 0 + 36.928525, -5.631073, 1425.29, 09/05/03 15:36:41, 0 + 36.928096, -5.631523, 1430.10, 09/05/03 15:36:45, 0 + 36.927903, -5.632102, 1432.98, 09/05/03 15:36:49, 0 + 36.927946, -5.632617, 1437.79, 09/05/03 15:36:53, 0 + 36.928031, -5.632789, 1439.23, 09/05/03 15:36:55, 0 + 36.928182, -5.632875, 1443.56, 09/05/03 15:36:58, 0 + 36.928203, -5.632811, 1446.92, 09/05/03 15:37:00, 0 + 36.928203, -5.632682, 1451.25, 09/05/03 15:37:02, 0 + 36.928096, -5.632575, 1456.05, 09/05/03 15:37:04, 0 + 36.927924, -5.632467, 1459.42, 09/05/03 15:37:06, 0 + 36.927710, -5.632424, 1463.74, 09/05/03 15:37:08, 0 + 36.927366, -5.632553, 1466.15, 09/05/03 15:37:11, 0 + 36.926851, -5.633283, 1468.55, 09/05/03 15:37:17, 0 + 36.926851, -5.633690, 1472.40, 09/05/03 15:37:20, 0 + 36.927023, -5.634077, 1476.72, 09/05/03 15:37:24, 0 + 36.927130, -5.634055, 1480.57, 09/05/03 15:37:27, 0 + 36.927152, -5.634012, 1483.93, 09/05/03 15:37:28, 0 + 36.927152, -5.633905, 1487.30, 09/05/03 15:37:30, 0 + 36.926894, -5.633647, 1491.62, 09/05/03 15:37:34, 0 + 36.926701, -5.633626, 1495.47, 09/05/03 15:37:36, 0 + 36.926143, -5.633991, 1495.95, 09/05/03 15:37:41, 0 + 36.925950, -5.634742, 1496.43, 09/05/03 15:37:46, 0 + 36.926186, -5.635235, 1500.27, 09/05/03 15:37:51, 0 + 36.926272, -5.635278, 1504.60, 09/05/03 15:37:53, 0 + 36.926336, -5.635214, 1508.45, 09/05/03 15:37:55, 0 + 36.926315, -5.635042, 1512.77, 09/05/03 15:37:58, 0 + 36.926122, -5.634871, 1516.62, 09/05/03 15:38:01, 0 + 36.925929, -5.634849, 1519.98, 09/05/03 15:38:03, 0 + 36.925714, -5.634913, 1521.42, 09/05/03 15:38:05, 0 + 36.925220, -5.635450, 1520.94, 09/05/03 15:38:10, 0 + 36.925092, -5.636072, 1517.10, 09/05/03 15:38:14, 0 + 36.925220, -5.636458, 1515.66, 09/05/03 15:38:17, 0 + 36.925457, -5.636630, 1519.50, 09/05/03 15:38:21, 0 + 36.925564, -5.636544, 1523.35, 09/05/03 15:38:24, 0 + 36.925521, -5.636415, 1526.23, 09/05/03 15:38:26, 0 + 36.925414, -5.636351, 1530.08, 09/05/03 15:38:28, 0 + 36.925328, -5.636330, 1530.08, 09/05/03 15:38:29, 0 + 36.925220, -5.636330, 1530.08, 09/05/03 15:38:30, 0 + 36.924491, -5.636780, 1528.63, 09/05/03 15:38:37, 0 + 36.924298, -5.637231, 1525.75, 09/05/03 15:38:40, 0 + 36.924341, -5.637960, 1529.59, 09/05/03 15:38:45, 0 + 36.924491, -5.638218, 1531.04, 09/05/03 15:38:48, 0 + 36.924620, -5.638154, 1533.44, 09/05/03 15:38:53, 0 + 36.924405, -5.637875, 1533.44, 09/05/03 15:38:58, 0 + 36.924191, -5.637918, 1533.92, 09/05/03 15:39:00, 0 + 36.923997, -5.638003, 1534.88, 09/05/03 15:39:02, 0 + 36.923547, -5.638604, 1533.44, 09/05/03 15:39:07, 0 + 36.923504, -5.638754, 1533.44, 09/05/03 15:39:08, 0 + 36.923440, -5.639033, 1537.29, 09/05/03 15:39:10, 0 + 36.923568, -5.639548, 1536.32, 09/05/03 15:39:15, 0 + 36.923761, -5.639527, 1535.36, 09/05/03 15:39:21, 0 + 36.923504, -5.639226, 1535.36, 09/05/03 15:39:26, 0 + 36.923332, -5.639184, 1534.88, 09/05/03 15:39:28, 0 + 36.923118, -5.639119, 1534.88, 09/05/03 15:39:30, 0 + 36.922946, -5.639119, 1535.36, 09/05/03 15:39:32, 0 + 36.922517, -5.639205, 1535.36, 09/05/03 15:39:36, 0 + 36.921766, -5.639827, 1536.32, 09/05/03 15:39:43, 0 + 36.921508, -5.640771, 1537.29, 09/05/03 15:39:49, 0 + 36.921744, -5.641501, 1536.32, 09/05/03 15:39:55, 0 + 36.921873, -5.641565, 1534.88, 09/05/03 15:39:57, 0 + 36.921959, -5.641479, 1532.00, 09/05/03 15:40:00, 0 + 36.921916, -5.641308, 1528.63, 09/05/03 15:40:03, 0 + 36.921873, -5.641243, 1528.63, 09/05/03 15:40:04, 0 + 36.921594, -5.641050, 1525.27, 09/05/03 15:40:08, 0 + 36.921380, -5.641072, 1520.94, 09/05/03 15:40:10, 0 + 36.921251, -5.641115, 1521.42, 09/05/03 15:40:11, 0 + 36.920929, -5.641351, 1524.31, 09/05/03 15:40:14, 0 + 36.920822, -5.641458, 1525.27, 09/05/03 15:40:15, 0 + 36.920457, -5.642488, 1525.27, 09/05/03 15:40:22, 0 + 36.920714, -5.643089, 1525.27, 09/05/03 15:40:28, 0 + 36.920972, -5.643046, 1524.31, 09/05/03 15:40:34, 0 + 36.920886, -5.642831, 1520.94, 09/05/03 15:40:38, 0 + 36.920414, -5.642745, 1517.58, 09/05/03 15:40:43, 0 + 36.920178, -5.642831, 1516.62, 09/05/03 15:40:45, 0 + 36.919556, -5.643454, 1517.58, 09/05/03 15:40:51, 0 + 36.919427, -5.643926, 1515.18, 09/05/03 15:40:54, 0 + 36.919513, -5.644805, 1514.21, 09/05/03 15:41:00, 0 + 36.919770, -5.645106, 1513.73, 09/05/03 15:41:05, 0 + 36.919920, -5.644977, 1511.33, 09/05/03 15:41:10, 0 + 36.919577, -5.644698, 1510.37, 09/05/03 15:41:16, 0 + 36.919384, -5.644698, 1510.85, 09/05/03 15:41:18, 0 + 36.919041, -5.644741, 1507.48, 09/05/03 15:41:21, 0 + 36.918590, -5.645041, 1504.12, 09/05/03 15:41:25, 0 + 36.917646, -5.646007, 1500.76, 09/05/03 15:41:34, 0 + 36.917324, -5.646393, 1496.43, 09/05/03 15:41:37, 0 + 36.916251, -5.647917, 1492.58, 09/05/03 15:41:48, 0 + 36.915586, -5.649312, 1489.22, 09/05/03 15:41:57, 0 + 36.915500, -5.649655, 1488.26, 09/05/03 15:41:59, 0 + 36.915565, -5.650342, 1486.82, 09/05/03 15:42:04, 0 + 36.915629, -5.650535, 1486.82, 09/05/03 15:42:06, 0 + 36.915779, -5.650706, 1482.49, 09/05/03 15:42:10, 0 + 36.915822, -5.650706, 1478.65, 09/05/03 15:42:12, 0 + 36.915886, -5.650642, 1473.36, 09/05/03 15:42:14, 0 + 36.915908, -5.650599, 1469.99, 09/05/03 15:42:15, 0 + 36.915929, -5.650449, 1466.15, 09/05/03 15:42:18, 0 + 36.915801, -5.650213, 1463.26, 09/05/03 15:42:22, 0 + 36.915693, -5.650084, 1462.30, 09/05/03 15:42:24, 0 + 36.915479, -5.649977, 1466.15, 09/05/03 15:42:27, 0 + 36.915414, -5.649977, 1466.15, 09/05/03 15:42:28, 0 + 36.915350, -5.649955, 1466.15, 09/05/03 15:42:29, 0 + 36.915157, -5.649912, 1463.74, 09/05/03 15:42:31, 0 + 36.914492, -5.649977, 1460.38, 09/05/03 15:42:37, 0 + 36.913998, -5.650213, 1455.09, 09/05/03 15:42:41, 0 + 36.913869, -5.650277, 1454.61, 09/05/03 15:42:42, 0 + 36.913655, -5.650492, 1453.65, 09/05/03 15:42:44, 0 + 36.913440, -5.650771, 1449.32, 09/05/03 15:42:46, 0 + 36.913269, -5.651050, 1445.00, 09/05/03 15:42:48, 0 + 36.913140, -5.651350, 1441.15, 09/05/03 15:42:50, 0 + 36.913033, -5.651672, 1438.27, 09/05/03 15:42:52, 0 + 36.912990, -5.651844, 1438.27, 09/05/03 15:42:53, 0 + 36.912947, -5.652316, 1434.42, 09/05/03 15:42:56, 0 + 36.913033, -5.652659, 1429.14, 09/05/03 15:42:59, 0 + 36.913118, -5.652831, 1426.25, 09/05/03 15:43:01, 0 + 36.913226, -5.652895, 1422.89, 09/05/03 15:43:04, 0 + 36.913247, -5.652766, 1418.56, 09/05/03 15:43:08, 0 + 36.913161, -5.652659, 1412.79, 09/05/03 15:43:10, 0 + 36.913011, -5.652595, 1409.91, 09/05/03 15:43:12, 0 + 36.912689, -5.652595, 1407.03, 09/05/03 15:43:15, 0 + 36.912453, -5.652702, 1403.66, 09/05/03 15:43:17, 0 + 36.912217, -5.652874, 1403.18, 09/05/03 15:43:19, 0 + 36.911874, -5.653152, 1398.86, 09/05/03 15:43:22, 0 + 36.911445, -5.653603, 1394.53, 09/05/03 15:43:26, 0 + 36.911209, -5.653839, 1390.20, 09/05/03 15:43:28, 0 + 36.910973, -5.654075, 1389.24, 09/05/03 15:43:30, 0 + 36.910651, -5.654418, 1383.96, 09/05/03 15:43:33, 0 + 36.910393, -5.654676, 1379.15, 09/05/03 15:43:35, 0 + 36.910050, -5.654998, 1376.26, 09/05/03 15:43:38, 0 + 36.909814, -5.655212, 1371.46, 09/05/03 15:43:40, 0 + 36.909556, -5.655427, 1367.61, 09/05/03 15:43:42, 0 + 36.909320, -5.655642, 1364.73, 09/05/03 15:43:44, 0 + 36.908956, -5.655985, 1358.48, 09/05/03 15:43:47, 0 + 36.908698, -5.656221, 1353.67, 09/05/03 15:43:49, 0 + 36.908441, -5.656457, 1350.31, 09/05/03 15:43:51, 0 + 36.908290, -5.656672, 1345.50, 09/05/03 15:43:53, 0 + 36.907904, -5.657015, 1338.29, 09/05/03 15:43:56, 0 + 36.907775, -5.657144, 1338.77, 09/05/03 15:43:57, 0 + 36.907496, -5.657444, 1334.45, 09/05/03 15:44:00, 0 + 36.907411, -5.657573, 1334.45, 09/05/03 15:44:01, 0 + 36.907303, -5.657680, 1329.64, 09/05/03 15:44:02, 0 + 36.907003, -5.658002, 1325.80, 09/05/03 15:44:05, 0 + 36.906788, -5.658216, 1321.95, 09/05/03 15:44:07, 0 + 36.906703, -5.658324, 1318.10, 09/05/03 15:44:08, 0 + 36.906595, -5.658431, 1316.18, 09/05/03 15:44:09, 0 + 36.906359, -5.658753, 1309.93, 09/05/03 15:44:12, 0 + 36.906188, -5.658967, 1304.65, 09/05/03 15:44:14, 0 + 36.906123, -5.659075, 1299.36, 09/05/03 15:44:15, 0 + 36.905930, -5.659289, 1297.92, 09/05/03 15:44:17, 0 + 36.905673, -5.659482, 1294.07, 09/05/03 15:44:19, 0 + 36.905437, -5.659697, 1289.75, 09/05/03 15:44:21, 0 + 36.905308, -5.659804, 1287.82, 09/05/03 15:44:22, 0 + 36.905286, -5.659826, 1296.48, 09/05/03 16:39:44, 1 + 36.905286, -5.659826, 188.56, 09/05/03 16:39:45, 0 + 36.905286, -5.659826, 188.08, 09/05/03 16:39:47, 0 + 36.761112, -5.836186, 189.52, 09/05/03 16:39:56, 1 + 36.761112, -5.836186, 186.15, 09/05/03 16:40:01, 0 + 36.761112, -5.836208, 182.79, 09/05/03 16:40:04, 0 + 36.761112, -5.836186, 179.42, 09/05/03 16:40:07, 0 + 36.761112, -5.836186, 176.54, 09/05/03 16:40:11, 0 + 36.761112, -5.836186, 174.14, 09/05/03 16:40:15, 0 + 36.761112, -5.836165, 170.77, 09/05/03 16:40:21, 0 + 36.761112, -5.836165, 168.37, 09/05/03 16:40:26, 0 + 36.761112, -5.836165, 164.52, 09/05/03 16:40:37, 0 + 36.761112, -5.836165, 160.68, 09/05/03 16:40:59, 0 + 36.761112, -5.836186, 159.72, 09/05/03 16:42:18, 0 + 36.761091, -5.836165, 161.16, 09/05/03 16:44:12, 0 diff --git a/reference/track/simpletrack.gpx b/reference/track/simpletrack.gpx new file mode 100644 index 000000000..7e760af8e --- /dev/null +++ b/reference/track/simpletrack.gpx @@ -0,0 +1,21 @@ + + + + + + +1.000000 + + + +0.000000 + + + + + diff --git a/reference/track/sportsim-sample.txt b/reference/track/sportsim-sample.txt new file mode 100644 index 000000000..8ec28aac5 --- /dev/null +++ b/reference/track/sportsim-sample.txt @@ -0,0 +1,66 @@ +SportsimVersion:01 +#Sportsim TrackFile +00000;0;30.062183;-91.610350;3;1022346381; +00001;0;30.062783;-91.610567;-328083987;1022346595; +00002;0;30.062700;-91.608267;-328083987;1022346720; +00003;0;30.062333;-91.607383;-328083987;1022346768; +00004;0;30.061533;-91.605283;-328083987;1022346881; +00005;0;30.059783;-91.599400;-328083987;1022347036; +00006;0;30.057800;-91.596683;-328083987;1022347066; +00007;0;30.055383;-91.594900;-328083987;1022347100; +00008;0;30.053883;-91.592617;-328083987;1022347141; +00009;0;30.049733;-91.589750;-328083987;1022347246; +00010;0;30.049017;-91.589883;-328083987;1022347270; +00011;0;30.048800;-91.592933;-328083987;1022347311; +00012;0;30.046233;-91.596450;-328083987;1022347355; +00013;0;30.045517;-91.598717;-328083987;1022347388; +00014;0;30.047300;-91.600267;-328083987;1022349863; +00015;0;30.047000;-91.599633;7;1022349964; +00016;0;30.046433;-91.599467;-328083987;1022350026; +00017;0;30.046200;-91.598950;3;1022350098; +00018;0;30.046367;-91.597733;-328083987;1022350220; +00019;0;30.046350;-91.597167;-328083987;1022350269; +00020;0;30.046783;-91.596333;-328083987;1022350338; +00021;0;30.047450;-91.595200;-328083987;1022350462; +00022;0;30.047800;-91.594767;7;1022350504; +00023;0;30.048250;-91.594083;3;1022350574; +00024;0;30.048683;-91.593800;3;1022350621; +00025;0;30.049350;-91.593850;-328083987;1022350687; +00026;0;30.050317;-91.593983;7;1022350791; +00027;0;30.050783;-91.594117;-328083987;1022350839; +00028;0;30.051233;-91.594367;-328083987;1022350884; +00029;0;30.051800;-91.594367;-328083987;1022350937; +00030;0;30.052217;-91.594667;-328083987;1022350998; +00031;0;30.053017;-91.594683;-328083987;1022351077; +00032;0;30.054867;-91.595200;20;1022351293; +00033;0;30.053733;-91.594933;7;1022351496; +00034;0;30.053183;-91.594783;-328083987;1022351576; +00035;0;30.052633;-91.594833;-328083987;1022351642; +00036;0;30.052450;-91.595433;-328083987;1022351763; +00037;0;30.052483;-91.595967;-328083987;1022351808; +00038;0;30.052650;-91.596783;3;1022351872; +00039;0;30.053133;-91.597850;-328083987;1022351958; +00040;0;30.053617;-91.597967;-328083987;1022352015; +00041;0;30.053967;-91.597767;20;1022352085; +00042;0;30.053617;-91.598083;-328083987;1022352157; +00043;0;30.053200;-91.597917;-328083987;1022352241; +00044;0;30.052817;-91.597517;-328083987;1022352353; +00045;0;30.052567;-91.596933;-328083987;1022352414; +00046;0;30.052333;-91.596433;-328083987;1022352462; +00047;0;30.052250;-91.595683;-328083987;1022352521; +00048;0;30.052217;-91.595017;-328083987;1022352592; +00049;0;30.051883;-91.594700;-328083987;1022352649; +00050;0;30.051050;-91.594400;-328083987;1022352734; +00051;0;30.050567;-91.594233;-328083987;1022352776; +00052;0;30.050183;-91.594100;-328083987;1022352818; +00053;0;30.049100;-91.593717;-328083987;1022352911; +00054;0;30.048450;-91.594250;-328083987;1022352992; +00055;0;30.048083;-91.594750;-328083987;1022353044; +00056;0;30.047500;-91.595450;23;1022353120; +00057;0;30.047067;-91.596000;-328083987;1022353168; +00058;0;30.046633;-91.596600;-328083987;1022353222; +00059;0;30.046400;-91.597650;-328083987;1022353301; +00060;0;30.046233;-91.598467;-328083987;1022353368; +00061;0;30.046317;-91.598967;-328083987;1022353423; +00062;0;30.046783;-91.599283;-328083987;1022353489; +00063;0;30.047133;-91.599667;-328083987;1022353557; diff --git a/reference/track/stmsdf-track.sdf b/reference/track/stmsdf-track.sdf new file mode 100644 index 000000000..742ab4964 --- /dev/null +++ b/reference/track/stmsdf-track.sdf @@ -0,0 +1,99 @@ +[HEADER] +FILEVERSION=1 +SOURCE=FILE +DATUM=WGS84 +TYPE=28 +NAME=ACTIVE LOG 006 +MINALT=130 +MAXALT=161 +MAXSPEED=3.16 +DISTANCE=653 +DURATION=1989 +DATE=01.05.2005 15:02.47 +AVGSPEED=0.33 +[POINTS] +"TP",01.05.2005,15:02.47,51.312938,12.413165,161,0.00,0.0,0 +"TP",01.05.2005,15:03.25,51.312883,12.413248,154,0.06,137.0,8.478119 +"TP",01.05.2005,15:03.39,51.312855,12.413248,148,0.06,180.0,11.566578 +"TP",01.05.2005,15:04.16,51.312827,12.413304,139,0.04,129.0,16.521235 +"TP",01.05.2005,15:05.02,51.312827,12.413276,145,0.02,270.0,18.457564 +"TP",01.05.2005,15:05.45,51.312827,12.413304,134,0.02,90.0,20.393893 +"TP",01.05.2005,15:06.44,51.312772,12.413332,131,0.03,163.0,26.865457 +"TP",01.05.2005,15:07.50,51.312772,12.413332,130,0.00,0.0,26.865457 +"TP",01.05.2005,15:08.19,51.312744,12.413332,132,0.03,180.0,29.963246 +"TP",01.05.2005,15:11.16,51.312799,12.413304,144,0.01,343.0,36.443717 +"TP",01.05.2005,15:12.34,51.312911,12.413443,147,0.05,38.0,52.143218 +"TP",01.05.2005,15:13.18,51.312994,12.413804,145,0.15,70.0,78.925927 +"TP",01.05.2005,15:13.27,51.313049,12.413804,145,0.15,0.0,85.112175 +"TP",01.05.2005,15:13.37,51.313049,12.413832,135,0.05,90.0,87.042662 +"TP",01.05.2005,15:13.46,51.313105,12.413832,135,0.15,0.0,93.219581 +"TP",01.05.2005,15:14.03,51.313216,12.413887,136,0.23,17.0,106.182252 +"TP",01.05.2005,15:14.16,51.313299,12.413971,135,0.23,32.0,117.119734 +"TP",01.05.2005,15:14.26,51.313272,12.414054,139,0.15,118.0,123.688361 +"TP",01.05.2005,15:14.30,51.313272,12.414110,139,0.23,90.0,127.555149 +"TP",01.05.2005,15:15.06,51.313049,12.414610,141,0.31,125.0,170.241955 +"TP",01.05.2005,15:15.27,51.312966,12.414832,140,0.23,121.0,188.281604 +"TP",01.05.2005,15:15.39,51.312911,12.414943,140,0.23,129.0,198.174693 +"TP",01.05.2005,15:25.31,51.312938,12.414971,152,0.00,32.0,201.819955 +"TP",01.05.2005,15:25.40,51.312938,12.414971,152,0.00,0.0,201.819955 +"TP",01.05.2005,15:29.18,51.312966,12.414943,155,0.01,328.0,205.465216 +"TP",01.05.2005,15:30.30,51.313160,12.414582,149,0.15,311.0,238.629832 +"TP",01.05.2005,15:30.37,51.313160,12.414554,150,0.08,270.0,240.560315 +"TP",01.05.2005,15:30.47,51.313160,12.414443,151,0.23,270.0,248.293911 +"TP",01.05.2005,15:30.48,51.313160,12.414387,151,1.08,270.0,252.160708 +"TP",01.05.2005,15:30.52,51.313327,12.413915,150,2.62,299.0,289.898474 +"TP",01.05.2005,15:30.57,51.313688,12.413332,150,3.16,315.0,347.021422 +"TP",01.05.2005,15:31.03,51.313994,12.412860,150,2.16,316.0,394.311899 +"TP",01.05.2005,15:31.10,51.314216,12.412498,150,1.39,315.0,429.569729 +"TP",01.05.2005,15:32.38,51.314633,12.409554,143,0.69,283.0,639.630841 +"TP",01.05.2005,15:32.45,51.314633,12.409499,141,0.15,270.0,643.491682 +"TP",01.05.2005,15:33.17,51.314633,12.409499,143,0.00,0.0,643.491682 +"TP",01.05.2005,15:33.42,51.314633,12.409443,139,0.05,270.0,647.358356 +"TP",01.05.2005,15:33.54,51.314633,12.409360,139,0.15,270.0,653.161283 +"TP",01.05.2005,15:34.04,51.314633,12.409360,138,0.00,0.0,653.161283 +"TP",01.05.2005,15:34.20,51.314633,12.409360,139,0.00,0.0,653.161283 +"TP",01.05.2005,15:35.45,51.314633,12.409360,144,0.00,0.0,653.161283 +"TP",01.05.2005,15:35.56,51.314633,12.409360,145,0.00,0.0,653.161283 +[CUSTOM1] +0,161 +38,154 +52,148 +89,139 +135,145 +178,134 +237,131 +303,130 +332,132 +509,144 +587,147 +631,145 +640,145 +650,135 +659,135 +676,136 +689,135 +699,139 +703,139 +739,141 +760,140 +772,140 +1364,152 +1373,152 +1591,155 +1663,149 +1670,150 +1680,151 +1681,151 +1685,150 +1690,150 +1696,150 +1703,150 +1791,143 +1798,141 +1830,143 +1855,139 +1867,139 +1877,138 +1893,139 +1978,144 +1989,145 diff --git a/reference/track/stmwpp-route.gpx b/reference/track/stmwpp-route.gpx new file mode 100644 index 000000000..92d4ec849 --- /dev/null +++ b/reference/track/stmwpp-route.gpx @@ -0,0 +1,64 @@ + + + + + + + NARVA + NARVA + NARVA + + + + Liebknechtstras + Liebknechtstras + Liebknechtstras + + + + Jahnstrasse11 + Jahnstrasse11 + Jahnstrasse11 + + + + Elsterberg + Elsterberg + Elsterberg + + + + Greiz + Greiz + Greiz + + + + Gosel + Gosel + Gosel + + + + 3 + 3 + 3 + + + + Altenburg-Umgehung + Altenburg-Umgehung + Altenburg-Umgehung + + + + Völkerschlachtdenkmal + Völkerschlachtdenkmal + Völkerschlachtdenkmal + + diff --git a/reference/track/stmwpp-track.gpx b/reference/track/stmwpp-track.gpx new file mode 100644 index 000000000..ae1454d38 --- /dev/null +++ b/reference/track/stmwpp-track.gpx @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/track/stmwpp-track.txt b/reference/track/stmwpp-track.txt new file mode 100644 index 000000000..fda1fa51d --- /dev/null +++ b/reference/track/stmwpp-track.txt @@ -0,0 +1,54 @@ +Datum,WGS 84,WGS 84,0,0,0,0,0 +TP,D,45.187113,4.6607297,08/23/2005,15:25:12.812, +TP,D,45.1868455,4.660163,08/23/2005,15:25:22.822, +TP,D,45.1863955,4.6599324,08/23/2005,15:25:39.839, +TP,D,45.1859246,4.6598826,08/23/2005,15:25:58.858, +TP,D,45.185478,4.6597676,08/23/2005,15:26:16.816, +TP,D,45.1850178,4.6597388,08/23/2005,15:26:33.833, +TP,D,45.1845797,4.6596044,08/23/2005,15:26:53.853, +TP,D,45.1841254,4.6596267,08/23/2005,15:27:09.89, +TP,D,45.1836672,4.6595521,08/23/2005,15:27:28.828, +TP,D,45.1836814,4.6588984,08/23/2005,15:28:02.82, +TP,D,45.183994,4.6584016,08/23/2005,15:28:15.815, +TP,D,45.1846076,4.657295,08/23/2005,15:28:30.830, +TP,D,45.1850065,4.6558776,08/23/2005,15:28:44.844, +TP,D,45.1845094,4.6552681,08/23/2005,15:28:54.854, +TP,D,45.1839276,4.6546767,08/23/2005,15:29:04.84, +TP,D,45.1834919,4.6543834,08/23/2005,15:29:16.816, +TP,D,45.1835007,4.6537414,08/23/2005,15:29:26.826, +TP,D,45.1833348,4.6531515,08/23/2005,15:29:42.842, +TP,D,45.1830662,4.6526252,08/23/2005,15:29:59.859, +TP,D,45.1830017,4.6519839,08/23/2005,15:30:15.815, +TP,D,45.1829897,4.6513269,08/23/2005,15:30:32.832, +TP,D,45.1829101,4.6506828,08/23/2005,15:30:44.844, +TP,D,45.1825391,4.6502882,08/23/2005,15:30:56.856, +TP,D,45.1821259,4.6499932,08/23/2005,15:31:14.814, +TP,D,45.1817943,4.6495713,08/23/2005,15:31:31.831, +TP,D,45.1816251,4.6489743,08/23/2005,15:31:50.850, +TP,D,45.1815118,4.6483493,08/23/2005,15:32:13.813, +TP,D,45.1812957,4.647775,08/23/2005,15:32:34.834, +TP,D,45.181057,4.6472012,08/23/2005,15:32:56.856, +TP,D,45.1807201,4.6467576,08/23/2005,15:33:15.815, +TP,D,45.1804336,4.6462213,08/23/2005,15:33:32.832, +TP,D,45.180078,4.6458228,08/23/2005,15:33:51.851, +TP,D,45.1796982,4.6454427,08/23/2005,15:34:09.89, +TP,D,45.1793545,4.6450331,08/23/2005,15:34:29.829, +TP,D,45.1788317,4.644899,08/23/2005,15:34:50.850, +TP,D,45.1788737,4.6442499,08/23/2005,15:35:15.815, +TP,D,45.1791315,4.6437253,08/23/2005,15:35:33.833, +TP,D,45.17924,4.6431102,08/23/2005,15:35:55.855, +TP,D,45.179606,4.6427364,08/23/2005,15:36:16.816, +TP,D,45.1797593,4.6421412,08/23/2005,15:36:39.839, +TP,D,45.1798951,4.6415263,08/23/2005,15:37:03.83, +TP,D,45.1799366,4.6408842,08/23/2005,15:37:33.833, +TP,D,45.1796929,4.6403555,08/23/2005,15:38:06.86, +TP,D,45.1797172,4.6397143,08/23/2005,15:38:36.836, +TP,D,45.1795321,4.6391257,08/23/2005,15:39:06.86, +TP,D,45.179173,4.6387332,08/23/2005,15:39:29.829, +TP,D,45.1790175,4.6381358,08/23/2005,15:39:51.851, +TP,D,45.1788947,4.6375252,08/23/2005,15:40:14.814, +TP,D,45.1786746,4.6369489,08/23/2005,15:40:34.834, +TP,D,45.1783918,4.6364349,08/23/2005,15:40:47.847, +TP,D,45.1781717,4.6358662,08/23/2005,15:40:59.859, +TP,D,45.1778664,4.6351585,08/23/2005,15:41:09.89, +TP,D,45.1774999,4.6345872,08/23/2005,15:41:19.819, diff --git a/reference/track/tef_xml.sample.xml b/reference/track/tef_xml.sample.xml new file mode 100644 index 000000000..ddb466e4a --- /dev/null +++ b/reference/track/tef_xml.sample.xml @@ -0,0 +1,2 @@ + +

    diff --git a/reference/track/tinterptrack.gpx b/reference/track/tinterptrack.gpx new file mode 100644 index 000000000..397ec8a7a --- /dev/null +++ b/reference/track/tinterptrack.gpx @@ -0,0 +1,58 @@ + + + + + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/tpo-sample1.gpx b/reference/track/tpo-sample1.gpx new file mode 100644 index 000000000..37e455ed7 --- /dev/null +++ b/reference/track/tpo-sample1.gpx @@ -0,0 +1,4839 @@ + + + + + + Track 1 + + + 0.000000 + + + 0.000000 + + + + + Track 2 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 3 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 4 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 5 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 6 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 7 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 8 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 9 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 10 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 11 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 12 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 13 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 14 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 15 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 16 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 17 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 18 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 19 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 20 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 21 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 22 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 23 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 24 + + + 0.000000 + + + 0.000000 + + + + + Track 25 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 26 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 27 + + + 0.000000 + + + 0.000000 + + + + + Track 28 + + + 0.000000 + + + 0.000000 + + + + + Track 29 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 30 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 31 + + + 0.000000 + + + 0.000000 + + + + diff --git a/reference/track/tpo-sample1.tpo b/reference/track/tpo-sample1.tpo new file mode 100644 index 0000000000000000000000000000000000000000..6c3751e1fd8537037ac773aeca3f299839c68f54 GIT binary patch literal 9293 zcmb`M2Y6OR)_~7P2qBHcPy{p(AdpBTBxq=Ye4z+ZBvKS9!6-pc0t)Pc!m`M!h~@vq ziYtmzr09xD5fr6Kv4R9vTtK8OkOUG+5)#69&%Sf-O)+fZ^FPmjzvs=FIWu!+?#$dN zCk=a~O&C9R(&UNb)1n5COB<6uCTdXngz@QP{dy!P`iuQ|M|+(>FGtQE>BhaTbW;ED zZ%mKQBU2_%dT4T5M${eSC!|jqIb>kUz-A+dqzoM0GkHkz$R5d~dnP1~jQXQ|5oD-T zl*$h$w6lM=B;1lv@%iuCTN9jL`-JutGbbeRyA|E<^+ub7t^>c074jRc(HU*Wgid8C zNr?%z#^}t?eG(JgU*a{|MCU2bYl@WVI)x6MIDRUFGk9v+)buHKS2HY|T0FR}xO0lv zj?Yf`Vbtpy6^{BjkkElWf8lO(FSj`UuG*PY$g)ZRZb@lj<}js;n)~hE~^>g9lrF zl>5J_-Vxn*4yv)GyLS)o7R0;NvfENb&FA3^{00Z1vi-R%Csn`e!%JI^PkAZTo8#B? z*)66U;L#px*NsP8>Numxu}gLSL@R!5%LRt z@~wu+CaohMXsEmc3*k-TFT+bNuOkQ#MQFGGP&*Ngg?X6Zydtqc&^=2Ev1_=;=04Jg z**Qj|9Yd~%bg+)o6djMv4DF|rsq@b;75-$?kGP?aPNV+mFpcmGm}$%5wDdk&JX{C4 z3`Pz?cQ19B+D$!UNgb=b^kKb|cj%=XiSHzRH`+XE&f<--v7Sd?UC>$d+l%z=OZ4$V z`gO53g2wVLV`X?lBjq`5Dsv!%v=PL+XskptRuPPyM{kw$RvXE&;w0OOu{n#p0Qpw5 zlvvk81G#F|E2G3>E?AA^lGTc`F_PT zOl!K8ZOyPQS&v(R`i9j^Ct9)kkkw9KvJ!NG)kW7^y>zZMNM~4M&`;L{>nUw!&DT!W zE85X|Rd2NxYMk|z23lJ+!1@P#p*5{dD(HN^&3Y9|d|R~0w@nKxaLKn_FT(jsTp-T{ z-&U7xb{>=OLZy6pzOOaUw*z)!W0&S4bBJe??<5?<#$oFI8U9KA2W&PY9o<3VhwMCC z^$2zTN}1!>JcW%c$idz@+x8AMZ8dGbOqpWJU-g-H+l2g_ciTXCJ*=UvpVF4KlwGT5 z(Vd1In=dq<{DqWP-);@J_Gl9;Q(IaG;HcKOvgorsY~@pz()Iw!gnhn1`QBGYzVJ1W zCB8sXotK1~dN^5xzp63+ug2W>`$uzlLCP}h9EPcp7 zK!(U5NpTrStiKGF-g39}K-&%3Rqla%r9F8J9c)shqugbagltQxIO$7`eW}^VKGG5^ z(Q=102S@fsXVUt~&E!u+wnuiRyhG*wSjo0s^}h4X&6)YTMyGmbjGb5e((BGS$($wJ z1E#y@6gQo%o}#8@=M$r@+Ge}kZ+-u>k*VHQ>2V#mW3xn;u&xEU=LgPH>{*3cgFUn+ zyHqVX$DWz3!SZhnkz>e1@J~)OKcW8~cEL9I68%Qb2OHUyHnF>Z$%?v-6?KbVFJHlz z=ssijT8I2VE4O(yhrX)Yym0aQ)!T-rdTWho`^>&KyL(Tta|Cg|OL2QZIMs+;<&1De z3$<8t;e;0HZ#I{ag?f}-@er&1FK`fk)_nHBLfwb_k@&Zi+NI}oJ94X@*RNT zJYO>pH)HE_?5?AZ)to>+V%I3;A8y!4!-urw1GRJ&((qxK{)(=^&QjX4NH6JI)UklN zUZ&0$^{hSz&(ntIZE4~;`V_m>Oq*=>!5qT5`d7+4Nt+FG*u`d3W)?fz446rt*_3|@ zo<{#P`JZu_OWt|#Eae?4kHf^e)r~{O=sTwt)=2g4sI#D1y%9Y)#}#T6r~X!D<4_(j zM^78N*vvJ$GA6vESGFr-Ey$RZZ7y6Q8 zApMiV=v7{mI)zvFJ`eT^^^4?v_U?QjV-PbFlvFU!ojS-p{#~= zSYhk3Ue}i=7{A$!?USrF^H?bt^2T42;~Y7z$}p+z86hDM>KO`sB-qmtU4qo|w1MVQ z(-STpPZ-xpZmFIC@n@3xd3;*ab46=;E@*9+K+ky%w8NLs8}gxmd13h^f zRexew0d&OJ;1u5;iSmq^TRxzy%8Y`sT0hZRV}a+}4r zG-*!!JzeRh8@ZD5t6WwfE4RVa;oy`ntz#K?;w7-yWeI+YW%534SdIyF2?g)PK@6%FMni=_cGR*jQM`q z0XqrrMt-9Q>>OEWxi*P`Hu46vd(-1yI?zPLAMz;5#C50pTid}CTw)SC$B8Nfi#n+oIJvLcKLE$ z#dIgUkv!!%_KmHIl-5~l$BCPAmDl30s$GlQ&B%_pC4Q85>Y|NVX}@{BKF))FoMcMx zCu|0snBF|yGko8oCS~^%;Cn>Vl)2g?1Fa-LvjSum?}DM8FO2c!EN%wcDFiXG)i z?l`mH37AHF0=rKJccpY2f26;R!RL5C`O`@sV^hZtk7L&u#||={ont(^#yFenNoyoy z*^$QKmmOCoBhg1n8r;vWb-y;l^VCd+!5~P1fi44({h=@PhMv%alX*9|ot>yFbRpah z5=d)<2Qr@B=_YL@9ia`x;c<+^tJNA}IV;9$YltIH9P(ypBQY8eZKb6qK%z|yXUZ7D zhFEA*MuM~@t%Xfn>NUhuZ#;RD&>Jd`VNE1+!!I~z@>Oi+F^7XVkG6D-*?-MFrY6*8HU~i{L_j^UI3rlx za(#^8RYtA^t}u$m&s#)q7tz~>%lPOE=-C2#^)fwqnI0{oC$7*d#q?$|y;RJeT+CUZ zh<&nhf_cinW3I456^}B6o`fA4U)}y==y4F3q=9Kw9*D*T--EXM| zD{c*T=gR%HoL8;dX854nGs5CVc|ZMa#XYZMbEjtEOKgmn#yraRZ?O0pEb6kjKlxm) zB1`x(O7Iqx(2rO6s)}tw=#M%OW>d%)Vle-;DL`L9f9I1gpECK_;5=`W#ZA1NVm-sn zI*S|I8CDF#X`2GVtnA#B9a!nP0cUYL&f+HKkd1VH*?NjQ^hr1l$H?(39D&2|FPpRY z5YFlW?$&#`NACtaefSN|>ozdHgDtK!VZ&yd3;5YD=ohqRJ$L`Lu!c5f;GG`>55pri zC-9FS$4~wn-s;~-I|{$xy*>y(yBxsdeE@&=0sP+k@we~C>z#?0I}_h{CO+~^JnWfx z?KAPFXX07U#1mdB_u<`l=#ET=ZZ2JsUGyiLuD0B(x9J}3>~b4#+!;FA?9mQLLlWsp zv?0hPfOge_n#BF6w+41S*b}g_3wzkob%Q+aN-jjV2NzOiu2 z>K~ZzkKF%BUamdg&3?qcR_(cI{xeqDUJ@x)&-EF1p4j*C)2ZIaTU<)+^;u8W8?!b9 zyWfvv)FaKO6lP{zDfcl{zrS_)+n?8lK9}nKZezV2Kdd)4oi)ty2e=I_6P0b7gsR&+ z@yde-F1?WI{VX`+vlDB}ZI`~kT+`O-?FF=4xa;TVxoZVIcJt2v2YW}dzgc{7UaEJ0 z`ur7-Rd{!t9Dnfq-}+(e#1)ZspH21FKGmn!xecZtcIYX*4A1-YkBmnb z&+Ig`g#=DHhD2z`e{XMrTL~xGgyTsL$1@#UEPWJQJf#%~`dIPzD z_jwba{9@i_8GIo3$!>X3zLVGGds6nwA~_(- + + + + 03-SEP-05 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 339.963379 + + + 72.236206 + + + 74.158813 + + + 70.794189 + + + 68.390869 + + + 68.871582 + + + 69.352295 + + + 70.794189 + + + 69.352295 + + + 65.507080 + + + 64.545654 + + + 65.026367 + + + 65.026367 + + + 64.545654 + + + 63.584351 + + + 64.545654 + + + 65.507080 + + + 65.507080 + + + 65.507080 + + + 65.507080 + + + 62.142334 + + + 58.777710 + + + 60.219727 + + + 59.739136 + + + 61.661743 + + + 62.142334 + + + 61.181030 + + + 57.335815 + + + 50.606567 + + + 49.164551 + + + 47.722534 + + + 44.358032 + + + 44.838623 + + + 48.203369 + + + 47.241821 + + + 46.761230 + + + 75.120239 + + + 75.120239 + + + 64.545654 + + + 57.335815 + + + 52.048584 + + + 49.645264 + + + 45.319214 + + + 45.319214 + + + 48.683960 + + + 46.280640 + + + 45.319214 + + + 47.241821 + + + 50.125977 + + + 54.451782 + + + 55.893799 + + + 57.816528 + + + 56.855103 + + + 59.258423 + + + 60.219727 + + + 63.103638 + + + 63.584351 + + + 64.545654 + + + 66.468262 + + + 67.429688 + + + 66.948975 + + + 66.948975 + + + 66.948975 + + + 66.948975 + + + 66.468262 + + + 68.390869 + + + 70.313477 + + + 72.236206 + + + 75.600830 + + + 77.523438 + + + 77.523438 + + + 77.042847 + + + 78.004028 + + + 78.004028 + + + 77.042847 + + + 77.523438 + + + 77.042847 + + + 76.081421 + + + 74.158813 + + + 72.236206 + + + 71.274902 + + + 72.236206 + + + 73.197632 + + + 74.639526 + + + 75.600830 + + + 75.600830 + + + 75.120239 + + + 74.158813 + + + 76.081421 + + + 76.081421 + + + 75.120239 + + + 73.197632 + + + 72.716919 + + + 74.158813 + + + 74.158813 + + + 74.158813 + + + 74.639526 + + + 74.639526 + + + 72.236206 + + + 72.716919 + + + 75.600830 + + + 79.446045 + + + 80.407471 + + + 84.733398 + + + 85.694580 + + + 89.059326 + + + 89.059326 + + + 91.943237 + + + 92.904541 + + + 93.865845 + + + 93.865845 + + + 93.865845 + + + + + 03-SEP-05 02 +1 + + + 282.765015 + + + 53.009766 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 339.963379 + + + 72.236206 + + + 74.158813 + + + 70.794189 + + + 68.390869 + + + 68.871582 + + + 69.352295 + + + 70.794189 + + + 69.352295 + + + 65.507080 + + + 64.545654 + + + 65.026367 + + + 65.026367 + + + 64.545654 + + + 63.584351 + + + 64.545654 + + + 65.507080 + + + 65.507080 + + + 65.507080 + + + 65.507080 + + + 62.142334 + + + 58.777710 + + + 60.219727 + + + 59.739136 + + + 61.661743 + + + 62.142334 + + + 61.181030 + + + 57.335815 + + + 50.606567 + + + 49.164551 + + + 47.722534 + + + 44.358032 + + + 44.838623 + + + 48.203369 + + + 47.241821 + + + 46.761230 + + + 75.120239 + + + 75.120239 + + + 64.545654 + + + 57.335815 + + + 52.048584 + + + 49.645264 + + + 45.319214 + + + 45.319214 + + + 48.683960 + + + 46.280640 + + + 45.319214 + + + 47.241821 + + + 50.125977 + + + 54.451782 + + + 55.893799 + + + 57.816528 + + + 56.855103 + + + 59.258423 + + + 60.219727 + + + 63.103638 + + + 63.584351 + + + 64.545654 + + + 66.468262 + + + 67.429688 + + + 66.948975 + + + 66.948975 + + + 66.948975 + + + 66.948975 + + + 66.468262 + + + 68.390869 + + + 70.313477 + + + 72.236206 + + + 75.600830 + + + 77.523438 + + + 77.523438 + + + 77.042847 + + + 78.004028 + + + 78.004028 + + + 77.042847 + + + 77.523438 + + + 77.042847 + + + 76.081421 + + + 74.158813 + + + 72.236206 + + + 71.274902 + + + 72.236206 + + + 73.197632 + + + 74.639526 + + + 75.600830 + + + 75.600830 + + + 75.120239 + + + 74.158813 + + + 76.081421 + + + 76.081421 + + + 75.120239 + + + 73.197632 + + + 72.716919 + + + 74.158813 + + + 74.158813 + + + 74.158813 + + + 74.639526 + + + 74.639526 + + + 72.236206 + + + 72.716919 + + + 75.600830 + + + 79.446045 + + + 80.407471 + + + 84.733398 + + + 85.694580 + + + 89.059326 + + + 89.059326 + + + 91.943237 + + + 92.904541 + + + 93.865845 + + + 93.865845 + + + 93.865845 + + + 98.672485 + + + 99.633789 + + + 100.114502 + + + 98.672485 + + + 97.711182 + + + 96.269287 + + + 95.788452 + + + 95.788452 + + + 94.827148 + + + 91.943237 + + + 90.981934 + + + 89.539917 + + + 87.136597 + + + 87.617188 + + + 88.098022 + + + 88.578735 + + + 90.501343 + + + 90.020630 + + + + + 03-SEP-05 03 +2 + + + 90.020630 + + + 92.423950 + + + 93.865845 + + + 90.501343 + + + 90.501343 + + + 93.865845 + + + 100.114502 + + + 103.479004 + + + 103.479004 + + + 103.479004 + + + 105.401733 + + + 105.401733 + + + 106.363037 + + + 106.363037 + + + 106.363037 + + + 103.959717 + + + 105.401733 + + + 107.805054 + + + 107.805054 + + + 105.882446 + + + 106.843628 + + + 106.363037 + + + 106.363037 + + + 104.921021 + + + 103.479004 + + + 102.517700 + + + 101.556396 + + + 101.075684 + + + 101.556396 + + + 100.595093 + + + 99.633789 + + + 98.672485 + + + 98.672485 + + + 98.191895 + + + 95.788452 + + + + + ACTIVE LOG +3 + + + 90.020630 + + + + 92.423950 + + + + 93.865845 + + + + 90.501343 + + + + 90.501343 + + + + 93.865845 + + + + 100.114502 + + + + 103.479004 + + + + 103.479004 + + + + 103.479004 + + + + 105.401733 + + + + 105.401733 + + + + 106.363037 + + + + 106.363037 + + + + 106.363037 + + + + 103.959717 + + + + 105.401733 + + + + 107.805054 + + + + 107.805054 + + + + 105.882446 + + + + 106.843628 + + + + 106.363037 + + + + 106.363037 + + + + 104.921021 + + + + 103.479004 + + + + 102.517700 + + + + 101.556396 + + + + 101.075684 + + + + 101.556396 + + + + 100.595093 + + + + 99.633789 + + + + 98.672485 + + + + 98.672485 + + + + 98.191895 + + + + 95.788452 + + + + + + ACTIVE LOG #2 +4 + + + 95.788452 + + + + 99.633789 + + + + 98.191895 + + + + 98.191895 + + + + 98.672485 + + + + 100.595093 + + + + 101.556396 + + + + 101.556396 + + + + 102.037109 + + + + 101.075684 + + + + 101.556396 + + + + 101.556396 + + + + 102.037109 + + + + 102.517700 + + + + 102.517700 + + + + 104.921021 + + + + 104.921021 + + + + 104.921021 + + + + 104.921021 + + + + 103.959717 + + + + 103.479004 + + + + 101.075684 + + + + 101.075684 + + + + 101.075684 + + + + 100.114502 + + + + 97.711182 + + + + 97.711182 + + + + 96.749878 + + + + 90.020630 + + + + 87.617188 + + + + 84.733398 + + + + 80.888184 + + + + 79.446045 + + + + 77.042847 + + + + 70.794189 + + + + 70.794189 + + + + 69.352295 + + + + 65.507080 + + + + 64.545654 + + + + 64.545654 + + + + 64.545654 + + + + 57.335815 + + + + 55.413086 + + + + 54.932373 + + + + 55.413086 + + + + 24.651001 + + + + 18.883057 + + + + 19.363770 + + + + 19.363770 + + + + 19.844360 + + + + 19.844360 + + + + 19.844360 + + + + 16.479736 + + + + 15.999023 + + + + 14.557007 + + + + 15.518433 + + + + 13.115112 + + + + 11.673218 + + + + 11.673218 + + + + 8.789185 + + + + 5.905273 + + + + 3.501953 + + + + 3.982666 + + + + 8.308594 + + + + 5.424561 + + + + 3.501953 + + + + 2.540649 + + + + 2.540649 + + + + 0.137451 + + + + 0.137451 + + + + 2.540649 + + + + -0.824097 + + + + -1.304688 + + + + -1.304688 + + + + -0.824097 + + + + -0.824097 + + + + 0.618042 + + + + 0.618042 + + + + -0.824097 + + + + 0.137451 + + + + 0.137451 + + + + -0.824097 + + + + -1.785278 + + + + -3.227295 + + + + -4.188599 + + + + -5.630493 + + + + -7.553101 + + + + -9.475830 + + + + -10.437256 + + + + -10.917847 + + + + -13.321045 + + + + -12.359863 + + + + -11.398438 + + + + -11.398438 + + + + -11.398438 + + + + -11.398438 + + + + -9.475830 + + + + -8.514648 + + + + -8.514648 + + + + -7.553101 + + + + -7.072510 + + + + -8.033936 + + + + -7.553101 + + + + -8.995239 + + + + 3.021240 + + + + 3.021240 + + + + 3.982666 + + + + 5.424561 + + + + 2.540649 + + + + -0.824097 + + + + -5.149902 + + + + -3.707886 + + + + -6.591919 + + + + 0.618042 + + + + 3.501953 + + + + 1.579346 + + + + -2.265991 + + + + -5.630493 + + + + -4.669312 + + + + -6.591919 + + + + -7.553101 + + + + -1.304688 + + + + 7.827881 + + + + 12.153809 + + + + 12.634399 + + + + 11.673218 + + + + 18.402344 + + + + 14.076416 + + + + 3.501953 + + + + 3.021240 + + + + + + ACTIVE LOG #3 +5 + + + 23.689575 + + + + 16.479736 + + + + 14.557007 + + + + 15.037720 + + + + 14.557007 + + + + 14.557007 + + + + 14.557007 + + + + 15.037720 + + + + 12.634399 + + + + 7.347168 + + + + 5.905273 + + + + 4.943848 + + + + 4.943848 + + + + 4.943848 + + + + 1.579346 + + + + 1.579346 + + + + 2.540649 + + + + 2.540649 + + + + 0.618042 + + + + 4.943848 + + + + 5.424561 + + + + 2.540649 + + + + 0.618042 + + + + 0.137451 + + + + 0.137451 + + + + 0.137451 + + + + -1.304688 + + + + -0.343384 + + + + -0.343384 + + + + 0.137451 + + + + 0.137451 + + + + 0.137451 + + + + 0.137451 + + + + 0.137451 + + + + + + ACTIVE LOG #4 +6 + + + 1.579346 + + + + 2.060059 + + + + 2.060059 + + + + 2.060059 + + + + 2.060059 + + + + + + ACTIVE LOG #5 +7 + + + 4.463257 + + + + 7.827881 + + + + 10.711792 + + + + 13.595825 + + + + 17.921753 + + + + 17.441162 + + + + 17.441162 + + + + 17.441162 + + + + 18.883057 + + + + 18.883057 + + + + 18.883057 + + + + 18.883057 + + + + + + ACTIVE LOG #6 +8 + + + 53.971191 + + + + 53.971191 + + + + 50.125977 + + + + 57.335815 + + + + 55.893799 + + + + 54.451782 + + + + 54.451782 + + + + 54.451782 + + + + 54.451782 + + + + 54.451782 + + + + 54.451782 + + + + 54.451782 + + + + 51.087158 + + + + 48.203369 + + + + 48.203369 + + + + 47.722534 + + + + 46.280640 + + + + 45.319214 + + + + 45.319214 + + + + 43.396606 + + + + + + ACTIVE LOG #7 +9 + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 69.352295 + + + + 67.910278 + + + + 57.816528 + + + + 52.529175 + + + + 50.606567 + + + + 46.280640 + + + + 43.877319 + + + + 43.396606 + + + + 42.435425 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 41.954712 + + + + 38.590088 + + + + 38.109375 + + + + 38.109375 + + + + 37.628662 + + + + 39.070679 + + + + 48.683960 + + + + 50.125977 + + + + 49.645264 + + + + 49.164551 + + + + 49.164551 + + + + 46.280640 + + + + 43.396606 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 38.109375 + + + + 33.783447 + + + + 31.860718 + + + + 31.380127 + + + + 31.380127 + + + + 31.380127 + + + + 31.380127 + + + + 31.380127 + + + + 31.380127 + + + + 30.899536 + + + + 30.418823 + + + + 29.938110 + + + + 11.673218 + + + + 11.673218 + + + + 11.192505 + + + + 11.192505 + + + + 10.711792 + + + + 10.711792 + + + + 11.673218 + + + + 10.711792 + + + + 10.711792 + + + + 10.711792 + + + + 11.673218 + + + + 11.673218 + + + + 10.711792 + + + + 8.789185 + + + + 6.385864 + + + + 6.385864 + + + + 6.385864 + + + + + + ACTIVE LOG #8 +10 + + + -4.188599 + + + + -6.111206 + + + + -5.630493 + + + + -0.824097 + + + + 0.618042 + + + + -0.343384 + + + + -0.343384 + + + + -0.824097 + + + + + + ACTIVE LOG #9 +11 + + + -0.824097 + + + + -0.824097 + + + + -0.343384 + + + + -0.824097 + + + + -0.824097 + + + + -0.824097 + + + + 0.618042 + + + + 1.579346 + + + + 3.021240 + + + + 3.021240 + + + + 5.424561 + + + + 9.269897 + + + + 9.269897 + + + + 9.750610 + + + + 13.595825 + + + + 15.037720 + + + + 15.518433 + + + + 18.402344 + + + + 19.363770 + + + + 19.363770 + + + + 19.363770 + + + + 22.728271 + + + + 24.170288 + + + + 24.651001 + + + + 26.573608 + + + + 28.496216 + + + + 31.860718 + + + + 31.860718 + + + + 31.860718 + + + + 31.860718 + + + + 31.860718 + + + + 32.341553 + + + + 33.783447 + + + + 33.783447 + + + + 33.783447 + + + + 37.148071 + + + + 41.954712 + + + + 42.435425 + + + + 47.722534 + + + + 48.203369 + + + + 48.203369 + + + + 54.451782 + + + + 58.297119 + + + + 60.700317 + + + + 60.700317 + + + + 60.700317 + + + + 60.700317 + + + + 60.700317 + + + + 65.026367 + + + + 68.871582 + + + + 68.871582 + + + + 68.871582 + + + + + + ACTIVE LOG #10 +12 + + + 96.749878 + + + + 90.501343 + + + + 90.020630 + + + + 90.981934 + + + + 91.462524 + + + + 91.462524 + + + + 91.462524 + + + + 91.943237 + + + + 91.462524 + + + + 90.020630 + + + + 87.136597 + + + + 87.136597 + + + + 87.617188 + + + + 88.578735 + + + + 88.098022 + + + + 88.098022 + + + + 87.617188 + + + + 86.175293 + + + + 86.175293 + + + + 83.771973 + + + + 83.291382 + + + + 83.771973 + + + + 83.771973 + + + + 78.004028 + + + + 72.716919 + + + + 70.794189 + + + + 70.794189 + + + + 69.352295 + + + + 68.390869 + + + + 68.871582 + + + + 66.948975 + + + + 63.103638 + + + + 57.335815 + + + + 57.335815 + + + + 54.932373 + + + + 54.451782 + + + + 52.048584 + + + + 52.048584 + + + + 44.358032 + + + + 41.473999 + + + + 41.473999 + + + + 37.628662 + + + + 35.706055 + + + + 34.264160 + + + + 31.860718 + + + + 24.651001 + + + + 22.247559 + + + + 20.324951 + + + + 18.402344 + + + + 20.805664 + + + + 16.479736 + + + + 16.479736 + + + + 15.518433 + + + + 12.634399 + + + + 12.634399 + + + + 8.308594 + + + + 2.060059 + + + + 0.618042 + + + + 0.618042 + + + + -0.343384 + + + + 0.618042 + + + + 0.137451 + + + + -2.265991 + + + + -1.304688 + + + + -1.785278 + + + + -1.785278 + + + + -3.227295 + + + + -3.227295 + + + + -2.265991 + + + + -2.265991 + + + + -2.265991 + + + + -0.824097 + + + + 3.021240 + + + + -0.824097 + + + + 3.982666 + + + + 0.137451 + + + + -3.227295 + + + + -2.746704 + + + + -2.265991 + + + + -4.188599 + + + + -7.072510 + + + + -6.591919 + + + + -4.669312 + + + + -4.669312 + + + + -8.033936 + + + + -3.227295 + + + + -3.227295 + + + + -1.785278 + + + + -1.304688 + + + + 0.137451 + + + + -1.304688 + + + + -2.265991 + + + + -2.265991 + + + + -3.707886 + + + + -4.188599 + + + + -5.630493 + + + + -6.111206 + + + + -4.669312 + + + + -3.227295 + + + + -1.304688 + + + + 0.618042 + + + + -0.824097 + + + + -1.304688 + + + + 0.137451 + + + + -0.343384 + + + + -0.343384 + + + + 3.501953 + + + + 3.501953 + + + + 4.463257 + + + + 6.385864 + + + + 7.347168 + + + + 8.308594 + + + + 11.192505 + + + + 15.518433 + + + + 10.711792 + + + + 10.231201 + + + + 8.789185 + + + + 9.269897 + + + + 6.866455 + + + + 5.424561 + + + + 4.943848 + + + + 4.463257 + + + + 4.943848 + + + + 4.943848 + + + + 4.943848 + + + + 3.501953 + + + + 3.982666 + + + + 4.943848 + + + + 4.943848 + + + + 3.982666 + + + + 3.982666 + + + + 1.579346 + + + + 3.501953 + + + + 5.424561 + + + + 4.463257 + + + + 7.827881 + + + + 12.153809 + + + + 7.827881 + + + + 7.827881 + + + + 6.866455 + + + + 6.385864 + + + + 5.905273 + + + + 7.827881 + + + + 5.424561 + + + + 10.231201 + + + + 12.153809 + + + + 20.324951 + + + + 21.766968 + + + + 23.208984 + + + + 18.402344 + + + + 17.921753 + + + + 15.037720 + + + + 12.153809 + + + + 15.037720 + + + + 16.960449 + + + + 19.844360 + + + + 27.534912 + + + + 28.976929 + + + + 32.822266 + + + + 33.783447 + + + + 35.225464 + + + + 35.225464 + + + + 28.015503 + + + + 21.766968 + + + + 24.651001 + + + + 26.573608 + + + + 30.418823 + + + + 30.899536 + + + + 28.496216 + + + + 16.479736 + + + + 16.479736 + + + + 19.363770 + + + + 24.170288 + + + + 32.822266 + + + + 33.783447 + + + + 36.667480 + + + + 37.148071 + + + + 37.148071 + + + + 36.667480 + + + + 38.109375 + + + + 37.148071 + + + + 37.148071 + + + + 37.148071 + + + + 36.667480 + + + + 36.667480 + + + + 36.667480 + + + + 41.954712 + + + + 42.435425 + + + + 40.993408 + + + + 40.032104 + + + + 39.551270 + + + + 38.590088 + + + + 37.628662 + + + + 36.667480 + + + + 35.706055 + + + + 34.744873 + + + + 34.264160 + + + + 34.744873 + + + + 33.783447 + + + + 32.341553 + + + + 32.341553 + + + + 31.860718 + + + + 32.341553 + + + + 32.341553 + + + + 28.976929 + + + + 27.534912 + + + + 29.457520 + + + + 30.418823 + + + + 30.899536 + + + + 30.418823 + + + + 28.976929 + + + + 28.496216 + + + + 29.457520 + + + + 28.976929 + + + + 28.015503 + + + + + + ACTIVE LOG #11 +13 + + + 50.125977 + + + + 46.280640 + + + + 41.954712 + + + + 44.838623 + + + + 45.799927 + + + + 45.799927 + + + + 47.241821 + + + + 44.838623 + + + + 43.396606 + + + + 43.877319 + + + + 43.877319 + + + + 42.916016 + + + + 45.319214 + + + + 42.916016 + + + + 43.396606 + + + + 44.838623 + + + + 43.396606 + + + + 32.341553 + + + + 29.457520 + + + + 26.573608 + + + + 24.170288 + + + + 22.728271 + + + + 22.247559 + + + + 22.247559 + + + + 19.363770 + + + + 21.286377 + + + + 18.402344 + + + + 20.805664 + + + + 22.247559 + + + + 23.689575 + + + + 21.766968 + + + + 18.402344 + + + + 15.518433 + + + + 15.518433 + + + + 13.595825 + + + + 11.192505 + + + + 12.153809 + + + + 13.595825 + + + + 10.231201 + + + + 11.192505 + + + + 9.750610 + + + + 8.789185 + + + + 9.269897 + + + + 8.789185 + + + + 6.866455 + + + + 6.866455 + + + + 7.347168 + + + + 8.789185 + + + + 16.960449 + + + + 18.883057 + + + + 19.844360 + + + + 14.557007 + + + + 13.115112 + + + + 10.711792 + + + + 8.308594 + + + + 8.308594 + + + + 7.827881 + + + + 6.866455 + + + + 5.905273 + + + + 13.115112 + + + + 9.750610 + + + + 9.269897 + + + + 7.347168 + + + + 8.308594 + + + + 9.750610 + + + + 10.231201 + + + + 7.827881 + + + + 7.347168 + + + + 6.385864 + + + + 7.347168 + + + + 7.347168 + + + + 11.673218 + + + + 12.634399 + + + + 15.518433 + + + + 15.518433 + + + + 14.557007 + + + + 14.557007 + + + + 10.231201 + + + + 8.308594 + + + + 3.501953 + + + + 8.789185 + + + + 8.789185 + + + + 9.269897 + + + + 8.308594 + + + + 13.115112 + + + + 12.153809 + + + + 19.844360 + + + + 17.921753 + + + + 18.883057 + + + + 18.883057 + + + + 19.363770 + + + + 18.883057 + + + + 19.844360 + + + + 19.844360 + + + + 19.363770 + + + + 19.363770 + + + + 19.363770 + + + + 17.441162 + + + + 19.844360 + + + + 18.402344 + + + + 18.402344 + + + + 18.402344 + + + + 16.960449 + + + + 15.518433 + + + + 11.192505 + + + + 11.192505 + + + + + + ACTIVE LOG #12 +14 + + + 39.551270 + + + + 43.396606 + + + + + diff --git a/reference/track/tpo-sample2.tpo b/reference/track/tpo-sample2.tpo new file mode 100644 index 0000000000000000000000000000000000000000..ab7556c2884125ae23f8d3a84375b30706545a33 GIT binary patch literal 5933 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 literal 0 HcmV?d00001 diff --git a/reference/track/trackDMm.ktf b/reference/track/trackDMm.ktf new file mode 100644 index 000000000..f2b8c83d2 --- /dev/null +++ b/reference/track/trackDMm.ktf @@ -0,0 +1,179 @@ +//Kartex TrackFil skapad av Kartex 5.0 +&KTF 2.0,sweref 99 lat long,1 +%,19,N56°9.098' E13°45.642',54.00,2006-03-07 15:58:36,,,$ +%,20,N56°9.101' E13°45.642',47.00,2006-03-07 15:58:38,,,$ +%,21,N56°9.080' E13°45.630',47.00,2006-03-07 15:59:00,,,$ +%,22,N56°9.056' E13°45.619',46.00,2006-03-07 15:59:29,,,$ +%,23,N56°9.021' E13°45.598',46.00,2006-03-07 16:00:12,,,$ +%,24,N56°8.984' E13°45.579',47.00,2006-03-07 16:00:58,,,$ +%,25,N56°8.953' E13°45.561',48.00,2006-03-07 16:01:38,,,$ +%,26,N56°8.930' E13°45.547',47.00,2006-03-07 16:02:06,,,$ +%,27,N56°8.913' E13°45.543',47.00,2006-03-07 16:02:27,,,$ +%,28,N56°8.882' E13°45.531',46.00,2006-03-07 16:03:04,,,$ +%,29,N56°8.856' E13°45.529',46.00,2006-03-07 16:03:35,,,$ +%,30,N56°8.838' E13°45.526',44.00,2006-03-07 16:04:02,,,$ +%,31,N56°8.838' E13°45.526',45.00,2006-03-07 16:04:11,,,$ +%,32,N56°8.837' E13°45.518',45.00,2006-03-07 16:04:16,,,$ +%,33,N56°8.827' E13°45.490',46.00,2006-03-07 16:04:39,,,$ +%,34,N56°8.820' E13°45.465',48.00,2006-03-07 16:04:59,,,$ +%,35,N56°8.797' E13°45.444',47.00,2006-03-07 16:05:33,,,$ +%,36,N56°8.773' E13°45.431',45.00,2006-03-07 16:06:04,,,$ +%,37,N56°8.742' E13°45.414',43.00,2006-03-07 16:06:46,,,$ +%,38,N56°8.727' E13°45.414',45.00,2006-03-07 16:07:07,,,$ +%,39,N56°8.721' E13°45.437',45.00,2006-03-07 16:07:26,,,$ +%,40,N56°8.718' E13°45.447',44.00,2006-03-07 16:07:35,,,$ +%,41,N56°8.697' E13°45.451',45.00,2006-03-07 16:08:03,,,$ +%,42,N56°8.680' E13°45.468',44.00,2006-03-07 16:08:28,,,$ +%,43,N56°8.667' E13°45.520',41.00,2006-03-07 16:09:08,,,$ +%,44,N56°8.671' E13°45.540',42.00,2006-03-07 16:09:23,,,$ +%,45,N56°8.667' E13°45.553',43.00,2006-03-07 16:09:35,,,$ +%,46,N56°8.648' E13°45.549',44.00,2006-03-07 16:09:58,,,$ +%,47,N56°8.612' E13°45.541',45.00,2006-03-07 16:10:40,,,$ +%,48,N56°8.587' E13°45.513',46.00,2006-03-07 16:11:14,,,$ +%,49,N56°8.565' E13°45.481',48.00,2006-03-07 16:11:49,,,$ +%,50,N56°8.531' E13°45.453',48.00,2006-03-07 16:12:34,,,$ +%,51,N56°8.529' E13°45.453',48.00,2006-03-07 16:12:53,,,$ +%,52,N56°8.528' E13°45.450',48.00,2006-03-07 16:13:21,,,$ +%,53,N56°8.505' E13°45.436',50.00,2006-03-07 16:13:51,,,$ +%,54,N56°8.487' E13°45.427',49.00,2006-03-07 16:14:17,,,$ +%,55,N56°8.462' E13°45.405',46.00,2006-03-07 16:14:51,,,$ +%,56,N56°8.444' E13°45.381',46.00,2006-03-07 16:15:19,,,$ +%,57,N56°8.428' E13°45.361',46.00,2006-03-07 16:15:54,,,$ +%,58,N56°8.424' E13°45.356',45.00,2006-03-07 16:16:13,,,$ +%,59,N56°8.413' E13°45.341',44.00,2006-03-07 16:16:33,,,$ +%,60,N56°8.385' E13°45.312',43.00,2006-03-07 16:17:11,,,$ +%,61,N56°8.373' E13°45.292',44.00,2006-03-07 16:17:35,,,$ +%,62,N56°8.370' E13°45.288',44.00,2006-03-07 16:17:41,,,$ +%,63,N56°8.340' E13°45.307',43.00,2006-03-07 16:18:19,,,$ +%,64,N56°8.326' E13°45.310',43.00,2006-03-07 16:18:35,,,$ +%,65,N56°8.323' E13°45.303',44.00,2006-03-07 16:18:41,,,$ +%,66,N56°8.317' E13°45.225',43.00,2006-03-07 16:19:36,,,$ +%,67,N56°8.314' E13°45.189',44.00,2006-03-07 16:20:01,,,$ +%,68,N56°8.300' E13°45.166',44.00,2006-03-07 16:20:25,,,$ +%,69,N56°8.264' E13°45.163',44.00,2006-03-07 16:21:11,,,$ +%,70,N56°8.224' E13°45.190',42.00,2006-03-07 16:22:05,,,$ +%,71,N56°8.210' E13°45.220',43.00,2006-03-07 16:22:34,,,$ +%,72,N56°8.198' E13°45.249',44.00,2006-03-07 16:23:01,,,$ +%,73,N56°8.182' E13°45.298',44.00,2006-03-07 16:23:42,,,$ +%,74,N56°8.178' E13°45.311',44.00,2006-03-07 16:24:03,,,$ +%,75,N56°8.178' E13°45.314',44.00,2006-03-07 16:24:05,,,$ +%,76,N56°8.173' E13°45.317',44.00,2006-03-07 16:24:11,,,$ +%,77,N56°8.146' E13°45.298',44.00,2006-03-07 16:24:48,,,$ +%,78,N56°8.121' E13°45.279',43.00,2006-03-07 16:25:22,,,$ +%,79,N56°8.097' E13°45.256',44.00,2006-03-07 16:26:03,,,$ +%,80,N56°8.086' E13°45.244',45.00,2006-03-07 16:26:35,,,$ +%,81,N56°8.080' E13°45.235',44.00,2006-03-07 16:26:55,,,$ +%,82,N56°8.050' E13°45.191',44.00,2006-03-07 16:27:42,,,$ +%,83,N56°8.025' E13°45.141',44.00,2006-03-07 16:28:30,,,$ +%,84,N56°8.022' E13°45.135',47.00,2006-03-07 16:28:55,,,$ +%,85,N56°8.014' E13°45.117',48.00,2006-03-07 16:29:40,,,$ +%,86,N56°7.995' E13°45.066',47.00,2006-03-07 16:30:23,,,$ +%,87,N56°7.976' E13°45.019',47.00,2006-03-07 16:31:04,,,$ +%,88,N56°7.958' E13°44.971',46.00,2006-03-07 16:31:45,,,$ +%,89,N56°7.952' E13°44.938',43.00,2006-03-07 16:32:13,,,$ +%,90,N56°7.950' E13°44.931',43.00,2006-03-07 16:32:27,,,$ +%,91,N56°7.950' E13°44.930',43.00,2006-03-07 16:32:29,,,$ +%,92,N56°7.923' E13°44.902',44.00,2006-03-07 16:33:09,,,$ +%,93,N56°7.913' E13°44.895',45.00,2006-03-07 16:33:31,,,$ +%,94,N56°7.882' E13°44.866',46.00,2006-03-07 16:34:15,,,$ +%,95,N56°7.866' E13°44.850',47.00,2006-03-07 16:34:44,,,$ +%,96,N56°7.840' E13°44.819',44.00,2006-03-07 16:35:22,,,$ +%,97,N56°7.810' E13°44.783',43.00,2006-03-07 16:36:09,,,$ +%,98,N56°7.781' E13°44.750',43.00,2006-03-07 16:36:52,,,$ +%,99,N56°7.754' E13°44.720',44.00,2006-03-07 16:37:30,,,$ +%,100,N56°7.723' E13°44.687',43.00,2006-03-07 16:38:15,,,$ +%,101,N56°7.687' E13°44.647',43.00,2006-03-07 16:39:06,,,$ +%,102,N56°7.656' E13°44.613',44.00,2006-03-07 16:39:52,,,$ +%,103,N56°7.636' E13°44.591',44.00,2006-03-07 16:40:24,,,$ +%,104,N56°7.607' E13°44.566',44.00,2006-03-07 16:41:05,,,$ +%,105,N56°7.588' E13°44.550',44.00,2006-03-07 16:41:34,,,$ +%,106,N56°7.574' E13°44.539',47.00,2006-03-07 16:42:03,,,$ +%,107,N56°7.567' E13°44.535',46.00,2006-03-07 16:42:15,,,$ +%,108,N56°7.565' E13°44.532',46.00,2006-03-07 16:42:37,,,$ +%,109,N56°7.558' E13°44.527',46.00,2006-03-07 16:42:58,,,$ +%,110,N56°7.547' E13°44.519',46.00,2006-03-07 16:43:16,,,$ +%,111,N56°7.517' E13°44.504',47.00,2006-03-07 16:43:54,,,$ +%,112,N56°7.486' E13°44.488',46.00,2006-03-07 16:44:36,,,$ +%,113,N56°7.466' E13°44.477',44.00,2006-03-07 16:45:04,,,$ +%,114,N56°7.440' E13°44.460',44.00,2006-03-07 16:45:38,,,$ +%,115,N56°7.409' E13°44.443',44.00,2006-03-07 16:46:20,,,$ +%,116,N56°7.376' E13°44.433',46.00,2006-03-07 16:47:02,,,$ +%,117,N56°7.345' E13°44.427',49.00,2006-03-07 16:47:40,,,$ +%,118,N56°7.309' E13°44.417',50.00,2006-03-07 16:48:25,,,$ +%,119,N56°7.275' E13°44.405',51.00,2006-03-07 16:49:07,,,$ +%,120,N56°7.268' E13°44.399',51.00,2006-03-07 16:49:31,,,$ +%,121,N56°7.262' E13°44.397',52.00,2006-03-07 16:49:52,,,$ +%,122,N56°7.259' E13°44.397',52.00,2006-03-07 16:50:18,,,$ +%,123,N56°7.237' E13°44.387',52.00,2006-03-07 16:50:49,,,$ +%,124,N56°7.216' E13°44.376',52.00,2006-03-07 16:51:23,,,$ +%,125,N56°7.204' E13°44.375',53.00,2006-03-07 16:51:56,,,$ +%,126,N56°7.188' E13°44.370',53.00,2006-03-07 16:52:26,,,$ +%,127,N56°7.188' E13°44.370',52.00,2006-03-07 16:52:35,,,$ +%,128,N56°7.154' E13°44.374',52.00,2006-03-07 16:53:17,,,$ +%,129,N56°7.119' E13°44.380',51.00,2006-03-07 16:54:00,,,$ +%,130,N56°7.083' E13°44.402',51.00,2006-03-07 16:54:47,,,$ +%,131,N56°7.056' E13°44.423',50.00,2006-03-07 16:55:24,,,$ +%,132,N56°7.024' E13°44.433',49.00,2006-03-07 16:56:05,,,$ +%,133,N56°6.983' E13°44.436',50.00,2006-03-07 16:56:54,,,$ +%,134,N56°6.957' E13°44.437',52.00,2006-03-07 16:57:27,,,$ +%,135,N56°6.922' E13°44.438',52.00,2006-03-07 16:58:11,,,$ +%,136,N56°6.902' E13°44.392',48.00,2006-03-07 16:58:52,,,$ +%,137,N56°6.898' E13°44.340',46.00,2006-03-07 16:59:27,,,$ +%,138,N56°6.901' E13°44.294',47.00,2006-03-07 16:59:57,,,$ +%,139,N56°6.904' E13°44.253',46.00,2006-03-07 17:00:26,,,$ +%,140,N56°6.922' E13°44.204',45.00,2006-03-07 17:01:07,,,$ +%,141,N56°6.950' E13°44.182',44.00,2006-03-07 17:01:45,,,$ +%,142,N56°6.979' E13°44.161',45.00,2006-03-07 17:02:25,,,$ +%,143,N56°6.998' E13°44.152',44.00,2006-03-07 17:02:50,,,$ +%,144,N56°7.033' E13°44.139',44.00,2006-03-07 17:03:32,,,$ +%,145,N56°7.069' E13°44.134',45.00,2006-03-07 17:04:17,,,$ +%,146,N56°7.104' E13°44.125',45.00,2006-03-07 17:04:59,,,$ +%,147,N56°7.112' E13°44.112',45.00,2006-03-07 17:05:11,,,$ +%,148,N56°7.136' E13°44.110',44.00,2006-03-07 17:05:43,,,$ +%,149,N56°7.149' E13°44.107',44.00,2006-03-07 17:05:58,,,$ +%,150,N56°7.156' E13°44.085',44.00,2006-03-07 17:06:16,,,$ +%,151,N56°7.175' E13°44.092',44.00,2006-03-07 17:06:41,,,$ +%,152,N56°7.190' E13°44.060',43.00,2006-03-07 17:07:15,,,$ +%,153,N56°7.204' E13°44.042',43.00,2006-03-07 17:07:38,,,$ +%,154,N56°7.217' E13°44.033',43.00,2006-03-07 17:07:59,,,$ +%,155,N56°7.221' E13°44.031',43.00,2006-03-07 17:08:27,,,$ +%,156,N56°7.221' E13°44.031',43.00,2006-03-07 17:08:35,,,$ +%,157,N56°7.240' E13°43.996',41.00,2006-03-07 17:09:12,,,$ +%,158,N56°7.256' E13°43.963',41.00,2006-03-07 17:09:45,,,$ +%,159,N56°7.270' E13°43.933',40.00,2006-03-07 17:10:14,,,$ +%,160,N56°7.287' E13°43.895',40.00,2006-03-07 17:10:51,,,$ +%,161,N56°7.307' E13°43.850',41.00,2006-03-07 17:11:35,,,$ +%,162,N56°7.322' E13°43.806',41.00,2006-03-07 17:12:14,,,$ +%,163,N56°7.337' E13°43.770',40.00,2006-03-07 17:12:47,,,$ +%,164,N56°7.355' E13°43.729',39.00,2006-03-07 17:13:27,,,$ +%,165,N56°7.373' E13°43.685',40.00,2006-03-07 17:14:09,,,$ +%,166,N56°7.390' E13°43.646',41.00,2006-03-07 17:14:48,,,$ +%,167,N56°7.396' E13°43.632',41.00,2006-03-07 17:15:08,,,$ +%,168,N56°7.407' E13°43.612',41.00,2006-03-07 17:15:32,,,$ +%,169,N56°7.418' E13°43.583',40.00,2006-03-07 17:15:59,,,$ +%,170,N56°7.434' E13°43.552',40.00,2006-03-07 17:16:30,,,$ +%,171,N56°7.453' E13°43.515',39.00,2006-03-07 17:17:09,,,$ +%,172,N56°7.468' E13°43.485',40.00,2006-03-07 17:17:41,,,$ +%,173,N56°7.484' E13°43.447',39.00,2006-03-07 17:18:17,,,$ +%,174,N56°7.490' E13°43.425',38.00,2006-03-07 17:18:45,,,$ +%,175,N56°7.497' E13°43.407',38.00,2006-03-07 17:19:21,,,$ +%,176,N56°7.512' E13°43.371',38.00,2006-03-07 17:19:54,,,$ +%,177,N56°7.520' E13°43.354',38.00,2006-03-07 17:20:12,,,$ +%,178,N56°7.524' E13°43.339',38.00,2006-03-07 17:20:29,,,$ +%,179,N56°7.528' E13°43.350',39.00,2006-03-07 17:20:39,,,$ +%,180,N56°7.547' E13°43.359',40.00,2006-03-07 17:21:06,,,$ +%,181,N56°7.549' E13°43.360',40.00,2006-03-07 17:21:11,,,$ +%,182,N56°7.553' E13°43.359',40.00,2006-03-07 17:21:16,,,$ +%,183,N56°7.551' E13°43.342',41.00,2006-03-07 17:21:32,,,$ +%,184,N56°7.552' E13°43.328',41.00,2006-03-07 17:21:56,,,$ +%,185,N56°7.552' E13°43.323',42.00,2006-03-07 17:22:16,,,$ +%,186,N56°7.551' E13°43.323',41.00,2006-03-07 17:22:52,,,$ +%,187,N56°7.552' E13°43.317',41.00,2006-03-07 17:23:10,,,$ +%,188,N56°7.555' E13°43.318',41.00,2006-03-07 17:23:30,,,$ +%,189,N56°7.553' E13°43.318',41.00,2006-03-07 17:24:15,,,$ +%,190,N56°7.552' E13°43.330',38.00,2006-03-07 17:33:44,,,$ +%,191,N56°7.548' E13°43.333',38.00,2006-03-07 17:34:10,,,$ +%,192,N56°7.547' E13°43.335',40.00,2006-03-07 17:34:40,,,$ +%,193,N56°7.547' E13°43.332',40.00,2006-03-07 17:34:58,,,$ +%,194,N56°7.549' E13°43.339',41.00,2006-03-07 17:35:12,,,$ +%,195,N56°7.549' E13°43.339',40.00,2006-03-07 17:35:52,,,$ diff --git a/reference/track/trackDd.ktf b/reference/track/trackDd.ktf new file mode 100644 index 000000000..b1688f926 --- /dev/null +++ b/reference/track/trackDd.ktf @@ -0,0 +1,179 @@ +//Kartex TrackFil skapad av Kartex 5.0 +&KTF 2.0,sweref 99 lat long,0 +%,19,N56.151633° E13.760700°,54.00,2006-03-07 15:58:36,,,$ +%,20,N56.151683° E13.760700°,47.00,2006-03-07 15:58:38,,,$ +%,21,N56.151333° E13.760500°,47.00,2006-03-07 15:59:00,,,$ +%,22,N56.150933° E13.760317°,46.00,2006-03-07 15:59:29,,,$ +%,23,N56.150350° E13.759967°,46.00,2006-03-07 16:00:12,,,$ +%,24,N56.149733° E13.759650°,47.00,2006-03-07 16:00:58,,,$ +%,25,N56.149217° E13.759350°,48.00,2006-03-07 16:01:38,,,$ +%,26,N56.148833° E13.759117°,47.00,2006-03-07 16:02:06,,,$ +%,27,N56.148550° E13.759050°,47.00,2006-03-07 16:02:27,,,$ +%,28,N56.148033° E13.758850°,46.00,2006-03-07 16:03:04,,,$ +%,29,N56.147600° E13.758817°,46.00,2006-03-07 16:03:35,,,$ +%,30,N56.147300° E13.758767°,44.00,2006-03-07 16:04:02,,,$ +%,31,N56.147300° E13.758767°,45.00,2006-03-07 16:04:11,,,$ +%,32,N56.147283° E13.758633°,45.00,2006-03-07 16:04:16,,,$ +%,33,N56.147117° E13.758167°,46.00,2006-03-07 16:04:39,,,$ +%,34,N56.147000° E13.757750°,48.00,2006-03-07 16:04:59,,,$ +%,35,N56.146617° E13.757400°,47.00,2006-03-07 16:05:33,,,$ +%,36,N56.146217° E13.757183°,45.00,2006-03-07 16:06:04,,,$ +%,37,N56.145700° E13.756900°,43.00,2006-03-07 16:06:46,,,$ +%,38,N56.145450° E13.756900°,45.00,2006-03-07 16:07:07,,,$ +%,39,N56.145350° E13.757283°,45.00,2006-03-07 16:07:26,,,$ +%,40,N56.145300° E13.757450°,44.00,2006-03-07 16:07:35,,,$ +%,41,N56.144950° E13.757517°,45.00,2006-03-07 16:08:03,,,$ +%,42,N56.144667° E13.757800°,44.00,2006-03-07 16:08:28,,,$ +%,43,N56.144450° E13.758667°,41.00,2006-03-07 16:09:08,,,$ +%,44,N56.144517° E13.759000°,42.00,2006-03-07 16:09:23,,,$ +%,45,N56.144450° E13.759217°,43.00,2006-03-07 16:09:35,,,$ +%,46,N56.144133° E13.759150°,44.00,2006-03-07 16:09:58,,,$ +%,47,N56.143533° E13.759017°,45.00,2006-03-07 16:10:40,,,$ +%,48,N56.143117° E13.758550°,46.00,2006-03-07 16:11:14,,,$ +%,49,N56.142750° E13.758017°,48.00,2006-03-07 16:11:49,,,$ +%,50,N56.142183° E13.757550°,48.00,2006-03-07 16:12:34,,,$ +%,51,N56.142150° E13.757550°,48.00,2006-03-07 16:12:53,,,$ +%,52,N56.142133° E13.757500°,48.00,2006-03-07 16:13:21,,,$ +%,53,N56.141750° E13.757267°,50.00,2006-03-07 16:13:51,,,$ +%,54,N56.141450° E13.757117°,49.00,2006-03-07 16:14:17,,,$ +%,55,N56.141033° E13.756750°,46.00,2006-03-07 16:14:51,,,$ +%,56,N56.140733° E13.756350°,46.00,2006-03-07 16:15:19,,,$ +%,57,N56.140467° E13.756017°,46.00,2006-03-07 16:15:54,,,$ +%,58,N56.140400° E13.755933°,45.00,2006-03-07 16:16:13,,,$ +%,59,N56.140217° E13.755683°,44.00,2006-03-07 16:16:33,,,$ +%,60,N56.139750° E13.755200°,43.00,2006-03-07 16:17:11,,,$ +%,61,N56.139550° E13.754867°,44.00,2006-03-07 16:17:35,,,$ +%,62,N56.139500° E13.754800°,44.00,2006-03-07 16:17:41,,,$ +%,63,N56.139000° E13.755117°,43.00,2006-03-07 16:18:19,,,$ +%,64,N56.138767° E13.755167°,43.00,2006-03-07 16:18:35,,,$ +%,65,N56.138717° E13.755050°,44.00,2006-03-07 16:18:41,,,$ +%,66,N56.138617° E13.753750°,43.00,2006-03-07 16:19:36,,,$ +%,67,N56.138567° E13.753150°,44.00,2006-03-07 16:20:01,,,$ +%,68,N56.138333° E13.752767°,44.00,2006-03-07 16:20:25,,,$ +%,69,N56.137733° E13.752717°,44.00,2006-03-07 16:21:11,,,$ +%,70,N56.137067° E13.753167°,42.00,2006-03-07 16:22:05,,,$ +%,71,N56.136833° E13.753667°,43.00,2006-03-07 16:22:34,,,$ +%,72,N56.136633° E13.754150°,44.00,2006-03-07 16:23:01,,,$ +%,73,N56.136367° E13.754967°,44.00,2006-03-07 16:23:42,,,$ +%,74,N56.136300° E13.755183°,44.00,2006-03-07 16:24:03,,,$ +%,75,N56.136300° E13.755233°,44.00,2006-03-07 16:24:05,,,$ +%,76,N56.136217° E13.755283°,44.00,2006-03-07 16:24:11,,,$ +%,77,N56.135767° E13.754967°,44.00,2006-03-07 16:24:48,,,$ +%,78,N56.135350° E13.754650°,43.00,2006-03-07 16:25:22,,,$ +%,79,N56.134950° E13.754267°,44.00,2006-03-07 16:26:03,,,$ +%,80,N56.134767° E13.754067°,45.00,2006-03-07 16:26:35,,,$ +%,81,N56.134667° E13.753917°,44.00,2006-03-07 16:26:55,,,$ +%,82,N56.134167° E13.753183°,44.00,2006-03-07 16:27:42,,,$ +%,83,N56.133750° E13.752350°,44.00,2006-03-07 16:28:30,,,$ +%,84,N56.133700° E13.752250°,47.00,2006-03-07 16:28:55,,,$ +%,85,N56.133567° E13.751950°,48.00,2006-03-07 16:29:40,,,$ +%,86,N56.133250° E13.751100°,47.00,2006-03-07 16:30:23,,,$ +%,87,N56.132933° E13.750317°,47.00,2006-03-07 16:31:04,,,$ +%,88,N56.132633° E13.749517°,46.00,2006-03-07 16:31:45,,,$ +%,89,N56.132533° E13.748967°,43.00,2006-03-07 16:32:13,,,$ +%,90,N56.132500° E13.748850°,43.00,2006-03-07 16:32:27,,,$ +%,91,N56.132500° E13.748833°,43.00,2006-03-07 16:32:29,,,$ +%,92,N56.132050° E13.748367°,44.00,2006-03-07 16:33:09,,,$ +%,93,N56.131883° E13.748250°,45.00,2006-03-07 16:33:31,,,$ +%,94,N56.131367° E13.747767°,46.00,2006-03-07 16:34:15,,,$ +%,95,N56.131100° E13.747500°,47.00,2006-03-07 16:34:44,,,$ +%,96,N56.130667° E13.746983°,44.00,2006-03-07 16:35:22,,,$ +%,97,N56.130167° E13.746383°,43.00,2006-03-07 16:36:09,,,$ +%,98,N56.129683° E13.745833°,43.00,2006-03-07 16:36:52,,,$ +%,99,N56.129233° E13.745333°,44.00,2006-03-07 16:37:30,,,$ +%,100,N56.128717° E13.744783°,43.00,2006-03-07 16:38:15,,,$ +%,101,N56.128117° E13.744117°,43.00,2006-03-07 16:39:06,,,$ +%,102,N56.127600° E13.743550°,44.00,2006-03-07 16:39:52,,,$ +%,103,N56.127267° E13.743183°,44.00,2006-03-07 16:40:24,,,$ +%,104,N56.126783° E13.742767°,44.00,2006-03-07 16:41:05,,,$ +%,105,N56.126467° E13.742500°,44.00,2006-03-07 16:41:34,,,$ +%,106,N56.126233° E13.742317°,47.00,2006-03-07 16:42:03,,,$ +%,107,N56.126117° E13.742250°,46.00,2006-03-07 16:42:15,,,$ +%,108,N56.126083° E13.742200°,46.00,2006-03-07 16:42:37,,,$ +%,109,N56.125967° E13.742117°,46.00,2006-03-07 16:42:58,,,$ +%,110,N56.125783° E13.741983°,46.00,2006-03-07 16:43:16,,,$ +%,111,N56.125283° E13.741733°,47.00,2006-03-07 16:43:54,,,$ +%,112,N56.124767° E13.741467°,46.00,2006-03-07 16:44:36,,,$ +%,113,N56.124433° E13.741283°,44.00,2006-03-07 16:45:04,,,$ +%,114,N56.124000° E13.741000°,44.00,2006-03-07 16:45:38,,,$ +%,115,N56.123483° E13.740717°,44.00,2006-03-07 16:46:20,,,$ +%,116,N56.122933° E13.740550°,46.00,2006-03-07 16:47:02,,,$ +%,117,N56.122417° E13.740450°,49.00,2006-03-07 16:47:40,,,$ +%,118,N56.121817° E13.740283°,50.00,2006-03-07 16:48:25,,,$ +%,119,N56.121250° E13.740083°,51.00,2006-03-07 16:49:07,,,$ +%,120,N56.121133° E13.739983°,51.00,2006-03-07 16:49:31,,,$ +%,121,N56.121033° E13.739950°,52.00,2006-03-07 16:49:52,,,$ +%,122,N56.120983° E13.739950°,52.00,2006-03-07 16:50:18,,,$ +%,123,N56.120617° E13.739783°,52.00,2006-03-07 16:50:49,,,$ +%,124,N56.120267° E13.739600°,52.00,2006-03-07 16:51:23,,,$ +%,125,N56.120067° E13.739583°,53.00,2006-03-07 16:51:56,,,$ +%,126,N56.119800° E13.739500°,53.00,2006-03-07 16:52:26,,,$ +%,127,N56.119800° E13.739500°,52.00,2006-03-07 16:52:35,,,$ +%,128,N56.119233° E13.739567°,52.00,2006-03-07 16:53:17,,,$ +%,129,N56.118650° E13.739667°,51.00,2006-03-07 16:54:00,,,$ +%,130,N56.118050° E13.740033°,51.00,2006-03-07 16:54:47,,,$ +%,131,N56.117600° E13.740383°,50.00,2006-03-07 16:55:24,,,$ +%,132,N56.117067° E13.740550°,49.00,2006-03-07 16:56:05,,,$ +%,133,N56.116383° E13.740600°,50.00,2006-03-07 16:56:54,,,$ +%,134,N56.115950° E13.740617°,52.00,2006-03-07 16:57:27,,,$ +%,135,N56.115367° E13.740633°,52.00,2006-03-07 16:58:11,,,$ +%,136,N56.115033° E13.739867°,48.00,2006-03-07 16:58:52,,,$ +%,137,N56.114967° E13.739000°,46.00,2006-03-07 16:59:27,,,$ +%,138,N56.115017° E13.738233°,47.00,2006-03-07 16:59:57,,,$ +%,139,N56.115067° E13.737550°,46.00,2006-03-07 17:00:26,,,$ +%,140,N56.115367° E13.736733°,45.00,2006-03-07 17:01:07,,,$ +%,141,N56.115833° E13.736367°,44.00,2006-03-07 17:01:45,,,$ +%,142,N56.116317° E13.736017°,45.00,2006-03-07 17:02:25,,,$ +%,143,N56.116633° E13.735867°,44.00,2006-03-07 17:02:50,,,$ +%,144,N56.117217° E13.735650°,44.00,2006-03-07 17:03:32,,,$ +%,145,N56.117817° E13.735567°,45.00,2006-03-07 17:04:17,,,$ +%,146,N56.118400° E13.735417°,45.00,2006-03-07 17:04:59,,,$ +%,147,N56.118533° E13.735200°,45.00,2006-03-07 17:05:11,,,$ +%,148,N56.118933° E13.735167°,44.00,2006-03-07 17:05:43,,,$ +%,149,N56.119150° E13.735117°,44.00,2006-03-07 17:05:58,,,$ +%,150,N56.119267° E13.734750°,44.00,2006-03-07 17:06:16,,,$ +%,151,N56.119583° E13.734867°,44.00,2006-03-07 17:06:41,,,$ +%,152,N56.119833° E13.734333°,43.00,2006-03-07 17:07:15,,,$ +%,153,N56.120067° E13.734033°,43.00,2006-03-07 17:07:38,,,$ +%,154,N56.120283° E13.733883°,43.00,2006-03-07 17:07:59,,,$ +%,155,N56.120350° E13.733850°,43.00,2006-03-07 17:08:27,,,$ +%,156,N56.120350° E13.733850°,43.00,2006-03-07 17:08:35,,,$ +%,157,N56.120667° E13.733267°,41.00,2006-03-07 17:09:12,,,$ +%,158,N56.120933° E13.732717°,41.00,2006-03-07 17:09:45,,,$ +%,159,N56.121167° E13.732217°,40.00,2006-03-07 17:10:14,,,$ +%,160,N56.121450° E13.731583°,40.00,2006-03-07 17:10:51,,,$ +%,161,N56.121783° E13.730833°,41.00,2006-03-07 17:11:35,,,$ +%,162,N56.122033° E13.730100°,41.00,2006-03-07 17:12:14,,,$ +%,163,N56.122283° E13.729500°,40.00,2006-03-07 17:12:47,,,$ +%,164,N56.122583° E13.728817°,39.00,2006-03-07 17:13:27,,,$ +%,165,N56.122883° E13.728083°,40.00,2006-03-07 17:14:09,,,$ +%,166,N56.123167° E13.727433°,41.00,2006-03-07 17:14:48,,,$ +%,167,N56.123267° E13.727200°,41.00,2006-03-07 17:15:08,,,$ +%,168,N56.123450° E13.726867°,41.00,2006-03-07 17:15:32,,,$ +%,169,N56.123633° E13.726383°,40.00,2006-03-07 17:15:59,,,$ +%,170,N56.123900° E13.725867°,40.00,2006-03-07 17:16:30,,,$ +%,171,N56.124217° E13.725250°,39.00,2006-03-07 17:17:09,,,$ +%,172,N56.124467° E13.724750°,40.00,2006-03-07 17:17:41,,,$ +%,173,N56.124733° E13.724117°,39.00,2006-03-07 17:18:17,,,$ +%,174,N56.124833° E13.723750°,38.00,2006-03-07 17:18:45,,,$ +%,175,N56.124950° E13.723450°,38.00,2006-03-07 17:19:21,,,$ +%,176,N56.125200° E13.722850°,38.00,2006-03-07 17:19:54,,,$ +%,177,N56.125333° E13.722567°,38.00,2006-03-07 17:20:12,,,$ +%,178,N56.125400° E13.722317°,38.00,2006-03-07 17:20:29,,,$ +%,179,N56.125467° E13.722500°,39.00,2006-03-07 17:20:39,,,$ +%,180,N56.125783° E13.722650°,40.00,2006-03-07 17:21:06,,,$ +%,181,N56.125817° E13.722667°,40.00,2006-03-07 17:21:11,,,$ +%,182,N56.125883° E13.722650°,40.00,2006-03-07 17:21:16,,,$ +%,183,N56.125850° E13.722367°,41.00,2006-03-07 17:21:32,,,$ +%,184,N56.125867° E13.722133°,41.00,2006-03-07 17:21:56,,,$ +%,185,N56.125867° E13.722050°,42.00,2006-03-07 17:22:16,,,$ +%,186,N56.125850° E13.722050°,41.00,2006-03-07 17:22:52,,,$ +%,187,N56.125867° E13.721950°,41.00,2006-03-07 17:23:10,,,$ +%,188,N56.125917° E13.721967°,41.00,2006-03-07 17:23:30,,,$ +%,189,N56.125883° E13.721967°,41.00,2006-03-07 17:24:15,,,$ +%,190,N56.125867° E13.722167°,38.00,2006-03-07 17:33:44,,,$ +%,191,N56.125800° E13.722217°,38.00,2006-03-07 17:34:10,,,$ +%,192,N56.125783° E13.722250°,40.00,2006-03-07 17:34:40,,,$ +%,193,N56.125783° E13.722200°,40.00,2006-03-07 17:34:58,,,$ +%,194,N56.125817° E13.722317°,41.00,2006-03-07 17:35:12,,,$ +%,195,N56.125817° E13.722317°,40.00,2006-03-07 17:35:52,,,$ diff --git a/reference/track/trackfilter-new.gpx b/reference/track/trackfilter-new.gpx new file mode 100644 index 000000000..faf61117a --- /dev/null +++ b/reference/track/trackfilter-new.gpx @@ -0,0 +1,280 @@ + + + + + LOG-20020525 + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 2.000000 + + + + 1.000000 + + + + 1.000000 + + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + LOG-20020526 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 7.000000 + + + + 0.000000 + + + + + + LOG-20020527 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/trackfilter-sdistance.gpx b/reference/track/trackfilter-sdistance.gpx new file mode 100644 index 000000000..abf54560c --- /dev/null +++ b/reference/track/trackfilter-sdistance.gpx @@ -0,0 +1,366 @@ + + + + + + LOG-20020525-20020525 + + + 1.000000 + + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 1.000000 + + + + + + 20020525 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + 2.000000 + + + + 1.000000 + + + + 1.000000 + + + + 0.000000 + + + + + + 20020525 + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020525 + + + 6.000000 + + + + + + 20020525 + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 1.000000 + + + + + + 20020525 + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020526 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 7.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020527 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/trackfilter-sdistance2.gpx b/reference/track/trackfilter-sdistance2.gpx new file mode 100644 index 000000000..2ca22488b --- /dev/null +++ b/reference/track/trackfilter-sdistance2.gpx @@ -0,0 +1,281 @@ + + + + + + 20020525 + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 2.000000 + + + + 1.000000 + + + + 1.000000 + + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020526 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 7.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/trackfilter.gpx b/reference/track/trackfilter.gpx new file mode 100644 index 000000000..9ebd3ae68 --- /dev/null +++ b/reference/track/trackfilter.gpx @@ -0,0 +1,281 @@ + + + + + + LOG-20020525 + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 2.000000 + + + + 1.000000 + + + + 1.000000 + + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + LOG-20020526 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 7.000000 + + + + 0.000000 + + + + + + LOG-20020527 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/tracks.gpssim b/reference/track/tracks.gpssim new file mode 100644 index 000000000..5ba41390e --- /dev/null +++ b/reference/track/tracks.gpssim @@ -0,0 +1,128 @@ +$FRSPD,0.02*63 +$FRWPT,3003.73100,N,09136.62100,W,1.0,250502,170621*63 +$FRSPD,0.64*63 +$FRWPT,3003.76700,N,09136.63400,W,0.0,250502,170955*69 +$FRSPD,3.45*63 +$FRWPT,3003.76200,N,09136.49600,W,0.0,250502,171200*6C +$FRSPD,3.82*68 +$FRWPT,3003.74000,N,09136.44300,W,0.0,250502,171248*68 +$FRSPD,3.80*6A +$FRWPT,3003.69200,N,09136.31700,W,0.0,250502,171441*6F +$FRSPD,7.52*61 +$FRWPT,3003.58700,N,09135.96400,W,0.0,250502,171716*64 +$FRSPD,22.19*59 +$FRWPT,3003.46800,N,09135.80100,W,0.0,250502,171746*63 +$FRSPD,18.25*5F +$FRWPT,3003.32300,N,09135.69400,W,0.0,250502,171820*66 +$FRSPD,13.09*5A +$FRWPT,3003.23300,N,09135.55700,W,0.0,250502,171901*68 +$FRSPD,9.96*67 +$FRWPT,3002.98400,N,09135.38500,W,0.0,250502,172046*6E +$FRSPD,6.54*66 +$FRWPT,3002.94100,N,09135.39300,W,0.0,250502,172110*62 +$FRSPD,13.98*52 +$FRWPT,3002.92800,N,09135.57600,W,0.0,250502,172151*65 +$FRSPD,19.58*54 +$FRWPT,3002.77400,N,09135.78700,W,0.0,250502,172235*6F +$FRSPD,13.70*54 +$FRWPT,3002.73100,N,09135.92300,W,0.0,250502,172308*61 +$FRSPD,0.20*63 +$FRWPT,3002.83800,N,09136.01600,W,0.0,250502,180423*68 +$FRSPD,1.34*67 +$FRWPT,3002.82000,N,09135.97800,W,2.0,250502,180604*66 +$FRSPD,2.04*67 +$FRWPT,3002.78600,N,09135.96800,W,0.0,250502,180706*65 +$FRSPD,1.52*67 +$FRWPT,3002.77200,N,09135.93700,W,1.0,250502,180818*65 +$FRSPD,1.89*61 +$FRWPT,3002.78200,N,09135.86400,W,0.0,250502,181020*6E +$FRSPD,2.17*65 +$FRWPT,3002.78100,N,09135.83000,W,0.0,250502,181109*66 +$FRSPD,2.64*61 +$FRWPT,3002.80700,N,09135.78000,W,0.0,250502,181218*60 +$FRSPD,2.07*64 +$FRWPT,3002.84700,N,09135.71200,W,0.0,250502,181422*60 +$FRSPD,2.64*61 +$FRWPT,3002.86800,N,09135.68600,W,2.0,250502,181504*66 +$FRSPD,2.30*60 +$FRWPT,3002.89500,N,09135.64500,W,1.0,250502,181614*6A +$FRSPD,2.29*68 +$FRWPT,3002.92100,N,09135.62800,W,1.0,250502,181701*6A +$FRSPD,2.19*6B +$FRWPT,3002.96100,N,09135.63100,W,0.0,250502,181807*6E +$FRSPD,2.03*60 +$FRWPT,3003.01900,N,09135.63900,W,2.0,250502,181951*61 +$FRSPD,2.17*65 +$FRWPT,3003.04700,N,09135.64700,W,0.0,250502,182039*65 +$FRSPD,2.40*67 +$FRWPT,3003.07400,N,09135.66200,W,0.0,250502,182124*6F +$FRSPD,2.31*61 +$FRWPT,3003.10800,N,09135.66200,W,0.0,250502,182217*66 +$FRSPD,1.74*63 +$FRWPT,3003.13300,N,09135.68000,W,0.0,250502,182318*6C +$FRSPD,2.19*6B +$FRWPT,3003.18100,N,09135.68100,W,0.0,250502,182437*6E +$FRSPD,1.91*68 +$FRWPT,3003.29200,N,09135.71200,W,6.0,250502,182813*68 +$FRSPD,1.23*61 +$FRWPT,3003.22400,N,09135.69600,W,2.0,250502,183136*63 +$FRSPD,1.53*66 +$FRWPT,3003.19100,N,09135.68700,W,0.0,250502,183256*69 +$FRSPD,1.81*69 +$FRWPT,3003.15800,N,09135.69000,W,0.0,250502,183402*6D +$FRSPD,0.98*60 +$FRWPT,3003.14700,N,09135.72600,W,0.0,250502,183603*6C +$FRSPD,2.23*62 +$FRWPT,3003.14900,N,09135.75800,W,0.0,250502,183648*64 +$FRSPD,2.46*61 +$FRWPT,3003.15900,N,09135.80700,W,1.0,250502,183752*6B +$FRSPD,2.62*67 +$FRWPT,3003.18800,N,09135.87100,W,0.0,250502,183918*67 +$FRSPD,1.87*6F +$FRWPT,3003.21700,N,09135.87800,W,0.0,250502,184015*68 +$FRSPD,1.21*63 +$FRWPT,3003.23800,N,09135.86600,W,6.0,250502,184125*6E +$FRSPD,1.34*67 +$FRWPT,3003.21700,N,09135.88500,W,0.0,250502,184237*68 +$FRSPD,1.14*65 +$FRWPT,3003.19200,N,09135.87500,W,0.0,250502,184401*6A +$FRSPD,1.00*60 +$FRWPT,3003.16900,N,09135.85100,W,0.0,250502,184553*6E +$FRSPD,2.00*63 +$FRWPT,3003.15400,N,09135.81600,W,0.0,250502,184654*67 +$FRSPD,2.22*63 +$FRWPT,3003.14000,N,09135.78600,W,0.0,250502,184742*62 +$FRSPD,2.40*67 +$FRWPT,3003.13500,N,09135.74100,W,0.0,250502,184841*67 +$FRSPD,1.76*61 +$FRWPT,3003.13300,N,09135.70100,W,0.0,250502,184952*66 +$FRSPD,1.64*62 +$FRWPT,3003.11300,N,09135.68200,W,0.0,250502,185049*6C +$FRSPD,2.22*63 +$FRWPT,3003.06300,N,09135.66400,W,0.0,250502,185214*68 +$FRSPD,2.60*65 +$FRWPT,3003.03400,N,09135.65400,W,0.0,250502,185256*6F +$FRSPD,2.06*65 +$FRWPT,3003.01100,N,09135.64600,W,0.0,250502,185338*62 +$FRSPD,2.64*61 +$FRWPT,3002.94600,N,09135.62300,W,0.0,250502,185511*66 +$FRSPD,2.13*61 +$FRWPT,3002.90700,N,09135.65500,W,0.0,250502,185632*60 +$FRSPD,2.36*66 +$FRWPT,3002.88500,N,09135.68500,W,0.0,250502,185724*60 +$FRSPD,2.39*69 +$FRWPT,3002.85000,N,09135.72700,W,7.0,250502,185840*6B +$FRSPD,2.90*6A +$FRWPT,3002.82400,N,09135.76000,W,0.0,250502,185928*63 +$FRSPD,2.71*65 +$FRWPT,3002.79800,N,09135.79600,W,0.0,250502,190022*65 +$FRSPD,2.57*61 +$FRWPT,3002.78400,N,09135.85900,W,0.0,250502,190141*60 +$FRSPD,2.35*65 +$FRWPT,3002.77400,N,09135.90800,W,0.0,250502,190248*60 +$FRSPD,1.73*64 +$FRWPT,3002.77900,N,09135.93800,W,0.0,250502,190343*64 +$FRSPD,1.77*60 +$FRWPT,3002.80700,N,09135.95700,W,0.0,250502,190449*66 +$FRSPD,1.53*66 +$FRWPT,3002.82800,N,09135.98000,W,0.0,250502,190557*6F diff --git a/reference/track/tracks.gpx b/reference/track/tracks.gpx new file mode 100644 index 000000000..1b510a9c0 --- /dev/null +++ b/reference/track/tracks.gpx @@ -0,0 +1,271 @@ + + + + + + meridian + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 2.000000 + + + + 1.000000 + + + + 1.000000 + + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 7.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/vidaone.csv b/reference/track/vidaone.csv new file mode 100644 index 000000000..a44e84a54 --- /dev/null +++ b/reference/track/vidaone.csv @@ -0,0 +1,65 @@ +No,Latitude,Longitude +1,30.062183,-91.610350 +2,30.062783,-91.610567 +3,30.062700,-91.608267 +4,30.062333,-91.607383 +5,30.061533,-91.605283 +6,30.059783,-91.599400 +7,30.057800,-91.596683 +8,30.055383,-91.594900 +9,30.053883,-91.592617 +10,30.049733,-91.589750 +11,30.049017,-91.589883 +12,30.048800,-91.592933 +13,30.046233,-91.596450 +14,30.045517,-91.598717 +15,30.047300,-91.600267 +16,30.047000,-91.599633 +17,30.046433,-91.599467 +18,30.046200,-91.598950 +19,30.046367,-91.597733 +20,30.046350,-91.597167 +21,30.046783,-91.596333 +22,30.047450,-91.595200 +23,30.047800,-91.594767 +24,30.048250,-91.594083 +25,30.048683,-91.593800 +26,30.049350,-91.593850 +27,30.050317,-91.593983 +28,30.050783,-91.594117 +29,30.051233,-91.594367 +30,30.051800,-91.594367 +31,30.052217,-91.594667 +32,30.053017,-91.594683 +33,30.054867,-91.595200 +34,30.053733,-91.594933 +35,30.053183,-91.594783 +36,30.052633,-91.594833 +37,30.052450,-91.595433 +38,30.052483,-91.595967 +39,30.052650,-91.596783 +40,30.053133,-91.597850 +41,30.053617,-91.597967 +42,30.053967,-91.597767 +43,30.053617,-91.598083 +44,30.053200,-91.597917 +45,30.052817,-91.597517 +46,30.052567,-91.596933 +47,30.052333,-91.596433 +48,30.052250,-91.595683 +49,30.052217,-91.595017 +50,30.051883,-91.594700 +51,30.051050,-91.594400 +52,30.050567,-91.594233 +53,30.050183,-91.594100 +54,30.049100,-91.593717 +55,30.048450,-91.594250 +56,30.048083,-91.594750 +57,30.047500,-91.595450 +58,30.047067,-91.596000 +59,30.046633,-91.596600 +60,30.046400,-91.597650 +61,30.046233,-91.598467 +62,30.046317,-91.598967 +63,30.046783,-91.599283 +64,30.047133,-91.599667 diff --git a/reference/track/vidaone.gpb b/reference/track/vidaone.gpb new file mode 100644 index 0000000000000000000000000000000000000000..897f846b89e7da9fb4a44c4d181eec3d5d96b3f0 GIT binary patch literal 1280 zcmZA1c`(#r7zgmp#+qc^v$V9MVmeq>8cf>#ZM8+&YRzaSE!m6?)tay@QVlsekVuEK zbc|B6DHX9u<0zr2&_PkIRJMd9J$QaIP5b9(zRx`SzR&yoCcLtp`gOR3U~S;2PWNUd z1%7#D-;e9-atT9zMw|g!qHI4?8;q%Qw`JhdbZ$|IJ$(pjyc!o(d1eS79IqneIYVcXd{0#23}}!3FYT3 zXDjRxvHKY1Dp*}EQzAlZFcGyep*Ase?PGtmuwF}!CRl5b5<3qxMyA!BcVOazUOpdf&yt^K-h$B@zm7Se@zf5DjDqEwcZwFHjdDKS zw1B?)mmgLz&3Oms0oty4d*$I^Ro~qUIcV9N zn^@<;fHOs*I=%|qANNJa?b2) zg4Jled%G@d`9yYcEX(*5D+!v`5={SWDpt=CMgMv;@t~;V9n+jHODu&O#&a z*`$kIX^7VC;AZavxpO6HC&_yrmUU$4fkoT6T_NYD8fo<{VDK_Z z$v5)ieoUHd0{5sq(#&xu*wjv7t>?jx#T&s?&BE>EjKoQmLkq#C_6c+G_nc18 z2Fsaa^Ol^4VPEh3Z}9Hx>>d@eG1m~^{H_Dc$gK7w4~^Vk`s7Cd?KW?d^flz-j0?iZ beIxgX6>W6Y6LZ5!F+IA_*LRy@klf$Dw$0P2 literal 0 HcmV?d00001 diff --git a/reference/track/vitosmt_t.gpx b/reference/track/vitosmt_t.gpx new file mode 100644 index 000000000..c86662c12 --- /dev/null +++ b/reference/track/vitosmt_t.gpx @@ -0,0 +1,2204 @@ + + + + + + + + 33.700000 + + 0.000000 + 0.000000 + WP0001 + 2d + 3 + 30.600000 + + + 33.700000 + + 0.000000 + 0.000000 + WP0002 + 2d + 3 + 30.600000 + + + 105.400000 + + 251.259995 + 1.419867 + WP0003 + dgps + 7 + 1.400000 + + + 104.600000 + + 260.420013 + 1.450733 + WP0004 + dgps + 5 + 2.400000 + + + 102.500000 + + 232.600006 + 0.334389 + WP0005 + dgps + 5 + 2.400000 + + + 108.900000 + + 297.440002 + 1.106055 + WP0006 + dgps + 6 + 2.200000 + + + 108.400000 + + 290.190002 + 1.162644 + WP0007 + dgps + 9 + 1.000000 + + + 110.600000 + + 30.709999 + 1.111200 + WP0008 + dgps + 8 + 1.400000 + + + 106.200000 + + 32.630001 + 0.185200 + WP0009 + dgps + 10 + 1.000000 + + + 34.100000 + + 0.000000 + 0.000000 + WP0010 + 2d + 3 + 7.000000 + + + -22.300000 + + 150.550003 + 1.476456 + WP0011 + dgps + 5 + 2.600000 + + + -34.800000 + + 140.809998 + 1.533044 + WP0012 + 3d + 4 + 3.400000 + + + -28.700000 + + 165.830002 + 1.342700 + WP0013 + dgps + 5 + 2.600000 + + + -21.000000 + + 166.179993 + 0.735656 + WP0014 + 3d + 4 + 3.800000 + + + -25.300000 + + 114.070000 + 1.507322 + WP0015 + 2 + + + 43.400000 + + 79.120003 + 1.517611 + WP0016 + 3d + 4 + 3.800000 + + + 39.300000 + + 65.169998 + 1.378711 + WP0017 + dgps + 6 + 1.600000 + + + 48.300000 + + 87.449997 + 1.260389 + WP0018 + dgps + 5 + 1.600000 + + + 44.500000 + + 88.230003 + 1.476456 + WP0019 + dgps + 5 + 1.600000 + + + 39.900000 + + 68.449997 + 1.558767 + WP0020 + dgps + 5 + 2.600000 + + + 23.600000 + + 140.080002 + 0.138900 + WP0021 + dgps + 5 + 2.600000 + + + 46.700000 + + 114.720001 + 0.195489 + WP0022 + 3d + 4 + 4.000000 + + + 61.300000 + + 128.500000 + 0.169767 + WP0023 + dgps + 5 + 1.600000 + + + 74.600000 + + 0.890000 + 0.262367 + WP0024 + 3d + 4 + 4.000000 + + + 63.600000 + + 214.169998 + 0.144044 + WP0025 + 3d + 4 + 2.200000 + + + 83.600000 + + 156.059998 + 0.205778 + WP0026 + 3d + 4 + 5.200000 + + + 76.200000 + + 136.899994 + 0.082311 + WP0027 + 3d + 4 + 5.200000 + + + 76.300000 + + 151.399994 + 0.108033 + WP0028 + 2d + 3 + 10.600000 + + + 59.800000 + + 0.000000 + 0.000000 + WP0029 + 3d + 4 + 5.200000 + + + 34.300000 + + 0.000000 + 0.000000 + WP0030 + 2d + 3 + 25.400000 + + + 34.300000 + + 0.000000 + 0.000000 + WP0031 + 2d + 3 + 28.200001 + + + 34.300000 + + 157.210007 + 0.036011 + WP0032 + 2d + 3 + 28.200001 + + + 70.800000 + + 31.549999 + 0.118322 + WP0033 + dgps + 5 + 1.800000 + + + 61.200000 + + 160.520004 + 1.044322 + WP0034 + 3d + 4 + 2.000000 + + + 62.400000 + + 162.570007 + 0.102889 + WP0035 + 1 + + + 54.200000 + + 66.839996 + 0.411556 + WP0036 + 3d + 4 + 6.800000 + + + 57.000000 + + 0.000000 + 0.000000 + WP0037 + 3d + 4 + 19.400000 + + + 0.000000 + + 0.000000 + 0.000000 + WP0038 + 24.700001 + + + 57.600000 + + 0.000000 + 0.000000 + WP0039 + 3d + 4 + 17.799999 + + + 74.800000 + + 51.320000 + 0.087456 + WP0040 + dgps + 7 + 1.000000 + + + 95.100000 + + 22.510000 + 0.092600 + WP0041 + dgps + 5 + 1.600000 + + + 69.100000 + + 272.899994 + 1.208944 + WP0042 + dgps + 7 + 1.000000 + + + 71.300000 + + 304.450012 + 1.188367 + WP0043 + dgps + 7 + 1.000000 + + + 71.300000 + + 321.899994 + 1.332411 + WP0044 + dgps + 6 + 1.400000 + + + 71.300000 + + 346.209991 + 0.853978 + WP0045 + dgps + 6 + 1.400000 + + + 70.700000 + + 31.530001 + 0.041156 + WP0046 + dgps + 6 + 1.400000 + + + 68.400000 + + 124.980003 + 0.807678 + WP0047 + dgps + 6 + 1.200000 + + + 72.900000 + + 301.549988 + 1.301544 + WP0048 + dgps + 6 + 1.200000 + + + 71.400000 + + 312.899994 + 0.488722 + WP0049 + dgps + 7 + 1.000000 + + + 71.200000 + + 54.860001 + 0.077167 + WP0050 + dgps + 8 + 1.000000 + + + 71.600000 + + 338.209991 + 1.821133 + WP0051 + dgps + 7 + 1.400000 + + + 71.000000 + + 300.459991 + 0.632767 + WP0052 + 2 + + + 72.100000 + + 306.429993 + 1.059756 + WP0053 + 2 + + + 72.700000 + + 284.540009 + 0.967156 + WP0054 + 2d + 3 + 6.200000 + + + 72.200000 + + 310.510010 + 0.648200 + WP0055 + 2 + + + 72.500000 + + 208.550003 + 0.529878 + WP0056 + 2 + + + 73.000000 + + 292.980011 + 1.574200 + WP0057 + 2 + + + 73.300000 + + 348.260010 + 1.409578 + WP0058 + 2d + 3 + 19.400000 + + + 78.100000 + + 357.940002 + 1.352989 + WP0059 + 2d + 3 + 6.000000 + + + 77.000000 + + 341.100006 + 0.905422 + WP0060 + 3d + 4 + 4.200000 + + + 75.500000 + + 11.500000 + 0.216067 + WP0061 + 3d + 4 + 4.200000 + + + 71.000000 + + 26.420000 + 0.807678 + WP0062 + 3d + 4 + 12.400000 + + + 75.800000 + + 37.529999 + 1.188367 + WP0063 + 3d + 4 + 4.200000 + + + 72.600000 + + 48.630001 + 1.527900 + WP0064 + dgps + 6 + 1.600000 + + + 70.300000 + + 26.750000 + 1.059756 + WP0065 + dgps + 5 + 2.800000 + + + 74.600000 + + 201.380005 + 0.843689 + WP0066 + dgps + 5 + 1.800000 + + + 76.300000 + + 117.099998 + 0.457856 + WP0067 + dgps + 5 + 1.600000 + + + 72.100000 + + 130.149994 + 0.149189 + WP0068 + 2d + 3 + 5.200000 + + + 80.900000 + + 129.250000 + 0.313811 + WP0069 + 3d + 4 + 4.000000 + + + 89.500000 + + 87.769997 + 0.061733 + WP0070 + 3d + 4 + 4.000000 + + + 102.100000 + + 164.850006 + 0.123467 + WP0071 + 3d + 4 + 2.200000 + + + 102.800000 + + 244.000000 + 0.396122 + WP0072 + 2d + 3 + 13.400000 + + + 94.100000 + + 86.839996 + 0.812822 + WP0073 + dgps + 5 + 1.600000 + + + 93.300000 + + 216.110001 + 0.118322 + WP0074 + dgps + 5 + 1.600000 + + + 83.800000 + + 250.699997 + 1.198656 + WP0075 + 2 + + + 85.100000 + + 238.919998 + 1.656511 + WP0076 + 2 + + + 85.600000 + + 235.460007 + 1.718244 + WP0077 + 2d + 3 + 16.000000 + + + 85.900000 + + 248.250000 + 1.342700 + WP0078 + 2 + + + 85.200000 + + 260.279999 + 0.992878 + WP0079 + 3d + 4 + 2.400000 + + + 87.100000 + + 215.869995 + 1.270678 + WP0080 + 3d + 4 + 3.200000 + + + 82.300000 + + 238.919998 + 1.095767 + WP0081 + dgps + 6 + 1.200000 + + + 78.800000 + + 235.889999 + 0.992878 + WP0082 + 3d + 4 + 2.400000 + + + 75.500000 + + 228.059998 + 0.987733 + WP0083 + dgps + 5 + 1.400000 + + + 74.100000 + + 322.799988 + 1.152356 + WP0084 + 3d + 4 + 2.000000 + + + 72.500000 + + 333.309998 + 0.468144 + WP0085 + 2 + + + 74.000000 + + 154.389999 + 1.275822 + WP0086 + 2d + 3 + 40.599998 + + + 74.700000 + + 197.889999 + 1.234667 + WP0087 + 3d + 4 + 2.000000 + + + 72.300000 + + 194.039993 + 0.365256 + WP0088 + + + 72.200000 + + 237.380005 + 0.776811 + WP0089 + + + 73.000000 + + 272.200012 + 0.874556 + WP0090 + 2d + 3 + 38.200001 + + + 74.400000 + + 214.550003 + 0.174911 + WP0091 + 2 + + + 81.200000 + + 209.389999 + 0.216067 + WP0092 + 2d + 3 + 37.200001 + + + 70.100000 + + 256.739990 + 0.673922 + WP0093 + 3d + 4 + 9.400000 + + + 64.400000 + + 294.750000 + 0.817967 + WP0094 + 2 + + + 64.000000 + + 174.509995 + 0.617333 + WP0095 + 1 + + + 64.600000 + + 122.470001 + 0.720222 + WP0096 + 2d + 3 + 23.000000 + + + 67.300000 + + 189.600006 + 0.128611 + WP0097 + 2d + 3 + 5.200000 + + + 71.400000 + + 182.949997 + 0.108033 + WP0098 + 3d + 4 + 43.599998 + + + 71.700000 + + 52.070000 + 0.164622 + WP0099 + 2d + 3 + 24.200001 + + + 72.300000 + + 155.990005 + 0.113178 + WP0100 + 3d + 4 + 2.200000 + + + 81.200000 + + 97.730003 + 1.111200 + WP0101 + 2d + 3 + 36.400002 + + + 74.500000 + + 50.860001 + 1.625644 + WP0102 + 2 + + + 74.700000 + + 44.029999 + 1.347844 + WP0103 + 2d + 3 + 13.600000 + + + 76.200000 + + 82.080002 + 0.715078 + WP0104 + 2d + 3 + 50.000000 + + + 77.900000 + + 80.239998 + 0.745944 + WP0105 + 2d + 3 + 26.400000 + + + 78.600000 + + 47.939999 + 1.733678 + WP0106 + 3d + 4 + 50.000000 + + + 80.700000 + + 62.310001 + 1.116344 + WP0107 + dgps + 5 + 1.600000 + + + 84.400000 + + 59.770000 + 1.435300 + WP0108 + 2 + + + 92.600000 + + 57.660000 + 1.260389 + WP0109 + dgps + 5 + 2.000000 + + + 95.800000 + + 55.730000 + 1.399289 + WP0110 + 3d + 4 + 5.000000 + + + 94.700000 + + 28.459999 + 1.286111 + WP0111 + dgps + 7 + 0.800000 + + + 59.200000 + + 245.169998 + 0.972300 + WP0112 + 3d + 4 + 9.400000 + + + 55.200000 + + 240.100006 + 1.553622 + WP0113 + 2d + 3 + 6.000000 + + + 56.100000 + + 238.809998 + 1.265533 + WP0114 + 2d + 3 + 7.600000 + + + 54.500000 + + 242.740005 + 1.183222 + WP0115 + 3d + 4 + 11.800000 + + + 48.700000 + + 236.539993 + 1.003167 + WP0116 + 2 + + + 43.700000 + + 261.720001 + 1.713100 + WP0117 + 2d + 3 + 7.200000 + + + 45.100000 + + 298.739990 + 1.265533 + WP0118 + 2 + + + 44.600000 + + 313.660004 + 1.188367 + WP0119 + 3d + 4 + 16.600000 + + + 44.100000 + + 330.829987 + 1.347844 + WP0120 + 2 + + + 43.000000 + + 334.989990 + 1.198656 + WP0121 + 2 + + + 42.000000 + + 341.049988 + 1.687378 + WP0122 + 2d + 3 + 7.200000 + + + 41.400000 + + 1.620000 + 1.594778 + WP0123 + 2d + 3 + 6.800000 + + + 41.600000 + + 18.180000 + 1.106055 + WP0124 + 2d + 3 + 6.800000 + + + 41.600000 + + 10.700000 + 1.311833 + WP0125 + 1 + + + 41.600000 + + 333.260010 + 0.766522 + WP0126 + 2d + 3 + 7.000000 + + + 41.600000 + + 348.489990 + 1.126633 + WP0127 + 2 + + + 41.600000 + + 335.130005 + 1.106055 + WP0128 + 2 + + + 41.600000 + + 356.950012 + 1.733678 + WP0129 + 2 + + + 41.600000 + + 344.679993 + 0.977444 + WP0130 + 2 + + + 41.600000 + + 69.209999 + 1.239811 + WP0131 + 1 + + + 41.600000 + + 83.389999 + 1.491889 + WP0132 + 2d + 3 + 7.400000 + + + 41.700000 + + 93.379997 + 1.569056 + WP0133 + 3d + 4 + 33.799999 + + + 41.700000 + + 105.099998 + 1.831422 + WP0134 + 2d + 3 + 6.800000 + + + 41.800000 + + 63.990002 + 1.373567 + WP0135 + 2 + + + 42.300000 + + 67.769997 + 1.769689 + WP0136 + 3d + 4 + 21.799999 + + + 45.200000 + + 108.410004 + 1.358133 + WP0137 + 2d + 3 + 7.000000 + + + 46.700000 + + 104.510002 + 1.219233 + WP0138 + 2d + 3 + 8.400000 + + + 47.400000 + + 260.720001 + 1.023744 + WP0139 + 2d + 3 + 8.600000 + + + 48.300000 + + 274.910004 + 1.399289 + WP0140 + 2 + + + 49.000000 + + 252.429993 + 0.802533 + WP0141 + + + 49.400000 + + 174.869995 + 0.504156 + WP0142 + 2 + + + 49.900000 + + 223.550003 + 0.838544 + WP0143 + 3d + 4 + 8.200000 + + + 49.500000 + + 255.070007 + 1.244956 + WP0144 + 2d + 3 + 6.400000 + + + 55.000000 + + 267.149994 + 1.080333 + WP0145 + 2d + 3 + 9.400000 + + + 56.600000 + + 158.740005 + 0.761378 + WP0146 + 2d + 3 + 5.400000 + + + 56.100000 + + 233.080002 + 1.121489 + WP0147 + 2d + 3 + 10.000000 + + + 56.700000 + + 150.190002 + 0.169767 + WP0148 + 2 + + + 70.600000 + + 155.179993 + 0.915711 + WP0149 + 3d + 4 + 5.200000 + + + 75.600000 + + 137.089996 + 0.571033 + WP0150 + 3d + 4 + 5.000000 + + + 76.100000 + + 356.690002 + 0.226356 + WP0151 + 2d + 3 + 10.600000 + + + 77.400000 + + 233.190002 + 0.926000 + WP0152 + 2d + 3 + 6.400000 + + + 84.500000 + + 66.459999 + 1.075189 + WP0153 + 1 + + + 90.200000 + + 285.640015 + 0.853978 + WP0154 + 2 + + + 93.200000 + + 250.550003 + 1.214089 + WP0155 + 2 + + + 94.400000 + + 245.679993 + 1.100911 + WP0156 + 2d + 3 + 6.400000 + + + 95.400000 + + 244.559998 + 1.188367 + WP0157 + 2 + + + 96.500000 + + 262.299988 + 1.671944 + WP0158 + 2d + 3 + 6.200000 + + + 96.300000 + + 207.820007 + 1.070044 + WP0159 + 2 + + + 97.000000 + + 269.070007 + 1.404433 + WP0160 + 2d + 3 + 6.200000 + + + 96.900000 + + 229.419998 + 0.982589 + WP0161 + 2 + + + 98.200000 + + 242.610001 + 0.730511 + WP0162 + 2d + 3 + 6.200000 + + + 98.600000 + + 220.550003 + 1.497033 + WP0163 + 2d + 3 + 6.200000 + + + 98.400000 + + 237.889999 + 1.106055 + WP0164 + 2 + + + 98.200000 + + 253.720001 + 1.445589 + WP0165 + 2d + 3 + 6.200000 + + + 97.000000 + + 224.910004 + 2.515633 + WP0166 + 2d + 3 + 6.200000 + + + 96.600000 + + 204.449997 + 2.459044 + WP0167 + 2d + 3 + 13.400000 + + + 96.100000 + + 185.449997 + 2.165811 + WP0168 + 3d + 4 + 3.200000 + + + 94.800000 + + 157.490005 + 2.021767 + WP0169 + 2d + 3 + 13.400000 + + + 95.200000 + + 137.639999 + 1.764544 + WP0170 + 2d + 3 + 13.600000 + + + 93.600000 + + 83.290001 + 1.455878 + WP0171 + 2d + 3 + 8.800000 + + + 92.400000 + + 86.800003 + 0.895133 + WP0172 + 3d + 4 + 3.000000 + + + 91.200000 + + 79.180000 + 0.828256 + WP0173 + 3d + 4 + 3.000000 + + + 92.400000 + + 82.589996 + 0.766522 + WP0174 + 2d + 3 + 6.200000 + + + 94.400000 + + 67.809998 + 0.956867 + WP0175 + 3d + 4 + 2.800000 + + + 92.800000 + + 43.900002 + 1.260389 + WP0176 + 3d + 4 + 2.800000 + + + 94.900000 + + 81.980003 + 1.142067 + WP0177 + 2d + 3 + 9.000000 + + + 95.600000 + + 109.800003 + 0.056589 + WP0178 + 3d + 4 + 2.800000 + + + 96.300000 + + 206.750000 + 0.627622 + WP0179 + 2d + 3 + 9.200000 + + + 96.300000 + + 186.479996 + 0.735656 + WP0180 + 1 + + + 98.800000 + + 185.270004 + 0.483578 + WP0181 + 3d + 4 + 2.600000 + + + 97.900000 + + 166.690002 + 6.152756 + WP0182 + 2d + 3 + 9.600000 + + + 97.600000 + + 166.690002 + 6.152756 + WP0183 + 1 + + + 97.300000 + + 166.690002 + 6.152756 + WP0184 + + + 97.500000 + + 131.520004 + 24.652178 + WP0185 + 2 + + + 97.700000 + + 135.419998 + 23.268322 + WP0186 + 2 + + + 98.100000 + + 144.899994 + 21.025345 + WP0187 + 2 + + + 98.200000 + + 147.210007 + 20.654945 + WP0188 + 2 + + + 98.200000 + + 147.210007 + 20.654945 + WP0189 + + + 97.900000 + + 160.369995 + 15.068078 + WP0190 + 2 + + + 97.800000 + + 182.169998 + 9.877334 + WP0191 + 1 + + + 101.300000 + + 174.380005 + 7.963600 + WP0192 + 2 + + + 105.300000 + + 179.320007 + 8.323711 + WP0193 + 2d + 3 + 10.000000 + + + 105.600000 + + 183.029999 + 8.267122 + WP0194 + 2 + + + 105.700000 + + 183.029999 + 8.267122 + WP0195 + 1 + + + 104.700000 + + 126.190002 + 4.876933 + WP0196 + 2 + + + 103.600000 + + 83.410004 + 14.347856 + WP0197 + 2 + + + 101.300000 + + 84.290001 + 13.828267 + WP0198 + 2 + + + 99.900000 + + 109.540001 + 15.947778 + WP0199 + 2d + 3 + 2.600000 + + + 98.100000 + + 115.199997 + 14.759411 + WP0200 + 1 + + + 97.900000 + + 105.970001 + 16.909788 + WP0201 + 2 + + + 97.700000 + + 105.970001 + 16.909788 + WP0202 + 1 + + + 97.700000 + + 87.070000 + 14.203811 + WP0203 + 2 + + + 97.700000 + + 85.029999 + 14.121500 + WP0204 + 2 + + + 97.500000 + + 84.540001 + 18.633179 + WP0205 + 2 + + + 97.300000 + + 84.480003 + 19.055021 + WP0206 + 2 + + + 97.100000 + + 84.480003 + 19.055021 + WP0207 + 1 + + + 97.000000 + + 84.480003 + 19.055021 + WP0208 + 1 + + + 97.100000 + + 86.349998 + 7.526322 + WP0209 + 2d + 3 + 6.400000 + + + 97.200000 + + 103.959999 + 0.164622 + WP0210 + 2d + 3 + 6.400000 + + + 97.100000 + + 198.320007 + 0.174911 + WP0211 + 2d + 3 + 6.400000 + + + 96.900000 + + 2.360000 + 0.920856 + WP0212 + 1 + + + 96.900000 + + 81.510002 + 14.769700 + WP0213 + 2 + + + 97.300000 + + 94.290001 + 4.218444 + WP0214 + + + 97.200000 + + 90.029999 + 1.450733 + WP0215 + 2d + 3 + 6.400000 + + + 97.200000 + + 91.970001 + 1.430156 + WP0216 + 2 + + + 97.100000 + + 93.570000 + 15.705989 + WP0217 + 1 + + + 97.400000 + + 93.570000 + 15.705989 + WP0218 + + + 97.500000 + + 76.129997 + 14.399300 + WP0219 + 2 + + + 97.500000 + + 75.209999 + 14.574211 + WP0220 + 1 + + + 97.500000 + + 75.209999 + 14.574211 + WP0221 + 1 + + + 97.400000 + + 75.209999 + 14.574211 + WP0222 + 1 + + + 97.400000 + + 90.370003 + 13.159489 + WP0223 + + + 97.300000 + + 111.029999 + 13.776822 + WP0224 + 2 + + + 97.300000 + + 126.019997 + 15.505356 + WP0225 + 2 + + + 99.000000 + + 171.699997 + 10.607844 + WP0226 + 2d + 3 + 2.000000 + + + 99.300000 + + 154.520004 + 6.543733 + WP0227 + 2 + + + 99.200000 + + 159.869995 + 0.133756 + WP0228 + 2d + 3 + 2.000000 + + + 99.000000 + + 169.960007 + 0.154333 + WP0229 + 2d + 3 + 2.000000 + + + 98.600000 + + 167.100006 + 1.152356 + WP0230 + 2d + 3 + 2.000000 + + + 98.300000 + + 318.260010 + 0.864267 + WP0231 + 1 + + + 98.000000 + + 76.680000 + 1.646222 + WP0232 + 1 + + + 98.200000 + + 47.889999 + 3.251289 + WP0233 + 1 + + + 98.400000 + + 47.889999 + 3.251289 + WP0234 + 1 + + + 98.400000 + + 240.000000 + 0.123467 + WP0235 + 2d + 3 + 2.000000 + + + 98.100000 + + 159.000000 + 0.128611 + WP0236 + 2 + + + 97.400000 + + 247.240005 + 0.334389 + WP0237 + 2 + + + + diff --git a/reference/track/vitovtt-sample.gpx b/reference/track/vitovtt-sample.gpx new file mode 100644 index 000000000..0129febf6 --- /dev/null +++ b/reference/track/vitovtt-sample.gpx @@ -0,0 +1,7478 @@ + + + + + + + + -0.800000 + + + + -0.100000 + + + + 1.600000 + + + + 2.600000 + + + + 3.000000 + + + + 4.400000 + + + + 4.600000 + + + + 4.700000 + + + + 4.900000 + + + + 7.900000 + + + + 10.900000 + + + + 11.900000 + + + + 13.600000 + + + + 15.100000 + + + + 15.700000 + + + + 14.100000 + + + + 13.900000 + + + + 12.600000 + + + + 11.400000 + + + + 10.000000 + + + + 10.300000 + + + + 9.800000 + + + + 8.900000 + + + + 6.900000 + + + + 6.500000 + + + + 5.900000 + + + + 4.000000 + + + + 4.600000 + + + + 4.200000 + + + + 3.500000 + + + + 2.000000 + + + + 1.100000 + + + + -0.200000 + + + + -0.500000 + + + + -1.300000 + + + + -1.500000 + + + + -3.300000 + + + + -4.800000 + + + + -5.100000 + + + + -5.300000 + + + + -4.900000 + + + + -4.500000 + + + + -4.200000 + + + + -5.200000 + + + + -6.300000 + + + + -6.800000 + + + + -7.100000 + + + + -9.800000 + + + + -10.000000 + + + + -12.000000 + + + + -12.400000 + + + + -11.300000 + + + + -11.300000 + + + + -10.900000 + + + + -8.800000 + + + + -8.100000 + + + + -6.700000 + + + + -5.700000 + + + + -3.200000 + + + + -0.800000 + + + + 2.600000 + + + + 7.000000 + + + + 11.900000 + + + + 15.300000 + + + + 17.700001 + + + + 21.700001 + + + + 26.200001 + + + + 29.900000 + + + + 35.500000 + + + + 40.200001 + + + + 42.700001 + + + + 45.900002 + + + + 44.700001 + + + + 44.099998 + + + + 45.200001 + + + + 44.200001 + + + + 47.000000 + + + + 50.200001 + + + + 54.500000 + + + + 58.200001 + + + + 60.099998 + + + + 64.800003 + + + + 69.400002 + + + + 75.199997 + + + + 78.500000 + + + + 78.099998 + + + + 77.099998 + + + + 74.900002 + + + + 68.599998 + + + + 69.099998 + + + + 69.400002 + + + + 68.099998 + + + + 66.500000 + + + + 64.000000 + + + + 58.400002 + + + + 56.900002 + + + + 52.099998 + + + + 48.799999 + + + + 46.500000 + + + + 50.599998 + + + + 52.400002 + + + + 54.000000 + + + + 49.200001 + + + + 43.700001 + + + + 37.900002 + + + + 32.200001 + + + + 24.400000 + + + + 18.100000 + + + + 9.700000 + + + + 0.500000 + + + + -3.700000 + + + + -7.900000 + + + + -6.900000 + + + + -4.400000 + + + + 1.600000 + + + + 9.400000 + + + + 14.900000 + + + + 20.500000 + + + + 22.799999 + + + + 22.600000 + + + + 21.000000 + + + + 13.700000 + + + + 10.500000 + + + + 6.400000 + + + + 1.000000 + + + + -3.600000 + + + + -10.100000 + + + + -15.400000 + + + + -17.500000 + + + + -17.400000 + + + + -18.600000 + + + + -19.200001 + + + + -21.299999 + + + + -22.400000 + + + + -25.799999 + + + + -26.100000 + + + + -25.600000 + + + + -24.400000 + + + + -26.000000 + + + + -28.700001 + + + + -32.400002 + + + + -35.599998 + + + + -36.900002 + + + + -38.200001 + + + + -38.799999 + + + + -37.099998 + + + + -37.599998 + + + + -37.400002 + + + + -42.200001 + + + + -41.900002 + + + + -40.799999 + + + + -40.900002 + + + + -39.599998 + + + + -40.599998 + + + + -41.000000 + + + + -40.099998 + + + + -35.799999 + + + + -32.900002 + + + + -33.000000 + + + + -31.500000 + + + + -29.299999 + + + + -28.400000 + + + + -29.500000 + + + + -30.200001 + + + + -30.100000 + + + + -31.100000 + + + + -34.299999 + + + + -33.599998 + + + + -31.500000 + + + + -27.400000 + + + + -24.600000 + + + + -17.200001 + + + + -13.400000 + + + + -8.000000 + + + + -4.300000 + + + + -0.900000 + + + + 3.000000 + + + + 8.100000 + + + + 11.200000 + + + + 14.600000 + + + + 17.200001 + + + + 17.299999 + + + + 20.500000 + + + + 21.799999 + + + + 22.900000 + + + + 22.799999 + + + + 23.100000 + + + + 23.000000 + + + + 22.200001 + + + + 21.900000 + + + + 23.100000 + + + + 24.299999 + + + + 27.900000 + + + + 27.799999 + + + + 25.299999 + + + + 26.299999 + + + + 29.200001 + + + + 31.200001 + + + + 30.100000 + + + + 32.400002 + + + + 34.700001 + + + + 37.099998 + + + + 38.200001 + + + + 39.599998 + + + + 38.299999 + + + + 38.200001 + + + + 37.299999 + + + + 35.700001 + + + + 34.400002 + + + + 30.400000 + + + + 29.400000 + + + + 28.600000 + + + + 27.299999 + + + + 27.000000 + + + + 27.900000 + + + + 27.900000 + + + + 26.100000 + + + + 25.299999 + + + + 25.400000 + + + + 25.200001 + + + + 23.799999 + + + + 22.799999 + + + + 21.100000 + + + + 20.200001 + + + + 20.200001 + + + + 18.900000 + + + + 19.000000 + + + + 18.100000 + + + + 16.400000 + + + + 14.600000 + + + + 12.400000 + + + + 11.900000 + + + + 9.400000 + + + + 8.300000 + + + + 5.700000 + + + + 6.800000 + + + + 7.500000 + + + + 5.100000 + + + + 3.700000 + + + + 2.900000 + + + + 0.300000 + + + + 0.300000 + + + + -3.600000 + + + + -5.900000 + + + + -8.800000 + + + + -8.700000 + + + + -9.200000 + + + + -9.900000 + + + + -10.600000 + + + + -10.700000 + + + + -10.900000 + + + + -10.800000 + + + + -11.800000 + + + + -13.100000 + + + + -15.300000 + + + + -14.500000 + + + + -14.600000 + + + + -14.700000 + + + + -15.600000 + + + + -19.500000 + + + + -22.400000 + + + + -20.600000 + + + + -20.000000 + + + + -20.100000 + + + + -20.600000 + + + + -20.900000 + + + + -21.799999 + + + + -25.500000 + + + + -26.100000 + + + + -25.500000 + + + + -24.500000 + + + + -25.000000 + + + + -24.900000 + + + + -23.299999 + + + + -23.100000 + + + + -20.700001 + + + + -17.799999 + + + + -15.600000 + + + + -14.700000 + + + + -14.100000 + + + + -11.500000 + + + + -12.500000 + + + + -12.200000 + + + + -12.500000 + + + + -11.800000 + + + + -10.600000 + + + + -8.000000 + + + + -5.600000 + + + + -4.600000 + + + + -3.900000 + + + + -1.800000 + + + + -0.100000 + + + + 0.100000 + + + + 1.000000 + + + + 1.000000 + + + + 1.800000 + + + + 2.200000 + + + + 3.800000 + + + + 5.000000 + + + + 6.300000 + + + + 6.800000 + + + + 8.400000 + + + + 9.400000 + + + + 10.300000 + + + + 11.300000 + + + + 13.700000 + + + + 15.600000 + + + + 19.000000 + + + + 19.299999 + + + + 20.500000 + + + + 21.400000 + + + + 23.000000 + + + + 24.200001 + + + + 28.799999 + + + + 31.100000 + + + + 35.099998 + + + + 39.799999 + + + + 46.200001 + + + + 51.000000 + + + + 52.799999 + + + + 53.900002 + + + + 58.500000 + + + + 63.400002 + + + + 66.599998 + + + + 70.099998 + + + + 74.099998 + + + + 77.400002 + + + + 81.599998 + + + + 84.599998 + + + + 87.900002 + + + + 91.599998 + + + + 91.199997 + + + + 91.099998 + + + + 92.300003 + + + + 94.199997 + + + + 96.000000 + + + + 96.300003 + + + + 95.000000 + + + + 95.699997 + + + + 97.400002 + + + + 99.199997 + + + + 100.199997 + + + + 101.599998 + + + + 102.500000 + + + + 104.500000 + + + + 104.199997 + + + + 105.000000 + + + + 106.800003 + + + + 104.599998 + + + + 100.800003 + + + + 99.699997 + + + + 99.000000 + + + + 97.000000 + + + + 94.300003 + + + + 92.300003 + + + + 91.099998 + + + + 91.500000 + + + + 91.099998 + + + + 89.800003 + + + + 88.500000 + + + + 89.099998 + + + + 85.099998 + + + + 83.300003 + + + + 82.000000 + + + + 79.199997 + + + + 76.900002 + + + + 78.199997 + + + + 80.000000 + + + + 81.199997 + + + + 81.300003 + + + + 79.500000 + + + + 79.199997 + + + + 78.400002 + + + + 77.099998 + + + + 78.000000 + + + + 78.199997 + + + + 76.599998 + + + + 78.000000 + + + + 81.199997 + + + + 82.599998 + + + + 79.800003 + + + + 78.099998 + + + + 77.199997 + + + + 75.400002 + + + + 77.400002 + + + + 76.800003 + + + + 76.800003 + + + + 77.000000 + + + + 78.300003 + + + + 78.800003 + + + + 77.500000 + + + + 78.599998 + + + + 78.099998 + + + + 79.099998 + + + + 78.300003 + + + + 77.199997 + + + + 76.199997 + + + + 72.599998 + + + + 69.599998 + + + + 67.400002 + + + + 64.699997 + + + + 61.900002 + + + + 59.400002 + + + + 57.799999 + + + + 54.299999 + + + + 51.500000 + + + + 48.000000 + + + + 45.400002 + + + + 43.000000 + + + + 42.200001 + + + + 40.200001 + + + + 37.700001 + + + + 36.599998 + + + + 35.799999 + + + + 33.599998 + + + + 33.400002 + + + + 30.299999 + + + + 28.900000 + + + + 27.000000 + + + + 25.299999 + + + + 23.799999 + + + + 21.900000 + + + + 21.200001 + + + + 19.799999 + + + + 17.500000 + + + + 15.600000 + + + + 14.000000 + + + + 12.200000 + + + + 11.500000 + + + + 10.000000 + + + + 10.000000 + + + + 9.100000 + + + + 8.300000 + + + + 7.800000 + + + + 7.900000 + + + + 7.400000 + + + + 9.200000 + + + + 10.500000 + + + + 11.500000 + + + + 11.000000 + + + + 10.500000 + + + + 11.300000 + + + + 11.300000 + + + + 12.500000 + + + + 13.100000 + + + + 13.800000 + + + + 15.100000 + + + + 15.400000 + + + + 15.300000 + + + + 16.200001 + + + + 16.100000 + + + + 15.800000 + + + + 15.500000 + + + + 15.800000 + + + + 14.200000 + + + + 14.600000 + + + + 13.900000 + + + + 15.200000 + + + + 15.400000 + + + + 15.700000 + + + + 15.400000 + + + + 15.800000 + + + + 16.000000 + + + + 16.799999 + + + + 16.600000 + + + + 17.200001 + + + + 17.900000 + + + + 17.100000 + + + + 18.000000 + + + + 19.400000 + + + + 19.500000 + + + + 19.299999 + + + + 21.000000 + + + + 23.299999 + + + + 23.500000 + + + + 23.299999 + + + + 23.600000 + + + + 24.100000 + + + + 24.700001 + + + + 25.100000 + + + + 24.900000 + + + + 23.900000 + + + + 24.700001 + + + + 24.100000 + + + + 25.200001 + + + + 24.900000 + + + + 24.700001 + + + + 24.600000 + + + + 23.600000 + + + + 23.700001 + + + + 22.400000 + + + + 22.500000 + + + + 21.799999 + + + + 21.200001 + + + + 20.799999 + + + + 20.100000 + + + + 17.500000 + + + + 16.600000 + + + + 18.400000 + + + + 20.200001 + + + + 20.100000 + + + + 20.799999 + + + + 21.000000 + + + + 20.900000 + + + + 19.100000 + + + + 18.299999 + + + + 18.500000 + + + + 19.600000 + + + + 19.299999 + + + + 18.299999 + + + + 17.900000 + + + + 16.299999 + + + + 13.900000 + + + + 13.100000 + + + + 10.900000 + + + + 9.900000 + + + + 8.500000 + + + + 7.500000 + + + + 5.900000 + + + + 5.600000 + + + + 4.400000 + + + + 5.000000 + + + + 3.400000 + + + + 3.700000 + + + + 3.800000 + + + + 4.100000 + + + + 3.800000 + + + + 4.300000 + + + + 5.500000 + + + + 4.800000 + + + + 6.000000 + + + + 6.000000 + + + + 6.100000 + + + + 6.100000 + + + + 6.700000 + + + + 6.100000 + + + + 5.600000 + + + + 4.400000 + + + + 3.700000 + + + + 4.800000 + + + + 6.000000 + + + + 4.900000 + + + + 4.300000 + + + + 2.400000 + + + + 2.800000 + + + + 1.600000 + + + + 1.300000 + + + + 1.300000 + + + + -1.800000 + + + + -2.800000 + + + + -4.200000 + + + + -4.400000 + + + + -3.900000 + + + + -3.000000 + + + + -2.700000 + + + + -2.100000 + + + + 0.500000 + + + + 1.900000 + + + + 3.300000 + + + + 5.100000 + + + + 6.200000 + + + + 6.800000 + + + + 8.100000 + + + + 7.800000 + + + + 7.300000 + + + + 8.800000 + + + + 9.500000 + + + + 11.200000 + + + + 10.900000 + + + + 11.400000 + + + + 11.600000 + + + + 11.000000 + + + + 10.300000 + + + + 9.800000 + + + + 9.500000 + + + + 8.200000 + + + + 6.600000 + + + + 6.600000 + + + + 7.100000 + + + + 7.300000 + + + + 6.700000 + + + + 6.300000 + + + + 7.600000 + + + + 8.100000 + + + + 9.000000 + + + + 9.300000 + + + + 8.900000 + + + + 7.700000 + + + + 8.200000 + + + + 9.200000 + + + + 10.100000 + + + + 11.600000 + + + + 11.800000 + + + + 12.800000 + + + + 14.800000 + + + + 17.100000 + + + + 17.700001 + + + + 17.299999 + + + + 18.600000 + + + + 20.100000 + + + + 21.700001 + + + + 22.600000 + + + + 22.900000 + + + + 23.200001 + + + + 23.200001 + + + + 22.100000 + + + + 19.200001 + + + + 17.600000 + + + + 16.200001 + + + + 18.000000 + + + + 18.700001 + + + + 18.400000 + + + + 18.000000 + + + + 16.299999 + + + + 15.400000 + + + + 13.900000 + + + + 12.900000 + + + + 12.800000 + + + + 12.000000 + + + + 11.200000 + + + + 11.000000 + + + + 10.100000 + + + + 9.900000 + + + + 10.600000 + + + + 9.600000 + + + + 9.300000 + + + + 7.300000 + + + + 5.700000 + + + + 5.400000 + + + + 5.100000 + + + + 5.000000 + + + + 4.100000 + + + + 5.000000 + + + + 7.200000 + + + + 8.000000 + + + + 8.100000 + + + + 8.800000 + + + + 10.700000 + + + + 12.800000 + + + + 13.900000 + + + + 14.200000 + + + + 12.600000 + + + + 10.800000 + + + + 11.200000 + + + + 13.000000 + + + + 15.400000 + + + + 19.900000 + + + + 23.400000 + + + + 25.100000 + + + + 26.299999 + + + + 26.299999 + + + + 26.400000 + + + + 26.600000 + + + + 27.299999 + + + + 25.799999 + + + + 25.400000 + + + + 25.400000 + + + + 24.799999 + + + + 25.500000 + + + + 24.900000 + + + + 25.000000 + + + + 25.799999 + + + + 27.200001 + + + + 26.799999 + + + + 25.700001 + + + + 26.500000 + + + + 25.500000 + + + + 24.200001 + + + + 24.000000 + + + + 23.299999 + + + + 24.100000 + + + + 24.700001 + + + + 24.799999 + + + + 24.200001 + + + + 25.200001 + + + + 25.799999 + + + + 25.799999 + + + + 26.799999 + + + + 26.100000 + + + + 23.500000 + + + + 22.700001 + + + + 22.600000 + + + + 22.100000 + + + + 21.100000 + + + + 21.600000 + + + + 20.600000 + + + + 20.400000 + + + + 20.600000 + + + + 20.799999 + + + + 19.100000 + + + + 20.200001 + + + + 20.000000 + + + + 20.900000 + + + + 20.700001 + + + + 20.900000 + + + + 22.700001 + + + + 23.400000 + + + + 24.200001 + + + + 24.900000 + + + + 24.600000 + + + + 23.700001 + + + + 23.500000 + + + + 24.900000 + + + + 25.600000 + + + + 25.100000 + + + + 24.700001 + + + + 24.500000 + + + + 23.299999 + + + + 22.799999 + + + + 23.799999 + + + + 23.400000 + + + + 24.500000 + + + + 24.500000 + + + + 23.600000 + + + + 22.900000 + + + + 21.600000 + + + + 21.100000 + + + + 21.000000 + + + + 23.100000 + + + + 24.400000 + + + + 27.299999 + + + + 27.600000 + + + + 29.900000 + + + + 30.600000 + + + + 30.900000 + + + + 32.799999 + + + + 34.599998 + + + + 35.299999 + + + + 35.500000 + + + + 35.099998 + + + + 37.099998 + + + + 38.299999 + + + + 38.799999 + + + + 38.700001 + + + + 39.799999 + + + + 40.500000 + + + + 40.599998 + + + + 41.700001 + + + + 42.400002 + + + + 43.500000 + + + + 44.299999 + + + + 44.799999 + + + + 46.099998 + + + + 45.900002 + + + + 46.799999 + + + + 48.000000 + + + + 49.200001 + + + + 50.599998 + + + + 51.200001 + + + + 52.799999 + + + + 53.700001 + + + + 55.299999 + + + + 56.500000 + + + + 57.799999 + + + + 56.900002 + + + + 55.099998 + + + + 53.099998 + + + + 52.200001 + + + + 52.299999 + + + + 50.700001 + + + + 50.799999 + + + + 51.200001 + + + + 49.000000 + + + + 48.299999 + + + + 47.200001 + + + + 46.599998 + + + + 43.799999 + + + + 42.200001 + + + + 40.500000 + + + + 38.500000 + + + + 37.599998 + + + + 37.500000 + + + + 37.099998 + + + + 35.400002 + + + + 34.099998 + + + + 33.900002 + + + + 33.299999 + + + + 33.299999 + + + + 32.299999 + + + + 31.100000 + + + + 30.500000 + + + + 30.400000 + + + + 30.600000 + + + + 29.700001 + + + + 28.600000 + + + + 27.900000 + + + + 26.200001 + + + + 25.200001 + + + + 24.100000 + + + + 23.200001 + + + + 21.100000 + + + + 21.100000 + + + + 20.100000 + + + + 20.900000 + + + + 20.799999 + + + + 19.200001 + + + + 18.500000 + + + + 17.900000 + + + + 16.600000 + + + + 16.299999 + + + + 14.000000 + + + + 12.100000 + + + + 12.500000 + + + + 11.000000 + + + + 10.200000 + + + + 10.600000 + + + + 12.100000 + + + + 13.000000 + + + + 14.800000 + + + + 15.200000 + + + + 15.400000 + + + + 17.900000 + + + + 18.700001 + + + + 20.100000 + + + + 20.200001 + + + + 21.000000 + + + + 19.500000 + + + + 18.500000 + + + + 19.200001 + + + + 19.600000 + + + + 20.299999 + + + + 22.200001 + + + + 21.400000 + + + + 23.700001 + + + + 24.100000 + + + + 26.799999 + + + + 29.799999 + + + + 30.200001 + + + + 31.000000 + + + + 32.500000 + + + + 33.000000 + + + + 32.400002 + + + + 32.400002 + + + + 33.099998 + + + + 33.299999 + + + + 36.500000 + + + + 38.099998 + + + + 37.700001 + + + + 37.500000 + + + + 38.200001 + + + + 39.000000 + + + + 39.400002 + + + + 38.500000 + + + + 36.700001 + + + + 36.400002 + + + + 35.599998 + + + + 37.500000 + + + + 38.299999 + + + + 37.500000 + + + + 38.700001 + + + + 39.599998 + + + + 38.500000 + + + + 38.000000 + + + + 39.099998 + + + + 39.700001 + + + + 41.000000 + + + + 40.400002 + + + + 40.799999 + + + + 39.200001 + + + + 39.900002 + + + + 39.200001 + + + + 38.299999 + + + + 38.299999 + + + + 38.900002 + + + + 40.599998 + + + + 41.599998 + + + + 42.299999 + + + + 42.299999 + + + + 43.299999 + + + + 41.500000 + + + + 40.500000 + + + + 37.599998 + + + + 36.299999 + + + + 37.599998 + + + + 37.200001 + + + + 37.299999 + + + + 36.500000 + + + + 34.799999 + + + + 34.200001 + + + + 32.099998 + + + + 29.700001 + + + + 29.400000 + + + + 28.900000 + + + + 27.500000 + + + + 28.900000 + + + + 32.400002 + + + + 32.299999 + + + + 33.700001 + + + + 35.299999 + + + + 34.700001 + + + + 35.400002 + + + + 35.099998 + + + + 34.299999 + + + + 31.799999 + + + + 28.900000 + + + + 23.799999 + + + + 23.400000 + + + + 23.799999 + + + + 22.799999 + + + + 21.900000 + + + + 21.600000 + + + + 21.400000 + + + + 21.799999 + + + + 22.100000 + + + + 22.500000 + + + + 23.200001 + + + + 24.200001 + + + + 25.200001 + + + + 25.900000 + + + + 26.100000 + + + + 25.799999 + + + + 23.799999 + + + + 21.799999 + + + + 20.400000 + + + + 19.799999 + + + + 19.100000 + + + + 20.000000 + + + + 21.100000 + + + + 21.400000 + + + + 22.400000 + + + + 23.299999 + + + + 25.500000 + + + + 27.100000 + + + + 29.700001 + + + + 31.600000 + + + + 33.599998 + + + + 36.099998 + + + + 36.599998 + + + + 32.900002 + + + + 31.600000 + + + + 31.100000 + + + + 30.100000 + + + + 30.200001 + + + + 29.500000 + + + + 29.799999 + + + + 31.400000 + + + + 33.500000 + + + + 34.900002 + + + + 36.500000 + + + + 38.000000 + + + + 39.400002 + + + + 41.299999 + + + + 42.700001 + + + + 43.900002 + + + + 44.500000 + + + + 44.900002 + + + + 43.900002 + + + + 43.299999 + + + + 42.700001 + + + + 41.900002 + + + + 41.099998 + + + + 40.500000 + + + + 39.000000 + + + + 36.900002 + + + + 35.400002 + + + + 34.799999 + + + + 35.400002 + + + + 35.599998 + + + + 35.700001 + + + + 36.200001 + + + + 36.400002 + + + + 36.299999 + + + + 36.599998 + + + + 35.599998 + + + + 34.000000 + + + + 32.599998 + + + + 31.100000 + + + + 31.100000 + + + + 30.299999 + + + + 29.900000 + + + + 29.600000 + + + + 30.100000 + + + + 31.000000 + + + + 31.000000 + + + + 30.299999 + + + + 29.900000 + + + + 29.700001 + + + + 29.500000 + + + + 28.100000 + + + + 26.799999 + + + + 25.900000 + + + + 25.100000 + + + + 24.200001 + + + + 23.000000 + + + + 22.500000 + + + + 21.799999 + + + + 21.100000 + + + + 20.900000 + + + + 19.799999 + + + + 19.299999 + + + + 19.799999 + + + + 20.500000 + + + + 22.299999 + + + + 24.400000 + + + + 25.799999 + + + + 28.200001 + + + + 29.600000 + + + + 31.100000 + + + + 31.600000 + + + + 32.000000 + + + + 32.299999 + + + + 33.200001 + + + + 33.900002 + + + + 35.400002 + + + + 36.299999 + + + + 36.799999 + + + + 36.500000 + + + + 36.200001 + + + + 36.400002 + + + + 36.200001 + + + + 36.400002 + + + + 36.599998 + + + + 35.599998 + + + + 35.099998 + + + + 33.900002 + + + + 33.700001 + + + + 34.299999 + + + + 35.200001 + + + + 35.799999 + + + + 35.299999 + + + + 34.299999 + + + + 34.099998 + + + + 34.000000 + + + + 34.400002 + + + + 35.599998 + + + + 35.500000 + + + + 37.099998 + + + + 37.900002 + + + + 37.799999 + + + + 37.799999 + + + + 36.700001 + + + + 36.299999 + + + + 36.599998 + + + + 38.099998 + + + + 40.099998 + + + + 40.000000 + + + + 38.799999 + + + + 36.700001 + + + + 34.700001 + + + + 33.900002 + + + + 33.700001 + + + + 34.299999 + + + + 35.299999 + + + + 35.700001 + + + + 36.099998 + + + + 35.200001 + + + + 35.799999 + + + + 36.299999 + + + + 35.900002 + + + + 36.000000 + + + + 35.700001 + + + + 34.500000 + + + + 32.900002 + + + + 32.299999 + + + + 32.299999 + + + + 33.200001 + + + + 33.000000 + + + + 31.799999 + + + + 31.100000 + + + + 30.600000 + + + + 28.799999 + + + + 28.299999 + + + + 27.500000 + + + + 27.700001 + + + + 27.200001 + + + + 25.600000 + + + + 23.200001 + + + + 21.900000 + + + + 20.900000 + + + + 20.900000 + + + + 19.600000 + + + + 20.500000 + + + + 20.500000 + + + + 19.000000 + + + + 15.900000 + + + + 14.600000 + + + + 13.400000 + + + + 13.400000 + + + + 15.300000 + + + + 15.100000 + + + + 15.300000 + + + + 16.799999 + + + + 16.799999 + + + + 19.799999 + + + + 19.700001 + + + + 18.600000 + + + + 18.600000 + + + + 12.900000 + + + + 12.300000 + + + + 11.900000 + + + + 11.900000 + + + + 13.100000 + + + + 13.700000 + + + + 13.700000 + + + + 13.700000 + + + + 14.600000 + + + + 14.600000 + + + + 14.600000 + + + + 14.400000 + + + + 15.300000 + + + + 15.700000 + + + + 15.700000 + + + + 16.100000 + + + + 15.900000 + + + + 16.400000 + + + + 16.400000 + + + + 15.500000 + + + + 15.700000 + + + + 16.100000 + + + + 16.100000 + + + + 18.299999 + + + + 18.900000 + + + + 19.299999 + + + + 19.299999 + + + + 22.200001 + + + + 22.500000 + + + + 23.000000 + + + + 23.000000 + + + + 23.700001 + + + + 24.400000 + + + + 25.400000 + + + + 25.400000 + + + + 28.799999 + + + + 30.299999 + + + + 31.400000 + + + + 31.200001 + + + + 30.700001 + + + + 30.700001 + + + + 31.500000 + + + + 31.900000 + + + + 31.900000 + + + + 31.900000 + + + + 33.700001 + + + + 34.299999 + + + + 34.299999 + + + + 35.400002 + + + + 36.099998 + + + + 36.000000 + + + + 36.299999 + + + + 36.299999 + + + + 37.299999 + + + + 36.700001 + + + + 36.400002 + + + + 37.299999 + + + + 38.400002 + + + + 40.099998 + + + + 40.099998 + + + + 44.700001 + + + + 45.799999 + + + + 45.500000 + + + + 44.599998 + + + + 44.400002 + + + + 44.700001 + + + + 44.700001 + + + + 43.400002 + + + + 42.799999 + + + + 42.700001 + + + + 42.700001 + + + + 40.299999 + + + + 40.000000 + + + + 39.200001 + + + + 39.200001 + + + + 36.700001 + + + + 36.200001 + + + + 35.099998 + + + + 35.099998 + + + + 32.400002 + + + + 31.799999 + + + + 31.000000 + + + + 31.000000 + + + + 28.900000 + + + + 28.000000 + + + + 27.200001 + + + + 27.200001 + + + + 23.700001 + + + + 23.100000 + + + + 22.000000 + + + + 21.100000 + + + + 20.799999 + + + + 20.400000 + + + + 20.400000 + + + + 19.900000 + + + + 20.500000 + + + + 20.600000 + + + + 20.600000 + + + + 20.299999 + + + + 19.900000 + + + + 19.900000 + + + + 21.299999 + + + + 21.600000 + + + + 21.600000 + + + + 21.200001 + + + + 21.100000 + + + + 21.100000 + + + + 19.600000 + + + + 19.799999 + + + + 20.100000 + + + + 20.100000 + + + + 21.799999 + + + + 22.400000 + + + + 22.700001 + + + + 22.700001 + + + + 24.400000 + + + + 24.400000 + + + + 24.500000 + + + + 23.900000 + + + + 23.900000 + + + + 25.600000 + + + + 26.500000 + + + + 26.900000 + + + + 28.700001 + + + + 28.700001 + + + + 31.700001 + + + + 32.400002 + + + + 32.299999 + + + + 32.299999 + + + + 35.599998 + + + + 36.700001 + + + + 37.799999 + + + + 37.799999 + + + + 38.599998 + + + + 37.799999 + + + + 36.500000 + + + + 36.500000 + + + + 35.099998 + + + + 34.799999 + + + + 34.200001 + + + + 34.200001 + + + + 34.400002 + + + + 33.900002 + + + + 33.500000 + + + + 33.500000 + + + + 32.799999 + + + + 33.900002 + + + + 34.299999 + + + + 34.299999 + + + + 34.099998 + + + + 34.200001 + + + + 33.599998 + + + + 33.599998 + + + + 33.900002 + + + + 33.599998 + + + + 33.400002 + + + + 33.400002 + + + + 34.299999 + + + + 34.799999 + + + + 34.299999 + + + + 33.900002 + + + + 33.900002 + + + + 33.200001 + + + + 34.500000 + + + + 34.799999 + + + + 34.799999 + + + + 35.500000 + + + + 35.599998 + + + + 36.500000 + + + + 37.500000 + + + + 37.500000 + + + + 38.799999 + + + + 39.200001 + + + + 39.200001 + + + + 39.400002 + + + + 39.200001 + + + + 39.500000 + + + + 39.500000 + + + + 39.599998 + + + + 39.099998 + + + + 39.200001 + + + + 39.200001 + + + + 39.200001 + + + + 39.299999 + + + + 39.299999 + + + + 39.299999 + + + + 41.099998 + + + + 41.599998 + + + + 41.599998 + + + + 43.700001 + + + + 43.900002 + + + + 43.900002 + + + + 42.700001 + + + + 42.700001 + + + + 40.900002 + + + + 39.799999 + + + + 39.500000 + + + + 39.299999 + + + + 39.299999 + + + + 35.200001 + + + + 34.900002 + + + + 34.900002 + + + + 32.500000 + + + + 31.700001 + + + + 31.700001 + + + + 30.900000 + + + + 29.799999 + + + + 29.299999 + + + + 28.600000 + + + + 28.600000 + + + + 25.100000 + + + + 24.700001 + + + + 24.500000 + + + + 24.500000 + + + + 26.900000 + + + + 26.000000 + + + + 26.000000 + + + + 26.000000 + + + + 26.600000 + + + + 27.000000 + + + + 27.000000 + + + + 25.900000 + + + + 26.200001 + + + + 25.700001 + + + + 25.700001 + + + + 26.400000 + + + + 26.799999 + + + + 27.100000 + + + + 27.000000 + + + + 27.000000 + + + + 26.799999 + + + + 26.799999 + + + + 27.200001 + + + + 27.000000 + + + + 27.000000 + + + + 28.500000 + + + + 28.200001 + + + + 27.500000 + + + + 27.500000 + + + + 26.200001 + + + + 26.200001 + + + + 28.100000 + + + + 28.100000 + + + + 28.100000 + + + + 29.299999 + + + + 28.900000 + + + + 28.900000 + + + + 28.400000 + + + + 28.600000 + + + + 28.600000 + + + + 28.600000 + + + + 31.100000 + + + + 32.000000 + + + + 32.200001 + + + + 32.200001 + + + + 31.600000 + + + + 32.000000 + + + + 32.000000 + + + + 32.000000 + + + + 30.400000 + + + + 29.799999 + + + + 28.900000 + + + + 28.400000 + + + + 28.200001 + + + + 27.200001 + + + + 27.200001 + + + + 27.200001 + + + + 25.900000 + + + + 25.500000 + + + + 24.700001 + + + + 24.799999 + + + + 24.600000 + + + + 24.600000 + + + + 24.600000 + + + + 21.600000 + + + + 20.799999 + + + + 20.400000 + + + + 20.200001 + + + + 19.500000 + + + + 18.500000 + + + + 17.700001 + + + + 17.700001 + + + + 15.700000 + + + + 16.299999 + + + + 16.799999 + + + + 16.900000 + + + + 16.900000 + + + + 17.100000 + + + + 18.100000 + + + + 18.700001 + + + + 18.700001 + + + + 19.600000 + + + + 19.400000 + + + + 19.400000 + + + + 19.700001 + + + + 20.100000 + + + + 20.200001 + + + + 20.200001 + + + + 20.100000 + + + + 18.700001 + + + + 18.799999 + + + + 18.799999 + + + + 22.600000 + + + + 22.900000 + + + + 23.799999 + + + + 23.799999 + + + + 28.799999 + + + + 29.100000 + + + + 30.200001 + + + + 31.200001 + + + + 32.200001 + + + + 33.400002 + + + + 33.400002 + + + + 34.599998 + + + + 35.200001 + + + + 35.799999 + + + + 35.799999 + + + + 34.799999 + + + + 34.900002 + + + + 34.900002 + + + + 34.200001 + + + + 34.500000 + + + + 34.500000 + + + + 35.200001 + + + + 35.400002 + + + + 35.500000 + + + + 35.500000 + + + + 33.200001 + + + + 33.400002 + + + + 33.400002 + + + + 34.799999 + + + + 35.000000 + + + + 35.299999 + + + + 35.299999 + + + + 37.700001 + + + + 37.900002 + + + + 37.900002 + + + + 38.400002 + + + + 38.299999 + + + + 38.000000 + + + + 35.500000 + + + + 35.099998 + + + + 34.599998 + + + + 34.599998 + + + + 33.799999 + + + + 34.000000 + + + + 34.799999 + + + + 34.799999 + + + + 36.500000 + + + + 37.799999 + + + + 37.799999 + + + + 41.799999 + + + + 41.700001 + + + + 41.700001 + + + + 36.799999 + + + + 34.700001 + + + + 34.700001 + + + + 26.000000 + + + + 24.299999 + + + + 23.700001 + + + + 21.900000 + + + + 21.900000 + + + + 15.800000 + + + + 14.100000 + + + + 14.100000 + + + + 5.000000 + + + + 3.800000 + + + + 2.900000 + + + + 2.900000 + + + + -0.700000 + + + + -0.400000 + + + + 0.800000 + + + + 0.800000 + + + + 0.600000 + + + + 0.400000 + + + + -0.300000 + + + + -0.300000 + + + + -1.800000 + + + + -2.700000 + + + + -2.700000 + + + + -4.500000 + + + + -4.900000 + + + + -4.900000 + + + + -4.700000 + + + + -4.600000 + + + + -3.800000 + + + + -4.300000 + + + + -4.300000 + + + + -5.100000 + + + + -4.200000 + + + + -2.000000 + + + + -2.000000 + + + + -0.500000 + + + + -0.200000 + + + + -0.800000 + + + + -0.800000 + + + + -2.100000 + + + + -2.200000 + + + + -1.600000 + + + + -1.600000 + + + + -0.900000 + + + + -0.700000 + + + + -0.700000 + + + + 1.200000 + + + + 2.400000 + + + + 1.800000 + + + + 1.800000 + + + + -0.800000 + + + + -2.100000 + + + + -2.100000 + + + + -5.400000 + + + + -5.500000 + + + + -5.500000 + + + + -5.500000 + + + + -5.500000 + + + + -6.200000 + + + + -6.400000 + + + + -6.400000 + + + + -7.900000 + + + + -7.500000 + + + + -6.600000 + + + + -6.600000 + + + + -3.700000 + + + + -3.500000 + + + + -2.500000 + + + + -2.500000 + + + + -1.200000 + + + + -0.200000 + + + + 0.800000 + + + + 1.300000 + + + + 1.700000 + + + + 1.900000 + + + + 2.600000 + + + + 2.600000 + + + + 5.700000 + + + + 6.600000 + + + + 6.900000 + + + + 8.400000 + + + + 8.400000 + + + + 14.100000 + + + + 14.700000 + + + + 14.900000 + + + + 14.900000 + + + + 15.600000 + + + + 15.500000 + + + + 15.500000 + + + + 16.200001 + + + + 16.200001 + + + + 18.200001 + + + + 18.200001 + + + + 18.200001 + + + + 18.200001 + + + + 16.500000 + + + + 16.000000 + + + + 16.799999 + + + + 16.799999 + + + + 17.400000 + + + + 17.299999 + + + + 17.100000 + + + + 17.400000 + + + + 17.400000 + + + + 17.900000 + + + + 18.400000 + + + + 19.000000 + + + + 19.000000 + + + + 17.299999 + + + + 16.799999 + + + + 16.900000 + + + + 16.900000 + + + + 17.700001 + + + + 18.400000 + + + + 18.500000 + + + + 18.500000 + + + + 18.200001 + + + + 18.200001 + + + + 17.200001 + + + + 17.200001 + + + + 17.200001 + + + + 15.900000 + + + + 15.500000 + + + + 16.000000 + + + + 16.000000 + + + + 19.299999 + + + + 18.600000 + + + + 18.600000 + + + + 18.600000 + + + + 17.000000 + + + + 17.000000 + + + + 16.600000 + + + + 16.600000 + + + + 15.300000 + + + + 15.500000 + + + + 15.300000 + + + + 15.300000 + + + + 14.300000 + + + + 14.300000 + + + + 14.300000 + + + + 12.000000 + + + + 11.100000 + + + + 10.800000 + + + + 10.800000 + + + + 12.100000 + + + + 11.800000 + + + + 12.200000 + + + + 12.200000 + + + + 13.600000 + + + + 14.500000 + + + + 14.500000 + + + + 19.000000 + + + + 19.600000 + + + + 20.799999 + + + + 20.500000 + + + + 20.100000 + + + + 19.500000 + + + + 20.500000 + + + + 21.100000 + + + + 21.100000 + + + + 23.100000 + + + + 23.000000 + + + + 23.000000 + + + + 25.000000 + + + + 25.400000 + + + + 24.900000 + + + + 24.299999 + + + + 22.900000 + + + + 22.600000 + + + + 22.600000 + + + + 19.900000 + + + + 19.299999 + + + + 19.100000 + + + + 18.900000 + + + + 18.900000 + + + + 18.000000 + + + + 17.200001 + + + + 16.500000 + + + + 16.500000 + + + + 16.500000 + + + + 13.100000 + + + + 12.700000 + + + + 12.800000 + + + + 12.800000 + + + + 12.100000 + + + + 12.800000 + + + + 12.900000 + + + + 14.600000 + + + + 14.300000 + + + + 15.300000 + + + + 15.300000 + + + + 15.100000 + + + + 15.000000 + + + + 15.500000 + + + + 15.500000 + + + + 16.500000 + + + + 18.299999 + + + + 19.500000 + + + + 19.500000 + + + + 22.500000 + + + + 23.299999 + + + + 23.299999 + + + + 22.700001 + + + + 22.700001 + + + + 22.799999 + + + + 23.400000 + + + + 24.000000 + + + + 24.000000 + + + + 21.100000 + + + + 20.100000 + + + + 19.799999 + + + + 19.500000 + + + + 19.500000 + + + + 19.299999 + + + + 18.600000 + + + + 18.600000 + + + + 16.799999 + + + + 16.200001 + + + + 15.800000 + + + + 17.100000 + + + + 16.600000 + + + + 16.700001 + + + + 16.700001 + + + + 16.799999 + + + + 17.700001 + + + + 17.700001 + + + + 17.400000 + + + + 16.900000 + + + + 16.700001 + + + + 16.700001 + + + + 18.100000 + + + + 18.700001 + + + + 18.400000 + + + + 17.500000 + + + + 17.000000 + + + + 17.700001 + + + + 18.200001 + + + + 20.400000 + + + + 21.700001 + + + + 21.600000 + + + + 21.600000 + + + + 25.200001 + + + + 26.200001 + + + + 27.000000 + + + + 27.000000 + + + + 28.500000 + + + + 28.299999 + + + + 28.799999 + + + + 27.700001 + + + + 27.900000 + + + + 28.500000 + + + + 28.900000 + + + + 28.900000 + + + + 30.000000 + + + + 29.700001 + + + + 27.700001 + + + + 27.700001 + + + + 26.600000 + + + + 27.400000 + + + + 27.100000 + + + + 27.100000 + + + + 26.600000 + + + + 26.600000 + + + + 26.600000 + + + + 26.299999 + + + + 27.200001 + + + + 27.200001 + + + + 28.200001 + + + + 28.500000 + + + + 28.500000 + + + + 31.000000 + + + + 32.099998 + + + + 32.099998 + + + + 34.299999 + + + + 34.900002 + + + + 35.000000 + + + + 35.000000 + + + + 34.900002 + + + + 35.299999 + + + + 36.500000 + + + + 36.500000 + + + + 38.599998 + + + + 38.799999 + + + + 39.200001 + + + + 39.200001 + + + + 38.900002 + + + + 38.400002 + + + + 38.400002 + + + + 35.299999 + + + + 34.299999 + + + + 33.799999 + + + + 31.400000 + + + + 30.400000 + + + + 29.900000 + + + + 29.400000 + + + + 29.200001 + + + + 29.200001 + + + + 28.600000 + + + + 27.900000 + + + + 27.000000 + + + + 25.700001 + + + + 25.700001 + + + + 22.400000 + + + + 22.200001 + + + + 22.000000 + + + + 21.100000 + + + + 18.299999 + + + + 19.100000 + + + + 18.799999 + + + + 18.799999 + + + + 23.600000 + + + + 24.100000 + + + + 24.299999 + + + + 25.400000 + + + + 25.400000 + + + + 25.100000 + + + + 26.000000 + + + + 26.900000 + + + + 28.200001 + + + + 28.200001 + + + + 33.599998 + + + + 34.599998 + + + + 34.500000 + + + + 34.200001 + + + + 33.799999 + + + + 33.400002 + + + + 32.299999 + + + + 32.299999 + + + + 31.400000 + + + + 30.600000 + + + + 30.799999 + + + + 29.799999 + + + + 28.900000 + + + + 28.000000 + + + + 23.400000 + + + + 23.100000 + + + + 22.500000 + + + + 21.799999 + + + + 20.500000 + + + + 19.900000 + + + + 20.000000 + + + + 19.200001 + + + + 19.200001 + + + + 18.000000 + + + + 18.299999 + + + + 18.200001 + + + + 18.200001 + + + + 19.500000 + + + + 19.000000 + + + + 19.200001 + + + + 19.400000 + + + + 19.400000 + + + + 23.100000 + + + + 23.000000 + + + + 23.900000 + + + + 23.900000 + + + + 28.299999 + + + + 28.000000 + + + + 27.299999 + + + + 27.299999 + + + + 24.700001 + + + + 25.100000 + + + + 25.000000 + + + + 25.400000 + + + + 25.400000 + + + + 23.799999 + + + + 22.900000 + + + + 23.100000 + + + + 23.000000 + + + + 23.000000 + + + + 24.400000 + + + + 24.299999 + + + + 24.600000 + + + + 26.400000 + + + + 26.000000 + + + + 25.000000 + + + + 24.900000 + + + + 24.900000 + + + + 24.900000 + + + + 25.100000 + + + + 25.100000 + + + + 25.799999 + + + + 26.200001 + + + + 26.600000 + + + + 26.600000 + + + + 26.900000 + + + + 27.100000 + + + + 26.400000 + + + + 25.400000 + + + + 25.400000 + + + + 25.299999 + + + + 26.100000 + + + + 27.500000 + + + + 28.100000 + + + + 28.500000 + + + + 28.500000 + + + + 35.299999 + + + + 36.900002 + + + + 36.700001 + + + + 36.700001 + + + + 38.400002 + + + + 38.599998 + + + + 38.599998 + + + + 38.599998 + + + + 38.599998 + + + + 38.900002 + + + + 38.299999 + + + + 38.700001 + + + + 38.700001 + + + + 38.200001 + + + + 37.700001 + + + + 37.599998 + + + + 37.599998 + + + + 37.500000 + + + + 37.500000 + + + + 35.799999 + + + + 34.599998 + + + + 34.599998 + + + + 34.900002 + + + + 35.400002 + + + + 36.000000 + + + + 36.599998 + + + + + diff --git a/reference/track/vitovtt-sample.vtt b/reference/track/vitovtt-sample.vtt new file mode 100644 index 0000000000000000000000000000000000000000..6911853b40c78cfd257089a48ff277697c815bf8 GIT binary patch literal 59720 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 + + + + + + + + 44.586548 + + 5066 + 5066 + 5066 + Crossing +Crossing + + + 57.607200 + + 5067 + 5067 + 5067 + Dot +Intersection + + + 44.826904 + + 5096 + 5096 + 5096 + Dot +Dot + + + 50.594727 + + 5142 + 5142 + 5142 + Dot +Dot + + + 127.711200 + + 5156 + 5156 + 5156 + Dot +Intersection + + + 96.926400 + + 5224 + 5224 + 5224 + Dot +Intersection + + + 82.600800 + + 5229 + 5229 + 5229 + Dot +Intersection + + + 82.905600 + + 5237 + 5237 + 5237 + Dot +Intersection + + + 66.696655 + + 5254 + 5254 + 5254 + Dot +Dot + + + 74.627442 + + 5258 + 5258 + 5258 + Dot +Dot + + + 65.254761 + + 5264 + 5264 + 5264 + Dot +Dot + + + 77.419200 + + 526708 + 526708 + 526708 + Dot +Intersection + + + 74.676000 + + 526750 + 526750 + 526750 + Dot +Intersection + + + 78.713135 + + 527614 + 527614 + 527614 + Dot +Dot + + + 78.713135 + + 527631 + 527631 + 527631 + Dot +Dot + + + 68.275200 + + 5278 + 5278 + 5278 + Dot +Intersection + + + 64.008000 + + 5289 + 5289 + 5289 + Dot +Intersection + + + 52.997925 + + 5374FIRE + 5374FIRE + 5374FIRE + Dot +Dot + + + 56.388000 + + 5376 + 5376 + 5376 + Dot +Intersection + + + 56.388000 + + 6006 + 600698 + 600698 + Dot +Intersection + + + 46.028564 + + 6006BLUE + 6006BLUE + 6006BLUE + Dot +Dot + + + 37.616943 + + 6014MEADOW + 6014MEADOW + 6014MEADOW + Dot +Dot + + + 56.388000 + + 6029 + 6029 + 6029 + Dot +Intersection + + + 50.292000 + + 6053 + 6053 + 6053 + Dot +Intersection + + + 25.603200 + + 6066 + 6066 + 6066 + Dot +Intersection + + + 34.442400 + + 6067 + 6067 + 6067 + Dot +Intersection + + + 30.480000 + + 6071 + 6071 + 6071 + Dot +Intersection + + + 15.240000 + + 6073 + 6073 + 6073 + Dot +Intersection + + + 37.795200 + + 6084 + 6084 + 6084 + Dot +Intersection + + + 64.008000 + + 6130 + 6130 + 6130 + Dot +Intersection + + + 64.008000 + + 6131 + 6131 + 6131 + Dot +Intersection + + + 62.788800 + + 6153 + 6153 + 6153 + Dot +Intersection + + + 55.473600 + + 6171 + 6171 + 6171 + Dot +Intersection + + + 62.484000 + + 6176 + 6176 + 6176 + Dot +Intersection + + + 62.179200 + + 6177 + 6177 + 6177 + Dot +Intersection + + + 69.799200 + + 6272 + 6272 + 6272 + Dot +Intersection + + + 73.152000 + + 6272 + 6272 + 6272 + Dot +Intersection + + + 70.104000 + + 6278 + 6278 + 6278 + Dot +Intersection + + + 57.564209 + + 6280 + 6280 + 6280 + Dot +Dot + + + 66.696655 + + 6283 + 6283 + 6283 + Dot +Dot + + + 72.945191 + + 6289 + 6289 + 6289 + Dot +Dot + + + 72.847200 + + 6297 + 6297 + 6297 + Dot +Intersection + + + 53.644800 + + 6328 + 6328 + 6328 + Dot +Intersection + + + 43.891200 + + 6354 + 6354 + 6354 + Dot +Intersection + + + 48.768000 + + 635722 + 635722 + 635722 + Dot +Intersection + + + 49.072800 + + 635783 + 635783 + 635783 + Dot +Intersection + + + 62.484000 + + 6373 + 6373 + 6373 + Dot +Intersection + + + 3.962400 + + 6634 + 6634 + 6634 + Dot +Intersection + + + 13.411200 + + 6979 + 6979 + 6979 + Dot +Intersection + + + 34.012085 + + 6997 + 6997 + 6997 + Dot +Dot + + + 87.782400 + + BEAR HILL + BEAR HILL TOWER + Bear Hill Tower + Tall Tower +Tower + + + 23.469600 + + BELLEVUE + BELLEVUE + Bellevue Parking Lot + Parking Area +Parking + + + 43.384766 + + 6016 + Bike Loop Connector + Bike Loop Connector + Waypoint +Intersection + + + 89.916000 + + 5236BRIDGE + Bridge + Bridge + Bridge +Bridge + + + 55.473600 + + 5376BRIDGE + Bridge + Bridge + Bridge +Bridge + + + 52.730400 + + 6181CROSS + Crossing + Crossing + Crossing +Crossing + + + 45.110400 + + 6042CROSS + Crossing + Crossing + Crossing +Crossing + + + DARKHOLLPO + Dark Hollow Pond + Dark Hollow Pond + Fishing Area + + + 56.083200 + + 6121DEAD + Dead End + Dead End + Danger Area +Dead End + + + 117.043200 + + 5179DEAD + Dead End + Dead End + Danger Area +Dead End + + + 69.494400 + + 5299DEAD + Dead End + Dead End + Danger Area +Dead End + + + 56.997600 + + 5376DEAD + Dead End + Dead End + Danger Area +Dead End + + + 46.939200 + + 6353DEAD + Dead End + Dead End + Danger Area +Dead End + + + 61.264800 + + 6155DEAD + Dead End + Dead End + Danger Area +Dead End + + + 110.947200 + + GATE14 + Gate 14 + Gate 14 + Truck Stop +Road + + + 77.724000 + + GATE16 + Gate 16 + Gate 16 + Truck Stop +Road + + + 65.836800 + + GATE17 + Gate 17 + Gate 17 + Truck Stop +Road + + + 57.302400 + + GATE19 + Gate 19 + Gate 19 + Truck Stop +Road + + + 49.377600 + + GATE21 + Gate 21 + Gate 21 + Truck Stop +Road + + + 81.076800 + + GATE24 + Gate 24 + Gate 24 + Truck Stop +Road + + + 21.515015 + + GATE5 + Gate 5 + Gate 5 + Truck Stop +Truck Stop + + + 26.561890 + + GATE6 + Gate 6 + Gate 6 + Waypoint +Trail Head + + + 32.004000 + + 6077LOGS + Log Crossing + Log Crossing + Amusement Park +Obstacle + + + 119.809082 + + 5148NANEPA + Nanepashemet Road Crossing + Nanepashemet Road Crossing + Waypoint +Trail Head + + + 73.761600 + + 5267OBSTAC + Obstacle + Obstacle + Amusement Park +Obstacle + + + 45.307495 + + PANTHRCAVE + Panther Cave + Panther Cave + Tunnel +Tunnel + + + 77.992066 + + 5252PURPLE + Purple Rock Hill + Purple Rock Hill + Summit +Summit + + + 67.970400 + + 5287WATER + Reservoir + Reservoir + Swimming Area +Reservoir + + + 81.076800 + + 5239ROAD + Road + Road + Truck Stop +Road + + + 67.360800 + + 5278ROAD + Road + Road + Truck Stop +Road + + + 53.949600 + + 5058ROAD + ROAD CROSSING + Road Crossing + Dot +Road Crossing + + + 69.799200 + + SHEEPFOLD + Sheepfold Parking Lot + Sheepfold Parking Lot + Parking Area +Parking + + + 64.008000 + + SOAPBOX + Soap Box Derby Track + Soap Box Derby Track + Cemetery +Intersection + + + 64.533692 + + 5376STREAM + Stream Crossing + Stream Crossing + Bridge +Bridge + + + 61.649902 + + 5144SUMMIT + Summit + Summit + Summit +Summit + + + 67.360800 + + 5150TANK + WATER TANK + Water Tank + Museum +Water Tank + + + diff --git a/reference/transform-wpt.gpx b/reference/transform-wpt.gpx new file mode 100644 index 000000000..a16a39b41 --- /dev/null +++ b/reference/transform-wpt.gpx @@ -0,0 +1,380 @@ + + + + + + + + 23.469600 + + BELLEVUE + BELLEVUE + Bellevue Parking Lot + Parking Area + + + 26.561890 + + GATE6 + Gate 6 + Gate 6 + Waypoint + + + 45.307495 + + PANTHRCAVE + Panther Cave + Panther Cave + Tunnel + + + 37.616943 + + 6014MEADOW + 6014MEADOW + 6014MEADOW + Dot + + + 56.388000 + + 6006 + 600698 + 600698 + Dot + + + 46.028564 + + 6006BLUE + 6006BLUE + 6006BLUE + Dot + + + 44.826904 + + 5096 + 5096 + 5096 + Dot + + + 44.586548 + + 5066 + 5066 + 5066 + Crossing + + + 57.607200 + + 5067 + 5067 + 5067 + Dot + + + 53.949600 + + 5058ROAD + ROAD CROSSING + Road Crossing + Dot + + + 67.360800 + + 5150TANK + WATER TANK + Water Tank + Museum + + + 50.594727 + + 5142 + 5142 + 5142 + Dot + + + 61.649902 + + 5144SUMMIT + Summit + Summit + Summit + + + 127.711200 + + 5156 + 5156 + 5156 + Dot + + + 119.809082 + + 5148NANEPA + Nanepashemet Road Crossing + Nanepashemet Road Crossing + Waypoint + + + 74.627442 + + 5258 + 5258 + 5258 + Dot + + + 77.992066 + + 5252PURPLE + Purple Rock Hill + Purple Rock Hill + Summit + + + 78.713135 + + 527631 + 527631 + 527631 + Dot + + + 78.713135 + + 527614 + 527614 + 527614 + Dot + + + 73.761600 + + 5267OBSTAC + Obstacle + Obstacle + Amusement Park + + + 68.275200 + + 5278 + 5278 + 5278 + Dot + + + 64.008000 + + 5289 + 5289 + 5289 + Dot + + + 52.997925 + + 5374FIRE + 5374FIRE + 5374FIRE + Dot + + + 56.388000 + + 5376 + 5376 + 5376 + Dot + + + 64.533692 + + 5376STREAM + Stream Crossing + Stream Crossing + Bridge + + + 53.644800 + + 6328 + 6328 + 6328 + Dot + + + 48.768000 + + 635722 + 635722 + 635722 + Dot + + + 49.072800 + + 635783 + 635783 + 635783 + Dot + + + 62.484000 + + 6373 + 6373 + 6373 + Dot + + + 87.782400 + + BEAR HILL + BEAR HILL TOWER + Bear Hill Tower + Tall Tower + + + 72.945191 + + 6289 + 6289 + 6289 + Dot + + + 72.847200 + + 6297 + 6297 + 6297 + Dot + + + 66.696655 + + 6283 + 6283 + 6283 + Dot + + + 57.564209 + + 6280 + 6280 + 6280 + Dot + + + 62.179200 + + 6177 + 6177 + 6177 + Dot + + + 62.484000 + + 6176 + 6176 + 6176 + Dot + + + 62.788800 + + 6153 + 6153 + 6153 + Dot + + + 55.473600 + + 6171 + 6171 + 6171 + Dot + + + 64.008000 + + 6131 + 6131 + 6131 + Dot + + + 64.008000 + + 6130 + 6130 + 6130 + Dot + + + 56.388000 + + 6029 + 6029 + 6029 + Dot + + + 56.388000 + + 6006 + 600698 + 600698 + Dot + + + 37.616943 + + 6014MEADOW + 6014MEADOW + 6014MEADOW + Dot + + + 45.307495 + + PANTHRCAVE + Panther Cave + Panther Cave + Tunnel + + + 26.561890 + + GATE6 + Gate 6 + Gate 6 + Waypoint + + + 23.469600 + + BELLEVUE + BELLEVUE + Bellevue Parking Lot + Parking Area + + diff --git a/reference/unicsv.gpx b/reference/unicsv.gpx new file mode 100644 index 000000000..09e2cf33b --- /dev/null +++ b/reference/unicsv.gpx @@ -0,0 +1,55 @@ + + + + + + GCEBB + Mountain Bike Heaven by susy1313 + Mountain Bike Heaven by susy1313 + + + GC1A37 + The Troll by a182pilot & Family + The Troll by a182pilot & Family + + + GC1C2B + Dive Bomber by JoGPS & family + Dive Bomber by JoGPS & family + + + GC25A9 + FOSTER by JoGPS & Family + FOSTER by JoGPS & Family + + + GC2723 + Logan Lighthouse by JoGps & Family + Logan Lighthouse by JoGps & Family + + + GC2B71 + Ganier Cache by Susy1313 + Ganier Cache by Susy1313 + + + GC309F + Shy's Hill by FireFighterEng33 + Shy's Hill by FireFighterEng33 + + + GC317A + GittyUp by JoGPS / Warner Parks + GittyUp by JoGPS / Warner Parks + + + GC317D + Inlighting by JoGPS / Warner Parks + Inlighting by JoGPS / Warner Parks + + diff --git a/reference/vitosmt.gpx b/reference/vitosmt.gpx new file mode 100644 index 000000000..72a6da92b --- /dev/null +++ b/reference/vitosmt.gpx @@ -0,0 +1,2200 @@ + + + + + + 33.700000 + + WP0001 + WP0001 + WP0001 + 2d + 3 + 30.600000 + + + 33.700000 + + WP0002 + WP0002 + WP0002 + 2d + 3 + 30.600000 + + + 105.400000 + + WP0003 + WP0003 + WP0003 + dgps + 7 + 1.400000 + + + 104.600000 + + WP0004 + WP0004 + WP0004 + dgps + 5 + 2.400000 + + + 102.500000 + + WP0005 + WP0005 + WP0005 + dgps + 5 + 2.400000 + + + 108.900000 + + WP0006 + WP0006 + WP0006 + dgps + 6 + 2.200000 + + + 108.400000 + + WP0007 + WP0007 + WP0007 + dgps + 9 + 1.000000 + + + 110.600000 + + WP0008 + WP0008 + WP0008 + dgps + 8 + 1.400000 + + + 106.200000 + + WP0009 + WP0009 + WP0009 + dgps + 10 + 1.000000 + + + 34.100000 + + WP0010 + WP0010 + WP0010 + 2d + 3 + 7.000000 + + + -22.300000 + + WP0011 + WP0011 + WP0011 + dgps + 5 + 2.600000 + + + -34.800000 + + WP0012 + WP0012 + WP0012 + 3d + 4 + 3.400000 + + + -28.700000 + + WP0013 + WP0013 + WP0013 + dgps + 5 + 2.600000 + + + -21.000000 + + WP0014 + WP0014 + WP0014 + 3d + 4 + 3.800000 + + + -25.300000 + + WP0015 + WP0015 + WP0015 + 2 + + + 43.400000 + + WP0016 + WP0016 + WP0016 + 3d + 4 + 3.800000 + + + 39.300000 + + WP0017 + WP0017 + WP0017 + dgps + 6 + 1.600000 + + + 48.300000 + + WP0018 + WP0018 + WP0018 + dgps + 5 + 1.600000 + + + 44.500000 + + WP0019 + WP0019 + WP0019 + dgps + 5 + 1.600000 + + + 39.900000 + + WP0020 + WP0020 + WP0020 + dgps + 5 + 2.600000 + + + 23.600000 + + WP0021 + WP0021 + WP0021 + dgps + 5 + 2.600000 + + + 46.700000 + + WP0022 + WP0022 + WP0022 + 3d + 4 + 4.000000 + + + 61.300000 + + WP0023 + WP0023 + WP0023 + dgps + 5 + 1.600000 + + + 74.600000 + + WP0024 + WP0024 + WP0024 + 3d + 4 + 4.000000 + + + 63.600000 + + WP0025 + WP0025 + WP0025 + 3d + 4 + 2.200000 + + + 83.600000 + + WP0026 + WP0026 + WP0026 + 3d + 4 + 5.200000 + + + 76.200000 + + WP0027 + WP0027 + WP0027 + 3d + 4 + 5.200000 + + + 76.300000 + + WP0028 + WP0028 + WP0028 + 2d + 3 + 10.600000 + + + 59.800000 + + WP0029 + WP0029 + WP0029 + 3d + 4 + 5.200000 + + + 34.300000 + + WP0030 + WP0030 + WP0030 + 2d + 3 + 25.400000 + + + 34.300000 + + WP0031 + WP0031 + WP0031 + 2d + 3 + 28.200001 + + + 34.300000 + + WP0032 + WP0032 + WP0032 + 2d + 3 + 28.200001 + + + 70.800000 + + WP0033 + WP0033 + WP0033 + dgps + 5 + 1.800000 + + + 61.200000 + + WP0034 + WP0034 + WP0034 + 3d + 4 + 2.000000 + + + 62.400000 + + WP0035 + WP0035 + WP0035 + 1 + + + 54.200000 + + WP0036 + WP0036 + WP0036 + 3d + 4 + 6.800000 + + + 57.000000 + + WP0037 + WP0037 + WP0037 + 3d + 4 + 19.400000 + + + 0.000000 + + WP0038 + WP0038 + WP0038 + 24.700001 + + + 57.600000 + + WP0039 + WP0039 + WP0039 + 3d + 4 + 17.799999 + + + 74.800000 + + WP0040 + WP0040 + WP0040 + dgps + 7 + 1.000000 + + + 95.100000 + + WP0041 + WP0041 + WP0041 + dgps + 5 + 1.600000 + + + 69.100000 + + WP0042 + WP0042 + WP0042 + dgps + 7 + 1.000000 + + + 71.300000 + + WP0043 + WP0043 + WP0043 + dgps + 7 + 1.000000 + + + 71.300000 + + WP0044 + WP0044 + WP0044 + dgps + 6 + 1.400000 + + + 71.300000 + + WP0045 + WP0045 + WP0045 + dgps + 6 + 1.400000 + + + 70.700000 + + WP0046 + WP0046 + WP0046 + dgps + 6 + 1.400000 + + + 68.400000 + + WP0047 + WP0047 + WP0047 + dgps + 6 + 1.200000 + + + 72.900000 + + WP0048 + WP0048 + WP0048 + dgps + 6 + 1.200000 + + + 71.400000 + + WP0049 + WP0049 + WP0049 + dgps + 7 + 1.000000 + + + 71.200000 + + WP0050 + WP0050 + WP0050 + dgps + 8 + 1.000000 + + + 71.600000 + + WP0051 + WP0051 + WP0051 + dgps + 7 + 1.400000 + + + 71.000000 + + WP0052 + WP0052 + WP0052 + 2 + + + 72.100000 + + WP0053 + WP0053 + WP0053 + 2 + + + 72.700000 + + WP0054 + WP0054 + WP0054 + 2d + 3 + 6.200000 + + + 72.200000 + + WP0055 + WP0055 + WP0055 + 2 + + + 72.500000 + + WP0056 + WP0056 + WP0056 + 2 + + + 73.000000 + + WP0057 + WP0057 + WP0057 + 2 + + + 73.300000 + + WP0058 + WP0058 + WP0058 + 2d + 3 + 19.400000 + + + 78.100000 + + WP0059 + WP0059 + WP0059 + 2d + 3 + 6.000000 + + + 77.000000 + + WP0060 + WP0060 + WP0060 + 3d + 4 + 4.200000 + + + 75.500000 + + WP0061 + WP0061 + WP0061 + 3d + 4 + 4.200000 + + + 71.000000 + + WP0062 + WP0062 + WP0062 + 3d + 4 + 12.400000 + + + 75.800000 + + WP0063 + WP0063 + WP0063 + 3d + 4 + 4.200000 + + + 72.600000 + + WP0064 + WP0064 + WP0064 + dgps + 6 + 1.600000 + + + 70.300000 + + WP0065 + WP0065 + WP0065 + dgps + 5 + 2.800000 + + + 74.600000 + + WP0066 + WP0066 + WP0066 + dgps + 5 + 1.800000 + + + 76.300000 + + WP0067 + WP0067 + WP0067 + dgps + 5 + 1.600000 + + + 72.100000 + + WP0068 + WP0068 + WP0068 + 2d + 3 + 5.200000 + + + 80.900000 + + WP0069 + WP0069 + WP0069 + 3d + 4 + 4.000000 + + + 89.500000 + + WP0070 + WP0070 + WP0070 + 3d + 4 + 4.000000 + + + 102.100000 + + WP0071 + WP0071 + WP0071 + 3d + 4 + 2.200000 + + + 102.800000 + + WP0072 + WP0072 + WP0072 + 2d + 3 + 13.400000 + + + 94.100000 + + WP0073 + WP0073 + WP0073 + dgps + 5 + 1.600000 + + + 93.300000 + + WP0074 + WP0074 + WP0074 + dgps + 5 + 1.600000 + + + 83.800000 + + WP0075 + WP0075 + WP0075 + 2 + + + 85.100000 + + WP0076 + WP0076 + WP0076 + 2 + + + 85.600000 + + WP0077 + WP0077 + WP0077 + 2d + 3 + 16.000000 + + + 85.900000 + + WP0078 + WP0078 + WP0078 + 2 + + + 85.200000 + + WP0079 + WP0079 + WP0079 + 3d + 4 + 2.400000 + + + 87.100000 + + WP0080 + WP0080 + WP0080 + 3d + 4 + 3.200000 + + + 82.300000 + + WP0081 + WP0081 + WP0081 + dgps + 6 + 1.200000 + + + 78.800000 + + WP0082 + WP0082 + WP0082 + 3d + 4 + 2.400000 + + + 75.500000 + + WP0083 + WP0083 + WP0083 + dgps + 5 + 1.400000 + + + 74.100000 + + WP0084 + WP0084 + WP0084 + 3d + 4 + 2.000000 + + + 72.500000 + + WP0085 + WP0085 + WP0085 + 2 + + + 74.000000 + + WP0086 + WP0086 + WP0086 + 2d + 3 + 40.599998 + + + 74.700000 + + WP0087 + WP0087 + WP0087 + 3d + 4 + 2.000000 + + + 72.300000 + + WP0088 + WP0088 + WP0088 + + + 72.200000 + + WP0089 + WP0089 + WP0089 + + + 73.000000 + + WP0090 + WP0090 + WP0090 + 2d + 3 + 38.200001 + + + 74.400000 + + WP0091 + WP0091 + WP0091 + 2 + + + 81.200000 + + WP0092 + WP0092 + WP0092 + 2d + 3 + 37.200001 + + + 70.100000 + + WP0093 + WP0093 + WP0093 + 3d + 4 + 9.400000 + + + 64.400000 + + WP0094 + WP0094 + WP0094 + 2 + + + 64.000000 + + WP0095 + WP0095 + WP0095 + 1 + + + 64.600000 + + WP0096 + WP0096 + WP0096 + 2d + 3 + 23.000000 + + + 67.300000 + + WP0097 + WP0097 + WP0097 + 2d + 3 + 5.200000 + + + 71.400000 + + WP0098 + WP0098 + WP0098 + 3d + 4 + 43.599998 + + + 71.700000 + + WP0099 + WP0099 + WP0099 + 2d + 3 + 24.200001 + + + 72.300000 + + WP0100 + WP0100 + WP0100 + 3d + 4 + 2.200000 + + + 81.200000 + + WP0101 + WP0101 + WP0101 + 2d + 3 + 36.400002 + + + 74.500000 + + WP0102 + WP0102 + WP0102 + 2 + + + 74.700000 + + WP0103 + WP0103 + WP0103 + 2d + 3 + 13.600000 + + + 76.200000 + + WP0104 + WP0104 + WP0104 + 2d + 3 + 50.000000 + + + 77.900000 + + WP0105 + WP0105 + WP0105 + 2d + 3 + 26.400000 + + + 78.600000 + + WP0106 + WP0106 + WP0106 + 3d + 4 + 50.000000 + + + 80.700000 + + WP0107 + WP0107 + WP0107 + dgps + 5 + 1.600000 + + + 84.400000 + + WP0108 + WP0108 + WP0108 + 2 + + + 92.600000 + + WP0109 + WP0109 + WP0109 + dgps + 5 + 2.000000 + + + 95.800000 + + WP0110 + WP0110 + WP0110 + 3d + 4 + 5.000000 + + + 94.700000 + + WP0111 + WP0111 + WP0111 + dgps + 7 + 0.800000 + + + 59.200000 + + WP0112 + WP0112 + WP0112 + 3d + 4 + 9.400000 + + + 55.200000 + + WP0113 + WP0113 + WP0113 + 2d + 3 + 6.000000 + + + 56.100000 + + WP0114 + WP0114 + WP0114 + 2d + 3 + 7.600000 + + + 54.500000 + + WP0115 + WP0115 + WP0115 + 3d + 4 + 11.800000 + + + 48.700000 + + WP0116 + WP0116 + WP0116 + 2 + + + 43.700000 + + WP0117 + WP0117 + WP0117 + 2d + 3 + 7.200000 + + + 45.100000 + + WP0118 + WP0118 + WP0118 + 2 + + + 44.600000 + + WP0119 + WP0119 + WP0119 + 3d + 4 + 16.600000 + + + 44.100000 + + WP0120 + WP0120 + WP0120 + 2 + + + 43.000000 + + WP0121 + WP0121 + WP0121 + 2 + + + 42.000000 + + WP0122 + WP0122 + WP0122 + 2d + 3 + 7.200000 + + + 41.400000 + + WP0123 + WP0123 + WP0123 + 2d + 3 + 6.800000 + + + 41.600000 + + WP0124 + WP0124 + WP0124 + 2d + 3 + 6.800000 + + + 41.600000 + + WP0125 + WP0125 + WP0125 + 1 + + + 41.600000 + + WP0126 + WP0126 + WP0126 + 2d + 3 + 7.000000 + + + 41.600000 + + WP0127 + WP0127 + WP0127 + 2 + + + 41.600000 + + WP0128 + WP0128 + WP0128 + 2 + + + 41.600000 + + WP0129 + WP0129 + WP0129 + 2 + + + 41.600000 + + WP0130 + WP0130 + WP0130 + 2 + + + 41.600000 + + WP0131 + WP0131 + WP0131 + 1 + + + 41.600000 + + WP0132 + WP0132 + WP0132 + 2d + 3 + 7.400000 + + + 41.700000 + + WP0133 + WP0133 + WP0133 + 3d + 4 + 33.799999 + + + 41.700000 + + WP0134 + WP0134 + WP0134 + 2d + 3 + 6.800000 + + + 41.800000 + + WP0135 + WP0135 + WP0135 + 2 + + + 42.300000 + + WP0136 + WP0136 + WP0136 + 3d + 4 + 21.799999 + + + 45.200000 + + WP0137 + WP0137 + WP0137 + 2d + 3 + 7.000000 + + + 46.700000 + + WP0138 + WP0138 + WP0138 + 2d + 3 + 8.400000 + + + 47.400000 + + WP0139 + WP0139 + WP0139 + 2d + 3 + 8.600000 + + + 48.300000 + + WP0140 + WP0140 + WP0140 + 2 + + + 49.000000 + + WP0141 + WP0141 + WP0141 + + + 49.400000 + + WP0142 + WP0142 + WP0142 + 2 + + + 49.900000 + + WP0143 + WP0143 + WP0143 + 3d + 4 + 8.200000 + + + 49.500000 + + WP0144 + WP0144 + WP0144 + 2d + 3 + 6.400000 + + + 55.000000 + + WP0145 + WP0145 + WP0145 + 2d + 3 + 9.400000 + + + 56.600000 + + WP0146 + WP0146 + WP0146 + 2d + 3 + 5.400000 + + + 56.100000 + + WP0147 + WP0147 + WP0147 + 2d + 3 + 10.000000 + + + 56.700000 + + WP0148 + WP0148 + WP0148 + 2 + + + 70.600000 + + WP0149 + WP0149 + WP0149 + 3d + 4 + 5.200000 + + + 75.600000 + + WP0150 + WP0150 + WP0150 + 3d + 4 + 5.000000 + + + 76.100000 + + WP0151 + WP0151 + WP0151 + 2d + 3 + 10.600000 + + + 77.400000 + + WP0152 + WP0152 + WP0152 + 2d + 3 + 6.400000 + + + 84.500000 + + WP0153 + WP0153 + WP0153 + 1 + + + 90.200000 + + WP0154 + WP0154 + WP0154 + 2 + + + 93.200000 + + WP0155 + WP0155 + WP0155 + 2 + + + 94.400000 + + WP0156 + WP0156 + WP0156 + 2d + 3 + 6.400000 + + + 95.400000 + + WP0157 + WP0157 + WP0157 + 2 + + + 96.500000 + + WP0158 + WP0158 + WP0158 + 2d + 3 + 6.200000 + + + 96.300000 + + WP0159 + WP0159 + WP0159 + 2 + + + 97.000000 + + WP0160 + WP0160 + WP0160 + 2d + 3 + 6.200000 + + + 96.900000 + + WP0161 + WP0161 + WP0161 + 2 + + + 98.200000 + + WP0162 + WP0162 + WP0162 + 2d + 3 + 6.200000 + + + 98.600000 + + WP0163 + WP0163 + WP0163 + 2d + 3 + 6.200000 + + + 98.400000 + + WP0164 + WP0164 + WP0164 + 2 + + + 98.200000 + + WP0165 + WP0165 + WP0165 + 2d + 3 + 6.200000 + + + 97.000000 + + WP0166 + WP0166 + WP0166 + 2d + 3 + 6.200000 + + + 96.600000 + + WP0167 + WP0167 + WP0167 + 2d + 3 + 13.400000 + + + 96.100000 + + WP0168 + WP0168 + WP0168 + 3d + 4 + 3.200000 + + + 94.800000 + + WP0169 + WP0169 + WP0169 + 2d + 3 + 13.400000 + + + 95.200000 + + WP0170 + WP0170 + WP0170 + 2d + 3 + 13.600000 + + + 93.600000 + + WP0171 + WP0171 + WP0171 + 2d + 3 + 8.800000 + + + 92.400000 + + WP0172 + WP0172 + WP0172 + 3d + 4 + 3.000000 + + + 91.200000 + + WP0173 + WP0173 + WP0173 + 3d + 4 + 3.000000 + + + 92.400000 + + WP0174 + WP0174 + WP0174 + 2d + 3 + 6.200000 + + + 94.400000 + + WP0175 + WP0175 + WP0175 + 3d + 4 + 2.800000 + + + 92.800000 + + WP0176 + WP0176 + WP0176 + 3d + 4 + 2.800000 + + + 94.900000 + + WP0177 + WP0177 + WP0177 + 2d + 3 + 9.000000 + + + 95.600000 + + WP0178 + WP0178 + WP0178 + 3d + 4 + 2.800000 + + + 96.300000 + + WP0179 + WP0179 + WP0179 + 2d + 3 + 9.200000 + + + 96.300000 + + WP0180 + WP0180 + WP0180 + 1 + + + 98.800000 + + WP0181 + WP0181 + WP0181 + 3d + 4 + 2.600000 + + + 97.900000 + + WP0182 + WP0182 + WP0182 + 2d + 3 + 9.600000 + + + 97.600000 + + WP0183 + WP0183 + WP0183 + 1 + + + 97.300000 + + WP0184 + WP0184 + WP0184 + + + 97.500000 + + WP0185 + WP0185 + WP0185 + 2 + + + 97.700000 + + WP0186 + WP0186 + WP0186 + 2 + + + 98.100000 + + WP0187 + WP0187 + WP0187 + 2 + + + 98.200000 + + WP0188 + WP0188 + WP0188 + 2 + + + 98.200000 + + WP0189 + WP0189 + WP0189 + + + 97.900000 + + WP0190 + WP0190 + WP0190 + 2 + + + 97.800000 + + WP0191 + WP0191 + WP0191 + 1 + + + 101.300000 + + WP0192 + WP0192 + WP0192 + 2 + + + 105.300000 + + WP0193 + WP0193 + WP0193 + 2d + 3 + 10.000000 + + + 105.600000 + + WP0194 + WP0194 + WP0194 + 2 + + + 105.700000 + + WP0195 + WP0195 + WP0195 + 1 + + + 104.700000 + + WP0196 + WP0196 + WP0196 + 2 + + + 103.600000 + + WP0197 + WP0197 + WP0197 + 2 + + + 101.300000 + + WP0198 + WP0198 + WP0198 + 2 + + + 99.900000 + + WP0199 + WP0199 + WP0199 + 2d + 3 + 2.600000 + + + 98.100000 + + WP0200 + WP0200 + WP0200 + 1 + + + 97.900000 + + WP0201 + WP0201 + WP0201 + 2 + + + 97.700000 + + WP0202 + WP0202 + WP0202 + 1 + + + 97.700000 + + WP0203 + WP0203 + WP0203 + 2 + + + 97.700000 + + WP0204 + WP0204 + WP0204 + 2 + + + 97.500000 + + WP0205 + WP0205 + WP0205 + 2 + + + 97.300000 + + WP0206 + WP0206 + WP0206 + 2 + + + 97.100000 + + WP0207 + WP0207 + WP0207 + 1 + + + 97.000000 + + WP0208 + WP0208 + WP0208 + 1 + + + 97.100000 + + WP0209 + WP0209 + WP0209 + 2d + 3 + 6.400000 + + + 97.200000 + + WP0210 + WP0210 + WP0210 + 2d + 3 + 6.400000 + + + 97.100000 + + WP0211 + WP0211 + WP0211 + 2d + 3 + 6.400000 + + + 96.900000 + + WP0212 + WP0212 + WP0212 + 1 + + + 96.900000 + + WP0213 + WP0213 + WP0213 + 2 + + + 97.300000 + + WP0214 + WP0214 + WP0214 + + + 97.200000 + + WP0215 + WP0215 + WP0215 + 2d + 3 + 6.400000 + + + 97.200000 + + WP0216 + WP0216 + WP0216 + 2 + + + 97.100000 + + WP0217 + WP0217 + WP0217 + 1 + + + 97.400000 + + WP0218 + WP0218 + WP0218 + + + 97.500000 + + WP0219 + WP0219 + WP0219 + 2 + + + 97.500000 + + WP0220 + WP0220 + WP0220 + 1 + + + 97.500000 + + WP0221 + WP0221 + WP0221 + 1 + + + 97.400000 + + WP0222 + WP0222 + WP0222 + 1 + + + 97.400000 + + WP0223 + WP0223 + WP0223 + + + 97.300000 + + WP0224 + WP0224 + WP0224 + 2 + + + 97.300000 + + WP0225 + WP0225 + WP0225 + 2 + + + 99.000000 + + WP0226 + WP0226 + WP0226 + 2d + 3 + 2.000000 + + + 99.300000 + + WP0227 + WP0227 + WP0227 + 2 + + + 99.200000 + + WP0228 + WP0228 + WP0228 + 2d + 3 + 2.000000 + + + 99.000000 + + WP0229 + WP0229 + WP0229 + 2d + 3 + 2.000000 + + + 98.600000 + + WP0230 + WP0230 + WP0230 + 2d + 3 + 2.000000 + + + 98.300000 + + WP0231 + WP0231 + WP0231 + 1 + + + 98.000000 + + WP0232 + WP0232 + WP0232 + 1 + + + 98.200000 + + WP0233 + WP0233 + WP0233 + 1 + + + 98.400000 + + WP0234 + WP0234 + WP0234 + 1 + + + 98.400000 + + WP0235 + WP0235 + WP0235 + 2d + 3 + 2.000000 + + + 98.100000 + + WP0236 + WP0236 + WP0236 + 2 + + + 97.400000 + + WP0237 + WP0237 + WP0237 + 2 + + diff --git a/reference/vitosmt.smt b/reference/vitosmt.smt new file mode 100644 index 0000000000000000000000000000000000000000..3179e59aca8c47c188b2ac577070c019aa72c27a GIT binary patch literal 15192 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 NzrJOXuhHps{|97SdzSzJ literal 0 HcmV?d00001 diff --git a/reference/waypoints.gpssim b/reference/waypoints.gpssim new file mode 100644 index 000000000..9d7800ab9 --- /dev/null +++ b/reference/waypoints.gpssim @@ -0,0 +1,9 @@ +$FRWPT,3558.32200,N,08708.08200,W,0.0*69 +$FRWPT,3605.44100,N,08640.77300,W,0.0*64 +$FRWPT,3559.77600,N,08637.20700,W,0.0*6F +$FRWPT,3602.30900,N,08638.91700,W,0.0*6B +$FRWPT,3606.73100,N,08644.50600,W,0.0*67 +$FRWPT,3603.84500,N,08647.43100,W,0.0*68 +$FRWPT,3605.26600,N,08648.58400,W,0.0*65 +$FRWPT,3603.45000,N,08653.52000,W,0.0*64 +$FRWPT,3604.96800,N,08652.03700,W,0.0*67 diff --git a/reference/waypointsDMm.kwf b/reference/waypointsDMm.kwf new file mode 100644 index 000000000..962a2feb1 --- /dev/null +++ b/reference/waypointsDMm.kwf @@ -0,0 +1,13 @@ +//Kartex WaypointFil skapad av Kartex 5.0 +&KWF 2.0,sweref 99 lat long,1 +#,0,GC1B51,N56°4.717' E13°7.465',0.00,,,12,,$ +#,1,GC1DE6,N56°23.471' E12°53.771',0.00,,,12,,$ +#,2,GC1E56,N57°28.592' E12°10.402',0.00,,,12,,$ +#,3,GC2182,N56°13.627' E14°21.366',0.00,,,12,,$ +#,4,GC23F6,N57°21.837' E12°50.586',0.00,,,12,,$ +#,5,GC28B4,N56°19.809' E14°22.637',0.00,,,12,,$ +#,6,GC2A45,N56°42.798' E13°1.599',0.00,,,12,,$ +#,7,GC2AFD,N56°11.461' E14°16.266',0.00,,,12,,$ +#,8,GC2BC9,N56°8.548' E14°33.886',0.00,,,12,,$ +#,9,GC2BCA,N56°18.119' E13°3.645',0.00,,,12,,$ +#,10,GC2D31,N57°22.484' E12°54.991',0.00,,,12,,$ diff --git a/reference/waypointsDd.kwf b/reference/waypointsDd.kwf new file mode 100644 index 000000000..8e3499aae --- /dev/null +++ b/reference/waypointsDd.kwf @@ -0,0 +1,13 @@ +//Kartex WaypointFil skapad av Kartex 5.0 +&KWF 2.0,sweref 99 lat long,0 +#,0,GC1B51,N56.078617° E13.124417°,0.00,,,12,,$ +#,1,GC1DE6,N56.391183° E12.896183°,0.00,,,12,,$ +#,2,GC1E56,N57.476533° E12.173367°,0.00,,,12,,$ +#,3,GC2182,N56.227117° E14.356100°,0.00,,,12,,$ +#,4,GC23F6,N57.363950° E12.843100°,0.00,,,12,,$ +#,5,GC28B4,N56.330150° E14.377283°,0.00,,,12,,$ +#,6,GC2A45,N56.713300° E13.026650°,0.00,,,12,,$ +#,7,GC2AFD,N56.191017° E14.271100°,0.00,,,12,,$ +#,8,GC2BC9,N56.142467° E14.564767°,0.00,,,12,,$ +#,9,GC2BCA,N56.301983° E13.060750°,0.00,,,12,,$ +#,10,GC2D31,N57.374733° E12.916517°,0.00,,,12,,$ diff --git a/reference/wbt-200.bin b/reference/wbt-200.bin new file mode 100644 index 0000000000000000000000000000000000000000..a99d163971af83c4c1f8ab3e425b907c86f18749 GIT binary patch literal 3120 zcmXZeca&De83*9FQBZ>oIJq%~Yq>I?WxOU=;o97ht8p{Fi>q@t?#Z>d3t!EFoAc?;Nt(^s zypwadDzD}SeAIs}w%9~}F$?6lH@rAwUn53(? z+twIPwolUaeE+r>#L2sc~d4g8TR6z<@v6h`|{CEo>9+t@m+l2<|G}IvHX|t5Wd2Ac5af6)i=TiQ9Sq!tT zS3f-3{8!3$6_oKiT8dSLw%WVh=SOZx(o@`SWeh*_*_W#s9%CQRcTtz?{w;SiQzN9y@m%D#ZbYG z_;-adB4lGn=Tah}W#R>iPZ&INp$cgc1puaMgic^2^{Yt*grIoy@U8lTVO z_&Q#|udG!A<|*c6oo~>134h4Ft*4Ynt&gFqep1GN;V!(AhjBe#$4~IRypiYdJl?|Z za2apo4|qP8^A`SsckwCS%lo+ch8T|XL9WlW?QaG5`P8>5s}nqc7jjn6WBCYI<~#T& zu5xC)pE{|=gNWB9@ z6JLKw{cy=)z2dLxhhIMx!*8a!^YGjQG2ET6ez?qeH)ELk;pJOmSk+Jc@RPo&mv2=+ z{4n>{#|Cp_y*JgPMsORwrKNLlG?(i0i}d!f+(`d9?kvdXjrzk78BXGbU&XMvkNV+` z_U;nzRlrmAlNa=gncTsD4KZgC=W?F!aSpe3&R*MF{cy>bYUU30!%uLPKdT?U$ukYP zgdgL?noBd!^E58wdv@BFLF$LcyBp*TS3lfLCNGXxKm5^g_4$AyY26W zO#k5@?dke^)DJJK@Q%;9^Kg#4$D!Mjv?k}tYNa!-4qxX!@RnY86`v!kbGRuVH|J7y z(voxCHy&_jXvh1%(Ze5fpW)iuoI&cRE9at=O2k-!XruApBL}b nKgT8MGu*-d7CT3#@*1^Q=}~t-&fI^p)J*Ob?iKdB(E0U0T7=qB literal 0 HcmV?d00001 diff --git a/reference/wbt-200.gpx b/reference/wbt-200.gpx new file mode 100644 index 000000000..e6f95ac55 --- /dev/null +++ b/reference/wbt-200.gpx @@ -0,0 +1,793 @@ + + + + + + + TP0001 + + + TP0002 + + + TP0003 + + + TP0004 + + + TP0005 + + + TP0006 + + + TP0007 + + + TP0008 + + + TP0009 + + + TP0010 + + + TP0011 + + + TP0012 + + + TP0013 + + + TP0014 + + + TP0015 + + + TP0016 + + + TP0017 + + + TP0018 + + + TP0019 + + + TP0020 + + + TP0021 + + + TP0022 + + + TP0023 + + + TP0024 + + + TP0025 + + + TP0026 + + + TP0027 + + + TP0028 + + + TP0029 + + + TP0030 + + + TP0031 + + + TP0032 + + + TP0033 + + + TP0034 + + + TP0035 + + + TP0036 + + + TP0037 + + + TP0038 + + + TP0039 + + + TP0040 + + + TP0041 + + + TP0042 + + + TP0043 + + + TP0044 + + + TP0045 + + + TP0046 + + + TP0047 + + + TP0048 + + + TP0049 + + + TP0050 + + + TP0051 + + + TP0052 + + + TP0053 + + + TP0054 + + + TP0055 + + + TP0056 + + + TP0057 + + + TP0058 + + + TP0059 + + + TP0060 + + + TP0061 + + + TP0062 + + + TP0063 + + + TP0064 + + + TP0065 + + + TP0066 + + + TP0067 + + + TP0068 + + + TP0069 + + + TP0070 + + + TP0071 + + + TP0072 + + + TP0073 + + + TP0074 + + + TP0075 + + + TP0076 + + + TP0077 + + + TP0078 + + + TP0079 + + + TP0080 + + + TP0081 + + + TP0082 + + + TP0083 + + + TP0084 + + + TP0085 + + + TP0086 + + + TP0087 + + + TP0088 + + + TP0089 + + + TP0090 + + + TP0091 + + + TP0092 + + + TP0093 + + + TP0094 + + + TP0095 + + + TP0096 + + + TP0097 + + + TP0098 + + + TP0099 + + + TP0100 + + + TP0101 + + + TP0102 + + + TP0103 + + + TP0104 + + + TP0105 + + + TP0106 + + + TP0107 + + + TP0108 + + + TP0109 + + + TP0110 + + + TP0111 + + + TP0112 + + + TP0113 + + + TP0114 + + + TP0115 + + + TP0116 + + + TP0117 + + + TP0118 + + + TP0119 + + + TP0120 + + + TP0121 + + + TP0122 + + + TP0123 + + + TP0124 + + + TP0125 + + + TP0126 + + + TP0127 + + + TP0128 + + + TP0129 + + + TP0130 + + + TP0131 + + + TP0132 + + + TP0133 + + + TP0134 + + + TP0135 + + + TP0136 + + + TP0137 + + + TP0138 + + + TP0139 + + + TP0140 + + + TP0141 + + + TP0142 + + + TP0143 + + + TP0144 + + + TP0145 + + + TP0146 + + + TP0147 + + + TP0148 + + + TP0149 + + + TP0150 + + + TP0151 + + + TP0152 + + + TP0153 + + + TP0154 + + + TP0155 + + + TP0156 + + + TP0157 + + + TP0158 + + + TP0159 + + + TP0160 + + + TP0161 + + + TP0162 + + + TP0163 + + + TP0164 + + + TP0165 + + + TP0166 + + + TP0167 + + + TP0168 + + + TP0169 + + + TP0170 + + + TP0171 + + + TP0172 + + + TP0173 + + + TP0174 + + + TP0175 + + + TP0176 + + + TP0177 + + + TP0178 + + + TP0179 + + + TP0180 + + + TP0181 + + + TP0182 + + + TP0183 + + + TP0184 + + + TP0185 + + + TP0186 + + + TP0187 + + + TP0188 + + + TP0189 + + + TP0190 + + + TP0191 + + + TP0192 + + + TP0193 + + + TP0194 + + + TP0195 + + + TP0196 + + + TP0197 + + + TP0198 + + + TP0199 + + + TP0200 + + + TP0201 + + + TP0202 + + + TP0203 + + + TP0204 + + + TP0205 + + + TP0206 + + + TP0207 + + + TP0208 + + + TP0209 + + + TP0210 + + + TP0211 + + + TP0212 + + + TP0213 + + + TP0214 + + + TP0215 + + + TP0216 + + + TP0217 + + + TP0218 + + + TP0219 + + + TP0220 + + + TP0221 + + + TP0222 + + + TP0223 + + + TP0224 + + + TP0225 + + + TP0226 + + + TP0227 + + + TP0228 + + + TP0229 + + + TP0230 + + + TP0231 + + + TP0232 + + + TP0233 + + + TP0234 + + + TP0235 + + + TP0236 + + + TP0237 + + + TP0238 + + + TP0239 + + + TP0240 + + + TP0241 + + + TP0242 + + + TP0243 + + + TP0244 + + + TP0245 + + + TP0246 + + + TP0247 + + + TP0248 + + + TP0249 + + + TP0250 + + + TP0251 + + + TP0252 + + + TP0253 + + + TP0254 + + + TP0255 + + + TP0256 + + + TP0257 + + + TP0258 + + + TP0259 + + + TP0260 + + + + diff --git a/reference/wbt-201.gpx b/reference/wbt-201.gpx new file mode 100644 index 000000000..e051ecfb6 --- /dev/null +++ b/reference/wbt-201.gpx @@ -0,0 +1,16151 @@ + + + + + 378.000000 + WP0001 + WP0001 + WP0001 + + + 379.000000 + WP0002 + WP0002 + WP0002 + + + 379.000000 + WP0003 + WP0003 + WP0003 + + + 377.000000 + WP0004 + WP0004 + WP0004 + + + 531.000000 + WP0005 + WP0005 + WP0005 + + + + + 435.000000 + TP0001 + + + 434.000000 + TP0002 + + + 435.000000 + TP0003 + + + 434.000000 + TP0004 + + + 434.000000 + TP0005 + + + 434.000000 + TP0006 + + + 433.000000 + TP0007 + + + 433.000000 + TP0008 + + + 434.000000 + TP0009 + + + 434.000000 + TP0010 + + + 433.000000 + TP0011 + + + 433.000000 + TP0012 + + + 433.000000 + TP0013 + + + 433.000000 + TP0014 + + + 433.000000 + TP0015 + + + 432.000000 + TP0016 + + + 431.000000 + TP0017 + + + 430.000000 + TP0018 + + + 430.000000 + TP0019 + + + 430.000000 + TP0020 + + + 431.000000 + TP0021 + + + 431.000000 + TP0022 + + + 430.000000 + TP0023 + + + 430.000000 + TP0024 + + + 430.000000 + TP0025 + + + 431.000000 + TP0026 + + + 431.000000 + TP0027 + + + 431.000000 + TP0028 + + + 431.000000 + TP0029 + + + 431.000000 + TP0030 + + + 430.000000 + TP0031 + + + 430.000000 + TP0032 + + + 428.000000 + TP0033 + + + 427.000000 + TP0034 + + + 426.000000 + TP0035 + + + 426.000000 + TP0036 + + + 426.000000 + TP0037 + + + 427.000000 + TP0038 + + + 427.000000 + TP0039 + + + 428.000000 + TP0040 + + + 426.000000 + TP0041 + + + 425.000000 + TP0042 + + + 428.000000 + TP0043 + + + 429.000000 + TP0044 + + + 429.000000 + TP0045 + + + 431.000000 + TP0046 + + + 431.000000 + TP0047 + + + 432.000000 + TP0048 + + + 444.000000 + TP0049 + + + 445.000000 + TP0050 + + + 448.000000 + TP0051 + + + 432.000000 + TP0052 + + + 426.000000 + TP0053 + + + 420.000000 + TP0054 + + + 409.000000 + TP0055 + + + 408.000000 + TP0056 + + + 405.000000 + TP0057 + + + 393.000000 + TP0058 + + + 392.000000 + TP0059 + + + 392.000000 + TP0060 + + + 392.000000 + TP0061 + + + 391.000000 + TP0062 + + + 391.000000 + TP0063 + + + 387.000000 + TP0064 + + + 386.000000 + TP0065 + + + 383.000000 + TP0066 + + + 373.000000 + TP0067 + + + 372.000000 + TP0068 + + + 372.000000 + TP0069 + + + 369.000000 + TP0070 + + + 364.000000 + TP0071 + + + 361.000000 + TP0072 + + + 360.000000 + TP0073 + + + 359.000000 + TP0074 + + + 359.000000 + TP0075 + + + 359.000000 + TP0076 + + + 364.000000 + TP0077 + + + 363.000000 + TP0078 + + + 364.000000 + TP0079 + + + 363.000000 + TP0080 + + + 364.000000 + TP0081 + + + 369.000000 + TP0082 + + + 369.000000 + TP0083 + + + 369.000000 + TP0084 + + + 368.000000 + TP0085 + + + 368.000000 + TP0086 + + + 370.000000 + TP0087 + + + 373.000000 + TP0088 + + + 375.000000 + TP0089 + + + 380.000000 + TP0090 + + + 378.000000 + TP0091 + + + 379.000000 + TP0092 + + + 379.000000 + TP0093 + + + 376.000000 + TP0094 + + + 378.000000 + TP0095 + + + 379.000000 + TP0096 + + + 378.000000 + TP0097 + + + 377.000000 + TP0098 + + + 368.000000 + TP0099 + + + 341.000000 + TP0100 + + + 341.000000 + TP0101 + + + 341.000000 + TP0102 + + + 341.000000 + TP0103 + + + 341.000000 + TP0104 + + + 340.000000 + TP0105 + + + 337.000000 + TP0106 + + + 330.000000 + TP0107 + + + 324.000000 + TP0108 + + + 324.000000 + TP0109 + + + 322.000000 + TP0110 + + + 322.000000 + TP0111 + + + 321.000000 + TP0112 + + + 321.000000 + TP0113 + + + 321.000000 + TP0114 + + + 319.000000 + TP0115 + + + 317.000000 + TP0116 + + + 317.000000 + TP0117 + + + 311.000000 + TP0118 + + + 304.000000 + TP0119 + + + 304.000000 + TP0120 + + + 303.000000 + TP0121 + + + 303.000000 + TP0122 + + + 303.000000 + TP0123 + + + 303.000000 + TP0124 + + + 303.000000 + TP0125 + + + 303.000000 + TP0126 + + + 303.000000 + TP0127 + + + 303.000000 + TP0128 + + + 303.000000 + TP0129 + + + 303.000000 + TP0130 + + + 303.000000 + TP0131 + + + 303.000000 + TP0132 + + + 304.000000 + TP0133 + + + 305.000000 + TP0134 + + + 306.000000 + TP0135 + + + 306.000000 + TP0136 + + + 314.000000 + TP0137 + + + 315.000000 + TP0138 + + + 316.000000 + TP0139 + + + 323.000000 + TP0140 + + + 325.000000 + TP0141 + + + 327.000000 + TP0142 + + + 327.000000 + TP0143 + + + 326.000000 + TP0144 + + + 326.000000 + TP0145 + + + 328.000000 + TP0146 + + + 334.000000 + TP0147 + + + 336.000000 + TP0148 + + + 339.000000 + TP0149 + + + 347.000000 + TP0150 + + + 348.000000 + TP0151 + + + 356.000000 + TP0152 + + + 367.000000 + TP0153 + + + 378.000000 + TP0154 + + + 382.000000 + TP0155 + + + 379.000000 + TP0156 + + + 379.000000 + TP0157 + + + 379.000000 + TP0158 + + + 381.000000 + TP0159 + + + 418.000000 + TP0160 + + + 418.000000 + TP0161 + + + 419.000000 + TP0162 + + + 419.000000 + TP0163 + + + 419.000000 + TP0164 + + + 419.000000 + TP0165 + + + 419.000000 + TP0166 + + + 423.000000 + TP0167 + + + 422.000000 + TP0168 + + + 423.000000 + TP0169 + + + 424.000000 + TP0170 + + + 425.000000 + TP0171 + + + 427.000000 + TP0172 + + + 429.000000 + TP0173 + + + 430.000000 + TP0174 + + + 451.000000 + TP0175 + + + 452.000000 + TP0176 + + + 453.000000 + TP0177 + + + 453.000000 + TP0178 + + + 453.000000 + TP0179 + + + 458.000000 + TP0180 + + + 459.000000 + TP0181 + + + 462.000000 + TP0182 + + + 462.000000 + TP0183 + + + 462.000000 + TP0184 + + + 462.000000 + TP0185 + + + 451.000000 + TP0186 + + + 449.000000 + TP0187 + + + 448.000000 + TP0188 + + + 447.000000 + TP0189 + + + 447.000000 + TP0190 + + + 446.000000 + TP0191 + + + 434.000000 + TP0192 + + + 434.000000 + TP0193 + + + 434.000000 + TP0194 + + + 434.000000 + TP0195 + + + 434.000000 + TP0196 + + + 434.000000 + TP0197 + + + 434.000000 + TP0198 + + + 434.000000 + TP0199 + + + 434.000000 + TP0200 + + + 436.000000 + TP0201 + + + 437.000000 + TP0202 + + + 438.000000 + TP0203 + + + 438.000000 + TP0204 + + + 438.000000 + TP0205 + + + 437.000000 + TP0206 + + + 438.000000 + TP0207 + + + 438.000000 + TP0208 + + + 439.000000 + TP0209 + + + 442.000000 + TP0210 + + + 447.000000 + TP0211 + + + 499.000000 + TP0212 + + + 499.000000 + TP0213 + + + 500.000000 + TP0214 + + + 501.000000 + TP0215 + + + 503.000000 + TP0216 + + + 507.000000 + TP0217 + + + 521.000000 + TP0218 + + + 523.000000 + TP0219 + + + 544.000000 + TP0220 + + + 545.000000 + TP0221 + + + 547.000000 + TP0222 + + + 551.000000 + TP0223 + + + 551.000000 + TP0224 + + + 553.000000 + TP0225 + + + 555.000000 + TP0226 + + + 560.000000 + TP0227 + + + 563.000000 + TP0228 + + + 565.000000 + TP0229 + + + 603.000000 + TP0230 + + + 603.000000 + TP0231 + + + 590.000000 + TP0232 + + + 590.000000 + TP0233 + + + 586.000000 + TP0234 + + + 585.000000 + TP0235 + + + 583.000000 + TP0236 + + + 574.000000 + TP0237 + + + 563.000000 + TP0238 + + + 554.000000 + TP0239 + + + 547.000000 + TP0240 + + + 545.000000 + TP0241 + + + 531.000000 + TP0242 + + + 532.000000 + TP0243 + + + 530.000000 + TP0244 + + + 524.000000 + TP0245 + + + 522.000000 + TP0246 + + + 520.000000 + TP0247 + + + 513.000000 + TP0248 + + + 488.000000 + TP0249 + + + 486.000000 + TP0250 + + + 476.000000 + TP0251 + + + 468.000000 + TP0252 + + + 464.000000 + TP0253 + + + 454.000000 + TP0254 + + + 448.000000 + TP0255 + + + 447.000000 + TP0256 + + + 446.000000 + TP0257 + + + 440.000000 + TP0258 + + + 439.000000 + TP0259 + + + 439.000000 + TP0260 + + + 439.000000 + TP0261 + + + 439.000000 + TP0262 + + + 439.000000 + TP0263 + + + 439.000000 + TP0264 + + + 439.000000 + TP0265 + + + 440.000000 + TP0266 + + + 440.000000 + TP0267 + + + 439.000000 + TP0268 + + + 439.000000 + TP0269 + + + 439.000000 + TP0270 + + + 439.000000 + TP0271 + + + 439.000000 + TP0272 + + + 439.000000 + TP0273 + + + 439.000000 + TP0274 + + + 439.000000 + TP0275 + + + 439.000000 + TP0276 + + + + + + + 438.000000 + TP0277 + + + 438.000000 + TP0278 + + + 438.000000 + TP0279 + + + 438.000000 + TP0280 + + + 438.000000 + TP0281 + + + 438.000000 + TP0282 + + + 438.000000 + TP0283 + + + 438.000000 + TP0284 + + + 438.000000 + TP0285 + + + 438.000000 + TP0286 + + + 438.000000 + TP0287 + + + 438.000000 + TP0288 + + + 438.000000 + TP0289 + + + 438.000000 + TP0290 + + + 438.000000 + TP0291 + + + 438.000000 + TP0292 + + + 438.000000 + TP0293 + + + 438.000000 + TP0294 + + + 438.000000 + TP0295 + + + 438.000000 + TP0296 + + + 438.000000 + TP0297 + + + 438.000000 + TP0298 + + + 438.000000 + TP0299 + + + 438.000000 + TP0300 + + + 438.000000 + TP0301 + + + 438.000000 + TP0302 + + + 438.000000 + TP0303 + + + 438.000000 + TP0304 + + + 438.000000 + TP0305 + + + 438.000000 + TP0306 + + + 438.000000 + TP0307 + + + 416.000000 + TP0308 + + + 416.000000 + TP0309 + + + 416.000000 + TP0310 + + + 416.000000 + TP0311 + + + 416.000000 + TP0312 + + + 416.000000 + TP0313 + + + 416.000000 + TP0314 + + + 416.000000 + TP0315 + + + 416.000000 + TP0316 + + + 416.000000 + TP0317 + + + 416.000000 + TP0318 + + + 416.000000 + TP0319 + + + 416.000000 + TP0320 + + + 416.000000 + TP0321 + + + 417.000000 + TP0322 + + + 417.000000 + TP0323 + + + 417.000000 + TP0324 + + + 417.000000 + TP0325 + + + 417.000000 + TP0326 + + + 418.000000 + TP0327 + + + 418.000000 + TP0328 + + + 418.000000 + TP0329 + + + 418.000000 + TP0330 + + + 418.000000 + TP0331 + + + 418.000000 + TP0332 + + + 418.000000 + TP0333 + + + 418.000000 + TP0334 + + + 418.000000 + TP0335 + + + 418.000000 + TP0336 + + + 418.000000 + TP0337 + + + 418.000000 + TP0338 + + + 418.000000 + TP0339 + + + 419.000000 + TP0340 + + + 419.000000 + TP0341 + + + 419.000000 + TP0342 + + + 419.000000 + TP0343 + + + 419.000000 + TP0344 + + + 419.000000 + TP0345 + + + 419.000000 + TP0346 + + + 419.000000 + TP0347 + + + 419.000000 + TP0348 + + + 419.000000 + TP0349 + + + 419.000000 + TP0350 + + + 419.000000 + TP0351 + + + 419.000000 + TP0352 + + + 419.000000 + TP0353 + + + 419.000000 + TP0354 + + + 419.000000 + TP0355 + + + 419.000000 + TP0356 + + + 419.000000 + TP0357 + + + 420.000000 + TP0358 + + + 420.000000 + TP0359 + + + 420.000000 + TP0360 + + + 420.000000 + TP0361 + + + 420.000000 + TP0362 + + + 420.000000 + TP0363 + + + 420.000000 + TP0364 + + + 420.000000 + TP0365 + + + 420.000000 + TP0366 + + + 420.000000 + TP0367 + + + 421.000000 + TP0368 + + + 421.000000 + TP0369 + + + 421.000000 + TP0370 + + + 421.000000 + TP0371 + + + 421.000000 + TP0372 + + + 421.000000 + TP0373 + + + 421.000000 + TP0374 + + + 421.000000 + TP0375 + + + 421.000000 + TP0376 + + + 421.000000 + TP0377 + + + 421.000000 + TP0378 + + + 421.000000 + TP0379 + + + 421.000000 + TP0380 + + + 421.000000 + TP0381 + + + 421.000000 + TP0382 + + + 421.000000 + TP0383 + + + 421.000000 + TP0384 + + + 421.000000 + TP0385 + + + 421.000000 + TP0386 + + + 421.000000 + TP0387 + + + 421.000000 + TP0388 + + + 421.000000 + TP0389 + + + 421.000000 + TP0390 + + + 421.000000 + TP0391 + + + 421.000000 + TP0392 + + + 421.000000 + TP0393 + + + 421.000000 + TP0394 + + + 421.000000 + TP0395 + + + 421.000000 + TP0396 + + + 421.000000 + TP0397 + + + 421.000000 + TP0398 + + + 421.000000 + TP0399 + + + 421.000000 + TP0400 + + + 421.000000 + TP0401 + + + 421.000000 + TP0402 + + + 421.000000 + TP0403 + + + 421.000000 + TP0404 + + + 421.000000 + TP0405 + + + 421.000000 + TP0406 + + + 421.000000 + TP0407 + + + 421.000000 + TP0408 + + + 421.000000 + TP0409 + + + 421.000000 + TP0410 + + + 420.000000 + TP0411 + + + 416.000000 + TP0412 + + + 413.000000 + TP0413 + + + 410.000000 + TP0414 + + + 407.000000 + TP0415 + + + 406.000000 + TP0416 + + + 408.000000 + TP0417 + + + 415.000000 + TP0418 + + + 415.000000 + TP0419 + + + 415.000000 + TP0420 + + + 415.000000 + TP0421 + + + 415.000000 + TP0422 + + + 415.000000 + TP0423 + + + 415.000000 + TP0424 + + + 415.000000 + TP0425 + + + 415.000000 + TP0426 + + + 415.000000 + TP0427 + + + 415.000000 + TP0428 + + + 415.000000 + TP0429 + + + 415.000000 + TP0430 + + + 415.000000 + TP0431 + + + 415.000000 + TP0432 + + + 415.000000 + TP0433 + + + 415.000000 + TP0434 + + + 415.000000 + TP0435 + + + 415.000000 + TP0436 + + + 415.000000 + TP0437 + + + 416.000000 + TP0438 + + + 416.000000 + TP0439 + + + 416.000000 + TP0440 + + + 416.000000 + TP0441 + + + 416.000000 + TP0442 + + + 416.000000 + TP0443 + + + 416.000000 + TP0444 + + + 416.000000 + TP0445 + + + 416.000000 + TP0446 + + + 416.000000 + TP0447 + + + 416.000000 + TP0448 + + + 417.000000 + TP0449 + + + 417.000000 + TP0450 + + + 417.000000 + TP0451 + + + 419.000000 + TP0452 + + + 419.000000 + TP0453 + + + 419.000000 + TP0454 + + + 419.000000 + TP0455 + + + 419.000000 + TP0456 + + + 419.000000 + TP0457 + + + 419.000000 + TP0458 + + + 419.000000 + TP0459 + + + 419.000000 + TP0460 + + + 419.000000 + TP0461 + + + + + + + 423.000000 + TP0462 + + + 423.000000 + TP0463 + + + + + + + 431.000000 + TP0464 + + + 431.000000 + TP0465 + + + 432.000000 + TP0466 + + + 432.000000 + TP0467 + + + + + + + 451.000000 + TP0468 + + + 451.000000 + TP0469 + + + 451.000000 + TP0470 + + + 450.000000 + TP0471 + + + 450.000000 + TP0472 + + + 450.000000 + TP0473 + + + 450.000000 + TP0474 + + + 450.000000 + TP0475 + + + 450.000000 + TP0476 + + + 450.000000 + TP0477 + + + 450.000000 + TP0478 + + + 450.000000 + TP0479 + + + 450.000000 + TP0480 + + + 450.000000 + TP0481 + + + 450.000000 + TP0482 + + + 450.000000 + TP0483 + + + 450.000000 + TP0484 + + + 450.000000 + TP0485 + + + 450.000000 + TP0486 + + + 450.000000 + TP0487 + + + 450.000000 + TP0488 + + + 450.000000 + TP0489 + + + 450.000000 + TP0490 + + + 450.000000 + TP0491 + + + 450.000000 + TP0492 + + + 450.000000 + TP0493 + + + 450.000000 + TP0494 + + + 450.000000 + TP0495 + + + 450.000000 + TP0496 + + + 450.000000 + TP0497 + + + 450.000000 + TP0498 + + + 450.000000 + TP0499 + + + 450.000000 + TP0500 + + + 450.000000 + TP0501 + + + 450.000000 + TP0502 + + + 450.000000 + TP0503 + + + 450.000000 + TP0504 + + + 450.000000 + TP0505 + + + 450.000000 + TP0506 + + + 450.000000 + TP0507 + + + 450.000000 + TP0508 + + + 450.000000 + TP0509 + + + 450.000000 + TP0510 + + + 450.000000 + TP0511 + + + 450.000000 + TP0512 + + + 450.000000 + TP0513 + + + 450.000000 + TP0514 + + + 450.000000 + TP0515 + + + 450.000000 + TP0516 + + + 450.000000 + TP0517 + + + 450.000000 + TP0518 + + + 450.000000 + TP0519 + + + 450.000000 + TP0520 + + + 450.000000 + TP0521 + + + 450.000000 + TP0522 + + + 450.000000 + TP0523 + + + 449.000000 + TP0524 + + + 448.000000 + TP0525 + + + 447.000000 + TP0526 + + + 446.000000 + TP0527 + + + 445.000000 + TP0528 + + + 443.000000 + TP0529 + + + 441.000000 + TP0530 + + + 438.000000 + TP0531 + + + 435.000000 + TP0532 + + + 429.000000 + TP0533 + + + 423.000000 + TP0534 + + + 413.000000 + TP0535 + + + 414.000000 + TP0536 + + + 415.000000 + TP0537 + + + 415.000000 + TP0538 + + + 415.000000 + TP0539 + + + 415.000000 + TP0540 + + + 415.000000 + TP0541 + + + 415.000000 + TP0542 + + + 415.000000 + TP0543 + + + 415.000000 + TP0544 + + + 415.000000 + TP0545 + + + 415.000000 + TP0546 + + + 415.000000 + TP0547 + + + 415.000000 + TP0548 + + + 415.000000 + TP0549 + + + 415.000000 + TP0550 + + + 415.000000 + TP0551 + + + 415.000000 + TP0552 + + + 415.000000 + TP0553 + + + 415.000000 + TP0554 + + + 415.000000 + TP0555 + + + 415.000000 + TP0556 + + + 415.000000 + TP0557 + + + 415.000000 + TP0558 + + + 415.000000 + TP0559 + + + 415.000000 + TP0560 + + + 415.000000 + TP0561 + + + 415.000000 + TP0562 + + + 415.000000 + TP0563 + + + 415.000000 + TP0564 + + + 415.000000 + TP0565 + + + 415.000000 + TP0566 + + + 415.000000 + TP0567 + + + 415.000000 + TP0568 + + + 415.000000 + TP0569 + + + 415.000000 + TP0570 + + + 415.000000 + TP0571 + + + 415.000000 + TP0572 + + + 415.000000 + TP0573 + + + 415.000000 + TP0574 + + + 415.000000 + TP0575 + + + 415.000000 + TP0576 + + + 415.000000 + TP0577 + + + 415.000000 + TP0578 + + + 415.000000 + TP0579 + + + 415.000000 + TP0580 + + + 415.000000 + TP0581 + + + 415.000000 + TP0582 + + + 415.000000 + TP0583 + + + 415.000000 + TP0584 + + + 415.000000 + TP0585 + + + 415.000000 + TP0586 + + + 415.000000 + TP0587 + + + 415.000000 + TP0588 + + + 415.000000 + TP0589 + + + 415.000000 + TP0590 + + + 415.000000 + TP0591 + + + 415.000000 + TP0592 + + + 415.000000 + TP0593 + + + 415.000000 + TP0594 + + + 415.000000 + TP0595 + + + 415.000000 + TP0596 + + + 415.000000 + TP0597 + + + 415.000000 + TP0598 + + + 415.000000 + TP0599 + + + 415.000000 + TP0600 + + + 415.000000 + TP0601 + + + 415.000000 + TP0602 + + + 415.000000 + TP0603 + + + 415.000000 + TP0604 + + + 415.000000 + TP0605 + + + 415.000000 + TP0606 + + + 415.000000 + TP0607 + + + 415.000000 + TP0608 + + + 415.000000 + TP0609 + + + 415.000000 + TP0610 + + + 415.000000 + TP0611 + + + 415.000000 + TP0612 + + + 415.000000 + TP0613 + + + 415.000000 + TP0614 + + + 415.000000 + TP0615 + + + 415.000000 + TP0616 + + + 415.000000 + TP0617 + + + 415.000000 + TP0618 + + + 415.000000 + TP0619 + + + 415.000000 + TP0620 + + + 415.000000 + TP0621 + + + 415.000000 + TP0622 + + + 415.000000 + TP0623 + + + 415.000000 + TP0624 + + + 415.000000 + TP0625 + + + 415.000000 + TP0626 + + + 415.000000 + TP0627 + + + 415.000000 + TP0628 + + + 415.000000 + TP0629 + + + 415.000000 + TP0630 + + + 415.000000 + TP0631 + + + 415.000000 + TP0632 + + + 415.000000 + TP0633 + + + 415.000000 + TP0634 + + + 415.000000 + TP0635 + + + 415.000000 + TP0636 + + + 416.000000 + TP0637 + + + 416.000000 + TP0638 + + + 416.000000 + TP0639 + + + 416.000000 + TP0640 + + + 416.000000 + TP0641 + + + 416.000000 + TP0642 + + + 416.000000 + TP0643 + + + 416.000000 + TP0644 + + + 416.000000 + TP0645 + + + 416.000000 + TP0646 + + + 416.000000 + TP0647 + + + 418.000000 + TP0648 + + + 418.000000 + TP0649 + + + 419.000000 + TP0650 + + + 419.000000 + TP0651 + + + 420.000000 + TP0652 + + + 420.000000 + TP0653 + + + 420.000000 + TP0654 + + + 420.000000 + TP0655 + + + 420.000000 + TP0656 + + + 420.000000 + TP0657 + + + 420.000000 + TP0658 + + + 420.000000 + TP0659 + + + 420.000000 + TP0660 + + + 421.000000 + TP0661 + + + 421.000000 + TP0662 + + + 421.000000 + TP0663 + + + 421.000000 + TP0664 + + + 421.000000 + TP0665 + + + 421.000000 + TP0666 + + + 421.000000 + TP0667 + + + 421.000000 + TP0668 + + + 421.000000 + TP0669 + + + 420.000000 + TP0670 + + + 420.000000 + TP0671 + + + 420.000000 + TP0672 + + + 420.000000 + TP0673 + + + 420.000000 + TP0674 + + + 421.000000 + TP0675 + + + 421.000000 + TP0676 + + + 421.000000 + TP0677 + + + 421.000000 + TP0678 + + + 421.000000 + TP0679 + + + 421.000000 + TP0680 + + + 421.000000 + TP0681 + + + 421.000000 + TP0682 + + + 421.000000 + TP0683 + + + 421.000000 + TP0684 + + + 421.000000 + TP0685 + + + 421.000000 + TP0686 + + + 421.000000 + TP0687 + + + 421.000000 + TP0688 + + + 421.000000 + TP0689 + + + 421.000000 + TP0690 + + + 421.000000 + TP0691 + + + 421.000000 + TP0692 + + + 421.000000 + TP0693 + + + 421.000000 + TP0694 + + + 421.000000 + TP0695 + + + 421.000000 + TP0696 + + + 421.000000 + TP0697 + + + 421.000000 + TP0698 + + + 421.000000 + TP0699 + + + 421.000000 + TP0700 + + + 421.000000 + TP0701 + + + 421.000000 + TP0702 + + + 421.000000 + TP0703 + + + 421.000000 + TP0704 + + + 421.000000 + TP0705 + + + 421.000000 + TP0706 + + + 421.000000 + TP0707 + + + 421.000000 + TP0708 + + + 421.000000 + TP0709 + + + 421.000000 + TP0710 + + + 421.000000 + TP0711 + + + 421.000000 + TP0712 + + + 421.000000 + TP0713 + + + 421.000000 + TP0714 + + + 421.000000 + TP0715 + + + 421.000000 + TP0716 + + + 421.000000 + TP0717 + + + 421.000000 + TP0718 + + + 421.000000 + TP0719 + + + 421.000000 + TP0720 + + + 421.000000 + TP0721 + + + 421.000000 + TP0722 + + + 421.000000 + TP0723 + + + 421.000000 + TP0724 + + + 421.000000 + TP0725 + + + 421.000000 + TP0726 + + + 421.000000 + TP0727 + + + 421.000000 + TP0728 + + + 422.000000 + TP0729 + + + 422.000000 + TP0730 + + + 422.000000 + TP0731 + + + 422.000000 + TP0732 + + + 422.000000 + TP0733 + + + 422.000000 + TP0734 + + + 422.000000 + TP0735 + + + 422.000000 + TP0736 + + + 422.000000 + TP0737 + + + 422.000000 + TP0738 + + + 422.000000 + TP0739 + + + 422.000000 + TP0740 + + + 422.000000 + TP0741 + + + 422.000000 + TP0742 + + + 422.000000 + TP0743 + + + 422.000000 + TP0744 + + + 422.000000 + TP0745 + + + 422.000000 + TP0746 + + + 422.000000 + TP0747 + + + 422.000000 + TP0748 + + + 422.000000 + TP0749 + + + 422.000000 + TP0750 + + + 422.000000 + TP0751 + + + 423.000000 + TP0752 + + + 423.000000 + TP0753 + + + 423.000000 + TP0754 + + + 423.000000 + TP0755 + + + 423.000000 + TP0756 + + + 423.000000 + TP0757 + + + 423.000000 + TP0758 + + + 423.000000 + TP0759 + + + 424.000000 + TP0760 + + + 424.000000 + TP0761 + + + 424.000000 + TP0762 + + + 424.000000 + TP0763 + + + 424.000000 + TP0764 + + + 424.000000 + TP0765 + + + 424.000000 + TP0766 + + + 424.000000 + TP0767 + + + 424.000000 + TP0768 + + + 424.000000 + TP0769 + + + 424.000000 + TP0770 + + + 425.000000 + TP0771 + + + 425.000000 + TP0772 + + + 425.000000 + TP0773 + + + 425.000000 + TP0774 + + + 425.000000 + TP0775 + + + 425.000000 + TP0776 + + + 425.000000 + TP0777 + + + 425.000000 + TP0778 + + + 425.000000 + TP0779 + + + 425.000000 + TP0780 + + + 425.000000 + TP0781 + + + 425.000000 + TP0782 + + + 425.000000 + TP0783 + + + 425.000000 + TP0784 + + + 425.000000 + TP0785 + + + 425.000000 + TP0786 + + + 425.000000 + TP0787 + + + 425.000000 + TP0788 + + + 425.000000 + TP0789 + + + 425.000000 + TP0790 + + + 425.000000 + TP0791 + + + 425.000000 + TP0792 + + + 425.000000 + TP0793 + + + 425.000000 + TP0794 + + + 425.000000 + TP0795 + + + 425.000000 + TP0796 + + + 425.000000 + TP0797 + + + 425.000000 + TP0798 + + + 425.000000 + TP0799 + + + 422.000000 + TP0800 + + + 421.000000 + TP0801 + + + 420.000000 + TP0802 + + + 422.000000 + TP0803 + + + 422.000000 + TP0804 + + + 422.000000 + TP0805 + + + 422.000000 + TP0806 + + + 422.000000 + TP0807 + + + 416.000000 + TP0808 + + + 413.000000 + TP0809 + + + 413.000000 + TP0810 + + + 413.000000 + TP0811 + + + 413.000000 + TP0812 + + + 413.000000 + TP0813 + + + 413.000000 + TP0814 + + + 413.000000 + TP0815 + + + 413.000000 + TP0816 + + + 413.000000 + TP0817 + + + 413.000000 + TP0818 + + + 413.000000 + TP0819 + + + 413.000000 + TP0820 + + + 413.000000 + TP0821 + + + 413.000000 + TP0822 + + + 414.000000 + TP0823 + + + 414.000000 + TP0824 + + + 414.000000 + TP0825 + + + 414.000000 + TP0826 + + + 414.000000 + TP0827 + + + 414.000000 + TP0828 + + + 414.000000 + TP0829 + + + 414.000000 + TP0830 + + + 414.000000 + TP0831 + + + 414.000000 + TP0832 + + + 414.000000 + TP0833 + + + 414.000000 + TP0834 + + + 414.000000 + TP0835 + + + 414.000000 + TP0836 + + + 415.000000 + TP0837 + + + 416.000000 + TP0838 + + + 416.000000 + TP0839 + + + 416.000000 + TP0840 + + + 416.000000 + TP0841 + + + 416.000000 + TP0842 + + + 416.000000 + TP0843 + + + 416.000000 + TP0844 + + + 416.000000 + TP0845 + + + 416.000000 + TP0846 + + + 416.000000 + TP0847 + + + 416.000000 + TP0848 + + + 416.000000 + TP0849 + + + 416.000000 + TP0850 + + + 416.000000 + TP0851 + + + 416.000000 + TP0852 + + + 416.000000 + TP0853 + + + 416.000000 + TP0854 + + + 416.000000 + TP0855 + + + 416.000000 + TP0856 + + + 416.000000 + TP0857 + + + 416.000000 + TP0858 + + + 417.000000 + TP0859 + + + 417.000000 + TP0860 + + + 418.000000 + TP0861 + + + 418.000000 + TP0862 + + + 419.000000 + TP0863 + + + 419.000000 + TP0864 + + + 420.000000 + TP0865 + + + 420.000000 + TP0866 + + + 419.000000 + TP0867 + + + 419.000000 + TP0868 + + + 419.000000 + TP0869 + + + 421.000000 + TP0870 + + + 421.000000 + TP0871 + + + 421.000000 + TP0872 + + + 421.000000 + TP0873 + + + 422.000000 + TP0874 + + + 422.000000 + TP0875 + + + 422.000000 + TP0876 + + + 422.000000 + TP0877 + + + 422.000000 + TP0878 + + + 423.000000 + TP0879 + + + 423.000000 + TP0880 + + + 423.000000 + TP0881 + + + 423.000000 + TP0882 + + + 423.000000 + TP0883 + + + 423.000000 + TP0884 + + + 423.000000 + TP0885 + + + 423.000000 + TP0886 + + + 423.000000 + TP0887 + + + 423.000000 + TP0888 + + + 423.000000 + TP0889 + + + 423.000000 + TP0890 + + + 423.000000 + TP0891 + + + 423.000000 + TP0892 + + + 423.000000 + TP0893 + + + 423.000000 + TP0894 + + + 424.000000 + TP0895 + + + 424.000000 + TP0896 + + + 425.000000 + TP0897 + + + 425.000000 + TP0898 + + + 425.000000 + TP0899 + + + 425.000000 + TP0900 + + + 425.000000 + TP0901 + + + 425.000000 + TP0902 + + + 425.000000 + TP0903 + + + 425.000000 + TP0904 + + + 425.000000 + TP0905 + + + 425.000000 + TP0906 + + + 425.000000 + TP0907 + + + 425.000000 + TP0908 + + + 425.000000 + TP0909 + + + 425.000000 + TP0910 + + + 425.000000 + TP0911 + + + 425.000000 + TP0912 + + + 425.000000 + TP0913 + + + 425.000000 + TP0914 + + + 425.000000 + TP0915 + + + 425.000000 + TP0916 + + + 425.000000 + TP0917 + + + 425.000000 + TP0918 + + + 425.000000 + TP0919 + + + 425.000000 + TP0920 + + + 425.000000 + TP0921 + + + 425.000000 + TP0922 + + + 425.000000 + TP0923 + + + 425.000000 + TP0924 + + + 425.000000 + TP0925 + + + 425.000000 + TP0926 + + + 425.000000 + TP0927 + + + 425.000000 + TP0928 + + + 425.000000 + TP0929 + + + 425.000000 + TP0930 + + + 425.000000 + TP0931 + + + 425.000000 + TP0932 + + + 425.000000 + TP0933 + + + 425.000000 + TP0934 + + + 425.000000 + TP0935 + + + 425.000000 + TP0936 + + + 425.000000 + TP0937 + + + 425.000000 + TP0938 + + + 425.000000 + TP0939 + + + 425.000000 + TP0940 + + + 425.000000 + TP0941 + + + 425.000000 + TP0942 + + + 425.000000 + TP0943 + + + 425.000000 + TP0944 + + + 425.000000 + TP0945 + + + 425.000000 + TP0946 + + + 426.000000 + TP0947 + + + 426.000000 + TP0948 + + + 426.000000 + TP0949 + + + 426.000000 + TP0950 + + + 426.000000 + TP0951 + + + 426.000000 + TP0952 + + + 426.000000 + TP0953 + + + 426.000000 + TP0954 + + + 426.000000 + TP0955 + + + 426.000000 + TP0956 + + + 426.000000 + TP0957 + + + 426.000000 + TP0958 + + + 426.000000 + TP0959 + + + 426.000000 + TP0960 + + + 426.000000 + TP0961 + + + 426.000000 + TP0962 + + + 426.000000 + TP0963 + + + 426.000000 + TP0964 + + + 426.000000 + TP0965 + + + 426.000000 + TP0966 + + + 426.000000 + TP0967 + + + 426.000000 + TP0968 + + + 426.000000 + TP0969 + + + 426.000000 + TP0970 + + + 426.000000 + TP0971 + + + 426.000000 + TP0972 + + + 426.000000 + TP0973 + + + 426.000000 + TP0974 + + + 426.000000 + TP0975 + + + 426.000000 + TP0976 + + + 426.000000 + TP0977 + + + 426.000000 + TP0978 + + + 426.000000 + TP0979 + + + 426.000000 + TP0980 + + + 426.000000 + TP0981 + + + 426.000000 + TP0982 + + + 426.000000 + TP0983 + + + 426.000000 + TP0984 + + + 426.000000 + TP0985 + + + 426.000000 + TP0986 + + + 426.000000 + TP0987 + + + 426.000000 + TP0988 + + + 426.000000 + TP0989 + + + 426.000000 + TP0990 + + + 426.000000 + TP0991 + + + 426.000000 + TP0992 + + + 426.000000 + TP0993 + + + 426.000000 + TP0994 + + + 426.000000 + TP0995 + + + 426.000000 + TP0996 + + + 426.000000 + TP0997 + + + 426.000000 + TP0998 + + + 426.000000 + TP0999 + + + 426.000000 + TP1000 + + + 426.000000 + TP1001 + + + 426.000000 + TP1002 + + + 426.000000 + TP1003 + + + 426.000000 + TP1004 + + + 426.000000 + TP1005 + + + 426.000000 + TP1006 + + + 426.000000 + TP1007 + + + 426.000000 + TP1008 + + + 426.000000 + TP1009 + + + 426.000000 + TP1010 + + + 426.000000 + TP1011 + + + 426.000000 + TP1012 + + + 426.000000 + TP1013 + + + 426.000000 + TP1014 + + + 426.000000 + TP1015 + + + 426.000000 + TP1016 + + + 426.000000 + TP1017 + + + 426.000000 + TP1018 + + + 426.000000 + TP1019 + + + 426.000000 + TP1020 + + + 426.000000 + TP1021 + + + 425.000000 + TP1022 + + + 425.000000 + TP1023 + + + 426.000000 + TP1024 + + + 426.000000 + TP1025 + + + 426.000000 + TP1026 + + + 426.000000 + TP1027 + + + 426.000000 + TP1028 + + + 426.000000 + TP1029 + + + 426.000000 + TP1030 + + + 426.000000 + TP1031 + + + 426.000000 + TP1032 + + + 426.000000 + TP1033 + + + 426.000000 + TP1034 + + + 426.000000 + TP1035 + + + 426.000000 + TP1036 + + + 426.000000 + TP1037 + + + 426.000000 + TP1038 + + + 426.000000 + TP1039 + + + 426.000000 + TP1040 + + + 426.000000 + TP1041 + + + 426.000000 + TP1042 + + + 426.000000 + TP1043 + + + 426.000000 + TP1044 + + + 426.000000 + TP1045 + + + 426.000000 + TP1046 + + + 427.000000 + TP1047 + + + 427.000000 + TP1048 + + + 427.000000 + TP1049 + + + 427.000000 + TP1050 + + + 427.000000 + TP1051 + + + 427.000000 + TP1052 + + + 427.000000 + TP1053 + + + 427.000000 + TP1054 + + + 427.000000 + TP1055 + + + 427.000000 + TP1056 + + + 427.000000 + TP1057 + + + 427.000000 + TP1058 + + + 427.000000 + TP1059 + + + 427.000000 + TP1060 + + + 427.000000 + TP1061 + + + 427.000000 + TP1062 + + + 427.000000 + TP1063 + + + 427.000000 + TP1064 + + + 427.000000 + TP1065 + + + 427.000000 + TP1066 + + + 427.000000 + TP1067 + + + 427.000000 + TP1068 + + + 427.000000 + TP1069 + + + 427.000000 + TP1070 + + + 427.000000 + TP1071 + + + 427.000000 + TP1072 + + + 427.000000 + TP1073 + + + 427.000000 + TP1074 + + + 427.000000 + TP1075 + + + 427.000000 + TP1076 + + + 427.000000 + TP1077 + + + 427.000000 + TP1078 + + + 427.000000 + TP1079 + + + 427.000000 + TP1080 + + + 427.000000 + TP1081 + + + 427.000000 + TP1082 + + + 427.000000 + TP1083 + + + 427.000000 + TP1084 + + + 427.000000 + TP1085 + + + 427.000000 + TP1086 + + + 427.000000 + TP1087 + + + 427.000000 + TP1088 + + + 427.000000 + TP1089 + + + 427.000000 + TP1090 + + + 427.000000 + TP1091 + + + 427.000000 + TP1092 + + + 427.000000 + TP1093 + + + 427.000000 + TP1094 + + + 427.000000 + TP1095 + + + 427.000000 + TP1096 + + + 427.000000 + TP1097 + + + 427.000000 + TP1098 + + + 427.000000 + TP1099 + + + 427.000000 + TP1100 + + + 427.000000 + TP1101 + + + 428.000000 + TP1102 + + + 428.000000 + TP1103 + + + 428.000000 + TP1104 + + + 428.000000 + TP1105 + + + 428.000000 + TP1106 + + + 428.000000 + TP1107 + + + 428.000000 + TP1108 + + + 428.000000 + TP1109 + + + 428.000000 + TP1110 + + + 428.000000 + TP1111 + + + 428.000000 + TP1112 + + + 428.000000 + TP1113 + + + 428.000000 + TP1114 + + + 428.000000 + TP1115 + + + 428.000000 + TP1116 + + + 428.000000 + TP1117 + + + 428.000000 + TP1118 + + + 428.000000 + TP1119 + + + 428.000000 + TP1120 + + + 428.000000 + TP1121 + + + 428.000000 + TP1122 + + + 428.000000 + TP1123 + + + 428.000000 + TP1124 + + + 428.000000 + TP1125 + + + 428.000000 + TP1126 + + + 428.000000 + TP1127 + + + 428.000000 + TP1128 + + + 428.000000 + TP1129 + + + 428.000000 + TP1130 + + + 428.000000 + TP1131 + + + 428.000000 + TP1132 + + + 428.000000 + TP1133 + + + 428.000000 + TP1134 + + + 428.000000 + TP1135 + + + 428.000000 + TP1136 + + + 428.000000 + TP1137 + + + 428.000000 + TP1138 + + + 428.000000 + TP1139 + + + 428.000000 + TP1140 + + + 428.000000 + TP1141 + + + 428.000000 + TP1142 + + + 428.000000 + TP1143 + + + 428.000000 + TP1144 + + + 428.000000 + TP1145 + + + 428.000000 + TP1146 + + + 428.000000 + TP1147 + + + 428.000000 + TP1148 + + + 428.000000 + TP1149 + + + 428.000000 + TP1150 + + + 428.000000 + TP1151 + + + 428.000000 + TP1152 + + + 428.000000 + TP1153 + + + 428.000000 + TP1154 + + + 428.000000 + TP1155 + + + 428.000000 + TP1156 + + + 428.000000 + TP1157 + + + 428.000000 + TP1158 + + + 428.000000 + TP1159 + + + 428.000000 + TP1160 + + + 428.000000 + TP1161 + + + 428.000000 + TP1162 + + + 428.000000 + TP1163 + + + 428.000000 + TP1164 + + + 428.000000 + TP1165 + + + 428.000000 + TP1166 + + + 428.000000 + TP1167 + + + 428.000000 + TP1168 + + + 428.000000 + TP1169 + + + 428.000000 + TP1170 + + + 428.000000 + TP1171 + + + 428.000000 + TP1172 + + + 428.000000 + TP1173 + + + 428.000000 + TP1174 + + + 428.000000 + TP1175 + + + 428.000000 + TP1176 + + + 428.000000 + TP1177 + + + 428.000000 + TP1178 + + + 428.000000 + TP1179 + + + 428.000000 + TP1180 + + + 428.000000 + TP1181 + + + 428.000000 + TP1182 + + + 428.000000 + TP1183 + + + 428.000000 + TP1184 + + + 428.000000 + TP1185 + + + 428.000000 + TP1186 + + + 428.000000 + TP1187 + + + 428.000000 + TP1188 + + + 428.000000 + TP1189 + + + 428.000000 + TP1190 + + + 428.000000 + TP1191 + + + 428.000000 + TP1192 + + + 428.000000 + TP1193 + + + 428.000000 + TP1194 + + + 428.000000 + TP1195 + + + 428.000000 + TP1196 + + + 428.000000 + TP1197 + + + 428.000000 + TP1198 + + + 428.000000 + TP1199 + + + 428.000000 + TP1200 + + + 428.000000 + TP1201 + + + 428.000000 + TP1202 + + + 428.000000 + TP1203 + + + 428.000000 + TP1204 + + + 428.000000 + TP1205 + + + 428.000000 + TP1206 + + + 428.000000 + TP1207 + + + 428.000000 + TP1208 + + + 428.000000 + TP1209 + + + 428.000000 + TP1210 + + + 428.000000 + TP1211 + + + 429.000000 + TP1212 + + + 429.000000 + TP1213 + + + 429.000000 + TP1214 + + + 429.000000 + TP1215 + + + 429.000000 + TP1216 + + + 429.000000 + TP1217 + + + 429.000000 + TP1218 + + + 429.000000 + TP1219 + + + 429.000000 + TP1220 + + + 429.000000 + TP1221 + + + 429.000000 + TP1222 + + + 429.000000 + TP1223 + + + 430.000000 + TP1224 + + + 430.000000 + TP1225 + + + 430.000000 + TP1226 + + + 430.000000 + TP1227 + + + 430.000000 + TP1228 + + + 430.000000 + TP1229 + + + 430.000000 + TP1230 + + + 430.000000 + TP1231 + + + 430.000000 + TP1232 + + + 430.000000 + TP1233 + + + 430.000000 + TP1234 + + + 430.000000 + TP1235 + + + 430.000000 + TP1236 + + + 430.000000 + TP1237 + + + 430.000000 + TP1238 + + + 430.000000 + TP1239 + + + 430.000000 + TP1240 + + + 430.000000 + TP1241 + + + 430.000000 + TP1242 + + + 430.000000 + TP1243 + + + 430.000000 + TP1244 + + + 430.000000 + TP1245 + + + 430.000000 + TP1246 + + + 430.000000 + TP1247 + + + 430.000000 + TP1248 + + + 430.000000 + TP1249 + + + 430.000000 + TP1250 + + + 430.000000 + TP1251 + + + 430.000000 + TP1252 + + + 430.000000 + TP1253 + + + 430.000000 + TP1254 + + + 430.000000 + TP1255 + + + 430.000000 + TP1256 + + + 430.000000 + TP1257 + + + 430.000000 + TP1258 + + + 430.000000 + TP1259 + + + 430.000000 + TP1260 + + + 430.000000 + TP1261 + + + 430.000000 + TP1262 + + + 430.000000 + TP1263 + + + 430.000000 + TP1264 + + + 430.000000 + TP1265 + + + 430.000000 + TP1266 + + + 430.000000 + TP1267 + + + 430.000000 + TP1268 + + + 430.000000 + TP1269 + + + 430.000000 + TP1270 + + + 430.000000 + TP1271 + + + 430.000000 + TP1272 + + + 431.000000 + TP1273 + + + 431.000000 + TP1274 + + + 431.000000 + TP1275 + + + 431.000000 + TP1276 + + + 431.000000 + TP1277 + + + 431.000000 + TP1278 + + + 431.000000 + TP1279 + + + 431.000000 + TP1280 + + + 431.000000 + TP1281 + + + 431.000000 + TP1282 + + + 431.000000 + TP1283 + + + 431.000000 + TP1284 + + + 431.000000 + TP1285 + + + 431.000000 + TP1286 + + + 431.000000 + TP1287 + + + 431.000000 + TP1288 + + + 431.000000 + TP1289 + + + 431.000000 + TP1290 + + + 431.000000 + TP1291 + + + 431.000000 + TP1292 + + + 431.000000 + TP1293 + + + 431.000000 + TP1294 + + + 431.000000 + TP1295 + + + 431.000000 + TP1296 + + + 431.000000 + TP1297 + + + 431.000000 + TP1298 + + + 431.000000 + TP1299 + + + 431.000000 + TP1300 + + + 431.000000 + TP1301 + + + 431.000000 + TP1302 + + + 431.000000 + TP1303 + + + 431.000000 + TP1304 + + + 431.000000 + TP1305 + + + 431.000000 + TP1306 + + + 431.000000 + TP1307 + + + 431.000000 + TP1308 + + + 431.000000 + TP1309 + + + 431.000000 + TP1310 + + + 431.000000 + TP1311 + + + 431.000000 + TP1312 + + + 431.000000 + TP1313 + + + 431.000000 + TP1314 + + + 431.000000 + TP1315 + + + 431.000000 + TP1316 + + + 431.000000 + TP1317 + + + 431.000000 + TP1318 + + + 431.000000 + TP1319 + + + 431.000000 + TP1320 + + + 431.000000 + TP1321 + + + 431.000000 + TP1322 + + + 431.000000 + TP1323 + + + 431.000000 + TP1324 + + + 431.000000 + TP1325 + + + 431.000000 + TP1326 + + + 431.000000 + TP1327 + + + 431.000000 + TP1328 + + + 431.000000 + TP1329 + + + 431.000000 + TP1330 + + + 431.000000 + TP1331 + + + 431.000000 + TP1332 + + + 431.000000 + TP1333 + + + 431.000000 + TP1334 + + + 431.000000 + TP1335 + + + 431.000000 + TP1336 + + + 431.000000 + TP1337 + + + 431.000000 + TP1338 + + + 431.000000 + TP1339 + + + 432.000000 + TP1340 + + + 432.000000 + TP1341 + + + 432.000000 + TP1342 + + + 432.000000 + TP1343 + + + 432.000000 + TP1344 + + + 432.000000 + TP1345 + + + 432.000000 + TP1346 + + + 432.000000 + TP1347 + + + 432.000000 + TP1348 + + + 432.000000 + TP1349 + + + 432.000000 + TP1350 + + + 432.000000 + TP1351 + + + 432.000000 + TP1352 + + + 432.000000 + TP1353 + + + 432.000000 + TP1354 + + + 432.000000 + TP1355 + + + 432.000000 + TP1356 + + + 432.000000 + TP1357 + + + 432.000000 + TP1358 + + + 432.000000 + TP1359 + + + 432.000000 + TP1360 + + + 432.000000 + TP1361 + + + 432.000000 + TP1362 + + + 432.000000 + TP1363 + + + 432.000000 + TP1364 + + + 432.000000 + TP1365 + + + 432.000000 + TP1366 + + + 432.000000 + TP1367 + + + 432.000000 + TP1368 + + + 432.000000 + TP1369 + + + 432.000000 + TP1370 + + + 432.000000 + TP1371 + + + 432.000000 + TP1372 + + + 432.000000 + TP1373 + + + 432.000000 + TP1374 + + + 432.000000 + TP1375 + + + 432.000000 + TP1376 + + + 432.000000 + TP1377 + + + 432.000000 + TP1378 + + + 432.000000 + TP1379 + + + 432.000000 + TP1380 + + + 432.000000 + TP1381 + + + 432.000000 + TP1382 + + + 432.000000 + TP1383 + + + 432.000000 + TP1384 + + + 432.000000 + TP1385 + + + 432.000000 + TP1386 + + + 432.000000 + TP1387 + + + 432.000000 + TP1388 + + + 432.000000 + TP1389 + + + 432.000000 + TP1390 + + + 432.000000 + TP1391 + + + 432.000000 + TP1392 + + + 432.000000 + TP1393 + + + 432.000000 + TP1394 + + + 432.000000 + TP1395 + + + 432.000000 + TP1396 + + + 432.000000 + TP1397 + + + 432.000000 + TP1398 + + + 432.000000 + TP1399 + + + 432.000000 + TP1400 + + + 432.000000 + TP1401 + + + 432.000000 + TP1402 + + + 432.000000 + TP1403 + + + 432.000000 + TP1404 + + + 432.000000 + TP1405 + + + 432.000000 + TP1406 + + + 432.000000 + TP1407 + + + 432.000000 + TP1408 + + + 432.000000 + TP1409 + + + 432.000000 + TP1410 + + + 432.000000 + TP1411 + + + 432.000000 + TP1412 + + + 432.000000 + TP1413 + + + 432.000000 + TP1414 + + + 432.000000 + TP1415 + + + 432.000000 + TP1416 + + + 432.000000 + TP1417 + + + 432.000000 + TP1418 + + + 432.000000 + TP1419 + + + 432.000000 + TP1420 + + + 432.000000 + TP1421 + + + 432.000000 + TP1422 + + + 432.000000 + TP1423 + + + 432.000000 + TP1424 + + + 432.000000 + TP1425 + + + 432.000000 + TP1426 + + + 432.000000 + TP1427 + + + 432.000000 + TP1428 + + + 432.000000 + TP1429 + + + 432.000000 + TP1430 + + + 432.000000 + TP1431 + + + 433.000000 + TP1432 + + + 434.000000 + TP1433 + + + 434.000000 + TP1434 + + + 434.000000 + TP1435 + + + 434.000000 + TP1436 + + + 434.000000 + TP1437 + + + 434.000000 + TP1438 + + + 434.000000 + TP1439 + + + 434.000000 + TP1440 + + + 435.000000 + TP1441 + + + 435.000000 + TP1442 + + + 435.000000 + TP1443 + + + 435.000000 + TP1444 + + + 435.000000 + TP1445 + + + 435.000000 + TP1446 + + + 435.000000 + TP1447 + + + 435.000000 + TP1448 + + + 435.000000 + TP1449 + + + 435.000000 + TP1450 + + + 435.000000 + TP1451 + + + 435.000000 + TP1452 + + + 435.000000 + TP1453 + + + 435.000000 + TP1454 + + + 435.000000 + TP1455 + + + 435.000000 + TP1456 + + + 435.000000 + TP1457 + + + 435.000000 + TP1458 + + + 435.000000 + TP1459 + + + 435.000000 + TP1460 + + + 435.000000 + TP1461 + + + 435.000000 + TP1462 + + + 435.000000 + TP1463 + + + 435.000000 + TP1464 + + + 435.000000 + TP1465 + + + 435.000000 + TP1466 + + + 435.000000 + TP1467 + + + 435.000000 + TP1468 + + + 435.000000 + TP1469 + + + 435.000000 + TP1470 + + + 435.000000 + TP1471 + + + 435.000000 + TP1472 + + + 435.000000 + TP1473 + + + 435.000000 + TP1474 + + + 435.000000 + TP1475 + + + 435.000000 + TP1476 + + + 435.000000 + TP1477 + + + 435.000000 + TP1478 + + + 435.000000 + TP1479 + + + 435.000000 + TP1480 + + + 436.000000 + TP1481 + + + 436.000000 + TP1482 + + + 436.000000 + TP1483 + + + 436.000000 + TP1484 + + + 435.000000 + TP1485 + + + 435.000000 + TP1486 + + + 435.000000 + TP1487 + + + 435.000000 + TP1488 + + + 435.000000 + TP1489 + + + 435.000000 + TP1490 + + + 435.000000 + TP1491 + + + 435.000000 + TP1492 + + + 435.000000 + TP1493 + + + 435.000000 + TP1494 + + + 435.000000 + TP1495 + + + 436.000000 + TP1496 + + + 436.000000 + TP1497 + + + 436.000000 + TP1498 + + + 436.000000 + TP1499 + + + 436.000000 + TP1500 + + + 436.000000 + TP1501 + + + 436.000000 + TP1502 + + + 436.000000 + TP1503 + + + 436.000000 + TP1504 + + + 436.000000 + TP1505 + + + 436.000000 + TP1506 + + + 436.000000 + TP1507 + + + 436.000000 + TP1508 + + + 436.000000 + TP1509 + + + 436.000000 + TP1510 + + + 436.000000 + TP1511 + + + 436.000000 + TP1512 + + + 436.000000 + TP1513 + + + 436.000000 + TP1514 + + + 436.000000 + TP1515 + + + 436.000000 + TP1516 + + + 436.000000 + TP1517 + + + 436.000000 + TP1518 + + + 436.000000 + TP1519 + + + 436.000000 + TP1520 + + + 436.000000 + TP1521 + + + 436.000000 + TP1522 + + + 436.000000 + TP1523 + + + 436.000000 + TP1524 + + + 436.000000 + TP1525 + + + 436.000000 + TP1526 + + + 436.000000 + TP1527 + + + 436.000000 + TP1528 + + + 436.000000 + TP1529 + + + 436.000000 + TP1530 + + + 436.000000 + TP1531 + + + 436.000000 + TP1532 + + + 436.000000 + TP1533 + + + 436.000000 + TP1534 + + + 436.000000 + TP1535 + + + 436.000000 + TP1536 + + + 436.000000 + TP1537 + + + 436.000000 + TP1538 + + + 436.000000 + TP1539 + + + 436.000000 + TP1540 + + + 436.000000 + TP1541 + + + 436.000000 + TP1542 + + + 436.000000 + TP1543 + + + 436.000000 + TP1544 + + + 436.000000 + TP1545 + + + 436.000000 + TP1546 + + + 436.000000 + TP1547 + + + 436.000000 + TP1548 + + + 436.000000 + TP1549 + + + 436.000000 + TP1550 + + + 436.000000 + TP1551 + + + 436.000000 + TP1552 + + + 436.000000 + TP1553 + + + 436.000000 + TP1554 + + + 436.000000 + TP1555 + + + 436.000000 + TP1556 + + + 436.000000 + TP1557 + + + 436.000000 + TP1558 + + + 436.000000 + TP1559 + + + 436.000000 + TP1560 + + + 436.000000 + TP1561 + + + 436.000000 + TP1562 + + + 437.000000 + TP1563 + + + 437.000000 + TP1564 + + + 437.000000 + TP1565 + + + 437.000000 + TP1566 + + + 437.000000 + TP1567 + + + 437.000000 + TP1568 + + + 437.000000 + TP1569 + + + 437.000000 + TP1570 + + + 437.000000 + TP1571 + + + 437.000000 + TP1572 + + + 437.000000 + TP1573 + + + 437.000000 + TP1574 + + + 437.000000 + TP1575 + + + 437.000000 + TP1576 + + + 437.000000 + TP1577 + + + 437.000000 + TP1578 + + + 437.000000 + TP1579 + + + 438.000000 + TP1580 + + + 438.000000 + TP1581 + + + 438.000000 + TP1582 + + + 438.000000 + TP1583 + + + 438.000000 + TP1584 + + + 438.000000 + TP1585 + + + 438.000000 + TP1586 + + + 438.000000 + TP1587 + + + 438.000000 + TP1588 + + + 438.000000 + TP1589 + + + 438.000000 + TP1590 + + + 438.000000 + TP1591 + + + 438.000000 + TP1592 + + + 438.000000 + TP1593 + + + 438.000000 + TP1594 + + + 438.000000 + TP1595 + + + 438.000000 + TP1596 + + + 438.000000 + TP1597 + + + 438.000000 + TP1598 + + + 438.000000 + TP1599 + + + 438.000000 + TP1600 + + + 438.000000 + TP1601 + + + 439.000000 + TP1602 + + + 439.000000 + TP1603 + + + 439.000000 + TP1604 + + + 439.000000 + TP1605 + + + 439.000000 + TP1606 + + + 439.000000 + TP1607 + + + 439.000000 + TP1608 + + + 439.000000 + TP1609 + + + 439.000000 + TP1610 + + + 439.000000 + TP1611 + + + 439.000000 + TP1612 + + + 439.000000 + TP1613 + + + 439.000000 + TP1614 + + + 439.000000 + TP1615 + + + 439.000000 + TP1616 + + + 439.000000 + TP1617 + + + 439.000000 + TP1618 + + + 439.000000 + TP1619 + + + 439.000000 + TP1620 + + + 439.000000 + TP1621 + + + 439.000000 + TP1622 + + + 439.000000 + TP1623 + + + 439.000000 + TP1624 + + + 439.000000 + TP1625 + + + 439.000000 + TP1626 + + + 439.000000 + TP1627 + + + 439.000000 + TP1628 + + + 439.000000 + TP1629 + + + 439.000000 + TP1630 + + + 439.000000 + TP1631 + + + 439.000000 + TP1632 + + + 439.000000 + TP1633 + + + 439.000000 + TP1634 + + + 439.000000 + TP1635 + + + 439.000000 + TP1636 + + + 439.000000 + TP1637 + + + 439.000000 + TP1638 + + + 439.000000 + TP1639 + + + 439.000000 + TP1640 + + + 439.000000 + TP1641 + + + 439.000000 + TP1642 + + + 439.000000 + TP1643 + + + 440.000000 + TP1644 + + + 440.000000 + TP1645 + + + 440.000000 + TP1646 + + + 440.000000 + TP1647 + + + 440.000000 + TP1648 + + + 440.000000 + TP1649 + + + 440.000000 + TP1650 + + + 440.000000 + TP1651 + + + 440.000000 + TP1652 + + + 440.000000 + TP1653 + + + 440.000000 + TP1654 + + + 440.000000 + TP1655 + + + 440.000000 + TP1656 + + + 440.000000 + TP1657 + + + 440.000000 + TP1658 + + + 440.000000 + TP1659 + + + 440.000000 + TP1660 + + + 440.000000 + TP1661 + + + 440.000000 + TP1662 + + + 440.000000 + TP1663 + + + 440.000000 + TP1664 + + + 440.000000 + TP1665 + + + 440.000000 + TP1666 + + + 440.000000 + TP1667 + + + 440.000000 + TP1668 + + + 440.000000 + TP1669 + + + 440.000000 + TP1670 + + + 440.000000 + TP1671 + + + 440.000000 + TP1672 + + + 440.000000 + TP1673 + + + 440.000000 + TP1674 + + + 440.000000 + TP1675 + + + 440.000000 + TP1676 + + + 440.000000 + TP1677 + + + 440.000000 + TP1678 + + + 440.000000 + TP1679 + + + 440.000000 + TP1680 + + + 440.000000 + TP1681 + + + 440.000000 + TP1682 + + + 440.000000 + TP1683 + + + 440.000000 + TP1684 + + + 440.000000 + TP1685 + + + 440.000000 + TP1686 + + + 440.000000 + TP1687 + + + 440.000000 + TP1688 + + + 440.000000 + TP1689 + + + 440.000000 + TP1690 + + + 440.000000 + TP1691 + + + 440.000000 + TP1692 + + + 440.000000 + TP1693 + + + 440.000000 + TP1694 + + + 440.000000 + TP1695 + + + 440.000000 + TP1696 + + + 440.000000 + TP1697 + + + 440.000000 + TP1698 + + + 440.000000 + TP1699 + + + 440.000000 + TP1700 + + + 440.000000 + TP1701 + + + 440.000000 + TP1702 + + + 440.000000 + TP1703 + + + 440.000000 + TP1704 + + + 440.000000 + TP1705 + + + 440.000000 + TP1706 + + + 440.000000 + TP1707 + + + 440.000000 + TP1708 + + + 440.000000 + TP1709 + + + 440.000000 + TP1710 + + + 440.000000 + TP1711 + + + 440.000000 + TP1712 + + + 440.000000 + TP1713 + + + 440.000000 + TP1714 + + + 440.000000 + TP1715 + + + 440.000000 + TP1716 + + + 440.000000 + TP1717 + + + 440.000000 + TP1718 + + + 440.000000 + TP1719 + + + 440.000000 + TP1720 + + + 440.000000 + TP1721 + + + 440.000000 + TP1722 + + + 440.000000 + TP1723 + + + 440.000000 + TP1724 + + + 440.000000 + TP1725 + + + 440.000000 + TP1726 + + + 440.000000 + TP1727 + + + 440.000000 + TP1728 + + + 440.000000 + TP1729 + + + 440.000000 + TP1730 + + + 440.000000 + TP1731 + + + 440.000000 + TP1732 + + + 440.000000 + TP1733 + + + 440.000000 + TP1734 + + + 440.000000 + TP1735 + + + 440.000000 + TP1736 + + + 440.000000 + TP1737 + + + 440.000000 + TP1738 + + + 440.000000 + TP1739 + + + 440.000000 + TP1740 + + + 440.000000 + TP1741 + + + 440.000000 + TP1742 + + + 440.000000 + TP1743 + + + 440.000000 + TP1744 + + + 440.000000 + TP1745 + + + 440.000000 + TP1746 + + + 440.000000 + TP1747 + + + 440.000000 + TP1748 + + + 440.000000 + TP1749 + + + 440.000000 + TP1750 + + + 440.000000 + TP1751 + + + 440.000000 + TP1752 + + + 440.000000 + TP1753 + + + 440.000000 + TP1754 + + + 440.000000 + TP1755 + + + 440.000000 + TP1756 + + + 440.000000 + TP1757 + + + 440.000000 + TP1758 + + + 440.000000 + TP1759 + + + 441.000000 + TP1760 + + + 441.000000 + TP1761 + + + 441.000000 + TP1762 + + + 441.000000 + TP1763 + + + 441.000000 + TP1764 + + + 441.000000 + TP1765 + + + 441.000000 + TP1766 + + + 441.000000 + TP1767 + + + 441.000000 + TP1768 + + + 441.000000 + TP1769 + + + 441.000000 + TP1770 + + + 441.000000 + TP1771 + + + 441.000000 + TP1772 + + + 441.000000 + TP1773 + + + 441.000000 + TP1774 + + + 441.000000 + TP1775 + + + 441.000000 + TP1776 + + + 441.000000 + TP1777 + + + 441.000000 + TP1778 + + + 441.000000 + TP1779 + + + 441.000000 + TP1780 + + + 441.000000 + TP1781 + + + 441.000000 + TP1782 + + + 441.000000 + TP1783 + + + 441.000000 + TP1784 + + + 441.000000 + TP1785 + + + 441.000000 + TP1786 + + + 441.000000 + TP1787 + + + 441.000000 + TP1788 + + + 441.000000 + TP1789 + + + 441.000000 + TP1790 + + + 441.000000 + TP1791 + + + 441.000000 + TP1792 + + + 441.000000 + TP1793 + + + 441.000000 + TP1794 + + + 441.000000 + TP1795 + + + 441.000000 + TP1796 + + + 441.000000 + TP1797 + + + 441.000000 + TP1798 + + + 441.000000 + TP1799 + + + 441.000000 + TP1800 + + + 441.000000 + TP1801 + + + 441.000000 + TP1802 + + + 441.000000 + TP1803 + + + 441.000000 + TP1804 + + + 441.000000 + TP1805 + + + 441.000000 + TP1806 + + + 441.000000 + TP1807 + + + 441.000000 + TP1808 + + + 441.000000 + TP1809 + + + 441.000000 + TP1810 + + + 441.000000 + TP1811 + + + 441.000000 + TP1812 + + + 441.000000 + TP1813 + + + 441.000000 + TP1814 + + + 441.000000 + TP1815 + + + 441.000000 + TP1816 + + + 441.000000 + TP1817 + + + 441.000000 + TP1818 + + + 441.000000 + TP1819 + + + 441.000000 + TP1820 + + + 441.000000 + TP1821 + + + 441.000000 + TP1822 + + + 441.000000 + TP1823 + + + 441.000000 + TP1824 + + + 441.000000 + TP1825 + + + 441.000000 + TP1826 + + + 441.000000 + TP1827 + + + 441.000000 + TP1828 + + + 441.000000 + TP1829 + + + 441.000000 + TP1830 + + + 441.000000 + TP1831 + + + 441.000000 + TP1832 + + + 441.000000 + TP1833 + + + 441.000000 + TP1834 + + + 441.000000 + TP1835 + + + 441.000000 + TP1836 + + + 441.000000 + TP1837 + + + 441.000000 + TP1838 + + + 441.000000 + TP1839 + + + 441.000000 + TP1840 + + + 441.000000 + TP1841 + + + 441.000000 + TP1842 + + + 441.000000 + TP1843 + + + 441.000000 + TP1844 + + + 441.000000 + TP1845 + + + 441.000000 + TP1846 + + + 441.000000 + TP1847 + + + 441.000000 + TP1848 + + + 441.000000 + TP1849 + + + 441.000000 + TP1850 + + + 441.000000 + TP1851 + + + 441.000000 + TP1852 + + + 441.000000 + TP1853 + + + 441.000000 + TP1854 + + + 441.000000 + TP1855 + + + 441.000000 + TP1856 + + + 441.000000 + TP1857 + + + 441.000000 + TP1858 + + + 441.000000 + TP1859 + + + 441.000000 + TP1860 + + + 441.000000 + TP1861 + + + 441.000000 + TP1862 + + + 441.000000 + TP1863 + + + 441.000000 + TP1864 + + + 441.000000 + TP1865 + + + 441.000000 + TP1866 + + + 441.000000 + TP1867 + + + 441.000000 + TP1868 + + + 441.000000 + TP1869 + + + 441.000000 + TP1870 + + + 441.000000 + TP1871 + + + 441.000000 + TP1872 + + + 441.000000 + TP1873 + + + 441.000000 + TP1874 + + + 441.000000 + TP1875 + + + 441.000000 + TP1876 + + + 441.000000 + TP1877 + + + 441.000000 + TP1878 + + + 441.000000 + TP1879 + + + 441.000000 + TP1880 + + + 441.000000 + TP1881 + + + 441.000000 + TP1882 + + + 441.000000 + TP1883 + + + 441.000000 + TP1884 + + + 441.000000 + TP1885 + + + 441.000000 + TP1886 + + + 441.000000 + TP1887 + + + 441.000000 + TP1888 + + + 441.000000 + TP1889 + + + 441.000000 + TP1890 + + + 441.000000 + TP1891 + + + 441.000000 + TP1892 + + + 441.000000 + TP1893 + + + 441.000000 + TP1894 + + + 441.000000 + TP1895 + + + 441.000000 + TP1896 + + + 441.000000 + TP1897 + + + 441.000000 + TP1898 + + + 441.000000 + TP1899 + + + 441.000000 + TP1900 + + + 441.000000 + TP1901 + + + 441.000000 + TP1902 + + + 441.000000 + TP1903 + + + 441.000000 + TP1904 + + + 441.000000 + TP1905 + + + 441.000000 + TP1906 + + + 441.000000 + TP1907 + + + 441.000000 + TP1908 + + + 441.000000 + TP1909 + + + 441.000000 + TP1910 + + + 441.000000 + TP1911 + + + 441.000000 + TP1912 + + + 441.000000 + TP1913 + + + 441.000000 + TP1914 + + + 441.000000 + TP1915 + + + 441.000000 + TP1916 + + + 441.000000 + TP1917 + + + 441.000000 + TP1918 + + + 441.000000 + TP1919 + + + 441.000000 + TP1920 + + + 441.000000 + TP1921 + + + 441.000000 + TP1922 + + + 441.000000 + TP1923 + + + 441.000000 + TP1924 + + + 441.000000 + TP1925 + + + 441.000000 + TP1926 + + + 441.000000 + TP1927 + + + 441.000000 + TP1928 + + + 441.000000 + TP1929 + + + 441.000000 + TP1930 + + + 441.000000 + TP1931 + + + 441.000000 + TP1932 + + + 441.000000 + TP1933 + + + 441.000000 + TP1934 + + + 441.000000 + TP1935 + + + 441.000000 + TP1936 + + + 441.000000 + TP1937 + + + 441.000000 + TP1938 + + + 441.000000 + TP1939 + + + 441.000000 + TP1940 + + + 441.000000 + TP1941 + + + 441.000000 + TP1942 + + + 441.000000 + TP1943 + + + 441.000000 + TP1944 + + + 441.000000 + TP1945 + + + 441.000000 + TP1946 + + + 441.000000 + TP1947 + + + 441.000000 + TP1948 + + + 441.000000 + TP1949 + + + 441.000000 + TP1950 + + + 441.000000 + TP1951 + + + 441.000000 + TP1952 + + + 441.000000 + TP1953 + + + 441.000000 + TP1954 + + + 441.000000 + TP1955 + + + 441.000000 + TP1956 + + + 441.000000 + TP1957 + + + 441.000000 + TP1958 + + + 441.000000 + TP1959 + + + 441.000000 + TP1960 + + + 441.000000 + TP1961 + + + 441.000000 + TP1962 + + + 441.000000 + TP1963 + + + 441.000000 + TP1964 + + + 441.000000 + TP1965 + + + 441.000000 + TP1966 + + + 441.000000 + TP1967 + + + 441.000000 + TP1968 + + + 441.000000 + TP1969 + + + 441.000000 + TP1970 + + + 441.000000 + TP1971 + + + 441.000000 + TP1972 + + + 441.000000 + TP1973 + + + 441.000000 + TP1974 + + + 441.000000 + TP1975 + + + 441.000000 + TP1976 + + + 441.000000 + TP1977 + + + 441.000000 + TP1978 + + + 441.000000 + TP1979 + + + 441.000000 + TP1980 + + + 441.000000 + TP1981 + + + 441.000000 + TP1982 + + + 441.000000 + TP1983 + + + 441.000000 + TP1984 + + + 441.000000 + TP1985 + + + 441.000000 + TP1986 + + + 441.000000 + TP1987 + + + 441.000000 + TP1988 + + + 441.000000 + TP1989 + + + 441.000000 + TP1990 + + + 441.000000 + TP1991 + + + 441.000000 + TP1992 + + + 441.000000 + TP1993 + + + 441.000000 + TP1994 + + + 441.000000 + TP1995 + + + 441.000000 + TP1996 + + + 441.000000 + TP1997 + + + 441.000000 + TP1998 + + + 441.000000 + TP1999 + + + 441.000000 + TP2000 + + + 441.000000 + TP2001 + + + 441.000000 + TP2002 + + + 441.000000 + TP2003 + + + 441.000000 + TP2004 + + + 441.000000 + TP2005 + + + 441.000000 + TP2006 + + + 441.000000 + TP2007 + + + 441.000000 + TP2008 + + + 441.000000 + TP2009 + + + 441.000000 + TP2010 + + + 441.000000 + TP2011 + + + 441.000000 + TP2012 + + + 441.000000 + TP2013 + + + 441.000000 + TP2014 + + + 441.000000 + TP2015 + + + 441.000000 + TP2016 + + + 441.000000 + TP2017 + + + 441.000000 + TP2018 + + + 441.000000 + TP2019 + + + 441.000000 + TP2020 + + + 441.000000 + TP2021 + + + 441.000000 + TP2022 + + + 441.000000 + TP2023 + + + 441.000000 + TP2024 + + + 441.000000 + TP2025 + + + 441.000000 + TP2026 + + + 441.000000 + TP2027 + + + 441.000000 + TP2028 + + + 441.000000 + TP2029 + + + 441.000000 + TP2030 + + + 441.000000 + TP2031 + + + 441.000000 + TP2032 + + + 441.000000 + TP2033 + + + 441.000000 + TP2034 + + + 441.000000 + TP2035 + + + 441.000000 + TP2036 + + + 441.000000 + TP2037 + + + 441.000000 + TP2038 + + + 441.000000 + TP2039 + + + 441.000000 + TP2040 + + + 441.000000 + TP2041 + + + 441.000000 + TP2042 + + + 441.000000 + TP2043 + + + 441.000000 + TP2044 + + + 441.000000 + TP2045 + + + 440.000000 + TP2046 + + + 440.000000 + TP2047 + + + 440.000000 + TP2048 + + + 440.000000 + TP2049 + + + 440.000000 + TP2050 + + + 440.000000 + TP2051 + + + 440.000000 + TP2052 + + + 440.000000 + TP2053 + + + 440.000000 + TP2054 + + + 440.000000 + TP2055 + + + 440.000000 + TP2056 + + + 440.000000 + TP2057 + + + 440.000000 + TP2058 + + + 440.000000 + TP2059 + + + 440.000000 + TP2060 + + + 440.000000 + TP2061 + + + 440.000000 + TP2062 + + + 440.000000 + TP2063 + + + 440.000000 + TP2064 + + + 440.000000 + TP2065 + + + 440.000000 + TP2066 + + + 440.000000 + TP2067 + + + 440.000000 + TP2068 + + + 440.000000 + TP2069 + + + 440.000000 + TP2070 + + + 440.000000 + TP2071 + + + 440.000000 + TP2072 + + + 440.000000 + TP2073 + + + 440.000000 + TP2074 + + + 440.000000 + TP2075 + + + 440.000000 + TP2076 + + + 440.000000 + TP2077 + + + 440.000000 + TP2078 + + + 440.000000 + TP2079 + + + 440.000000 + TP2080 + + + 440.000000 + TP2081 + + + 440.000000 + TP2082 + + + 440.000000 + TP2083 + + + 440.000000 + TP2084 + + + 440.000000 + TP2085 + + + 440.000000 + TP2086 + + + 440.000000 + TP2087 + + + 440.000000 + TP2088 + + + 440.000000 + TP2089 + + + 440.000000 + TP2090 + + + 440.000000 + TP2091 + + + 440.000000 + TP2092 + + + 440.000000 + TP2093 + + + 440.000000 + TP2094 + + + 440.000000 + TP2095 + + + 440.000000 + TP2096 + + + 440.000000 + TP2097 + + + 440.000000 + TP2098 + + + 440.000000 + TP2099 + + + 440.000000 + TP2100 + + + 440.000000 + TP2101 + + + 440.000000 + TP2102 + + + 440.000000 + TP2103 + + + 440.000000 + TP2104 + + + 440.000000 + TP2105 + + + 440.000000 + TP2106 + + + 440.000000 + TP2107 + + + 440.000000 + TP2108 + + + 440.000000 + TP2109 + + + 440.000000 + TP2110 + + + 440.000000 + TP2111 + + + 440.000000 + TP2112 + + + 440.000000 + TP2113 + + + 440.000000 + TP2114 + + + 440.000000 + TP2115 + + + 440.000000 + TP2116 + + + 440.000000 + TP2117 + + + 440.000000 + TP2118 + + + 440.000000 + TP2119 + + + 440.000000 + TP2120 + + + 447.000000 + TP2121 + + + 447.000000 + TP2122 + + + 446.000000 + TP2123 + + + 446.000000 + TP2124 + + + 446.000000 + TP2125 + + + 446.000000 + TP2126 + + + 446.000000 + TP2127 + + + 446.000000 + TP2128 + + + 446.000000 + TP2129 + + + 446.000000 + TP2130 + + + 446.000000 + TP2131 + + + 446.000000 + TP2132 + + + 446.000000 + TP2133 + + + 446.000000 + TP2134 + + + 446.000000 + TP2135 + + + 446.000000 + TP2136 + + + 446.000000 + TP2137 + + + 446.000000 + TP2138 + + + 446.000000 + TP2139 + + + 446.000000 + TP2140 + + + 446.000000 + TP2141 + + + 446.000000 + TP2142 + + + 446.000000 + TP2143 + + + 446.000000 + TP2144 + + + 446.000000 + TP2145 + + + 446.000000 + TP2146 + + + 446.000000 + TP2147 + + + 446.000000 + TP2148 + + + 446.000000 + TP2149 + + + 446.000000 + TP2150 + + + 446.000000 + TP2151 + + + 446.000000 + TP2152 + + + 446.000000 + TP2153 + + + 446.000000 + TP2154 + + + 446.000000 + TP2155 + + + 446.000000 + TP2156 + + + 446.000000 + TP2157 + + + 446.000000 + TP2158 + + + 446.000000 + TP2159 + + + 446.000000 + TP2160 + + + 446.000000 + TP2161 + + + 446.000000 + TP2162 + + + 446.000000 + TP2163 + + + 446.000000 + TP2164 + + + 446.000000 + TP2165 + + + 446.000000 + TP2166 + + + 446.000000 + TP2167 + + + 446.000000 + TP2168 + + + 446.000000 + TP2169 + + + 446.000000 + TP2170 + + + 446.000000 + TP2171 + + + 446.000000 + TP2172 + + + 446.000000 + TP2173 + + + 446.000000 + TP2174 + + + 446.000000 + TP2175 + + + 446.000000 + TP2176 + + + 446.000000 + TP2177 + + + 446.000000 + TP2178 + + + 446.000000 + TP2179 + + + 446.000000 + TP2180 + + + 446.000000 + TP2181 + + + 446.000000 + TP2182 + + + 446.000000 + TP2183 + + + 446.000000 + TP2184 + + + 446.000000 + TP2185 + + + 446.000000 + TP2186 + + + 446.000000 + TP2187 + + + 446.000000 + TP2188 + + + 446.000000 + TP2189 + + + 446.000000 + TP2190 + + + 446.000000 + TP2191 + + + 446.000000 + TP2192 + + + 446.000000 + TP2193 + + + 446.000000 + TP2194 + + + 446.000000 + TP2195 + + + 446.000000 + TP2196 + + + 446.000000 + TP2197 + + + 446.000000 + TP2198 + + + 446.000000 + TP2199 + + + 446.000000 + TP2200 + + + 446.000000 + TP2201 + + + 446.000000 + TP2202 + + + 446.000000 + TP2203 + + + 446.000000 + TP2204 + + + 446.000000 + TP2205 + + + 446.000000 + TP2206 + + + 446.000000 + TP2207 + + + 446.000000 + TP2208 + + + 446.000000 + TP2209 + + + 446.000000 + TP2210 + + + 446.000000 + TP2211 + + + 446.000000 + TP2212 + + + 446.000000 + TP2213 + + + 446.000000 + TP2214 + + + 446.000000 + TP2215 + + + 446.000000 + TP2216 + + + 446.000000 + TP2217 + + + 446.000000 + TP2218 + + + 446.000000 + TP2219 + + + 446.000000 + TP2220 + + + 446.000000 + TP2221 + + + 446.000000 + TP2222 + + + 446.000000 + TP2223 + + + 446.000000 + TP2224 + + + 446.000000 + TP2225 + + + 446.000000 + TP2226 + + + 446.000000 + TP2227 + + + 446.000000 + TP2228 + + + 446.000000 + TP2229 + + + 446.000000 + TP2230 + + + 446.000000 + TP2231 + + + 446.000000 + TP2232 + + + 446.000000 + TP2233 + + + 446.000000 + TP2234 + + + 446.000000 + TP2235 + + + 446.000000 + TP2236 + + + 446.000000 + TP2237 + + + 446.000000 + TP2238 + + + 446.000000 + TP2239 + + + 446.000000 + TP2240 + + + 446.000000 + TP2241 + + + 446.000000 + TP2242 + + + 446.000000 + TP2243 + + + 446.000000 + TP2244 + + + 446.000000 + TP2245 + + + 446.000000 + TP2246 + + + 446.000000 + TP2247 + + + 446.000000 + TP2248 + + + 446.000000 + TP2249 + + + 446.000000 + TP2250 + + + 446.000000 + TP2251 + + + 446.000000 + TP2252 + + + 446.000000 + TP2253 + + + 446.000000 + TP2254 + + + 446.000000 + TP2255 + + + 446.000000 + TP2256 + + + 446.000000 + TP2257 + + + 446.000000 + TP2258 + + + 446.000000 + TP2259 + + + 446.000000 + TP2260 + + + 446.000000 + TP2261 + + + 446.000000 + TP2262 + + + 446.000000 + TP2263 + + + 446.000000 + TP2264 + + + 446.000000 + TP2265 + + + 446.000000 + TP2266 + + + 446.000000 + TP2267 + + + 446.000000 + TP2268 + + + 446.000000 + TP2269 + + + 446.000000 + TP2270 + + + 446.000000 + TP2271 + + + 446.000000 + TP2272 + + + 446.000000 + TP2273 + + + 446.000000 + TP2274 + + + 446.000000 + TP2275 + + + 446.000000 + TP2276 + + + 446.000000 + TP2277 + + + 446.000000 + TP2278 + + + 446.000000 + TP2279 + + + 446.000000 + TP2280 + + + 446.000000 + TP2281 + + + 446.000000 + TP2282 + + + 446.000000 + TP2283 + + + 446.000000 + TP2284 + + + 446.000000 + TP2285 + + + 446.000000 + TP2286 + + + 446.000000 + TP2287 + + + 446.000000 + TP2288 + + + 446.000000 + TP2289 + + + 446.000000 + TP2290 + + + 446.000000 + TP2291 + + + 446.000000 + TP2292 + + + 446.000000 + TP2293 + + + 446.000000 + TP2294 + + + 446.000000 + TP2295 + + + 446.000000 + TP2296 + + + 446.000000 + TP2297 + + + 446.000000 + TP2298 + + + 446.000000 + TP2299 + + + 446.000000 + TP2300 + + + 446.000000 + TP2301 + + + 446.000000 + TP2302 + + + 446.000000 + TP2303 + + + 446.000000 + TP2304 + + + 446.000000 + TP2305 + + + 446.000000 + TP2306 + + + 446.000000 + TP2307 + + + 446.000000 + TP2308 + + + 446.000000 + TP2309 + + + 446.000000 + TP2310 + + + 446.000000 + TP2311 + + + 446.000000 + TP2312 + + + 446.000000 + TP2313 + + + 446.000000 + TP2314 + + + 446.000000 + TP2315 + + + 446.000000 + TP2316 + + + 446.000000 + TP2317 + + + 446.000000 + TP2318 + + + 446.000000 + TP2319 + + + 446.000000 + TP2320 + + + 446.000000 + TP2321 + + + 446.000000 + TP2322 + + + 446.000000 + TP2323 + + + 446.000000 + TP2324 + + + 446.000000 + TP2325 + + + 446.000000 + TP2326 + + + 446.000000 + TP2327 + + + 446.000000 + TP2328 + + + 446.000000 + TP2329 + + + 446.000000 + TP2330 + + + 446.000000 + TP2331 + + + 446.000000 + TP2332 + + + 446.000000 + TP2333 + + + 446.000000 + TP2334 + + + 446.000000 + TP2335 + + + 446.000000 + TP2336 + + + 446.000000 + TP2337 + + + 446.000000 + TP2338 + + + 446.000000 + TP2339 + + + 446.000000 + TP2340 + + + 446.000000 + TP2341 + + + 446.000000 + TP2342 + + + 446.000000 + TP2343 + + + 446.000000 + TP2344 + + + 446.000000 + TP2345 + + + 446.000000 + TP2346 + + + 446.000000 + TP2347 + + + 446.000000 + TP2348 + + + 446.000000 + TP2349 + + + 446.000000 + TP2350 + + + 446.000000 + TP2351 + + + 446.000000 + TP2352 + + + 446.000000 + TP2353 + + + 446.000000 + TP2354 + + + 446.000000 + TP2355 + + + 446.000000 + TP2356 + + + 446.000000 + TP2357 + + + 446.000000 + TP2358 + + + 446.000000 + TP2359 + + + 446.000000 + TP2360 + + + 446.000000 + TP2361 + + + 446.000000 + TP2362 + + + 446.000000 + TP2363 + + + 446.000000 + TP2364 + + + 446.000000 + TP2365 + + + 446.000000 + TP2366 + + + 446.000000 + TP2367 + + + 446.000000 + TP2368 + + + 446.000000 + TP2369 + + + 446.000000 + TP2370 + + + 446.000000 + TP2371 + + + 446.000000 + TP2372 + + + 446.000000 + TP2373 + + + 446.000000 + TP2374 + + + 446.000000 + TP2375 + + + 446.000000 + TP2376 + + + 446.000000 + TP2377 + + + 446.000000 + TP2378 + + + 446.000000 + TP2379 + + + 446.000000 + TP2380 + + + 446.000000 + TP2381 + + + 446.000000 + TP2382 + + + 446.000000 + TP2383 + + + 446.000000 + TP2384 + + + 446.000000 + TP2385 + + + 446.000000 + TP2386 + + + 446.000000 + TP2387 + + + 446.000000 + TP2388 + + + 446.000000 + TP2389 + + + 446.000000 + TP2390 + + + 446.000000 + TP2391 + + + 446.000000 + TP2392 + + + 446.000000 + TP2393 + + + 446.000000 + TP2394 + + + 446.000000 + TP2395 + + + 446.000000 + TP2396 + + + 446.000000 + TP2397 + + + 446.000000 + TP2398 + + + 446.000000 + TP2399 + + + 446.000000 + TP2400 + + + 446.000000 + TP2401 + + + 446.000000 + TP2402 + + + 446.000000 + TP2403 + + + 446.000000 + TP2404 + + + 446.000000 + TP2405 + + + 446.000000 + TP2406 + + + 446.000000 + TP2407 + + + 446.000000 + TP2408 + + + 446.000000 + TP2409 + + + 446.000000 + TP2410 + + + 446.000000 + TP2411 + + + 446.000000 + TP2412 + + + 446.000000 + TP2413 + + + 446.000000 + TP2414 + + + 446.000000 + TP2415 + + + 446.000000 + TP2416 + + + 446.000000 + TP2417 + + + 446.000000 + TP2418 + + + 446.000000 + TP2419 + + + 446.000000 + TP2420 + + + 446.000000 + TP2421 + + + 446.000000 + TP2422 + + + 446.000000 + TP2423 + + + 446.000000 + TP2424 + + + 446.000000 + TP2425 + + + 446.000000 + TP2426 + + + 446.000000 + TP2427 + + + 446.000000 + TP2428 + + + 446.000000 + TP2429 + + + 446.000000 + TP2430 + + + 446.000000 + TP2431 + + + 446.000000 + TP2432 + + + 446.000000 + TP2433 + + + 446.000000 + TP2434 + + + 446.000000 + TP2435 + + + 446.000000 + TP2436 + + + 446.000000 + TP2437 + + + 446.000000 + TP2438 + + + 446.000000 + TP2439 + + + 446.000000 + TP2440 + + + 446.000000 + TP2441 + + + 446.000000 + TP2442 + + + 446.000000 + TP2443 + + + 446.000000 + TP2444 + + + 446.000000 + TP2445 + + + 446.000000 + TP2446 + + + 446.000000 + TP2447 + + + 446.000000 + TP2448 + + + 446.000000 + TP2449 + + + 446.000000 + TP2450 + + + 446.000000 + TP2451 + + + 446.000000 + TP2452 + + + 446.000000 + TP2453 + + + 446.000000 + TP2454 + + + 446.000000 + TP2455 + + + 446.000000 + TP2456 + + + 446.000000 + TP2457 + + + 446.000000 + TP2458 + + + 446.000000 + TP2459 + + + 446.000000 + TP2460 + + + 446.000000 + TP2461 + + + 446.000000 + TP2462 + + + 446.000000 + TP2463 + + + 446.000000 + TP2464 + + + 446.000000 + TP2465 + + + 446.000000 + TP2466 + + + 446.000000 + TP2467 + + + 446.000000 + TP2468 + + + 446.000000 + TP2469 + + + 446.000000 + TP2470 + + + 446.000000 + TP2471 + + + 446.000000 + TP2472 + + + 446.000000 + TP2473 + + + 446.000000 + TP2474 + + + 446.000000 + TP2475 + + + 446.000000 + TP2476 + + + 446.000000 + TP2477 + + + 446.000000 + TP2478 + + + 446.000000 + TP2479 + + + 446.000000 + TP2480 + + + 446.000000 + TP2481 + + + 446.000000 + TP2482 + + + 446.000000 + TP2483 + + + 446.000000 + TP2484 + + + 446.000000 + TP2485 + + + 446.000000 + TP2486 + + + 446.000000 + TP2487 + + + 446.000000 + TP2488 + + + 446.000000 + TP2489 + + + 446.000000 + TP2490 + + + 446.000000 + TP2491 + + + 446.000000 + TP2492 + + + 446.000000 + TP2493 + + + 446.000000 + TP2494 + + + 446.000000 + TP2495 + + + 446.000000 + TP2496 + + + 446.000000 + TP2497 + + + 446.000000 + TP2498 + + + 446.000000 + TP2499 + + + 446.000000 + TP2500 + + + 446.000000 + TP2501 + + + 446.000000 + TP2502 + + + 446.000000 + TP2503 + + + 446.000000 + TP2504 + + + 446.000000 + TP2505 + + + 446.000000 + TP2506 + + + 446.000000 + TP2507 + + + 446.000000 + TP2508 + + + 446.000000 + TP2509 + + + 446.000000 + TP2510 + + + 446.000000 + TP2511 + + + 446.000000 + TP2512 + + + 446.000000 + TP2513 + + + 446.000000 + TP2514 + + + 446.000000 + TP2515 + + + 446.000000 + TP2516 + + + 446.000000 + TP2517 + + + 446.000000 + TP2518 + + + 446.000000 + TP2519 + + + 446.000000 + TP2520 + + + 446.000000 + TP2521 + + + 446.000000 + TP2522 + + + 446.000000 + TP2523 + + + 446.000000 + TP2524 + + + 446.000000 + TP2525 + + + 446.000000 + TP2526 + + + 446.000000 + TP2527 + + + 446.000000 + TP2528 + + + 446.000000 + TP2529 + + + 446.000000 + TP2530 + + + 446.000000 + TP2531 + + + 446.000000 + TP2532 + + + 446.000000 + TP2533 + + + 446.000000 + TP2534 + + + 446.000000 + TP2535 + + + 446.000000 + TP2536 + + + 446.000000 + TP2537 + + + 446.000000 + TP2538 + + + 446.000000 + TP2539 + + + 446.000000 + TP2540 + + + 446.000000 + TP2541 + + + 446.000000 + TP2542 + + + 446.000000 + TP2543 + + + 446.000000 + TP2544 + + + 446.000000 + TP2545 + + + 446.000000 + TP2546 + + + 446.000000 + TP2547 + + + 446.000000 + TP2548 + + + 446.000000 + TP2549 + + + 446.000000 + TP2550 + + + 446.000000 + TP2551 + + + 446.000000 + TP2552 + + + 446.000000 + TP2553 + + + 446.000000 + TP2554 + + + 446.000000 + TP2555 + + + 446.000000 + TP2556 + + + 446.000000 + TP2557 + + + 446.000000 + TP2558 + + + 446.000000 + TP2559 + + + 446.000000 + TP2560 + + + 446.000000 + TP2561 + + + 446.000000 + TP2562 + + + 446.000000 + TP2563 + + + 446.000000 + TP2564 + + + 446.000000 + TP2565 + + + 446.000000 + TP2566 + + + 446.000000 + TP2567 + + + 446.000000 + TP2568 + + + 446.000000 + TP2569 + + + 446.000000 + TP2570 + + + 446.000000 + TP2571 + + + 446.000000 + TP2572 + + + 446.000000 + TP2573 + + + 446.000000 + TP2574 + + + 446.000000 + TP2575 + + + 446.000000 + TP2576 + + + 446.000000 + TP2577 + + + 446.000000 + TP2578 + + + 446.000000 + TP2579 + + + 446.000000 + TP2580 + + + 446.000000 + TP2581 + + + 446.000000 + TP2582 + + + 446.000000 + TP2583 + + + 446.000000 + TP2584 + + + 446.000000 + TP2585 + + + 446.000000 + TP2586 + + + 446.000000 + TP2587 + + + 446.000000 + TP2588 + + + 446.000000 + TP2589 + + + 447.000000 + TP2590 + + + 447.000000 + TP2591 + + + 447.000000 + TP2592 + + + 447.000000 + TP2593 + + + 447.000000 + TP2594 + + + 447.000000 + TP2595 + + + 447.000000 + TP2596 + + + 447.000000 + TP2597 + + + 447.000000 + TP2598 + + + 447.000000 + TP2599 + + + 447.000000 + TP2600 + + + 447.000000 + TP2601 + + + 447.000000 + TP2602 + + + 447.000000 + TP2603 + + + 447.000000 + TP2604 + + + 447.000000 + TP2605 + + + 447.000000 + TP2606 + + + 447.000000 + TP2607 + + + 447.000000 + TP2608 + + + 447.000000 + TP2609 + + + 447.000000 + TP2610 + + + 447.000000 + TP2611 + + + 447.000000 + TP2612 + + + 447.000000 + TP2613 + + + 447.000000 + TP2614 + + + 447.000000 + TP2615 + + + 447.000000 + TP2616 + + + 447.000000 + TP2617 + + + 447.000000 + TP2618 + + + 447.000000 + TP2619 + + + 447.000000 + TP2620 + + + 447.000000 + TP2621 + + + 447.000000 + TP2622 + + + 447.000000 + TP2623 + + + 447.000000 + TP2624 + + + 447.000000 + TP2625 + + + 447.000000 + TP2626 + + + 446.000000 + TP2627 + + + 446.000000 + TP2628 + + + 446.000000 + TP2629 + + + 446.000000 + TP2630 + + + 446.000000 + TP2631 + + + 446.000000 + TP2632 + + + 446.000000 + TP2633 + + + 446.000000 + TP2634 + + + 446.000000 + TP2635 + + + 446.000000 + TP2636 + + + 446.000000 + TP2637 + + + 446.000000 + TP2638 + + + 446.000000 + TP2639 + + + 446.000000 + TP2640 + + + 446.000000 + TP2641 + + + 446.000000 + TP2642 + + + 446.000000 + TP2643 + + + 447.000000 + TP2644 + + + 447.000000 + TP2645 + + + 447.000000 + TP2646 + + + 447.000000 + TP2647 + + + 447.000000 + TP2648 + + + 447.000000 + TP2649 + + + 447.000000 + TP2650 + + + 447.000000 + TP2651 + + + 447.000000 + TP2652 + + + 447.000000 + TP2653 + + + 447.000000 + TP2654 + + + 447.000000 + TP2655 + + + 447.000000 + TP2656 + + + 447.000000 + TP2657 + + + 447.000000 + TP2658 + + + 447.000000 + TP2659 + + + 447.000000 + TP2660 + + + 447.000000 + TP2661 + + + 447.000000 + TP2662 + + + 447.000000 + TP2663 + + + 447.000000 + TP2664 + + + 447.000000 + TP2665 + + + 447.000000 + TP2666 + + + 447.000000 + TP2667 + + + 448.000000 + TP2668 + + + 448.000000 + TP2669 + + + 448.000000 + TP2670 + + + 448.000000 + TP2671 + + + 448.000000 + TP2672 + + + 448.000000 + TP2673 + + + 448.000000 + TP2674 + + + 448.000000 + TP2675 + + + 448.000000 + TP2676 + + + 448.000000 + TP2677 + + + 448.000000 + TP2678 + + + 448.000000 + TP2679 + + + 448.000000 + TP2680 + + + 448.000000 + TP2681 + + + 448.000000 + TP2682 + + + 448.000000 + TP2683 + + + 448.000000 + TP2684 + + + 448.000000 + TP2685 + + + 448.000000 + TP2686 + + + 448.000000 + TP2687 + + + 448.000000 + TP2688 + + + 448.000000 + TP2689 + + + 448.000000 + TP2690 + + + 448.000000 + TP2691 + + + 448.000000 + TP2692 + + + 448.000000 + TP2693 + + + 448.000000 + TP2694 + + + 448.000000 + TP2695 + + + 448.000000 + TP2696 + + + 448.000000 + TP2697 + + + 448.000000 + TP2698 + + + 448.000000 + TP2699 + + + 448.000000 + TP2700 + + + 448.000000 + TP2701 + + + 448.000000 + TP2702 + + + 448.000000 + TP2703 + + + 448.000000 + TP2704 + + + 448.000000 + TP2705 + + + 448.000000 + TP2706 + + + 448.000000 + TP2707 + + + 448.000000 + TP2708 + + + 448.000000 + TP2709 + + + 448.000000 + TP2710 + + + 448.000000 + TP2711 + + + 448.000000 + TP2712 + + + 448.000000 + TP2713 + + + 448.000000 + TP2714 + + + 448.000000 + TP2715 + + + 448.000000 + TP2716 + + + 448.000000 + TP2717 + + + 448.000000 + TP2718 + + + 448.000000 + TP2719 + + + 448.000000 + TP2720 + + + 448.000000 + TP2721 + + + 448.000000 + TP2722 + + + 448.000000 + TP2723 + + + 448.000000 + TP2724 + + + 448.000000 + TP2725 + + + 448.000000 + TP2726 + + + 448.000000 + TP2727 + + + 448.000000 + TP2728 + + + 448.000000 + TP2729 + + + 448.000000 + TP2730 + + + 448.000000 + TP2731 + + + 448.000000 + TP2732 + + + 448.000000 + TP2733 + + + 448.000000 + TP2734 + + + 448.000000 + TP2735 + + + 448.000000 + TP2736 + + + 448.000000 + TP2737 + + + 448.000000 + TP2738 + + + 448.000000 + TP2739 + + + 448.000000 + TP2740 + + + 448.000000 + TP2741 + + + 448.000000 + TP2742 + + + 448.000000 + TP2743 + + + 448.000000 + TP2744 + + + 448.000000 + TP2745 + + + 448.000000 + TP2746 + + + 448.000000 + TP2747 + + + 448.000000 + TP2748 + + + 448.000000 + TP2749 + + + 448.000000 + TP2750 + + + 448.000000 + TP2751 + + + 448.000000 + TP2752 + + + 448.000000 + TP2753 + + + 448.000000 + TP2754 + + + 448.000000 + TP2755 + + + 448.000000 + TP2756 + + + 448.000000 + TP2757 + + + 448.000000 + TP2758 + + + 448.000000 + TP2759 + + + 448.000000 + TP2760 + + + 448.000000 + TP2761 + + + 448.000000 + TP2762 + + + 448.000000 + TP2763 + + + 448.000000 + TP2764 + + + 448.000000 + TP2765 + + + 448.000000 + TP2766 + + + 448.000000 + TP2767 + + + 448.000000 + TP2768 + + + 448.000000 + TP2769 + + + 448.000000 + TP2770 + + + 448.000000 + TP2771 + + + 448.000000 + TP2772 + + + 448.000000 + TP2773 + + + 448.000000 + TP2774 + + + 448.000000 + TP2775 + + + 448.000000 + TP2776 + + + 448.000000 + TP2777 + + + 448.000000 + TP2778 + + + 448.000000 + TP2779 + + + 448.000000 + TP2780 + + + 448.000000 + TP2781 + + + 448.000000 + TP2782 + + + 448.000000 + TP2783 + + + 448.000000 + TP2784 + + + 448.000000 + TP2785 + + + 448.000000 + TP2786 + + + 448.000000 + TP2787 + + + 448.000000 + TP2788 + + + 448.000000 + TP2789 + + + 448.000000 + TP2790 + + + 448.000000 + TP2791 + + + 448.000000 + TP2792 + + + 448.000000 + TP2793 + + + 448.000000 + TP2794 + + + 448.000000 + TP2795 + + + 448.000000 + TP2796 + + + 448.000000 + TP2797 + + + 448.000000 + TP2798 + + + 449.000000 + TP2799 + + + 449.000000 + TP2800 + + + 449.000000 + TP2801 + + + 449.000000 + TP2802 + + + 449.000000 + TP2803 + + + 449.000000 + TP2804 + + + 449.000000 + TP2805 + + + 449.000000 + TP2806 + + + 449.000000 + TP2807 + + + 449.000000 + TP2808 + + + 449.000000 + TP2809 + + + 449.000000 + TP2810 + + + 449.000000 + TP2811 + + + 449.000000 + TP2812 + + + 449.000000 + TP2813 + + + 449.000000 + TP2814 + + + 449.000000 + TP2815 + + + 449.000000 + TP2816 + + + 449.000000 + TP2817 + + + 449.000000 + TP2818 + + + 449.000000 + TP2819 + + + 449.000000 + TP2820 + + + 449.000000 + TP2821 + + + 449.000000 + TP2822 + + + 449.000000 + TP2823 + + + 449.000000 + TP2824 + + + 449.000000 + TP2825 + + + 449.000000 + TP2826 + + + 449.000000 + TP2827 + + + 449.000000 + TP2828 + + + 449.000000 + TP2829 + + + 449.000000 + TP2830 + + + 449.000000 + TP2831 + + + 449.000000 + TP2832 + + + 449.000000 + TP2833 + + + 449.000000 + TP2834 + + + 449.000000 + TP2835 + + + 449.000000 + TP2836 + + + 449.000000 + TP2837 + + + 449.000000 + TP2838 + + + 449.000000 + TP2839 + + + 449.000000 + TP2840 + + + 449.000000 + TP2841 + + + 449.000000 + TP2842 + + + 449.000000 + TP2843 + + + 449.000000 + TP2844 + + + 449.000000 + TP2845 + + + 449.000000 + TP2846 + + + 449.000000 + TP2847 + + + 449.000000 + TP2848 + + + 449.000000 + TP2849 + + + 449.000000 + TP2850 + + + 449.000000 + TP2851 + + + 449.000000 + TP2852 + + + 449.000000 + TP2853 + + + 449.000000 + TP2854 + + + 449.000000 + TP2855 + + + 449.000000 + TP2856 + + + 449.000000 + TP2857 + + + 449.000000 + TP2858 + + + 449.000000 + TP2859 + + + 449.000000 + TP2860 + + + 449.000000 + TP2861 + + + 449.000000 + TP2862 + + + 449.000000 + TP2863 + + + 449.000000 + TP2864 + + + 449.000000 + TP2865 + + + 449.000000 + TP2866 + + + 449.000000 + TP2867 + + + 449.000000 + TP2868 + + + 449.000000 + TP2869 + + + 449.000000 + TP2870 + + + 449.000000 + TP2871 + + + 449.000000 + TP2872 + + + 449.000000 + TP2873 + + + 448.000000 + TP2874 + + + 448.000000 + TP2875 + + + 448.000000 + TP2876 + + + 448.000000 + TP2877 + + + 448.000000 + TP2878 + + + 448.000000 + TP2879 + + + 448.000000 + TP2880 + + + 448.000000 + TP2881 + + + 448.000000 + TP2882 + + + 448.000000 + TP2883 + + + 448.000000 + TP2884 + + + 448.000000 + TP2885 + + + 448.000000 + TP2886 + + + 448.000000 + TP2887 + + + 448.000000 + TP2888 + + + 448.000000 + TP2889 + + + 448.000000 + TP2890 + + + 448.000000 + TP2891 + + + 448.000000 + TP2892 + + + 448.000000 + TP2893 + + + 448.000000 + TP2894 + + + 448.000000 + TP2895 + + + 448.000000 + TP2896 + + + 448.000000 + TP2897 + + + 448.000000 + TP2898 + + + 448.000000 + TP2899 + + + 448.000000 + TP2900 + + + 448.000000 + TP2901 + + + 448.000000 + TP2902 + + + 448.000000 + TP2903 + + + 448.000000 + TP2904 + + + 448.000000 + TP2905 + + + 448.000000 + TP2906 + + + 448.000000 + TP2907 + + + 448.000000 + TP2908 + + + 448.000000 + TP2909 + + + 448.000000 + TP2910 + + + 448.000000 + TP2911 + + + 448.000000 + TP2912 + + + 448.000000 + TP2913 + + + 448.000000 + TP2914 + + + 448.000000 + TP2915 + + + 448.000000 + TP2916 + + + 448.000000 + TP2917 + + + 448.000000 + TP2918 + + + 448.000000 + TP2919 + + + 448.000000 + TP2920 + + + 448.000000 + TP2921 + + + 448.000000 + TP2922 + + + 448.000000 + TP2923 + + + 448.000000 + TP2924 + + + 448.000000 + TP2925 + + + 448.000000 + TP2926 + + + 448.000000 + TP2927 + + + 448.000000 + TP2928 + + + 448.000000 + TP2929 + + + 448.000000 + TP2930 + + + 448.000000 + TP2931 + + + 448.000000 + TP2932 + + + 448.000000 + TP2933 + + + 448.000000 + TP2934 + + + 448.000000 + TP2935 + + + 448.000000 + TP2936 + + + 448.000000 + TP2937 + + + 448.000000 + TP2938 + + + 448.000000 + TP2939 + + + 448.000000 + TP2940 + + + 448.000000 + TP2941 + + + 448.000000 + TP2942 + + + 448.000000 + TP2943 + + + 448.000000 + TP2944 + + + 448.000000 + TP2945 + + + 448.000000 + TP2946 + + + 448.000000 + TP2947 + + + 448.000000 + TP2948 + + + 448.000000 + TP2949 + + + 448.000000 + TP2950 + + + 448.000000 + TP2951 + + + 448.000000 + TP2952 + + + 448.000000 + TP2953 + + + 448.000000 + TP2954 + + + 448.000000 + TP2955 + + + 448.000000 + TP2956 + + + 448.000000 + TP2957 + + + 448.000000 + TP2958 + + + 448.000000 + TP2959 + + + 448.000000 + TP2960 + + + 448.000000 + TP2961 + + + 448.000000 + TP2962 + + + 448.000000 + TP2963 + + + 448.000000 + TP2964 + + + 448.000000 + TP2965 + + + 448.000000 + TP2966 + + + 448.000000 + TP2967 + + + 448.000000 + TP2968 + + + 448.000000 + TP2969 + + + 448.000000 + TP2970 + + + 448.000000 + TP2971 + + + 448.000000 + TP2972 + + + 448.000000 + TP2973 + + + 448.000000 + TP2974 + + + 448.000000 + TP2975 + + + 448.000000 + TP2976 + + + 448.000000 + TP2977 + + + 448.000000 + TP2978 + + + 448.000000 + TP2979 + + + 448.000000 + TP2980 + + + 448.000000 + TP2981 + + + 448.000000 + TP2982 + + + 448.000000 + TP2983 + + + 448.000000 + TP2984 + + + 448.000000 + TP2985 + + + 448.000000 + TP2986 + + + 448.000000 + TP2987 + + + 448.000000 + TP2988 + + + 448.000000 + TP2989 + + + 448.000000 + TP2990 + + + 448.000000 + TP2991 + + + 448.000000 + TP2992 + + + 448.000000 + TP2993 + + + 448.000000 + TP2994 + + + 448.000000 + TP2995 + + + 448.000000 + TP2996 + + + 449.000000 + TP2997 + + + 449.000000 + TP2998 + + + 449.000000 + TP2999 + + + 449.000000 + TP3000 + + + 449.000000 + TP3001 + + + 449.000000 + TP3002 + + + 449.000000 + TP3003 + + + 449.000000 + TP3004 + + + 449.000000 + TP3005 + + + 449.000000 + TP3006 + + + 449.000000 + TP3007 + + + 449.000000 + TP3008 + + + 449.000000 + TP3009 + + + 449.000000 + TP3010 + + + 449.000000 + TP3011 + + + 449.000000 + TP3012 + + + 449.000000 + TP3013 + + + 449.000000 + TP3014 + + + 449.000000 + TP3015 + + + 449.000000 + TP3016 + + + 449.000000 + TP3017 + + + 449.000000 + TP3018 + + + 449.000000 + TP3019 + + + 449.000000 + TP3020 + + + 449.000000 + TP3021 + + + 449.000000 + TP3022 + + + 449.000000 + TP3023 + + + 449.000000 + TP3024 + + + 449.000000 + TP3025 + + + 449.000000 + TP3026 + + + 449.000000 + TP3027 + + + 449.000000 + TP3028 + + + 449.000000 + TP3029 + + + 449.000000 + TP3030 + + + 449.000000 + TP3031 + + + 449.000000 + TP3032 + + + 449.000000 + TP3033 + + + 449.000000 + TP3034 + + + 449.000000 + TP3035 + + + 449.000000 + TP3036 + + + 449.000000 + TP3037 + + + 449.000000 + TP3038 + + + 449.000000 + TP3039 + + + 449.000000 + TP3040 + + + 449.000000 + TP3041 + + + 449.000000 + TP3042 + + + 449.000000 + TP3043 + + + 449.000000 + TP3044 + + + 449.000000 + TP3045 + + + 449.000000 + TP3046 + + + 449.000000 + TP3047 + + + 449.000000 + TP3048 + + + 449.000000 + TP3049 + + + 449.000000 + TP3050 + + + 449.000000 + TP3051 + + + 449.000000 + TP3052 + + + 449.000000 + TP3053 + + + 449.000000 + TP3054 + + + 449.000000 + TP3055 + + + 449.000000 + TP3056 + + + 449.000000 + TP3057 + + + 449.000000 + TP3058 + + + 449.000000 + TP3059 + + + 449.000000 + TP3060 + + + 449.000000 + TP3061 + + + 449.000000 + TP3062 + + + 449.000000 + TP3063 + + + 449.000000 + TP3064 + + + 449.000000 + TP3065 + + + 449.000000 + TP3066 + + + 449.000000 + TP3067 + + + 449.000000 + TP3068 + + + 449.000000 + TP3069 + + + 449.000000 + TP3070 + + + 449.000000 + TP3071 + + + 449.000000 + TP3072 + + + 449.000000 + TP3073 + + + 449.000000 + TP3074 + + + 449.000000 + TP3075 + + + 449.000000 + TP3076 + + + 449.000000 + TP3077 + + + 449.000000 + TP3078 + + + 449.000000 + TP3079 + + + 449.000000 + TP3080 + + + 449.000000 + TP3081 + + + 449.000000 + TP3082 + + + 449.000000 + TP3083 + + + 449.000000 + TP3084 + + + 449.000000 + TP3085 + + + 449.000000 + TP3086 + + + 449.000000 + TP3087 + + + 449.000000 + TP3088 + + + 449.000000 + TP3089 + + + 449.000000 + TP3090 + + + 449.000000 + TP3091 + + + 449.000000 + TP3092 + + + 449.000000 + TP3093 + + + 449.000000 + TP3094 + + + 449.000000 + TP3095 + + + 449.000000 + TP3096 + + + 449.000000 + TP3097 + + + 449.000000 + TP3098 + + + 449.000000 + TP3099 + + + 449.000000 + TP3100 + + + 449.000000 + TP3101 + + + 449.000000 + TP3102 + + + 449.000000 + TP3103 + + + 449.000000 + TP3104 + + + 449.000000 + TP3105 + + + 449.000000 + TP3106 + + + 449.000000 + TP3107 + + + 449.000000 + TP3108 + + + 449.000000 + TP3109 + + + 449.000000 + TP3110 + + + 449.000000 + TP3111 + + + 449.000000 + TP3112 + + + 449.000000 + TP3113 + + + 449.000000 + TP3114 + + + 449.000000 + TP3115 + + + 449.000000 + TP3116 + + + 449.000000 + TP3117 + + + 449.000000 + TP3118 + + + 449.000000 + TP3119 + + + 449.000000 + TP3120 + + + 449.000000 + TP3121 + + + 449.000000 + TP3122 + + + 449.000000 + TP3123 + + + 449.000000 + TP3124 + + + 449.000000 + TP3125 + + + 449.000000 + TP3126 + + + 449.000000 + TP3127 + + + 449.000000 + TP3128 + + + 449.000000 + TP3129 + + + 449.000000 + TP3130 + + + 449.000000 + TP3131 + + + 449.000000 + TP3132 + + + 449.000000 + TP3133 + + + 449.000000 + TP3134 + + + 449.000000 + TP3135 + + + 449.000000 + TP3136 + + + 449.000000 + TP3137 + + + 449.000000 + TP3138 + + + 449.000000 + TP3139 + + + 449.000000 + TP3140 + + + 449.000000 + TP3141 + + + 449.000000 + TP3142 + + + 449.000000 + TP3143 + + + 449.000000 + TP3144 + + + 449.000000 + TP3145 + + + 449.000000 + TP3146 + + + 449.000000 + TP3147 + + + 449.000000 + TP3148 + + + 449.000000 + TP3149 + + + 449.000000 + TP3150 + + + 449.000000 + TP3151 + + + 449.000000 + TP3152 + + + 449.000000 + TP3153 + + + 449.000000 + TP3154 + + + 449.000000 + TP3155 + + + 449.000000 + TP3156 + + + 449.000000 + TP3157 + + + 449.000000 + TP3158 + + + 449.000000 + TP3159 + + + 449.000000 + TP3160 + + + 449.000000 + TP3161 + + + 449.000000 + TP3162 + + + 449.000000 + TP3163 + + + 449.000000 + TP3164 + + + 449.000000 + TP3165 + + + 449.000000 + TP3166 + + + 449.000000 + TP3167 + + + 449.000000 + TP3168 + + + 449.000000 + TP3169 + + + 449.000000 + TP3170 + + + 449.000000 + TP3171 + + + 449.000000 + TP3172 + + + 449.000000 + TP3173 + + + 449.000000 + TP3174 + + + 449.000000 + TP3175 + + + 449.000000 + TP3176 + + + 449.000000 + TP3177 + + + 449.000000 + TP3178 + + + 449.000000 + TP3179 + + + 449.000000 + TP3180 + + + 449.000000 + TP3181 + + + 449.000000 + TP3182 + + + 449.000000 + TP3183 + + + 449.000000 + TP3184 + + + 449.000000 + TP3185 + + + 449.000000 + TP3186 + + + 449.000000 + TP3187 + + + 449.000000 + TP3188 + + + 449.000000 + TP3189 + + + 449.000000 + TP3190 + + + 449.000000 + TP3191 + + + 449.000000 + TP3192 + + + 449.000000 + TP3193 + + + 449.000000 + TP3194 + + + 449.000000 + TP3195 + + + 449.000000 + TP3196 + + + 449.000000 + TP3197 + + + 449.000000 + TP3198 + + + 449.000000 + TP3199 + + + 449.000000 + TP3200 + + + 449.000000 + TP3201 + + + 449.000000 + TP3202 + + + 449.000000 + TP3203 + + + 449.000000 + TP3204 + + + 449.000000 + TP3205 + + + 449.000000 + TP3206 + + + 449.000000 + TP3207 + + + 449.000000 + TP3208 + + + 449.000000 + TP3209 + + + 449.000000 + TP3210 + + + 449.000000 + TP3211 + + + 449.000000 + TP3212 + + + 449.000000 + TP3213 + + + 449.000000 + TP3214 + + + 449.000000 + TP3215 + + + 449.000000 + TP3216 + + + 449.000000 + TP3217 + + + 449.000000 + TP3218 + + + 449.000000 + TP3219 + + + 449.000000 + TP3220 + + + 449.000000 + TP3221 + + + 449.000000 + TP3222 + + + 449.000000 + TP3223 + + + 449.000000 + TP3224 + + + 449.000000 + TP3225 + + + 449.000000 + TP3226 + + + 449.000000 + TP3227 + + + 449.000000 + TP3228 + + + 449.000000 + TP3229 + + + 449.000000 + TP3230 + + + 449.000000 + TP3231 + + + 449.000000 + TP3232 + + + 449.000000 + TP3233 + + + 449.000000 + TP3234 + + + 449.000000 + TP3235 + + + 449.000000 + TP3236 + + + 449.000000 + TP3237 + + + 449.000000 + TP3238 + + + 449.000000 + TP3239 + + + 449.000000 + TP3240 + + + 449.000000 + TP3241 + + + 449.000000 + TP3242 + + + 449.000000 + TP3243 + + + 449.000000 + TP3244 + + + 449.000000 + TP3245 + + + 449.000000 + TP3246 + + + 449.000000 + TP3247 + + + 449.000000 + TP3248 + + + 449.000000 + TP3249 + + + 449.000000 + TP3250 + + + 449.000000 + TP3251 + + + 449.000000 + TP3252 + + + 449.000000 + TP3253 + + + 449.000000 + TP3254 + + + 449.000000 + TP3255 + + + 449.000000 + TP3256 + + + 449.000000 + TP3257 + + + 449.000000 + TP3258 + + + 449.000000 + TP3259 + + + 449.000000 + TP3260 + + + 449.000000 + TP3261 + + + 449.000000 + TP3262 + + + 449.000000 + TP3263 + + + 449.000000 + TP3264 + + + 449.000000 + TP3265 + + + 449.000000 + TP3266 + + + 449.000000 + TP3267 + + + 449.000000 + TP3268 + + + 449.000000 + TP3269 + + + 449.000000 + TP3270 + + + 449.000000 + TP3271 + + + 449.000000 + TP3272 + + + 449.000000 + TP3273 + + + 449.000000 + TP3274 + + + 449.000000 + TP3275 + + + 449.000000 + TP3276 + + + 449.000000 + TP3277 + + + 449.000000 + TP3278 + + + 449.000000 + TP3279 + + + 449.000000 + TP3280 + + + 449.000000 + TP3281 + + + 449.000000 + TP3282 + + + 449.000000 + TP3283 + + + 449.000000 + TP3284 + + + 449.000000 + TP3285 + + + 449.000000 + TP3286 + + + 449.000000 + TP3287 + + + 449.000000 + TP3288 + + + 449.000000 + TP3289 + + + 449.000000 + TP3290 + + + 449.000000 + TP3291 + + + 449.000000 + TP3292 + + + 449.000000 + TP3293 + + + 449.000000 + TP3294 + + + 449.000000 + TP3295 + + + 449.000000 + TP3296 + + + 449.000000 + TP3297 + + + 449.000000 + TP3298 + + + 449.000000 + TP3299 + + + 449.000000 + TP3300 + + + 449.000000 + TP3301 + + + 449.000000 + TP3302 + + + 449.000000 + TP3303 + + + 449.000000 + TP3304 + + + 449.000000 + TP3305 + + + 449.000000 + TP3306 + + + 449.000000 + TP3307 + + + 449.000000 + TP3308 + + + 449.000000 + TP3309 + + + 449.000000 + TP3310 + + + 449.000000 + TP3311 + + + 449.000000 + TP3312 + + + 449.000000 + TP3313 + + + 449.000000 + TP3314 + + + 449.000000 + TP3315 + + + 450.000000 + TP3316 + + + 450.000000 + TP3317 + + + 450.000000 + TP3318 + + + 450.000000 + TP3319 + + + 450.000000 + TP3320 + + + 450.000000 + TP3321 + + + 450.000000 + TP3322 + + + 450.000000 + TP3323 + + + 450.000000 + TP3324 + + + 450.000000 + TP3325 + + + 450.000000 + TP3326 + + + 450.000000 + TP3327 + + + 450.000000 + TP3328 + + + 450.000000 + TP3329 + + + 450.000000 + TP3330 + + + 450.000000 + TP3331 + + + 450.000000 + TP3332 + + + 450.000000 + TP3333 + + + 450.000000 + TP3334 + + + 450.000000 + TP3335 + + + 450.000000 + TP3336 + + + 450.000000 + TP3337 + + + 450.000000 + TP3338 + + + 450.000000 + TP3339 + + + 450.000000 + TP3340 + + + 450.000000 + TP3341 + + + 450.000000 + TP3342 + + + 450.000000 + TP3343 + + + 450.000000 + TP3344 + + + 450.000000 + TP3345 + + + 450.000000 + TP3346 + + + 450.000000 + TP3347 + + + 450.000000 + TP3348 + + + 450.000000 + TP3349 + + + 450.000000 + TP3350 + + + 450.000000 + TP3351 + + + 450.000000 + TP3352 + + + 450.000000 + TP3353 + + + 450.000000 + TP3354 + + + 450.000000 + TP3355 + + + 450.000000 + TP3356 + + + 450.000000 + TP3357 + + + 450.000000 + TP3358 + + + 443.000000 + TP3359 + + + 443.000000 + TP3360 + + + 443.000000 + TP3361 + + + 443.000000 + TP3362 + + + 443.000000 + TP3363 + + + 443.000000 + TP3364 + + + 443.000000 + TP3365 + + + 443.000000 + TP3366 + + + 443.000000 + TP3367 + + + 443.000000 + TP3368 + + + 443.000000 + TP3369 + + + 443.000000 + TP3370 + + + 456.000000 + TP3371 + + + 456.000000 + TP3372 + + + 456.000000 + TP3373 + + + 456.000000 + TP3374 + + + 456.000000 + TP3375 + + + 456.000000 + TP3376 + + + 456.000000 + TP3377 + + + 456.000000 + TP3378 + + + 456.000000 + TP3379 + + + 456.000000 + TP3380 + + + 456.000000 + TP3381 + + + 456.000000 + TP3382 + + + 456.000000 + TP3383 + + + 456.000000 + TP3384 + + + 456.000000 + TP3385 + + + 456.000000 + TP3386 + + + 456.000000 + TP3387 + + + 456.000000 + TP3388 + + + 456.000000 + TP3389 + + + 456.000000 + TP3390 + + + 456.000000 + TP3391 + + + 456.000000 + TP3392 + + + 456.000000 + TP3393 + + + 456.000000 + TP3394 + + + 456.000000 + TP3395 + + + 456.000000 + TP3396 + + + 456.000000 + TP3397 + + + 456.000000 + TP3398 + + + 456.000000 + TP3399 + + + 456.000000 + TP3400 + + + 456.000000 + TP3401 + + + 456.000000 + TP3402 + + + 455.000000 + TP3403 + + + 455.000000 + TP3404 + + + 455.000000 + TP3405 + + + 455.000000 + TP3406 + + + 455.000000 + TP3407 + + + 455.000000 + TP3408 + + + 455.000000 + TP3409 + + + 455.000000 + TP3410 + + + 455.000000 + TP3411 + + + 455.000000 + TP3412 + + + 455.000000 + TP3413 + + + 455.000000 + TP3414 + + + 455.000000 + TP3415 + + + 455.000000 + TP3416 + + + 455.000000 + TP3417 + + + 455.000000 + TP3418 + + + 455.000000 + TP3419 + + + 455.000000 + TP3420 + + + 455.000000 + TP3421 + + + 455.000000 + TP3422 + + + 455.000000 + TP3423 + + + 455.000000 + TP3424 + + + 455.000000 + TP3425 + + + 455.000000 + TP3426 + + + 455.000000 + TP3427 + + + 455.000000 + TP3428 + + + 455.000000 + TP3429 + + + 455.000000 + TP3430 + + + 455.000000 + TP3431 + + + 455.000000 + TP3432 + + + 455.000000 + TP3433 + + + 456.000000 + TP3434 + + + 456.000000 + TP3435 + + + 456.000000 + TP3436 + + + 456.000000 + TP3437 + + + 456.000000 + TP3438 + + + 456.000000 + TP3439 + + + 456.000000 + TP3440 + + + 456.000000 + TP3441 + + + 456.000000 + TP3442 + + + 456.000000 + TP3443 + + + 456.000000 + TP3444 + + + 456.000000 + TP3445 + + + 456.000000 + TP3446 + + + 456.000000 + TP3447 + + + 456.000000 + TP3448 + + + 456.000000 + TP3449 + + + 456.000000 + TP3450 + + + 456.000000 + TP3451 + + + 456.000000 + TP3452 + + + 456.000000 + TP3453 + + + 456.000000 + TP3454 + + + 456.000000 + TP3455 + + + 456.000000 + TP3456 + + + 456.000000 + TP3457 + + + 456.000000 + TP3458 + + + 456.000000 + TP3459 + + + 456.000000 + TP3460 + + + 456.000000 + TP3461 + + + 456.000000 + TP3462 + + + 456.000000 + TP3463 + + + 456.000000 + TP3464 + + + 456.000000 + TP3465 + + + 456.000000 + TP3466 + + + 456.000000 + TP3467 + + + 456.000000 + TP3468 + + + 456.000000 + TP3469 + + + 456.000000 + TP3470 + + + 456.000000 + TP3471 + + + 456.000000 + TP3472 + + + 456.000000 + TP3473 + + + 456.000000 + TP3474 + + + 456.000000 + TP3475 + + + 456.000000 + TP3476 + + + 456.000000 + TP3477 + + + 456.000000 + TP3478 + + + 456.000000 + TP3479 + + + 456.000000 + TP3480 + + + 456.000000 + TP3481 + + + 456.000000 + TP3482 + + + 456.000000 + TP3483 + + + 456.000000 + TP3484 + + + 456.000000 + TP3485 + + + 456.000000 + TP3486 + + + 456.000000 + TP3487 + + + 456.000000 + TP3488 + + + 456.000000 + TP3489 + + + 456.000000 + TP3490 + + + 456.000000 + TP3491 + + + 456.000000 + TP3492 + + + 456.000000 + TP3493 + + + 456.000000 + TP3494 + + + 456.000000 + TP3495 + + + 456.000000 + TP3496 + + + 456.000000 + TP3497 + + + 456.000000 + TP3498 + + + 456.000000 + TP3499 + + + 456.000000 + TP3500 + + + 456.000000 + TP3501 + + + 456.000000 + TP3502 + + + 456.000000 + TP3503 + + + 456.000000 + TP3504 + + + 456.000000 + TP3505 + + + 456.000000 + TP3506 + + + 456.000000 + TP3507 + + + 456.000000 + TP3508 + + + 456.000000 + TP3509 + + + 456.000000 + TP3510 + + + 456.000000 + TP3511 + + + 456.000000 + TP3512 + + + 456.000000 + TP3513 + + + 456.000000 + TP3514 + + + 456.000000 + TP3515 + + + 456.000000 + TP3516 + + + 456.000000 + TP3517 + + + 456.000000 + TP3518 + + + 456.000000 + TP3519 + + + 456.000000 + TP3520 + + + 456.000000 + TP3521 + + + 456.000000 + TP3522 + + + 456.000000 + TP3523 + + + 456.000000 + TP3524 + + + 456.000000 + TP3525 + + + 456.000000 + TP3526 + + + 456.000000 + TP3527 + + + 456.000000 + TP3528 + + + 456.000000 + TP3529 + + + 456.000000 + TP3530 + + + 456.000000 + TP3531 + + + 456.000000 + TP3532 + + + 456.000000 + TP3533 + + + 456.000000 + TP3534 + + + 456.000000 + TP3535 + + + 456.000000 + TP3536 + + + 456.000000 + TP3537 + + + 456.000000 + TP3538 + + + 456.000000 + TP3539 + + + 456.000000 + TP3540 + + + 456.000000 + TP3541 + + + 456.000000 + TP3542 + + + 456.000000 + TP3543 + + + 456.000000 + TP3544 + + + 456.000000 + TP3545 + + + 456.000000 + TP3546 + + + 456.000000 + TP3547 + + + 456.000000 + TP3548 + + + 456.000000 + TP3549 + + + 456.000000 + TP3550 + + + 456.000000 + TP3551 + + + 456.000000 + TP3552 + + + 456.000000 + TP3553 + + + 456.000000 + TP3554 + + + 456.000000 + TP3555 + + + 456.000000 + TP3556 + + + 456.000000 + TP3557 + + + 456.000000 + TP3558 + + + 456.000000 + TP3559 + + + 456.000000 + TP3560 + + + 456.000000 + TP3561 + + + 456.000000 + TP3562 + + + 456.000000 + TP3563 + + + 456.000000 + TP3564 + + + 456.000000 + TP3565 + + + 456.000000 + TP3566 + + + 456.000000 + TP3567 + + + 456.000000 + TP3568 + + + 456.000000 + TP3569 + + + 456.000000 + TP3570 + + + 456.000000 + TP3571 + + + 456.000000 + TP3572 + + + 456.000000 + TP3573 + + + 456.000000 + TP3574 + + + 456.000000 + TP3575 + + + 456.000000 + TP3576 + + + 456.000000 + TP3577 + + + 456.000000 + TP3578 + + + 456.000000 + TP3579 + + + 456.000000 + TP3580 + + + 456.000000 + TP3581 + + + 456.000000 + TP3582 + + + 456.000000 + TP3583 + + + 456.000000 + TP3584 + + + 456.000000 + TP3585 + + + 456.000000 + TP3586 + + + 456.000000 + TP3587 + + + 456.000000 + TP3588 + + + 456.000000 + TP3589 + + + 456.000000 + TP3590 + + + 456.000000 + TP3591 + + + 456.000000 + TP3592 + + + 456.000000 + TP3593 + + + 456.000000 + TP3594 + + + 456.000000 + TP3595 + + + 456.000000 + TP3596 + + + 456.000000 + TP3597 + + + 456.000000 + TP3598 + + + 456.000000 + TP3599 + + + 456.000000 + TP3600 + + + 456.000000 + TP3601 + + + 456.000000 + TP3602 + + + 456.000000 + TP3603 + + + 456.000000 + TP3604 + + + 456.000000 + TP3605 + + + 456.000000 + TP3606 + + + 456.000000 + TP3607 + + + 456.000000 + TP3608 + + + 456.000000 + TP3609 + + + 456.000000 + TP3610 + + + 456.000000 + TP3611 + + + 456.000000 + TP3612 + + + 456.000000 + TP3613 + + + 456.000000 + TP3614 + + + 456.000000 + TP3615 + + + 456.000000 + TP3616 + + + 456.000000 + TP3617 + + + 456.000000 + TP3618 + + + 456.000000 + TP3619 + + + 456.000000 + TP3620 + + + 456.000000 + TP3621 + + + 456.000000 + TP3622 + + + 456.000000 + TP3623 + + + 456.000000 + TP3624 + + + 456.000000 + TP3625 + + + 456.000000 + TP3626 + + + 456.000000 + TP3627 + + + 456.000000 + TP3628 + + + 456.000000 + TP3629 + + + 456.000000 + TP3630 + + + 456.000000 + TP3631 + + + 456.000000 + TP3632 + + + 456.000000 + TP3633 + + + 456.000000 + TP3634 + + + 456.000000 + TP3635 + + + 456.000000 + TP3636 + + + 456.000000 + TP3637 + + + 456.000000 + TP3638 + + + 456.000000 + TP3639 + + + 456.000000 + TP3640 + + + 456.000000 + TP3641 + + + 456.000000 + TP3642 + + + 456.000000 + TP3643 + + + 456.000000 + TP3644 + + + 456.000000 + TP3645 + + + 456.000000 + TP3646 + + + 456.000000 + TP3647 + + + 456.000000 + TP3648 + + + 456.000000 + TP3649 + + + 456.000000 + TP3650 + + + 456.000000 + TP3651 + + + 456.000000 + TP3652 + + + 456.000000 + TP3653 + + + 456.000000 + TP3654 + + + 456.000000 + TP3655 + + + 456.000000 + TP3656 + + + 456.000000 + TP3657 + + + 456.000000 + TP3658 + + + 456.000000 + TP3659 + + + 456.000000 + TP3660 + + + 456.000000 + TP3661 + + + 456.000000 + TP3662 + + + 456.000000 + TP3663 + + + 456.000000 + TP3664 + + + 456.000000 + TP3665 + + + 456.000000 + TP3666 + + + 456.000000 + TP3667 + + + 456.000000 + TP3668 + + + 456.000000 + TP3669 + + + 456.000000 + TP3670 + + + 456.000000 + TP3671 + + + 456.000000 + TP3672 + + + 456.000000 + TP3673 + + + 456.000000 + TP3674 + + + 456.000000 + TP3675 + + + 456.000000 + TP3676 + + + 456.000000 + TP3677 + + + 456.000000 + TP3678 + + + 456.000000 + TP3679 + + + 456.000000 + TP3680 + + + 456.000000 + TP3681 + + + 456.000000 + TP3682 + + + 456.000000 + TP3683 + + + 456.000000 + TP3684 + + + 456.000000 + TP3685 + + + 456.000000 + TP3686 + + + 456.000000 + TP3687 + + + 456.000000 + TP3688 + + + 456.000000 + TP3689 + + + 456.000000 + TP3690 + + + 456.000000 + TP3691 + + + 456.000000 + TP3692 + + + 456.000000 + TP3693 + + + 456.000000 + TP3694 + + + 456.000000 + TP3695 + + + 456.000000 + TP3696 + + + 456.000000 + TP3697 + + + 456.000000 + TP3698 + + + 456.000000 + TP3699 + + + 456.000000 + TP3700 + + + 456.000000 + TP3701 + + + 456.000000 + TP3702 + + + 456.000000 + TP3703 + + + 456.000000 + TP3704 + + + 456.000000 + TP3705 + + + 456.000000 + TP3706 + + + 456.000000 + TP3707 + + + 456.000000 + TP3708 + + + 456.000000 + TP3709 + + + 456.000000 + TP3710 + + + 456.000000 + TP3711 + + + 456.000000 + TP3712 + + + 456.000000 + TP3713 + + + 456.000000 + TP3714 + + + 456.000000 + TP3715 + + + 456.000000 + TP3716 + + + 456.000000 + TP3717 + + + 456.000000 + TP3718 + + + 456.000000 + TP3719 + + + 456.000000 + TP3720 + + + 456.000000 + TP3721 + + + 456.000000 + TP3722 + + + 456.000000 + TP3723 + + + 456.000000 + TP3724 + + + 456.000000 + TP3725 + + + 456.000000 + TP3726 + + + 456.000000 + TP3727 + + + 456.000000 + TP3728 + + + 456.000000 + TP3729 + + + 456.000000 + TP3730 + + + 456.000000 + TP3731 + + + 456.000000 + TP3732 + + + 456.000000 + TP3733 + + + 456.000000 + TP3734 + + + 456.000000 + TP3735 + + + 456.000000 + TP3736 + + + 456.000000 + TP3737 + + + 456.000000 + TP3738 + + + 456.000000 + TP3739 + + + 456.000000 + TP3740 + + + 456.000000 + TP3741 + + + 456.000000 + TP3742 + + + 456.000000 + TP3743 + + + 456.000000 + TP3744 + + + 456.000000 + TP3745 + + + 456.000000 + TP3746 + + + 456.000000 + TP3747 + + + 456.000000 + TP3748 + + + 456.000000 + TP3749 + + + 456.000000 + TP3750 + + + 456.000000 + TP3751 + + + 456.000000 + TP3752 + + + 456.000000 + TP3753 + + + 456.000000 + TP3754 + + + 456.000000 + TP3755 + + + 456.000000 + TP3756 + + + 456.000000 + TP3757 + + + 456.000000 + TP3758 + + + 456.000000 + TP3759 + + + 456.000000 + TP3760 + + + 456.000000 + TP3761 + + + 456.000000 + TP3762 + + + 456.000000 + TP3763 + + + 456.000000 + TP3764 + + + 456.000000 + TP3765 + + + 456.000000 + TP3766 + + + 456.000000 + TP3767 + + + 456.000000 + TP3768 + + + 456.000000 + TP3769 + + + 456.000000 + TP3770 + + + 456.000000 + TP3771 + + + 456.000000 + TP3772 + + + 456.000000 + TP3773 + + + 456.000000 + TP3774 + + + 456.000000 + TP3775 + + + 456.000000 + TP3776 + + + 456.000000 + TP3777 + + + 456.000000 + TP3778 + + + 456.000000 + TP3779 + + + 456.000000 + TP3780 + + + 456.000000 + TP3781 + + + 456.000000 + TP3782 + + + 456.000000 + TP3783 + + + 456.000000 + TP3784 + + + 456.000000 + TP3785 + + + 456.000000 + TP3786 + + + 456.000000 + TP3787 + + + 456.000000 + TP3788 + + + 456.000000 + TP3789 + + + 456.000000 + TP3790 + + + 456.000000 + TP3791 + + + 456.000000 + TP3792 + + + 456.000000 + TP3793 + + + 456.000000 + TP3794 + + + 456.000000 + TP3795 + + + 456.000000 + TP3796 + + + 456.000000 + TP3797 + + + 456.000000 + TP3798 + + + 456.000000 + TP3799 + + + 456.000000 + TP3800 + + + 456.000000 + TP3801 + + + 456.000000 + TP3802 + + + 456.000000 + TP3803 + + + 456.000000 + TP3804 + + + 456.000000 + TP3805 + + + 456.000000 + TP3806 + + + 456.000000 + TP3807 + + + 456.000000 + TP3808 + + + 456.000000 + TP3809 + + + 456.000000 + TP3810 + + + 456.000000 + TP3811 + + + 456.000000 + TP3812 + + + 456.000000 + TP3813 + + + 456.000000 + TP3814 + + + 456.000000 + TP3815 + + + 456.000000 + TP3816 + + + 456.000000 + TP3817 + + + 456.000000 + TP3818 + + + 456.000000 + TP3819 + + + 456.000000 + TP3820 + + + 456.000000 + TP3821 + + + 456.000000 + TP3822 + + + 456.000000 + TP3823 + + + 456.000000 + TP3824 + + + 456.000000 + TP3825 + + + 456.000000 + TP3826 + + + 456.000000 + TP3827 + + + 456.000000 + TP3828 + + + 456.000000 + TP3829 + + + 456.000000 + TP3830 + + + 456.000000 + TP3831 + + + 456.000000 + TP3832 + + + 456.000000 + TP3833 + + + 456.000000 + TP3834 + + + 456.000000 + TP3835 + + + 456.000000 + TP3836 + + + 456.000000 + TP3837 + + + 456.000000 + TP3838 + + + 456.000000 + TP3839 + + + 456.000000 + TP3840 + + + 456.000000 + TP3841 + + + 456.000000 + TP3842 + + + 456.000000 + TP3843 + + + 456.000000 + TP3844 + + + 456.000000 + TP3845 + + + 456.000000 + TP3846 + + + 456.000000 + TP3847 + + + 456.000000 + TP3848 + + + 456.000000 + TP3849 + + + 456.000000 + TP3850 + + + 456.000000 + TP3851 + + + 456.000000 + TP3852 + + + 456.000000 + TP3853 + + + 456.000000 + TP3854 + + + 456.000000 + TP3855 + + + 456.000000 + TP3856 + + + 456.000000 + TP3857 + + + 456.000000 + TP3858 + + + 456.000000 + TP3859 + + + 456.000000 + TP3860 + + + 456.000000 + TP3861 + + + 456.000000 + TP3862 + + + 456.000000 + TP3863 + + + 456.000000 + TP3864 + + + 456.000000 + TP3865 + + + 456.000000 + TP3866 + + + 456.000000 + TP3867 + + + 456.000000 + TP3868 + + + 456.000000 + TP3869 + + + 456.000000 + TP3870 + + + 456.000000 + TP3871 + + + 456.000000 + TP3872 + + + 456.000000 + TP3873 + + + 456.000000 + TP3874 + + + 456.000000 + TP3875 + + + 456.000000 + TP3876 + + + 456.000000 + TP3877 + + + 456.000000 + TP3878 + + + 456.000000 + TP3879 + + + 456.000000 + TP3880 + + + 456.000000 + TP3881 + + + 456.000000 + TP3882 + + + 456.000000 + TP3883 + + + 456.000000 + TP3884 + + + 456.000000 + TP3885 + + + 456.000000 + TP3886 + + + 456.000000 + TP3887 + + + 456.000000 + TP3888 + + + 456.000000 + TP3889 + + + 456.000000 + TP3890 + + + 456.000000 + TP3891 + + + 456.000000 + TP3892 + + + 456.000000 + TP3893 + + + 456.000000 + TP3894 + + + 456.000000 + TP3895 + + + 456.000000 + TP3896 + + + 456.000000 + TP3897 + + + 456.000000 + TP3898 + + + 456.000000 + TP3899 + + + 456.000000 + TP3900 + + + 456.000000 + TP3901 + + + 456.000000 + TP3902 + + + 456.000000 + TP3903 + + + 456.000000 + TP3904 + + + 456.000000 + TP3905 + + + 456.000000 + TP3906 + + + 456.000000 + TP3907 + + + 456.000000 + TP3908 + + + 456.000000 + TP3909 + + + 456.000000 + TP3910 + + + 456.000000 + TP3911 + + + 456.000000 + TP3912 + + + 456.000000 + TP3913 + + + 456.000000 + TP3914 + + + 456.000000 + TP3915 + + + 456.000000 + TP3916 + + + 456.000000 + TP3917 + + + 456.000000 + TP3918 + + + 456.000000 + TP3919 + + + 456.000000 + TP3920 + + + 456.000000 + TP3921 + + + 456.000000 + TP3922 + + + 456.000000 + TP3923 + + + 456.000000 + TP3924 + + + 456.000000 + TP3925 + + + 456.000000 + TP3926 + + + 456.000000 + TP3927 + + + 456.000000 + TP3928 + + + 456.000000 + TP3929 + + + 456.000000 + TP3930 + + + 456.000000 + TP3931 + + + 456.000000 + TP3932 + + + 456.000000 + TP3933 + + + 456.000000 + TP3934 + + + 456.000000 + TP3935 + + + 456.000000 + TP3936 + + + 456.000000 + TP3937 + + + 456.000000 + TP3938 + + + 457.000000 + TP3939 + + + 457.000000 + TP3940 + + + 456.000000 + TP3941 + + + 456.000000 + TP3942 + + + 457.000000 + TP3943 + + + 457.000000 + TP3944 + + + 457.000000 + TP3945 + + + 457.000000 + TP3946 + + + 457.000000 + TP3947 + + + 457.000000 + TP3948 + + + 457.000000 + TP3949 + + + 457.000000 + TP3950 + + + 457.000000 + TP3951 + + + 457.000000 + TP3952 + + + 457.000000 + TP3953 + + + 457.000000 + TP3954 + + + 457.000000 + TP3955 + + + 456.000000 + TP3956 + + + 457.000000 + TP3957 + + + 458.000000 + TP3958 + + + 458.000000 + TP3959 + + + 458.000000 + TP3960 + + + 457.000000 + TP3961 + + + 456.000000 + TP3962 + + + 456.000000 + TP3963 + + + 456.000000 + TP3964 + + + 456.000000 + TP3965 + + + 456.000000 + TP3966 + + + 456.000000 + TP3967 + + + 456.000000 + TP3968 + + + 456.000000 + TP3969 + + + 456.000000 + TP3970 + + + 456.000000 + TP3971 + + + 456.000000 + TP3972 + + + 456.000000 + TP3973 + + + 456.000000 + TP3974 + + + 456.000000 + TP3975 + + + 456.000000 + TP3976 + + + 456.000000 + TP3977 + + + 456.000000 + TP3978 + + + 456.000000 + TP3979 + + + 456.000000 + TP3980 + + + 456.000000 + TP3981 + + + 456.000000 + TP3982 + + + 456.000000 + TP3983 + + + 456.000000 + TP3984 + + + 456.000000 + TP3985 + + + 456.000000 + TP3986 + + + 456.000000 + TP3987 + + + 456.000000 + TP3988 + + + 456.000000 + TP3989 + + + 456.000000 + TP3990 + + + 456.000000 + TP3991 + + + 456.000000 + TP3992 + + + 456.000000 + TP3993 + + + 456.000000 + TP3994 + + + 456.000000 + TP3995 + + + 456.000000 + TP3996 + + + 456.000000 + TP3997 + + + 456.000000 + TP3998 + + + 456.000000 + TP3999 + + + 456.000000 + TP4000 + + + 456.000000 + TP4001 + + + 456.000000 + TP4002 + + + 456.000000 + TP4003 + + + 456.000000 + TP4004 + + + 456.000000 + TP4005 + + + 456.000000 + TP4006 + + + 456.000000 + TP4007 + + + 456.000000 + TP4008 + + + 456.000000 + TP4009 + + + 456.000000 + TP4010 + + + 456.000000 + TP4011 + + + 456.000000 + TP4012 + + + 456.000000 + TP4013 + + + 456.000000 + TP4014 + + + 456.000000 + TP4015 + + + 456.000000 + TP4016 + + + 456.000000 + TP4017 + + + 456.000000 + TP4018 + + + 456.000000 + TP4019 + + + 456.000000 + TP4020 + + + 456.000000 + TP4021 + + + 456.000000 + TP4022 + + + 456.000000 + TP4023 + + + + diff --git a/reference/wbt-201.tk1 b/reference/wbt-201.tk1 new file mode 100644 index 0000000000000000000000000000000000000000..c1bc918aff7a6315d5c34cd22b3f1b3489e3cf08 GIT binary patch literal 65512 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 S`CqepYvPWne|)7$`~L@ZsCW+m literal 0 HcmV?d00001 diff --git a/reference/wfff.gpu b/reference/wfff.gpu new file mode 100644 index 000000000..dec2b1836 --- /dev/null +++ b/reference/wfff.gpu @@ -0,0 +1 @@ +WitoldM 4529.388N 07541.190W 0000000m 001217AD3124/AP/WEP On/Ch 11/- a diff --git a/reference/wfff.xml b/reference/wfff.xml new file mode 100644 index 000000000..fc70b56d2 --- /dev/null +++ b/reference/wfff.xml @@ -0,0 +1,17 @@ + + + On + 001217AD3124 + WitoldM + AP + 0 + -77 + -85 + 11 + 2006-03-11T09:07:46-05:00 + 2006-03-11T09:07:52-05:00 + 14.2 + 45.489801666666672 + -75.686505 + + diff --git a/reference/xmap b/reference/xmap new file mode 100644 index 000000000..b5911f218 --- /dev/null +++ b/reference/xmap @@ -0,0 +1,4 @@ +BEGIN SYMBOL +36.04768, -86.87918, Tennessee Scavenger Hunt Cache +35.95765, -86.67185, Stonebrook-Greystone +END diff --git a/reference/xmapwpt.wpt b/reference/xmapwpt.wpt new file mode 100644 index 000000000..48885aad5 --- /dev/null +++ b/reference/xmapwpt.wpt @@ -0,0 +1,9 @@ +1296126539:1481466224:1845728360:1416544806:3137157:GCEBB::Mountain Bike Heaven by susy1313 +1296126539:1481466224:1844733052:1420362881:3137157:GC1A37::The Troll by a182pilot & Family +1296126539:1481466224:1845525076:1420861444:3137157:GC1C2B::Dive Bomber by JoGPS & family +1296126539:1481466224:1845170937:1420622369:3137157:GC25A9::FOSTER by JoGPS & Family +1296126539:1481466224:1844552696:1419840970:3137157:GC2723::Logan Lighthouse by JoGps & Family +1296126539:1481466224:1844956189:1419432025:3137157:GC2B71::Ganier Cache by Susy1313 +1296126539:1481466224:1844757518:1419270824:3137157:GC309F::Shy's Hill by FireFighterEng33 +1296126539:1481466224:1845011414:1418580721:3137157:GC317A::GittyUp by JoGPS / Warner Parks +1296126539:1481466224:1844799182:1418788060:3137157:GC317D::Inlighting by JoGPS / Warner Parks diff --git a/reference/xol-sample-gpx.xol b/reference/xol-sample-gpx.xol new file mode 100644 index 000000000..098820d78 --- /dev/null +++ b/reference/xol-sample-gpx.xol @@ -0,0 +1,182 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/xol-sample.gpx b/reference/xol-sample.gpx new file mode 100644 index 000000000..231908278 --- /dev/null +++ b/reference/xol-sample.gpx @@ -0,0 +1,167 @@ + + + + + + 002 + 002 + 002 + Waypoint + + + 012 + 012 + 012 + Waypoint + + + 015 + 015 + 015 + Waypoint + + + 017 + 017 + 017 + Waypoint + + + 019 + 019 + 019 + Waypoint + + + 020 + 020 + 020 + Waypoint + + + 021 + 021 + 021 + Waypoint + + + 041 + 041 + 041 + Waypoint + + + 044 + 044 + 044 + Waypoint + + + 047 + 047 + 047 + Waypoint + + + 056 + 056 + 056 + Waypoint + + + 060 + 060 + 060 + Waypoint + + + 062 + 062 + 062 + Waypoint + + + 065 + 065 + 065 + Waypoint + + + 068 + 068 + 068 + Waypoint + + + 073 + 073 + 073 + Waypoint + + + 074 + 074 + 074 + Waypoint + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/xol-sample.xol b/reference/xol-sample.xol new file mode 100644 index 000000000..4f81d9beb --- /dev/null +++ b/reference/xol-sample.xol @@ -0,0 +1,182 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reverse_route.c b/reverse_route.c new file mode 100644 index 000000000..5636cf6fa --- /dev/null +++ b/reverse_route.c @@ -0,0 +1,70 @@ +/* + Route reversal filter. + + Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED + +#define MYNAME "Route reversal filter" + +static +arglist_t reverse_route_args[] = { + ARG_TERMINATOR +}; + +void +reverse_route_head( const route_head *rte ) +{ + route_reverse(rte); +} + +void +reverse_route_process( void ) +{ + route_disp_all( reverse_route_head, NULL, NULL ); +} + +void +reverse_route_init(const char *args) +{ + switch (global_opts.objective) { + case rtedata: break; + case trkdata: break; + default: + fatal(MYNAME ": This filter only works in track " + "or route (-t or -r) mode.\n"); + } +} + +void +reverse_route_deinit(void) +{ + /* do nothing */ +} + +filter_vecs_t reverse_route_vecs = { + reverse_route_init, + reverse_route_process, + reverse_route_deinit, + NULL, + reverse_route_args +}; +#endif diff --git a/rgbcolors.c b/rgbcolors.c new file mode 100644 index 000000000..bfbe0f035 --- /dev/null +++ b/rgbcolors.c @@ -0,0 +1,248 @@ +/* + Color utilities. + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +/* + * Colors derived from http://www.w3.org/TR/SVG/types.html#ColorKeywords + * which is also referenced in the CSS3 spec from w3.org as being the + * same colors supported by X11. + */ + +static struct { + char *cn; + unsigned char r; + unsigned char g; + unsigned char b; +} color_table[] = { + {"aliceblue", 240, 248, 255}, + {"antiquewhite", 250, 235, 215}, + {"aqua", 0, 255, 255}, + {"aquamarine", 127, 255, 212}, + {"azure", 240, 255, 255}, + {"beige", 245, 245, 220}, + {"bisque", 255, 228, 196}, + {"black", 0, 0, 0}, + {"blanchedalmond", 255, 235, 205}, + {"blue", 0, 0, 255}, + {"blueviolet", 138, 43, 226}, + {"brown", 165, 42, 42}, + {"burlywood", 222, 184, 135}, + {"cadetblue", 95, 158, 160}, + {"chartreuse", 127, 255, 0}, + {"chocolate", 210, 105, 30}, + {"coral", 255, 127, 80}, + {"cornflowerblue", 100, 149, 237}, + {"cornsilk", 255, 248, 220}, + {"crimson", 220, 20, 60}, + {"cyan", 0, 255, 255}, + {"darkblue", 0, 0, 139}, + {"darkcyan", 0, 139, 139}, + {"darkgoldenrod", 184, 134, 11}, + {"darkgray", 169, 169, 169}, + {"darkgreen", 0, 100, 0}, + {"darkgrey", 169, 169, 169}, + {"darkkhaki", 189, 183, 107}, + {"darkmagenta", 139, 0, 139}, + {"darkolivegreen", 85, 107, 47}, + {"darkorange", 255, 140, 0}, + {"darkorchid", 153, 50, 204}, + {"darkred", 139, 0, 0}, + {"darksalmon", 233, 150, 122}, + {"darkseagreen", 143, 188, 143}, + {"darkslateblue", 72, 61, 139}, + {"darkslategray", 47, 79, 79}, + {"darkslategrey", 47, 79, 79}, + {"darkturquoise", 0, 206, 209}, + {"darkviolet", 148, 0, 211}, + {"deeppink", 255, 20, 147}, + {"deepskyblue", 0, 191, 255}, + {"dimgray", 105, 105, 105}, + {"dimgrey", 105, 105, 105}, + {"dodgerblue", 30, 144, 255}, + {"firebrick", 178, 34, 34}, + {"floralwhite", 255, 250, 240}, + {"forestgreen", 34, 139, 34}, + {"fuchsia", 255, 0, 255}, + {"gainsboro", 220, 220, 220}, + {"ghostwhite", 248, 248, 255}, + {"gold", 255, 215, 0}, + {"goldenrod", 218, 165, 32}, + {"gray", 128, 128, 128}, + {"grey", 128, 128, 128}, + {"green", 0, 128, 0}, + {"greenyellow", 173, 255, 47}, + {"honeydew", 240, 255, 240}, + {"hotpink", 255, 105, 180}, + {"indianred", 205, 92, 92}, + {"indigo", 75, 0, 130}, + {"ivory", 255, 255, 240}, + {"khaki", 240, 230, 140}, + {"lavender", 230, 230, 250}, + {"lavenderblush", 255, 240, 245}, + {"lawngreen", 124, 252, 0}, + {"lemonchiffon", 255, 250, 205}, + {"lightblue", 173, 216, 230}, + {"lightcoral", 240, 128, 128}, + {"lightcyan", 224, 255, 255}, + {"lightgoldenrodyellow", 250, 250, 210}, + {"lightgray", 211, 211, 211}, + {"lightgreen", 144, 238, 144}, + {"lightgrey", 211, 211, 211}, + {"lightpink", 255, 182, 193}, + {"lightsalmon", 255, 160, 122}, + {"lightseagreen", 32, 178, 170}, + {"lightskyblue", 135, 206, 250}, + {"lightslategray", 119, 136, 153}, + {"lightslategrey", 119, 136, 153}, + {"lightsteelblue", 176, 196, 222}, + {"lightyellow", 255, 255, 224}, + {"lime", 0, 255, 0}, + {"limegreen", 50, 205, 50}, + {"linen", 250, 240, 230}, + {"magenta", 255, 0, 255}, + {"maroon", 128, 0, 0}, + {"mediumaquamarine", 102, 205, 170}, + {"mediumblue", 0, 0, 205}, + {"mediumorchid", 186, 85, 211}, + {"mediumpurple", 147, 112, 219}, + {"mediumseagreen", 60, 179, 113}, + {"mediumslateblue", 123, 104, 238}, + {"mediumspringgreen", 0, 250, 154}, + {"mediumturquoise", 72, 209, 204}, + {"mediumvioletred", 199, 21, 133}, + {"midnightblue", 25, 25, 112}, + {"mintcream", 245, 255, 250}, + {"mistyrose", 255, 228, 225}, + {"moccasin", 255, 228, 181}, + {"navajowhite", 255, 222, 173}, + {"navy", 0, 0, 128}, + {"oldlace", 253, 245, 230}, + {"olive", 128, 128, 0}, + {"olivedrab", 107, 142, 35}, + {"orange", 255, 165, 0}, + {"orangered", 255, 69, 0}, + {"orchid", 218, 112, 214}, + {"palegoldenrod", 238, 232, 170}, + {"palegreen", 152, 251, 152}, + {"paleturquoise", 175, 238, 238}, + {"palevioletred", 219, 112, 147}, + {"papayawhip", 255, 239, 213}, + {"peachpuff", 255, 218, 185}, + {"peru", 205, 133, 63}, + {"pink", 255, 192, 203}, + {"plum", 221, 160, 221}, + {"powderblue", 176, 224, 230}, + {"purple", 128, 0, 128}, + {"red", 255, 0, 0}, + {"rosybrown", 188, 143, 143}, + {"royalblue", 65, 105, 225}, + {"saddlebrown", 139, 69, 19}, + {"salmon", 250, 128, 114}, + {"sandybrown", 244, 164, 96}, + {"seagreen", 46, 139, 87}, + {"seashell", 255, 245, 238}, + {"sienna", 160, 82, 45}, + {"silver", 192, 192, 192}, + {"skyblue", 135, 206, 235}, + {"slateblue", 106, 90, 205}, + {"slategray", 112, 128, 144}, + {"slategrey", 112, 128, 144}, + {"snow", 255, 250, 250}, + {"springgreen", 0, 255, 127}, + {"steelblue", 70, 130, 180}, + {"tan", 210, 180, 140}, + {"teal", 0, 128, 128}, + {"thistle", 216, 191, 216}, + {"tomato", 255, 99, 71}, + {"turquoise", 64, 224, 208}, + {"violet", 238, 130, 238}, + {"wheat", 245, 222, 179}, + {"white", 255, 255, 255}, + {"whitesmoke", 245, 245, 245}, + {"yellow", 255, 255, 0}, + {"yellowgreen", 154, 205, 50}, +}; + + +/* + * Functions for converting human-readable colors to BBGGRR value. + * Substantial optimization opportunities remain. + */ +static int HexDigit( char hex ) { + const char *Digits = "0123456789ABCDEF"; + const char *digits = "0123456789abcdef"; + char * ofs = strchr( digits, hex ); + if ( ofs ) { + return ofs-digits; + } + + ofs = strchr( Digits, hex ); + if ( ofs ) { + return ofs-Digits; + } + return 0; +} + +static int HexByte( char* hex ) { + int b = (HexDigit(hex[0])<<4)+HexDigit(hex[1]); + return b; +} + +/* + * Given an input of the form: + * # + * + * + * return the BBGGRR value for it. + */ + +int +color_to_bbggrr( char *opt_color ) +{ + int color_num; + unsigned int i; + char *ep; + + color_num = strtol(opt_color, &ep, 10); + + if (ep != opt_color) { + return color_num; + } + + if ( opt_color[0] == '#' ) { + color_num = (HexByte( opt_color+1 )) + // red + (HexByte( opt_color+3 )<<8) + // green + (HexByte( opt_color+5 )<<16); // blue + return color_num; + } + + for (i = 0; i < sizeof(color_table) / sizeof(color_table[0]); i++) { + if (0 == case_ignore_strcmp(opt_color, color_table[i].cn)) { + return (color_table[i].b << 16) + + (color_table[i].g << 8) + + color_table[i].r; + } + } + + fatal( "unrecognized color name %s\n", opt_color ); + return -1; +} diff --git a/route.c b/route.c new file mode 100644 index 000000000..2bbb6f90b --- /dev/null +++ b/route.c @@ -0,0 +1,607 @@ +/* + Copyright (C) 2002-2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include "defs.h" +#include "grtcirc.h" + +static queue my_route_head; +static queue my_track_head; +static int rte_head_ct; +static int rte_waypts; +static int trk_head_ct; +static int trk_waypts; + +void +route_init(void) +{ + QUEUE_INIT(&my_route_head); + QUEUE_INIT(&my_track_head); +} + +unsigned int +route_waypt_count(void) +{ + /* total wapoint count -- all routes */ + return rte_waypts; +} + +unsigned int +route_count(void) +{ + return rte_head_ct; /* total # of routes */ +} + +unsigned int +track_waypt_count(void) +{ + /* totaly waypoint count -- all tracks */ + return trk_waypts; +} + +unsigned int +track_count(void) +{ + return trk_head_ct; /* total # of tracks */ +} + +route_head * +route_head_alloc(void) +{ + route_head *rte_head; + rte_head = (route_head *) xcalloc(sizeof (*rte_head), 1); + QUEUE_INIT(&rte_head->Q); + QUEUE_INIT(&rte_head->waypoint_list); + return rte_head; +} + +static void +any_route_free(route_head *rte) +{ + if ( rte->rte_name ) { + xfree(rte->rte_name); + } + if ( rte->rte_desc ) { + xfree(rte->rte_desc); + } + if ( rte->rte_url ) { + xfree(rte->rte_url); + } + waypt_flush(&rte->waypoint_list); + if ( rte->fs ) { + fs_chain_destroy( rte->fs ); + } + xfree(rte); +} + + +static void +any_route_add_head( route_head *rte, queue *head ) { + ENQUEUE_TAIL( head, &rte->Q ); +} + +static void +any_route_del_head( route_head *rte ) { + dequeue( &rte->Q ); + any_route_free( rte ); +} + +void +route_add_head(route_head *rte) +{ + any_route_add_head( rte, &my_route_head ); + rte_head_ct++; +} + +void +route_del_head(route_head *rte) +{ + any_route_del_head( rte ); + rte_head_ct--; +} + +void +track_add_head(route_head *rte) +{ + any_route_add_head( rte, &my_track_head ); + trk_head_ct++; +} + +void +track_del_head(route_head *rte) +{ + any_route_del_head( rte ); + trk_head_ct--; +} + +static +route_head * +common_route_by_name(queue *routes, const char *name) +{ + queue *elem, *tmp; + route_head *rte; + + QUEUE_FOR_EACH(routes, elem, tmp) { + rte = (route_head *) elem; + if (0 == strcmp(rte->rte_name, name)) { + return rte; + } + } + + return NULL; +} + +route_head * +route_find_route_by_name(const char *name) +{ + return common_route_by_name(&my_route_head, name); +} + +route_head * +route_find_track_by_name(const char *name) +{ + return common_route_by_name(&my_track_head, name); +} + +static void +any_route_add_wpt(route_head *rte, waypoint *wpt, int *ct, int synth ) +{ + ENQUEUE_TAIL(&rte->waypoint_list, &wpt->Q); + rte->rte_waypt_ct++; /* waypoints in this route */ + if ( ct ) { + (*ct)++; + } + if ( synth && !wpt->shortname ) { + char tmpnam[10]; + snprintf(tmpnam, sizeof(tmpnam), "RPT%03d",*ct); + wpt->shortname = xstrdup(tmpnam); + wpt->wpt_flags.shortname_is_synthetic = 1; + } +} + +void +route_add_wpt( route_head *rte, waypoint *wpt ) +{ + any_route_add_wpt( rte, wpt, &rte_waypts, 1 ); +} + +void +track_add_wpt( route_head *rte, waypoint *wpt ) +{ + any_route_add_wpt( rte, wpt, &trk_waypts, 0 ); +} + +waypoint * +route_find_waypt_by_name( route_head *rh, const char *name ) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&rh->waypoint_list, elem, tmp) { + waypoint *waypointp = (waypoint *) elem; + if (0 == strcmp(waypointp->shortname, name)) { + return waypointp; + } + } + return NULL; +} + +static void +any_route_del_wpt( route_head *rte, waypoint *wpt, int *ct) +{ + dequeue( &wpt->Q ); + rte->rte_waypt_ct--; + if ( ct ) (*ct)--; +} + +void +route_del_wpt( route_head *rte, waypoint *wpt ) +{ + any_route_del_wpt( rte, wpt, &rte_waypts ); +} + +void +track_del_wpt( route_head *rte, waypoint *wpt ) +{ + any_route_del_wpt( rte, wpt, &trk_waypts ); +} + +void +route_disp (const route_head *rh, waypt_cb cb ) +{ + queue *elem, *tmp; + if (!cb) { + return; + } + QUEUE_FOR_EACH(&rh->waypoint_list, elem, tmp) { + waypoint *waypointp; + waypointp = (waypoint *) elem; + (*cb)(waypointp); + } + +} + +void +route_reverse(const route_head *rte_hd) +{ + /* Cast away const-ness */ + route_head *rh = (route_head *) rte_hd; + queue *elem, *tmp; + QUEUE_FOR_EACH(&rh->waypoint_list, elem, tmp) { + ENQUEUE_HEAD(&rh->waypoint_list, dequeue(elem)); + } +} + +static void +common_disp_all(queue *qh, route_hdr rh, route_trl rt, waypt_cb wc) +{ + queue *elem, *tmp; + QUEUE_FOR_EACH(qh, elem, tmp) { + const route_head *rhp; + rhp = (route_head *) elem; + if (rh) (*rh)(rhp); + route_disp(rhp, wc); + if (rt) (*rt)(rhp); + } +} + +void +route_disp_all(route_hdr rh, route_trl rt, waypt_cb wc) +{ + common_disp_all(&my_route_head, rh, rt, wc); +} + +void +track_disp_all(route_hdr rh, route_trl rt, waypt_cb wc) +{ + common_disp_all(&my_track_head, rh, rt, wc); +} + +static void +route_flush_q(queue *head) +{ + queue *elem, *tmp; + queue *q; + + QUEUE_FOR_EACH(head, elem, tmp) { + q = dequeue(elem); + any_route_free((route_head *) q); + } +} + +void +route_flush_all_routes(void) +{ + route_flush_q(&my_route_head); + rte_head_ct = 0; + rte_waypts = 0; +} + +void +route_flush_all_tracks(void) +{ + route_flush_q(&my_track_head); + trk_head_ct = 0; + trk_waypts = 0; +} + +void +route_flush_all() +{ + route_flush_all_tracks(); + route_flush_all_routes(); +} + +void +route_flush( queue *head ) +{ + queue *elem, *tmp; + queue *q; + QUEUE_FOR_EACH(head, elem, tmp ) { + q = dequeue(elem); + any_route_free((route_head *)q); + } +} + +void +route_copy( int *dst_count, int *dst_wpt_count, queue **dst, queue *src ) { + queue *elem, *tmp, *elem2, *tmp2; + route_head *rte_new; + int junk; + if ( !dst_wpt_count ) { + dst_wpt_count = &junk; + } + + if ( !*dst ) { + *dst = xcalloc( 1, sizeof( queue )); + QUEUE_INIT( *dst ); + *dst_count = 0; + *dst_wpt_count = 0; + } + QUEUE_FOR_EACH(src, elem, tmp ) + { + route_head *rte_old = (route_head *)elem; + + rte_new = route_head_alloc(); + rte_new->rte_name = xstrdup( rte_old->rte_name ); + rte_new->rte_desc = xstrdup( rte_old->rte_desc ); + rte_new->rte_url = xstrdup( rte_old->rte_url ); + rte_new->fs = fs_chain_copy( rte_old->fs ); + rte_new->rte_num = rte_old->rte_num; + any_route_add_head( rte_new, *dst ); + QUEUE_FOR_EACH( &rte_old->waypoint_list, elem2, tmp2 ) + { + any_route_add_wpt( rte_new, waypt_dupe((waypoint *)elem2), dst_wpt_count, 0); + } + (*dst_count)++; + } +} + +void +route_append( queue *src ) +{ + queue *dst = &my_route_head; + route_copy( &rte_head_ct, &rte_waypts, &dst, src ); +} + +void +track_append( queue *src ) +{ + queue *dst = &my_track_head; + route_copy( &trk_head_ct, &trk_waypts, &dst, src ); +} + +void +route_backup(signed int *count, queue **head_bak) +{ + route_copy( count, NULL, head_bak, &my_route_head ); +} + +static void +route_restore_hdr(const route_head *rte) +{ + rte_head_ct++; +} + +static void +track_restore_hdr(const route_head *trk) +{ + trk_head_ct++; +} + +static void +route_restore_tlr(const route_head *rte) +{ +} + +static void +route_restore_wpt(const waypoint *wpt) +{ + rte_waypts++; +} + +static void +track_restore_wpt(const waypoint *wpt) +{ + trk_waypts++; +} + +static void +common_restore_finish(void) +{ + rte_head_ct = 0; + trk_head_ct = 0; + rte_waypts = 0; + trk_waypts = 0; + route_disp_all(route_restore_hdr, route_restore_tlr, route_restore_wpt); + track_disp_all(track_restore_hdr, route_restore_tlr, track_restore_wpt); +} + +void +route_restore( queue *head_bak) +{ + if (head_bak == NULL) return; + + route_flush_q(&my_route_head); + QUEUE_INIT(&my_route_head); + QUEUE_MOVE(&my_route_head, head_bak); + + common_restore_finish(); +} + +void +track_backup(signed int *count, queue **head_bak) +{ + route_copy( count, NULL, head_bak, &my_track_head ); +} + +void +track_restore( queue *head_bak) +{ + if (head_bak == NULL) return; + + route_flush_q(&my_track_head); + QUEUE_INIT(&my_track_head); + QUEUE_MOVE(&my_track_head, head_bak); + + common_restore_finish(); +} + +/* + * Move the entire track queue onto the route queue making no attempt + * at all to "fix" anything in the process. + */ +void +routes_to_tracks(void) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&my_route_head, elem, tmp) { + route_head *trk = (route_head *) elem; + dequeue(&trk->Q); + ENQUEUE_TAIL(&my_track_head, &trk->Q); + } +} + +/* + * Same, but in opposite direction. + */ +void +tracks_to_routes(void) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&my_track_head, elem, tmp) { + route_head *trk = (route_head *) elem; + dequeue(&trk->Q); + ENQUEUE_TAIL(&my_route_head, &trk->Q); + } +} + + +/* + * This really makes more sense for tracks than routes. + * Run over all the trackpoints, computing heading (course), speed, and + * and so on. + * + * If trkdatap is non-null upon entry, a pointer to an allocated collection + * (hopefully interesting) statistics about the track will be placed there. + */ +void track_recompute(const route_head *trk, computed_trkdata **trkdatap) +{ + waypoint first; + waypoint *this; + waypoint *prev = &first; + queue *elem, *tmp; + int tkpt = 0; + int pts_hrt = 0; + double tot_hrt = 0.0; + int pts_cad = 0; + double tot_cad = 0.0; + char tkptname[100]; + computed_trkdata *tdata = xcalloc(1, sizeof (computed_trkdata)); + + if (trkdatap) { + *trkdatap = tdata; + } + + first.latitude = 0; + first.longitude = 0; + first.creation_time = 0; + tdata->min_hrt = 9999; + tdata->min_alt = 999999999; + tdata->max_alt = -999999999; + + QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { + time_t timed; + double tlat, tlon, plat, plon, dist; + + this = (waypoint *)elem; + timed = this->creation_time - prev->creation_time; + + /* + * gcdist and heading want radians, not degrees. + */ + tlat = RAD(this->latitude); + tlon = RAD(this->longitude); + plat = RAD(prev->latitude); + plon = RAD(prev->longitude); + WAYPT_SET(this, course, heading_true_degrees(plat, plon, + tlat, tlon)); + dist = radtometers(gcdist(plat, plon, tlat, tlon)); + + /* + * Avoid that 6300 mile jump as we move from 0,0. + */ + if (plat && plon) { + tdata->distance_meters += dist; + } + + /* + * If we've moved as much as a meter, recompute speed. + */ + if (timed && (dist > 1)) { + WAYPT_SET(this, speed, dist / labs(timed)); + if (this->speed > tdata->max_spd) { + tdata->max_spd = this->speed; + } + if (this->speed < tdata->min_spd) { + tdata->min_spd = this->speed; + } + } + + if ((this->altitude > 0) && (this->altitude < tdata->min_alt)) { + tdata->min_alt = this->altitude; + } + if (this->altitude > tdata->max_alt) { + tdata->max_alt = this->altitude; + } + + if (this->heartrate > 0) { + pts_hrt++; + tot_hrt += (float) this->heartrate; + } + + if ((this->heartrate > 0) && (this->heartrate < tdata->min_hrt)) { + tdata->min_hrt = (int) this->heartrate; + } + + if ((this->heartrate > 0) && (this->heartrate > tdata->max_hrt)) { + tdata->max_hrt = (int) this->heartrate; + } + + if (this->cadence > 0) { + pts_cad++; + tot_cad += (float) this->cadence; + } + + if ((this->cadence > 0) && (this->cadence > tdata->max_cad)) { + tdata->max_cad = (int) this->cadence; + } + + if (this->creation_time && (this->creation_time < tdata->start)) { + tdata->start = this->creation_time; + } + + if (this->creation_time > tdata->end) { + tdata->end = this->creation_time; + if (tdata->start == 0) { + tdata->start = tdata->end; + } + } + prev = this; + if (!this->shortname || !this->shortname[0] ) { + snprintf(tkptname, sizeof(tkptname), "%s-%d", + trk->rte_name ? trk->rte_name : "" , tkpt); + this->shortname = xstrdup(tkptname); + } + tkpt++; + } + + if (pts_hrt > 0) { + tdata->avg_hrt = tot_hrt / (float) pts_hrt; + } + + if (pts_cad > 0) { + tdata->avg_cad = tot_cad / (float) pts_cad; + } + + if (!trkdatap) { + xfree(tdata); + } +} diff --git a/saroute.c b/saroute.c new file mode 100644 index 000000000..519bde10e --- /dev/null +++ b/saroute.c @@ -0,0 +1,451 @@ +/* + Read various Delorme routes including anr, rte, and rtd. + + Copyright (C) 2003 Ron Parker and Robert Lipe. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include + +#define MYNAME "saroute" +#include "defs.h" +#include "grtcirc.h" + +gbfile *infile; + +char *turns_important = NULL; +char *turns_only = NULL; +char *controls = NULL; +char *split = NULL; +char *timesynth = NULL; + +int control = 0; + +static +arglist_t saroute_args[] = { + {"turns_important", &turns_important, + "Keep turns if simplify filter is used", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"turns_only", &turns_only, "Only read turns; skip all other points", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"split", &split, "Split into multiple routes at turns", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"controls", &controls, "Read control points as waypoint/route/none", + "none", ARGTYPE_STRING, ARG_NOMINMAX }, + {"times", ×ynth, "Synthesize track times", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +#define ReadShort(f) gbfgetint16(f) +#define ReadLong(f) gbfgetint32(f) + +unsigned char * +ReadRecord(gbfile *f, gbsize_t size) +{ + unsigned char *result = (unsigned char *) xmalloc(size); + + (void)gbfread(result, size, 1, f); + return result; +} + +void +Skip(gbfile * f, gbsize_t distance) +{ + gbfseek(f, distance, SEEK_CUR); +} + +static void +rd_init(const char *fname) +{ + infile = gbfopen(fname, "rb", MYNAME); + if ( split && (turns_important || turns_only )) { + fatal( MYNAME + ": turns options are not compatible with split\n" ); + } + if ( controls ) { + switch( controls[0] ) { + case 'n': control = 0; break; + case 'r': control = 1; break; + case 'w': control = 2; break; + default: + fatal( MYNAME + ": unrecognized value for 'controls'\n" ); + break; + } + } +} + +static void +rd_deinit(void) +{ + gbfclose(infile); +} + +static void +my_read(void) +{ + + gbuint16 version; + gbuint32 count; + gbuint32 outercount; + gbuint32 recsize; + gbuint16 stringlen; + unsigned char *record; + static int serial = 0; + struct ll { + gbint32 lat; + gbint32 lon; + } *latlon; + gbuint16 coordcount; + route_head *track_head = NULL; + route_head *old_track_head = NULL; + waypoint *wpt_tmp; + char *routename = NULL; + double seglen = 0.0; + gbint32 starttime = 0; + gbint32 transittime = 0; + double totaldist = 0.0; + double oldlat = 0; + double oldlon = 0; + int first = 0; + + ReadShort(infile); /* magic */ + version = ReadShort(infile); + + ReadLong(infile); + if (version >= 6) { + ReadLong(infile); + ReadLong(infile); + } + + /* + * end of header + */ + + ReadShort(infile); + recsize = ReadLong(infile); + /* + * the first recsize, oddly, doesn't include the filename string + * but it does include the header. + */ + record = ReadRecord(infile, recsize); + + stringlen = le_read16((gbuint16 *)(record + 0x1a)); + if ( stringlen ) { + routename = (char *)xmalloc( stringlen + 1 ); + routename[stringlen] = '\0'; + memcpy( routename, record+0x1c, stringlen ); + } + Skip(infile, stringlen - 4); + xfree(record); + + /* + * end of filename record + */ + + /* + * here lie the route description records + */ + if ( version < 6 || (control == 1)) { + track_head = route_head_alloc(); + route_add_head(track_head); + if ( control ) { + track_head->rte_name = xstrdup("control points"); + } + else { + track_head->rte_name = xstrdup( routename ); + } + } + count = ReadLong(infile); + while (count) { + ReadShort(infile); + recsize = ReadLong(infile); + if (version < 6 || control) { + double lat; + double lon; + + record = ReadRecord(infile, recsize); + latlon = (struct ll *)(record); + + /* These records are backwards for some reason */ + lat = (0x80000000UL - + le_read32(&latlon->lon)) / (double)(0x800000); + lon = (0x80000000UL - + le_read32(&latlon->lat)) / (double)(0x800000); + + wpt_tmp = waypt_new(); + wpt_tmp->latitude = lat; + wpt_tmp->longitude = -lon; + if ( control ) { + int obase, addrlen, cmtlen; + + /* Somewhere around TopoUSA 6.0, these moved */ + /* This block also seems to get miscompiled + * at -O0 on Linux. I tried rewriting it to + * reduce/eliminate some of the really funky + * pointer math and casting that was here. + */ + if (version >= 11) { + obase = 20; + } else { + obase = 18; + } + + addrlen = le_read16(&record[obase]); + cmtlen = le_read16(&record[obase+2+addrlen]); + + wpt_tmp->shortname = xmalloc(addrlen+1); + wpt_tmp->shortname[addrlen]='\0'; + wpt_tmp->notes = xmalloc(cmtlen+1); + wpt_tmp->notes[cmtlen] = '\0'; + memcpy(wpt_tmp->notes, + record+obase+4+addrlen, + cmtlen ); + memcpy(wpt_tmp->shortname, + record+obase+2, + addrlen ); + } + else { + wpt_tmp->shortname = xmalloc(7); + sprintf( wpt_tmp->shortname, "\\%5.5x", serial++ ); + } + if ( control == 2 ) { + waypt_add( wpt_tmp ); + } + else { + route_add_wpt(track_head, wpt_tmp); + } + xfree(record); + if (version >= 6 ) { + /* + * two longs of scrap after each record, don't know why + */ + ReadLong(infile); + ReadLong(infile); + } + } else { + Skip(infile, recsize); + /* + * two longs of scrap after each record, don't know why + */ + ReadLong(infile); + ReadLong(infile); + } + count--; + } + /* + * end of route desc records + */ + + /* + * outercount is the number of route segments (start+end+stops+vias-1) + */ + + outercount = ReadLong(infile); + while (outercount) { + + /* + * unknown record (route params?) lives here + */ + ReadShort(infile); + recsize = ReadLong(infile); + Skip(infile, recsize); + + /* + * end of unknown record + */ + + /* + * routing begins here + */ + count = ReadLong(infile); + if ( count ) { + track_head = route_head_alloc(); + if ( timesynth ) { + track_add_head(track_head); + } + else { + route_add_head(track_head); + } + if ( routename && !split ) { + track_head->rte_name = xstrdup( routename ); + } + } + while (count) { + old_track_head = NULL; + ReadShort(infile); + recsize = ReadLong(infile); + record = ReadRecord(infile, recsize); + stringlen = le_read16((gbuint16 *)record); + if ( split && stringlen ) { + if ( track_head->rte_waypt_ct ) { + old_track_head = track_head; + track_head = route_head_alloc(); + if ( timesynth ) { + track_add_head( track_head ); + } + else { + route_add_head( track_head ); + } + } // end if + if ( !track_head->rte_name ) { + track_head->rte_name = + (char *)xmalloc(stringlen+1); + strncpy( track_head->rte_name, + (const char *) record+2, stringlen ); + track_head->rte_name[stringlen] = '\0'; + } + } + + if ( timesynth ) { + seglen = le_read_double( + record + 2 + stringlen + 0x08 ); + starttime = le_read32((gbuint32 *) + (record + 2 + stringlen + 0x30 )); + transittime = le_read32((gbuint32 *) + (record + 2 + stringlen + 0x10 )); + seglen /= 5280*12*2.54/100000; /* to miles */ + } + + coordcount = le_read16((gbuint16 *) + (record + 2 + stringlen + 0x3c)); + latlon = (struct ll *)(record + 2 + stringlen + 0x3c + 2); + count--; + if (count) { + coordcount--; + } + + first = 1; + + while (coordcount) { + double lat; + double lon; + + wpt_tmp = waypt_new(); + + lat = (0x80000000UL - + le_read32(&latlon->lat)) / + (double)(0x800000); + lon = (0x80000000UL - + le_read32(&latlon->lon)) / + (double)(0x800000); + + wpt_tmp->latitude = lat; + wpt_tmp->longitude = -lon; + if ( stringlen && ((coordcount>1) || count)) { + wpt_tmp->shortname = xmalloc(stringlen+1); + wpt_tmp->shortname[stringlen] = '\0'; + memcpy( wpt_tmp->shortname, + ((char *)record)+2, + stringlen ); + } + else { + wpt_tmp->shortname = (char *) xmalloc(7); + sprintf( wpt_tmp->shortname, "\\%5.5x", + serial++ ); + } + if ( timesynth ) { + if ( !first ) { + double dist = radtomiles(gcdist( + RAD(lat), RAD(-lon), + RAD(oldlat), + RAD(-oldlon) )); + totaldist += dist; + if ( totaldist > seglen ) { + totaldist = seglen; + } + wpt_tmp->creation_time = + gpsbabel_time+starttime+ + transittime * totaldist/seglen; + } + else { + wpt_tmp->creation_time = + gpsbabel_time+starttime; + totaldist = 0; + } + oldlat = lat; + oldlon = lon; + } + if ( turns_important && stringlen ) + wpt_tmp->route_priority=1; + if ( !turns_only || stringlen ) { + if ( timesynth ) { + track_add_wpt(track_head,wpt_tmp); + } + else { + route_add_wpt(track_head, wpt_tmp); + } + if ( old_track_head ) { + if ( timesynth ) { + track_add_wpt(old_track_head, + waypt_dupe(wpt_tmp)); + } + else { + route_add_wpt(old_track_head, + waypt_dupe(wpt_tmp)); + } + old_track_head = NULL; + } + } + + latlon++; + coordcount--; + stringlen = 0; + /* the stop point is a "turn" */ + if ( coordcount == 1 && count == 0 ) { + stringlen = 1; + } + first = 0; + } + if ( version > 10 ) { + Skip(infile,2*sizeof(gbuint32)); + } + xfree(record); + } + /* + * end of routing + */ + outercount--; + } + if ( routename ) { + xfree( routename ); + } + +} + +static void +wr_init(const char *fname) +{ + fatal(MYNAME ":Not enough information is known about this format to write it.\n"); +} + +ff_vecs_t saroute_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none}, + rd_init, + wr_init, + rd_deinit, + NULL, + my_read, + NULL, + NULL, + saroute_args, + CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ +}; diff --git a/shape.c b/shape.c new file mode 100644 index 000000000..109541238 --- /dev/null +++ b/shape.c @@ -0,0 +1,319 @@ +/* + + ESRI shp/shx shapefiles. + + Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "shapelib/shapefil.h" + +#if SHAPELIB_ENABLED +static SHPHandle ihandle; +static DBFHandle ihandledb; +static SHPHandle ohandle; +#define MYNAME "shape" + +static unsigned poly_count; +static double *polybufx; +static double *polybufy; +static double *polybufz; +static const char *ofname; +static int nameidx; +static int urlidx; + +static char *opt_name = NULL; +static char *opt_url = NULL; + +static +arglist_t shp_args[] = { + {"name", &opt_name, "Index of name field in .dbf", + NULL, ARGTYPE_STRING, "0", NULL }, + {"url", &opt_url, "Index of URL field in .dbf", + NULL, ARGTYPE_INT, "0", NULL }, + ARG_TERMINATOR +}; + +static void +my_rd_init(const char *fname) +{ + ihandle = SHPOpen(fname, "rb" ); + if (ihandle == NULL) { + fatal(MYNAME ":Cannot open shp file %s for reading\n", fname); + } + + ihandledb = DBFOpen(fname, "rb" ); + if (ihandledb == NULL) { + fatal(MYNAME ":Cannot open dbf file %s for reading\n", fname); + } + + if ( opt_name ) { + if ( opt_name[0] == '?' ) { + int nFields = 0; + int i = 0; + char name[12]; + char *txt = xstrdup(" Database fields\n"); + nFields = DBFGetFieldCount( ihandledb ); + for ( i = 0; i < nFields; i++ ) { + char txtName[50]; + DBFGetFieldInfo( ihandledb, i, name, NULL, NULL); + sprintf( txtName,"%2d %s\n", i, name ); + txt = xstrappend( txt, txtName ); + } + txt = xstrappend( txt, "\n" ); + fatal( txt ); + } + if ( strchr(opt_name, '+')) { + nameidx = -2; + } + else if ( opt_name[0] >= '0' && opt_name[0] <= '9' ) { + nameidx = atoi( opt_name ); + } + else { + nameidx = DBFGetFieldIndex( ihandledb, opt_name ); + if (nameidx == -1) { + fatal(MYNAME ":dbf file for %s doesn't have '%s' field.\n", fname, opt_name); + } + } + } + else { + nameidx = DBFGetFieldIndex( ihandledb, "NAME" ); + if (nameidx == -1) { +// fatal(MYNAME ":dbf file for %s doesn't have 'NAME' field.\n Please specify the name index with the 'name' option.\n", fname); + } + } + if ( opt_url ) { + if ( opt_url[0] >= '0' && opt_url[0] <= '9' ) { + urlidx = atoi( opt_url ); + } + else { + urlidx = DBFGetFieldIndex( ihandledb, opt_url ); + } + } + else { + urlidx = DBFGetFieldIndex( ihandledb, "URL" ); + } +} + +void +my_read(void) +{ + int npts; + + SHPGetInfo(ihandle, &npts, NULL, NULL, NULL); + + while (npts) { + SHPObject *shp; + waypoint *wpt; + const char *name = ""; + const char *url; + char *tmpName = NULL; + char *tmpIndex = opt_name; + + shp = SHPReadObject(ihandle, npts-1); + if ( nameidx >0 ) { + name = DBFReadStringAttribute(ihandledb, npts-1, nameidx); + } + else { + if ( nameidx == -1 ) { + name = ""; + } + else if (nameidx == -2 ) { + tmpName = xstrdup( "" ); + tmpIndex = opt_name; + while ( tmpIndex ) { + char *tmp2 = tmpIndex; + tmpIndex = strchr(tmpIndex,'+'); + if ( tmpIndex ) { + *tmpIndex = '\0'; + tmpIndex++; + } + if( tmp2[0]>='0' && tmp2[0]<='9' ) { + name = DBFReadStringAttribute( + ihandledb, npts-1, atoi(tmp2)); + } + else { + int idx = 0; + idx = DBFGetFieldIndex( ihandledb, tmp2); + if ( idx >= 0 ) { + name = DBFReadStringAttribute( + ihandledb, npts-1, idx); + } + } + + tmpName = xstrappend(tmpName, name ); + if ( tmpIndex ) { + tmpName = xstrappend( tmpName, " / " ); + } + } + name = tmpName; + } + } + if ( urlidx > 0 ) { + url = DBFReadStringAttribute( ihandledb, npts-1, urlidx); + } + else { + url = NULL; + } + + if (shp->nSHPType == SHPT_ARC) { + int j; + route_head *routehead = route_head_alloc(); + routehead->rte_name = xstrdup(name); + route_add_head(routehead); + for (j = 0; j < shp->nVertices; j++) { + wpt = waypt_new(); + wpt->latitude = shp->padfY[j]; + wpt->longitude = shp->padfX[j]; + wpt->altitude = shp->padfZ[j]; + route_add_wpt(routehead, wpt); + } + } + + if (shp->nSHPType == SHPT_POINT) { + wpt = waypt_new(); + wpt->latitude = shp->dfYMin; + wpt->longitude = shp->dfXMin; + wpt->shortname = xstrdup(name); + if ( url ) { + wpt->url = xstrdup(url); + } + waypt_add(wpt); + } + + SHPDestroyObject(shp); + + npts--; + if ( tmpName ) { + xfree( tmpName ); + tmpName = NULL; + } + } + +} + +void +my_rd_deinit(void) +{ + SHPClose (ihandle); +} + +void +my_wr_init(const char *fname) +{ + ofname = fname; +} + +void +my_wr_deinit(void) +{ + SHPClose (ohandle); +} + +void +my_write_wpt(const waypoint *wpt) +{ + SHPObject *shpobject; + + shpobject = SHPCreateSimpleObject(SHPT_POINT, 1, + (double *)(void *)&wpt->longitude, + (double *)(void *)&wpt->latitude, + (double *)(void *)&wpt->altitude); + SHPWriteObject(ohandle, -1, shpobject); + SHPDestroyObject(shpobject); +} + +void +poly_init(const route_head *h) +{ + int ct = track_waypt_count(); + polybufx = xcalloc(ct, sizeof(double)); + polybufy = xcalloc(ct, sizeof(double)); + polybufz = xcalloc(ct, sizeof(double)); +} + + +void +poly_point(const waypoint *wpt) +{ + polybufx[poly_count] = wpt->longitude; + polybufy[poly_count] = wpt->latitude; + polybufz[poly_count] = wpt->altitude; + poly_count++; +} + +void +poly_deinit(const route_head *h) +{ + SHPObject *shpobject; + shpobject = SHPCreateSimpleObject(SHPT_ARC, track_waypt_count(), + polybufx, polybufy, polybufz); + SHPWriteObject(ohandle, -1, shpobject); + SHPDestroyObject(shpobject); + xfree(polybufx); + xfree(polybufy); + xfree(polybufz); + fprintf(stderr, "Done\n"); + poly_count = 0; +} + + +void +my_write(void) +{ + switch(global_opts.objective) { + case wptdata: + ohandle = SHPCreate(ofname, SHPT_POINT); + + if (ohandle == NULL) { + fatal(MYNAME ":Cannot open %s for writing\n", + ofname); + } + waypt_disp_all(my_write_wpt); + break; + case trkdata: + ohandle = SHPCreate(ofname, SHPT_ARC); + + if (ohandle == NULL) { + fatal(MYNAME ":Cannot open %s for writing\n", + ofname); + } + route_disp_all(poly_init, poly_deinit, poly_point); + break; + case rtedata: + fatal(MYNAME ": Routes are not supported\n"); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported\n"); + break; + } +} + +ff_vecs_t shape_vecs = { + ff_type_internal, + FF_CAP_RW_ALL, + my_rd_init, + my_wr_init, + my_rd_deinit, + my_wr_deinit, + my_read, + my_write, + NULL, + shp_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; +#endif /* SHAPELIB_ENABLED */ diff --git a/shapelib/.cvsignore b/shapelib/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/shapelib/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/shapelib/Makefile.in b/shapelib/Makefile.in new file mode 100644 index 000000000..e69de29bb diff --git a/shapelib/README.GPSBabel b/shapelib/README.GPSBabel new file mode 100644 index 000000000..7961447b0 --- /dev/null +++ b/shapelib/README.GPSBabel @@ -0,0 +1,4 @@ +This is a subset of Shapelib v1.2.10 from http://shapelib.maptools.org/ + +The source is unmodified. It's subsetted here only to reduce the amount of +size in our tree that it takes and to reduce ongoing merge maintenance. diff --git a/shapelib/dbf_api.html b/shapelib/dbf_api.html new file mode 100644 index 000000000..b0fa37372 --- /dev/null +++ b/shapelib/dbf_api.html @@ -0,0 +1,408 @@ + + +Attribute (.DBF) API + + +

    Attribute (.DBF) API

    + +The Attribute (DBF) API uses DBFHandle to represent a handle for access +to one .dbf file. The contents of the DBFHandle are visible (see shapefil.h) +but should be ignored by the application. It is intended that all information +be accessed by API functions. Note that there should be exactly one record +in the .dbf file for each shape in the .shp/.shx files. This constraint +must be maintained by the application.

    + + + +

    DBFOpen()

    + +
    +DBFHandle DBFOpen( const char * pszDBFFile, const char * pszAccess );
    +
    +  pszDBFFile:		The name of the xBase (.dbf) file to access.
    +
    +  pszAccess:		The fopen() style access string.  At this time only
    +			"rb" (read-only binary) and "rb+" (read/write binary) 
    +		        should be used.
    +
    + + The DBFOpen() function should be used to establish access to an existing + xBase format table file. The returned DBFHandle is passed to other + access functions, and DBFClose() should be invoked to recover resources, and + flush changes to disk when complete. The DBFCreate() function should + called to create new xBase files. As a convenience, DBFOpen() can be + called with the name of a .shp or .shx file, and it will figure out the + name of the related .dbf file.

    + + + +

    DBFCreate()

    + +
    +DBFHandle DBFCreate( const char * pszDBFFile );
    +
    +  pszDBFFile:		The name of the xBase (.dbf) file to create.
    +
    + + The DBFCreate() function creates a new xBase format file with the given + name, and returns an access handle that can be used with other DBF functions. + The newly created file will have no fields, and no records. Fields should + be added with DBFAddField() before any records add written. + + + +

    DBFGetFieldCount()

    + +
    +int DBFGetFieldCount( DBFHandle hDBF );
    +
    +  hDBF:		The access handle for the file to be queried, as returned
    +                by DBFOpen(), or DBFCreate().
    +
    + + The DBFGetFieldCount() function returns the number of fields currently + defined for the indicated xBase file. + + + +

    DBFGetRecordCount()

    + +
    +int DBFGetRecordCount( DBFHandle hDBF );
    +
    +  hDBF:		The access handle for the file to be queried, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    + + The DBFGetRecordCount() function returns the number of records that + exist on the xBase file currently. Note that with shape files one xBase + record exists for each shape in the .shp/.shx files.

    + + + +

    DBFGetFieldIndex()

    + +
    +int DBFGetFieldIndex( DBFHandle hDBF, const char *pszFieldName );
    +
    +  hDBF:		The access handle for the file to be queried, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  pszFieldName: Name of the field to search for.
    +
    + + Returns the index of the field matching this name, or -1 on failure. The + comparison is case insensitive. However, lengths must match exactly.

    + + + +

    DBFGetFieldInfo()

    + +
    +DBFFieldType DBFGetFieldInfo( DBFHandle hDBF, int iField, char * pszFieldName,
    +                              int * pnWidth, int * pnDecimals );
    +
    +  hDBF:		The access handle for the file to be queried, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  iField:	The field to be queried.  This should be a number between 
    +                0 and n-1, where n is the number fields on the file, as
    +                returned by DBFGetFieldCount().
    +
    +  pszFieldName:	If this pointer is not NULL the name of the requested field
    +		will be written to this location.  The pszFieldName buffer 
    +                should be at least 12 character is size in order to hold
    +		the longest possible field name of 11 characters plus a 
    +                terminating zero character.
    +
    +  pnWidth:	If this pointer is not NULL, the width of the requested field
    +		will be returned in the int pointed to by pnWidth.  This is
    +                the width in characters.  
    +
    +  pnDecimals:	If this pointer is not NULL, the number of decimal places
    +                precision defined for the field will be returned.  This is
    +                zero for integer fields, or non-numeric fields.
    +
    + + The DBFGetFieldInfo() returns the type of the requested field, which is + one of the DBFFieldType enumerated values. As well, the field name, and + field width information can optionally be returned. The field type returned + does not correspond one to one with the xBase field types. For instance + the xBase field type for Date will just be returned as being FTInteger.

    + +

    +    typedef enum {
    +      FTString,			/* fixed length string field 		*/
    +      FTInteger,		/* numeric field with no decimals 	*/
    +      FTDouble,			/* numeric field with decimals 		*/
    +      FTLogical,		/* logical field.                       */
    +      FTInvalid                 /* not a recognised field type 		*/
    +    } DBFFieldType;
    +
    + + + +

    DBFAddField()

    + +
    +int DBFAddField( DBFHandle hDBF, const char * pszFieldName, 
    +                 DBFFieldType eType, int nWidth, int nDecimals );
    +
    +  hDBF:		The access handle for the file to be updated, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  pszFieldName:	The name of the new field.  At most 11 character will be used.
    +                In order to use the xBase file in some packages it may be
    +                necessary to avoid some special characters in the field names
    +                such as spaces, or arithmetic operators.
    +
    +  eType:	One of FTString, FTInteger or FTDouble in order to establish
    +                the type of the new field.  Note that some valid xBase field
    +                types cannot be created such as date fields.
    +
    +  nWidth:	The width of the field to be created.  For FTString fields this
    +                establishes the maximum length of string that can be stored.
    +                For FTInteger this establishes the number of digits of the
    +                largest number that can
    +                be represented.  For FTDouble fields this in combination
    +                with the nDecimals value establish the size, and precision
    +                of the created field.
    +
    +  nDecimals:    The number of decimal places to reserve for FTDouble fields.
    +                For all other field types this should be zero.  For instance
    +                with nWidth=7, and nDecimals=3 numbers would be formatted
    +                similarly to `123.456'.
    +
    + + The DBFAddField() function is used to add new fields to an existing xBase + file opened with DBFOpen(), or created with DBFCreate(). Note that fields + can only be added to xBase files with no records, though this is limitation + of this API, not of the file format.

    + + The DBFAddField() return value is the field number of the new field, or + -1 if the addition of the field failed.

    + + + +

    DBFReadIntegerAttribute()

    + +
    +int DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
    +  
    +  hDBF:		The access handle for the file to be queried, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  iShape:	The record number (shape number) from which the field value
    +                should be read.
    +
    +  iField:	The field within the selected record that should be read.
    +
    + + The DBFReadIntegerAttribute() will read the value of one field and return + it as an integer. This can be used even with FTString fields, though the + returned value will be zero if not interpretable as a number.

    + + + +

    DBFReadDoubleAttribute()

    + +
    +double DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
    +  
    +  hDBF:		The access handle for the file to be queried, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  iShape:	The record number (shape number) from which the field value
    +                should be read.
    +
    +  iField:	The field within the selected record that should be read.
    +
    + + The DBFReadDoubleAttribute() will read the value of one field and return + it as a double. This can be used even with FTString fields, though the + returned value will be zero if not interpretable as a number.

    + + + +

    DBFReadStringAttribute()

    + +
    +const char *DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
    +  
    +  hDBF:		The access handle for the file to be queried, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  iShape:	The record number (shape number) from which the field value
    +                should be read.
    +
    +  iField:	The field within the selected record that should be read.
    +
    + + The DBFReadStringAttribute() will read the value of one field and return + it as a string. This function may be used on any field type (including + FTInteger and FTDouble) and will return the string representation stored + in the .dbf file. The returned pointer is to an internal buffer + which is only valid untill the next DBF function call. It's contents may + be copied with normal string functions such as strcpy(), or strdup(). If + the TRIM_DBF_WHITESPACE macro is defined in shapefil.h (it is by default) + then all leading and trailing space (ASCII 32) characters will be stripped + before the string is returned.

    + + + +

    DBFIsAttributeNULL()

    + +
    +int DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
    +  
    +  hDBF:		The access handle for the file to be queried, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  iShape:	The record number (shape number) from which the field value
    +                should be read.
    +
    +  iField:	The field within the selected record that should be read.
    +
    + + This function will return TRUE if the indicated field is NULL valued + otherwise FALSE. Note that NULL fields are represented in the .dbf file + as having all spaces in the field. Reading NULL fields will result in + a value of 0.0 or an empty string with the other DBFRead*Attribute() + functions.

    + + + +

    DBFWriteIntegerAttribute

    + +
    +int DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField,
    +                              int nFieldValue );
    +
    +  hDBF:		The access handle for the file to be written, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  iShape:	The record number (shape number) to which the field value
    +                should be written.
    +
    +  iField:	The field within the selected record that should be written.
    +
    +  nFieldValue:	The integer value that should be written.
    +
    + +The DBFWriteIntegerAttribute() function is used to write a value to a numeric +field (FTInteger, or FTDouble). If the write succeeds the value TRUE will +be returned, otherwise FALSE will be returned. If the value is too large to +fit in the field, it will be truncated and FALSE returned.

    + + + +

    DBFWriteDoubleAttribute()

    + +
    +int DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
    +                             double dFieldValue );
    +
    +  hDBF:		The access handle for the file to be written, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  iShape:	The record number (shape number) to which the field value
    +                should be written.
    +
    +  iField:	The field within the selected record that should be written.
    +
    +  dFieldValue:	The floating point value that should be written.
    +
    + +The DBFWriteDoubleAttribute() function is used to write a value to a numeric +field (FTInteger, or FTDouble). If the write succeeds the value TRUE will +be returned, otherwise FALSE will be returned. If the value is too large to +fit in the field, it will be truncated and FALSE returned.

    + + + +

    DBFWriteStringAttribute()

    + +
    +int DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
    +                             const char * pszFieldValue );
    +
    +  hDBF:		The access handle for the file to be written, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  iShape:	The record number (shape number) to which the field value
    +                should be written.
    +
    +  iField:	The field within the selected record that should be written.
    +
    +  pszFieldValue: The string to be written to the field.
    +
    + +The DBFWriteStringAttribute() function is used to write a value to a string +field (FString). If the write succeeds the value TRUE willbe returned, +otherwise FALSE will be returned. If the value is too large to +fit in the field, it will be truncated and FALSE returned.

    + + + +

    DBFWriteNULLAttribute()

    + +
    +int DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField );
    +
    +  hDBF:		The access handle for the file to be written, as returned by
    +		DBFOpen(), or DBFCreate().
    +
    +  iShape:	The record number (shape number) to which the field value
    +                should be written.
    +
    +  iField:	The field within the selected record that should be written.
    +
    + +The DBFWriteNULLAttribute() function is used to clear the indicated field +to a NULL value. In the .dbf file this is represented by setting the entire +field to spaces. If the write succeeds the value TRUE willbe returned, +otherwise FALSE will be returned.

    + + + +

    DBFClose()

    + +
    +void DBFClose( DBFHandle hDBF );
    +
    +  hDBF:		The access handle for the file to be closed.
    +
    + + The DBFClose() function will close the indicated xBase file (opened with + DBFOpen(), or DBFCreate()), flushing out all information to the file on + disk, and recovering any resources associated with having the file open. + The file handle (hDBF) should not be used again with the DBF API after + calling DBFClose().

    + + + +

    DBFGetNativeFieldType()

    + +
    +char DBFGetNativeFieldType( DBFHandle hDBF, int iField );
    +
    +  hDBF:		The access handle for the file.
    +  iField:       The field index to query.
    +  
    +
    + + This function returns the DBF type code of the indicated field. It will + be one of:

    + +

      +
    • 'C' (String) +
    • 'D' (Date) +
    • 'F' (Float) +
    • 'N' (Numeric, with or without decimal) +
    • 'L' (Logical) +
    • 'M' (Memo: 10 digits .DBT block ptr) +
    • ' ' (field out of range) +
    + + + diff --git a/shapelib/dbfopen.c b/shapelib/dbfopen.c new file mode 100644 index 000000000..600271092 --- /dev/null +++ b/shapelib/dbfopen.c @@ -0,0 +1,1509 @@ +/****************************************************************************** + * $Id: dbfopen.c,v 1.3 2006/07/13 03:27:54 robertl Exp $ + * + * Project: Shapelib + * Purpose: Implementation of .dbf access API documented in dbf_api.html. + * Author: Frank Warmerdam, warmerdam@pobox.com + * + ****************************************************************************** + * Copyright (c) 1999, Frank Warmerdam + * + * This software is available under the following "MIT Style" license, + * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This + * option is discussed in more detail in shapelib.html. + * + * -- + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * $Log: dbfopen.c,v $ + * Revision 1.3 2006/07/13 03:27:54 robertl + * Andy Armstrong turns on -Wall for GCC builds and kills about a sequillion warnings. Most of them aren't "real", but it's still a good thing to clean up. + * (I hope I don't regret this before 1.3.1...) + * + * Revision 1.2 2006/05/07 02:14:35 robertl + * Make shapefile and all palm pdb formats deselectable at build time. + * + * Revision 1.1 2004/09/20 17:21:22 robertl + * Check in shapelib and experimental prototype of crude shapefile support. + * + * Revision 1.48 2003/03/10 14:51:27 warmerda + * DBFWrite* calls now return FALSE if they have to truncate + * + * Revision 1.47 2002/11/20 03:32:22 warmerda + * Ensure field name in DBFGetFieldIndex() is properly terminated. + * + * Revision 1.46 2002/10/09 13:10:21 warmerda + * Added check that width is positive. + * + * Revision 1.45 2002/09/29 00:00:08 warmerda + * added FTLogical and logical attribute read/write calls + * + * Revision 1.44 2002/05/07 13:46:11 warmerda + * Added DBFWriteAttributeDirectly(). + * + * Revision 1.43 2002/02/13 19:39:21 warmerda + * Fix casting issues in DBFCloneEmpty(). + * + * Revision 1.42 2002/01/15 14:36:07 warmerda + * updated email address + * + * Revision 1.41 2002/01/15 14:31:49 warmerda + * compute rather than copying nHeaderLength in DBFCloneEmpty() + * + * Revision 1.40 2002/01/09 04:32:35 warmerda + * fixed to read correct amount of header + * + * Revision 1.39 2001/12/11 22:41:03 warmerda + * improve io related error checking when reading header + * + * Revision 1.38 2001/11/28 16:07:31 warmerda + * Cleanup to avoid compiler warnings as suggested by Richard Hash. + * + * Revision 1.37 2001/07/04 05:18:09 warmerda + * do last fix properly + * + * Revision 1.36 2001/07/04 05:16:09 warmerda + * fixed fieldname comparison in DBFGetFieldIndex + * + * Revision 1.35 2001/06/22 02:10:06 warmerda + * fixed NULL shape support with help from Jim Matthews + * + * Revision 1.33 2001/05/31 19:20:13 warmerda + * added DBFGetFieldIndex() + * + * Revision 1.32 2001/05/31 18:15:40 warmerda + * Added support for NULL fields in DBF files + * + * Revision 1.31 2001/05/23 13:36:52 warmerda + * added use of SHPAPI_CALL + * + * Revision 1.30 2000/12/05 14:43:38 warmerda + * DBReadAttribute() white space trimming bug fix + * + * Revision 1.29 2000/10/05 14:36:44 warmerda + * fix bug with writing very wide numeric fields + * + * Revision 1.28 2000/09/25 14:18:07 warmerda + * Added some casts of strlen() return result to fix warnings on some + * systems, as submitted by Daniel. + * + * Revision 1.27 2000/09/25 14:15:51 warmerda + * added DBFGetNativeFieldType() + * + * Revision 1.26 2000/07/07 13:39:45 warmerda + * removed unused variables, and added system include files + * + * Revision 1.25 2000/05/29 18:19:13 warmerda + * avoid use of uchar, and adding casting fix + * + * Revision 1.24 2000/05/23 13:38:27 warmerda + * Added error checks on return results of fread() and fseek(). + * + * Revision 1.23 2000/05/23 13:25:49 warmerda + * Avoid crashing if field or record are out of range in dbfread*attribute(). + * + * Revision 1.22 1999/12/15 13:47:24 warmerda + * Added stdlib.h to ensure that atof() is prototyped. + * + * Revision 1.21 1999/12/13 17:25:46 warmerda + * Added support for upper case .DBF extention. + * + * Revision 1.20 1999/11/30 16:32:11 warmerda + * Use atof() instead of sscanf(). + * + * Revision 1.19 1999/11/05 14:12:04 warmerda + * updated license terms + * + * Revision 1.18 1999/07/27 00:53:28 warmerda + * ensure that whole old field value clear on write of string + * + * Revision 1.1 1999/07/05 18:58:07 warmerda + * New + * + * Revision 1.17 1999/06/11 19:14:12 warmerda + * Fixed some memory leaks. + * + * Revision 1.16 1999/06/11 19:04:11 warmerda + * Remoted some unused variables. + * + * Revision 1.15 1999/05/11 03:19:28 warmerda + * added new Tuple api, and improved extension handling - add from candrsn + * + * Revision 1.14 1999/05/04 15:01:48 warmerda + * Added 'F' support. + * + * Revision 1.13 1999/03/23 17:38:59 warmerda + * DBFAddField() now actually does return the new field number, or -1 if + * it fails. + * + * Revision 1.12 1999/03/06 02:54:46 warmerda + * Added logic to convert shapefile name to dbf filename in DBFOpen() + * for convenience. + * + * Revision 1.11 1998/12/31 15:30:34 warmerda + * Improved the interchangability of numeric and string attributes. Add + * white space trimming option for attributes. + * + * Revision 1.10 1998/12/03 16:36:44 warmerda + * Use r+b instead of rb+ for binary access. + * + * Revision 1.9 1998/12/03 15:34:23 warmerda + * Updated copyright message. + * + * Revision 1.8 1997/12/04 15:40:15 warmerda + * Added newline character after field definitions. + * + * Revision 1.7 1997/03/06 14:02:10 warmerda + * Ensure bUpdated is initialized. + * + * Revision 1.6 1996/02/12 04:54:41 warmerda + * Ensure that DBFWriteAttribute() returns TRUE if it succeeds. + * + * Revision 1.5 1995/10/21 03:15:12 warmerda + * Changed to use binary file access, and ensure that the + * field name field is zero filled, and limited to 10 chars. + * + * Revision 1.4 1995/08/24 18:10:42 warmerda + * Added use of SfRealloc() to avoid pre-ANSI realloc() functions such + * as on the Sun. + * + * Revision 1.3 1995/08/04 03:15:16 warmerda + * Fixed up header. + * + * Revision 1.2 1995/08/04 03:14:43 warmerda + * Added header. + */ + +/*static char rcsid[] = + "$Id: dbfopen.c,v 1.3 2006/07/13 03:27:54 robertl Exp $";*/ + +#include "shapefil.h" +#include "config.h" + +#if SHAPELIB_ENABLED + +#include +#include +#include +#include + +#ifndef FALSE +# define FALSE 0 +# define TRUE 1 +#endif + +static int nStringFieldLen = 0; +static char * pszStringField = NULL; + +/************************************************************************/ +/* SfRealloc() */ +/* */ +/* A realloc cover function that will access a NULL pointer as */ +/* a valid input. */ +/************************************************************************/ + +static void * SfRealloc( void * pMem, int nNewSize ) + +{ + if( pMem == NULL ) + return( (void *) malloc(nNewSize) ); + else + return( (void *) realloc(pMem,nNewSize) ); +} + +/************************************************************************/ +/* DBFWriteHeader() */ +/* */ +/* This is called to write out the file header, and field */ +/* descriptions before writing any actual data records. This */ +/* also computes all the DBFDataSet field offset/size/decimals */ +/* and so forth values. */ +/************************************************************************/ + +static void DBFWriteHeader(DBFHandle psDBF) + +{ + unsigned char abyHeader[XBASE_FLDHDR_SZ]; + int i; + + if( !psDBF->bNoHeader ) + return; + + psDBF->bNoHeader = FALSE; + +/* -------------------------------------------------------------------- */ +/* Initialize the file header information. */ +/* -------------------------------------------------------------------- */ + for( i = 0; i < XBASE_FLDHDR_SZ; i++ ) + abyHeader[i] = 0; + + abyHeader[0] = 0x03; /* memo field? - just copying */ + + /* date updated on close, record count preset at zero */ + + abyHeader[8] = psDBF->nHeaderLength % 256; + abyHeader[9] = psDBF->nHeaderLength / 256; + + abyHeader[10] = psDBF->nRecordLength % 256; + abyHeader[11] = psDBF->nRecordLength / 256; + +/* -------------------------------------------------------------------- */ +/* Write the initial 32 byte file header, and all the field */ +/* descriptions. */ +/* -------------------------------------------------------------------- */ + fseek( psDBF->fp, 0, 0 ); + fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp ); + fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp ); + +/* -------------------------------------------------------------------- */ +/* Write out the newline character if there is room for it. */ +/* -------------------------------------------------------------------- */ + if( psDBF->nHeaderLength > 32*psDBF->nFields + 32 ) + { + char cNewline; + + cNewline = 0x0d; + fwrite( &cNewline, 1, 1, psDBF->fp ); + } +} + +/************************************************************************/ +/* DBFFlushRecord() */ +/* */ +/* Write out the current record if there is one. */ +/************************************************************************/ + +static void DBFFlushRecord( DBFHandle psDBF ) + +{ + int nRecordOffset; + + if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 ) + { + psDBF->bCurrentRecordModified = FALSE; + + nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord + + psDBF->nHeaderLength; + + fseek( psDBF->fp, nRecordOffset, 0 ); + fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); + } +} + +/************************************************************************/ +/* DBFOpen() */ +/* */ +/* Open a .dbf file. */ +/************************************************************************/ + +DBFHandle SHPAPI_CALL +DBFOpen( const char * pszFilename, const char * pszAccess ) + +{ + DBFHandle psDBF; + unsigned char *pabyBuf; + int nFields, nHeadLen, nRecLen, iField, i; + char *pszBasename, *pszFullname; + +/* -------------------------------------------------------------------- */ +/* We only allow the access strings "rb" and "r+". */ +/* -------------------------------------------------------------------- */ + if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0 + && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0 + && strcmp(pszAccess,"r+b") != 0 ) + return( NULL ); + + if( strcmp(pszAccess,"r") == 0 ) + pszAccess = "rb"; + + if( strcmp(pszAccess,"r+") == 0 ) + pszAccess = "rb+"; + +/* -------------------------------------------------------------------- */ +/* Compute the base (layer) name. If there is any extension */ +/* on the passed in filename we will strip it off. */ +/* -------------------------------------------------------------------- */ + pszBasename = (char *) malloc(strlen(pszFilename)+5); + strcpy( pszBasename, pszFilename ); + for( i = strlen(pszBasename)-1; + i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' + && pszBasename[i] != '\\'; + i-- ) {} + + if( pszBasename[i] == '.' ) + pszBasename[i] = '\0'; + + pszFullname = (char *) malloc(strlen(pszBasename) + 5); + sprintf( pszFullname, "%s.dbf", pszBasename ); + + psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) ); + psDBF->fp = fopen( pszFullname, pszAccess ); + + if( psDBF->fp == NULL ) + { + sprintf( pszFullname, "%s.DBF", pszBasename ); + psDBF->fp = fopen(pszFullname, pszAccess ); + } + + free( pszBasename ); + free( pszFullname ); + + if( psDBF->fp == NULL ) + { + free( psDBF ); + return( NULL ); + } + + psDBF->bNoHeader = FALSE; + psDBF->nCurrentRecord = -1; + psDBF->bCurrentRecordModified = FALSE; + +/* -------------------------------------------------------------------- */ +/* Read Table Header info */ +/* -------------------------------------------------------------------- */ + pabyBuf = (unsigned char *) malloc(500); + if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 ) + { + fclose( psDBF->fp ); + free( pabyBuf ); + free( psDBF ); + return NULL; + } + + psDBF->nRecords = + pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256; + + psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256; + psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256; + + psDBF->nFields = nFields = (nHeadLen - 32) / 32; + + psDBF->pszCurrentRecord = (char *) malloc(nRecLen); + +/* -------------------------------------------------------------------- */ +/* Read in Field Definitions */ +/* -------------------------------------------------------------------- */ + + pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen); + psDBF->pszHeader = (char *) pabyBuf; + + fseek( psDBF->fp, 32, 0 ); + if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 ) + { + fclose( psDBF->fp ); + free( pabyBuf ); + free( psDBF ); + return NULL; + } + + psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields); + psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields); + psDBF->panFieldDecimals = (int *) malloc(sizeof(int) * nFields); + psDBF->pachFieldType = (char *) malloc(sizeof(char) * nFields); + + for( iField = 0; iField < nFields; iField++ ) + { + unsigned char *pabyFInfo; + + pabyFInfo = pabyBuf+iField*32; + + if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' ) + { + psDBF->panFieldSize[iField] = pabyFInfo[16]; + psDBF->panFieldDecimals[iField] = pabyFInfo[17]; + } + else + { + psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256; + psDBF->panFieldDecimals[iField] = 0; + } + + psDBF->pachFieldType[iField] = (char) pabyFInfo[11]; + if( iField == 0 ) + psDBF->panFieldOffset[iField] = 1; + else + psDBF->panFieldOffset[iField] = + psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1]; + } + + return( psDBF ); +} + +/************************************************************************/ +/* DBFClose() */ +/************************************************************************/ + +void SHPAPI_CALL +DBFClose(DBFHandle psDBF) +{ +/* -------------------------------------------------------------------- */ +/* Write out header if not already written. */ +/* -------------------------------------------------------------------- */ + if( psDBF->bNoHeader ) + DBFWriteHeader( psDBF ); + + DBFFlushRecord( psDBF ); + +/* -------------------------------------------------------------------- */ +/* Update last access date, and number of records if we have */ +/* write access. */ +/* -------------------------------------------------------------------- */ + if( psDBF->bUpdated ) + { + unsigned char abyFileHeader[32]; + + fseek( psDBF->fp, 0, 0 ); + fread( abyFileHeader, 32, 1, psDBF->fp ); + + abyFileHeader[1] = 95; /* YY */ + abyFileHeader[2] = 7; /* MM */ + abyFileHeader[3] = 26; /* DD */ + + abyFileHeader[4] = psDBF->nRecords % 256; + abyFileHeader[5] = (psDBF->nRecords/256) % 256; + abyFileHeader[6] = (psDBF->nRecords/(256*256)) % 256; + abyFileHeader[7] = (psDBF->nRecords/(256*256*256)) % 256; + + fseek( psDBF->fp, 0, 0 ); + fwrite( abyFileHeader, 32, 1, psDBF->fp ); + } + +/* -------------------------------------------------------------------- */ +/* Close, and free resources. */ +/* -------------------------------------------------------------------- */ + fclose( psDBF->fp ); + + if( psDBF->panFieldOffset != NULL ) + { + free( psDBF->panFieldOffset ); + free( psDBF->panFieldSize ); + free( psDBF->panFieldDecimals ); + free( psDBF->pachFieldType ); + } + + free( psDBF->pszHeader ); + free( psDBF->pszCurrentRecord ); + + free( psDBF ); + + if( pszStringField != NULL ) + { + free( pszStringField ); + pszStringField = NULL; + nStringFieldLen = 0; + } +} + +/************************************************************************/ +/* DBFCreate() */ +/* */ +/* Create a new .dbf file. */ +/************************************************************************/ + +DBFHandle SHPAPI_CALL +DBFCreate( const char * pszFilename ) + +{ + DBFHandle psDBF; + FILE *fp; + char *pszFullname, *pszBasename; + int i; + +/* -------------------------------------------------------------------- */ +/* Compute the base (layer) name. If there is any extension */ +/* on the passed in filename we will strip it off. */ +/* -------------------------------------------------------------------- */ + pszBasename = (char *) malloc(strlen(pszFilename)+5); + strcpy( pszBasename, pszFilename ); + for( i = strlen(pszBasename)-1; + i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' + && pszBasename[i] != '\\'; + i-- ) {} + + if( pszBasename[i] == '.' ) + pszBasename[i] = '\0'; + + pszFullname = (char *) malloc(strlen(pszBasename) + 5); + sprintf( pszFullname, "%s.dbf", pszBasename ); + free( pszBasename ); + +/* -------------------------------------------------------------------- */ +/* Create the file. */ +/* -------------------------------------------------------------------- */ + fp = fopen( pszFullname, "wb" ); + if( fp == NULL ) + return( NULL ); + + fputc( 0, fp ); + fclose( fp ); + + fp = fopen( pszFullname, "rb+" ); + if( fp == NULL ) + return( NULL ); + + free( pszFullname ); + +/* -------------------------------------------------------------------- */ +/* Create the info structure. */ +/* -------------------------------------------------------------------- */ + psDBF = (DBFHandle) malloc(sizeof(DBFInfo)); + + psDBF->fp = fp; + psDBF->nRecords = 0; + psDBF->nFields = 0; + psDBF->nRecordLength = 1; + psDBF->nHeaderLength = 33; + + psDBF->panFieldOffset = NULL; + psDBF->panFieldSize = NULL; + psDBF->panFieldDecimals = NULL; + psDBF->pachFieldType = NULL; + psDBF->pszHeader = NULL; + + psDBF->nCurrentRecord = -1; + psDBF->bCurrentRecordModified = FALSE; + psDBF->pszCurrentRecord = NULL; + + psDBF->bNoHeader = TRUE; + + return( psDBF ); +} + +/************************************************************************/ +/* DBFAddField() */ +/* */ +/* Add a field to a newly created .dbf file before any records */ +/* are written. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFAddField(DBFHandle psDBF, const char * pszFieldName, + DBFFieldType eType, int nWidth, int nDecimals ) + +{ + char *pszFInfo; + int i; + +/* -------------------------------------------------------------------- */ +/* Do some checking to ensure we can add records to this file. */ +/* -------------------------------------------------------------------- */ + if( psDBF->nRecords > 0 ) + return( -1 ); + + if( !psDBF->bNoHeader ) + return( -1 ); + + if( eType != FTDouble && nDecimals != 0 ) + return( -1 ); + + if( nWidth < 1 ) + return -1; + +/* -------------------------------------------------------------------- */ +/* SfRealloc all the arrays larger to hold the additional field */ +/* information. */ +/* -------------------------------------------------------------------- */ + psDBF->nFields++; + + psDBF->panFieldOffset = (int *) + SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ); + + psDBF->panFieldSize = (int *) + SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields ); + + psDBF->panFieldDecimals = (int *) + SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ); + + psDBF->pachFieldType = (char *) + SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields ); + +/* -------------------------------------------------------------------- */ +/* Assign the new field information fields. */ +/* -------------------------------------------------------------------- */ + psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength; + psDBF->nRecordLength += nWidth; + psDBF->panFieldSize[psDBF->nFields-1] = nWidth; + psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals; + + if( eType == FTLogical ) + psDBF->pachFieldType[psDBF->nFields-1] = 'L'; + else if( eType == FTString ) + psDBF->pachFieldType[psDBF->nFields-1] = 'C'; + else + psDBF->pachFieldType[psDBF->nFields-1] = 'N'; + +/* -------------------------------------------------------------------- */ +/* Extend the required header information. */ +/* -------------------------------------------------------------------- */ + psDBF->nHeaderLength += 32; + psDBF->bUpdated = FALSE; + + psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32); + + pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1); + + for( i = 0; i < 32; i++ ) + pszFInfo[i] = '\0'; + + if( (int) strlen(pszFieldName) < 10 ) + strncpy( pszFInfo, pszFieldName, strlen(pszFieldName)); + else + strncpy( pszFInfo, pszFieldName, 10); + + pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1]; + + if( eType == FTString ) + { + pszFInfo[16] = nWidth % 256; + pszFInfo[17] = nWidth / 256; + } + else + { + pszFInfo[16] = nWidth; + pszFInfo[17] = nDecimals; + } + +/* -------------------------------------------------------------------- */ +/* Make the current record buffer appropriately larger. */ +/* -------------------------------------------------------------------- */ + psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord, + psDBF->nRecordLength); + + return( psDBF->nFields-1 ); +} + +/************************************************************************/ +/* DBFReadAttribute() */ +/* */ +/* Read one of the attribute fields of a record. */ +/************************************************************************/ + +static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField, + char chReqType ) + +{ + int nRecordOffset; + unsigned char *pabyRec; + void *pReturnField = NULL; + + static double dDoubleField; + +/* -------------------------------------------------------------------- */ +/* Verify selection. */ +/* -------------------------------------------------------------------- */ + if( hEntity < 0 || hEntity >= psDBF->nRecords ) + return( NULL ); + + if( iField < 0 || iField >= psDBF->nFields ) + return( NULL ); + +/* -------------------------------------------------------------------- */ +/* Have we read the record? */ +/* -------------------------------------------------------------------- */ + if( psDBF->nCurrentRecord != hEntity ) + { + DBFFlushRecord( psDBF ); + + nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; + + if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 ) + { + fprintf( stderr, "fseek(%d) failed on DBF file.\n", + nRecordOffset ); + return NULL; + } + + if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, + 1, psDBF->fp ) != 1 ) + { + fprintf( stderr, "fread(%d) failed on DBF file.\n", + psDBF->nRecordLength ); + return NULL; + } + + psDBF->nCurrentRecord = hEntity; + } + + pabyRec = (unsigned char *) psDBF->pszCurrentRecord; + +/* -------------------------------------------------------------------- */ +/* Ensure our field buffer is large enough to hold this buffer. */ +/* -------------------------------------------------------------------- */ + if( psDBF->panFieldSize[iField]+1 > nStringFieldLen ) + { + nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10; + pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen); + } + +/* -------------------------------------------------------------------- */ +/* Extract the requested field. */ +/* -------------------------------------------------------------------- */ + strncpy( pszStringField, + ((const char *) pabyRec) + psDBF->panFieldOffset[iField], + psDBF->panFieldSize[iField] ); + pszStringField[psDBF->panFieldSize[iField]] = '\0'; + + pReturnField = pszStringField; + +/* -------------------------------------------------------------------- */ +/* Decode the field. */ +/* -------------------------------------------------------------------- */ + if( chReqType == 'N' ) + { + dDoubleField = atof(pszStringField); + + pReturnField = &dDoubleField; + } + +/* -------------------------------------------------------------------- */ +/* Should we trim white space off the string attribute value? */ +/* -------------------------------------------------------------------- */ +#ifdef TRIM_DBF_WHITESPACE + else + { + char *pchSrc, *pchDst; + + pchDst = pchSrc = pszStringField; + while( *pchSrc == ' ' ) + pchSrc++; + + while( *pchSrc != '\0' ) + *(pchDst++) = *(pchSrc++); + *pchDst = '\0'; + + while( pchDst != pszStringField && *(--pchDst) == ' ' ) + *pchDst = '\0'; + } +#endif + + return( pReturnField ); +} + +/************************************************************************/ +/* DBFReadIntAttribute() */ +/* */ +/* Read an integer attribute. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField ) + +{ + double *pdValue; + + pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' ); + + if( pdValue == NULL ) + return 0; + else + return( (int) *pdValue ); +} + +/************************************************************************/ +/* DBFReadDoubleAttribute() */ +/* */ +/* Read a double attribute. */ +/************************************************************************/ + +double SHPAPI_CALL +DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField ) + +{ + double *pdValue; + + pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' ); + + if( pdValue == NULL ) + return 0.0; + else + return( *pdValue ); +} + +/************************************************************************/ +/* DBFReadStringAttribute() */ +/* */ +/* Read a string attribute. */ +/************************************************************************/ + +const char SHPAPI_CALL1(*) +DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField ) + +{ + return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) ); +} + +/************************************************************************/ +/* DBFReadLogicalAttribute() */ +/* */ +/* Read a logical attribute. */ +/************************************************************************/ + +const char SHPAPI_CALL1(*) +DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField ) + +{ + return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) ); +} + +/************************************************************************/ +/* DBFIsAttributeNULL() */ +/* */ +/* Return TRUE if value for field is NULL. */ +/* */ +/* Contributed by Jim Matthews. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField ) + +{ + const char *pszValue; + + pszValue = DBFReadStringAttribute( psDBF, iRecord, iField ); + + switch(psDBF->pachFieldType[iField]) + { + case 'N': + case 'F': + /* NULL numeric fields have value "****************" */ + return pszValue[0] == '*'; + + case 'D': + /* NULL date fields have value "00000000" */ + return strncmp(pszValue,"00000000",8) == 0; + + case 'L': + /* NULL boolean fields have value "?" */ + return pszValue[0] == '?'; + + default: + /* empty string fields are considered NULL */ + return strlen(pszValue) == 0; + } +} + +/************************************************************************/ +/* DBFGetFieldCount() */ +/* */ +/* Return the number of fields in this table. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFGetFieldCount( DBFHandle psDBF ) + +{ + return( psDBF->nFields ); +} + +/************************************************************************/ +/* DBFGetRecordCount() */ +/* */ +/* Return the number of records in this table. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFGetRecordCount( DBFHandle psDBF ) + +{ + return( psDBF->nRecords ); +} + +/************************************************************************/ +/* DBFGetFieldInfo() */ +/* */ +/* Return any requested information about the field. */ +/************************************************************************/ + +DBFFieldType SHPAPI_CALL +DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName, + int * pnWidth, int * pnDecimals ) + +{ + if( iField < 0 || iField >= psDBF->nFields ) + return( FTInvalid ); + + if( pnWidth != NULL ) + *pnWidth = psDBF->panFieldSize[iField]; + + if( pnDecimals != NULL ) + *pnDecimals = psDBF->panFieldDecimals[iField]; + + if( pszFieldName != NULL ) + { + int i; + + strncpy( pszFieldName, (char *) psDBF->pszHeader+iField*32, 11 ); + pszFieldName[11] = '\0'; + for( i = 10; i > 0 && pszFieldName[i] == ' '; i-- ) + pszFieldName[i] = '\0'; + } + + if ( psDBF->pachFieldType[iField] == 'L' ) + return( FTLogical); + + else if( psDBF->pachFieldType[iField] == 'N' + || psDBF->pachFieldType[iField] == 'F' + || psDBF->pachFieldType[iField] == 'D' ) + { + if( psDBF->panFieldDecimals[iField] > 0 ) + return( FTDouble ); + else + return( FTInteger ); + } + else + { + return( FTString ); + } +} + +/************************************************************************/ +/* DBFWriteAttribute() */ +/* */ +/* Write an attribute record to the file. */ +/************************************************************************/ + +static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, + void * pValue ) + +{ + int nRecordOffset, i, j, nRetResult = TRUE; + unsigned char *pabyRec; + char szSField[400], szFormat[20]; + +/* -------------------------------------------------------------------- */ +/* Is this a valid record? */ +/* -------------------------------------------------------------------- */ + if( hEntity < 0 || hEntity > psDBF->nRecords ) + return( FALSE ); + + if( psDBF->bNoHeader ) + DBFWriteHeader(psDBF); + +/* -------------------------------------------------------------------- */ +/* Is this a brand new record? */ +/* -------------------------------------------------------------------- */ + if( hEntity == psDBF->nRecords ) + { + DBFFlushRecord( psDBF ); + + psDBF->nRecords++; + for( i = 0; i < psDBF->nRecordLength; i++ ) + psDBF->pszCurrentRecord[i] = ' '; + + psDBF->nCurrentRecord = hEntity; + } + +/* -------------------------------------------------------------------- */ +/* Is this an existing record, but different than the last one */ +/* we accessed? */ +/* -------------------------------------------------------------------- */ + if( psDBF->nCurrentRecord != hEntity ) + { + DBFFlushRecord( psDBF ); + + nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; + + fseek( psDBF->fp, nRecordOffset, 0 ); + fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); + + psDBF->nCurrentRecord = hEntity; + } + + pabyRec = (unsigned char *) psDBF->pszCurrentRecord; + + psDBF->bCurrentRecordModified = TRUE; + psDBF->bUpdated = TRUE; + +/* -------------------------------------------------------------------- */ +/* Translate NULL value to valid DBF file representation. */ +/* */ +/* Contributed by Jim Matthews. */ +/* -------------------------------------------------------------------- */ + if( pValue == NULL ) + { + switch(psDBF->pachFieldType[iField]) + { + case 'N': + case 'F': + /* NULL numeric fields have value "****************" */ + memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*', + psDBF->panFieldSize[iField] ); + break; + + case 'D': + /* NULL date fields have value "00000000" */ + memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0', + psDBF->panFieldSize[iField] ); + break; + + case 'L': + /* NULL boolean fields have value "?" */ + memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?', + psDBF->panFieldSize[iField] ); + break; + + default: + /* empty string fields are considered NULL */ + memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0', + psDBF->panFieldSize[iField] ); + break; + } + return TRUE; + } + +/* -------------------------------------------------------------------- */ +/* Assign all the record fields. */ +/* -------------------------------------------------------------------- */ + switch( psDBF->pachFieldType[iField] ) + { + case 'D': + case 'N': + case 'F': + if( psDBF->panFieldDecimals[iField] == 0 ) + { + int nWidth = psDBF->panFieldSize[iField]; + + if( sizeof(szSField)-2 < nWidth ) + nWidth = sizeof(szSField)-2; + + sprintf( szFormat, "%%%dd", nWidth ); + sprintf(szSField, szFormat, (int) *((double *) pValue) ); + if( (int)strlen(szSField) > psDBF->panFieldSize[iField] ) + { + szSField[psDBF->panFieldSize[iField]] = '\0'; + nRetResult = FALSE; + } + + strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), + szSField, strlen(szSField) ); + } + else + { + int nWidth = psDBF->panFieldSize[iField]; + + if( sizeof(szSField)-2 < nWidth ) + nWidth = sizeof(szSField)-2; + + sprintf( szFormat, "%%%d.%df", + nWidth, psDBF->panFieldDecimals[iField] ); + sprintf(szSField, szFormat, *((double *) pValue) ); + if( (int) strlen(szSField) > psDBF->panFieldSize[iField] ) + { + szSField[psDBF->panFieldSize[iField]] = '\0'; + nRetResult = FALSE; + } + strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), + szSField, strlen(szSField) ); + } + break; + + case 'L': + if (psDBF->panFieldSize[iField] >= 1 && + (*(char*)pValue == 'F' || *(char*)pValue == 'T')) + *(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue; + break; + + default: + if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] ) + { + j = psDBF->panFieldSize[iField]; + nRetResult = FALSE; + } + else + { + memset( pabyRec+psDBF->panFieldOffset[iField], ' ', + psDBF->panFieldSize[iField] ); + j = strlen((char *) pValue); + } + + strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), + (char *) pValue, j ); + break; + } + + return( nRetResult ); +} + +/************************************************************************/ +/* DBFWriteAttributeDirectly() */ +/* */ +/* Write an attribute record to the file, but without any */ +/* reformatting based on type. The provided buffer is written */ +/* as is to the field position in the record. */ +/************************************************************************/ + +int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, + void * pValue ) + +{ + int nRecordOffset, i, j; + unsigned char *pabyRec; + +/* -------------------------------------------------------------------- */ +/* Is this a valid record? */ +/* -------------------------------------------------------------------- */ + if( hEntity < 0 || hEntity > psDBF->nRecords ) + return( FALSE ); + + if( psDBF->bNoHeader ) + DBFWriteHeader(psDBF); + +/* -------------------------------------------------------------------- */ +/* Is this a brand new record? */ +/* -------------------------------------------------------------------- */ + if( hEntity == psDBF->nRecords ) + { + DBFFlushRecord( psDBF ); + + psDBF->nRecords++; + for( i = 0; i < psDBF->nRecordLength; i++ ) + psDBF->pszCurrentRecord[i] = ' '; + + psDBF->nCurrentRecord = hEntity; + } + +/* -------------------------------------------------------------------- */ +/* Is this an existing record, but different than the last one */ +/* we accessed? */ +/* -------------------------------------------------------------------- */ + if( psDBF->nCurrentRecord != hEntity ) + { + DBFFlushRecord( psDBF ); + + nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; + + fseek( psDBF->fp, nRecordOffset, 0 ); + fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); + + psDBF->nCurrentRecord = hEntity; + } + + pabyRec = (unsigned char *) psDBF->pszCurrentRecord; + +/* -------------------------------------------------------------------- */ +/* Assign all the record fields. */ +/* -------------------------------------------------------------------- */ + if( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] ) + j = psDBF->panFieldSize[iField]; + else + { + memset( pabyRec+psDBF->panFieldOffset[iField], ' ', + psDBF->panFieldSize[iField] ); + j = strlen((char *) pValue); + } + + strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), + (char *) pValue, j ); + + psDBF->bCurrentRecordModified = TRUE; + psDBF->bUpdated = TRUE; + + return( TRUE ); +} + +/************************************************************************/ +/* DBFWriteDoubleAttribute() */ +/* */ +/* Write a double attribute. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField, + double dValue ) + +{ + return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) ); +} + +/************************************************************************/ +/* DBFWriteIntegerAttribute() */ +/* */ +/* Write a integer attribute. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField, + int nValue ) + +{ + double dValue = nValue; + + return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) ); +} + +/************************************************************************/ +/* DBFWriteStringAttribute() */ +/* */ +/* Write a string attribute. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFWriteStringAttribute( DBFHandle psDBF, int iRecord, int iField, + const char * pszValue ) + +{ + return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) pszValue ) ); +} + +/************************************************************************/ +/* DBFWriteNULLAttribute() */ +/* */ +/* Write a string attribute. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFWriteNULLAttribute( DBFHandle psDBF, int iRecord, int iField ) + +{ + return( DBFWriteAttribute( psDBF, iRecord, iField, NULL ) ); +} + +/************************************************************************/ +/* DBFWriteLogicalAttribute() */ +/* */ +/* Write a logical attribute. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFWriteLogicalAttribute( DBFHandle psDBF, int iRecord, int iField, + const char lValue) + +{ + return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) (&lValue) ) ); +} + +/************************************************************************/ +/* DBFWriteTuple() */ +/* */ +/* Write an attribute record to the file. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple ) + +{ + int nRecordOffset, i; + unsigned char *pabyRec; + +/* -------------------------------------------------------------------- */ +/* Is this a valid record? */ +/* -------------------------------------------------------------------- */ + if( hEntity < 0 || hEntity > psDBF->nRecords ) + return( FALSE ); + + if( psDBF->bNoHeader ) + DBFWriteHeader(psDBF); + +/* -------------------------------------------------------------------- */ +/* Is this a brand new record? */ +/* -------------------------------------------------------------------- */ + if( hEntity == psDBF->nRecords ) + { + DBFFlushRecord( psDBF ); + + psDBF->nRecords++; + for( i = 0; i < psDBF->nRecordLength; i++ ) + psDBF->pszCurrentRecord[i] = ' '; + + psDBF->nCurrentRecord = hEntity; + } + +/* -------------------------------------------------------------------- */ +/* Is this an existing record, but different than the last one */ +/* we accessed? */ +/* -------------------------------------------------------------------- */ + if( psDBF->nCurrentRecord != hEntity ) + { + DBFFlushRecord( psDBF ); + + nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; + + fseek( psDBF->fp, nRecordOffset, 0 ); + fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); + + psDBF->nCurrentRecord = hEntity; + } + + pabyRec = (unsigned char *) psDBF->pszCurrentRecord; + + memcpy ( pabyRec, pRawTuple, psDBF->nRecordLength ); + + psDBF->bCurrentRecordModified = TRUE; + psDBF->bUpdated = TRUE; + + return( TRUE ); +} + +/************************************************************************/ +/* DBFReadTuple() */ +/* */ +/* Read one of the attribute fields of a record. */ +/************************************************************************/ + +const char SHPAPI_CALL1(*) +DBFReadTuple(DBFHandle psDBF, int hEntity ) + +{ + int nRecordOffset; + unsigned char *pabyRec; + static char *pReturnTuple = NULL; + + static int nTupleLen = 0; + +/* -------------------------------------------------------------------- */ +/* Have we read the record? */ +/* -------------------------------------------------------------------- */ + if( hEntity < 0 || hEntity >= psDBF->nRecords ) + return( NULL ); + + if( psDBF->nCurrentRecord != hEntity ) + { + DBFFlushRecord( psDBF ); + + nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; + + fseek( psDBF->fp, nRecordOffset, 0 ); + fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); + + psDBF->nCurrentRecord = hEntity; + } + + pabyRec = (unsigned char *) psDBF->pszCurrentRecord; + + if ( nTupleLen < psDBF->nRecordLength) { + nTupleLen = psDBF->nRecordLength; + pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength); + } + + memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength ); + + return( pReturnTuple ); +} + +/************************************************************************/ +/* DBFCloneEmpty() */ +/* */ +/* Read one of the attribute fields of a record. */ +/************************************************************************/ + +DBFHandle SHPAPI_CALL +DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ) +{ + DBFHandle newDBF; + + newDBF = DBFCreate ( pszFilename ); + if ( newDBF == NULL ) return ( NULL ); + + newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields ); + memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields ); + + newDBF->nFields = psDBF->nFields; + newDBF->nRecordLength = psDBF->nRecordLength; + newDBF->nHeaderLength = 32 * (psDBF->nFields+1); + + newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields ); + memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ); + newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields ); + memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields ); + newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields ); + memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ); + newDBF->pachFieldType = (char *) malloc ( sizeof(int) * psDBF->nFields ); + memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields ); + + newDBF->bNoHeader = TRUE; + newDBF->bUpdated = TRUE; + + DBFWriteHeader ( newDBF ); + DBFClose ( newDBF ); + + newDBF = DBFOpen ( pszFilename, "rb+" ); + + return ( newDBF ); +} + +/************************************************************************/ +/* DBFGetNativeFieldType() */ +/* */ +/* Return the DBase field type for the specified field. */ +/* */ +/* Value can be one of: 'C' (String), 'D' (Date), 'F' (Float), */ +/* 'N' (Numeric, with or without decimal), */ +/* 'L' (Logical), */ +/* 'M' (Memo: 10 digits .DBT block ptr) */ +/************************************************************************/ + +char SHPAPI_CALL +DBFGetNativeFieldType( DBFHandle psDBF, int iField ) + +{ + if( iField >=0 && iField < psDBF->nFields ) + return psDBF->pachFieldType[iField]; + + return ' '; +} + +/************************************************************************/ +/* str_to_upper() */ +/************************************************************************/ + +static void str_to_upper (char *string) +{ + int len; + short i = -1; + + len = strlen (string); + + while (++i < len) + if (isalpha(string[i]) && islower(string[i])) + string[i] = toupper ((int)string[i]); +} + +/************************************************************************/ +/* DBFGetFieldIndex() */ +/* */ +/* Get the index number for a field in a .dbf file. */ +/* */ +/* Contributed by Jim Matthews. */ +/************************************************************************/ + +int SHPAPI_CALL +DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName) + +{ + char name[12], name1[12], name2[12]; + int i; + + strncpy(name1, pszFieldName,11); + name1[11] = '\0'; + str_to_upper(name1); + + for( i = 0; i < DBFGetFieldCount(psDBF); i++ ) + { + DBFGetFieldInfo( psDBF, i, name, NULL, NULL ); + strncpy(name2,name,11); + str_to_upper(name2); + + if(!strncmp(name1,name2,10)) + return(i); + } + return(-1); +} +#endif diff --git a/shapelib/shapefil.h b/shapelib/shapefil.h new file mode 100644 index 000000000..00d7d0d2b --- /dev/null +++ b/shapelib/shapefil.h @@ -0,0 +1,490 @@ +#ifndef _SHAPEFILE_H_INCLUDED +#define _SHAPEFILE_H_INCLUDED + +/****************************************************************************** + * $Id: shapefil.h,v 1.2 2004/09/27 01:13:58 robertl Exp $ + * + * Project: Shapelib + * Purpose: Primary include file for Shapelib. + * Author: Frank Warmerdam, warmerdam@pobox.com + * + ****************************************************************************** + * Copyright (c) 1999, Frank Warmerdam + * + * This software is available under the following "MIT Style" license, + * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This + * option is discussed in more detail in shapelib.html. + * + * -- + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * $Log: shapefil.h,v $ + * Revision 1.2 2004/09/27 01:13:58 robertl + * warning fixes in shapelib. From Alexander Stohr. + * + * Revision 1.1 2004/09/20 17:22:55 robertl + * Bring in shapefil.h. + * + * Revision 1.26 2002/09/29 00:00:08 warmerda + * added FTLogical and logical attribute read/write calls + * + * Revision 1.25 2002/05/07 13:46:30 warmerda + * added DBFWriteAttributeDirectly(). + * + * Revision 1.24 2002/04/10 16:59:54 warmerda + * added SHPRewindObject + * + * Revision 1.23 2002/01/15 14:36:07 warmerda + * updated email address + * + * Revision 1.22 2002/01/15 14:32:00 warmerda + * try to improve SHPAPI_CALL docs + * + * Revision 1.21 2001/11/01 16:29:55 warmerda + * move pabyRec into SHPInfo for thread safety + * + * Revision 1.20 2001/07/20 13:06:02 warmerda + * fixed SHPAPI attribute for SHPTreeFindLikelyShapes + * + * Revision 1.19 2001/05/31 19:20:13 warmerda + * added DBFGetFieldIndex() + * + * Revision 1.18 2001/05/31 18:15:40 warmerda + * Added support for NULL fields in DBF files + * + * Revision 1.17 2001/05/23 13:36:52 warmerda + * added use of SHPAPI_CALL + * + * Revision 1.16 2000/09/25 14:15:59 warmerda + * added DBFGetNativeFieldType() + * + * Revision 1.15 2000/02/16 16:03:51 warmerda + * added null shape support + * + * Revision 1.14 1999/11/05 14:12:05 warmerda + * updated license terms + * + * Revision 1.13 1999/06/02 18:24:21 warmerda + * added trimming code + * + * Revision 1.12 1999/06/02 17:56:12 warmerda + * added quad'' subnode support for trees + * + * Revision 1.11 1999/05/18 19:11:11 warmerda + * Added example searching capability + * + * Revision 1.10 1999/05/18 17:49:38 warmerda + * added initial quadtree support + * + * Revision 1.9 1999/05/11 03:19:28 warmerda + * added new Tuple api, and improved extension handling - add from candrsn + * + * Revision 1.8 1999/03/23 17:22:27 warmerda + * Added extern "C" protection for C++ users of shapefil.h. + * + * Revision 1.7 1998/12/31 15:31:07 warmerda + * Added the TRIM_DBF_WHITESPACE and DISABLE_MULTIPATCH_MEASURE options. + * + * Revision 1.6 1998/12/03 15:48:15 warmerda + * Added SHPCalculateExtents(). + * + * Revision 1.5 1998/11/09 20:57:16 warmerda + * Altered SHPGetInfo() call. + * + * Revision 1.4 1998/11/09 20:19:33 warmerda + * Added 3D support, and use of SHPObject. + * + * Revision 1.3 1995/08/23 02:24:05 warmerda + * Added support for reading bounds. + * + * Revision 1.2 1995/08/04 03:17:39 warmerda + * Added header. + * + */ + +#include + +#ifdef USE_DBMALLOC +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************/ +/* Configuration options. */ +/************************************************************************/ + +/* -------------------------------------------------------------------- */ +/* Should the DBFReadStringAttribute() strip leading and */ +/* trailing white space? */ +/* -------------------------------------------------------------------- */ +#define TRIM_DBF_WHITESPACE + +/* -------------------------------------------------------------------- */ +/* Should we write measure values to the Multipatch object? */ +/* Reportedly ArcView crashes if we do write it, so for now it */ +/* is disabled. */ +/* -------------------------------------------------------------------- */ +#define DISABLE_MULTIPATCH_MEASURE + +/* -------------------------------------------------------------------- */ +/* SHPAPI_CALL */ +/* */ +/* The following two macros are present to allow forcing */ +/* various calling conventions on the Shapelib API. */ +/* */ +/* To force __stdcall conventions (needed to call Shapelib */ +/* from Visual Basic and/or Dephi I believe) the makefile could */ +/* be modified to define: */ +/* */ +/* /DSHPAPI_CALL=__stdcall */ +/* */ +/* If it is desired to force export of the Shapelib API without */ +/* using the shapelib.def file, use the following definition. */ +/* */ +/* /DSHAPELIB_DLLEXPORT */ +/* */ +/* To get both at once it will be necessary to hack this */ +/* include file to define: */ +/* */ +/* #define SHPAPI_CALL __declspec(dllexport) __stdcall */ +/* #define SHPAPI_CALL1 __declspec(dllexport) * __stdcall */ +/* */ +/* The complexity of the situtation is partly caused by the */ +/* peculiar requirement of Visual C++ that __stdcall appear */ +/* after any "*"'s in the return value of a function while the */ +/* __declspec(dllexport) must appear before them. */ +/* -------------------------------------------------------------------- */ + +#ifdef SHAPELIB_DLLEXPORT +# define SHPAPI_CALL __declspec(dllexport) +# define SHPAPI_CALL1(x) __declspec(dllexport) x +#endif + +#ifndef SHPAPI_CALL +# define SHPAPI_CALL +#endif + +#ifndef SHPAPI_CALL1 +# define SHPAPI_CALL1(x) x SHPAPI_CALL +#endif + +/************************************************************************/ +/* SHP Support. */ +/************************************************************************/ +typedef struct +{ + FILE *fpSHP; + FILE *fpSHX; + + int nShapeType; /* SHPT_* */ + + int nFileSize; /* SHP file */ + + int nRecords; + int nMaxRecords; + int *panRecOffset; + int *panRecSize; + + double adBoundsMin[4]; + double adBoundsMax[4]; + + int bUpdated; + + unsigned char *pabyRec; + int nBufSize; +} SHPInfo; + +typedef SHPInfo * SHPHandle; + +/* -------------------------------------------------------------------- */ +/* Shape types (nSHPType) */ +/* -------------------------------------------------------------------- */ +#define SHPT_NULL 0 +#define SHPT_POINT 1 +#define SHPT_ARC 3 +#define SHPT_POLYGON 5 +#define SHPT_MULTIPOINT 8 +#define SHPT_POINTZ 11 +#define SHPT_ARCZ 13 +#define SHPT_POLYGONZ 15 +#define SHPT_MULTIPOINTZ 18 +#define SHPT_POINTM 21 +#define SHPT_ARCM 23 +#define SHPT_POLYGONM 25 +#define SHPT_MULTIPOINTM 28 +#define SHPT_MULTIPATCH 31 + + +/* -------------------------------------------------------------------- */ +/* Part types - everything but SHPT_MULTIPATCH just uses */ +/* SHPP_RING. */ +/* -------------------------------------------------------------------- */ + +#define SHPP_TRISTRIP 0 +#define SHPP_TRIFAN 1 +#define SHPP_OUTERRING 2 +#define SHPP_INNERRING 3 +#define SHPP_FIRSTRING 4 +#define SHPP_RING 5 + +/* -------------------------------------------------------------------- */ +/* SHPObject - represents on shape (without attributes) read */ +/* from the .shp file. */ +/* -------------------------------------------------------------------- */ +typedef struct +{ + int nSHPType; + + int nShapeId; /* -1 is unknown/unassigned */ + + int nParts; + int *panPartStart; + int *panPartType; + + int nVertices; + double *padfX; + double *padfY; + double *padfZ; + double *padfM; + + double dfXMin; + double dfYMin; + double dfZMin; + double dfMMin; + + double dfXMax; + double dfYMax; + double dfZMax; + double dfMMax; +} SHPObject; + +/* -------------------------------------------------------------------- */ +/* SHP API Prototypes */ +/* -------------------------------------------------------------------- */ +SHPHandle SHPAPI_CALL + SHPOpen( const char * pszShapeFile, const char * pszAccess ); +SHPHandle SHPAPI_CALL + SHPCreate( const char * pszShapeFile, int nShapeType ); +void SHPAPI_CALL + SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType, + double * padfMinBound, double * padfMaxBound ); + +SHPObject SHPAPI_CALL1(*) + SHPReadObject( SHPHandle hSHP, int iShape ); +int SHPAPI_CALL + SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject ); + +void SHPAPI_CALL + SHPDestroyObject( SHPObject * psObject ); +void SHPAPI_CALL + SHPComputeExtents( SHPObject * psObject ); +SHPObject SHPAPI_CALL1(*) + SHPCreateObject( int nSHPType, int nShapeId, + int nParts, int * panPartStart, int * panPartType, + int nVertices, const double * padfX, const double * padfY, + const double * padfZ, const double * padfM ); +SHPObject SHPAPI_CALL1(*) + SHPCreateSimpleObject( int nSHPType, int nVertices, + const double * padfX, const double * padfY, const double * padfZ ); + +int SHPAPI_CALL + SHPRewindObject( SHPHandle hSHP, SHPObject * psObject ); + +void SHPAPI_CALL + SHPClose( SHPHandle hSHP ); + +const char SHPAPI_CALL1(*) + SHPTypeName( int nSHPType ); +const char SHPAPI_CALL1(*) + SHPPartTypeName( int nPartType ); + +/* -------------------------------------------------------------------- */ +/* Shape quadtree indexing API. */ +/* -------------------------------------------------------------------- */ + +/* this can be two or four for binary or quad tree */ +#define MAX_SUBNODE 4 + +typedef struct shape_tree_node +{ + /* region covered by this node */ + double adfBoundsMin[4]; + double adfBoundsMax[4]; + + /* list of shapes stored at this node. The papsShapeObj pointers + or the whole list can be NULL */ + int nShapeCount; + int *panShapeIds; + SHPObject **papsShapeObj; + + int nSubNodes; + struct shape_tree_node *apsSubNode[MAX_SUBNODE]; + +} SHPTreeNode; + +typedef struct +{ + SHPHandle hSHP; + + int nMaxDepth; + int nDimension; + + SHPTreeNode *psRoot; +} SHPTree; + +SHPTree SHPAPI_CALL1(*) + SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth, + double *padfBoundsMin, double *padfBoundsMax ); +void SHPAPI_CALL + SHPDestroyTree( SHPTree * hTree ); + +int SHPAPI_CALL + SHPWriteTree( SHPTree *hTree, const char * pszFilename ); +SHPTree SHPAPI_CALL + SHPReadTree( const char * pszFilename ); + +int SHPAPI_CALL + SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject ); +int SHPAPI_CALL + SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject ); +int SHPAPI_CALL + SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId ); + +void SHPAPI_CALL + SHPTreeTrimExtraNodes( SHPTree * hTree ); + +int SHPAPI_CALL1(*) + SHPTreeFindLikelyShapes( SHPTree * hTree, + double * padfBoundsMin, + double * padfBoundsMax, + int * ); +int SHPAPI_CALL + SHPCheckBoundsOverlap( double *, double *, double *, double *, int ); + +/************************************************************************/ +/* DBF Support. */ +/************************************************************************/ +typedef struct +{ + FILE *fp; + + int nRecords; + + int nRecordLength; + int nHeaderLength; + int nFields; + int *panFieldOffset; + int *panFieldSize; + int *panFieldDecimals; + char *pachFieldType; + + char *pszHeader; + + int nCurrentRecord; + int bCurrentRecordModified; + char *pszCurrentRecord; + + int bNoHeader; + int bUpdated; +} DBFInfo; + +typedef DBFInfo * DBFHandle; + +typedef enum { + FTString, + FTInteger, + FTDouble, + FTLogical, + FTInvalid +} DBFFieldType; + +#define XBASE_FLDHDR_SZ 32 + +DBFHandle SHPAPI_CALL + DBFOpen( const char * pszDBFFile, const char * pszAccess ); +DBFHandle SHPAPI_CALL + DBFCreate( const char * pszDBFFile ); + +int SHPAPI_CALL + DBFGetFieldCount( DBFHandle psDBF ); +int SHPAPI_CALL + DBFGetRecordCount( DBFHandle psDBF ); +int SHPAPI_CALL + DBFAddField( DBFHandle hDBF, const char * pszFieldName, + DBFFieldType eType, int nWidth, int nDecimals ); + +DBFFieldType SHPAPI_CALL + DBFGetFieldInfo( DBFHandle psDBF, int iField, + char * pszFieldName, int * pnWidth, int * pnDecimals ); + +int SHPAPI_CALL + DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName); + +int SHPAPI_CALL + DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField ); +double SHPAPI_CALL + DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField ); +const char SHPAPI_CALL1(*) + DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField ); +const char SHPAPI_CALL1(*) + DBFReadLogicalAttribute( DBFHandle hDBF, int iShape, int iField ); +int SHPAPI_CALL + DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField ); + +int SHPAPI_CALL + DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField, + int nFieldValue ); +int SHPAPI_CALL + DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField, + double dFieldValue ); +int SHPAPI_CALL + DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField, + const char * pszFieldValue ); +int SHPAPI_CALL + DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField ); + +int SHPAPI_CALL + DBFWriteLogicalAttribute( DBFHandle hDBF, int iShape, int iField, + const char lFieldValue); +int SHPAPI_CALL + DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, + void * pValue ); +const char SHPAPI_CALL1(*) + DBFReadTuple(DBFHandle psDBF, int hEntity ); +int SHPAPI_CALL + DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple ); + +DBFHandle SHPAPI_CALL + DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ); + +void SHPAPI_CALL + DBFClose( DBFHandle hDBF ); +char SHPAPI_CALL + DBFGetNativeFieldType( DBFHandle hDBF, int iField ); + +#ifdef __cplusplus +} +#endif + +#endif /* ndef _SHAPEFILE_H_INCLUDED */ diff --git a/shapelib/shapelib.html b/shapelib/shapelib.html new file mode 100644 index 000000000..4372d1d6c --- /dev/null +++ b/shapelib/shapelib.html @@ -0,0 +1,334 @@ + + +Shapefile C Library V1.2 + + + +

    Shapefile C Library V1.2

    + +

    Purpose

    + +The Shapefile C Library provides the ability to write simple C programs +for reading, writing and updating (to a limited extent) ESRI Shapefiles, +and the associated attribute file (.dbf).

    + +

    Manifest

    + +
      +
    • shapelib.html: This file - general documentation on the +Shapefile C Library.

      + +

    • shp_api.html: Documentation +for the API for accessing the .shp/.shx files.

      + +

    • dbf_api.html: Documentation +for the API for accessing the .dbf attribute files.

      + +

    • shpopen.c: C code for access to .shp/.shx vertex files.

      + +

    • dbfopen.c: C code for access to .dbf attribute file.

      + +

    • shapefil.h: Include file defining all the services of dbfopen.c +and shpopen.c.

      + +

    • contrib/: A directory of "in progress" contributed programs +from Carl Anderson.

      + +

    • dbfcreate.c: Simple example program for creating a new .dbf file. +

      + +

    • dbfadd.c: + Simple example program for adding a record to a .dbf file.

      + +

    • dbfdump.c: Simple example program for displaying the contents of + a .dbf file.

      + +

    • shpcreate.c: Simple example program for creating a new .shp and +.shx file.

      + +

    • shpadd.c: Simple example program for adding a shape to an existing + shape file.

      + +

    • shpdump.c: Simple program for dumping all the vertices in a + shapefile with an indicating of the parts.

      + +

    • shputils.c: Complex contributed program capable of clipping and + appending + shapefiles as well as a few other things. Type shputils + after building to get a full usage message.

      + +

    • Makefile: A simple makefile to compile the library and example + programs.

      + +

    • makeshape.sh: A simple script for running some of the example +programs.

      + +

    • shptest.c: A simple test harnass to generate each of the supported + types of shapefiles.

      + + +

    • shptree.c: Implements a simple quadtree algorithm for fast +spatial searches of shapefiles.

      + +

    • shptreedump.c: A simple mainly showing information on quad +trees build using the quad tree api.

      + +

    • stream1.sh - A test script, which should produce stream1.out. +Note this will only work if you have the example data downloaded.

      + +

    • stream1.out: Expected output of stream1.sh test script.

      + +

    • stream2.sh: A test script, which should produce stream2.out.

      + +

    • stream2.out: Expected output of stream2.sh test script.

      + +

    • pyshapelib-0.1: Prototype contributed Python bindings.

      + +

    + +

    What is a Shapefile?

    + +If you don't know, you probably don't need this library. The Shapefile +format is a new working and interchange format promulagated by ESRI +(http://www.esri.com/) for simple vector data with attributes. It is +apparently the only file format that can be edited in ARCView 2/3, and can +also be exported and imported in Arc/Info.

    + +An excellent white paper on the shapefile format is available from ESRI, +but it is .pdf format, so you will need Adobe Acrobat to browse it.

    + +The file format actually consists of three files.

    + +

    +XXX.shp - holds the actual vertices.
    +XXX.shx - hold index data pointing to the structures in the .shp file.
    +XXX.dbf - holds the attributes in xBase (dBase) format.  
    +
    + +

    Release Notes

    + +To get notification of new releases of Shapelib subscribe to +the project at www.freshmeat.net. This is currently the only reliable +way of finding out about new releases since there is no shapelib specific +mailing list.

    + +Release 1.2.10: Added SHPRewindObject() function, and shprewind utility +program. Added FTLogical, DBFReadLogicalAttribute() and +DBFWriteLogicalAttribute() (thanks to Olek Neyman).

    + +Release 1.2.9: Good support for reading and writing NULL fields +in .dbf files, good support for NULL shapes and addition of the +DBFGetFieldIndex() functions (all contributed by Jim Matthews).

    + +An upgraded shputils.c has been contributed by Bill Miller. Daniel +Morissette contributed DBFGetNativeFieldType(). Better error checking +for disk errors in dbfopen.c. Various other bug fixes and safety improvements. +

    + +Release 1.2.8: Added hacked libtool support (supplied by Jan) +and "rpm ready" install logic.

    + +Release 1.2.7: Fix record size (was 4 bytes too long). Modify +SHPReadObject() to handle null shapes properly. Use atof() instead of +sscanf(). Support .DBF as well as .dbf.

    + +Release 1.2.6: Now available under old MIT style license, or at the +users option, LGPL. Added the contrib directory of stuff from Carl Anderson +and the shptree.c API for quadtree based spatial searches.

    + +Release 1.2.5: SHPOpen() now forcably uses "rb" or "r+b" access string +to avoid common mistakes on Windows. Also fixed a serious bug with .dbf +files with a 'F' field type.

    + +Release 1.2.4: DBFOpen() will now automatically translate a .shp +extension to .dbf for convenience. SHPOpen() will try datasets with lower +and uppercase extension. DBFAddField() now returns the field number, +not TRUE/FALSE.

    + +Release 1.2.3: Disable writing measures to multi-patches as ArcView +seems to puke on them (as reported by Monika Sester). Add white space +trimming, and string/numeric attribute interchangability in DBF API +as suggested by Steve Lime. Dbfdump was updated to include several +reporting options.

    + +Release 1.2.2: Added proper support for multipatch (reading and +writing) - this release just for testing purposes.

    + +Release 1.2 is mostly a rewrite of the .shp/.shx access API to account +for ArcView 3.x 3D shapes, and to encapsulate the shapes in a structure. +Existing code using the shapefile library will require substantial changes +to use release 1.2.

    + +Release V1.1 has been built on a number of platforms, and used by a +number of people successfully. V1.1 is the first release with the xBase API +documentation.

    + + +

    Maintainer

    + +This library is maintained by me (Frank Warmerdam) on my own time. Please +send me bug patches and suggestions for the library. Email can be sent to +warmerdam@pobox.com.

    + +The current status of the Shapelib code can be found at + +http://pobox.com/~warmerdam/root/projects/shapelib/. To find out about +new releases of Shapelib, select the "Subscribe to new releases" option +from the link at +Freshmeat.

    + +The shputils.c module was contributed by Bill Miller (NC-DOT) who can be +reached at bmiller@doh.dot.state.nc.us. I had to modify it substantially +to work with the 1.2 API, and I am not sure that it works as well as it +did when it was originally provided by Bill.

    + +

    Credits

    + +I didn't start this section anywhere near soon enough, so alot of earlier +contributors to Shapelib are lost in pre-history. + +
      +
    • Bill Miller (NY-DOT) for shputils.c +
    • Carl Anderson for the contents of the contrib directory, and +the "tuple" additions to dbfopen.c. +
    • Andrea Giacomelli for patches for dbfopen.c. +
    • Doug Matthews for portability improvements. +
    • Jan-Oliver Wagner for convincing me to make it available under LGPL, +shared library support, and various other patches. +
    • Dennis Christopher (of Avenza) for testing and bug fixes. +
    • Miko Syrjä (of 3D-system Oy) for a record size bug fix. +
    • Steven Lime and Curtis Hill for help with NULL shapes. +
    • Jim Matthews for support of NULL attributes in dbf files. +
    • PCI Geomatics who let me +release a modified version of their shapefile code in the beginning and +who hosted shapelib for years. +
    + +

    In Memorium

    + +I would like to dedicate Shapelib to the memory of Sol Katz. While I never +met him in person, his generous contributions to the GIS community took +many forms, including free distribution of a variety of GIS translators +with source. The fact that he used this Shapelib in some of his utilities, +and thanked me was a great encouragement to me. I hope I can do his memory +honour by trying to contribute in a similar fashion.

    + +

    Portability

    + +The Shapefile C Library should port easily to 32bit systems with ANSI C +compilers. It should work on 64 bit architectures (such as the DEC AXP).

    + +Care should also be taken to pass the binary access flag into SHPOpen() +and DBFOpen() when operating on systems with special text file translation +such as MSDOS.

    + +The shputils.c module is contributed, and may not take the same approach +to portability as the rest of the package.

    + +On Linux, and most unix systems it should be possible to build and +install shapefile support as a shared library using the "lib" and "lib_install" +targets of the Makefile. Note that this Makefile doesn't use autoconf +mechanisms and will generally require some hand tailoring for your environment. + +

    Limitations

    + +
      + +
    • You can't modify the vertices of existing structures (though you + can update the attributes of existing structures, and create new + structures).

      + +

    • Not written in such a way as to be particularly fast. This is +particularly true of the 1.2 API. For applications more concerned with +speed it may be worth using the V1.1 API.

      + +

    • Doesn't set the last access time properly in the .dbf files.

      + +

    • There is no way to synchronize information to the file except to close it. +

      + +

    • Poor error checking and reporting.

      + +

    • Not professionally supported (well it can be, if you want to pay).

      + +

    • Some aspects of xBase files not supported, though I believe they are +not used by ESRI.

      + +

    • The application must keep the .dbf file in sync with the .shp/.shx +files through appropriate use of the DBF and SHP APIs.

      + +

    • No support for the undocumented .sbn/.sbx spatial index files.

      + +

    + +

    Copyright

    + +The source for the Shapefile C Library is (c) 1998 Frank Warmerdam, +and released under the following conditions. The intent is that anyone +can do anything with the code, but that I do not assume any liability, nor +express any warranty for this code.

    + +As of Shapelib 1.2.6 the core portions of the library are made available +under two possible licenses. The licensee can choose to use the code +under either the Library GNU Public License (LGPL) described in +LICENSE.LGPL or under the following MIT style license. Any files in +the Shapelib distribution without explicit copyright license terms +(such as this documentation, the Makefile and so forth) should be +considered to have the following licensing terms. Some auxilary portions +of Shapelib, notably some of the components in the contrib directory +come under slightly different license restrictions. Check the source +files that you are actually using for conditions.

    + +

    Default License Terms

    + + +Copyright (c) 1999, Frank Warmerdam

    + +This software is available under the following "MIT Style" license, +or at the option of the licensee under the LGPL (see LICENSE.LGPL). This +option is discussed in more detail in shapelib.html.

    + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions:

    + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software.

    + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE.

    + + +

    Shapelib Modifications

    + +I am pleased to receive bug fixes, and improvements for Shapelib. Unless +the submissions indicate otherwise I will assume that changes submitted to +me remain under the the above "dual license" terms. If changes are made +to the library with the intention that those changes should be protected by +the LGPL then I should be informed upon submission. Note that I will not +generally incorporate changes into the core of Shapelib that are protected +under the LGPL as this would effectively limit the whole file and +distribution to LGPL terms.

    + +

    Opting for LGPL

    + +For licensee's opting to use Shapelib under LGPL as opposed to the MIT +Style license above, and wishing to redistribute the software based on +Shapelib, I would ask that all "dual license" modules be updated to +indicate that only the LGPL (and not the MIT Style license) applies. This +action represents opting for the LGPL, and thereafter LGPL terms apply to +any redistribution and modification of the affected modules.

    + + + + + + diff --git a/shapelib/shp_api.html b/shapelib/shp_api.html new file mode 100644 index 000000000..d773e3e56 --- /dev/null +++ b/shapelib/shp_api.html @@ -0,0 +1,376 @@ + + +.SHP File API + + + +

    .SHP File API

    + +The .SHP API uses a SHPHandle to represent an open .shp/.shx file pair. +The contents of the SHPHandle are visible (see shapefile.h) but should +be ignored by the application. It is intended that all information be +accessed by the API functions.

    + + + +

    Shape Types

    + +Shapes have types associated with them. The following is a list of the +different shapetypes supported by Shapefiles. At this time all shapes in +a Shapefile must be of the same type (with the exception of NULL shapes).

    + +

    +  #define SHPT_NULL             0
    +
    +  2D Shape Types (pre ArcView 3.x):
    +
    +  #define SHPT_POINT		1	Points
    +  #define SHPT_ARC		3	Arcs (Polylines, possible in parts)
    +  #define SHPT_POLYGON		5	Polygons (possible in parts)
    +  #define SHPT_MULTIPOINT	8	MultiPoint (related points)
    +
    +  3D Shape Types (may include "measure" values for vertices):
    +
    +  #define SHPT_POINTZ		11	
    +  #define SHPT_ARCZ		13
    +  #define SHPT_POLYGONZ		15
    +  #define SHPT_MULTIPOINTZ 	18
    +
    +  2D + Measure Types:
    +
    +  #define SHPT_POINTM		21
    +  #define SHPT_ARCM		23
    +  #define SHPT_POLYGONM		25
    +  #define SHPT_MULTIPOINTM 	28
    +
    +  Complex (TIN-like) with Z, and Measure:
    +
    +  #define SHPT_MULTIPATCH 	31
    +
    + + + +

    SHPObject

    + +An individual shape is represented by the SHPObject structure. SHPObject's +created with SHPCreateObject(), SHPCreateSimpleObject(), or SHPReadObject() +should be disposed of with SHPDestroyObject().

    + +

    +  typedef struct
    +  {
    +    int		nSHPType;	Shape Type (SHPT_* - see list above)
    +
    +    int		nShapeId; 	Shape Number (-1 is unknown/unassigned)
    +
    +    int		nParts;		# of Parts (0 implies single part with no info)
    +    int		*panPartStart;  Start Vertex of part
    +    int		*panPartType;	Part Type (SHPP_RING if not SHPT_MULTIPATCH)
    +    
    +    int		nVertices;	Vertex list 
    +    double	*padfX;		
    +    double	*padfY;
    +    double	*padfZ;		(all zero if not provided)
    +    double	*padfM;		(all zero if not provided)
    +
    +    double	dfXMin;		Bounds in X, Y, Z and M dimensions
    +    double	dfYMin;
    +    double	dfZMin;
    +    double	dfMMin;
    +
    +    double	dfXMax;
    +    double	dfYMax;
    +    double	dfZMax;
    +    double	dfMMax;
    +  } SHPObject;
    +
    + + + +

    SHPOpen()

    + +
    +SHPHandle SHPOpen( const char * pszShapeFile, const char * pszAccess );
    +
    +  pszShapeFile:		The name of the layer to access.  This can be the
    +			name of either the .shp or the .shx file or can
    +			just be the path plus the basename of the pair.
    +
    +  pszAccess:		The fopen() style access string.  At this time only
    +			"rb" (read-only binary) and "rb+" (read/write binary) 
    +		        should be used.
    +
    + + The SHPOpen() function should be used to establish access to the two files + for accessing vertices (.shp and .shx). Note that both files have to + be in the indicated directory, and must have the expected extensions in + lower case. The returned SHPHandle is passed to other access functions, + and SHPClose() should be invoked to recover resources, and flush changes + to disk when complete.

    + + + +

    SHPGetInfo()

    + +
    +void SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
    +                 double * padfMinBound, double * padfMaxBound );
    +
    +  hSHP:			The handle previously returned by SHPOpen() 
    +			or SHPCreate().
    +
    +  pnEntities:		A pointer to an integer into which the number of
    +			entities/structures should be placed.  May be NULL.
    +
    +  pnShapetype:		A pointer to an integer into which the shapetype
    +			of this file should be placed.  Shapefiles may contain
    +			either SHPT_POINT, SHPT_ARC, SHPT_POLYGON or 
    +			SHPT_MULTIPOINT entities.  This may be NULL.
    +
    +  padfMinBound:		The X, Y, Z and M minimum values will be placed into
    +                        this four entry array.  This may be NULL.
    +			
    +  padfMaxBound:		The X, Y, Z and M maximum values will be placed into
    +                        this four entry array.  This may be NULL.
    +
    + + The SHPGetInfo() function retrieves various information about shapefile + as a whole. The bounds are read from the file header, and may be + inaccurate if the file was improperly generated.

    + + + +

    SHPReadObject()

    + +
    +SHPObject *SHPReadObject( SHPHandle hSHP, int iShape );
    +
    +  hSHP:			The handle previously returned by SHPOpen() 
    +			or SHPCreate().
    +
    +  iShape:		The entity number of the shape to read.  Entity 
    +			numbers are between 0 and nEntities-1 (as returned
    +			by SHPGetInfo()).
    +
    + + The SHPReadObject() call is used to read a single structure, or entity + from the shapefile. See the definition of the SHPObject structure for + detailed information on fields of a SHPObject. SHPObject's returned from + SHPReadObject() should be deallocated with SHPDestroyShape(). + SHPReadObject() will return NULL if an illegal iShape value is requested.

    + + Note that the bounds placed into the SHPObject are those read from the + file, and may not be correct. For points the bounds are generated from + the single point since bounds aren't normally provided for point types.

    + + Generally the shapes returned will be of the type of the file as a whole. + However, any file may also contain type SHPT_NULL shapes which will have + no geometry. Generally speaking applications should skip rather than + preserve them, as they usually represented interactively deleted shapes.

    + + + +

    SHPClose()

    + +
    +void	SHPClose( SHPHandle hSHP );
    +
    +  hSHP:			The handle previously returned by SHPOpen() 
    +			or SHPCreate().
    +
    + + The SHPClose() function will close the .shp and .shx files, and flush + all outstanding header information to the files. It will also recover + resources associated with the handle. After this call the hSHP handle + cannot be used again.

    + + + +

    SHPCreate()

    + +
    +SHPHandle SHPCreate( const char * pszShapeFile, int nShapeType );
    +
    +  pszShapeFile:		The name of the layer to access.  This can be the
    +			name of either the .shp or the .shx file or can
    +			just be the path plus the basename of the pair.
    +
    +  nShapeType:		The type of shapes to be stored in the newly created
    +			file.  It may be either SHPT_POINT, SHPT_ARC, 
    +		        SHPT_POLYGON or SHPT_MULTIPOINT.
    +
    + + The SHPCreate() function will create a new .shp and .shx file of the + desired type.

    + + + +

    SHPCreateSimpleObject()

    + +
    +SHPObject * 
    +     SHPCreateSimpleObject( int nSHPType, int nVertices, 
    +			    double *padfX, double * padfY, double *padfZ, );
    +
    +  nSHPType:		The SHPT_ type of the object to be created, such
    +                        as SHPT_POINT, or SHPT_POLYGON.
    +  
    +  nVertices:		The number of vertices being passed in padfX,    
    +                        padfY, and padfZ. 
    +
    +  padfX:		An array of nVertices X coordinates of the vertices
    +                        for this object.
    +
    +  padfY:		An array of nVertices Y coordinates of the vertices
    +                        for this object.
    +
    +  padfZ:		An array of nVertices Z coordinates of the vertices
    +                        for this object.  This may be NULL in which case
    +		        they are all assumed to be zero.
    +
    + + The SHPCreateSimpleObject() allows for the convenient creation of + simple objects. This is normally used so that the SHPObject can be + passed to SHPWriteObject() to write it to the file. The simple object + creation API assumes an M (measure) value of zero for each vertex. For + complex objects (such as polygons) it is assumed that there is only one + part, and that it is of the default type (SHPP_RING).

    + + Use the SHPCreateObject() function for more sophisticated objects. The + SHPDestroyObject() function should be used to free resources associated with + an object allocated with SHPCreateSimpleObject().

    + + This function computes a bounding box for the SHPObject from the given + vertices.

    + + + +

    SHPCreateObject()

    + +
    +SHPObject * 
    +     SHPCreateObject( int nSHPType, int iShape,
    +                      int nParts, int * panPartStart, int * panPartType,
    +                      int nVertices, double *padfX, double * padfY, 
    +                      double *padfZ, double *padfM );
    +
    +  nSHPType:		The SHPT_ type of the object to be created, such
    +                        as SHPT_POINT, or SHPT_POLYGON.
    +
    +  iShape:		The shapeid to be recorded with this shape.
    +
    +  nParts:		The number of parts for this object.  If this is
    +                        zero for ARC, or POLYGON type objects, a single 
    +                        zero valued part will be created internally.
    +  
    +  panPartStart:		The list of zero based start vertices for the rings
    +                        (parts) in this object.  The first should always be
    +                        zero.  This may be NULL if nParts is 0.
    +  
    +  panPartType:		The type of each of the parts.  This is only meaningful
    +                        for MULTIPATCH files.  For all other cases this may
    +                        be NULL, and will be assumed to be SHPP_RING.
    +  
    +  nVertices:		The number of vertices being passed in padfX,    
    +                        padfY, and padfZ. 
    +
    +  padfX:		An array of nVertices X coordinates of the vertices
    +                        for this object.
    +
    +  padfY:		An array of nVertices Y coordinates of the vertices
    +                        for this object.
    +
    +  padfZ:		An array of nVertices Z coordinates of the vertices
    +                        for this object.  This may be NULL in which case
    +		        they are all assumed to be zero.
    +
    +  padfM:		An array of nVertices M (measure values) of the 
    +			vertices for this object.  This may be NULL in which 
    +			case they are all assumed to be zero.
    +
    + + The SHPCreateSimpleObject() allows for the creation of objects (shapes). + This is normally used so that the SHPObject can be passed to + SHPWriteObject() to write it to the file.

    + + The SHPDestroyObject() function should be used to free resources associated + with an object allocated with SHPCreateObject().

    + + This function computes a bounding box for the SHPObject from the given + vertices.

    + + + +

    SHPComputeExtents()

    + +
    +void SHPComputeExtents( SHPObject * psObject );
    +
    +  psObject:		An existing shape object to be updated in place.
    +
    + + This function will recompute the extents of this shape, replacing the + existing values of the dfXMin, dfYMin, dfZMin, dfMMin, dfXMax, dfYMax, + dfZMax, and dfMMax values based on the current set of vertices for the + shape. This function is automatically called by SHPCreateObject() but + if the vertices of an existing object are altered it should be called again + to fix up the extents.

    + + + +

    SHPWriteObject()

    + +
    +int SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject *psObject );
    +
    +  hSHP:			The handle previously returned by SHPOpen("r+") 
    +			or SHPCreate().
    +
    +  iShape:		The entity number of the shape to write.  A value of
    +		        -1 should be used for new shapes.  
    +
    +  psObject:		The shape to write to the file. This should have
    +                        been created with SHPCreateObject(), or 
    +                        SHPCreateSimpleObject().
    +
    + + The SHPWriteObject() call is used to write a single structure, or entity + to the shapefile. See the definition of the SHPObject structure for + detailed information on fields of a SHPObject. The return value is the + entity number of the written shape.

    + + + +

    SHPDestroyObject()

    + +
    +void SHPDestroyObject( SHPObject *psObject );
    +
    +  psObject:		The object to deallocate.
    +
    + + This function should be used to deallocate the resources associated with + a SHPObject when it is no longer needed, including those created with + SHPCreateSimpleObject(), SHPCreateObject() and returned from SHPReadObject(). +

    + + + +

    SHPRewindObject()

    + +
    +int SHPRewindObject( SHPHandle hSHP, SHPObject *psObject );
    +
    +  hSHP:                 The shapefile (not used at this time).
    +  psObject:		The object to deallocate.
    +
    + + This function will reverse any rings necessary in order to enforce the + shapefile restrictions on the required order of inner and outer rings in + the Shapefile specification. It returns TRUE if a change is made and FALSE + if no change is made. Only polygon objects will be affected though any + object may be passed. +

    + + + diff --git a/shapelib/shpopen.c b/shapelib/shpopen.c new file mode 100644 index 000000000..255068b98 --- /dev/null +++ b/shapelib/shpopen.c @@ -0,0 +1,1886 @@ +/****************************************************************************** + * $Id: shpopen.c,v 1.5 2006/11/24 21:55:52 oliskoli Exp $ + * + * Project: Shapelib + * Purpose: Implementation of core Shapefile read/write functions. + * Author: Frank Warmerdam, warmerdam@pobox.com + * + ****************************************************************************** + * Copyright (c) 1999, 2001, Frank Warmerdam + * + * This software is available under the following "MIT Style" license, + * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This + * option is discussed in more detail in shapelib.html. + * + * -- + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * $Log: shpopen.c,v $ + * Revision 1.5 2006/11/24 21:55:52 oliskoli + * Remove (shpopen) warning on FreeBSD. + * + * Revision 1.4 2006/07/13 03:27:54 robertl + * Andy Armstrong turns on -Wall for GCC builds and kills about a sequillion warnings. Most of them aren't "real", but it's still a good thing to clean up. + * (I hope I don't regret this before 1.3.1...) + * + * Revision 1.3 2006/05/07 02:14:35 robertl + * Make shapefile and all palm pdb formats deselectable at build time. + * + * Revision 1.2 2004/09/27 01:13:58 robertl + * warning fixes in shapelib. From Alexander Stohr. + * + * Revision 1.1 2004/09/20 17:21:22 robertl + * Check in shapelib and experimental prototype of crude shapefile support. + * + * Revision 1.39 2002/08/26 06:46:56 warmerda + * avoid c++ comments + * + * Revision 1.38 2002/05/07 16:43:39 warmerda + * Removed debugging printf. + * + * Revision 1.37 2002/04/10 17:35:22 warmerda + * fixed bug in ring reversal code + * + * Revision 1.36 2002/04/10 16:59:54 warmerda + * added SHPRewindObject + * + * Revision 1.35 2001/12/07 15:10:44 warmerda + * fix if .shx fails to open + * + * Revision 1.34 2001/11/01 16:29:55 warmerda + * move pabyRec into SHPInfo for thread safety + * + * Revision 1.33 2001/07/03 12:18:15 warmerda + * Improved cleanup if SHX not found, provied by Riccardo Cohen. + * + * Revision 1.32 2001/06/22 01:58:07 warmerda + * be more careful about establishing initial bounds in face of NULL shapes + * + * Revision 1.31 2001/05/31 19:35:29 warmerda + * added support for writing null shapes + * + * Revision 1.30 2001/05/28 12:46:29 warmerda + * Add some checking on reasonableness of record count when opening. + * + * Revision 1.29 2001/05/23 13:36:52 warmerda + * added use of SHPAPI_CALL + * + * Revision 1.28 2001/02/06 22:25:06 warmerda + * fixed memory leaks when SHPOpen() fails + * + * Revision 1.27 2000/07/18 15:21:33 warmerda + * added better enforcement of -1 for append in SHPWriteObject + * + * Revision 1.26 2000/02/16 16:03:51 warmerda + * added null shape support + * + * Revision 1.25 1999/12/15 13:47:07 warmerda + * Fixed record size settings in .shp file (was 4 words too long) + * Added stdlib.h. + * + * Revision 1.24 1999/11/05 14:12:04 warmerda + * updated license terms + * + * Revision 1.23 1999/07/27 00:53:46 warmerda + * added support for rewriting shapes + * + * Revision 1.22 1999/06/11 19:19:11 warmerda + * Cleanup pabyRec static buffer on SHPClose(). + * + * Revision 1.21 1999/06/02 14:57:56 kshih + * Remove unused variables + * + * Revision 1.20 1999/04/19 21:04:17 warmerda + * Fixed syntax error. + * + * Revision 1.19 1999/04/19 21:01:57 warmerda + * Force access string to binary in SHPOpen(). + * + * Revision 1.18 1999/04/01 18:48:07 warmerda + * Try upper case extensions if lower case doesn't work. + * + * Revision 1.17 1998/12/31 15:29:39 warmerda + * Disable writing measure values to multipatch objects if + * DISABLE_MULTIPATCH_MEASURE is defined. + * + * Revision 1.16 1998/12/16 05:14:33 warmerda + * Added support to write MULTIPATCH. Fixed reading Z coordinate of + * MULTIPATCH. Fixed record size written for all feature types. + * + * Revision 1.15 1998/12/03 16:35:29 warmerda + * r+b is proper binary access string, not rb+. + * + * Revision 1.14 1998/12/03 15:47:56 warmerda + * Fixed setting of nVertices in SHPCreateObject(). + * + * Revision 1.13 1998/12/03 15:33:54 warmerda + * Made SHPCalculateExtents() separately callable. + * + * Revision 1.12 1998/11/11 20:01:50 warmerda + * Fixed bug writing ArcM/Z, and PolygonM/Z for big endian machines. + * + * Revision 1.11 1998/11/09 20:56:44 warmerda + * Fixed up handling of file wide bounds. + * + * Revision 1.10 1998/11/09 20:18:51 warmerda + * Converted to support 3D shapefiles, and use of SHPObject. + * + * Revision 1.9 1998/02/24 15:09:05 warmerda + * Fixed memory leak. + * + * Revision 1.8 1997/12/04 15:40:29 warmerda + * Fixed byte swapping of record number, and record length fields in the + * .shp file. + * + * Revision 1.7 1995/10/21 03:15:58 warmerda + * Added support for binary file access, the magic cookie 9997 + * and tried to improve the int32 selection logic for 16bit systems. + * + * Revision 1.6 1995/09/04 04:19:41 warmerda + * Added fix for file bounds. + * + * Revision 1.5 1995/08/25 15:16:44 warmerda + * Fixed a couple of problems with big endian systems ... one with bounds + * and the other with multipart polygons. + * + * Revision 1.4 1995/08/24 18:10:17 warmerda + * Switch to use SfRealloc() to avoid problems with pre-ANSI realloc() + * functions (such as on the Sun). + * + * Revision 1.3 1995/08/23 02:23:15 warmerda + * Added support for reading bounds, and fixed up problems in setting the + * file wide bounds. + * + * Revision 1.2 1995/08/04 03:16:57 warmerda + * Added header. + * + */ + +/*static char rcsid[] = + "$Id: shpopen.c,v 1.5 2006/11/24 21:55:52 oliskoli Exp $";*/ + +#include "shapefil.h" +#include "config.h" +#if SHAPELIB_ENABLED + +#include +#include +#include +#include +#include + +typedef unsigned char uchar; + +#if UINT_MAX == 65535 +typedef long int32; +#else +typedef int int32; +#endif + +#ifndef FALSE +# define FALSE 0 +# define TRUE 1 +#endif + +#define ByteCopy( a, b, c ) memcpy( b, a, c ) +#ifndef MAX +# define MIN(a,b) ((ab) ? a : b) +#endif + +static int bBigEndian; + + +/************************************************************************/ +/* SwapWord() */ +/* */ +/* Swap a 2, 4 or 8 byte word. */ +/************************************************************************/ + +static void SwapWord( int length, void * wordP ) + +{ + int i; + uchar temp; + + for( i=0; i < length/2; i++ ) + { + temp = ((uchar *) wordP)[i]; + ((uchar *)wordP)[i] = ((uchar *) wordP)[length-i-1]; + ((uchar *) wordP)[length-i-1] = temp; + } +} + +/************************************************************************/ +/* SfRealloc() */ +/* */ +/* A realloc cover function that will access a NULL pointer as */ +/* a valid input. */ +/************************************************************************/ + +static void * SfRealloc( void * pMem, int nNewSize ) + +{ + if( pMem == NULL ) + return( (void *) malloc(nNewSize) ); + else + return( (void *) realloc(pMem,nNewSize) ); +} + +/************************************************************************/ +/* SHPWriteHeader() */ +/* */ +/* Write out a header for the .shp and .shx files as well as the */ +/* contents of the index (.shx) file. */ +/************************************************************************/ + +static void SHPWriteHeader( SHPHandle psSHP ) + +{ + uchar abyHeader[100]; + int i; + int32 i32; + double dValue; + int32 *panSHX; + +/* -------------------------------------------------------------------- */ +/* Prepare header block for .shp file. */ +/* -------------------------------------------------------------------- */ + for( i = 0; i < 100; i++ ) + abyHeader[i] = 0; + + abyHeader[2] = 0x27; /* magic cookie */ + abyHeader[3] = 0x0a; + + i32 = psSHP->nFileSize/2; /* file size */ + ByteCopy( &i32, abyHeader+24, 4 ); + if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); + + i32 = 1000; /* version */ + ByteCopy( &i32, abyHeader+28, 4 ); + if( bBigEndian ) SwapWord( 4, abyHeader+28 ); + + i32 = psSHP->nShapeType; /* shape type */ + ByteCopy( &i32, abyHeader+32, 4 ); + if( bBigEndian ) SwapWord( 4, abyHeader+32 ); + + dValue = psSHP->adBoundsMin[0]; /* set bounds */ + ByteCopy( &dValue, abyHeader+36, 8 ); + if( bBigEndian ) SwapWord( 8, abyHeader+36 ); + + dValue = psSHP->adBoundsMin[1]; + ByteCopy( &dValue, abyHeader+44, 8 ); + if( bBigEndian ) SwapWord( 8, abyHeader+44 ); + + dValue = psSHP->adBoundsMax[0]; + ByteCopy( &dValue, abyHeader+52, 8 ); + if( bBigEndian ) SwapWord( 8, abyHeader+52 ); + + dValue = psSHP->adBoundsMax[1]; + ByteCopy( &dValue, abyHeader+60, 8 ); + if( bBigEndian ) SwapWord( 8, abyHeader+60 ); + + dValue = psSHP->adBoundsMin[2]; /* z */ + ByteCopy( &dValue, abyHeader+68, 8 ); + if( bBigEndian ) SwapWord( 8, abyHeader+68 ); + + dValue = psSHP->adBoundsMax[2]; + ByteCopy( &dValue, abyHeader+76, 8 ); + if( bBigEndian ) SwapWord( 8, abyHeader+76 ); + + dValue = psSHP->adBoundsMin[3]; /* m */ + ByteCopy( &dValue, abyHeader+84, 8 ); + if( bBigEndian ) SwapWord( 8, abyHeader+84 ); + + dValue = psSHP->adBoundsMax[3]; + ByteCopy( &dValue, abyHeader+92, 8 ); + if( bBigEndian ) SwapWord( 8, abyHeader+92 ); + +/* -------------------------------------------------------------------- */ +/* Write .shp file header. */ +/* -------------------------------------------------------------------- */ + fseek( psSHP->fpSHP, 0, 0 ); + fwrite( abyHeader, 100, 1, psSHP->fpSHP ); + +/* -------------------------------------------------------------------- */ +/* Prepare, and write .shx file header. */ +/* -------------------------------------------------------------------- */ + i32 = (psSHP->nRecords * 2 * sizeof(int32) + 100)/2; /* file size */ + ByteCopy( &i32, abyHeader+24, 4 ); + if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); + + fseek( psSHP->fpSHX, 0, 0 ); + fwrite( abyHeader, 100, 1, psSHP->fpSHX ); + +/* -------------------------------------------------------------------- */ +/* Write out the .shx contents. */ +/* -------------------------------------------------------------------- */ + panSHX = (int32 *) malloc(sizeof(int32) * 2 * psSHP->nRecords); + + for( i = 0; i < psSHP->nRecords; i++ ) + { + panSHX[i*2 ] = psSHP->panRecOffset[i]/2; + panSHX[i*2+1] = psSHP->panRecSize[i]/2; + if( !bBigEndian ) SwapWord( 4, panSHX+i*2 ); + if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 ); + } + + fwrite( panSHX, sizeof(int32) * 2, psSHP->nRecords, psSHP->fpSHX ); + + free( panSHX ); +} + +/************************************************************************/ +/* SHPOpen() */ +/* */ +/* Open the .shp and .shx files based on the basename of the */ +/* files or either file name. */ +/************************************************************************/ + +SHPHandle SHPAPI_CALL +SHPOpen( const char * pszLayer, const char * pszAccess ) + +{ + char *pszFullname, *pszBasename; + SHPHandle psSHP; + + uchar *pabyBuf; + int i; + double dValue; + +/* -------------------------------------------------------------------- */ +/* Ensure the access string is one of the legal ones. We */ +/* ensure the result string indicates binary to avoid common */ +/* problems on Windows. */ +/* -------------------------------------------------------------------- */ + if( strcmp(pszAccess,"rb+") == 0 || strcmp(pszAccess,"r+b") == 0 + || strcmp(pszAccess,"r+") == 0 ) + pszAccess = "r+b"; + else + pszAccess = "rb"; + +/* -------------------------------------------------------------------- */ +/* Establish the byte order on this machine. */ +/* -------------------------------------------------------------------- */ + i = 1; + if( *((uchar *) &i) == 1 ) + bBigEndian = FALSE; + else + bBigEndian = TRUE; + +/* -------------------------------------------------------------------- */ +/* Initialize the info structure. */ +/* -------------------------------------------------------------------- */ + psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1); + + psSHP->bUpdated = FALSE; + +/* -------------------------------------------------------------------- */ +/* Compute the base (layer) name. If there is any extension */ +/* on the passed in filename we will strip it off. */ +/* -------------------------------------------------------------------- */ + pszBasename = (char *) malloc(strlen(pszLayer)+5); + strcpy( pszBasename, pszLayer ); + for( i = strlen(pszBasename)-1; + i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' + && pszBasename[i] != '\\'; + i-- ) {} + + if( pszBasename[i] == '.' ) + pszBasename[i] = '\0'; + +/* -------------------------------------------------------------------- */ +/* Open the .shp and .shx files. Note that files pulled from */ +/* a PC to Unix with upper case filenames won't work! */ +/* -------------------------------------------------------------------- */ + pszFullname = (char *) malloc(strlen(pszBasename) + 5); + sprintf( pszFullname, "%s.shp", pszBasename ); + psSHP->fpSHP = fopen(pszFullname, pszAccess ); + if( psSHP->fpSHP == NULL ) + { + sprintf( pszFullname, "%s.SHP", pszBasename ); + psSHP->fpSHP = fopen(pszFullname, pszAccess ); + } + + if( psSHP->fpSHP == NULL ) + { + free( psSHP ); + free( pszBasename ); + free( pszFullname ); + return( NULL ); + } + + sprintf( pszFullname, "%s.shx", pszBasename ); + psSHP->fpSHX = fopen(pszFullname, pszAccess ); + if( psSHP->fpSHX == NULL ) + { + sprintf( pszFullname, "%s.SHX", pszBasename ); + psSHP->fpSHX = fopen(pszFullname, pszAccess ); + } + + if( psSHP->fpSHX == NULL ) + { + fclose( psSHP->fpSHP ); + free( psSHP ); + free( pszBasename ); + free( pszFullname ); + return( NULL ); + } + + free( pszFullname ); + free( pszBasename ); + +/* -------------------------------------------------------------------- */ +/* Read the file size from the SHP file. */ +/* -------------------------------------------------------------------- */ + pabyBuf = (uchar *) malloc(100); + fread( pabyBuf, 100, 1, psSHP->fpSHP ); + + psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256 + + pabyBuf[25] * 256 * 256 + + pabyBuf[26] * 256 + + pabyBuf[27]) * 2; + +/* -------------------------------------------------------------------- */ +/* Read SHX file Header info */ +/* -------------------------------------------------------------------- */ + fread( pabyBuf, 100, 1, psSHP->fpSHX ); + + if( pabyBuf[0] != 0 + || pabyBuf[1] != 0 + || pabyBuf[2] != 0x27 + || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) ) + { + fclose( psSHP->fpSHP ); + fclose( psSHP->fpSHX ); + free( psSHP ); + + return( NULL ); + } + + psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256 + + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256; + psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8; + + psSHP->nShapeType = pabyBuf[32]; + + if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 ) + { + /* this header appears to be corrupt. Give up. */ + fclose( psSHP->fpSHP ); + fclose( psSHP->fpSHX ); + free( psSHP ); + + return( NULL ); + } + +/* -------------------------------------------------------------------- */ +/* Read the bounds. */ +/* -------------------------------------------------------------------- */ + if( bBigEndian ) SwapWord( 8, pabyBuf+36 ); + memcpy( &dValue, pabyBuf+36, 8 ); + psSHP->adBoundsMin[0] = dValue; + + if( bBigEndian ) SwapWord( 8, pabyBuf+44 ); + memcpy( &dValue, pabyBuf+44, 8 ); + psSHP->adBoundsMin[1] = dValue; + + if( bBigEndian ) SwapWord( 8, pabyBuf+52 ); + memcpy( &dValue, pabyBuf+52, 8 ); + psSHP->adBoundsMax[0] = dValue; + + if( bBigEndian ) SwapWord( 8, pabyBuf+60 ); + memcpy( &dValue, pabyBuf+60, 8 ); + psSHP->adBoundsMax[1] = dValue; + + if( bBigEndian ) SwapWord( 8, pabyBuf+68 ); /* z */ + memcpy( &dValue, pabyBuf+68, 8 ); + psSHP->adBoundsMin[2] = dValue; + + if( bBigEndian ) SwapWord( 8, pabyBuf+76 ); + memcpy( &dValue, pabyBuf+76, 8 ); + psSHP->adBoundsMax[2] = dValue; + + if( bBigEndian ) SwapWord( 8, pabyBuf+84 ); /* z */ + memcpy( &dValue, pabyBuf+84, 8 ); + psSHP->adBoundsMin[3] = dValue; + + if( bBigEndian ) SwapWord( 8, pabyBuf+92 ); + memcpy( &dValue, pabyBuf+92, 8 ); + psSHP->adBoundsMax[3] = dValue; + + free( pabyBuf ); + +/* -------------------------------------------------------------------- */ +/* Read the .shx file to get the offsets to each record in */ +/* the .shp file. */ +/* -------------------------------------------------------------------- */ + psSHP->nMaxRecords = psSHP->nRecords; + + psSHP->panRecOffset = + (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) ); + psSHP->panRecSize = + (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) ); + + pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) ); + fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ); + + for( i = 0; i < psSHP->nRecords; i++ ) + { + int32 nOffset, nLength; + + memcpy( &nOffset, pabyBuf + i * 8, 4 ); + if( !bBigEndian ) SwapWord( 4, &nOffset ); + + memcpy( &nLength, pabyBuf + i * 8 + 4, 4 ); + if( !bBigEndian ) SwapWord( 4, &nLength ); + + psSHP->panRecOffset[i] = nOffset*2; + psSHP->panRecSize[i] = nLength*2; + } + free( pabyBuf ); + + return( psSHP ); +} + +/************************************************************************/ +/* SHPClose() */ +/* */ +/* Close the .shp and .shx files. */ +/************************************************************************/ + +void SHPAPI_CALL +SHPClose(SHPHandle psSHP ) + +{ +/* -------------------------------------------------------------------- */ +/* Update the header if we have modified anything. */ +/* -------------------------------------------------------------------- */ + if( psSHP->bUpdated ) + { + SHPWriteHeader( psSHP ); + } + +/* -------------------------------------------------------------------- */ +/* Free all resources, and close files. */ +/* -------------------------------------------------------------------- */ + free( psSHP->panRecOffset ); + free( psSHP->panRecSize ); + + fclose( psSHP->fpSHX ); + fclose( psSHP->fpSHP ); + + if( psSHP->pabyRec != NULL ) + { + free( psSHP->pabyRec ); + } + + free( psSHP ); +} + +/************************************************************************/ +/* SHPGetInfo() */ +/* */ +/* Fetch general information about the shape file. */ +/************************************************************************/ + +void SHPAPI_CALL +SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType, + double * padfMinBound, double * padfMaxBound ) + +{ + int i; + + if( pnEntities != NULL ) + *pnEntities = psSHP->nRecords; + + if( pnShapeType != NULL ) + *pnShapeType = psSHP->nShapeType; + + for( i = 0; i < 4; i++ ) + { + if( padfMinBound != NULL ) + padfMinBound[i] = psSHP->adBoundsMin[i]; + if( padfMaxBound != NULL ) + padfMaxBound[i] = psSHP->adBoundsMax[i]; + } +} + +/************************************************************************/ +/* SHPCreate() */ +/* */ +/* Create a new shape file and return a handle to the open */ +/* shape file with read/write access. */ +/************************************************************************/ + +SHPHandle SHPAPI_CALL +SHPCreate( const char * pszLayer, int nShapeType ) + +{ + char *pszBasename, *pszFullname; + int i; + FILE *fpSHP, *fpSHX; + uchar abyHeader[100]; + int32 i32; + double dValue; + +/* -------------------------------------------------------------------- */ +/* Establish the byte order on this system. */ +/* -------------------------------------------------------------------- */ + i = 1; + if( *((uchar *) &i) == 1 ) + bBigEndian = FALSE; + else + bBigEndian = TRUE; + +/* -------------------------------------------------------------------- */ +/* Compute the base (layer) name. If there is any extension */ +/* on the passed in filename we will strip it off. */ +/* -------------------------------------------------------------------- */ + pszBasename = (char *) malloc(strlen(pszLayer)+5); + strcpy( pszBasename, pszLayer ); + for( i = strlen(pszBasename)-1; + i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' + && pszBasename[i] != '\\'; + i-- ) {} + + if( pszBasename[i] == '.' ) + pszBasename[i] = '\0'; + +/* -------------------------------------------------------------------- */ +/* Open the two files so we can write their headers. */ +/* -------------------------------------------------------------------- */ + pszFullname = (char *) malloc(strlen(pszBasename) + 5); + sprintf( pszFullname, "%s.shp", pszBasename ); + fpSHP = fopen(pszFullname, "wb" ); + if( fpSHP == NULL ) + return( NULL ); + + sprintf( pszFullname, "%s.shx", pszBasename ); + fpSHX = fopen(pszFullname, "wb" ); + if( fpSHX == NULL ) + return( NULL ); + + free( pszFullname ); + free( pszBasename ); + +/* -------------------------------------------------------------------- */ +/* Prepare header block for .shp file. */ +/* -------------------------------------------------------------------- */ + for( i = 0; i < 100; i++ ) + abyHeader[i] = 0; + + abyHeader[2] = 0x27; /* magic cookie */ + abyHeader[3] = 0x0a; + + i32 = 50; /* file size */ + ByteCopy( &i32, abyHeader+24, 4 ); + if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); + + i32 = 1000; /* version */ + ByteCopy( &i32, abyHeader+28, 4 ); + if( bBigEndian ) SwapWord( 4, abyHeader+28 ); + + i32 = nShapeType; /* shape type */ + ByteCopy( &i32, abyHeader+32, 4 ); + if( bBigEndian ) SwapWord( 4, abyHeader+32 ); + + dValue = 0.0; /* set bounds */ + ByteCopy( &dValue, abyHeader+36, 8 ); + ByteCopy( &dValue, abyHeader+44, 8 ); + ByteCopy( &dValue, abyHeader+52, 8 ); + ByteCopy( &dValue, abyHeader+60, 8 ); + +/* -------------------------------------------------------------------- */ +/* Write .shp file header. */ +/* -------------------------------------------------------------------- */ + fwrite( abyHeader, 100, 1, fpSHP ); + +/* -------------------------------------------------------------------- */ +/* Prepare, and write .shx file header. */ +/* -------------------------------------------------------------------- */ + i32 = 50; /* file size */ + ByteCopy( &i32, abyHeader+24, 4 ); + if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); + + fwrite( abyHeader, 100, 1, fpSHX ); + +/* -------------------------------------------------------------------- */ +/* Close the files, and then open them as regular existing files. */ +/* -------------------------------------------------------------------- */ + fclose( fpSHP ); + fclose( fpSHX ); + + return( SHPOpen( pszLayer, "r+b" ) ); +} + +/************************************************************************/ +/* _SHPSetBounds() */ +/* */ +/* Compute a bounds rectangle for a shape, and set it into the */ +/* indicated location in the record. */ +/************************************************************************/ + +static void _SHPSetBounds( uchar * pabyRec, SHPObject * psShape ) + +{ + ByteCopy( &(psShape->dfXMin), pabyRec + 0, 8 ); + ByteCopy( &(psShape->dfYMin), pabyRec + 8, 8 ); + ByteCopy( &(psShape->dfXMax), pabyRec + 16, 8 ); + ByteCopy( &(psShape->dfYMax), pabyRec + 24, 8 ); + + if( bBigEndian ) + { + SwapWord( 8, pabyRec + 0 ); + SwapWord( 8, pabyRec + 8 ); + SwapWord( 8, pabyRec + 16 ); + SwapWord( 8, pabyRec + 24 ); + } +} + +/************************************************************************/ +/* SHPComputeExtents() */ +/* */ +/* Recompute the extents of a shape. Automatically done by */ +/* SHPCreateObject(). */ +/************************************************************************/ + +void SHPAPI_CALL +SHPComputeExtents( SHPObject * psObject ) + +{ + int i; + +/* -------------------------------------------------------------------- */ +/* Build extents for this object. */ +/* -------------------------------------------------------------------- */ + if( psObject->nVertices > 0 ) + { + psObject->dfXMin = psObject->dfXMax = psObject->padfX[0]; + psObject->dfYMin = psObject->dfYMax = psObject->padfY[0]; + psObject->dfZMin = psObject->dfZMax = psObject->padfZ[0]; + psObject->dfMMin = psObject->dfMMax = psObject->padfM[0]; + } + + for( i = 0; i < psObject->nVertices; i++ ) + { + psObject->dfXMin = MIN(psObject->dfXMin, psObject->padfX[i]); + psObject->dfYMin = MIN(psObject->dfYMin, psObject->padfY[i]); + psObject->dfZMin = MIN(psObject->dfZMin, psObject->padfZ[i]); + psObject->dfMMin = MIN(psObject->dfMMin, psObject->padfM[i]); + + psObject->dfXMax = MAX(psObject->dfXMax, psObject->padfX[i]); + psObject->dfYMax = MAX(psObject->dfYMax, psObject->padfY[i]); + psObject->dfZMax = MAX(psObject->dfZMax, psObject->padfZ[i]); + psObject->dfMMax = MAX(psObject->dfMMax, psObject->padfM[i]); + } +} + +/************************************************************************/ +/* SHPCreateObject() */ +/* */ +/* Create a shape object. It should be freed with */ +/* SHPDestroyObject(). */ +/************************************************************************/ + +SHPObject SHPAPI_CALL1(*) +SHPCreateObject( int nSHPType, int nShapeId, int nParts, + int * panPartStart, int * panPartType, + int nVertices, const double * padfX, const double * padfY, + const double * padfZ, const double * padfM ) + +{ + SHPObject *psObject; + int i, bHasM, bHasZ; + + psObject = (SHPObject *) calloc(1,sizeof(SHPObject)); + psObject->nSHPType = nSHPType; + psObject->nShapeId = nShapeId; + +/* -------------------------------------------------------------------- */ +/* Establish whether this shape type has M, and Z values. */ +/* -------------------------------------------------------------------- */ + if( nSHPType == SHPT_ARCM + || nSHPType == SHPT_POINTM + || nSHPType == SHPT_POLYGONM + || nSHPType == SHPT_MULTIPOINTM ) + { + bHasM = TRUE; + bHasZ = FALSE; + } + else if( nSHPType == SHPT_ARCZ + || nSHPType == SHPT_POINTZ + || nSHPType == SHPT_POLYGONZ + || nSHPType == SHPT_MULTIPOINTZ + || nSHPType == SHPT_MULTIPATCH ) + { + bHasM = TRUE; + bHasZ = TRUE; + } + else + { + bHasM = FALSE; + bHasZ = FALSE; + } + +/* -------------------------------------------------------------------- */ +/* Capture parts. Note that part type is optional, and */ +/* defaults to ring. */ +/* -------------------------------------------------------------------- */ + if( nSHPType == SHPT_ARC || nSHPType == SHPT_POLYGON + || nSHPType == SHPT_ARCM || nSHPType == SHPT_POLYGONM + || nSHPType == SHPT_ARCZ || nSHPType == SHPT_POLYGONZ + || nSHPType == SHPT_MULTIPATCH ) + { + psObject->nParts = MAX(1,nParts); + + psObject->panPartStart = (int *) + malloc(sizeof(int) * psObject->nParts); + psObject->panPartType = (int *) + malloc(sizeof(int) * psObject->nParts); + + psObject->panPartStart[0] = 0; + psObject->panPartType[0] = SHPP_RING; + + for( i = 0; i < nParts; i++ ) + { + psObject->panPartStart[i] = panPartStart[i]; + if( panPartType != NULL ) + psObject->panPartType[i] = panPartType[i]; + else + psObject->panPartType[i] = SHPP_RING; + } + } + +/* -------------------------------------------------------------------- */ +/* Capture vertices. Note that Z and M are optional, but X and */ +/* Y are not. */ +/* -------------------------------------------------------------------- */ + if( nVertices > 0 ) + { + psObject->padfX = (double *) calloc(sizeof(double),nVertices); + psObject->padfY = (double *) calloc(sizeof(double),nVertices); + psObject->padfZ = (double *) calloc(sizeof(double),nVertices); + psObject->padfM = (double *) calloc(sizeof(double),nVertices); + + assert( padfX != NULL ); + assert( padfY != NULL ); + + for( i = 0; i < nVertices; i++ ) + { + psObject->padfX[i] = padfX[i]; + psObject->padfY[i] = padfY[i]; + if( padfZ != NULL && bHasZ ) + psObject->padfZ[i] = padfZ[i]; + if( padfM != NULL && bHasM ) + psObject->padfM[i] = padfM[i]; + } + } + +/* -------------------------------------------------------------------- */ +/* Compute the extents. */ +/* -------------------------------------------------------------------- */ + psObject->nVertices = nVertices; + SHPComputeExtents( psObject ); + + return( psObject ); +} + +/************************************************************************/ +/* SHPCreateSimpleObject() */ +/* */ +/* Create a simple (common) shape object. Destroy with */ +/* SHPDestroyObject(). */ +/************************************************************************/ + +SHPObject SHPAPI_CALL1(*) +SHPCreateSimpleObject( int nSHPType, int nVertices, + const double * padfX, const double * padfY, + const double * padfZ ) + +{ + return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL, + nVertices, padfX, padfY, padfZ, NULL ) ); +} + +/************************************************************************/ +/* SHPWriteObject() */ +/* */ +/* Write out the vertices of a new structure. Note that it is */ +/* only possible to write vertices at the end of the file. */ +/************************************************************************/ + +int SHPAPI_CALL +SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject ) + +{ + int nRecordOffset, i, nRecordSize; + uchar *pabyRec; + int32 i32; + + nRecordSize = 0; + psSHP->bUpdated = TRUE; + +/* -------------------------------------------------------------------- */ +/* Ensure that shape object matches the type of the file it is */ +/* being written to. */ +/* -------------------------------------------------------------------- */ + assert( psObject->nSHPType == psSHP->nShapeType + || psObject->nSHPType == SHPT_NULL ); + +/* -------------------------------------------------------------------- */ +/* Ensure that -1 is used for appends. Either blow an */ +/* assertion, or if they are disabled, set the shapeid to -1 */ +/* for appends. */ +/* -------------------------------------------------------------------- */ + assert( nShapeId == -1 + || (nShapeId >= 0 && nShapeId < psSHP->nRecords) ); + + if( nShapeId != -1 && nShapeId >= psSHP->nRecords ) + nShapeId = -1; + +/* -------------------------------------------------------------------- */ +/* Add the new entity to the in memory index. */ +/* -------------------------------------------------------------------- */ + if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords ) + { + psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100); + + psSHP->panRecOffset = (int *) + SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords ); + psSHP->panRecSize = (int *) + SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords ); + } + +/* -------------------------------------------------------------------- */ +/* Initialize record. */ +/* -------------------------------------------------------------------- */ + pabyRec = (uchar *) malloc(psObject->nVertices * 4 * sizeof(double) + + psObject->nParts * 8 + 128); + +/* -------------------------------------------------------------------- */ +/* Extract vertices for a Polygon or Arc. */ +/* -------------------------------------------------------------------- */ + if( psObject->nSHPType == SHPT_POLYGON + || psObject->nSHPType == SHPT_POLYGONZ + || psObject->nSHPType == SHPT_POLYGONM + || psObject->nSHPType == SHPT_ARC + || psObject->nSHPType == SHPT_ARCZ + || psObject->nSHPType == SHPT_ARCM + || psObject->nSHPType == SHPT_MULTIPATCH ) + { + int32 nPoints, nParts; + int i; + + nPoints = psObject->nVertices; + nParts = psObject->nParts; + + _SHPSetBounds( pabyRec + 12, psObject ); + + if( bBigEndian ) SwapWord( 4, &nPoints ); + if( bBigEndian ) SwapWord( 4, &nParts ); + + ByteCopy( &nPoints, pabyRec + 40 + 8, 4 ); + ByteCopy( &nParts, pabyRec + 36 + 8, 4 ); + + nRecordSize = 52; + + /* + * Write part start positions. + */ + ByteCopy( psObject->panPartStart, pabyRec + 44 + 8, + 4 * psObject->nParts ); + for( i = 0; i < psObject->nParts; i++ ) + { + if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i ); + nRecordSize += 4; + } + + /* + * Write multipatch part types if needed. + */ + if( psObject->nSHPType == SHPT_MULTIPATCH ) + { + memcpy( pabyRec + nRecordSize, psObject->panPartType, + 4*psObject->nParts ); + for( i = 0; i < psObject->nParts; i++ ) + { + if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize ); + nRecordSize += 4; + } + } + + /* + * Write the (x,y) vertex values. + */ + for( i = 0; i < psObject->nVertices; i++ ) + { + ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 ); + ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 ); + + if( bBigEndian ) + SwapWord( 8, pabyRec + nRecordSize ); + + if( bBigEndian ) + SwapWord( 8, pabyRec + nRecordSize + 8 ); + + nRecordSize += 2 * 8; + } + + /* + * Write the Z coordinates (if any). + */ + if( psObject->nSHPType == SHPT_POLYGONZ + || psObject->nSHPType == SHPT_ARCZ + || psObject->nSHPType == SHPT_MULTIPATCH ) + { + ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + + ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + + for( i = 0; i < psObject->nVertices; i++ ) + { + ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + } + } + + /* + * Write the M values, if any. + */ + if( psObject->nSHPType == SHPT_POLYGONM + || psObject->nSHPType == SHPT_ARCM +#ifndef DISABLE_MULTIPATCH_MEASURE + || psObject->nSHPType == SHPT_MULTIPATCH +#endif + || psObject->nSHPType == SHPT_POLYGONZ + || psObject->nSHPType == SHPT_ARCZ ) + { + ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + + ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + + for( i = 0; i < psObject->nVertices; i++ ) + { + ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + } + } + } + +/* -------------------------------------------------------------------- */ +/* Extract vertices for a MultiPoint. */ +/* -------------------------------------------------------------------- */ + else if( psObject->nSHPType == SHPT_MULTIPOINT + || psObject->nSHPType == SHPT_MULTIPOINTZ + || psObject->nSHPType == SHPT_MULTIPOINTM ) + { + int32 nPoints; + int i; + + nPoints = psObject->nVertices; + + _SHPSetBounds( pabyRec + 12, psObject ); + + if( bBigEndian ) SwapWord( 4, &nPoints ); + ByteCopy( &nPoints, pabyRec + 44, 4 ); + + for( i = 0; i < psObject->nVertices; i++ ) + { + ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 ); + ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 ); + + if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 ); + if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 ); + } + + nRecordSize = 48 + 16 * psObject->nVertices; + + if( psObject->nSHPType == SHPT_MULTIPOINTZ ) + { + ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + + ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + + for( i = 0; i < psObject->nVertices; i++ ) + { + ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + } + } + + if( psObject->nSHPType == SHPT_MULTIPOINTZ + || psObject->nSHPType == SHPT_MULTIPOINTM ) + { + ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + + ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + + for( i = 0; i < psObject->nVertices; i++ ) + { + ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + } + } + } + +/* -------------------------------------------------------------------- */ +/* Write point. */ +/* -------------------------------------------------------------------- */ + else if( psObject->nSHPType == SHPT_POINT + || psObject->nSHPType == SHPT_POINTZ + || psObject->nSHPType == SHPT_POINTM ) + { + ByteCopy( psObject->padfX, pabyRec + 12, 8 ); + ByteCopy( psObject->padfY, pabyRec + 20, 8 ); + + if( bBigEndian ) SwapWord( 8, pabyRec + 12 ); + if( bBigEndian ) SwapWord( 8, pabyRec + 20 ); + + nRecordSize = 28; + + if( psObject->nSHPType == SHPT_POINTZ ) + { + ByteCopy( psObject->padfZ, pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + } + + if( psObject->nSHPType == SHPT_POINTZ + || psObject->nSHPType == SHPT_POINTM ) + { + ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 ); + if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); + nRecordSize += 8; + } + } + +/* -------------------------------------------------------------------- */ +/* Not much to do for null geometries. */ +/* -------------------------------------------------------------------- */ + else if( psObject->nSHPType == SHPT_NULL ) + { + nRecordSize = 12; + } + + else + { + /* unknown type */ + assert( FALSE ); + } + +/* -------------------------------------------------------------------- */ +/* Establish where we are going to put this record. If we are */ +/* rewriting and existing record, and it will fit, then put it */ +/* back where the original came from. Otherwise write at the end. */ +/* -------------------------------------------------------------------- */ + if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 ) + { + if( nShapeId == -1 ) + nShapeId = psSHP->nRecords++; + + psSHP->panRecOffset[nShapeId] = nRecordOffset = psSHP->nFileSize; + psSHP->panRecSize[nShapeId] = nRecordSize-8; + psSHP->nFileSize += nRecordSize; + } + else + { + nRecordOffset = psSHP->panRecOffset[nShapeId]; + } + +/* -------------------------------------------------------------------- */ +/* Set the shape type, record number, and record size. */ +/* -------------------------------------------------------------------- */ + i32 = nShapeId+1; /* record # */ + if( !bBigEndian ) SwapWord( 4, &i32 ); + ByteCopy( &i32, pabyRec, 4 ); + + i32 = (nRecordSize-8)/2; /* record size */ + if( !bBigEndian ) SwapWord( 4, &i32 ); + ByteCopy( &i32, pabyRec + 4, 4 ); + + i32 = psObject->nSHPType; /* shape type */ + if( bBigEndian ) SwapWord( 4, &i32 ); + ByteCopy( &i32, pabyRec + 8, 4 ); + +/* -------------------------------------------------------------------- */ +/* Write out record. */ +/* -------------------------------------------------------------------- */ + if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 + || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 ) + { + printf( "Error in fseek() or fwrite().\n" ); + free( pabyRec ); + return -1; + } + + free( pabyRec ); + +/* -------------------------------------------------------------------- */ +/* Expand file wide bounds based on this shape. */ +/* -------------------------------------------------------------------- */ + if( psSHP->adBoundsMin[0] == 0.0 + && psSHP->adBoundsMax[0] == 0.0 + && psSHP->adBoundsMin[1] == 0.0 + && psSHP->adBoundsMax[1] == 0.0 + && psObject->nSHPType != SHPT_NULL ) + { + psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0]; + psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0]; + psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0]; + psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0]; + } + + for( i = 0; i < psObject->nVertices; i++ ) + { + psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]); + psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]); + psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]); + psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]); + psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]); + psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]); + psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]); + psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]); + } + + return( nShapeId ); +} + +/************************************************************************/ +/* SHPReadObject() */ +/* */ +/* Read the vertices, parts, and other non-attribute information */ +/* for one shape. */ +/************************************************************************/ + +SHPObject SHPAPI_CALL1(*) +SHPReadObject( SHPHandle psSHP, int hEntity ) + +{ + SHPObject *psShape; + +/* -------------------------------------------------------------------- */ +/* Validate the record/entity number. */ +/* -------------------------------------------------------------------- */ + if( hEntity < 0 || hEntity >= psSHP->nRecords ) + return( NULL ); + +/* -------------------------------------------------------------------- */ +/* Ensure our record buffer is large enough. */ +/* -------------------------------------------------------------------- */ + if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize ) + { + psSHP->nBufSize = psSHP->panRecSize[hEntity]+8; + psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize); + } + +/* -------------------------------------------------------------------- */ +/* Read the record. */ +/* -------------------------------------------------------------------- */ + fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ); + fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP ); + +/* -------------------------------------------------------------------- */ +/* Allocate and minimally initialize the object. */ +/* -------------------------------------------------------------------- */ + psShape = (SHPObject *) calloc(1,sizeof(SHPObject)); + psShape->nShapeId = hEntity; + + memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 ); + if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) ); + +/* ==================================================================== */ +/* Extract vertices for a Polygon or Arc. */ +/* ==================================================================== */ + if( psShape->nSHPType == SHPT_POLYGON || psShape->nSHPType == SHPT_ARC + || psShape->nSHPType == SHPT_POLYGONZ + || psShape->nSHPType == SHPT_POLYGONM + || psShape->nSHPType == SHPT_ARCZ + || psShape->nSHPType == SHPT_ARCM + || psShape->nSHPType == SHPT_MULTIPATCH ) + { + int32 nPoints, nParts; + int i, nOffset; + +/* -------------------------------------------------------------------- */ +/* Get the X/Y bounds. */ +/* -------------------------------------------------------------------- */ + memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); + memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); + memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); + memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); + + if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); + if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); + if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) ); + if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) ); + +/* -------------------------------------------------------------------- */ +/* Extract part/point count, and build vertex and part arrays */ +/* to proper size. */ +/* -------------------------------------------------------------------- */ + memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 ); + memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 ); + + if( bBigEndian ) SwapWord( 4, &nPoints ); + if( bBigEndian ) SwapWord( 4, &nParts ); + + psShape->nVertices = nPoints; + psShape->padfX = (double *) calloc(nPoints,sizeof(double)); + psShape->padfY = (double *) calloc(nPoints,sizeof(double)); + psShape->padfZ = (double *) calloc(nPoints,sizeof(double)); + psShape->padfM = (double *) calloc(nPoints,sizeof(double)); + + psShape->nParts = nParts; + psShape->panPartStart = (int *) calloc(nParts,sizeof(int)); + psShape->panPartType = (int *) calloc(nParts,sizeof(int)); + + for( i = 0; i < nParts; i++ ) + psShape->panPartType[i] = SHPP_RING; + +/* -------------------------------------------------------------------- */ +/* Copy out the part array from the record. */ +/* -------------------------------------------------------------------- */ + memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts ); + for( i = 0; i < nParts; i++ ) + { + if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i ); + } + + nOffset = 44 + 8 + 4*nParts; + +/* -------------------------------------------------------------------- */ +/* If this is a multipatch, we will also have parts types. */ +/* -------------------------------------------------------------------- */ + if( psShape->nSHPType == SHPT_MULTIPATCH ) + { + memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts ); + for( i = 0; i < nParts; i++ ) + { + if( bBigEndian ) SwapWord( 4, psShape->panPartType+i ); + } + + nOffset += 4*nParts; + } + +/* -------------------------------------------------------------------- */ +/* Copy out the vertices from the record. */ +/* -------------------------------------------------------------------- */ + for( i = 0; i < nPoints; i++ ) + { + memcpy(psShape->padfX + i, + psSHP->pabyRec + nOffset + i * 16, + 8 ); + + memcpy(psShape->padfY + i, + psSHP->pabyRec + nOffset + i * 16 + 8, + 8 ); + + if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); + if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); + } + + nOffset += 16*nPoints; + +/* -------------------------------------------------------------------- */ +/* If we have a Z coordinate, collect that now. */ +/* -------------------------------------------------------------------- */ + if( psShape->nSHPType == SHPT_POLYGONZ + || psShape->nSHPType == SHPT_ARCZ + || psShape->nSHPType == SHPT_MULTIPATCH ) + { + memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); + memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); + + if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); + if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); + + for( i = 0; i < nPoints; i++ ) + { + memcpy( psShape->padfZ + i, + psSHP->pabyRec + nOffset + 16 + i*8, 8 ); + if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); + } + + nOffset += 16 + 8*nPoints; + } + +/* -------------------------------------------------------------------- */ +/* If we have a M measure value, then read it now. We assume */ +/* that the measure can be present for any shape if the size is */ +/* big enough, but really it will only occur for the Z shapes */ +/* (options), and the M shapes. */ +/* -------------------------------------------------------------------- */ + if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) + { + memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); + memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); + + if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); + if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); + + for( i = 0; i < nPoints; i++ ) + { + memcpy( psShape->padfM + i, + psSHP->pabyRec + nOffset + 16 + i*8, 8 ); + if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); + } + } + + } + +/* ==================================================================== */ +/* Extract vertices for a MultiPoint. */ +/* ==================================================================== */ + else if( psShape->nSHPType == SHPT_MULTIPOINT + || psShape->nSHPType == SHPT_MULTIPOINTM + || psShape->nSHPType == SHPT_MULTIPOINTZ ) + { + int32 nPoints; + int i, nOffset; + + memcpy( &nPoints, psSHP->pabyRec + 44, 4 ); + if( bBigEndian ) SwapWord( 4, &nPoints ); + + psShape->nVertices = nPoints; + psShape->padfX = (double *) calloc(nPoints,sizeof(double)); + psShape->padfY = (double *) calloc(nPoints,sizeof(double)); + psShape->padfZ = (double *) calloc(nPoints,sizeof(double)); + psShape->padfM = (double *) calloc(nPoints,sizeof(double)); + + for( i = 0; i < nPoints; i++ ) + { + memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 ); + memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 ); + + if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); + if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); + } + + nOffset = 48 + 16*nPoints; + +/* -------------------------------------------------------------------- */ +/* Get the X/Y bounds. */ +/* -------------------------------------------------------------------- */ + memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); + memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); + memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); + memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); + + if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); + if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); + if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) ); + if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) ); + +/* -------------------------------------------------------------------- */ +/* If we have a Z coordinate, collect that now. */ +/* -------------------------------------------------------------------- */ + if( psShape->nSHPType == SHPT_MULTIPOINTZ ) + { + memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); + memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); + + if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); + if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); + + for( i = 0; i < nPoints; i++ ) + { + memcpy( psShape->padfZ + i, + psSHP->pabyRec + nOffset + 16 + i*8, 8 ); + if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); + } + + nOffset += 16 + 8*nPoints; + } + +/* -------------------------------------------------------------------- */ +/* If we have a M measure value, then read it now. We assume */ +/* that the measure can be present for any shape if the size is */ +/* big enough, but really it will only occur for the Z shapes */ +/* (options), and the M shapes. */ +/* -------------------------------------------------------------------- */ + if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) + { + memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); + memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); + + if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); + if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); + + for( i = 0; i < nPoints; i++ ) + { + memcpy( psShape->padfM + i, + psSHP->pabyRec + nOffset + 16 + i*8, 8 ); + if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); + } + } + } + +/* ==================================================================== */ +/* Extract vertices for a point. */ +/* ==================================================================== */ + else if( psShape->nSHPType == SHPT_POINT + || psShape->nSHPType == SHPT_POINTM + || psShape->nSHPType == SHPT_POINTZ ) + { + int nOffset; + + psShape->nVertices = 1; + psShape->padfX = (double *) calloc(1,sizeof(double)); + psShape->padfY = (double *) calloc(1,sizeof(double)); + psShape->padfZ = (double *) calloc(1,sizeof(double)); + psShape->padfM = (double *) calloc(1,sizeof(double)); + + memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 ); + memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 ); + + if( bBigEndian ) SwapWord( 8, psShape->padfX ); + if( bBigEndian ) SwapWord( 8, psShape->padfY ); + + nOffset = 20 + 8; + +/* -------------------------------------------------------------------- */ +/* If we have a Z coordinate, collect that now. */ +/* -------------------------------------------------------------------- */ + if( psShape->nSHPType == SHPT_POINTZ ) + { + memcpy( psShape->padfZ, psSHP->pabyRec + nOffset, 8 ); + + if( bBigEndian ) SwapWord( 8, psShape->padfZ ); + + nOffset += 8; + } + +/* -------------------------------------------------------------------- */ +/* If we have a M measure value, then read it now. We assume */ +/* that the measure can be present for any shape if the size is */ +/* big enough, but really it will only occur for the Z shapes */ +/* (options), and the M shapes. */ +/* -------------------------------------------------------------------- */ + if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 ) + { + memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 ); + + if( bBigEndian ) SwapWord( 8, psShape->padfM ); + } + +/* -------------------------------------------------------------------- */ +/* Since no extents are supplied in the record, we will apply */ +/* them from the single vertex. */ +/* -------------------------------------------------------------------- */ + psShape->dfXMin = psShape->dfXMax = psShape->padfX[0]; + psShape->dfYMin = psShape->dfYMax = psShape->padfY[0]; + psShape->dfZMin = psShape->dfZMax = psShape->padfZ[0]; + psShape->dfMMin = psShape->dfMMax = psShape->padfM[0]; + } + + return( psShape ); +} + +/************************************************************************/ +/* SHPTypeName() */ +/************************************************************************/ + +const char SHPAPI_CALL1(*) +SHPTypeName( int nSHPType ) + +{ + switch( nSHPType ) + { + case SHPT_NULL: + return "NullShape"; + + case SHPT_POINT: + return "Point"; + + case SHPT_ARC: + return "Arc"; + + case SHPT_POLYGON: + return "Polygon"; + + case SHPT_MULTIPOINT: + return "MultiPoint"; + + case SHPT_POINTZ: + return "PointZ"; + + case SHPT_ARCZ: + return "ArcZ"; + + case SHPT_POLYGONZ: + return "PolygonZ"; + + case SHPT_MULTIPOINTZ: + return "MultiPointZ"; + + case SHPT_POINTM: + return "PointM"; + + case SHPT_ARCM: + return "ArcM"; + + case SHPT_POLYGONM: + return "PolygonM"; + + case SHPT_MULTIPOINTM: + return "MultiPointM"; + + case SHPT_MULTIPATCH: + return "MultiPatch"; + + default: + return "UnknownShapeType"; + } +} + +/************************************************************************/ +/* SHPPartTypeName() */ +/************************************************************************/ + +const char SHPAPI_CALL1(*) +SHPPartTypeName( int nPartType ) + +{ + switch( nPartType ) + { + case SHPP_TRISTRIP: + return "TriangleStrip"; + + case SHPP_TRIFAN: + return "TriangleFan"; + + case SHPP_OUTERRING: + return "OuterRing"; + + case SHPP_INNERRING: + return "InnerRing"; + + case SHPP_FIRSTRING: + return "FirstRing"; + + case SHPP_RING: + return "Ring"; + + default: + return "UnknownPartType"; + } +} + +/************************************************************************/ +/* SHPDestroyObject() */ +/************************************************************************/ + +void SHPAPI_CALL +SHPDestroyObject( SHPObject * psShape ) + +{ + if( psShape == NULL ) + return; + + if( psShape->padfX != NULL ) + free( psShape->padfX ); + if( psShape->padfY != NULL ) + free( psShape->padfY ); + if( psShape->padfZ != NULL ) + free( psShape->padfZ ); + if( psShape->padfM != NULL ) + free( psShape->padfM ); + + if( psShape->panPartStart != NULL ) + free( psShape->panPartStart ); + if( psShape->panPartType != NULL ) + free( psShape->panPartType ); + + free( psShape ); +} + +/************************************************************************/ +/* SHPRewindObject() */ +/* */ +/* Reset the winding of polygon objects to adhere to the */ +/* specification. */ +/************************************************************************/ + +int SHPAPI_CALL +SHPRewindObject( SHPHandle hSHP, SHPObject * psObject ) + +{ + int iOpRing, bAltered = 0; + +/* -------------------------------------------------------------------- */ +/* Do nothing if this is not a polygon object. */ +/* -------------------------------------------------------------------- */ + if( psObject->nSHPType != SHPT_POLYGON + && psObject->nSHPType != SHPT_POLYGONZ + && psObject->nSHPType != SHPT_POLYGONM ) + return 0; + +/* -------------------------------------------------------------------- */ +/* Process each of the rings. */ +/* -------------------------------------------------------------------- */ + for( iOpRing = 0; iOpRing < psObject->nParts; iOpRing++ ) + { + int bInner, iVert, nVertCount, nVertStart, iCheckRing; + double dfSum, dfTestX, dfTestY; + +/* -------------------------------------------------------------------- */ +/* Determine if this ring is an inner ring or an outer ring */ +/* relative to all the other rings. For now we assume the */ +/* first ring is outer and all others are inner, but eventually */ +/* we need to fix this to handle multiple island polygons and */ +/* unordered sets of rings. */ +/* -------------------------------------------------------------------- */ + dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]]; + dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]]; + + bInner = FALSE; + for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ ) + { + int iEdge; + + if( iCheckRing == iOpRing ) + continue; + + nVertStart = psObject->panPartStart[iCheckRing]; + + if( iCheckRing == psObject->nParts-1 ) + nVertCount = psObject->nVertices + - psObject->panPartStart[iCheckRing]; + else + nVertCount = psObject->panPartStart[iCheckRing+1] + - psObject->panPartStart[iCheckRing]; + + for( iEdge = 0; iEdge < nVertCount; iEdge++ ) + { + int iNext; + + if( iEdge < nVertCount-1 ) + iNext = iEdge+1; + else + iNext = 0; + + if( (psObject->padfY[iEdge+nVertStart] < dfTestY + && psObject->padfY[iNext+nVertStart] >= dfTestY) + || (psObject->padfY[iNext+nVertStart] < dfTestY + && psObject->padfY[iEdge+nVertStart] >= dfTestY) ) + { + if( psObject->padfX[iEdge+nVertStart] + + (dfTestY - psObject->padfY[iEdge+nVertStart]) + / (psObject->padfY[iNext+nVertStart] + - psObject->padfY[iEdge+nVertStart]) + * (psObject->padfX[iNext+nVertStart] + - psObject->padfX[iEdge+nVertStart]) < dfTestX ) + bInner = !bInner; + } + } + } + +/* -------------------------------------------------------------------- */ +/* Determine the current order of this ring so we will know if */ +/* it has to be reversed. */ +/* -------------------------------------------------------------------- */ + nVertStart = psObject->panPartStart[iOpRing]; + + if( iOpRing == psObject->nParts-1 ) + nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing]; + else + nVertCount = psObject->panPartStart[iOpRing+1] + - psObject->panPartStart[iOpRing]; + + dfSum = 0.0; + for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ ) + { + dfSum += psObject->padfX[iVert] * psObject->padfY[iVert+1] + - psObject->padfY[iVert] * psObject->padfX[iVert+1]; + } + + dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart] + - psObject->padfY[iVert] * psObject->padfX[nVertStart]; + +/* -------------------------------------------------------------------- */ +/* Reverse if necessary. */ +/* -------------------------------------------------------------------- */ + if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) ) + { + int i; + + bAltered++; + for( i = 0; i < nVertCount/2; i++ ) + { + double dfSaved; + + /* Swap X */ + dfSaved = psObject->padfX[nVertStart+i]; + psObject->padfX[nVertStart+i] = + psObject->padfX[nVertStart+nVertCount-i-1]; + psObject->padfX[nVertStart+nVertCount-i-1] = dfSaved; + + /* Swap Y */ + dfSaved = psObject->padfY[nVertStart+i]; + psObject->padfY[nVertStart+i] = + psObject->padfY[nVertStart+nVertCount-i-1]; + psObject->padfY[nVertStart+nVertCount-i-1] = dfSaved; + + /* Swap Z */ + if( psObject->padfZ ) + { + dfSaved = psObject->padfZ[nVertStart+i]; + psObject->padfZ[nVertStart+i] = + psObject->padfZ[nVertStart+nVertCount-i-1]; + psObject->padfZ[nVertStart+nVertCount-i-1] = dfSaved; + } + + /* Swap M */ + if( psObject->padfM ) + { + dfSaved = psObject->padfM[nVertStart+i]; + psObject->padfM[nVertStart+i] = + psObject->padfM[nVertStart+nVertCount-i-1]; + psObject->padfM[nVertStart+nVertCount-i-1] = dfSaved; + } + } + } + } + + return bAltered; +} +#endif diff --git a/smplrout.c b/smplrout.c new file mode 100644 index 000000000..a7bdd2edb --- /dev/null +++ b/smplrout.c @@ -0,0 +1,352 @@ +/* + Route simplification filter + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +/* The following comments are from an email I wrote to Paul Fox in November + * 2005 in an attempt to explain how the cross track error minimization method + * works (RLP 2005): + * + * It's pretty simple, really: for each triplet of vertices A-B-C, we compute + * how much cross-track error we'd introduce by going straight from A to C + * (the maximum cross-track error for that segment is the height of the + * triangle ABC, measured between vertex B and edge AC.) If we need to remove + * 40 points, we just sort the points by that metric and remove the 40 + * smallest ones. + * + * It's actually a little more complicated than that, because removing a + * point changes the result for its two nearest neighbors. When we remove + * one, we recompute the neighbors and then sort them back into the list + * at their new locations. + * + * As you can see, this hasn't been shown to be an optimal algorithm. After + * all, removing one high-xte point might create two very low-xte neighbors + * that more than make up for the high xte of the original point. I believe + * the optimal algorithm would be NP-complete, but I haven't proven it. This + * is really more of a heuristic than anything, but it seems to work well for + * the routes I've fed it. + * + * Not in that email was an explanation of how the pathlength-based calculation + * works: instead of computing the height of the triangle, we just compute + * the difference in pathlength from taking the direct route. This case, + * too, is only a heuristic, as it's possible that a different combination or + * order of point removals could lead to a smaller number of points with less + * reduction in path length. In the case of pathlength, error is cumulative. + */ + + +#include "defs.h" +#include "filterdefs.h" +#include "grtcirc.h" + +#define MYNAME "Route simplification filter" + +static int count = 0; +static double totalerror = 0; +static double error = 0; + +static char *countopt = NULL; +static char *erroropt = NULL; +static char *xteopt = NULL; +static char *lenopt = NULL; +void (*waypt_del_fnp) (route_head *rte, waypoint *wpt); + +static +arglist_t routesimple_args[] = { + {"count", &countopt, "Maximum number of points in route", + NULL, ARGTYPE_INT | ARGTYPE_BEGIN_REQ | ARGTYPE_BEGIN_EXCL, "1", NULL}, + {"error", &erroropt, "Maximum error", NULL, + ARGTYPE_STRING | ARGTYPE_END_REQ | ARGTYPE_END_EXCL, "0", NULL}, + {"crosstrack", &xteopt, "Use cross-track error (default)", NULL, + ARGTYPE_BOOL | ARGTYPE_BEGIN_EXCL, ARG_NOMINMAX }, + {"length", &lenopt, "Use arclength error", NULL, + ARGTYPE_BOOL | ARGTYPE_END_EXCL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +struct xte_intermed; + +struct xte { + double distance; + int ordinal; + struct xte_intermed *intermed; +}; + +struct xte_intermed { + struct xte *xte_rec; + struct xte_intermed *next; + struct xte_intermed *prev; + const waypoint *wpt; +}; + +void +free_xte( struct xte *xte_rec ) +{ + xfree(xte_rec->intermed); +} + +#define HUGEVAL 2000000000 + +static struct xte_intermed *tmpprev = NULL; +static int xte_count = 0; +static const route_head *cur_rte = NULL; +static struct xte *xte_recs = NULL; + +void +routesimple_waypt_pr( const waypoint *wpt ) +{ + if ( !cur_rte ) return; + xte_recs[xte_count].ordinal=xte_count; + xte_recs[xte_count].intermed = (struct xte_intermed *) xmalloc( sizeof(struct xte_intermed)); + xte_recs[xte_count].intermed->wpt = wpt; + xte_recs[xte_count].intermed->xte_rec = xte_recs+xte_count; + xte_recs[xte_count].intermed->next = NULL; + xte_recs[xte_count].intermed->prev = tmpprev; + if ( tmpprev ) { + tmpprev->next = xte_recs[xte_count].intermed; + } + tmpprev = xte_recs[xte_count].intermed; + xte_count++; +} + +void +compute_xte( struct xte *xte_rec ) { + const waypoint *wpt3 = xte_rec->intermed->wpt; + const waypoint *wpt1 = NULL; + const waypoint *wpt2 = NULL; + /* if no previous, this is an endpoint and must be preserved. */ + if ( !xte_rec->intermed->prev ) { + xte_rec->distance = HUGEVAL; + return; + } + wpt1 = xte_rec->intermed->prev->wpt; + + /* if no next, this is an endpoint and must be preserved. */ + if ( !xte_rec->intermed->next ) { + xte_rec->distance = HUGEVAL; + return; + } + wpt2 = xte_rec->intermed->next->wpt; + + if ( xteopt || !lenopt ) { + xte_rec->distance = radtomiles(linedist( + wpt1->latitude, wpt1->longitude, + wpt2->latitude, wpt2->longitude, + wpt3->latitude, wpt3->longitude )); + } + else { + xte_rec->distance = radtomiles( + gcdist( wpt1->latitude, wpt1->longitude, + wpt3->latitude, wpt3->longitude ) + + gcdist( wpt3->latitude, wpt3->longitude, + wpt2->latitude, wpt2->longitude ) - + gcdist( wpt1->latitude, wpt1->longitude, + wpt2->latitude, wpt2->longitude )); + } +} + + +int +compare_xte( const void *a, const void *b ) +{ + double distdiff = ((struct xte *)a)->distance - + ((struct xte *)b)->distance; + int priodiff = ((struct xte *)a)->intermed->wpt->route_priority - + ((struct xte *)b)->intermed->wpt->route_priority; + + if (HUGEVAL == ((struct xte *)a)->distance) + return -1; + + if (HUGEVAL == ((struct xte *)b)->distance) + return 1; + + if ( priodiff < 0 ) return 1; + if ( priodiff > 0 ) return -1; + if ( distdiff < 0 ) return 1; + if ( distdiff > 0 ) return -1; + return 0; +} + +void +routesimple_head( const route_head *rte ) +{ + cur_rte = NULL; + /* build array of XTE/wpt xref records */ + xte_count = 0; + tmpprev = NULL; + totalerror = 0; + + /* short-circuit if we already have fewer than the max points */ + if ( countopt && count >= rte->rte_waypt_ct) return; + + /* short-circuit if the route is impossible to simplify, too. */ + if ( 2 >= rte->rte_waypt_ct ) return; + + xte_recs = (struct xte *) xcalloc( rte->rte_waypt_ct, sizeof (struct xte)); + cur_rte = rte; + +} + +void +shuffle_xte( struct xte *xte_rec ) +{ + struct xte tmp_xte; + while ( xte_rec > xte_recs && compare_xte(xte_rec, xte_rec-1) < 0 ) { + tmp_xte.distance = xte_rec->distance; + tmp_xte.ordinal = xte_rec->ordinal; + tmp_xte.intermed = xte_rec->intermed; + xte_rec->distance = xte_rec[-1].distance; + xte_rec->ordinal = xte_rec[-1].ordinal; + xte_rec->intermed = xte_rec[-1].intermed; + xte_rec->intermed->xte_rec = xte_rec; + xte_rec--; + xte_rec->distance = tmp_xte.distance; + xte_rec->ordinal = tmp_xte.ordinal; + xte_rec->intermed = tmp_xte.intermed; + xte_rec->intermed->xte_rec = xte_rec; + } + while ( xte_rec - xte_recs < xte_count-2 && + compare_xte( xte_rec, xte_rec+1) > 0 ) { + tmp_xte.distance = xte_rec->distance; + tmp_xte.ordinal = xte_rec->ordinal; + tmp_xte.intermed = xte_rec->intermed; + xte_rec->distance = xte_rec[1].distance; + xte_rec->ordinal = xte_rec[1].ordinal; + xte_rec->intermed = xte_rec[1].intermed; + xte_rec->intermed->xte_rec = xte_rec; + xte_rec++; + xte_rec->distance = tmp_xte.distance; + xte_rec->ordinal = tmp_xte.ordinal; + xte_rec->intermed = tmp_xte.intermed; + xte_rec->intermed->xte_rec = xte_rec; + } +} + +void +routesimple_tail( const route_head *rte ) +{ + int i; + if ( !cur_rte ) return; + + /* compute all distances */ + for (i = 0; i < xte_count ; i++ ) { + compute_xte( xte_recs+i ); + } + + + /* sort XTE array, lowest XTE last */ + qsort( xte_recs, xte_count, sizeof( struct xte ), compare_xte ); + + for (i = 0; i < xte_count; i++ ) { + xte_recs[i].intermed->xte_rec = xte_recs+i; + } + /* while we still have too many records... */ + while ( (countopt && count < xte_count) || (erroropt && totalerror < error) ) { + i = xte_count - 1; + /* remove the record with the lowest XTE */ + if ( erroropt ) { + if ( xteopt ) { + if ( i > 1 ) { + totalerror = xte_recs[i-1].distance; + } + else { + totalerror = xte_recs[i].distance; + } + } + if ( lenopt ) { + totalerror += xte_recs[i].distance; + } + } + (*waypt_del_fnp)( (route_head *)(void *)rte, + (waypoint *)(void *)(xte_recs[i].intermed->wpt)); + waypt_free((waypoint *)(void *)(xte_recs[i].intermed->wpt)); + + if ( xte_recs[i].intermed->prev ) { + xte_recs[i].intermed->prev->next = xte_recs[i].intermed->next; + compute_xte(xte_recs[i].intermed->prev->xte_rec); + shuffle_xte(xte_recs[i].intermed->prev->xte_rec); + } + if ( xte_recs[i].intermed->next ) { + xte_recs[i].intermed->next->prev = xte_recs[i].intermed->prev; + compute_xte(xte_recs[i].intermed->next->xte_rec); + shuffle_xte(xte_recs[i].intermed->next->xte_rec); + } + xte_count--; + free_xte( xte_recs+xte_count); + /* end of loop */ + } + if ( xte_count ) { + do { + xte_count--; + free_xte( xte_recs+xte_count ); + } while(xte_count); + } + xfree( xte_recs ); +} + +void +routesimple_process( void ) +{ + waypt_del_fnp = route_del_wpt; + route_disp_all( routesimple_head, routesimple_tail, routesimple_waypt_pr ); + + waypt_del_fnp = track_del_wpt; + track_disp_all( routesimple_head, routesimple_tail, routesimple_waypt_pr ); +} + +void +routesimple_init(const char *args) { + char *fm = NULL; + count = 0; + + if ( !!countopt == !!erroropt ) { + fatal( MYNAME ": You must specify either count or error, but not both.\n"); + } + if ( xteopt && lenopt ) { + fatal( MYNAME ": crosstrack and length may not be used together.\n"); + } + if ( !xteopt && !lenopt ) { + xteopt = (char *)xmalloc( 1 ); + } + + if (countopt) { + count = atol(countopt); + } + if (erroropt) { + error = strtod(erroropt, &fm); + + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to miles */ + error *= .6214; + } + } +} + +void +routesimple_deinit(void) { + /* do nothing */ +} + +filter_vecs_t routesimple_vecs = { + routesimple_init, + routesimple_process, + routesimple_deinit, + NULL, + routesimple_args +}; diff --git a/sort.c b/sort.c new file mode 100644 index 000000000..52c9bd810 --- /dev/null +++ b/sort.c @@ -0,0 +1,92 @@ +/* + Arbitrary Sorting Filter(s) + + Copyright (C) 2004 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED + +typedef enum { + sm_unknown = 0, + sm_gcid, + sm_shortname, + sm_description, + sm_time +} sort_mode_; + +sort_mode_ sort_mode = sm_shortname; /* How are we sorting these? */ + +static char *opt_sm_gcid, *opt_sm_shortname, *opt_sm_description, *opt_sm_time; + +static +arglist_t sort_args[] = { + {"gcid", &opt_sm_gcid, "Sort by numeric geocache ID", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"shortname", &opt_sm_shortname, "Sort by waypoint short name", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"description", &opt_sm_description, "Sort by waypoint description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"time", &opt_sm_time, "Sort by time", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static int +sort_comp(const queue * a, const queue * b) +{ + const waypoint *x1 = (waypoint *)a; + const waypoint *x2 = (waypoint *)b; + + switch (sort_mode) { + case sm_gcid: return x1->gc_data.id - x2->gc_data.id; + case sm_shortname: return strcmp (x1->shortname, x2->shortname); + case sm_description: return strcmp (x1->description, x2->description); + case sm_time: return x1->creation_time - x2->creation_time; + default: abort(); return 0; /* Internal caller error. */ + } +} + +void +sort_process(void) +{ + sortqueue(&waypt_head, sort_comp); +} + +void +sort_init(const char *args) +{ + if (opt_sm_gcid) + sort_mode = sm_gcid; + if (opt_sm_shortname) + sort_mode = sm_shortname; + if (opt_sm_description) + sort_mode = sm_description; + if (opt_sm_time) + sort_mode = sm_time; +} + +filter_vecs_t sort_vecs = { + sort_init, + sort_process, + NULL, + NULL, + sort_args +}; +#endif // FILTERS_ENABLED diff --git a/stackfilter.c b/stackfilter.c new file mode 100644 index 000000000..e8bbf71e6 --- /dev/null +++ b/stackfilter.c @@ -0,0 +1,250 @@ +/* + Stack filter + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED + +#define MYNAME "Stack filter" + +static char *opt_push = NULL; +static char *opt_copy = NULL; +static char *opt_pop = NULL; +static char *opt_append = NULL; +static char *opt_discard = NULL; +static char *opt_replace = NULL; +static char *opt_swap = NULL; +static char *opt_depth = NULL; +static char *nowarn = NULL; +static int warnings_enabled = 1; +static int swapdepth = 0; + +static +arglist_t stackfilt_args[] = { + {"push", &opt_push, "Push waypoint list onto stack", NULL, + ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, + {"pop", &opt_pop, "Pop waypoint list from stack", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX}, + {"swap", &opt_swap, "Swap waypoint list with item on stack", + NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, + {"copy", &opt_copy, "(push) Copy waypoint list", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX}, + {"append", &opt_append, "(pop) Append list", NULL, + ARGTYPE_BEGIN_EXCL | ARGTYPE_BOOL, ARG_NOMINMAX}, + {"discard", &opt_discard, "(pop) Discard top of stack", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"replace", &opt_replace, "(pop) Replace list (default)", + NULL, ARGTYPE_END_EXCL | ARGTYPE_BOOL, ARG_NOMINMAX}, + {"depth", &opt_depth, "(swap) Item to use (default=1)", + NULL, ARGTYPE_INT, "0", NULL}, + {"nowarn", &nowarn, "Suppress cleanup warning", NULL, + ARGTYPE_BOOL | ARGTYPE_HIDDEN, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +struct stack_elt { + queue waypts; + queue routes; + queue tracks; + unsigned int waypt_ct; + int route_count; + int track_count; + struct stack_elt *next; +} *stack = NULL; + + +void +stackfilt_process(void) +{ + struct stack_elt *tmp_elt = NULL; + queue *elem = NULL; + queue *tmp = NULL; + queue tmp_queue; + unsigned int tmp_count; + + if ( opt_push ) { + tmp_elt = (struct stack_elt *)xmalloc(sizeof(struct stack_elt)); + + QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head); + tmp_elt->waypt_ct = waypt_count(); + set_waypt_count(0); + tmp_elt->next = stack; + stack = tmp_elt; + if ( opt_copy ) { + QUEUE_FOR_EACH( &(stack->waypts), elem, tmp ) { + waypt_add( waypt_dupe((waypoint *)elem)); + } + } + + tmp = NULL; + route_backup( &(tmp_elt->route_count), &tmp ); + QUEUE_MOVE( &(tmp_elt->routes), tmp ); + xfree( tmp ); + if ( !opt_copy ) { + route_flush_all_routes(); + } + + tmp = NULL; + track_backup( &(tmp_elt->track_count), &tmp ); + QUEUE_MOVE( &(tmp_elt->tracks), tmp ); + xfree( tmp ); + if ( !opt_copy ) { + route_flush_all_tracks(); + } + + } + else if ( opt_pop ) { + tmp_elt = stack; + if ( !tmp_elt ) { + fatal( MYNAME ": stack empty\n"); + } + if ( opt_append ) { + QUEUE_FOR_EACH( &(stack->waypts), elem, tmp ) { + waypt_add( (waypoint *)elem); + } + route_append( &(stack->routes)); + route_flush( &(stack->routes)); + track_append( &(stack->tracks)); + route_flush( &(stack->tracks)); + } + else if ( opt_discard ) { + waypt_flush( &(stack->waypts)); + route_flush( &(stack->routes)); + route_flush( &(stack->tracks)); + } + else { + waypt_flush( &waypt_head ); + QUEUE_MOVE(&(waypt_head), &(stack->waypts) ); + set_waypt_count(stack->waypt_ct); + + route_restore( &(stack->routes)); + track_restore( &(stack->tracks)); + } + + stack = tmp_elt->next; + xfree( tmp_elt ); + } + else if ( opt_swap ) { + tmp_elt = stack; + while ( swapdepth > 1 ) { + if ( !tmp_elt->next ) { + fatal (MYNAME ": swap with nonexistent element\n"); + } + tmp_elt = tmp_elt->next; + swapdepth--; + } + QUEUE_MOVE(&tmp_queue, &(tmp_elt->waypts) ); + QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head ); + QUEUE_MOVE(&waypt_head, &tmp_queue ); + + QUEUE_MOVE(&tmp_queue, &(tmp_elt->routes)); + tmp = NULL; + route_backup( &(tmp_elt->route_count), &tmp); + QUEUE_MOVE(&(tmp_elt->routes), tmp ); + xfree( tmp ); + route_restore( &tmp_queue ); + + QUEUE_MOVE(&tmp_queue, &(tmp_elt->tracks)); + tmp = NULL; + track_backup( &(tmp_elt->track_count), &tmp); + QUEUE_MOVE(&(tmp_elt->tracks), tmp ); + xfree( tmp ); + track_restore( &tmp_queue ); + + tmp_count = waypt_count(); + set_waypt_count( tmp_elt->waypt_ct ); + tmp_elt->waypt_ct = tmp_count; + } +} + +void +stackfilt_init(const char *args) { + + int invalid = 0; + + if ( nowarn ) { + warnings_enabled = 0; + } + + if ( opt_depth ) { + swapdepth = atoi( opt_depth ); + } + if ( opt_push ) { + if ( opt_pop || opt_append || opt_discard || opt_replace || + opt_swap || opt_depth ) { + invalid = 1; + } + } + else if ( opt_pop ) { + if ( opt_push || opt_copy || opt_swap || opt_depth ) { + invalid = 1; + } + if ( !!opt_append + !!opt_discard + !!opt_replace > 1 ) { + invalid = 1; + } + } + else if ( opt_swap ) { + if ( opt_push || opt_copy || opt_pop || opt_append || + opt_discard || opt_replace ) { + invalid = 1; + } + } + else { + invalid = 1; + } + + if ( invalid ) { + fatal (MYNAME ": invalid combination of options\n"); + } + +} + +void +stackfilt_deinit(void) { + swapdepth = 0; +} + +void +stackfilt_exit( void ) { + struct stack_elt *tmp_elt = NULL; + + if ( warnings_enabled && stack ) { + warning( MYNAME " Warning: leftover stack entries; " + "check command line for mistakes\n" ); + } + while ( stack ) { + waypt_flush( &(stack->waypts) ); + tmp_elt = stack; + stack = stack->next; + xfree(tmp_elt); + } +} + +filter_vecs_t stackfilt_vecs = { + stackfilt_init, + stackfilt_process, + stackfilt_deinit, + stackfilt_exit, + stackfilt_args +}; + +#endif // FILTERS_ENABLED diff --git a/stmsdf.c b/stmsdf.c new file mode 100644 index 000000000..ac69fd232 --- /dev/null +++ b/stmsdf.c @@ -0,0 +1,740 @@ +/* + + Support for Suunto Trackmanager SDF format. + + Copyright (C) 2005,2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +/* + 2006/04/05: initial release (not published in GPSBbabel) + 2006/07/19: finished reader and writer for type 4,5,28 of ver. 1 + 2006/10/31: remove wptdata from case statement (data_write) + + ToDo: Ascending/Descending +*/ + +#include "defs.h" + +#if CSVFMTS_ENABLED + +#include +#include +#include +#include + +#include "csv_util.h" +#include "strptime.h" +#include "jeeps/gpsmath.h" +#include "grtcirc.h" + +#include + +#define MYNAME "stmsdf" + +#define ALT(a) (a->altitude != unknown_alt) ? a->altitude : 0 + +typedef enum { + sdf_unknown, + sdf_header, + sdf_points, + sdf_custom +} sdf_section_e; + +static gbfile *fin, *fout; + +static int lineno; +static int datum; +static int filetype; +static route_head *route; +static queue trackpts; +static char *rte_name; +static char *rte_desc; + +static waypoint *trkpt_out; +static route_head *trk_out; + +static double trkpt_dist; +static double minalt, maxalt, maxspeed; +static double this_distance, all_dist; +static time_t this_time, all_time; +static double all_asc, all_desc; +static int this_index; /* from 1 to ... */ +static int all_points; +static int this_points; +static int saved_points; +static time_t start_time; +static unsigned char this_valid; +static short_handle short_h; + +#define route_index this_index +#define track_index this_index +#define all_route_points all_points +#define all_track_points all_points +#define route_points this_points +#define track_points this_points +#define saved_track_points saved_points +#define this_route_valid this_valid + +/* placeholders for options */ + +static char *opt_route_index; +static int opt_route_index_value; + +static +arglist_t stmsdf_args[] = { + { "index", &opt_route_index, + "Index of route (if more the one in source)", "1", ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + + +/* ----------------------------------------------------------- */ + +static void +parse_header(char *line) +{ + char *str; + char *key = NULL; + char *prod = NULL; + int column = -1; + + while ((str = csv_lineparse(line, "=", "", lineno))) + { + line = NULL; + column++; + + switch(column) { + case 0: + key = xstrdup(str); + break; + case 1: + if (case_ignore_strcmp(key, "DATUM") == 0) datum = GPS_Lookup_Datum_Index(str); + else if (case_ignore_strcmp(key, "FILEVERSION") == 0) { + int ver = atoi(str); + is_fatal( (ver != 1), + MYNAME ": This version '%d' is not yet supported. Please report!", ver); + } + else if (case_ignore_strcmp(key, "NAME") == 0) rte_name = xstrdup(str); + else if (case_ignore_strcmp(key, "NOTES") == 0) /* ToDo */; + else if (case_ignore_strcmp(key, "SOURCE") == 0) rte_desc = xstrdup(str); + else if (case_ignore_strcmp(key, "TYPE") == 0) { + filetype = atoi(str); + switch(filetype) { + case 4: /* M9 TrackLog (Suunto Sail Manager) */ + case 5: /* route */ + case 28: /* X9 TrackLog (Suunto Trek Manager */ + break; + + case 78: prod = "S6 SkiChrono"; + case 79: prod = "S6 Skilog"; + + default: + if (prod == NULL) prod = "unknown"; + fatal(MYNAME ": Unsupported file type (%s, type %d)!\n", prod, filetype); + } + } + break; + } + } + if (key) xfree(key); + +} + +static int +track_qsort_cb(const void *a, const void *b) +{ + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; + + return wa->creation_time - wb->creation_time; +} + +static void +finalize_tracks(void) +{ + waypoint **list; + int count = 0; + queue *elem, *tmp; + int index; + route_head *track = NULL; + int trackno = 0; + + count = 0; + QUEUE_FOR_EACH(&trackpts, elem, tmp) { count++; }; + if (count == 0) return; + + list = (void *)xmalloc(count * sizeof(*list)); + + index = 0; + QUEUE_FOR_EACH(&trackpts, elem, tmp) { + list[index] = (waypoint *)elem; + dequeue(elem); + index++; + } + + qsort(list, count, sizeof(*list), track_qsort_cb); + + for (index = 0; index < count; index++) { + waypoint *wpt = list[index]; + if (wpt->microseconds == 2) { /* log continued */ + track = NULL; + } + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + trackno++; + if (rte_name != NULL) { + if (trackno > 1) + xasprintf(&track->rte_name, "%s (%d)", rte_name, trackno); + else + track->rte_name = xstrdup(rte_name); + } + if (rte_desc != NULL) + track->rte_desc = xstrdup(rte_desc); + } + track_add_wpt(track, wpt); + if (wpt->microseconds == 1) { /* log pause */ + track = NULL; + } + wpt->microseconds = 0; + } + + xfree(list); +} + +static void +parse_point(char *line) +{ + char *str; + int column = -1; + int what = -1; /* -1 = unknown, 0 = tp, 1 = mp, 2 = wp, 3 = ap */ + waypoint *wpt = NULL; + char *cx; + int hour, min, sec, day, month, year; + + year = hour = -1; + + while ((str = csv_lineparse(line, ",", "", lineno))) + { + + line = NULL; + column++; + + switch(column) { + + case 0: + if (strcmp(str, "\"TP\"") == 0) { + what = 0; + column++; /* skip name */ + } + else if (strcmp(str, "\"MP\"") == 0) what = 1; + else if (strcmp(str, "\"WP\"") == 0) what = 2; + else if (strcmp(str, "\"AP\"") == 0) what = 3; + else { + warning(MYNAME ": Unknown point type %s at line %d!\n", str, lineno); + return; + } + wpt = waypt_new(); + break; + + case 1: + wpt->shortname = csv_stringclean(str, "\""); + if ((what == 2) || (what == 3)) column += 2; /* doesn't have date and time */ + break; + case 2: + sscanf(str, "%d.%d.%d", &day, &month, &year); + break; + case 3: + while ((cx = strchr(str, '.'))) *cx = ':'; + sscanf(str, "%d:%d:%d", &hour, &min, &sec); + break; + case 4: + wpt->latitude = atof(str); + break; + case 5: + wpt->longitude = atof(str); + break; + case 6: + wpt->altitude = atof(str); + break; + case 7: + switch(what) { + case 0: + WAYPT_SET(wpt, speed, atof(str) * 3.6); break; + case 3: + WAYPT_SET(wpt, proximity, atof(str)); + xasprintf(&wpt->notes, "Alarm point: radius=%s", str); + break; + } + break; + case 8: + if (what == 0) WAYPT_SET(wpt, course, atof(str)); + break; + case 9: + case 10: + break; + case 11: + if (what == 1) wpt->microseconds = atoi(str); /* memory point type */ + break; + } + } + + if ((year > -1) && (hour > -1)) { + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + tm.tm_year = year - 1900; + tm.tm_mon = month - 1; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = min; + tm.tm_sec = sec; + + wpt->creation_time = mklocaltime(&tm); + } + + if (datum != DATUM_WGS84) { + double ht; + GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0, + &wpt->latitude, &wpt->longitude, &ht, datum); + } + + switch(what) { + case 0: + case 1: + ENQUEUE_TAIL(&trackpts, &wpt->Q); + break; + case 2: + case 3: + if (route == NULL) { + route = route_head_alloc(); + route_add_head(route); + } + route_add_wpt(route, wpt); + break; + } +} + +/* ----------------------------------------------------------- */ + +static void +rd_init(const char *fname) +{ + fin = gbfopen(fname, "r", MYNAME); + + lineno = 0; + route = NULL; + datum = DATUM_WGS84; + filetype = 28; + rte_name = rte_desc = NULL; + + QUEUE_INIT(&trackpts); +} + +static void +rd_deinit(void) +{ + gbfclose(fin); + if (rte_name) xfree(rte_name); + if (rte_desc) xfree(rte_desc); +} + +static void +data_read(void) +{ + char *buf; + sdf_section_e section = sdf_unknown; + + while ((buf = gbfgetstr(fin))) + { + char *cin = lrtrim(buf); + lineno++; + + if (*cin == '\0') continue; + + if (*cin == '[') + { + char *cend = strchr(++cin, ']'); + + if (cend != NULL) + { + *cend = '\0'; + cin = lrtrim(cin); + } + if ((*cin == '\0') || (cend == NULL)) + fatal(MYNAME ": Invalid section header!\n"); + + if (case_ignore_strcmp(cin, "HEADER") == 0) section = sdf_header; + else if (case_ignore_strcmp(cin, "POINTS") == 0) section = sdf_points; + else if (case_ignore_strncmp(cin, "CUSTOM", 6) == 0) section = sdf_custom; + else { + warning(MYNAME ": Unknown section \"%s\". Please report.\n", cin); + section = sdf_unknown; + } + } + else switch(section) + { + case sdf_header: + parse_header(cin); + break; + case sdf_points: + parse_point(cin); + break; + case sdf_custom: + case sdf_unknown: break; + } + } + finalize_tracks(); /* memory points can be at the end of all trackpoints */ +} + + +static void +calculate(const waypoint *wpt, double *dist, double *speed, double *course, + double *asc, double *desc) +{ + if (trkpt_out != NULL) { + + time_t time; + + *course = heading_true_degrees( + RAD(trkpt_out->latitude), RAD(trkpt_out->longitude), + RAD(wpt->latitude), RAD(wpt->longitude)); + + *dist = radtometers(gcdist( + RAD(trkpt_out->latitude), RAD(trkpt_out->longitude), + RAD(wpt->latitude), RAD(wpt->longitude))); + if (*dist < 0.1) *dist = 0; /* calc. diffs on 32- and 64-bit hosts */ + + time = wpt->creation_time - trkpt_out->creation_time; + if (time == 0) + *speed = 0; + else + *speed = *dist / (double)time; + + if (asc && desc && (trkpt_out->altitude != unknown_alt) && (wpt->altitude != unknown_alt)) { + double dh = wpt->altitude - trkpt_out->altitude; + if (dh > 0) + *asc += dh; + else + *desc -= dh; + } + } + else { + *speed = 0; + *dist = 0; + *course = 0; + if (asc) *asc = 0; + if (desc) *desc = 0; + } + if WAYPT_HAS(wpt, speed) *speed = wpt->speed / 3.6; /* -> meters per second */ + if WAYPT_HAS(wpt, course) *course = wpt->course; + +} + +/* pre-calculation callbacks */ + +static void +any_hdr_calc_cb(const route_head *trk) +{ + + trkpt_out = NULL; + this_distance = 0; + this_time = 0; + this_points = 0; + + this_index++; + this_valid = ((opt_route_index_value < 1) || (opt_route_index_value == this_index)); + if (! this_valid) return; + + if (!rte_name && trk->rte_name) { + rte_name = trk->rte_name; + rte_desc = trk->rte_desc; + } + + trk_out = (route_head *)trk; +} + +static void +any_waypt_calc_cb(const waypoint *wpt) +{ + double speed, course, dist; + + /* we can only write ONE route */ + if (! this_valid) return; + + if ((all_points == 0) && (this_points == 0)) start_time = wpt->creation_time; + + this_points++; + + if ((wpt->altitude != unknown_alt) && (wpt->altitude < minalt)) minalt = wpt->altitude; + if ((wpt->altitude != unknown_alt) && (wpt->altitude > maxalt)) maxalt = wpt->altitude; + calculate(wpt, &dist, &speed, &course, &all_asc, &all_desc); + if (speed > maxspeed) maxspeed = speed; + + this_distance = this_distance + dist; + if (trkpt_out != NULL) + this_time += (wpt->creation_time - trkpt_out->creation_time); + + trkpt_out = (waypoint *)wpt; +} + +static void +any_tlr_calc_cb(const route_head *trk) +{ + if (! this_valid) return; + + all_dist += this_distance; + all_time += this_time; + all_points += this_points; +} + +/* write callbacks */ + +static void +track_disp_hdr_cb(const route_head *trk) +{ + track_index++; + track_points = 0; + trk_out = (route_head *)trk; + trkpt_out = NULL; +} + + +static void +track_disp_wpt_cb(const waypoint *wpt) +{ + struct tm tm; + char tbuf[32]; + double course, speed, dist; + int flag = 0; + + track_points++; + all_track_points++; + + tm = *localtime(&wpt->creation_time); + strftime(tbuf, sizeof(tbuf), "%d.%m.%Y,%H:%M.%S", &tm); + + calculate(wpt, &dist, &speed, &course, NULL, NULL); + trkpt_dist = trkpt_dist + dist; + + if (track_points == trk_out->rte_waypt_ct) { /* I'm the last in that list */ + if (all_track_points != saved_track_points) { /* but not the overall latest */ + flag = 1; + } + } + else if (track_points == 1) { /* I'm the first in that list */ + if (all_track_points > 1) { /* but not the first ever seen */ + flag = 2; + } + } + + if (flag == 1) { + char *name = wpt->shortname; + if (name == NULL) name = "Log paused"; + gbfprintf(fout, "\"MP\",\"%s\"", name); + } + else if (flag == 2) { + char *name = wpt->shortname; + if (name == NULL) name = "Log continued"; + gbfprintf(fout, "\"MP\",\"%s\"", name); + } + else + gbfprintf(fout, "\"TP\""); + + gbfprintf(fout, ",%s,%.6lf,%.6lf,%.f,%.2f", + tbuf, + wpt->latitude, wpt->longitude, ALT(wpt), speed); + if (flag) + gbfprintf(fout, ",0,0,%d", flag); /* press, temperature, memory point type */ + else + gbfprintf(fout, ",%.1f", course); + + if (trkpt_dist != 0) + gbfprintf(fout, ",%.6f\n", trkpt_dist); + else + gbfprintf(fout, ",0\n"); + + trkpt_out = (waypoint *)wpt; +} + +static void +track_disp_tlr_cb(const route_head *rte) +{ + trkpt_out = NULL; +} + +static void +route_disp_hdr_cb(const route_head *rte) +{ + route_index++; + this_route_valid = ((opt_route_index_value < 1) || (opt_route_index_value == track_index)); +} + +static void +route_disp_wpt_cb(const waypoint *wpt) +{ + if (this_route_valid) { + char *sn; + + if (global_opts.synthesize_shortnames) + sn = mkshort_from_wpt(short_h, wpt); + else + sn = mkshort(short_h, wpt->shortname); + gbfprintf(fout, "\"WP\",\"%s\",%.8lf,%.8lf,%.f\n", + sn, wpt->latitude, wpt->longitude, ALT(wpt)); + xfree(sn); + } +} + +static void +track_disp_custom_cb(const waypoint *wpt) +{ + if (wpt->creation_time && (wpt->altitude != unknown_alt)) { + gbfprintf(fout, "%d,%.f\n", (int)(wpt->creation_time - start_time), wpt->altitude); + } +} + +static void +wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); + short_h = mkshort_new_handle(); +} + +static void +wr_deinit(void) +{ + mkshort_del_handle(&short_h); + gbfclose(fout); +} + +static void +data_write(void) +{ + gbfprintf(fout, "[HEADER]\n"); + gbfprintf(fout, "FILEVERSION=1\n"); + gbfprintf(fout, "SOURCE=FILE\n"); + gbfprintf(fout, "DATUM=WGS84\n"); + + rte_name = NULL; + rte_desc = NULL; + trkpt_out = NULL; + opt_route_index_value = -1; /* take all tracks from data pool */ + track_index = 0; + minalt = -unknown_alt; + maxalt = unknown_alt; + maxspeed = 0; + all_dist = 0; + all_time = 0; + all_asc = 0; + all_desc = 0; + all_points = 0; + start_time = 0; + + setshort_length(short_h, 100); + setshort_badchars(short_h, "\r\n"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 0); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 1); + + switch(global_opts.objective) + { + case wptdata: + break; + + case rtedata: + gbfprintf(fout, "TYPE=5\n"); + + opt_route_index_value = atoi(opt_route_index); + route_disp_all(any_hdr_calc_cb, any_tlr_calc_cb, any_waypt_calc_cb); + gbfprintf(fout, "DISTANCE=%.f\n", all_dist); + if (rte_name) gbfprintf(fout, "NAME=%s\n", rte_name); + gbfprintf(fout, "[POINTS]\n"); + if (route_points > 0) { + track_index = 0; + route_disp_all(route_disp_hdr_cb, NULL, route_disp_wpt_cb); + } + break; + + case trkdata: + gbfprintf(fout, "TYPE=28\n"); + + track_disp_all(any_hdr_calc_cb, any_tlr_calc_cb, any_waypt_calc_cb); + if (all_track_points > 0) { + if (rte_name) gbfprintf(fout, "NAME=%s\n", rte_name); + if (minalt != -unknown_alt) gbfprintf(fout, "MINALT=%.f\n", minalt); + if (maxalt != unknown_alt) gbfprintf(fout, "MAXALT=%.f\n", maxalt); + gbfprintf(fout, "MAXSPEED=%.2f\n", maxspeed); + gbfprintf(fout, "DISTANCE=%.f\n", all_dist); + gbfprintf(fout, "DURATION=%lu\n", all_time); +// gbfprintf(fout, "TOTASC=%.f\n", all_asc); +// gbfprintf(fout, "TOTDSC=%.f\n", all_desc); + if (start_time) { + struct tm tm; + char tbuf[32]; + + tm = *localtime(&start_time); + strftime(tbuf, sizeof(tbuf), "%d.%m.%Y %H:%M.%S", &tm); + gbfprintf(fout, "DATE=%s\n", tbuf); + } + if (all_time) gbfprintf(fout, "AVGSPEED=%.2f\n", all_dist / (double)all_time); + } + gbfprintf(fout, "[POINTS]\n"); + if (all_track_points > 0) { + + trkpt_dist = 0; + saved_track_points = all_track_points; + all_track_points = 0; + track_disp_all(track_disp_hdr_cb, track_disp_tlr_cb, track_disp_wpt_cb); + + if (start_time) { + gbfprintf(fout, "[CUSTOM1]\n"); + track_index = 0; + track_disp_all(NULL, NULL, track_disp_custom_cb); + } + } + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } +} + +/* ------------------------------------------------------------------ */ + +ff_vecs_t stmsdf_vecs = { + ff_type_file, + { ff_cap_none, + ff_cap_read | ff_cap_write, + ff_cap_read | ff_cap_write }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + stmsdf_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ +}; + +/* ================================================================== */ + +#endif /* CSVFMTS_ENABLED */ + diff --git a/stmwpp.c b/stmwpp.c new file mode 100644 index 000000000..95155c4ef --- /dev/null +++ b/stmwpp.c @@ -0,0 +1,328 @@ + /* + + Support for "Suunto Trek Manager" (STM) WaypointPlus files, + see homepage "http://www.suunto.fi" for more details, + + Copyright (C) 2005,2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include "defs.h" + +#if CSVFMTS_ENABLED + +#include "csv_util.h" +#include +#include +#include + +static gbfile *fin, *fout; +static route_head *track, *route; +static waypoint *wpt; +static short_handle short_h; + +#define MYNAME "STMwpp" + +#define STM_NOTHING 0 +#define STM_WAYPT 1 +#define STM_TRKPT 2 +#define STM_RTEPT 3 + +static int track_index; +static int track_num; +static int what; + +static char *index_opt = NULL; + +static +arglist_t stmwpp_args[] = +{ + {"index", &index_opt, "Index of route/track to write (if more the one in source)", + NULL, ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + + +static void +stmwpp_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); + track = NULL; + route = NULL; + wpt = NULL; +} + +static void +stmwpp_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +stmwpp_data_read(void) +{ + char *buff; + + what = STM_NOTHING; + buff = gbfgetstr(fin); + buff = (buff == NULL) ? "" : buff; + + if (case_ignore_strncmp(buff, "Datum,WGS 84,WGS 84,", 20) != 0) + fatal(MYNAME ": Invalid GPS datum or not \"WaypointPlus\"\" file!\n"); + + while ((buff = gbfgetstr(fin))) + { + char *c; + int column = -1; + struct tm time; + + buff = lrtrim(buff); + if (*buff == '\0') continue; + + wpt = NULL; + memset(&time, 0, sizeof(time)); + + while ((c = csv_lineparse(buff, ",", "", column++))) + { + int new_what; + int fracsec; + + buff = NULL; + + switch(column) + { + case 0: + if (case_ignore_strcmp(c, "WP") == 0) + { + new_what = STM_WAYPT; + } + else if (case_ignore_strcmp(c, "TP") == 0) + { + new_what = STM_TRKPT; + } + else + fatal(MYNAME ": Unknown feature \"%s\"!\n", c); + + if ((what != STM_NOTHING) && (new_what != what)) + fatal(MYNAME ": Only one feature (route or track) is supported by STM!\n"); + + what = new_what; + wpt = waypt_new(); + break; + + case 1: + if (what == STM_TRKPT) column++; /* no name -> skip column two */ + break; + + case 2: + wpt->shortname = xstrdup(c); + break; + + case 3: + wpt->latitude = atof(c); + break; + + case 4: + wpt->longitude = atof(c); + break; + + case 5: + sscanf(c, "%d/%d/%d", &time.tm_mon, &time.tm_mday, &time.tm_year); + break; + + case 6: + sscanf(c, "%d:%d:%d.%d", &time.tm_hour, &time.tm_min, &time.tm_sec, &fracsec); + wpt->microseconds = MILLI_TO_MICRO(fracsec); + /* makes sense only for recorded trackpoints */ + if (what != STM_TRKPT) wpt->microseconds = 0; + break; + + default: + break; + } + } + if (wpt != NULL) + { + time.tm_year -= 1900; + time.tm_mon--; + wpt->creation_time = mkgmtime(&time); + + switch(what) + { + case STM_WAYPT: + waypt_add(wpt); + if (global_opts.objective == rtedata) { + if (route == NULL) { + route = route_head_alloc(); + route_add_head(route); + } + route_add_wpt(route, waypt_dupe(wpt)); + } + break; + + case STM_TRKPT: + if (track == NULL) + { + track = route_head_alloc(); + track_add_head(track); + } + track_add_wpt(track, wpt); + break; + } + wpt = NULL; + } + } +} + +static void +stmwpp_rw_init(const char *fname) +{ + fout = gbfopen(fname, "wb", MYNAME); + short_h = mkshort_new_handle(); +} + +static void +stmwpp_rw_deinit(void) +{ + mkshort_del_handle(&short_h); + gbfclose(fout); +} + +static void +stmwpp_track_hdr(const route_head *track) +{ + track_num++; +} + +static void +stmwpp_write_double(const double val) +{ + char buff[64]; + char *c; + + c = buff + snprintf(buff, sizeof(buff), "%3.7f", val); + while (*--c == '0') *c = '\0'; + if (*c == '.') *++c = '0'; + gbfprintf(fout, "%s,", buff); +} + +static void +stmwpp_waypt_cb(const waypoint *wpt) +{ + char cdate[16], ctime[16]; + struct tm tm; + + if (track_index != track_num) return; + + tm = *gmtime(&wpt->creation_time); + tm.tm_year += 1900; + tm.tm_mon++; + + snprintf(cdate, sizeof(cdate), "%02d/%02d/%04d", tm.tm_mon, tm.tm_mday, tm.tm_year); + snprintf(ctime, sizeof(ctime), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); + + switch(what) + { + char *sn; + + case STM_WAYPT: + case STM_RTEPT: + if (global_opts.synthesize_shortnames) + sn = mkshort_from_wpt(short_h, wpt); + else + sn = mkshort(short_h, wpt->shortname); + gbfprintf(fout, "WP,D,%s,", sn); + xfree(sn); + break; + + case STM_TRKPT: + gbfprintf(fout, "TP,D,"); + break; + } + stmwpp_write_double(wpt->latitude); + stmwpp_write_double(wpt->longitude); + gbfprintf(fout, "%s,%s", cdate, ctime); + switch(what) + { + case STM_WAYPT: + case STM_RTEPT: + gbfprintf(fout, ".%02d", 0); + break; + case STM_TRKPT: + gbfprintf(fout, ".%03d", MICRO_TO_MILLI(wpt->microseconds)); + break; + } + gbfprintf(fout, ",\r\n"); +} + +static void +stmwpp_data_write(void) +{ + setshort_length(short_h, 100); + setshort_badchars(short_h, ",\r\n"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 0); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 1); + + track_num = 0; + if (index_opt != NULL) + track_index = atoi(index_opt); + else + track_index = 1; + + gbfprintf(fout, "Datum,WGS 84,WGS 84,0,0,0,0,0\r\n"); + + switch(global_opts.objective) + { + case wptdata: + what = STM_WAYPT; + track_index = track_num; /* disable filter */ + setshort_defname(short_h, "WPT"); + waypt_disp_all(stmwpp_waypt_cb); + break; + case rtedata: + what = STM_RTEPT; + setshort_defname(short_h, "RPT"); + route_disp_all(stmwpp_track_hdr, NULL, stmwpp_waypt_cb); + break; + case trkdata: + what = STM_TRKPT; + track_disp_all(stmwpp_track_hdr, NULL, stmwpp_waypt_cb); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } +} + +ff_vecs_t stmwpp_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + stmwpp_rd_init, + stmwpp_rw_init, + stmwpp_rd_deinit, + stmwpp_rw_deinit, + stmwpp_data_read, + stmwpp_data_write, + NULL, + stmwpp_args, + CET_CHARSET_MS_ANSI, 0 +}; + +#endif /* CSVFMTS_ENABLED */ + diff --git a/strptime.c b/strptime.c new file mode 100644 index 000000000..7d56a1539 --- /dev/null +++ b/strptime.c @@ -0,0 +1,1022 @@ +/* Convert a string representation of time to a time value. + Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* XXX This version of the implementation is not really complete. + Some of the fields cannot add information alone. But if seeing + some of them in the same format (such as year, week and weekday) + this is enough information for determining the date. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#ifdef _LIBC +# include "../locale/localeinfo.h" +#endif + +#include "strptime.h" + +#ifndef __P +# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +# define __P(args) args +# else +# define __P(args) () +# endif /* GCC. */ +#endif /* Not __P. */ + +#if ! HAVE_LOCALTIME_R && ! defined localtime_r +# ifdef _LIBC +# define localtime_r __localtime_r +# else +/* Approximate localtime_r as best we can in its absence. */ +# define localtime_r my_localtime_r +static struct tm *localtime_r __P ((const time_t *, struct tm *)); +static struct tm * +localtime_r (t, tp) + const time_t *t; + struct tm *tp; +{ + struct tm *l = localtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} +# endif /* ! _LIBC */ +#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */ + + +#define match_char(ch1, ch2) if (ch1 != ch2) return NULL +#if defined __GNUC__ && __GNUC__ >= 2 +# define match_string(cs1, s2) \ + ({ size_t len = strlen (cs1); \ + int result = strncasecmp ((cs1), (s2), len) == 0; \ + if (result) (s2) += len; \ + result; }) +#else +/* Oh come on. Get a reasonable compiler. */ +# define match_string(cs1, s2) \ + (case_ignore_strncmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) +/* now now, don't need to be rude .... */ +static +int +case_ignore_strncmp(const char *s1, const char *s2, int n) +{ + int rv = 0; + + while (n && ((rv = toupper(*s1) - toupper(*s2)) == 0) + && *s1) { + s1++; + s2++; + n--; + } + return rv; +} +#endif +/* We intentionally do not use isdigit() for testing because this will + lead to problems with the wide character version. */ +#define get_number(from, to, n) \ + do { \ + int __n = n; \ + val = 0; \ + while (*rp == ' ') \ + ++rp; \ + if (*rp < '0' || *rp > '9') \ + return NULL; \ + do { \ + val *= 10; \ + val += *rp++ - '0'; \ + } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ + if (val < from || val > to) \ + return NULL; \ + } while (0) +#ifdef _NL_CURRENT +# define get_alt_number(from, to, n) \ + ({ \ + __label__ do_normal; \ + if (*decided != raw) \ + { \ + const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \ + int __n = n; \ + int any = 0; \ + while (*rp == ' ') \ + ++rp; \ + val = 0; \ + do { \ + val *= 10; \ + while (*alts != '\0') \ + { \ + size_t len = strlen (alts); \ + if (strncasecmp (alts, rp, len) == 0) \ + break; \ + alts += len + 1; \ + ++val; \ + } \ + if (*alts == '\0') \ + { \ + if (*decided == not && ! any) \ + goto do_normal; \ + /* If we haven't read anything it's an error. */ \ + if (! any) \ + return NULL; \ + /* Correct the premature multiplication. */ \ + val /= 10; \ + break; \ + } \ + else \ + *decided = loc; \ + } while (--__n > 0 && val * 10 <= to); \ + if (val < from || val > to) \ + return NULL; \ + } \ + else \ + { \ + do_normal: \ + get_number (from, to, n); \ + } \ + 0; \ + }) +#else +# define get_alt_number(from, to, n) \ + /* We don't have the alternate representation. */ \ + get_number(from, to, n) +#endif +#define recursive(new_fmt) \ + (*(new_fmt) != '\0' \ + && (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL) + + +#ifdef _LIBC +/* This is defined in locale/C-time.c in the GNU libc. */ +extern const struct locale_data _nl_C_LC_TIME; +extern const unsigned short int __mon_yday[2][13]; + +# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string) +# define ab_weekday_name \ + (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) +# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string) +# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) +# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string) +# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string) +# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string) +# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string) +# define HERE_T_FMT_AMPM \ + (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string) +# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string) + +# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n) +#else +static char const weekday_name[][10] = + { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; +static char const ab_weekday_name[][4] = + { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; +static char const month_name[][10] = + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }; +static char const ab_month_name[][4] = + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; +# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" +# define HERE_D_FMT "%m/%d/%y" +# define HERE_AM_STR "AM" +# define HERE_PM_STR "PM" +# define HERE_T_FMT_AMPM "%I:%M:%S %p" +# define HERE_T_FMT "%H:%M:%S" + +const unsigned short int __mon_yday[2][13] = + { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } + }; +#endif + +/* Status of lookup: do we use the locale data or the raw data? */ +enum locale_status { not, loc, raw }; + + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +# define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + +/* Compute the day of the week. */ +static void +day_of_the_week (struct tm *tm) +{ + /* We know that January 1st 1970 was a Thursday (= 4). Compute the + the difference between this data in the one on TM and so determine + the weekday. */ + int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); + int wday = (-473 + + (365 * (tm->tm_year - 70)) + + (corr_year / 4) + - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) + + (((corr_year / 4) / 25) / 4) + + __mon_yday[0][tm->tm_mon] + + tm->tm_mday - 1); + tm->tm_wday = ((wday % 7) + 7) % 7; +} + +/* Compute the day of the year. */ +static void +day_of_the_year (struct tm *tm) +{ + tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] + + (tm->tm_mday - 1)); +} + +static char * +#ifdef _LIBC +internal_function +#endif +strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm, + enum locale_status *decided, int era_cnt)); + +static char * +#ifdef _LIBC +internal_function +#endif +strptime_internal (rp, fmt, tm, decided, era_cnt) + const char *rp; + const char *fmt; + struct tm *tm; + enum locale_status *decided; + int era_cnt; +{ + const char *rp_backup; + int cnt; + size_t val; + int have_I, is_pm; + int century, want_century; + int want_era; + int have_wday, want_xday; + int have_yday; + int have_mon, have_mday; +#ifdef _NL_CURRENT + size_t num_eras; +#endif + struct era_entry *era; + + have_I = is_pm = 0; + century = -1; + want_century = 0; + want_era = 0; + era = NULL; + + have_wday = want_xday = have_yday = have_mon = have_mday = 0; + + while (*fmt != '\0') + { + /* A white space in the format string matches 0 more or white + space in the input string. */ + if (isspace (*fmt)) + { + while (isspace (*rp)) + ++rp; + ++fmt; + continue; + } + + /* Any character but `%' must be matched by the same character + in the iput string. */ + if (*fmt != '%') + { + match_char (*fmt++, *rp++); + continue; + } + + ++fmt; +#ifndef _NL_CURRENT + /* We need this for handling the `E' modifier. */ + start_over: +#endif + + /* Make back up of current processing pointer. */ + rp_backup = rp; + + switch (*fmt++) + { + case '%': + /* Match the `%' character itself. */ + match_char ('%', *rp++); + break; + case 'a': + case 'A': + /* Match day of week. */ + for (cnt = 0; cnt < 7; ++cnt) + { +#ifdef _NL_CURRENT + if (*decided !=raw) + { + if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), + weekday_name[cnt])) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), + ab_weekday_name[cnt])) + *decided = loc; + break; + } + } +#endif + if (*decided != loc + && (match_string (weekday_name[cnt], rp) + || match_string (ab_weekday_name[cnt], rp))) + { + *decided = raw; + break; + } + } + if (cnt == 7) + /* Does not match a weekday name. */ + return NULL; + tm->tm_wday = cnt; + have_wday = 1; + break; + case 'b': + case 'B': + case 'h': + /* Match month name. */ + for (cnt = 0; cnt < 12; ++cnt) + { +#ifdef _NL_CURRENT + if (*decided !=raw) + { + if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), + month_name[cnt])) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), + ab_month_name[cnt])) + *decided = loc; + break; + } + } +#endif + if (match_string (month_name[cnt], rp) + || match_string (ab_month_name[cnt], rp)) + { + *decided = raw; + break; + } + } + if (cnt == 12) + /* Does not match a month name. */ + return NULL; + tm->tm_mon = cnt; + want_xday = 1; + break; + case 'c': + /* Match locale's date and time format. */ +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not && + strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } +#endif + if (!recursive (HERE_D_T_FMT)) + return NULL; + want_xday = 1; + break; + case 'C': + /* Match century number. */ +#ifdef _NL_CURRENT + match_century: +#endif + get_number (0, 99, 2); + century = val; + want_xday = 1; + break; + case 'd': + case 'e': + /* Match day of month. */ + get_number (1, 31, 2); + tm->tm_mday = val; + have_mday = 1; + want_xday = 1; + break; + case 'F': + if (!recursive ("%Y-%m-%d")) + return NULL; + want_xday = 1; + break; + case 'x': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } +#endif + /* Fall through. */ + case 'D': + /* Match standard day format. */ + if (!recursive (HERE_D_FMT)) + return NULL; + want_xday = 1; + break; + case 'k': + case 'H': + /* Match hour in 24-hour clock. */ + get_number (0, 23, 2); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock. */ + get_number (1, 12, 2); + tm->tm_hour = val % 12; + have_I = 1; + break; + case 'j': + /* Match day number of year. */ + get_number (1, 366, 3); + tm->tm_yday = val - 1; + have_yday = 1; + break; + case 'm': + /* Match number of month. */ + get_number (1, 12, 2); + tm->tm_mon = val - 1; + have_mon = 1; + want_xday = 1; + break; + case 'M': + /* Match minute. */ + get_number (0, 59, 2); + tm->tm_min = val; + break; + case 'n': + case 't': + /* Match any white space. */ + while (isspace (*rp)) + ++rp; + break; + case 'p': + /* Match locale's equivalent of AM/PM. */ +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) + { + if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) + { + if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) + *decided = loc; + is_pm = 1; + break; + } + *decided = raw; + } +#endif + if (!match_string (HERE_AM_STR, rp)) { + if (match_string (HERE_PM_STR, rp)) { + is_pm = 1; + } else { + return NULL; + } + } + break; + case 'r': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not && + strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), + HERE_T_FMT_AMPM)) + *decided = loc; + break; + } + *decided = raw; + } +#endif + if (!recursive (HERE_T_FMT_AMPM)) + return NULL; + break; + case 'R': + if (!recursive ("%H:%M")) + return NULL; + break; + case 's': + { + /* The number of seconds may be very high so we cannot use + the `get_number' macro. Instead read the number + character for character and construct the result while + doing this. */ + time_t secs = 0; + if (*rp < '0' || *rp > '9') + /* We need at least one digit. */ + return NULL; + + do + { + secs *= 10; + secs += *rp++ - '0'; + } + while (*rp >= '0' && *rp <= '9'); + + if (localtime_r (&secs, tm) == NULL) + /* Error in function. */ + return NULL; + } + break; + case 'S': + get_number (0, 61, 2); + tm->tm_sec = val; + break; + case 'X': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) + *decided = loc; + break; + } + *decided = raw; + } +#endif + /* Fall through. */ + case 'T': + if (!recursive (HERE_T_FMT)) + return NULL; + break; + case 'u': + get_number (1, 7, 1); + tm->tm_wday = val % 7; + have_wday = 1; + break; + case 'g': + get_number (0, 99, 2); + /* XXX This cannot determine any field in TM. */ + break; + case 'G': + if (*rp < '0' || *rp > '9') + return NULL; + /* XXX Ignore the number since we would need some more + information to compute a real date. */ + do + ++rp; + while (*rp >= '0' && *rp <= '9'); + break; + case 'U': + case 'V': + case 'W': + get_number (0, 53, 2); + /* XXX This cannot determine any field in TM without some + information. */ + break; + case 'w': + /* Match number of weekday. */ + get_number (0, 6, 1); + tm->tm_wday = val; + have_wday = 1; + break; + case 'y': +#ifdef _NL_CURRENT + match_year_in_century: +#endif + /* Match year within century. */ + get_number (0, 99, 2); + /* The "Year 2000: The Millennium Rollover" paper suggests that + values in the range 69-99 refer to the twentieth century. */ + tm->tm_year = val >= 69 ? val : val + 100; + /* Indicate that we want to use the century, if specified. */ + want_century = 1; + want_xday = 1; + break; + case 'Y': + /* Match year including century number. */ + get_number (0, 9999, 4); + tm->tm_year = val - 1900; + want_century = 0; + want_xday = 1; + break; + case 'Z': + /* XXX How to handle this? */ + break; + case 'E': +#ifdef _NL_CURRENT + switch (*fmt++) + { + case 'c': + /* Match locale's alternate date and time format. */ + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, D_T_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_D_T_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } + /* The C locale has no era information, so use the + normal representation. */ + if (!recursive (HERE_D_T_FMT)) + return NULL; + want_xday = 1; + break; + case 'C': + if (*decided != raw) + { + if (era_cnt >= 0) + { + era = _nl_select_era_entry (era_cnt); + if (match_string (era->era_name, rp)) + { + *decided = loc; + break; + } + else + return NULL; + } + else + { + num_eras = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; + ++era_cnt, rp = rp_backup) + { + era = _nl_select_era_entry (era_cnt); + if (match_string (era->era_name, rp)) + { + *decided = loc; + break; + } + } + if (era_cnt == (int) num_eras) + { + era_cnt = -1; + if (*decided == loc) + return NULL; + } + else + break; + } + + *decided = raw; + } + /* The C locale has no era information, so use the + normal representation. */ + goto match_century; + case 'y': + if (*decided == raw) + goto match_year_in_century; + + get_number(0, 9999, 4); + tm->tm_year = val; + want_era = 1; + want_xday = 1; + break; + case 'Y': + if (*decided != raw) + { + num_eras = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; + ++era_cnt, rp = rp_backup) + { + era = _nl_select_era_entry (era_cnt); + if (recursive (era->era_format)) + break; + } + if (era_cnt == (int) num_eras) + { + era_cnt = -1; + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + *decided = loc; + era_cnt = -1; + break; + } + + *decided = raw; + } + get_number (0, 9999, 4); + tm->tm_year = val - 1900; + want_century = 0; + want_xday = 1; + break; + case 'x': + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, D_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_D_FMT)) + *decided = loc; + break; + } + *decided = raw; + } + if (!recursive (HERE_D_FMT)) + return NULL; + break; + case 'X': + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, T_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_T_FMT)) + *decided = loc; + break; + } + *decided = raw; + } + if (!recursive (HERE_T_FMT)) + return NULL; + break; + default: + return NULL; + } + break; +#else + /* We have no information about the era format. Just use + the normal format. */ + if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' + && *fmt != 'x' && *fmt != 'X') + /* This is an illegal format. */ + return NULL; + + goto start_over; +#endif + case 'O': + switch (*fmt++) + { + case 'd': + case 'e': + /* Match day of month using alternate numeric symbols. */ + get_alt_number (1, 31, 2); + tm->tm_mday = val; + have_mday = 1; + want_xday = 1; + break; + case 'H': + /* Match hour in 24-hour clock using alternate numeric + symbols. */ + get_alt_number (0, 23, 2); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock using alternate numeric + symbols. */ + get_alt_number (1, 12, 2); + tm->tm_hour = val - 1; + have_I = 1; + break; + case 'm': + /* Match month using alternate numeric symbols. */ + get_alt_number (1, 12, 2); + tm->tm_mon = val - 1; + have_mon = 1; + want_xday = 1; + break; + case 'M': + /* Match minutes using alternate numeric symbols. */ + get_alt_number (0, 59, 2); + tm->tm_min = val; + break; + case 'S': + /* Match seconds using alternate numeric symbols. */ + get_alt_number (0, 61, 2); + tm->tm_sec = val; + break; + case 'U': + case 'V': + case 'W': + get_alt_number (0, 53, 2); + /* XXX This cannot determine any field in TM without + further information. */ + break; + case 'w': + /* Match number of weekday using alternate numeric symbols. */ + get_alt_number (0, 6, 1); + tm->tm_wday = val; + have_wday = 1; + break; + case 'y': + /* Match year within century using alternate numeric symbols. */ + get_alt_number (0, 99, 2); + tm->tm_year = val >= 69 ? val : val + 100; + want_xday = 1; + break; + default: + return NULL; + } + break; + default: + return NULL; + } + } + + if (have_I && is_pm) + tm->tm_hour += 12; + + if (century != -1) + { + if (want_century) + tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; + else + /* Only the century, but not the year. Strange, but so be it. */ + tm->tm_year = (century - 19) * 100; + } + +#ifdef _NL_CURRENT + if (era_cnt != -1) + { + era = _nl_select_era_entry(era_cnt); + if (want_era) + tm->tm_year = (era->start_date[0] + + ((tm->tm_year - era->offset) + * era->absolute_direction)); + else + /* Era start year assumed. */ + tm->tm_year = era->start_date[0]; + } + else +#endif + if (want_era) + return NULL; + + if (want_xday && !have_wday) + { + if ( !(have_mon && have_mday) && have_yday) + { + /* We don't have tm_mon and/or tm_mday, compute them. */ + int t_mon = 0; + while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) + t_mon++; + if (!have_mon) + tm->tm_mon = t_mon - 1; + if (!have_mday) + tm->tm_mday = + (tm->tm_yday + - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); + } + day_of_the_week (tm); + } + if (want_xday && !have_yday) + day_of_the_year (tm); + + return (char *) rp; +} + + +char * +strptime (buf, format, tm) + const char *buf; + const char *format; + struct tm *tm; +{ + enum locale_status decided; + +#ifdef _NL_CURRENT + decided = not; +#else + decided = raw; +#endif + return strptime_internal (buf, format, tm, &decided, -1); +} + diff --git a/strptime.h b/strptime.h new file mode 100644 index 000000000..fe8d53edb --- /dev/null +++ b/strptime.h @@ -0,0 +1,33 @@ +/* strptime.h + * + * $Id: strptime.h,v 1.1 2005/07/16 17:02:10 robertl Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __STRPTIME_H__ +#define __STRPTIME_H__ + +/* + * Version of "strptime()", for the benefit of OSes that don't have it. + */ +extern char *strptime(const char *, const char *, struct tm *); + +#endif + diff --git a/style/arc.style b/style/arc.style new file mode 100644 index 000000000..85a102d29 --- /dev/null +++ b/style/arc.style @@ -0,0 +1,24 @@ +# gpsbabel XCSV style file +# +# Format: GPSBabel arc filter format +# Author: Ron Parker +# Date: 17 July 2003 +# + +DESCRIPTION GPSBabel arc filter file +EXTENSION txt + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER TAB +RECORD_DELIMITER NEWLINE + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LAT_HUMAN_READABLE, "", "%08.5f" +IFIELD LON_HUMAN_READABLE, "", "%08.5f" + +OFIELD LAT_DECIMAL, "", "%08.5f" +OFIELD LON_DECIMAL, "", "%08.5f" diff --git a/style/cambridge.style b/style/cambridge.style new file mode 100644 index 000000000..f0e2bce12 --- /dev/null +++ b/style/cambridge.style @@ -0,0 +1,18 @@ +DESCRIPTION Cambridge/Winpilot glider software +SHORTLEN 8 +EXTENSION dat +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA + +IFIELD INDEX,"1","%d" +IFIELD LAT_HUMAN_READABLE,"","%d:%06.3f%c" +IFIELD LON_HUMAN_READABLE,"","%03d:%06.3f%c" +IFIELD ALT_METERS,"","%3.0fM" +IFIELD CONSTANT,"","T" +IFIELD SHORTNAME,"","%s" +IFIELD DESCRIPTION,"","%s" diff --git a/style/csv.style b/style/csv.style new file mode 100644 index 000000000..3129a74fa --- /dev/null +++ b/style/csv.style @@ -0,0 +1,27 @@ +# gpsbabel XCSV style file +# +# Format: DeLorme SA 9.0 CSV +# Author: Alex Mottram +# Date: 12/09/2002 +# +# +DESCRIPTION Comma separated values +SHORTLEN 8 +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMASPACE +RECORD_DELIMITER NEWLINE +BADCHARS COMMA + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LAT_HUMAN_READABLE, "", "%08.5f" +IFIELD LON_HUMAN_READABLE, "", "%08.5f" +IFIELD DESCRIPTION, "", "%s" + +OFIELD LAT_DECIMAL, "", "%08.5f" +OFIELD LON_DECIMAL, "", "%08.5f" +OFIELD DESCRIPTION, "", "%s" diff --git a/style/cup.style b/style/cup.style new file mode 100644 index 000000000..0a5c225aa --- /dev/null +++ b/style/cup.style @@ -0,0 +1,46 @@ +# +# (c) 2006, Robert Lipe, based on sample files by Krzysztof Wojtas +# Reference info: http://www.seeyou.ws/thankyou.php?fname=cup_format.pdf +# + +DESCRIPTION See You flight analysis data +SHORTLEN 8 +EXTENSION cup +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS ," +PROLOGUE name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc +EPILOGUE -----Related Tasks----- + + +IFIELD SHORTNAME,"", ""%s"" +IFIELD SHORTNAME,"", "%s" +IFIELD CONSTANT,"", "" +IFIELD LAT_NMEA, "%f", "%08.3f", "absolute" +IFIELD LON_NMEA, "%f", "%09.3f", "absolute" +IFIELD ALT_METERS,"", "%dm" +IFIELD CONSTANT,"", "1" +IFIELD CONSTANT,"", "" +IFIELD CONSTANT,"", "" +IFIELD CONSTANT,"", "" +IFIELD DESCRIPTION,"", ""%s"" + +OFIELD SHORTNAME,"", ""%s"" +OFIELD SHORTNAME,"", "%s" +OFIELD CONSTANT,"", "" +OFIELD LAT_NMEA, "%f", "%08.3f", "absolute" +OFIELD LAT_DIR, "", "%c", "no_delim_before" +OFIELD LON_NMEA, "%f", "%09.3f", "absolute" +OFIELD LON_DIR, "", "%c", "no_delim_before" +OFIELD ALT_METERS,"", "%3.1fm" +OFIELD CONSTANT,"", "1" +OFIELD CONSTANT,"", "" +OFIELD CONSTANT,"", "" +OFIELD CONSTANT,"", "" +OFIELD DESCRIPTION,"", ""%s"" + + diff --git a/style/custom.style b/style/custom.style new file mode 100644 index 000000000..ffdb341a0 --- /dev/null +++ b/style/custom.style @@ -0,0 +1,52 @@ +# gpsbabel XCSV style file +# +# Format: Custom "Everything" Style +# Author: Alex Mottram +# Date: 11/24/2002 +# +# + +DESCRIPTION Custom "Everything" Style + +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA +FORMAT_TYPE INTERNAL + +# +# HEADER STUFF: +# +PROLOGUE Prologue Line 1 __FILE__ +PROLOGUE Prologue Line 2 + +# +# INDIVIDUAL DATA FIELDS: +# +IFIELD CONSTANT, "CONSTANT", "%s" +IFIELD INDEX, "", "%d" +IFIELD LAT_DECIMAL, "", "%f" +IFIELD LAT_DIR, "", "%c" +IFIELD LON_DECIMAL, "", "%f" +IFIELD LON_DIR, "", "%c" +IFIELD ICON_DESCR, "", "%s" +IFIELD SHORTNAME, "", "%s" +IFIELD DESCRIPTION, "", "%s" +IFIELD NOTES, "", "%s" +IFIELD URL, "", "%s" +IFIELD URL_LINK_TEXT, "", "%s" +IFIELD ALT_METERS, "", "%fM" +IFIELD ALT_FEET, "", "%fF" +IFIELD LAT_DECIMALDIR, "", "%f/%c" +IFIELD LON_DECIMALDIR, "", "%f/%c" +IFIELD LAT_DIRDECIMAL, "", "%c/%f" +IFIELD LON_DIRDECIMAL, "", "%c/%f" +IFIELD LAT_INT32DEG, "", "%ld" +IFIELD LON_INT32DEG, "", "%ld" +IFIELD TIMET_TIME, "", "%ld" +IFIELD EXCEL_TIME, "", "%f" + +# EPILOGUE: +EPILOGUE Epilogue Line 1 +EPILOGUE Epilogue Line 2 diff --git a/style/dna.style b/style/dna.style new file mode 100644 index 000000000..5cbacbec8 --- /dev/null +++ b/style/dna.style @@ -0,0 +1,28 @@ +# gpsbabel XCSV style file +# +# Format: DNA Marker Format +# Author: Alex Mottram +# Date: 12/09/2002 +# +# +# As defined in dna.c +# +# + +DESCRIPTION Navitrak DNA marker format +EXTENSION dna + +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD INDEX, "", "%d" +IFIELD LAT_DECIMAL, "", "%08.5f" +IFIELD LON_DECIMAL, "", "%08.5f" +IFIELD DESCRIPTION, "", "%s" + diff --git a/style/fugawi.style b/style/fugawi.style new file mode 100644 index 000000000..e47b38966 --- /dev/null +++ b/style/fugawi.style @@ -0,0 +1,41 @@ +# fugawi XCSV style file +# +# Format: Fugawi +# Author: Robert Lipe, Patrick Ohly +# Date: 07/24/2005 +# +# + +DESCRIPTION Fugawi +EXTENSION txt +SHORTLEN 10 + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA + +PROLOGUE \# Latitude, Longitude and UTM coordinates are in WGS84 datum +PROLOGUE \# +PROLOGUE \# Every set of data contains the following: +PROLOGUE \# +PROLOGUE \# Waypoint name +PROLOGUE \# Waypoint comment +PROLOGUE \# Waypoint description +PROLOGUE \# Latitude in Degree and decimals (soutern hemisphere has neg. degrees) +PROLOGUE \# Longitude in degree and decimals (neg. numbers: west of Greenwich) +PROLOGUE \# Height in meters [optional when importing, always present when exporting: Date (GMT) as ISO YYYYMMDD, Time of the day relative to the date as HHMMSS + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD SHORTNAME, "", "%s" +IFIELD DESCRIPTION, "", "%s" +IFIELD NOTES, "", "%s" +IFIELD LAT_DECIMAL, "", "%-.7f" +IFIELD LON_DECIMAL, "", "%-.7f" +IFIELD ALT_METERS, "", "%-7.1f" +IFIELD GMT_TIME, "", "%Y%m%d" +IFIELD HMSG_TIME, "", "%02d%02d%02d" diff --git a/style/garmin301.style b/style/garmin301.style new file mode 100644 index 000000000..57e199ad8 --- /dev/null +++ b/style/garmin301.style @@ -0,0 +1,34 @@ +# gpsbabel XCSV style file +# +# Format: Garmin 301 Position + Heartrate data +# Author: Jeff Kalikstein +# Date: 08/29/2005 +# + +DESCRIPTION Garmin 301 Custom position and heartrate + +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA +#FORMAT_TYPE INTERNAL + +# +# HEADER STUFF: +# +PROLOGUE Garmin 301 data __FILE__ +PROLOGUE Timestamp,Latitude, Longitude, Altitude(ft), heart rate +# +# INDIVIDUAL DATA FIELDS: +# +IFIELD TIMET_TIME,"","%ld" +IFIELD LAT_DECIMAL, "", "%f" +IFIELD LON_DECIMAL, "", "%f" +IFIELD ALT_FEET, "", "%fF" +IFIELD HEART_RATE,""," %d" # beats per minute + + +# EPILOGUE: +#EPILOGUE Epilogue Line 1 +#EPILOGUE Epilogue Line 2 diff --git a/style/garmin_poi.style b/style/garmin_poi.style new file mode 100644 index 000000000..e15b35bf3 --- /dev/null +++ b/style/garmin_poi.style @@ -0,0 +1,34 @@ +# gpsbabel XCSV style file +# +# Format: Garmin POI +# Author: Robert Lipe +# Date: 10/07/2005 +# Reference: http://forums.groundspeak.com/GC/index.php?showtopic=110641&st=0&#entry1752204 +# +DESCRIPTION Garmin POI database +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA +SHORTLEN 24 +# PROLOGUE Longitude,Latitude,Name, comment + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LON_HUMAN_READABLE, "", "%08.5f" +IFIELD LAT_HUMAN_READABLE, "", "%08.5f" +IFIELD SHORTNAME, "", "%s" +IFIELD DESCRIPTION, "", "%s" + +OFIELD LON_DECIMAL, "", "%08.5f" +OFIELD LAT_DECIMAL, "", "%08.5f" +OFIELD SHORTNAME, "", "%-.24s" +OFIELD GEOCACHE_TYPE, "", " %-.4s", "no_delim_before,optional" +OFIELD GEOCACHE_CONTAINER, "", "/%-.4s ", "no_delim_before,optional" +OFIELD GEOCACHE_DIFF, "", "(%3.1f", "no_delim_before,optional" +OFIELD GEOCACHE_TERR, "", "/%3.1f)", "no_delim_before,optional" +OFIELD DESCRIPTION, "", "%-.50s" diff --git a/style/geonet.style b/style/geonet.style new file mode 100644 index 000000000..7b7d3a15c --- /dev/null +++ b/style/geonet.style @@ -0,0 +1,49 @@ +# gpsbabel XCSV style file +# +# Format: GEOnet Names Server (GNS) (http://earth-info.nga.mil/gns/html/cntry_files.html) +# Author: Olaf Klein +# Date: 08/20/2002 +# + +DESCRIPTION GEOnet Names Server (GNS) +EXTENSION txt + +# +# FILE LAYOUT DEFINITIIONS: +# + +FIELD_DELIMITER TAB +RECORD_DELIMITER CRNEWLINE +BADCHARS TAB +ENCODING UTF-8 + +PROLOGUE RC UFI UNI LAT LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD IGNORE, "", "%s" # RC ( http://earth-info.nga.mil/gns/html/gis_contryfiles.html ) +IFIELD IGNORE, "", "%s" # UFI +IFIELD IGNORE, "", "%s" # UNI +IFIELD LAT_DECIMAL, "", "%03.7f" # LAT +IFIELD LON_DECIMAL, "", "%03.7f" # LONG +IFIELD IGNORE, "", "%s" # DMS_LAT +IFIELD IGNORE, "", "%s" # DMS_LONG +IFIELD IGNORE, "", "%s" # UTM +IFIELD IGNORE, "", "%s" # JOG +IFIELD IGNORE, "", "%s" # FC +IFIELD IGNORE, "", "%s" # DSG +IFIELD IGNORE, "", "%s" # PC +IFIELD IGNORE, "", "%s" # CC1 +IFIELD IGNORE, "", "%s" # ADM1 +IFIELD IGNORE, "", "%s" # ADM2 +IFIELD IGNORE, "", "%s" # DIM +IFIELD IGNORE, "", "%s" # CC2 +IFIELD IGNORE, "", "%s" # NT +IFIELD IGNORE, "", "%s" # LC +IFIELD IGNORE, "", "%s" # SHORT_FORM +IFIELD IGNORE, "", "%s" # GENERIC +IFIELD SHORTNAME, "", "%s" # SHORT_NAME +IFIELD DESCRIPTION, "", "%s" # FULL_NAME +IFIELD IGNORE, "", "%s" # FULL_NAME_ND +IFIELD IGNORE, "", "%s" # MOD_DATE diff --git a/style/gpsdrive.style b/style/gpsdrive.style new file mode 100644 index 000000000..dfe80ccaa --- /dev/null +++ b/style/gpsdrive.style @@ -0,0 +1,32 @@ +# gpsbabel XCSV style file +# +# Format: GPSDrive +# Author: Alex Mottram +# Date: 12/11/2002 +# +# +# + +DESCRIPTION GpsDrive Format + +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER WHITESPACE +RECORD_DELIMITER NEWLINE +BADCHARS ,'" + +SHORTLEN 20 +SHORTWHITE 0 + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: + +IFIELD SHORTNAME, "", "%s" +IFIELD LAT_DECIMAL, "", "%08.5f" +IFIELD LON_DECIMAL, "", "%08.5f" +IFIELD ICON_DESCR, "", "%s" + +OFIELD ANYNAME, "", "%s" +OFIELD LAT_DECIMAL, "", "%08.5f" +OFIELD LON_DECIMAL, "", "%08.5f" +OFIELD ICON_DESCR, "", "%s" diff --git a/style/gpsdrivetrack.style b/style/gpsdrivetrack.style new file mode 100644 index 000000000..a23e14174 --- /dev/null +++ b/style/gpsdrivetrack.style @@ -0,0 +1,30 @@ +# gpsbabel XCSV style file +# +# Format: GPSDriveTrack +# Author: Tobias Minich +# Date: 12/07/2005 +# +# +# + +DESCRIPTION GpsDrive Format for Tracks + +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER WHITESPACE +RECORD_DELIMITER NEWLINE +BADCHARS ,'" + +SHORTLEN 20 +SHORTWHITE 0 + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: + +IFIELD LAT_DECIMAL, "", "%10.6f" +IFIELD LON_DECIMAL, "", "%10.6f" +IFIELD ALT_METERS, "", "%10.0f" +# Reports are that this format stores in local time, not GMT as +# originally thought. +# IFIELD GMT_TIME, "", "%a %b %d %H:%M:%S %Y" +IFIELD LOCAL_TIME, "", "%a %b %d %H:%M:%S %Y" diff --git a/style/gpsman.style b/style/gpsman.style new file mode 100644 index 000000000..e1046dcce --- /dev/null +++ b/style/gpsman.style @@ -0,0 +1,34 @@ +# gpsbabel XCSV style file +# +# Format: GPSMAN Format +# Author: Alex Mottram +# Date: 12/09/2002 +# +# +# As defined in gpsman.c +# +# + +DESCRIPTION GPSman +SHORTLEN 8 +SHORTWHITE 0 + +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER TAB +RECORD_DELIMITER NEWLINE +BADCHARS TAB + +PROLOGUE !Format: DDD 1 WGS 84 +PROLOGUE !W: + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD SHORTNAME, "", "%-8.8s" +IFIELD DESCRIPTION, "", "%s" +IFIELD LAT_DIRDECIMAL, "", "%c%f" +IFIELD LON_DIRDECIMAL, "", "%c%f" +IFIELD IGNORE, "", "%s" + +# gpsman.c likes mkshort len = 8, whitespace = 0. diff --git a/style/kompass_tk.style b/style/kompass_tk.style new file mode 100644 index 000000000..2b6ffaff9 --- /dev/null +++ b/style/kompass_tk.style @@ -0,0 +1,18 @@ +# gpsbabel XCSV style file +# +# Format: Kompass / Deutscher Alpenverein (DAV) Waypoints +# Author: Olaf Klein +# Date: 01/10/2007 +# +# +DESCRIPTION Kompass (DAV) Track (.tk) +DATATYPE TRACK +EXTENSION wp +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS ," +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LAT_DECIMAL, "", "%.7f" +IFIELD LON_DECIMAL, "", "%.7f" diff --git a/style/kompass_wp.style b/style/kompass_wp.style new file mode 100644 index 000000000..2f4db451f --- /dev/null +++ b/style/kompass_wp.style @@ -0,0 +1,26 @@ +# gpsbabel XCSV style file +# +# Format: Kompass / Deutscher Alpenverein (DAV) Waypoints +# Author: Olaf Klein +# Date: 01/10/2007 +# +# +DESCRIPTION Kompass (DAV) Waypoints (.wp) +DATATYPE WAYPOINT +EXTENSION wp +ENCODING UTF-8 +FIELD_DELIMITER SEMICOLON +RECORD_DELIMITER CRNEWLINE +BADCHARS ," +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD SHORTNAME, "", "%s" +IFIELD LON_DECIMAL, "", "%.7f" +IFIELD LAT_DECIMAL, "", "%.7f" +IFIELD ALT_METERS, "", "%.0f" +IFIELD LOCAL_TIME,"","%d.%m.%Y %H:%M:%S" +IFIELD CONSTANT, "Icons\Wegpunkt grün.bmp", "%s" +IFIELD IGNORE, "", "%s" +IFIELD CONSTANT, "1", "%s" # unknown +IFIELD DESCRIPTION, "", "%s" diff --git a/style/ktf2.style b/style/ktf2.style new file mode 100644 index 000000000..61913768e --- /dev/null +++ b/style/ktf2.style @@ -0,0 +1,36 @@ +# gpsbabel XCSV style file +# +# Format: Kartex KTF 2.0 Degrees with decimals +# Author: Harald Nordius +# Date: 4/13 2006 +# +# +DESCRIPTION Kartex 5 Track File +EXTENSION ktf +DATATYPE TRACK +SHORTLEN 10 +SHORTWHITE 1 +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER CRNEWLINE +# +# +# FILE HEADER +# +PROLOGUE //Kartex Track File created by GPSBabel +PROLOGUE &KTF 2.0,sweref 99 lat long,0 +# +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD CONSTANT, %, "%s" +IFIELD INDEX, "", "%d" +IFIELD LATLON_HUMAN_READABLE, "", "%c%f°" +IFIELD ALT_METERS, "", "%.2f" +IFIELD GMT_TIME, "", "%Y-%m-%d %H:%M:%S" +IFIELD IGNORE, "", "%s" #Empty field +IFIELD IGNORE, "", "%s" #Empty field +IFIELD CONSTANT, "$", "%s" diff --git a/style/kwf2.style b/style/kwf2.style new file mode 100644 index 000000000..77fab79d4 --- /dev/null +++ b/style/kwf2.style @@ -0,0 +1,38 @@ +# gpsbabel XCSV style file +# +# Format: Kartex KWF 2.0 Degrees with decimals +# Author: Harald Nordius +# Date: 12/08 2004 +# +# +DESCRIPTION Kartex 5 Waypoint File +EXTENSION kwf +SHORTLEN 10 +SHORTWHITE 1 +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER CRNEWLINE +ENCODING CP1252 +# +# +# FILE HEADER +# +PROLOGUE //Kartex Waypoint File created by GPSBabel +PROLOGUE &KWF 2.0,sweref 99 lat long,0 +# +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD CONSTANT, \#, "%s" +IFIELD INDEX,"","%d" +IFIELD SHORTNAME,"","%s" +IFIELD LATLON_HUMAN_READABLE,"","%c%f°" +IFIELD ALT_METERS,"","%.2f" +IFIELD IGNORE, "","%s" #Empty field +IFIELD IGNORE, "","%s" #Empty field +IFIELD CONSTANT, "0","%s" #Waypoint symbol code +IFIELD DESCRIPTION, "", "%s" +IFIELD CONSTANT, "$", "%s" diff --git a/style/mapconverter.style b/style/mapconverter.style new file mode 100644 index 000000000..cf38b1f15 --- /dev/null +++ b/style/mapconverter.style @@ -0,0 +1,35 @@ +# Format: Mapopolis.com Mapconverter +# Author: Gary Paulson +# Date: 01/13/2003 +# Requires unsupported mapconverter.exe from mapopolis.com. +# +# Modifications by Alex Mottram documented 6/30/2003 +# Change %-40.40s on description output to %-.40s to stop padding. +# Add QUOTE as badchars, remove COMMA. +# Removed Mapconverter.exe's README information from style file. +# Changed OFIELD to IFIELD in case you ever want to read one of these things. +# +# +DESCRIPTION Mapopolis.com Mapconverter CSV +EXTENSION txt + +# FILE LAYOUT DEFINITIIONS: + +FIELD_DELIMITER COMMASPACE +RECORD_DELIMITER NEWLINE +BADCHARS ", + +# Map Info Record (header): +PROLOGUE M, "Geocaches", "GPSBabel", Geocaches, __FILE__ +# + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +# L Records: +IFIELD CONSTANT, "L", "%s" # [L]ANDMARK +IFIELD CONSTANT, "Geocaches", "%s" # Category for Landmark Searches +IFIELD DESCRIPTION, "", "%-.40s" # Name +IFIELD CONSTANT, "1", "%s" # View at Zoom Level 1 (1-4) +IFIELD LON_DECIMAL, "", "%08.5f" # Longitude +IFIELD LAT_DECIMAL, "", "%08.5f" # Latitude diff --git a/style/mxf.style b/style/mxf.style new file mode 100644 index 000000000..08d35e7d6 --- /dev/null +++ b/style/mxf.style @@ -0,0 +1,39 @@ +# gpsbabel XCSV style file +# +# Format: Ozi Explorer +# Author: Alex Mottram +# Date: 12/09/2002 +# +# +# As used in mxf.c +# +# + +DESCRIPTION MapTech Exchange Format +EXTENSION mxf + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMASPACE +RECORD_DELIMITER NEWLINE +BADCHARS ," + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LAT_DECIMAL, "", "%08.5f" +IFIELD LON_DECIMAL, "", "%08.5f" +IFIELD DESCRIPTION, "", ""%s"" +IFIELD SHORTNAME, "", ""%s"" +IFIELD IGNORE, "", "%s" +IFIELD CONSTANT, "ff0000", "%s" # COLOR +IFIELD CONSTANT, "47", "%s" # ICON + +OFIELD LAT_DECIMAL, "", "%08.5f" +OFIELD LON_DECIMAL, "", "%08.5f" +OFIELD DESCRIPTION, "", ""%s"" +OFIELD SHORTNAME, "", ""%s"" +OFIELD DESCRIPTION, "", ""%s"" +OFIELD CONSTANT, "ff0000", "%s" # COLOR +OFIELD CONSTANT, "47", "%s" # ICON diff --git a/style/nima.style b/style/nima.style new file mode 100644 index 000000000..f0562db59 --- /dev/null +++ b/style/nima.style @@ -0,0 +1,45 @@ +# gpsbabel XCSV style file +# +# Format: NIMA/GNIS Geographic Names File +# Author: Alex Mottram +# Date: 11/24/2002 +# + +DESCRIPTION NIMA/GNIS Geographic Names File + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER TAB +RECORD_DELIMITER NEWLINE +BADCHARS TAB +PROLOGUE RC UFI UNI DD_LAT DD_LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD IGNORE, "", "%s" # RC +IFIELD IGNORE, "", "%s" # UFI +IFIELD IGNORE, "", "%s" # UNI +IFIELD LAT_DECIMAL, "", "%f" # DD_LAT +IFIELD LON_DECIMAL, "", "%f" # DD_LON +IFIELD IGNORE, "", "%s" # DMS_LAT +IFIELD IGNORE, "", "%s" # DMS_LON +IFIELD IGNORE, "", "%s" # UTM +IFIELD IGNORE, "", "%s" # JOG +IFIELD IGNORE, "", "%s" # FC +IFIELD IGNORE, "", "%s" # DSG +IFIELD IGNORE, "", "%s" # PC +IFIELD IGNORE, "", "%s" # CC1 +IFIELD IGNORE, "", "%s" # ADM1 +IFIELD IGNORE, "", "%s" # ADM2 +IFIELD IGNORE, "", "%s" # DIM +IFIELD IGNORE, "", "%s" # CC2 +IFIELD IGNORE, "", "%s" # NT +IFIELD IGNORE, "", "%s" # LC +IFIELD IGNORE, "", "%s" # SHORT_FORM +IFIELD IGNORE, "", "%s" # GENERIC +IFIELD SHORTNAME, "", "%s" # SORT_NAME +IFIELD IGNORE, "", "%s" # FULL_NAME (unicoded!) +IFIELD DESCRIPTION, "", "%s" # FULL_NAME_ND +IFIELD IGNORE, "", "%s" # MODIFY_DATE diff --git a/style/openoffice.style b/style/openoffice.style new file mode 100644 index 000000000..9ba62534a --- /dev/null +++ b/style/openoffice.style @@ -0,0 +1,47 @@ +# gpsbabel XCSV style file +# +# Format: Tab delimited useful for OpenOffice, Ploticus etc. +# Author: Tobias Minich +# Date: 07/18/2005 +# +# + +DESCRIPTION Tab delimited fields useful for OpenOffice, Ploticus etc. + +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER TAB +RECORD_DELIMITER NEWLINE +BADCHARS TAB + +# +# HEADER STUFF: +# +PROLOGUE Index Lat Lon Icon Name Description Notes URL Link Text Altitude (m) Distance (km) Speed (m/s) Course (°) Time HDOP VDOP PDOP Satellites Fix + +# +# INDIVIDUAL DATA FIELDS: +# +IFIELD INDEX, "", "%d" +IFIELD LAT_DECIMAL, "", "%f" +IFIELD LAT_DIR, "", "%c" +IFIELD LAT_HUMAN_READABLE, "", "%d° %f' %c" +IFIELD LON_DECIMAL, "", "%f" +IFIELD LON_DIR, "", "%c" +IFIELD LON_HUMAN_READABLE, "", "%d° %f' %c" +IFIELD ICON_DESCR, "", "%s" +IFIELD SHORTNAME, "", "%s" +IFIELD DESCRIPTION, "", "%s" +IFIELD NOTES, "", "%s" +IFIELD URL, "", "%s" +IFIELD URL_LINK_TEXT, "", "%s" +IFIELD ALT_METERS, "", "%f" +IFIELD PATH_DISTANCE_KM, "", "%f" +IFIELD PATH_SPEED, "", "%f" +IFIELD PATH_COURSE, "", "%f" +IFIELD EXCEL_TIME, "", "%f" +IFIELD GPS_HDOP, "", "%f" +IFIELD GPS_VDOP, "", "%f" +IFIELD GPS_PDOP, "", "%f" +IFIELD GPS_SAT, "", "%d" +IFIELD GPS_FIX, "", "%s" diff --git a/style/s_and_t.style b/style/s_and_t.style new file mode 100644 index 000000000..dbc61c741 --- /dev/null +++ b/style/s_and_t.style @@ -0,0 +1,41 @@ +# gpsbabel XCSV style file +# +# Format: MS S&T 2002/2003 +# Author: Alex Mottram +# Date: 12/09/2002 +# +# +# As requested by Noel Shrum on the gpsbabel-code mailing list. +# Name,Latitude,Longitude,Name 2,URL,Type +# GCCBF,44.479133,-85.56515,High Rollaway by rjlint,http://www.geocaching.com/seek/cache_details.aspx?ID=3263,Traditional Cache +# GC110D,44.6522,-85.492483,Brown Bridge Pond Peek-a-Boo Cache by Big Bird,http://www.geocaching.com/seek/cache_details.aspx?ID=4365,Traditional Cache +# GC171C,44.70605,-85.62265,The Michigan Frog by RealDcoy & LRB,http://www.geocaching.com/seek/cache_details.aspx?ID=5916,Traditional Cache +# + +DESCRIPTION Microsoft Streets and Trips 2002-2007 +EXTENSION txt + + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER TAB +RECORD_DELIMITER NEWLINE +BADCHARS ," + +PROLOGUE Name Latitude Longitude Description URL Type Container Diff Terr + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# NOTE: MS S&T ONLY IMPORTS DATA, IT DOESN'T EXPORT THIS ANYWHERE SO WE CAN +# HAVE OUR WAY WITH THE FORMATTING. +# +IFIELD SHORTNAME, "", "%s" # Name +IFIELD LAT_DECIMAL, "", "%f" # Latitude +IFIELD LON_DECIMAL, "", "%f" # Longitude +IFIELD DESCRIPTION, "", "%s" # Name 2 (Big Description) +IFIELD URL, "", "%s" # URL +IFIELD GEOCACHE_TYPE, "", "%s" # Geocache Type +IFIELD GEOCACHE_CONTAINER, "", "%s" # Geocache Type +IFIELD GEOCACHE_DIFF, "", "%3.1f" # Geocache Type +IFIELD GEOCACHE_TERR, "", "%3.1f" # Geocache Type diff --git a/style/saplus.style b/style/saplus.style new file mode 100644 index 000000000..26f24b65b --- /dev/null +++ b/style/saplus.style @@ -0,0 +1,28 @@ +# gpsbabel XCSV style file +# +# Format: +# Author: Jim Bensman +# Date: 02/22/04 +# + +DESCRIPTION DeLorme Street Atlas Plus + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS ," + +PROLOGUE Name 2,Name,Latitude,Longitude,URL,Type + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD DESCRIPTION, "", "%s" # Name 2 (Big Description) +IFIELD SHORTNAME, "", "%s" # Name +IFIELD LAT_DECIMAL, "", "%f" # Latitude +IFIELD LON_DECIMAL, "", "%f" # Longitude +IFIELD URL, "", "%s" # URL +IFIELD IGNORE, "", "" # Holder for Geocache Type + diff --git a/style/sportsim.style b/style/sportsim.style new file mode 100644 index 000000000..a029a99be --- /dev/null +++ b/style/sportsim.style @@ -0,0 +1,33 @@ +# gpsbabel XCSV style file +# +# Format: Sportsim track files +# Author: Olaf Klein +# Date: 07/05/2006 +# +DESCRIPTION Sportsim track files (part of zipped .ssz files) +EXTENSION txt +DATATYPE TRACK + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER SEMICOLON +RECORD_DELIMITER CRNEWLINE +BADCHARS TAB + +# +# FILE HEADER +# +PROLOGUE SportsimVersion:01 +PROLOGUE \#Sportsim TrackFile + +# +# INDIVIDUAL DATA FIELDS: +# +IFIELD INDEX, "", "%05d" +IFIELD CONSTANT, "0", "%s" +IFIELD LAT_DECIMAL, "", "%f" +IFIELD LON_DECIMAL, "", "%f" +IFIELD ALT_FEET, "", "%.f" +IFIELD TIMET_TIME, "", "%ld" +IFIELD CONSTANT, ";", "%s" diff --git a/style/tabsep.style b/style/tabsep.style new file mode 100644 index 000000000..65d0f31d4 --- /dev/null +++ b/style/tabsep.style @@ -0,0 +1,57 @@ +# gpsbabel XCSV style file +# +# Format: Dumps all fields in a traditional Unix tab separated style +# +# The order of the fields (with the exception of LAT_DIR/LON_DIR) was +# the same as documented in README.style when this format was created. +# LAT_DIR/LON_DIR were undocumented, so I stuck them at the end of the +# other lat/lon fields. +# +# However, please add any new gpsbabel fields to the end (to avoid +# upsetting existing applications) regardless of where they land in +# the README.style documentation. +# + +DESCRIPTION All database fields on one tab-separated line + +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER TAB +RECORD_DELIMITER NEWLINE +BADCHARS TAB +FORMAT_TYPE INTERNAL + +# +# INDIVIDUAL DATA FIELDS: +# +IFIELD INDEX, "", "%d" +IFIELD SHORTNAME, "", "%s" +IFIELD DESCRIPTION, "", "%s" +IFIELD NOTES, "", "%s" +IFIELD URL, "", "%s" +IFIELD URL_LINK_TEXT, "", "%s" +IFIELD ICON_DESCR, "", "%s" +IFIELD LAT_DECIMAL, "", "%f" +IFIELD LON_DECIMAL, "", "%f" +IFIELD LAT_INT32DEG, "", "%ld" +IFIELD LON_INT32DEG, "", "%ld" +IFIELD LAT_DECIMALDIR, "", "%f%c" +IFIELD LON_DECIMALDIR, "", "%f%c" +IFIELD LAT_DIRDECIMAL, "", "%c%f" +IFIELD LON_DIRDECIMAL, "", "%c%f" +IFIELD LAT_DIR, "", "%c" +IFIELD LON_DIR, "", "%c" +IFIELD ALT_FEET, "", "%fF" +IFIELD ALT_METERS, "", "%fM" +IFIELD EXCEL_TIME, "", "%f" +IFIELD TIMET_TIME, "", "%ld" +IFIELD GEOCACHE_DIFF,"","%3.1f" +IFIELD GEOCACHE_TERR,"","%3.1f" +IFIELD GEOCACHE_CONTAINER,"","%s" +IFIELD GEOCACHE_TYPE,"","%s" +IFIELD PATH_DISTANCE_MILES,"","%f" +IFIELD PATH_DISTANCE_KM, "", "%f" +IFIELD GEOCACHE_PLACER,"","%s" +IFIELD YYYYMMDD_TIME,"","%ld" +IFIELD GEOCACHE_HINT, "", "%s" +IFIELD GEOCACHE_LAST_FOUND, "", "%d" diff --git a/style/tomtom_asc.style b/style/tomtom_asc.style new file mode 100644 index 000000000..022936a9f --- /dev/null +++ b/style/tomtom_asc.style @@ -0,0 +1,27 @@ +# gpsbabel XCSV style file +# +# Format: TomTom Navigator Places of Interest +# Author: Olaf Klein +# Date: 04/17/2007 +# +DESCRIPTION TomTom POI file (.asc) +EXTENSION asc +DATATYPE WAYPOINT +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER CRNEWLINE +BADCHARS ," +ENCODING MS-ANSI +# +PROLOGUE TomTom Navigator Places of Interest +PROLOGUE GPSBabel-__VERSION__ ASCII Export +PROLOGUE Points +PROLOGUE Created at: __DATE_AND_TIME__ +# # +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LON_DECIMAL, "", "%.6f" +IFIELD LAT_DECIMAL, "", "%.6f" +IFIELD SHORTNAME, "", ""%s"" diff --git a/style/tomtom_itn.style b/style/tomtom_itn.style new file mode 100644 index 000000000..60e9af9ff --- /dev/null +++ b/style/tomtom_itn.style @@ -0,0 +1,23 @@ +# gpsbabel XCSV style file +# +# Format: TomTom Navigator Itineraries (Routes) +# Author: Olaf Klein +# Date: 04/17/2007 +# +DESCRIPTION TomTom Itineraries (.itn) +EXTENSION itn +DATATYPE ROUTE +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER PIPE +RECORD_DELIMITER CRNEWLINE +BADCHARS ,| +ENCODING MS-ANSI +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LON_10E5, "", "%.f" +IFIELD LAT_10E5, "", "%.f" +IFIELD SHORTNAME, "", "%s" +IFIELD CONSTANT, "0", "%s" diff --git a/style/xmap.style b/style/xmap.style new file mode 100644 index 000000000..96a2246d6 --- /dev/null +++ b/style/xmap.style @@ -0,0 +1,32 @@ +# gpsbabel XCSV style file +# +# Format: DeLorme Xmap Conduit +# Author: Alex Mottram +# Date: 12/09/2002 +# +# +# As defined in csv.c/xmap +# + +DESCRIPTION DeLorme XMap HH Native .WPT +EXTENSION wpt + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMASPACE +RECORD_DELIMITER NEWLINE +BADCHARS COMMA + +PROLOGUE BEGIN SYMBOL +EPILOGUE END +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LAT_HUMAN_READABLE, "", "%08.5f" +IFIELD LON_HUMAN_READABLE, "", "%08.5f" +IFIELD DESCRIPTION, "", "%s" + +OFIELD LAT_DECIMAL, "", "%08.5f" +OFIELD LON_DECIMAL, "", "%08.5f" +OFIELD DESCRIPTION, "", "%s" diff --git a/style/xmap2006.style b/style/xmap2006.style new file mode 100644 index 000000000..7b4ce2380 --- /dev/null +++ b/style/xmap2006.style @@ -0,0 +1,37 @@ +# gpsbabel XCSV style file +# +# Format: DeLorme Xmap/Street Atlas Handheld 2006 Conduit +# Author: Pasha Phares +# Date: 5/5/2006 +# +# Amazingly, 2006 won't read the "COMMASPACE" that we used in +# in Xmap prior to this and versions before 2006 won't read files +# separated by only a comma. +# + +DESCRIPTION DeLorme XMap/SAHH 2006 Native .TXT +EXTENSION txt + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA + +PROLOGUE BEGIN SYMBOL +EPILOGUE END +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LAT_HUMAN_READABLE, "", "%.12g" +IFIELD LON_HUMAN_READABLE, "", "%.12g" +IFIELD SHORTNAME, "", "%s" + +OFIELD LAT_DECIMAL, "", "%.12g" +OFIELD LON_DECIMAL, "", "%.12g" +OFIELD SHORTNAME, "", "%s" + + + + diff --git a/style/xmapwpt.style b/style/xmapwpt.style new file mode 100644 index 000000000..f6dd56337 --- /dev/null +++ b/style/xmapwpt.style @@ -0,0 +1,30 @@ +# gpsbabel XCSV style file +# +# Format: DeLorme Xmap HH Street Atlas USA .WPT (PocketPC) +# Author: Alex Mottram +# Date: 12/09/2002 +# +# +DESCRIPTION DeLorme XMat HH Street Atlas USA .WPT (PPC) +SHORTLEN 32 +SHORTWHITE 0 + +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COLON +RECORD_DELIMITER NEWLINE +BADCHARS COLON + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD CONSTANT, "1296126539", "%s" +IFIELD CONSTANT, "1481466224", "%s" +IFIELD LAT_INT32DEG, "", "%d" +IFIELD LON_INT32DEG, "", "%d" +IFIELD CONSTANT, "3137157", "%s" +IFIELD SHORTNAME, "", "%-.31s" +IFIELD IGNORE, "", "%-.31s" +IFIELD DESCRIPTION, "", "%-.78s" diff --git a/tef_xml.c b/tef_xml.c new file mode 100644 index 000000000..70d9d0dfd --- /dev/null +++ b/tef_xml.c @@ -0,0 +1,318 @@ +/* + Support for XML based "TourExchangeFormat", + found in Map & Guide Motorrad-Tourenplaner 2005/06 + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + Based on kml.c, Keyhole "kml" format. + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#include "defs.h" +#include "xmlgeneric.h" + +static waypoint *wpt_tmp; +static int item_count; +static int waypoints; +static double version; +static route_head *route = NULL; + +static char *routevia = NULL; + +static arglist_t tef_xml_args[] = +{ + {"routevia", &routevia, "Include only via stations in route", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +#define MYNAME "TourExchangeFormat" + +#if ! HAVE_LIBEXPAT +void +tef_xml_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded TEF support because expat was not installed.\n"); +} + +void +tef_xml_read(void) +{ +} + +#else + +static char * +trimmed_strdup(const char *str) +{ + char *c1, *c2, *res; + + c1 = xstrdup(str); + c2 = lrtrim(c1); + if (*c2) res = xstrdup(c2); + else res = NULL; + xfree(c1); + return res; +} + +static xg_callback tef_start, tef_header, tef_list_start, tef_list_end; +static xg_callback tef_item_start, tef_point, tef_item_end; + +static +xg_tag_mapping tef_xml_map[] = { + { tef_start, cb_start, "/TEF" }, + { tef_header, cb_start, "/TEF/Header" }, + { tef_list_start, cb_start, "/TEF/WaypointList" }, + { tef_item_start, cb_start, "/TEF/WaypointList/Item" }, + { tef_point, cb_start, "/TEF/WaypointList/Item/Point" }, + { tef_item_end, cb_end, "/TEF/WaypointList/Item" }, + { tef_list_end, cb_end, "/TEF/WaypointList" }, + { NULL, 0, NULL } +}; + + +/* + * tef_start: check for comment "TourExchangeFormat" + */ + +void +tef_start(const char *args, const char **attrv) +{ + int valid = 0; + const char **avp = &attrv[0]; + + while (*avp) { + if (0 == case_ignore_strcmp(avp[0], "Comment")) { + if (0 == case_ignore_strcmp(avp[1], "TourExchangeFormat")) + valid = 1; + } + else if (0 == case_ignore_strcmp(avp[0], "Version")) + version = atof(avp[1]); + avp+=2; + } + if (!valid) + fatal(MYNAME ": Error in source file.\n"); +} + +/* + * tef_header: "Name" > Route name, "Software" > Route descr. + */ + +static void +tef_header(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + route = route_head_alloc(); + while (*avp) { + if (case_ignore_strcmp(avp[0], "Name") == 0) + route->rte_name = trimmed_strdup(avp[1]); + else if (case_ignore_strcmp(avp[0], "Software") == 0) + route->rte_desc = trimmed_strdup(avp[1]); + avp+=2; + } + route_add_head(route); +} + +static void +tef_list_start(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "ItemCount") == 0) + sscanf(avp[1], "%d", &item_count); + avp+=2; + } +} + +/* in "TourExchangeFormat" the following can happen: + * + * SegDescription="L34\Wittlicher Strasse" + * PointDescription="Wittlicher Strasse ( " + * + * fix_notes tries to create a new PointDescription, which + * should be "Wittlicher Strasse (L34)" for the example above + */ + +static char * +fix_notes(const char *name, char *notes) +{ + char *cleft, *cright, *cback, *ctmp; + + if ((! name) || (! notes)) return notes; + + /* do we have a BACKSLASH in shortname ? */ + cback = strchr(name, '\\'); + if ((! cback) || (cback == name)) return notes; + + /* do we have left, but no right parenthesis in notes ? */ + if (! (cleft = strchr(notes, '('))) return notes; + cright = strchr(notes, ')'); + if (cright && (cright > cleft)) return notes; + + /* now contruct the new name */ + ctmp = lrtrim(xstrndup(notes, cleft - notes)); + xfree(notes); + xasprintf(¬es, "%s (%*.*s)", ctmp, cback - name, cback - name, name); + xfree(ctmp); + + return notes; +} + +static void +waypoint_final() +{ + int via; + if (wpt_tmp == NULL) return; + + via = wpt_tmp->microseconds; + wpt_tmp->microseconds = 0; + + if (version < 2) { /* keep the old behaviour */ + wpt_tmp->notes = wpt_tmp->description; + wpt_tmp->description = NULL; + } + + wpt_tmp->notes = fix_notes(wpt_tmp->shortname, wpt_tmp->notes); + + if (via != 0) + waypt_add(wpt_tmp); + + if (route != NULL) { + if ((via != 0) || (routevia == NULL)) { + waypoint *wpt = waypt_dupe(wpt_tmp); + route_add_wpt(route, wpt); + } + } + + if (via == 0) + waypt_free(wpt_tmp); + + wpt_tmp = NULL; +} + +static void +tef_item_end(const char *args, const char **unused) +{ + waypoint_final(); +} + +static void +tef_list_end(const char *args, const char **unused) +{ + waypoint_final(); + if (waypoints != item_count) + fatal(MYNAME ": waypoint count differs to internal \"ItemCount\"! (%d to %d)\n", + waypoints, item_count); +} + +static void +tef_item_start(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + waypoints++; + + wpt_tmp = waypt_new(); + if ((waypoints == 1) || (waypoints == item_count)) + wpt_tmp->microseconds++; + + while (*avp) + { + if (0 == case_ignore_strcmp(avp[0], "SegDescription")) + wpt_tmp->shortname = trimmed_strdup(avp[1]); + else if (0 == case_ignore_strcmp(avp[0], "PointDescription")) + wpt_tmp->description = trimmed_strdup(avp[1]); + else if ((0 == case_ignore_strcmp(avp[0], "ViaStation")) && + (0 == case_ignore_strcmp(avp[1], "true"))) + wpt_tmp->microseconds = 1; /* only a flag */ + + /* new in TEF V2 */ + else if (0 == case_ignore_strcmp(avp[0], "Instruction")) + wpt_tmp->description = trimmed_strdup(avp[1]); + else if (0 == case_ignore_strcmp(avp[0], "Altitude")) + wpt_tmp->altitude = atof(avp[1]); + else if (0 == case_ignore_strcmp(avp[0], "TimeStamp")) + /* nothing for the moment */; + + avp+=2; + } +} + +static void +tef_point(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + char *comma; + + if (!wpt_tmp) return; + + while (*avp) { + if (strcmp(avp[0], "y") == 0) { + comma = strstr(avp[1], ","); + if (comma) *comma='.'; + sscanf(avp[1], "%lf", &wpt_tmp->latitude); + } + else if (strcmp(avp[0], "x") == 0) { + comma = strstr(avp[1], ","); + if (comma) *comma='.'; + sscanf(avp[1], "%lf", &wpt_tmp->longitude); + } + avp+=2; + } +} + +static void +tef_xml_rd_init(const char *fname) +{ + wpt_tmp = NULL; + waypoints = 0; + item_count = -1; + version = 1.5; + + xml_init(fname, tef_xml_map, NULL); +} + +static void +tef_xml_read(void) +{ + xml_read(); +} + +#endif + +static void +tef_xml_rd_deinit(void) +{ + xml_deinit(); +} + +ff_vecs_t tef_xml_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read }, + tef_xml_rd_init, + NULL, + tef_xml_rd_deinit, + NULL, + tef_xml_read, + NULL, + NULL, + tef_xml_args, + CET_CHARSET_UTF8, 1 +}; diff --git a/test-all b/test-all new file mode 100755 index 000000000..088c7ca96 --- /dev/null +++ b/test-all @@ -0,0 +1,213 @@ +#!/bin/bash + +### cross format read/(write) test ### + +PNAME=${PNAME:-./gpsbabel} +REFGPX="reference/expertgps.gpx" # reference file for all tests +EXCL="exif ozi vitosmt xol" # exclude formats from test +CAPS="" +TEMPDIR=${GBTEMP:-/tmp}/gb-test-all +CATALOG=/tmp/gb-test-all.done +LOGFILE=/tmp/gb-test-all.log +RNDFILE=/tmp/gb-random.gpx + +# options +vg=0 +prep=0 + +function log_entry() +{ + touch $LOGFILE + echo "-----------------------------------------------------------------------" >> ${LOGFILE} + date >> ${LOGFILE} + echo "$*" >> ${LOGFILE} +} + +function try_run() # command line +{ + local CMD="$*" + local RES=0 + + [ $vg -ne 0 ] && CMD="valgrind -q $CMD" + + ${CMD} > $TEMPDIR/.result 2>&1 + RES=$? + if [ $RES -ne 0 -o -s $TEMPDIR/.result ]; then + if [ $RES -ne 0 ]; then + echo " -- Uhps --" + echo "-----------------------------------------------------------------------" + test -s $TEMPDIR/.result && cat $TEMPDIR/.result + echo "-----------------------------------------------------------------------" + else + echo "" + fi + log_entry "cmd($RES): $CMD" + test -s $TEMPDIR/.result && cat $TEMPDIR/.result >> ${LOGFILE} + return 1 + else + return 0 + fi +} + +function STAGE_1 () # type format +{ + local TYP=$1 + local FMT=$2 + local CMD1 CMD2 IFILE OFILE + + echo "$CAPS" | + + while read type caps format comment; do + + for i in $EXCL; do + if [ "$format" == "$i" ]; then + caps="------" + fi + done + + grep "$TYP: $FMT & $format" ${CATALOG} > /dev/null && continue + + echo -n "testing " + case $TYP in + w) + echo -n "waypoints" + caps=${caps:0:2} + ;; + t) + echo -n "tracks" + caps=${caps:2:2} + ;; + r) + echo -n "routes" + caps=${caps:4:2} + ;; + esac + + echo -n ": \"$FMT\" with \"$format\" " + + IFILE=$TEMPDIR/$TYP-$FMT + OFILE=$TEMPDIR/$TYP-$FMT.$format + + case $caps in + -w) + echo -n "*" + CMD1="${PNAME} -$TYP -i $FMT -f $IFILE -o $format -F $OFILE" + try_run "${CMD1}" || continue + ;; + + rw) + echo -n "*" + CMD1="${PNAME} -$TYP -i $FMT -f $IFILE -o $format -F $OFILE" + try_run "${CMD1}" || continue + echo -n "*" + CMD2="${PNAME} -$TYP -i $format -f $OFILE -o $FMT -F $OFILE.$FMT" + try_run "${CMD2}" || continue + ;; + esac + + echo "*" + echo "$TYP: $FMT & $format" >> $CATALOG + done + return 0 +} + +function STAGE_0 () +{ + echo "$CAPS" | + + while read type caps format comment; do + + for i in $EXCL; do + if [ "$format" == "$i" ]; then + caps="------" + fi + done + + case ${caps:0:2} in + rw) + CMD="${PNAME} -i gpx -f $REFGPX -x nuketypes,routes,tracks -o $format -F $TEMPDIR/w-$format" + try_run "${CMD}" || continue + STAGE_1 "w" $format || exit 1 + ;; + -w) + CMD="${PNAME} -i gpx -f $REFGPX -x nuketypes,routes,tracks -o $format -F $TEMPDIR/w-$format" + try_run "${CMD}" || continue + ;; + esac + case ${caps:2:2} in + rw) + CMD="${PNAME} -t -i gpx -f $REFGPX -x nuketypes,waypoints,routes -x track,fix=2D -o $format -F $TEMPDIR/t-$format" + try_run "${CMD}" || continue + STAGE_1 "t" $format || exit 1 + ;; + -w) + CMD="${PNAME} -t -i gpx -f $REFGPX -x nuketypes,waypoints,routes -x track,fix=2D -o $format -F $TEMPDIR/t-$format" + try_run "${CMD}" || continue + ;; + esac + case ${caps:4:2} in + rw) + CMD="${PNAME} -r -i gpx -f $REFGPX -x nuketypes,waypoints,tracks -o $format -F $TEMPDIR/r-$format" + try_run "${CMD}" || continue + STAGE_1 "r" $format || exit 1 + ;; + -w) + CMD="${PNAME} -r -i gpx -f $REFGPX -x nuketypes,waypoints,tracks -o $format -F $TEMPDIR/r-$format" + try_run "${CMD}" || continue + ;; + esac + done + rm -f $TEMPDIR/.result +} + +rm -rf $TEMPDIR > /dev/null +mkdir -p $TEMPDIR > /dev/null + +while [ $# -gt 0 ]; do + case $1 in + -s|--start) # remove catalog. run the full test. + rm -f $CATALOG + ;; + -v|--valgrind) + vg=1 + ;; + -p|--prepare) # prepare for valgrind check. + prep=1 + ;; + -c|--clean) + trap "rm -fr $TEMPDIR; exit 1" 0 1 2 3 15 + ;; + -n|--random) + ${PNAME} -i random -w -f - -i random,points=48 -r -f - -i random,points=120 -t -f - -o gpx,gpxver=1.1 -F $RNDFILE + REFGPX=/tmp/gb-random.gpx + ;; + -r|--reference) + shift + REFGPX=$1 + ;; + esac + shift +done + +if [ $prep -ne 0 ]; then + test -s Makefile && make clean + CFLAGS="-O0" ./configure || exit 1 # -O0 is suggested by vg. + make || exit 1 + echo "All fine. You can do now a 'test-all -v'" + exit 0 +fi + +if test ! -s $REFGPX; then + echo "GPX reference \"$REFGPX\" doesn't exist!" + exit 1 +fi + +test -s $LOGFILE && rm -f $LOGFILE.bak > /dev/null +touch $LOGFILE +touch $CATALOG + +log_entry "test-all started." +echo "Catalog: $CATALOG" >> $LOGFILE + +CAPS=`${PNAME} -^2 | grep "^file"` +STAGE_0 diff --git a/testc b/testc new file mode 100755 index 000000000..aa9d64a9e --- /dev/null +++ b/testc @@ -0,0 +1,57 @@ +#!/bin/bash + +# +# try to read and write all combinations we can. Don't try to +# be terribly portable and don't test for correctness. This test +# is meant for code coverage. +# + +# Exercise read and write of waypoint/track/route in every format. + +TMPD=/tmp/babeltest.$$ +GB="./gpsbabel" +GB="valgrind -q ./gpsbabel" + +mkdir $TMPD + +rwall() { + name=$1 + cap=$2 + + REFFILE=reference/expertgps.gpx + + if [ $(echo $cap | grep -s w) ]; then + $GB -i gpx -f $REFFILE -o $name -F $TMPD/$name + if [ $(echo $cap | grep -s r) ]; then + $GB -i $name -f $TMPD/$name -o gpx -F /dev/null + fi + fi +} + +# +# Given a Geocache as input, verify we can write it. +# +wgc() { + name=$1 + cap=$2 + + REFDIR=reference/gc + if [ $(echo $cap | grep -s '^.w') ]; then + $GB -i gpx -f $REFDIR/GC7FA4.gpx -o $name -F $TMPD/$name-gc1 + $GB -i gpx -f $REFDIR/GCGCA8.gpx -o $name -F $TMPD/$name-gc2 + fi +} + + +$GB -^2 | while read fmt cap name junk +do + if [ "$fmt" != "file" ]; then + continue; + fi + + rwall $name $cap + wgc $name $cap + + echo $name + +done diff --git a/testo b/testo new file mode 100755 index 000000000..b6a9a4ed7 --- /dev/null +++ b/testo @@ -0,0 +1,1335 @@ +#!/bin/sh + +GPSBABEL_FREEZE_TIME=y +export GPSBABEL_FREEZE_TIME + +# Turn on GNU libc instrumentation. +MALLOC_CHECK_=2 +export MALLOC_CHECK_ + +PNAME=${PNAME:-./gpsbabel} +DIFF=${DIFF:-diff} +REFERENCE=reference +# OD=${OD:-od -Ax -txC -v} +if [ -x /usr/bin/hexdump ] ; then + OD=${OD:-hexdump -v -C} +else + OD=${OD:-od -Ax -txC -v} +fi + +TMPDIR=${GBTEMP:-/tmp}/gpsbabel.$$ +mkdir -p $TMPDIR +trap "rm -fr $TMPDIR" 0 1 2 3 15 + +bincompare() +{ + rm -f ${TMPDIR}/bc1 + rm -f ${TMPDIR}/bc2 + ${OD} $1 >${TMPDIR}/bc1 + ${OD} $2 >${TMPDIR}/bc2 + ${DIFF} -u ${TMPDIR}/bc1 ${TMPDIR}/bc2 || { + echo ERROR binary comparing $* + exit 1 + } +} + +compare() +{ + ${DIFF} $* || { + echo ERROR comparing $* + exit 1 + } +} + +sort_and_compare() +{ + sort $1 > $TMPDIR/s1 + sort $2 > $TMPDIR/s2 + compare $TMPDIR/s1 $TMPDIR/s2 +} + +# Some formats are just too boring to test. The ones that +# are xcsv include +# garmin301 +# garmin_poi +# gpsdrivetrack +# nima +# mapconverter +# geonet +# saplus +# s_and_t +# xmap2006 +# cambridge +# cup + +# Geocaching .loc +rm -f ${TMPDIR}/gl.loc +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o geo -F ${TMPDIR}/gl.loc +compare ${TMPDIR}/gl.loc ${REFERENCE} + +# GPSUtil +rm -f ${TMPDIR}/gu.wpt ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpsutil -F ${TMPDIR}/gu.wpt +compare ${TMPDIR}/gu.wpt ${REFERENCE} +${PNAME} -i gpsutil -f ${TMPDIR}/gu.wpt -o gpx -F ${TMPDIR}/1.gpx +${PNAME} -i gpsutil -f ${REFERENCE}/gu.wpt -o gpx -F ${TMPDIR}/2.gpx +compare ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx + +# GPSman +rm -f ${TMPDIR}/gm.gm ${TMPDIR}/gm.gm+ +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpsman -F ${TMPDIR}/gm.gm +${PNAME} -i gpsman -f ${TMPDIR}/gm.gm -o gpsutil -F ${TMPDIR}/gm.gm+ +compare ${TMPDIR}/gm.gm+ ${TMPDIR}/gu.wpt + +# GPX +rm -f ${TMPDIR}/gl.gpx ${TMPDIR}/gpx.gpx +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpx -F ${TMPDIR}/gl.gpx +${PNAME} -i gpx -f ${TMPDIR}/gl.gpx -o gpsutil -F ${TMPDIR}/gpx.gpx +compare ${TMPDIR}/gpx.gpx ${TMPDIR}/gu.wpt + +# GTM +rm -f ${TMPDIR}/gl.gpx ${TMPDIR}/gpx.gpx +${PNAME} -i gtm -f ${REFERENCE}/sample.gtm -o gpx -F ${TMPDIR}/gtm1.gpx +${PNAME} -i gpx -f ${TMPDIR}/gtm1.gpx -o gtm -F ${TMPDIR}/gtm.gtm +${PNAME} -i gtm -f ${TMPDIR}/gtm.gtm -o gpx -F ${TMPDIR}/gtm2.gpx +compare ${TMPDIR}/gtm1.gpx ${TMPDIR}/gtm2.gpx +bincompare ${TMPDIR}/gtm.gtm ${REFERENCE}/sample.gtm +# +# GTM compressed files +# ... do the same as above but with gzipped gtm files +# +rm -f ${TMPDIR}/gl.gpx ${TMPDIR}/gpx.gpx +${PNAME} -i gtm -f ${REFERENCE}/sample.gtm.gz -o gpx -F ${TMPDIR}/gtm1.gpx +${PNAME} -i gpx -f ${TMPDIR}/gtm1.gpx -o gtm -F ${TMPDIR}/gtm.gtm.gz +${PNAME} -i gtm -f ${TMPDIR}/gtm.gtm.gz -o gpx -F ${TMPDIR}/gtm2.gpx +compare ${TMPDIR}/gtm1.gpx ${TMPDIR}/gtm2.gpx +bincompare ${TMPDIR}/gtm.gtm.gz ${REFERENCE}/sample.gtm.gz +gunzip -c ${TMPDIR}/gtm.gtm.gz > ${TMPDIR}/gtm.gtm +gunzip -c ${REFERENCE}/sample.gtm.gz > ${TMPDIR}/sample.gtm +bincompare ${TMPDIR}/gtm.gtm ${REFERENCE}/sample.gtm + +# Magellan Mapsend +rm -f ${TMPDIR}/mm.mapsend ${TMPDIR}/mm.gps +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o mapsend -F ${TMPDIR}/mm.mapsend +${PNAME} -i mapsend -f ${TMPDIR}/mm.mapsend -o gpsutil -F ${TMPDIR}/mm.gps +compare ${TMPDIR}/mm.gps ${TMPDIR}/gu.wpt + +# Magellan serial +# TODO + +# Tiger +# This one is a little tacky, becuase it's a very lossy format. +# so we simply test we can write it, and then read it and write it and +# get an identical file back. +rm -f ${TMPDIR}/tiger +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o tiger -F ${TMPDIR}/tiger +${PNAME} -i tiger -f ${TMPDIR}/tiger -o tiger -F ${TMPDIR}/tiger2 +compare ${TMPDIR}/tiger ${TMPDIR}/tiger2 + +# +# Lowrance USR. Binary, and also slightly lossy because of the math to +# convert lat/long. It also doesn't support description, which makes it +# awkward to test. +# +rm -f ${TMPDIR}/lowrance1.usr +rm -f ${TMPDIR}/enchilada1.usr +rm -f ${TMPDIR}/enchilada.gpx +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o lowranceusr -F ${TMPDIR}/lowrance1.usr +bincompare ${TMPDIR}/lowrance1.usr ${REFERENCE}/lowrance.usr +${PNAME} -i lowranceusr -f ${TMPDIR}/lowrance1.usr -o lowranceusr -F ${TMPDIR}/lowrance1.usr +# And because of the FP rounding, we can't even read our file, write it back +# and get the same data. Sigh. +# bincompare ${REFERENCE}/lowrance.usr ${TMPDIR}/lowrance1.usr +${PNAME} -i lowranceusr -f ${REFERENCE}/all.usr -o gpx -F ${TMPDIR}/enchilada.gpx +${PNAME} -i gpx -f ${TMPDIR}/enchilada.gpx -o lowranceusr -F ${TMPDIR}/enchilada1.usr +bincompare ${TMPDIR}/enchilada1.usr ${REFERENCE}/enchilada.usr +# Don't convert icons as waypts +${PNAME} -i lowranceusr,ignoreicons -f ${REFERENCE}/all.usr -o gpx -F ${TMPDIR}/enchilada.gpx +${PNAME} -i gpx -f ${TMPDIR}/enchilada.gpx -o lowranceusr -F ${TMPDIR}/enchilada1.usr +bincompare ${TMPDIR}/enchilada1.usr ${REFERENCE}/ignoreicons.usr + +# CSV (Comma separated value) data. + +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o csv -F ${TMPDIR}/csv.csv +${PNAME} -i csv -f ${TMPDIR}/csv.csv -o csv -F ${TMPDIR}/csv2.csv +compare ${TMPDIR}/csv2.csv ${TMPDIR}/csv.csv + +# +# Delorme TopoUSA 4 is a CSV strain. +# +rm -f ${TMPDIR}/xmap-1.gpx ${TMPDIR}/xmap-2.gpx ${TMPDIR}/xmap +${PNAME} -i xmap -f ${REFERENCE}/xmap -o xmap -F ${TMPDIR}/xmap +${PNAME} -i xmap -f ${REFERENCE}/xmap -o gpx -F ${TMPDIR}/xmap-1.gpx +${PNAME} -i xmap -f ${TMPDIR}/xmap -o gpx -F ${TMPDIR}/xmap-2.gpx +compare ${TMPDIR}/xmap-1.gpx ${TMPDIR}/xmap-2.gpx +compare ${REFERENCE}/xmap ${TMPDIR}/xmap + +# PCX (Garmin mapsource import) file format +rm -f ${TMPDIR}/mm.pcx ${TMPDIR}/pcx.gps +${PNAME} -i gpx -f ${REFERENCE}/geocaching.gpx -o pcx -F ${TMPDIR}/mm.pcx +${PNAME} -i pcx -f ${TMPDIR}/mm.pcx -o gpsutil -F ${TMPDIR}/pcx.gps +compare ${TMPDIR}/mm.gps ${TMPDIR}/gu.wpt +${PNAME} -t -i gpx -f ${REFERENCE}/track/tracks.gpx -o pcx -F ${TMPDIR}/pcx.trk +${PNAME} -t -i pcx -f ${REFERENCE}/track/pcx.trk -o pcx -F ${TMPDIR}/pcx2.trk +compare ${TMPDIR}/pcx.trk ${TMPDIR}/pcx2.trk +# GPSUtil strain - hand crafted, but based on problem report. +${PNAME} -i pcx -f reference/gpsutil-1.pcx -o pcx -F ${TMPDIR}/mm-2.pcx +compare ${TMPDIR}/mm-2.pcx ${TMPDIR}/mm.pcx + +# +# Magellan file format +# +${PNAME} -i magellan -f ${REFERENCE}/magfile -o magellan -F ${TMPDIR}/magfile +compare ${TMPDIR}/magfile ${REFERENCE}/magfile + +# +# Magellanx is just like, but with longer names. (which this admittedly +# doesn't actually exercise...) +# +${PNAME} -i magellan -f ${REFERENCE}/magfile -o magellanx -F ${TMPDIR}/magfile2 +compare ${TMPDIR}/magfile2 ${REFERENCE}/magfile + +# Magellanx routes, however, have an extra 'name' field in them. +${PNAME} -r -i magellanx -f ${REFERENCE}/route/magexplorist.rte -o magellanx -F ${TMPDIR}/magxfile.rte +${PNAME} -r -i magellanx -f ${TMPDIR}/magxfile.rte -o magellanx -F ${TMPDIR}/magxfile2.rte +compare ${TMPDIR}/magxfile2.rte ${REFERENCE}/route/magexplorist.rte + + +# Navitrak DNA marker format +${PNAME} -i dna -f ${REFERENCE}/dnatest.txt -o dna -F ${TMPDIR}/dnatest.txt +compare ${TMPDIR}/dnatest.txt ${REFERENCE}/dnatest.txt + +# PSP (PocketStreets 2002 Pushpin (.PSP)) file format. Use mxf as an +# intermediate format to avoid binary FP anomalies on compareerent platforms. +rm -f ${TMPDIR}/psp.mxf ${TMPDIR}/mxf.psp +${PNAME} -i psp -f ${REFERENCE}/ps.psp -o mxf -F ${TMPDIR}/psp.mxf +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o mxf -F ${TMPDIR}/mxf.psp +compare ${TMPDIR}/psp.mxf ${TMPDIR}/mxf.psp +${PNAME} -i psp -f ${REFERENCE}/ps.psp -o gpx -F ${TMPDIR}/psp1.gpx +${PNAME} -i psp -f ${REFERENCE}/ps.psp -o psp -F ${TMPDIR}/xxx.psp +${PNAME} -i psp -f ${TMPDIR}/xxx.psp -o gpx -F ${TMPDIR}/psp2.gpx +compare ${TMPDIR}/psp1.gpx ${TMPDIR}/psp2.gpx + +# MXF (Maptech Exchange Format) file format +rm -f ${TMPDIR}/mx.mxf ${TMPDIR}/mxf.mxf +${PNAME} -i mxf -f ${REFERENCE}/mxf.mxf -o mxf -F ${TMPDIR}/mx.mxf +${PNAME} -i mxf -f ${TMPDIR}/mx.mxf -o mxf -F ${TMPDIR}/mxf.mxf +compare ${TMPDIR}/mxf.mxf ${REFERENCE} + +# tmpro (TopoMapPro Places) file format +rm -f ${TMPDIR}/topomappro.txt ${TMPDIR}/mxf.mxf +${PNAME} -i tmpro -f ${REFERENCE}/topomappro.txt -o tmpro -F ${TMPDIR}/tmp.txt +${PNAME} -i tmpro -f ${TMPDIR}/tmp.txt -o tmpro -F ${TMPDIR}/topomappro.txt +compare ${TMPDIR}/topomappro.txt ${REFERENCE} + +# TPG (NG Topo!) file format +# This is hard to test as the datum conversions create minute +# inconsistencies in the coordinates. So.. we test our i/o +# against a format that rounds higher than we care to compare +# for binary data. +rm -f ${TMPDIR}/topo.mxf ${TMPDIR}/tpg.mxf ${TMPDIR}/geo.tpg +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o tpg -F ${TMPDIR}/geo.tpg +${PNAME} -i tpg -f ${TMPDIR}/geo.tpg -o mxf -F ${TMPDIR}/tpg.mxf +${PNAME} -i tpg -f ${REFERENCE}/tpg.tpg -o mxf -F ${TMPDIR}/topo.mxf +compare ${TMPDIR}/tpg.mxf ${TMPDIR}/topo.mxf + +# TPO (NG Topo!) file format +# This is hard to test as the datum conversions create minute +# inconsistencies in the coordinates. We have four reference files: +# tpo-sample1.tpo, tpo-sample1.gpx, tpo-sample2.gpx, and +# tpo-sample2.tpo. These are used to check the conversion to/from +# TPO format. +# +# Version 2.x tests +rm -f ${TMPDIR}/tpo-sample1.gpx ${TMPDIR}/tpo-sample2.tpo +${PNAME} -t -i tpo2 -f reference/track/tpo-sample1.tpo -o gpx -F ${TMPDIR}/tpo-sample1.gpx +compare ${TMPDIR}/tpo-sample1.gpx reference/track/tpo-sample1.gpx +#${PNAME} -t -i gpx -f reference/track/tpo-sample2.gpx -o tpo2 -F ${TMPDIR}/tpo-sample2.tpo +#bincompare ${TMPDIR}/tpo-sample2.tpo reference/track/tpo-sample2.tpo +# +# Version 3.x tests. Remove the timestamp from the generated file +# so that the compare will succeed. +rm -f ${TMPDIR}/tpo-sample3.gpx ${TMPDIR}/tpo-sample3.gpx2 +${PNAME} -t -r -w -i tpo3 -f reference/tpo-sample3.tpo -o gpx -F ${TMPDIR}/tpo-sample3.gpx +# Remove the timestamp +grep -v time <${TMPDIR}/tpo-sample3.gpx >${TMPDIR}/tpo-sample3.gpx2 +compare ${TMPDIR}/tpo-sample3.gpx2 reference/tpo-sample3.gpx + +# OZI (OziExplorer 1.1) file format +rm -f ${TMPDIR}/oz.wpt ${TMPDIR}/ozi.wpt +${PNAME} -i ozi -f ${REFERENCE}/ozi.wpt -o ozi -F ${TMPDIR}/oz.wpt +${PNAME} -i ozi -f ${TMPDIR}/oz.wpt -o ozi -F ${TMPDIR}/ozi.wpt +compare ${TMPDIR}/ozi.wpt ${REFERENCE} + +# Holux support is a little funky to test. Becuase it loses precision, +# if we convert it to another format, we lose accuracy (rounding) in the +# coords, so converting it so something else and comparing it never works. +# So we verify that we can read the reference and write it and get an +# identical reference. +${PNAME} -i holux -f ${REFERENCE}/paris.wpo -o holux -F ${TMPDIR}/paris.wpo +# compare ${REFERENCE}/paris.wpo ${TMPDIR}/paris.wpo + +# Magellan NAV Companion for PalmOS +# This format is hard to test, because each record and the database itself +# contains the time of creation, so two otherwise identical files won't +# compare accurately. In any case, the files are binary so compare wouldn't +# like them. So, we convert the reference file to gpsutil and the converted +# file to gpsutil and make sure they're the same, and that they're the same +# as one converted on a known-working installation. Unfortunately, this does +# not verify that the appinfo block was written correctly. However, it does +# successfully test for some endianness errors that might otherwise go +# unnoticed. +rm -f ${TMPDIR}/magnav.pdb ${TMPDIR}/magnav.gpu ${TMPDIR}/magnavt.gpu +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o magnav -F ${TMPDIR}/magnav.pdb +${PNAME} -i magnav -f ${TMPDIR}/magnav.pdb -o gpsutil -F ${TMPDIR}/magnav.gpu +${PNAME} -i magnav -f ${REFERENCE}/magnav.pdb -o gpsutil -F ${TMPDIR}/magnavt.gpu +compare ${TMPDIR}/magnavt.gpu ${TMPDIR}/magnav.gpu +compare ${REFERENCE}/gu.wpt ${TMPDIR}/magnav.gpu + +rm -f ${TMPDIR}/magnav.pdb +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o magnav -F ${TMPDIR}/magnav.pdb +bincompare ${TMPDIR}/magnav.pdb ${REFERENCE}/magnav.pdb + + + +# GPSPilot Tracker for PalmOS +# This test is eerily similar to the NAV Companion test. In fact, the +# converted reference file (magnavr.gpu) is identical. +rm -f ${TMPDIR}/gpspilot.pdb ${TMPDIR}/gpspilot.gpu ${TMPDIR}/gpspil_t.gpu +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpspilot -F ${TMPDIR}/gpspilot.pdb +${PNAME} -i gpspilot -f ${TMPDIR}/gpspilot.pdb -o gpsutil -F ${TMPDIR}/gpspilot.gpu +${PNAME} -i gpspilot -f ${REFERENCE}/gpspilot.pdb -o gpsutil -F ${TMPDIR}/gpspil_t.gpu +compare ${TMPDIR}/gpspil_t.gpu ${TMPDIR}/gpspilot.gpu +compare ${REFERENCE}/gu.wpt ${TMPDIR}/gpspilot.gpu + +# Cetus GPS for PalmOS +# This test is also similar to the NAV Companion test. +rm -f ${TMPDIR}/cetus.pdb ${TMPDIR}/cetus.gpu ${TMPDIR}/cetust.gpu +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o cetus -F ${TMPDIR}/cetus.pdb +${PNAME} -i cetus -f ${TMPDIR}/cetus.pdb -o gpsutil -F ${TMPDIR}/cetus.gpu +${PNAME} -i cetus -f ${REFERENCE}/cetus.pdb -o gpsutil -F ${TMPDIR}/cetust.gpu +compare ${TMPDIR}/cetust.gpu ${TMPDIR}/cetus.gpu +compare ${REFERENCE}/cetus.gpu ${TMPDIR}/cetus.gpu + +# QuoVadis GPS for PalmOS +# This test is derived from the Cetus test above. +rm -f ${TMPDIR}/quovadis.pdb ${TMPDIR}/quovadis.gpu ${TMPDIR}/quovadist.gpu +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o quovadis -F ${TMPDIR}/quovadis.pdb +${PNAME} -i quovadis -f ${TMPDIR}/quovadis.pdb -o gpsutil -F ${TMPDIR}/quovadis.gpu +${PNAME} -i quovadis -f ${REFERENCE}/quovadis.pdb -o gpsutil -F ${TMPDIR}/quovadist.gpu +compare ${TMPDIR}/quovadist.gpu ${TMPDIR}/quovadis.gpu +compare ${REFERENCE}/quovadis.gpu ${TMPDIR}/quovadis.gpu + +# GpsDrive +rm -f ${TMPDIR}/gpsdrive.txt +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpsdrive -F ${TMPDIR}/gpsdrive.txt +compare ${TMPDIR}/gpsdrive.txt ${REFERENCE} +${PNAME} -i gpsdrive -f ${REFERENCE}/gpsdrive.txt -o gpsdrive -F ${TMPDIR}/gpsdrive2.txt +compare ${TMPDIR}/gpsdrive2.txt ${REFERENCE}/gpsdrive.txt + +# XMapHH Street Atlas USA file format +rm -f ${TMPDIR}/xmapwpt.wpt ${TMPDIR}/xmapwpt.xmapwpt +${PNAME} -i xmapwpt -f ${REFERENCE}/xmapwpt.wpt -o xmapwpt -F ${TMPDIR}/xmapwpt.xmapwpt +${PNAME} -i xmapwpt -f ${TMPDIR}/xmapwpt.xmapwpt -o xmapwpt -F ${TMPDIR}/xmapwpt.wpt +compare ${TMPDIR}/xmapwpt.wpt ${REFERENCE} + +# XCSV +# Test that we can parse a style file, and read and write data in the +# same xcsv format (a complete test is virtually impossible). +echo "RECORD_DELIMITER NEWLINE" > ${TMPDIR}/testo.style +echo "FIELD_DELIMITER COMMA" >> ${TMPDIR}/testo.style +echo "BADCHARS COMMA" >> ${TMPDIR}/testo.style +echo "PROLOGUE Header" >> ${TMPDIR}/testo.style +echo "EPILOGUE Footer" >> ${TMPDIR}/testo.style +echo "IFIELD SHORTNAME,,%s" >> ${TMPDIR}/testo.style +echo "IFIELD LAT_DIRDECIMAL,,%c%lf" >> ${TMPDIR}/testo.style +echo "IFIELD LON_DECIMALDIR,,%lf%c" >> ${TMPDIR}/testo.style +rm -f ${TMPDIR}/xcsv.geo ${TMPDIR}/xcsv.xcsv +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o xcsv,style=${TMPDIR}/testo.style -F ${TMPDIR}/xcsv.geo +${PNAME} -i xcsv,style=${TMPDIR}/testo.style -f ${TMPDIR}/xcsv.geo -o xcsv,style=${TMPDIR}/testo.style -F ${TMPDIR}/xcsv.xcsv +compare ${TMPDIR}/xcsv.geo ${TMPDIR}/xcsv.xcsv + +# Garmin Mapsource This is a binary format with some undocumented +# fields. This test is therefore intentionally vague. We read a file, +# convert it to GPX, then write a file as MPS, then read it back and +# write it as GPX and compare them. Since we're writing both GPX files +# ourselves from the same version, we're immune to changes in our own +# GPX output. + +rm -fr ${TMPDIR}/ms.gpx ${TMPDIR}/ms[12].gpx +${PNAME} -i mapsource -f ${REFERENCE}/mapsource.mps -o gpx -F ${TMPDIR}/ms1.gpx +${PNAME} -i mapsource -f ${REFERENCE}/mapsource.mps -o mapsource -F ${TMPDIR}/ms.mps +${PNAME} -i mapsource -f ${TMPDIR}/ms.mps -o gpx -F ${TMPDIR}/ms2.gpx +compare ${TMPDIR}/ms1.gpx ${TMPDIR}/ms2.gpx + +# +# MRCB mapsource track test +# +rm -f ${TMPDIR}/mps-track.mps +${PNAME} -t -i mapsource -f ${REFERENCE}/track/mps-track.mps -o mapsource,mpsverout=3 \ + -F ${TMPDIR}/mps-track.mps +compare ${TMPDIR}/mps-track.mps ${REFERENCE}/track + +# Now do a test of reading waypoints from a track-only file - should have an empty result +rm -f ${TMPDIR}/mps-track.mps +${PNAME} -i mapsource -f ${REFERENCE}/track/mps-track.mps -o mapsource,mpsverout=3 \ + -F ${TMPDIR}/mps-track.mps +compare ${TMPDIR}/mps-track.mps ${REFERENCE}/mps-empty.mps + +# +# MRCB mapsource route test +# +rm -f ${TMPDIR}/mps-route.mps +${PNAME} -r -i mapsource -f ${REFERENCE}/route/route.mps -o mapsource,mpsverout=4 \ + -F ${TMPDIR}/mps-route.mps +compare ${TMPDIR}/mps-route.mps ${REFERENCE}/route/route.mps + +# Now do a test of reading tracks from a route-only file - should have an empty result +rm -f ${TMPDIR}/mps-route.mps +${PNAME} -t -i mapsource -f ${REFERENCE}/route/route.mps -o mapsource,mpsverout=3 \ + -F ${TMPDIR}/mps-route.mps +compare ${TMPDIR}/mps-route.mps ${REFERENCE}/mps-empty.mps + +# +# Geocaching Database is a binary Palm format that, like the GPX variants +# has a zillion "equivalent" encodings of any given record set. So we +# read the reference file, spin it to GPX and back to GCDB and then spin +# that one to GPX. +# + +${PNAME} -i gcdb -f ${REFERENCE}/GeocachingDB.PDB -o gpx -F ${TMPDIR}/gcdb1.gpx \ + -o gcdb -F ${TMPDIR}/gcdb1.pdb +${PNAME} -i gpx -f ${TMPDIR}/gcdb1.gpx -o gpx -F ${TMPDIR}/gcdb2.gpx +compare ${TMPDIR}/gcdb1.gpx ${TMPDIR}/gcdb1.gpx + +# +# Duplicate filter - Since filters have no format of their own, we use csv +# as an intermediate format for testing the filter. +# +rm -f ${TMPDIR}/filterdupe.csv1 ${TMPDIR}/filterdupe.csv2 +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o csv -F ${TMPDIR}/filterdupe.csv1 +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -f ${REFERENCE}/../geocaching.loc -x duplicate,shortname \ + -o csv -F ${TMPDIR}/filterdupe.csv2 +sort_and_compare ${TMPDIR}/filterdupe.csv1 ${TMPDIR}/filterdupe.csv2 + +# +# Position filter - Since very small distances are essentialy a duplicate +# position filter, we can test very similarly to the duplicate filter. +# +rm -f ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2 +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o csv -F ${TMPDIR}/filterpos.csv1 +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -f ${REFERENCE}/../geocaching.loc -x position,distance=5f \ + -o csv -F ${TMPDIR}/filterpos.csv2 +sort_and_compare ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2 + +# +# Radius filter +# +rm -f ${TMPDIR}/radius.csv +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc \ + -x radius,lat=35.9720,lon=-87.1347,distance=14.7 \ + -o csv -F ${TMPDIR}/radius.csv +compare ${TMPDIR}/radius.csv ${REFERENCE} + +# +# magellan SD card waypoint / route format +# +rm -f ${TMPDIR}/magellan.rte +${PNAME} -r -i magellan -f ${REFERENCE}/route/magellan.rte -o magellan \ + -F ${TMPDIR}/magellan.rte +compare ${TMPDIR}/magellan.rte ${REFERENCE}/route/magellan.rte + + +# +# GPX routes -- since GPX contains a date stamp, tests will always +# fail, so we use magellan as an interim format... +# +rm -f ${TMPDIR}/gpxroute.gpx ${TMPDIR}/maggpx.rte +${PNAME} -r -i gpx -f ${REFERENCE}/route/route.gpx -o gpx \ + -F ${TMPDIR}/gpxroute.gpx +${PNAME} -r -i gpx -f ${TMPDIR}/gpxroute.gpx -o magellan \ + -F ${TMPDIR}/maggpx.rte +compare ${TMPDIR}/maggpx.rte ${REFERENCE}/route/magellan.rte + +# +# GPX tracks -- since GPX contains a date stamp, tests will always +# fail, so we use magellan as an interim format... +# +rm -f ${TMPDIR}/gpxtrack.gpx ${TMPDIR}/maggpx.trk +${PNAME} -t -i gpx -f ${REFERENCE}/track/tracks.gpx -o gpx \ + -F ${TMPDIR}/gpxtrack.gpx +${PNAME} -t -i magellan -f ${REFERENCE}/track/meridian.trk -o gpx \ + -F ${TMPDIR}/maggpx.trk +compare ${TMPDIR}/maggpx.trk ${TMPDIR}/gpxtrack.gpx + +# +# MAPSEND waypoint / route format +# +rm -f ${TMPDIR}/route.mapsend +${PNAME} -r -i mapsend -f ${REFERENCE}/route/route.mapsend -o mapsend \ + -F ${TMPDIR}/route.mapsend +bincompare ${TMPDIR}/route.mapsend ${REFERENCE}/route/route.mapsend + +# +# MAPSEND track format +# +rm -f ${TMPDIR}/mapsend.trk +${PNAME} -t -i mapsend -f ${REFERENCE}/track/mapsend.trk -o mapsend,trkver=3 \ + -F ${TMPDIR}/mapsend.trk +compare ${TMPDIR}/mapsend.trk ${REFERENCE}/track/ + +# +# copilot +# +rm -f ${TMPDIR}/copilot.pdb +${PNAME} -i copilot -f ${REFERENCE}/UKultralight.pdb -o copilot -F ${TMPDIR}/cop.pdb +${PNAME} -i copilot -f ${REFERENCE}/UKultralight.pdb -o gpx -F ${TMPDIR}/cop1.gpx +${PNAME} -i copilot -f ${TMPDIR}/cop.pdb -o gpx -F ${TMPDIR}/cop2.gpx +compare ${TMPDIR}/cop1.gpx ${TMPDIR}/cop2.gpx + +# +# EasyGPS. Another binary format. +# +rm -f ${TMPDIR}/easy.loc +${PNAME} -i easygps -f ${REFERENCE}/easygps.loc -o easygps -F ${TMPDIR}/ez.loc +${PNAME} -i easygps -f ${REFERENCE}/easygps.loc -o gpx -F ${TMPDIR}/ez1.gpx +${PNAME} -i easygps -f ${TMPDIR}/ez.loc -o gpx -F ${TMPDIR}/ez2.gpx +compare ${TMPDIR}/ez1.gpx ${TMPDIR}/ez2.gpx + +# +# GPilotS. A Palm format. Another binary format that +# +# rm -f ${TMPDIR/gpilots.l +#${PNAME} -i easygps -f ${REFERENCE}/gpilots.pdb -o gpx -F ${TMPDIR}/gp.gpx +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpilots -F ${TMPDIR}/blah.pdb +${PNAME} -i gpilots -f ${TMPDIR}/blah.pdb -o gpx -F ${TMPDIR}/1.gpx +${PNAME} -i gpilots -f ${REFERENCE}/gpilots.pdb -o gpx -F ${TMPDIR}/2.gpx +compare ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx +#${PNAME} -i easygps -f ${REFERENCE}/gpilots.pdb -o gpx -F ${TMPDIR}/gp.gpx + +# +# Navicache. +${PNAME} -i navicache -f ${REFERENCE}/navicache.xml -o gpsutil -F ${TMPDIR}/navi.wpt +compare ${TMPDIR}/navi.wpt ${REFERENCE}/navicache.ref +# + +# +# CoastalExplorer.. +${PNAME} -r -i coastexp -f ${REFERENCE}/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx +compare ${TMPDIR}/coastexp.gpx ${REFERENCE}/coastexp.ref +${PNAME} -r -i gpx -f ${TMPDIR}/coastexp.gpx -o coastexp -F ${TMPDIR}/coastexp.nob +compare ${TMPDIR}/coastexp.nob ${REFERENCE}/coastexp.ref2 +${PNAME} -w -i coastexp -f ${REFERENCE}/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx +compare ${TMPDIR}/coastexp.gpx ${REFERENCE}/coastexp.ref3 +${PNAME} -w -i gpx -f ${TMPDIR}/coastexp.gpx -o coastexp -F ${TMPDIR}/coastexp.nob +compare ${TMPDIR}/coastexp.nob ${REFERENCE}/coastexp.ref4 +# + +# PsiTrex. A text format that can't be handled by XCSV due to context of +# data based on other data values in the file +# Waypoints first +rm -f ${TMPDIR}/psit-ww.txt ${TMPDIR}/psit-ww.mps +${PNAME} -i psitrex -f ${REFERENCE}/psitwpts.txt -o mapsource -F ${TMPDIR}/psit-ww.mps +${PNAME} -i mapsource -f ${TMPDIR}/psit-ww.mps -o psitrex -F ${TMPDIR}/psit-ww.txt +compare ${REFERENCE}/psitwpts.txt ${TMPDIR}/psit-ww.txt + +# Now test correct "empty" handling - ask for routes when there aren't any +# Uses mapsource as the empty handling for this has already happened above +rm -f ${TMPDIR}/psit-wr.mps +${PNAME} -r -i psitrex -f ${REFERENCE}/psitwpts.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-wr.mps +compare ${REFERENCE}/mps-empty.mps ${TMPDIR}/psit-wr.mps + +# Routes next +rm -f ${TMPDIR}/psit-rr.txt ${TMPDIR}/psit-rr.mps +${PNAME} -r -i psitrex -f ${REFERENCE}/route/psitrtes.txt -o mapsource -F ${TMPDIR}/psit-rr.mps +${PNAME} -r -i mapsource -f ${TMPDIR}/psit-rr.mps -o psitrex -F ${TMPDIR}/psit-rr.txt +compare ${REFERENCE}/route/psitrtes.txt ${TMPDIR}/psit-rr.txt + +# Now test correct "empty" handling - ask for tracks when there aren't any +# Uses mapsource as the empty handling for this has already happened above +rm -f ${TMPDIR}/psit-rt.mps +${PNAME} -t -i psitrex -f ${REFERENCE}/route/psitrtes.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-rt.mps +compare ${REFERENCE}/mps-empty.mps ${TMPDIR}/psit-rt.mps + +# Tracks last +rm -f ${TMPDIR}/psit-tt.txt ${TMPDIR}/psit-tt.mps +${PNAME} -t -i psitrex -f ${REFERENCE}/track/psittrks.txt -o mapsource -F ${TMPDIR}/psit-tt.mps +${PNAME} -t -i mapsource -f ${TMPDIR}/psit-tt.mps -o psitrex -F ${TMPDIR}/psit-tt.txt +compare ${REFERENCE}/track/psittrks.txt ${TMPDIR}/psit-tt.txt + +# Now test correct "empty" handling - ask for waypoints when there aren't any +# Uses mapsource as the empty handling for this has already happened above +rm -f ${TMPDIR}/psit-tw.mps +${PNAME} -i psitrex -f ${REFERENCE}/track/psittrks.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-tw.mps +compare ${REFERENCE}/mps-empty.mps ${TMPDIR}/psit-tw.mps + +# +# Arc Distance filter +# +rm -f ${TMPDIR}/arcdist.txt +${PNAME} -i xmap -f ${REFERENCE}/arcdist_input.txt \ + -x arc,file=${REFERENCE}/arcdist_arc.txt,distance=1 \ + -o xmap -F ${TMPDIR}/arcdist.txt +compare ${TMPDIR}/arcdist.txt ${REFERENCE}/arcdist_output.txt + +# +# Polygon filter +# +rm -f ${TMPDIR}/polygon.txt +${PNAME} -i xmap -f ${REFERENCE}/arcdist_input.txt \ + -x polygon,file=${REFERENCE}/polygon_allencty.txt \ + -o xmap -F ${TMPDIR}/polygon.txt +compare ${TMPDIR}/polygon.txt ${REFERENCE}/polygon_output.txt + +# +# Simplify filter +# +rm -f ${TMPDIR}/simplify.txt +${PNAME} -r -i gpx -f ${REFERENCE}/route/route.gpx \ + -x simplify,count=10 \ + -o arc -F ${TMPDIR}/simplify.txt +compare ${TMPDIR}/simplify.txt ${REFERENCE}/simplify_output.txt + +# +# Route reversal filter. Do it twice and be sure we get what we +# started with. +# +rm -f ${TMPDIR}/reverse1.arc ${TMPDIR}/reverse2.arc ${TMPDIR}/reference.arc +${PNAME} -r -i gpx -f ${REFERENCE}/route/route.gpx \ + -o arc -F ${TMPDIR}/reference.arc +${PNAME} -r -i gpx -f ${REFERENCE}/route/route.gpx \ + -x reverse \ + -o arc -F ${TMPDIR}/reverse1.arc +${PNAME} -r -i gpx -f ${REFERENCE}/route/route.gpx \ + -x reverse \ + -x reverse \ + -o arc -F ${TMPDIR}/reverse2.arc +# Verify the first and last are the same +compare ${TMPDIR}/reference.arc ${TMPDIR}/reverse2.arc +# Verify the first and second are different. +#${DIFF} ${TMPDIR}/reverse1.arc ${TMPDIR}/reverse2.arc > /dev/null && { +# echo ERROR Failed reversal test. +# exit 1 +#} + +# parkrrrr: This isn't a straightforward compare; we *want* it to fail. +# Obviously this test should just be rewritten with a new reference. +#compare ${TMPDIR}/reverse1.arc ${TMPDIR}/reverse2.arc + +# +# Geoniche: No reference file was available, so we created one and just +# test it against itself. +# +rm -f ${TMPDIR}/gn.pdb ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx +${PNAME} -i geoniche -f ${REFERENCE}/geoniche.pdb -o geoniche -F ${TMPDIR}/gn.pdb +${PNAME} -i geoniche -f ${REFERENCE}/geoniche.pdb -o gpx -F ${TMPDIR}/1.gpx +${PNAME} -i geoniche -f ${TMPDIR}/gn.pdb -o gpx -F ${TMPDIR}/2.gpx +compare ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx +# +${PNAME} -i geoniche -f ${REFERENCE}/gn-targets.pdb -o gpx -F ${TMPDIR}/gn-targets.gpx +compare ${TMPDIR}/gn-targets.gpx ${REFERENCE}/gn-targets.gpx + +# +# saroute covers *.anr, *.rte, and *.rtd, but I only have an .anr for testing. +# Unfortunately for us, this is a read-only format for now. +# +${PNAME} -t -i saroute -f ${REFERENCE}/track/i65.anr -o gpx -F ${TMPDIR}/gpl1.gpx +${PNAME} -t -i gpx -f ${REFERENCE}/track/i65.anr.gpx -o gpx -F ${TMPDIR}/gpl2.gpx +compare ${TMPDIR}/gpl1.gpx ${TMPDIR}/gpl2.gpx + +# +# Delorme GPL file. This is sort of a track format. +# +rm -f ${TMPDIR}/gpl1.gpx ${TMPDIR}/gpl2.gpx ${TMPDIR}/gpl1.gpl +${PNAME} -t -i gpl -f ${REFERENCE}/track/webpark1.gpl -o gpx -F ${TMPDIR}/gpl1.gpx +${PNAME} -t -i gpl -f ${REFERENCE}/track/webpark1.gpl -o gpl -F ${TMPDIR}/gpl1.gpl +${PNAME} -t -i gpl -f ${TMPDIR}/gpl1.gpl -o gpx -F ${TMPDIR}/gpl2.gpx +compare ${TMPDIR}/gpl1.gpx ${TMPDIR}/gpl2.gpx + +# +# NetStumbler Summary File (read-only) +# +rm -f ${TMPDIR}/netstumbler.mps +${PNAME} -i netstumbler -f ${REFERENCE}/netstumbler.txt -o mapsource -F ${TMPDIR}/netstumbler.mps +bincompare ${TMPDIR}/netstumbler.mps ${REFERENCE}/netstumbler.mps + +# +# IGC tests +# +rm -f ${TMPDIR}/igc*out +${PNAME} -i gpx -f ${REFERENCE}/igc1.gpx -o igc -F ${TMPDIR}/igc.out +sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed.out +compare ${TMPDIR}/igc_sed.out ${REFERENCE}/igc1_igc.out + +${PNAME} -i igc -f ${TMPDIR}/igc.out -o gpx -F ${TMPDIR}/igc.gpx +compare ${TMPDIR}/igc.gpx ${REFERENCE}/igc1_gpx.out + +${PNAME} -i gpx -f ${TMPDIR}/igc.gpx -o igc -F ${TMPDIR}/igc.out +sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed.out +compare ${TMPDIR}/igc_sed.out ${REFERENCE}/igc1_igc.out + +${PNAME} -i gpx -f ${REFERENCE}/igc1_baro.gpx -i igc -f ${REFERENCE}/igc1_igc.out -o igc,timeadj=auto -F ${TMPDIR}/igc.out +sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed.out +compare ${TMPDIR}/igc_sed.out ${REFERENCE}/igc1_3d.out + + +${PNAME} -i igc -f ${REFERENCE}/igc2.igc -o gpx -F ${TMPDIR}/igc.gpx +compare ${TMPDIR}/igc.gpx ${REFERENCE}/igc2_gpx.out + +${PNAME} -i gpx -f ${TMPDIR}/igc.gpx -o igc -F ${TMPDIR}/igc.out +sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed.out +compare ${TMPDIR}/igc_sed.out ${REFERENCE}/igc2_igc.out + +${PNAME} -i igc -f ${TMPDIR}/igc.out -o gpx -F ${TMPDIR}/igc.gpx +compare ${TMPDIR}/igc.gpx ${REFERENCE}/igc2_gpx.out + +# +# Google Maps XML test +# +rm -f ${TMPDIR}/google.out +${PNAME} -i google -f ${REFERENCE}/google.xml -o csv -F ${TMPDIR}/google.out +compare ${TMPDIR}/google.out ${REFERENCE}/google.csv + +rm -f ${TMPDIR}/google.out +${PNAME} -i google -f ${REFERENCE}/google.js -o csv -F ${TMPDIR}/google.out +compare ${TMPDIR}/google.out ${REFERENCE}/google.csv + +rm -f ${TMPDIR}/google.out +${PNAME} -i google -f ${REFERENCE}/google_jan_06.html -o csv -F ${TMPDIR}/google.out +compare ${TMPDIR}/google.out ${REFERENCE}/google_jan_06.csv + +# +# DeLorme .an1 tests +# +rm -f ${TMPDIR}/an1.out +${PNAME} -i an1 -f ${REFERENCE}/foo.an1 -o csv -F ${TMPDIR}/an1.out +compare ${TMPDIR}/an1.out ${REFERENCE}/an1-in.ref + +rm -f ${TMPDIR}/an1.out +${PNAME} -i an1 -f ${REFERENCE}/foo.an1 -o an1 -F ${TMPDIR}/an1.out +bincompare ${TMPDIR}/an1.out ${REFERENCE}/an1-an1.ref + +rm -f ${TMPDIR}/an1.out +${PNAME} -i xmap -f ${REFERENCE}/xmap -o an1 -F ${TMPDIR}/an1.out +bincompare ${TMPDIR}/an1.out ${REFERENCE}/an1-out.ref + +rm -f ${TMPDIR}/an1.out +${PNAME} -i google -f ${REFERENCE}/google.js -o an1 -F ${TMPDIR}/an1.out +bincompare ${TMPDIR}/an1.out ${REFERENCE}/an1-line-out.ref + +# +# TomTom .ov2 tests +# + +rm -f ${TMPDIR}/ov2.out +${PNAME} -i arc -f ${REFERENCE}/google.arc -o tomtom -F ${TMPDIR}/ov2.out +compare ${TMPDIR}/ov2.out ${REFERENCE}/ov2-arc-out.ref + +rm -f ${TMPDIR}/ov2.out +${PNAME} -i geo -f ${REFERENCE}/gl.loc -o tomtom -F ${TMPDIR}/ov2.out +compare ${TMPDIR}/ov2.out ${REFERENCE}/ov2-geo-out.ref + +rm -f ${TMPDIR}/ov2.out +${PNAME} -i tomtom -f ${REFERENCE}/ov2-geo-out.ref -o gpsutil -F ${TMPDIR}/ov2.out +compare ${TMPDIR}/ov2.out ${REFERENCE}/ov2-in.ref + +# +# XCSV "human readable" tests +# +rm -f ${TMPDIR}/humanread.out +${PNAME} -i xcsv,style=${REFERENCE}/humanread.style -f ${REFERENCE}/human.in -o arc -F ${TMPDIR}/humanread.out +compare ${TMPDIR}/humanread.out ${REFERENCE}/humanread.out + +rm -f ${TMPDIR}/humanwrite.out +${PNAME} -i xcsv,style=${REFERENCE}/humanread.style -f ${REFERENCE}/human.in -o xcsv,style=${REFERENCE}/humanwrite.style -F ${TMPDIR}/humanwrite.out +compare ${TMPDIR}/humanwrite.out ${REFERENCE}/humanwrite.out + +# +# XCSV "path distance" test +# +rm -f ${TMPDIR}/pathdist.out +${PNAME} -i magellan -f ${REFERENCE}/dusky.trk -o xcsv,style=${REFERENCE}/gnuplot.style -F ${TMPDIR}/pathdist.out +compare ${TMPDIR}/pathdist.out ${REFERENCE}/dusky.gnuplot + +# hsandv +rm -f ${TMPDIR}/hsandv.exp ${TMPDIR}/1.exp ${TMPDIR}/1.exp ${TMPDIR}/Glad_5.exp +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o hsandv -F ${TMPDIR}/hsandv.exp +compare ${TMPDIR}/hsandv.exp ${REFERENCE} +#the hsandv format is too lossy to do this test :( +#${PNAME} -i hsandv -f ${TMPDIR}/hsandv.exp -o geo -F ${TMPDIR}/1.exp +#${PNAME} -i hsandv -f ${REFERENCE}/hsandv.exp -o geo -F ${TMPDIR}/2.exp +#compare ${TMPDIR}/1.exp ${TMPDIR}/2.exp +#test conversion from v4 to v5 files +${PNAME} -i hsandv -f ${REFERENCE}/Glad_4.exp -o hsandv -F ${TMPDIR}/Glad_5.exp +# FIXME: Can't compare directly because of potential FP rounding. +# FIXME: compare ${TMPDIR}/Glad_5.exp reference + +# +# stack filter tests +# These don't actually test for proper behavior, for now, but they do +# exercise all of the currently-extant filter code. +# + +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -x stack,push,copy,nowarn -x stack,push,copy -x stack,push -x stack,pop,replace -x stack,pop,append -x stack,push,copy -x stack,pop,discard -x stack,swap,depth=1 -o arc -F ${TMPDIR}/stackfilt.txt + +# +# 'tabsep' isn't really tested in any non-trivial way, but we do exercise +# it. +# + +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o tabsep -F ${TMPDIR}/tabsep.in +${PNAME} -i tabsep -f ${TMPDIR}/tabsep.in -o geo -F ${TMPDIR}/tabsep.out +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o geo -F ${TMPDIR}/geotabsep.out +compare ${TMPDIR}/tabsep.out ${TMPDIR}/geotabsep.out + +# +# Now do the same for custom - it has the same issues. +# + +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o custom -F ${TMPDIR}/custom.in +${PNAME} -i custom -f ${TMPDIR}/custom.in -o geo -F ${TMPDIR}/custom.out +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o geo -F ${TMPDIR}/geocustom.out + +# +# Write something to the various output-only formats +# +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o text -F ${TMPDIR}/text.out -o html -F ${TMPDIR}/html.out -o vcard -F ${TMPDIR}/vcard.out #-o palmdoc -F ${TMPDIR}/pd.out + +# +# tef "TourExchangeFormat" read test +# +rm -f ${TMPDIR}/tef_xml* +${PNAME} -i tef -f ${REFERENCE}/route/tef_xml.sample.xml -o gpx -F ${TMPDIR}/tef_xml.sample.gpx +compare ${TMPDIR}/tef_xml.sample.gpx ${REFERENCE}/route/tef_xml.sample.gpx + +# +# PathAway Palm Database .pdb tests +# +rm -f ${TMPDIR}/pathaway* +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o pathaway,dbname="pathaway-geo" -F ${TMPDIR}/pathaway-geo.pdb +${PNAME} -i pathaway -f ${TMPDIR}/pathaway-geo.pdb -o geo -F ${TMPDIR}/pathaway-geo.loc +compare ${TMPDIR}/pathaway-geo.loc ${REFERENCE}/pathaway-geo.loc +rm -f ${TMPDIR}/pathaway* +${PNAME} -t -i pathaway -f ${REFERENCE}/track/pathaway.pdb -o gpx -F ${TMPDIR}/pathaway.gpx +compare ${TMPDIR}/pathaway.gpx ${REFERENCE}/track/pathaway.gpx + +# +# Garmin GPS Database .gdb tests +# +rm -f ${TMPDIR}/gdb-* +${PNAME} -i gdb,via -f ${REFERENCE}/gdb-sample.gdb -o gpx -F ${TMPDIR}/gdb-sample.gpx +compare ${REFERENCE}/gdb-sample.gpx ${TMPDIR}/gdb-sample.gpx +${PNAME} -i gpx -f ${REFERENCE}/gdb-sample.gpx -o gdb,ver=1 -F ${TMPDIR}/gdb-sample.gdb +${PNAME} -i gdb -f ${TMPDIR}/gdb-sample.gdb -o gpx -F ${TMPDIR}/gdb-sample.gpx +${PNAME} -i gdb,via -f ${REFERENCE}/gdb-sample-v3.gdb -o gpx -F ${TMPDIR}/gdb-sample_v3.gpx +compare ${REFERENCE}/gdb-sample.gpx ${TMPDIR}/gdb-sample_v3.gpx +# +# Because of Garmin coordinates storage gpx is not good for this test +# compare ${REFERENCE}/gdb-sample.gpx ${TMPDIR}/gdb-sample.gpx +# +# compare ${TMPDIR}/gdb-sample.gpx ${REFERENCE}/gdb-sample.gpx + +# +# Vito Navigator II .smt tests +# +rm -f ${TMPDIR}/vitosmt* +${PNAME} -i vitosmt -f ${REFERENCE}/vitosmt.smt -o gpx -F ${TMPDIR}/vitosmt.gpx +compare ${TMPDIR}/vitosmt.gpx ${REFERENCE}/vitosmt.gpx +${PNAME} -t -i vitosmt -f ${REFERENCE}/vitosmt.smt -o gpx -F ${TMPDIR}/vitosmt_t.gpx +compare ${TMPDIR}/vitosmt_t.gpx ${REFERENCE}/track/vitosmt_t.gpx + +# +# tracks filter tests +# + +rm -f ${TMPDIR}/trackfilter* + +${PNAME} -t -i gpx -f ${REFERENCE}/track/trackfilter.gpx -x track,pack,split,title="LOG-%Y%m%d" -o gpx -F ${TMPDIR}/trackfilter.gpx +compare ${TMPDIR}/trackfilter.gpx ${REFERENCE}/track/trackfilter.gpx + +${PNAME} -t -i gpx -f ${REFERENCE}/track/trackfilter.gpx -x track,pack,split,sdistance=0.1k -o gpx -F ${TMPDIR}/trackfilter2.gpx +compare ${TMPDIR}/trackfilter2.gpx ${REFERENCE}/track/trackfilter-sdistance.gpx + +${PNAME} -t -i gpx -f ${REFERENCE}/track/trackfilter.gpx -x track,pack,sdistance=0.1k,split=5m,title=%Y%m%d -o gpx -F ${TMPDIR}/trackfilter-sdistance2.gpx +compare ${TMPDIR}/trackfilter-sdistance2.gpx ${REFERENCE}/track/trackfilter-sdistance2.gpx + +# +# Map&Guide Motorrad Routenplaner .bcr files test +# +rm -f ${TMPDIR}/bcr* +${PNAME} -r -i bcr -f ${REFERENCE}/route/bcr-sample.bcr -o gpx -F ${TMPDIR}/bcr-sample.gpx +compare ${TMPDIR}/bcr-sample.gpx ${REFERENCE}/route/bcr-sample.gpx +${PNAME} -r -i gpx -f ${REFERENCE}/route/bcr-sample.gpx -o bcr -F ${TMPDIR}/bcr-sample2.bcr +compare ${REFERENCE}/route/bcr-sample2.bcr ${TMPDIR}/bcr-sample2.bcr +${PNAME} -r -i bcr -f ${TMPDIR}/bcr-sample2.bcr -o gpx -F ${TMPDIR}/bcr-sample2.gpx +compare ${REFERENCE}/route/bcr-sample.gpx ${TMPDIR}/bcr-sample2.gpx + +# +# cet - Character encoding transformation tests +# +rm -f ${TMPDIR}/cet-sample* +${PNAME} -w -i gdb -f ${REFERENCE}/cet/cet-sample.gdb -o gpx -F ${TMPDIR}/cet-sample.gpx +compare ${TMPDIR}/cet-sample.gpx ${REFERENCE}/cet/cet-sample.gpx +${PNAME} -w -i gpx -f ${TMPDIR}/cet-sample.gpx -o tmpro -c Latin1 -F ${TMPDIR}/cet-sample.latin1.txt +compare ${TMPDIR}/cet-sample.latin1.txt ${REFERENCE}/cet/cet-sample.latin1.txt +${PNAME} -w -i gdb -f ${REFERENCE}/cet/cet-sample.gdb -o tmpro -c Latin2 -F ${TMPDIR}/cet-sample.latin2.txt +compare ${TMPDIR}/cet-sample.latin2.txt ${REFERENCE}/cet/cet-sample.latin2.txt +${PNAME} -w -i gdb -f ${REFERENCE}/cet/cet-sample.gdb -o tmpro -c cp1250 -F ${TMPDIR}/cet-sample.cp1250.txt +compare ${TMPDIR}/cet-sample.cp1250.txt ${REFERENCE}/cet/cet-sample.cp1250.txt +${PNAME} -w -i gdb -f ${REFERENCE}/cet/cet-sample.gdb -o tmpro -c macroman -F ${TMPDIR}/cet-sample.macroman.txt +compare ${TMPDIR}/cet-sample.macroman.txt ${REFERENCE}/cet/cet-sample.macroman.txt + +# +# Garmin logbook. This format has an extra section (lap data with things +# like heartbeat and calories burned) that we don't know what to do with, +# so we convert it to gpx, convert it to itself, convert THAT to gpx, and +# compare those. +# +rm -f ${TMPDIR}/glogbook* +${PNAME} -i glogbook -f ${REFERENCE}/track/garmin_logbook.xml -o gpx -F ${TMPDIR}/glog1.gpx +${PNAME} -i glogbook -f ${REFERENCE}/track/garmin_logbook.xml -o glogbook -F ${TMPDIR}/glog.xml +${PNAME} -i glogbook -f ${TMPDIR}/glog.xml -o gpx -F ${TMPDIR}/glog2.gpx +compare ${TMPDIR}/glog1.gpx ${TMPDIR}/glog2.gpx + +# +# Dop filter test +# +rm -f ${TMPDIR}/dop* +sed '/50/d' ${REFERENCE}/dop-test.gpx | ${PNAME} -i gpx -f - -o openoffice -F - | sed 's/RPT...//g' > ${TMPDIR}/dop-hdop.ref +${PNAME} -i gpx -f ${REFERENCE}/dop-test.gpx -x discard,hdop=50 -o openoffice -F - | sed 's/RPT...//g' > ${TMPDIR}/dop-hdop.fil +compare ${TMPDIR}/dop-hdop.ref ${TMPDIR}/dop-hdop.fil +sed '/50/d' ${REFERENCE}/dop-test.gpx | ${PNAME} -i gpx -f - -o openoffice -F - | sed 's/RPT...//g' > ${TMPDIR}/dop-vdop.ref +${PNAME} -i gpx -f ${REFERENCE}/dop-test.gpx -x discard,vdop=50 -o openoffice -F - | sed 's/RPT...//g' > ${TMPDIR}/dop-vdop.fil +compare ${TMPDIR}/dop-vdop.ref ${TMPDIR}/dop-vdop.fil + +# +# cotoGPS tests +# +rm -f ${TMPDIR}/coto* +# Track reading +${PNAME} -i coto -f ${REFERENCE}/cototesttrack.pdb -o xcsv,style=${REFERENCE}/cototest.style -F ${TMPDIR}/cototrack.csv +compare ${REFERENCE}/cototesttrack.csv ${TMPDIR}/cototrack.csv +# Marker read +${PNAME} -i coto -f ${REFERENCE}/cototestmarker.pdb -o gpx -F ${TMPDIR}/cotomarker.gpx +compare ${REFERENCE}/cototestmarker.gpx ${TMPDIR}/cotomarker.gpx +# Marker write +${PNAME} -i gpx -f ${REFERENCE}/cototestmarker.gpx -o coto -F ${TMPDIR}/cotomarker.pdb +# bincompare ${REFERENCE}/cototestmarker.pdb ${TMPDIR}/cotomarker.pdb +${PNAME} -i coto -f ${TMPDIR}/cotomarker.pdb -o gpx -F ${TMPDIR}/cotomarker.gpx +compare ${REFERENCE}/cototestmarker.gpx ${TMPDIR}/cotomarker.gpx + +# +# Fugawi test cases +rm -f ${TMPDIR}/fugawi* +${PNAME} -i fugawi -f ${REFERENCE}/fugawi.notime.txt -o fugawi -F ${TMPDIR}/fugawi1.txt +compare ${REFERENCE}/fugawi.ref.txt ${TMPDIR}/fugawi1.txt +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o fugawi -F ${TMPDIR}/fugawi2.txt +compare ${REFERENCE}/fugawi.ref.txt ${TMPDIR}/fugawi2.txt +${PNAME} -i fugawi -f ${TMPDIR}/fugawi2.txt -o fugawi -F ${TMPDIR}/fugawi3.txt +compare ${TMPDIR}/fugawi2.txt ${TMPDIR}/fugawi3.txt +${PNAME} -i fugawi -f ${REFERENCE}/fugawi.time.txt -o fugawi -F ${TMPDIR}/fugawi4.txt +compare ${REFERENCE}/fugawi.time.ref.txt ${TMPDIR}/fugawi4.txt +${PNAME} -i gpx -f ${REFERENCE}/track/tracks.gpx -o fugawi -F ${TMPDIR}/fugawi5.txt +compare ${REFERENCE}/track/fugawi.txt ${TMPDIR}/fugawi5.txt + +# +# Magellan Explorist geocaching format (write-only). +# +${PNAME} -i gpx -f ${REFERENCE}/gc/GC7FA4.gpx -f ${REFERENCE}/gc/GCGCA8.gpx -o maggeo -F ${TMPDIR}/maggeo.gs +compare ${REFERENCE}/gc/maggeo.gs ${TMPDIR}/maggeo.gs + +# +# IGN Rando tests +# +${PNAME} -i ignrando -f ${REFERENCE}/track/ignrando-sample.rdn -o ignrando -F ${TMPDIR}/ignrando-sample.rdn +${PNAME} -i ignrando -f ${TMPDIR}/ignrando-sample.rdn -o gpx -F ${TMPDIR}/ignrando-sample.gpx +compare ${TMPDIR}/ignrando-sample.gpx ${REFERENCE}/track/ignrando-sample.gpx + +# +# STMwpp "Suunto Trek Manager" WaypointPlus format tests +# +rm -f ${TMPDIR}/stmwpp-* +${PNAME} -i stmwpp -f ${REFERENCE}/track/stmwpp-track.txt -o gpx -F ${TMPDIR}/stmwpp-track.gpx +compare ${TMPDIR}/stmwpp-track.gpx ${REFERENCE}/track/stmwpp-track.gpx +${PNAME} -i stmwpp -f ${REFERENCE}/route/stmwpp-route.txt -o gpx -F ${TMPDIR}/stmwpp-route.gpx +compare ${TMPDIR}/stmwpp-route.gpx ${REFERENCE}/route/stmwpp-route.gpx +${PNAME} -i stmwpp -f ${REFERENCE}/route/stmwpp-route.txt -o stmwpp -F ${TMPDIR}/stmwpp-route.txt +compare ${TMPDIR}/stmwpp-route.txt ${REFERENCE}/route/stmwpp-route.txt + +# +# Microsoft AutoRoute 2002 test (read-only) +# +${PNAME} -i msroute -f ${REFERENCE}/route/msroute-sample.axe -o gpx -F ${TMPDIR}/msroute-sample.gpx +compare ${TMPDIR}/msroute-sample.gpx ${REFERENCE}/route/msroute-sample.gpx + +# +# CarteSurTable read test +# +rm -f ${TMPDIR}/cst-* +${PNAME} -i cst -f ${REFERENCE}/route/cst-sample.cst -o gpx -F ${TMPDIR}/cst-sample.gpx +compare ${TMPDIR}/cst-sample.gpx ${REFERENCE}/route/cst-sample.gpx + +# +# Navigon Mobile Navigator .rte tests +# +rm -f ${TMPDIR}/nmn4-sample* +${PNAME} -i nmn4 -f ${REFERENCE}/route/nmn4-sample.rte -o gpx -F ${TMPDIR}/nmn4-sample.gpx +compare ${REFERENCE}/route/nmn4-sample.gpx ${TMPDIR}/nmn4-sample.gpx +${PNAME} -i gpx -f ${REFERENCE}/route/nmn4-sample.gpx -o nmn4 -F ${TMPDIR}/nmn4-sample-out.rte +compare ${REFERENCE}/route/nmn4-sample-out.rte ${TMPDIR}/nmn4-sample-out.rte + +# +# Map&Guide Palm/OS .pdb files (read-only) +# +rm -f ${TMPDIR}/mag_pdb-* +${PNAME} -i mag_pdb -f ${REFERENCE}/route/mag_pdb-sample.pdb -o gpx -F ${TMPDIR}/mag_pdb-sample.gpx +compare ${TMPDIR}/mag_pdb-sample.gpx ${REFERENCE}/route/mag_pdb-sample.gpx + +# +# CompeGPS I/O tests +# +rm -f ${TMPDIR}/compegps* +# read (CompeGPS) +${PNAME} -i compegps -f ${REFERENCE}/compegps.wpt -o gpx -F ${TMPDIR}/compegps-wpt.gpx +compare ${REFERENCE}/compegps-wpt.gpx ${TMPDIR}/compegps-wpt.gpx +${PNAME} -i compegps -f ${REFERENCE}/route/compegps.rte -o gpx -F ${TMPDIR}/compegps-rte.gpx +compare ${REFERENCE}/route/compegps-rte.gpx ${TMPDIR}/compegps-rte.gpx +${PNAME} -i compegps -f ${REFERENCE}/track/compegps.trk -o gpx -F ${TMPDIR}/compegps-trk.gpx +compare ${REFERENCE}/track/compegps-trk.gpx ${TMPDIR}/compegps-trk.gpx +# write (CompeGPS) +${PNAME} -i compegps -f ${REFERENCE}/compegps.wpt -o compegps -F ${TMPDIR}/compegps.wpt +${PNAME} -i compegps -f ${TMPDIR}/compegps.wpt -o gpx -F ${TMPDIR}/compegps-wpt2.gpx +compare ${REFERENCE}/compegps-wpt.gpx ${TMPDIR}/compegps-wpt2.gpx +${PNAME} -t -i compegps -f ${REFERENCE}/track/compegps.trk -o compegps -F ${TMPDIR}/compegps.trk +${PNAME} -i compegps -f ${TMPDIR}/compegps.trk -o gpx -F ${TMPDIR}/compegps-trk2.gpx +compare ${REFERENCE}/track/compegps-trk.gpx ${TMPDIR}/compegps-trk2.gpx +${PNAME} -r -i compegps -f ${REFERENCE}/route/compegps.rte -o compegps -F ${TMPDIR}/compegps.rte +${PNAME} -i compegps -f ${TMPDIR}/compegps.rte -o gpx -F ${TMPDIR}/compegps-rte2.gpx +compare ${REFERENCE}/route/compegps-rte.gpx ${TMPDIR}/compegps-rte2.gpx + +# +# Testing the 'nuketypes' filter is funky. +# Convert a GPX file to GPX to eliminate jitter. +# Then nuke the all but the three individual types, merge the result together +# and verify we got the original back. +# +${PNAME} -i gpx -f ${REFERENCE}/gdb-sample.gpx -o gpx -F ${TMPDIR}/alltypes.gpx +${PNAME} -i gpx -f ${TMPDIR}/alltypes.gpx -x nuketypes,tracks,routes -o gpx -F ${TMPDIR}/wpts.gpx +${PNAME} -i gpx -f ${TMPDIR}/alltypes.gpx -x nuketypes,waypoints,routes -o gpx -F ${TMPDIR}/trks.gpx +${PNAME} -i gpx -f ${TMPDIR}/alltypes.gpx -x nuketypes,waypoints,tracks -o gpx -F ${TMPDIR}/rtes.gpx +${PNAME} -i gpx -f ${TMPDIR}/wpts.gpx -f ${TMPDIR}/trks.gpx -f ${TMPDIR}/rtes.gpx -o gpx -F ${TMPDIR}/merged.gpx +compare ${TMPDIR}/alltypes.gpx ${TMPDIR}/merged.gpx + +# +# Interpolate filter +# + +${PNAME} -i gpx -f ${REFERENCE}/track/simpletrack.gpx -x interpolate,distance=50m -o gpx -F ${TMPDIR}/interp.gpx +compare ${REFERENCE}/track/interptrack.gpx ${TMPDIR}/interp.gpx +${PNAME} -i gpx -f ${REFERENCE}/track/simpletrack.gpx -x interpolate,time=1 -o gpx -F ${TMPDIR}/tinterp.gpx +compare ${REFERENCE}/track/tinterptrack.gpx ${TMPDIR}/tinterp.gpx + +# +# Universal CSV - unicsv +# +echo "lat,lon,descr,name,notes,unk,unk" > ${TMPDIR}/unicsv.txt +cat ${REFERENCE}/mxf.mxf >> ${TMPDIR}/unicsv.txt +${PNAME} -i unicsv -f ${TMPDIR}/unicsv.txt -o gpx -F ${TMPDIR}/unicsv.gpx +compare ${TMPDIR}/unicsv.gpx ${REFERENCE}/unicsv.gpx +${PNAME} -i garmin_txt -f ${REFERENCE}/garmin_txt.txt -x nuketypes,routes,tracks -o unicsv -F ${TMPDIR}/garmin_txt-uni.csv +compare ${TMPDIR}/garmin_txt-uni.csv ${REFERENCE}/garmin_txt-uni.csv + +# +# Basic NMEA tests +# +${PNAME} -i nmea -f ${REFERENCE}/track/nmea -o gpx -F ${TMPDIR}/nmea.gpx +compare ${TMPDIR}/nmea.gpx ${REFERENCE}/track/nmea.gpx +${PNAME} -i nmea -f ${REFERENCE}/track/nmea+ms.txt -o gpx -F ${TMPDIR}/nmea+ms.gpx +compare ${TMPDIR}/nmea+ms.gpx ${REFERENCE}/track/nmea+ms.gpx + +# +# Wfff. +# +${PNAME} -i wfff -f ${REFERENCE}/wfff.xml -o gpsutil -F ${TMPDIR}/wfff.gpu +compare ${TMPDIR}/wfff.gpu ${REFERENCE}/wfff.gpu + +# +# Garmin MapSource tab delimited text files - garmin_txt +# +rm -f ${TMPDIR}/garmin_txt* +# +# !!! garmin_txt timestamps are stored in localtime !!! +# +${PNAME} -i gdb -f ${REFERENCE}/gdb-sample2.gdb -o garmin_txt,utc,prec=9 -F ${TMPDIR}/garmin_txt.txt +compare ${REFERENCE}/garmin_txt.txt ${TMPDIR}/garmin_txt.txt +${PNAME} -i garmin_txt -f ${REFERENCE}/garmin_txt.txt -o garmin_txt,prec=9 -F ${TMPDIR}/garmin_txt-2.txt +${PNAME} -i garmin_txt -f ${TMPDIR}/garmin_txt-2.txt -o garmin_txt,prec=9 -F ${TMPDIR}/garmin_txt-3.txt +# +# test can fail because of localtime/gmtime differences +# +## compare ${TMPDIR}/garmin_txt-2.txt ${TMPDIR}/garmin_txt-3.txt + +# +# hiketech tests +# +rm -f ${TMPDIR}/hiketech* +${PNAME} -i gpx -f ${REFERENCE}/expertgps.gpx -o hiketech -F ${TMPDIR}/hiketech.out +compare ${TMPDIR}/hiketech.out ${REFERENCE}/hiketech.ref +${PNAME} -i hiketech -f ${REFERENCE}/hiketech.ref -o gpx -F ${TMPDIR}/hiketech.gpx +compare ${TMPDIR}/hiketech.gpx ${REFERENCE}/hiketech.gpx + +# +# Kartex waypoints and tracks +# +rm -f ${TMPDIR}/kartex* +${PNAME} -i kwf2 -f ${REFERENCE}/waypointsDd.kwf -o kwf2 -F ${TMPDIR}/kartex-1a.kwf +compare ${REFERENCE}/kartex-out.kwf ${TMPDIR}/kartex-1a.kwf +# ! different format of coords; this checks LATLON_HUMAN_READABLE ! +${PNAME} -i kwf2 -f ${REFERENCE}/waypointsDMm.kwf -o kwf2 -F ${TMPDIR}/kartex-1b.kwf +compare ${TMPDIR}/kartex-1a.kwf ${TMPDIR}/kartex-1b.kwf +# +${PNAME} -i ktf2 -f ${REFERENCE}/track/trackDd.ktf -o ktf2 -F ${TMPDIR}/kartex-2a.ktf +compare ${REFERENCE}/track/kartex-out.ktf ${TMPDIR}/kartex-2a.ktf +# ! different format of coords; this checks LATLON_HUMAN_READABLE ! +${PNAME} -i ktf2 -f ${REFERENCE}/track/trackDMm.ktf -o ktf2 -F ${TMPDIR}/kartex-2b.ktf +compare ${TMPDIR}/kartex-2a.ktf ${TMPDIR}/kartex-2b.ktf + +# +# Dell Axim Navigation System 'axim_gpb' test +# +rm -f ${TMPDIR}/axim-* +${PNAME} -i axim_gpb -f ${REFERENCE}/track/axim-sample.gpb -o gpx -F ${TMPDIR}/axim-sample.gpx +compare ${REFERENCE}/track/axim-sample.gpx ${TMPDIR}/axim-sample.gpx + +# +# Franson GPSGate simulation +# +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpssim -F ${TMPDIR}/waypoints.gpssim +compare ${TMPDIR}/waypoints.gpssim ${REFERENCE} +${PNAME} -i gpx -f ${REFERENCE}/track/tracks.gpx -o gpssim -F ${TMPDIR}/tracks.gpssim +compare ${TMPDIR}/tracks.gpssim ${REFERENCE}/track + +# +# WBT-200 tests +# +rm -f ${TMPDIR}/wbt-200.* +${PNAME} -i wbt-bin -f ${REFERENCE}/wbt-200.bin -o gpx -F ${TMPDIR}/wbt-200.gpx +# Remove the timestamp +grep -v time <${TMPDIR}/wbt-200.gpx >${TMPDIR}/wbt-200.gpx2 +compare ${TMPDIR}/wbt-200.gpx2 ${REFERENCE}/wbt-200.gpx + +# +# WBT-201 tests +# +rm -f ${TMPDIR}/wbt-200.* +${PNAME} -t -w -i wbt-bin -f ${REFERENCE}/wbt-201.tk1 -o gpx -F ${TMPDIR}/wbt-201.gpx +# Remove the timestamp +grep -v time <${TMPDIR}/wbt-201.gpx >${TMPDIR}/wbt-201.gpx2 +compare ${TMPDIR}/wbt-201.gpx2 ${REFERENCE}/wbt-201.gpx + +# +# Sportsim style-sheet +# +rm -f ${TMPDIR}/sportsim* +${PNAME} -i gpx -f ${REFERENCE}/expertgps.gpx -x nuketypes,waypoints,routes -o sportsim -F ${TMPDIR}/sportsim.txt +compare ${TMPDIR}/sportsim.txt ${REFERENCE}/track/sportsim-sample.txt + +# +# Suunto SDF +# +rm -f ${TMPDIR}/stmsdf* +${PNAME} -i garmin_txt -f ${REFERENCE}/garmin_txt.txt -t -o stmsdf -F ${TMPDIR}/stmsdf-track.sdf -r -o stmsdf,index=2 -F ${TMPDIR}/stmsdf-route.sdf +compare ${TMPDIR}/stmsdf-track.sdf ${REFERENCE}/track/stmsdf-track.sdf +compare ${TMPDIR}/stmsdf-route.sdf ${REFERENCE}/route/stmsdf-route.sdf +${PNAME} -i stmsdf -f ${TMPDIR}/stmsdf-track.sdf -f ${TMPDIR}/stmsdf-route.sdf -o garmin_txt,prec=2 -F ${TMPDIR}/stmsdf.txt +compare ${TMPDIR}/stmsdf.txt ${REFERENCE}/stmsdf.txt + +# +# Digital Mapping Tracklogs +# +rm -f ${TMPDIR}/dmtlog* +${PNAME} -i gpx -f ${REFERENCE}/expertgps.gpx -o dmtlog -F ${TMPDIR}/dmtlog-sample.trl +${PNAME} -i dmtlog -f ${TMPDIR}/dmtlog-sample.trl -o gpx -F ${TMPDIR}/dmtlog-sample.gpx +compare ${TMPDIR}/dmtlog-sample.gpx ${REFERENCE}/track/dmtlog-sample.gpx + +# +# gzipped file i/o +# +${PNAME} -i compegps -f ${REFERENCE}/compegps.wpt.gz -o gpx -F ${TMPDIR}/compegps-wpt.gpx +compare ${REFERENCE}/compegps-wpt.gpx ${TMPDIR}/compegps-wpt.gpx +${PNAME} -i cst -f ${REFERENCE}/route/cst-sample.cst.gz -o gpx -F ${TMPDIR}/cst-sample.gpx +compare ${TMPDIR}/cst-sample.gpx ${REFERENCE}/route/cst-sample.gpx + +# +# Quick tests for Google Earth/KML format +# Note: Reference files are from GPSBabel's own output. +# +${PNAME} -i gpx -f ${REFERENCE}/gc/GC7FA4.gpx -f ${REFERENCE}/gc/GCGCA8.gpx -o kml -F ${TMPDIR}/ge-gc.kml +compare ${TMPDIR}/ge-gc.kml ${REFERENCE}/earth-gc.kml +${PNAME} -i gpx -f ${REFERENCE}/expertgps.gpx -o kml -F ${TMPDIR}/ge-eg.kml +compare ${TMPDIR}/ge-eg.kml ${REFERENCE}/earth-expertgps.kml + +# +# Transformation filter (transform) tests +# +rm -f ${TMPDIR}/transform* +${PNAME} -i gpx -f ${REFERENCE}/expertgps.gpx -x nuketypes,routes,tracks -x transform,rte=wpt,del=y -o gpx,gpxver=1.1 -F ${TMPDIR}/transform-rte.gpx +compare ${TMPDIR}/transform-rte.gpx ${REFERENCE}/transform-rte.gpx +${PNAME} -i gpx -f ${REFERENCE}/expertgps.gpx -x nuketypes,waypoints,tracks -x transform,wpt=rte,del=y -o gpx,gpxver=1.1 -F ${TMPDIR}/transform-wpt.gpx +compare ${TMPDIR}/transform-wpt.gpx ${REFERENCE}/transform-wpt.gpx + +# +# "Raymarine Waypoint File" tests +# +${PNAME} -i raymarine -f ${REFERENCE}/raymarine-sample.rwf -o gpx -F ${TMPDIR}/raymarine-sample.gpx +compare ${TMPDIR}/raymarine-sample.gpx ${REFERENCE}/raymarine-sample.gpx +${PNAME} -i gpx -f ${REFERENCE}/expertgps.gpx -o raymarine -F ${TMPDIR}/expertgps.rwf +compare ${TMPDIR}/expertgps.rwf ${REFERENCE}/expertgps.rwf + + +# +# Alan MAp500 waypoint & route test +# +rm -f ${TMPDIR}/alanwpr* +${PNAME} -i alanwpr -f ${REFERENCE}/alanwpr.wpr -o alanwpr -F ${TMPDIR}/alanwpr-new.wpr +${PNAME} -i alanwpr -f ${TMPDIR}/alanwpr-new.wpr -o gpx -F ${TMPDIR}/alanwpr-new.gpx +compare ${TMPDIR}/alanwpr-new.gpx ${REFERENCE}/alanwpr.gpx + +# +# Alan Map500 tracklogs< test +# +rm -f ${TMPDIR}/alantrl* +${PNAME} -i alantrl -f ${REFERENCE}/alantrl.trl -o alantrl -F ${TMPDIR}/alantrl-new.trl +${PNAME} -i alantrl -f ${TMPDIR}/alantrl-new.trl -o gpx -F ${TMPDIR}/alantrl-new.gpx +compare ${TMPDIR}/alantrl-new.gpx ${REFERENCE}/alantrl.gpx + +# +# VITO SmartMap .vtt track file 'vitovtt' test +# +rm -f ${TMPDIR}/vitovtt-* +${PNAME} -i vitovtt -f ${REFERENCE}/track/vitovtt-sample.vtt -o gpx -F ${TMPDIR}/vitovtt-sample.gpx +compare ${REFERENCE}/track/vitovtt-sample.gpx ${TMPDIR}/vitovtt-sample.gpx + +# +# Test > 1 URL in selected files. +# +rm -f ${TMPDIR}/mlink* +${PNAME} -i gpx -f reference/multiple-links.gpx -o gpx,gpxver=1.1 -F ${TMPDIR}/mlink-1.gpx +compare ${TMPDIR}/mlink-1.gpx reference/multiple-links.gpx + +# +# Geogrid Viewer tracklogs +# +rm -f ${TMPDIR}/ggv_log* +${PNAME} -i gdb -f ${REFERENCE}/gdb-sample.gdb -x track,pack -o ggv_log -F ${TMPDIR}/ggv_log-sample.log +bincompare ${REFERENCE}/track/ggv_log-sample.log ${TMPDIR}/ggv_log-sample.log +${PNAME} -i ggv_log -f ${REFERENCE}/track/ggv_log-sample.log -o ggv_log -F ${TMPDIR}/ggv_log-sample2.log +bincompare ${REFERENCE}/track/ggv_log-sample.log ${TMPDIR}/ggv_log-sample2.log + +# +# G7ToWin (read only) test +# +${PNAME} -i g7towin -f ${REFERENCE}/expertgps.g7t -o garmin_txt,utc=0 -F ${TMPDIR}/expertgps-g7t.txt +compare ${REFERENCE}/expertgps-g7t.txt ${TMPDIR}/expertgps-g7t.txt + +# +# TomTom Navigator Places of Interest (.asc) +# +${PNAME} -i tomtom_asc -f ${REFERENCE}/tomtom_poi.asc -o tomtom_asc -F ${TMPDIR}/tomtom_poi.asc +compare ${REFERENCE}/tomtom_poi.asc ${TMPDIR}/tomtom_poi.asc + +# +# TomTom Navigator Itinerary files (.asc) +# +${PNAME} -i tomtom_itn -f ${REFERENCE}/route/tomtom_itn.itn -o tomtom_itn -F ${TMPDIR}/tomtom_itn.itn +compare ${REFERENCE}/route/tomtom_itn.itn ${TMPDIR}/tomtom_itn.itn + +# +# Garmin Points of Interest "garmin_gpi" (.gpi) +# +${PNAME} -i garmin_gpi -f ${REFERENCE}/garmin_gpi.gpi -o gpx -F ${TMPDIR}/garmin_gpi.gpx +compare ${REFERENCE}/garmin_gpi.gpx ${TMPDIR}/garmin_gpi.gpx +${PNAME} -i gpx -f ${REFERENCE}/garmin_gpi.gpx -o garmin_gpi -F ${TMPDIR}/garmin_gpi.gpi +${PNAME} -i garmin_gpi -f ${TMPDIR}/garmin_gpi.gpi -o gpx -F ${TMPDIR}/garmin_gpi2.gpx +compare ${REFERENCE}/garmin_gpi2.gpx ${TMPDIR}/garmin_gpi2.gpx +${PNAME} -i gpx -f ${REFERENCE}/track/vitovtt-sample.gpx -x transform,wpt=trk -o garmin_gpi -F ${TMPDIR}/garmin_gpi3a.gpi +${PNAME} -i garmin_gpi -f ${TMPDIR}/garmin_gpi3a.gpi -o garmin_gpi -F ${TMPDIR}/garmin_gpi3b.gpi +bincompare ${TMPDIR}/garmin_gpi3a.gpi ${TMPDIR}/garmin_gpi3b.gpi +${PNAME} -i garmin_gpi -f ${REFERENCE}/gpi_ext-sample.gpi -o unicsv -F ${TMPDIR}/gpi_ext-sample.csv +compare ${REFERENCE}/gpi_ext-sample.csv ${TMPDIR}/gpi_ext-sample.csv + +# +# Nokia LMX +# +${PNAME} -i lmx -f ${REFERENCE}/nokia.lmx -o lmx -F ${TMPDIR}/nokia.lmx +compare ${REFERENCE}/nokia.lmx ${TMPDIR}/nokia.lmx + +# +# Swiss Map (.xol) tests +# +${PNAME} -i xol -f ${REFERENCE}/xol-sample.xol -o gpx -F ${TMPDIR}/xol-sample.gpx +compare ${TMPDIR}/xol-sample.gpx ${REFERENCE}/xol-sample.gpx +${PNAME} -i gpx -f ${REFERENCE}/xol-sample.gpx -o xol -F ${TMPDIR}/xol-sample-gpx.xol +compare ${TMPDIR}/xol-sample-gpx.xol ${REFERENCE}/xol-sample-gpx.xol + +# +# NaviLink waypoints +# +${PNAME} -i navilink -f ${REFERENCE}/navilink_waypoints.wpt -o gpx -F ${TMPDIR}/navilink_waypoints.gpx +compare ${TMPDIR}/navilink_waypoints.gpx ${REFERENCE}/navilink_waypoints.gpx +${PNAME} -i gpx -f ${TMPDIR}/navilink_waypoints.gpx -o navilink -F ${TMPDIR}/navilink_waypoints_gpx.wpt +#compare ${TMPDIR}/navilink_waypoints_gpx.wpt ${REFERENCE}/navilink_waypoints_gpx.wpt + +# +# NaviLink tracks +# +${PNAME} -t -i navilink -f ${REFERENCE}/navilink_tracks.trk -o gpx -F ${TMPDIR}/navilink_tracks.gpx +compare ${TMPDIR}/navilink_tracks.gpx ${REFERENCE}/navilink_tracks.gpx +${PNAME} -t -i gpx -f ${TMPDIR}/navilink_tracks.gpx -o navilink -F ${TMPDIR}/navilink_tracks_gpx.trk +#compare ${TMPDIR}/navilink_tracks_gpx.trk ${REFERENCE}/navilink_tracks_gpx.trk + +# +# MTK logger tests +# +rm -f ${TMPDIR}/mtk_logger.* +${PNAME} -t -w -i mtk-bin,csv=${TMPDIR}/mtk_logger.csv -f ${REFERENCE}/track/mtk_logger.bin -o gpx -F ${TMPDIR}/mtk_logger.gpx +compare ${TMPDIR}/mtk_logger.gpx ${REFERENCE}/track/mtk_logger.gpx +## CSV compare needs to be done with '-w' - ignore whitespace. +compare ${TMPDIR}/mtk_logger.csv ${REFERENCE}/track/mtk_logger.csv + +# +# MagicMaps IK3D Project File .ikt test +# +${PNAME} -i ik3d -f ${REFERENCE}/ik3d-sample.ikt -o gpx -F ${TMPDIR}/ik3d-sample.gpx +compare ${TMPDIR}/ik3d-sample.gpx ${REFERENCE}/ik3d-sample.gpx + +# osm data files +rm -f ${TMPDIR}/osm-* +${PNAME} -i osm -f ${REFERENCE}/osm-data.xml -o gpx -F ${TMPDIR}/osm-data.gpx +compare ${TMPDIR}/osm-data.gpx ${REFERENCE}/osm-data.gpx + +# Destinator POI +${PNAME} -i gpx -f ${REFERENCE}/expertgps.gpx -o destinator_poi -F ${TMPDIR}/destinator_poi.dat +${PNAME} -i destinator_poi -f ${TMPDIR}/destinator_poi.dat -w -o unicsv,utc=0 -F ${TMPDIR}/destinator_poi.txt +compare ${TMPDIR}/destinator_poi.txt ${REFERENCE}/destinator_poi.txt + +# Destinator Itinerary +${PNAME} -i gpx -f ${REFERENCE}/expertgps.gpx -o destinator_itn -F ${TMPDIR}/destinator_itn.dat +${PNAME} -i destinator_itn -f ${TMPDIR}/destinator_itn.dat -r -o unicsv,utc=0 -F ${TMPDIR}/destinator_itn.txt +compare ${TMPDIR}/destinator_itn.txt ${REFERENCE}/route/destinator_itn.txt + +# Destinator TrackLog +${PNAME} -i nmea -f ${REFERENCE}/track/nmea+ms.txt -o destinator_trl -F ${TMPDIR}/destinator_trl.dat +${PNAME} -i destinator_trl -f ${TMPDIR}/destinator_trl.dat -t -o unicsv,utc=0 -F ${TMPDIR}/destinator_trl.txt +compare ${TMPDIR}/destinator_trl.txt ${REFERENCE}/track/destinator_trl.txt + +# Exif format test (read only) +${PNAME} -i exif -f ${REFERENCE}/IMG_2065.JPG -o unicsv,utc=0 -F ${TMPDIR}/exif-dat.csv +compare ${TMPDIR}/exif-dat.csv ${REFERENCE}/exif-dat.csv + +# VidaOne track logs +${PNAME} -i vidaone -f ${REFERENCE}/track/vidaone.gpb -t -o unicsv -F ${TMPDIR}/vidaone.csv +compare ${TMPDIR}/vidaone.csv ${REFERENCE}/track/vidaone.csv + + +exit 0 diff --git a/testw b/testw new file mode 100755 index 000000000..d41a6ef86 --- /dev/null +++ b/testw @@ -0,0 +1,166 @@ +#!/bin/sh + +### cross format waypoint check ### + +PNAME=${PNAME:-./gpsbabel} +REFGPX="reference/expertgps.gpx" # reference file for all tests +EXCL="ozi vitosmt" # exclude formats from test +CAPS="" +TEMPDIR=/tmp/gb-testw +CATALOG=/tmp/gb-testw.done +LOGFILE=/tmp/gb-testw.log + +# options +vg=0 +prep=0 + +function log_entry() +{ + touch $LOGFILE + echo "-----------------------------------------------------------------------" >> ${LOGFILE} + date >> ${LOGFILE} + echo "$*" >> ${LOGFILE} +} + +function try_run() # command line +{ + local CMD="$*" + local RES=0 + + [ $vg -ne 0 ] && CMD="valgrind -q $CMD" + + ${CMD} > $TEMPDIR/.result 2>&1 + RES=$? + if [ $RES -ne 0 -o -s $TEMPDIR/.result ]; then + if [ $RES -ne 0 ]; then + echo " -- Uhps --" + echo "-----------------------------------------------------------------------" + test -s $TEMPDIR/.result && cat $TEMPDIR/.result + echo "-----------------------------------------------------------------------" + else + echo "" + fi + log_entry "cmd($RES): $CMD" + test -s $TEMPDIR/.result && cat $TEMPDIR/.result >> ${LOGFILE} + return 1 + else + return 0 + fi +} + +function STAGE_1 () # format +{ + local FMT=$1 + local CMD1 CMD2 + + echo "$CAPS" | + + while read type caps format comment; do + + for i in $EXCL; do + if [ "$format" == "$i" ]; then + caps="------" + fi + done + + grep "$FMT & $format" ${CATALOG} > /dev/null && continue + + echo -n "testing \"$FMT\" with \"$format\" " + + case $caps in + + -w*) + echo -n "*" + CMD1="${PNAME} -i $FMT -f $TEMPDIR/$FMT -o $format -F $TEMPDIR/$FMT.$format" + try_run "${CMD1}" || continue + ;; + + rw*) + echo -n "*" + CMD1="${PNAME} -i $FMT -f $TEMPDIR/$FMT -o $format -F $TEMPDIR/$FMT.$format" + try_run "${CMD1}" || continue + echo -n "*" + CMD2="${PNAME} -i $format -f $TEMPDIR/$FMT.$format -o $FMT -F $TEMPDIR/$FMT.$format.$FMT" + try_run "${CMD2}" || continue + ;; + esac + echo "*" + echo "$FMT & $format" >> $CATALOG + done + return 0 +} + +function STAGE_0 () +{ + echo "$CAPS" | + + while read type caps format comment; do + + for i in $EXCL; do + if [ "$format" == "$i" ]; then + caps="------" + fi + done + + case $caps in + rw*) + CMD="${PNAME} -i gpx -f $REFGPX -x nuketypes,routes,tracks -o $format -F $TEMPDIR/$format" + try_run "${CMD}" || continue + STAGE_1 $format || exit 1 + ;; + esac + case $caps in + -w*) + CMD="${PNAME} -i gpx -f $REFGPX -x nuketypes,routes,tracks -o $format -F $TEMPDIR/$format" + try_run "${CMD}" || continue + ;; + esac + done + rm -f $TEMPDIR/.result +} + +rm -rf $TEMPDIR > /dev/null +mkdir -p $TEMPDIR > /dev/null + +while [ $# -gt 0 ]; do + case $1 in + -s|--start) # remove catalog. run the full test. + rm -f $CATALOG + ;; + -v|--valgrind) + vg=1 + ;; + -p|--prepare) # prepare for valgrind check. + prep=1 + ;; + -c|--clean) + trap "rm -fr $TEMPDIR; exit 1" 0 1 2 3 15 + ;; + -r|--reference) + shift + REFGPX=$1 + ;; + esac + shift +done + +if [ $prep -ne 0 ]; then + test -s Makefile && make clean + CFLAGS="-O0" ./configure || exit 1 # -O0 is suggested by vg. + make || exit 1 + echo "All fine. You can do now a 'testw -v'" + exit 0 +fi + +if test ! -s $REFGPX; then + echo "GPX reference \"$REFGPX\" doesn't exist!" + exit 1 +fi + +touch $CATALOG + +log_entry "testw started." +echo "Catalog: $CATALOG" >> $LOGFILE + +CAPS=`${PNAME} -^2 | grep "^file"` +STAGE_0 diff --git a/text.c b/text.c new file mode 100644 index 000000000..ab04d7d1b --- /dev/null +++ b/text.c @@ -0,0 +1,278 @@ +/* + Output only format for Human Readable formats. + + Copyright (C) 2004 Scott Brynen, scott (at) brynen.com + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include "defs.h" +#include "jeeps/gpsmath.h" +#include + +static gbfile *file_out; +static short_handle mkshort_handle; + +static char *suppresssep = NULL; +static char *txt_encrypt = NULL; +static char *includelogs = NULL; +static char *degformat = NULL; +static char *altunits = NULL; +static char *split_output = NULL; +static int waypoint_count; +static char *output_name; + +#define MYNAME "TEXT" + +static +arglist_t text_args[] = { + { "nosep", &suppresssep, + "Suppress separator lines between waypoints", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + { "encrypt", &txt_encrypt, + "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + { "logs", &includelogs, + "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + { "degformat", °format, + "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX }, + { "altunits", &altunits, + "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX }, + { "splitoutput", &split_output, + "Write each waypoint in a separate file", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + + ARG_TERMINATOR +}; + + + +static void +wr_init(const char *fname) +{ + waypoint_count = 0; + output_name = xstrdup(fname); + if (!split_output) { + file_out = gbfopen(fname, "w", MYNAME); + } + mkshort_handle = mkshort_new_handle(); +} + +static void +wr_deinit(void) +{ + if (!split_output) { + gbfclose(file_out); + } + mkshort_del_handle(&mkshort_handle); + xfree(output_name); +} + +static void +text_disp(const waypoint *wpt) +{ + int latint, lonint; + char tbuf[1024]; + time_t tm = wpt->creation_time; + gbint32 utmz; + double utme, utmn; + char utmzc; + char *tmpout1, *tmpout2; + char *altout; + fs_xml *fs_gpx; + + waypoint_count++; + + if (split_output) { + char *thisfname; + xasprintf(&thisfname, "%s%d", output_name, waypoint_count); + file_out = gbfopen(thisfname, "w", MYNAME); + } + + lonint = abs((int) wpt->longitude); + latint = abs((int) wpt->latitude); + + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + + if (tm == 0) + tm = time(NULL); + strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); + + tmpout1 = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 0); + if (wpt->altitude != unknown_alt) { + xasprintf(&altout, " alt:%d", (int) ( (altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude) ); + } + else { + altout = ""; + } + xasprintf (&tmpout2, "%s (%d%c %6.0f %7.0f)%s", tmpout1, utmz, utmzc, utme, utmn, altout ); + gbfprintf(file_out, "%-16s %59s\n", + (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, + tmpout2); + xfree(tmpout2); + xfree(tmpout1); + if (altout[0]) + xfree(altout); + + + if (strcmp(wpt->description, wpt->shortname)) { + gbfprintf(file_out, "%s", wpt->description); + if (wpt->gc_data.placer) + gbfprintf(file_out, " by %s", wpt->gc_data.placer); + } + if (wpt->gc_data.terr) { + gbfprintf(file_out, " - %s / %s - (%d%s / %d%s)\n", + gs_get_cachetype(wpt->gc_data.type), gs_get_container(wpt->gc_data.container), + (int)(wpt->gc_data.diff / 10), (wpt->gc_data.diff%10)?".5":"", + (int)(wpt->gc_data.terr / 10), (wpt->gc_data.terr%10)?".5":"" ); + if (wpt->gc_data.desc_short.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data.desc_short); + gbfprintf (file_out, "\n%s\n", stripped_html); + xfree(stripped_html); + } + if (wpt->gc_data.desc_long.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data.desc_long); + gbfprintf (file_out, "\n%s\n", stripped_html); + xfree(stripped_html); + } + if (wpt->gc_data.hint) { + char *hint = NULL; + if ( txt_encrypt ) + hint = rot13( wpt->gc_data.hint ); + else + hint = xstrdup( wpt->gc_data.hint ); + gbfprintf (file_out, "\nHint: %s\n", hint); + xfree( hint ); + } + } + else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { + gbfprintf (file_out, "\n%s\n", wpt->notes); + } + + fs_gpx = NULL; + if ( includelogs ) { + fs_gpx = (fs_xml *)fs_chain_find( wpt->fs, FS_GPX); + } + + if ( fs_gpx && fs_gpx->tag ) { + xml_tag *root = fs_gpx->tag; + xml_tag *curlog = NULL; + xml_tag *logpart = NULL; + curlog = xml_findfirst( root, "groundspeak:log" ); + while ( curlog ) { + time_t logtime = 0; + struct tm *logtm = NULL; + gbfprintf( file_out, "\n" ); + + logpart = xml_findfirst( curlog, "groundspeak:type" ); + if ( logpart ) { + gbfprintf( file_out, "%s by ", logpart->cdata ); + } + + logpart = xml_findfirst( curlog, "groundspeak:finder" ); + if ( logpart ) { + gbfprintf( file_out, "%s on ", logpart->cdata ); + } + + logpart = xml_findfirst( curlog, "groundspeak:date" ); + if ( logpart ) { + logtime = xml_parse_time( logpart->cdata, NULL); + logtm = localtime( &logtime ); + if ( logtm ) { + gbfprintf( file_out, + "%4.4d-%2.2d-%2.2d\n", + logtm->tm_year+1900, + logtm->tm_mon+1, + logtm->tm_mday ); + } + } + + logpart = xml_findfirst( curlog, "groundspeak:log_wpt" ); + if ( logpart ) { + char *coordstr = NULL; + float lat = 0; + float lon = 0; + coordstr = xml_attribute( logpart, "lat" ); + if ( coordstr ) { + lat = atof( coordstr ); + } + coordstr = xml_attribute( logpart, "lon" ); + if ( coordstr ) { + lon = atof( coordstr ); + } + coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 0); + gbfprintf( file_out, "%s\n", coordstr); + xfree(coordstr); + } + + logpart = xml_findfirst( curlog, "groundspeak:text" ); + if ( logpart ) { + char *encstr = NULL; + char *s = NULL; + int encoded = 0; + encstr = xml_attribute( logpart, "encoded" ); + encoded = (encstr[0] != 'F'); + + if ( txt_encrypt && encoded ) { + s = rot13( logpart->cdata ); + } + else { + s = xstrdup( logpart->cdata ); + } + + gbfprintf( file_out, "%s", s ); + xfree( s ); + } + + gbfprintf( file_out, "\n" ); + curlog = xml_findnext( root, curlog, "groundspeak:log" ); + } + } + if (! suppresssep) + gbfprintf(file_out, "\n-----------------------------------------------------------------------------\n"); + else + gbfprintf(file_out, "\n"); + + if (split_output) { + gbfclose(file_out); + file_out = NULL; + } +} + +static void +data_write(void) +{ + if (! suppresssep && !split_output) + gbfprintf(file_out, "-----------------------------------------------------------------------------\n"); + setshort_length(mkshort_handle, 6); + waypt_disp_all(text_disp); +} + + +ff_vecs_t text_vecs = { + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none}, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + text_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + +}; diff --git a/tiger.c b/tiger.c new file mode 100644 index 000000000..4b0ae8385 --- /dev/null +++ b/tiger.c @@ -0,0 +1,288 @@ +/* + Access to U.S. Census Bureau "tiger" format. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "csv_util.h" + +static gbfile *file_in, *file_out; +static short_handle mkshort_handle; +static short_handle mkshort_whandle; + +#define MYNAME "GPSUTIL" + +static double maxlat, maxlon, minlat, minlon; +static int rec_cnt; +static char *nolabels = NULL; +static char *genurl = NULL; +static char *suppresswhite = NULL; +static char *iconismarker = NULL; +static char *snlen = NULL; + +static char *margin = NULL; +static char *xpixels = NULL; +static char *ypixels = NULL; +static char *oldthresh = NULL; +static char *oldmarker = NULL; +static char *newmarker = NULL; +static char *unfoundmarker = NULL; + +static int short_length; +static double thresh_days; + +/* + * The code bracketed by CLICKMAP is to generate clickable image maps + * for a web browser. It's functional, but is missing the math to do + * the projection transformations. Some trig geek can finish that. + */ +#if CLICKMAP +static gbfile *linkf; +static char *clickmap = NULL; +#endif + + +static +arglist_t tiger_args[] = { + {"nolabels", &nolabels, "Suppress labels on generated pins", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"genurl", &genurl, "Generate file with lat/lon for centering map", + NULL, ARGTYPE_OUTFILE, ARG_NOMINMAX }, + {"margin", &margin, "Margin for map. Degrees or percentage", + "15%", ARGTYPE_FLOAT, ARG_NOMINMAX}, + {"snlen", &snlen, "Max shortname length when used with -s", + "10", ARGTYPE_INT, "1", NULL}, + {"oldthresh", &oldthresh, + "Days after which points are considered old", + "14", ARGTYPE_INT, ARG_NOMINMAX}, + {"oldmarker", &oldmarker, "Marker type for old points", + "redpin", ARGTYPE_STRING, ARG_NOMINMAX}, + {"newmarker", &newmarker, "Marker type for new points", + "greenpin", ARGTYPE_STRING, ARG_NOMINMAX}, + {"suppresswhite", &suppresswhite, + "Suppress whitespace in generated shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"unfoundmarker", &unfoundmarker, "Marker type for unfound points", + "bluepin", ARGTYPE_STRING, ARG_NOMINMAX}, + {"xpixels", &xpixels, "Width in pixels of map", + "768", ARGTYPE_INT, ARG_NOMINMAX}, + {"ypixels", &ypixels, "Height in pixels of map", + "768", ARGTYPE_INT, ARG_NOMINMAX}, + {"iconismarker", &iconismarker, + "The icon description is already the marker", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX }, +#if CLICKMAP + {"clickmap", &clickmap, "Generate Clickable map web page", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, +#endif + ARG_TERMINATOR +}; + + +static void +rd_init(const char *fname) +{ + file_in = gbfopen(fname, "rb", MYNAME); + mkshort_handle = mkshort_new_handle(); +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); + mkshort_del_handle(&mkshort_handle); +} + +static void +wr_init(const char *fname) +{ + file_out = gbfopen(fname, "w", MYNAME); + thresh_days = strtod(oldthresh, NULL); +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); +} + +static void +data_read(void) +{ + double lat,lon; + char desc[100]; + char icon[100]; + char *ibuf; + waypoint *wpt_tmp; + + while ((ibuf = gbfgetstr(file_in))) { + if( sscanf(ibuf, "%lf,%lf:%100[^:]:%100[^\n]", + &lon, &lat, icon, desc)) { + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + wpt_tmp->description = xstrdup(desc); + wpt_tmp->shortname = mkshort(mkshort_handle, desc); + + waypt_add(wpt_tmp); + } + } +} + +static void +tiger_disp(const waypoint *wpt) +{ + const char *pin; + double lat = wpt->latitude; + double lon = wpt->longitude; + + if (iconismarker) + pin = wpt->icon_descr ? wpt->icon_descr : ""; + else if (wpt->icon_descr && strstr(wpt->icon_descr, "-unfound")) + pin = unfoundmarker; + else if (wpt->creation_time > current_time() - 3600 * 24 * thresh_days) + pin = newmarker; + else + pin = oldmarker; + + if (genurl) { + if (lat > maxlat) maxlat = lat; + if (lon > maxlon) maxlon = lon; + if (lat < minlat) minlat = lat; + if (lon < minlon) minlon = lon; + } + + gbfprintf(file_out, "%f,%f:%s", lon, lat, pin); + if (!nolabels) { + char *temp = NULL; + char *desc = csv_stringclean(wpt->description, ":"); + if (global_opts.synthesize_shortnames) + { + temp = desc; + desc = mkshort(mkshort_whandle, desc); + } + gbfprintf(file_out, ":%s", desc); + if (temp != NULL) desc = temp; + xfree(desc); + } + gbfprintf(file_out, "\n"); +} + +#if CLICKMAP +static void +map_plot(const waypoint *wpt) +{ + static int x,y; + + /* Replace with real math. */ + x+=10; + y+=10; + + gbfprintf(linkf, "\"%s\"\n",url, wpt->description); +} +#endif /* CLICKMAP */ + +static double +dscale(double distance) +{ + /* + * If we have any specified margin options factor those in now. + * A additional little boundary is helpful because Tiger always + * puts the pin above the actual coord and if we don't pad the + * top will be clipped. It also makes the maps more useful to + * have a little bit of context around the pins on the border. + */ + + if (strchr(margin, '%')) + return distance + strtod(margin, NULL) / 100.0 * distance; + else + return strtod(margin, NULL) + distance; +} + +static void +data_write(void) +{ + double latsz,lonsz; + maxlat = -9999.0; + maxlon = -9999.0; + minlat = 9999.0; + minlon = 9999.0; + rec_cnt = 0; + + short_length = atoi(snlen); + mkshort_whandle = mkshort_new_handle(); + + if (suppresswhite) { + setshort_whitespace_ok(mkshort_whandle, 0); + } + + setshort_length(mkshort_whandle, short_length); + + gbfprintf(file_out, "#tms-marker\n"); + waypt_disp_all(tiger_disp); + + if (genurl) { + gbfile *urlf; + + urlf = gbfopen(genurl, "w", MYNAME); + latsz = fabs(maxlat - minlat); + lonsz = fabs(maxlon - minlon); + + /* + * Center the map along X and Y axis the midpoint of + * our min and max coords each way. + */ + gbfprintf(urlf, "lat=%f&lon=%f&ht=%f&wid=%f", + minlat + (latsz/2.0), + minlon + (lonsz/2.0), + dscale(latsz), + dscale(lonsz)); + + gbfprintf(urlf, "&iwd=%s&iht=%s", xpixels, ypixels); + gbfclose(urlf); +#if CLICKMAP + if (clickmap) { + linkf = gbfopen(clickmap, "w", MYNAME); + gbfprintf(linkf, "\n"); + waypt_disp_all(map_plot); + gbfprintf(linkf, "\n"); + gbfclose(linkf); + linkf = NULL; + } +#endif + } + + mkshort_del_handle(&mkshort_whandle); +} + + +ff_vecs_t tiger_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + tiger_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/tmpro.c b/tmpro.c new file mode 100644 index 000000000..ee632250e --- /dev/null +++ b/tmpro.c @@ -0,0 +1,259 @@ +/* + ---------------------------------------------------------------------------------------- + TopoMapPro (.txt) + New Zealand Mapping Software + www.topomappro.com + (Tab Delimited text file) + + Based on gpsbabel .MXF format by Alex Mottram (geo_alexm at cox-internet.com) + Tweaked for TopoMapPro by Nick Heaphy (nick at automata dot co dot nz) + + Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink + 25 6 80 8 8 8 8 8 4 4 128 (lengths) + + Based on the specifications found in the TopoMapPro documentation available from website + ---------------------------------------------------------------------------------------- + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "csv_util.h" +#include + +#define MYNAME "TMPro" + +static gbfile *file_in, *file_out; +static short_handle mkshort_handle; + +static void +rd_init(const char *fname) +{ + file_in = gbfopen(fname, "rb", MYNAME); +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = gbfopen(fname, "w", MYNAME); +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); +} + +static void +data_read(void) +{ + char *buff; + char *s; + char *holder; + waypoint *wpt_tmp; + int i; + int linecount = 0; + + while ((buff = gbfgetstr(file_in))) { + linecount++; + + /* skip the line if it contains "sHyperLink" as it is a header (I hope :) */ + if ((strlen(buff)) && (strstr(buff, "sHyperLink") == NULL)) { + + wpt_tmp = waypt_new(); + + /* data delimited by tabs, not enclosed in quotes. */ + s = buff; + s = csv_lineparse(s, "\t", "", linecount); + + i = 0; + while (s) { + switch (i) { + + /* Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink */ + /* 0 1 2 3 4 5 6 7 8 9 10 */ + + case 0: + /* ignore: group */ + break; + case 1: + wpt_tmp->shortname = csv_stringtrim(s, "", 0); + break; + case 2: + /* Description is not a TopoMapPro format requirement. + If we assign "" then .loc/.gpx will generate empty XML tags :( + */ + holder = csv_stringtrim(s, "", 0); + if (strlen(holder)) + wpt_tmp->description = holder; + else + xfree(holder); + break; + case 3: + wpt_tmp->latitude = atof(s); + break; + case 4: + wpt_tmp->longitude = atof(s); + break; + case 5: + /* ignore: NZMapGrid Easting */ + break; + case 6: + /* ignore: NZMapGrid Northing */ + break; + case 7: + wpt_tmp->altitude = atof(s); + break; + case 8: + /* ignore: color */ + break; + case 9: + /* ignore: symbol (non standard) */ + break; + case 10: + /* URL is not a TopoMapPro format requirement. + You can store file links etc, we will discard anything that is not http + (as URLs in TMPro must start "http:") as other GPS formats probably can't + use the TopoMapLinks links. + (plus discards length 0 strings (so no empty XML tags)) + */ + holder = csv_stringtrim(s, "", 0); + if (strstr(holder, "http:") != NULL) + wpt_tmp->url = holder; + else + xfree(holder); + break; + default: + /* whoa! nelly */ + warning(MYNAME ": Warning: data fields on line %d exceed specification.\n", + linecount); + break; + } + i++; + + s = csv_lineparse(NULL, "\t", "\"", linecount); + } + + if (i != 11) { + xfree(wpt_tmp); + warning(MYNAME ": WARNING - extracted %d fields from line %d. \nData on line ignored.\n", + i, linecount); + } else { + waypt_add(wpt_tmp); + } + + } else { + /* empty line */ + } + + } +} + +static void +tmpro_waypt_pr(const waypoint * wpt) +{ + int icon = 1; /* default to "flag" */ + int colour = 255; /*default to red */ + char *shortname = NULL; + char *description = NULL; + + if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) + shortname = mkshort_from_wpt(mkshort_handle, wpt); + else + shortname = csv_stringclean(wpt->description, ",\""); + } else { + /* no description available */ + shortname = xstrdup(""); + } + } else{ + shortname = csv_stringclean(wpt->shortname, ",\""); + } + + if (! wpt->description) { + if (shortname) { + description = csv_stringclean(shortname, ",\""); + } else { + description = xstrdup(""); + } + } else{ + description = csv_stringclean(wpt->description, ",\""); + } + + /* Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink */ + /* 0 1 2 3 4 5 6 7 8 9 10 */ + /* Number of characters */ + /* 25 6 80 8 8 8 8 8 4 4 128 */ + + gbfprintf(file_out, "new\t%.6s\t%.80s\t%08.6f\t%08.6f\t\t\t%.2f\t%d\t%d\t%.128s\n", + shortname, + description, + wpt->latitude, + wpt->longitude, + wpt->altitude, + colour, + icon, + wpt->url ? wpt->url : "" + ); + + + if (description) + xfree(description); + if (shortname) + xfree(shortname); +} + +static void +data_write(void) +{ + /* Short names */ + if (global_opts.synthesize_shortnames) { + mkshort_handle = mkshort_new_handle(); + setshort_length(mkshort_handle, 6); + setshort_whitespace_ok(mkshort_handle, 0); + setshort_badchars(mkshort_handle, "\","); + } + + /* Write file header */ + gbfprintf(file_out, "Group\tsID\tsDescription\tfLat\tfLong\tfEasting\tfNorthing\tfAlt\tiColour\tiSymbol\tsHyperLink\n"); + + waypt_disp_all(tmpro_waypt_pr); + mkshort_del_handle(&mkshort_handle); +} + +ff_vecs_t tmpro_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; + diff --git a/tomtom.c b/tomtom.c new file mode 100644 index 000000000..a85de57ba --- /dev/null +++ b/tomtom.c @@ -0,0 +1,345 @@ +/* + Read and write TomTom .ov2 files. + + Copyright (C) 2005 Ronald Parker (babeltomtom@parkrrrr.com) and + Robert Lipe (robertlipe@usa.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +/* + This module is based on my reverse-engineering of the .ov2 format, so + it might not be aware of all record types. In particular, I've seen + a type-3 record that may contain additional strings, but since I haven't + seen any of those from a legitimate source, I don't know what they are + supposed to contain. Thus, they are not currently supported. (The one + I saw was due to an errant pair of double-quotes in the input to + makeov2.exe.) -- Ron Parker, 28 April 2005 + + Because they've been seen in the wild, I have updated the reader to + deal with type 3 as if they were type 2. I still haven't seen any + records that fill in the other two strings, so until I know for sure + that they are indeed strings, I'm just putting them on the end of the + description string beyond the NUL terminator. -- Ron Parker, 17 July 2006 +*/ + + +#include "defs.h" + +#define MYNAME "TomTom" + +static gbfile *file_in; +static gbfile *file_out; + +static +arglist_t tomtom_args[] = { + ARG_TERMINATOR +}; + +static void +rd_init(const char *fname) +{ + file_in = gbfopen_le(fname, "rb", MYNAME); +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = gbfopen_le(fname, "wb", MYNAME); +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); +} + +#define read_long(f) gbfgetint32((f)) +#define read_char(f) (unsigned char)gbfgetc((f)) + +static void +data_read(void) +{ + unsigned char rectype; + long recsize; + long x; + long y; + char *desc; + waypoint *wpt_tmp; + while (!gbfeof( file_in ) ) { + rectype = read_char( file_in ); + if ( rectype == 1 ) { + /* a block header; ignored on read */ + read_long( file_in ); + read_long( file_in ); + read_long( file_in ); + read_long( file_in ); + read_long( file_in ); + } + else if ( rectype == 2 || rectype == 3 ) { + recsize = read_long( file_in ); + x = read_long( file_in ); + y = read_long( file_in ); + desc = (char *)xmalloc( recsize - 13 ); + gbfread( desc, recsize-13, 1, file_in ); + + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = x/100000.0; + wpt_tmp->latitude = y/100000.0; + wpt_tmp->description = desc; + + waypt_add(wpt_tmp); + } + } +} + + +struct hdr{ + waypoint *wpt; +}; + +static int compare_lon(const void *a, const void *b); + +static +int +compare_lat(const void *a, const void *b) +{ + const struct hdr *wa = a; + const struct hdr *wb = b; + + double difference = wa->wpt->latitude - wb->wpt->latitude; + if ( difference < 0 ) { + return -1; + } + if ( difference ) { + return 1; + } + if ( wa->wpt->longitude - wb->wpt->longitude == 0 ) { + return strcmp(wa->wpt->shortname, wb->wpt->shortname); + } + return compare_lon(a,b); +} + +static +int +compare_lon(const void *a, const void *b) +{ + const struct hdr *wa = a; + const struct hdr *wb = b; + + double difference = wa->wpt->longitude - wb->wpt->longitude; + if ( difference < 0 ) { + return -1; + } + if ( difference ) { + return 1; + } + if ( wa->wpt->latitude - wb->wpt->latitude == 0 ) { + return strcmp(wa->wpt->shortname, wb->wpt->shortname); + } + return compare_lat(a,b); +} + +#define write_long(f,v) gbfputint32((v),f) + +static void +write_float_as_long( gbfile *file, double value ) +{ + long tmp = (value + 0.500000000001); + write_long( file, tmp); +} + +#define write_char(f,c) gbfputc((c),f) +#define write_string(f,s) gbfputcstr((s),f) + +struct blockheader { + struct hdr *start; + long count; + long size; + double minlat; + double maxlat; + double minlon; + double maxlon; + struct blockheader *ch1; + struct blockheader *ch2; +}; + +static void +write_blocks( gbfile *f, struct blockheader *blocks ) { + int i; + write_char( f, 1 ); + write_long( f, blocks->size ); + write_float_as_long( f, blocks->maxlon*100000 ); + write_float_as_long( f, blocks->maxlat*100000 ); + write_float_as_long( f, blocks->minlon*100000 ); + write_float_as_long( f, blocks->minlat*100000 ); + if ( blocks->ch1 ) { + write_blocks( f, blocks->ch1 ); + } + if ( blocks->ch2 ) { + write_blocks( f, blocks->ch2 ); + } + if ( !blocks->ch1 && !blocks->ch2 ) { + for ( i = 0; i < blocks->count; i++ ) { + char desc_field [256]; + write_char( f, 2 ); + if (global_opts.smart_names && + blocks->start[i].wpt->gc_data.diff && + blocks->start[i].wpt->gc_data.terr) { + snprintf(desc_field,sizeof(desc_field),"%s(t%ud%u)%s(type%dcont%d)",blocks->start[i].wpt->description, + blocks->start[i].wpt->gc_data.terr/10, + blocks->start[i].wpt->gc_data.diff/10, + blocks->start[i].wpt->shortname, + (int) blocks->start[i].wpt->gc_data.type, + (int) blocks->start[i].wpt->gc_data.container); + //Unfortunately enums mean we get numbers for cache type and container. + } else { + snprintf(desc_field, sizeof(desc_field), "%s", + blocks->start[i].wpt->description); + } + write_long( f, strlen( desc_field ) + 14 ); + write_float_as_long( f, blocks->start[i].wpt->longitude*100000); + write_float_as_long( f, blocks->start[i].wpt->latitude*100000); + write_string( f, desc_field); + } + } +} + +static struct blockheader * +compute_blocks( struct hdr *start, int count, + double minlon, double maxlon, double minlat, double maxlat ) { + struct blockheader *newblock; + + newblock = (struct blockheader *)xcalloc( sizeof( *newblock ), 1); + newblock->start = start; + newblock->count = count; + newblock->minlon = minlon; + newblock->maxlon = maxlon; + newblock->minlat = minlat; + newblock->maxlat = maxlat; + newblock->size = 4 * 5 + 1; /* hdr is 5 longs, 1 char */ + if ( count < 20 ) { + int i; + waypoint *wpt = NULL; + + for ( i = 0; i < count; i++ ) { + newblock->size += 4 * 3 + 1; + /* wpt const part 3 longs, 1 char */ + wpt = start[i].wpt; + newblock->size += strlen( wpt->description ) + 1; + } + } + else { + if ( (maxlat-minlat)>(maxlon-minlon)) { + /* split along lats */ + qsort( start, count, sizeof(*start), compare_lat); + newblock->ch1 = compute_blocks( start, count/2, + minlon, maxlon, minlat, + start[count/2].wpt->latitude ); + newblock->ch2 = compute_blocks( start+count/2, + count-count/2, minlon, maxlon, + start[count/2].wpt->latitude, maxlat ); + } + else { + /* split along lons */ + qsort( start, count, sizeof(*start), compare_lon); + newblock->ch1 = compute_blocks( start, count/2, + minlon, start[count/2].wpt->longitude, + minlat, maxlat ); + newblock->ch2 = compute_blocks( start+count/2, + count-count/2, start[count/2].wpt->longitude, + maxlon, minlat, maxlat ); + } + if ( newblock->ch1 ) { + newblock->size += newblock->ch1->size; + } + if ( newblock->ch2 ) { + newblock->size += newblock->ch2->size; + } + } + return newblock; +} + +static void +free_blocks( struct blockheader *block ) { + if ( block->ch1 ) free_blocks( block->ch1 ); + if ( block->ch2 ) free_blocks( block->ch2 ); + xfree( block ); +} + +static void +data_write(void) +{ + int ct = waypt_count(); + struct hdr *htable, *bh; + queue *elem, *tmp; + extern queue waypt_head; + waypoint *waypointp; + double minlon = 200; + double maxlon = -200; + double minlat = 200; + double maxlat = -200; + struct blockheader *blocks = NULL; + + htable = xmalloc(ct * sizeof(*htable)); + bh = htable; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + bh->wpt = waypointp; + if ( waypointp->longitude > maxlon ) { + maxlon = waypointp->longitude; + } + if ( waypointp->longitude < minlon ) { + minlon = waypointp->longitude; + } + if ( waypointp->latitude > maxlat ) { + maxlat = waypointp->latitude; + } + if ( waypointp->latitude < minlat ) { + minlat = waypointp->latitude; + } + bh ++; + } + + blocks = compute_blocks( htable, ct, minlon, maxlon, minlat, maxlat ); + write_blocks( file_out, blocks ); + free_blocks( blocks ); + + xfree(htable); +} + +ff_vecs_t tomtom_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + tomtom_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/tools/.cvsignore b/tools/.cvsignore new file mode 100644 index 000000000..bff3bd09a --- /dev/null +++ b/tools/.cvsignore @@ -0,0 +1 @@ +mkcapabilities diff --git a/tools/cleardebug b/tools/cleardebug new file mode 100755 index 000000000..1ee27e11a --- /dev/null +++ b/tools/cleardebug @@ -0,0 +1,5 @@ +#!/bin/sh + +rm /tmp/gpsbabel.debug +touch /tmp/gpsbabel.debug + diff --git a/tools/cvslog b/tools/cvslog new file mode 100644 index 000000000..9ec5899a0 --- /dev/null +++ b/tools/cvslog @@ -0,0 +1 @@ +# cvs log -b -N -d '>2003-09-22' | less +date diff --git a/tools/functions b/tools/functions new file mode 100755 index 000000000..a0fb09362 --- /dev/null +++ b/tools/functions @@ -0,0 +1,41 @@ +function trim_filelist() +{ + sort | + uniq | # remove duplicate lines + sed 's/^[ \t]*//;s/[ \t]*$//' | # remove leading and trailing whitespaces + sed '/^$/d' # drop empty lines +} + +function check_filelist() # check presence of all files +{ + while read f; do + [ -e "$f" ] && continue + echo missing: "$f"; exit 1 + done + exit 0 +} + +function ask_mrproper() +{ + echo "" + echo "--------------------------------------------------" + echo "!!! WARNING !!! WARNING !!! WARNING !!!WARNING !!!" + echo "--------------------------------------------------" + echo "All files they are not part of the CVS source tree" + echo " and they not registered in .filelist-devel" + echo " will be killed." + echo "" + echo -n "Please type yyeess if you are know what you do: " + read answer + test "$answer" != "yyeess" && exit 1 + exit 0 +} + +function ask() # $1=Question $2=Answer for TRUE +{ + echo "" + echo -n "$1 : " + read answer + test "$answer" != "$2" && exit 1 + exit 0 +} diff --git a/tools/gcfg b/tools/gcfg new file mode 100755 index 000000000..031c20831 --- /dev/null +++ b/tools/gcfg @@ -0,0 +1,17 @@ +# Script to configure cross build suitable for inclusion in Earth. +S=. +LDFLAGS=-s \ +CFLAGS=-DXML_UNICODE \ +CC=/usr/local/cross-tools/bin/i386-mingw32msvc-gcc \ +$S/configure --host=i386-pc-mingw32 \ + --without-zlib \ + --disable-shapefile \ + --disable-pdb \ + --disable-csv \ + --disable-filters \ + --without-cet \ + --without-pdb \ + --without-filters \ + --with-expathdr=$S/mingw/includew \ + --with-libexpat=$S/mingw/libw + diff --git a/tools/mac-config b/tools/mac-config new file mode 100755 index 000000000..c986085f1 --- /dev/null +++ b/tools/mac-config @@ -0,0 +1,12 @@ + +case `uname -r` in + 9.0) ;; # 10.3/ + 9.1) ;; # 10.4/Tiger + *) XFLAGS="-mmacosx-version-min=10.4" ;; # 10.5/Leopard +esac +SRC=. +CFLAGS="$XFLAGS -O -arch i386 -arch ppc" \ + LDFLAGS="$XFLAGS -arch i386 -arch ppc" ${SRC}/configure \ + --with-libexpat=${SRC}/mac/lib/libexpat.a \ + --with-expathdr=${SRC}/mac/include + diff --git a/tools/memdebug b/tools/memdebug new file mode 100755 index 000000000..874879944 --- /dev/null +++ b/tools/memdebug @@ -0,0 +1,74 @@ +#!/usr/bin/perl + +sub alloc { + my $addr = shift; + my $file = shift; + my $line = shift; + + if ( $arena{$addr} ) { + ($ofile,$oline) = @{$arena{$addr}}; + print( "duplicate allocation $addr at $file $line\n allocated at $ofile $oline\n" ); + } + if ( $freed{$addr} ) { + delete $freed{$addr}; + } + $arena{$addr} = [$file,$line]; +} + +sub free { + my $addr = shift; + my $file = shift; + my $line = shift; + + if ( $arena{$addr} ) { + $freed{$addr} = [$arena{$addr}->[0], $arena{$addr}->[1], $file, $line]; + delete $arena{$addr}; + } + else { + if ($freed{$addr}) { + ($afile,$aline,$ffile,$fline) = @{$freed{$addr}}; + print( "double free $addr at $file $line\n allocated at $afile $aline\n last freed at $ffile $fline\n" ); + } + else { + print( "freeing unallocated $addr at $file $line\n" ); + } + } +} + +sub unfreed { + for $addr (keys %arena) { + ($file,$line)=@{$arena{$addr}}; + print( "unfreed $addr allocated at $file $line\n" ); + } + undef %arena; + undef %freed; +} + +open(FILE, ") { + chomp; + @args = split(', ',$_); + if ($args[0] eq 'malloc') { + &alloc($args[1], $args[3], $args[4]); + } + if ($args[0] eq 'calloc') { + &alloc($args[1], $args[4], $args[5]); + } + if ($args[0] eq 'strdup') { + &alloc($args[1], $args[3], $args[4]); + } + if ($args[0] eq 'realloc') { + &free($args[2], $args[4], $args[5]); + &alloc($args[1], $args[4], $args[5]); + } + if ($args[0] eq 'free') { + &free($args[1], $args[2], $args[3]); + } + if ($args[0] =~ m/^command/) { + &unfreed; + print "$args[0]\n"; + } +} +&unfreed; +close(FILE); diff --git a/tools/mkcapabilities.in b/tools/mkcapabilities.in new file mode 100755 index 000000000..00848db72 --- /dev/null +++ b/tools/mkcapabilities.in @@ -0,0 +1,42 @@ +# +# mkcapabilities.in is used to create mkcapabilities. +# +./gpsbabel -^2 | sed 's/\&/\&/' | awk -F'\t' ' +function getcap(type, cap, sname, lname) { + if (type == "internal") return + print "" + print "" lname "" + + print " " sname "" + # This is bad... + + printf "" + if (sname == "geo") { + printf "Yes" + } else if (sname == "s_and_t") { + printf "[1][2]" + } else if (sname == "an1") { + printf "Yes" + } + print "" + + + for (i = 1; i <= 6; i++) { + c = substr(cap, i, 1) + printf "" + if (c != ("-")) printf "yes" + printf "\n" + } + print "" +} + +getcap($1, $2, $3, $5) +' > @DOCDIR@capabilities.inc > @DOCDIR@capabilities.inc + +FMTS=`./gpsbabel -^2 | grep -v '^internal' | sed 's/\&/\&/' | awk -F'\t' '{print $3}'` +for f in $FMTS +do + [ ! -f @DOCDIR@/htmldoc-@DOCVERSION@/fmt_${f}.html ] && echo Missing doc for $f +done + +exit 0 diff --git a/tools/mkchangelog b/tools/mkchangelog new file mode 100755 index 000000000..9d1a27d40 --- /dev/null +++ b/tools/mkchangelog @@ -0,0 +1,62 @@ +#!/bin/sh +# +# creates a RPM compatible ChangeLog file from babelweb/changes.html +# (published at http://www.gpsbabel.org) +# +# !!! input from stdin and output to stdout !!! +# + +LANG='POSIX'; export LANG > /dev/null + +sed -e :a -e 's/<[^<]*>/ /g;//g' -e 's/</\ +BEGIN { line=0; item=0; OUTP="" } +/^20[0-9][0-9]-[0-9][0-9]-/ { # this will be work until 2099 + line++ + item=0 + if (length(OUTP) > 0) + { + printf("%s\n", OUTP) + OUTP="" + } + printf("%s", substr($0, 1, 10)) + next +} +{ if (line==0) next } # skip header stuff +{ + item++; + if (item==1) + { + if (length($0) > 0) OUTP=sprintf(" %s:", $0) + next + } + else if (length($0) > 0) + { + OUTP=sprintf("%s %s", OUTP, $0) + next + } +} +END { if (length(OUTP) > 0) printf("%s\n", OUTP) } +' | +sort -r | # keep sure, lines "YYYY-MM-DD ....." are sorted in descending order +uniq | # and remove duplicates +awk ' +BEGIN { TMx=0 } +{ + DT=sprintf("%s %s %s 00 00 00", substr($0, 1, 4), substr($0, 6, 2), substr($0, 9, 2)) + TM=mktime(DT) + if (TM != TMx) + { + TX=strftime("%a %b %d %Y", TM) + printf("* %s http://www.gpsbabel.org\n", TX) + TMx = TM + } + OUTP=substr($0, 11) + while (substr(OUTP, 1, 1) <= " " ) { OUTP=substr(OUTP, 2) } + printf("- %s \n", OUTP) + next +} +' diff --git a/tools/mkchanges b/tools/mkchanges new file mode 100644 index 000000000..3ef2c933c --- /dev/null +++ b/tools/mkchanges @@ -0,0 +1,16 @@ +# cvsps -u +cvsps $* | awk ' +/^Date:/ { + logt = ""; + gsub("/", "-"); + split($0, dte, " "); + + printf "\n%s", dte[2]; + printf "" + } +/^Log:/ { gsub("^Log:", ""); inlog = 1 } +/^Members:/ {printf "%s", logt ; inlog = 0; } +{ if (inlog > 0) { logt = logt $0 ;} } +' | sort -rn | sed "s##\\ +<\/tr>#g" diff --git a/tools/mkdmg b/tools/mkdmg new file mode 100755 index 000000000..19581abbc --- /dev/null +++ b/tools/mkdmg @@ -0,0 +1,40 @@ + +VERSION=$(./gpsbabel -V | awk '/\./ {print $3}') +NAME=GPSBabel+-${VERSION} +UDMG=${NAME}-uncompressed.dmg +DMG=${NAME}.dmg +WORKDIR=/tmp/${NAME}-$$ +QUIET=-quiet + + +checkgpsbabel() { + file $1 | grep -q "2 architectures" || { + echo $1 is not a universal binary. Aborting + exit 1 + } + otool -L $1 | grep expat && { + echo $1 does not staticly link expat. Use tools/mac-config + exit 1 + } +} + + +makedmg() { + mkdir -p $WORKDIR + rm -f ${UDMG} ${DMG} + + trap 'rm -fr $WORKDIR' 0 1 15 + + # Create the image uncompressed based on our preloaded copy. + hdiutil create ${QUIET} -srcfolder mac/dmg-contents -scrub -size 15m ${UDMG} -format UDRW -volname ${NAME} + hdiutil attach ${QUIET} ${UDMG} -noautoopen -mountpoint ${WORKDIR} + + # Copy in the new executable. + cp -p ./gpsbabel ${WORKDIR} + hdiutil detach ${QUIET} ${WORKDIR} + + hdiutil convert ${QUIET} ${UDMG} -format UDZO -imagekey zlib-level=9 -o ${DMG} +} + +checkgpsbabel ./gpsbabel +makedmg diff --git a/tools/mkfilelist b/tools/mkfilelist new file mode 100755 index 000000000..09c9df168 --- /dev/null +++ b/tools/mkfilelist @@ -0,0 +1,51 @@ +#!/bin/sh + +# create filelist using CVS Entries files +# +# Parameter 1: base directory where we're looking for the first CVS directory +# Parameter 2: insert directory name "$2" at the beginning of +# resulting filenames +# +# foo> ./tools/mkfilelist . gpsbabel-1.2.8/ +# +# creates a output like the this: +# +# ... +# gpsbabel-1.2.8/win32/gui-2/options.pas +# gpsbabel-1.2.8/win32/gui-2/utils.pas +# gpsbabel-1.2.8/win32/gui-2/GPSBabelGUI.res +# gpsbabel-1.2.8/win32/GPSBabelGUI.exe +# gpsbabel-1.2.8/copilot.c +# gpsbabel-1.2.8/gcdb.c +# gpsbabel-1.2.8/fatal.c +# ... + +function loop() +{ + test -f "$1/CVS/Entries" || return 0 + + case $1 in + /) return 0;; + esac + + IFS="/" + cat "$1/CVS/Entries" | + while read LINE; do + echo "$LINE" | + ( + read LEAD NAME READ + test "x$NAME" == "x" && continue + case $LEAD in + D) + loop "$1/$NAME/" "$2" + ;; + *) + echo "$2$1/$NAME" + ;; + esac + ) + done + IFS=" " +} + +loop "$1" "$2" | sed -e 's|\/\/|\/|g' -e 's|\.\.|\.|g' -e 's|\.\/||g' diff --git a/tools/mkmoreclean b/tools/mkmoreclean new file mode 100755 index 000000000..624e42779 --- /dev/null +++ b/tools/mkmoreclean @@ -0,0 +1,15 @@ +#!/bin/sh + +# +# delete all files listed in .cvsignore +# + +find . -type d | +while read dirname; do + test -s "$dirname/.cvsignore" || continue + while read filemask; do + test -z "$filemask" && continue + cmd="rm -Rfv $dirname/$filemask" + ${cmd} + done < "$dirname/.cvsignore" +done diff --git a/tools/mkrpm b/tools/mkrpm new file mode 100755 index 000000000..f723b34d7 --- /dev/null +++ b/tools/mkrpm @@ -0,0 +1,52 @@ +#!/bin/sh +# + +WEB=$1 +VERSION=$2 +RELEASE=$3 + +SPEC=gpsbabel.spec +TAR_IGNORE="--exclude CVS" + +if test -x /usr/bin/rpmbuild; then + RPM=rpmbuild +else + RPM=rpm +fi + +test -f gpsbabel.html || exit 1 + +SRC=`pwd` +TEMPDIR=/tmp/gpsbabel-rpm.$$ + +mkdir -p $TEMPDIR +trap "rm -fr $TEMPDIR" 0 1 2 3 15 + +mkdir -p $TEMPDIR/BUILD $TEMPDIR/RPMS $TEMPDIR/SPECS \ + $TEMPDIR/SOURCES $TEMPDIR/SRPMS $TEMPDIR/TMP $TEMPDIR/install + +echo "Generate rpm spec file..." +sh $SRC/tools/mkspec "$WEB" "$VERSION" "$RELEASE" > "$TEMPDIR/SPECS/gpsbabel.spec" +cp -apr ./ $TEMPDIR/TMP/gpsbabel-$VERSION + +# +pushd $TEMPDIR/TMP/gpsbabel-$VERSION +echo "Cleaning source..." +make more-clean > /dev/null 2>&1 +find . -type d -name CVS -exec rm -rf \{\} \; > /dev/null 2>&1 +find . -type d -name "autom4*" -exec rm -rf \{\} \; > /dev/null 2>&1 + +echo "Add needed files..." +cp -ap $SRC/gpsbabel.html ./ +cp -ap $SRC/CHANGELOG ./ + +echo "Create rpm source tarball..." +cd .. +# --verbose +tar --owner=0 --group=0 -czf ../SOURCES/gpsbabel-$VERSION.tgz gpsbabel-$VERSION +echo "And now create rpm packages..." +${RPM} -ba \ + --define "_topdir $TEMPDIR" \ + --define "buildroot $TEMPDIR/install" \ + $TEMPDIR/SPECS/gpsbabel.spec +find ../. -type f -name "*.rpm" -exec cp -apf \{\} /tmp/ \; diff --git a/tools/mkspec b/tools/mkspec new file mode 100755 index 000000000..6c620bdfa --- /dev/null +++ b/tools/mkspec @@ -0,0 +1,56 @@ +#!/bin/sh +# + +WEB=$1 +VERSION=$2 +RELEASE=$3 # may be empty + +REL=`echo $RELEASE | sed 's/^-//'` +test "$REL" == "" && REL=0 + +cat << EOF +Summary: GPSBabel +Name: gpsbabel +Version: $VERSION +Release: $REL +License: GPL +Group: File tools +Source: %{name}-%{version}.tgz +BuildRoot: %{_tmppath}/%{name}-%{version}-build +URL: http://www.gpsbabel.org + +%description +Converts GPS waypoint, route and track data from one format type to another. + + +Authors: +-------- +EOF + +cat AUTHORS + +cat << EOF + +%prep +%setup -q + + +%build +LDFLAGS="-s" ./configure +make + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/bin +install -m 555 gpsbabel %{buildroot}/usr/bin/gpsbabel + +%files +%defattr(-,root,root) +/usr/bin/gpsbabel +%doc README* COPYING CHANGELOG AUTHORS gpsbabel.html + +%changelog +EOF + +cat $WEB/changes.html | tools/mkchangelog > CHANGELOG +cat CHANGELOG diff --git a/tools/release-process b/tools/release-process new file mode 100644 index 000000000..46bbd9f63 --- /dev/null +++ b/tools/release-process @@ -0,0 +1,10 @@ +0) Ensure 'changes' file is up to date. + Regenerate capabilties. (done by 'make doc') + Refresh public web version. +1) Bump version in configure.in. Commit that. +2) Go to empty directory. Check out tree. +3) 'make release' +4) Visit https://sourceforge.net/project/admin/editpackages.php?group_id=58972 + to make new releases public. +5) Send announcemnts to gpsbabel-announce, gpsbabel-misc, gpsbabel-code, + freshmeat, geocaching forums, various yahoo groups (which?) diff --git a/torture_test b/torture_test new file mode 100755 index 000000000..66095cf55 --- /dev/null +++ b/torture_test @@ -0,0 +1,27 @@ + +PNAME=${PNAME:-./gpsbabel} +DIFF=${DIFF:-diff} + +TMPDIR=/tmp/gpsbabel.$$ +mkdir -p $TMPDIR +trap "rm -fr $TMPDIR" 0 1 2 3 15 + +# +# This is nasty. If we have a dictionary handy, treat it as a list of +# waypoints and reduce all the names to eight characters. Fewer chars +# results in lost waypoints currently and that's a defect. +# +DICT=/usr/share/dict/words +if [ -f $DICT ]; +then + WORDS=`cat $DICT | wc -l` + SWORDS=`${PNAME} -i gpsdrive -f $DICT -o gpsdrive,snlen=8 -F /dev/fd/1 | + wc -l` + if [ $WORDS -ne $SWORDS ]; + then + echo "Shortname reduction failed." + exit 1 + fi +fi + +exit 0 diff --git a/tpg.c b/tpg.c new file mode 100644 index 000000000..4fe014ea8 --- /dev/null +++ b/tpg.c @@ -0,0 +1,328 @@ +/* + National Geographic Topo! TPG file support (Waypoints/Routes) + Contributed to gpsbabel by Alex Mottram + + For Topo! version 2.x. Routes are currently not implemented. + + Copyright (C) 2002 Alex Mottram, geo_alexm at cox-internet.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include +#include +#include "jeeps/gpsmath.h" /* for datum conversions */ + +#define MYNAME "TPG" + +#define MAXTPGSTRINGSIZE 256 +#define MAXTPGOUTPUTPINS 65535 + +static gbfile *tpg_file_in; +static gbfile *tpg_file_out; +static short_handle mkshort_handle; +static char *tpg_datum_opt; +static int tpg_datum_idx; + +static unsigned int waypt_out_count; + +static +arglist_t tpg_args[] = { + {"datum", &tpg_datum_opt, "Datum (default=NAD27)", "N. America 1927 mean", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static int +valid_tpg_header(char * header, int len) +{ + unsigned char header_bytes[] = { 0xFF, 0xFF, 0x01, 0x00, 0x0D, + 0x00, 0x43, 0x54, 0x6F, 0x70, + 0x6F, 0x57, 0x61, 0x79, 0x70, + 0x6F, 0x69, 0x6E, 0x74 }; + if (len != 19) { + return (-1); + } + + return memcmp(header_bytes, header, len); +} + +static void +tpg_common_init(void) +{ + tpg_datum_idx = GPS_Lookup_Datum_Index(tpg_datum_opt); + if (tpg_datum_idx < 0) { + fatal(MYNAME ": Datum '%s' is not recognized.\n", tpg_datum_opt); + } +} + +static void +tpg_rd_init(const char *fname) +{ + tpg_common_init(); + tpg_file_in = gbfopen_le(fname, "rb", MYNAME); +} + +static void +tpg_rd_deinit(void) +{ + gbfclose(tpg_file_in); +} + +static void +tpg_wr_init(const char *fname) +{ + tpg_common_init(); + tpg_file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); + waypt_out_count = 0; +} + +static void +tpg_wr_deinit(void) +{ + mkshort_del_handle(&mkshort_handle); + gbfclose(tpg_file_out); +} + +static void +tpg_read(void) +{ + char buff[MAXTPGSTRINGSIZE + 1]; + waypoint *wpt_tmp; + double lat, lon, elev; + double amt; + short int pointcount; + + pointcount = gbfgetint16(tpg_file_in); + + /* the rest of the header */ + gbfread(&buff[0], 19, 1, tpg_file_in); + + if (valid_tpg_header(buff, 19) != 0) { + fatal(MYNAME ": input file does not appear to be a valid .TPG file.\n"); + } + + + while (pointcount--) { + wpt_tmp = waypt_new(); + + /* pascal-like shortname */ + wpt_tmp->shortname = gbfgetpstr(tpg_file_in); + + /* for some very odd reason, signs on longitude are swapped */ + /* coordinates are in NAD27/CONUS datum */ + + /* 8 bytes - longitude, sign swapped */ + lon = gbfgetdbl(tpg_file_in); + + /* 8 bytes - latitude */ + lat = gbfgetdbl(tpg_file_in); + + /* swap sign before we do datum conversions */ + lon *= -1.0; + + /* 2 bytes - elevation in feet */ + elev = FEET_TO_METERS(gbfgetint16(tpg_file_in)); + + /* convert incoming NAD27/CONUS coordinates to WGS84 */ + GPS_Math_Known_Datum_To_WGS84_M( + lat, + lon, + 0.0, + &wpt_tmp->latitude, + &wpt_tmp->longitude, + &amt, + tpg_datum_idx); + + wpt_tmp->altitude = elev; + + + /* 4 bytes? */ + (void) gbfgetint32(tpg_file_in); + + /* pascal-like description */ + wpt_tmp->description = gbfgetpstr(tpg_file_in); + + /* 2 bytes */ + (void) gbfgetint16(tpg_file_in); + + waypt_add(wpt_tmp); + } +} + +static void +tpg_waypt_pr(const waypoint *wpt) +{ + double lon, lat; + double amt; + short int elev; + char tbuf[64]; + char c,ocount; + char *shortname; + char *description; + int i; + + /* these unknown 4 are probably point properties (color, icon, etc..) */ + unsigned char unknown4[] = { 0x78, 0x56, 0x34, 0x12 }; + + /* these 2 appear to be constant across test files */ + unsigned char unknown2[] = { 0x01, 0x80 }; + + /* our personal waypoint counter */ + waypt_out_count++; + + /* this output format pretty much requires a description + * and a shortname + */ + + if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) + shortname = mkshort_from_wpt(mkshort_handle, wpt); + else + shortname = xstrdup(wpt->description); + } else { + /* no description available */ + shortname = xstrdup(""); + } + } else{ + shortname = xstrdup(wpt->shortname); + } + + if (! wpt->description) { + if (shortname) { + description = xstrdup(shortname); + } else { + description = xstrdup(""); + } + } else{ + description = xstrdup(wpt->description); + } + + /* convert lat/long to NAD27/CONUS datum */ + GPS_Math_WGS84_To_Known_Datum_M( + wpt->latitude, + wpt->longitude, + 0.0, + &lat, + &lon, + &amt, + tpg_datum_idx); + + + /* swap the sign back *after* the datum conversion */ + lon *= -1.0; + + /* convert meters back to feets */ + elev = (short int) METERS_TO_FEET(wpt->altitude); + + /* 1 bytes stringsize for shortname */ + c = strlen(shortname); + ocount = 0; + /* + * It's reported the only legal characters are upper case + * A-Z and 0-9. Wow. We have to make two passes: one to + * count and one to output. + */ + for (i = 0; i < c; i++) { + char oc = toupper(shortname[i]); + if (isalnum(oc) || oc == ' ') { + ocount++; + } + } + + gbfwrite(&ocount, 1, 1, tpg_file_out); + + for (i = 0; i < c; i++) { + char oc = toupper(shortname[i]); + if (isalnum(oc) || oc == ' ') { + gbfputc(oc, tpg_file_out); + } + } + + /* 8 bytes - longitude */ + gbfputdbl(lon, tpg_file_out); + + /* 8 bytes - latitude */ + gbfputdbl(lat, tpg_file_out); + + /* 2 bytes - elevation_feet */ + gbfputint16(elev, tpg_file_out); + + /* 4 unknown bytes */ + memset(tbuf, '\0', sizeof(tbuf)); + gbfwrite(unknown4, 1, 4, tpg_file_out); + + /* pascal-like description */ + gbfputpstr(description, tpg_file_out); + + /* and finally 2 unknown bytes */ + + if (waypt_out_count == waypt_count()) { + /* last point gets 0x0000 instead of 0x0180 */ + gbfputint16(0, tpg_file_out); + } else { + gbfwrite(unknown2, 1, 2, tpg_file_out); + } + + xfree(shortname); + xfree(description); +} + +static void +tpg_write(void) +{ + int s; + unsigned char header_bytes[] = { 0xFF, 0xFF, 0x01, 0x00, 0x0D, + 0x00, 0x43, 0x54, 0x6F, 0x70, + 0x6F, 0x57, 0x61, 0x79, 0x70, + 0x6F, 0x69, 0x6E, 0x74 }; + + s = waypt_count(); + + if (global_opts.synthesize_shortnames) { + setshort_length(mkshort_handle, 32); + setshort_whitespace_ok(mkshort_handle, 1); + setshort_mustupper(mkshort_handle, 1); + } + + if (s > MAXTPGOUTPUTPINS) { + fatal(MYNAME ": attempt to output too many points (%d). The max is %d. Sorry.\n", s, MAXTPGOUTPUTPINS); + } + + /* write the waypoint count */ + gbfputint16(s, tpg_file_out); + + /* write the rest of the header */ + gbfwrite(header_bytes, 1, 19, tpg_file_out); + + waypt_disp_all(tpg_waypt_pr); +} + +ff_vecs_t tpg_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + tpg_rd_init, + tpg_wr_init, + tpg_rd_deinit, + tpg_wr_deinit, + tpg_read, + tpg_write, + NULL, + tpg_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/tpo.README.patch b/tpo.README.patch new file mode 100644 index 000000000..048b4c579 --- /dev/null +++ b/tpo.README.patch @@ -0,0 +1,51 @@ +Index: README +=================================================================== +RCS file: /cvsroot/gpsbabel/gpsbabel/README,v +retrieving revision 1.145 +diff -p -u -r1.145 README +--- README 26 Oct 2005 23:54:45 -0000 1.145 ++++ README 31 Oct 2005 22:21:04 -0000 +@@ -467,9 +467,10 @@ THE FORMATS + + TPG + +- National Geographic Topo! Waypoint Format. This filter +- reads and writes .TPG files created by various editions of NG Topo! +- This filter will *not* work with the newer combined .TPO files. ++ National Geographic Topo! Waypoint and Route Format. This ++ format reads and writes .TPG files created by various editions ++ of NG Topo! This filter will *not* work with the newer combined ++ .TPO files. Reading/writing of route data is not supported yet. + + The option 'datum="datum name"' can be used to override the + default of NAD27 ("N. America 1927 mean") which is correct +@@ -478,6 +479,29 @@ THE FORMATS + + Contributed by Alex Mottram. + ++ TPO ++ ++ National Geographic Topo! Track Format. This format reads ++ and writes .TPO files created by various editions of NG Topo! ++ version 2.7.7 or earlier. This format will *not* work with the ++ newer .TPO files (version 3.0 and later) that have TPG data ++ combined into them. ++ ++ When writing TPO files, note that every TOPO! state edition ++ employs a slightly different data format, so you will need to ++ specify which state edition to generate output for. The current ++ supported states are CA, NY, NJ, MA, CT, RI, NH, VT, ME. It's ++ fairly easy to add support for additional states. Instructions ++ are in the source code. ++ ++ Additional options: ++ dumpheader - (0/1) Display the file header bytes (useful when ++ adding support for a new state) ++ state - State map format to write, default=CA ++ ++ Contributed by Steve Chamberlin. ++ ++ + HOLUX + + The Holuxgm-100 (e-fox) gps receiver uses standard compact diff --git a/tpo.c b/tpo.c new file mode 100644 index 000000000..7787e0c21 --- /dev/null +++ b/tpo.c @@ -0,0 +1,1859 @@ +/* + National Geographic Topo! TPO file support. + 2.x support contributed to gpsbabel by Steve Chamberlin. + 3.x support contributed to gpsbabel by Curt Mills. + + Topo! version 2.x: Tracks are implemented. + Topo! version 3.x: Reading of Tracks/Waypoints/Routes is + implemented. Also extracts Map Notes/ + Symbols/Text Labels as Waypoints. + + Copyright (C) 2005 Steve Chamberlin, slc at alum.mit.edu + Portions Copyright (C) 2006 Curtis E. Mills, archer at eskimo dot com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +/* + ***** This format has problems and the author hasn't returned emails + * on it, so we've set the format type to 'ff_type_internal' to make it + * disappear from the various lists... + */ + +/* + TPO format notes: + ----------------- + Most of the ASCII strings embedded in the text will have a + byte-count prepended to the string. Unknown yet whether other + fields have this same byte-count, but so far it doesn't look like + it. + + New format (3.x and later) files begin with a string byte-count + byte and then a string starting with "TOPO! Ver. 3.", like "TOPO! + Ver. 3.3.4". Can contain routes/tracks/waypoints, embedded + images, Map Notes, Symbols, Text Labels, Compass symbols, and + several others. + + Older (pre-3.0) format does not have the above string. Contains + only tracks. Waypoints are saved in a separate .TPG file. + + May contain these strings: + Frmt: String: + ----- -------------------------------- + 2.x "CTopoAzimuth" + 2.x "CTopoBookmark" + 2.x "CTopoGpsRoute". Saved in .tpg files (see tpg.c) + 2.x "CTopoRoute". The actual tracks we parse here. + 2.x "CTopoSymbol" + 2.x/3.x "CTopoText" + 2.x "CTopoWaypoint". Saved in .tpg files (see tpg.c) + 3.x "Notes" + 3.x "PNG." Embedded PNG image containing 2 rows of 40 + symbols each. Starts with signature: 89 50 4e 47 0d + 0a 1a 0a, ends with signature 49 45 4e 44 ae 42 60 82. + 3.x "shapes" + 3.x "arrows" + 3.x "recreation" +*/ + +#include "defs.h" +#include +#include +#include "jeeps/gpsmath.h" /* for datum conversions */ + +#define MYNAME "TPO" + +static char *dumpheader = NULL; +static char *output_state = NULL; + +/* +static +arglist_t tpo2_args[] = { + { "dumpheader", &dumpheader, "Display the file header bytes", + "0", ARGTYPE_BOOL, ARG_NOMINMAX} , + { "state", &output_state, "State map format to write, default=CA", + "CA", ARGTYPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR +}; +*/ +// +// Note that we've disabled the write capabilites for the tpo2 +// format at present. The "testo" tests were failing on some +// platforms and there wasn't anyone willing to work on the problem. +// If this is fixed in the future we can go back to the tpo2_args[] +// above. +// +static +arglist_t tpo2_args[] = { + ARG_TERMINATOR +}; + +static +arglist_t tpo3_args[] = { + ARG_TERMINATOR +}; + + +static gbfile *tpo_file_in; +static gbfile *tpo_file_out; +//static short_handle mkshort_handle; + +static double output_track_lon_scale; +static double output_track_lat_scale; + +static unsigned int track_out_count; +static double first_track_waypoint_lat; +static double first_track_waypoint_lon; +static double track_length; +static double last_waypoint_x; +static double last_waypoint_y; +static double last_waypoint_z; + +/*******************************************************************************/ +/* READ */ +/*******************************************************************************/ + +/* Define a global here that we can query from multiple places */ +float tpo_version = 0.0; + +/* tpo_check_version_string() + Check the first bytes of the file for a version 3.0 header. */ +static void +tpo_check_version_string() +{ + + unsigned char string_size; + char* string_buffer; + char* v3_id_string = "TOPO! Ver"; + + /* read the id string */ + gbfread(&string_size, 1, 1, tpo_file_in); + string_buffer = xmalloc(string_size+1); + gbfread(string_buffer, 1, string_size, tpo_file_in); + + /* terminate the string */ + string_buffer[string_size] = 0; + + /* check for the presence of a 3.0-style id string */ + if (strncmp(v3_id_string, string_buffer, strlen(v3_id_string)) == 0) + { +/* fatal(MYNAME ": gpsbabel can only read TPO version 2.7.7 or below; this file is %s\n", string_buffer); */ +//fprintf(stderr,"gpsbabel can only read TPO version 2.7.7 or below; this file is %s\n", string_buffer); + + gbfseek(tpo_file_in, -(string_size+1), SEEK_CUR); + xfree(string_buffer); + tpo_version = 3.0; /* Really any 3.x version */ + return; + + } + else { + /* We found a version 1.x or 2.x file */ + /* seek back to the beginning of the file */ + gbfseek(tpo_file_in, -(string_size+1), SEEK_CUR); + xfree(string_buffer); + tpo_version = 2.0; /* Really any 1.x or 2.x version */ + return; + } +} + +static void +/* tpo_dump_header_bytes(int header_size) + Write the first header_size bytes of the file to standard output + as a C array definition. */ +tpo_dump_header_bytes(int header_size) +{ + int i; + unsigned char* buffer = (unsigned char*)xmalloc(header_size); + + gbfread(buffer, 1, header_size, tpo_file_in); + + printf("unsigned char header_bytes[] = {\n"); + + for (i=0; irte_name = xstrdup(buff); + + /* zoom level 1-5 visibility flags */ + gbfread(&buff[0], 1, 10, tpo_file_in); + + /* 8 bytes of zeros, meaning unknown */ + gbfread(&buff[0], 1, 8, tpo_file_in); + + /* 4 more unknown bytes, possibly sign flags for the longitude and latitude? */ + gbfread(&buff[0], 1, 4, tpo_file_in); + + /* read the position of the initial track point */ + /* for some very odd reason, signs on longitude are swapped */ + /* coordinates are in NAD27/CONUS datum */ + + /* 8 bytes - longitude, sign swapped */ + first_lon = gbfgetdbl(tpo_file_in); + + /* 8 bytes - latitude */ + first_lat = gbfgetdbl(tpo_file_in); + + /* swap sign before we do datum conversions */ + first_lon *= -1.0; + + /* 8 unknown bytes: seems to be some kind of bounding box info */ + gbfread(&buff[0], 1, 8, tpo_file_in); + + /* number of route points */ + waypoint_count = gbfgetint16(tpo_file_in); + + /* allocate temporary memory for the waypoint deltas */ + lon_delta = (short*)xmalloc(waypoint_count * sizeof(short)); + lat_delta = (short*)xmalloc(waypoint_count * sizeof(short)); + + for (j=0; jlatitude, + &waypoint_temp->longitude, + &amt, + 78); + + /* there is no elevation data for the waypoints */ + waypoint_temp->altitude = 0; + + track_add_wpt(track_temp, waypoint_temp); + } + + /* free temporary memory */ + xfree(lon_delta); + xfree(lat_delta); + } +} + + + + + +//------------------------------------------------------------------- +//------------------------------------------------------------------- + +// This will read 8/16/32 bits in little-endian format depending +// upon the value of the first byte. +// +// For version 3.x files. +// +int tpo_read_int() +{ + unsigned char val; + + val = (unsigned char) gbfgetc(tpo_file_in); + + switch (val) { + + case 0xff: // 32-bit value +//printf("Found 32-bit value indicator: %x\n", val); + return( gbfgetint32(tpo_file_in) ); + break; + + case 0xfe: // 16-bit value +//printf("Found 16-bit value indicator: %x\n", val); + return( gbfgetint16(tpo_file_in) ); + break; + + default: // 8-bit value +//printf("Found 8-bit value: %x\n", val); + return( (int)val ); + break; + } +} + + + + + +// Find variable block of interest in the file. Leaves the file +// pointer pointing after the two 4-byte type/pointer bytes. The +// file pointer should be pointing at the first data byte of the +// block after calling this, which is normally an 8/16/32-bit value +// specifying the number of elements in the block. +// +// Returns -1 if block not found +// 0 if block found +// +// For version 3.x files. +// +int tpo_find_block(unsigned int block_desired) +{ + int block_type; + int block_offset; + + + // Skip 512 byte fixed-length header + block_offset = 512; + + do { + + // Seek to offset from start of file + gbfseek(tpo_file_in, block_offset, SEEK_SET); + + // Read record type + block_type = gbfgetint32(tpo_file_in); +//printf("Block: %08x\tat offset: %08x\n", block_type, block_offset); + + // Read offset to next record + block_offset = gbfgetint32(tpo_file_in); + } + while (block_type != block_desired && block_offset != 0); + + if (block_type == block_desired) + return(0); + else + return(-1); +} + + + + + +// Convert lat/long to normal values, save in waypoint struct +// +// For version 3.x files. +// +waypoint *tpo_convert_ll(int lat, int lon) { + double latitude; + double longitude; + waypoint *waypoint_temp; + + + waypoint_temp = waypt_new(); + + latitude = (double)lat / 0x800000; + longitude = (double)lon / 0x800000; + +//printf("lat: %f\tlon: %f\n", latitude, longitude); + +/* + // Note: We shouldn't need this section of code as the version + // 3.x files are already in WGS84 datum. + // + // Convert incoming NAD27/CONUS coordinates to WGS84, Molodensky + // transform. + // + GPS_Math_Known_Datum_To_WGS84_M( + latitude, // Source latitude + longitude, // Source longitude + 0.0, // Source height (meters) + &waypoint_temp->latitude, // Dest latitude + &waypoint_temp->longitude, // Dest longitude + &height, // Dest height (meters) + 78); +*/ + + waypoint_temp->latitude = latitude; + waypoint_temp->longitude = longitude; + +//printf("lat: %f\tlon: %f\tNew Height: %f\n", waypoint_temp->latitude, waypoint_temp->longitude, height); + + return(waypoint_temp); +} + + + + + +// Track decoder for version 3.x files. This block contains tracks +// (called "freehand routes" or just "routes" in Topo). +// +void tpo_process_tracks(void) +{ + unsigned int track_count; + unsigned int ii; + + +//printf("Processing Tracks...\n"); + + // Find block 0x060000 (free-hand routes) + if (tpo_find_block(0x060000)) + return; + + // Read the number of tracks. Can be 8/16/32-bit value. + track_count = tpo_read_int(); + +//printf("Total Tracks: %d\n", track_count); + + if (track_count == 0) + return; + + // Read/process each track in the file + // + for (ii = 0; ii < track_count; ii++) { + unsigned int line_type; + unsigned int track_number; + unsigned int track_length; + unsigned int name_length; + char *track_name; + unsigned int track_byte_count; + int llvalid; + unsigned char *buf; + int lonscale; + int latscale; + int waypoint_count = 0; + int lat = 0; + int lon = 0; + unsigned int jj; + route_head* track_temp; + + + // Allocate the track struct + track_temp = route_head_alloc(); + track_add_head(track_temp); + +//UNKNOWN DATA LENGTH + line_type = tpo_read_int(); + + // Can be 8/16/32-bit value + track_number = tpo_read_int(); + + // Can be 8/16/32-bit value + track_length = tpo_read_int(); + +//UNKNOWN DATA LENGTH + name_length = tpo_read_int(); + + if (name_length) { + track_name = xmalloc(name_length+1); + track_name[0] = '\0'; + gbfread(track_name, 1, name_length, tpo_file_in); + track_name[name_length] = '\0'; // Terminator + } + else { // Assign a generic track name + track_name = xmalloc(15); + sprintf(track_name, "TRK %d", ii+1); + } + track_temp->rte_name = track_name; +//printf("\nTrack Name: %s ", track_name); + + // Route description +// track_temp->rte_desc = NULL; + + // Route number + track_temp->rte_num = ii+1; + +//UNKNOWN DATA LENGTH + track_byte_count = tpo_read_int(); + + // Read the number of bytes specified for the track. These + // contain scaling factors, long/lat's, and offsets from + // those long/lat's. First will be a long/lat (8 bytes). + // Keep track of the bytes as we go so that we know how many + // we've read. We need to do this so that we start at the + // proper place for the next track. + + // Read the track bytes into a buffer + buf = xmalloc(track_byte_count); + gbfread(buf, 1, track_byte_count, tpo_file_in); + + latscale=0; + lonscale=0; + + // Process the track bytes + llvalid = 0; + for (jj = 0; jj < track_byte_count; ) { + waypoint* waypoint_temp; + + // Time to read a new latlong? + if (!llvalid) { + + lon = le_read32(buf+jj); + jj+=4; + + lat = le_read32(buf+jj); + jj+=4; + +//printf("L"); + + // Peek to see if next is a lonscale. Note that it + // can begin with 0x88, which is confusing. Here we + // allow up to 16-bits of offset, so two of the + // bytes must be 0x00 for us to recognize it. + if(jj+3>4]; + lat+=latscale*scarray[(buf[jj]&0xf)]; +//printf("."); + jj++; + + waypoint_temp = tpo_convert_ll(lat, lon); + route_add_wpt(track_temp, waypoint_temp); + waypoint_count++; + } + } + track_temp->rte_waypt_ct = waypoint_count; + + xfree(buf); + } +//printf("\n"); +} + + + + + +// Global index to waypoints, needed for routes, filled in by +// tpo_process_waypoints. +// +// For version 3.x files. +// +waypoint** tpo_wp_index; +unsigned int tpo_index_ptr = 0; + + + + + +// Waypoint decoder for version 3.x files. +// +void tpo_process_waypoints(void) +{ + unsigned int waypoint_count; + unsigned int ii; + + +//printf("Processing Waypoints...\n"); + + // Find block 0x0e0000 (GPS-Waypoints) + if (tpo_find_block(0x0e0000)) + return; + + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); + +//printf("Total Waypoints: %d\n", waypoint_count); + + // Fetch storage for the waypoint index (needed later for + // routes) + tpo_wp_index = (waypoint **)xmalloc(sizeof(waypoint *) * waypoint_count); + + if (waypoint_count == 0) + return; + + // Read/process each waypoint in the file + for (ii = 0; ii < waypoint_count; ii++) { + waypoint* waypoint_temp; + waypoint* waypoint_temp2; + unsigned int name_length; + char *waypoint_name; + int lat; + int lon; + int altitude; + + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); // 0x00 + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); // 0x00 + +//UNKNOWN DATA LENGTH + // Fetch name length + name_length = tpo_read_int(); +//printf("\nName Length: %d\n", name_length); + if (name_length) { + waypoint_name = xmalloc(name_length+1); + waypoint_name[0] = '\0'; + gbfread(waypoint_name, 1, name_length, tpo_file_in); + waypoint_name[name_length] = '\0'; // Terminator + } + else { // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "WPT %d", ii+1); + } +//printf("\tWaypoint Name: %s\n", waypoint_name); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + lon = gbfgetint32(tpo_file_in); + lat = gbfgetint32(tpo_file_in); + + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); + + // Assign the waypoint name + waypoint_temp->shortname = waypoint_name; + + // Grab the altitude in meters + altitude = gbfgetint32(tpo_file_in); + if (altitude == 0xfffd000c) // Unknown altitude + altitude = 0; + waypoint_temp->altitude = altitude / 100; // Meters +//printf("\tAltitude: %1.0f meters\n", waypoint_temp->altitude); + +//UNKNOWN DATA LENGTH + // Fetch comment length + name_length = tpo_read_int(); +//printf("\tComment length: %d\n", name_length); + if (name_length) { + char *comment; + + comment = xmalloc(name_length+1); + comment[0] = '\0'; + gbfread(comment, 1, name_length, tpo_file_in); + comment[name_length] = '\0'; // Terminator + waypoint_temp->description = comment; +//printf("\tComment: %s\n", waypoint_name); + } + else { +// waypoint_temp->description = NULL; + } + +// waypoint_temp->notes = NULL; +// waypoint_temp->url = NULL; +// waypoint_temp->url_link_text = NULL; + + // For routes (later), we need a duplicate of each waypoint + // indexed by the order we read them in. + waypoint_temp2 = waypt_dupe(waypoint_temp); + + // Attach the copy to our index + tpo_wp_index[tpo_index_ptr++] = waypoint_temp2; + + // Add the original waypoint to the chain of waypoints + waypt_add(waypoint_temp); + +//UNKNOWN DATA LENGTH +// (void)tpo_read_int(); + (void) gbfgetc(tpo_file_in); + +//UNKNOWN DATA LENGTH +// (void)tpo_read_int(); + (void) gbfgetc(tpo_file_in); + +//UNKNOWN DATA LENGTH +// (void)tpo_read_int(); + (void) gbfgetc(tpo_file_in); + +//UNKNOWN DATA LENGTH +// (void)tpo_read_int(); + (void) gbfgetc(tpo_file_in); + } +} + + + + + +// Map Notes decoder for version 3.x files. +// +void tpo_process_map_notes(void) +{ + unsigned int waypoint_count; + unsigned int ii; + + +//printf("Processing Map Notes...\n"); + + // Find block 0x090000 (Map Notes) + if (tpo_find_block(0x090000)) { + return; + } + + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); + +//printf("Elements: %d\n", waypoint_count); + + if (!waypoint_count) { + return; + } + + // Process each waypoint + for (ii = 0; ii < waypoint_count; ii++) { + int lat; + int lon; + unsigned int name_length; + char *waypoint_name; + waypoint* waypoint_temp; + unsigned int num_bytes; + unsigned int jj; + + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + lon = gbfgetint32(tpo_file_in); + lat = gbfgetint32(tpo_file_in); + + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); + + // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "NOTE %d", ii+1); +//printf("Waypoint Name: %s\t\t", waypoint_name); + waypoint_temp->shortname = waypoint_name; + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + // Fetch comment length + name_length = tpo_read_int(); + if (name_length) { + char *comment; + + comment = xmalloc(name_length+1); + comment[0] = '\0'; + gbfread(comment, 1, name_length, tpo_file_in); + comment[name_length] = '\0'; // Terminator + waypoint_temp->description = comment; +//printf("Comment: %s\n", comment); + } + else { +// waypoint_temp->description = NULL; + } + +// waypoint_temp->url_link_text = NULL; + + // Length of text for external path. If non-zero, skip past + // the text. +//UNKNOWN DATA LENGTH + name_length = tpo_read_int(); +//printf("name_length: %x\n", name_length); + if (name_length) { + char *notes; + + notes = xmalloc(name_length+1); + notes[0] = '\0'; + gbfread(notes, 1, name_length, tpo_file_in); + notes[name_length] = '\0'; // Terminator + waypoint_temp->url = notes; +//printf("Notes: %s\n", notes); + } + + // Length of text for image path. If non-zero, skip past + // the text. +//UNKNOWN DATA LENGTH + name_length = tpo_read_int(); + if (name_length) { + char *notes; + + notes = xmalloc(name_length+1); + notes[0] = '\0'; + gbfread(notes, 1, name_length, tpo_file_in); + notes[name_length] = '\0'; // Terminator + waypoint_temp->url = notes; +//printf("Notes: %s\n", notes); + } + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + // Number of bytes to skip until next element or end of + // block. May be 8/16/32 bits. + num_bytes = tpo_read_int(); +//printf("num_bytes: %x\n", num_bytes); + for (jj = 0; jj < num_bytes; jj++) { + (void) gbfgetc(tpo_file_in); // Skip bytes + } + + // Can be 8/16/32 bits + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + // Add the waypoint to the chain of waypoints + waypt_add(waypoint_temp); + } +} + + + + + +// Symbols decoder for version 3.x files. +// +void tpo_process_symbols(void) +{ + unsigned int waypoint_count; + unsigned int ii; + + +//printf("Processing Symbols...\n"); + + // Find block 0x040000 (Symbols) + if (tpo_find_block(0x040000)) + return; + + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); + +//printf("Elements: %d\n", waypoint_count); + + if (!waypoint_count) { + return; + } + + // Process each waypoint + for (ii = 0; ii < waypoint_count; ii++) { + int lat; + int lon; + char *waypoint_name; + waypoint* waypoint_temp; + + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + lon = gbfgetint32(tpo_file_in); + lat = gbfgetint32(tpo_file_in); + + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); + + // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "SYM %d", ii+1); +//printf("Waypoint Name: %s\n", waypoint_name); + waypoint_temp->shortname = waypoint_name; + +// waypoint_temp->description = NULL; +// waypoint_temp->notes = NULL; +// waypoint_temp->url = NULL; +// waypoint_temp->url_link_text = NULL; + + // Add the waypoint to the chain of waypoints + waypt_add(waypoint_temp); + } +} + + + + + +// Text Labels decoder for version 3.x files. +// +void tpo_process_text_labels(void) +{ + unsigned int waypoint_count; + unsigned int ii; + + +//printf("Processing Text Labels...\n"); + + // Find block 0x080000 (Text Labels) + if (tpo_find_block(0x080000)) + return; + + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); + +//printf("Elements: %d\n", waypoint_count); + + if (!waypoint_count) { + return; + } + + // Process each waypoint + for (ii = 0; ii < waypoint_count; ii++) { + int jj; + int lat; + int lon; + unsigned int name_length; + char *waypoint_name; + waypoint* waypoint_temp; + + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + lon = gbfgetint32(tpo_file_in); + lat = gbfgetint32(tpo_file_in); + + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); + + // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "TXT %d", ii+1); +//printf("Waypoint Name: %s\t\t", waypoint_name); + waypoint_temp->shortname = waypoint_name; + + for (jj = 0; jj < 16; jj++) { +//UNKNOWN DATA LENGTH + (void) gbfgetc(tpo_file_in); + } + + // Fetch comment length +//UNKNOWN DATA LENGTH + name_length = tpo_read_int(); + if (name_length) { + char *comment; + + comment = xmalloc(name_length+1); + comment[0] = '\0'; + gbfread(comment, 1, name_length, tpo_file_in); + comment[name_length] = '\0'; // Terminator + waypoint_temp->description = comment; +//printf("Comment: %s\n", comment); + } + else { +// waypoint_temp->description = NULL; + } + +// waypoint_temp->notes = NULL; +// waypoint_temp->url = NULL; +// waypoint_temp->url_link_text = NULL; + + // Add the waypoint to the chain of waypoints + waypt_add(waypoint_temp); + } +} + + + + + +// Route decoder for version 3.x files. +// +// We depend on tpo_wp_index[] having been malloc'ed and filled-in +// with pointers to waypoint objects by tpo_process_waypoints() +// function above. +// +void tpo_process_routes(void) +{ + unsigned int route_count; + unsigned int ii; + + +//printf("Processing Routes...\n"); + + // Find block 0x0f0000 (GPS-Routes) + if (tpo_find_block(0x0f0000)) + return; + + // Read the number of routes. 8/16/32-bit value + route_count = tpo_read_int(); + +//printf("Total Routes: %d\n", route_count); + + if (route_count == 0) + return; + + // Read/process each route in the file + // + for (ii = 0; ii < route_count; ii++) { + unsigned int name_length = 0; + char *route_name; + unsigned int jj; + unsigned int waypoint_cnt; + route_head* route_temp; + + + // Allocate the route struct + route_temp = route_head_alloc(); + route_add_head(route_temp); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + // Fetch name length + name_length = tpo_read_int(); + if (name_length) { + route_name = xmalloc(name_length+1); + route_name[0] = '\0'; + gbfread(route_name, 1, name_length, tpo_file_in); + route_name[name_length] = '\0'; // Terminator + } + else { // Assign a generic route name + route_name = xmalloc(15); + sprintf(route_name, "RTE %d", ii+1); + } + route_temp->rte_name = route_name; +//printf("Route Name: %s\n", route_name); + +//UNKNOWN DATA LENGTH + // Comment? + (void)tpo_read_int(); +// gbfgetc(tpo_file_in); +// route_temp->rte_desc = NULL; + + route_temp->rte_num = ii+1; + + // Fetch the number of waypoints in this route. 8/16/32-bit + // value. + waypoint_cnt = tpo_read_int(); + + route_temp->rte_waypt_ct = waypoint_cnt; + + // Run through the list of waypoints, look up each in our + // index, then add the waypoint to this route. + // + for (jj = 0; jj < waypoint_cnt; jj++) { + waypoint* waypoint_temp; + unsigned char val; + + +//UNKNOWN DATA LENGTH + // Fetch the index to the waypoint + val = tpo_read_int(); +//printf("val: %x\t\t", val); + + // Duplicate a waypoint from our index of waypoints. + waypoint_temp = waypt_dupe(tpo_wp_index[val-1]); + + // Add the waypoint to the route + route_add_wpt(route_temp, waypoint_temp); + } +//printf("\n"); + } + + // Free the waypoint index, we don't need it anymore. + for (ii = 0; ii < tpo_index_ptr; ii++) { + if (tpo_wp_index[ii]->shortname) + xfree(tpo_wp_index[ii]->shortname); + if (tpo_wp_index[ii]->description) + xfree(tpo_wp_index[ii]->description); + xfree(tpo_wp_index[ii]); + } + + // Free the index array itself + xfree(tpo_wp_index); +} + + + + + +// Compass decoder for version 3.x files. +// +void tpo_process_compass(void) +{ + + // Not implemented yet +} + + + + + +// Decoder for version 3.x files. These files have "tracks" +// (called "freehand routes" or just "routes" in Topo), "waypoints", +// and "gps-routes". We intend to read all three types. +// +void tpo_read_3_x(void) +{ + + if (doing_trks) { +//printf("Processing Tracks\n"); + tpo_process_tracks(); + } + + if (doing_wpts || doing_rtes) { +//printf("Processing Waypoints\n"); + tpo_process_waypoints(); + } + + if (doing_rtes) { + // + // Note: To process routes we _MUST_ process waypoints + // first! This creates the index of waypoints that we need + // for routes. + // +//printf("Processing Routes\n"); + tpo_process_routes(); + } + + if (doing_wpts) { + // + // Other blocks in the file have waypoint-type information + // in them. Map Notes, Symbols, and Text Labels. We + // process those here and add them to the end of the + // waypoint list. + // +//printf("Processing Map Notes\n"); + tpo_process_map_notes(); + +//printf("Processing Symbols\n"); + tpo_process_symbols(); + +//printf("Processing Text Labels\n"); + tpo_process_text_labels(); + +//printf("Processing Compass Symbols\n"); +// tpo_process_compass(); + + } +} + + + + + +//------------------------------------------------------------------- +//------------------------------------------------------------------- + + + + + +static void +tpo_read(void) +{ + + if (tpo_version == 2.0) { +//printf("\nFound a version 2.x file\n"); + tpo_read_2_x(); + } + else if (tpo_version == 3.0) { +//printf("\nFound a version 3.x file\n"); + tpo_read_3_x(); + } + else { + fatal(MYNAME ": gpsbabel can only read TPO versions through 3.x.x\n"); + } +} + + + + + +/*******************************************************************************/ +/* WRITE */ +/*******************************************************************************/ + +/* tpo_write_file_header() + Write the appropriate header for the desired TOPO! state. + + National Geographic sells about 75 different state and regional software + programs called TOPO! that use the TPO format. Each one uses a different + header data sequence. The header contains the name of the state maps, as well + as some map scaling information and other data. In most cases, you can't open + a TPO file created by a different state/regional version of TOPO! than the one + you're using yourself. When writing a TPO file, it is therefore necessary to + specify what TOPO! state product to create the file for. I believe that the + TOPO! regional products can open TPO files created by the TOPO! state products + as long as the track data is within the area covered by the regional product. + As a result, it's only necessary to decide what state product output format to + use. + + TO ADD SUPPORT FOR ANOTHER STATE: + 1. Obtain an example .tpo file generated by the state product for which you wish + to add support. National Geographic MapXchange (http://maps.nationalgeographic.com/topo/search.cfm) + is a good source of .tpo files. + 2. Run gpsbabel using the "dumpheader" option of the TPO format converter, and + specifying a dummy output file. For example: + gpsbabel -t -i tpo,dumpheader=1 -f sample_file.tpo -o csv -F dummy.txt + This will write a snippet of C code containing the header bytes to the shell window. + 3. Add a new if() clause to tpo_write_file_header(). Copy the header bytes definition + from the previous step. + 4. Recompile gpsbabel. + 5. You should now be able write TPO ouput in the new state's format. For example, if + you added support for Texas: + gpsbabel -t -i gpx -f input.gpx -o tpo,state="TX" -F output.tpo */ +static void +tpo_write_file_header() +{ + /* force upper-case state name */ + strupper(output_state); + + if (strncmp("CA", output_state, 2) == 0) { + + unsigned char header_bytes[] = { + 0x18, 0x43, 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, + 0x6E, 0x69, 0x61, 0x20, 0x53, 0x68, 0x61, 0x64, + 0x65, 0x64, 0x20, 0x52, 0x65, 0x6C, 0x69, 0x65, + 0x66, 0x03, 0x43, 0x41, 0x31, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x5C, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x27, 0x43, 0x3A, 0x5C, + 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, + 0x46, 0x69, 0x6C, 0x65, 0x73, 0x5C, 0x54, 0x4F, + 0x50, 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, + 0x44, 0x41, 0x54, 0x41, 0x5C, 0x43, 0x41, 0x5F, + 0x44, 0x30, 0x31, 0x5C, 0x20, 0x43, 0x3A, 0x5C, + 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, + 0x46, 0x69, 0x6C, 0x65, 0x73, 0x5C, 0x54, 0x4F, + 0x50, 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, + 0x44, 0x41, 0x54, 0x41, 0x5C, 0x12, 0x43, 0x3A, + 0x5C, 0x54, 0x4F, 0x50, 0x4F, 0x21, 0x5C, 0x54, + 0x50, 0x4F, 0x5F, 0x44, 0x41, 0x54, 0x41, 0x5C, + 0x00, 0x00, 0x00, 0xDC, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x32, 0x30, 0x33, 0x30, 0x33, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x33, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x34, 0x30, 0x34, 0x30, 0x34, 0x30, 0x34, + 0x30, 0x36, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x34, 0x30, 0x36, + 0x30, 0x36, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, + 0x30, 0x37, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, + 0x30, 0x35, 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, + 0x30, 0x38, 0x30, 0x38, 0x30, 0x39, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, + 0x31, 0x30, 0x30, 0x38, 0x30, 0x38, 0x30, 0x38, + 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, + 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, + 0x30, 0x39, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x30, 0x39, 0x30, 0x39, + 0x0D, 0x55, 0x6E, 0x69, 0x74, 0x65, 0x64, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, 0xBC, 0x23, + 0x63, 0xB5, 0xF9, 0x3A, 0x50, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x50, 0x40, 0x22, 0xE2, + 0xE6, 0x54, 0x32, 0x28, 0x22, 0x40, 0x0A, 0x43, + 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, 0x6E, 0x69, + 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5C, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x40, 0x16, 0x2A, 0x47, 0x65, 0x6E, 0x65, 0x72, + 0x61, 0x6C, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4D, 0x61, 0x70, + 0x00, 0x09, 0x3D, 0x00, 0x0C, 0x43, 0x41, 0x31, + 0x5F, 0x4D, 0x41, 0x50, 0x31, 0x5C, 0x53, 0x31, + 0x4C, 0xAF, 0x02, 0x15, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x26, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x40, 0x84, 0x00, 0x78, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16, + 0x2A, 0x4E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x61, + 0x6C, 0x20, 0x41, 0x74, 0x6C, 0x61, 0x73, 0x20, + 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0xE8, 0x32, + 0x0D, 0x00, 0x02, 0x44, 0x41, 0x23, 0x01, 0x6C, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x3C, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x10, 0x2A, 0x35, 0x30, 0x30, + 0x4B, 0x20, 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, + 0x72, 0x69, 0x65, 0x73, 0xC0, 0xFE, 0x04, 0x00, + 0x02, 0x44, 0x46, 0x00, 0x01, 0x40, 0x01, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0x28, + 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x10, 0x2A, 0x31, 0x30, 0x30, 0x4B, 0x20, + 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, + 0x65, 0x73, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x44, + 0x4B, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x2D, 0x00, 0x2D, + 0x00, 0x0C, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x10, + 0x2A, 0x37, 0x2E, 0x35, 0x27, 0x20, 0x4D, 0x61, + 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x0F, 0x3C, 0x00, 0x00, 0x02, 0x44, 0x51, 0x00, + 0x00, 0x00, 0x01, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x99, 0x3F, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x89, 0x3F, 0x5A, 0x00, 0x2D, 0x00, 0x0D, + 0x00, 0x01, 0x00, 0x28, 0x00 + }; + + gbfwrite(header_bytes, sizeof(header_bytes), 1, tpo_file_out); + } + else if (strncmp("CT", output_state, 2) == 0 || + strncmp("MA", output_state, 2) == 0 || + strncmp("ME", output_state, 2) == 0 || + strncmp("NJ", output_state, 2) == 0 || + strncmp("NH", output_state, 2) == 0 || + strncmp("NY", output_state, 2) == 0 || + strncmp("RI", output_state, 2) == 0 || + strncmp("VT", output_state, 2) == 0) { + /* These 8 states are all covered in a single "Northeast" title */ + + unsigned char header_bytes[] = { + 0x1E, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61, + 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x55, 0x53, + 0x41, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x64, + 0x20, 0x52, 0x65, 0x6C, 0x69, 0x65, 0x66, 0x03, + 0x4E, 0x45, 0x31, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x50, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x43, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0B, 0x44, 0x3A, 0x5C, 0x4E, 0x45, + 0x31, 0x5F, 0x44, 0x30, 0x31, 0x5C, 0x12, 0x43, + 0x3A, 0x5C, 0x54, 0x4F, 0x50, 0x4F, 0x21, 0x5C, + 0x54, 0x50, 0x4F, 0x5F, 0x44, 0x41, 0x54, 0x41, + 0x5C, 0x12, 0x45, 0x3A, 0x5C, 0x54, 0x4F, 0x50, + 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, 0x44, + 0x41, 0x54, 0x41, 0x5C, 0x00, 0x00, 0x00, 0xFF, + 0x18, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37, + 0x30, 0x37, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x34, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, + 0x30, 0x37, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x30, 0x33, + 0x30, 0x34, 0x30, 0x34, 0x30, 0x35, 0x30, 0x35, + 0x30, 0x36, 0x30, 0x36, 0x30, 0x36, 0x30, 0x36, + 0x30, 0x36, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x33, 0x30, 0x33, 0x30, 0x34, 0x30, 0x34, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x36, + 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, + 0x30, 0x32, 0x30, 0x32, 0x30, 0x33, 0x30, 0x33, + 0x30, 0x38, 0x30, 0x38, 0x30, 0x38, 0x30, 0x39, + 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x33, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, + 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, + 0x31, 0x30, 0x31, 0x30, 0x30, 0x39, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x0D, 0x55, 0x6E, 0x69, 0x74, 0x65, + 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x4E, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x50, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x40, + 0x10, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61, + 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x55, 0x53, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x48, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x50, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, + 0x40, 0x16, 0x2A, 0x47, 0x65, 0x6E, 0x65, 0x72, + 0x61, 0x6C, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4D, 0x61, 0x70, + 0x00, 0x09, 0x3D, 0x00, 0x0C, 0x4E, 0x45, 0x31, + 0x5F, 0x4D, 0x41, 0x50, 0x31, 0x5C, 0x53, 0x31, + 0x4C, 0x68, 0x03, 0x16, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2C, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x40, 0x8C, 0x00, 0x64, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16, + 0x2A, 0x4E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x61, + 0x6C, 0x20, 0x41, 0x74, 0x6C, 0x61, 0x73, 0x20, + 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0xE8, 0x32, + 0x0D, 0x00, 0x02, 0x44, 0x41, 0x0B, 0x01, 0x6C, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x3C, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x10, 0x2A, 0x35, 0x30, 0x30, + 0x4B, 0x20, 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, + 0x72, 0x69, 0x65, 0x73, 0xC0, 0xFE, 0x04, 0x00, + 0x02, 0x44, 0x46, 0xEA, 0x00, 0x40, 0x01, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0x28, + 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x10, 0x2A, 0x31, 0x30, 0x30, 0x4B, 0x20, + 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, + 0x65, 0x73, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x44, + 0x4B, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x2D, 0x00, 0x2D, + 0x00, 0x0C, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x10, + 0x2A, 0x37, 0x2E, 0x35, 0x27, 0x20, 0x4D, 0x61, + 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x0F, 0x3C, 0x00, 0x00, 0x02, 0x44, 0x51, 0x00, + 0x00, 0x00, 0x01, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x99, 0x3F, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x89, 0x3F, 0x5A, 0x00, 0x2D, 0x00, 0x0D, + 0x00, 0x01, 0x00, 0x28, 0x00 + }; + + gbfwrite(header_bytes, sizeof(header_bytes), 1, tpo_file_out); + } + + else { + fatal(MYNAME ": writing ouput for state \"%s\" is not currently supported.\n", output_state); + } +} + +static void +tpo_track_hdr(const route_head *rte) +{ + double amt; + unsigned char temp_buffer[8]; + unsigned char visibility_flags[] = { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 }; + unsigned char unknown1[] = { 0xFF, 0x00, 0x00, 0x00 }; + unsigned char bounding_box[8] = { 0x00, 0x80, 0x00, 0x80, 0xFF, 0x7F, 0xFF, 0x7F }; + + waypoint* first_track_waypoint = (waypoint*) QUEUE_FIRST(&rte->waypoint_list); + + /* zoom level 1-5 visibility flags */ + gbfwrite(visibility_flags, 1, sizeof(visibility_flags), tpo_file_out); + + /* 8 bytes of zeros, meaning unknown */ + memset(temp_buffer, 0, sizeof(temp_buffer)); + gbfwrite(temp_buffer, 1, sizeof(temp_buffer), tpo_file_out); + + /* 4 more unknown bytes, possibly sign flags for the longitude and latitude? */ + gbfwrite(unknown1, 1, sizeof(unknown1), tpo_file_out); + + /* the starting point of the route */ + /* convert lat/long to NAD27/CONUS datum */ + GPS_Math_WGS84_To_Known_Datum_M( + first_track_waypoint->latitude, + first_track_waypoint->longitude, + first_track_waypoint->altitude, + &first_track_waypoint_lat, + &first_track_waypoint_lon, + &amt, + 78); + + /* swap the sign back *after* the datum conversion */ + first_track_waypoint_lon *= -1.0; + + /* Compute this track's scaling factors: Used for scaling each track point and then + later written out to the track footer. These are approximately the ratios between + pixels and degrees when viewing the 1:24000 map in TOPO!. In practice, it doesn't + appear to be necessary that they be correct, as long as the same values are used + for doing the scaling and for writing into the track footer data. */ + output_track_lat_scale = 4.8828125e-005; /* TOPO! appears to use a constant lat scale */ + output_track_lon_scale = output_track_lat_scale / cos(GPS_Math_Deg_To_Rad(first_track_waypoint_lat)); + + /* 8 bytes - longitude */ + gbfputdbl(first_track_waypoint_lon, tpo_file_out); + + /* 8 bytes - latitude */ + gbfputdbl(first_track_waypoint_lat, tpo_file_out); + + /* 8 bytes: seems to be bounding box info */ + gbfwrite(bounding_box, 1, sizeof(bounding_box), tpo_file_out); + + /* number of route points */ + gbfputint16(rte->rte_waypt_ct, tpo_file_out); + + /* initialize the track length computation */ + track_length = 0; + GPS_Math_WGS84LatLonH_To_XYZ( + first_track_waypoint->latitude, + first_track_waypoint->longitude, + 0.0, + &last_waypoint_x, + &last_waypoint_y, + &last_waypoint_z); +} + +static void +tpo_track_disp(const waypoint *waypointp) +{ + double lat, lon, amt, x, y, z; + short lat_delta, lon_delta; + +/* fprintf(stderr, "%f/%f\n", waypointp->latitude, waypointp->longitude); */ + + /* convert lat/lon position to XYZ meters */ + GPS_Math_WGS84LatLonH_To_XYZ( + waypointp->latitude, + waypointp->longitude, + 0.0, + &x, + &y, + &z); + + /* increase the track length by the 3D length of last track segment in feet */ + track_length += METERS_TO_FEET(sqrt( + (x - last_waypoint_x) * (x - last_waypoint_x) + + (y - last_waypoint_y) * (y - last_waypoint_y) + + (z - last_waypoint_z) * (z - last_waypoint_z))); + last_waypoint_x = x; + last_waypoint_y = y; + last_waypoint_z = z; + + /* convert lat/long to NAD27/CONUS datum */ + GPS_Math_WGS84_To_Known_Datum_M( + waypointp->latitude, + waypointp->longitude, + waypointp->altitude, + &lat, + &lon, + &amt, + 78); + + /* swap the sign back *after* the datum conversion */ + lon *= -1.0; + + /* longitude delta from first route point */ + lon_delta = (short)((first_track_waypoint_lon - lon) / output_track_lon_scale); + gbfputint16(lon_delta, tpo_file_out); + + /* latitude delta from first route point */ + lat_delta = (short)((first_track_waypoint_lat - lat) / output_track_lat_scale); + gbfputint16(lat_delta, tpo_file_out); + +/* +fprintf(stderr, "%f %f: %x %x - %f %f %f / %f\n", lon, lat, lon_delta, lat_delta, first_track_waypoint_lat, lat, output_track_lat_scale, (first_track_waypoint_lat - lat) ); +*/ + +} + +static void +tpo_track_tlr(const route_head *rte) +{ + unsigned char unknown1[] = { 0x06, 0x00 }; + + unsigned char continue_marker[] = { 0x01, 0x80 }; + unsigned char end_marker[] = { 0x00, 0x00 }; + + /* pixel to degree scaling factors */ + gbfputdbl(output_track_lon_scale, tpo_file_out); + gbfputdbl(output_track_lat_scale, tpo_file_out); + + /* 4 bytes: the total length of the route */ + gbfputint32(track_length, tpo_file_out); + + /* 2 unknown bytes */ + gbfwrite(unknown1, 1, sizeof(unknown1), tpo_file_out); + + /* the last track ends with 0x0000 instead of 0x0180 */ + track_out_count++; + if (track_out_count == track_count()) { + gbfwrite(end_marker, 1, sizeof(end_marker), tpo_file_out); + } else { + gbfwrite(continue_marker, 1, sizeof(continue_marker), tpo_file_out); + } +} + +static void +tpo_wr_init(const char *fname) +{ + if (doing_wpts || doing_rtes) + { + fatal(MYNAME ": this file format only supports tracks, not waypoints or routes.\n"); + } + + tpo_file_out = gbfopen_le(fname, "wb", MYNAME); + tpo_write_file_header(); +} + +static void +tpo_wr_deinit(void) +{ + /* the file footer is six bytes of zeroes */ + unsigned char file_footer_bytes[6]; + memset(file_footer_bytes, 0, sizeof(file_footer_bytes)); + gbfwrite(file_footer_bytes, 1, sizeof(file_footer_bytes), tpo_file_out); + + gbfclose(tpo_file_out); +} + +static void +tpo_write(void) +{ + unsigned char unknown1[] = { 0xFF, 0xFF, 0x01, 0x00 }; + + char* chunk_name = "CTopoRoute"; + int chunk_name_length = strlen(chunk_name); + + /* write the total number of tracks */ + gbfputint16(track_count(), tpo_file_out); + + /* 4 unknown bytes */ + gbfwrite(unknown1, 1, 4, tpo_file_out); + + /* chunk name: "CTopoRoute" */ + gbfputint16(chunk_name_length, tpo_file_out); + gbfwrite(chunk_name, 1, chunk_name_length, tpo_file_out); + + track_out_count = 0; + track_disp_all(tpo_track_hdr, tpo_track_tlr, tpo_track_disp); +} + +/* TPO 2.x format can read tracks only */ +ff_vecs_t tpo2_vecs = { + ff_type_file, /* ff_type_internal */ +/* { ff_cap_none | ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none | ff_cap_none }, */ + { ff_cap_none | ff_cap_none, ff_cap_read, ff_cap_none | ff_cap_none }, + tpo_rd_init, + tpo_wr_init, + tpo_rd_deinit, + tpo_wr_deinit, + tpo_read, + tpo_write, + NULL, + tpo2_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; + +/* TPO 3.x format can read waypoints/tracks/routes */ +ff_vecs_t tpo3_vecs = { + ff_type_file, /* ff_type_internal */ + { ff_cap_read, ff_cap_read, ff_cap_read }, + tpo_rd_init, + tpo_wr_init, + tpo_rd_deinit, + tpo_wr_deinit, + tpo_read, + tpo_write, + NULL, + tpo3_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; + diff --git a/tpo.testo.patch b/tpo.testo.patch new file mode 100644 index 000000000..1dec24cec --- /dev/null +++ b/tpo.testo.patch @@ -0,0 +1,27 @@ +Index: testo +=================================================================== +RCS file: /cvsroot/gpsbabel/gpsbabel/testo,v +retrieving revision 1.110 +diff -p -u -r1.110 testo +--- testo 26 Oct 2005 23:11:21 -0000 1.110 ++++ testo 31 Oct 2005 22:23:33 -0000 +@@ -172,6 +172,19 @@ ${PNAME} -i tpg -f ${TMPDIR}/geo.tpg -o + ${PNAME} -i tpg -f reference/tpg.tpg -o mxf -F ${TMPDIR}/topo.mxf + compare ${TMPDIR}/tpg.mxf ${TMPDIR}/topo.mxf + ++# TPO (NG Topo!) file format ++# This is hard to test because the datum conversions create minute ++# inconsistencies in the coordinates. We have four reference files: ++# sample1.tpo, sample1.gpx, sample2.gpx, and sample2.tpo. These are ++# used to check the conversion to and from TPO format. ++rm -f ${TMPDIR}/sample1.gpx ${TMPDIR}/sample2.tpo ++${PNAME} -t -i tpo -f reference/track/sample1.tpo -o gpx -F ${TMPDIR}/sample1.gpx ++compare ${TMPDIR}/sample1.gpx reference/track/sample1.gpx ++${PNAME} -t -i gpx -f reference/track/sample2.gpx -o tpo -F ${TMPDIR}/sample2.tpo ++bincompare ${TMPDIR}/sample2.tpo reference/track/sample2.tpo ++ ++ ++ + # OZI (OziExplorer 1.1) file format + rm -f ${TMPDIR}/oz.wpt ${TMPDIR}/ozi.wpt + ${PNAME} -i ozi -f reference/ozi.wpt -o ozi -F ${TMPDIR}/oz.wpt diff --git a/trackfilter.c b/trackfilter.c new file mode 100644 index 000000000..7f5676c27 --- /dev/null +++ b/trackfilter.c @@ -0,0 +1,999 @@ +/* + + Track manipulation filter + + Copyright (C) 2005-2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + /* + 2005-07-20: implemented interval option from Etienne Tasse + 2005-07-26: implemented range option + 2005-07-26: implemented move option + 2005-07-26: implemented merge option + 2005-07-29: warning fixes + 2005-08-01: Add 'static' qualifier when we can (robertl) + 2005-10-04: Add filterdefs to hold protos for filter functions... (robertl) + 2005-10-04: Fix range-check max. value; exit filter, if no more tracks left + 2006-04-06: Add fix, course, and speed options (parkrrrr) + 2006-06-01: Add name option + 2007-01-08: if not really needed disable check for valid timestamps + (based on patch from Vladimir Kondratiev) + 2007-07-26: Allow 'range' together with trackpoints without timestamp + */ + +#include +#include "defs.h" +#include "filterdefs.h" +#include "strptime.h" +#include "grtcirc.h" + +#if FILTERS_ENABLED +#define MYNAME "trackfilter" + +#define TRACKFILTER_PACK_OPTION "pack" +#define TRACKFILTER_SPLIT_OPTION "split" +#define TRACKFILTER_SDIST_OPTION "sdistance" +#define TRACKFILTER_TITLE_OPTION "title" +#define TRACKFILTER_MERGE_OPTION "merge" +#define TRACKFILTER_NAME_OPTION "name" +#define TRACKFILTER_STOP_OPTION "stop" +#define TRACKFILTER_START_OPTION "start" +#define TRACKFILTER_MOVE_OPTION "move" +#define TRACKFILTER_FIX_OPTION "fix" +#define TRACKFILTER_COURSE_OPTION "course" +#define TRACKFILTER_SPEED_OPTION "speed" + +#undef TRACKF_DBG + +static char *opt_merge = NULL; +static char *opt_pack = NULL; +static char *opt_split = NULL; +static char *opt_sdistance = NULL; +static char *opt_move = NULL; +static char *opt_title = NULL; +static char *opt_start = NULL; +static char *opt_stop = NULL; +static char *opt_fix = NULL; +static char *opt_course = NULL; +static char *opt_speed = NULL; +static char *opt_name = NULL; + +static +arglist_t trackfilter_args[] = { + {TRACKFILTER_MOVE_OPTION, &opt_move, + "Correct trackpoint timestamps by a delta", NULL, ARGTYPE_STRING, + ARG_NOMINMAX}, + {TRACKFILTER_PACK_OPTION, &opt_pack, + "Pack all tracks into one", NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {TRACKFILTER_SPLIT_OPTION, &opt_split, + "Split by date or time interval (see README)", NULL, + ARGTYPE_STRING, ARG_NOMINMAX}, + {TRACKFILTER_SDIST_OPTION, &opt_sdistance, + "Split by distance", NULL, + ARGTYPE_STRING, ARG_NOMINMAX}, + {TRACKFILTER_MERGE_OPTION, &opt_merge, + "Merge multiple tracks for the same way", NULL, ARGTYPE_STRING, + ARG_NOMINMAX}, + {TRACKFILTER_NAME_OPTION, &opt_name, + "Use only track(s) where title matches given name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX}, + {TRACKFILTER_START_OPTION, &opt_start, + "Use only track points after this timestamp", NULL, ARGTYPE_INT, + ARG_NOMINMAX}, + {TRACKFILTER_STOP_OPTION, &opt_stop, + "Use only track points before this timestamp", NULL, ARGTYPE_INT, + ARG_NOMINMAX}, + {TRACKFILTER_TITLE_OPTION, &opt_title, + "Basic title for new track(s)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {TRACKFILTER_FIX_OPTION, &opt_fix, + "Synthesize GPS fixes (PPS, DGPS, 3D, 2D, NONE)", NULL, + ARGTYPE_STRING, ARG_NOMINMAX }, + {TRACKFILTER_COURSE_OPTION, &opt_course, "Synthesize course", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {TRACKFILTER_SPEED_OPTION, &opt_speed, "Synthesize speed", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + + +typedef struct trkflt_s +{ + route_head *track; + time_t first_time; + time_t last_time; +} trkflt_t; + +static trkflt_t *track_list = NULL; +static int track_ct = 0; +static int track_pts = 0; +static int opt_interval = 0; +static int opt_distance = 0; +static char need_time; /* initialized within trackfilter_init */ + +/******************************************************************************* +* helpers +*******************************************************************************/ + +static int +trackfilter_opt_count(void) +{ + int res = 0; + arglist_t *a = trackfilter_args; + + while (a->argstring) + { + if (*a->argval != NULL) res++; + a++; + } + return res; +} + +static int +trackfilter_parse_time_opt(const char *arg) +{ + time_t t0, t1; + int sign = 1; + char *cin = (char *)arg; + char c; + + t0 = t1 = 0; + + while ((c = *cin++)) + { + time_t seconds; + + if (c >= '0' && c <= '9') + { + t1 = (t1 * 10) + (c - '0'); + continue; + } + switch(tolower(c)) + { + case 'd': seconds = SECONDS_PER_DAY; break; + case 'h': seconds = SECONDS_PER_HOUR; break; + case 'm': seconds = 60; break; + case 's': seconds = 1; break; + case '+': sign = +1; continue; + case '-': sign = -1; continue; + default: fatal(MYNAME "-time: invalid character in time option!\n"); + } + t0 += (t1 * seconds * sign); + sign = +1; + t1 = 0; + } + t0 += t1; + return t0; +} + +static int +trackfilter_init_qsort_cb(const void *a, const void *b) +{ + const trkflt_t *ra = a; + const trkflt_t *rb = b; + + return ra->first_time - rb->first_time; +} + +static int +trackfilter_merge_qsort_cb(const void *a, const void *b) +{ + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; + + return wa->creation_time - wb->creation_time; +} + +static fix_type +trackfilter_parse_fix() +{ + if ( !opt_fix ) { + return fix_unknown; + } + if ( !case_ignore_strcmp( opt_fix, "pps" )) { + return fix_pps; + } + if ( !case_ignore_strcmp( opt_fix, "dgps" )) { + return fix_dgps; + } + if ( !case_ignore_strcmp( opt_fix, "3d" )) { + return fix_3d; + } + if ( !case_ignore_strcmp( opt_fix, "2d" )) { + return fix_2d; + } + if ( !case_ignore_strcmp( opt_fix, "none" )) { + return fix_none; + } + fatal( MYNAME ": invalid fix type\n" ); + return 0; +} + +static void +trackfilter_fill_track_list_cb(const route_head *track) /* callback for track_disp_all */ +{ + int i; + waypoint *wpt, *prev; + queue *elem, *tmp; + + if (track->rte_waypt_ct == 0) + { + track_del_head((route_head *)track); + return; + } + + if (opt_name != NULL) + { + if ((track->rte_name == NULL) || + (case_ignore_str_match(track->rte_name, opt_name) == 0)) + { + track_del_head((route_head *)track); + return; + } + } + + track_list[track_ct].track = (route_head *)track; + + i = 0; + prev = NULL; + + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) + { + track_pts++; + + wpt = (waypoint *)elem; + is_fatal((need_time != 0) && (wpt->creation_time == 0), + MYNAME "-init: Found track point without time!"); + + i++; + if (i == 1) + track_list[track_ct].first_time = wpt->creation_time; + else + if (i == track->rte_waypt_ct) + track_list[track_ct].last_time = wpt->creation_time; + + if ((need_time != 0) && (prev != NULL) && (prev->creation_time > wpt->creation_time)) + { + if (opt_merge == NULL) + fatal(MYNAME "-init: Track points badly ordered (timestamp)!\n"); + } + prev = wpt; + } + track_ct++; +} + +/******************************************************************************* +* track title producers +*******************************************************************************/ + +static void +trackfilter_split_init_rte_name(route_head *track, const time_t time) +{ + char buff[128], tbuff[128]; + struct tm tm; + + tm = *localtime(&time); + + (opt_interval != 0) ? + strftime(tbuff, sizeof(tbuff), "%Y%m%d%H%M%S", &tm) : + strftime(tbuff, sizeof(tbuff), "%Y%m%d", &tm); + + if ((opt_title != NULL) && (strlen(opt_title) > 0)) + { + if (strchr(opt_title, '%') != NULL) { + strftime(buff, sizeof(buff), opt_title, &tm); + } + else { + snprintf(buff, sizeof(buff), "%s-%s", opt_title, tbuff); + } + } + else if ((track->rte_name != NULL ) && (strlen(track->rte_name) > 0)) + { + snprintf(buff, sizeof(buff), "%s-%s", track->rte_name, tbuff); + } + else { + strncpy(buff, tbuff, sizeof(buff)); + } + + if (track->rte_name != NULL) { + xfree(track->rte_name); + } + track->rte_name = xstrdup(buff); +} + +static void +trackfilter_pack_init_rte_name(route_head *track, const time_t default_time) +{ + char buff[128]; + + if (strchr(opt_title, '%') != NULL) + { + struct tm tm; + waypoint *wpt; + + if (track->rte_waypt_ct == 0) + { + tm = *localtime(&default_time); + } + else + { + wpt = (waypoint *) QUEUE_FIRST((queue *)&track->waypoint_list); + tm = *localtime(&wpt->creation_time); + } + strftime(buff, sizeof(buff), opt_title, &tm); + } + else + strncpy(buff, opt_title, sizeof(buff)); + + if (track->rte_name != NULL) + xfree(track->rte_name); + track->rte_name = xstrdup(buff); +} + +/******************************************************************************* +* option "title" +*******************************************************************************/ + +static void +trackfilter_title(void) +{ + int i; + + if (opt_title == NULL) return; + + if (strlen(opt_title) == 0) { + fatal(MYNAME "-title: Missing your title!\n"); + } + for (i = 0; i < track_ct; i++) + { + route_head *track = track_list[i].track; + trackfilter_pack_init_rte_name(track, 0); + } +} + +/******************************************************************************* +* option "pack" (default) +*******************************************************************************/ + +static void +trackfilter_pack(void) +{ + int i, j; + trkflt_t prev; + route_head *master; + + for (i = 1, j = 0; i < track_ct; i++, j++) + { + prev = track_list[j]; + if (prev.last_time >= track_list[i].first_time) + fatal(MYNAME "-pack: Tracks overlap in time!\n"); + } + + /* we fill up the first track by all other track points */ + + master = track_list[0].track; + + for (i = 1; i < track_ct; i++) + { + queue *elem, *tmp; + route_head *curr = track_list[i].track; + + QUEUE_FOR_EACH((queue *)&curr->waypoint_list, elem, tmp) + { + waypoint *wpt = (waypoint *)elem; + route_add_wpt(master, waypt_dupe(wpt)); + } + track_del_head(curr); + track_list[i].track = NULL; + } + track_ct = 1; +} + +/******************************************************************************* +* option "merge" +*******************************************************************************/ + +static void +trackfilter_merge(void) +{ + int i, j, dropped; + + queue *elem, *tmp; + waypoint **buff; + waypoint *prev, *wpt; + route_head *master = track_list[0].track; + + if (track_pts < 1) return; + + buff = xcalloc(track_pts, sizeof(*buff)); + + j = 0; + for (i = 0; i < track_ct; i++) /* put all points into temp buffer */ + { + route_head *track = track_list[i].track; + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) + { + wpt = (waypoint *)elem; + buff[j++] = waypt_dupe(wpt); + track_del_wpt(track, wpt); + waypt_free(wpt); + } + if (track != master) /* i > 0 */ + track_del_head(track); + } + track_ct = 1; + + qsort(buff, track_pts, sizeof(*buff), trackfilter_merge_qsort_cb); + + dropped = 0; + prev = NULL; + + for (i = 0; i < track_pts; i++) + { + wpt = buff[i]; + if ((prev == NULL) || (prev->creation_time != wpt->creation_time)) + { + route_add_wpt(master, wpt); + prev = wpt; + } + else + { + waypt_free(wpt); + dropped++; + } + } + xfree(buff); + + if (global_opts.verbose_status > 0) + printf(MYNAME "-merge: %d track point(s) merged, %d dropped.\n", track_pts - dropped, dropped); +} + +/******************************************************************************* +* option "split" +*******************************************************************************/ + +static void +trackfilter_split(void) +{ + route_head *curr; + route_head *master = track_list[0].track; + int count = master->rte_waypt_ct; + + waypoint **buff; + waypoint *wpt; + queue *elem, *tmp; + int i, j; + double interval = -1; + double distance = -1; + + if (count <= 1) return; + + /* check additional options */ + + opt_interval = (opt_split && (strlen(opt_split) > 0) && (0 != strcmp(opt_split, TRACKFILTER_SPLIT_OPTION))); + opt_distance = (opt_sdistance && (strlen(opt_sdistance) > 0) && (0 != strcmp(opt_sdistance, TRACKFILTER_SDIST_OPTION))); + + if (opt_interval != 0) + { + double base; + char unit; + + switch(strlen(opt_split)) + { + case 0: + fatal(MYNAME ": No time interval specified.\n"); + break; /* ? */ + + case 1: + unit = *opt_split; + interval = 1; + break; + + default: + i = sscanf(opt_split,"%lf%c", &interval, &unit); + if (i == 0) + { + /* test reverse order */ + i = sscanf(opt_split,"%c%lf", &unit, &interval); + } + if ((i != 2) || (interval <= 0)) + { + fatal(MYNAME ": invalid time interval specified, must be one a positive number.\n"); + } + break; + } + + switch(tolower(unit)) + { + case 's': + base = 1; + break; + case 'm': + base = 60; + break; + case 'h': + base = 60 * 60; + break; + case 'd': + base = 24 * 60 * 60; + break; + default: + fatal(MYNAME ": invalid time interval specified, must be one of [dhms].\n"); + break; + } +#ifdef TRACKF_DBG + printf(MYNAME ": unit \"%c\", interval %g -> %g\n", unit, interval, base * interval); +#endif + interval *= base; + } + + if (opt_distance != 0) + { + double base; + char unit; + + switch(strlen(opt_sdistance)) + { + case 0: + fatal(MYNAME ": No distance specified.\n"); + break; /* ? */ + + case 1: + unit = *opt_sdistance; + distance = 1; + break; + + default: + i = sscanf(opt_sdistance,"%lf%c", &distance, &unit); + if (i == 0) + { + /* test reverse order */ + i = sscanf(opt_sdistance,"%c%lf", &unit, &distance); + } + if ((i != 2) || (distance <= 0)) + { + fatal(MYNAME ": invalid distance specified, must be one a positive number.\n"); + } + break; + } + + switch(tolower(unit)) + { + case 'k': /* kilometers */ + base = 0.6214; + break; + case 'm': /* miles */ + base = 1; + break; + default: + fatal(MYNAME ": invalid distance specified, must be one of [km].\n"); + break; + } +#ifdef TRACKF_DBG + printf(MYNAME ": unit \"%c\", distance %g -> %g\n", unit, distance, base * distance); +#endif + distance *= base; + } + + trackfilter_split_init_rte_name(master, track_list[0].first_time); + + buff = (waypoint **) xcalloc(count, sizeof(*buff)); + + i = 0; + QUEUE_FOR_EACH((queue *)&master->waypoint_list, elem, tmp) + { + wpt = (waypoint *)elem; + buff[i++] = wpt; + } + + curr = NULL; /* will be set by first new track */ + + for (i=0, j=1; jcreation_time); + t2 = *localtime(&buff[j]->creation_time); + + new_track_flag = ((t1.tm_year != t2.tm_year) || (t1.tm_mon != t2.tm_mon) || + (t1.tm_mday != t2.tm_mday)); +#ifdef TRACKF_DBG + if (new_track_flag != 0) + printf(MYNAME ": new day %02d.%02d.%04d\n", t2.tm_mday, t2.tm_mon+1, t2.tm_year+1900); +#endif + } + else + { + new_track_flag = 1; + + if (distance > 0) + { + double rt1 = RAD(buff[i]->latitude); + double rn1 = RAD(buff[i]->longitude); + double rt2 = RAD(buff[j]->latitude); + double rn2 = RAD(buff[j]->longitude); + double curdist = gcdist( rt1, rn1, rt2, rn2 ); + curdist = radtomiles(curdist); + if ( curdist <= distance ) + new_track_flag = 0; +#ifdef TRACKF_DBG + else + printf(MYNAME ": sdistance, %g > %g\n", curdist, distance ); +#endif + } + + if (interval > 0) + { + double tr_interval = difftime(buff[j]->creation_time,buff[i]->creation_time); + if ( tr_interval <= interval ) + new_track_flag = 0; +#ifdef TRACKF_DBG + else + printf(MYNAME ": split, %g > %g\n", tr_interval, interval ); +#endif + } + + } + if (new_track_flag != 0) + { +#ifdef TRACKF_DBG + printf(MYNAME ": splitting new track\n" ); +#endif + curr = (route_head *) route_head_alloc(); + trackfilter_split_init_rte_name(curr, buff[j]->creation_time); + track_add_head(curr); + } + if (curr != NULL) + { + wpt = buff[j]; + track_del_wpt(master, wpt); + track_add_wpt(curr, wpt); + buff[j] = wpt; + } + } + xfree(buff); +} + +/******************************************************************************* +* option "move" +*******************************************************************************/ + +static void +trackfilter_move(void) +{ + int i; + queue *elem, *tmp; + waypoint *wpt; + time_t delta; + + delta = trackfilter_parse_time_opt(opt_move); + if (delta == 0) return; + + for (i = 0; i < track_ct; i++) + { + route_head *track = track_list[i].track; + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) + { + wpt = (waypoint *)elem; + wpt->creation_time += delta; + } + track_list[i].first_time += delta; + track_list[i].last_time += delta; + } +} + +/******************************************************************************* +* options "fix", "course", "speed" +*******************************************************************************/ + +static void +trackfilter_synth(void) +{ + int i; + queue *elem, *tmp; + waypoint *wpt; + + double oldlat = -999; + double oldlon = -999; + time_t oldtime = 0; + int first = 1; + fix_type fix; + + fix = trackfilter_parse_fix(); + + for (i = 0; i < track_ct; i++) + { + route_head *track = track_list[i].track; + first = 1; + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) + { + wpt = (waypoint *)elem; + if ( opt_fix ) { + wpt->fix = fix; + } + if ( first ) { + if ( opt_course ) { + WAYPT_SET(wpt, course, 0); + } + if ( opt_speed ) { + WAYPT_SET(wpt, speed, 0); + } + first = 0; + } + else { + if ( opt_course ) { + WAYPT_SET(wpt, course, heading_true_degrees( RAD(oldlat), + RAD(oldlon),RAD(wpt->latitude), + RAD(wpt->longitude)) ); + } + if ( opt_speed ) { + if ( oldtime != wpt->creation_time ) { + WAYPT_SET(wpt, speed, radtometers(gcdist( + RAD(oldlat), RAD(oldlon), + RAD(wpt->latitude), + RAD(wpt->longitude))) / + labs(wpt->creation_time-oldtime)); + } + else { + WAYPT_UNSET(wpt, speed); + } + } + } + oldlat = wpt->latitude; + oldlon = wpt->longitude; + oldtime = wpt->creation_time; + } + } +} + + +/******************************************************************************* +* option: "start" / "stop" +*******************************************************************************/ + +static time_t +trackfilter_range_check(const char *timestr) +{ + int i; + char fmt[20]; + char c; + char *cin; + struct tm time; + + + i = 0; + strncpy(fmt, "00000101000000", sizeof(fmt)); + cin = (char *)timestr; + + while ((c = *cin++)) + { + if (fmt[i] == '\0') fatal(MYNAME "-range: parameter too long \"%s\"!\n", timestr); + if (isdigit(c) == 0) fatal(MYNAME "-range: invalid character \"%c\"!\n", c); + fmt[i++] = c; + } + cin = strptime(fmt, "%Y%m%d%H%M%S", &time); + if ((cin != NULL) && (*cin != '\0')) + fatal(MYNAME "-range-check: Invalid time stamp (stopped at %s of %s)!\n", cin, fmt); + + return mkgmtime(&time); +} + +static int +trackfilter_range(void) /* returns number of track points left after filtering */ +{ + time_t start, stop; + queue *elem, *tmp; + int i, dropped, inside = 0; + + if (opt_start != 0) + start = trackfilter_range_check(opt_start); + else + start = 0; + + if (opt_stop != 0) + stop = trackfilter_range_check(opt_stop); + else + stop = 0x7FFFFFFF; + + dropped = inside = 0; + + for (i = 0; i < track_ct; i++) + { + route_head *track = track_list[i].track; + + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) + { + waypoint *wpt = (waypoint *)elem; + + if (wpt->creation_time > 0) { + inside = ((wpt->creation_time >= start) && (wpt->creation_time <= stop)); + } + + if (! inside) { + track_del_wpt(track, wpt); + waypt_free(wpt); + dropped++; + } + } + + if (track->rte_waypt_ct == 0) + { + track_del_head(track); + track_list[i].track = NULL; + } + } + + if ((track_pts > 0) && (dropped == track_pts)) + warning(MYNAME "-range: All %d track points have been dropped!\n", track_pts); + + return track_pts - dropped; +} + +/******************************************************************************* +* global cb's +*******************************************************************************/ + +static void +trackfilter_init(const char *args) +{ + + int count = track_count(); + +/* + * check time presence only if required. Options that NOT require time: + * + * - opt_title (!!! only if no format specifier is present !!!) + * - opt_course + * - opt_name + */ + need_time = ( + opt_merge || opt_pack || opt_split || opt_sdistance || + opt_move || opt_fix || opt_speed || + (trackfilter_opt_count() == 0) /* do pack by default */ + ); + /* in case of a formated title we also need valid timestamps */ + if ((opt_title != NULL) && (strchr(opt_title, '%') != NULL)) need_time = 1; + + track_ct = 0; + track_pts = 0; + + if (count > 0) + { + track_list = (trkflt_t *) xcalloc(count, sizeof(*track_list)); + + /* check all tracks for time and order (except merging) */ + + track_disp_all(trackfilter_fill_track_list_cb, NULL, NULL); + if (need_time) + qsort(track_list, track_ct, sizeof(*track_list), trackfilter_init_qsort_cb); + } +} + +static void +trackfilter_deinit(void) +{ + if (track_list != NULL) + { + xfree(track_list); + track_list = NULL; + } + track_ct = 0; + track_pts = 0; +} + +/******************************************************************************* +* trackfilter_process: called from gpsbabel central engine +*******************************************************************************/ + +static void +trackfilter_process(void) +{ + int opts, something_done; + + if (track_ct == 0) return; /* no track(s), no fun */ + + opts = trackfilter_opt_count(); + if (opts == 0) opts = -1; /* flag for do "pack" by default */ + + if (opt_name != NULL) + { + if (--opts == 0) return; + } + + if (opt_move != NULL) /* Correct timestamps before any other op */ + { + trackfilter_move(); + if (--opts == 0) return; + } + + if ( opt_speed || opt_course || opt_fix ) { + trackfilter_synth(); + if ( opt_speed ) opts--; + if ( opt_course ) opts--; + if ( opt_fix ) opts--; + if ( !opts ) return; + } + + if ((opt_stop != NULL) || (opt_start != NULL)) + { + if (opt_start != NULL) opts--; + if (opt_stop != NULL) opts--; + + trackfilter_range(); + + if (opts == 0) return; + + trackfilter_deinit(); /* reinitialize */ + trackfilter_init(NULL); + + if (track_ct == 0) return; /* no more track(s), no more fun */ + + } + + if (opt_title != NULL) + { + if (--opts == 0) + { + trackfilter_title(); + return; + } + } + + something_done = 0; + + if ((opt_pack != NULL) || (opts == -1)) /* call our default option */ + { + trackfilter_pack(); + something_done = 1; + } + else if (opt_merge != NULL) + { + trackfilter_merge(); + something_done = 1; + } + + if ((something_done == 1) && (--opts <= 0)) + { + if (opt_title != NULL) + trackfilter_title(); + return; + } + + if ((opt_split != NULL) || (opt_sdistance != NULL)) + { + if (track_ct > 1) + fatal(MYNAME "-split: Cannot split more than one track, please pack (or merge) before!\n"); + + trackfilter_split(); + } +} + +/******************************************************************************************/ + +filter_vecs_t trackfilter_vecs = { + trackfilter_init, + trackfilter_process, + trackfilter_deinit, + NULL, + trackfilter_args +}; + +/******************************************************************************************/ +#endif // FILTERS_ENABLED diff --git a/transform.c b/transform.c new file mode 100644 index 000000000..9d47f4360 --- /dev/null +++ b/transform.c @@ -0,0 +1,199 @@ +/* + + Transformation filter for GPS data. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED + +#include + +#define MYNAME "transform" + +static char current_target; +static route_head *current_trk; +static route_head *current_rte; + +static char *opt_routes, *opt_tracks, *opt_waypts, *opt_delete; + +static +arglist_t transform_args[] = { + {"wpt", &opt_waypts, "Transform track(s) or route(s) into waypoint(s) [R/T]", NULL, + ARGTYPE_STRING, ARG_NOMINMAX}, + {"rte", &opt_routes, "Transform waypoint(s) or track(s) into route(s) [W/T]", NULL, + ARGTYPE_STRING, ARG_NOMINMAX}, + {"trk", &opt_tracks, "Transform waypoint(s) or route(s) into tracks(s) [W/R]", NULL, + ARGTYPE_STRING, ARG_NOMINMAX}, + {"del", &opt_delete, "Delete source data after transformation", "N", + ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +static void +transform_waypoints(void) +{ + queue *elem, *tmp; + route_head *rte; + + rte = route_head_alloc(); + switch(current_target) { + case 'R': route_add_head(rte); break; + case 'T': track_add_head(rte); break; + } + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) + { + waypoint *wpt = (waypoint *) elem; + + wpt = waypt_dupe(wpt); + switch(current_target) { + case 'R': route_add_wpt(rte, wpt); break; + case 'T': track_add_wpt(rte, wpt); break; + } + } +} + +static void +transform_rte_disp_hdr_cb(const route_head *rte) +{ + if (current_target == 'T') { + current_trk = route_head_alloc(); + track_add_head(current_trk); + if (rte->rte_name && *rte->rte_name) + xasprintf(¤t_trk->rte_desc, "Generated from route %s", rte->rte_name); + } +} + +static void +transform_trk_disp_hdr_cb(const route_head *trk) +{ + if (current_target == 'R') { + current_rte = route_head_alloc(); + route_add_head(current_rte); + if (trk->rte_name && *trk->rte_name) + xasprintf(¤t_rte->rte_desc, "Generated from track %s", trk->rte_name); + } +} + +static void +transform_any_disp_wpt_cb(const waypoint *wpt) +{ + waypoint *temp = waypt_dupe(wpt); + if (current_target == 'R') + route_add_wpt(current_rte, temp); + else if (current_target == 'T') + track_add_wpt(current_trk, temp); + else + waypt_add(temp); +} + +static void +transform_routes(void) +{ + route_disp_all(transform_rte_disp_hdr_cb, NULL, transform_any_disp_wpt_cb); +} + +static void +transform_tracks(void) +{ + track_disp_all(transform_trk_disp_hdr_cb, NULL, transform_any_disp_wpt_cb); +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +transform_init(const char *args) +{ +} + +static void +transform_deinit(void) +{ +} + +static void +transform_process(void) +{ + int delete_after = (opt_delete && (*opt_delete == '1')) ? 1 : 0; + + if (opt_waypts != NULL) { + current_target = 'W'; + switch(toupper(*opt_waypts)) { + case 'R': + transform_routes(); + if (delete_after) route_flush_all_routes(); + break; + case 'T': + transform_tracks(); + if (delete_after) route_flush_all_tracks(); + break; + default: + fatal(MYNAME ": Invalid option value (%s)!\n", opt_waypts); + } + } + if (opt_routes != NULL) { + current_target = 'R'; + switch(toupper(*opt_routes)) { + case 'W': + transform_waypoints(); + if (delete_after) waypt_flush_all(); + break; + case 'T': + transform_tracks(); + if (delete_after) route_flush_all_tracks(); + break; + default: + fatal(MYNAME ": Invalid option value (%s)!\n", opt_routes); + } + } + if (opt_tracks != NULL) { + current_target = 'T'; + switch(toupper(*opt_tracks)) { + case 'W': + transform_waypoints(); + if (delete_after) waypt_flush_all(); + break; + case 'R': + transform_routes(); + if (delete_after) route_flush_all_routes(); + break; + default: + fatal(MYNAME ": Invalid option value (%s)!\n", opt_tracks); + } + } +} + +/*******************************************************************************/ + +filter_vecs_t transform_vecs = { + transform_init, + transform_process, + transform_deinit, + NULL, + transform_args +}; + +/*******************************************************************************/ + +#endif // FILTERS_ENABLED diff --git a/unicsv.c b/unicsv.c new file mode 100644 index 000000000..388c6b242 --- /dev/null +++ b/unicsv.c @@ -0,0 +1,1444 @@ +/* + Universal CSV - support for csv files, divining field order from the header. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net, + copyright (C) 2007,2008 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include "defs.h" +#include "cet.h" +#include "cet_util.h" +#include "csv_util.h" +#include "garmin_fs.h" +#include "garmin_tables.h" +#include "jeeps/gpsmath.h" +#include "strptime.h" +#include +#include + +#define MYNAME "unicsv" + +/* "UNICSV_FIELD_SEP" and "UNICSV_LINE_SEP" are only used by the writer */ + +#define UNICSV_FIELD_SEP "," +#define UNICSV_LINE_SEP "\r\n" +#define UNICSV_QUOT_CHAR '"' + +/* GPSBabel internal and calculated fields */ + +typedef enum { + fld_shortname = 0, + fld_latitude, + fld_longitude, + fld_description, + fld_notes, + fld_url, + fld_altitude, + fld_utm_zone, + fld_utm_zone_char, + fld_utm_northing, + fld_utm_easting, + fld_utm, + fld_bng, + fld_bng_zone, + fld_bng_northing, + fld_bng_easting, + fld_swiss, + fld_swiss_northing, + fld_swiss_easting, + fld_hdop, + fld_pdop, + fld_vdop, + fld_sat, + fld_fix, + fld_utc_date, + fld_utc_time, + fld_course, + fld_speed, + fld_temperature, + fld_temperature_f, + fld_heartrate, + fld_cadence, + fld_proximity, + fld_depth, + fld_symbol, + fld_date, + fld_time, + fld_datetime, + fld_iso_time, + fld_year, + fld_month, + fld_day, + fld_hour, + fld_min, + fld_sec, + fld_ns, + fld_ew, + fld_garmin_city, + fld_garmin_postal_code, + fld_garmin_state, + fld_garmin_country, + fld_garmin_addr, + fld_garmin_phone_nr, + fld_garmin_facility, + fld_terminator +} field_e; + +#define STR_LEFT 1 +#define STR_RIGHT 2 +#define STR_ANY 4 +#define STR_EQUAL 8 +#define STR_CASE 16 + +#define unicsv_unknown 1e25 + +typedef struct { + char *name; + field_e type; + gbuint32 options; +} field_t; + +/* + * ! Please use always underscores in field names ! + * we check a second time after replacing underscores with spaces + */ +static field_t fields_def[] = { + /* unhandled columns */ + { "index", fld_terminator, STR_ANY }, + { "no", fld_terminator, STR_EQUAL }, + { "mini", fld_terminator, STR_ANY }, /* maybe minimum anything, so + avoid detection as 'min' for minute */ + /* handled columns */ + { "name", fld_shortname, STR_ANY }, + { "title", fld_shortname, STR_ANY }, + { "desc", fld_description, STR_ANY }, + { "notes", fld_notes, STR_ANY }, + { "omment", fld_notes, STR_ANY }, /* works also for German "Kommentar" */ + { "text", fld_notes, STR_ANY }, + { "url", fld_url, STR_ANY }, + { "icon", fld_symbol, STR_ANY }, + { "symb", fld_symbol, STR_ANY }, + { "lat", fld_latitude, STR_ANY }, + { "lon", fld_longitude, STR_ANY }, + { "lng", fld_longitude, STR_ANY }, + { "x", fld_longitude, STR_EQUAL }, + { "y", fld_latitude, STR_EQUAL }, + { "z", fld_altitude, STR_EQUAL }, + { "x_pos", fld_longitude, STR_ANY }, + { "y_pos", fld_latitude, STR_ANY }, + { "alt", fld_altitude, STR_ANY }, + { "ele", fld_altitude, STR_ANY }, + { "height", fld_altitude, STR_ANY }, + { "utm_z", fld_utm_zone, STR_ANY }, + { "utm_c", fld_utm_zone_char, STR_ANY }, + { "utm_zc", fld_utm_zone_char, STR_ANY }, + { "utm_n", fld_utm_northing, STR_ANY }, + { "utm_e", fld_utm_easting, STR_ANY }, + { "utm", fld_utm, STR_EQUAL }, + { "utm_coo", fld_utm, STR_ANY }, + { "utm_pos", fld_utm, STR_ANY }, + { "bng_z", fld_bng_zone, STR_ANY }, + { "bng_n", fld_bng_northing, STR_ANY }, + { "bng_e", fld_bng_easting, STR_ANY }, + { "bng", fld_bng, STR_EQUAL }, + { "bng_coo", fld_bng, STR_ANY }, + { "bng_pos", fld_bng, STR_ANY }, + { "swiss_e", fld_swiss_easting, STR_ANY }, + { "swiss_n", fld_swiss_northing, STR_ANY }, + { "swiss", fld_swiss, STR_EQUAL }, + { "swiss_coo", fld_swiss, STR_ANY }, + { "swiss_pos", fld_swiss, STR_ANY }, + { "hdop", fld_hdop, STR_ANY }, + { "pdop", fld_pdop, STR_ANY }, + { "vdop", fld_vdop, STR_ANY }, + { "sat", fld_sat, STR_ANY }, + { "fix", fld_fix, STR_ANY }, + { "utc_d", fld_utc_date, STR_ANY }, + { "utc_t", fld_utc_time, STR_ANY }, + { "head", fld_course, STR_ANY }, + { "cour", fld_course, STR_ANY }, + { "speed", fld_speed, STR_ANY }, + { "velo", fld_speed, STR_ANY }, + { "geschw", fld_speed, STR_ANY }, /* speed in german */ + { "tempf", fld_temperature_f, STR_EQUAL }, /* degrees fahrenheit */ + { "temp", fld_temperature, STR_ANY }, /* degrees celsius by default */ + { "heart", fld_heartrate, STR_ANY }, + { "caden", fld_cadence, STR_ANY }, + { "prox", fld_proximity, STR_ANY }, + { "depth", fld_depth, STR_ANY }, + { "date", fld_date, STR_ANY }, + { "datum", fld_date, STR_ANY }, + { "time", fld_time, STR_ANY }, + { "zeit", fld_time, STR_ANY }, + { "hour", fld_hour, STR_LEFT }, + { "min", fld_min, STR_LEFT }, + { "sec", fld_sec, STR_LEFT }, + { "year", fld_year, STR_LEFT }, + { "month", fld_month, STR_LEFT }, + { "day", fld_day, STR_LEFT }, + { "n/s", fld_ns, STR_ANY }, + { "e/w", fld_ew, STR_ANY }, + + /* garmin specials */ + { "addr", fld_garmin_addr, STR_ANY }, + { "street", fld_garmin_addr, STR_ANY }, + { "city", fld_garmin_city, STR_ANY }, + { "country", fld_garmin_country, STR_ANY }, + { "post", fld_garmin_postal_code, STR_ANY }, + { "zip", fld_garmin_postal_code, STR_ANY }, + { "phone", fld_garmin_phone_nr, STR_ANY }, + { "state", fld_garmin_state, STR_ANY }, + { "faci", fld_garmin_facility, STR_ANY }, + { NULL, fld_terminator, 0 } +}; + +static field_e *unicsv_fields_tab; +static int unicsv_fields_tab_ct; +static double unicsv_altscale, unicsv_depthscale, unicsv_proximityscale +; +static char *unicsv_fieldsep; +static gbfile *fin, *fout; +static gpsdata_type unicsv_data_type; +static route_head *unicsv_track, *unicsv_route; +static unsigned long long unicsv_outp_flags; +static grid_type unicsv_grid_idx; +static int unicsv_datum_idx; +static char *opt_datum, *opt_grid, *opt_utc; +static int unicsv_waypt_ct; +static char unicsv_detect; + +static arglist_t unicsv_args[] = { + {"datum", &opt_datum, "GPS datum (def. WGS 84)", + "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, + {"grid", &opt_grid, "Write position using this grid.", + NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"utc", &opt_utc, "Write timestamps with offset x to UTC time", + NULL, ARGTYPE_INT, "-23", "+23"}, + ARG_TERMINATOR }; + + +/* helpers */ + +// #define UNICSV_IS(f) (0 == strcmp(s, f)) +#define UNICSV_CONTAINS(f) (0 != strstr(s, f)) + +/* here we only need a simple yes(0) or no(1) */ +static int +unicsv_strrcmp(const char *s1, const char *s2) +{ + int l1, l2; + + l1 = strlen(s1); + l2 = strlen(s2); + if ((l1 - l2) >= 0) + return strcmp(s1 + (l1 - l2), s2); + else + return 1; /* false */ +} + +static int +unicsv_parse_date(const char *str, int *consumed) +{ + int p1, p2, p3, ct; + char sep[2]; + struct tm tm; + int lconsumed = 0; + + memset(&tm, 0, sizeof(tm)); + ct = sscanf(str, "%d%1[-.//]%d%1[-.//]%d%n", &p1, sep, &p2, sep, &p3, &lconsumed); + if (consumed && lconsumed) { + *consumed = lconsumed; + } + if (ct != 5) { + if (consumed) { /* don't stop here; it's only sniffing */ + *consumed = 0; /* for a possible date */ + return 0; + } + fatal(MYNAME ": Could not parse date string (%s).\n", str); + } + + if ((p1 > 99) || (sep[0] == '-')) { /* Y-M-D (iso like) */ + tm.tm_year = p1; + tm.tm_mon = p2; + tm.tm_mday = p3; + } + else if (sep[0] == '.') { /* Germany and any other countries */ + tm.tm_mday = p1; /* have a fixed D.M.Y format */ + tm.tm_mon = p2; + tm.tm_year = p3; + } + else { + tm.tm_mday = p2; + tm.tm_mon = p1; + tm.tm_year = p3; + } + if ((p1 < 100) && (p2 < 100) && (p3 < 100)) { + if (tm.tm_year < 70) tm.tm_year += 2000; + else tm.tm_year += 1900; + } + /* some low-level checks */ + if ((tm.tm_mon > 12) || (tm.tm_mon < 1) || (tm.tm_mday > 31) || (tm.tm_mday < 1)) { + if (consumed) { + *consumed = 0; + return 0; /* don't stop here */ + } + fatal(MYNAME ": Could not parse date string (%s).\n", str); + } + + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + return mkgmtime(&tm); +} + +static int +unicsv_parse_time(const char *str, int *msec, int *date) +{ + int hour, min, ct, sec; + int consumed = 0; + double ms; + char sep[1]; + int ldate; + + /* If we have somethine we're pretty sure is a date, parse that + * first, skip over it, and pass that back to the caller) + */ + ldate = unicsv_parse_date(str, &consumed); + if (consumed && ldate) { + str += consumed; + if (date) { + *date = ldate; + } + } + + ct = sscanf(str, "%d%1[.://]%d%1[.://]%d%lf", &hour, sep, &min, sep, &sec, &ms); + is_fatal(ct < 5, MYNAME ": Could not parse time string (%s).\n", str); + if (ct == 6) { + *msec = (ms * 1000000) + 0.5; + if (*msec > 999999) { + *msec = 0; + sec++; + } + } + else *msec = 0; + + return ((hour * SECONDS_PER_HOUR) + (min * 60) + (int)sec); +} + +static char +unicsv_compare_fields(char *s, const field_t *f) +{ + char *name = (char *)f->name; + char *test = s; + char result; + + if (! (f->options & STR_CASE)) { + test = strupper(xstrdup(s)); + name = strupper(xstrdup(f->name)); + } + + if (f->options & STR_EQUAL) { + result = (strcmp(test, name) == 0); + } + else if (f->options & STR_ANY) { + result = (strstr(test, name) != NULL); + } + else { + if (f->options & STR_LEFT) { + result = (strncmp(test, name, strlen(name)) == 0); + } + else if (f->options & STR_RIGHT) { + result = (unicsv_strrcmp(test, name) == 0); + } + else { + result = 0; /* fallback to "FALSE" */ + } + } + + if ((! result) && (strchr(test, ' ') != NULL)) { + /* replace ' ' with '_' and try again */ + char *tmp = gstrsub(test, " ", "_"); + result = unicsv_compare_fields(tmp, f); + xfree(tmp); + } + if ((! result) && (strchr(test, '-') != NULL)) { + /* replace '-' with '_' and try again */ + char *tmp = gstrsub(test, "-", "_"); + result = unicsv_compare_fields(tmp, f); + xfree(tmp); + } + + if (name != f->name) { + xfree(name); + xfree(test); + } + + return result; +} + + +static void +unicsv_fondle_header(char *ibuf) +{ + char *s; + char *buf = NULL; + int i, column; + const cet_cs_vec_t *ascii = &cet_cs_vec_ansi_x3_4_1968; /* us-ascii */ + + /* Convert the entire header to lower case for convenience. + * If we see a tab in that header, we decree it to be tabsep. + */ + unicsv_fieldsep = ","; + for (s = ibuf; *s; s++) { + if (*s == '\t') { + unicsv_fieldsep = "\t"; + } + else if (*s == ';') { + unicsv_fieldsep = ";"; + } + else if (*s == '|') { + unicsv_fieldsep = "|"; + } + else { + continue; + } + break; + } + for (s = ibuf; *s; s++) { + *s = tolower(*s); + } + + /* convert the header line into native ascii */ + if (global_opts.charset != ascii) { + buf = cet_str_any_to_any(ibuf, global_opts.charset, ascii); + ibuf = buf; + } + + column = -1; + while ((s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0))) { + + field_t *f = &fields_def[0]; + + ibuf = NULL; + column++; + unicsv_fields_tab_ct++; + s = lrtrim(s); + + if (column % 4 == 0) { + int sz = (column + 4) * sizeof(*unicsv_fields_tab); + if (column == 0) unicsv_fields_tab = xmalloc(sz); + else unicsv_fields_tab = xrealloc(unicsv_fields_tab, sz); + for (i = 0; i < 4; i++) unicsv_fields_tab[column + i] = fld_terminator; + } + + while (f->name) { + if (unicsv_compare_fields(s, f)) { + unicsv_fields_tab[column] = f->type; + break; + } + f++; + } + if ((! f->name) && global_opts.debug_level) + warning(MYNAME ": Unhandled column \"%s\".\n", s); + + /* handle some special items */ + if (f->type == fld_altitude) { + if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) { + unicsv_altscale = FEET_TO_METERS(1); + } + } + if (f->type == fld_depth) { + if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) { + unicsv_depthscale = FEET_TO_METERS(1); + } + } + if (f->type == fld_proximity) { + if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) { + unicsv_proximityscale = FEET_TO_METERS(1); + } + } + if ((f->type == fld_time) || (f->type == fld_date)) { + if (UNICSV_CONTAINS("iso")) + f->type = fld_iso_time; + } + } + if (buf) xfree(buf); +} + +static void +unicsv_rd_init(const char *fname) +{ + char *c; + unicsv_altscale = 1.0; + unicsv_depthscale = 1.0; + unicsv_proximityscale = 1.0; + + unicsv_fields_tab = NULL; + unicsv_fields_tab_ct = 0; + unicsv_data_type = global_opts.objective; + unicsv_detect = (! (global_opts.masked_objective & (WPTDATAMASK | TRKDATAMASK | RTEDATAMASK | POSNDATAMASK))); + + unicsv_track = unicsv_route = NULL; + unicsv_datum_idx = gt_lookup_datum_index(opt_datum, MYNAME); + + fin = gbfopen(fname, "rb", MYNAME); + + if ((c = gbfgetstr(fin))) + unicsv_fondle_header(c); + else + unicsv_fieldsep = NULL; +} + +static void +unicsv_rd_deinit(void) +{ + gbfclose(fin); + if (unicsv_fields_tab) xfree(unicsv_fields_tab); +} + +static void +unicsv_parse_one_line(char *ibuf) +{ + char *s; + waypoint *wpt = NULL; + int column; + int utm_zone = -9999; + double utm_easting = 0; + double utm_northing = 0; + char utm_zc = 'N'; + char bng_zone[3] = ""; + double bng_easting = 0; + double bng_northing = 0; + double swiss_easting = unicsv_unknown; + double swiss_northing = unicsv_unknown; + int checked = 0; + int date = -1, time = -1, msec = -1; + char is_localtime = 0; + garmin_fs_t *gmsd; + double d; + struct tm ymd; + int src_datum = unicsv_datum_idx; + int ns = 1; + int ew = 1; + + wpt = waypt_new(); + wpt->latitude = unicsv_unknown; + wpt->longitude = unicsv_unknown; + memset(&ymd, 0, sizeof(ymd)); + + column = -1; + while ((s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0))) { + + if (column > unicsv_fields_tab_ct) break; /* ignore extra fields on line */ + + ibuf = NULL; + + column++; + checked++; + + s = lrtrim(s); + if (! *s) continue; /* skip empty columns */ + switch(unicsv_fields_tab[column]) { + + case fld_time: + case fld_date: + /* switch column type if it looks like an iso time string */ + if (strchr(s, 'T')) + unicsv_fields_tab[column] = fld_iso_time; + break; + default: ; + } + + + switch(unicsv_fields_tab[column]) { + + case fld_latitude: + human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 ); + wpt->latitude = wpt->latitude * ns; + break; + + case fld_longitude: + human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 ); + wpt->longitude = wpt->longitude * ew; + break; + + case fld_shortname: + wpt->shortname = xstrdup(s); + break; + + case fld_description: + wpt->description = xstrdup(s); + break; + + case fld_notes: + wpt->notes = xstrdup(s); + break; + + case fld_url: + wpt->url = xstrdup(s); + break; + + case fld_altitude: + if (parse_distance(s, &d, unicsv_altscale, MYNAME)) { + if (fabs(d) < fabs(unknown_alt)) + wpt->altitude = d; + } + break; + + case fld_utm_zone: + utm_zone = atoi(s); + break; + + case fld_utm_easting: + utm_easting = atof(s); + break; + + case fld_utm_northing: + utm_northing = atof(s); + break; + + case fld_utm_zone_char: + utm_zc = toupper(s[0]); + break; + + case fld_utm: + parse_coordinates(s, unicsv_datum_idx, grid_utm, + &wpt->latitude, &wpt->longitude, MYNAME); + /* coordinates from parse_coordinates are in WGS84 + don't convert a second time */ + src_datum = DATUM_WGS84; + break; + + case fld_bng: + parse_coordinates(s, DATUM_OSGB36, grid_bng, + &wpt->latitude, &wpt->longitude, MYNAME); + /* coordinates from parse_coordinates are in WGS84 + don't convert a second time */ + src_datum = DATUM_WGS84; + break; + + case fld_bng_zone: + strncpy(bng_zone, s, sizeof(bng_zone)); + strupper(bng_zone); + break; + + case fld_bng_northing: + bng_northing = atof(s); + break; + + case fld_bng_easting: + bng_easting = atof(s); + break; + + case fld_swiss: + parse_coordinates(s, DATUM_WGS84, grid_swiss, + &wpt->latitude, &wpt->longitude, MYNAME); + /* coordinates from parse_coordinates are in WGS84 + don't convert a second time */ + src_datum = DATUM_WGS84; + break; + + case fld_swiss_easting: + swiss_easting = atof(s); + break; + + case fld_swiss_northing: + swiss_northing = atof(s); + break; + + case fld_hdop: + wpt->hdop = atof(s); + if (unicsv_detect) unicsv_data_type = trkdata; + break; + + case fld_pdop: + wpt->pdop = atof(s); + if (unicsv_detect) unicsv_data_type = trkdata; + break; + + case fld_vdop: + wpt->vdop = atof(s); + if (unicsv_detect) unicsv_data_type = trkdata; + break; + + case fld_sat: + wpt->sat = atoi(s); + if (unicsv_detect) unicsv_data_type = trkdata; + break; + + case fld_fix: + if (unicsv_detect) unicsv_data_type = trkdata; + if (case_ignore_strcmp(s, "none") == 0) + wpt->fix = fix_none; + else if (case_ignore_strcmp(s, "2d") == 0) + wpt->fix = fix_2d; + else if (case_ignore_strcmp(s, "3d") == 0) + wpt->fix = fix_3d; + else if (case_ignore_strcmp(s, "dgps") == 0) + wpt->fix = fix_dgps; + else if (case_ignore_strcmp(s, "pps") == 0) + wpt->fix = fix_pps; + else wpt->fix = fix_unknown; + break; + + case fld_utc_date: + if ((is_localtime < 2) && (date < 0)) { + date = unicsv_parse_date(s, NULL); + is_localtime = 0; + } + break; + + case fld_utc_time: + if ((is_localtime < 2) && (time < 0)) { + time = unicsv_parse_time(s, &msec, &date); + is_localtime = 0; + } + break; + + case fld_speed: + if (parse_speed(s, &d, 1.0, MYNAME)) { + WAYPT_SET(wpt, speed, d); + if (unicsv_detect) + unicsv_data_type = trkdata; + } + break; + + case fld_course: + WAYPT_SET(wpt, course, atof(s)); + if (unicsv_detect) unicsv_data_type = trkdata; + break; + + case fld_temperature: + d = atof(s); + if (fabs(d) < 999999) WAYPT_SET(wpt, temperature, d); + break; + + case fld_temperature_f: + d = atof(s); + if (fabs(d) < 999999) WAYPT_SET(wpt, temperature, FAHRENHEIT_TO_CELSIUS(d)); + break; + + case fld_heartrate: + wpt->heartrate = atoi(s); + if (unicsv_detect) unicsv_data_type = trkdata; + break; + + case fld_cadence: + wpt->cadence = atoi(s); + if (unicsv_detect) unicsv_data_type = trkdata; + break; + + case fld_proximity: + if (parse_distance(s, &d, unicsv_proximityscale, MYNAME)) + WAYPT_SET(wpt, proximity, d); + break; + + case fld_depth: + if (parse_distance(s, &d, unicsv_depthscale, MYNAME)) + WAYPT_SET(wpt, depth, d); + break; + + case fld_symbol: + wpt->icon_descr = xstrdup(s); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + break; + + case fld_iso_time: + is_localtime = 2; /* fix result */ + wpt->creation_time = xml_parse_time(s, &wpt->microseconds); + break; + + case fld_time: + if ((is_localtime < 2) && (time < 0)) { + time = unicsv_parse_time(s, &msec, &date); + is_localtime = 1; + } + break; + + case fld_date: + if ((is_localtime < 2) && (date < 0)) { + date = unicsv_parse_date(s, NULL); + is_localtime = 1; + } + break; + + case fld_year: + ymd.tm_year = atoi(s); + break; + + case fld_month: + ymd.tm_mon = atoi(s); + break; + + case fld_day: + ymd.tm_mday = atoi(s); + break; + + case fld_hour: + ymd.tm_hour = atoi(s); + break; + + case fld_min: + ymd.tm_min = atoi(s); + break; + + case fld_sec: + ymd.tm_sec = atoi(s); + break; + + case fld_datetime: + /* not implemented */ + break; + case fld_ns: + ns = tolower(s[0]) == 'n' ? 1 : -1; + wpt->latitude *= ns; + break; + case fld_ew: + ew = tolower(s[0]) == 'e' ? 1 : -1; + wpt->longitude *= ew; + break; + case fld_garmin_city: + case fld_garmin_postal_code: + case fld_garmin_state: + case fld_garmin_country: + case fld_garmin_addr: + case fld_garmin_phone_nr: + case fld_garmin_facility: + gmsd = GMSD_FIND(wpt); + if (! gmsd) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + switch(unicsv_fields_tab[column]) { + case fld_garmin_city: GMSD_SETSTR(city, s); break; + case fld_garmin_postal_code: GMSD_SETSTR(postal_code, s); break; + case fld_garmin_state: GMSD_SETSTR(state, s); break; + case fld_garmin_country: GMSD_SETSTR(country, s); break; + case fld_garmin_addr: GMSD_SETSTR(addr, s); break; + case fld_garmin_phone_nr: GMSD_SETSTR(phone_nr, s); break; + case fld_garmin_facility: GMSD_SETSTR(facility, s); break; + default: break; + } + break; + + case fld_terminator: /* dummy */ + checked--; + break; + } + } + + if (checked == 0) { + waypt_free(wpt); + return; + } + + if (is_localtime < 2) { /* not fixed */ + if ((time >= 0) && (date >= 0)) { + time_t t = date + time; + + if (is_localtime) { + struct tm tm; + tm = *gmtime(&t); + if (opt_utc) + wpt->creation_time = mkgmtime(&tm); + else + wpt->creation_time = mklocaltime(&tm); + } + else + wpt->creation_time = t; + } + else if (time >= 0) + wpt->creation_time = time; + else if (date >= 0) + wpt->creation_time = date; + else if (ymd.tm_year || ymd.tm_mon || ymd.tm_mday) { + if (ymd.tm_year < 100) { + if (ymd.tm_year <= 70) ymd.tm_year += 2000; + else ymd.tm_year += 1900; + } + ymd.tm_year -= 1900; + + if (ymd.tm_mon == 0) ymd.tm_mon = 1; + if (ymd.tm_mday == 0) ymd.tm_mday = 1; + + ymd.tm_mon--; + if (opt_utc) + wpt->creation_time = mkgmtime(&ymd); + else + wpt->creation_time = mklocaltime(&ymd); + } + else if (ymd.tm_hour || ymd.tm_min || ymd.tm_sec) { + if (opt_utc) + wpt->creation_time = mkgmtime(&ymd); + else + wpt->creation_time = mklocaltime(&ymd); + } + + if (msec >= 0) + wpt->microseconds = msec; + + if (opt_utc) + wpt->creation_time += atoi(opt_utc) * SECONDS_PER_HOUR; + } + + /* utm/bng/swiss can be optional */ + + if ((wpt->latitude == unicsv_unknown) && (wpt->longitude == unicsv_unknown)) { + if (utm_zone != -9999) { + GPS_Math_UTM_EN_To_Known_Datum(&wpt->latitude, &wpt->longitude, + utm_easting, utm_northing, utm_zone, utm_zc, unicsv_datum_idx); + } + else if (bng_zone[0]) { + if (! GPS_Math_UKOSMap_To_WGS84_M( + bng_zone, bng_easting, bng_northing, + &wpt->latitude, &wpt->longitude)) + fatal(MYNAME ": Unable to convert BNG coordinates (%s %.f %.f)!\n", + bng_zone, bng_easting, bng_northing); + src_datum = DATUM_WGS84; /* don't convert afterwards */ + } + else if ((swiss_easting != unicsv_unknown) && (swiss_northing != unicsv_unknown)) { + GPS_Math_CH1903_NGEN_To_WGS84(swiss_easting, swiss_northing, + &wpt->latitude, &wpt->longitude); + src_datum = DATUM_WGS84; /* don't convert afterwards */ + } + } + + if ((src_datum != DATUM_WGS84) && + (wpt->latitude != unicsv_unknown) && (wpt->longitude != unicsv_unknown)) { + double alt; + GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, (double) 0.0, + &wpt->latitude, &wpt->longitude, &alt, src_datum); + } + + switch(unicsv_data_type) { + case rtedata: + if (! unicsv_route) { + unicsv_route = route_head_alloc(); + route_add_head(unicsv_route); + } + route_add_wpt(unicsv_route, wpt); + break; + case trkdata: + if (! unicsv_track) { + unicsv_track = route_head_alloc(); + track_add_head(unicsv_track); + } + track_add_wpt(unicsv_track, wpt); + break; + default: + waypt_add(wpt); + } +} + +static void +unicsv_rd(void) +{ + char *buff; + + if (unicsv_fieldsep == NULL) return; + + while ((buff = gbfgetstr(fin))) { + buff = lrtrim(buff); + if ((*buff == '\0') || (*buff == '#')) continue; + unicsv_parse_one_line(buff); + } +} + +/* =========================================================================== */ + +static void +unicsv_fatal_outside(const waypoint *wpt) +{ + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": %s (%s) is outside of convertable area of grid \"%s\"!\n", + wpt->shortname ? wpt->shortname : "Waypoint", + pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), + gt_get_mps_grid_longname(unicsv_grid_idx, MYNAME)); +} + +static void +unicsv_print_str(const char *str) +{ + if (str && *str) { + char *cout, *cx; + + cout = strenquote(str, UNICSV_QUOT_CHAR); + + while ((cx = strstr(cout, "\r\n"))) { + memmove(cx, cx + 1, strlen(cx)); + *cx++ = ','; + lrtrim(cx); + } + while ((cx = strchr(cout, '\r'))) { + *cx++ = ','; + lrtrim(cx); + } + while ((cx = strchr(cout, '\n'))) { + *cx++ = ','; + lrtrim(cx); + } + + gbfprintf(fout, "%s%s", unicsv_fieldsep, cout); + xfree(cout); + } + else gbfputs(unicsv_fieldsep, fout); +} + +#define BIT_OF(a) (1ULL << a) +#define FIELD_USED(a) (unicsv_outp_flags & (1ULL << a)) + +static void +unicsv_waypt_enum_cb(const waypoint *wpt) +{ + char *shortname; + garmin_fs_t *gmsd; + + shortname = (wpt->shortname) ? wpt->shortname : ""; + gmsd = GMSD_FIND(wpt); + + if (*shortname) unicsv_outp_flags |= BIT_OF(fld_shortname); + if (wpt->altitude != unknown_alt) unicsv_outp_flags |= BIT_OF(fld_altitude); + if (wpt->icon_descr && *wpt->icon_descr) unicsv_outp_flags |= BIT_OF(fld_symbol); + if (wpt->description && *wpt->description && (strcmp(shortname, wpt->description) != 0)) + unicsv_outp_flags |= BIT_OF(fld_description); + if (wpt->notes && *wpt->notes && (strcmp(shortname, wpt->notes) != 0)) { + if ((! wpt->description) || (strcmp(wpt->description, wpt->notes) != 0)) + unicsv_outp_flags |= BIT_OF(fld_notes); + } + if (wpt->url && *wpt->url) unicsv_outp_flags |= BIT_OF(fld_url); + if (wpt->creation_time != 0) { + unicsv_outp_flags |= BIT_OF(fld_time); + if (wpt->creation_time >= SECONDS_PER_DAY) + unicsv_outp_flags |= BIT_OF(fld_date); + } + + if (wpt->fix != fix_unknown) unicsv_outp_flags |= BIT_OF(fld_fix); + if (wpt->vdop > 0) unicsv_outp_flags |= BIT_OF(fld_vdop); + if (wpt->hdop > 0) unicsv_outp_flags |= BIT_OF(fld_hdop); + if (wpt->pdop > 0) unicsv_outp_flags |= BIT_OF(fld_pdop); + if (wpt->sat > 0) unicsv_outp_flags |= BIT_OF(fld_sat); + if (wpt->heartrate != 0) unicsv_outp_flags |= BIT_OF(fld_heartrate); + if (wpt->cadence != 0) unicsv_outp_flags |= BIT_OF(fld_cadence); + + /* "flagged" waypoint members */ + if WAYPT_HAS(wpt, course) unicsv_outp_flags |= BIT_OF(fld_course); + if WAYPT_HAS(wpt, depth) unicsv_outp_flags |= BIT_OF(fld_depth); + if WAYPT_HAS(wpt, speed) unicsv_outp_flags |= BIT_OF(fld_speed); + if WAYPT_HAS(wpt, proximity) unicsv_outp_flags |= BIT_OF(fld_proximity); + if WAYPT_HAS(wpt, temperature) unicsv_outp_flags |= BIT_OF(fld_temperature); + + if (gmsd) { + if GMSD_HAS(addr) unicsv_outp_flags |= BIT_OF(fld_garmin_addr); + if GMSD_HAS(city) unicsv_outp_flags |= BIT_OF(fld_garmin_city); + if GMSD_HAS(country) unicsv_outp_flags |= BIT_OF(fld_garmin_country); + if GMSD_HAS(phone_nr) unicsv_outp_flags |= BIT_OF(fld_garmin_phone_nr); + if GMSD_HAS(postal_code) unicsv_outp_flags |= BIT_OF(fld_garmin_postal_code); + if GMSD_HAS(state) unicsv_outp_flags |= BIT_OF(fld_garmin_state); + if GMSD_HAS(facility) unicsv_outp_flags |= BIT_OF(fld_garmin_facility); + } +} + +static void +unicsv_waypt_disp_cb(const waypoint *wpt) +{ + double lat, lon, alt; + char *cout = NULL; + char *shortname; + garmin_fs_t *gmsd; + + unicsv_waypt_ct++; + + shortname = (wpt->shortname) ? wpt->shortname : ""; + gmsd = GMSD_FIND(wpt); + + if (unicsv_datum_idx == DATUM_WGS84) { + lat = wpt->latitude; + lon = wpt->longitude; + alt = wpt->altitude; + } + else { + GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, + &lat, &lon, &alt, unicsv_datum_idx); + } + + gbfprintf(fout, "%d%s", unicsv_waypt_ct, unicsv_fieldsep); + + switch(unicsv_grid_idx) { + + case grid_lat_lon_ddd: + cout = pretty_deg_format(lat, lon, 'd', unicsv_fieldsep, 0); + gbfputs(cout, fout); + break; + + case grid_lat_lon_dmm: + cout = pretty_deg_format(lat, lon, 'm', unicsv_fieldsep, 0); + gbfputs(cout, fout); + break; + + case grid_lat_lon_dms: { + char *sep, *tmp; + cout = pretty_deg_format(lat, lon, 's', unicsv_fieldsep, 0); + sep = strchr(cout, ','); + *sep = '\0'; + tmp = strenquote(cout, UNICSV_QUOT_CHAR); + gbfprintf(fout, "%s%s", tmp, unicsv_fieldsep); + xfree(tmp); + tmp = strenquote(sep+1, UNICSV_QUOT_CHAR); + gbfputs(tmp, fout); + xfree(tmp); + } + break; + + case grid_bng: { + char map[3]; + double north, east; + + if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map)) + unicsv_fatal_outside(wpt); + gbfprintf(fout, "%s%s%5.0f%s%5.0f", + map, unicsv_fieldsep, + east, unicsv_fieldsep, + north); + break; + } + case grid_utm: { + int zone; + char zonec; + double north, east; + + if (! GPS_Math_Known_Datum_To_UTM_EN(lat, lon, + &east, &north, &zone, &zonec, unicsv_datum_idx)) + unicsv_fatal_outside(wpt); + gbfprintf(fout, "%02d%s%c%s%.0f%s%.0f", + zone, unicsv_fieldsep, + zonec, unicsv_fieldsep, + east, unicsv_fieldsep, + north); + break; + } + case grid_swiss: { + double north, east; + + if (! GPS_Math_WGS84_To_CH1903_NGEN(wpt->latitude, wpt->longitude, &east, &north)) + unicsv_fatal_outside(wpt); + gbfprintf(fout, "%.f%s%.f%s", + east, unicsv_fieldsep, north, unicsv_fieldsep); + + } + default: + gbfprintf(fout, "%.6f%s%.6f", lat, unicsv_fieldsep, lon); + break; + } + + if (cout) xfree(cout); + + if FIELD_USED(fld_shortname) unicsv_print_str(shortname); + if FIELD_USED(fld_altitude) { + if (wpt->altitude != unknown_alt) + gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->altitude); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_description) unicsv_print_str(wpt->description); + if FIELD_USED(fld_notes) unicsv_print_str(wpt->notes); + if FIELD_USED(fld_symbol) + unicsv_print_str((wpt->icon_descr != NULL) ? wpt->icon_descr : "Waypoint"); + if FIELD_USED(fld_depth) { + if WAYPT_HAS(wpt, depth) + gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->depth); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_proximity) { + if WAYPT_HAS(wpt, proximity) + gbfprintf(fout, "%s%.f", unicsv_fieldsep, wpt->proximity); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_temperature) { + if WAYPT_HAS(wpt, temperature) + gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->temperature); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_speed) { + if WAYPT_HAS(wpt, speed) + gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->speed); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_course) { + if WAYPT_HAS(wpt, course) + gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->course); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_fix) { + char *fix; + switch(wpt->fix) { + case fix_none: fix = "none"; break; + case fix_2d: fix = "2d"; break; + case fix_3d: fix = "3d"; break; + case fix_dgps: fix = "dgps"; break; + case fix_pps: fix = "pps"; break; + default: fix = NULL; + } + if (fix) unicsv_print_str(fix); + else gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_hdop) { + if (wpt->hdop > 0) + gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->hdop); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_vdop) { + if (wpt->vdop > 0) + gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->vdop); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_pdop) { + if (wpt->pdop > 0) + gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->pdop); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_sat) { + if (wpt->sat > 0) + gbfprintf(fout, "%s%d", unicsv_fieldsep, wpt->sat); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_heartrate) { + if (wpt->heartrate != 0) + gbfprintf(fout, "%s%u", unicsv_fieldsep, wpt->heartrate); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_cadence) { + if (wpt->cadence != 0) + gbfprintf(fout, "%s%u", unicsv_fieldsep, wpt->cadence); + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_date) { + if (wpt->creation_time >= SECONDS_PER_DAY) { + struct tm tm; + char buf[32]; + time_t time = wpt->creation_time; + + if (opt_utc) { + time += atoi(opt_utc) * SECONDS_PER_HOUR; + tm = *gmtime(&time); + } + else tm = *localtime(&wpt->creation_time); + tm.tm_year += 1900; + tm.tm_mon += 1; + snprintf(buf, sizeof(buf), "%04d/%02d/%02d", tm.tm_year, tm.tm_mon, tm.tm_mday); + gbfprintf(fout, "%s%s", unicsv_fieldsep, buf); + } + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_time) { + if (wpt->creation_time != 0) { + struct tm tm; + char buf[32], msec[12]; + time_t time = wpt->creation_time; + + if (opt_utc) { + time += atoi(opt_utc) * SECONDS_PER_HOUR; + tm = *gmtime(&time); + } + else tm = *localtime(&wpt->creation_time); + snprintf(buf, sizeof(buf), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); + + if (wpt->microseconds > 0) { + int len = 6; + int ms = wpt->microseconds; + + while (len && (ms % 10 == 0)) { + ms /= 10; + len--; + } + snprintf(msec, sizeof(msec), ".%0*d", len, ms); + strcat(buf, msec); + } + gbfprintf(fout, "%s%s", unicsv_fieldsep, buf); + } + else + gbfputs(unicsv_fieldsep, fout); + } + if FIELD_USED(fld_url) unicsv_print_str(wpt->url); + + if FIELD_USED(fld_garmin_facility) unicsv_print_str(GMSD_GET(facility, NULL)); + if FIELD_USED(fld_garmin_addr) unicsv_print_str(GMSD_GET(addr, NULL)); + if FIELD_USED(fld_garmin_city) unicsv_print_str(GMSD_GET(city, NULL)); + if FIELD_USED(fld_garmin_postal_code) unicsv_print_str(GMSD_GET(postal_code, NULL)); + if FIELD_USED(fld_garmin_state) unicsv_print_str(GMSD_GET(state, NULL)); + if FIELD_USED(fld_garmin_country) unicsv_print_str(GMSD_GET(country, NULL)); + if FIELD_USED(fld_garmin_phone_nr) unicsv_print_str(GMSD_GET(phone_nr, NULL)); + + gbfputs(UNICSV_LINE_SEP, fout); +} + +/* --------------------------------------------------------------------------- */ + + +static void +unicsv_wr_init(const char *filename) +{ + fout = gbfopen(filename, "wb", MYNAME); + + unicsv_outp_flags = 0; + unicsv_grid_idx = grid_unknown; + unicsv_datum_idx = DATUM_WGS84; + unicsv_fieldsep = UNICSV_FIELD_SEP; + unicsv_waypt_ct = 0; + + if (opt_grid != NULL) { + int i; + + if (sscanf(opt_grid, "%d", &i)) { + unicsv_grid_idx = (grid_type) i; + if ((unicsv_grid_idx < GRID_INDEX_MIN) || (unicsv_grid_idx > GRID_INDEX_MAX)) + fatal(MYNAME ": Grid index out of range (%d..%d)!\n", + (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); + } + else unicsv_grid_idx = gt_lookup_grid_type(opt_grid, MYNAME); + } + + if (unicsv_grid_idx == grid_bng) + /* force datum to "Ord Srvy Grt Britn" / OSGB36 */ + /* ! ignore parameter "Datum" ! */ + unicsv_datum_idx = DATUM_OSGB36; + else if (unicsv_grid_idx == grid_swiss) + /* ! ignore parameter "Datum" ! */ + unicsv_datum_idx = DATUM_WGS84; /* internal, becomes CH1903 */ + else + unicsv_datum_idx = gt_lookup_datum_index(opt_datum, MYNAME); +} + +static void +unicsv_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +unicsv_wr(void) +{ + switch(global_opts.objective) { + case wptdata: + waypt_disp_all(unicsv_waypt_enum_cb); + break; + case trkdata: + track_disp_all(NULL, NULL, unicsv_waypt_enum_cb); + break; + case rtedata: + route_disp_all(NULL, NULL, unicsv_waypt_enum_cb); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + } + + gbfprintf(fout, "No%s", unicsv_fieldsep); + + switch(unicsv_grid_idx) { + case grid_bng: +/* indexed parameters doesn't work under __win32__ (mingw) + gbfprintf(fout, "BNG-Zone%1$sBNG-East%1$sBNG-North", unicsv_fieldsep); +*/ + gbfprintf(fout, "BNG-Zone%sBNG-East%sBNG-North", + unicsv_fieldsep, unicsv_fieldsep); + break; + case grid_utm: +/* indexed parameters doesn't work under __win32__ (mingw) + gbfprintf(fout, "BNG-Zone%1$sBNG-East%1$sBNG-North", unicsv_fieldsep); +*/ + gbfprintf(fout, "UTM-Zone%sUTM-Ch%sUTM-East%sUTM-North", + unicsv_fieldsep, unicsv_fieldsep, unicsv_fieldsep); + break; + case grid_swiss: + gbfprintf(fout, "Swiss-East%sSwiss-North", + unicsv_fieldsep); + break; + default: + gbfprintf(fout, "Latitude%sLongitude", unicsv_fieldsep); + } + + if FIELD_USED(fld_shortname) gbfprintf(fout, "%sName", unicsv_fieldsep); + if FIELD_USED(fld_altitude) gbfprintf(fout, "%sAltitude", unicsv_fieldsep); + if FIELD_USED(fld_description) gbfprintf(fout, "%sDescription", unicsv_fieldsep); + if FIELD_USED(fld_notes) gbfprintf(fout, "%sNotes", unicsv_fieldsep); + if FIELD_USED(fld_symbol) gbfprintf(fout, "%sSymbol", unicsv_fieldsep); + if FIELD_USED(fld_depth) gbfprintf(fout, "%sDepth", unicsv_fieldsep); + if FIELD_USED(fld_proximity) gbfprintf(fout, "%sProximity", unicsv_fieldsep); + if FIELD_USED(fld_temperature) gbfprintf(fout, "%sTemperature", unicsv_fieldsep); + if FIELD_USED(fld_speed) gbfprintf(fout, "%sSpeed", unicsv_fieldsep); + if FIELD_USED(fld_course) gbfprintf(fout, "%sCourse", unicsv_fieldsep); + if FIELD_USED(fld_fix) gbfprintf(fout, "%sFIX", unicsv_fieldsep); + if FIELD_USED(fld_hdop) gbfprintf(fout, "%sHDOP", unicsv_fieldsep); + if FIELD_USED(fld_vdop) gbfprintf(fout, "%sVDOP", unicsv_fieldsep); + if FIELD_USED(fld_pdop) gbfprintf(fout, "%sPDOP", unicsv_fieldsep); + if FIELD_USED(fld_sat) gbfprintf(fout, "%sSatellites", unicsv_fieldsep); + if FIELD_USED(fld_heartrate) gbfprintf(fout, "%sHeartrate", unicsv_fieldsep); + if FIELD_USED(fld_cadence) gbfprintf(fout, "%sCadence", unicsv_fieldsep); + if FIELD_USED(fld_date) gbfprintf(fout, "%sDate", unicsv_fieldsep); + if FIELD_USED(fld_time) gbfprintf(fout, "%sTime", unicsv_fieldsep); + if FIELD_USED(fld_url) gbfprintf(fout, "%sURL", unicsv_fieldsep); + if FIELD_USED(fld_garmin_facility) gbfprintf(fout, "%sFacility", unicsv_fieldsep); + if FIELD_USED(fld_garmin_addr) gbfprintf(fout, "%sAddress", unicsv_fieldsep); + if FIELD_USED(fld_garmin_city) gbfprintf(fout, "%sCity", unicsv_fieldsep); + if FIELD_USED(fld_garmin_postal_code) gbfprintf(fout, "%sPostalCode", unicsv_fieldsep); + if FIELD_USED(fld_garmin_state) gbfprintf(fout, "%sState", unicsv_fieldsep); + if FIELD_USED(fld_garmin_country) gbfprintf(fout, "%sCountry", unicsv_fieldsep); + if FIELD_USED(fld_garmin_phone_nr) gbfprintf(fout, "%sPhone", unicsv_fieldsep); + + gbfputs(UNICSV_LINE_SEP, fout); + + switch(global_opts.objective) { + case wptdata: + waypt_disp_all(unicsv_waypt_disp_cb); + break; + case trkdata: + track_disp_all(NULL, NULL, unicsv_waypt_disp_cb); + break; + case rtedata: + route_disp_all(NULL, NULL, unicsv_waypt_disp_cb); + break; + default: + break; + } +} + +/* --------------------------------------------------------------------------- */ + +ff_vecs_t unicsv_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + unicsv_rd_init, + unicsv_wr_init, + unicsv_rd_deinit, + unicsv_wr_deinit, + unicsv_rd, + unicsv_wr, + NULL, + unicsv_args, + CET_CHARSET_ASCII, 0 /* can be changed with -c ... */ +}; diff --git a/units.c b/units.c new file mode 100644 index 000000000..d3a85bfed --- /dev/null +++ b/units.c @@ -0,0 +1,94 @@ +/* + Display scaled distances in 'local' units. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +static int units = units_statute; + +int +fmt_setunits(fmt_units u) +{ + switch (u) { + case units_statute: + case units_metric: + units = u; + return 0; + default: + return 1; + } +} + +double +fmt_distance(const double distance_meters, char **tag) +{ + double d; + + switch (units) { + case units_statute: + d = METERS_TO_FEET(distance_meters); + if (d < 5280) { + *tag = "ft"; + } else { + d = METERS_TO_MILES(distance_meters); + *tag = "mi"; + } + break; + case units_metric: + d = distance_meters; + if (d < 1000) { + *tag = "meters"; + } else { + d = d / (double) 1000.0; + *tag = "km"; + } + break; + + default: + fatal("not done yet"); + break; + } + + return d; +} + +double +fmt_speed(const double distance_meters_sec, char **tag) +{ + double d; + + switch (units) { + case units_statute: + d = METERS_TO_MILES(distance_meters_sec) * SECONDS_PER_HOUR ; + *tag = "mph"; + break; + case units_metric: + d = distance_meters_sec * SECONDS_PER_HOUR; + *tag = "meters/hour"; + if (d > 1000.0) { + d /= 1000.0; + *tag = "km/hour"; + } + break; + default: fatal("not done yet"); + + } + return d; +} diff --git a/util.c b/util.c new file mode 100644 index 000000000..8ded3ea2a --- /dev/null +++ b/util.c @@ -0,0 +1,1732 @@ +/* + Misc utilities. + + Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "jeeps/gpsmath.h" + +#include +#include +#include +#include +#include +#include + +#if defined WORDS_BIGENDIAN +# define i_am_little_endian 0 +#else +# define i_am_little_endian 1 +#endif + +#ifdef DEBUG_MEM +#define DEBUG_FILENAME "/tmp/gpsbabel.debug" + +static FILE *debug_mem_file = NULL; +void +debug_mem_open() +{ + debug_mem_file = xfopen( DEBUG_FILENAME, "a", "debug" ); +} + +void +debug_mem_output(char *format, ...) +{ + va_list args; + va_start( args, format ); + if ( debug_mem_file ) { + vfprintf( debug_mem_file, format, args ); + fflush( debug_mem_file ); + } + va_end( args ); +} + +void +debug_mem_close() +{ + if ( debug_mem_file ) { + fclose(debug_mem_file); + } + debug_mem_file = NULL; +} +#endif + +void * +#ifdef DEBUG_MEM +XMALLOC(size_t size, DEBUG_PARAMS) +#else +xmalloc(size_t size) +#endif +{ + void *obj = malloc(size); + +#ifdef DEBUG_MEM + debug_mem_output( "malloc, %x, %d, %s, %d\n", + obj, size, file, line ); +#endif + if (!obj) { + fatal("gpsbabel: Unable to allocate %ld bytes of memory.\n", (unsigned long) size); + } + + return obj; +} + +void * +#ifdef DEBUG_MEM +XCALLOC(size_t nmemb, size_t size, DEBUG_PARAMS) +#else +xcalloc(size_t nmemb, size_t size) +#endif +{ + void *obj = calloc(nmemb, size); +#ifdef DEBUG_MEM + debug_mem_output( "calloc, %x, %d, %d, %s, %d\n", + obj, nmemb, size, file, line ); +#endif + + if (!obj) { + fatal("gpsbabel: Unable to allocate %ld units of %ld bytes of memory.\n", (unsigned long) nmemb, (unsigned long) size); + } + + return obj; +} + +void +#ifdef DEBUG_MEM +XFREE( void *mem, DEBUG_PARAMS ) +#else +xfree( void *mem ) +#endif +{ + free(mem); +#ifdef DEBUG_MEM + debug_mem_output( "free, %x, %s, %d\n", + mem, file, line ); +#endif +} + +char * +#ifdef DEBUG_MEM +XSTRDUP(const char *s, DEBUG_PARAMS ) +#else +xstrdup(const char *s) +#endif +{ + char *o = s ? strdup(s) : strdup(""); +#ifdef DEBUG_MEM + debug_mem_output( "strdup, %x, %x, %s, %d\n", + o, s, file, line ); +#endif + + if (!o) { + fatal("gpsbabel: Unable to allocate %ld bytes of memory.\n", (unsigned long) strlen(s)); + } + + return o; +} + +/* + * Duplicate at most sz bytes in str. + */ +char * +#ifdef DEBUG_MEM +XSTRNDUP(const char *str, size_t sz, DEBUG_PARAMS ) +#else +xstrndup(const char *str, size_t sz) +#endif +{ + size_t newlen = 0; + char *cin = (char *)str; + char *newstr; + + while ((newlen < sz) && (*cin != '\0')) { + newlen++; + cin++; + } + + newstr = (char *) xmalloc(newlen + 1); + memcpy(newstr, str, newlen); + newstr[newlen] = 0; + + return newstr; +} + +/* + * Lazily trim whitespace (though not from allocated version) + * while copying. + */ +char * +#ifdef DEBUG_MEM +XSTRNDUPT(const char *str, size_t sz, DEBUG_PARAMS ) +#else +xstrndupt(const char *str, size_t sz) +#endif +{ + size_t newlen = 0; + char *cin = (char *)str; + char *newstr; + + while ((newlen < sz) && (*cin != '\0')) { + newlen++; + cin++; + } + + newstr = (char *) xmalloc(newlen + 1); + memcpy(newstr, str, newlen); + newstr[newlen] = 0; + rtrim(newstr); + + return newstr; +} + +void * +#ifdef DEBUG_MEM +XREALLOC(void *p, size_t s, DEBUG_PARAMS ) +#else +xrealloc(void *p, size_t s) +#endif +{ + char *o = (char *) realloc(p,s); +#ifdef DEBUG_MEM + debug_mem_output( "realloc, %x, %x, %x, %s, %d\n", + o, p, s, file, line ); +#endif + + if (!o) { + fatal("gpsbabel: Unable to realloc %ld bytes of memory.\n", (unsigned long) s); + } + + return o; +} + +/* +* For an allocated string, realloc it and append 's' +*/ +char * +#ifdef DEBUG_MEM +XSTRAPPEND(char *src, const char *newd, DEBUG_PARAMS) +#else +xstrappend(char *src, const char *newd) +#endif +{ + size_t newsz; + + if (!src) { + return xxstrdup(newd, file, line); + } + if (!newd) { + return xxstrdup(src, file, line); + } + + newsz = strlen(src) + strlen(newd) + 1; + src = xxrealloc(src, newsz, file, line); + strcat(src, newd); + + return src; +} + +/* + * Wrapper for open that honours - for stdin, stdout, unifies error text. + */ +FILE * +xfopen(const char *fname, const char *type, const char *errtxt) +{ + FILE *f; + int am_writing = strchr(type, 'w') != NULL; + + if (fname == NULL) { + fatal("%s must have a filename specified for %s.\n", + errtxt, am_writing ? "write" : "read"); + } + + if (0 == strcmp(fname, "-")) + return am_writing ? stdout : stdin; + f = fopen(fname, type); + if (NULL == f) { + fatal("%s cannot open '%s' for %s. Error was '%s'.\n", + errtxt, fname, + am_writing ? "write" : "read", + strerror(errno)); + } + return f; +} + +void +xfprintf(const char *errtxt, FILE *stream, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + if (vfprintf(stream, format, ap) < 0) { + fatal("%s writing output file. Error was '%s'.\n", + errtxt, strerror(errno)); + } + va_end(ap); +} + +void +xfputs(const char *errtxt, const char *s, FILE *stream) +{ + if (fputs(s, stream) < 0) { + fatal("%s Writing output file. Error was '%s'.\n", + errtxt, strerror(errno)); + } +} + +/* + * Allocate a string using a format list with optional arguments + * Returns -1 on error. + * If return value is anything else, *strp will be populated with an + * allocated string containging the formatted buffer. + * + * Freeing that is the responsbility of the caller. + */ + +int +xasprintf(char **strp, const char *fmt, ...) +{ + va_list args; + int res; + + va_start(args, fmt); + res = xvasprintf(strp, fmt, args); + va_end(args); + + return res; +} + +int +xvasprintf(char **strp, const char *fmt, va_list ap) +{ +/* From http://perfec.to/vsnprintf/pasprintf.c */ +/* size of first buffer malloc; start small to exercise grow routines */ +#ifdef DEBUG_MEM +# define FIRSTSIZE 64 +#else +# define FIRSTSIZE 1 +#endif + char *buf = NULL; + int bufsize; + char *newbuf; + size_t nextsize = 0; + int outsize; + va_list args; + + bufsize = 0; + for (;;) { + if (bufsize == 0) { + if ((buf = xmalloc(FIRSTSIZE)) == NULL) { + *strp = NULL; + return -1; + } + bufsize = FIRSTSIZE; + } else if ((newbuf = xrealloc(buf, nextsize)) != NULL) { + buf = newbuf; + bufsize = nextsize; + } else { + xfree(buf); + *strp = NULL; + return -1; + } + + va_copy(args, ap); + outsize = vsnprintf(buf, bufsize, fmt, args); + va_end(args); + + if (outsize == -1) { + /* Clear indication that output was truncated, but no + * clear indication of how big buffer needs to be, so + * simply double existing buffer size for next time. + */ + nextsize = bufsize * 2; + + } else if (outsize == bufsize) { + /* Output was truncated (since at least the \0 could + * not fit), but no indication of how big the buffer + * needs to be, so just double existing buffer size + * for next time. + */ + nextsize = bufsize * 2; + + } else if (outsize > bufsize) { + /* Output was truncated, but we were told exactly how + * big the buffer needs to be next time. Add two chars + * to the returned size. One for the \0, and one to + * prevent ambiguity in the next case below. + */ + nextsize = outsize + 2; + + } else if (outsize == bufsize - 1) { + /* This is ambiguous. May mean that the output string + * exactly fits, but on some systems the output string + * may have been trucated. We can't tell. + * Just double the buffer size for next time. + */ + nextsize = bufsize * 2; + + } else { + /* Output was not truncated */ + break; + } + } + /* Prevent us from allocating millions of unused bytes. */ + /* O.K.: I think this is not the final solution. */ + if (bufsize > outsize + 1) { + const unsigned ptrsz = sizeof(buf); + if (((bufsize + ptrsz + 1) / ptrsz) > ((outsize + ptrsz + 1) / ptrsz)) + buf = xrealloc(buf, outsize + 1); + + } + *strp = buf; + return outsize; +} + + +/* + * Duplicate a pascal string into a normal C string. + */ +char * +pstrdup(char *src) +{ + int len = src[0]; + char *obuf = xmalloc(len + 1); + + memcpy(obuf, src + 1, len); + obuf[len] = 0; + + return obuf; +} + +void +rtrim(char *s) +{ + char *t = s; + + if (!s || !*s) { + return; + } + + while (*s) { + s++; + } + + s--; + while ((s >= t) && isspace (*s)) { + *s = 0; + s--; + } +} + +/* + * Like trim, but trims whitespace from both beginning and end. + */ +char * +lrtrim(char *buff) +{ + char *c; + + if (buff[0] == '\0') + return buff; + + c = buff + strlen(buff); + while ((c >= buff) && ((unsigned char)*c <= ' ')) *c-- = '\0'; + + c = buff; + while ((*c != '\0') && ((unsigned char)*c <= ' ')) c++; + + if (c != buff) { + char *src = c; + char *dst = buff; + + while (*src) *dst++ = *src++; + *dst = '\0'; + } + + return buff; +} + +/* + * Like strcmp, but case insensitive. Like Berkeley's strcasecmp. + */ + +int +case_ignore_strcmp(const char *s1, const char *s2) +{ + for(;toupper(*s1) == toupper(*s2); ++ s1, ++s2) { + if (*s1 == 0) + return 0; + } + return (toupper(*s1) < toupper(*s2)) ? -1 : +1; + +} + +int +case_ignore_strncmp(const char *s1, const char *s2, int n) +{ + int rv = 0; + + while (n && ((rv = toupper(*s1) - toupper(*s2)) == 0) + && *s1) { + s1++; + s2++; + n--; + } + return rv; +} + +/* + * compare str with match + * match may contain wildcards "*" and "?" + * + * examples: + * str_match("ABCDE", "*BC*") -> 1 + * str_match("ABCDE", "A*C*E") -> 1 + * str_match("?ABCDE", "\\?A*") -> 1 + * str_match("", "*A") -> 0 + */ + +int +str_match(const char *str, const char *match) +{ + char *m, *s; + + s = (char *)str; + m = (char *)match; + + while (*m || *s) + { + switch(*m) + { + + case '\0': + /* there is something left in s, FAIL */ + return 0; + + case '*': + /* skip all wildcards */ + while ((*m == '*') || (*m == '?')) m++; + if (*m == '\0') return 1; + + if (*m == '\\') /* ? escaped ? */ + { + m++; + if (*m == '\0') return 0; + } + + do + { + char *mx, *sx; + + while (*s && (*s != *m)) s++; + if (*s == '\0') return 0; + + sx = s + 1; + mx = m + 1; + + while (*sx) + { + if (*mx == '\\') /* ? escaped ? */ + { + mx++; + if (*mx == '\0') return 0; + + } + if (*sx == *mx) + { + sx++; + mx++; + } + else + break; + } + if (*mx == '\0') /* end of match */ + { + if (*sx == '\0') return 1; + s++; + } + else if ((*mx == '?') || (*mx == '*')) + { + s = sx; + m = mx; + break; + } + else + s++; + } while (*s); + break; + + case '?': + if (*s == '\0') return 0; /* no character left */ + m++; + s++; + break; + + case '\\': + m++; + if (*m == '\0') return 0; /* incomplete escape sequence */ + /* pass-through next character */ + + default: + if (*m != *s) return 0; + m++; + s++; + } + } + return ((*s == '\0') && (*m == '\0')); +} + +/* + * as str_match, but case insensitive + */ + +int +case_ignore_str_match(const char *str, const char *match) +{ + char *s1, *s2; + int res; + + s1 = strupper(xstrdup(str)); + s2 = strupper(xstrdup(match)); + res = str_match(s1, s2); + xfree(s1); + xfree(s2); + + return res; +} + +char * +strenquote(const char *str, const char quot_char) +{ + int len; + char *cin, *cout; + char *tmp; + + if (str == NULL) cin = ""; + else cin = (char *)str; + + len = strlen(cin); + cout = tmp = xmalloc((len * 2) + 3); + + *cout++ = quot_char; + while (*cin) { + *cout++ = *cin; + if (*cin++ == quot_char) + *cout++ = quot_char; + } + *cout++ = quot_char; + *cout = '\0'; + + cout = xstrdup(tmp); + xfree(tmp); + return cout; +} + +void +printposn(const double c, int is_lat) +{ + char d; + if (is_lat) { + if (c < 0) d = 'S'; else d = 'N'; + } else { + if (c < 0) d = 'W'; else d = 'E'; + } + printf("%f%c ", fabs(c), d); +} + +void +is_fatal(const int condition, const char *fmt, ...) +{ + va_list args; + char buff[128]; + + if (condition == 0) return; + + va_start(args, fmt); + vsnprintf(buff, sizeof(buff), fmt, args); + va_end(args); + + fatal("%s\n", buff); +} + +/* + * Read 4 bytes in big-endian. Return as "int" in native endianness. + */ +signed int +be_read32(const void *p) +{ + unsigned char *i = (unsigned char *) p; + return i[0] << 24 | i[1] << 16 | i[2] << 8 | i[3]; +} + +signed int +be_read16(const void *p) +{ + unsigned char *i = (unsigned char *) p; + return i[0] << 8 | i[1]; +} + +void +be_write16(void *addr, const unsigned value) +{ + unsigned char *p = addr; + p[0] = value >> 8; + p[1] = value; + +} + +void +be_write32(void *pp, const unsigned i) +{ + char *p = (char *)pp; + + p[0] = (i >> 24) & 0xff; + p[1] = (i >> 16) & 0xff; + p[2] = (i >> 8) & 0xff; + p[3] = i & 0xff; +} + +signed int +le_read16(const void *addr) +{ + const unsigned char *p = addr; + return p[0] | (p[1] << 8); +} + +unsigned int +le_readu16(const void *addr) +{ + const unsigned char *p = addr; + return p[0] | (p[1] << 8); +} + +signed int +le_read32(const void *addr) +{ + const unsigned char *p = addr; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + +unsigned int +le_readu32(const void *addr) +{ + const unsigned char *p = addr; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + +/* + * Read a little-endian 64-bit value from 'src' and return it in 'dest' + * in host endianness. + */ +void +le_read64(void *dest, const void *src) +{ + char *cdest = dest; + const char *csrc = src; + + if (i_am_little_endian) { + memcpy(dest, src, 8); + } else { + int i; + for (i = 0; i < 8; i++) { + cdest[i] = csrc[7-i]; + } + } +} + +void +le_write16(void *addr, const unsigned value) +{ + unsigned char *p = addr; + p[0] = value; + p[1] = value >> 8; + +} + +void +le_write32(void *addr, const unsigned value) +{ + unsigned char *p = addr; + p[0] = value; + p[1] = value >> 8; + p[2] = value >> 16; + p[3] = value >> 24; +} + +signed int +si_round( double d ) +{ + if ( d < 0 ) { + return (signed int)(d-0.5); + } + else { + return (signed int)(d+0.5); + } +} + +/* + * Return a time_t suitable for adding to a time_t that is in GMT to + * make it a local time. + * Obsolete: to use mkgmtime instead. + */ +signed int +get_tz_offset(void) +{ + time_t now = current_time(); + time_t later = mktime(gmtime(&now)); + + if (later == -1) { + return 0; + } else { + return (signed int) difftime(now, later); + } +} + +/* + mkgmtime -- convert tm struct in UTC to time_t + + works just like mktime but without all the mucking + around with timezones and daylight savings + + obsoletes get_tz_offset() + + Borrowed from lynx GPL source code + http://lynx.isc.org/release/lynx2-8-5/src/mktime.c + + Written by Philippe De Muyter . +*/ + +time_t +mkgmtime(struct tm *t) +{ + short month, year; + time_t result; + static int m_to_d[12] = + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + + month = t->tm_mon; + year = t->tm_year + month / 12 + 1900; + month %= 12; + if (month < 0) + { + year -= 1; + month += 12; + } + result = (year - 1970) * 365 + m_to_d[month]; + if (month <= 1) + year -= 1; + result += (year - 1968) / 4; + result -= (year - 1900) / 100; + result += (year - 1600) / 400; + result += t->tm_mday; + result -= 1; + result *= 24; + result += t->tm_hour; + result *= 60; + result += t->tm_min; + result *= 60; + result += t->tm_sec; + return(result); +} + +/* + * mklocaltime: same as mktime, but try to recover the "Summer time flag", + * which is evaluated by mktime + */ +time_t +mklocaltime(struct tm *t) +{ + time_t result; + struct tm check = *t; + + check.tm_isdst = 0; + result = mktime(&check); + check = *localtime(&result); + if (check.tm_isdst == 1) { /* DST is in effect */ + check = *t; + check.tm_isdst = 1; + result = mktime(&check); + } + return result; +} + +/* + * A wrapper for time(2) that allows us to "freeze" time for testing. + */ +time_t +current_time(void) +{ + if (getenv("GPSBABEL_FREEZE_TIME")) { + return 0; + } + + return time(NULL); +} + +/* + * Return the (zero based) month number of the year or -1 for failure. + */ +signed int +month_lookup(const char *m) +{ + static const char *months[] = { + "JAN", "FEB", "MAR", "APR", "MAY", "JUN", + "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", NULL }; + const char **mp; + + for (mp = months; *mp; mp++) { + if (0 == case_ignore_strcmp(*mp, m)) + return mp - months; + } + return -1; +} + +/* + * Return a pointer to a constant string that is suitable for icon lookup + * based on geocache attributes. The strings used are those present in + * a GPX file from geocaching.com. Thus we sort of make all the other + * formats do lookups based on these strings. + */ +const char * +get_cache_icon(const waypoint *waypointp) +{ + if (!global_opts.smart_icons) + return NULL; + + /* + * For icons, type overwrites container. So a multi-micro will + * get the icons for "multi". + */ + switch (waypointp->gc_data.type) { + case gt_virtual: + return "Virtual cache"; + case gt_multi: + return "Multi-Cache"; + case gt_event: + return "Event Cache"; + case gt_suprise: + return "Unknown Cache"; + case gt_webcam: + return "Webcam Cache"; + default: + break; + } + + switch (waypointp->gc_data.container) { + case gc_micro: + return "Micro-Cache"; + break; + default: + break; + } + + if (waypointp->gc_data.diff > 1) { + return "Geocache"; + } + + return NULL; +} + +double +endian_read_double(void* ptr, int read_le) +{ + double ret; + char r[8]; + void *p; + int i; + + if ( i_am_little_endian == read_le ) { + p = ptr; + } + else { + for (i = 0; i < 8; i++) + { + r[i] = ((char*)ptr)[7-i]; + } + p = r; + } + + memcpy(&ret, p, 8); + return ret; +} + +float +endian_read_float(void* ptr, int read_le) +{ + float ret; + char r[4]; + void *p; + int i; + + if ( i_am_little_endian == read_le ) { + p = ptr; + } + else { + for (i = 0; i < 4; i++) + { + r[i] = ((char*)ptr)[3-i]; + } + p = r; + } + + memcpy(&ret, p, 4); + return ret; +} + +void +endian_write_double(void* ptr, double d, int write_le) +{ + char *r = (char *)(void *)&d; + int i; + char *optr = ptr; + + if ( i_am_little_endian == write_le ) { + memcpy( ptr, &d, 8); + } + else { + for (i = 0; i < 8; i++) + { + *optr++ = r[7-i]; + } + } +} + +void +endian_write_float(void* ptr, float f, int write_le) +{ + char *r = (char *)(void *)&f; + int i; + char *optr = ptr; + + if ( i_am_little_endian == write_le ) { + memcpy( ptr, &f, 4); + } + else { + for (i = 0; i < 4; i++) + { + *optr++ = r[3-i]; + } + } +} + +float +le_read_float( void *ptr ) {return endian_read_float(ptr, 1);} + +void +le_write_float( void *ptr, float f ) {endian_write_float(ptr,f,1);} + +float +be_read_float( void *ptr ) {return endian_read_float(ptr, 0);} + +void +be_write_float( void *ptr, float f ) {endian_write_float(ptr,f,0);} + +double +le_read_double( void *ptr ) {return endian_read_double(ptr,1);} + +void +le_write_double( void *ptr, double d ) {endian_write_double(ptr,d,1);} + +double +be_read_double( void *ptr ) {return endian_read_double(ptr,0);} + +void +be_write_double( void *ptr, double d ) {endian_write_double(ptr,d,0);} + + +/* Magellan and PCX formats use this DDMM.mm format */ +double ddmm2degrees(double pcx_val) { + double minutes; + signed int deg; + deg = (signed int) (pcx_val / 100.0); + minutes = (((pcx_val / 100.0) - deg) * 100.0) / 60.0; + return (double) deg + minutes; +} + +double degrees2ddmm(double deg_val) { + signed int deg; + deg = (signed int) deg_val; + return (double) (deg * 100.0) + ((deg_val - deg) * 60.0); +} + +/* + * replace a single occurrence of "search" in "s" with "replace". + * Returns an allocated copy if substitution was made, otherwise returns NULL. + * Doesn't try to make an optimally sized dest buffer. + */ +char * +strsub(const char *s, const char *search, const char *replace) +{ + char *p; + int len = strlen(s); + int slen = strlen(search); + int rlen = strlen(replace); + char *d; + + p = strstr(s, search); + if (!slen || !p) { + return NULL; + } + + d = xmalloc(len + rlen); + + /* Copy first part */ + len = p - s; + memcpy(d, s, len); + d[len] = 0; + + /* Copy replacement */ + strcat(d, replace); + + /* Copy last part */ + strcat(d, p + slen); + return d; +} + +/* + * As strsub, but do it globally. + */ +char * +gstrsub(const char *s, const char *search, const char *replace) +{ + int ooffs = 0; + char *o, *c; + char *src = (char *)s; + int olen = strlen(src); + int slen = strlen(search); + int rlen = strlen(replace); + + o = xmalloc(olen + 1); + + while ((c = strstr(src, search))) { + olen += (rlen - slen); + o = xrealloc(o, olen + 1); + memcpy(o + ooffs, src, c - src); + ooffs += (c - src); + src = c + slen; + if (rlen) { + memcpy(o + ooffs, replace, rlen); + ooffs += rlen; + } + } + + if (ooffs < olen) + memcpy(o + ooffs, src, olen - ooffs); + o[olen] = '\0'; + return o; +} + +/* + * Like strstr, but starts from back of string. + */ +char * +xstrrstr(const char *s1, const char *s2) +{ + char *r = NULL, *next = NULL; + + while (next = strstr(s1, s2), NULL != next) { + r = next; + s1 = next + 1; + } + return r; +} + +/* + * + */ +char * +strupper(char *src) +{ + char *c; + + for (c = src; *c; c++) { + *c = toupper(*c); + } + return src; +} + +/* + * + */ +char * +strlower(char *src) +{ + char *c; + + for (c = src; *c; c++) { + *c = tolower(*c); + } + return src; +} + +char * +rot13( const char *s ) +{ + char *result = xstrdup( s ); + char *cur = result; + int flip = 1; + while (cur && *cur ) { + if ( flip ) { + if (*cur == '[') flip = 0; + else if ( *cur >= 'A' && *cur <= 'Z' ) { + *cur = 'A' + ((*cur-'A')+13)%26; + } + else if ( *cur >= 'a' && *cur <= 'z' ) { + *cur = 'a' + ((*cur-'a')+13)%26; + } + } + else if ( *cur == ']' ) flip = 1; + cur++; + } + return result; +} + +/* + * Convert a human readable date format (i.e. "YYYY/MM/DD") into + * a format usable for strftime and others + */ + +char * +convert_human_date_format(const char *human_datef) +{ + char *result, *cin, *cout; + char prev; + int ylen; + + result = xcalloc((2*strlen(human_datef)) + 1, 1); + cout = result; + prev = '\0'; + ylen = 0; + + for (cin = (char *)human_datef; *cin; cin++) + { + char okay = 1; + + if (toupper(*cin) != 'Y') ylen = 0; + if (isalpha(*cin)) + { + switch(*cin) + { + case 'y': case 'Y': + if (prev != 'Y') + { + strcat(cout, "%y"); + cout += 2; + prev = 'Y'; + } + ylen++; + if (ylen > 2) *(cout-1) = 'Y'; + break; + case 'm': case 'M': + if (prev != 'M') + { + strcat(cout, "%m"); + cout += 2; + prev = 'M'; + } + break; + case 'd': case 'D': + if (prev != 'D') + { + strcat(cout, "%d"); + cout += 2; + prev = 'D'; + } + break; + default: + okay = 0; + } + } + else if (ispunct(*cin)) + { + *cout++ = *cin; + prev = '\0'; + } + else okay = 0; + + is_fatal(okay == 0, "Invalid character \"%c\" in date format!", *cin); + } + return result; +} + +/* + * Convert a human readable time format (i.e. "HH:mm:ss") into + * a format usable for strftime and others + */ + +char * +convert_human_time_format(const char *human_timef) +{ + char *result, *cin, *cout; + char prev; + + result = xcalloc((2*strlen(human_timef)) + 1, 1); + cout = result; + prev = '\0'; + + for (cin = (char *)human_timef; *cin; cin++) + { + int okay = 1; + + if (isalpha(*cin)) + { + switch(*cin) + { + case 'S': case 's': + if (prev != 'S') { + strcat(cout, "%S"); + cout += 2; + prev = 'S'; + } + break; + + case 'M': case 'm': + if (prev != 'M') { + strcat(cout, "%M"); + cout += 2; + prev = 'M'; + } + break; + + case 'h': /* 12-hour-clock */ + if (prev != 'H') { + strcat(cout, "%l"); /* 1 .. 12 */ + cout += 2; + prev = 'H'; + } + else *(cout-1) = 'I'; /* 01 .. 12 */ + break; + + case 'H': /* 24-hour-clock */ + if (prev != 'H') { + strcat(cout, "%k"); + cout += 2; + prev = 'H'; + } + else *(cout-1) = 'H'; + break; + + case 'x': + if (prev != 'X') { + strcat(cout, "%P"); + cout += 2; + prev = 'X'; + } + else *(cout-1) = 'P'; + break; + + case 'X': + if (prev != 'X') { + strcat(cout, "%p"); + cout += 2; + prev = 'X'; + } + else *(cout-1) = 'p'; + break; + + default: + okay = 0; + } + } + else if (ispunct(*cin) || isspace(*cin)) + { + *cout++ = *cin; + prev = '\0'; + } + else okay = 0; + + is_fatal(okay == 0, "Invalid character \"%c\" in time format!", *cin); + } + return result; +} + + +/* + * Return a decimal degree pair as + * DD.DDDDD DD MM.MMM or DD MM SS.S + * fmt = ['d', 'm', 's'] + * sep = string between lat and lon (separator) + * html = 1 for html output otherwise text + */ +char * +pretty_deg_format(double lat, double lon, char fmt, char *sep, int html) +{ + double latmin, lonmin, latsec, lonsec; + int latint, lonint; + char latsig, lonsig; + char *result; + latsig = lat < 0 ? 'S':'N'; + lonsig = lon < 0 ? 'W':'E'; + latint = abs((int) lat); + lonint = abs((int) lon); + latmin = 60.0 * (fabs(lat) - latint); + lonmin = 60.0 * (fabs(lon) - lonint); + latsec = 60.0 * (latmin - floor(latmin)); + lonsec = 60.0 * (lonmin - floor(lonmin)); + if (sep == NULL) sep = " "; /* default " " */ + if (fmt == 'd') { /* ddd */ + xasprintf ( &result, "%c%6.5f%s%s%c%6.5f%s", + latsig, fabs(lat), html?"°":"", sep, + lonsig, fabs(lon), html?"°":"" ); + } + else if (fmt == 's') { /* dms */ + xasprintf ( &result, "%c%d%s%02d'%04.1f\"%s%c%d%s%02d'%04.1f\"", + latsig, latint, html?"°":" ", (int)latmin, latsec, sep, + lonsig, lonint, html?"°":" ", (int)lonmin, lonsec); + } + else { /* default dmm */ + xasprintf ( &result, "%c%d%s%06.3f%s%c%d%s%06.3f", + latsig, latint, html?"°":" ", latmin, sep, + lonsig, lonint, html?"°":" ", lonmin); + } + return result; +} + + + +/* + * Get rid of potentially nasty HTML that would influence another record + * that includes; + * - to stop backgrounds/background colours from being loaded + * and - stop processing altogether + * - stop overriding styles for everything + */ +char * +strip_nastyhtml(const char * in) +{ + char *returnstr, *sp; + char *lcstr, *lcp; + + sp = returnstr = xstrdup(in); + lcp = lcstr = strlower(xstrdup(in)); + + while (lcp = strstr(lcstr, ""), NULL != lcp) { + sp = returnstr + (lcp - lcstr) ; /* becomes */ + sp++; *sp++ = '!'; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; + *lcp = '*'; /* so we wont find it again */ + } + while (lcp = strstr(lcstr, " */ + sp = returnstr + (lcp - lcstr) ; + sp++; *sp++ = '!'; *sp++ = '-'; *sp++ = '-'; + while ( (*sp) && (*sp != '>') ) { + sp++; + } + *--sp = '-'; *--sp = '-'; + *lcp = '*'; /* so we wont find it again */ + } + while (lcp = strstr(lcstr, ""), NULL != lcp) { + sp = returnstr + (lcp - lcstr) ; /* becomes */ + *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = '-'; *sp++ = '-'; + *lcp = '*'; /* so we wont find it again */ + } + while (lcp = strstr(lcstr, "utfstring; + char tag[8]; + unsigned short int taglen = 0; + + if (!in->is_html) + return xstrdup(in->utfstring); + /* + * We only shorten, so just dupe the input buf for space. + */ + + outstring = out = xstrdup(in->utfstring); + + tag[0] = 0; + while (*instr) { + if ((*instr == '<') || (*instr == '&')) { + tag[0] = *instr; + taglen = 0; + } + + if (! tag[0]) { + if (*instr == '\n') { + *out++ = ' '; + do { + instr++; + } while (isspace(*instr)); + continue; + } else { + *out++ = *instr; + } + } + else { + if (taglen < (sizeof(tag)-1)) { + tag[taglen++] = tolower(*instr); + tag[taglen] = 0; + } + } + + if ( ((tag[0] == '<') && (*instr == '>')) || + ((tag[0] == '&') && (*instr == ';')) ) { + if (! strcmp(tag,"&")) + *out++ = '&'; + else if (! strcmp (tag, "<")) + *out++ = '<'; + else if (! strcmp (tag, ">")) + *out++ = '>'; + else if (! strcmp (tag, """)) + *out++ = '"'; + else if (! strcmp (tag, " ")) + *out++ = ' '; + else if (! strcmp (tag, "°")) { + *out++ = 'd'; *out++ = 'e'; *out++ = 'g'; + } + else if ((tag[0]=='<') && (tag[1]=='p')) + *out++ = '\n'; + else if ((tag[0]=='<') && (tag[1]=='b') && (tag[2]=='r')) + *out++ = '\n'; + else if ((tag[0]=='<') && (tag[1]=='/') && (tag[2]=='t') && (tag[3]=='r')) + *out++ = '\n'; + else if ((tag[0]=='<') && (tag[1]=='/') && (tag[2]=='t') && (tag[3]=='d')) + *out++ = ' '; + else if ((tag[0]=='<') && (tag[1]=='i') && (tag[2]=='m') && (tag[3]=='g')) { + *out++ = '['; *out++ = 'I'; *out++ = 'M'; *out++ = 'G'; *out++ = ']'; + } + + tag[0] = 0; + } + instr++; + } + *out++ = 0; + return (outstring); +} + +typedef struct { + const char * text; + const char * entity; + int not_html; +} entity_types; + +static +entity_types stdentities[] = { + { "&", "&", 0 }, + { "'", "'", 1 }, + { "<", "<", 0 }, + { ">", ">", 0 }, + { "\"", """, 0 }, + { NULL, NULL, 0 } +}; + +static +char * +entitize(const char * str, int is_html) +{ + int elen, ecount, nsecount; + entity_types *ep; + const char * cp; + char * p, * tmp, * xstr; + + int bytes = 0; + int value = 0; + ep = stdentities; + elen = ecount = nsecount = 0; + + /* figure # of entity replacements and additional size. */ + while (ep->text) { + cp = str; + while ((cp = strstr(cp, ep->text)) != NULL) { + elen += strlen(ep->entity) - strlen(ep->text); + ecount++; + cp += strlen(ep->text); + } + ep++; + } + + /* figure the same for other than standard entities (i.e. anything + * that isn't in the range U+0000 to U+007F */ + +#if 0 + for ( cp = str; *cp; cp++ ) { + if ( *cp & 0x80 ) { + cet_utf8_to_ucs4( cp, &bytes, &value ); + cp += bytes-1; + elen += sprintf( tmpsub, "&#x%x;", value ) - bytes; + nsecount++; + } + } +#endif + + /* enough space for the whole string plus entity replacements, if any */ + tmp = xcalloc((strlen(str) + elen + 1), 1); + strcpy(tmp, str); + + /* no entity replacements */ + if (ecount == 0 && nsecount == 0) + return (tmp); + + if ( ecount != 0 ) { + for (ep = stdentities; ep->text; ep++) { + p = tmp; + if (is_html && ep->not_html) { + continue; + } + while ((p = strstr(p, ep->text)) != NULL) { + elen = strlen(ep->entity); + + xstr = xstrdup(p + strlen(ep->text)); + + strcpy(p, ep->entity); + strcpy(p + elen, xstr); + + xfree(xstr); + + p += elen; + } + } + } + + if ( nsecount != 0 ) { + p = tmp; + while (*p) { + if ( *p & 0x80 ) { + cet_utf8_to_ucs4( p, &bytes, &value ); + if ( p[bytes] ) { + xstr = xstrdup( p + bytes ); + } + else { + xstr = NULL; + } + sprintf( p, "&#x%x;", value ); + p = p+strlen(p); + if ( xstr ) { + strcpy( p, xstr ); + xfree(xstr); + } + } + else { + p++; + } + } + } + return (tmp); +} + +/* + * Public callers for the above to hide the absence of &apos from HTML + */ + +char * xml_entitize(const char * str) +{ + return entitize(str, 0); +} + +char * html_entitize(const char * str) +{ + return entitize(str, 1); +} + +/* + * xml_tag utilities + */ + +xml_tag *xml_next( xml_tag *root, xml_tag *cur ) +{ + if ( cur->child ) { + cur = cur->child; + } + else if ( cur->sibling ) { + cur = cur->sibling; + } + else { + cur = cur->parent; + if ( cur == root ) { + cur = NULL; + } + if ( cur ) { + cur = cur->sibling; + } + } + return cur; +} + +xml_tag *xml_findnext( xml_tag *root, xml_tag *cur, char *tagname ) +{ + xml_tag *result = cur; + do { + result = xml_next( root, result ); + } while ( result && case_ignore_strcmp( result->tagname, tagname )); + return result; +} + +xml_tag *xml_findfirst( xml_tag *root, char *tagname ) +{ + return xml_findnext( root, root, tagname ); +} + +char *xml_attribute( xml_tag *tag, char *attrname ) +{ + char *result = NULL; + if ( tag->attributes ) { + char **attr = tag->attributes; + while ( attr && *attr ) { + if ( 0 == case_ignore_strcmp( *attr, attrname )) { + result = attr[1]; + break; + } + attr+=2; + } + } + return result; +} + +char *get_filename(const char *fname) +{ + char *res, *cb, *cs; + + cb = strrchr(fname, '\\'); + cs = strrchr(fname, '/'); + + if (cb == NULL) res = cs; + else if (cs == NULL) res = cb; + else res = (cs > cb) ? cs : cb; + + return (res == NULL) ? (char *) fname : ++res; +} diff --git a/util_crc.c b/util_crc.c new file mode 100644 index 000000000..cba43adcb --- /dev/null +++ b/util_crc.c @@ -0,0 +1,96 @@ +/* + Compute CRC32's. + + Copyright (C) 2002, 2003, 2004 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +static unsigned long crc32_table[256] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, + 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, + 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, + 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, + 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, + 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, + 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, + 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, + 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, + 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, + 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, + 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, + 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, + 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, + 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, + 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, + 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, + 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, + 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, + 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, + 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, + 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + +unsigned long +get_crc32(const void * data, int datalen) +{ + unsigned long crc = 0xFFFFFFFF; + const unsigned char * cp = (unsigned char *)data; + + while (cp < ((unsigned char *)data + datalen)) { + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; + cp++; + } + + return (crc ^ 0xFFFFFFFF); +} + +/* + * As above, but on null-terminated string. + */ +unsigned long +get_crc32_s(const void *data) +{ + unsigned long crc = 0xFFFFFFFF; + const unsigned char* cp = (unsigned char *)data; + + for (;*cp;cp++) { + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; + } + return (crc ^ 0xFFFFFFFF); +} diff --git a/uuid.c b/uuid.c new file mode 100755 index 000000000..cba1d65ff --- /dev/null +++ b/uuid.c @@ -0,0 +1,37 @@ +/* + Copyright (C) 2004 Justin Broughton, justinbr@earthlink.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "uuid.h" +#include + +void +gb_uuid_generate(uuid_t uu) +{ + unsigned char *cp; + int i; + for (cp = uu, i = 0; i < 16; i++) { + if (getenv("GPSBABEL_FREEZE_TIME")) { + static unsigned char blech = 0; + *cp++ = blech++; + } else { + *cp++ ^= (rand() >> 7) & 0xFF; + } + } +} + diff --git a/uuid.h b/uuid.h new file mode 100755 index 000000000..161b89e91 --- /dev/null +++ b/uuid.h @@ -0,0 +1,22 @@ +/* + Copyright (C) 2004 Justin Broughton, justinbr@earthlink.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +typedef unsigned char uuid_t[16]; + +void gb_uuid_generate(uuid_t uu); diff --git a/vcf.c b/vcf.c new file mode 100644 index 000000000..0792af963 --- /dev/null +++ b/vcf.c @@ -0,0 +1,143 @@ +/* + Output only format for Vcard format, VCF + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include "defs.h" +#include "jeeps/gpsmath.h" +#include + +static gbfile *file_out; +static short_handle mkshort_handle; + +static char *vcf_encrypt = NULL; + +#define MYNAME "VCF" + +static +arglist_t vcf_args[] = { + { "encrypt", &vcf_encrypt, + "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static void +wr_init(const char *fname) +{ + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); +} + +/* + * Print a possibly empty input string, replacing newlines with escaped + * newlines as we go. + */ +static void +vcf_print_utf(const utf_string *s) +{ + char *p, *p2, *p3; + char *stripped_html; + + if (!s) + return; + + stripped_html = strip_html(s); + p = gstrsub(stripped_html, "\n", "\\n"); + p2 = gstrsub(p, "

    ", "\\n"); + p3 = gstrsub(p2, ";", "\\;"); + gbfputs(p3, file_out); + xfree(p); + xfree(p2); + xfree(p3); + xfree(stripped_html); +} + +static void +vcf_print(const char *s) +{ + char *p; + + if (!s) + return; + + p = gstrsub(s, "\n", "\\n"); + gbfputs(p, file_out); + xfree(p); +} + +static void +vcf_disp(const waypoint *wpt) +{ + int latint, lonint; + + lonint = abs((int) wpt->longitude); + latint = abs((int) wpt->latitude); + + gbfprintf(file_out, "BEGIN:VCARD\nVERSION:3.0\n"); + gbfprintf(file_out, "N:%s;%s;;;\n", wpt->description,wpt->shortname); + gbfprintf(file_out, "ADR:%c%d %06.3f %c%d %06.3f\n", wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint)); + + if (wpt->url) { + gbfprintf(file_out, "URL:%s\n", wpt->url); + } + + gbfprintf(file_out, "NOTE:"); + vcf_print_utf(&wpt->gc_data.desc_short); + gbfprintf(file_out, "\\n"); + vcf_print_utf(&wpt->gc_data.desc_long); + gbfprintf(file_out, "\\n\\nHINT:\\n"); + if (vcf_encrypt) { + char *s = rot13(wpt->gc_data.hint); + vcf_print(s); + xfree(s); + } else { + vcf_print(wpt->gc_data.hint); + } + + gbfprintf(file_out, "\nEND:VCARD\n"); +} + +static void +data_write(void) +{ + setshort_length(mkshort_handle, 6); + waypt_disp_all(vcf_disp); +} + + +ff_vecs_t vcf_vecs = { + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none}, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + vcf_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/vecs.c b/vecs.c new file mode 100644 index 000000000..c091ae435 --- /dev/null +++ b/vecs.c @@ -0,0 +1,1343 @@ +/* + Describe vectors containing file operations. + + Copyright (C) 2002, 2004, 2005, 2006, 2007 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include "defs.h" +#include "csv_util.h" +#include "inifile.h" +#include "gbversion.h" + +#define MYNAME "vecs.c" + +typedef struct { + ff_vecs_t *vec; + const char *name; + const char *desc; + const char *extension; + const char *parent; +} vecs_t; + +extern ff_vecs_t an1_vecs; +extern ff_vecs_t axim_gpb_vecs; +extern ff_vecs_t bcr_vecs; +extern ff_vecs_t brauniger_iq_vecs; +extern ff_vecs_t cetus_vecs; +extern ff_vecs_t coastexp_vecs; +extern ff_vecs_t compegps_vecs; +extern ff_vecs_t copilot_vecs; +extern ff_vecs_t coto_vecs; +extern ff_vecs_t cst_vecs; +extern ff_vecs_t dg100_vecs; +extern ff_vecs_t easygps_vecs; +extern ff_vecs_t garmin_vecs; +extern ff_vecs_t garmin_txt_vecs; +extern ff_vecs_t gcdb_vecs; +extern ff_vecs_t gdb_vecs; +extern ff_vecs_t geoniche_vecs; +extern ff_vecs_t geo_vecs; +extern ff_vecs_t glogbook_vecs; +extern ff_vecs_t google_vecs; +extern ff_vecs_t gpilots_vecs; +extern ff_vecs_t gpl_vecs; +extern ff_vecs_t gpssim_vecs; +extern ff_vecs_t gpspilot_vecs; +extern ff_vecs_t gpsutil_vecs; +extern ff_vecs_t gpx_vecs; +extern ff_vecs_t gtm_vecs; +extern ff_vecs_t hiketech_vecs; +extern ff_vecs_t holux_vecs; +extern ff_vecs_t HsaEndeavourNavigator_vecs; +extern ff_vecs_t html_vecs; +extern ff_vecs_t igc_vecs; +extern ff_vecs_t ignr_vecs; +extern ff_vecs_t kml_vecs; +extern ff_vecs_t lowranceusr_vecs; +extern ff_vecs_t mag_fvecs; +extern ff_vecs_t maggeo_vecs; +extern ff_vecs_t magnav_vec; +extern ff_vecs_t magpdb_vecs; +extern ff_vecs_t mag_svecs; +extern ff_vecs_t magX_fvecs; +extern ff_vecs_t mapsend_vecs; +extern ff_vecs_t mps_vecs; +extern ff_vecs_t msroute_vecs; +extern ff_vecs_t mtk_vecs; +extern ff_vecs_t mtk_fvecs; +extern ff_vecs_t navicache_vecs; +extern ff_vecs_t netstumbler_vecs; +extern ff_vecs_t nmea_vecs; +extern ff_vecs_t nmn4_vecs; +extern ff_vecs_t overlay_vecs; +extern ff_vecs_t ozi_vecs; +extern ff_vecs_t palmdoc_vecs; +extern ff_vecs_t pcx_vecs; +extern ff_vecs_t ppdb_vecs; +extern ff_vecs_t psit_vecs; /* MRCB */ +extern ff_vecs_t psp_vecs; +extern ff_vecs_t quovadis_vecs; +extern ff_vecs_t saroute_vecs; +extern ff_vecs_t shape_vecs; +#if CSVFMTS_ENABLED +extern ff_vecs_t stmsdf_vecs; +#endif +#if CSVFMTS_ENABLED +extern ff_vecs_t stmwpp_vecs; +#endif +extern ff_vecs_t tef_xml_vecs; +extern ff_vecs_t text_vecs; +extern ff_vecs_t tiger_vecs; +extern ff_vecs_t tmpro_vecs; +extern ff_vecs_t tomtom_vecs; +extern ff_vecs_t tpg_vecs; +extern ff_vecs_t tpo2_vecs; +extern ff_vecs_t tpo3_vecs; +extern ff_vecs_t unicsv_vecs; +extern ff_vecs_t vcf_vecs; +extern ff_vecs_t vitosmt_vecs; +extern ff_vecs_t wfff_xml_vecs; +extern ff_vecs_t xcsv_vecs; +extern ff_vecs_t yahoo_vecs; +extern ff_vecs_t wbt_svecs; +extern ff_vecs_t wbt_fvecs; +extern ff_vecs_t gtc_vecs; +extern ff_vecs_t dmtlog_vecs; +extern ff_vecs_t raymarine_vecs; +extern ff_vecs_t alanwpr_vecs; +extern ff_vecs_t alantrl_vecs; +extern ff_vecs_t vitovtt_vecs; +extern ff_vecs_t ggv_log_vecs; +extern ff_vecs_t g7towin_vecs; +extern ff_vecs_t garmin_gpi_vecs; +extern ff_vecs_t lmx_vecs; +extern ff_vecs_t random_vecs; +extern ff_vecs_t xol_vecs; +extern ff_vecs_t navilink_vecs; +extern ff_vecs_t ik3d_vecs; +extern ff_vecs_t osm_vecs; +extern ff_vecs_t destinator_poi_vecs; +extern ff_vecs_t destinator_trl_vecs; +extern ff_vecs_t destinator_itn_vecs; +extern ff_vecs_t exif_vecs; +extern ff_vecs_t vidaone_vecs; + +static +vecs_t vec_list[] = { +#if CSVFMTS_ENABLED + /* XCSV must be the first entry in this table. */ + { + &xcsv_vecs, + "xcsv", + "? Character Separated Values", + NULL + }, +#endif + { + &geo_vecs, + "geo", + "Geocaching.com .loc", + "loc" + }, + { + &gpx_vecs, + "gpx", + "GPX XML", + "gpx" + }, + { + &mag_svecs, + "magellan", + "Magellan serial protocol", + NULL + }, + { + &mag_fvecs, + "magellan", + "Magellan SD files (as for Meridian)", + NULL + }, + { + &magX_fvecs, + "magellanx", + "Magellan SD files (as for eXplorist)", + "upt" + }, + { + &garmin_vecs, + "garmin", + "Garmin serial/USB protocol", + NULL + }, + { + &mapsend_vecs, + "mapsend", + "Magellan Mapsend", + NULL + }, + { + &mps_vecs, + "mapsource", + "Garmin MapSource - mps", + "mps" + }, + { + &nmea_vecs, + "nmea", + "NMEA 0183 sentences", + NULL + }, + { + &kml_vecs, + "kml", + "Google Earth (Keyhole) Markup Language", + "kml" + }, +#if MAXIMAL_ENABLED + { + &pcx_vecs, + "pcx", + "Garmin PCX5", + "pcx" + }, + { + &gpsutil_vecs, + "gpsutil", + "gpsutil", + NULL + }, + { + &psp_vecs, + "psp", + "MS PocketStreets 2002 Pushpin", + "psp" + }, + { + &lowranceusr_vecs, + "lowranceusr", + "Lowrance USR", + "usr" + }, +#if PDBFMTS_ENABLED + { + &cetus_vecs, + "cetus", + "Cetus for Palm/OS", + "pdb" + }, + { + &copilot_vecs, + "copilot", + "CoPilot Flight Planner for Palm/OS", + "pdb" + }, + { + &gpspilot_vecs, + "gpspilot", + "GPSPilot Tracker for Palm/OS", + "pdb" + }, + { + &magnav_vec, + "magnav", + "Magellan NAV Companion for Palm/OS", + "pdb" + }, +#endif /* PDBFMTS_ENABLED */ + { + &holux_vecs, + "holux", + "Holux (gm-100) .wpo Format", + "wpo" + }, + { + &tpg_vecs, + "tpg", + "National Geographic Topo .tpg (waypoints)", + "tpg" + }, + { + &tpo2_vecs, + "tpo2", + "National Geographic Topo 2.x .tpo", + "tpo" + }, + { + &tpo3_vecs, + "tpo3", + "National Geographic Topo 3.x/4.x .tpo", + "tpo" + }, + { + &tmpro_vecs, + "tmpro", + "TopoMapPro Places File", + "tmpro" + }, +#if PDBFMTS_ENABLED + { + &gcdb_vecs, + "gcdb", + "GeocachingDB for Palm/OS", + "pdb" + }, +#endif + { + &tiger_vecs, + "tiger", + "U.S. Census Bureau Tiger Mapping Service", + NULL + }, + { + &easygps_vecs, + "easygps", + "EasyGPS binary format", + ".loc" + }, +#if PDBFMTS_ENABLED + { + &quovadis_vecs, + "quovadis", + "Quovadis", + "pdb" + }, + { + &gpilots_vecs, + "gpilots", + "GpilotS", + "pdb" + }, +#endif + { + &saroute_vecs, + "saroute", + "DeLorme Street Atlas Route", + "anr" + }, + { + &navicache_vecs, + "navicache", + "Navicache.com XML", + NULL + }, + { + &coastexp_vecs, + "coastexp", + "CoastalExplorer XML", + NULL + }, + { /* MRCB */ + &psit_vecs, + "psitrex", + "KuDaTa PsiTrex text", + NULL + }, +#if SHAPELIB_ENABLED + { + &shape_vecs, + "shape", + "ESRI shapefile", + "shp" + }, +#endif +#if PDBFMTS_ENABLED + { + &geoniche_vecs, + "geoniche", + "GeoNiche .pdb", + "pdb" + }, +#endif + { + &gpl_vecs, + "gpl", + "DeLorme GPL", + "gpl" + }, + { + &ozi_vecs, + "ozi", + "OziExplorer", + NULL + }, + { + &text_vecs, + "text", + "Textual Output", + "txt" + }, + { + &html_vecs, + "html", + "HTML Output", + "html" + }, +#if PDBFMTS_ENABLED + { + &palmdoc_vecs, + "palmdoc", + "PalmDoc Output", + "pdb" + }, +#endif + { + &netstumbler_vecs, + "netstumbler", + "NetStumbler Summary File (text)", + NULL + }, + { + &HsaEndeavourNavigator_vecs, + "hsandv", + "HSA Endeavour Navigator export File", + NULL + }, + { + &igc_vecs, + "igc", + "FAI/IGC Flight Recorder Data Format", + NULL + }, + { + &brauniger_iq_vecs, + "baroiq", + "Brauniger IQ Series Barograph Download", + NULL + }, + { + &mtk_vecs, + "mtk", + "MTK Logger (iBlue 747,Qstarz BT-1000,...) download", + NULL + }, + { + &mtk_fvecs, + "mtk-bin", + "MTK Logger (iBlue 747,...) Binary File Format", + "bin" + }, + { + &wbt_svecs, + "wbt", + "Wintec WBT-100/200 GPS Download", + NULL + }, + { + &wbt_fvecs, + "wbt-bin", + "Wintec WBT-100/200 Binary File Format", + "bin" + }, + { + &wbt_fvecs, + "wbt-tk1", + "Wintec WBT-201/G-Rays 2 Binary File Format", + "tk1" + }, + { + &hiketech_vecs, + "hiketech", + "HikeTech", + "gps" + }, + { + &glogbook_vecs, + "glogbook", + "Garmin Logbook XML", + "xml" + }, + { + &vcf_vecs, + "vcard", + "Vcard Output (for iPod)", + "vcf", + }, +#if 0 + { + &overlay_vecs, + "overlay", + "GeoGrid-Viewer", + "ovl" + }, +#endif + { + &google_vecs, + "google", + "Google Maps XML", + "xml" + }, + { + &maggeo_vecs, + "maggeo", + "Magellan Explorist Geocaching", + "gs" + }, + { + &an1_vecs, + "an1", + "DeLorme .an1 (drawing) file", + "an1" + }, + { + &tomtom_vecs, + "tomtom", + "TomTom POI file (.ov2)", + "ov2" + }, + { + &tef_xml_vecs, + "tef", + "Map&Guide 'TourExchangeFormat' XML", + "xml" + }, +#if PDBFMTS_ENABLED + { + &ppdb_vecs, + "pathaway", + "PathAway Database for Palm/OS", + "pdb" + }, +#endif + { + &vitosmt_vecs, + "vitosmt", + "Vito Navigator II tracks", + "smt" + }, + { + &wfff_xml_vecs, + "wfff", + "WiFiFoFum 2.0 for PocketPC XML", + "xml" + }, + { + &gdb_vecs, + "gdb", + "Garmin MapSource - gdb", + "gdb" + }, + { + &bcr_vecs, + "bcr", + "Motorrad Routenplaner (Map&Guide) .bcr files", + "bcr" + }, +#if PDBFMTS_ENABLED + { + &coto_vecs, + "coto", + "cotoGPS for Palm/OS", + "pdb" + }, +#endif + { + &ignr_vecs, + "ignrando", + "IGN Rando track files", + "rdn" + }, +#if CSVFMTS_ENABLED + { + &stmsdf_vecs, + "stmsdf", + "Suunto Trek Manager (STM) .sdf files", + "sdf" + }, +#endif +#if CSVFMTS_ENABLED + { + &stmwpp_vecs, + "stmwpp", + "Suunto Trek Manager (STM) WaypointPlus files", + "txt" + }, +#endif // CSVFMTS_ENABLED + { + &msroute_vecs, + "msroute", + "Microsoft AutoRoute 2002 (pin/route reader)", + "axe" + }, + { + &msroute_vecs, + "msroute", + "Microsoft Streets and Trips (pin/route reader)" , + "est" + }, + { + &cst_vecs, + "cst", + "CarteSurTable data file", + "cst" + }, + { + &nmn4_vecs, + "nmn4", + "Navigon Mobile Navigator .rte files", + "rte" + }, +#if PDBFMTS_ENABLED + { + &magpdb_vecs, + "mag_pdb", + "Map&Guide to Palm/OS exported files (.pdb)", + "pdb" + }, +#endif +#if CSVFMTS_ENABLED + { + &compegps_vecs, + "compegps", + "CompeGPS data files (.wpt/.trk/.rte)", + NULL + }, +#endif //CSVFMTS_ENABLED + { + &yahoo_vecs, + "yahoo", + "Yahoo Geocode API data", + NULL + }, + { + &unicsv_vecs, + "unicsv", + "Universal csv with field structure in first line", + NULL + }, + { + >m_vecs, + "gtm", + "GPS TrackMaker", + "gtm" + }, + { + &gpssim_vecs, + "gpssim", + "Franson GPSGate Simulation", + "gpssim" + }, +#if CSVFMTS_ENABLED + { + &garmin_txt_vecs, + "garmin_txt", + "Garmin MapSource - txt (tab delimited)", + "txt" + }, +#endif // CSVFMTS_ENABLED + { + &axim_gpb_vecs, + "axim_gpb", + "Dell Axim Navigation System (.gpb) file format", + "gpb" + }, + { + >c_vecs, + "gtrnctr", + "Garmin Training Center" + "xml" + }, + { + &dmtlog_vecs, + "dmtlog", + "TrackLogs digital mapping (.trl)", + "trl" + }, + { + &raymarine_vecs, + "raymarine", + "Raymarine Waypoint File (.rwf)", + "rwf" + }, + { + &alanwpr_vecs, + "alanwpr", + "Alan Map500 waypoints and routes (.wpr)", + "wpr" + }, + { + &alantrl_vecs, + "alantrl", + "Alan Map500 tracklogs (.trl)", + "trl" + }, + { + &vitovtt_vecs, + "vitovtt", + "Vito SmartMap tracks (.vtt)", + "vtt" + }, + { + &ggv_log_vecs, + "ggv_log", + "Geogrid Viewer tracklogs (.log)", + "log" + }, +#if CSVFMTS_ENABLED + { + &g7towin_vecs, + "g7towin", + "G7ToWin data files (.g7t)", + "g7t" + }, +#endif + { + &garmin_gpi_vecs, + "garmin_gpi", + "Garmin Points of Interest (.gpi)", + "gpi" + }, + { + &lmx_vecs, + "lmx", + "Nokia Landmark Exchange", + NULL + }, + { + &random_vecs, + "random", + "Internal GPS data generator", + NULL + }, + { + &xol_vecs, + "xol", + "Swiss Map # (.xol) format", + "xol" + }, + { + &dg100_vecs, + "dg-100", + "GlobalSat DG-100/BT-335 Download", + NULL + }, + { + &navilink_vecs, + "navilink", + "NaviGPS GT-11/BGT-11 Download", + NULL + }, + { + &ik3d_vecs, + "ik3d", + "MagicMaps IK3D project file (.ikt)", + "ikt" + }, + { + &osm_vecs, + "osm", + "OpenStreetMap data files", + "xml" + }, + { + &destinator_poi_vecs, + "destinator_poi", + "Destinator Points of Interest (.dat)", + "dat" + }, + { + &destinator_itn_vecs, + "destinator_itn", + "Destinator Itineraries (.dat)", + "dat" + }, + { + &destinator_trl_vecs, + "destinator_trl", + "Destinator TrackLogs (.dat)", + "dat" + }, + { + &exif_vecs, + "exif", + "Embedded Exif-GPS data (.jpg)", + "jpg" + }, + { + &vidaone_vecs, + "vidaone", + "VidaOne GPS for Pocket PC (.gpb)", + "gpb" + }, +#endif // MAXIMAL_ENABLED + { + NULL, + NULL, + NULL, + NULL + } +}; + +void +exit_vecs( void ) +{ + vecs_t *vec = vec_list; + while ( vec->vec ) { + arglist_t *ap; + if ( vec->vec->exit ) { + (*vec->vec->exit)(); + } + if ( vec->vec->args ) { + for ( ap = vec->vec->args; ap->argstring; ap++ ) { + if ( ap->defaultvalue && + ( ap->argtype == ARGTYPE_INT ) && + ! isdigit(ap->defaultvalue[0])) { + warning("%s: not an integer\n", ap->argstring); + } + if ( ap->argval && *ap->argval ) { + xfree(*ap->argval); + *ap->argval = NULL; + } + } + } + vec++; + } +} + +void +assign_option(const char *module, arglist_t *ap, const char *val) +{ + char *c; + + if (*ap->argval != NULL) { + xfree(*ap->argval); + *ap->argval = NULL; + } + if (val == NULL) return; + + if (case_ignore_strcmp(val, ap->argstring) == 0) c = ""; + else c = (char *)val; + + switch(ap->argtype & ARGTYPE_TYPEMASK) { + case ARGTYPE_INT: + if (*c == '\0') c = "0"; + else { + int test; + is_fatal(1 != sscanf(c, "%d", &test), + "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); + } + break; + case ARGTYPE_FLOAT: + if (*c == '\0') c = "0"; + else { + double test; + is_fatal(1 != sscanf(c, "%lf", &test), + "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); + } + break; + case ARGTYPE_BOOL: + if (*c == '\0') c = "1"; + else { + switch(*c) { + case 'Y': + case 'y': c = "1"; break; + case 'N': + case 'n': c = "0"; break; + default: + if (isdigit(*c)) { + if (*c == '0') c = "0"; + else c = "1"; + } + else { + warning(MYNAME ": Invalid logical value '%s' (%s)!\n", c, module); + c = "0"; + } + break; + } + } + break; + } + + /* for bool options without default: don't set argval if "FALSE" */ + + if (((ap->argtype & ARGTYPE_TYPEMASK) == ARGTYPE_BOOL) && + (*c == '0') && (ap->defaultvalue == NULL)) { + return; + } + *ap->argval = xstrdup(c); +} + +void +disp_vec_options(const char *vecname, arglist_t *ap) +{ + for (ap = ap; ap && ap->argstring; ap++) { + if (*ap->argval && ap->argval) { + printf("options: module/option=value: %s/%s=\"%s\"", + vecname, ap->argstring, *ap->argval); + if (ap->defaultvalue && (case_ignore_strcmp(ap->defaultvalue, *ap->argval) == 0)) + printf(" (=default)"); + printf("\n"); + } + } +} + +ff_vecs_t * +find_vec(char *const vecname, char **opts) +{ + vecs_t *vec = vec_list; + style_vecs_t *svec = style_list; + char *v = xstrdup(vecname); + char *svecname = strtok(v, ","); + int found = 0; + + if (vecname == NULL) { + fatal("A format name is required.\n"); + } + + while (vec->vec) { + arglist_t *ap; + char *res; + + if (case_ignore_strcmp(svecname, vec->name)) { + vec++; + continue; + } + + res = strchr(vecname, ','); + if (res) { + *opts = strchr(vecname, ',')+1; + } else { + *opts = NULL; + } + + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + char *opt; + + if ( res ) { + opt = get_option(*opts, ap->argstring); + if ( opt ) { + found = 1; + assign_option(svecname, ap, opt); + xfree(opt); + continue; + } + } + opt = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); + if (opt == NULL) opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); + if (opt == NULL) opt = ap->defaultvalue; + assign_option(vec->name, ap, opt); + } + } + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, vec->name); + } + + if (global_opts.debug_level >= 1) + disp_vec_options(vec->name, vec->vec->args); + +#if CSVFMTS_ENABLED + xcsv_setup_internal_style( NULL ); +#endif // CSVFMTS_ENABLED + xfree(v); + return vec->vec; + + } + + /* + * Didn't find it in the table of "real" file types, so plan B + * is to search the list of xcsv styles. + */ + while (svec->name) { + arglist_t *ap; + char *res; + + if (case_ignore_strcmp(svecname, svec->name)) { + svec++; + continue; + } + + res = strchr(vecname, ','); + if (res) { + *opts = strchr(vecname, ',') + 1; + } else { + *opts = NULL; + } + + if (vec_list[0].vec->args) { + for (ap = vec_list[0].vec->args; ap->argstring; ap++) { + char *opt; + + if ( res ) { + opt = get_option(*opts, ap->argstring); + if ( opt ) { + found = 1; + assign_option(svecname, ap, opt); + xfree(opt); + continue; + } + } + opt = inifile_readstr(global_opts.inifile, svec->name, ap->argstring); + if (opt == NULL) opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); + if (opt == NULL) opt = ap->defaultvalue; + assign_option(svec->name, ap, opt); + } + } + + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, svec->name); + } + + if (global_opts.debug_level >= 1) + disp_vec_options(svec->name, vec_list[0].vec->args); +#if CSVFMTS_ENABLED + xcsv_setup_internal_style(svec->style_buf); +#endif // CSVFMTS_ENABLED + + xfree(v); + + return vec_list[0].vec; + } + + /* + * Not found. + */ + xfree(v); + return NULL; +} + +/* + * Find and return a specific argument in an arg list. + * Modelled approximately after getenv. + */ +char * +#ifdef DEBUG_MEM +GET_OPTION(const char *iarglist, const char *argname, DEBUG_PARAMS) +#else +get_option(const char *iarglist, const char *argname) +#endif +{ + size_t arglen = strlen(argname); + char *arglist; + char *rval = NULL; + char *arg; + char *argp; + + if (!iarglist) { + return NULL; + } + + arglen = strlen(argname); + arglist = xstrdup(iarglist); + + for (arg = arglist; argp = strtok(arg, ","), NULL != argp; arg = NULL) { + if (0 == case_ignore_strncmp(argp, argname, arglen)) { + /* + * If we have something of the form "foo=bar" + * return "bar". Otherwise, we assume we have + * simply "foo" so we return that. + */ + if (argp[arglen] == '=') + rval = argp + arglen + 1; + else + rval = argp; + break; + } + } + /* + * Return an offset into the allocated copy. + * The caller mustn't free or otherwise get froggy with + * this data. + */ + if ( rval ) { + rval = xxstrdup(rval,file, line); + } + xfree(arglist); + return rval; +} + +/* + * Display the available formats in a format that's easy for humans to + * parse for help on available command line options. + */ +static signed int +alpha (const void *a, const void *b) +{ + + const vecs_t *const *ap = a; + const vecs_t *const *bp = b; + + return case_ignore_strcmp((*ap)->desc , (*bp)->desc); +} + +/* + * Smoosh the vecs list and style lists together and sort them + * alphabetically. Returns an allocated copy of a style_vecs_array + * that's populated and sorted. + */ +vecs_t ** +sort_and_unify_vecs(int *ctp) +{ + int vc; + vecs_t **svp; + vecs_t *vec; +#if CSVFMTS_ENABLED + style_vecs_t *svec; +#endif + int i = 0; + + /* Get a count from both the vec (normal) and the svec (csv) lists */ + +#if CSVFMTS_ENABLED + extern size_t nstyles; + vc = sizeof vec_list / sizeof vec_list[0] - 1 + nstyles; +#else + vc = sizeof vec_list / sizeof vec_list[0] - 1; +#endif // CSVFMTS_ENABLED + + + svp = xcalloc(vc, sizeof(style_vecs_t *)); + /* Normal vecs are easy; populate the first part of the array. */ + for (vec = vec_list; vec->vec; vec++, i++) { + svp[i] = vec; + if (svp[i]->parent == NULL) { + svp[i]->parent = svp[i]->name; + } + } + +#if CSVFMTS_ENABLED + /* Walk the style list, parse the entries, dummy up a "normal" vec */ + for (svec = style_list; svec->name; svec++, i++) { + xcsv_read_internal_style(svec->style_buf); + svp[i] = xcalloc(1, sizeof **svp); + svp[i]->name = svec->name; + svp[i]->vec = xmalloc(sizeof(*svp[i]->vec)); + svp[i]->extension = xcsv_file.extension; + *svp[i]->vec = *vec_list[0].vec; /* Interits xcsv opts */ + /* Reset file type to inherit ff_type from xcsv for everything + * except the xcsv format itself, which we leave as "internal" + */ + if (case_ignore_strcmp(svec->name, "xcsv")) { + svp[i]->vec->type = xcsv_file.type; + /* Skip over the first help entry for all but the + * actual 'xcsv' format - so we don't expose the + * 'full path to xcsv style file' argument to any + * GUIs for an internal format. + */ + svp[i]->vec->args++; + } + memset(&svp[i]->vec->cap, 0, sizeof(svp[i]->vec->cap)); + switch(xcsv_file.datatype) { + case 0: + case wptdata: + svp[i]->vec->cap[ff_cap_rw_wpt] = ff_cap_read | ff_cap_write; break; + case trkdata: + svp[i]->vec->cap[ff_cap_rw_trk] = ff_cap_read | ff_cap_write; break; + case rtedata: + svp[i]->vec->cap[ff_cap_rw_rte] = ff_cap_read | ff_cap_write; break; + default: ; + } + svp[i]->desc = xcsv_file.description; + svp[i]->parent = "xcsv"; + } +#endif // CSVFMTS_ENABLED + + /* Now that we have everything in an array, alphabetize them */ + qsort(svp, vc, sizeof(*svp), alpha); + + *ctp = i; + return svp; +} + +#define VEC_FMT " %-20.20s %-.50s\n" + +void +disp_vecs(void) +{ + vecs_t **svp; + arglist_t *ap; + int vc; + int i = 0; + + svp = sort_and_unify_vecs(&vc); + for (i=0;ivec->type == ff_type_internal ) { + continue; + } + printf(VEC_FMT, svp[i]->name, svp[i]->desc); + for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { + if ( !(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %s%-.50s %s\n", + ap->argstring, + (ap->argtype & ARGTYPE_TYPEMASK) == + ARGTYPE_BOOL ? "(0/1) " : "", + ap->helpstring, + (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); + } + } + xfree (svp); + return; +} + +void +disp_vec( const char *vecname ) +{ + vecs_t **svp; + arglist_t *ap; + int vc; + int i = 0; + + svp = sort_and_unify_vecs(&vc); + for (i=0;iname, vecname )) { + continue; + } + printf(VEC_FMT, svp[i]->name, svp[i]->desc); + for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { + if ( !(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %s%-.50s %s\n", + ap->argstring, + (ap->argtype & ARGTYPE_TYPEMASK) == + ARGTYPE_BOOL ? "(0/1) " : "", + ap->helpstring, + (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); + } + } + xfree (svp); + return; +} + +/* + * Additional information for V1. + * Output format type at front of line. + */ +static void +disp_v1(ff_type t) +{ + char *tstring; + + switch (t) { + case ff_type_file: tstring = "file"; break; + case ff_type_serial: tstring = "serial"; break; + case ff_type_internal: tstring = "internal"; break; + default: tstring = "unknown"; break; + } + printf("%s\t", tstring); +} + +static void +disp_v2(ff_vecs_t *v) +{ + int i; + for (i = 0; i < 3; i++) { + putchar(v->cap[i] & ff_cap_read ? 'r' : '-'); + putchar(v->cap[i] & ff_cap_write ? 'w' : '-'); + } + putchar('\t'); +} + +const char * +name_option(long type) +{ + const char *at[] = { + "unknown", + "integer", + "float", + "string", + "boolean", + "file", + "outfile" + }; + + if ((type & ARGTYPE_TYPEMASK) <= 6) { + return at[type & ARGTYPE_TYPEMASK]; + } + return at[0]; +} + +static +void disp_help_url(const vecs_t *vec, arglist_t *arg) +{ + printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); + if (arg) { + printf("#fmt_%s_o_%s",vec->name, arg->argstring); + } + printf("\n"); +} + + +static void +disp_v3(const vecs_t *vec) +{ + arglist_t *ap; + + disp_help_url(vec, NULL); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if ( !(ap->argtype & ARGTYPE_HIDDEN)) { + printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", + vec->name, + ap->argstring, + ap->helpstring, + name_option(ap->argtype), + ap->defaultvalue? ap->defaultvalue : "", + ap->minvalue? ap->minvalue : "", + ap->maxvalue? ap->maxvalue : ""); + } + disp_help_url(vec, ap); + printf("\n"); + } +} + +/* + * Display the available formats in a format that's easy to machine + * parse. Typically invoked by programs like graphical wrappers to + * determine what formats are supported. + */ +void +disp_formats(int version) +{ + vecs_t **svp; + vecs_t *vec; + int i, vc = 0; + + switch(version) { + case 0: + case 1: + case 2: + case 3: + svp = sort_and_unify_vecs(&vc); + for (i=0;i 0) { + disp_v1(vec->vec->type); + } else { + if (vec->vec->type == ff_type_internal) + continue; + } + if (version >= 2) { + disp_v2(vec->vec); + } + printf("%s\t%s\t%s%s%s\n", vec->name, + vec->extension? vec->extension : "", + vec->desc, + version >= 3 ? "\t" : "", + version >= 3 ? vec->parent : ""); + if (version >= 3) { + disp_v3(vec); + } + } + xfree (svp); + break; + default: + ; + } +} diff --git a/vidaone.c b/vidaone.c new file mode 100644 index 000000000..91cfcafc7 --- /dev/null +++ b/vidaone.c @@ -0,0 +1,134 @@ +/* + + Support for VidaOne GPS for Pocket PC (.gpb) files + + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + /* + Simple layout: + + struct + { + double dLatitude + double dLongitude + float fReserved + }; + */ + +#include "defs.h" +#include +#include + +#define MYNAME "vidaone" + +static +arglist_t vidaone_args[] = { + ARG_TERMINATOR +}; + +static gbfile *fin, *fout; + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +vidaone_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); +} + +static void +vidaone_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +vidaone_read(void) +{ + route_head *trk = NULL; + + while (! gbfeof(fin)) { + waypoint *wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + (void) gbfgetflt(fin); + + /* Only one basic check of data integrity */ + if ((fabs(wpt->latitude) > 90) || (fabs(wpt->longitude) > 180)) + fatal(MYNAME ": Latitude and/or longitude out of range.\n"); + + if (!trk) { + trk = route_head_alloc(); + track_add_head(trk); + } + + track_add_wpt(trk, wpt); + } +} + +static void +vidaone_wr_init(const char *fname) +{ + fout = gbfopen(fname, "wb", MYNAME); +} + +static void +vidaone_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +vidaone_trkpt(const waypoint *wpt) +{ + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputflt(0, fout); +} + +static void +vidaone_write(void) +{ + track_disp_all(NULL, NULL, vidaone_trkpt); +} + +/**************************************************************************/ + +ff_vecs_t vidaone_vecs = { + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + vidaone_rd_init, + vidaone_wr_init, + vidaone_rd_deinit, + vidaone_wr_deinit, + vidaone_read, + vidaone_write, + NULL, + vidaone_args, + CET_CHARSET_UTF8, 1 +}; + +/**************************************************************************/ diff --git a/vitosmt.c b/vitosmt.c new file mode 100644 index 000000000..1297eb7b4 --- /dev/null +++ b/vitosmt.c @@ -0,0 +1,383 @@ +/* + Read Vito Navigator .SMT tracks + + Copyright (C) 2005 Etienne TASSE + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include +#include + +#define MYNAME "vitosmt" +#include "defs.h" +#include "grtcirc.h" + +static gbfile *infile =NULL; +static gbfile *ofs =NULL; +static long count =0; + +const long vitosmt_version =2; +const long vitosmt_subversion =1000; +const size_t vitosmt_headersize =24; +const size_t vitosmt_datasize =64; + +static unsigned char * +ReadRecord(gbfile *f, gbsize_t size) +{ + unsigned char *result = (unsigned char *) xmalloc(size); + + gbfread(result, size, 1, f); + return result; +} + +static void +WriteDouble(void* ptr, double d) +{ + unsigned char result[8]="\0\0\0\0\0\0\0\0"; + le_write_double(result,d); + memcpy(ptr, result, 8); +} + + +static void +rd_init(const char *fname) +{ + infile = gbfopen_le(fname, "rb", MYNAME); +} + +static void +rd_deinit(void) +{ + gbfclose(infile); +} + +static void +vitosmt_read(void) +{ + long version =0; + long subversion =0; + long check1 =-1; + long check2 =-2; + long check3 =-3; + route_head *route_head =0; + waypoint *wpt_tmp =0; + double latrad =0; + double lonrad =0; + double elev =0; + unsigned char* timestamp =0; + struct tm tmStruct; + double seconds =0.0; + double speed =0.0; + double course =0.0; + double pdop =0.0; + unsigned char gpsfix =0; + unsigned char gpsvalid =0; + unsigned char gpssats =0; + int serial =0; + + + memset(&tmStruct, 0, sizeof(tmStruct)); + /* + * 24 bytes header + */ + version = gbfgetint32(infile); /* 2 */ + subversion = gbfgetint32(infile); /* 1000 */ + count = gbfgetint32(infile); /* n */ + check1 = gbfgetint32(infile); /* 0 */ + check2 = gbfgetint32(infile); /* not sure */ + check3 = gbfgetint32(infile); /* n */ + + if (version!=vitosmt_version) { + + fatal("%s (%d) reading file. Unsupported version %ld.%ld\n", + MYNAME, __LINE__, version, subversion ); + } + + if (subversion!=vitosmt_subversion) { + warning("%s (%d) reading file. Unsafe version %ld.%ld\n", + MYNAME, __LINE__, version, subversion ); + } + + if ((count!=check3) || + (check1!=count-1) || + (check3!=count) ) { + + fatal("%s (%d) reading file. Invalid file header\n", + MYNAME, __LINE__ ); + + } + + while (count) { + /* + * 64 bytes of data + */ + if (gbfeof(infile)||gbferror(infile)) + { + warning("%s (%d) reading file. Unexpected end of file %s\n", + MYNAME, __LINE__, strerror(errno) ); + break; + } +#if 0 + fprintf(stderr, "Looptop %d\n", gbftell(infile)); +#endif + latrad =gbfgetdbl(infile); /* WGS84 latitude in radians */ + lonrad =gbfgetdbl(infile); /* WGS84 longitude in radians */ + elev =gbfgetdbl(infile); /* elevation in meters */ +#if 0 + fprintf(stderr, "before %d\n", gbftell(infile)); +#endif + timestamp =ReadRecord(infile,5); /* UTC time yr/mo/dy/hr/mi */ +#if 0 + fprintf(stderr, "%d latrad %f/%f ele %f\n", gbftell(infile),latrad, DEG(latrad), elev); +#endif + seconds =gbfgetdbl(infile); /* seconds */ + speed =gbfgetdbl(infile); /* speed in knots */ + course =gbfgetdbl(infile); /* course in degrees */ + pdop =gbfgetdbl(infile); /* dilution of precision */ + gpsfix =gbfgetc(infile); /* fix type x08,x10, x20 */ + gpsvalid =gbfgetc(infile); /* fix is valid */ + gpssats =gbfgetc(infile); /* number of sats */ + + wpt_tmp = waypt_new(); + + wpt_tmp->latitude =DEG(latrad); + wpt_tmp->longitude =DEG(lonrad); + wpt_tmp->altitude =elev; + + tmStruct.tm_year =timestamp[0]+100; + tmStruct.tm_mon =timestamp[1]-1; + tmStruct.tm_mday =timestamp[2]; + tmStruct.tm_hour =timestamp[3]; + tmStruct.tm_min =timestamp[4]; + tmStruct.tm_sec =(int)floor(seconds); + tmStruct.tm_isdst =-1; + + wpt_tmp->creation_time = mkgmtime(&tmStruct); + wpt_tmp->microseconds = fmod(1000000*seconds+0.5,1000000); + wpt_tmp->shortname =xcalloc(16,1); + snprintf(wpt_tmp->shortname, 15 , "WP%04d", ++serial); + + WAYPT_SET(wpt_tmp, speed, KNOTS_TO_MPS(speed)); /* meters per second */ + WAYPT_SET(wpt_tmp, course, course); + wpt_tmp->pdop = pdop; + + /* + GPS Fix data + */ + if (gpsvalid&0x7) { + if (gpsfix==0) + wpt_tmp->fix =fix_none; + if (gpsfix&0x8) + wpt_tmp->fix =fix_2d; + else if (gpsfix&0x10) + wpt_tmp->fix =fix_3d; + else if (gpsfix&0x20) + wpt_tmp->fix =fix_dgps; + else + wpt_tmp->fix =fix_unknown; + + /* */ + wpt_tmp->sat = gpssats; + } + else + wpt_tmp->fix =fix_unknown; + + if (doing_wpts) /* process as waypoints */ + { + waypt_add(wpt_tmp); + } + else if (doing_rtes) /* process as route */ + { + if (route_head == NULL) { + route_head = route_head_alloc(); + route_add_head(route_head); + } + route_add_wpt(route_head, wpt_tmp); + } + else /* default track mode */ + { + if (route_head == NULL) { + route_head = route_head_alloc(); + track_add_head(route_head); + } + track_add_wpt(route_head, wpt_tmp); + } + + xfree(timestamp); + + count--; + } +} + +static void +wr_init(const char *fname) +{ + warning(MYNAME " write: format is experimental and may crash Vito Navigator II.\n"); + ofs = gbfopen_le(fname, "wb", MYNAME); +} + +static void +wr_deinit(void) +{ + gbfclose(ofs); + +} + +static void +vitosmt_waypt_pr(const waypoint *waypointp) +{ + unsigned char * workbuffer =0; + size_t position =0; + struct tm* tmstructp =0; + double seconds =0; + + ++count; + workbuffer = xcalloc(vitosmt_datasize,1); + + WriteDouble(&workbuffer[position], RAD(waypointp->latitude) ); + position += sizeof(double); + WriteDouble(&workbuffer[position], RAD(waypointp->longitude) ); + position += sizeof(double); + if ( waypointp->altitude-1 > unknown_alt) + WriteDouble(&workbuffer[position], waypointp->altitude ); + position += sizeof(double); + + tmstructp = gmtime(&waypointp->creation_time); + seconds = (double) tmstructp->tm_sec + 0.0000001*waypointp->microseconds; + + workbuffer[position++] =tmstructp->tm_year-100; + workbuffer[position++] =tmstructp->tm_mon+1; + workbuffer[position++] =tmstructp->tm_mday; + workbuffer[position++] =tmstructp->tm_hour; + workbuffer[position++] =tmstructp->tm_min; + + WriteDouble(&workbuffer[position], seconds ); + position += sizeof(double); + + /* speed */ + if (waypointp->speed>0) + WriteDouble(&workbuffer[position], MPS_TO_MPH(waypointp->speed)); + position += sizeof(double); + + /* course */ + if ((waypointp->course>=-360.0)&&(waypointp->course<=360.0)) + WriteDouble(&workbuffer[position], waypointp->course ); + position += sizeof(double); + + /* pdop */ + if (waypointp->pdop>0) + WriteDouble(&workbuffer[position], waypointp->pdop ); + position += sizeof(double); + + + /* fix type */ + switch (waypointp->fix) + { + case fix_2d: + workbuffer[position++] = 0x08; + break; + case fix_3d: + workbuffer[position++] = 0x10; + break; + case fix_dgps: + workbuffer[position++] = 0x20; + break; + default: + workbuffer[position++] = 0; + break; + } + + /* Assume position is valid */ + workbuffer[position++] = 0x07; + + if ((waypointp->sat>0)&&(waypointp->sat<128)) + workbuffer[position++] = waypointp->sat; + else + workbuffer[position++] = 0; + + (void)gbfwrite(workbuffer,vitosmt_datasize,1,ofs); + + xfree(workbuffer); +} + + +static void +vitosmt_write(void) +{ + time_t now = 0; + unsigned char * workbuffer =0; + size_t position =0; + + workbuffer = xcalloc(vitosmt_headersize,1); + + now = current_time(); + count = 0; + position = 0; + + /* leave a spacer for the header */ + memset(workbuffer,0,vitosmt_headersize); + (void)gbfwrite(workbuffer,vitosmt_headersize,1,ofs); + + if (doing_wpts) /* process as waypoints */ + { + waypt_disp_all(vitosmt_waypt_pr); + } + else if (doing_rtes) /* process as route */ + { + route_disp_all(NULL, NULL, vitosmt_waypt_pr); + } + else /* default track mode */ + { + track_disp_all(NULL, NULL, vitosmt_waypt_pr); + } + + + /* write the complete the header */ + le_write32(&workbuffer[position],vitosmt_version); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],vitosmt_subversion); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],count); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],0); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],count-1); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],count); + position += sizeof(gbuint32); + + gbfrewind(ofs); + (void)gbfwrite(workbuffer,vitosmt_headersize,1,ofs); + + xfree(workbuffer); +} + +ff_vecs_t vitosmt_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + vitosmt_read, + vitosmt_write, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ +}; diff --git a/vitovtt.c b/vitovtt.c new file mode 100644 index 000000000..99f6538e5 --- /dev/null +++ b/vitovtt.c @@ -0,0 +1,139 @@ +/* + Read Vito SmartMap .vtt tracks + + Copyright (C) 2007 Jeremy Ehrhardt, jeremye@caltech.edu + + based on vitostc.c, which is + Copyright (C) 2005 Etienne TASSE + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include +#include + +#define MYNAME "vitovtt" +#include "defs.h" + +#define TM_YEAR_ZERO 1900 +#define TM_MONTH_ZERO 1 + +static gbfile *infile = 0; +static int count = 0; + +static const int vitovtt_version = 3; +static const size_t vitovtt_headersize = 16; +static const size_t vitovtt_datasize = 32; + +static const double vitovtt_latitudescale = 20000000.0; +static const double vitovtt_longitudescale = 10000000.0; +static const int vitovtt_secondscale = 30000000; +static const int vitovtt_microsecondscale = 30; + +static void +rd_init(const char *fname) +{ + infile = gbfopen_le(fname, "rb", MYNAME); +} + +static void +rd_deinit(void) +{ + gbfclose(infile); +} + +static void +vitovtt_read(void) +{ + int version = 0; + route_head *route_head = 0; + waypoint *wpt_tmp = 0; + int scaled_lat = 0; + int scaled_lon = 0; + double altitude = 0; + struct tm tmStruct; + int scaled_sec = 0; + int microseconds = 0; + double speed = 0; + int course = 0; + int status = 0; + + memset(&tmStruct, 0, sizeof(tmStruct)); + + route_head = route_head_alloc(); + track_add_head(route_head); + + /* Read the header. */ + version = gbfgetint32(infile); + count = gbfgetint32(infile); + + if (version!=vitovtt_version) { + + fatal("%s (%d) reading file. Unsupported version %d\n", + MYNAME, __LINE__, version ); + } + + while (count) { + /* Read an entry. */ + scaled_lat = gbfgetint32(infile); + scaled_lon = gbfgetint32(infile); + altitude = gbfgetflt(infile); + tmStruct.tm_year = gbfgetint16(infile) - TM_YEAR_ZERO; + tmStruct.tm_mon = gbfgetc(infile) - TM_MONTH_ZERO; + tmStruct.tm_mday = gbfgetc(infile); + tmStruct.tm_hour = gbfgetc(infile); + tmStruct.tm_min = gbfgetc(infile); + scaled_sec = gbfgetint32(infile); + speed = gbfgetflt(infile); + course = gbfgetint16(infile); + status = gbfgetint32(infile); + + wpt_tmp = waypt_new(); + + wpt_tmp->latitude = scaled_lat / vitovtt_latitudescale; + wpt_tmp->longitude = scaled_lon / vitovtt_longitudescale; + wpt_tmp->altitude = altitude; + + tmStruct.tm_sec = scaled_sec / vitovtt_secondscale; + microseconds = (scaled_sec % vitovtt_secondscale) / vitovtt_microsecondscale; + wpt_tmp->creation_time = mkgmtime(&tmStruct); + wpt_tmp->microseconds = microseconds; + + /* + * TODO: interpret speed, course, status + */ + + track_add_wpt(route_head, wpt_tmp); + + count--; + } +} + +ff_vecs_t vitovtt_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none }, + rd_init, + NULL, + rd_deinit, + NULL, + vitovtt_read, + NULL, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ +}; diff --git a/vmem.c b/vmem.c new file mode 100644 index 000000000..f1834f1c2 --- /dev/null +++ b/vmem.c @@ -0,0 +1,67 @@ +/* + vmem utilities. Manipulate allocated object optimized for + long-term persistence over raw speed. + + Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include + +vmem_t +vmem_alloc(size_t size, int flags) +{ + vmem_t vm; + /* + * By default, zero the allocated thingy. + */ + if (flags & VMFL_NOZERO) + vm.mem = xmalloc(size); + else + vm.mem = xcalloc(size, 1); + vm.size = size; + return vm; +} + +void +vmem_free(vmem_t *vm) +{ + if (vm->mem) xfree(vm->mem); + vm->mem = NULL; + vm->size = 0; + return; +} + +/* + * We never shrink a vmem object on the premise that over time, object + * will only grow for a while then reach a steady state. + */ +void +vmem_realloc(vmem_t *vm, size_t size) +{ + /* + * Reallocate only if we must. + */ + if (size > vm->size) { + vm->mem = xrealloc(vm->mem, size); + vm->size = size; + } + return; +} + + diff --git a/vtesto b/vtesto new file mode 100755 index 000000000..396b099b0 --- /dev/null +++ b/vtesto @@ -0,0 +1,9 @@ +#!/bin/sh + +# +# Run our testsuite under valgrind. Mostly it complains about core GNU libc +# functions, but it does actually help find interesting stuff in our own code +# from time to time. +# + +PNAME="valgrind -q ./gpsbabel" ./testo diff --git a/waypt.c b/waypt.c new file mode 100644 index 000000000..b1d49e3db --- /dev/null +++ b/waypt.c @@ -0,0 +1,585 @@ +/* + Perform various operations on waypoints. + + Copyright (C) 2002-2007 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include "defs.h" +#include "cet_util.h" +#include "grtcirc.h" +#include "garmin_fs.h" + +queue waypt_head; +static unsigned int waypt_ct; +static short_handle mkshort_handle; +int geocaches_present; + +void +waypt_init(void) +{ + mkshort_handle = mkshort_new_handle(); + QUEUE_INIT(&waypt_head); +} + +waypoint * +waypt_dupe(const waypoint *wpt) +{ + /* + * This and waypt_free should be closely synced. + */ + waypoint * tmp; + url_link *url_next; + + tmp = waypt_new(); + memcpy(tmp, wpt, sizeof(waypoint)); + tmp->url_next = NULL; + + if (wpt->shortname) + tmp->shortname = xstrdup(wpt->shortname); + if (wpt->description) + tmp->description = xstrdup(wpt->description); + if (wpt->notes) + tmp->notes = xstrdup(wpt->notes); + if (wpt->url) + tmp->url = xstrdup(wpt->url); + if (wpt->url_link_text) + tmp->url_link_text = xstrdup(wpt->url_link_text); + for (url_next = wpt->url_next; url_next; url_next = url_next->url_next) { + waypt_add_url(tmp, + (url_next->url) ? xstrdup(url_next->url) : NULL, + (url_next->url_link_text) ? xstrdup(url_next->url_link_text) : NULL); + } + if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) + tmp->icon_descr = xstrdup(wpt->icon_descr); + if (wpt->gc_data.desc_short.utfstring) { + tmp->gc_data.desc_short.utfstring = + xstrdup(wpt->gc_data.desc_short.utfstring); + } + if (wpt->gc_data.desc_long.utfstring) { + tmp->gc_data.desc_long.utfstring = + xstrdup(wpt->gc_data.desc_long.utfstring); + } + if (wpt->gc_data.placer) { + tmp->gc_data.placer = xstrdup(wpt->gc_data.placer); + } + if (wpt->gc_data.hint) { + tmp->gc_data.hint = xstrdup(wpt->gc_data.hint); + } + + /* + * It's important that this duplicated waypoint not appear + * on the master Q. + */ + QUEUE_INIT(&tmp->Q); + tmp->fs = fs_chain_copy( wpt->fs ); + + return tmp; +} + +void +waypt_add(waypoint *wpt) +{ + double lat_orig = wpt->latitude; + double lon_orig = wpt->longitude; + + ENQUEUE_TAIL(&waypt_head, &wpt->Q); + waypt_ct++; + + if (wpt->latitude < -90) wpt->latitude += 180; + else if (wpt->latitude > +90) wpt->latitude -= 180; + if (wpt->longitude < -180) wpt->longitude += 360; + else if (wpt->longitude > +180) wpt->longitude -= 360; + + if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) + fatal ("Invalid latitude %f in waypoint %s.\n", + lat_orig, wpt->shortname ? wpt->shortname : ""); + if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) + fatal ("Invalid longitude %f in waypoint %s.\n", + lon_orig, wpt->shortname ? wpt->shortname : ""); + + /* + * Some input may not have one or more of these types so we + * try to be sure that we have these fields even if just by + * copying them from elsewhere. + */ + if (wpt->shortname == NULL) { + if (wpt->description) { + wpt->shortname = xstrdup(wpt->description); + } else if (wpt->notes) { + wpt->shortname = xstrdup(wpt->notes); + } else { + /* Last ditch: make up a name */ + char cbuf[10]; + snprintf(cbuf, sizeof(cbuf), "WPT%03d", waypt_ct); + wpt->shortname = xstrdup(cbuf); + } + } + + if (wpt->description == NULL || strlen(wpt->description) == 0) { + if (wpt->description) + xfree(wpt->description); + if (wpt->notes != NULL) { + wpt->description = xstrdup(wpt->notes); + } else { + if (wpt->shortname != NULL) { + wpt->description = xstrdup(wpt->shortname); + } + } + } + + /* This is a bit tacky, but it allows a hint whether we've seen + * geocaches or not in the life cycle of this run. Of course, + * the caches could have been filtered out of existance and not + * all waypoints may have this and a few other pitfalls, but it's + * an easy and fast test here. + */ + if (wpt->gc_data.diff && wpt->gc_data.terr) { + geocaches_present = 1; + } +} + +void +waypt_del(waypoint *wpt) +{ + dequeue(&wpt->Q); + waypt_ct--; +} + +/* + * A constructor for a single waypoint. + */ +waypoint * +waypt_new(void) +{ + waypoint *wpt; + + wpt = (waypoint *) xcalloc(sizeof (*wpt), 1); + wpt->altitude = unknown_alt; + wpt->fix = fix_unknown; + wpt->sat = -1; + + QUEUE_INIT(&wpt->Q); + return wpt; +} + +unsigned int +waypt_count(void) +{ + return waypt_ct; +} + +void +set_waypt_count(unsigned int nc) +{ + waypt_ct = nc; +} + +void +waypt_disp(const waypoint *wpt) +{ + char *tmpdesc = NULL; + if (wpt->creation_time) { + printf("%s ", ctime(&wpt->creation_time)); + } + printposn(wpt->latitude,1); + printposn(wpt->longitude,0); + + if ( wpt->description ) { + tmpdesc = xstrdup( wpt->description); + printf("%s/%s", + global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, tmpdesc) : + wpt->shortname, + tmpdesc); + if ( tmpdesc ) + xfree(tmpdesc); + } + + if (wpt->altitude != unknown_alt) + printf(" %f", wpt->altitude); + printf("\n"); +} + +void +waypt_status_disp(int total_ct, int myct) +{ + fprintf(stdout, "%d/%d/%d\r", myct*100/total_ct, myct, total_ct); + fflush(stdout); +} + +void +waypt_disp_all(waypt_cb cb) +{ + queue *elem, *tmp; + waypoint *waypointp; + int i = 0; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + if (global_opts.verbose_status) { + i++; + waypt_status_disp(waypt_ct, i); + } + (*cb) (waypointp); + } + if (global_opts.verbose_status) { + fprintf(stdout, "\r\n"); + } +} + +void +waypt_init_bounds(bounds *bounds) +{ + /* Set data out of bounds so that even one waypoint will reset */ + bounds->max_lat = -9999; + bounds->max_lon = -9999; + bounds->min_lat = 9999; + bounds->min_lon = 9999; + bounds->max_alt = -unknown_alt; + bounds->min_alt = unknown_alt; +} + +int +waypt_bounds_valid(bounds *bounds) +{ + /* Returns true if bb has any 'real' data in it */ + return bounds->max_lat > -9999; +} + +/* + * Recompund bounding box based on new position point. + */ +void +waypt_add_to_bounds(bounds *bounds, const waypoint *waypointp) +{ + if (waypointp->latitude > bounds->max_lat) + bounds->max_lat = waypointp->latitude; + if (waypointp->longitude > bounds->max_lon) + bounds->max_lon = waypointp->longitude; + if (waypointp->latitude < bounds->min_lat) + bounds->min_lat = waypointp->latitude; + if (waypointp->longitude < bounds->min_lon) + bounds->min_lon = waypointp->longitude; + if (waypointp->altitude != unknown_alt) { + if (waypointp->altitude < bounds->min_alt) + bounds->min_alt = waypointp->altitude; + if (waypointp->altitude > bounds->max_alt) + bounds->max_alt = waypointp->altitude; + } +} + + +/* + * Makes another pass over the data to compute bounding + * box data and populates bounding box information. + */ + +void +waypt_compute_bounds(bounds *bounds) +{ + queue *elem, *tmp; + waypoint *waypointp; + + waypt_init_bounds(bounds); + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + waypt_add_to_bounds(bounds, waypointp); + } +} + +waypoint * +find_waypt_by_name(const char *name) +{ + queue *elem, *tmp; + waypoint *waypointp; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + if (0 == strcmp(waypointp->shortname, name)) { + return waypointp; + } + } + + return NULL; +} + +void +waypt_free( waypoint *wpt ) +{ + /* + * This and waypt_dupe should be closely synced. + */ + if (wpt->shortname) { + xfree(wpt->shortname); + } + if (wpt->description) { + xfree(wpt->description); + } + if (wpt->notes) { + xfree(wpt->notes); + } + if (wpt->url) { + xfree(wpt->url); + } + if (wpt->url_link_text) { + xfree(wpt->url_link_text); + } + if (wpt->url_next) { + url_link *url_next; + + for (url_next = wpt->url_next; url_next; ) { + + url_link *tonuke = url_next; + if (tonuke->url) { + xfree(tonuke->url); + } + if (tonuke->url_link_text) { + xfree(tonuke->url_link_text); + } + url_next = tonuke->url_next; + xfree(tonuke); + } + } + if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) { + xfree((char *)(void *)wpt->icon_descr); + } + if (wpt->gc_data.desc_short.utfstring) { + xfree(wpt->gc_data.desc_short.utfstring); + } + if (wpt->gc_data.desc_long.utfstring) { + xfree(wpt->gc_data.desc_long.utfstring); + } + if (wpt->gc_data.placer) { + xfree(wpt->gc_data.placer); + } + if (wpt->gc_data.hint) { + xfree (wpt->gc_data.hint); + } + fs_chain_destroy( wpt->fs ); + xfree(wpt); +} + +void +waypt_flush( queue *head ) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(head, elem, tmp) { + waypoint *q = (waypoint *) dequeue(elem); + waypt_free(q); + if (head == &waypt_head) { + waypt_ct--; + } + } +} + +void +waypt_flush_all() +{ + if ( mkshort_handle ) { + mkshort_del_handle( &mkshort_handle ); + } + waypt_flush(&waypt_head); +} + +void +waypt_backup(signed int *count, queue **head_bak) +{ + queue *elem, *tmp, *qbackup; + waypoint *wpt; + int no = 0; + + qbackup = (queue *) xcalloc(1, sizeof(*qbackup)); + QUEUE_INIT(qbackup); + + QUEUE_MOVE(qbackup, &waypt_head); + QUEUE_INIT(&waypt_head); + + waypt_ct = 0; + + QUEUE_FOR_EACH(qbackup, elem, tmp) + { + wpt = (waypoint *)elem; + waypt_add(waypt_dupe(wpt)); + no++; + } + + *head_bak = qbackup; + *count = no; +} + +void +waypt_restore(signed int count, queue *head_bak) +{ + if (head_bak == NULL) return; + + waypt_flush(&waypt_head); + QUEUE_INIT(&waypt_head); + QUEUE_MOVE(&waypt_head, head_bak); + waypt_ct = count; + xfree(head_bak); +} + +void +waypt_add_url(waypoint *wpt, char *link, char *url_link_text) +{ + if ((link == NULL) && (url_link_text == NULL)) return; + + /* Special case first one; it goes right into the waypoint. */ + if ((wpt->url == NULL) && (wpt->url_link_text == NULL)) { + wpt->url = link; + wpt->url_link_text = url_link_text; + } else { + url_link *tail; + url_link *new_link = xcalloc(sizeof(url_link), 1); + new_link->url = link; + new_link->url_link_text = url_link_text; + + /* Find current end of chain and tack this onto the end.. */ + for (tail = wpt->url_next;;tail = tail->url_next) { + if (tail == NULL) { + wpt->url_next = new_link; + break; + } + if (tail->url_next == NULL) { + tail->url_next = new_link; + break; + } + } + } +} + +static double +gcgeodist(const double lat1, const double lon1, + const double lat2, const double lon2) +{ + double res; + + res = radtometers(gcdist(RAD(lat1), RAD(lon1), RAD(lat2), RAD(lon2))); + if (res < 0.1) res = 0; /* calc. diffs on 32- and 64-bit hosts */ + + return res; +} + +/* + * returns full creation_time with parts of seconds in fractional portion + */ + +double +waypt_time(const waypoint *wpt) +{ + if (wpt->creation_time <= 0) + return (double) 0; + else + return ((double)wpt->creation_time + ((double)wpt->microseconds / 1000000)); +} + +/* + * Calculates the distance between points "A" and "B" including + * special data (Garmin interstep links) + * The result comes in meters. + */ + +double +waypt_distance_ex(const waypoint *A, const waypoint *B) +{ + double res = 0; + garmin_fs_p gmsd; + + if ((A == NULL) || (B == NULL)) return 0; + + if ((gmsd = GMSD_FIND(A)) && (gmsd->ilinks != NULL)) + { + garmin_ilink_t *link = gmsd->ilinks; + + res = gcgeodist(A->latitude, A->longitude, link->lat, link->lon); + while (link->next != NULL) + { + garmin_ilink_t *prev = link; + link = link->next; + res += gcgeodist(prev->lat, prev->lon, link->lat, link->lon); + } + res += gcgeodist(link->lat, link->lon, B->latitude, B->longitude); + } + else + res = gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude); + + return res; +} + +double +waypt_distance(const waypoint *A, const waypoint *B) +{ + if ((A == NULL) || (B == NULL)) return 0; + else return gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude); +} + +/* + * Calculates the speed between points "A" and "B" including + * special data (Garmin interstep links) + * The result comes in meters per second and is always positive. + */ + +double +waypt_speed_ex(const waypoint *A, const waypoint *B) +{ + double dist, time; + + dist = waypt_distance_ex(A, B); + if (dist == 0) return 0; + + time = fabs(waypt_time(A) - waypt_time(B)); + if (time > 0) + return (dist / time); + else + return 0; +} + +/* + * Calculates the speed between points "A" and "B" + * the result comes in meters per second and is always positive + */ + +double +waypt_speed(const waypoint *A, const waypoint *B) +{ + double dist, time; + + dist = waypt_distance(A, B); + if (dist == 0) return 0; + + time = fabs(waypt_time(A) - waypt_time(B)); + if (time > 0) + return (dist / time); + else + return 0; +} + +/* + * Calculates "Course True" from A to B + */ +double +waypt_course(const waypoint *A, const waypoint *B) +{ + if (A && B) + return heading_true_degrees(RAD(A->latitude), RAD(A->longitude), RAD(B->latitude), RAD(B->longitude)); + else + return 0; +} diff --git a/wbt-200.c b/wbt-200.c new file mode 100644 index 000000000..788450562 --- /dev/null +++ b/wbt-200.c @@ -0,0 +1,1022 @@ +/* + * Serial download of track data from a Wintec WBT-200. + * + * Copyright (C) 2006 Andy Armstrong + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include "defs.h" +#include "gbser.h" +#include "grtcirc.h" +#include + +#define MYNAME "WBT-100/200" +#define NL "\x0D\x0A" + +#define WBT200BAUD 9600 + +#define WBT201BAUD 57600 +#define WBT201CHUNK 4096 + +#define TIMEOUT 5000 + +#define RECLEN_V1 12 +#define RECLEN_V2 16 + +#define RECLEN_WBT201 16 + +/* tk1 file format stuff */ + +#define TK1_MAGIC "WintecLogFormat" +#define TK1_DATA_OFFSET 0x0400 +#define TK1_END_FLAG 0x04000000ul + +/* Used to sanity check data - from + * http://hypertextbook.com/facts/2001/DanaWollman.shtml + * The MAXALT check doesn't need to be enabled unless there's + * a format with larger records than V2. + */ +/*#define MAXALT 120000*/ + +#define _MAX(a, b) ((a) > (b) ? (a) : (b)) +#define RECLEN_MAX _MAX(RECLEN_V1, RECLEN_V2) + +/* Flags for WBT201 */ +enum { + WBT201_TRACK_START = 0x01, + WBT201_WAYPOINT = 0x02, + WBT201_OVER_SPEED = 0x04 +}; + +#define BUFSPEC(b) b, sizeof(b) + +/* The formats here must be in ascending record length order so that + * each format identification attempt can read more data from the + * device if necessary. If that proves to be a bad order to try the + * heuristics the format matching code will have to be rejigged. + */ +static struct { + size_t reclen; +} fmt_version[] = { + { RECLEN_V1 }, + { RECLEN_V2 }, + { 0 } +}; + +/* Number of lines to skip while waiting for an ACK from a command. I've seen + * conversations with up to 30 lines of cruft before the response so 60 isn't + * too crazy. + */ +#define RETRIES 60 + +/* + * For WBT-200 protocol documentation see: + * http://hexten.net/wiki/index.php/WBT-200_Comms_Protocol + */ + +static void *fd; +static FILE *fl; +static char *port; +static char *erase; + +static enum { + UNKNOWN, WBT200, WBT201 +} dev_type = UNKNOWN; + +struct buf_chunk { + struct buf_chunk *next; + size_t size; + size_t used; + /* data follows in memory */ +}; + +#define buf_CHUNK_DATA(c) \ + ((void *) ((struct buf_chunk *) (c) + 1)) + +#define buf_CHUNK_PTR(c, offset) \ + ((void *) ((char *) buf_CHUNK_DATA(c) + (offset))) + +struct buf_head { + struct buf_chunk *head; + struct buf_chunk *tail; + size_t alloc; + size_t used; + /* read position */ + struct buf_chunk *current; + unsigned long offset; + /* shoehorned in here primarily out of laziness */ + unsigned checksum; +}; + +struct read_state { + route_head *route_head; + unsigned wpn, tpn; + + struct buf_head data; +}; + +static void db(int l, const char *msg, ...) { + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vprintf(msg, ap); + } + va_end(ap); +} + +/* Growable buffer support. TODO: Put this in a separate file and + * tidy up its interface. + */ + +static void buf_init(struct buf_head *h, size_t alloc) { + h->head = NULL; + h->tail = NULL; + h->alloc = alloc; + h->used = 0; + h->checksum = 0; + h->offset = 0; +} + +static void buf_empty(struct buf_head *h) { + struct buf_chunk *chunk, *next; + for (chunk = h->head; chunk; chunk = next) { + next = chunk->next; + xfree(chunk); + } + h->head = NULL; + h->tail = NULL; + h->used = 0; + h->checksum = 0; +} + +static void buf_rewind(struct buf_head *h) { + h->current = h->head; + h->offset = 0; +} + +static size_t buf_read(struct buf_head *h, void *data, size_t len) { + char *bp = data; + size_t got = 0; + + while (len != 0 && h->current != NULL) { + size_t avail = h->current->used - h->offset; + if (avail > len) { avail = len; } + + /* Allow NULL buffer pointer to skip bytes */ + if (NULL != bp) { + memcpy(bp, buf_CHUNK_PTR(h->current, h->offset), avail); + bp += avail; + } + + h->offset += avail; + len -= avail; + got += avail; + + if (h->offset == h->current->used) { + h->current = h->current->next; + h->offset = 0; + } + } + + return got; +} + +static void buf_extend(struct buf_head *h, size_t amt) { + struct buf_chunk *c; + size_t sz = amt + sizeof(struct buf_chunk); + if (c = xmalloc(sz), NULL == c) { + fatal(MYNAME ": Can't allocate %lu bytes for buffer\n", (unsigned long) sz); + } + + c->next = NULL; + c->size = amt; + c->used = 0; + + if (NULL == h->head) { + h->head = c; + } else { + h->tail->next = c; + } + + h->tail = c; +} + +static void buf_update_checksum(struct buf_head *h, const void *data, size_t len) { + unsigned char *cp = (unsigned char *) data; + unsigned i; + + db(4, "Updating checksum with %p, %lu, before: %02x ", + data, (unsigned long) len, h->checksum); + for (i = 0; i < len; i++) { + h->checksum ^= cp[i]; + } + db(4, "after: %02x\n", h->checksum); +} + +static void buf_write(struct buf_head *h, const void *data, size_t len) { + size_t avail; + const char *bp = data; + + buf_update_checksum(h, data, len); + + h->used += len; + + if (NULL == h->tail) { + buf_extend(h, h->alloc); + } + + for (;;) { + avail = h->tail->size - h->tail->used; + if (avail > len) { avail = len; } + + memcpy((char *) buf_CHUNK_PTR(h->tail, h->tail->used), bp, avail); + h->tail->used += avail; + bp += avail; + len -= avail; + if (len == 0) { + break; + } + buf_extend(h, h->alloc); + } +} + +static void rd_drain() { + if (gbser_flush(fd)) { + fatal(MYNAME ": Comm error\n"); + } +} + +static void rd_line(char *buf, int len) { + int rc; + if (rc = gbser_read_line(fd, buf, len, TIMEOUT, 0x0A, 0x0D), rc != gbser_OK) { + fatal(MYNAME ": Read error (%d)\n", rc); + } + db(3, "Got response: \"%s\"\n", buf); +} + +static void wr_cmd(const char *cmd) { + int rc; + db(3, "Sending: %s\n", cmd); + if (rc = gbser_print(fd, cmd), gbser_OK != rc) { + fatal(MYNAME ": Write error (%d)\n", rc); + } +} + +static void wr_cmdl(const char *cmd) { + wr_cmd(cmd); + wr_cmd(NL); +} + +static int expect(const char *str) { + int state = 0; + int c, i; + int errors = 5; /* allow this many errors */ + + for (i = 0; i < 5000; i++) { + /* reached end of string */ + if (str[state] == '\0') { + return 1; + } + + c = gbser_readc_wait(fd, 500); + if (c < 0) { + db(3, "Got error: %d\n", c); + if (--errors <= 0) { + return 0; + } + } else { + db(3, "Got char: %02x '%c'\n", c, isprint(c) ? c : '.'); + if (c == str[state]) { + state++; /* carry on */ + } else { + state = 0; /* go back to start */ + } + } + } + + return 0; +} + +static int wbt200_try() { + int rc; + + db(1, "Trying WBT100/200\n"); + + if ((rc = gbser_set_port(fd, WBT200BAUD, 8, 0, 1))) { + db(1, "Set baud rate to %d failed (%d)\n", WBT200BAUD, rc); + return 0; + } + + wr_cmdl("$PFST,NORMAL"); + return expect("$PFST"); +} + +static int wbt201_try() { + int rc; + + db(1, "Trying WBT201/G-Rays 2\n"); + + if ((rc = gbser_set_port(fd, WBT201BAUD, 8, 0, 1))) { + db(1, "Set baud rate to %d failed (%d)\n", WBT201BAUD, rc); + return 0; + } + + wr_cmdl("@AL"); + return expect("@AL"); +} + +static int guess_device() { + int i; + db(1, "Guessing device...\n"); + for (i = 0; i < 5; i++) { + if (wbt200_try()) { + return WBT200; + } + if (wbt201_try()) { + return WBT201; + } + } + return UNKNOWN; +} + +static void rd_init(const char *fname) { + port = xstrdup(fname); + + db(1, "Opening port...\n"); + if (fd = gbser_init(port), NULL == fd) { + fatal(MYNAME ": Can't initialise port \"%s\"\n", port); + } + + dev_type = guess_device(); + if (UNKNOWN == dev_type) { + fatal(MYNAME ": Can't determine device type\n"); + } +} + +static void rd_deinit(void) { + db(1, "Closing port...\n"); + gbser_deinit(fd); + fd = NULL; + xfree(port); +} + +static void rd_buf(void *buf, int len) { + int rc; + if (rc = gbser_read_wait(fd, buf, len, TIMEOUT), rc < 0) { + fatal(MYNAME ": Read error (%d)\n", rc); + } else if (rc < len) { + fatal(MYNAME ": Read timout\n"); + } +} + +static void file_init(const char *fname) { + db(1, "Opening file...\n"); + if (fl = fopen(fname, "rb"), NULL == fl) { + fatal(MYNAME ": Can't open file '%s'\n", fname); + } +} + +static void file_deinit(void) { + db(1, "Closing file...\n"); + fclose(fl); +} + +static int starts_with(const char *buf, const char *pat) { + size_t pat_len = strlen(pat); + return (pat_len <= strlen(buf)) + ? (memcmp(buf, pat, pat_len) == 0) + : 0; +} + +/* Send a command then wait for a line starting with the command string + * to be returned. + */ +static int do_cmd(const char *cmd, const char *expect, char *buf, int len) { + int try; + + rd_drain(); + wr_cmdl(cmd); + + db(2, "Cmd: %s\n", cmd); + + /* We may need to skip a load of data to start with - the unit streams + * NMEA data all the time so it's highly likely that it'll be in the + * middle of an NMEA sentence when we start listening. + */ + for (try = 0; try < RETRIES; try++) { + rd_line(buf, len); + db(3, "Got: %s\n", buf); + if (starts_with(buf, expect)) { + db(2, "Matched: %s\n", buf); + return strlen(expect); + } + db(2, "Skip %d: %s\n", try, buf); + } + + fatal(MYNAME ": Bad response from unit\n"); + return 0; /* keep compiler quiet */ +} + +/* Issue a command that expects the same string to be echoed + * back as an ACK + */ +static int do_simple(const char *cmd, char *buf, int len) { + return do_cmd(cmd, cmd, buf, len); +} + +static char *get_param(const char *cmd, char *buf, int len) { + int cl = do_simple(cmd, buf, len); + return buf + cl + 1; +} + +static int get_param_int(const char *cmd) { + char buf[80]; + return atoi(get_param(cmd, buf, sizeof(buf))); +} + +static double get_param_float(const char *cmd) { + char buf[80]; + return atof(get_param(cmd, buf, sizeof(buf))); +} + +/* Decompose binary date into discreet fields */ +#define _SPLIT_DATE(tim) \ + int sec = (((tim) >> 0) & 0x3F); \ + int min = (((tim) >> 6) & 0x3F); \ + int hour = (((tim) >> 12) & 0x1F); \ + int mday = (((tim) >> 17) & 0x1F); \ + int mon = (((tim) >> 22) & 0x0F); \ + int year = (((tim) >> 26) & 0x3F); + +static time_t decode_date(gbuint32 tim) { + _SPLIT_DATE(tim) + struct tm t; + + t.tm_sec = sec; + t.tm_min = min; + t.tm_hour = hour; + t.tm_mday = mday; + t.tm_mon = mon - 1; + t.tm_year = year + 100; + + return mkgmtime(&t); +} + +static int check_date(gbuint32 tim) { + _SPLIT_DATE(tim) + + /* Sanity check the date. We don't allow years prior to 2004 because zero in + * those bits will usually indicate that we have an altitude instead of a + * date (i.e. that the data is the new format that uses 16 byte records). + */ + return sec < 60 && min < 60 && hour < 24 && + mday > 0 && mday <= 31 && mon > 0 && mon <= 12 && year >= 4; +} + +static waypoint *make_point(double lat, double lon, double alt, time_t tim, const char *fmt, int index) { + char wp_name[20]; + waypoint *wpt = waypt_new(); + + sprintf(wp_name, fmt, index); + + wpt->latitude = lat;; + wpt->longitude = lon; + wpt->altitude = alt; + wpt->creation_time = tim; + wpt->shortname = xstrdup(wp_name); + + return wpt; +} + +static waypoint *make_waypoint(struct read_state *st, double lat, double lon, double alt, time_t tim) { + return make_point(lat, lon, alt, tim, "WP%04d", ++st->wpn); +} + +static waypoint *make_trackpoint(struct read_state *st, double lat, double lon, double alt, time_t tim) { + return make_point(lat, lon, alt, tim, "TP%04d", ++st->tpn); +} + +static int wbt200_data_chunk(struct read_state *st, const void *buf, int fmt) { + gbuint32 tim; + double lat, lon, alt; + time_t rtim; + waypoint *tpt = NULL; + const char *bp = buf; + size_t buf_used = fmt_version[fmt].reclen; + + tim = le_read32(bp + 0); + + lat = (double) ((gbint32) le_read32(bp + 4)) / 10000000; + lon = (double) ((gbint32) le_read32(bp + 8)) / 10000000; + + /* Handle extra fields in longer records here. */ + if (buf_used >= 16) { + alt = (double) le_read32(bp + 12) / 10; + } else { + alt = unknown_alt; + } + + rtim = decode_date(tim); + + if (lat >= 100) { + /* Start new track in the northern hemisphere */ + lat -= 100; + st->route_head = NULL; + } else if (lat <= -100) { + /* Start new track in the southern hemisphere */ + /* This fix courtesy of Anton Frolich */ + lat += 100; + st->route_head = NULL; + } + + tpt = make_trackpoint(st, lat, lon, alt, rtim); + + if (NULL == st->route_head) { + db(1, "New Track\n"); + st->route_head = route_head_alloc(); + track_add_head(st->route_head); + } + + track_add_wpt(st->route_head, tpt); + + return 1; +} + +/* Return true iff the data appears valid with the specified record length */ +static int is_valid(struct buf_head *h, int fmt) { + char buf[RECLEN_MAX]; + size_t reclen = fmt_version[fmt].reclen; + + buf_rewind(h); + + db(2, "Checking %lu bytes of data against format %d\n", h->used, fmt); + + for (;;) { + size_t got = buf_read(h, buf, reclen); + gbuint32 tim; + /* Don't mind odd bytes at the end - we may + * be examining an incomplete dataset. + */ + if (got != reclen) { + break; + } + + tim = le_read32(buf + 0); + if (!check_date(tim)) { + return 0; + } + + if (reclen > 12) { +#ifdef MAXALT + gbuint32 alt = le_read32(buf + 12); + if (alt > MAXALT * 10) { + return 0; + } +#endif + } + } + + return 1; +} + +static void wbt200_process_data(struct read_state *pst, int fmt) { + char buf[RECLEN_MAX]; + size_t reclen = fmt_version[fmt].reclen; + + buf_rewind(&pst->data); + + db(2, "Processing %lu bytes of data using format %d\n", pst->data.used, fmt); + + for (;;) { + size_t got = buf_read(&pst->data, buf, reclen); + if (got != reclen) { + break; + } + wbt200_data_chunk(pst, buf, fmt); + } +} + +static void state_init(struct read_state *pst) { + pst->route_head = NULL; + pst->wpn = 0; + pst->tpn = 0; + + buf_init(&pst->data, RECLEN_V1 * RECLEN_V2); +} + +static void state_empty(struct read_state *pst) { + buf_empty(&pst->data); + state_init(pst); +} + +static void want_bytes(struct buf_head *h, size_t len) { + char buf[512]; + + db(3, "Reading %lu bytes from device\n", (unsigned long) len); + + while (len > 0) { + size_t want = sizeof(buf); + if (want > len) { want = len; } + rd_buf(buf, want); + buf_write(h, buf, want); + len -= want; + } +} + +static void wbt200_data_read(void) { + /* Awooga! Awooga! Statically allocated buffer danger! + * Actually, it's OK because rd_line can read arbitrarily + * long lines returning only the first N characters + */ + char line_buf[100]; + int fmt; + unsigned long count; + struct read_state st; + + state_init(&st); + + /* We could potentially parse the version string to find out which + * data format to use - but it's not clear how the version string + * will increment in the future - so just now it's more future- + * proof to rely on analysing the data. We need to be able to do + * that with files anyway - because they're not versioned. + */ + do_simple("$PFST,FIRMWAREVERSION", BUFSPEC(line_buf)); + + do_simple("$PFST,NORMAL", BUFSPEC(line_buf)); + do_simple("$PFST,READLOGGER", BUFSPEC(line_buf)); + + /* Now we're into binary mode */ + rd_buf(line_buf, 6); /* six byte header */ + count = le_read16(line_buf + 2) + 1; + if (count == 0x10000) { + count = 0; + } + + db(3, "%lu points available\n", count); + + /* Loop through the known formats requesting more data from the + * device each time. When the device contains only a single + * point the first format will get a false positive - so we'll + * lose the altitude data. + */ + for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { + size_t reclen = fmt_version[fmt].reclen; + size_t want = reclen * count; + + if (want < st.data.used) { + fatal(MYNAME ": Internal error: formats not ordered in ascending size order\n"); + } + + db(3, "Want %lu bytes of data\n", (unsigned long) want); + + /* Top up the buffer */ + want_bytes(&st.data, want - st.data.used); + + /* And see if it's valid */ + if (is_valid(&st.data, fmt)) { + break; + } + } + + if (fmt_version[fmt].reclen == 0) { + fatal(MYNAME ": Can't autodetect data format\n"); + } + + wbt200_process_data(&st, fmt); + + /* Erase data? */ + + if (*erase != '0') { + int f; + db(1, "Erasing data\n"); + for (f = 27; f <= 31; f++) { + sprintf(line_buf, "$PFST,REMOVEFILE,%d", f); + do_cmd(line_buf, "$PFST,REMOVEFILE", BUFSPEC(line_buf)); + } + db(1, "Reclaiming free space\n"); + for (f = 0; f <= 3; f++) { + sprintf(line_buf, "$PFST,FFSRECLAIM,%d", f); + do_cmd(line_buf, "$PFST,FFSRECLAIM", BUFSPEC(line_buf)); + } + } + + do_simple("$PFST,NORMAL", BUFSPEC(line_buf)); + + state_empty(&st); +} + +static int all_null(const void *buf, const int len) { + const char *bp = buf; + int i; + + for (i = 0; i < len; i++) { + if (bp[i]) { + return 0; + } + } + + return 1; +} + +static int wbt201_data_chunk(struct read_state *st, const void *buf) { + gbuint32 tim; + gbuint16 flags; + double lat, lon, alt; + time_t rtim; + waypoint *tpt = NULL; + const char *bp = buf; + + /* Zero records are skipped */ + if (all_null(buf, RECLEN_WBT201)) { + return 1; + } + + flags = le_read16(bp + 0); + tim = le_read32(bp + 2); + + if (TK1_END_FLAG == tim) { + /* EOF? (TK1 files only as far as I know) */ + return 0; + } + + lat = (double) ((gbint32) le_read32(bp + 6)) / 10000000; + lon = (double) ((gbint32) le_read32(bp + 10)) / 10000000; + alt = (double) ((gbint16) le_read16(bp + 14)); + + rtim = decode_date(tim); + + if ((flags & WBT201_WAYPOINT) && (global_opts.masked_objective & WPTDATAMASK)) { + waypoint *wpt = make_waypoint(st, lat, lon, alt, rtim); + waypt_add(wpt); + } + + if (global_opts.masked_objective & TRKDATAMASK) { + if (flags & WBT201_TRACK_START) { + st->route_head = NULL; + } + + tpt = make_trackpoint(st, lat, lon, alt, rtim); + + if (NULL == st->route_head) { + db(1, "New Track\n"); + st->route_head = route_head_alloc(); + track_add_head(st->route_head); + } + + track_add_wpt(st->route_head, tpt); + } + + return 1; +} + +static void wbt201_process_chunk(struct read_state *st) { + char buf[RECLEN_WBT201]; + + db(2, "Processing %lu bytes of data\n", st->data.used); + + while (buf_read(&st->data, buf, sizeof(buf)) == sizeof(buf) + && wbt201_data_chunk(st, buf)) { + /* do nothing */ + } +} + +static int wbt201_read_chunk(struct read_state *st, unsigned pos, unsigned limit) { + char cmd_buf[30]; + char line_buf[100]; + unsigned long cs; + char *lp, *op; + static char *cs_prefix = "@AL,CS,"; + + unsigned want = limit - pos; + if (want > WBT201CHUNK) { + want = WBT201CHUNK; + } + + db(3, "Reading bytes at %u (0x%x), limit = %u (0x%x), want = %u (0x%x)\n", + pos, pos, limit, limit, want, want); + + buf_empty(&st->data); + + rd_drain(); + sprintf(cmd_buf, "@AL,5,3,%d", pos); + wr_cmdl(cmd_buf); + + want_bytes(&st->data, want); + + /* checksum */ + rd_line(BUFSPEC(line_buf)); + + if (!starts_with(line_buf, cs_prefix)) { + db(2, "Bad checksum response\n"); + return 0; + } + + lp = line_buf + strlen(cs_prefix); + cs = strtoul(lp, &op, 16); + if (*lp == ',' || *op != ',') { + db(2, "Badly formed checksum\n"); + return 0; + } + + if (cs != st->data.checksum) { + db(2, "Checksums don't match. Got %02x, expected %02\n", cs, st->data.checksum); + return 0; + } + + /* ack */ + rd_line(BUFSPEC(line_buf)); + return starts_with(line_buf, cmd_buf); +} + +static void wbt201_data_read(void) { + char line_buf[100]; + struct read_state st; + unsigned tries; + + const char *tmp; + + double ver_hw; + double ver_sw; + double ver_fmt; + + unsigned log_addr_start; + unsigned log_addr_end; + unsigned log_area_start; + unsigned log_area_end; + + /* Read various device information. We don't use much of this yet - + * just log_addr_start and log_addr_end - but it's useful to have it + * here for debug and documentation purposes. + */ + tmp = get_param("@AL,7,1", BUFSPEC(line_buf)); + db(1, "Reading device \"%s\"\n", tmp); + + ver_hw = get_param_float("@AL,8,1"); + ver_sw = get_param_float("@AL,8,2"); + ver_fmt = get_param_float("@AL,8,3"); + + db(2, "versions: hw=%f, sw=%f, fmt=%f\n", + ver_hw, ver_sw, ver_fmt); + + log_addr_start = get_param_int("@AL,5,1"); /* we read from here... */ + log_addr_end = get_param_int("@AL,5,2"); /* ...to here and ... */ + log_area_start = get_param_int("@AL,5,9"); /* ...probably don't... */ + log_area_end = get_param_int("@AL,5,10"); /* ...need these. */ + + db(2, "Log addr=(%d..%d), area=(%d..%d)\n", + log_addr_start, log_addr_end, + log_area_start, log_area_end); + + state_init(&st); + + tries = 10; + while (log_addr_start < log_addr_end) { + if (wbt201_read_chunk(&st, log_addr_start, log_addr_end)) { + buf_rewind(&st.data); + wbt201_process_chunk(&st); + log_addr_start += st.data.used; + } else { + if (--tries <= 0) { + fatal(MYNAME ": Too many data errors during read\n"); + } + } + } + + if (*erase != '0') { + /* erase device */ + do_simple("@AL,5,6", BUFSPEC(line_buf)); + } + + state_empty(&st); + do_simple("@AL,2,1", BUFSPEC(line_buf)); +} + +static void file_read(void) { + char buf[512]; + size_t rc; + struct read_state st; + int fmt; + + const char * tk1_magic = TK1_MAGIC; + size_t tk1_magic_len = strlen(tk1_magic) + 1; + + state_init(&st); + + /* Read the whole file into the buffer */ + rc = fread(buf, 1, sizeof(buf), fl); + while (rc != 0) { + buf_write(&st.data, buf, rc); + rc = fread(buf, 1, sizeof(buf), fl); + } + + if (!feof(fl)) { + fatal(MYNAME ": Read error\n"); + } + + /* Although wbt-tk1 and wbt-bin are enumerated as distinct formats + * we handle them both here and autodetect which type we have. + */ + + /* WBT201 TK1 format? */ + + buf_rewind(&st.data); + buf_read(&st.data, buf, tk1_magic_len); + if (memcmp(buf, tk1_magic, tk1_magic_len) == 0) { + db(1, "Got TK1 file\n"); + buf_rewind(&st.data); + /* Seek */ + buf_read(&st.data, NULL, TK1_DATA_OFFSET); + wbt201_process_chunk(&st); + } + else { + db(1, "Got bin file\n"); + + /* Try to guess the data format */ + for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { + size_t reclen = fmt_version[fmt].reclen; + if ((st.data.used % reclen) == 0 && is_valid(&st.data, fmt)) { + break; + } + } + + if (fmt_version[fmt].reclen == 0) { + fatal(MYNAME ": Can't autodetect data format\n"); + } + + wbt200_process_data(&st, fmt); + } + + state_empty(&st); +} + +static void data_read(void) { + switch (dev_type) { + case WBT200: + wbt200_data_read(); + break; + + case WBT201: + wbt201_data_read(); + break; + + default: + fatal(MYNAME ": Unknown device type (internal)\n"); + break; + } +} + +/* wbt */ + +static arglist_t wbt_sargs[] = { + { "erase", &erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +ff_vecs_t wbt_svecs = { + ff_type_serial, + { ff_cap_read, ff_cap_read, ff_cap_none }, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + wbt_sargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ +}; + +/* used for wbt-bin /and/ wbt-tk1 */ + +static arglist_t wbt_fargs[] = { + ARG_TERMINATOR +}; + +ff_vecs_t wbt_fvecs = { + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none }, + file_init, + NULL, + file_deinit, + NULL, + file_read, + NULL, + NULL, + wbt_fargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ +}; diff --git a/wfff_xml.c b/wfff_xml.c new file mode 100644 index 000000000..4259cdca4 --- /dev/null +++ b/wfff_xml.c @@ -0,0 +1,295 @@ +/* + Copyright (C) 2006 Etienne Tasse etasse@yahoo.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "xmlgeneric.h" + +/* argument storage */ +static char * aicicon =0; +static char * aioicon =0; +static char * ahcicon =0; +static char * ahoicon =0; +static char * snmac =0; + +static +arglist_t wfff_xml_args[] = { + {"aicicon", &aicicon, "Infrastructure closed icon name", + "Red Square", ARGTYPE_STRING }, + {"aioicon", &aioicon, "Infrastructure open icon name", + "Green Square", ARGTYPE_STRING }, + {"ahcicon", &ahcicon, "Ad-hoc closed icon name", + "Red Diamond", ARGTYPE_STRING }, + {"ahoicon", &ahoicon, "Ad-hoc open icon name", + "Green Diamond", ARGTYPE_STRING }, + {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL }, + {0, 0, 0, 0, 0} +}; + +#define xfreez(p) { if (p) xfree(p); p=0; } + +#define MYNAME "wfff_xml" +#define MY_CBUF 4096 + +#if ! HAVE_LIBEXPAT +void +wfff_xml_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded WFFF_XML support because expat was not installed.\n"); +} +void +wfff_xml_read(void) +{ +} +void +wfff_xml_rd_deinit(void) +{ +} + +#else + +static xg_callback wfff_s, wfff_e; +static xg_callback wfff_wep, wfff_mac, wfff_type; +static xg_callback wfff_ssid, wfff_chan; +static xg_callback wfff_mnrssi, wfff_mxrssi; +static xg_callback wfff_first, wfff_last; +static xg_callback wfff_hdop, wfff_lat, wfff_lon; + +static +xg_tag_mapping loc_map[] = { + { wfff_s, cb_start, "/DocumentElement/AP" }, + { wfff_e, cb_end, "/DocumentElement/AP" }, + { wfff_wep, cb_cdata, "/DocumentElement/AP/WEP" }, + { wfff_mac, cb_cdata, "/DocumentElement/AP/MAC" }, + { wfff_ssid, cb_cdata, "/DocumentElement/AP/SSID" }, + { wfff_type, cb_cdata, "/DocumentElement/AP/Type" }, + { wfff_mnrssi, cb_cdata, "/DocumentElement/AP/MinRSSI" }, + { wfff_mxrssi, cb_cdata, "/DocumentElement/AP/MaxRSSI" }, + { wfff_chan, cb_cdata, "/DocumentElement/AP/Channel" }, + { wfff_first, cb_cdata, "/DocumentElement/AP/FirstSeen" }, + { wfff_last, cb_cdata, "/DocumentElement/AP/LastSeen" }, + { wfff_hdop, cb_cdata, "/DocumentElement/AP/HDOP" }, + { wfff_lat, cb_cdata, "/DocumentElement/AP/Lat" }, + { wfff_lon, cb_cdata, "/DocumentElement/AP/Lon" }, + { 0,0,0 } +}; + +/* work variables for wfff_xxx */ +static char* ap_mac =0; +static char* ap_ssid =0; +static char* ap_type =0; +static char* ap_wep =0; +static int ap_chan =0; +static time_t ap_first =0; +static char* ap_last =0; +static float ap_mnrssi =0.0; +static float ap_mxrssi =0.0; +static float ap_hdop =0.0; +static double ap_lat =0.0; +static double ap_lon =0.0; + +/* Start of AP block */ +void wfff_s(const char *args, const char **unused) +{ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); + ap_mnrssi=0.0; + ap_mxrssi=0.0; + ap_chan=0; + ap_hdop=0.0; + ap_first=0; + ap_last=0; + ap_lat=0.0; + ap_lon=0.0; +} + +void wfff_mac(const char *args, const char **unused) +{ + if (args) ap_mac = xstrdup(args); +} + +void wfff_ssid(const char *args, const char **unused) +{ + if (args) ap_ssid = xstrdup(args); +} + +void wfff_type(const char *args, const char **unused) +{ + if (args) ap_type = xstrdup(args); +} + +void wfff_mnrssi(const char *args, const char **unused) +{ + if (args) ap_mnrssi = atof(args); +} + +void wfff_mxrssi(const char *args, const char **unused) +{ + if (args) ap_mxrssi = atof(args); +} + +void wfff_chan(const char *args, const char **unused) +{ + if (args) ap_chan = atoi(args); +} + +void wfff_first(const char *args, const char **unused) +{ + if (args) { + ap_first = xml_parse_time(args, NULL); + } +} + +void wfff_last(const char *args, const char **unused) +{ + if (args) ap_last = xstrdup(args); +} + +void wfff_wep(const char *args, const char **unused) +{ + if (args) ap_wep = xstrdup(args); +} + +void wfff_hdop(const char *args, const char **unused) +{ + if (args) ap_hdop = atof(args); +} + +void wfff_lat(const char *args, const char **unused) +{ + if (args) ap_lat = atof(args); +} + +void wfff_lon(const char *args, const char **unused) +{ + if (args) ap_lon = atof(args); +} + +/* End of AP Block, set waypoint and add */ +static long tosscount=0; + +void wfff_e(const char *args, const char **unused) +{ + waypoint* wpt_tmp =0; + char desc[255] ="\0"; + + if ((ap_hdop>=1)&&(ap_hdop<50)) // Discard invalid GPS fix + { + wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1); + + if ( snmac ) { + wpt_tmp->shortname = xstrdup(ap_mac); + } else { + wpt_tmp->shortname = xstrdup(ap_ssid); + } + + snprintf(desc, sizeof desc, + "%s/%s/WEP %s/Ch %d/%2.0fdB/%2.0fdB/%s", + (snmac?ap_ssid:ap_mac), ap_type, ap_wep, + ap_chan, ap_mnrssi, ap_mxrssi, ap_last); + wpt_tmp->description = xstrdup(desc); + + wpt_tmp->latitude = ap_lat; + wpt_tmp->longitude = ap_lon; + wpt_tmp->hdop = ap_hdop; + wpt_tmp->altitude = unknown_alt; + wpt_tmp->fix = fix_unknown; + + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + if (case_ignore_strncmp(ap_wep,"On",2)==0) { + if (case_ignore_strncmp(ap_type,"AP",2)==0) { + wpt_tmp->icon_descr = xstrdup(aicicon); /* Infra Closed */ + } else { + wpt_tmp->icon_descr = xstrdup(ahcicon); /* AdHoc Closed */ + } + } else { + if (case_ignore_strncmp(ap_type,"AP",2)==0) { + wpt_tmp->icon_descr = xstrdup(aioicon); /* Infra Open */ + } else { + wpt_tmp->icon_descr = xstrdup(ahoicon); /* AdHoc Open */ + } + } + + wpt_tmp->creation_time = ap_first; + + waypt_add(wpt_tmp); + + } else { + tosscount++; + } + + /* cleanup */ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); + +} + + +void +wfff_xml_rd_init(const char *fname) +{ + tosscount = 0; + + xml_init(fname, loc_map, NULL); +} + +void +wfff_xml_read(void) +{ + xml_read(); +} + +void +wfff_xml_rd_deinit(void) +{ + + /* cleanup */ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); + + xml_deinit(); + + if (tosscount) { + warning("Warning: %s reading file. Threw away %ld invalid entries.\n", + MYNAME, tosscount ); + } + +} + +#endif + +ff_vecs_t wfff_xml_vecs = { + ff_type_file, + {ff_cap_read, ff_cap_none, ff_cap_none}, + wfff_xml_rd_init, + 0, + wfff_xml_rd_deinit, + 0, + wfff_xml_read, + 0, + 0, + wfff_xml_args +}; diff --git a/win32/.cvsignore b/win32/.cvsignore new file mode 100644 index 000000000..18e0e26db --- /dev/null +++ b/win32/.cvsignore @@ -0,0 +1 @@ +gpsbabel.rc diff --git a/win32/GPSBabelGUI.exe b/win32/GPSBabelGUI.exe new file mode 100644 index 0000000000000000000000000000000000000000..9bb790ac308f559ebcb51e9dae1af4e4b1ea6ec0 GIT binary patch literal 1057288 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≫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⋘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 U4ed0t_#JEbzJq3HmiSY`6N|IkkpKVy literal 0 HcmV?d00001 diff --git a/win32/gpsbabel.rc.in b/win32/gpsbabel.rc.in new file mode 100644 index 000000000..efe8d8025 --- /dev/null +++ b/win32/gpsbabel.rc.in @@ -0,0 +1,27 @@ +MAINICON ICON "@srcdir@/win32/gpsbabel.ico" + +1 VERSIONINFO +FILEVERSION @GBMAJOR@,@GBMINOR@,@GBMICRO@,@GBBUILD@ +PRODUCTVERSION @GBMAJOR@,@GBMINOR@,@GBMICRO@,@GBBUILD@ +FILEOS 0x4 +FILETYPE 0x1 +FILESUBTYPE 0x0L +FILEFLAGSMASK 0x3fL +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName", "GPSBabel Makers\0" + VALUE "FileDescription", "GPS format converter\0" + VALUE "FileVersion", "@GBMAJOR@.@GBMINOR@.@GBMICRO@@PACKAGE_RELEASE@\0" + VALUE "InternalName", "\0" + VALUE "LegalCopyright", "(C) 2002-2008 The people behind GPSBabel\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "gpsbabel.exe\0" + VALUE "ProductName", "GPSBabel\0" + VALUE "ProductVersion", "@GBMAJOR@.@GBMINOR@.@GBMICRO@@PACKAGE_RELEASE@\0" + VALUE "Comments", "http://www.gpsbabel.org\0" + } + } +} diff --git a/win32/gui-2/.cvsignore b/win32/gui-2/.cvsignore new file mode 100644 index 000000000..c3da04466 --- /dev/null +++ b/win32/gui-2/.cvsignore @@ -0,0 +1,2 @@ +GPSBabelGUI.rc +GPSBabelGUI.dsk diff --git a/win32/gui-2/GPSBabelGUI.cfg b/win32/gui-2/GPSBabelGUI.cfg new file mode 100644 index 000000000..8adc0e882 --- /dev/null +++ b/win32/gui-2/GPSBabelGUI.cfg @@ -0,0 +1,35 @@ +-$A- +-$B- +-$C- +-$D- +-$E- +-$F- +-$G+ +-$H+ +-$I- +-$J+ +-$K- +-$L- +-$M- +-$N+ +-$O+ +-$P+ +-$Q- +-$R- +-$S- +-$T- +-$U- +-$V- +-$W- +-$X+ +-$Y- +-$Z1 +-cg +-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +-H- +-W- +-M +-$M16384,1048576 +-K$00400000 +-LNc:\programme\borland\delphi4\Lib +-DMSWINDOWS diff --git a/win32/gui-2/GPSBabelGUI.dof b/win32/gui-2/GPSBabelGUI.dof new file mode 100644 index 000000000..a1981ffe9 --- /dev/null +++ b/win32/gui-2/GPSBabelGUI.dof @@ -0,0 +1,84 @@ +[Compiler] +A=0 +B=0 +C=0 +D=0 +E=0 +F=0 +G=1 +H=1 +I=0 +J=1 +K=0 +L=0 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=0 +W=0 +X=1 +Y=0 +Z=1 +ShowHints=0 +ShowWarnings=0 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir= +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath= +Packages=vcl;rtl;vclx;dbrtl;adortl;vcldb;bdertl;vcldbx;teeui;teedb;tee;ibxpress;visualclx;visualdbclx;dsnap;vclactnband +Conditionals=MSWINDOWS +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=0 +MajorVer=0 +MinorVer=2 +Release=15 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1033 +CodePage=1252 +[Version Info Keys] +CompanyName=GPSBabel Makers +FileDescription=GPSBabel Windows Frontend +FileVersion=0.2.15.0 +InternalName= +LegalCopyright=(C) 2005-2008 Olaf Klein (o.b.klein@gpsbabel.org) +LegalTrademarks= +OriginalFilename=GPSBabelGUI.exe +ProductName=GPSBabel +ProductVersion=1.3.x +Comments= +[HistoryLists\hlConditionals] +Count=1 +Item0=MSWINDOWS +[HistoryLists\hlUnitAliases] +Count=1 +Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; diff --git a/win32/gui-2/GPSBabelGUI.dpr b/win32/gui-2/GPSBabelGUI.dpr new file mode 100644 index 000000000..9dd0094e0 --- /dev/null +++ b/win32/gui-2/GPSBabelGUI.dpr @@ -0,0 +1,53 @@ +program GPSBabelGUI; +{ + Copyright (C) 2005-2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +} + +uses + gnugettext in 'gnugettext.pas', + gnugettextDx in 'gnugettextDx.pas', + delphi in 'delphi.pas', + Windows, + SysUtils, + classes, + Forms, + main in 'main.pas' {frmMain}, + utils in 'utils.pas', + common in 'common.pas', + filter in 'filter.pas' {frmFilter}, + about in 'about.pas' {frmAbout}, + options in 'options.pas' {frmOptions}, + select in 'select.pas' {frmSelect}; + +{$R *.RES} + +var + lang: string; + +begin + AddDomainForResourceString('delphi'); + lang := ReadProfile('Global:Language', ''); + if (lang <> '') then + UseLanguage(lang); +{$IFOPT D+} +// UseLanguage('fr'); // for testing +{$ENDIF} + + Application.Initialize; + Application.CreateForm(TfrmMain, frmMain); + Application.Run; +end. diff --git a/win32/gui-2/GPSBabelGUI.ico b/win32/gui-2/GPSBabelGUI.ico new file mode 100644 index 0000000000000000000000000000000000000000..76a19fd4f8255c3c2e0030659d9d33beef9973bc GIT binary patch literal 766 zcmcIiF%H5o47?(Sj!euQc?Lhjqo380p;8{vg(omXm@{cn9JL!bJ=@o_<3tM3aSg)> zZjS?SX1ovsaV0t&=>eg(Z9MIDk^== z(brrR-n7=kGZyS|FRkm94Pn1_9vj@&{Vek)X3sr76}#{0>`!K??oXB*o+4*Us85kk m*3>tgkIgc^2Qn zgrf(NeF!~x^Xg$^`&IW0%#7|$J5$qD-G5d6RoyK~G2&bh)YABVF5e#k6ZyS*{X#7V zjiba!3yBn#6MX(Y5{XYq5+?qrNTTE8V>XP0O)gCQ120?rbEIJ;+0JNYr>C~kBuz$( zwnmF~n#!DVyi5Zy%rF}M#d26K=f0NYGSxH@=PqhV z_q3qL$c&bm^HF>k_8KC^aoxWPdqt5JN0hy_I&t#1G*-*~7e}U1*R-m2{txs7ZNX<) z_xa|~ZG5i%fM%rd%r2eIcm1wp0Ymg`f$5V6uj)`e?Wm(|%`xw3i^v_l(mt4v9@Eq` zmEJ+7;b4qfvMOf4yir$e@b9U*jkV$IsoxPSMbmC&9Z)= zm!3x#K0Czi42kpHbKL~-4xgA9J&!&lMn{`?O=+wUdo9a(7PF}an1&{Gi@%+qbQO=t z*KKinL~6sjSdnM; zUACUbcQy61Yv<0(6BD&L~}ZS-B=VXI1d=+9|6 z<7gSJuDtJNg%hiu*Swz5jRrA~ki4fW#Mvj)Th8jR)Saroo? q-H7~78LJLC?5^0D_5U?rU(WvQmP*(B4G*2@;ANdI-lMVFx7u$`ace37 literal 0 HcmV?d00001 diff --git a/win32/gui-2/Makefile b/win32/gui-2/Makefile new file mode 100644 index 000000000..116e8dde7 --- /dev/null +++ b/win32/gui-2/Makefile @@ -0,0 +1,64 @@ +# +# requires: unix utilities +# GNU gettext +# + +DCC = dcc32.exe +RC = brcc32.exe + +SRC = delphi.pas gnugettext.pas gnugettextD4.pas gnugettextD5.pas \ + gnugettextDx.pas common.pas utils.pas \ + about.pas filter.pas options.pas main.pas select.pas + +FRM = about.dfm filter.dfm options.dfm main.dfm select.dfm + +LANG = \ + locale\de\LC_MESSAGES\delphi.mo \ + locale\de\LC_MESSAGES\default.mo \ + locale\de\LC_MESSAGES\gpsbabel.mo \ + locale\es\LC_MESSAGES\delphi.mo \ + locale\es\LC_MESSAGES\default.mo \ + locale\es\LC_MESSAGES\gpsbabel.mo \ + locale\fr\LC_MESSAGES\delphi.mo \ + locale\fr\LC_MESSAGES\default.mo \ + locale\fr\LC_MESSAGES\gpsbabel.mo \ + locale\hu\LC_MESSAGES\delphi.mo \ + locale\hu\LC_MESSAGES\default.mo \ + locale\hu\LC_MESSAGES\gpsbabel.mo + +.suffixes: .po + +.po.mo: + msgfmt -o $@ $< + +.rc.res: + $(RC) $< + +.dpr.exe: + $(DCC) $< + +default: GPSBabelGUI.exe + +GPSBabelGUI.exe: GPSBabelGUI.dpr GPSBabelGUI.res $(SRC) $(FRM) $(LANG) + $(DCC) GPSBabelGUI.dpr + assemble GPSBabelGUI.exe --dxgettext + +run: GPSBabelGUI.exe + xcopy /Y ..\..\gpsbabel.exe + xcopy /Y ..\..\mingw\libexpat.dll + xcopy /Y ..\..\gpsbabel.html + GPSBabelGUI.exe + +GPSBabelGUI.res: GPSBabelGUI.dof dof2rc.exe + dof2rc GPSBabelGUI + $(RC) GPSBabelGUI.rc + +clean: + rm -f *.~* *.??~ + rm -f *.bak *.dcu *.exe *.mo *.dll *.res *.rc + rm -f readme.html README readme.xml + rm -f locale\de\LC_MESSAGES\*.mo + rm -f locale\es\LC_MESSAGES\*.mo + rm -f locale\fr\LC_MESSAGES\*.mo + rm -f locale\hu\LC_MESSAGES\*.mo + diff --git a/win32/gui-2/README.gui b/win32/gui-2/README.gui new file mode 100644 index 000000000..220ac043f --- /dev/null +++ b/win32/gui-2/README.gui @@ -0,0 +1,70 @@ +* Adding your own language to GPSBabelGUI * +------------------------------------------- + +In first step you need an editor for .PO files. These files contains the +strings needed to be translated. The basic .po file for GPSBabelGUI is +default.po and should be located in your gui directory. The translation can be +done with any editor, but I suggest poedit (http://www.poedit.org/download.php). +poedit is the "must have" tool for doing such translations. + +If you have done the translation of the billions of messages from +the gui have to do the following: + +- Download and install the package dxgettext from "http://dybdahl.dk/dxgettext" +- Create a new folder below your gui directory in form + \locale\\LC_MESSAGES +- Replace with the shortcut for your language. +- The file "languagecodes.txt" from dxgettext is a good reference for + finding the valid shortcut. +- (1) Move your new default.po to folder LC_MESSAGE below . +- (2) Right-mouse-click on the .po file ... and you should see a new command + in your context menu "compile to mo file" ... doit. +- Borland Delphi uses a lot of internal strings, but you don't have to + translate them. On + "http://svn.berlios.de/wsvn/dxgettext/trunk/translations/" you will find + a lot of Delphi internal translations. For our gui you should download + "delphi.po" for Delphi5 and for +- Repeat steps (1) and (2) for delphi.po +- Start the gui and be happy. + +- That's all, but please please please, send us a copy of your translation. + A mail to gpsbabel-misc@lists.sourceforge.net with your translated + default.po will be implemented in the project (as fast as possible) and + will be available for many other users. + + +* Getting the source * +---------------------- + +There are two ways to get the source of the gui. One of them is source +release package you can download from SourceForge. Open "www.gpsbabel.org" +in your browser and go over "downloads" to the download list. The file you +need is called gpsbabel--.tar.gz. The gui source you will +find in the win32/gui-2 folder. + +The second way is to checkout the current development tree with CVS. +At SourceForge.net you will find the infos for working with cvs. +("http://sourceforge.net/cvs/?group_id=58972" for a short visit) + +To checkout the gpsbabel source tree the command line should look like this: + +cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/gpsbabel co gpsbabel + +This command will create a new folder in your working directory and +receive the complete source tree like the source tree but with all +changes made after the latest release. + +I generally encourage developers to work with the CVS tree instead of +the snapshots. + + +* Compiling from source * +------------------------- + +Currently the gui is developed under Delphi 4. Other releases of Delphi are +tested but are not used because of backward compatibility. If you want to help +us and Delphi is not in your software collection, "Delphi 6 Personal Edition" +would be the cheapest (or free) way. + + + diff --git a/win32/gui-2/about.dfm b/win32/gui-2/about.dfm new file mode 100644 index 0000000000000000000000000000000000000000..da7417a420d02497e7c9f9a6225fbeb2cb903f02 GIT binary patch literal 3505 zcmcgv&2QsG6rVUv>?BRL6#|LdAnjpSg3tw_1;JsHG}%T?>!|j!tU!XXGf7OGnaG|r zT`uHC{sg%2pCGNog~Lj{A|Xy(xNt#2;!t7U_$yA^6)V1+*qP^<_c`zV<|Qa2vvYFP zXzCA4w72th6(O_V*(;etZ`!cKWp(OI6MC_Z{N$ zk=i0N;c!+ggv{G5*P%=tP-iq2`44lIh<@k{#5jLbDYUrDJ+)-JO~E?ErrRCPM7=d8 zo==5(W53;LJm{Gpw+_- z*r1*>jQB%~E2w-(ANM_a>d-~0rn`fdM~R@i^hwkD+;^lKYHh|1+oP1VzzvwuS+q_C zS>7}nmvjcQ_W6RTV2C%3iE7_DqpshlUYFTp<&(0sG`6vdie{fM>S{9oCv%yJq1z!QdWFVT}HPhcVlzbFXg2yXbuSMqVqwTiA~ zJf+3-Dy7kCxms#j8fjU2wL+39S&!rh7CeiVOS9`&z_20jvOZvtS0XRC08fJ8_h->h zqwBk8%>(~=5S(ZE&x4Cg^!X+YEF0_3H|eLrrS+F+P`7FC#nVkXGmj!~SIgM`fAuFo zx!?~-g$sl}|1WQ;L+T2GpEhn;Q)$VDU=Y>Q>)CqB|B_2e_LZF4fV$_NUn!D_#Lfbl zKy|BRaw5?X#o(s`kc}OYt=@{xj`-ZCNBoqkyMPd(y7Uzo(vvlrckB>Yu#d1hIf%y=NF~#@$MhFyg{!?m;SMiwpf)22(`&ePgwce+m z54f0Bc{5h|!&+sEC0eRnjX6_cRo5~-fM%Bnh*3sh{)-s@ly?$vTKlk_@PHA1Dy!gH z4^DcajQp1ohJF+S+y_@>>?{_G`e^1`GKh8Vjh_G1DZ)wR>JeZ~DZ8eUxXDrou7e zI`%{@hlYpajZLqG@7Ft?>_Ek}T7336OrT82lsBJi58jo$o=iS`t92W{vA6fuYw&m* z>n<7MLzg-X-{N(vK9R$F*$~}MV+|%BagTP{kY_DO;(dHI-n$(*sPPn-umfC}h*TJ) zu+d4k4u`#k66dg@Uln!3;B(KWaLSHool$YAhW?k0tVA0bwk}%vAMI+zGz1ZjEjxp% zFZQW#drsItWkXwzH}}W1z;;VvH!y{KQZ+#$eE18vS=Z!7=T`D9-5y--g^gI4Q8ZonzxM(t^-+!b^hx3;xH^p{}Awe$s}-o8f`9q5Dy zYeS(sRL$mG2+nGjV8?XPBWyH>el^_oe1rq}?-N76MF|q@rb+r@V=!>o2oucc0=qH) zT1P&0DFxdXHg$!lD_fNHx!&Yp(=^Jx@EFNM<9(?YS8lFb@o4>8X-@j(2>3Ho0A2cF q #0) do + begin + if ((str^ < '0') or (str^ > '9')) then Break; + Result := (Result * 10) + (Ord(str^) - Ord('0')); + str := str + 1; + end; +end; + +function GetFileVersion(const Filename: string): string; +var + buff: PChar; + hdl: DWORD; + len: DWORD; + sub: PChar; + sublen: UINT; + fix: PVSFixedFileInfo; + i: Integer; +begin + Result := '?.?'; + + FillChar(CFixedFileinfo, SizeOf(CFixedFileinfo), #0); + + len := GetFileVersionInfoSize(PChar(Filename), hdl); + if not(len > 0) then exit; + + GetMem(buff, len); + try + + if not GetFileVersionInfo(PChar(FileName), 0, len, buff) then Exit; + + fix := Pointer(buff); + i := len - SizeOf(fix^); + while (i > 0) do + begin + Dec(i); + if (fix.dwSignature = $feef04bd) then + begin + CFixedFileinfo := fix^; + Break; + end; + PChar(fix) := PChar(fix) + 1; + end; + + if not VerQueryValue(buff, PChar('\\StringFileInfo\\040904E4\\FileVersion'), + Pointer(sub), sublen) then Exit; + if not(sublen > 0) then Exit; + Result := string(sub); + finally + FreeMem(buff); + end; +end; + +{ TOptions } + +constructor TOptions.Create(ACapabilities: TCapabilities); +begin + inherited Create; + FCaps := ACapabilities; + Sorted := False; +end; + +procedure TOptions.AddOptionLine(const ALine: string); +var + buff: array[0..1023] of Char; + cin, cend: PChar; + index: Integer; + opt, opt2: POption; + list: TStringList; + i: Integer; + s: string; +begin + StrPCopy(buff, ALine); + StrCat(buff, #9); + + cin := @buff; + index := 0; + while (true) do + begin + cend := StrScan(cin, #9); + if (cend = nil) then break; + cend^ := #0; + + case index of + 0: + if (StrIComp(cin, 'option') <> 0) then + Exit else + begin + New(opt); + FillChar(opt^, SizeOf(opt^), #0); + end; + 1: + opt.format := string(cin); + 2: + opt.name := string(cin); + 3: + opt.hint := string(cin); + 4: + for i := 0 to high(OTypes) do + if (StrIComp(cin, OTypes[i]) = 0) then + begin + opt.otype := i; + Break; + end; + 5: + if (cin^ <> #0) then + begin + opt.gbdef := StrNew(cin); + if (opt.def = nil) then + opt.def := opt.gbdef; + end; + 6: + if (cin^ <> #0) then + opt.min := StrNew(cin); + 7: + if (cin^ <> #0) then + opt.max := StrNew(cin); + end; + + index := index + 1; + cin := cend + 1; + end; + + if (opt.name = 'snlen') and (opt.gbdef = nil) then + begin + opt.gbdef := StrNew('10'); + opt.def := opt.gbdef; + end; + + opt.dir := 3; // in and out + opt.defname := opt.name; + + index := Self.IndexOf(opt.format); + if (index >= 0) then + list := TStringList(Self.Objects[index]) + else begin + list := TStringList.Create; + list.Sorted := True; + Self.AddObject(opt.format, list); + end; + list.AddObject(opt.name, Pointer(opt)); + if (opt.format = 'xcsv') then + begin + if (opt.name = 'style') then + begin + opt.dir := 1; + New(opt2); + opt2^ := opt^; + opt2.name := 'style_out'; + opt2.dir := 2; + list.AddObject(opt2.name, Pointer(opt2)); + end; + end; +end; + +procedure TOptions.DebugGetHints(List: TStringList); +var + i, j, k: Integer; + l: TStrings; + o: POption; +begin + List.Clear; + List.Sorted := True; + for i := 0 to Count - 1 do + begin + l := Pointer(Objects[i]); + for j := 0 to l.Count - 1 do + begin + o := Pointer(l.Objects[j]); + k := List.IndexOf(o.hint); + if (k < 0) then + List.Add(o.hint); + end; + end; +end; + +function TOptions.FormatOpts(const Descr: string): TStringList; +var + i: Integer; + s: string; +begin + s := FCaps.GetName(Descr); + if (s <> '') and Self.Find(s, i) then + Result := TStringList(Self.Objects[i]) + else + Result := nil; +end; + +function TOptions.GetList: TStrings; +begin + Result := Self; +end; + +function TOptions.HasFormatOpts(const Format: string): Boolean; +begin + Result := (FormatOpts(Format) <> nil); +end; + +procedure TOptions.SetList(const Value: TStrings); +var + i: Integer; +begin + Clear; + for i := 0 to Value.Count - 1 do + AddOptionLine(Value[i]); + Sorted := True; +end; + +{ TCapabilities } + +procedure TCapabilities.AddFormat(const Line: string); +var + index: Integer; + buff: array[0..1023] of Char; + cin, cend: PChar; + i: Integer; + scaps: string; + ext: string; + comment: string; + name: string; + internal: string; + caps: Integer; + info: PFileInfo; + +begin + StrPCopy(buff, Line); + StrCat(buff, #9); + + cin := @buff; + index := 0; + + while (true) do + begin + cend := StrScan(cin, #9); + if (cend = nil) then break; + cend^ := #0; + + case index of + 0: + if (StrIComp(cin, 'option') = 0) then + Exit + else + internal := StrPas(cin); + 1: + scaps := StrPas(cin); + 2: + name := StrPas(cin); + 3: + ext := StrPas(cin); + else + begin + comment := StrPas(cin); + if (Length(comment) = 0) or (Length(name) = 0) then break; + +// if (comment[1] = '?') then break; + + caps := 0; + for i := 1 to Length(scaps) do + if (scaps[i] <> '-') then caps := caps or (1 shl (i - 1)); + + New(info); + info.Descr := comment; + info.Ext := ext; + info.internal := internal; + info.Capas := caps; + + i := SELF.Add(name); + SELF.PutObject(i, Pointer(info)); + + if (name = 'garmin_txt') then + begin + gpsbabel_knows_inifile := True; + // add -p "" to command-line + end + else if (name = 'xcsv') then + info.internal := 'file'; + break; + end; + end; + + index := index + 1; + cin := cend + 1; + end; +end; + +function TCapabilities.CanReadAny(Index: Integer): Boolean; +var + caps: Integer; +begin + caps := PFileInfo(SELF.Objects[Index]).Capas; + Result := caps and (1 or 4 or 16) <> 0; +end; + +function TCapabilities.CanWriteAny(Index: Integer): Boolean; +var + caps: Integer; +begin + caps := PFileInfo(SELF.Objects[Index]).Capas; + Result := caps and (2 or 8 or 32) <> 0; +end; + +function TCapabilities.GetCaps(const Descr: string): Integer; +var + info: PFileInfo; + i: Integer; +begin + for i := 0 to Count - 1 do + begin + info := PFileInfo(Objects[i]); + if (AnsiCompareText(info.Descr, Descr) = 0) then + begin + Result := info.Capas; + Exit; + end; + end; + Result := 0; +end; + +function TCapabilities.GetDescr(Index: Integer): string; +var + info: PFileInfo; +begin + info := PFileInfo(Objects[Index]); + Result := info.Descr; +end; + +function TCapabilities.GetExt(const Descr: string): string; +var + i: Integer; + info: PFileInfo; +begin + for i := 0 to Count - 1 do + begin + info := PFileInfo(Objects[i]); + if (AnsiCompareText(info.Descr, Descr) = 0) then + begin + Result := info.Ext; + Exit; + end; + end; + Result := '.*'; +end; + +function TCapabilities.GetList: TStrings; +begin + Result := TStringList.Create; +end; + +function TCapabilities.GetName(const Descr: string): string; +var + i: Integer; + info: PFileInfo; +begin + for i := 0 to Count - 1 do + begin + info := PFileInfo(Objects[i]); + if (AnsiCompareText(info.Descr, Descr) = 0) then + begin + Result := SELF[i]; + Exit; + end; + end; + Result := 'unknown'; +end; + +function TCapabilities.IsDevice(Index: Integer): Boolean; +var + info: PFileInfo; +begin + info := PFileInfo(Objects[Index]); + Result := (AnsiCompareText(info.Internal, 'serial') = 0); +end; + +function TCapabilities.IsFile(Index: Integer): Boolean; +var + info: PFileInfo; + name: string; +begin + info := PFileInfo(Objects[Index]); + Result := (AnsiCompareText(info.Internal, 'file') = 0); +end; + +procedure TCapabilities.SetList(const Value: TStrings); +var + i: Integer; + s: string; +begin + Clear; + for i := 0 to Value.Count - 1 do + begin + s := Value.Strings[i]; + AddFormat(s); + end; +end; + +(* +function Open_gpsbabel_ini(): TInifile; +var + s: string; +begin + s := SysUtils.ExpandFileName(SGPSBabelIniFilename); + if not(SysUtils.FileExists(s)) then + s := SysUtils.ExtractFilePath(ParamStr(0)) + SGPSBabelIniFilename; + if not(SysUtils.FileExists(s)) then + Result := TIniFile.Create(SGPSBabelIniFilename) + else + Result := TIniFile.Create(s) +end; +*) + +initialization + + gpsbabel_exe := SysUtils.ExtractFilePath(ParamStr(0)) + SGPSBabelExeFilename; + SGPSBabelGUIVersion := GetFileVersion(ParamStr(0)); +//gpsbabel_ini := Open_gpsbabel_ini(); + +end. diff --git a/win32/gui-2/default.po b/win32/gui-2/default.po new file mode 100644 index 000000000..d3759d6d8 --- /dev/null +++ b/win32/gui-2/default.po @@ -0,0 +1,941 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2007-05-01 19:36\n" +"PO-Revision-Date: 2007-05-01 19:36\n" +"Last-Translator: Somebody \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2.1\n" + +#. frmAbout..Caption +#: about.dfm:5 +msgid "About" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbHint1..Caption +#: about.dfm:76 +msgid "This program is part of the GPSBabel project, hosted " +"on" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbVersion..Caption +#: about.dfm:84 +#: about.pas:80 +msgid "Version" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbTranslators..Caption +#: about.dfm:91 +msgid "Translations" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbURL..Caption +#: about.dfm:98 +msgid "www.gpsbabel.org" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbCopyRight..Caption +#: about.dfm:114 +msgid "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbMoreInfo..Caption +#: about.dfm:121 +msgid "Find more info at" +msgstr "" + +#. frmAbout..pnClient..pnCenter..stDescription..Caption +#: about.dfm:149 +msgid "The frontend for GPSBabel command line " +"program" +msgstr "" + +#. frmAbout..pnClient..pnCenter..stLicense..Caption +#: about.dfm:163 +msgid "THIS SOFTWARE MAY ONLY BE LICENSED FREE OF " +"CHARGE" +msgstr "" + +#. frmAbout..pnClient..pnCenter..btnNewLanguage..Caption +#: about.dfm:192 +msgid "Adding a new language" +msgstr "" + +#. frmFilter..Caption +#: filter.dfm:6 +msgid "Filter" +msgstr "" + +#. frmFilter..gbTracks..Caption +#: filter.dfm:31 +#. frmMain..pnBottom..cbTracks..Caption +#: main.dfm:581 +msgid "&Tracks" +msgstr "" + +#. frmFilter..gbTracks..lbTimePlusMinus..Caption +#: filter.dfm:39 +#: about.pas:87 +#: about.pas:88 +#: about.pas:89 +#: about.pas:90 +msgid "by" +msgstr "" + +#. frmFilter..gbTracks..lbTimeDays..Caption +#: filter.dfm:46 +msgid "day(s), " +msgstr "" + +#. frmFilter..gbTracks..lbTimeHours..Caption +#: filter.dfm:53 +msgid "hour(s), " +msgstr "" + +#. frmFilter..gbTracks..lbTimeMinutes..Caption +#: filter.dfm:60 +msgid "minute(s)," +msgstr "" + +#. frmFilter..gbTracks..lbTimeSeconds..Caption +#: filter.dfm:67 +msgid "second(s)" +msgstr "" + +#. frmFilter..gbTracks..cbTrackTitle..Hint +#: filter.dfm:74 +msgid "Title for new tracks" +msgstr "" + +#. frmFilter..gbTracks..cbTrackTitle..Caption +#: filter.dfm:76 +msgid "Tit&le" +msgstr "" + +#. frmFilter..gbTracks..cbTrackSplit..Hint +#: filter.dfm:95 +msgid "Split track into several tracks depending on date of " +"trackpoint" +msgstr "" + +#. frmFilter..gbTracks..cbTrackSplit..Caption +#: filter.dfm:96 +msgid "&Split" +msgstr "" + +#. frmFilter..gbTracks..cbTrackTime..Hint +#: filter.dfm:104 +msgid "Shift all tracks" +msgstr "" + +#. frmFilter..gbTracks..cbTrackTime..Caption +#: filter.dfm:105 +msgid "&Move" +msgstr "" + +#. frmFilter..gbTracks..cbTrackStart..Hint +#: filter.dfm:197 +msgid "Take only trackpoints starting at" +msgstr "" + +#. frmFilter..gbTracks..cbTrackStart..Caption +#: filter.dfm:198 +msgid "Start at" +msgstr "" + +#. frmFilter..gbTracks..cbTrackStop..Caption +#: filter.dfm:237 +msgid "stop at" +msgstr "" + +#. frmFilter..gbTracks..cbTrackPack..Hint +#: filter.dfm:276 +msgid "Pack all tracks into one track (No duplicate " +"timestamps)" +msgstr "" + +#. frmFilter..gbTracks..cbTrackPack..Caption +#: filter.dfm:277 +msgid "&Pack (or)" +msgstr "" + +#. frmFilter..gbTracks..cbTrackMerge..Hint +#: filter.dfm:286 +msgid "Merge all tracks into one track" +msgstr "" + +#. frmFilter..gbTracks..cbTrackMerge..Caption +#: filter.dfm:287 +msgid "Merge" +msgstr "" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Hint +#: filter.dfm:296 +msgid "Shift start/stop by local timezone offset" +msgstr "" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Caption +#: filter.dfm:297 +msgid "TZ" +msgstr "" + +#. frmFilter..gbTracks..cbGPSfix..Hint +#: filter.dfm:306 +msgid "Synthesize GPS fixes (PPS, DGPS, 3D, " +"2D)" +msgstr "" + +#. frmFilter..gbTracks..cbGPSfix..Caption +#: filter.dfm:307 +msgid "GPS fixes" +msgstr "" + +#. frmFilter..gbTracks..cbTrackCourse..Hint +#: filter.dfm:316 +msgid "Synthesize course values" +msgstr "" + +#. frmFilter..gbTracks..cbTrackCourse..Caption +#: filter.dfm:317 +msgid "Course" +msgstr "" + +#. frmFilter..gbTracks..cbTrackSpeed..Hint +#: filter.dfm:325 +msgid "Synthesize speed values" +msgstr "" + +#. frmFilter..gbTracks..cbTrackSpeed..Caption +#: filter.dfm:326 +msgid "Speed" +msgstr "" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:338 +msgid "none" +msgstr "" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:339 +msgid "pps" +msgstr "" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:340 +msgid "dgps" +msgstr "" + +#. frmFilter..gbRoutes..Caption +#: filter.dfm:352 +msgid "&Routes && Tracks" +msgstr "" + +#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption +#: filter.dfm:360 +msgid "limit to" +msgstr "" + +#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption +#: filter.dfm:368 +msgid "Points" +msgstr "" + +#. frmFilter..gbRoutes..cbRouteSimplify..Hint +#: filter.dfm:375 +msgid "Simplify routes and tracks by limited number of " +"points" +msgstr "" + +#. frmFilter..gbRoutes..cbRouteSimplify..Caption +#: filter.dfm:376 +msgid "Simplify" +msgstr "" + +#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint +#: filter.dfm:385 +msgid "Upper limit of points for routes and " +"tracks" +msgstr "" + +#. frmFilter..gbRoutes..cbReverse..Hint +#: filter.dfm:407 +msgid "Reverse routes and tracks" +msgstr "" + +#. frmFilter..gbRoutes..cbReverse..Caption +#: filter.dfm:408 +msgid "Reverse" +msgstr "" + +#. frmFilter..pnBottom..btnOK..Caption +#: filter.dfm:425 +msgid "OK" +msgstr "" + +#. frmFilter..pnBottom..BitBtn1..Caption +#: filter.dfm:461 +msgid "File based filters" +msgstr "" + +#. frmFilter..gbWaypoints..Caption +#: filter.dfm:490 +#. frmMain..pnBottom..cbWaypoints..Caption +#: main.dfm:555 +msgid "&Waypoints" +msgstr "" + +#. frmFilter..gbWaypoints..lbWayptRadiusLat..Caption +#: filter.dfm:499 +msgid "Latitude" +msgstr "" + +#. frmFilter..gbWaypoints..lbWayptRadiusLon..Caption +#: filter.dfm:507 +msgid "Longitude" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint +#: filter.dfm:515 +msgid "Merge waypoints with duplicate locations" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption +#: filter.dfm:516 +msgid "locations" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint +#: filter.dfm:525 +msgid "Merge waypoints with duplicate \"short " +"name\"" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption +#: filter.dfm:526 +msgid "\"short names\"" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint +#: filter.dfm:535 +msgid "Merge waypoints separated by less then" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption +#: filter.dfm:536 +msgid "Position" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptSort..Hint +#: filter.dfm:564 +msgid "Sort waypoints by \"short name\" or by " +"description" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptSort..Caption +#: filter.dfm:565 +msgid "Sort" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint +#: filter.dfm:573 +msgid "Merge duplicate waypoints" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption +#: filter.dfm:574 +msgid "Duplicates" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptRadius..Hint +#: filter.dfm:583 +msgid "Include points based on their proximity to central " +"point" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptRadius..Caption +#: filter.dfm:584 +msgid "Radius" +msgstr "" + +#. frmFilter..gbWaypoints..edWayptRadiusLat..Hint +#: filter.dfm:612 +msgid "Latitude of central point" +msgstr "" + +#. frmFilter..gbWaypoints..edWayptRadiusLon..Hint +#: filter.dfm:622 +msgid "Longitude of central point" +msgstr "" + +#. frmFilter..gbTransform..Caption +#: filter.dfm:634 +msgid "Transformation" +msgstr "" + +#. frmFilter..gbTransform..cbTransform..Caption +#: filter.dfm:651 +msgid "Transform" +msgstr "" + +#. frmFilter..gbTransform..cbTransformDelete..Hint +#: filter.dfm:660 +msgid "Delete source data after transformation" +msgstr "" + +#. frmFilter..gbTransform..cbTransformDelete..Caption +#: filter.dfm:661 +msgid "Delete" +msgstr "" + +#. frmMain..pnTop..gbInput..Caption +#: main.dfm:38 +#: main.pas:270 +#: main.pas:275 +#: main.pas:467 +#: main.pas:868 +msgid "Input" +msgstr "" + +#. frmMain..pnTop..gbInput..sbOpenFile..Hint +#: main.dfm:45 +msgid "Start the file open dialog" +msgstr "" + +#. frmMain..pnTop..gbInput..lbInputOpts..Caption +#: main.dfm:68 +#. frmMain..pnTop..gbOutput..lbOutputOpts..Caption +#: main.dfm:229 +#. frmMain..ActionList1..acOptionsSourceFormat..Category +#: main.dfm:1418 +#. frmMain..ActionList1..acOptionsTargetFormat..Category +#: main.dfm:1423 +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Category +#: main.dfm:1437 +msgid "Options" +msgstr "" + +#. frmMain..pnTop..gbInput..lbInputFormat..Caption +#: main.dfm:76 +#. frmMain..pnTop..gbOutput..lbOutputFormat..Caption +#: main.dfm:259 +msgid "Format" +msgstr "" + +#. frmMain..pnTop..gbInput..lbInputFile..Caption +#: main.dfm:83 +#. frmMain..pnTop..gbOutput..lbOutputFile..Caption +#: main.dfm:266 +#. frmMain..ActionList1..acFileExit..Category +#: main.dfm:1399 +#. frmMain..ActionList1..acFileClearMemo..Category +#: main.dfm:1428 +#. frmMain..ActionList1..acFileOutputToScreen..Category +#: main.dfm:1443 +#. frmMain..ActionList1..acFileChangeLanguage..Category +#: main.dfm:1455 +#. frmMain..ActionList1..acFileExportCSV..Category +#: main.dfm:1460 +#: main.pas:865 +#: main.pas:919 +msgid "File" +msgstr "" + +#. frmMain..pnTop..gbInput..chbInputDevice..Hint +#: main.dfm:112 +msgid "Read data from device instead from file" +msgstr "" + +#. frmMain..pnTop..gbInput..chbInputDevice..Caption +#: main.dfm:115 +#. frmMain..pnTop..gbOutput..chbOutputDevice..Caption +#: main.dfm:299 +msgid "Device" +msgstr "" + +#. frmMain..pnTop..gbInput..edInputOpts..Hint +#: main.dfm:124 +msgid "Options for the selected input format" +msgstr "" + +#. frmMain..pnTop..gbInput..edInputFile..Hint +#: main.dfm:135 +msgid "Read data from given filename" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputLang..Hint +#: main.dfm:146 +msgid "Characterset for input data" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:152 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:363 +msgid "- default -" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputDevice..Hint +#: main.dfm:179 +msgid "Read data from device ..." +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputFormatDevice..Hint +#: main.dfm:194 +msgid "Format for input from device" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputFormat..Hint +#: main.dfm:208 +msgid "Format for input from file" +msgstr "" + +#. frmMain..pnTop..gbOutput..Caption +#: main.dfm:222 +#: main.pas:271 +#: main.pas:276 +#: main.pas:476 +#: main.pas:922 +msgid "Output" +msgstr "" + +#. frmMain..pnTop..gbOutput..sbSaveFile..Hint +#: main.dfm:273 +msgid "Start the file save dialog" +msgstr "" + +#. frmMain..pnTop..gbOutput..chbOutputDevice..Hint +#: main.dfm:296 +msgid "Write data to device instead to file" +msgstr "" + +#. frmMain..pnTop..gbOutput..cbOutputFormatDevice..Hint +#: main.dfm:309 +msgid "Format for ouput to device" +msgstr "" + +#. frmMain..pnTop..gbOutput..edOutputOpts..Hint +#: main.dfm:321 +msgid "Options for the selected output format" +msgstr "" + +#. frmMain..pnTop..gbOutput..cbOutputFormat..Hint +#: main.dfm:332 +msgid "Format for output to file" +msgstr "" + +#. frmMain..pnTop..gbOutput..edOutputFile..Hint +#: main.dfm:345 +msgid "Write data to given filename" +msgstr "" + +#. frmMain..pnTop..gbOutput..cbOutputLang..Hint +#: main.dfm:357 +msgid "Characterset for output data" +msgstr "" + +#. frmMain..pnTop..gbOutput..cbOutputDevice..Hint +#: main.dfm:390 +msgid "Write data to device ..." +msgstr "" + +#. frmMain..pnBottom..lbWhat..Caption +#: main.dfm:415 +msgid "What ?" +msgstr "" + +#. frmMain..pnBottom..cbWaypoints..Hint +#: main.dfm:554 +msgid "Process waypoint information" +msgstr "" + +#. frmMain..pnBottom..cbRoutes..Hint +#: main.dfm:568 +msgid "Process route information" +msgstr "" + +#. frmMain..pnBottom..cbRoutes..Caption +#: main.dfm:569 +msgid "&Routes" +msgstr "" + +#. frmMain..pnBottom..cbTracks..Hint +#: main.dfm:580 +msgid "Process track information" +msgstr "" + +#. frmMain..pnBottom..btnFilter..Caption +#: main.dfm:594 +#. frmMain..ActionList1..acFilterSelect..Caption +#: main.dfm:1393 +msgid "&Filter" +msgstr "" + +#. frmMain..pnBottom..btnProcess..Hint +#: main.dfm:638 +msgid "Start data conversion" +msgstr "" + +#. frmMain..pnBottom..btnProcess..Caption +#: main.dfm:641 +#. frmMain..ActionList1..acConvert..Caption +#: main.dfm:1386 +msgid "let's go" +msgstr "" + +#. frmMain..OpenDialog..Filter +#: main.dfm:701 +msgid "Garmin Mapsource mps|*.mps|All files|*.*" +msgstr "" + +#. frmMain..SaveDialog..Filter +#: main.dfm:707 +msgid "All file(s)|*.*|Garmin MapSource mps|*.mps" +msgstr "" + +#. frmMain..ActionList1..acConvert..Category +#: main.dfm:1385 +#. frmMain..ActionList1..acFilterSelect..Category +#: main.dfm:1392 +msgid "Babel" +msgstr "" + +#. frmMain..ActionList1..acFilterSelect..Hint +#: main.dfm:1394 +msgid "Filter incomming data before writing them to file or " +"device" +msgstr "" + +#. frmMain..ActionList1..acFileExit..Caption +#: main.dfm:1400 +msgid "E&xit" +msgstr "" + +#. frmMain..ActionList1..acHelpAbout..Category +#: main.dfm:1404 +#. frmMain..ActionList1..acHelpIntro..Category +#: main.dfm:1409 +#. frmMain..ActionList1..acHelpReadme..Category +#: main.dfm:1413 +msgid "Help" +msgstr "" + +#. frmMain..ActionList1..acHelpAbout..Caption +#: main.dfm:1405 +msgid "&About" +msgstr "" + +#. frmMain..ActionList1..acHelpIntro..Caption +#: main.dfm:1410 +msgid "&Intro" +msgstr "" + +#. frmMain..ActionList1..acHelpReadme..Caption +#: main.dfm:1414 +#. frmReadme..Caption +#: readme.dfm:6 +msgid "GPSBabel README" +msgstr "" + +#. frmMain..ActionList1..acOptionsSourceFormat..Caption +#: main.dfm:1419 +msgid "... for source format" +msgstr "" + +#. frmMain..ActionList1..acOptionsTargetFormat..Caption +#: main.dfm:1424 +msgid "... for target format" +msgstr "" + +#. frmMain..ActionList1..acFileClearMemo..Caption +#: main.dfm:1429 +msgid "Clear output" +msgstr "" + +#. frmMain..ActionList1..acFileClearMemo..Hint +#: main.dfm:1430 +msgid "Clear messages" +msgstr "" + +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Caption +#: main.dfm:1438 +msgid "Enable characterset transformation" +msgstr "" + +#. frmMain..ActionList1..acFileOutputToScreen..Caption +#: main.dfm:1444 +msgid "Output to screen" +msgstr "" + +#. frmMain..ActionList1..acFileChangeLanguage..Caption +#: main.dfm:1456 +msgid "Change language" +msgstr "" + +#. frmMain..ActionList1..acFileExportCSV..Caption +#: main.dfm:1461 +msgid "Export gpsbabel.csv (unicode)" +msgstr "" + +#. frmMain..MainMenu1..mnuFile..Caption +#: main.dfm:1469 +msgid "&File" +msgstr "" + +#. frmMain..MainMenu1..mnuFile..File1..Caption +#: main.dfm:1477 +msgid "Export" +msgstr "" + +#. frmMain..MainMenu1..mnuOptions..Caption +#: main.dfm:1498 +msgid "&Options" +msgstr "" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames..Caption +#: main.dfm:1500 +msgid "Synthesize shortnames" +msgstr "" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames....Hint +#: main.dfm:1503 +msgid "Ignore shortnames from source data and synthesize them from " +"description or notes" +msgstr "" + +#. frmMain..MainMenu1..mnuOptions..mnuOptionsForceDataType..Caption +#: main.dfm:1507 +msgid "Force selected GPS data types (nuketypes " +"filter)" +msgstr "" + +#. frmMain..MainMenu1..mnuHelp..Caption +#: main.dfm:1548 +msgid "&Help" +msgstr "" + +#. frmOptions..Caption +#: options.dfm:5 +msgid "Options for ..." +msgstr "" + +#. frmSelect..pnBottom..btnCancel..Caption +#: select.dfm:66 +msgid "Abort" +msgstr "" + +#: about.pas:87 +#: select.pas:81 +msgid "German" +msgstr "" + +#: about.pas:88 +#: select.pas:83 +msgid "French" +msgstr "" + +#: about.pas:89 +#: select.pas:82 +msgid "Spanish" +msgstr "" + +#: about.pas:90 +#: select.pas:85 +msgid "Hungarian" +msgstr "" + +#: about.pas:132 +msgid "Please have a look at the file README.GUI.\n" +"\nThere you will find all information you need to\n" +"get GPSBabelGUI working in your own " +"language." +msgstr "" + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:184 +#: filter.pas:185 +msgid "Waypoints" +msgstr "" + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:182 +#: filter.pas:183 +msgid "Routes" +msgstr "" + +#: filter.pas:182 +#: filter.pas:183 +#: filter.pas:184 +#: filter.pas:185 +msgid "Tracks" +msgstr "" + +#: filter.pas:224 +msgid "Feet" +msgstr "" + +#: filter.pas:225 +msgid "Meter" +msgstr "" + +#: filter.pas:228 +msgid "Miles" +msgstr "" + +#: filter.pas:229 +msgid "Kilometer" +msgstr "" + +#: filter.pas:239 +msgid "Not supported by gpsbabel.exe, release " +"%s!" +msgstr "" + +#: filter.pas:288 +msgid "Value (%s) out of range (%g to %g)!" +msgstr "" + +#: filter.pas:593 +#: options.pas:661 +msgid "Discard changes?" +msgstr "" + +#: main.pas:244 +msgid "Internal development release" +msgstr "" + +#: main.pas:246 +msgid "BETA" +msgstr "" + +#: main.pas:248 +msgid "Private release" +msgstr "" + +#: main.pas:250 +msgid "Special release" +msgstr "" + +#: main.pas:342 +msgid "The file \"gpsbabel.exe\" found in current directory is too " +"old!" +msgstr "" + +#: main.pas:416 +#: main.pas:550 +msgid "All files|*.*" +msgstr "" + +#: main.pas:484 +msgid "Select and edit options for \"%s\"" +msgstr "" + +#: main.pas:488 +msgid "No options available for \"%s\"" +msgstr "" + +#. s := s + '-1'; +#: main.pas:603 +msgid "File %s not found." +msgstr "" + +#: main.pas:664 +msgid "File \"%s\" exists ! Overwrite ?" +msgstr "" + +#: main.pas:665 +msgid "Warning" +msgstr "" + +#: main.pas:698 +msgid "Could not run \"gpsbabel.exe\"!" +msgstr "" + +#: main.pas:707 +msgid "Sorry, gpsbabel.exe reported problems!" +msgstr "" + +#: main.pas:709 +msgid "Converted successfully from \"%s\" to " +"\"%s\"." +msgstr "" + +#: main.pas:820 +msgid "GPSBabel, version %s" +msgstr "" + +#: main.pas:854 +#: main.pas:909 +msgid "Port" +msgstr "" + +#: main.pas:1013 +msgid "Options for \"%s\"" +msgstr "" + +#: main.pas:1203 +#: main.pas:1273 +msgid "Choose language" +msgstr "" + +#: main.pas:1203 +msgid "for GUIBabelGUI" +msgstr "" + +#: main.pas:1273 +msgid "for export" +msgstr "" + +#. override; +#: options.pas:147 +msgid "Be aware, that most options are made for the output side. " +msgstr "" + +#: options.pas:148 +msgid "Currently we don't have a flag which tells us which direction is used " +"by the options." +msgstr "" + +#: options.pas:208 +msgid "Short \"%s\"" +msgstr "" + +#: options.pas:332 +msgid "Invalid line format!" +msgstr "" + +#: options.pas:353 +msgid "Unknown option \"%s\"!" +msgstr "" + +#: select.pas:84 +msgid "English" +msgstr "" + +#: utils.pas:119 +msgid "Error WINAPI: Could not create \"NamedPipe\"!" +msgstr "" + +#: utils.pas:124 +msgid "\"gpsbabel.exe\" not found!!!" +msgstr "" + +#. dwCreationFlags, // creation flags +#: utils.pas:143 +msgid "Could not run \"gpsbabel.exe\" (Error " +"%d)!" +msgstr "" + +#: utils.pas:176 +msgid "\"gpsbabel.exe\" returned error 0x%x (%d)" +msgstr "" + diff --git a/win32/gui-2/delphi.pas b/win32/gui-2/delphi.pas new file mode 100644 index 000000000..c9c5261c5 --- /dev/null +++ b/win32/gui-2/delphi.pas @@ -0,0 +1,93 @@ +unit delphi; + +// Delpi compatibility unit // + +interface + +uses + SysUtils, TypInfo; + +{$IFDEF VER120} +function GetPropInfo(Instance: TObject; const PropertyName: string): PPropInfo; overload; +function GetPropInfo(Instance: TObject; const Name: string; var PropInfo: TPropInfo): Boolean; overload; +function GetObjectProp(Instance: TObject; Info: PPropInfo): TObject; +function GetStrProp(Instance: TObject; const Name: string): string; overload; +function GetStrProp(Instance: TObject; Info: PPropInfo): string; overload; +procedure SetStrProp(Instance: TObject; const Name, Value: string); overload; +procedure SetStrProp(Instance: TObject; Info: PPropInfo; const Value: string); overload; +{$ENDIF} + +implementation + +{$IFDEF VER120} +function GetPropInfo(Instance: TObject; const PropertyName: string): PPropInfo; +begin + Result := TypInfo.GetPropInfo(Instance.ClassInfo, PropertyName); +end; + +function GetObjectProp(Instance: TObject; Info: PPropInfo): TObject; +begin + Result := Pointer(TypInfo.GetOrdProp(Instance, Info)); +end; + +function GetPropInfo(Instance: TObject; const Name: string; var PropInfo: TPropInfo): Boolean; +var + Props: PPropList; + TypeData: PTypeData; + Info: PPropInfo; + i: Integer; +begin + TypeData := GetTypeData(Instance.ClassInfo); + if ((TypeData <> nil) and (TypeData.PropCount > 0)) then + begin + GetMem(Props, TypeData.PropCount * SizeOf(Pointer)); + try + GetPropInfos(Instance.ClassInfo, Props); + for i := 0 to TypeData.PropCount - 1 do + begin + Info := Props[i]; + if (CompareText(Info.Name, Name) = 0) then + begin + PropInfo := Info^; + Result := True; + Exit; + end + end; + finally + FreeMem(Props); + end; + end; + Result := False; +end; + +function GetStrProp(Instance: TObject; Info: PPropInfo): string; +begin + Result := TypInfo.GetStrProp(Instance, Info); +end; + +function GetStrProp(Instance: TObject; const Name: string): string; +var + Info: TPropInfo; +begin + if GetPropInfo(Instance, Name, Info) then + Result := TypInfo.GetStrProp(Instance, @Info) + else + Result := ''; +end; + +procedure SetStrProp(Instance: TObject; const Name, Value: string); +var + Info: TPropInfo; +begin + if GetPropInfo(Instance, Name, Info) then + SetStrProp(Instance, @Info, Value); +end; + +procedure SetStrProp(Instance: TObject; Info: PPropInfo; const Value: string); +begin + TypInfo.SetStrProp(Instance, Info, Value); +end; + +{$ENDIF} + +end. diff --git a/win32/gui-2/dof2rc.dpr b/win32/gui-2/dof2rc.dpr new file mode 100644 index 000000000..feb557c21 --- /dev/null +++ b/win32/gui-2/dof2rc.dpr @@ -0,0 +1,108 @@ +program DOF2RC; +uses + Windows, SysUtils, Inifiles; + +var + Ini: TInifile; + IFName: string; + OFName: string; + OFile: Text; + s: string; + i: Integer; + + procedure WriteValue(const Key: string); + var + s: string; + begin + s := Ini.ReadString('Version Info Keys', Key, ''); + WriteLn(OFile, #9#9'VALUE "', Key, '", "', s, '\0"'); + end; + +begin + IFName := ChangeFileExt(ExpandFileName(ParamStr(1)), '.dof'); + Ini := TIniFile.Create(IFName); + try + OFName := SysUtils.ChangeFileExt(Ini.FileName, '.rc'); + if not Ini.SectionExists('Compiler') then + begin + WriteLn('Invalid DOF!'); + Halt(1); + end; + + System.Assign(OFile, OFName); +{$I-} + System.Rewrite(OFile); +{$I+} + if (IOResult <> 0) then + begin + Halt(1); + end; + try + s := SysUtils.ExtractFileName(Ini.FileName); + s := SysUtils.ChangeFileExt(s, '.ico'); + + System.WriteLn(OFile, 'MAINICON ICON "', s, '"'); + System.WriteLn(OFile); + + if not Ini.SectionExists('Version Info') then Exit; + + WriteLn(OFile, '1 VERSIONINFO'); + s := Ini.ReadString('Version Info', 'MajorVer', '0') + ',' + + Ini.ReadString('Version Info', 'MinorVer', '0') + ',' + + Ini.ReadString('Version Info', 'Release', '0') + ',' + + Ini.ReadString('Version Info', 'Build', '0'); + WriteLn(OFile, 'FILEVERSION ', s); + WriteLn(OFile, 'PRODUCTVERSION ', s); + WriteLn(OFile, 'FILEOS 0x4'); + WriteLn(OFile, 'FILETYPE 0x1'); + WriteLn(OFile, 'FILESUBTYPE 0x0L'); + WriteLn(OFile, 'FILEFLAGSMASK 0x3fL'); + + i := 0; + if (Ini.ReadInteger('Version Info', 'Debug', 0) <> 0) then i := 1; + if (Ini.ReadInteger('Version Info', 'PreRelease', 0) <> 0) then i := (i or 2); + if (Ini.ReadInteger('Version Info', 'Special', 0) <> 0) then i := (i or $20); + if (Ini.ReadInteger('Version Info', 'Private', 0) <> 0) then i := (i or 8); + if (i <> 0) then + WriteLn(OFile, 'FILEFLAGS ', SysUtils.Format('0x%2.2x', [i])); + + WriteLn(OFile, '{'); + WriteLn(OFile, 'BLOCK "StringFileInfo"'); + WriteLn(OFile, '{'); + + if ini.SectionExists('Version Info Keys') then + begin + WriteLn(OFile, #9'BLOCK "040904E4"'); + WriteLn(OFile, #9'{'); + WriteValue('CompanyName'); + WriteValue('FileDescription'); + WriteValue('FileVersion'); + WriteValue('InternalName'); + WriteValue('LegalCopyright'); + WriteValue('LegalTrademarks'); + WriteValue('OriginalFilename'); + WriteValue('ProductName'); + WriteValue('ProductVersion'); + WriteValue('Comments'); + WriteLn(OFile, #9'}'); + end; + WriteLn(OFile, '}'); + + WriteLn(OFile, 'BLOCK "VarFileInfo"'); + WriteLn(OFile, '{'); + WriteLn(OFile, #9'VALUE "Translation", ', + SysUtils.Format('0x%4.4x 0x%4.4x', [ + Ini.ReadInteger('Version Info', 'Locale', 1033), + Ini.ReadInteger('Version Info', 'CodePage', 1252)])); + WriteLn(OFile, '}'); + WriteLn(OFile, '}'); + + + finally + System.Close(OFile); + end; + finally + ini.Free; + end; +end. + diff --git a/win32/gui-2/filter.dfm b/win32/gui-2/filter.dfm new file mode 100644 index 0000000000000000000000000000000000000000..a6a38a91c4e2e4b4571612a63d2835ce0f867d3b GIT binary patch literal 8971 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 ' + _('Routes')); + cobTransformType.Items.Add(_('Routes') + ' -> ' + _('Waypoints')); + cobTransformType.Items.Add(_('Routes') + ' -> ' + _('Tracks')); + cobTransformType.Items.Add(_('Tracks') + ' -> ' + _('Routes')); + cobTransformType.Items.Add(_('Waypoints') + ' -> ' + _('Tracks')); + cobTransformType.Items.Add(_('Tracks') + ' -> ' + _('Waypoints')); + cobTransformType.ItemIndex := 0; + + CurrentTime := SysUtils.Now; + dtpTrackStartDate.DateTime := Int(CurrentTime); + dtpTrackStopDate.DateTime := Int(CurrentTime); + + lTrackTimeList := TList.Create; + + lTrackTimeList.Add(edTrackTimeDays); + lTrackTimeList.Add(edTrackTimeHours); + lTrackTimeList.Add(edTrackTimeMinutes); + lTrackTimeList.Add(edTrackTimeSeconds); + + EnableList(lTrackTimeList, False); + + FixPosition(edTrackTimeDays, lbTimePlusMinus, True); + FixPosition(udTimeDays, edTrackTimeDays, False); + FixPosition(lbTimeDays, udTimeDays, True); + + FixPosition(edTrackTimeHours, lbTimeDays, True); + FixPosition(udTimeHours, edTrackTimeHours, False); + FixPosition(lbTimeHours, udTimeHours, True); + + FixPosition(edTrackTimeMinutes, lbTimeHours, True); + FixPosition(udTimeMinutes, edTrackTimeMinutes, False); + FixPosition(lbTimeMinutes, udTimeMinutes, True); + + FixPosition(edTrackTimeSeconds, lbTimeMinutes, True); + FixPosition(udTimeSeconds, edTrackTimeSeconds, False); + FixPosition(lbTimeSeconds, udTimeSeconds, True); + + FixPosition(lbWayptRadiusLat, cobWayptRadiusUnit, True); + FixPosition(edWayptRadiusLat, lbWayptRadiusLat, True); + FixPosition(lbWayptRadiusLon, edWayptRadiusLat, True); + FixPosition(edWayptRadiusLon, lbWayptRadiusLon, True); + + // will not be translated, fill by hand + + cobWayptMergeDistUnit.Items.Add(_('Feet')); + cobWayptMergeDistUnit.Items.Add(_('Meter')); + cobWayptMergeDistUnit.ItemIndex := 0; + + cobWayptRadiusUnit.Items.Add(_('Miles')); + cobWayptRadiusUnit.Items.Add(_('Kilometer')); + cobWayptRadiusUnit.ItemIndex := 0; + + dtpTrackStopTime.Time := 1 - (1.0 / (24*60*60)); + + // Enable/Disable depending on gpsbabel.exe version + + if (common.gpsbabel_vfmt < '001.002.007') then + begin + EnableAll(gbTracks, False); + gbTracks.Hint := Format(_('Not supported by gpsbabel.exe, release %s!'), [ + gpsbabel_version]); + gbTracks.ShowHint := True; + end; + + if not(gpsbabel_knows_inifile) then + begin + cbGPSfix.Enabled := False; + cbTrackCourse.Enabled := False; + cbTrackSpeed.Enabled := False; + cobGPSfixes.Enabled := False; + end; + + LoadSettingsFromRegistry(); + + gbTransform.Enabled := (common.gpsbabel_vfmt >= '001.003.002'); + EnableAll(gbTransform, gbTransform.Enabled); + + cobTransformType.Enabled := cbTransform.Checked; + cbTransformDelete.Enabled := cbTransform.Checked; +end; + +function TfrmFilter.ValidateNumerical(AEdit: TCustomEdit; AMin, AMax: Extended): Boolean; +var + s: string; + v: Extended; +begin + Result := True; + if not(AEdit.Enabled) then Exit; + if (ModalResult <> mrOK) then Exit; + + Result := False; + s := Trim(AEdit.Text); + if (s = '') then s := '0'; + while (Pos(',', s) <> 0) do + s[Pos(',', s)] := '.'; + + AEdit.Text := s; + + try + v := SysUtils.StrToFloat(s); + except + on E: EConvertError do + begin + AEdit.SetFocus; + raise; + end; + end; + + if (v < AMin) or (v > AMax) then + begin + AEdit.SetFocus; + raise eOutOfRange.CreateFmt(_('Value (%s) out of range (%g to %g)!'), + [s, AMin, AMax]); + end; + Result := True; +end; + +procedure TfrmFilter.cbTrackTimeClick(Sender: TObject); +begin + EnableList(lTrackTimeList, cbTrackTime.Checked); +end; + +procedure TfrmFilter.EnableList(List: TList; Enable: Boolean); +var + i: Integer; + o: TObject; +begin + for i := 0 to List.Count - 1 do + begin + o := Pointer(List.Items[i]); + if (o is TControl) then + with o as TControl do + Enabled := Enable; + end; +end; + +procedure TfrmFilter.cbTrackTitleClick(Sender: TObject); +begin + edTrackTitleValue.Enabled := cbTrackTitle.Checked; +end; + +function TfrmFilter.CmdLine: string; + + procedure SimpleOption(var CmdLine: string; CheckBox: TCheckBox; const Option: string); + begin + if (CheckBox.Checked) then + CmdLine := Format('%s -x %s', [CmdLine, Option]); + end; + +var + s: string; + tz_Info: TTimeZoneInformation; + dt: TDateTime; + dt_bias: TDateTime; +begin + Result := ''; + if not AnyChecked(Self) then Exit; + + Result := ''; + + if gbTransform.Enabled and cbTransform.Checked then + begin + Result := Format('%s -x %s', [Result, 'transform,']); + case cobTransformType.ItemIndex of + 0: Result := Result + 'rte=wpt'; + 1: Result := Result + 'wpt=rte'; + 2: Result := Result + 'trk=rte'; + 3: Result := Result + 'rte=trk'; + 4: Result := Result + 'trk=wpt'; + 5: Result := Result + 'wpt=trk'; + end; + if cbTransformDelete.Checked then + Result := Result + ',del=y' else + Result := Result + ',del=n'; + end; + if AnyChecked(gbWaypoints) then + begin + if cbWayptMergeDups.Checked and + (cbWayptMergeDupNames.Checked or cbWayptMergeDupLoc.Checked) then + begin + Result := Format('%s -x %s', [Result, 'duplicate']); + if cbWayptMergeDupNames.Checked then + Result := Format('%s,%s', [Result, 'shortname']); + if cbWayptMergeDupLoc.Checked then + Result := Format('%s,%s', [Result, 'location']); + end; + if cbWayptMergeDistance.Checked then + begin + Result := Format('%s -x position,distance=%s', [Result, edWayptMergeDist.Text]); + if (cobWayptMergeDistUnit.ItemIndex = 0) then + Result := Result + 'f' else + Result := Result + 'm'; + end; + if cbWayptRadius.Checked then + begin + Result := Format('%s -x radius,distance=%s', [Result, edWayptRadius.Text]); + if (cobWayptRadiusUnit.ItemIndex = 0) then + Result := Result + 'M' else + Result := Result + 'K'; + Result := Format('%s,lat=%s,lon=%s', [Result, edWayptRadiusLat.Text, edWayptRadiusLon.Text]); + end; + SimpleOption(Result, cbWayptSort, 'sort'); + end; + + if AnyChecked(gbTracks) then + begin + Result := Format('%s -x %s', [Result, 'track']); + if cbTrackTitle.Checked then + Result := Format('%s,title="%s"', [Result, edTrackTitleValue.Text]); + + if cbTrackTime.Checked then + begin + s := Format('%sd%sh%sm%ss', + [edTrackTimeDays.Text, edTrackTimeHours.Text, + edTrackTimeMinutes.Text, edTrackTimeSeconds.Text]); + if (s <> '0d0h0m0s') then + Result := Format('%s,move=%s', [Result, s]); + end; + + if cbTrackPack.Checked then + Result := Format('%s,pack', [Result]) + else if cbTrackMerge.Checked then + Result := Format('%s,merge', [Result]); + + if cbTrackSplit.Checked then + Result := Format('%s,split', [Result]); + + if (cbTrackRangeTimeZone.Enabled and cbTrackRangeTimeZone.Checked) then + begin + Windows.GetTimeZoneInformation(tz_Info); + tz_Info.Bias := tz_Info.Bias + tz_Info.DaylightBias; + dt_bias := tz_Info.Bias / (24*60); + end + else + dt_bias := 0.0; + + if cbTrackStart.Checked then + begin + dt := Int(dtpTrackStartDate.DateTime) + Frac(dtpTrackStartTime.DateTime) + dt_bias; + Result := Format('%s,start=%s', [ + Result, + FormatDateTime('yyyymmddhhnnss', dt)]); + end; + if cbTrackStop.Checked then + begin + dt := Int(dtpTrackStopDate.DateTime) + Frac(dtpTrackStopTime.DateTime) + dt_bias; + Result := Format('%s,stop=%s', [ + Result, + FormatDateTime('yyyymmddhhnnss', dt)]); + end; + if cbGPSfix.Checked then + Result := Format('%s,fix=%s', [Result, cobGPSfixes.Text]); + if cbTrackCourse.Checked then + Result := Format('%s,course', [Result]); + if cbTrackSpeed.Checked then + Result := Format('%s,speed', [Result]); + end; + + if AnyChecked(gbRoutes) then + begin + if cbRouteSimplify.Checked then + Result := Format('%s -x simplify,count=%s', + [Result, Trim(edRoutesSimplifyMaxPoints.Text)]); + + SimpleOption(Result, cbReverse, 'reverse'); + end; +end; + +function TfrmFilter.AnyChecked(Control: TWinControl): Boolean; +var + i: Integer; + c: TWinControl; +begin + Result := False; + for i := 0 to Self.ComponentCount - 1 do + begin + c := Pointer(Self.Components[i]); + if not(c.InheritsFrom(TWinControl)) then Continue; + if (c.parent <> Control) then Continue; + + if ((c is TCheckBox) and TCheckBox(c).Enabled) then + Result := TCheckBox(c).Checked else + if ((c is TGroupBox) and c.Enabled) then + Result := AnyChecked(c); + if (Result) then Exit; + end; +end; + +procedure TfrmFilter.SetTracksEnabled(const Value: Boolean); +begin + FTracksEnabled := Value; + gbTracks.Enabled := Value; +end; + +function TfrmFilter.AllValid: Boolean; +begin + Result := True; +end; + +procedure TfrmFilter.btnOKClick(Sender: TObject); +begin + if AllValid then + begin +// StoreSettingsToInifile(); + StoreSettingsToRegistry(); + ModalResult := mrOK; + end; +end; + +procedure TfrmFilter.cbTrackStartClick(Sender: TObject); +begin + dtpTrackStartDate.Enabled := cbTrackStart.Checked; + dtpTrackStartTime.Enabled := cbTrackStart.Checked; + cbTrackRangeTimeZone.Enabled := + cbTrackStart.Checked or cbTrackStop.Checked; +end; + +procedure TfrmFilter.cbTrackStopClick(Sender: TObject); +begin + dtpTrackStopDate.Enabled := cbTrackStop.Checked; + dtpTrackStopTime.Enabled := cbTrackStop.Checked; + cbTrackRangeTimeZone.Enabled := + cbTrackStart.Checked or cbTrackStop.Checked; +end; + +procedure TfrmFilter.cbRouteSimplifyClick(Sender: TObject); +begin + edRoutesSimplifyMaxPoints.Enabled := cbRouteSimplify.Checked; +end; + +procedure TfrmFilter.cbTrackPackClick(Sender: TObject); +begin + if cbTrackPack.Checked then + cbTrackMerge.Checked := False; +end; + +procedure TfrmFilter.cbTrackMergeClick(Sender: TObject); +begin + if cbTrackMerge.Checked then + cbTrackPack.Checked := False; +end; + +procedure TfrmFilter.cbWayptMergeDistanceClick(Sender: TObject); +begin + edWayptMergeDist.Enabled := cbWayptMergeDistance.Checked; + cobWayptMergeDistUnit.Enabled := cbWayptMergeDistance.Checked; +end; + +procedure TfrmFilter.cbWayptMergeDupsClick(Sender: TObject); +begin + cbWayptMergeDupLoc.Enabled := cbWayptMergeDups.Checked; + cbWayptMergeDupNames.Enabled := cbWayptMergeDups.Checked; +end; + +procedure TfrmFilter.cbWayptRadiusClick(Sender: TObject); +begin + edWayptRadius.Enabled := cbWayptRadius.Checked; + cobWayptRadiusUnit.Enabled := cbWayptRadius.Checked; + edWayptRadiusLat.Enabled := cbWayptRadius.Checked; + edWayptRadiusLon.Enabled := cbWayptRadius.Checked; +end; + +procedure TfrmFilter.FormCloseQuery(Sender: TObject; + var CanClose: Boolean); +begin + if (ModalResult <> mrOK) then + begin + ChangeCheckBoxesChecked(Self, True); + CanClose := True; + Exit; + end; + CanClose := + ValidateNumerical(edWayptRadius, 0, 99999) and + ValidateNumerical(edWayptRadiusLat, -90, 90) and + ValidateNumerical(edWayptRadiusLon, -180, 180) and + ValidateNumerical(edWayptMergeDist, 0, 99999999) and + ValidateNumerical(edRoutesSimplifyMaxPoints, 1, 9999); + ChangeCheckBoxesChecked(Self, False); +end; + +procedure TfrmFilter.FormShow(Sender: TObject); +begin + ChangeCheckBoxesChecked(Self); + FInitialValues := CmdLine; +end; + +procedure TfrmFilter.ChangeCheckBoxesChecked(AComponent: TComponent; Restore: Boolean = False); +var + i, j: Integer; + c: TComponent; +begin + j := AComponent.ComponentCount; + for i := 0 to j - 1 do + begin + c := AComponent.Components[i]; + if (c is TCheckBox) then + begin + if (Restore) then + TCheckBox(c).Checked := (c.Tag <> 0) else + c.Tag := Integer(TCheckBox(c).Checked); + end + else if (c.ComponentCount > 0) then + ChangeCheckBoxesChecked(c); + end; +end; + +procedure TfrmFilter.FormKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +var + str: string; +begin + if (Key <> 27) then Exit; + + + str := Self.CmdLine; + if (str <> FInitialValues) then + begin + if not(MessageDlg(_('Discard changes?'), mtWarning, mbOKCancel, 0) = mrOK) then + Exit; + end; + ModalResult := mrCancel; +end; + +procedure TfrmFilter.btnHelpClick(Sender: TObject); +begin + WinOpenURL(readme_html_path + '#Data_Filters'); +end; + +procedure TfrmFilter.LoadSettingsFromInifile(); +var + c: TComponent; + i: Integer; + l: TStrings; + s: string; +begin +(* + l := TStringList.Create; + try + gpsbabel_ini.ReadSection('GPSBabelGUI', l); + for i := 0 to l.Count - 1 do + begin + s := l.Strings[i]; + c := SELF.FindComponent('cb' + s); + if (c <> nil) and (c is TCheckbox) then + TCheckbox(c).Checked := (gpsbabel_ini.ReadString('GPSBabelGUI', s, '0') <> '0'); + end; + edTrackTitleValue.Text := gpsbabel_ini.ReadString('track', 'title', + edTrackTitleValue.Text); + edRoutesSimplifyMaxPoints.Text := gpsbabel_ini.ReadString('simplify', 'count', + edRoutesSimplifyMaxPoints.Text); + finally + l.Free; + end; +*) +end; + +procedure TfrmFilter.StoreSettingsToInifile(); +var + i: Integer; + c: TComponent; +begin +(* + for i := 0 to SELF.ComponentCount - 1 do + begin + c := SELF.Components[i]; + if (c is TCheckBox) then + begin + if TCheckBox(c).Checked then + gpsbabel_ini.WriteString('GPSBabelGUI', Copy(TCheckbox(c).Name, 3, 256), '1') + else + gpsbabel_ini.DeleteKey('GPSBabelGUI', Copy(TCheckbox(c).Name, 3, 256)); + end; + end; + + if cbTrackTitle.Checked then + gpsbabel_ini.WriteString('track', 'title', edTrackTitleValue.Text) + else + gpsbabel_ini.DeleteKey('track', 'title'); + + if cbRouteSimplify.Checked then + gpsbabel_ini.WriteString('simplify', 'count', edRoutesSimplifyMaxPoints.Text) + else + gpsbabel_ini.DeleteKey('simplify', 'count'); +*) +end; + +procedure TfrmFilter.StoreSettingsToRegistry(); +var + i: Integer; + c: TComponent; + r: TRegistry; +begin + r := TRegistry.Create; + try + r.RootKey := HKEY_CURRENT_USER; + if not(r.OpenKey('\SOFTWARE\GPSBabel', True)) then Exit; + + for i := 0 to SELF.ComponentCount - 1 do + begin + c := SELF.Components[i]; + if (c is TCheckbox) then + r.WriteBool('filter:' + Copy(c.Name, 3, 256), TCheckBox(c).Checked) + else if (c is TEdit) then + r.WriteString('filter:' + Copy(c.Name, 3, 256), TEdit(c).Text) + else if (c is TCombobox) then + r.WriteString('filter:' + Copy(c.Name, 4, 256), IntToStr(TCombobox(c).ItemIndex)); + end; + finally + r.Free; + end; +end; + +procedure TfrmFilter.LoadSettingsFromRegistry(); +var + i: Integer; + c: TComponent; + r: TRegistry; + s: string; + u: TUpDown; + + function ReadString(R: TRegistry; const Key, Def: string): string; + begin + if R.ValueExists(Key) then + Result := R.ReadString(Key) + else + Result := Def; + end; + +begin + r := TRegistry.Create; + try + r.RootKey := HKEY_CURRENT_USER; + if not(r.OpenKey('\SOFTWARE\GPSBabel', True)) then Exit; + + for i := 0 to SELF.ComponentCount - 1 do + begin + c := SELF.Components[i]; + try + if (c is TCheckbox) then + TCheckBox(c).Checked := r.ReadBool('filter:' + Copy(c.Name, 3, 256)) + else if (c is TEdit) then + begin + s := ReadString(r, 'filter:' + Copy(c.Name, 3, 256), TEdit(c).Text); + if HasUpDown(TEdit(c), u) then + u.Position := StrToInt(s) + else + TEdit(c).Text := s; + end + else if (c is TCombobox) then + begin + s := ReadString(r, 'filter:' + Copy(c.Name, 4, 256), '0'); + TCombobox(c).ItemIndex := StrToIntDef(s, 0); + end; + except + on E: Exception do ; + end; + end; + finally + r.Free; + end; +end; + +procedure TfrmFilter.cbTransformClick(Sender: TObject); +begin + cobTransformType.Enabled := cbTransform.Checked; + cbTransformDelete.Enabled := cbTransform.Checked; +end; + +procedure TfrmFilter.FormClose(Sender: TObject; var Action: TCloseAction); +begin + StoreBounds('filter_form', Self); +end; + +procedure TfrmFilter.cbGPSfixClick(Sender: TObject); +begin + cobGPSfixes.Enabled := TCheckBox(Sender).Checked; +end; + +end. diff --git a/win32/gui-2/gnugettext.pas b/win32/gui-2/gnugettext.pas new file mode 100644 index 000000000..e81821bcf --- /dev/null +++ b/win32/gui-2/gnugettext.pas @@ -0,0 +1,2842 @@ +unit gnugettext; +(**************************************************************) +(* *) +(* (C) Copyright by Lars B. Dybdahl and others *) +(* E-mail: Lars@dybdahl.dk, phone +45 70201241 *) +(* File version: $Date: 2005/12/06 00:25:47 $ *) +(* Revision: $Revision: 1.3 $ *) +(* *) +(* Contributors: Peter Thornqvist, Troy Wolbrink, *) +(* Frank Andreas de Groot, Igor Siticov, *) +(* Jacques Garcia Vazquez *) +(* *) +(* See http://dybdahl.dk/dxgettext/ for more information *) +(* *) +(**************************************************************) + +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// The names of any contributor may not be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +interface + +// If the conditional define DXGETTEXTDEBUG is defined, debugging log is activated. +// Use DefaultInstance.DebugLogToFile() to write the log to a file. +{ $define DXGETTEXTDEBUG} + +{$ifdef VER100} + // Delphi 3 + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} +{$endif} +{$ifdef VER110} + // C++ Builder 3 + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} +{$endif} +{$ifdef VER120} + // Delphi 4 + {$DEFINE DELPHI4OROLDER} + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} +{$endif} +{$ifdef VER125} + // C++ Builder 4 + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} +{$endif} +{$ifdef VER130} + // Delphi 5 + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} + {$ifdef WIN32} + {$DEFINE MSWINDOWS} + {$endif} +{$endif} +{$ifdef VER135} + // C++ Builder 5 + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} + {$ifdef WIN32} + {$DEFINE MSWINDOWS} + {$endif} +{$endif} +{$ifdef VER140} + // Delphi 6 +{$ifdef MSWINDOWS} + {$DEFINE DELPHI6OROLDER} +{$endif} +{$endif} +{$ifdef VER150} + // Delphi 7 +{$endif} + +uses + TypInfo, +{$ifdef DELPHI4OROLDER} + gnugettextD4, +{$else} + {$ifdef DELPHI5OROLDER} + gnugettextD5, + {$endif} +{$endif} + +{$ifdef MSWINDOWS} + Windows, + Delphi, +{$else} + Libc, +{$endif} + Classes, SysUtils; + +(*****************************************************************************) +(* *) +(* MAIN API *) +(* *) +(*****************************************************************************) + +// Main GNU gettext functions. See documentation for instructions on how to use them. +function _(const szMsgId: widestring): widestring; +function gettext(const szMsgId: widestring): widestring; +function dgettext(const szDomain: string; const szMsgId: widestring): widestring; +function dngettext(const szDomain: string; const singular,plural: widestring; Number:longint): widestring; +function ngettext(const singular,plural: widestring; Number:longint): widestring; +procedure textdomain(const szDomain: string); +function getcurrenttextdomain: string; +procedure bindtextdomain(const szDomain: string; const szDirectory: string); + +// Set language to use +procedure UseLanguage(LanguageCode: string); +function GetCurrentLanguage:string; + +// Translates a component (form, frame etc.) to the currently selected language. +// Put TranslateComponent(self) in the OnCreate event of all your forms. +// See the manual for documentation on these functions +type + TTranslator=procedure (obj:TObject) of object; + +procedure TP_Ignore(AnObject:TObject; const name:string); +procedure TP_IgnoreClass (IgnClass:TClass); +procedure TP_IgnoreClassProperty (IgnClass:TClass;const propertyname:string); +procedure TP_GlobalIgnoreClass (IgnClass:TClass); +procedure TP_GlobalIgnoreClassProperty (IgnClass:TClass;const propertyname:string); +procedure TP_GlobalHandleClass (HClass:TClass;Handler:TTranslator); +procedure TranslateComponent(AnObject: TComponent; const TextDomain:string=''); +procedure RetranslateComponent(AnObject: TComponent; const TextDomain:string=''); + +// Add more domains that resourcestrings can be extracted from. If a translation +// is not found in the default domain, this domain will be searched, too. +// This is useful for adding mo files for certain runtime libraries and 3rd +// party component libraries +procedure AddDomainForResourceString (const domain:string); +procedure RemoveDomainForResourceString (const domain:string); + +// Unicode-enabled way to get resourcestrings, automatically translated +// Use like this: ws:=LoadResStringW(@NameOfResourceString); +function LoadResString(ResStringRec: PResStringRec): widestring; +function LoadResStringA(ResStringRec: PResStringRec): ansistring; +function LoadResStringW(ResStringRec: PResStringRec): widestring; + +// This returns an empty string if not translated or translator name is not specified. +function GetTranslatorNameAndEmail:widestring; + + +(*****************************************************************************) +(* *) +(* ADVANCED FUNCTIONALITY *) +(* *) +(*****************************************************************************) + +const + DefaultTextDomain = 'default'; + +var + ExecutableFilename:string; // This is set to paramstr(0) or the name of the DLL you are creating. + +type + EGnuGettext=class(Exception); + EGGProgrammingError=class(EGnuGettext); + EGGComponentError=class(EGnuGettext); + EGGIOError=class(EGnuGettext); + EGGAnsi2WideConvError=class(EGnuGettext); + +// This function will turn resourcestring hooks on or off, eventually with BPL file support. +// Please do not activate BPL file support when the package is in design mode. +const AutoCreateHooks=true; +procedure HookIntoResourceStrings (enabled:boolean=true; SupportPackages:boolean=false); + + + + +(*****************************************************************************) +(* *) +(* CLASS based implementation. *) +(* Use TGnuGettextInstance to have more than one language *) +(* in your application at the same time *) +(* *) +(*****************************************************************************) + +{$ifdef MSWINDOWS} +{$ifndef DELPHI6OROLDER} +{$WARN UNSAFE_TYPE OFF} +{$WARN UNSAFE_CODE OFF} +{$WARN UNSAFE_CAST OFF} +{$endif} +{$endif} + +type + TOnDebugLine = Procedure (Sender: TObject; const Line: String; var Discard: Boolean) of Object; // Set Discard to false if output should still go to ordinary debug log + TGetPluralForm=function (Number:Longint):Integer; + TDebugLogger=procedure (line: ansistring) of object; + TMoFile= // Don't use this class. It's for internal use. + class // Threadsafe. Only constructor and destructor are writing to memory + private + doswap: boolean; + public + Users:Integer; // Reference count. If it reaches zero, this object should be destroyed. + constructor Create (filename:string;Offset,Size:int64); + destructor Destroy; override; + function gettext(const msgid: ansistring;var found:boolean): ansistring; // uses mo file + property isSwappedArchitecture:boolean read doswap; + private + N, O, T: Cardinal; // Values defined at http://www.linuxselfhelp.com/gnu/gettext/html_chapter/gettext_6.html + startindex,startstep:integer; + {$ifdef mswindows} + mo: THandle; + momapping: THandle; + {$endif} + momemoryHandle:PChar; + momemory: PChar; + function autoswap32(i: cardinal): cardinal; + function CardinalInMem(baseptr: PChar; Offset: Cardinal): Cardinal; + end; + TDomain= // Don't use this class. It's for internal use. + class + private + Enabled:boolean; + vDirectory: string; + procedure setDirectory(const dir: string); + public + DebugLogger:TDebugLogger; + Domain: string; + property Directory: string read vDirectory write setDirectory; + constructor Create; + destructor Destroy; override; + // Set parameters + procedure SetLanguageCode (const langcode:string); + procedure SetFilename (const filename:string); // Bind this domain to a specific file + // Get information + procedure GetListOfLanguages(list:TStrings); + function GetTranslationProperty(Propertyname: string): WideString; + function gettext(const msgid: ansistring): ansistring; // uses mo file + private + mofile:TMoFile; + SpecificFilename:string; + curlang: string; + OpenHasFailedBefore: boolean; + procedure OpenMoFile; + procedure CloseMoFile; + end; + TExecutable= + class + procedure Execute; virtual; abstract; + end; + TGnuGettextInstance= + class + private + fOnDebugLine:TOnDebugLine; + CreatorThread:Cardinal; // Only this thread can use LoadResString + public + Enabled:Boolean; // Set this to false to disable translations + DesignTimeCodePage:Integer; // See MultiByteToWideChar() in Win32 API for documentation + constructor Create; + destructor Destroy; override; + procedure UseLanguage(LanguageCode: string); + procedure GetListOfLanguages (const domain:string; list:TStrings); // Puts list of language codes, for which there are translations in the specified domain, into list + {$ifdef DELPHI5OROLDER} + function gettext(const szMsgId: widestring): widestring; + function ngettext(const singular,plural:widestring;Number:longint):widestring; + {$endif} + {$ifndef DELPHI5OROLDER} + function gettext(const szMsgId: ansistring): widestring; overload; + function gettext(const szMsgId: widestring): widestring; overload; + function ngettext(const singular,plural:ansistring;Number:longint):widestring; overload; + function ngettext(const singular,plural:widestring;Number:longint):widestring; overload; + {$endif} + function GetCurrentLanguage:string; + function GetTranslationProperty (const Propertyname:string):WideString; + function GetTranslatorNameAndEmail:widestring; + + // Form translation tools, these are not threadsafe. All TP_ procs must be called just before TranslateProperites() + procedure TP_Ignore(AnObject:TObject; const name:string); + procedure TP_IgnoreClass (IgnClass:TClass); + procedure TP_IgnoreClassProperty (IgnClass:TClass;propertyname:string); + procedure TP_GlobalIgnoreClass (IgnClass:TClass); + procedure TP_GlobalIgnoreClassProperty (IgnClass:TClass;propertyname:string); + procedure TP_GlobalHandleClass (HClass:TClass;Handler:TTranslator); + procedure TranslateProperties(AnObject: TObject; textdomain:string=''); + procedure TranslateComponent(AnObject: TComponent; const TextDomain:string=''); + procedure RetranslateComponent(AnObject: TComponent; const TextDomain:string=''); + + // Multi-domain functions + {$ifdef DELPHI5OROLDER} + function dgettext(const szDomain: string; const szMsgId: widestring): widestring; + function dngettext(const szDomain: string; const singular,plural:widestring;Number:longint):widestring; + {$endif} + {$ifndef DELPHI5OROLDER} + function dgettext(const szDomain: string; const szMsgId: ansistring): widestring; overload; + function dgettext(const szDomain: string; const szMsgId: widestring): widestring; overload; + function dngettext(const szDomain: string; const singular,plural:ansistring;Number:longint):widestring; overload; + function dngettext(const szDomain: string; const singular,plural:widestring;Number:longint):widestring; overload; + {$endif} + procedure textdomain(const szDomain: string); + function getcurrenttextdomain: string; + procedure bindtextdomain(const szDomain: string; const szDirectory: string); + procedure bindtextdomainToFile (const szDomain: string; const filename: string); // Also works with files embedded in exe file + + // Windows API functions + function LoadResString(ResStringRec: PResStringRec): widestring; + + // Output all log info to this file. This may only be called once. + procedure DebugLogToFile (const filename:string; append:boolean=false); + procedure DebugLogPause (PauseEnabled:boolean); + property OnDebugLine: TOnDebugLine read fOnDebugLine write fOnDebugLine; // If set, all debug output goes here + + // Conversion according to design-time character set + function ansi2wide (const s:ansistring):widestring; + protected + procedure TranslateStrings (sl:TStrings;const TextDomain:string); + + // Override these three, if you want to inherited from this class + // to create a new class that handles other domain and language dependent + // issues + procedure WhenNewLanguage (const LanguageID:string); virtual; // Override to know when language changes + procedure WhenNewDomain (const TextDomain:string); virtual; // Override to know when text domain changes. Directory is purely informational + procedure WhenNewDomainDirectory (const TextDomain,Directory:string); virtual; // Override to know when any text domain's directory changes. It won't be called if a domain is fixed to a specific file. + private + curlang: string; + curGetPluralForm:TGetPluralForm; + curmsgdomain: string; + savefileCS: TMultiReadExclusiveWriteSynchronizer; + savefile: TextFile; + savememory: TStringList; + DefaultDomainDirectory:string; + domainlist: TStringList; // List of domain names. Objects are TDomain. + TP_IgnoreList:TStringList; // Temporary list, reset each time TranslateProperties is called + TP_ClassHandling:TList; // Items are TClassMode. If a is derived from b, a comes first + TP_GlobalClassHandling:TList; // Items are TClassMode. If a is derived from b, a comes first + TP_Retranslator:TExecutable; // Cast this to TTP_Retranslator + DebugLogCS:TMultiReadExclusiveWriteSynchronizer; + DebugLog:TStream; + DebugLogOutputPaused:Boolean; + function TP_CreateRetranslator:TExecutable; // Must be freed by caller! + procedure FreeTP_ClassHandlingItems; + procedure DebugWriteln(line: ansistring); + procedure TranslateProperty(AnObject: TObject; PropInfo: PPropInfo; + TodoList: TStrings; const TextDomain:string); + function Getdomain(const domain, DefaultDomainDirectory, CurLang: string): TDomain; // Translates a single property of an object + end; + +var + DefaultInstance:TGnuGettextInstance; + +implementation + +(**************************************************************************) +// Some comments on the implementation: +// This unit should be independent of other units where possible. +// It should have a small footprint in any way. +(**************************************************************************) +// TMultiReadExclusiveWriteSynchronizer is used instead of TCriticalSection +// because it makes this unit independent of the SyncObjs unit +(**************************************************************************) + +{$ifdef DELPHI5OROLDER} +uses + FileCtrl; +{$endif} + +type + TTP_RetranslatorItem= + class + obj:TObject; + Propname:string; + OldValue:WideString; + end; + TTP_Retranslator= + class (TExecutable) + TextDomain:string; + Instance:TGnuGettextInstance; + constructor Create; + destructor Destroy; override; + procedure Remember (obj:TObject; PropName:String; OldValue:WideString); + procedure Execute; override; + private + list:TList; + end; + TEmbeddedFileInfo= + class + offset,size:int64; + end; + TFileLocator= + class // This class finds files even when embedded inside executable + constructor Create; + destructor Destroy; override; + procedure Analyze; // List files embedded inside executable + function FileExists (filename:string):boolean; + function GetMoFile (filename:string;DebugLogger:TDebugLogger):TMoFile; + procedure ReleaseMoFile (mofile:TMoFile); + private + basedirectory:string; + filelist:TStringList; //Objects are TEmbeddedFileInfo. Filenames are relative to .exe file + MoFilesCS:TMultiReadExclusiveWriteSynchronizer; + MoFiles:TStringList; // Objects are filenames+offset, objects are TMoFile + function ReadInt64 (str:TStream):int64; + end; + TGnuGettextComponentMarker= + class (TComponent) + public + LastLanguage:string; + Retranslator:TExecutable; + destructor Destroy; override; + end; + TClassMode= + class + HClass:TClass; + SpecialHandler:TTranslator; + PropertiesToIgnore:TStringList; // This is ignored if Handler is set + constructor Create; + destructor Destroy; override; + end; + TRStrinfo = record + strlength, stroffset: cardinal; + end; + TStrInfoArr = array[0..10000000] of TRStrinfo; + PStrInfoArr = ^TStrInfoArr; + TCharArray5=array[0..4] of ansichar; + THook= // Replaces a runtime library procedure with a custom procedure + class + public + constructor Create (OldProcedure, NewProcedure: pointer; FollowJump:boolean=false); + destructor Destroy; override; // Restores unhooked state + procedure Reset (FollowJump:boolean=false); // Disables and picks up patch points again + procedure Disable; + procedure Enable; + private + oldproc,newproc:Pointer; + Patch:TCharArray5; + Original:TCharArray5; + PatchPosition:PChar; + procedure Shutdown; // Same as destroy, except that object is not destroyed + end; + +var + // System information + Win32PlatformIsUnicode:boolean=False; + + // Information about files embedded inside .exe file + FileLocator:TFileLocator; + + // Hooks into runtime library functions + ResourceStringDomainListCS:TMultiReadExclusiveWriteSynchronizer; + ResourceStringDomainList:TStringList; + HookLoadResString:THook; + HookLoadStr:THook; + HookFmtLoadStr:THook; + +function GGGetEnvironmentVariable(const Name:string):string; +var + Len: integer; + W : String; +begin + Result := ''; + SetLength(W,1); + Len := Windows.GetEnvironmentVariable(PChar(Name), PChar(W), 1); + if Len > 0 then begin + SetLength(Result, Len - 1); + Windows.GetEnvironmentVariable(PChar(Name), PChar(Result), Len); + end; +end; + +function StripCR (s:string):string; +var + i:integer; +begin + i:=1; + while i<=length(s) do begin + if s[i]=#13 then delete (s,i,1) else inc (i); + end; + Result:=s; +end; + +function LF2LineBreakA (s:string):string; +{$ifdef MSWINDOWS} +var + i:integer; +{$endif} +begin + {$ifdef MSWINDOWS} + Assert (sLinebreak=#13#10); + i:=1; + while i<=length(s) do begin + if (s[i]=#10) and (copy(s,i-1,1)<>#13) then begin + insert (#13,s,i); + inc (i,2); + end else + inc (i); + end; + {$endif} + Result:=s; +end; + +function IsWriteProp(Info: PPropInfo): Boolean; +begin + Result := Assigned(Info) and (Info^.SetProc <> nil); +end; + +function string2csyntax(s: string): string; +// Converts a string to the syntax that is used in .po files +var + i: integer; + c: char; +begin + Result := ''; + for i := 1 to length(s) do begin + c := s[i]; + case c of + #32..#33, #35..#255: Result := Result + c; + #13: Result := Result + '\r'; + #10: Result := Result + '\n"'#13#10'"'; + #34: Result := Result + '\"'; + else + Result := Result + '\0x' + IntToHex(ord(c), 2); + end; + end; + Result := '"' + Result + '"'; +end; + +function ResourceStringGettext(MsgId: widestring): widestring; +var + i:integer; +begin + if (MsgID='') or (ResourceStringDomainListCS=nil) then begin + // This only happens during very complicated program startups that fail, + // or when Msgid='' + Result:=MsgId; + exit; + end; + ResourceStringDomainListCS.BeginRead; + try + for i:=0 to ResourceStringDomainList.Count-1 do begin + Result:=dgettext(ResourceStringDomainList.Strings[i], MsgId); + if Result<>MsgId then + break; + end; + finally + ResourceStringDomainListCS.EndRead; + end; +end; + +function gettext(const szMsgId: widestring): widestring; +begin + Result:=DefaultInstance.gettext(szMsgId); +end; + +function _(const szMsgId: widestring): widestring; +begin + Result:=DefaultInstance.gettext(szMsgId); +end; + +function dgettext(const szDomain: string; const szMsgId: widestring): widestring; +begin + Result:=DefaultInstance.dgettext(szDomain, szMsgId); +end; + +function dngettext(const szDomain: string; const singular,plural: widestring; Number:longint): widestring; +begin + Result:=DefaultInstance.dngettext(szDomain,singular,plural,Number); +end; + +function ngettext(const singular,plural: widestring; Number:longint): widestring; +begin + Result:=DefaultInstance.ngettext(singular,plural,Number); +end; + +procedure textdomain(const szDomain: string); +begin + DefaultInstance.textdomain(szDomain); +end; + +procedure SetGettextEnabled (enabled:boolean); +begin + DefaultInstance.Enabled:=enabled; +end; + +function getcurrenttextdomain: string; +begin + Result:=DefaultInstance.getcurrenttextdomain; +end; + +procedure bindtextdomain(const szDomain: string; const szDirectory: string); +begin + DefaultInstance.bindtextdomain(szDomain, szDirectory); +end; + +procedure TP_Ignore(AnObject:TObject; const name:string); +begin + DefaultInstance.TP_Ignore(AnObject, name); +end; + +procedure TP_GlobalIgnoreClass (IgnClass:TClass); +begin + DefaultInstance.TP_GlobalIgnoreClass(IgnClass); +end; + +procedure TP_IgnoreClass (IgnClass:TClass); +begin + DefaultInstance.TP_IgnoreClass(IgnClass); +end; + +procedure TP_IgnoreClassProperty (IgnClass:TClass;const propertyname:string); +begin + DefaultInstance.TP_IgnoreClassProperty(IgnClass,propertyname); +end; + +procedure TP_GlobalIgnoreClassProperty (IgnClass:TClass;const propertyname:string); +begin + DefaultInstance.TP_GlobalIgnoreClassProperty(IgnClass,propertyname); +end; + +procedure TP_GlobalHandleClass (HClass:TClass;Handler:TTranslator); +begin + DefaultInstance.TP_GlobalHandleClass (HClass, Handler); +end; + +procedure TranslateComponent(AnObject: TComponent; const TextDomain:string=''); +begin + DefaultInstance.TranslateComponent(AnObject, TextDomain); +end; + +procedure RetranslateComponent(AnObject: TComponent; const TextDomain:string=''); +begin + DefaultInstance.RetranslateComponent(AnObject, TextDomain); +end; + +{$ifdef MSWINDOWS} + +// These constants are only used in Windows 95 +// Thanks to Frank Andreas de Groot for this table +const + IDAfrikaans = $0436; IDAlbanian = $041C; + IDArabicAlgeria = $1401; IDArabicBahrain = $3C01; + IDArabicEgypt = $0C01; IDArabicIraq = $0801; + IDArabicJordan = $2C01; IDArabicKuwait = $3401; + IDArabicLebanon = $3001; IDArabicLibya = $1001; + IDArabicMorocco = $1801; IDArabicOman = $2001; + IDArabicQatar = $4001; IDArabic = $0401; + IDArabicSyria = $2801; IDArabicTunisia = $1C01; + IDArabicUAE = $3801; IDArabicYemen = $2401; + IDArmenian = $042B; IDAssamese = $044D; + IDAzeriCyrillic = $082C; IDAzeriLatin = $042C; + IDBasque = $042D; IDByelorussian = $0423; + IDBengali = $0445; IDBulgarian = $0402; + IDBurmese = $0455; IDCatalan = $0403; + IDChineseHongKong = $0C04; IDChineseMacao = $1404; + IDSimplifiedChinese = $0804; IDChineseSingapore = $1004; + IDTraditionalChinese = $0404; IDCroatian = $041A; + IDCzech = $0405; IDDanish = $0406; + IDBelgianDutch = $0813; IDDutch = $0413; + IDEnglishAUS = $0C09; IDEnglishBelize = $2809; + IDEnglishCanadian = $1009; IDEnglishCaribbean = $2409; + IDEnglishIreland = $1809; IDEnglishJamaica = $2009; + IDEnglishNewZealand = $1409; IDEnglishPhilippines = $3409; + IDEnglishSouthAfrica = $1C09; IDEnglishTrinidad = $2C09; + IDEnglishUK = $0809; IDEnglishUS = $0409; + IDEnglishZimbabwe = $3009; IDEstonian = $0425; + IDFaeroese = $0438; IDFarsi = $0429; + IDFinnish = $040B; IDBelgianFrench = $080C; + IDFrenchCameroon = $2C0C; IDFrenchCanadian = $0C0C; + IDFrenchCotedIvoire = $300C; IDFrench = $040C; + IDFrenchLuxembourg = $140C; IDFrenchMali = $340C; + IDFrenchMonaco = $180C; IDFrenchReunion = $200C; + IDFrenchSenegal = $280C; IDSwissFrench = $100C; + IDFrenchWestIndies = $1C0C; IDFrenchZaire = $240C; + IDFrisianNetherlands = $0462; IDGaelicIreland = $083C; + IDGaelicScotland = $043C; IDGalician = $0456; + IDGeorgian = $0437; IDGermanAustria = $0C07; + IDGerman = $0407; IDGermanLiechtenstein = $1407; + IDGermanLuxembourg = $1007; IDSwissGerman = $0807; + IDGreek = $0408; IDGujarati = $0447; + IDHebrew = $040D; IDHindi = $0439; + IDHungarian = $040E; IDIcelandic = $040F; + IDIndonesian = $0421; IDItalian = $0410; + IDSwissItalian = $0810; IDJapanese = $0411; + IDKannada = $044B; IDKashmiri = $0460; + IDKazakh = $043F; IDKhmer = $0453; + IDKirghiz = $0440; IDKonkani = $0457; + IDKorean = $0412; IDLao = $0454; + IDLatvian = $0426; IDLithuanian = $0427; + IDMacedonian = $042F; IDMalaysian = $043E; + IDMalayBruneiDarussalam = $083E; IDMalayalam = $044C; + IDMaltese = $043A; IDManipuri = $0458; + IDMarathi = $044E; IDMongolian = $0450; + IDNepali = $0461; IDNorwegianBokmol = $0414; + IDNorwegianNynorsk = $0814; IDOriya = $0448; + IDPolish = $0415; IDBrazilianPortuguese = $0416; + IDPortuguese = $0816; IDPunjabi = $0446; + IDRhaetoRomanic = $0417; IDRomanianMoldova = $0818; + IDRomanian = $0418; IDRussianMoldova = $0819; + IDRussian = $0419; IDSamiLappish = $043B; + IDSanskrit = $044F; IDSerbianCyrillic = $0C1A; + IDSerbianLatin = $081A; IDSesotho = $0430; + IDSindhi = $0459; IDSlovak = $041B; + IDSlovenian = $0424; IDSorbian = $042E; + IDSpanishArgentina = $2C0A; IDSpanishBolivia = $400A; + IDSpanishChile = $340A; IDSpanishColombia = $240A; + IDSpanishCostaRica = $140A; IDSpanishDominicanRepublic = $1C0A; + IDSpanishEcuador = $300A; IDSpanishElSalvador = $440A; + IDSpanishGuatemala = $100A; IDSpanishHonduras = $480A; + IDMexicanSpanish = $080A; IDSpanishNicaragua = $4C0A; + IDSpanishPanama = $180A; IDSpanishParaguay = $3C0A; + IDSpanishPeru = $280A; IDSpanishPuertoRico = $500A; + IDSpanishModernSort = $0C0A; IDSpanish = $040A; + IDSpanishUruguay = $380A; IDSpanishVenezuela = $200A; + IDSutu = $0430; IDSwahili = $0441; + IDSwedishFinland = $081D; IDSwedish = $041D; + IDTajik = $0428; IDTamil = $0449; + IDTatar = $0444; IDTelugu = $044A; + IDThai = $041E; IDTibetan = $0451; + IDTsonga = $0431; IDTswana = $0432; + IDTurkish = $041F; IDTurkmen = $0442; + IDUkrainian = $0422; IDUrdu = $0420; + IDUzbekCyrillic = $0843; IDUzbekLatin = $0443; + IDVenda = $0433; IDVietnamese = $042A; + IDWelsh = $0452; IDXhosa = $0434; + IDZulu = $0435; + +function GetWindowsLanguage: string; +var + langid: Cardinal; + langcode: string; + CountryName: array[0..4] of char; + LanguageName: array[0..4] of char; + works: boolean; +begin + // The return value of GetLocaleInfo is compared with 3 = 2 characters and a zero + works := 3 = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, LanguageName, SizeOf(LanguageName)); + works := works and (3 = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, CountryName, + SizeOf(CountryName))); + if works then begin + // Windows 98, Me, NT4, 2000, XP and newer + LangCode := PChar(@LanguageName[0]); + if lowercase(LangCode)='no' then LangCode:='nb'; + LangCode:=LangCode + '_' + PChar(@CountryName[0]); + end else begin + // This part should only happen on Windows 95. + langid := GetThreadLocale; + case langid of + IDBelgianDutch: langcode := 'nl_BE'; + IDBelgianFrench: langcode := 'fr_BE'; + IDBrazilianPortuguese: langcode := 'pt_BR'; + IDDanish: langcode := 'da_DK'; + IDDutch: langcode := 'nl_NL'; + IDEnglishUK: langcode := 'en_GB'; + IDEnglishUS: langcode := 'en_US'; + IDFinnish: langcode := 'fi_FI'; + IDFrench: langcode := 'fr_FR'; + IDFrenchCanadian: langcode := 'fr_CA'; + IDGerman: langcode := 'de_DE'; + IDGermanLuxembourg: langcode := 'de_LU'; + IDGreek: langcode := 'el_GR'; + IDIcelandic: langcode := 'is_IS'; + IDItalian: langcode := 'it_IT'; + IDKorean: langcode := 'ko_KO'; + IDNorwegianBokmol: langcode := 'nb_NO'; + IDNorwegianNynorsk: langcode := 'nn_NO'; + IDPolish: langcode := 'pl_PL'; + IDPortuguese: langcode := 'pt_PT'; + IDRussian: langcode := 'ru_RU'; + IDSpanish, IDSpanishModernSort: langcode := 'es_ES'; + IDSwedish: langcode := 'sv_SE'; + IDSwedishFinland: langcode := 'sv_FI'; + else + langcode := 'C'; + end; + end; + Result := langcode; +end; +{$endif} + +function LoadResStringA(ResStringRec: PResStringRec): string; +begin + Result:=DefaultInstance.LoadResString(ResStringRec); +end; + +function GetTranslatorNameAndEmail:widestring; +begin + Result:=DefaultInstance.GetTranslatorNameAndEmail; +end; + +procedure UseLanguage(LanguageCode: string); +begin + DefaultInstance.UseLanguage(LanguageCode); +end; + +type + PStrData = ^TStrData; + TStrData = record + Ident: Integer; + Str: string; + end; + +function SysUtilsEnumStringModules(Instance: Longint; Data: Pointer): Boolean; +{$IFDEF MSWINDOWS} +var + Buffer: array [0..1023] of char; +begin + with PStrData(Data)^ do begin + SetString(Str, Buffer, + LoadString(Instance, Ident, Buffer, sizeof(Buffer))); + Result := Str = ''; + end; +end; +{$ENDIF} +{$IFDEF LINUX} +var + rs:TResStringRec; + Module:HModule; +begin + Module:=Instance; + rs.Module:=@Module; + with PStrData(Data)^ do begin + rs.Identifier:=Ident; + Str:=System.LoadResString(@rs); + Result:=Str=''; + end; +end; +{$ENDIF} + +function SysUtilsFindStringResource(Ident: Integer): string; +var + StrData: TStrData; +begin + StrData.Ident := Ident; + StrData.Str := ''; + EnumResourceModules(SysUtilsEnumStringModules, @StrData); + Result := StrData.Str; +end; + +function SysUtilsLoadStr(Ident: Integer): string; +begin + {$ifdef DXGETTEXTDEBUG} + DefaultInstance.DebugWriteln ('Sysutils.LoadRes('+IntToStr(ident)+') called'); + {$endif} + Result := ResourceStringGettext(SysUtilsFindStringResource(Ident)); +end; + +function SysUtilsFmtLoadStr(Ident: Integer; const Args: array of const): string; +begin + {$ifdef DXGETTEXTDEBUG} + DefaultInstance.DebugWriteln ('Sysutils.FmtLoadRes('+IntToStr(ident)+',Args) called'); + {$endif} + FmtStr(Result, SysUtilsFindStringResource(Ident), Args); + Result:=ResourceStringGettext(Result); +end; + +function LoadResString(ResStringRec: PResStringRec): widestring; +begin + Result:=DefaultInstance.LoadResString(ResStringRec); +end; + +function LoadResStringW(ResStringRec: PResStringRec): widestring; +begin + Result:=DefaultInstance.LoadResString(ResStringRec); +end; + + + +function GetCurrentLanguage:string; +begin + Result:=DefaultInstance.GetCurrentLanguage; +end; + +{ TDomain } + +procedure TDomain.CloseMoFile; +begin + if mofile<>nil then begin + FileLocator.ReleaseMoFile(mofile); + mofile:=nil; + end; + OpenHasFailedBefore:=False; +end; + +destructor TDomain.Destroy; +begin + CloseMoFile; + inherited; +end; + +{$ifdef mswindows} +function GetLastWinError:string; +var + errcode:Cardinal; +begin + SetLength (Result,2000); + errcode:=GetLastError(); + Windows.FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,errcode,0,PChar(Result),2000,nil); + Result:=StrPas(PChar(Result)); +end; +{$endif} + +procedure TDomain.OpenMoFile; +var + filename: string; +begin + // Check if it is already open + if mofile<>nil then + exit; + + // Check if it has been attempted to open the file before + if OpenHasFailedBefore then + exit; + + if SpecificFilename<>'' then + filename:=SpecificFilename + else begin + filename := Directory + curlang + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo'; + if (not FileLocator.FileExists(filename)) and (not fileexists(filename)) then + filename := Directory + copy(curlang, 1, 2) + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo'; + end; + if (not FileLocator.FileExists(filename)) and (not fileexists(filename)) then begin + OpenHasFailedBefore:=True; + exit; + end; + mofile:=FileLocator.GetMoFile(filename, DebugLogger); + + {$ifdef DXGETTEXTDEBUG} + if mofile.isSwappedArchitecture then + DebugLogger ('.mo file is swapped (comes from another CPU architecture)'); + {$endif} + + // Check, that the contents of the file is utf-8 + if pos('CHARSET=UTF-8',uppercase(GetTranslationProperty('Content-Type')))=0 then begin + CloseMoFile; + {$ifdef DXGETTEXTDEBUG} + DebugLogger ('The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.'); + {$endif} + {$ifdef MSWINDOWS} + MessageBox(0,PChar('The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.'),'Localization problem',MB_OK); + {$else} + writeln (stderr,'The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.'); + {$endif} + Enabled:=False; + end; +end; + +function TDomain.GetTranslationProperty( + Propertyname: string): WideString; +var + sl:TStringList; + i:integer; + s:string; +begin + Propertyname:=uppercase(Propertyname)+': '; + sl:=TStringList.Create; + try + sl.Text:=utf8encode(gettext('')); + for i:=0 to sl.Count-1 do begin + s:=sl.Strings[i]; + if uppercase(copy(s,1,length(Propertyname)))=Propertyname then begin + Result:=utf8decode(trim(copy(s,length(PropertyName)+1,maxint))); + {$ifdef DXGETTEXTDEBUG} + DebugLogger ('GetTranslationProperty('+PropertyName+') returns '''+Result+'''.'); + {$endif} + exit; + end; + end; + finally + FreeAndNil (sl); + end; + Result:=''; + {$ifdef DXGETTEXTDEBUG} + DebugLogger ('GetTranslationProperty('+PropertyName+') did not find any value. An empty string is returned.'); + {$endif} +end; + +procedure TDomain.setDirectory(const dir: string); +begin + vDirectory := IncludeTrailingPathDelimiter(dir); + SpecificFilename:=''; + CloseMoFile; +end; + +procedure AddDomainForResourceString (const domain:string); +begin + {$ifdef DXGETTEXTDEBUG} + DefaultInstance.DebugWriteln ('Extra domain for resourcestring: '+domain); + {$endif} + ResourceStringDomainListCS.BeginWrite; + try + if ResourceStringDomainList.IndexOf(domain)=-1 then + ResourceStringDomainList.Add (domain); + finally + ResourceStringDomainListCS.EndWrite; + end; +end; + +procedure RemoveDomainForResourceString (const domain:string); +var + i:integer; +begin + {$ifdef DXGETTEXTDEBUG} + DefaultInstance.DebugWriteln ('Remove domain for resourcestring: '+domain); + {$endif} + ResourceStringDomainListCS.BeginWrite; + try + i:=ResourceStringDomainList.IndexOf(domain); + if i<>-1 then + ResourceStringDomainList.Delete (i); + finally + ResourceStringDomainListCS.EndWrite; + end; +end; + +procedure TDomain.SetLanguageCode(const langcode: string); +begin + CloseMoFile; + curlang:=langcode; +end; + +function GetPluralForm2EN(Number: Integer): Integer; +begin + Number:=abs(Number); + if Number=1 then Result:=0 else Result:=1; +end; + +function GetPluralForm1(Number: Integer): Integer; +begin + Result:=0; +end; + +function GetPluralForm2FR(Number: Integer): Integer; +begin + Number:=abs(Number); + if (Number=1) or (Number=0) then Result:=0 else Result:=1; +end; + +function GetPluralForm3LV(Number: Integer): Integer; +begin + Number:=abs(Number); + if (Number mod 10=1) and (Number mod 100<>11) then + Result:=0 + else + if Number<>0 then Result:=1 + else Result:=2; +end; + +function GetPluralForm3GA(Number: Integer): Integer; +begin + Number:=abs(Number); + if Number=1 then Result:=0 + else if Number=2 then Result:=1 + else Result:=2; +end; + +function GetPluralForm3LT(Number: Integer): Integer; +var + n1,n2:byte; +begin + Number:=abs(Number); + n1:=Number mod 10; + n2:=Number mod 100; + if (n1=1) and (n2<>11) then + Result:=0 + else + if (n1>=2) and ((n2<10) or (n2>=20)) then Result:=1 + else Result:=2; +end; + +function GetPluralForm3PL(Number: Integer): Integer; +var + n1,n2:byte; +begin + Number:=abs(Number); + n1:=Number mod 10; + n2:=Number mod 100; + if n1=1 then Result:=0 + else if (n1>=2) and (n1<=4) and ((n2<10) or (n2>=20)) then Result:=1 + else Result:=2; +end; + +function GetPluralForm3RU(Number: Integer): Integer; +var + n1,n2:byte; +begin + Number:=abs(Number); + n1:=Number mod 10; + n2:=Number mod 100; + if (n1=1) and (n2<>11) then + Result:=0 + else + if (n1>=2) and (n1<=4) and ((n2<10) or (n2>=20)) then Result:=1 + else Result:=2; +end; + +function GetPluralForm4SL(Number: Integer): Integer; +var + n2:byte; +begin + Number:=abs(Number); + n2:=Number mod 100; + if n2=1 then Result:=0 + else + if n2=2 then Result:=1 + else + if (n2=3) or (n2=4) then Result:=2 + else + Result:=3; +end; + +procedure TDomain.GetListOfLanguages(list: TStrings); +var + sr:TSearchRec; + more:boolean; + filename, path, langcode:string; + i, j:integer; +begin + list.Clear; + + // Iterate through filesystem + more:=FindFirst (Directory+'*',faAnyFile,sr)=0; + while more do begin + if (sr.Attr and faDirectory<>0) and (sr.name<>'.') and (sr.name<>'..') then begin + filename := Directory + sr.Name + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo'; + if fileexists(filename) then begin + langcode:=lowercase(sr.name); + if list.IndexOf(langcode)=-1 then + list.Add(langcode); + end; + end; + more:=FindNext (sr)=0; + end; + + // Iterate through embedded files + for i:=0 to FileLocator.filelist.Count-1 do begin + filename:=FileLocator.basedirectory+FileLocator.filelist.Strings[i]; + path:=Directory; + {$ifdef MSWINDOWS} + path:=uppercase(path); + filename:=uppercase(filename); + {$endif} + j:=length(path); + if copy(filename,1,j)=path then begin + path:=PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo'; + {$ifdef MSWINDOWS} + path:=uppercase(path); + {$endif} + if copy(filename,length(filename)-length(path)+1,length(path))=path then begin + langcode:=lowercase(copy(filename,j+1,length(filename)-length(path)-j)); + if list.IndexOf(langcode)=-1 then + list.Add(langcode); + end; + end; + end; +end; + +procedure TDomain.SetFilename(const filename: string); +begin + CloseMoFile; + vDirectory := ''; + SpecificFilename:=filename; +end; + +function TDomain.gettext(const msgid: ansistring): ansistring; +var + found:boolean; +begin + if not Enabled then begin + Result:=msgid; + exit; + end; + if (mofile=nil) and (not OpenHasFailedBefore) then + OpenMoFile; + if mofile=nil then begin + {$ifdef DXGETTEXTDEBUG} + DebugLogger('.mo file is not open. Not translating "'+msgid+'"'); + {$endif} + Result := msgid; + end else begin + Result:=mofile.gettext(msgid,found); + {$ifdef DXGETTEXTDEBUG} + if found then + DebugLogger ('Found in .mo ('+Domain+'): "'+utf8encode(msgid)+'"->"'+utf8encode(Result)+'"') + else + DebugLogger ('Translation not found in .mo file ('+Domain+') : "'+utf8encode(msgid)+'"'); + {$endif} + end; +end; + +constructor TDomain.Create; +begin + inherited Create; + Enabled:=True; +end; + +{ TGnuGettextInstance } + +procedure TGnuGettextInstance.bindtextdomain(const szDomain, + szDirectory: string); +var + dir:string; +begin + dir:=IncludeTrailingPathDelimiter(szDirectory); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Text domain "'+szDomain+'" is now located at "'+dir+'"'); + {$endif} + getdomain(szDomain,DefaultDomainDirectory,CurLang).Directory := dir; + WhenNewDomainDirectory (szDomain, szDirectory); +end; + +constructor TGnuGettextInstance.Create; +begin + CreatorThread:=GetCurrentThreadId; + {$ifdef MSWindows} + DesignTimeCodePage:=CP_ACP; + {$endif} + {$ifdef DXGETTEXTDEBUG} + DebugLogCS:=TMultiReadExclusiveWriteSynchronizer.Create; + DebugLog:=TMemoryStream.Create; + DebugWriteln('Debug log started '+DateTimeToStr(Now)); + DebugWriteln(''); + {$endif} + curGetPluralForm:=GetPluralForm2EN; + Enabled:=True; + curmsgdomain:=DefaultTextDomain; + savefileCS := TMultiReadExclusiveWriteSynchronizer.Create; + domainlist := TStringList.Create; + TP_IgnoreList:=TStringList.Create; + TP_IgnoreList.Sorted:=True; + TP_GlobalClassHandling:=TList.Create; + TP_ClassHandling:=TList.Create; + + // Set some settings + DefaultDomainDirectory := IncludeTrailingPathDelimiter(extractfilepath(ExecutableFilename))+'locale'; + + UseLanguage(''); + + bindtextdomain(DefaultTextDomain, DefaultDomainDirectory); + textdomain(DefaultTextDomain); + + // Add default properties to ignore + TP_GlobalIgnoreClassProperty(TComponent,'Name'); + TP_GlobalIgnoreClassProperty(TCollection,'PropName'); +end; + +destructor TGnuGettextInstance.Destroy; +begin + if savememory <> nil then begin + savefileCS.BeginWrite; + try + CloseFile(savefile); + finally + savefileCS.EndWrite; + end; + FreeAndNil(savememory); + end; + FreeAndNil (savefileCS); + FreeAndNil (TP_IgnoreList); + while TP_GlobalClassHandling.Count<>0 do begin + TObject(TP_GlobalClassHandling.Items[0]).Free; + TP_GlobalClassHandling.Delete(0); + end; + FreeAndNil (TP_GlobalClassHandling); + FreeTP_ClassHandlingItems; + FreeAndNil (TP_ClassHandling); + while domainlist.Count <> 0 do begin + domainlist.Objects[0].Free; + domainlist.Delete(0); + end; + FreeAndNil(domainlist); + {$ifdef DXGETTEXTDEBUG} + FreeAndNil (DebugLog); + FreeAndNil (DebugLogCS); + {$endif} + inherited; +end; + +{$ifndef DELPHI5OROLDER} +function TGnuGettextInstance.dgettext(const szDomain: string; const szMsgId: ansistring): widestring; +begin + Result:=dgettext(szDomain, ansi2wide(szMsgId)); +end; +{$endif} + +function TGnuGettextInstance.dgettext(const szDomain: string; + const szMsgId: widestring): widestring; +begin + if not Enabled then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Translation has been disabled. Text is not being translated: '+szMsgid); + {$endif} + Result:=szMsgId; + end else begin + Result:=UTF8Decode(LF2LineBreakA(getdomain(szDomain,DefaultDomainDirectory,CurLang).gettext(StripCR(utf8encode(szMsgId))))); + {$ifdef DXGETTEXTDEBUG} + if (szMsgId<>'') and (Result='') then + DebugWriteln (Format('Error: Translation of %s was an empty string. This may never occur.',[szMsgId])); + {$endif} + end; +end; + +function TGnuGettextInstance.GetCurrentLanguage: string; +begin + Result:=curlang; +end; + +function TGnuGettextInstance.getcurrenttextdomain: string; +begin + Result := curmsgdomain; +end; + +{$ifndef DELPHI5OROLDER} +function TGnuGettextInstance.gettext( + const szMsgId: ansistring): widestring; +begin + Result := dgettext(curmsgdomain, szMsgId); +end; +{$endif} + +function TGnuGettextInstance.gettext( + const szMsgId: widestring): widestring; +begin + Result := dgettext(curmsgdomain, szMsgId); +end; + +procedure TGnuGettextInstance.textdomain(const szDomain: string); +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Changed text domain to "'+szDomain+'"'); + {$endif} + curmsgdomain := szDomain; + WhenNewDomain (szDomain); +end; + +function TGnuGettextInstance.TP_CreateRetranslator : TExecutable; +var + ttpr:TTP_Retranslator; +begin + ttpr:=TTP_Retranslator.Create; + ttpr.Instance:=self; + TP_Retranslator:=ttpr; + Result:=ttpr; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('A retranslator was created.'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_GlobalHandleClass(HClass: TClass; + Handler: TTranslator); +var + cm:TClassMode; + i:integer; +begin + for i:=0 to TP_GlobalClassHandling.Count-1 do begin + cm:=TObject(TP_GlobalClassHandling.Items[i]) as TClassMode; + if cm.HClass=HClass then + raise EGGProgrammingError.Create ('You cannot set a handler for a class that has already been assigned otherwise.'); + if HClass.InheritsFrom(cm.HClass) then begin + // This is the place to insert this class + cm:=TClassMode.Create; + cm.HClass:=HClass; + cm.SpecialHandler:=Handler; + TP_GlobalClassHandling.Insert(i,cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('A handler was set for class '+HClass.ClassName+'.'); + {$endif} + exit; + end; + end; + cm:=TClassMode.Create; + cm.HClass:=HClass; + cm.SpecialHandler:=Handler; + TP_GlobalClassHandling.Add(cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('A handler was set for class '+HClass.ClassName+'.'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_GlobalIgnoreClass(IgnClass: TClass); +var + cm:TClassMode; + i:integer; +begin + for i:=0 to TP_GlobalClassHandling.Count-1 do begin + cm:=TObject(TP_GlobalClassHandling.Items[i]) as TClassMode; + if cm.HClass=IgnClass then + raise EGGProgrammingError.Create ('You cannot add a class to the ignore list that is already on that list: '+IgnClass.ClassName+'. You should keep all TP_Global functions in one place in your source code.'); + if IgnClass.InheritsFrom(cm.HClass) then begin + // This is the place to insert this class + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + TP_GlobalClassHandling.Insert(i,cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + end; + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + TP_GlobalClassHandling.Add(cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, class '+IgnClass.ClassName+' is being ignored.'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_GlobalIgnoreClassProperty( + IgnClass: TClass; propertyname: string); +var + cm:TClassMode; + i,idx:integer; +begin + propertyname:=uppercase(propertyname); + for i:=0 to TP_GlobalClassHandling.Count-1 do begin + cm:=TObject(TP_GlobalClassHandling.Items[i]) as TClassMode; + if cm.HClass=IgnClass then begin + if Assigned(cm.SpecialHandler) then + raise EGGProgrammingError.Create ('You cannot ignore a class property for a class that has a handler set.'); + if not cm.PropertiesToIgnore.Find(propertyname,idx) then + cm.PropertiesToIgnore.Add(propertyname); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + if IgnClass.InheritsFrom(cm.HClass) then begin + // This is the place to insert this class + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + cm.PropertiesToIgnore.Add(propertyname); + TP_GlobalClassHandling.Insert(i,cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + end; + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + cm.PropertiesToIgnore.Add(propertyname); + TP_GlobalClassHandling.Add(cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_Ignore(AnObject: TObject; + const name: string); +begin + TP_IgnoreList.Add(uppercase(name)); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('On object with class name '+AnObject.ClassName+', ignore is set on '+name); + {$endif} +end; + +procedure TGnuGettextInstance.TranslateComponent(AnObject: TComponent; + const TextDomain: string); +var + comp:TGnuGettextComponentMarker; +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('======================================================================'); + DebugWriteln ('TranslateComponent() was called for a component with name '+AnObject.Name+'.'); + {$endif} + comp:=AnObject.FindComponent('GNUgettextMarker') as TGnuGettextComponentMarker; + if comp=nil then begin + comp:=TGnuGettextComponentMarker.Create (nil); + comp.Name:='GNUgettextMarker'; + comp.Retranslator:=TP_CreateRetranslator; + TranslateProperties (AnObject, TextDomain); + AnObject.InsertComponent(comp); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('This is the first time, that this component has been translated. A retranslator component has been created for this component.'); + {$endif} + end else begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('This is not the first time, that this component has been translated.'); + {$endif} + if comp.LastLanguage<>curlang then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('ERROR: TranslateComponent() was called twice with different languages. This indicates an attempt to switch language at runtime, but by using TranslateComponent every time. This API has changed - please use RetranslateComponent() instead.'); + {$endif} + {$ifdef mswindows} + MessageBox (0,'This application tried to switch the language, but in an incorrect way. The programmer needs to replace a call to TranslateComponent with a call to RetranslateComponent(). The programmer should see the changelog of gnugettext.pas for more information.','Error',MB_OK); + {$else} + writeln (stderr,'This application tried to switch the language, but in an incorrect way. The programmer needs to replace a call to TranslateComponent with a call to RetranslateComponent(). The programmer should see the changelog of gnugettext.pas for more information.'); + {$endif} + end else begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('ERROR: TranslateComponent has been called twice, but with the same language chosen. This is a mistake, but in order to prevent that the application breaks, no exception is raised.'); + {$endif} + end; + end; + comp.LastLanguage:=curlang; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('======================================================================'); + {$endif} +end; + +procedure TGnuGettextInstance.TranslateProperty (AnObject:TObject; PropInfo:PPropInfo; TodoList:TStrings; const TextDomain:string); +var + {$ifdef DELPHI5OROLDER} + ws: string; + old: string; + {$endif} + {$ifndef DELPHI5OROLDER} + ppi:PPropInfo; + ws: WideString; + old: WideString; + {$endif} + obj:TObject; + Propname:string; +begin + PropName:=PropInfo^.Name; + try + // Translate certain types of properties + case PropInfo^.PropType^.Kind of + tkString, tkLString, tkWString: + begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Translating '+AnObject.ClassName+'.'+PropName); + {$endif} + {$ifdef DELPHI5OROLDER} + old := GetStrProp(AnObject, PropName); + {$endif} + {$ifndef DELPHI5OROLDER} + if PropInfo^.PropType^.Kind<>tkWString then + old := ansi2wide(GetStrProp(AnObject, PropName)) + else + old := GetWideStrProp(AnObject, PropName); + {$endif} + {$ifdef DXGETTEXTDEBUG} + if old='' then + DebugWriteln ('(Empty, not translated)') + else + DebugWriteln ('Old value: "'+old+'"'); + {$endif} + if (old <> '') and (IsWriteProp(PropInfo)) then begin + if TP_Retranslator<>nil then + (TP_Retranslator as TTP_Retranslator).Remember(AnObject, PropName, old); + ws := dgettext(textdomain,old); + if ws <> old then begin + {$ifdef DELPHI5OROLDER} + SetStrProp(AnObject, PropName, ws); + {$endif} + {$ifndef DELPHI5OROLDER} + ppi:=GetPropInfo(AnObject, Propname); + if ppi<>nil then begin + SetWideStrProp(AnObject, ppi, ws); + end else begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('ERROR: Property disappeared: '+Propname+' for object of type '+AnObject.ClassName); + {$endif} + end; + {$endif} + end; + end; + end { case item }; + tkClass: + begin +// obj:=GetObjectProp(AnObject, PropName); +// if obj<>nil then +// TodoList.AddObject ('',obj); + end { case item }; + end { case }; + except + on E:Exception do + raise EGGComponentError.Create ('Property cannot be translated.'+sLineBreak+ + 'Add TP_GlobalIgnoreClassProperty('+AnObject.ClassName+','''+PropName+''') to your source code or use'+sLineBreak+ + 'TP_Ignore (self,''.'+PropName+''') to prevent this message.'+sLineBreak+ + 'Reason: '+e.Message); + end; +end; + +procedure TGnuGettextInstance.TranslateProperties(AnObject: TObject; textdomain:string=''); +var + TodoList:TStringList; // List of Name/TObject's that is to be processed + DoneList:TStringList; // List of hex codes representing pointers to objects that have been done + i, j, Count: integer; + PropList: PPropList; + UPropName: string; + PropInfo: PPropInfo; + comp:TComponent; + cm,currentcm:TClassMode; + ObjectPropertyIgnoreList:TStringList; + objid, Name:string; + {$ifdef DELPHI5OROLDER} + Data:PTypeData; + {$endif} +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('----------------------------------------------------------------------'); + DebugWriteln ('TranslateProperties() was called for an object of class '+AnObject.ClassName+' with domain "'+textdomain+'".'); + {$endif} + if textdomain='' then + textdomain:=curmsgdomain; + if TP_Retranslator<>nil then + (TP_Retranslator as TTP_Retranslator).TextDomain:=textdomain; + DoneList:=TStringList.Create; + TodoList:=TStringList.Create; + ObjectPropertyIgnoreList:=TStringList.Create; + try + TodoList.AddObject('', AnObject); + DoneList.Sorted:=True; + ObjectPropertyIgnoreList.Sorted:=True; + {$ifndef DELPHI5OROLDER} + ObjectPropertyIgnoreList.Duplicates:=dupIgnore; + ObjectPropertyIgnoreList.CaseSensitive:=False; + DoneList.Duplicates:=dupError; + DoneList.CaseSensitive:=True; + {$endif} + + while TodoList.Count<>0 do begin + AnObject:=TodoList.Objects[0]; + Name:=TodoList.Strings[0]; + TodoList.Delete(0); + if (AnObject<>nil) and (AnObject is TPersistent) then begin + // Make sure each object is only translated once + Assert (sizeof(integer)=sizeof(TObject)); + objid:=IntToHex(integer(AnObject),8); + if DoneList.Find(objid,i) then begin + continue; + end else begin + DoneList.Add(objid); + end; + + ObjectPropertyIgnoreList.Clear; + + // Find out if there is special handling of this object + currentcm:=nil; + // First check the local handling instructions + for j:=0 to TP_ClassHandling.Count-1 do begin + cm:=TObject(TP_ClassHandling.Items[j]) as TClassMode; + if AnObject.InheritsFrom(cm.HClass) then begin + if cm.PropertiesToIgnore.Count<>0 then begin + ObjectPropertyIgnoreList.AddStrings(cm.PropertiesToIgnore); + end else begin + // Ignore the entire class + currentcm:=cm; + break; + end; + end; + end; + // Then check the global handling instructions + if currentcm=nil then + for j:=0 to TP_GlobalClassHandling.Count-1 do begin + cm:=TObject(TP_GlobalClassHandling.Items[j]) as TClassMode; + if AnObject.InheritsFrom(cm.HClass) then begin + if cm.PropertiesToIgnore.Count<>0 then begin + ObjectPropertyIgnoreList.AddStrings(cm.PropertiesToIgnore); + end else begin + // Ignore the entire class + currentcm:=cm; + break; + end; + end; + end; + if currentcm<>nil then begin + ObjectPropertyIgnoreList.Clear; + // Ignore or use special handler + if Assigned(currentcm.SpecialHandler) then begin + currentcm.SpecialHandler (AnObject); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Special handler activated for '+AnObject.ClassName); + {$endif} + end else begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Ignoring object '+AnObject.ClassName); + {$endif} + end; + continue; + end; + + {$ifdef DELPHI5OROLDER} + if AnObject.ClassInfo=nil then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('ClassInfo=nil encountered for class '+AnObject.ClassName+'. Translation of that component has stopped. You should ignore this object.'); + {$endif} + continue; + end; + Data := GetTypeData(AnObject.Classinfo); + Count := Data^.PropCount; + GetMem(PropList, Count * Sizeof(PPropInfo)); + {$endif} + {$ifndef DELPHI5OROLDER} + Count := GetPropList(AnObject, PropList); + {$endif} + try + {$ifdef DELPHI5OROLDER} + GetPropInfos(AnObject.ClassInfo, PropList); + {$endif} + for j := 0 to Count - 1 do begin + PropInfo := PropList[j]; + UPropName:=uppercase(PropInfo^.Name); + // Ignore properties that are meant to be ignored + if ((currentcm=nil) or (not currentcm.PropertiesToIgnore.Find(UPropName,i))) and + (not TP_IgnoreList.Find(Name+'.'+UPropName,i)) and + (not ObjectPropertyIgnoreList.Find(UPropName,i)) then begin + TranslateProperty (AnObject,PropInfo,TodoList,TextDomain); + end; // if + end; // for + finally + {$ifdef DELPHI5OROLDER} + FreeMem(PropList, Data^.PropCount * Sizeof(PPropInfo)); + {$endif} + {$ifndef DELPHI5OROLDER} + if Count<>0 then + FreeMem (PropList); + {$endif} + end; + if AnObject is TStrings then begin + if ((AnObject as TStrings).Text<>'') and (TP_Retranslator<>nil) then + (TP_Retranslator as TTP_Retranslator).Remember(AnObject, 'Text', (AnObject as TStrings).Text); + TranslateStrings (AnObject as TStrings,TextDomain); + end; + // Check for TCollection + if AnObject is TCollection then begin + for i := 0 to (AnObject as TCollection).Count - 1 do + TodoList.AddObject('',(AnObject as TCollection).Items[i]); + end; + if AnObject is TComponent then begin + for i := 0 to TComponent(AnObject).ComponentCount - 1 do begin + comp:=TComponent(AnObject).Components[i]; + if (not TP_IgnoreList.Find(uppercase(comp.Name),j)) then begin + TodoList.AddObject(uppercase(comp.Name),comp); + end; + end; + end; + end { if AnObject<>nil }; + end { while todolist.count<>0 }; + finally + FreeAndNil (todolist); + FreeAndNil (ObjectPropertyIgnoreList); + FreeAndNil (DoneList); + end; + FreeTP_ClassHandlingItems; + TP_IgnoreList.Clear; + TP_Retranslator:=nil; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('----------------------------------------------------------------------'); + {$endif} +end; + +procedure TGnuGettextInstance.UseLanguage(LanguageCode: string); +var + i,p:integer; + dom:TDomain; + l2:string[2]; +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln('UseLanguage('''+LanguageCode+'''); called'); + {$endif} + + if LanguageCode='' then begin + LanguageCode:=GGGetEnvironmentVariable('LANG'); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('LANG env variable is '''+LanguageCode+'''.'); + {$endif} + {$ifdef MSWINDOWS} + if LanguageCode='' then begin + LanguageCode:=GetWindowsLanguage; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Found Windows language code to be '''+LanguageCode+'''.'); + {$endif} + end; + {$endif} + p:=pos('.',LanguageCode); + if p<>0 then + LanguageCode:=copy(LanguageCode,1,p-1); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Language code that will be set is '''+LanguageCode+'''.'); + {$endif} + end; + + curlang := LanguageCode; + for i:=0 to domainlist.Count-1 do begin + dom:=domainlist.Objects[i] as TDomain; + dom.SetLanguageCode (curlang); + end; + + l2:=lowercase(copy(curlang,1,2)); + if (l2='en') or (l2='de') then curGetPluralForm:=GetPluralForm2EN else + if (l2='hu') or (l2='ko') or (l2='zh') or (l2='ja') or (l2='tr') then curGetPluralForm:=GetPluralForm1 else + if (l2='fr') or (l2='fa') or (lowercase(curlang)='pt_br') then curGetPluralForm:=GetPluralForm2FR else + if (l2='lv') then curGetPluralForm:=GetPluralForm3LV else + if (l2='ga') then curGetPluralForm:=GetPluralForm3GA else + if (l2='lt') then curGetPluralForm:=GetPluralForm3LT else + if (l2='ru') or (l2='cs') or (l2='sk') or (l2='uk') or (l2='hr') then curGetPluralForm:=GetPluralForm3RU else + if (l2='pl') then curGetPluralForm:=GetPluralForm3PL else + if (l2='sl') then curGetPluralForm:=GetPluralForm4SL else begin + curGetPluralForm:=GetPluralForm2EN; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Plural form for the language was not found. English plurality system assumed.'); + {$endif} + end; + + WhenNewLanguage (curlang); + + {$ifdef DXGETTEXTDEBUG} + DebugWriteln(''); + {$endif} +end; + +procedure TGnuGettextInstance.TranslateStrings(sl: TStrings;const TextDomain:string); +var + line: string; + i: integer; + s:TStringList; +begin + if sl.Count > 0 then begin + sl.BeginUpdate; + try + s:=TStringList.Create; + try + s.Assign (sl); + for i:=0 to s.Count-1 do begin + line:=s.Strings[i]; + if line<>'' then + s.Strings[i]:=dgettext(TextDomain,line); + end; + sl.Assign(s); + finally + FreeAndNil (s); + end; + finally + sl.EndUpdate; + end; + end; +end; + +function TGnuGettextInstance.GetTranslatorNameAndEmail: widestring; +begin + Result:=GetTranslationProperty('LAST-TRANSLATOR'); +end; + +function TGnuGettextInstance.GetTranslationProperty( + const Propertyname: string): WideString; +begin + Result:=getdomain(curmsgdomain,DefaultDomainDirectory,CurLang).GetTranslationProperty (Propertyname); +end; + +function TGnuGettextInstance.dngettext(const szDomain: string; const singular, plural: widestring; + Number: Integer): widestring; +var + org,trans:widestring; + idx:integer; + p:integer; +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('dngettext translation (domain '+szDomain+', number is '+IntTostr(Number)+') of '+singular+'/'+plural); + {$endif} + org:=singular+#0+plural; + trans:=dgettext(szDomain,org); + if org=trans then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Translation was equal to english version. English plural forms assumed.'); + {$endif} + idx:=GetPluralForm2EN(Number) + end else + idx:=curGetPluralForm(Number); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Index '+IntToStr(idx)+' will be used'); + {$endif} + while true do begin + p:=pos(#0,trans); + if p=0 then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Last translation used: '+utf8encode(trans)); + {$endif} + Result:=trans; + exit; + end; + if idx=0 then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Translation found: '+utf8encode(trans)); + {$endif} + Result:=copy(trans,1,p-1); + exit; + end; + delete (trans,1,p); + dec (idx); + end; +end; + +{$ifndef DELPHI5OROLDER} +function TGnuGettextInstance.ngettext(const singular, plural: ansistring; + Number: Integer): widestring; +begin + Result := dngettext(curmsgdomain, singular, plural, Number); +end; +{$endif} + +function TGnuGettextInstance.ngettext(const singular, plural: widestring; + Number: Integer): widestring; +begin + Result := dngettext(curmsgdomain, singular, plural, Number); +end; + +procedure TGnuGettextInstance.WhenNewDomain(const TextDomain: string); +begin + // This is meant to be empty. +end; + +procedure TGnuGettextInstance.WhenNewLanguage(const LanguageID: string); +begin + // This is meant to be empty. +end; + +procedure TGnuGettextInstance.WhenNewDomainDirectory(const TextDomain, + Directory: string); +begin + // This is meant to be empty. +end; + +procedure TGnuGettextInstance.GetListOfLanguages(const domain: string; + list: TStrings); +begin + getdomain(Domain,DefaultDomainDirectory,CurLang).GetListOfLanguages(list); +end; + +procedure TGnuGettextInstance.bindtextdomainToFile(const szDomain, + filename: string); +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Text domain "'+szDomain+'" is now bound to file named "'+filename+'"'); + {$endif} + getdomain(szDomain,DefaultDomainDirectory,CurLang).SetFilename (filename); +end; + +procedure TGnuGettextInstance.DebugLogPause(PauseEnabled: boolean); +begin + DebugLogOutputPaused:=PauseEnabled; +end; + +procedure TGnuGettextInstance.DebugLogToFile(const filename: string; append:boolean=false); +{$ifdef DXGETTEXTDEBUG} +var + fs:TFileStream; + marker:string; +{$endif} +begin + {$ifdef DXGETTEXTDEBUG} + // Create the file if needed + if (not fileexists(filename)) or (not append) then + fileclose (filecreate (filename)); + + // Open file + fs:=TFileStream.Create (filename,fmOpenWrite or fmShareDenyWrite); + if append then + fs.Seek(0,soFromEnd); + + // Write header if appending + if fs.Position<>0 then begin + marker:=sLineBreak+'==========================================================================='+sLineBreak; + fs.WriteBuffer(marker[1],length(marker)); + end; + + // Copy the memorystream contents to the file + DebugLog.Seek(0,soFromBeginning); + fs.CopyFrom(DebugLog,0); + + // Make DebugLog point to the filestream + FreeAndNil (DebugLog); + DebugLog:=fs; +{$endif} +end; + +procedure TGnuGettextInstance.DebugWriteln(line: ansistring); +Var + Discard: Boolean; +begin + Assert (DebugLogCS<>nil); + Assert (DebugLog<>nil); + + DebugLogCS.BeginWrite; + try + if DebugLogOutputPaused then + exit; + + if Assigned (fOnDebugLine) then begin + Discard := True; + fOnDebugLine (Self, Line, Discard); + If Discard then Exit; + end; + + line:=line+sLineBreak; + + // Ensure that memory usage doesn't get too big. + if (DebugLog is TMemoryStream) and (DebugLog.Position>1000000) then begin + line:=sLineBreak+sLineBreak+sLineBreak+sLineBreak+sLineBreak+ + 'Debug log halted because memory usage grew too much.'+sLineBreak+ + 'Specify a filename to store the debug log in or disable debug loggin in gnugettext.pas.'+ + sLineBreak+sLineBreak+sLineBreak+sLineBreak+sLineBreak; + DebugLogOutputPaused:=True; + end; + DebugLog.WriteBuffer(line[1],length(line)); + finally + DebugLogCS.EndWrite; + end; +end; + +function TGnuGettextInstance.Getdomain(const domain, DefaultDomainDirectory, CurLang: string): TDomain; +// Retrieves the TDomain object for the specified domain. +// Creates one, if none there, yet. +var + idx: integer; +begin + idx := domainlist.IndexOf(Domain); + if idx = -1 then begin + Result := TDomain.Create; + Result.DebugLogger:=DebugWriteln; + Result.Domain := Domain; + Result.Directory := DefaultDomainDirectory; + Result.SetLanguageCode(curlang); + domainlist.AddObject(Domain, Result); + end else begin + Result := domainlist.Objects[idx] as TDomain; + end; +end; + +function TGnuGettextInstance.LoadResString( + ResStringRec: PResStringRec): widestring; +{$ifdef MSWINDOWS} +var + Len: Integer; + Buffer: array [0..1023] of char; +{$endif} +{$ifdef LINUX } +const + ResStringTableLen = 16; +type + ResStringTable = array [0..ResStringTableLen-1] of LongWord; +var + Handle: TResourceHandle; + Tab: ^ResStringTable; + ResMod: HMODULE; +{$endif } +begin + if ResStringRec=nil then + exit; + if ResStringRec.Identifier>=64*1024 then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('LoadResString was given an invalid ResStringRec.Identifier'); + {$endif} + Result:='ERROR'; + exit; + end else begin + {$ifdef LINUX} + // This works with Unicode if the Linux has utf-8 character set + // Result:=System.LoadResString(ResStringRec); + ResMod:=FindResourceHInstance(ResStringRec^.Module^); + Handle:=FindResource(ResMod, + PChar(ResStringRec^.Identifier div ResStringTableLen), PChar(6)); // RT_STRING + Tab:=Pointer(LoadResource(ResMod, Handle)); + if Tab=nil then + Result:='' + else + Result:=PWideChar(PChar(Tab)+Tab[ResStringRec^.Identifier mod ResStringTableLen]); + {$endif} + {$ifdef MSWINDOWS} + if not Win32PlatformIsUnicode then begin + SetString(Result, Buffer, + LoadString(FindResourceHInstance(ResStringRec.Module^), + ResStringRec.Identifier, Buffer, SizeOf(Buffer))) + end else begin + Result := ''; + Len := 0; + While Len = Length(Result) do begin + if Length(Result) = 0 then + SetLength(Result, 1024) + else + SetLength(Result, Length(Result) * 2); + Len := LoadStringW(FindResourceHInstance(ResStringRec.Module^), + ResStringRec.Identifier, PWideChar(Result), Length(Result)); + end; + SetLength(Result, Len); + end; + {$endif} + end; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Loaded resourcestring: '+utf8encode(Result)); + {$endif} + if CreatorThread<>GetCurrentThreadId then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('LoadResString was called from an invalid thread. Resourcestring was not translated.'); + {$endif} + end else + Result:=ResourceStringGettext(Result); +end; + +procedure TGnuGettextInstance.RetranslateComponent(AnObject: TComponent; + const TextDomain: string); +var + comp:TGnuGettextComponentMarker; +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('======================================================================'); + DebugWriteln ('RetranslateComponent() was called for a component with name '+AnObject.Name+'.'); + {$endif} + comp:=AnObject.FindComponent('GNUgettextMarker') as TGnuGettextComponentMarker; + if comp=nil then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Retranslate was called on an object that has not been translated before. An Exception is being raised.'); + {$endif} + raise EGGProgrammingError.Create ('Retranslate was called on an object that has not been translated before. Please use TranslateComponent() before RetranslateComponent().'); + end else begin + if comp.LastLanguage<>curlang then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('The retranslator is being executed.'); + {$endif} + comp.Retranslator.Execute; + end else begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('The language has not changed. The retranslator is not executed.'); + {$endif} + end; + end; + comp.LastLanguage:=curlang; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('======================================================================'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_IgnoreClass(IgnClass: TClass); +var + cm:TClassMode; + i:integer; +begin + for i:=0 to TP_ClassHandling.Count-1 do begin + cm:=TObject(TP_ClassHandling.Items[i]) as TClassMode; + if cm.HClass=IgnClass then + raise EGGProgrammingError.Create ('You cannot add a class to the ignore list that is already on that list: '+IgnClass.ClassName+'.'); + if IgnClass.InheritsFrom(cm.HClass) then begin + // This is the place to insert this class + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + TP_ClassHandling.Insert(i,cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Locally, class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + end; + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + TP_ClassHandling.Add(cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Locally, class '+IgnClass.ClassName+' is being ignored.'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_IgnoreClassProperty(IgnClass: TClass; + propertyname: string); +var + cm:TClassMode; + i:integer; +begin + propertyname:=uppercase(propertyname); + for i:=0 to TP_ClassHandling.Count-1 do begin + cm:=TObject(TP_ClassHandling.Items[i]) as TClassMode; + if cm.HClass=IgnClass then begin + if Assigned(cm.SpecialHandler) then + raise EGGProgrammingError.Create ('You cannot ignore a class property for a class that has a handler set.'); + cm.PropertiesToIgnore.Add(propertyname); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + if IgnClass.InheritsFrom(cm.HClass) then begin + // This is the place to insert this class + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + cm.PropertiesToIgnore.Add(propertyname); + TP_ClassHandling.Insert(i,cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Locally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + end; + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + cm.PropertiesToIgnore.Add(propertyname); + TP_GlobalClassHandling.Add(cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Locally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} +end; + +procedure TGnuGettextInstance.FreeTP_ClassHandlingItems; +begin + while TP_ClassHandling.Count<>0 do begin + TObject(TP_ClassHandling.Items[0]).Free; + TP_ClassHandling.Delete(0); + end; +end; + +function TGnuGettextInstance.ansi2wide(const s: ansistring): widestring; +{$ifdef MSWindows} +var + len:integer; +{$endif} +begin +{$ifdef MSWindows} + if DesignTimeCodePage=CP_ACP then begin + // No design-time codepage specified. Using runtime codepage instead. +{$endif} + Result:=s; +{$ifdef MSWindows} + end else begin + len:=length(s); + if len=0 then + Result:='' + else begin + SetLength (Result,len); + len:=MultiByteToWideChar(DesignTimeCodePage,0,pchar(s),len,pwidechar(Result),len); + if len=0 then + raise EGGAnsi2WideConvError.Create ('Cannot convert string to widestring:'+sLineBreak+s); + SetLength (Result,len); + end; + end; +{$endif} +end; + +{$ifndef DELPHI5OROLDER} +function TGnuGettextInstance.dngettext(const szDomain: string; const singular, + plural: ansistring; Number: Integer): widestring; +begin + Result:=dngettext (szDomain, ansi2wide(singular), ansi2wide(plural), Number); +end; +{$endif} + +{ TClassMode } + +constructor TClassMode.Create; +begin + PropertiesToIgnore:=TStringList.Create; + PropertiesToIgnore.Sorted:=True; + PropertiesToIgnore.Duplicates:=dupError; + {$ifndef DELPHI5OROLDER} + PropertiesToIgnore.CaseSensitive:=False; + {$endif} +end; + +destructor TClassMode.Destroy; +begin + FreeAndNil (PropertiesToIgnore); + inherited; +end; + +{ TFileLocator } + +procedure TFileLocator.Analyze; +var + s:ansistring; + i:integer; + offset:int64; + fs:TFileStream; + fi:TEmbeddedFileInfo; + filename:string; +begin + s:='6637DB2E-62E1-4A60-AC19-C23867046A89'#0#0#0#0#0#0#0#0; + s:=copy(s,length(s)-7,8); + offset:=0; + for i:=8 downto 1 do + offset:=offset shl 8+ord(s[i]); + if offset=0 then + exit; + BaseDirectory:=ExtractFilePath(ExecutableFilename); + try + fs:=TFileStream.Create(ExecutableFilename,fmOpenRead or fmShareDenyNone); + try + while true do begin + fs.Seek(offset,soFromBeginning); + offset:=ReadInt64(fs); + if offset=0 then + exit; + fi:=TEmbeddedFileInfo.Create; + try + fi.Offset:=ReadInt64(fs); + fi.Size:=ReadInt64(fs); + SetLength (filename, offset-fs.position); + fs.ReadBuffer (filename[1],offset-fs.position); + filename:=trim(filename); + filelist.AddObject(filename,fi); + except + FreeAndNil (fi); + raise; + end; + end; + finally + FreeAndNil (fs); + end; + except + {$ifdef DXGETTEXTDEBUG} + raise; + {$endif} + end; +end; + +constructor TFileLocator.Create; +begin + MoFilesCS:=TMultiReadExclusiveWriteSynchronizer.Create; + MoFiles:=TStringList.Create; + filelist:=TStringList.Create; + {$ifdef LINUX} + filelist.Duplicates:=dupError; + filelist.CaseSensitive:=True; + {$endif} + MoFiles.Sorted:=True; + {$ifndef DELPHI5OROLDER} + MoFiles.Duplicates:=dupError; + MoFiles.CaseSensitive:=False; + {$ifdef MSWINDOWS} + filelist.Duplicates:=dupError; + filelist.CaseSensitive:=False; + {$endif} + {$endif} + filelist.Sorted:=True; +end; + +destructor TFileLocator.Destroy; +begin + while filelist.count<>0 do begin + filelist.Objects[0].Free; + filelist.Delete (0); + end; + FreeAndNil (filelist); + FreeAndNil (MoFiles); + FreeAndNil (MoFilesCS); + inherited; +end; + +function TFileLocator.FileExists(filename: string): boolean; +var + idx:integer; +begin + if copy(filename,1,length(basedirectory))=basedirectory then + filename:=copy(filename,length(basedirectory)+1,maxint); + Result:=filelist.Find(filename,idx); +end; + +function TFileLocator.GetMoFile(filename: string; DebugLogger:TDebugLogger): TMoFile; +var + fi:TEmbeddedFileInfo; + idx:integer; + idxname:string; + Offset, Size: Int64; + realfilename:string; +begin + // Find real filename + offset:=0; + size:=0; + realfilename:=filename; + if copy(filename,1,length(basedirectory))=basedirectory then begin + filename:=copy(filename,length(basedirectory)+1,maxint); + idx:=filelist.IndexOf(filename); + if idx<>-1 then begin + fi:=filelist.Objects[idx] as TEmbeddedFileInfo; + realfilename:=ExecutableFilename; + offset:=fi.offset; + size:=fi.size; + {$ifdef DXGETTEXTDEBUG} + DebugLogger ('Instead of '+filename+', using '+realfilename+' from offset '+IntTostr(offset)+', size '+IntToStr(size)); + {$endif} + end; + end; + + + {$ifdef DXGETTEXTDEBUG} + DebugLogger ('Reading .mo data from file '''+filename+''''); + {$endif} + + // Find TMoFile object + MoFilesCS.BeginWrite; + try + idxname:=realfilename+#1+IntToStr(offset); + if MoFiles.Find(idxname, idx) then begin + Result:=MoFiles.Objects[idx] as TMoFile; + end else begin + Result:=TMoFile.Create (realfilename, Offset, Size); + MoFiles.AddObject(idxname, Result); + end; + Inc (Result.Users); + finally + MoFilesCS.EndWrite; + end; +end; + +function TFileLocator.ReadInt64(str: TStream): int64; +begin + Assert (sizeof(Result)=8); + str.ReadBuffer(Result,8); +end; + +procedure TFileLocator.ReleaseMoFile(mofile: TMoFile); +var + i:integer; +begin + Assert (mofile<>nil); + + MoFilesCS.BeginWrite; + try + dec (mofile.Users); + if mofile.Users<=0 then begin + i:=MoFiles.Count-1; + while i>=0 do begin + if MoFiles.Objects[i]=mofile then begin + MoFiles.Delete(i); + FreeAndNil (mofile); + break; + end; + dec (i); + end; + end; + finally + MoFilesCS.EndWrite; + end; +end; + +{ TTP_Retranslator } + +constructor TTP_Retranslator.Create; +begin + list:=TList.Create; +end; + +destructor TTP_Retranslator.Destroy; +var + i:integer; +begin + for i:=0 to list.Count-1 do + TObject(list.Items[i]).Free; + FreeAndNil (list); + inherited; +end; + +procedure TTP_Retranslator.Execute; +var + i:integer; + sl:TStrings; + item:TTP_RetranslatorItem; + newvalue:WideString; + {$ifndef DELPHI5OROLDER} + ppi:PPropInfo; + {$endif} +begin + for i:=0 to list.Count-1 do begin + item:=TObject(list.items[i]) as TTP_RetranslatorItem; + if item.obj is TStrings then begin + // Since we don't know the order of items in sl, and don't have + // the original .Objects[] anywhere, we cannot anticipate anything + // about the current sl.Strings[] and sl.Objects[] values. We therefore + // have to discard both values. We can, however, set the original .Strings[] + // value into the list and retranslate that. + sl:=TStringList.Create; + try + sl.Text:=item.OldValue; + Instance.TranslateStrings(sl,textdomain); + (item.obj as TStrings).BeginUpdate; + try + (item.obj as TStrings).Text:=sl.Text; + finally + (item.obj as TStrings).EndUpdate; + end; + finally + FreeAndNil (sl); + end; + end else begin + newValue:=instance.dgettext(textdomain,item.OldValue); + {$ifdef DELPHI5OROLDER} + SetStrProp(item.obj, item.PropName, newValue); + {$endif} + {$ifndef DELPHI5OROLDER} + ppi:=GetPropInfo(item.obj, item.Propname); + if ppi<>nil then begin + SetWideStrProp(item.obj, ppi, newValue); + end else begin + {$ifdef DXGETTEXTDEBUG} + Instance.DebugWriteln ('ERROR: On retranslation, property disappeared: '+item.Propname+' for object of type '+item.obj.ClassName); + {$endif} + end; + {$endif} + end; + end; +end; + +procedure TTP_Retranslator.Remember(obj: TObject; PropName: String; + OldValue: WideString); +var + item:TTP_RetranslatorItem; +begin + item:=TTP_RetranslatorItem.Create; + item.obj:=obj; + item.Propname:=Propname; + item.OldValue:=OldValue; + list.Add(item); +end; + +{ TGnuGettextComponentMarker } + +destructor TGnuGettextComponentMarker.Destroy; +begin + FreeAndNil (Retranslator); + inherited; +end; + +{ THook } + +constructor THook.Create(OldProcedure, NewProcedure: pointer; FollowJump:boolean=false); +{ Idea and original code from Igor Siticov } +{ Modified by Jacques Garcia Vazquez and Lars Dybdahl } +begin + {$ifndef CPU386} + 'This procedure only works on Intel i386 compatible processors.' + {$endif} + + oldproc:=OldProcedure; + newproc:=NewProcedure; + + Reset (FollowJump); +end; + +destructor THook.Destroy; +begin + Shutdown; + inherited; +end; + +procedure THook.Disable; +begin + Assert (PatchPosition<>nil,'Patch position in THook was nil when Disable was called'); + PatchPosition[0]:=Original[0]; + PatchPosition[1]:=Original[1]; + PatchPosition[2]:=Original[2]; + PatchPosition[3]:=Original[3]; + PatchPosition[4]:=Original[4]; +end; + +procedure THook.Enable; +begin + Assert (PatchPosition<>nil,'Patch position in THook was nil when Enable was called'); + PatchPosition[0]:=Patch[0]; + PatchPosition[1]:=Patch[1]; + PatchPosition[2]:=Patch[2]; + PatchPosition[3]:=Patch[3]; + PatchPosition[4]:=Patch[4]; +end; + +procedure THook.Reset(FollowJump: boolean); +var + offset:integer; + {$ifdef LINUX} + p:pointer; + pagesize:integer; + {$endif} + {$ifdef MSWindows} + ov: cardinal; + {$endif} +begin + if PatchPosition<>nil then + Shutdown; + + patchPosition := OldProc; + if FollowJump and (Word(OldProc^) = $25FF) then begin + // This finds the correct procedure if a virtual jump has been inserted + // at the procedure address + Inc(Integer(patchPosition), 2); // skip the jump + patchPosition := pChar(Pointer(pointer(patchPosition)^)^); + end; + offset:=integer(NewProc)-integer(pointer(patchPosition))-5; + + Patch[0] := char($E9); + Patch[1] := char(offset and 255); + Patch[2] := char((offset shr 8) and 255); + Patch[3] := char((offset shr 16) and 255); + Patch[4] := char((offset shr 24) and 255); + + Original[0]:=PatchPosition[0]; + Original[1]:=PatchPosition[1]; + Original[2]:=PatchPosition[2]; + Original[3]:=PatchPosition[3]; + Original[4]:=PatchPosition[4]; + + {$ifdef MSWINDOWS} + if not VirtualProtect(Pointer(PatchPosition), 5, PAGE_EXECUTE_READWRITE, @ov) then + RaiseLastOSError; + {$endif} + {$ifdef LINUX} + pageSize:=sysconf (_SC_PAGE_SIZE); + p:=pointer(PatchPosition); + p:=pointer((integer(p) + PAGESIZE-1) and not (PAGESIZE-1) - pageSize); + if mprotect (p, pageSize, PROT_READ + PROT_WRITE + PROT_EXEC) <> 0 then + RaiseLastOSError; + {$endif} +end; + +procedure THook.Shutdown; +begin + Disable; + PatchPosition:=nil; +end; + +procedure HookIntoResourceStrings (enabled:boolean=true; SupportPackages:boolean=false); +begin + HookLoadResString.Reset (SupportPackages); + HookLoadStr.Reset (SupportPackages); + HookFmtLoadStr.Reset (SupportPackages); + if enabled then begin + HookLoadResString.Enable; + HookLoadStr.Enable; + HookFmtLoadStr.Enable; + end; +end; + +{ TMoFile } + +function TMoFile.autoswap32(i: cardinal): cardinal; +var + cnv1, cnv2: + record + case integer of + 0: (arr: array[0..3] of byte); + 1: (int: cardinal); + end; +begin + if doswap then begin + cnv1.int := i; + cnv2.arr[0] := cnv1.arr[3]; + cnv2.arr[1] := cnv1.arr[2]; + cnv2.arr[2] := cnv1.arr[1]; + cnv2.arr[3] := cnv1.arr[0]; + Result := cnv2.int; + end else + Result := i; +end; + +function TMoFile.CardinalInMem(baseptr: PChar; Offset: Cardinal): Cardinal; +var pc:^Cardinal; +begin + inc (baseptr,offset); + pc:=Pointer(baseptr); + Result:=pc^; + if doswap then + autoswap32(Result); +end; + +constructor TMoFile.Create(filename: string; Offset,Size:int64); +var + i:cardinal; + nn:integer; + {$ifdef linux} + mofile:TFileStream; + {$endif} +begin + if sizeof(i) <> 4 then + raise EGGProgrammingError.Create('TDomain in gnugettext is written for an architecture that has 32 bit integers.'); + + {$ifdef mswindows} + // Map the mo file into memory and let the operating system decide how to cache + mo:=createfile (PChar(filename),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,0,0); + if mo=INVALID_HANDLE_VALUE then + raise EGGIOError.Create ('Cannot open file '+filename); + momapping:=CreateFileMapping (mo, nil, PAGE_READONLY, 0, 0, nil); + if momapping=0 then + raise EGGIOError.Create ('Cannot create memory map on file '+filename); + momemoryHandle:=MapViewOfFile (momapping,FILE_MAP_READ,0,0,0); + if momemoryHandle=nil then begin + raise EGGIOError.Create ('Cannot map file '+filename+' into memory. Reason: '+GetLastWinError); + end; + momemory:=momemoryHandle+offset; + {$endif} + {$ifdef linux} + // Read the whole file into memory + mofile:=TFileStream.Create (filename, fmOpenRead or fmShareDenyNone); + try + if size=0 then + size:=mofile.Size; + Getmem (momemoryHandle,size); + momemory:=momemoryHandle; + mofile.Seek(offset,soFromBeginning); + mofile.ReadBuffer(momemory^,size); + finally + FreeAndNil (mofile); + end; + {$endif} + + // Check the magic number + doswap:=False; + i:=CardinalInMem(momemory,0); + if (i <> $950412DE) and (i <> $DE120495) then + EGGIOError.Create('This file is not a valid GNU gettext mo file: ' + filename); + doswap := (i = $DE120495); + + + // Find the positions in the file according to the file format spec + CardinalInMem(momemory,4); // Read the version number, but don't use it for anything. + N:=CardinalInMem(momemory,8); // Get string count + O:=CardinalInMem(momemory,12); // Get offset of original strings + T:=CardinalInMem(momemory,16); // Get offset of translated strings + + // Calculate start conditions for a binary search + nn := N; + startindex := 1; + while nn <> 0 do begin + nn := nn shr 1; + startindex := startindex shl 1; + end; + startindex := startindex shr 1; + startstep := startindex shr 1; +end; + +destructor TMoFile.Destroy; +begin + {$ifdef mswindows} + UnMapViewOfFile (momemoryHandle); + CloseHandle (momapping); + CloseHandle (mo); + {$endif} + {$ifdef linux} + FreeMem (momemoryHandle); + {$endif} + inherited; +end; + +function TMoFile.gettext(const msgid: ansistring;var found:boolean): ansistring; +var + i, step: cardinal; + offset, pos: cardinal; + CompareResult:integer; + msgidptr,a,b:PChar; + abidx:integer; + size, msgidsize:integer; +begin + found:=false; + msgidptr:=PChar(msgid); + msgidsize:=length(msgid); + + // Do binary search + i:=startindex; + step:=startstep; + while true do begin + // Get string for index i + pos:=O+8*(i-1); + offset:=CardinalInMem (momemory,pos+4); + size:=CardinalInMem (momemory,pos); + a:=msgidptr; + b:=momemory+offset; + abidx:=size; + if msgidsize0 do begin + CompareResult:=integer(byte(a^))-integer(byte(b^)); + if CompareResult<>0 then + break; + dec (abidx); + inc (a); + inc (b); + end; + if CompareResult=0 then + CompareResult:=msgidsize-size; + if CompareResult=0 then begin // msgid=s + // Found the msgid + pos:=T+8*(i-1); + offset:=CardinalInMem (momemory,pos+4); + size:=CardinalInMem (momemory,pos); + SetString (Result,momemory+offset,size); + found:=True; + break; + end; + if step=0 then begin + // Not found + Result:=msgid; + break; + end; + if CompareResult<0 then begin // msgids + i := i + step; + if i > N then + i := N; + step := step shr 1; + end; + end; +end; + +initialization + {$ifdef DXGETTEXTDEBUG} + {$ifdef MSWINDOWS} + MessageBox (0,'gnugettext.pas debugging is enabled. Turn it off before releasing this piece of software.','Information',MB_OK); + {$endif} + {$ifdef LINUX} + writeln (stderr,'gnugettext.pas debugging is enabled. Turn it off before releasing this piece of software.'); + {$endif} + {$endif} + if IsLibrary then begin + // Get DLL/shared object filename + SetLength (ExecutableFilename,300); + {$ifdef MSWINDOWS} + SetLength (ExecutableFilename,GetModuleFileName(HInstance, PChar(ExecutableFilename), length(ExecutableFilename))); + {$else} + // This line has not been tested on Linux, yet, but should work. + SetLength (ExecutableFilename,GetModuleFileName(0, PChar(ExecutableFilename), length(ExecutableFilename))); + {$endif} + end else + ExecutableFilename:=Paramstr(0); + FileLocator:=TFileLocator.Create; + FileLocator.Analyze; + ResourceStringDomainList:=TStringList.Create; + ResourceStringDomainList.Add(DefaultTextDomain); + ResourceStringDomainListCS:=TMultiReadExclusiveWriteSynchronizer.Create; + DefaultInstance:=TGnuGettextInstance.Create; + {$ifdef MSWINDOWS} + Win32PlatformIsUnicode := (Win32Platform = VER_PLATFORM_WIN32_NT); + {$endif} + + // replace Borlands LoadResString with gettext enabled version: + HookLoadResString:=THook.Create (@system.LoadResString, @LoadResStringA); + HookLoadStr:=THook.Create (@sysutils.LoadStr, @SysUtilsLoadStr); + HookFmtLoadStr:=THook.Create (@sysutils.FmtLoadStr, @SysUtilsFmtLoadStr); + HookIntoResourceStrings (AutoCreateHooks,false); + +finalization + FreeAndNil (DefaultInstance); + FreeAndNil (ResourceStringDomainListCS); + FreeAndNil (ResourceStringDomainList); + FreeAndNil (HookFmtLoadStr); + FreeAndNil (HookLoadStr); + FreeAndNil (HookLoadResString); + FreeAndNil (FileLocator); + +end. + diff --git a/win32/gui-2/gnugettextD4.pas b/win32/gui-2/gnugettextD4.pas new file mode 100644 index 000000000..f11c49555 --- /dev/null +++ b/win32/gui-2/gnugettextD4.pas @@ -0,0 +1,290 @@ +unit gnugettextD4; +(* File version: $Date: 2005/12/06 00:25:47 $ *) +(* Revision: $Revision: 1.3 $ *) +// Delphi 5 optimized interface for gnugettext.pas +// This unit must only be used on Delphi 5. When you upgrade to Delphi 6 or +// later, you should remove this unit and replace all reference to gnugettextD5 +// with refernces to gnugettext. + +interface + +uses + Classes, TypInfo; + +// Ansistring versions of the api +function _(const szMsgId: string): string; +function gettext(const szMsgId: string): string; +function dgettext(const szDomain: string; const szMsgId: string): string; +procedure TranslateComponent(AnObject: TComponent); + +//***************************************************************************** +// Don't use anything in the interface below this line. +// It only contains code or gnugettext.pas to make it compile with Delphi 5. + +type + UTF8String = AnsiString; + +const + PathDelim='\'; + sLineBreak=#13#10; + +function GetEnvironmentVariable(const VarName: string): string; +function DirectoryExists(const Name:string):boolean; +function IncludeTrailingPathDelimiter(s: string): string; +function ExcludeTrailingPathDelimiter(s: string): string; +procedure RaiseLastOSError; +function StrToFloatDef(const S:String;Default:Extended):Extended; +function Utf8Decode(const S: UTF8String): WideString; +function Utf8Encode(const WS: WideString): UTF8String; + +// for delphi 4 + +procedure FreeAndNil(var P); +function IncludeTrailingBackSlash(const Path: string): string; +function ExcludeTrailingBackslash(const Path: string): string; + +implementation + +uses + filectrl, Windows, SysUtils, + gnugettext; + +function GetEnvironmentVariable(const VarName: string): string; +var Size: Integer; +begin + Size := Windows.GetEnvironmentVariable(PChar(VarName), nil, 0); + SetLength(Result, Size - 1); + Windows.GetEnvironmentVariable(PChar(VarName), PChar(Result), Size); +end; + +function DirectoryExists(const Name:string):boolean; +begin + Result := FileCtrl.DirectoryExists(Name); +end; + +function IncludeTrailingPathDelimiter(s: string): string; +begin + Result := IncludeTrailingBackslash(s); +end; + +function ExcludeTrailingPathDelimiter(s: string): string; +begin + Result := ExcludeTrailingBackslash(s); +end; + +procedure RaiseLastOSError; +begin + RaiseLastWin32Error; +end; + +function StrToFloatDef(const S:String;Default:Extended):Extended; +begin + if not TextToFloat(PChar(S), Result, fvExtended) then + Result := Default; +end; + +function UnicodeToUtf8(Dest: PChar; MaxDestBytes: Cardinal; Source: PWideChar; SourceChars: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Cardinal; +begin + Result := 0; + if Source = nil then + Exit; + count := 0; + i := 0; + if Dest <> nil then begin + while (i < SourceChars) and (count < MaxDestBytes) do begin + c := Cardinal(Source[i]); + Inc(i); + if c <= $7F then begin + Dest[count] := Char(c); + Inc(count); + end else + if c > $7FF then begin + if count + 3 > MaxDestBytes then + break; + Dest[count] := Char($E0 or (c shr 12)); + Dest[count + 1] := Char($80 or ((c shr 6) and $3F)); + Dest[count + 2] := Char($80 or (c and $3F)); + Inc(count, 3); + end else // $7F < Source[i] <= $7FF + begin + if count + 2 > MaxDestBytes then + break; + Dest[count] := Char($C0 or (c shr 6)); + Dest[count + 1] := Char($80 or (c and $3F)); + Inc(count, 2); + end; + end; + if count >= MaxDestBytes then + count := MaxDestBytes - 1; + Dest[count] := #0; + end else begin + while i < SourceChars do begin + c := Integer(Source[i]); + Inc(i); + if c > $7F then begin + if c > $7FF then + Inc(count); + Inc(count); + end; + Inc(count); + end; + end; + Result := count + 1; // convert zero based index to byte count +end; + +function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: PChar; SourceBytes: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Byte; + wc: Cardinal; +begin + if Source = nil then begin + Result := 0; + Exit; + end; + Result := Cardinal(-1); + count := 0; + i := 0; + if Dest <> nil then begin + while (i < SourceBytes) and (count < MaxDestChars) do begin + wc := Cardinal(Source[i]); + Inc(i); + if (wc and $80) <> 0 then begin + if i >= SourceBytes then + Exit; // incomplete multibyte char + wc := wc and $3F; + if (wc and $20) <> 0 then begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte or out of range char + if i >= SourceBytes then + Exit; // incomplete multibyte char + wc := (wc shl 6) or (c and $3F); + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte + + Dest[count] := WideChar((wc shl 6) or (c and $3F)); + end else + Dest[count] := WideChar(wc); + Inc(count); + end; + if count >= MaxDestChars then + count := MaxDestChars - 1; + Dest[count] := #0; + end else begin + while (i < SourceBytes) do begin + c := Byte(Source[i]); + Inc(i); + if (c and $80) <> 0 then begin + if i >= SourceBytes then + Exit; // incomplete multibyte char + c := c and $3F; + if (c and $20) <> 0 then begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte or out of range char + if i >= SourceBytes then + Exit; // incomplete multibyte char + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte + end; + Inc(count); + end; + end; + Result := count + 1; +end; + +function Utf8Decode(const S: UTF8String): WideString; +var + L: Integer; + Temp: WideString; +begin + Result := ''; + if S = '' then + Exit; + SetLength(Temp, Length(S)); + + L := Utf8ToUnicode(PWideChar(Temp), Length(Temp) + 1, PChar(S), Length(S)); + if L > 0 then + SetLength(Temp, L - 1) + else + Temp := ''; + Result := Temp; +end; + +function Utf8Encode(const WS: WideString): UTF8String; +var + L: Integer; + Temp: UTF8String; +begin + Result := ''; + if WS = '' then + Exit; + SetLength(Temp, Length(WS) * 3); // SetLength includes space for null terminator + + L := UnicodeToUtf8(PChar(Temp), Length(Temp) + 1, PWideChar(WS), Length(WS)); + if L > 0 then + SetLength(Temp, L - 1) + else + Temp := ''; + Result := Temp; +end; + +function _(const szMsgId: string): string; +begin + Result:=gettext(szMsgid); +end; + +function gettext(const szMsgId: string): string; +begin + Result:=string(DefaultInstance.gettext(DefaultInstance.ansi2wide(szMsgId))); +end; + +function dgettext(const szDomain: string; const szMsgId: string): string; +begin + Result:=string(DefaultInstance.dgettext(szDomain,DefaultInstance.ansi2wide(szMsgId))); +end; + +procedure TranslateComponent(AnObject: TComponent); +begin + gnugettext.TranslateComponent(AnObject); +end; + +// for delphi 4 + +procedure FreeAndNil(var P); +begin + TObject(P).Free; + Pointer(P) := NIL; +end; + +function IncludeTrailingBackSlash(const Path: string): string; +begin + if (Path <> '') and + not(Path[Length(Path)] in [':', '\']) then + Result := Path + '\' + else + Result := Path; +end; + +function ExcludeTrailingBackslash(const Path: string): string; +var + Len: Integer; +begin + Len := Length(Path); + while (Len > 0) and (Path[Len] in ['/', '\']) do Dec(Len); + SetString(Result, PChar(Path), Len); +end; + +end. diff --git a/win32/gui-2/gnugettextD5.pas b/win32/gui-2/gnugettextD5.pas new file mode 100644 index 000000000..8a586060d --- /dev/null +++ b/win32/gui-2/gnugettextD5.pas @@ -0,0 +1,265 @@ +unit gnugettextD5; +// Information about this file: +// $LastChangedDate: 2005-04-04 19:40:57 +0200 (Mon, 04 Apr 2005) $ +// $LastChangedRevision: 60 $ +// $HeadURL: svn://svn.berlios.de/dxgettext/trunk/dxgettext/sample/gnugettextD5.pas $ + +// Delphi 5 optimized interface for gnugettext.pas +// This unit must only be used on Delphi 5. When you upgrade to Delphi 6 or +// later, you should remove this unit and replace all reference to gnugettextD5 +// with refernces to gnugettext. + +interface + +uses + Classes; + +// Ansistring versions of the api +function _(const szMsgId: string): string; +function gettext(const szMsgId: string): string; +function dgettext(const szDomain: string; const szMsgId: string): string; +procedure TranslateComponent(AnObject: TComponent); + + + +//***************************************************************************** +// Don't use anything in the interface below this line. +// It only contains code or gnugettext.pas to make it compile with Delphi 5. + +type + UTF8String = AnsiString; + +const + PathDelim='\'; + sLineBreak=#13#10; + +function GetEnvironmentVariable(const VarName: string): string; +function DirectoryExists(const Name:string):boolean; +function IncludeTrailingPathDelimiter(s: string): string; +function ExcludeTrailingPathDelimiter(s: string): string; +procedure RaiseLastOSError; +function StrToFloatDef(const S:String;Default:Extended):Extended; +function Utf8Decode(const S: UTF8String): WideString; +function Utf8Encode(const WS: WideString): UTF8String; + + + +implementation + +uses + filectrl, Windows, SysUtils, + gnugettext; + +function GetEnvironmentVariable(const VarName: string): string; +var Size: Integer; +begin + Size := Windows.GetEnvironmentVariable(PChar(VarName), nil, 0); + SetLength(Result, Size - 1); + Windows.GetEnvironmentVariable(PChar(VarName), PChar(Result), Size); +end; + +function DirectoryExists(const Name:string):boolean; +begin + Result := FileCtrl.DirectoryExists(Name); +end; + +function IncludeTrailingPathDelimiter(s: string): string; +begin + Result := IncludeTrailingBackslash(s); +end; + +function ExcludeTrailingPathDelimiter(s: string): string; +begin + Result := ExcludeTrailingBackslash(s); +end; + +procedure RaiseLastOSError; +begin + RaiseLastWin32Error; +end; + +function StrToFloatDef(const S:String;Default:Extended):Extended; +begin + if not TextToFloat(PChar(S), Result, fvExtended) then + Result := Default; +end; + +function UnicodeToUtf8(Dest: PChar; MaxDestBytes: Cardinal; Source: PWideChar; SourceChars: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Cardinal; +begin + Result := 0; + if Source = nil then + Exit; + count := 0; + i := 0; + if Dest <> nil then begin + while (i < SourceChars) and (count < MaxDestBytes) do begin + c := Cardinal(Source[i]); + Inc(i); + if c <= $7F then begin + Dest[count] := Char(c); + Inc(count); + end else + if c > $7FF then begin + if count + 3 > MaxDestBytes then + break; + Dest[count] := Char($E0 or (c shr 12)); + Dest[count + 1] := Char($80 or ((c shr 6) and $3F)); + Dest[count + 2] := Char($80 or (c and $3F)); + Inc(count, 3); + end else // $7F < Source[i] <= $7FF + begin + if count + 2 > MaxDestBytes then + break; + Dest[count] := Char($C0 or (c shr 6)); + Dest[count + 1] := Char($80 or (c and $3F)); + Inc(count, 2); + end; + end; + if count >= MaxDestBytes then + count := MaxDestBytes - 1; + Dest[count] := #0; + end else begin + while i < SourceChars do begin + c := Integer(Source[i]); + Inc(i); + if c > $7F then begin + if c > $7FF then + Inc(count); + Inc(count); + end; + Inc(count); + end; + end; + Result := count + 1; // convert zero based index to byte count +end; + +function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: PChar; SourceBytes: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Byte; + wc: Cardinal; +begin + if Source = nil then begin + Result := 0; + Exit; + end; + Result := Cardinal(-1); + count := 0; + i := 0; + if Dest <> nil then begin + while (i < SourceBytes) and (count < MaxDestChars) do begin + wc := Cardinal(Source[i]); + Inc(i); + if (wc and $80) <> 0 then begin + if i >= SourceBytes then + Exit; // incomplete multibyte char + wc := wc and $3F; + if (wc and $20) <> 0 then begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte or out of range char + if i >= SourceBytes then + Exit; // incomplete multibyte char + wc := (wc shl 6) or (c and $3F); + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte + + Dest[count] := WideChar((wc shl 6) or (c and $3F)); + end else + Dest[count] := WideChar(wc); + Inc(count); + end; + if count >= MaxDestChars then + count := MaxDestChars - 1; + Dest[count] := #0; + end else begin + while (i < SourceBytes) do begin + c := Byte(Source[i]); + Inc(i); + if (c and $80) <> 0 then begin + if i >= SourceBytes then + Exit; // incomplete multibyte char + c := c and $3F; + if (c and $20) <> 0 then begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte or out of range char + if i >= SourceBytes then + Exit; // incomplete multibyte char + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte + end; + Inc(count); + end; + end; + Result := count + 1; +end; + +function Utf8Decode(const S: UTF8String): WideString; +var + L: Integer; + Temp: WideString; +begin + Result := ''; + if S = '' then + Exit; + SetLength(Temp, Length(S)); + + L := Utf8ToUnicode(PWideChar(Temp), Length(Temp) + 1, PChar(S), Length(S)); + if L > 0 then + SetLength(Temp, L - 1) + else + Temp := ''; + Result := Temp; +end; + +function Utf8Encode(const WS: WideString): UTF8String; +var + L: Integer; + Temp: UTF8String; +begin + Result := ''; + if WS = '' then + Exit; + SetLength(Temp, Length(WS) * 3); // SetLength includes space for null terminator + + L := UnicodeToUtf8(PChar(Temp), Length(Temp) + 1, PWideChar(WS), Length(WS)); + if L > 0 then + SetLength(Temp, L - 1) + else + Temp := ''; + Result := Temp; +end; + +function _(const szMsgId: string): string; +begin + Result:=gettext(szMsgid); +end; + +function gettext(const szMsgId: string): string; +begin + Result:=string(DefaultInstance.gettext(DefaultInstance.ansi2wideDTCP(szMsgId))); +end; + +function dgettext(const szDomain: string; const szMsgId: string): string; +begin + Result:=string(DefaultInstance.dgettext(szDomain,DefaultInstance.ansi2wideDTCP(szMsgId))); +end; + +procedure TranslateComponent(AnObject: TComponent); +begin + gnugettext.TranslateComponent(AnObject); +end; + +end. diff --git a/win32/gui-2/gnugettextDx.pas b/win32/gui-2/gnugettextDx.pas new file mode 100644 index 000000000..af1c713b8 --- /dev/null +++ b/win32/gui-2/gnugettextDx.pas @@ -0,0 +1,72 @@ +unit gnugettextDx; + +interface + +uses + Classes, TypInfo, +{$IFDEF VER120} + gnugettextD4; +{$ELSE} +{$IFDEF VER130} + gnugettextD5; +{$ELSE} + gnugettext; +{$ENDIF} +{$ENDIF} + +function _(const szMsgId: string): string; +function gettext(const szMsgId: string): string; +function dgettext(const szDomain: string; const szMsgId: string): string; +procedure TranslateComponent(AnObject: TComponent); + +implementation + +function _(const szMsgId: string): string; +begin +{$IFDEF VER120} + Result := gnugettextD4._(szMsgId); +{$ELSE} +{$IFDEF VER130} + Result := gnugettextD5._(szMsgId); +{$ELSE} + Result := gnugettext._(szMsgId); +{$ENDIF}{$ENDIF} +end; + +function gettext(const szMsgId: string): string; +begin +{$IFDEF VER120} + Result := gnugettextD4.gettext(szMsgId); +{$ELSE} +{$IFDEF VER130} + Result := gnugettextD5.gettext(szMsgId); +{$ELSE} + Result := gnugettext.gettext(szMsgId); +{$ENDIF}{$ENDIF} +end; + +function dgettext(const szDomain: string; const szMsgId: string): string; +begin +{$IFDEF VER120} + Result := gnugettextD4.dgettext(szDomain, szMsgId); +{$ELSE} +{$IFDEF VER130} + Result := gnugettextD5.dgettext(szDomain, szMsgId); +{$ELSE} + Result := gnugettext.dgettext(szDomain, szMsgId); +{$ENDIF}{$ENDIF} +end; + +procedure TranslateComponent(AnObject: TComponent); +begin +{$IFDEF VER120} + gnugettextD4.TranslateComponent(AnObject); +{$ELSE} +{$IFDEF VER130} + gnugettextD5.TranslateComponent(AnObject); +{$ELSE} + gnugettext.TranslateComponent(AnObject); +{$ENDIF}{$ENDIF} +end; + +end. diff --git a/win32/gui-2/gpsbabel.iss b/win32/gui-2/gpsbabel.iss new file mode 100644 index 000000000..d703b5e7a --- /dev/null +++ b/win32/gui-2/gpsbabel.iss @@ -0,0 +1,116 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define Version "1.3.5" +#define Release "-beta20070807" + +[Setup] +AppName=GPSBabel +AppVerName=GPSBabel-{#Version}{#Release} +RestartIfNeededByRun=false +DefaultDirName={pf}\GPSBabel +ShowLanguageDialog=auto +OutputDir=C:\TEMP +SourceDir=.\ +DefaultGroupName=GPSBabel +AlwaysUsePersonalGroup=true +UserInfoPage=false +EnableDirDoesntExistWarning=true +VersionInfoVersion={#Version} +VersionInfoCompany=GPSBabel makers +AllowRootDirectory=true +AlwaysShowGroupOnReadyPage=true +InternalCompressLevel=fast +WindowVisible=false +SetupIconFile=GPSBabelGUI.ico +DisableFinishedPage=false +AppVersion={#Version}{#Release} +UninstallDisplayIcon={app}\GPSBabelGUI.exe +UninstallDisplayName=GPSBabel {#Version} +AppPublisherURL=http://www.gpsbabel.org +AppUpdatesURL=http://sourceforge.net/project/showfiles.php?group_id=58972 +DisableStartupPrompt=true +AppID={{E25E9E85-2244-4AB0-B00D-7F44C6E9F635} +AppMutex=GPSBabelGUI_mutex +OutputBaseFilename=iGPSBabel-{#Version}{#Release} +UsePreviousAppDir=false + +[Tasks] +Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked +Name: quicklaunchicon; Description: {cm:CreateQuickLaunchIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked + +[Files] +Source: GPSBabelGUI.exe; DestDir: {app}; Flags: replacesameversion +Source: README.gui; DestDir: {app} +Source: ..\..\mingw\libexpat.dll; DestDir: {app} +; Source: ..\..\mingw\sqlite3.dll; DestDir: {app} +Source: ..\..\gpsbabel.exe; DestDir: {app}; Flags: comparetimestamp ignoreversion; Languages: +Source: ..\..\gpsbabel.html; DestDir: {app}; Tasks: ; Languages: +Source: ..\..\COPYING; DestDir: {app} +Source: ..\..\README.contrib; DestDir: {app} +Source: ..\..\AUTHORS; DestDir: {app}; Tasks: ; Languages: +Source: ..\..\CHANGELOG; DestDir: {app} + +[Dirs] +Name: {app} + +[Languages] +Name: en; MessagesFile: compiler:Default.isl +Name: de; MessagesFile: compiler:Languages\German.isl +Name: fr; MessagesFile: compiler:Languages\French.isl + +[Icons] +Name: {group}\GPSBabelGUI; Filename: {app}\GPSBabelGUI.exe; WorkingDir: {app}; IconFilename: {app}\GPSBabelGUI.exe; IconIndex: 0; Flags: useapppaths +Name: {group}\{cm:UninstallProgram, GPSBabel}; Filename: {uninstallexe} +Name: {userdesktop}\GPSBabelGUI; Filename: {app}\GPSBabelGUI.exe; WorkingDir: {app}; Tasks: desktopicon; IconIndex: 0 +Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\GPSBabelGUI; Filename: {app}\GPSBabelGUI.exe; Tasks: quicklaunchicon; WorkingDir: {app}; IconFilename: {app}\GPSBabelGUI.exe; IconIndex: 0 + +[Run] +Filename: {app}\GPSBabelGUI.exe; WorkingDir: {app}; Flags: postinstall unchecked skipifsilent; Description: {cm:LaunchProgram,GPSBabelBUI} + +[Code] +var + GPSBabelPathRead: Boolean; + GPSBabelPath: string; + +function InitializeSetup(): Boolean; +begin + GPSBabelPathRead := False; + Result := True; +end; + +function GetGPSBabelPath(): String; +var + GPSBabelPathKeyName, GPSBabelPathValueName: String; +begin + if not GPSBabelPathRead then + begin + GPSBabelPathRead := True; + GPSBabelPathKeyName := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{E25E9E85-2244-4AB0-B00D-7F44C6E9F635}_is1'; + GPSBabelPathValueName := 'Inno Setup: App Path'; + if not(RegQueryStringValue(HKLM, GPSBabelPathKeyName, GPSBabelPathValueName, GPSBabelPath)) then + begin + Result := ''; + GPSBabelPath := Result; + end; + end; + Result := GPSBabelPath; +end; + +function NextButtonClick(CurPageID: Integer): Boolean; +var + s: string; +begin +// PageID's (wpSelectDir, wpSelectProgramGroup, wpReady) + Result := True; + if (CurPageID = wpSelectDir) then + begin + s := GetGPSBabelPath(); + if (s <> '') and (CompareText(s, WizardDirValue()) = 0) then + begin + Result := ( + MsgBox('GPSBabel seems to be installed in this path!' + #13#13 + + 'Overwrite previous installation?', mbConfirmation, mb_YesNo) = mrYes); + end; + end; +end; diff --git a/win32/gui-2/gpsbabel.po b/win32/gui-2/gpsbabel.po new file mode 100644 index 000000000..cae0ee6b1 --- /dev/null +++ b/win32/gui-2/gpsbabel.po @@ -0,0 +1,486 @@ +msgid "" +msgstr "" + +msgid "(integer sec or 'auto') Barograph to GPS time diff" +msgstr "" + +msgid "(USR input) Break segments into separate tracks" +msgstr "" + +msgid "(USR output) Merge into one segmented track" +msgstr "" + +msgid "Ad-hoc closed icon name" +msgstr "" + +msgid "Ad-hoc open icon name" +msgstr "" + +msgid "After output job done sleep n second(s)" +msgstr "" + +msgid "Allow whitespace synth. shortnames" +msgstr "" + +msgid "Altitudes are absolute and not clamped to ground" +msgstr "" + +msgid "Append icon_descr to description" +msgstr "" + +msgid "Append realtime positioning data to the output file instead of truncating" +msgstr "" + +msgid "Base URL for link tag in output" +msgstr "" + +msgid "Basename prepended to URL on output" +msgstr "" + +msgid "Bitmap of categories" +msgstr "" + +msgid "Category name (Cache)" +msgstr "" + +msgid "Category number to use for written waypoints" +msgstr "" + +msgid "Color for lines or mapnotes" +msgstr "" + +msgid "Command unit to power itself down" +msgstr "" + +msgid "Complete date-free tracks with given date (YYYYMMDD)." +msgstr "" + +msgid "Create unique waypoint names (default = yes)" +msgstr "" + +msgid "Create waypoints from geocache log entries" +msgstr "" + +msgid "Database name" +msgstr "" + +msgid "Database name (filename)" +msgstr "" + +msgid "Datum (default=NAD27)" +msgstr "" + +msgid "Days after which points are considered old" +msgstr "" + +msgid "Decimal seconds to pause between groups of strings" +msgstr "" + +msgid "Default category on output" +msgstr "" + +msgid "Default category on output (1..16)" +msgstr "" + +msgid "Default icon name" +msgstr "" + +msgid "Default location" +msgstr "" + +msgid "Default proximity" +msgstr "" + +msgid "Default speed" +msgstr "" + +msgid "Default speed for waypoints (knots/hr)" +msgstr "" + +msgid "Degrees output as 'ddd', 'dmm'(default) or 'dms'" +msgstr "" + +msgid "Delete all routes" +msgstr "" + +msgid "Delete all track points" +msgstr "" + +msgid "Delete all waypoints" +msgstr "" + +msgid "Display labels on track and routepoints (default = 1)" +msgstr "" + +msgid "Distance unit [m=metric, s=statute]" +msgstr "" + +msgid "Do not add geocache data to description" +msgstr "" + +msgid "Do not add URLs to description" +msgstr "" + +msgid "Don't show gpi bitmap on device" +msgstr "" + +msgid "Draw extrusion line from trackpoint to ground" +msgstr "" + +msgid "Drop route points that do not have an equivalent waypoint (hidden points)" +msgstr "" + +msgid "Enable alerts on speed or proximity distance" +msgstr "" + +msgid "Encrypt hints using ROT13" +msgstr "" + +msgid "Encrypt hints with ROT13" +msgstr "" + +msgid "Erase device data after download" +msgstr "" + +msgid "Export linestrings for tracks and routes" +msgstr "" + +msgid "Export placemarks for tracks and routes" +msgstr "" + +msgid "Full path to XCSV style file" +msgstr "" + +msgid "Generate # points" +msgstr "" + +msgid "Generate file with lat/lon for centering map" +msgstr "" + +msgid "Give points (waypoints/route points) a default radius (proximity)" +msgstr "" + +msgid "GPS datum (def. WGS 84)" +msgstr "" + +msgid "Height in pixels of map" +msgstr "" + +msgid "Ignore event marker icons on read" +msgstr "" + +msgid "Include extended data for trackpoints (default = 1)" +msgstr "" + +msgid "Include groundspeak logs if present" +msgstr "" + +msgid "Include major turn points (with description) from calculated route" +msgstr "" + +msgid "Include only via stations in route" +msgstr "" + +msgid "Include short name in bookmarks" +msgstr "" + +msgid "Index of name field in .dbf" +msgstr "" + +msgid "Index of route (if more the one in source)" +msgstr "" + +msgid "Index of route to write (if more the one in source)" +msgstr "" + +msgid "Index of route/track to write (if more the one in source)" +msgstr "" + +msgid "Index of track (if more the one in source)" +msgstr "" + +msgid "Index of track to write (if more the one in source)" +msgstr "" + +msgid "Index of URL field in .dbf" +msgstr "" + +msgid "Indicate direction of travel in track icons (default = 0)" +msgstr "" + +msgid "Infrastructure closed icon name" +msgstr "" + +msgid "Infrastructure open icon name" +msgstr "" + +msgid "Keep turns if simplify filter is used" +msgstr "" + +msgid "Length of generated shortnames" +msgstr "" + +msgid "Length of generated shortnames (default 16)" +msgstr "" + +msgid "Line color, specified in hex AABBGGRR" +msgstr "" + +msgid "Make synth. shortnames unique" +msgstr "" + +msgid "MapSend version TRK file to generate (3,4)" +msgstr "" + +msgid "Margin for map. Degrees or percentage" +msgstr "" + +msgid "Marker type for new points" +msgstr "" + +msgid "Marker type for old points" +msgstr "" + +msgid "Marker type for unfound points" +msgstr "" + +msgid "Max length of waypoint name to write" +msgstr "" + +msgid "Max number of comments to write (maxcmts=200)" +msgstr "" + +msgid "Max shortname length when used with -s" +msgstr "" + +msgid "Max synthesized shortname length" +msgstr "" + +msgid "Merge output with existing file" +msgstr "" + +msgid "MTK compatible CSV output file" +msgstr "" + +msgid "Name of the 'unassigned' category" +msgstr "" + +msgid "New name for the route" +msgstr "" + +msgid "No separator lines between waypoints" +msgstr "" + +msgid "No whitespace in generated shortnames" +msgstr "" + +msgid "Non-stealth encrypted icon name" +msgstr "" + +msgid "Non-stealth non-encrypted icon name" +msgstr "" + +msgid "Numeric value of bitrate (baud=4800)" +msgstr "" + +msgid "Omit Placer name" +msgstr "" + +msgid "Only read turns; skip all other points" +msgstr "" + +msgid "Path to HTML style sheet" +msgstr "" + +msgid "Precision of coordinates" +msgstr "" + +msgid "Proximity distance" +msgstr "" + +msgid "Radius for circles" +msgstr "" + +msgid "Radius of our big earth (default 6371000 meters)" +msgstr "" + +msgid "Read control points as waypoint/route/none" +msgstr "" + +msgid "Read/Write date format (i.e. DDMMYYYY)" +msgstr "" + +msgid "Read/Write date format (i.e. yyyy/mm/dd)" +msgstr "" + +msgid "Read/write GPGGA sentences" +msgstr "" + +msgid "Read/write GPGSA sentences" +msgstr "" + +msgid "Read/write GPRMC sentences" +msgstr "" + +msgid "Read/write GPVTG sentences" +msgstr "" + +msgid "Read/Write time format (i.e. HH:mm:ss xx)" +msgstr "" + +msgid "Retain at most this number of position points (0 = unlimited)" +msgstr "" + +msgid "Return current position as a waypoint" +msgstr "" + +msgid "Road type changes" +msgstr "" + +msgid "Set waypoint name to source filename." +msgstr "" + +msgid "Shortname is MAC address" +msgstr "" + +msgid "Speed in bits per second of serial port (baud=4800)" +msgstr "" + +msgid "Split input into separate files" +msgstr "" + +msgid "Split into multiple routes at turns" +msgstr "" + +msgid "Starting seed of the internal number generator" +msgstr "" + +msgid "Stealth encrypted icon name" +msgstr "" + +msgid "Stealth non-encrypted icon name" +msgstr "" + +msgid "String to separate concatenated address fields (default=\", \")" +msgstr "" + +msgid "Suppress labels on generated pins" +msgstr "" + +msgid "Suppress retired geocaches" +msgstr "" + +msgid "Suppress separator lines between waypoints" +msgstr "" + +msgid "Suppress use of handshaking in name of speed" +msgstr "" + +msgid "Suppress whitespace in generated shortnames" +msgstr "" + +msgid "Symbol to use for point data" +msgstr "" + +msgid "Sync GPS time to computer time" +msgstr "" + +msgid "Synthesize track times" +msgstr "" + +msgid "Target GPX version for output" +msgstr "" + +msgid "Temperature unit [c=Celsius, f=Fahrenheit]" +msgstr "" + +msgid "The icon description is already the marker" +msgstr "" + +msgid "Treat waypoints as icons on write" +msgstr "" + +msgid "Type of .an1 file" +msgstr "" + +msgid "Units for altitude (f)eet or (m)etres" +msgstr "" + +msgid "Units used for names with @speed ('s'tatute or 'm'etric)" +msgstr "" + +msgid "Units used when writing comments ('s'tatute or 'm'etric)" +msgstr "" + +msgid "UPPERCASE synth. shortnames" +msgstr "" + +msgid "Use depth values on output (default is ignore)" +msgstr "" + +msgid "Use proximity values on output (default is ignore)" +msgstr "" + +msgid "Use shortname instead of description" +msgstr "" + +msgid "Use specified bitmap on output" +msgstr "" + +msgid "Version of gdb file to generate (1..3)" +msgstr "" + +msgid "Version of mapsource file to generate (3,4,5)" +msgstr "" + +msgid "Waypoint background color" +msgstr "" + +msgid "Waypoint foreground color" +msgstr "" + +msgid "Waypoint type" +msgstr "" + +msgid "Width in pixels of map" +msgstr "" + +msgid "Width of lines, in pixels" +msgstr "" + +msgid "Write additional node tag key/value pairs" +msgstr "" + +msgid "Write additional way tag key/value pairs" +msgstr "" + +msgid "Write all tracks into one file" +msgstr "" + +msgid "Write description to address field" +msgstr "" + +msgid "Write each waypoint in a separate file" +msgstr "" + +msgid "Write notes to address field" +msgstr "" + +msgid "Write position to address field" +msgstr "" + +msgid "Write position using this grid." +msgstr "" + +msgid "Write timestamps with offset x to UTC time" +msgstr "" + +msgid "Write tracks compatible with Carto Exploreur" +msgstr "" + +msgid "Write tracks for Gisteq Phototracker" +msgstr "" + +msgid "Zoom level to reduce points" +msgstr "" + diff --git a/win32/gui-2/ignore.po b/win32/gui-2/ignore.po new file mode 100644 index 000000000..af13bc5d2 --- /dev/null +++ b/win32/gui-2/ignore.po @@ -0,0 +1,311 @@ +# Doesn't have any letters +#. frmMain..MainMenu1..mnuFile..N5..Caption +#: main.dfm:1485 +#. frmMain..MainMenu1..mnuFile..N3..Caption +#: main.dfm:1491 +#. frmMain..MainMenu1..mnuOptions..N2..Caption +#: main.dfm:1515 +#. frmMain..MainMenu1..mnuOptions..N4..Caption +#: main.dfm:1527 +#. frmMain..MainMenu1..mnuHelp..N1..Caption +#: main.dfm:1556 +msgid "-" +msgstr "" + +# Doesn't have any letters +#. frmFilter..gbTracks..lbTimePlusMinus..Caption +#: filter.dfm:33 +msgid "+/-" +msgstr "" + +# Doesn't look like text +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:342 +msgid "2d" +msgstr "" + +# Doesn't look like text +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:341 +msgid "3d" +msgstr "" + +# Doesn't have any letters +#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Text +#: filter.dfm:344 +msgid "50 " +msgstr "" + +#. frmFilter..gbTracks..edTrackTitleValue..Text +#: filter.dfm:88 +msgid "ACTIVE LOG # %Y%m%d" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:153 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:364 +msgid "ASCII" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputDevice....Items.Strings +#: main.dfm:184 +#. frmMain..pnTop..gbOutput..cbOutputDevice....Items.Strings +#: main.dfm:399 +msgid "COM1" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputDevice....Items.Strings +#: main.dfm:185 +#. frmMain..pnTop..gbOutput..cbOutputDevice....Items.Strings +#: main.dfm:400 +msgid "COM2" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputDevice....Items.Strings +#: main.dfm:186 +#. frmMain..pnTop..gbOutput..cbOutputDevice....Items.Strings +#: main.dfm:401 +msgid "COM3" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputDevice....Items.Strings +#: main.dfm:187 +#. frmMain..pnTop..gbOutput..cbOutputDevice....Items.Strings +#: main.dfm:402 +msgid "COM4" +msgstr "" + +#. frmMain..ActionList1..acDebugCreatePo..Caption +#: main.dfm:1449 +msgid "Create options.po" +msgstr "" + +#. frmMain..ActionList1..acDebugCreatePo..Category +#: main.dfm:1448 +#. frmMain..MainMenu1..mnuDebug..Caption +#: main.dfm:1536 +msgid "Debug" +msgstr "" + +# Seems like a Font.Name extract +#. frmMain..memoOutput..Font.Name +#: main.dfm:670 +msgid "Fixedsys" +msgstr "" + +# Doesn't look like text +#. frmMain..Caption +#: main.dfm:6 +#. Programmer's name for it: SGPSBabelTitle +#: common.pas:35 +msgid "GPSBabelGUI-2" +msgstr "" + +# Doesn't look like text +#. frmAbout..pnClient..Panel1..StaticText1..Caption +#: about.dfm:94 +msgid "GPSBabelGUI-2:" +msgstr "" + +#. frmMain..stbMain......Text +#: main.dfm:693 +#. Programmer's name for it: SGPSBabelURL +#: common.pas:34 +msgid "http://www.gpsbabel.org" +msgstr "" + +#. frmMain..stbMain........Text +#: main.dfm:703 +msgid "http://www.gpsbabel.org (http://sourceforge.net/projects/gpsbabel)" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:156 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:367 +msgid "ISO-8859-1" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:165 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:376 +msgid "ISO-8859-10" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:166 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:377 +msgid "ISO-8859-13" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:167 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:378 +msgid "ISO-8859-14" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:168 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:379 +msgid "ISO-8859-15" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:157 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:368 +msgid "ISO-8859-2" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:158 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:369 +msgid "ISO-8859-3" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:159 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:370 +msgid "ISO-8859-4" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:160 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:371 +msgid "ISO-8859-5" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:161 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:372 +msgid "ISO-8859-6" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:162 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:373 +msgid "ISO-8859-7" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:163 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:374 +msgid "ISO-8859-8" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:164 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:375 +msgid "ISO-8859-9" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:169 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:380 +msgid "KOI-8" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:170 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:381 +msgid "MACROMAN" +msgstr "" + +msgid "MAC-ROMAN" +msgstr "" + +# Seems like a Font.Name extract +#. frmAbout..Font.Name +#: about.dfm:12 +#. frmAbout..pnClient..pnCenter..lbURL..Font.Name +#: about.dfm:102 +#. frmAbout..pnClient..pnCenter..lbSFURL..Font.Name +#: about.dfm:133 +#. frmAbout..pnClient..pnCenter..stLicense..Font.Name +#: about.dfm:168 +#. frmFilter..Font.Name +#: filter.dfm:13 +#. frmMain..Font.Name +#: main.dfm:13 +#. frmMain..pnBottom..lbWhat..Font.Name +#: main.dfm:419 +#. frmMain..stbMain..Font.Name +#: main.dfm:685 +#. frmOptions..Font.Name +#: options.dfm:14 +#. frmOptions..pnOptions..Font.Name +#: options.dfm:69 +#. frmOptions..pnOptions..mmWarning..Font.Name +#: options.dfm:86 +#. frmReadme..Font.Name +#: readme.dfm:11 +#. frmSelect..Font.Name +#: select.dfm:12 +#. frmSelect..pnTop..lbSelect..Font.Name +#: select.dfm:36 +msgid "MS Sans Serif" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:154 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:365 +msgid "MS-ANSI" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbSFURL..Caption +#: about.dfm:128 +msgid "SourceForge.net" +msgstr "" + +# +msgid "US-ASCII" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputDevice....Items.Strings +#: main.dfm:183 +#. frmMain..pnTop..gbOutput..cbOutputDevice....Items.Strings +#: main.dfm:394 +msgid "USB" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:155 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:366 +msgid "UTF-8" +msgstr "" + diff --git a/win32/gui-2/locale/de/LC_MESSAGES/default.po b/win32/gui-2/locale/de/LC_MESSAGES/default.po new file mode 100644 index 000000000..77d76e102 --- /dev/null +++ b/win32/gui-2/locale/de/LC_MESSAGES/default.po @@ -0,0 +1,924 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: GPSBabelGUI-2\n" +"POT-Creation-Date: 2005-08-12 14:50\n" +"PO-Revision-Date: 2007-05-01 19:38+0100\n" +"Last-Translator: Olaf Klein \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2\n" +"X-Poedit-Language: German\n" + +#. frmAbout..Caption +#: about.dfm:5 +msgid "About" +msgstr "Über" + +#. frmAbout..pnClient..pnCenter..lbHint1..Caption +#: about.dfm:76 +msgid "This program is part of the GPSBabel project, hosted on" +msgstr "Dieses Programm ist Bestandteil des Projektes \"GPSBabel\", zu finden auf" + +#. frmAbout..pnClient..pnCenter..lbVersion..Caption +#: about.dfm:84 +#: about.pas:80 +msgid "Version" +msgstr "Version" + +#. frmAbout..pnClient..pnCenter..lbTranslators..Caption +#: about.dfm:91 +msgid "Translations" +msgstr "Übersetzungen" + +#. frmAbout..pnClient..pnCenter..lbURL..Caption +#: about.dfm:98 +msgid "www.gpsbabel.org" +msgstr "www.gpsbabel.org" + +#. frmAbout..pnClient..pnCenter..lbCopyRight..Caption +#: about.dfm:114 +msgid "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" +msgstr "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" + +#. frmAbout..pnClient..pnCenter..lbMoreInfo..Caption +#: about.dfm:121 +msgid "Find more info at" +msgstr "Mehr Info's unter" + +#. frmAbout..pnClient..pnCenter..stDescription..Caption +#: about.dfm:149 +msgid "The frontend for GPSBabel command line program" +msgstr "Das Windows-Fontend für \"gpsbabel.exe\"" + +#. frmAbout..pnClient..pnCenter..stLicense..Caption +#: about.dfm:163 +msgid "THIS SOFTWARE MAY ONLY BE LICENSED FREE OF CHARGE" +msgstr "DIESE SOFTWARE KANN UND DARF NUR KOSTENLOS WEITERGEGEBEN WERDEN" + +#. frmAbout..pnClient..pnCenter..btnNewLanguage..Caption +#: about.dfm:192 +msgid "Adding a new language" +msgstr "Eine neue Sprache hinzufügen" + +#. frmFilter..Caption +#: filter.dfm:6 +msgid "Filter" +msgstr "Filter" + +#. frmFilter..gbTracks..Caption +#. frmMain..pnBottom..cbTracks..Caption +#: filter.dfm:31 +#: main.dfm:581 +msgid "&Tracks" +msgstr "&Tracks" + +#. frmFilter..gbTracks..lbTimePlusMinus..Caption +#: filter.dfm:39 +#: about.pas:87 +#: about.pas:88 +#: about.pas:89 +#: about.pas:90 +msgid "by" +msgstr "von" + +#. frmFilter..gbTracks..lbTimeDays..Caption +#: filter.dfm:46 +msgid "day(s), " +msgstr "Tag(e)," + +#. frmFilter..gbTracks..lbTimeHours..Caption +#: filter.dfm:53 +msgid "hour(s), " +msgstr "Stunde(n)," + +#. frmFilter..gbTracks..lbTimeMinutes..Caption +#: filter.dfm:60 +msgid "minute(s)," +msgstr "Minute(n)," + +#. frmFilter..gbTracks..lbTimeSeconds..Caption +#: filter.dfm:67 +msgid "second(s)" +msgstr "Sekunde(n)" + +#. frmFilter..gbTracks..cbTrackTitle..Hint +#: filter.dfm:74 +msgid "Title for new tracks" +msgstr "Titel für neu erstellte Tracks" + +#. frmFilter..gbTracks..cbTrackTitle..Caption +#: filter.dfm:76 +msgid "Tit&le" +msgstr "Tite&l" + +#. frmFilter..gbTracks..cbTrackSplit..Hint +#: filter.dfm:95 +msgid "Split track into several tracks depending on date of trackpoint" +msgstr "Erzeuge mehrere Tracks abhängig vom Datum der Trackpunkte" + +#. frmFilter..gbTracks..cbTrackSplit..Caption +#: filter.dfm:96 +msgid "&Split" +msgstr "&Splitten" + +#. frmFilter..gbTracks..cbTrackTime..Hint +#: filter.dfm:104 +msgid "Shift all tracks" +msgstr "Tracks um ein Zeitintervall verschieben " + +#. frmFilter..gbTracks..cbTrackTime..Caption +#: filter.dfm:105 +msgid "&Move" +msgstr "Verschieben" + +#. frmFilter..gbTracks..cbTrackStart..Hint +#: filter.dfm:197 +msgid "Take only trackpoints starting at" +msgstr "beginne bei Zeitpunkt ..." + +#. frmFilter..gbTracks..cbTrackStart..Caption +#: filter.dfm:198 +msgid "Start at" +msgstr "Beginnend am" + +#. frmFilter..gbTracks..cbTrackStop..Caption +#: filter.dfm:237 +msgid "stop at" +msgstr "bis zum" + +#. frmFilter..gbTracks..cbTrackPack..Hint +#: filter.dfm:276 +msgid "Pack all tracks into one track (No duplicate timestamps)" +msgstr "Alle Tracks zu einem einzigen zusammenfassen (doppelte Zeitstempel unzulässig)" + +#. frmFilter..gbTracks..cbTrackPack..Caption +#: filter.dfm:277 +msgid "&Pack (or)" +msgstr "&Packen (oder)" + +#. frmFilter..gbTracks..cbTrackMerge..Hint +#: filter.dfm:286 +msgid "Merge all tracks into one track" +msgstr "Fasse alle Tracks zu einem einzigen zusammen (doppelte Zeitstempel werden verworfen)" + +#. frmFilter..gbTracks..cbTrackMerge..Caption +#: filter.dfm:287 +msgid "Merge" +msgstr "Zusammenführen" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Hint +#: filter.dfm:296 +msgid "Shift start/stop by local timezone offset" +msgstr "Verschiebe Beginn/Ende um Differenz zur lokalen Zeitzone" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Caption +#: filter.dfm:297 +msgid "TZ" +msgstr "\"TZ\"" + +#. frmFilter..gbTracks..cbGPSfix..Hint +#: filter.dfm:306 +msgid "Synthesize GPS fixes (PPS, DGPS, 3D, 2D)" +msgstr "" + +#. frmFilter..gbTracks..cbGPSfix..Caption +#: filter.dfm:307 +msgid "GPS fixes" +msgstr "" + +#. frmFilter..gbTracks..cbTrackCourse..Hint +#: filter.dfm:316 +msgid "Synthesize course values" +msgstr "Generiere Kurs-Werte" + +#. frmFilter..gbTracks..cbTrackCourse..Caption +#: filter.dfm:317 +msgid "Course" +msgstr "Kurs" + +#. frmFilter..gbTracks..cbTrackSpeed..Hint +#: filter.dfm:325 +msgid "Synthesize speed values" +msgstr "Generiere Geschwindigkeitswerte" + +#. frmFilter..gbTracks..cbTrackSpeed..Caption +#: filter.dfm:326 +msgid "Speed" +msgstr "Geschwindigkeit" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:338 +msgid "none" +msgstr "" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:339 +msgid "pps" +msgstr "" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:340 +msgid "dgps" +msgstr "" + +#. frmFilter..gbRoutes..Caption +#: filter.dfm:352 +msgid "&Routes && Tracks" +msgstr "&Routen && Tracks" + +#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption +#: filter.dfm:360 +msgid "limit to" +msgstr "auf maximal" + +#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption +#: filter.dfm:368 +msgid "Points" +msgstr "Punkte" + +#. frmFilter..gbRoutes..cbRouteSimplify..Hint +#: filter.dfm:375 +msgid "Simplify routes and tracks by limited number of points" +msgstr "Limitiert die Anzahl von Wegpunkten in Routen und Tracks" + +#. frmFilter..gbRoutes..cbRouteSimplify..Caption +#: filter.dfm:376 +msgid "Simplify" +msgstr "Vereinfachen" + +#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint +#: filter.dfm:385 +msgid "Upper limit of points for routes and tracks" +msgstr "Maximale Anzahl an Punkten innerhalb von Routen und Tracks" + +#. frmFilter..gbRoutes..cbReverse..Hint +#: filter.dfm:407 +msgid "Reverse routes and tracks" +msgstr "Reihenfolge von Wegpunkten in Routen und Tracks umdrehen" + +#. frmFilter..gbRoutes..cbReverse..Caption +#: filter.dfm:408 +msgid "Reverse" +msgstr "Umdrehen" + +#. frmFilter..pnBottom..btnOK..Caption +#: filter.dfm:425 +msgid "OK" +msgstr "OK" + +#. frmFilter..pnBottom..BitBtn1..Caption +#: filter.dfm:461 +msgid "File based filters" +msgstr "Datei basierende Filter" + +#. frmFilter..gbWaypoints..Caption +#. frmMain..pnBottom..cbWaypoints..Caption +#: filter.dfm:490 +#: main.dfm:555 +msgid "&Waypoints" +msgstr "&Wegpunkte" + +#. frmFilter..gbWaypoints..lbWayptRadiusLat..Caption +#: filter.dfm:499 +msgid "Latitude" +msgstr "Breitengrad" + +#. frmFilter..gbWaypoints..lbWayptRadiusLon..Caption +#: filter.dfm:507 +msgid "Longitude" +msgstr "Längengrad" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint +#: filter.dfm:515 +msgid "Merge waypoints with duplicate locations" +msgstr "Fasse Wegpunkte mit gleichen Koordinaten zusammen" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption +#: filter.dfm:516 +msgid "locations" +msgstr "Koordinaten" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint +#: filter.dfm:525 +msgid "Merge waypoints with duplicate \"short name\"" +msgstr "Fasse Wegpunkte mit gleichem Namen zusammen" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption +#: filter.dfm:526 +msgid "\"short names\"" +msgstr "\"Kurznamen\"" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint +#: filter.dfm:535 +msgid "Merge waypoints separated by less then" +msgstr "Fasse alle Wegpunkte zusammen, die weniger als ... auseinander liegen" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption +#: filter.dfm:536 +msgid "Position" +msgstr "Position" + +#. frmFilter..gbWaypoints..cbWayptSort..Hint +#: filter.dfm:564 +msgid "Sort waypoints by \"short name\" or by description" +msgstr "Sortiere Wegpunkte nach Name oder Beschreibung" + +#. frmFilter..gbWaypoints..cbWayptSort..Caption +#: filter.dfm:565 +msgid "Sort" +msgstr "Sortieren" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint +#: filter.dfm:573 +msgid "Merge duplicate waypoints" +msgstr "Entferne doppelte Wegpunkte" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption +#: filter.dfm:574 +msgid "Duplicates" +msgstr "Duplikate" + +#. frmFilter..gbWaypoints..cbWayptRadius..Hint +#: filter.dfm:583 +msgid "Include points based on their proximity to central point" +msgstr "Übernehme nur Punkte mit Entfernung von maximal ... um Mittelpunkt ..." + +#. frmFilter..gbWaypoints..cbWayptRadius..Caption +#: filter.dfm:584 +msgid "Radius" +msgstr "Radius" + +#. frmFilter..gbWaypoints..edWayptRadiusLat..Hint +#: filter.dfm:612 +msgid "Latitude of central point" +msgstr "Breitengrad (Latitude) des Mittelpunktes" + +#. frmFilter..gbWaypoints..edWayptRadiusLon..Hint +#: filter.dfm:622 +msgid "Longitude of central point" +msgstr "Längengrad (Longitude) des Mittelpunktes" + +#. frmFilter..gbTransform..Caption +#: filter.dfm:634 +msgid "Transformation" +msgstr "Transformation" + +#. frmFilter..gbTransform..cbTransform..Caption +#: filter.dfm:651 +msgid "Transform" +msgstr "Transformiere" + +#. frmFilter..gbTransform..cbTransformDelete..Hint +#: filter.dfm:660 +msgid "Delete source data after transformation" +msgstr "Lösche anschließend die internen Quelldaten" + +#. frmFilter..gbTransform..cbTransformDelete..Caption +#: filter.dfm:661 +msgid "Delete" +msgstr "Lösche" + +#. frmMain..pnTop..gbInput..Caption +#: main.dfm:38 +#: main.pas:270 +#: main.pas:275 +#: main.pas:467 +#: main.pas:868 +msgid "Input" +msgstr "Eingabe" + +#. frmMain..pnTop..gbInput..sbOpenFile..Hint +#: main.dfm:45 +msgid "Start the file open dialog" +msgstr "Die zu lesende Datei auswählen" + +#. frmMain..pnTop..gbInput..lbInputOpts..Caption +#. frmMain..pnTop..gbOutput..lbOutputOpts..Caption +#. frmMain..ActionList1..acOptionsSourceFormat..Category +#. frmMain..ActionList1..acOptionsTargetFormat..Category +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Category +#: main.dfm:68 +#: main.dfm:229 +#: main.dfm:1418 +#: main.dfm:1423 +#: main.dfm:1437 +msgid "Options" +msgstr "Optionen" + +#. frmMain..pnTop..gbInput..lbInputFormat..Caption +#. frmMain..pnTop..gbOutput..lbOutputFormat..Caption +#: main.dfm:76 +#: main.dfm:259 +msgid "Format" +msgstr "Format" + +#. frmMain..pnTop..gbInput..lbInputFile..Caption +#. frmMain..pnTop..gbOutput..lbOutputFile..Caption +#. frmMain..ActionList1..acFileExit..Category +#. frmMain..ActionList1..acFileClearMemo..Category +#. frmMain..ActionList1..acFileOutputToScreen..Category +#. frmMain..ActionList1..acFileChangeLanguage..Category +#. frmMain..ActionList1..acFileExportCSV..Category +#: main.dfm:83 +#: main.dfm:266 +#: main.dfm:1399 +#: main.dfm:1428 +#: main.dfm:1443 +#: main.dfm:1455 +#: main.dfm:1460 +#: main.pas:865 +#: main.pas:919 +msgid "File" +msgstr "Datei" + +#. frmMain..pnTop..gbInput..chbInputDevice..Hint +#: main.dfm:112 +msgid "Read data from device instead from file" +msgstr "Dateneingabe von \"Gerät\"" + +#. frmMain..pnTop..gbInput..chbInputDevice..Caption +#. frmMain..pnTop..gbOutput..chbOutputDevice..Caption +#: main.dfm:115 +#: main.dfm:299 +msgid "Device" +msgstr "Gerät" + +#. frmMain..pnTop..gbInput..edInputOpts..Hint +#: main.dfm:124 +msgid "Options for the selected input format" +msgstr "Optionen für das gewählte Eingabe-Format" + +#. frmMain..pnTop..gbInput..edInputFile..Hint +#: main.dfm:135 +msgid "Read data from given filename" +msgstr "Lese Daten von Datei ..." + +#. frmMain..pnTop..gbInput..cbInputLang..Hint +#: main.dfm:146 +msgid "Characterset for input data" +msgstr "Zeichensatz für Eingangsdaten (nicht jedes Format unterstützt dies!)" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:152 +#: main.dfm:363 +msgid "- default -" +msgstr "- Standard -" + +#. frmMain..pnTop..gbInput..cbInputDevice..Hint +#: main.dfm:179 +msgid "Read data from device ..." +msgstr "lese von Interface/Anschluß..." + +#. frmMain..pnTop..gbInput..cbInputFormatDevice..Hint +#: main.dfm:194 +msgid "Format for input from device" +msgstr "Eingabeformat des angeschlossenen Gerätes" + +#. frmMain..pnTop..gbInput..cbInputFormat..Hint +#: main.dfm:208 +msgid "Format for input from file" +msgstr "zu benutzendes Eingabeformat" + +#. frmMain..pnTop..gbOutput..Caption +#: main.dfm:222 +#: main.pas:271 +#: main.pas:276 +#: main.pas:476 +#: main.pas:922 +msgid "Output" +msgstr "Ausgabe" + +#. frmMain..pnTop..gbOutput..sbSaveFile..Hint +#: main.dfm:273 +msgid "Start the file save dialog" +msgstr "Die zu schreibende Datei auswählen" + +#. frmMain..pnTop..gbOutput..chbOutputDevice..Hint +#: main.dfm:296 +msgid "Write data to device instead to file" +msgstr "Datenausgabe auf \"Gerät\"" + +#. frmMain..pnTop..gbOutput..cbOutputFormatDevice..Hint +#: main.dfm:309 +msgid "Format for ouput to device" +msgstr "Ausgabeformat für angeschlossenes Gerät" + +#. frmMain..pnTop..gbOutput..edOutputOpts..Hint +#: main.dfm:321 +msgid "Options for the selected output format" +msgstr "Optionen für das gewählte Ausgabeformat" + +#. frmMain..pnTop..gbOutput..cbOutputFormat..Hint +#: main.dfm:332 +msgid "Format for output to file" +msgstr "zu benutzendes Ausgabeformat" + +#. frmMain..pnTop..gbOutput..edOutputFile..Hint +#: main.dfm:345 +msgid "Write data to given filename" +msgstr "Dateiname für Datenausgabe" + +#. frmMain..pnTop..gbOutput..cbOutputLang..Hint +#: main.dfm:357 +msgid "Characterset for output data" +msgstr "Zeichensatz für Ausgangsdaten (nicht jedes Format unterstützt dies!)" + +#. frmMain..pnTop..gbOutput..cbOutputDevice..Hint +#: main.dfm:390 +msgid "Write data to device ..." +msgstr "schreibe nach Interface/Anschluß" + +#. frmMain..pnBottom..lbWhat..Caption +#: main.dfm:415 +msgid "What ?" +msgstr "Was?" + +#. frmMain..pnBottom..cbWaypoints..Hint +#: main.dfm:554 +msgid "Process waypoint information" +msgstr "Wegpunkte in Konvertierung einschließen" + +#. frmMain..pnBottom..cbRoutes..Hint +#: main.dfm:568 +msgid "Process route information" +msgstr "Routen in Konvertierung einschließen" + +#. frmMain..pnBottom..cbRoutes..Caption +#: main.dfm:569 +msgid "&Routes" +msgstr "&Routen" + +#. frmMain..pnBottom..cbTracks..Hint +#: main.dfm:580 +msgid "Process track information" +msgstr "Tracks in Konvertierung einschließen" + +#. frmMain..pnBottom..btnFilter..Caption +#. frmMain..ActionList1..acFilterSelect..Caption +#: main.dfm:594 +#: main.dfm:1393 +msgid "&Filter" +msgstr "&Filter" + +#. frmMain..pnBottom..btnProcess..Hint +#: main.dfm:638 +msgid "Start data conversion" +msgstr "Konvertierung starten" + +#. frmMain..pnBottom..btnProcess..Caption +#. frmMain..ActionList1..acConvert..Caption +#: main.dfm:641 +#: main.dfm:1386 +msgid "let's go" +msgstr "und los" + +#. frmMain..OpenDialog..Filter +#: main.dfm:701 +msgid "Garmin Mapsource mps|*.mps|All files|*.*" +msgstr "Garmin Mapsource mps|*.mps|Alle Dateien|*.*" + +#. frmMain..SaveDialog..Filter +#: main.dfm:707 +msgid "All file(s)|*.*|Garmin MapSource mps|*.mps" +msgstr "Alle Dateien|*.*|Garmin MapSource mps|*.mps" + +#. frmMain..ActionList1..acConvert..Category +#. frmMain..ActionList1..acFilterSelect..Category +#: main.dfm:1385 +#: main.dfm:1392 +msgid "Babel" +msgstr "Babel" + +#. frmMain..ActionList1..acFilterSelect..Hint +#: main.dfm:1394 +msgid "Filter incomming data before writing them to file or device" +msgstr "gelesene Daten filtern" + +#. frmMain..ActionList1..acFileExit..Caption +#: main.dfm:1400 +msgid "E&xit" +msgstr "Beenden" + +#. frmMain..ActionList1..acHelpAbout..Category +#. frmMain..ActionList1..acHelpIntro..Category +#. frmMain..ActionList1..acHelpReadme..Category +#: main.dfm:1404 +#: main.dfm:1409 +#: main.dfm:1413 +msgid "Help" +msgstr "Hilfe" + +#. frmMain..ActionList1..acHelpAbout..Caption +#: main.dfm:1405 +msgid "&About" +msgstr "Über" + +#. frmMain..ActionList1..acHelpIntro..Caption +#: main.dfm:1410 +msgid "&Intro" +msgstr "Einführung" + +#. frmMain..ActionList1..acHelpReadme..Caption +#. frmReadme..Caption +#: main.dfm:1414 +#: readme.dfm:6 +msgid "GPSBabel README" +msgstr "GPSBabel README" + +#. frmMain..ActionList1..acOptionsSourceFormat..Caption +#: main.dfm:1419 +msgid "... for source format" +msgstr "... für Quellformat" + +#. frmMain..ActionList1..acOptionsTargetFormat..Caption +#: main.dfm:1424 +msgid "... for target format" +msgstr "... für Zielformat" + +#. frmMain..ActionList1..acFileClearMemo..Caption +#: main.dfm:1429 +msgid "Clear output" +msgstr "Meldungen löschen" + +#. frmMain..ActionList1..acFileClearMemo..Hint +#: main.dfm:1430 +msgid "Clear messages" +msgstr "Meldungen löschen" + +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Caption +#: main.dfm:1438 +msgid "Enable characterset transformation" +msgstr "Zeichensatz transformieren" + +#. frmMain..ActionList1..acFileOutputToScreen..Caption +#: main.dfm:1444 +msgid "Output to screen" +msgstr "Ausgabe auf Bildschirm" + +#. frmMain..ActionList1..acFileChangeLanguage..Caption +#: main.dfm:1456 +msgid "Change language" +msgstr "Sprache ändern" + +#. frmMain..ActionList1..acFileExportCSV..Caption +#: main.dfm:1461 +msgid "Export gpsbabel.csv (unicode)" +msgstr "" + +#. frmMain..MainMenu1..mnuFile..Caption +#: main.dfm:1469 +msgid "&File" +msgstr "&Datei" + +#. frmMain..MainMenu1..mnuFile..File1..Caption +#: main.dfm:1477 +msgid "Export" +msgstr "Export" + +#. frmMain..MainMenu1..mnuOptions..Caption +#: main.dfm:1498 +msgid "&Options" +msgstr "&Optionen" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames..Caption +#: main.dfm:1500 +msgid "Synthesize shortnames" +msgstr "Synthetisiere Kurznamen" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames....Hint +#: main.dfm:1503 +msgid "Ignore shortnames from source data and synthesize them from description or notes" +msgstr "Ignoriere alle \"Kurznamen\" und generiere diese neu aus Bechreibung oder Bemerkung" + +#. frmMain..MainMenu1..mnuOptions..mnuOptionsForceDataType..Caption +#: main.dfm:1507 +msgid "Force selected GPS data types (nuketypes filter)" +msgstr "Erzwinge Selektion(en)" + +#. frmMain..MainMenu1..mnuHelp..Caption +#: main.dfm:1548 +msgid "&Help" +msgstr "&Hilfe" + +#. frmOptions..Caption +#: options.dfm:5 +msgid "Options for ..." +msgstr "Optionen für ..." + +#. frmSelect..pnBottom..btnCancel..Caption +#: select.dfm:66 +msgid "Abort" +msgstr "Abbrechen" + +#: about.pas:87 +#: select.pas:81 +msgid "German" +msgstr "Deutsch" + +#: about.pas:88 +#: select.pas:83 +msgid "French" +msgstr "Französisch" + +#: about.pas:89 +#: select.pas:82 +msgid "Spanish" +msgstr "Spanisch" + +#: about.pas:90 +#: select.pas:85 +msgid "Hungarian" +msgstr "Ungarisch" + +#: about.pas:132 +msgid "" +"Please have a look at the file README.GUI.\n" +"\n" +"There you will find all information you need to\n" +"get GPSBabelGUI working in your own language." +msgstr "" +"Werfen Sie einen kurzen Blick in die Datei \"README.GUI\"\n" +"\n" +"Dort finden Sie alle nötigen Informationen, um\n" +"GPSBabelGUI eine neue Sprache beizubringen." + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:184 +#: filter.pas:185 +msgid "Waypoints" +msgstr "Wegpunkte" + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:182 +#: filter.pas:183 +msgid "Routes" +msgstr "Routen" + +#: filter.pas:182 +#: filter.pas:183 +#: filter.pas:184 +#: filter.pas:185 +msgid "Tracks" +msgstr "Tracks" + +#: filter.pas:224 +msgid "Feet" +msgstr "\"Feet\" (engl.)" + +#: filter.pas:225 +msgid "Meter" +msgstr "Meter" + +#: filter.pas:228 +msgid "Miles" +msgstr "Meilen" + +#: filter.pas:229 +msgid "Kilometer" +msgstr "Kilometer" + +#: filter.pas:239 +msgid "Not supported by gpsbabel.exe, release %s!" +msgstr "Wird von gpsbabel.exe, Version %s, nicht unterstützt!" + +#: filter.pas:288 +msgid "Value (%s) out of range (%g to %g)!" +msgstr "Wert (%s) liegt außerhalb des zulässigen Bereiches (%g to %g)!" + +#: filter.pas:593 +#: options.pas:661 +msgid "Discard changes?" +msgstr "Änderungen verwerfen?" + +#: main.pas:244 +msgid "Internal development release" +msgstr "Interne Entwicklungsausgabe" + +#: main.pas:246 +msgid "BETA" +msgstr "BETA" + +#: main.pas:248 +msgid "Private release" +msgstr "Private Version" + +#: main.pas:250 +msgid "Special release" +msgstr "Spezial-Version" + +#: main.pas:342 +msgid "The file \"gpsbabel.exe\" found in current directory is too old!" +msgstr "Die Datei \"gpsbabel.exe\" ist zu alt für diese GUI!" + +#: main.pas:416 +#: main.pas:550 +msgid "All files|*.*" +msgstr "Alle Dateien|*.*" + +#: main.pas:484 +msgid "Select and edit options for \"%s\"" +msgstr "Optionen von \"%s\" bearbeiten" + +#: main.pas:488 +msgid "No options available for \"%s\"" +msgstr " \"%s\" hat keine Optionen!" + +#. s := s + '-1'; +#: main.pas:603 +msgid "File %s not found." +msgstr "Datei \"%s\" nicht gefunden." + +#: main.pas:664 +msgid "File \"%s\" exists ! Overwrite ?" +msgstr "Datei \"%s\" existiert bereits! Überschreiben?" + +#: main.pas:665 +msgid "Warning" +msgstr "Warnung" + +#: main.pas:698 +msgid "Could not run \"gpsbabel.exe\"!" +msgstr "Konnte \"gpsbabel.exe\" nicht ausführen!" + +#: main.pas:707 +msgid "Sorry, gpsbabel.exe reported problems!" +msgstr "Uhps, da ging etwas schief!" + +#: main.pas:709 +msgid "Converted successfully from \"%s\" to \"%s\"." +msgstr "Erfolgreich konvertiert von \"%s\" zu \"%s\"." + +#: main.pas:820 +msgid "GPSBabel, version %s" +msgstr "GPSBabel, Version %s" + +#: main.pas:854 +#: main.pas:909 +msgid "Port" +msgstr "Schnittstelle" + +#: main.pas:1013 +msgid "Options for \"%s\"" +msgstr "Optionen für \"%s\"" + +#: main.pas:1203 +#: main.pas:1273 +msgid "Choose language" +msgstr "Wähle Sprache" + +#: main.pas:1203 +msgid "for GUIBabelGUI" +msgstr "für GPSBabelGUI" + +#: main.pas:1273 +msgid "for export" +msgstr "für Export" + +#. override; +#: options.pas:147 +msgid "Be aware, that most options are made for the output side. " +msgstr "Achtung: die meisten Optionen sind vermutlich für die Datenausgabe gedacht." + +#: options.pas:148 +msgid "Currently we don't have a flag which tells us which direction is used by the options." +msgstr "Wir verfügen z.Z. über kein Merkmal über die Arbeitsweise der Optionen." + +#: options.pas:208 +msgid "Short \"%s\"" +msgstr "Abkürzung \"%s\"" + +#: options.pas:332 +msgid "Invalid line format!" +msgstr "Ungültiger Zeilenaufbau!" + +#: options.pas:353 +msgid "Unknown option \"%s\"!" +msgstr "Unbekannte Option \"%s\"!" + +#: select.pas:84 +msgid "English" +msgstr "Englisch" + +#: utils.pas:119 +msgid "Error WINAPI: Could not create \"NamedPipe\"!" +msgstr "Fehler WINAPI: \"NamedPipe\" konnte nicht erstellt werden!" + +#: utils.pas:124 +msgid "\"gpsbabel.exe\" not found!!!" +msgstr "\"gpsbabel.exe\" wurde nicht gefunden!!!" + +#. dwCreationFlags, // creation flags +#: utils.pas:143 +msgid "Could not run \"gpsbabel.exe\" (Error %d)!" +msgstr "Konnte \"gpsbabel.exe\" nicht ausführen (Fehler %d)!" + +#: utils.pas:176 +msgid "\"gpsbabel.exe\" returned error 0x%x (%d)" +msgstr "\"gpsbabel.exe\" verließ uns mit Fehler 0x%x (%d)!" + diff --git a/win32/gui-2/locale/de/LC_MESSAGES/delphi.po b/win32/gui-2/locale/de/LC_MESSAGES/delphi.po new file mode 100644 index 000000000..6dbc9851a --- /dev/null +++ b/win32/gui-2/locale/de/LC_MESSAGES/delphi.po @@ -0,0 +1,10164 @@ +msgid "" +msgstr "" +"Project-Id-Version: Delphi 5 german\n" +"POT-Creation-Date: 2003-03-04 15:18\n" +"PO-Revision-Date: 2006-04-14 14:12+0100\n" +"Last-Translator: Olaf Klein \n" +"Language-Team: XAN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" + +#. Programmer's name for it: sRowError +#: Decision Cube/mxconsts.pas:27 +msgid "row error" +msgstr "Zeilenfehler" + +#. Programmer's name for it: sAllValues +#: Decision Cube/mxconsts.pas:29 +msgid "All Values" +msgstr "Alle Werte" + +#. Programmer's name for it: sMovetoRow +#: Decision Cube/mxconsts.pas:30 +msgid "Move to Row Area" +msgstr "Zum Zeilenbereich" + +#. Programmer's name for it: sMovetoCol +#: Decision Cube/mxconsts.pas:31 +msgid "Move to Column Area" +msgstr "Zum Spaltenbereich" + +#. Programmer's name for it: sMakeDimOpen +#: Decision Cube/mxconsts.pas:32 +msgid "Open Dimension" +msgstr "Dimension öffnen" + +#. Programmer's name for it: sDrilled +#: Decision Cube/mxconsts.pas:33 +msgid "Drilled In" +msgstr "Untersucht" + +#. Programmer's name for it: sCouldNotOpen +#: Decision Cube/mxconsts.pas:34 +msgid "The information requested could not be loaded. " +msgstr "Die angeforderte Information konnte nicht geladen werden." + +#. Programmer's name for it: sNoSumsAvailable +#: Decision Cube/mxconsts.pas:35 +msgid "No active summaries have been defined. " +msgstr "Es wurden keine aktiven Zusammenfassungen definiert." + +#. Programmer's name for it: sNoSumsCouldBeLoaded +#: Decision Cube/mxconsts.pas:36 +msgid "Not enough room available to load a summary. " +msgstr "Es steht nicht genügend Speicher zur Verfügung, um eine Zusammenfassung zu laden." + +#. Programmer's name for it: sNoDimsAvailable +#: Decision Cube/mxconsts.pas:37 +msgid "No available dimensions have been defined. " +msgstr "Es wurden keine verfügbaren Dimensionen definiert." + +#. Programmer's name for it: sNoDimsCouldBeLoaded +#: Decision Cube/mxconsts.pas:38 +msgid "Not enough space available to load a dimension. " +msgstr "Es steht nicht genügend Speicher zur Verfügung, um eine Dimension zu laden." + +#. Programmer's name for it: sTemplatePrefix +#: Decision Cube/mxconsts.pas:40 +msgid "Template: " +msgstr "Vorlage: " + +#. Programmer's name for it: sGridCellError +#: Decision Cube/mxconsts.pas:42 +msgid "[Error]" +msgstr "[Fehler]" + +#. Programmer's name for it: sTotalCaption +#: Decision Cube/mxconsts.pas:43 +msgid "Sum" +msgstr "Summe" + +#. Programmer's name for it: sActivateLabel +#: Decision Cube/mxconsts.pas:44 +msgid "Inactive Dimensions" +msgstr "Nicht aktive Dimensionen" + +#. Programmer's name for it: sRowCaption +#: Decision Cube/mxconsts.pas:45 +msgid "R" +msgstr "R" + +#. Programmer's name for it: sColCaption +#: Decision Cube/mxconsts.pas:46 +msgid "C" +msgstr "K" + +#. Programmer's name for it: sCaptionMenu1 +#: Decision Cube/mxconsts.pas:47 +msgid "Display Data and Subtotals" +msgstr "Daten und Zwischensummen anzeigen" + +#. Programmer's name for it: sCaptionMenu2 +#: Decision Cube/mxconsts.pas:48 +msgid "Display Data Only" +msgstr "Nur Daten anzeigen" + +#. Programmer's name for it: sCaptionMenu3 +#: Decision Cube/mxconsts.pas:49 +msgid "Display Subtotals Only" +msgstr "Nur Zwischensummen anzeigen" + +#. Programmer's name for it: sDrillIn +#: Decision Cube/mxconsts.pas:50 +msgid "Drill in to this value" +msgstr "Diesen Wert untersuchen" + +#. Programmer's name for it: sGridMenu1 +#: Decision Cube/mxconsts.pas:51 +msgid "Subtotals on/off" +msgstr "Zwischensummen an/aus" + +#. Programmer's name for it: sGridMenu2 +#: Decision Cube/mxconsts.pas:52 +msgid "Decision Cube Editor.." +msgstr "Editor für Entscheidungswürfel..." + +#. Programmer's name for it: sGridMenu3 +#: Decision Cube/mxconsts.pas:53 +msgid "Decision Query Editor.." +msgstr "Editor für Entscheidungsabfrage..." + +#. Programmer's name for it: sGridMenu4 +#: Decision Cube/mxconsts.pas:54 +msgid "Show Detail Records.." +msgstr "Detaildatensätze anzeigen..." + +#. Programmer's name for it: sUnsupportedDataType +#: Decision Cube/mxconsts.pas:57 +msgid "Unsupported data type : %s" +msgstr "Nicht unterstützter Datentyp: %s" + +#. Programmer's name for it: sRowOutOfRange +#: Decision Cube/mxconsts.pas:58 +msgid "Row index out of range : %d" +msgstr "Zeilenindex außerhalb des gültigen Bereichs: %d" + +#. Programmer's name for it: sColOutOfRange +#: Decision Cube/mxconsts.pas:59 +msgid "Column index out of range : %d" +msgstr "Spaltenindex außerhalb des gültigen Bereichs: %d" + +#. Programmer's name for it: sDupeItem +#: Decision Cube/mxconsts.pas:60 +msgid "Duplicate item in array" +msgstr "Im Array befinden sich Doppeleinträge" + +#. Programmer's name for it: sArrayIndexOutOfRange +#: Decision Cube/mxconsts.pas:61 +msgid "Array index out of range : %d" +msgstr "Array-Index außerhalb des gültigen Bereichs: %d" + +#. Programmer's name for it: sLowCapacityError +#: Decision Cube/mxconsts.pas:62 +msgid "The DecisionCube Capacity is low. Please deactivate dimensions or change the data set." +msgstr "Die Kapazität des Entscheidungswürfels ist erschöpft. Deaktivieren Sie einige Dimensionen oder ändern Sie die Datenmenge." + +#. Programmer's name for it: sQryNotInitialized +#: Decision Cube/mxconsts.pas:63 +msgid "Query could not be run. Check that the query, SQL text, and Database are correct." +msgstr "Die Abfrage konnte nicht gestartet werden. Überprüfen Sie, ob Abfrage, SQL-Text und Datenbank korrekt sind." + +#. Programmer's name for it: sSortedListError +#: Decision Cube/mxconsts.pas:64 +msgid "Operation not allowed on sorted string list." +msgstr "Diese Operation ist bei einer sortierten String-Liste nicht erlaubt." + +#. Programmer's name for it: sDuplicateString +#: Decision Cube/mxconsts.pas:65 +msgid "String list does not allow duplicates." +msgstr "Die String-Liste lässt keine Doppeleinträge zu." + +#. Programmer's name for it: sMaxAllowedSums +#: Decision Cube/mxconsts.pas:66 +msgid "The maximum allowed summaries of %d has been exceeded." +msgstr "Das erlaubte Maximum an Zusammenfassungen (%d) wurde überschritten." + +#. Programmer's name for it: sGeneralArrayError +#: Decision Cube/mxconsts.pas:67 +msgid "General array error." +msgstr "Allgemeiner Fehler im Array." + +#. Programmer's name for it: sDimIndexError +#: Decision Cube/mxconsts.pas:70 +msgid "Illegal Dimension Index" +msgstr "Ungültiger Dimensionsindex" + +#. Programmer's name for it: sIllegalValueForBin +#: Decision Cube/mxconsts.pas:73 +msgid "Initial Value is not legal for this type of Grouping" +msgstr "Der Anfangswert ist für diesen Gruppierungstyp nicht erlaubt" + +#. Programmer's name for it: sIllegalDimMap +#: Decision Cube/mxconsts.pas:74 +msgid "Dimension Map is not the correct size" +msgstr "Die Größe der Dimensionszuweisung ist nicht korrekt" + +#. Programmer's name for it: sDimMapActiveError +#: Decision Cube/mxconsts.pas:75 +msgid "Cannot perform this action on an active Dimension Map" +msgstr "Diese Aktion kann nicht auf eine aktive Dimensionszuweisung angewendet werden" + +#. Programmer's name for it: sNotAvailable +#: Decision Cube/mxconsts.pas:76 +msgid "Not Available" +msgstr "Nicht verfügbar" + +#. Programmer's name for it: sGetValueCounts +#: Decision Cube/mxconsts.pas:77 +msgid "Information required to do Maximum Cell limit is not current. Do you want to fetch it now?" +msgstr "Die Information für das Berechnen des Zellmaximums ist nicht mehr aktuell. Soll diese Information aktualisiert werden?" + +#. Programmer's name for it: sDateBinningNotAllowed +#: Decision Cube/mxconsts.pas:78 +msgid "Date grouping is not allowed for fields of this type" +msgstr "Die Gruppierung nach Datum ist für diesen Feldtyp nicht erlaubt" + +#. Programmer's name for it: sEmptyDataSet +#: Decision Cube/mxconsts.pas:79 +msgid "Cannot build the Decision Cube with an empty data set" +msgstr "Der Entscheidungswürfel kann nicht mit einer leeren Datenmenge erstellt werden" + +#. Programmer's name for it: sNoDataSet +#: Decision Cube/mxconsts.pas:82 +msgid "Data set property is not assigned" +msgstr "Der Eigenschaft Data Set wurde kein Wert zugewiesen" + +#. Programmer's name for it: sNoAggs +#: Decision Cube/mxconsts.pas:83 +msgid "No summaries are defined. " +msgstr "Es sind keine Zusammenfassungen definiert." + +#. Programmer's name for it: sNoDims +#: Decision Cube/mxconsts.pas:84 +msgid "No dimension fields are defined. " +msgstr "Es sind keine Dimensionsfelder definiert." + +#. Programmer's name for it: sUnknownDims +#: Decision Cube/mxconsts.pas:85 +msgid "The dimension types for this dataset cannot be determined automatically. You must map the fields to dimensions or summaries with the Decision Cube Editor" +msgstr "Die Dimensionstypen für diese Datenmenge können nicht automatisch festgelegt werden. Sie müssen diese Felder mit dem Editor für Entscheidungswürfel einer Dimension oder Zusammenfassung zuweisen." + +#. Programmer's name for it: sGroupsMissing +#: Decision Cube/mxconsts.pas:86 +msgid "All dimension fields must be grouped. " +msgstr "Alle Dimensionsfelder müssen gruppiert werden." + +#. Programmer's name for it: sDecisionQueryError +#. Programmer's name for it: sQueryError +#. Programmer's name for it: sDecisionQueryError +#. Programmer's name for it: sQueryError +#: Decision Cube/mxconsts.pas:87 +#: Vcl/mxconsts.pas:89 +msgid "The query may be incorrectly defined, or you may need to map its fields to active dimensions or summaries with the Decision Cube Editor" +msgstr "Die Abfrage wurde inkorrekt definiert oder die Felder der Abfrage müssen mit dem Editor für Entscheidungswürfel aktiven Dimensionen oder Zusammenfassungen zugewiesen werden" + +#. Programmer's name for it: sDataSetError +#: Decision Cube/mxconsts.pas:88 +msgid "The dataset may be incorrectly defined, or you may need to map its fields to active dimensions or summaries with the Decision Cube Editor" +msgstr "Die Datenmenge wurde inkorrekt definiert oder die Felder müssen mit dem Editor für Entscheidungswürfel aktiven Dimensionen oder Zusammenfassungen zugewiesen werden" + +#. Programmer's name for it: sCountStar +#: Decision Cube/mxconsts.pas:90 +msgid "COUNTALL" +msgstr "COUNTALL" + +#. Programmer's name for it: sAddAvgWarning +#: Decision Cube/mxconsts.pas:91 +msgid "Average is calculated using sum and count summaries for each field. The necessary summaries have been added." +msgstr "Der Mittelwert wird durch Ermittlung der Summe und der Anzahl für jedes Feld ermittelt. Die dazu notwendigen Zusammenfassungen wurden hinzugefügt." + +#. Programmer's name for it: sAddAvgStarWarning +#: Decision Cube/mxconsts.pas:92 +msgid "Average is calculated using a field sum and count(*). The necessary summaries have been added." +msgstr "Der Mittelwert wird durch Ermittlung der Feldsumme und count(*) ermittelt. Die dazu notwendigen Zusammenfassungen wurden hinzugefügt." + +#. Programmer's name for it: sQueryLegal +#: Decision Cube/mxconsts.pas:95 +msgid "Query is legal." +msgstr "Die Abfrage ist gültig." + +#. Programmer's name for it: sAddFieldExists +#: Decision Cube/mxconsts.pas:96 +msgid " is already in the query" +msgstr " ist bereits in der Abfrage" + +#. Programmer's name for it: sAggTypeNotAllowed +#: Decision Cube/mxconsts.pas:97 +msgid " is not an allowed summary type" +msgstr " ist kein erlaubter Zusammenfassungstyp" + +#. Programmer's name for it: sDimTypeNotAllowed +#: Decision Cube/mxconsts.pas:98 +msgid " is not an allowed dimension type" +msgstr " ist kein erlaubter Dimensionstyp" + +#. Programmer's name for it: sAverageRequires +#: Decision Cube/mxconsts.pas:99 +msgid "Average summaries use Sum and Count" +msgstr "Mittelwert verwendet Summe und Anzahl" + +#. Programmer's name for it: sWantToExit +#: Decision Cube/mxconsts.pas:100 +msgid "Do you still want to Exit?" +msgstr "Wollen Sie wirklich beenden?" + +#. Programmer's name for it: sQueryIllegal +#: Decision Cube/mxconsts.pas:101 +msgid "The query you have created is not legal." +msgstr "Die von Ihnen erstellte Abfrage ist ungültig." + +#. Programmer's name for it: sQueryEditIllegal +#: Decision Cube/mxconsts.pas:102 +msgid "The query you have entered is not legal. Please correct it before continuing." +msgstr "Die eingegebene Abfrage ist ungültig. Sie muß geändert werden, bevor Sie weitermachen." + +#. Programmer's name for it: sRemoveFieldError +#: Decision Cube/mxconsts.pas:103 +msgid "Could not remove the field" +msgstr "Das Feld konnte nicht entfernt werden" + +#. Programmer's name for it: sAllFields +#: Decision Cube/mxconsts.pas:104 +msgid "All Fields" +msgstr "&Alle Felder" + +#. Programmer's name for it: sQueryFields +#: Decision Cube/mxconsts.pas:105 +msgid "Query Fields" +msgstr "Felder abfragen" + +#. Programmer's name for it: sEditDone +#: Decision Cube/mxconsts.pas:106 +msgid "&Edit Done" +msgstr "Bearbeitung &abschließen" + +#. Programmer's name for it: sEditQuery +#. DSSQueryEditor..Pager..Query..EditQry..Caption +#: Decision Cube/mxconsts.pas:107 +msgid "&Edit Query" +msgstr "Ab&frage bearbeiten" + +#. Programmer's name for it: sQParseRemovedField +#: Decision Cube/mxconsts.pas:110 +msgid "One or more fields of a type which cannot be tabulated were removed from the query." +msgstr "Ein oder mehrere Felder wurden aus der Abfrage entfernt, da sie nicht tabularisiert werden konnten." + +#. Programmer's name for it: sCubeLimitsExceeded +#: Decision Cube/mxconsts.pas:113 +msgid "Decision Cube size excedes limits" +msgstr "Der Entscheidungswürfel überschreitet seine Kapazität" + +#. Programmer's name for it: sMaxAllowedDims +#: Decision Cube/mxconsts.pas:114 +msgid "The maximum allowed dimensions of %d has been exceeded." +msgstr "Das erlaubte Maximum an Dimensionen (%d) wurde überschritten." + +#. Programmer's name for it: sMaxAllowedCells +#: Decision Cube/mxconsts.pas:115 +msgid "Total cell count of %d exceeds the maximum of %d." +msgstr "Die Gesamtanzahl an Zellen von %d überschreitet das Maximum von %d." + +#. Programmer's name for it: sUnsupportedFieldType +#: Decision Cube/mxconsts.pas:116 +msgid "Field %s has an unsupported data type: %s" +msgstr "Feld %s ist vom nicht unterstützten Datentyp %s" + +#. Programmer's name for it: sFetchValues +#: Decision Cube/mxconsts.pas:117 +msgid "Scanning data set values..." +msgstr "Datenwerte analysieren..." + +#. Programmer's name for it: sUserCanceled +#: Decision Cube/mxconsts.pas:118 +msgid "User canceled DecisionCube population." +msgstr "Das Füllen des Entscheidungswürfels wurde durch den Anwender unterbrochen." + +#. Programmer's name for it: sBinningValues +#: Decision Cube/mxconsts.pas:119 +msgid "Grouping values ..." +msgstr "Werte gruppieren..." + +#. Programmer's name for it: sCreatingIndexes +#: Decision Cube/mxconsts.pas:120 +msgid "Creating Cube index for %s ..." +msgstr "Erstellen des Würfelindex für %s..." + +#. Programmer's name for it: sCreateDerivedSummaryError +#: Decision Cube/mxconsts.pas:121 +msgid "Unable to create derived summary." +msgstr "Abgeleitete Zusammenfassung konnte nicht erzeugt werden." + +#. Programmer's name for it: sTrue +#. Programmer's name for it: STextTrue +#. Programmer's name for it: sTrue +#: Decision Cube/mxconsts.pas:122 +msgid "True" +msgstr "Wahr" + +#. Programmer's name for it: sFalse +#. Programmer's name for it: STextFalse +#. Programmer's name for it: sFalse +#: Decision Cube/mxconsts.pas:123 +msgid "False" +msgstr "Falsch" + +#. Programmer's name for it: sBinTypeMismatch +#: Decision Cube/mxconsts.pas:124 +msgid "The bin type does not match the fieldtype." +msgstr "Der Gruppierungstyp entspricht nicht dem Feldtyp." + +#. Programmer's name for it: sFatalCacheError +#: Decision Cube/mxconsts.pas:125 +msgid "Fatal error in cache: code: %d" +msgstr "Schwerer Fehler im Cache: Code: %d" + +#. Programmer's name for it: sStringTypeNoSupported +#: Decision Cube/mxconsts.pas:126 +msgid "String Data type not supported for summaries" +msgstr "Datentyp String wird von Zusammenfassungen nicht unterstützt" + +#. Programmer's name for it: sDataSetTooLarge +#: Decision Cube/mxconsts.pas:127 +msgid "Dataset is too large" +msgstr "Datenmenge ist zu groß" + +#. Programmer's name for it: sBuildingDataStore +#: Decision Cube/mxconsts.pas:128 +msgid "Building data store..." +msgstr "Datenspeicher aufbauen..." + +#. Programmer's name for it: sSumLabel +#: Decision Cube/mxconsts.pas:131 +msgid "Sum of %s" +msgstr "Summe von %s" + +#. Programmer's name for it: sCountLabel +#: Decision Cube/mxconsts.pas:132 +msgid "Count of %s" +msgstr "Anzahl von %s" + +#. Programmer's name for it: sMaxLabel +#: Decision Cube/mxconsts.pas:133 +msgid "Maximum of %s" +msgstr "Maximum von %s" + +#. Programmer's name for it: sMinLabel +#: Decision Cube/mxconsts.pas:134 +msgid "Minimum of %s" +msgstr "Minimum von %s" + +#. Programmer's name for it: sAverageLabel +#: Decision Cube/mxconsts.pas:135 +msgid "Average of %s" +msgstr "Mittelwert von %s" + +#. Programmer's name for it: sVarLabel +#: Decision Cube/mxconsts.pas:136 +msgid "Variance of %s" +msgstr "Varianz von %s" + +#. Programmer's name for it: sSDLabel +#: Decision Cube/mxconsts.pas:137 +msgid "Standard Deviation of %s" +msgstr "Standardabweichung von %s" + +#. Programmer's name for it: sAggLabel +#: Decision Cube/mxconsts.pas:138 +msgid "Summary of %s" +msgstr "Zusammenfassung von: %s" + +#. Programmer's name for it: sUnsupportedVarType +#: Decision Cube/mxconsts.pas:139 +msgid "Unsupported Data Type %d" +msgstr "Nicht unterstützter Datentyp: %d" + +#. Programmer's name for it: sOtherValues +#: Decision Cube/mxconsts.pas:140 +msgid "Other Values" +msgstr "Andere Werte" + +#. Programmer's name for it: sSelectFromError +#: Decision Cube/mxconsts.pas:142 +msgid "Query lacks a Select/From clause." +msgstr "Der Abfrage fehlt eine Select/From-Klausel." + +#. Programmer's name for it: sArgumentExpected +#: Decision Cube/mxconsts.pas:143 +msgid "No argument provided for an operator or summary" +msgstr "Für einen Operator oder eine Zusammenfassung fehlt ein Argument" + +#. Programmer's name for it: sGroupOnExpressionError +#: Decision Cube/mxconsts.pas:144 +msgid "An expression cannot be used for a grouping field" +msgstr "Ein Ausdruck kann nicht zum Gruppieren eines Feldes verwendet werden" + +#. Programmer's name for it: SOutofBounds +#: Decision Cube/mxconsts.pas:146 +msgid "Out of Bounds" +msgstr "Außerhalb des Bereichs" + +#. Programmer's name for it: sIDAPILangID +#. Programmer's name for it: SIDAPILangID +#. Programmer's name for it: sIDAPILangID +#: Decision Cube/mxconsts.pas:147 +msgid "0009" +msgstr "0007" + +#. Programmer's name for it: sComponentTabName +#: Decision Cube/mxdconst.pas:14 +msgid "Decision Cube" +msgstr "Datenanalyse" + +#. Programmer's name for it: sQueryVerb0 +#: Decision Cube/mxdconst.pas:15 +msgid "&Graphical Query Builder..." +msgstr "&Grafischer Abfragegenerator..." + +#. Programmer's name for it: sQueryVerb1 +#: Decision Cube/mxdconst.pas:16 +msgid "&Decision Query Editor..." +msgstr "&Editor für Entscheidungsabfrage..." + +#. Programmer's name for it: sCubeVerb0 +#: Decision Cube/mxdconst.pas:17 +msgid "&Decision Cube Editor..." +msgstr "&Editor für Entscheidungsanalyse..." + +#. Programmer's name for it: sCubeVerb1 +#: Decision Cube/mxdconst.pas:18 +msgid "&Query Editor..." +msgstr "Abfragee&ditor..." + +#. Programmer's name for it: sGridVerb0 +#: Decision Cube/mxdconst.pas:19 +msgid "Sub&totals on/off" +msgstr "&Zwischensummen an/aus" + +#. Programmer's name for it: sSourceVerb0 +#: Decision Cube/mxdconst.pas:20 +msgid "&Do not display Sparse Rows/Columns" +msgstr "S&palten/Zeilen mit wenig Werten nicht anzeigen" + +#. Programmer's name for it: sSourceVerb1 +#: Decision Cube/mxdconst.pas:21 +msgid "&Display Sparse Rows/Columns" +msgstr "S&palten/Zeilen mit wenig Werten anzeigen" + +#. Programmer's name for it: sGridDimOptions +#: Decision Cube/mxdconst.pas:22 +msgid "Grid Dimension Options" +msgstr "Optionen für Rasterdimension" + +#. Programmer's name for it: sGridDimSettings +#: Decision Cube/mxdconst.pas:23 +msgid "Grid Dimension Settings" +msgstr "Einstellung für Rasterdimension" + +#. Programmer's name for it: sCubeProperties +#: Decision Cube/mxdconst.pas:24 +msgid "Cube Properties" +msgstr "Würfeleigenschaften" + +#. Programmer's name for it: sOnlyOneDataModuleAllowed +#: Internet/brkrconst.pas:14 +msgid "Only one data module per application" +msgstr "Nur ein Datenmodul pro Anwendung" + +#. Programmer's name for it: sNoDataModulesRegistered +#: Internet/brkrconst.pas:15 +msgid "No data modules registered" +msgstr "Es wurden keine Datenmodule registriert" + +#. Programmer's name for it: sNoDispatcherComponent +#: Internet/brkrconst.pas:16 +msgid "No dispatcher component found on data module" +msgstr "Im Datenmodul wurde keine Dispatcher-Komponente gefunden" + +#. Programmer's name for it: sTooManyActiveConnections +#: Internet/brkrconst.pas:18 +msgid "Maximum number of concurrent connections exceeded. Please try again later" +msgstr "Die maximale Anzahl gleichzeitiger Verbindungen wurde überschritten. Versuchen Sie später noch erneut" + +#. Programmer's name for it: sInternalServerError +#: Internet/brkrconst.pas:22 +msgid "" +"Internal Server Error 500\n" +"

    Internal Server Error 500


    \n" +"Exception: %s
    \n" +"Message: %s
    \n" +msgstr "" +"Interner Server-Fehler 500\n" +"

    Interner Server-Fehlerr 500


    \n" +"Exception: %s
    \n" +"Meldung: %s
    \n" + +#. Programmer's name for it: sDocumentMoved +#: Internet/brkrconst.pas:26 +msgid "" +"Document Moved 302\n" +"

    Object Moved


    \n" +"This Object may be found
    here.
    \n" +"
    \n" +msgstr "" +"Dokument wurde verschoben 302\n" +"

    Objekt wurde verschoben


    \n" +"Das Objekt könnte hier gefunden werden.
    \n" +"
    \n" + +#. Programmer's name for it: sInvalidISAPIApp +#: Internet/nstois.pas:109 +msgid "Invalid ISAPI application: %s" +msgstr "Ungültige ISAPI-Anwendung: %s" + +#. Programmer's name for it: sUnSupportedISAPIApp +#: Internet/nstois.pas:110 +msgid "Unsupported ISAPI Application version: %.8x" +msgstr "Nicht unterstützte ISAPI-Anwendungsversion: %.8x" + +#. Programmer's name for it: sGEVFailed +#: Internet/nstois.pas:111 +msgid "Call to GetExtensionVersion FAILED. Error Code: %d" +msgstr "Aufruf von GetExtensionVersion FEHLGESCHLAGEN. Fehler-Code: %d" + +#. Programmer's name for it: sErrorLoadingISAPIApp +#: Internet/nstois.pas:112 +msgid "Error loading ISAPI Application: %s" +msgstr "Fehler beim Laden von ISAPI-Anwendung %s" + +#. Programmer's name for it: sInvalidRedirectParam +#: Internet/nstois.pas:113 +msgid "Invalid Redirect parameter" +msgstr "Ungültiger Redirect-Parameter" + +#. Programmer's name for it: sISAPIAppError +#: Internet/nstois.pas:114 +msgid "ISAPI Application Error" +msgstr "Fehler in ISAPI-Anwendung" + +#. Programmer's name for it: sDataSetFieldBlank +#: Internet/wbmconst.pas:15 +msgid "Data set field is blank" +msgstr "Datenmengenfeld ist leer" + +#. Programmer's name for it: sDataSetFieldNotFound +#: Internet/wbmconst.pas:16 +msgid "Data set field not found: %s" +msgstr "Feld der Datenmenge nicht gefunden %s" + +#. Programmer's name for it: sNotDataSetField +#: Internet/wbmconst.pas:17 +msgid "Field is not a dataset field: %s" +msgstr "Feld ist kein Feld aus der Datenmenge: %s" + +#. Programmer's name for it: ScriptTableName +#: Internet/wbmconst.pas:18 +msgid "%s_Table" +msgstr "%s_Table" + +#. Programmer's name for it: sNoXMLBroker +#: Internet/wbmconst.pas:19 +msgid "%s: missing XMLBroker" +msgstr "%s: XMLBroker fehlt" + +#. Programmer's name for it: sFieldNotFound +#: Internet/wbmconst.pas:20 +msgid "%0:s: Field \"%1:s\" not found" +msgstr "%0:s: Feld \"%1:s\" nicht gefunden" + +#. Programmer's name for it: sXMLBrokerNotDefined +#: Internet/wbmconst.pas:21 +msgid "%s.XMLBroker = nil" +msgstr "%s.XMLBroker = nil" + +#. Programmer's name for it: sSubmitQuery +#: Internet/wbmconst.pas:22 +msgid "Submit" +msgstr "Absenden" + +#. Programmer's name for it: sResetQuery +#: Internet/wbmconst.pas:23 +msgid "Reset" +msgstr "Zurücksetzen" + +#. Programmer's name for it: sApplyUpdates +#: Internet/wbmconst.pas:24 +msgid "Apply Updates" +msgstr "Aktualisierung durchführen" + +#. Programmer's name for it: sFieldNameBlank +#: Internet/wbmconst.pas:25 +msgid "%s.FieldName = ''" +msgstr "%s.FieldName = ''" + +#. Programmer's name for it: sXMLComponentNotDefined +#: Internet/wbmconst.pas:26 +msgid "%s.XMLComponent = nil" +msgstr "%s.XMLComponent = nil" + +#. Programmer's name for it: ScriptNamesVar +#: Internet/wbmconst.pas:27 +msgid "%s_Names" +msgstr "%s_Names" + +#. Programmer's name for it: ScriptIDsVar +#: Internet/wbmconst.pas:28 +msgid "%s_IDs" +msgstr "%s_IDs" + +#. Programmer's name for it: ScriptXMLDisplayName +#: Internet/wbmconst.pas:29 +msgid "%s_Disp" +msgstr "%s_Disp" + +#. Programmer's name for it: sInvalidParent +#: Internet/wbmconst.pas:30 +msgid "Invalid parent" +msgstr "Ungültiges übergeordnetes Element" + +#. Programmer's name for it: sDuplicateStatusField +#: Internet/wbmconst.pas:31 +msgid "Field %s ignored, only one status field allowed" +msgstr "Feld %s wird ignoriert, es ist nur ein Statusfeld gestattet" + +#. Programmer's name for it: sFirstButton +#: Internet/wbmconst.pas:32 +msgid "|<" +msgstr "|<" + +#. Programmer's name for it: sLastButton +#: Internet/wbmconst.pas:33 +msgid ">|" +msgstr ">|" + +#. Programmer's name for it: sPriorButton +#: Internet/wbmconst.pas:34 +msgid "<" +msgstr "<" + +#. Programmer's name for it: sNextButton +#: Internet/wbmconst.pas:35 +msgid ">" +msgstr ">" + +#. Programmer's name for it: sPriorPageButton +#: Internet/wbmconst.pas:36 +msgid "<<" +msgstr "<<" + +#. Programmer's name for it: sNextPageButton +#: Internet/wbmconst.pas:37 +msgid ">>" +msgstr ">>" + +#. Programmer's name for it: sDeleteButton +#: Internet/wbmconst.pas:38 +msgid " - " +msgstr " - " + +#. Programmer's name for it: sInsertButton +#: Internet/wbmconst.pas:39 +msgid " + " +msgstr " + " + +#. Programmer's name for it: sUndoButton +#: Internet/wbmconst.pas:40 +msgid "Undo" +msgstr "Rückgängig" + +#. Programmer's name for it: sPostButton +#: Internet/wbmconst.pas:41 +msgid "Post" +msgstr "Übernehmen" + +#. Programmer's name for it: sWarningsBody +#: Internet/wbmconst.pas:46 +msgid "" +"\n" +"\n" +"

    Design-time Warnings

    \n" +"%s\n" +"

    \n" +msgstr "" +"\n" +"\n" +"

    Warnungen zur Entwurfszeit

    \n" +"%s\n" +"

    \n" + +#. Programmer's name for it: ScriptDocumentVarName +#: Internet/wbmconst.pas:47 +msgid "%s_Doc" +msgstr "%s_Doc" + +#. Programmer's name for it: ScriptXMLVarName +#: Internet/wbmconst.pas:48 +msgid "%s_XML" +msgstr "%s_XML" + +#. Programmer's name for it: sInvalidWebComponentsRegistration +#: Internet/wbmconst.pas:49 +msgid "Invalid Web component registration" +msgstr "Ungültige Registrierung der Web-Komponente" + +#. Programmer's name for it: sInvalidWebComponentsEnumeration +#: Internet/wbmconst.pas:50 +msgid "Invalid Web component enumeration" +msgstr "Ungültige Enumeration von Web-Komponente" + +#. Programmer's name for it: sInvalidWebComponentsCreation +#: Internet/wbmconst.pas:51 +msgid "Invalid Web component creation" +msgstr "Fehlendes Delta-Paket" + +#. Programmer's name for it: ScriptRowSetVarName +#: Internet/wbmconst.pas:52 +msgid "%s_RS" +msgstr "%s_RS" + +#. Programmer's name for it: sApplyUpdatesError +#: Internet/wbmconst.pas:53 +msgid "ApplyUpdates error. Error count: %d." +msgstr "DataSet: %s ist nicht aktiv" + +#. Programmer's name for it: sDeltaNotFound +#: Internet/wbmconst.pas:54 +msgid "Missing Delta Packet" +msgstr "Fehlendes Delta-Paket" + +#. Programmer's name for it: sXMLBrokerNotConnected +#: Internet/wbmconst.pas:55 +msgid "XMLBroker: %s is not connected" +msgstr "XMLBroker: %s hat keine Verbindung" + +#. Programmer's name for it: sDataSetNotActive +#: Internet/wbmconst.pas:56 +msgid "DataSet: %s is not active" +msgstr "DataSet: %s ist nicht aktiv" + +#. Programmer's name for it: SNewLookupFieldCaption +#: Property Editors/dsdefine.pas:442 +msgid "New Lookup Field" +msgstr "Neues Nachschlagefeld" + +#. Programmer's name for it: srSamples +#: Samples/ibconst.pas:6 +msgid "Samples" +msgstr "Beispiele" + +#. Programmer's name for it: SNoEventsRegistered +#: Samples/ibconst.pas:7 +msgid "You must register events before queueing them" +msgstr "Ereignisse müssen registriert werden, bevor sie in die Warteschlange gestellt werden können" + +#. Programmer's name for it: SInvalidDBConnection +#: Samples/ibconst.pas:8 +msgid "Component is not connected to an open Database" +msgstr "Die Komponente ist nicht mit einer offenen Datenbank verbunden" + +#. Programmer's name for it: SInvalidDatabase +#: Samples/ibconst.pas:9 +msgid "''%s'' is not connected to an InterBase database" +msgstr "''%s'' ist nicht mit einer InterBase-Datenbank verbunden" + +#. Programmer's name for it: SInvalidCancellation +#: Samples/ibconst.pas:10 +msgid "You cannot call CancelEvents from within an OnEventAlert handler" +msgstr "CancelEvents kann nicht aus einer OnEventAlert-Behandlungsroutine heraus aufgerufen werden" + +#. Programmer's name for it: SInvalidEvent +#: Samples/ibconst.pas:11 +msgid "Invalid blank event added to EventAlerter events list" +msgstr "Der Ereignisliste des Event-Alerters wurde ein ungültiges leeres Ereignis hinzugefügt" + +#. Programmer's name for it: SInvalidQueueing +#: Samples/ibconst.pas:12 +msgid "You cannot call QueueEvents from within an OnEventAlert handler" +msgstr "QueueEvents kann nicht aus einem OnEventAlert-Behandlungsroutine heraus aufgerufen werden" + +#. Programmer's name for it: SInvalidRegistration +#: Samples/ibconst.pas:13 +msgid "You cannot Register or Unregister events from within an OnEventAlert handler" +msgstr "Die Registrierung von Ereignissen bzw. deren Aufhebung kann nicht von innerhalb einer OnEventAlert-Behandlung vorgenommen werden" + +#. Programmer's name for it: SMaximumEvents +#: Samples/ibconst.pas:13 +msgid "You can only register 15 events per EventAlerter" +msgstr "Es können nur 15 Ereignisse pro Event-Alerter registriert werden" + +#. Programmer's name for it: SInterbaseNotInstalled +#: Samples/ibctrls.pas:103 +msgid "You must have Interbase installed to use this component" +msgstr "Um diese Komponenten verwenden zu können, muß InterBase installiert sein." + +#. Programmer's name for it: SFailedQueEvents +#: Samples/ibctrls.pas:104 +msgid "Failed to lookup isc_que_events" +msgstr "isc_que_events konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SFailedInterprete +#: Samples/ibctrls.pas:105 +msgid "Failed to lookup isc_interprete" +msgstr "isc_interprete konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SFailedFree +#: Samples/ibctrls.pas:106 +msgid "Failed to lookup isc_free" +msgstr "isc_free konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SFailedEventBlock +#: Samples/ibctrls.pas:107 +msgid "Failed to lookup isc_event_block" +msgstr "isc_event_block konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SFailedEventCounts +#: Samples/ibctrls.pas:108 +msgid "Failed to lookup isc_event_counts" +msgstr "isc_event_counts konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SFailedCancelEvents +#: Samples/ibctrls.pas:109 +msgid "Failed to lookup isc_cancel_events" +msgstr "isc_cancel_events konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SInvalidEnumValue +#: Vcl/adoconst.pas:15 +msgid "Invalid Enum Value" +msgstr "Ungültiger Enum-Wert" + +#. Programmer's name for it: SMissingConnection +#: Vcl/adoconst.pas:16 +msgid "Missing Connection or ConnectionString" +msgstr "Fehlende Connection oder ConnectionString" + +#. Programmer's name for it: SNoDetailFilter +#: Vcl/adoconst.pas:17 +msgid "Filter property cannot be used for detail tables" +msgstr "Die Filter-Eigenschaft kann nicht bei Detail-Tabellen verwendet werden" + +#. Programmer's name for it: SBookmarksRequired +#: Vcl/adoconst.pas:18 +msgid "Dataset does not support bookmarks, which are required for multi-record data controls" +msgstr "Die Datenmenge unterstützt keine Positionsmarken, die von Multi-Datensatz-Elementen benötigt werden." + +#. Programmer's name for it: SMissingCommandText +#: Vcl/adoconst.pas:19 +msgid "Missing %s property" +msgstr "Eigenschaft %s fehlt" + +#. Programmer's name for it: SNoResultSet +#: Vcl/adoconst.pas:20 +msgid "CommandText does not return a result set" +msgstr "CommandText gibt keine Ergebnismenge zurück" + +#. Programmer's name for it: SADOCreateError +#: Vcl/adoconst.pas:21 +msgid "Error creating object. Please verify that the Microsoft Data Access Components 2.1 (or later) have been properly installed" +msgstr "Fehler bei der Objekterzeugung. Stellen Sie sicher, daß die Microsoft Data Access Components 2.1 (oder höher) richtig installiert sind" + +#. Programmer's name for it: SEventsNotSupported +#: Vcl/adoconst.pas:22 +msgid "Events are not supported with server side TableDirect cursors" +msgstr "Ereignisse werden nicht mit server-seitigen TableDirect-Cursorn unterstützt" + +#. Programmer's name for it: SUsupportedFieldType +#: Vcl/adoconst.pas:23 +msgid "Unsupported field type (%s) in field %s" +msgstr "Nicht unterstützter Feldtyp (%s) in Feld %s" + +#. Programmer's name for it: SNoMatchingADOType +#: Vcl/adoconst.pas:24 +msgid "No matching ADO data type for %s" +msgstr "Kein passender ADO-Datentyp für %s" + +#. Programmer's name for it: SConnectionRequired +#: Vcl/adoconst.pas:25 +msgid "A connection component is required for async ExecuteOptions" +msgstr "Für asynchrone ExecuteOptions wird eine Verbindungskomponente erwartet" + +#. Programmer's name for it: SCantRequery +#: Vcl/adoconst.pas:26 +msgid "Cannot perform a requery after connection has changed" +msgstr "Nach Wechsel der Verbindung kann keine Abfrage durchgeführt werden" + +#. Programmer's name for it: SNoFilterOptions +#: Vcl/adoconst.pas:27 +msgid "FilterOptions are not supported" +msgstr "Filteroptionen werden nicht unterstützt" + +#. Programmer's name for it: SAutoSessionExclusive +#: Vcl/bdeconst.pas:15 +msgid "Cannot enable AutoSessionName property with more than one session on a form or data-module" +msgstr "Die Eigenschaft AutoSessionName kann nicht aktiviert werden, wenn sich mehr als eine Session in einem Formular oder einem Datenmodul befinden" + +#. Programmer's name for it: SAutoSessionExists +#: Vcl/bdeconst.pas:16 +msgid "Cannot add a session to the form or data-module while session '%s' has AutoSessionName enabled" +msgstr "Einem Formular oder Datenmodul kann keine Session hinzugefügt werden, da Session '%s' AutoSessionName aktiviert hat" + +#. Programmer's name for it: SAutoSessionActive +#: Vcl/bdeconst.pas:17 +msgid "Cannot modify SessionName while AutoSessionName is enabled" +msgstr "Während AutoSessionName aktiviert ist, kann SessionName nicht geändert werden." + +#. Programmer's name for it: SDuplicateDatabaseName +#: Vcl/bdeconst.pas:18 +msgid "Duplicate database name '%s'" +msgstr "Doppelter Datenbankname '%s'" + +#. Programmer's name for it: SDuplicateSessionName +#: Vcl/bdeconst.pas:19 +msgid "Duplicate session name '%s'" +msgstr "Doppelter Name für eine Sitzung: '%s'" + +#. Programmer's name for it: SInvalidSessionName +#: Vcl/bdeconst.pas:20 +msgid "Invalid session name %s" +msgstr "Ungültiger Sitzungsname %s" + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/bdeconst.pas:21 +msgid "Database name missing" +msgstr "Datenbankname fehlt" + +#. Programmer's name for it: SSessionNameMissing +#: Vcl/bdeconst.pas:22 +msgid "Session name missing" +msgstr "Name der Sitzung fehlt" + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/bdeconst.pas:23 +msgid "Cannot perform this operation on an open database" +msgstr "Operation bei geöffneter Datenbank nicht ausführbar" + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/bdeconst.pas:24 +msgid "Cannot perform this operation on a closed database" +msgstr "Operation bei geschlossener Datenbank nicht ausführbar" + +#. Programmer's name for it: SDatabaseHandleSet +#: Vcl/bdeconst.pas:25 +msgid "Database handle owned by a different session" +msgstr "Datenbank-Handle gehört zu einer anderen Sitzung" + +#. Programmer's name for it: SSessionActive +#: Vcl/bdeconst.pas:26 +msgid "Cannot perform this operation on an active session" +msgstr "Diese Operation kann auf eine aktive Sitzung nicht angewendet werden" + +#. Programmer's name for it: SHandleError +#: Vcl/bdeconst.pas:27 +msgid "Error creating cursor handle" +msgstr "Fehler beim Erstellen des Cursor-Handle" + +#. Programmer's name for it: SInvalidFloatField +#: Vcl/bdeconst.pas:28 +msgid "Cannot convert field '%s' to a floating point value" +msgstr "Feld '%s' kann nicht in Fließkommawert konvertiert werden" + +#. Programmer's name for it: SInvalidIntegerField +#: Vcl/bdeconst.pas:29 +msgid "Cannot convert field '%s' to an integer value" +msgstr "Feld '%s' kann nicht in Integerwert konvertiert werden" + +#. Programmer's name for it: STableMismatch +#: Vcl/bdeconst.pas:30 +msgid "Source and destination tables are incompatible" +msgstr "Quell- und Zieltabellen sind inkompatibel" + +#. Programmer's name for it: SFieldAssignError +#: Vcl/bdeconst.pas:31 +msgid "Fields '%s' and '%s' are not assignment compatible" +msgstr "Die Felder '%s' und '%s' sind nicht zuweisungskompatibel" + +#. Programmer's name for it: SNoReferenceTableName +#: Vcl/bdeconst.pas:32 +msgid "ReferenceTableName not specified for field '%s'" +msgstr "Für Feld '%s' wurde kein Referenztabellenname angegeben" + +#. Programmer's name for it: SCompositeIndexError +#: Vcl/bdeconst.pas:33 +msgid "Cannot use array of Field values with Expression Indices" +msgstr "Ein Array von Feldwerten kann nicht mit auf Ausdrücken basierenden Indizes verwendet werden" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/bdeconst.pas:34 +msgid "Invalid batch move parameters" +msgstr "Ungültige Batch-Move-Parameter" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/bdeconst.pas:35 +msgid "No SQL statement available" +msgstr "Keine SQL-Anweisung verfügbar" + +#. Programmer's name for it: SNoParameterValue +#: Vcl/bdeconst.pas:36 +msgid "No value for parameter '%s'" +msgstr "Fehlender Wert für Parameter '%s'" + +#. Programmer's name for it: SNoParameterType +#: Vcl/bdeconst.pas:37 +msgid "No parameter type for parameter '%s'" +msgstr "Kein Parametertyp für Parameter '%s'" + +#. Programmer's name for it: SLoginError +#: Vcl/bdeconst.pas:38 +msgid "Cannot connect to database '%s'" +msgstr "Verbindung zu Datenbank '%s' nicht möglich" + +#. Programmer's name for it: SInitError +#: Vcl/bdeconst.pas:39 +msgid "An error occurred while attempting to initialize the Borland Database Engine (error $%.4x)" +msgstr "Bei der Initialisierung der Borland Database Engine ist ein Fehler aufgetreten (Fehler $%.4x)" + +#. Programmer's name for it: SDatabaseEditor +#. Programmer's name for it: SIBDatabaseEditor +#: Vcl/bdeconst.pas:40 +msgid "Da&tabase Editor..." +msgstr "&Datenbank-Editor..." + +#. Programmer's name for it: SExplore +#: Vcl/bdeconst.pas:41 +msgid "E&xplore" +msgstr "E&xplorer" + +#. Programmer's name for it: SLinkDetail +#: Vcl/bdeconst.pas:42 +msgid "'%s' cannot be opened" +msgstr "'%s' kann nicht geöffnet werden" + +#. Programmer's name for it: SLinkMasterSource +#: Vcl/bdeconst.pas:43 +msgid "The MasterSource property of '%s' must be linked to a DataSource" +msgstr "Die MasterSource-Eigenschaft von '%s' muss mit einer DataSource verbunden sein." + +#. Programmer's name for it: SLinkMaster +#: Vcl/bdeconst.pas:44 +msgid "Unable to open the MasterSource Table" +msgstr "MasterSource-Tabelle kann nicht geöffnet werden" + +#. Programmer's name for it: SGQEVerb +#: Vcl/bdeconst.pas:45 +msgid "S&QL Builder..." +msgstr "SQL-&Builder..." + +#. Programmer's name for it: SBindVerb +#: Vcl/bdeconst.pas:46 +msgid "Define &Parameters..." +msgstr "&Parameter definieren..." + +#. Programmer's name for it: SDisconnectDatabase +#: Vcl/bdeconst.pas:48 +msgid "Database is currently connected. Disconnect and continue?" +msgstr "Die Datenbank ist verbunden. Verbindung beenden und weitermachen?" + +#. Programmer's name for it: SBDEError +#: Vcl/bdeconst.pas:49 +msgid "BDE error $%.4x" +msgstr "BDE-Fehler $%.4x" + +#. Programmer's name for it: SLookupSourceError +#: Vcl/bdeconst.pas:50 +msgid "Unable to use duplicate DataSource and LookupSource" +msgstr "Kann doppelte DataSource und LookupSource nicht benutzen" + +#. Programmer's name for it: SLookupTableError +#: Vcl/bdeconst.pas:51 +msgid "LookupSource must be connected to TTable component" +msgstr "LookupSource muss mit TTable-Komponente verbunden werden" + +#. Programmer's name for it: SLookupIndexError +#: Vcl/bdeconst.pas:52 +msgid "%s must be the lookup table's active index" +msgstr "%s muss der aktive Index der Nachschlagetabelle sein." + +#. Programmer's name for it: SParameterTypes +#: Vcl/bdeconst.pas:53 +msgid ";Input;Output;Input/Output;Result" +msgstr ";Eingabe;Ausgabe;Eingabe/Ausgabe;Ergebnis" + +#. Programmer's name for it: SInvalidParamFieldType +#: Vcl/bdeconst.pas:54 +msgid "Must have a valid field type selected" +msgstr "Sie müssen einen gültigen Feldtypen auswählen" + +#. Programmer's name for it: STruncationError +#: Vcl/bdeconst.pas:55 +msgid "Parameter '%s' truncated on output" +msgstr "Parameter '%s' wurde bei Ausgabe abgeschnitten" + +#. Programmer's name for it: SDataTypes +#: Vcl/bdeconst.pas:56 +msgid ";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" +msgstr ";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" + +#. Programmer's name for it: SResultName +#: Vcl/bdeconst.pas:57 +msgid "Result" +msgstr "Ergebnis" + +#. Programmer's name for it: SDBCaption +#: Vcl/bdeconst.pas:58 +msgid "%s%s%s Database" +msgstr "%s%s%s Datenbanken" + +#. Programmer's name for it: SParamEditor +#: Vcl/bdeconst.pas:59 +msgid "%s%s%s Parameters" +msgstr "%s%s%s Parameter" + +#. Programmer's name for it: SIndexFilesEditor +#: Vcl/bdeconst.pas:60 +msgid "%s%s%s Index Files" +msgstr "%s%s%s Indexdateien" + +#. Programmer's name for it: SNoIndexFiles +#. Programmer's name for it: srNone +#: Vcl/bdeconst.pas:61 +msgid "(None)" +msgstr "(Ohne)" + +#. Programmer's name for it: SIndexDoesNotExist +#: Vcl/bdeconst.pas:62 +msgid "Index does not exist. Index: %s" +msgstr "Index existiert nicht. Index: %s" + +#. Programmer's name for it: SNoTableName +#: Vcl/bdeconst.pas:63 +msgid "Missing TableName property" +msgstr "Eigenschaft TableName fehlt" + +#. Programmer's name for it: SNoDataSetField +#: Vcl/bdeconst.pas:64 +msgid "Missing DataSetField property" +msgstr "Eigenschaft DataSetField fehlt" + +#. Programmer's name for it: SBatchExecute +#. Programmer's name for it: SExecute +#: Vcl/bdeconst.pas:65 +msgid "E&xecute" +msgstr "&Ausführen" + +#. Programmer's name for it: SNoCachedUpdates +#: Vcl/bdeconst.pas:66 +msgid "Not in cached update mode" +msgstr "Nicht im Cached-Update-Modus" + +#. Programmer's name for it: SInvalidAliasName +#: Vcl/bdeconst.pas:67 +msgid "Invalid alias name %s" +msgstr "Ungültiger Aliasname %s" + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/bdeconst.pas:68 +msgid "Cannot access field '%s' in a filter" +msgstr "Auf Feld '%s' kann in einem Filter nicht zugegriffen werden" + +#. Programmer's name for it: SUpdateSQLEditor +#. Programmer's name for it: SIBUpdateSQLEditor +#: Vcl/bdeconst.pas:69 +msgid "&UpdateSQL Editor..." +msgstr "UpdateS&QL-Editor..." + +#. Programmer's name for it: SNoDataSet +#: Vcl/bdeconst.pas:70 +msgid "No dataset association" +msgstr "Keine Datenmengenverknüpfung" + +#. Programmer's name for it: SUntitled +#: Vcl/bdeconst.pas:71 +msgid "Untitled Application" +msgstr "Unbenannte Anwendung" + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/bdeconst.pas:72 +msgid "Cannot update, %s is not owned by %s" +msgstr "Aktualisierung nicht möglich, %s gehört zu %s" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/bdeconst.pas:73 +msgid "Update failed" +msgstr "Aktualisierung misslungen" + +#. Programmer's name for it: SSQLGenSelect +#: Vcl/bdeconst.pas:74 +msgid "Must select at least one key field and one update field" +msgstr "Sie müssen mindestens ein Schlüsselfeld und ein Updatefeld auswählen" + +#. Programmer's name for it: SSQLNotGenerated +#: Vcl/bdeconst.pas:75 +msgid "Update SQL statements not generated, exit anyway?" +msgstr "Aktualisierungs-SQL-Anweisungen nicht generiert; trotzdem beenden" + +#. Programmer's name for it: SSQLDataSetOpen +#: Vcl/bdeconst.pas:76 +msgid "Unable to determine field names for %s" +msgstr "Die Feldnamen für %s konnten nicht erkannt werden" + +#. Programmer's name for it: SLocalTransDirty +#: Vcl/bdeconst.pas:77 +msgid "The transaction isolation level must be dirty read for local databases" +msgstr "Die Isolationsebene für Transaktionen muss für lokale Datenbanken Dirty-Read sein." + +#. Programmer's name for it: SMissingDataSet +#: Vcl/bdeconst.pas:78 +msgid "Missing DataSet property" +msgstr "Eigenschaft DataSet fehlt" + +#. Programmer's name for it: SNoProvider +#: Vcl/bdeconst.pas:79 +msgid "No provider available" +msgstr "Kein Provider verfügbar" + +#. Programmer's name for it: SNotAQuery +#: Vcl/bdeconst.pas:80 +msgid "Dataset is not a query" +msgstr "Die Datenmenge ist keine Abfrage" + +#. Programmer's name for it: sTabFailClear +#: Vcl/comstrs.pas:15 +msgid "Failed to clear tab control" +msgstr "Register-Element konnte nicht geleert werden" + +#. Programmer's name for it: sTabFailDelete +#: Vcl/comstrs.pas:16 +msgid "Failed to delete tab at index %d" +msgstr "Registerseite mit Index %d konnte nicht gelöscht werden" + +#. Programmer's name for it: sTabFailRetrieve +#: Vcl/comstrs.pas:17 +msgid "Failed to retrieve tab at index %d" +msgstr "Registerseite mit Index %d konnte nicht gelesen werden" + +#. Programmer's name for it: sTabFailGetObject +#: Vcl/comstrs.pas:18 +msgid "Failed to get object at index %d" +msgstr "Objekt mit Index %d konnte nicht gelesen werden" + +#. Programmer's name for it: sTabFailSet +#: Vcl/comstrs.pas:19 +msgid "Failed to set tab \"%s\" at index %d" +msgstr "Registerseite '%s' mit Index %d konnte nicht gesetzt werden" + +#. Programmer's name for it: sTabFailSetObject +#: Vcl/comstrs.pas:20 +msgid "Failed to set object at index %d" +msgstr "Objekt mit Index %d konnte nicht gesetzt werden" + +#. Programmer's name for it: sTabMustBeMultiLine +#: Vcl/comstrs.pas:21 +msgid "MultiLine must be True when TabPosition is tpLeft or tpRight" +msgstr "Bei TabPosition tpLeft und tpRight muß MultiLine True sein" + +#. Programmer's name for it: sInvalidLevel +#: Vcl/comstrs.pas:23 +msgid "Invalid item level assignment" +msgstr "Ungültige Zuweisung von Eintragsebenen" + +#. Programmer's name for it: sInvalidLevelEx +#: Vcl/comstrs.pas:24 +msgid "Invalid level (%d) for item \"%s\"" +msgstr "Ungültige Ebene (%d) für Eintrag \"%s\"" + +#. Programmer's name for it: sInvalidIndex +#: Vcl/comstrs.pas:25 +msgid "Invalid index" +msgstr "Ungültiger Index" + +#. Programmer's name for it: sInsertError +#: Vcl/comstrs.pas:26 +msgid "Unable to insert an item" +msgstr "Eintrag kann nicht eingefügt werden" + +#. Programmer's name for it: sInvalidOwner +#: Vcl/comstrs.pas:28 +msgid "Invalid owner" +msgstr "Ungültiger Besitzer" + +#. Programmer's name for it: sUnableToCreateColumn +#: Vcl/comstrs.pas:29 +msgid "Unable to create new column" +msgstr "Eine neue Spalte kann nicht erzeugt werden" + +#. Programmer's name for it: sUnableToCreateItem +#: Vcl/comstrs.pas:30 +msgid "Unable to create new item" +msgstr "Ein neuer Eintrag kann nicht erzeugt werden" + +#. Programmer's name for it: sRichEditInsertError +#: Vcl/comstrs.pas:32 +msgid "RichEdit line insertion error" +msgstr "Fehler bei Einfügen von RichEdit-Zeile" + +#. Programmer's name for it: sRichEditLoadFail +#: Vcl/comstrs.pas:33 +msgid "Failed to Load Stream" +msgstr "Das Laden des Streams ist mißlungen" + +#. Programmer's name for it: sRichEditSaveFail +#: Vcl/comstrs.pas:34 +msgid "Failed to Save Stream" +msgstr "Das Speichern des Streams ist mißlungen" + +#. Programmer's name for it: sTooManyPanels +#: Vcl/comstrs.pas:36 +msgid "StatusBar cannot have more than 64 panels" +msgstr "StatusBar kann nicht mehr als 64 Bedienfelder (Panels) haben" + +#. Programmer's name for it: sHKError +#: Vcl/comstrs.pas:38 +msgid "Error assigning Hot-Key to %s. %s" +msgstr "Fehler bei der Zuordnung des Tastenkürzels zu %s. %s" + +#. Programmer's name for it: sHKInvalid +#: Vcl/comstrs.pas:39 +msgid "Hot-Key is invalid" +msgstr "Tastenkürzel ist ungültig" + +#. Programmer's name for it: sHKInvalidWindow +#: Vcl/comstrs.pas:40 +msgid "Window is invalid or a child window" +msgstr "Fenster ist ungültig oder ein untergeordnetes Fenster" + +#. Programmer's name for it: sHKAssigned +#: Vcl/comstrs.pas:41 +msgid "Hot-Key is assigned to another window" +msgstr "Tastenkürzel ist einem anderen Fenster zugeordnet" + +#. Programmer's name for it: sUDAssociated +#: Vcl/comstrs.pas:43 +msgid "%s is already associated with %s" +msgstr "%s ist bereits mit %s verknüpft" + +#. Programmer's name for it: sPageIndexError +#: Vcl/comstrs.pas:46 +msgid "%d is an invalid PageIndex value. PageIndex must be between 0 and %d" +msgstr "%d ist ein ungültiger Wert für PageIndex. PageIndex muß einen Wert zwischen 0 und %d besitzen" + +#. Programmer's name for it: sInvalidComCtl32 +#: Vcl/comstrs.pas:48 +msgid "This control requires version 4.70 or greater of COMCTL32.DLL" +msgstr "Dieses Element benötigt COMCTL32.DLL in der Version 4.70 oder höher" + +#. Programmer's name for it: sDateTimeMax +#: Vcl/comstrs.pas:50 +msgid "Date exceeds maximum of %s" +msgstr "Das Datum überschreitet das Maximum von %s" + +#. Programmer's name for it: sDateTimeMin +#: Vcl/comstrs.pas:51 +msgid "Date is less than minimum of %s" +msgstr "Das Datum unterschreitet das Minimum von %s" + +#. Programmer's name for it: sNeedAllowNone +#: Vcl/comstrs.pas:52 +msgid "You must be in ShowCheckbox mode to set to this date" +msgstr "Um das Datum zu setzen, müssen Sie im Modus ShowCheckbox sein" + +#. Programmer's name for it: sFailSetCalDateTime +#: Vcl/comstrs.pas:53 +msgid "Failed to set calendar date or time" +msgstr "Kalenderzeit oder -datum konnte nicht gesetzt werden" + +#. Programmer's name for it: sFailSetCalMaxSelRange +#: Vcl/comstrs.pas:54 +msgid "Failed to set maximum selection range" +msgstr "Der max. Auswahlbereich konnte nicht gesetzt werden" + +#. Programmer's name for it: sFailSetCalMinMaxRange +#: Vcl/comstrs.pas:55 +msgid "Failed to set calendar min/max range" +msgstr "Der max./min. Bereich des Kalenders konnte nicht gesetzt werden" + +#. Programmer's name for it: sCalRangeNeedsMultiSelect +#: Vcl/comstrs.pas:56 +msgid "Date range can only be used in multiselect mode" +msgstr "Datumsbereich kann nur im Multiselect-Modus gebraucht werden" + +#. Programmer's name for it: sFailsetCalSelRange +#: Vcl/comstrs.pas:57 +msgid "Failed to set calendar selected range" +msgstr "Der ausgewählte Bereich des Kalenders kann nicht gesetzt werden" + +#. Programmer's name for it: SOpenFileTitle +#. IndexFiles..OpenDialog..Title +#: Vcl/consts.pas:15 +msgid "Open" +msgstr "Öffnen" + +#. Programmer's name for it: SAssignError +#: Vcl/consts.pas:16 +msgid "Cannot assign a %s to a %s" +msgstr "%s kann nicht zu %s zugewiesen werden" + +#. Programmer's name for it: SFCreateError +#: Vcl/consts.pas:17 +msgid "Cannot create file %s" +msgstr "Datei %s kann nicht erstellt werden" + +#. Programmer's name for it: SFOpenError +#: Vcl/consts.pas:18 +msgid "Cannot open file %s" +msgstr "Datei %s kann nicht geöffnet werden" + +#. Programmer's name for it: SReadError +#: Vcl/consts.pas:19 +msgid "Stream read error" +msgstr "Stream-Lesefehler" + +#. Programmer's name for it: SWriteError +#: Vcl/consts.pas:20 +msgid "Stream write error" +msgstr "Stream-Schreibfehler" + +#. Programmer's name for it: SMemoryStreamError +#: Vcl/consts.pas:21 +msgid "Out of memory while expanding memory stream" +msgstr "Expandieren des Speicher-Stream wegen Speichermangel nicht möglich" + +#. Programmer's name for it: SCantWriteResourceStreamError +#: Vcl/consts.pas:22 +msgid "Can't write to a read-only resource stream" +msgstr "In einen zum Lesen geöffneten Ressourcen-Stream kann nicht geschrieben werden" + +#. Programmer's name for it: SDuplicateReference +#: Vcl/consts.pas:23 +msgid "WriteObject called twice for the same instance" +msgstr "Zweimaliger Aufruf von WriteObject für die gleiche Instanz" + +#. Programmer's name for it: SClassNotFound +#: Vcl/consts.pas:24 +msgid "Class %s not found" +msgstr "Klasse %s nicht gefunden" + +#. Programmer's name for it: SInvalidImage +#. Programmer's name for it: SInvalidStreamFormat +#: Vcl/consts.pas:25 +msgid "Invalid stream format" +msgstr "Ungültiges Stream-Format" + +#. Programmer's name for it: SResNotFound +#. Programmer's name for it: sResNotFound +#: Vcl/consts.pas:26 +msgid "Resource %s not found" +msgstr "Ressource %s wurde nicht gefunden" + +#. Programmer's name for it: SClassMismatch +#: Vcl/consts.pas:27 +msgid "Resource %s is of incorrect class" +msgstr "Ressource %s hat die falsche Klasse" + +#. Programmer's name for it: SListIndexError +#: Vcl/consts.pas:28 +msgid "List index out of bounds (%d)" +msgstr "Listenindex überschreitet das Maximum (%d)" + +#. Programmer's name for it: SListCapacityError +#: Vcl/consts.pas:29 +msgid "List capacity out of bounds (%d)" +msgstr "Kapazität der Liste ist erschöpft (%d)" + +#. Programmer's name for it: SListCountError +#: Vcl/consts.pas:30 +msgid "List count out of bounds (%d)" +msgstr "Zu viele Einträge in der Liste (%d)" + +#. Programmer's name for it: SSortedListError +#: Vcl/consts.pas:31 +msgid "Operation not allowed on sorted string list" +msgstr "Operation bei sortierten Stringlisten nicht erlaubt" + +#. Programmer's name for it: SDuplicateString +#: Vcl/consts.pas:32 +msgid "String list does not allow duplicates" +msgstr "In der Stringliste sind Duplikate nicht erlaubt" + +#. Programmer's name for it: SInvalidTabIndex +#: Vcl/consts.pas:33 +msgid "Tab index out of bounds" +msgstr "Registerindex außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SInvalidTabPosition +#: Vcl/consts.pas:34 +msgid "Tab position incompatible with current tab style" +msgstr "Die Position des Register ist nicht mit dem aktuellen Erscheinungsbild kompatibel." + +#. Programmer's name for it: SInvalidTabStyle +#: Vcl/consts.pas:35 +msgid "Tab style incompatible with current tab position" +msgstr "Das Erscheinungsbild des Registers ist nicht mit der aktuellen Position kompatibel." + +#. Programmer's name for it: SDuplicateName +#: Vcl/consts.pas:36 +msgid "A component named %s already exists" +msgstr "Komponente mit der Bezeichnung %s existiert bereits" + +#. Programmer's name for it: SInvalidName +#: Vcl/consts.pas:37 +msgid "''%s'' is not a valid component name" +msgstr "''%s'' ist kein gültiger Komponentenname" + +#. Programmer's name for it: SDuplicateClass +#: Vcl/consts.pas:38 +msgid "A class named %s already exists" +msgstr "Klasse mit der Bezeichnung %s existiert bereits" + +#. Programmer's name for it: SNoComSupport +#: Vcl/consts.pas:39 +msgid "%s has not been registered as a COM class" +msgstr "%s wurde nicht als COM-Klasse registriert" + +#. Programmer's name for it: SInvalidInteger +#: Vcl/consts.pas:40 +msgid "''%s'' is not a valid integer value" +msgstr "''%s'' ist kein gültiger Integer-Wert" + +#. Programmer's name for it: SLineTooLong +#. Programmer's name for it: SOutlineLongLine +#: Vcl/consts.pas:41 +msgid "Line too long" +msgstr "Zeile zu lang" + +#. Programmer's name for it: SInvalidPropertyValue +#. Programmer's name for it: SInvalidProperty +#: Vcl/consts.pas:42 +msgid "Invalid property value" +msgstr "Ungültiger Eigenschaftswert" + +#. Programmer's name for it: SInvalidPropertyPath +#: Vcl/consts.pas:43 +msgid "Invalid property path" +msgstr "Ungültiger Pfad für Eigenschaft" + +#. Programmer's name for it: SInvalidPropertyType +#: Vcl/consts.pas:44 +msgid "Invalid property type: %s" +msgstr "Ungültiger Eigenschaftstyp: %s" + +#. Programmer's name for it: SInvalidPropertyElement +#: Vcl/consts.pas:45 +msgid "Invalid property element: %s" +msgstr "Ungültiges Eigenschaftselement: %s" + +#. Programmer's name for it: SUnknownProperty +#: Vcl/consts.pas:46 +msgid "Property does not exist" +msgstr "Eigenschaft existiert nicht" + +#. Programmer's name for it: SReadOnlyProperty +#: Vcl/consts.pas:47 +msgid "Property is read-only" +msgstr "Eigenschaft kann nur gelesen werden" + +#. Programmer's name for it: SPropertyException +#: Vcl/consts.pas:48 +msgid "Error reading %s%s%s: %s" +msgstr "Fehler beim Lesen von %s%s%s: %s" + +#. Programmer's name for it: SAncestorNotFound +#: Vcl/consts.pas:49 +msgid "Ancestor for '%s' not found" +msgstr "Vorfahr für '%s' nicht gefunden" + +#. Programmer's name for it: SInvalidBitmap +#: Vcl/consts.pas:50 +msgid "Bitmap image is not valid" +msgstr "Bitmap ist ungültig" + +#. Programmer's name for it: SInvalidIcon +#: Vcl/consts.pas:51 +msgid "Icon image is not valid" +msgstr "Ungültiges Symbol" + +#. Programmer's name for it: SInvalidMetafile +#: Vcl/consts.pas:52 +msgid "Metafile is not valid" +msgstr "Metadatei ist ungültig" + +#. Programmer's name for it: SInvalidPixelFormat +#: Vcl/consts.pas:53 +msgid "Invalid pixel format" +msgstr "Ungültiges Pixelformat" + +#. Programmer's name for it: SBitmapEmpty +#: Vcl/consts.pas:54 +msgid "Bitmap is empty" +msgstr "Bitmap ist leer" + +#. Programmer's name for it: SScanLine +#: Vcl/consts.pas:55 +msgid "Scan line index out of range" +msgstr "Bereichsüberschreitung bei Zeilenindex" + +#. Programmer's name for it: SChangeIconSize +#: Vcl/consts.pas:56 +msgid "Cannot change the size of an icon" +msgstr "Die Größe eines Symbols kann nicht geändert werden" + +#. Programmer's name for it: SOleGraphic +#: Vcl/consts.pas:57 +msgid "Invalid operation on TOleGraphic" +msgstr "Ungültige Operation für TOleGraphic" + +#. Programmer's name for it: SUnknownExtension +#: Vcl/consts.pas:58 +msgid "Unknown picture file extension (.%s)" +msgstr "Unbekannte Bilddateierweiterung (.%s)" + +#. Programmer's name for it: SUnknownClipboardFormat +#: Vcl/consts.pas:59 +msgid "Unsupported clipboard format" +msgstr "Format der Zwischenablage wird nicht unterstützt" + +#. Programmer's name for it: SOutOfResources +#: Vcl/consts.pas:60 +msgid "Out of system resources" +msgstr "Systemressourcen erschöpft." + +#. Programmer's name for it: SNoCanvasHandle +#: Vcl/consts.pas:61 +msgid "Canvas does not allow drawing" +msgstr "Leinwand/Bild erlaubt kein Zeichnen" + +#. Programmer's name for it: SInvalidImageSize +#: Vcl/consts.pas:62 +msgid "Invalid image size" +msgstr "Ungültige Bildgröße" + +#. Programmer's name for it: STooManyImages +#: Vcl/consts.pas:63 +msgid "Too many images" +msgstr "Zu viele Bilder" + +#. Programmer's name for it: SDimsDoNotMatch +#: Vcl/consts.pas:64 +msgid "Image dimensions do not match image list dimensions" +msgstr "Bildgröße und Bildlistengröße stimmen nicht überein" + +#. Programmer's name for it: SInvalidImageList +#: Vcl/consts.pas:65 +msgid "Invalid ImageList" +msgstr "Ungültige ImageList" + +#. Programmer's name for it: SReplaceImage +#: Vcl/consts.pas:66 +msgid "Unable to Replace Image" +msgstr "Bild kann nicht ersetzt werden" + +#. Programmer's name for it: SImageIndexError +#: Vcl/consts.pas:67 +msgid "Invalid ImageList Index" +msgstr "Ungültiger ImageList-Index" + +#. Programmer's name for it: SImageReadFail +#: Vcl/consts.pas:68 +msgid "Failed to read ImageList data from stream" +msgstr "Die ImageList-Daten konnten nicht aus dem Stream gelesen werden" + +#. Programmer's name for it: SImageWriteFail +#: Vcl/consts.pas:69 +msgid "Failed to write ImageList data to stream" +msgstr "Die ImageList-Daten konnten nicht in den Stream geschrieben werden" + +#. Programmer's name for it: SWindowDCError +#: Vcl/consts.pas:70 +msgid "Error creating window device context" +msgstr "Fehler beim Erstellen des Fenster-Gerätekontexts" + +#. Programmer's name for it: SClientNotSet +#: Vcl/consts.pas:71 +msgid "Client of TDrag not initialized" +msgstr "Client von TDrag wurde nicht initialisiert" + +#. Programmer's name for it: SWindowClass +#: Vcl/consts.pas:72 +msgid "Error creating window class" +msgstr "Metadateien" + +#. Programmer's name for it: SWindowCreate +#: Vcl/consts.pas:73 +msgid "Error creating window" +msgstr "Fehler beim Erzeugen eines Fensters" + +#. Programmer's name for it: SCannotFocus +#: Vcl/consts.pas:74 +msgid "Cannot focus a disabled or invisible window" +msgstr "Ein deaktiviertes oder unsichtbares Fenster kann nicht den Fokus erhalten" + +#. Programmer's name for it: SParentRequired +#: Vcl/consts.pas:75 +msgid "Control '%s' has no parent window" +msgstr "Element '%s' hat kein übergeordnetes Fenster" + +#. Programmer's name for it: SMDIChildNotVisible +#: Vcl/consts.pas:76 +msgid "Cannot hide an MDI Child Form" +msgstr "Ein MDI-Kindformular kann nicht verborgen werden" + +#. Programmer's name for it: SVisibleChanged +#: Vcl/consts.pas:77 +msgid "Cannot change Visible in OnShow or OnHide" +msgstr "Eigenschaft Visible kann in OnShow oder OnHide nicht verändert werden" + +#. Programmer's name for it: SCannotShowModal +#: Vcl/consts.pas:78 +msgid "Cannot make a visible window modal" +msgstr "Aus einem sichtbaren Fenster kann kein modales gemacht werden" + +#. Programmer's name for it: SScrollBarRange +#: Vcl/consts.pas:79 +msgid "Scrollbar property out of range" +msgstr "Eigenschaft Scrollbar außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SPropertyOutOfRange +#: Vcl/consts.pas:80 +msgid "%s property out of range" +msgstr "Eigenschaft %s außerhalb des gültigen Bereichs" + +#. Programmer's name for it: SMenuIndexError +#: Vcl/consts.pas:81 +msgid "Menu index out of range" +msgstr "Menüindex außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SMenuReinserted +#: Vcl/consts.pas:82 +msgid "Menu inserted twice" +msgstr "Menü zweimal eingefügt" + +#. Programmer's name for it: SMenuNotFound +#: Vcl/consts.pas:83 +msgid "Sub-menu is not in menu" +msgstr "Untermenü ist nicht im Menü" + +#. Programmer's name for it: SNoTimers +#: Vcl/consts.pas:84 +msgid "Not enough timers available" +msgstr "Nicht genügend Timer verfügbar" + +#. Programmer's name for it: SNotPrinting +#: Vcl/consts.pas:85 +msgid "Printer is not currently printing" +msgstr "Der Drucker druckt aktuell nicht" + +#. Programmer's name for it: SPrinting +#: Vcl/consts.pas:86 +msgid "Printing in progress" +msgstr "Druckvorgang läuft" + +#. Programmer's name for it: SPrinterIndexError +#: Vcl/consts.pas:87 +msgid "Printer index out of range" +msgstr "Druckerindex außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SInvalidPrinter +#: Vcl/consts.pas:88 +msgid "Printer selected is not valid" +msgstr "Ausgewählter Drucker ist ungültig" + +#. Programmer's name for it: SDeviceOnPort +#: Vcl/consts.pas:89 +msgid "%s on %s" +msgstr "%s an %s" + +#. Programmer's name for it: SGroupIndexTooLow +#: Vcl/consts.pas:90 +msgid "GroupIndex cannot be less than a previous menu item's GroupIndex" +msgstr "GroupIndex kann nicht kleiner sein als der GroupIndex eines vorhergehenden Menüelementes" + +#. Programmer's name for it: STwoMDIForms +#: Vcl/consts.pas:91 +msgid "Cannot have more than one MDI form per application" +msgstr "Es ist nur ein MDI-Formular pro Anwendung möglich" + +#. Programmer's name for it: SNoMDIForm +#: Vcl/consts.pas:92 +msgid "Cannot create form. No MDI forms are currently active" +msgstr "Formular kann nicht erstellt werden. Zur Zeit sind keine MDI-Formulare aktiv" + +#. Programmer's name for it: SRegisterError +#: Vcl/consts.pas:93 +msgid "Invalid component registration" +msgstr "Ungültige Komponentenregistrierung" + +#. Programmer's name for it: SImageCanvasNeedsBitmap +#: Vcl/consts.pas:94 +msgid "Can only modify an image if it contains a bitmap" +msgstr "Ein Bild kann nur geändert werden, wenn es ein Bitmap enthält" + +#. Programmer's name for it: SControlParentSetToSelf +#: Vcl/consts.pas:95 +msgid "A control cannot have itself as its parent" +msgstr "Ein Steuerelement kann nicht sich selbst als Vorfahr haben" + +#. Programmer's name for it: SOKButton +#. Programmer's name for it: SMsgDlgOK +#. DSSCubeEditor..OKButton..Caption +#. DSSQueryEditor..OKButton..Caption +#. ConnEditForm..OkButton..Caption +#. ClientDataForm..OkBtn..Caption +#. DBEditForm..OkButton..Caption +#. AddFields..OkBtn..Caption +#. AssociateAttributes..OKBtn..Caption +#. SaveAttributesAs..OKBtn..Caption +#. DefineField..OkBtn..Caption +#. LinkFields..Button1..Caption +#. IndexFiles..Ok..Caption +#. PictureEditorDlg..OKButton..Caption +#: Vcl/consts.pas:96 +#: Cube/mxdssqry.dfm:321 +#: Property Editors/adoconed.dfm:19 +#: Editors/cdsedit.dfm:39 +#: Editors/dbedit.dfm:140 +#: Editors/dsadd.dfm:24 +#: Editors/dsattra.dfm:18 +#: Editors/dsattrs.dfm:56 +#: Editors/dsdefine.dfm:103 +#: Editors/fldlinks.dfm:141 +#: Editors/ixedit.dfm:64 +#: Editors/picedit.dfm:22 +msgid "OK" +msgstr "OK" + +#. Programmer's name for it: SCancelButton +#. Programmer's name for it: SMsgDlgCancel +#. DSSCubeEditor..CancelButton..Caption +#. DSSQueryEditor..Cancel..Caption +#. ConnEditForm..CancelButton..Caption +#. ClientDataForm..CancelBtn..Caption +#. DBEditForm..CancelButton..Caption +#. InputReqDialog..CancelButton..Caption +#. LoginDialog..CancelButton..Caption +#. AddFields..CancelBtn..Caption +#. AssociateAttributes..CancelBtn..Caption +#. SaveAttributesAs..CancelBtn..Caption +#. DefineField..CancelBtn..Caption +#. LinkFields..Button2..Caption +#. IndexFiles..Cancel..Caption +#. PictureEditorDlg..CancelButton..Caption +#. SQLEditForm..ButtonPanel..CancelButton..Caption +#. StrEditDlg..CancelButton..Caption +#. UpdateSQLEditForm..CancelButton..Caption +#: Vcl/consts.pas:97 +#: Cube/mxdssqry.dfm:311 +#: Property Editors/adoconed.dfm:30 +#: Editors/cdsedit.dfm:52 +#: Editors/dbedit.dfm:152 +#: Editors/dbinpreq.dfm:29 +#: Editors/dblogdlg.dfm:30 +#: Editors/dsadd.dfm:36 +#: Editors/dsattra.dfm:30 +#: Editors/dsattrs.dfm:67 +#: Editors/dsdefine.dfm:115 +#: Editors/fldlinks.dfm:153 +#: Editors/ixedit.dfm:75 +#: Editors/picedit.dfm:33 +#: Editors/sqledit.dfm:106 +#: Editors/stredit.dfm:66 +#: Editors/updsqled.dfm:32 +msgid "Cancel" +msgstr "Abbrechen" + +#. Programmer's name for it: SYesButton +#. Programmer's name for it: SMsgDlgYes +#: Vcl/consts.pas:98 +msgid "&Yes" +msgstr "&Ja" + +#. Programmer's name for it: SNoButton +#. Programmer's name for it: SMsgDlgNo +#: Vcl/consts.pas:99 +msgid "&No" +msgstr "&Nein" + +#. Programmer's name for it: SHelpButton +#. Programmer's name for it: SMsgDlgHelp +#. DSSCubeEditor..HelpButton..Caption +#. DSSQueryEditor..HelpButton..Caption +#. ConnEditForm..HelpButton..Caption +#. ClientDataForm..HelpBtn..Caption +#. DBEditForm..HelpButton..Caption +#. DataBindForm..HelpBtn..Caption +#. AddFields..HelpBtn..Caption +#. AssociateAttributes..HelpBtn..Caption +#. SaveAttributesAs..HelpBtn..Caption +#. DefineField..HelpBtn..Caption +#. LinkFields..Help..Caption +#. IndexFiles..Help..Caption +#. PictureEditorDlg..HelpButton..Caption +#. SQLEditForm..ButtonPanel..HelpButton..Caption +#. StrEditDlg..HelpButton..Caption +#. UpdateSQLEditForm..HelpButton..Caption +#: Vcl/consts.pas:100 +#: Cube/mxdssqry.dfm:331 +#: Property Editors/adoconed.dfm:39 +#: Editors/cdsedit.dfm:61 +#: Editors/dbedit.dfm:161 +#: Editors/dboleedt.dfm:128 +#: Editors/dsadd.dfm:65 +#: Editors/dsattra.dfm:40 +#: Editors/dsattrs.dfm:77 +#: Editors/dsdefine.dfm:124 +#: Editors/fldlinks.dfm:162 +#: Editors/ixedit.dfm:84 +#: Editors/picedit.dfm:42 +#: Editors/sqledit.dfm:116 +#: Editors/stredit.dfm:46 +#: Editors/updsqled.dfm:41 +msgid "&Help" +msgstr "&Hilfe" + +#. Programmer's name for it: SCloseButton +#. SocketForm..PopupMenu..miClose..Caption +#: Vcl/consts.pas:101 +msgid "&Close" +msgstr "S&chließen" + +#. Programmer's name for it: SIgnoreButton +#. Programmer's name for it: SMsgDlgIgnore +#: Vcl/consts.pas:102 +msgid "&Ignore" +msgstr "&Ignorieren" + +#. Programmer's name for it: SRetryButton +#. Programmer's name for it: SMsgDlgRetry +#: Vcl/consts.pas:103 +msgid "&Retry" +msgstr "&Wiederholen" + +#. Programmer's name for it: SAbortButton +#: Vcl/consts.pas:104 +msgid "Abort" +msgstr "Abbrechen" + +#. Programmer's name for it: SAllButton +#. Programmer's name for it: SMsgDlgAll +#: Vcl/consts.pas:105 +msgid "&All" +msgstr "&Alle" + +#. Programmer's name for it: SCannotDragForm +#: Vcl/consts.pas:107 +msgid "Cannot drag a form" +msgstr "Formulare können nicht gezogen werden" + +#. Programmer's name for it: SPutObjectError +#: Vcl/consts.pas:108 +msgid "PutObject to undefined item" +msgstr "PutObject auf undefiniertes Element" + +#. Programmer's name for it: SCardDLLNotLoaded +#: Vcl/consts.pas:109 +msgid "Could not load CARDS.DLL" +msgstr "CARDS.DLL kann nicht geladen werden" + +#. Programmer's name for it: SDuplicateCardId +#: Vcl/consts.pas:110 +msgid "Duplicate CardId found" +msgstr "Doppelte CardId gefunden" + +#. Programmer's name for it: SDdeErr +#: Vcl/consts.pas:112 +msgid "An error returned from DDE ($0%x)" +msgstr "Vom DDE wurde ein Fehler zurückgegeben ($0%x)" + +#. Programmer's name for it: SDdeConvErr +#: Vcl/consts.pas:113 +msgid "DDE Error - conversation not established ($0%x)" +msgstr "DDE-Fehler - Konversation konnte nicht etabliert werden ($0%x)" + +#. Programmer's name for it: SDdeMemErr +#: Vcl/consts.pas:114 +msgid "Error occurred when DDE ran out of memory ($0%x)" +msgstr "Wegen Speichermangel bei DDE ist ein Fehler aufgetreten ($0%x)." + +#. Programmer's name for it: SDdeNoConnect +#: Vcl/consts.pas:115 +msgid "Unable to connect DDE conversation" +msgstr "DDE-Konversation konnte nicht verbunden werden." + +#. Programmer's name for it: SFB +#: Vcl/consts.pas:117 +msgid "FB" +msgstr "VH" + +#. Programmer's name for it: SFG +#: Vcl/consts.pas:118 +msgid "FG" +msgstr "VG" + +#. Programmer's name for it: SBG +#: Vcl/consts.pas:119 +msgid "BG" +msgstr "HG" + +#. Programmer's name for it: SOldTShape +#: Vcl/consts.pas:120 +msgid "Cannot load older version of TShape" +msgstr "Kann ältere Version von TShape nicht laden" + +#. Programmer's name for it: SVMetafiles +#: Vcl/consts.pas:121 +msgid "Metafiles" +msgstr "Metadateien" + +#. Programmer's name for it: SVEnhMetafiles +#: Vcl/consts.pas:122 +msgid "Enhanced Metafiles" +msgstr "Erweiterte Metadateien" + +#. Programmer's name for it: SVIcons +#: Vcl/consts.pas:123 +msgid "Icons" +msgstr "Symbole" + +#. Programmer's name for it: SVBitmaps +#: Vcl/consts.pas:124 +msgid "Bitmaps" +msgstr "Bitmaps" + +#. Programmer's name for it: SGridTooLarge +#: Vcl/consts.pas:125 +msgid "Grid too large for operation" +msgstr "Gitter zu groß für Operation" + +#. Programmer's name for it: STooManyDeleted +#: Vcl/consts.pas:126 +msgid "Too many rows or columns deleted" +msgstr "Zu viele Zeilen oder Spalten gelöscht" + +#. Programmer's name for it: SIndexOutOfRange +#: Vcl/consts.pas:127 +msgid "Grid index out of range" +msgstr "Gitterindex außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SFixedColTooBig +#: Vcl/consts.pas:128 +msgid "Fixed column count must be less than column count" +msgstr "Die Anzahl fester Spalten muss kleiner sein als die Spaltenanzahl" + +#. Programmer's name for it: SFixedRowTooBig +#: Vcl/consts.pas:129 +msgid "Fixed row count must be less than row count" +msgstr "Die Anzahl fester Zeilen muss kleiner sein als die Zeilenanzahl" + +#. Programmer's name for it: SInvalidStringGridOp +#: Vcl/consts.pas:130 +msgid "Cannot insert or delete rows from grid" +msgstr "Es können keine Zeilen des Tabellengitters gelöscht oder eingefügt werden" + +#. Programmer's name for it: SParseError +#: Vcl/consts.pas:131 +msgid "%s on line %d" +msgstr "%s in Zeile %d" + +#. Programmer's name for it: SIdentifierExpected +#: Vcl/consts.pas:132 +msgid "Identifier expected" +msgstr "Bezeichner erwartet" + +#. Programmer's name for it: SStringExpected +#: Vcl/consts.pas:133 +msgid "String expected" +msgstr "String erwartet" + +#. Programmer's name for it: SNumberExpected +#: Vcl/consts.pas:134 +msgid "Number expected" +msgstr "Zahl erwartet" + +#. Programmer's name for it: SCharExpected +#: Vcl/consts.pas:135 +msgid "''%s'' expected" +msgstr "''%s'' erwartet" + +#. Programmer's name for it: SSymbolExpected +#: Vcl/consts.pas:136 +msgid "%s expected" +msgstr "%s erwartet" + +#. Programmer's name for it: SInvalidNumber +#: Vcl/consts.pas:137 +msgid "Invalid numeric value" +msgstr "Ungültiger numerischer Wert" + +#. Programmer's name for it: SInvalidString +#: Vcl/consts.pas:138 +msgid "Invalid string constant" +msgstr "Ungültige Stringkonstante" + +#. Programmer's name for it: SInvalidBinary +#: Vcl/consts.pas:140 +msgid "Invalid binary value" +msgstr "Ungültiger Binärwert" + +#. Programmer's name for it: SOutlineIndexError +#: Vcl/consts.pas:141 +msgid "Outline index not found" +msgstr "Gliederungsindex nicht gefunden" + +#. Programmer's name for it: SOutlineExpandError +#: Vcl/consts.pas:142 +msgid "Parent must be expanded" +msgstr "Elternknoten muß expandiert sein" + +#. Programmer's name for it: SInvalidCurrentItem +#: Vcl/consts.pas:143 +msgid "Invalid value for current item" +msgstr "Ungültiger Wert" + +#. Programmer's name for it: SMaskErr +#: Vcl/consts.pas:144 +msgid "Invalid input value" +msgstr "Ungültiger Eingabewert" + +#. Programmer's name for it: SMaskEditErr +#: Vcl/consts.pas:145 +msgid "Invalid input value. Use escape key to abandon changes" +msgstr "Ungültiger Eingabewert. Mit der Taste ESC machen Sie die Änderungen rückgängig." + +#. Programmer's name for it: SOutlineError +#: Vcl/consts.pas:146 +msgid "Invalid outline index" +msgstr "Ungültiger Gliederungsindex" + +#. Programmer's name for it: SOutlineBadLevel +#: Vcl/consts.pas:147 +msgid "Incorrect level assignment" +msgstr "Ungültige Zuweisung von Ebenen" + +#. Programmer's name for it: SOutlineSelection +#: Vcl/consts.pas:148 +msgid "Invalid selection" +msgstr "Ungültige Auswahl" + +#. Programmer's name for it: SOutlineFileLoad +#: Vcl/consts.pas:149 +msgid "File load error" +msgstr "Fehler beim Dateiladen" + +#. Programmer's name for it: SOutlineMaxLevels +#: Vcl/consts.pas:151 +msgid "Maximum outline depth exceeded" +msgstr "Maximale Gliederungstiefe überschritten" + +#. Programmer's name for it: SMsgDlgWarning +#: Vcl/consts.pas:153 +msgid "Warning" +msgstr "Warnung" + +#. Programmer's name for it: SMsgDlgError +#: Vcl/consts.pas:154 +msgid "Error" +msgstr "Fehler" + +#. Programmer's name for it: SMsgDlgInformation +#: Vcl/consts.pas:155 +msgid "Information" +msgstr "Information" + +#. Programmer's name for it: SMsgDlgConfirm +#: Vcl/consts.pas:156 +msgid "Confirm" +msgstr "Bestätigung" + +#. Programmer's name for it: SMsgDlgHelpNone +#: Vcl/consts.pas:162 +msgid "No help available" +msgstr "Keine Hilfe verfügbar" + +#. Programmer's name for it: SMsgDlgHelpHelp +#: Vcl/consts.pas:163 +msgid "Help" +msgstr "Hilfe" + +#. Programmer's name for it: SMsgDlgAbort +#: Vcl/consts.pas:164 +msgid "&Abort" +msgstr "&Abbrechen" + +#. Programmer's name for it: SMsgDlgNoToAll +#: Vcl/consts.pas:168 +msgid "N&o to All" +msgstr "&Alle Nein" + +#. Programmer's name for it: SMsgDlgYesToAll +#: Vcl/consts.pas:169 +msgid "Yes to &All" +msgstr "A&lle Ja" + +#. Programmer's name for it: SmkcBkSp +#: Vcl/consts.pas:171 +msgid "BkSp" +msgstr "Rück" + +#. Programmer's name for it: SmkcTab +#: Vcl/consts.pas:172 +msgid "Tab" +msgstr "Tab" + +#. Programmer's name for it: SmkcEsc +#: Vcl/consts.pas:173 +msgid "Esc" +msgstr "Esc" + +#. Programmer's name for it: SmkcEnter +#: Vcl/consts.pas:174 +msgid "Enter" +msgstr "Eingabe" + +#. Programmer's name for it: SmkcSpace +#: Vcl/consts.pas:175 +msgid "Space" +msgstr "Leertaste" + +#. Programmer's name for it: SmkcPgUp +#: Vcl/consts.pas:176 +msgid "PgUp" +msgstr "BildAuf" + +#. Programmer's name for it: SmkcPgDn +#: Vcl/consts.pas:177 +msgid "PgDn" +msgstr "BildAb" + +#. Programmer's name for it: SmkcEnd +#: Vcl/consts.pas:178 +msgid "End" +msgstr "Ende" + +#. Programmer's name for it: SmkcHome +#: Vcl/consts.pas:179 +msgid "Home" +msgstr "Pos1" + +#. Programmer's name for it: SmkcLeft +#: Vcl/consts.pas:180 +msgid "Left" +msgstr "Left" + +#. Programmer's name for it: SmkcUp +#: Vcl/consts.pas:181 +msgid "Up" +msgstr "Nach oben" + +#. Programmer's name for it: SmkcRight +#: Vcl/consts.pas:182 +msgid "Right" +msgstr "Rechts" + +#. Programmer's name for it: SmkcDown +#: Vcl/consts.pas:183 +msgid "Down" +msgstr "Nach unten" + +#. Programmer's name for it: SmkcIns +#: Vcl/consts.pas:184 +msgid "Ins" +msgstr "Einfg" + +#. Programmer's name for it: SmkcDel +#: Vcl/consts.pas:185 +msgid "Del" +msgstr "Entf" + +#. Programmer's name for it: SmkcShift +#: Vcl/consts.pas:186 +msgid "Shift+" +msgstr "Umsch+" + +#. Programmer's name for it: SmkcCtrl +#: Vcl/consts.pas:187 +msgid "Ctrl+" +msgstr "Strg+" + +#. Programmer's name for it: SmkcAlt +#: Vcl/consts.pas:188 +msgid "Alt+" +msgstr "Alt+" + +#. Programmer's name for it: srUnknown +#. Programmer's name for it: SHostUnknown +#: Vcl/consts.pas:190 +msgid "(Unknown)" +msgstr "(Unbekannt)" + +#. Programmer's name for it: SOutOfRange +#: Vcl/consts.pas:192 +msgid "Value must be between %d and %d" +msgstr "Wert muß zwischen %d und %d liegen" + +#. Programmer's name for it: SCannotCreateName +#: Vcl/consts.pas:193 +msgid "Cannot create a default method name for an unnamed component" +msgstr "Für eine unbenannte Komponente kann kein Standard-Methodennamen erstellt werden" + +#. Programmer's name for it: SDateEncodeError +#: Vcl/consts.pas:195 +msgid "Invalid argument to date encode" +msgstr "Ungültiges Argument zum Codieren des Datums" + +#. Programmer's name for it: STimeEncodeError +#: Vcl/consts.pas:196 +msgid "Invalid argument to time encode" +msgstr "Ungültiges Argument zur zeit-Codierung" + +#. Programmer's name for it: SInvalidDate +#: Vcl/consts.pas:197 +msgid "''%s'' is not a valid date" +msgstr "''%s'' ist kein gültiges Datum" + +#. Programmer's name for it: SInvalidTime +#: Vcl/consts.pas:198 +msgid "''%s'' is not a valid time" +msgstr "''%s'' ist keine gültige Zeit" + +#. Programmer's name for it: SInvalidDateTime +#: Vcl/consts.pas:199 +msgid "''%s'' is not a valid date and time" +msgstr "''%s'' ist kein gültiges Datum und Zeit" + +#. Programmer's name for it: SInvalidFileName +#: Vcl/consts.pas:200 +msgid "Invalid file name - %s" +msgstr "Ungültiger Dateiname - %s" + +#. Programmer's name for it: SDefaultFilter +#: Vcl/consts.pas:201 +msgid "All files (*.*)|*.*" +msgstr "Alle Dateien (*.*)|*.*" + +#. Programmer's name for it: sAllFilter +#: Vcl/consts.pas:202 +msgid "All" +msgstr "Alle" + +#. Programmer's name for it: SNoVolumeLabel +#: Vcl/consts.pas:203 +msgid ": [ - no volume label - ]" +msgstr ": [ - Ohne Namen - ]" + +#. Programmer's name for it: SInsertLineError +#: Vcl/consts.pas:204 +msgid "Unable to insert a line" +msgstr "Zeile kann nicht eingefügt werden" + +#. Programmer's name for it: SConfirmCreateDir +#: Vcl/consts.pas:206 +msgid "The specified directory does not exist. Create it?" +msgstr "Das angegebene Verzeichnis existiert nicht. Soll es angelegt werden?" + +#. Programmer's name for it: SSelectDirCap +#: Vcl/consts.pas:207 +msgid "Select Directory" +msgstr "Verzeichnis auswählen" + +#. Programmer's name for it: SCannotCreateDir +#: Vcl/consts.pas:208 +msgid "Unable to create directory" +msgstr "Verzeichnis kann nicht erstellt werden" + +#. Programmer's name for it: SDirNameCap +#: Vcl/consts.pas:209 +msgid "Directory &Name:" +msgstr "Verzeichnis&name:" + +#. Programmer's name for it: SDrivesCap +#: Vcl/consts.pas:210 +msgid "D&rives:" +msgstr "&Laufwerke:" + +#. Programmer's name for it: SDirsCap +#: Vcl/consts.pas:211 +msgid "&Directories:" +msgstr "&Verzeichnisse:" + +#. Programmer's name for it: SFilesCap +#: Vcl/consts.pas:212 +msgid "&Files: (*.*)" +msgstr "&Dateien: (*.*)" + +#. Programmer's name for it: SNetworkCap +#: Vcl/consts.pas:213 +msgid "Ne&twork..." +msgstr "Ne&tzwerk..." + +#. !! obsolete - delete in 5.0 +#: Vcl/consts.pas:215 +msgid "Color" +msgstr "Farben" + +#. !! obsolete - delete in 5.0 +#: Vcl/consts.pas:216 +msgid "ABCDEFGHIJKLMNOP" +msgstr "ABCDEFGHIJKLMNOP" + +#. Programmer's name for it: SInvalidClipFmt +#: Vcl/consts.pas:218 +msgid "Invalid clipboard format" +msgstr "Ungültiges Format der Zwischenablage" + +#. Programmer's name for it: SIconToClipboard +#: Vcl/consts.pas:219 +msgid "Clipboard does not support Icons" +msgstr "Zwischenablage unterstützt keine Symbole" + +#. Programmer's name for it: SCannotOpenClipboard +#: Vcl/consts.pas:220 +msgid "Cannot open clipboard" +msgstr "Zwischenablage kann nicht geöffnet werden" + +#. Programmer's name for it: SDefault +#. Programmer's name for it: sHTTPItemDefault +#. SQLWindow..DBGrid1..TitleFont.Name +#. DSSQueryEditor..Pager..Dimensions..AddAgg..Font.Name +#: Vcl/consts.pas:222 +#: Cube/mxdssqry.dfm:193 +msgid "Default" +msgstr "Vorgabe" + +#. Programmer's name for it: SInvalidMemoSize +#: Vcl/consts.pas:224 +msgid "Text exceeds memo capacity" +msgstr "Text überschreitet Memo-Kapazität" + +#. Programmer's name for it: SCustomColors +#: Vcl/consts.pas:225 +msgid "Custom Colors" +msgstr "Selbstdefinierte Farben" + +#. Programmer's name for it: SInvalidPrinterOp +#: Vcl/consts.pas:226 +msgid "Operation not supported on selected printer" +msgstr "Operation auf ausgewähltem Drucker nicht verfügbar" + +#. Programmer's name for it: SNoDefaultPrinter +#: Vcl/consts.pas:227 +msgid "There is no default printer currently selected" +msgstr "Zur Zeit ist kein Standard-Drucker gewählt" + +#. Programmer's name for it: SIniFileWriteError +#: Vcl/consts.pas:229 +msgid "Unable to write to %s" +msgstr "In %s kann nicht geschrieben werden" + +#. Programmer's name for it: SBitsIndexError +#: Vcl/consts.pas:231 +msgid "Bits index out of range" +msgstr "Bits-Index außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SUntitled +#: Vcl/consts.pas:233 +msgid "(Untitled)" +msgstr "(Unbenannt)" + +#. Programmer's name for it: SInvalidRegType +#: Vcl/consts.pas:235 +msgid "Invalid data type for '%s'" +msgstr "Ungültiger Datentyp für '%s'" + +#. Programmer's name for it: SRegCreateFailed +#: Vcl/consts.pas:236 +msgid "Failed to create key %s" +msgstr "Erzeugung von Schlüssel %s misslungen" + +#. Programmer's name for it: SRegSetDataFailed +#: Vcl/consts.pas:237 +msgid "Failed to set data for '%s'" +msgstr "Fehler beim Setzen der Daten für '%s'" + +#. Programmer's name for it: SRegGetDataFailed +#: Vcl/consts.pas:238 +msgid "Failed to get data for '%s'" +msgstr "Fehler beim Holen der Daten für '%s'" + +#. Programmer's name for it: SUnknownConversion +#: Vcl/consts.pas:240 +msgid "Unknown RichEdit conversion file extension (.%s)" +msgstr "Unbekannte Dateierweiterung für RichEdit-Konvertierung (.%s)" + +#. Programmer's name for it: SDuplicateMenus +#: Vcl/consts.pas:241 +msgid "Menu '%s' is already being used by another form" +msgstr "Menü '%s' wird bereits von einem anderen Formular benutzt" + +#. Programmer's name for it: SPictureLabel +#: Vcl/consts.pas:243 +msgid "Picture:" +msgstr "Grafik:" + +#. Programmer's name for it: SPictureDesc +#: Vcl/consts.pas:244 +msgid " (%dx%d)" +msgstr " (%dx%d)" + +#. Programmer's name for it: SPreviewLabel +#: Vcl/consts.pas:245 +msgid "Preview" +msgstr "Vorschau" + +#. Programmer's name for it: SCannotOpenAVI +#: Vcl/consts.pas:247 +msgid "Cannot open AVI" +msgstr "AVI kann nicht geöffnet werden" + +#. Programmer's name for it: SNotOpenErr +#: Vcl/consts.pas:249 +msgid "No MCI device open" +msgstr "Kein MCI-Gerät geöffnet" + +#. Programmer's name for it: SMPOpenFilter +#: Vcl/consts.pas:250 +msgid "All files (*.*)|*.*|Wave files (*.wav)|*.wav|Midi files (*.mid)|*.mid|Video for Windows (*.avi)|*.avi" +msgstr "Alle Dateien (*.*)|*.*|Wave-Dateien (*.WAV)|*.WAV|Midi-Dateien (*.MID)|*.MID|Video für Windows (*.avi)|*.avi" + +#. Programmer's name for it: SMCIAVIVideo +#: Vcl/consts.pas:252 +msgid "AVIVideo" +msgstr "AVIVideo" + +#. Programmer's name for it: SMCICDAudio +#: Vcl/consts.pas:253 +msgid "CDAudio" +msgstr "CDAudio" + +#. Programmer's name for it: SMCIDAT +#: Vcl/consts.pas:254 +msgid "DAT" +msgstr "DAT" + +#. Programmer's name for it: SMCIDigitalVideo +#: Vcl/consts.pas:255 +msgid "DigitalVideo" +msgstr "DigitalVideo" + +#. Programmer's name for it: SMCIMMMovie +#: Vcl/consts.pas:256 +msgid "MMMovie" +msgstr "MMMovie" + +#. Programmer's name for it: SMCIOther +#: Vcl/consts.pas:257 +msgid "Other" +msgstr "Andere" + +#. Programmer's name for it: SMCIOverlay +#: Vcl/consts.pas:258 +msgid "Overlay" +msgstr "Überlagert" + +#. Programmer's name for it: SMCIScanner +#: Vcl/consts.pas:259 +msgid "Scanner" +msgstr "Scanner" + +#. Programmer's name for it: SMCISequencer +#: Vcl/consts.pas:260 +msgid "Sequencer" +msgstr "Sequencer" + +#. Programmer's name for it: SMCIVCR +#: Vcl/consts.pas:261 +msgid "VCR" +msgstr "VCR" + +#. Programmer's name for it: SMCIVideodisc +#: Vcl/consts.pas:262 +msgid "Videodisc" +msgstr "Videodisc" + +#. Programmer's name for it: SMCIWaveAudio +#: Vcl/consts.pas:263 +msgid "WaveAudio" +msgstr "WaveAudio" + +#. Programmer's name for it: SMCIUnknownError +#: Vcl/consts.pas:264 +msgid "Unknown error code" +msgstr "Unbekannter Fehler-Code" + +#. Programmer's name for it: SBoldItalicFont +#: Vcl/consts.pas:266 +msgid "Bold Italic" +msgstr "Fett kursiv" + +#. Programmer's name for it: SBoldFont +#: Vcl/consts.pas:267 +msgid "Bold" +msgstr "Fett" + +#. Programmer's name for it: SItalicFont +#: Vcl/consts.pas:268 +msgid "Italic" +msgstr "Kursiv" + +#. Programmer's name for it: SRegularFont +#: Vcl/consts.pas:269 +msgid "Regular" +msgstr "Normal" + +#. Programmer's name for it: SPropertiesVerb +#. SocketForm..Pages..PropPage..Caption +#: Vcl/consts.pas:271 +msgid "Properties" +msgstr "Eigenschaften" + +#. Programmer's name for it: sWindowsSocketError +#: Vcl/consts.pas:273 +msgid "Windows socket error: %s (%d), on API '%s'" +msgstr "Windows-Socket-Fehler: %s (%d), auf API '%s'" + +#. Programmer's name for it: sAsyncSocketError +#: Vcl/consts.pas:274 +msgid "Asynchronous socket error %d" +msgstr "Asynchroner Socket-Fehler %d" + +#. Programmer's name for it: sNoAddress +#: Vcl/consts.pas:275 +msgid "No address specified" +msgstr "Keine Adresse angegeben" + +#. Programmer's name for it: sCannotListenOnOpen +#: Vcl/consts.pas:276 +msgid "Can't listen on an open socket" +msgstr "Offener Socket kann nicht überwacht werden" + +#. Programmer's name for it: sCannotCreateSocket +#: Vcl/consts.pas:277 +msgid "Can't create new socket" +msgstr "Es kann kein neuer Socket erzeugt werden" + +#. Programmer's name for it: sSocketAlreadyOpen +#: Vcl/consts.pas:278 +msgid "Socket already open" +msgstr "Socket ist bereits geöffnet" + +#. Programmer's name for it: sCantChangeWhileActive +#: Vcl/consts.pas:279 +msgid "Can't change value while socket is active" +msgstr "Wert kann nicht geändert werden, während der Socket aktiv ist" + +#. Programmer's name for it: sSocketMustBeBlocking +#: Vcl/consts.pas:280 +msgid "Socket must be in blocking mode" +msgstr "Socket muss sich im Blocking-Modus befinden" + +#. Programmer's name for it: sSocketIOError +#: Vcl/consts.pas:281 +msgid "%s error %d, %s" +msgstr "%s-Fehler %d, %s" + +#. Programmer's name for it: sSocketRead +#. Programmer's name for it: SReadAccess +#: Vcl/consts.pas:282 +msgid "Read" +msgstr "Lesen" + +#. Programmer's name for it: sSocketWrite +#. Programmer's name for it: SWriteAccess +#: Vcl/consts.pas:283 +msgid "Write" +msgstr "Schreiben" + +#. Programmer's name for it: SServiceFailed +#: Vcl/consts.pas:285 +msgid "Service failed on %s: %s" +msgstr "Service fehlgeschlagen bei %s:%s" + +#. Programmer's name for it: SExecute +#: Vcl/consts.pas:286 +msgid "execute" +msgstr "Ausführen" + +#. Programmer's name for it: SStart +#: Vcl/consts.pas:287 +msgid "start" +msgstr "Start" + +#. Programmer's name for it: SStop +#: Vcl/consts.pas:288 +msgid "stop" +msgstr "Stop" + +#. Programmer's name for it: SPause +#: Vcl/consts.pas:289 +msgid "pause" +msgstr "Pause" + +#. Programmer's name for it: SContinue +#: Vcl/consts.pas:290 +msgid "continue" +msgstr "Weiter" + +#. Programmer's name for it: SInterrogate +#: Vcl/consts.pas:291 +msgid "interrogate" +msgstr "Anfragen" + +#. Programmer's name for it: SShutdown +#: Vcl/consts.pas:292 +msgid "shutdown" +msgstr "Herunterfahren" + +#. Programmer's name for it: SCustomError +#: Vcl/consts.pas:293 +msgid "Service failed in custom message(%d): %s" +msgstr "Service fehlgeschlagen in selbstdef. Meldung (%d): %s" + +#. Programmer's name for it: SServiceInstallOK +#: Vcl/consts.pas:294 +msgid "Service installed successfully" +msgstr "Service erfolgreich installiert" + +#. Programmer's name for it: SServiceInstallFailed +#: Vcl/consts.pas:295 +msgid "Service \"%s\" failed to install with error: \"%s\"" +msgstr "Service \"%s\" konnte nicht installiert werden; Fehler: \"%s\"" + +#. Programmer's name for it: SServiceUninstallOK +#: Vcl/consts.pas:296 +msgid "Service uninstalled successfully" +msgstr "Service erfolgreich deinstalliert" + +#. Programmer's name for it: SServiceUninstallFailed +#: Vcl/consts.pas:297 +msgid "Service \"%s\" failed to uninstall with error: \"%s\"" +msgstr "Service \"%s\" konnte nicht deinstalliert werden; Fehler: \"%s\"" + +#. Programmer's name for it: SInvalidActionRegistration +#: Vcl/consts.pas:299 +msgid "Invalid action registration" +msgstr "Ungültige Aktionsregistrierung" + +#. Programmer's name for it: SInvalidActionUnregistration +#: Vcl/consts.pas:300 +msgid "Invalid action unregistration" +msgstr "Ungültige Aufhebung der Aktionsregistrierung" + +#. Programmer's name for it: SInvalidActionEnumeration +#: Vcl/consts.pas:301 +msgid "Invalid action enumeration" +msgstr "Ungültige Aktionsaufzählung" + +#. Programmer's name for it: SInvalidActionCreation +#: Vcl/consts.pas:302 +msgid "Invalid action creation" +msgstr "Ungültige Aktionserstellung" + +#. Programmer's name for it: SDockedCtlNeedsName +#: Vcl/consts.pas:304 +msgid "Docked control must have a name" +msgstr "Angedocktes Steuerelement muß einen Namen haben." + +#. Programmer's name for it: SDockTreeRemoveError +#: Vcl/consts.pas:305 +msgid "Error removing control from dock tree" +msgstr "Fehler beim Entfernen des Steuerelements aus der Andock-Hierarchie" + +#. Programmer's name for it: SDockZoneNotFound +#: Vcl/consts.pas:306 +msgid " - Dock zone not found" +msgstr " - Andockzone nicht gefunden" + +#. Programmer's name for it: SDockZoneHasNoCtl +#: Vcl/consts.pas:307 +msgid " - Dock zone has no control" +msgstr " - Andockzone besitzt kein Steuerelement" + +#. Programmer's name for it: SAllCommands +#: Vcl/consts.pas:309 +msgid "All Commands" +msgstr "Alle Befehle" + +#. Programmer's name for it: SDuplicateItem +#: Vcl/consts.pas:311 +msgid "List does not allow duplicates ($0%x)" +msgstr "Liste gestattet keine doppelten Einträge ($0%x)" + +#. Programmer's name for it: SDuplicatePropertyCategory +#: Vcl/consts.pas:313 +msgid "A property category called %s already exists" +msgstr "Eine Eigenschaftskategorie mit Namen %s gibt es bereits" + +#. Programmer's name for it: SUnknownPropertyCategory +#: Vcl/consts.pas:314 +msgid "Property category does not exist (%s)" +msgstr "Eigenschaftskategorie existiert nicht (%s)" + +#. Programmer's name for it: SActionCategoryName +#: Vcl/consts.pas:316 +msgid "Action" +msgstr "Aktion" + +#. Programmer's name for it: SActionCategoryDesc +#: Vcl/consts.pas:317 +msgid "Action properties and/or events" +msgstr "Aktionen Eigenschaften/Ereignisse" + +#. Programmer's name for it: SDataCategoryName +#: Vcl/consts.pas:318 +msgid "Data" +msgstr "Daten" + +#. Programmer's name for it: SDataCategoryDesc +#: Vcl/consts.pas:319 +msgid "Data properties and/or events" +msgstr "Dateneigenschaften und/oder -ereignisse" + +#. Programmer's name for it: SDatabaseCategoryName +#: Vcl/consts.pas:320 +msgid "Database" +msgstr "Datenbank" + +#. Programmer's name for it: SDatabaseCategoryDesc +#: Vcl/consts.pas:321 +msgid "Database and Data Aware properties and/or events" +msgstr "Daten- und datenbankbezogene Eigenschaften/Ereignisse" + +#. Programmer's name for it: SDragNDropCategoryName +#: Vcl/consts.pas:322 +msgid "Drag, Drop and Docking" +msgstr "Drag, Drop und Docking" + +#. Programmer's name for it: SDragNDropCategoryDesc +#: Vcl/consts.pas:323 +msgid "Drag, Drop and Docking properties and/or events" +msgstr "Eigenschaften/Ereignisse zu Drag, Drop und Docking" + +#. Programmer's name for it: SHelpCategoryName +#: Vcl/consts.pas:324 +msgid "Help and Hints" +msgstr "Hilfe und Hinweise" + +#. Programmer's name for it: SHelpCategoryDesc +#: Vcl/consts.pas:325 +msgid "Help and Hint properties and/or events" +msgstr "Eigenschaften/Ereignisse zu: Hilfe und Hinweise" + +#. Programmer's name for it: SLayoutCategoryName +#: Vcl/consts.pas:326 +msgid "Layout" +msgstr "Layout" + +#. Programmer's name for it: SLayoutCategoryDesc +#: Vcl/consts.pas:327 +msgid "Layout properties and/or events" +msgstr "Layout Eigenschaften/Ereignisse" + +#. Programmer's name for it: SLegacyCategoryName +#: Vcl/consts.pas:328 +msgid "Legacy" +msgstr "Legacy" + +#. Programmer's name for it: SLegacyCategoryDesc +#: Vcl/consts.pas:329 +msgid "Legacy properties and/or events" +msgstr "Vererbungsrelevante Eigenschaften/Ereignisse" + +#. Programmer's name for it: SLinkageCategoryName +#: Vcl/consts.pas:330 +msgid "Linkage" +msgstr "Linkage" + +#. Programmer's name for it: SLinkageCategoryDesc +#: Vcl/consts.pas:331 +msgid "Linkage properties and/or events" +msgstr "Verbindungsbezogene Eigenschaften/Ereignisse" + +#. Programmer's name for it: SLocaleCategoryName +#: Vcl/consts.pas:332 +msgid "Locale" +msgstr "Länderkennung" + +#. Programmer's name for it: SLocaleCategoryDesc +#: Vcl/consts.pas:333 +msgid "Locale properties and/or events" +msgstr "Lokale Eigenschaften/Ereignisse" + +#. Programmer's name for it: SLocalizableCategoryName +#: Vcl/consts.pas:334 +msgid "Localizable" +msgstr "Übersetzungsrelevant" + +#. Programmer's name for it: SLocalizableCategoryDesc +#: Vcl/consts.pas:335 +msgid "Localizable properties and/or events" +msgstr "Lokalisierbare Eigenschaften/Ereignisse" + +#. Programmer's name for it: SMiscellaneousCategoryName +#: Vcl/consts.pas:336 +msgid "Miscellaneous" +msgstr "Verschiedene" + +#. Programmer's name for it: SMiscellaneousCategoryDesc +#: Vcl/consts.pas:337 +msgid "Miscellaneous properties and/or events" +msgstr "Sonstige Eigenschaften/Ereignisse" + +#. Programmer's name for it: SVisualCategoryName +#: Vcl/consts.pas:338 +msgid "Visual" +msgstr "Visuell" + +#. Programmer's name for it: SVisualCategoryDesc +#: Vcl/consts.pas:339 +msgid "Visual properties and/or events" +msgstr "Visuelle Eigenschaften/Ereignisse" + +#. Programmer's name for it: SInputCategoryName +#: Vcl/consts.pas:340 +msgid "Input" +msgstr "Eingabe" + +#. Programmer's name for it: SInputCategoryDesc +#: Vcl/consts.pas:341 +msgid "Input properties and/or events" +msgstr "Eingabebezogene Eigenschaften/Ereignisse" + +#. Programmer's name for it: SInvalidMask +#: Vcl/consts.pas:343 +msgid "'%s' is an invalid mask at (%d)" +msgstr "'%s' ist eine ungültige Maske für (%d)" + +#. Programmer's name for it: SInvalidFilter +#: Vcl/consts.pas:344 +msgid "Property filters may only be name, class or type based (%d:%d)" +msgstr "Eigenschaftsfilter dürfen nur auf Name, Klasse oder Typ basieren (%d:%d)" + +#. Programmer's name for it: SInvalidCategory +#: Vcl/consts.pas:345 +msgid "Categories must define their own name and description" +msgstr "Kategorien müssen ihre eigenen Namen und Beschreibung definieren" + +#. Programmer's name for it: sOperationNotAllowed +#: Vcl/consts.pas:347 +msgid "Operation not allowed while dispatching application events" +msgstr "Operation bei der Weiterleitung von Anwendungsereignissen nicht gestattet" + +#. Programmer's name for it: sInvalidClassReference +#: Vcl/ctlpanel.pas:129 +msgid "Invalid class reference for TAppletApplication" +msgstr "Ungültige Klassenreferenz für TAppletApplication" + +#. Programmer's name for it: SInvalidFieldSize +#: Vcl/dbconsts.pas:15 +msgid "Invalid field size" +msgstr "Ungültige Feldgröße" + +#. Programmer's name for it: SInvalidFieldKind +#: Vcl/dbconsts.pas:16 +msgid "Invalid FieldKind" +msgstr "FieldKind ungültig" + +#. Programmer's name for it: SInvalidFieldRegistration +#: Vcl/dbconsts.pas:17 +msgid "Invalid field registration" +msgstr "Ungültige Feldregistrierung" + +#. Programmer's name for it: SUnknownFieldType +#: Vcl/dbconsts.pas:18 +msgid "Field '%s' is of an unknown type" +msgstr "Typ für Feld '%s' ist unbekannt" + +#. Programmer's name for it: SFieldNameMissing +#: Vcl/dbconsts.pas:19 +msgid "Field name missing" +msgstr "Feldname fehlt" + +#. Programmer's name for it: SDuplicateFieldName +#: Vcl/dbconsts.pas:20 +msgid "Duplicate field name '%s'" +msgstr "Doppelter Feldname '%s'" + +#. Programmer's name for it: SFieldNotFound +#: Vcl/dbconsts.pas:21 +msgid "Field '%s' not found" +msgstr "Das Feld '%s' wurde nicht gefunden" + +#. Programmer's name for it: SFieldAccessError +#: Vcl/dbconsts.pas:22 +msgid "Cannot access field '%s' as type %s" +msgstr "Feld '%s' kann nicht als Typ %s angesprochen werden" + +#. Programmer's name for it: SFieldValueError +#: Vcl/dbconsts.pas:23 +msgid "Invalid value for field '%s'" +msgstr "Ungültiger Wert für Feld '%s'" + +#. Programmer's name for it: SFieldRangeError +#: Vcl/dbconsts.pas:24 +msgid "%g is not a valid value for field '%s'. The allowed range is %g to %g" +msgstr "%g ist kein gültiger Wert für das Feld '%s'. Der zulässige Bereich ist %g bis %g" + +#. Programmer's name for it: SInvalidIntegerValue +#: Vcl/dbconsts.pas:25 +msgid "'%s' is not a valid integer value for field '%s'" +msgstr "'%s' ist kein gültiger Integerwert für Feld '%s'" + +#. Programmer's name for it: SInvalidBoolValue +#: Vcl/dbconsts.pas:26 +msgid "'%s' is not a valid boolean value for field '%s'" +msgstr "'%s' ist kein gültiger boolescher Wert für Feld '%s'" + +#. Programmer's name for it: SInvalidFloatValue +#: Vcl/dbconsts.pas:27 +msgid "'%s' is not a valid floating point value for field '%s'" +msgstr "'%s' ist kein gültiger Fließkommawert für Feld '%s'" + +#. Programmer's name for it: SFieldTypeMismatch +#: Vcl/dbconsts.pas:28 +msgid "Type mismatch for field '%s', expecting: %s actual: %s" +msgstr "Unterschiedliche Typen für Feld '%s'; erwartet: %s, gefunden: %s" + +#. Programmer's name for it: SFieldSizeMismatch +#: Vcl/dbconsts.pas:29 +msgid "Size mismatch for field '%s', expecting: %d actual: %d" +msgstr "Unterschiedliche Größe für Feld '%s'; erwartet: %d, gefunden: %d" + +#. Programmer's name for it: SInvalidVarByteArray +#: Vcl/dbconsts.pas:30 +msgid "Invalid variant type or size for field '%s'" +msgstr "Variant-Typ oder -größe für Feld '%s' ist ungültig" + +#. Programmer's name for it: SFieldOutOfRange +#: Vcl/dbconsts.pas:31 +msgid "Value of field '%s' is out of range" +msgstr "Wert des Feldes '%s' ist außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SBCDOverflow +#: Vcl/dbconsts.pas:32 +msgid "(Overflow)" +msgstr "(Überlauf)" + +#. Programmer's name for it: SFieldRequired +#: Vcl/dbconsts.pas:33 +msgid "Field '%s' must have a value" +msgstr "Feld '%s' muss einen Wert haben" + +#. Programmer's name for it: SDataSetMissing +#: Vcl/dbconsts.pas:34 +msgid "Field '%s' has no dataset" +msgstr "Feld '%s' hat keine Datenmenge" + +#. Programmer's name for it: SInvalidCalcType +#: Vcl/dbconsts.pas:35 +msgid "Field '%s' cannot be a calculated or lookup field" +msgstr "Feld '%s' kann kein berechnetes oder Nachschlage-Feld sein" + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/dbconsts.pas:36 +msgid "Field '%s' cannot be modified" +msgstr "Feld '%s' kann nicht verändert werden" + +#. Programmer's name for it: SFieldIndexError +#: Vcl/dbconsts.pas:37 +msgid "Field index out of range" +msgstr "Feldindex außerhalb des gültigen Bereichs" + +#. Programmer's name for it: SNoFieldIndexes +#: Vcl/dbconsts.pas:38 +msgid "No index currently active" +msgstr "Es ist momentan kein Index aktiv" + +#. Programmer's name for it: SNotIndexField +#: Vcl/dbconsts.pas:39 +msgid "Field '%s' is not indexed and cannot be modified" +msgstr "Feld '%s' ist nicht indiziert und kann nicht verändert werden" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/dbconsts.pas:40 +msgid "Cannot access index field '%s'" +msgstr "Zugriff auf Indexfeld '%s' nicht möglich" + +#. Programmer's name for it: SDuplicateIndexName +#: Vcl/dbconsts.pas:41 +msgid "Duplicate index name '%s'" +msgstr "Doppelter Indexname '%s'" + +#. Programmer's name for it: SNoIndexForFields +#: Vcl/dbconsts.pas:42 +msgid "No index for fields '%s'" +msgstr "Kein Index für die Felder '%s' vorhanden" + +#. Programmer's name for it: SIndexNotFound +#: Vcl/dbconsts.pas:43 +msgid "Index '%s' not found" +msgstr "Index '%s' wurde nicht gefunden" + +#. Programmer's name for it: SDuplicateName +#: Vcl/dbconsts.pas:44 +msgid "Duplicate name '%s' in %s" +msgstr "Doppelter Name '%s' in %s" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/dbconsts.pas:45 +msgid "Circular datalinks are not allowed" +msgstr "Zirkuläre Datenverbindungen sind nicht erlaubt" + +#. Programmer's name for it: SLookupInfoError +#: Vcl/dbconsts.pas:46 +msgid "Lookup information for field '%s' is incomplete" +msgstr "Lookup-Information für Feld '%s' ist unvollständig" + +#. Programmer's name for it: SDataSourceChange +#: Vcl/dbconsts.pas:47 +msgid "DataSource cannot be changed" +msgstr "DataSource kann nicht geändert werden" + +#. Programmer's name for it: SNoNestedMasterSource +#: Vcl/dbconsts.pas:48 +msgid "Nested datasets cannot have a MasterSource" +msgstr "Bei verschachtelten Datenmengen ist MasterSource nicht zulässig" + +#. Programmer's name for it: SDataSetOpen +#: Vcl/dbconsts.pas:49 +msgid "Cannot perform this operation on an open dataset" +msgstr "Operation bei geöffneter Datenmenge nicht ausführbar" + +#. Programmer's name for it: SNotEditing +#: Vcl/dbconsts.pas:50 +msgid "Dataset not in edit or insert mode" +msgstr "Datenmenge weder im Editier- noch im Einfügemodus" + +#. Programmer's name for it: SDataSetClosed +#: Vcl/dbconsts.pas:51 +msgid "Cannot perform this operation on a closed dataset" +msgstr "Operation bei geschlossener Datenmenge nicht ausführbar" + +#. Programmer's name for it: SDataSetEmpty +#: Vcl/dbconsts.pas:52 +msgid "Cannot perform this operation on an empty dataset" +msgstr "Operation bei leerer Datenmenge nicht ausführbar" + +#. Programmer's name for it: SDataSetReadOnly +#: Vcl/dbconsts.pas:53 +msgid "Cannot modify a read-only dataset" +msgstr "Eine Datenmenge, die nur zum Lesen ist, kann nicht geändert werden" + +#. Programmer's name for it: SNestedDataSetClass +#: Vcl/dbconsts.pas:54 +msgid "Nested dataset must inherit from %s" +msgstr "Verschachtelte Datenmengen müssen von %s vererbt sein" + +#. Programmer's name for it: SExprTermination +#: Vcl/dbconsts.pas:55 +msgid "Filter expression incorrectly terminated" +msgstr "Filterausdruck fehlerhaft abgeschlossen" + +#. Programmer's name for it: SExprNameError +#: Vcl/dbconsts.pas:56 +msgid "Unterminated field name" +msgstr "Nicht begrenzter Feldname" + +#. Programmer's name for it: SExprStringError +#: Vcl/dbconsts.pas:57 +msgid "Unterminated string constant" +msgstr "Nicht begrenzte String-Konstante" + +#. Programmer's name for it: SExprInvalidChar +#: Vcl/dbconsts.pas:58 +msgid "Invalid filter expression character: '%s'" +msgstr "Ungültiges Zeichen in Filterausdruck: '%s'" + +#. Programmer's name for it: SExprNoLParen +#: Vcl/dbconsts.pas:59 +msgid "'(' expected but %s found" +msgstr "'(' erwartet, aber %s vorgefunden" + +#. Programmer's name for it: SExprNoRParen +#: Vcl/dbconsts.pas:60 +msgid "')' expected but %s found" +msgstr "')' erwartet, jedoch %s vorgefunden" + +#. Programmer's name for it: SExprNoRParenOrComma +#: Vcl/dbconsts.pas:61 +msgid "')' or ',' expected but %s found" +msgstr "')' oder ',' erwartet, jedoch %s vorgefunden" + +#. Programmer's name for it: SExprExpected +#: Vcl/dbconsts.pas:62 +msgid "Expression expected but %s found" +msgstr "Ausdruck erwartet, jedoch %s vorgefunden" + +#. Programmer's name for it: SExprBadField +#: Vcl/dbconsts.pas:63 +msgid "Field '%s' cannot be used in a filter expression" +msgstr "Feld '%s' kann nicht in einem Filterausdruck verwendet werden" + +#. Programmer's name for it: SExprBadNullTest +#: Vcl/dbconsts.pas:64 +msgid "NULL only allowed with '=' and '<>'" +msgstr "NULL ist nur mit '=' und '<>' erlaubt" + +#. Programmer's name for it: SExprRangeError +#: Vcl/dbconsts.pas:65 +msgid "Constant out of range" +msgstr "Konstante außerhalb des zulässigen Wertebereichs" + +#. Programmer's name for it: SExprNotBoolean +#: Vcl/dbconsts.pas:66 +msgid "Field '%s' is not of type Boolean" +msgstr "Feld '%s' ist kein boolescher Typ" + +#. Programmer's name for it: SExprIncorrect +#: Vcl/dbconsts.pas:67 +msgid "Incorrectly formed filter expression" +msgstr "Ungültiger Filterausdruck" + +#. Programmer's name for it: SExprNothing +#: Vcl/dbconsts.pas:68 +msgid "nothing" +msgstr "leer" + +#. Programmer's name for it: SExprTypeMis +#: Vcl/dbconsts.pas:69 +msgid "Type mismatch in expression" +msgstr "Fehlende Typübereinstimmung im Ausdruck" + +#. Programmer's name for it: SExprBadScope +#: Vcl/dbconsts.pas:70 +msgid "Operation cannot mix aggregate value with record-varying value" +msgstr "Die Operation kann keine Zusammenfassungswerte mit Datensatzwerten mischen" + +#. Programmer's name for it: SExprNoArith +#: Vcl/dbconsts.pas:71 +msgid "Arithmetic in filter expressions not supported" +msgstr "Arithmetische Filterausdrücke werden nicht unterstützt" + +#. Programmer's name for it: SExprNotAgg +#: Vcl/dbconsts.pas:72 +msgid "Expression is not an aggregate expression" +msgstr "Der Ausdruck ist kein Aggregat-Ausdruck" + +#. Programmer's name for it: SExprBadConst +#: Vcl/dbconsts.pas:73 +msgid "Constant is not correct type %s" +msgstr "Die Konstante ist nicht vom richtigen Typ %s" + +#. Programmer's name for it: SExprNoAggFilter +#: Vcl/dbconsts.pas:74 +msgid "Aggregate expressions not allowed in filters" +msgstr "In Filtern sind keine Aggregationsausdrücke erlaubt" + +#. Programmer's name for it: SExprEmptyInList +#: Vcl/dbconsts.pas:75 +msgid "IN predicate list may not be empty" +msgstr "Die IN-Liste darf nicht leer bleiben" + +#. Programmer's name for it: SInvalidKeywordUse +#: Vcl/dbconsts.pas:76 +msgid "Invalid use of keyword" +msgstr "Ungültige Verwendung eines Schlüsselworts" + +#. Programmer's name for it: SParameterNotFound +#: Vcl/dbconsts.pas:79 +msgid "Parameter '%s' not found" +msgstr "Parameter '%s' nicht gefunden" + +#. Programmer's name for it: SInvalidVersion +#: Vcl/dbconsts.pas:80 +msgid "Unable to load bind parameters" +msgstr "Bind-Parameter können nicht geladen werden" + +#. Programmer's name for it: SParamTooBig +#: Vcl/dbconsts.pas:81 +msgid "Parameter '%s', cannot save data larger than %d bytes" +msgstr "Parameter '%s': Daten, die größer sind als %d Byte, können nicht gespeichert werden" + +#. Programmer's name for it: SBadFieldType +#: Vcl/dbconsts.pas:82 +msgid "Field '%s' is of an unsupported type" +msgstr "Der Typ von Feld '%s' wird nicht unterstützt" + +#. Programmer's name for it: SAggActive +#: Vcl/dbconsts.pas:83 +msgid "Property may not be modified while aggregate is active" +msgstr "Die Eigenschaft kann nicht geändert werden, während die Aggregatfunktion aktiv ist" + +#. Programmer's name for it: SProviderSQLNotSupported +#: Vcl/dbconsts.pas:84 +msgid "SQL not supported: %s" +msgstr "SQL nicht unterstützt: %s" + +#. Programmer's name for it: SProviderExecuteNotSupported +#: Vcl/dbconsts.pas:85 +msgid "Execute not supported: %s" +msgstr "Ausführung nicht unterstützt: %s" + +#. Programmer's name for it: SExprNoAggOnCalcs +#: Vcl/dbconsts.pas:86 +msgid "Field '%s' is not the correct type of calculated field to be used in an aggregate, use an internalcalc" +msgstr "Feld '%s' ist nicht der korrekte Typ eines berechneten Feldes für eine Aggregierung; verwenden Sie internalcalc" + +#. Programmer's name for it: SRecordChanged +#: Vcl/dbconsts.pas:87 +msgid "Record changed by another user" +msgstr "Der Datensatz wurde von einem anderen Anwender geändert" + +#. Programmer's name for it: SFirstRecord +#: Vcl/dbconsts.pas:90 +msgid "First record" +msgstr "Erster Datensatz" + +#. Programmer's name for it: SPriorRecord +#: Vcl/dbconsts.pas:91 +msgid "Prior record" +msgstr "Vorheriger Datensatz" + +#. Programmer's name for it: SNextRecord +#: Vcl/dbconsts.pas:92 +msgid "Next record" +msgstr "Nächster Datensatz" + +#. Programmer's name for it: SLastRecord +#: Vcl/dbconsts.pas:93 +msgid "Last record" +msgstr "Letzter Datensatz" + +#. Programmer's name for it: SInsertRecord +#: Vcl/dbconsts.pas:94 +msgid "Insert record" +msgstr "Datensatz einfügen" + +#. Programmer's name for it: SDeleteRecord +#: Vcl/dbconsts.pas:95 +msgid "Delete record" +msgstr "Datensatz löschen" + +#. Programmer's name for it: SEditRecord +#: Vcl/dbconsts.pas:96 +msgid "Edit record" +msgstr "Datensatz bearbeiten" + +#. Programmer's name for it: SPostEdit +#: Vcl/dbconsts.pas:97 +msgid "Post edit" +msgstr "Übernehmen" + +#. Programmer's name for it: SCancelEdit +#: Vcl/dbconsts.pas:98 +msgid "Cancel edit" +msgstr "Bearbeiten abbrechen" + +#. Programmer's name for it: SRefreshRecord +#: Vcl/dbconsts.pas:99 +msgid "Refresh data" +msgstr "Daten aktualisieren" + +#. Programmer's name for it: SDeleteRecordQuestion +#: Vcl/dbconsts.pas:100 +msgid "Delete record?" +msgstr "Datensatz löschen?" + +#. Programmer's name for it: SDeleteMultipleRecordsQuestion +#: Vcl/dbconsts.pas:101 +msgid "Delete all selected records?" +msgstr "Alle markierten Datensätze löschen?" + +#. Programmer's name for it: SRecordNotFound +#: Vcl/dbconsts.pas:102 +msgid "Record not found" +msgstr "Datensatz nicht gefunden" + +#. Programmer's name for it: SDataSourceFixed +#: Vcl/dbconsts.pas:103 +msgid "Operation not allowed in a DBCtrlGrid" +msgstr "Operation in einem DBCtrlGrid nicht erlaubt" + +#. Programmer's name for it: SNotReplicatable +#: Vcl/dbconsts.pas:104 +msgid "Control cannot be used in a DBCtrlGrid" +msgstr "Element kann in einem DBCtrlGrid nicht verwendet werden" + +#. Programmer's name for it: SPropDefByLookup +#: Vcl/dbconsts.pas:105 +msgid "Property already defined by lookup field" +msgstr "Eigenschaft bereits durch Lookup-Feld definiert" + +#. Programmer's name for it: STooManyColumns +#: Vcl/dbconsts.pas:106 +msgid "Grid requested to display more than 256 columns" +msgstr "Gitter soll mehr als 256 Spalten darstellen" + +#. Programmer's name for it: SRemoteLogin +#: Vcl/dbconsts.pas:109 +msgid "Remote Login" +msgstr "Externe Anmeldung" + +#. Programmer's name for it: SDataBindings +#: Vcl/dbconsts.pas:112 +msgid "Data Bindings..." +msgstr "Datenbindungen..." + +#. Programmer's name for it: SIBTransactionEditor +#: Vcl/ib.pas:156 +msgid "&Transaction Editor..." +msgstr "Transa&ktions-Editor..." + +#. Programmer's name for it: SDatabaseFilter +#: Vcl/ib.pas:157 +msgid "Database Files (*.gdb)|*.gdb|All files (*.*)|*.*" +msgstr "Datenbank-Dateien (*.gdb)|*.gdb|Alle Dateien (*.*)|*.*" + +#. Programmer's name for it: SCommitTransaction +#: Vcl/ib.pas:159 +msgid "Transaction is currently Active. Rollback and continue?" +msgstr "Es ist gerade eine Transaktion aktiv. Zurücksetzen und weitermachen?" + +#. Programmer's name for it: SUnknownError +#: Vcl/ib.pas:168 +msgid "Unknown error" +msgstr "Unbekannter Fehler." + +#. Programmer's name for it: SInterBaseMissing +#: Vcl/ib.pas:169 +msgid "InterBase library gds32.dll not found in the path. Please install InterBase to use this functionality" +msgstr "InterBase-DLL gds32.dll wurde im Pfad nicht gefunden" + +#. Programmer's name for it: SInterBaseInstallMissing +#: Vcl/ib.pas:170 +msgid "InterBase Install DLL ibinstall.dll not found in the path. Please install InterBase 6 to use this functionality" +msgstr "Die InterBase-Installations-DLL ibinstall.dll wurde im Pfad nicht gefunden" + +#. Programmer's name for it: SIB60feature +#: Vcl/ib.pas:171 +msgid "%s is an InterBase6 function. Please upgrade to InterBase6 to use this functonality" +msgstr "%s ist eine Funktion von InterBase 6. Um diese Funktionalität zu nutzen, müssen Sie auf IB6 updaten" + +#. Programmer's name for it: SNotSupported +#: Vcl/ib.pas:172 +msgid "Unsupported feature" +msgstr "Nicht unterstütztes Merkmal." + +#. Programmer's name for it: SNotPermitted +#: Vcl/ib.pas:173 +msgid "Not permitted" +msgstr "Nicht gestattet." + +#. Programmer's name for it: SFileAccessError +#: Vcl/ib.pas:174 +msgid "Temporary file access error" +msgstr "Zugriffsfehler bei temporären Dateien." + +#. Programmer's name for it: SConnectionTimeout +#: Vcl/ib.pas:175 +msgid "Database connection timed out" +msgstr "Zeitüberschreitung bei Datenbankverbindung." + +#. Programmer's name for it: SCannotSetDatabase +#: Vcl/ib.pas:176 +msgid "Cannot set database" +msgstr "Datenbank kann nicht gesetzt werden." + +#. Programmer's name for it: SCannotSetTransaction +#: Vcl/ib.pas:177 +msgid "Cannot set transaction" +msgstr "Transaktion kann nicht gesetzt werden." + +#. Programmer's name for it: SOperationCancelled +#: Vcl/ib.pas:178 +msgid "Operation cancelled at user's request" +msgstr "Die Operation wurde auf Anforderung des Anwenders abgebrochen." + +#. Programmer's name for it: SDPBConstantNotSupported +#: Vcl/ib.pas:179 +msgid "DPB Constant (isc_dpb_%s) is unsupported" +msgstr "DPB-Konstante (isc_dpb_%s) wird nicht unterstützt." + +#. Programmer's name for it: SDPBConstantUnknown +#: Vcl/ib.pas:180 +msgid "DPB Constant (%d) is unknown" +msgstr "DPB-Konstante (%d) ist unbekannt." + +#. Programmer's name for it: STPBConstantNotSupported +#: Vcl/ib.pas:181 +msgid "TPB Constant (isc_tpb_%s) is unsupported" +msgstr "TPB-Konstante (isc_tpb_%s) ist nicht unterstützt." + +#. Programmer's name for it: STPBConstantUnknown +#: Vcl/ib.pas:182 +msgid "TPB Constant (%d) is unknown" +msgstr "TPB-Konstante (%d) ist unbekannt." + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/ib.pas:183 +msgid "Cannot perform operation -- DB is not open" +msgstr "Operation kann nicht durchgeführt werden -- DB ist nicht offen." + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/ib.pas:184 +msgid "Cannot perform operation -- DB is currently open" +msgstr "Operation kann nicht durchgeführt werden -- DB ist im Moment geöffnet." + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/ib.pas:185 +msgid "Database name is missing" +msgstr "Der Name der Datenbank fehlt." + +#. Programmer's name for it: SNotInTransaction +#: Vcl/ib.pas:186 +msgid "Transaction is not active" +msgstr "Transaktion ist nicht aktiv." + +#. Programmer's name for it: SInTransaction +#: Vcl/ib.pas:187 +msgid "Transaction is active" +msgstr "Transaktion ist aktiv." + +#. Programmer's name for it: STimeoutNegative +#: Vcl/ib.pas:188 +msgid "Timeout values cannot be negative" +msgstr "Werte für Zeitüberschreitung dürfen nicht negativ sein." + +#. Programmer's name for it: SNoDatabasesInTransaction +#: Vcl/ib.pas:189 +msgid "No databases are listed in transaction component" +msgstr "In der Transaktionskomponente sind keine Datenbanken aufgeführt." + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/ib.pas:190 +msgid "Updating wrong database" +msgstr "Es wurde die falsche Datenbank aktualisiert." + +#. Programmer's name for it: SUpdateWrongTR +#: Vcl/ib.pas:191 +msgid "Updating wrong transaction. Unique transaction expected in set" +msgstr "Aktualisierung der falschen Transaktion. In der Menge wird eine eindeutige Transaktion erwartet" + +#. Programmer's name for it: SDatabaseNotAssigned +#: Vcl/ib.pas:192 +msgid "Database not assigned" +msgstr "Datenbank nicht zugewiesen." + +#. Programmer's name for it: STransactionNotAssigned +#: Vcl/ib.pas:193 +msgid "Transaction not assigned" +msgstr "Transaktion ist nicht zugewiesen." + +#. Programmer's name for it: SXSQLDAIndexOutOfRange +#: Vcl/ib.pas:194 +msgid "XSQLDA index out of range" +msgstr "XSQLDA-Index außerhalb des gültigen Bereichs." + +#. Programmer's name for it: SXSQLDANameDoesNotExist +#: Vcl/ib.pas:195 +msgid "XSQLDA name does not exist (%s)" +msgstr "XSQLDA-Name existiert nicht (%s)." + +#. Programmer's name for it: SEOF +#: Vcl/ib.pas:196 +msgid "End of file" +msgstr "Ende der Datei." + +#. Programmer's name for it: SBOF +#: Vcl/ib.pas:197 +msgid "Beginning of file" +msgstr "Beginn der Datei." + +#. Programmer's name for it: SInvalidStatementHandle +#: Vcl/ib.pas:198 +msgid "Invalid statement handle" +msgstr "Ungültiges Anweisungs-Handle." + +#. Programmer's name for it: SSQLOpen +#: Vcl/ib.pas:199 +msgid "IBSQL Open" +msgstr "IBSQL geöffnet" + +#. Programmer's name for it: SSQLClosed +#: Vcl/ib.pas:200 +msgid "IBSQL Closed" +msgstr "IBSQL geschlossen" + +#. Programmer's name for it: SDatasetOpen +#: Vcl/ib.pas:201 +msgid "Dataset open" +msgstr "Datenmenge geöffnet." + +#. Programmer's name for it: SDatasetClosed +#: Vcl/ib.pas:202 +msgid "Dataset closed" +msgstr "Datenmenge geschlossen." + +#. Programmer's name for it: SUnknownSQLDataType +#: Vcl/ib.pas:203 +msgid "Unknown SQL Data type (%d)" +msgstr "Unbekannter SQL-Datentyp (%d)." + +#. Programmer's name for it: SInvalidColumnIndex +#: Vcl/ib.pas:204 +msgid "Invalid column index (index exceeds permitted range)" +msgstr "Ungültiger Spaltenindex (Der Index überschreitet den erlaubten Bereich)." + +#. Programmer's name for it: SInvalidParamColumnIndex +#: Vcl/ib.pas:205 +msgid "Invalid parameter index (index exceeds permitted range)" +msgstr "Ungültiger Parameterindex (Der Index überschreitet den erlaubten Bereich)." + +#. Programmer's name for it: SInvalidDataConversion +#: Vcl/ib.pas:206 +msgid "Invalid data conversion" +msgstr "Ungültige Datenkonvertierung." + +#. Programmer's name for it: SColumnIsNotNullable +#: Vcl/ib.pas:207 +msgid "Column cannot be set to null (%s)" +msgstr "Spalte kann nicht auf null gesetzt werden (%s)" + +#. Programmer's name for it: SBlobCannotBeRead +#: Vcl/ib.pas:208 +msgid "Blob stream cannot be read" +msgstr "Blob-Stream kann nicht gelesen werden." + +#. Programmer's name for it: SBlobCannotBeWritten +#: Vcl/ib.pas:209 +msgid "Blob stream cannot be written" +msgstr "Blob-Stream kann nicht geschrieben werden." + +#. Programmer's name for it: SEmptyQuery +#: Vcl/ib.pas:210 +msgid "Empty query" +msgstr "Leere Abfrage." + +#. Programmer's name for it: SCannotOpenNonSQLSelect +#: Vcl/ib.pas:211 +msgid "Cannot \"open\" a non-select statement. Use ExecQuery" +msgstr "Ein Nicht-Select-Statement kann nicht \"geöffnet\" werden. Verwenden Sie ExecQuery." + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/ib.pas:212 +msgid "No access to field \"%s\"" +msgstr "Kein Zugriff auf Feld \"%s\"." + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/ib.pas:213 +msgid "Field \"%s\" is read-only" +msgstr "Feld \"%s\" ist schreibgeschützt." + +#. Programmer's name for it: SFieldNotFound +#: Vcl/ib.pas:214 +msgid "Field \"%s\" not found" +msgstr "Feld \"%s\" konnte nicht gefunden werden." + +#. Programmer's name for it: SNotEditing +#: Vcl/ib.pas:215 +msgid "Not editing" +msgstr "Kein Bearbeiten." + +#. Programmer's name for it: SCannotInsert +#: Vcl/ib.pas:216 +msgid "Cannot insert into dataset. (No insert query)" +msgstr "In Datenmenge kann nicht eingefügt werden. (Keine Einfüge-Abfrage)." + +#. Programmer's name for it: SCannotPost +#: Vcl/ib.pas:217 +msgid "Cannot post. (No update/insert query)" +msgstr "Zurückschreiben nicht möglich. (Keine Aktualisierungs-/Einfügen-Abfrage)" + +#. Programmer's name for it: SCannotUpdate +#: Vcl/ib.pas:218 +msgid "Cannot update. (No update query)" +msgstr "Keine Aktualisierung möglich. (Keine Aktualisierungs-Abfrage)." + +#. Programmer's name for it: SCannotDelete +#: Vcl/ib.pas:219 +msgid "Cannot delete from dataset. (No delete query)" +msgstr "Aus der Datenmenge kann nichts gelöscht werden. (Keine Lösch-Abfrage)." + +#. Programmer's name for it: SCannotRefresh +#: Vcl/ib.pas:220 +msgid "Cannot refresh row. (No refresh query)" +msgstr "Zeile kann nicht aktualisiert werden. (Keine Aktualisierungs-Abfrage)." + +#. Programmer's name for it: SBufferNotSet +#: Vcl/ib.pas:221 +msgid "Buffer not set" +msgstr "Puffer nicht gesetzt." + +#. Programmer's name for it: SCircularReference +#: Vcl/ib.pas:222 +msgid "Circular references not permitted" +msgstr "Zirkuläre Verweise sind nicht gestattet." + +#. Programmer's name for it: SSQLParseError +#: Vcl/ib.pas:223 +msgid "" +"SQL Parse Error:\n" +"\n" +"%s" +msgstr "" +"Fehler bei der SQL-Auswertung:\n" +"\n" +"%s" + +#. Programmer's name for it: SUserAbort +#: Vcl/ib.pas:224 +msgid "User abort" +msgstr "Abbruch durch Anwender." + +#. Programmer's name for it: SDataSetUniDirectional +#: Vcl/ib.pas:225 +msgid "Data set is uni-directional" +msgstr "Datenmenge ist unidirektional." + +#. Programmer's name for it: SCannotCreateSharedResource +#: Vcl/ib.pas:226 +msgid "Cannot create shared resource. (Windows error %d)" +msgstr "Gemeinsam genutzte Ressource kann nicht erzeugt werden. (Windows-Fehler %d)" + +#. Programmer's name for it: SWindowsAPIError +#: Vcl/ib.pas:227 +msgid "Windows API error. (Windows error %d [$%.8x])" +msgstr "Fehler der Windows-API. (Windows-Fehler %d [$%.8x])" + +#. Programmer's name for it: SColumnListsDontMatch +#: Vcl/ib.pas:228 +msgid "Column lists do not match" +msgstr "Fehlende Überinstimmung bei Spaltenlisten." + +#. Programmer's name for it: SColumnTypesDontMatch +#: Vcl/ib.pas:229 +msgid "Column types don't match. (From index: %d; To index: %d)" +msgstr "Spaltentypen stimmen nicht überein. (Von Index: %d; Zu Index: %d)" + +#. Programmer's name for it: SCantEndSharedTransaction +#: Vcl/ib.pas:231 +msgid "Can't end a shared transaction unless it is forced and equal to the transaction's TimeoutAction" +msgstr "Eine gemeinsame Transaktion kann nicht beendet werden, außer es wird erzwungen und ist gleich der TimeOutAction der Transaktion." + +#. Programmer's name for it: SFieldUnsupportedType +#: Vcl/ib.pas:232 +msgid "Unsupported Field Type" +msgstr "Nicht unterstützter Feldtyp" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/ib.pas:233 +msgid "Circular DataLink Reference" +msgstr "Zirkuläre DataLink-Verweis" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/ib.pas:234 +msgid "Empty SQL Statement" +msgstr "Leere SQL-Anweisung." + +#. Programmer's name for it: SIsASelectStatement +#: Vcl/ib.pas:235 +msgid "use Open for a Select Statement" +msgstr "Verwenden Sie Open für eine Select-Anweisung" + +#. Programmer's name for it: SRequiredParamNotSet +#: Vcl/ib.pas:236 +msgid "Required Param value not set" +msgstr "Wert für Required Param nicht gesetzt" + +#. Programmer's name for it: SNoStoredProcName +#: Vcl/ib.pas:237 +msgid "No Stored Procedure Name assigned" +msgstr "Stored Procedure wurde kein Name zugewiesen" + +#. Programmer's name for it: SIsAExecuteProcedure +#: Vcl/ib.pas:238 +msgid "use ExecProc for Procedure; use TQuery for Select procedures" +msgstr "Verwenden Sie ExecProc für Prozeduren; verwenden SieTQuery für Select-Prozeduren" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/ib.pas:239 +msgid "Update Failed" +msgstr "Aktualisierung nicht erfolgreich" + +#. Programmer's name for it: SNotCachedUpdates +#: Vcl/ib.pas:240 +msgid "CachedUpdates not enabled" +msgstr "CachedUpdates ist nicht aktiviert" + +#. Programmer's name for it: SNotLiveRequest +#: Vcl/ib.pas:241 +msgid "Request is not live - cannot modify" +msgstr "Die Anforderung ist nicht 'live' - Änderung nicht möglich." + +#. Programmer's name for it: SNoProvider +#: Vcl/ib.pas:242 +msgid "No Provider" +msgstr "Kein Provider" + +#. Programmer's name for it: SNoRecordsAffected +#: Vcl/ib.pas:243 +msgid "No Records Affected" +msgstr "Keine Datensätze betroffen" + +#. Programmer's name for it: SNoTableName +#: Vcl/ib.pas:244 +msgid "No Table Name assigned" +msgstr "Kein Tabellenname zugewiesen" + +#. Programmer's name for it: SCannotCreatePrimaryIndex +#: Vcl/ib.pas:245 +msgid "Cannot Create Primary Index; are created automatically" +msgstr "Primärindizes können nicht erzeugt werden, da sie automatisch erzeugt werden" + +#. Programmer's name for it: SCannotDropSystemIndex +#: Vcl/ib.pas:246 +msgid "Cannot Drop System Index" +msgstr "Systemindex kann nicht entfernt werden" + +#. Programmer's name for it: STableNameMismatch +#: Vcl/ib.pas:247 +msgid "Table Name Mismatch" +msgstr "Fehlende Übereinstimmung bei Tabellennamen" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/ib.pas:248 +msgid "Index Field Missing" +msgstr "Indexfeld fehlt" + +#. Programmer's name for it: SInvalidCancellation +#: Vcl/ib.pas:249 +msgid "Cannot Cancel events while processing" +msgstr "Während deren Bearbeitung können Ereignisse nicht abgebrochen werden" + +#. Programmer's name for it: SInvalidEvent +#: Vcl/ib.pas:250 +msgid "Invalid Event" +msgstr "Ungültiges Ereignis" + +#. Programmer's name for it: SMaximumEvents +#: Vcl/ib.pas:251 +msgid "Exceded Maximum Event limits" +msgstr "Das Maximum an Ereignissen wurde überschritten" + +#. Programmer's name for it: SNoEventsRegistered +#: Vcl/ib.pas:252 +msgid "No Events Registered" +msgstr "Es sind keine Ereignisse registriert" + +#. Programmer's name for it: SInvalidQueueing +#: Vcl/ib.pas:253 +msgid "Invalid Queueing" +msgstr "Ungültiges Queueing" + +#. Programmer's name for it: SInvalidRegistration +#: Vcl/ib.pas:254 +msgid "Invalid Registration" +msgstr "Ungültige Registrierung" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/ib.pas:255 +msgid "Invalid Batch Move" +msgstr "Ungültige Batch-Operation" + +#. Programmer's name for it: SSQLDialectInvalid +#: Vcl/ib.pas:256 +msgid "SQL Dialect Invalid" +msgstr "Ungültiger SQL-Dialekt" + +#. Programmer's name for it: SSPBConstantNotSupported +#: Vcl/ib.pas:257 +msgid "SPB Constant Not supported" +msgstr "SPB-Konstante nicht unterstützt" + +#. Programmer's name for it: SSPBConstantUnknown +#: Vcl/ib.pas:258 +msgid "SPB Constant Unknown" +msgstr "SPB-Konstante unbekannt" + +#. Programmer's name for it: SServiceActive +#: Vcl/ib.pas:259 +msgid "Cannot perform operation -- service is not attached" +msgstr "Operation kann nicht durchgeführt werden -- Es ist kein Service verbunden." + +#. Programmer's name for it: SServiceInActive +#: Vcl/ib.pas:260 +msgid "Cannot perform operation -- service is attached" +msgstr "Operation kann nicht durchgeführt werden -- Ein Service ist verbunden." + +#. Programmer's name for it: SServerNameMissing +#: Vcl/ib.pas:261 +msgid "Server Name Missing" +msgstr "Server-Name fehlt" + +#. Programmer's name for it: SQueryParamsError +#: Vcl/ib.pas:262 +msgid "Query Parameters missing or incorrect" +msgstr "Abfrageparameter fehlen oder sind nicht korrekt" + +#. Programmer's name for it: SStartParamsError +#: Vcl/ib.pas:263 +msgid "start Parameters missing or incorrect" +msgstr "start-Parameter fehlen oder sind nicht korrekt" + +#. Programmer's name for it: SOutputParsingError +#: Vcl/ib.pas:264 +msgid "Unexpected Output buffer value" +msgstr "Unerwarteter Wert für Ausgabepuffer" + +#. Programmer's name for it: SUseSpecificProcedures +#: Vcl/ib.pas:265 +msgid "Generic ServiceStart not applicable: Use Specific Procedures to set configuration params" +msgstr "Generisches ServiceStart ist hier nicht anwendbar: Verwenden Sie spezifische Prozeduren, um die Konfigurationsparameter zu setzen." + +#. Programmer's name for it: SSQLMonitorAlreadyPresent +#: Vcl/ib.pas:266 +msgid "SQL Monitor Instance is already present" +msgstr "Es gibt schon eine Instanz des SQL-Monitor" + +#. Programmer's name for it: SEOFInComment +#: Vcl/ibsql.pas:24 +msgid "EOF in comment detected" +msgstr "EOF im Kommentar gefunden" + +#. Programmer's name for it: SEOFInString +#: Vcl/ibsql.pas:25 +msgid "EOF in string detected" +msgstr "EOF im String gefunden" + +#. Programmer's name for it: SParamNameExpected +#: Vcl/ibsql.pas:26 +msgid "Parameter name expected" +msgstr "Parametername erwartet" + +#. Programmer's name for it: SCantPrintValue +#: Vcl/ibsqlmonitor.pas:24 +msgid "Cannot print value" +msgstr "Wert kann nicht gedruckt werden" + +#. Programmer's name for it: SEOFReached +#: Vcl/ibsqlmonitor.pas:25 +msgid "SEOFReached" +msgstr "SEOFReached" + +#. Programmer's name for it: SProviderNotExported +#: Vcl/midconst.pas:33 +msgid "Provider not exported: %s" +msgstr "Der Provider wurde nicht exportiert: %s" + +#. Programmer's name for it: SNoDataProvider +#: Vcl/midconst.pas:36 +msgid "Missing data provider or data packet" +msgstr "Fehlender Daten-Provider oder Datenpaket" + +#. Programmer's name for it: SInvalidDataPacket +#: Vcl/midconst.pas:37 +msgid "Invalid data packet" +msgstr "Ungültiges Datenpaket" + +#. Programmer's name for it: SRefreshError +#: Vcl/midconst.pas:38 +msgid "Must apply updates before refreshing data" +msgstr "Die Änderungen müssen vor der Aktualisierung der Daten übernommen werden" + +#. Programmer's name for it: SProviderInvalid +#: Vcl/midconst.pas:39 +msgid "Invalid provider. Provider was freed by the application server" +msgstr "Ungültiger Provider. Der Provider wurde bereits vom Anwendungsserver entladen" + +#. Programmer's name for it: SServerNameBlank +#: Vcl/midconst.pas:40 +msgid "Cannot connect, %s must contain a valid ServerName or ServerGUID" +msgstr "Es kann keine Verbindung hergestellt werden; %s muss einen gültigen Server-Namen oder eine ServerGUID enthalten" + +#. Programmer's name for it: SRepositoryIdBlank +#: Vcl/midconst.pas:41 +msgid "Cannot connect, %s must contain a valid repository id" +msgstr "Es kann keine Verbindung hergestellt werden; %s muss eine gültige Objketablagen-ID enthalten" + +#. Programmer's name for it: SAggsGroupingLevel +#: Vcl/midconst.pas:42 +msgid "Grouping level exceeds current index field count" +msgstr "Die Gruppierungsebene überschreitet die aktuelle Feldanzahl des Index" + +#. Programmer's name for it: SAggsNoSuchLevel +#: Vcl/midconst.pas:43 +msgid "Grouping level not defined" +msgstr "Die Gruppierungsebene ist nicht definiert" + +#. Programmer's name for it: SNoCircularReference +#: Vcl/midconst.pas:44 +msgid "Circular provider references not allowed" +msgstr "Zirkuläre Verweise von Providern sind nicht gestattet" + +#. Programmer's name for it: SErrorLoadingMidas +#: Vcl/midconst.pas:45 +msgid "Error loading MIDAS.DLL" +msgstr "Fehler beim Laden von MIDAS.DLL" + +#. Programmer's name for it: SCannotCreateDataSet +#: Vcl/midconst.pas:46 +msgid "No fields defined. Cannot create dataset" +msgstr "Es wurden keine Felder definiert. Datenmenge kann nicht erzeugt werden" + +#. Programmer's name for it: SSocketReadError +#: Vcl/midconst.pas:49 +msgid "Error reading from socket" +msgstr "Fehler beim Lesen aus Socket" + +#. Programmer's name for it: SInvalidProviderName +#: Vcl/midconst.pas:50 +msgid "Provider name \"%s\" was not recognized by the server" +msgstr "Der Provider-Name '%s' wurde vom Server nicht erkannt" + +#. Programmer's name for it: SBadVariantType +#: Vcl/midconst.pas:51 +msgid "Unsupported variant type: %s" +msgstr "Nicht unterstützter Variant-Typ: %s" + +#. Programmer's name for it: SInvalidAction +#: Vcl/midconst.pas:52 +msgid "Invalid action received: %d" +msgstr "Ungültige Aktion erhalten: %d" + +#. Programmer's name for it: SInvalidResponse +#: Vcl/midconst.pas:55 +msgid "Invalid response" +msgstr "Ungültige Rückmeldung" + +#. Programmer's name for it: STooManyRecordsModified +#: Vcl/midconst.pas:57 +msgid "Update affected more than 1 record." +msgstr "Die Aktualisierung betrifft mehr als 1 Datensatz." + +#. Programmer's name for it: SInvalidOptParamType +#: Vcl/midconst.pas:60 +msgid "Value cannot be stored in an optional parameter" +msgstr "Der Wert kann nicht als optionaler Parameter gespeichert werden" + +#. Programmer's name for it: SConstraintFailed +#: Vcl/midconst.pas:62 +msgid "Record or field constraint failed." +msgstr "Datensatz- oder Feldbedingung wurde geändert." + +#. Programmer's name for it: SField +#: Vcl/midconst.pas:63 +msgid "Field" +msgstr "Feld" + +#. Programmer's name for it: SReadOnlyProvider +#: Vcl/midconst.pas:64 +msgid "Cannot apply updates to a ReadOnly provider" +msgstr "Ein schreibgeschützter Provider kann nicht aktualisiert werden" + +#. Programmer's name for it: SNoKeySpecified +#: Vcl/midconst.pas:65 +msgid "Unable to find record. No key specified" +msgstr "Datensatz nicht gefunden; es wurde kein Schlüssel angegeben" + +#. Programmer's name for it: SFieldNameTooLong +#: Vcl/midconst.pas:67 +msgid "Field name cannot be longer then %d characters. Try setting ObjectView to True on the dataset" +msgstr "Der Feldname darf nicht länger als %d Zeichen sein. Sie sollten für die Datenmenge ObjectView auf True setzen" + +#. Programmer's name for it: SNoDataSets +#: Vcl/midconst.pas:68 +msgid "Cannot resolve to dataset when using nested datasets or references" +msgstr "Bei Datenmengen oder -referenzen kann in die Datenmenge nicht zurückgeschrieben werden" + +#. Programmer's name for it: SRecConstFail +#: Vcl/midconst.pas:69 +msgid "Preparation of record constraint failed with error \"%s\"" +msgstr "Die Vorbereitung der Datensatzbedingung konnte nicht durchgeführt werden; Fehler '%s'" + +#. Programmer's name for it: SFieldConstFail +#: Vcl/midconst.pas:70 +msgid "Preparation of field constraint failed with error \"%s\"" +msgstr "Die Vorbereitung der Feldbedingung konnte nicht durchgeführt werden; Fehler '%s'" + +#. Programmer's name for it: SDefExprFail +#: Vcl/midconst.pas:71 +msgid "Preparation of default expression failed with error \"%s\"" +msgstr "Die Vorbereitung des Standardausdrucks konnte nicht durchgeführt werden; Fehler '%s'" + +#. Programmer's name for it: SArrayElementError +#: Vcl/midconst.pas:72 +msgid "Array elements of type %s are not supported" +msgstr "Array-Elemente vom Typ %s werden nicht unterstützt" + +#. Programmer's name for it: SNoTableName +#: Vcl/midconst.pas:73 +msgid "Unable to resolve records. Table name not found." +msgstr "Datensätze können nicht zurückgeschrieben werden. Der Tabellenname wurde nicht gefunden." + +#. Programmer's name for it: SNoEditsAllowed +#: Vcl/midconst.pas:74 +msgid "Modifications are not allowed" +msgstr "Änderungen sind nicht gestattet" + +#. Programmer's name for it: SNoDeletesAllowed +#: Vcl/midconst.pas:75 +msgid "Deletes are not allowed" +msgstr "Löschen nicht gestattet" + +#. Programmer's name for it: SNoInsertsAllowed +#: Vcl/midconst.pas:76 +msgid "Inserts are not allowed" +msgstr "Einfügen nicht gestattet" + +#. Programmer's name for it: SCannotChangeCommandText +#: Vcl/midconst.pas:77 +msgid "CommandText changes are not allowed" +msgstr "Änderungen an CommandText sind nicht gestattet" + +#. Programmer's name for it: SNoServers +#: Vcl/midconst.pas:80 +msgid "No server available" +msgstr "Kein Server verfügbar" + +#. Programmer's name for it: SReturnError +#: Vcl/midconst.pas:83 +msgid "Expected return value not received" +msgstr "Der erwartete Rückgabewert wurde nicht empfangen" + +#. Programmer's name for it: SNoWinSock2 +#: Vcl/midconst.pas:84 +msgid "WinSock 2 must be installed to use the socket connection" +msgstr "Um Socket-Verbindungen verwenden zu können, muss WinSock2 installiert sein" + +#. Programmer's name for it: SURLRequired +#: Vcl/midconst.pas:87 +msgid "URL required" +msgstr "Es wird eine URL benötigt" + +#. Programmer's name for it: SDefaultURL +#: Vcl/midconst.pas:88 +msgid "http://server.company.com/scripts/httpsrvr.dll" +msgstr "http://server.company.com/scripts/httpsrvr.dll" + +#. Programmer's name for it: SInvalidURL +#: Vcl/midconst.pas:89 +msgid "URL must be in the form \"http://server.company.com/scripts/httpsrvr.dll\"" +msgstr "Die URL muss folgende Form besitzen: \"http://server.company.com/scripts/httpsrvr.dll\"" + +#. Programmer's name for it: SServerIsBusy +#: Vcl/midconst.pas:90 +msgid "Server is busy" +msgstr "Der Server ist ausgelastet" + +#. Programmer's name for it: SObjectNotAvailable +#: Vcl/midconst.pas:92 +msgid "Object not available: %s" +msgstr "Das Objekt ist nicht verfügbar: %s" + +#. Programmer's name for it: SBadPropValue +#: Vcl/oleconst.pas:15 +msgid "'%s' is not a valid property value" +msgstr "'%s' ist kein gültiger Wert für die Eigenschaft" + +#. Programmer's name for it: SCannotActivate +#: Vcl/oleconst.pas:16 +msgid "OLE control activation failed" +msgstr "Aktivierung des OLE-Steuerelements mißlungen" + +#. Programmer's name for it: SNoWindowHandle +#: Vcl/oleconst.pas:17 +msgid "Could not obtain OLE control window handle" +msgstr "Das Fenster-Handle des OLE-Elements nicht verfügbar" + +#. Programmer's name for it: SOleError +#: Vcl/oleconst.pas:18 +msgid "OLE error %.8x" +msgstr "OLE-Fehler %.8x" + +#. Programmer's name for it: SVarNotObject +#: Vcl/oleconst.pas:19 +msgid "Variant does not reference an OLE object" +msgstr "Variante referenziert kein OLE-Objekt" + +#. Programmer's name for it: SVarNotAutoObject +#. Programmer's name for it: SVarNotObject +#: Vcl/oleconst.pas:20 +msgid "Variant does not reference an automation object" +msgstr "Variante referenziert kein Automatisierungsobjekt" + +#. Programmer's name for it: SNoMethod +#: Vcl/oleconst.pas:21 +msgid "Method '%s' not supported by OLE object" +msgstr "Methode '%s' wird vom OLE-Objekt nicht unterstützt" + +#. Programmer's name for it: SLinkProperties +#: Vcl/oleconst.pas:22 +msgid "Link Properties" +msgstr "Verknüpfungseigenschaften" + +#. Programmer's name for it: SInvalidLinkSource +#: Vcl/oleconst.pas:23 +msgid "Cannot link to an invalid source." +msgstr "Zu einer ungültigen Quelle kann nicht verknüpft werden." + +#. Programmer's name for it: SCannotBreakLink +#: Vcl/oleconst.pas:24 +msgid "Break link operation is not supported." +msgstr "Operation zur Trennung der Verbindung nicht erlaubt." + +#. Programmer's name for it: SLinkedObject +#: Vcl/oleconst.pas:25 +msgid "Linked %s" +msgstr "Verknüpft %s" + +#. Programmer's name for it: SEmptyContainer +#: Vcl/oleconst.pas:26 +msgid "Operation not allowed on an empty OLE container" +msgstr "Operation mit einem leeren OLE-Container nicht zulässig" + +#. Programmer's name for it: SInvalidVerb +#: Vcl/oleconst.pas:27 +msgid "Invalid object verb" +msgstr "Ungültiges Objekt-Verb" + +#. Programmer's name for it: SPropDlgCaption +#: Vcl/oleconst.pas:28 +msgid "%s Properties" +msgstr "%s Eigenschaften" + +#. Programmer's name for it: SInvalidLicense +#: Vcl/oleconst.pas:30 +msgid "License information for %s is invalid" +msgstr "Lizenz-Information für %s ist ungültig" + +#. Programmer's name for it: SNotLicensed +#: Vcl/oleconst.pas:31 +msgid "License information for %s not found. You cannot use this control in design mode" +msgstr "Lizenz-Information für %s nicht gefunden. Sie können dieses Steuerelement im Entwurfsmodus nicht verwenden" + +#. Programmer's name for it: sNoRunningObject +#: Vcl/oleconst.pas:32 +msgid "Unable to retrieve a pointer to a running object registered with OLE for %s/%s" +msgstr "Es kann kein Zeiger auf ein ausgeführtes Objekt geholt werden, daß mit OLE für %s/%s registriert ist" + +#. Programmer's name for it: SServiceOnly +#: Vcl/scktcnst.pas:29 +msgid "The Socket Server can only be run as a service on NT 3.51 and prior" +msgstr "Der Socket-Server kann auf Win NT 3.51 und älter als Service ausgeführt werden" + +#. Programmer's name for it: SErrClose +#: Vcl/scktcnst.pas:30 +msgid "Cannot exit when there are active connections. Kill connections?" +msgstr "Das Programm kann nicht beendet werden, da noch aktive Verbindungen bestehen. Sollen diese Verbindungen abgebrochen werden?" + +#. Programmer's name for it: SErrChangeSettings +#: Vcl/scktcnst.pas:31 +msgid "Cannot change settings when there are active connections. Kill connections?" +msgstr "Die Einstellungen können nicht geändert werden, da noch aktive Verbindungen bestehen. Sollen diese Verbindungen abgebrochen werden?" + +#. Programmer's name for it: SQueryDisconnect +#: Vcl/scktcnst.pas:32 +msgid "Disconnecting clients can cause application errors. Continue?" +msgstr "Wenn die Verbindung zu den Clients getrennt wird, kann das zu Fehlern in der Anwendung führen. Weiter?" + +#. Programmer's name for it: SOpenError +#: Vcl/scktcnst.pas:33 +msgid "Error opening port %d with error: %s" +msgstr "Fehler beim Öffnen von Port %d. Fehler: %s" + +#. Programmer's name for it: SNotShown +#: Vcl/scktcnst.pas:35 +msgid "(Not Shown)" +msgstr "(Nicht angezeigt)" + +#. Programmer's name for it: SStatusline +#: Vcl/scktcnst.pas:37 +msgid "%d current connections" +msgstr "%d aktuelle Verbindungen" + +#. Programmer's name for it: SAlreadyRunning +#: Vcl/scktcnst.pas:38 +msgid "The Socket Server is already running" +msgstr "Der Socket-Server wird bereits ausgeführt" + +#. Programmer's name for it: SNotUntilRestart +#: Vcl/scktcnst.pas:39 +msgid "This change will not take affect until the Socket Server is restarted" +msgstr "Die Änderungen werden erst nach Neustart des Socket-Server wirksam" + +#. Programmer's name for it: sInvalidActionRegistration +#: Vcl/webconst.pas:15 +msgid "Invalid Action registration" +msgstr "Ungültige Aktionsregistrierung" + +#. Programmer's name for it: sDuplicateActionName +#: Vcl/webconst.pas:16 +msgid "Duplicate action name" +msgstr "Doppelter Aktionsname" + +#. Programmer's name for it: sOnlyOneDispatcher +#: Vcl/webconst.pas:17 +msgid "Only one WebDispatcher per form/data module" +msgstr "Nur ein WebDispatcher pro Formular/Datenmodul" + +#. Programmer's name for it: sHTTPItemName +#: Vcl/webconst.pas:18 +msgid "Name" +msgstr "Name" + +#. Programmer's name for it: sHTTPItemURI +#: Vcl/webconst.pas:19 +msgid "PathInfo" +msgstr "VerzInfo" + +#. Programmer's name for it: sHTTPItemEnabled +#: Vcl/webconst.pas:20 +msgid "Enabled" +msgstr "Aktiviert" + +#. Programmer's name for it: sHTTPItemProducer +#: Vcl/webconst.pas:22 +msgid "Producer" +msgstr "Produzent" + +#. Programmer's name for it: sTooManyColumns +#: Vcl/webconst.pas:26 +msgid "Too many table columns" +msgstr "Zu viele Tabellenspalten" + +#. Programmer's name for it: sFieldNameColumn +#: Vcl/webconst.pas:27 +msgid "Field Name" +msgstr "Feldname" + +#. Programmer's name for it: sFieldTypeColumn +#: Vcl/webconst.pas:28 +msgid "Field Type" +msgstr "Feldtyp" + +#. Programmer's name for it: SCorbaDllNotLoaded +#: Rtl/Corba/corbcnst.pas:15 +msgid "Unable to load CORBA libraries" +msgstr "Die CORBA-Bibliothek konnte nicht geladen werden" + +#. Programmer's name for it: SCorbaNotInitialized +#: Rtl/Corba/corbcnst.pas:16 +msgid "CORBA libraries are unavailable or not initialized" +msgstr "CORBA-Bibliotheken stehen nicht zur Verfügung oder sind nicht initialisiert" + +#. Programmer's name for it: SCorbaSkeletonNotRegistered +#: Rtl/Corba/corbcnst.pas:17 +msgid "CORBA server skeleton not registered for object %s" +msgstr "CORBA server skeleton nicht registriert für das Objekt %s" + +#. Programmer's name for it: SCorbaStubNotRegistered +#: Rtl/Corba/corbcnst.pas:18 +msgid "CORBA client stub not registered" +msgstr "CORBA-Client-Stub nicht registriert" + +#. Programmer's name for it: SCorbaInterfaceIDNotRegister +#: Rtl/Corba/corbcnst.pas:19 +msgid "CORBA interface not registered" +msgstr "CORBA-Schnittstelle nicht registriert" + +#. Programmer's name for it: SCorbaRepositoryIDNotRegistered +#: Rtl/Corba/corbcnst.pas:20 +msgid "CORBA Repository ID \"%s\" not registered" +msgstr "CORBA Repository ID \"%s\" nicht registriert" + +#. Programmer's name for it: SCorbaIncompleteFactory +#: Rtl/Corba/corbcnst.pas:21 +msgid "CORBA Factory did not implement CreateInterface" +msgstr "Die CORBA Factory implementiert CreateInterface nicht" + +#. Programmer's name for it: sInvalidTypeCast +#: Rtl/Corba/corbcnst.pas:24 +msgid "Variant cannot be converted to a CORBA Any" +msgstr "Variant kann nicht in CORBA Any konvertiert werden" + +#. Programmer's name for it: sNotCorbaObject +#: Rtl/Corba/corbcnst.pas:25 +msgid "Variant/Any not a CORBA object" +msgstr "Variant/Any ist kein CORBA-Objekt" + +#. Programmer's name for it: sParamTypeCast +#: Rtl/Corba/corbcnst.pas:26 +msgid "Parameter (%d) of method %s not of the correct type" +msgstr "Inkorrekter Typ des Parameters (%d) der Methode %s" + +#. Programmer's name for it: sParamOut +#: Rtl/Corba/corbcnst.pas:27 +msgid "Parameter (%d) of method %s is an out or in/out parameter and requires a variable reference" +msgstr "Der %d. Parameter der Methode %s ist ein out oder in/out Paramter und benötigt eine Referenz auf eine Variable" + +#. Programmer's name for it: sNoRepository +#: Rtl/Corba/corbcnst.pas:28 +msgid "Could not perform CORBA Dispatch, no interface repository found" +msgstr "CORBA Dispatch konnte nicht durchgeführt werden, da kein Schnittstellen-Repository gefunden wurde" + +#. Programmer's name for it: sInvalidParameterCount +#: Rtl/Corba/corbcnst.pas:29 +msgid "Incorrect number of parameters to method %s" +msgstr "Inkorrekte Parameteranzahl für Methode %s" + +#. Programmer's name for it: sMethodNotFound +#: Rtl/Corba/corbcnst.pas:30 +msgid "Method %s not found" +msgstr "Methode %s nicht gefunden" + +#. Programmer's name for it: sConnecting +#: Rtl/Corba/corbcnst.pas:31 +msgid "Connecting to CORBA server..." +msgstr "Verbindung mit CORBA-Server wird hergestellt..." + +#. Programmer's name for it: SCreateRegKeyError +#: Rtl/Sys/comconst.pas:15 +msgid "Error creating system registry entry" +msgstr "Fehler beim Erstellen eines Eintrages in der Systemregistrierung" + +#. Programmer's name for it: SObjectFactoryMissing +#: Rtl/Sys/comconst.pas:17 +msgid "Object factory for class %s missing" +msgstr "Der Objektgenerator für die Klasse %s fehlt" + +#. Programmer's name for it: STypeInfoMissing +#: Rtl/Sys/comconst.pas:18 +msgid "Type information missing for class %s" +msgstr "Für die Klasse %s fehlt die Typinformation" + +#. Programmer's name for it: SBadTypeInfo +#: Rtl/Sys/comconst.pas:19 +msgid "Incorrect type information for class %s" +msgstr "Falsche Typinformation für Klasse %s" + +#. Programmer's name for it: SDispIntfMissing +#: Rtl/Sys/comconst.pas:20 +msgid "Dispatch interface missing from class %s" +msgstr "Dispatch-Schnittstelle der Klasse %s fehlt" + +#. Programmer's name for it: SNoMethod +#: Rtl/Sys/comconst.pas:21 +msgid "Method '%s' not supported by automation object" +msgstr "Die Methode '%s' wird vom Automatisierungsobjekt nicht unterstützt" + +#. Programmer's name for it: SDCOMNotInstalled +#: Rtl/Sys/comconst.pas:23 +msgid "DCOM not installed" +msgstr "DCOM ist nicht installiert" + +#. Programmer's name for it: SDAXError +#: Rtl/Sys/comconst.pas:24 +msgid "DAX Error" +msgstr "DAX-Fehler" + +#. Programmer's name for it: SAutomationWarning +#: Rtl/Sys/comconst.pas:26 +msgid "COM Server Warning" +msgstr "Warnung des COM-Servers" + +#. Programmer's name for it: SNoCloseActiveServer1 +#: Rtl/Sys/comconst.pas:29 +msgid "There are still active COM objects in this application. One or more clients may have references to these objects, so manually closing " +msgstr "Diese Anwendung enthält noch aktive COM-Objekte.Mindestens ein Client verweist noch auf diese Objekte,so daß manuelles Schließen " + +#. Programmer's name for it: SNoCloseActiveServer2 +#: Rtl/Sys/comconst.pas:32 +msgid "" +"this application may cause those client application(s) to fail.\n" +"\n" +"Are you sure you want to close this application?" +msgstr "" +"dieser Anwendung dazu führen könnte, daß die Client-Anwendungennicht korrekt funktionieren.\n" +"\n" +"Sind Sie sicher, daß Sie diese Anwendung schließen möchten?" + +#. Programmer's name for it: SUnknown +#: Rtl/Sys/sysconst.pas:15 +msgid "" +msgstr "" + +#. Programmer's name for it: SInvalidInteger +#: Rtl/Sys/sysconst.pas:16 +msgid "'%s' is not a valid integer value" +msgstr "'%s' ist kein gültiger Integerwert" + +#. Programmer's name for it: SInvalidFloat +#: Rtl/Sys/sysconst.pas:17 +msgid "'%s' is not a valid floating point value" +msgstr "'%s' ist kein gültiger Gleitkommawert" + +#. Programmer's name for it: SInvalidDate +#: Rtl/Sys/sysconst.pas:18 +msgid "'%s' is not a valid date" +msgstr "'%s' ist kein gültiges Datum" + +#. Programmer's name for it: SInvalidTime +#: Rtl/Sys/sysconst.pas:19 +msgid "'%s' is not a valid time" +msgstr "'%s' ist keine gültige Uhrzeit" + +#. Programmer's name for it: SInvalidDateTime +#: Rtl/Sys/sysconst.pas:20 +msgid "'%s' is not a valid date and time" +msgstr "'%s' ist keine gültige Datums- und Uhrzeitangabe" + +#. Programmer's name for it: SOutOfMemory +#: Rtl/Sys/sysconst.pas:23 +msgid "Out of memory" +msgstr "Zu wenig Arbeitsspeicher" + +#. Programmer's name for it: SInOutError +#: Rtl/Sys/sysconst.pas:24 +msgid "I/O error %d" +msgstr "E/A-Fehler %d" + +#. Programmer's name for it: SFileNotFound +#: Rtl/Sys/sysconst.pas:25 +msgid "File not found" +msgstr "Datei nicht gefunden" + +#. Programmer's name for it: SInvalidFilename +#: Rtl/Sys/sysconst.pas:26 +msgid "Invalid filename" +msgstr "Ungültiger Dateiname" + +#. Programmer's name for it: STooManyOpenFiles +#: Rtl/Sys/sysconst.pas:27 +msgid "Too many open files" +msgstr "Zu viele geöffnete Dateien" + +#. Programmer's name for it: SAccessDenied +#: Rtl/Sys/sysconst.pas:28 +msgid "File access denied" +msgstr "Dateizugriff verweigert" + +#. Programmer's name for it: SEndOfFile +#: Rtl/Sys/sysconst.pas:29 +msgid "Read beyond end of file" +msgstr "Versuch hinter dem Dateiende zu lesen" + +#. Programmer's name for it: SDiskFull +#: Rtl/Sys/sysconst.pas:30 +msgid "Disk full" +msgstr "Zu wenig Speicherplatz" + +#. Programmer's name for it: SInvalidInput +#: Rtl/Sys/sysconst.pas:31 +msgid "Invalid numeric input" +msgstr "Ungültige numerische Eingabe" + +#. Programmer's name for it: SDivByZero +#: Rtl/Sys/sysconst.pas:32 +msgid "Division by zero" +msgstr "Division durch Null" + +#. Programmer's name for it: SRangeError +#: Rtl/Sys/sysconst.pas:33 +msgid "Range check error" +msgstr "Fehler bei Bereichsprüfung" + +#. Programmer's name for it: SIntOverflow +#: Rtl/Sys/sysconst.pas:34 +msgid "Integer overflow" +msgstr "Integerüberlauf" + +#. Programmer's name for it: SInvalidOp +#: Rtl/Sys/sysconst.pas:35 +msgid "Invalid floating point operation" +msgstr "Ungültige Gleitkommaoperation" + +#. Programmer's name for it: SZeroDivide +#: Rtl/Sys/sysconst.pas:36 +msgid "Floating point division by zero" +msgstr "Gleitkommadivision durch Null" + +#. Programmer's name for it: SOverflow +#: Rtl/Sys/sysconst.pas:37 +msgid "Floating point overflow" +msgstr "Gleitkommaüberlauf" + +#. Programmer's name for it: SUnderflow +#: Rtl/Sys/sysconst.pas:38 +msgid "Floating point underflow" +msgstr "Gleitkommaunterlauf" + +#. Programmer's name for it: SInvalidPointer +#: Rtl/Sys/sysconst.pas:39 +msgid "Invalid pointer operation" +msgstr "Ungültige Zeigeroperation" + +#. Programmer's name for it: SInvalidCast +#: Rtl/Sys/sysconst.pas:40 +msgid "Invalid class typecast" +msgstr "Ungültige Typumwandlung" + +#. Programmer's name for it: SAccessViolation +#: Rtl/Sys/sysconst.pas:41 +msgid "Access violation at address %p. %s of address %p" +msgstr "Zugriffsverletzung bei Adresse %p. %s von Adresse %p" + +#. Programmer's name for it: SStackOverflow +#: Rtl/Sys/sysconst.pas:42 +msgid "Stack overflow" +msgstr "Stack-Überlauf" + +#. Programmer's name for it: SControlC +#: Rtl/Sys/sysconst.pas:43 +msgid "Control-C hit" +msgstr "Strg+C gedrückt" + +#. Programmer's name for it: SPrivilege +#: Rtl/Sys/sysconst.pas:44 +msgid "Privileged instruction" +msgstr "Privilegierte Anweisung" + +#. Programmer's name for it: SOperationAborted +#: Rtl/Sys/sysconst.pas:45 +msgid "Operation aborted" +msgstr "Operation abgebrochen" + +#. Programmer's name for it: SException +#: Rtl/Sys/sysconst.pas:46 +msgid "" +"Exception %s in module %s at %p.\n" +"%s%s" +msgstr "" +"Exception %s im Modul %s bei %p.\n" +"%s%s" + +#. Programmer's name for it: SExceptTitle +#: Rtl/Sys/sysconst.pas:47 +msgid "Application Error" +msgstr "Anwendungsfehler" + +#. Programmer's name for it: SInvalidFormat +#: Rtl/Sys/sysconst.pas:48 +msgid "Format '%s' invalid or incompatible with argument" +msgstr "Format '%s' ungültig oder nicht kompatibel mit Argument" + +#. Programmer's name for it: SArgumentMissing +#: Rtl/Sys/sysconst.pas:49 +msgid "No argument for format '%s'" +msgstr "Kein Argument für Format '%s'" + +#. Programmer's name for it: SInvalidVarCast +#: Rtl/Sys/sysconst.pas:50 +msgid "Invalid variant type conversion" +msgstr "Ungültige Variant-Typumwandlung" + +#. Programmer's name for it: SInvalidVarOp +#: Rtl/Sys/sysconst.pas:51 +msgid "Invalid variant operation" +msgstr "Ungültige Variant-Operation" + +#. Programmer's name for it: SDispatchError +#: Rtl/Sys/sysconst.pas:52 +msgid "Variant method calls not supported" +msgstr "Variant-Methodenaufruf nicht unterstützt" + +#. Programmer's name for it: SResultTooLong +#: Rtl/Sys/sysconst.pas:55 +msgid "Format result longer than 4096 characters" +msgstr "Formatergebnis länger als 4096 Zeichen" + +#. Programmer's name for it: SFormatTooLong +#: Rtl/Sys/sysconst.pas:56 +msgid "Format string too long" +msgstr "Format-String zu lang" + +#. Programmer's name for it: SVarArrayCreate +#: Rtl/Sys/sysconst.pas:57 +msgid "Error creating variant array" +msgstr "Fehler beim Erstellen des Variant-Arrays" + +#. Programmer's name for it: SVarNotArray +#: Rtl/Sys/sysconst.pas:58 +msgid "Variant is not an array" +msgstr "Variant ist kein Array" + +#. Programmer's name for it: SVarArrayBounds +#: Rtl/Sys/sysconst.pas:59 +msgid "Variant array index out of bounds" +msgstr "Index des Variant-Arrays außerhalb des Bereichs" + +#. Programmer's name for it: SExternalException +#: Rtl/Sys/sysconst.pas:60 +msgid "External exception %x" +msgstr "Externe Exception %x" + +#. Programmer's name for it: SAssertionFailed +#: Rtl/Sys/sysconst.pas:61 +msgid "Assertion failed" +msgstr "Auswertung von assert fehlgeschlagen" + +#. Programmer's name for it: SIntfCastError +#: Rtl/Sys/sysconst.pas:62 +msgid "Interface not supported" +msgstr "Schnittstelle nicht unterstützt" + +#. Programmer's name for it: SSafecallException +#: Rtl/Sys/sysconst.pas:63 +msgid "Exception in safecall method" +msgstr "Exception in safecall-Methode" + +#. Programmer's name for it: SAssertError +#: Rtl/Sys/sysconst.pas:64 +msgid "%s (%s, line %d)" +msgstr "%s (%s, Zeile %d)" + +#. Programmer's name for it: SAbstractError +#: Rtl/Sys/sysconst.pas:65 +msgid "Abstract Error" +msgstr "Abstrakter Fehler" + +#. Programmer's name for it: SModuleAccessViolation +#: Rtl/Sys/sysconst.pas:66 +msgid "Access violation at address %p in module '%s'. %s of address %p" +msgstr "Zugriffsverletzung bei Adresse %p in Modul '%s'. %s von Adresse %p" + +#. Programmer's name for it: SCannotReadPackageInfo +#: Rtl/Sys/sysconst.pas:67 +msgid "Cannot access package information for package '%s'" +msgstr "Zugriff auf Package-Informationen von '%s' nicht möglich" + +#. Programmer's name for it: sErrorLoadingPackage +#: Rtl/Sys/sysconst.pas:68 +msgid "" +"Can't load package %s.\n" +"%s" +msgstr "" +"Package %s kann nicht geladen werden.\n" +"%s" + +#. Programmer's name for it: SInvalidPackageFile +#: Rtl/Sys/sysconst.pas:69 +msgid "Invalid package file '%s'" +msgstr "Ungültige Package-Datei '%s'" + +#. Programmer's name for it: SInvalidPackageHandle +#: Rtl/Sys/sysconst.pas:70 +msgid "Invalid package handle" +msgstr "Ungültiges Package-Handle" + +#. Programmer's name for it: SDuplicatePackageUnit +#: Rtl/Sys/sysconst.pas:72 +msgid "Cannot load package '%s.' It contains unit '%s,';which is also contained in package '%s'" +msgstr "Package '%s' kann nicht geladen werden. Es enthält die Unit '%s', die auch im Package '%s' enthalten ist" + +#. Programmer's name for it: SWin32Error +#: Rtl/Sys/sysconst.pas:73 +msgid "" +"Win32 Error. Code: %d.\n" +"%s" +msgstr "" +"Win32 Fehler.\tCode: %d.\n" +"%s" + +#. Programmer's name for it: SUnkWin32Error +#: Rtl/Sys/sysconst.pas:74 +msgid "A Win32 API function failed" +msgstr "Fehler bei einer Win32 API-Funktion" + +#. Programmer's name for it: SNL +#: Rtl/Sys/sysconst.pas:75 +msgid "Application is not licensed to use this feature" +msgstr "Die Anwendung ist für diese Funktion nicht lizenziert." + +#. Programmer's name for it: SShortMonthNameJan +#: Rtl/Sys/sysconst.pas:77 +msgid "Jan" +msgstr "Jan" + +#. Programmer's name for it: SShortMonthNameFeb +#: Rtl/Sys/sysconst.pas:78 +msgid "Feb" +msgstr "Feb" + +#. Programmer's name for it: SShortMonthNameMar +#: Rtl/Sys/sysconst.pas:79 +msgid "Mar" +msgstr "Mär" + +#. Programmer's name for it: SShortMonthNameApr +#: Rtl/Sys/sysconst.pas:80 +msgid "Apr" +msgstr "Apr" + +#. Programmer's name for it: SShortMonthNameMay +#. Programmer's name for it: SLongMonthNameMay +#: Rtl/Sys/sysconst.pas:81 +msgid "May" +msgstr "Mai" + +#. Programmer's name for it: SShortMonthNameJun +#: Rtl/Sys/sysconst.pas:82 +msgid "Jun" +msgstr "Jun" + +#. Programmer's name for it: SShortMonthNameJul +#: Rtl/Sys/sysconst.pas:83 +msgid "Jul" +msgstr "Jul" + +#. Programmer's name for it: SShortMonthNameAug +#: Rtl/Sys/sysconst.pas:84 +msgid "Aug" +msgstr "Aug" + +#. Programmer's name for it: SShortMonthNameSep +#: Rtl/Sys/sysconst.pas:85 +msgid "Sep" +msgstr "Sep" + +#. Programmer's name for it: SShortMonthNameOct +#: Rtl/Sys/sysconst.pas:86 +msgid "Oct" +msgstr "Okt" + +#. Programmer's name for it: SShortMonthNameNov +#: Rtl/Sys/sysconst.pas:87 +msgid "Nov" +msgstr "Nov" + +#. Programmer's name for it: SShortMonthNameDec +#: Rtl/Sys/sysconst.pas:88 +msgid "Dec" +msgstr "Dez" + +#. Programmer's name for it: SLongMonthNameJan +#: Rtl/Sys/sysconst.pas:90 +msgid "January" +msgstr "Januar" + +#. Programmer's name for it: SLongMonthNameFeb +#: Rtl/Sys/sysconst.pas:91 +msgid "February" +msgstr "Februar" + +#. Programmer's name for it: SLongMonthNameMar +#: Rtl/Sys/sysconst.pas:92 +msgid "March" +msgstr "März" + +#. Programmer's name for it: SLongMonthNameApr +#: Rtl/Sys/sysconst.pas:93 +msgid "April" +msgstr "April" + +#. Programmer's name for it: SLongMonthNameJun +#: Rtl/Sys/sysconst.pas:95 +msgid "June" +msgstr "Juni" + +#. Programmer's name for it: SLongMonthNameJul +#: Rtl/Sys/sysconst.pas:96 +msgid "July" +msgstr "Juli" + +#. Programmer's name for it: SLongMonthNameAug +#: Rtl/Sys/sysconst.pas:97 +msgid "August" +msgstr "August" + +#. Programmer's name for it: SLongMonthNameSep +#: Rtl/Sys/sysconst.pas:98 +msgid "September" +msgstr "September" + +#. Programmer's name for it: SLongMonthNameOct +#: Rtl/Sys/sysconst.pas:99 +msgid "October" +msgstr "Oktober" + +#. Programmer's name for it: SLongMonthNameNov +#: Rtl/Sys/sysconst.pas:100 +msgid "November" +msgstr "November" + +#. Programmer's name for it: SLongMonthNameDec +#: Rtl/Sys/sysconst.pas:101 +msgid "December" +msgstr "Dezember" + +#. Programmer's name for it: SShortDayNameSun +#: Rtl/Sys/sysconst.pas:103 +msgid "Sun" +msgstr "So" + +#. Programmer's name for it: SShortDayNameMon +#: Rtl/Sys/sysconst.pas:104 +msgid "Mon" +msgstr "Mo" + +#. Programmer's name for it: SShortDayNameTue +#: Rtl/Sys/sysconst.pas:105 +msgid "Tue" +msgstr "Di" + +#. Programmer's name for it: SShortDayNameWed +#: Rtl/Sys/sysconst.pas:106 +msgid "Wed" +msgstr "Mi" + +#. Programmer's name for it: SShortDayNameThu +#: Rtl/Sys/sysconst.pas:107 +msgid "Thu" +msgstr "Do" + +#. Programmer's name for it: SShortDayNameFri +#: Rtl/Sys/sysconst.pas:108 +msgid "Fri" +msgstr "Fr" + +#. Programmer's name for it: SShortDayNameSat +#: Rtl/Sys/sysconst.pas:109 +msgid "Sat" +msgstr "Sa" + +#. Programmer's name for it: SLongDayNameSun +#: Rtl/Sys/sysconst.pas:111 +msgid "Sunday" +msgstr "Sonntag" + +#. Programmer's name for it: SLongDayNameMon +#: Rtl/Sys/sysconst.pas:112 +msgid "Monday" +msgstr "Montag" + +#. Programmer's name for it: SLongDayNameTue +#: Rtl/Sys/sysconst.pas:113 +msgid "Tuesday" +msgstr "Dienstag" + +#. Programmer's name for it: SLongDayNameWed +#: Rtl/Sys/sysconst.pas:114 +msgid "Wednesday" +msgstr "Mittwoch" + +#. Programmer's name for it: SLongDayNameThu +#: Rtl/Sys/sysconst.pas:115 +msgid "Thursday" +msgstr "Donnerstag" + +#. Programmer's name for it: SLongDayNameFri +#: Rtl/Sys/sysconst.pas:116 +msgid "Friday" +msgstr "Freitag" + +#. Programmer's name for it: SLongDayNameSat +#: Rtl/Sys/sysconst.pas:117 +msgid "Saturday" +msgstr "Samstag" + +#. Programmer's name: FONT 8 +#: Vcl/extdlgs.rc:14 +msgid "MS Sans Serif" +msgstr "MS Sans Serif" + +#. DSSCubeEditor..Caption +#: Decision Cube/mxdcube.dfm:6 +msgid "Decision Cube Editor" +msgstr "Editor für Entscheidungswürfel" + +#. DSSCubeEditor..Pager..DimensionInfo..Caption +#: Decision Cube/mxdcube.dfm:24 +msgid "Dimension Settings" +msgstr "Dimensionseinstellungen" + +#. DSSCubeEditor..Pager..DimensionInfo..CaptionLabel..Caption +#: Decision Cube/mxdcube.dfm:31 +msgid "Display &Name" +msgstr "A&nzeige" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveLabel..Caption +#: Decision Cube/mxdcube.dfm:40 +msgid "&Active Type" +msgstr "A&ktivität" + +#. DSSCubeEditor..Pager..DimensionInfo..BinLabel..Caption +#: Decision Cube/mxdcube.dfm:49 +msgid "&Grouping" +msgstr "&Gruppierung" + +#. DSSCubeEditor..Pager..DimensionInfo..StartLabel..Caption +#: Decision Cube/mxdcube.dfm:58 +msgid "&Initial Value" +msgstr "&Anfangswert" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeLabel..Caption +#: Decision Cube/mxdcube.dfm:67 +msgid "&Type" +msgstr "&Typ" + +#. DSSCubeEditor..Pager..DimensionInfo..Label1..Caption +#: Decision Cube/mxdcube.dfm:76 +msgid "Available &Fields" +msgstr "Verfügbare &Felder:" + +#. DSSCubeEditor..Pager..DimensionInfo..Label2..Caption +#: Decision Cube/mxdcube.dfm:85 +msgid "For&mat" +msgstr "For&mat" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameLabel..Caption +#: Decision Cube/mxdcube.dfm:102 +msgid "&Base Field" +msgstr "&Basisfeld" + +#. DSSCubeEditor..Pager..DimensionInfo..CaptionEdit..Text +#: Decision Cube/mxdcube.dfm:122 +msgid "CaptionEdit" +msgstr "CaptionEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit..Hint +#: Decision Cube/mxdcube.dfm:130 +msgid "Control of when the information for this field is loaded" +msgstr "Steuerung wenn die Information für dieses Feld geladen ist" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:136 +msgid "" +"Active\n" +"As Needed\n" +"Inactive\n" +msgstr "" +"Aktiv\n" +"Bei Bedarf\n" +"Inaktiv\n" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit..Text +#: Decision Cube/mxdcube.dfm:139 +msgid "ActiveEdit" +msgstr "ActiveEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit..Hint +#: Decision Cube/mxdcube.dfm:147 +msgid "Group values for this field into ranges" +msgstr "Gruppiere Werte dieses Feldes in Bereiche" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:155 +msgid "" +"None\n" +"Year\n" +"Quarter\n" +"Month\n" +"Single Value\n" +msgstr "" +"Keines\n" +"Jahr\n" +"Quartal\n" +"Monat\n" +"Einzelwert\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit..Text +#: Decision Cube/mxdcube.dfm:158 +msgid "BinEdit" +msgstr "BinEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:176 +msgid "" +"Dimension\n" +"Sum\n" +"Count\n" +"Average\n" +"Min\n" +"Max\n" +"GenericAgg\n" +"Unknown\n" +msgstr "" +"Ausmaß\n" +"Summe\n" +"Anzahl\n" +"Durchschnitt\n" +"Min\n" +"Max\n" +"GenericAgg\n" +"Unbekannt\n" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeEdit..Text +#: Decision Cube/mxdcube.dfm:179 +msgid "TypeEdit" +msgstr "TypeEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..FormatEdit..Text +#: Decision Cube/mxdcube.dfm:190 +msgid "FormatEdit" +msgstr "FormatEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..StartEdit....Height +#: Decision Cube/mxdcube.dfm:201 +msgid "Starting value for date ranges, Intial value for single valued dimensions\n" +msgstr "Startwert für Datumsbereich, Startwert für eindimensionale Einheiten\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameEdit....Height +#: Decision Cube/mxdcube.dfm:214 +msgid "Fieldname (for a summary, the original field used to calculate the summary)\n" +msgstr "Feldname (für die Zusammanfassung, das ursprüngliche Feld wird für die Kalkulation der Summe benutzt)\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameEdit..Text +#: Decision Cube/mxdcube.dfm:217 +msgid "BaseNameEdit" +msgstr "BaseNameEdit" + +#. DSSCubeEditor..Pager..MemoryControl..Caption +#: Decision Cube/mxdcube.dfm:223 +msgid "Memory Control" +msgstr "Speicherkontrolle" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..Hint +#: Decision Cube/mxdcube.dfm:229 +msgid "Control whether to load the decision cube at design time" +msgstr "Steuerung, ob der Decision Cube zur Laufzeit geladen wird" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..Caption +#: Decision Cube/mxdcube.dfm:230 +msgid "Designer Data Options" +msgstr "Optionen für Designer Daten" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioMetaData..Caption +#: Decision Cube/mxdcube.dfm:239 +msgid "Display Dimension &Names" +msgstr "Maßeinheiten a&nzeigen" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioDimensionData..Caption +#: Decision Cube/mxdcube.dfm:250 +msgid "Display Names and &Values" +msgstr "Namen und &Werte anzeigen" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioAllData..Caption +#: Decision Cube/mxdcube.dfm:259 +msgid "Display Names, Values, and &Totals" +msgstr "Namen, Wer&te und Summen anzeigen" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioNoData..Caption +#: Decision Cube/mxdcube.dfm:268 +msgid "&Run Time Display Only" +msgstr "Nu&r Laufzeitanzeige" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Caption +#: Decision Cube/mxdcube.dfm:278 +msgid "Cube Maximums" +msgstr "Cube Maxima" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label4..Caption +#: Decision Cube/mxdcube.dfm:304 +msgid "Active" +msgstr "Aktiv" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label7..Caption +#: Decision Cube/mxdcube.dfm:312 +msgid "Active+Needed" +msgstr "Aktiv+Benötigt" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label9..Caption +#: Decision Cube/mxdcube.dfm:320 +msgid "&Dimensions" +msgstr "&Maße" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label6..Caption +#: Decision Cube/mxdcube.dfm:348 +msgid "&Summaries" +msgstr "Zu&sammenfassungen" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label12..Caption +#: Decision Cube/mxdcube.dfm:358 +msgid "&Cells" +msgstr "&Zellen" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label5..Caption +#: Decision Cube/mxdcube.dfm:376 +msgid "Maximum" +msgstr "Maximum" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label3..Caption +#: Decision Cube/mxdcube.dfm:384 +msgid "Current" +msgstr "Aktuell" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxDims....Height +#: Decision Cube/mxdcube.dfm:421 +msgid "Limit on the number of dimensions which can be loaded at one time\n" +msgstr "Limitierung der Anzahl der Einheiten, die gleichzeitig geladen werden können\n" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxSums..Hint +#: Decision Cube/mxdcube.dfm:430 +msgid "Limit on the number of summaries which can be loaded at one time" +msgstr "Limitierung der Anzahl der Zusammanfassungen, die gleichzeitig geladen werden können" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxCells....Height +#: Decision Cube/mxdcube.dfm:443 +msgid "Limit on the number of storage cells which can be loaded at one time\n" +msgstr "Limitierung der Anzahl der Speicherzellen, die gleichzeitig geladen werden können\n" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..GetCellCounts..Hint +#: Decision Cube/mxdcube.dfm:452 +msgid "Run a query to fetch information required to estimate cell usage" +msgstr "Abfrage zum Einholen von notwendigen Informationen starten, um den Zellenverbrauch abzuschätzen" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..GetCellCounts..Caption +#: Decision Cube/mxdcube.dfm:453 +msgid "&Get Cell Counts" +msgstr "&Ermittle Zellenanzahl" + +#. DimEditor..Caption +#. FieldsEditor..Caption +#: Decision Cube/mxdesign.dfm:6 +#: Editors/dsdesign.dfm:8 +msgid "Form1.Table1" +msgstr "Form1.Table1" + +#. SQLWindow..Caption +#: Decision Cube/mxdsql.dfm:6 +msgid "Form2" +msgstr "Form2" + +#. SQLWindow..Memo1....Lines.Strings +#: Decision Cube/mxdsql.dfm:32 +msgid "Memo1\n" +msgstr "Memo1\n" + +#. DSSQueryEditor..Caption +#: Decision Cube/mxdssqry.dfm:6 +msgid "Decision Query Editor" +msgstr "Editor für Entscheidungsabfrage" + +#. DSSQueryEditor..Pager..Dimensions..Caption +#: Decision Cube/mxdssqry.dfm:23 +msgid "Dimensions/Summaries" +msgstr "Maße/Zusammenfassungen" + +#. DSSQueryEditor..Pager..Dimensions..Label2..Caption +#: Decision Cube/mxdssqry.dfm:30 +msgid "&Dimensions:" +msgstr "&Maße:" + +#. DSSQueryEditor..Pager..Dimensions..Label3..Caption +#: Decision Cube/mxdssqry.dfm:39 +msgid "&Summaries:" +msgstr "&Zusammenfassungen:" + +#. DSSQueryEditor..Pager..Dimensions..Label4..Caption +#: Decision Cube/mxdssqry.dfm:48 +msgid "&List of Available Fields:" +msgstr "&Liste der verfügbaren Felder:" + +#. DSSQueryEditor..Pager..Dimensions..Label5..Caption +#: Decision Cube/mxdssqry.dfm:57 +msgid "&Table:" +msgstr "&Tabelle:" + +#. DSSQueryEditor..Pager..Dimensions..Label6..Caption +#: Decision Cube/mxdssqry.dfm:66 +msgid "Databas&e:" +msgstr "Dat&enbank:" + +#. DSSQueryEditor..Pager..Dimensions..Label7..Caption +#. CollectionEditor..ActionList1..AddCmd..Caption +#. LinkFields..AddButton..Caption +#. SocketForm..MainMenu1..miPorts..miAdd..Caption +#: Decision Cube/mxdssqry.dfm:76 +#: Editors/fldlinks.dfm:114 +#: Vcl/scktmain.dfm:345 +msgid "&Add" +msgstr "Hinzu&fügen" + +#. DSSQueryEditor..Pager..Dimensions..SelectAllFields..Hint +#: Decision Cube/mxdssqry.dfm:129 +msgid "List all fields or List only the fields in the query" +msgstr "&Alle Felder" + +#. DSSQueryEditor..Pager..Dimensions..SelectAllFields..Caption +#: Decision Cube/mxdssqry.dfm:130 +msgid "All &Fields" +msgstr "Alle &Felder" + +#. DSSQueryEditor..Pager..Dimensions..TableCombo..Hint +#: Decision Cube/mxdssqry.dfm:141 +msgid "Start a new query using a table from the database" +msgstr "Starte eine neue Abfrage unter Benutzung einer Tabelle der Datenbank" + +#. DSSQueryEditor..Pager..Dimensions..CountStarAvg..Hint +#: Decision Cube/mxdssqry.dfm:251 +msgid "Use count(*) to calculate averages (counts null values)" +msgstr "Benutze count(*), um den Durchschnitt zu ermitteln (zählt Leerwerte)" + +#. DSSQueryEditor..Pager..Dimensions..CountStarAvg..Caption +#: Decision Cube/mxdssqry.dfm:252 +msgid "Count (*) for Averages" +msgstr "Zur Berechnung von Mittelwerten count(*) verwenden (zählt Nullwerte mit)" + +#. DSSQueryEditor..Pager..Query..Caption +#: Decision Cube/mxdssqry.dfm:261 +msgid "SQL Query" +msgstr "SQL-Abfrage" + +#. DSSQueryEditor..Pager..Query..Label1..Caption +#: Decision Cube/mxdssqry.dfm:268 +msgid "&Query Text:" +msgstr "&Abfragetext:" + +#. DSSQueryEditor..Pager..Query..CancelQryMod..Caption +#: Decision Cube/mxdssqry.dfm:287 +msgid "&Cancel Edit" +msgstr "Bearbeiten &abbrechen" + +#. DSSQueryEditor..Pager..Query..EditQry..Hint +#: Decision Cube/mxdssqry.dfm:296 +msgid "Type in the query directly" +msgstr "Geben Sie die Abfrage direkt ein" + +#. DSSQueryEditor..VQB..Hint +#: Decision Cube/mxdssqry.dfm:340 +msgid "Add/Join Tables and Create Field List with SQL Builder" +msgstr "Add/Join Tables und Create Field List mit dem SQL Builder" + +#. DSSQueryEditor..VQB..Caption +#: Decision Cube/mxdssqry.dfm:341 +msgid "SQL &Builder ..." +msgstr "SQL-&Builder..." + +#. DSSQueryEditor..AggPopup..count1..Caption +#: Decision Cube/mxdssqry.dfm:351 +msgid "&sum" +msgstr "&Summe" + +#. DSSQueryEditor..AggPopup..count2..Caption +#: Decision Cube/mxdssqry.dfm:355 +msgid "&count" +msgstr "&Anzahl" + +#. DSSQueryEditor..AggPopup..average1..Caption +#: Decision Cube/mxdssqry.dfm:359 +msgid "&average" +msgstr "&durchschnittlich" + +#. ProgressDialog..Caption +#: Decision Cube/mxpbar.dfm:6 +msgid "ProgressDialog" +msgstr "Fortschrittsanzeige" + +#. ProgressDialog..CancelButton..Caption +#. DataBindForm..CancelBtn..Caption +#: Decision Cube/mxpbar.dfm:29 +msgid "&Cancel" +msgstr "&Abbrechen" + +#. ProgressDialog..StatusText..Caption +#: Decision Cube/mxpbar.dfm:40 +msgid "StatusText" +msgstr "StatusText" + +#. ConnEditForm..SourceofConnection..Caption +#: Property Editors/adoconed.dfm:49 +msgid " Source of Connection " +msgstr " Quelle der Verbindung " + +#. ConnEditForm..SourceofConnection..UseDataLinkFile..Caption +#: Property Editors/adoconed.dfm:57 +msgid "Use Data &Link File" +msgstr "D&atenverknüpfungsdatei verwenden" + +#. ConnEditForm..SourceofConnection..Browse..Caption +#: Property Editors/adoconed.dfm:77 +msgid "&Browse..." +msgstr "&Durchsuchen..." + +#. ConnEditForm..SourceofConnection..UseConnectionString..Caption +#: Property Editors/adoconed.dfm:87 +msgid "Use &Connection String" +msgstr "&Verbindungs-String verwenden" + +#. ConnEditForm..SourceofConnection..Build..Caption +#: Property Editors/adoconed.dfm:105 +msgid "B&uild..." +msgstr "A&ufbauen..." + +#. ClientDataForm..Caption +#: Property Editors/cdsedit.dfm:6 +msgid "Client DataSet Data" +msgstr "Daten der Client-Datenmenge" + +#. ClientDataForm..GroupBox1..Caption +#: Property Editors/cdsedit.dfm:19 +msgid " Assign Data From " +msgstr " Daten zuweisen von " + +#. CollectionEditor..Caption +#: Property Editors/colnedit.dfm:10 +msgid "CollectionEditor" +msgstr "CollectionEditor" + +#. CollectionEditor..ToolBar1..ToolButton3..Caption +#: Property Editors/colnedit.dfm:41 +msgid "ToolButton3" +msgstr "ToolButton3" + +#. CollectionEditor..PopupMenu1..N2..Caption +#. FieldsEditor..LocalMenu..N1..Caption +#. SocketForm..PopupMenu..N1..Caption +#. SocketForm..MainMenu1..miPorts..N3..Caption +#. SocketForm..MainMenu1..Connections1..N2..Caption +#: Property Editors/colnedit.dfm:183 +#: Vcl/scktmain.dfm:324 +#: Vcl/scktmain.dfm:352 +#: Vcl/scktmain.dfm:368 +msgid "-" +msgstr "-" + +#. CollectionEditor..ActionList1..AddCmd..Hint +#: Property Editors/colnedit.dfm:190 +msgid "Add New" +msgstr "Neue hinzufügen" + +#. CollectionEditor..ActionList1..DeleteCmd..Caption +#. DataBindForm..Panel1..DeleteBtn..Caption +#. FieldsEditor..LocalMenu..DeleteItem..Caption +#. LinkFields..DeleteButton..Caption +#. IndexFiles..GroupBox1..Delete..Caption +#: Property Editors/colnedit.dfm:196 +#: Editors/dsdesign.dfm:157 +#: Editors/fldlinks.dfm:123 +#: Editors/ixedit.dfm:43 +msgid "&Delete" +msgstr "&Löschen" + +#. CollectionEditor..ActionList1..DeleteCmd..Hint +#: Property Editors/colnedit.dfm:198 +msgid "Delete Selected" +msgstr "Auswahl löschen" + +#. CollectionEditor..ActionList1..MoveUpCmd..Caption +#: Property Editors/colnedit.dfm:205 +msgid "Move &Up" +msgstr "Nach &oben" + +#. CollectionEditor..ActionList1..MoveUpCmd..Hint +#: Property Editors/colnedit.dfm:207 +msgid "Move Selected Up" +msgstr "Auswahl nach oben verschieben" + +#. CollectionEditor..ActionList1..MoveDownCmd..Caption +#: Property Editors/colnedit.dfm:214 +msgid "Move Dow&n" +msgstr "Nach &unten" + +#. CollectionEditor..ActionList1..MoveDownCmd..Hint +#: Property Editors/colnedit.dfm:216 +msgid "Move Selected Down" +msgstr "Auswahl nach unten verschieben" + +#. CollectionEditor..ActionList1..SelectAllCmd..Caption +#. UpdateSQLEditForm..FieldListPopup..miSelectAll..Caption +#: Property Editors/colnedit.dfm:223 +msgid "&Select All" +msgstr "Alles &markieren" + +#. DBEditForm..GroupBox1..Caption +#: Property Editors/dbedit.dfm:18 +msgid " Database " +msgstr " Datenbank " + +#. DBEditForm..GroupBox1..Label1..Caption +#: Property Editors/dbedit.dfm:25 +msgid "&Alias name:" +msgstr "Alia&sname:" + +#. DBEditForm..GroupBox1..Label2..Caption +#: Property Editors/dbedit.dfm:33 +msgid "&Driver name:" +msgstr "&Treiber-Name:" + +#. DBEditForm..GroupBox1..Label3..Caption +#: Property Editors/dbedit.dfm:41 +msgid "&Parameter overrides:" +msgstr "&Parameter überschreibt:" + +#. DBEditForm..GroupBox1..Label4..Caption +#. DefineField..FieldGroup..FieldNameLabel..Caption +#: Property Editors/dbedit.dfm:49 +msgid "&Name:" +msgstr "&Name:" + +#. DBEditForm..GroupBox1..DefaultsButton..Caption +#: Property Editors/dbedit.dfm:90 +msgid "D&efaults" +msgstr "&Vorgaben" + +#. DBEditForm..GroupBox1..ClearButton..Caption +#. LinkFields..ClearButton..Caption +#. IndexFiles..GroupBox1..Clear..Caption +#. PictureEditorDlg..GroupBox1..Clear..Caption +#: Property Editors/dbedit.dfm:99 +#: Editors/ixedit.dfm:53 +#: Editors/picedit.dfm:94 +msgid "&Clear" +msgstr "Ent&fernen" + +#. DBEditForm..GroupBox3..Caption +#: Property Editors/dbedit.dfm:116 +msgid " Options " +msgstr " Optionen " + +#. DBEditForm..GroupBox3..LoginPrompt..Caption +#: Property Editors/dbedit.dfm:123 +msgid "&Login prompt" +msgstr "L&ogin-Abfrage" + +#. DBEditForm..GroupBox3..KeepConnection..Caption +#: Property Editors/dbedit.dfm:131 +msgid "&Keep inactive connection" +msgstr "&Inaktive Verbindung halten" + +#. InputReqDialog..Caption +#: Property Editors/dbinpreq.dfm:6 +msgid "Input Requested" +msgstr "Eingabeaufforderung" + +#. InputReqDialog..OKButton..Caption +#. LoginDialog..OKButton..Caption +#. DataBindForm..OkBtn..Caption +#. SQLEditForm..ButtonPanel..OkButton..Caption +#. StrEditDlg..OKButton..Caption +#. UpdateSQLEditForm..OkButton..Caption +#: Property Editors/dbinpreq.dfm:18 +#: Editors/dboleedt.dfm:109 +#: Editors/sqledit.dfm:94 +#: Editors/stredit.dfm:55 +#: Editors/updsqled.dfm:20 +msgid "&OK" +msgstr "&OK" + +#. InputReqDialog..NoPromptAgain..Caption +#: Property Editors/dbinpreq.dfm:48 +msgid "Don't Prompt Again" +msgstr "Meldung nicht mehr anzeigen" + +#. LoginDialog..Caption +#: Property Editors/dblogdlg.dfm:6 +msgid "Database Login" +msgstr "Datenbank-Login" + +#. LoginDialog..Panel..Label3..Caption +#: Property Editors/dblogdlg.dfm:47 +msgid "Database:" +msgstr "Datenbank:" + +#. LoginDialog..Panel..Panel1..Label1..Caption +#: Property Editors/dblogdlg.dfm:75 +msgid "&User Name:" +msgstr "&Benutzername:" + +#. LoginDialog..Panel..Panel1..Label2..Caption +#: Property Editors/dblogdlg.dfm:83 +msgid "&Password:" +msgstr "&Passwort:" + +#. LoginDialog..Panel..Panel1..Password..PasswordChar +#: Property Editors/dblogdlg.dfm:100 +msgid "*" +msgstr "*" + +#. DataBindForm..Caption +#: Property Editors/dboleedt.dfm:6 +msgid "ActiveX Control Data Bindings Editor" +msgstr "Editor für ActiveX-Datenbindung" + +#. DataBindForm..Panel1..Label1..Caption +#: Property Editors/dboleedt.dfm:29 +msgid "&Property Name:" +msgstr "Name der &Eigenschaft:" + +#. DataBindForm..Panel1..Label2..Caption +#: Property Editors/dboleedt.dfm:37 +msgid "&Field Name:" +msgstr "&Feldname:" + +#. DataBindForm..Panel1..Label3..Caption +#: Property Editors/dboleedt.dfm:45 +msgid "Bo&und Properties to Fields:" +msgstr "&Bindung von Eigenschaften an Feld:" + +#. DataBindForm..Panel1..BindBtn..Caption +#: Property Editors/dboleedt.dfm:73 +msgid "<- &Bind ->" +msgstr "<- B&indung ->" + +#. DataBindForm..Panel1..ClearBtn..Caption +#: Property Editors/dboleedt.dfm:99 +msgid "C&lear" +msgstr "E&ntfernen" + +#. AddFields..Caption +#: Property Editors/dsadd.dfm:6 +msgid "Add Fields" +msgstr "Felder hinzufügen" + +#. AddFields..GroupBox1..Caption +#: Property Editors/dsadd.dfm:46 +msgid "Available fields" +msgstr "Verfügbare Felder" + +#. AssociateAttributes..Caption +#: Property Editors/dsattra.dfm:5 +msgid "Associate attributes" +msgstr "Attribute verknüpfen" + +#. AssociateAttributes..GroupBox1..Caption +#: Property Editors/dsattra.dfm:51 +msgid "Attribute set name" +msgstr "Name der Attributmenge" + +#. SaveAttributesAs..Caption +#: Property Editors/dsattrs.dfm:5 +msgid "Save %s attributes as" +msgstr "%s-Attribute unter anderem Namen speichern" + +#. SaveAttributesAs..Label1..Caption +#: Property Editors/dsattrs.dfm:25 +msgid "&Attribute set name:" +msgstr "Name der &Attributmenge:" + +#. SaveAttributesAs..Label2..Caption +#: Property Editors/dsattrs.dfm:33 +msgid "&Based on:" +msgstr "&Basierend auf:" + +#. DefineField..Caption +#: Property Editors/dsdefine.dfm:5 +msgid "New Field" +msgstr "Neues Feld" + +#. DefineField..LookupGroup..Caption +#: Property Editors/dsdefine.dfm:18 +msgid "Lookup definition" +msgstr "Nachschlage-Definition" + +#. DefineField..LookupGroup..DatasetLabel..Caption +#: Property Editors/dsdefine.dfm:25 +msgid "D&ataset:" +msgstr "Daten&menge:" + +#. DefineField..LookupGroup..KeyFieldsLabel..Caption +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label3..Caption +#: Property Editors/dsdefine.dfm:34 +msgid "&Key Fields:" +msgstr "&Schlüsselfelder:" + +#. DefineField..LookupGroup..LookupKeysLabel..Caption +#: Property Editors/dsdefine.dfm:43 +msgid "Look&up Keys:" +msgstr "S&chlüssel:" + +#. DefineField..LookupGroup..ResultFieldLabel..Caption +#: Property Editors/dsdefine.dfm:52 +msgid "&Result Field:" +msgstr "E&rgebnisfeld:" + +#. DefineField..FieldGroup..Caption +#: Property Editors/dsdefine.dfm:133 +msgid "Field properties" +msgstr "Feldeigenschaften" + +#. DefineField..FieldGroup..ComponentNameLabel..Caption +#: Property Editors/dsdefine.dfm:140 +msgid "C&omponent:" +msgstr "K&omponente:" + +#. DefineField..FieldGroup..FieldTypeLabel..Caption +#: Property Editors/dsdefine.dfm:156 +msgid "&Type:" +msgstr "&Typ:" + +#. DefineField..FieldGroup..SizeEditLabel..Caption +#: Property Editors/dsdefine.dfm:164 +msgid "&Size:" +msgstr "&Größe:" + +#. DefineField..FieldKind..Caption +#: Property Editors/dsdefine.dfm:206 +msgid "Field type" +msgstr "Feldtyp" + +#. DefineField..FieldKind....Items.Strings +#: Property Editors/dsdefine.dfm:213 +msgid "" +"&Data\n" +"&Calculated\n" +"&Lookup\n" +msgstr "" +"&Daten\n" +"&Berechnung\n" +"&Lookup\n" + +#. FieldsEditor..FieldListBox..Hint +#: Property Editors/dsdesign.dfm:81 +msgid "Fields" +msgstr "Felder" + +#. FieldsEditor..AggListBox..Hint +#: Property Editors/dsdesign.dfm:99 +msgid "Aggregates" +msgstr "Aggregatfunktionen" + +#. FieldsEditor..LocalMenu..AddItem..Caption +#: Property Editors/dsdesign.dfm:119 +msgid "&Add fields..." +msgstr "&Felder hinzufügen..." + +#. FieldsEditor..LocalMenu..NewItem..Caption +#: Property Editors/dsdesign.dfm:125 +msgid "&New field..." +msgstr "&Neues Feld..." + +#. FieldsEditor..LocalMenu..Addallfields1..Caption +#: Property Editors/dsdesign.dfm:131 +msgid "Add all &fields" +msgstr "Alle Fel&der hinzufügen..." + +#. FieldsEditor..LocalMenu..CutItem..Caption +#: Property Editors/dsdesign.dfm:139 +msgid "Cu&t" +msgstr "&Ausschneiden" + +#. FieldsEditor..LocalMenu..CopyItem..Caption +#: Property Editors/dsdesign.dfm:145 +msgid "&Copy" +msgstr "&Kopieren" + +#. FieldsEditor..LocalMenu..PasteItem..Caption +#: Property Editors/dsdesign.dfm:151 +msgid "&Paste" +msgstr "&Einfügen" + +#. FieldsEditor..LocalMenu..SelectAllItem..Caption +#: Property Editors/dsdesign.dfm:163 +msgid "Se&lect all" +msgstr "Alles mar&kieren" + +#. LinkFields..Caption +#: Property Editors/fldlinks.dfm:6 +msgid "Field Link Designer" +msgstr "Feldverbindungs-Designer" + +#. LinkFields..Label30..Caption +#: Property Editors/fldlinks.dfm:35 +msgid "D&etail Fields" +msgstr "D&etailfelder" + +#. LinkFields..Label31..Caption +#: Property Editors/fldlinks.dfm:44 +msgid "&Master Fields" +msgstr "H&auptfelder" + +#. LinkFields..IndexLabel..Caption +#: Property Editors/fldlinks.dfm:53 +msgid "A&vailable Indexes" +msgstr "Verfügbare &Indizes" + +#. LinkFields..Label2..Caption +#: Property Editors/fldlinks.dfm:61 +msgid "&Joined Fields" +msgstr "Ver&knüpfte Felder" + +#. IndexFiles..Caption +#. IndexFiles..GroupBox1..Caption +#: Property Editors/ixedit.dfm:5 +msgid "Index Files" +msgstr "Indexdateien" + +#. IndexFiles..GroupBox1..Add..Caption +#: Property Editors/ixedit.dfm:34 +msgid "&Add..." +msgstr "Hin&zufügen..." + +#. IndexFiles..OpenDialog....OnClick +#: Property Editors/ixedit.dfm:92 +msgid "dBASE Multiple Index (*.MDX)|*.mdx|dBase Index (*.NDX)|*.ndx|FoxPro Index (*.CDX)|*.cdx\n" +msgstr "dBASE Mehrfachindex (*.MDX)|*.mdx|dBase Index (*.NDX)|*.ndx|FoxPro Index (*.CDX)|*.cdx\n" + +#. PictureEditorDlg..Caption +#: Property Editors/picedit.dfm:6 +msgid "Picture Editor" +msgstr "Bild-Editor" + +#. PictureEditorDlg..GroupBox1..Load..Caption +#. StrEditDlg..StringEditorMenu..LoadItem..Caption +#: Property Editors/picedit.dfm:76 +msgid "&Load..." +msgstr "&Laden..." + +#. PictureEditorDlg..GroupBox1..Save..Caption +#. StrEditDlg..StringEditorMenu..SaveItem..Caption +#: Property Editors/picedit.dfm:85 +msgid "&Save..." +msgstr "&Speichern..." + +#. PictureEditorDlg..OpenDialog....OnClick +#. PictureEditorDlg..SaveDialog....Top +#: Property Editors/picedit.dfm:104 +msgid "All (*.bmp;*.ico;*.emf;*.wmf)|*.bmp;*.ico;*.emf;*.wmf|Bitmaps (*.bmp)|*.bmp|Icons (*.ico)|*.ico|Enhanced Metafiles (*.emf)|*.emf|Metafiles (*.wmf)|*.wmf\n" +msgstr "Alle (*.bmp;*.ico;*.emf;*.wmf)|*.bmp;*.ico;*.emf;*.wmf|Bitmaps (*.bmp)|*.bmp|Icons (*.ico)|*.ico|Erweiterte Metadateien (*.emf)|*.emf|Metadateien (*.wmf)|*.wmf\n" + +#. SQLEditForm..Caption +#: Property Editors/sqledit.dfm:5 +msgid "CommandText Editor" +msgstr "Anweisungstext-Editor" + +#. SQLEditForm..TopPanel..TableListLabel..Caption +#: Property Editors/sqledit.dfm:52 +msgid "&Tables:" +msgstr "&Tabellen:" + +#. SQLEditForm..TopPanel..SQLLabel..Caption +#: Property Editors/sqledit.dfm:60 +msgid "&SQL:" +msgstr "&SQL:" + +#. SQLEditForm..MetaInfoPanel..TableListPanel..AddTableButton..Caption +#: Property Editors/sqledit.dfm:165 +msgid "Add T&able to SQL" +msgstr "T&abelle zu SQL hinzufügen" + +#. SQLEditForm..MetaInfoPanel..FieldsPanel..FieldListLabel..Caption +#: Property Editors/sqledit.dfm:183 +msgid "&Fields:" +msgstr "&Felder:" + +#. SQLEditForm..MetaInfoPanel..FieldsPanel..AddFieldButton..Caption +#: Property Editors/sqledit.dfm:203 +msgid "Add F&ield to SQL" +msgstr "F&eld zu SQL hinzufügen" + +#. StrEditDlg..Caption +#: Property Editors/stredit.dfm:5 +msgid "String List editor" +msgstr "String-Listen-Editor" + +#. StrEditDlg..LineCount..Caption +#: Property Editors/stredit.dfm:29 +msgid "0 lines" +msgstr "0 Linien" + +#. StrEditDlg..CodeWndBtn..Caption +#. StrEditDlg..StringEditorMenu..CodeEditorItem..Caption +#: Property Editors/stredit.dfm:36 +msgid "&Code Editor..." +msgstr "&Quelltext-Editor..." + +#. StrEditDlg..OpenDialog..DefaultExt +#: Property Editors/stredit.dfm:84 +msgid "TXT" +msgstr "TXT" + +#. StrEditDlg..OpenDialog....DefaultExt +#. StrEditDlg..SaveDialog....Left +#: Property Editors/stredit.dfm:88 +msgid "Text files (*.TXT)|*.TXT|Config files (*.SYS;*.INI)|*.SYS;*.INI|Batch files (*.BAT)|*.BAT|All files (*.*)|*.*\n" +msgstr "Textdateien (*.TXT)|*.TXT|Konfigurationsdateien (*.SYS;*.INI)|*.SYS;*.INI|Batchdateien (*.BAT)|*.BAT|Alle Dateien (*.*)|*.*\n" + +#. StrEditDlg..OpenDialog..Title +#: Property Editors/stredit.dfm:89 +msgid "Load string list" +msgstr "String-Liste laden" + +#. StrEditDlg..SaveDialog..Title +#: Property Editors/stredit.dfm:97 +msgid "Save string list" +msgstr "String-Liste speichern" + +#. UpdateSQLEditForm..PageControl..FieldsPage..Caption +#: Property Editors/updsqled.dfm:54 +msgid "Options" +msgstr "Optionen" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Caption +#: Property Editors/updsqled.dfm:60 +msgid " SQL Generation " +msgstr "SQL Generierung" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label1..Caption +#: Property Editors/updsqled.dfm:67 +msgid "Table &Name:" +msgstr "Tabellen&name:" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label4..Caption +#: Property Editors/updsqled.dfm:83 +msgid "Update &Fields:" +msgstr "Update &Felder:" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..GenerateButton..Caption +#: Property Editors/updsqled.dfm:123 +msgid "&Generate SQL" +msgstr "SQL &generieren" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..PrimaryKeyButton..Caption +#: Property Editors/updsqled.dfm:132 +msgid "Select &Primary Keys" +msgstr "Hau&ptschlüsseln auswählen" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..DefaultButton..Caption +#: Property Editors/updsqled.dfm:141 +msgid "&Dataset Defaults" +msgstr "&Dataset Voreinstellungen" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..QuoteFields..Caption +#: Property Editors/updsqled.dfm:151 +msgid "&Quote Field Names" +msgstr "&Feldname in Hochkoma setzen:" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..GetTableFieldsButton..Caption +#: Property Editors/updsqled.dfm:160 +msgid "Get &Table Fields" +msgstr "&Tabellenfelder holen" + +#. UpdateSQLEditForm..PageControl..SQLPage..Caption +#: Property Editors/updsqled.dfm:167 +msgid "SQL" +msgstr "SQL" + +#. UpdateSQLEditForm..PageControl..SQLPage..Label2..Caption +#: Property Editors/updsqled.dfm:173 +msgid "S&QL Text:" +msgstr "S&QL Text:" + +#. UpdateSQLEditForm..PageControl..SQLPage..StatementType..Caption +#: Property Editors/updsqled.dfm:190 +msgid "Statement Type" +msgstr "Angabentyp" + +#. UpdateSQLEditForm..PageControl..SQLPage..StatementType....Items.Strings +#: Property Editors/updsqled.dfm:197 +msgid "" +"&Modify\n" +"&Insert\n" +"&Delete\n" +msgstr "" +"&Modifizieren\n" +"&Einfügen\n" +"&Löschen\n" + +#. UpdateSQLEditForm..FieldListPopup..miClearAll..Caption +#: Property Editors/updsqled.dfm:214 +msgid "&Clear All" +msgstr "Alles Entfernen" + +#. HTTPServer......Name +#: Vcl/httpintr.dfm:6 +msgid "Interpreter" +msgstr "Interpreter" + +#. SocketForm..Caption +#: Vcl/scktmain.dfm:6 +msgid "Borland Socket Server" +msgstr "Borland Socket-Server" + +#. SocketForm..Pages..PropPage..PortGroup..Caption +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#. SocketForm..Panel1..HeaderControl1......Text +#: Vcl/scktmain.dfm:38 +msgid "Port" +msgstr "Port" + +#. SocketForm..Pages..PropPage..PortGroup..Label1..Caption +#: Vcl/scktmain.dfm:46 +msgid "&Listen on Port:" +msgstr "P&ort überwachen:" + +#. SocketForm..Pages..PropPage..PortGroup..PortDesc....AutoSize +#: Vcl/scktmain.dfm:60 +msgid "Many values of Port are associated by convention with a particular service such as ftp or http. Port is the ID of the connection on which the server listens for client requests. \n" +msgstr "Viele Werte von Port sind mit bestimmten Diensten wie ftp oder http assoziiert. Port ist die ID der Verbindung, auf der der Server auf Client-Anfragen wartet. \n" + +#. SocketForm..Pages..PropPage..ThreadGroup..Caption +#: Vcl/scktmain.dfm:92 +msgid "Thread Caching" +msgstr "Thread-Pufferung" + +#. SocketForm..Pages..PropPage..ThreadGroup..Label4..Caption +#: Vcl/scktmain.dfm:100 +msgid "&Thread Cache Size:" +msgstr "Größe des &Thread-Puffers:" + +#. SocketForm..Pages..PropPage..ThreadGroup..ThreadDesc....AutoSize +#: Vcl/scktmain.dfm:113 +msgid "Thread Cache Size is the maximum number of threads that can be reused for new client connections.\n" +msgstr "Thread Cache Size ist die maximale Anzahl der Threads, die für neue Cleint-Verbindungen wiederbenutzt werden können.\n" + +#. SocketForm..Pages..PropPage..InterceptGroup..Caption +#: Vcl/scktmain.dfm:145 +msgid "Intercept GUID" +msgstr "Abfang-GUID" + +#. SocketForm..Pages..PropPage..InterceptGroup..Label5..Caption +#: Vcl/scktmain.dfm:152 +msgid "&GUID:" +msgstr "&GUID:" + +#. SocketForm..Pages..PropPage..InterceptGroup..GUIDDesc....AutoSize +#: Vcl/scktmain.dfm:164 +msgid "Intercept GUID is the GUID for a data interceptor COM object. See help for the TSocketConnection for details.\n" +msgstr "Intercept GUID ist die GUID für ein Data Interceptor COM-Objekt. Für Details siehe Hilfe von TSocketConnection.\n" + +#. SocketForm..Pages..PropPage..TimeoutGroup..Caption +#: Vcl/scktmain.dfm:180 +msgid "Timeout" +msgstr "Zeitüberschreitung" + +#. SocketForm..Pages..PropPage..TimeoutGroup..Label7..Caption +#: Vcl/scktmain.dfm:188 +msgid "&Inactive Timeout:" +msgstr "&Inaktivitäts-Timeout:" + +#. SocketForm..Pages..PropPage..TimeoutGroup..TimeoutDesc....AutoSize +#: Vcl/scktmain.dfm:201 +msgid "Inactive Timeout specifes the number of minutes a client can be inactive before being disconnected. (0 indicates infinite)\n" +msgstr "Inaktivitäts-Timeout gibt die Minuten an, bevor die Verbindung zu einem nicht aktiver Client getrennt wird. (0 bedeutet kein Timeout)\n" + +#. SocketForm..Pages..StatPage..Caption +#: Vcl/scktmain.dfm:239 +msgid "Users" +msgstr "Benutzer" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:252 +msgid "IP Address" +msgstr "IP-Adresse" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:256 +msgid "Host" +msgstr "Host" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:260 +msgid "Last Activity" +msgstr "Letzte Aktivität" + +#. SocketForm..PopupMenu..miProperties..Caption +#: Vcl/scktmain.dfm:327 +msgid "&Properties" +msgstr "&Eigenschaften" + +#. SocketForm..MainMenu1..miPorts..Caption +#: Vcl/scktmain.dfm:343 +msgid "&Ports" +msgstr "&Ports" + +#. SocketForm..MainMenu1..miPorts..miExit..Caption +#: Vcl/scktmain.dfm:355 +msgid "&Exit" +msgstr "&Beenden" + +#. SocketForm..MainMenu1..Connections1..Caption +#: Vcl/scktmain.dfm:360 +msgid "&Connections" +msgstr "V&erbindungen" + +#. SocketForm..ActionList1..ApplyAction..Caption +#: Vcl/scktmain.dfm:379 +msgid "&Apply" +msgstr "Ü&bernehmen" + +#. SocketForm..ActionList1..DisconnectAction..Caption +#: Vcl/scktmain.dfm:384 +msgid "&Disconnect" +msgstr "&Verbindung trennen" + +#. SocketForm..ActionList1..ShowHostAction..Caption +#: Vcl/scktmain.dfm:389 +msgid "&Show Host Name" +msgstr "Zeige Ho&stname" + +#. SocketForm..ActionList1..RemovePortAction..Caption +#: Vcl/scktmain.dfm:394 +msgid "&Remove" +msgstr "Ent&fernen" + +#. SocketForm..ActionList1..RegisteredAction..Caption +#: Vcl/scktmain.dfm:399 +msgid "&Registered Objects Only" +msgstr "&Nur registrierte Objekte" + +#~ msgid " &Images " +#~ msgstr " B&ilder " +#~ msgid " &Selected Image " +#~ msgstr " Ausge&wählte Grafik " +#~ msgid " Log S&ize " +#~ msgstr " &Protokollgröße " +#~ msgid " Value" +#~ msgstr " Wert" +#~ msgid " any known drive" +#~ msgstr " Alle bekannten Laufwerke" +#~ msgid " not specified" +#~ msgstr " nicht angegeben" +#~ msgid "" +#~ "\"%s\"\n" +#~ "File not found." +#~ msgstr "" +#~ "\"%s\"\n" +#~ "Datei nicht gefunden." +#~ msgid "" +#~ "\"%s\"\n" +#~ "File not found.\n" +#~ "Please verify the correct filename was given." +#~ msgstr "" +#~ "\"%s\"\n" +#~ "Datei nicht gefunden.\n" +#~ "Überprüfen Sie, ob der\t korrekte Dateiname angegeben wurde." +#~ msgid "" +#~ "\"%s\"\n" +#~ "Path not found.\n" +#~ "Please verify the correct path was given." +#~ msgstr "" +#~ "%s\n" +#~ "Pfad nicht gefunden.\n" +#~ "Überprüfen Sie, ob der korrektePfad angegeben wurde." +#~ msgid "\"%s\" Command not implemented." +#~ msgstr "\"%s\" Anweisung nicht implementiert." +#~ msgid "\"%s\" DOMImplementation already registered" +#~ msgstr "DOM-Implementierung \"%s\" bereits registriert" +#~ msgid "" +#~ "\"%s\" already exists.\n" +#~ "Do you want to replace it?" +#~ msgstr "" +#~ "%s existiert bereits.\n" +#~ "Soll es überschrieben werden?" +#~ msgid "\"%s\" created." +#~ msgstr "\"%s\" erzeugt." +#~ msgid "\"%s\" is is working directory." +#~ msgstr "\"%s\" ist Arbeitsverzeichnis." +#~ msgid "\"%s\" is not a subdirectory of \"%s\"" +#~ msgstr "\"%s\" ist kein Unterverzeichnis von \"%s\"" +#~ msgid "%0:s: Action %1:s not found in associated Adapter" +#~ msgstr "%0:s: Aktion %1:s im zugeordneten Adapter nicht gefunden" +#~ msgid "%0:s: Dataset %1:s not active" +#~ msgstr "%0:s: Datenmenge %1:s ist nicht aktiv" +#~ msgid "%0:s: Dataset %1:s unknown keyfields" +#~ msgstr "%0:s: Datenmenge %1:s unbekannte Schlüsselfelder" +#~ msgid "%0:s: Field %1:s not found in associated Adapter" +#~ msgstr "%0:s: Feld %1:s im zugeordneten Adapter nicht gefunden" +#~ msgid "%0:s: ValueField property value is blank" +#~ msgstr "%0:s: Eigenschaftswert von ValueField ist leer" +#~ msgid "%d MB" +#~ msgstr "%d MB" +#~ msgid "%d: Circular links are not allowed" +#~ msgstr "%d: Zirkulärverweise sind nicht gestattet" +#~ msgid "%f Julian cannot be represented as a DateTime" +#~ msgstr "" +#~ "%f Julianischer Wert kann nicht als Datum/Uhrzeitwert dargestellt werden" +#~ msgid "%s" +#~ msgstr "%s" +#~ msgid "%s %s Error: (%d)%s" +#~ msgstr "%s %s Fehler (%d)%s" +#~ msgid "%s - %s" +#~ msgstr "%s - %s" +#~ msgid "%s - PortTypes:" +#~ msgstr "%s - PortTypen:" +#~ msgid "%s ActionManager property has not been assigned" +#~ msgstr "%s ActionManager-Eigenschaft wurde nichts zugewiesen" +#~ msgid "%s Address Error" +#~ msgstr "%s Adress-Fehler" +#~ msgid "%s Address Okay" +#~ msgstr "%s Adresse OK" +#~ msgid "%s Command successful." +#~ msgstr "%s Anweisung erfolgreich." +#~ msgid "%s Non-visual component for 32-bit Delphi." +#~ msgstr "%s Nichtvisuelle Komponente für 32-Bit Delphi." +#~ msgid "%s [%s%s]" +#~ msgstr "%s [%s%s]" +#~ msgid "%s cannot be set on a ref item" +#~ msgstr "%s darf für ein Verweiselement nicht gesetzt werden" +#~ msgid "%s component requires Client to function properly" +#~ msgstr "Komponente %s setzt voraus, dass der Client richtig funktioniert." +#~ msgid "%s component requires Server to function properly" +#~ msgstr "Komponente %s setzt voraus, dass der Server richtig funktioniert." +#~ msgid "%s could not be loaded." +#~ msgstr "%s konnte nicht geladen werden." +#~ msgid "%s directory structure." +#~ msgstr "%s Verzeichnisstruktur." +#~ msgid "%s does not allow hiding" +#~ msgstr "%s kann nicht verborgen werden" +#~ msgid "%s does not allow multiple files" +#~ msgstr "Mehrere Dateien bei %s nicht zulässig" +#~ msgid "%s does not allow multiple values" +#~ msgstr "Mehrere Werte bei %s nicht zulässig" +#~ msgid "%s does not support file upload" +#~ msgstr "%s unterstützt den Datei-Upload nicht" +#~ msgid "%s has a factor of zero" +#~ msgstr "%s hat den Faktor Null" +#~ msgid "%s is already in the StatusBar" +#~ msgstr "%s befindet sich bereits in der Statuszeile" +#~ msgid "%s is corrupt." +#~ msgstr "%s ist beschädigt." +#~ msgid "%s is not a Gopher+ server" +#~ msgstr "%s ist kein Gopher+-Server" +#~ msgid "%s is not a valid BCD value" +#~ msgstr "%s ist kein gültiger BCD-Wert" +#~ msgid "%s is not a valid hex string" +#~ msgstr "%s ist kein gültiger Hex-String" +#~ msgid "%s is not a valid service." +#~ msgstr "%s ist kein gültiger Service." +#~ msgid "" +#~ "%s is not a valid value for field '%s'. The allowed range is %s to %s" +#~ msgstr "" +#~ "%s ist kein gültiger Wert für Feld '%s'. Der zulässige Bereich ist %s bis " +#~ "%s" +#~ msgid "%s not in a class registration group" +#~ msgstr "%s befindet sich nicht in einer Gruppe für Klassenregistrierungen" +#~ msgid "%s requires a file" +#~ msgstr "Für %s ist eine Datei erforderlich" +#~ msgid "%s%s%s %s" +#~ msgstr "%s%s%s %s" +#~ msgid "%s, Default" +#~ msgstr "%s, Standard" +#~ msgid "%s.Seek not implemented" +#~ msgstr "%s.Seek nicht implementiert" +#~ msgid "%s: Action name is blank" +#~ msgstr "%s: Aktionsname fehlt" +#~ msgid "%s: Adapter property is nil" +#~ msgstr "%s: Adaptereigenschaft ist nil" +#~ msgid "%s: DataSet property is nil" +#~ msgstr "%s: Eigenschaft DataSet ist nil" +#~ msgid "%s: DisplayComponent property is nil" +#~ msgstr "%s: Eigenschaft DisplayComponent ist nil" +#~ msgid "%s: Fieldname is blank" +#~ msgstr "%s: Feldname fehlt" +#~ msgid "&About..." +#~ msgstr "&Info..." +#~ msgid "&Activate at Startup" +#~ msgstr "Bei Start &aktivieren" +#~ msgid "&Active" +#~ msgstr "&Aktiv" +#~ msgid "&Add or Remove Buttons" +#~ msgstr "&Schaltflächen hinzufügen oder entfernen" +#~ msgid "&Allow XML Packets" +#~ msgstr "Erl&aube XML-Pakete" +#~ msgid "&Apply Event" +#~ msgstr "Ereignis &anwenden" +#~ msgid "&Arrange" +#~ msgstr "An&ordnen" +#~ msgid "&Back" +#~ msgstr "&Zurück" +#~ msgid "&Bindings" +#~ msgstr "&Bindungen" +#~ msgid "&Bold" +#~ msgstr "Fe&tt" +#~ msgid "&Browse" +#~ msgstr "&Durchsuchen..." +#~ msgid "&Browse URL" +#~ msgstr "&URL durchsuchen" +#~ msgid "&Browser:" +#~ msgstr "&Browser:" +#~ msgid "&Bullets" +#~ msgstr "&Aufzählungszeichen" +#~ msgid "&Caption Options" +#~ msgstr "Ü&berschriftoptionen" +#~ msgid "&Caption:" +#~ msgstr "&Titel:" +#~ msgid "&Cascade" +#~ msgstr "Ü&berlappend" +#~ msgid "&Center" +#~ msgstr "&Zentriert" +#~ msgid "&Connection" +#~ msgstr "V&erbindung" +#~ msgid "&Contents" +#~ msgstr "I&nhalt" +#~ msgid "&Copy Selection" +#~ msgstr "Auswahl &kopieren" +#~ msgid "&Customize" +#~ msgstr "A&npassen" +#~ msgid "&Database:" +#~ msgstr "Datenban&k:" +#~ msgid "&Dataset Editor..." +#~ msgstr "&Dataset-Editor..." +#~ msgid "&Default URL:" +#~ msgstr "Standard-&URL:" +#~ msgid "&Delete Selection" +#~ msgstr "Auswahl &entfernen" +#~ msgid "&Delete when max exceeded:" +#~ msgstr "Bei Überschreiten des &Maximums löschen:" +#~ msgid "&Detail" +#~ msgstr "&Details" +#~ msgid "&Details..." +#~ msgstr "&Details..." +#~ msgid "&Down" +#~ msgstr "A&bwärts" +#~ msgid "&Download URL" +#~ msgstr "Von &URL herunterladen" +#~ msgid "&Edit CommandText" +#~ msgstr "Anweisungstext &bearbeiten" +#~ msgid "&Edit Connection Properties" +#~ msgstr "&Verbindungseigenschaften bearbeiten" +#~ msgid "&Field" +#~ msgstr "&Feld" +#~ msgid "&Fill Color:" +#~ msgstr "Füllf&arbe:" +#~ msgid "&Find Next" +#~ msgstr "&Weitersuchen" +#~ msgid "&Find..." +#~ msgstr "Su&chen..." +#~ msgid "&Finish" +#~ msgstr "&Fertig stellen" +#~ msgid "&Forward" +#~ msgstr "&Weiter" +#~ msgid "&Help on Help" +#~ msgstr "&Verwendung der Hilfe" +#~ msgid "&IP Address" +#~ msgstr "&IP-Adresse" +#~ msgid "&Italic" +#~ msgstr "&Kursiv" +#~ msgid "&Items" +#~ msgstr "&Einträge" +#~ msgid "&Large icons" +#~ msgstr "&Große Symbole" +#~ msgid "&List" +#~ msgstr "&Liste" +#~ msgid "&Local" +#~ msgstr "&Lokal" +#~ msgid "&Log" +#~ msgstr "Pr&otokoll" +#~ msgid "&Log To List" +#~ msgstr "&Log in Liste" +#~ msgid "&Log Traffic" +#~ msgstr "&Log des Verkehrs" +#~ msgid "&Look in:" +#~ msgstr "&Suchen in:" +#~ msgid "&Menu animations:" +#~ msgstr "&Menüanimationen:" +#~ msgid "&Minimize All" +#~ msgstr "&Alle verkleinern" +#~ msgid "&Move Selection" +#~ msgstr "Auswahl &verlagern" +#~ msgid "&New Item" +#~ msgstr "&Neuer Eintrag" +#~ msgid "&New Message Part..." +#~ msgstr "&Neuer Botschaftsteil..." +#~ msgid "&New Node" +#~ msgstr "&Neuer Knoten" +#~ msgid "&Next" +#~ msgstr "Tab" +#~ msgid "&Open" +#~ msgstr "Ö&ffnen" +#~ msgid "&Open Picture..." +#~ msgstr "&Bild öffnen..." +#~ msgid "&Open..." +#~ msgstr "Ö&ffnen..." +#~ msgid "&Options..." +#~ msgstr "&Optionen..." +#~ msgid "&Port" +#~ msgstr "&Port" +#~ msgid "&Port:" +#~ msgstr "&Port:" +#~ msgid "&Previous" +#~ msgstr "&Zurück" +#~ msgid "&Print..." +#~ msgstr "D&rucken..." +#~ msgid "&Protocol:" +#~ msgstr "&Protokoll:" +#~ msgid "&Reload" +#~ msgstr "Neu &laden" +#~ msgid "&Remote" +#~ msgstr "E&xtern" +#~ msgid "&Rename" +#~ msgstr "U&mbenennen" +#~ msgid "&Replace" +#~ msgstr "Erset&zen" +#~ msgid "&Reset" +#~ msgstr "&Zurücksetzen" +#~ msgid "&Reset..." +#~ msgstr "Symbolleisten" +#~ msgid "&Run..." +#~ msgstr "&Ausführen..." +#~ msgid "&Save Picture..." +#~ msgstr "Bild &speichern..." +#~ msgid "&Search Path:" +#~ msgstr "&Suchpfad:" +#~ msgid "&Send Mail..." +#~ msgstr "Mail &senden..." +#~ msgid "&Server" +#~ msgstr "&Server:" +#~ msgid "&Server:" +#~ msgstr "&Server:" +#~ msgid "&Service Editor ..." +#~ msgstr "&Service-Editor..." +#~ msgid "&Show in Log" +#~ msgstr "I&n Protokoll anzeigen" +#~ msgid "&Small Icons" +#~ msgstr "&Kleine Symbole" +#~ msgid "&Start Server" +#~ msgstr "&Server starten" +#~ msgid "&State Index:" +#~ msgstr "Status-&Index:" +#~ msgid "&Strikeout" +#~ msgstr "Format" +#~ msgid "&Tile Vertically" +#~ msgstr "&Vertikal anordnen" +#~ msgid "&Toolbar Options" +#~ msgstr "Sy&mbolleistenoptionen" +#~ msgid "&Topic Search" +#~ msgstr "&Suche über Schlüsselwort" +#~ msgid "&Translate Post" +#~ msgstr "&POST übersetzen" +#~ msgid "&Translate Text" +#~ msgstr "&Text übersetzen" +#~ msgid "&Transparent Color:" +#~ msgstr "&Transparent:" +#~ msgid "&UDP Port:" +#~ msgstr "U&DP-Port:" +#~ msgid "&Underline" +#~ msgstr "&Unterstrichen" +#~ msgid "&Undo" +#~ msgstr "&Rückgängig" +#~ msgid "&Up" +#~ msgstr "A&ufwärts" +#~ msgid "&Up one directory" +#~ msgstr "Ein Verzeichnis nach &oben" +#~ msgid "&Web Page Editor..." +#~ msgstr "Editor für &Web-Seiten..." +#~ msgid "&Wrap Text" +#~ msgstr "Text &umbrechen" +#~ msgid "" +#~ "  Link to WS-Inspection document of " +#~ "Services here" +#~ msgstr "" +#~ "  Verknüpfung mit WS-Inspektionsdokument " +#~ "der Services hier" +#~ msgid "'%d.%d' is not a valid timestamp" +#~ msgstr "'%d.%d' ist kein gültiger Zeitstempel" +#~ msgid "'%g' is not a valid date and time" +#~ msgstr "'%g' kein gültiger Datums- und Zeitwet" +#~ msgid "'%s' is not a valid GUID value" +#~ msgstr "'%s' kein gültiger Wert für GUID" +#~ msgid "'%s' is not a valid boolean value" +#~ msgstr "'%s' ist kein gültiger boolescher Wert" +#~ msgid "'%s' is not a valid currency value" +#~ msgstr "'%s' ist kein gültiger Währungwert" +#~ msgid "(%d, %d) is not a valid DateDay pair" +#~ msgstr "(%d, %d) ist kein gültiger Wert für die Tagesangabe im Datum" +#~ msgid "(%d, %d, %d) is not a valid DateWeek triplet" +#~ msgstr "(%d, %d, %d) ist kein gültiger Wert für die Wochenangabe im Datum" +#~ msgid "(%d, %d, %d, %d) is not a valid DateMonthWeek quad" +#~ msgstr "" +#~ "(%d, %d, %d, %d) ist kein gültiger Wert für die Monats- und Wochenangabe " +#~ "im Datum" +#~ msgid "(%d, %d, %d, %d) is not a valid DayOfWeekInMonth quad" +#~ msgstr "" +#~ "(%d, %d, %d, %d) ist kein gültiger Wert für dieTages- und Monatsangabe im " +#~ "Datum" +#~ msgid "(ADT)" +#~ msgstr "(ADT)" +#~ msgid "(All Actions)" +#~ msgstr "(Alle Aktionen)" +#~ msgid "(Array)" +#~ msgstr "(Array)" +#~ msgid "(Binary)" +#~ msgstr "(Binär)" +#~ msgid "(Checkmark toggles visibility)" +#~ msgstr "(Häkchen schaltet Anzeige um)" +#~ msgid "(No Category)" +#~ msgstr "(Keine Kategorie)" +#~ msgid "(No Name)" +#~ msgstr "(Kein Name)" +#~ msgid "(Not available)" +#~ msgstr "(Nicht verfügbar)" +#~ msgid "(Null)" +#~ msgstr "(Null)" +#~ msgid "(Unassigned)" +#~ msgstr "(Nicht zugewiesen)" +#~ msgid "(none)" +#~ msgstr "(Leer)" +#~ msgid "-Err 501 MailB is not implemented" +#~ msgstr "-Err 501 MailB ist nicht implementiert" +#~ msgid "/Clean" +#~ msgstr "/Clean" +#~ msgid "/Details" +#~ msgstr "/Details" +#~ msgid "/List" +#~ msgstr "/List" +#~ msgid "1999 XML Schema Translator (.xsd <-> .xsd)" +#~ msgstr "1999 XML-Schema-Übersetzung (.xsd <-> .xsd)" +#~ msgid "3D Dark Shadow" +#~ msgstr "3D Dunkler Schatten" +#~ msgid "3D Light" +#~ msgstr "3D Hell" +#~ msgid "<#LIST>" +#~ msgstr "<#LIST>" +#~ msgid "" +#~ msgstr "" +#~ msgid "" +#~ msgstr "" +#~ msgid "\n" +#~ msgstr "\n" +#~ msgid "" +#~ "

    Error Encountered

    Interface %s not found

    " +#~ msgstr "" +#~ "

    Fehler aufgetreten

    Interface %s wurde nicht " +#~ "gefunden

    " +#~ msgid "" +#~ "

    Forbidden (403)

    Access Forbidden

    " +#~ msgstr "" +#~ "

    Verboten (403)

    Zugang verboten

    " +#~ msgid "" +#~ msgstr "" +#~ msgid "" +#~ msgstr "" +#~ msgid "" +#~ msgstr "" +#~ msgid "" +#~ "Directory of %s

    Directory of %" +#~ "0:s

    \n" +#~ msgstr "" +#~ "Verzeichnis von %s

    Verzeichnis " +#~ "von %0:s

    \n" +#~ msgid "" +#~ "Unauthorized

    UnauthorizedProper authorization is required for this area. Either your browser " +#~ "does not perform authorization, or your authorization has failed.\n" +#~ msgstr "" +#~ "Nicht autorisiert

    Nicht " +#~ "autorisiert

    Für diesen Bereich ist eine Anmeldung erforderlich. " +#~ "Entweder hat Ihr Browser keine Anmeldung durchgeführt oder Ihre Anmeldung " +#~ "ist mißlungen.\n" +#~ msgid "" +#~ "Directory browsing is forbidden

    The " +#~ "requested URL is forbidden

    HTTP status code: 403\n" +#~ msgstr "" +#~ "Das Durchsuchen von Verzeichnissen ist nicht gestattet</" +#~ "TITLE><BODY><H1>Der Zugriff auf die angeforderte URL ist nicht gestattet</" +#~ "H1><P>HTTP-Statuscode: 403</BODY></HTML>\n" +#~ msgid "" +#~ "<HTML><TITLE>Invalid HTTP request: Method not allowed for HTTP/1.0</" +#~ "TITLE><BODY><H1>Invalid HTTP request: Method not allowed for HTTP/1.0</" +#~ "H1><P>HTTP status code: 400</BODY></HTML>\n" +#~ msgstr "" +#~ "<HTML><TITLE>Ungültige HTTP-Anforderung: Methode für HTTP/1.0 nicht " +#~ "zulässig

    Ungültige HTTP-Anforderung: Methode für " +#~ "HTTP/1.0 nicht zulässig

    HTTP-Statuscode: 400\n" +#~ msgid "" +#~ "The requested URL is forbidden

    The " +#~ "requested URL is forbidden

    HTTP status code: 403\n" +#~ msgstr "" +#~ "Der Zugriff auf die angeforderte URL ist nicht gestattet</" +#~ "TITLE><BODY><H1>Der Zugriff auf die angeforderte URL ist nicht gestattet</" +#~ "H1><P>HTTP-Statuscode: 403</BODY></HTML>\n" +#~ msgid "<LF>" +#~ msgstr "<LF>" +#~ msgid "<LI><A HREF=\"%s\">%s</A> (%d bytes)\n" +#~ msgstr "<LI><A HREF=\"%s\">%s</A> (%d Bytes)\n" +#~ msgid "<LI>[ <A HREF=\"%s\">%s</A> ]\n" +#~ msgstr "<LI>[ <A HREF=\"%s\">%s</A> ]\n" +#~ msgid "<No Records>" +#~ msgstr "<Keine Datensätze>" +#~ msgid "" +#~ "<TITLE>Internal Server Error

    Internal Server Error

    HTTP status code: 500

    HTTP error message: %s" +#~ msgstr "" +#~ "Interner Server-Fehler

    Interner Server-Fehler

    HTTP-Statuscode: 500

    HTTP-Fehlermeldung: %s" +#~ msgid "" +#~ "The requested URL was not found

    The requested URL " +#~ "was not found

    HTTP status code: 404" +#~ msgstr "" +#~ "Die angeforderte URL wurde nicht gefunden

    Die " +#~ "angeforderte URL wurde nicht gefunden

    HTTP-Statuscode: 404" +#~ msgid "

      \n" +#~ msgstr "
        \n" +#~ msgid "" +#~ msgstr "" +#~ msgid "List>View List | View Details\n" +#~ msgstr "" +#~ "List>Zeige Lise | Zeige Details\n" +#~ msgid "%s > %s" +#~ msgstr "%s > %s" +#~ msgid "" +#~ "View List | Details\">View Details\n" +#~ msgstr "" +#~ "Zeige Liste | Details\">Zeige Details\n" +#~ msgid "" +#~ "

        Internal Application Error

        \n" +#~ "

        %0:s\n" +#~ "


        %1:s" +#~ msgstr "" +#~ "

        Interner Anwendungsfehler

        \n" +#~ "

        %0:s\n" +#~ "


        %1:s" +#~ msgid "" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "
        \n" +#~ "Error[%0:d]: \n" +#~ "%1:s\n" +#~ "\n" +#~ "
        \n" +#~ "Line: \n" +#~ "%2:d\n" +#~ "\n" +#~ "\n" +#~ "Position: \n" +#~ "%3:d\n" +#~ "\n" +#~ "
        \n" +#~ msgstr "" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "
        \n" +#~ "Fehler[%0:d]: \n" +#~ "%1:s\n" +#~ "\n" +#~ "
        \n" +#~ "Zeile: \n" +#~ "%2:d\n" +#~ "\n" +#~ "\n" +#~ "Position: \n" +#~ "%3:d\n" +#~ "\n" +#~ "
        \n" +#~ msgid "@ Outside address" +#~ msgstr "@ Outside-Adresse" +#~ msgid "A call to an OS function failed" +#~ msgstr "Ein Aufruf einer Betriebssystemfunktion ist fehlgeschlagen" +#~ msgid "" +#~ "A file with that name already exists. Please specify a different filename." +#~ msgstr "" +#~ "Eine Datei mit diesem Namen gibt es bereits. Geben Sie einen anderen " +#~ "Dateinamen an." +#~ msgid "A key with the name of \"%s\" already exists" +#~ msgstr "Schlüssel mit der Bezeichnung \"%s\" existiert bereits" +#~ msgid "A message has been received but the commication mode is unknown" +#~ msgstr "" +#~ "Es wurde eine Botschaft empfangen, aber der Kommunikationsmodus ist " +#~ "unbekannt" +#~ msgid "A script error occured. Do you want to debug?" +#~ msgstr "Es ist ein Script-Fehler aufgetreten. Möchten Sie ihn suchen?" +#~ msgid "A style named %s has already been registered" +#~ msgstr "Ein Attribut namens %s wurde bereits registriert" +#~ msgid "A transaction is already active" +#~ msgstr "Es ist bereits eine Transaktion aktiv" +#~ msgid "A&ctions:" +#~ msgstr "&Aktionen:" +#~ msgid "A&pply" +#~ msgstr "Ü&bernehmen" +#~ msgid "About" +#~ msgstr "Info" +#~ msgid "About Internet &Direct (Indy) %s..." +#~ msgstr "Info über Internet &Direct (Indy) %s..." +#~ msgid "About Web App Debugger" +#~ msgstr "Info über den Debugger für Web-Anwendungen" +#~ msgid "About..." +#~ msgstr "Info..." +#~ msgid "AcceptWait property cannot be modified while server is active." +#~ msgstr "" +#~ "Die Eigenschaft AcceptWait kann nicht modifiziert werden, während der " +#~ "Server aktiv ist." +#~ msgid "Accepted" +#~ msgstr "Akzeptiert" +#~ msgid "Access denied to \"%s\"" +#~ msgstr "Zugriff auf \"%s\" verweigert" +#~ msgid "Access denied." +#~ msgstr "Zugriff verweigert." +#~ msgid "Access to %s denied" +#~ msgstr "Zugriff auf %s verweigert." +#~ msgid "Access violation" +#~ msgstr "Zugriffsverletzung" +#~ msgid "Access violation at address %p, accessing address %p" +#~ msgstr "Access violation at address %p, accessing address %p" +#~ msgid "AccessRights" +#~ msgstr "Zugriffsrechte" +#~ msgid "AcreFeet" +#~ msgstr "Morgen/Fuß" +#~ msgid "AcreInches" +#~ msgstr "Morgen/Zoll" +#~ msgid "Acres" +#~ msgstr "Morgen" +#~ msgid "Action can't redirect to blank URL" +#~ msgstr "Aktion kann nicht zu leerer URL umleiten" +#~ msgid "Action can't respone to unknown HTTP method" +#~ msgstr "Aktion kann nicht auf unbekannte HTTP -Methode antworten" +#~ msgid "Action does not provide response" +#~ msgstr "Aktion sieht keine Antwort vor" +#~ msgid "ActionManager must first be assigned" +#~ msgstr "ActionManager muss zuerst zugewiesen werden" +#~ msgid "Actions" +#~ msgstr "Aktionen" +#~ msgid "Active Border" +#~ msgstr "Aktiver Rahmen" +#~ msgid "Active Caption" +#~ msgstr "Aktive Titelleiste" +#~ msgid "Adapter Request not handled: %0:s, %1:s" +#~ msgstr "Adapteranforderung nicht behandelt: %0:s, %1:s" +#~ msgid "Add" +#~ msgstr "Hinzufügen" +#~ msgid "Add &SubItem" +#~ msgstr "Hin&zufügen" +#~ msgid "Add Actions" +#~ msgstr "Aktionen hinzufügen" +#~ msgid "Add Actions..." +#~ msgstr "Aktionen hinzufügen..." +#~ msgid "Add All Actions" +#~ msgstr "Alle Aktionen hinzufügen" +#~ msgid "Add All Actions..." +#~ msgstr "Alle Aktionen hinzufügen..." +#~ msgid "Add All Columns" +#~ msgstr "Alle Spalten hinzufügen" +#~ msgid "Add All Commands" +#~ msgstr "Alle Befehle hinzufügen" +#~ msgid "Add All Fields" +#~ msgstr "Alle Felder hinzufügen" +#~ msgid "Add All Params" +#~ msgstr "Alle Parameter hinzufügen" +#~ msgid "Add Columns" +#~ msgstr "Spalten hinzufügen" +#~ msgid "Add Columns..." +#~ msgstr "Spalten hinzufügen..." +#~ msgid "Add Commands" +#~ msgstr "Befehle hinzufügen" +#~ msgid "Add Commands..." +#~ msgstr "Befehle hinzufügen..." +#~ msgid "Add Fields..." +#~ msgstr "Felder hinzufügen..." +#~ msgid "Add Images" +#~ msgstr "Bilder hinzufügen" +#~ msgid "Add Params..." +#~ msgstr "Parameter hinzufügen..." +#~ msgid "Add item" +#~ msgstr "Eintrag hinzufügen" +#~ msgid "Additional" +#~ msgstr "Zusätzlich" +#~ msgid "Address already in use." +#~ msgstr "Die Adresse ist bereits in Gebrauch." +#~ msgid "Address family not supported by protocol family." +#~ msgstr "Die Adressfamilie wird von der Protokollfamilie nicht unterstützt." +#~ msgid "Address type not supported." +#~ msgstr "Der Adresstyp wird nicht unterstützt." +#~ msgid "Administrator" +#~ msgstr "Administrator" +#~ msgid "Alert: action must be taken immediately" +#~ msgstr "Alarm: Es muss sofort etwas getan werden" +#~ msgid "Align &Left" +#~ msgstr "&Links ausrichten" +#~ msgid "Align &Right" +#~ msgstr "&Rechts ausrichten" +#~ msgid "Align Left|Aligns text at the left indent" +#~ msgstr "Links ausrichten|Text linksbündig ausrichten" +#~ msgid "Align Right|Aligns text at the right indent" +#~ msgstr "Rechts ausrichten|Text rechtsbündig ausrichten" +#~ msgid "All Files (*)|*" +#~ msgstr "Alle Dateien(*)|*" +#~ msgid "All Files (*)|*|" +#~ msgstr "Alle Dateien (*)|*|" +#~ msgid "All Files (*.*)|*.*" +#~ msgstr "Alle Dateien(*.*)|*.*" +#~ msgid "All Files (*.*)|*.*|" +#~ msgstr "Alle Dateien (*.*)|*.*|" +#~ msgid "All Files(*)" +#~ msgstr "Alle Dateien (*)" +#~ msgid "Allowed login attempts exceeded, good bye." +#~ msgstr "Die Anzahl erlaubter Anmeldeversuche wurde überschritten, goodbye." +#~ msgid "Already connected." +#~ msgstr "Verbindung besteht bereits." +#~ msgid "An About Box is not available for this control" +#~ msgstr "Für dieses Element gibt es kein Info-Fenster" +#~ msgid "An unknown error occurred while processing the certificate." +#~ msgstr "Beim Bearbeiten des Zertifikats ist ein Fehler aufgetreten." +#~ msgid "Angstroms" +#~ msgstr "Angström" +#~ msgid "Anonymous login OK, send e-mail as password." +#~ msgstr "Anonyme Anmeldung OK, E-Mail als Passwort senden." +#~ msgid "Anonymous user logged in, proceed." +#~ msgstr "Anonymer Benutzer angemeldet, weiter." +#~ msgid "Any" +#~ msgstr "Any" +#~ msgid "Application Workspace" +#~ msgstr "Anwendungsarbeitsbereich" +#~ msgid "Apply &to all toolbars" +#~ msgstr "&Für alle Symbolleisten verwenden" +#~ msgid "Apply caption options &to all toolbars" +#~ msgstr "Optionen für alle Symbolleisten verwenden" +#~ msgid "Aqua" +#~ msgstr "Aquamarin" +#~ msgid "Are you sure you want to delete \"%s\"?" +#~ msgstr "Wollen Sie \"%s\" wirklich löschen?" +#~ msgid "Are you sure you want to delete these %d items?" +#~ msgstr "Wollen Sie diese %d Einträge wirklich löschen?" +#~ msgid "Area" +#~ msgstr "Fläche" +#~ msgid "Ares" +#~ msgstr "Ar" +#~ msgid "Array Node: %s has too many elements" +#~ msgstr "Array-Knoten: %s hat zu viele Elemente" +#~ msgid "Array type expected. Node %s" +#~ msgstr "Array-Typ erwartet. Knoten %s" +#~ msgid "Assigned Port value %d is invalid" +#~ msgstr "Zugewiesener Wert für Port %d ist ungültig" +#~ msgid "AstronomicalUnits" +#~ msgstr "Astronomische Einheiten" +#~ msgid "Attempt to %s while the HL7 Component is not working" +#~ msgstr "Versuch zu %s wobei die HL7-Komponente nicht funktioniert" +#~ msgid "Attempting to put items into a virtual style listbox" +#~ msgstr "Versuch, Elemente in ein virtuelles Stillistenfeld einzufügen" +#~ msgid "Attribute already associated with another element" +#~ msgstr "Das Attribut ist bereits mit einem anderen Element verknüpft" +#~ msgid "Attributes" +#~ msgstr "Attribute" +#~ msgid "Attributes are not supported on this node type" +#~ msgstr "Attribute werden bei diesem Knotentyp nicht unterstützt" +#~ msgid "Authenticated" +#~ msgstr "Authentifiziert" +#~ msgid "Authentication Failed" +#~ msgstr "Authentifizierung fehlgeschlagen" +#~ msgid "Authentication error to socks server." +#~ msgstr "Authentifizierungsfehler bei Socks-Server." +#~ msgid "Auto Preview" +#~ msgstr "Schnellvorschau" +#~ msgid "Avg Response Time:" +#~ msgstr "Mittlere Antwortzeit:" +#~ msgid "BCD overflow" +#~ msgstr "BCD-Überlauf" +#~ msgid "Back" +#~ msgstr "Zurück" +#~ msgid "BackTab" +#~ msgstr "RückTab" +#~ msgid "Background" +#~ msgstr "Hintergrund" +#~ msgid "Backspace" +#~ msgstr "Rück" +#~ msgid "Backup Database files" +#~ msgstr "Datenbankdateien sichern" +#~ msgid "Bad Gateway" +#~ msgstr "Falsches Gateway" +#~ msgid "Bad Request" +#~ msgstr "Falsche Anforderung" +#~ msgid "Bad address." +#~ msgstr "Falsche Adresse." +#~ msgid "Bad file number." +#~ msgstr "Falsche Dateinummer." +#~ msgid "Bad protocol option." +#~ msgstr "Falsche Protokolloption." +#~ msgid "Bad variant type %x" +#~ msgstr "Falscher Variant-Typ %x" +#~ msgid "Binding Editor" +#~ msgstr "Editor für Bindungen" +#~ msgid "Bitmaps (*.bmp)|*.bmp" +#~ msgstr "Bitmaps (*.bmp)|*.bmp" +#~ msgid "Black" +#~ msgstr "Schwarz" +#~ msgid "Blue" +#~ msgstr "Blau" +#~ msgid "Body Text Editor" +#~ msgstr "Editor für Textkörper" +#~ msgid "Boolean parameter expected" +#~ msgstr "Boolescher Parameter erwartet" +#~ msgid "Bring to Front" +#~ msgstr "Nach vorne setzen" +#~ msgid "Browse URL" +#~ msgstr "Internet" +#~ msgid "BrowseAction" +#~ msgstr "BrowseAction" +#~ msgid "Build" +#~ msgstr "Erzeugen" +#~ msgid "Built-in Type" +#~ msgstr "Integrierter Typ" +#~ msgid "Bullets|Inserts a bullet on the current line" +#~ msgstr "" +#~ "Aufzählungszeichen|In die aktuielle Zeile ein Aufzählungszeichen einfügen" +#~ msgid "Button Face" +#~ msgstr "Schalterfläche" +#~ msgid "Button Highlight" +#~ msgstr "Schalterhervorhebung" +#~ msgid "Button Shadow" +#~ msgstr "Schalterschatten" +#~ msgid "Button Text" +#~ msgstr "Schaltertext" +#~ msgid "Byte index out of range." +#~ msgstr "Byte-Index außerhalb des gültigen Bereichs." +#~ msgid "" +#~ "ByteBool, WordBool and LongBool cannot be exposed by WebServices. Please " +#~ "use 'Boolean'" +#~ msgstr "" +#~ "ByteBool, WordBool und LongBool käönnen durch WebServices nicht " +#~ "dargestellt werden. Bitte verwenden Sie 'Boolean'" +#~ msgid "C&lose" +#~ msgstr "S&chließen" +#~ msgid "CRC Failed" +#~ msgstr "CRC fehlgeschlagen" +#~ msgid "Call to %s.GetByte [property Bytes] with index <> [0..%d]" +#~ msgstr "Aufruf von %s.GetByte [property Bytes] mit Index <> [0..%d]" +#~ msgid "Can not bind in port range (%d - %d)" +#~ msgstr "Port-Beriech (%d - %d) kann nicht eingebunden werden" +#~ msgid "Can not change credentials after handle aquired. Use Release first" +#~ msgstr "" +#~ "Beglaubigung kann nicht nach Holen des Handle geändert werden. Zuerst " +#~ "Release benutzen" +#~ msgid "Can't execute %s %d" +#~ msgstr "Ausführung nicht möglich von %s %d" +#~ msgid "Can't find included page: %s" +#~ msgstr "Einbezogene Seite %s nicht gefunden" +#~ msgid "Can't open data connection." +#~ msgstr "Datenverbindung klann nicht geöffnet werden." +#~ msgid "Cannot allocate socket." +#~ msgstr "Socket kann nicht zugewiesen werden." +#~ msgid "" +#~ "Cannot assign a subitem to an actionbar when one of it's parent's is " +#~ "already assigned to an actionbar" +#~ msgstr "" +#~ "Unterelement kann nicht zu Aktionsleiste hinzugefügt werden, wenn ein " +#~ "übergeordnetes Element bereits einer Aktionsleiste zugewiesen ist" +#~ msgid "Cannot assign requested address." +#~ msgstr "Die angeforderte Adresse kann nicht zugewiesen werden." +#~ msgid "Cannot call TerminateAndWaitFor on FreeAndTerminate threads" +#~ msgstr "" +#~ "Aufruf von TerminateAndWaitFor für FreeAndTerminate-Threads nicht möglich" +#~ msgid "Cannot change connection on Active Monitor" +#~ msgstr "Die Verbindung kann bei aktivem Monitor nicht geändert werden" +#~ msgid "Cannot change session state when the server is active." +#~ msgstr "" +#~ "Sitzungsstatus kann nicht geändert werden, während der Server aktiv ist.." +#~ msgid "Cannot change target while active." +#~ msgstr "Ziel kann in aktivem Zustand nicht geändert werden." +#~ msgid "Cannot convert NAN to TBcd value" +#~ msgstr "NAN kann nicht zu TBcd-Wert konvertiert werden" +#~ msgid "Cannot convert empty string to TBcd value" +#~ msgstr "Leerer String kann nicht in TBcd-Wert konvertiert werden" +#~ msgid "Cannot convert from the specified type" +#~ msgstr "Konvertierung des angegebenen Typs kann nicht durchgeführt werden" +#~ msgid "Cannot convert scientific notation to TBcd value" +#~ msgstr "" +#~ "Wissenschaftliche Notation kann nicht zu TBcd-Wert konvertiert werden" +#~ msgid "Cannot convert to TBcd: string has more than 64 digits: %s" +#~ msgstr "" +#~ "Keine Konvertierung nach TBcd: String enthält mehr als 64 Ziffern: %s" +#~ msgid "Cannot convert to the specified type" +#~ msgstr "Konvertierung in den angegebenen Typ kann nicht durchgeführt werden" +#~ msgid "Cannot create a method for an unnamed component" +#~ msgstr "Für eine unbenannte Komponente kann keine Methode erstellt werden." +#~ msgid "Cannot create file \"%s\". %s" +#~ msgstr "Datei \"%s\" kann nicht erstellt werden. %s" +#~ msgid "Cannot create script engine: %s. Error: %x" +#~ msgstr "Script-Engine kann nicht erzeugt werden: %s. Fehler: %x" +#~ msgid "Cannot find TableName in CommandText" +#~ msgstr "Eigenschaft TableName in CommandText nicht gefunden" +#~ msgid "Cannot find node referenced by ID %s" +#~ msgstr "Von ID %s referenzierten Knoten nicht gefunden" +#~ msgid "Cannot focus a disabled or invisible window (%s)" +#~ msgstr "" +#~ "Ein deaktiviertes oder unsichtbares Fenster (%s) kann den Fokus nicht " +#~ "erhalten" +#~ msgid "Cannot initialize script engine" +#~ msgstr "Script-Engine kann nicht initialisiert werden" +#~ msgid "Cannot insert child node" +#~ msgstr "Untergeordneter Knoten kann nicht eingefügt werden" +#~ msgid "Cannot open detail table with master closed" +#~ msgstr "" +#~ "Detailtabelle kann nicht geöffnet werden, wenn die Haupttabelle " +#~ "geschlossen ist." +#~ msgid "Cannot open file \"%s\". %s" +#~ msgstr "Datei %s kann nicht geöffnet werden. %s" +#~ msgid "Cannot perform task while server is active." +#~ msgstr "Task kann nicht ausgeführt werden, während der Server aktiv ist." +#~ msgid "Cannot perform this operation on a closed connection" +#~ msgstr "" +#~ "Bei einer geschlossenen Verbindung ist diese Operation nicht möglich" +#~ msgid "Cannot perform this operation on an open connection" +#~ msgstr "Bei einer geöffneten Verbindung ist diese Operation nicht möglich" +#~ msgid "Cannot read WideString from odd byte position" +#~ msgstr "" +#~ "WideString kann nicht von einer ungeraden Byte-Position aus gelesen werden" +#~ msgid "" +#~ "Cannot read directory:\n" +#~ "\"%s\"" +#~ msgstr "" +#~ "Verzeichnis kann nicht gelesen werden:\n" +#~ "\"%s\"" +#~ msgid "Cannot send or receive after socket is closed." +#~ msgstr "" +#~ "Nach Schließen des Socket kann weder gesendet noch empfangen werden." +#~ msgid "Cannot set Clipped property while painting" +#~ msgstr "" +#~ "Die Eigenschaft Clipped kann während des Zeichnens nicht geändert werden" +#~ msgid "Cannot write WideString to odd byte position" +#~ msgstr "" +#~ "WideString kann nicht an eine ungerade Byte-Position geschrieben werden" +#~ msgid "Cannt connect to the Master server" +#~ msgstr "Zum Haupt-Server kann keine Verbindung hergestellt werden" +#~ msgid "Capacity cannot be less than size" +#~ msgstr "Die Kapazität darf nicht geringer als die Größe sein" +#~ msgid "Caption Text" +#~ msgstr "Titeltext" +#~ msgid "Cascade" +#~ msgstr "Überlappend" +#~ msgid "Cate&gories:" +#~ msgstr "&Kategorien:" +#~ msgid "Celsius" +#~ msgstr "Celsius" +#~ msgid "Centares" +#~ msgstr "Zentarien" +#~ msgid "Center|Centers text between margins" +#~ msgstr "Zentriert|Text zentriert ausrichten" +#~ msgid "CentiLiters" +#~ msgstr "Zentiliter" +#~ msgid "Centigrams" +#~ msgstr "Zentigramm" +#~ msgid "Centimeters" +#~ msgstr "Zentimeter" +#~ msgid "Centuries" +#~ msgstr "Jahrhundert" +#~ msgid "Chains" +#~ msgstr "Messkette" +#~ msgid "Change view" +#~ msgstr "Ansicht ändern" +#~ msgid "" +#~ "CheckSynchronize called from thread $%x, which is NOT the main thread" +#~ msgstr "" +#~ "CheckSynchronize wurde vom Thread $%x aufgerufen, der NICHT der Haupt-" +#~ "Thread ist." +#~ msgid "ChildName cannot be blank" +#~ msgstr "ChildName muss angegeben werden" +#~ msgid "Chunk Started" +#~ msgstr "Chunk gestartet" +#~ msgid "Circular provider references not allowed." +#~ msgstr "Zirkuläre Provider-Referenzen nicht erlaubt." +#~ msgid "Circular reference to Connection not allowed" +#~ msgstr "Zirkulärer Verweis auf Verbindung nicht zulässig" +#~ msgid "Circular references not allowed" +#~ msgstr "Zirkuläre Verweise sind nicht gestattet" +#~ msgid "Class %s could not create QT widget" +#~ msgstr "Klasse %s konnte kein QT-Widget erzeugen" +#~ msgid "Class %s does not implement interface GUID %s" +#~ msgstr "Klasse %s implementiert Schnittstelle GUID %s nicht" +#~ msgid "Class %s is not applicable to this module" +#~ msgstr "Klasse %s kann bei diesem Modul nicht angewendet werden" +#~ msgid "Class not registered" +#~ msgstr "Klasse nicht registriert" +#~ msgid "" +#~ "Classes that represent scalar types must descend from TRemotableXS, %s " +#~ "does not" +#~ msgstr "" +#~ "Klassen, die Skalartypen repräsentieren, müssen von TRemotableXS " +#~ "abgeleitet worden sein; %s ist es nicht" +#~ msgid "Clear" +#~ msgstr "Löschen" +#~ msgid "Clear Selection" +#~ msgstr "Liste" +#~ msgid "CloneConnection invalid: distinct ClientDataSet descendents" +#~ msgstr "CloneConnection ungültig: verschiedene ClientDataSet-Nachkommen" +#~ msgid "Close" +#~ msgstr "Schließen" +#~ msgid "Closing data connection." +#~ msgstr "Datenverbindung wird geschlossen." +#~ msgid "Code" +#~ msgstr "Code" +#~ msgid "Codeset conversion failure" +#~ msgstr "Fehler bei Codeset-Konvertierung" +#~ msgid "Color Select" +#~ msgstr "Dialog" +#~ msgid "Color depth must be 1, 8 or 32 bpp" +#~ msgstr "Die Farbtiefe muss 1, 8 oder 32 bpp betragen" +#~ msgid "Command Not Handled: %s" +#~ msgstr "Anweisung nicht behandelt: %s" +#~ msgid "Command Not Recognised" +#~ msgstr "Anweisung nicht erkannt" +#~ msgid "Command not recognized" +#~ msgstr "Anweisung nicht erkannt" +#~ msgid "Command not supported." +#~ msgstr "Anweisung nicht unterstützt" +#~ msgid "CompleteAuthToken is not supported" +#~ msgstr "CompleteAuthToken nicht unterstützt" +#~ msgid "Component %s not found" +#~ msgstr "Komponente %s nicht gefunden" +#~ msgid "Component does not support scripting. Class: %0:s, Name: %1:s" +#~ msgstr "" +#~ "Komponente unterstützt das Scripting nicht. Klasse: %0:s, Name: %1:s" +#~ msgid "" +#~ "Component is in Asynchronous mode but OnMessageArrive has not been hooked" +#~ msgstr "" +#~ "Komponente ist in asynchronen Modus, aber OnMessageArrive wurde nicht " +#~ "eingehängt (hooked)" +#~ msgid "" +#~ "Component is in Synchronous mode but OnMessageReceive has not been hooked" +#~ msgstr "" +#~ "Komponente ist in synchronen Modus, aber OnMessageReceive wurde nicht " +#~ "eingehängt (hooked)" +#~ msgid "Component name '%s' exceeds 64 character limit" +#~ msgstr "Komponentenname '%s' überschreitet 64 Zeichen" +#~ msgid "" +#~ "Component was expected to implement IInterfaceComponentReference for " +#~ "ValuesList support" +#~ msgstr "" +#~ "Es wurde erwartet, dass die Komponente zur Unterstützung von ValuesList " +#~ "IInterfaceComponentReference implementiert" +#~ msgid "Compression error" +#~ msgstr "Kompressionsfehler" +#~ msgid "Configuration file %s not found" +#~ msgstr "Konfigurationsdatei %s nicht gefunden" +#~ msgid "Confirm file deletion" +#~ msgstr "Bestätigung" +#~ msgid "Conflict" +#~ msgstr "Konflikt" +#~ msgid "Conflicting Value" +#~ msgstr "Widersprüchliche Werte" +#~ msgid "Connect timed out." +#~ msgstr "Zeitüberschreitung der Verbindung." +#~ msgid "Connected" +#~ msgstr "Verbunden" +#~ msgid "Connected." +#~ msgstr "Verbunden." +#~ msgid "Connecting" +#~ msgstr "Herstellen der Verbindung" +#~ msgid "Connecting to %s." +#~ msgstr "Verbinden mit %s." +#~ msgid "Connection" +#~ msgstr "Verbindung" +#~ msgid "Connection Closed Gracefully." +#~ msgstr "Die Verbindung wurde erfolgreich geschlossen." +#~ msgid "Connection established" +#~ msgstr "Verbindung hergestellt" +#~ msgid "Connection explicitly refused by NNTP server." +#~ msgstr "Die Verbindung wurde explizit vom NNTP-Server abgelehnt." +#~ msgid "Connection name missing" +#~ msgstr "Name der Verbindung fehlt" +#~ msgid "Connection not allowed by ruleset." +#~ msgstr "Die Verbindung wird von der Regelmenge nicht zugelassen." +#~ msgid "Connection not allowed to TConnectionBroker" +#~ msgstr "Verbindung für TConnectionBroker nicht gestattet" +#~ msgid "Connection refused." +#~ msgstr "Verbindung abgelehnt." +#~ msgid "Connection reset by peer." +#~ msgstr "Die Verbindung wurde von Peer zurückgesetzt." +#~ msgid "Connection timed out." +#~ msgstr "Zeitüberschreitung bei Verbindung." +#~ msgid "Content Length" +#~ msgstr "Inhaltslänge" +#~ msgid "Content-Length header not found" +#~ msgstr "Inhaltslängen-Header nicht gefunden" +#~ msgid "ContentModel not set" +#~ msgstr "ContentModel nicht gesetzt" +#~ msgid "Continue" +#~ msgstr "Fortsetzen" +#~ msgid "Continue delete operation?" +#~ msgstr "Soll der Löschvorgang fortgesetzt werden?" +#~ msgid "Control" +#~ msgstr "Element" +#~ msgid "Control '%s' has no parent widget" +#~ msgstr "Element '%s' besitzt kein übergeordnetes Widget" +#~ msgid "Control file save to %s" +#~ msgstr "Steuerungsdatei speichern in %s" +#~ msgid "Conversion family (%s) already registered" +#~ msgstr "Konvertierungsfamilie (%s) bereits registriert" +#~ msgid "" +#~ "Conversion from class %s to SOAP is not supported - SOAP classes must " +#~ "derive from TRemotable" +#~ msgstr "" +#~ "Die Konvertierung von Klasse %s zu SOAP wird nicht unterstützt - SOAP-" +#~ "Klassen müssen von TRemotable abgeleitet worden sein" +#~ msgid "Conversion type (%s) already registered in %s" +#~ msgstr "Konvertierungstyp (%s) bereits registriert in %s" +#~ msgid "Copy" +#~ msgstr "Kopieren" +#~ msgid "Copy Selection" +#~ msgstr "Liste" +#~ msgid "" +#~ "Copyright (c) 1993 - 2002\n" +#~ "Kudzu (Chad Z. Hower)\n" +#~ "and the\n" +#~ "Indy Pit Crew" +#~ msgstr "" +#~ "Copyright (c) 1993 - 2002\n" +#~ "Kudzu (Chad Z. Hower)\n" +#~ "und die\n" +#~ "Indy Boxen-Crew" +#~ msgid "Copy|Copies the selection and puts it on the Clipboard" +#~ msgstr "Kopieren|Markiertes Objekt in die Zwischenablage kopieren" +#~ msgid "CordFeet" +#~ msgstr "Klasterfuß" +#~ msgid "Cords" +#~ msgstr "Klaster" +#~ msgid "Correct" +#~ msgstr "Korrekt" +#~ msgid "Could not bind socket. Address and port are already in use." +#~ msgstr "" +#~ "Socket konnte nicht gebunden werden. Adresse und Port werden bereits " +#~ "benutzt." +#~ msgid "Could not convert variant of type (%s) into type (%s)" +#~ msgstr "Variante des Typs (%s) konnte nicht in Typ (%s) konvertiert werden" +#~ msgid "Could not create XMLDocument" +#~ msgstr "XML-Dokument konnte nicht erzeugt werden" +#~ msgid "Could not find server in ObjectManager list" +#~ msgstr "Der Server kann in der ObjectManager-Liste nicht gefunden werden" +#~ msgid "Could not load SSL library." +#~ msgstr "SSL.-Bibliothek konnte nicht geladen werden." +#~ msgid "Could not load certificate." +#~ msgstr "Zertifikat konnte nicht geladen werden." +#~ msgid "Could not load key, check password." +#~ msgstr "" +#~ "Der Schlüssel konnte nicht geladen werden; überprüfen Sie das Passwort." +#~ msgid "Could not load root certificate." +#~ msgstr "Stammzertifikat konnte nicht geladen werden." +#~ msgid "Could not open file " +#~ msgstr "Datei kann nicht geöffnet werden: " +#~ msgid "Could not parse %s" +#~ msgstr "%s konnte nicht analysiert werden" +#~ msgid "Could not parse SQL TimeStamp string" +#~ msgstr "SQL-TimeStamp-String konnte nicht analysiert werden" +#~ msgid "Could not parse imaginary portion" +#~ msgstr "Imaginärer Anteil konnte nicht analysiert werden" +#~ msgid "Could not parse real portion" +#~ msgstr "Realer Anteil konnte nicht analysiert werden" +#~ msgid "Could not parse required '%s' symbol" +#~ msgstr "Erforderliches '%s'-Symbol kann nicht analysiert werden" +#~ msgid "Could not parse required '+' (or '-') symbol" +#~ msgstr "Erforderliches '+' (oder '-') Symbol konnte nicht analysiert werden" +#~ msgid "" +#~ "Cr&op\n" +#~ "St&retch\n" +#~ "C&enter\n" +#~ msgstr "" +#~ "Cr&op\n" +#~ "St&retch\n" +#~ "C&enter\n" +#~ msgid "Cream" +#~ msgstr "Creme" +#~ msgid "Create new directory" +#~ msgstr "Neues Verzeichnis erstellen" +#~ msgid "Created" +#~ msgstr "Erstellt" +#~ msgid "Creates a WebSnap Application" +#~ msgstr "WebSnap-Anwendung erzeugen" +#~ msgid "Creates a WebSnap Data Module" +#~ msgstr "WebSnap-Datenmodul erzeugen" +#~ msgid "Creates a WebSnap Page Module" +#~ msgstr "WebSnap-Seitenmodul erzeugen" +#~ msgid "Critical: critical conditions" +#~ msgstr "Kritisch: Kritischer Zustand" +#~ msgid "CubicCentimeters" +#~ msgstr "Kubikzentimeter" +#~ msgid "CubicDecameters" +#~ msgstr "Kubikdekameter" +#~ msgid "CubicDecimeters" +#~ msgstr "Kubikdezimeter" +#~ msgid "CubicFeet" +#~ msgstr "Kubikfuß" +#~ msgid "CubicHectometers" +#~ msgstr "Kubikhektometer" +#~ msgid "CubicInches" +#~ msgstr "Kubikzoll" +#~ msgid "CubicKilometers" +#~ msgstr "Kubikkilometer" +#~ msgid "CubicMeters" +#~ msgstr "Kubikmeter" +#~ msgid "CubicMiles" +#~ msgstr "Kubikmeilen" +#~ msgid "CubicMillimeters" +#~ msgstr "Kubikmillimeter" +#~ msgid "CubicYards" +#~ msgstr "Kubik-Yard" +#~ msgid "Cubits" +#~ msgstr "Elle" +#~ msgid "Cursor not returned from Query" +#~ msgstr "Cursor nicht aus Abfrage zurückgekehrt" +#~ msgid "Custom message interpretation failed" +#~ msgstr "Individuelle Botschaftsinterpretation ist fehlgeschlagen" +#~ msgid "Custom variant type ($%.4x) already used by %s" +#~ msgstr "Benutzerdefinierter Variant-Typ ($%.4x) bereits benutzt von %s" +#~ msgid "Custom variant type ($%.4x) is not usable" +#~ msgstr "Benutzerdefinierter Variant-Typ ($%.4x) nicht brauchbar" +#~ msgid "Custom variant type ($%.4x) is out of range" +#~ msgstr "" +#~ "Benutzerdefinierter Variant-Typ ($%.4x) außerhalb des gültigen Bereichs" +#~ msgid "Custom variant type (%s%.4x) already used by %s" +#~ msgstr "Benutzerdefinierter Variant-Typ (%s%.4x) bereits benutzt von %s" +#~ msgid "Custom variant type (%s%.4x) is not usable" +#~ msgstr "Benutzerdefinierter Variant-Typ (%s%.4x) nicht brauchbar" +#~ msgid "Custom variant type (%s%.4x) is out of range" +#~ msgstr "" +#~ "Benutzerdefinierter Variant-Typ (%s%.4x) außerhalb des gültigen Bereichs" +#~ msgid "Custom..." +#~ msgstr "Individuell..." +#~ msgid "Customize" +#~ msgstr "Anpassen" +#~ msgid "Cut" +#~ msgstr "Ausschneiden" +#~ msgid "Cut|Cuts the selection and puts it on the Clipboard" +#~ msgstr "Ausschneiden|Markiertes Objekt in die Zwischenablage verschieben" +#~ msgid "DBX Error: Command not found, error message cannot be retrieved" +#~ msgstr "" +#~ "DBX-Fehler: Befehl nicht gefunden, Fehlermeldung kann nicht abgerufen " +#~ "werden" +#~ msgid "DBX Error: Connection not found, error message cannot be retrieved" +#~ msgstr "" +#~ "DBX-Fehler: Verbindung nicht gefunden, Fehlermeldung kann nicht abgerufen " +#~ "werden" +#~ msgid "DBX Error: Cursor not found, error message cannot be retrieved" +#~ msgstr "" +#~ "DBX-Fehler: Cursor nicht gefunden, Fehlermeldung kann nicht abgerufen " +#~ "werden" +#~ msgid "" +#~ "DBX Error: MetadataObject not found, error message cannot be retrieved" +#~ msgstr "" +#~ "DBX-Fehler: MetadataObject nicht gefunden, Fehlermeldung kann nicht " +#~ "abgerufen werden" +#~ msgid "DBX Error: No Mapping for Error Code Found" +#~ msgstr "DBX-Fehler: Keine Zuordnung des Fehlercodes gefunden" +#~ msgid "DLL/Shared Library Name not Set" +#~ msgstr "Name für DLL/Gemeinsame Bibliothek ist nicht gesetzt" +#~ msgid "DNS Server Reports Query Format Error" +#~ msgstr "Der DNS-Server meldet einen Fehler im Abfrageformat" +#~ msgid "DNS Server Reports Query Name Error" +#~ msgstr "Der DNS-Server meldet einen Fehler im Abfragenamen" +#~ msgid "DNS Server Reports Query Not Implemented Error" +#~ msgstr "" +#~ "Der DNS-Server meldet einen Fehler, dass die Abfrage nicht implementiert " +#~ "ist" +#~ msgid "DNS Server Reports Query Refused Error" +#~ msgstr "" +#~ "Der DNS-Server meldet einen Fehler, dass die Abfrage zurückgewiesen wurde" +#~ msgid "DNS Server Reports Query Server Error" +#~ msgstr "Der DNS-Server meldet einen Fehler beim Abfrage-Server" +#~ msgid "DOM Error: " +#~ msgstr "DOM-Fehler: " +#~ msgid "DOM Implementation does not support IDOMParseOptions" +#~ msgstr "DOM-Implementation unterstützt nicht IDOMParseOptions" +#~ msgid "DPB Constant (%s) is unknown" +#~ msgstr "DPB-Konstante (%s) ist unbekannt." +#~ msgid "DTD to XML Schema Translator (.dtd <-> .xsd)" +#~ msgstr "Übersetzer DTD nach XML-Schema (.dtd <-> .xsd)" +#~ msgid "Data Access" +#~ msgstr "Datenzugriff" +#~ msgid "Data Modification is not permitted" +#~ msgstr "Datenmodifikation ist nicht zulässig" +#~ msgid "Data Packet" +#~ msgstr "Datenpaket" +#~ msgid "Data connection already open; transfer starting." +#~ msgstr "Datenverbindung besteht bereits; Transfer wird gestartet." +#~ msgid "Data connection closed abnormally." +#~ msgstr "Datenverbindung wurde abnormal geschlossen." +#~ msgid "Data connection open; no transfer in progress." +#~ msgstr "Datenverbindung besteht bereits; kein Transfer läuft." +#~ msgid "Data file saved to %s" +#~ msgstr "Datendatei gespeichert in %s" +#~ msgid "DataSet is nil" +#~ msgstr "DataSet ist nil" +#~ msgid "Database Files|*.gdb" +#~ msgstr "Datenbankdateien|*.gdb" +#~ msgid "Database Parameters" +#~ msgstr "Datenbank-Parameter" +#~ msgid "" +#~ "Datatype of TypeKind: %s not supported as argument for remote invocation" +#~ msgstr "" +#~ "Datentyp von TypeKind: %s wird als Argument für Remote-Aufruf nicht " +#~ "unterstützt" +#~ msgid "Date" +#~ msgstr "Datum" +#~ msgid "Date Modified" +#~ msgstr "Datum geändert" +#~ msgid "DateTime" +#~ msgstr "Datum/Uhrzeit" +#~ msgid "Days" +#~ msgstr "Tag" +#~ msgid "De&lete" +#~ msgstr "&Löschen" +#~ msgid "Debug: debug-level messages" +#~ msgstr "Debug: debug-level-Botschaften" +#~ msgid "DecaLiters" +#~ msgstr "Dekaliter" +#~ msgid "Decades" +#~ msgstr "Dekade" +#~ msgid "Decagrams" +#~ msgstr "Dekagramm" +#~ msgid "Decameters" +#~ msgstr "Dekameter" +#~ msgid "Decasteres" +#~ msgstr "Dekaster" +#~ msgid "DeciLiters" +#~ msgstr "Deziliter" +#~ msgid "Decigrams" +#~ msgstr "Dezigramm" +#~ msgid "Decimeters" +#~ msgstr "Dezimeter" +#~ msgid "Decisteres" +#~ msgstr "Dezister" +#~ msgid "Decompression error" +#~ msgstr "Dekompressionsfehler" +#~ msgid "Default URL:" +#~ msgstr "Standard-URL:" +#~ msgid "Delete" +#~ msgstr "Löschen" +#~ msgid "Delete Selection" +#~ msgstr "Liste" +#~ msgid "Delete existing components?" +#~ msgstr "Existierende Komponenten löschen?" +#~ msgid "Deleted" +#~ msgstr "Gelöscht" +#~ msgid "Delete|Erases the selection" +#~ msgstr "Löschen|Auswahl löschen" +#~ msgid "Delimiter and QuoteChar properties cannot have the same value" +#~ msgstr "" +#~ "Die Eigenschaften Delimiter und QuoteChar dürfen nicht denselben Wert " +#~ "besitzen" +#~ msgid "DelphiException %s" +#~ msgstr "DelphiException %s" +#~ msgid "Demos Coordinator" +#~ msgstr "Demos-Koordinator" +#~ msgid "Description" +#~ msgstr "Beschreibung" +#~ msgid "Destination address required." +#~ msgstr "Zieladresse erforderlich." +#~ msgid "Destination file already exists." +#~ msgstr "Die Zieldatei existiert bereits." +#~ msgid "DestinationDirectory is not set" +#~ msgstr "DestinationDirectory nicht gesetzt" +#~ msgid "Detaul view" +#~ msgstr "Detailansicht" +#~ msgid "Dialog" +#~ msgstr "Dialog" +#~ msgid "Direction" +#~ msgstr "Richtung" +#~ msgid "Directory" +#~ msgstr "Verzeichnis" +#~ msgid "Directory \"%s\" is not empty." +#~ msgstr "Verzeichnis \"%s\" ist nicht leer." +#~ msgid "Directory %s does not exist" +#~ msgstr "Verzeichnis %s ist nicht vorhanden" +#~ msgid "Directory not empty" +#~ msgstr "Verzeichnis ist nicht leer" +#~ msgid "Disconnect" +#~ msgstr "Verbindung trennen" +#~ msgid "Disconnected." +#~ msgstr "Verbindung aufgehoben." +#~ msgid "Disconnecting." +#~ msgstr "Verbindung wird getrennt." +#~ msgid "Disk Quota Exceeded." +#~ msgstr "Festplattenkontingent überschritten." +#~ msgid "Dispatch methods do not support more than 64 parameters" +#~ msgstr "Dispatch-Methoden unterstützen maximal 64 Parameter." +#~ msgid "Dispatching blank page name" +#~ msgstr "Weiterleiten eines leeren Seitennamens" +#~ msgid "Distance" +#~ msgstr "Entfernung" +#~ msgid "Distribution Coordinator" +#~ msgstr "Distributions-Koordinator" +#~ msgid "Do AcquireCredentialsHandle first" +#~ msgstr "Erst AcquireCredentialsHandle" +#~ msgid "Do not allow connctions now" +#~ msgstr "Verbindungen jetzt nicht zulassen" +#~ msgid "DocumentElement %s:%s expected, %s:%s found" +#~ msgstr "Dokumentelement %s:%s erwartet, %s:%s gefunden" +#~ msgid "Documentation" +#~ msgstr "Dokumentation" +#~ msgid "Documentation Coordinator" +#~ msgstr "Dokumentationskoordinator" +#~ msgid "Double parameter expected" +#~ msgstr "Doppelparameter erwartet" +#~ msgid "Download from URL" +#~ msgstr "Internet" +#~ msgid "Drag and Drop" +#~ msgstr "Drag und Drop" +#~ msgid "Drag to create Separators" +#~ msgstr "Ziehen für das Erstellen von Separatoren" +#~ msgid "Drams" +#~ msgstr "Drachme" +#~ msgid "Drawings" +#~ msgstr "Zeichnungen" +#~ msgid "" +#~ "Drive %s does not exist.\n" +#~ "Please verify the correct drive was given." +#~ msgstr "" +#~ "Laufwerk %s existiert nicht.\n" +#~ "Überprüfen Sie, ob das richtige Laufwerkangegeben wurde." +#~ msgid "Driver (%s) not found in Cfg file (%s)" +#~ msgstr "Treiber (%s) in der CFG-Datei (%s) nicht gefunden" +#~ msgid "Driver/Connection Registry File '%s' not found" +#~ msgstr "Registrierungsdatei '%s' für Treiber/Verbindung nicht gefunden" +#~ msgid "DryBuckets" +#~ msgstr "DryBuckets" +#~ msgid "DryBushels" +#~ msgstr "Scheffel (Trockenmaß)" +#~ msgid "DryGallons" +#~ msgstr "Gallone (Trockenmaß)" +#~ msgid "DryPecks" +#~ msgstr "Viertelscheffel (Trockenmaß)" +#~ msgid "DryPints" +#~ msgstr "Pinte (Trockenmaß)" +#~ msgid "DryQuarts" +#~ msgstr "Quart (Trockenmaß)" +#~ msgid "Duplication prototype name" +#~ msgstr "Doppelter Prototypname" +#~ msgid "E&xit" +#~ msgstr "&Beenden" +#~ msgid "E&xport..." +#~ msgstr "E&xportieren..." +#~ msgid "ERROR" +#~ msgstr "FEHLER" +#~ msgid "Edit" +#~ msgstr "Bearbeiten" +#~ msgid "Edit SQL" +#~ msgstr "SQL bearbeiten" +#~ msgid "Editing %s%s%s" +#~ msgstr "%s%s%s wird bearbeitet" +#~ msgid "Elapsed" +#~ msgstr "Vergangen" +#~ msgid "Element does not contain a single text node" +#~ msgstr "Element enthält keinen einzelnen Textknoten" +#~ msgid "Element of Array type %s has no RTTI" +#~ msgstr "Element des Array-Typs %s hat kein RTTI" +#~ msgid "Emergency: system is unusable" +#~ msgstr "Notfall: System ist unbrauchbar" +#~ msgid "Empty document" +#~ msgstr "Leeres Dokument" +#~ msgid "Encoding attachment" +#~ msgstr "Anlage wird codiert" +#~ msgid "Encoding text" +#~ msgstr "Text wird codiert" +#~ msgid "End of Status" +#~ msgstr "Ende des Status" +#~ msgid "Enter password" +#~ msgstr "Passwort eingeben" +#~ msgid "Entering Passive Mode (%s)." +#~ msgstr "Gehe in Passiv-Modus (%s)." +#~ msgid "Error Loading XML" +#~ msgstr "Fehler beim Laden von XML" +#~ msgid "Error Processing Header (%s)%s" +#~ msgstr "Fehler beim Verarbeiten von Header (%s)%s" +#~ msgid "Error accepting connection with SSL." +#~ msgstr "Fehler beim Akzeptieren der Verbindung mit SSL." +#~ msgid "Error binding data to SSL socket." +#~ msgstr "Fehler beim Binden der Daten an den SSL-Socket.." +#~ msgid "Error connecting with SSL." +#~ msgstr "Fehler bei Verbinden mit SSL." +#~ msgid "Error creating SSL context." +#~ msgstr "Fehler beim Anlegen eines SSL-Kontexts." +#~ msgid "Error creating file \"%s\"" +#~ msgstr "Fehler beim Erzeugen von Datei %s" +#~ msgid "Error creating variant or safe array" +#~ msgstr "Fehler beim Erzeugen von Variante oder sicherem Array" +#~ msgid "Error creating widget" +#~ msgstr "Fehler beim Erzeugen von Widget" +#~ msgid "Error decoding URL style (%%XX) encoded string at position %d" +#~ msgstr "" +#~ "Fehler beim Decodieren eines im URL-Stil (%%XX) codierten Strings bei " +#~ "Position %d" +#~ msgid "Error downloading URL: %s" +#~ msgstr "Fehler beim Download von URL: %s" +#~ msgid "Error geting SSL method." +#~ msgstr "Fehler beim Einlesen einer SSL-Methode." +#~ msgid "Error in parsing command." +#~ msgstr "Fehler bei der Analyse einer Anweisung." +#~ msgid "Error in transformation before send" +#~ msgstr "Fehler bei der Transformation vor dem Senden" +#~ msgid "Error loading library \"%s\": \"%s\"" +#~ msgstr "Fehler beim Laden der Bibliothek \"%s\": \"%s\"" +#~ msgid "" +#~ "Error loading previously saved settings file: %sWould you like to delete " +#~ "it?" +#~ msgstr "" +#~ "Fehler beim Laden der zuvor gespeicherten Einstellungsdatei: %sSoll die " +#~ "Datei gelöscht werden?" +#~ msgid "Error on call Winsock2 library function %s" +#~ msgstr "Fehler beim Aufruf einer Winsock2-Bibliotheksfunktion %s" +#~ msgid "Error on line %d, position %d" +#~ msgstr "Fehler in Zeile %d, Position %d" +#~ msgid "Error on loading Winsock2 library (%s)" +#~ msgstr "Fehler beim Laden einer Winsock2-Bibliothek (%s)" +#~ msgid "Error opening file" +#~ msgstr "Fehler beim Öffnen von Datei" +#~ msgid "Error reading from Mime Request Stream" +#~ msgstr "Fehler beim Lesen von Mime-Anforderungs-Stream" +#~ msgid "Error resizing ImageList" +#~ msgstr "Fehler bei der Größenänderung der ImageList" +#~ msgid "Error saving attachment." +#~ msgstr "Fehler beim Speichern der Anlage." +#~ msgid "Error saving file" +#~ msgstr "Fehler beim Speichern von Datei" +#~ msgid "Error sending mail" +#~ msgstr "Fehler beim Versenden von Mail" +#~ msgid "Error setting %s.Count" +#~ msgstr "Fehler beim Setzen von %s.Count" +#~ msgid "Error setting path: \"%s\"" +#~ msgstr "Fehler beim Festlegen des Pfades: \"%s\"" +#~ msgid "Error setting stream size" +#~ msgstr "Fehler beim Setzen der Größe des Stream" +#~ msgid "Error: " +#~ msgstr "Fehler: " +#~ msgid "Error: No program code to return request!" +#~ msgstr "Fehler: Kein Programm-Code, um die Anforderung zurückzugeben!" +#~ msgid "Error: error conditions" +#~ msgstr "Fehler: Fehlerzustand" +#~ msgid "Error: no queues defined" +#~ msgstr "Fehler: Keine Warteschlange definiert" +#~ msgid "Errors object must support the interface IIterateIntfSupport" +#~ msgstr "Fehlerobjekte müssen das Interface IIterateIntfSupport unterstützen" +#~ msgid "Event" +#~ msgstr "Ereignis" +#~ msgid "Events already registered" +#~ msgstr "Ereignisse bereits registriert" +#~ msgid "Exception in InterpretData: %s" +#~ msgstr "Exception in InterpretData: %s" +#~ msgid "Execution of action %s is not permitted" +#~ msgstr "Ausführung der Aktion %s ist nicht zulässig" +#~ msgid "Exit|Quits the application" +#~ msgstr "Beenden|Anwendung beenden" +#~ msgid "Expand" +#~ msgstr "Einblenden" +#~ msgid "Export Images" +#~ msgstr "Bilder exportieren" +#~ msgid "Extension already exits" +#~ msgstr "Erweiterung existiert bereits" +#~ msgid "Extension is empty" +#~ msgstr "Erweiterung ist leer" +#~ msgid "" +#~ "Extensions supported:\n" +#~ "SIZE\n" +#~ "PASV\n" +#~ "REST\n" +#~ "End of extentions." +#~ msgstr "" +#~ "Unterstützte Erweiterungen:\n" +#~ "SIZE\n" +#~ "PASV\n" +#~ "REST\n" +#~ "Ende der Erweiterungen." +#~ msgid "Extra Headers Text Editor" +#~ msgstr "Texteditor für Extra-Header" +#~ msgid "F&ind First" +#~ msgstr "&Ersten suchen" +#~ msgid "FTP daemon" +#~ msgstr "FTP-Daemon" +#~ msgid "Facets and Enumeration not allowed on this kind of datatype \"%s\"" +#~ msgstr "Facetten und Enumeration für diesen Datentyp \"%s\" nicht zulässig" +#~ msgid "Fahrenheit" +#~ msgstr "Fahrenheit" +#~ msgid "Failed attempting to retrieve time zone information." +#~ msgstr "" +#~ "Das Einlesen der Informationen über die Zeitzone ist fehlgeschlagen." +#~ msgid "Failed to Start: %s" +#~ msgstr "Start fehlgeschlagen: %s" +#~ msgid "Failed to Stop: %s" +#~ msgstr "Anhalten fehlgeschlagen: %s" +#~ msgid "" +#~ "Fatal error: Cannot create application object in a shared object or " +#~ "library." +#~ msgstr "" +#~ "Fataler Fehler: Ein Anwendungsobjekt kann nicht in einem Shared Object " +#~ "oder einer Bibliothek erzeugt werden." +#~ msgid "Fatal error: Cannot create more than one TApplication instance" +#~ msgstr "" +#~ "Fataler Fehler: Mehr als eine Instanz von TApplication kann nicht erzeugt " +#~ "werden" +#~ msgid "Fathoms" +#~ msgstr "Faden" +#~ msgid "Feet" +#~ msgstr "Fuß" +#~ msgid "Fetch &Params" +#~ msgstr "&Parameter holen" +#~ msgid "Fi&nd what:" +#~ msgstr "&Suchen nach:" +#~ msgid "Field %s changed by another user" +#~ msgstr "Feld %s wurde von einem anderen Benutzer geändert" +#~ msgid "Field %s did not provide an image" +#~ msgstr "Feld %s enthielt kein Bild" +#~ msgid "Field %s requires a value" +#~ msgstr "Für Feld %s ist ein Wert erforderlich" +#~ msgid "Field not found: %s" +#~ msgstr "Feld nicht gefunden: %s" +#~ msgid "Field view not permitted" +#~ msgstr "Feldansicht nicht zulässig" +#~ msgid "Fieldname %s exceeds %d chars" +#~ msgstr "Feldname %s überschreitet %d Zeichen" +#~ msgid "File" +#~ msgstr "Datei" +#~ msgid "File \"%s\" not found" +#~ msgstr "Datei \"%s\" konnte nicht gefunden werden" +#~ msgid "File Status:" +#~ msgstr "Dateistatus:" +#~ msgid "File Type:" +#~ msgstr "Dateityp:" +#~ msgid "File include error on line %d: expecting \"" +#~ msgstr "include-Dateifehler auf Zeile %d: erwartet \"" +#~ msgid "File include error on line %d: expecting =" +#~ msgstr "include-Dateifehler auf Zeile %d: erwartet =" +#~ msgid "" +#~ "File include error on line %d: expecting virtual, file, or page, but " +#~ "found %s." +#~ msgstr "" +#~ "include-Dateifehler auf Zeile %d: erwaret virtual, Datei, oder Seite, " +#~ "aber %s gefunden." +#~ msgid "File name too long." +#~ msgstr "Dateiname ist zu lang." +#~ msgid "File status okay; about to open data connection." +#~ msgstr "Dateistatus OK; Datenverbindung wird geöffnet." +#~ msgid "FileName cannot be blank" +#~ msgstr "FileName muss angegeben werden" +#~ msgid "FileName property cannot be blank" +#~ msgstr "Eigenschaft FileName darf nicht leer sein" +#~ msgid "Filename(s)" +#~ msgstr "Dateiname(n)" +#~ msgid "Find" +#~ msgstr "Suchen" +#~ msgid "Find &Next" +#~ msgstr "&Weitersuchen" +#~ msgid "Find First|Finds the first occurance of specified text" +#~ msgstr "Suchen" +#~ msgid "Find Next|Repeats the last find" +#~ msgstr "Weitersuchen|Letzte Suche wiederholen" +#~ msgid "Find|Finds the specified text" +#~ msgstr "Suchen|Angegebenen Text suchen" +#~ msgid "FluidCups" +#~ msgstr "Tasse (Flüssigkeit)" +#~ msgid "FluidGallons" +#~ msgstr "Gallone (Flüssigkeit)" +#~ msgid "FluidGills" +#~ msgstr "Gill (Flüssigkeit)" +#~ msgid "FluidOunces" +#~ msgstr "Unze (Flüssigkeit)" +#~ msgid "FluidPints" +#~ msgstr "Pinte (Flüssigkeit)" +#~ msgid "FluidQuarts" +#~ msgstr "Quart (Flüssigkeit)" +#~ msgid "FluidTablespoons" +#~ msgstr "Esslöffel (Flüssigkeit)" +#~ msgid "FluidTeaspoons" +#~ msgstr "Teelöffel (Flüssigkeit)" +#~ msgid "Font Select" +#~ msgstr "MS Sans Serif" +#~ msgid "For the latest updates and information please visit:" +#~ msgstr "Die neuesten Aktualisierungen und Informationen finden Sie unter:" +#~ msgid "Forbidden" +#~ msgstr "Verboten" +#~ msgid "Format" +#~ msgstr "Format" +#~ msgid "Fortnights" +#~ msgstr "Vierzehn Tage" +#~ msgid "Forward" +#~ msgstr "Weiter" +#~ msgid "Found" +#~ msgstr "Gefunden" +#~ msgid "Free Space" +#~ msgstr "Freier Speicherplatz" +#~ msgid "Fuchsia" +#~ msgstr "Fuchsie" +#~ msgid "Furlongs" +#~ msgstr "Achtelmeile" +#~ msgid "Gateway timeout" +#~ msgstr "Zeitüberschreitung bei Gateway" +#~ msgid "General SOCKS server failure." +#~ msgstr "Allgemeiner SOCKS-Serverausfall." +#~ msgid "Getting the Count of a TComponentsEnumerator object is not supported" +#~ msgstr "" +#~ "Das Lesen von Count eines TComponentsEnumerator-Objekts wiurd nicht " +#~ "unterstützt" +#~ msgid "Gigameters" +#~ msgstr "Gigameter" +#~ msgid "Global scheam items may not contain a ref" +#~ msgstr "Globale Schemaelemente dürfen keine Verweise enthalten" +#~ msgid "Go" +#~ msgstr "Start" +#~ msgid "Gone" +#~ msgstr "Fort" +#~ msgid "Goodbye" +#~ msgstr "Auf Wiedersehen" +#~ msgid "Gradient Active Caption" +#~ msgstr "Gradient aktiver Titel" +#~ msgid "Gradient Inactive Caption" +#~ msgstr "Gradient inaktiver Titel" +#~ msgid "Grains" +#~ msgstr "Gran" +#~ msgid "Grams" +#~ msgstr "Gramm" +#~ msgid "Gray" +#~ msgstr "Grau" +#~ msgid "Gray Text" +#~ msgstr "Grauer Text" +#~ msgid "Green" +#~ msgstr "Grün" +#~ msgid "Group" +#~ msgstr "Gruppe" +#~ msgid "HTTP version not supported" +#~ msgstr "HTTP-Version nicht unterstützt" +#~ msgid "Hands" +#~ msgstr "Handbreite" +#~ msgid "Header Section owner must be a TCustomHeaderControl" +#~ msgstr "" +#~ "Der Besitzer des Header-Abschnitts muss ein TCustomHeaderControl sein" +#~ msgid "Header has already been written." +#~ msgstr "Der Header wurde bereits geschrieben." +#~ msgid "Hectares" +#~ msgstr "Hektoar" +#~ msgid "HectoLiters" +#~ msgstr "Hektoliter" +#~ msgid "Hectograms" +#~ msgstr "Hektogramm" +#~ msgid "Hectometers" +#~ msgstr "Hektometer" +#~ msgid "Hello %s" +#~ msgstr "Hallo %s" +#~ msgid "Help Contents" +#~ msgstr "Inhalt der Hilfe" +#~ msgid "Help on help" +#~ msgstr "Verwendung der Hilfe" +#~ msgid "Hidden User: Information was not returned at a user's request" +#~ msgstr "" +#~ "Verborgener Benutzer: Information wurde nicht auf Anforderung des " +#~ "Benutzers zurückgeschickt" +#~ msgid "Highlight Background" +#~ msgstr "Hervorgehobener Hintergrund" +#~ msgid "Highlight Text" +#~ msgstr "Hervorgehobener Text" +#~ msgid "Ho&me" +#~ msgstr "&Start" +#~ msgid "Home directory" +#~ msgstr "Startverzeichnis" +#~ msgid "Host field is empty" +#~ msgstr "Host-Feld ist leer" +#~ msgid "Host is down." +#~ msgstr "Der Host ist ausgefallen." +#~ msgid "Host is empty" +#~ msgstr "Host ist leer" +#~ msgid "Host not found." +#~ msgstr "Host nicht gefunden." +#~ msgid "Host unreachable." +#~ msgstr "Host nicht erreichbar." +#~ msgid "Hour Offset portion of time invalid" +#~ msgstr "Der Stunden-Offset des Zeitwertes ist ungültig" +#~ msgid "Hours" +#~ msgstr "Stunde" +#~ msgid "Html files (*.htm *.html)|*.htm;*.html" +#~ msgstr "Html-Dateien (*.htm;*.html)|*.htm;*.html" +#~ msgid "Html files (*.htm;*.html)|*.htm;*.html" +#~ msgstr "Html-Dateien (*.htm;*.html)|*.htm;*.html" +#~ msgid "I&mage Index:" +#~ msgstr "Bild-Inde&x:" +#~ msgid "ICMP Receive Error = 0." +#~ msgstr "ICMP Receive Error = 0." +#~ msgid "IDOMNode required" +#~ msgstr "IDOMNode erforderlich" +#~ msgid "IOHandler value is not valid" +#~ msgstr "Wert für IOHandler ist ungültig" +#~ msgid "IRC Connect Failed" +#~ msgstr "IRC-Verbindung fehlgeschlagen" +#~ msgid "IconView Items Editor" +#~ msgstr "IconView-Eintragseditor" +#~ msgid "Illegal family" +#~ msgstr "Ungültige Familie" +#~ msgid "Illegal type" +#~ msgstr "Ungültiger Typ" +#~ msgid "Ima&ge Index:" +#~ msgstr "&Bildindex:" +#~ msgid "Image format not recognized" +#~ msgstr "Das Grafikformat wurde nicht erkannt" +#~ msgid "Image width and heigth must match" +#~ msgstr "Die Höhe muss mit der Breite der Grafik übereinstimmen" +#~ msgid "ImageList Editor" +#~ msgstr "Bilderlisteneditor" +#~ msgid "Inactive Border" +#~ msgstr "Inaktiver Rahmen" +#~ msgid "Inactive Caption" +#~ msgstr "Inaktiver Titel" +#~ msgid "Inactive Caption Text" +#~ msgstr "Inaktiver Titeltext" +#~ msgid "Inches" +#~ msgstr "Zoll" +#~ msgid "Include file %s includes itself" +#~ msgstr "Include-Datei %s verweist auf sich selbst" +#~ msgid "Incompatible conversion types [%s - %s, %s - %s]" +#~ msgstr "Inkompatible Konvertierungstypen [%s - %s, %s - %s]" +#~ msgid "Incompatible conversion types [%s, %s, %s]" +#~ msgstr "Inkompatible Konvertierungstypen [%s, %s, %s]" +#~ msgid "Incompatible conversion types [%s, %s]" +#~ msgstr "Inkompatible Konvertierungstypen [%s, %s]" +#~ msgid "Incorrect image format (%0:s) for field %1:s" +#~ msgstr "Falsches Image-Format (%0:s) für Feld %1:s" +#~ msgid "Incorrect length in received block" +#~ msgstr "Falsche Länge in empfangenem Block" +#~ msgid "Increment By" +#~ msgstr "Erhöhen um" +#~ msgid "Indy Clients" +#~ msgstr "Indy-Clients" +#~ msgid "Indy FTP Server ready." +#~ msgstr "Indy FTP-Server bereit." +#~ msgid "Indy I/O Handlers" +#~ msgstr "Indy-I/O-Handler" +#~ msgid "Indy Intercepts" +#~ msgstr "Indy-Intercepts" +#~ msgid "Indy Misc" +#~ msgstr "Indy-Misc" +#~ msgid "Indy SMTP Server" +#~ msgstr "Indy SMTP-Server" +#~ msgid "Indy Servers" +#~ msgstr "Indy-Server" +#~ msgid "Indy Telnet Server" +#~ msgstr "Indy Telnet-Server" +#~ msgid "Info Background" +#~ msgstr "Info-Hintergrund" +#~ msgid "Info Text" +#~ msgstr "Info-Text" +#~ msgid "Informational: informational messages" +#~ msgstr "Informational: Informationsbotschaften" +#~ msgid "" +#~ "Initialization of script debugger failed. Verify that a script debugger " +#~ "is installed" +#~ msgstr "" +#~ "Initialisierung des Script-Debugger ist misslungen. Überprüfen Sie, ob " +#~ "ein Script-Debugger installiert ist." +#~ msgid "Inserted" +#~ msgstr "Eingefügt" +#~ msgid "Insufficient data for Content-Length" +#~ msgstr "Nicht ausreichnede Daten für Inhaltslänge" +#~ msgid "Integer parameter expected" +#~ msgstr "Integer-Parameter erwartet" +#~ msgid "" +#~ "InterBase library gds.so.0 not found in the path. Please install " +#~ "InterBase to use this functionality" +#~ msgstr "" +#~ "InterBase-Bibliothek gds.so.0 im Pfad nicht gefunden. Bitte installieren " +#~ "Sie InterBase für diese Funktion" +#~ msgid "InterbaseExpress %g" +#~ msgstr "InterbaseExpress %g" +#~ msgid "InterbaseExpress 4.3" +#~ msgstr "InterbaseExpress 4.3" +#~ msgid "InterceptEnabled cannot be set to true when Intercept is nil." +#~ msgstr "" +#~ "InterceptEnabled darf nicht auf true gesetzt sein, wenn Intercept nil ist." +#~ msgid "Interface %s has no RTTI" +#~ msgstr "Schnittstelle %s hat kein RTTI" +#~ msgid "" +#~ "Interface (%s) canno be remoted - please verify the interface declaration " +#~ "- specially the methods calling convention!" +#~ msgstr "" +#~ "Interface (%s) kann nicht ausgelagert werden - überprüfen Sie die " +#~ "Interface-Deklaration - speziell die Aufrufkonventionen der Methoden!" +#~ msgid "" +#~ "Interface (%s) is not registered - please include the unit that registers " +#~ "this interface to your project" +#~ msgstr "" +#~ "Interface (%s) ist nicht registriert - fügen Sie die Unit, die dieses " +#~ "Interface registriert, in Ihr Projekt ein" +#~ msgid "Interface has no RTTI, UUID = %s" +#~ msgstr "Schnittstelle hat kein RTTI, UUID = %s" +#~ msgid "Interface is unusable due to failure to stop" +#~ msgstr "Interface ist unbrauchbar, da es nicht angehalten werden kann" +#~ msgid "Interface not registered, UUID = %s" +#~ msgstr "Schnittstelle nicht registriert, UUID = %s" +#~ msgid "Interface was already started" +#~ msgstr "Interface wurde bereits gestartet" +#~ msgid "Interface was already stopped" +#~ msgstr "Interface wurde bereits angehalten" +#~ msgid "Internal Server Error" +#~ msgstr "Interner Server-Fehler" +#~ msgid "Internal error: data type kind %s not expected in this context" +#~ msgstr "Interner Fehler: Datentyp %s in diesem Kontext nicht erwartet" +#~ msgid "Internet" +#~ msgstr "Internet" +#~ msgid "Internet Direct (Indy)" +#~ msgstr "Internet Direct (Indy)" +#~ msgid "Interpretation of message failed" +#~ msgstr "Die Interpretation der Botschaft ist nicht gelungen" +#~ msgid "Interrupted system call." +#~ msgstr "Unterbrochener Systemaufruf." +#~ msgid "Invalid %s value: \"%s\"" +#~ msgstr "Ungültiger %s-Wert: \"%s\"" +#~ msgid "Invalid Action %d" +#~ msgstr "Ungültige Aktion %d" +#~ msgid "Invalid Bcd Precision (%d) or Scale (%d)" +#~ msgstr "Ungültige Bcd-Genauigkeit (%d) oder -Skalierung (%d)" +#~ msgid "" +#~ "Invalid Colormap this ActionBand requires ColorMaps of type " +#~ "TCustomActionBarColorMapEx" +#~ msgstr "" +#~ "Ungültige Colormap. Dieses ActionBand benötigt ColorMaps des Typ " +#~ "TCustomActionBarColorMapEx" +#~ msgid "Invalid DOMString size" +#~ msgstr "Fehler bei DOMString-Größe" +#~ msgid "Invalid DispID for parameter %d in method %s" +#~ msgstr "Ungültige DispID für Parameter %d in Methode %s" +#~ msgid "Invalid Encoding. UU only allows Body and Attachments" +#~ msgstr "Ungültige Codierung. UU gestattet nur Rumpf und Anlage" +#~ msgid "Invalid HTML encoded character (%s) at position %d" +#~ msgstr "Ungültiges HTML-codiertes Zeichen (%s) an Position %d" +#~ msgid "Invalid HTTP Request: Length is 0" +#~ msgstr "Ungültige HTTP-Anforderung: Länge ist 0" +#~ msgid "Invalid HTTP Response: Length is 0" +#~ msgstr "Ungültige HTTP-Antwort: Länge ist 0" +#~ msgid "Invalid Header Id %d" +#~ msgstr "Ungültige Header-Id %d" +#~ msgid "Invalid LCDNumber value" +#~ msgstr "Ungültiger Wert für LCDNumber" +#~ msgid "Invalid Login." +#~ msgstr "Ungültige Anmeldung." +#~ msgid "Invalid MDIParent for class %s" +#~ msgstr "Ungültiger MDIParent für Klasse %s" +#~ msgid "Invalid NULL variant operation" +#~ msgstr "Ungültige NULL-Variant-Operation" +#~ msgid "Invalid Packet Size %d" +#~ msgstr "Ungültige Paketgröße %d" +#~ msgid "Invalid Pointer" +#~ msgstr "Ungültiger Zeiger" +#~ msgid "Invalid Port Range (%d - %d)" +#~ msgstr "Ungültiger Port-Bereich (%d - %d)" +#~ msgid "" +#~ "Invalid Port: The foreign or local port is not specified correctly or " +#~ "invalid" +#~ msgstr "" +#~ "Ungültiger Port: Der fremde oder lokale Port ist nicht korrekt angegeben " +#~ "oder ungültig" +#~ msgid "Invalid Query Count %d" +#~ msgstr "Ungültige Abfragezahl %d" +#~ msgid "Invalid SOAP Response" +#~ msgstr "Ungültige SOAP-Antwort" +#~ msgid "Invalid SOAP array specification" +#~ msgstr "Ungültige SOAP-Array-Festlegung" +#~ msgid "Invalid SOAP request" +#~ msgstr "Ungültige SOAP-Anforderung" +#~ msgid "Invalid SOAP response" +#~ msgstr "Ungültige SOAP-Antwort" +#~ msgid "Invalid SQL date/time values" +#~ msgstr "Ungültige SQL-Datums-/Uhrzeitwerte" +#~ msgid "Invalid Syslog message: packet too large (%d bytes)" +#~ msgstr "Ungültige syslog-Botschaft: Paket zu groß (%d Byte)" +#~ msgid "Invalid Text count. TIdText must be greater than 1" +#~ msgstr "Ungültige Anzahl für Text. TIdText muss größer als 1 sein" +#~ msgid "Invalid URL encoded character (%s) at position %d" +#~ msgstr "Ungültiger URL-codiertes Zeichen (%s) bei Position %d" +#~ msgid "" +#~ "Invalid WSDL document '%s' - Please verify the location and content!\n" +#~ "Error: %s" +#~ msgstr "" +#~ "Ungültiges WSDL-Dokument '%s' - Bitte überprüfen Sie Speicherort und " +#~ "Inhalt!\n" +#~ "Fehler: %s" +#~ msgid "Invalid XImage" +#~ msgstr "Ungültiges XImage" +#~ msgid "Invalid access" +#~ msgstr "Ungültiger Zugriff" +#~ msgid "Invalid argument" +#~ msgstr "Ungültiges Argument" +#~ msgid "Invalid argument." +#~ msgstr "Ungültiges Argument." +#~ msgid "Invalid built-in type name \"%s\"" +#~ msgstr "Ungültiger Name für integrierten Typ \"%s\"" +#~ msgid "Invalid canvas state request" +#~ msgstr "Ungültige Status-Anforderung für Canvas" +#~ msgid "Invalid character in name" +#~ msgstr "Ungültiges Zeichen im Namen" +#~ msgid "Invalid complex type derivation: %s" +#~ msgstr "Ungültige Ableitung des komplexen Typs: %s" +#~ msgid "Invalid date string: %s" +#~ msgstr "Ungültiger Datums-String: %s" +#~ msgid "Invalid day: %d" +#~ msgstr "Ungültiger Tag: %d" +#~ msgid "Invalid decimal string: ''%s''" +#~ msgstr "Ungültiger Dezimal-String: ''%s''" +#~ msgid "Invalid duration string: %s" +#~ msgstr "Ungültiger Zeitdauer-String: %s" +#~ msgid "Invalid format type for BCD" +#~ msgstr "Ungültiger Formattyp für BCD" +#~ msgid "Invalid fractional second: %f" +#~ msgstr "Ungültiger Sekundenbruchteil: %f" +#~ msgid "Invalid graphic format" +#~ msgstr "Ungültiges Grafikformat" +#~ msgid "Invalid group declaration in \"%s\"" +#~ msgstr "Ungültige Gruppendeklaration in \"%s\"" +#~ msgid "Invalid handle value for %s" +#~ msgstr "Ungültiger Handle-Wert für %s" +#~ msgid "" +#~ "Invalid host name. A SYSLOG host name cannot contain any space (\"%s\")+" +#~ msgstr "" +#~ "Ungültiger Host-Name. Ein SYSLOG Host-Name darf keine Leerzeichen " +#~ "enthalten(\"%s\")+" +#~ msgid "Invalid hour offset: %d" +#~ msgstr "Ungültiger Stunden-Offset: %d" +#~ msgid "Invalid hour: %d" +#~ msgstr "Ungültige Stunde: %d" +#~ msgid "Invalid image" +#~ msgstr "Ungültiges Bild" +#~ msgid "Invalid image (the size is less than 4 bytes long)." +#~ msgstr "Ungültige Grafik (die Größe ist geringer als 4 Byte)." +#~ msgid "Invalid image dimension" +#~ msgstr "Ungültige Grafikdimension" +#~ msgid "Invalid image type" +#~ msgstr "Ungültiger Grafiktyp" +#~ msgid "Invalid millisecond: %d" +#~ msgstr "Ungültige Millisekunde: %d" +#~ msgid "Invalid minute: %d" +#~ msgstr "Ungültige Minute: %d" +#~ msgid "Invalid modification" +#~ msgstr "Ungültige Änderung" +#~ msgid "Invalid month: %d" +#~ msgstr "Ungültiger Monat: %d" +#~ msgid "Invalid namespace request" +#~ msgstr "Ungültige Namespace-Anforderung" +#~ msgid "Invalid network mask." +#~ msgstr "Ungültige Netzwerkmaske." +#~ msgid "Invalid node type" +#~ msgstr "Ungültiger Knotentyp" +#~ msgid "Invalid operation on a hosted node" +#~ msgstr "Ungültige Operation für einen hosted-Knoten" +#~ msgid "Invalid option specified" +#~ msgstr "Ungültige Option angegeben" +#~ msgid "Invalid or Unknown Time Zone" +#~ msgstr "Ungültige oder unbekannte Zeitzone" +#~ msgid "Invalid or unsupported XML Schema document" +#~ msgstr "Ungültiges oder nicht unterstütztes XML-Schemadokument" +#~ msgid "Invalid parent class: %s" +#~ msgstr "Ungültige übergeordnete Klasse: %s" +#~ msgid "Invalid password" +#~ msgstr "Ungültiges Passwort" +#~ msgid "Invalid second: %d" +#~ msgstr "Ungültige Sekunde: %d" +#~ msgid "Invalid second: %f" +#~ msgstr "Ungültige Sekunde: %f" +#~ msgid "Invalid socks authentication method." +#~ msgstr "Ungültige Authentifizierungmethode für SOCKS." +#~ msgid "Invalid state" +#~ msgstr "Ungültiger Status" +#~ msgid "Invalid stream operation" +#~ msgstr "Ungültige Stream-Operation" +#~ msgid "Invalid string offset" +#~ msgstr "Ungültiger String-Offset" +#~ msgid "Invalid syntax" +#~ msgstr "Syntaxfehler" +#~ msgid "Invalid syslog message: incorrect PRI number \"%s\"" +#~ msgstr "Ungültige syslog-Botschaft: Nicht korrekte PRI-Nummer \"%s\"" +#~ msgid "Invalid syslog message: incorrect PRI section" +#~ msgstr "Ungültige syslog-Botschaft: Nicht korrekter PRI-Abschnitt" +#~ msgid "Invalid syslog message: incorrect timestamp \"%s\"" +#~ msgstr "Ungültige syslog-Botschaft: Ungültiger Zeitstempel \"%s\"" +#~ msgid "Invalid time string: %s" +#~ msgstr "Ungültiger Zeit-String: %s" +#~ msgid "Invalid url '%s' - only supports 'http' and 'https' schemes" +#~ msgstr "Ungültige URL '%s' - unterstützt nur Schemata 'http' und 'https'" +#~ msgid "Invalid value length: Should be 32." +#~ msgstr "Ungültige Länge von Wert: sollte 32 sein." +#~ msgid "Invalid variant operation ($%.8x)" +#~ msgstr "Ungültige Variant-Operation ($%.8x)" +#~ msgid "" +#~ "Invalid variant operation (%s%.8x)\n" +#~ "%s" +#~ msgstr "" +#~ "Ungültige Variant-Operation (%s%.8x)\n" +#~ "%s" +#~ msgid "Invalid variant type" +#~ msgstr "Ungültiger Variant-Typ" +#~ msgid "Invalid widget handle" +#~ msgstr "Ungültiges Widget-Handle" +#~ msgid "Invokable Class %s implements no interfaces" +#~ msgstr "Aufrufbare Klasse %s implementiert keine Schnittstellen" +#~ msgid "Item %s has subitems, delete anyway?" +#~ msgstr "Element %s hat Unterelemente, trotzdem löschen?" +#~ msgid "Item %s is not allowed to be moved" +#~ msgstr "Eintrag %s darf nicht verschoben werden" +#~ msgid "Item Properties" +#~ msgstr "Eigens&chaften des Eintrags" +#~ msgid "Item not found ($0%x)" +#~ msgstr "Eintrag nicht gefunden ($0%x)" +#~ msgid "ItemTag property is not initialized" +#~ msgstr "Die Eigenschaft ItemTag ist nicht initialisiert" +#~ msgid "Items Editor..." +#~ msgstr "Eintrags-Editor..." +#~ msgid "Jpegs" +#~ msgstr "Jpegs" +#~ msgid "JulianDate" +#~ msgstr "Julianisches Datum" +#~ msgid "Kelvin" +#~ msgstr "Kelvin" +#~ msgid "Key" +#~ msgstr "Schlüssel" +#~ msgid "Key \"%s\" not found" +#~ msgstr "Taste \"%s\" nicht gefunden" +#~ msgid "Key may not contain equals sign (\"=\")" +#~ msgstr "Schlüssel darf keine Gleichheitszeichen (\"=\") enthalten" +#~ msgid "KiloLiters" +#~ msgstr "Kiloliter" +#~ msgid "Kilograms" +#~ msgstr "Kilogramm" +#~ msgid "Kilometers" +#~ msgstr "Kilometer" +#~ msgid "L&oad" +#~ msgstr "L&aden" +#~ msgid "L&og" +#~ msgstr "Pr&otokoll" +#~ msgid "Large &Icons" +#~ msgstr "&Große Symbole" +#~ msgid "Large icon view" +#~ msgstr "Große Symbole anzeigen" +#~ msgid "Last Response Time:" +#~ msgstr "Letzte Antwortzeit:" +#~ msgid "Length Required" +#~ msgstr "Länge benötigt" +#~ msgid "LightYears" +#~ msgstr "Lichtjahr" +#~ msgid "Lime" +#~ msgstr "Limone" +#~ msgid "Line" +#~ msgstr "Linie" +#~ msgid "Link to " +#~ msgstr "Verknüpfung auf " +#~ msgid "Links" +#~ msgstr "Link" +#~ msgid "List" +#~ msgstr "Liste" +#~ msgid "List is locked during an active ForEach" +#~ msgstr "Liste ist während eines aktiven ForEach gesperrt" +#~ msgid "List view" +#~ msgstr "Listenansicht" +#~ msgid "ListButton" +#~ msgstr "ListButton" +#~ msgid "ListView Items Editor" +#~ msgstr "ListView-Eintragseditor" +#~ msgid "Listbox (%s) style must be virtual in order to set Count" +#~ msgstr "" +#~ "Stil des Listenfeldes (%s) muss virtuell sein, damit Count gesetzt werden " +#~ "kann" +#~ msgid "Lists all the PortTypes published by this Service" +#~ msgstr "Listet alle PortTypes, die von diesem Service publiziert werden" +#~ msgid "Liters" +#~ msgstr "Liter" +#~ msgid "Lo&gin Prompt" +#~ msgstr "A&nmeldeaufforderung" +#~ msgid "Load Picture" +#~ msgstr "Bild laden" +#~ msgid "Loading..." +#~ msgstr "Laden..." +#~ msgid "Local time is %s" +#~ msgstr "Ortszeit ist %s" +#~ msgid "Local type declarations cannot have a name. Element: %s" +#~ msgstr "Lokale Typdeklarationen dürfen keinen Namen besitzen. Element: %s" +#~ msgid "Log files (*.log)" +#~ msgstr "Protokolldateien (*.log)" +#~ msgid "Log(%d)" +#~ msgstr "Log(%d)" +#~ msgid "LogDetail" +#~ msgstr "LogDetail" +#~ msgid "Login page is not defined" +#~ msgstr "Login-Seite ist nicht definiert" +#~ msgid "Login with USER first." +#~ msgstr "Zuerst anmelden mit USER." +#~ msgid "LongTons" +#~ msgstr "Tonne (UK)" +#~ msgid "MD is an Obsolete Command. Use MX." +#~ msgstr "MD ist eine veraltete Anweisung. Verwenden Sie MX." +#~ msgid "MF is an Obsolete Command. USE MX." +#~ msgstr "MFist eine veraltete Anweisung. Verwenden Sie MX." +#~ msgid "Ma&x Events:" +#~ msgstr "Ma&x. Ereignisse:" +#~ msgid "MailA is an Obsolete Command. USE MX." +#~ msgstr "MailA ist eine veraltete Anweisung. Verwenden Sie MX." +#~ msgid "MainUpdateAction" +#~ msgstr "MainUpdateAction" +#~ msgid "Maroon" +#~ msgstr "Braun" +#~ msgid "Mass" +#~ msgstr "Masse" +#~ msgid "Match &case" +#~ msgstr "Groß-/&Kleinschreibung" +#~ msgid "Match &whole word only" +#~ msgstr "&Nur ganze Wörter" +#~ msgid "Max Response Time:" +#~ msgstr "Max. Antwortzeit:" +#~ msgid "Max line length exceeded." +#~ msgstr "Max. Zeilenlänge überschritten." +#~ msgid "Maximum connections limit exceeded. Try again later." +#~ msgstr "Max. Anzahl an Verbindungen überschritten. Versuchen Sie es später." +#~ msgid "Maximum sessions exceeded" +#~ msgstr "Maximale Sitzungsanzahl überschritten" +#~ msgid "Me&nu show recently used items first" +#~ msgstr "Optionen" +#~ msgid "Medium Gray" +#~ msgstr "Mittelgrau" +#~ msgid "Megameters" +#~ msgstr "Megameter" +#~ msgid "Menu Background" +#~ msgstr "Menühintergrund" +#~ msgid "Menu Text" +#~ msgstr "Menütext" +#~ msgid "Menu insertion recursion not allowed" +#~ msgstr "Rekursion beim Einfügen von Menüs ist nicht gestattet" +#~ msgid "Merge" +#~ msgstr "Zusammenführen" +#~ msgid "Message decoder not found" +#~ msgstr "Botschafts-Decoder nicht gefunden" +#~ msgid "Message encoder not found" +#~ msgstr "Botschafts-Encoder nicht gefunden" +#~ msgid "Message handling failed" +#~ msgstr "Botschaftsbehandlung fehlgeschlagen" +#~ msgid "Message too long." +#~ msgstr "Die Botschaft ist zu lang." +#~ msgid "Message type recognition error" +#~ msgstr "Fehler beim Erkennen des Botschaftentyps" +#~ msgid "Meters" +#~ msgstr "Meter" +#~ msgid "Method %s of class %s not found" +#~ msgstr "Methode %s aus Klasse %s nicht gefunden" +#~ msgid "Method definition for %s has over %d parameters" +#~ msgstr "Methodendefinition für %s hat mehr als %d Parameter" +#~ msgid "Method has no RTTI" +#~ msgstr "Methode hat kein RTTI" +#~ msgid "Method not allowed" +#~ msgstr "Methode nicht erlaubt" +#~ msgid "Method not permitted in TSoapDataList" +#~ msgstr "Methode nicht erlaubt in TSoapDataList" +#~ msgid "MetricTons" +#~ msgstr "Metrische Tonne" +#~ msgid "Micrograms" +#~ msgstr "Mikrogramm" +#~ msgid "Micromicrons" +#~ msgstr "Mikromikron" +#~ msgid "Microns" +#~ msgstr "Mikron" +#~ msgid "Microsoft MSXML is not installed" +#~ msgstr "Microsoft MSXML ist nicht installiert" +#~ msgid "Miles" +#~ msgstr "Meile" +#~ msgid "Millennia" +#~ msgstr "Jahrtausend" +#~ msgid "MilliLiters" +#~ msgstr "Milliliter" +#~ msgid "MilliSeconds" +#~ msgstr "Millisekunde" +#~ msgid "Milligrams" +#~ msgstr "Milligramm" +#~ msgid "Millimeters" +#~ msgstr "Millimeter" +#~ msgid "Millimicrons" +#~ msgstr "Millimikron" +#~ msgid "Millisecond Values must be between 000 - 999" +#~ msgstr "Werte für Milliskeunden müssen zwischen 000 - 999 liegen" +#~ msgid "Mime format not supported for TIcon" +#~ msgstr "Mime-Format wird für TIcon nicht unterstützt" +#~ msgid "MimeSource format must have an associated data stream" +#~ msgstr "Dem MimeSource-Format muss ein Daten-Stream zugeordnet sein" +#~ msgid "Mimetype is empty" +#~ msgstr "Mimetype ist leer" +#~ msgid "Min Response Time:" +#~ msgstr "Min. Antwortzeit:" +#~ msgid "Minimize All" +#~ msgstr "Alle verkleinern" +#~ msgid "Minutes" +#~ msgstr "Minute" +#~ msgid "Mismatched paramaters to RegisterChildNodes" +#~ msgstr "Nicht übereinstimmende Parameter bei RegisterChildNodes" +#~ msgid "Missing Database property" +#~ msgstr "Eigenschaft Database fehlt" +#~ msgid "Missing DriverName property" +#~ msgstr "Eigenschaft DriverName fehlt" +#~ msgid "Missing FaultString or FaultCode element" +#~ msgstr "Fehlendes FaultString- oder FaultCode-Element" +#~ msgid "Missing ProgID" +#~ msgstr "Fehlende ProgID" +#~ msgid "Missing SQLConnection property" +#~ msgstr "Eigenschaft SQLConnection fehlt" +#~ msgid "Missing Type name" +#~ msgstr "Typname fehlt" +#~ msgid "Missing XML Data Component" +#~ msgstr "XML-Datenkomponente fehlt" +#~ msgid "Missing password" +#~ msgstr "Passwort fehlt" +#~ msgid "Missing query, table name or procedure name" +#~ msgstr "Fehlende Abfrage, Tabellen- oder Prozedurname" +#~ msgid "Missing user name" +#~ msgstr "Benutzername fehlt" +#~ msgid "Mode has not been set." +#~ msgstr "Der Modus wurde nicht gesetzt." +#~ msgid "Mode is not initialised" +#~ msgstr "Modus ist nicht initialisiert" +#~ msgid "Mode set to %s." +#~ msgstr "Modus ist gesetzt auf %s." +#~ msgid "Modification of %s is not permitted" +#~ msgstr "Modifikation von %s nicht zulässig" +#~ msgid "Modified" +#~ msgstr "Geändert" +#~ msgid "ModifiedJulianDate" +#~ msgstr "Modifiziertes julianisches Datum" +#~ msgid "Money Green" +#~ msgstr "Dollargrün" +#~ msgid "Months" +#~ msgstr "Monat" +#~ msgid "More Buttons" +#~ msgstr "Weitere Schaltflächen" +#~ msgid "Move Selection" +#~ msgstr "Liste" +#~ msgid "Moved Permanently" +#~ msgstr "Permanent verschoben" +#~ msgid "Moved Temporarily" +#~ msgstr "Temporär verschoben" +#~ msgid "Movie not loaded" +#~ msgstr "Film nicht geladen" +#~ msgid "Multiple Connections not supported by %s driver" +#~ msgstr "Mehrfach-Verbindungen werden vom %s-Treiber nicht unterstützt" +#~ msgid "Multiple body elements not supported" +#~ msgstr "Mehrere Rumpfelemente werden nicht unterstützt" +#~ msgid "Multiselect mode must be on for this feature" +#~ msgstr "Mehrfachauswahl muss für diese Funktion aktiviert sein" +#~ msgid "" +#~ "Must enable multiref output for objects when serializing a graph of " +#~ "objects - (%s)" +#~ msgstr "" +#~ "Multiref-Output für Objekte muss aktviert werden bei der Serialisierung " +#~ "eines Objektdiagramms - (%s)" +#~ msgid "Must have a target stream" +#~ msgstr "Ziel-Stream muss vorhanden sein" +#~ msgid "N&ew SubItem" +#~ msgstr "Neuer &Untereintrag" +#~ msgid "N&ew SubNode" +#~ msgstr "Neuer Unter&knoten" +#~ msgid "NTP subsystem" +#~ msgstr "NTP-Subsystem" +#~ msgid "Name not allowed on a ref item" +#~ msgstr "Name für Verweiselement nicht zulässig" +#~ msgid "Namespace URI" +#~ msgstr "Namespace-URI" +#~ msgid "Nanograms" +#~ msgstr "Nanogramm" +#~ msgid "NauticalMiles" +#~ msgstr "Seemeile" +#~ msgid "Navy" +#~ msgstr "Dunkelblau" +#~ msgid "Need account for login." +#~ msgstr "Benutzerkonto für Anmeldung wird benötigt." +#~ msgid "Need account for storing files." +#~ msgstr "Benutzerkonto für Speichern von Dateien wird benötigt." +#~ msgid "Negative stream size invalid" +#~ msgstr "Eine negative Stream-Größe ist ungültig" +#~ msgid "Net dropped connection or reset." +#~ msgstr "Netz hat die Verbindung verloren oder zurückgesetzt." +#~ msgid "Network is down." +#~ msgstr "Das Netzwerk ist ausgefallen." +#~ msgid "Network is unreachable." +#~ msgstr "Das Netzwerk ist nicht erreichbar." +#~ msgid "Network subsystem is unavailable." +#~ msgstr "Das Netzwerk-Subsystem ist nicht verfügbar." +#~ msgid "Network unreachable." +#~ msgstr "Das Netzwerk ist nicht erreichbar." +#~ msgid "New" +#~ msgstr "Neu" +#~ msgid "New &Directory" +#~ msgstr "Neues &Verzeichnis" +#~ msgid "New Folder" +#~ msgstr "Neuer Ordner" +#~ msgid "New components cannot be added to frame instances." +#~ msgstr "" +#~ "Zu Frame-Instanzen können keine neuen Komponenten hinzugefügt werden." +#~ msgid "Next|Go to the next tab" +#~ msgstr "&Fertig stellen" +#~ msgid "Nick" +#~ msgstr "Nick" +#~ msgid "" +#~ "No ActionBand style unit present in the uses clause.Your application must " +#~ "include either XPStyleActnCtrls, StdStyleActnCtrls or a third party " +#~ "ActionBand style unit in its uses clause." +#~ msgstr "" +#~ "In der uses-Klausel ist keine ActionBand-Attribut-Unit vorhanden.In Ihrer " +#~ "Anwendung muss XPStyleActnCtrls, StdStyleActnCtrls oder eine ActionBand-" +#~ "Attribut-Unit in der uses-Klausel vorhanden sein." +#~ msgid "No Class is regisgtered to implement interface %s" +#~ msgstr "Keine Klasse zum Implementieren der Schnittstelle %s registriert" +#~ msgid "No Content" +#~ msgstr "Kein Inhalt" +#~ msgid "No Dispatcher set" +#~ msgstr "Kein Dispatcher eingerichtet" +#~ msgid "No Help Manager installed." +#~ msgstr "Kein Hilfemanager installiert." +#~ msgid "No Install Options selected" +#~ msgstr "Es sind keine Installationsoptionen ausgewählt" +#~ msgid "No Message processing node set" +#~ msgstr "Kein Knoten zur Meldungsverarbeitung festgelegt" +#~ msgid "No Native to Message converter set" +#~ msgstr "Kein Konverter (Nativ zu Meldung) eingerichtet" +#~ msgid "No OnGetItem event handler assigned" +#~ msgstr "Es wurde keine OnGetItem-Ereignisbehandlung zugewiesen" +#~ msgid "No OnListDirectory event found!" +#~ msgstr "Es wurde kein Ereignis OnListDirectory gefunden!" +#~ msgid "No OnNewGroupsList event has been defined." +#~ msgstr "Es wurde kein Ereignis OnNewGroupsList definiert." +#~ msgid "No OnNewNewsList event has been defined." +#~ msgstr "Es wurde kein Ereignis OnNewNewsList definiert." +#~ msgid "No OnNewsgroupList event has been defined." +#~ msgstr "Es wurde kein Ereignis OnNewsgroupList definiert." +#~ msgid "No PSecPkgInfo specified" +#~ msgstr "Es wurde kein PSecPkgInfo angegeben" +#~ msgid "No Preview Available" +#~ msgstr "Keine Vorschau verfügbar" +#~ msgid "No Table of Contents found." +#~ msgstr "Kein Inhaltsverzeichnis gefunden" +#~ msgid "" +#~ "No URL property set - please specify the URL of the Service you wish to " +#~ "connect to" +#~ msgstr "" +#~ "URL-Eigenschaft nicht gesetzt - geben Sie die URL des Services an, zu dem " +#~ "Sie verbunden werden möchten" +#~ msgid "No URL was specified for 'GET'" +#~ msgstr "Für 'GET' wurde keine URL angegeben" +#~ msgid "No User: Port pair is not used or not used by an identifiable user" +#~ msgstr "" +#~ "Kein Benutzer: Port-Paar wird nicht oder nicht von identifizierbarem " +#~ "Benutzer verwendet" +#~ msgid "No WSDL document associated with WSDLView" +#~ msgstr "Kein WSDL-Dokument zugeordnet zu WSDLView" +#~ msgid "" +#~ "No WSDL or URL property was set in the THTTPRIO component. You must set " +#~ "the WSDL or URL property before invoking the Web Service" +#~ msgstr "" +#~ "In der THTTPPRIO-Komponente wurde keine WSDL- oder URL-Eigenschaft " +#~ "gesetzt. Vor Aufruf des Web Service muss eine dieser Eigenschaften " +#~ "gesetzt sein" +#~ msgid "No access to temporary file" +#~ msgstr "Kein Zugriff auf temporäre Datei" +#~ msgid "No access to temporary file: check TMPDIR setting" +#~ msgstr "Kein Zugriff auf temporäre Datei: prüfe TMPDIR-Einstellung" +#~ msgid "No active document" +#~ msgstr "Kein aktives Dokument" +#~ msgid "No authentication handler has been specified." +#~ msgstr "Es wurde keine Authentifizierungsbehandlung angegeben." +#~ msgid "No authority could be contacted for authentication." +#~ msgstr "" +#~ "Für die Authentifizierung konnte keine geeignete Stelle kontaktiert " +#~ "werden." +#~ msgid "No automatically activated data modules" +#~ msgstr "Keine automatisch aktivierten Datenmodule" +#~ msgid "No bindings specified." +#~ msgstr "Es wurde keine Bindung angegeben." +#~ msgid "No buffer space available." +#~ msgstr "Es ist kein Pufferplatz verfügbar." +#~ msgid "No class registered for invokable interface %s" +#~ msgstr "Keine Klasse registriert für aufrufbare Schnittstelle %s" +#~ msgid "No command handler found." +#~ msgstr "Es wurde kein Handler für Anweisungen gefunden." +#~ msgid "No context-sensitive Help installed." +#~ msgstr "Keine kontextsensitive Hilfe installiert." +#~ msgid "No context-sensitive help installed" +#~ msgstr "Keine kontextsensitive Hilfe installiert" +#~ msgid "No credential handle acquired" +#~ msgstr "Es wurde kein Beglaubigungs-Handle geholt" +#~ msgid "No credentials are available in the security package" +#~ msgstr "Im Sicherheits-Package sind keine Beglaubigungen verfügbar" +#~ msgid "No data allowed" +#~ msgstr "Keine Daten erlaubt" +#~ msgid "No data to read." +#~ msgstr "Keine Daten für den Lesezugriff." +#~ msgid "No default browser is specified" +#~ msgstr "Es ist kein Standard-Browser eingetragen" +#~ msgid "No execute handler found." +#~ msgstr "Es wurde keine Ausführungsbehandlung gefunden." +#~ msgid "No help found for \"%s\"" +#~ msgstr "Keine Hilfe gefunden für \"%s\"" +#~ msgid "No help found for %s" +#~ msgstr "Für %s sind keine Hilfeinformationen vorhanden." +#~ msgid "No help keyword specified." +#~ msgstr "Es wurden keine Schlüsselwörter für die Hilfe angegeben." +#~ msgid "No host" +#~ msgstr "Kein Host" +#~ msgid "No interface registered for URL '%s'" +#~ msgstr "Keine registrierte Schnittstelle für URL '%s'" +#~ msgid "No interface registered for soap action '%s'" +#~ msgstr "Keine registrierte Schnittstelle für die SOAP-Aktion '%s'" +#~ msgid "No interface is registered to handle URL %s" +#~ msgstr "Keine Schnittstelle registriert für die Behandlung der URL %s" +#~ msgid "" +#~ "No invokable class registered that implements interface %s of (soap " +#~ "action/path) %s" +#~ msgstr "" +#~ "Zum Implementieren von Interface %s für (SOAP-Aktion/Pfad) %s ist keine " +#~ "aufrufbare Klasse registriert." +#~ msgid "No matching DOM Vendor: \"%s\"" +#~ msgstr "Kein entsprechender DOM-Hersteller: \"%s\"" +#~ msgid "" +#~ "No matching Kylix type was found for type: URI = %s, Name = %s on Node %s" +#~ msgstr "" +#~ "Keinen passenden Kylix-Typ gefunden für: URI = %s, Name = %s von Node %s" +#~ msgid "No method named '%s' is supported by interface '%s'" +#~ msgstr "Methode mit Namen '%s' wird von Interface '%s' nicht unterstützt" +#~ msgid "No modification allowed (readonly data)" +#~ msgstr "Keine Änderung erlaubt (Daten können nur gelesen werden)" +#~ msgid "No printer adapter available for printing" +#~ msgstr "Für das Drucken ist kein Druckeradapter verfügbar" +#~ msgid "No property pages are available for this control" +#~ msgstr "Für dieses Element sind keine Eigenschaftsseiten verfügbar" +#~ msgid "" +#~ "No request handlers handled this request. The WebAppComponents " +#~ "PageDispatcher, AdapterDispatcher or DispatchActions property may not be " +#~ "set." +#~ msgstr "" +#~ "Diese Anforderung wurde von keiner entsprechenden Routine behandelt. Die " +#~ "WebAppComponents-Eigenschaft PageDispatcher, AdapterDispatcher oder " +#~ "DispatchActions sind u.U. nicht gesetzt." +#~ msgid "No route to host." +#~ msgstr "Keine Route zum Host." +#~ msgid "No service available for URL %s" +#~ msgstr "Kein Dienst für die URL %s verfügbar" +#~ msgid "No topic-based Help installed." +#~ msgstr "Keine themenbasierte Hilfe installiert." +#~ msgid "No topic-based help system installed" +#~ msgstr "Es ist keine themenbasierte Hilfe installiert." +#~ msgid "Node \"%s\" not found" +#~ msgstr "Knoten \"%s\" nicht gefunden" +#~ msgid "Node cannot be null" +#~ msgstr "Knoten kann nicht null sein" +#~ msgid "Node is owned by a different document" +#~ msgstr "Der Knoten ist im Besitz eines anderen Dokuments" +#~ msgid "Node is readonly" +#~ msgstr "Knoten ist schreibgeschützt" +#~ msgid "Node not found" +#~ msgstr "Knoten nicht gefunden" +#~ msgid "Non Authenticated" +#~ msgstr "Nicht authentifiziert" +#~ msgid "Non-authoritative Information" +#~ msgstr "Nicht-autoritative Information" +#~ msgid "Non-authoritative response (try again or check DNS setup)." +#~ msgstr "" +#~ "Nicht-autoritative Antwort (Versuchen Sie es noch einmal oder überprüfen " +#~ "Sie das DNS-Setup)." +#~ msgid "Non-echo type response received" +#~ msgstr "Nicht-Echo-Antwort empfangen" +#~ msgid "Non-recoverable errors: FORMERR, REFUSED, NOTIMP." +#~ msgstr "Nicht behebbare Fehler: FORMERR, REFUSED, NOTIMP." +#~ msgid "None" +#~ msgstr "Ohne" +#~ msgid "Not Acceptable" +#~ msgstr "Nicht akzeptabel" +#~ msgid "Not Connected" +#~ msgstr "Nicht verbunden" +#~ msgid "Not Found" +#~ msgstr "Nicht gefunden" +#~ msgid "Not Implemented" +#~ msgstr "Nicht implementiert" +#~ msgid "Not Modified" +#~ msgstr "Nicht geändert" +#~ msgid "Not all bytes sent." +#~ msgstr "Es wurden nicht alle Bytes gesendet." +#~ msgid "Not connected to server." +#~ msgstr "Nicht mit Server verbunden." +#~ msgid "Not enough bytes received" +#~ msgstr "Es wurden nicht genügend Bytes empfangen" +#~ msgid "Not enough data in buffer." +#~ msgstr "Nicht genügend Daten im Puffer." +#~ msgid "Not enough memory is available to complete this request" +#~ msgstr "Für diese Anforderung steht nicht genügend Speicher zur Verfügung" +#~ msgid "Not found" +#~ msgstr "Nicht gefunden" +#~ msgid "Not in edit mode" +#~ msgstr "Nicht im Bearbeitungs-Modus" +#~ msgid "Not logged in." +#~ msgstr "Nicht angemeldet." +#~ msgid "Not supported" +#~ msgstr "Nicht unterstützt" +#~ msgid "Notice: normal but significant condition" +#~ msgstr "Ankündigung: Normaler, aber bedeutender Zustand" +#~ msgid "Object does not support scripting. Class: %0:s" +#~ msgstr "Objekt unterstützt das Scripting nicht. Klasse: %0:s" +#~ msgid "Object type name required as parameter value" +#~ msgstr "Name des Objekttyps als Parameterwert erforderlich" +#~ msgid "Object type not supported." +#~ msgstr "Objekttyp nicht unterstützt." +#~ msgid "ObjectView must be True for Table with Object fields" +#~ msgstr "ObjectView muss bei Tabellen mit Objektfeldern True sein" +#~ msgid "Odd byte position not valid for WideString" +#~ msgstr "Eine ungerade Byte-Position ist für WideString nicht zulässig" +#~ msgid "Odd size not valid for WideString" +#~ msgstr "Eine ungerade Größe ist für WideString nicht zulässig" +#~ msgid "Ok" +#~ msgstr "Ok" +#~ msgid "Olive" +#~ msgstr "Olivgrün" +#~ msgid "OnDataAvailable event is nil." +#~ msgstr "Ereignis OnDataAvailable ist nil." +#~ msgid "OnExecute not assigned." +#~ msgstr "OnExecute nicht zugewiesen." +#~ msgid "Only one FaultCode element allowed" +#~ msgstr "Nur ein FaultCode-Element zulässig" +#~ msgid "Only one FaultString element allowed" +#~ msgstr "Nur ein FaultString-Element zulässig" +#~ msgid "Only one TIdAntiFreeze can exist per application." +#~ msgstr "Pro Anwendung kann es nur ein TIdAntiFreeze geben." +#~ msgid "Open MyBase table" +#~ msgstr "MyBase-Tabelle öffnen" +#~ msgid "Open Picture" +#~ msgstr "Dialog" +#~ msgid "Open Transformation File" +#~ msgstr "Transformationsdatei öffnen" +#~ msgid "Open Xml File" +#~ msgstr "Xml-Datei öffnen" +#~ msgid "Open as &read-only" +#~ msgstr "Nur zum &Lesen öffnen" +#~ msgid "Open trace log file" +#~ msgstr "Protokolldatei für Ablaufverfolgung öffnen" +#~ msgid "Open with..." +#~ msgstr "Öffnen mit..." +#~ msgid "Open|Opens an existing file" +#~ msgstr "Öffnen|Vorhandene Datei öffnen" +#~ msgid "Operation already in progress." +#~ msgstr "Die Operation wird bereits durchgeführt." +#~ msgid "Operation not allowed on a unidirectional dataset" +#~ msgstr "" +#~ "Diese Operation ist bei einer unidirektionalen Datenemenge nicht gestattet" +#~ msgid "Operation not allowed on sorted list" +#~ msgstr "Operation für sortierte Listen nicht zulässig" +#~ msgid "Operation not allowed with aggregates active" +#~ msgstr "Operation mit aktiven Aggregaten nicht zulässig" +#~ msgid "Operation not supported" +#~ msgstr "Operation nicht unterstützt" +#~ msgid "Operation not supported on socket." +#~ msgstr "Die Operation wird bei Socket nicht unterstützt." +#~ msgid "" +#~ "Operation not supported. %s component does not support " +#~ "IGetWebComponentList" +#~ msgstr "" +#~ "Operation wird nicht unterstützt. Komponente %s unterstützt nicht " +#~ "IGetWebComponentList" +#~ msgid "Operation now in progress." +#~ msgstr "Die Operation wird gerade durchgeführt." +#~ msgid "Operation would block. " +#~ msgstr "Die Operation würde blockieren. " +#~ msgid "Option not set to allow Native type to be set to NULL" +#~ msgstr "Option zum Setzen des Typs Native auf NULL nicht gesetzt" +#~ msgid "Original Value" +#~ msgstr "Originalwert" +#~ msgid "OtherNick" +#~ msgstr "OtherNick" +#~ msgid "Ounces" +#~ msgstr "Unze" +#~ msgid "Overflow while converting variant of type (%s) into type (%s)" +#~ msgstr "" +#~ "Überlauf bei der Konvertierung einer Variante vom Typ (%s) in Typ (%s)" +#~ msgid "Owner" +#~ msgstr "Besitzer" +#~ msgid "Owner is not a TCustomHeaderSection" +#~ msgstr "Besitzer ist kein TCustomHeaderSection" +#~ msgid "PNGs" +#~ msgstr "PNGs" +#~ msgid "POP3 proxy ready" +#~ msgstr "POP3-Proxy bereit" +#~ msgid "POP3 proxy signing off" +#~ msgstr "POP3-Proxy wird beendet" +#~ msgid "Paces" +#~ msgstr "Schritt" +#~ msgid "Package Size Too Big." +#~ msgstr "Package-Größe zu hoch" +#~ msgid "Packages are not supported by '%s' Server" +#~ msgstr "Packages werden vom '%s'-Server nicht unterstützt" +#~ msgid "Page %s does not support inclusion" +#~ msgstr "Seite %s unterstützt keine Inklusion" +#~ msgid "Page Set&up..." +#~ msgstr "Seite e&inrichten..." +#~ msgid "Page access denied" +#~ msgstr "Zugriff auf Seite verweigert" +#~ msgid "Pages" +#~ msgstr "Seiten" +#~ msgid "Parameter %d required for method %s" +#~ msgstr "Parameter %d erforderlich für Methode %s" +#~ msgid "Parameter %s on Method %s of Interface %s has no RTTI" +#~ msgstr "Parameter %s der Methode %s der Schnittstelle %s hat kein RTTI" +#~ msgid "Parameter expected" +#~ msgstr "Parameter erwartet" +#~ msgid "Parent given is not a parent of '%s'" +#~ msgstr "" +#~ "Das angegebene übergeordnete Element ist kein übergeordnetes Element von " +#~ "'%s'" +#~ msgid "ParentConnection is not assigned" +#~ msgstr "ParentConnection ist nicht zugewiesen" +#~ msgid "Parsecs" +#~ msgstr "Parsecs" +#~ msgid "Partial Content" +#~ msgstr "Teilinhalt" +#~ msgid "Pass&word:" +#~ msgstr "Pass&wort:" +#~ msgid "Password" +#~ msgstr "Passwort" +#~ msgid "Password must not be blank" +#~ msgstr "Passwort muss angegeben werden" +#~ msgid "Password: " +#~ msgstr "Passwort: " +#~ msgid "Paste" +#~ msgstr "Einfügen" +#~ msgid "Paste|Inserts Clipboard contents" +#~ msgstr "Einfügen|Inhalt der Zwischenablage einfügen" +#~ msgid "Path" +#~ msgstr "Pfad" +#~ msgid "Personalized Menus and Toolbars" +#~ msgstr "Individuelle Menüs und Symbolleisten" +#~ msgid "Picas" +#~ msgstr "Pica" +#~ msgid "Pixmaps" +#~ msgstr "Pixmaps" +#~ msgid "Points" +#~ msgstr "Punkt" +#~ msgid "Polite people say HELO" +#~ msgstr "Höfliche Menschen sagen HALLO" +#~ msgid "Port Type" +#~ msgstr "Port-Typ" +#~ msgid "Port:" +#~ msgstr "Port:" +#~ msgid "PortName" +#~ msgstr "Port-Name" +#~ msgid "Pounds" +#~ msgstr "Pfund" +#~ msgid "Precondition Failed" +#~ msgstr "Vorbedingung fehlgeschlagen" +#~ msgid "PreviewLabel" +#~ msgstr "Labelvorschau" +#~ msgid "Previous|Go back to the previous tab" +#~ msgstr "Tab" +#~ msgid "Print Set&up..." +#~ msgstr "&Druckereinstellungen..." +#~ msgid "Print Setup" +#~ msgstr "Druckereinstellungen" +#~ msgid "Project Co-Coordinator" +#~ msgstr "Projekt-Co-Koordinator" +#~ msgid "Project Coordinator" +#~ msgstr "Projekt-Koordinator" +#~ msgid "Property %s does not exist" +#~ msgstr "Eigenschaft %s existiert nicht." +#~ msgid "Property '%s' has not been initialized on component '%s'" +#~ msgstr "Eigenschaft '%s' wurde für Komponente '%s' nicht initialisiert" +#~ msgid "Property or Method \"%s\" is not supported by DOM Vendor \"%s\"" +#~ msgstr "" +#~ "Eigenschaft oder Methode \"%s\" wird von diesem DOM-Hersteller \"%s\" " +#~ "nicht unterstützt" +#~ msgid "Protocol family not supported." +#~ msgstr "Die Protokollfamilie wird nicht unterstützt." +#~ msgid "Protocol field is empty" +#~ msgstr "Protokollfeld ist leer" +#~ msgid "Protocol not supported." +#~ msgstr "Das Protokoll wird nicht unterstützt." +#~ msgid "Protocol wrong type for socket." +#~ msgstr "Das Protokoll hat für Socket den falschen Typ." +#~ msgid "Proxy Authentication Required" +#~ msgstr "Proxy-Authentifizierung erforderlich" +#~ msgid "Purple" +#~ msgstr "Purpur" +#~ msgid "Queue %s status: %s" +#~ msgstr "Warteschlange %s Status: %s" +#~ msgid "Quit key hit" +#~ msgstr "Taste zum Verlassen gedrückt" +#~ msgid "RCode NO Error" +#~ msgstr "RCode NO Fehler" +#~ msgid "RESPONSE" +#~ msgstr "RESPONSE" +#~ msgid "Radio items must have a Controller as a parent" +#~ msgstr "" +#~ "Optionsfelder müssen einen Controller als übergeordnetes Element besitzen" +#~ msgid "Range check error for variant of type (%s)" +#~ msgstr "Fehler bei Bereichsprüfung für Variant des Typs (%s)" +#~ msgid "" +#~ "Range check error while converting variant of type (%s) into type (%s)" +#~ msgstr "" +#~ "Fehler bei Bereichsprüfung bei der Konvertierung von Variant von Typ (%s) " +#~ "zu Typ (%s)" +#~ msgid "Range of %d to %d is invalid" +#~ msgstr "Der Bereich von %d bis %d ist ungültig" +#~ msgid "Rankine" +#~ msgstr "Rangordnung" +#~ msgid "Raw Receive Error = 0." +#~ msgstr "Raw Receive-Fehler = 0." +#~ msgid "Re&move all" +#~ msgstr "&Alle entfernen" +#~ msgid "Read Timeout" +#~ msgstr "Zeitüberschreitung beim Lesen" +#~ msgid "Real name" +#~ msgstr "Wirklicher Name" +#~ msgid "Reason: %s\n" +#~ msgstr "Grund: %s\n" +#~ msgid "Reaumur" +#~ msgstr "Reaumur" +#~ msgid "Receive" +#~ msgstr "Erhalten" +#~ msgid "Receive control file" +#~ msgstr "Empfang von Steuerungsdatei" +#~ msgid "Receive data file" +#~ msgstr "Empfang von Datendatei" +#~ msgid "Received Packet is too small. %d" +#~ msgstr "Empfangenes Paket ist zu klein. %d" +#~ msgid "Received Packet is too small. Less than 12 bytes %d" +#~ msgstr "Empfangenes Paket ist zu klein. Weniger als 12 Byte %d" +#~ msgid "Received Packet is too small. Less than 4 bytes %d" +#~ msgstr "Empfangenes Paket ist zu klein. Weniger als 4 Byte %d" +#~ msgid "" +#~ "Received content of invalid Content-Type setting: %s - SOAP expects " +#~ "\"text/xml\"" +#~ msgstr "" +#~ "Empfang von Inhalt mit ungültigen Einstellungen für Inhaltstyp: %s - SOAP " +#~ "erwartet \"text/xml\"" +#~ msgid "Received someone else's packet" +#~ msgstr "Es ist ein Paket für einen anderen Empfänger angekommen" +#~ msgid "Reconnect at %s: %s" +#~ msgstr "Wieder verbinden bei %s: %s" +#~ msgid "Record not found or changed by another user" +#~ msgstr "Datensatz nicht gefunden oder von einem anderen Benutzer geändert" +#~ msgid "Recordset is not open" +#~ msgstr "Recordset ist nicht geöffnet" +#~ msgid "Recursion while doing a VarDataCastTo" +#~ msgstr "Rekursion beim Durchführen eines VarDataCastTo" +#~ msgid "Recursion while doing a VarDataClear" +#~ msgstr "Rekursion beim Durchführen eines VarDataClear" +#~ msgid "Recursion while doing a VarDataCopy" +#~ msgstr "Rekursion beim Durchführen eines VarDataCopy" +#~ msgid "Recursion while doing a VarDataCopyNoInd" +#~ msgstr "Rekursion beim Durchführen eines VarDataCopyNoInd" +#~ msgid "Recursion while doing a VarDataInit" +#~ msgstr "Rekursion beim Durchführen eines VarDataInit" +#~ msgid "Recv " +#~ msgstr "Empf " +#~ msgid "Red" +#~ msgstr "Rot" +#~ msgid "Redo" +#~ msgstr "Widerrufen" +#~ msgid "Refresh" +#~ msgstr "Aktualisieren" +#~ msgid "Refresh is only supported if the FileName or XML properties are set" +#~ msgstr "" +#~ "Aktualisierung wird nur unterstützt, wenn die Eigenschaften FileName oder " +#~ "XML gesetzt sind" +#~ msgid "Registered Types" +#~ msgstr "Registrierte Typen" +#~ msgid "Reload" +#~ msgstr "Neu laden" +#~ msgid "Remotable Type %s not registered" +#~ msgstr "Typ %s ist nicht registriert" +#~ msgid "" +#~ "Remote Method Call: unsupported calling convention %s for method %s on " +#~ "interface %s" +#~ msgstr "" +#~ "Remote-Methodenaufruf: nicht unterstützte Aufrufkonvention %s für Methode " +#~ "%s in Schnittstelle %s" +#~ msgid "Remove" +#~ msgstr "Entfernen" +#~ msgid "Rep&lace with:" +#~ msgstr "&Ersetzen durch:" +#~ msgid "Replace" +#~ msgstr "Ersetzen" +#~ msgid "Replace &All" +#~ msgstr "&Alles ersetzen" +#~ msgid "Replace|Replaces specific text with different text" +#~ msgstr "Ersetzen|Angegebenen Text durch neuen Text ersetzen" +#~ msgid "Reply %s on Job ID %s" +#~ msgstr "Antwort %s auf Job-ID %s" +#~ msgid "" +#~ "Reply Timed Out: The server did not return a response and the query has " +#~ "been abandoned" +#~ msgstr "" +#~ "Zeit überschritten bei Antwort: Der Server gab keine Antwort und die " +#~ "Abfrage wurde nicht eingestellt" +#~ msgid "Request Entity To Long" +#~ msgstr "Anforderungs-Entität zu lang" +#~ msgid "Request Timeout" +#~ msgstr "Zeitüberschreitung für Anforderung" +#~ msgid "Request rejected because SOCKS server cannot connect." +#~ msgstr "" +#~ "Die Anforderung wurde zurückgewiesen, da der SOCKS-Server keine " +#~ "Verbindung herstellen konnte." +#~ msgid "" +#~ "Request rejected because the client program and identd report different " +#~ "user-ids." +#~ msgstr "" +#~ "Die Anforderung wurde zurückgewiesen, da das Client-Programm und identd " +#~ "verschiedene Anwender-IDs melden." +#~ msgid "Request rejected or failed." +#~ msgstr "Anforderung zurückgewiesen oder fehlgeschlagen." +#~ msgid "Request-URI Too Long. 256 Chars max" +#~ msgstr "Anforderungs-URI zu lang. Max. 256 Zeichen" +#~ msgid "RequestCount:" +#~ msgstr "Anforderungen:" +#~ msgid "Requested action aborted: local error in processing." +#~ msgstr "Angeforderte Aktion abgebrochen: Lokaler Fehler bei Bearbeitung." +#~ msgid "Requested action aborted: page type unknown." +#~ msgstr "Angeforderte Aktion abgebrochen: Seitenzahl unbekannt." +#~ msgid "Requested action not taken." +#~ msgstr "Angeforderte Aktion nicht durchgeführt." +#~ msgid "Requested file action aborted." +#~ msgstr "Angeforderte Dateiaktion nicht abgebrochen." +#~ msgid "Requested file action not taken." +#~ msgstr "Angeforderte Dateiaktion nicht durchgeführt." +#~ msgid "Requested file action okay, completed." +#~ msgstr "Angeforderte Dateiaktion OK, abgeschlossen." +#~ msgid "Requested file action pending further information." +#~ msgstr "Angeforderte Dateiaktion steht aus wegen Informationsbedarf." +#~ msgid "Requires Connection before opening" +#~ msgstr "Vor dem Öffnen ist eine Verbindung erforderlich" +#~ msgid "Reset Content" +#~ msgstr "Inhalt zurücksetzen" +#~ msgid "Reset Toolbar" +#~ msgstr "Symbolleiste zurücksetzen" +#~ msgid "Reset Usage Data" +#~ msgstr "Optionen" +#~ msgid "Reset all usage data?" +#~ msgstr "Alle verwendeten Daten zurücksetzen" +#~ msgid "Resolving hostname %s." +#~ msgstr "Host-Name %s wird aufgelöst." +#~ msgid "Restore Database Files" +#~ msgstr "Datenbankdateien wiederherstellen" +#~ msgid "Retired/Past Contributors" +#~ msgstr "Pensionierte/ehemalige Mitarbeiter" +#~ msgid "Return" +#~ msgstr "Eingabe" +#~ msgid "Rods" +#~ msgstr "Messrute" +#~ msgid "Row not found in %s" +#~ msgstr "Reihe in %s nicht gefunden" +#~ msgid "Run" +#~ msgstr "Start" +#~ msgid "Run|Runs an application" +#~ msgstr "Start" +#~ msgid "S&top Server" +#~ msgstr "Server s&toppen" +#~ msgid "S&ub Items" +#~ msgstr "&Untereinträge" +#~ msgid "SOAP Response Packet: result element expected, received \"%s\"" +#~ msgstr "SOAP-Antwortpaket: Ergebniselement erwartet, \"%s\" gefunden" +#~ msgid "SQL Error: Error mapping failed" +#~ msgstr "SQL-Fehler: Fehlerzuweisung gescheitert" +#~ msgid "SQLConnection property required for this operation" +#~ msgstr "Für diese Operation ist die Eigenschaft SQLConnection erforderlich" +#~ msgid "SSL certificate request error." +#~ msgstr "Fehler bei der Anforderung eines SSL-Zertifikats." +#~ msgid "SSL connection has dropped." +#~ msgstr "Die SSL-Verbindung ging verloren." +#~ msgid "SSL library internal error." +#~ msgstr "SSL-Bibliotheksinterner Fehler." +#~ msgid "SSL status: \"%s\"" +#~ msgstr "SSL-Status: \"%s\"" +#~ msgid "SSPI %s returns error #%d(0x%x): %s" +#~ msgstr "SSPI %s gibt Fehler #%d(0x%x) zurück: %s" +#~ msgid "SSPI interface has failed to initialise properly" +#~ msgstr "SSPI-Interface hat sich nicht richtig initialisiert" +#~ msgid "Save" +#~ msgstr "Speichern" +#~ msgid "Save %s as" +#~ msgstr "%s speichern unter" +#~ msgid "Save &As..." +#~ msgstr "Speichern &unter..." +#~ msgid "Save As" +#~ msgstr "Speichern unter" +#~ msgid "Save As|Saves the active file with a new name" +#~ msgstr "Speichern unter|Aktive Datei unter einem neuen Namen speichern" +#~ msgid "Save Picture" +#~ msgstr "Dialog" +#~ msgid "Save Picture As" +#~ msgstr "Bild speichern unter" +#~ msgid "Script Error" +#~ msgstr "Script-Fehler" +#~ msgid "Script Object expected" +#~ msgstr "Script-Objekt erwartet" +#~ msgid "Script engine not found: %s." +#~ msgstr "Script-Engine nicht gefunden: %s." +#~ msgid "Script execution timed out after %d seconds" +#~ msgstr "Zeit der Script-Ausführung nach %d Sekunden überschritten" +#~ msgid "Scroll Bar" +#~ msgstr "Bildlaufleiste" +#~ msgid "Se&ttings:" +#~ msgstr "Eins&tellungen:" +#~ msgid "Search" +#~ msgstr "Suchen" +#~ msgid "Seconds" +#~ msgstr "Sekunde" +#~ msgid "See Other" +#~ msgstr "Siehe Weitere" +#~ msgid "Sele&cted Index:" +#~ msgstr "Ausgewählt-&Index:" +#~ msgid "Select &All" +#~ msgstr "Alles &markieren" +#~ msgid "Select &Color..." +#~ msgstr "&Farbe wählen..." +#~ msgid "Select &Font..." +#~ msgstr "&Schriftart wählen..." +#~ msgid "Select All" +#~ msgstr "Alles markieren" +#~ msgid "Select All|Selects the entire document" +#~ msgstr "Alles markieren|Markiert das gesamte Dokument" +#~ msgid "Selected" +#~ msgstr "Ausgewählte" +#~ msgid "Selected DOM Vendor does not support this property or method" +#~ msgstr "" +#~ "Der gewählte DOM-Hersteller unterstützt diese Eigenschaft oder Methode " +#~ "nicht" +#~ msgid "" +#~ "Selection contains a component introduced in an ancestor form which " +#~ "cannot be deleted" +#~ msgstr "" +#~ "Auswahl enthält eine Komponente, die in einem Vorfahr-Formular eingeführt " +#~ "wurde, das nicht gelöscht werden kann." +#~ msgid "Send" +#~ msgstr "Senden" +#~ msgid "Send a message" +#~ msgstr "Eine Botschaft senden" +#~ msgid "Send email" +#~ msgstr "E-mail senden" +#~ msgid "Send to Back" +#~ msgstr "Nach hinten setzen" +#~ msgid "Sent " +#~ msgstr "Gesendet " +#~ msgid "Separator" +#~ msgstr "Separator" +#~ msgid "Server Connection not locatable when sending message" +#~ msgstr "" +#~ "Die Serververbindung ist beim Senden einer Botschaft nicht ausfindig zu " +#~ "machen" +#~ msgid "Server Returned Unknown Error" +#~ msgstr "Der Server gab einen unbekannten Fehler zurück" +#~ msgid "Server did not respond." +#~ msgstr "Server hat nicht geantwortet." +#~ msgid "Server do not support APOP (no timestamp)" +#~ msgstr "Server unterstützt kein APOP (kein Zeitstempel)" +#~ msgid "Server status: active" +#~ msgstr "Server-Status: aktiv" +#~ msgid "ServerInfo" +#~ msgstr "ServerInfo" +#~ msgid "Service Editor" +#~ msgstr "Service-Editor" +#~ msgid "Service Info Page" +#~ msgstr "Service Info-Seite" +#~ msgid "Service Unavailable" +#~ msgstr "Service nicht verfügbar" +#~ msgid "Service closing control connection." +#~ msgstr "Service schließt die Steuerverbindung." +#~ msgid "Service not available, closing control connection." +#~ msgstr "Service nicht verfügbar, Steuerverbindung wird geschlossen." +#~ msgid "Service ready for new user." +#~ msgstr "Service bereit für neuen Benutzer." +#~ msgid "Set Size Exceeded." +#~ msgstr "Mengengröße überschritten." +#~ msgid "Set the GroupRef property for the cmGroupRef content model" +#~ msgstr "" +#~ "Legen Sie die Eigenschaft GroupRef für das cmGroupRef-Inhaltsmodell fest" +#~ msgid "SetCipher failed." +#~ msgstr "SetCipher fehlgeschlagen." +#~ msgid "Show &Hidden Files" +#~ msgstr "Verborgene Dateien an&zeigen" +#~ msgid "Show &tips on toolbars" +#~ msgstr "&Kurzhinweise in Symbolleisten anzeigen" +#~ msgid "Show f&ull menus after a short delay" +#~ msgstr "&Nach kurzer Verzögerung vollständige Menüs anzeigen" +#~ msgid "Show shortcut keys in tips" +#~ msgstr "&Tastenkürzel in Kurzhinweisen anzeigen" +#~ msgid "Signing Off" +#~ msgstr "Beendigung" +#~ msgid "Silver" +#~ msgstr "Silber" +#~ msgid "Size" +#~ msgstr "Größe" +#~ msgid "Size Mismatch - Field %s size is too small for data" +#~ msgstr "Größenfehler - Feld %s ist zu klein für die Daten" +#~ msgid "Size(Bytes)" +#~ msgstr "Größe(Bytes)" +#~ msgid "Skip" +#~ msgstr "Überspringen" +#~ msgid "Sky Blue" +#~ msgstr "Himmelblau" +#~ msgid "Small Icon view" +#~ msgstr "Kleine Symoble anzeigen" +#~ msgid "" +#~ "Soap header %s with attribute 'mustUnderstand' set to true was not handled" +#~ msgstr "" +#~ "SOAP-Header %s mit Attribut 'mustUnderstand' true wurde nicht behandelt" +#~ msgid "" +#~ "Socket Error # %d\n" +#~ "%s" +#~ msgstr "" +#~ "Socket-Fehler # %d\n" +#~ "%s" +#~ msgid "Socket is already connected." +#~ msgstr "Socket ist bereits verbunden." +#~ msgid "Socket is not connected." +#~ msgstr "Socket ist nicht verbunden." +#~ msgid "Socket operation on non-socket." +#~ msgstr "Socket-Operation auf Nicht-Socket." +#~ msgid "Socket read error" +#~ msgstr "Fehler beim Lesen von Socket" +#~ msgid "Socket type not supported." +#~ msgstr "Sockettyp wird nicht unterstützt." +#~ msgid "Socks server did not respond." +#~ msgstr "Socks-Server hat nicht geantwortet." +#~ msgid "Software caused connection abort." +#~ msgstr "Die Software hat den Abbruch der Verbindung verursacht." +#~ msgid "SourceDirectory is not set" +#~ msgstr "SourceDirectory nicht gesetzt" +#~ msgid "SquareCentimeters" +#~ msgstr "Quadratzentimeter" +#~ msgid "SquareDecameters" +#~ msgstr "Quadratdekameter" +#~ msgid "SquareDecimeters" +#~ msgstr "Quadratdezimeter" +#~ msgid "SquareFeet" +#~ msgstr "Quadratfuß" +#~ msgid "SquareHectometers" +#~ msgstr "Quadrathektometer" +#~ msgid "SquareInches" +#~ msgstr "Quadratzoll" +#~ msgid "SquareKilometers" +#~ msgstr "Quadratkilometer" +#~ msgid "SquareMeters" +#~ msgstr "Quadratmeter" +#~ msgid "SquareMiles" +#~ msgstr "Quadratmeilen" +#~ msgid "SquareMillimeters" +#~ msgstr "Quadratmillimeter" +#~ msgid "SquareRods" +#~ msgstr "Quadratrute" +#~ msgid "SquareYards" +#~ msgstr "Quadrat-Yard" +#~ msgid "St&atistics" +#~ msgstr "St&atistik" +#~ msgid "Stale NFS file handle." +#~ msgstr "Abgelaufenes NFS-Datei-Handle." +#~ msgid "Standard" +#~ msgstr "Standard" +#~ msgid "Standard Style" +#~ msgstr "Standard-Attribut" +#~ msgid "Start" +#~ msgstr "Start" +#~ msgid "Start mail input; end with ." +#~ msgstr "Mail-Eingabe starten; beenden mit ." +#~ msgid "Starting FTP transfer" +#~ msgstr "FTP-Transfer wird gestartet" +#~ msgid "Stat " +#~ msgstr "Stat " +#~ msgid "Steres" +#~ msgstr "Ster" +#~ msgid "Stones" +#~ msgstr "Stones" +#~ msgid "Stop" +#~ msgstr "Stop" +#~ msgid "Stopped" +#~ msgstr "Angehalten" +#~ msgid "Stored Procedures not supported by '%s' Server" +#~ msgstr "Stored Procedures werden vom '%s'-Server nicht unterstützt" +#~ msgid "Strikeout" +#~ msgstr "Durchstreichen" +#~ msgid "String" +#~ msgstr "String" +#~ msgid "String list editor" +#~ msgstr "String-Listen-Editor" +#~ msgid "String parameter expected" +#~ msgstr "String-Parameter erwartet" +#~ msgid "Stringlist not initialized!" +#~ msgstr "Die String-Liste ist nicht initialisiert!" +#~ msgid "Structure set to %s." +#~ msgstr "Struktur gesetzt auf %s." +#~ msgid "Sub Item &Properties" +#~ msgstr "Eigenschaften des Untereintrags" +#~ msgid "Successful Connection" +#~ msgstr "Erfogreiche Verbindung" +#~ msgid "Successful execution" +#~ msgstr "Ausführung erfolgreich" +#~ msgid "Successfull API call" +#~ msgstr "Erfolgreicher API-Aufruf" +#~ msgid "Switching protocols" +#~ msgstr "Protokollumschaltung" +#~ msgid "Syntax Error - Command not understood: %s" +#~ msgstr "Syntaxfehler - Anweisung unverständlich: %s" +#~ msgid "Syntax error, command unrecognized." +#~ msgstr "Syntaxfehler, Anweisung nicht erkannt" +#~ msgid "" +#~ "System Error. Code: %d.\n" +#~ "%s" +#~ msgstr "" +#~ "Systemfehler. Code: %d.\n" +#~ "%s" +#~ msgid "TAggregateStream Error: no internal streams" +#~ msgstr "TAggregateStream-Fehler: Keine interne Streams" +#~ msgid "TIdIRC 1.061 by Steve Williams" +#~ msgstr "TIdIRC 1.061 von Steve Williams" +#~ msgid "TIdMessagePart can not be created. Use descendant classes. " +#~ msgstr "" +#~ "TIdMessagePart kann nicht erzeugt werden. Verwenden Sie abgeleitete " +#~ "Klassen. " +#~ msgid "TIdSNPP Mess command only supports single line Messages." +#~ msgstr "TIdSNPP-Anweisung Mess unterstützt nur einzeilige Botschaften." +#~ msgid "TMenu.SetForm: argument must be TCustomForm" +#~ msgstr "Das Argument von TMenu.SetForm: muss ein TCustomForm sein" +#~ msgid "TPB Constant (%s) is unknown" +#~ msgstr "TPB-Konstante (%s) ist unbekannt." +#~ msgid "TStrings descendant %s failed to call inherited constructor" +#~ msgstr "" +#~ "Der Nachkomme von TStrings %s konnte den geerbten Konstruktor nicht " +#~ "aufrufen" +#~ msgid "TTL expired." +#~ msgstr "TTL abgelaufen." +#~ msgid "Table/Procedure not found" +#~ msgstr "Tabelle/Prozedur wurde nicht gefunden" +#~ msgid "Te&xt:" +#~ msgstr "Te&xt:" +#~ msgid "Teal" +#~ msgstr "Grünblau" +#~ msgid "Temperature" +#~ msgstr "Temperatur" +#~ msgid "Terminate Thread Timeout" +#~ msgstr "Zeitüberschreitung bei Beenden von Thread" +#~ msgid "Text file (*.txt)|*.txt|Any file (*)|*" +#~ msgstr "Textdatei (*.txt)|*.txt|Alle Dateien (*)|*" +#~ msgid "Text file (*.txt)|*.txt|Any file (*.*)|*.*" +#~ msgstr "Textdatei (*.txt)|*.txt|Alle Dateien (*.*)|*.*" +#~ msgid "Text files (*.txt)|*.txt|All files (*.*)|*.*" +#~ msgstr "Textdateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*" +#~ msgid "" +#~ "Text files (*.txt)|*.txt|Shell scripts (*.sh)|*.sh|Config files (*.conf)|" +#~ "*.conf|All files (*)|*\n" +#~ msgstr "" +#~ "Textdateien (*.txt)|*.txt|Shellskripte (*.sh)|*.sh|Konfigurationsdateien " +#~ "(*.conf)|*.conf|Alle Dateien (*)|*\n" +#~ msgid "" +#~ "Text files (*.txt)|Config files (*.conf)|Shell scripts (*.sh)|All files " +#~ "(*)\n" +#~ msgstr "" +#~ "Textdateien (*.txt)|Konfigurationsdateien (*.conf)|Shellskripte (*.sh)|" +#~ "Alle Dateien (*)\n" +#~ msgid "Text not found: \"%s\"" +#~ msgstr "Text nicht gefunden: \"%s\"" +#~ msgid "The Local Security Authority cannot be contacted" +#~ msgstr "Die lokale Sicherheitsautorität kann nicht kontaktiert werden" +#~ msgid "The buffers supplied to a function was too small." +#~ msgstr "Die der Funktion mitgegebenen Puffer sind zu klein." +#~ msgid "The caller is not the owner of the desired credentials" +#~ msgstr "Der Aufrufer ist nicht der Besitzer der gewünschten Beglaubigung" +#~ msgid "The certificate chain was issued by an untrusted authority." +#~ msgstr "" +#~ "Die Zertifikatskette wurde von einer nicht vertrauenswürdigen Autorität " +#~ "ausgegeben." +#~ msgid "" +#~ "The client and server cannot communicate, because they do not possess a " +#~ "common algorithm." +#~ msgstr "" +#~ "Client und Server können nicht kommunizieren, da sie keinen gemeinsamen " +#~ "Algorithmus besitzen." +#~ msgid "The clocks on the client and server machines are skewed." +#~ msgstr "Die Uhrzeit auf Client und Server ist unterschiedlich." +#~ msgid "The context data must be renegotiated with the peer." +#~ msgstr "Die Kontextdaten müssen mit dem Peer neu ausgehandelt werden." +#~ msgid "The context has expired and can no longer be used." +#~ msgstr "Der Kontext ist abgelaufen und kann nicht mehr verwendet werden." +#~ msgid "The credentials supplied to the package were not recognized" +#~ msgstr "Die Beglaubigungen aus dem Package wurden nicht erkannt" +#~ msgid "" +#~ "The credentials supplied were not complete, and could not be verified. " +#~ "Additional information can be returned from the context." +#~ msgstr "" +#~ "Die aufgeführten Beglaubigungen waren unvollständig und konnten nicht " +#~ "verifiziert werden. Zusatzinformationen können aus dem Kontext " +#~ "zurückgegeben werden." +#~ msgid "" +#~ "The credentials supplied were not complete, and could not be verified. " +#~ "The context could not be initialized." +#~ msgstr "" +#~ "Die aufgeführten Beglaubigungen waren unvollständig und konnten nicht " +#~ "verifiziert werden. Der Kontext konnte nicht initialisiert werden." +#~ msgid "The following SITE commands are supported: HELP DIRSTYLE" +#~ msgstr "Folgende SITE-Anweisungen werden unterstützt: HELP DIRSTYLE" +#~ msgid "" +#~ "The function completed successfully, but CompleteToken must be called" +#~ msgstr "" +#~ "Die Funktion wurde erfolgreich ausgeführt, aber CompleteToken muss " +#~ "aufgerufen werden" +#~ msgid "" +#~ "The function completed successfully, but both CompleteToken and this " +#~ "function must be called to complete the context" +#~ msgstr "" +#~ "Die Funktion wurde erfolgreich ausgeführt, aber CompleteToken als auch " +#~ "diese Funktion müssen aufgerufen werden, um den Kontext zu " +#~ "vervollständigen" +#~ msgid "" +#~ "The function completed successfully, but must be called again to complete " +#~ "the context" +#~ msgstr "" +#~ "Die Funktion wurde erfolgreich ausgeführt, muss aber zur " +#~ "Vervollständigung des Kontexts wieder aufgerufen werden" +#~ msgid "The function requested is not supported" +#~ msgstr "Die angeforderte Funktion wird nicht unterstützt" +#~ msgid "The handle specified is invalid" +#~ msgstr "Das angegebene Handle ist ungültig" +#~ msgid "The logon attempt failed" +#~ msgstr "Der Versuch der Anmeldung ist fehlgeschlagen" +#~ msgid "" +#~ "The logon was completed, but no network authority was available. The " +#~ "logon was made using locally known information" +#~ msgstr "" +#~ "Die Anmeldung wurde durchgeführt, aber es war keine Netzwerk-Autorität " +#~ "verfügbar. Die Anmeldung wurde unter Verwendung lokal bekannter " +#~ "Informationen durchgeführt" +#~ msgid "The message or signature supplied for verification has been altered" +#~ msgstr "" +#~ "Die zur Verifizierung übermittelte Botschaft oder Signatur wurde verändert" +#~ msgid "The message received was unexpected or badly formatted." +#~ msgstr "Die empfangene Botschaft war nicht erwartet oder falsch formatiert." +#~ msgid "The message supplied for verification is out of sequence" +#~ msgstr "" +#~ "Die zur Verifizierung übermittelte Botschaft ist außerhalb der Sequenz" +#~ msgid "" +#~ "The per-message Quality of Protection is not supported by the security " +#~ "package" +#~ msgstr "" +#~ "Der Qualitätsschutz pro Botschaft wird vom Sicherheits-Package nicht " +#~ "unterstützt" +#~ msgid "The received certificate has expired." +#~ msgstr "Das empfangene Zertifikat ist abgelaufen." +#~ msgid "The requested security package does not exist" +#~ msgstr "Das angeforderte Sicherheits-Package existiert nicht" +#~ msgid "" +#~ "The security context could not be established due to a failure in the " +#~ "requested quality of service (e.g. mutual authentication or delegation)." +#~ msgstr "" +#~ "Der Sicherheitskontext konnte nicht eingerichtet werden, da Qualität des " +#~ "Service fehlt (z.B. gegenseitige Authentifizierung oder Delegation)." +#~ msgid "The security context does not allow impersonation of the client" +#~ msgstr "Der Sicherheitskontext erlaubt keine Darstellung des Client" +#~ msgid "The security package failed to initialize, and cannot be installed" +#~ msgstr "" +#~ "Das Sicherheits-Package konnte nicht initialisiert werden und kann nicht " +#~ "installiert werden" +#~ msgid "" +#~ "The security package is not able to marshall the logon buffer, so the " +#~ "logon attempt has failed" +#~ msgstr "" +#~ "Das Sicherheits-Package kann den Anmelde-Puffer nicht einrichten, " +#~ "deswegen ist der Versuch der Anmeldung fehlgeschlagen" +#~ msgid "The specified data could not be decrypted." +#~ msgstr "Die angegebenen Daten konnten nicht entschlüsselt werden." +#~ msgid "The specified data could not be encrypted." +#~ msgstr "Die angegebenen Daten konnten nicht verschlüsselt werden." +#~ msgid "The specified target is unknown or unreachable" +#~ msgstr "Das angegebene Ziel ist unbekannt oder nicht erreichbar" +#~ msgid "The string %s does not translate into a valid IP." +#~ msgstr "Zeichenkette %s ergibt keine gültige IP." +#~ msgid "" +#~ "The supplied IP address is not a valid multicast address [224.0.0.0 to " +#~ "239.255.255.255]." +#~ msgstr "" +#~ "Die übermittelte IP-Adresse ist keine gültige Multicast-Adresse " +#~ "[224.0.0.0 bis 239.255.255.255]." +#~ msgid "The supplied message is incomplete. The signature was not verified." +#~ msgstr "" +#~ "Die übermittelte Botschaft ist unvollständig. Die Signatur wurde nicht " +#~ "verifiziert." +#~ msgid "The target principal name is incorrect." +#~ msgstr "Der Ziel-Prinzipalname ist nicht korrekt." +#~ msgid "The token supplied to the function is invalid" +#~ msgstr "Das der Funktion übermittelte Token ist ungültig" +#~ msgid "There is currently no active project." +#~ msgstr "Es gibt momentan kein aktives Projekt." +#~ msgid "There is no LSA mode context associated with this context." +#~ msgstr "Mit diesem Kontext ist kein LSA-Modus-Kontext verknüpft." +#~ msgid "There is no active transaction" +#~ msgstr "Es ist keine Transaktion aktiv" +#~ msgid "" +#~ "There is too many IP addresses in the specified range (%d) to be " +#~ "displayed at design time." +#~ msgstr "" +#~ "Im angegebenen Bereich (%d) gibt es mehr IP-Adressen als zur Entwurfszeit " +#~ "angezeigt werden können." +#~ msgid "This authentication method is already registered with class name %s." +#~ msgstr "" +#~ "Diese Authentifizierungsmethode ist bereits mit Klassennamen %s " +#~ "registriert." +#~ msgid "This function is not supported on Win32." +#~ msgstr "Diese Funktion wird nicht auf Win32 unterstützt." +#~ msgid "This property or method is not implemented in the Open XML Parser" +#~ msgstr "Eigenschaft oder Methode ist nicht im Open XML Parser implementiert" +#~ msgid "Thread" +#~ msgstr "Thread" +#~ msgid "Thread Class Not Specified." +#~ msgstr "Thread-Klasse wurde nicht angegeben." +#~ msgid "Thread Error: %s (%d)" +#~ msgstr "Thread-Fehler: %s (%d)" +#~ msgid "Thread creation error: %s" +#~ msgstr "Fehler beim Erzeugen des Thread: %s" +#~ msgid "Tile &Horizontally" +#~ msgstr "Hori&zontal anordnen" +#~ msgid "Tile Horizontal" +#~ msgstr "Horizontal anordnen" +#~ msgid "Tile Vertical" +#~ msgstr "Vertikal anordnen" +#~ msgid "Time" +#~ msgstr "Uhrzeit" +#~ msgid "TimedOut" +#~ msgstr "TimedOut" +#~ msgid "Timeout occurred waiting for %s to execute" +#~ msgstr "" +#~ "Beim Warten auf die AUsführung von %s ist eine Zeitüberschreitung " +#~ "aufgetreten" +#~ msgid "" +#~ "To add actions to your application simply drag and drop from either " +#~ "Categories or Actions onto an existing ActionBar.\n" +#~ msgstr "" +#~ "Um Akionen zur Applikation hinzuzufügen, ziehen Sie sie einfach mittels " +#~ "Drag&&Drop entweder von den Kategorien oder Aktionen auf ein " +#~ "existierendes ActionBar-Element.\n" +#~ msgid "Toggle" +#~ msgstr "Umschalten" +#~ msgid "Tons" +#~ msgstr "Tonne" +#~ msgid "Too many buttons specified for message box" +#~ msgstr "Bei diesem Meldungsfenster wurden zu viele Schalter angegeben" +#~ msgid "Too many custom variant types have been registered" +#~ msgstr "Es wurden zu viele benutzerdefinierte Variant-Typen registriert" +#~ msgid "Too many levels of remote in path." +#~ msgstr "Zu viele Ebenen von remote in Pfad." +#~ msgid "Too many levels of symbolic links." +#~ msgstr "Zu viele Ebenen von symbolischen Links." +#~ msgid "Too many open files." +#~ msgstr "Zu viele geöffnete Dateien." +#~ msgid "Too many parameters for method %s" +#~ msgstr "Zu viele Parameter für Methode %s" +#~ msgid "Too many parameters in method %s" +#~ msgstr "Zu viele Parameter in Methode %s" +#~ msgid "Too many processes." +#~ msgstr "Zu viele Prozesse." +#~ msgid "Too many references, cannot splice." +#~ msgstr "Zu viele Referenzen; keine Verbindungen möglich." +#~ msgid "Too many users." +#~ msgstr "Zu viele Benutzer." +#~ msgid "Toolb&ars:" +#~ msgstr "&Symbolleisten" +#~ msgid "Toolbars" +#~ msgstr "Symbolleisten" +#~ msgid "Topic Search" +#~ msgstr "Suche über Schlüsselwort" +#~ msgid "Total Response Time:" +#~ msgstr "Antwortzeit, gesamt:" +#~ msgid "Transfer aborted" +#~ msgstr "Transfer abgebrochen" +#~ msgid "Transfer complete" +#~ msgstr "Transfer abgeschlossen" +#~ msgid "Transform failed" +#~ msgstr "Transformation fehlgeschlagen" +#~ msgid "" +#~ "TransformNode most be called using a document node (not a document " +#~ "element) for the source and the stylesheet." +#~ msgstr "" +#~ "TransformNode muss mit einem Dokumentknoten (nicht einem Dokumentelement) " +#~ "für die Quelle und das Stylesheet aufgerufen werden." +#~ msgid "TransformationFile must be specified" +#~ msgstr "TransformationFile muss angegeben werden" +#~ msgid "TreeView Items Editor" +#~ msgstr "TreeView-Eintragseditor" +#~ msgid "" +#~ "Trying to store a string of length %d into a field that can only contain %" +#~ "d" +#~ msgstr "" +#~ "Versuch, String mit der Länge %d in einem Feld zu speichern, das nur %d " +#~ "aufnehmen kann" +#~ msgid "Type" +#~ msgstr "Typ" +#~ msgid "Type cannot be cast as Variant" +#~ msgstr "Typ kann nicht in Variant umgewandelt werden" +#~ msgid "Type mismatch in parameter %d for method %s" +#~ msgstr "Keine Übereinstimmung in Parameter %d für Methode %s" +#~ msgid "Type mismatch in parameter %s" +#~ msgstr "Keine Typübereinstimmung im Parameter %s" +#~ msgid "Type set to %s." +#~ msgstr "Typ auf %s gesetzt." +#~ msgid "UDP Receive Error = 0." +#~ msgstr "UDP Empfangsfehler = 0." +#~ msgid "UKBuckets" +#~ msgstr "UKBuckets" +#~ msgid "UKBushels" +#~ msgstr "Scheffel (UK)" +#~ msgid "UKGallons" +#~ msgstr "Gallone (UK)" +#~ msgid "UKGill" +#~ msgstr "Viertelpinte (UK)" +#~ msgid "UKOunces" +#~ msgstr "Unze (UK)" +#~ msgid "UKPecks" +#~ msgstr "Viertelscheffel (UK)" +#~ msgid "UKPints" +#~ msgstr "Pinte (UK)" +#~ msgid "UKPottle" +#~ msgstr "Pottle (UK)" +#~ msgid "UKQuarts" +#~ msgstr "Quart (UK)" +#~ msgid "UUCP subsystem" +#~ msgstr "UUCP-Subsystem" +#~ msgid "Unable to Find Procedure %s" +#~ msgstr "Prozedur %s nicht gefunden" +#~ msgid "Unable to Load %s" +#~ msgstr "%s kann nicht geladen werden" +#~ msgid "Unable to Open Metadata" +#~ msgstr "Metadaten können nicht geöffnet werden" +#~ msgid "Unable to complete write request, progress halted at %d bytes" +#~ msgstr "" +#~ "Die Schreibanforderung konnte nicht abgeschlossen werden, der Fortschritt " +#~ "wurde bei %d Byte angehalten" +#~ msgid "Unable to create directory \"%s\"." +#~ msgstr "Verzeichnis \"%s\" kann nicht angelegt werden." +#~ msgid "Unable to execute %s" +#~ msgstr "%s kann nicht ausgeführt werden" +#~ msgid "Unable to execute Query" +#~ msgstr "Abfrage kann nicht ausgeführt werden" +#~ msgid "" +#~ "Unable to execute command, wrong connection state;Current connection " +#~ "state: %s." +#~ msgstr "" +#~ "Anweisung kann nicht ausgeführt werden, falscher Verbindungsstatus;" +#~ "aktueller Verbindungsstatus: %s." +#~ msgid "Unable to find a Table of Contents" +#~ msgstr "Inhaltsverzeichnis konnte nicht gefunden werden" +#~ msgid "Unable to initialize compressor" +#~ msgstr "Kompressor kann nicht initialisiert werden" +#~ msgid "Unable to initialize decompressor" +#~ msgstr "Dekompressor kann nicht initialisiert werden" +#~ msgid "Unable to load WSDL File/Location: %s. Error [%s]" +#~ msgstr "WSDL-Datei/-Ort kann nicht geladen werden: %s.\tFehler [%s]" +#~ msgid "Unable to locate form/component, '%s'" +#~ msgstr "Formular/Komponente '%s' nicht gefunden" +#~ msgid "Unable to locate property '%s' on component '%s'" +#~ msgstr "Eigenschaft '%s' in Komponente '%s' nicht gefunden" +#~ msgid "Unable to move %s to %s" +#~ msgstr "%s kann nicht nach %s verschoben werden" +#~ msgid "Unable to not open registry key: %s" +#~ msgstr "Der Registrierungsschlüssel %s kann nicht geöffnet werden" +#~ msgid "Unable to open %s" +#~ msgstr "%s kann nicht geöffnet werden" +#~ msgid "Unable to read directory \"%s\"." +#~ msgstr "Verzeichnis \"%s\" kann nicht gelesen werden." +#~ msgid "" +#~ "Unable to retrieve the URL endpoint for Service/Port '%s'/'%s' from WSDL " +#~ "'%s'" +#~ msgstr "" +#~ "URL-Endpunkt für Service/Port '%s'/'%s' kann nicht von WSDL '%s' gelesen " +#~ "werden" +#~ msgid "Unable to save settings" +#~ msgstr "Einstellungen konnten nicht gespeichert werden" +#~ msgid "Unable to stop client thread" +#~ msgstr "Client-Thread kann nicht angehalten werden" +#~ msgid "Unable to write bitmap" +#~ msgstr "Bitmap kann nicht geschrieben werden" +#~ msgid "Unassigned variant value" +#~ msgstr "Nicht zugewiesener Variant-Wert" +#~ msgid "Unauthorized" +#~ msgstr "Nicht autorisiert" +#~ msgid "Underline" +#~ msgstr "Unterstrichen" +#~ msgid "Undo|Reverts the last action" +#~ msgstr "Rückgängig|Letzte Aktuion rückgängig machen" +#~ msgid "Uneven size in DecodeToStream." +#~ msgstr "Ungleichmäßige Größe in DecodeToStream." +#~ msgid "Uneven size in Encode." +#~ msgstr "Ungleichmäßige Größe in Encode." +#~ msgid "Unexpected characters" +#~ msgstr "Unerwartete Zeichen" +#~ msgid "Unexpected end of string [%s]" +#~ msgstr "Unerwartetes Ende des Strings [%s]" +#~ msgid "Unexpected error occurred executing %s" +#~ msgstr "Bei der Ausführung von %s ist ein Fehler aufgetreten" +#~ msgid "Unexpected message arrived to an interface that is not listening" +#~ msgstr "" +#~ "Eine unerwartete Botschaft kam bei einem Interface an, das nicht " +#~ "empfangsbereit ist." +#~ msgid "Unexpected onError return value" +#~ msgstr "Unerwarteter Rückgabewert von onError" +#~ msgid "Unexpected onStatus return value" +#~ msgstr "Unerwarteter Rückgabewert von onStatus" +#~ msgid "Unexpected operation from %s:%d" +#~ msgstr "Unerwartete Operation von %s:%d" +#~ msgid "Unexpected parameter type" +#~ msgstr "Unerwarteter Parametertyp" +#~ msgid "Unexpected return type" +#~ msgstr "Unerwarteter Rückgabetyp" +#~ msgid "Unexpected script error" +#~ msgstr "Unerwarteter Script-Fehler" +#~ msgid "Unexpected variant error" +#~ msgstr "Unerwarteter Variant-Fehler" +#~ msgid "Unexpected variant or safe array error: %s%.8x" +#~ msgstr "Unerwarteter Fehler bei Variante oder sicherem Array: %s%.8x" +#~ msgid "Unhandled Xerces DOM error (no message available): %d" +#~ msgstr "Unbehandelter Xerces-DOM-Fehler (keine Meldung verfügbar): %d" +#~ msgid "Uninstall File Name is not set" +#~ msgstr "Dateiname für die Deinstallation ist nicht gesetzt" +#~ msgid "Unknown" +#~ msgstr "Unbekannt" +#~ msgid "Unknown Adapter mode: %s" +#~ msgstr "Unbekannter Adaptermodus: %s" +#~ msgid "Unknown Error" +#~ msgstr "Unbekannter Fehler" +#~ msgid "Unknown Error - Can't retrieve plan" +#~ msgstr "Unbekannter Fehler - Plan kann nicht ermittelt werden" +#~ msgid "Unknown FTP listing format" +#~ msgstr "Unbekanntes FTP-Listenformat" +#~ msgid "Unknown Message Part Type." +#~ msgstr "Unbekannter Typ von Botschaftsteil." +#~ msgid "Unknown Response Code" +#~ msgstr "Unbekannter Antwort-Code" +#~ msgid "Unknown SOAPAction %s" +#~ msgstr "Unbekannte SOAP-Aktion %s" +#~ msgid "Unknown Type" +#~ msgstr "Unbekannter Typ" +#~ msgid "Unknown command" +#~ msgstr "Unbekannte Anweisung" +#~ msgid "Unknown conversion family %s" +#~ msgstr "Unbekannte Konvertierungsfamilie %s" +#~ msgid "Unknown conversion type %s" +#~ msgstr "Unkannter Konvertierungstyp %s" +#~ msgid "Unknown credentials use" +#~ msgstr "Verwendung unbekannter Beglaubigung" +#~ msgid "Unknown custom variant type ($%.4x)" +#~ msgstr "Unbekannter benutzerdefinierter Variant-Typ ($%.4x)" +#~ msgid "Unknown datatype \"%s\"" +#~ msgstr "Unbekannter Datentyp \"%s\"" +#~ msgid "Unknown mode" +#~ msgstr "Unbekannter Modus" +#~ msgid "Unknown or illegale facility code" +#~ msgstr "Unbekannter oder ungültiger Facility-Code" +#~ msgid "Unknown or illegale security code" +#~ msgstr "Unbekannter oder ungültiger Sicherheits-Code" +#~ msgid "" +#~ "Unknown or other error: Can not determine owner, other error, or the " +#~ "error can not be revealed." +#~ msgstr "" +#~ "Unbekannter oder anderer Fehler: Der Besitzer oder anderer Fehler kann " +#~ "nicht festgelegt werden oder der Fehler kann nicht angezeigt werden." +#~ msgid "Unknown queue %s" +#~ msgstr "Unbekannte Warteschlange %s" +#~ msgid "Unknown socks error." +#~ msgstr "Unbekannter SOCKS-Fehler." +#~ msgid "Unknown user name" +#~ msgstr "Unbekannter Benutzername" +#~ msgid "Unnamed" +#~ msgstr "Unbenannt" +#~ msgid "Unrecognized IMAP4 Response Header." +#~ msgstr "Nicht erkannter IMAP4-Response-Header." +#~ msgid "" +#~ "Unrecognized POP3 Response Header:\n" +#~ "\"%s\"" +#~ msgstr "" +#~ "Nicht erkannter POP3-Response-Header:\n" +#~ "\"%s\"" +#~ msgid "Unrecognized UUE encoding scheme." +#~ msgstr "Nicht erkannter UUE-Codierungsschema." +#~ msgid "Unrecognized content trasnfer encoding." +#~ msgstr "Nicht erkannte Inhalts-Transfer-Codierung." +#~ msgid "Unrecognized movie format" +#~ msgstr "Unbekanntes Filmformat" +#~ msgid "Unsupported Media Type" +#~ msgstr "Nicht unterstützter Medientyp" +#~ msgid "Unsupported SOAP encodingStyle %s" +#~ msgstr "Nicht unterstützter SOAP-Codierungsstil %s" +#~ msgid "Unsupported authorization scheme." +#~ msgstr "Nicht unterstütztes Autorisierungs-Schema." +#~ msgid "Unsupported calling convention: %s" +#~ msgstr "Nicht unterstützte Aufrufkonvention: %s" +#~ msgid "Unsupported character encoding \"%s\", try using LoadFromFile" +#~ msgstr "" +#~ "Nicht unterstützte Zeichencodierung \"%s\", versuchen Sie LoadFromFile" +#~ msgid "" +#~ "Unsupported hash algorithm. This implementation supports only MD5 " +#~ "encoding." +#~ msgstr "" +#~ "Nicht unterstützter Hash-Algorithmus. Die Implementierung unterstützt nur " +#~ "MD5-Codierung." +#~ msgid "" +#~ "Unsupported object type. You can assign only one of the following types " +#~ "or thir descendants: TStrings, TStream." +#~ msgstr "" +#~ "Nicht unterstützter Objekttyp. Sie können nur einen der folgenden Typen " +#~ "oder deren Nachkommen zuweisen: TStrings, TStream." +#~ msgid "Unsupported transfer mode: \"%s\"" +#~ msgstr "Nicht unterstützter Transfer-Modus: \"%s\"" +#~ msgid "Unsuppported variant type %d" +#~ msgstr "Nicht unterstützter Variant-Typ %d" +#~ msgid "Up one directory" +#~ msgstr "Ein Verzeichnis nach oben" +#~ msgid "" +#~ "Up to
        %0:s\n" +#~ "
          " +#~ msgstr "" +#~ "Bis zu %0:s\n" +#~ "
            " +#~ msgid "" +#~ "Up to root directory\n" +#~ "
              " +#~ msgstr "" +#~ "Bis zu Stammverzeichnis\n" +#~ "
                " +#~ msgid "Update Error - %s" +#~ msgstr "Fehler bei der Aktualisierung - %s" +#~ msgid "Uploaded file expected for field %s" +#~ msgstr "Für Feld %s wird eine gesendete Datei erwartet" +#~ msgid "Use Proxy" +#~ msgstr "Proxy verwenden" +#~ msgid "User logged in, proceed." +#~ msgstr "Benutzer angemeldet, weiter." +#~ msgid "User name okay, need password." +#~ msgstr "Benutzername OK, Passwort wird benötigt." +#~ msgid "User not local, Will forward" +#~ msgstr "Benutzer nicht lokal, wird weitergeleitet" +#~ msgid "UserID not found" +#~ msgstr "Benutzer-ID nicht gefunden" +#~ msgid "UserName" +#~ msgstr "Benutzername" +#~ msgid "Username must not be blank" +#~ msgstr "Benutzername muss angegeben werden" +#~ msgid "Username: " +#~ msgstr "Benutzername: " +#~ msgid "Valid name, no data record (check DNS setup)." +#~ msgstr "Gültiger Name, kein Datensatz (überprüfen Sie das DNS-Setup)." +#~ msgid "Value" +#~ msgstr "Wert" +#~ msgid "Value List editor" +#~ msgstr "Wertlisten-Editor" +#~ msgid "Variable %s is not a container" +#~ msgstr "Variable %s ist kein Container" +#~ msgid "Variable not found: %s" +#~ msgstr "Variable nicht gefunden: %s" +#~ msgid "Variant is empty" +#~ msgstr "Die Variante ist leer" +#~ msgid "Variant operation ran out memory" +#~ msgstr "Speichermangel bei Varinat-Operation" +#~ msgid "Variant or safe array index out of bounds" +#~ msgstr "Variante oder sicherer Array-Index außerhalb des gültigen Bereichs" +#~ msgid "Variant or safe array is locked" +#~ msgstr "Variante oder sicherer Array ist gesperrt" +#~ msgid "Variant overflow" +#~ msgstr "Variant-Überlauf" +#~ msgid "Version %s" +#~ msgstr "Version %s" +#~ msgid "Version 3.0" +#~ msgstr "Version 3.0" +#~ msgid "Version of Transformation File not supported" +#~ msgstr "Version der Umwandlungsdatei wird nicht unterstützt" +#~ msgid "Volume" +#~ msgstr "Volumen" +#~ msgid "WINSOCK DLL Version out of range." +#~ msgstr "Version der WINSOCK-DLL ist außerhalb des gültigen Bereichs." +#~ msgid "WSDL" +#~ msgstr "WSDL" +#~ msgid "WSDL Ports for PortType" +#~ msgstr "WSDL-Ports für PortType" +#~ msgid "WSIL:" +#~ msgstr "WSIL:" +#~ msgid "Warning: warning conditions" +#~ msgstr "Warnung: Warnungszustand" +#~ msgid "Web App Debugger" +#~ msgstr "Web-Anwendungs-Debugger" +#~ msgid "Web App Module Factory already registered." +#~ msgstr "Modul-Factory für Web-Anwendung bereits registriert." +#~ msgid "Web Application Debugger" +#~ msgstr "Debugger für Web-Anwendungen" +#~ msgid "Web Module Factory already registered" +#~ msgstr "Web-Modul-Factory bereits registriert." +#~ msgid "Web Page does not provide content" +#~ msgstr "Web-Seite enthält keinen Inhalt" +#~ msgid "Web Page does not support redirect" +#~ msgstr "Web-Seite unterstützt Umleitungen nicht" +#~ msgid "Web Page not found: %s" +#~ msgstr "Web-Seite nicht gefunden: %s" +#~ msgid "WebAppModule" +#~ msgstr "WebAppModule" +#~ msgid "WebService Listing" +#~ msgstr "WebService-Liste" +#~ msgid "WebService Listing Administrator" +#~ msgstr "Administrator für WebService-Listen" +#~ msgid "WebSnap" +#~ msgstr "WebSnap" +#~ msgid "WebSnap Application" +#~ msgstr "WebSnap-Anwendung" +#~ msgid "WebSnap Data Module" +#~ msgstr "WebSnap-Datenmodul" +#~ msgid "WebSnap Page Module" +#~ msgstr "WebSnap-Seitenmodul" +#~ msgid "Weeks" +#~ msgstr "Woche" +#~ msgid "Welcome to the INDY SMTP Server" +#~ msgstr "Willkommen beim INDY SMTP-Server" +#~ msgid "White" +#~ msgstr "Weiß" +#~ msgid "WideString index out of bounds" +#~ msgstr "WideString-Index außerhalb des gültigen Bereichs" +#~ msgid "Window" +#~ msgstr "Fenster" +#~ msgid "Window Background" +#~ msgstr "Fensterhintergrund" +#~ msgid "Window Frame" +#~ msgstr "Fensterrahmen" +#~ msgid "Window Text" +#~ msgstr "Fenstertext" +#~ msgid "Winshoes LPD Server %s " +#~ msgstr "Winshoes LPD-Server %s " +#~ msgid "Winsock Initialization Error." +#~ msgstr "Fehler bei der Winsock-Initialisierung." +#~ msgid "Winsock not loaded yet." +#~ msgstr "Winsock noch nicht geladen." +#~ msgid "Winsock stack" +#~ msgstr "Winsock-Stack" +#~ msgid "Would you like to reset to the default Priority Schedule?" +#~ msgstr "Wollen Sie auf die Standard-Prioritätenverteilung zurücksetzen?" +#~ msgid "XDR to XML Schema Translator (.xdr <-> .xsd)" +#~ msgstr "Übersetzer XDR nach XML-Schema (.xdr <-> .xsd)" +#~ msgid "XML Parse Error:\n" +#~ msgstr "XML-Auswertungsfehler:\n" +#~ msgid "XML files (*.xml)|*.xml" +#~ msgstr "XML-Dateien (*.xml)|*.xml" +#~ msgid "XMLData to XML Schema Translator (.xml -> .xsd)" +#~ msgstr "Übersetzer XMLData nach XML-Schema (.xml -> .xsd)" +#~ msgid "XMLDataFile must be specified" +#~ msgstr "XMLDataFile muss angegeben werden" +#~ msgid "XP Style" +#~ msgstr "XP-Attribut" +#~ msgid "XTR files (*.xtr)|*.xtr" +#~ msgstr "XTR-Dateien(*.xtr)|*.xtr" +#~ msgid "Yards" +#~ msgstr "Yard" +#~ msgid "Year portion of date too large for conversion" +#~ msgstr "Die Jahreszahl im Datumswert ist zu groß für eine Konvertierung" +#~ msgid "Years" +#~ msgstr "Jahr" +#~ msgid "Yellow" +#~ msgstr "Gelb" +#~ msgid "You are not allowed to delete this item" +#~ msgstr "Sie dürfen diesen Eintrag nicht löschen" +#~ msgid "You cannot send a message while you are still waiting for an answer" +#~ msgstr "" +#~ "Sie können keine Botschaft schicken, während Sie auf eine Antwort warten." +#~ msgid "You cannot set %s while the HL7 Component is working" +#~ msgstr "Sie können %s nicht setzen, während die HL7-Komponente arbeitet" +#~ msgid "You must chain this component to another I/O Handler before using it" +#~ msgstr "" +#~ "Sie müssen diese Komponenten vor ihrer Verwendung an einen anderen I/O-" +#~ "Handler binden" +#~ msgid "ZLib error: target buffer may be too small" +#~ msgstr "Zlib-Fehler: Zielpuffer könnte zu klein sein" +#~ msgid "abort job" +#~ msgstr "Job abbrechen" +#~ msgid "address" +#~ msgstr "Adresse" +#~ msgid "bmp" +#~ msgstr "bmp" +#~ msgid "by DNSName [127.0.0.1] running Indy SMTP" +#~ msgstr "nach DNSName [127.0.0.1] ausgeführt wird Indy SMTP" +#~ msgid "cbxFields" +#~ msgstr "cbxFelder" +#~ msgid "cbxGenerators" +#~ msgstr "cbxGeneratoren" +#~ msgid "clock daemon (1)" +#~ msgstr "Uhrzeit-Daemon (1)" +#~ msgid "clock daemon (2)" +#~ msgstr "Uhrzeit-Daemon (2)" +#~ msgid "closing connection" +#~ msgstr "Verbindung wird geschlossen" +#~ msgid "command must be either USER or QUIT" +#~ msgstr "Anweisung muss entweder USER oder QUIT sein" +#~ msgid "command not recognized" +#~ msgstr "Anweisung nicht erkannt" +#~ msgid "connected with %s" +#~ msgstr "Verbunden mit %s" +#~ msgid "dbExpress Error: Application is not licensed to use this feature" +#~ msgstr "dbExpress-Fehler: Anwendung ist für diese Funktion nicht lizenziert" +#~ msgid "dbExpress Error: Duplicate Transaction ID" +#~ msgstr "dbExpress-Fehler: Doppelte Transaktions-ID" +#~ msgid "dbExpress Error: Insufficient Memory for Operation" +#~ msgstr "dbExpress-Fehler: Nicht genügend Speicher für diese Operation" +#~ msgid "dbExpress Error: Invalid Data Translation" +#~ msgstr "dbExpress-Fehler: Ungültige Übersetzung" +#~ msgid "dbExpress Error: Invalid Field Type" +#~ msgstr "dbExpress-Fehler: Ungültiger Feldtyp" +#~ msgid "dbExpress Error: Invalid Handle" +#~ msgstr "dbExpress-Fehler: Ungültiges Handle" +#~ msgid "dbExpress Error: Invalid Length" +#~ msgstr "dbExpress-Fehler: Ungültige Länge" +#~ msgid "dbExpress Error: Invalid Parameter" +#~ msgstr "dbExpress-Fehler: Ungültiger Parameter" +#~ msgid "dbExpress Error: Invalid Precision" +#~ msgstr "dbExpress-Fehler: Ungültige Genauigkeit" +#~ msgid "dbExpress Error: Invalid Time" +#~ msgstr "dbExpress-Fehler: Ungültiger Zeitwert" +#~ msgid "dbExpress Error: Invalid Transaction ID" +#~ msgstr "dbExpress-Fehler: Ungültige Transaktions-ID" +#~ msgid "dbExpress Error: Invalid Transaction Isolation Level" +#~ msgstr "dbExpress-Fehler: Ungültige Ebene für Transaktionsisolation" +#~ msgid "dbExpress Error: Invalid Username/Password" +#~ msgstr "dbExpress-Fehler: Ungültiger Wert für Anwendername oder Passwort" +#~ msgid "dbExpress Error: Local Transaction already active" +#~ msgstr "dbExpress-Fehler: Lokale Transaktion bereits aktiv" +#~ msgid "dbExpress Error: Multiple Transactions not Enabled" +#~ msgstr "dbExpress-Fehler: Mehrfach-Transaktionen nicht aktiviert" +#~ msgid "dbExpress Error: Operation Not Supported" +#~ msgstr "dbExpress-Fehler: Die Operation wird nicht unterstützt" +#~ msgid "dbExpress Error: Parameter Not Set" +#~ msgstr "dbExpress-Fehler: Parameter ist nicht gesetzt" +#~ msgid "dbExpress Error: Parameter/Column out of Range" +#~ msgstr "dbExpress-Fehler: Parameter/Spalte außerhalb des gültigen Bereichs" +#~ msgid "dbExpress Error: Result set at EOF" +#~ msgstr "dbExpress-Fehler: Ergebnismenge am Dateiende" +#~ msgid "ddd, dd mmm yyyy hh:mm:ss" +#~ msgstr "ttt, tt mmm jjjj hh:mm:ss" +#~ msgid "frmGeneratorEditor" +#~ msgstr "frmGeneratorEditor" +#~ msgid "goColMoving is not a supported option" +#~ msgstr "goColMoving wird nicht unterstützt" +#~ msgid "http://www.nevrona.com/indy/" +#~ msgstr "http://www.nevrona.com/indy/" +#~ msgid "kernel messages" +#~ msgstr "Kernel-Botschaften" +#~ msgid "line" +#~ msgstr "Zeile" +#~ msgid "line printer subsystem" +#~ msgstr "Zeilendrucker-Untersystem" +#~ msgid "lines" +#~ msgstr "Zeilen" +#~ msgid "local use 0 (local0)" +#~ msgstr "Lokale Verwendung 0 (local0)" +#~ msgid "local use 1 (local1)" +#~ msgstr "Lokale Verwendung 1 (local1)" +#~ msgid "local use 2 (local2)" +#~ msgstr "Lokale Verwendung 2 (local2)" +#~ msgid "local use 3 (local3)" +#~ msgstr "Lokale Verwendung 3 (local3)" +#~ msgid "local use 4 (local4)" +#~ msgstr "Lokale Verwendung 4 (local4)" +#~ msgid "local use 5 (local5)" +#~ msgstr "Lokale Verwendung 5 (local5)" +#~ msgid "local use 6 (local6)" +#~ msgstr "Lokale Verwendung 6 (local6)" +#~ msgid "local use 7 (local7)" +#~ msgstr "Lokale Verwendung 7 (local7)" +#~ msgid "log alert" +#~ msgstr "Protokollalarm" +#~ msgid "log audit" +#~ msgstr "Protokollüberprüfung" +#~ msgid "mail system" +#~ msgstr "Mail-System" +#~ msgid "messages generated internally by syslogd" +#~ msgstr "Botschaften, die intern von syslogd generiert werden" +#~ msgid "method not supported" +#~ msgstr "Methode nicht unterstützt" +#~ msgid "network news subsystem" +#~ msgstr "Netzwerknachrichtensystem" +#~ msgid "open" +#~ msgstr "&Ausführen..." +#~ msgid "security/authorization messages (1)" +#~ msgstr "Sicherheits-/Autorisierungsbotschaften (1)" +#~ msgid "security/authorization messages (2)" +#~ msgstr "Sicherheits-/Autorisierungsbotschaften (2)" +#~ msgid "server not responding" +#~ msgstr "Server antwortet nicht." +#~ msgid "sigaction call failed" +#~ msgstr "sigaction call failed" +#~ msgid "system daemons" +#~ msgstr "System-Daemone" +#~ msgid "txt" +#~ msgstr "txt" +#~ msgid "unknown" +#~ msgstr "Unbekannt" +#~ msgid "user-level messages" +#~ msgstr "Botschaften auf Benutzerebene" +#~ msgid "username" +#~ msgstr "Benutzername" +#~ msgid "varDate type not supported" +#~ msgstr "Typ varDate wird nicht unterstützt" +#~ msgid "varDispatch type not supported" +#~ msgstr "Typ varDispatch wird nicht unterstützt" +#~ msgid "varError type not supported" +#~ msgstr "Typ varError wird nicht unterstützt" +#~ msgid "varVariant type not supported" +#~ msgstr "Typ varVariant wird nicht unterstützt" +#~ msgid "xml" +#~ msgstr "xml" +#~ msgid "xtr" +#~ msgstr "xtr" + diff --git a/win32/gui-2/locale/de/LC_MESSAGES/gpsbabel.po b/win32/gui-2/locale/de/LC_MESSAGES/gpsbabel.po new file mode 100644 index 000000000..ce9ae415f --- /dev/null +++ b/win32/gui-2/locale/de/LC_MESSAGES/gpsbabel.po @@ -0,0 +1,498 @@ +msgid "" +msgstr "" +"Project-Id-Version: GPSBabel command line program\n" +"POT-Creation-Date: 2005-11-19 01:14\n" +"PO-Revision-Date: 2008-04-26 21:18+0100\n" +"Last-Translator: oliskoli \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2.1\n" +"Language-Team: \n" +"X-Poedit-SourceCharset: iso-8859-1\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" + +msgid "(integer sec or 'auto') Barograph to GPS time diff" +msgstr "Zeitdifferent zwischen Barograph und GPS (ganzz. Sekunden oder 'auto')" + +msgid "(USR input) Break segments into separate tracks" +msgstr "USR Eingabe: Segmente in seperate Tracks aufteilen" + +msgid "(USR output) Merge into one segmented track" +msgstr "USR-Ausgabe: zu einem segmentierten Track zusammenfassen" + +msgid "Ad-hoc closed icon name" +msgstr "Icon allgemein für \"geschlossen\"" + +msgid "Ad-hoc open icon name" +msgstr "Icon allgemein für \"offen\"" + +msgid "After output job done sleep n second(s)" +msgstr "Pausiere im Anschluß n sekunde(n)" + +msgid "Allow whitespace synth. shortnames" +msgstr "Erlaube Leerzeichen in Kurznamen" + +msgid "Altitudes are absolute and not clamped to ground" +msgstr "Absolute Höhenangaben (nicht bodenverbunden)" + +msgid "Append icon_descr to description" +msgstr "Erweitere Beschreibung um Symbolbeschreibung" + +msgid "Append realtime positioning data to the output file instead of truncating" +msgstr "" + +msgid "Base URL for link tag in output" +msgstr "Basis-URL für Verknüpfungseintrag " + +msgid "Basename prepended to URL on output" +msgstr "Basis-Adresse für erzeugte URL's" + +msgid "Bitmap of categories" +msgstr "Mehrfachkategorie, als Dezimal- oder Hexadezimalwert" + +msgid "Category name (Cache)" +msgstr "Kategoriename (Cache)" + +msgid "Category number to use for written waypoints" +msgstr "Benutze Kategorie # beim Schreiben von Wegpunkten (1..16)" + +msgid "Color for lines or mapnotes" +msgstr "Farbe für Linien oder Kartenangaben" + +msgid "Command unit to power itself down" +msgstr "Gerät im Anschluß abschalten" + +msgid "Complete date-free tracks with given date (YYYYMMDD)." +msgstr "Komplettiere Tracks ohne Datumsangaben mit Datum ... (YYYYMMDD)" + +msgid "Create unique waypoint names (default = yes)" +msgstr "Erzeuge eindeutige Wegpunktnamen (Vorgabe: JA)" + +msgid "Create waypoints from geocache log entries" +msgstr "Erzeuge Wegpunkte aus Geocache Log-Einträgen" + +msgid "Database name" +msgstr "Interner Name für die Palm/OS Datenbank" + +msgid "Database name (filename)" +msgstr "Datenbankname (Dateiname)" + +msgid "Datum (default=NAD27)" +msgstr "GPS-Datum (Vorgabe: NAD27)" + +msgid "Days after which points are considered old" +msgstr "Anzahl an Tagen, nach denen Punkte als alt betrachtet werden" + +msgid "Decimal seconds to pause between groups of strings" +msgstr "Pause (in Sekunden) zwischen Zeilengruppen" + +msgid "Default category on output" +msgstr "Standardkategorie beim Schreiben" + +msgid "Default category on output (1..16)" +msgstr "Standard Kategorie (1..16)" + +msgid "Default icon name" +msgstr "Standard Symbol" + +msgid "Default location" +msgstr "Vorgabestandort" + +msgid "Default proximity" +msgstr "Vorgabe-Annäherungsabstand" + +msgid "Default speed" +msgstr "Standardgeschwindigkeit" + +msgid "Default speed for waypoints (knots/hr)" +msgstr "Vorgabegeschwindigkeit (Knoten/h)" + +msgid "Degrees output as 'ddd', 'dmm'(default) or 'dms'" +msgstr "Schreibe Gradangaben in 'ddd', 'dmm' (Vorgabe) oder 'dms' (Gitter)" + +msgid "Delete all routes" +msgstr "Lösche alle Routen" + +msgid "Delete all track points" +msgstr "Lösche alle Trackpunkte" + +msgid "Delete all waypoints" +msgstr "Lösche alle Wegpunkte" + +msgid "Display labels on track and routepoints (default = 1)" +msgstr "Zeige Beschriftung bei Track- und Routenpunkten (Vorgabe: 1)" + +msgid "Distance unit [m=metric, s=statute]" +msgstr "Entfernungsangaben [m=Metrisch, s=Statute]" + +msgid "Do not add geocache data to description" +msgstr "Keine Geocache-Daten zur Beschreibung hinzufügen" + +msgid "Do not add URLs to description" +msgstr "Hänge keine URL's an die Beschreibung an" + +msgid "Don't show gpi bitmap on device" +msgstr "Zeige keine Bitmap (Icon) auf dem GPS" + +msgid "Draw extrusion line from trackpoint to ground" +msgstr "Zeichne eine Verbindungslinie vom Trackpunkt zum Erdboden" + +msgid "Drop route points that do not have an equivalent waypoint (hidden points)" +msgstr "Lösche versteckte Wegpunkte (automatisch berechnete Routenpunkte)" + +msgid "Enable alerts on speed or proximity distance" +msgstr "Aktiviere Alarm für Annäherung and Geschwindigkeit" + +msgid "Encrypt hints using ROT13" +msgstr "Verschlüsselung mit ROT13" + +msgid "Encrypt hints with ROT13" +msgstr "Verschlüsselung mit ROT13" + +msgid "Erase device data after download" +msgstr "Nach Download Daten auf dem Gerät löschen" + +msgid "Export linestrings for tracks and routes" +msgstr "Exportiere Linendaten (linestrings) für Tracks und Routen (Vorgabe: JA)" + +msgid "Export placemarks for tracks and routes" +msgstr "Exportiere Markierungen für Tracks und Routen" + +msgid "Full path to XCSV style file" +msgstr "Pfad zur 'XCSV-Style'-Datei" + +msgid "Generate # points" +msgstr "Erzeuge # Punkte" + +msgid "Generate file with lat/lon for centering map" +msgstr "Erzeuge Datei mit Breiten- und Längengradwerten (für Kartenzentrierung)" + +msgid "Give points (waypoints/route points) a default radius (proximity)" +msgstr "Gebe Wegpunkten/Routenpunkten diesen Radius " + +msgid "GPS datum (def. WGS 84)" +msgstr "GPS-Datum (Vorgabe: WGS 84)" + +msgid "Height in pixels of map" +msgstr "Kartenhöhe in Pixel" + +msgid "Ignore event marker icons on read" +msgstr "Ignoriere Ereignis-Icons beim Lesen" + +msgid "Include extended data for trackpoints (default = 1)" +msgstr "Erweiterte Daten in Trackpoints mit einbeziehen (Vorgabe = 1)" + +msgid "Include groundspeak logs if present" +msgstr "Groundspeak Log's beifügen (wenn vorhandan)" + +msgid "Include major turn points (with description) from calculated route" +msgstr "Beziehe Hauptrichtungsänderungen (Ansage vorhanden) mit ein" + +msgid "Include only via stations in route" +msgstr "Übernehme nur Stationspunkte ('viastations') der Route" + +msgid "Include short name in bookmarks" +msgstr "Übernehme Kurznamen in Lesezeichen" + +msgid "Index of name field in .dbf" +msgstr "Index des Namensfeldes innerhalb der .dbf" + +msgid "Index of route (if more the one in source)" +msgstr "Index des Route (falls mehrere im Eingabeformat)" + +msgid "Index of route to write (if more the one in source)" +msgstr "Routen-Index (wenn mehrere vorhanden)" + +msgid "Index of route/track to write (if more the one in source)" +msgstr "Route oder Track-Index (wenn mehrere vorhanden)" + +msgid "Index of track (if more the one in source)" +msgstr "Index des Tracks (falls mehrere im Eingabeformat)" + +msgid "Index of track to write (if more the one in source)" +msgstr "Track-Index (wenn mehrere vorhanden)" + +msgid "Index of URL field in .dbf" +msgstr "Index der URL innerhalb der .dbf" + +msgid "Indicate direction of travel in track icons (default = 0)" +msgstr "Erzeuge spezielle Icons (Richtungspfeile)" + +msgid "Infrastructure closed icon name" +msgstr "Icon \"Komplex (Infrastruktur) geschlossen\"" + +msgid "Infrastructure open icon name" +msgstr "Icon \"Komplex (Infrastruktur) offen\"" + +msgid "Keep turns if simplify filter is used" +msgstr "Erhalte Abbiegungen bei Benutzung des Simplify-Filters (Vereinfachen)" + +msgid "Length of generated shortnames" +msgstr "Maximale Länge der generierten Kurznamen" + +msgid "Length of generated shortnames (default 16)" +msgstr "Maximale Länge der zu generierten Kurznamen" + +msgid "Line color, specified in hex AABBGGRR" +msgstr "Linienfarbe (hex. Angabe in Form AABBGGRR)" + +msgid "Make synth. shortnames unique" +msgstr "Eindeutige Kurznamen erzeugen" + +msgid "MapSend version TRK file to generate (3,4)" +msgstr "Generiere TRK-Datei in MapSend-Version # (3,4)" + +msgid "Margin for map. Degrees or percentage" +msgstr "Begrenzung der Karte (in Grad oder Prozent)" + +msgid "Marker type for new points" +msgstr "Markierungstyp für neue Punkte" + +msgid "Marker type for old points" +msgstr "Markierungstyp für alte Punkte" + +msgid "Marker type for unfound points" +msgstr "Markierungstyp für nicht gefundene Punkte" + +msgid "Max length of waypoint name to write" +msgstr "Max. Länge der zu schreibenden Wegpunktnamen" + +msgid "Max number of comments to write (maxcmts=200)" +msgstr "Maximale Anzahl an Kommentaren für die Ausgabe" + +msgid "Max shortname length when used with -s" +msgstr "Maximale Länge der generierten Kurznamen" + +msgid "Max synthesized shortname length" +msgstr "Maximale Länge der generierten Kurznamen" + +msgid "Merge output with existing file" +msgstr "Ausgabe in existierende Datei einfügen" + +msgid "MTK compatible CSV output file" +msgstr "Ausgabe-CSV-Datei kompatibel zum MTK-Datalogger" + +msgid "Name of the 'unassigned' category" +msgstr "Name der 'unassigned'-Kategorie" + +msgid "New name for the route" +msgstr "Name der neuen Route" + +msgid "No separator lines between waypoints" +msgstr "keine Trennlinien zwischen den Wegpunkten" + +msgid "No whitespace in generated shortnames" +msgstr "Leerzeichen in Kurznamen unterdrücken" + +msgid "Non-stealth encrypted icon name" +msgstr "Sichtbar verschlüsselter Symbolname" + +msgid "Non-stealth non-encrypted icon name" +msgstr "Sichtbar und unverschlüsselter Symbolname" + +msgid "Numeric value of bitrate (baud=4800)" +msgstr "Baudrate (Vorgabe: 4800)" + +msgid "Omit Placer name" +msgstr "Placername auslassen" + +msgid "Only read turns; skip all other points" +msgstr "Lese nur Abbiegungen und ignoriere alle sonstigen Punkte" + +msgid "Path to HTML style sheet" +msgstr "Pfad zum HTML-Style-Sheet" + +msgid "Precision of coordinates" +msgstr "Präzision der Koordinaten (Anzahl Nachkommastellen)" + +msgid "Proximity distance" +msgstr "Standardmäßiger Annäherungsabstand" + +msgid "Radius for circles" +msgstr "Kreisradius" + +msgid "Radius of our big earth (default 6371000 meters)" +msgstr "Erdradius in Meter (Vorgabe: 6371000 Meter)" + +msgid "Read control points as waypoint/route/none" +msgstr "Lese Kontrollpunkte als Wegpunkt/Route/nichts" + +msgid "Read/Write date format (i.e. DDMMYYYY)" +msgstr "Datumsformat für Ein-/Ausgabe (z.B. DDMMYYYY)" + +msgid "Read/Write date format (i.e. yyyy/mm/dd)" +msgstr "Datumsformat (z.B. DD.MM.YYYY)" + +msgid "Read/write GPGGA sentences" +msgstr "Schreibe/Lese GPGGA Sequenzen" + +msgid "Read/write GPGSA sentences" +msgstr "Schreibe/Lese GPGSA Sequenzen" + +msgid "Read/write GPRMC sentences" +msgstr "Schreibe/Lese GPRMC Sequenzen" + +msgid "Read/write GPVTG sentences" +msgstr "Schreibe/Lese GPVTG Sequenzen" + +msgid "Read/Write time format (i.e. HH:mm:ss xx)" +msgstr "Zeitformat (z.B. HH:mm:ss xx)" + +msgid "Retain at most this number of position points (0 = unlimited)" +msgstr "Behalte höchstens diese Anzahl an Positionspunkten (0 = kein Limit)" + +msgid "Return current position as a waypoint" +msgstr "Übertrage aktuelle Position als Wegpunkt" + +msgid "Road type changes" +msgstr "Straßentyp-Wechsel" + +msgid "Set waypoint name to source filename." +msgstr "Erzeuge den Wegpunktnamen an Hand des Dateinames" + +msgid "Shortname is MAC address" +msgstr "Kurzname ergibt sich aus MAC-Adresse" + +msgid "Speed in bits per second of serial port (baud=4800)" +msgstr "Übertragungsrate des seriellen Ports in Bits/Sekunde (Vorgabe: baud=4800)" + +msgid "Split input into separate files" +msgstr "Teile gelesene Daten in seperate Dateien" + +msgid "Split into multiple routes at turns" +msgstr "Route an Abbiegungen teilen" + +msgid "Starting seed of the internal number generator" +msgstr "Startwert für internen Zufallszahlengenerator" + +msgid "Stealth encrypted icon name" +msgstr "Unsichtbar verschlüsselter Symbolname" + +msgid "Stealth non-encrypted icon name" +msgstr "Unsichtbarer unverschlüsselter Symbolname" + +msgid "String to separate concatenated address fields (default=\", \")" +msgstr "Trennzeichen für zusammengefügte Adressfelder (Vorgabe: \", \")" + +msgid "Suppress labels on generated pins" +msgstr "Unterdücke Kennzeichnung für erzeugte Pins" + +msgid "Suppress retired geocaches" +msgstr "Unterdrücke zurückgezogene (?) Geocaches" + +msgid "Suppress separator lines between waypoints" +msgstr "Keine Trennlinien zwischen den Wegpunkten" + +msgid "Suppress use of handshaking in name of speed" +msgstr "Kein 'Handshaking' (im Namen der Geschwindigkeit)" + +msgid "Suppress whitespace in generated shortnames" +msgstr "Keine Leerzeichen in Kurznamen" + +msgid "Symbol to use for point data" +msgstr "Symbol für Punkte" + +msgid "Sync GPS time to computer time" +msgstr "Synchronisiere PC-Uhr mit dem GPS (PC -> GPS)" + +msgid "Synthesize track times" +msgstr "Erzeuge Tracknamen" + +msgid "Target GPX version for output" +msgstr "Schreibe in GPX-Version (1.0 oder 1.1)" + +msgid "Temperature unit [c=Celsius, f=Fahrenheit]" +msgstr "Temperatureinheit [c=Celsius, F=Fahrenheit]" + +msgid "The icon description is already the marker" +msgstr "Die Symbolbeschreibung ist bereits die Markierung" + +msgid "Treat waypoints as icons on write" +msgstr "Behandle Wegpunkte als Icons beim Schreiben" + +msgid "Type of .an1 file" +msgstr ".an1 Dateityp" + +msgid "Units for altitude (f)eet or (m)etres" +msgstr "Höhenangaben in Fuß oder Meter ('f' oder 'm')" + +msgid "Units used for names with @speed ('s'tatute or 'm'etric)" +msgstr "Einheit für Geschwindigkeit in Wegpunkten [...@30] ( 's'tatute oder 'm'etrisch)" + +msgid "Units used when writing comments ('s'tatute or 'm'etric)" +msgstr "Einheit innerhalb von Kommentaren ( 's'tatute oder 'm'etrisch)" + +msgid "UPPERCASE synth. shortnames" +msgstr "Erzeuge Kurznamen in Großbuchstaben" + +msgid "Use depth values on output (default is ignore)" +msgstr "Tiefenangaben mit ausgeben (normalerweise ausgeschaltet)" + +msgid "Use proximity values on output (default is ignore)" +msgstr "Benutze Proximity-Werte bei der Ausgabe (Vorgabe: NEIN)" + +msgid "Use shortname instead of description" +msgstr "Benutze den Kurznamen anstelle der Beschreibung" + +msgid "Use specified bitmap on output" +msgstr "Benutze spezifische Bitmap (.BMP) für die Ausgabe" + +msgid "Version of gdb file to generate (1..3)" +msgstr "Schreibe GDB-Version 1, 2 oder 3" + +msgid "Version of mapsource file to generate (3,4,5)" +msgstr "Schreibe MapSource Datei in Version ... (3,4 oder 5)" + +msgid "Waypoint background color" +msgstr "Wegpunkt Hintergrundfarbe" + +msgid "Waypoint foreground color" +msgstr "Wegpunkt Vordergrundfarbe" + +msgid "Waypoint type" +msgstr "Wegpunkt Typ" + +msgid "Width in pixels of map" +msgstr "Kartenbreite in Pixel" + +msgid "Width of lines, in pixels" +msgstr "Linienhöhe in Pixel" + +msgid "Write additional node tag key/value pairs" +msgstr "Schreibe zusätzliche Wegpunkt (node) Informationspaare (tags)" + +msgid "Write additional way tag key/value pairs" +msgstr "Schreibe zusätzliche Routen (way) Informationspaare (tags)" + +msgid "Write all tracks into one file" +msgstr "Schreibe alle Tracks in eine Datei" + +msgid "Write description to address field" +msgstr "Platziere die Beschreibung im Adressfeld" + +msgid "Write each waypoint in a separate file" +msgstr "Schreibe jeden Wegpunkt in eine separate Datei" + +msgid "Write notes to address field" +msgstr "Schreibe Kommentar (Notizen) in das Adressfeld" + +msgid "Write position to address field" +msgstr "Platziere die Koordinaten im Adressfeld" + +msgid "Write position using this grid." +msgstr "Erzeuge Koordinaten unter Benutzung dieses Gitters (Grids)." + +msgid "Write timestamps with offset x to UTC time" +msgstr "Schreibe Zeitstempel relativ zur UTC + x" + +msgid "Write tracks compatible with Carto Exploreur" +msgstr "Erzeuge Tracks ohne Titel (kompatibel zu \"Carto Exploreur\")" + +msgid "Write tracks for Gisteq Phototracker" +msgstr "Schreibe Tracks für \"Gisteq Phototracker\"" + +msgid "Zoom level to reduce points" +msgstr "Vergrößerungsfakter um Punkte zu unterdrücken" + diff --git a/win32/gui-2/locale/es/LC_MESSAGES/default.po b/win32/gui-2/locale/es/LC_MESSAGES/default.po new file mode 100644 index 000000000..0131592b7 --- /dev/null +++ b/win32/gui-2/locale/es/LC_MESSAGES/default.po @@ -0,0 +1,925 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: GPSBabelGUI-2\n" +"POT-Creation-Date: 2005-12-06 17:57\n" +"PO-Revision-Date: 2007-05-01 20:30+0100\n" +"Last-Translator: Olaf Klein \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2.1\n" +"Language-Team: Daniel Díaz \n" +"X-Poedit-Language: Spanish\n" +"X-Poedit-Country: SPAIN\n" + +#. frmAbout..Caption +#: about.dfm:5 +msgid "About" +msgstr "Acerca de..." + +#. frmAbout..pnClient..pnCenter..lbHint1..Caption +#: about.dfm:76 +msgid "This program is part of the GPSBabel project, hosted on" +msgstr "Este programa forma parte del proyecto GPSBabel, alojado en" + +#. frmAbout..pnClient..pnCenter..lbVersion..Caption +#: about.dfm:84 +#: about.pas:80 +msgid "Version" +msgstr "Versión" + +#. frmAbout..pnClient..pnCenter..lbTranslators..Caption +#: about.dfm:91 +msgid "Translations" +msgstr "Traducciones" + +#. frmAbout..pnClient..pnCenter..lbURL..Caption +#: about.dfm:98 +msgid "www.gpsbabel.org" +msgstr "www.gpsbabel.org" + +#. frmAbout..pnClient..pnCenter..lbCopyRight..Caption +#: about.dfm:114 +msgid "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" +msgstr "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" + +#. frmAbout..pnClient..pnCenter..lbMoreInfo..Caption +#: about.dfm:121 +msgid "Find more info at" +msgstr "Más información en" + +#. frmAbout..pnClient..pnCenter..stDescription..Caption +#: about.dfm:149 +msgid "The frontend for GPSBabel command line program" +msgstr "Frontal para línea de comandos de GPSBabel" + +#. frmAbout..pnClient..pnCenter..stLicense..Caption +#: about.dfm:163 +msgid "THIS SOFTWARE MAY ONLY BE LICENSED FREE OF CHARGE" +msgstr "ESTE SOFTWARE SOLO PUEDE TENER LICENCIA GRATUITA" + +#. frmAbout..pnClient..pnCenter..btnNewLanguage..Caption +#: about.dfm:192 +msgid "Adding a new language" +msgstr "Añadir un nuevo lenguaje" + +#. frmFilter..Caption +#: filter.dfm:6 +msgid "Filter" +msgstr "Filtro" + +#. frmFilter..gbTracks..Caption +#. frmMain..pnBottom..cbTracks..Caption +#: filter.dfm:31 +#: main.dfm:581 +msgid "&Tracks" +msgstr "&Trazas" + +#. frmFilter..gbTracks..lbTimePlusMinus..Caption +#: filter.dfm:39 +#: about.pas:87 +#: about.pas:88 +#: about.pas:89 +#: about.pas:90 +msgid "by" +msgstr "por" + +#. frmFilter..gbTracks..lbTimeDays..Caption +#: filter.dfm:46 +msgid "day(s), " +msgstr "dia(s)" + +#. frmFilter..gbTracks..lbTimeHours..Caption +#: filter.dfm:53 +msgid "hour(s), " +msgstr "hora(s)" + +#. frmFilter..gbTracks..lbTimeMinutes..Caption +#: filter.dfm:60 +msgid "minute(s)," +msgstr "minuto(s)" + +#. frmFilter..gbTracks..lbTimeSeconds..Caption +#: filter.dfm:67 +msgid "second(s)" +msgstr "segundo(s)" + +#. frmFilter..gbTracks..cbTrackTitle..Hint +#: filter.dfm:74 +msgid "Title for new tracks" +msgstr "Nombre para nuevas trazas" + +#. frmFilter..gbTracks..cbTrackTitle..Caption +#: filter.dfm:76 +msgid "Tit&le" +msgstr "&Nombre" + +#. frmFilter..gbTracks..cbTrackSplit..Hint +#: filter.dfm:95 +msgid "Split track into several tracks depending on date of trackpoint" +msgstr "Dividir en varias trazas pedendiendo de la fecha de los puntos de información" + +#. frmFilter..gbTracks..cbTrackSplit..Caption +#: filter.dfm:96 +msgid "&Split" +msgstr "&Dividir" + +#. frmFilter..gbTracks..cbTrackTime..Hint +#: filter.dfm:104 +msgid "Shift all tracks" +msgstr "Desplazar todas las trazas" + +#. frmFilter..gbTracks..cbTrackTime..Caption +#: filter.dfm:105 +msgid "&Move" +msgstr "&Mover" + +#. frmFilter..gbTracks..cbTrackStart..Hint +#: filter.dfm:197 +msgid "Take only trackpoints starting at" +msgstr "Recuperar registros de trazado que empiecen el" + +#. frmFilter..gbTracks..cbTrackStart..Caption +#: filter.dfm:198 +msgid "Start at" +msgstr "Empezar el" + +#. frmFilter..gbTracks..cbTrackStop..Caption +#: filter.dfm:237 +msgid "stop at" +msgstr "parar el" + +#. frmFilter..gbTracks..cbTrackPack..Hint +#: filter.dfm:276 +msgid "Pack all tracks into one track (No duplicate timestamps)" +msgstr "Agrupar todas las trazas en una sola (Sin fechas duplicadas)" + +#. frmFilter..gbTracks..cbTrackPack..Caption +#: filter.dfm:277 +msgid "&Pack (or)" +msgstr "&Agrupar(o)" + +#. frmFilter..gbTracks..cbTrackMerge..Hint +#: filter.dfm:286 +msgid "Merge all tracks into one track" +msgstr "Mezclar todas las trazas en una sola" + +#. frmFilter..gbTracks..cbTrackMerge..Caption +#: filter.dfm:287 +msgid "Merge" +msgstr "Mezclar" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Hint +#: filter.dfm:296 +msgid "Shift start/stop by local timezone offset" +msgstr "Desplazar inicio/fin según diferencia horaria local" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Caption +#: filter.dfm:297 +msgid "TZ" +msgstr "TZ" + +#. frmFilter..gbTracks..cbGPSfix..Hint +#: filter.dfm:306 +msgid "Synthesize GPS fixes (PPS, DGPS, 3D, 2D)" +msgstr "" + +#. frmFilter..gbTracks..cbGPSfix..Caption +#: filter.dfm:307 +msgid "GPS fixes" +msgstr "" + +#. frmFilter..gbTracks..cbTrackCourse..Hint +#: filter.dfm:316 +msgid "Synthesize course values" +msgstr "Sintetizar los valores del curso" + +#. frmFilter..gbTracks..cbTrackCourse..Caption +#: filter.dfm:317 +msgid "Course" +msgstr "Curso" + +#. frmFilter..gbTracks..cbTrackSpeed..Hint +#: filter.dfm:325 +msgid "Synthesize speed values" +msgstr "Sintetizar los valores de la velocidad" + +#. frmFilter..gbTracks..cbTrackSpeed..Caption +#: filter.dfm:326 +msgid "Speed" +msgstr "Rutas" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:338 +msgid "none" +msgstr "" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:339 +msgid "pps" +msgstr "" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:340 +msgid "dgps" +msgstr "" + +#. frmFilter..gbRoutes..Caption +#: filter.dfm:352 +msgid "&Routes && Tracks" +msgstr "&Rutas && Trazas" + +#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption +#: filter.dfm:360 +msgid "limit to" +msgstr "limitar a" + +#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption +#: filter.dfm:368 +msgid "Points" +msgstr "Puntos" + +#. frmFilter..gbRoutes..cbRouteSimplify..Hint +#: filter.dfm:375 +msgid "Simplify routes and tracks by limited number of points" +msgstr "Simplificar rutas y trazas limitando el número de puntos" + +#. frmFilter..gbRoutes..cbRouteSimplify..Caption +#: filter.dfm:376 +msgid "Simplify" +msgstr "Simplificar" + +#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint +#: filter.dfm:385 +msgid "Upper limit of points for routes and tracks" +msgstr "Aumentar número de puntos para rutas y trazas" + +#. frmFilter..gbRoutes..cbReverse..Hint +#: filter.dfm:407 +msgid "Reverse routes and tracks" +msgstr "Rutas y trazas inversas" + +#. frmFilter..gbRoutes..cbReverse..Caption +#: filter.dfm:408 +msgid "Reverse" +msgstr "Inverso" + +#. frmFilter..pnBottom..btnOK..Caption +#: filter.dfm:425 +msgid "OK" +msgstr "OK" + +#. frmFilter..pnBottom..BitBtn1..Caption +#: filter.dfm:461 +msgid "File based filters" +msgstr "Archivos de filtros" + +#. frmFilter..gbWaypoints..Caption +#. frmMain..pnBottom..cbWaypoints..Caption +#: filter.dfm:490 +#: main.dfm:555 +msgid "&Waypoints" +msgstr "&Registros de trazado" + +#. frmFilter..gbWaypoints..lbWayptRadiusLat..Caption +#: filter.dfm:499 +msgid "Latitude" +msgstr "Latitud" + +#. frmFilter..gbWaypoints..lbWayptRadiusLon..Caption +#: filter.dfm:507 +msgid "Longitude" +msgstr "Longitud" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint +#: filter.dfm:515 +msgid "Merge waypoints with duplicate locations" +msgstr "Mezclar registros de trazado con ubicaciones duplicadas" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption +#: filter.dfm:516 +msgid "locations" +msgstr "ubicaciones" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint +#: filter.dfm:525 +msgid "Merge waypoints with duplicate \"short name\"" +msgstr "Mezclar registros de trazado duplicados con \"nombre corto\"" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption +#: filter.dfm:526 +msgid "\"short names\"" +msgstr "\"nombre corto\"" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint +#: filter.dfm:535 +msgid "Merge waypoints separated by less then" +msgstr "Mezclar registros de trazado menores cuando" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption +#: filter.dfm:536 +msgid "Position" +msgstr "Posición" + +#. frmFilter..gbWaypoints..cbWayptSort..Hint +#: filter.dfm:564 +msgid "Sort waypoints by \"short name\" or by description" +msgstr "Ordenar registros de trazado por \"nombre corto\" o por descripción" + +#. frmFilter..gbWaypoints..cbWayptSort..Caption +#: filter.dfm:565 +msgid "Sort" +msgstr "Ordenar" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint +#: filter.dfm:573 +msgid "Merge duplicate waypoints" +msgstr "Mezclar registros de trazado duplicados" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption +#: filter.dfm:574 +msgid "Duplicates" +msgstr "Duplicados" + +#. frmFilter..gbWaypoints..cbWayptRadius..Hint +#: filter.dfm:583 +msgid "Include points based on their proximity to central point" +msgstr "Incluir puntos basándose en la proximidad a un punto central" + +#. frmFilter..gbWaypoints..cbWayptRadius..Caption +#: filter.dfm:584 +msgid "Radius" +msgstr "Radio" + +#. frmFilter..gbWaypoints..edWayptRadiusLat..Hint +#: filter.dfm:612 +msgid "Latitude of central point" +msgstr "Latitud del punto central" + +#. frmFilter..gbWaypoints..edWayptRadiusLon..Hint +#: filter.dfm:622 +msgid "Longitude of central point" +msgstr "Longitud del punto central" + +#. frmFilter..gbTransform..Caption +#: filter.dfm:634 +msgid "Transformation" +msgstr "" + +#. frmFilter..gbTransform..cbTransform..Caption +#: filter.dfm:651 +msgid "Transform" +msgstr "" + +#. frmFilter..gbTransform..cbTransformDelete..Hint +#: filter.dfm:660 +msgid "Delete source data after transformation" +msgstr "" + +#. frmFilter..gbTransform..cbTransformDelete..Caption +#: filter.dfm:661 +msgid "Delete" +msgstr "Eliminar" + +#. frmMain..pnTop..gbInput..Caption +#: main.dfm:38 +#: main.pas:270 +#: main.pas:275 +#: main.pas:467 +#: main.pas:868 +msgid "Input" +msgstr "Entrada" + +#. frmMain..pnTop..gbInput..sbOpenFile..Hint +#: main.dfm:45 +msgid "Start the file open dialog" +msgstr "Iniciar el cuadro de diálogo de abrir archivo" + +#. frmMain..pnTop..gbInput..lbInputOpts..Caption +#. frmMain..pnTop..gbOutput..lbOutputOpts..Caption +#. frmMain..ActionList1..acOptionsSourceFormat..Category +#. frmMain..ActionList1..acOptionsTargetFormat..Category +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Category +#: main.dfm:68 +#: main.dfm:229 +#: main.dfm:1418 +#: main.dfm:1423 +#: main.dfm:1437 +msgid "Options" +msgstr "Opciones" + +#. frmMain..pnTop..gbInput..lbInputFormat..Caption +#. frmMain..pnTop..gbOutput..lbOutputFormat..Caption +#: main.dfm:76 +#: main.dfm:259 +msgid "Format" +msgstr "Formato" + +#. frmMain..pnTop..gbInput..lbInputFile..Caption +#. frmMain..pnTop..gbOutput..lbOutputFile..Caption +#. frmMain..ActionList1..acFileExit..Category +#. frmMain..ActionList1..acFileClearMemo..Category +#. frmMain..ActionList1..acFileOutputToScreen..Category +#. frmMain..ActionList1..acFileChangeLanguage..Category +#. frmMain..ActionList1..acFileExportCSV..Category +#: main.dfm:83 +#: main.dfm:266 +#: main.dfm:1399 +#: main.dfm:1428 +#: main.dfm:1443 +#: main.dfm:1455 +#: main.dfm:1460 +#: main.pas:865 +#: main.pas:919 +msgid "File" +msgstr "Archivo" + +#. frmMain..pnTop..gbInput..chbInputDevice..Hint +#: main.dfm:112 +msgid "Read data from device instead from file" +msgstr "Leer datos del dispositivo en vez de archivo" + +#. frmMain..pnTop..gbInput..chbInputDevice..Caption +#. frmMain..pnTop..gbOutput..chbOutputDevice..Caption +#: main.dfm:115 +#: main.dfm:299 +msgid "Device" +msgstr "Dispositivo" + +#. frmMain..pnTop..gbInput..edInputOpts..Hint +#: main.dfm:124 +msgid "Options for the selected input format" +msgstr "Opciones de formato de la entrada seleccionada" + +#. frmMain..pnTop..gbInput..edInputFile..Hint +#: main.dfm:135 +msgid "Read data from given filename" +msgstr "Leer datos del archivo facilitado" + +#. frmMain..pnTop..gbInput..cbInputLang..Hint +#: main.dfm:146 +msgid "Characterset for input data" +msgstr "Juego de caracteres para la entrada" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:152 +#: main.dfm:363 +msgid "- default -" +msgstr "- por defecto -" + +#. frmMain..pnTop..gbInput..cbInputDevice..Hint +#: main.dfm:179 +msgid "Read data from device ..." +msgstr "Leer datos del dispositivo ..." + +#. frmMain..pnTop..gbInput..cbInputFormatDevice..Hint +#: main.dfm:194 +msgid "Format for input from device" +msgstr "Formato del dispositivo de entrada" + +#. frmMain..pnTop..gbInput..cbInputFormat..Hint +#: main.dfm:208 +msgid "Format for input from file" +msgstr "Formato del archivo de entrada" + +#. frmMain..pnTop..gbOutput..Caption +#: main.dfm:222 +#: main.pas:271 +#: main.pas:276 +#: main.pas:476 +#: main.pas:922 +msgid "Output" +msgstr "Salida" + +#. frmMain..pnTop..gbOutput..sbSaveFile..Hint +#: main.dfm:273 +msgid "Start the file save dialog" +msgstr "Iniciar el cuadro de diálogo de guardar en archivo" + +#. frmMain..pnTop..gbOutput..chbOutputDevice..Hint +#: main.dfm:296 +msgid "Write data to device instead to file" +msgstr "Escribir datos en el dispositivo en vez de archivo" + +#. frmMain..pnTop..gbOutput..cbOutputFormatDevice..Hint +#: main.dfm:309 +msgid "Format for ouput to device" +msgstr "Formato del dispositivo de salida" + +#. frmMain..pnTop..gbOutput..edOutputOpts..Hint +#: main.dfm:321 +msgid "Options for the selected output format" +msgstr "Opciones para el formato de salida seleccionado" + +#. frmMain..pnTop..gbOutput..cbOutputFormat..Hint +#: main.dfm:332 +msgid "Format for output to file" +msgstr "Formato del archivo de salida" + +#. frmMain..pnTop..gbOutput..edOutputFile..Hint +#: main.dfm:345 +msgid "Write data to given filename" +msgstr "Escribir datos al archivo seleccionado" + +#. frmMain..pnTop..gbOutput..cbOutputLang..Hint +#: main.dfm:357 +msgid "Characterset for output data" +msgstr "Juego de caracteres para los datos de salida" + +#. frmMain..pnTop..gbOutput..cbOutputDevice..Hint +#: main.dfm:390 +msgid "Write data to device ..." +msgstr "Escribir datos al dispositivo ..." + +#. frmMain..pnBottom..lbWhat..Caption +#: main.dfm:415 +msgid "What ?" +msgstr "¿Qué?" + +#. frmMain..pnBottom..cbWaypoints..Hint +#: main.dfm:554 +msgid "Process waypoint information" +msgstr "Información del proceso de registros de trazado" + +#. frmMain..pnBottom..cbRoutes..Hint +#: main.dfm:568 +msgid "Process route information" +msgstr "Información del proceso de rutas" + +#. frmMain..pnBottom..cbRoutes..Caption +#: main.dfm:569 +msgid "&Routes" +msgstr "&Rutas" + +#. frmMain..pnBottom..cbTracks..Hint +#: main.dfm:580 +msgid "Process track information" +msgstr "Información del proceso de trazas" + +#. frmMain..pnBottom..btnFilter..Caption +#. frmMain..ActionList1..acFilterSelect..Caption +#: main.dfm:594 +#: main.dfm:1393 +msgid "&Filter" +msgstr "&Filtrar" + +#. frmMain..pnBottom..btnProcess..Hint +#: main.dfm:638 +msgid "Start data conversion" +msgstr "Empezar la conversión datos" + +#. frmMain..pnBottom..btnProcess..Caption +#. frmMain..ActionList1..acConvert..Caption +#: main.dfm:641 +#: main.dfm:1386 +msgid "let's go" +msgstr "iniciar" + +#. frmMain..OpenDialog..Filter +#: main.dfm:701 +msgid "Garmin Mapsource mps|*.mps|All files|*.*" +msgstr "Garmin Mapsource mps|*.mps|Todos los archivos|*.*" + +#. frmMain..SaveDialog..Filter +#: main.dfm:707 +msgid "All file(s)|*.*|Garmin MapSource mps|*.mps" +msgstr "Todos los archivos|*.*|Garmin Mapsource mps|*.mps" + +#. frmMain..ActionList1..acConvert..Category +#. frmMain..ActionList1..acFilterSelect..Category +#: main.dfm:1385 +#: main.dfm:1392 +msgid "Babel" +msgstr "Babel" + +#. frmMain..ActionList1..acFilterSelect..Hint +#: main.dfm:1394 +msgid "Filter incomming data before writing them to file or device" +msgstr "Filtrar los datos de entrada antes de guardarlos a archivo o dispositivo" + +#. frmMain..ActionList1..acFileExit..Caption +#: main.dfm:1400 +msgid "E&xit" +msgstr "&Salir" + +#. frmMain..ActionList1..acHelpAbout..Category +#. frmMain..ActionList1..acHelpIntro..Category +#. frmMain..ActionList1..acHelpReadme..Category +#: main.dfm:1404 +#: main.dfm:1409 +#: main.dfm:1413 +msgid "Help" +msgstr "A&yuda" + +#. frmMain..ActionList1..acHelpAbout..Caption +#: main.dfm:1405 +msgid "&About" +msgstr "&Acerca de" + +#. frmMain..ActionList1..acHelpIntro..Caption +#: main.dfm:1410 +msgid "&Intro" +msgstr "&Introducción" + +#. frmMain..ActionList1..acHelpReadme..Caption +#. frmReadme..Caption +#: main.dfm:1414 +#: readme.dfm:6 +msgid "GPSBabel README" +msgstr "GPSBabel README" + +#. frmMain..ActionList1..acOptionsSourceFormat..Caption +#: main.dfm:1419 +msgid "... for source format" +msgstr "... para formato origen" + +#. frmMain..ActionList1..acOptionsTargetFormat..Caption +#: main.dfm:1424 +msgid "... for target format" +msgstr "... para formato destino" + +#. frmMain..ActionList1..acFileClearMemo..Caption +#: main.dfm:1429 +msgid "Clear output" +msgstr "Limpiar salida" + +#. frmMain..ActionList1..acFileClearMemo..Hint +#: main.dfm:1430 +msgid "Clear messages" +msgstr "Limpiar mensajes" + +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Caption +#: main.dfm:1438 +msgid "Enable characterset transformation" +msgstr "Habilitar transformación juego de caracteres" + +#. frmMain..ActionList1..acFileOutputToScreen..Caption +#: main.dfm:1444 +msgid "Output to screen" +msgstr "Salida a pantalla" + +#. frmMain..ActionList1..acFileChangeLanguage..Caption +#: main.dfm:1456 +msgid "Change language" +msgstr "Seleccionar lenguaje" + +#. frmMain..ActionList1..acFileExportCSV..Caption +#: main.dfm:1461 +msgid "Export gpsbabel.csv (unicode)" +msgstr "Exportar a gpsbabel.csv (unicode)" + +#. frmMain..MainMenu1..mnuFile..Caption +#: main.dfm:1469 +msgid "&File" +msgstr "&Archivo" + +#. frmMain..MainMenu1..mnuFile..File1..Caption +#: main.dfm:1477 +msgid "Export" +msgstr "Exportar" + +#. frmMain..MainMenu1..mnuOptions..Caption +#: main.dfm:1498 +msgid "&Options" +msgstr "&Opciones" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames..Caption +#: main.dfm:1500 +msgid "Synthesize shortnames" +msgstr "Agrupar nombres cortos" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames....Hint +#: main.dfm:1503 +msgid "Ignore shortnames from source data and synthesize them from description or notes" +msgstr "Ignorar nombres cortos del origen y agruparlos desde las descripciones o notas" + +#. frmMain..MainMenu1..mnuOptions..mnuOptionsForceDataType..Caption +#: main.dfm:1507 +msgid "Force selected GPS data types (nuketypes filter)" +msgstr "Forzar tipos de datos del GPS seleccionado (filtro nuketipes)" + +#. frmMain..MainMenu1..mnuHelp..Caption +#: main.dfm:1548 +msgid "&Help" +msgstr "&Ayuda" + +#. frmOptions..Caption +#: options.dfm:5 +msgid "Options for ..." +msgstr "Opciones de ..." + +#. frmSelect..pnBottom..btnCancel..Caption +#: select.dfm:66 +msgid "Abort" +msgstr "Interrumpir" + +#: about.pas:87 +#: select.pas:81 +msgid "German" +msgstr "Alemán" + +#: about.pas:88 +#: select.pas:83 +msgid "French" +msgstr "Francés" + +#: about.pas:89 +#: select.pas:82 +msgid "Spanish" +msgstr "Español" + +#: about.pas:90 +#: select.pas:85 +msgid "Hungarian" +msgstr "Húngaro" + +#: about.pas:132 +msgid "" +"Please have a look at the file README.GUI.\n" +"\n" +"There you will find all information you need to\n" +"get GPSBabelGUI working in your own language." +msgstr "" +"Por favor lea el archivo README.GUI.\n" +"\n" +"Allí encontrará toda la inforamción que necesita\n" +"para ejecutar GPSBabelGUI en su propio lenguaje." + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:184 +#: filter.pas:185 +msgid "Waypoints" +msgstr "Registros de trazado" + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:182 +#: filter.pas:183 +msgid "Routes" +msgstr "Rutas" + +#: filter.pas:182 +#: filter.pas:183 +#: filter.pas:184 +#: filter.pas:185 +msgid "Tracks" +msgstr "Trazas" + +#: filter.pas:224 +msgid "Feet" +msgstr "Pie" + +#: filter.pas:225 +msgid "Meter" +msgstr "Metro" + +#: filter.pas:228 +msgid "Miles" +msgstr "Milla" + +#: filter.pas:229 +msgid "Kilometer" +msgstr "Kilómetro" + +#: filter.pas:239 +msgid "Not supported by gpsbabel.exe, release %s!" +msgstr "¡No soportado por gpsbabel.exe, versión %s!" + +#: filter.pas:288 +msgid "Value (%s) out of range (%g to %g)!" +msgstr "¡Valor (%s) fuera de rango (de %g a %g)!" + +#: filter.pas:593 +#: options.pas:661 +msgid "Discard changes?" +msgstr "¿Descartar cambios?" + +#: main.pas:244 +msgid "Internal development release" +msgstr "Versión en desarrollo interno" + +#: main.pas:246 +msgid "BETA" +msgstr "BETA" + +#: main.pas:248 +msgid "Private release" +msgstr "Versión privada" + +#: main.pas:250 +msgid "Special release" +msgstr "Versión especial" + +#: main.pas:342 +msgid "The file \"gpsbabel.exe\" found in current directory is too old!" +msgstr "¡El archivo \"gpsbabel.exe\" encontrado en el directorio es obsoleto!" + +#: main.pas:416 +#: main.pas:550 +msgid "All files|*.*" +msgstr "Todos los archivo|*.*" + +#: main.pas:484 +msgid "Select and edit options for \"%s\"" +msgstr "Seleccionar y editar opciones para \"%s\"" + +#: main.pas:488 +msgid "No options available for \"%s\"" +msgstr "No hay opciones disponibles para \"%s\"" + +#. s := s + '-1'; +#: main.pas:603 +msgid "File %s not found." +msgstr "No se encontró el archivo %s." + +#: main.pas:664 +msgid "File \"%s\" exists ! Overwrite ?" +msgstr "El archivo \"%s\" ya existe ¿sobreescribir?" + +#: main.pas:665 +msgid "Warning" +msgstr "Precaución" + +#: main.pas:698 +msgid "Could not run \"gpsbabel.exe\"!" +msgstr "¡No se puede ejecutar \"gpsbabel.exe\"!" + +#: main.pas:707 +msgid "Sorry, gpsbabel.exe reported problems!" +msgstr "¡Perdón, gpsbabel.exe indicó algún problema!" + +#: main.pas:709 +msgid "Converted successfully from \"%s\" to \"%s\"." +msgstr "Conversión correcta de \"%s\" to \"%s\"." + +#: main.pas:820 +msgid "GPSBabel, version %s" +msgstr "GPSBabel, versión %s" + +#: main.pas:854 +#: main.pas:909 +msgid "Port" +msgstr "Puerto" + +#: main.pas:1013 +msgid "Options for \"%s\"" +msgstr "Opciones para \"%s\"" + +#: main.pas:1203 +#: main.pas:1273 +msgid "Choose language" +msgstr "Elejir lenguaje" + +#: main.pas:1203 +msgid "for GUIBabelGUI" +msgstr "para GUIBabelGUI" + +#: main.pas:1273 +msgid "for export" +msgstr "para exportar" + +#. override; +#: options.pas:147 +msgid "Be aware, that most options are made for the output side. " +msgstr "Tenga precaución, la mayoría de las opciones están pensadas para la salida." + +#: options.pas:148 +msgid "Currently we don't have a flag which tells us which direction is used by the options." +msgstr "Ahora mismo no hay seleccionada opción alguna que indique en que dirección se aplican las opciones." + +#: options.pas:208 +msgid "Short \"%s\"" +msgstr "Ordenar \"%s\"" + +#: options.pas:332 +msgid "Invalid line format!" +msgstr "¡Formato de línea invalido!" + +#: options.pas:353 +msgid "Unknown option \"%s\"!" +msgstr "¡Opción \"%s\" desconocida!" + +#: select.pas:84 +msgid "English" +msgstr "Inglés" + +#: utils.pas:119 +msgid "Error WINAPI: Could not create \"NamedPipe\"!" +msgstr "¡Error de WINAPI: No se pudo crear \"NamedPipe\"!" + +#: utils.pas:124 +msgid "\"gpsbabel.exe\" not found!!!" +msgstr "¡¡¡ No se ha encontrado \"gpsbabel.exe\"!!!" + +#. dwCreationFlags, // creation flags +#: utils.pas:143 +msgid "Could not run \"gpsbabel.exe\" (Error %d)!" +msgstr "¡No se puede ejecutar \"gpsbabel.exe\" (Error %d)!" + +#: utils.pas:176 +msgid "\"gpsbabel.exe\" returned error 0x%x (%d)" +msgstr "\"gpsbabel.exe\" devolvió el error 0x%x (%d)" + diff --git a/win32/gui-2/locale/es/LC_MESSAGES/delphi.po b/win32/gui-2/locale/es/LC_MESSAGES/delphi.po new file mode 100644 index 000000000..10702c2cf --- /dev/null +++ b/win32/gui-2/locale/es/LC_MESSAGES/delphi.po @@ -0,0 +1,12734 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2003-03-04 17:49\n" +"PO-Revision-Date: 2005-10-25 08:14+0100\n" +"Last-Translator: Jordi March \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Programmer's name for it: SInvalidCreateWidget +#: Clx/QConsts.pas:22 +msgid "Class %s could not create QT widget" +msgstr "La clase %s no pudo crear el widget QT" + +#. Programmer's name for it: STooManyMessageBoxButtons +#: Clx/QConsts.pas:23 +msgid "Too many buttons specified for message box" +msgstr "Demasiados botones especificados para la caja del mensaje" + +#. Programmer's name for it: SmkcBkSp +#: Clx/QConsts.pas:25 +msgid "Backspace" +msgstr "Retroceso" + +#. Programmer's name for it: SmkcTab +#. StandardActions..ActionList1..PreviousTab1..Category +#. StandardActions..ActionList1..NextTab1..Category +#: Clx/QConsts.pas:26 Vcl/Consts.pas:137 Vcl/ActnRes.dfm:244 +#: Vcl/ActnRes.dfm:249 +msgid "Tab" +msgstr "Tab" + +#. Programmer's name for it: SmkcBackTab +#: Clx/QConsts.pas:27 +msgid "BackTab" +msgstr "Tab Atrás" + +#. Programmer's name for it: SmkcEsc +#: Clx/QConsts.pas:28 Vcl/Consts.pas:138 +msgid "Esc" +msgstr "Esc" + +#. Programmer's name for it: SmkcReturn +#: Clx/QConsts.pas:29 +msgid "Return" +msgstr "Retorno" + +#. Programmer's name for it: SmkcEnter +#: Clx/QConsts.pas:30 Vcl/Consts.pas:139 +msgid "Enter" +msgstr "Intro" + +#. Programmer's name for it: SmkcSpace +#: Clx/QConsts.pas:31 Vcl/Consts.pas:140 +msgid "Space" +msgstr "Espacio" + +#. Programmer's name for it: SmkcPgUp +#: Clx/QConsts.pas:32 Vcl/Consts.pas:141 +msgid "PgUp" +msgstr "Re Pág" + +#. Programmer's name for it: SmkcPgDn +#: Clx/QConsts.pas:33 Vcl/Consts.pas:142 +msgid "PgDn" +msgstr "Av Pág" + +#. Programmer's name for it: SmkcEnd +#: Clx/QConsts.pas:34 Vcl/Consts.pas:143 +msgid "End" +msgstr "Fin" + +#. Programmer's name for it: SmkcHome +#. WebAppDbgMainForm..Home..Caption +#: Clx/QConsts.pas:35 Vcl/Consts.pas:144 Internet/SvrMainForm.dfm:38 +msgid "Home" +msgstr "Inicio" + +#. Programmer's name for it: SmkcLeft +#: Clx/QConsts.pas:36 Vcl/Consts.pas:145 +msgid "Left" +msgstr "Izq" + +#. Programmer's name for it: SmkcUp +#: Clx/QConsts.pas:37 Vcl/Consts.pas:146 +msgid "Up" +msgstr "Arriba" + +#. Programmer's name for it: SmkcRight +#: Clx/QConsts.pas:38 Vcl/Consts.pas:147 +msgid "Right" +msgstr "Der" + +#. Programmer's name for it: SmkcDown +#: Clx/QConsts.pas:39 Vcl/Consts.pas:148 +msgid "Down" +msgstr "Abajo" + +#. Programmer's name for it: SmkcIns +#: Clx/QConsts.pas:40 Vcl/Consts.pas:149 +msgid "Ins" +msgstr "Ins" + +#. Programmer's name for it: SmkcDel +#: Clx/QConsts.pas:41 Vcl/Consts.pas:150 +msgid "Del" +msgstr "Supr" + +#. Programmer's name for it: SmkcShift +#: Clx/QConsts.pas:42 Vcl/Consts.pas:151 +msgid "Shift+" +msgstr "Mayús+" + +#. Programmer's name for it: SmkcCtrl +#: Clx/QConsts.pas:43 Vcl/Consts.pas:152 +msgid "Ctrl+" +msgstr "Ctrl+" + +#. Programmer's name for it: SmkcAlt +#: Clx/QConsts.pas:44 Vcl/Consts.pas:153 +msgid "Alt+" +msgstr "Alt+" + +#. Programmer's name for it: SOpenFileTitle +#. Programmer's name for it: SOpen +#. Programmer's name for it: SOpenFileTitle +#. ClxTreeViewItems..OpenDialog1..Title +#. Title +#. IndexFiles..OpenDialog..Title +#: Clx/QConsts.pas:46 Clx/QConsts.pas:276 Vcl/Consts.pas:15 Property +#: Editors/ClxNodeEdit.xfm:278 Editors/ClxPicEdit.xfm:111 +#: Editors/Ixedit.dfm:92 +msgid "Open" +msgstr "Abrir" + +#. Programmer's name for it: SAssignError +#: Clx/QConsts.pas:47 Rtl/Common/RTLConsts.pas:15 +msgid "Cannot assign a %s to a %s" +msgstr "No puede asignarse %s a %s" + +#. Programmer's name for it: SFCreateError +#. Programmer's name for it: SCannotCreateFile +#. Programmer's name for it: SFCreateError +#: Clx/QConsts.pas:48 Vcl/SqlConst.pas:121 Rtl/Common/RTLConsts.pas:27 +msgid "Cannot create file %s" +msgstr "No puede crearse el archivo %s" + +#. Programmer's name for it: SFOpenError +#: Clx/QConsts.pas:49 Rtl/Common/RTLConsts.pas:30 +msgid "Cannot open file %s" +msgstr "No puede abrirse el archivo %s" + +#. Programmer's name for it: SReadError +#: Clx/QConsts.pas:50 Rtl/Common/RTLConsts.pas:71 +msgid "Stream read error" +msgstr "Hay un error de lectura del flujo" + +#. Programmer's name for it: SWriteError +#: Clx/QConsts.pas:51 Rtl/Common/RTLConsts.pas:86 +msgid "Stream write error" +msgstr "Hay un error de escritura del flujo" + +#. Programmer's name for it: SMemoryStreamError +#: Clx/QConsts.pas:52 Rtl/Common/RTLConsts.pas:63 +msgid "Out of memory while expanding memory stream" +msgstr "Sin memoria expandiendo el flujo de memoria" + +#. Programmer's name for it: SCantWriteResourceStreamError +#: Clx/QConsts.pas:53 Vcl/Consts.pas:16 Rtl/Common/RTLConsts.pas:18 +msgid "Can't write to a read-only resource stream" +msgstr "No se puede escribir sobre un flujo de recursos de solo lectura" + +#. Programmer's name for it: SDuplicateReference +#: Clx/QConsts.pas:54 Vcl/Consts.pas:17 +msgid "WriteObject called twice for the same instance" +msgstr "WriteObject llamado dos veces por la misma instancia" + +#. Programmer's name for it: SClassNotFound +#: Clx/QConsts.pas:55 Rtl/Common/RTLConsts.pas:21 +msgid "Class %s not found" +msgstr "Clase %s no encontrada" + +#. Programmer's name for it: SInvalidImage +#. Programmer's name for it: SInvalidStreamFormat +#. Programmer's name for it: SInvalidImage +#: Clx/QConsts.pas:56 Vcl/OleConst.pas:29 Rtl/Common/RTLConsts.pas:43 +msgid "Invalid stream format" +msgstr "Formato del flujo no válido" + +#. Programmer's name for it: SResNotFound +#. Programmer's name for it: sResNotFound +#. Programmer's name for it: SResNotFound +#: Clx/QConsts.pas:57 Internet/WebConst.pas:33 Rtl/Common/RTLConsts.pas:77 +msgid "Resource %s not found" +msgstr "Recurso %s no encontado" + +#. Programmer's name for it: SClassMismatch +#: Clx/QConsts.pas:58 Vcl/Consts.pas:18 +msgid "Resource %s is of incorrect class" +msgstr "El recurso %s es una clase incorrecta" + +#. Programmer's name for it: SListIndexError +#: Clx/QConsts.pas:59 Rtl/Common/RTLConsts.pas:60 +msgid "List index out of bounds (%d)" +msgstr "Indice de la lista fuera de rango (%d)" + +#. Programmer's name for it: SListCapacityError +#: Clx/QConsts.pas:60 Rtl/Common/RTLConsts.pas:58 +msgid "List capacity out of bounds (%d)" +msgstr "Desbordamiento de la capacidad de la lista (%d)" + +#. Programmer's name for it: SListCountError +#: Clx/QConsts.pas:61 Rtl/Common/RTLConsts.pas:59 +msgid "List count out of bounds (%d)" +msgstr "Desbordamiento del contador de la lista (%d)" + +#. Programmer's name for it: SSortedListError +#: Clx/QConsts.pas:62 +msgid "Operation not allowed on sorted string list" +msgstr "Operación no soportada en una lista de cadenas ordenada" + +#. Programmer's name for it: SDuplicateString +#: Clx/QConsts.pas:63 Rtl/Common/RTLConsts.pas:26 +msgid "String list does not allow duplicates" +msgstr "La lista de cadenas no permite duplicados" + +#. Programmer's name for it: SInvalidTabIndex +#: Clx/QConsts.pas:64 Vcl/Consts.pas:19 +msgid "Tab index out of bounds" +msgstr "Indice de página fuera de rango" + +#. Programmer's name for it: SInvalidTabPosition +#: Clx/QConsts.pas:65 Vcl/Consts.pas:20 +msgid "Tab position incompatible with current tab style" +msgstr "Posición de página incompatible con el actual estilo de página" + +#. Programmer's name for it: SInvalidTabStyle +#: Clx/QConsts.pas:66 Vcl/Consts.pas:21 +msgid "Tab style incompatible with current tab position" +msgstr "Estilo de página incompatible con la actual posición de página" + +#. Programmer's name for it: SDuplicateName +#: Clx/QConsts.pas:67 Rtl/Common/RTLConsts.pas:25 +msgid "A component named %s already exists" +msgstr "Ya existe una componente de nombre %s" + +#. Programmer's name for it: SInvalidName +#: Clx/QConsts.pas:68 Rtl/Common/RTLConsts.pas:46 +msgid "''%s'' is not a valid component name" +msgstr "'%s' no es un nombre de componente válido" + +#. Programmer's name for it: SDuplicateClass +#: Clx/QConsts.pas:69 Rtl/Common/RTLConsts.pas:23 +msgid "A class named %s already exists" +msgstr "Ya existe una clase con nombre %s" + +#. Programmer's name for it: SInvalidInteger +#: Clx/QConsts.pas:70 Rtl/Common/RTLConsts.pas:44 +msgid "''%s'' is not a valid integer value" +msgstr "'%s' no es un valor entero válido" + +#. Programmer's name for it: SLineTooLong +#. Programmer's name for it: SOutlineLongLine +#. Programmer's name for it: SLineTooLong +#: Clx/QConsts.pas:71 Vcl/Consts.pas:115 Rtl/Common/RTLConsts.pas:57 +msgid "Line too long" +msgstr "Línea demasiado larga" + +#. Programmer's name for it: SInvalidPropertyValue +#. Programmer's name for it: SInvalidProperty +#. Programmer's name for it: SInvalidPropertyValue +#: Clx/QConsts.pas:72 Clx/QConsts.pas:158 Rtl/Common/RTLConsts.pas:47 +#: Rtl/Common/RTLConsts.pas:51 +msgid "Invalid property value" +msgstr "Valor de propiedad no válido" + +#. Programmer's name for it: SInvalidPropertyPath +#: Clx/QConsts.pas:73 Rtl/Common/RTLConsts.pas:49 +msgid "Invalid property path" +msgstr "Ruta de propiedad no válida" + +#. Programmer's name for it: SInvalidPropertyType +#: Clx/QConsts.pas:74 Rtl/Common/RTLConsts.pas:50 +msgid "Invalid property type: %s" +msgstr "Tipo de propiedad no válido: %s" + +#. Programmer's name for it: SInvalidPropertyElement +#: Clx/QConsts.pas:75 Rtl/Common/RTLConsts.pas:48 +msgid "Invalid property element: %s" +msgstr "Elemento de propiedad no válido: %s" + +#. Programmer's name for it: SUnknownProperty +#: Clx/QConsts.pas:76 +msgid "Property does not exist" +msgstr "No existe la propiedad" + +#. Programmer's name for it: SReadOnlyProperty +#: Clx/QConsts.pas:77 Rtl/Common/RTLConsts.pas:72 +msgid "Property is read-only" +msgstr "La propiedad es de sólo lectura" + +#. Programmer's name for it: SPropertyException +#: Clx/QConsts.pas:78 Rtl/Common/RTLConsts.pas:69 +msgid "Error reading %s%s%s: %s" +msgstr "Se ha producido un error leyendo %s%s%s: %s" + +#. Programmer's name for it: SAncestorNotFound +#: Clx/QConsts.pas:79 Rtl/Common/RTLConsts.pas:14 +msgid "Ancestor for '%s' not found" +msgstr "No se ha encontrado predecesor para '%s'" + +#. Programmer's name for it: SInvalidBitmap +#: Clx/QConsts.pas:80 Vcl/Consts.pas:22 +msgid "Bitmap image is not valid" +msgstr "Imagen bitmap no válida" + +#. Programmer's name for it: SInvalidIcon +#: Clx/QConsts.pas:81 Vcl/Consts.pas:23 +msgid "Icon image is not valid" +msgstr "Imagen del icono no válido" + +#. Programmer's name for it: SInvalidPixelFormat +#: Clx/QConsts.pas:82 Vcl/Consts.pas:25 +msgid "Invalid pixel format" +msgstr "Formato de pixel no válido" + +#. Programmer's name for it: SBitmapEmpty +#: Clx/QConsts.pas:83 Vcl/Consts.pas:27 +msgid "Bitmap is empty" +msgstr "El bitmap está vacío" + +#. Programmer's name for it: SScanLine +#: Clx/QConsts.pas:84 Vcl/Consts.pas:28 +msgid "Scan line index out of range" +msgstr "Indice de la línea examinada fuera de rango" + +#. Programmer's name for it: SChangeIconSize +#: Clx/QConsts.pas:85 Vcl/Consts.pas:29 +msgid "Cannot change the size of an icon" +msgstr "No se puede cambiar el tamaño de un icono" + +#. Programmer's name for it: SUnknownExtension +#: Clx/QConsts.pas:86 Vcl/Consts.pas:31 +msgid "Unknown picture file extension (.%s)" +msgstr "Extensión de archivo de imagen (.%s) desconocida" + +#. Programmer's name for it: SUnknownClipboardFormat +#: Clx/QConsts.pas:87 Vcl/Consts.pas:32 +msgid "Unsupported clipboard format" +msgstr "Formato del portapapeles no soportado" + +#. Programmer's name for it: SOutOfResources +#: Clx/QConsts.pas:88 Vcl/Consts.pas:33 +msgid "Out of system resources" +msgstr "Sin recursos del sistema" + +#. Programmer's name for it: SNoCanvasHandle +#: Clx/QConsts.pas:89 Vcl/Consts.pas:34 +msgid "Canvas does not allow drawing" +msgstr "El canvas no permite dibujar" + +#. Programmer's name for it: SInvalidCanvasState +#: Clx/QConsts.pas:90 +msgid "Invalid canvas state request" +msgstr "Petición del estado del canvas no válida" + +#. Programmer's name for it: SInvalidImageSize +#: Clx/QConsts.pas:91 Vcl/Consts.pas:35 +msgid "Invalid image size" +msgstr "Tamaño de imagen no válido" + +#. Programmer's name for it: SInvalidWidgetHandle +#: Clx/QConsts.pas:92 +msgid "Invalid widget handle" +msgstr "Manejador (handle) widjet no válido" + +#. Programmer's name for it: SInvalidColorDepth +#: Clx/QConsts.pas:93 +msgid "Color depth must be 1, 8 or 32 bpp" +msgstr "La profundidad del color debe ser 1, 8 o 32 bpp" + +#. Programmer's name for it: STooManyImages +#: Clx/QConsts.pas:94 Vcl/Consts.pas:36 +msgid "Too many images" +msgstr "Demasiadas imágenes" + +#. Programmer's name for it: SWidgetCreate +#: Clx/QConsts.pas:95 +msgid "Error creating widget" +msgstr "Se ha producido un error creando widget" + +#. Programmer's name for it: SCannotFocus +#: Clx/QConsts.pas:96 +msgid "Cannot focus a disabled or invisible window (%s)" +msgstr "No puede enfocarse una ventana deshabilitada o invisible (%s)" + +#. Programmer's name for it: SParentRequired +#: Clx/QConsts.pas:97 +msgid "Control '%s' has no parent widget" +msgstr "El control '%s' no tiene un widget padre" + +#. Programmer's name for it: SParentGivenNotAParent +#: Clx/QConsts.pas:98 Vcl/Consts.pas:49 +msgid "Parent given is not a parent of '%s'" +msgstr "El padre dado no es un padre de '%s'" + +#. Programmer's name for it: SVisibleChanged +#: Clx/QConsts.pas:99 Vcl/Consts.pas:51 +msgid "Cannot change Visible in OnShow or OnHide" +msgstr "No es posible cambiar la visibilidad en OnShow u OnHide" + +#. Programmer's name for it: SCannotShowModal +#: Clx/QConsts.pas:100 Vcl/Consts.pas:52 +msgid "Cannot make a visible window modal" +msgstr "No se puede hacer visible una ventana modal" + +#. Programmer's name for it: SScrollBarRange +#: Clx/QConsts.pas:101 Vcl/Consts.pas:53 +msgid "Scrollbar property out of range" +msgstr "Propiedad Scrollbar fuera de rango" + +#. Programmer's name for it: SPropertyOutOfRange +#: Clx/QConsts.pas:102 Vcl/Consts.pas:54 +msgid "%s property out of range" +msgstr "Propiedad %s fuera de rango" + +#. Programmer's name for it: SMenuIndexError +#: Clx/QConsts.pas:103 Vcl/Consts.pas:55 +msgid "Menu index out of range" +msgstr "Indice de menú fuera de rango" + +#. Programmer's name for it: SMenuReinserted +#: Clx/QConsts.pas:104 Vcl/Consts.pas:56 +msgid "Menu inserted twice" +msgstr "Menú insertado dos veces" + +#. Programmer's name for it: SNoMenuRecursion +#: Clx/QConsts.pas:105 +msgid "Menu insertion recursion not allowed" +msgstr "No está permitida la recursividad en la inserción del menú" + +#. Programmer's name for it: SMenuNotFound +#: Clx/QConsts.pas:106 Vcl/Consts.pas:57 +msgid "Sub-menu is not in menu" +msgstr "El sub-menú no se encuentra en un menú" + +#. Programmer's name for it: SMenuSetFormError +#: Clx/QConsts.pas:107 +msgid "TMenu.SetForm: argument must be TCustomForm" +msgstr "TMenu.SetForm: el argumento debe ser TCustomForm" + +#. Programmer's name for it: SNoTimers +#: Clx/QConsts.pas:108 Vcl/Consts.pas:58 Vcl/IBXConst.pas:187 +msgid "Not enough timers available" +msgstr "No hay suficientes cronometradores disponibles" + +#. Programmer's name for it: SNotPrinting +#: Clx/QConsts.pas:109 Vcl/Consts.pas:59 Rtl/Common/RTLConsts.pas:65 +msgid "Printer is not currently printing" +msgstr "La impresora no se encuentra actualmente imprimiendo" + +#. Programmer's name for it: SPrinting +#: Clx/QConsts.pas:110 Vcl/Consts.pas:60 Rtl/Common/RTLConsts.pas:70 +msgid "Printing in progress" +msgstr "Impresión en progreso" + +#. Programmer's name for it: SNoAdapter +#: Clx/QConsts.pas:111 +msgid "No printer adapter available for printing" +msgstr "No hay adaptador de impresora disponible para imprimir" + +#. Programmer's name for it: SPrinterIndexError +#: Clx/QConsts.pas:112 Vcl/Consts.pas:61 +msgid "Printer index out of range" +msgstr "Indice de impresora fuera de rango" + +#. Programmer's name for it: SInvalidPrinter +#: Clx/QConsts.pas:113 Vcl/Consts.pas:62 +msgid "Printer selected is not valid" +msgstr "La impresora seleccionada no es válida" + +#. Programmer's name for it: SDeviceOnPort +#: Clx/QConsts.pas:114 Vcl/Consts.pas:63 +msgid "%s on %s" +msgstr "%s en %s" + +#. Programmer's name for it: SGroupIndexTooLow +#: Clx/QConsts.pas:115 Vcl/Consts.pas:64 +msgid "GroupIndex cannot be less than a previous menu item's GroupIndex" +msgstr "" +"GroupIndex no puede ser menor que el GroupIndex de un item del menú previo" + +#. Programmer's name for it: SNoMDIForm +#: Clx/QConsts.pas:116 Vcl/Consts.pas:66 +msgid "Cannot create form. No MDI forms are currently active" +msgstr "" +"No se puede crear el formulario. Actualmente no hay formularios MDI activos" + +#. Programmer's name for it: SNotAnMDIForm +#: Clx/QConsts.pas:117 +msgid "Invalid MDIParent for class %s" +msgstr "Padre MDI para la clase %s es no válido" + +#. Programmer's name for it: SMDIChildNotVisible +#: Clx/QConsts.pas:118 Vcl/Consts.pas:50 +msgid "Cannot hide an MDI Child Form" +msgstr "No se puede ocultar un formulario MDI Child" + +#. Programmer's name for it: SRegisterError +#: Clx/QConsts.pas:119 Rtl/Common/RTLConsts.pas:75 +msgid "Invalid component registration" +msgstr "Registro de componente no válido" + +#. Programmer's name for it: SImageCanvasNeedsBitmap +#: Clx/QConsts.pas:120 Vcl/Consts.pas:67 +msgid "Can only modify an image if it contains a bitmap" +msgstr "Sólo se puede modificar una imagen si contiene un bitmap" + +#. Programmer's name for it: SControlParentSetToSelf +#: Clx/QConsts.pas:121 Vcl/Consts.pas:68 +msgid "A control cannot have itself as its parent" +msgstr "Un control no puede referirse al él mismo como ancestro" + +#. Programmer's name for it: SOKButton +#. Programmer's name for it: SMsgDlgOK +#. Programmer's name for it: RSHTTPOK +#. Programmer's name for it: SOKButton +#. Programmer's name for it: SMsgDlgOK +#. formAbout..btnOk..Caption +#. IdPropEdBindingEntry..btnOk..Caption +#. ClxIconViewItemsEditor..Button4..Caption +#. ClxImageListEditor..OK..Caption +#. ClxListViewItems..Button4..Caption +#. ClxTreeViewItems..Button4..Caption +#. Caption +#. DSSCubeEditor..OKButton..Caption +#. DSSQueryEditor..OKButton..Caption +#. formAbout..Panel1..btnOk..Caption +#. IdPropEdBindingEntry..btnOk..Caption +#. DlgProperties..OkButton..Caption +#. AboutBox..OKButton..Caption +#. ConnEditForm..OkButton..Caption +#. ClientDataForm..OkBtn..Caption +#. DBEditForm..OkButton..Caption +#. AddFields..OkBtn..Caption +#. AssociateAttributes..OKBtn..Caption +#. SaveAttributesAs..OKBtn..Caption +#. DefineField..OkBtn..Caption +#. LinkFields..Button1..Caption +#. IndexFiles..Ok..Caption +#. PictureEditorDlg..OKButton..Caption +#. SQLEditForm..ButtonPanel..OkButton..Caption +#. frmGeneratorEditor..OKBtn..Caption +#. frmIBRestoreEditor..Panel1..OKBtn..Caption +#. frmIBSecurityEditor..Panel1..OKBtn..Caption +#. frmIBServiceEditor..Panel1..OKBtn..Caption +#: Clx/QConsts.pas:122 Clx/QConsts.pas:170 Indy/IdResourceStrings.pas:62 +#: Vcl/Consts.pas:69 Vcl/Consts.pas:124 Indy/IdAbout.xfm:3333 +#: Indy/IdDsnPropEdBinding.xfm:53 Property Editors/ClxIconEdit.xfm:122 +#: Editors/ClxImgEdit.xfm:28 Editors/ClxItemEdit.xfm:148 +#: Editors/ClxNodeEdit.xfm:158 Editors/ClxPicEdit.xfm:104 Decision +#: Cube/MXDCUBE.DFM:470 Cube/MXDSSQRY.DFM:323 Indy/IdAbout.dfm:68 +#: Indy/IdDsnPropEdBinding.dfm:47 Internet/SvrPropDlg.dfm:26 +#: Internet/WebAppDbgAbout.dfm:55 Editors/AdoConEd.dfm:19 +#: Editors/CDSEdit.dfm:39 Editors/Dbedit.dfm:140 Editors/DSAdd.dfm:24 +#: Editors/DSAttrA.dfm:18 Editors/DSAttrS.dfm:56 Editors/DSDefine.dfm:109 +#: Editors/FldLinks.DFM:141 Editors/Ixedit.dfm:64 Editors/PicEdit.dfm:22 +#: Editors/SqlEdit.dfm:94 Vcl/IBGeneratorEditor.dfm:51 +#: Vcl/IBRestoreEditor.dfm:51 Vcl/IBSecurityEditor.dfm:99 +#: Vcl/IBServiceEditor.dfm:122 +msgid "OK" +msgstr "Aceptar" + +#. Programmer's name for it: SCancelButton +#. Programmer's name for it: SMsgDlgCancel +#. Programmer's name for it: SCancel +#. Programmer's name for it: SCancelButton +#. Programmer's name for it: SMsgDlgCancel +#. LoginDialog..CancelButton..Caption +#. PasswordDialog..CancelButton..Caption +#. IdPropEdBindingEntry..btnCancel..Caption +#. ClxIconViewItemsEditor..Cancel..Caption +#. ClxImageListEditor..Cancel..Caption +#. ClxListViewItems..Cancel..Caption +#. ClxTreeViewItems..Cancel..Caption +#. Caption +#. ClxStrEditDlg..CancelButton..Caption +#. DSSCubeEditor..CancelButton..Caption +#. DSSQueryEditor..Cancel..Caption +#. frmNewMessagePart..Panel2..btnCancel..Caption +#. IdPropEdBindingEntry..btnCancel..Caption +#. DlgProperties..CancelButton..Caption +#. ConnEditForm..CancelButton..Caption +#. ClientDataForm..CancelBtn..Caption +#. DBEditForm..CancelButton..Caption +#. InputReqDialog..CancelButton..Caption +#. AddFields..CancelBtn..Caption +#. AssociateAttributes..CancelBtn..Caption +#. SaveAttributesAs..CancelBtn..Caption +#. DefineField..CancelBtn..Caption +#. LinkFields..Button2..Caption +#. IndexFiles..Cancel..Caption +#. PictureEditorDlg..CancelButton..Caption +#. SQLEditForm..ButtonPanel..CancelButton..Caption +#. StrEditDlg..CancelButton..Caption +#. UpdateSQLEditForm..CancelButton..Caption +#. LoginDialog..CancelButton..Caption +#. PasswordDialog..CancelButton..Caption +#. frmGeneratorEditor..CancelBtn..Caption +#. frmIBRestoreEditor..Panel1..CancelBtn..Caption +#. frmIBSecurityEditor..Panel1..CancelBtn..Caption +#. frmIBServiceEditor..Panel1..CancelBtn..Caption +#: Clx/QConsts.pas:123 Clx/QConsts.pas:171 Clx/QConsts.pas:282 +#: Vcl/Consts.pas:70 Vcl/Consts.pas:125 Clx/QDBLogDlg.xfm:31 +#: Clx/QDBPWDlg.xfm:33 Indy/IdDsnPropEdBinding.xfm:65 Property +#: Editors/ClxIconEdit.xfm:133 Editors/ClxImgEdit.xfm:40 +#: Editors/ClxItemEdit.xfm:159 Editors/ClxNodeEdit.xfm:169 +#: Editors/ClxPicEdit.xfm:25 Editors/ClxStrEdit.xfm:54 Decision +#: Cube/MXDCUBE.DFM:480 Cube/MXDSSQRY.DFM:313 Indy/IdDsnNewMessagePart.dfm:44 +#: Indy/IdDsnPropEdBinding.dfm:59 Internet/SvrPropDlg.dfm:38 +#: Editors/AdoConEd.dfm:30 Editors/CDSEdit.dfm:52 Editors/Dbedit.dfm:152 +#: Editors/dbinpreq.dfm:29 Editors/DSAdd.dfm:36 Editors/DSAttrA.dfm:30 +#: Editors/DSAttrS.dfm:67 Editors/DSDefine.dfm:121 Editors/FldLinks.DFM:153 +#: Editors/Ixedit.dfm:75 Editors/PicEdit.dfm:33 Editors/SqlEdit.dfm:106 +#: Editors/StrEdit.dfm:50 Editors/UpdSqlEd.dfm:32 Vcl/DBLOGDLG.dfm:32 +#: Vcl/DbPWDlg.dfm:31 Vcl/IBGeneratorEditor.dfm:62 Vcl/IBRestoreEditor.dfm:62 +#: Vcl/IBSecurityEditor.dfm:110 Vcl/IBServiceEditor.dfm:133 +msgid "Cancel" +msgstr "Cancelar" + +#. Programmer's name for it: SYesButton +#. Programmer's name for it: SMsgDlgYes +#. Programmer's name for it: SYesButton +#. Programmer's name for it: SMsgDlgYes +#: Clx/QConsts.pas:124 Clx/QConsts.pas:168 Vcl/Consts.pas:71 +#: Vcl/Consts.pas:122 +msgid "&Yes" +msgstr "&Sí" + +#. Programmer's name for it: SNoButton +#. Programmer's name for it: SMsgDlgNo +#. Programmer's name for it: SNoButton +#. Programmer's name for it: SMsgDlgNo +#: Clx/QConsts.pas:125 Clx/QConsts.pas:169 Vcl/Consts.pas:72 +#: Vcl/Consts.pas:123 +msgid "&No" +msgstr "&No" + +#. Programmer's name for it: SHelpButton +#. Programmer's name for it: SMsgDlgHelp +#. Programmer's name for it: SHelpButton +#. Programmer's name for it: SMsgDlgHelp +#. ClxIconViewItemsEditor..Button7..Caption +#. ClxImageListEditor..Help..Caption +#. ClxListViewItems..Button7..Caption +#. ClxTreeViewItems..Help..Caption +#. Caption +#. ClxStrEditDlg..HelpButton..Caption +#. DSSCubeEditor..HelpButton..Caption +#. DSSQueryEditor..HelpButton..Caption +#. WebAppDbgMainForm..MainMenu1..Help1..Caption +#. DlgProperties..Button1..Caption +#. ConnEditForm..HelpButton..Caption +#. ClientDataForm..HelpBtn..Caption +#. DBEditForm..HelpButton..Caption +#. DataBindForm..HelpBtn..Caption +#. AddFields..HelpBtn..Caption +#. AssociateAttributes..HelpBtn..Caption +#. SaveAttributesAs..HelpBtn..Caption +#. DefineField..HelpBtn..Caption +#. LinkFields..Help..Caption +#. IndexFiles..Help..Caption +#. PictureEditorDlg..HelpButton..Caption +#. SQLEditForm..ButtonPanel..HelpButton..Caption +#. StrEditDlg..HelpButton..Caption +#. UpdateSQLEditForm..HelpButton..Caption +#. frmIBRestoreEditor..Panel1..HelpBtn..Caption +#. frmIBSecurityEditor..Panel1..HelpBtn..Caption +#. frmIBServiceEditor..Panel1..HelpBtn..Caption +#: Clx/QConsts.pas:126 Clx/QConsts.pas:172 Vcl/Consts.pas:73 +#: Vcl/Consts.pas:126 Property Editors/ClxIconEdit.xfm:153 +#: Editors/ClxImgEdit.xfm:143 Editors/ClxItemEdit.xfm:179 +#: Editors/ClxNodeEdit.xfm:189 Editors/ClxPicEdit.xfm:36 +#: Editors/ClxStrEdit.xfm:64 Decision Cube/MXDCUBE.DFM:491 +#: Cube/MXDSSQRY.DFM:333 Internet/SvrMainForm.dfm:199 +#: Internet/SvrPropDlg.dfm:207 Editors/AdoConEd.dfm:39 Editors/CDSEdit.dfm:61 +#: Editors/Dbedit.dfm:161 Editors/DbOleEdt.dfm:128 Editors/DSAdd.dfm:65 +#: Editors/DSAttrA.dfm:40 Editors/DSAttrS.dfm:77 Editors/DSDefine.dfm:130 +#: Editors/FldLinks.DFM:162 Editors/Ixedit.dfm:84 Editors/PicEdit.dfm:42 +#: Editors/SqlEdit.dfm:116 Editors/StrEdit.dfm:30 Editors/UpdSqlEd.dfm:41 +#: Vcl/IBRestoreEditor.dfm:71 Vcl/IBSecurityEditor.dfm:119 +#: Vcl/IBServiceEditor.dfm:142 +msgid "&Help" +msgstr "Ay&uda" + +#. Programmer's name for it: SCloseButton +#. LogDetail..ActionList1..CloseAction..Caption +#. CustomizeFrm..CloseMenu..CloseItem..Caption +#. SocketForm..PopupMenu..miClose..Caption +#: Clx/QConsts.pas:127 Vcl/Consts.pas:74 Internet/SvrLogDetailDlg.dfm:80 +#: Vcl/CustomizeDlg.dfm:372 Vcl/ScktMain.dfm:319 +msgid "&Close" +msgstr "&Cerrar" + +#. Programmer's name for it: SIgnoreButton +#. Programmer's name for it: SMsgDlgIgnore +#. Programmer's name for it: SIgnoreButton +#. Programmer's name for it: SMsgDlgIgnore +#: Clx/QConsts.pas:128 Clx/QConsts.pas:177 Vcl/Consts.pas:75 +#: Vcl/Consts.pas:131 +msgid "&Ignore" +msgstr "&Ignorar" + +#. Programmer's name for it: SRetryButton +#. Programmer's name for it: SMsgDlgRetry +#. Programmer's name for it: SRetryButton +#. Programmer's name for it: SMsgDlgRetry +#: Clx/QConsts.pas:129 Clx/QConsts.pas:176 Vcl/Consts.pas:76 +#: Vcl/Consts.pas:130 +msgid "&Retry" +msgstr "&Reintentar" + +#. Programmer's name for it: SAbortButton +#: Clx/QConsts.pas:130 Vcl/Consts.pas:77 +msgid "Abort" +msgstr "Abortar" + +#. Programmer's name for it: SAllButton +#. Programmer's name for it: SMsgDlgAll +#. Programmer's name for it: SAllButton +#. Programmer's name for it: SMsgDlgAll +#: Clx/QConsts.pas:131 Clx/QConsts.pas:178 Vcl/Consts.pas:78 +#: Vcl/Consts.pas:132 +msgid "&All" +msgstr "&Todo" + +#. Programmer's name for it: SCannotDragForm +#: Clx/QConsts.pas:133 Vcl/Consts.pas:80 +msgid "Cannot drag a form" +msgstr "No se puede arrastrar un formulario" + +#. Programmer's name for it: SPutObjectError +#: Clx/QConsts.pas:134 Vcl/Consts.pas:81 +msgid "PutObject to undefined item" +msgstr "Elemento no definido para PutObject" + +#. Programmer's name for it: SFB +#: Clx/QConsts.pas:136 Vcl/Consts.pas:90 +msgid "FB" +msgstr "FB" + +#. Programmer's name for it: SFG +#: Clx/QConsts.pas:137 Vcl/Consts.pas:91 +msgid "FG" +msgstr "FG" + +#. Programmer's name for it: SBG +#: Clx/QConsts.pas:138 Vcl/Consts.pas:92 +msgid "BG" +msgstr "BG" + +#. Programmer's name for it: SVIcons +#: Clx/QConsts.pas:139 Vcl/Consts.pas:96 +msgid "Icons" +msgstr "Iconos" + +#. Programmer's name for it: SVBitmaps +#: Clx/QConsts.pas:140 Vcl/Consts.pas:97 +msgid "Bitmaps" +msgstr "Mapas de bit" + +#. Programmer's name for it: SVPixmaps +#: Clx/QConsts.pas:141 +msgid "Pixmaps" +msgstr "Pixmaps" + +#. Programmer's name for it: SVPNGs +#: Clx/QConsts.pas:142 +msgid "PNGs" +msgstr "PNGs" + +#. Programmer's name for it: SDrawings +#: Clx/QConsts.pas:143 +msgid "Drawings" +msgstr "Dibujos" + +#. Programmer's name for it: SGridTooLarge +#: Clx/QConsts.pas:144 Vcl/Consts.pas:98 Rtl/Common/RTLConsts.pas:31 +msgid "Grid too large for operation" +msgstr "Rejilla demasiado grande para la operación" + +#. Programmer's name for it: STooManyDeleted +#: Clx/QConsts.pas:145 Vcl/Consts.pas:99 Rtl/Common/RTLConsts.pas:83 +msgid "Too many rows or columns deleted" +msgstr "Demasiadas filas o columnas eliminadas" + +#. Programmer's name for it: SIndexOutOfRange +#: Clx/QConsts.pas:146 Vcl/Consts.pas:100 Rtl/Common/RTLConsts.pas:33 +msgid "Grid index out of range" +msgstr "Indice de la rejilla fuera de rango" + +#. Programmer's name for it: SFixedColTooBig +#: Clx/QConsts.pas:147 Vcl/Consts.pas:101 Rtl/Common/RTLConsts.pas:28 +msgid "Fixed column count must be less than column count" +msgstr "" +"El número de columnas fijas debe ser menor que el número total de columnas" + +#. Programmer's name for it: SFixedRowTooBig +#: Clx/QConsts.pas:148 Vcl/Consts.pas:102 Rtl/Common/RTLConsts.pas:29 +msgid "Fixed row count must be less than row count" +msgstr "El número de filas fijas debe ser menor que el número total de filas" + +#. Programmer's name for it: SInvalidStringGridOp +#: Clx/QConsts.pas:149 Vcl/Consts.pas:103 Rtl/Common/RTLConsts.pas:54 +msgid "Cannot insert or delete rows from grid" +msgstr "No se puede insertar o eliminar filas de la rejilla" + +#. Programmer's name for it: SParseError +#: Clx/QConsts.pas:150 Rtl/Common/RTLConsts.pas:67 +msgid "%s on line %d" +msgstr "%s en la linea %d" + +#. Programmer's name for it: SIdentifierExpected +#: Clx/QConsts.pas:151 Rtl/Common/RTLConsts.pas:32 +msgid "Identifier expected" +msgstr "Se esperaba un identificador" + +#. Programmer's name for it: SStringExpected +#: Clx/QConsts.pas:152 Rtl/Common/RTLConsts.pas:80 +msgid "String expected" +msgstr "Se esperaba una cadena" + +#. Programmer's name for it: SNumberExpected +#: Clx/QConsts.pas:153 Rtl/Common/RTLConsts.pas:66 +msgid "Number expected" +msgstr "Se esperaba un número" + +#. Programmer's name for it: SCharExpected +#: Clx/QConsts.pas:154 Rtl/Common/RTLConsts.pas:19 +msgid "''%s'' expected" +msgstr "Se esperaba '%s'" + +#. Programmer's name for it: SSymbolExpected +#: Clx/QConsts.pas:155 Rtl/Common/RTLConsts.pas:81 +msgid "%s expected" +msgstr "Se esperaba %s" + +#. Programmer's name for it: SInvalidNumber +#: Clx/QConsts.pas:156 Vcl/Consts.pas:105 +msgid "Invalid numeric value" +msgstr "Valor numérico no válido" + +#. Programmer's name for it: SInvalidString +#: Clx/QConsts.pas:157 Rtl/Common/RTLConsts.pas:53 +msgid "Invalid string constant" +msgstr "Constante de cadena no válida" + +#. Programmer's name for it: SInvalidBinary +#: Clx/QConsts.pas:159 Rtl/Common/RTLConsts.pas:39 +msgid "Invalid binary value" +msgstr "Valor binario no válido" + +#. Programmer's name for it: SInvalidCurrentItem +#: Clx/QConsts.pas:160 Vcl/Consts.pas:108 +msgid "Invalid value for current item" +msgstr "Valor no válido para el elemento actual" + +#. Programmer's name for it: SMaskErr +#: Clx/QConsts.pas:161 Vcl/Consts.pas:109 Rtl/Common/RTLConsts.pas:61 +msgid "Invalid input value" +msgstr "Valor de entrada no válido" + +#. Programmer's name for it: SMaskEditErr +#: Clx/QConsts.pas:162 Vcl/Consts.pas:110 Rtl/Common/RTLConsts.pas:62 +msgid "Invalid input value. Use escape key to abandon changes" +msgstr "" +"Valor de entrada no válido. Use la tecla ESC para abandonar los cambios" + +#. Programmer's name for it: SMsgDlgWarning +#: Clx/QConsts.pas:164 Vcl/Consts.pas:118 +msgid "Warning" +msgstr "Aviso" + +#. Programmer's name for it: SMsgDlgError +#: Clx/QConsts.pas:165 Vcl/Consts.pas:119 +msgid "Error" +msgstr "Error" + +#. Programmer's name for it: SMsgDlgInformation +#: Clx/QConsts.pas:166 Vcl/Consts.pas:120 +msgid "Information" +msgstr "Información" + +#. Programmer's name for it: SMsgDlgConfirm +#. Programmer's name for it: SConfirmCaption +#. Programmer's name for it: SMsgDlgConfirm +#. Programmer's name for it: SConfirmCaption +#: Clx/QConsts.pas:167 Clx/QDBConsts.pas:29 Vcl/Consts.pas:121 +#: Vcl/VDBConsts.pas:28 +msgid "Confirm" +msgstr "Confirmación" + +#. Programmer's name for it: SMsgDlgHelpNone +#: Clx/QConsts.pas:173 Vcl/Consts.pas:127 +msgid "No help available" +msgstr "No hay ayuda disponible" + +#. Programmer's name for it: SMsgDlgHelpHelp +#. Programmer's name for it: SHelp +#. Programmer's name for it: SMsgDlgHelpHelp +#. StandardActions..ActionList1..HelpContents1..Category +#. StandardActions..ActionList1..HelpOnHelp1..Category +#. StandardActions..ActionList1..HelpTopicSearch1..Category +#. StandardActions..ActionList1..HelpContextAction1..Category +#. frmGeneratorEditor..HelpBtn..Caption +#: Clx/QConsts.pas:174 Clx/QConsts.pas:283 Vcl/Consts.pas:128 +#: Vcl/ActnRes.dfm:85 Vcl/ActnRes.dfm:91 Vcl/ActnRes.dfm:96 +#: Vcl/ActnRes.dfm:260 Vcl/IBGeneratorEditor.dfm:104 +msgid "Help" +msgstr "Ayuda" + +#. Programmer's name for it: SMsgDlgAbort +#: Clx/QConsts.pas:175 Vcl/Consts.pas:129 +msgid "&Abort" +msgstr "&Abortar" + +#. Programmer's name for it: SMsgDlgNoToAll +#: Clx/QConsts.pas:179 Vcl/Consts.pas:133 +msgid "N&o to All" +msgstr "N&o a todo" + +#. Programmer's name for it: SMsgDlgYesToAll +#: Clx/QConsts.pas:180 Vcl/Consts.pas:134 +msgid "Yes to &All" +msgstr "Sí a &todo" + +#. Programmer's name for it: srUnknown +#. Programmer's name for it: SUnknown +#. Programmer's name for it: srUnknown +#. Programmer's name for it: SHostUnknown +#: Clx/QConsts.pas:182 ToolsAPI/DesignConst.pas:31 Vcl/Consts.pas:155 +#: Vcl/ScktCnst.pas:34 +msgid "(Unknown)" +msgstr "(Desconocido)" + +#. Programmer's name for it: srNone +#. Programmer's name for it: SNoIndexFiles +#. Programmer's name for it: srNone +#: Clx/QConsts.pas:183 ToolsAPI/DesignConst.pas:13 Vcl/bdeconst.pas:61 +#: Vcl/Consts.pas:156 +msgid "(None)" +msgstr "(Ninguno)" + +#. Programmer's name for it: SOutOfRange +#: Clx/QConsts.pas:184 Vcl/Consts.pas:157 +msgid "Value must be between %d and %d" +msgstr "El valor debe hallarse entre %d y %d" + +#. Programmer's name for it: SUnnamed +#: Clx/QConsts.pas:185 +msgid "Unnamed" +msgstr "Sin nombre" + +#. Programmer's name for it: SDateEncodeError +#: Clx/QConsts.pas:187 Vcl/Consts.pas:159 Rtl/Sys/SysConst.pas:26 +msgid "Invalid argument to date encode" +msgstr "Argumento no válido para codificar fecha" + +#. Programmer's name for it: STimeEncodeError +#: Clx/QConsts.pas:188 Rtl/Common/RTLConsts.pas:82 Rtl/Sys/SysConst.pas:25 +msgid "Invalid argument to time encode" +msgstr "Argumento para codificar la hora no válido" + +#. Programmer's name for it: SInvalidDate +#: Clx/QConsts.pas:189 Rtl/Common/RTLConsts.pas:40 +msgid "''%s'' is not a valid date" +msgstr "'%s' no es una fecha válida" + +#. Programmer's name for it: SInvalidTime +#: Clx/QConsts.pas:190 Rtl/Common/RTLConsts.pas:55 +msgid "''%s'' is not a valid time" +msgstr "'%s' no es una hora válida" + +#. Programmer's name for it: SInvalidDateTime +#: Clx/QConsts.pas:191 Rtl/Common/RTLConsts.pas:41 +msgid "''%s'' is not a valid date and time" +msgstr "'%s' no es una fecha y hora válidas" + +#. Programmer's name for it: SInvalidFileName +#: Clx/QConsts.pas:192 Rtl/Common/RTLConsts.pas:42 +msgid "Invalid file name - %s" +msgstr "Nombre de archivo no válido - %s" + +#. Programmer's name for it: SDefaultFilter +#: Clx/QConsts.pas:193 Vcl/Consts.pas:160 +msgid "All files (*.*)|*.*" +msgstr "Todos los archivos (*.*)|*.*" + +#. Programmer's name for it: SInsertLineError +#: Clx/QConsts.pas:194 Vcl/Consts.pas:163 +msgid "Unable to insert a line" +msgstr "Incapaz de insertar una línea" + +#. Programmer's name for it: SConfirmCreateDir +#: Clx/QConsts.pas:196 Vcl/Consts.pas:165 +msgid "The specified directory does not exist. Create it?" +msgstr "La carpeta especificada no existe. ¿Crearla?" + +#. Programmer's name for it: SSelectDirCap +#: Clx/QConsts.pas:197 Vcl/Consts.pas:166 +msgid "Select Directory" +msgstr "Seleccione una carpeta" + +#. Programmer's name for it: SCannotCreateDir +#: Clx/QConsts.pas:198 Rtl/Sys/SysConst.pas:165 +msgid "Unable to create directory" +msgstr "Incapaz de crear directorio" + +#. Programmer's name for it: SDirNameCap +#: Clx/QConsts.pas:199 Vcl/Consts.pas:167 +msgid "Directory &Name:" +msgstr "&Nombre de carpeta:" + +#. Programmer's name for it: SDrivesCap +#: Clx/QConsts.pas:200 Vcl/Consts.pas:168 +msgid "D&rives:" +msgstr "&Discos:" + +#. Programmer's name for it: SDirsCap +#: Clx/QConsts.pas:201 Vcl/Consts.pas:169 +msgid "&Directories:" +msgstr "&Carpetas:" + +#. Programmer's name for it: SFilesCap +#: Clx/QConsts.pas:202 Vcl/Consts.pas:170 +msgid "&Files: (*.*)" +msgstr "&Archivos:" + +#. Programmer's name for it: SNetworkCap +#: Clx/QConsts.pas:203 Vcl/Consts.pas:171 +msgid "Ne&twork..." +msgstr "&Red..." + +#. Programmer's name for it: SInvalidClipFmt +#: Clx/QConsts.pas:205 Vcl/Consts.pas:176 +msgid "Invalid clipboard format" +msgstr "El formato del portapapeles no es válido" + +#. Programmer's name for it: SIconToClipboard +#: Clx/QConsts.pas:206 Vcl/Consts.pas:177 +msgid "Clipboard does not support Icons" +msgstr "El portapapeles no soporta iconos" + +#. Programmer's name for it: SCannotOpenClipboard +#: Clx/QConsts.pas:207 Vcl/Consts.pas:178 +msgid "Cannot open clipboard" +msgstr "No se puede abrir el portapapeles" + +#. Programmer's name for it: SInvalidActionRegistration +#: Clx/QConsts.pas:209 Vcl/Consts.pas:242 Rtl/Common/RTLConsts.pas:37 +msgid "Invalid action registration" +msgstr "Acción de registro no válida" + +#. Programmer's name for it: SInvalidActionUnregistration +#: Clx/QConsts.pas:210 Vcl/Consts.pas:243 Rtl/Common/RTLConsts.pas:38 +msgid "Invalid action unregistration" +msgstr "Acción de eliminación del registro no válida" + +#. Programmer's name for it: SInvalidActionEnumeration +#: Clx/QConsts.pas:211 Vcl/Consts.pas:244 Rtl/Common/RTLConsts.pas:36 +msgid "Invalid action enumeration" +msgstr "Acción de enumeración no válida" + +#. Programmer's name for it: SInvalidActionCreation +#: Clx/QConsts.pas:212 Vcl/Consts.pas:245 Rtl/Common/RTLConsts.pas:35 +msgid "Invalid action creation" +msgstr "Acción de creación no válida" + +#. Programmer's name for it: SDefault +#. Programmer's name for it: sHTTPItemDefault +#. Programmer's name for it: SDefault +#. SQLWindow..DBGrid1..TitleFont.Name +#. DSSQueryEditor..Pager..Dimensions..AddAgg..Font.Name +#. CustomizeFrm..Tabs..OptionsTab..MenuAnimationStyles..Text +#: Clx/QConsts.pas:214 Internet/WebConst.pas:30 Vcl/Consts.pas:180 Decision +#: Cube/MXDSQL.DFM:21 Cube/MXDSSQRY.DFM:195 Vcl/CustomizeDlg.dfm:357 +msgid "Default" +msgstr "Por defecto" + +#. Programmer's name for it: SInvalidMemoSize +#: Clx/QConsts.pas:216 Vcl/Consts.pas:182 +msgid "Text exceeds memo capacity" +msgstr "El texto excede la capacidad de la memoria" + +#. Programmer's name for it: SCustomColors +#: Clx/QConsts.pas:217 Vcl/Consts.pas:183 +msgid "Custom Colors" +msgstr "Colores personalizados" + +#. Programmer's name for it: SInvalidPrinterOp +#: Clx/QConsts.pas:218 Vcl/Consts.pas:184 +msgid "Operation not supported on selected printer" +msgstr "Operación no soportada por la impresora seleccionada" + +#. Programmer's name for it: SNoDefaultPrinter +#: Clx/QConsts.pas:219 Vcl/Consts.pas:185 +msgid "There is no default printer currently selected" +msgstr "Actualmente no hay impresora seleccionada por defecto" + +#. Programmer's name for it: SIniFileWriteError +#: Clx/QConsts.pas:221 Vcl/Consts.pas:187 Rtl/Common/RTLConsts.pas:34 +msgid "Unable to write to %s" +msgstr "Incapaz de escribir en %s" + +#. Programmer's name for it: SBitsIndexError +#: Clx/QConsts.pas:223 Vcl/Consts.pas:189 Rtl/Common/RTLConsts.pas:16 +msgid "Bits index out of range" +msgstr "Indice de bits fuera de rango" + +#. Programmer's name for it: SUntitled +#: Clx/QConsts.pas:225 Vcl/Consts.pas:191 +msgid "(Untitled)" +msgstr "(Sin título)" + +#. Programmer's name for it: SDuplicateMenus +#: Clx/QConsts.pas:227 Vcl/Consts.pas:196 +msgid "Menu '%s' is already being used by another form" +msgstr "El menú '%s' está siendo actualmente usado en otro formulario" + +#. Programmer's name for it: SPictureLabel +#: Clx/QConsts.pas:229 Vcl/Consts.pas:198 +msgid "Picture:" +msgstr "Imagen:" + +#. Programmer's name for it: SPictureDesc +#: Clx/QConsts.pas:230 Vcl/Consts.pas:199 +msgid " (%dx%d)" +msgstr " (%dx%d)" + +#. Programmer's name for it: SPreviewLabel +#: Clx/QConsts.pas:231 Vcl/Consts.pas:200 +msgid "Preview" +msgstr "Previsualización" + +#. Programmer's name for it: SBoldItalicFont +#: Clx/QConsts.pas:233 Vcl/Consts.pas:221 +msgid "Bold Italic" +msgstr "Negrita itálica" + +#. Programmer's name for it: SBoldFont +#. StandardActions..ActionList1..RichEditBold1..Hint +#: Clx/QConsts.pas:234 Vcl/Consts.pas:222 Vcl/ActnRes.dfm:129 +msgid "Bold" +msgstr "Negrita" + +#. Programmer's name for it: SItalicFont +#. StandardActions..ActionList1..RichEditItalic1..Hint +#: Clx/QConsts.pas:235 Vcl/Consts.pas:223 Vcl/ActnRes.dfm:137 +msgid "Italic" +msgstr "Itálica" + +#. Programmer's name for it: SRegularFont +#: Clx/QConsts.pas:236 Vcl/Consts.pas:224 +msgid "Regular" +msgstr "Normal" + +#. Programmer's name for it: SPropertiesVerb +#. SocketForm..Pages..PropPage..Caption +#: Clx/QConsts.pas:238 Vcl/Consts.pas:226 Vcl/ScktMain.dfm:31 +msgid "Properties" +msgstr "Propiedades" + +#. Programmer's name for it: sAsyncSocketError +#: Clx/QConsts.pas:240 Rtl/Common/RTLConsts.pas:113 +msgid "Asynchronous socket error %d" +msgstr "Hay un error de socket asíncrono %d" + +#. Programmer's name for it: sNoAddress +#: Clx/QConsts.pas:241 Rtl/Common/RTLConsts.pas:114 +msgid "No address specified" +msgstr "Dirección no especificada" + +#. Programmer's name for it: sCannotListenOnOpen +#: Clx/QConsts.pas:242 Rtl/Common/RTLConsts.pas:115 +msgid "Can't listen on an open socket" +msgstr "No puede escucharse un socket abierto" + +#. Programmer's name for it: sCannotCreateSocket +#: Clx/QConsts.pas:243 Rtl/Common/RTLConsts.pas:116 +msgid "Can't create new socket" +msgstr "No puede crearse un nuevo socket" + +#. Programmer's name for it: sSocketAlreadyOpen +#: Clx/QConsts.pas:244 Rtl/Common/RTLConsts.pas:117 +msgid "Socket already open" +msgstr "El socket ya está abierto" + +#. Programmer's name for it: sCantChangeWhileActive +#: Clx/QConsts.pas:245 Rtl/Common/RTLConsts.pas:118 +msgid "Can't change value while socket is active" +msgstr "No puede cambiarse el valor mientras el socket está activo" + +#. Programmer's name for it: sSocketMustBeBlocking +#: Clx/QConsts.pas:246 Rtl/Common/RTLConsts.pas:119 +msgid "Socket must be in blocking mode" +msgstr "El socket debe estar en modo bloqueado" + +#. Programmer's name for it: sSocketIOError +#: Clx/QConsts.pas:247 Rtl/Common/RTLConsts.pas:120 +msgid "%s error %d, %s" +msgstr "%s error %d, %s" + +#. Programmer's name for it: sSocketRead +#. Programmer's name for it: SReadAccess +#: Clx/QConsts.pas:248 Rtl/Common/RTLConsts.pas:121 Rtl/Sys/SysConst.pas:66 +msgid "Read" +msgstr "Leer" + +#. Programmer's name for it: sSocketWrite +#. Programmer's name for it: SWriteAccess +#: Clx/QConsts.pas:249 Rtl/Common/RTLConsts.pas:122 Rtl/Sys/SysConst.pas:67 +msgid "Write" +msgstr "Escribir" + +#. Programmer's name for it: SAllCommands +#: Clx/QConsts.pas:251 Vcl/Consts.pas:252 +msgid "All Commands" +msgstr "Todos los comandos" + +#. Programmer's name for it: SDuplicateItem +#: Clx/QConsts.pas:253 Vcl/Consts.pas:254 Rtl/Common/RTLConsts.pas:24 +msgid "List does not allow duplicates ($0%x)" +msgstr "La lista no permite duplicados ($0%x)" + +#. Programmer's name for it: SDuplicatePropertyCategory +#: Clx/QConsts.pas:255 +msgid "A property category called %s already exists" +msgstr "Una categoría de propiedad con nombre %s ya existe" + +#. Programmer's name for it: SUnknownPropertyCategory +#: Clx/QConsts.pas:256 +msgid "Property category does not exist (%s)" +msgstr "No existe categoría de pripiedad (%s)" + +#. Programmer's name for it: SInvalidMask +#: Clx/QConsts.pas:258 Rtl/Common/RTLConsts.pas:45 +msgid "'%s' is an invalid mask at (%d)" +msgstr "'%s' es una máscara no válida en (%d)" + +#. Programmer's name for it: SInvalidFilter +#. Programmer's name for it: sInvalidFilter +#: Clx/QConsts.pas:259 ToolsAPI/DesignIntf.pas:475 +msgid "Property filters may only be name, class or type based (%d:%d)" +msgstr "" +"Los filtros de propiedad deben ser nombres, clases o tipos de clases (%d:%d)" + +#. Programmer's name for it: SInvalidCategory +#: Clx/QConsts.pas:260 +msgid "Categories must define their own name and description" +msgstr "Las categorias deben definir su propio nombre y descripción" + +#. Programmer's name for it: sOperationNotAllowed +#: Clx/QConsts.pas:262 +msgid "Operation not allowed while dispatching application events" +msgstr "" + +#. Programmer's name for it: STextNotFound +#: Clx/QConsts.pas:263 Vcl/Consts.pas:256 +msgid "Text not found: \"%s\"" +msgstr "Texto no encontrado: \"%s\"" + +#. Programmer's name for it: SImageIndexError +#: Clx/QConsts.pas:265 Vcl/Consts.pas:40 +msgid "Invalid ImageList Index" +msgstr "Indice de ImageList no válido" + +#. Programmer's name for it: SReplaceImage +#: Clx/QConsts.pas:266 Vcl/Consts.pas:39 +msgid "Unable to Replace Image" +msgstr "Incapaz de reemplazar imagen" + +#. Programmer's name for it: SInvalidImageType +#: Clx/QConsts.pas:267 +msgid "Invalid image type" +msgstr "Tipo de imagen no válido" + +#. Programmer's name for it: SInvalidImageDimensions +#: Clx/QConsts.pas:268 +msgid "Image width and heigth must match" +msgstr "El ancho y alto de la imagen deben coincidir" + +#. Programmer's name for it: SInvalidImageDimension +#: Clx/QConsts.pas:269 +msgid "Invalid image dimension" +msgstr "Dimensión de imagen no válida" + +#. Programmer's name for it: SErrorResizingImageList +#: Clx/QConsts.pas:270 +msgid "Error resizing ImageList" +msgstr "Error cambiando el tamaño del ImageList" + +#. Programmer's name for it: SInvalidRangeError +#: Clx/QConsts.pas:272 +msgid "Range of %d to %d is invalid" +msgstr "El rango de %d a %d es no válido" + +#. Programmer's name for it: SInvalidMimeSourceStream +#: Clx/QConsts.pas:273 +msgid "MimeSource format must have an associated data stream" +msgstr "" +"El formato del MimeSource debe tener un conjunto (stream) de datos asociado" + +#. Programmer's name for it: SMimeNotSupportedForIcon +#: Clx/QConsts.pas:274 +msgid "Mime format not supported for TIcon" +msgstr "Formato Mime no soportado para TIcon" + +#. Programmer's name for it: SSave +#. Title +#: Clx/QConsts.pas:277 Property Editors/ClxPicEdit.xfm:117 +msgid "Save As" +msgstr "Grabar como" + +#. Programmer's name for it: SFindWhat +#: Clx/QConsts.pas:278 +msgid "Fi&nd what:" +msgstr "" + +#. Programmer's name for it: SWholeWord +#: Clx/QConsts.pas:279 +msgid "Match &whole word only" +msgstr "" + +#. Programmer's name for it: SMatchCase +#: Clx/QConsts.pas:280 +msgid "Match &case" +msgstr "" + +#. Programmer's name for it: SFindNext +#: Clx/QConsts.pas:281 +msgid "&Find Next" +msgstr "" + +#. Programmer's name for it: SFindTitle +#: Clx/QConsts.pas:284 +msgid "Find" +msgstr "Buscar" + +#. Programmer's name for it: SDirection +#: Clx/QConsts.pas:285 +msgid "Direction" +msgstr "Dirección" + +#. Programmer's name for it: SUp +#: Clx/QConsts.pas:286 +msgid "&Up" +msgstr "&Arriba" + +#. Programmer's name for it: SDown +#: Clx/QConsts.pas:287 +msgid "&Down" +msgstr "A&bajo" + +#. Programmer's name for it: SReplaceWith +#: Clx/QConsts.pas:288 +msgid "Rep&lace with:" +msgstr "Reemp&lazar con:" + +#. Programmer's name for it: SReplace +#. StandardActions..ActionList1..SearchReplace1..Caption +#: Clx/QConsts.pas:289 Vcl/ActnRes.dfm:165 +msgid "&Replace" +msgstr "&Reemplazar" + +#. Programmer's name for it: SReplaceTitle +#: Clx/QConsts.pas:290 +msgid "Replace" +msgstr "Reemplazar" + +#. Programmer's name for it: SReplaceAll +#: Clx/QConsts.pas:291 +msgid "Replace &All" +msgstr "Reemplaz&ar todo" + +#. Programmer's name for it: SOverwriteCaption +#: Clx/QConsts.pas:292 +msgid "Save %s as" +msgstr "Grabar %s como" + +#. Programmer's name for it: SOverwriteText +#: Clx/QConsts.pas:293 +msgid "%s already exists.Do you want to replace it?" +msgstr "" + +#. Programmer's name for it: SFileMustExist +#: Clx/QConsts.pas:295 +msgid "%sFile not found.Please verify the correct filename was given." +msgstr "" +"\"%s\"\n" +"Archivo no encontrado.\n" +"Por favor verifique el nombre del archivo." + +#. Programmer's name for it: SPathMustExist +#: Clx/QConsts.pas:297 +msgid "%sPath not found.Please verify the correct path was given." +msgstr "" +"\"%s\"\n" +"Directorio no encontrado.\n" +"Por favor verifique el nombre del directorio." + +#. Programmer's name for it: SUnknownImageFormat +#: Clx/QConsts.pas:299 +msgid "Image format not recognized" +msgstr "Formato de imagen no reconocido" + +#. Programmer's name for it: SInvalidHandle +#: Clx/QConsts.pas:300 +msgid "Invalid handle value for %s" +msgstr "Valor para el manejador (handle) no válido %s" + +#. Programmer's name for it: SUnableToWrite +#: Clx/QConsts.pas:301 +msgid "Unable to write bitmap" +msgstr "No se puede escribir el bitmap" + +#. Programmer's name for it: sAllFilter +#: Clx/QConsts.pas:302 Vcl/Consts.pas:161 +msgid "All" +msgstr "Todos" + +#. Programmer's name for it: sInvalidSetClipped +#: Clx/QConsts.pas:304 +msgid "Cannot set Clipped property while painting" +msgstr "No se puede asignar la propiedad Clipped mientras se pinta" + +#. Programmer's name for it: sInvalidLCDValue +#: Clx/QConsts.pas:306 +msgid "Invalid LCDNumber value" +msgstr "Valor del LCDNumber no válido" + +#. Programmer's name for it: sTabFailDelete +#: Clx/QConsts.pas:308 Vcl/ComStrs.pas:16 +msgid "Failed to delete tab at index %d" +msgstr "Se ha producido un error al eliminar la página en índice %d" + +#. Programmer's name for it: sPageIndexError +#: Clx/QConsts.pas:310 Vcl/ComStrs.pas:46 +msgid "%d is an invalid PageIndex value. PageIndex must be between 0 and %d" +msgstr "" +"%d es un valor de índice de página (PageIndex) no válido. El índice de " +"página debe estar entre 0 y %d" + +#. Programmer's name for it: sInvalidLevel +#: Clx/QConsts.pas:311 Vcl/ComStrs.pas:23 +msgid "Invalid item level assignment" +msgstr "Asignación de nivel de elemento no válida" + +#. Programmer's name for it: sInvalidLevelEx +#: Clx/QConsts.pas:312 Vcl/ComStrs.pas:24 +msgid "Invalid level (%d) for item \"%s\"" +msgstr "Nivel (%d) no válido para el elemento \"%s\"" + +#. Programmer's name for it: sTabMustBeMultiLine +#: Clx/QConsts.pas:313 Vcl/ComStrs.pas:21 +msgid "MultiLine must be True when TabPosition is tpLeft or tpRight" +msgstr "" +"MultiLine debe ser \"True\" cuando TabPosition es \"tpLeft\" o \"tpRight\"" + +#. Programmer's name for it: sStatusBarContainsControl +#: Clx/QConsts.pas:314 +msgid "%s is already in the StatusBar" +msgstr "%s ya està en la StatusBar" + +#. Programmer's name for it: sListRadioItemBadParent +#: Clx/QConsts.pas:315 +msgid "Radio items must have a Controller as a parent" +msgstr "" +"Los elementos de múltiple selección deben tener un Controlador como padre" + +#. Programmer's name for it: sOwnerNotCustomHeaderSections +#: Clx/QConsts.pas:316 +msgid "Owner is not a TCustomHeaderSection" +msgstr "El dueño no es un TCustomHeaderSection" + +#. Programmer's name for it: sHeaderSectionOwnerNotHeaderControl +#: Clx/QConsts.pas:317 +msgid "Header Section owner must be a TCustomHeaderControl" +msgstr "El dueño de la Banda de Encabezado debe tener un TCustomHeaderControl" + +#. Programmer's name for it: SFirstRecord +#: Clx/QDBConsts.pas:20 Vcl/VDBConsts.pas:19 +msgid "First record" +msgstr "Primer registro" + +#. Programmer's name for it: SPriorRecord +#: Clx/QDBConsts.pas:21 Vcl/VDBConsts.pas:20 +msgid "Prior record" +msgstr "Anterior registro" + +#. Programmer's name for it: SNextRecord +#: Clx/QDBConsts.pas:22 Vcl/VDBConsts.pas:21 +msgid "Next record" +msgstr "Siguiente registro" + +#. Programmer's name for it: SLastRecord +#: Clx/QDBConsts.pas:23 Vcl/VDBConsts.pas:22 +msgid "Last record" +msgstr "Último registro" + +#. Programmer's name for it: SInsertRecord +#: Clx/QDBConsts.pas:24 Vcl/VDBConsts.pas:23 +msgid "Insert record" +msgstr "Insertar registro" + +#. Programmer's name for it: SDeleteRecord +#: Clx/QDBConsts.pas:25 Vcl/VDBConsts.pas:24 +msgid "Delete record" +msgstr "Eliminar registro" + +#. Programmer's name for it: SEditRecord +#: Clx/QDBConsts.pas:26 Vcl/VDBConsts.pas:25 +msgid "Edit record" +msgstr "Editar registro" + +#. Programmer's name for it: SPostEdit +#: Clx/QDBConsts.pas:27 Vcl/VDBConsts.pas:26 +msgid "Post edit" +msgstr "Grabar edición" + +#. Programmer's name for it: SCancelEdit +#: Clx/QDBConsts.pas:28 Vcl/VDBConsts.pas:27 +msgid "Cancel edit" +msgstr "Cancelar edición" + +#. Programmer's name for it: SRefreshRecord +#: Clx/QDBConsts.pas:30 Vcl/VDBConsts.pas:29 +msgid "Refresh data" +msgstr "Refrescar datos" + +#. Programmer's name for it: SDeleteRecordQuestion +#: Clx/QDBConsts.pas:31 Vcl/DBConsts.pas:106 Vcl/VDBConsts.pas:30 +msgid "Delete record?" +msgstr "¿Desea eliminar el registro?" + +#. Programmer's name for it: SDeleteMultipleRecordsQuestion +#: Clx/QDBConsts.pas:32 Vcl/DBConsts.pas:107 Vcl/VDBConsts.pas:31 +msgid "Delete all selected records?" +msgstr "¿Desea eliminar todos los registros seleccionados?" + +#. Programmer's name for it: SDataSourceFixed +#: Clx/QDBConsts.pas:33 Vcl/VDBConsts.pas:32 +msgid "Operation not allowed in a DBCtrlGrid" +msgstr "Operación no permitida en un DBCtrlGrid" + +#. Programmer's name for it: SNotReplicatable +#: Clx/QDBConsts.pas:34 Vcl/VDBConsts.pas:33 +msgid "Control cannot be used in a DBCtrlGrid" +msgstr "El control no puede ser utilizado en un DBCtrlGrid" + +#. Programmer's name for it: SPropDefByLookup +#: Clx/QDBConsts.pas:35 Vcl/VDBConsts.pas:34 +msgid "Property already defined by lookup field" +msgstr "Propiedad ya definida anteriormente por el campo de búsqueda" + +#. Programmer's name for it: STooManyColumns +#: Clx/QDBConsts.pas:36 Vcl/DBConsts.pas:108 Vcl/VDBConsts.pas:35 +msgid "Grid requested to display more than 256 columns" +msgstr "La rejilla pidió desplegar más de 256 columnas" + +#. Programmer's name for it: SRemoteLogin +#: Clx/QDBConsts.pas:39 Vcl/VDBConsts.pas:38 +msgid "Remote Login" +msgstr "Login Remoto" + +#. Programmer's name for it: sRowError +#: Decision Cube/Mxconsts.pas:27 Vcl/Mxconsts.pas:27 +msgid "row error" +msgstr "error de fila" + +#. Programmer's name for it: sAllValues +#: Decision Cube/Mxconsts.pas:29 Vcl/Mxconsts.pas:29 +msgid "All Values" +msgstr "Todos los valores" + +#. Programmer's name for it: sMovetoRow +#: Decision Cube/Mxconsts.pas:30 Vcl/Mxconsts.pas:30 +msgid "Move to Row Area" +msgstr "Mover al Área de Filas" + +#. Programmer's name for it: sMovetoCol +#: Decision Cube/Mxconsts.pas:31 Vcl/Mxconsts.pas:31 +msgid "Move to Column Area" +msgstr "Mover al Área de Columnas" + +#. Programmer's name for it: sMakeDimOpen +#: Decision Cube/Mxconsts.pas:32 Vcl/Mxconsts.pas:32 +msgid "Open Dimension" +msgstr "Abrir Dimensión" + +#. Programmer's name for it: sDrilled +#: Decision Cube/Mxconsts.pas:33 Vcl/Mxconsts.pas:33 +msgid "Drilled In" +msgstr "Profundizado" + +#. Programmer's name for it: sCouldNotOpen +#: Decision Cube/Mxconsts.pas:34 Vcl/Mxconsts.pas:34 +msgid "The information requested could not be loaded. " +msgstr "La información requerida no pudo ser cargada." + +#. Programmer's name for it: sNoSumsAvailable +#: Decision Cube/Mxconsts.pas:35 Vcl/Mxconsts.pas:35 +msgid "No active summaries have been defined. " +msgstr "No ha sidos definidos los sumarios activos." + +#. Programmer's name for it: sNoSumsCouldBeLoaded +#: Decision Cube/Mxconsts.pas:36 Vcl/Mxconsts.pas:36 +msgid "Not enough room available to load a summary. " +msgstr "No hay espacio suficiente para cargar un sumario." + +#. Programmer's name for it: sNoDimsAvailable +#: Decision Cube/Mxconsts.pas:37 Vcl/Mxconsts.pas:37 +msgid "No available dimensions have been defined. " +msgstr "No ha sido definidas las dimensiones disponibles" + +#. Programmer's name for it: sNoDimsCouldBeLoaded +#: Decision Cube/Mxconsts.pas:38 Vcl/Mxconsts.pas:38 +msgid "Not enough space available to load a dimension. " +msgstr "No hay espacio suficiente para cargar una dimensión." + +#. Programmer's name for it: sTemplatePrefix +#: Decision Cube/Mxconsts.pas:40 Vcl/Mxconsts.pas:40 +msgid "Template: " +msgstr "Patrón: " + +#. Programmer's name for it: sGridCellError +#: Decision Cube/Mxconsts.pas:42 Vcl/Mxconsts.pas:42 +msgid "[Error]" +msgstr "[Error]" + +#. Programmer's name for it: sTotalCaption +#: Decision Cube/Mxconsts.pas:43 Vcl/Mxconsts.pas:43 +msgid "Sum" +msgstr "Suma" + +#. Programmer's name for it: sActivateLabel +#: Decision Cube/Mxconsts.pas:44 Vcl/Mxconsts.pas:44 +msgid "Inactive Dimensions" +msgstr "Dimensiones inactivas" + +#. Programmer's name for it: sRowCaption +#: Decision Cube/Mxconsts.pas:45 Vcl/Mxconsts.pas:45 +msgid "R" +msgstr "" + +#. Programmer's name for it: sColCaption +#: Decision Cube/Mxconsts.pas:46 Vcl/Mxconsts.pas:46 +msgid "C" +msgstr "" + +#. Programmer's name for it: sCaptionMenu1 +#: Decision Cube/Mxconsts.pas:47 Vcl/Mxconsts.pas:47 +msgid "Display Data and Subtotals" +msgstr "Mostrar datos y subtotales" + +#. Programmer's name for it: sCaptionMenu2 +#: Decision Cube/Mxconsts.pas:48 Vcl/Mxconsts.pas:48 +msgid "Display Data Only" +msgstr "Mostrar solo datos" + +#. Programmer's name for it: sCaptionMenu3 +#: Decision Cube/Mxconsts.pas:49 Vcl/Mxconsts.pas:49 +msgid "Display Subtotals Only" +msgstr "Mostrar solo subtotales" + +#. Programmer's name for it: sDrillIn +#: Decision Cube/Mxconsts.pas:50 Vcl/Mxconsts.pas:50 +msgid "Drill in to this value" +msgstr "Profundizar en éste valor" + +#. Programmer's name for it: sGridMenu1 +#: Decision Cube/Mxconsts.pas:51 Vcl/Mxconsts.pas:51 +msgid "Subtotals on/off" +msgstr "Subtotales activados/desactivados" + +#. Programmer's name for it: sGridMenu2 +#: Decision Cube/Mxconsts.pas:52 Vcl/Mxconsts.pas:52 +msgid "Decision Cube Editor.." +msgstr "Editor de Cubo de Decisiones.." + +#. Programmer's name for it: sGridMenu3 +#: Decision Cube/Mxconsts.pas:53 Vcl/Mxconsts.pas:53 +msgid "Decision Query Editor.." +msgstr "Editor de Query de Decisiones.." + +#. Programmer's name for it: sGridMenu4 +#: Decision Cube/Mxconsts.pas:54 Vcl/Mxconsts.pas:54 +msgid "Show Detail Records.." +msgstr "Mostrar Registros Detallados.." + +#. Programmer's name for it: sUnsupportedDataType +#: Decision Cube/Mxconsts.pas:57 Vcl/Mxconsts.pas:57 +msgid "Unsupported data type : %s" +msgstr "Tipo de dato no soportado : %s" + +#. Programmer's name for it: sRowOutOfRange +#: Decision Cube/Mxconsts.pas:58 Vcl/Mxconsts.pas:58 +msgid "Row index out of range : %d" +msgstr "Indice de fila fuera de rango : %d" + +#. Programmer's name for it: sColOutOfRange +#: Decision Cube/Mxconsts.pas:59 Vcl/Mxconsts.pas:59 +msgid "Column index out of range : %d" +msgstr "Indice de columna fuera de rango : %d" + +#. Programmer's name for it: sDupeItem +#: Decision Cube/Mxconsts.pas:60 Vcl/Mxconsts.pas:60 +msgid "Duplicate item in array" +msgstr "Dato duplicado en la matriz" + +#. Programmer's name for it: sArrayIndexOutOfRange +#: Decision Cube/Mxconsts.pas:61 Vcl/Mxconsts.pas:61 +msgid "Array index out of range : %d" +msgstr "Indice de matriz fuera de rango : %d" + +#. Programmer's name for it: sLowCapacityError +#: Decision Cube/Mxconsts.pas:62 Vcl/Mxconsts.pas:62 +msgid "" +"The DecisionCube Capacity is low. Please deactivate dimensions or change the " +"data set." +msgstr "" +"La capacidad (Capacity) del Cubo de Decisiónes es baja. Por favor, desactive " +"las dimensiones o cambie el DataSet." + +#. Programmer's name for it: sQryNotInitialized +#: Decision Cube/Mxconsts.pas:63 Vcl/Mxconsts.pas:63 +msgid "" +"Query could not be run. Check that the query, SQL text, and Database are " +"correct." +msgstr "" +"La consulta no puede ser ejecutada. Verifique que la consulta, el texto SQL, " +"y el DataBase son correctos." + +#. Programmer's name for it: sSortedListError +#: Decision Cube/Mxconsts.pas:64 Vcl/Mxconsts.pas:64 +msgid "Operation not allowed on sorted string list." +msgstr "Operación no soportada en una lista de cadenes ordenada." + +#. Programmer's name for it: sDuplicateString +#: Decision Cube/Mxconsts.pas:65 Vcl/Mxconsts.pas:65 +msgid "String list does not allow duplicates." +msgstr "Las listas de cadenas no permiten duplicados." + +#. Programmer's name for it: sMaxAllowedSums +#: Decision Cube/Mxconsts.pas:66 Vcl/Mxconsts.pas:66 +msgid "The maximum allowed summaries of %d has been exceeded." +msgstr "El número máximo de sumarios permitidos de %d ha sido excedido." + +#. Programmer's name for it: sGeneralArrayError +#: Decision Cube/Mxconsts.pas:67 Vcl/Mxconsts.pas:67 +msgid "General array error." +msgstr "Hay un error en la matriz general." + +#. Programmer's name for it: sDimIndexError +#: Decision Cube/Mxconsts.pas:70 Vcl/Mxconsts.pas:70 +msgid "Illegal Dimension Index" +msgstr "Índice de Dimensiones ilegal" + +#. Programmer's name for it: sIllegalValueForBin +#: Decision Cube/Mxconsts.pas:73 Vcl/Mxconsts.pas:73 +msgid "Initial Value is not legal for this type of Grouping" +msgstr "El valor inicial no es legal para éste tipo de agrupamiento" + +#. Programmer's name for it: sIllegalDimMap +#: Decision Cube/Mxconsts.pas:74 Vcl/Mxconsts.pas:74 +msgid "Dimension Map is not the correct size" +msgstr "El Mapa de Dimensiones no tiene el tamaño correcto" + +#. Programmer's name for it: sDimMapActiveError +#: Decision Cube/Mxconsts.pas:75 Vcl/Mxconsts.pas:75 +msgid "Cannot perform this action on an active Dimension Map" +msgstr "No se puede ejecutar esta operación sobre una Dimension Map activa" + +#. Programmer's name for it: sNotAvailable +#: Decision Cube/Mxconsts.pas:76 Vcl/Mxconsts.pas:76 +msgid "Not Available" +msgstr "No disponible" + +#. Programmer's name for it: sGetValueCounts +#: Decision Cube/Mxconsts.pas:77 Vcl/Mxconsts.pas:77 +msgid "" +"Information required to do Maximum Cell limit is not current. Do you want " +"to fetch it now?" +msgstr "" +"La información requerida para el límite Máximo de Celda no está presente. " +"¿Desea adquirirla ahora?" + +#. Programmer's name for it: sDateBinningNotAllowed +#: Decision Cube/Mxconsts.pas:78 Vcl/Mxconsts.pas:78 +msgid "Date grouping is not allowed for fields of this type" +msgstr "El Agrupamiento por Fecha no está permitido para campos de éste tipo" + +#. Programmer's name for it: sEmptyDataSet +#: Decision Cube/Mxconsts.pas:79 Vcl/Mxconsts.pas:79 +msgid "Cannot build the Decision Cube with an empty data set" +msgstr "" +"No se puede construir el Cubo de Decisiones con un conjunto de datos vacío" + +#. Programmer's name for it: sNoDataSet +#: Decision Cube/Mxconsts.pas:82 Vcl/Mxconsts.pas:82 +msgid "Data set property is not assigned" +msgstr "El dataset no está asignado" + +#. Programmer's name for it: sNoAggs +#: Decision Cube/Mxconsts.pas:83 Vcl/Mxconsts.pas:83 +msgid "No summaries are defined. " +msgstr "No se han definido sumarios. " + +#. Programmer's name for it: sNoDims +#: Decision Cube/Mxconsts.pas:84 Vcl/Mxconsts.pas:84 +msgid "No dimension fields are defined. " +msgstr "No se han definido campos de dimensión. " + +#. Programmer's name for it: sUnknownDims +#: Decision Cube/Mxconsts.pas:85 Vcl/Mxconsts.pas:85 +msgid "" +"The dimension types for this dataset cannot be determined automatically. " +"You must map the fields to dimensions or summaries with the Decision Cube " +"Editor" +msgstr "" +"Los tipos de dimensión para este dataset no pueden ser determinados " +"automáticamente. Debe definir las dimensiones de los campos o los resúmenes " +"con el Editor del Cubo de Desición" + +#. Programmer's name for it: sGroupsMissing +#: Decision Cube/Mxconsts.pas:86 Vcl/Mxconsts.pas:86 +msgid "All dimension fields must be grouped. " +msgstr "Todos los campos de dimensión deben estar agrupados. " + +#. Programmer's name for it: sDecisionQueryError +#. Programmer's name for it: sQueryError +#. Programmer's name for it: sDecisionQueryError +#. Programmer's name for it: sQueryError +#: Decision Cube/Mxconsts.pas:87 Cube/Mxconsts.pas:89 Vcl/Mxconsts.pas:87 +#: Vcl/Mxconsts.pas:89 +msgid "" +"The query may be incorrectly defined, or you may need to map its fields to " +"active dimensions or summaries with the Decision Cube Editor" +msgstr "" +"La consulta puede estar definida incorrectamente, o tal vez necesite indicar " +"en el mapa los campos para activar las dimensiones o sumarios con el Editor " +"de Cubo de Decisión" + +#. Programmer's name for it: sDataSetError +#: Decision Cube/Mxconsts.pas:88 Vcl/Mxconsts.pas:88 +msgid "" +"The dataset may be incorrectly defined, or you may need to map its fields to " +"active dimensions or summaries with the Decision Cube Editor" +msgstr "" +"El dataSet puede estar definido incorrectamente, o tal vez necesite indicar " +"en el mapa los campos para activar las dimensiones o sumarios con el Editor " +"de Cubo de Decisión" + +#. Programmer's name for it: sCountStar +#: Decision Cube/Mxconsts.pas:90 Vcl/Mxconsts.pas:90 +msgid "COUNTALL" +msgstr "" + +#. Programmer's name for it: sAddAvgWarning +#: Decision Cube/Mxconsts.pas:91 Vcl/Mxconsts.pas:91 +msgid "" +"Average is calculated using sum and count summaries for each field. The " +"necessary summaries have been added." +msgstr "" + +#. Programmer's name for it: sAddAvgStarWarning +#: Decision Cube/Mxconsts.pas:92 Vcl/Mxconsts.pas:92 +msgid "" +"Average is calculated using a field sum and count(*). The necessary " +"summaries have been added." +msgstr "" +"El promedio está calculado utilizando SUM y COUNT para cada campo. Los " +"sumarios necesarios han sido añadidos." + +#. Programmer's name for it: sQueryLegal +#: Decision Cube/Mxconsts.pas:95 Vcl/Mxconsts.pas:95 +msgid "Query is legal." +msgstr "La consulta es legal." + +#. Programmer's name for it: sAddFieldExists +#: Decision Cube/Mxconsts.pas:96 Vcl/Mxconsts.pas:96 +msgid " is already in the query" +msgstr " ya estaba en la consulta" + +#. Programmer's name for it: sAggTypeNotAllowed +#: Decision Cube/Mxconsts.pas:97 Vcl/Mxconsts.pas:97 +msgid " is not an allowed summary type" +msgstr " no es un tipo de sumario permitido" + +#. Programmer's name for it: sDimTypeNotAllowed +#: Decision Cube/Mxconsts.pas:98 Vcl/Mxconsts.pas:98 +msgid " is not an allowed dimension type" +msgstr " no es un tipo de dimensión permitida" + +#. Programmer's name for it: sAverageRequires +#: Decision Cube/Mxconsts.pas:99 Vcl/Mxconsts.pas:99 +msgid "Average summaries use Sum and Count" +msgstr "El promedio de sumarios utiliza SUM Y COUNT" + +#. Programmer's name for it: sWantToExit +#: Decision Cube/Mxconsts.pas:100 Vcl/Mxconsts.pas:100 +msgid "Do you still want to Exit?" +msgstr "¿Aún desea salir?" + +#. Programmer's name for it: sQueryIllegal +#: Decision Cube/Mxconsts.pas:101 Vcl/Mxconsts.pas:101 +msgid "The query you have created is not legal." +msgstr "La consulta que ha creado no es legal." + +#. Programmer's name for it: sQueryEditIllegal +#: Decision Cube/Mxconsts.pas:102 Vcl/Mxconsts.pas:102 +msgid "" +"The query you have entered is not legal. Please correct it before " +"continuing." +msgstr "" +"La consulta que ha ingresadono es legal. Por favor corríjala anes de " +"continuar" + +#. Programmer's name for it: sRemoveFieldError +#: Decision Cube/Mxconsts.pas:103 Vcl/Mxconsts.pas:103 +msgid "Could not remove the field" +msgstr "No se pudo eliminar el campo" + +#. Programmer's name for it: sAllFields +#: Decision Cube/Mxconsts.pas:104 Vcl/Mxconsts.pas:104 +msgid "All Fields" +msgstr "Todos los Campos" + +#. Programmer's name for it: sQueryFields +#: Decision Cube/Mxconsts.pas:105 Vcl/Mxconsts.pas:105 +msgid "Query Fields" +msgstr "Campos de Consulta" + +#. Programmer's name for it: sEditDone +#: Decision Cube/Mxconsts.pas:106 Vcl/Mxconsts.pas:106 +msgid "&Edit Done" +msgstr "&Edición Finalizada" + +#. Programmer's name for it: sEditQuery +#. DSSQueryEditor..Pager..Query..EditQry..Caption +#: Decision Cube/Mxconsts.pas:107 Vcl/Mxconsts.pas:107 +#: Cube/MXDSSQRY.DFM:299 +msgid "&Edit Query" +msgstr "&Editar Consulta" + +#. Programmer's name for it: sQParseRemovedField +#: Decision Cube/Mxconsts.pas:110 Vcl/Mxconsts.pas:110 +msgid "" +"One or more fields of a type which cannot be tabulated were removed from the " +"query." +msgstr "" +"Uno o más campos por cuyo tipo no pueden ser tabulados fueron eliminados de " +"la consulta." + +#. Programmer's name for it: sCubeLimitsExceeded +#: Decision Cube/Mxconsts.pas:113 Vcl/Mxconsts.pas:113 +msgid "Decision Cube size excedes limits" +msgstr "El tamaño del Cubo de Decisión excede los límites" + +#. Programmer's name for it: sMaxAllowedDims +#: Decision Cube/Mxconsts.pas:114 Vcl/Mxconsts.pas:114 +msgid "The maximum allowed dimensions of %d has been exceeded." +msgstr "El número máximo de dimensiones permitidas de %d ha sido excedido." + +#. Programmer's name for it: sMaxAllowedCells +#: Decision Cube/Mxconsts.pas:115 Vcl/Mxconsts.pas:115 +msgid "Total cell count of %d exceeds the maximum of %d." +msgstr "El número total de celdas de %d excede el máximo de %d." + +#. Programmer's name for it: sUnsupportedFieldType +#: Decision Cube/Mxconsts.pas:116 Vcl/Mxconsts.pas:116 +msgid "Field %s has an unsupported data type: %s" +msgstr "El campo %s es de un tipo no soportado: %s" + +#. Programmer's name for it: sFetchValues +#: Decision Cube/Mxconsts.pas:117 Vcl/Mxconsts.pas:117 +msgid "Scanning data set values..." +msgstr "Explorando los valores del DataSet..." + +#. Programmer's name for it: sUserCanceled +#: Decision Cube/Mxconsts.pas:118 Vcl/Mxconsts.pas:118 +msgid "User canceled DecisionCube population." +msgstr "El usuario canceló el procesamiento del DecisionCube." + +#. Programmer's name for it: sBinningValues +#: Decision Cube/Mxconsts.pas:119 Vcl/Mxconsts.pas:119 +msgid "Grouping values ..." +msgstr "Agrupando valores..." + +#. Programmer's name for it: sCreatingIndexes +#: Decision Cube/Mxconsts.pas:120 Vcl/Mxconsts.pas:120 +msgid "Creating Cube index for %s ..." +msgstr "Creando el índice del Cubo para %s ..." + +#. Programmer's name for it: sCreateDerivedSummaryError +#: Decision Cube/Mxconsts.pas:121 Vcl/Mxconsts.pas:121 +msgid "Unable to create derived summary." +msgstr "No es posible crear un sumario derivado." + +#. Programmer's name for it: sTrue +#. Programmer's name for it: STextTrue +#. Programmer's name for it: sTrue +#: Decision Cube/Mxconsts.pas:122 Vcl/DBConsts.pas:80 Vcl/Mxconsts.pas:122 +msgid "True" +msgstr "Verdadero" + +#. Programmer's name for it: sFalse +#. Programmer's name for it: STextFalse +#. Programmer's name for it: sFalse +#: Decision Cube/Mxconsts.pas:123 Vcl/DBConsts.pas:79 Vcl/Mxconsts.pas:123 +msgid "False" +msgstr "Falso" + +#. Programmer's name for it: sBinTypeMismatch +#: Decision Cube/Mxconsts.pas:124 Vcl/Mxconsts.pas:124 +msgid "The bin type does not match the fieldtype." +msgstr "El tipo de contenedor no concuerda con el tipo de campo." + +#. Programmer's name for it: sFatalCacheError +#: Decision Cube/Mxconsts.pas:125 Vcl/Mxconsts.pas:125 +msgid "Fatal error in cache: code: %d" +msgstr "Error fatal en cache: código: %d" + +#. Programmer's name for it: sStringTypeNoSupported +#: Decision Cube/Mxconsts.pas:126 Vcl/Mxconsts.pas:126 +msgid "String Data type not supported for summaries" +msgstr "Tipo de Dato de Cadena no soportado por sumarios" + +#. Programmer's name for it: sDataSetTooLarge +#: Decision Cube/Mxconsts.pas:127 Vcl/Mxconsts.pas:127 +msgid "Dataset is too large" +msgstr "El dataset es demasiado grande" + +#. Programmer's name for it: sBuildingDataStore +#: Decision Cube/Mxconsts.pas:128 Vcl/Mxconsts.pas:128 +msgid "Building data store..." +msgstr "Construyendo almacén de datos..." + +#. Programmer's name for it: sSumLabel +#: Decision Cube/Mxconsts.pas:131 Vcl/Mxconsts.pas:131 +msgid "Sum of %s" +msgstr "Suma de %s" + +#. Programmer's name for it: sCountLabel +#: Decision Cube/Mxconsts.pas:132 Vcl/Mxconsts.pas:132 +msgid "Count of %s" +msgstr "Recuento de %s" + +#. Programmer's name for it: sMaxLabel +#: Decision Cube/Mxconsts.pas:133 Vcl/Mxconsts.pas:133 +msgid "Maximum of %s" +msgstr "Máximo de %s" + +#. Programmer's name for it: sMinLabel +#: Decision Cube/Mxconsts.pas:134 Vcl/Mxconsts.pas:134 +msgid "Minimum of %s" +msgstr "Mínimo de %s" + +#. Programmer's name for it: sAverageLabel +#: Decision Cube/Mxconsts.pas:135 Vcl/Mxconsts.pas:135 +msgid "Average of %s" +msgstr "Promedio de %s" + +#. Programmer's name for it: sVarLabel +#: Decision Cube/Mxconsts.pas:136 Vcl/Mxconsts.pas:136 +msgid "Variance of %s" +msgstr "Varianza de %s" + +#. Programmer's name for it: sSDLabel +#: Decision Cube/Mxconsts.pas:137 Vcl/Mxconsts.pas:137 +msgid "Standard Deviation of %s" +msgstr "Desviación estándar de %s" + +#. Programmer's name for it: sAggLabel +#: Decision Cube/Mxconsts.pas:138 Vcl/Mxconsts.pas:138 +msgid "Summary of %s" +msgstr "Sumario de %s" + +#. Programmer's name for it: sUnsupportedVarType +#: Decision Cube/Mxconsts.pas:139 Vcl/Mxconsts.pas:139 +msgid "Unsupported Data Type %d" +msgstr "Tipo de dato no soportado" + +#. Programmer's name for it: sOtherValues +#: Decision Cube/Mxconsts.pas:140 Vcl/Mxconsts.pas:140 +msgid "Other Values" +msgstr "Otros valores" + +#. Programmer's name for it: sSelectFromError +#: Decision Cube/Mxconsts.pas:142 Vcl/Mxconsts.pas:142 +msgid "Query lacks a Select/From clause." +msgstr "La consulta carece de una cláusula Select/From." + +#. Programmer's name for it: sArgumentExpected +#: Decision Cube/Mxconsts.pas:143 Vcl/Mxconsts.pas:143 +msgid "No argument provided for an operator or summary" +msgstr "No se proveyó ningún argumento para un operador o sumario" + +#. Programmer's name for it: sGroupOnExpressionError +#: Decision Cube/Mxconsts.pas:144 Vcl/Mxconsts.pas:144 +msgid "An expression cannot be used for a grouping field" +msgstr "No es posible utilizar una expresión para un campo de agrupamiento" + +#. Programmer's name for it: SOutofBounds +#: Decision Cube/Mxconsts.pas:146 Vcl/Mxconsts.pas:146 +msgid "Out of Bounds" +msgstr "Fuera de Límites" + +#. Programmer's name for it: sIDAPILangID +#. Programmer's name for it: SIDAPILangID +#. Programmer's name for it: sIDAPILangID +#: Decision Cube/Mxconsts.pas:147 Vcl/bdeconst.pas:47 Vcl/Mxconsts.pas:147 +msgid "0009" +msgstr "" + +#. Programmer's name for it: sComponentTabName +#: Decision Cube/MXDCONST.PAS:14 +msgid "Decision Cube" +msgstr "Cubo de Decisión" + +#. Programmer's name for it: sQueryVerb0 +#: Decision Cube/MXDCONST.PAS:15 +msgid "&Graphical Query Builder..." +msgstr "" + +#. Programmer's name for it: sQueryVerb1 +#: Decision Cube/MXDCONST.PAS:16 +msgid "&Decision Query Editor..." +msgstr "" + +#. Programmer's name for it: sCubeVerb0 +#: Decision Cube/MXDCONST.PAS:17 +msgid "&Decision Cube Editor..." +msgstr "&Editor de Cubo de Decisión..." + +#. Programmer's name for it: sCubeVerb1 +#: Decision Cube/MXDCONST.PAS:18 +msgid "&Query Editor..." +msgstr "" + +#. Programmer's name for it: sGridVerb0 +#: Decision Cube/MXDCONST.PAS:19 +msgid "Sub&totals on/off" +msgstr "Sub&totales si/no" + +#. Programmer's name for it: sSourceVerb0 +#: Decision Cube/MXDCONST.PAS:20 +msgid "&Do not display Sparse Rows/Columns" +msgstr "" + +#. Programmer's name for it: sSourceVerb1 +#: Decision Cube/MXDCONST.PAS:21 +msgid "&Display Sparse Rows/Columns" +msgstr "" + +#. Programmer's name for it: sGridDimOptions +#: Decision Cube/MXDCONST.PAS:22 +msgid "Grid Dimension Options" +msgstr "Opciones de la Dimensión de la Rejilla" + +#. Programmer's name for it: sGridDimSettings +#: Decision Cube/MXDCONST.PAS:23 +msgid "Grid Dimension Settings" +msgstr "Configuración de la Dimensión de la Rejilla" + +#. Programmer's name for it: sCubeProperties +#: Decision Cube/MXDCONST.PAS:24 +msgid "Cube Properties" +msgstr "Propiedades del Cubo" + +#. Programmer's name for it: RSAlreadyConnected +#: Indy/IdResourceStrings.pas:7 +msgid "Already connected." +msgstr "Ya está conectado." + +#. Programmer's name for it: RSByteIndexOutOfBounds +#: Indy/IdResourceStrings.pas:8 +msgid "Byte index out of range." +msgstr "Indice de Byte fuera de rango." + +#. Programmer's name for it: RSCannotAllocateSocket +#: Indy/IdResourceStrings.pas:9 +msgid "Cannot allocate socket." +msgstr "No se encuentra el socket." + +#. Programmer's name for it: RSConnectionClosedGracefully +#: Indy/IdResourceStrings.pas:10 +msgid "Connection Closed Gracefully." +msgstr "Conexión cerrada." + +#. Programmer's name for it: RSConnectionClosedGracefully +#: Indy/IdResourceStrings.pas:12 +msgid "Could not bind socket. Address and port are already in use." +msgstr "Could not bind socket. Address and port are already in use." + +#. Programmer's name for it: RSFailedTimeZoneInfo +#: Indy/IdResourceStrings.pas:13 +msgid "Failed attempting to retrieve time zone information." +msgstr "Fallo al intentar recuperar la información de hora de la zona." + +#. Programmer's name for it: RSNoBindingsSpecified +#: Indy/IdResourceStrings.pas:14 +msgid "No bindings specified." +msgstr "Encuadernación no especificada." + +#. Programmer's name for it: RSOnExecuteNotAssigned +#: Indy/IdResourceStrings.pas:15 +msgid "OnExecute not assigned." +msgstr "Evento OnExecute no asignado." + +#. Programmer's name for it: RSNotAllBytesSent +#: Indy/IdResourceStrings.pas:16 +msgid "Not all bytes sent." +msgstr "No se han enviado todos los bytes." + +#. Programmer's name for it: RSNotEnoughDataInBuffer +#: Indy/IdResourceStrings.pas:17 +msgid "Not enough data in buffer." +msgstr "No hay datos suficientes en el búfer." + +#. Programmer's name for it: RSPackageSizeTooBig +#: Indy/IdResourceStrings.pas:18 +msgid "Package Size Too Big." +msgstr "El tamaño del paquete es demasiado grande." + +#. Programmer's name for it: RSUDPReceiveError0 +#: Indy/IdResourceStrings.pas:19 +msgid "UDP Receive Error = 0." +msgstr "Se ha producido un error al recibir UDP = 0." + +#. Programmer's name for it: RSRawReceiveError0 +#: Indy/IdResourceStrings.pas:20 +msgid "Raw Receive Error = 0." +msgstr "Se ha producido un error al recibir Raw = 0." + +#. Programmer's name for it: RSICMPReceiveError0 +#: Indy/IdResourceStrings.pas:21 +msgid "ICMP Receive Error = 0." +msgstr "Se ha producido un error al recibir ICMP = 0." + +#. Programmer's name for it: RSWinsockInitializationError +#: Indy/IdResourceStrings.pas:22 +msgid "Winsock Initialization Error." +msgstr "Hay un error de inicialización de Winsock." + +#. Programmer's name for it: RSCouldNotLoad +#: Indy/IdResourceStrings.pas:23 +msgid "%s could not be loaded." +msgstr "%s no puede ser cargado." + +#. Programmer's name for it: RSSetSizeExceeded +#: Indy/IdResourceStrings.pas:24 +msgid "Set Size Exceeded." +msgstr "Asignación de tamaño excedida." + +#. Programmer's name for it: RSThreadClassNotSpecified +#: Indy/IdResourceStrings.pas:25 +msgid "Thread Class Not Specified." +msgstr "Clase Thread no especificada." + +#. Programmer's name for it: RSCannotChangeDebugTargetAtWhileActive +#: Indy/IdResourceStrings.pas:26 +msgid "Cannot change target while active." +msgstr "No se puede cambiar objetivo mientras esté activo." + +#. Programmer's name for it: RSOnlyOneAntiFreeze +#: Indy/IdResourceStrings.pas:27 +msgid "Only one TIdAntiFreeze can exist per application." +msgstr "Sólo puede existir un TIdAntiFreeze por aplicación." + +#. Programmer's name for it: RSOnlyOneAntiFreeze +#: Indy/IdResourceStrings.pas:29 +msgid "InterceptEnabled cannot be set to true when Intercept is nil." +msgstr "InterceptEnabled cannot be set to true when Intercept is nil." + +#. Programmer's name for it: RSInterceptPropInvalid +#: Indy/IdResourceStrings.pas:30 +msgid "Intercept value is not valid" +msgstr "Valor de Intercept no válido" + +#. Programmer's name for it: RSObjectTypeNotSupported +#: Indy/IdResourceStrings.pas:31 +msgid "Object type not supported." +msgstr "Tipo de objeto no soportado." + +#: Indy/IdResourceStrings.pas:33 +msgid "AcceptWait property cannot be modified while server is active." +msgstr "" + +#. Programmer's name for it: RSNoExecuteSpecified +#: Indy/IdResourceStrings.pas:34 +msgid "No execute handler found." +msgstr "Ejecución guiada no especificada." + +#. Programmer's name for it: RSIdNoDataToRead +#: Indy/IdResourceStrings.pas:35 +msgid "No data to read." +msgstr "No hay datos para leer." + +#. Status Strings +#: Indy/IdResourceStrings.pas:37 +msgid "Resolving hostname %s." +msgstr "" + +#. Programmer's name for it: RSStatusConnecting +#: Indy/IdResourceStrings.pas:38 +msgid "Connecting to %s." +msgstr "Conectando a %s." + +#. Programmer's name for it: RSStatusConnected +#. Programmer's name for it: RSLogConnected +#: Indy/IdResourceStrings.pas:39 Indy/IdResourceStrings.pas:327 +msgid "Connected." +msgstr "Conectado." + +#. Programmer's name for it: RSStatusDisconnecting +#: Indy/IdResourceStrings.pas:40 +msgid "Disconnecting from %s." +msgstr "Desconectando desde %s." + +#. Programmer's name for it: RSStatusDisconnected +#: Indy/IdResourceStrings.pas:41 +msgid "Not connected." +msgstr "No conectado." + +#. Programmer's name for it: RSStatusText +#: Indy/IdResourceStrings.pas:42 +msgid "%s" +msgstr "%s" + +#. IdRegister +#: Indy/IdResourceStrings.pas:44 +msgid "Indy Clients" +msgstr "" + +#. Programmer's name for it: RSRegIndyServers +#: Indy/IdResourceStrings.pas:45 +msgid "Indy Servers" +msgstr "Servidores Indy" + +#. Programmer's name for it: RSRegIndyMisc +#: Indy/IdResourceStrings.pas:46 +msgid "Indy Misc" +msgstr "Indy Misc" + +#. IdCoder3To4 +#: Indy/IdResourceStrings.pas:48 +msgid "Coding table entry not found." +msgstr "" + +#. MessageClient Strings +#: Indy/IdResourceStrings.pas:50 +msgid "Encoding text" +msgstr "" + +#. Programmer's name for it: RSMsgClientEncodingAttachment +#: Indy/IdResourceStrings.pas:51 +msgid "Encoding attachment" +msgstr "Codificando datos adjuntos" + +#. NNTP Exceptions +#: Indy/IdResourceStrings.pas:53 +msgid "Connection explicitly refused by NNTP server." +msgstr "" + +#. Programmer's name for it: RSNNTPStringListNotInitialized +#: Indy/IdResourceStrings.pas:54 +msgid "Stringlist not initialized!" +msgstr "Lista no inicializada!" + +#. Programmer's name for it: RSNNTPNoOnNewsgroupList +#: Indy/IdResourceStrings.pas:55 +msgid "No OnNewsgroupList event has been defined." +msgstr "El evento OnNewsgroupList no ha sido definido." + +#. Programmer's name for it: RSNNTPNoOnNewGroupsList +#: Indy/IdResourceStrings.pas:56 +msgid "No OnNewGroupsList event has been defined." +msgstr "El evento OnNewGroupsList no ha sido definido." + +#. Programmer's name for it: RSNNTPNoOnNewNewsList +#: Indy/IdResourceStrings.pas:57 +msgid "No OnNewNewsList event has been defined." +msgstr "El evento OnNewNewsList no ha sido definido." + +#. HTTP Status +#: Indy/IdResourceStrings.pas:59 +msgid "Chunk Started" +msgstr "" + +#. Programmer's name for it: RSHTTPContinue +#: Indy/IdResourceStrings.pas:60 +msgid "Continue" +msgstr "Continuar" + +#. Programmer's name for it: RSHTTPSwitchingProtocols +#: Indy/IdResourceStrings.pas:61 +msgid "Switching protocols" +msgstr "Protocolos Switching" + +#. Programmer's name for it: RSHTTPCreated +#: Indy/IdResourceStrings.pas:63 +msgid "Created" +msgstr "Creado" + +#. Programmer's name for it: RSHTTPAccepted +#: Indy/IdResourceStrings.pas:64 +msgid "Accepted" +msgstr "Aceptado" + +#. Programmer's name for it: RSHTTPNonAuthoritativeInformation +#: Indy/IdResourceStrings.pas:65 +msgid "Non-authoritative Information" +msgstr "Información sin autoridad" + +#. Programmer's name for it: RSHTTPNoContent +#: Indy/IdResourceStrings.pas:66 +msgid "No Content" +msgstr "Sin contenido" + +#. Programmer's name for it: RSHTTPResetContent +#: Indy/IdResourceStrings.pas:67 +msgid "Reset Content" +msgstr "Resetear contenido" + +#. Programmer's name for it: RSHTTPPartialContent +#: Indy/IdResourceStrings.pas:68 +msgid "Partial Content" +msgstr "Contenido parcial" + +#. Programmer's name for it: RSHTTPMovedPermanently +#: Indy/IdResourceStrings.pas:69 +msgid "Moved Permanently" +msgstr "Movido permanentemente" + +#. Programmer's name for it: RSHTTPMovedTemporarily +#: Indy/IdResourceStrings.pas:70 +msgid "Moved Temporarily" +msgstr "Movido temporalmente" + +#. Programmer's name for it: RSHTTPSeeOther +#: Indy/IdResourceStrings.pas:71 +msgid "See Other" +msgstr "Ver otro" + +#. Programmer's name for it: RSHTTPNotModified +#: Indy/IdResourceStrings.pas:72 +msgid "Not Modified" +msgstr "No modificado" + +#. Programmer's name for it: RSHTTPUseProxy +#: Indy/IdResourceStrings.pas:73 +msgid "Use Proxy" +msgstr "Usar Proxy" + +#. Programmer's name for it: RSHTTPBadRequest +#: Indy/IdResourceStrings.pas:74 +msgid "Bad Request" +msgstr "Respuesta errónea" + +#. Programmer's name for it: RSHTTPUnauthorized +#: Indy/IdResourceStrings.pas:75 +msgid "Unauthorized" +msgstr "No autorizado" + +#. Programmer's name for it: RSHTTPForbidden +#: Indy/IdResourceStrings.pas:76 +msgid "Forbidden" +msgstr "Prohibido" + +#. Programmer's name for it: RSHTTPNotFound +#: Indy/IdResourceStrings.pas:77 +msgid "Not Found" +msgstr "No encontrado" + +#. Programmer's name for it: RSHTTPMethodeNotallowed +#: Indy/IdResourceStrings.pas:78 +msgid "Method not allowed" +msgstr "Método no admitido" + +#. Programmer's name for it: RSHTTPNotAcceptable +#: Indy/IdResourceStrings.pas:79 +msgid "Not Acceptable" +msgstr "No aceptable" + +#. Programmer's name for it: RSHTTPProxyAuthenticationRequired +#: Indy/IdResourceStrings.pas:80 +msgid "Proxy Authentication Required" +msgstr "Autentificación de Proxy requerida" + +#. Programmer's name for it: RSHTTPRequestTimeout +#: Indy/IdResourceStrings.pas:81 +msgid "Request Timeout" +msgstr "Respuesta fuera de tiempo" + +#. Programmer's name for it: RSHTTPConflict +#: Indy/IdResourceStrings.pas:82 +msgid "Conflict" +msgstr "Conflicto" + +#. Programmer's name for it: RSHTTPGone +#: Indy/IdResourceStrings.pas:83 +msgid "Gone" +msgstr "Ido" + +#. Programmer's name for it: RSHTTPLengthRequired +#: Indy/IdResourceStrings.pas:84 +msgid "Length Required" +msgstr "Tamaño requerido" + +#. Programmer's name for it: RSHTTPPreconditionFailed +#: Indy/IdResourceStrings.pas:85 +msgid "Precondition Failed" +msgstr "Precondición fallida" + +#. Programmer's name for it: RSHTTPRequestEntityToLong +#: Indy/IdResourceStrings.pas:86 +msgid "Request Entity To Long" +msgstr "Entidad de respuesta a alargar" + +#. Programmer's name for it: RSHTTPRequestURITooLong +#: Indy/IdResourceStrings.pas:87 +msgid "Request-URI Too Long. 256 Chars max" +msgstr "Respuesta URI demasiado larga. 256 caracteres máximo" + +#. Programmer's name for it: RSHTTPUnsupportedMediaType +#: Indy/IdResourceStrings.pas:88 +msgid "Unsupported Media Type" +msgstr "Tipo de medio no soportado" + +#. Programmer's name for it: RSHTTPInternalServerError +#: Indy/IdResourceStrings.pas:89 +msgid "Internal Server Error" +msgstr "Hay un error interno del servidor" + +#. Programmer's name for it: RSHTTPNotImplemented +#: Indy/IdResourceStrings.pas:90 +msgid "Not Implemented" +msgstr "No implementado" + +#. Programmer's name for it: RSHTTPBadGateway +#: Indy/IdResourceStrings.pas:91 +msgid "Bad Gateway" +msgstr "Gateway erróneo" + +#. Programmer's name for it: RSHTTPServiceUnavailable +#: Indy/IdResourceStrings.pas:92 +msgid "Service Unavailable" +msgstr "Servicio no disponible" + +#. Programmer's name for it: RSHTTPGatewayTimeout +#: Indy/IdResourceStrings.pas:93 +msgid "Gateway timeout" +msgstr "Gateway fuera de tiempo" + +#. Programmer's name for it: RSHTTPHTTPVersionNotSupported +#: Indy/IdResourceStrings.pas:94 +msgid "HTTP version not supported" +msgstr "Versión de HTTP no soportada" + +#. Programmer's name for it: RSHTTPUnknownResponseCode +#: Indy/IdResourceStrings.pas:95 +msgid "Unknown Response Code" +msgstr "Código de respuesta desconocido" + +#. HTTP Other +#: Indy/IdResourceStrings.pas:97 +msgid "Header has already been written." +msgstr "" + +#. Programmer's name for it: RSHTTPErrorParsingCommand +#: Indy/IdResourceStrings.pas:98 +msgid "Error in parsing command." +msgstr "Hay un error en el comando de corrección." + +#. Programmer's name for it: RSHTTPUnsupportedAuthorisationScheme +#: Indy/IdResourceStrings.pas:99 +msgid "Unsupported authorization scheme." +msgstr "Combinación de autorización no soportada." + +#. Programmer's name for it: RSHTTPUnsupportedAuthorisationScheme +#: Indy/IdResourceStrings.pas:101 +msgid "Cannot change session state when the server is active." +msgstr "" + +#. FTP +#. Programmer's name for it: SUnknown +#: Indy/IdResourceStrings.pas:104 Internet/XMLDoc.pas:512 +msgid "Unknown" +msgstr "" + +#. Property editor exceptions +#: Indy/IdResourceStrings.pas:106 +msgid "%s is corrupt." +msgstr "" + +#. Programmer's name for it: RSInvalidServiceName +#: Indy/IdResourceStrings.pas:107 +msgid "%s is not a valid service." +msgstr "%s no es un servicio válido." + +#. Stack Error Messages +#: Indy/IdResourceStrings.pas:109 +msgid "" +"Socket Error # %d\n" +"%s" +msgstr "" + +#. Programmer's name for it: RSStackEINTR +#: Indy/IdResourceStrings.pas:110 +msgid "Interrupted system call." +msgstr "Llamada de sistema interrumpida." + +#. Programmer's name for it: RSStackEBADF +#: Indy/IdResourceStrings.pas:111 +msgid "Bad file number." +msgstr "Numero de archivo erróneo." + +#. Programmer's name for it: RSStackEACCES +#: Indy/IdResourceStrings.pas:112 +msgid "Access denied." +msgstr "Acceso denegado." + +#. Programmer's name for it: RSStackEFAULT +#: Indy/IdResourceStrings.pas:113 +msgid "Bad address." +msgstr "Dirección errónea." + +#. Programmer's name for it: RSStackEINVAL +#: Indy/IdResourceStrings.pas:114 +msgid "Invalid argument." +msgstr "Argumento no válido." + +#. Programmer's name for it: RSStackEMFILE +#: Indy/IdResourceStrings.pas:115 +msgid "Too many open files." +msgstr "Demasiados archivos abiertos." + +#. Programmer's name for it: RSStackEWOULDBLOCK +#: Indy/IdResourceStrings.pas:116 +msgid "Operation would block. " +msgstr "Bloquearía la operación. " + +#. Programmer's name for it: RSStackEINPROGRESS +#: Indy/IdResourceStrings.pas:117 +msgid "Operation now in progress." +msgstr "Operación ahora en progreso." + +#. Programmer's name for it: RSStackEALREADY +#: Indy/IdResourceStrings.pas:118 +msgid "Operation already in progress." +msgstr "Operación ya en progreso." + +#. Programmer's name for it: RSStackENOTSOCK +#: Indy/IdResourceStrings.pas:119 +msgid "Socket operation on non-socket." +msgstr "Operación de Socket en non-socket." + +#. Programmer's name for it: RSStackEDESTADDRREQ +#: Indy/IdResourceStrings.pas:120 +msgid "Destination address required." +msgstr "Dirección de destino requerida." + +#. Programmer's name for it: RSStackEMSGSIZE +#: Indy/IdResourceStrings.pas:121 +msgid "Message too long." +msgstr "Mensaje demasiado largo." + +#. Programmer's name for it: RSStackEPROTOTYPE +#: Indy/IdResourceStrings.pas:122 +msgid "Protocol wrong type for socket." +msgstr "Protocolo de tipo incorrecto para socket." + +#. Programmer's name for it: RSStackENOPROTOOPT +#: Indy/IdResourceStrings.pas:123 +msgid "Bad protocol option." +msgstr "Opción de protocolo errónea." + +#. Programmer's name for it: RSStackEPROTONOSUPPORT +#: Indy/IdResourceStrings.pas:124 +msgid "Protocol not supported." +msgstr "Protocolo no soportado." + +#. Programmer's name for it: RSStackESOCKTNOSUPPORT +#: Indy/IdResourceStrings.pas:125 +msgid "Socket type not supported." +msgstr "Tipo de Socket no soportado." + +#. Programmer's name for it: RSStackEOPNOTSUPP +#: Indy/IdResourceStrings.pas:126 +msgid "Operation not supported on socket." +msgstr "Operación no soportada en socket." + +#. Programmer's name for it: RSStackEPFNOSUPPORT +#: Indy/IdResourceStrings.pas:127 +msgid "Protocol family not supported." +msgstr "Familia de protocolo no soportada." + +#. Programmer's name for it: RSStackEAFNOSUPPORT +#: Indy/IdResourceStrings.pas:128 +msgid "Address family not supported by protocol family." +msgstr "Address family not supported by protocol family." + +#. Programmer's name for it: RSStackEADDRINUSE +#: Indy/IdResourceStrings.pas:129 +msgid "Address already in use." +msgstr "Dirección ya en uso." + +#. Programmer's name for it: RSStackEADDRNOTAVAIL +#: Indy/IdResourceStrings.pas:130 +msgid "Cannot assign requested address." +msgstr "No se puede asignar dirección de respuesta." + +#. Programmer's name for it: RSStackENETDOWN +#: Indy/IdResourceStrings.pas:131 +msgid "Network is down." +msgstr "Red caída." + +#. Programmer's name for it: RSStackENETUNREACH +#: Indy/IdResourceStrings.pas:132 +msgid "Network is unreachable." +msgstr "" + +#. Programmer's name for it: RSStackENETRESET +#: Indy/IdResourceStrings.pas:133 +msgid "Net dropped connection or reset." +msgstr "Conexión de red caída o reseteada" + +#. Programmer's name for it: RSStackECONNABORTED +#: Indy/IdResourceStrings.pas:134 +msgid "Software caused connection abort." +msgstr "El software causo que se abortara la conexión." + +#. Programmer's name for it: RSStackECONNRESET +#: Indy/IdResourceStrings.pas:135 +msgid "Connection reset by peer." +msgstr "Connection reset by peer." + +#. Programmer's name for it: RSStackENOBUFS +#: Indy/IdResourceStrings.pas:136 +msgid "No buffer space available." +msgstr "Espacio del búfer no disponible." + +#. Programmer's name for it: RSStackEISCONN +#: Indy/IdResourceStrings.pas:137 +msgid "Socket is already connected." +msgstr "El Socket está actualmente conectado." + +#. Programmer's name for it: RSStackENOTCONN +#: Indy/IdResourceStrings.pas:138 +msgid "Socket is not connected." +msgstr "El Socket no está conectado." + +#. Programmer's name for it: RSStackESHUTDOWN +#: Indy/IdResourceStrings.pas:139 +msgid "Cannot send or receive after socket is closed." +msgstr "No se puede enviar y/o recibir una vez que el socket esté cerrado." + +#. Programmer's name for it: RSStackETOOMANYREFS +#: Indy/IdResourceStrings.pas:140 +msgid "Too many references, cannot splice." +msgstr "Demasiadas referencias, no se pueden unir." + +#. Programmer's name for it: RSStackETIMEDOUT +#: Indy/IdResourceStrings.pas:141 +msgid "Connection timed out." +msgstr "Conexión fuera de tiempo." + +#. Programmer's name for it: RSStackECONNREFUSED +#. Programmer's name for it: RSSocksServerConnectionRefusedError +#: Indy/IdResourceStrings.pas:142 Indy/IdResourceStrings.pas:284 +msgid "Connection refused." +msgstr "Conexión rechazada." + +#. Programmer's name for it: RSStackELOOP +#: Indy/IdResourceStrings.pas:143 +msgid "Too many levels of symbolic links." +msgstr "Demasiados niveles de enlaces simbólicos." + +#. Programmer's name for it: RSStackENAMETOOLONG +#: Indy/IdResourceStrings.pas:144 +msgid "File name too long." +msgstr "Nombre de archivo demasiado largo." + +#. Programmer's name for it: RSStackEHOSTDOWN +#: Indy/IdResourceStrings.pas:145 +msgid "Host is down." +msgstr "Host caído." + +#. Programmer's name for it: RSStackEHOSTUNREACH +#: Indy/IdResourceStrings.pas:146 +msgid "No route to host." +msgstr "No guiado al host." + +#. Programmer's name for it: RSStackENOTEMPTY +#: Indy/IdResourceStrings.pas:147 +msgid "Directory not empty" +msgstr "Directorio no vacío" + +#. Programmer's name for it: RSStackEPROCLIM +#: Indy/IdResourceStrings.pas:148 +msgid "Too many processes." +msgstr "Demasiados procesos." + +#. Programmer's name for it: RSStackEUSERS +#: Indy/IdResourceStrings.pas:149 +msgid "Too many users." +msgstr "Demasiados usuarios." + +#. Programmer's name for it: RSStackEDQUOT +#: Indy/IdResourceStrings.pas:150 +msgid "Disk Quota Exceeded." +msgstr "Cuenta de tamaño en disco excedida." + +#. Programmer's name for it: RSStackESTALE +#: Indy/IdResourceStrings.pas:151 +msgid "Stale NFS file handle." +msgstr "" + +#. Programmer's name for it: RSStackEREMOTE +#: Indy/IdResourceStrings.pas:152 +msgid "Too many levels of remote in path." +msgstr "Demasiados niveles de la ruta remota." + +#. Programmer's name for it: RSStackSYSNOTREADY +#: Indy/IdResourceStrings.pas:153 +msgid "Network subsystem is unavailable." +msgstr "Subsistema de red no disponible." + +#. Programmer's name for it: RSStackVERNOTSUPPORTED +#: Indy/IdResourceStrings.pas:154 +msgid "WINSOCK DLL Version out of range." +msgstr "Versión WINSOCK DLL fuera de rango." + +#. Programmer's name for it: RSStackNOTINITIALISED +#: Indy/IdResourceStrings.pas:155 +msgid "Winsock not loaded yet." +msgstr "Winsock no cargado todavía." + +#. Programmer's name for it: RSStackHOST_NOT_FOUND +#: Indy/IdResourceStrings.pas:156 +msgid "Host not found." +msgstr "Host no encontrado." + +#. Programmer's name for it: RSStackHOST_NOT_FOUND +#: Indy/IdResourceStrings.pas:158 +msgid "Non-authoritative response (try again or check DNS setup)." +msgstr "" + +#. Programmer's name for it: RSStackNO_RECOVERY +#: Indy/IdResourceStrings.pas:159 +msgid "Non-recoverable errors: FORMERR, REFUSED, NOTIMP." +msgstr "Errores no recuperables: FORMERR, REFUSED, NOTIMP." + +#. Programmer's name for it: RSStackNO_DATA +#: Indy/IdResourceStrings.pas:160 +msgid "Valid name, no data record (check DNS setup)." +msgstr "Nombre válido, datos no grabados (verifique la configuración DNS)." + +#. Programmer's name for it: RSCMDNotRecognized +#: Indy/IdResourceStrings.pas:162 +msgid "command not recognized" +msgstr "comando no reconocido" + +#. Programmer's name for it: RSGopherNotGopherPlus +#: Indy/IdResourceStrings.pas:164 +msgid "%s is not a Gopher+ server" +msgstr "%s no es un servidor Gopher+" + +#. Programmer's name for it: RSCodeNoError +#: Indy/IdResourceStrings.pas:166 +msgid "RCode NO Error" +msgstr "Hay un error RCode NO" + +#. Programmer's name for it: RSCodeQueryFormat +#: Indy/IdResourceStrings.pas:167 +msgid "DNS Server Reports Query Format Error" +msgstr "El servidor DNS mostró un error en el formato de la consulta" + +#. Programmer's name for it: RSCodeQueryServer +#: Indy/IdResourceStrings.pas:168 +msgid "DNS Server Reports Query Server Error" +msgstr "El servidor DNS mostró un error del servidor en la consulta" + +#. Programmer's name for it: RSCodeQueryName +#: Indy/IdResourceStrings.pas:169 +msgid "DNS Server Reports Query Name Error" +msgstr "El servidor DNS mostró un error en el nombre de la consulta" + +#. Programmer's name for it: RSCodeQueryNotImplemented +#: Indy/IdResourceStrings.pas:170 +msgid "DNS Server Reports Query Not Implemented Error" +msgstr "El servidor DNS mostró un error de No Implementación en la consulta" + +#. Programmer's name for it: RSCodeQueryQueryRefused +#: Indy/IdResourceStrings.pas:171 +msgid "DNS Server Reports Query Refused Error" +msgstr "El servidor DNS mostró un error de rechazo en la consulta" + +#. Programmer's name for it: RSCodeQueryUnknownError +#: Indy/IdResourceStrings.pas:172 +msgid "Server Returned Unknown Error" +msgstr "El servidor retornó un error desconocido" + +#. Programmer's name for it: RSDNSMFIsObsolete +#: Indy/IdResourceStrings.pas:174 +msgid "MF is an Obsolete Command. USE MX." +msgstr "MF es un comando obsoleto. USE MX." + +#. Programmer's name for it: RSDNSMDISObsolete +#: Indy/IdResourceStrings.pas:175 +msgid "MD is an Obsolete Command. Use MX." +msgstr "MD es un comando obsoleto. Use MX." + +#. Programmer's name for it: RSDNSMailAObsolete +#: Indy/IdResourceStrings.pas:176 +msgid "MailA is an Obsolete Command. USE MX." +msgstr "MailA es un comando obsoleto. USE MX." + +#. Programmer's name for it: RSDNSMailBNotImplemented +#: Indy/IdResourceStrings.pas:177 +msgid "-Err 501 MailB is not implemented" +msgstr "-Err 501 MailB no está implementado" + +#. Programmer's name for it: RSQueryInvalidQueryCount +#: Indy/IdResourceStrings.pas:179 +msgid "Invaild Query Count %d" +msgstr "Contador %d de consulta no válido" + +#. Programmer's name for it: RSQueryInvalidPacketSize +#: Indy/IdResourceStrings.pas:180 +msgid "Invalid Packet Size %d" +msgstr "Tamaño de paquete no válido %d" + +#. Programmer's name for it: RSQueryLessThanFour +#: Indy/IdResourceStrings.pas:181 +msgid "Received Packet is too small. Less than 4 bytes %d" +msgstr "El paquete recibido es demasiado pequeño. Más que 4 bytes %d" + +#. Programmer's name for it: RSQueryInvalidHeaderID +#: Indy/IdResourceStrings.pas:182 +msgid "Invalid Header Id %d" +msgstr "Id %d de cabecera invalido" + +#. Programmer's name for it: RSQueryLessThanTwelve +#: Indy/IdResourceStrings.pas:183 +msgid "Received Packet is too small. Less than 12 bytes %d" +msgstr "El paquete recibido es demasiado pequeño. Más que 12 bytes %d" + +#. Programmer's name for it: RSQueryPackReceivedTooSmall +#: Indy/IdResourceStrings.pas:184 +msgid "Received Packet is too small. %d" +msgstr "El paquete recibido es demasiado pequeño. %d" + +#. Programmer's name for it: RSLPDDataFileSaved +#: Indy/IdResourceStrings.pas:187 +msgid "Data file saved to %s" +msgstr "Datos de archivo guardados en %s" + +#. Programmer's name for it: RSLPDControlFileSaved +#: Indy/IdResourceStrings.pas:188 +msgid "Control file save to %s" +msgstr "Archivo de control guardado en %s" + +#. Programmer's name for it: RSLPDDirectoryDoesNotExist +#: Indy/IdResourceStrings.pas:189 +msgid "Directory %s does not exist" +msgstr "El directorio %s no existe" + +#. Programmer's name for it: RSLPDServerStartTitle +#: Indy/IdResourceStrings.pas:190 +msgid "Winshoes LPD Server %s " +msgstr "Servidor Winshoes LPD %s " + +#. Programmer's name for it: RSLPDServerActive +#: Indy/IdResourceStrings.pas:191 +msgid "Server status: active" +msgstr "Estado del servidor: activo" + +#. Programmer's name for it: RSLPDQueueStatus +#: Indy/IdResourceStrings.pas:192 +msgid "Queue %s status: %s" +msgstr "Estado de la cola %s : %s" + +#. Programmer's name for it: RSLPDClosingConnection +#: Indy/IdResourceStrings.pas:193 +msgid "closing connection" +msgstr "Cerrando conexión" + +#. Programmer's name for it: RSLPDUnknownQueue +#: Indy/IdResourceStrings.pas:194 +msgid "Unknown queue %s" +msgstr "Cola %s desconocida" + +#. Programmer's name for it: RSLPDConnectTo +#: Indy/IdResourceStrings.pas:195 +msgid "connected with %s" +msgstr "Conectado con %s" + +#. Programmer's name for it: RSLPDAbortJob +#: Indy/IdResourceStrings.pas:196 +msgid "abort job" +msgstr "Abortar trabajo" + +#. Programmer's name for it: RSLPDReceiveControlFile +#: Indy/IdResourceStrings.pas:197 +msgid "Receive control file" +msgstr "Recibir archivo de control" + +#. Programmer's name for it: RSLPDReceiveDataFile +#: Indy/IdResourceStrings.pas:198 +msgid "Receive data file" +msgstr "Recibir archivo de datos" + +#. Programmer's name for it: RSLPDNoQueuesDefined +#: Indy/IdResourceStrings.pas:201 +msgid "Error: no queues defined" +msgstr "Error: Listas de trabajo no definidas" + +#. Programmer's name for it: RSTimeOut +#. SocketForm..Pages..PropPage..TimeoutGroup..Caption +#: Indy/IdResourceStrings.pas:204 Vcl/ScktMain.dfm:180 +msgid "Timeout" +msgstr "Fuera de tiempo" + +#. Programmer's name for it: RSTFTPUnexpectedOp +#: Indy/IdResourceStrings.pas:205 +msgid "Unexpected operation from %s:%d" +msgstr "Operación inesperada desde %s:%d" + +#. Programmer's name for it: RSTFTPUnsupportedTrxMode +#: Indy/IdResourceStrings.pas:206 +msgid "Unsupported transfer mode: \"%s\"" +msgstr "Modo de trasnferencia no soportado: \"%s\"" + +#. Programmer's name for it: RSTFTPUnsupportedTrxMode +#: Indy/IdResourceStrings.pas:208 +msgid "Unable to complete write request, progress halted at %d bytes" +msgstr "" + +#. Programmer's name for it: RSTFTPFileNotFound +#: Indy/IdResourceStrings.pas:209 +msgid "Unable to open %s" +msgstr "No se puede abrir %s" + +#. Programmer's name for it: RSTFTPAccessDenied +#: Indy/IdResourceStrings.pas:210 +msgid "Access to %s denied" +msgstr "Acceso a %s denegado" + +#. Programmer's name for it: RSTIdTextInvalidCount +#: Indy/IdResourceStrings.pas:213 +msgid "Invalid Text count. TIdText must be greater than 1" +msgstr "Contador de texto no válido. TIdText debe ser mayor que 1" + +#. Programmer's name for it: RSTIdTextInvalidCount +#: Indy/IdResourceStrings.pas:215 +msgid "TIdMessagePart can not be created. Use descendant classes. " +msgstr "TIdMessagePart no puede ser creado. Use descendant classes. " + +#. Programmer's name for it: RSPOP3FieldNotSpecified +#: Indy/IdResourceStrings.pas:218 +msgid " not specified" +msgstr " no especificado" + +#. Programmer's name for it: RSTELNETSRVUsernamePrompt +#: Indy/IdResourceStrings.pas:221 +msgid "Username: " +msgstr "Nombre de usuario: " + +#. Programmer's name for it: RSTELNETSRVPasswordPrompt +#: Indy/IdResourceStrings.pas:222 +msgid "Password: " +msgstr "Contraseña: " + +#. Programmer's name for it: RSTELNETSRVInvalidLogin +#: Indy/IdResourceStrings.pas:223 +msgid "Invalid Login." +msgstr "Nombre de usuario no válido." + +#. Programmer's name for it: RSTELNETSRVMaxloginAttempt +#: Indy/IdResourceStrings.pas:224 +msgid "Allowed login attempts exceeded, good bye." +msgstr "No se permiten más intentos de acceso, adios." + +#. Programmer's name for it: RSTELNETSRVNoAuthHandler +#: Indy/IdResourceStrings.pas:225 +msgid "No authentication handler has been specified." +msgstr "No ha sido espeficiada una atentifiación." + +#. Programmer's name for it: RSTELNETSRVWelcomeString +#: Indy/IdResourceStrings.pas:226 +msgid "Indy Telnet Server" +msgstr "Servidor Telnet Indy" + +#. Programmer's name for it: RSTELNETSRVOnDataAvailableIsNil +#: Indy/IdResourceStrings.pas:227 +msgid "OnDataAvailable event is nil." +msgstr "El evento OnDataAvailable es nulo." + +#. Programmer's name for it: RSTELNETCLIConnectError +#: Indy/IdResourceStrings.pas:230 +msgid "server not responding" +msgstr "server not responding" + +#. Programmer's name for it: RSTELNETCLIReadError +#: Indy/IdResourceStrings.pas:231 +msgid "Server did not respond." +msgstr "El servidor no respondió." + +#. Programmer's name for it: RSNETCALInvalidIPString +#: Indy/IdResourceStrings.pas:234 +msgid "The string %s does not translate into a valid IP." +msgstr "El texto %s no se puede pasar a una IP válida." + +#. Programmer's name for it: RSNETCALCInvalidNetworkMask +#: Indy/IdResourceStrings.pas:235 +msgid "Invalid network mask." +msgstr "Máscara de red no válida." + +#. Programmer's name for it: RSNETCALCInvalidValueLength +#: Indy/IdResourceStrings.pas:236 +msgid "Invalid value length: Should be 32." +msgstr "Valor de anchura no válido: Debe ser 32." + +#. Programmer's name for it: RSNETCALCInvalidValueLength +#: Indy/IdResourceStrings.pas:238 +msgid "" +"There is too many IP addresses in the specified range (%d) to be displayed " +"at design time." +msgstr "" +"There is too many IP addresses in the specified range (%d) to be displayed " +"at design time." + +#. Programmer's name for it: RSAAboutFormCaption +#: Indy/IdResourceStrings.pas:241 +msgid "About" +msgstr "Acerca de..." + +#. Programmer's name for it: RSAAboutBoxCompName +#: Indy/IdResourceStrings.pas:242 +msgid "Internet Direct (Indy)" +msgstr "Internet Direct (Indy)" + +#. Programmer's name for it: RSAAboutMenuItemName +#: Indy/IdResourceStrings.pas:243 +msgid "About Internet &Direct (Indy) %s..." +msgstr "Acerca de Internet &Direct (Indy) %s..." + +#. Programmer's name for it: RSAAboutBoxVersion +#: Indy/IdResourceStrings.pas:244 +msgid "Version %s" +msgstr "Versión %s" + +#. Programmer's name for it: RSAAboutBoxCopyright +#: Indy/IdResourceStrings.pas:250 +msgid "For the latest updates and information please visit:" +msgstr "For the latest updates and information please visit:" + +#. Programmer's name for it: RSAAboutBoxIndyWebsite +#: Indy/IdResourceStrings.pas:251 +msgid "http://www.nevrona.com/indy/" +msgstr "http://www.nevrona.com/indy/" + +#. Programmer's name for it: RSAAboutCreditsCoordinator +#: Indy/IdResourceStrings.pas:252 +msgid "Project Coordinator" +msgstr "Coordinador de proyecto" + +#. Programmer's name for it: RSAAboutCreditsCoCordinator +#: Indy/IdResourceStrings.pas:253 +msgid "Project Co-Coordinator" +msgstr "Ayte. de Coordinador de proyecto" + +#. Programmer's name for it: RSAAboutCreditsCoCordinator +#: Indy/IdResourceStrings.pas:257 +msgid "Call to %s.GetByte [property Bytes] with index <> [0..%d]" +msgstr "" + +#. Programmer's name for it: RSTunnelTransformErrorBS +#: Indy/IdResourceStrings.pas:258 +msgid "Error in transformation before send" +msgstr "Hay un error en la transformación antes enviada" + +#. Programmer's name for it: RSTunnelTransformError +#: Indy/IdResourceStrings.pas:259 +msgid "Transform failed" +msgstr "Tranformación fallida" + +#. Programmer's name for it: RSTunnelCRCFailed +#: Indy/IdResourceStrings.pas:260 +msgid "CRC Failed" +msgstr "CRC fallido" + +#. Programmer's name for it: RSTunnelConnectMsg +#: Indy/IdResourceStrings.pas:261 +msgid "Connecting" +msgstr "Conectando" + +#. Programmer's name for it: RSTunnelDisconnectMsg +#: Indy/IdResourceStrings.pas:262 +msgid "Disconnect" +msgstr "Desconectado" + +#. Programmer's name for it: RSTunnelConnectToMasterFailed +#: Indy/IdResourceStrings.pas:263 +msgid "Cannt connect to the Master server" +msgstr "No se puede conectar al servidor maestro" + +#. Programmer's name for it: RSTunnelDontAllowConnections +#: Indy/IdResourceStrings.pas:264 +msgid "Do not allow connctions now" +msgstr "No se encuentran conecxiones ahora" + +#. Programmer's name for it: RSTunnelMessageTypeError +#: Indy/IdResourceStrings.pas:265 +msgid "Message type recognition error" +msgstr "Hay un error de tipo de reconocimiento" + +#. Programmer's name for it: RSTunnelMessageHandlingError +#: Indy/IdResourceStrings.pas:266 +msgid "Message handling failed" +msgstr "Message handling failed" + +#. Programmer's name for it: RSTunnelMessageInterpretError +#: Indy/IdResourceStrings.pas:267 +msgid "Interpretation of message failed" +msgstr "Interpretación de mensaje fallida" + +#. Programmer's name for it: RSTunnelMessageCustomInterpretError +#: Indy/IdResourceStrings.pas:268 +msgid "Custom message interpretation failed" +msgstr "Interpretación del mensaje personalizado fallida" + +#. Programmer's name for it: RSSocksRequestFailed +#: Indy/IdResourceStrings.pas:271 +msgid "Request rejected or failed." +msgstr "Respuesta rechazada o fallida." + +#. Programmer's name for it: RSSocksRequestFailed +#: Indy/IdResourceStrings.pas:273 +msgid "Request rejected because SOCKS server cannot connect." +msgstr "Request rejected because SOCKS server cannot connect." + +#. Programmer's name for it: RSSocksRequestFailed +#: Indy/IdResourceStrings.pas:275 +msgid "" +"Request rejected because the client program and identd report different user-" +"ids." +msgstr "" +"Request rejected because the client program and identd report different user-" +"ids." + +#. Programmer's name for it: RSSocksUnknownError +#: Indy/IdResourceStrings.pas:276 +msgid "Unknown socks error." +msgstr "Hay un error de sock desconocido." + +#. Programmer's name for it: RSSocksServerRespondError +#: Indy/IdResourceStrings.pas:277 +msgid "Socks server did not respond." +msgstr "El Sock del servidor no respondió." + +#. Programmer's name for it: RSSocksAuthMethodError +#: Indy/IdResourceStrings.pas:278 +msgid "Invalid socks authentication method." +msgstr "Método de autentificación de socks no válida." + +#. Programmer's name for it: RSSocksAuthError +#: Indy/IdResourceStrings.pas:279 +msgid "Authentication error to socks server." +msgstr "Hay un error de autentificación al socks del servidor." + +#. Programmer's name for it: RSSocksServerGeneralError +#: Indy/IdResourceStrings.pas:280 +msgid "General SOCKS server failure." +msgstr "Hay un error general de SOCKS del servidor." + +#. Programmer's name for it: RSSocksServerPermissionError +#: Indy/IdResourceStrings.pas:281 +msgid "Connection not allowed by ruleset." +msgstr "Conexión no soportada por ruleset." + +#. Programmer's name for it: RSSocksServerNetUnreachableError +#: Indy/IdResourceStrings.pas:282 +msgid "Network unreachable." +msgstr "Red inaccesible." + +#. Programmer's name for it: RSSocksServerHostUnreachableError +#: Indy/IdResourceStrings.pas:283 +msgid "Host unreachable." +msgstr "Host inaccesible." + +#. Programmer's name for it: RSSocksServerTTLExpiredError +#: Indy/IdResourceStrings.pas:285 +msgid "TTL expired." +msgstr "TTL caducada." + +#. Programmer's name for it: RSSocksServerCommandError +#: Indy/IdResourceStrings.pas:286 +msgid "Command not supported." +msgstr "Comando no soportado." + +#. Programmer's name for it: RSSocksServerAddressError +#: Indy/IdResourceStrings.pas:287 +msgid "Address type not supported." +msgstr "Tipo de dirección no soportada." + +#. Programmer's name for it: RSDestinationFileAlreadyExists +#: Indy/IdResourceStrings.pas:290 +msgid "Destination file already exists." +msgstr "El archivo de destino ya existe." + +#. Programmer's name for it: RSSSLAcceptError +#: Indy/IdResourceStrings.pas:293 +msgid "Error accepting connection with SSL." +msgstr "Se ha producido un error al aceptar la conexión con SSL." + +#. Programmer's name for it: RSSSLConnectError +#: Indy/IdResourceStrings.pas:294 +msgid "Error connecting with SSL." +msgstr "Se ha producido un error al conectar con SSL." + +#. Programmer's name for it: RSSSLSettingChiperError +#: Indy/IdResourceStrings.pas:295 +msgid "SetCipher failed." +msgstr "SetCipher fallido." + +#. Programmer's name for it: RSSSLCreatingContextError +#: Indy/IdResourceStrings.pas:296 +msgid "Error creating SSL context." +msgstr "Se ha producido un error al crear un contexto SSL." + +#. Programmer's name for it: RSSSLLoadingRootCertError +#: Indy/IdResourceStrings.pas:297 +msgid "Could not load root certificate." +msgstr "No se puede leer el certificado del administrador." + +#. Programmer's name for it: RSSSLLoadingCertError +#: Indy/IdResourceStrings.pas:298 +msgid "Could not load certificate." +msgstr "No se puede leer el certificado." + +#. Programmer's name for it: RSSSLLoadingKeyError +#: Indy/IdResourceStrings.pas:299 +msgid "Could not load key, check password." +msgstr "No se puede cargar la clave, verifique la contraseña." + +#. Programmer's name for it: RSSSLGetMethodError +#: Indy/IdResourceStrings.pas:300 +msgid "Error geting SSL method." +msgstr "Se ha producido un error al obtener un método SSL." + +#. Programmer's name for it: RSSSLDataBindingError +#: Indy/IdResourceStrings.pas:301 +msgid "Error binding data to SSL socket." +msgstr "Se ha producido un error al encuadernar datos al socket SSL." + +#. Programmer's name for it: RSMsgCmpEdtrNew +#: Indy/IdResourceStrings.pas:303 +msgid "&New Message Part..." +msgstr "&Nueva parte de mensaje..." + +#. Programmer's name for it: RSMsgCmpEdtrExtraHead +#: Indy/IdResourceStrings.pas:304 +msgid "Extra Headers Text Editor" +msgstr "Editor de texto de cabeceras extra" + +#. Programmer's name for it: RSMsgCmpEdtrBodyText +#: Indy/IdResourceStrings.pas:305 +msgid "Body Text Editor" +msgstr "Editor de texto del cuerpo" + +#. Programmer's name for it: RSICMPNotEnoughtBytes +#: Indy/IdResourceStrings.pas:307 +msgid "Not enough bytes received" +msgstr "No se han recibido los suficientes datos" + +#. Programmer's name for it: RSICMPNonEchoResponse +#: Indy/IdResourceStrings.pas:308 +msgid "Non-echo type response received" +msgstr "Respuesta recibida de tipo No-Eco" + +#. Programmer's name for it: RSICMPWrongDestination +#: Indy/IdResourceStrings.pas:309 +msgid "Received someone else's packet" +msgstr "Recibidos algunos paquetes" + +#. Programmer's name for it: RSNNTPServerNotRecognized +#: Indy/IdResourceStrings.pas:311 +msgid "command not recognized (%s)" +msgstr "Comando no reconocido (%s)" + +#. Programmer's name for it: RSNNTPServerGoodBye +#: Indy/IdResourceStrings.pas:312 +msgid "Goodbye" +msgstr "Adios" + +#. Programmer's name for it: RSGopherServerNoProgramCode +#: Indy/IdResourceStrings.pas:314 +msgid "Error: No program code to return request!" +msgstr "Error: Sin código de programa para ofrecer respuesta!" + +#. Programmer's name for it: RSOSSLModeNotSet +#: Indy/IdResourceStrings.pas:317 +msgid "Mode has not been set." +msgstr "El modo no ha sido asignado." + +#. Programmer's name for it: RSOSSLCouldNotLoadSSLLibrary +#: Indy/IdResourceStrings.pas:318 +msgid "Could not load SSL library." +msgstr "No se puede leer la librería SSL." + +#. Programmer's name for it: RSOSSLStatusString +#: Indy/IdResourceStrings.pas:319 +msgid "SSL status: \"%s\"" +msgstr "Estado SSL: \"%s\"" + +#. Programmer's name for it: RSOSSLConnectionDropped +#: Indy/IdResourceStrings.pas:320 +msgid "SSL connection has dropped." +msgstr "La conexión SSL ha sido detenida." + +#. Programmer's name for it: RSOSSLCertificateLookup +#: Indy/IdResourceStrings.pas:321 +msgid "SSL certificate request error." +msgstr "Hay un error en la respuesta de certificado SSL." + +#. Programmer's name for it: RSOSSLInternal +#: Indy/IdResourceStrings.pas:322 +msgid "SSL library internal error." +msgstr "Hay un error interno de librería SSL." + +#. Programmer's name for it: RSWSockStack +#: Indy/IdResourceStrings.pas:325 +msgid "Winsock stack" +msgstr "Winsock stack" + +#. Programmer's name for it: RSLogRecV +#: Indy/IdResourceStrings.pas:328 +msgid "Recv: " +msgstr "Recivido: " + +#. Programmer's name for it: RSLogSent +#: Indy/IdResourceStrings.pas:329 +msgid "Sent: " +msgstr "Enviado: " + +#. Programmer's name for it: RSLogDisconnected +#: Indy/IdResourceStrings.pas:330 +msgid "Disconnected." +msgstr "Desconectado." + +#. Programmer's name for it: RSLogEOL +#: Indy/IdResourceStrings.pas:331 +msgid "" +msgstr "" + +#. Programmer's name for it: sActionDoesNotProvideResponse +#: Internet/AdaptReq.pas:459 +msgid "Action does not provide response" +msgstr "" + +#. Programmer's name for it: sActionCantRespondToUnkownHTTPMethod +#: Internet/AdaptReq.pas:460 +msgid "Action can't respone to unknown HTTP method" +msgstr "" + +#. Programmer's name for it: sActionCantRedirectToBlankURL +#: Internet/AdaptReq.pas:461 +msgid "Action can't redirect to blank URL" +msgstr "" + +#. Programmer's name for it: sOnlyOneDataModuleAllowed +#: Internet/BrkrConst.pas:20 +msgid "Only one data module per application" +msgstr "Sólo se permite un módulo de datos por aplicación" + +#. Programmer's name for it: sNoDataModulesRegistered +#: Internet/BrkrConst.pas:21 +msgid "No data modules registered" +msgstr "No hay módulos de datos registrados" + +#. Programmer's name for it: sNoDispatcherComponent +#: Internet/BrkrConst.pas:22 +msgid "No dispatcher component found on data module" +msgstr "" + +#. Programmer's name for it: sNoWebModulesActivated +#: Internet/BrkrConst.pas:23 +msgid "No automatically activated data modules" +msgstr "" + +#. Programmer's name for it: sTooManyActiveConnections +#: Internet/BrkrConst.pas:25 +msgid "" +"Maximum number of concurrent connections exceeded. Please try again later" +msgstr "" + +#. Programmer's name for it: sInternalServerError +#: Internet/BrkrConst.pas:29 +msgid "" +"Internal Server Error 500\n" +"

                Internal Server Error 500


                \n" +"Exception: %s
                \n" +"Message: %s
                \n" +msgstr "" + +#. Programmer's name for it: sDocumentMoved +#: Internet/BrkrConst.pas:33 +msgid "" +"Document Moved 302\n" +"

                Object Moved


                \n" +"This Object may be found here.
                \n" +"
                \n" +msgstr "" + +#. Programmer's name for it: SDescription +#: Internet/DTDSchema.pas:57 +msgid "DTD to XML Schema Translator (.dtd <-> .xsd)" +msgstr "" + +#. Programmer's name for it: SNodeExpected +#: Internet/msxmldom.pas:401 +msgid "Node cannot be null" +msgstr "" + +#. Programmer's name for it: SMSDOMNotInstalled +#: Internet/msxmldom.pas:402 +msgid "Microsoft MSXML is not installed" +msgstr "" + +#. Programmer's name for it: sInvalidISAPIApp +#: Internet/NSToIS.pas:109 +msgid "Invalid ISAPI application: %s" +msgstr "" + +#. Programmer's name for it: sUnSupportedISAPIApp +#: Internet/NSToIS.pas:110 +msgid "Unsupported ISAPI Application version: %.8x" +msgstr "" + +#. Programmer's name for it: sGEVFailed +#: Internet/NSToIS.pas:111 +msgid "Call to GetExtensionVersion FAILED. Error Code: %d" +msgstr "" + +#. Programmer's name for it: sErrorLoadingISAPIApp +#: Internet/NSToIS.pas:112 +msgid "Error loading ISAPI Application: %s" +msgstr "" + +#. Programmer's name for it: sInvalidRedirectParam +#: Internet/NSToIS.pas:113 +msgid "Invalid Redirect parameter" +msgstr "" + +#. Programmer's name for it: sISAPIAppError +#: Internet/NSToIS.pas:114 +msgid "ISAPI Application Error" +msgstr "" + +#. Adapter errors +#: Internet/SiteConst.pas:16 +msgid "Field %s requires a value" +msgstr "" + +#. Programmer's name for it: sFieldDoesNotAllowMultipleValues +#: Internet/SiteConst.pas:17 +msgid "%s does not allow multiple values" +msgstr "" + +#. Programmer's name for it: sFieldDoesNotAllowMultipleFiles +#: Internet/SiteConst.pas:18 +msgid "%s does not allow multiple files" +msgstr "" + +#. Programmer's name for it: sFieldRequiresAFile +#: Internet/SiteConst.pas:19 +msgid "%s requires a file" +msgstr "" + +#. Programmer's name for it: sFieldModificationNotPermitted +#: Internet/SiteConst.pas:20 +msgid "Modification of %s is not permitted" +msgstr "" + +#. Programmer's name for it: sActionExecutionNotPermitted +#: Internet/SiteConst.pas:21 +msgid "Execution of action %s is not permitted" +msgstr "" + +#. Programmer's name for it: sFieldViewNotPermitted +#: Internet/SiteConst.pas:22 +msgid "Field view not permitted" +msgstr "" + +#. Programmer's name for it: sAdapterModificationNotPermitted +#: Internet/SiteConst.pas:23 +msgid "Data Modification is not permitted" +msgstr "" + +#. Programmer's name for it: sFileUploadNotSupported +#: Internet/SiteConst.pas:24 +msgid "%s does not support file upload" +msgstr "" + +#. Programmer's name for it: sNoLoginPage +#: Internet/SiteConst.pas:25 +msgid "Login page is not defined" +msgstr "" + +#. Programmer's name for it: sPageNotFound +#: Internet/SiteConst.pas:26 +msgid "Web Page not found: %s" +msgstr "" + +#. Programmer's name for it: sPageContentNotProvided +#: Internet/SiteConst.pas:27 +msgid "Web Page does not provide content" +msgstr "" + +#. Programmer's name for it: sImageNotProvided +#: Internet/SiteConst.pas:28 +msgid "Field %s did not provide an image" +msgstr "" + +#. DataSetAdapter errors +#: Internet/SiteConst.pas:31 +msgid "Unknown Adapter mode: %s" +msgstr "Modo de adaptador desconocido: %s" + +#. Programmer's name for it: sNilAdapterDataSet +#: Internet/SiteConst.pas:32 +msgid "DataSet is nil" +msgstr "DataSet no está asignado" + +#. Programmer's name for it: sAdapterRowNotFound +#: Internet/SiteConst.pas:33 +msgid "Row not found in %s" +msgstr "No se ha encontrado la fila en %s" + +#. Programmer's name for it: sFieldChangedByAnotherUser +#: Internet/SiteConst.pas:34 +msgid "Field %s changed by another user" +msgstr "" + +#. Programmer's name for it: sAdapterFieldNotFound +#: Internet/SiteConst.pas:35 +msgid "Field not found: %s" +msgstr "" + +#. Programmer's name for it: sDataSetPropertyIsNil +#: Internet/SiteConst.pas:36 +msgid "%s: DataSet property is nil" +msgstr "%s: Propiedad DataSet no está asignada" + +#. Programmer's name for it: sDataSetUnknownKeyFields +#: Internet/SiteConst.pas:37 +msgid "%0:s: Dataset %1:s unknown keyfields" +msgstr "" + +#. Programmer's name for it: sDataSetNotActive +#: Internet/SiteConst.pas:38 +msgid "%0:s: Dataset %1:s not active" +msgstr "%0:s: Dataset %1:s no está activa" + +#. Programmer's name for it: sValueFieldIsBlank +#: Internet/SiteConst.pas:39 +msgid "%0:s: ValueField property value is blank" +msgstr "" + +#. XSLPageProducer errors +#: Internet/SiteConst.pas:42 +msgid "Missing XML Data Component" +msgstr "Se ha perdido el componente de datos XML" + +#. Programmer's name for it: SNoXMLDocument +#: Internet/SiteConst.pas:43 +msgid "Could not create XMLDocument" +msgstr "" + +#. Add Adapter Fields Editor +#. Programmer's name for it: sAddFieldItems +#: Internet/SiteConst.pas:46 Internet/SiteConst.pas:59 +msgid "Add Fields..." +msgstr "" + +#. Programmer's name for it: sAddAllAdapterData +#. Programmer's name for it: sAddAllFieldItems +#: Internet/SiteConst.pas:47 Internet/SiteConst.pas:60 +msgid "Add All Fields" +msgstr "" + +#. Programmer's name for it: sAddAdapterDataDlgCaption +#. Programmer's name for it: sAddFieldItemsDlgCaption +#. AddFields..Caption +#: Internet/SiteConst.pas:48 Internet/SiteConst.pas:61 Property +#: Editors/DSAdd.dfm:6 +msgid "Add Fields" +msgstr "" + +#. Programmer's name for it: sAddAdapterActions +#: Internet/SiteConst.pas:49 +msgid "Add Actions..." +msgstr "" + +#. Programmer's name for it: sAddAllAdapterActions +#: Internet/SiteConst.pas:50 +msgid "Add All Actions" +msgstr "" + +#. Programmer's name for it: sAddAdapterActionsDlgCaption +#: Internet/SiteConst.pas:51 +msgid "Add Actions" +msgstr "" + +#. Do not location +#. Programmer's name for it: sActionCategoryName +#: Internet/SiteConst.pas:52 ToolsAPI/DesignIntf.pas:428 +msgid "Action" +msgstr "" + +#. Programmer's name for it: sAddCommands +#: Internet/SiteConst.pas:53 +msgid "Add Commands..." +msgstr "" + +#. Programmer's name for it: sAddAllCommands +#: Internet/SiteConst.pas:54 +msgid "Add All Commands" +msgstr "" + +#. Programmer's name for it: sAddCommandsDlgCaption +#: Internet/SiteConst.pas:55 +msgid "Add Commands" +msgstr "" + +#. Programmer's name for it: sAddColumns +#: Internet/SiteConst.pas:56 +msgid "Add Columns..." +msgstr "" + +#. Programmer's name for it: sAddAllColumns +#: Internet/SiteConst.pas:57 +msgid "Add All Columns" +msgstr "" + +#. Programmer's name for it: sAddColumnsDlgCaption +#: Internet/SiteConst.pas:58 +msgid "Add Columns" +msgstr "" + +#. SitePageProducer errors +#: Internet/SiteConst.pas:65 +msgid "%s: Adapter property is nil" +msgstr "" + +#. Programmer's name for it: sAdapterFieldNameIsBlank +#: Internet/SiteConst.pas:66 +msgid "%s: Fieldname is blank" +msgstr "" + +#. 0 - Component name, 1 - Adapter Field name +#: Internet/SiteConst.pas:67 +msgid "%0:s: Field %1:s not found in associated Adapter" +msgstr "" + +#. Programmer's name for it: sAdapterActionNameIsBlank +#: Internet/SiteConst.pas:68 +msgid "%s: Action name is blank" +msgstr "" + +#. 0 - Component name, 1 - Adapter Action name +#: Internet/SiteConst.pas:69 +msgid "%0:s: Action %1:s not found in associated Adapter" +msgstr "" + +#. Programmer's name for it: sDisplayComponentPropertyIsNil +#: Internet/SiteConst.pas:70 +msgid "%s: DisplayComponent property is nil" +msgstr "" + +#. LoginAdapter validation +#: Internet/SiteConst.pas:75 +msgid "Password must not be blank" +msgstr "" + +#. Programmer's name for it: sBlankUserName +#: Internet/SiteConst.pas:76 +msgid "Username must not be blank" +msgstr "" + +#. 0 - Request identifier, 1 - object identifier +#: Internet/SiteConst.pas:79 +msgid "Adapter Request not handled: %0:s, %1:s" +msgstr "" + +#. Programmer's name for it: sDispatchBlankPageName +#: Internet/SiteConst.pas:80 +msgid "Dispatching blank page name" +msgstr "" + +#. Programmer's name for it: sPageAccessDenied +#: Internet/SiteConst.pas:81 +msgid "Page access denied" +msgstr "Acceso denegado a la página" + +#. Programmer's name for it: sPageDoesNotSupportRedirect +#: Internet/SiteConst.pas:82 +msgid "Web Page does not support redirect" +msgstr "" + +#. Include errors +#: Internet/SiteConst.pas:85 +msgid "Can't find included page: %s" +msgstr "" + +#. Programmer's name for it: sInclusionNotSupported +#: Internet/SiteConst.pas:86 +msgid "Page %s does not support inclusion" +msgstr "" + +#. Programmer's name for it: sRecursiveIncludeFile +#: Internet/SiteConst.pas:87 +msgid "Include file %s includes itself" +msgstr "" + +#. DB Image errors +#: Internet/SiteConst.pas:90 +msgid "Incorrect image format (%s) for field %%s" +msgstr "" + +#. Programmer's name for it: sFileExpected +#: Internet/SiteConst.pas:91 +msgid "Uploaded file expected for field %s" +msgstr "" + +#. WebUserList names - must be valid identifiers +#: Internet/SiteConst.pas:94 +msgid "UserName" +msgstr "Nombre de usuario" + +#. Programmer's name for it: sWebUserPassword +#. PasswordDialog..GroupBox1..Caption +#: Internet/SiteConst.pas:95 Clx/QDBPWDlg.xfm:42 Vcl/DbPWDlg.dfm:40 +msgid "Password" +msgstr "Contraseña" + +#. Programmer's name for it: sWebUserAccessRights +#: Internet/SiteConst.pas:96 +msgid "AccessRights" +msgstr "" + +#. WebUserList errors +#: Internet/SiteConst.pas:99 +msgid "UserID not found" +msgstr "UserID no se ha encontrado." + +#. Programmer's name for it: sInvalidPassword +#: Internet/SiteConst.pas:100 +msgid "Invalid password" +msgstr "Contraseña no válida" + +#. Programmer's name for it: sMissingPassword +#: Internet/SiteConst.pas:101 +msgid "Missing password" +msgstr "" + +#. Programmer's name for it: sUnknownUserName +#: Internet/SiteConst.pas:102 +msgid "Unknown user name" +msgstr "Nombre de usuario desconocido" + +#. Programmer's name for it: sMissingUserName +#: Internet/SiteConst.pas:103 +msgid "Missing user name" +msgstr "" + +#. Script errors +#: Internet/SiteConst.pas:107 +msgid "Cannot create script engine: %s. Error: %x" +msgstr "" + +#. 4 - source line text +#: Internet/SiteConst.pas:144 +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"
                \n" +"Error[%0:d]: \n" +"%1:s\n" +"\n" +"
                \n" +"Line: \n" +"%2:d\n" +"\n" +"\n" +"Position: \n" +"%3:d\n" +"\n" +"
                \n" +msgstr "" + +#. Programmer's name for it: sMaximumSessionsExceeded +#: Internet/SiteConst.pas:146 +msgid "Maximum sessions exceeded" +msgstr "" + +#. Programmer's name for it: sVariableNotFound +#: Internet/SiteConst.pas:147 +msgid "Variable not found: %s" +msgstr "No se ha encontrado la variable: %s" + +#. Programmer's name for it: sComponentDoesNotSupportScripting +#: Internet/SiteConst.pas:148 +msgid "Component does not support scripting. Class: %0:s, Name: %1:s" +msgstr "" + +#. Programmer's name for it: sClassDoesNotSupportScripting +#: Internet/SiteConst.pas:149 +msgid "Object does not support scripting. Class: %0:s" +msgstr "" + +#. Programmer's name for it: sWebAppDebugger +#: Internet/SvrConst.pas:14 +msgid "Web App Debugger" +msgstr "" + +#. Programmer's name for it: sStopServer +#: Internet/SvrConst.pas:15 +msgid "Stop" +msgstr "" + +#. Programmer's name for it: sStartServer +#: Internet/SvrConst.pas:16 +msgid "Start" +msgstr "" + +#. Programmer's name for it: sCouldNotOpenRegKey +#: Internet/SvrConst.pas:17 +msgid "Unable to not open registry key: %s" +msgstr "No se puede abrir la llave del registro: %s" + +#. Programmer's name for it: sUnauthorizedString +#. Programmer's name for it: UnauthorizedString +#: Internet/SvrConst.pas:23 Internet/SvrConst.pas:66 +msgid "" +"Unauthorized

                UnauthorizedProper authorization is required for this area. Either your browser does " +"not perform authorization, or your authorization has failed.\n" +msgstr "" + +#. Programmer's name for it: sForbiddenString +#. Programmer's name for it: ForbiddenString +#: Internet/SvrConst.pas:24 Internet/SvrConst.pas:67 +msgid "" +"The requested URL is forbidden

                The requested " +"URL is forbidden

                HTTP status code: 403\n" +msgstr "" + +#. Programmer's name for it: sNoDirBrowseString +#. Programmer's name for it: NoDirBrowseString +#: Internet/SvrConst.pas:25 Internet/SvrConst.pas:68 +msgid "" +"Directory browsing is forbidden

                The requested " +"URL is forbidden

                HTTP status code: 403\n" +msgstr "" + +#. Programmer's name for it: sBadRequest +#. Programmer's name for it: BadRequest +#: Internet/SvrConst.pas:26 Internet/SvrConst.pas:69 +msgid "" +"Invalid HTTP request: Method not allowed for HTTP/1.0</" +"TITLE><BODY><H1>Invalid HTTP request: Method not allowed for HTTP/1.0</" +"H1><P>HTTP status code: 400</BODY></HTML>\n" +msgstr "" + +#. Programmer's name for it: sBadRequest +#. Programmer's name for it: BadRequest +#: Internet/SvrConst.pas:32 Internet/SvrConst.pas:75 +msgid "" +"<TITLE>The requested URL was not found

                The requested URL " +"was not found

                HTTP status code: 404" +msgstr "" + +#. Programmer's name for it: sBadRequest +#: Internet/SvrConst.pas:39 +msgid "" +"Internal Server Error

                Internal Server Error

                HTTP status code: 500

                HTTP error message: %s" +msgstr "" + +#. Programmer's name for it: sInvalidActionRegistration +#: Internet/SvrConst.pas:41 Internet/WebConst.pas:22 +msgid "Invalid Action registration" +msgstr "" + +#. Programmer's name for it: sErrorEvent +#: Internet/SvrConst.pas:42 +msgid "ERROR" +msgstr "" + +#. Programmer's name for it: sResponseEvent +#: Internet/SvrConst.pas:43 +msgid "RESPONSE" +msgstr "" + +#. Programmer's name for it: sEvent +#: Internet/SvrConst.pas:44 +msgid "Event" +msgstr "" + +#. Programmer's name for it: sTime +#. Programmer's name for it: STimeDescription +#: Internet/SvrConst.pas:45 Rtl/Common/StdConvs.pas:452 +msgid "Time" +msgstr "Hora" + +#. Programmer's name for it: sDate +#: Internet/SvrConst.pas:46 +msgid "Date" +msgstr "" + +#. Programmer's name for it: sElapsed +#: Internet/SvrConst.pas:47 +msgid "Elapsed" +msgstr "" + +#. Programmer's name for it: sPath +#: Internet/SvrConst.pas:48 +msgid "Path" +msgstr "" + +#. Programmer's name for it: sCode +#: Internet/SvrConst.pas:49 +msgid "Code" +msgstr "" + +#. Programmer's name for it: sContentLength +#: Internet/SvrConst.pas:50 +msgid "Content Length" +msgstr "" + +#. Programmer's name for it: sContentType +#: Internet/SvrConst.pas:51 +msgid "Content Type" +msgstr "Tipo de contenido" + +#. Programmer's name for it: sThread +#: Internet/SvrConst.pas:52 +msgid "Thread" +msgstr "Thread (hilo)" + +#. Programmer's name for it: sNoDefaultURL +#: Internet/SvrConst.pas:54 +msgid "(none)" +msgstr "" + +#. Programmer's name for it: sLogTab +#: Internet/SvrConst.pas:55 +msgid "Log(%d)" +msgstr "" + +#. Programmer's name for it: sSend +#: Internet/SvrConst.pas:57 +msgid "Send" +msgstr "" + +#. Programmer's name for it: sReceive +#: Internet/SvrConst.pas:58 +msgid "Receive" +msgstr "Recibir" + +#. Programmer's name for it: sLogStrTemplate +#: Internet/SvrConst.pas:59 +msgid "%s %s Error: (%d)%s" +msgstr "" + +#. Programmer's name for it: DateFormat +#: Internet/SvrConst.pas:76 +msgid "ddd, dd mmm yyyy hh:mm:ss" +msgstr "" + +#. Programmer's name for it: sBuild +#: Internet/SvrConst.pas:77 +msgid "Build" +msgstr "" + +#. Programmer's name for it: sDirHeader +#: Internet/SvrConst.pas:79 +msgid "" +"Directory of %s

                Directory of %0:" +"s

                \n" +msgstr "" + +#. Programmer's name for it: sDirParent +#: Internet/SvrConst.pas:80 +msgid "" +"Up to %0:s\n" +"
                  " +msgstr "" + +#. Programmer's name for it: sDirRoot +#: Internet/SvrConst.pas:81 +msgid "" +"Up to root directory\n" +"
                    " +msgstr "" + +#. Programmer's name for it: sDirEntry +#: Internet/SvrConst.pas:82 +msgid "
                  • [ %s ]\n" +msgstr "
                  • [ %s ]\n" + +#. Programmer's name for it: sFileEntry +#: Internet/SvrConst.pas:83 +msgid "
                  • %s (%d bytes)\n" +msgstr "
                  • %s (%d bytes)\n" + +#. Programmer's name for it: sListStart +#: Internet/SvrConst.pas:84 +msgid "
                      \n" +msgstr "
                        \n" + +#. Programmer's name for it: sDirFooter +#: Internet/SvrConst.pas:85 +msgid "
                      \n" +msgstr "
                    \n" + +#. Programmer's name for it: sFileStatus +#: Internet/SvrInfoConst.pas:13 +msgid "File Status:" +msgstr "" + +#. Programmer's name for it: sFound +#: Internet/SvrInfoConst.pas:14 +msgid "Found" +msgstr "Encontrado" + +#. Programmer's name for it: sNotFound +#: Internet/SvrInfoConst.pas:15 +msgid "Not found" +msgstr "No encontrado" + +#. Programmer's name for it: sMissingClsID +#: Internet/SvrInfoConst.pas:16 +msgid "Missing ClassID" +msgstr "" + +#. Programmer's name for it: sGo +#: Internet/SvrInfoConst.pas:17 +msgid "Go" +msgstr "Ir" + +#. Programmer's name for it: sDataSetFieldBlank +#: Internet/WbmConst.pas:15 +msgid "Data set field is blank" +msgstr "" + +#. Programmer's name for it: sDataSetFieldNotFound +#: Internet/WbmConst.pas:16 +msgid "Data set field not found: %s" +msgstr "No se ha encontrado el campo del dataset: %s" + +#. Programmer's name for it: sNotDataSetField +#: Internet/WbmConst.pas:17 +msgid "Field is not a dataset field: %s" +msgstr "" + +#. Programmer's name for it: ScriptTableName +#: Internet/WbmConst.pas:18 +msgid "%s_Table" +msgstr "" + +#. Programmer's name for it: sNoXMLBroker +#: Internet/WbmConst.pas:19 +msgid "%s: missing XMLBroker" +msgstr "" + +#. Programmer's name for it: sFieldNotFound +#: Internet/WbmConst.pas:20 +msgid "%0:s: Field \"%1:s\" not found" +msgstr "" + +#. Programmer's name for it: sXMLBrokerNotDefined +#: Internet/WbmConst.pas:21 +msgid "%s.XMLBroker = nil" +msgstr "" + +#. Programmer's name for it: sSubmitQuery +#: Internet/WbmConst.pas:22 +msgid "Submit" +msgstr "" + +#. Programmer's name for it: sResetQuery +#: Internet/WbmConst.pas:23 +msgid "Reset" +msgstr "Reinicializa" + +#. Programmer's name for it: sApplyUpdates +#: Internet/WbmConst.pas:24 +msgid "Apply Updates" +msgstr "" + +#. Programmer's name for it: sFieldNameBlank +#: Internet/WbmConst.pas:25 +msgid "%s.FieldName = ''" +msgstr "" + +#. Programmer's name for it: sXMLComponentNotDefined +#: Internet/WbmConst.pas:26 +msgid "%s.XMLComponent = nil" +msgstr "" + +#. Programmer's name for it: ScriptNamesVar +#: Internet/WbmConst.pas:27 +msgid "%s_Names" +msgstr "" + +#. Programmer's name for it: ScriptIDsVar +#: Internet/WbmConst.pas:28 +msgid "%s_IDs" +msgstr "" + +#. Programmer's name for it: ScriptXMLDisplayName +#: Internet/WbmConst.pas:29 +msgid "%s_Disp" +msgstr "" + +#. Programmer's name for it: sInvalidParent +#: Internet/WbmConst.pas:30 Internet/WebConst.pas:46 +msgid "Invalid parent" +msgstr "Padre no válido" + +#. Programmer's name for it: sInvalidParentClass +#: Internet/WbmConst.pas:31 +msgid "Invalid parent class: %s" +msgstr "Clase de padre no válido: %s" + +#. Programmer's name for it: sDuplicateStatusField +#: Internet/WbmConst.pas:32 +msgid "Field %s ignored, only one status field allowed" +msgstr "" + +#. Programmer's name for it: sFirstButton +#: Internet/WbmConst.pas:33 +msgid "|<" +msgstr "" + +#. Programmer's name for it: sLastButton +#: Internet/WbmConst.pas:34 +msgid ">|" +msgstr "" + +#. Programmer's name for it: sPriorButton +#: Internet/WbmConst.pas:35 +msgid "<" +msgstr "" + +#. Programmer's name for it: sNextButton +#: Internet/WbmConst.pas:36 +msgid ">" +msgstr "" + +#. Programmer's name for it: sPriorPageButton +#: Internet/WbmConst.pas:37 +msgid "<<" +msgstr "" + +#. Programmer's name for it: sNextPageButton +#: Internet/WbmConst.pas:38 +msgid ">>" +msgstr "" + +#. Programmer's name for it: sDeleteButton +#: Internet/WbmConst.pas:39 +msgid " - " +msgstr "" + +#. Programmer's name for it: sInsertButton +#: Internet/WbmConst.pas:40 +msgid " + " +msgstr "" + +#. Programmer's name for it: sUndoButton +#. Programmer's name for it: sUndoComponent +#: Internet/WbmConst.pas:41 ToolsAPI/DesignEditors.pas:2767 +msgid "Undo" +msgstr "" + +#. Programmer's name for it: sPostButton +#: Internet/WbmConst.pas:42 +msgid "Post" +msgstr "" + +#. Programmer's name for it: sWarningsBody +#: Internet/WbmConst.pas:47 +msgid "" +"\n" +"\n" +"

                    Design-time Warnings

                    \n" +"%s\n" +"

                    \n" +msgstr "" + +#. Programmer's name for it: ScriptDocumentVarName +#: Internet/WbmConst.pas:48 +msgid "%s_Doc" +msgstr "" + +#. Programmer's name for it: ScriptXMLVarName +#: Internet/WbmConst.pas:49 +msgid "%s_XML" +msgstr "" + +#. Programmer's name for it: sInvalidWebComponentsCreation +#: Internet/WbmConst.pas:50 +msgid "Invalid Web component creation" +msgstr "" + +#. Programmer's name for it: ScriptRowSetVarName +#: Internet/WbmConst.pas:51 +msgid "%s_RS" +msgstr "" + +#. Programmer's name for it: sApplyUpdatesError +#: Internet/WbmConst.pas:52 +msgid "ApplyUpdates error. Error count: %d." +msgstr "" + +#. Programmer's name for it: sDeltaNotFound +#: Internet/WbmConst.pas:53 +msgid "Missing Delta Packet" +msgstr "" + +#. Programmer's name for it: sXMLBrokerNotConnected +#: Internet/WbmConst.pas:54 +msgid "XMLBroker: %s is not connected" +msgstr "XMLBroker: %s no está conectado." + +#. Programmer's name for it: sDataSetNotActive +#: Internet/WbmConst.pas:55 +msgid "DataSet: %s is not active" +msgstr "Dataset: %s no está activo" + +#. Programmer's name for it: sMemKB +#: Internet/WebAppDbgAbout.pas:35 +msgid "#,###,###\" KB\"" +msgstr "" + +#. Programmer's name for it: sErrorDecodingURLText +#: Internet/WebConst.pas:20 +msgid "Error decoding URL style (%XX) encoded string at position %d" +msgstr "" + +#. Programmer's name for it: sInvalidURLEncodedChar +#: Internet/WebConst.pas:21 +msgid "Invalid URL encoded character (%s) at position %d" +msgstr "" + +#. Programmer's name for it: sDuplicateActionName +#: Internet/WebConst.pas:23 +msgid "Duplicate action name" +msgstr "Nombre de acción duplicado" + +#. Programmer's name for it: sFactoryAlreadyRegistered +#: Internet/WebConst.pas:24 +msgid "Web Module Factory already registered" +msgstr "" + +#. Programmer's name for it: sAppFactoryAlreadyRegistered +#: Internet/WebConst.pas:25 +msgid "Web App Module Factory already registered." +msgstr "" + +#. Programmer's name for it: sOnlyOneDispatcher +#: Internet/WebConst.pas:26 +msgid "Only one WebDispatcher per form/data module" +msgstr "" + +#. Programmer's name for it: sHTTPItemName +#: Internet/WebConst.pas:27 +msgid "Name" +msgstr "" + +#. Programmer's name for it: sHTTPItemURI +#: Internet/WebConst.pas:28 +msgid "PathInfo" +msgstr "" + +#. Programmer's name for it: sHTTPItemEnabled +#: Internet/WebConst.pas:29 +msgid "Enabled" +msgstr "" + +#. Programmer's name for it: sHTTPItemProducer +#: Internet/WebConst.pas:31 +msgid "Producer" +msgstr "" + +#. Programmer's name for it: sTooManyColumns +#: Internet/WebConst.pas:35 +msgid "Too many table columns" +msgstr "Tabla con demasiadas columnas" + +#. Programmer's name for it: sFieldNameColumn +#: Internet/WebConst.pas:36 +msgid "Field Name" +msgstr "" + +#. Programmer's name for it: sFieldTypeColumn +#: Internet/WebConst.pas:37 +msgid "Field Type" +msgstr "" + +#. Programmer's name for it: sInvalidWebComponentsRegistration +#: Internet/WebConst.pas:39 +msgid "Invalid Web component registration" +msgstr "" + +#. Programmer's name for it: sInvalidWebComponentsEnumeration +#: Internet/WebConst.pas:40 +msgid "Invalid Web component enumeration" +msgstr "" + +#. Programmer's name for it: sVariableIsNotAContainer +#: Internet/WebConst.pas:42 +msgid "Variable %s is not a container" +msgstr "" + +#. Programmer's name for it: sInternalApplicationError +#: Internet/WebConst.pas:45 +msgid "" +"

                    Internal Application Error

                    \n" +"

                    %0:s\n" +"


                    %1:s" +msgstr "" + +#. Programmer's name for it: SWideStringOutOfBounds +#: Internet/WSDLIntf.pas:126 +msgid "WideString Index outof bounds" +msgstr "" + +#. Programmer's name for it: sWebServiceListing +#: Internet/WSDLPub.pas:80 +msgid "WebService Listing" +msgstr "" + +#. Programmer's name for it: sWebServiceListingAdmin +#: Internet/WSDLPub.pas:81 +msgid "WebService Listing Administrator" +msgstr "" + +#. Programmer's name for it: sPortType +#: Internet/WSDLPub.pas:82 +msgid "Port Type" +msgstr "" + +#. Programmer's name for it: sNameSpaceURI +#: Internet/WSDLPub.pas:83 +msgid "Namespace URI" +msgstr "" + +#. Programmer's name for it: sDocumentation +#: Internet/WSDLPub.pas:84 +msgid "Documentation" +msgstr "" + +#. Programmer's name for it: sWSDL +#: Internet/WSDLPub.pas:85 +msgid "WSDL" +msgstr "" + +#. Programmer's name for it: sPortName +#: Internet/WSDLPub.pas:86 +msgid "PortName" +msgstr "" + +#. Programmer's name for it: sAddress +#: Internet/WSDLPub.pas:87 +msgid "Address" +msgstr "Dirección" + +#. Programmer's name for it: sInterfaceNotFound +#: Internet/WSDLPub.pas:88 +msgid "

                    Interface %s not found

                    " +msgstr "" + +#. Programmer's name for it: sWSDLPortsforPortType +#: Internet/WSDLPub.pas:89 +msgid "WSDL Ports for PortType" +msgstr "" + +#. Programmer's name for it: sWSDLFor +#: Internet/WSDLPub.pas:90 +msgid "WSDL for " +msgstr "" + +#. Programmer's name for it: SPropertyAccessors +#: Internet/XMLBindGen.pas:67 +msgid " { Property Accessors }" +msgstr "" + +#. Programmer's name for it: SMethodsAndProps +#: Internet/XMLBindGen.pas:68 +msgid " { Methods & Properties }" +msgstr "" + +#. Programmer's name for it: SForwardDecl +#: Internet/XMLBindGen.pas:69 +msgid "Forward Decls" +msgstr "" + +#. Programmer's name for it: SGlobalFunctions +#: Internet/XMLBindGen.pas:70 +msgid "Global Functions" +msgstr "" + +#. Programmer's name for it: SDescription +#: Internet/XMLDataToSchema.pas:46 +msgid "XMLData to XML Schema Translator (.xml -> .xsd)" +msgstr "" + +#. Programmer's name for it: SNotActive +#: Internet/XMLDoc.pas:497 +msgid "No active document" +msgstr "" + +#. Programmer's name for it: SNodeNotFound +#: Internet/XMLDoc.pas:498 +msgid "Node \"%s\" not found" +msgstr "No se ha encontrado el nodo \"%s\"" + +#. Programmer's name for it: SMissingNode +#: Internet/XMLDoc.pas:499 +msgid "IDOMNode required" +msgstr "" + +#. Programmer's name for it: SNoAttributes +#: Internet/XMLDoc.pas:500 +msgid "Attributes are not supported on this node type" +msgstr "" + +#. Programmer's name for it: SInvalidNodeType +#: Internet/XMLDoc.pas:501 +msgid "Invalid node type" +msgstr "Tipo de nodo no válido" + +#. Programmer's name for it: SMismatchedRegItems +#: Internet/XMLDoc.pas:502 +msgid "Mismatched paramaters to RegisterChildNodes" +msgstr "" + +#. Programmer's name for it: SNotSingleTextNode +#: Internet/XMLDoc.pas:503 +msgid "Element does not contain a single text node" +msgstr "" + +#. Programmer's name for it: SNoDOMParseOptions +#: Internet/XMLDoc.pas:504 +msgid "DOM Implementation does not support IDOMParseOptions" +msgstr "" + +#. Programmer's name for it: SNotOnHostedNode +#: Internet/XMLDoc.pas:505 +msgid "Invalid operation on a hosted node" +msgstr "" + +#. Programmer's name for it: SMissingItemTag +#: Internet/XMLDoc.pas:506 +msgid "ItemTag property is not initialized" +msgstr "La propiedad ItemTag no está inicializada" + +#. Programmer's name for it: SNodeReadOnly +#: Internet/XMLDoc.pas:507 +msgid "Node is readonly" +msgstr "" + +#. Programmer's name for it: SUnsupportedEncoding +#: Internet/XMLDoc.pas:508 +msgid "Unsupported character encoding \"%s\", try using LoadFromFile" +msgstr "" + +#. Programmer's name for it: SNoRefresh +#: Internet/XMLDoc.pas:509 +msgid "Refresh is only supported if the FileName or XML properties are set" +msgstr "" + +#. Programmer's name for it: SMissingFileName +#: Internet/XMLDoc.pas:510 +msgid "FileName cannot be blank" +msgstr "" + +#. Programmer's name for it: SLine +#: Internet/XMLDoc.pas:511 +msgid "Line" +msgstr "" + +#. Programmer's name for it: SDuplicateRegistration +#: Internet/xmldom.pas:554 +msgid "\"%s\" DOMImplementation already registered" +msgstr "" + +#. Programmer's name for it: SNoMatchingDOMVendor +#: Internet/xmldom.pas:555 +msgid "No matching DOM Vendor" +msgstr "" + +#. Programmer's name for it: SNoDOMNodeEx +#: Internet/xmldom.pas:556 +msgid "Selected DOM Vendor does not support this property or method" +msgstr "" + +#. Programmer's name for it: SDOMNotSupported +#: Internet/xmldom.pas:557 +msgid "Property or Method \"%s\" is not supported by DOM Vendor \"%s\"" +msgstr "" + +#. Programmer's name for it: SDescription +#: Internet/XMLSchema99.pas:70 +msgid "1999 XML Schema Translator (.xsd <-> .xsd)" +msgstr "" + +#. Programmer's name for it: SInvalidSchema +#: Internet/XMLSchemaTags.pas:176 +msgid "Invalid or unsupported XML Schema document" +msgstr "" + +#. Programmer's name for it: SNoLocalTypeName +#: Internet/XMLSchemaTags.pas:177 +msgid "Local type declarations cannot have a name. Element: %s" +msgstr "" + +#. Programmer's name for it: SUnknownDataType +#: Internet/XMLSchemaTags.pas:178 +msgid "Unknown datatype \"%s\"" +msgstr "Tipo de dato desconocido \"%s\"" + +#. Programmer's name for it: SInvalidValue +#: Internet/XMLSchemaTags.pas:179 +msgid "Invalid %s value: \"%s\"" +msgstr "Valor %s no válido: \"%s\"" + +#. Programmer's name for it: SInvalidGroupDecl +#: Internet/XMLSchemaTags.pas:180 +msgid "Invalid group declaration in \"%s\"" +msgstr "Declaración de grupo no válido en \"%s\"" + +#. Programmer's name for it: SMissingName +#: Internet/XMLSchemaTags.pas:181 +msgid "Missing Type name" +msgstr "Nombre de tipo sin valor" + +#. Programmer's name for it: SInvalidDerivation +#: Internet/XMLSchemaTags.pas:182 +msgid "Invalid complex type derivation: %s" +msgstr "" + +#. Programmer's name for it: SNoNameOnRef +#: Internet/XMLSchemaTags.pas:183 +msgid "Name not allowed on a ref item" +msgstr "" + +#. Programmer's name for it: SNoGlobalRef +#: Internet/XMLSchemaTags.pas:184 +msgid "Global scheam items may not contain a ref" +msgstr "" + +#. Programmer's name for it: SNoRefPropSet +#: Internet/XMLSchemaTags.pas:185 +msgid "%s cannot be set on a ref item" +msgstr "" + +#. Programmer's name for it: SSetGroupRefProp +#: Internet/XMLSchemaTags.pas:186 +msgid "Set the GroupRef property for the cmGroupRef content model" +msgstr "" + +#. Programmer's name for it: SNoContentModel +#: Internet/XMLSchemaTags.pas:187 +msgid "ContentModel not set" +msgstr "" + +#. Programmer's name for it: SNoFacetsAllowed +#: Internet/XMLSchemaTags.pas:188 +msgid "Facets and Enumeration not allowed on this kind of datatype \"%s\"" +msgstr "" + +#. Programmer's name for it: SNotBuiltInType +#: Internet/XMLSchemaTags.pas:189 +msgid "Invalid built-in type name \"%s\"" +msgstr "" + +#. Programmer's name for it: SBuiltInType +#: Internet/XMLSchemaTags.pas:190 +msgid "Built-in Type" +msgstr "" + +#. Programmer's name for it: SMissingSourceFile +#: Internet/xmlutil.pas:47 +msgid "XMLDataFile must be specified" +msgstr "" + +#. Programmer's name for it: SMissingTransform +#: Internet/xmlutil.pas:48 +msgid "TransformationFile must be specified" +msgstr "" + +#. Programmer's name for it: SOldVersion +#: Internet/xmlutil.pas:49 +msgid "Version of Transformation File not supported" +msgstr "" + +#. Programmer's name for it: sFileSaveError +#: Internet/xmlutil.pas:50 +msgid "Error saving file" +msgstr "" + +#. Programmer's name for it: sFileOpenError +#: Internet/xmlutil.pas:51 +msgid "Error opening file" +msgstr "" + +#. Programmer's name for it: sXMLFileOpenError +#: Internet/xmlutil.pas:52 +msgid "Could not open file " +msgstr "No se puede abrir el fichero" + +#. Programmer's name for it: sXMLLoadError +#: Internet/xmlutil.pas:53 +msgid "Error Loading XML" +msgstr "" + +#. Programmer's name for it: sLinePosError +#: Internet/xmlutil.pas:54 +msgid "Error on line %d, position %d" +msgstr "" + +#. Programmer's name for it: sReason +#: Internet/xmlutil.pas:55 +msgid "Reason: %s\n" +msgstr "Motivo: %s\n" + +#. Programmer's name for it: sParseError +#: Internet/xmlutil.pas:56 +msgid "XML Parse Error:\n" +msgstr "" + +#. Programmer's name for it: SIconViewEditor +#: Property Editors/ClxIconEdit.pas:321 +msgid "Items Editor..." +msgstr "Editor de elementos..." + +#. Programmer's name for it: srSamples +#: Samples/IBConst.pas:6 +msgid "Samples" +msgstr "Ejemplos" + +#. Programmer's name for it: SNoEventsRegistered +#: Samples/IBConst.pas:7 +msgid "You must register events before queueing them" +msgstr "" + +#. Programmer's name for it: SInvalidDBConnection +#: Samples/IBConst.pas:8 +msgid "Component is not connected to an open Database" +msgstr "El componente no está conectado a una base de datos abierta" + +#. Programmer's name for it: SInvalidDatabase +#: Samples/IBConst.pas:9 +msgid "''%s'' is not connected to an InterBase database" +msgstr "" + +#. Programmer's name for it: SInvalidCancellation +#: Samples/IBConst.pas:10 +msgid "You cannot call CancelEvents from within an OnEventAlert handler" +msgstr "" + +#. Programmer's name for it: SInvalidEvent +#: Samples/IBConst.pas:11 +msgid "Invalid blank event added to EventAlerter events list" +msgstr "" + +#. Programmer's name for it: SInvalidQueueing +#: Samples/IBConst.pas:12 +msgid "You cannot call QueueEvents from within an OnEventAlert handler" +msgstr "" + +#. Programmer's name for it: SInvalidRegistration +#: Samples/IBConst.pas:13 +msgid "" +"You cannot Register or Unregister events from within an OnEventAlert handler" +msgstr "" + +#. Programmer's name for it: SMaximumEvents +#: Samples/IBConst.pas:13 +msgid "You can only register 15 events per EventAlerter" +msgstr "" + +#. Programmer's name for it: SInterbaseNotInstalled +#: Samples/IBCtrls.pas:103 +msgid "You must have Interbase installed to use this component" +msgstr "" + +#. Programmer's name for it: SFailedQueEvents +#: Samples/IBCtrls.pas:104 +msgid "Failed to lookup isc_que_events" +msgstr "" + +#. Programmer's name for it: SFailedInterprete +#: Samples/IBCtrls.pas:105 +msgid "Failed to lookup isc_interprete" +msgstr "" + +#. Programmer's name for it: SFailedFree +#: Samples/IBCtrls.pas:106 +msgid "Failed to lookup isc_free" +msgstr "" + +#. Programmer's name for it: SFailedEventBlock +#: Samples/IBCtrls.pas:107 +msgid "Failed to lookup isc_event_block" +msgstr "" + +#. Programmer's name for it: SFailedEventCounts +#: Samples/IBCtrls.pas:108 +msgid "Failed to lookup isc_event_counts" +msgstr "" + +#. Programmer's name for it: SFailedCancelEvents +#: Samples/IBCtrls.pas:109 +msgid "Failed to lookup isc_cancel_events" +msgstr "" + +#. Programmer's name for it: SNoRTTI +#: Soap/IntfInfo.pas:69 +msgid "Interface %s has no RTTI" +msgstr "" + +#. Programmer's name for it: SNoRTTIParam +#: Soap/IntfInfo.pas:70 +msgid "Parameter %s on Method %s of Interface %s has no RTTI" +msgstr "" + +#. Programmer's name for it: SClassNotRegistered +#: Soap/InvConst.pas:15 +msgid "Class not registered" +msgstr "" + +#. Programmer's name for it: SIntfNotRegistered +#: Soap/InvConst.pas:16 +msgid "Interface %s not registered" +msgstr "" + +#. Programmer's name for it: SUnsupportedEncodingSyle +#: Soap/SoapConst.pas:81 +msgid "Unsupported SOAP encodingStyle %s" +msgstr "" + +#. Programmer's name for it: SInvalidSoapRequest +#: Soap/SoapConst.pas:82 +msgid "Invalid SOAP request" +msgstr "" + +#. Programmer's name for it: SMultiBodyNotSupported +#: Soap/SoapConst.pas:83 +msgid "Multiple body elements not supported" +msgstr "" + +#. Programmer's name for it: SUnsupportedCC +#: Soap/SoapConst.pas:84 +msgid "Unsupported calling convention: %s" +msgstr "Convención de llamada no soportado: %s" + +#. Programmer's name for it: SUnsupportedCCIntfMeth +#: Soap/SoapConst.pas:85 +msgid "" +"Remote Method Call: unsupported calling convention %s for method %s on " +"interface %s" +msgstr "" + +#. Programmer's name for it: SInvClassNotRegistered +#: Soap/SoapConst.pas:86 +msgid "No class registered to implement interface %s for soap action %s" +msgstr "" + +#. Programmer's name for it: SInvInterfaceNotReg +#: Soap/SoapConst.pas:87 +msgid "No interface registered for soap action %s" +msgstr "" + +#. Programmer's name for it: SInvInterfaceNotRegURL +#: Soap/SoapConst.pas:88 +msgid "No interface registered for URL %s" +msgstr "" + +#. Programmer's name for it: SRemTypeNotRegistered +#: Soap/SoapConst.pas:89 +msgid "Remotable Type %s not registered" +msgstr "" + +#. Programmer's name for it: STypeMismatchInParam +#: Soap/SoapConst.pas:90 +msgid "Type mismatch in parameter %s" +msgstr "" + +#. Programmer's name for it: SNoSuchMethod +#: Soap/SoapConst.pas:91 +msgid "No such method %s" +msgstr "" + +#. Programmer's name for it: SInterfaceNotReg +#: Soap/SoapConst.pas:92 +msgid "Interface not registered, UUID = %s" +msgstr "" + +#. Programmer's name for it: SInterfaceNoRTTI +#: Soap/SoapConst.pas:93 +msgid "Interface has no RTTI, UUID = %s" +msgstr "" + +#. Programmer's name for it: SNoWSDL +#: Soap/SoapConst.pas:94 +msgid "No WSDL document associated with WSDLView" +msgstr "" + +#. Programmer's name for it: SDataTypeNotSupported +#: Soap/SoapConst.pas:95 +msgid "" +"Datatype of TypeKind: %s not supported as argument for remote invocation" +msgstr "" + +#. Programmer's name for it: SNoMatchingDelphiType +#: Soap/SoapConst.pas:96 +msgid "" +"No matching Delphi type was found for type: URI = %s, Name = %s on Node %s" +msgstr "" + +#. Programmer's name for it: SUnknownSOAPAction +#: Soap/SoapConst.pas:97 +msgid "Unknown SOAPAction %s" +msgstr "" + +#. Programmer's name for it: SScalarFromTRemotableS +#: Soap/SoapConst.pas:98 +msgid "" +"Classes that represent scalar types must decsend from TRemotable, %s does not" +msgstr "" + +#. Programmer's name for it: SNoSerializeGraphs +#: Soap/SoapConst.pas:99 +msgid "" +"Must allow multiref output for objects when serializing a graph of objects" +msgstr "" + +#. Programmer's name for it: SUnsuportedClassType +#: Soap/SoapConst.pas:100 +msgid "Conversion from Class %s to SOAP is not supported" +msgstr "" + +#. Programmer's name for it: SUnexpectedDataType +#: Soap/SoapConst.pas:101 +msgid "Internal error: data type kind %s not expected in this context" +msgstr "" + +#. Programmer's name for it: SArrayTooManyElem +#: Soap/SoapConst.pas:104 +msgid "Array Node: %s has too many elements" +msgstr "" + +#. Programmer's name for it: SWrongDocElem +#: Soap/SoapConst.pas:105 +msgid "DocumentElement %s:%s expected, %s:%s found" +msgstr "" + +#. Programmer's name for it: STooManyParameters +#: Soap/SoapConst.pas:106 +msgid "Too many parameters in method %s" +msgstr "" + +#. Programmer's name for it: SArrayExpected +#: Soap/SoapConst.pas:107 +msgid "Array type expected. Node %s" +msgstr "" + +#. Programmer's name for it: SNoMultiDimVar +#: Soap/SoapConst.pas:108 +msgid "Multidimensional variant arrays not supported in this release" +msgstr "" + +#. Programmer's name for it: SNoURL +#: Soap/SoapConst.pas:109 +msgid "No URL set" +msgstr "" + +#. Programmer's name for it: SNoInterfaceGUID +#: Soap/SoapConst.pas:111 +msgid "Class %s does not implement interface GUID %s" +msgstr "" + +#. Programmer's name for it: SNoArrayElemRTTI +#: Soap/SoapConst.pas:112 +msgid "Element of Array type %s has no RTTI" +msgstr "" + +#. Programmer's name for it: SInvalidResponse +#: Soap/SoapConst.pas:113 +msgid "Invalid SOAP Response" +msgstr "" + +#. Programmer's name for it: SInvalidArraySpec +#: Soap/SoapConst.pas:114 +msgid "Invalid SOAP array specification" +msgstr "" + +#. Programmer's name for it: SCannotFindNodeID +#: Soap/SoapConst.pas:115 +msgid "Cannot find node referenced by ID %s" +msgstr "" + +#. Programmer's name for it: SNoNativeNULL +#: Soap/SoapConst.pas:116 +msgid "Option not set to allow Native type to be set to NULL" +msgstr "" + +#. Programmer's name for it: SFaultCodeOnlyAllowed +#: Soap/SoapConst.pas:117 +msgid "Only one FaultCode element allowed" +msgstr "" + +#. Programmer's name for it: SFaultStringOnlyAllowed +#: Soap/SoapConst.pas:118 +msgid "Only one FaultString element allowed" +msgstr "" + +#. Programmer's name for it: SMissingFaultValue +#: Soap/SoapConst.pas:119 +msgid "Missing FaultString or FaultCode element" +msgstr "" + +#. Programmer's name for it: SNoInterfacesInClass +#: Soap/SoapConst.pas:120 +msgid "Invokable Class %s implements no interfaces" +msgstr "" + +#. Programmer's name for it: SVariantCastNotSupported +#: Soap/SoapConst.pas:122 +msgid "Type cannot be cast as Variant" +msgstr "" + +#. Programmer's name for it: SVarDateNotSupported +#: Soap/SoapConst.pas:123 +msgid "varDate type not supported" +msgstr "Tipo varDate no soportado" + +#. Programmer's name for it: SVarDispatchNotSupported +#. Programmer's name for it: SNoVarDispatch +#: Soap/SoapConst.pas:124 Soap/SoapConst.pas:142 +msgid "varDispatch type not supported" +msgstr "Tipo varDispatch no soportado" + +#. Programmer's name for it: SVarErrorNotSupported +#. Programmer's name for it: SNoErrorDispatch +#: Soap/SoapConst.pas:125 Soap/SoapConst.pas:143 +msgid "varError type not supported" +msgstr "Tipo varError no soportado" + +#. Programmer's name for it: SVarVariantNotSupported +#: Soap/SoapConst.pas:126 +msgid "varVariant type not supported" +msgstr "Tipo varVariant no soportado" + +#. Programmer's name for it: SHeaderError +#: Soap/SoapConst.pas:127 +msgid "Error Processing Header %s" +msgstr "" + +#. Programmer's name for it: SMissingSoapReturn +#: Soap/SoapConst.pas:128 +msgid "SOAP Response Packet: result element expected, %s found" +msgstr "" + +#. Programmer's name for it: SInvalidPointer +#: Soap/SoapConst.pas:129 +msgid "Invalid Pointer" +msgstr "Puntero no válido" + +#. Programmer's name for it: SNoMessageConverter +#: Soap/SoapConst.pas:130 +msgid "No Pascal to Message converter set" +msgstr "" + +#. Programmer's name for it: SNoMsgProcessingNode +#: Soap/SoapConst.pas:131 +msgid "No Message processing node set" +msgstr "" + +#. Programmer's name for it: SHeaderAttributeError +#: Soap/SoapConst.pas:132 +msgid "Soap header attribute %s with must understand true not understand" +msgstr "" + +#. Programmer's name for it: SNoServiceForURL +#: Soap/SoapConst.pas:134 +msgid "No service available for URL %s" +msgstr "Servicio no disponible para la URL %s" + +#. Programmer's name for it: SNoInterfaceForURL +#: Soap/SoapConst.pas:135 +msgid "No interface is registered to handle URL %s" +msgstr "" + +#. Programmer's name for it: SNoClassRegisteredForURL +#: Soap/SoapConst.pas:136 +msgid "No Class is regisgtered to implement interface %s" +msgstr "" + +#. Programmer's name for it: SInvalidURL +#: Soap/SoapConst.pas:137 +msgid "Invalid url" +msgstr "URL no válida" + +#. Programmer's name for it: SNoClassRegistered +#: Soap/SoapConst.pas:138 +msgid "No class registered for invokable interface %s" +msgstr "" + +#. Programmer's name for it: SNoDispatcher +#: Soap/SoapConst.pas:139 +msgid "No Dispatcher set" +msgstr "" + +#. Programmer's name for it: SMethNoRTTI +#: Soap/SoapConst.pas:140 +msgid "Method has no RTTI" +msgstr "" + +#. Programmer's name for it: SUnsupportedVariant +#: Soap/SoapConst.pas:141 +msgid "Unsuppported variant type" +msgstr "Tipo de variant no soportada" + +#. Programmer's name for it: SInvalidTimeZone +#: Soap/SoapConst.pas:145 +msgid "Invalid or Unknown Time Zone" +msgstr "" + +#. Programmer's name for it: SLocationFilter +#: Soap/SoapConst.pas:146 +msgid "WSDL files (*.wsdl)|*.wsdl|XML files (*.xml)|*.xml" +msgstr "" + +#. Programmer's name for it: SInvalidHour +#: Soap/XSBuiltIns.pas:35 +msgid "Invalid hour: %d" +msgstr "Hora no válida: %d" + +#. Programmer's name for it: SInvalidMinute +#: Soap/XSBuiltIns.pas:36 +msgid "Invalid minute: %d" +msgstr "Minutos no válidos: %d" + +#. Programmer's name for it: SInvalidSecond +#: Soap/XSBuiltIns.pas:37 +msgid "Invalid second: %d" +msgstr "Segundos no válidos: %d" + +#. Programmer's name for it: SInvalidFractionSecond +#: Soap/XSBuiltIns.pas:38 +msgid "Invalid second: %f" +msgstr "Segundos no válidos: %f" + +#. Programmer's name for it: SInvalidMillisecond +#: Soap/XSBuiltIns.pas:39 +msgid "Invalid millisecond: %d" +msgstr "Milisegundos no válidos: %d" + +#. Programmer's name for it: SInvalidHourOffset +#: Soap/XSBuiltIns.pas:40 +msgid "Invalid hour offset: %d" +msgstr "Offset de la hora no válido: %d" + +#. Programmer's name for it: SInvalidDay +#: Soap/XSBuiltIns.pas:41 +msgid "Invalid day: %d" +msgstr "Día no válido: %d" + +#. Programmer's name for it: SInvalidMonth +#: Soap/XSBuiltIns.pas:42 +msgid "Invalid month: %d" +msgstr "Mes no válido: %d" + +#. Programmer's name for it: SInvalidDuration +#: Soap/XSBuiltIns.pas:43 +msgid "Invalid Duration String: %s" +msgstr "Cadena de duración no válido: %s" + +#. Programmer's name for it: sHTMLFilter +#: ToolsAPI/ClxEditors.pas:629 +msgid "html files (*.htm *.html)" +msgstr "" + +#. Programmer's name for it: srLine +#: ToolsAPI/DesignConst.pas:14 +msgid "line" +msgstr "" + +#. Programmer's name for it: srLines +#: ToolsAPI/DesignConst.pas:15 +msgid "lines" +msgstr "" + +#. Programmer's name for it: SInvalidFormat +#: ToolsAPI/DesignConst.pas:17 +msgid "Invalid graphic format" +msgstr "Formato gráfico no válido" + +#. Programmer's name for it: SUnableToFindComponent +#: ToolsAPI/DesignConst.pas:19 +msgid "Unable to locate form/component, '%s'" +msgstr "No se puede localizar el form/componente, '%s'" + +#. Programmer's name for it: SCantFindProperty +#: ToolsAPI/DesignConst.pas:20 +msgid "Unable to locate property '%s' on component '%s'" +msgstr "" + +#. Programmer's name for it: SStringsPropertyInvalid +#: ToolsAPI/DesignConst.pas:21 +msgid "Property '%s' has not been initialized on component '%s'" +msgstr "" + +#. Programmer's name for it: SLoadPictureTitle +#: ToolsAPI/DesignConst.pas:23 +msgid "Load Picture" +msgstr "Cargar Imagen" + +#. Programmer's name for it: SSavePictureTitle +#: ToolsAPI/DesignConst.pas:24 +msgid "Save Picture As" +msgstr "Grabar Imagen Como" + +#. Programmer's name for it: SAboutVerb +#: ToolsAPI/DesignConst.pas:26 +msgid "About..." +msgstr "Acerca de..." + +#. Programmer's name for it: SNoPropertyPageAvailable +#: ToolsAPI/DesignConst.pas:27 +msgid "No property pages are available for this control" +msgstr "" + +#. Programmer's name for it: SNoAboutBoxAvailable +#: ToolsAPI/DesignConst.pas:28 +msgid "An About Box is not available for this control" +msgstr "" + +#. Programmer's name for it: SNull +#: ToolsAPI/DesignConst.pas:29 +msgid "(Null)" +msgstr "(Null)" + +#. Programmer's name for it: SUnassigned +#: ToolsAPI/DesignConst.pas:30 +msgid "(Unassigned)" +msgstr "(Sin asignación)" + +#. Programmer's name for it: SString +#: ToolsAPI/DesignConst.pas:32 +msgid "String" +msgstr "String" + +#. Programmer's name for it: SUnknownType +#: ToolsAPI/DesignConst.pas:34 +msgid "Unknown Type" +msgstr "Tipo desconocido" + +#. Programmer's name for it: SCannotCreateName +#: ToolsAPI/DesignConst.pas:36 +msgid "Cannot create a method for an unnamed component" +msgstr "" + +#. Programmer's name for it: SColEditCaption +#: ToolsAPI/DesignConst.pas:38 +msgid "Editing %s%s%s" +msgstr "" + +#. Programmer's name for it: SCantDeleteAncestor +#: ToolsAPI/DesignConst.pas:40 +msgid "" +"Selection contains a component introduced in an ancestor form which cannot " +"be deleted" +msgstr "" + +#. Programmer's name for it: SCantAddToFrame +#: ToolsAPI/DesignConst.pas:41 +msgid "New components cannot be added to frame instances." +msgstr "" + +#. Programmer's name for it: SAllFiles +#: ToolsAPI/DesignConst.pas:44 +msgid "all files (*)" +msgstr "" + +#. Programmer's name for it: SAllFiles +#: ToolsAPI/DesignConst.pas:47 +msgid "all files (*.*)" +msgstr "" + +#. Programmer's name for it: sClassNotApplicable +#: ToolsAPI/DesignEditors.pas:491 +msgid "Class %s is not applicable to this module" +msgstr "" + +#. Programmer's name for it: sNotAvailable +#: ToolsAPI/DesignEditors.pas:492 +msgid "(Not available)" +msgstr "(No disponible)" + +#. Programmer's name for it: sEditSubmenu +#. LogDetailFrame..ActionList1..EditCut1..Category +#. LogDetailFrame..ActionList1..EditCopy1..Category +#. LogDetailFrame..ActionList1..EditPaste1..Category +#. LogDetailFrame..ActionList1..EditSelectAll1..Category +#. LogDetailFrame..ActionList1..EditUndo1..Category +#. StandardActions..ActionList1..EditCut1..Category +#. StandardActions..ActionList1..EditCopy1..Category +#. StandardActions..ActionList1..EditPaste1..Category +#. StandardActions..ActionList1..EditDelete1..Category +#. StandardActions..ActionList1..EditSelectAll1..Category +#. StandardActions..ActionList1..EditUndo1..Category +#: ToolsAPI/DesignEditors.pas:2766 Internet/SvrLogDetailFrame.dfm:62 +#: Internet/SvrLogDetailFrame.dfm:69 Internet/SvrLogDetailFrame.dfm:76 +#: Internet/SvrLogDetailFrame.dfm:83 Internet/SvrLogDetailFrame.dfm:89 +#: Vcl/ActnRes.dfm:12 Vcl/ActnRes.dfm:19 Vcl/ActnRes.dfm:26 Vcl/ActnRes.dfm:65 +#: Vcl/ActnRes.dfm:72 Vcl/ActnRes.dfm:78 +msgid "Edit" +msgstr "" + +#. Programmer's name for it: sCutComponent +#: ToolsAPI/DesignEditors.pas:2768 +msgid "Cut" +msgstr "" + +#. Programmer's name for it: sCopyComponent +#: ToolsAPI/DesignEditors.pas:2769 +msgid "Copy" +msgstr "" + +#. Programmer's name for it: sPasteComponent +#: ToolsAPI/DesignEditors.pas:2770 +msgid "Paste" +msgstr "" + +#. Programmer's name for it: sDeleteComponent +#. ClxTreeViewItems..gbSubItems..btnDelSub..Caption +#: ToolsAPI/DesignEditors.pas:2771 Property Editors/ClxNodeEdit.xfm:226 +msgid "Delete" +msgstr "" + +#. Programmer's name for it: sSelectAllComponent +#. StandardActions..ActionList1..ListControlSelectAll1..Hint +#: ToolsAPI/DesignEditors.pas:2772 Vcl/ActnRes.dfm:277 +msgid "Select All" +msgstr "" + +#. Programmer's name for it: sControlSubmenu +#: ToolsAPI/DesignEditors.pas:2773 +msgid "Control" +msgstr "Control" + +#. Programmer's name for it: sToFrontControl +#: ToolsAPI/DesignEditors.pas:2774 +msgid "Bring to Front" +msgstr "" + +#. Programmer's name for it: sToBackControl +#: ToolsAPI/DesignEditors.pas:2775 +msgid "Send to Back" +msgstr "" + +#. Programmer's name for it: sDataCategoryName +#: ToolsAPI/DesignIntf.pas:429 +msgid "Data" +msgstr "" + +#. Programmer's name for it: sDatabaseCategoryName +#: ToolsAPI/DesignIntf.pas:430 +msgid "Database" +msgstr "Base de datos" + +#. Programmer's name for it: sDragNDropCategoryName +#: ToolsAPI/DesignIntf.pas:432 +msgid "Drag, Drop and Docking" +msgstr "" + +#. Programmer's name for it: sDragNDropCategoryName +#: ToolsAPI/DesignIntf.pas:435 +msgid "Drag and Drop" +msgstr "" + +#. Programmer's name for it: sHelpCategoryName +#: ToolsAPI/DesignIntf.pas:437 +msgid "Help and Hints" +msgstr "" + +#. Programmer's name for it: sLayoutCategoryName +#: ToolsAPI/DesignIntf.pas:438 +msgid "Layout" +msgstr "" + +#. Programmer's name for it: sLegacyCategoryName +#: ToolsAPI/DesignIntf.pas:439 +msgid "Legacy" +msgstr "" + +#. Programmer's name for it: sLinkageCategoryName +#: ToolsAPI/DesignIntf.pas:440 +msgid "Linkage" +msgstr "" + +#. Programmer's name for it: sLocaleCategoryName +#: ToolsAPI/DesignIntf.pas:441 +msgid "Locale" +msgstr "" + +#. Programmer's name for it: sLocalizableCategoryName +#: ToolsAPI/DesignIntf.pas:442 +msgid "Localizable" +msgstr "" + +#. Programmer's name for it: sMiscellaneousCategoryName +#: ToolsAPI/DesignIntf.pas:443 +msgid "Miscellaneous" +msgstr "" + +#. Programmer's name for it: sVisualCategoryName +#: ToolsAPI/DesignIntf.pas:444 +msgid "Visual" +msgstr "Visual" + +#. Programmer's name for it: sInputCategoryName +#: ToolsAPI/DesignIntf.pas:445 +msgid "Input" +msgstr "" + +#. Programmer's name for it: sAddCaption +#: ToolsAPI/TreeIntf.pas:2456 +msgid "Add item" +msgstr "" + +#. Programmer's name for it: SUnnamedItemCaption +#: ToolsAPI/TreeIntf.pas:2651 +msgid "" +msgstr "" + +#. Programmer's name for it: SInvalidEnumValue +#: Vcl/ADOConst.pas:15 Vcl/Consts.pas:104 +msgid "Invalid Enum Value" +msgstr "Valor de Enum no válido" + +#. Programmer's name for it: SMissingConnection +#: Vcl/ADOConst.pas:16 +msgid "Missing Connection or ConnectionString" +msgstr "Falta Connection o ConnectionString" + +#. Programmer's name for it: SNoDetailFilter +#: Vcl/ADOConst.pas:17 +msgid "Filter property cannot be used for detail tables" +msgstr "La propiedad Filter no puede ser utilizada para tablas de detalle" + +#. Programmer's name for it: SBookmarksRequired +#: Vcl/ADOConst.pas:18 +msgid "" +"Dataset does not support bookmarks, which are required for multi-record data " +"controls" +msgstr "" +"El Dataset no soporta separadores, los cuales son requeridos para controles " +"de datos multiregistros" + +#. Programmer's name for it: SMissingCommandText +#: Vcl/ADOConst.pas:19 +msgid "Missing %s property" +msgstr "No se encuentra la propiedad %s" + +#. Programmer's name for it: SNoResultSet +#: Vcl/ADOConst.pas:20 +msgid "CommandText does not return a result set" +msgstr "CommandText no devuelve un conjunto de resultados" + +#. Programmer's name for it: SADOCreateError +#: Vcl/ADOConst.pas:21 +msgid "" +"Error creating object. Please verify that the Microsoft Data Access " +"Components 2.1 (or later) have been properly installed" +msgstr "" + +#. Programmer's name for it: SEventsNotSupported +#: Vcl/ADOConst.pas:22 +msgid "Events are not supported with server side TableDirect cursors" +msgstr "Los eventos por parte del servidor no soportan cursores TableDirect" + +#. Programmer's name for it: SUsupportedFieldType +#: Vcl/ADOConst.pas:23 +msgid "Unsupported field type (%s) in field %s" +msgstr "Tipo de campo no soportado (%s) en el campo %s" + +#. Programmer's name for it: SNoMatchingADOType +#: Vcl/ADOConst.pas:24 +msgid "No matching ADO data type for %s" +msgstr "Tipo ADO no coincidente para %s" + +#. Programmer's name for it: SConnectionRequired +#: Vcl/ADOConst.pas:25 +msgid "A connection component is required for async ExecuteOptions" +msgstr "Se requiere un componente de conexión para async ExecuteOptions" + +#. Programmer's name for it: SCantRequery +#: Vcl/ADOConst.pas:26 +msgid "Cannot perform a requery after connection has changed" +msgstr "" +"No se puede realizar una repetición de búsqueda una vez que la conexión ha " +"cambiado" + +#. Programmer's name for it: SNoFilterOptions +#: Vcl/ADOConst.pas:27 +msgid "FilterOptions are not supported" +msgstr "FilterOptions no estan soportadas" + +#. Programmer's name for it: SRecordsetNotOpen +#: Vcl/ADOConst.pas:28 +msgid "Recordset is not open" +msgstr "Recordset no está abierto" + +#. Programmer's name for it: SAutoSessionExclusive +#: Vcl/bdeconst.pas:15 +msgid "" +"Cannot enable AutoSessionName property with more than one session on a form " +"or data-module" +msgstr "" +"No se puede activar la propiedad AutoSessionName con más de una sesión en un " +"formulario o módulo de datos" + +#. Programmer's name for it: SAutoSessionExists +#: Vcl/bdeconst.pas:16 +msgid "" +"Cannot add a session to the form or data-module while session '%s' has " +"AutoSessionName enabled" +msgstr "" +"No se puede añadir una sesión al formulario o módulo de datos mientras la " +"sesión '%s' tiene la propiedad AutoSessionName activada" + +#. Programmer's name for it: SAutoSessionActive +#: Vcl/bdeconst.pas:17 +msgid "Cannot modify SessionName while AutoSessionName is enabled" +msgstr "" +"No se puede modificar SessionName mientras la propiedad AutoSessionName está " +"activada" + +#. Programmer's name for it: SDuplicateDatabaseName +#: Vcl/bdeconst.pas:18 +msgid "Duplicate database name '%s'" +msgstr "Duplicado el nombre de base de datos: '%s'" + +#. Programmer's name for it: SDuplicateSessionName +#: Vcl/bdeconst.pas:19 +msgid "Duplicate session name '%s'" +msgstr "Duplicado el nombre de sesión: '%s'" + +#. Programmer's name for it: SInvalidSessionName +#: Vcl/bdeconst.pas:20 +msgid "Invalid session name %s" +msgstr "Nombre de sesión no válido: %s" + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/bdeconst.pas:21 +msgid "Database name missing" +msgstr "Nombre de la base de datos ausente" + +#. Programmer's name for it: SSessionNameMissing +#: Vcl/bdeconst.pas:22 +msgid "Session name missing" +msgstr "Nombre de sesión ausente" + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/bdeconst.pas:23 +msgid "Cannot perform this operation on an open database" +msgstr "No se puede ejecutar esta operación en una base de datos abierta" + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/bdeconst.pas:24 +msgid "Cannot perform this operation on a closed database" +msgstr "No se puede ejecutar esta operación en una base de datos cerrada" + +#. Programmer's name for it: SDatabaseHandleSet +#: Vcl/bdeconst.pas:25 +msgid "Database handle owned by a different session" +msgstr "" +"El manejador (handle) de la base de datos está siendo utilizado por una " +"sesión diferente" + +#. Programmer's name for it: SSessionActive +#: Vcl/bdeconst.pas:26 +msgid "Cannot perform this operation on an active session" +msgstr "No se puede ejecutar esta operación sobre una sesión activa" + +#. Programmer's name for it: SHandleError +#: Vcl/bdeconst.pas:27 +msgid "Error creating cursor handle" +msgstr "Se ha producido un error al crear el manejador (handle) del cursor" + +#. Programmer's name for it: SInvalidFloatField +#: Vcl/bdeconst.pas:28 +msgid "Cannot convert field '%s' to a floating point value" +msgstr "No se puede convertir el campo '%s' en un valor de punto flotante" + +#. Programmer's name for it: SInvalidIntegerField +#: Vcl/bdeconst.pas:29 +msgid "Cannot convert field '%s' to an integer value" +msgstr "No se puede convertir el campo '%s' en un valor entero" + +#. Programmer's name for it: STableMismatch +#: Vcl/bdeconst.pas:30 +msgid "Source and destination tables are incompatible" +msgstr "Las tablas fuente y destino son incompatibles" + +#. Programmer's name for it: SFieldAssignError +#: Vcl/bdeconst.pas:31 +msgid "Fields '%s' and '%s' are not assignment compatible" +msgstr "Los campos '%s' y '%s' no son de asignación compatible" + +#. Programmer's name for it: SNoReferenceTableName +#: Vcl/bdeconst.pas:32 +msgid "ReferenceTableName not specified for field '%s'" +msgstr "ReferenceTableName no ha sido especificado para el campo '%s'" + +#. Programmer's name for it: SCompositeIndexError +#: Vcl/bdeconst.pas:33 +msgid "Cannot use array of Field values with Expression Indices" +msgstr "No se puede usar la matriz de valores Campo con Expression Indices" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/bdeconst.pas:34 +msgid "Invalid batch move parameters" +msgstr "Parámetros de TBatchMove no válidos" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/bdeconst.pas:35 Vcl/SqlConst.pas:63 +msgid "No SQL statement available" +msgstr "No hay sentencia SQL disponible" + +#. Programmer's name for it: SNoParameterValue +#: Vcl/bdeconst.pas:36 Vcl/SqlConst.pas:64 +msgid "No value for parameter '%s'" +msgstr "No hay valor para el parámetro '%s'" + +#. Programmer's name for it: SNoParameterType +#: Vcl/bdeconst.pas:37 Vcl/SqlConst.pas:65 +msgid "No parameter type for parameter '%s'" +msgstr "No hay tipo de parámetro para el parámetro '%s'" + +#. Programmer's name for it: SLoginError +#: Vcl/bdeconst.pas:38 Vcl/SqlConst.pas:56 +msgid "Cannot connect to database '%s'" +msgstr "No se puede conectar con la base de datos '%s'" + +#. Programmer's name for it: SInitError +#: Vcl/bdeconst.pas:39 +msgid "" +"An error occurred while attempting to initialize the Borland Database Engine " +"(error $%.4x)" +msgstr "" +"Ha ocurrido un error mientras se intentaba inicializar el Motor de la Base " +"de Datos (error $%.4x)" + +#. Programmer's name for it: SDatabaseEditor +#. Programmer's name for it: SIBDatabaseEditor +#: Vcl/bdeconst.pas:40 Vcl/IBXConst.pas:40 +msgid "Da&tabase Editor..." +msgstr "Editor de Base de Da&tos..." + +#. Programmer's name for it: SExplore +#: Vcl/bdeconst.pas:41 +msgid "E&xplore" +msgstr "E&xplorador" + +#. Programmer's name for it: SLinkDetail +#: Vcl/bdeconst.pas:42 +msgid "'%s' cannot be opened" +msgstr "'%s' no puede ser abierto" + +#. Programmer's name for it: SLinkMasterSource +#: Vcl/bdeconst.pas:43 +msgid "The MasterSource property of '%s' must be linked to a DataSource" +msgstr "" +"La propiedad MasterSource de '%s' debe estar enlazada con una fuente de " +"datos DataSource" + +#. Programmer's name for it: SLinkMaster +#: Vcl/bdeconst.pas:44 +msgid "Unable to open the MasterSource Table" +msgstr "Incapaz de abrir la tabla maestra" + +#. Programmer's name for it: SGQEVerb +#: Vcl/bdeconst.pas:45 +msgid "S&QL Builder..." +msgstr "Constructor S&QL..." + +#. Programmer's name for it: SBindVerb +#: Vcl/bdeconst.pas:46 +msgid "Define &Parameters..." +msgstr "Define &Parametros..." + +#. Programmer's name for it: SDisconnectDatabase +#: Vcl/bdeconst.pas:48 Vcl/IBXConst.pas:43 +msgid "Database is currently connected. Disconnect and continue?" +msgstr "La base de datos está conectada actualmente. Desconectar y continuar?" + +#. Programmer's name for it: SBDEError +#: Vcl/bdeconst.pas:49 +msgid "BDE error $%.4x" +msgstr "Error BDE $%.4x" + +#. Programmer's name for it: SLookupSourceError +#: Vcl/bdeconst.pas:50 +msgid "Unable to use duplicate DataSource and LookupSource" +msgstr "Incapaz de usar DataSource y LookupSource duplicados" + +#. Programmer's name for it: SLookupTableError +#: Vcl/bdeconst.pas:51 +msgid "LookupSource must be connected to TTable component" +msgstr "LookupSource debe estar conectado a un componente TTable" + +#. Programmer's name for it: SLookupIndexError +#: Vcl/bdeconst.pas:52 +msgid "%s must be the lookup table's active index" +msgstr "%s debe ser el índice activo de la tabla de búsqueda" + +#. Programmer's name for it: SParameterTypes +#: Vcl/bdeconst.pas:53 Vcl/SqlConst.pas:66 +msgid ";Input;Output;Input/Output;Result" +msgstr ";Entrada;Salida;Entrada/Salida;Resultado" + +#. Programmer's name for it: SInvalidParamFieldType +#: Vcl/bdeconst.pas:54 +msgid "Must have a valid field type selected" +msgstr "Debe haber un tipo de campo válido seleccionado" + +#. Programmer's name for it: STruncationError +#: Vcl/bdeconst.pas:55 +msgid "Parameter '%s' truncated on output" +msgstr "El parámetro '%s' truncado en salida" + +#. Programmer's name for it: SDataTypes +#: Vcl/bdeconst.pas:56 Vcl/SqlConst.pas:67 +msgid "" +";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;" +"DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" +msgstr "" +";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;" +"DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" + +#. Programmer's name for it: SResultName +#: Vcl/bdeconst.pas:57 Vcl/SqlConst.pas:68 +msgid "Result" +msgstr "Resultado" + +#. Programmer's name for it: SDBCaption +#: Vcl/bdeconst.pas:58 +msgid "%s%s%s Database" +msgstr "%s%s%s Base de datos" + +#. Programmer's name for it: SParamEditor +#: Vcl/bdeconst.pas:59 +msgid "%s%s%s Parameters" +msgstr "%s%s%s parámetros" + +#. Programmer's name for it: SIndexFilesEditor +#: Vcl/bdeconst.pas:60 +msgid "%s%s%s Index Files" +msgstr "%s%s%s archivos de índice" + +#. Programmer's name for it: SIndexDoesNotExist +#: Vcl/bdeconst.pas:62 +msgid "Index does not exist. Index: %s" +msgstr "El índice no existe. Indice: %s" + +#. Programmer's name for it: SNoTableName +#: Vcl/bdeconst.pas:63 Vcl/SqlConst.pas:69 +msgid "Missing TableName property" +msgstr "Propiedad TableName sin valor" + +#. Programmer's name for it: SNoDataSetField +#: Vcl/bdeconst.pas:64 Vcl/SqlConst.pas:71 +msgid "Missing DataSetField property" +msgstr "Propiedad DataSetField sin valor" + +#. Programmer's name for it: SBatchExecute +#. Programmer's name for it: SExecute +#: Vcl/bdeconst.pas:65 Vcl/IBXConst.pas:45 +msgid "E&xecute" +msgstr "E&jectuar" + +#. Programmer's name for it: SNoCachedUpdates +#: Vcl/bdeconst.pas:66 Vcl/SqlConst.pas:72 +msgid "Not in cached update mode" +msgstr "No se encuentra en modo cached update" + +#. Programmer's name for it: SInvalidAliasName +#: Vcl/bdeconst.pas:67 +msgid "Invalid alias name %s" +msgstr "Nombre de alias no válido: %s" + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/bdeconst.pas:68 +msgid "Cannot access field '%s' in a filter" +msgstr "No se puede acceder al campo '%s' en un filtro" + +#. Programmer's name for it: SUpdateSQLEditor +#. Programmer's name for it: SIBUpdateSQLEditor +#: Vcl/bdeconst.pas:69 Vcl/IBXConst.pas:49 +msgid "&UpdateSQL Editor..." +msgstr "Editor &UpdateSQL..." + +#. Programmer's name for it: SNoDataSet +#: Vcl/bdeconst.pas:70 Vcl/IBXConst.pas:46 +msgid "No dataset association" +msgstr "No hay asociación con dataset" + +#. Programmer's name for it: SUntitled +#: Vcl/bdeconst.pas:71 +msgid "Untitled Application" +msgstr "Aplicación sín nombre" + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/bdeconst.pas:72 +msgid "Cannot update, %s is not owned by %s" +msgstr "No se puede actualizar, %s no es propiedad de %s" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/bdeconst.pas:73 +msgid "Update failed" +msgstr "Fallo en la actualización" + +#. Programmer's name for it: SSQLGenSelect +#: Vcl/bdeconst.pas:74 Vcl/IBXConst.pas:47 +msgid "Must select at least one key field and one update field" +msgstr "Debe seleccionar, al menos, un campo clave y un campo para actualizar" + +#. Programmer's name for it: SSQLNotGenerated +#: Vcl/bdeconst.pas:75 Vcl/IBXConst.pas:48 +msgid "Update SQL statements not generated, exit anyway?" +msgstr "Sentencia SQL no generada, abandonar?" + +#. Programmer's name for it: SSQLDataSetOpen +#: Vcl/bdeconst.pas:76 Vcl/IBXConst.pas:51 Vcl/SqlConst.pas:78 +msgid "Unable to determine field names for %s" +msgstr "Incapaz de determinar los nombres de campo para %s" + +#. Programmer's name for it: SLocalTransDirty +#: Vcl/bdeconst.pas:77 +msgid "The transaction isolation level must be dirty read for local databases" +msgstr "" +"El nivel de transacción debe ser ''dirty read'' para bases de datos locales" + +#. Programmer's name for it: SMissingDataSet +#: Vcl/bdeconst.pas:78 Vcl/MidConst.pas:67 Vcl/SqlConst.pas:74 +msgid "Missing DataSet property" +msgstr "Propiedad DataSet sin valor" + +#. Programmer's name for it: SNoProvider +#: Vcl/bdeconst.pas:79 +msgid "No provider available" +msgstr "Proveedor no disponible" + +#. Programmer's name for it: SNotAQuery +#: Vcl/bdeconst.pas:80 +msgid "Dataset is not a query" +msgstr "Fuente de datos no es resultado de una consulta" + +#. Programmer's name for it: sTabFailClear +#: Vcl/ComStrs.pas:15 +msgid "Failed to clear tab control" +msgstr "Se ha producido un error al limpiar el control de página" + +#. Programmer's name for it: sTabFailRetrieve +#: Vcl/ComStrs.pas:17 +msgid "Failed to retrieve tab at index %d" +msgstr "Se ha producido un error al recuperar la página en índice %d" + +#. Programmer's name for it: sTabFailGetObject +#: Vcl/ComStrs.pas:18 +msgid "Failed to get object at index %d" +msgstr "Se ha producido un error al obtener objeto en índice %d" + +#. Programmer's name for it: sTabFailSet +#: Vcl/ComStrs.pas:19 +msgid "Failed to set tab \"%s\" at index %d" +msgstr "Se ha producido un error al establecer página \"%s\" en el índice %d" + +#. Programmer's name for it: sTabFailSetObject +#: Vcl/ComStrs.pas:20 +msgid "Failed to set object at index %d" +msgstr "Se ha producido un error al establecer objetos en el índice %d" + +#. Programmer's name for it: sInvalidIndex +#: Vcl/ComStrs.pas:25 +msgid "Invalid index" +msgstr "Indice no válido" + +#. Programmer's name for it: sInsertError +#: Vcl/ComStrs.pas:26 +msgid "Unable to insert an item" +msgstr "Incapaz de insertar un elemento" + +#. Programmer's name for it: sInvalidOwner +#: Vcl/ComStrs.pas:28 +msgid "Invalid owner" +msgstr "Propietario no válido" + +#. Programmer's name for it: sUnableToCreateColumn +#: Vcl/ComStrs.pas:29 +msgid "Unable to create new column" +msgstr "Incapaz de crear una nueva columna" + +#. Programmer's name for it: sUnableToCreateItem +#: Vcl/ComStrs.pas:30 +msgid "Unable to create new item" +msgstr "Incapaz de crear un nuevo elemento" + +#. Programmer's name for it: sRichEditInsertError +#: Vcl/ComStrs.pas:32 +msgid "RichEdit line insertion error" +msgstr "Se ha producido un error al insertar una linea en RichEdit" + +#. Programmer's name for it: sRichEditLoadFail +#: Vcl/ComStrs.pas:33 +msgid "Failed to Load Stream" +msgstr "Se ha producido un error al cargar un Stream" + +#. Programmer's name for it: sRichEditSaveFail +#: Vcl/ComStrs.pas:34 +msgid "Failed to Save Stream" +msgstr "Se ha producido un error al grabar un Stream" + +#. Programmer's name for it: sTooManyPanels +#: Vcl/ComStrs.pas:36 +msgid "StatusBar cannot have more than 64 panels" +msgstr "El StatusBar no puede tener más de 64 paneles" + +#. Programmer's name for it: sHKError +#: Vcl/ComStrs.pas:38 +msgid "Error assigning Hot-Key to %s. %s" +msgstr "Se ha producido un error al asignar Hot-Key a %s. %s" + +#. Programmer's name for it: sHKInvalid +#: Vcl/ComStrs.pas:39 +msgid "Hot-Key is invalid" +msgstr "Hot-Key no es valido" + +#. Programmer's name for it: sHKInvalidWindow +#: Vcl/ComStrs.pas:40 +msgid "Window is invalid or a child window" +msgstr "La ventana no es válida o es una ventana-hija" + +#. Programmer's name for it: sHKAssigned +#: Vcl/ComStrs.pas:41 +msgid "Hot-Key is assigned to another window" +msgstr "Hot-Key está asignada a otra ventana" + +#. Programmer's name for it: sUDAssociated +#: Vcl/ComStrs.pas:43 +msgid "%s is already associated with %s" +msgstr "%s ya está asociada con %s" + +#. Programmer's name for it: sInvalidComCtl32 +#: Vcl/ComStrs.pas:48 +msgid "This control requires version 4.70 or greater of COMCTL32.DLL" +msgstr "Este control requiere versión 4.70 o mayor de COMCTL32.DLL" + +#. Programmer's name for it: sDateTimeMax +#: Vcl/ComStrs.pas:50 +msgid "Date exceeds maximum of %s" +msgstr "La fecha excede el máximo de %s" + +#. Programmer's name for it: sDateTimeMin +#: Vcl/ComStrs.pas:51 +msgid "Date is less than minimum of %s" +msgstr "La fecha es menor que el mínimo de %s" + +#. Programmer's name for it: sNeedAllowNone +#: Vcl/ComStrs.pas:52 +msgid "You must be in ShowCheckbox mode to set to this date" +msgstr "Debe estar en modo ShoyCheckbox para asignar esta fecha" + +#. Programmer's name for it: sFailSetCalDateTime +#: Vcl/ComStrs.pas:53 +msgid "Failed to set calendar date or time" +msgstr "" +"Se ha producido un error al establecer la fecha o la hora del calendario" + +#. Programmer's name for it: sFailSetCalMaxSelRange +#: Vcl/ComStrs.pas:54 +msgid "Failed to set maximum selection range" +msgstr "Se ha producido un error al establecer el rango máximo de selección" + +#. Programmer's name for it: sFailSetCalMinMaxRange +#: Vcl/ComStrs.pas:55 +msgid "Failed to set calendar min/max range" +msgstr "Se ha producido un error al establecer el rango max/min del calendario" + +#. Programmer's name for it: sCalRangeNeedsMultiSelect +#: Vcl/ComStrs.pas:56 +msgid "Date range can only be used in multiselect mode" +msgstr "El rango de la fecha sólo puede ser usado en el modo multiselección" + +#. Programmer's name for it: sFailsetCalSelRange +#: Vcl/ComStrs.pas:57 +msgid "Failed to set calendar selected range" +msgstr "" +"Se ha producido un error al establecer el rango seleccionado del calendario" + +#. Programmer's name for it: SInvalidMetafile +#: Vcl/Consts.pas:24 +msgid "Metafile is not valid" +msgstr "Metaarchivo no válido" + +#. Programmer's name for it: SInvalidImage +#: Vcl/Consts.pas:26 +msgid "Invalid image" +msgstr "Imagen no válida" + +#. Programmer's name for it: SOleGraphic +#: Vcl/Consts.pas:30 +msgid "Invalid operation on TOleGraphic" +msgstr "Operación sobre TOleGraphic no válida" + +#. Programmer's name for it: SDimsDoNotMatch +#: Vcl/Consts.pas:37 +msgid "Image dimensions do not match image list dimensions" +msgstr "" +"El tamaño de la imagen no concuerda con el tamaño de la lista de imágenes" + +#. Programmer's name for it: SInvalidImageList +#: Vcl/Consts.pas:38 +msgid "Invalid ImageList" +msgstr "ImageList no válida" + +#. Programmer's name for it: SImageReadFail +#: Vcl/Consts.pas:41 +msgid "Failed to read ImageList data from stream" +msgstr "Se ha producido un error al leer datos de ImageList desde el flujo" + +#. Programmer's name for it: SImageWriteFail +#: Vcl/Consts.pas:42 +msgid "Failed to write ImageList data to stream" +msgstr "" +"Se ha producido un error al escribir en el flujo los datos de Imagelist" + +#. Programmer's name for it: SWindowDCError +#: Vcl/Consts.pas:43 +msgid "Error creating window device context" +msgstr "" +"Se ha producido un error al crear el dispositivo de contexto de la ventana" + +#. Programmer's name for it: SClientNotSet +#: Vcl/Consts.pas:44 +msgid "Client of TDrag not initialized" +msgstr "Cliente de TDrag no inicializado" + +#. Programmer's name for it: SWindowClass +#: Vcl/Consts.pas:45 +msgid "Error creating window class" +msgstr "Se ha producido un error al crear la clase de ventana" + +#. Programmer's name for it: SWindowCreate +#: Vcl/Consts.pas:46 +msgid "Error creating window" +msgstr "Se ha producido un error al crear la ventana" + +#. Programmer's name for it: SCannotFocus +#: Vcl/Consts.pas:47 +msgid "Cannot focus a disabled or invisible window" +msgstr "Una ventana invisible o desactivada no puede recibir el foco" + +#. Programmer's name for it: SParentRequired +#: Vcl/Consts.pas:48 +msgid "Control '%s' has no parent window" +msgstr "El control '%s' no tiene ventana contenedora" + +#. Programmer's name for it: STwoMDIForms +#: Vcl/Consts.pas:65 +msgid "Cannot have more than one MDI form per application" +msgstr "No puede haber más de un formulario MDI por aplicación" + +#. Programmer's name for it: SCardDLLNotLoaded +#: Vcl/Consts.pas:82 +msgid "Could not load CARDS.DLL" +msgstr "No se pudo cargar CARDS.DLL" + +#. Programmer's name for it: SDuplicateCardId +#: Vcl/Consts.pas:83 +msgid "Duplicate CardId found" +msgstr "CardId duplicado encontrado" + +#. Programmer's name for it: SDdeErr +#: Vcl/Consts.pas:85 +msgid "An error returned from DDE ($0%x)" +msgstr "DDE devolvió un error ($0%x)" + +#. Programmer's name for it: SDdeConvErr +#: Vcl/Consts.pas:86 +msgid "DDE Error - conversation not established ($0%x)" +msgstr "Hay un error DDE - conversación no establecida ($0%x)" + +#. Programmer's name for it: SDdeMemErr +#: Vcl/Consts.pas:87 +msgid "Error occurred when DDE ran out of memory ($0%x)" +msgstr "Ocurrió un error cuando DDE se ejecutó fuera de memoria ($0%x)" + +#. Programmer's name for it: SDdeNoConnect +#: Vcl/Consts.pas:88 +msgid "Unable to connect DDE conversation" +msgstr "Incapaz de conectar con conversación DDE" + +#. Programmer's name for it: SOldTShape +#: Vcl/Consts.pas:93 +msgid "Cannot load older version of TShape" +msgstr "No se puede cargar una versión anterior de TShape" + +#. Programmer's name for it: SVMetafiles +#: Vcl/Consts.pas:94 +msgid "Metafiles" +msgstr "Metaarchivos" + +#. Programmer's name for it: SVEnhMetafiles +#: Vcl/Consts.pas:95 +msgid "Enhanced Metafiles" +msgstr "Metaarchivos realzados" + +#. Programmer's name for it: SOutlineIndexError +#: Vcl/Consts.pas:106 +msgid "Outline index not found" +msgstr "Indice de Outline no encontrado" + +#. Programmer's name for it: SOutlineExpandError +#: Vcl/Consts.pas:107 +msgid "Parent must be expanded" +msgstr "El ancestro debe estar expandido" + +#. Programmer's name for it: SOutlineError +#: Vcl/Consts.pas:111 +msgid "Invalid outline index" +msgstr "Indice Outline no válido" + +#. Programmer's name for it: SOutlineBadLevel +#: Vcl/Consts.pas:112 +msgid "Incorrect level assignment" +msgstr "Nivel de asignación incorrecto" + +#. Programmer's name for it: SOutlineSelection +#: Vcl/Consts.pas:113 +msgid "Invalid selection" +msgstr "Selección no válida" + +#. Programmer's name for it: SOutlineFileLoad +#: Vcl/Consts.pas:114 +msgid "File load error" +msgstr "Hay un error en la carga del archivo" + +#. Programmer's name for it: SOutlineMaxLevels +#: Vcl/Consts.pas:116 +msgid "Maximum outline depth exceeded" +msgstr "Profundidad máxima de Outline excedida" + +#. Programmer's name for it: SmkcBkSp +#: Vcl/Consts.pas:136 +msgid "BkSp" +msgstr "Retr" + +#. Programmer's name for it: SNoVolumeLabel +#: Vcl/Consts.pas:162 +msgid ": [ - no volume label - ]" +msgstr ": [ - sin etiqueta - ]" + +#. !! obsolete - delete in 5.0 +#: Vcl/Consts.pas:173 +msgid "Color" +msgstr "Color" + +#. !! obsolete - delete in 5.0 +#: Vcl/Consts.pas:174 +msgid "ABCDEFGHIJKLMNOP" +msgstr "ABCDEFGHIJKLMNOP" + +#. Programmer's name for it: SInvalidRegType +#: Vcl/Consts.pas:193 Rtl/Common/RTLConsts.pas:52 +msgid "Invalid data type for '%s'" +msgstr "Tipo de dato que no es válido para '%s'" + +#. Programmer's name for it: SUnknownConversion +#: Vcl/Consts.pas:195 +msgid "Unknown RichEdit conversion file extension (.%s)" +msgstr "Extensión de archivo (.%s) de texto enriquecido desconocida" + +#. Programmer's name for it: SCannotOpenAVI +#: Vcl/Consts.pas:202 +msgid "Cannot open AVI" +msgstr "No se puede abrir el archivo AVI" + +#. Programmer's name for it: SNotOpenErr +#: Vcl/Consts.pas:204 +msgid "No MCI device open" +msgstr "No hay dispositivos MCI abiertos" + +#. Programmer's name for it: SMPOpenFilter +#: Vcl/Consts.pas:205 +msgid "" +"All files (*.*)|*.*|Wave files (*.wav)|*.wav|Midi files (*.mid)|*.mid|Video " +"for Windows (*.avi)|*.avi" +msgstr "" +"Todos los archivos (*.*)|*.*|Archivos Wave|(*.wav)|*.wav|Archivos Midi (*." +"mid)|*.mid|Videos para Windows (*.avi)|*.avi" + +#. Programmer's name for it: SMCIAVIVideo +#: Vcl/Consts.pas:207 +msgid "AVIVideo" +msgstr "Video AVI" + +#. Programmer's name for it: SMCICDAudio +#: Vcl/Consts.pas:208 +msgid "CDAudio" +msgstr "CD de Audio" + +#. Programmer's name for it: SMCIDAT +#: Vcl/Consts.pas:209 +msgid "DAT" +msgstr "DAT" + +#. Programmer's name for it: SMCIDigitalVideo +#: Vcl/Consts.pas:210 +msgid "DigitalVideo" +msgstr "Video Digital" + +#. Programmer's name for it: SMCIMMMovie +#: Vcl/Consts.pas:211 +msgid "MMMovie" +msgstr "MMMovie" + +#. Programmer's name for it: SMCIOther +#. CustomizeFrm..Tabs..OptionsTab..OtherLbl..Caption +#: Vcl/Consts.pas:212 Vcl/CustomizeDlg.dfm:297 +msgid "Other" +msgstr "Otro" + +#. Programmer's name for it: SMCIOverlay +#: Vcl/Consts.pas:213 +msgid "Overlay" +msgstr "Overlay" + +#. Programmer's name for it: SMCIScanner +#: Vcl/Consts.pas:214 +msgid "Scanner" +msgstr "Escáner" + +#. Programmer's name for it: SMCISequencer +#: Vcl/Consts.pas:215 +msgid "Sequencer" +msgstr "Secuenciador" + +#. Programmer's name for it: SMCIVCR +#: Vcl/Consts.pas:216 +msgid "VCR" +msgstr "VCR" + +#. Programmer's name for it: SMCIVideodisc +#: Vcl/Consts.pas:217 +msgid "Videodisc" +msgstr "Videodisc" + +#. Programmer's name for it: SMCIWaveAudio +#: Vcl/Consts.pas:218 +msgid "WaveAudio" +msgstr "WaveAudio" + +#. Programmer's name for it: SMCIUnknownError +#: Vcl/Consts.pas:219 +msgid "Unknown error code" +msgstr "Código de error desconocido" + +#. Programmer's name for it: SServiceFailed +#: Vcl/Consts.pas:228 +msgid "Service failed on %s: %s" +msgstr "El servicio falló en %s: %s" + +#. Programmer's name for it: SExecute +#: Vcl/Consts.pas:229 +msgid "execute" +msgstr "ejecuta" + +#. Programmer's name for it: SStart +#: Vcl/Consts.pas:230 +msgid "start" +msgstr "inicio" + +#. Programmer's name for it: SStop +#: Vcl/Consts.pas:231 +msgid "stop" +msgstr "parada" + +#. Programmer's name for it: SPause +#: Vcl/Consts.pas:232 +msgid "pause" +msgstr "pausa" + +#. Programmer's name for it: SContinue +#: Vcl/Consts.pas:233 +msgid "continue" +msgstr "continuar" + +#. Programmer's name for it: SInterrogate +#: Vcl/Consts.pas:234 +msgid "interrogate" +msgstr "pregunta" + +#. Programmer's name for it: SShutdown +#: Vcl/Consts.pas:235 +msgid "shutdown" +msgstr "apagado" + +#. Programmer's name for it: SCustomError +#: Vcl/Consts.pas:236 +msgid "Service failed in custom message(%d): %s" +msgstr "El servicio falló en mensaje personalizado (%d): %s" + +#. Programmer's name for it: SServiceInstallOK +#: Vcl/Consts.pas:237 +msgid "Service installed successfully" +msgstr "Servicio instalado satisfactoriamente" + +#. Programmer's name for it: SServiceInstallFailed +#: Vcl/Consts.pas:238 +msgid "Service \"%s\" failed to install with error: \"%s\"" +msgstr "Se ha producido un error al instalar el servicio \"%s\". Error: \"%s\"" + +#. Programmer's name for it: SServiceUninstallOK +#: Vcl/Consts.pas:239 +msgid "Service uninstalled successfully" +msgstr "Servicio desinstalado satisfactoriamente" + +#. Programmer's name for it: SServiceUninstallFailed +#: Vcl/Consts.pas:240 +msgid "Service \"%s\" failed to uninstall with error: \"%s\"" +msgstr "" +"Se ha producido un error al desintalar el servicio \"%s\". Error: \"%s\"" + +#. Programmer's name for it: SDockedCtlNeedsName +#: Vcl/Consts.pas:247 +msgid "Docked control must have a name" +msgstr "El control de acoplamiento debe tener un nombre" + +#. Programmer's name for it: SDockTreeRemoveError +#: Vcl/Consts.pas:248 +msgid "Error removing control from dock tree" +msgstr "" +"Se ha producido un error al eliminar el control del árbol de acoplamiento" + +#. Programmer's name for it: SDockZoneNotFound +#: Vcl/Consts.pas:249 +msgid " - Dock zone not found" +msgstr " - Zona de acoplamiento no encontrada" + +#. Programmer's name for it: SDockZoneHasNoCtl +#: Vcl/Consts.pas:250 +msgid " - Dock zone has no control" +msgstr " - Zona de acoplamiento no tiene un control" + +#. Programmer's name for it: SBrowserExecError +#: Vcl/Consts.pas:257 +msgid "No default browser is specified" +msgstr "No hay navegador especificado por defecto" + +#. Programmer's name for it: SColorBoxCustomCaption +#: Vcl/Consts.pas:259 +msgid "Custom..." +msgstr "Personalizar..." + +#. Programmer's name for it: SMultiSelectRequired +#: Vcl/Consts.pas:261 +msgid "Multiselect mode must be on for this feature" +msgstr "El modo Multiselect debe estar activado para esta opción" + +#. Programmer's name for it: SKeyCaption +#: Vcl/Consts.pas:263 +msgid "Key" +msgstr "Clave" + +#. Programmer's name for it: SValueCaption +#: Vcl/Consts.pas:264 +msgid "Value" +msgstr "Valor" + +#. Programmer's name for it: SKeyConflict +#: Vcl/Consts.pas:265 +msgid "A key with the name of \"%s\" already exists" +msgstr "Una clave con el nombre \"%s\" ya existe" + +#. Programmer's name for it: SKeyNotFound +#: Vcl/Consts.pas:266 +msgid "Key \"%s\" not found" +msgstr "Clave \"%s\" no encontrada" + +#. Programmer's name for it: SNoColumnMoving +#: Vcl/Consts.pas:267 +msgid "goColMoving is not a supported option" +msgstr "goColMoving no es una opción soportada" + +#. Programmer's name for it: SNoEqualsInKey +#: Vcl/Consts.pas:268 +msgid "Key may not contain equals sign (\"=\")" +msgstr "La clave podría no contener signos igual (\"=\")" + +#. Programmer's name for it: SSendError +#: Vcl/Consts.pas:270 +msgid "Error sending mail" +msgstr "Se ha producido un error al enviar el correo" + +#. Programmer's name for it: SAssignSubItemError +#: Vcl/Consts.pas:271 +msgid "" +"Cannot assign a subitem to an actionbar when one of it's parent's is already " +"assigned to an actionbar" +msgstr "" +"No se puede asignar un subelemento a un ActionBar cuando uno de sus " +"ancestros ya está asignado a un ActionBar" + +#. Programmer's name for it: SDeleteItemWithSubItems +#: Vcl/Consts.pas:272 +msgid "Item %s has subitems, delete anyway?" +msgstr "El elemento %s tiene subelementos. ¿Eliminar de todos modos?" + +#. Programmer's name for it: SMoreButtons +#: Vcl/Consts.pas:273 +msgid "More Buttons" +msgstr "Más botones" + +#. Programmer's name for it: SErrorDownloadingURL +#: Vcl/Consts.pas:274 +msgid "Error downloading URL: %s" +msgstr "Se ha producido un error en la descarga URL: %s" + +#. Programmer's name for it: SAllActions +#: Vcl/Consts.pas:275 +msgid "(All Actions)" +msgstr "(Todas las acciones)" + +#. Programmer's name for it: SNoCategory +#: Vcl/Consts.pas:276 +msgid "(No Category)" +msgstr "Ninguna categoría" + +#. Programmer's name for it: SExpand +#: Vcl/Consts.pas:277 +msgid "Expand" +msgstr "Expandir" + +#. Programmer's name for it: SErrorSettingPath +#: Vcl/Consts.pas:278 +msgid "Error setting path: \"%s\"" +msgstr "Se ha producido un error al establecer la ruta: \"%s\"" + +#. Programmer's name for it: SLBPutError +#: Vcl/Consts.pas:279 +msgid "Attempting to put items into a virtual style listbox" +msgstr "Intentando colocar elementos en una ListBox de estilo virtual" + +#. Programmer's name for it: SErrorLoadingFile +#: Vcl/Consts.pas:280 +msgid "" +"Error loading previously saved settings file: %sWould you like to delete it?" +msgstr "" +"Se ha producido un error al cargar el archivo de asignaciones previamente " +"guardado: %s ¿Querría borrarlo?" + +#. Programmer's name for it: SResetUsageData +#: Vcl/Consts.pas:281 +msgid "Reset all usage data?" +msgstr "¿Inicializar todos los datos del usuario?" + +#. Programmer's name for it: SFileRunDialogTitle +#. StandardActions..ActionList1..FileRun1..BrowseDlg.Title +#: Vcl/Consts.pas:282 Vcl/ActnRes.dfm:237 +msgid "Run" +msgstr "Ejecutar" + +#. Programmer's name for it: SNoName +#: Vcl/Consts.pas:283 +msgid "(No Name)" +msgstr "(Sin nombre)" + +#. Programmer's name for it: SErrorActionManagerNotAssigned +#: Vcl/Consts.pas:284 +msgid "ActionManager must first be assigned" +msgstr "El ActionManager primero debe ser asignado" + +#. Programmer's name for it: SAddRemoveButtons +#: Vcl/Consts.pas:285 +msgid "&Add or Remove Buttons" +msgstr "&Añadir o eliminar botones" + +#. Programmer's name for it: SResetActionToolBar +#: Vcl/Consts.pas:286 +msgid "Reset Toolbar" +msgstr "Inicializar Toolbar" + +#. Programmer's name for it: SCustomize +#: Vcl/Consts.pas:287 +msgid "&Customize" +msgstr "&Personalizar" + +#. Programmer's name for it: SSeparator +#: Vcl/Consts.pas:288 +msgid "Separator" +msgstr "Separador" + +#. Programmer's name for it: SCirularReferencesNotAllowed +#: Vcl/Consts.pas:289 +msgid "Circular references not allowed" +msgstr "No se permiten referencias circulares" + +#. Programmer's name for it: SCannotHideActionBand +#: Vcl/Consts.pas:290 +msgid "%s does not allow hiding" +msgstr "%s no permite ocultarse" + +#. Programmer's name for it: SErrorSettingCount +#: Vcl/Consts.pas:291 +msgid "Error setting %s.Count" +msgstr "Se ha producido un error al establecer %s.Count" + +#. Programmer's name for it: SListBoxMustBeVirtual +#: Vcl/Consts.pas:292 +msgid "Listbox (%s) style must be virtual in order to set Count" +msgstr "El estilo del Listbox (%s) debe ser virtual para establecer Count" + +#. Programmer's name for it: SUnableToSaveSettings +#: Vcl/Consts.pas:293 +msgid "Unable to save settings" +msgstr "Incapaz de guadar la configuración" + +#. Programmer's name for it: sInvalidClassReference +#: Vcl/CtlConsts.pas:14 +msgid "Invalid class reference for TAppletApplication" +msgstr "Referencia de clase no válida para TAppletApplication" + +#. Programmer's name for it: SInvalidFieldSize +#: Vcl/DBConsts.pas:15 +msgid "Invalid field size" +msgstr "Tamaño de campo no válido" + +#. Programmer's name for it: SInvalidFieldKind +#: Vcl/DBConsts.pas:16 +msgid "Invalid FieldKind" +msgstr "Tipo de campo no válido" + +#. Programmer's name for it: SInvalidFieldRegistration +#: Vcl/DBConsts.pas:17 +msgid "Invalid field registration" +msgstr "Registro del campo no válido" + +#. Programmer's name for it: SUnknownFieldType +#: Vcl/DBConsts.pas:18 +msgid "Field '%s' is of an unknown type" +msgstr "El tipo del campo '%s' es desconocido" + +#. Programmer's name for it: SFieldNameMissing +#: Vcl/DBConsts.pas:19 +msgid "Field name missing" +msgstr "Falta el nombre del campo" + +#. Programmer's name for it: SDuplicateFieldName +#: Vcl/DBConsts.pas:20 +msgid "Duplicate field name '%s'" +msgstr "Nombre de campo '%s' duplicado" + +#. Programmer's name for it: SFieldNotFound +#: Vcl/DBConsts.pas:21 +msgid "Field '%s' not found" +msgstr "No se encuentra el campo %s" + +#. Programmer's name for it: SFieldAccessError +#: Vcl/DBConsts.pas:22 +msgid "Cannot access field '%s' as type %s" +msgstr "No se puede acceder el campo '%s' como tipo %s" + +#. Programmer's name for it: SFieldValueError +#: Vcl/DBConsts.pas:23 +msgid "Invalid value for field '%s'" +msgstr "Valor no válido para el campo '%s'" + +#. Programmer's name for it: SFieldRangeError +#: Vcl/DBConsts.pas:24 +msgid "%g is not a valid value for field '%s'. The allowed range is %g to %g" +msgstr "" +"%g no es un valor permitido para el campo '%s'. El rango válido es de %g a %g" + +#. Programmer's name for it: SBcdFieldRangeError +#: Vcl/DBConsts.pas:25 +msgid "%s is not a valid value for field '%s'. The allowed range is %s to %s" +msgstr "" +"%s no es un valor permitido para el campo '%s'. El rango válido es de %s a %s" + +#. Programmer's name for it: SInvalidIntegerValue +#: Vcl/DBConsts.pas:26 +msgid "'%s' is not a valid integer value for field '%s'" +msgstr "'%s' no es un valor entero válido para el campo '%s'" + +#. Programmer's name for it: SInvalidBoolValue +#: Vcl/DBConsts.pas:27 +msgid "'%s' is not a valid boolean value for field '%s'" +msgstr "'%s' no es un valor lógico válido para el campo '%s'" + +#. Programmer's name for it: SInvalidFloatValue +#: Vcl/DBConsts.pas:28 +msgid "'%s' is not a valid floating point value for field '%s'" +msgstr "'%s' no es un valor punto flotante válido para el campo '%s'" + +#. Programmer's name for it: SFieldTypeMismatch +#: Vcl/DBConsts.pas:29 +msgid "Type mismatch for field '%s', expecting: %s actual: %s" +msgstr "El campo '%s' no es del tipo esperado %s, es %s" + +#. Programmer's name for it: SFieldSizeMismatch +#: Vcl/DBConsts.pas:30 +msgid "Size mismatch for field '%s', expecting: %d actual: %d" +msgstr "El campo '%s' no es del tamaño esperado %d, es %d" + +#. Programmer's name for it: SInvalidVarByteArray +#: Vcl/DBConsts.pas:31 +msgid "Invalid variant type or size for field '%s'" +msgstr "Tipo o tamaño de variante no válido para el campo '%s'" + +#. Programmer's name for it: SFieldOutOfRange +#: Vcl/DBConsts.pas:32 +msgid "Value of field '%s' is out of range" +msgstr "El valor del campo '%s' está fuera del rango" + +#. SBCDOverflow = '(Overflow)'; +#: Vcl/DBConsts.pas:34 +msgid "Field '%s' must have a value" +msgstr "El campo '%s' debe contener un valor" + +#. Programmer's name for it: SDataSetMissing +#: Vcl/DBConsts.pas:35 +msgid "Field '%s' has no dataset" +msgstr "El campo '%s' no tiene fuente de datos" + +#. Programmer's name for it: SInvalidCalcType +#: Vcl/DBConsts.pas:36 +msgid "Field '%s' cannot be a calculated or lookup field" +msgstr "El campo '%s' no es de tipo calculado o búsqueda" + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/DBConsts.pas:37 +msgid "Field '%s' cannot be modified" +msgstr "El campo '%s' no se puede modificar" + +#. Programmer's name for it: SFieldIndexError +#: Vcl/DBConsts.pas:38 +msgid "Field index out of range" +msgstr "Indice de campo fuera de rango" + +#. Programmer's name for it: SNoFieldIndexes +#: Vcl/DBConsts.pas:39 +msgid "No index currently active" +msgstr "Actualmente no hay un índice activo" + +#. Programmer's name for it: SNotIndexField +#: Vcl/DBConsts.pas:40 +msgid "Field '%s' is not indexed and cannot be modified" +msgstr "El campo '%s' no está indexado y no se puede modificar" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/DBConsts.pas:41 +msgid "Cannot access index field '%s'" +msgstr "Inaccesible el campo '%s' del índice" + +#. Programmer's name for it: SDuplicateIndexName +#: Vcl/DBConsts.pas:42 +msgid "Duplicate index name '%s'" +msgstr "Nombre de índice '%s' duplicado" + +#. Programmer's name for it: SNoIndexForFields +#: Vcl/DBConsts.pas:43 +msgid "No index for fields '%s'" +msgstr "No hay índice para los campos '%s' " + +#. Programmer's name for it: SIndexNotFound +#: Vcl/DBConsts.pas:44 +msgid "Index '%s' not found" +msgstr "El índice '%s' no existe" + +#. Programmer's name for it: SDuplicateName +#: Vcl/DBConsts.pas:45 +msgid "Duplicate name '%s' in %s" +msgstr "Nombre '%s' duplicado en %s" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/DBConsts.pas:46 +msgid "Circular datalinks are not allowed" +msgstr "No se permiten enlaces de datos circulares" + +#. Programmer's name for it: SLookupInfoError +#: Vcl/DBConsts.pas:47 +msgid "Lookup information for field '%s' is incomplete" +msgstr "La información de búsqueda para el campo '%s' está incompleta" + +#. Programmer's name for it: SNewLookupFieldCaption +#: Vcl/DBConsts.pas:48 +msgid "New Lookup Field" +msgstr "Nuevo campo Lookup" + +#. Programmer's name for it: SDataSourceChange +#: Vcl/DBConsts.pas:49 +msgid "DataSource cannot be changed" +msgstr "La fuente de datos no puede ser cambiada" + +#. Programmer's name for it: SNoNestedMasterSource +#: Vcl/DBConsts.pas:50 +msgid "Nested datasets cannot have a MasterSource" +msgstr "La datasets anidados no pueden tener un MasterSource" + +#. Programmer's name for it: SDataSetOpen +#: Vcl/DBConsts.pas:51 +msgid "Cannot perform this operation on an open dataset" +msgstr "No puede ejecutarse esta operación en un dataset abierto" + +#. Programmer's name for it: SNotEditing +#: Vcl/DBConsts.pas:52 +msgid "Dataset not in edit or insert mode" +msgstr "El dataset no está en modo edición o inserción" + +#. Programmer's name for it: SDataSetClosed +#: Vcl/DBConsts.pas:53 +msgid "Cannot perform this operation on a closed dataset" +msgstr "No puede ejecutarse esta operación en un dataset cerrado" + +#. Programmer's name for it: SDataSetEmpty +#: Vcl/DBConsts.pas:54 +msgid "Cannot perform this operation on an empty dataset" +msgstr "No puede ejecutarse esta operación en un dataset vacío" + +#. Programmer's name for it: SDataSetReadOnly +#: Vcl/DBConsts.pas:55 +msgid "Cannot modify a read-only dataset" +msgstr "No puede modificarse un dataset de sólo lectura" + +#. Programmer's name for it: SNestedDataSetClass +#: Vcl/DBConsts.pas:56 +msgid "Nested dataset must inherit from %s" +msgstr "El dataset anidado debe heredar de %s" + +#. Programmer's name for it: SExprTermination +#: Vcl/DBConsts.pas:57 +msgid "Filter expression incorrectly terminated" +msgstr "Expresión del filtro terminada incorrectamente" + +#. Programmer's name for it: SExprNameError +#: Vcl/DBConsts.pas:58 +msgid "Unterminated field name" +msgstr "Nombre de campo sin terminar" + +#. Programmer's name for it: SExprStringError +#: Vcl/DBConsts.pas:59 +msgid "Unterminated string constant" +msgstr "Cadena constante sin terminar" + +#. Programmer's name for it: SExprInvalidChar +#: Vcl/DBConsts.pas:60 +msgid "Invalid filter expression character: '%s'" +msgstr "Carácter '%s' no válido en una expresión de filtro" + +#. Programmer's name for it: SExprNoLParen +#: Vcl/DBConsts.pas:61 +msgid "'(' expected but %s found" +msgstr " '(' esperado, pero se encontró %s" + +#. Programmer's name for it: SExprNoRParen +#: Vcl/DBConsts.pas:62 +msgid "')' expected but %s found" +msgstr " ')' esperado, pero se encontró %s" + +#. Programmer's name for it: SExprNoRParenOrComma +#: Vcl/DBConsts.pas:63 +msgid "')' or ',' expected but %s found" +msgstr "')' o ',' esperados, pero se encontró %s" + +#. Programmer's name for it: SExprExpected +#: Vcl/DBConsts.pas:64 +msgid "Expression expected but %s found" +msgstr "Expresión esperada pero encontrado %s" + +#. Programmer's name for it: SExprBadField +#: Vcl/DBConsts.pas:65 +msgid "Field '%s' cannot be used in a filter expression" +msgstr "El campo '%s' no se puede utilizar en una expresión de filtro" + +#. Programmer's name for it: SExprBadNullTest +#: Vcl/DBConsts.pas:66 +msgid "NULL only allowed with '=' and '<>'" +msgstr "El valor nulo (NULL) sólo se permite con '=' y '<>'" + +#. Programmer's name for it: SExprRangeError +#: Vcl/DBConsts.pas:67 +msgid "Constant out of range" +msgstr "Constante fuera de rango" + +#. Programmer's name for it: SExprNotBoolean +#: Vcl/DBConsts.pas:68 +msgid "Field '%s' is not of type Boolean" +msgstr "El campo '%s' no es de tipo lógico" + +#. Programmer's name for it: SExprIncorrect +#: Vcl/DBConsts.pas:69 +msgid "Incorrectly formed filter expression" +msgstr "Expresión del filtro formada incorrectamente" + +#. Programmer's name for it: SExprNothing +#: Vcl/DBConsts.pas:70 +msgid "nothing" +msgstr "nada" + +#. Programmer's name for it: SExprTypeMis +#: Vcl/DBConsts.pas:71 +msgid "Type mismatch in expression" +msgstr "El tipo no concuerda en la expresión" + +#. Programmer's name for it: SExprBadScope +#: Vcl/DBConsts.pas:72 +msgid "Operation cannot mix aggregate value with record-varying value" +msgstr "" +"La operación no puede mezclar valores de agregación con valores de registro " +"variable" + +#. Programmer's name for it: SExprNoArith +#: Vcl/DBConsts.pas:73 +msgid "Arithmetic in filter expressions not supported" +msgstr "Operación aritmética no soportada en la expresión del filtro" + +#. Programmer's name for it: SExprNotAgg +#: Vcl/DBConsts.pas:74 +msgid "Expression is not an aggregate expression" +msgstr "La expresión no es una expresión de agregación" + +#. Programmer's name for it: SExprBadConst +#: Vcl/DBConsts.pas:75 +msgid "Constant is not correct type %s" +msgstr "La constante no es del tipo correcto %s" + +#. Programmer's name for it: SExprNoAggFilter +#: Vcl/DBConsts.pas:76 +msgid "Aggregate expressions not allowed in filters" +msgstr "No se permiten expresiones de agregación en los filtros" + +#. Programmer's name for it: SExprEmptyInList +#: Vcl/DBConsts.pas:77 +msgid "IN predicate list may not be empty" +msgstr "No puede estar vacía la lista de predicados de entrada (IN)" + +#. Programmer's name for it: SInvalidKeywordUse +#: Vcl/DBConsts.pas:78 +msgid "Invalid use of keyword" +msgstr "Uso de clave no válido" + +#. Programmer's name for it: SParameterNotFound +#: Vcl/DBConsts.pas:81 +msgid "Parameter '%s' not found" +msgstr "No se encuentra el parámetro '%s'" + +#. Programmer's name for it: SInvalidVersion +#: Vcl/DBConsts.pas:82 +msgid "Unable to load bind parameters" +msgstr "No se pueden leer los argumentos de enlace" + +#. Programmer's name for it: SParamTooBig +#: Vcl/DBConsts.pas:83 +msgid "Parameter '%s', cannot save data larger than %d bytes" +msgstr "El parámetro '%s' no puede guardar datos mayores a %d bytes" + +#. Programmer's name for it: SBadFieldType +#: Vcl/DBConsts.pas:84 +msgid "Field '%s' is of an unsupported type" +msgstr "El campo '%s' es de un tipo no soportado" + +#. Programmer's name for it: SAggActive +#: Vcl/DBConsts.pas:85 +msgid "Property may not be modified while aggregate is active" +msgstr "La propiedad no puede ser modificada mientras agregar esté activo" + +#. Programmer's name for it: SProviderSQLNotSupported +#: Vcl/DBConsts.pas:86 +msgid "SQL not supported: %s" +msgstr "SQL no soportado: %s" + +#. Programmer's name for it: SProviderExecuteNotSupported +#: Vcl/DBConsts.pas:87 +msgid "Execute not supported: %s" +msgstr "Ejecutar no soportado: %s" + +#. Programmer's name for it: SExprNoAggOnCalcs +#: Vcl/DBConsts.pas:88 +msgid "" +"Field '%s' is not the correct type of calculated field to be used in an " +"aggregate, use an internalcalc" +msgstr "" +"El campo %s no es un tipo correcto de campo calculado para ser usado en una " +"agregración, utiliza un \"internalcalc\"" + +#. Programmer's name for it: SRecordChanged +#: Vcl/DBConsts.pas:89 +msgid "Record not found or changed by another user" +msgstr "Registro no encontrado o cambiado por otro usuario" + +#. Programmer's name for it: SDataSetUnidirectional +#: Vcl/DBConsts.pas:90 +msgid "Operation not allowed on a unidirectional dataset" +msgstr "Operación no permitida en una fuente de datos unidireccional" + +#. Programmer's name for it: SUnassignedVar +#: Vcl/DBConsts.pas:91 +msgid "Unassigned variant value" +msgstr "Valor variant sin asignar" + +#. Programmer's name for it: SRecordNotFound +#: Vcl/DBConsts.pas:92 Vcl/MidConst.pas:62 +msgid "Record not found" +msgstr "Registro no encontrado" + +#. Programmer's name for it: SFileNameBlank +#: Vcl/DBConsts.pas:93 +msgid "FileName property cannot be blank" +msgstr "La propiedad FileName no puede estar en blanco" + +#. Programmer's name for it: SBcdOverflow +#: Vcl/DBConsts.pas:97 +msgid "BCD overflow" +msgstr "Sobrecarga BCD" + +#. Programmer's name for it: SInvalidBcdValue +#: Vcl/DBConsts.pas:98 +msgid "%s is not a valid BCD value" +msgstr "%s no es un valor BCD válido" + +#. Programmer's name for it: SInvalidFormatType +#: Vcl/DBConsts.pas:99 +msgid "Invalid format type for BCD" +msgstr "Tipo de formato para BCD no válido" + +#. Programmer's name for it: SCouldNotParseTimeStamp +#: Vcl/DBConsts.pas:103 +msgid "Could not parse SQL TimeStamp string" +msgstr "Podría no analizar la cadena SQL TimeStamp" + +#. Programmer's name for it: SInvalidSqlTimeStamp +#: Vcl/DBConsts.pas:104 +msgid "Invalid SQL date/time values" +msgstr "Valores fecha/hora SQL no válidos" + +#. Programmer's name for it: SBackupCaption +#: Vcl/IBDCLConst.pas:6 +msgid "Backup Database files" +msgstr "" + +#. Programmer's name for it: SRestoreSize +#: Vcl/IBDCLConst.pas:7 +msgid "Size(Bytes)" +msgstr "" + +#. Programmer's name for it: SFileNames +#: Vcl/IBDCLConst.pas:8 +msgid "Filename(s)" +msgstr "" + +#. Programmer's name for it: SPages +#: Vcl/IBDCLConst.pas:9 +msgid "Pages" +msgstr "Páginas" + +#. Programmer's name for it: SDatabasefiles +#: Vcl/IBDCLConst.pas:10 +msgid "Database Files|*.gdb" +msgstr "" + +#. Programmer's name for it: SIBTransactionEditor +#: Vcl/IBXConst.pas:41 +msgid "&Transaction Editor..." +msgstr "Editor de transacción..." + +#. Programmer's name for it: SDatabaseFilter +#: Vcl/IBXConst.pas:42 +msgid "Database Files (*.gdb)|*.gdb|All files (*.*)|*.*" +msgstr "" + +#. Programmer's name for it: SCommitTransaction +#: Vcl/IBXConst.pas:44 +msgid "Transaction is currently Active. Rollback and continue?" +msgstr "" + +#. Programmer's name for it: SIBDataSetEditor +#: Vcl/IBXConst.pas:50 +msgid "&Dataset Editor..." +msgstr "Editor del Conjunto de Da&tos..." + +#. Programmer's name for it: SDefaultTransaction +#: Vcl/IBXConst.pas:52 +msgid "%s, Default" +msgstr "" + +#. Programmer's name for it: SUnknownError +#: Vcl/IBXConst.pas:55 +msgid "Unknown error" +msgstr "Hay un error desconocido" + +#. Programmer's name for it: SInterBaseMissing +#: Vcl/IBXConst.pas:57 +msgid "" +"InterBase library gds32.dll not found in the path. Please install InterBase " +"to use this functionality" +msgstr "" + +#. Programmer's name for it: SInterBaseMissing +#: Vcl/IBXConst.pas:60 +msgid "" +"InterBase library gds.so.0 not found in the path. Please install InterBase " +"to use this functionality" +msgstr "" + +#. Programmer's name for it: SInterBaseInstallMissing +#: Vcl/IBXConst.pas:62 +msgid "" +"InterBase Install DLL ibinstall.dll not found in the path. Please install " +"InterBase 6 to use this functionality" +msgstr "" + +#. Programmer's name for it: SIB60feature +#: Vcl/IBXConst.pas:63 +msgid "" +"%s is an InterBase 6 function. Please upgrade to InterBase 6 to use this " +"functonality" +msgstr "" + +#. Programmer's name for it: SNotSupported +#: Vcl/IBXConst.pas:64 +msgid "Unsupported feature" +msgstr "Característica no soportada" + +#. Programmer's name for it: SNotPermitted +#: Vcl/IBXConst.pas:65 +msgid "Not permitted" +msgstr "No permitido" + +#. Programmer's name for it: SFileAccessError +#: Vcl/IBXConst.pas:66 +msgid "Temporary file access error" +msgstr "" + +#. Programmer's name for it: SConnectionTimeout +#: Vcl/IBXConst.pas:67 +msgid "Database connection timed out" +msgstr "Conexión a base de datos fuera de tiempo." + +#. Programmer's name for it: SCannotSetDatabase +#: Vcl/IBXConst.pas:68 +msgid "Cannot set database" +msgstr "No se puede establecer la base de datos" + +#. Programmer's name for it: SCannotSetTransaction +#: Vcl/IBXConst.pas:69 +msgid "Cannot set transaction" +msgstr "" + +#. Programmer's name for it: SOperationCancelled +#: Vcl/IBXConst.pas:70 +msgid "Operation cancelled at user's request" +msgstr "" + +#. Programmer's name for it: SDPBConstantNotSupported +#: Vcl/IBXConst.pas:71 +msgid "DPB Constant (isc_dpb_%s) is unsupported" +msgstr "" + +#. Programmer's name for it: SDPBConstantUnknown +#: Vcl/IBXConst.pas:72 +msgid "DPB Constant (%d) is unknown" +msgstr "" + +#. Programmer's name for it: STPBConstantNotSupported +#: Vcl/IBXConst.pas:73 +msgid "TPB Constant (isc_tpb_%s) is unsupported" +msgstr "" + +#. Programmer's name for it: STPBConstantUnknown +#: Vcl/IBXConst.pas:74 +msgid "TPB Constant (%d) is unknown" +msgstr "" + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/IBXConst.pas:75 +msgid "Cannot perform operation -- DB is not open" +msgstr "" +"No se puede ejecutar esta operación en una base de datos que no está abierta" + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/IBXConst.pas:76 +msgid "Cannot perform operation -- DB is currently open" +msgstr "No se puede ejecutar esta operación en una base de datos abierta" + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/IBXConst.pas:77 +msgid "Database name is missing" +msgstr "Base de datos no posee nombre" + +#. Programmer's name for it: SNotInTransaction +#: Vcl/IBXConst.pas:78 +msgid "Transaction is not active" +msgstr "" + +#. Programmer's name for it: SInTransaction +#: Vcl/IBXConst.pas:79 +msgid "Transaction is active" +msgstr "" + +#. Programmer's name for it: STimeoutNegative +#: Vcl/IBXConst.pas:80 +msgid "Timeout values cannot be negative" +msgstr "" + +#. Programmer's name for it: SNoDatabasesInTransaction +#: Vcl/IBXConst.pas:81 +msgid "No databases are listed in transaction component" +msgstr "" + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/IBXConst.pas:82 +msgid "Updating wrong database" +msgstr "" + +#. Programmer's name for it: SUpdateWrongTR +#: Vcl/IBXConst.pas:83 +msgid "Updating wrong transaction. Unique transaction expected in set" +msgstr "" + +#. Programmer's name for it: SDatabaseNotAssigned +#: Vcl/IBXConst.pas:84 +msgid "Database not assigned" +msgstr "Base de datos no asignada" + +#. Programmer's name for it: STransactionNotAssigned +#: Vcl/IBXConst.pas:85 +msgid "Transaction not assigned" +msgstr "Transacción no asignada" + +#. Programmer's name for it: SXSQLDAIndexOutOfRange +#: Vcl/IBXConst.pas:86 +msgid "XSQLDA index out of range" +msgstr "El índice de XSQLDA está fuera del rango" + +#. Programmer's name for it: SXSQLDANameDoesNotExist +#: Vcl/IBXConst.pas:87 +msgid "XSQLDA name does not exist (%s)" +msgstr "El nombre XSQLDA no existe (%s)" + +#. Programmer's name for it: SEOF +#: Vcl/IBXConst.pas:88 +msgid "End of file" +msgstr "" + +#. Programmer's name for it: SBOF +#: Vcl/IBXConst.pas:89 +msgid "Beginning of file" +msgstr "" + +#. Programmer's name for it: SInvalidStatementHandle +#: Vcl/IBXConst.pas:90 +msgid "Invalid statement handle" +msgstr "Manejador (handle) de la declaración no válido" + +#. Programmer's name for it: SSQLOpen +#: Vcl/IBXConst.pas:91 +msgid "IBSQL Open" +msgstr "" + +#. Programmer's name for it: SSQLClosed +#: Vcl/IBXConst.pas:92 +msgid "IBSQL Closed" +msgstr "" + +#. Programmer's name for it: SDatasetOpen +#: Vcl/IBXConst.pas:93 +msgid "Dataset open" +msgstr "" + +#. Programmer's name for it: SDatasetClosed +#: Vcl/IBXConst.pas:94 +msgid "Dataset closed" +msgstr "" + +#. Programmer's name for it: SUnknownSQLDataType +#: Vcl/IBXConst.pas:95 +msgid "Unknown SQL Data type (%d)" +msgstr "Tipo de dato SQL (%d) desconocido" + +#. Programmer's name for it: SInvalidColumnIndex +#: Vcl/IBXConst.pas:96 +msgid "Invalid column index (index exceeds permitted range)" +msgstr "" + +#. Programmer's name for it: SInvalidParamColumnIndex +#: Vcl/IBXConst.pas:97 +msgid "Invalid parameter index (index exceeds permitted range)" +msgstr "" + +#. Programmer's name for it: SInvalidDataConversion +#: Vcl/IBXConst.pas:98 +msgid "Invalid data conversion" +msgstr "Conversión de dato no válida" + +#. Programmer's name for it: SColumnIsNotNullable +#: Vcl/IBXConst.pas:99 +msgid "Column cannot be set to null (%s)" +msgstr "" + +#. Programmer's name for it: SBlobCannotBeRead +#: Vcl/IBXConst.pas:100 +msgid "Blob stream cannot be read" +msgstr "" + +#. Programmer's name for it: SBlobCannotBeWritten +#: Vcl/IBXConst.pas:101 +msgid "Blob stream cannot be written" +msgstr "" + +#. Programmer's name for it: SEmptyQuery +#: Vcl/IBXConst.pas:102 +msgid "Empty query" +msgstr "" + +#. Programmer's name for it: SCannotOpenNonSQLSelect +#: Vcl/IBXConst.pas:103 +msgid "Cannot \"open\" a non-select statement. Use ExecQuery" +msgstr "" + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/IBXConst.pas:104 +msgid "No access to field \"%s\"" +msgstr "" + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/IBXConst.pas:105 +msgid "Field \"%s\" is read-only" +msgstr "" + +#. Programmer's name for it: SFieldNotFound +#: Vcl/IBXConst.pas:106 +msgid "Field \"%s\" not found" +msgstr "El campo \"%s\" no se ha encontrado" + +#. Programmer's name for it: SNotEditing +#: Vcl/IBXConst.pas:107 +msgid "Not in edit mode" +msgstr "No está en modo de edición" + +#. Programmer's name for it: SCannotInsert +#: Vcl/IBXConst.pas:108 +msgid "Cannot insert into dataset. (No insert query)" +msgstr "" + +#. Programmer's name for it: SCannotPost +#: Vcl/IBXConst.pas:109 +msgid "Cannot post. (No update/insert query)" +msgstr "" + +#. Programmer's name for it: SCannotUpdate +#: Vcl/IBXConst.pas:110 +msgid "Cannot update. (No update query)" +msgstr "" + +#. Programmer's name for it: SCannotDelete +#: Vcl/IBXConst.pas:111 +msgid "Cannot delete from dataset. (No delete query)" +msgstr "" + +#. Programmer's name for it: SCannotRefresh +#: Vcl/IBXConst.pas:112 +msgid "Cannot refresh row. (No refresh query)" +msgstr "" + +#. Programmer's name for it: SBufferNotSet +#: Vcl/IBXConst.pas:113 +msgid "Buffer not set" +msgstr "" + +#. Programmer's name for it: SCircularReference +#: Vcl/IBXConst.pas:114 +msgid "Circular references not permitted" +msgstr "" + +#. Programmer's name for it: SSQLParseError +#: Vcl/IBXConst.pas:115 +msgid "" +"SQL Parse Error:\n" +"\n" +"%s" +msgstr "" + +#. Programmer's name for it: SUserAbort +#: Vcl/IBXConst.pas:116 +msgid "User abort" +msgstr "" + +#. Programmer's name for it: SDataSetUniDirectional +#: Vcl/IBXConst.pas:117 +msgid "Data set is uni-directional" +msgstr "" + +#. Programmer's name for it: SCannotCreateSharedResource +#: Vcl/IBXConst.pas:118 +msgid "Cannot create shared resource. (Windows error %d)" +msgstr "" + +#. Programmer's name for it: SWindowsAPIError +#: Vcl/IBXConst.pas:119 +msgid "Windows API error. (Windows error %d [$%.8x])" +msgstr "" + +#. Programmer's name for it: SColumnListsDontMatch +#: Vcl/IBXConst.pas:120 +msgid "Column lists do not match" +msgstr "" + +#. Programmer's name for it: SColumnTypesDontMatch +#: Vcl/IBXConst.pas:121 +msgid "Column types don't match. (From index: %d; To index: %d)" +msgstr "" + +#. Programmer's name for it: SCantEndSharedTransaction +#: Vcl/IBXConst.pas:123 +msgid "" +"Can't end a shared transaction unless it is forced and equal to the " +"transaction's TimeoutAction" +msgstr "" + +#. Programmer's name for it: SFieldUnsupportedType +#: Vcl/IBXConst.pas:124 +msgid "Unsupported Field Type" +msgstr "Tipo de campo no soportado" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/IBXConst.pas:125 +msgid "Circular DataLink Reference" +msgstr "" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/IBXConst.pas:126 +msgid "Empty SQL Statement" +msgstr "" + +#. Programmer's name for it: SIsASelectStatement +#: Vcl/IBXConst.pas:127 +msgid "use Open for a Select Statement" +msgstr "" + +#. Programmer's name for it: SRequiredParamNotSet +#: Vcl/IBXConst.pas:128 +msgid "Required Param value not set" +msgstr "" + +#. Programmer's name for it: SNoStoredProcName +#: Vcl/IBXConst.pas:129 +msgid "No Stored Procedure Name assigned" +msgstr "" + +#. Programmer's name for it: SIsAExecuteProcedure +#: Vcl/IBXConst.pas:130 +msgid "use ExecProc for Procedure; use TQuery for Select procedures" +msgstr "" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/IBXConst.pas:131 +msgid "Update Failed" +msgstr "Fallo en la actualización" + +#. Programmer's name for it: SNotCachedUpdates +#: Vcl/IBXConst.pas:132 +msgid "CachedUpdates not enabled" +msgstr "" + +#. Programmer's name for it: SNotLiveRequest +#: Vcl/IBXConst.pas:133 +msgid "Request is not live - cannot modify" +msgstr "" + +#. Programmer's name for it: SNoProvider +#: Vcl/IBXConst.pas:134 +msgid "No Provider" +msgstr "Proveedor no disponible" + +#. Programmer's name for it: SNoRecordsAffected +#: Vcl/IBXConst.pas:135 +msgid "No Records Affected" +msgstr "No se han alterado los registros" + +#. Programmer's name for it: SNoTableName +#: Vcl/IBXConst.pas:136 +msgid "No Table Name assigned" +msgstr "La propiedad TableName no tiene valor" + +#. Programmer's name for it: SCannotCreatePrimaryIndex +#: Vcl/IBXConst.pas:137 +msgid "Cannot Create Primary Index; are created automatically" +msgstr "" + +#. Programmer's name for it: SCannotDropSystemIndex +#: Vcl/IBXConst.pas:138 +msgid "Cannot Drop System Index" +msgstr "" + +#. Programmer's name for it: STableNameMismatch +#: Vcl/IBXConst.pas:139 +msgid "Table Name Mismatch" +msgstr "" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/IBXConst.pas:140 +msgid "Index Field Missing" +msgstr "Inaccesible el campo '%s' del índice" + +#. Programmer's name for it: SInvalidCancellation +#: Vcl/IBXConst.pas:141 +msgid "Cannot Cancel events while processing" +msgstr "No se puede cancelar los eventos mientras se procesa" + +#. Programmer's name for it: SInvalidEvent +#: Vcl/IBXConst.pas:142 +msgid "Invalid Event" +msgstr "Evento no válido." + +#. Programmer's name for it: SMaximumEvents +#: Vcl/IBXConst.pas:143 +msgid "Exceded Maximum Event limits" +msgstr "" + +#. Programmer's name for it: SNoEventsRegistered +#: Vcl/IBXConst.pas:144 +msgid "No Events Registered" +msgstr "" + +#. Programmer's name for it: SInvalidQueueing +#: Vcl/IBXConst.pas:145 +msgid "Invalid Queueing" +msgstr "Queueing no válido" + +#. Programmer's name for it: SInvalidRegistration +#: Vcl/IBXConst.pas:146 +msgid "Invalid Registration" +msgstr "Acción de registrar no válido" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/IBXConst.pas:147 +msgid "Invalid Batch Move" +msgstr "Batch Move no válido" + +#. Programmer's name for it: SSQLDialectInvalid +#: Vcl/IBXConst.pas:148 +msgid "SQL Dialect Invalid" +msgstr "" + +#. Programmer's name for it: SSPBConstantNotSupported +#: Vcl/IBXConst.pas:149 +msgid "SPB Constant Not supported" +msgstr "Constante SPB no permitida" + +#. Programmer's name for it: SSPBConstantUnknown +#: Vcl/IBXConst.pas:150 +msgid "SPB Constant Unknown" +msgstr "" + +#. Programmer's name for it: SServiceActive +#: Vcl/IBXConst.pas:151 +msgid "Cannot perform operation -- service is not attached" +msgstr "No se puede ejecutar esta operación -- el servicio no está conectado" + +#. Programmer's name for it: SServiceInActive +#: Vcl/IBXConst.pas:152 +msgid "Cannot perform operation -- service is attached" +msgstr "No se puede ejecutar esta operación -- el servicio está conectado" + +#. Programmer's name for it: SServerNameMissing +#: Vcl/IBXConst.pas:153 +msgid "Server Name Missing" +msgstr "Se ha perdido el nombre del servidor" + +#. Programmer's name for it: SQueryParamsError +#: Vcl/IBXConst.pas:154 +msgid "Query Parameters missing or incorrect" +msgstr "" + +#. Programmer's name for it: SStartParamsError +#: Vcl/IBXConst.pas:155 +msgid "start Parameters missing or incorrect" +msgstr "" + +#. Programmer's name for it: SOutputParsingError +#: Vcl/IBXConst.pas:156 +msgid "Unexpected Output buffer value" +msgstr "" + +#. Programmer's name for it: SUseSpecificProcedures +#: Vcl/IBXConst.pas:157 +msgid "" +"Generic ServiceStart not applicable: Use Specific Procedures to set " +"configuration params" +msgstr "" + +#. Programmer's name for it: SSQLMonitorAlreadyPresent +#: Vcl/IBXConst.pas:158 +msgid "SQL Monitor Instance is already present" +msgstr "" + +#. Programmer's name for it: SCantPrintValue +#: Vcl/IBXConst.pas:159 +msgid "Cannot print value" +msgstr "" + +#. Programmer's name for it: SEOFReached +#: Vcl/IBXConst.pas:160 +msgid "SEOFReached" +msgstr "" + +#. Programmer's name for it: SEOFInComment +#: Vcl/IBXConst.pas:161 +msgid "EOF in comment detected" +msgstr "" + +#. Programmer's name for it: SEOFInString +#: Vcl/IBXConst.pas:162 +msgid "EOF in string detected" +msgstr "" + +#. Programmer's name for it: SParamNameExpected +#: Vcl/IBXConst.pas:163 +msgid "Parameter name expected" +msgstr "" + +#. Programmer's name for it: SSuccess +#: Vcl/IBXConst.pas:164 +msgid "Successful execution" +msgstr "" + +#. Programmer's name for it: SDelphiException +#: Vcl/IBXConst.pas:165 +msgid "DelphiException %s" +msgstr "" + +#. Programmer's name for it: SNoOptionsSet +#: Vcl/IBXConst.pas:166 +msgid "No Install Options selected" +msgstr "" + +#. Programmer's name for it: SNoDestinationDirectory +#: Vcl/IBXConst.pas:167 +msgid "DestinationDirectory is not set" +msgstr "El DestinationDirectory no está asignado" + +#. Programmer's name for it: SNosourceDirectory +#: Vcl/IBXConst.pas:168 +msgid "SourceDirectory is not set" +msgstr "El SourceDirectory no está asignado" + +#. Programmer's name for it: SNoUninstallFile +#: Vcl/IBXConst.pas:169 +msgid "Uninstall File Name is not set" +msgstr "" + +#. Programmer's name for it: SOptionNeedsClient +#: Vcl/IBXConst.pas:170 +msgid "%s component requires Client to function properly" +msgstr "" + +#. Programmer's name for it: SOptionNeedsServer +#: Vcl/IBXConst.pas:171 +msgid "%s component requires Server to function properly" +msgstr "" + +#. Programmer's name for it: SInvalidOption +#: Vcl/IBXConst.pas:172 +msgid "Invalid option specified" +msgstr "Se especificó una opción no válida" + +#. Programmer's name for it: SInvalidOnErrorResult +#: Vcl/IBXConst.pas:173 +msgid "Unexpected onError return value" +msgstr "" + +#. Programmer's name for it: SInvalidOnStatusResult +#: Vcl/IBXConst.pas:174 +msgid "Unexpected onStatus return value" +msgstr "" + +#. Programmer's name for it: SInterbaseExpressVersion +#: Vcl/IBXConst.pas:176 +msgid "InterbaseExpress 4.3" +msgstr "" + +#. Programmer's name for it: SEditSQL +#: Vcl/IBXConst.pas:177 +msgid "Edit SQL" +msgstr "" + +#. Programmer's name for it: SDPBConstantUnknownEx +#: Vcl/IBXConst.pas:178 +msgid "DPB Constant (%s) is unknown" +msgstr "" + +#. Programmer's name for it: STPBConstantUnknownEx +#: Vcl/IBXConst.pas:179 +msgid "TPB Constant (%s) is unknown" +msgstr "" + +#. Programmer's name for it: SInterbaseExpressVersionEx +#: Vcl/IBXConst.pas:180 +msgid "InterbaseExpress %g" +msgstr "" + +#. Programmer's name for it: SUnknownPlan +#: Vcl/IBXConst.pas:181 +msgid "Unknown Error - Can't retrieve plan" +msgstr "" + +#. Programmer's name for it: SFieldSizeMismatch +#: Vcl/IBXConst.pas:182 +msgid "Size Mismatch - Field %s size is too small for data" +msgstr "" + +#. Programmer's name for it: SEventAlreadyRegistered +#: Vcl/IBXConst.pas:183 +msgid "Events already registered" +msgstr "Los eventos ya estaban registrados" + +#. Programmer's name for it: SStringTooLarge +#: Vcl/IBXConst.pas:184 +msgid "" +"Trying to store a string of length %d into a field that can only contain %d" +msgstr "" + +#. Programmer's name for it: SIBServiceEditor +#: Vcl/IBXConst.pas:185 +msgid "&Service Editor ..." +msgstr "Editor del servicio..." + +#. Programmer's name for it: SIBSuccessConnect +#: Vcl/IBXConst.pas:186 +msgid "Successful Connection" +msgstr "Conexión establecida" + +#. Programmer's name for it: SProviderNotExported +#: Vcl/MidConst.pas:35 +msgid "Provider not exported: %s" +msgstr "" + +#. Programmer's name for it: SNoDataProvider +#: Vcl/MidConst.pas:38 +msgid "Missing data provider or data packet" +msgstr "" + +#. Programmer's name for it: SInvalidDataPacket +#: Vcl/MidConst.pas:39 +msgid "Invalid data packet" +msgstr "Paquete de datos no válido" + +#. Programmer's name for it: SRefreshError +#: Vcl/MidConst.pas:40 +msgid "Must apply updates before refreshing data" +msgstr "" + +#. Programmer's name for it: SProviderInvalid +#: Vcl/MidConst.pas:41 +msgid "Invalid provider. Provider was freed by the application server" +msgstr "" + +#. Programmer's name for it: SServerNameBlank +#: Vcl/MidConst.pas:42 +msgid "Cannot connect, %s must contain a valid ServerName or ServerGUID" +msgstr "" + +#. Programmer's name for it: SRepositoryIdBlank +#: Vcl/MidConst.pas:43 +msgid "Cannot connect, %s must contain a valid repository id" +msgstr "" + +#. Programmer's name for it: SAggsGroupingLevel +#: Vcl/MidConst.pas:44 +msgid "Grouping level exceeds current index field count" +msgstr "" + +#. Programmer's name for it: SAggsNoSuchLevel +#: Vcl/MidConst.pas:45 +msgid "Grouping level not defined" +msgstr "" + +#. Programmer's name for it: SNoCircularReference +#: Vcl/MidConst.pas:46 +msgid "Circular provider references not allowed" +msgstr "" + +#. Programmer's name for it: SErrorLoadingMidas +#: Vcl/MidConst.pas:47 +msgid "Error loading MIDAS.DLL" +msgstr "" + +#. Programmer's name for it: SCannotCreateDataSet +#: Vcl/MidConst.pas:48 +msgid "No fields defined. Cannot create dataset" +msgstr "" + +#. Programmer's name for it: SFieldNameTooLarge +#: Vcl/MidConst.pas:49 +msgid "Fieldname %s exceeds %d chars" +msgstr "" + +#. Programmer's name for it: SInvalidClone +#: Vcl/MidConst.pas:50 +msgid "CloneConnection invalid: distinct ClientDataSet descendents" +msgstr "" + +#. Programmer's name for it: SSocketReadError +#: Vcl/MidConst.pas:53 +msgid "Error reading from socket" +msgstr "Se ha producido un error leyendo desde el enchufe (socket)" + +#. Programmer's name for it: SInvalidProviderName +#: Vcl/MidConst.pas:54 +msgid "Provider name \"%s\" was not recognized by the server" +msgstr "" + +#. Programmer's name for it: SBadVariantType +#: Vcl/MidConst.pas:55 +msgid "Unsupported variant type: %s" +msgstr "Tipo de variante no soportado: %s" + +#. Programmer's name for it: SInvalidAction +#: Vcl/MidConst.pas:56 +msgid "Invalid action received: %d" +msgstr "Se ha recibido una acción no válida: %d" + +#. Programmer's name for it: SNoParentConnection +#: Vcl/MidConst.pas:57 +msgid "ParentConnection is not assigned" +msgstr "ParentConnection no está asignada" + +#. Programmer's name for it: SBlankChildName +#: Vcl/MidConst.pas:58 +msgid "ChildName cannot be blank" +msgstr "" + +#. Programmer's name for it: SInvalidResponse +#: Vcl/MidConst.pas:61 +msgid "Invalid response" +msgstr "Respuesta no válida" + +#. Programmer's name for it: STooManyRecordsModified +#: Vcl/MidConst.pas:63 +msgid "Update affected more than 1 record." +msgstr "" + +#. Programmer's name for it: SInvalidOptParamType +#: Vcl/MidConst.pas:66 +msgid "Value cannot be stored in an optional parameter" +msgstr "" + +#. Programmer's name for it: SConstraintFailed +#: Vcl/MidConst.pas:68 +msgid "Record or field constraint failed." +msgstr "" + +#. Programmer's name for it: SField +#: Vcl/MidConst.pas:69 +msgid "Field" +msgstr "" + +#. Programmer's name for it: SReadOnlyProvider +#: Vcl/MidConst.pas:70 +msgid "Cannot apply updates to a ReadOnly provider" +msgstr "" + +#. Programmer's name for it: SNoKeySpecified +#: Vcl/MidConst.pas:71 +msgid "Unable to find record. No key specified" +msgstr "" + +#. Programmer's name for it: SFieldNameTooLong +#: Vcl/MidConst.pas:73 +msgid "" +"Field name cannot be longer then %d characters. Try setting ObjectView to " +"True on the dataset" +msgstr "" + +#. Programmer's name for it: SNoDataSets +#: Vcl/MidConst.pas:74 +msgid "Cannot resolve to dataset when using nested datasets or references" +msgstr "" + +#. Programmer's name for it: SRecConstFail +#: Vcl/MidConst.pas:75 +msgid "Preparation of record constraint failed with error \"%s\"" +msgstr "" + +#. Programmer's name for it: SFieldConstFail +#: Vcl/MidConst.pas:76 +msgid "Preparation of field constraint failed with error \"%s\"" +msgstr "" + +#. Programmer's name for it: SDefExprFail +#: Vcl/MidConst.pas:77 +msgid "Preparation of default expression failed with error \"%s\"" +msgstr "" + +#. Programmer's name for it: SArrayElementError +#: Vcl/MidConst.pas:78 +msgid "Array elements of type %s are not supported" +msgstr "El tipo %s de elementos de matriz no son permitidos" + +#. Programmer's name for it: SNoTableName +#: Vcl/MidConst.pas:79 +msgid "Unable to resolve records. Table name not found." +msgstr "" + +#. Programmer's name for it: SNoEditsAllowed +#: Vcl/MidConst.pas:80 +msgid "Modifications are not allowed" +msgstr "No se permiten las modificaciones" + +#. Programmer's name for it: SNoDeletesAllowed +#: Vcl/MidConst.pas:81 +msgid "Deletes are not allowed" +msgstr "No se permite eliminar" + +#. Programmer's name for it: SNoInsertsAllowed +#: Vcl/MidConst.pas:82 +msgid "Inserts are not allowed" +msgstr "No se permite insertar" + +#. Programmer's name for it: SCannotChangeCommandText +#: Vcl/MidConst.pas:83 +msgid "CommandText changes are not allowed" +msgstr "" + +#. Programmer's name for it: SAggregatesActive +#: Vcl/MidConst.pas:84 +msgid "Operation not allowed with aggregates active" +msgstr "" + +#. Programmer's name for it: SNoServers +#: Vcl/MidConst.pas:87 +msgid "No server available" +msgstr "Servidor no disponible" + +#. Programmer's name for it: SConnectionMissing +#: Vcl/MidConst.pas:91 +msgid "Requires Connection before opening" +msgstr "" + +#. Programmer's name for it: SNoCircularConnection +#: Vcl/MidConst.pas:92 +msgid "Circular reference to Connection not allowed" +msgstr "" + +#. Programmer's name for it: SReturnError +#: Vcl/MidConst.pas:95 +msgid "Expected return value not received" +msgstr "" + +#. Programmer's name for it: SNoWinSock2 +#: Vcl/MidConst.pas:96 Vcl/ScktCnst.pas:36 +msgid "WinSock 2 must be installed to use the socket connection" +msgstr "" + +#. Programmer's name for it: SURLRequired +#: Vcl/MidConst.pas:99 +msgid "URL required" +msgstr "Se requiere URL " + +#. Programmer's name for it: SDefaultURL +#: Vcl/MidConst.pas:100 +msgid "http://server.company.com/scripts/httpsrvr.dll" +msgstr "" + +#. Programmer's name for it: SInvalidURL +#: Vcl/MidConst.pas:101 +msgid "" +"URL must be in the form \"http://server.company.com/scripts/httpsrvr.dll\"" +msgstr "" + +#. Programmer's name for it: SServerIsBusy +#: Vcl/MidConst.pas:102 +msgid "Server is busy" +msgstr "" + +#. Programmer's name for it: SObjectNotAvailable +#: Vcl/MidConst.pas:104 +msgid "Object not available: %s" +msgstr "Objecto no disponible: %s" + +#. Programmer's name for it: SMasterNotOpen +#: Vcl/MidConst.pas:107 +msgid "Cannot open detail table with master closed" +msgstr "No se puede abrir una tabla de detalle estando la maestra cerrada" + +#. Programmer's name for it: SBadPropValue +#: Vcl/OleConst.pas:15 +msgid "'%s' is not a valid property value" +msgstr "'%s' no es un valor de la propiedad válido" + +#. Programmer's name for it: SCannotActivate +#: Vcl/OleConst.pas:16 +msgid "OLE control activation failed" +msgstr "Falló la activación del control OLE" + +#. Programmer's name for it: SNoWindowHandle +#: Vcl/OleConst.pas:17 +msgid "Could not obtain OLE control window handle" +msgstr "No pudo obtenerse el manejador (handle) de ventana del control OLE" + +#. Programmer's name for it: SOleError +#: Vcl/OleConst.pas:18 Rtl/Common/ComConst.pas:15 +msgid "OLE error %.8x" +msgstr "Hay un error OLE %.8x" + +#. Programmer's name for it: SVarNotObject +#: Vcl/OleConst.pas:19 +msgid "Variant does not reference an OLE object" +msgstr "La variable no hace referencia a un objeto OLE" + +#. Programmer's name for it: SVarNotAutoObject +#. Programmer's name for it: SVarNotObject +#: Vcl/OleConst.pas:20 Rtl/Common/ComConst.pas:21 +msgid "Variant does not reference an automation object" +msgstr "La variante no hace referencia a un objeto de automatización" + +#. Programmer's name for it: SNoMethod +#: Vcl/OleConst.pas:21 +msgid "Method '%s' not supported by OLE object" +msgstr "El método '%s' no es soportado por un objeto OLE" + +#. Programmer's name for it: SLinkProperties +#: Vcl/OleConst.pas:22 +msgid "Link Properties" +msgstr "Propiedades del enlace" + +#. Programmer's name for it: SInvalidLinkSource +#: Vcl/OleConst.pas:23 +msgid "Cannot link to an invalid source." +msgstr "No puede enlazarse a una fuente no válida" + +#. Programmer's name for it: SCannotBreakLink +#: Vcl/OleConst.pas:24 +msgid "Break link operation is not supported." +msgstr "La operación de rotura de enlace no es soportada" + +#. Programmer's name for it: SLinkedObject +#: Vcl/OleConst.pas:25 +msgid "Linked %s" +msgstr "Enlazado %s" + +#. Programmer's name for it: SEmptyContainer +#: Vcl/OleConst.pas:26 +msgid "Operation not allowed on an empty OLE container" +msgstr "Operación no permitida en un contenedor OLE vacío" + +#. Programmer's name for it: SInvalidVerb +#: Vcl/OleConst.pas:27 +msgid "Invalid object verb" +msgstr "Verbo de objeto no válido" + +#. Programmer's name for it: SPropDlgCaption +#: Vcl/OleConst.pas:28 +msgid "%s Properties" +msgstr "Propiedades %s" + +#. Programmer's name for it: SInvalidLicense +#: Vcl/OleConst.pas:30 +msgid "License information for %s is invalid" +msgstr "La información de licencia para %s no es válida" + +#. Programmer's name for it: SNotLicensed +#: Vcl/OleConst.pas:31 +msgid "" +"License information for %s not found. You cannot use this control in design " +"mode" +msgstr "" +"Información de licencia para %s no encontrada. No se puede usar este control " +"en modo de diseño" + +#. Programmer's name for it: sNoRunningObject +#: Vcl/OleConst.pas:32 +msgid "" +"Unable to retrieve a pointer to a running object registered with OLE for %s/%" +"s" +msgstr "" +"No se puede recuperar un puntero a un objeto que se está ejecutando, " +"registrado con OLE por %s/%s" + +#. Programmer's name for it: SServiceOnly +#: Vcl/ScktCnst.pas:29 +msgid "The Socket Server can only be run as a service on NT 3.51 and prior" +msgstr "" + +#. Programmer's name for it: SErrClose +#: Vcl/ScktCnst.pas:30 +msgid "Cannot exit when there are active connections. Kill connections?" +msgstr "" + +#. Programmer's name for it: SErrChangeSettings +#: Vcl/ScktCnst.pas:31 +msgid "" +"Cannot change settings when there are active connections. Kill connections?" +msgstr "" +"No se pueden cambiar la configuración cuando estan activas las conexiones. " +"¿Desconectarlas?" + +#. Programmer's name for it: SQueryDisconnect +#: Vcl/ScktCnst.pas:32 +msgid "Disconnecting clients can cause application errors. Continue?" +msgstr "" + +#. Programmer's name for it: SOpenError +#: Vcl/ScktCnst.pas:33 +msgid "Error opening port %d with error: %s" +msgstr "" + +#. Programmer's name for it: SNotShown +#: Vcl/ScktCnst.pas:35 +msgid "(Not Shown)" +msgstr "" + +#. Programmer's name for it: SStatusline +#: Vcl/ScktCnst.pas:37 +msgid "%d current connections" +msgstr "Hay actualmente %d conexiones" + +#. Programmer's name for it: SAlreadyRunning +#: Vcl/ScktCnst.pas:38 +msgid "The Socket Server is already running" +msgstr "El Servidor del enchufe (socket) ya estaba funcionando" + +#. Programmer's name for it: SNotUntilRestart +#: Vcl/ScktCnst.pas:39 +msgid "This change will not take affect until the Socket Server is restarted" +msgstr "" + +#. Programmer's name for it: SMonitorActive +#: Vcl/SqlConst.pas:57 +msgid "Cannot change connection on Active Monitor" +msgstr "No se puede cambiar la conexión al Monitor Activo" + +#. Programmer's name for it: SMissingConnection +#: Vcl/SqlConst.pas:58 +msgid "Missing SQLConnection property" +msgstr "Propiedad SQLConnection sin valor" + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/SqlConst.pas:59 +msgid "Cannot perform this operation on an open connection" +msgstr "No se puede ejecutar esta operación en una conexión abierta" + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/SqlConst.pas:60 +msgid "Cannot perform this operation on a closed connection" +msgstr "No se puede ejecutar esta operación en una conexión cerrada" + +#. Programmer's name for it: SMissingSQLConnection +#: Vcl/SqlConst.pas:61 +msgid "SQLConnection property required for this operation" +msgstr "Se requiere la propiedad SQLConnection para esta operación" + +#. Programmer's name for it: SConnectionNameMissing +#: Vcl/SqlConst.pas:62 +msgid "Connection name missing" +msgstr "Nombre de la conexión ausente" + +#. Programmer's name for it: SNoSqlStatement +#: Vcl/SqlConst.pas:70 +msgid "Missing query, table name or procedure name" +msgstr "Consulta, nombre de la tabla o nombre del procedimiento sin valor" + +#. Programmer's name for it: SMissingDataBaseName +#: Vcl/SqlConst.pas:73 +msgid "Missing Database property" +msgstr "Propiedad Database sin valor" + +#. Programmer's name for it: SMissingDriverName +#: Vcl/SqlConst.pas:75 +msgid "Missing DriverName property" +msgstr "Propiedad DriverName sin valor" + +#. Programmer's name for it: SPrepareError +#: Vcl/SqlConst.pas:76 +msgid "Unable to execute Query" +msgstr "No se puede ejecutar la consulta" + +#. Programmer's name for it: SObjectNameError +#: Vcl/SqlConst.pas:77 +msgid "Table/Procedure not found" +msgstr "No se encontró tabla/procedimiento" + +#. Programmer's name for it: SNoActiveTrans +#: Vcl/SqlConst.pas:79 +msgid "There is no active transaction" +msgstr "No hay ninguna transacción activa" + +#. Programmer's name for it: SActiveTrans +#: Vcl/SqlConst.pas:80 +msgid "A transaction is already active" +msgstr "Una transacción ya estaba activa" + +#. Programmer's name for it: SDllLoadError +#: Vcl/SqlConst.pas:81 +msgid "Unable to Load %s" +msgstr "No se puede cargar %s" + +#. Programmer's name for it: SDllProcLoadError +#: Vcl/SqlConst.pas:82 +msgid "Unable to Find Procedure %s" +msgstr "No se puede encontrar el procedimiento %s" + +#. Programmer's name for it: SConnectionEditor +#: Vcl/SqlConst.pas:83 +msgid "&Edit Connection Properties" +msgstr "Edición de las propiedades de conexión" + +#. Programmer's name for it: SCommandTextEditor +#: Vcl/SqlConst.pas:84 +msgid "&Edit CommandText" +msgstr "&Editar CommandText" + +#. Programmer's name for it: SMissingDLLName +#: Vcl/SqlConst.pas:85 +msgid "DLL/Shared Library Name not Set" +msgstr "DLL/Nombre de Librería Compartida no especificada" + +#. Programmer's name for it: SMissingDriverRegFile +#: Vcl/SqlConst.pas:86 +msgid "Driver/Connection Registry File '%s' not found" +msgstr "" + +#. Programmer's name for it: STableNameNotFound +#: Vcl/SqlConst.pas:87 +msgid "Cannot find TableName in CommandText" +msgstr "No es posible encontrar TableName en CommandText" + +#. Programmer's name for it: SNoCursor +#: Vcl/SqlConst.pas:88 +msgid "Cursor not returned from Query" +msgstr "Cursor no devuelto por la consulta" + +#. Programmer's name for it: SMetaDataOpenError +#: Vcl/SqlConst.pas:89 +msgid "Unable to Open Metadata" +msgstr "No se puede abrir Metadata" + +#. Programmer's name for it: SErrorMappingError +#: Vcl/SqlConst.pas:90 +msgid "SQL Error: Error mapping failed" +msgstr "Error de SQL: Fallo al mapear" + +#. Programmer's name for it: SStoredProcsNotSupported +#: Vcl/SqlConst.pas:91 +msgid "Stored Procedures not supported by '%s' Server" +msgstr "" + +#. Programmer's name for it: SDBXUNKNOWNERROR +#: Vcl/SqlConst.pas:92 +msgid "DBX Error: No Mapping for Error Code Found" +msgstr "Error DBX: Mapeo para el Código de Error no encontrado" + +#. Programmer's name for it: SDBXNOCONNECTION +#. Programmer's name for it: SDBXNOCOMMAND +#. Programmer's name for it: SDBXNOCURSOR +#: Vcl/SqlConst.pas:93 Vcl/SqlConst.pas:95 Vcl/SqlConst.pas:96 +msgid "DBX Error: Connection not found, error message cannot be retrieved" +msgstr "" +"Error DBX: Conexión no encontrada, no es posible recuperar el mensaje de " +"error" + +#. Programmer's name for it: SDBXNOMETAOBJECT +#: Vcl/SqlConst.pas:94 +msgid "DBX Error: MetadataObject not found, error message cannot be retrieved" +msgstr "" +"Error DBX: MetadataObject no encontrado, no es posible recuperar el mensaje " +"de error" + +#. Programmer's name for it: SNOMEMORY +#: Vcl/SqlConst.pas:97 +msgid "DBX Error: Insufficient Memory for Operation" +msgstr "Error dbExpress: Memoria insuficiente para la operación" + +#. Programmer's name for it: SINVALIDFLDTYPE +#: Vcl/SqlConst.pas:98 +msgid "DBX Error: Invalid Field Type" +msgstr "Error dbExpress: Tipo de Campo no válido" + +#. Programmer's name for it: SINVALIDHNDL +#: Vcl/SqlConst.pas:99 +msgid "DBX Error: Invalid Handle" +msgstr "Error dbExpress: Handle no válido" + +#. Programmer's name for it: SINVALIDTIME +#: Vcl/SqlConst.pas:100 +msgid "DBX Error: Invalid Time" +msgstr "Error dbExpress: Hora no válida" + +#. Programmer's name for it: SNOTSUPPORTED +#: Vcl/SqlConst.pas:101 +msgid "DBX Error: Operation Not Supported" +msgstr "Error DBX: Operación no soportada" + +#. Programmer's name for it: SINVALIDXLATION +#: Vcl/SqlConst.pas:102 +msgid "DBX Error: Invalid Translation" +msgstr "Error dbExpress: Datos de traducción no válidos" + +#. Programmer's name for it: SINVALIDPARAM +#: Vcl/SqlConst.pas:103 +msgid "DBX Error: Invalid Parameter" +msgstr "Error dbExpress: Parámetro no válido" + +#. Programmer's name for it: SOUTOFRANGE +#: Vcl/SqlConst.pas:104 +msgid "DBX Error: Argument out of Range" +msgstr "Error dbExpress: Argumento fuera de rango" + +#. Programmer's name for it: SSQLPARAMNOTSET +#: Vcl/SqlConst.pas:105 +msgid "DBX Error: Parameter Not Set" +msgstr "Error dbExpress: Parámetro sin asignar" + +#. Programmer's name for it: SEOF +#: Vcl/SqlConst.pas:106 +msgid "DBX Error: Result set at EOF" +msgstr "Error dbExpress: Resultado asignado a EOF" + +#. Programmer's name for it: SINVALIDUSRPASS +#: Vcl/SqlConst.pas:107 +msgid "DBX Error: Invalid Username/Password" +msgstr "Error dbExpress: Nombre de usuario/Contraseña no válida" + +#. Programmer's name for it: SINVALIDPRECISION +#: Vcl/SqlConst.pas:108 +msgid "DBX Error: Invalid Precision" +msgstr "Error dbExpress: Precisión no válida" + +#. Programmer's name for it: SINVALIDLEN +#: Vcl/SqlConst.pas:109 +msgid "DBX Error: Invalid Length" +msgstr "Error dbExpress: Longitud no válida" + +#. Programmer's name for it: SINVALIDXISOLEVEL +#: Vcl/SqlConst.pas:110 +msgid "DBX Error: Invalid Transaction Isolation Level" +msgstr "Error dbExpress: Nivel de Aislamiento de Transacción no válido" + +#. Programmer's name for it: SINVALIDTXNID +#: Vcl/SqlConst.pas:111 +msgid "DBX Error: Invalid Transaction ID" +msgstr "Error dbExpress: Identificador de Transacción no válido" + +#. Programmer's name for it: SDUPLICATETXNID +#: Vcl/SqlConst.pas:112 +msgid "DBX Error: Duplicate Transaction ID" +msgstr "Error dbExpress: Identificador de Transacción duplicado" + +#. Programmer's name for it: SDRIVERRESTRICTED +#: Vcl/SqlConst.pas:113 +msgid "dbExpress: Application is not licensed to use this feature" +msgstr "" +"Error dbExpress: La Aplicación no tiene licencia para utilizar esta " +"característica" + +#. Programmer's name for it: SLOCALTRANSACTIVE +#: Vcl/SqlConst.pas:114 +msgid "DBX Error: Local Transaction already active" +msgstr "Error dbExpress: Ya hay activa una Transacción Local" + +#. Programmer's name for it: SMultiConnNotSupported +#: Vcl/SqlConst.pas:115 +msgid "Multiple Connections not supported by %s driver" +msgstr "Conexiones múltiples no soportadas por el driver %s" + +#. Programmer's name for it: SConfFileMoveError +#: Vcl/SqlConst.pas:116 +msgid "Unable to move %s to %s" +msgstr "No se puede mover %s a %s" + +#. Programmer's name for it: SMissingConfFile +#: Vcl/SqlConst.pas:117 +msgid "Configuration file %s not found" +msgstr "Configuración de archivo %s no encontrada" + +#. Programmer's name for it: SObjectViewNotTrue +#: Vcl/SqlConst.pas:118 +msgid "ObjectView must be True for Table with Object fields" +msgstr "ObjectView debe ser True para una Tabla con campos Object" + +#. Programmer's name for it: SDriverNotInConfigFile +#: Vcl/SqlConst.pas:119 +msgid "Driver (%s) not found in Cfg file (%s)" +msgstr "Driver (%s) no encontrado en archivo Cfg (%s)" + +#. Programmer's name for it: SObjectTypenameRequired +#: Vcl/SqlConst.pas:120 +msgid "Object type name required as parameter value" +msgstr "Nombre de tipo de Objeto requerido como valor de parámetro" + +#. used in SqlReg.pas +#: Vcl/SqlConst.pas:123 +msgid "Text files (*.txt)|*.txt|All files (*.*)|*.*" +msgstr "Archivos de texto (*.txt)|*.txt|Todos los archivos (*.*)|*.*" + +#. Programmer's name for it: SLogFileFilter +#: Vcl/SqlConst.pas:124 +msgid "Log files (*.log)" +msgstr "Archivos de diario (*.log)" + +#. Programmer's name for it: SDataBindings +#: Vcl/VDBConsts.pas:41 +msgid "Data Bindings..." +msgstr "Enlazador de datos..." + +#. Programmer's name for it: SCreateRegKeyError +#: Rtl/Common/ComConst.pas:14 +msgid "Error creating system registry entry" +msgstr "Se ha producido un error al crear la entrada del registro del sistema" + +#. Programmer's name for it: SObjectFactoryMissing +#: Rtl/Common/ComConst.pas:16 +msgid "Object factory for class %s missing" +msgstr "" + +#. Programmer's name for it: STypeInfoMissing +#: Rtl/Common/ComConst.pas:17 +msgid "Type information missing for class %s" +msgstr "" + +#. Programmer's name for it: SBadTypeInfo +#: Rtl/Common/ComConst.pas:18 +msgid "Incorrect type information for class %s" +msgstr "" + +#. Programmer's name for it: SDispIntfMissing +#: Rtl/Common/ComConst.pas:19 +msgid "Dispatch interface missing from class %s" +msgstr "" + +#. Programmer's name for it: SNoMethod +#: Rtl/Common/ComConst.pas:20 +msgid "Method '%s' not supported by automation object" +msgstr "" + +#. Programmer's name for it: STooManyParams +#: Rtl/Common/ComConst.pas:22 +msgid "Dispatch methods do not support more than 64 parameters" +msgstr "" + +#. Programmer's name for it: SDCOMNotInstalled +#: Rtl/Common/ComConst.pas:23 +msgid "DCOM not installed" +msgstr "No está instalado DCOM " + +#. Programmer's name for it: SDAXError +#: Rtl/Common/ComConst.pas:24 +msgid "DAX Error" +msgstr "Error DAX" + +#. Programmer's name for it: SAutomationWarning +#: Rtl/Common/ComConst.pas:26 +msgid "COM Server Warning" +msgstr "" + +#. Programmer's name for it: SNoCloseActiveServer1 +#: Rtl/Common/ComConst.pas:29 +msgid "" +"There are still active COM objects in this application. One or more clients " +"may have references to these objects, so manually closing " +msgstr "" + +#. Programmer's name for it: SNoCloseActiveServer2 +#: Rtl/Common/ComConst.pas:32 +msgid "" +"this application may cause those client application(s) to fail.\n" +"\n" +"Are you sure you want to close this application?" +msgstr "" + +#. Programmer's name for it: hNoTableOfContents +#: Rtl/Common/HelpIntfs.pas:252 +msgid "Unable to find a Table Of Contents" +msgstr "No se puede encontrar la tabla de contenidos" + +#. Programmer's name for it: hNothingFound +#: Rtl/Common/HelpIntfs.pas:253 +msgid "No help found for %s" +msgstr "" + +#. Programmer's name for it: hNoContext +#: Rtl/Common/HelpIntfs.pas:254 +msgid "No context-sensitive help installed" +msgstr "" + +#. Programmer's name for it: hNoTopics +#: Rtl/Common/HelpIntfs.pas:255 +msgid "No topic-based help system installed" +msgstr "" + +#. Programmer's name for it: SBucketListLocked +#: Rtl/Common/RTLConsts.pas:17 +msgid "List is locked during an active ForEach" +msgstr "La lista está bloqueada durante un ForEach activo" + +#. Programmer's name for it: SCheckSynchronizeError +#: Rtl/Common/RTLConsts.pas:20 +msgid "CheckSynchronize called from thread $%x, which is NOT the main thread" +msgstr "" +"Llamada de CheckSynchronize desde el hilo (thread) $%x, que no es el hilo " +"principal" + +#. Programmer's name for it: SDelimiterQuoteCharError +#: Rtl/Common/RTLConsts.pas:22 +msgid "Delimiter and QuoteChar properties cannot have the same value" +msgstr "Las propiedades Delimiter y QuoteChar no pueden tener el mismo valor" + +#. Programmer's name for it: SItemNotFound +#: Rtl/Common/RTLConsts.pas:56 +msgid "Item not found ($0%x)" +msgstr "No se ha encontrado el elemento ($0%x) " + +#. Programmer's name for it: SNoComSupport +#: Rtl/Common/RTLConsts.pas:64 +msgid "%s has not been registered as a COM class" +msgstr "%s no es una clase COM registrada" + +#. Programmer's name for it: SComponentNameTooLong +#: Rtl/Common/RTLConsts.pas:68 +msgid "Component name '%s' exceeds 64 character limit" +msgstr "El nombre del componente '%s' excede el límite de los 64 caracteres" + +#. Programmer's name for it: SRegCreateFailed +#: Rtl/Common/RTLConsts.pas:73 +msgid "Failed to create key %s" +msgstr "Se ha producido un error al crear la llave %s" + +#. Programmer's name for it: SRegGetDataFailed +#: Rtl/Common/RTLConsts.pas:74 +msgid "Failed to get data for '%s'" +msgstr "Se ha producido un error al obtener el dato para '%s'" + +#. Programmer's name for it: SRegSetDataFailed +#: Rtl/Common/RTLConsts.pas:76 +msgid "Failed to set data for '%s'" +msgstr "Se ha producido un error al asignar el dato para '%s'" + +#. Programmer's name for it: SSeekNotImplemented +#: Rtl/Common/RTLConsts.pas:78 +msgid "%s.Seek not implemented" +msgstr "%s.Seek no implementado" + +#. Programmer's name for it: SSortedListError +#: Rtl/Common/RTLConsts.pas:79 +msgid "Operation not allowed on sorted list" +msgstr "Operación no permitida en una lista ordenada" + +#. Programmer's name for it: SUnknownGroup +#: Rtl/Common/RTLConsts.pas:84 +msgid "%s not in a class registration group" +msgstr "%s no en un grupo de registro de clase" + +#. Programmer's name for it: SUnknownProperty +#: Rtl/Common/RTLConsts.pas:85 +msgid "Property %s does not exist" +msgstr "La propiedad %s no existe" + +#. Programmer's name for it: SStreamSetSize +#: Rtl/Common/RTLConsts.pas:87 +msgid "Stream.SetSize failure" +msgstr "Se ha producido un error al asignar el tamaño del flujo (stream)" + +#. Programmer's name for it: SThreadCreateError +#: Rtl/Common/RTLConsts.pas:88 +msgid "Thread creation error: %s" +msgstr "Hay un error de creación de hilo (thread): %s" + +#. Programmer's name for it: SThreadError +#: Rtl/Common/RTLConsts.pas:89 +msgid "Thread Error: %s (%d)" +msgstr "Hay un error de hilo (thread): %s (%d)" + +#. Programmer's name for it: SInvalidDateDay +#: Rtl/Common/RTLConsts.pas:91 +msgid "(%d, %d) is not a valid DateDay pair" +msgstr "(%d, %d) no es una pareja DateDay válida " + +#. Programmer's name for it: SInvalidDateWeek +#: Rtl/Common/RTLConsts.pas:92 +msgid "(%d, %d, %d) is not a valid DateWeek triplet" +msgstr "(%d, %d, %d) no es un triplete de DateWeek válido" + +#. Programmer's name for it: SInvalidDateMonthWeek +#: Rtl/Common/RTLConsts.pas:93 +msgid "(%d, %d, %d, %d) is not a valid DateMonthWeek quad" +msgstr "(%d, %d, %d, %d) no es un cuarteto de DateMonthWeek válido" + +#. Programmer's name for it: SInvalidDayOfWeekInMonth +#: Rtl/Common/RTLConsts.pas:94 +msgid "(%d, %d, %d, %d) is not a valid DayOfWeekInMonth quad" +msgstr "(%d, %d, %d, %d) no es un cuarteto de DayOfWeekInMonth válido" + +#. Programmer's name for it: SInvalidJulianDate +#: Rtl/Common/RTLConsts.pas:95 +msgid "%f Julian cannot be represented as a DateTime" +msgstr "La fecha juliana %f no puede representarse como un DateTime" + +#. Programmer's name for it: SMissingDateTimeField +#: Rtl/Common/RTLConsts.pas:96 +msgid "?" +msgstr "" + +#. Programmer's name for it: SConvIncompatibleTypes2 +#: Rtl/Common/RTLConsts.pas:98 Rtl/Sys/SysConst.pas:107 +msgid "Incompatible conversion types [%s, %s]" +msgstr "Conversión de tipos [%s, %s] incompatible" + +#. Programmer's name for it: SConvIncompatibleTypes3 +#: Rtl/Common/RTLConsts.pas:99 Rtl/Sys/SysConst.pas:108 +msgid "Incompatible conversion types [%s, %s, %s]" +msgstr "Conversión de tipos [%s, %s, %s] incompatible" + +#. Programmer's name for it: SConvIncompatibleTypes4 +#: Rtl/Common/RTLConsts.pas:100 Rtl/Sys/SysConst.pas:109 +msgid "Incompatible conversion types [%s - %s, %s - %s]" +msgstr "Conversión de tipos [%s - %s, %s - %s] incompatible" + +#. Programmer's name for it: SConvUnknownType +#: Rtl/Common/RTLConsts.pas:101 Rtl/Sys/SysConst.pas:110 +msgid "Unknown conversion type %s" +msgstr "Conversión del tipo %s desconocida" + +#. Programmer's name for it: SConvDuplicateType +#: Rtl/Common/RTLConsts.pas:102 +msgid "Conversion type (%s) already registered in %s" +msgstr "La conversión del tipo (%s) ya estaba registrada en %s" + +#. Programmer's name for it: SConvUnknownFamily +#: Rtl/Common/RTLConsts.pas:103 Rtl/Sys/SysConst.pas:112 +msgid "Unknown conversion family %s" +msgstr "Familia de conversión (%s) desconocida" + +#. Programmer's name for it: SConvDuplicateFamily +#: Rtl/Common/RTLConsts.pas:104 Rtl/Sys/SysConst.pas:113 +msgid "Conversion family (%s) already registered" +msgstr "La familia de conversión (%s) ya está registrada" + +#. Programmer's name for it: SConvUnknownDescription +#: Rtl/Common/RTLConsts.pas:105 Rtl/Sys/SysConst.pas:114 +msgid "[%.8x]" +msgstr "" + +#. Programmer's name for it: SConvIllegalType +#: Rtl/Common/RTLConsts.pas:106 Rtl/Sys/SysConst.pas:115 +msgid "Illegal type" +msgstr "Tipo ilegal" + +#. Programmer's name for it: SConvIllegalFamily +#: Rtl/Common/RTLConsts.pas:107 Rtl/Sys/SysConst.pas:116 +msgid "Illegal family" +msgstr "Familia ilegal" + +#. Programmer's name for it: SConvFactorZero +#: Rtl/Common/RTLConsts.pas:108 Rtl/Sys/SysConst.pas:117 +msgid "%s has a factor of zero" +msgstr "%s tiene un factor de cero" + +#. Programmer's name for it: SConvStrParseError +#: Rtl/Common/RTLConsts.pas:109 +msgid "Could not parse %s" +msgstr "No se pudo analizar %s" + +#. Programmer's name for it: SFailedToCallConstructor +#: Rtl/Common/RTLConsts.pas:110 +msgid "TStrings descendant %s failed to call inherited constructor" +msgstr "" +"El descendiente de TStrings %s falló en la llamada al constructor heredado" + +#. Programmer's name for it: sWindowsSocketError +#: Rtl/Common/RTLConsts.pas:112 +msgid "Windows socket error: %s (%d), on API '%s'" +msgstr "Hay un error en el socket de Windows: %s (%d), en API '%s'" + +#. Programmer's name for it: SDistanceDescription +#: Rtl/Common/StdConvs.pas:300 +msgid "Distance" +msgstr "Distancia" + +#. Programmer's name for it: SMicromicronsDescription +#: Rtl/Common/StdConvs.pas:303 +msgid "Micromicrons" +msgstr "Micromicrones" + +#. Programmer's name for it: SAngstromsDescription +#: Rtl/Common/StdConvs.pas:304 +msgid "Angstroms" +msgstr "Amstrongs" + +#. Programmer's name for it: SMillimicronsDescription +#: Rtl/Common/StdConvs.pas:305 +msgid "Millimicrons" +msgstr "Milimicrones" + +#. Programmer's name for it: SMicronsDescription +#: Rtl/Common/StdConvs.pas:306 +msgid "Microns" +msgstr "Micrones" + +#. Programmer's name for it: SMillimetersDescription +#: Rtl/Common/StdConvs.pas:307 +msgid "Millimeters" +msgstr "Milímetros" + +#. Programmer's name for it: SCentimetersDescription +#: Rtl/Common/StdConvs.pas:308 +msgid "Centimeters" +msgstr "Centímetros" + +#. Programmer's name for it: SDecimetersDescription +#: Rtl/Common/StdConvs.pas:309 +msgid "Decimeters" +msgstr "Decímetros" + +#. Programmer's name for it: SMetersDescription +#: Rtl/Common/StdConvs.pas:310 +msgid "Meters" +msgstr "Metros" + +#. Programmer's name for it: SDecametersDescription +#: Rtl/Common/StdConvs.pas:311 +msgid "Decameters" +msgstr "Decámetros" + +#. Programmer's name for it: SHectometersDescription +#: Rtl/Common/StdConvs.pas:312 +msgid "Hectometers" +msgstr "Hectómetros" + +#. Programmer's name for it: SKilometersDescription +#: Rtl/Common/StdConvs.pas:313 +msgid "Kilometers" +msgstr "Kilómetros" + +#. Programmer's name for it: SMegametersDescription +#: Rtl/Common/StdConvs.pas:314 +msgid "Megameters" +msgstr "Megámetros" + +#. Programmer's name for it: SGigametersDescription +#: Rtl/Common/StdConvs.pas:315 +msgid "Gigameters" +msgstr "Gigámetros" + +#. Programmer's name for it: SInchesDescription +#: Rtl/Common/StdConvs.pas:316 +msgid "Inches" +msgstr "Pulgadas" + +#. Programmer's name for it: SFeetDescription +#: Rtl/Common/StdConvs.pas:317 +msgid "Feet" +msgstr "Pies" + +#. Programmer's name for it: SYardsDescription +#: Rtl/Common/StdConvs.pas:318 +msgid "Yards" +msgstr "Yardas" + +#. Programmer's name for it: SMilesDescription +#: Rtl/Common/StdConvs.pas:319 +msgid "Miles" +msgstr "Millas" + +#. Programmer's name for it: SNauticalMilesDescription +#: Rtl/Common/StdConvs.pas:320 +msgid "NauticalMiles" +msgstr "Millas náuticas" + +#. Programmer's name for it: SAstronomicalUnitsDescription +#: Rtl/Common/StdConvs.pas:321 +msgid "AstronomicalUnits" +msgstr "Unidades Astronómicas" + +#. Programmer's name for it: SLightYearsDescription +#: Rtl/Common/StdConvs.pas:322 +msgid "LightYears" +msgstr "Años Luz" + +#. Programmer's name for it: SParsecsDescription +#: Rtl/Common/StdConvs.pas:323 +msgid "Parsecs" +msgstr "Parsecs" + +#. Programmer's name for it: SCubitsDescription +#: Rtl/Common/StdConvs.pas:324 +msgid "Cubits" +msgstr "Codos" + +#. Programmer's name for it: SFathomsDescription +#: Rtl/Common/StdConvs.pas:325 +msgid "Fathoms" +msgstr "Brazas" + +#. Programmer's name for it: SFurlongsDescription +#: Rtl/Common/StdConvs.pas:326 +msgid "Furlongs" +msgstr "Furlongs" + +#. Programmer's name for it: SHandsDescription +#: Rtl/Common/StdConvs.pas:327 +msgid "Hands" +msgstr "Palmas" + +#. Programmer's name for it: SPacesDescription +#: Rtl/Common/StdConvs.pas:328 +msgid "Paces" +msgstr "Pasos" + +#. Programmer's name for it: SRodsDescription +#: Rtl/Common/StdConvs.pas:329 +msgid "Rods" +msgstr "" + +#. Programmer's name for it: SChainsDescription +#: Rtl/Common/StdConvs.pas:330 +msgid "Chains" +msgstr "" + +#. Programmer's name for it: SLinksDescription +#: Rtl/Common/StdConvs.pas:331 +msgid "Links" +msgstr "" + +#. Programmer's name for it: SPicasDescription +#: Rtl/Common/StdConvs.pas:332 +msgid "Picas" +msgstr "Picas" + +#. Programmer's name for it: SPointsDescription +#: Rtl/Common/StdConvs.pas:333 +msgid "Points" +msgstr "Puntos" + +#. Programmer's name for it: SAreaDescription +#: Rtl/Common/StdConvs.pas:337 +msgid "Area" +msgstr "Área" + +#. Programmer's name for it: SSquareMillimetersDescription +#: Rtl/Common/StdConvs.pas:340 +msgid "SquareMillimeters" +msgstr "Millímetros cuadrados" + +#. Programmer's name for it: SSquareCentimetersDescription +#: Rtl/Common/StdConvs.pas:341 +msgid "SquareCentimeters" +msgstr "Centímetros cuadrados" + +#. Programmer's name for it: SSquareDecimetersDescription +#: Rtl/Common/StdConvs.pas:342 +msgid "SquareDecimeters" +msgstr "Decímetros cuadrados" + +#. Programmer's name for it: SSquareMetersDescription +#: Rtl/Common/StdConvs.pas:343 +msgid "SquareMeters" +msgstr "Metros cuadrados" + +#. Programmer's name for it: SSquareDecametersDescription +#: Rtl/Common/StdConvs.pas:344 +msgid "SquareDecameters" +msgstr "Decámetros cuadrados" + +#. Programmer's name for it: SSquareHectometersDescription +#: Rtl/Common/StdConvs.pas:345 +msgid "SquareHectometers" +msgstr "Hectómetros cuadrados" + +#. Programmer's name for it: SSquareKilometersDescription +#: Rtl/Common/StdConvs.pas:346 +msgid "SquareKilometers" +msgstr "Kilómetros cuadrados" + +#. Programmer's name for it: SSquareInchesDescription +#: Rtl/Common/StdConvs.pas:347 +msgid "SquareInches" +msgstr "Pulgadas cuadradas" + +#. Programmer's name for it: SSquareFeetDescription +#: Rtl/Common/StdConvs.pas:348 +msgid "SquareFeet" +msgstr "Pies cuadrados" + +#. Programmer's name for it: SSquareYardsDescription +#: Rtl/Common/StdConvs.pas:349 +msgid "SquareYards" +msgstr "Yardas cuadradas" + +#. Programmer's name for it: SSquareMilesDescription +#: Rtl/Common/StdConvs.pas:350 +msgid "SquareMiles" +msgstr "Millas cuadradas" + +#. Programmer's name for it: SAcresDescription +#: Rtl/Common/StdConvs.pas:351 +msgid "Acres" +msgstr "Ácres" + +#. Programmer's name for it: SCentaresDescription +#: Rtl/Common/StdConvs.pas:352 +msgid "Centares" +msgstr "Centares" + +#. Programmer's name for it: SAresDescription +#: Rtl/Common/StdConvs.pas:353 +msgid "Ares" +msgstr "Ares" + +#. Programmer's name for it: SHectaresDescription +#: Rtl/Common/StdConvs.pas:354 +msgid "Hectares" +msgstr "Hectáreas" + +#. Programmer's name for it: SSquareRodsDescription +#: Rtl/Common/StdConvs.pas:355 +msgid "SquareRods" +msgstr "" + +#. Programmer's name for it: SVolumeDescription +#: Rtl/Common/StdConvs.pas:359 +msgid "Volume" +msgstr "Volumen" + +#. Programmer's name for it: SCubicMillimetersDescription +#: Rtl/Common/StdConvs.pas:362 +msgid "CubicMillimeters" +msgstr "Milímetros cúbicos" + +#. Programmer's name for it: SCubicCentimetersDescription +#: Rtl/Common/StdConvs.pas:363 +msgid "CubicCentimeters" +msgstr "Centímetros cúbicos" + +#. Programmer's name for it: SCubicDecimetersDescription +#: Rtl/Common/StdConvs.pas:364 +msgid "CubicDecimeters" +msgstr "Decímetros cúbicos" + +#. Programmer's name for it: SCubicMetersDescription +#: Rtl/Common/StdConvs.pas:365 +msgid "CubicMeters" +msgstr "Metros cúbicos" + +#. Programmer's name for it: SCubicDecametersDescription +#: Rtl/Common/StdConvs.pas:366 +msgid "CubicDecameters" +msgstr "Decámetros cúbicos" + +#. Programmer's name for it: SCubicHectometersDescription +#: Rtl/Common/StdConvs.pas:367 +msgid "CubicHectometers" +msgstr "Hectómetros cúbicos" + +#. Programmer's name for it: SCubicKilometersDescription +#: Rtl/Common/StdConvs.pas:368 +msgid "CubicKilometers" +msgstr "Kilómetros cúbicos" + +#. Programmer's name for it: SCubicInchesDescription +#: Rtl/Common/StdConvs.pas:369 +msgid "CubicInches" +msgstr "Pulgadas cúbicas" + +#. Programmer's name for it: SCubicFeetDescription +#: Rtl/Common/StdConvs.pas:370 +msgid "CubicFeet" +msgstr "Pies cúbicos" + +#. Programmer's name for it: SCubicYardsDescription +#: Rtl/Common/StdConvs.pas:371 +msgid "CubicYards" +msgstr "Yardas cúbicas" + +#. Programmer's name for it: SCubicMilesDescription +#: Rtl/Common/StdConvs.pas:372 +msgid "CubicMiles" +msgstr "Millas cúbicas" + +#. Programmer's name for it: SMilliLitersDescription +#: Rtl/Common/StdConvs.pas:373 +msgid "MilliLiters" +msgstr "Mililitros" + +#. Programmer's name for it: SCentiLitersDescription +#: Rtl/Common/StdConvs.pas:374 +msgid "CentiLiters" +msgstr "Centilitros" + +#. Programmer's name for it: SDeciLitersDescription +#: Rtl/Common/StdConvs.pas:375 +msgid "DeciLiters" +msgstr "Decilitros" + +#. Programmer's name for it: SLitersDescription +#: Rtl/Common/StdConvs.pas:376 +msgid "Liters" +msgstr "Litros" + +#. Programmer's name for it: SDecaLitersDescription +#: Rtl/Common/StdConvs.pas:377 +msgid "DecaLiters" +msgstr "Decalitros" + +#. Programmer's name for it: SHectoLitersDescription +#: Rtl/Common/StdConvs.pas:378 +msgid "HectoLiters" +msgstr "Hectolitros" + +#. Programmer's name for it: SKiloLitersDescription +#: Rtl/Common/StdConvs.pas:379 +msgid "KiloLiters" +msgstr "Kilolitros" + +#. Programmer's name for it: SAcreFeetDescription +#: Rtl/Common/StdConvs.pas:380 +msgid "AcreFeet" +msgstr "" + +#. Programmer's name for it: SAcreInchesDescription +#: Rtl/Common/StdConvs.pas:381 +msgid "AcreInches" +msgstr "" + +#. Programmer's name for it: SCordsDescription +#: Rtl/Common/StdConvs.pas:382 +msgid "Cords" +msgstr "" + +#. Programmer's name for it: SCordFeetDescription +#: Rtl/Common/StdConvs.pas:383 +msgid "CordFeet" +msgstr "" + +#. Programmer's name for it: SDecisteresDescription +#: Rtl/Common/StdConvs.pas:384 +msgid "Decisteres" +msgstr "" + +#. Programmer's name for it: SSteresDescription +#: Rtl/Common/StdConvs.pas:385 +msgid "Steres" +msgstr "" + +#. Programmer's name for it: SDecasteresDescription +#: Rtl/Common/StdConvs.pas:386 +msgid "Decasteres" +msgstr "" + +#. Programmer's name for it: SFluidGallonsDescription +#: Rtl/Common/StdConvs.pas:389 +msgid "FluidGallons" +msgstr "" + +#. Programmer's name for it: SFluidQuartsDescription +#: Rtl/Common/StdConvs.pas:390 +msgid "FluidQuarts" +msgstr "" + +#. Programmer's name for it: SFluidPintsDescription +#: Rtl/Common/StdConvs.pas:391 +msgid "FluidPints" +msgstr "" + +#. Programmer's name for it: SFluidCupsDescription +#: Rtl/Common/StdConvs.pas:392 +msgid "FluidCups" +msgstr "" + +#. Programmer's name for it: SFluidGillsDescription +#: Rtl/Common/StdConvs.pas:393 +msgid "FluidGills" +msgstr "" + +#. Programmer's name for it: SFluidOuncesDescription +#: Rtl/Common/StdConvs.pas:394 +msgid "FluidOunces" +msgstr "" + +#. Programmer's name for it: SFluidTablespoonsDescription +#: Rtl/Common/StdConvs.pas:395 +msgid "FluidTablespoons" +msgstr "" + +#. Programmer's name for it: SFluidTeaspoonsDescription +#: Rtl/Common/StdConvs.pas:396 +msgid "FluidTeaspoons" +msgstr "" + +#. Programmer's name for it: SDryGallonsDescription +#: Rtl/Common/StdConvs.pas:399 +msgid "DryGallons" +msgstr "" + +#. Programmer's name for it: SDryQuartsDescription +#: Rtl/Common/StdConvs.pas:400 +msgid "DryQuarts" +msgstr "" + +#. Programmer's name for it: SDryPintsDescription +#: Rtl/Common/StdConvs.pas:401 +msgid "DryPints" +msgstr "" + +#. Programmer's name for it: SDryPecksDescription +#: Rtl/Common/StdConvs.pas:402 +msgid "DryPecks" +msgstr "" + +#. Programmer's name for it: SDryBucketsDescription +#: Rtl/Common/StdConvs.pas:403 +msgid "DryBuckets" +msgstr "" + +#. Programmer's name for it: SDryBushelsDescription +#: Rtl/Common/StdConvs.pas:404 +msgid "DryBushels" +msgstr "" + +#. Programmer's name for it: SUKGallonsDescription +#: Rtl/Common/StdConvs.pas:407 +msgid "UKGallons" +msgstr "" + +#. Programmer's name for it: SUKPottlesDescription +#: Rtl/Common/StdConvs.pas:408 +msgid "UKPottle" +msgstr "" + +#. Programmer's name for it: SUKQuartsDescription +#: Rtl/Common/StdConvs.pas:409 +msgid "UKQuarts" +msgstr "" + +#. Programmer's name for it: SUKPintsDescription +#: Rtl/Common/StdConvs.pas:410 +msgid "UKPints" +msgstr "" + +#. Programmer's name for it: SUKGillsDescription +#: Rtl/Common/StdConvs.pas:411 +msgid "UKGill" +msgstr "" + +#. Programmer's name for it: SUKOuncesDescription +#: Rtl/Common/StdConvs.pas:412 +msgid "UKOunces" +msgstr "" + +#. Programmer's name for it: SUKPecksDescription +#: Rtl/Common/StdConvs.pas:413 +msgid "UKPecks" +msgstr "" + +#. Programmer's name for it: SUKBucketsDescription +#: Rtl/Common/StdConvs.pas:414 +msgid "UKBuckets" +msgstr "" + +#. Programmer's name for it: SUKBushelsDescription +#: Rtl/Common/StdConvs.pas:415 +msgid "UKBushels" +msgstr "" + +#. Programmer's name for it: SMassDescription +#: Rtl/Common/StdConvs.pas:419 +msgid "Mass" +msgstr "Masa" + +#. Programmer's name for it: SNanogramsDescription +#: Rtl/Common/StdConvs.pas:422 +msgid "Nanograms" +msgstr "Nanogramos" + +#. Programmer's name for it: SMicrogramsDescription +#: Rtl/Common/StdConvs.pas:423 +msgid "Micrograms" +msgstr "Microgramos" + +#. Programmer's name for it: SMilligramsDescription +#: Rtl/Common/StdConvs.pas:424 +msgid "Milligrams" +msgstr "Miligramos" + +#. Programmer's name for it: SCentigramsDescription +#: Rtl/Common/StdConvs.pas:425 +msgid "Centigrams" +msgstr "Centigramos" + +#. Programmer's name for it: SDecigramsDescription +#: Rtl/Common/StdConvs.pas:426 +msgid "Decigrams" +msgstr "Decigramos" + +#. Programmer's name for it: SGramsDescription +#: Rtl/Common/StdConvs.pas:427 +msgid "Grams" +msgstr "Gramos" + +#. Programmer's name for it: SDecagramsDescription +#: Rtl/Common/StdConvs.pas:428 +msgid "Decagrams" +msgstr "Decagramos" + +#. Programmer's name for it: SHectogramsDescription +#: Rtl/Common/StdConvs.pas:429 +msgid "Hectograms" +msgstr "Hectogramos" + +#. Programmer's name for it: SKilogramsDescription +#: Rtl/Common/StdConvs.pas:430 +msgid "Kilograms" +msgstr "Kilogramos" + +#. Programmer's name for it: SMetricTonsDescription +#: Rtl/Common/StdConvs.pas:431 +msgid "MetricTons" +msgstr "Toneladas métricas" + +#. Programmer's name for it: SDramsDescription +#: Rtl/Common/StdConvs.pas:432 +msgid "Drams" +msgstr "" + +#. Programmer's name for it: SGrainsDescription +#: Rtl/Common/StdConvs.pas:433 +msgid "Grains" +msgstr "" + +#. Programmer's name for it: STonsDescription +#: Rtl/Common/StdConvs.pas:434 +msgid "Tons" +msgstr "Toneladas" + +#. Programmer's name for it: SLongTonsDescription +#: Rtl/Common/StdConvs.pas:435 +msgid "LongTons" +msgstr "" + +#. Programmer's name for it: SOuncesDescription +#: Rtl/Common/StdConvs.pas:436 +msgid "Ounces" +msgstr "" + +#. Programmer's name for it: SPoundsDescription +#: Rtl/Common/StdConvs.pas:437 +msgid "Pounds" +msgstr "" + +#. Programmer's name for it: STemperatureDescription +#: Rtl/Common/StdConvs.pas:441 +msgid "Temperature" +msgstr "Temperatura" + +#. Programmer's name for it: SCelsiusDescription +#: Rtl/Common/StdConvs.pas:444 +msgid "Celsius" +msgstr "Celsius" + +#. Programmer's name for it: SKelvinDescription +#: Rtl/Common/StdConvs.pas:445 +msgid "Kelvin" +msgstr "Kelvin" + +#. Programmer's name for it: SFahrenheitDescription +#: Rtl/Common/StdConvs.pas:446 +msgid "Fahrenheit" +msgstr "Fahrenheit" + +#. Programmer's name for it: SRankineDescription +#: Rtl/Common/StdConvs.pas:447 +msgid "Rankine" +msgstr "Rankine" + +#. Programmer's name for it: SReaumurDescription +#: Rtl/Common/StdConvs.pas:448 +msgid "Reaumur" +msgstr "Reaumur" + +#. Programmer's name for it: SMilliSecondsDescription +#: Rtl/Common/StdConvs.pas:455 +msgid "MilliSeconds" +msgstr "Milisegundos" + +#. Programmer's name for it: SSecondsDescription +#: Rtl/Common/StdConvs.pas:456 +msgid "Seconds" +msgstr "Segundos" + +#. Programmer's name for it: SMinutesDescription +#: Rtl/Common/StdConvs.pas:457 +msgid "Minutes" +msgstr "Minutos" + +#. Programmer's name for it: SHoursDescription +#: Rtl/Common/StdConvs.pas:458 +msgid "Hours" +msgstr "Horas" + +#. Programmer's name for it: SDaysDescription +#: Rtl/Common/StdConvs.pas:459 +msgid "Days" +msgstr "Días" + +#. Programmer's name for it: SWeeksDescription +#: Rtl/Common/StdConvs.pas:460 +msgid "Weeks" +msgstr "Semanas" + +#. Programmer's name for it: SFortnightsDescription +#: Rtl/Common/StdConvs.pas:461 +msgid "Fortnights" +msgstr "" + +#. Programmer's name for it: SMonthsDescription +#: Rtl/Common/StdConvs.pas:462 +msgid "Months" +msgstr "Meses" + +#. Programmer's name for it: SYearsDescription +#: Rtl/Common/StdConvs.pas:463 +msgid "Years" +msgstr "Años" + +#. Programmer's name for it: SDecadesDescription +#: Rtl/Common/StdConvs.pas:464 +msgid "Decades" +msgstr "Décadas" + +#. Programmer's name for it: SCenturiesDescription +#: Rtl/Common/StdConvs.pas:465 +msgid "Centuries" +msgstr "Cenurias" + +#. Programmer's name for it: SMillenniaDescription +#: Rtl/Common/StdConvs.pas:466 +msgid "Millennia" +msgstr "Milenios" + +#. Programmer's name for it: SDateTimeDescription +#: Rtl/Common/StdConvs.pas:467 +msgid "DateTime" +msgstr "Fecha y Hora" + +#. Programmer's name for it: SJulianDateDescription +#: Rtl/Common/StdConvs.pas:468 +msgid "JulianDate" +msgstr "Fecha Juliana" + +#. Programmer's name for it: SModifiedJulianDateDescription +#: Rtl/Common/StdConvs.pas:469 +msgid "ModifiedJulianDate" +msgstr "Fecha Juliana Modificada" + +#. Programmer's name for it: SCouldNotParseImaginary +#: Rtl/Common/VarCmplx.pas:255 +msgid "Could not parse imaginary portion" +msgstr "" + +#. Programmer's name for it: SCouldNotParseSymbol +#: Rtl/Common/VarCmplx.pas:256 +msgid "Could not parse required '%s' symbol" +msgstr "" + +#. Programmer's name for it: SCouldNotParsePlus +#: Rtl/Common/VarCmplx.pas:257 +msgid "Could not parse required '+' (or '-') symbol" +msgstr "" + +#. Programmer's name for it: SCouldNotParseReal +#: Rtl/Common/VarCmplx.pas:258 +msgid "Could not parse real portion" +msgstr "" + +#. Programmer's name for it: SUnexpectedEOS +#: Rtl/Common/VarCmplx.pas:259 +msgid "Unexpected end of string [%s]" +msgstr "Fin de cadena inesperada [%s]" + +#. Programmer's name for it: SErrorSuffix +#: Rtl/Common/VarCmplx.pas:260 +msgid "%s [%s%s]" +msgstr "" + +#. Programmer's name for it: SCorbaDllNotLoaded +#: Rtl/Corba/CorbCnst.pas:14 Rtl/Corba40/CorbCnst.pas:14 +msgid "Unable to load CORBA libraries" +msgstr "No se pueden cargar las librerias CORBA" + +#. Programmer's name for it: SCorbaNotInitialized +#: Rtl/Corba/CorbCnst.pas:15 Rtl/Corba40/CorbCnst.pas:15 +msgid "CORBA libraries are unavailable or not initialized" +msgstr "" + +#. Programmer's name for it: SCorbaSkeletonNotRegistered +#: Rtl/Corba/CorbCnst.pas:16 Rtl/Corba40/CorbCnst.pas:16 +msgid "CORBA server skeleton not registered for object %s" +msgstr "" + +#. Programmer's name for it: SCorbaStubNotRegistered +#: Rtl/Corba/CorbCnst.pas:17 Rtl/Corba40/CorbCnst.pas:17 +msgid "CORBA client stub not registered" +msgstr "" + +#. Programmer's name for it: SCorbaInterfaceIDNotRegister +#: Rtl/Corba/CorbCnst.pas:18 Rtl/Corba40/CorbCnst.pas:18 +msgid "CORBA interface not registered" +msgstr "" + +#. Programmer's name for it: SCorbaRepositoryIDNotRegistered +#: Rtl/Corba/CorbCnst.pas:19 Rtl/Corba40/CorbCnst.pas:19 +msgid "CORBA Repository ID \"%s\" not registered" +msgstr "" + +#. Programmer's name for it: SCorbaIncompleteFactory +#: Rtl/Corba/CorbCnst.pas:20 Rtl/Corba40/CorbCnst.pas:20 +msgid "CORBA Factory did not implement CreateInterface" +msgstr "" + +#. Programmer's name for it: sInvalidTypeCast +#: Rtl/Corba/CorbCnst.pas:23 Rtl/Corba40/CorbCnst.pas:23 +msgid "Variant cannot be converted to a CORBA Any" +msgstr "" + +#. Programmer's name for it: sNotCorbaObject +#: Rtl/Corba/CorbCnst.pas:24 Rtl/Corba40/CorbCnst.pas:24 +msgid "Variant/Any not a CORBA object" +msgstr "" + +#. Programmer's name for it: sParamTypeCast +#: Rtl/Corba/CorbCnst.pas:25 Rtl/Corba40/CorbCnst.pas:25 +msgid "Parameter (%d) of method %s not of the correct type" +msgstr "" + +#. Programmer's name for it: sParamOut +#: Rtl/Corba/CorbCnst.pas:26 Rtl/Corba40/CorbCnst.pas:26 +msgid "" +"Parameter (%d) of method %s is an out or in/out parameter and requires a " +"variable reference" +msgstr "" + +#. Programmer's name for it: sNoRepository +#: Rtl/Corba/CorbCnst.pas:27 Rtl/Corba40/CorbCnst.pas:27 +msgid "Could not perform CORBA Dispatch, no interface repository found" +msgstr "" + +#. Programmer's name for it: sInvalidParameterCount +#: Rtl/Corba/CorbCnst.pas:28 Rtl/Corba40/CorbCnst.pas:28 +msgid "Incorrect number of parameters to method %s" +msgstr "" + +#. Programmer's name for it: sMethodNotFound +#: Rtl/Corba/CorbCnst.pas:29 Rtl/Corba40/CorbCnst.pas:29 +msgid "Method %s not found" +msgstr "No se ha encontrado el método %s" + +#. Programmer's name for it: sConnecting +#: Rtl/Corba/CorbCnst.pas:30 Rtl/Corba40/CorbCnst.pas:30 +msgid "Connecting to CORBA server..." +msgstr "Conectando al servidor CORBA " + +#. Programmer's name for it: SUnknown +#: Rtl/Sys/SysConst.pas:14 +msgid "" +msgstr "" + +#. Programmer's name for it: SInvalidInteger +#: Rtl/Sys/SysConst.pas:15 +msgid "'%s' is not a valid integer value" +msgstr "'%s' no es un valor entero válido" + +#. Programmer's name for it: SInvalidFloat +#: Rtl/Sys/SysConst.pas:16 +msgid "'%s' is not a valid floating point value" +msgstr "'%s' no es un valor con punto flotante válido" + +#. Programmer's name for it: SInvalidCurrency +#: Rtl/Sys/SysConst.pas:17 +msgid "'%s' is not a valid currency value" +msgstr "'%s' no es un valor de dinero válido" + +#. Programmer's name for it: SInvalidDate +#: Rtl/Sys/SysConst.pas:18 +msgid "'%s' is not a valid date" +msgstr "'%s' no es una fecha válida" + +#. Programmer's name for it: SInvalidTime +#: Rtl/Sys/SysConst.pas:19 +msgid "'%s' is not a valid time" +msgstr "'%s' no es una hora válida" + +#. Programmer's name for it: SInvalidDateTime +#: Rtl/Sys/SysConst.pas:20 +msgid "'%s' is not a valid date and time" +msgstr "'%s' no es una fecha y hora válidas" + +#. Programmer's name for it: SInvalidDateTimeFloat +#: Rtl/Sys/SysConst.pas:21 +msgid "'%g' is not a valid date and time" +msgstr "'%g' no es una fecha y tiempo válidos" + +#. Programmer's name for it: SInvalidTimeStamp +#: Rtl/Sys/SysConst.pas:22 +msgid "'%d.%d' is not a valid timestamp" +msgstr "'%d.%d' no es un timestamp válido" + +#. Programmer's name for it: SInvalidGUID +#: Rtl/Sys/SysConst.pas:23 +msgid "'%s' is not a valid GUID value" +msgstr "'%s' no es un valor de GUID válido" + +#. Programmer's name for it: SInvalidBoolean +#: Rtl/Sys/SysConst.pas:24 +msgid "'%s' is not a valid boolean value" +msgstr "'%s' no es un valor de GUID válido" + +#. Programmer's name for it: SOutOfMemory +#: Rtl/Sys/SysConst.pas:27 +msgid "Out of memory" +msgstr "Fuera de memoria" + +#. Programmer's name for it: SInOutError +#: Rtl/Sys/SysConst.pas:28 +msgid "I/O error %d" +msgstr "Hay un error E/S %d" + +#. Programmer's name for it: SFileNotFound +#: Rtl/Sys/SysConst.pas:29 +msgid "File not found" +msgstr "Archivo no encontrado" + +#. Programmer's name for it: SInvalidFilename +#: Rtl/Sys/SysConst.pas:30 +msgid "Invalid filename" +msgstr "Nombre de archivo no válido" + +#. Programmer's name for it: STooManyOpenFiles +#: Rtl/Sys/SysConst.pas:31 +msgid "Too many open files" +msgstr "Demasiados archivos abiertos" + +#. Programmer's name for it: SAccessDenied +#: Rtl/Sys/SysConst.pas:32 +msgid "File access denied" +msgstr "Acceso al archivo denegado" + +#. Programmer's name for it: SEndOfFile +#: Rtl/Sys/SysConst.pas:33 +msgid "Read beyond end of file" +msgstr "Lectura más allá del final del archivo" + +#. Programmer's name for it: SDiskFull +#: Rtl/Sys/SysConst.pas:34 +msgid "Disk full" +msgstr "Disco lleno" + +#. Programmer's name for it: SInvalidInput +#: Rtl/Sys/SysConst.pas:35 +msgid "Invalid numeric input" +msgstr "Entrada numérica no válida" + +#. Programmer's name for it: SDivByZero +#: Rtl/Sys/SysConst.pas:36 +msgid "Division by zero" +msgstr "División por cero" + +#. Programmer's name for it: SRangeError +#: Rtl/Sys/SysConst.pas:37 +msgid "Range check error" +msgstr "Hay un error de comprobación de rango" + +#. Programmer's name for it: SIntOverflow +#: Rtl/Sys/SysConst.pas:38 +msgid "Integer overflow" +msgstr "Desbordamimento de entero" + +#. Programmer's name for it: SInvalidOp +#: Rtl/Sys/SysConst.pas:39 +msgid "Invalid floating point operation" +msgstr "Operación de coma flotante no válida" + +#. Programmer's name for it: SZeroDivide +#: Rtl/Sys/SysConst.pas:40 +msgid "Floating point division by zero" +msgstr "División de coma flotante por cero" + +#. Programmer's name for it: SOverflow +#: Rtl/Sys/SysConst.pas:41 +msgid "Floating point overflow" +msgstr "Desbordamiento de coma flotante" + +#. Programmer's name for it: SUnderflow +#: Rtl/Sys/SysConst.pas:42 +msgid "Floating point underflow" +msgstr "Coma flotante por debajo de su valor" + +#. Programmer's name for it: SInvalidPointer +#: Rtl/Sys/SysConst.pas:43 +msgid "Invalid pointer operation" +msgstr "Operación de puntero no válida" + +#. Programmer's name for it: SInvalidCast +#: Rtl/Sys/SysConst.pas:44 +msgid "Invalid class typecast" +msgstr "Tipo no válido (typecast) de clase" + +#. Programmer's name for it: SAccessViolation +#: Rtl/Sys/SysConst.pas:46 +msgid "Access violation at address %p. %s of address %p" +msgstr "Violación de acceso a la dirección %p. Accediendo a la dirección %p" + +#. Programmer's name for it: SAccessViolation +#: Rtl/Sys/SysConst.pas:49 +msgid "Access violation at address %p, accessing address %p" +msgstr "Violación de acceso a la dirección %p. %s de dirección %p" + +#. Programmer's name for it: SStackOverflow +#: Rtl/Sys/SysConst.pas:51 +msgid "Stack overflow" +msgstr "Desbordamiento de la pila" + +#. Programmer's name for it: SControlC +#: Rtl/Sys/SysConst.pas:52 +msgid "Control-C hit" +msgstr "Control-C pulsado" + +#. Programmer's name for it: SQuit +#: Rtl/Sys/SysConst.pas:53 +msgid "Quit key hit" +msgstr "Tecla de salida pulsada" + +#. Programmer's name for it: SPrivilege +#: Rtl/Sys/SysConst.pas:54 +msgid "Privileged instruction" +msgstr "Instrucción privilegiada" + +#. Programmer's name for it: SOperationAborted +#: Rtl/Sys/SysConst.pas:55 +msgid "Operation aborted" +msgstr "Operación abortada" + +#. Programmer's name for it: SException +#: Rtl/Sys/SysConst.pas:56 +msgid "" +"Exception %s in module %s at %p.\n" +"%s%s" +msgstr "" +"Excepción %s en el módulo %s en %p.\n" +"%s%s" + +#. Programmer's name for it: SExceptTitle +#: Rtl/Sys/SysConst.pas:57 +msgid "Application Error" +msgstr "Hay un error de la aplicación" + +#. Programmer's name for it: SSigactionFailed +#: Rtl/Sys/SysConst.pas:59 +msgid "sigaction call failed" +msgstr "La llamada del sigaction falló" + +#. Programmer's name for it: SInvalidFormat +#: Rtl/Sys/SysConst.pas:61 +msgid "Format '%s' invalid or incompatible with argument" +msgstr "Formato '%s' no válido o incompatible con el argumento" + +#. Programmer's name for it: SArgumentMissing +#: Rtl/Sys/SysConst.pas:62 +msgid "No argument for format '%s'" +msgstr "No existe argumento para el formato '%s'" + +#. Programmer's name for it: SInvalidVarCast +#: Rtl/Sys/SysConst.pas:63 +msgid "Invalid variant type conversion" +msgstr "Conversión de tipo variant no válida" + +#. Programmer's name for it: SInvalidVarOp +#: Rtl/Sys/SysConst.pas:64 +msgid "Invalid variant operation" +msgstr "Operación variant no válida" + +#. Programmer's name for it: SDispatchError +#: Rtl/Sys/SysConst.pas:65 +msgid "Variant method calls not supported" +msgstr "Llamadas al método variant no soportadas" + +#. Programmer's name for it: SResultTooLong +#: Rtl/Sys/SysConst.pas:68 +msgid "Format result longer than 4096 characters" +msgstr "Formato del resultado más largo de 4096 caracteres" + +#. Programmer's name for it: SFormatTooLong +#: Rtl/Sys/SysConst.pas:69 +msgid "Format string too long" +msgstr "Formato de cadena demasiado largo" + +#. Programmer's name for it: SVarArrayCreate +#: Rtl/Sys/SysConst.pas:70 +msgid "Error creating variant array" +msgstr "Se ha producido un error al crear matriz de variant" + +#. Programmer's name for it: SVarNotArray +#: Rtl/Sys/SysConst.pas:71 +msgid "Variant is not an array" +msgstr "Variant no es una matriz" + +#. Programmer's name for it: SVarArrayBounds +#: Rtl/Sys/SysConst.pas:72 +msgid "Variant array index out of bounds" +msgstr "Indice de matriz variant fuera de rango" + +#. Programmer's name for it: SVarTypeUnknown +#: Rtl/Sys/SysConst.pas:73 +msgid "Unknown custom variant type ($.4x)" +msgstr "Tipo variant del cliente desconocido ($.4x)" + +#. Programmer's name for it: SVarTypeOutOfRange +#: Rtl/Sys/SysConst.pas:74 +msgid "Custom variant type ($.4x) is out of range" +msgstr "El tipo variant personalizado ($.4x) está fuera de rango" + +#. Programmer's name for it: SVarTypeAlreadyUsed +#: Rtl/Sys/SysConst.pas:75 +msgid "Custom variant type (%.4x) already used by %s" +msgstr "El tipo variant personalizado (%.4x) ya està usado por %s" + +#. Programmer's name for it: SVarTypeNotUsable +#: Rtl/Sys/SysConst.pas:76 +msgid "Custom variant type (%.4x) is not usable" +msgstr "El tipo variant personalizado (%.4x) no es utilizable" + +#. Programmer's name for it: SVarTypeTooManyCustom +#: Rtl/Sys/SysConst.pas:77 +msgid "Too many custom variants have been registered" +msgstr "Han sido registradas demasiadas variantes personalizadas" + +#. Programmer's name for it: SVarDataClearRecursing +#: Rtl/Sys/SysConst.pas:78 +msgid "Recursion while doing a VarDataClear" +msgstr "Recursión mientras se hacía un VarDataClear" + +#. Programmer's name for it: SVarDataCopyRecursing +#: Rtl/Sys/SysConst.pas:79 +msgid "Recursion while doing a VarDataCopy" +msgstr "Recursión mientras se hacía un VarDataCopy" + +#. Programmer's name for it: SVarDataCopyNoIndRecursing +#: Rtl/Sys/SysConst.pas:80 +msgid "Recursion while doing a VarDataCopyNoInd" +msgstr "Recursión mientras se hacía un VarDataCopyNoInd" + +#. Programmer's name for it: SVarDataInitRecursing +#: Rtl/Sys/SysConst.pas:81 +msgid "Recursion while doing a VarDataInit" +msgstr "Recursión mientras se hacía un VarDataInit" + +#. Programmer's name for it: SVarDataCastToRecursing +#: Rtl/Sys/SysConst.pas:82 +msgid "Recursion while doing a VarDataCastTo" +msgstr "Recursión mientras se hacía un VarDataCastTo" + +#. Programmer's name for it: SVarIsEmpty +#: Rtl/Sys/SysConst.pas:83 +msgid "Variant is empty" +msgstr "La variable está vacía" + +#. Programmer's name for it: sUnknownFromType +#: Rtl/Sys/SysConst.pas:84 +msgid "Cannot convert from the specified type" +msgstr "No se puede convertir desde el tipo especificado" + +#. Programmer's name for it: sUnknownToType +#: Rtl/Sys/SysConst.pas:85 +msgid "Cannot convert to the specified type" +msgstr "No se puede convertir al tipo especificado" + +#. Programmer's name for it: SExternalException +#: Rtl/Sys/SysConst.pas:86 +msgid "External exception %x" +msgstr "Excepción externa %x" + +#. Programmer's name for it: SAssertionFailed +#: Rtl/Sys/SysConst.pas:87 +msgid "Assertion failed" +msgstr "Falló la aserción" + +#. Programmer's name for it: SIntfCastError +#: Rtl/Sys/SysConst.pas:88 +msgid "Interface not supported" +msgstr "Interfaz no soportada" + +#. Programmer's name for it: SSafecallException +#: Rtl/Sys/SysConst.pas:89 +msgid "Exception in safecall method" +msgstr "Excepción en método Safecall" + +#. Programmer's name for it: SAssertError +#: Rtl/Sys/SysConst.pas:90 +msgid "%s (%s, line %d)" +msgstr "%s (%s, línea %d)" + +#. Programmer's name for it: SAbstractError +#: Rtl/Sys/SysConst.pas:91 +msgid "Abstract Error" +msgstr "Hay un error abstracto" + +#. Programmer's name for it: SModuleAccessViolation +#: Rtl/Sys/SysConst.pas:92 +msgid "Access violation at address %p in module '%s'. %s of address %p" +msgstr "" +"Violación de acceso a la dirección %p en el módulo '%s'. %s de dirección %p" + +#. Programmer's name for it: SCannotReadPackageInfo +#: Rtl/Sys/SysConst.pas:93 +msgid "Cannot access package information for package '%s'" +msgstr "No puede acceder la información del paquete para el paquete '%s'" + +#. Programmer's name for it: sErrorLoadingPackage +#: Rtl/Sys/SysConst.pas:94 +msgid "" +"Can't load package %s.\n" +"%s" +msgstr "" +"No se puede cargar el paquete %s.\n" +"%s" + +#. Programmer's name for it: SInvalidPackageFile +#: Rtl/Sys/SysConst.pas:95 +msgid "Invalid package file '%s'" +msgstr "El archivo del paquete no es válido '%s'" + +#. Programmer's name for it: SInvalidPackageHandle +#: Rtl/Sys/SysConst.pas:96 +msgid "Invalid package handle" +msgstr "El manejador (handle) del paquete no es válido" + +#. Programmer's name for it: SDuplicatePackageUnit +#: Rtl/Sys/SysConst.pas:98 +msgid "" +"Cannot load package '%s.' It contains unit '%s,'which is also contained in " +"package '%s'" +msgstr "" +"No se puede cargar el paquete '%s'. Contiene la unidad '%s,' que también " +"está contenida en el paquete '%s'" + +#. Programmer's name for it: SOSError +#: Rtl/Sys/SysConst.pas:99 +msgid "" +"System Error. Code: %d.\n" +"%s" +msgstr "" +"Hay un error del sistema. Código: %d\n" +"%s" + +#. Programmer's name for it: SUnkOSError +#: Rtl/Sys/SysConst.pas:100 +msgid "A call to an OS function failed" +msgstr "Ha fallado una llamada a una función del SO" + +#. use SOSError +#: Rtl/Sys/SysConst.pas:102 +msgid "" +"Win32 Error. Code: %d.\n" +"%s" +msgstr "" +"Hay un error Win32. Código: %d.\n" +"%s" + +#. use SUnkOSError +#: Rtl/Sys/SysConst.pas:103 +msgid "A Win32 API function failed" +msgstr "Ha fallado una función del API Win32" + +#. Programmer's name for it: SNL +#: Rtl/Sys/SysConst.pas:105 +msgid "Application is not licensed to use this feature" +msgstr "La aplicación no está autorizada para usar esta característica" + +#. Programmer's name for it: SConvDuplicateType +#: Rtl/Sys/SysConst.pas:111 +msgid "Conversion type (%s) already registered" +msgstr "La conversión de tipo (%s) ya está registrada" + +#. Programmer's name for it: SShortMonthNameJan +#: Rtl/Sys/SysConst.pas:119 +msgid "Jan" +msgstr "Ene" + +#. Programmer's name for it: SShortMonthNameFeb +#: Rtl/Sys/SysConst.pas:120 +msgid "Feb" +msgstr "Feb" + +#. Programmer's name for it: SShortMonthNameMar +#: Rtl/Sys/SysConst.pas:121 +msgid "Mar" +msgstr "Mar" + +#. Programmer's name for it: SShortMonthNameApr +#: Rtl/Sys/SysConst.pas:122 +msgid "Apr" +msgstr "Abr" + +#. Programmer's name for it: SShortMonthNameMay +#. Programmer's name for it: SLongMonthNameMay +#: Rtl/Sys/SysConst.pas:123 Rtl/Sys/SysConst.pas:136 +msgid "May" +msgstr "May" + +#. Programmer's name for it: SShortMonthNameJun +#: Rtl/Sys/SysConst.pas:124 +msgid "Jun" +msgstr "Jun" + +#. Programmer's name for it: SShortMonthNameJul +#: Rtl/Sys/SysConst.pas:125 +msgid "Jul" +msgstr "Jul" + +#. Programmer's name for it: SShortMonthNameAug +#: Rtl/Sys/SysConst.pas:126 +msgid "Aug" +msgstr "Ago" + +#. Programmer's name for it: SShortMonthNameSep +#: Rtl/Sys/SysConst.pas:127 +msgid "Sep" +msgstr "Sep" + +#. Programmer's name for it: SShortMonthNameOct +#: Rtl/Sys/SysConst.pas:128 +msgid "Oct" +msgstr "Oct" + +#. Programmer's name for it: SShortMonthNameNov +#: Rtl/Sys/SysConst.pas:129 +msgid "Nov" +msgstr "Nov" + +#. Programmer's name for it: SShortMonthNameDec +#: Rtl/Sys/SysConst.pas:130 +msgid "Dec" +msgstr "Dic" + +#. Programmer's name for it: SLongMonthNameJan +#: Rtl/Sys/SysConst.pas:132 +msgid "January" +msgstr "Enero" + +#. Programmer's name for it: SLongMonthNameFeb +#: Rtl/Sys/SysConst.pas:133 +msgid "February" +msgstr "Febrero" + +#. Programmer's name for it: SLongMonthNameMar +#: Rtl/Sys/SysConst.pas:134 +msgid "March" +msgstr "Marzo" + +#. Programmer's name for it: SLongMonthNameApr +#: Rtl/Sys/SysConst.pas:135 +msgid "April" +msgstr "Abril" + +#. Programmer's name for it: SLongMonthNameJun +#: Rtl/Sys/SysConst.pas:137 +msgid "June" +msgstr "Junio" + +#. Programmer's name for it: SLongMonthNameJul +#: Rtl/Sys/SysConst.pas:138 +msgid "July" +msgstr "Julio" + +#. Programmer's name for it: SLongMonthNameAug +#: Rtl/Sys/SysConst.pas:139 +msgid "August" +msgstr "Agosto" + +#. Programmer's name for it: SLongMonthNameSep +#: Rtl/Sys/SysConst.pas:140 +msgid "September" +msgstr "Septiembre" + +#. Programmer's name for it: SLongMonthNameOct +#: Rtl/Sys/SysConst.pas:141 +msgid "October" +msgstr "Octubre" + +#. Programmer's name for it: SLongMonthNameNov +#: Rtl/Sys/SysConst.pas:142 +msgid "November" +msgstr "Noviembre" + +#. Programmer's name for it: SLongMonthNameDec +#: Rtl/Sys/SysConst.pas:143 +msgid "December" +msgstr "Diciembre" + +#. Programmer's name for it: SShortDayNameSun +#: Rtl/Sys/SysConst.pas:145 +msgid "Sun" +msgstr "Dom" + +#. Programmer's name for it: SShortDayNameMon +#: Rtl/Sys/SysConst.pas:146 +msgid "Mon" +msgstr "Lun" + +#. Programmer's name for it: SShortDayNameTue +#: Rtl/Sys/SysConst.pas:147 +msgid "Tue" +msgstr "Mar" + +#. Programmer's name for it: SShortDayNameWed +#: Rtl/Sys/SysConst.pas:148 +msgid "Wed" +msgstr "Mie" + +#. Programmer's name for it: SShortDayNameThu +#: Rtl/Sys/SysConst.pas:149 +msgid "Thu" +msgstr "Jue" + +#. Programmer's name for it: SShortDayNameFri +#: Rtl/Sys/SysConst.pas:150 +msgid "Fri" +msgstr "Vie" + +#. Programmer's name for it: SShortDayNameSat +#: Rtl/Sys/SysConst.pas:151 +msgid "Sat" +msgstr "Sab" + +#. Programmer's name for it: SLongDayNameSun +#: Rtl/Sys/SysConst.pas:153 +msgid "Sunday" +msgstr "Domingo" + +#. Programmer's name for it: SLongDayNameMon +#: Rtl/Sys/SysConst.pas:154 +msgid "Monday" +msgstr "Lunes" + +#. Programmer's name for it: SLongDayNameTue +#: Rtl/Sys/SysConst.pas:155 +msgid "Tuesday" +msgstr "Martes" + +#. Programmer's name for it: SLongDayNameWed +#: Rtl/Sys/SysConst.pas:156 +msgid "Wednesday" +msgstr "Miércoles" + +#. Programmer's name for it: SLongDayNameThu +#: Rtl/Sys/SysConst.pas:157 +msgid "Thursday" +msgstr "Jueves" + +#. Programmer's name for it: SLongDayNameFri +#: Rtl/Sys/SysConst.pas:158 +msgid "Friday" +msgstr "Viernes" + +#. Programmer's name for it: SLongDayNameSat +#: Rtl/Sys/SysConst.pas:159 +msgid "Saturday" +msgstr "Sábado" + +#. Programmer's name: FONT 8 +#. formAbout..Font.Name +#. formAbout..lblCopyright..Font.Name +#. formAbout..lblPleaseVisitUs..Font.Name +#. formAbout..lblURL..Font.Name +#. IdPropEdBindingEntry..Font.Name +#. formAbout..Font.Name +#. formAbout..Panel1..lblPleaseVisitUs..Font.Name +#. formAbout..Panel1..lblURL..Font.Name +#. formAbout..Panel2..lblCopyright..Font.Name +#. frmNewMessagePart..Font.Name +#. IdPropEdBindingEntry..Font.Name +#. Form1..Font.Name +#. LogDetailFrame..ActionList1..FontEdit1..Dialog.Font.Name +#. AboutBox..DetailsPanel..Copyright..Font.Name +#. AboutBox..DetailsPanel..Version..Font.Name +#. AboutBox..DetailsPanel..SKUName..Font.Name +#. AboutBox..DetailsPanel..CompanyName..Font.Name +#. StandardActions..ActionList1..FontEdit1..Dialog.Font.Name +#. frmGeneratorEditor..Font.Name +#. frmIBRestoreEditor..Font.Name +#. frmIBSecurityEditor..Font.Name +#. frmIBServiceEditor..Font.Name +#: Vcl/ExtDlgs.rc:14 Indy/IdAbout.xfm:20 Indy/IdAbout.xfm:2805 +#: Indy/IdAbout.xfm:2844 Indy/IdAbout.xfm:2864 Indy/IdDsnPropEdBinding.xfm:15 +#: Indy/IdAbout.dfm:13 Indy/IdAbout.dfm:38 Indy/IdAbout.dfm:55 +#: Indy/IdAbout.dfm:100 Indy/IdDsnNewMessagePart.dfm:12 +#: Indy/IdDsnPropEdBinding.dfm:14 Internet/SvrInfoConsole.dfm:11 +#: Internet/SvrLogDetailFrame.dfm:54 Internet/WebAppDbgAbout.dfm:84 +#: Internet/WebAppDbgAbout.dfm:98 Internet/WebAppDbgAbout.dfm:112 +#: Internet/WebAppDbgAbout.dfm:301 Vcl/ActnRes.dfm:216 +#: Vcl/IBGeneratorEditor.dfm:12 Vcl/IBRestoreEditor.dfm:12 +#: Vcl/IBSecurityEditor.dfm:11 Vcl/IBServiceEditor.dfm:11 +msgid "MS Sans Serif" +msgstr "" + +#. LoginDialog..Caption +#: Clx/QDBLogDlg.xfm:7 Vcl/DBLOGDLG.dfm:6 +msgid "Database Login" +msgstr "Entrada a la base de datos" + +#. LoginDialog..OKButton..Caption +#. PasswordDialog..OKButton..Caption +#. ClxStrEditDlg..OKButton..Caption +#. InputReqDialog..OKButton..Caption +#. DataBindForm..OkBtn..Caption +#. StrEditDlg..OKButton..Caption +#. UpdateSQLEditForm..OkButton..Caption +#. LoginDialog..OKButton..Caption +#. PasswordDialog..OKButton..Caption +#: Clx/QDBLogDlg.xfm:20 Clx/QDBPWDlg.xfm:20 Property +#: Editors/ClxStrEdit.xfm:42 Editors/dbinpreq.dfm:18 Editors/DbOleEdt.dfm:109 +#: Editors/StrEdit.dfm:39 Editors/UpdSqlEd.dfm:20 Vcl/DBLOGDLG.dfm:21 +#: Vcl/DbPWDlg.dfm:18 +msgid "&OK" +msgstr "&Aceptar" + +#. LoginDialog..Panel..Label3..Caption +#: Clx/QDBLogDlg.xfm:56 Vcl/DBLOGDLG.dfm:49 +msgid "Database:" +msgstr "Base de datos:" + +#. LoginDialog..Panel..Panel1..Label1..Caption +#. frmIBSecurityEditor..GroupBox1..Label2..Caption +#. frmIBServiceEditor..GroupBox1..Label2..Caption +#: Clx/QDBLogDlg.xfm:81 Vcl/DBLOGDLG.dfm:77 Vcl/IBSecurityEditor.dfm:136 +#: Vcl/IBServiceEditor.dfm:159 +msgid "&User Name:" +msgstr "Nombre de &usuario: " + +#. LoginDialog..Panel..Panel1..Label2..Caption +#: Clx/QDBLogDlg.xfm:91 Vcl/DBLOGDLG.dfm:85 +msgid "&Password:" +msgstr "&Contraseña: " + +#. PasswordDialog..Caption +#: Clx/QDBPWDlg.xfm:7 Vcl/DbPWDlg.dfm:6 +msgid "Enter password" +msgstr "Entrada de contraseña" + +#. PasswordDialog..GroupBox1..AddButton..Caption +#. IdPropEdBindingEntry..btnAdd..Caption +#. IdPropEdBindingEntry..actBndEditor..actAdd..Caption +#. DSSQueryEditor..Pager..Dimensions..Label7..Caption +#. IdPropEdBindingEntry..actBndEditor..actAdd..Caption +#. CollectionEditor..ActionList1..AddCmd..Caption +#. LinkFields..AddButton..Caption +#. PasswordDialog..GroupBox1..AddButton..Caption +#. SocketForm..MainMenu1..miPorts..miAdd..Caption +#: Clx/QDBPWDlg.xfm:57 Indy/IdDsnPropEdBinding.xfm:87 +#: Indy/IdDsnPropEdBinding.xfm:123 Decision Cube/MXDSSQRY.DFM:78 +#: Indy/IdDsnPropEdBinding.dfm:113 Property Editors/ColnEdit.dfm:189 +#: Editors/FldLinks.DFM:114 Vcl/DbPWDlg.dfm:56 Vcl/ScktMain.dfm:344 +msgid "&Add" +msgstr "" + +#. PasswordDialog..GroupBox1..RemoveButton..Caption +#. IdPropEdBindingEntry..btnRemove..Caption +#. IdPropEdBindingEntry..actBndEditor..actRemove..Caption +#. PasswordDialog..GroupBox1..RemoveButton..Caption +#. SocketForm..ActionList1..RemovePortAction..Caption +#: Clx/QDBPWDlg.xfm:67 Indy/IdDsnPropEdBinding.xfm:96 +#: Indy/IdDsnPropEdBinding.xfm:128 Indy/IdDsnPropEdBinding.dfm:118 +#: Vcl/DbPWDlg.dfm:66 Vcl/ScktMain.dfm:396 +msgid "&Remove" +msgstr "" + +#. PasswordDialog..GroupBox1..RemoveAllButton..Caption +#: Clx/QDBPWDlg.xfm:77 Vcl/DbPWDlg.dfm:76 +msgid "Re&move all" +msgstr "" + +#. formAbout..Caption +#: Indy/IdAbout.xfm:11 +msgid "About Indy" +msgstr "Acerca de Indy" + +#. formAbout..lblName..Font.Name +#. formAbout..lblVersion..Font.Name +#. formAbout..Panel2..lblVersion..Font.Name +#. formAbout..Panel2..lblName..Font.Name +#: Indy/IdAbout.xfm:2786 Indy/IdAbout.xfm:2825 Indy/IdAbout.dfm:117 +#: Indy/IdAbout.dfm:133 +msgid "Times New Roman" +msgstr "" + +#. formAbout..lblURL..Caption +#: Indy/IdAbout.xfm:2860 +#, fuzzy +msgid "http://www.nevrona.com/indy" +msgstr "http://www.nevrona.com/indy/" + +#. formAbout..scbxCredits..panlScroll..lblJimGunkel..Caption +#: Indy/IdAbout.xfm:2894 +msgid "Jim Gunkel" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblJimGunkel..Font.Name +#. formAbout..scbxCredits..panlScroll..lblNevronaDesignsFour..Font.Name +#. formAbout..scbxCredits..panlScroll..lblKudzu..Font.Name +#. formAbout..scbxCredits..panlScroll..lblNevronaOne..Font.Name +#. formAbout..scbxCredits..panlScroll..lblHadi..Font.Name +#. formAbout..scbxCredits..panlScroll..lblNevronaTwo..Font.Name +#. formAbout..scbxCredits..panlScroll..lblAndrewPeeMee..Font.Name +#. formAbout..scbxCredits..panlScroll..lblCharlesStack..Font.Name +#. formAbout..scbxCredits..panlScroll..lblGregorIbic..Font.Name +#. formAbout..scbxCredits..panlScroll..lblIntelicomdoo..Font.Name +#. formAbout..scbxCredits..panlScroll..lblJPeterMugaas..Font.Name +#. formAbout..scbxCredits..panlScroll..lblNevronaThree..Font.Name +#. formAbout..scbxCredits..panlScroll..lblMarkHolmes..Font.Name +#. formAbout..scbxCredits..panlScroll..lblRuneMoberg..Font.Name +#. formAbout..scbxCredits..panlScroll..lblStephaneGrobety..Font.Name +#. formAbout..scbxCredits..panlScroll..lblDonSIders..Font.Name +#. formAbout..scbxCredits..panlScroll..lblAllenOneil..Font.Name +#: Indy/IdAbout.xfm:2898 Indy/IdAbout.xfm:2918 Indy/IdAbout.xfm:2957 +#: Indy/IdAbout.xfm:2977 Indy/IdAbout.xfm:3016 Indy/IdAbout.xfm:3036 +#: Indy/IdAbout.xfm:3076 Indy/IdAbout.xfm:3096 Indy/IdAbout.xfm:3116 +#: Indy/IdAbout.xfm:3136 Indy/IdAbout.xfm:3156 Indy/IdAbout.xfm:3176 +#: Indy/IdAbout.xfm:3196 Indy/IdAbout.xfm:3216 Indy/IdAbout.xfm:3236 +#: Indy/IdAbout.xfm:3276 Indy/IdAbout.xfm:3316 +msgid "Courier New" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblNevronaDesignsFour..Caption +#. formAbout..scbxCredits..panlScroll..lblNevronaOne..Caption +#. formAbout..scbxCredits..panlScroll..lblNevronaTwo..Caption +#. formAbout..scbxCredits..panlScroll..lblNevronaThree..Caption +#: Indy/IdAbout.xfm:2914 Indy/IdAbout.xfm:2973 Indy/IdAbout.xfm:3032 +#: Indy/IdAbout.xfm:3172 +msgid "Nevrona Designs" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lbCoordinator..Font.Name +#. formAbout..scbxCredits..panlScroll..lbCoCordinator..Font.Name +#. formAbout..scbxCredits..panlScroll..lblIndyPitCrew..Font.Name +#. formAbout..scbxCredits..panlScroll..lblDocumentCoordinator..Font.Name +#. formAbout..scbxCredits..panlScroll..lblProgramsCoordinator..Font.Name +#: Indy/IdAbout.xfm:2937 Indy/IdAbout.xfm:2996 Indy/IdAbout.xfm:3056 +#: Indy/IdAbout.xfm:3256 Indy/IdAbout.xfm:3296 +#, fuzzy +msgid "Arial" +msgstr "Abril" + +#. formAbout..scbxCredits..panlScroll..lblKudzu..Caption +#: Indy/IdAbout.xfm:2953 +msgid "Kudzu (Chad Z. Hower)" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblHadi..Caption +#: Indy/IdAbout.xfm:3012 +msgid "Hadi Hariri" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblIndyPitCrew..Caption +#: Indy/IdAbout.xfm:3052 +msgid "The Indy Crew" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblAndrewPeeMee..Caption +#: Indy/IdAbout.xfm:3072 +msgid "Andrew Peter Mee" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblCharlesStack..Caption +#: Indy/IdAbout.xfm:3092 +msgid "Charles Stack" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblGregorIbic..Caption +#: Indy/IdAbout.xfm:3112 +msgid "Gregor Ibic" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblIntelicomdoo..Caption +#: Indy/IdAbout.xfm:3132 +msgid "Intelicom d.o.o." +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblJPeterMugaas..Caption +#: Indy/IdAbout.xfm:3152 +msgid "J. Peter Mugaas" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblMarkHolmes..Caption +#: Indy/IdAbout.xfm:3192 +msgid "Mark Holmes" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblRuneMoberg..Caption +#: Indy/IdAbout.xfm:3212 +msgid "Rune Moberg" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblDocumentCoordinator..Caption +#: Indy/IdAbout.xfm:3252 +msgid "Documentation Coordinator" +msgstr "Coordinador de la documentación" + +#. formAbout..scbxCredits..panlScroll..lblDonSIders..Caption +#: Indy/IdAbout.xfm:3272 +msgid "Don Siders" +msgstr "" + +#. formAbout..scbxCredits..panlScroll..lblProgramsCoordinator..Caption +#: Indy/IdAbout.xfm:3292 +msgid "Demo Programs Coordinator" +msgstr "Coordinador de los programas demo" + +#. formAbout..scbxCredits..panlScroll..lblAllenOneil..Caption +#: Indy/IdAbout.xfm:3312 +msgid "Allen O'Neill" +msgstr "" + +#. IdPropEdBindingEntry..Caption +#: Indy/IdDsnPropEdBinding.xfm:6 Indy/IdDsnPropEdBinding.dfm:5 +msgid "Binding Editor" +msgstr "" + +#. IdPropEdBindingEntry..Label1..Caption +#: Indy/IdDsnPropEdBinding.xfm:28 Indy/IdDsnPropEdBinding.dfm:25 +msgid "Bindings" +msgstr "" + +#. IdPropEdBindingEntry..Label2..Caption +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Indy/IdDsnPropEdBinding.xfm:36 Indy/IdDsnPropEdBinding.dfm:32 +#: Vcl/ScktMain.dfm:252 +msgid "IP Address" +msgstr "Dirección IP" + +#. IdPropEdBindingEntry..Label3..Caption +#. WebAppDbgMainForm..Port..Caption +#. SocketForm..Pages..PropPage..PortGroup..Caption +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#. SocketForm..Panel1..HeaderControl1......Text +#: Indy/IdDsnPropEdBinding.xfm:44 Indy/IdDsnPropEdBinding.dfm:39 +#: Internet/SvrMainForm.dfm:57 Vcl/ScktMain.dfm:38 Vcl/ScktMain.dfm:248 +#: Vcl/ScktMain.dfm:310 +msgid "Port" +msgstr "" + +#. ClxIconViewItemsEditor..Caption +#: Property Editors/ClxIconEdit.xfm:7 +msgid "IconView Items Editor" +msgstr "" + +#. ClxIconViewItemsEditor..GroupBox1..Caption +#. ClxListViewItems..GroupBox1..Caption +#. ClxTreeViewItems..GroupBox1..Caption +#: Property Editors/ClxIconEdit.xfm:22 Editors/ClxItemEdit.xfm:22 +#: Editors/ClxNodeEdit.xfm:22 +msgid "&Items" +msgstr "" + +#. ClxIconViewItemsEditor..GroupBox1..New..Caption +#. ClxListViewItems..GroupBox1..New..Caption +#: Property Editors/ClxIconEdit.xfm:30 Editors/ClxItemEdit.xfm:30 +msgid "&New Item" +msgstr "" + +#. ClxIconViewItemsEditor..GroupBox1..Delete..Caption +#. ClxImageListEditor..GroupBox1..Delete..Caption +#. ClxListViewItems..GroupBox1..Delete..Caption +#. ClxTreeViewItems..GroupBox1..Delete..Caption +#. CollectionEditor..ActionList1..DeleteCmd..Caption +#. DataBindForm..Panel1..DeleteBtn..Caption +#. FieldsEditor..LocalMenu..DeleteItem..Caption +#. LinkFields..DeleteButton..Caption +#. IndexFiles..GroupBox1..Delete..Caption +#. StandardActions..ActionList1..EditDelete1..Caption +#: Property Editors/ClxIconEdit.xfm:41 Editors/ClxImgEdit.xfm:184 +#: Editors/ClxItemEdit.xfm:41 Editors/ClxNodeEdit.xfm:41 +#: Editors/ColnEdit.dfm:196 Editors/DbOleEdt.dfm:90 Editors/DSDesign.dfm:159 +#: Editors/FldLinks.DFM:123 Editors/Ixedit.dfm:43 Vcl/ActnRes.dfm:66 +msgid "&Delete" +msgstr "" + +#. ClxIconViewItemsEditor..PropGroupBox..Caption +#. ClxListViewItems..PropGroupBox..Caption +#. ClxTreeViewItems..PropGroupBox..Caption +#: Property Editors/ClxIconEdit.xfm:69 Editors/ClxItemEdit.xfm:79 +#: Editors/ClxNodeEdit.xfm:89 +msgid "Item Properties" +msgstr "" + +#. ClxIconViewItemsEditor..PropGroupBox..Label1..Caption +#. ClxListViewItems..PropGroupBox..Label1..Caption +#: Property Editors/ClxIconEdit.xfm:77 Editors/ClxItemEdit.xfm:87 +msgid "&Caption:" +msgstr "" + +#. ClxIconViewItemsEditor..PropGroupBox..Label2..Caption +#. ClxListViewItems..PropGroupBox..Label2..Caption +#. ClxTreeViewItems..PropGroupBox..Label2..Caption +#: Property Editors/ClxIconEdit.xfm:87 Editors/ClxItemEdit.xfm:96 +#: Editors/ClxNodeEdit.xfm:105 +msgid "I&mage Index:" +msgstr "" + +#. ClxIconViewItemsEditor..Apply..Caption +#. ClxListViewItems..Apply..Caption +#. ClxTreeViewItems..Apply..Caption +#. SocketForm..ActionList1..ApplyAction..Caption +#: Property Editors/ClxIconEdit.xfm:143 Editors/ClxItemEdit.xfm:169 +#: Editors/ClxNodeEdit.xfm:179 Vcl/ScktMain.dfm:381 +msgid "&Apply" +msgstr "" + +#. ClxImageListEditor..Caption +#: Property Editors/ClxImgEdit.xfm:10 +msgid "ImageList Editor" +msgstr "" + +#. ClxImageListEditor..ImageGroup..Caption +#: Property Editors/ClxImgEdit.xfm:50 +msgid " &Selected Image " +msgstr "" + +#. ClxImageListEditor..ImageGroup..TransparentLabel..Caption +#: Property Editors/ClxImgEdit.xfm:58 +msgid "&Transparent Color:" +msgstr "" + +#. ClxImageListEditor..ImageGroup..FillLabel..Caption +#: Property Editors/ClxImgEdit.xfm:67 +msgid "&Fill Color:" +msgstr "" + +#. ClxImageListEditor..ImageGroup..OptionsGroup....Items.Strings +#: Property Editors/ClxImgEdit.xfm:79 +msgid "" +"Cr&op\n" +"St&retch\n" +"C&enter\n" +msgstr "" + +#. ClxImageListEditor..ImageGroup..OptionsGroup..Caption +#. DBEditForm..GroupBox3..Caption +#: Property Editors/ClxImgEdit.xfm:80 Editors/Dbedit.dfm:116 +msgid " Options " +msgstr "" + +#. ClxImageListEditor..Apply..Caption +#: Property Editors/ClxImgEdit.xfm:133 +msgid "A&pply" +msgstr "" + +#. ClxImageListEditor..GroupBox1..Caption +#: Property Editors/ClxImgEdit.xfm:153 +msgid " &Images " +msgstr "" + +#. ClxImageListEditor..GroupBox1..Add..Caption +#. IndexFiles..GroupBox1..Add..Caption +#: Property Editors/ClxImgEdit.xfm:174 Editors/Ixedit.dfm:34 +msgid "&Add..." +msgstr "" + +#. ClxImageListEditor..GroupBox1..Clear..Caption +#. Caption +#. ClxStrEditDlg..PopupMenu1..Clear1..Caption +#. LogFrame..ActionList1..ClearAction..Caption +#. WebAppDbgMainForm..ActionList1..ClearAction..Caption +#. DBEditForm..GroupBox1..ClearButton..Caption +#. LinkFields..ClearButton..Caption +#. IndexFiles..GroupBox1..Clear..Caption +#. PictureEditorDlg..GroupBox1..Clear..Caption +#: Property Editors/ClxImgEdit.xfm:195 Editors/ClxPicEdit.xfm:93 +#: Editors/ClxStrEdit.xfm:115 Internet/SvrLogFrame.dfm:40 +#: Internet/SvrMainForm.dfm:166 Editors/Dbedit.dfm:99 Editors/FldLinks.DFM:132 +#: Editors/Ixedit.dfm:53 Editors/PicEdit.dfm:94 +msgid "&Clear" +msgstr "" + +#. ClxImageListEditor..GroupBox1..ExportBtn..Caption +#: Property Editors/ClxImgEdit.xfm:206 +msgid "E&xport..." +msgstr "E&xportar..." + +#. ClxImageListEditor..OpenDialog..DefaultExt +#. ClxImageListEditor..SaveDialog..DefaultExt +#: Property Editors/ClxImgEdit.xfm:215 Editors/ClxImgEdit.xfm:227 +msgid "bmp" +msgstr "bmp" + +#. ClxImageListEditor..OpenDialog....DefaultExt +#: Property Editors/ClxImgEdit.xfm:219 +msgid "" +"All (*.bmp; *.ico; *.png; *.xpm)|Bitmaps (*.bmp)|Icons (*.ico)|PNG's (*.png)|" +"X Pixmaps (*.xpm)\n" +msgstr "" + +#. ClxImageListEditor..OpenDialog..Title +#: Property Editors/ClxImgEdit.xfm:220 +msgid "Add Images" +msgstr "" + +#. ClxImageListEditor..SaveDialog..Filter +#: Property Editors/ClxImgEdit.xfm:228 +msgid "Bitmaps (*.bmp)" +msgstr "Mapas de bits (*.bmp)" + +#. ClxImageListEditor..SaveDialog..Title +#: Property Editors/ClxImgEdit.xfm:230 +msgid "Export Images" +msgstr "Exportar imágenes" + +#. ClxListViewItems..Caption +#: Property Editors/ClxItemEdit.xfm:7 +msgid "ListView Items Editor" +msgstr "" + +#. ClxListViewItems..GroupBox1..NewSub..Caption +#: Property Editors/ClxItemEdit.xfm:51 +msgid "N&ew SubItem" +msgstr "" + +#. ClxListViewItems..PropGroupBox..Label3..Caption +#: Property Editors/ClxItemEdit.xfm:105 +msgid "&State Index:" +msgstr "" + +#. ClxTreeViewItems..Caption +#: Property Editors/ClxNodeEdit.xfm:8 +msgid "TreeView Items Editor" +msgstr "" + +#. ClxTreeViewItems..GroupBox1..New..Caption +#: Property Editors/ClxNodeEdit.xfm:30 +msgid "&New Node" +msgstr "" + +#. ClxTreeViewItems..GroupBox1..NewSub..Caption +#: Property Editors/ClxNodeEdit.xfm:51 +msgid "N&ew SubNode" +msgstr "" + +#. ClxTreeViewItems..GroupBox1..Load..Caption +#: Property Editors/ClxNodeEdit.xfm:61 +msgid "&Load" +msgstr "" + +#. ClxTreeViewItems..PropGroupBox..Label1..Caption +#: Property Editors/ClxNodeEdit.xfm:96 +msgid "&Text:" +msgstr "" + +#. ClxTreeViewItems..PropGroupBox..Label4..Caption +#: Property Editors/ClxNodeEdit.xfm:114 +msgid "&Selected Index:" +msgstr "" + +#. ClxTreeViewItems..gbSubItems..Caption +#: Property Editors/ClxNodeEdit.xfm:199 +msgid "Sub Items" +msgstr "" + +#. ClxTreeViewItems..gbSubItems..btnAddSub..Caption +#: Property Editors/ClxNodeEdit.xfm:216 +msgid "Add SubItem" +msgstr "" + +#. ClxTreeViewItems..gbSubItemProps..Caption +#: Property Editors/ClxNodeEdit.xfm:237 +msgid "Sub Item Properties" +msgstr "" + +#. ClxTreeViewItems..gbSubItemProps..lblSubText..Caption +#: Property Editors/ClxNodeEdit.xfm:264 +msgid "Text:" +msgstr "" + +#. ClxTreeViewItems..gbSubItemProps..lblSubImgIndex..Caption +#: Property Editors/ClxNodeEdit.xfm:272 +msgid "Image Index:" +msgstr "" + +#. ClxTreeViewItems..OpenDialog1..Filter +#: Property Editors/ClxNodeEdit.xfm:277 +msgid "All Files(*)" +msgstr "" + +#. ClxPictureEditorDlg..Caption +#. PictureEditorDlg..Caption +#: Property Editors/ClxPicEdit.xfm:9 Editors/PicEdit.dfm:6 +msgid "Picture Editor" +msgstr "" + +#. Caption +#. ClxStrEditDlg..PopupMenu1..Load1..Caption +#. PictureEditorDlg..GroupBox1..Load..Caption +#. StrEditDlg..StringEditorMenu..LoadItem..Caption +#: Property Editors/ClxPicEdit.xfm:73 Editors/ClxStrEdit.xfm:105 +#: Editors/PicEdit.dfm:76 Editors/StrEdit.dfm:76 +msgid "&Load..." +msgstr "" + +#. Caption +#. ClxStrEditDlg..PopupMenu1..Save1..Caption +#. PictureEditorDlg..GroupBox1..Save..Caption +#. StrEditDlg..StringEditorMenu..SaveItem..Caption +#: Property Editors/ClxPicEdit.xfm:83 Editors/ClxStrEdit.xfm:110 +#: Editors/PicEdit.dfm:85 Editors/StrEdit.dfm:80 +msgid "&Save..." +msgstr "" + +#. ClxStrEditDlg..Caption +#: Property Editors/ClxStrEdit.xfm:10 +msgid "String list editor" +msgstr "" + +#. ClxStrEditDlg..LineCount..Caption +#. StringsEditDlg..LineCount..Caption +#: Property Editors/ClxStrEdit.xfm:33 Editors/StringsEdit.dfm:13 +msgid "0 lines" +msgstr "" + +#. ClxStrEditDlg..OpenDialog....HelpContext +#. ClxStrEditDlg..SaveDialog....DefaultExt +#: Property Editors/ClxStrEdit.xfm:85 Editors/ClxStrEdit.xfm:96 +msgid "" +"Text files (*.txt)|Config files (*.conf)|Shell scripts (*.sh)|All files (*)\n" +msgstr "" + +#. ClxStrEditDlg..OpenDialog..Title +#. StrEditDlg..OpenDialog..Title +#: Property Editors/ClxStrEdit.xfm:85 Editors/StrEdit.dfm:61 +msgid "Load string list" +msgstr "" + +#. ClxStrEditDlg..SaveDialog..DefaultExt +#: Property Editors/ClxStrEdit.xfm:92 +msgid "txt" +msgstr "txt" + +#. ClxStrEditDlg..SaveDialog..Title +#. StrEditDlg..SaveDialog..Title +#: Property Editors/ClxStrEdit.xfm:97 Editors/StrEdit.dfm:70 +msgid "Save string list" +msgstr "" + +#. DSSCubeEditor..Caption +#: Decision Cube/MXDCUBE.DFM:6 +msgid "Decision Cube Editor" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..Caption +#: Decision Cube/MXDCUBE.DFM:27 +msgid "Dimension Settings" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..CaptionLabel..Caption +#: Decision Cube/MXDCUBE.DFM:34 +msgid "Display &Name" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveLabel..Caption +#: Decision Cube/MXDCUBE.DFM:43 +msgid "&Active Type" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..BinLabel..Caption +#: Decision Cube/MXDCUBE.DFM:52 +msgid "&Grouping" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..StartLabel..Caption +#: Decision Cube/MXDCUBE.DFM:61 +msgid "&Initial Value" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeLabel..Caption +#: Decision Cube/MXDCUBE.DFM:70 +msgid "&Type" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..Label1..Caption +#: Decision Cube/MXDCUBE.DFM:79 +msgid "Available &Fields" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..Label2..Caption +#: Decision Cube/MXDCUBE.DFM:88 +msgid "For&mat" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameLabel..Caption +#: Decision Cube/MXDCUBE.DFM:105 +msgid "&Base Field" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..CaptionEdit..Text +#: Decision Cube/MXDCUBE.DFM:125 +msgid "CaptionEdit" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit..Hint +#: Decision Cube/MXDCUBE.DFM:133 +msgid "Control of when the information for this field is loaded" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit..Text +#: Decision Cube/MXDCUBE.DFM:138 +msgid "ActiveEdit" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit....Items.Strings +#: Decision Cube/MXDCUBE.DFM:144 +msgid "" +"Active\n" +"As Needed\n" +"Inactive\n" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit..Hint +#: Decision Cube/MXDCUBE.DFM:150 +msgid "Group values for this field into ranges" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit..Text +#: Decision Cube/MXDCUBE.DFM:155 +msgid "BinEdit" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit....Items.Strings +#: Decision Cube/MXDCUBE.DFM:163 +msgid "" +"None\n" +"Year\n" +"Quarter\n" +"Month\n" +"Single Value\n" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeEdit..Text +#: Decision Cube/MXDCUBE.DFM:173 +msgid "TypeEdit" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeEdit....Items.Strings +#: Decision Cube/MXDCUBE.DFM:184 +msgid "" +"Dimension\n" +"Sum\n" +"Count\n" +"Average\n" +"Min\n" +"Max\n" +"GenericAgg\n" +"Unknown\n" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..FormatEdit..Text +#: Decision Cube/MXDCUBE.DFM:193 +msgid "FormatEdit" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..StartEdit....Height +#: Decision Cube/MXDCUBE.DFM:204 +msgid "" +"Starting value for date ranges, Intial value for single valued dimensions\n" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameEdit....Height +#: Decision Cube/MXDCUBE.DFM:217 +msgid "" +"Fieldname (for a summary, the original field used to calculate the summary)\n" +msgstr "" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameEdit..Text +#: Decision Cube/MXDCUBE.DFM:220 +msgid "BaseNameEdit" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..Caption +#: Decision Cube/MXDCUBE.DFM:226 +msgid "Memory Control" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..Hint +#: Decision Cube/MXDCUBE.DFM:232 +msgid "Control whether to load the decision cube at design time" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..Caption +#: Decision Cube/MXDCUBE.DFM:233 +msgid "Designer Data Options" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioMetaData..Caption +#: Decision Cube/MXDCUBE.DFM:242 +msgid "Display Dimension &Names" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioDimensionData..Caption +#: Decision Cube/MXDCUBE.DFM:253 +msgid "Display Names and &Values" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioAllData..Caption +#: Decision Cube/MXDCUBE.DFM:262 +msgid "Display Names, Values, and &Totals" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioNoData..Caption +#: Decision Cube/MXDCUBE.DFM:271 +msgid "&Run Time Display Only" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Caption +#: Decision Cube/MXDCUBE.DFM:281 +msgid "Cube Maximums" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label4..Caption +#: Decision Cube/MXDCUBE.DFM:307 +msgid "Active" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label7..Caption +#: Decision Cube/MXDCUBE.DFM:315 +msgid "Active+Needed" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label9..Caption +#: Decision Cube/MXDCUBE.DFM:323 +msgid "&Dimensions" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label6..Caption +#: Decision Cube/MXDCUBE.DFM:351 +msgid "&Summaries" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label12..Caption +#: Decision Cube/MXDCUBE.DFM:361 +msgid "&Cells" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label5..Caption +#: Decision Cube/MXDCUBE.DFM:379 +msgid "Maximum" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label3..Caption +#: Decision Cube/MXDCUBE.DFM:387 +msgid "Current" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxDims....Height +#: Decision Cube/MXDCUBE.DFM:424 +msgid "Limit on the number of dimensions which can be loaded at one time\n" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxSums..Hint +#: Decision Cube/MXDCUBE.DFM:433 +msgid "Limit on the number of summaries which can be loaded at one time" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxCells....Height +#: Decision Cube/MXDCUBE.DFM:446 +msgid "Limit on the number of storage cells which can be loaded at one time\n" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..GetCellCounts..Hint +#: Decision Cube/MXDCUBE.DFM:455 +msgid "Run a query to fetch information required to estimate cell usage" +msgstr "" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..GetCellCounts..Caption +#: Decision Cube/MXDCUBE.DFM:456 +msgid "&Get Cell Counts" +msgstr "" + +#. DimEditor..Caption +#. FieldsEditor..Caption +#: Decision Cube/MXDESIGN.DFM:6 Cube/MXDIMEDT.DFM:7 Property +#: Editors/DSDesign.dfm:8 +msgid "Form1.Table1" +msgstr "" + +#. SQLWindow..Caption +#: Decision Cube/MXDSQL.DFM:6 +msgid "Form2" +msgstr "" + +#. SQLWindow..Memo1....Lines.Strings +#. LogDetailFrame..Memo1....Lines.Strings +#: Decision Cube/MXDSQL.DFM:32 Internet/SvrLogDetailFrame.dfm:18 +msgid "Memo1\n" +msgstr "" + +#. DSSQueryEditor..Caption +#: Decision Cube/MXDSSQRY.DFM:6 +msgid "Decision Query Editor" +msgstr "" + +#. DSSQueryEditor..Pager..Dimensions..Caption +#: Decision Cube/MXDSSQRY.DFM:25 +msgid "Dimensions/Summaries" +msgstr "" + +#. DSSQueryEditor..Pager..Dimensions..Label2..Caption +#: Decision Cube/MXDSSQRY.DFM:32 +msgid "&Dimensions:" +msgstr "" + +#. DSSQueryEditor..Pager..Dimensions..Label3..Caption +#: Decision Cube/MXDSSQRY.DFM:41 +msgid "&Summaries:" +msgstr "" + +#. DSSQueryEditor..Pager..Dimensions..Label4..Caption +#: Decision Cube/MXDSSQRY.DFM:50 +msgid "&List of Available Fields:" +msgstr "" + +#. DSSQueryEditor..Pager..Dimensions..Label5..Caption +#: Decision Cube/MXDSSQRY.DFM:59 +msgid "&Table:" +msgstr "" + +#. DSSQueryEditor..Pager..Dimensions..Label6..Caption +#: Decision Cube/MXDSSQRY.DFM:68 +msgid "Databas&e:" +msgstr "Bas&e de datos" + +#. DSSQueryEditor..Pager..Dimensions..SelectAllFields..Hint +#: Decision Cube/MXDSSQRY.DFM:131 +msgid "List all fields or List only the fields in the query" +msgstr "" + +#. DSSQueryEditor..Pager..Dimensions..SelectAllFields..Caption +#: Decision Cube/MXDSSQRY.DFM:132 +msgid "All &Fields" +msgstr "" + +#. DSSQueryEditor..Pager..Dimensions..TableCombo..Hint +#: Decision Cube/MXDSSQRY.DFM:143 +msgid "Start a new query using a table from the database" +msgstr "" + +#. DSSQueryEditor..Pager..Dimensions..CountStarAvg..Hint +#: Decision Cube/MXDSSQRY.DFM:253 +msgid "Use count(*) to calculate averages (counts null values)" +msgstr "" + +#. DSSQueryEditor..Pager..Dimensions..CountStarAvg..Caption +#: Decision Cube/MXDSSQRY.DFM:254 +msgid "Count (*) for Averages" +msgstr "" + +#. DSSQueryEditor..Pager..Query..Caption +#: Decision Cube/MXDSSQRY.DFM:263 +msgid "SQL Query" +msgstr "" + +#. DSSQueryEditor..Pager..Query..Label1..Caption +#: Decision Cube/MXDSSQRY.DFM:270 +msgid "&Query Text:" +msgstr "" + +#. DSSQueryEditor..Pager..Query..CancelQryMod..Caption +#: Decision Cube/MXDSSQRY.DFM:289 +msgid "&Cancel Edit" +msgstr "" + +#. DSSQueryEditor..Pager..Query..EditQry..Hint +#: Decision Cube/MXDSSQRY.DFM:298 +msgid "Type in the query directly" +msgstr "" + +#. DSSQueryEditor..VQB..Hint +#: Decision Cube/MXDSSQRY.DFM:342 +msgid "Add/Join Tables and Create Field List with SQL Builder" +msgstr "" + +#. DSSQueryEditor..VQB..Caption +#: Decision Cube/MXDSSQRY.DFM:343 +msgid "SQL &Builder ..." +msgstr "Constructor S&QL..." + +#. DSSQueryEditor..AggPopup..count1..Caption +#: Decision Cube/MXDSSQRY.DFM:353 +msgid "&sum" +msgstr "" + +#. DSSQueryEditor..AggPopup..count2..Caption +#: Decision Cube/MXDSSQRY.DFM:357 +msgid "&count" +msgstr "" + +#. DSSQueryEditor..AggPopup..average1..Caption +#: Decision Cube/MXDSSQRY.DFM:361 +msgid "&average" +msgstr "" + +#. ProgressDialog..Caption +#: Decision Cube/MXPBAR.DFM:6 +msgid "ProgressDialog" +msgstr "" + +#. ProgressDialog..CancelButton..Caption +#. DataBindForm..CancelBtn..Caption +#: Decision Cube/MXPBAR.DFM:29 Property Editors/DbOleEdt.dfm:119 +msgid "&Cancel" +msgstr "" + +#. ProgressDialog..StatusText..Caption +#: Decision Cube/MXPBAR.DFM:40 +msgid "StatusText" +msgstr "" + +#. formAbout..Caption +#: Indy/IdAbout.dfm:6 +msgid "formAbout" +msgstr "Referencia" + +#. frmNewMessagePart..Caption +#: Indy/IdDsnNewMessagePart.dfm:5 +msgid "New Message Part" +msgstr "&Nueva parte del mensaje" + +#. frmNewMessagePart..Panel2..btnOk..Caption +#: Indy/IdDsnNewMessagePart.dfm:31 +msgid "Ok" +msgstr "" + +#. frmNewMessagePart..lbTypes....Items.Strings +#: Indy/IdDsnNewMessagePart.dfm:59 +msgid "" +"Attachment\n" +"Text\n" +msgstr "" + +#. StubActionModule......Name +#. WebModule2......Name +#: Internet/StubAction.dfm:6 Internet/SvrInfoModule.dfm:6 +msgid "WebActionItem1" +msgstr "" + +#. Form1..Caption +#: Internet/SvrInfoConsole.dfm:6 +msgid "ServerInfo" +msgstr "" + +#. WebModule2......PathInfo +#: Internet/SvrInfoModule.dfm:7 +msgid "/List" +msgstr "/List" + +#. WebModule2......Name +#: Internet/SvrInfoModule.dfm:11 +msgid "WebActionItem2" +msgstr "" + +#. WebModule2......PathInfo +#: Internet/SvrInfoModule.dfm:12 +msgid "/Clean" +msgstr "/Clean" + +#. WebModule2......Name +#: Internet/SvrInfoModule.dfm:16 +msgid "WebActionItem3" +msgstr "" + +#. WebModule2......PathInfo +#: Internet/SvrInfoModule.dfm:17 +msgid "/Details" +msgstr "/Details" + +#. WebModule2..PageProducerSelect......HTMLDoc.Strings +#: Internet/SvrInfoModule.dfm:71 +msgid "" +"View List | Details\">View Details\n" +msgstr "" +"View List | Details\">View Details\n" + +#. WebModule2..PageProducerSelect....HTMLDoc.Strings +#: Internet/SvrInfoModule.dfm:71 +msgid "<#LIST>" +msgstr "<#LIST>" + +#. WebModule2..PageProducerSelect....HTMLDoc.Strings +#. WebModule2..PageProducerDetails....HTMLDoc.Strings +#: Internet/SvrInfoModule.dfm:72 Internet/SvrInfoModule.dfm:92 +msgid "" +msgstr "" + +#. WebModule2..PageProducerSelect....HTMLDoc.Strings +#. WebModule2..PageProducerDetails....HTMLDoc.Strings +#: Internet/SvrInfoModule.dfm:73 Internet/SvrInfoModule.dfm:93 +msgid "" +msgstr "" + +#. WebModule2..PageProducerSelect....HTMLDoc.Strings +#. WebModule2..PageProducerDetails....HTMLDoc.Strings +#: Internet/SvrInfoModule.dfm:74 Internet/SvrInfoModule.dfm:75 +#: Internet/SvrInfoModule.dfm:76 Internet/SvrInfoModule.dfm:94 +msgid " " +msgstr "" + +#. WebModule2..PageProducerDetails......HTMLDoc.Strings +#: Internet/SvrInfoModule.dfm:91 +msgid "List>View List | View Details\n" +msgstr "List>View List | View Details\n" + +#. WebModule2..PageProducerDetails....HTMLDoc.Strings +#: Internet/SvrInfoModule.dfm:91 +msgid "<#DETAILS>" +msgstr "<#DETAILS>" + +#. LogDetail..Caption +#: Internet/SvrLogDetailDlg.dfm:8 +msgid "LogDetail" +msgstr "" + +#. LogDetail..LogDetailFrame..cbTranslateText..Caption +#: Internet/SvrLogDetailDlg.dfm:60 +msgid "&Translate Post" +msgstr "" + +#. LogDetail..ActionList1..PrevAction..Caption +#. StandardActions..ActionList1..PreviousTab1..Caption +#: Internet/SvrLogDetailDlg.dfm:70 Vcl/ActnRes.dfm:245 +msgid "&Previous" +msgstr "" + +#. LogDetail..ActionList1..NextAction..Caption +#. StandardActions..ActionList1..NextTab1..Caption +#: Internet/SvrLogDetailDlg.dfm:75 Vcl/ActnRes.dfm:251 +msgid "&Next" +msgstr "" + +#. LogDetailFrame..cbTranslateText..Caption +#: Internet/SvrLogDetailFrame.dfm:30 +msgid "&Translate Text" +msgstr "" + +#. LogDetailFrame..cbWrapText..Caption +#: Internet/SvrLogDetailFrame.dfm:40 +msgid "&Wrap Text" +msgstr "" + +#. LogDetailFrame..ActionList1..FontEdit1..Category +#. StandardActions..ActionList1..ColorSelect1..Category +#. StandardActions..ActionList1..FontEdit1..Category +#. StandardActions..ActionList1..OpenPicture1..Category +#. StandardActions..ActionList1..SavePicture1..Category +#. StandardActions..ActionList1..PrintDlg1..Category +#. CustomizeFrm..ActionList1..CloseActn..Category +#: Internet/SvrLogDetailFrame.dfm:49 Vcl/ActnRes.dfm:205 Vcl/ActnRes.dfm:211 +#: Vcl/ActnRes.dfm:223 Vcl/ActnRes.dfm:229 Vcl/ActnRes.dfm:305 +#: Vcl/CustomizeDlg.dfm:392 +msgid "Dialog" +msgstr "" + +#. LogDetailFrame..ActionList1..FontEdit1..Caption +#. StandardActions..ActionList1..FontEdit1..Caption +#: Internet/SvrLogDetailFrame.dfm:50 Vcl/ActnRes.dfm:212 +msgid "Select &Font..." +msgstr "" + +#. LogDetailFrame..ActionList1..FontEdit1..Hint +#. StandardActions..ActionList1..FontEdit1..Hint +#: Internet/SvrLogDetailFrame.dfm:58 Vcl/ActnRes.dfm:220 +msgid "Font Select" +msgstr "" + +#. LogDetailFrame..ActionList1..EditCut1..Caption +#. FieldsEditor..LocalMenu..CutItem..Caption +#. StandardActions..ActionList1..EditCut1..Caption +#: Internet/SvrLogDetailFrame.dfm:63 Property Editors/DSDesign.dfm:141 +#: Vcl/ActnRes.dfm:13 +msgid "Cu&t" +msgstr "" + +#. LogDetailFrame..ActionList1..EditCut1..Hint +#. StandardActions..ActionList1..EditCut1..Hint +#: Internet/SvrLogDetailFrame.dfm:64 Vcl/ActnRes.dfm:14 +msgid "Cut|Cuts the selection and puts it on the Clipboard" +msgstr "" + +#. LogDetailFrame..ActionList1..EditCopy1..Caption +#. FieldsEditor..LocalMenu..CopyItem..Caption +#. StandardActions..ActionList1..EditCopy1..Caption +#: Internet/SvrLogDetailFrame.dfm:70 Property Editors/DSDesign.dfm:147 +#: Vcl/ActnRes.dfm:20 +msgid "&Copy" +msgstr "" + +#. LogDetailFrame..ActionList1..EditCopy1..Hint +#. StandardActions..ActionList1..EditCopy1..Hint +#: Internet/SvrLogDetailFrame.dfm:71 Vcl/ActnRes.dfm:21 +msgid "Copy|Copies the selection and puts it on the Clipboard" +msgstr "" + +#. LogDetailFrame..ActionList1..EditPaste1..Caption +#. FieldsEditor..LocalMenu..PasteItem..Caption +#. StandardActions..ActionList1..EditPaste1..Caption +#: Internet/SvrLogDetailFrame.dfm:77 Property Editors/DSDesign.dfm:153 +#: Vcl/ActnRes.dfm:27 +msgid "&Paste" +msgstr "" + +#. LogDetailFrame..ActionList1..EditPaste1..Hint +#. StandardActions..ActionList1..EditPaste1..Hint +#: Internet/SvrLogDetailFrame.dfm:78 Vcl/ActnRes.dfm:28 +msgid "Paste|Inserts Clipboard contents" +msgstr "" + +#. LogDetailFrame..ActionList1..EditSelectAll1..Caption +#. StandardActions..ActionList1..EditSelectAll1..Caption +#: Internet/SvrLogDetailFrame.dfm:84 Vcl/ActnRes.dfm:73 +msgid "Select &All" +msgstr "" + +#. LogDetailFrame..ActionList1..EditSelectAll1..Hint +#. StandardActions..ActionList1..EditSelectAll1..Hint +#: Internet/SvrLogDetailFrame.dfm:85 Vcl/ActnRes.dfm:74 +msgid "Select All|Selects the entire document" +msgstr "" + +#. LogDetailFrame..ActionList1..EditUndo1..Caption +#. StandardActions..ActionList1..EditUndo1..Caption +#: Internet/SvrLogDetailFrame.dfm:90 Vcl/ActnRes.dfm:79 +msgid "&Undo" +msgstr "" + +#. LogDetailFrame..ActionList1..EditUndo1..Hint +#. StandardActions..ActionList1..EditUndo1..Hint +#: Internet/SvrLogDetailFrame.dfm:91 Vcl/ActnRes.dfm:80 +msgid "Undo|Reverts the last action" +msgstr "" + +#. LogDetailFrame..PopupMenu1..N1..Caption +#. LogDetailFrame..PopupMenu1..N2..Caption +#. WebAppDbgMainForm..MainMenu1..PropertiesItem..N2..Caption +#. WebAppDbgMainForm..MainMenu1..PropertiesItem..N1..Caption +#. CollectionEditor..PopupMenu1..N2..Caption +#. FieldsEditor..LocalMenu..N1..Caption +#. SocketForm..PopupMenu..N1..Caption +#. SocketForm..MainMenu1..miPorts..N3..Caption +#. SocketForm..MainMenu1..Connections1..N2..Caption +#: Internet/SvrLogDetailFrame.dfm:319 Internet/SvrLogDetailFrame.dfm:334 +#: Internet/SvrMainForm.dfm:186 Internet/SvrMainForm.dfm:192 Property +#: Editors/ColnEdit.dfm:183 Editors/DSDesign.dfm:138 Vcl/ScktMain.dfm:323 +#: Vcl/ScktMain.dfm:351 Vcl/ScktMain.dfm:370 +msgid "-" +msgstr "" + +#. LogFrame..ActionList1..DetailAction..Caption +#: Internet/SvrLogFrame.dfm:45 +msgid "&Details..." +msgstr "" + +#. WebAppDbgMainForm..Caption +#. WebAppDbgMainForm..ActionList1..MainUpdateAction..Caption +#: Internet/SvrMainForm.dfm:7 Internet/SvrMainForm.dfm:161 +msgid "MainUpdateAction" +msgstr "" + +#. WebAppDbgMainForm..Label2..Caption +#: Internet/SvrMainForm.dfm:29 +msgid "Default URL:" +msgstr "" + +#. WebAppDbgMainForm..Label1..Caption +#: Internet/SvrMainForm.dfm:47 +msgid "Port:" +msgstr "" + +#. WebAppDbgMainForm..PageControl1..TabSheet2..Caption +#: Internet/SvrMainForm.dfm:77 +msgid "Statistics" +msgstr "" + +#. WebAppDbgMainForm..PageControl1..TabSheet1..Caption +#. DlgProperties..PageControl1..TabLog..Caption +#: Internet/SvrMainForm.dfm:89 Internet/SvrPropDlg.dfm:124 +msgid "Log" +msgstr "" + +#. WebAppDbgMainForm..PageControl1..TabSheet1..GroupBox1..CheckBox1..Caption +#: Internet/SvrMainForm.dfm:121 +msgid "&Log To List" +msgstr "" + +#. WebAppDbgMainForm..ActionList1..ToggleServerAction..Caption +#: Internet/SvrMainForm.dfm:131 +msgid "Toggle" +msgstr "" + +#. WebAppDbgMainForm..ActionList1..ExitAction..Caption +#. StandardActions..ActionList1..FileExit1..Caption +#: Internet/SvrMainForm.dfm:136 Vcl/ActnRes.dfm:103 +msgid "E&xit" +msgstr "Marchar" + +#. WebAppDbgMainForm..ActionList1..StopAction..Caption +#: Internet/SvrMainForm.dfm:140 +msgid "S&top Server" +msgstr "" + +#. WebAppDbgMainForm..ActionList1..StartAction..Caption +#: Internet/SvrMainForm.dfm:145 +msgid "&Start Server" +msgstr "" + +#. WebAppDbgMainForm..ActionList1..AboutAction..Caption +#: Internet/SvrMainForm.dfm:150 +msgid "&About..." +msgstr "&Acerca de..." + +#. WebAppDbgMainForm..ActionList1..PropertiesAction..Caption +#: Internet/SvrMainForm.dfm:154 +msgid "&Options..." +msgstr "" + +#. WebAppDbgMainForm..ActionList1..BrowseAction..Caption +#: Internet/SvrMainForm.dfm:158 +msgid "BrowseAction" +msgstr "" + +#. WebAppDbgMainForm..ActionList1..ToggleLogAction..Caption +#: Internet/SvrMainForm.dfm:169 +msgid "&Log Traffic" +msgstr "" + +#. WebAppDbgMainForm..MainMenu1..PropertiesItem..Caption +#: Internet/SvrMainForm.dfm:178 +msgid "&Server" +msgstr "&Servidor" + +#. DlgProperties..Caption +#. UpdateSQLEditForm..PageControl..FieldsPage..Caption +#. CustomizeFrm..Tabs..OptionsTab..Caption +#. CustomizeFrm..ActionList1..ResetUsageDataActn..Category +#. CustomizeFrm..ActionList1..RecentlyUsedActn..Category +#. CustomizeFrm..ActionList1..FullMenusActn..Category +#. CustomizeFrm..ActionList1..ShowHintsActn..Category +#. CustomizeFrm..ActionList1..ShowShortCutsInTipsActn..Category +#. CustomizeFrm..ActionList1..LargeIconsActn..Category +#: Internet/SvrPropDlg.dfm:6 Property Editors/UpdSqlEd.dfm:54 +#: Vcl/CustomizeDlg.dfm:260 Vcl/CustomizeDlg.dfm:396 Vcl/CustomizeDlg.dfm:401 +#: Vcl/CustomizeDlg.dfm:407 Vcl/CustomizeDlg.dfm:413 Vcl/CustomizeDlg.dfm:420 +#: Vcl/CustomizeDlg.dfm:432 +msgid "Options" +msgstr "" + +#. DlgProperties..PageControl1..TabConnection..Caption +#. frmIBSecurityEditor..GroupBox2..Caption +#. frmIBServiceEditor..GroupBox2..Caption +#: Internet/SvrPropDlg.dfm:52 Vcl/IBSecurityEditor.dfm:23 +#: Vcl/IBServiceEditor.dfm:23 +msgid "Connection" +msgstr "Conexión" + +#. DlgProperties..PageControl1..TabConnection..GroupBox1..Label1..Caption +#: Internet/SvrPropDlg.dfm:68 +msgid "&Port:" +msgstr "" + +#. DlgProperties..PageControl1..TabConnection..GroupBox1..Label2..Caption +#: Internet/SvrPropDlg.dfm:76 +msgid "&Search Path:" +msgstr "" + +#. DlgProperties..PageControl1..TabConnection..GroupBox1..Label3..Caption +#: Internet/SvrPropDlg.dfm:84 +msgid "&Default URL:" +msgstr "" + +#. DlgProperties..PageControl1..TabConnection..GroupBox1..cbPort..Text +#: Internet/SvrPropDlg.dfm:94 +msgid "cbPort" +msgstr "" + +#. DlgProperties..PageControl1..TabConnection..GroupBox1..cbActiveAtStartup..Caption +#: Internet/SvrPropDlg.dfm:102 +msgid "&Activate at Startup" +msgstr "" + +#. DlgProperties..PageControl1..TabConnection..GroupBox1..edDefault..Text +#: Internet/SvrPropDlg.dfm:111 +msgid "edDefault" +msgstr "" + +#. DlgProperties..PageControl1..TabConnection..GroupBox1..edPath..Text +#: Internet/SvrPropDlg.dfm:119 +msgid "edPath" +msgstr "" + +#. DlgProperties..PageControl1..TabLog..GroupBox2..Caption +#: Internet/SvrPropDlg.dfm:135 +msgid "Show in Log" +msgstr "" + +#. DlgProperties..PageControl1..TabLog..GroupBox6..Caption +#: Internet/SvrPropDlg.dfm:159 +msgid " Log Size " +msgstr "" + +#. DlgProperties..PageControl1..TabLog..GroupBox6..Label4..Caption +#: Internet/SvrPropDlg.dfm:170 +msgid "Max Events:" +msgstr "" + +#. DlgProperties..PageControl1..TabLog..GroupBox6..Label5..Caption +#: Internet/SvrPropDlg.dfm:178 +msgid "Delete when max exceeded:" +msgstr "" + +#. DlgProperties..PageControl1..TabLog..GroupBox6..edLogMax..Text +#: Internet/SvrPropDlg.dfm:187 +msgid "edLogMax" +msgstr "" + +#. StatsFrame..GroupBox1..Label3..Caption +#: Internet/SvrStatsFrame.dfm:46 +msgid "RequestCount:" +msgstr "" + +#. StatsFrame..GroupBox1..Label5..Caption +#: Internet/SvrStatsFrame.dfm:53 +msgid "Total Response Time:" +msgstr "" + +#. StatsFrame..GroupBox1..Label7..Caption +#: Internet/SvrStatsFrame.dfm:60 +msgid "Avg Response Time:" +msgstr "" + +#. StatsFrame..GroupBox1..Label8..Caption +#: Internet/SvrStatsFrame.dfm:67 +msgid "Last Response Time:" +msgstr "" + +#. StatsFrame..GroupBox1..Label1..Caption +#: Internet/SvrStatsFrame.dfm:74 +msgid "Min Response Time:" +msgstr "Tiempo mín. de respuesta:" + +#. StatsFrame..GroupBox1..Label2..Caption +#: Internet/SvrStatsFrame.dfm:81 +msgid "Max Response Time:" +msgstr "Tiempo max. de respuesta:" + +#. StatsFrame..ActionList1..ResetCountsAction..Caption +#: Internet/SvrStatsFrame.dfm:110 +msgid "&Reset" +msgstr "Reinicializar" + +#. AboutBox..Caption +#: Internet/WebAppDbgAbout.dfm:5 +msgid "About Web App Debugger" +msgstr "" + +#. AboutBox..Label3..Caption +#: Internet/WebAppDbgAbout.dfm:29 +msgid "Memory Available to Windows:" +msgstr "" + +#. AboutBox..OS..Caption +#: Internet/WebAppDbgAbout.dfm:47 +msgid "OS" +msgstr "" + +#. AboutBox..DetailsPanel..Version..Caption +#: Internet/WebAppDbgAbout.dfm:94 +msgid "Version 6.0" +msgstr "Versión 6.0" + +#. AboutBox..DetailsPanel..SKUName..Caption +#: Internet/WebAppDbgAbout.dfm:108 +msgid "Web Application Debugger" +msgstr "" + +#. AboutBox..DetailsPanel..CompanyName..Caption +#: Internet/WebAppDbgAbout.dfm:297 +msgid "Borland Software Corporation" +msgstr "" + +#. ConnEditForm..SourceofConnection..Caption +#: Property Editors/AdoConEd.dfm:49 +msgid " Source of Connection " +msgstr "" + +#. ConnEditForm..SourceofConnection..UseDataLinkFile..Caption +#: Property Editors/AdoConEd.dfm:57 +msgid "Use Data &Link File" +msgstr "" + +#. ConnEditForm..SourceofConnection..Browse..Caption +#: Property Editors/AdoConEd.dfm:77 +msgid "&Browse..." +msgstr "" + +#. ConnEditForm..SourceofConnection..UseConnectionString..Caption +#: Property Editors/AdoConEd.dfm:87 +msgid "Use &Connection String" +msgstr "Usar cadena de conexión" + +#. ConnEditForm..SourceofConnection..Build..Caption +#: Property Editors/AdoConEd.dfm:105 +msgid "B&uild..." +msgstr "Construir..." + +#. ClientDataForm..Caption +#: Property Editors/CDSEdit.dfm:6 +msgid "Client DataSet Data" +msgstr "" + +#. ClientDataForm..GroupBox1..Caption +#: Property Editors/CDSEdit.dfm:19 +msgid " Assign Data From " +msgstr "" + +#. CollectionEditor..Caption +#: Property Editors/ColnEdit.dfm:10 +msgid "CollectionEditor" +msgstr "" + +#. CollectionEditor..ToolBar1..ToolButton3..Caption +#: Property Editors/ColnEdit.dfm:41 +#, fuzzy +msgid "ToolButton3" +msgstr "Más botones" + +#. CollectionEditor..ActionList1..AddCmd..Hint +#: Property Editors/ColnEdit.dfm:190 +msgid "Add New" +msgstr "" + +#. CollectionEditor..ActionList1..DeleteCmd..Hint +#: Property Editors/ColnEdit.dfm:198 +msgid "Delete Selected" +msgstr "" + +#. CollectionEditor..ActionList1..MoveUpCmd..Caption +#: Property Editors/ColnEdit.dfm:205 +msgid "Move &Up" +msgstr "" + +#. CollectionEditor..ActionList1..MoveUpCmd..Hint +#: Property Editors/ColnEdit.dfm:207 +msgid "Move Selected Up" +msgstr "" + +#. CollectionEditor..ActionList1..MoveDownCmd..Caption +#: Property Editors/ColnEdit.dfm:214 +msgid "Move Dow&n" +msgstr "" + +#. CollectionEditor..ActionList1..MoveDownCmd..Hint +#: Property Editors/ColnEdit.dfm:216 +msgid "Move Selected Down" +msgstr "" + +#. CollectionEditor..ActionList1..SelectAllCmd..Caption +#. UpdateSQLEditForm..FieldListPopup..miSelectAll..Caption +#. StandardActions..ActionList1..ListControlSelectAll1..Caption +#: Property Editors/ColnEdit.dfm:223 Editors/UpdSqlEd.dfm:210 +#: Vcl/ActnRes.dfm:276 +msgid "&Select All" +msgstr "" + +#. DBEditForm..GroupBox1..Caption +#: Property Editors/Dbedit.dfm:18 +msgid " Database " +msgstr "Base de datos" + +#. DBEditForm..GroupBox1..Label1..Caption +#: Property Editors/Dbedit.dfm:25 +msgid "&Alias name:" +msgstr "" + +#. DBEditForm..GroupBox1..Label2..Caption +#: Property Editors/Dbedit.dfm:33 +msgid "&Driver name:" +msgstr "Nombre del dispositivo:" + +#. DBEditForm..GroupBox1..Label3..Caption +#: Property Editors/Dbedit.dfm:41 +msgid "&Parameter overrides:" +msgstr "" + +#. DBEditForm..GroupBox1..Label4..Caption +#. DefineField..FieldGroup..FieldNameLabel..Caption +#: Property Editors/Dbedit.dfm:49 Editors/DSDefine.dfm:154 +msgid "&Name:" +msgstr "" + +#. DBEditForm..GroupBox1..DefaultsButton..Caption +#: Property Editors/Dbedit.dfm:90 +msgid "D&efaults" +msgstr "" + +#. DBEditForm..GroupBox3..LoginPrompt..Caption +#: Property Editors/Dbedit.dfm:123 +msgid "&Login prompt" +msgstr "" + +#. DBEditForm..GroupBox3..KeepConnection..Caption +#: Property Editors/Dbedit.dfm:131 +msgid "&Keep inactive connection" +msgstr "Mantener la conexión inactiva" + +#. InputReqDialog..Caption +#: Property Editors/dbinpreq.dfm:6 +msgid "Input Requested" +msgstr "Entrada esperada" + +#. InputReqDialog..NoPromptAgain..Caption +#: Property Editors/dbinpreq.dfm:48 +msgid "Don't Prompt Again" +msgstr "" + +#. DataBindForm..Caption +#: Property Editors/DbOleEdt.dfm:6 +msgid "ActiveX Control Data Bindings Editor" +msgstr "" + +#. DataBindForm..Panel1..Label1..Caption +#: Property Editors/DbOleEdt.dfm:29 +msgid "&Property Name:" +msgstr "" + +#. DataBindForm..Panel1..Label2..Caption +#: Property Editors/DbOleEdt.dfm:37 +msgid "&Field Name:" +msgstr "" + +#. DataBindForm..Panel1..Label3..Caption +#: Property Editors/DbOleEdt.dfm:45 +msgid "Bo&und Properties to Fields:" +msgstr "" + +#. DataBindForm..Panel1..BindBtn..Caption +#: Property Editors/DbOleEdt.dfm:73 +msgid "<- &Bind ->" +msgstr "" + +#. DataBindForm..Panel1..ClearBtn..Caption +#: Property Editors/DbOleEdt.dfm:99 +msgid "C&lear" +msgstr "" + +#. AddFields..GroupBox1..Caption +#: Property Editors/DSAdd.dfm:46 +msgid "Available fields" +msgstr "" + +#. AssociateAttributes..Caption +#: Property Editors/DSAttrA.dfm:5 +msgid "Associate attributes" +msgstr "" + +#. AssociateAttributes..GroupBox1..Caption +#: Property Editors/DSAttrA.dfm:51 +msgid "Attribute set name" +msgstr "" + +#. SaveAttributesAs..Caption +#: Property Editors/DSAttrS.dfm:5 +msgid "Save %s attributes as" +msgstr "" + +#. SaveAttributesAs..Label1..Caption +#: Property Editors/DSAttrS.dfm:25 +msgid "&Attribute set name:" +msgstr "" + +#. SaveAttributesAs..Label2..Caption +#: Property Editors/DSAttrS.dfm:33 +msgid "&Based on:" +msgstr "" + +#. DefineField..Caption +#: Property Editors/DSDefine.dfm:5 +msgid "New Field" +msgstr "" + +#. DefineField..LookupGroup..Caption +#: Property Editors/DSDefine.dfm:20 +msgid "Lookup definition" +msgstr "" + +#. DefineField..LookupGroup..DatasetLabel..Caption +#: Property Editors/DSDefine.dfm:27 +msgid "D&ataset:" +msgstr "" + +#. DefineField..LookupGroup..KeyFieldsLabel..Caption +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label3..Caption +#: Property Editors/DSDefine.dfm:36 Editors/UpdSqlEd.dfm:75 +msgid "&Key Fields:" +msgstr "" + +#. DefineField..LookupGroup..LookupKeysLabel..Caption +#: Property Editors/DSDefine.dfm:45 +msgid "Look&up Keys:" +msgstr "" + +#. DefineField..LookupGroup..ResultFieldLabel..Caption +#: Property Editors/DSDefine.dfm:54 +msgid "&Result Field:" +msgstr "" + +#. DefineField..FieldGroup..Caption +#: Property Editors/DSDefine.dfm:139 +msgid "Field properties" +msgstr "" + +#. DefineField..FieldGroup..ComponentNameLabel..Caption +#: Property Editors/DSDefine.dfm:146 +msgid "C&omponent:" +msgstr "" + +#. DefineField..FieldGroup..FieldTypeLabel..Caption +#: Property Editors/DSDefine.dfm:162 +msgid "&Type:" +msgstr "" + +#. DefineField..FieldGroup..SizeEditLabel..Caption +#: Property Editors/DSDefine.dfm:170 +msgid "&Size:" +msgstr "" + +#. DefineField..FieldKind..Caption +#: Property Editors/DSDefine.dfm:216 +msgid "Field type" +msgstr "" + +#. DefineField..FieldKind....Items.Strings +#: Property Editors/DSDefine.dfm:223 +msgid "" +"&Data\n" +"&Calculated\n" +"&Lookup\n" +msgstr "" + +#. FieldsEditor..FieldListBox..Hint +#: Property Editors/DSDesign.dfm:81 +msgid "Fields" +msgstr "" + +#. FieldsEditor..AggListBox..Hint +#: Property Editors/DSDesign.dfm:100 +msgid "Aggregates" +msgstr "" + +#. FieldsEditor..LocalMenu..AddItem..Caption +#: Property Editors/DSDesign.dfm:121 +msgid "&Add fields..." +msgstr "" + +#. FieldsEditor..LocalMenu..NewItem..Caption +#: Property Editors/DSDesign.dfm:127 +msgid "&New field..." +msgstr "" + +#. FieldsEditor..LocalMenu..Addallfields1..Caption +#: Property Editors/DSDesign.dfm:133 +msgid "Add all &fields" +msgstr "" + +#. FieldsEditor..LocalMenu..SelectAllItem..Caption +#: Property Editors/DSDesign.dfm:165 +msgid "Se&lect all" +msgstr "" + +#. LinkFields..Caption +#: Property Editors/FldLinks.DFM:6 +msgid "Field Link Designer" +msgstr "" + +#. LinkFields..Label30..Caption +#: Property Editors/FldLinks.DFM:35 +msgid "D&etail Fields" +msgstr "" + +#. LinkFields..Label31..Caption +#: Property Editors/FldLinks.DFM:44 +msgid "&Master Fields" +msgstr "" + +#. LinkFields..IndexLabel..Caption +#: Property Editors/FldLinks.DFM:53 +msgid "A&vailable Indexes" +msgstr "" + +#. LinkFields..Label2..Caption +#: Property Editors/FldLinks.DFM:61 +msgid "&Joined Fields" +msgstr "" + +#. IndexFiles..Caption +#. IndexFiles..GroupBox1..Caption +#: Property Editors/Ixedit.dfm:5 Editors/Ixedit.dfm:17 +msgid "Index Files" +msgstr "Archivos del índice" + +#. IndexFiles..OpenDialog....OnClick +#: Property Editors/Ixedit.dfm:92 +msgid "" +"dBASE Multiple Index (*.MDX)|*.mdx|dBase Index (*.NDX)|*.ndx|FoxPro Index (*." +"CDX)|*.cdx\n" +msgstr "" + +#. PictureEditorDlg..OpenDialog....OnClick +#. PictureEditorDlg..SaveDialog....Top +#: Property Editors/PicEdit.dfm:104 Editors/PicEdit.dfm:112 +msgid "" +"All (*.bmp;*.ico;*.emf;*.wmf)|*.bmp;*.ico;*.emf;*.wmf|Bitmaps (*.bmp)|*.bmp|" +"Icons (*.ico)|*.ico|Enhanced Metafiles (*.emf)|*.emf|Metafiles (*.wmf)|*." +"wmf\n" +msgstr "" + +#. SQLEditForm..Caption +#: Property Editors/SqlEdit.dfm:5 +msgid "CommandText Editor" +msgstr "Editor del CommandText" + +#. SQLEditForm..TopPanel..TableListLabel..Caption +#: Property Editors/SqlEdit.dfm:52 +msgid "&Tables:" +msgstr "" + +#. SQLEditForm..TopPanel..SQLLabel..Caption +#: Property Editors/SqlEdit.dfm:60 +msgid "&SQL:" +msgstr "" + +#. SQLEditForm..MetaInfoPanel..TableListPanel..AddTableButton..Caption +#: Property Editors/SqlEdit.dfm:165 +msgid "Add T&able to SQL" +msgstr "" + +#. SQLEditForm..MetaInfoPanel..FieldsPanel..FieldListLabel..Caption +#: Property Editors/SqlEdit.dfm:183 +msgid "&Fields:" +msgstr "" + +#. SQLEditForm..MetaInfoPanel..FieldsPanel..AddFieldButton..Caption +#: Property Editors/SqlEdit.dfm:203 +msgid "Add F&ield to SQL" +msgstr "" + +#. StrEditDlg..Caption +#: Property Editors/StrEdit.dfm:5 +msgid "String List Editor" +msgstr "" + +#. StrEditDlg..CodeWndBtn..Caption +#. StrEditDlg..StringEditorMenu..CodeEditorItem..Caption +#: Property Editors/StrEdit.dfm:20 Editors/StrEdit.dfm:84 +msgid "&Code Editor..." +msgstr "Editor de &código..." + +#. StrEditDlg..OpenDialog..DefaultExt +#: Property Editors/StrEdit.dfm:56 +msgid "TXT" +msgstr "TXT" + +#. StrEditDlg..OpenDialog....DefaultExt +#. StrEditDlg..SaveDialog....HelpContext +#: Property Editors/StrEdit.dfm:60 Editors/StrEdit.dfm:69 +msgid "" +"Text files (*.TXT)|*.TXT|Config files (*.SYS;*.INI)|*.SYS;*.INI|Batch files " +"(*.BAT)|*.BAT|All files (*.*)|*.*\n" +msgstr "" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Caption +#: Property Editors/UpdSqlEd.dfm:60 +msgid " SQL Generation " +msgstr "" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label1..Caption +#: Property Editors/UpdSqlEd.dfm:67 +msgid "Table &Name:" +msgstr "" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label4..Caption +#: Property Editors/UpdSqlEd.dfm:83 +msgid "Update &Fields:" +msgstr "Actualiza campos:" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..GenerateButton..Caption +#: Property Editors/UpdSqlEd.dfm:123 +msgid "&Generate SQL" +msgstr "" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..PrimaryKeyButton..Caption +#: Property Editors/UpdSqlEd.dfm:132 +msgid "Select &Primary Keys" +msgstr "" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..DefaultButton..Caption +#: Property Editors/UpdSqlEd.dfm:141 +msgid "&Dataset Defaults" +msgstr "" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..QuoteFields..Caption +#: Property Editors/UpdSqlEd.dfm:151 +msgid "&Quote Field Names" +msgstr "" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..GetTableFieldsButton..Caption +#: Property Editors/UpdSqlEd.dfm:160 +msgid "Get &Table Fields" +msgstr "" + +#. UpdateSQLEditForm..PageControl..SQLPage..Caption +#: Property Editors/UpdSqlEd.dfm:167 +msgid "SQL" +msgstr "" + +#. UpdateSQLEditForm..PageControl..SQLPage..Label2..Caption +#: Property Editors/UpdSqlEd.dfm:173 +msgid "S&QL Text:" +msgstr "" + +#. UpdateSQLEditForm..PageControl..SQLPage..StatementType..Caption +#: Property Editors/UpdSqlEd.dfm:190 +msgid "Statement Type" +msgstr "" + +#. UpdateSQLEditForm..PageControl..SQLPage..StatementType....Items.Strings +#: Property Editors/UpdSqlEd.dfm:197 +msgid "" +"&Modify\n" +"&Insert\n" +"&Delete\n" +msgstr "" + +#. UpdateSQLEditForm..FieldListPopup..miClearAll..Caption +#: Property Editors/UpdSqlEd.dfm:214 +msgid "&Clear All" +msgstr "" + +#. ValueEditDlg..Caption +#: Property Editors/ValueEdit.dfm:4 +msgid "Value List editor" +msgstr "" + +#. StandardActions..ActionList1..WindowArrange1..Category +#. StandardActions..ActionList1..WindowCascade1..Category +#. StandardActions..ActionList1..WindowClose1..Category +#. StandardActions..ActionList1..WindowMinimizeAll1..Category +#. StandardActions..ActionList1..WindowTileHorizontal1..Category +#. StandardActions..ActionList1..WindowTileVertical1..Category +#: Vcl/ActnRes.dfm:33 Vcl/ActnRes.dfm:37 Vcl/ActnRes.dfm:43 +#: Vcl/ActnRes.dfm:48 Vcl/ActnRes.dfm:53 Vcl/ActnRes.dfm:59 +msgid "Window" +msgstr "" + +#. StandardActions..ActionList1..WindowArrange1..Caption +#: Vcl/ActnRes.dfm:34 +msgid "&Arrange" +msgstr "" + +#. StandardActions..ActionList1..WindowCascade1..Caption +#: Vcl/ActnRes.dfm:38 +msgid "&Cascade" +msgstr "" + +#. StandardActions..ActionList1..WindowCascade1..Hint +#: Vcl/ActnRes.dfm:39 +msgid "Cascade" +msgstr "" + +#. StandardActions..ActionList1..WindowClose1..Caption +#: Vcl/ActnRes.dfm:44 +msgid "C&lose" +msgstr "" + +#. StandardActions..ActionList1..WindowClose1..Hint +#. CustomizeFrm..CloseBtn..Caption +#. CustomizeFrm..ActionList1..CloseActn..Caption +#: Vcl/ActnRes.dfm:45 Vcl/CustomizeDlg.dfm:35 Vcl/CustomizeDlg.dfm:393 +msgid "Close" +msgstr "" + +#. StandardActions..ActionList1..WindowMinimizeAll1..Caption +#: Vcl/ActnRes.dfm:49 +msgid "&Minimize All" +msgstr "" + +#. StandardActions..ActionList1..WindowMinimizeAll1..Hint +#: Vcl/ActnRes.dfm:50 +msgid "Minimize All" +msgstr "" + +#. StandardActions..ActionList1..WindowTileHorizontal1..Caption +#: Vcl/ActnRes.dfm:54 +msgid "Tile &Horizontally" +msgstr "" + +#. StandardActions..ActionList1..WindowTileHorizontal1..Hint +#: Vcl/ActnRes.dfm:55 +msgid "Tile Horizontal" +msgstr "" + +#. StandardActions..ActionList1..WindowTileVertical1..Caption +#: Vcl/ActnRes.dfm:60 +msgid "&Tile Vertically" +msgstr "" + +#. StandardActions..ActionList1..WindowTileVertical1..Hint +#: Vcl/ActnRes.dfm:61 +msgid "Tile Vertical" +msgstr "" + +#. StandardActions..ActionList1..EditDelete1..Hint +#: Vcl/ActnRes.dfm:67 +msgid "Delete|Erases the selection" +msgstr "" + +#. StandardActions..ActionList1..HelpContents1..Caption +#: Vcl/ActnRes.dfm:86 +msgid "&Contents" +msgstr "&Contenido" + +#. StandardActions..ActionList1..HelpContents1..Hint +#: Vcl/ActnRes.dfm:87 +msgid "Help Contents" +msgstr "Contenidos de la ayuda" + +#. StandardActions..ActionList1..HelpOnHelp1..Caption +#: Vcl/ActnRes.dfm:92 +msgid "&Help on Help" +msgstr "" + +#. StandardActions..ActionList1..HelpOnHelp1..Hint +#: Vcl/ActnRes.dfm:93 +msgid "Help on help" +msgstr "" + +#. StandardActions..ActionList1..HelpTopicSearch1..Caption +#: Vcl/ActnRes.dfm:97 +msgid "&Topic Search" +msgstr "" + +#. StandardActions..ActionList1..HelpTopicSearch1..Hint +#: Vcl/ActnRes.dfm:98 +msgid "Topic Search" +msgstr "" + +#. StandardActions..ActionList1..FileExit1..Category +#. StandardActions..ActionList1..FileOpen1..Category +#. StandardActions..ActionList1..FilePrintSetup1..Category +#. StandardActions..ActionList1..FileSaveAs1..Category +#. StandardActions..ActionList1..FileRun1..Category +#: Vcl/ActnRes.dfm:102 Vcl/ActnRes.dfm:108 Vcl/ActnRes.dfm:115 +#: Vcl/ActnRes.dfm:120 Vcl/ActnRes.dfm:235 +msgid "File" +msgstr "" + +#. StandardActions..ActionList1..FileExit1..Hint +#: Vcl/ActnRes.dfm:104 +msgid "Exit|Quits the application" +msgstr "Marchar|Salir de la aplicación" + +#. StandardActions..ActionList1..FileOpen1..Caption +#: Vcl/ActnRes.dfm:109 +msgid "&Open..." +msgstr "" + +#. StandardActions..ActionList1..FileOpen1..Hint +#: Vcl/ActnRes.dfm:110 +msgid "Open|Opens an existing file" +msgstr "" + +#. StandardActions..ActionList1..FilePrintSetup1..Caption +#: Vcl/ActnRes.dfm:116 +msgid "Print Set&up..." +msgstr "" + +#. StandardActions..ActionList1..FilePrintSetup1..Hint +#: Vcl/ActnRes.dfm:117 +msgid "Print Setup" +msgstr "" + +#. StandardActions..ActionList1..FileSaveAs1..Caption +#: Vcl/ActnRes.dfm:121 +msgid "Save &As..." +msgstr "" + +#. StandardActions..ActionList1..FileSaveAs1..Hint +#: Vcl/ActnRes.dfm:122 +msgid "Save As|Saves the active file with a new name" +msgstr "" + +#. StandardActions..ActionList1..RichEditBold1..Category +#. StandardActions..ActionList1..RichEditItalic1..Category +#. StandardActions..ActionList1..RichEditUnderline1..Category +#. StandardActions..ActionList1..RichEditAlignCenter1..Category +#. StandardActions..ActionList1..RichEditAlignLeft1..Category +#. StandardActions..ActionList1..RichEditAlignRight1..Category +#. StandardActions..ActionList1..RichEditBullets1..Category +#. StandardActions..ActionList1..RichEditStrikeOut1..Category +#: Vcl/ActnRes.dfm:126 Vcl/ActnRes.dfm:134 Vcl/ActnRes.dfm:142 +#: Vcl/ActnRes.dfm:170 Vcl/ActnRes.dfm:177 Vcl/ActnRes.dfm:184 +#: Vcl/ActnRes.dfm:191 Vcl/ActnRes.dfm:198 +msgid "Format" +msgstr "" + +#. StandardActions..ActionList1..RichEditBold1..Caption +#: Vcl/ActnRes.dfm:128 +msgid "&Bold" +msgstr "" + +#. StandardActions..ActionList1..RichEditItalic1..Caption +#: Vcl/ActnRes.dfm:136 +msgid "&Italic" +msgstr "" + +#. StandardActions..ActionList1..RichEditUnderline1..Caption +#: Vcl/ActnRes.dfm:144 +msgid "&Underline" +msgstr "" + +#. StandardActions..ActionList1..RichEditUnderline1..Hint +#: Vcl/ActnRes.dfm:145 +msgid "Underline" +msgstr "" + +#. StandardActions..ActionList1..SearchFind1..Category +#. StandardActions..ActionList1..SearchFindNext1..Category +#. StandardActions..ActionList1..SearchReplace1..Category +#. StandardActions..ActionList1..SearchFindFirst1..Category +#: Vcl/ActnRes.dfm:150 Vcl/ActnRes.dfm:157 Vcl/ActnRes.dfm:164 +#: Vcl/ActnRes.dfm:255 +msgid "Search" +msgstr "" + +#. StandardActions..ActionList1..SearchFind1..Caption +#: Vcl/ActnRes.dfm:151 +msgid "&Find..." +msgstr "" + +#. StandardActions..ActionList1..SearchFind1..Hint +#: Vcl/ActnRes.dfm:152 +msgid "Find|Finds the specified text" +msgstr "Encontrar|Encuentra el texto especificado" + +#. StandardActions..ActionList1..SearchFindNext1..Caption +#: Vcl/ActnRes.dfm:158 +msgid "Find &Next" +msgstr "" + +#. StandardActions..ActionList1..SearchFindNext1..Hint +#: Vcl/ActnRes.dfm:159 +msgid "Find Next|Repeats the last find" +msgstr "" + +#. StandardActions..ActionList1..SearchReplace1..Hint +#: Vcl/ActnRes.dfm:166 +msgid "Replace|Replaces specific text with different text" +msgstr "" + +#. StandardActions..ActionList1..RichEditAlignCenter1..Caption +#: Vcl/ActnRes.dfm:172 +msgid "&Center" +msgstr "" + +#. StandardActions..ActionList1..RichEditAlignCenter1..Hint +#: Vcl/ActnRes.dfm:173 +msgid "Center|Centers text between margins" +msgstr "" + +#. StandardActions..ActionList1..RichEditAlignLeft1..Caption +#: Vcl/ActnRes.dfm:179 +msgid "Align &Left" +msgstr "" + +#. StandardActions..ActionList1..RichEditAlignLeft1..Hint +#: Vcl/ActnRes.dfm:180 +msgid "Align Left|Aligns text at the left indent" +msgstr "" + +#. StandardActions..ActionList1..RichEditAlignRight1..Caption +#: Vcl/ActnRes.dfm:186 +msgid "Align &Right" +msgstr "" + +#. StandardActions..ActionList1..RichEditAlignRight1..Hint +#: Vcl/ActnRes.dfm:187 +msgid "Align Right|Aligns text at the right indent" +msgstr "" + +#. StandardActions..ActionList1..RichEditBullets1..Caption +#: Vcl/ActnRes.dfm:193 +msgid "&Bullets" +msgstr "" + +#. StandardActions..ActionList1..RichEditBullets1..Hint +#: Vcl/ActnRes.dfm:194 +msgid "Bullets|Inserts a bullet on the current line" +msgstr "" + +#. StandardActions..ActionList1..RichEditStrikeOut1..Caption +#: Vcl/ActnRes.dfm:200 +msgid "&Strikeout" +msgstr "" + +#. StandardActions..ActionList1..RichEditStrikeOut1..Hint +#: Vcl/ActnRes.dfm:201 +msgid "Strikeout" +msgstr "" + +#. StandardActions..ActionList1..ColorSelect1..Caption +#: Vcl/ActnRes.dfm:206 +msgid "Select &Color..." +msgstr "" + +#. StandardActions..ActionList1..ColorSelect1..Hint +#: Vcl/ActnRes.dfm:208 +msgid "Color Select" +msgstr "" + +#. StandardActions..ActionList1..OpenPicture1..Caption +#: Vcl/ActnRes.dfm:224 +msgid "&Open Picture..." +msgstr "" + +#. StandardActions..ActionList1..OpenPicture1..Hint +#: Vcl/ActnRes.dfm:225 +msgid "Open Picture" +msgstr "" + +#. StandardActions..ActionList1..SavePicture1..Caption +#: Vcl/ActnRes.dfm:230 +msgid "&Save Picture..." +msgstr "" + +#. StandardActions..ActionList1..SavePicture1..Hint +#: Vcl/ActnRes.dfm:231 +msgid "Save Picture" +msgstr "" + +#. StandardActions..ActionList1..FileRun1..Caption +#: Vcl/ActnRes.dfm:238 +msgid "&Run..." +msgstr "" + +#. StandardActions..ActionList1..FileRun1..Hint +#: Vcl/ActnRes.dfm:239 +msgid "Run|Runs an application" +msgstr "" + +#. StandardActions..ActionList1..FileRun1..Operation +#: Vcl/ActnRes.dfm:240 +msgid "open" +msgstr "" + +#. StandardActions..ActionList1..PreviousTab1..Hint +#: Vcl/ActnRes.dfm:246 +msgid "Previous|Go back to the previous tab" +msgstr "" + +#. StandardActions..ActionList1..NextTab1..LastTabCaption +#: Vcl/ActnRes.dfm:250 +msgid "&Finish" +msgstr "" + +#. StandardActions..ActionList1..NextTab1..Hint +#: Vcl/ActnRes.dfm:252 +msgid "Next|Go to the next tab" +msgstr "" + +#. StandardActions..ActionList1..SearchFindFirst1..Caption +#: Vcl/ActnRes.dfm:256 +msgid "F&ind First" +msgstr "" + +#. StandardActions..ActionList1..SearchFindFirst1..Hint +#: Vcl/ActnRes.dfm:257 +msgid "Find First|Finds the first occurance of specified text" +msgstr "" + +#. StandardActions..ActionList1..HelpContextAction1..Caption +#: Vcl/ActnRes.dfm:261 +#, fuzzy +msgid "HelpContextAction1" +msgstr "Contenidos de la ayuda" + +#. StandardActions..ActionList1..ListControlCopySelection1..Category +#. StandardActions..ActionList1..ListControlDeleteSelection1..Category +#. StandardActions..ActionList1..ListControlSelectAll1..Category +#. StandardActions..ActionList1..ListControlClearSelection1..Category +#. StandardActions..ActionList1..ListControlMoveSelection1..Category +#: Vcl/ActnRes.dfm:265 Vcl/ActnRes.dfm:270 Vcl/ActnRes.dfm:275 +#: Vcl/ActnRes.dfm:280 Vcl/ActnRes.dfm:285 +msgid "List" +msgstr "" + +#. StandardActions..ActionList1..ListControlCopySelection1..Caption +#: Vcl/ActnRes.dfm:266 +msgid "&Copy Selection" +msgstr "" + +#. StandardActions..ActionList1..ListControlCopySelection1..Hint +#: Vcl/ActnRes.dfm:267 +msgid "Copy Selection" +msgstr "" + +#. StandardActions..ActionList1..ListControlDeleteSelection1..Caption +#: Vcl/ActnRes.dfm:271 +msgid "&Delete Selection" +msgstr "" + +#. StandardActions..ActionList1..ListControlDeleteSelection1..Hint +#: Vcl/ActnRes.dfm:272 +msgid "Delete Selection" +msgstr "" + +#. StandardActions..ActionList1..ListControlClearSelection1..Caption +#. StandardActions..ActionList1..ListControlClearSelection1..Hint +#: Vcl/ActnRes.dfm:281 Vcl/ActnRes.dfm:282 +msgid "Clear Selection" +msgstr "" + +#. StandardActions..ActionList1..ListControlMoveSelection1..Caption +#: Vcl/ActnRes.dfm:286 +msgid "&Move Selection" +msgstr "" + +#. StandardActions..ActionList1..ListControlMoveSelection1..Hint +#: Vcl/ActnRes.dfm:287 +msgid "Move Selection" +msgstr "" + +#. StandardActions..ActionList1..BrowseURL1..Category +#. StandardActions..ActionList1..DownLoadURL1..Category +#. StandardActions..ActionList1..SendMail1..Category +#: Vcl/ActnRes.dfm:290 Vcl/ActnRes.dfm:295 Vcl/ActnRes.dfm:300 +msgid "Internet" +msgstr "" + +#. StandardActions..ActionList1..BrowseURL1..Caption +#: Vcl/ActnRes.dfm:291 +msgid "&Browse URL" +msgstr "" + +#. StandardActions..ActionList1..BrowseURL1..Hint +#: Vcl/ActnRes.dfm:292 +msgid "Browse URL" +msgstr "" + +#. StandardActions..ActionList1..DownLoadURL1..Caption +#: Vcl/ActnRes.dfm:296 +msgid "&Download URL" +msgstr "" + +#. StandardActions..ActionList1..DownLoadURL1..Hint +#: Vcl/ActnRes.dfm:297 +msgid "Download from URL" +msgstr "" + +#. StandardActions..ActionList1..SendMail1..Caption +#: Vcl/ActnRes.dfm:301 +msgid "&Send Mail..." +msgstr "" + +#. StandardActions..ActionList1..SendMail1..Hint +#: Vcl/ActnRes.dfm:302 +msgid "Send email" +msgstr "" + +#. StandardActions..ActionList1..PrintDlg1..Caption +#: Vcl/ActnRes.dfm:306 +msgid "&Print..." +msgstr "" + +#. CustomizeFrm..Caption +#: Vcl/CustomizeDlg.dfm:6 +msgid "Customize" +msgstr "" + +#. CustomizeFrm..Font.Name +#: Vcl/CustomizeDlg.dfm:15 +#, fuzzy +msgid "Tahoma" +msgstr "Brazas" + +#. CustomizeFrm..Tabs..ToolbarsTab..Caption +#. CustomizeFrm..ActionList1..ResetActn..Category +#. CustomizeFrm..ActionList1..ApplyToAllActn..Category +#: Vcl/CustomizeDlg.dfm:52 Vcl/CustomizeDlg.dfm:386 Vcl/CustomizeDlg.dfm:426 +msgid "Toolbars" +msgstr "" + +#. CustomizeFrm..Tabs..ToolbarsTab..ToolbarsLbl..Caption +#: Vcl/CustomizeDlg.dfm:62 +msgid "Toolb&ars:" +msgstr "" + +#. CustomizeFrm..Tabs..ToolbarsTab..Label2..Caption +#: Vcl/CustomizeDlg.dfm:71 +msgid "(Checkmark toggles visibility)" +msgstr "" + +#. CustomizeFrm..Tabs..ToolbarsTab..CaptionOptionsGrp..Caption +#: Vcl/CustomizeDlg.dfm:100 +msgid "&Toolbar Options" +msgstr "" + +#. CustomizeFrm..Tabs..ToolbarsTab..CaptionOptionsGrp..Label4..Caption +#: Vcl/CustomizeDlg.dfm:108 +msgid "&Caption Options" +msgstr "" + +#. CustomizeFrm..Tabs..ToolbarsTab..CaptionOptionsGrp..ApplyToAllChk..Caption +#: Vcl/CustomizeDlg.dfm:116 +msgid "Apply caption options &to all toolbars" +msgstr "" + +#. CustomizeFrm..Tabs..ToolbarsTab..CaptionOptionsGrp..CaptionOptionsCombo....Items.Strings +#: Vcl/CustomizeDlg.dfm:132 +msgid "" +"None\n" +"Selective\n" +"All\n" +msgstr "" + +#. CustomizeFrm..Tabs..ActionsTab..Caption +#: Vcl/CustomizeDlg.dfm:136 +msgid "Actions" +msgstr "" + +#. CustomizeFrm..Tabs..ActionsTab..InfoLbl....AutoSize +#: Vcl/CustomizeDlg.dfm:152 +msgid "" +"To add actions to your application simply drag and drop from either " +"Categories or Actions onto an existing ActionBar.\n" +msgstr "" + +#. CustomizeFrm..Tabs..ActionsTab..ListPanel..ActionsCatLbl..Caption +#: Vcl/CustomizeDlg.dfm:172 +msgid "Cate&gories:" +msgstr "" + +#. CustomizeFrm..Tabs..ActionsTab..ListPanel..ActionsActionsLbl..Caption +#: Vcl/CustomizeDlg.dfm:181 +msgid "A&ctions:" +msgstr "" + +#. CustomizeFrm..Tabs..ActionsTab..DescGroupBox..Caption +#: Vcl/CustomizeDlg.dfm:222 +msgid "Description" +msgstr "" + +#. CustomizeFrm..Tabs..ActionsTab..DescGroupBox..HintLbl..Caption +#: Vcl/CustomizeDlg.dfm:235 +msgid "HintLbl" +msgstr "" + +#. CustomizeFrm..Tabs..OptionsTab..PersonalizeLbl..Caption +#: Vcl/CustomizeDlg.dfm:271 +msgid "Personalized Menus and Toolbars" +msgstr "" + +#. CustomizeFrm..Tabs..OptionsTab..Label1..Caption +#: Vcl/CustomizeDlg.dfm:305 +msgid "&Menu animations:" +msgstr "" + +#. CustomizeFrm..Tabs..OptionsTab..MenuAnimationStyles....Items.Strings +#: Vcl/CustomizeDlg.dfm:365 +msgid "" +"(None)\n" +"Default\n" +"UnFold\n" +"Slide\n" +"Fade\n" +msgstr "" + +#. CustomizeFrm..ActionList1..ResetActn..Caption +#: Vcl/CustomizeDlg.dfm:387 +msgid "&Reset..." +msgstr "" + +#. CustomizeFrm..ActionList1..ResetUsageDataActn..Caption +#: Vcl/CustomizeDlg.dfm:397 +msgid "Reset Usage Data" +msgstr "" + +#. CustomizeFrm..ActionList1..RecentlyUsedActn..Caption +#: Vcl/CustomizeDlg.dfm:402 +msgid "Me&nu show recently used items first" +msgstr "" + +#. CustomizeFrm..ActionList1..FullMenusActn..Caption +#: Vcl/CustomizeDlg.dfm:409 +msgid "Show f&ull menus after a short delay" +msgstr "" + +#. CustomizeFrm..ActionList1..ShowHintsActn..Caption +#: Vcl/CustomizeDlg.dfm:415 +msgid "Show &tips on toolbars" +msgstr "" + +#. CustomizeFrm..ActionList1..ShowShortCutsInTipsActn..Caption +#: Vcl/CustomizeDlg.dfm:422 +msgid "Show shortcut keys in tips" +msgstr "" + +#. CustomizeFrm..ActionList1..ApplyToAllActn..Caption +#: Vcl/CustomizeDlg.dfm:428 +msgid "Apply &to all toolbars" +msgstr "" + +#. CustomizeFrm..ActionList1..LargeIconsActn..Caption +#: Vcl/CustomizeDlg.dfm:434 +msgid "&Large icons" +msgstr "" + +#. LoginDialog..Panel..Panel1..Password..PasswordChar +#. PasswordDialog..GroupBox1..Edit..PasswordChar +#: Vcl/DBLOGDLG.dfm:102 Vcl/DbPWDlg.dfm:47 +msgid "*" +msgstr "" + +#. HTTPServer......Name +#: Vcl/HTTPIntr.dfm:6 +msgid "Interpreter" +msgstr "" + +#. frmGeneratorEditor..Caption +#: Vcl/IBGeneratorEditor.dfm:5 +msgid "frmGeneratorEditor" +msgstr "" + +#. frmGeneratorEditor..Label1..Caption +#: Vcl/IBGeneratorEditor.dfm:25 +msgid "&Generator" +msgstr "" + +#. frmGeneratorEditor..Label2..Caption +#: Vcl/IBGeneratorEditor.dfm:35 +msgid "&Field" +msgstr "" + +#. frmGeneratorEditor..Label3..Caption +#: Vcl/IBGeneratorEditor.dfm:44 +msgid "Increment By" +msgstr "" + +#. frmGeneratorEditor..cbxGenerators..Text +#: Vcl/IBGeneratorEditor.dfm:74 +msgid "cbxGenerators" +msgstr "" + +#. frmGeneratorEditor..cbxFields..Text +#: Vcl/IBGeneratorEditor.dfm:84 +msgid "cbxFields" +msgstr "" + +#. frmGeneratorEditor..grpApplyEvent..Caption +#: Vcl/IBGeneratorEditor.dfm:91 +msgid "&Apply Event" +msgstr "" + +#. frmGeneratorEditor..grpApplyEvent....Items.Strings +#: Vcl/IBGeneratorEditor.dfm:97 +msgid "" +"On New Record\n" +"On Post\n" +"On Server\n" +msgstr "" + +#. frmIBRestoreEditor..Caption +#: Vcl/IBRestoreEditor.dfm:5 +msgid "Restore Database Files" +msgstr "" + +#. frmIBSecurityEditor..Caption +#. frmIBServiceEditor..Caption +#: Vcl/IBSecurityEditor.dfm:6 Vcl/IBServiceEditor.dfm:6 +msgid "Service Editor" +msgstr "" + +#. frmIBSecurityEditor..GroupBox2..Label7..Caption +#. frmIBServiceEditor..GroupBox2..Label7..Caption +#: Vcl/IBSecurityEditor.dfm:30 Vcl/IBServiceEditor.dfm:38 +msgid "&Server:" +msgstr "" + +#. frmIBSecurityEditor..GroupBox2..Label8..Caption +#. frmIBServiceEditor..GroupBox2..Label8..Caption +#: Vcl/IBSecurityEditor.dfm:39 Vcl/IBServiceEditor.dfm:47 +msgid "&Protocol:" +msgstr "" + +#. frmIBSecurityEditor..GroupBox2..LocalRbtn..Caption +#. frmIBServiceEditor..GroupBox2..LocalRbtn..Caption +#: Vcl/IBSecurityEditor.dfm:48 Vcl/IBServiceEditor.dfm:63 +msgid "&Local" +msgstr "" + +#. frmIBSecurityEditor..GroupBox2..RemoteRbtn..Caption +#. frmIBServiceEditor..GroupBox2..RemoteRbtn..Caption +#: Vcl/IBSecurityEditor.dfm:59 Vcl/IBServiceEditor.dfm:74 +msgid "&Remote" +msgstr "" + +#. frmIBSecurityEditor..GroupBox2..Protocol....Items.Strings +#. frmIBServiceEditor..GroupBox2..Protocol....Items.Strings +#: Vcl/IBSecurityEditor.dfm:84 Vcl/IBServiceEditor.dfm:107 +msgid "" +"TCP\n" +"NamedPipe\n" +"SPX\n" +msgstr "" + +#. frmIBSecurityEditor..GroupBox1..Caption +#. frmIBServiceEditor..GroupBox1..Caption +#: Vcl/IBSecurityEditor.dfm:129 Vcl/IBServiceEditor.dfm:152 +msgid "Database Parameters" +msgstr "Parámetros de la base de datos" + +#. frmIBSecurityEditor..GroupBox1..Label3..Caption +#. frmIBServiceEditor..GroupBox1..Label3..Caption +#: Vcl/IBSecurityEditor.dfm:144 Vcl/IBServiceEditor.dfm:167 +msgid "Pass&word:" +msgstr "Contrase&ña: " + +#. frmIBSecurityEditor..GroupBox1..Label5..Caption +#. frmIBServiceEditor..GroupBox1..Label5..Caption +#: Vcl/IBSecurityEditor.dfm:152 Vcl/IBServiceEditor.dfm:175 +msgid "Se&ttings:" +msgstr "" + +#. frmIBSecurityEditor..GroupBox1..LoginPrompt..Caption +#. frmIBServiceEditor..GroupBox1..LoginPrompt..Caption +#: Vcl/IBSecurityEditor.dfm:185 Vcl/IBServiceEditor.dfm:208 +msgid "Lo&gin Prompt" +msgstr "" + +#. frmIBSecurityEditor..GroupBox1..chkActive..Caption +#. frmIBServiceEditor..GroupBox1..chkActive..Caption +#: Vcl/IBSecurityEditor.dfm:193 Vcl/IBServiceEditor.dfm:216 +msgid "&Active" +msgstr "" + +#. frmIBServiceEditor..GroupBox2..Label1..Caption +#: Vcl/IBServiceEditor.dfm:30 +msgid "&Database:" +msgstr "Base de &datos:" + +#. frmIBServiceEditor..GroupBox2..Browse..Caption +#: Vcl/IBServiceEditor.dfm:83 +msgid "&Browse" +msgstr "" + +#. SocketForm..Caption +#: Vcl/ScktMain.dfm:6 +msgid "Borland Socket Server" +msgstr "" + +#. SocketForm..Pages..PropPage..PortGroup..Label1..Caption +#: Vcl/ScktMain.dfm:46 +msgid "&Listen on Port:" +msgstr "" + +#. SocketForm..Pages..PropPage..PortGroup..PortDesc....AutoSize +#: Vcl/ScktMain.dfm:60 +msgid "" +"Many values of Port are associated by convention with a particular service " +"such as ftp or http. Port is the ID of the connection on which the server " +"listens for client requests. \n" +msgstr "" + +#. SocketForm..Pages..PropPage..ThreadGroup..Caption +#: Vcl/ScktMain.dfm:92 +msgid "Thread Caching" +msgstr "" + +#. SocketForm..Pages..PropPage..ThreadGroup..Label4..Caption +#: Vcl/ScktMain.dfm:100 +msgid "&Thread Cache Size:" +msgstr "" + +#. SocketForm..Pages..PropPage..ThreadGroup..ThreadDesc....AutoSize +#: Vcl/ScktMain.dfm:113 +msgid "" +"Thread Cache Size is the maximum number of threads that can be reused for " +"new client connections.\n" +msgstr "" + +#. SocketForm..Pages..PropPage..InterceptGroup..Caption +#: Vcl/ScktMain.dfm:145 +msgid "Intercept GUID" +msgstr "" + +#. SocketForm..Pages..PropPage..InterceptGroup..Label5..Caption +#: Vcl/ScktMain.dfm:152 +msgid "&GUID:" +msgstr "" + +#. SocketForm..Pages..PropPage..InterceptGroup..GUIDDesc....AutoSize +#: Vcl/ScktMain.dfm:164 +msgid "" +"Intercept GUID is the GUID for a data interceptor COM object. See help for " +"the TSocketConnection for details.\n" +msgstr "" + +#. SocketForm..Pages..PropPage..TimeoutGroup..Label7..Caption +#: Vcl/ScktMain.dfm:188 +msgid "&Inactive Timeout:" +msgstr "Fuera de tiempo inactivo:" + +#. SocketForm..Pages..PropPage..TimeoutGroup..TimeoutDesc....AutoSize +#: Vcl/ScktMain.dfm:201 +msgid "" +"Inactive Timeout specifes the number of minutes a client can be inactive " +"before being disconnected. (0 indicates infinite)\n" +msgstr "" + +#. SocketForm..Pages..StatPage..Caption +#: Vcl/ScktMain.dfm:239 +msgid "Users" +msgstr "" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/ScktMain.dfm:256 +msgid "Host" +msgstr "" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/ScktMain.dfm:260 +msgid "Last Activity" +msgstr "" + +#. SocketForm..PopupMenu..miProperties..Caption +#: Vcl/ScktMain.dfm:326 +msgid "&Properties" +msgstr "" + +#. SocketForm..MainMenu1..miPorts..Caption +#: Vcl/ScktMain.dfm:342 +msgid "&Ports" +msgstr "" + +#. SocketForm..MainMenu1..miPorts..miExit..Caption +#: Vcl/ScktMain.dfm:354 +msgid "&Exit" +msgstr "" + +#. SocketForm..MainMenu1..Connections1..Caption +#: Vcl/ScktMain.dfm:359 +msgid "&Connections" +msgstr "&Conexiones" + +#. SocketForm..ActionList1..DisconnectAction..Caption +#: Vcl/ScktMain.dfm:386 +msgid "&Disconnect" +msgstr "&Desconectar" + +#. SocketForm..ActionList1..ShowHostAction..Caption +#: Vcl/ScktMain.dfm:391 +msgid "&Show Host Name" +msgstr "" + +#. SocketForm..ActionList1..RegisteredAction..Caption +#: Vcl/ScktMain.dfm:401 +msgid "&Registered Objects Only" +msgstr "" + +#. SocketForm..ActionList1..AllowXML..Caption +#: Vcl/ScktMain.dfm:406 +msgid "&Allow XML Packets" +msgstr "" diff --git a/win32/gui-2/locale/es/LC_MESSAGES/gpsbabel.po b/win32/gui-2/locale/es/LC_MESSAGES/gpsbabel.po new file mode 100644 index 000000000..dd1c4a02e --- /dev/null +++ b/win32/gui-2/locale/es/LC_MESSAGES/gpsbabel.po @@ -0,0 +1,495 @@ +msgid "" +msgstr "" +"Project-Id-Version: GPSBabel command line program\n" +"POT-Creation-Date: 2006-10-29 16:00\n" +"PO-Revision-Date: 2008-05-01 10:24+0100\n" +"Last-Translator: Daniel Díaz \n" +"Language-Team: Daniel Díaz \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Country: SPAIN\n" + +msgid "(integer sec or 'auto') Barograph to GPS time diff" +msgstr "Dif. de tiempos de barógrafo a GPS (núm de segs. o 'auto')" + +msgid "(USR input) Break segments into separate tracks" +msgstr "(Entrada USR) Dividir segmentos en trazas separadas" + +msgid "(USR output) Merge into one segmented track" +msgstr "(Salida USR) Combinar en una traza segmentada" + +msgid "Ad-hoc closed icon name" +msgstr "Cerrar nombre de icono Ad-hoc" + +msgid "Ad-hoc open icon name" +msgstr "Abrir nombre de icono Ad-hoc" + +msgid "After output job done sleep n second(s)" +msgstr "Después de la conversión, para 'n' segundos." + +msgid "Allow whitespace synth. shortnames" +msgstr "Permitir espacios en los nombres cortos a generar" + +msgid "Altitudes are absolute and not clamped to ground" +msgstr "Altitudes absolutas, no relativas al suelo" + +msgid "Append icon_descr to description" +msgstr "Añadir descripción de icono a la descripción" + +msgid "Append realtime positioning data to the output file instead of truncating" +msgstr "Añadir datos de posicionamiento de tiempo real al fichero de salida en vez de truncarlo" + +msgid "Base URL for link tag in output" +msgstr "URL base para marca de enlace en salida" + +msgid "Basename prepended to URL on output" +msgstr "Prefijo de la URL del resultado" + +msgid "Bitmap of categories" +msgstr "Categorías de bitmap" + +msgid "Category name (Cache)" +msgstr "Nombre de categoría (Cache)" + +msgid "Category number to use for written waypoints" +msgstr "Número de categoría a usar en los puntos de ruta" + +msgid "Color for lines or mapnotes" +msgstr "Color para líneas o notas de mapa" + +msgid "Command unit to power itself down" +msgstr "Enviar comando de apagado a la unidad" + +msgid "Complete date-free tracks with given date (YYYYMMDD)." +msgstr "Completar las trazas sin fecha con la fecha facilitada (AAAAMMDD)." + +msgid "Create unique waypoint names (default = yes)" +msgstr "Crear nombres únicos para los puntos de ruta (defecto = si)" + +msgid "Create waypoints from geocache log entries" +msgstr "Crear puntos de ruta a partir de entradas de log de geocache" + +msgid "Database name" +msgstr "Nombre de la base de datos" + +msgid "Database name (filename)" +msgstr "Nombre de la base de datos (nombre de fichero)" + +msgid "Datum (default=NAD27)" +msgstr "Datum (por defecto=NAD27)" + +msgid "Days after which points are considered old" +msgstr "Días después de los cuales los puntos se consideran antiguos" + +msgid "Decimal seconds to pause between groups of strings" +msgstr "Segundos de pausa (en decimal) entre grupos de cadenas." + +msgid "Default category on output" +msgstr "Categoría por defecto en la salida" + +msgid "Default category on output (1..16)" +msgstr "Categoría por defecto del resultado (1..16)" + +msgid "Default icon name" +msgstr "Nombre del icono por defecto" + +msgid "Default location" +msgstr "Localización por defecto" + +msgid "Default proximity" +msgstr "Proximidad por defecto" + +msgid "Default speed" +msgstr "Velocidad por defecto" + +msgid "Default speed for waypoints (knots/hr)" +msgstr "Velocidad por defecto para los puntos de ruta (nudos/hora)" + +msgid "Degrees output as 'ddd', 'dmm'(default) or 'dms'" +msgstr "Salida en grados como 'ggg', 'gmm' (defecto) o 'gms'" + +msgid "Delete all routes" +msgstr "Borrar todas las rutas" + +msgid "Delete all track points" +msgstr "Borrar todos los puntos de la traza" + +msgid "Delete all waypoints" +msgstr "Borrar todos los puntos de ruta" + +msgid "Display labels on track and routepoints (default = 1)" +msgstr "Mostrar etiquetas en las trazas y puntos de ruta (defecto=1)" + +msgid "Distance unit [m=metric, s=statute]" +msgstr "Unidades de distancia [m=metrico,s=imperial]" + +msgid "Do not add geocache data to description" +msgstr "No añadir datos de geocache a la descripción" + +msgid "Do not add URLs to description" +msgstr "No añadir URL a la descripción" + +msgid "Don't show gpi bitmap on device" +msgstr "No mostrar bitmaps gpi en el dispositivo" + +msgid "Draw extrusion line from trackpoint to ground" +msgstr "Dibujar línea de extrusión desde el punto de trazado a tierra." + +msgid "Drop route points that do not have an equivalent waypoint (hidden points)" +msgstr "Descartar puntos de la ruta que no tengan punto de ruta equivalente (oculto)" + +msgid "Enable alerts on speed or proximity distance" +msgstr "Habilitar alertas de velocidad o proximidad" + +msgid "Encrypt hints using ROT13" +msgstr "Encriptar sugerencias mediante ROT13" + +msgid "Encrypt hints with ROT13" +msgstr "Encriptar sugerencias mediante ROT13" + +msgid "Erase device data after download" +msgstr "Borrar datos del dispositivo después de descargar." + +msgid "Export linestrings for tracks and routes" +msgstr "Exportar las cadenas de caracteres para las trazas y rutas" + +msgid "Export placemarks for tracks and routes" +msgstr "Exportar marcas de situación para trazas y rutas" + +msgid "Full path to XCSV style file" +msgstr "Ruta completa de la hoja de estilo XCSV" + +msgid "Generate # points" +msgstr "Genera # puntos" + +msgid "Generate file with lat/lon for centering map" +msgstr "Generar fichero con lat/lon para centrar mapa" + +msgid "Give points (waypoints/route points) a default radius (proximity)" +msgstr "Dar a los puntos (puntos de ruta/puntos de la ruta) un radio por defecto (proximidad)" + +msgid "GPS datum (def. WGS 84)" +msgstr "Datum GPS (def. WGS 84)" + +msgid "Height in pixels of map" +msgstr "Alto del mapa, en pixels" + +msgid "Ignore event marker icons on read" +msgstr "Ignorar iconos marcadores de eventos en la lectura" + +msgid "Include extended data for trackpoints (default = 1)" +msgstr "Incluir datos extendidos para los puntos de la traza (defecto = 1)" + +msgid "Include groundspeak logs if present" +msgstr "Incluir registros de groundspeak, si existen" + +msgid "Include major turn points (with description) from calculated route" +msgstr "Incluir los puntos de giros más importantes (con descripción) de la ruta calculada" + +msgid "Include only via stations in route" +msgstr "Suprimir puntos de ruta calculados" + +msgid "Include short name in bookmarks" +msgstr "Incluir nombre corto en Favoritos" + +msgid "Index of name field in .dbf" +msgstr "Índice del campo nombre en .dbf" + +msgid "Index of route (if more the one in source)" +msgstr "Índice de ruta (si hay más de una en el origen)" + +msgid "Index of route to write (if more the one in source)" +msgstr "Índice de la ruta a escribir (si existe más de una en origen)" + +msgid "Index of route/track to write (if more the one in source)" +msgstr "Índice de la ruta/traza a escribir (si existe más de una)" + +msgid "Index of track (if more the one in source)" +msgstr "Índice de traza (si hay más de una en el origen)" + +msgid "Index of track to write (if more the one in source)" +msgstr "Índice de la traza a grabar (si hay más de una en el origen)" + +msgid "Index of URL field in .dbf" +msgstr "Índice del campo URL en .dbf" + +msgid "Indicate direction of travel in track icons (default = 0)" +msgstr "Indicar la dirección del viaje en los iconos de la traza" + +msgid "Infrastructure closed icon name" +msgstr "Nombre de icono para cerrar infraestructura." + +msgid "Infrastructure open icon name" +msgstr "Nombre de icono para abrir infraestructura." + +msgid "Keep turns if simplify filter is used" +msgstr "Mantener giros si se usa el filtro de simplificación" + +msgid "Length of generated shortnames" +msgstr "Longitud de nombres cortos a generar" + +msgid "Length of generated shortnames (default 16)" +msgstr "Longitud de nombres cortos a generar" + +msgid "Line color, specified in hex AABBGGRR" +msgstr "Color de línea, especificado en hex AABBGGRR" + +msgid "Make synth. shortnames unique" +msgstr "Crear nombres cortos únicos" + +msgid "MapSend version TRK file to generate (3,4)" +msgstr "Versión de fichero TRK de MapSend a generar (3,4)" + +msgid "Margin for map. Degrees or percentage" +msgstr "Márgen para el mapa. Grados de porcentaje." + +msgid "Marker type for new points" +msgstr "Tipo de marcador para puntos nuevos" + +msgid "Marker type for old points" +msgstr "Tipo de marcador para puntos antiguos" + +msgid "Marker type for unfound points" +msgstr "Tipo de marcador para puntos no encontrados" + +msgid "Max length of waypoint name to write" +msgstr "Longitud máxima de nombre de los puntos de rutas a escribir" + +msgid "Max number of comments to write (maxcmts=200)" +msgstr "Máximo número de comentarios a escribir (maxcmts=200)" + +msgid "Max shortname length when used with -s" +msgstr "Longitud máxima de nombre corto cuando se use con -s" + +msgid "Max synthesized shortname length" +msgstr "Longitud máxima de nombre corto a generar" + +msgid "Merge output with existing file" +msgstr "Combinar salida con fichero existente" + +msgid "MTK compatible CSV output file" +msgstr "MTK compatible con fichero CSV" + +msgid "Name of the 'unassigned' category" +msgstr "Nombre de la categoría 'Sin asignar'" + +msgid "New name for the route" +msgstr "Nuevo nombre de la ruta" + +msgid "No separator lines between waypoints" +msgstr "Sin líneas de separación entre puntos de ruta" + +msgid "No whitespace in generated shortnames" +msgstr "Sin espacios en blanco en nombres cortos." + +msgid "Non-stealth encrypted icon name" +msgstr "Nombre de icono encriptado (No oculto)" + +msgid "Non-stealth non-encrypted icon name" +msgstr "Nombre de icono no encriptado (No oculto)" + +msgid "Numeric value of bitrate (baud=4800)" +msgstr "Valor numérico de bitrate (baudios=4800)" + +msgid "Omit Placer name" +msgstr "Omitir nombre del creador" + +msgid "Only read turns; skip all other points" +msgstr "Sólo leer giros; ignorar todos los demás puntos" + +msgid "Path to HTML style sheet" +msgstr "Ruta de la hoja de estilo HTML" + +msgid "Precision of coordinates" +msgstr "Precisión de las coordenadas." + +msgid "Proximity distance" +msgstr "Distancia de proximidad" + +msgid "Radius for circles" +msgstr "Radio para los círculos" + +msgid "Radius of our big earth (default 6371000 meters)" +msgstr "Radio de nuestra gran Tierra (por defecto 6371000 metros)" + +msgid "Read control points as waypoint/route/none" +msgstr "Leer puntos de control como punto de ruta/ruta/ninguno" + +msgid "Read/Write date format (i.e. DDMMYYYY)" +msgstr "Formato de fecha en Lectura/Escritura (p.e. DDMMAAAA)" + +msgid "Read/Write date format (i.e. yyyy/mm/dd)" +msgstr "Formato de fecha en Lectura/Escritura (p.e. aaaa/mm/dd)" + +msgid "Read/write GPGGA sentences" +msgstr "Comandos de Lectura/Escritura en GPGGA" + +msgid "Read/write GPGSA sentences" +msgstr "Comandos de Lectura/Escritura en GPGSA" + +msgid "Read/write GPRMC sentences" +msgstr "Comandos de Lectura/Escritura en GPRMC" + +msgid "Read/write GPVTG sentences" +msgstr "Comandos de Lectura/Escritura en GPVTG" + +msgid "Read/Write time format (i.e. HH:mm:ss xx)" +msgstr "Formato de hora en Lectura/Escritura (p.e. HH:mm:ss xx)" + +msgid "Retain at most this number of position points (0 = unlimited)" +msgstr "Almacenar como poco este número de puntos de posición (0=ilimitado)" + +msgid "Return current position as a waypoint" +msgstr "Devolver la posición actual como un punto de ruta" + +msgid "Road type changes" +msgstr "Cambios en tipo de carretera." + +msgid "Set waypoint name to source filename." +msgstr "Establecer el nombre de los puntos de ruta al fichero origen" + +msgid "Shortname is MAC address" +msgstr "El nombre corto es la dirección MAC" + +msgid "Speed in bits per second of serial port (baud=4800)" +msgstr "Velocidad en bits por segundos del puerto serie (4800 baudios)" + +msgid "Split input into separate files" +msgstr "Dividir la entrada en archivos separados" + +msgid "Split into multiple routes at turns" +msgstr "Dividir en múltiples rutas en los giros" + +msgid "Starting seed of the internal number generator" +msgstr "Iniciando el origen de datos del generador numérico interno" + +msgid "Stealth encrypted icon name" +msgstr "Nombre de icono encriptado (Oculto)" + +msgid "Stealth non-encrypted icon name" +msgstr "Nombre de icono no encriptado (Oculto)" + +msgid "String to separate concatenated address fields (default=\", \")" +msgstr "Separar la cadena en campos de dirección concatenados (defecto=\",\")" + +msgid "Suppress labels on generated pins" +msgstr "Quitar etiquetas en pins generados" + +msgid "Suppress retired geocaches" +msgstr "Eliminar geocaches retirados" + +msgid "Suppress separator lines between waypoints" +msgstr "Quitar líneas de separación entre puntos de ruta" + +msgid "Suppress use of handshaking in name of speed" +msgstr "Eliminar uso de handshaking en nombre de velocidad (???)" + +msgid "Suppress whitespace in generated shortnames" +msgstr "Quitar espacios en nombres cortos generados" + +msgid "Symbol to use for point data" +msgstr "Símbolo a usar para los datos de puntos" + +msgid "Sync GPS time to computer time" +msgstr "Sincronizar la hora del GPS con la del PC" + +msgid "Synthesize track times" +msgstr "Resumir los tiempos de las trazas" + +msgid "Target GPX version for output" +msgstr "Versión GPX destino para la salida" + +msgid "Temperature unit [c=Celsius, f=Fahrenheit]" +msgstr "Unidades de temperatura [c=Celsius, f=Fahrenheit]" + +msgid "The icon description is already the marker" +msgstr "La descripción del icono ya es el marcador" + +msgid "Treat waypoints as icons on write" +msgstr "Tratar los puntos de ruta como iconos en la escritura" + +msgid "Type of .an1 file" +msgstr "Fichero de tipo .an1" + +msgid "Units for altitude (f)eet or (m)etres" +msgstr "Unidades de altitud (p)íes o (m)etros" + +msgid "Units used for names with @speed ('s'tatute or 'm'etric)" +msgstr "Unidades utilizadas para los nombre con @velocidad ('s'tatute o 'm'etrica)" + +msgid "Units used when writing comments ('s'tatute or 'm'etric)" +msgstr "Unidades utilizadas en los comentarios ('i'mperial o 'm'étrico')" + +msgid "UPPERCASE synth. shortnames" +msgstr "Nombres cortos a generar en MAYÚSCULAS" + +msgid "Use depth values on output (default is ignore)" +msgstr "Usar valores de profundidad en resultado (por defecto: ignorar)" + +msgid "Use proximity values on output (default is ignore)" +msgstr "Usar valores de proximidad en resultado (por defecto: ignorar)" + +msgid "Use shortname instead of description" +msgstr "Usar el nombre corto en lugar de la descripción" + +msgid "Use specified bitmap on output" +msgstr "Utilizar el bitmap escificado en la salida" + +msgid "Version of gdb file to generate (1..3)" +msgstr "Versión del fichero gbd a generar (1..3)" + +msgid "Version of mapsource file to generate (3,4,5)" +msgstr "Versión de fichero mapsource a generar (3,4,5)" + +msgid "Waypoint background color" +msgstr "Color de fondo para los puntos de ruta" + +msgid "Waypoint foreground color" +msgstr "Color primer plano para los puntos de ruta" + +msgid "Waypoint type" +msgstr "Tipo de punto de trazado" + +msgid "Width in pixels of map" +msgstr "Ancho del mapa, en pixels" + +msgid "Width of lines, in pixels" +msgstr "Ancho de líneas, en pixels" + +msgid "Write additional node tag key/value pairs" +msgstr "Escribir etiquetas adicionales de clave/valor en los nodos" + +msgid "Write additional way tag key/value pairs" +msgstr "Graba etiquetas adicionales de clave/valor en la ruta" + +msgid "Write all tracks into one file" +msgstr "Graba todas las trazas en un fichero" + +msgid "Write description to address field" +msgstr "Graba la descripción al campo dirección" + +msgid "Write each waypoint in a separate file" +msgstr "Graba cada punto de ruta en un fichero individual" + +msgid "Write notes to address field" +msgstr "Graba las notas al campo dirección" + +msgid "Write position to address field" +msgstr "Graba la posición al campo dirección" + +msgid "Write position using this grid." +msgstr "Graba la posición utilizando esta rejilla" + +msgid "Write timestamps with offset x to UTC time" +msgstr "Escribir marcas de tiempo con un desplazamiento de 'x' sobre la hora UTC" + +msgid "Write tracks compatible with Carto Exploreur" +msgstr "Crear trazas compatibles con Carto Exploreur" + +msgid "Write tracks for Gisteq Phototracker" +msgstr "Graba las trazas para el Gisteq Phototracker " + +msgid "Zoom level to reduce points" +msgstr "Nivel de Zoom para reducir puntos" + diff --git a/win32/gui-2/locale/fr/LC_MESSAGES/default.po b/win32/gui-2/locale/fr/LC_MESSAGES/default.po new file mode 100644 index 000000000..c0a7f9e07 --- /dev/null +++ b/win32/gui-2/locale/fr/LC_MESSAGES/default.po @@ -0,0 +1,926 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: GPSBabelGUI-2\n" +"POT-Creation-Date: 2005-09-22 23:44\n" +"PO-Revision-Date: 2007-05-01 20:29+0100\n" +"Last-Translator: Olaf Klein \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2\n" +"Language-Team: Utagawa VTT \n" +"X-Poedit-Language: French\n" +"X-Poedit-SourceCharset: utf-8\n" +"Plural-Forms: s\n" + +#. frmAbout..Caption +#: about.dfm:5 +msgid "About" +msgstr "A propos" + +#. frmAbout..pnClient..pnCenter..lbHint1..Caption +#: about.dfm:76 +msgid "This program is part of the GPSBabel project, hosted on" +msgstr "Ce programme fait partie du projet GPSBabel, hébergé sur" + +#. frmAbout..pnClient..pnCenter..lbVersion..Caption +#: about.dfm:84 +#: about.pas:80 +msgid "Version" +msgstr "Version" + +#. frmAbout..pnClient..pnCenter..lbTranslators..Caption +#: about.dfm:91 +msgid "Translations" +msgstr "Traductions" + +#. frmAbout..pnClient..pnCenter..lbURL..Caption +#: about.dfm:98 +msgid "www.gpsbabel.org" +msgstr "www.gpsbabel.org" + +#. frmAbout..pnClient..pnCenter..lbCopyRight..Caption +#: about.dfm:114 +msgid "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" +msgstr "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" + +#. frmAbout..pnClient..pnCenter..lbMoreInfo..Caption +#: about.dfm:121 +msgid "Find more info at" +msgstr "Plus d'infos sur" + +#. frmAbout..pnClient..pnCenter..stDescription..Caption +#: about.dfm:149 +msgid "The frontend for GPSBabel command line program" +msgstr "L'interface graphique de GPSBabel" + +#. frmAbout..pnClient..pnCenter..stLicense..Caption +#: about.dfm:163 +msgid "THIS SOFTWARE MAY ONLY BE LICENSED FREE OF CHARGE" +msgstr "Ce prgramme ne peut être utilisé que sous license gratuite" + +#. frmAbout..pnClient..pnCenter..btnNewLanguage..Caption +#: about.dfm:192 +msgid "Adding a new language" +msgstr "Ajouter une nouvelle langue" + +#. frmFilter..Caption +#: filter.dfm:6 +msgid "Filter" +msgstr "Filtre" + +#. frmFilter..gbTracks..Caption +#. frmMain..pnBottom..cbTracks..Caption +#: filter.dfm:31 +#: main.dfm:581 +msgid "&Tracks" +msgstr "&Traces" + +#. frmFilter..gbTracks..lbTimePlusMinus..Caption +#: filter.dfm:39 +#: about.pas:87 +#: about.pas:88 +#: about.pas:89 +#: about.pas:90 +msgid "by" +msgstr "par" + +#. frmFilter..gbTracks..lbTimeDays..Caption +#: filter.dfm:46 +msgid "day(s), " +msgstr "jour(s)," + +#. frmFilter..gbTracks..lbTimeHours..Caption +#: filter.dfm:53 +msgid "hour(s), " +msgstr "heure(s)" + +#. frmFilter..gbTracks..lbTimeMinutes..Caption +#: filter.dfm:60 +msgid "minute(s)," +msgstr "minute(s)" + +#. frmFilter..gbTracks..lbTimeSeconds..Caption +#: filter.dfm:67 +msgid "second(s)" +msgstr "seconde(s)" + +#. frmFilter..gbTracks..cbTrackTitle..Hint +#: filter.dfm:74 +msgid "Title for new tracks" +msgstr "Titres des nouvelles traces" + +#. frmFilter..gbTracks..cbTrackTitle..Caption +#: filter.dfm:76 +msgid "Tit&le" +msgstr "Tit&re" + +#. frmFilter..gbTracks..cbTrackSplit..Hint +#: filter.dfm:95 +msgid "Split track into several tracks depending on date of trackpoint" +msgstr "Scinder la trace en plusieurs traces en fonction de la date des points" + +#. frmFilter..gbTracks..cbTrackSplit..Caption +#: filter.dfm:96 +msgid "&Split" +msgstr "&Scinder" + +#. frmFilter..gbTracks..cbTrackTime..Hint +#: filter.dfm:104 +msgid "Shift all tracks" +msgstr "Inverser toutes les traces" + +#. frmFilter..gbTracks..cbTrackTime..Caption +#: filter.dfm:105 +msgid "&Move" +msgstr "&Déplacer" + +#. frmFilter..gbTracks..cbTrackStart..Hint +#: filter.dfm:197 +msgid "Take only trackpoints starting at" +msgstr "Utiliser seulement les points commençant à" + +#. frmFilter..gbTracks..cbTrackStart..Caption +#: filter.dfm:198 +msgid "Start at" +msgstr "Commencer à" + +#. frmFilter..gbTracks..cbTrackStop..Caption +#: filter.dfm:237 +msgid "stop at" +msgstr "Arrêter à" + +#. frmFilter..gbTracks..cbTrackPack..Hint +#: filter.dfm:276 +msgid "Pack all tracks into one track (No duplicate timestamps)" +msgstr "Fusionner toutes les traces en une seule (pas de duplication de l'horodatage)" + +#. frmFilter..gbTracks..cbTrackPack..Caption +#: filter.dfm:277 +msgid "&Pack (or)" +msgstr "&Fusionner (ou)" + +#. frmFilter..gbTracks..cbTrackMerge..Hint +#: filter.dfm:286 +msgid "Merge all tracks into one track" +msgstr "Fusionner toutes les traces en une seule" + +#. frmFilter..gbTracks..cbTrackMerge..Caption +#: filter.dfm:287 +msgid "Merge" +msgstr "Fusionner" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Hint +#: filter.dfm:296 +msgid "Shift start/stop by local timezone offset" +msgstr "Décaler le début/fin en fonction du décalage horaire local" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Caption +#: filter.dfm:297 +msgid "TZ" +msgstr "TZ" + +#. frmFilter..gbTracks..cbGPSfix..Hint +#: filter.dfm:306 +msgid "Synthesize GPS fixes (PPS, DGPS, 3D, 2D)" +msgstr "" + +#. frmFilter..gbTracks..cbGPSfix..Caption +#: filter.dfm:307 +msgid "GPS fixes" +msgstr "" + +#. frmFilter..gbTracks..cbTrackCourse..Hint +#: filter.dfm:316 +msgid "Synthesize course values" +msgstr "" + +#. frmFilter..gbTracks..cbTrackCourse..Caption +#: filter.dfm:317 +msgid "Course" +msgstr "" + +#. frmFilter..gbTracks..cbTrackSpeed..Hint +#: filter.dfm:325 +msgid "Synthesize speed values" +msgstr "" + +#. frmFilter..gbTracks..cbTrackSpeed..Caption +#: filter.dfm:326 +msgid "Speed" +msgstr "Vitesse" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:338 +msgid "none" +msgstr "" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:339 +msgid "pps" +msgstr "" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:340 +msgid "dgps" +msgstr "" + +#. frmFilter..gbRoutes..Caption +#: filter.dfm:352 +msgid "&Routes && Tracks" +msgstr "&Routes && Traces" + +#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption +#: filter.dfm:360 +msgid "limit to" +msgstr "limiter à" + +#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption +#: filter.dfm:368 +msgid "Points" +msgstr "Points" + +#. frmFilter..gbRoutes..cbRouteSimplify..Hint +#: filter.dfm:375 +msgid "Simplify routes and tracks by limited number of points" +msgstr "Simplifier les routes et traces en limitant le nombre de points" + +#. frmFilter..gbRoutes..cbRouteSimplify..Caption +#: filter.dfm:376 +msgid "Simplify" +msgstr "Simplifier" + +#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint +#: filter.dfm:385 +msgid "Upper limit of points for routes and tracks" +msgstr "Limite maximum du nombre de points pour les routes et traces" + +#. frmFilter..gbRoutes..cbReverse..Hint +#: filter.dfm:407 +msgid "Reverse routes and tracks" +msgstr "Inverser les routes et les traces" + +#. frmFilter..gbRoutes..cbReverse..Caption +#: filter.dfm:408 +msgid "Reverse" +msgstr "Inverser" + +#. frmFilter..pnBottom..btnOK..Caption +#: filter.dfm:425 +msgid "OK" +msgstr "OK" + +#. frmFilter..pnBottom..BitBtn1..Caption +#: filter.dfm:461 +msgid "File based filters" +msgstr "Filtres de fichiers" + +#. frmFilter..gbWaypoints..Caption +#. frmMain..pnBottom..cbWaypoints..Caption +#: filter.dfm:490 +#: main.dfm:555 +msgid "&Waypoints" +msgstr "&Waypoints" + +#. frmFilter..gbWaypoints..lbWayptRadiusLat..Caption +#: filter.dfm:499 +msgid "Latitude" +msgstr "Latitude" + +#. frmFilter..gbWaypoints..lbWayptRadiusLon..Caption +#: filter.dfm:507 +msgid "Longitude" +msgstr "Longitude" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint +#: filter.dfm:515 +msgid "Merge waypoints with duplicate locations" +msgstr "Fusionner les waypoints avec les positions en doublon" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption +#: filter.dfm:516 +msgid "locations" +msgstr "positions" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint +#: filter.dfm:525 +msgid "Merge waypoints with duplicate \"short name\"" +msgstr "Fusionner les waypoints avec les doublons \"short name\"" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption +#: filter.dfm:526 +msgid "\"short names\"" +msgstr "\"noms courts\"" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint +#: filter.dfm:535 +msgid "Merge waypoints separated by less then" +msgstr "Fusionner les waypoints séparé par moins de" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption +#: filter.dfm:536 +msgid "Position" +msgstr "Position" + +#. frmFilter..gbWaypoints..cbWayptSort..Hint +#: filter.dfm:564 +msgid "Sort waypoints by \"short name\" or by description" +msgstr "Trier les waypoints par \"short name\" ou par description" + +#. frmFilter..gbWaypoints..cbWayptSort..Caption +#: filter.dfm:565 +msgid "Sort" +msgstr "Trier" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint +#: filter.dfm:573 +msgid "Merge duplicate waypoints" +msgstr "Fusionner les waypoints identiques" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption +#: filter.dfm:574 +msgid "Duplicates" +msgstr "Doublons" + +#. frmFilter..gbWaypoints..cbWayptRadius..Hint +#: filter.dfm:583 +msgid "Include points based on their proximity to central point" +msgstr "Inclure les points en fonction de la proximité d'un point central" + +#. frmFilter..gbWaypoints..cbWayptRadius..Caption +#: filter.dfm:584 +msgid "Radius" +msgstr "Rayon" + +#. frmFilter..gbWaypoints..edWayptRadiusLat..Hint +#: filter.dfm:612 +msgid "Latitude of central point" +msgstr "Latitude du point central" + +#. frmFilter..gbWaypoints..edWayptRadiusLon..Hint +#: filter.dfm:622 +msgid "Longitude of central point" +msgstr "Longitude du point central" + +#. frmFilter..gbTransform..Caption +#: filter.dfm:634 +msgid "Transformation" +msgstr "" + +#. frmFilter..gbTransform..cbTransform..Caption +#: filter.dfm:651 +msgid "Transform" +msgstr "" + +#. frmFilter..gbTransform..cbTransformDelete..Hint +#: filter.dfm:660 +msgid "Delete source data after transformation" +msgstr "" + +#. frmFilter..gbTransform..cbTransformDelete..Caption +#: filter.dfm:661 +msgid "Delete" +msgstr "" + +#. frmMain..pnTop..gbInput..Caption +#: main.dfm:38 +#: main.pas:270 +#: main.pas:275 +#: main.pas:467 +#: main.pas:868 +msgid "Input" +msgstr "Entrée" + +#. frmMain..pnTop..gbInput..sbOpenFile..Hint +#: main.dfm:45 +msgid "Start the file open dialog" +msgstr "Menu de d'ouverture de fichier" + +#. frmMain..pnTop..gbInput..lbInputOpts..Caption +#. frmMain..pnTop..gbOutput..lbOutputOpts..Caption +#. frmMain..ActionList1..acOptionsSourceFormat..Category +#. frmMain..ActionList1..acOptionsTargetFormat..Category +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Category +#: main.dfm:68 +#: main.dfm:229 +#: main.dfm:1418 +#: main.dfm:1423 +#: main.dfm:1437 +msgid "Options" +msgstr "Options" + +#. frmMain..pnTop..gbInput..lbInputFormat..Caption +#. frmMain..pnTop..gbOutput..lbOutputFormat..Caption +#: main.dfm:76 +#: main.dfm:259 +msgid "Format" +msgstr "Format" + +#. frmMain..pnTop..gbInput..lbInputFile..Caption +#. frmMain..pnTop..gbOutput..lbOutputFile..Caption +#. frmMain..ActionList1..acFileExit..Category +#. frmMain..ActionList1..acFileClearMemo..Category +#. frmMain..ActionList1..acFileOutputToScreen..Category +#. frmMain..ActionList1..acFileChangeLanguage..Category +#. frmMain..ActionList1..acFileExportCSV..Category +#: main.dfm:83 +#: main.dfm:266 +#: main.dfm:1399 +#: main.dfm:1428 +#: main.dfm:1443 +#: main.dfm:1455 +#: main.dfm:1460 +#: main.pas:865 +#: main.pas:919 +msgid "File" +msgstr "Fichier" + +#. frmMain..pnTop..gbInput..chbInputDevice..Hint +#: main.dfm:112 +msgid "Read data from device instead from file" +msgstr "Lire les données depuis un périphérique plutôt qu'un fichier" + +#. frmMain..pnTop..gbInput..chbInputDevice..Caption +#. frmMain..pnTop..gbOutput..chbOutputDevice..Caption +#: main.dfm:115 +#: main.dfm:299 +msgid "Device" +msgstr "Périphérique" + +#. frmMain..pnTop..gbInput..edInputOpts..Hint +#: main.dfm:124 +msgid "Options for the selected input format" +msgstr "Options du format d'entrée sélectionné" + +#. frmMain..pnTop..gbInput..edInputFile..Hint +#: main.dfm:135 +msgid "Read data from given filename" +msgstr "Lire les données de puis un fichier" + +#. frmMain..pnTop..gbInput..cbInputLang..Hint +#: main.dfm:146 +msgid "Characterset for input data" +msgstr "Code de caractères pour l'entrée" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:152 +#: main.dfm:363 +msgid "- default -" +msgstr "- défaut -" + +#. frmMain..pnTop..gbInput..cbInputDevice..Hint +#: main.dfm:179 +msgid "Read data from device ..." +msgstr "Lire les données depuis le périphérique" + +#. frmMain..pnTop..gbInput..cbInputFormatDevice..Hint +#: main.dfm:194 +msgid "Format for input from device" +msgstr "Format d'entrée depuis le périphérique" + +#. frmMain..pnTop..gbInput..cbInputFormat..Hint +#: main.dfm:208 +msgid "Format for input from file" +msgstr "Format d'entrée depuis un fichier" + +#. frmMain..pnTop..gbOutput..Caption +#: main.dfm:222 +#: main.pas:271 +#: main.pas:276 +#: main.pas:476 +#: main.pas:922 +msgid "Output" +msgstr "Sortie" + +#. frmMain..pnTop..gbOutput..sbSaveFile..Hint +#: main.dfm:273 +msgid "Start the file save dialog" +msgstr "Menu de sauvegarde de fichier" + +#. frmMain..pnTop..gbOutput..chbOutputDevice..Hint +#: main.dfm:296 +msgid "Write data to device instead to file" +msgstr "Ecrire les données sur le périphérique plutôt que dans un fichier" + +#. frmMain..pnTop..gbOutput..cbOutputFormatDevice..Hint +#: main.dfm:309 +msgid "Format for ouput to device" +msgstr "Format de sortie vers le périphérique" + +#. frmMain..pnTop..gbOutput..edOutputOpts..Hint +#: main.dfm:321 +msgid "Options for the selected output format" +msgstr "Options du format de sortie sélectionné" + +#. frmMain..pnTop..gbOutput..cbOutputFormat..Hint +#: main.dfm:332 +msgid "Format for output to file" +msgstr "Format de sortie vers un fichier" + +#. frmMain..pnTop..gbOutput..edOutputFile..Hint +#: main.dfm:345 +msgid "Write data to given filename" +msgstr "Ecrire les données dans un fichier" + +#. frmMain..pnTop..gbOutput..cbOutputLang..Hint +#: main.dfm:357 +msgid "Characterset for output data" +msgstr "Code de caractères pour la sortie" + +#. frmMain..pnTop..gbOutput..cbOutputDevice..Hint +#: main.dfm:390 +msgid "Write data to device ..." +msgstr "Ecrire les données sur le périphérique" + +#. frmMain..pnBottom..lbWhat..Caption +#: main.dfm:415 +msgid "What ?" +msgstr "Quoi ?" + +#. frmMain..pnBottom..cbWaypoints..Hint +#: main.dfm:554 +msgid "Process waypoint information" +msgstr "Inclure les waypoints" + +#. frmMain..pnBottom..cbRoutes..Hint +#: main.dfm:568 +msgid "Process route information" +msgstr "Inclure les routes" + +#. frmMain..pnBottom..cbRoutes..Caption +#: main.dfm:569 +msgid "&Routes" +msgstr "&Routes" + +#. frmMain..pnBottom..cbTracks..Hint +#: main.dfm:580 +msgid "Process track information" +msgstr "Inclure les traces" + +#. frmMain..pnBottom..btnFilter..Caption +#. frmMain..ActionList1..acFilterSelect..Caption +#: main.dfm:594 +#: main.dfm:1393 +msgid "&Filter" +msgstr "&Filtre" + +#. frmMain..pnBottom..btnProcess..Hint +#: main.dfm:638 +msgid "Start data conversion" +msgstr "Démarrer la conversion de données" + +#. frmMain..pnBottom..btnProcess..Caption +#. frmMain..ActionList1..acConvert..Caption +#: main.dfm:641 +#: main.dfm:1386 +msgid "let's go" +msgstr "Lancer" + +#. frmMain..OpenDialog..Filter +#: main.dfm:701 +msgid "Garmin Mapsource mps|*.mps|All files|*.*" +msgstr "Garmin Mapsource mps|*.mps|Tous les fichiers|*.*" + +#. frmMain..SaveDialog..Filter +#: main.dfm:707 +msgid "All file(s)|*.*|Garmin MapSource mps|*.mps" +msgstr "Tous les fichier(s)|*.*|Garmin MapSource mps|*.mps" + +#. frmMain..ActionList1..acConvert..Category +#. frmMain..ActionList1..acFilterSelect..Category +#: main.dfm:1385 +#: main.dfm:1392 +msgid "Babel" +msgstr "Babel" + +#. frmMain..ActionList1..acFilterSelect..Hint +#: main.dfm:1394 +msgid "Filter incomming data before writing them to file or device" +msgstr "Filtrer les données envoyées avant de les écrire sur un périphérique ou dans un fichier" + +#. frmMain..ActionList1..acFileExit..Caption +#: main.dfm:1400 +msgid "E&xit" +msgstr "F&ermer" + +#. frmMain..ActionList1..acHelpAbout..Category +#. frmMain..ActionList1..acHelpIntro..Category +#. frmMain..ActionList1..acHelpReadme..Category +#: main.dfm:1404 +#: main.dfm:1409 +#: main.dfm:1413 +msgid "Help" +msgstr "Aide" + +#. frmMain..ActionList1..acHelpAbout..Caption +#: main.dfm:1405 +msgid "&About" +msgstr "&A propos" + +#. frmMain..ActionList1..acHelpIntro..Caption +#: main.dfm:1410 +msgid "&Intro" +msgstr "&Introduction" + +#. frmMain..ActionList1..acHelpReadme..Caption +#. frmReadme..Caption +#: main.dfm:1414 +#: readme.dfm:6 +msgid "GPSBabel README" +msgstr "GPSBabel README" + +#. frmMain..ActionList1..acOptionsSourceFormat..Caption +#: main.dfm:1419 +msgid "... for source format" +msgstr "... pour le format source" + +#. frmMain..ActionList1..acOptionsTargetFormat..Caption +#: main.dfm:1424 +msgid "... for target format" +msgstr "... pour le format cible" + +#. frmMain..ActionList1..acFileClearMemo..Caption +#: main.dfm:1429 +msgid "Clear output" +msgstr "Effacer la sortie" + +#. frmMain..ActionList1..acFileClearMemo..Hint +#: main.dfm:1430 +msgid "Clear messages" +msgstr "Effacer les messages" + +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Caption +#: main.dfm:1438 +msgid "Enable characterset transformation" +msgstr "Activer la transformation du code de caractères" + +#. frmMain..ActionList1..acFileOutputToScreen..Caption +#: main.dfm:1444 +msgid "Output to screen" +msgstr "Afficher sur l'écran" + +#. frmMain..ActionList1..acFileChangeLanguage..Caption +#: main.dfm:1456 +msgid "Change language" +msgstr "Changer de langue" + +#. frmMain..ActionList1..acFileExportCSV..Caption +#: main.dfm:1461 +msgid "Export gpsbabel.csv (unicode)" +msgstr "Export gpsbabel.csv (unicode)" + +#. frmMain..MainMenu1..mnuFile..Caption +#: main.dfm:1469 +msgid "&File" +msgstr "&Fichier" + +#. frmMain..MainMenu1..mnuFile..File1..Caption +#: main.dfm:1477 +msgid "Export" +msgstr "Export" + +#. frmMain..MainMenu1..mnuOptions..Caption +#: main.dfm:1498 +msgid "&Options" +msgstr "&Options" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames..Caption +#: main.dfm:1500 +msgid "Synthesize shortnames" +msgstr "Générer les nom courts" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames....Hint +#: main.dfm:1503 +msgid "Ignore shortnames from source data and synthesize them from description or notes" +msgstr "Ingorer les noms \"courts\" de la source de données et les générer à partir des noms longs" + +#. frmMain..MainMenu1..mnuOptions..mnuOptionsForceDataType..Caption +#: main.dfm:1507 +msgid "Force selected GPS data types (nuketypes filter)" +msgstr "Forcer le type de données GPS selctionné (filtre nuketypes)" + +#. frmMain..MainMenu1..mnuHelp..Caption +#: main.dfm:1548 +msgid "&Help" +msgstr "&Aide" + +#. frmOptions..Caption +#: options.dfm:5 +msgid "Options for ..." +msgstr "Options pour ..." + +#. frmSelect..pnBottom..btnCancel..Caption +#: select.dfm:66 +msgid "Abort" +msgstr "Annuler" + +#: about.pas:87 +#: select.pas:81 +msgid "German" +msgstr "Allemand" + +#: about.pas:88 +#: select.pas:83 +msgid "French" +msgstr "Français" + +#: about.pas:89 +#: select.pas:82 +msgid "Spanish" +msgstr "Espagnol" + +#: about.pas:90 +#: select.pas:85 +msgid "Hungarian" +msgstr "Hongrois" + +#: about.pas:132 +msgid "" +"Please have a look at the file README.GUI.\n" +"\n" +"There you will find all information you need to\n" +"get GPSBabelGUI working in your own language." +msgstr "" +"Consultez le fichier README.GUI\n" +"\n" +"Vous trouverez toutes l'information nécessaire\n" +"pour faire fonctionner GPSBabelGUI dans votre langue." + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:184 +#: filter.pas:185 +msgid "Waypoints" +msgstr "Waypoints" + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:182 +#: filter.pas:183 +msgid "Routes" +msgstr "Routes" + +#: filter.pas:182 +#: filter.pas:183 +#: filter.pas:184 +#: filter.pas:185 +msgid "Tracks" +msgstr "Traces" + +#: filter.pas:224 +msgid "Feet" +msgstr "Pieds" + +#: filter.pas:225 +msgid "Meter" +msgstr "Mètre" + +#: filter.pas:228 +msgid "Miles" +msgstr "Miles" + +#: filter.pas:229 +msgid "Kilometer" +msgstr "Kilomètre" + +#: filter.pas:239 +msgid "Not supported by gpsbabel.exe, release %s!" +msgstr "Non supporté par GPSBabel, version %s!" + +#: filter.pas:288 +msgid "Value (%s) out of range (%g to %g)!" +msgstr "Valeurs (%s) en dehors des limites (%g à %g)!" + +#: filter.pas:593 +#: options.pas:661 +msgid "Discard changes?" +msgstr "Ne pas tenir compte des changements?" + +#: main.pas:244 +msgid "Internal development release" +msgstr "Version interne" + +#: main.pas:246 +msgid "BETA" +msgstr "BETA" + +#: main.pas:248 +msgid "Private release" +msgstr "Version privée" + +#: main.pas:250 +msgid "Special release" +msgstr "Version spéciale" + +#: main.pas:342 +msgid "The file \"gpsbabel.exe\" found in current directory is too old!" +msgstr "Le fichier \"gpsbabel.exe\" présent dans le répertoir courant est trop vieux!" + +#: main.pas:416 +#: main.pas:550 +msgid "All files|*.*" +msgstr "Tous les fichiers|*.*" + +#: main.pas:484 +msgid "Select and edit options for \"%s\"" +msgstr "Selctionner et éditer les options pour \"%s\"" + +#: main.pas:488 +msgid "No options available for \"%s\"" +msgstr "Pas d'option disponible pour \"%s\"" + +#. s := s + '-1'; +#: main.pas:603 +msgid "File %s not found." +msgstr "Fichier%s non trouvé." + +#: main.pas:664 +msgid "File \"%s\" exists ! Overwrite ?" +msgstr "Le fichier \"%s\" existe déjà ! Ecraser ?" + +#: main.pas:665 +msgid "Warning" +msgstr "Attention" + +#: main.pas:698 +msgid "Could not run \"gpsbabel.exe\"!" +msgstr "Impossible d'éxécuter \"gpsbabel.exe\"!" + +#: main.pas:707 +msgid "Sorry, gpsbabel.exe reported problems!" +msgstr "Désolé, GPSBabel a reporté un problème !" + +#: main.pas:709 +msgid "Converted successfully from \"%s\" to \"%s\"." +msgstr "Conversion de \"%s\" à \"%s\" réussie." + +#: main.pas:820 +msgid "GPSBabel, version %s" +msgstr "GPSBabel, version %s" + +#: main.pas:854 +#: main.pas:909 +msgid "Port" +msgstr "Port" + +#: main.pas:1013 +msgid "Options for \"%s\"" +msgstr "Options pour \"%s\"" + +#: main.pas:1203 +#: main.pas:1273 +msgid "Choose language" +msgstr "Choisir la langue" + +#: main.pas:1203 +msgid "for GUIBabelGUI" +msgstr "pour GPSBabelGUI" + +#: main.pas:1273 +msgid "for export" +msgstr "pour export" + +#. override; +#: options.pas:147 +msgid "Be aware, that most options are made for the output side. " +msgstr "Attention, la plupart des options sont faites pour le format de sortie." + +#: options.pas:148 +msgid "Currently we don't have a flag which tells us which direction is used by the options." +msgstr "Nous n'avons pour l'instant pas de drapeau indiquant dans quelle direction sont utilisées les options." + +#: options.pas:208 +msgid "Short \"%s\"" +msgstr "Raccourci \"%s\"" + +#: options.pas:332 +msgid "Invalid line format!" +msgstr "Format de ligne invalide" + +#: options.pas:353 +msgid "Unknown option \"%s\"!" +msgstr "Option inconnue \"%s\"" + +#: select.pas:84 +msgid "English" +msgstr "Anglais" + +#: utils.pas:119 +msgid "Error WINAPI: Could not create \"NamedPipe\"!" +msgstr "Erreur WIANPI: Ne peut pas créer \"NamedPipe\"!" + +#: utils.pas:124 +msgid "\"gpsbabel.exe\" not found!!!" +msgstr "\"gpsbabel.exe\" non trouvé!!!" + +#. dwCreationFlags, // creation flags +#: utils.pas:143 +msgid "Could not run \"gpsbabel.exe\" (Error %d)!" +msgstr "Impossible d'éxecuter \"gpsbabel.exe\" (Error %d)!" + +#: utils.pas:176 +msgid "\"gpsbabel.exe\" returned error 0x%x (%d)" +msgstr "\"gpsbabel.exe\" a renvoyé l'erreur 0x%x (%d)" + diff --git a/win32/gui-2/locale/fr/LC_MESSAGES/delphi.po b/win32/gui-2/locale/fr/LC_MESSAGES/delphi.po new file mode 100644 index 000000000..0f96748ed --- /dev/null +++ b/win32/gui-2/locale/fr/LC_MESSAGES/delphi.po @@ -0,0 +1,6177 @@ +msgid "" +msgstr "" +"Project-Id-Version: Borland Delphi 5 Runtime libraries\n" +"POT-Creation-Date: 2003-03-04 15:18\n" +"PO-Revision-Date: 2006-04-14 14:12+0100\n" +"Last-Translator: Olaf Klein \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2\n" +"License: May only be used with a purchased Borland Delphi\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: FRANCE\n" + +#. Programmer's name for it: sRowError +#: Decision Cube/mxconsts.pas:27 +msgid "row error" +msgstr "Erreur ligne" + +#. Programmer's name for it: sAllValues +#: Decision Cube/mxconsts.pas:29 +msgid "All Values" +msgstr "Toutes les valeurs" + +#. Programmer's name for it: sMovetoRow +#: Decision Cube/mxconsts.pas:30 +msgid "Move to Row Area" +msgstr "Déplacer vers zone Ligne" + +#. Programmer's name for it: sMovetoCol +#: Decision Cube/mxconsts.pas:31 +msgid "Move to Column Area" +msgstr "Déplacer vers zone Colonne" + +#. Programmer's name for it: sMakeDimOpen +#: Decision Cube/mxconsts.pas:32 +msgid "Open Dimension" +msgstr "Ouvrir dimension" + +#. Programmer's name for it: sDrilled +#: Decision Cube/mxconsts.pas:33 +msgid "Drilled In" +msgstr "Perforé" + +#. Programmer's name for it: sCouldNotOpen +#: Decision Cube/mxconsts.pas:34 +msgid "The information requested could not be loaded. " +msgstr "L'information demandée n'a pas pu être chargée. " + +#. Programmer's name for it: sNoSumsAvailable +#: Decision Cube/mxconsts.pas:35 +msgid "No active summaries have been defined. " +msgstr "Aucun récapitulatif actif n'a été défini. " + +#. Programmer's name for it: sNoSumsCouldBeLoaded +#: Decision Cube/mxconsts.pas:36 +msgid "Not enough room available to load a summary. " +msgstr "Pas assez de place disponible pour charger un récapitulatif. " + +#. Programmer's name for it: sNoDimsAvailable +#: Decision Cube/mxconsts.pas:37 +msgid "No available dimensions have been defined. " +msgstr "Aucune dimension disponible n'a été définie. " + +#. Programmer's name for it: sNoDimsCouldBeLoaded +#: Decision Cube/mxconsts.pas:38 +msgid "Not enough space available to load a dimension. " +msgstr "Pas assez d'espace pour charger une dimension. " + +#. Programmer's name for it: sTemplatePrefix +#: Decision Cube/mxconsts.pas:40 +msgid "Template: " +msgstr "Modèle : " + +#. Programmer's name for it: sGridCellError +#: Decision Cube/mxconsts.pas:42 +msgid "[Error]" +msgstr "[Erreur]" + +#. Programmer's name for it: sTotalCaption +#: Decision Cube/mxconsts.pas:43 +msgid "Sum" +msgstr "Somme" + +#. Programmer's name for it: sActivateLabel +#: Decision Cube/mxconsts.pas:44 +msgid "Inactive Dimensions" +msgstr "Dimensions inactives" + +#. Programmer's name for it: sRowCaption +#: Decision Cube/mxconsts.pas:45 +msgid "R" +msgstr "L" + +#. Programmer's name for it: sColCaption +#: Decision Cube/mxconsts.pas:46 +msgid "C" +msgstr "C" + +#. Programmer's name for it: sCaptionMenu1 +#: Decision Cube/mxconsts.pas:47 +msgid "Display Data and Subtotals" +msgstr "Afficher les données et les sous-totaux" + +#. Programmer's name for it: sCaptionMenu2 +#: Decision Cube/mxconsts.pas:48 +msgid "Display Data Only" +msgstr "Afficher seulement les données" + +#. Programmer's name for it: sCaptionMenu3 +#: Decision Cube/mxconsts.pas:49 +msgid "Display Subtotals Only" +msgstr "Afficher seulement les sous-totaux" + +#. Programmer's name for it: sDrillIn +#: Decision Cube/mxconsts.pas:50 +msgid "Drill in to this value" +msgstr "Percer jusqu'à cette valeur" + +#. Programmer's name for it: sGridMenu1 +#: Decision Cube/mxconsts.pas:51 +msgid "Subtotals on/off" +msgstr "Sous-totaux oui/non" + +#. Programmer's name for it: sGridMenu2 +#: Decision Cube/mxconsts.pas:52 +msgid "Decision Cube Editor.." +msgstr "Editeur de cube de décision..." + +#. Programmer's name for it: sGridMenu3 +#: Decision Cube/mxconsts.pas:53 +msgid "Decision Query Editor.." +msgstr "Editeur de requête de décision..." + +#. Programmer's name for it: sGridMenu4 +#: Decision Cube/mxconsts.pas:54 +msgid "Show Detail Records.." +msgstr "Montrer les enregistrements détail." + +#. Programmer's name for it: sUnsupportedDataType +#: Decision Cube/mxconsts.pas:57 +msgid "Unsupported data type : %s" +msgstr "Type de données non supporté : %s" + +#. Programmer's name for it: sRowOutOfRange +#: Decision Cube/mxconsts.pas:58 +msgid "Row index out of range : %d" +msgstr "Index de ligne hors limites : %d" + +#. Programmer's name for it: sColOutOfRange +#: Decision Cube/mxconsts.pas:59 +msgid "Column index out of range : %d" +msgstr "Index de colonne hors limites : %d" + +#. Programmer's name for it: sDupeItem +#: Decision Cube/mxconsts.pas:60 +msgid "Duplicate item in array" +msgstr "Elément dupliqué dans le tableau" + +#. Programmer's name for it: sArrayIndexOutOfRange +#: Decision Cube/mxconsts.pas:61 +msgid "Array index out of range : %d" +msgstr "Index de tableau hors limites : %d" + +#. Programmer's name for it: sLowCapacityError +#: Decision Cube/mxconsts.pas:62 +msgid "The DecisionCube Capacity is low. Please deactivate dimensions or change the data set." +msgstr "La capacité du cube de décision est faible. Désactivez des dimensions ou modifiez le dataset." + +#. Programmer's name for it: sQryNotInitialized +#: Decision Cube/mxconsts.pas:63 +msgid "Query could not be run. Check that the query, SQL text, and Database are correct." +msgstr "La requête n'a pu être exécutée. Vérifiez que la requête, le texte SQL et la base de données sont corrects." + +#. Programmer's name for it: sSortedListError +#: Decision Cube/mxconsts.pas:64 +msgid "Operation not allowed on sorted string list." +msgstr "Opération non autorisée sur une liste de chaînes triée." + +#. Programmer's name for it: sDuplicateString +#: Decision Cube/mxconsts.pas:65 +msgid "String list does not allow duplicates." +msgstr "La liste de chaînes n'autorise pas les doublons." + +#. Programmer's name for it: sMaxAllowedSums +#: Decision Cube/mxconsts.pas:66 +msgid "The maximum allowed summaries of %d has been exceeded." +msgstr "Le nombre maximum de %d récapitulatifs a été dépassé." + +#. Programmer's name for it: sGeneralArrayError +#: Decision Cube/mxconsts.pas:67 +msgid "General array error." +msgstr "Erreur générale de tableau." + +#. Programmer's name for it: sDimIndexError +#: Decision Cube/mxconsts.pas:70 +msgid "Illegal Dimension Index" +msgstr "Index de dimension illégal" + +#. Programmer's name for it: sIllegalValueForBin +#: Decision Cube/mxconsts.pas:73 +msgid "Initial Value is not legal for this type of Grouping" +msgstr "Valeur initiale illégale pour ce type de groupage" + +#. Programmer's name for it: sIllegalDimMap +#: Decision Cube/mxconsts.pas:74 +msgid "Dimension Map is not the correct size" +msgstr "Carte de dimension de taille incorrecte" + +#. Programmer's name for it: sDimMapActiveError +#: Decision Cube/mxconsts.pas:75 +msgid "Cannot perform this action on an active Dimension Map" +msgstr "Impossible d'effectuer cette action sur une carte de dimensions active" + +#. Programmer's name for it: sNotAvailable +#: Decision Cube/mxconsts.pas:76 +msgid "Not Available" +msgstr "Non disponible" + +#. Programmer's name for it: sGetValueCounts +#: Decision Cube/mxconsts.pas:77 +msgid "Information required to do Maximum Cell limit is not current. Do you want to fetch it now?" +msgstr "L'information requise pour calculer la limite de cellule maximum n'est pas à jour. Voulez-vous l'obtenir maintenant ?" + +#. Programmer's name for it: sDateBinningNotAllowed +#: Decision Cube/mxconsts.pas:78 +msgid "Date grouping is not allowed for fields of this type" +msgstr "Le groupage par date n'est pas autorisé pour ces types de champs" + +#. Programmer's name for it: sEmptyDataSet +#: Decision Cube/mxconsts.pas:79 +msgid "Cannot build the Decision Cube with an empty data set" +msgstr "Impossible de construire le cube de décision avec un ensemble de données vide" + +#. Programmer's name for it: sNoDataSet +#: Decision Cube/mxconsts.pas:82 +msgid "Data set property is not assigned" +msgstr "La propriété dataset n'est pas affectée" + +#. Programmer's name for it: sNoAggs +#: Decision Cube/mxconsts.pas:83 +msgid "No summaries are defined. " +msgstr "Aucun récapitulatif n'est défini. " + +#. Programmer's name for it: sNoDims +#: Decision Cube/mxconsts.pas:84 +msgid "No dimension fields are defined. " +msgstr "Pas de champs de dimensions définis. " + +#. Programmer's name for it: sUnknownDims +#: Decision Cube/mxconsts.pas:85 +msgid "The dimension types for this dataset cannot be determined automatically. You must map the fields to dimensions or summaries with the Decision Cube Editor" +msgstr "Les types de dimensions pour cet ensemble de données ne peuvent être déterminés automatiquement. Vous devez affecter les champs aux dimensions ou récapitulatifs avec l'éditeur de cube de décision." + +#. Programmer's name for it: sGroupsMissing +#: Decision Cube/mxconsts.pas:86 +msgid "All dimension fields must be grouped. " +msgstr "Tous les champs de dimensions doivent être groupés. " + +#. Programmer's name for it: sDecisionQueryError +#. Programmer's name for it: sQueryError +#. Programmer's name for it: sDecisionQueryError +#. Programmer's name for it: sQueryError +#: Decision Cube/mxconsts.pas:87 +#: Vcl/mxconsts.pas:89 +msgid "The query may be incorrectly defined, or you may need to map its fields to active dimensions or summaries with the Decision Cube Editor" +msgstr "La requête est mal définie, ou vous devez affecter ses champs aux dimensions ou récapitulatifs actifs avec l'éditeur de cube de décision." + +#. Programmer's name for it: sDataSetError +#: Decision Cube/mxconsts.pas:88 +msgid "The dataset may be incorrectly defined, or you may need to map its fields to active dimensions or summaries with the Decision Cube Editor" +msgstr "Le dataset est incorrectement défini, ou vous devez affecter ses champs aux dimensions ou récapitulatifs actifs avec l'éditeur de cube de décision." + +#. Programmer's name for it: sCountStar +#: Decision Cube/mxconsts.pas:90 +msgid "COUNTALL" +msgstr "COUNTALL" + +#. Programmer's name for it: sAddAvgWarning +#: Decision Cube/mxconsts.pas:91 +msgid "Average is calculated using sum and count summaries for each field. The necessary summaries have been added." +msgstr "La moyenne est calculée en utilisant les récapitulatifs somme et nombre pour chaque champ. Les récapitulatifs nécessaires ont été ajoutés." + +#. Programmer's name for it: sAddAvgStarWarning +#: Decision Cube/mxconsts.pas:92 +msgid "Average is calculated using a field sum and count(*). The necessary summaries have been added." +msgstr "La moyenne est calculée en utilisant la somme et le nombre du champ(*). Les récapitulatifs nécessaires ont été ajoutés." + +#. Programmer's name for it: sQueryLegal +#: Decision Cube/mxconsts.pas:95 +msgid "Query is legal." +msgstr "La requête est légale." + +#. Programmer's name for it: sAddFieldExists +#: Decision Cube/mxconsts.pas:96 +msgid " is already in the query" +msgstr " est déjà dans la requête" + +#. Programmer's name for it: sAggTypeNotAllowed +#: Decision Cube/mxconsts.pas:97 +msgid " is not an allowed summary type" +msgstr " n'est pas un type de récapitulatif autorisé" + +#. Programmer's name for it: sDimTypeNotAllowed +#: Decision Cube/mxconsts.pas:98 +msgid " is not an allowed dimension type" +msgstr " n'est pas un type de dimension autorisé" + +#. Programmer's name for it: sAverageRequires +#: Decision Cube/mxconsts.pas:99 +msgid "Average summaries use Sum and Count" +msgstr "Les récapitulatifs Moyenne utilisent Sum et Count" + +#. Programmer's name for it: sWantToExit +#: Decision Cube/mxconsts.pas:100 +msgid "Do you still want to Exit?" +msgstr "Voulez-vous quand-même quitter ?" + +#. Programmer's name for it: sQueryIllegal +#: Decision Cube/mxconsts.pas:101 +msgid "The query you have created is not legal." +msgstr "La requête que vous avez créée n'est pas correcte." + +#. Programmer's name for it: sQueryEditIllegal +#: Decision Cube/mxconsts.pas:102 +msgid "The query you have entered is not legal. Please correct it before continuing." +msgstr "La requête que vous avez saisie n'est pas correcte. Veuillez la corriger avant de continuer." + +#. Programmer's name for it: sRemoveFieldError +#: Decision Cube/mxconsts.pas:103 +msgid "Could not remove the field" +msgstr "Impossible d'enlever le champ" + +#. Programmer's name for it: sAllFields +#: Decision Cube/mxconsts.pas:104 +msgid "All Fields" +msgstr "Tous les champs" + +#. Programmer's name for it: sQueryFields +#: Decision Cube/mxconsts.pas:105 +msgid "Query Fields" +msgstr "Champs de requête" + +#. Programmer's name for it: sEditDone +#: Decision Cube/mxconsts.pas:106 +msgid "&Edit Done" +msgstr "Modi&fications terminées" + +#. Programmer's name for it: sEditQuery +#. DSSQueryEditor..Pager..Query..EditQry..Caption +#: Decision Cube/mxconsts.pas:107 +msgid "&Edit Query" +msgstr "&Modifier la requête" + +#. Programmer's name for it: sQParseRemovedField +#: Decision Cube/mxconsts.pas:110 +msgid "One or more fields of a type which cannot be tabulated were removed from the query." +msgstr "Un champ ou plusieurs d'un type ne pouvant être tabulé ont été supprimés de la requête." + +#. Programmer's name for it: sCubeLimitsExceeded +#: Decision Cube/mxconsts.pas:113 +msgid "Decision Cube size excedes limits" +msgstr "La taille du cube de décision dépasse les limites" + +#. Programmer's name for it: sMaxAllowedDims +#: Decision Cube/mxconsts.pas:114 +msgid "The maximum allowed dimensions of %d has been exceeded." +msgstr "Le nombre maximum de %d dimensions a été dépassé." + +#. Programmer's name for it: sMaxAllowedCells +#: Decision Cube/mxconsts.pas:115 +msgid "Total cell count of %d exceeds the maximum of %d." +msgstr "Le nombre total de cellules, %d, dépasse le maximum de %d." + +#. Programmer's name for it: sUnsupportedFieldType +#: Decision Cube/mxconsts.pas:116 +msgid "Field %s has an unsupported data type: %s" +msgstr "Le champ %s a un type de données non supporté : %s" + +#. Programmer's name for it: sFetchValues +#: Decision Cube/mxconsts.pas:117 +msgid "Scanning data set values..." +msgstr "Parcours des valeurs de l'ensemble de données..." + +#. Programmer's name for it: sUserCanceled +#: Decision Cube/mxconsts.pas:118 +msgid "User canceled DecisionCube population." +msgstr "L'utilisateur a annulé la population du cube de décision." + +#. Programmer's name for it: sBinningValues +#: Decision Cube/mxconsts.pas:119 +msgid "Grouping values ..." +msgstr "Valeurs de groupage ..." + +#. Programmer's name for it: sCreatingIndexes +#: Decision Cube/mxconsts.pas:120 +msgid "Creating Cube index for %s ..." +msgstr "Création de l'indice de cube pour %s ..." + +#. Programmer's name for it: sCreateDerivedSummaryError +#: Decision Cube/mxconsts.pas:121 +msgid "Unable to create derived summary." +msgstr "Impossible de créer le récapitulatif dérivé." + +#. Programmer's name for it: sTrue +#. Programmer's name for it: STextTrue +#. Programmer's name for it: sTrue +#: Decision Cube/mxconsts.pas:122 +msgid "True" +msgstr "Vrai" + +#. Programmer's name for it: sFalse +#. Programmer's name for it: STextFalse +#. Programmer's name for it: sFalse +#: Decision Cube/mxconsts.pas:123 +msgid "False" +msgstr "Faux" + +#. Programmer's name for it: sBinTypeMismatch +#: Decision Cube/mxconsts.pas:124 +msgid "The bin type does not match the fieldtype." +msgstr "Le type de casier ne correspond pas au type de champ." + +#. Programmer's name for it: sFatalCacheError +#: Decision Cube/mxconsts.pas:125 +msgid "Fatal error in cache: code: %d" +msgstr "Erreur fatale dans le cache, code : %d" + +#. Programmer's name for it: sStringTypeNoSupported +#: Decision Cube/mxconsts.pas:126 +msgid "String Data type not supported for summaries" +msgstr "Type chaîne non supporté pour les récapitulatifs" + +#. Programmer's name for it: sDataSetTooLarge +#: Decision Cube/mxconsts.pas:127 +msgid "Dataset is too large" +msgstr "L'ensemble de données est trop grand" + +#. Programmer's name for it: sBuildingDataStore +#: Decision Cube/mxconsts.pas:128 +msgid "Building data store..." +msgstr "Construction du magasin de données..." + +#. Programmer's name for it: sSumLabel +#: Decision Cube/mxconsts.pas:131 +msgid "Sum of %s" +msgstr "Somme de %s" + +#. Programmer's name for it: sCountLabel +#: Decision Cube/mxconsts.pas:132 +msgid "Count of %s" +msgstr "Nombre de %s" + +#. Programmer's name for it: sMaxLabel +#: Decision Cube/mxconsts.pas:133 +msgid "Maximum of %s" +msgstr "Maximum de %s" + +#. Programmer's name for it: sMinLabel +#: Decision Cube/mxconsts.pas:134 +msgid "Minimum of %s" +msgstr "Minimum de %s" + +#. Programmer's name for it: sAverageLabel +#: Decision Cube/mxconsts.pas:135 +msgid "Average of %s" +msgstr "Moyenne de %s" + +#. Programmer's name for it: sVarLabel +#: Decision Cube/mxconsts.pas:136 +msgid "Variance of %s" +msgstr "Variance de %s" + +#. Programmer's name for it: sSDLabel +#: Decision Cube/mxconsts.pas:137 +msgid "Standard Deviation of %s" +msgstr "Ecart-type de %s" + +#. Programmer's name for it: sAggLabel +#: Decision Cube/mxconsts.pas:138 +msgid "Summary of %s" +msgstr "Récapitulatif de %s" + +#. Programmer's name for it: sUnsupportedVarType +#: Decision Cube/mxconsts.pas:139 +msgid "Unsupported Data Type %d" +msgstr "Type de données non supporté : %d" + +#. Programmer's name for it: sOtherValues +#: Decision Cube/mxconsts.pas:140 +msgid "Other Values" +msgstr "Autres valeurs" + +#. Programmer's name for it: sSelectFromError +#: Decision Cube/mxconsts.pas:142 +msgid "Query lacks a Select/From clause." +msgstr "Il manque une clause Select/From à la requête" + +#. Programmer's name for it: sArgumentExpected +#: Decision Cube/mxconsts.pas:143 +msgid "No argument provided for an operator or summary" +msgstr "Aucun argument fourni pour un opérateur ou un récapitulatif" + +#. Programmer's name for it: sGroupOnExpressionError +#: Decision Cube/mxconsts.pas:144 +msgid "An expression cannot be used for a grouping field" +msgstr "Une expression ne peut être utilisée dans un champ groupé" + +#. Programmer's name for it: SOutofBounds +#: Decision Cube/mxconsts.pas:146 +msgid "Out of Bounds" +msgstr "Hors limites" + +#. Programmer's name for it: sIDAPILangID +#. Programmer's name for it: SIDAPILangID +#. Programmer's name for it: sIDAPILangID +#: Decision Cube/mxconsts.pas:147 +msgid "0009" +msgstr "000C" + +#. Programmer's name for it: sComponentTabName +#: Decision Cube/mxdconst.pas:14 +msgid "Decision Cube" +msgstr "Decision Cube" + +#. Programmer's name for it: sQueryVerb0 +#: Decision Cube/mxdconst.pas:15 +msgid "&Graphical Query Builder..." +msgstr "&Constructeur de requêtes graphiques..." + +#. Programmer's name for it: sQueryVerb1 +#: Decision Cube/mxdconst.pas:16 +msgid "&Decision Query Editor..." +msgstr "Edite&ur de requête de décision..." + +#. Programmer's name for it: sCubeVerb0 +#: Decision Cube/mxdconst.pas:17 +msgid "&Decision Cube Editor..." +msgstr "Edite&ur de cube de décision..." + +#. Programmer's name for it: sCubeVerb1 +#: Decision Cube/mxdconst.pas:18 +msgid "&Query Editor..." +msgstr "Edite&ur de requête..." + +#. Programmer's name for it: sGridVerb0 +#: Decision Cube/mxdconst.pas:19 +msgid "Sub&totals on/off" +msgstr "&Sous-totaux oui/non" + +#. Programmer's name for it: sSourceVerb0 +#: Decision Cube/mxdconst.pas:20 +msgid "&Do not display Sparse Rows/Columns" +msgstr "Ne &pas afficher les lignes/colonnes éparses" + +#. Programmer's name for it: sSourceVerb1 +#: Decision Cube/mxdconst.pas:21 +msgid "&Display Sparse Rows/Columns" +msgstr "Afficher les &lignes/colonnes éparses" + +#. Programmer's name for it: sGridDimOptions +#: Decision Cube/mxdconst.pas:22 +msgid "Grid Dimension Options" +msgstr "Options de dimensions de grille" + +#. Programmer's name for it: sGridDimSettings +#: Decision Cube/mxdconst.pas:23 +msgid "Grid Dimension Settings" +msgstr "Paramètres de dimensions de grille" + +#. Programmer's name for it: sCubeProperties +#: Decision Cube/mxdconst.pas:24 +msgid "Cube Properties" +msgstr "Propriétés du cube" + +#. Programmer's name for it: sOnlyOneDataModuleAllowed +#: Internet/brkrconst.pas:14 +msgid "Only one data module per application" +msgstr "Impossible d'avoir plus d'un Data Module par application" + +#. Programmer's name for it: sNoDataModulesRegistered +#: Internet/brkrconst.pas:15 +msgid "No data modules registered" +msgstr "Aucun Data Module recensé" + +#. Programmer's name for it: sNoDispatcherComponent +#: Internet/brkrconst.pas:16 +msgid "No dispatcher component found on data module" +msgstr "Il n'y a aucun Dispatcher dans le Data Module" + +#. Programmer's name for it: sTooManyActiveConnections +#: Internet/brkrconst.pas:18 +msgid "Maximum number of concurrent connections exceeded. Please try again later" +msgstr "Nombre maximum de connexions ouvertes simultanément atteint. Veuillez réessayer ultérieurement" + +#. Programmer's name for it: sInternalServerError +#: Internet/brkrconst.pas:22 +msgid "" +"Internal Server Error 500\n" +"

                    Internal Server Error 500


                    \n" +"Exception: %s
                    \n" +"Message: %s
                    \n" +msgstr "" +"Erreur interne au serveur 500\n" +"

                    Erreur interne au serveur 500


                    \n" +"Exception: %s
                    \n" +"Message: %s
                    \n" + +#. Programmer's name for it: sDocumentMoved +#: Internet/brkrconst.pas:26 +msgid "" +"Document Moved 302\n" +"

                    Object Moved


                    \n" +"This Object may be found here.
                    \n" +"
                    \n" +msgstr "" +"Document déplacé 302\n" +"

                    Objet déplacé


                    \n" +"Vous trouverez l'objet recherché ici.
                    \n" +"
                    \n" + +#. Programmer's name for it: sInvalidISAPIApp +#: Internet/nstois.pas:109 +msgid "Invalid ISAPI application: %s" +msgstr "Application ISAPI invalide: %s" + +#. Programmer's name for it: sUnSupportedISAPIApp +#: Internet/nstois.pas:110 +msgid "Unsupported ISAPI Application version: %.8x" +msgstr "Version de programme ISAPI non supportée: %.8x" + +#. Programmer's name for it: sGEVFailed +#: Internet/nstois.pas:111 +msgid "Call to GetExtensionVersion FAILED. Error Code: %d" +msgstr "L'appel de GetExtensionVersion a échoué. Code erreur: %d" + +#. Programmer's name for it: sErrorLoadingISAPIApp +#: Internet/nstois.pas:112 +msgid "Error loading ISAPI Application: %s" +msgstr "Erreur lors du chargement de l'ISAPI: %s" + +#. Programmer's name for it: sInvalidRedirectParam +#: Internet/nstois.pas:113 +msgid "Invalid Redirect parameter" +msgstr "Paramètre Redirect incorrect" + +#. Programmer's name for it: sISAPIAppError +#: Internet/nstois.pas:114 +msgid "ISAPI Application Error" +msgstr "Erreur d'application ISAPI" + +#. Programmer's name for it: sDataSetFieldBlank +#: Internet/wbmconst.pas:15 +msgid "Data set field is blank" +msgstr "Le champ de dataset est vide." + +#. Programmer's name for it: sDataSetFieldNotFound +#: Internet/wbmconst.pas:16 +msgid "Data set field not found: %s" +msgstr "Champ de dataset non trouvé : %s" + +#. Programmer's name for it: sNotDataSetField +#: Internet/wbmconst.pas:17 +msgid "Field is not a dataset field: %s" +msgstr "Le champ n'est pas un champ de dataset : %s" + +#. Programmer's name for it: ScriptTableName +#: Internet/wbmconst.pas:18 +msgid "%s_Table" +msgstr "%s_Table" + +#. Programmer's name for it: sNoXMLBroker +#: Internet/wbmconst.pas:19 +msgid "%s: missing XMLBroker" +msgstr "%s: il manque XMLBroker" + +#. Programmer's name for it: sFieldNotFound +#: Internet/wbmconst.pas:20 +msgid "%0:s: Field \"%1:s\" not found" +msgstr "%0:s: Champ \"%1:s\" non trouvé" + +#. Programmer's name for it: sXMLBrokerNotDefined +#: Internet/wbmconst.pas:21 +msgid "%s.XMLBroker = nil" +msgstr "%s.XMLBroker = nil" + +#. Programmer's name for it: sSubmitQuery +#: Internet/wbmconst.pas:22 +msgid "Submit" +msgstr "Soumettre" + +#. Programmer's name for it: sResetQuery +#: Internet/wbmconst.pas:23 +msgid "Reset" +msgstr "Réinitialiser" + +#. Programmer's name for it: sApplyUpdates +#: Internet/wbmconst.pas:24 +msgid "Apply Updates" +msgstr "Appliquer les modifications" + +#. Programmer's name for it: sFieldNameBlank +#: Internet/wbmconst.pas:25 +msgid "%s.FieldName = ''" +msgstr "%s.FieldName = ''" + +#. Programmer's name for it: sXMLComponentNotDefined +#: Internet/wbmconst.pas:26 +msgid "%s.XMLComponent = nil" +msgstr "%s.XMLComponent = nil" + +#. Programmer's name for it: ScriptNamesVar +#: Internet/wbmconst.pas:27 +msgid "%s_Names" +msgstr "%s_Names" + +#. Programmer's name for it: ScriptIDsVar +#: Internet/wbmconst.pas:28 +msgid "%s_IDs" +msgstr "%s_IDs" + +#. Programmer's name for it: ScriptXMLDisplayName +#: Internet/wbmconst.pas:29 +msgid "%s_Disp" +msgstr "%s_Display" + +#. Programmer's name for it: sInvalidParent +#: Internet/wbmconst.pas:30 +msgid "Invalid parent" +msgstr "Parent incorrect" + +#. Programmer's name for it: sDuplicateStatusField +#: Internet/wbmconst.pas:31 +msgid "Field %s ignored, only one status field allowed" +msgstr "Champ %s ignoré, un seul champ d'état autorisé" + +#. Programmer's name for it: sFirstButton +#: Internet/wbmconst.pas:32 +msgid "|<" +msgstr "|<" + +#. Programmer's name for it: sLastButton +#: Internet/wbmconst.pas:33 +msgid ">|" +msgstr ">|" + +#. Programmer's name for it: sPriorButton +#: Internet/wbmconst.pas:34 +msgid "<" +msgstr "<" + +#. Programmer's name for it: sNextButton +#: Internet/wbmconst.pas:35 +msgid ">" +msgstr ">" + +#. Programmer's name for it: sPriorPageButton +#: Internet/wbmconst.pas:36 +msgid "<<" +msgstr "<<" + +#. Programmer's name for it: sNextPageButton +#: Internet/wbmconst.pas:37 +msgid ">>" +msgstr ">>" + +#. Programmer's name for it: sDeleteButton +#: Internet/wbmconst.pas:38 +msgid " - " +msgstr " - " + +#. Programmer's name for it: sInsertButton +#: Internet/wbmconst.pas:39 +msgid " + " +msgstr " + " + +#. Programmer's name for it: sUndoButton +#: Internet/wbmconst.pas:40 +msgid "Undo" +msgstr "Défaire" + +#. Programmer's name for it: sPostButton +#: Internet/wbmconst.pas:41 +msgid "Post" +msgstr "Poster" + +#. Programmer's name for it: sWarningsBody +#: Internet/wbmconst.pas:46 +msgid "" +"\n" +"\n" +"

                    Design-time Warnings

                    \n" +"%s\n" +"

                    \n" +msgstr "" +"\n" +"\n" +"

                    Avertissements de conception

                    \n" +"%s\n" +"

                    \n" + +#. Programmer's name for it: ScriptDocumentVarName +#: Internet/wbmconst.pas:47 +msgid "%s_Doc" +msgstr "%s_Doc" + +#. Programmer's name for it: ScriptXMLVarName +#: Internet/wbmconst.pas:48 +msgid "%s_XML" +msgstr "%s_Xml" + +#. Programmer's name for it: sInvalidWebComponentsRegistration +#: Internet/wbmconst.pas:49 +msgid "Invalid Web component registration" +msgstr "Recensement de composant Web incorrect" + +#. Programmer's name for it: sInvalidWebComponentsEnumeration +#: Internet/wbmconst.pas:50 +msgid "Invalid Web component enumeration" +msgstr "Enumération de composant Web incorrecte" + +#. Programmer's name for it: sInvalidWebComponentsCreation +#: Internet/wbmconst.pas:51 +msgid "Invalid Web component creation" +msgstr "Création de composant Web incorrecte" + +#. Programmer's name for it: ScriptRowSetVarName +#: Internet/wbmconst.pas:52 +msgid "%s_RS" +msgstr "%s_RowSet" + +#. Programmer's name for it: sApplyUpdatesError +#: Internet/wbmconst.pas:53 +msgid "ApplyUpdates error. Error count: %d." +msgstr "Erreur ApplyUpdates. Nombre d'erreurs : %d." + +#. Programmer's name for it: sDeltaNotFound +#: Internet/wbmconst.pas:54 +msgid "Missing Delta Packet" +msgstr "Paquet Delta manquant" + +#. Programmer's name for it: sXMLBrokerNotConnected +#: Internet/wbmconst.pas:55 +msgid "XMLBroker: %s is not connected" +msgstr "XMLBroker : %s n'est pas connecté" + +#. Programmer's name for it: sDataSetNotActive +#: Internet/wbmconst.pas:56 +msgid "DataSet: %s is not active" +msgstr "Le dataSet : %s n'est pas actif" + +#. Programmer's name for it: SNewLookupFieldCaption +#: Property Editors/dsdefine.pas:442 +msgid "New Lookup Field" +msgstr "Nouveau champ de recherche" + +#. Programmer's name for it: srSamples +#: Samples/ibconst.pas:6 +msgid "Samples" +msgstr "Exemples" + +#. Programmer's name for it: SNoEventsRegistered +#: Samples/ibconst.pas:7 +msgid "You must register events before queueing them" +msgstr "Vous devez recenser les événements avant de les mettre dans la queue" + +#. Programmer's name for it: SInvalidDBConnection +#: Samples/ibconst.pas:8 +msgid "Component is not connected to an open Database" +msgstr "Le composant n'est pas connecté à une base de données ouverte" + +#. Programmer's name for it: SInvalidDatabase +#: Samples/ibconst.pas:9 +msgid "''%s'' is not connected to an InterBase database" +msgstr "''%s'' n'est pas connecté à une base de données InterBase" + +#. Programmer's name for it: SInvalidCancellation +#: Samples/ibconst.pas:10 +msgid "You cannot call CancelEvents from within an OnEventAlert handler" +msgstr "Vous ne pouvez pas appeler CancelEvents depuis un gestionnaire OnEventAlerterr" + +#. Programmer's name for it: SInvalidEvent +#: Samples/ibconst.pas:11 +msgid "Invalid blank event added to EventAlerter events list" +msgstr "Evénement vide ajouté à la liste d'événements EventAlerter incorrect" + +#. Programmer's name for it: SInvalidQueueing +#: Samples/ibconst.pas:12 +msgid "You cannot call QueueEvents from within an OnEventAlert handler" +msgstr "Vous ne pouvez appeler QueueEvents depuis un gestionnaire OnEventAlerter" + +#. Programmer's name for it: SInvalidRegistration +#: Samples/ibconst.pas:13 +msgid "You cannot Register or Unregister events from within an OnEventAlert handler" +msgstr "Vous ne pouvez appeler Register ou Unregister depuis un gestionnaire OnEventAlerter" + +#. Programmer's name for it: SMaximumEvents +#: Samples/ibconst.pas:13 +msgid "You can only register 15 events per EventAlerter" +msgstr "Vous ne pouvez recenser que 15 événements par EventAlerter" + +#. Programmer's name for it: SInterbaseNotInstalled +#: Samples/ibctrls.pas:103 +msgid "You must have Interbase installed to use this component" +msgstr "InterBase doit être installé pour pouvoir utiliser ce composant" + +#. Programmer's name for it: SFailedQueEvents +#: Samples/ibctrls.pas:104 +msgid "Failed to lookup isc_que_events" +msgstr "Echec de la consultation de isc_que_events" + +#. Programmer's name for it: SFailedInterprete +#: Samples/ibctrls.pas:105 +msgid "Failed to lookup isc_interprete" +msgstr "Echec de la consultation de isc_interprete" + +#. Programmer's name for it: SFailedFree +#: Samples/ibctrls.pas:106 +msgid "Failed to lookup isc_free" +msgstr "Echec de la consultation de isc_free" + +#. Programmer's name for it: SFailedEventBlock +#: Samples/ibctrls.pas:107 +msgid "Failed to lookup isc_event_block" +msgstr "Echec de la consultation de isc_event_block" + +#. Programmer's name for it: SFailedEventCounts +#: Samples/ibctrls.pas:108 +msgid "Failed to lookup isc_event_counts" +msgstr "Echec de la consultation de isc_event_counts" + +#. Programmer's name for it: SFailedCancelEvents +#: Samples/ibctrls.pas:109 +msgid "Failed to lookup isc_cancel_events" +msgstr "Echec de la consultation de isc_cancel_events" + +#. Programmer's name for it: SInvalidEnumValue +#: Vcl/adoconst.pas:15 +msgid "Invalid Enum Value" +msgstr "Valeur enum incorrecte" + +#. Programmer's name for it: SMissingConnection +#: Vcl/adoconst.pas:16 +msgid "Missing Connection or ConnectionString" +msgstr "Connexion ou ConnectionString manquante" + +#. Programmer's name for it: SNoDetailFilter +#: Vcl/adoconst.pas:17 +msgid "Filter property cannot be used for detail tables" +msgstr "La propriété Filter ne peut être utilisée pour les tables détail" + +#. Programmer's name for it: SBookmarksRequired +#: Vcl/adoconst.pas:18 +msgid "Dataset does not support bookmarks, which are required for multi-record data controls" +msgstr "Le dataset ne supporte pas les marques (bookmark), qui sont requises pour les contrôles de données multienregistrement" + +#. Programmer's name for it: SMissingCommandText +#: Vcl/adoconst.pas:19 +msgid "Missing %s property" +msgstr "Propriété %s manquante" + +#. Programmer's name for it: SNoResultSet +#: Vcl/adoconst.pas:20 +msgid "CommandText does not return a result set" +msgstr "CommandText ne renvoie pas un ensemble de résultats" + +#. Programmer's name for it: SADOCreateError +#: Vcl/adoconst.pas:21 +msgid "Error creating object. Please verify that the Microsoft Data Access Components 2.1 (or later) have been properly installed" +msgstr "Erreur à la création de l'objet. Vérifiez que les composants Microsoft Data Access 2.1 (ou supérieur) ont été correctement installés" + +#. Programmer's name for it: SEventsNotSupported +#: Vcl/adoconst.pas:22 +msgid "Events are not supported with server side TableDirect cursors" +msgstr "Les événements ne sont pas supportés avec les curseurs TableDirect côté serveur" + +#. Programmer's name for it: SUsupportedFieldType +#: Vcl/adoconst.pas:23 +msgid "Unsupported field type (%s) in field %s" +msgstr "Type de champ non supporté (%s) dans le champ %s" + +#. Programmer's name for it: SNoMatchingADOType +#: Vcl/adoconst.pas:24 +msgid "No matching ADO data type for %s" +msgstr "Aucun type de données ADO correspondant pour %s" + +#. Programmer's name for it: SConnectionRequired +#: Vcl/adoconst.pas:25 +msgid "A connection component is required for async ExecuteOptions" +msgstr "Un composant connexion est requis pour ExecuteOptions asynchrone" + +#. Programmer's name for it: SCantRequery +#: Vcl/adoconst.pas:26 +msgid "Cannot perform a requery after connection has changed" +msgstr "Ne peut effectuer une requête après que la connexion a changé" + +#. Programmer's name for it: SNoFilterOptions +#: Vcl/adoconst.pas:27 +msgid "FilterOptions are not supported" +msgstr "Les FilterOptions ne sont pas supportées" + +#. Programmer's name for it: SAutoSessionExclusive +#: Vcl/bdeconst.pas:15 +msgid "Cannot enable AutoSessionName property with more than one session on a form or data-module" +msgstr "Impossible d'activer la propriété AutoSessionName avec plus d'une session sur une fiche ou un module de données" + +#. Programmer's name for it: SAutoSessionExists +#: Vcl/bdeconst.pas:16 +msgid "Cannot add a session to the form or data-module while session '%s' has AutoSessionName enabled" +msgstr "Impossible d'ajouter une session à la fiche ou au module de données alors que la session '%s' a AutoSessionName activé" + +#. Programmer's name for it: SAutoSessionActive +#: Vcl/bdeconst.pas:17 +msgid "Cannot modify SessionName while AutoSessionName is enabled" +msgstr "Impossible de modifier SessionName alors que AutoSessionName est activé" + +#. Programmer's name for it: SDuplicateDatabaseName +#: Vcl/bdeconst.pas:18 +msgid "Duplicate database name '%s'" +msgstr "Nom de base de données dupliqué '%s'" + +#. Programmer's name for it: SDuplicateSessionName +#: Vcl/bdeconst.pas:19 +msgid "Duplicate session name '%s'" +msgstr "Nom de session dupliqué '%s'" + +#. Programmer's name for it: SInvalidSessionName +#: Vcl/bdeconst.pas:20 +msgid "Invalid session name %s" +msgstr "Nom de session %s incorrect" + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/bdeconst.pas:21 +msgid "Database name missing" +msgstr "Nom de base de données manquant" + +#. Programmer's name for it: SSessionNameMissing +#: Vcl/bdeconst.pas:22 +msgid "Session name missing" +msgstr "Nom de session manquant" + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/bdeconst.pas:23 +msgid "Cannot perform this operation on an open database" +msgstr "Impossible d'effectuer cette opération sur une table ouverte" + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/bdeconst.pas:24 +msgid "Cannot perform this operation on a closed database" +msgstr "Impossible d'effectuer cette opération sur une table fermée" + +#. Programmer's name for it: SDatabaseHandleSet +#: Vcl/bdeconst.pas:25 +msgid "Database handle owned by a different session" +msgstr "Le handle de base de données appartient à une autre session" + +#. Programmer's name for it: SSessionActive +#: Vcl/bdeconst.pas:26 +msgid "Cannot perform this operation on an active session" +msgstr "Impossible d'effectuer cette opération sur une session active" + +#. Programmer's name for it: SHandleError +#: Vcl/bdeconst.pas:27 +msgid "Error creating cursor handle" +msgstr "Erreur à la création du handle de curseur" + +#. Programmer's name for it: SInvalidFloatField +#: Vcl/bdeconst.pas:28 +msgid "Cannot convert field '%s' to a floating point value" +msgstr "Impossible de convertir le champ '%s' en valeur flottante" + +#. Programmer's name for it: SInvalidIntegerField +#: Vcl/bdeconst.pas:29 +msgid "Cannot convert field '%s' to an integer value" +msgstr "Impossible de convertir le champ '%s' en valeur entière" + +#. Programmer's name for it: STableMismatch +#: Vcl/bdeconst.pas:30 +msgid "Source and destination tables are incompatible" +msgstr "Les tables source et destination sont incompatibles" + +#. Programmer's name for it: SFieldAssignError +#: Vcl/bdeconst.pas:31 +msgid "Fields '%s' and '%s' are not assignment compatible" +msgstr "Les champs '%s' et '%s' ne sont pas compatibles pour une affectation" + +#. Programmer's name for it: SNoReferenceTableName +#: Vcl/bdeconst.pas:32 +msgid "ReferenceTableName not specified for field '%s'" +msgstr "Table de référence non spécifiée pour le champ '%s'" + +#. Programmer's name for it: SCompositeIndexError +#: Vcl/bdeconst.pas:33 +msgid "Cannot use array of Field values with Expression Indices" +msgstr "Impossible d'utiliser de valeurs tableau de champs avec des Indices Expression" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/bdeconst.pas:34 +msgid "Invalid batch move parameters" +msgstr "Paramètres de déplacement batch incorrects" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/bdeconst.pas:35 +msgid "No SQL statement available" +msgstr "Aucune instruction SQL disponible" + +#. Programmer's name for it: SNoParameterValue +#: Vcl/bdeconst.pas:36 +msgid "No value for parameter '%s'" +msgstr "Pas de valeur pour le paramètre '%s'" + +#. Programmer's name for it: SNoParameterType +#: Vcl/bdeconst.pas:37 +msgid "No parameter type for parameter '%s'" +msgstr "Pas de type pour le paramètre '%s'" + +#. Programmer's name for it: SLoginError +#: Vcl/bdeconst.pas:38 +msgid "Cannot connect to database '%s'" +msgstr "Impossible de se connecter à la base '%s'" + +#. Programmer's name for it: SInitError +#: Vcl/bdeconst.pas:39 +msgid "An error occurred while attempting to initialize the Borland Database Engine (error $%.4x)" +msgstr "Une erreur est survenue lors de l'initialisation de Borland Database Engine (erreur $%.4x)" + +#. Programmer's name for it: SDatabaseEditor +#. Programmer's name for it: SIBDatabaseEditor +#: Vcl/bdeconst.pas:40 +msgid "Da&tabase Editor..." +msgstr "Edite&ur base de données..." + +#. Programmer's name for it: SExplore +#: Vcl/bdeconst.pas:41 +msgid "E&xplore" +msgstr "Exp&lorateur" + +#. Programmer's name for it: SLinkDetail +#: Vcl/bdeconst.pas:42 +msgid "'%s' cannot be opened" +msgstr "'%s' ne peut être ouvert" + +#. Programmer's name for it: SLinkMasterSource +#: Vcl/bdeconst.pas:43 +msgid "The MasterSource property of '%s' must be linked to a DataSource" +msgstr "La propriété MasterSource de '%s' doit être liée à une source de données" + +#. Programmer's name for it: SLinkMaster +#: Vcl/bdeconst.pas:44 +msgid "Unable to open the MasterSource Table" +msgstr "Impossible d'ouvrir la table MasterSource" + +#. Programmer's name for it: SGQEVerb +#: Vcl/bdeconst.pas:45 +msgid "S&QL Builder..." +msgstr "Constructeur &SQL..." + +#. Programmer's name for it: SBindVerb +#: Vcl/bdeconst.pas:46 +msgid "Define &Parameters..." +msgstr "Définir les ¶mètres..." + +#. Programmer's name for it: SDisconnectDatabase +#: Vcl/bdeconst.pas:48 +msgid "Database is currently connected. Disconnect and continue?" +msgstr "La base de données est connectée. Déconnecter et continuer ?" + +#. Programmer's name for it: SBDEError +#: Vcl/bdeconst.pas:49 +msgid "BDE error $%.4x" +msgstr "Erreur BDE $%.4x" + +#. Programmer's name for it: SLookupSourceError +#: Vcl/bdeconst.pas:50 +msgid "Unable to use duplicate DataSource and LookupSource" +msgstr "Impossible d'utiliser DataSource et LookupSource dupliqués" + +#. Programmer's name for it: SLookupTableError +#: Vcl/bdeconst.pas:51 +msgid "LookupSource must be connected to TTable component" +msgstr "LookupSource doit être connecté au composant TTable" + +#. Programmer's name for it: SLookupIndexError +#: Vcl/bdeconst.pas:52 +msgid "%s must be the lookup table's active index" +msgstr "%s doit être l'index actif de la table de référence" + +#. Programmer's name for it: SParameterTypes +#: Vcl/bdeconst.pas:53 +msgid ";Input;Output;Input/Output;Result" +msgstr ";Entrée;Sortie;Entrée/Sortie;Résultat" + +#. Programmer's name for it: SInvalidParamFieldType +#: Vcl/bdeconst.pas:54 +msgid "Must have a valid field type selected" +msgstr "Un type de champ correct doit être sélectionné" + +#. Programmer's name for it: STruncationError +#: Vcl/bdeconst.pas:55 +msgid "Parameter '%s' truncated on output" +msgstr "Paramètre '%s' tronqué en sortie" + +#. Programmer's name for it: SDataTypes +#: Vcl/bdeconst.pas:56 +msgid ";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" +msgstr ";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" + +#. Programmer's name for it: SResultName +#: Vcl/bdeconst.pas:57 +msgid "Result" +msgstr "Result" + +#. Programmer's name for it: SDBCaption +#: Vcl/bdeconst.pas:58 +msgid "%s%s%s Database" +msgstr "Base de données %s%s%s" + +#. Programmer's name for it: SParamEditor +#: Vcl/bdeconst.pas:59 +msgid "%s%s%s Parameters" +msgstr "Paramètres %s%s%s" + +#. Programmer's name for it: SIndexFilesEditor +#: Vcl/bdeconst.pas:60 +msgid "%s%s%s Index Files" +msgstr "Fichiers index %s%s%s" + +#. Programmer's name for it: SNoIndexFiles +#. Programmer's name for it: srNone +#: Vcl/bdeconst.pas:61 +msgid "(None)" +msgstr "(vide)" + +#. Programmer's name for it: SIndexDoesNotExist +#: Vcl/bdeconst.pas:62 +msgid "Index does not exist. Index: %s" +msgstr "L'index n'existe pas. Index : %s" + +#. Programmer's name for it: SNoTableName +#: Vcl/bdeconst.pas:63 +msgid "Missing TableName property" +msgstr "Propriété TableName manquante" + +#. Programmer's name for it: SNoDataSetField +#: Vcl/bdeconst.pas:64 +msgid "Missing DataSetField property" +msgstr "Propriété DataSetField manquante" + +#. Programmer's name for it: SBatchExecute +#. Programmer's name for it: SExecute +#: Vcl/bdeconst.pas:65 +msgid "E&xecute" +msgstr "Exéc&uter" + +#. Programmer's name for it: SNoCachedUpdates +#: Vcl/bdeconst.pas:66 +msgid "Not in cached update mode" +msgstr "Pas en mode modification cachée" + +#. Programmer's name for it: SInvalidAliasName +#: Vcl/bdeconst.pas:67 +msgid "Invalid alias name %s" +msgstr "Nom d'alias %s incorrect" + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/bdeconst.pas:68 +msgid "Cannot access field '%s' in a filter" +msgstr "Impossible d'accéder au champ '%s' dans un filtre" + +#. Programmer's name for it: SUpdateSQLEditor +#. Programmer's name for it: SIBUpdateSQLEditor +#: Vcl/bdeconst.pas:69 +msgid "&UpdateSQL Editor..." +msgstr "Editeur &UpdateSQL..." + +#. Programmer's name for it: SNoDataSet +#: Vcl/bdeconst.pas:70 +msgid "No dataset association" +msgstr "Il n'y a pas d'association de dataset" + +#. Programmer's name for it: SUntitled +#: Vcl/bdeconst.pas:71 +msgid "Untitled Application" +msgstr "Application sans titre" + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/bdeconst.pas:72 +msgid "Cannot update, %s is not owned by %s" +msgstr "Impossible de mettre à jour, %s n'est pas possédé par %s" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/bdeconst.pas:73 +msgid "Update failed" +msgstr "Echec de la mise à jour" + +#. Programmer's name for it: SSQLGenSelect +#: Vcl/bdeconst.pas:74 +msgid "Must select at least one key field and one update field" +msgstr "Vous devez sélectionner au moins un champ clé et un champ de mise à jour" + +#. Programmer's name for it: SSQLNotGenerated +#: Vcl/bdeconst.pas:75 +msgid "Update SQL statements not generated, exit anyway?" +msgstr "Instructions de mise à jour SQL non générées, quitter quand même ?" + +#. Programmer's name for it: SSQLDataSetOpen +#: Vcl/bdeconst.pas:76 +msgid "Unable to determine field names for %s" +msgstr "Impossible de déterminer les noms de champs pour %s" + +#. Programmer's name for it: SLocalTransDirty +#: Vcl/bdeconst.pas:77 +msgid "The transaction isolation level must be dirty read for local databases" +msgstr "Le niveau d'isolation de transaction doit être Lecture Dirty (dirty read) pour les bases locales" + +#. Programmer's name for it: SMissingDataSet +#: Vcl/bdeconst.pas:78 +msgid "Missing DataSet property" +msgstr "Propriété DataSet manquante" + +#. Programmer's name for it: SNoProvider +#: Vcl/bdeconst.pas:79 +msgid "No provider available" +msgstr "Aucun fournisseur disponible" + +#. Programmer's name for it: SNotAQuery +#: Vcl/bdeconst.pas:80 +msgid "Dataset is not a query" +msgstr "Le dataset n'est pas une requête" + +#. Programmer's name for it: sTabFailClear +#: Vcl/comstrs.pas:15 +msgid "Failed to clear tab control" +msgstr "Echec à l'effacement du contrôle onglet" + +#. Programmer's name for it: sTabFailDelete +#: Vcl/comstrs.pas:16 +msgid "Failed to delete tab at index %d" +msgstr "Echec à la suppression de l'onglet d'indice %d" + +#. Programmer's name for it: sTabFailRetrieve +#: Vcl/comstrs.pas:17 +msgid "Failed to retrieve tab at index %d" +msgstr "Echec à la récupération de l'onglet d'indice %d" + +#. Programmer's name for it: sTabFailGetObject +#: Vcl/comstrs.pas:18 +msgid "Failed to get object at index %d" +msgstr "Echec à l'obtention de l'objet à l'indice %d" + +#. Programmer's name for it: sTabFailSet +#: Vcl/comstrs.pas:19 +msgid "Failed to set tab \"%s\" at index %d" +msgstr "Echec pour mettre l'onglet %s à l'indice %d" + +#. Programmer's name for it: sTabFailSetObject +#: Vcl/comstrs.pas:20 +msgid "Failed to set object at index %d" +msgstr "Echec pour mettre l'objet à l'indice %d" + +#. Programmer's name for it: sTabMustBeMultiLine +#: Vcl/comstrs.pas:21 +msgid "MultiLine must be True when TabPosition is tpLeft or tpRight" +msgstr "MultiLine doit être vrai lorsque TabPosition est tpLeft ou tpRight" + +#. Programmer's name for it: sInvalidLevel +#: Vcl/comstrs.pas:23 +msgid "Invalid item level assignment" +msgstr "Affectation de niveau d'élément incorrecte" + +#. Programmer's name for it: sInvalidLevelEx +#: Vcl/comstrs.pas:24 +msgid "Invalid level (%d) for item \"%s\"" +msgstr "Niveau incorrect (%d) pour l'élément \"%s\"" + +#. Programmer's name for it: sInvalidIndex +#: Vcl/comstrs.pas:25 +msgid "Invalid index" +msgstr "Index incorrect" + +#. Programmer's name for it: sInsertError +#: Vcl/comstrs.pas:26 +msgid "Unable to insert an item" +msgstr "Impossible d'insérer un élément" + +#. Programmer's name for it: sInvalidOwner +#: Vcl/comstrs.pas:28 +msgid "Invalid owner" +msgstr "Propriétaire incorrect" + +#. Programmer's name for it: sUnableToCreateColumn +#: Vcl/comstrs.pas:29 +msgid "Unable to create new column" +msgstr "Impossible de créer une nouvelle colonne" + +#. Programmer's name for it: sUnableToCreateItem +#: Vcl/comstrs.pas:30 +msgid "Unable to create new item" +msgstr "Impossible de créer un nouvel élément" + +#. Programmer's name for it: sRichEditInsertError +#: Vcl/comstrs.pas:32 +msgid "RichEdit line insertion error" +msgstr "Erreur d'insertion de ligne RichEdit" + +#. Programmer's name for it: sRichEditLoadFail +#: Vcl/comstrs.pas:33 +msgid "Failed to Load Stream" +msgstr "Erreur au chargement du flux" + +#. Programmer's name for it: sRichEditSaveFail +#: Vcl/comstrs.pas:34 +msgid "Failed to Save Stream" +msgstr "Erreur à l'enregistrement du flux" + +#. Programmer's name for it: sTooManyPanels +#: Vcl/comstrs.pas:36 +msgid "StatusBar cannot have more than 64 panels" +msgstr "StatusBar ne peut avoir plus de 64 volets" + +#. Programmer's name for it: sHKError +#: Vcl/comstrs.pas:38 +msgid "Error assigning Hot-Key to %s. %s" +msgstr "Erreur d'affectation de raccourci clavier à %s. %s" + +#. Programmer's name for it: sHKInvalid +#: Vcl/comstrs.pas:39 +msgid "Hot-Key is invalid" +msgstr "Raccourci clavier incorrect" + +#. Programmer's name for it: sHKInvalidWindow +#: Vcl/comstrs.pas:40 +msgid "Window is invalid or a child window" +msgstr "Fenêtre incorrecte ou fenêtre enfant" + +#. Programmer's name for it: sHKAssigned +#: Vcl/comstrs.pas:41 +msgid "Hot-Key is assigned to another window" +msgstr "Raccourci clavier affecté à une autre fenêtre" + +#. Programmer's name for it: sUDAssociated +#: Vcl/comstrs.pas:43 +msgid "%s is already associated with %s" +msgstr "%s est déjà associé avec %s" + +#. Programmer's name for it: sPageIndexError +#: Vcl/comstrs.pas:46 +msgid "%d is an invalid PageIndex value. PageIndex must be between 0 and %d" +msgstr "%d est une valeur de PageIndex incorrecte. PageIndex doit être compris entre 0 et %d" + +#. Programmer's name for it: sInvalidComCtl32 +#: Vcl/comstrs.pas:48 +msgid "This control requires version 4.70 or greater of COMCTL32.DLL" +msgstr "Ce contrôle nécessite COMCTL32.DLL version 4.70 ou supérieure" + +#. Programmer's name for it: sDateTimeMax +#: Vcl/comstrs.pas:50 +msgid "Date exceeds maximum of %s" +msgstr "La date dépasse le maximum de %s" + +#. Programmer's name for it: sDateTimeMin +#: Vcl/comstrs.pas:51 +msgid "Date is less than minimum of %s" +msgstr "La date est inférieure au minimum de %s" + +#. Programmer's name for it: sNeedAllowNone +#: Vcl/comstrs.pas:52 +msgid "You must be in ShowCheckbox mode to set to this date" +msgstr "Vous devez être en mode ShowCheckBox pour définir cette date" + +#. Programmer's name for it: sFailSetCalDateTime +#: Vcl/comstrs.pas:53 +msgid "Failed to set calendar date or time" +msgstr "Echec lors du paramétrage de la date ou l'heure du calendrier" + +#. Programmer's name for it: sFailSetCalMaxSelRange +#: Vcl/comstrs.pas:54 +msgid "Failed to set maximum selection range" +msgstr "Echec lors du paramétrage de l'étendue de sélection maximum" + +#. Programmer's name for it: sFailSetCalMinMaxRange +#: Vcl/comstrs.pas:55 +msgid "Failed to set calendar min/max range" +msgstr "Echec lors du paramétrage de l'étendue minimum/maximum du calendrier" + +#. Programmer's name for it: sCalRangeNeedsMultiSelect +#: Vcl/comstrs.pas:56 +msgid "Date range can only be used in multiselect mode" +msgstr "Une étendue de date ne peut être utilisée qu'en mode multisélection" + +#. Programmer's name for it: sFailsetCalSelRange +#: Vcl/comstrs.pas:57 +msgid "Failed to set calendar selected range" +msgstr "Echec lors du paramétrage de l'étendue sélectionnée du calendrier" + +#. Programmer's name for it: SOpenFileTitle +#. IndexFiles..OpenDialog..Title +#: Vcl/consts.pas:15 +msgid "Open" +msgstr "Ouvrir" + +#. Programmer's name for it: SAssignError +#: Vcl/consts.pas:16 +msgid "Cannot assign a %s to a %s" +msgstr "Impossible d'affecter %s à %s" + +#. Programmer's name for it: SFCreateError +#: Vcl/consts.pas:17 +msgid "Cannot create file %s" +msgstr "Impossible de créer le fichier %s" + +#. Programmer's name for it: SFOpenError +#: Vcl/consts.pas:18 +msgid "Cannot open file %s" +msgstr "Impossible d'ouvrir le fichier %s" + +#. Programmer's name for it: SReadError +#: Vcl/consts.pas:19 +msgid "Stream read error" +msgstr "Erreur de lecture du flux" + +#. Programmer's name for it: SWriteError +#: Vcl/consts.pas:20 +msgid "Stream write error" +msgstr "Erreur d'écriture dans le flux" + +#. Programmer's name for it: SMemoryStreamError +#: Vcl/consts.pas:21 +msgid "Out of memory while expanding memory stream" +msgstr "Plus de mémoire lors de l'expansion du flux mémoire" + +#. Programmer's name for it: SCantWriteResourceStreamError +#: Vcl/consts.pas:22 +msgid "Can't write to a read-only resource stream" +msgstr "Impossible d'écrire dans un flux en lecture seule" + +#. Programmer's name for it: SDuplicateReference +#: Vcl/consts.pas:23 +msgid "WriteObject called twice for the same instance" +msgstr "WriteObject appelé deux fois pour la même instance" + +#. Programmer's name for it: SClassNotFound +#: Vcl/consts.pas:24 +msgid "Class %s not found" +msgstr "Classe %s non trouvée" + +#. Programmer's name for it: SInvalidImage +#. Programmer's name for it: SInvalidStreamFormat +#: Vcl/consts.pas:25 +msgid "Invalid stream format" +msgstr "Format de flux incorrect" + +#. Programmer's name for it: SResNotFound +#. Programmer's name for it: sResNotFound +#: Vcl/consts.pas:26 +msgid "Resource %s not found" +msgstr "Ressource %s non trouvée" + +#. Programmer's name for it: SClassMismatch +#: Vcl/consts.pas:27 +msgid "Resource %s is of incorrect class" +msgstr "La ressource %s est d'une classe incorrecte" + +#. Programmer's name for it: SListIndexError +#: Vcl/consts.pas:28 +msgid "List index out of bounds (%d)" +msgstr "Indice de liste hors limites (%d)" + +#. Programmer's name for it: SListCapacityError +#: Vcl/consts.pas:29 +msgid "List capacity out of bounds (%d)" +msgstr "Capacité de liste hors limites (%d)" + +#. Programmer's name for it: SListCountError +#: Vcl/consts.pas:30 +msgid "List count out of bounds (%d)" +msgstr "Compte de liste hors limites (%d)" + +#. Programmer's name for it: SSortedListError +#: Vcl/consts.pas:31 +msgid "Operation not allowed on sorted string list" +msgstr "Opération non autorisée sur une liste de chaînes triée" + +#. Programmer's name for it: SDuplicateString +#: Vcl/consts.pas:32 +msgid "String list does not allow duplicates" +msgstr "La liste de chaînes n'autorise pas les doublons" + +#. Programmer's name for it: SInvalidTabIndex +#: Vcl/consts.pas:33 +msgid "Tab index out of bounds" +msgstr "Indice d'onglet hors limites" + +#. Programmer's name for it: SInvalidTabPosition +#: Vcl/consts.pas:34 +msgid "Tab position incompatible with current tab style" +msgstr "Position d'onglet incompatible avec le style d'onglet actuel" + +#. Programmer's name for it: SInvalidTabStyle +#: Vcl/consts.pas:35 +msgid "Tab style incompatible with current tab position" +msgstr "Style d'onglet incompatible avec la position d'onglet actuelle" + +#. Programmer's name for it: SDuplicateName +#: Vcl/consts.pas:36 +msgid "A component named %s already exists" +msgstr "Un composant nommé %s existe déjà" + +#. Programmer's name for it: SInvalidName +#: Vcl/consts.pas:37 +msgid "''%s'' is not a valid component name" +msgstr "''%s'' n'est pas un nom de composant correct" + +#. Programmer's name for it: SDuplicateClass +#: Vcl/consts.pas:38 +msgid "A class named %s already exists" +msgstr "Une classe nommée %s existe déjà" + +#. Programmer's name for it: SNoComSupport +#: Vcl/consts.pas:39 +msgid "%s has not been registered as a COM class" +msgstr "%s n'a pas été recensé comme classe COM" + +#. Programmer's name for it: SInvalidInteger +#: Vcl/consts.pas:40 +msgid "''%s'' is not a valid integer value" +msgstr "''%s'' n'est pas une valeur entière correcte" + +#. Programmer's name for it: SLineTooLong +#. Programmer's name for it: SOutlineLongLine +#: Vcl/consts.pas:41 +msgid "Line too long" +msgstr "Ligne trop longue" + +#. Programmer's name for it: SInvalidPropertyValue +#. Programmer's name for it: SInvalidProperty +#: Vcl/consts.pas:42 +msgid "Invalid property value" +msgstr "Valeur de propriété incorrecte" + +#. Programmer's name for it: SInvalidPropertyPath +#: Vcl/consts.pas:43 +msgid "Invalid property path" +msgstr "Chemin de propriété incorrect" + +#. Programmer's name for it: SInvalidPropertyType +#: Vcl/consts.pas:44 +msgid "Invalid property type: %s" +msgstr "Type de propriété incorrect : %s" + +#. Programmer's name for it: SInvalidPropertyElement +#: Vcl/consts.pas:45 +msgid "Invalid property element: %s" +msgstr "Elément de propriété incorrect : %s" + +#. Programmer's name for it: SUnknownProperty +#: Vcl/consts.pas:46 +msgid "Property does not exist" +msgstr "Propriété inexistante" + +#. Programmer's name for it: SReadOnlyProperty +#: Vcl/consts.pas:47 +msgid "Property is read-only" +msgstr "Propriété en lecture seule" + +#. Programmer's name for it: SPropertyException +#: Vcl/consts.pas:48 +msgid "Error reading %s%s%s: %s" +msgstr "Erreur lors de la lecture de %s%s%s: %s" + +#. Programmer's name for it: SAncestorNotFound +#: Vcl/consts.pas:49 +msgid "Ancestor for '%s' not found" +msgstr "Ancêtre de '%s' non trouvé" + +#. Programmer's name for it: SInvalidBitmap +#: Vcl/consts.pas:50 +msgid "Bitmap image is not valid" +msgstr "Image bitmap incorrecte" + +#. Programmer's name for it: SInvalidIcon +#: Vcl/consts.pas:51 +msgid "Icon image is not valid" +msgstr "Image icône incorrecte" + +#. Programmer's name for it: SInvalidMetafile +#: Vcl/consts.pas:52 +msgid "Metafile is not valid" +msgstr "MetaFichier incorrect" + +#. Programmer's name for it: SInvalidPixelFormat +#: Vcl/consts.pas:53 +msgid "Invalid pixel format" +msgstr "Format de pixel incorrect" + +#. Programmer's name for it: SBitmapEmpty +#: Vcl/consts.pas:54 +msgid "Bitmap is empty" +msgstr "Bitmap vide" + +#. Programmer's name for it: SScanLine +#: Vcl/consts.pas:55 +msgid "Scan line index out of range" +msgstr "Indice ligne hors limites" + +#. Programmer's name for it: SChangeIconSize +#: Vcl/consts.pas:56 +msgid "Cannot change the size of an icon" +msgstr "Impossible de modifier la taille d'une icône" + +#. Programmer's name for it: SOleGraphic +#: Vcl/consts.pas:57 +msgid "Invalid operation on TOleGraphic" +msgstr "Opération incorrecte sur TOleGraphic" + +#. Programmer's name for it: SUnknownExtension +#: Vcl/consts.pas:58 +msgid "Unknown picture file extension (.%s)" +msgstr "Extension de fichier graphique inconnue (.%s)" + +#. Programmer's name for it: SUnknownClipboardFormat +#: Vcl/consts.pas:59 +msgid "Unsupported clipboard format" +msgstr "Format de Presse-papiers non supporté" + +#. Programmer's name for it: SOutOfResources +#: Vcl/consts.pas:60 +msgid "Out of system resources" +msgstr "Plus de ressources système" + +#. Programmer's name for it: SNoCanvasHandle +#: Vcl/consts.pas:61 +msgid "Canvas does not allow drawing" +msgstr "Le canevas ne permet pas de dessiner" + +#. Programmer's name for it: SInvalidImageSize +#: Vcl/consts.pas:62 +msgid "Invalid image size" +msgstr "Taille d'image incorrecte" + +#. Programmer's name for it: STooManyImages +#: Vcl/consts.pas:63 +msgid "Too many images" +msgstr "Trop d'images" + +#. Programmer's name for it: SDimsDoNotMatch +#: Vcl/consts.pas:64 +msgid "Image dimensions do not match image list dimensions" +msgstr "Les dimensions de l'image ne correspondent pas à celles de la liste d'image" + +#. Programmer's name for it: SInvalidImageList +#: Vcl/consts.pas:65 +msgid "Invalid ImageList" +msgstr "ImageList incorrecte" + +#. Programmer's name for it: SReplaceImage +#: Vcl/consts.pas:66 +msgid "Unable to Replace Image" +msgstr "Impossible de remplacer l'image" + +#. Programmer's name for it: SImageIndexError +#: Vcl/consts.pas:67 +msgid "Invalid ImageList Index" +msgstr "Indice ImageList incorrect" + +#. Programmer's name for it: SImageReadFail +#: Vcl/consts.pas:68 +msgid "Failed to read ImageList data from stream" +msgstr "Erreur à la lecture des données ImageList du flux" + +#. Programmer's name for it: SImageWriteFail +#: Vcl/consts.pas:69 +msgid "Failed to write ImageList data to stream" +msgstr "Erreur à l'écriture des données ImageList dans le flux" + +#. Programmer's name for it: SWindowDCError +#: Vcl/consts.pas:70 +msgid "Error creating window device context" +msgstr "Erreur à la création du contexte périphérique fenêtre" + +#. Programmer's name for it: SClientNotSet +#: Vcl/consts.pas:71 +msgid "Client of TDrag not initialized" +msgstr "Client de TDrag non initialisé" + +#. Programmer's name for it: SWindowClass +#: Vcl/consts.pas:72 +msgid "Error creating window class" +msgstr "Erreur à la création de la classe fenêtre" + +#. Programmer's name for it: SWindowCreate +#: Vcl/consts.pas:73 +msgid "Error creating window" +msgstr "Erreur à la création de fenêtre" + +#. Programmer's name for it: SCannotFocus +#: Vcl/consts.pas:74 +msgid "Cannot focus a disabled or invisible window" +msgstr "Impossible de focaliser une fenêtre désactivée ou invisible" + +#. Programmer's name for it: SParentRequired +#: Vcl/consts.pas:75 +msgid "Control '%s' has no parent window" +msgstr "Le contrôle '%s' n'a pas de fenêtre parente" + +#. Programmer's name for it: SMDIChildNotVisible +#: Vcl/consts.pas:76 +msgid "Cannot hide an MDI Child Form" +msgstr "Impossible de cacher une fiche enfant MDI" + +#. Programmer's name for it: SVisibleChanged +#: Vcl/consts.pas:77 +msgid "Cannot change Visible in OnShow or OnHide" +msgstr "Impossible de changer Visible dans OnShow ou OnHide" + +#. Programmer's name for it: SCannotShowModal +#: Vcl/consts.pas:78 +msgid "Cannot make a visible window modal" +msgstr "Impossible de rendre modale une fenêtre visible" + +#. Programmer's name for it: SScrollBarRange +#: Vcl/consts.pas:79 +msgid "Scrollbar property out of range" +msgstr "Propriété barre de défilement hors limites" + +#. Programmer's name for it: SPropertyOutOfRange +#: Vcl/consts.pas:80 +msgid "%s property out of range" +msgstr "Propriété %s hors limites" + +#. Programmer's name for it: SMenuIndexError +#: Vcl/consts.pas:81 +msgid "Menu index out of range" +msgstr "Indice de menu hors limites" + +#. Programmer's name for it: SMenuReinserted +#: Vcl/consts.pas:82 +msgid "Menu inserted twice" +msgstr "Menu inséré deux fois" + +#. Programmer's name for it: SMenuNotFound +#: Vcl/consts.pas:83 +msgid "Sub-menu is not in menu" +msgstr "Sous-menu pas dans le menu" + +#. Programmer's name for it: SNoTimers +#: Vcl/consts.pas:84 +msgid "Not enough timers available" +msgstr "Pas assez de timers disponibles" + +#. Programmer's name for it: SNotPrinting +#: Vcl/consts.pas:85 +msgid "Printer is not currently printing" +msgstr "L'imprimante n'imprime pas pour l'instant" + +#. Programmer's name for it: SPrinting +#: Vcl/consts.pas:86 +msgid "Printing in progress" +msgstr "Impression en cours" + +#. Programmer's name for it: SPrinterIndexError +#: Vcl/consts.pas:87 +msgid "Printer index out of range" +msgstr "Indice imprimante hors limites" + +#. Programmer's name for it: SInvalidPrinter +#: Vcl/consts.pas:88 +msgid "Printer selected is not valid" +msgstr "Imprimante sélectionnée incorrecte" + +#. Programmer's name for it: SDeviceOnPort +#: Vcl/consts.pas:89 +msgid "%s on %s" +msgstr "%s sur %s" + +#. Programmer's name for it: SGroupIndexTooLow +#: Vcl/consts.pas:90 +msgid "GroupIndex cannot be less than a previous menu item's GroupIndex" +msgstr "GroupIndex ne peut être inférieur à celui de l'élément de menu précédent" + +#. Programmer's name for it: STwoMDIForms +#: Vcl/consts.pas:91 +msgid "Cannot have more than one MDI form per application" +msgstr "Impossible d'avoir plus d'une fiche MDI par application" + +#. Programmer's name for it: SNoMDIForm +#: Vcl/consts.pas:92 +msgid "Cannot create form. No MDI forms are currently active" +msgstr "Impossible de créer la fiche. Aucune fiche Non MDI active" + +#. Programmer's name for it: SRegisterError +#: Vcl/consts.pas:93 +msgid "Invalid component registration" +msgstr "Enregistrement de composant incorrect" + +#. Programmer's name for it: SImageCanvasNeedsBitmap +#: Vcl/consts.pas:94 +msgid "Can only modify an image if it contains a bitmap" +msgstr "Ne peut modifier une image que si elle contient un bitmap" + +#. Programmer's name for it: SControlParentSetToSelf +#: Vcl/consts.pas:95 +msgid "A control cannot have itself as its parent" +msgstr "Un contrôle ne peut avoir lui-même comme parent" + +#. Programmer's name for it: SOKButton +#. Programmer's name for it: SMsgDlgOK +#. DSSCubeEditor..OKButton..Caption +#. DSSQueryEditor..OKButton..Caption +#. ConnEditForm..OkButton..Caption +#. ClientDataForm..OkBtn..Caption +#. DBEditForm..OkButton..Caption +#. AddFields..OkBtn..Caption +#. AssociateAttributes..OKBtn..Caption +#. SaveAttributesAs..OKBtn..Caption +#. DefineField..OkBtn..Caption +#. LinkFields..Button1..Caption +#. IndexFiles..Ok..Caption +#. PictureEditorDlg..OKButton..Caption +#: Vcl/consts.pas:96 +#: Cube/mxdssqry.dfm:321 +#: Property Editors/adoconed.dfm:19 +#: Editors/cdsedit.dfm:39 +#: Editors/dbedit.dfm:140 +#: Editors/dsadd.dfm:24 +#: Editors/dsattra.dfm:18 +#: Editors/dsattrs.dfm:56 +#: Editors/dsdefine.dfm:103 +#: Editors/fldlinks.dfm:141 +#: Editors/ixedit.dfm:64 +#: Editors/picedit.dfm:22 +msgid "OK" +msgstr "OK" + +#. Programmer's name for it: SCancelButton +#. Programmer's name for it: SMsgDlgCancel +#. DSSCubeEditor..CancelButton..Caption +#. DSSQueryEditor..Cancel..Caption +#. ConnEditForm..CancelButton..Caption +#. ClientDataForm..CancelBtn..Caption +#. DBEditForm..CancelButton..Caption +#. InputReqDialog..CancelButton..Caption +#. LoginDialog..CancelButton..Caption +#. AddFields..CancelBtn..Caption +#. AssociateAttributes..CancelBtn..Caption +#. SaveAttributesAs..CancelBtn..Caption +#. DefineField..CancelBtn..Caption +#. LinkFields..Button2..Caption +#. IndexFiles..Cancel..Caption +#. PictureEditorDlg..CancelButton..Caption +#. SQLEditForm..ButtonPanel..CancelButton..Caption +#. StrEditDlg..CancelButton..Caption +#. UpdateSQLEditForm..CancelButton..Caption +#: Vcl/consts.pas:97 +#: Cube/mxdssqry.dfm:311 +#: Property Editors/adoconed.dfm:30 +#: Editors/cdsedit.dfm:52 +#: Editors/dbedit.dfm:152 +#: Editors/dbinpreq.dfm:29 +#: Editors/dblogdlg.dfm:30 +#: Editors/dsadd.dfm:36 +#: Editors/dsattra.dfm:30 +#: Editors/dsattrs.dfm:67 +#: Editors/dsdefine.dfm:115 +#: Editors/fldlinks.dfm:153 +#: Editors/ixedit.dfm:75 +#: Editors/picedit.dfm:33 +#: Editors/sqledit.dfm:106 +#: Editors/stredit.dfm:66 +#: Editors/updsqled.dfm:32 +msgid "Cancel" +msgstr "Annuler" + +#. Programmer's name for it: SYesButton +#. Programmer's name for it: SMsgDlgYes +#: Vcl/consts.pas:98 +msgid "&Yes" +msgstr "&Oui" + +#. Programmer's name for it: SNoButton +#. Programmer's name for it: SMsgDlgNo +#: Vcl/consts.pas:99 +msgid "&No" +msgstr "&Non" + +#. Programmer's name for it: SHelpButton +#. Programmer's name for it: SMsgDlgHelp +#. DSSCubeEditor..HelpButton..Caption +#. DSSQueryEditor..HelpButton..Caption +#. ConnEditForm..HelpButton..Caption +#. ClientDataForm..HelpBtn..Caption +#. DBEditForm..HelpButton..Caption +#. DataBindForm..HelpBtn..Caption +#. AddFields..HelpBtn..Caption +#. AssociateAttributes..HelpBtn..Caption +#. SaveAttributesAs..HelpBtn..Caption +#. DefineField..HelpBtn..Caption +#. LinkFields..Help..Caption +#. IndexFiles..Help..Caption +#. PictureEditorDlg..HelpButton..Caption +#. SQLEditForm..ButtonPanel..HelpButton..Caption +#. StrEditDlg..HelpButton..Caption +#. UpdateSQLEditForm..HelpButton..Caption +#: Vcl/consts.pas:100 +#: Cube/mxdssqry.dfm:331 +#: Property Editors/adoconed.dfm:39 +#: Editors/cdsedit.dfm:61 +#: Editors/dbedit.dfm:161 +#: Editors/dboleedt.dfm:128 +#: Editors/dsadd.dfm:65 +#: Editors/dsattra.dfm:40 +#: Editors/dsattrs.dfm:77 +#: Editors/dsdefine.dfm:124 +#: Editors/fldlinks.dfm:162 +#: Editors/ixedit.dfm:84 +#: Editors/picedit.dfm:42 +#: Editors/sqledit.dfm:116 +#: Editors/stredit.dfm:46 +#: Editors/updsqled.dfm:41 +msgid "&Help" +msgstr "&Aide" + +#. Programmer's name for it: SCloseButton +#. SocketForm..PopupMenu..miClose..Caption +#: Vcl/consts.pas:101 +msgid "&Close" +msgstr "&Fermer" + +#. Programmer's name for it: SIgnoreButton +#. Programmer's name for it: SMsgDlgIgnore +#: Vcl/consts.pas:102 +msgid "&Ignore" +msgstr "I&gnorer" + +#. Programmer's name for it: SRetryButton +#. Programmer's name for it: SMsgDlgRetry +#: Vcl/consts.pas:103 +msgid "&Retry" +msgstr "&Retenter" + +#. Programmer's name for it: SAbortButton +#: Vcl/consts.pas:104 +msgid "Abort" +msgstr "Abandon" + +#. Programmer's name for it: SAllButton +#. Programmer's name for it: SMsgDlgAll +#: Vcl/consts.pas:105 +msgid "&All" +msgstr "&Tout" + +#. Programmer's name for it: SCannotDragForm +#: Vcl/consts.pas:107 +msgid "Cannot drag a form" +msgstr "Impossible de glisser une fiche" + +#. Programmer's name for it: SPutObjectError +#: Vcl/consts.pas:108 +msgid "PutObject to undefined item" +msgstr "PutObject à élément indéfini" + +#. Programmer's name for it: SCardDLLNotLoaded +#: Vcl/consts.pas:109 +msgid "Could not load CARDS.DLL" +msgstr "Impossible de charger CARDS.DLL" + +#. Programmer's name for it: SDuplicateCardId +#: Vcl/consts.pas:110 +msgid "Duplicate CardId found" +msgstr "CardID dupliqué" + +#. Programmer's name for it: SDdeErr +#: Vcl/consts.pas:112 +msgid "An error returned from DDE ($0%x)" +msgstr "Une erreur a été renvoyée par DDE ($0%x)" + +#. Programmer's name for it: SDdeConvErr +#: Vcl/consts.pas:113 +msgid "DDE Error - conversation not established ($0%x)" +msgstr "Erreur DDE - Conversation non établie ($0%x)" + +#. Programmer's name for it: SDdeMemErr +#: Vcl/consts.pas:114 +msgid "Error occurred when DDE ran out of memory ($0%x)" +msgstr "Erreur apparue lorsque DDE manqua de mémoire ($0%x)" + +#. Programmer's name for it: SDdeNoConnect +#: Vcl/consts.pas:115 +msgid "Unable to connect DDE conversation" +msgstr "Impossible de connecter la conversation DDE" + +#. Programmer's name for it: SFB +#: Vcl/consts.pas:117 +msgid "FB" +msgstr "TF" + +#. Programmer's name for it: SFG +#: Vcl/consts.pas:118 +msgid "FG" +msgstr "T" + +#. Programmer's name for it: SBG +#: Vcl/consts.pas:119 +msgid "BG" +msgstr "F" + +#. Programmer's name for it: SOldTShape +#: Vcl/consts.pas:120 +msgid "Cannot load older version of TShape" +msgstr "Impossible de charger version antérieure de TShape" + +#. Programmer's name for it: SVMetafiles +#: Vcl/consts.pas:121 +msgid "Metafiles" +msgstr "MétaFichiers" + +#. Programmer's name for it: SVEnhMetafiles +#: Vcl/consts.pas:122 +msgid "Enhanced Metafiles" +msgstr "MétaFichiers évolués" + +#. Programmer's name for it: SVIcons +#: Vcl/consts.pas:123 +msgid "Icons" +msgstr "Icônes" + +#. Programmer's name for it: SVBitmaps +#: Vcl/consts.pas:124 +msgid "Bitmaps" +msgstr "Bitmaps" + +#. Programmer's name for it: SGridTooLarge +#: Vcl/consts.pas:125 +msgid "Grid too large for operation" +msgstr "Grille trop grande pour l'opération" + +#. Programmer's name for it: STooManyDeleted +#: Vcl/consts.pas:126 +msgid "Too many rows or columns deleted" +msgstr "Trop de lignes ou colonnes supprimées" + +#. Programmer's name for it: SIndexOutOfRange +#: Vcl/consts.pas:127 +msgid "Grid index out of range" +msgstr "Indice de grille hors limites" + +#. Programmer's name for it: SFixedColTooBig +#: Vcl/consts.pas:128 +msgid "Fixed column count must be less than column count" +msgstr "Le nombre de colonnes fixes doit être inférieur au nombre de colonnes" + +#. Programmer's name for it: SFixedRowTooBig +#: Vcl/consts.pas:129 +msgid "Fixed row count must be less than row count" +msgstr "Le nombre de lignes fixes doit être inférieur au nombre de lignes" + +#. Programmer's name for it: SInvalidStringGridOp +#: Vcl/consts.pas:130 +msgid "Cannot insert or delete rows from grid" +msgstr "Impossible d'insérer ou de supprimer les lignes de la grille" + +#. Programmer's name for it: SParseError +#: Vcl/consts.pas:131 +msgid "%s on line %d" +msgstr "%s à la ligne %d" + +#. Programmer's name for it: SIdentifierExpected +#: Vcl/consts.pas:132 +msgid "Identifier expected" +msgstr "Identificateur attendu" + +#. Programmer's name for it: SStringExpected +#: Vcl/consts.pas:133 +msgid "String expected" +msgstr "Chaîne attendue" + +#. Programmer's name for it: SNumberExpected +#: Vcl/consts.pas:134 +msgid "Number expected" +msgstr "Nombre attendu" + +#. Programmer's name for it: SCharExpected +#: Vcl/consts.pas:135 +msgid "''%s'' expected" +msgstr "''%s'' attendu" + +#. Programmer's name for it: SSymbolExpected +#: Vcl/consts.pas:136 +msgid "%s expected" +msgstr "%s attendu" + +#. Programmer's name for it: SInvalidNumber +#: Vcl/consts.pas:137 +msgid "Invalid numeric value" +msgstr "Valeur numérique incorrecte" + +#. Programmer's name for it: SInvalidString +#: Vcl/consts.pas:138 +msgid "Invalid string constant" +msgstr "Constante chaîne incorrecte" + +#. Programmer's name for it: SInvalidBinary +#: Vcl/consts.pas:140 +msgid "Invalid binary value" +msgstr "Valeur binaire incorrecte" + +#. Programmer's name for it: SOutlineIndexError +#: Vcl/consts.pas:141 +msgid "Outline index not found" +msgstr "Indice arborescence non trouvé" + +#. Programmer's name for it: SOutlineExpandError +#: Vcl/consts.pas:142 +msgid "Parent must be expanded" +msgstr "Le parent doit être développé" + +#. Programmer's name for it: SInvalidCurrentItem +#: Vcl/consts.pas:143 +msgid "Invalid value for current item" +msgstr "Valeur incorrecte pour l'élément en cours" + +#. Programmer's name for it: SMaskErr +#: Vcl/consts.pas:144 +msgid "Invalid input value" +msgstr "Valeur d'entrée incorrecte" + +#. Programmer's name for it: SMaskEditErr +#: Vcl/consts.pas:145 +msgid "Invalid input value. Use escape key to abandon changes" +msgstr "Valeur d'entrée incorrecte. Utiliser Echap pour abandonner les modifications" + +#. Programmer's name for it: SOutlineError +#: Vcl/consts.pas:146 +msgid "Invalid outline index" +msgstr "Indice arborescence incorrect" + +#. Programmer's name for it: SOutlineBadLevel +#: Vcl/consts.pas:147 +msgid "Incorrect level assignment" +msgstr "Affectation de niveau incorrect" + +#. Programmer's name for it: SOutlineSelection +#: Vcl/consts.pas:148 +msgid "Invalid selection" +msgstr "Sélection incorrecte" + +#. Programmer's name for it: SOutlineFileLoad +#: Vcl/consts.pas:149 +msgid "File load error" +msgstr "Erreur chargement de fichier" + +#. Programmer's name for it: SOutlineMaxLevels +#: Vcl/consts.pas:151 +msgid "Maximum outline depth exceeded" +msgstr "Profondeur maximum arborescence dépassée" + +#. Programmer's name for it: SMsgDlgWarning +#: Vcl/consts.pas:153 +msgid "Warning" +msgstr "Avertissement" + +#. Programmer's name for it: SMsgDlgError +#: Vcl/consts.pas:154 +msgid "Error" +msgstr "Erreur" + +#. Programmer's name for it: SMsgDlgInformation +#: Vcl/consts.pas:155 +msgid "Information" +msgstr "Information" + +#. Programmer's name for it: SMsgDlgConfirm +#: Vcl/consts.pas:156 +msgid "Confirm" +msgstr "Confirmation" + +#. Programmer's name for it: SMsgDlgHelpNone +#: Vcl/consts.pas:162 +msgid "No help available" +msgstr "Aucune aide disponible" + +#. Programmer's name for it: SMsgDlgHelpHelp +#: Vcl/consts.pas:163 +msgid "Help" +msgstr "Aide" + +#. Programmer's name for it: SMsgDlgAbort +#: Vcl/consts.pas:164 +msgid "&Abort" +msgstr "&Abandon" + +#. Programmer's name for it: SMsgDlgNoToAll +#: Vcl/consts.pas:168 +msgid "N&o to All" +msgstr "Non &pour tout" + +#. Programmer's name for it: SMsgDlgYesToAll +#: Vcl/consts.pas:169 +msgid "Yes to &All" +msgstr "O&ui pour tout" + +#. Programmer's name for it: SmkcBkSp +#: Vcl/consts.pas:171 +msgid "BkSp" +msgstr "RetArr" + +#. Programmer's name for it: SmkcTab +#: Vcl/consts.pas:172 +msgid "Tab" +msgstr "Tab" + +#. Programmer's name for it: SmkcEsc +#: Vcl/consts.pas:173 +msgid "Esc" +msgstr "Echap" + +#. Programmer's name for it: SmkcEnter +#: Vcl/consts.pas:174 +msgid "Enter" +msgstr "Entrée" + +#. Programmer's name for it: SmkcSpace +#: Vcl/consts.pas:175 +msgid "Space" +msgstr "Espace" + +#. Programmer's name for it: SmkcPgUp +#: Vcl/consts.pas:176 +msgid "PgUp" +msgstr "PagePréc" + +#. Programmer's name for it: SmkcPgDn +#: Vcl/consts.pas:177 +msgid "PgDn" +msgstr "PageSuiv" + +#. Programmer's name for it: SmkcEnd +#: Vcl/consts.pas:178 +msgid "End" +msgstr "Fin" + +#. Programmer's name for it: SmkcHome +#: Vcl/consts.pas:179 +msgid "Home" +msgstr "Origine" + +#. Programmer's name for it: SmkcLeft +#: Vcl/consts.pas:180 +msgid "Left" +msgstr "Gauche" + +#. Programmer's name for it: SmkcUp +#: Vcl/consts.pas:181 +msgid "Up" +msgstr "Haut" + +#. Programmer's name for it: SmkcRight +#: Vcl/consts.pas:182 +msgid "Right" +msgstr "Droite" + +#. Programmer's name for it: SmkcDown +#: Vcl/consts.pas:183 +msgid "Down" +msgstr "Bas" + +#. Programmer's name for it: SmkcIns +#: Vcl/consts.pas:184 +msgid "Ins" +msgstr "Ins" + +#. Programmer's name for it: SmkcDel +#: Vcl/consts.pas:185 +msgid "Del" +msgstr "Suppr" + +#. Programmer's name for it: SmkcShift +#: Vcl/consts.pas:186 +msgid "Shift+" +msgstr "Maj+" + +#. Programmer's name for it: SmkcCtrl +#: Vcl/consts.pas:187 +msgid "Ctrl+" +msgstr "Ctrl+" + +#. Programmer's name for it: SmkcAlt +#: Vcl/consts.pas:188 +msgid "Alt+" +msgstr "Alt+" + +#. Programmer's name for it: srUnknown +#. Programmer's name for it: SHostUnknown +#: Vcl/consts.pas:190 +msgid "(Unknown)" +msgstr "(inconnu)" + +#. Programmer's name for it: SOutOfRange +#: Vcl/consts.pas:192 +msgid "Value must be between %d and %d" +msgstr "La valeur doit être comprise entre %d et %d" + +#. Programmer's name for it: SCannotCreateName +#: Vcl/consts.pas:193 +msgid "Cannot create a default method name for an unnamed component" +msgstr "Impossible de créer un nom de méthode par défaut pour un composant sans nom" + +#. Programmer's name for it: SDateEncodeError +#: Vcl/consts.pas:195 +msgid "Invalid argument to date encode" +msgstr "Argument incorrect pour l'encodage de date" + +#. Programmer's name for it: STimeEncodeError +#: Vcl/consts.pas:196 +msgid "Invalid argument to time encode" +msgstr "Argument incorrect pour l'encodage d'heure" + +#. Programmer's name for it: SInvalidDate +#: Vcl/consts.pas:197 +msgid "''%s'' is not a valid date" +msgstr "''%s'' n'est pas une date correcte" + +#. Programmer's name for it: SInvalidTime +#: Vcl/consts.pas:198 +msgid "''%s'' is not a valid time" +msgstr "''%s'' n'est pas une heure correcte" + +#. Programmer's name for it: SInvalidDateTime +#: Vcl/consts.pas:199 +msgid "''%s'' is not a valid date and time" +msgstr "''%s'' n'est pas une date et heure correcte" + +#. Programmer's name for it: SInvalidFileName +#: Vcl/consts.pas:200 +msgid "Invalid file name - %s" +msgstr "Nom de fichier incorrect - %s" + +#. Programmer's name for it: SDefaultFilter +#: Vcl/consts.pas:201 +msgid "All files (*.*)|*.*" +msgstr "Tous les fichiers (*.*)|*.*" + +#. Programmer's name for it: sAllFilter +#: Vcl/consts.pas:202 +msgid "All" +msgstr "Tout" + +#. Programmer's name for it: SNoVolumeLabel +#: Vcl/consts.pas:203 +msgid ": [ - no volume label - ]" +msgstr ": [ Pas de nom de volume ]" + +#. Programmer's name for it: SInsertLineError +#: Vcl/consts.pas:204 +msgid "Unable to insert a line" +msgstr "Impossible d'insérer une ligne" + +#. Programmer's name for it: SConfirmCreateDir +#: Vcl/consts.pas:206 +msgid "The specified directory does not exist. Create it?" +msgstr "Le répertoire spécifié n'existe pas. Le créer ?" + +#. Programmer's name for it: SSelectDirCap +#: Vcl/consts.pas:207 +msgid "Select Directory" +msgstr "Sélection du répertoire" + +#. Programmer's name for it: SCannotCreateDir +#: Vcl/consts.pas:208 +msgid "Unable to create directory" +msgstr "Impossible de créer le répertoire" + +#. Programmer's name for it: SDirNameCap +#: Vcl/consts.pas:209 +msgid "Directory &Name:" +msgstr "&Nom de répertoire :" + +#. Programmer's name for it: SDrivesCap +#: Vcl/consts.pas:210 +msgid "D&rives:" +msgstr "&Lecteurs :" + +#. Programmer's name for it: SDirsCap +#: Vcl/consts.pas:211 +msgid "&Directories:" +msgstr "&Répertoires :" + +#. Programmer's name for it: SFilesCap +#: Vcl/consts.pas:212 +msgid "&Files: (*.*)" +msgstr "&Fichiers : (*.*)" + +#. Programmer's name for it: SNetworkCap +#: Vcl/consts.pas:213 +msgid "Ne&twork..." +msgstr "Ré&seau..." + +#. !! obsolete - delete in 5.0 +#: Vcl/consts.pas:215 +msgid "Color" +msgstr "Couleur" + +#. !! obsolete - delete in 5.0 +#: Vcl/consts.pas:216 +msgid "ABCDEFGHIJKLMNOP" +msgstr "ABCDEFGHIJKLMNOP" + +#. Programmer's name for it: SInvalidClipFmt +#: Vcl/consts.pas:218 +msgid "Invalid clipboard format" +msgstr "Format de Presse-papiers incorrect" + +#. Programmer's name for it: SIconToClipboard +#: Vcl/consts.pas:219 +msgid "Clipboard does not support Icons" +msgstr "Le Presse-papiers ne supporte pas les icônes" + +#. Programmer's name for it: SCannotOpenClipboard +#: Vcl/consts.pas:220 +msgid "Cannot open clipboard" +msgstr "Ne peut ouvrir le Presse-papiers" + +#. Programmer's name for it: SDefault +#. Programmer's name for it: sHTTPItemDefault +#. SQLWindow..DBGrid1..TitleFont.Name +#. DSSQueryEditor..Pager..Dimensions..AddAgg..Font.Name +#: Vcl/consts.pas:222 +#: Cube/mxdssqry.dfm:193 +msgid "Default" +msgstr "Défaut" + +#. Programmer's name for it: SInvalidMemoSize +#: Vcl/consts.pas:224 +msgid "Text exceeds memo capacity" +msgstr "Le texte dépasse la capacité du mémo" + +#. Programmer's name for it: SCustomColors +#: Vcl/consts.pas:225 +msgid "Custom Colors" +msgstr "Couleurs personnalisées" + +#. Programmer's name for it: SInvalidPrinterOp +#: Vcl/consts.pas:226 +msgid "Operation not supported on selected printer" +msgstr "Opération non supportée par l'imprimante sélectionnée" + +#. Programmer's name for it: SNoDefaultPrinter +#: Vcl/consts.pas:227 +msgid "There is no default printer currently selected" +msgstr "Aucune imprimante par défaut sélectionnée" + +#. Programmer's name for it: SIniFileWriteError +#: Vcl/consts.pas:229 +msgid "Unable to write to %s" +msgstr "Impossible d'écrire dans %s" + +#. Programmer's name for it: SBitsIndexError +#: Vcl/consts.pas:231 +msgid "Bits index out of range" +msgstr "Indice de bits hors limites" + +#. Programmer's name for it: SUntitled +#: Vcl/consts.pas:233 +msgid "(Untitled)" +msgstr "(sans titre)" + +#. Programmer's name for it: SInvalidRegType +#: Vcl/consts.pas:235 +msgid "Invalid data type for '%s'" +msgstr "Type de données incorrect pour '%s'" + +#. Programmer's name for it: SRegCreateFailed +#: Vcl/consts.pas:236 +msgid "Failed to create key %s" +msgstr "Echec à la création de la clé %s" + +#. Programmer's name for it: SRegSetDataFailed +#: Vcl/consts.pas:237 +msgid "Failed to set data for '%s'" +msgstr "Echec à la définition des données pour '%s'" + +#. Programmer's name for it: SRegGetDataFailed +#: Vcl/consts.pas:238 +msgid "Failed to get data for '%s'" +msgstr "Echec à l'obtention des données pour '%s'" + +#. Programmer's name for it: SUnknownConversion +#: Vcl/consts.pas:240 +msgid "Unknown RichEdit conversion file extension (.%s)" +msgstr "Extension de fichier de conversion RichEdit inconnue (.%s)" + +#. Programmer's name for it: SDuplicateMenus +#: Vcl/consts.pas:241 +msgid "Menu '%s' is already being used by another form" +msgstr "Le menu '%s' est déjà utilisé par une autre fiche" + +#. Programmer's name for it: SPictureLabel +#: Vcl/consts.pas:243 +msgid "Picture:" +msgstr "Image :" + +#. Programmer's name for it: SPictureDesc +#: Vcl/consts.pas:244 +msgid " (%dx%d)" +msgstr " (%dx%d)" + +#. Programmer's name for it: SPreviewLabel +#: Vcl/consts.pas:245 +msgid "Preview" +msgstr "Prévisualiser" + +#. Programmer's name for it: SCannotOpenAVI +#: Vcl/consts.pas:247 +msgid "Cannot open AVI" +msgstr "Impossible d'ouvrir l'AVI" + +#. Programmer's name for it: SNotOpenErr +#: Vcl/consts.pas:249 +msgid "No MCI device open" +msgstr "Aucun périphérique MCI ouvert" + +#. Programmer's name for it: SMPOpenFilter +#: Vcl/consts.pas:250 +msgid "All files (*.*)|*.*|Wave files (*.wav)|*.wav|Midi files (*.mid)|*.mid|Video for Windows (*.avi)|*.avi" +msgstr "Tous les fichiers (*.*)|*.*|Fichiers wave (*.wav)|*.wav|Fichiers Midi (*.mid)|*.mid|Vidéo pour Windows (*.avi)|*.avi" + +#. Programmer's name for it: SMCIAVIVideo +#: Vcl/consts.pas:252 +msgid "AVIVideo" +msgstr "AVIVideo" + +#. Programmer's name for it: SMCICDAudio +#: Vcl/consts.pas:253 +msgid "CDAudio" +msgstr "CDAudio" + +#. Programmer's name for it: SMCIDAT +#: Vcl/consts.pas:254 +msgid "DAT" +msgstr "DAT" + +#. Programmer's name for it: SMCIDigitalVideo +#: Vcl/consts.pas:255 +msgid "DigitalVideo" +msgstr "DigitalVideo" + +#. Programmer's name for it: SMCIMMMovie +#: Vcl/consts.pas:256 +msgid "MMMovie" +msgstr "MMMovie" + +#. Programmer's name for it: SMCIOther +#: Vcl/consts.pas:257 +msgid "Other" +msgstr "Autre" + +#. Programmer's name for it: SMCIOverlay +#: Vcl/consts.pas:258 +msgid "Overlay" +msgstr "Overlay" + +#. Programmer's name for it: SMCIScanner +#: Vcl/consts.pas:259 +msgid "Scanner" +msgstr "Scanner" + +#. Programmer's name for it: SMCISequencer +#: Vcl/consts.pas:260 +msgid "Sequencer" +msgstr "Séquenceur" + +#. Programmer's name for it: SMCIVCR +#: Vcl/consts.pas:261 +msgid "VCR" +msgstr "Magnétoscope" + +#. Programmer's name for it: SMCIVideodisc +#: Vcl/consts.pas:262 +msgid "Videodisc" +msgstr "Vidéodisque" + +#. Programmer's name for it: SMCIWaveAudio +#: Vcl/consts.pas:263 +msgid "WaveAudio" +msgstr "Audio wav" + +#. Programmer's name for it: SMCIUnknownError +#: Vcl/consts.pas:264 +msgid "Unknown error code" +msgstr "Code d'erreur inconnu" + +#. Programmer's name for it: SBoldItalicFont +#: Vcl/consts.pas:266 +msgid "Bold Italic" +msgstr "Gras Italique" + +#. Programmer's name for it: SBoldFont +#: Vcl/consts.pas:267 +msgid "Bold" +msgstr "Gras" + +#. Programmer's name for it: SItalicFont +#: Vcl/consts.pas:268 +msgid "Italic" +msgstr "Italique" + +#. Programmer's name for it: SRegularFont +#: Vcl/consts.pas:269 +msgid "Regular" +msgstr "Normal" + +#. Programmer's name for it: SPropertiesVerb +#. SocketForm..Pages..PropPage..Caption +#: Vcl/consts.pas:271 +msgid "Properties" +msgstr "Propriétés" + +#. Programmer's name for it: sWindowsSocketError +#: Vcl/consts.pas:273 +msgid "Windows socket error: %s (%d), on API '%s'" +msgstr "Erreur socket Windows : %s (%d), avec l'API '%s'" + +#. Programmer's name for it: sAsyncSocketError +#: Vcl/consts.pas:274 +msgid "Asynchronous socket error %d" +msgstr "Erreur socket asynchrone %d" + +#. Programmer's name for it: sNoAddress +#: Vcl/consts.pas:275 +msgid "No address specified" +msgstr "Aucune adresse spécifiée" + +#. Programmer's name for it: sCannotListenOnOpen +#: Vcl/consts.pas:276 +msgid "Can't listen on an open socket" +msgstr "Ne peut écouter sur un socket ouvert" + +#. Programmer's name for it: sCannotCreateSocket +#: Vcl/consts.pas:277 +msgid "Can't create new socket" +msgstr "Ne peut créer le nouveau socket" + +#. Programmer's name for it: sSocketAlreadyOpen +#: Vcl/consts.pas:278 +msgid "Socket already open" +msgstr "Socket déjà ouvert" + +#. Programmer's name for it: sCantChangeWhileActive +#: Vcl/consts.pas:279 +msgid "Can't change value while socket is active" +msgstr "Ne peut modifier la valeur lorsque le socket est actif" + +#. Programmer's name for it: sSocketMustBeBlocking +#: Vcl/consts.pas:280 +msgid "Socket must be in blocking mode" +msgstr "Le socket doit être en mode bloquant" + +#. Programmer's name for it: sSocketIOError +#: Vcl/consts.pas:281 +msgid "%s error %d, %s" +msgstr "%s erreur %d, %s" + +#. Programmer's name for it: sSocketRead +#. Programmer's name for it: SReadAccess +#: Vcl/consts.pas:282 +msgid "Read" +msgstr "Lecture" + +#. Programmer's name for it: sSocketWrite +#. Programmer's name for it: SWriteAccess +#: Vcl/consts.pas:283 +msgid "Write" +msgstr "Ecriture" + +#. Programmer's name for it: SServiceFailed +#: Vcl/consts.pas:285 +msgid "Service failed on %s: %s" +msgstr "Le service a échoué pour %s : %s" + +#. Programmer's name for it: SExecute +#: Vcl/consts.pas:286 +msgid "execute" +msgstr "exécuter" + +#. Programmer's name for it: SStart +#: Vcl/consts.pas:287 +msgid "start" +msgstr "lancer" + +#. Programmer's name for it: SStop +#: Vcl/consts.pas:288 +msgid "stop" +msgstr "arrêter" + +#. Programmer's name for it: SPause +#: Vcl/consts.pas:289 +msgid "pause" +msgstr "pause" + +#. Programmer's name for it: SContinue +#: Vcl/consts.pas:290 +msgid "continue" +msgstr "continuer" + +#. Programmer's name for it: SInterrogate +#: Vcl/consts.pas:291 +msgid "interrogate" +msgstr "interroger" + +#. Programmer's name for it: SShutdown +#: Vcl/consts.pas:292 +msgid "shutdown" +msgstr "terminer" + +#. Programmer's name for it: SCustomError +#: Vcl/consts.pas:293 +msgid "Service failed in custom message(%d): %s" +msgstr "Le service a échoué dans le message personnalisée (%d) : %s" + +#. Programmer's name for it: SServiceInstallOK +#: Vcl/consts.pas:294 +msgid "Service installed successfully" +msgstr "Service installé avec succès" + +#. Programmer's name for it: SServiceInstallFailed +#: Vcl/consts.pas:295 +msgid "Service \"%s\" failed to install with error: \"%s\"" +msgstr "Le service \"%s\" a échoué pendant son installation avec l'erreur : \"%s\"" + +#. Programmer's name for it: SServiceUninstallOK +#: Vcl/consts.pas:296 +msgid "Service uninstalled successfully" +msgstr "Service désinstallé avec succès" + +#. Programmer's name for it: SServiceUninstallFailed +#: Vcl/consts.pas:297 +msgid "Service \"%s\" failed to uninstall with error: \"%s\"" +msgstr "Le service \"%s\" a échoué pendant sa désinstallation avec l'erreur : \"%s\"" + +#. Programmer's name for it: SInvalidActionRegistration +#: Vcl/consts.pas:299 +msgid "Invalid action registration" +msgstr "Enregistrement d'action incorrecte" + +#. Programmer's name for it: SInvalidActionUnregistration +#: Vcl/consts.pas:300 +msgid "Invalid action unregistration" +msgstr "Désenregistrement d'action incorrecte" + +#. Programmer's name for it: SInvalidActionEnumeration +#: Vcl/consts.pas:301 +msgid "Invalid action enumeration" +msgstr "Enumération d'action incorrecte" + +#. Programmer's name for it: SInvalidActionCreation +#: Vcl/consts.pas:302 +msgid "Invalid action creation" +msgstr "Création d'action incorrecte" + +#. Programmer's name for it: SDockedCtlNeedsName +#: Vcl/consts.pas:304 +msgid "Docked control must have a name" +msgstr "Le composant arrimé doit avoir un nom" + +#. Programmer's name for it: SDockTreeRemoveError +#: Vcl/consts.pas:305 +msgid "Error removing control from dock tree" +msgstr "Erreur à la suppression du contrôle de l'arbre arrimé" + +#. Programmer's name for it: SDockZoneNotFound +#: Vcl/consts.pas:306 +msgid " - Dock zone not found" +msgstr " - Zone d'arrimage non trouvée" + +#. Programmer's name for it: SDockZoneHasNoCtl +#: Vcl/consts.pas:307 +msgid " - Dock zone has no control" +msgstr " - La zone d'arrimage n'a pas de contrôle" + +#. Programmer's name for it: SAllCommands +#: Vcl/consts.pas:309 +msgid "All Commands" +msgstr "Toutes les commandes" + +#. Programmer's name for it: SDuplicateItem +#: Vcl/consts.pas:311 +msgid "List does not allow duplicates ($0%x)" +msgstr "La liste n'autorise pas les doublons ($0%x)" + +#. Programmer's name for it: SDuplicatePropertyCategory +#: Vcl/consts.pas:313 +msgid "A property category called %s already exists" +msgstr "Une catégorie de propriété nommée %s existe déjà" + +#. Programmer's name for it: SUnknownPropertyCategory +#: Vcl/consts.pas:314 +msgid "Property category does not exist (%s)" +msgstr "La catégorie de propriété n'existe pas (%s)" + +#. Programmer's name for it: SActionCategoryName +#: Vcl/consts.pas:316 +msgid "Action" +msgstr "Action" + +#. Programmer's name for it: SActionCategoryDesc +#: Vcl/consts.pas:317 +msgid "Action properties and/or events" +msgstr "Propriétés et/ou événements Action" + +#. Programmer's name for it: SDataCategoryName +#: Vcl/consts.pas:318 +msgid "Data" +msgstr "Données" + +#. Programmer's name for it: SDataCategoryDesc +#: Vcl/consts.pas:319 +msgid "Data properties and/or events" +msgstr "Evénements et/ou événements Données" + +#. Programmer's name for it: SDatabaseCategoryName +#: Vcl/consts.pas:320 +msgid "Database" +msgstr "Base de données" + +#. Programmer's name for it: SDatabaseCategoryDesc +#: Vcl/consts.pas:321 +msgid "Database and Data Aware properties and/or events" +msgstr "Propriétés et/ou événements Base de données et Orientées données" + +#. Programmer's name for it: SDragNDropCategoryName +#: Vcl/consts.pas:322 +msgid "Drag, Drop and Docking" +msgstr "Glisser, Déplacer et Arrimer" + +#. Programmer's name for it: SDragNDropCategoryDesc +#: Vcl/consts.pas:323 +msgid "Drag, Drop and Docking properties and/or events" +msgstr "Propriétés et/ou événements Glisser, Déplacer et Arrimer" + +#. Programmer's name for it: SHelpCategoryName +#: Vcl/consts.pas:324 +msgid "Help and Hints" +msgstr "Aide et Conseil" + +#. Programmer's name for it: SHelpCategoryDesc +#: Vcl/consts.pas:325 +msgid "Help and Hint properties and/or events" +msgstr "Propriétés et/ou événements Aide et Conseil" + +#. Programmer's name for it: SLayoutCategoryName +#: Vcl/consts.pas:326 +msgid "Layout" +msgstr "Disposition" + +#. Programmer's name for it: SLayoutCategoryDesc +#: Vcl/consts.pas:327 +msgid "Layout properties and/or events" +msgstr "Propriétés et/ou événements Disposition" + +#. Programmer's name for it: SLegacyCategoryName +#: Vcl/consts.pas:328 +msgid "Legacy" +msgstr "Legs" + +#. Programmer's name for it: SLegacyCategoryDesc +#: Vcl/consts.pas:329 +msgid "Legacy properties and/or events" +msgstr "Propriétés et/ou événements Legs" + +#. Programmer's name for it: SLinkageCategoryName +#: Vcl/consts.pas:330 +msgid "Linkage" +msgstr "Liaison" + +#. Programmer's name for it: SLinkageCategoryDesc +#: Vcl/consts.pas:331 +msgid "Linkage properties and/or events" +msgstr "Propriétés et/ou événements Liaison" + +#. Programmer's name for it: SLocaleCategoryName +#: Vcl/consts.pas:332 +msgid "Locale" +msgstr "Locale" + +#. Programmer's name for it: SLocaleCategoryDesc +#: Vcl/consts.pas:333 +msgid "Locale properties and/or events" +msgstr "Propriétés et/ou événements Locale" + +#. Programmer's name for it: SLocalizableCategoryName +#: Vcl/consts.pas:334 +msgid "Localizable" +msgstr "Localisable" + +#. Programmer's name for it: SLocalizableCategoryDesc +#: Vcl/consts.pas:335 +msgid "Localizable properties and/or events" +msgstr "Propriétés et/ou événements Localisable" + +#. Programmer's name for it: SMiscellaneousCategoryName +#: Vcl/consts.pas:336 +msgid "Miscellaneous" +msgstr "Divers" + +#. Programmer's name for it: SMiscellaneousCategoryDesc +#: Vcl/consts.pas:337 +msgid "Miscellaneous properties and/or events" +msgstr "Propriétés et/ou événements Divers" + +#. Programmer's name for it: SVisualCategoryName +#: Vcl/consts.pas:338 +msgid "Visual" +msgstr "Visuel" + +#. Programmer's name for it: SVisualCategoryDesc +#: Vcl/consts.pas:339 +msgid "Visual properties and/or events" +msgstr "Propriétés et/ou événements Visuel" + +#. Programmer's name for it: SInputCategoryName +#: Vcl/consts.pas:340 +msgid "Input" +msgstr "Entrée" + +#. Programmer's name for it: SInputCategoryDesc +#: Vcl/consts.pas:341 +msgid "Input properties and/or events" +msgstr "Propriétés et/ou événements Entrée" + +#. Programmer's name for it: SInvalidMask +#: Vcl/consts.pas:343 +msgid "'%s' is an invalid mask at (%d)" +msgstr "'%s' est un masque incorrect à (%d)" + +#. Programmer's name for it: SInvalidFilter +#: Vcl/consts.pas:344 +msgid "Property filters may only be name, class or type based (%d:%d)" +msgstr "Les filtres de propriétés ne peuvent être basés que sur nom, classe ou type (%d:%d)" + +#. Programmer's name for it: SInvalidCategory +#: Vcl/consts.pas:345 +msgid "Categories must define their own name and description" +msgstr "Les catégories doivent définir leur propre nom et description" + +#. Programmer's name for it: sOperationNotAllowed +#: Vcl/consts.pas:347 +msgid "Operation not allowed while dispatching application events" +msgstr "Opération non autorisée lors de la répartition des événements de l'application" + +#. Programmer's name for it: sInvalidClassReference +#: Vcl/ctlpanel.pas:129 +msgid "Invalid class reference for TAppletApplication" +msgstr "Référence de classe incorrecte pour TAppletApplication" + +#. Programmer's name for it: SInvalidFieldSize +#: Vcl/dbconsts.pas:15 +msgid "Invalid field size" +msgstr "Taille de champ incorrecte" + +#. Programmer's name for it: SInvalidFieldKind +#: Vcl/dbconsts.pas:16 +msgid "Invalid FieldKind" +msgstr "FieldKind incorrect" + +#. Programmer's name for it: SInvalidFieldRegistration +#: Vcl/dbconsts.pas:17 +msgid "Invalid field registration" +msgstr "Enregistrement de champ incorrect" + +#. Programmer's name for it: SUnknownFieldType +#: Vcl/dbconsts.pas:18 +msgid "Field '%s' is of an unknown type" +msgstr "Le champ '%s' est d'un type inconnu" + +#. Programmer's name for it: SFieldNameMissing +#: Vcl/dbconsts.pas:19 +msgid "Field name missing" +msgstr "Nom de champ manquant" + +#. Programmer's name for it: SDuplicateFieldName +#: Vcl/dbconsts.pas:20 +msgid "Duplicate field name '%s'" +msgstr "Nom de champ dupliqué '%s'" + +#. Programmer's name for it: SFieldNotFound +#: Vcl/dbconsts.pas:21 +msgid "Field '%s' not found" +msgstr "Champ '%s' non trouvé" + +#. Programmer's name for it: SFieldAccessError +#: Vcl/dbconsts.pas:22 +msgid "Cannot access field '%s' as type %s" +msgstr "Impossible d'accéder au champ '%s' comme type %s" + +#. Programmer's name for it: SFieldValueError +#: Vcl/dbconsts.pas:23 +msgid "Invalid value for field '%s'" +msgstr "Valeur incorrecte pour le champ '%s'" + +#. Programmer's name for it: SFieldRangeError +#: Vcl/dbconsts.pas:24 +msgid "%g is not a valid value for field '%s'. The allowed range is %g to %g" +msgstr "%g n'est pas une valeur correcte pour le champ '%s'. Les valeurs doivent être comprises entre %g et %g" + +#. Programmer's name for it: SInvalidIntegerValue +#: Vcl/dbconsts.pas:25 +msgid "'%s' is not a valid integer value for field '%s'" +msgstr "'%s' n'est pas une valeur entière correcte pour le champ '%s'" + +#. Programmer's name for it: SInvalidBoolValue +#: Vcl/dbconsts.pas:26 +msgid "'%s' is not a valid boolean value for field '%s'" +msgstr "'%s' n'est pas une valeur booléenne correcte pour le champ '%s'" + +#. Programmer's name for it: SInvalidFloatValue +#: Vcl/dbconsts.pas:27 +msgid "'%s' is not a valid floating point value for field '%s'" +msgstr "'%s' n'est pas une valeur flottante correcte pour le champ '%s'" + +#. Programmer's name for it: SFieldTypeMismatch +#: Vcl/dbconsts.pas:28 +msgid "Type mismatch for field '%s', expecting: %s actual: %s" +msgstr "Type inadéquat pour le champ '%s', attendu : %s actuel : %s" + +#. Programmer's name for it: SFieldSizeMismatch +#: Vcl/dbconsts.pas:29 +msgid "Size mismatch for field '%s', expecting: %d actual: %d" +msgstr "Taille inadéquate pour le champ '%s', attendu : %d actuel : %d" + +#. Programmer's name for it: SInvalidVarByteArray +#: Vcl/dbconsts.pas:30 +msgid "Invalid variant type or size for field '%s'" +msgstr "Type ou taille de variant incorrect pour le champ '%s'" + +#. Programmer's name for it: SFieldOutOfRange +#: Vcl/dbconsts.pas:31 +msgid "Value of field '%s' is out of range" +msgstr "La valeur du champ '%s' est hors limites" + +#. Programmer's name for it: SBCDOverflow +#: Vcl/dbconsts.pas:32 +msgid "(Overflow)" +msgstr "(débordement)" + +#. Programmer's name for it: SFieldRequired +#: Vcl/dbconsts.pas:33 +msgid "Field '%s' must have a value" +msgstr "Le champ '%s' doit avoir une valeur" + +#. Programmer's name for it: SDataSetMissing +#: Vcl/dbconsts.pas:34 +msgid "Field '%s' has no dataset" +msgstr "Le champ '%s' n'a pas de DataSet" + +#. Programmer's name for it: SInvalidCalcType +#: Vcl/dbconsts.pas:35 +msgid "Field '%s' cannot be a calculated or lookup field" +msgstr "Le champ '%s' ne peut être un champ calculé ni lookup" + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/dbconsts.pas:36 +msgid "Field '%s' cannot be modified" +msgstr "Le champ '%s' ne peut être modifié" + +#. Programmer's name for it: SFieldIndexError +#: Vcl/dbconsts.pas:37 +msgid "Field index out of range" +msgstr "Index de champ hors limites" + +#. Programmer's name for it: SNoFieldIndexes +#: Vcl/dbconsts.pas:38 +msgid "No index currently active" +msgstr "Aucun index actif actuellement" + +#. Programmer's name for it: SNotIndexField +#: Vcl/dbconsts.pas:39 +msgid "Field '%s' is not indexed and cannot be modified" +msgstr "Le champ '%s' n'est pas indexé et ne peut être modifié" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/dbconsts.pas:40 +msgid "Cannot access index field '%s'" +msgstr "Impossible d'accéder au champ index '%s'" + +#. Programmer's name for it: SDuplicateIndexName +#: Vcl/dbconsts.pas:41 +msgid "Duplicate index name '%s'" +msgstr "Nom d'index dupliqué '%s'" + +#. Programmer's name for it: SNoIndexForFields +#: Vcl/dbconsts.pas:42 +msgid "No index for fields '%s'" +msgstr "Pas d'index pour les champs '%s'" + +#. Programmer's name for it: SIndexNotFound +#: Vcl/dbconsts.pas:43 +msgid "Index '%s' not found" +msgstr "Index '%s' non trouvé" + +#. Programmer's name for it: SDuplicateName +#: Vcl/dbconsts.pas:44 +msgid "Duplicate name '%s' in %s" +msgstr "Nom '%s' dupliqué dans %s" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/dbconsts.pas:45 +msgid "Circular datalinks are not allowed" +msgstr "Liaisons de données circulaires non autorisées" + +#. Programmer's name for it: SLookupInfoError +#: Vcl/dbconsts.pas:46 +msgid "Lookup information for field '%s' is incomplete" +msgstr "Information de référence pour le champ '%s' incomplète" + +#. Programmer's name for it: SDataSourceChange +#: Vcl/dbconsts.pas:47 +msgid "DataSource cannot be changed" +msgstr "DataSource ne peut être modifié" + +#. Programmer's name for it: SNoNestedMasterSource +#: Vcl/dbconsts.pas:48 +msgid "Nested datasets cannot have a MasterSource" +msgstr "Les datasets imbriqués ne peuvent avoir de MasterSource" + +#. Programmer's name for it: SDataSetOpen +#: Vcl/dbconsts.pas:49 +msgid "Cannot perform this operation on an open dataset" +msgstr "Impossible d'effectuer cette opération sur un ensemble de données ouvert" + +#. Programmer's name for it: SNotEditing +#: Vcl/dbconsts.pas:50 +msgid "Dataset not in edit or insert mode" +msgstr "L'ensemble de données n'est pas en mode Edition ou Insertion" + +#. Programmer's name for it: SDataSetClosed +#: Vcl/dbconsts.pas:51 +msgid "Cannot perform this operation on a closed dataset" +msgstr "Impossible d'effectuer cette opération sur un ensemble de données fermé" + +#. Programmer's name for it: SDataSetEmpty +#: Vcl/dbconsts.pas:52 +msgid "Cannot perform this operation on an empty dataset" +msgstr "Impossible d'effectuer cette opération sur un ensemble de données vide" + +#. Programmer's name for it: SDataSetReadOnly +#: Vcl/dbconsts.pas:53 +msgid "Cannot modify a read-only dataset" +msgstr "Impossible de modifier un ensemble de données en lecture seule" + +#. Programmer's name for it: SNestedDataSetClass +#: Vcl/dbconsts.pas:54 +msgid "Nested dataset must inherit from %s" +msgstr "Le dataset imbriqué doit hériter de %s" + +#. Programmer's name for it: SExprTermination +#: Vcl/dbconsts.pas:55 +msgid "Filter expression incorrectly terminated" +msgstr "Expression filtre terminée incorrectement" + +#. Programmer's name for it: SExprNameError +#: Vcl/dbconsts.pas:56 +msgid "Unterminated field name" +msgstr "Nom de champ non terminé" + +#. Programmer's name for it: SExprStringError +#: Vcl/dbconsts.pas:57 +msgid "Unterminated string constant" +msgstr "Constante chaîne non terminée" + +#. Programmer's name for it: SExprInvalidChar +#: Vcl/dbconsts.pas:58 +msgid "Invalid filter expression character: '%s'" +msgstr "Caractère d'expression filtre incorrect : '%s'" + +#. Programmer's name for it: SExprNoLParen +#: Vcl/dbconsts.pas:59 +msgid "'(' expected but %s found" +msgstr "'(' attendu mais %s trouvé" + +#. Programmer's name for it: SExprNoRParen +#: Vcl/dbconsts.pas:60 +msgid "')' expected but %s found" +msgstr "')' attendu mais %s trouvé" + +#. Programmer's name for it: SExprNoRParenOrComma +#: Vcl/dbconsts.pas:61 +msgid "')' or ',' expected but %s found" +msgstr "')' ou ',' attendu mais %s trouvé" + +#. Programmer's name for it: SExprExpected +#: Vcl/dbconsts.pas:62 +msgid "Expression expected but %s found" +msgstr "Expression attendue mais %s trouvé" + +#. Programmer's name for it: SExprBadField +#: Vcl/dbconsts.pas:63 +msgid "Field '%s' cannot be used in a filter expression" +msgstr "Le champ '%s' ne peut être utilisé dans une expression filtre" + +#. Programmer's name for it: SExprBadNullTest +#: Vcl/dbconsts.pas:64 +msgid "NULL only allowed with '=' and '<>'" +msgstr "NULL autorisé seulement avec '=' et '<>'" + +#. Programmer's name for it: SExprRangeError +#: Vcl/dbconsts.pas:65 +msgid "Constant out of range" +msgstr "Constante hors limites" + +#. Programmer's name for it: SExprNotBoolean +#: Vcl/dbconsts.pas:66 +msgid "Field '%s' is not of type Boolean" +msgstr "Le champ '%s' n'est pas de type BOOLEAN" + +#. Programmer's name for it: SExprIncorrect +#: Vcl/dbconsts.pas:67 +msgid "Incorrectly formed filter expression" +msgstr "Expression filtre formée incorrectement" + +#. Programmer's name for it: SExprNothing +#: Vcl/dbconsts.pas:68 +msgid "nothing" +msgstr "vide" + +#. Programmer's name for it: SExprTypeMis +#: Vcl/dbconsts.pas:69 +msgid "Type mismatch in expression" +msgstr "Non concordance de type dans l'expression" + +#. Programmer's name for it: SExprBadScope +#: Vcl/dbconsts.pas:70 +msgid "Operation cannot mix aggregate value with record-varying value" +msgstr "L'opération ne peut grouper une valeur globale avec une valeur variant par enregistrement" + +#. Programmer's name for it: SExprNoArith +#: Vcl/dbconsts.pas:71 +msgid "Arithmetic in filter expressions not supported" +msgstr "Arithmétique non supportée dans les expressions filtre" + +#. Programmer's name for it: SExprNotAgg +#: Vcl/dbconsts.pas:72 +msgid "Expression is not an aggregate expression" +msgstr "L'expression n'est pas une expression globale" + +#. Programmer's name for it: SExprBadConst +#: Vcl/dbconsts.pas:73 +msgid "Constant is not correct type %s" +msgstr "La constante n'est pas du type correct %s" + +#. Programmer's name for it: SExprNoAggFilter +#: Vcl/dbconsts.pas:74 +msgid "Aggregate expressions not allowed in filters" +msgstr "Les expressions globales ne sont pas autorisées dans les filtres" + +#. Programmer's name for it: SExprEmptyInList +#: Vcl/dbconsts.pas:75 +msgid "IN predicate list may not be empty" +msgstr "La liste de prédicats IN ne peut être vide" + +#. Programmer's name for it: SInvalidKeywordUse +#: Vcl/dbconsts.pas:76 +msgid "Invalid use of keyword" +msgstr "Utilisation incorrecte du mot clé" + +#. Programmer's name for it: SParameterNotFound +#: Vcl/dbconsts.pas:79 +msgid "Parameter '%s' not found" +msgstr "Paramètres '%s' non trouvés" + +#. Programmer's name for it: SInvalidVersion +#: Vcl/dbconsts.pas:80 +msgid "Unable to load bind parameters" +msgstr "Impossible de charger les paramètres de liaison" + +#. Programmer's name for it: SParamTooBig +#: Vcl/dbconsts.pas:81 +msgid "Parameter '%s', cannot save data larger than %d bytes" +msgstr "Le paramètre '%s' ne peut enregistrer des données de plus de %d octets" + +#. Programmer's name for it: SBadFieldType +#: Vcl/dbconsts.pas:82 +msgid "Field '%s' is of an unsupported type" +msgstr "Le champ '%s' est d'un type non supporté" + +#. Programmer's name for it: SAggActive +#: Vcl/dbconsts.pas:83 +msgid "Property may not be modified while aggregate is active" +msgstr "La propriété ne peut être modifiée lorsque aggregate est actif" + +#. Programmer's name for it: SProviderSQLNotSupported +#: Vcl/dbconsts.pas:84 +msgid "SQL not supported: %s" +msgstr "SQL non supporté : %s" + +#. Programmer's name for it: SProviderExecuteNotSupported +#: Vcl/dbconsts.pas:85 +msgid "Execute not supported: %s" +msgstr "Execute non supporté : %s" + +#. Programmer's name for it: SExprNoAggOnCalcs +#: Vcl/dbconsts.pas:86 +msgid "Field '%s' is not the correct type of calculated field to be used in an aggregate, use an internalcalc" +msgstr "Le champ '%s' n'est pas le type correct de champ calculé à utiliser dans un agrégat, utilisez un CalcInterne" + +#. Programmer's name for it: SRecordChanged +#: Vcl/dbconsts.pas:87 +msgid "Record changed by another user" +msgstr "Enregistrement modifié par un autre utilisateur" + +#. Programmer's name for it: SFirstRecord +#: Vcl/dbconsts.pas:90 +msgid "First record" +msgstr "Premier enregistrement" + +#. Programmer's name for it: SPriorRecord +#: Vcl/dbconsts.pas:91 +msgid "Prior record" +msgstr "Enregistrement précédent" + +#. Programmer's name for it: SNextRecord +#: Vcl/dbconsts.pas:92 +msgid "Next record" +msgstr "Enregistrement suivant" + +#. Programmer's name for it: SLastRecord +#: Vcl/dbconsts.pas:93 +msgid "Last record" +msgstr "Dernier enregistrement" + +#. Programmer's name for it: SInsertRecord +#: Vcl/dbconsts.pas:94 +msgid "Insert record" +msgstr "Insérer enregistrement" + +#. Programmer's name for it: SDeleteRecord +#: Vcl/dbconsts.pas:95 +msgid "Delete record" +msgstr "Supprimer enregistrement" + +#. Programmer's name for it: SEditRecord +#: Vcl/dbconsts.pas:96 +msgid "Edit record" +msgstr "Modifier enregistrement" + +#. Programmer's name for it: SPostEdit +#: Vcl/dbconsts.pas:97 +msgid "Post edit" +msgstr "Valider modifications" + +#. Programmer's name for it: SCancelEdit +#: Vcl/dbconsts.pas:98 +msgid "Cancel edit" +msgstr "Annuler modifications" + +#. Programmer's name for it: SRefreshRecord +#: Vcl/dbconsts.pas:99 +msgid "Refresh data" +msgstr "Rafraîchir données" + +#. Programmer's name for it: SDeleteRecordQuestion +#: Vcl/dbconsts.pas:100 +msgid "Delete record?" +msgstr "Supprimer l'enregistrement ?" + +#. Programmer's name for it: SDeleteMultipleRecordsQuestion +#: Vcl/dbconsts.pas:101 +msgid "Delete all selected records?" +msgstr "Supprimer tous les enregistrements sélectionnés ?" + +#. Programmer's name for it: SRecordNotFound +#: Vcl/dbconsts.pas:102 +msgid "Record not found" +msgstr "Enregistrement non trouvé" + +#. Programmer's name for it: SDataSourceFixed +#: Vcl/dbconsts.pas:103 +msgid "Operation not allowed in a DBCtrlGrid" +msgstr "Opération non autorisée dans un DBCtrlGrid" + +#. Programmer's name for it: SNotReplicatable +#: Vcl/dbconsts.pas:104 +msgid "Control cannot be used in a DBCtrlGrid" +msgstr "Le contrôle ne peut être utilisé dans un DBCtrlGrid" + +#. Programmer's name for it: SPropDefByLookup +#: Vcl/dbconsts.pas:105 +msgid "Property already defined by lookup field" +msgstr "Propriété déjà définie dans un DBCtrlGrid" + +#. Programmer's name for it: STooManyColumns +#: Vcl/dbconsts.pas:106 +msgid "Grid requested to display more than 256 columns" +msgstr "La grille nécessitait d'afficher plus de 256 colonnes" + +#. Programmer's name for it: SRemoteLogin +#: Vcl/dbconsts.pas:109 +msgid "Remote Login" +msgstr "Connexion distante" + +#. Programmer's name for it: SDataBindings +#: Vcl/dbconsts.pas:112 +msgid "Data Bindings..." +msgstr "Liaisons de données..." + +#. Programmer's name for it: SIBTransactionEditor +#: Vcl/ib.pas:156 +msgid "&Transaction Editor..." +msgstr "Editeur de &transaction..." + +#. Programmer's name for it: SDatabaseFilter +#: Vcl/ib.pas:157 +msgid "Database Files (*.gdb)|*.gdb|All files (*.*)|*.*" +msgstr "Fichiers bases de données (*.gdb)|*.gdb|Tous les fichiers (*.*)|*.*" + +#. Programmer's name for it: SCommitTransaction +#: Vcl/ib.pas:159 +msgid "Transaction is currently Active. Rollback and continue?" +msgstr "Transaction actuellement active. Rollback et continuer ?" + +#. Programmer's name for it: SUnknownError +#: Vcl/ib.pas:168 +msgid "Unknown error" +msgstr "Erreur inconnue." + +#. Programmer's name for it: SInterBaseMissing +#: Vcl/ib.pas:169 +msgid "InterBase library gds32.dll not found in the path. Please install InterBase to use this functionality" +msgstr "DLL InterBase gds32.dll non trouvée dans le chemin" + +#. Programmer's name for it: SInterBaseInstallMissing +#: Vcl/ib.pas:170 +msgid "InterBase Install DLL ibinstall.dll not found in the path. Please install InterBase 6 to use this functionality" +msgstr "DLL d'installation InterBase ibinstall.dll non trouvée dans le chemin. Veuillez installer InterBase 6 pour cette fonctionnalité" + +#. Programmer's name for it: SIB60feature +#: Vcl/ib.pas:171 +msgid "%s is an InterBase6 function. Please upgrade to InterBase6 to use this functonality" +msgstr "%s est une fonction spécifique IB 6. Passez à IB6 pour utiliser cette fonctionnalité" + +#. Programmer's name for it: SNotSupported +#: Vcl/ib.pas:172 +msgid "Unsupported feature" +msgstr "Fonctionnalité non supportée." + +#. Programmer's name for it: SNotPermitted +#: Vcl/ib.pas:173 +msgid "Not permitted" +msgstr "Non permis." + +#. Programmer's name for it: SFileAccessError +#: Vcl/ib.pas:174 +msgid "Temporary file access error" +msgstr "Erreur d'accès au fichier temporaire." + +#. Programmer's name for it: SConnectionTimeout +#: Vcl/ib.pas:175 +msgid "Database connection timed out" +msgstr "La connexion base de données a dépassé le temps imparti." + +#. Programmer's name for it: SCannotSetDatabase +#: Vcl/ib.pas:176 +msgid "Cannot set database" +msgstr "Ne peut définir la base de données." + +#. Programmer's name for it: SCannotSetTransaction +#: Vcl/ib.pas:177 +msgid "Cannot set transaction" +msgstr "Ne peut définir la transaction." + +#. Programmer's name for it: SOperationCancelled +#: Vcl/ib.pas:178 +msgid "Operation cancelled at user's request" +msgstr "Opération annulée à la demande de l'utilisateur." + +#. Programmer's name for it: SDPBConstantNotSupported +#: Vcl/ib.pas:179 +msgid "DPB Constant (isc_dpb_%s) is unsupported" +msgstr "Constante DPB (isc_dpb_%s) non supportée." + +#. Programmer's name for it: SDPBConstantUnknown +#: Vcl/ib.pas:180 +msgid "DPB Constant (%d) is unknown" +msgstr "Constante DPB (%d) inconnue." + +#. Programmer's name for it: STPBConstantNotSupported +#: Vcl/ib.pas:181 +msgid "TPB Constant (isc_tpb_%s) is unsupported" +msgstr "Constante TPB (isc_tpb_%s) non supportée." + +#. Programmer's name for it: STPBConstantUnknown +#: Vcl/ib.pas:182 +msgid "TPB Constant (%d) is unknown" +msgstr "Constante TPB (%d) inconnue." + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/ib.pas:183 +msgid "Cannot perform operation -- DB is not open" +msgstr "Ne peut effectuer l'opération -- La base n'est pas ouverte." + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/ib.pas:184 +msgid "Cannot perform operation -- DB is currently open" +msgstr "Ne peut effectuer l'opération -- La base est actuellement ouverte." + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/ib.pas:185 +msgid "Database name is missing" +msgstr "Le nom de base de données est manquant." + +#. Programmer's name for it: SNotInTransaction +#: Vcl/ib.pas:186 +msgid "Transaction is not active" +msgstr "La transaction n'est pas active." + +#. Programmer's name for it: SInTransaction +#: Vcl/ib.pas:187 +msgid "Transaction is active" +msgstr "La transaction est active." + +#. Programmer's name for it: STimeoutNegative +#: Vcl/ib.pas:188 +msgid "Timeout values cannot be negative" +msgstr "Les valeurs de délai imparti ne peuvent être négatives." + +#. Programmer's name for it: SNoDatabasesInTransaction +#: Vcl/ib.pas:189 +msgid "No databases are listed in transaction component" +msgstr "Aucune base de données listée dans le composant transaction." + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/ib.pas:190 +msgid "Updating wrong database" +msgstr "Mise à jour de la mauvaise base de données." + +#. Programmer's name for it: SUpdateWrongTR +#: Vcl/ib.pas:191 +msgid "Updating wrong transaction. Unique transaction expected in set" +msgstr "Mise à jour de la mauvaise transaction. Transaction unique attendue dans le set" + +#. Programmer's name for it: SDatabaseNotAssigned +#: Vcl/ib.pas:192 +msgid "Database not assigned" +msgstr "Base de données non affectée." + +#. Programmer's name for it: STransactionNotAssigned +#: Vcl/ib.pas:193 +msgid "Transaction not assigned" +msgstr "Transaction non affectée." + +#. Programmer's name for it: SXSQLDAIndexOutOfRange +#: Vcl/ib.pas:194 +msgid "XSQLDA index out of range" +msgstr "Index XSQLDA hors limites." + +#. Programmer's name for it: SXSQLDANameDoesNotExist +#: Vcl/ib.pas:195 +msgid "XSQLDA name does not exist (%s)" +msgstr "Nom XSQLDA inexistant (%s)." + +#. Programmer's name for it: SEOF +#: Vcl/ib.pas:196 +msgid "End of file" +msgstr "Fin de fichier." + +#. Programmer's name for it: SBOF +#: Vcl/ib.pas:197 +msgid "Beginning of file" +msgstr "Début du fichier." + +#. Programmer's name for it: SInvalidStatementHandle +#: Vcl/ib.pas:198 +msgid "Invalid statement handle" +msgstr "Handle d'instruction incorrect." + +#. Programmer's name for it: SSQLOpen +#: Vcl/ib.pas:199 +msgid "IBSQL Open" +msgstr "IBSQL ouvert" + +#. Programmer's name for it: SSQLClosed +#: Vcl/ib.pas:200 +msgid "IBSQL Closed" +msgstr "IBSQL fermé" + +#. Programmer's name for it: SDatasetOpen +#: Vcl/ib.pas:201 +msgid "Dataset open" +msgstr "Dataset ouvert." + +#. Programmer's name for it: SDatasetClosed +#: Vcl/ib.pas:202 +msgid "Dataset closed" +msgstr "Dataset fermé." + +#. Programmer's name for it: SUnknownSQLDataType +#: Vcl/ib.pas:203 +msgid "Unknown SQL Data type (%d)" +msgstr "Type de données SQL inconnu (%d)." + +#. Programmer's name for it: SInvalidColumnIndex +#: Vcl/ib.pas:204 +msgid "Invalid column index (index exceeds permitted range)" +msgstr "indice de colonne incorrect (il dépasse les limites)." + +#. Programmer's name for it: SInvalidParamColumnIndex +#: Vcl/ib.pas:205 +msgid "Invalid parameter index (index exceeds permitted range)" +msgstr "Indice de paramètre incorrect (il dépasse les limites)." + +#. Programmer's name for it: SInvalidDataConversion +#: Vcl/ib.pas:206 +msgid "Invalid data conversion" +msgstr "Conversion de données incorrecte." + +#. Programmer's name for it: SColumnIsNotNullable +#: Vcl/ib.pas:207 +msgid "Column cannot be set to null (%s)" +msgstr "La colonne ne peut être définie à null (%s)" + +#. Programmer's name for it: SBlobCannotBeRead +#: Vcl/ib.pas:208 +msgid "Blob stream cannot be read" +msgstr "Ne peut lire dans le flux blob." + +#. Programmer's name for it: SBlobCannotBeWritten +#: Vcl/ib.pas:209 +msgid "Blob stream cannot be written" +msgstr "Ne peut écrire dans le flux blob." + +#. Programmer's name for it: SEmptyQuery +#: Vcl/ib.pas:210 +msgid "Empty query" +msgstr "Requête vide." + +#. Programmer's name for it: SCannotOpenNonSQLSelect +#: Vcl/ib.pas:211 +msgid "Cannot \"open\" a non-select statement. Use ExecQuery" +msgstr "Ne peut ouvrir (open) une instruction non sélectionnée. Utilisez ExecQuery." + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/ib.pas:212 +msgid "No access to field \"%s\"" +msgstr "Pas d'accès au champ %s." + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/ib.pas:213 +msgid "Field \"%s\" is read-only" +msgstr "Champ %s en lecture-seule." + +#. Programmer's name for it: SFieldNotFound +#: Vcl/ib.pas:214 +msgid "Field \"%s\" not found" +msgstr "Champ %s non trouvé." + +#. Programmer's name for it: SNotEditing +#: Vcl/ib.pas:215 +msgid "Not editing" +msgstr "Pas en édition." + +#. Programmer's name for it: SCannotInsert +#: Vcl/ib.pas:216 +msgid "Cannot insert into dataset. (No insert query)" +msgstr "Ne peut insérer dans le dataset. (pas de requête insert)." + +#. Programmer's name for it: SCannotPost +#: Vcl/ib.pas:217 +msgid "Cannot post. (No update/insert query)" +msgstr "Ne peut poster. (pas de requête update/insert)." + +#. Programmer's name for it: SCannotUpdate +#: Vcl/ib.pas:218 +msgid "Cannot update. (No update query)" +msgstr "Ne peut mettre à jour. (pas de requête update)." + +#. Programmer's name for it: SCannotDelete +#: Vcl/ib.pas:219 +msgid "Cannot delete from dataset. (No delete query)" +msgstr "Ne peut supprimer depuis le dataset. (pas de requête delete)." + +#. Programmer's name for it: SCannotRefresh +#: Vcl/ib.pas:220 +msgid "Cannot refresh row. (No refresh query)" +msgstr "Ne peut rafraîchir la ligne. (pas de requête refresh)." + +#. Programmer's name for it: SBufferNotSet +#: Vcl/ib.pas:221 +msgid "Buffer not set" +msgstr "Tampon non défini." + +#. Programmer's name for it: SCircularReference +#: Vcl/ib.pas:222 +msgid "Circular references not permitted" +msgstr "Références circulaires non autorisées" + +#. Programmer's name for it: SSQLParseError +#: Vcl/ib.pas:223 +msgid "" +"SQL Parse Error:\n" +"\n" +"%s" +msgstr "" +"Erreur analyse SQL :\n" +"\n" +"%s" + +#. Programmer's name for it: SUserAbort +#: Vcl/ib.pas:224 +msgid "User abort" +msgstr "Abandon par l'utilisateur." + +#. Programmer's name for it: SDataSetUniDirectional +#: Vcl/ib.pas:225 +msgid "Data set is uni-directional" +msgstr "Le Dataset est uni-directionnel." + +#. Programmer's name for it: SCannotCreateSharedResource +#: Vcl/ib.pas:226 +msgid "Cannot create shared resource. (Windows error %d)" +msgstr "Ne peut créer la ressource partagée. (Erreur Windows %d)" + +#. Programmer's name for it: SWindowsAPIError +#: Vcl/ib.pas:227 +msgid "Windows API error. (Windows error %d [$%.8x])" +msgstr "Erreur de l'API Windows. (Erreur Windows %d [$%.8x])" + +#. Programmer's name for it: SColumnListsDontMatch +#: Vcl/ib.pas:228 +msgid "Column lists do not match" +msgstr "Les listes de colonnes ne correspondent pas." + +#. Programmer's name for it: SColumnTypesDontMatch +#: Vcl/ib.pas:229 +msgid "Column types don't match. (From index: %d; To index: %d)" +msgstr "Les types de colonnes ne correspondent pas. (From index: %d; To index: %d)" + +#. Programmer's name for it: SCantEndSharedTransaction +#: Vcl/ib.pas:231 +msgid "Can't end a shared transaction unless it is forced and equal to the transaction's TimeoutAction" +msgstr "Ne peut terminer une transaction partagée à moins qu'elle soit forcée et égale au TimeoutAction de la transaction." + +#. Programmer's name for it: SFieldUnsupportedType +#: Vcl/ib.pas:232 +msgid "Unsupported Field Type" +msgstr "Type de champ non supporté" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/ib.pas:233 +msgid "Circular DataLink Reference" +msgstr "Référence circulaire DataLink" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/ib.pas:234 +msgid "Empty SQL Statement" +msgstr "Instruction SQL vide" + +#. Programmer's name for it: SIsASelectStatement +#: Vcl/ib.pas:235 +msgid "use Open for a Select Statement" +msgstr "Utilisez Open pour l'instruction Select" + +#. Programmer's name for it: SRequiredParamNotSet +#: Vcl/ib.pas:236 +msgid "Required Param value not set" +msgstr "Valeur de paramètre requise non définie" + +#. Programmer's name for it: SNoStoredProcName +#: Vcl/ib.pas:237 +msgid "No Stored Procedure Name assigned" +msgstr "Aucun nom de procédure stockée affecté" + +#. Programmer's name for it: SIsAExecuteProcedure +#: Vcl/ib.pas:238 +msgid "use ExecProc for Procedure; use TQuery for Select procedures" +msgstr "Utilisez ExecProc pour Procedure; Utilisez TQuery pour Select procedures" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/ib.pas:239 +msgid "Update Failed" +msgstr "Echec de la mise à jour" + +#. Programmer's name for it: SNotCachedUpdates +#: Vcl/ib.pas:240 +msgid "CachedUpdates not enabled" +msgstr "CachedUpdates non activé" + +#. Programmer's name for it: SNotLiveRequest +#: Vcl/ib.pas:241 +msgid "Request is not live - cannot modify" +msgstr "La requête n'est pas vivante. Ne peut la modifier" + +#. Programmer's name for it: SNoProvider +#: Vcl/ib.pas:242 +msgid "No Provider" +msgstr "Aucun fournisseur" + +#. Programmer's name for it: SNoRecordsAffected +#: Vcl/ib.pas:243 +msgid "No Records Affected" +msgstr "Aucun enregistrement affecté" + +#. Programmer's name for it: SNoTableName +#: Vcl/ib.pas:244 +msgid "No Table Name assigned" +msgstr "Aucun nom de table affecté" + +#. Programmer's name for it: SCannotCreatePrimaryIndex +#: Vcl/ib.pas:245 +msgid "Cannot Create Primary Index; are created automatically" +msgstr "Ne peut créer l'index primaire ; créé automatiquement" + +#. Programmer's name for it: SCannotDropSystemIndex +#: Vcl/ib.pas:246 +msgid "Cannot Drop System Index" +msgstr "Ne peut abandonner l'index système" + +#. Programmer's name for it: STableNameMismatch +#: Vcl/ib.pas:247 +msgid "Table Name Mismatch" +msgstr "Nom de table inadéquat" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/ib.pas:248 +msgid "Index Field Missing" +msgstr "Champ index manquant" + +#. Programmer's name for it: SInvalidCancellation +#: Vcl/ib.pas:249 +msgid "Cannot Cancel events while processing" +msgstr "Ne peut annuler les événements lors du traitement" + +#. Programmer's name for it: SInvalidEvent +#: Vcl/ib.pas:250 +msgid "Invalid Event" +msgstr "Evénement incorrect" + +#. Programmer's name for it: SMaximumEvents +#: Vcl/ib.pas:251 +msgid "Exceded Maximum Event limits" +msgstr "Limite maxi d'événements dépassée" + +#. Programmer's name for it: SNoEventsRegistered +#: Vcl/ib.pas:252 +msgid "No Events Registered" +msgstr "Aucun événement recensé" + +#. Programmer's name for it: SInvalidQueueing +#: Vcl/ib.pas:253 +msgid "Invalid Queueing" +msgstr "Queueing incorrect" + +#. Programmer's name for it: SInvalidRegistration +#: Vcl/ib.pas:254 +msgid "Invalid Registration" +msgstr "Enregistrement incorrect" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/ib.pas:255 +msgid "Invalid Batch Move" +msgstr "Batch Move invalide" + +#. Programmer's name for it: SSQLDialectInvalid +#: Vcl/ib.pas:256 +msgid "SQL Dialect Invalid" +msgstr "Dialecte SQL incorrect" + +#. Programmer's name for it: SSPBConstantNotSupported +#: Vcl/ib.pas:257 +msgid "SPB Constant Not supported" +msgstr "Constante SPB non supportée" + +#. Programmer's name for it: SSPBConstantUnknown +#: Vcl/ib.pas:258 +msgid "SPB Constant Unknown" +msgstr "Constante SPB inconnue" + +#. Programmer's name for it: SServiceActive +#: Vcl/ib.pas:259 +msgid "Cannot perform operation -- service is not attached" +msgstr "Ne peut effectuer l'opération -- le service n'est pas attaché." + +#. Programmer's name for it: SServiceInActive +#: Vcl/ib.pas:260 +msgid "Cannot perform operation -- service is attached" +msgstr "Ne peut effectuer l'opération -- le service est attaché." + +#. Programmer's name for it: SServerNameMissing +#: Vcl/ib.pas:261 +msgid "Server Name Missing" +msgstr "Nom de serveur manquant" + +#. Programmer's name for it: SQueryParamsError +#: Vcl/ib.pas:262 +msgid "Query Parameters missing or incorrect" +msgstr "Paramètres de requête manquants ou incorrects" + +#. Programmer's name for it: SStartParamsError +#: Vcl/ib.pas:263 +msgid "start Parameters missing or incorrect" +msgstr "Paramètres start manquants ou incorrect" + +#. Programmer's name for it: SOutputParsingError +#: Vcl/ib.pas:264 +msgid "Unexpected Output buffer value" +msgstr "Valeur de tampon de sortie inattendue" + +#. Programmer's name for it: SUseSpecificProcedures +#: Vcl/ib.pas:265 +msgid "Generic ServiceStart not applicable: Use Specific Procedures to set configuration params" +msgstr "ServiceStart générique non applicable : Utilisez des procédures spécifiques pour définir les paramètres de configuration" + +#. Programmer's name for it: SSQLMonitorAlreadyPresent +#: Vcl/ib.pas:266 +msgid "SQL Monitor Instance is already present" +msgstr "Une instance du Moniteur SQL est déjà présente" + +#. Programmer's name for it: SEOFInComment +#: Vcl/ibsql.pas:24 +msgid "EOF in comment detected" +msgstr "EOF détecté dans un commentaire" + +#. Programmer's name for it: SEOFInString +#: Vcl/ibsql.pas:25 +msgid "EOF in string detected" +msgstr "EOF détecté dans une chaîne" + +#. Programmer's name for it: SParamNameExpected +#: Vcl/ibsql.pas:26 +msgid "Parameter name expected" +msgstr "Nom de paramètre attendu" + +#. Programmer's name for it: SCantPrintValue +#: Vcl/ibsqlmonitor.pas:24 +msgid "Cannot print value" +msgstr "Ne peut imprimer la valeur" + +#. Programmer's name for it: SEOFReached +#: Vcl/ibsqlmonitor.pas:25 +msgid "SEOFReached" +msgstr "SEOFReached" + +#. Programmer's name for it: SProviderNotExported +#: Vcl/midconst.pas:33 +msgid "Provider not exported: %s" +msgstr "Fournisseur non exporté : %s" + +#. Programmer's name for it: SNoDataProvider +#: Vcl/midconst.pas:36 +msgid "Missing data provider or data packet" +msgstr "Fournisseur de données ou paquet de données manquant" + +#. Programmer's name for it: SInvalidDataPacket +#: Vcl/midconst.pas:37 +msgid "Invalid data packet" +msgstr "Paquet de données incorrect" + +#. Programmer's name for it: SRefreshError +#: Vcl/midconst.pas:38 +msgid "Must apply updates before refreshing data" +msgstr "Vous devez valider les modifications avant de rafraîchir les données" + +#. Programmer's name for it: SProviderInvalid +#: Vcl/midconst.pas:39 +msgid "Invalid provider. Provider was freed by the application server" +msgstr "Fournisseur incorrect. Le fournisseur a été libéré par le serveur d'application" + +#. Programmer's name for it: SServerNameBlank +#: Vcl/midconst.pas:40 +msgid "Cannot connect, %s must contain a valid ServerName or ServerGUID" +msgstr "Impossible de se connecter, %s doit contenir un ServerName ou ServerGUID correct" + +#. Programmer's name for it: SRepositoryIdBlank +#: Vcl/midconst.pas:41 +msgid "Cannot connect, %s must contain a valid repository id" +msgstr "Connexion impossible, %s doit contenir un id de référentiel correct" + +#. Programmer's name for it: SAggsGroupingLevel +#: Vcl/midconst.pas:42 +msgid "Grouping level exceeds current index field count" +msgstr "Le niveau de groupement dépasse le nombre de champs d'index actuel" + +#. Programmer's name for it: SAggsNoSuchLevel +#: Vcl/midconst.pas:43 +msgid "Grouping level not defined" +msgstr "Niveau de groupement non défini" + +#. Programmer's name for it: SNoCircularReference +#: Vcl/midconst.pas:44 +msgid "Circular provider references not allowed" +msgstr "Références de fournisseurs circulaires non autorisées" + +#. Programmer's name for it: SErrorLoadingMidas +#: Vcl/midconst.pas:45 +msgid "Error loading MIDAS.DLL" +msgstr "Erreur au chargement de MIDAS.DLL" + +#. Programmer's name for it: SCannotCreateDataSet +#: Vcl/midconst.pas:46 +msgid "No fields defined. Cannot create dataset" +msgstr "Aucun champ défini. Ne peut créer le dataset" + +#. Programmer's name for it: SSocketReadError +#: Vcl/midconst.pas:49 +msgid "Error reading from socket" +msgstr "Erreur de lecture de la socket" + +#. Programmer's name for it: SInvalidProviderName +#: Vcl/midconst.pas:50 +msgid "Provider name \"%s\" was not recognized by the server" +msgstr "Le nom de fournisseur \"%s\" n'a pas été reconnu par le serveur" + +#. Programmer's name for it: SBadVariantType +#: Vcl/midconst.pas:51 +msgid "Unsupported variant type: %s" +msgstr "Type de variant non supporté : %s" + +#. Programmer's name for it: SInvalidAction +#: Vcl/midconst.pas:52 +msgid "Invalid action received: %d" +msgstr "Action reçue incorrecte : %d" + +#. Programmer's name for it: SInvalidResponse +#: Vcl/midconst.pas:55 +msgid "Invalid response" +msgstr "Réponse incorrecte" + +#. Programmer's name for it: STooManyRecordsModified +#: Vcl/midconst.pas:57 +msgid "Update affected more than 1 record." +msgstr "La mise à jour a affecté plus d'un enregistrement" + +#. Programmer's name for it: SInvalidOptParamType +#: Vcl/midconst.pas:60 +msgid "Value cannot be stored in an optional parameter" +msgstr "La valeur ne peut être stockée dans un paramètre optionnel" + +#. Programmer's name for it: SConstraintFailed +#: Vcl/midconst.pas:62 +msgid "Record or field constraint failed." +msgstr "La contrainte d'enregistrement ou de champ a échoué." + +#. Programmer's name for it: SField +#: Vcl/midconst.pas:63 +msgid "Field" +msgstr "Champ" + +#. Programmer's name for it: SReadOnlyProvider +#: Vcl/midconst.pas:64 +msgid "Cannot apply updates to a ReadOnly provider" +msgstr "Ne peut appliquer les mises à jour à un fournisseur en lecture seule" + +#. Programmer's name for it: SNoKeySpecified +#: Vcl/midconst.pas:65 +msgid "Unable to find record. No key specified" +msgstr "Ne peut trouver l'enregistrement. Aucune clé spécifiée" + +#. Programmer's name for it: SFieldNameTooLong +#: Vcl/midconst.pas:67 +msgid "Field name cannot be longer then %d characters. Try setting ObjectView to True on the dataset" +msgstr "Le nom de champ ne peut dépasser %d caractères. Essayez de définir ObjectView à True dans le dataset" + +#. Programmer's name for it: SNoDataSets +#: Vcl/midconst.pas:68 +msgid "Cannot resolve to dataset when using nested datasets or references" +msgstr "Ne peut résoudre vers un dataset lors de l'utilisation de datasets ou de références imbriqués" + +#. Programmer's name for it: SRecConstFail +#: Vcl/midconst.pas:69 +msgid "Preparation of record constraint failed with error \"%s\"" +msgstr "La préparation de contrainte d'enregistrement a échoué avec l'erreur %s" + +#. Programmer's name for it: SFieldConstFail +#: Vcl/midconst.pas:70 +msgid "Preparation of field constraint failed with error \"%s\"" +msgstr "La préparation de contrainte de champ a échoué avec l'erreur %s" + +#. Programmer's name for it: SDefExprFail +#: Vcl/midconst.pas:71 +msgid "Preparation of default expression failed with error \"%s\"" +msgstr "La préparation d'expression par défaut a échoué avec l'erreur %s" + +#. Programmer's name for it: SArrayElementError +#: Vcl/midconst.pas:72 +msgid "Array elements of type %s are not supported" +msgstr "Les éléments de tableau de type %s ne sont pas supportés" + +#. Programmer's name for it: SNoTableName +#: Vcl/midconst.pas:73 +msgid "Unable to resolve records. Table name not found." +msgstr "Ne peut résoudre les enregistrements. Nom de table non trouvé." + +#. Programmer's name for it: SNoEditsAllowed +#: Vcl/midconst.pas:74 +msgid "Modifications are not allowed" +msgstr "Modifications non autorisées" + +#. Programmer's name for it: SNoDeletesAllowed +#: Vcl/midconst.pas:75 +msgid "Deletes are not allowed" +msgstr "Suppressions non autorisées" + +#. Programmer's name for it: SNoInsertsAllowed +#: Vcl/midconst.pas:76 +msgid "Inserts are not allowed" +msgstr "Insertions non autorisées" + +#. Programmer's name for it: SCannotChangeCommandText +#: Vcl/midconst.pas:77 +msgid "CommandText changes are not allowed" +msgstr "Modifications CommandText non autorisées" + +#. Programmer's name for it: SNoServers +#: Vcl/midconst.pas:80 +msgid "No server available" +msgstr "Aucun serveur disponible" + +#. Programmer's name for it: SReturnError +#: Vcl/midconst.pas:83 +msgid "Expected return value not received" +msgstr "Valeur de retour attendue non reçue" + +#. Programmer's name for it: SNoWinSock2 +#: Vcl/midconst.pas:84 +msgid "WinSock 2 must be installed to use the socket connection" +msgstr "WinSock 2 doit être installé pour utiliser la connexion socket" + +#. Programmer's name for it: SURLRequired +#: Vcl/midconst.pas:87 +msgid "URL required" +msgstr "URL requis" + +#. Programmer's name for it: SDefaultURL +#: Vcl/midconst.pas:88 +msgid "http://server.company.com/scripts/httpsrvr.dll" +msgstr "http://server.company.com/scripts/httpsrvr.dll" + +#. Programmer's name for it: SInvalidURL +#: Vcl/midconst.pas:89 +msgid "URL must be in the form \"http://server.company.com/scripts/httpsrvr.dll\"" +msgstr "L'URL doit être de la forme \"http://server.company.com/scripts/httpsrvr.dll\"" + +#. Programmer's name for it: SServerIsBusy +#: Vcl/midconst.pas:90 +msgid "Server is busy" +msgstr "Le serveur est occupé" + +#. Programmer's name for it: SObjectNotAvailable +#: Vcl/midconst.pas:92 +msgid "Object not available: %s" +msgstr "Objet non disponible : %s" + +#. Programmer's name for it: SBadPropValue +#: Vcl/oleconst.pas:15 +msgid "'%s' is not a valid property value" +msgstr "'%s' n'est pas une valeur de propriété correcte" + +#. Programmer's name for it: SCannotActivate +#: Vcl/oleconst.pas:16 +msgid "OLE control activation failed" +msgstr "Echec de l'activation du contrôle OLE" + +#. Programmer's name for it: SNoWindowHandle +#: Vcl/oleconst.pas:17 +msgid "Could not obtain OLE control window handle" +msgstr "Impossible d'obtenir le handle de fenêtre du contrôle OLE" + +#. Programmer's name for it: SOleError +#: Vcl/oleconst.pas:18 +msgid "OLE error %.8x" +msgstr "Erreur OLE %.8x" + +#. Programmer's name for it: SVarNotObject +#: Vcl/oleconst.pas:19 +msgid "Variant does not reference an OLE object" +msgstr "Le variant ne référence pas un objet OLE" + +#. Programmer's name for it: SVarNotAutoObject +#. Programmer's name for it: SVarNotObject +#: Vcl/oleconst.pas:20 +msgid "Variant does not reference an automation object" +msgstr "Le variant ne référence pas un objet Automation" + +#. Programmer's name for it: SNoMethod +#: Vcl/oleconst.pas:21 +msgid "Method '%s' not supported by OLE object" +msgstr "Méthode '%s' non supportée par l'objet OLE" + +#. Programmer's name for it: SLinkProperties +#: Vcl/oleconst.pas:22 +msgid "Link Properties" +msgstr "Propriétés de liaison" + +#. Programmer's name for it: SInvalidLinkSource +#: Vcl/oleconst.pas:23 +msgid "Cannot link to an invalid source." +msgstr "Impossible de lier à une source incorrecte." + +#. Programmer's name for it: SCannotBreakLink +#: Vcl/oleconst.pas:24 +msgid "Break link operation is not supported." +msgstr "Opération interruption de liaison non supportée." + +#. Programmer's name for it: SLinkedObject +#: Vcl/oleconst.pas:25 +msgid "Linked %s" +msgstr "%s lié(e)" + +#. Programmer's name for it: SEmptyContainer +#: Vcl/oleconst.pas:26 +msgid "Operation not allowed on an empty OLE container" +msgstr "Opération non autorisée pour un conteneur OLE vide" + +#. Programmer's name for it: SInvalidVerb +#: Vcl/oleconst.pas:27 +msgid "Invalid object verb" +msgstr "Verbe d'objet incorrect" + +#. Programmer's name for it: SPropDlgCaption +#: Vcl/oleconst.pas:28 +msgid "%s Properties" +msgstr "Propriétés %s" + +#. Programmer's name for it: SInvalidLicense +#: Vcl/oleconst.pas:30 +msgid "License information for %s is invalid" +msgstr "Les informations de licence pour %s sont incorrectes" + +#. Programmer's name for it: SNotLicensed +#: Vcl/oleconst.pas:31 +msgid "License information for %s not found. You cannot use this control in design mode" +msgstr "Informations de licence pour %s non trouvées. Vous ne pouvez utiliser ce contrôle en mode conception" + +#. Programmer's name for it: sNoRunningObject +#: Vcl/oleconst.pas:32 +msgid "Unable to retrieve a pointer to a running object registered with OLE for %s/%s" +msgstr "Ne peut récupérer un pointeur sur un objet en cours d'exécution recensé avec OLE pour %s/%s" + +#. Programmer's name for it: SServiceOnly +#: Vcl/scktcnst.pas:29 +msgid "The Socket Server can only be run as a service on NT 3.51 and prior" +msgstr "Le serveur de Socket ne fonctionne en mode service que sur système NT 3.51 ou plus ancien." + +#. Programmer's name for it: SErrClose +#: Vcl/scktcnst.pas:30 +msgid "Cannot exit when there are active connections. Kill connections?" +msgstr "Arrêt impossible tant que des connexions sont établies. Stopper les connexions?" + +#. Programmer's name for it: SErrChangeSettings +#: Vcl/scktcnst.pas:31 +msgid "Cannot change settings when there are active connections. Kill connections?" +msgstr "Impossible de changer les paramètres tant que des connexions sont établies. Stopper les connexions?" + +#. Programmer's name for it: SQueryDisconnect +#: Vcl/scktcnst.pas:32 +msgid "Disconnecting clients can cause application errors. Continue?" +msgstr "Déconnecter un client peut provoquer des erreurs dans le programme. Voulez-vous continuer?" + +#. Programmer's name for it: SOpenError +#: Vcl/scktcnst.pas:33 +msgid "Error opening port %d with error: %s" +msgstr "Erreur à l'ouverture du port %d: %s" + +#. Programmer's name for it: SNotShown +#: Vcl/scktcnst.pas:35 +msgid "(Not Shown)" +msgstr "(invisible)" + +#. Programmer's name for it: SStatusline +#: Vcl/scktcnst.pas:37 +msgid "%d current connections" +msgstr "%d connexions actuellement" + +#. Programmer's name for it: SAlreadyRunning +#: Vcl/scktcnst.pas:38 +msgid "The Socket Server is already running" +msgstr "Le serveur de socket est déjà en fonction" + +#. Programmer's name for it: SNotUntilRestart +#: Vcl/scktcnst.pas:39 +msgid "This change will not take affect until the Socket Server is restarted" +msgstr "Ce changement ne serra effectif qu'après le redémarrage du serveur de Socket" + +#. Programmer's name for it: sInvalidActionRegistration +#: Vcl/webconst.pas:15 +msgid "Invalid Action registration" +msgstr "Enregistrement d'action incorrect" + +#. Programmer's name for it: sDuplicateActionName +#: Vcl/webconst.pas:16 +msgid "Duplicate action name" +msgstr "Nom d'action dupliqué" + +#. Programmer's name for it: sOnlyOneDispatcher +#: Vcl/webconst.pas:17 +msgid "Only one WebDispatcher per form/data module" +msgstr "Un seul WebDispatcher par fiche/module de données" + +#. Programmer's name for it: sHTTPItemName +#: Vcl/webconst.pas:18 +msgid "Name" +msgstr "Nom" + +#. Programmer's name for it: sHTTPItemURI +#: Vcl/webconst.pas:19 +msgid "PathInfo" +msgstr "Chemin" + +#. Programmer's name for it: sHTTPItemEnabled +#: Vcl/webconst.pas:20 +msgid "Enabled" +msgstr "Activé" + +#. Programmer's name for it: sHTTPItemProducer +#: Vcl/webconst.pas:22 +msgid "Producer" +msgstr "Producteur" + +#. Programmer's name for it: sTooManyColumns +#: Vcl/webconst.pas:26 +msgid "Too many table columns" +msgstr "Trop de colonnes de table" + +#. Programmer's name for it: sFieldNameColumn +#: Vcl/webconst.pas:27 +msgid "Field Name" +msgstr "Nom champ" + +#. Programmer's name for it: sFieldTypeColumn +#: Vcl/webconst.pas:28 +msgid "Field Type" +msgstr "Type champ" + +#. Programmer's name for it: SCorbaDllNotLoaded +#: Rtl/Corba/corbcnst.pas:15 +msgid "Unable to load CORBA libraries" +msgstr "Ne peut charger les bibliothèques CORBA" + +#. Programmer's name for it: SCorbaNotInitialized +#: Rtl/Corba/corbcnst.pas:16 +msgid "CORBA libraries are unavailable or not initialized" +msgstr "Les bibliothèques CORBA sont indisponibles ou non initialisées" + +#. Programmer's name for it: SCorbaSkeletonNotRegistered +#: Rtl/Corba/corbcnst.pas:17 +msgid "CORBA server skeleton not registered for object %s" +msgstr "Squelette de serveur CORBA non recensé pour l'objet %s" + +#. Programmer's name for it: SCorbaStubNotRegistered +#: Rtl/Corba/corbcnst.pas:18 +msgid "CORBA client stub not registered" +msgstr "Stub client CORBA non recensé" + +#. Programmer's name for it: SCorbaInterfaceIDNotRegister +#: Rtl/Corba/corbcnst.pas:19 +msgid "CORBA interface not registered" +msgstr "Interface CORBA non recensée" + +#. Programmer's name for it: SCorbaRepositoryIDNotRegistered +#: Rtl/Corba/corbcnst.pas:20 +msgid "CORBA Repository ID \"%s\" not registered" +msgstr "Id de référentiel CORBA \"%s\" non recensé" + +#. Programmer's name for it: SCorbaIncompleteFactory +#: Rtl/Corba/corbcnst.pas:21 +msgid "CORBA Factory did not implement CreateInterface" +msgstr "La fabrique CORBA n'a pas implémenté CreateInterface" + +#. Programmer's name for it: sInvalidTypeCast +#: Rtl/Corba/corbcnst.pas:24 +msgid "Variant cannot be converted to a CORBA Any" +msgstr "Le variant ne peut être converti en Any CORBA" + +#. Programmer's name for it: sNotCorbaObject +#: Rtl/Corba/corbcnst.pas:25 +msgid "Variant/Any not a CORBA object" +msgstr "Le Variant/Any n'est pas un objet CORBA" + +#. Programmer's name for it: sParamTypeCast +#: Rtl/Corba/corbcnst.pas:26 +msgid "Parameter (%d) of method %s not of the correct type" +msgstr "Le paramètre (%d) de la méthode %s n'est pas du type correct" + +#. Programmer's name for it: sParamOut +#: Rtl/Corba/corbcnst.pas:27 +msgid "Parameter (%d) of method %s is an out or in/out parameter and requires a variable reference" +msgstr "Le paramètre (%d) de la méthode %s est un paramètre sortie ou entrée/sortie et requiert une référence de variable" + +#. Programmer's name for it: sNoRepository +#: Rtl/Corba/corbcnst.pas:28 +msgid "Could not perform CORBA Dispatch, no interface repository found" +msgstr "Ne peut effectuer le Dispatch CORBA, aucun référentiel d'interface trouvé" + +#. Programmer's name for it: sInvalidParameterCount +#: Rtl/Corba/corbcnst.pas:29 +msgid "Incorrect number of parameters to method %s" +msgstr "Nombre de paramètres incorrect pour la méthode %s" + +#. Programmer's name for it: sMethodNotFound +#: Rtl/Corba/corbcnst.pas:30 +msgid "Method %s not found" +msgstr "Méthode %s non trouvée" + +#. Programmer's name for it: sConnecting +#: Rtl/Corba/corbcnst.pas:31 +msgid "Connecting to CORBA server..." +msgstr "Connexion au serveur CORBA..." + +#. Programmer's name for it: SCreateRegKeyError +#: Rtl/Sys/comconst.pas:15 +msgid "Error creating system registry entry" +msgstr "Erreur à la création de l'entrée de registre système" + +#. Programmer's name for it: SObjectFactoryMissing +#: Rtl/Sys/comconst.pas:17 +msgid "Object factory for class %s missing" +msgstr "Object factory manquant pour la classe %s" + +#. Programmer's name for it: STypeInfoMissing +#: Rtl/Sys/comconst.pas:18 +msgid "Type information missing for class %s" +msgstr "Information de type manquante pour la classe %s" + +#. Programmer's name for it: SBadTypeInfo +#: Rtl/Sys/comconst.pas:19 +msgid "Incorrect type information for class %s" +msgstr "Information de type incorrecte pour la classe %s" + +#. Programmer's name for it: SDispIntfMissing +#: Rtl/Sys/comconst.pas:20 +msgid "Dispatch interface missing from class %s" +msgstr "Interface dispatch manquante dans la classe %s" + +#. Programmer's name for it: SNoMethod +#: Rtl/Sys/comconst.pas:21 +msgid "Method '%s' not supported by automation object" +msgstr "Méthode '%s' non supportée par l'objet Automation" + +#. Programmer's name for it: SDCOMNotInstalled +#: Rtl/Sys/comconst.pas:23 +msgid "DCOM not installed" +msgstr "DCOM non installé" + +#. Programmer's name for it: SDAXError +#: Rtl/Sys/comconst.pas:24 +msgid "DAX Error" +msgstr "Erreur DAX" + +#. Programmer's name for it: SAutomationWarning +#: Rtl/Sys/comconst.pas:26 +msgid "COM Server Warning" +msgstr "Avertissement du serveur COM" + +#. Programmer's name for it: SNoCloseActiveServer1 +#: Rtl/Sys/comconst.pas:29 +msgid "There are still active COM objects in this application. One or more clients may have references to these objects, so manually closing " +msgstr "Il y a encore des serveurs COM actifs dans cette application. Un ou plusieurs clients ont peut-être des références à ces objets, donc la fermeture manuelle de " + +#. Programmer's name for it: SNoCloseActiveServer2 +#: Rtl/Sys/comconst.pas:32 +msgid "" +"this application may cause those client application(s) to fail.\n" +"\n" +"Are you sure you want to close this application?" +msgstr "" +"cette application peut provoquer des erreurs dans les clients.\n" +"\n" +"Etes-vous sûr de vouloir fermer cette application ?" + +#. Programmer's name for it: SUnknown +#: Rtl/Sys/sysconst.pas:15 +msgid "" +msgstr "" + +#. Programmer's name for it: SInvalidInteger +#: Rtl/Sys/sysconst.pas:16 +msgid "'%s' is not a valid integer value" +msgstr "'%s' n'est pas une valeur entière correcte" + +#. Programmer's name for it: SInvalidFloat +#: Rtl/Sys/sysconst.pas:17 +msgid "'%s' is not a valid floating point value" +msgstr "'%s' n'est pas une valeur en virgule flottante correcte" + +#. Programmer's name for it: SInvalidDate +#: Rtl/Sys/sysconst.pas:18 +msgid "'%s' is not a valid date" +msgstr "'%s' n'est pas une date correcte" + +#. Programmer's name for it: SInvalidTime +#: Rtl/Sys/sysconst.pas:19 +msgid "'%s' is not a valid time" +msgstr "'%s' n'est pas une heure correcte" + +#. Programmer's name for it: SInvalidDateTime +#: Rtl/Sys/sysconst.pas:20 +msgid "'%s' is not a valid date and time" +msgstr "'%s' n'est pas une date et heure correcte" + +#. Programmer's name for it: SOutOfMemory +#: Rtl/Sys/sysconst.pas:23 +msgid "Out of memory" +msgstr "Mémoire insuffisante" + +#. Programmer's name for it: SInOutError +#: Rtl/Sys/sysconst.pas:24 +msgid "I/O error %d" +msgstr "Erreur E/S %d" + +#. Programmer's name for it: SFileNotFound +#: Rtl/Sys/sysconst.pas:25 +msgid "File not found" +msgstr "Fichier introuvable" + +#. Programmer's name for it: SInvalidFilename +#: Rtl/Sys/sysconst.pas:26 +msgid "Invalid filename" +msgstr "Nom de fichier incorrect" + +#. Programmer's name for it: STooManyOpenFiles +#: Rtl/Sys/sysconst.pas:27 +msgid "Too many open files" +msgstr "Trop de fichiers ouverts" + +#. Programmer's name for it: SAccessDenied +#: Rtl/Sys/sysconst.pas:28 +msgid "File access denied" +msgstr "Accès au fichier refusé" + +#. Programmer's name for it: SEndOfFile +#: Rtl/Sys/sysconst.pas:29 +msgid "Read beyond end of file" +msgstr "Lecture au-delà de la fin de fichier" + +#. Programmer's name for it: SDiskFull +#: Rtl/Sys/sysconst.pas:30 +msgid "Disk full" +msgstr "Disque plein" + +#. Programmer's name for it: SInvalidInput +#: Rtl/Sys/sysconst.pas:31 +msgid "Invalid numeric input" +msgstr "Saisie numérique incorrecte" + +#. Programmer's name for it: SDivByZero +#: Rtl/Sys/sysconst.pas:32 +msgid "Division by zero" +msgstr "Division par zéro" + +#. Programmer's name for it: SRangeError +#: Rtl/Sys/sysconst.pas:33 +msgid "Range check error" +msgstr "Erreur de vérification d'étendue" + +#. Programmer's name for it: SIntOverflow +#: Rtl/Sys/sysconst.pas:34 +msgid "Integer overflow" +msgstr "Débordement d'entier" + +#. Programmer's name for it: SInvalidOp +#: Rtl/Sys/sysconst.pas:35 +msgid "Invalid floating point operation" +msgstr "Opération en virgule flottante incorrecte" + +#. Programmer's name for it: SZeroDivide +#: Rtl/Sys/sysconst.pas:36 +msgid "Floating point division by zero" +msgstr "Division par zéro en virgule flottante" + +#. Programmer's name for it: SOverflow +#: Rtl/Sys/sysconst.pas:37 +msgid "Floating point overflow" +msgstr "Débordement en virgule flottante" + +#. Programmer's name for it: SUnderflow +#: Rtl/Sys/sysconst.pas:38 +msgid "Floating point underflow" +msgstr "Débordement inférieur flottant" + +#. Programmer's name for it: SInvalidPointer +#: Rtl/Sys/sysconst.pas:39 +msgid "Invalid pointer operation" +msgstr "Opération de pointeur incorrecte" + +#. Programmer's name for it: SInvalidCast +#: Rtl/Sys/sysconst.pas:40 +msgid "Invalid class typecast" +msgstr "Transtypage de classe incorrect" + +#. Programmer's name for it: SAccessViolation +#: Rtl/Sys/sysconst.pas:41 +msgid "Access violation at address %p. %s of address %p" +msgstr "Violation d'accès à l'adresse %p. %s de l'adresse %p" + +#. Programmer's name for it: SStackOverflow +#: Rtl/Sys/sysconst.pas:42 +msgid "Stack overflow" +msgstr "Débordement de pile" + +#. Programmer's name for it: SControlC +#: Rtl/Sys/sysconst.pas:43 +msgid "Control-C hit" +msgstr "Frappe de Contrôle-C" + +#. Programmer's name for it: SPrivilege +#: Rtl/Sys/sysconst.pas:44 +msgid "Privileged instruction" +msgstr "Instruction privilégiée" + +#. Programmer's name for it: SOperationAborted +#: Rtl/Sys/sysconst.pas:45 +msgid "Operation aborted" +msgstr "Opération abandonnée" + +#. Programmer's name for it: SException +#: Rtl/Sys/sysconst.pas:46 +msgid "" +"Exception %s in module %s at %p.\n" +"%s%s" +msgstr "" +"Exception %s dans le module %s à %p.\n" +"%s%s" + +#. Programmer's name for it: SExceptTitle +#: Rtl/Sys/sysconst.pas:47 +msgid "Application Error" +msgstr "Erreur d'application" + +#. Programmer's name for it: SInvalidFormat +#: Rtl/Sys/sysconst.pas:48 +msgid "Format '%s' invalid or incompatible with argument" +msgstr "Le format '%s' est incorrect ou incompatible avec l'argument" + +#. Programmer's name for it: SArgumentMissing +#: Rtl/Sys/sysconst.pas:49 +msgid "No argument for format '%s'" +msgstr "Aucun argument pour le format '%s'" + +#. Programmer's name for it: SInvalidVarCast +#: Rtl/Sys/sysconst.pas:50 +msgid "Invalid variant type conversion" +msgstr "Conversion de type variant incorrecte" + +#. Programmer's name for it: SInvalidVarOp +#: Rtl/Sys/sysconst.pas:51 +msgid "Invalid variant operation" +msgstr "Opération de variant incorrecte" + +#. Programmer's name for it: SDispatchError +#: Rtl/Sys/sysconst.pas:52 +msgid "Variant method calls not supported" +msgstr "Appels de méthode variante non supportés" + +#. Programmer's name for it: SResultTooLong +#: Rtl/Sys/sysconst.pas:55 +msgid "Format result longer than 4096 characters" +msgstr "Résultat de format supérieur à 4096 caractères" + +#. Programmer's name for it: SFormatTooLong +#: Rtl/Sys/sysconst.pas:56 +msgid "Format string too long" +msgstr "Chaîne de format trop longue" + +#. Programmer's name for it: SVarArrayCreate +#: Rtl/Sys/sysconst.pas:57 +msgid "Error creating variant array" +msgstr "Erreur lors de la création de tableau de variants" + +#. Programmer's name for it: SVarNotArray +#: Rtl/Sys/sysconst.pas:58 +msgid "Variant is not an array" +msgstr "Le variant n'est pas un tableau" + +#. Programmer's name for it: SVarArrayBounds +#: Rtl/Sys/sysconst.pas:59 +msgid "Variant array index out of bounds" +msgstr "Indice de tableau de variants hors limites" + +#. Programmer's name for it: SExternalException +#: Rtl/Sys/sysconst.pas:60 +msgid "External exception %x" +msgstr "Exception externe %x" + +#. Programmer's name for it: SAssertionFailed +#: Rtl/Sys/sysconst.pas:61 +msgid "Assertion failed" +msgstr "Echec de l'assertion" + +#. Programmer's name for it: SIntfCastError +#: Rtl/Sys/sysconst.pas:62 +msgid "Interface not supported" +msgstr "Interface non supportée" + +#. Programmer's name for it: SSafecallException +#: Rtl/Sys/sysconst.pas:63 +msgid "Exception in safecall method" +msgstr "Exception dans méthode safecall" + +#. Programmer's name for it: SAssertError +#: Rtl/Sys/sysconst.pas:64 +msgid "%s (%s, line %d)" +msgstr "%s (%s, ligne %d)" + +#. Programmer's name for it: SAbstractError +#: Rtl/Sys/sysconst.pas:65 +msgid "Abstract Error" +msgstr "Erreur abstraite" + +#. Programmer's name for it: SModuleAccessViolation +#: Rtl/Sys/sysconst.pas:66 +msgid "Access violation at address %p in module '%s'. %s of address %p" +msgstr "Violation d'accès à l'adresse %p dans le module '%s'. %s de l'adresse %p" + +#. Programmer's name for it: SCannotReadPackageInfo +#: Rtl/Sys/sysconst.pas:67 +msgid "Cannot access package information for package '%s'" +msgstr "Impossible d'accéder à l'information de paquet pour le paquet '%s'" + +#. Programmer's name for it: sErrorLoadingPackage +#: Rtl/Sys/sysconst.pas:68 +msgid "" +"Can't load package %s.\n" +"%s" +msgstr "" +"Ne peut charger le paquet %s.\n" +"%s" + +#. Programmer's name for it: SInvalidPackageFile +#: Rtl/Sys/sysconst.pas:69 +msgid "Invalid package file '%s'" +msgstr "Fichier paquet incorrect '%s'" + +#. Programmer's name for it: SInvalidPackageHandle +#: Rtl/Sys/sysconst.pas:70 +msgid "Invalid package handle" +msgstr "Handle de paquet incorrect" + +#. Programmer's name for it: SDuplicatePackageUnit +#: Rtl/Sys/sysconst.pas:72 +msgid "Cannot load package '%s.' It contains unit '%s,';which is also contained in package '%s'" +msgstr "Ne peut charger le paquet '%s.' Il contient l'unité '%s', qui est également contenue dans le paquet '%s'" + +#. Programmer's name for it: SWin32Error +#: Rtl/Sys/sysconst.pas:73 +msgid "" +"Win32 Error. Code: %d.\n" +"%s" +msgstr "" +"Erreur Win32. Code : %d.\n" +"%s" + +#. Programmer's name for it: SUnkWin32Error +#: Rtl/Sys/sysconst.pas:74 +msgid "A Win32 API function failed" +msgstr "Une fonction de l'API Win32 a échoué" + +#. Programmer's name for it: SNL +#: Rtl/Sys/sysconst.pas:75 +msgid "Application is not licensed to use this feature" +msgstr "L'application n'a pas de licence pour cette fonctionnalité" + +#. Programmer's name for it: SShortMonthNameJan +#: Rtl/Sys/sysconst.pas:77 +msgid "Jan" +msgstr "Jan" + +#. Programmer's name for it: SShortMonthNameFeb +#: Rtl/Sys/sysconst.pas:78 +msgid "Feb" +msgstr "Fév" + +#. Programmer's name for it: SShortMonthNameMar +#: Rtl/Sys/sysconst.pas:79 +msgid "Mar" +msgstr "Mar" + +#. Programmer's name for it: SShortMonthNameApr +#: Rtl/Sys/sysconst.pas:80 +msgid "Apr" +msgstr "Avr" + +#. Programmer's name for it: SShortMonthNameMay +#. Programmer's name for it: SLongMonthNameMay +#: Rtl/Sys/sysconst.pas:81 +msgid "May" +msgstr "Mai" + +#. Programmer's name for it: SShortMonthNameJun +#: Rtl/Sys/sysconst.pas:82 +msgid "Jun" +msgstr "Jun" + +#. Programmer's name for it: SShortMonthNameJul +#: Rtl/Sys/sysconst.pas:83 +msgid "Jul" +msgstr "Jul" + +#. Programmer's name for it: SShortMonthNameAug +#: Rtl/Sys/sysconst.pas:84 +msgid "Aug" +msgstr "Aoû" + +#. Programmer's name for it: SShortMonthNameSep +#: Rtl/Sys/sysconst.pas:85 +msgid "Sep" +msgstr "Sep" + +#. Programmer's name for it: SShortMonthNameOct +#: Rtl/Sys/sysconst.pas:86 +msgid "Oct" +msgstr "Oct" + +#. Programmer's name for it: SShortMonthNameNov +#: Rtl/Sys/sysconst.pas:87 +msgid "Nov" +msgstr "Nov" + +#. Programmer's name for it: SShortMonthNameDec +#: Rtl/Sys/sysconst.pas:88 +msgid "Dec" +msgstr "Déc" + +#. Programmer's name for it: SLongMonthNameJan +#: Rtl/Sys/sysconst.pas:90 +msgid "January" +msgstr "Janvier" + +#. Programmer's name for it: SLongMonthNameFeb +#: Rtl/Sys/sysconst.pas:91 +msgid "February" +msgstr "Février" + +#. Programmer's name for it: SLongMonthNameMar +#: Rtl/Sys/sysconst.pas:92 +msgid "March" +msgstr "Mars" + +#. Programmer's name for it: SLongMonthNameApr +#: Rtl/Sys/sysconst.pas:93 +msgid "April" +msgstr "Avril" + +#. Programmer's name for it: SLongMonthNameJun +#: Rtl/Sys/sysconst.pas:95 +msgid "June" +msgstr "Juin" + +#. Programmer's name for it: SLongMonthNameJul +#: Rtl/Sys/sysconst.pas:96 +msgid "July" +msgstr "Juillet" + +#. Programmer's name for it: SLongMonthNameAug +#: Rtl/Sys/sysconst.pas:97 +msgid "August" +msgstr "Août" + +#. Programmer's name for it: SLongMonthNameSep +#: Rtl/Sys/sysconst.pas:98 +msgid "September" +msgstr "Septembre" + +#. Programmer's name for it: SLongMonthNameOct +#: Rtl/Sys/sysconst.pas:99 +msgid "October" +msgstr "Octobre" + +#. Programmer's name for it: SLongMonthNameNov +#: Rtl/Sys/sysconst.pas:100 +msgid "November" +msgstr "Novembre" + +#. Programmer's name for it: SLongMonthNameDec +#: Rtl/Sys/sysconst.pas:101 +msgid "December" +msgstr "Décembre" + +#. Programmer's name for it: SShortDayNameSun +#: Rtl/Sys/sysconst.pas:103 +msgid "Sun" +msgstr "Dim" + +#. Programmer's name for it: SShortDayNameMon +#: Rtl/Sys/sysconst.pas:104 +msgid "Mon" +msgstr "Lun" + +#. Programmer's name for it: SShortDayNameTue +#: Rtl/Sys/sysconst.pas:105 +msgid "Tue" +msgstr "Mar" + +#. Programmer's name for it: SShortDayNameWed +#: Rtl/Sys/sysconst.pas:106 +msgid "Wed" +msgstr "Mer" + +#. Programmer's name for it: SShortDayNameThu +#: Rtl/Sys/sysconst.pas:107 +msgid "Thu" +msgstr "Jeu" + +#. Programmer's name for it: SShortDayNameFri +#: Rtl/Sys/sysconst.pas:108 +msgid "Fri" +msgstr "Ven" + +#. Programmer's name for it: SShortDayNameSat +#: Rtl/Sys/sysconst.pas:109 +msgid "Sat" +msgstr "Sam" + +#. Programmer's name for it: SLongDayNameSun +#: Rtl/Sys/sysconst.pas:111 +msgid "Sunday" +msgstr "Dimanche" + +#. Programmer's name for it: SLongDayNameMon +#: Rtl/Sys/sysconst.pas:112 +msgid "Monday" +msgstr "Lundi" + +#. Programmer's name for it: SLongDayNameTue +#: Rtl/Sys/sysconst.pas:113 +msgid "Tuesday" +msgstr "Mardi" + +#. Programmer's name for it: SLongDayNameWed +#: Rtl/Sys/sysconst.pas:114 +msgid "Wednesday" +msgstr "Mercredi" + +#. Programmer's name for it: SLongDayNameThu +#: Rtl/Sys/sysconst.pas:115 +msgid "Thursday" +msgstr "Jeudi" + +#. Programmer's name for it: SLongDayNameFri +#: Rtl/Sys/sysconst.pas:116 +msgid "Friday" +msgstr "Vendredi" + +#. Programmer's name for it: SLongDayNameSat +#: Rtl/Sys/sysconst.pas:117 +msgid "Saturday" +msgstr "Samedi" + +#. Programmer's name: FONT 8 +#: Vcl/extdlgs.rc:14 +msgid "MS Sans Serif" +msgstr "MS Sans Serif" + +#. DSSCubeEditor..Caption +#: Decision Cube/mxdcube.dfm:6 +msgid "Decision Cube Editor" +msgstr "Editeur de cube de décision" + +#. DSSCubeEditor..Pager..DimensionInfo..Caption +#: Decision Cube/mxdcube.dfm:24 +msgid "Dimension Settings" +msgstr "Paramètres de dimensions" + +#. DSSCubeEditor..Pager..DimensionInfo..CaptionLabel..Caption +#: Decision Cube/mxdcube.dfm:31 +msgid "Display &Name" +msgstr "&Nom affiché :" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveLabel..Caption +#: Decision Cube/mxdcube.dfm:40 +msgid "&Active Type" +msgstr "Typ&e actif :" + +#. DSSCubeEditor..Pager..DimensionInfo..BinLabel..Caption +#: Decision Cube/mxdcube.dfm:49 +msgid "&Grouping" +msgstr "&Groupement :" + +#. DSSCubeEditor..Pager..DimensionInfo..StartLabel..Caption +#: Decision Cube/mxdcube.dfm:58 +msgid "&Initial Value" +msgstr "&Valeur initiale :" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeLabel..Caption +#: Decision Cube/mxdcube.dfm:67 +msgid "&Type" +msgstr "&Type :" + +#. DSSCubeEditor..Pager..DimensionInfo..Label1..Caption +#: Decision Cube/mxdcube.dfm:76 +msgid "Available &Fields" +msgstr "Champs &disponibles" + +#. DSSCubeEditor..Pager..DimensionInfo..Label2..Caption +#: Decision Cube/mxdcube.dfm:85 +msgid "For&mat" +msgstr "&Format :" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameLabel..Caption +#: Decision Cube/mxdcube.dfm:102 +msgid "&Base Field" +msgstr "&Champ de base :" + +#. DSSCubeEditor..Pager..DimensionInfo..CaptionEdit..Text +#: Decision Cube/mxdcube.dfm:122 +msgid "CaptionEdit" +msgstr "CaptionEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit..Hint +#: Decision Cube/mxdcube.dfm:130 +msgid "Control of when the information for this field is loaded" +msgstr "Contrôle quand l'information pour ce champ est chargée" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:136 +msgid "" +"Active\n" +"As Needed\n" +"Inactive\n" +msgstr "" +"actif\n" +"au besoin\n" +"inactif\n" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit..Text +#: Decision Cube/mxdcube.dfm:139 +msgid "ActiveEdit" +msgstr "ActiveEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit..Hint +#: Decision Cube/mxdcube.dfm:147 +msgid "Group values for this field into ranges" +msgstr "Grouper les valeurs de champ en étendues" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:155 +msgid "" +"None\n" +"Year\n" +"Quarter\n" +"Month\n" +"Single Value\n" +msgstr "" +"Aucun\n" +"Année\n" +"Trimestre\n" +"Mois\n" +"Valeur simple\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit..Text +#: Decision Cube/mxdcube.dfm:158 +msgid "BinEdit" +msgstr "BinEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:176 +msgid "" +"Dimension\n" +"Sum\n" +"Count\n" +"Average\n" +"Min\n" +"Max\n" +"GenericAgg\n" +"Unknown\n" +msgstr "" +"Dimension\n" +"Somme\n" +"Décompte\n" +"Moyenne\n" +"Minimum\n" +"Maximum\n" +"GenericAgg\n" +"Inconnu\n" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeEdit..Text +#: Decision Cube/mxdcube.dfm:179 +msgid "TypeEdit" +msgstr "TypeEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..FormatEdit..Text +#: Decision Cube/mxdcube.dfm:190 +msgid "FormatEdit" +msgstr "FormatEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..StartEdit....Height +#: Decision Cube/mxdcube.dfm:201 +msgid "Starting value for date ranges, Intial value for single valued dimensions\n" +msgstr "Valeur basse pour un intervalle de temps, valeur initiale pour une donnée unidimensionnelle\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameEdit....Height +#: Decision Cube/mxdcube.dfm:214 +msgid "Fieldname (for a summary, the original field used to calculate the summary)\n" +msgstr "Nom du champ (pour les calculs de somme, champ de base à utiliser)\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameEdit..Text +#: Decision Cube/mxdcube.dfm:217 +msgid "BaseNameEdit" +msgstr "BaseNameEdit" + +#. DSSCubeEditor..Pager..MemoryControl..Caption +#: Decision Cube/mxdcube.dfm:223 +msgid "Memory Control" +msgstr "Contrôle de la mémoire" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..Hint +#: Decision Cube/mxdcube.dfm:229 +msgid "Control whether to load the decision cube at design time" +msgstr "Contrôle si le cube de décision est chargé à la conception" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..Caption +#: Decision Cube/mxdcube.dfm:230 +msgid "Designer Data Options" +msgstr "Options de données du concepteur" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioMetaData..Caption +#: Decision Cube/mxdcube.dfm:239 +msgid "Display Dimension &Names" +msgstr "Afficher les &noms de dimensions" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioDimensionData..Caption +#: Decision Cube/mxdcube.dfm:250 +msgid "Display Names and &Values" +msgstr "Afficher les noms et les &valeurs" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioAllData..Caption +#: Decision Cube/mxdcube.dfm:259 +msgid "Display Names, Values, and &Totals" +msgstr "Afficher les noms, valeurs et &totaux" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioNoData..Caption +#: Decision Cube/mxdcube.dfm:268 +msgid "&Run Time Display Only" +msgstr "Affichage à l'e&xécution seulement" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Caption +#: Decision Cube/mxdcube.dfm:278 +msgid "Cube Maximums" +msgstr "Capacités du cube" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label4..Caption +#: Decision Cube/mxdcube.dfm:304 +msgid "Active" +msgstr "Actif" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label7..Caption +#: Decision Cube/mxdcube.dfm:312 +msgid "Active+Needed" +msgstr "Actif+Nécessaire" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label9..Caption +#: Decision Cube/mxdcube.dfm:320 +msgid "&Dimensions" +msgstr "&Dimensions" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label6..Caption +#: Decision Cube/mxdcube.dfm:348 +msgid "&Summaries" +msgstr "&Récapitulatifs" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label12..Caption +#: Decision Cube/mxdcube.dfm:358 +msgid "&Cells" +msgstr "&Cellules" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label5..Caption +#: Decision Cube/mxdcube.dfm:376 +msgid "Maximum" +msgstr "Maximum" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label3..Caption +#: Decision Cube/mxdcube.dfm:384 +msgid "Current" +msgstr "En cours" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxDims....Height +#: Decision Cube/mxdcube.dfm:421 +msgid "Limit on the number of dimensions which can be loaded at one time\n" +msgstr "Limite du nombre de dimensions pouvant être chargés en une seule fois\n" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxSums..Hint +#: Decision Cube/mxdcube.dfm:430 +msgid "Limit on the number of summaries which can be loaded at one time" +msgstr "Limite du nombre récapitulatifs pouvant être chargés en une seule fois" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxCells....Height +#: Decision Cube/mxdcube.dfm:443 +msgid "Limit on the number of storage cells which can be loaded at one time\n" +msgstr "Limite du nombre de cellules de sauvegarde pouvant être chargés en une seule fois\n" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..GetCellCounts..Hint +#: Decision Cube/mxdcube.dfm:452 +msgid "Run a query to fetch information required to estimate cell usage" +msgstr "Lancer une requête pour obtenir les informations requises pour estimer l'utilisation des cellules" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..GetCellCounts..Caption +#: Decision Cube/mxdcube.dfm:453 +msgid "&Get Cell Counts" +msgstr "&Obtenir nb. de cellules" + +#. DimEditor..Caption +#. FieldsEditor..Caption +#: Decision Cube/mxdesign.dfm:6 +#: Editors/dsdesign.dfm:8 +msgid "Form1.Table1" +msgstr "Form1.Table1" + +#. SQLWindow..Caption +#: Decision Cube/mxdsql.dfm:6 +msgid "Form2" +msgstr "Form2" + +#. SQLWindow..Memo1....Lines.Strings +#: Decision Cube/mxdsql.dfm:32 +msgid "Memo1\n" +msgstr "Memo1\n" + +#. DSSQueryEditor..Caption +#: Decision Cube/mxdssqry.dfm:6 +msgid "Decision Query Editor" +msgstr "Editeur de requête de décision" + +#. DSSQueryEditor..Pager..Dimensions..Caption +#: Decision Cube/mxdssqry.dfm:23 +msgid "Dimensions/Summaries" +msgstr "Dimensions / récapitulatifs" + +#. DSSQueryEditor..Pager..Dimensions..Label2..Caption +#: Decision Cube/mxdssqry.dfm:30 +msgid "&Dimensions:" +msgstr "&Dimensions :" + +#. DSSQueryEditor..Pager..Dimensions..Label3..Caption +#: Decision Cube/mxdssqry.dfm:39 +msgid "&Summaries:" +msgstr "&Récapitulatifs :" + +#. DSSQueryEditor..Pager..Dimensions..Label4..Caption +#: Decision Cube/mxdssqry.dfm:48 +msgid "&List of Available Fields:" +msgstr "&Liste des champs disponibles :" + +#. DSSQueryEditor..Pager..Dimensions..Label5..Caption +#: Decision Cube/mxdssqry.dfm:57 +msgid "&Table:" +msgstr "&Table :" + +#. DSSQueryEditor..Pager..Dimensions..Label6..Caption +#: Decision Cube/mxdssqry.dfm:66 +msgid "Databas&e:" +msgstr "Ba&se :" + +#. DSSQueryEditor..Pager..Dimensions..Label7..Caption +#. CollectionEditor..ActionList1..AddCmd..Caption +#. LinkFields..AddButton..Caption +#. SocketForm..MainMenu1..miPorts..miAdd..Caption +#: Decision Cube/mxdssqry.dfm:76 +#: Editors/fldlinks.dfm:114 +#: Vcl/scktmain.dfm:345 +msgid "&Add" +msgstr "Aj&outer" + +#. DSSQueryEditor..Pager..Dimensions..SelectAllFields..Hint +#: Decision Cube/mxdssqry.dfm:129 +msgid "List all fields or List only the fields in the query" +msgstr "Afficher tous les champs ou seulement ceux de la requête" + +#. DSSQueryEditor..Pager..Dimensions..SelectAllFields..Caption +#: Decision Cube/mxdssqry.dfm:130 +msgid "All &Fields" +msgstr "T&ous les champs" + +#. DSSQueryEditor..Pager..Dimensions..TableCombo..Hint +#: Decision Cube/mxdssqry.dfm:141 +msgid "Start a new query using a table from the database" +msgstr "Lancer une nouvelle requête sur une table de la base de données" + +#. DSSQueryEditor..Pager..Dimensions..CountStarAvg..Hint +#: Decision Cube/mxdssqry.dfm:251 +msgid "Use count(*) to calculate averages (counts null values)" +msgstr "Utiliser count(*) pour calculer les moyennes (compte les valeurs nulles)" + +#. DSSQueryEditor..Pager..Dimensions..CountStarAvg..Caption +#: Decision Cube/mxdssqry.dfm:252 +msgid "Count (*) for Averages" +msgstr "Compter (*) pour moyennes" + +#. DSSQueryEditor..Pager..Query..Caption +#: Decision Cube/mxdssqry.dfm:261 +msgid "SQL Query" +msgstr "Requête SQL" + +#. DSSQueryEditor..Pager..Query..Label1..Caption +#: Decision Cube/mxdssqry.dfm:268 +msgid "&Query Text:" +msgstr "&Texte de requête :" + +#. DSSQueryEditor..Pager..Query..CancelQryMod..Caption +#: Decision Cube/mxdssqry.dfm:287 +msgid "&Cancel Edit" +msgstr "A&nnuler les modifications" + +#. DSSQueryEditor..Pager..Query..EditQry..Hint +#: Decision Cube/mxdssqry.dfm:296 +msgid "Type in the query directly" +msgstr "Saisir la requête directement" + +#. DSSQueryEditor..VQB..Hint +#: Decision Cube/mxdssqry.dfm:340 +msgid "Add/Join Tables and Create Field List with SQL Builder" +msgstr "Ajouter/fusionner les tables et créer la liste de champs avec SQL Builder" + +#. DSSQueryEditor..VQB..Caption +#: Decision Cube/mxdssqry.dfm:341 +msgid "SQL &Builder ..." +msgstr "&Constructeur SQL ..." + +#. DSSQueryEditor..AggPopup..count1..Caption +#: Decision Cube/mxdssqry.dfm:351 +msgid "&sum" +msgstr "&Somme" + +#. DSSQueryEditor..AggPopup..count2..Caption +#: Decision Cube/mxdssqry.dfm:355 +msgid "&count" +msgstr "&Nombre" + +#. DSSQueryEditor..AggPopup..average1..Caption +#: Decision Cube/mxdssqry.dfm:359 +msgid "&average" +msgstr "&Moyenne" + +#. ProgressDialog..Caption +#: Decision Cube/mxpbar.dfm:6 +msgid "ProgressDialog" +msgstr "Progression" + +#. ProgressDialog..CancelButton..Caption +#. DataBindForm..CancelBtn..Caption +#: Decision Cube/mxpbar.dfm:29 +msgid "&Cancel" +msgstr "&Annuler" + +#. ProgressDialog..StatusText..Caption +#: Decision Cube/mxpbar.dfm:40 +msgid "StatusText" +msgstr "StatusText" + +#. ConnEditForm..SourceofConnection..Caption +#: Property Editors/adoconed.dfm:49 +msgid " Source of Connection " +msgstr " Source de connexion " + +#. ConnEditForm..SourceofConnection..UseDataLinkFile..Caption +#: Property Editors/adoconed.dfm:57 +msgid "Use Data &Link File" +msgstr "Utiliser le &Fichier de Liaison de Données" + +#. ConnEditForm..SourceofConnection..Browse..Caption +#: Property Editors/adoconed.dfm:77 +msgid "&Browse..." +msgstr "&Parcourir..." + +#. ConnEditForm..SourceofConnection..UseConnectionString..Caption +#: Property Editors/adoconed.dfm:87 +msgid "Use &Connection String" +msgstr "Utiliser la chaîne de conne&xion" + +#. ConnEditForm..SourceofConnection..Build..Caption +#: Property Editors/adoconed.dfm:105 +msgid "B&uild..." +msgstr "&Construire..." + +#. ClientDataForm..Caption +#: Property Editors/cdsedit.dfm:6 +msgid "Client DataSet Data" +msgstr "Données DataSet client" + +#. ClientDataForm..GroupBox1..Caption +#: Property Editors/cdsedit.dfm:19 +msgid " Assign Data From " +msgstr " Affecter les données depuis" + +#. CollectionEditor..Caption +#: Property Editors/colnedit.dfm:10 +msgid "CollectionEditor" +msgstr "EditeurCollection" + +#. CollectionEditor..ToolBar1..ToolButton3..Caption +#: Property Editors/colnedit.dfm:41 +msgid "ToolButton3" +msgstr "ToolButton3" + +#. CollectionEditor..PopupMenu1..N2..Caption +#. FieldsEditor..LocalMenu..N1..Caption +#. SocketForm..PopupMenu..N1..Caption +#. SocketForm..MainMenu1..miPorts..N3..Caption +#. SocketForm..MainMenu1..Connections1..N2..Caption +#: Property Editors/colnedit.dfm:183 +#: Vcl/scktmain.dfm:324 +#: Vcl/scktmain.dfm:352 +#: Vcl/scktmain.dfm:368 +msgid "-" +msgstr "-" + +#. CollectionEditor..ActionList1..AddCmd..Hint +#: Property Editors/colnedit.dfm:190 +msgid "Add New" +msgstr "Ajouter un nouveau" + +#. CollectionEditor..ActionList1..DeleteCmd..Caption +#. DataBindForm..Panel1..DeleteBtn..Caption +#. FieldsEditor..LocalMenu..DeleteItem..Caption +#. LinkFields..DeleteButton..Caption +#. IndexFiles..GroupBox1..Delete..Caption +#: Property Editors/colnedit.dfm:196 +#: Editors/dsdesign.dfm:157 +#: Editors/fldlinks.dfm:123 +#: Editors/ixedit.dfm:43 +msgid "&Delete" +msgstr "S&upprimer" + +#. CollectionEditor..ActionList1..DeleteCmd..Hint +#: Property Editors/colnedit.dfm:198 +msgid "Delete Selected" +msgstr "Supprimer sélectionnés" + +#. CollectionEditor..ActionList1..MoveUpCmd..Caption +#: Property Editors/colnedit.dfm:205 +msgid "Move &Up" +msgstr "Vers le &haut" + +#. CollectionEditor..ActionList1..MoveUpCmd..Hint +#: Property Editors/colnedit.dfm:207 +msgid "Move Selected Up" +msgstr "Déplacer la sélection vers le haut" + +#. CollectionEditor..ActionList1..MoveDownCmd..Caption +#: Property Editors/colnedit.dfm:214 +msgid "Move Dow&n" +msgstr "Vers le &bas" + +#. CollectionEditor..ActionList1..MoveDownCmd..Hint +#: Property Editors/colnedit.dfm:216 +msgid "Move Selected Down" +msgstr "Déplacer la sélection vers le bas" + +#. CollectionEditor..ActionList1..SelectAllCmd..Caption +#. UpdateSQLEditForm..FieldListPopup..miSelectAll..Caption +#: Property Editors/colnedit.dfm:223 +msgid "&Select All" +msgstr "Tout &sélectionner" + +#. DBEditForm..GroupBox1..Caption +#: Property Editors/dbedit.dfm:18 +msgid " Database " +msgstr " Base de données" + +#. DBEditForm..GroupBox1..Label1..Caption +#: Property Editors/dbedit.dfm:25 +msgid "&Alias name:" +msgstr "Nom d'a&lias :" + +#. DBEditForm..GroupBox1..Label2..Caption +#: Property Editors/dbedit.dfm:33 +msgid "&Driver name:" +msgstr "Nom de &pilote :" + +#. DBEditForm..GroupBox1..Label3..Caption +#: Property Editors/dbedit.dfm:41 +msgid "&Parameter overrides:" +msgstr "&Remplacements paramètres :" + +#. DBEditForm..GroupBox1..Label4..Caption +#. DefineField..FieldGroup..FieldNameLabel..Caption +#: Property Editors/dbedit.dfm:49 +msgid "&Name:" +msgstr "&Nom :" + +#. DBEditForm..GroupBox1..DefaultsButton..Caption +#: Property Editors/dbedit.dfm:90 +msgid "D&efaults" +msgstr "&Défaut" + +#. DBEditForm..GroupBox1..ClearButton..Caption +#. LinkFields..ClearButton..Caption +#. IndexFiles..GroupBox1..Clear..Caption +#. PictureEditorDlg..GroupBox1..Clear..Caption +#: Property Editors/dbedit.dfm:99 +#: Editors/ixedit.dfm:53 +#: Editors/picedit.dfm:94 +msgid "&Clear" +msgstr "&Effacer" + +#. DBEditForm..GroupBox3..Caption +#: Property Editors/dbedit.dfm:116 +msgid " Options " +msgstr " Options " + +#. DBEditForm..GroupBox3..LoginPrompt..Caption +#: Property Editors/dbedit.dfm:123 +msgid "&Login prompt" +msgstr "In&vite de connexion" + +#. DBEditForm..GroupBox3..KeepConnection..Caption +#: Property Editors/dbedit.dfm:131 +msgid "&Keep inactive connection" +msgstr "&Conserver connexion inactive" + +#. InputReqDialog..Caption +#: Property Editors/dbinpreq.dfm:6 +msgid "Input Requested" +msgstr "Saisie requise" + +#. InputReqDialog..OKButton..Caption +#. LoginDialog..OKButton..Caption +#. DataBindForm..OkBtn..Caption +#. SQLEditForm..ButtonPanel..OkButton..Caption +#. StrEditDlg..OKButton..Caption +#. UpdateSQLEditForm..OkButton..Caption +#: Property Editors/dbinpreq.dfm:18 +#: Editors/dboleedt.dfm:109 +#: Editors/sqledit.dfm:94 +#: Editors/stredit.dfm:55 +#: Editors/updsqled.dfm:20 +msgid "&OK" +msgstr "&OK" + +#. InputReqDialog..NoPromptAgain..Caption +#: Property Editors/dbinpreq.dfm:48 +msgid "Don't Prompt Again" +msgstr "Ne plus demander" + +#. LoginDialog..Caption +#: Property Editors/dblogdlg.dfm:6 +msgid "Database Login" +msgstr "Connexion base de données" + +#. LoginDialog..Panel..Label3..Caption +#: Property Editors/dblogdlg.dfm:47 +msgid "Database:" +msgstr "Base de données :" + +#. LoginDialog..Panel..Panel1..Label1..Caption +#: Property Editors/dblogdlg.dfm:75 +msgid "&User Name:" +msgstr "&Utilisateur :" + +#. LoginDialog..Panel..Panel1..Label2..Caption +#: Property Editors/dblogdlg.dfm:83 +msgid "&Password:" +msgstr "&Mot de passe :" + +#. LoginDialog..Panel..Panel1..Password..PasswordChar +#: Property Editors/dblogdlg.dfm:100 +msgid "*" +msgstr "*" + +#. DataBindForm..Caption +#: Property Editors/dboleedt.dfm:6 +msgid "ActiveX Control Data Bindings Editor" +msgstr "Editeur de liaisons de données de contrôle ActiveX" + +#. DataBindForm..Panel1..Label1..Caption +#: Property Editors/dboleedt.dfm:29 +msgid "&Property Name:" +msgstr "&Nom de propriété :" + +#. DataBindForm..Panel1..Label2..Caption +#: Property Editors/dboleedt.dfm:37 +msgid "&Field Name:" +msgstr "&Nom de champ :" + +#. DataBindForm..Panel1..Label3..Caption +#: Property Editors/dboleedt.dfm:45 +msgid "Bo&und Properties to Fields:" +msgstr "&Propriétés liées aux champs :" + +#. DataBindForm..Panel1..BindBtn..Caption +#: Property Editors/dboleedt.dfm:73 +msgid "<- &Bind ->" +msgstr "<- &Lier ->" + +#. DataBindForm..Panel1..ClearBtn..Caption +#: Property Editors/dboleedt.dfm:99 +msgid "C&lear" +msgstr "&Effacer" + +#. AddFields..Caption +#: Property Editors/dsadd.dfm:6 +msgid "Add Fields" +msgstr "Ajout de champs" + +#. AddFields..GroupBox1..Caption +#: Property Editors/dsadd.dfm:46 +msgid "Available fields" +msgstr "Champs disponibles" + +#. AssociateAttributes..Caption +#: Property Editors/dsattra.dfm:5 +msgid "Associate attributes" +msgstr "Association d'attributs" + +#. AssociateAttributes..GroupBox1..Caption +#: Property Editors/dsattra.dfm:51 +msgid "Attribute set name" +msgstr "Nom ensemble d'attributs" + +#. SaveAttributesAs..Caption +#: Property Editors/dsattrs.dfm:5 +msgid "Save %s attributes as" +msgstr "Enregistrer attributs %s sous" + +#. SaveAttributesAs..Label1..Caption +#: Property Editors/dsattrs.dfm:25 +msgid "&Attribute set name:" +msgstr "&Nom d'ensemble d'attributs :" + +#. SaveAttributesAs..Label2..Caption +#: Property Editors/dsattrs.dfm:33 +msgid "&Based on:" +msgstr "&Basé sur :" + +#. DefineField..Caption +#: Property Editors/dsdefine.dfm:5 +msgid "New Field" +msgstr "Nouveau champ" + +#. DefineField..LookupGroup..Caption +#: Property Editors/dsdefine.dfm:18 +msgid "Lookup definition" +msgstr "Définition de la référence" + +#. DefineField..LookupGroup..DatasetLabel..Caption +#: Property Editors/dsdefine.dfm:25 +msgid "D&ataset:" +msgstr "&Dataset :" + +#. DefineField..LookupGroup..KeyFieldsLabel..Caption +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label3..Caption +#: Property Editors/dsdefine.dfm:34 +msgid "&Key Fields:" +msgstr "Champs c&lé :" + +#. DefineField..LookupGroup..LookupKeysLabel..Caption +#: Property Editors/dsdefine.dfm:43 +msgid "Look&up Keys:" +msgstr "Clés de ré&férence :" + +#. DefineField..LookupGroup..ResultFieldLabel..Caption +#: Property Editors/dsdefine.dfm:52 +msgid "&Result Field:" +msgstr "Champ rés&ultat :" + +#. DefineField..FieldGroup..Caption +#: Property Editors/dsdefine.dfm:133 +msgid "Field properties" +msgstr "Propriétés du champ" + +#. DefineField..FieldGroup..ComponentNameLabel..Caption +#: Property Editors/dsdefine.dfm:140 +msgid "C&omponent:" +msgstr "Com&posant :" + +#. DefineField..FieldGroup..FieldTypeLabel..Caption +#: Property Editors/dsdefine.dfm:156 +msgid "&Type:" +msgstr "T&ype :" + +#. DefineField..FieldGroup..SizeEditLabel..Caption +#: Property Editors/dsdefine.dfm:164 +msgid "&Size:" +msgstr "&Taille :" + +#. DefineField..FieldKind..Caption +#: Property Editors/dsdefine.dfm:206 +msgid "Field type" +msgstr "Type de champ" + +#. DefineField..FieldKind....Items.Strings +#: Property Editors/dsdefine.dfm:213 +msgid "" +"&Data\n" +"&Calculated\n" +"&Lookup\n" +msgstr "" +"&Donnée\n" +"&Calcul\n" +"&Lookup\n" + +#. FieldsEditor..FieldListBox..Hint +#: Property Editors/dsdesign.dfm:81 +msgid "Fields" +msgstr "Champs" + +#. FieldsEditor..AggListBox..Hint +#: Property Editors/dsdesign.dfm:99 +msgid "Aggregates" +msgstr "Globaux" + +#. FieldsEditor..LocalMenu..AddItem..Caption +#: Property Editors/dsdesign.dfm:119 +msgid "&Add fields..." +msgstr "&Ajouter des champs..." + +#. FieldsEditor..LocalMenu..NewItem..Caption +#: Property Editors/dsdesign.dfm:125 +msgid "&New field..." +msgstr "&Nouveau champ..." + +#. FieldsEditor..LocalMenu..Addallfields1..Caption +#: Property Editors/dsdesign.dfm:131 +msgid "Add all &fields" +msgstr "Ajouter tous les c&hamps" + +#. FieldsEditor..LocalMenu..CutItem..Caption +#: Property Editors/dsdesign.dfm:139 +msgid "Cu&t" +msgstr "&Couper" + +#. FieldsEditor..LocalMenu..CopyItem..Caption +#: Property Editors/dsdesign.dfm:145 +msgid "&Copy" +msgstr "&Copier" + +#. FieldsEditor..LocalMenu..PasteItem..Caption +#: Property Editors/dsdesign.dfm:151 +msgid "&Paste" +msgstr "C&oller" + +#. FieldsEditor..LocalMenu..SelectAllItem..Caption +#: Property Editors/dsdesign.dfm:163 +msgid "Se&lect all" +msgstr "&Tout sélectionner" + +#. LinkFields..Caption +#: Property Editors/fldlinks.dfm:6 +msgid "Field Link Designer" +msgstr "Concepteur de liaison de champs" + +#. LinkFields..Label30..Caption +#: Property Editors/fldlinks.dfm:35 +msgid "D&etail Fields" +msgstr "Champs &détail" + +#. LinkFields..Label31..Caption +#: Property Editors/fldlinks.dfm:44 +msgid "&Master Fields" +msgstr "Champs &maître" + +#. LinkFields..IndexLabel..Caption +#: Property Editors/fldlinks.dfm:53 +msgid "A&vailable Indexes" +msgstr "&Index disponibles :" + +#. LinkFields..Label2..Caption +#: Property Editors/fldlinks.dfm:61 +msgid "&Joined Fields" +msgstr "&Champs joints" + +#. IndexFiles..Caption +#. IndexFiles..GroupBox1..Caption +#: Property Editors/ixedit.dfm:5 +msgid "Index Files" +msgstr "Fichiers index" + +#. IndexFiles..GroupBox1..Add..Caption +#: Property Editors/ixedit.dfm:34 +msgid "&Add..." +msgstr "Aj&outer..." + +#. IndexFiles..OpenDialog....OnClick +#: Property Editors/ixedit.dfm:92 +msgid "dBASE Multiple Index (*.MDX)|*.mdx|dBase Index (*.NDX)|*.ndx|FoxPro Index (*.CDX)|*.cdx\n" +msgstr "dBASE Multiple Index (*.MDX)|*.mdx|dBase Index (*.NDX)|*.ndx|FoxPro Index (*.CDX)|*.cdx\n" + +#. PictureEditorDlg..Caption +#: Property Editors/picedit.dfm:6 +msgid "Picture Editor" +msgstr "Editeur d'images" + +#. PictureEditorDlg..GroupBox1..Load..Caption +#. StrEditDlg..StringEditorMenu..LoadItem..Caption +#: Property Editors/picedit.dfm:76 +msgid "&Load..." +msgstr "&Charger..." + +#. PictureEditorDlg..GroupBox1..Save..Caption +#. StrEditDlg..StringEditorMenu..SaveItem..Caption +#: Property Editors/picedit.dfm:85 +msgid "&Save..." +msgstr "Enregi&strer..." + +#. PictureEditorDlg..OpenDialog....OnClick +#. PictureEditorDlg..SaveDialog....Top +#: Property Editors/picedit.dfm:104 +msgid "All (*.bmp;*.ico;*.emf;*.wmf)|*.bmp;*.ico;*.emf;*.wmf|Bitmaps (*.bmp)|*.bmp|Icons (*.ico)|*.ico|Enhanced Metafiles (*.emf)|*.emf|Metafiles (*.wmf)|*.wmf\n" +msgstr "Tous les fichiers (*.bmp;*.ico;*.emf;*.wmf)|*.bmp;*.ico;*.emf;*.wmf|Bitmaps (*.bmp)|*.bmp|Icons (*.ico)|*.ico|Enhanced Metafiles (*.emf)|*.emf|Metafiles (*.wmf)|*.wmf\n" + +#. SQLEditForm..Caption +#: Property Editors/sqledit.dfm:5 +msgid "CommandText Editor" +msgstr "Editeur de CommandText" + +#. SQLEditForm..TopPanel..TableListLabel..Caption +#: Property Editors/sqledit.dfm:52 +msgid "&Tables:" +msgstr "&Tables :" + +#. SQLEditForm..TopPanel..SQLLabel..Caption +#: Property Editors/sqledit.dfm:60 +msgid "&SQL:" +msgstr "&SQL :" + +#. SQLEditForm..MetaInfoPanel..TableListPanel..AddTableButton..Caption +#: Property Editors/sqledit.dfm:165 +msgid "Add T&able to SQL" +msgstr "Ajouter la ta&ble à SQL" + +#. SQLEditForm..MetaInfoPanel..FieldsPanel..FieldListLabel..Caption +#: Property Editors/sqledit.dfm:183 +msgid "&Fields:" +msgstr "&Champs :" + +#. SQLEditForm..MetaInfoPanel..FieldsPanel..AddFieldButton..Caption +#: Property Editors/sqledit.dfm:203 +msgid "Add F&ield to SQL" +msgstr "Ajouter le c&hamp à SQL" + +#. StrEditDlg..Caption +#: Property Editors/stredit.dfm:5 +msgid "String List editor" +msgstr "Editeur de liste de chaînes" + +#. StrEditDlg..LineCount..Caption +#: Property Editors/stredit.dfm:29 +msgid "0 lines" +msgstr "0 lignes" + +#. StrEditDlg..CodeWndBtn..Caption +#. StrEditDlg..StringEditorMenu..CodeEditorItem..Caption +#: Property Editors/stredit.dfm:36 +msgid "&Code Editor..." +msgstr "Editeur de &code..." + +#. StrEditDlg..OpenDialog..DefaultExt +#: Property Editors/stredit.dfm:84 +msgid "TXT" +msgstr "TXT" + +#. StrEditDlg..OpenDialog....DefaultExt +#. StrEditDlg..SaveDialog....Left +#: Property Editors/stredit.dfm:88 +msgid "Text files (*.TXT)|*.TXT|Config files (*.SYS;*.INI)|*.SYS;*.INI|Batch files (*.BAT)|*.BAT|All files (*.*)|*.*\n" +msgstr "Fichiers textes (*.TXT)|*.TXT|Fichiers de configuration (*.SYS;*.INI)|*.SYS;*.INI|Fichiers Batch (*.BAT)|*.BAT|Tous les fichiers (*.*)|*.*\n" + +#. StrEditDlg..OpenDialog..Title +#: Property Editors/stredit.dfm:89 +msgid "Load string list" +msgstr "Charger la liste de chaînes" + +#. StrEditDlg..SaveDialog..Title +#: Property Editors/stredit.dfm:97 +msgid "Save string list" +msgstr "Enregistrer la liste de chaînes" + +#. UpdateSQLEditForm..PageControl..FieldsPage..Caption +#: Property Editors/updsqled.dfm:54 +msgid "Options" +msgstr "Options" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Caption +#: Property Editors/updsqled.dfm:60 +msgid " SQL Generation " +msgstr " Génération SQL" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label1..Caption +#: Property Editors/updsqled.dfm:67 +msgid "Table &Name:" +msgstr "&Nom de table :" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label4..Caption +#: Property Editors/updsqled.dfm:83 +msgid "Update &Fields:" +msgstr "C&hamps mise à jour :" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..GenerateButton..Caption +#: Property Editors/updsqled.dfm:123 +msgid "&Generate SQL" +msgstr "&Générer SQL" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..PrimaryKeyButton..Caption +#: Property Editors/updsqled.dfm:132 +msgid "Select &Primary Keys" +msgstr "&Sélectionner clés primaires" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..DefaultButton..Caption +#: Property Editors/updsqled.dfm:141 +msgid "&Dataset Defaults" +msgstr "&Défaut pour DataSet" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..QuoteFields..Caption +#: Property Editors/updsqled.dfm:151 +msgid "&Quote Field Names" +msgstr "Noms de champs &entre guillemets" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..GetTableFieldsButton..Caption +#: Property Editors/updsqled.dfm:160 +msgid "Get &Table Fields" +msgstr "O&btenir les champs" + +#. UpdateSQLEditForm..PageControl..SQLPage..Caption +#: Property Editors/updsqled.dfm:167 +msgid "SQL" +msgstr "SQL" + +#. UpdateSQLEditForm..PageControl..SQLPage..Label2..Caption +#: Property Editors/updsqled.dfm:173 +msgid "S&QL Text:" +msgstr "Texte S&QL :" + +#. UpdateSQLEditForm..PageControl..SQLPage..StatementType..Caption +#: Property Editors/updsqled.dfm:190 +msgid "Statement Type" +msgstr "Type d'instruction" + +#. UpdateSQLEditForm..PageControl..SQLPage..StatementType....Items.Strings +#: Property Editors/updsqled.dfm:197 +msgid "" +"&Modify\n" +"&Insert\n" +"&Delete\n" +msgstr "" +"&Modifier\n" +"&Insérer\n" +"&Effacer\n" + +#. UpdateSQLEditForm..FieldListPopup..miClearAll..Caption +#: Property Editors/updsqled.dfm:214 +msgid "&Clear All" +msgstr "Tout &effacer" + +#. HTTPServer......Name +#: Vcl/httpintr.dfm:6 +msgid "Interpreter" +msgstr "interpréteur" + +#. SocketForm..Caption +#: Vcl/scktmain.dfm:6 +msgid "Borland Socket Server" +msgstr "Borland Socket Server" + +#. SocketForm..Pages..PropPage..PortGroup..Caption +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#. SocketForm..Panel1..HeaderControl1......Text +#: Vcl/scktmain.dfm:38 +msgid "Port" +msgstr "Port" + +#. SocketForm..Pages..PropPage..PortGroup..Label1..Caption +#: Vcl/scktmain.dfm:46 +msgid "&Listen on Port:" +msgstr "à &l'écoute du port:" + +#. SocketForm..Pages..PropPage..PortGroup..PortDesc....AutoSize +#: Vcl/scktmain.dfm:60 +msgid "Many values of Port are associated by convention with a particular service such as ftp or http. Port is the ID of the connection on which the server listens for client requests. \n" +msgstr "Beaucoup de numéros de port sont associés par défaut avec des services tels que FTP ou HTTP. Le numéro de port est l'identifiant de connexion assigné à un serveur de service donné, réagissant aux demandes issues de processus client.\n" + +#. SocketForm..Pages..PropPage..ThreadGroup..Caption +#: Vcl/scktmain.dfm:92 +msgid "Thread Caching" +msgstr "Cache de Thread" + +#. SocketForm..Pages..PropPage..ThreadGroup..Label4..Caption +#: Vcl/scktmain.dfm:100 +msgid "&Thread Cache Size:" +msgstr "Taille du cache de &Thread:" + +#. SocketForm..Pages..PropPage..ThreadGroup..ThreadDesc....AutoSize +#: Vcl/scktmain.dfm:113 +msgid "Thread Cache Size is the maximum number of threads that can be reused for new client connections.\n" +msgstr "La taille du cache de Thread est le nombre maximum de Threads réutilisables pour traiter de nouvelles connextions des processus clients.\n" + +#. SocketForm..Pages..PropPage..InterceptGroup..Caption +#: Vcl/scktmain.dfm:145 +msgid "Intercept GUID" +msgstr "GUID d'interception" + +#. SocketForm..Pages..PropPage..InterceptGroup..Label5..Caption +#: Vcl/scktmain.dfm:152 +msgid "&GUID:" +msgstr "&GUID:" + +#. SocketForm..Pages..PropPage..InterceptGroup..GUIDDesc....AutoSize +#: Vcl/scktmain.dfm:164 +msgid "Intercept GUID is the GUID for a data interceptor COM object. See help for the TSocketConnection for details.\n" +msgstr "Une GUID d'interception est la GUID d'un objet COM d'interception de données. Voir l'aide en ligne pour les détails.\n" + +#. SocketForm..Pages..PropPage..TimeoutGroup..Caption +#: Vcl/scktmain.dfm:180 +msgid "Timeout" +msgstr "dépassement de temps" + +#. SocketForm..Pages..PropPage..TimeoutGroup..Label7..Caption +#: Vcl/scktmain.dfm:188 +msgid "&Inactive Timeout:" +msgstr "Désact&iver le dépassement de temps" + +#. SocketForm..Pages..PropPage..TimeoutGroup..TimeoutDesc....AutoSize +#: Vcl/scktmain.dfm:201 +msgid "Inactive Timeout specifes the number of minutes a client can be inactive before being disconnected. (0 indicates infinite)\n" +msgstr "Le temps de dépassement correspond à la durée d'inactivité d'un client, en minutes, après laquelle celui-ci sera déconnecté automatiquement (0 pour une durée infinie)\n" + +#. SocketForm..Pages..StatPage..Caption +#: Vcl/scktmain.dfm:239 +msgid "Users" +msgstr "Utilisateurs" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:252 +msgid "IP Address" +msgstr "Adresse IP" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:256 +msgid "Host" +msgstr "Host" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:260 +msgid "Last Activity" +msgstr "Dernière action" + +#. SocketForm..PopupMenu..miProperties..Caption +#: Vcl/scktmain.dfm:327 +msgid "&Properties" +msgstr "&Propriétés" + +#. SocketForm..MainMenu1..miPorts..Caption +#: Vcl/scktmain.dfm:343 +msgid "&Ports" +msgstr "&Ports" + +#. SocketForm..MainMenu1..miPorts..miExit..Caption +#: Vcl/scktmain.dfm:355 +msgid "&Exit" +msgstr "%Sortir" + +#. SocketForm..MainMenu1..Connections1..Caption +#: Vcl/scktmain.dfm:360 +msgid "&Connections" +msgstr "&connexion" + +#. SocketForm..ActionList1..ApplyAction..Caption +#: Vcl/scktmain.dfm:379 +msgid "&Apply" +msgstr "Appli&quer" + +#. SocketForm..ActionList1..DisconnectAction..Caption +#: Vcl/scktmain.dfm:384 +msgid "&Disconnect" +msgstr "&Déconnecter" + +#. SocketForm..ActionList1..ShowHostAction..Caption +#: Vcl/scktmain.dfm:389 +msgid "&Show Host Name" +msgstr "&Afficher les noms des Host" + +#. SocketForm..ActionList1..RemovePortAction..Caption +#: Vcl/scktmain.dfm:394 +msgid "&Remove" +msgstr "&Supprimer" + +#. SocketForm..ActionList1..RegisteredAction..Caption +#: Vcl/scktmain.dfm:399 +msgid "&Registered Objects Only" +msgstr "Uniquement les objets &recensés" + diff --git a/win32/gui-2/locale/fr/LC_MESSAGES/gpsbabel.po b/win32/gui-2/locale/fr/LC_MESSAGES/gpsbabel.po new file mode 100644 index 000000000..0ef174067 --- /dev/null +++ b/win32/gui-2/locale/fr/LC_MESSAGES/gpsbabel.po @@ -0,0 +1,497 @@ +msgid "" +msgstr "" +"Project-Id-Version: GPSBabel command line program\n" +"POT-Creation-Date: 2005-11-19 01:14\n" +"PO-Revision-Date: 2008-04-26 23:12+0100\n" +"Last-Translator: Lilian \n" +"Language-Team: Lilian Morinon \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Midnight Commander\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: FRANCE\n" + +msgid "(integer sec or 'auto') Barograph to GPS time diff" +msgstr "(entier sec ou 'auto') Barograph de différence temporelle GPS" + +msgid "(USR input) Break segments into separate tracks" +msgstr "(entrée USR) Séparer les segment en plusieurs traces" + +msgid "(USR output) Merge into one segmented track" +msgstr "(sortie USR) Fusionner en une trace segmentée" + +msgid "Ad-hoc closed icon name" +msgstr "Nom de l'icône pour Ad-hoc fermé" + +msgid "Ad-hoc open icon name" +msgstr "Nom de l'icône pour Ad-hoc ouvert" + +msgid "After output job done sleep n second(s)" +msgstr "Faire une pause de n secondes lorsque l'éxécution est terminée" + +msgid "Allow whitespace synth. shortnames" +msgstr "Autoriser les espaces dans les noms courts" + +msgid "Altitudes are absolute and not clamped to ground" +msgstr "Les altitudes sont absolue et idépendantes du sol" + +msgid "Append icon_descr to description" +msgstr "Ajouter icon_descr à la description" + +msgid "Append realtime positioning data to the output file instead of truncating" +msgstr "Ajoute les données de position en temps réel au fichier de sortie plutôt que de le tronquer" + +msgid "Base URL for link tag in output" +msgstr "URL de base pour l'étiquette de lien en sortie" + +msgid "Basename prepended to URL on output" +msgstr "Nom de base à utiliser pour l'URL de sortie" + +msgid "Bitmap of categories" +msgstr "Cartographie des catégories" + +msgid "Category name (Cache)" +msgstr "Nom de la catégorie" + +msgid "Category number to use for written waypoints" +msgstr "Numéro de catégorie pour les balises écrites" + +msgid "Color for lines or mapnotes" +msgstr "Couleur des lignes ou des notes" + +msgid "Command unit to power itself down" +msgstr "Ordonner au GPS de s'éteindre" + +msgid "Complete date-free tracks with given date (YYYYMMDD)." +msgstr "Ajouter une date donnée (AAAAMMJJ) à une trace sans horodatage" + +msgid "Create unique waypoint names (default = yes)" +msgstr "Créer des noms de balises uniques (oui par défaut)" + +msgid "Create waypoints from geocache log entries" +msgstr "Créer des balises à partir des entrés de log géocache" + +msgid "Database name" +msgstr "Nom de la base de données" + +msgid "Database name (filename)" +msgstr "Nom de la base de données (nom de fichier)" + +msgid "Datum (default=NAD27)" +msgstr "Datum (défaut=NAD27)" + +msgid "Days after which points are considered old" +msgstr "Nombre de jours après lesquels les points sont considérés comme anciens" + +msgid "Decimal seconds to pause between groups of strings" +msgstr "Dixième de seconde de pause entre les groups de chaines" + +msgid "Default category on output" +msgstr "Catégorie par défaut en sortie" + +msgid "Default category on output (1..16)" +msgstr "Catégorie par défaut en sortie (1..16)" + +msgid "Default icon name" +msgstr "Nom d'icone par défaut" + +msgid "Default location" +msgstr "Endroit par défaut" + +msgid "Default proximity" +msgstr "Proximité par défaut" + +msgid "Default speed" +msgstr "Vitesse par défaut" + +msgid "Default speed for waypoints (knots/hr)" +msgstr "Vitesse par défaut pour les balises (noeuds par heures)" + +msgid "Degrees output as 'ddd', 'dmm'(default) or 'dms'" +msgstr "Ecrire les dégrés en 'd°d°d°', 'd°m'm''(défaut) ou 'd°m's'''" + +msgid "Delete all routes" +msgstr "Supprimer toutes les routes" + +msgid "Delete all track points" +msgstr "Supprimer tous les points de traces" + +msgid "Delete all waypoints" +msgstr "Supprimer toutes les balises" + +msgid "Display labels on track and routepoints (default = 1)" +msgstr "Afficher les labels sur les traces et les points de routes (défaut = 1)" + +msgid "Distance unit [m=metric, s=statute]" +msgstr "Unité de distance [m = métrique, s=stature]" + +msgid "Do not add geocache data to description" +msgstr "Ne pas ajouter d'inforamtion de geocache à la description" + +msgid "Do not add URLs to description" +msgstr "Ne pas ajouter les URLs aux descriptions" + +msgid "Don't show gpi bitmap on device" +msgstr "Ne pas afficher les images gpi sur le périphérique" + +msgid "Draw extrusion line from trackpoint to ground" +msgstr "Générer une ligne d'extrusion entre le sol et le point de trace" + +msgid "Drop route points that do not have an equivalent waypoint (hidden points)" +msgstr "Eliminer les points de route qui n'ont pas de balises équivallentes (points cachés)" + +msgid "Enable alerts on speed or proximity distance" +msgstr "Activer les alertes de vitesse ou de proximité" + +msgid "Encrypt hints using ROT13" +msgstr "Encrypter les signes en ROT13" + +msgid "Encrypt hints with ROT13" +msgstr "Encrypter les signes avec ROT13" + +msgid "Erase device data after download" +msgstr "Effacer les données du périphérique après téléchargement" + +msgid "Export linestrings for tracks and routes" +msgstr "Exporter les chaînes de caractères pour les traces et les routes" + +msgid "Export placemarks for tracks and routes" +msgstr "Exporter les marqueurs pour les traces et les routes" + +msgid "Full path to XCSV style file" +msgstr "Chemin complet du fichier de modèle de XCSV" + +msgid "Generate # points" +msgstr "Générer # points" + +msgid "Generate file with lat/lon for centering map" +msgstr "Générer le fichier avec les infos de centrage de carte (lat/lon)" + +msgid "Give points (waypoints/route points) a default radius (proximity)" +msgstr "Donner un rayon de proximité par défaut aux points (balises/points de route)" + +msgid "GPS datum (def. WGS 84)" +msgstr "" + +msgid "Height in pixels of map" +msgstr "Hauteur de la carte en pixels" + +msgid "Ignore event marker icons on read" +msgstr "Ignorer les marqueurs d'événements lors de la lecture" + +msgid "Include extended data for trackpoints (default = 1)" +msgstr "Inclure les données étendues pour les points de trace (défaut = 1)" + +msgid "Include groundspeak logs if present" +msgstr "Inclure les logs groundspeak si disponible" + +msgid "Include major turn points (with description) from calculated route" +msgstr "Inclure les points de virage (avec description) de la route calculée" + +msgid "Include only via stations in route" +msgstr "Inclure seulement les étapes dans la route" + +msgid "Include short name in bookmarks" +msgstr "Inclure les noms courts dans les signets" + +msgid "Index of name field in .dbf" +msgstr "Index du champ nom dans le .dbf" + +msgid "Index of route (if more the one in source)" +msgstr "Index des routes (si plus d'une dans la source)" + +msgid "Index of route to write (if more the one in source)" +msgstr "Index des routes à écrire (si plusieurs sources)" + +msgid "Index of route/track to write (if more the one in source)" +msgstr "Index des routes/traces à écrire (si plusieurs sources)" + +msgid "Index of track (if more the one in source)" +msgstr "Index des traces (si plus d'une dans la source)" + +msgid "Index of track to write (if more the one in source)" +msgstr "Index des traces à écrire (si plusieurs sources)" + +msgid "Index of URL field in .dbf" +msgstr "Index du champ URL dans le .dbf" + +msgid "Indicate direction of travel in track icons (default = 0)" +msgstr "Indiquer la direction de déplacement dans les icones de la trace (défaut = 0)" + +msgid "Infrastructure closed icon name" +msgstr "Nom de l'icône pour l'Infrastructure fermée" + +msgid "Infrastructure open icon name" +msgstr "Nom de l'icône pour l'Infrastructure ouverte" + +msgid "Keep turns if simplify filter is used" +msgstr "Garder les virages si le filtre simplifié est utilisé" + +msgid "Length of generated shortnames" +msgstr "Longueur des nom courts générés" + +msgid "Length of generated shortnames (default 16)" +msgstr "Longueur des nom courts générés (défaut : 16)" + +msgid "Line color, specified in hex AABBGGRR" +msgstr "Couleur de la ligne, spécifié en hexadécimal AABBGGRR" + +msgid "Make synth. shortnames unique" +msgstr "Les noms courts sont tous différents" + +msgid "MapSend version TRK file to generate (3,4)" +msgstr "Version des fichiers TRK Mapsend à générer (3,4)" + +msgid "Margin for map. Degrees or percentage" +msgstr "Marge de la carte. Degrés ou pourcentage" + +msgid "Marker type for new points" +msgstr "Type de marqueur pour les nouveaux points" + +msgid "Marker type for old points" +msgstr "Type de marqueur pour les anciens points" + +msgid "Marker type for unfound points" +msgstr "Type de marqueur pour les points non trouvés" + +msgid "Max length of waypoint name to write" +msgstr "Longueur maximum du nom de la balise" + +msgid "Max number of comments to write (maxcmts=200)" +msgstr "Nombre maximum de commentaires à écrire (maxcmts=200)" + +msgid "Max shortname length when used with -s" +msgstr "Longueur maximum du nom court lorsque utilisé avec l'option -s" + +msgid "Max synthesized shortname length" +msgstr "Longueur max. de noms courts générés" + +msgid "Merge output with existing file" +msgstr "Fusionner la sortie avec un fichier existant" + +msgid "MTK compatible CSV output file" +msgstr "Fichier de sortie CSV compatible MTK" + +msgid "Name of the 'unassigned' category" +msgstr "Nom de la catégorie 'non assignée'" + +msgid "New name for the route" +msgstr "Nouveau nom pour la route" + +msgid "No separator lines between waypoints" +msgstr "Supprimer les lignes de séparation entre les balises" + +msgid "No whitespace in generated shortnames" +msgstr "Supprimer les espaces dans les noms courts générés" + +msgid "Non-stealth encrypted icon name" +msgstr "Ne pas récupérer les noms d'icones encryptés" + +msgid "Non-stealth non-encrypted icon name" +msgstr "Ne pas récupérer les noms d'icones non encryptés" + +msgid "Numeric value of bitrate (baud=4800)" +msgstr "Valeur numérique de la vitesse de transfert (4800 bauds)" + +msgid "Omit Placer name" +msgstr "Omettre le nom du Placer" + +msgid "Only read turns; skip all other points" +msgstr "Lire seulement les virages; ne pas tenire compte des autres points" + +msgid "Path to HTML style sheet" +msgstr "Chemin vers une feuille de style HTML" + +msgid "Precision of coordinates" +msgstr "Précision des coordonnées" + +msgid "Proximity distance" +msgstr "Distance de proximité" + +msgid "Radius for circles" +msgstr "Rayon des cercles" + +msgid "Radius of our big earth (default 6371000 meters)" +msgstr "Rayon de la terre (défaut : 6371000 mètres)" + +msgid "Read control points as waypoint/route/none" +msgstr "Lire les points de contrôle en temps à la balise/route/rien" + +msgid "Read/Write date format (i.e. DDMMYYYY)" +msgstr "Lire/Ecrire le format date (i.e. JJMMYYYY)" + +msgid "Read/Write date format (i.e. yyyy/mm/dd)" +msgstr "Lire/Ecrire le format de date (i.e. YYYY/MM/DD)" + +msgid "Read/write GPGGA sentences" +msgstr "Lire/Ecrire des séquences GPGGA" + +msgid "Read/write GPGSA sentences" +msgstr "Lire/Ecrire des séquences GPGSA" + +msgid "Read/write GPRMC sentences" +msgstr "Lire/Ecrire des séquences GPRMC " + +msgid "Read/write GPVTG sentences" +msgstr "Lire/ECrire des séquences GPVTG" + +msgid "Read/Write time format (i.e. HH:mm:ss xx)" +msgstr "Lire/Ecrire le format horaire (i.e. HH:mm:ss xx)" + +msgid "Retain at most this number of position points (0 = unlimited)" +msgstr "Retenir au maximum ce nombre de points de positions (0 = illimité)" + +msgid "Return current position as a waypoint" +msgstr "Renvoyer la position courante en tant que balise" + +msgid "Road type changes" +msgstr "Changement de type de route" + +msgid "Set waypoint name to source filename." +msgstr "Faire correspondre les nom de la balise au nom du fichier source." + +msgid "Shortname is MAC address" +msgstr "Le nom court est l'adresse MAC" + +msgid "Speed in bits per second of serial port (baud=4800)" +msgstr "Vitesse du port série en bits par seconde (baud=4800)" + +msgid "Split input into separate files" +msgstr "Découper l'entrée en fichiers séparés" + +msgid "Split into multiple routes at turns" +msgstr "Séparer en plusieurs routes à chaque virage" + +msgid "Starting seed of the internal number generator" +msgstr "Racine du générateur de nombres internes" + +msgid "Stealth encrypted icon name" +msgstr "Récupérer les noms d'icones encryptés" + +msgid "Stealth non-encrypted icon name" +msgstr "Récupérer les noms d'icones non encryptés" + +msgid "String to separate concatenated address fields (default=\", \")" +msgstr "Chaine de caractère pour séparer les champs d'adresse (\", \" par défaut)" + +msgid "Suppress labels on generated pins" +msgstr "Supprimer les labels des points créés" + +msgid "Suppress retired geocaches" +msgstr "Suypprimer les géocaches désactivées" + +msgid "Suppress separator lines between waypoints" +msgstr "Supprimer les lignes séparatrices entre les balises" + +msgid "Suppress use of handshaking in name of speed" +msgstr "Supprimer les controles pour améliorer les performances" + +msgid "Suppress whitespace in generated shortnames" +msgstr "Supprimer les espaces dans les noms courts générés" + +msgid "Symbol to use for point data" +msgstr "Symbole à utiliser pour les données de type point" + +msgid "Sync GPS time to computer time" +msgstr "Synchroniser l'heure du GPS avec l'heure du PC" + +msgid "Synthesize track times" +msgstr "Simplifier l'horodatage des traces" + +msgid "Target GPX version for output" +msgstr "Version du fichier GPX pour la sortie" + +msgid "Temperature unit [c=Celsius, f=Fahrenheit]" +msgstr "Unité de température (c=Celsius, f=Farenheit)" + +msgid "The icon description is already the marker" +msgstr "Les description de l'icon est identique au marqueur" + +msgid "Treat waypoints as icons on write" +msgstr "Traiter les balises comme des icônes à l'écriture" + +msgid "Type of .an1 file" +msgstr "Type de fichier .an1" + +msgid "Units for altitude (f)eet or (m)etres" +msgstr "Unités d'altitude (p)ieds ou (m)ètres" + +msgid "Units used for names with @speed ('s'tatute or 'm'etric)" +msgstr "Unités utilisées avec @vitess ('s'tatute ou 'm'étrique)" + +msgid "Units used when writing comments ('s'tatute or 'm'etric)" +msgstr "Unités utilisée lors de l'écriture de commentiares ('s'tatute ou 'm'étrique)" + +msgid "UPPERCASE synth. shortnames" +msgstr "Noms courts en MAJUSCULE" + +msgid "Use depth values on output (default is ignore)" +msgstr "Utiliser les valeurs de profondeur sur la sortie (par défaut : ignorer)" + +msgid "Use proximity values on output (default is ignore)" +msgstr "Utiliser les valeurs de proximité sur la sortie (par défaut : ignorer)" + +msgid "Use shortname instead of description" +msgstr "Utiliser le nom court au lieu de la description" + +msgid "Use specified bitmap on output" +msgstr "Utiliser l'images spécifiée en sortie" + +msgid "Version of gdb file to generate (1..3)" +msgstr "Version du fichier gbd à générer (1..3)" + +msgid "Version of mapsource file to generate (3,4,5)" +msgstr "Version du fichier mapsource à créer (3,4,5)" + +msgid "Waypoint background color" +msgstr "Couleur de fond de la balise" + +msgid "Waypoint foreground color" +msgstr "Couleur de la balise" + +msgid "Waypoint type" +msgstr "Type de balise" + +msgid "Width in pixels of map" +msgstr "Largeur de la carte en pixels" + +msgid "Width of lines, in pixels" +msgstr "Largeur des lignes en pixels" + +msgid "Write additional node tag key/value pairs" +msgstr "Ecrire des étiquettes de noeuds additionnelles clé/valeurs" + +msgid "Write additional way tag key/value pairs" +msgstr "Ecrire des étiquettes de chemins additionnelles clé/valeurs" + +msgid "Write all tracks into one file" +msgstr "Ecrire toutes les traces dans un fichier" + +msgid "Write description to address field" +msgstr "Ecrire la description dans le champ d'adresse" + +msgid "Write each waypoint in a separate file" +msgstr "Ecrire chaque balise dans un fichier séparé" + +msgid "Write notes to address field" +msgstr "Ecrire les notes dans le champ d'adresse" + +msgid "Write position to address field" +msgstr "Ecrire la position dans le champ d'adresse" + +msgid "Write position using this grid." +msgstr "Ecrire la position en utilisant cette grille." + +msgid "Write timestamps with offset x to UTC time" +msgstr "Ecrire l'horodatage avec un décalage de x par rapport à l'heure UTC" + +msgid "Write tracks compatible with Carto Exploreur" +msgstr "Ecrire des traces compatibles avec CartoExploreur" + +msgid "Write tracks for Gisteq Phototracker" +msgstr "Ecrire les traces pour Gisteq Phototracker" + +msgid "Zoom level to reduce points" +msgstr "Niveau de zoom pour réduire les points" + diff --git a/win32/gui-2/locale/hu/LC_MESSAGES/default.po b/win32/gui-2/locale/hu/LC_MESSAGES/default.po new file mode 100644 index 000000000..0adf5c3b4 --- /dev/null +++ b/win32/gui-2/locale/hu/LC_MESSAGES/default.po @@ -0,0 +1,930 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: GPSBabel Hungarian translation 0.1\n" +"POT-Creation-Date: 2005-12-06 17:57\n" +"PO-Revision-Date: 2007-06-07 02:37+0100\n" +"Last-Translator: Sprok Bence \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2.1\n" +"Language-Team: Sprok Bence \n" +"X-Poedit-Language: Hungarian\n" +"X-Poedit-Country: HUNGARY\n" + +#. frmAbout..Caption +#: about.dfm:5 +msgid "About" +msgstr "Névjegy" + +#. frmAbout..pnClient..pnCenter..lbHint1..Caption +#: about.dfm:76 +msgid "This program is part of the GPSBabel project, hosted on" +msgstr "Ez a program a GPSBabel Projekt része, letölthető:" + +#. frmAbout..pnClient..pnCenter..lbVersion..Caption +#: about.dfm:84 +#: about.pas:80 +msgid "Version" +msgstr "Verziószám" + +#. frmAbout..pnClient..pnCenter..lbTranslators..Caption +#: about.dfm:91 +msgid "Translations" +msgstr "Fordítások" + +#. frmAbout..pnClient..pnCenter..lbURL..Caption +#: about.dfm:98 +msgid "www.gpsbabel.org" +msgstr "www.gpsbabel.org" + +#. frmAbout..pnClient..pnCenter..lbCopyRight..Caption +#: about.dfm:114 +msgid "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" +msgstr "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" + +#. frmAbout..pnClient..pnCenter..lbMoreInfo..Caption +#: about.dfm:121 +msgid "Find more info at" +msgstr "További információ:" + +#. frmAbout..pnClient..pnCenter..stDescription..Caption +#: about.dfm:149 +msgid "The frontend for GPSBabel command line program" +msgstr "Grafikus felület a GPSbabel programhoz" + +#. frmAbout..pnClient..pnCenter..stLicense..Caption +#: about.dfm:163 +msgid "THIS SOFTWARE MAY ONLY BE LICENSED FREE OF CHARGE" +msgstr "EZ A SZOFTVER INGYENES, KERESKEDELMI ÁRUSÍTÁSA TILOS!" + +#. frmAbout..pnClient..pnCenter..btnNewLanguage..Caption +#: about.dfm:192 +msgid "Adding a new language" +msgstr "Új nyelv hozzáadása" + +#. frmFilter..Caption +#: filter.dfm:6 +msgid "Filter" +msgstr "Szűrő" + +#. frmFilter..gbTracks..Caption +#. frmMain..pnBottom..cbTracks..Caption +#: filter.dfm:31 +#: main.dfm:581 +msgid "&Tracks" +msgstr "Nyomvonalak" + +# It doesn't make sense to use 'by' in the hungarian language. This simply can be taken out. +#. frmFilter..gbTracks..lbTimePlusMinus..Caption +#: filter.dfm:39 +#: about.pas:87 +#: about.pas:88 +#: about.pas:89 +#: about.pas:90 +msgid "by" +msgstr " " + +#. frmFilter..gbTracks..lbTimeDays..Caption +#: filter.dfm:46 +msgid "day(s), " +msgstr "nappal" + +#. frmFilter..gbTracks..lbTimeHours..Caption +#: filter.dfm:53 +msgid "hour(s), " +msgstr "órával" + +#. frmFilter..gbTracks..lbTimeMinutes..Caption +#: filter.dfm:60 +msgid "minute(s)," +msgstr "perccel" + +#. frmFilter..gbTracks..lbTimeSeconds..Caption +#: filter.dfm:67 +msgid "second(s)" +msgstr "másodperccel" + +#. frmFilter..gbTracks..cbTrackTitle..Hint +#: filter.dfm:74 +msgid "Title for new tracks" +msgstr "Az új nyomvonal címe" + +#. frmFilter..gbTracks..cbTrackTitle..Caption +#: filter.dfm:76 +msgid "Tit&le" +msgstr "Cím" + +#. frmFilter..gbTracks..cbTrackSplit..Hint +#: filter.dfm:95 +msgid "Split track into several tracks depending on date of trackpoint" +msgstr "Nyomvonalak szétvágása dátum alapján" + +#. frmFilter..gbTracks..cbTrackSplit..Caption +#: filter.dfm:96 +msgid "&Split" +msgstr "Szétvágás" + +#. frmFilter..gbTracks..cbTrackTime..Hint +#: filter.dfm:104 +msgid "Shift all tracks" +msgstr "Az összes nyomvonal időbeli eltolása" + +#. frmFilter..gbTracks..cbTrackTime..Caption +#: filter.dfm:105 +msgid "&Move" +msgstr "Eltolás" + +#. frmFilter..gbTracks..cbTrackStart..Hint +#: filter.dfm:197 +msgid "Take only trackpoints starting at" +msgstr "Csak ettől az időponttól jelentkező nyomvonalpontok meghagyása" + +#. frmFilter..gbTracks..cbTrackStart..Caption +#: filter.dfm:198 +msgid "Start at" +msgstr "Vágás (-tól)" + +#. frmFilter..gbTracks..cbTrackStop..Caption +#: filter.dfm:237 +msgid "stop at" +msgstr "-ig" + +#. frmFilter..gbTracks..cbTrackPack..Hint +#: filter.dfm:276 +msgid "Pack all tracks into one track (No duplicate timestamps)" +msgstr "Csomagolj össze minden nyomvonalat egybe (nincs időazonosság)" + +#. frmFilter..gbTracks..cbTrackPack..Caption +#: filter.dfm:277 +msgid "&Pack (or)" +msgstr "Csomag (vagy)" + +#. frmFilter..gbTracks..cbTrackMerge..Hint +#: filter.dfm:286 +msgid "Merge all tracks into one track" +msgstr "Fűzz össze minden nyomvonalat egybe" + +#. frmFilter..gbTracks..cbTrackMerge..Caption +#: filter.dfm:287 +msgid "Merge" +msgstr "Fűzés" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Hint +#: filter.dfm:296 +msgid "Shift start/stop by local timezone offset" +msgstr "A -tól -ig helyi időzóna eltolással" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Caption +#: filter.dfm:297 +msgid "TZ" +msgstr "IZ" + +#. frmFilter..gbTracks..cbGPSfix..Hint +#: filter.dfm:306 +msgid "Synthesize GPS fixes (PPS, DGPS, 3D, 2D)" +msgstr "GPS fixek előállítása (PPS, DGPS, 3D, 2D)" + +#. frmFilter..gbTracks..cbGPSfix..Caption +#: filter.dfm:307 +msgid "GPS fixes" +msgstr "GPS fixek" + +#. frmFilter..gbTracks..cbTrackCourse..Hint +#: filter.dfm:316 +msgid "Synthesize course values" +msgstr "Azimut értékek előállítása" + +#. frmFilter..gbTracks..cbTrackCourse..Caption +#: filter.dfm:317 +msgid "Course" +msgstr "Azimut" + +#. frmFilter..gbTracks..cbTrackSpeed..Hint +#: filter.dfm:325 +msgid "Synthesize speed values" +msgstr "Sebesség értékek előállítása" + +#. frmFilter..gbTracks..cbTrackSpeed..Caption +#: filter.dfm:326 +msgid "Speed" +msgstr "Sebesség" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:338 +msgid "none" +msgstr "nincs" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:339 +msgid "pps" +msgstr "pps" + +#. frmFilter..gbTracks..cobGPSfixes....Items.Strings +#: filter.dfm:340 +msgid "dgps" +msgstr "dgps" + +#. frmFilter..gbRoutes..Caption +#: filter.dfm:352 +msgid "&Routes && Tracks" +msgstr "Útvonalak és Nyomvonalak" + +#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption +#: filter.dfm:360 +msgid "limit to" +msgstr "max." + +#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption +#: filter.dfm:368 +msgid "Points" +msgstr "Pontig" + +#. frmFilter..gbRoutes..cbRouteSimplify..Hint +#: filter.dfm:375 +msgid "Simplify routes and tracks by limited number of points" +msgstr "Nyomvonalak és útvonalak egyszerűsítése meghatározott pontig" + +#. frmFilter..gbRoutes..cbRouteSimplify..Caption +#: filter.dfm:376 +msgid "Simplify" +msgstr "Egyszerűsítés" + +#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint +#: filter.dfm:385 +msgid "Upper limit of points for routes and tracks" +msgstr "A pontok felső korlátja" + +#. frmFilter..gbRoutes..cbReverse..Hint +#: filter.dfm:407 +msgid "Reverse routes and tracks" +msgstr "Útvonalak és nyomvonalak irányának megfordítása" + +#. frmFilter..gbRoutes..cbReverse..Caption +#: filter.dfm:408 +msgid "Reverse" +msgstr "Megfordítás" + +#. frmFilter..pnBottom..btnOK..Caption +#: filter.dfm:425 +msgid "OK" +msgstr "OK" + +#. frmFilter..pnBottom..BitBtn1..Caption +#: filter.dfm:461 +msgid "File based filters" +msgstr "Fájl alapú szűrő" + +#. frmFilter..gbWaypoints..Caption +#. frmMain..pnBottom..cbWaypoints..Caption +#: filter.dfm:490 +#: main.dfm:555 +msgid "&Waypoints" +msgstr "Útpontok" + +#. frmFilter..gbWaypoints..lbWayptRadiusLat..Caption +#: filter.dfm:499 +msgid "Latitude" +msgstr "Szélesség" + +#. frmFilter..gbWaypoints..lbWayptRadiusLon..Caption +#: filter.dfm:507 +msgid "Longitude" +msgstr "Hosszúság" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint +#: filter.dfm:515 +msgid "Merge waypoints with duplicate locations" +msgstr "Azonos helyen levő pontok egyesítése" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption +#: filter.dfm:516 +msgid "locations" +msgstr "hely szerint" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint +#: filter.dfm:525 +msgid "Merge waypoints with duplicate \"short name\"" +msgstr "Útpontok egyesítése azonos \"rövid név\" -el" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption +#: filter.dfm:526 +msgid "\"short names\"" +msgstr "\"rövid név\"" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint +#: filter.dfm:535 +msgid "Merge waypoints separated by less then" +msgstr "Útpontok egyesítése, ha a távolság kevesebb mint:" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption +#: filter.dfm:536 +msgid "Position" +msgstr "Távolság" + +#. frmFilter..gbWaypoints..cbWayptSort..Hint +#: filter.dfm:564 +msgid "Sort waypoints by \"short name\" or by description" +msgstr "Rendezés \"rövid név\" vagy megjegyzés alapján" + +#. frmFilter..gbWaypoints..cbWayptSort..Caption +#: filter.dfm:565 +msgid "Sort" +msgstr "Rendezés" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint +#: filter.dfm:573 +msgid "Merge duplicate waypoints" +msgstr "Duplikált útpontok egyesítése" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption +#: filter.dfm:574 +msgid "Duplicates" +msgstr "Duplázás" + +#. frmFilter..gbWaypoints..cbWayptRadius..Hint +#: filter.dfm:583 +msgid "Include points based on their proximity to central point" +msgstr "A pontok a meghatározott körön belül maradnak" + +#. frmFilter..gbWaypoints..cbWayptRadius..Caption +#: filter.dfm:584 +msgid "Radius" +msgstr "Sugár" + +#. frmFilter..gbWaypoints..edWayptRadiusLat..Hint +#: filter.dfm:612 +msgid "Latitude of central point" +msgstr "Középpont (lat)" + +#. frmFilter..gbWaypoints..edWayptRadiusLon..Hint +#: filter.dfm:622 +msgid "Longitude of central point" +msgstr "Középpont (lon)" + +#. frmFilter..gbTransform..Caption +#: filter.dfm:634 +msgid "Transformation" +msgstr "Átalakítás" + +#. frmFilter..gbTransform..cbTransform..Caption +#: filter.dfm:651 +msgid "Transform" +msgstr "Konverzió" + +#. frmFilter..gbTransform..cbTransformDelete..Hint +#: filter.dfm:660 +msgid "Delete source data after transformation" +msgstr "Konverzió után az eredeti anyag törlése" + +#. frmFilter..gbTransform..cbTransformDelete..Caption +#: filter.dfm:661 +msgid "Delete" +msgstr "Törlés" + +#. frmMain..pnTop..gbInput..Caption +#: main.dfm:38 +#: main.pas:270 +#: main.pas:275 +#: main.pas:467 +#: main.pas:868 +msgid "Input" +msgstr "Bemenet" + +#. frmMain..pnTop..gbInput..sbOpenFile..Hint +#: main.dfm:45 +msgid "Start the file open dialog" +msgstr "Megnyitás" + +#. frmMain..pnTop..gbInput..lbInputOpts..Caption +#. frmMain..pnTop..gbOutput..lbOutputOpts..Caption +#. frmMain..ActionList1..acOptionsSourceFormat..Category +#. frmMain..ActionList1..acOptionsTargetFormat..Category +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Category +#: main.dfm:68 +#: main.dfm:229 +#: main.dfm:1418 +#: main.dfm:1423 +#: main.dfm:1437 +msgid "Options" +msgstr "Beállítások" + +#. frmMain..pnTop..gbInput..lbInputFormat..Caption +#. frmMain..pnTop..gbOutput..lbOutputFormat..Caption +#: main.dfm:76 +#: main.dfm:259 +msgid "Format" +msgstr "Formátum" + +#. frmMain..pnTop..gbInput..lbInputFile..Caption +#. frmMain..pnTop..gbOutput..lbOutputFile..Caption +#. frmMain..ActionList1..acFileExit..Category +#. frmMain..ActionList1..acFileClearMemo..Category +#. frmMain..ActionList1..acFileOutputToScreen..Category +#. frmMain..ActionList1..acFileChangeLanguage..Category +#. frmMain..ActionList1..acFileExportCSV..Category +#: main.dfm:83 +#: main.dfm:266 +#: main.dfm:1399 +#: main.dfm:1428 +#: main.dfm:1443 +#: main.dfm:1455 +#: main.dfm:1460 +#: main.pas:865 +#: main.pas:919 +msgid "File" +msgstr "Fájl" + +#. frmMain..pnTop..gbInput..chbInputDevice..Hint +#: main.dfm:112 +msgid "Read data from device instead from file" +msgstr "Beolvasás készülékből" + +#. frmMain..pnTop..gbInput..chbInputDevice..Caption +#. frmMain..pnTop..gbOutput..chbOutputDevice..Caption +#: main.dfm:115 +#: main.dfm:299 +msgid "Device" +msgstr "Készülék" + +#. frmMain..pnTop..gbInput..edInputOpts..Hint +#: main.dfm:124 +msgid "Options for the selected input format" +msgstr "A bemeneti fájl beállításai" + +#. frmMain..pnTop..gbInput..edInputFile..Hint +#: main.dfm:135 +msgid "Read data from given filename" +msgstr "Beolvasási az adott fájlból" + +#. frmMain..pnTop..gbInput..cbInputLang..Hint +#: main.dfm:146 +msgid "Characterset for input data" +msgstr "A bemeneti adat karakterkészlete" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:152 +#: main.dfm:363 +msgid "- default -" +msgstr "- alapértelmezett -" + +#. frmMain..pnTop..gbInput..cbInputDevice..Hint +#: main.dfm:179 +msgid "Read data from device ..." +msgstr "Adatok olvasása készülékből" + +#. frmMain..pnTop..gbInput..cbInputFormatDevice..Hint +#: main.dfm:194 +msgid "Format for input from device" +msgstr "A bemeneti készülék adatformátuma" + +#. frmMain..pnTop..gbInput..cbInputFormat..Hint +#: main.dfm:208 +msgid "Format for input from file" +msgstr "A bemeneti fájl formátuma" + +#. frmMain..pnTop..gbOutput..Caption +#: main.dfm:222 +#: main.pas:271 +#: main.pas:276 +#: main.pas:476 +#: main.pas:922 +msgid "Output" +msgstr "Kimenet" + +#. frmMain..pnTop..gbOutput..sbSaveFile..Hint +#: main.dfm:273 +msgid "Start the file save dialog" +msgstr "Mentés" + +#. frmMain..pnTop..gbOutput..chbOutputDevice..Hint +#: main.dfm:296 +msgid "Write data to device instead to file" +msgstr "Kimenetként készülékbe töltés" + +#. frmMain..pnTop..gbOutput..cbOutputFormatDevice..Hint +#: main.dfm:309 +msgid "Format for ouput to device" +msgstr "A kimeneti készülék adatformátuma" + +#. frmMain..pnTop..gbOutput..edOutputOpts..Hint +#: main.dfm:321 +msgid "Options for the selected output format" +msgstr "A kimeneti fájl beállításai" + +#. frmMain..pnTop..gbOutput..cbOutputFormat..Hint +#: main.dfm:332 +msgid "Format for output to file" +msgstr "A kimeneti fájl formátuma" + +#. frmMain..pnTop..gbOutput..edOutputFile..Hint +#: main.dfm:345 +msgid "Write data to given filename" +msgstr "Konvertálás az adott nevű fájlba" + +#. frmMain..pnTop..gbOutput..cbOutputLang..Hint +#: main.dfm:357 +msgid "Characterset for output data" +msgstr "A kimeneti adat karakterkészlete" + +#. frmMain..pnTop..gbOutput..cbOutputDevice..Hint +#: main.dfm:390 +msgid "Write data to device ..." +msgstr "Adatok küldése készülékbe" + +#. frmMain..pnBottom..lbWhat..Caption +#: main.dfm:415 +msgid "What ?" +msgstr "Mit?" + +#. frmMain..pnBottom..cbWaypoints..Hint +#: main.dfm:554 +msgid "Process waypoint information" +msgstr "Útpont adatok feldolgozása" + +#. frmMain..pnBottom..cbRoutes..Hint +#: main.dfm:568 +msgid "Process route information" +msgstr "Útvonal adatok feldolgozása" + +#. frmMain..pnBottom..cbRoutes..Caption +#: main.dfm:569 +msgid "&Routes" +msgstr "Útvonalak" + +#. frmMain..pnBottom..cbTracks..Hint +#: main.dfm:580 +msgid "Process track information" +msgstr "Nyomvonal adatok feldolgozása" + +#. frmMain..pnBottom..btnFilter..Caption +#. frmMain..ActionList1..acFilterSelect..Caption +#: main.dfm:594 +#: main.dfm:1393 +msgid "&Filter" +msgstr "Szűrő" + +#. frmMain..pnBottom..btnProcess..Hint +#: main.dfm:638 +msgid "Start data conversion" +msgstr "Konverzió indítása" + +#. frmMain..pnBottom..btnProcess..Caption +#. frmMain..ActionList1..acConvert..Caption +#: main.dfm:641 +#: main.dfm:1386 +msgid "let's go" +msgstr "Gyerünk!" + +#. frmMain..OpenDialog..Filter +#: main.dfm:701 +msgid "Garmin Mapsource mps|*.mps|All files|*.*" +msgstr "Garmin Mapsource mps|*.mps|Minden fájl|*.*" + +#. frmMain..SaveDialog..Filter +#: main.dfm:707 +msgid "All file(s)|*.*|Garmin MapSource mps|*.mps" +msgstr "Minden fájl|*.*|Garmin MapSource mps|*.mps" + +#. frmMain..ActionList1..acConvert..Category +#. frmMain..ActionList1..acFilterSelect..Category +#: main.dfm:1385 +#: main.dfm:1392 +msgid "Babel" +msgstr "Babel" + +#. frmMain..ActionList1..acFilterSelect..Hint +#: main.dfm:1394 +msgid "Filter incomming data before writing them to file or device" +msgstr "A bemeneti adatok szűrése a konverzió alatt" + +#. frmMain..ActionList1..acFileExit..Caption +#: main.dfm:1400 +msgid "E&xit" +msgstr "Kilépés" + +#. frmMain..ActionList1..acHelpAbout..Category +#. frmMain..ActionList1..acHelpIntro..Category +#. frmMain..ActionList1..acHelpReadme..Category +#: main.dfm:1404 +#: main.dfm:1409 +#: main.dfm:1413 +msgid "Help" +msgstr "Segítség" + +#. frmMain..ActionList1..acHelpAbout..Caption +#: main.dfm:1405 +msgid "&About" +msgstr "Névjegy" + +#. frmMain..ActionList1..acHelpIntro..Caption +#: main.dfm:1410 +msgid "&Intro" +msgstr "Bevezetés" + +#. frmMain..ActionList1..acHelpReadme..Caption +#. frmReadme..Caption +#: main.dfm:1414 +#: readme.dfm:6 +msgid "GPSBabel README" +msgstr "GPSBabel OLVASSEL!" + +#. frmMain..ActionList1..acOptionsSourceFormat..Caption +#: main.dfm:1419 +msgid "... for source format" +msgstr "... a bemeneti adathoz" + +#. frmMain..ActionList1..acOptionsTargetFormat..Caption +#: main.dfm:1424 +msgid "... for target format" +msgstr "... a kimeneti adathoz" + +#. frmMain..ActionList1..acFileClearMemo..Caption +#: main.dfm:1429 +msgid "Clear output" +msgstr "Mejegyzések törlése" + +#. frmMain..ActionList1..acFileClearMemo..Hint +#: main.dfm:1430 +msgid "Clear messages" +msgstr "Üzenetek törlése" + +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Caption +#: main.dfm:1438 +msgid "Enable characterset transformation" +msgstr "Karakterkészlet módosításának engedélyezése" + +#. frmMain..ActionList1..acFileOutputToScreen..Caption +#: main.dfm:1444 +msgid "Output to screen" +msgstr "Kimenetet a képernyőre" + +#. frmMain..ActionList1..acFileChangeLanguage..Caption +#: main.dfm:1456 +msgid "Change language" +msgstr "Nyelv választása" + +#. frmMain..ActionList1..acFileExportCSV..Caption +#: main.dfm:1461 +msgid "Export gpsbabel.csv (unicode)" +msgstr "Export gpsbabel.csv (unicode)" + +#. frmMain..MainMenu1..mnuFile..Caption +#: main.dfm:1469 +msgid "&File" +msgstr "Fájl" + +#. frmMain..MainMenu1..mnuFile..File1..Caption +#: main.dfm:1477 +msgid "Export" +msgstr "Export" + +#. frmMain..MainMenu1..mnuOptions..Caption +#: main.dfm:1498 +msgid "&Options" +msgstr "Beállítások" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames..Caption +#: main.dfm:1500 +msgid "Synthesize shortnames" +msgstr "Rövidnevek előállítása" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames....Hint +#: main.dfm:1503 +msgid "Ignore shortnames from source data and synthesize them from description or notes" +msgstr "Rövidnevek figyelmen kívül hagyása, előállítása a megjegyzésekből" + +#. frmMain..MainMenu1..mnuOptions..mnuOptionsForceDataType..Caption +#: main.dfm:1507 +msgid "Force selected GPS data types (nuketypes filter)" +msgstr "Kényszerített GPS adatformátum választás (nuketypes szűrő)" + +#. frmMain..MainMenu1..mnuHelp..Caption +#: main.dfm:1548 +msgid "&Help" +msgstr "Súgó" + +#. frmOptions..Caption +#: options.dfm:5 +msgid "Options for ..." +msgstr "Beállítások ..." + +#. frmSelect..pnBottom..btnCancel..Caption +#: select.dfm:66 +msgid "Abort" +msgstr "Mégse" + +#: about.pas:87 +#: select.pas:81 +msgid "German" +msgstr "Német" + +#: about.pas:88 +#: select.pas:83 +msgid "French" +msgstr "Francia" + +#: about.pas:89 +#: select.pas:82 +msgid "Spanish" +msgstr "Spanyol" + +#: about.pas:90 +#: select.pas:85 +msgid "Hungarian" +msgstr "Magyar" + +#: about.pas:132 +msgid "" +"Please have a look at the file README.GUI.\n" +"\n" +"There you will find all information you need to\n" +"get GPSBabelGUI working in your own language." +msgstr "" +"Kérem nézze meg a README.GUI fájlt.\n" +"\n" +"Abban talál további információkat arra vonatkozólag, hogy\n" +"érheti el a GPSBabelGUI programot más nyelveken is." + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:184 +#: filter.pas:185 +msgid "Waypoints" +msgstr "Útpontok" + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:182 +#: filter.pas:183 +msgid "Routes" +msgstr "Útvonalak" + +#: filter.pas:182 +#: filter.pas:183 +#: filter.pas:184 +#: filter.pas:185 +msgid "Tracks" +msgstr "Nyomvonalak" + +#: filter.pas:224 +msgid "Feet" +msgstr "láb" + +#: filter.pas:225 +msgid "Meter" +msgstr "méter" + +#: filter.pas:228 +msgid "Miles" +msgstr "mérföld" + +#: filter.pas:229 +msgid "Kilometer" +msgstr "kilométer" + +#: filter.pas:239 +msgid "Not supported by gpsbabel.exe, release %s!" +msgstr "Nem támogatott a gpsbabel ezen verziójával (%s)!" + +#: filter.pas:288 +msgid "Value (%s) out of range (%g to %g)!" +msgstr "Az érték: (%s) ,túlcsordul (%g to %g)!" + +#: filter.pas:593 +#: options.pas:661 +msgid "Discard changes?" +msgstr "Változások eldobása?" + +#: main.pas:244 +msgid "Internal development release" +msgstr "Belső, fejlesztői kiadás" + +#: main.pas:246 +msgid "BETA" +msgstr "BÉTA" + +#: main.pas:248 +msgid "Private release" +msgstr "Kiadás saját használatra" + +#: main.pas:250 +msgid "Special release" +msgstr "Speciális kiadás" + +#: main.pas:342 +msgid "The file \"gpsbabel.exe\" found in current directory is too old!" +msgstr "A \"gpsbabel.exe\" ezen verziója túl régi!" + +#: main.pas:416 +#: main.pas:550 +msgid "All files|*.*" +msgstr "Minden fájl|*.*" + +#: main.pas:484 +msgid "Select and edit options for \"%s\"" +msgstr "Beállítási lehetőségek \"%s\"" + +#: main.pas:488 +msgid "No options available for \"%s\"" +msgstr "Nincs beállítási lehetőség \"%s\"" + +#. s := s + '-1'; +#: main.pas:603 +msgid "File %s not found." +msgstr "%s fájl nem található." + +#: main.pas:664 +msgid "File \"%s\" exists ! Overwrite ?" +msgstr "\"%s\" fájl már létezik! Felülírja ?" + +#: main.pas:665 +msgid "Warning" +msgstr "Figyelem" + +#: main.pas:698 +msgid "Could not run \"gpsbabel.exe\"!" +msgstr "Futási hiba \"gpsbabel.exe\"!" + +#: main.pas:707 +msgid "Sorry, gpsbabel.exe reported problems!" +msgstr "Sajnálom, a program hibát észlelt!" + +#: main.pas:709 +msgid "Converted successfully from \"%s\" to \"%s\"." +msgstr "Sikeres konverzió \"%s\" -ból \"%s\" -ba." + +#: main.pas:820 +msgid "GPSBabel, version %s" +msgstr "GPSBabel, verzió %s" + +#: main.pas:854 +#: main.pas:909 +msgid "Port" +msgstr "Port" + +#: main.pas:1013 +msgid "Options for \"%s\"" +msgstr "Beállítások \"%s\"" + +#: main.pas:1203 +#: main.pas:1273 +msgid "Choose language" +msgstr "Nyelv választása" + +#: main.pas:1203 +msgid "for GUIBabelGUI" +msgstr "GUIBabelGUI-hoz" + +#: main.pas:1273 +msgid "for export" +msgstr "exportálásra" + +#. override; +#: options.pas:147 +msgid "Be aware, that most options are made for the output side. " +msgstr "Figyelem, ezek a beállítások a kiemetre hatnak." + +#: options.pas:148 +msgid "Currently we don't have a flag which tells us which direction is used by the options." +msgstr "Jelenleg nincs rá mód, hogy a beállítás oda-vissza hasson." + +#: options.pas:208 +msgid "Short \"%s\"" +msgstr "Rendezés \"%s\"" + +#: options.pas:332 +msgid "Invalid line format!" +msgstr "Érvénytelen formátum!" + +#: options.pas:353 +msgid "Unknown option \"%s\"!" +msgstr "Ismeretlen beállítás" + +#: select.pas:84 +msgid "English" +msgstr "Angol" + +#: utils.pas:119 +msgid "Error WINAPI: Could not create \"NamedPipe\"!" +msgstr "Hiba WINAPI: Hozzáférés sikertelen \"NamedPipe\"!" + +#: utils.pas:124 +msgid "\"gpsbabel.exe\" not found!!!" +msgstr "\"gpsbabel.exe\" nem található!!!" + +#. dwCreationFlags, // creation flags +#: utils.pas:143 +msgid "Could not run \"gpsbabel.exe\" (Error %d)!" +msgstr "Futtatási hiba \"gpsbabel.exe\" (Error %d)!" + +#: utils.pas:176 +msgid "\"gpsbabel.exe\" returned error 0x%x (%d)" +msgstr "\"gpsbabel.exe\" visszatérési hiba 0x%x (%d)" + diff --git a/win32/gui-2/locale/hu/LC_MESSAGES/delphi.po b/win32/gui-2/locale/hu/LC_MESSAGES/delphi.po new file mode 100644 index 000000000..8034b4252 --- /dev/null +++ b/win32/gui-2/locale/hu/LC_MESSAGES/delphi.po @@ -0,0 +1,2258 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Borland Delphi Hungarian translation 0.1\n" +"POT-Creation-Date: 2007-05-01 20:52\n" +"PO-Revision-Date: 2007-06-07 02:36+0100\n" +"Last-Translator: Sprok Bence \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2.1\n" +"Language-Team: Sprok Bence \n" +"X-Poedit-Language: Hungarian\n" +"X-Poedit-Country: HUNGARY\n" + +#. Programmer's name for it: SCreateRegKeyError +#: Rtl/Sys/comconst.pas:15 +msgid "Error creating system registry entry" +msgstr "Hiba a regisztrációs bejegyzés készítésekor" + +#. Programmer's name for it: SOleError +#. Programmer's name for it: SOleError +#: Rtl/Sys/comconst.pas:16 +#: Vcl/oleconst.pas:18 +msgid "OLE error %.8x" +msgstr "OLE hiba %.8x" + +#. Programmer's name for it: SObjectFactoryMissing +#: Rtl/Sys/comconst.pas:17 +msgid "Object factory for class %s missing" +msgstr "" + +#. Programmer's name for it: STypeInfoMissing +#: Rtl/Sys/comconst.pas:18 +msgid "Type information missing for class %s" +msgstr "" + +#. Programmer's name for it: SBadTypeInfo +#: Rtl/Sys/comconst.pas:19 +msgid "Incorrect type information for class %s" +msgstr "" + +#. Programmer's name for it: SDispIntfMissing +#: Rtl/Sys/comconst.pas:20 +msgid "Dispatch interface missing from class %s" +msgstr "" + +#. Programmer's name for it: SNoMethod +#: Rtl/Sys/comconst.pas:21 +msgid "Method '%s' not supported by automation object" +msgstr "" + +#. Programmer's name for it: SVarNotObject +#. Programmer's name for it: SVarNotAutoObject +#: Rtl/Sys/comconst.pas:22 +#: Vcl/oleconst.pas:20 +msgid "Variant does not reference an automation object" +msgstr "" + +#. Programmer's name for it: SDCOMNotInstalled +#: Rtl/Sys/comconst.pas:23 +msgid "DCOM not installed" +msgstr "DCOM nincs installálva" + +#. Programmer's name for it: SDAXError +#: Rtl/Sys/comconst.pas:24 +msgid "DAX Error" +msgstr "DAX Hiba" + +#. Programmer's name for it: SAutomationWarning +#: Rtl/Sys/comconst.pas:26 +msgid "COM Server Warning" +msgstr "COM Server figyelmeztetés" + +#. Programmer's name for it: SNoCloseActiveServer1 +#: Rtl/Sys/comconst.pas:29 +msgid "There are still active COM objects in this application. One or more clients may have references to these objects, so manually closing " +msgstr "Még jelenleg is futnak COM parancsok. Egy vagy több kliens még lehet, hogy hivatkozik ezekre. Kézi leállítás szükséges." + +#. Programmer's name for it: SNoCloseActiveServer2 +#: Rtl/Sys/comconst.pas:32 +msgid "" +"this application may cause those client application(s) to fail.\n" +"\n" +"Are you sure you want to close this application?" +msgstr "" +"ez az alkalmazás befagyaszthatja mások munkáját.\n" +"\n" +"Biztos, hogy be akarja zárni az alkalmazást?" + +#. Programmer's name for it: SAutoSessionExclusive +#: Vcl/bdeconst.pas:15 +msgid "Cannot enable AutoSessionName property with more than one session on a form or data-module" +msgstr "" + +#. Programmer's name for it: SAutoSessionExists +#: Vcl/bdeconst.pas:16 +msgid "Cannot add a session to the form or data-module while session '%s' has AutoSessionName enabled" +msgstr "" + +#. Programmer's name for it: SAutoSessionActive +#: Vcl/bdeconst.pas:17 +msgid "Cannot modify SessionName while AutoSessionName is enabled" +msgstr "" + +#. Programmer's name for it: SDuplicateDatabaseName +#: Vcl/bdeconst.pas:18 +msgid "Duplicate database name '%s'" +msgstr "Duplikált adatbázis-név '%s'" + +#. Programmer's name for it: SDuplicateSessionName +#: Vcl/bdeconst.pas:19 +msgid "Duplicate session name '%s'" +msgstr "Duplikált munkafázis név '%s'" + +#. Programmer's name for it: SInvalidSessionName +#: Vcl/bdeconst.pas:20 +msgid "Invalid session name %s" +msgstr "Érvénytelen munkafázis-név %s" + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/bdeconst.pas:21 +msgid "Database name missing" +msgstr "Hiányzó adatbázis-név" + +#. Programmer's name for it: SSessionNameMissing +#: Vcl/bdeconst.pas:22 +msgid "Session name missing" +msgstr "Hiányzó munkafázis-név" + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/bdeconst.pas:23 +msgid "Cannot perform this operation on an open database" +msgstr "A művelet nem hajtható végre nyitott adatbázison" + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/bdeconst.pas:24 +msgid "Cannot perform this operation on a closed database" +msgstr "A művelet nem hajtható végre zárt adatbázison" + +#. Programmer's name for it: SDatabaseHandleSet +#: Vcl/bdeconst.pas:25 +msgid "Database handle owned by a different session" +msgstr "Az adatbázis-kezelés jogosultsága egy másik munkafolyamathoz tartozik" + +#. Programmer's name for it: SSessionActive +#: Vcl/bdeconst.pas:26 +msgid "Cannot perform this operation on an active session" +msgstr "A műveletet nem lehet végrehajtani az aktív munkafolyamaton" + +#. Programmer's name for it: SHandleError +#: Vcl/bdeconst.pas:27 +msgid "Error creating cursor handle" +msgstr "" + +#. Programmer's name for it: SInvalidFloatField +#: Vcl/bdeconst.pas:28 +msgid "Cannot convert field '%s' to a floating point value" +msgstr "Az értéket '%s' nem lehet lebegőpontos értékké alakítani" + +#. Programmer's name for it: SInvalidIntegerField +#: Vcl/bdeconst.pas:29 +msgid "Cannot convert field '%s' to an integer value" +msgstr "" + +#. Programmer's name for it: STableMismatch +#: Vcl/bdeconst.pas:30 +msgid "Source and destination tables are incompatible" +msgstr "" + +#. Programmer's name for it: SFieldAssignError +#: Vcl/bdeconst.pas:31 +msgid "Fields '%s' and '%s' are not assignment compatible" +msgstr "" + +#. Programmer's name for it: SNoReferenceTableName +#: Vcl/bdeconst.pas:32 +msgid "ReferenceTableName not specified for field '%s'" +msgstr "" + +#. Programmer's name for it: SCompositeIndexError +#: Vcl/bdeconst.pas:33 +msgid "Cannot use array of Field values with Expression Indices" +msgstr "" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/bdeconst.pas:34 +msgid "Invalid batch move parameters" +msgstr "" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/bdeconst.pas:35 +msgid "No SQL statement available" +msgstr "" + +#. Programmer's name for it: SNoParameterValue +#: Vcl/bdeconst.pas:36 +msgid "No value for parameter '%s'" +msgstr "" + +#. Programmer's name for it: SNoParameterType +#: Vcl/bdeconst.pas:37 +msgid "No parameter type for parameter '%s'" +msgstr "" + +#. Programmer's name for it: SLoginError +#: Vcl/bdeconst.pas:38 +msgid "Cannot connect to database '%s'" +msgstr "" + +#. Programmer's name for it: SInitError +#: Vcl/bdeconst.pas:39 +msgid "An error occurred while attempting to initialize the Borland Database Engine (error $%.4x)" +msgstr "" + +#. Programmer's name for it: SDatasetDesigner +#: Vcl/bdeconst.pas:40 +msgid "Fields E&ditor..." +msgstr "" + +#. Programmer's name for it: SFKInternalCalc +#: Vcl/bdeconst.pas:41 +msgid "&InternalCalc" +msgstr "" + +#. Programmer's name for it: SFKAggregate +#: Vcl/bdeconst.pas:42 +msgid "&Aggregate" +msgstr "" + +#. Programmer's name for it: SDatabaseEditor +#: Vcl/bdeconst.pas:43 +msgid "Database &Editor..." +msgstr "" + +#. Programmer's name for it: SExplore +#: Vcl/bdeconst.pas:44 +msgid "E&xplore" +msgstr "" + +#. Programmer's name for it: SLinkDesigner +#: Vcl/bdeconst.pas:45 +msgid "Field '%s', from the Detail Fields list, must be linked" +msgstr "" + +#. Programmer's name for it: SLinkDetail +#: Vcl/bdeconst.pas:46 +msgid "'%s' cannot be opened" +msgstr "" + +#. Programmer's name for it: SLinkMasterSource +#: Vcl/bdeconst.pas:47 +msgid "The MasterSource property of '%s' must be linked to a DataSource" +msgstr "" + +#. Programmer's name for it: SLinkMaster +#: Vcl/bdeconst.pas:48 +msgid "Unable to open the MasterSource Table" +msgstr "" + +#. Programmer's name for it: SGQEVerb +#: Vcl/bdeconst.pas:49 +msgid "&SQL Builder..." +msgstr "" + +#. Programmer's name for it: SBindVerb +#: Vcl/bdeconst.pas:50 +msgid "Define &Parameters..." +msgstr "" + +#. Programmer's name for it: SDisconnectDatabase +#: Vcl/bdeconst.pas:52 +msgid "Database is currently connected. Disconnect and continue?" +msgstr "" + +#. Programmer's name for it: SBDEError +#: Vcl/bdeconst.pas:53 +msgid "BDE error $%.4x" +msgstr "" + +#. Programmer's name for it: SLookupSourceError +#: Vcl/bdeconst.pas:54 +msgid "Unable to use duplicate DataSource and LookupSource" +msgstr "" + +#. Programmer's name for it: SLookupTableError +#: Vcl/bdeconst.pas:55 +msgid "LookupSource must be connected to TTable component" +msgstr "" + +#. Programmer's name for it: SLookupIndexError +#: Vcl/bdeconst.pas:56 +msgid "%s must be the lookup table's active index" +msgstr "" + +#. Programmer's name for it: SParameterTypes +#: Vcl/bdeconst.pas:57 +msgid ";Input;Output;Input/Output;Result" +msgstr "" + +#. Programmer's name for it: SInvalidParamFieldType +#: Vcl/bdeconst.pas:58 +msgid "Must have a valid field type selected" +msgstr "" + +#. Programmer's name for it: STruncationError +#: Vcl/bdeconst.pas:59 +msgid "Parameter '%s' truncated on output" +msgstr "" + +#. Programmer's name for it: SDataTypes +#: Vcl/bdeconst.pas:60 +msgid ";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" +msgstr "" + +#. Programmer's name for it: SResultName +#: Vcl/bdeconst.pas:61 +msgid "Result" +msgstr "" + +#. Programmer's name for it: SDBCaption +#: Vcl/bdeconst.pas:62 +msgid "%s%s%s Database" +msgstr "" + +#. Programmer's name for it: SParamEditor +#: Vcl/bdeconst.pas:63 +msgid "%s%s%s Parameters" +msgstr "" + +#. Programmer's name for it: SDatasetEditor +#: Vcl/bdeconst.pas:64 +msgid "%s%s%s" +msgstr "" + +#. Programmer's name for it: SIndexFilesEditor +#: Vcl/bdeconst.pas:65 +msgid "%s%s%s Index Files" +msgstr "" + +#. Programmer's name for it: SNoIndexFiles +#. Programmer's name for it: srNone +#: Vcl/bdeconst.pas:66 +#: Vcl/consts.pas:189 +msgid "(None)" +msgstr "" + +#. Programmer's name for it: SIndexDoesNotExist +#: Vcl/bdeconst.pas:67 +msgid "Index does not exist. Index: %s" +msgstr "" + +#. Programmer's name for it: SNoTableName +#: Vcl/bdeconst.pas:68 +msgid "Missing TableName property" +msgstr "" + +#. Programmer's name for it: SNoDataSetField +#: Vcl/bdeconst.pas:69 +msgid "Missing DataSetField property" +msgstr "" + +#. Programmer's name for it: SBatchExecute +#: Vcl/bdeconst.pas:70 +msgid "E&xecute" +msgstr "" + +#. Programmer's name for it: SNoCachedUpdates +#: Vcl/bdeconst.pas:71 +msgid "Not in cached update mode" +msgstr "" + +#. Programmer's name for it: SInvalidAliasName +#: Vcl/bdeconst.pas:72 +msgid "Invalid alias name %s" +msgstr "" + +#. Programmer's name for it: SDBGridColEditor +#: Vcl/bdeconst.pas:73 +msgid "Co&lumns Editor..." +msgstr "" + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/bdeconst.pas:74 +msgid "Cannot access field '%s' in a filter" +msgstr "" + +#. Programmer's name for it: SUpdateSQLEditor +#: Vcl/bdeconst.pas:75 +msgid "&UpdateSQL Editor..." +msgstr "" + +#. Programmer's name for it: SNoDataSet +#: Vcl/bdeconst.pas:76 +msgid "No dataset association" +msgstr "" + +#. Programmer's name for it: SUntitled +#: Vcl/bdeconst.pas:77 +msgid "Untitled Application" +msgstr "" + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/bdeconst.pas:78 +msgid "Cannot update, %s is not owned by %s" +msgstr "" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/bdeconst.pas:79 +msgid "Update failed" +msgstr "" + +#. Programmer's name for it: SSQLGenSelect +#: Vcl/bdeconst.pas:80 +msgid "Must select at least one key field and one update field" +msgstr "" + +#. Programmer's name for it: SSQLNotGenerated +#: Vcl/bdeconst.pas:81 +msgid "Update SQL statements not generated, exit anyway?" +msgstr "" + +#. Programmer's name for it: SSQLDataSetOpen +#: Vcl/bdeconst.pas:82 +msgid "Unable to determine field names for %s" +msgstr "" + +#. Programmer's name for it: SLocalTransDirty +#: Vcl/bdeconst.pas:83 +msgid "The transaction isolation level must be dirty read for local databases" +msgstr "" + +#. Programmer's name for it: SPrimary +#: Vcl/bdeconst.pas:84 +msgid "Primary" +msgstr "" + +#. Programmer's name for it: SMissingDataSet +#: Vcl/bdeconst.pas:85 +msgid "Missing DataSet property" +msgstr "" + +#. Programmer's name for it: SNoProvider +#: Vcl/bdeconst.pas:86 +msgid "No provider available" +msgstr "" + +#. Programmer's name for it: SNotAQuery +#: Vcl/bdeconst.pas:87 +msgid "Dataset is not a query" +msgstr "" + +#. Programmer's name for it: SOpenFileTitle +#: Vcl/consts.pas:15 +msgid "Open" +msgstr "" + +#. Programmer's name for it: SAssignError +#: Vcl/consts.pas:16 +msgid "Cannot assign a %s to a %s" +msgstr "" + +#. Programmer's name for it: SFCreateError +#: Vcl/consts.pas:17 +msgid "Cannot create file %s" +msgstr "" + +#. Programmer's name for it: SFOpenError +#: Vcl/consts.pas:18 +msgid "Cannot open file %s" +msgstr "" + +#. Programmer's name for it: SReadError +#: Vcl/consts.pas:19 +msgid "Stream read error" +msgstr "" + +#. Programmer's name for it: SWriteError +#: Vcl/consts.pas:20 +msgid "Stream write error" +msgstr "" + +#. Programmer's name for it: SMemoryStreamError +#: Vcl/consts.pas:21 +msgid "Out of memory while expanding memory stream" +msgstr "" + +#. Programmer's name for it: SCantWriteResourceStreamError +#: Vcl/consts.pas:22 +msgid "Can't write to a read-only resource stream" +msgstr "" + +#. Programmer's name for it: SDuplicateReference +#: Vcl/consts.pas:23 +msgid "WriteObject called twice for the same instance" +msgstr "" + +#. Programmer's name for it: SClassNotFound +#: Vcl/consts.pas:24 +msgid "Class %s not found" +msgstr "" + +#. Programmer's name for it: SInvalidImage +#. Programmer's name for it: SInvalidStreamFormat +#: Vcl/consts.pas:25 +#: Vcl/oleconst.pas:29 +msgid "Invalid stream format" +msgstr "" + +#. Programmer's name for it: SResNotFound +#: Vcl/consts.pas:26 +msgid "Resource %s not found" +msgstr "" + +#. Programmer's name for it: SClassMismatch +#: Vcl/consts.pas:27 +msgid "Resource %s is of incorrect class" +msgstr "" + +#. Programmer's name for it: SListIndexError +#: Vcl/consts.pas:28 +msgid "List index out of bounds (%d)" +msgstr "" + +#. Programmer's name for it: SListCapacityError +#: Vcl/consts.pas:29 +msgid "List capacity out of bounds (%d)" +msgstr "" + +#. Programmer's name for it: SListCountError +#: Vcl/consts.pas:30 +msgid "List count out of bounds (%d)" +msgstr "" + +#. Programmer's name for it: SSortedListError +#: Vcl/consts.pas:31 +msgid "Operation not allowed on sorted string list" +msgstr "" + +#. Programmer's name for it: SDuplicateString +#: Vcl/consts.pas:32 +msgid "String list does not allow duplicates" +msgstr "" + +#. Programmer's name for it: SInvalidTabIndex +#: Vcl/consts.pas:33 +msgid "Tab index out of bounds" +msgstr "" + +#. Programmer's name for it: SInvalidTabPosition +#: Vcl/consts.pas:34 +msgid "Tab position incompatible with current tab style" +msgstr "" + +#. Programmer's name for it: SInvalidTabStyle +#: Vcl/consts.pas:35 +msgid "Tab style incompatible with current tab position" +msgstr "" + +#. Programmer's name for it: SDuplicateName +#: Vcl/consts.pas:36 +msgid "A component named %s already exists" +msgstr "" + +#. Programmer's name for it: SInvalidName +#: Vcl/consts.pas:37 +msgid "''%s'' is not a valid component name" +msgstr "" + +#. Programmer's name for it: SDuplicateClass +#: Vcl/consts.pas:38 +msgid "A class named %s already exists" +msgstr "" + +#. Programmer's name for it: SNoComSupport +#: Vcl/consts.pas:39 +msgid "%s has not been registered as a COM class" +msgstr "" + +#. Programmer's name for it: SInvalidInteger +#: Vcl/consts.pas:40 +msgid "''%s'' is not a valid integer value" +msgstr "" + +#. Programmer's name for it: SLineTooLong +#. Programmer's name for it: SOutlineLongLine +#: Vcl/consts.pas:41 +#: Vcl/consts.pas:148 +msgid "Line too long" +msgstr "" + +#. Programmer's name for it: SInvalidPropertyValue +#. Programmer's name for it: SInvalidProperty +#: Vcl/consts.pas:42 +#: Vcl/consts.pas:137 +msgid "Invalid property value" +msgstr "" + +#. Programmer's name for it: SInvalidPropertyPath +#: Vcl/consts.pas:43 +msgid "Invalid property path" +msgstr "" + +#. Programmer's name for it: SUnknownProperty +#: Vcl/consts.pas:44 +msgid "Property does not exist" +msgstr "" + +#. Programmer's name for it: SReadOnlyProperty +#: Vcl/consts.pas:45 +msgid "Property is read-only" +msgstr "" + +#. Programmer's name for it: SPropertyException +#: Vcl/consts.pas:46 +msgid "Error reading %s%s%s: %s" +msgstr "" + +#. Programmer's name for it: SAncestorNotFound +#: Vcl/consts.pas:47 +msgid "Ancestor for '%s' not found" +msgstr "" + +#. Programmer's name for it: SInvalidBitmap +#: Vcl/consts.pas:48 +msgid "Bitmap image is not valid" +msgstr "" + +#. Programmer's name for it: SInvalidIcon +#: Vcl/consts.pas:49 +msgid "Icon image is not valid" +msgstr "" + +#. Programmer's name for it: SInvalidMetafile +#: Vcl/consts.pas:50 +msgid "Metafile is not valid" +msgstr "" + +#. Programmer's name for it: SInvalidPixelFormat +#: Vcl/consts.pas:51 +msgid "Invalid pixel format" +msgstr "" + +#. Programmer's name for it: SBitmapEmpty +#: Vcl/consts.pas:52 +msgid "Bitmap is empty" +msgstr "" + +#. Programmer's name for it: SScanLine +#: Vcl/consts.pas:53 +msgid "Scan line index out of range" +msgstr "" + +#. Programmer's name for it: SChangeIconSize +#: Vcl/consts.pas:54 +msgid "Cannot change the size of an icon" +msgstr "" + +#. Programmer's name for it: SOleGraphic +#: Vcl/consts.pas:55 +msgid "Invalid operation on TOleGraphic" +msgstr "" + +#. Programmer's name for it: SUnknownExtension +#: Vcl/consts.pas:56 +msgid "Unknown picture file extension (.%s)" +msgstr "" + +#. Programmer's name for it: SUnknownClipboardFormat +#: Vcl/consts.pas:57 +msgid "Unsupported clipboard format" +msgstr "" + +#. Programmer's name for it: SOutOfResources +#: Vcl/consts.pas:58 +msgid "Out of system resources" +msgstr "" + +#. Programmer's name for it: SNoCanvasHandle +#: Vcl/consts.pas:59 +msgid "Canvas does not allow drawing" +msgstr "" + +#. Programmer's name for it: SInvalidImageSize +#: Vcl/consts.pas:60 +msgid "Invalid image size" +msgstr "" + +#. Programmer's name for it: STooManyImages +#: Vcl/consts.pas:61 +msgid "Too many images" +msgstr "" + +#. Programmer's name for it: SDimsDoNotMatch +#: Vcl/consts.pas:62 +msgid "Image dimensions do not match image list dimensions" +msgstr "" + +#. Programmer's name for it: SInvalidImageList +#: Vcl/consts.pas:63 +msgid "Invalid ImageList" +msgstr "" + +#. Programmer's name for it: SReplaceImage +#: Vcl/consts.pas:64 +msgid "Unable to Replace Image" +msgstr "" + +#. Programmer's name for it: SImageIndexError +#: Vcl/consts.pas:65 +msgid "Invalid ImageList Index" +msgstr "" + +#. Programmer's name for it: SImageReadFail +#: Vcl/consts.pas:66 +msgid "Failed to read ImageList data from stream" +msgstr "" + +#. Programmer's name for it: SImageWriteFail +#: Vcl/consts.pas:67 +msgid "Failed to write ImageList data to stream" +msgstr "" + +#. Programmer's name for it: SWindowDCError +#: Vcl/consts.pas:68 +msgid "Error creating window device context" +msgstr "" + +#. Programmer's name for it: SClientNotSet +#: Vcl/consts.pas:69 +msgid "Client of TDrag not initialized" +msgstr "" + +#. Programmer's name for it: SWindowClass +#: Vcl/consts.pas:70 +msgid "Error creating window class" +msgstr "" + +#. Programmer's name for it: SWindowCreate +#: Vcl/consts.pas:71 +msgid "Error creating window" +msgstr "" + +#. Programmer's name for it: SCannotFocus +#: Vcl/consts.pas:72 +msgid "Cannot focus a disabled or invisible window" +msgstr "" + +#. Programmer's name for it: SParentRequired +#: Vcl/consts.pas:73 +msgid "Control '%s' has no parent window" +msgstr "" + +#. Programmer's name for it: SMDIChildNotVisible +#: Vcl/consts.pas:74 +msgid "Cannot hide an MDI Child Form" +msgstr "" + +#. Programmer's name for it: SVisibleChanged +#: Vcl/consts.pas:75 +msgid "Cannot change Visible in OnShow or OnHide" +msgstr "" + +#. Programmer's name for it: SCannotShowModal +#: Vcl/consts.pas:76 +msgid "Cannot make a visible window modal" +msgstr "" + +#. Programmer's name for it: SScrollBarRange +#: Vcl/consts.pas:77 +msgid "Scrollbar property out of range" +msgstr "" + +#. Programmer's name for it: SPropertyOutOfRange +#: Vcl/consts.pas:78 +msgid "%s property out of range" +msgstr "" + +#. Programmer's name for it: SMenuIndexError +#: Vcl/consts.pas:79 +msgid "Menu index out of range" +msgstr "" + +#. Programmer's name for it: SMenuReinserted +#: Vcl/consts.pas:80 +msgid "Menu inserted twice" +msgstr "" + +#. Programmer's name for it: SMenuNotFound +#: Vcl/consts.pas:81 +msgid "Sub-menu is not in menu" +msgstr "" + +#. Programmer's name for it: SNoTimers +#: Vcl/consts.pas:82 +msgid "Not enough timers available" +msgstr "" + +#. Programmer's name for it: SNotPrinting +#: Vcl/consts.pas:83 +msgid "Printer is not currently printing" +msgstr "" + +#. Programmer's name for it: SPrinting +#: Vcl/consts.pas:84 +msgid "Printing in progress" +msgstr "" + +#. Programmer's name for it: SPrinterIndexError +#: Vcl/consts.pas:85 +msgid "Printer index out of range" +msgstr "" + +#. Programmer's name for it: SInvalidPrinter +#: Vcl/consts.pas:86 +msgid "Printer selected is not valid" +msgstr "" + +#. Programmer's name for it: SDeviceOnPort +#: Vcl/consts.pas:87 +msgid "%s on %s" +msgstr "" + +#. Programmer's name for it: SGroupIndexTooLow +#: Vcl/consts.pas:88 +msgid "GroupIndex cannot be less than a previous menu item's GroupIndex" +msgstr "" + +#. Programmer's name for it: STwoMDIForms +#: Vcl/consts.pas:89 +msgid "Cannot have more than one MDI form per application" +msgstr "" + +#. Programmer's name for it: SNoMDIForm +#: Vcl/consts.pas:90 +msgid "Cannot create form. No MDI forms are currently active" +msgstr "" + +#. Programmer's name for it: SRegisterError +#: Vcl/consts.pas:91 +msgid "Invalid component registration" +msgstr "" + +#. Programmer's name for it: SImageCanvasNeedsBitmap +#: Vcl/consts.pas:92 +msgid "Can only modify an image if it contains a bitmap" +msgstr "" + +#. Programmer's name for it: SControlParentSetToSelf +#: Vcl/consts.pas:93 +msgid "A control cannot have itself as its parent" +msgstr "" + +#. Programmer's name for it: SOKButton +#. Programmer's name for it: SMsgDlgOK +#: Vcl/consts.pas:94 +#: Vcl/consts.pas:157 +msgid "OK" +msgstr "" + +#. Programmer's name for it: SCancelButton +#. Programmer's name for it: SMsgDlgCancel +#: Vcl/consts.pas:95 +#: Vcl/consts.pas:158 +msgid "Cancel" +msgstr "" + +#. Programmer's name for it: SYesButton +#. Programmer's name for it: SMsgDlgYes +#: Vcl/consts.pas:96 +#: Vcl/consts.pas:155 +msgid "&Yes" +msgstr "" + +#. Programmer's name for it: SNoButton +#. Programmer's name for it: SMsgDlgNo +#: Vcl/consts.pas:97 +#: Vcl/consts.pas:156 +msgid "&No" +msgstr "" + +#. Programmer's name for it: SHelpButton +#. Programmer's name for it: SMsgDlgHelp +#: Vcl/consts.pas:98 +#: Vcl/consts.pas:159 +msgid "&Help" +msgstr "" + +#. Programmer's name for it: SCloseButton +#: Vcl/consts.pas:99 +msgid "&Close" +msgstr "" + +#. Programmer's name for it: SIgnoreButton +#. Programmer's name for it: SMsgDlgIgnore +#: Vcl/consts.pas:100 +#: Vcl/consts.pas:164 +msgid "&Ignore" +msgstr "" + +#. Programmer's name for it: SRetryButton +#. Programmer's name for it: SMsgDlgRetry +#: Vcl/consts.pas:101 +#: Vcl/consts.pas:163 +msgid "&Retry" +msgstr "" + +#. Programmer's name for it: SAbortButton +#: Vcl/consts.pas:102 +msgid "Abort" +msgstr "" + +#. Programmer's name for it: SAllButton +#. Programmer's name for it: SMsgDlgAll +#: Vcl/consts.pas:103 +#: Vcl/consts.pas:165 +msgid "&All" +msgstr "" + +#. Programmer's name for it: SCannotDragForm +#: Vcl/consts.pas:105 +msgid "Cannot drag a form" +msgstr "" + +#. Programmer's name for it: SPutObjectError +#: Vcl/consts.pas:106 +msgid "PutObject to undefined item" +msgstr "" + +#. Programmer's name for it: SCardDLLNotLoaded +#: Vcl/consts.pas:107 +msgid "Could not load CARDS.DLL" +msgstr "" + +#. Programmer's name for it: SDuplicateCardId +#: Vcl/consts.pas:108 +msgid "Duplicate CardId found" +msgstr "" + +#. Programmer's name for it: SDdeErr +#: Vcl/consts.pas:110 +msgid "An error returned from DDE ($0%x)" +msgstr "" + +#. Programmer's name for it: SDdeConvErr +#: Vcl/consts.pas:111 +msgid "DDE Error - conversation not established ($0%x)" +msgstr "" + +#. Programmer's name for it: SDdeMemErr +#: Vcl/consts.pas:112 +msgid "Error occurred when DDE ran out of memory ($0%x)" +msgstr "" + +#. Programmer's name for it: SDdeNoConnect +#: Vcl/consts.pas:113 +msgid "Unable to connect DDE conversation" +msgstr "" + +#. Programmer's name for it: SFB +#: Vcl/consts.pas:115 +msgid "FB" +msgstr "" + +#. Programmer's name for it: SFG +#: Vcl/consts.pas:116 +msgid "FG" +msgstr "" + +#. Programmer's name for it: SBG +#: Vcl/consts.pas:117 +msgid "BG" +msgstr "" + +#. Programmer's name for it: SOldTShape +#: Vcl/consts.pas:118 +msgid "Cannot load older version of TShape" +msgstr "" + +#. Programmer's name for it: SVMetafiles +#: Vcl/consts.pas:119 +msgid "Metafiles" +msgstr "" + +#. Programmer's name for it: SVEnhMetafiles +#: Vcl/consts.pas:120 +msgid "Enhanced Metafiles" +msgstr "" + +#. Programmer's name for it: SVIcons +#: Vcl/consts.pas:121 +msgid "Icons" +msgstr "" + +#. Programmer's name for it: SVBitmaps +#: Vcl/consts.pas:122 +msgid "Bitmaps" +msgstr "" + +#. Programmer's name for it: SGridTooLarge +#: Vcl/consts.pas:123 +msgid "Grid too large for operation" +msgstr "" + +#. Programmer's name for it: STooManyDeleted +#: Vcl/consts.pas:124 +msgid "Too many rows or columns deleted" +msgstr "" + +#. Programmer's name for it: SIndexOutOfRange +#: Vcl/consts.pas:125 +msgid "Grid index out of range" +msgstr "" + +#. Programmer's name for it: SFixedColTooBig +#: Vcl/consts.pas:126 +msgid "Fixed column count must be less than column count" +msgstr "" + +#. Programmer's name for it: SFixedRowTooBig +#: Vcl/consts.pas:127 +msgid "Fixed row count must be less than row count" +msgstr "" + +#. Programmer's name for it: SInvalidStringGridOp +#: Vcl/consts.pas:128 +msgid "Cannot insert or delete rows from grid" +msgstr "" + +#. Programmer's name for it: SParseError +#: Vcl/consts.pas:129 +msgid "%s on line %d" +msgstr "" + +#. Programmer's name for it: SIdentifierExpected +#: Vcl/consts.pas:130 +msgid "Identifier expected" +msgstr "" + +#. Programmer's name for it: SStringExpected +#: Vcl/consts.pas:131 +msgid "String expected" +msgstr "" + +#. Programmer's name for it: SNumberExpected +#: Vcl/consts.pas:132 +msgid "Number expected" +msgstr "" + +#. Programmer's name for it: SCharExpected +#: Vcl/consts.pas:133 +msgid "''%s'' expected" +msgstr "" + +#. Programmer's name for it: SSymbolExpected +#: Vcl/consts.pas:134 +msgid "%s expected" +msgstr "" + +#. Programmer's name for it: SInvalidNumber +#: Vcl/consts.pas:135 +msgid "Invalid numeric value" +msgstr "" + +#. Programmer's name for it: SInvalidString +#: Vcl/consts.pas:136 +msgid "Invalid string constant" +msgstr "" + +#. Programmer's name for it: SInvalidBinary +#: Vcl/consts.pas:138 +msgid "Invalid binary value" +msgstr "" + +#. Programmer's name for it: SOutlineIndexError +#: Vcl/consts.pas:139 +msgid "Outline index not found" +msgstr "" + +#. Programmer's name for it: SOutlineExpandError +#: Vcl/consts.pas:140 +msgid "Parent must be expanded" +msgstr "" + +#. Programmer's name for it: SInvalidCurrentItem +#: Vcl/consts.pas:141 +msgid "Invalid value for current item" +msgstr "" + +#. Programmer's name for it: SMaskErr +#: Vcl/consts.pas:142 +msgid "Invalid input value" +msgstr "" + +#. Programmer's name for it: SMaskEditErr +#: Vcl/consts.pas:143 +msgid "Invalid input value. Use escape key to abandon changes" +msgstr "" + +#. Programmer's name for it: SOutlineError +#: Vcl/consts.pas:144 +msgid "Invalid outline index" +msgstr "" + +#. Programmer's name for it: SOutlineBadLevel +#: Vcl/consts.pas:145 +msgid "Incorrect level assignment" +msgstr "" + +#. Programmer's name for it: SOutlineSelection +#: Vcl/consts.pas:146 +msgid "Invalid selection" +msgstr "" + +#. Programmer's name for it: SOutlineFileLoad +#: Vcl/consts.pas:147 +msgid "File load error" +msgstr "" + +#. Programmer's name for it: SOutlineMaxLevels +#: Vcl/consts.pas:149 +msgid "Maximum outline depth exceeded" +msgstr "" + +#. Programmer's name for it: SMsgDlgWarning +#: Vcl/consts.pas:151 +msgid "Warning" +msgstr "" + +#. Programmer's name for it: SMsgDlgError +#: Vcl/consts.pas:152 +msgid "Error" +msgstr "" + +#. Programmer's name for it: SMsgDlgInformation +#: Vcl/consts.pas:153 +msgid "Information" +msgstr "" + +#. Programmer's name for it: SMsgDlgConfirm +#: Vcl/consts.pas:154 +msgid "Confirm" +msgstr "" + +#. Programmer's name for it: SMsgDlgHelpNone +#: Vcl/consts.pas:160 +msgid "No help available" +msgstr "" + +#. Programmer's name for it: SMsgDlgHelpHelp +#: Vcl/consts.pas:161 +msgid "Help" +msgstr "" + +#. Programmer's name for it: SMsgDlgAbort +#: Vcl/consts.pas:162 +msgid "&Abort" +msgstr "" + +#. Programmer's name for it: SMsgDlgNoToAll +#: Vcl/consts.pas:166 +msgid "N&o to All" +msgstr "" + +#. Programmer's name for it: SMsgDlgYesToAll +#: Vcl/consts.pas:167 +msgid "Yes to &All" +msgstr "" + +#. Programmer's name for it: SmkcBkSp +#: Vcl/consts.pas:169 +msgid "BkSp" +msgstr "" + +#. Programmer's name for it: SmkcTab +#: Vcl/consts.pas:170 +msgid "Tab" +msgstr "" + +#. Programmer's name for it: SmkcEsc +#: Vcl/consts.pas:171 +msgid "Esc" +msgstr "" + +#. Programmer's name for it: SmkcEnter +#: Vcl/consts.pas:172 +msgid "Enter" +msgstr "" + +#. Programmer's name for it: SmkcSpace +#: Vcl/consts.pas:173 +msgid "Space" +msgstr "" + +#. Programmer's name for it: SmkcPgUp +#: Vcl/consts.pas:174 +msgid "PgUp" +msgstr "" + +#. Programmer's name for it: SmkcPgDn +#: Vcl/consts.pas:175 +msgid "PgDn" +msgstr "" + +#. Programmer's name for it: SmkcEnd +#: Vcl/consts.pas:176 +msgid "End" +msgstr "" + +#. Programmer's name for it: SmkcHome +#: Vcl/consts.pas:177 +msgid "Home" +msgstr "" + +#. Programmer's name for it: SmkcLeft +#: Vcl/consts.pas:178 +msgid "Left" +msgstr "" + +#. Programmer's name for it: SmkcUp +#: Vcl/consts.pas:179 +msgid "Up" +msgstr "" + +#. Programmer's name for it: SmkcRight +#: Vcl/consts.pas:180 +msgid "Right" +msgstr "" + +#. Programmer's name for it: SmkcDown +#: Vcl/consts.pas:181 +msgid "Down" +msgstr "" + +#. Programmer's name for it: SmkcIns +#: Vcl/consts.pas:182 +msgid "Ins" +msgstr "" + +#. Programmer's name for it: SmkcDel +#: Vcl/consts.pas:183 +msgid "Del" +msgstr "" + +#. Programmer's name for it: SmkcShift +#: Vcl/consts.pas:184 +msgid "Shift+" +msgstr "" + +#. Programmer's name for it: SmkcCtrl +#: Vcl/consts.pas:185 +msgid "Ctrl+" +msgstr "" + +#. Programmer's name for it: SmkcAlt +#: Vcl/consts.pas:186 +msgid "Alt+" +msgstr "" + +#. Programmer's name for it: srUnknown +#: Vcl/consts.pas:188 +msgid "(Unknown)" +msgstr "" + +#. Programmer's name for it: SOutOfRange +#: Vcl/consts.pas:190 +msgid "Value must be between %d and %d" +msgstr "" + +#. Programmer's name for it: SCannotCreateName +#: Vcl/consts.pas:191 +msgid "Cannot create a default method name for an unnamed component" +msgstr "" + +#. Programmer's name for it: SDateEncodeError +#: Vcl/consts.pas:193 +msgid "Invalid argument to date encode" +msgstr "" + +#. Programmer's name for it: STimeEncodeError +#: Vcl/consts.pas:194 +msgid "Invalid argument to time encode" +msgstr "" + +#. Programmer's name for it: SInvalidDate +#: Vcl/consts.pas:195 +msgid "''%s'' is not a valid date" +msgstr "" + +#. Programmer's name for it: SInvalidTime +#: Vcl/consts.pas:196 +msgid "''%s'' is not a valid time" +msgstr "" + +#. Programmer's name for it: SInvalidDateTime +#: Vcl/consts.pas:197 +msgid "''%s'' is not a valid date and time" +msgstr "" + +#. Programmer's name for it: SInvalidFileName +#: Vcl/consts.pas:198 +msgid "Invalid file name - %s" +msgstr "" + +#. Programmer's name for it: SDefaultFilter +#: Vcl/consts.pas:199 +msgid "All files (*.*)|*.*" +msgstr "" + +#. Programmer's name for it: sAllFilter +#: Vcl/consts.pas:200 +msgid "All" +msgstr "" + +#. Programmer's name for it: SNoVolumeLabel +#: Vcl/consts.pas:201 +msgid ": [ - no volume label - ]" +msgstr "" + +#. Programmer's name for it: SInsertLineError +#: Vcl/consts.pas:202 +msgid "Unable to insert a line" +msgstr "" + +#. Programmer's name for it: SConfirmCreateDir +#: Vcl/consts.pas:204 +msgid "The specified directory does not exist. Create it?" +msgstr "" + +#. Programmer's name for it: SSelectDirCap +#: Vcl/consts.pas:205 +msgid "Select Directory" +msgstr "" + +#. Programmer's name for it: SCannotCreateDir +#: Vcl/consts.pas:206 +msgid "Unable to create directory" +msgstr "" + +#. Programmer's name for it: SDirNameCap +#: Vcl/consts.pas:207 +msgid "Directory &Name:" +msgstr "Könyvtár Név:" + +#. Programmer's name for it: SDrivesCap +#: Vcl/consts.pas:208 +msgid "D&rives:" +msgstr "Meghajtók:" + +#. Programmer's name for it: SDirsCap +#: Vcl/consts.pas:209 +msgid "&Directories:" +msgstr "Könyvtárak:" + +#. Programmer's name for it: SFilesCap +#: Vcl/consts.pas:210 +msgid "&Files: (*.*)" +msgstr "Minden fájl (*.*)" + +#. Programmer's name for it: SNetworkCap +#: Vcl/consts.pas:211 +msgid "Ne&twork..." +msgstr "Hálózat..." + +#. Programmer's name for it: SColorPrefix +#: Vcl/consts.pas:213 +msgid "Color" +msgstr "Szín" + +#. Programmer's name for it: SColorTags +#: Vcl/consts.pas:214 +msgid "ABCDEFGHIJKLMNOP" +msgstr "ABCDEFGHIJKLMNOP" + +#. Programmer's name for it: SInvalidClipFmt +#: Vcl/consts.pas:216 +msgid "Invalid clipboard format" +msgstr "Nem megfelelő vágólap formátum" + +#. Programmer's name for it: SIconToClipboard +#: Vcl/consts.pas:217 +msgid "Clipboard does not support Icons" +msgstr "A vágólap nem támogat ikonokat" + +#. Programmer's name for it: SCannotOpenClipboard +#: Vcl/consts.pas:218 +msgid "Cannot open clipboard" +msgstr "Nem lehet megnyitni a vágólapot" + +#. Programmer's name for it: SDefault +#: Vcl/consts.pas:220 +msgid "Default" +msgstr "Alapértelmezett" + +#. Programmer's name for it: SInvalidMemoSize +#: Vcl/consts.pas:222 +msgid "Text exceeds memo capacity" +msgstr "A szöveg túllép a kapacitáson" + +#. Programmer's name for it: SCustomColors +#: Vcl/consts.pas:223 +msgid "Custom Colors" +msgstr "Egyedi színek" + +#. Programmer's name for it: SInvalidPrinterOp +#: Vcl/consts.pas:224 +msgid "Operation not supported on selected printer" +msgstr "A parancs nem támgatott ezen a nyomtatón" + +#. Programmer's name for it: SNoDefaultPrinter +#: Vcl/consts.pas:225 +msgid "There is no default printer currently selected" +msgstr "Nincs kiválasztva alapértelmezett nyomtató" + +#. Programmer's name for it: SIniFileWriteError +#: Vcl/consts.pas:227 +msgid "Unable to write to %s" +msgstr "Hiba az íráskor %s" + +#. Programmer's name for it: SBitsIndexError +#: Vcl/consts.pas:229 +msgid "Bits index out of range" +msgstr "Bit index hatókörön kívülre esik" + +#. Programmer's name for it: SUntitled +#: Vcl/consts.pas:231 +msgid "(Untitled)" +msgstr "(Névtelen)" + +#. Programmer's name for it: SInvalidRegType +#: Vcl/consts.pas:233 +msgid "Invalid data type for '%s'" +msgstr "Érvénytelen adattípus '%s'" + +#. Programmer's name for it: SRegCreateFailed +#: Vcl/consts.pas:234 +msgid "Failed to create key %s" +msgstr "Hiba a kulcs előállításakor %s" + +#. Programmer's name for it: SRegSetDataFailed +#: Vcl/consts.pas:235 +msgid "Failed to set data for '%s'" +msgstr "Hiba az adat beállításakor '%s'" + +#. Programmer's name for it: SRegGetDataFailed +#: Vcl/consts.pas:236 +msgid "Failed to get data for '%s'" +msgstr "Hiba az adat behívásakor '%s'" + +#. Programmer's name for it: SUnknownConversion +#: Vcl/consts.pas:238 +msgid "Unknown RichEdit conversion file extension (.%s)" +msgstr "" + +#. Programmer's name for it: SDuplicateMenus +#: Vcl/consts.pas:239 +msgid "Menu '%s' is already being used by another form" +msgstr "Menü '%s' már használatban van" + +#. Programmer's name for it: SPictureLabel +#: Vcl/consts.pas:241 +msgid "Picture:" +msgstr "Kép:" + +#. Programmer's name for it: SPictureDesc +#: Vcl/consts.pas:242 +msgid " (%dx%d)" +msgstr " (%dx%d)" + +#. Programmer's name for it: SPreviewLabel +#: Vcl/consts.pas:243 +msgid "Preview" +msgstr "Előnézet" + +#. Programmer's name for it: SCannotOpenAVI +#: Vcl/consts.pas:245 +msgid "Cannot open AVI" +msgstr "Nem lehet megnyitni az AVI-t" + +#. Programmer's name for it: SNotOpenErr +#: Vcl/consts.pas:247 +msgid "No MCI device open" +msgstr "Nincs megnyitva MCI eszköz" + +#. Programmer's name for it: SMPOpenFilter +#: Vcl/consts.pas:248 +msgid "All files (*.*)|*.*|Wave files (*.wav)|*.wav|Midi files (*.mid)|*.mid|Video for Windows (*.avi)|*.avi" +msgstr "Minden fájl (*.*)|*.*|Hangfájl (*.wav)|*.wav|Midi fájl (*.mid)|*.mid|Windows Video (*.avi)|*.avi" + +#. Programmer's name for it: SMCIAVIVideo +#: Vcl/consts.pas:250 +msgid "AVIVideo" +msgstr "AVIVideo" + +#. Programmer's name for it: SMCICDAudio +#: Vcl/consts.pas:251 +msgid "CDAudio" +msgstr "CDAudio" + +#. Programmer's name for it: SMCIDAT +#: Vcl/consts.pas:252 +msgid "DAT" +msgstr "DAT" + +#. Programmer's name for it: SMCIDigitalVideo +#: Vcl/consts.pas:253 +msgid "DigitalVideo" +msgstr "DigitalVideo" + +#. Programmer's name for it: SMCIMMMovie +#: Vcl/consts.pas:254 +msgid "MMMovie" +msgstr "MMMovie" + +#. Programmer's name for it: SMCIOther +#: Vcl/consts.pas:255 +msgid "Other" +msgstr "Egyéb" + +#. Programmer's name for it: SMCIOverlay +#: Vcl/consts.pas:256 +msgid "Overlay" +msgstr "Borítás" + +#. Programmer's name for it: SMCIScanner +#: Vcl/consts.pas:257 +msgid "Scanner" +msgstr "Képolvasó" + +#. Programmer's name for it: SMCISequencer +#: Vcl/consts.pas:258 +msgid "Sequencer" +msgstr "" + +#. Programmer's name for it: SMCIVCR +#: Vcl/consts.pas:259 +msgid "VCR" +msgstr "VCR" + +#. Programmer's name for it: SMCIVideodisc +#: Vcl/consts.pas:260 +msgid "Videodisc" +msgstr "Videolemez" + +#. Programmer's name for it: SMCIWaveAudio +#: Vcl/consts.pas:261 +msgid "WaveAudio" +msgstr "" + +#. Programmer's name for it: SMCIUnknownError +#: Vcl/consts.pas:262 +msgid "Unknown error code" +msgstr "Ismeretlen hibakód" + +#. Programmer's name for it: SBoldItalicFont +#: Vcl/consts.pas:264 +msgid "Bold Italic" +msgstr "Felkövér dőlt" + +#. Programmer's name for it: SBoldFont +#: Vcl/consts.pas:265 +msgid "Bold" +msgstr "Félkövér" + +#. Programmer's name for it: SItalicFont +#: Vcl/consts.pas:266 +msgid "Italic" +msgstr "Dőlt" + +#. Programmer's name for it: SRegularFont +#: Vcl/consts.pas:267 +msgid "Regular" +msgstr "Normál" + +#. Programmer's name for it: SPropertiesVerb +#: Vcl/consts.pas:269 +msgid "Properties" +msgstr "Tulajdonságok" + +#. Programmer's name for it: sWindowsSocketError +#: Vcl/consts.pas:271 +msgid "Windows socket error: %s (%d), on API '%s'" +msgstr "Windows foglalat hiba: %s (%d), on API '%s'" + +#. Programmer's name for it: sAsyncSocketError +#: Vcl/consts.pas:272 +msgid "Asynchronous socket error %d" +msgstr "" + +#. Programmer's name for it: sNoAddress +#: Vcl/consts.pas:273 +msgid "No address specified" +msgstr "" + +#. Programmer's name for it: sCannotListenOnOpen +#: Vcl/consts.pas:274 +msgid "Can't listen on an open socket" +msgstr "" + +#. Programmer's name for it: sCannotCreateSocket +#: Vcl/consts.pas:275 +msgid "Can't create new socket" +msgstr "" + +#. Programmer's name for it: sSocketAlreadyOpen +#: Vcl/consts.pas:276 +msgid "Socket already open" +msgstr "" + +#. Programmer's name for it: sCantChangeWhileActive +#: Vcl/consts.pas:277 +msgid "Can't change value while socket is active" +msgstr "" + +#. Programmer's name for it: sSocketMustBeBlocking +#: Vcl/consts.pas:278 +msgid "Socket must be in blocking mode" +msgstr "" + +#. Programmer's name for it: sSocketIOError +#: Vcl/consts.pas:279 +msgid "%s error %d, %s" +msgstr "" + +#. Programmer's name for it: sSocketRead +#: Vcl/consts.pas:280 +msgid "Read" +msgstr "" + +#. Programmer's name for it: sSocketWrite +#: Vcl/consts.pas:281 +msgid "Write" +msgstr "" + +#. Programmer's name for it: SServiceFailed +#: Vcl/consts.pas:283 +msgid "Service failed on %s: %s" +msgstr "" + +#. Programmer's name for it: SExecute +#: Vcl/consts.pas:284 +msgid "execute" +msgstr "" + +#. Programmer's name for it: SStart +#: Vcl/consts.pas:285 +msgid "start" +msgstr "" + +#. Programmer's name for it: SStop +#: Vcl/consts.pas:286 +msgid "stop" +msgstr "" + +#. Programmer's name for it: SPause +#: Vcl/consts.pas:287 +msgid "pause" +msgstr "" + +#. Programmer's name for it: SContinue +#: Vcl/consts.pas:288 +msgid "continue" +msgstr "" + +#. Programmer's name for it: SInterrogate +#: Vcl/consts.pas:289 +msgid "interrogate" +msgstr "" + +#. Programmer's name for it: SShutdown +#: Vcl/consts.pas:290 +msgid "shutdown" +msgstr "" + +#. Programmer's name for it: SCustomError +#: Vcl/consts.pas:291 +msgid "Service failed in custom message(%d): %s" +msgstr "" + +#. Programmer's name for it: SServiceInstallOK +#: Vcl/consts.pas:292 +msgid "Service installed successfully" +msgstr "" + +#. Programmer's name for it: SServiceInstallFailed +#: Vcl/consts.pas:293 +msgid "Service \"%s\" failed to install with error: \"%s\"" +msgstr "" + +#. Programmer's name for it: SServiceUninstallOK +#: Vcl/consts.pas:294 +msgid "Service uninstalled successfully" +msgstr "" + +#. Programmer's name for it: SServiceUninstallFailed +#: Vcl/consts.pas:295 +msgid "Service \"%s\" failed to uninstall with error: \"%s\"" +msgstr "" + +#. Programmer's name for it: SInvalidActionRegistration +#: Vcl/consts.pas:297 +msgid "Invalid action registration" +msgstr "" + +#. Programmer's name for it: SInvalidActionUnregistration +#: Vcl/consts.pas:298 +msgid "Invalid action unregistration" +msgstr "" + +#. Programmer's name for it: SInvalidActionEnumeration +#: Vcl/consts.pas:299 +msgid "Invalid action enumeration" +msgstr "" + +#. Programmer's name for it: SInvalidActionCreation +#: Vcl/consts.pas:300 +msgid "Invalid action creation" +msgstr "" + +#. Programmer's name for it: SDockedCtlNeedsName +#: Vcl/consts.pas:302 +msgid "Docked control must have a name" +msgstr "" + +#. Programmer's name for it: SDockTreeRemoveError +#: Vcl/consts.pas:303 +msgid "Error removing control from dock tree" +msgstr "" + +#. Programmer's name for it: SDockZoneNotFound +#: Vcl/consts.pas:304 +msgid " - Dock zone not found" +msgstr "" + +#. Programmer's name for it: SDockZoneHasNoCtl +#: Vcl/consts.pas:305 +msgid " - Dock zone has no control" +msgstr "" + +#. Programmer's name for it: SAllCommands +#: Vcl/consts.pas:307 +msgid "All Commands" +msgstr "" + +#. Programmer's name for it: SInvalidFieldSize +#: Vcl/dbconsts.pas:15 +msgid "Invalid field size" +msgstr "" + +#. Programmer's name for it: SInvalidFieldKind +#: Vcl/dbconsts.pas:16 +msgid "Invalid FieldKind" +msgstr "" + +#. Programmer's name for it: SInvalidFieldRegistration +#: Vcl/dbconsts.pas:17 +msgid "Invalid field registration" +msgstr "" + +#. Programmer's name for it: SUnknownFieldType +#: Vcl/dbconsts.pas:18 +msgid "Field '%s' is of an unknown type" +msgstr "" + +#. Programmer's name for it: SFieldNameMissing +#: Vcl/dbconsts.pas:19 +msgid "Field name missing" +msgstr "" + +#. Programmer's name for it: SDuplicateFieldName +#: Vcl/dbconsts.pas:20 +msgid "Duplicate field name '%s'" +msgstr "" + +#. Programmer's name for it: SFieldNotFound +#: Vcl/dbconsts.pas:21 +msgid "Field '%s' not found" +msgstr "" + +#. Programmer's name for it: SFieldAccessError +#: Vcl/dbconsts.pas:22 +msgid "Cannot access field '%s' as type %s" +msgstr "" + +#. Programmer's name for it: SFieldValueError +#: Vcl/dbconsts.pas:23 +msgid "Invalid value for field '%s'" +msgstr "" + +#. Programmer's name for it: SFieldRangeError +#: Vcl/dbconsts.pas:24 +msgid "%g is not a valid value for field '%s'. The allowed range is %g to %g" +msgstr "" + +#. Programmer's name for it: SInvalidIntegerValue +#: Vcl/dbconsts.pas:25 +msgid "'%s' is not a valid integer value for field '%s'" +msgstr "" + +#. Programmer's name for it: SInvalidBoolValue +#: Vcl/dbconsts.pas:26 +msgid "'%s' is not a valid boolean value for field '%s'" +msgstr "" + +#. Programmer's name for it: SInvalidFloatValue +#: Vcl/dbconsts.pas:27 +msgid "'%s' is not a valid floating point value for field '%s'" +msgstr "" + +#. Programmer's name for it: SFieldTypeMismatch +#: Vcl/dbconsts.pas:28 +msgid "Type mismatch for field '%s', expecting: %s actual: %s" +msgstr "" + +#. Programmer's name for it: SFieldSizeMismatch +#: Vcl/dbconsts.pas:29 +msgid "Size mismatch for field '%s', expecting: %d actual: %d" +msgstr "" + +#. Programmer's name for it: SInvalidVarByteArray +#: Vcl/dbconsts.pas:30 +msgid "Invalid variant type or size for field '%s'" +msgstr "" + +#. Programmer's name for it: SFieldOutOfRange +#: Vcl/dbconsts.pas:31 +msgid "Value of field '%s' is out of range" +msgstr "" + +#. Programmer's name for it: SBCDOverflow +#: Vcl/dbconsts.pas:32 +msgid "(Overflow)" +msgstr "" + +#. Programmer's name for it: SFieldRequired +#: Vcl/dbconsts.pas:33 +msgid "Field '%s' must have a value" +msgstr "" + +#. Programmer's name for it: SDataSetMissing +#: Vcl/dbconsts.pas:34 +msgid "Field '%s' has no dataset" +msgstr "" + +#. Programmer's name for it: SInvalidCalcType +#: Vcl/dbconsts.pas:35 +msgid "Field '%s' cannot be a calculated or lookup field" +msgstr "" + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/dbconsts.pas:36 +msgid "Field '%s' cannot be modified" +msgstr "" + +#. Programmer's name for it: SFieldIndexError +#: Vcl/dbconsts.pas:37 +msgid "Field index out of range" +msgstr "" + +#. Programmer's name for it: SNoFieldIndexes +#: Vcl/dbconsts.pas:38 +msgid "No index currently active" +msgstr "" + +#. Programmer's name for it: SNotIndexField +#: Vcl/dbconsts.pas:39 +msgid "Field '%s' is not indexed and cannot be modified" +msgstr "" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/dbconsts.pas:40 +msgid "Cannot access index field '%s'" +msgstr "" + +#. Programmer's name for it: SDuplicateIndexName +#: Vcl/dbconsts.pas:41 +msgid "Duplicate index name '%s'" +msgstr "" + +#. Programmer's name for it: SNoIndexForFields +#: Vcl/dbconsts.pas:42 +msgid "No index for fields '%s'" +msgstr "" + +#. Programmer's name for it: SIndexNotFound +#: Vcl/dbconsts.pas:43 +msgid "Index '%s' not found" +msgstr "" + +#. Programmer's name for it: SDuplicateName +#: Vcl/dbconsts.pas:44 +msgid "Duplicate name '%s' in %s" +msgstr "" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/dbconsts.pas:45 +msgid "Circular datalinks are not allowed" +msgstr "" + +#. Programmer's name for it: SLookupInfoError +#: Vcl/dbconsts.pas:46 +msgid "Lookup information for field '%s' is incomplete" +msgstr "" + +#. Programmer's name for it: SDataSourceChange +#: Vcl/dbconsts.pas:47 +msgid "DataSource cannot be changed" +msgstr "" + +#. Programmer's name for it: SNoNestedMasterSource +#: Vcl/dbconsts.pas:48 +msgid "Nested datasets cannot have a MasterSource" +msgstr "" + +#. Programmer's name for it: SDataSetOpen +#: Vcl/dbconsts.pas:49 +msgid "Cannot perform this operation on an open dataset" +msgstr "" + +#. Programmer's name for it: SNotEditing +#: Vcl/dbconsts.pas:50 +msgid "Dataset not in edit or insert mode" +msgstr "" + +#. Programmer's name for it: SDataSetClosed +#: Vcl/dbconsts.pas:51 +msgid "Cannot perform this operation on a closed dataset" +msgstr "" + +#. Programmer's name for it: SDataSetEmpty +#: Vcl/dbconsts.pas:52 +msgid "Cannot perform this operation on an empty dataset" +msgstr "" + +#. Programmer's name for it: SDataSetReadOnly +#: Vcl/dbconsts.pas:53 +msgid "Cannot modify a read-only dataset" +msgstr "" + +#. Programmer's name for it: SNestedDataSetClass +#: Vcl/dbconsts.pas:54 +msgid "Nested dataset must inherit from %s" +msgstr "" + +#. Programmer's name for it: SExprTermination +#: Vcl/dbconsts.pas:55 +msgid "Filter expression incorrectly terminated" +msgstr "" + +#. Programmer's name for it: SExprNameError +#: Vcl/dbconsts.pas:56 +msgid "Unterminated field name" +msgstr "" + +#. Programmer's name for it: SExprStringError +#: Vcl/dbconsts.pas:57 +msgid "Unterminated string constant" +msgstr "" + +#. Programmer's name for it: SExprInvalidChar +#: Vcl/dbconsts.pas:58 +msgid "Invalid filter expression character: '%s'" +msgstr "Hibás karakter a szűrő kifejezésben: '%s'" + +#. Programmer's name for it: SExprNoLParen +#: Vcl/dbconsts.pas:59 +msgid "'(' expected but %s found" +msgstr "%s találat, de hiányzó '('" + +#. Programmer's name for it: SExprNoRParen +#: Vcl/dbconsts.pas:60 +msgid "')' expected but %s found" +msgstr "%s találat, de hiányzó ')'" + +#. Programmer's name for it: SExprNoRParenOrComma +#: Vcl/dbconsts.pas:61 +msgid "')' or ',' expected but %s found" +msgstr "%s találat, de hiányzó ')' vagy ','" + +#. Programmer's name for it: SExprExpected +#: Vcl/dbconsts.pas:62 +msgid "Expression expected but %s found" +msgstr "%s találat, de hiányzó kifejezés" + +#. Programmer's name for it: SExprBadField +#: Vcl/dbconsts.pas:63 +msgid "Field '%s' cannot be used in a filter expression" +msgstr "'%s' mezőt nem lehet alkalmazni a szűrő kifejezésben" + +#. Programmer's name for it: SExprBadNullTest +#: Vcl/dbconsts.pas:64 +msgid "NULL only allowed with '=' and '<>'" +msgstr "Csak NULL engedélyezett '=' és/vagy '<>' -el" + +#. Programmer's name for it: SExprRangeError +#: Vcl/dbconsts.pas:65 +msgid "Constant out of range" +msgstr "Túlcsordulás" + +#. Programmer's name for it: SExprNotBoolean +#: Vcl/dbconsts.pas:66 +msgid "Field '%s' is not of type Boolean" +msgstr "'%s' mező nem Boolean típusú változó" + +#. Programmer's name for it: SExprIncorrect +#: Vcl/dbconsts.pas:67 +msgid "Incorrectly formed filter expression" +msgstr "Hibásan fogalmazott szűrő meghatározás" + +#. Programmer's name for it: SExprNothing +#: Vcl/dbconsts.pas:68 +msgid "nothing" +msgstr "semmi" + +#. Programmer's name for it: SExprTypeMis +#: Vcl/dbconsts.pas:69 +msgid "Type mismatch in expression" +msgstr "Gépelési hiba a kifejezésben" + +#. Programmer's name for it: SExprBadScope +#: Vcl/dbconsts.pas:70 +msgid "Operation cannot mix aggregate value with record-varying value" +msgstr "" + +#. Programmer's name for it: SExprNoArith +#: Vcl/dbconsts.pas:71 +msgid "Arithmetic in filter expressions not supported" +msgstr "" + +#. Programmer's name for it: SExprNotAgg +#: Vcl/dbconsts.pas:72 +msgid "Expression is not an aggregate expression" +msgstr "" + +#. Programmer's name for it: SExprBadConst +#: Vcl/dbconsts.pas:73 +msgid "Constant is not correct type %s" +msgstr "" + +#. Programmer's name for it: SExprNoAggFilter +#: Vcl/dbconsts.pas:74 +msgid "Aggregate expressions not allowed in filters" +msgstr "" + +#. Programmer's name for it: SExprEmptyInList +#: Vcl/dbconsts.pas:75 +msgid "IN predicate list may not be empty" +msgstr "" + +#. Programmer's name for it: SInvalidKeywordUse +#: Vcl/dbconsts.pas:76 +msgid "Invalid use of keyword" +msgstr "Nem megengedett kulcsszó használata" + +#. Programmer's name for it: STextFalse +#: Vcl/dbconsts.pas:77 +msgid "False" +msgstr "Hamis" + +#. Programmer's name for it: STextTrue +#: Vcl/dbconsts.pas:78 +msgid "True" +msgstr "Igaz" + +#. Programmer's name for it: SParameterNotFound +#: Vcl/dbconsts.pas:79 +msgid "Parameter '%s' not found" +msgstr "" + +#. Programmer's name for it: SInvalidVersion +#: Vcl/dbconsts.pas:80 +msgid "Unable to load bind parameters" +msgstr "" + +#. Programmer's name for it: SParamTooBig +#: Vcl/dbconsts.pas:81 +msgid "Parameter '%s', cannot save data larger than %d bytes" +msgstr "" + +#. Programmer's name for it: SParamBadFieldType +#: Vcl/dbconsts.pas:82 +msgid "Field '%s' is of an unsupported type" +msgstr "" + +#. Programmer's name for it: SAggActive +#: Vcl/dbconsts.pas:83 +msgid "Property may not be modified while aggregate is active" +msgstr "" + +#. Programmer's name for it: SFirstRecord +#: Vcl/dbconsts.pas:86 +msgid "First record" +msgstr "" + +#. Programmer's name for it: SPriorRecord +#: Vcl/dbconsts.pas:87 +msgid "Prior record" +msgstr "" + +#. Programmer's name for it: SNextRecord +#: Vcl/dbconsts.pas:88 +msgid "Next record" +msgstr "" + +#. Programmer's name for it: SLastRecord +#: Vcl/dbconsts.pas:89 +msgid "Last record" +msgstr "" + +#. Programmer's name for it: SInsertRecord +#: Vcl/dbconsts.pas:90 +msgid "Insert record" +msgstr "" + +#. Programmer's name for it: SDeleteRecord +#: Vcl/dbconsts.pas:91 +msgid "Delete record" +msgstr "" + +#. Programmer's name for it: SEditRecord +#: Vcl/dbconsts.pas:92 +msgid "Edit record" +msgstr "" + +#. Programmer's name for it: SPostEdit +#: Vcl/dbconsts.pas:93 +msgid "Post edit" +msgstr "" + +#. Programmer's name for it: SCancelEdit +#: Vcl/dbconsts.pas:94 +msgid "Cancel edit" +msgstr "" + +#. Programmer's name for it: SRefreshRecord +#: Vcl/dbconsts.pas:95 +msgid "Refresh data" +msgstr "" + +#. Programmer's name for it: SDeleteRecordQuestion +#: Vcl/dbconsts.pas:96 +msgid "Delete record?" +msgstr "" + +#. Programmer's name for it: SDeleteMultipleRecordsQuestion +#: Vcl/dbconsts.pas:97 +msgid "Delete all selected records?" +msgstr "" + +#. Programmer's name for it: SRecordNotFound +#: Vcl/dbconsts.pas:98 +msgid "Record not found" +msgstr "" + +#. Programmer's name for it: SDataSourceFixed +#: Vcl/dbconsts.pas:99 +msgid "Operation not allowed in a DBCtrlGrid" +msgstr "" + +#. Programmer's name for it: SNotReplicatable +#: Vcl/dbconsts.pas:100 +msgid "Control cannot be used in a DBCtrlGrid" +msgstr "" + +#. Programmer's name for it: SPropDefByLookup +#: Vcl/dbconsts.pas:101 +msgid "Property already defined by lookup field" +msgstr "" + +#. Programmer's name for it: STooManyColumns +#: Vcl/dbconsts.pas:102 +msgid "Grid requested to display more than 256 columns" +msgstr "" + +#. Programmer's name for it: SRemoteLogin +#: Vcl/dbconsts.pas:105 +msgid "Remote Login" +msgstr "Távoli bejelentkezés" + +#. Programmer's name for it: SDataBindings +#: Vcl/dbconsts.pas:108 +msgid "Data Bindings..." +msgstr "" + +#. Programmer's name for it: SBadPropValue +#: Vcl/oleconst.pas:15 +msgid "'%s' is not a valid property value" +msgstr "" + +#. Programmer's name for it: SCannotActivate +#: Vcl/oleconst.pas:16 +msgid "OLE control activation failed" +msgstr "Hibás OLE aktviációs parancs" + +#. Programmer's name for it: SNoWindowHandle +#: Vcl/oleconst.pas:17 +msgid "Could not obtain OLE control window handle" +msgstr "" + +#. Programmer's name for it: SVarNotObject +#: Vcl/oleconst.pas:19 +msgid "Variant does not reference an OLE object" +msgstr "" + +#. Programmer's name for it: SNoMethod +#: Vcl/oleconst.pas:21 +msgid "Method '%s' not supported by OLE object" +msgstr "" + +#. Programmer's name for it: SLinkProperties +#: Vcl/oleconst.pas:22 +msgid "Link Properties" +msgstr "Link tulajdonságok" + +#. Programmer's name for it: SInvalidLinkSource +#: Vcl/oleconst.pas:23 +msgid "Cannot link to an invalid source." +msgstr "Nem lehet hozzácsatolni érvénytelen forráshoz" + +#. Programmer's name for it: SCannotBreakLink +#: Vcl/oleconst.pas:24 +msgid "Break link operation is not supported." +msgstr "" + +#. Programmer's name for it: SLinkedObject +#: Vcl/oleconst.pas:25 +msgid "Linked %s" +msgstr "Linkelve %s" + +#. Programmer's name for it: SEmptyContainer +#: Vcl/oleconst.pas:26 +msgid "Operation not allowed on an empty OLE container" +msgstr "A művelet nem engedélyezett üres OLE tárolón" + +#. Programmer's name for it: SInvalidVerb +#: Vcl/oleconst.pas:27 +msgid "Invalid object verb" +msgstr "" + +#. Programmer's name for it: SPropDlgCaption +#: Vcl/oleconst.pas:28 +msgid "%s Properties" +msgstr "%s Tulajdonságok" + +#. Programmer's name for it: SInvalidLicense +#: Vcl/oleconst.pas:30 +msgid "License information for %s is invalid" +msgstr "Licensz információ nem megfelelő %s -hoz" + +#. Programmer's name for it: SNotLicensed +#: Vcl/oleconst.pas:31 +msgid "License information for %s not found. You cannot use this control in design mode" +msgstr "" + diff --git a/win32/gui-2/locale/hu/LC_MESSAGES/gpsbabel.po b/win32/gui-2/locale/hu/LC_MESSAGES/gpsbabel.po new file mode 100644 index 000000000..c96fa9871 --- /dev/null +++ b/win32/gui-2/locale/hu/LC_MESSAGES/gpsbabel.po @@ -0,0 +1,496 @@ +msgid "" +msgstr "" +"Project-Id-Version: GPSBabel command line program\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2008-04-27 10:58+0100\n" +"Last-Translator: Sprok Bence \n" +"Language-Team: Sprok Bence \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Hungarian\n" +"X-Poedit-Country: HUNGARY\n" + +msgid "(integer sec or 'auto') Barograph to GPS time diff" +msgstr "Barométer adatok GPS pozícióba (másodperc vagy 'auto')" + +msgid "(USR input) Break segments into separate tracks" +msgstr "Szegmensek külön nyomvonalakba vágása (USR bemenet)" + +msgid "(USR output) Merge into one segmented track" +msgstr "Szegmensek egy nyomvonalba fűzése (USR kimenet)" + +msgid "Ad-hoc closed icon name" +msgstr "Ad-hoc zárt hálózat ikonnév" + +msgid "Ad-hoc open icon name" +msgstr "Ad-hoc nyílt hálózat ikonnév" + +msgid "After output job done sleep n second(s)" +msgstr "Feltöltés után x másodperccel kikapcsolás" + +msgid "Allow whitespace synth. shortnames" +msgstr "Szóközök engedélyezése rövidnevek készítésekor" + +msgid "Altitudes are absolute and not clamped to ground" +msgstr "A magasság abszolút, nincs a felszínhez kötve" + +msgid "Append icon_descr to description" +msgstr "icon_descr hozzáfűzése a megjegyzéshez" + +msgid "Append realtime positioning data to the output file instead of truncating" +msgstr "A kimeneti fájl csonkítása helyett valósidő hozzáfűzése a pozícióhoz" + +msgid "Base URL for link tag in output" +msgstr "Alapért. URL a hivatkozásokban" + +msgid "Basename prepended to URL on output" +msgstr "URL előtag eléfűzése a kimenetben" + +msgid "Bitmap of categories" +msgstr "Raszter kategória" + +msgid "Category name (Cache)" +msgstr "Kategória név (Cache)" + +msgid "Category number to use for written waypoints" +msgstr "A készülő útpontok kategória-száma" + +msgid "Color for lines or mapnotes" +msgstr "Vonalak és térkép-megjegyzések színe" + +msgid "Command unit to power itself down" +msgstr "Zárásként a készülék kikapcsolása" + +msgid "Complete date-free tracks with given date (YYYYMMDD)." +msgstr "Dátum nélküli nyomvonalak új időpontja (ÉÉÉÉHHNN)" + +msgid "Create unique waypoint names (default = yes)" +msgstr "Egyedi útpont nevek (alapért. = igen)" + +msgid "Create waypoints from geocache log entries" +msgstr "Útpontok készítése a geocaching bejegyzésekből" + +msgid "Database name" +msgstr "Adatbázis név" + +msgid "Database name (filename)" +msgstr "Adatbázis név (fájlnév)" + +msgid "Datum (default=NAD27)" +msgstr "Térképdátum (alapért.=NAD27)" + +msgid "Days after which points are considered old" +msgstr "Ennyi nap után a pontok elévültnek számítanak" + +msgid "Decimal seconds to pause between groups of strings" +msgstr "Ennyi másodpercnyi szünet az adatfolyamban" + +msgid "Default category on output" +msgstr "Alapért. kimeneti kategória" + +msgid "Default category on output (1..16)" +msgstr "Alapértelmezett kimeneti kategória (1.. 16)" + +msgid "Default icon name" +msgstr "Alapértelmezett ikonnév" + +msgid "Default location" +msgstr "Alapértelmezett pozíció" + +msgid "Default proximity" +msgstr "Alapért. távolság" + +msgid "Default speed" +msgstr "Alapért. sebesség" + +msgid "Default speed for waypoints (knots/hr)" +msgstr "Alapértelmezett sebesség a pontokhoz (csomó/ó)" + +msgid "Degrees output as 'ddd', 'dmm'(default) or 'dms'" +msgstr "Pozíció formátum 'fff', 'fpp'(alapért.) vagy 'fpm'" + +msgid "Delete all routes" +msgstr "Minden útvonal törlése" + +msgid "Delete all track points" +msgstr "Minden nyomvonalpont törlése" + +msgid "Delete all waypoints" +msgstr "Minden útpont törlése" + +msgid "Display labels on track and routepoints (default = 1)" +msgstr "Címke megjelenítése nyomvonalakon és útvonalakon (alapért.=1)" + +msgid "Distance unit [m=metric, s=statute]" +msgstr "Távolság mértékegysége [m=metrikus, s=angolszász]" + +msgid "Do not add geocache data to description" +msgstr "Geocaching információk kihagyása a megjegyzésből" + +msgid "Do not add URLs to description" +msgstr "URL mező kihagyása a megjegyzésből" + +msgid "Don't show gpi bitmap on device" +msgstr "gpi raszter rejtése a készüléken" + +msgid "Draw extrusion line from trackpoint to ground" +msgstr "Meghosszabított vonal rajzolása útponttól felszínig" + +msgid "Drop route points that do not have an equivalent waypoint (hidden points)" +msgstr "Útvonalpont elhagyása, aminek nincs megegyező útpontja (rejtett pontok)" + +msgid "Enable alerts on speed or proximity distance" +msgstr "Figyelmeztetés engedélyezése sebességnél vagy közeledéskor" + +msgid "Encrypt hints using ROT13" +msgstr "Megjegyzések kódolása ROT13 használatával" + +msgid "Encrypt hints with ROT13" +msgstr "Megyjegyzések kódolása ROT13-al" + +msgid "Erase device data after download" +msgstr "A készülék memóriájának törlése letöltés után" + +msgid "Export linestrings for tracks and routes" +msgstr "Vonal-szöveg exportálása nyomvonalakba és útvonalakba" + +msgid "Export placemarks for tracks and routes" +msgstr "Hely-jelölések exportálása nyomvonalakba és útvonalakba" + +msgid "Full path to XCSV style file" +msgstr "Teljes elérési út a XCSV fájlban" + +msgid "Generate # points" +msgstr "# pontok készítése" + +msgid "Generate file with lat/lon for centering map" +msgstr "Szélesség/hosszúság használata térképi kalibráláshoz" + +msgid "Give points (waypoints/route points) a default radius (proximity)" +msgstr "Alapért. sugár megadása (útpontokhoz/útvonalpontokhoz)" + +msgid "GPS datum (def. WGS 84)" +msgstr "GPS dátum (alapért. WGS 84)" + +msgid "Height in pixels of map" +msgstr "Magasság a térképen (pixel)" + +msgid "Ignore event marker icons on read" +msgstr "Esemény pontok kihagyása" + +msgid "Include extended data for trackpoints (default = 1)" +msgstr "Bővített információk használata a nyomvonalakban (alapért.=1)" + +msgid "Include groundspeak logs if present" +msgstr "Groundspeak bejegyzések használata (ha van)" + +msgid "Include major turn points (with description) from calculated route" +msgstr "Fő kanyarodási pontok használata a számított útvonalból (megjegyzéssel)" + +msgid "Include only via stations in route" +msgstr "Csak az állomások használata az útvonalban" + +msgid "Include short name in bookmarks" +msgstr "Rövidnevek használata a könyvjelzőben" + +msgid "Index of name field in .dbf" +msgstr "Név mező hivatkozása a .dbf fájlban" + +msgid "Index of route (if more the one in source)" +msgstr "Útvonalak indexelése (ha több mint egy van a forrásban)" + +msgid "Index of route to write (if more the one in source)" +msgstr "Útvonalak indexelése íráshoz (ha több mint egy van a forrásban)" + +msgid "Index of route/track to write (if more the one in source)" +msgstr "Útvonalak/nyomvonalak indexelése íráshoz (ha több mint egy van a forrásban)" + +msgid "Index of track (if more the one in source)" +msgstr "Útvonalak/nyomvonalak indexelése (ha több mint egy van a forrásban)" + +msgid "Index of track to write (if more the one in source)" +msgstr "Nyomvonalak indexelése íráshoz (ha több mint egy van a forrásban)" + +msgid "Index of URL field in .dbf" +msgstr "URL mező hivatkozása a .dbf fájlban" + +msgid "Indicate direction of travel in track icons (default = 0)" +msgstr "Irány mutatása a nyomvonal ikonjánál" + +msgid "Infrastructure closed icon name" +msgstr "Zárt HotSpot ikonnév" + +msgid "Infrastructure open icon name" +msgstr "Nyitott HotSpot ikonnév" + +msgid "Keep turns if simplify filter is used" +msgstr "Fordulópontok megtartása egyszerűsítés esetén is." + +msgid "Length of generated shortnames" +msgstr "Rövidnevek hosszúsága" + +msgid "Length of generated shortnames (default 16)" +msgstr "Rövidnevek hosszúsága (alapért. 16)" + +msgid "Line color, specified in hex AABBGGRR" +msgstr "Vonal színe (hexa érték AABBGGRR)" + +msgid "Make synth. shortnames unique" +msgstr "A készülő rövidnevek egyediek legyenek" + +msgid "MapSend version TRK file to generate (3,4)" +msgstr "MapSend TRK fájl verziója (3,4)" + +msgid "Margin for map. Degrees or percentage" +msgstr "Térképi margó. Fok vagy százalék." + +msgid "Marker type for new points" +msgstr "Új pont jele" + +msgid "Marker type for old points" +msgstr "Régi pont jele" + +msgid "Marker type for unfound points" +msgstr "Meg nem talált pont jele" + +msgid "Max length of waypoint name to write" +msgstr "Útpont nevének max. hosszúsága" + +msgid "Max number of comments to write (maxcmts=200)" +msgstr "Megjegyzés max. hossza (maxcmts=200)" + +msgid "Max shortname length when used with -s" +msgstr "Rövidnév hosszának értéke -s használatával" + +msgid "Max synthesized shortname length" +msgstr "Előállított rövidnevek max. hosszúsága" + +msgid "Merge output with existing file" +msgstr "A jelenleg és a kész fájl összefűzése" + +msgid "MTK compatible CSV output file" +msgstr "MTK kompatibilis CSV készítés" + +msgid "Name of the 'unassigned' category" +msgstr "Az 'unassigned' kategória neve" + +msgid "New name for the route" +msgstr "Az útvonal új neve" + +msgid "No separator lines between waypoints" +msgstr "Nincs elválasztó karakter az útpontok között" + +msgid "No whitespace in generated shortnames" +msgstr "Szóközök mellőzése a rövidnevekben" + +msgid "Non-stealth encrypted icon name" +msgstr "Nem elcsent, titkosított ikonnév" + +msgid "Non-stealth non-encrypted icon name" +msgstr "Nem elcsent, nem titkosított ikonnév" + +msgid "Numeric value of bitrate (baud=4800)" +msgstr "Bitráta értéke (baud=4800)" + +msgid "Omit Placer name" +msgstr "Elhelyező nevének elhagyása" + +msgid "Only read turns; skip all other points" +msgstr "Csak a fordulópontok használata (a többi pont kihagyása)" + +msgid "Path to HTML style sheet" +msgstr "Hivatkozás HTML style sheet-be" + +msgid "Precision of coordinates" +msgstr "Koordináták pontossága" + +msgid "Proximity distance" +msgstr "Közelesédi riasztás értéke" + +msgid "Radius for circles" +msgstr "Kör sugara" + +msgid "Radius of our big earth (default 6371000 meters)" +msgstr "A Föld sugara (alapért. 6371000 méter)" + +msgid "Read control points as waypoint/route/none" +msgstr "Pontok beolvasása, mint útpont/útvonal/nincs" + +msgid "Read/Write date format (i.e. DDMMYYYY)" +msgstr "Dátum formátum írása/olvasása (NN/HH/ÉÉÉÉ)" + +msgid "Read/Write date format (i.e. yyyy/mm/dd)" +msgstr "Dátum formátum írása/olvasása (éééé/hh/nn)" + +msgid "Read/write GPGGA sentences" +msgstr "GPGGA montadok írása/olvasása" + +msgid "Read/write GPGSA sentences" +msgstr "GPGSA montadok írása/olvasása" + +msgid "Read/write GPRMC sentences" +msgstr "GPRMC montadok írása/olvasása" + +msgid "Read/write GPVTG sentences" +msgstr "GPVTG montadok írása/olvasása" + +msgid "Read/Write time format (i.e. HH:mm:ss xx)" +msgstr "Idő írása/olvasása (ÓÓ:pp:mm xx)" + +msgid "Retain at most this number of position points (0 = unlimited)" +msgstr "Max. pontszám megtartása a 'snail tail' előállításakor (0= végtelen)" + +msgid "Return current position as a waypoint" +msgstr "Visszatérés a jelenlegi pozícióba, mint útpont" + +msgid "Road type changes" +msgstr "Út típus változások" + +msgid "Set waypoint name to source filename." +msgstr "Útpont név szinkronizálása a forrással" + +msgid "Shortname is MAC address" +msgstr "A rövidnév, mint MAC cím" + +msgid "Speed in bits per second of serial port (baud=4800)" +msgstr "Soros port sebessége (bps; baud=4800)" + +msgid "Split input into separate files" +msgstr "Beviteli adatok darabolása külön fájlokba" + +msgid "Split into multiple routes at turns" +msgstr "Összetett útvonalakba és fordulópontokba darabolás" + +msgid "Starting seed of the internal number generator" +msgstr "Kezdőérték a belső indexhez" + +msgid "Stealth encrypted icon name" +msgstr "Titkosan kódolt ikonnevek" + +msgid "Stealth non-encrypted icon name" +msgstr "Nem titkosított ikonnevek elcsenése" + +msgid "String to separate concatenated address fields (default=\", \")" +msgstr "Összefűzött címnevek elválasztása (alapért.=\", \")" + +msgid "Suppress labels on generated pins" +msgstr "Címkék elhagyása a készülő pontokon" + +msgid "Suppress retired geocaches" +msgstr "Kiöregedett geoládák elhagyása" + +msgid "Suppress separator lines between waypoints" +msgstr "Elválasztó vonalak elhagyása útpontok között" + +msgid "Suppress use of handshaking in name of speed" +msgstr "Kézfogás elhagyása a sebességneveknél" + +msgid "Suppress whitespace in generated shortnames" +msgstr "Szóközök elhagyása a készülő rövidnevekben" + +msgid "Symbol to use for point data" +msgstr "Útpontok szimbóluma" + +msgid "Sync GPS time to computer time" +msgstr "GPS idő szinkronizálása a számítógéppel" + +msgid "Synthesize track times" +msgstr "Nyomvonal idejének előállítása" + +msgid "Target GPX version for output" +msgstr "A kimeneti GPX fájl verziója" + +msgid "Temperature unit [c=Celsius, f=Fahrenheit]" +msgstr "Hőmérséklet mértékegysége [c=Celsius, f=Fahrenheit]" + +msgid "The icon description is already the marker" +msgstr "Az ikon meghatározás már a pontjelzőben" + +msgid "Treat waypoints as icons on write" +msgstr "Útpontok ikonként való kezelése íráskor" + +msgid "Type of .an1 file" +msgstr "A .an1 fájl típusa" + +msgid "Units for altitude (f)eet or (m)etres" +msgstr "Magasság mértékegysége (méter vagy láb)" + +msgid "Units used for names with @speed ('s'tatute or 'm'etric)" +msgstr "Sebesség mértékegysége a neveknél ('s' angolszász vagy 'm' metrikus)" + +msgid "Units used when writing comments ('s'tatute or 'm'etric)" +msgstr "Mértékegység használata a megjegyzésben ('s' angolszász vagy 'm' metrikus)" + +msgid "UPPERCASE synth. shortnames" +msgstr "NAGYBETŰS rövidnevek előállítása" + +msgid "Use depth values on output (default is ignore)" +msgstr "Mélység adat használata a kimenetben (alapért. nincs)" + +msgid "Use proximity values on output (default is ignore)" +msgstr "Pontossági érték használata a kimenetben (alapért. nincs)" + +msgid "Use shortname instead of description" +msgstr "Rövid név használata a megyjegyzés helyett" + +msgid "Use specified bitmap on output" +msgstr "Meghatározott raszter használata a kimenetben" + +msgid "Version of gdb file to generate (1..3)" +msgstr "A készülő gdb fájl típusa (1..3)" + +msgid "Version of mapsource file to generate (3,4,5)" +msgstr "A készülő MapSource fájl típusa (3,4,5)" + +msgid "Waypoint background color" +msgstr "Útpont háttérszíne" + +msgid "Waypoint foreground color" +msgstr "Útpont színe" + +msgid "Waypoint type" +msgstr "Útpont típusa" + +msgid "Width in pixels of map" +msgstr "Térképi szélesség (pixel)" + +msgid "Width of lines, in pixels" +msgstr "Vonalvastagság (pixel)" + +msgid "Write additional node tag key/value pairs" +msgstr "További kulcs/érték címkepár írása (pont)" + +msgid "Write additional way tag key/value pairs" +msgstr "További kulcs/érték címkepár írása (út)" + +msgid "Write all tracks into one file" +msgstr "Az összes nyomvonal összefűzése egy fájlba" + +msgid "Write description to address field" +msgstr "Megjegyzést a cím mezőbe" + +msgid "Write each waypoint in a separate file" +msgstr "Minden útpont külön fájlba" + +msgid "Write notes to address field" +msgstr "Megjegyzés írása a cím megjegyzésbe" + +msgid "Write position to address field" +msgstr "Pozíció írása a cím megjegyzésbe" + +msgid "Write position using this grid." +msgstr "Pozíció készítése ezzel a ráccsal" + +msgid "Write timestamps with offset x to UTC time" +msgstr "Időértékek eltolása x értékkel UTC-hez képest" + +msgid "Write tracks compatible with Carto Exploreur" +msgstr "Carto Exploreur kompatibilis nyomvonal készítése" + +msgid "Write tracks for Gisteq Phototracker" +msgstr "Gisteq Phototracker kompatibilis nyomvonal készítése" + +msgid "Zoom level to reduce points" +msgstr "Zoom-szint a pontok szelektálásához" + diff --git a/win32/gui-2/main.dfm b/win32/gui-2/main.dfm new file mode 100644 index 0000000000000000000000000000000000000000..6561c8ccab00fdb09d14b5cc55a5fb142f009bf3 GIT binary patch literal 38547 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 I7%v0=54r= 0); +end; + +{ TfrmMain } + +procedure TfrmMain.RefreshDesign(FirstTime: Boolean); +begin + if not(FirstTime) then + ReTranslateComponent(SELF); + +// VS_FF_DEBUG The file contains debugging information or is compiled with debugging features enabled. +// VS_FF_INFOINFERRED The file's version structure was created dynamically; +// therefore, some of the members in this structure may be empty or incorrect. +// This flag should never be set in a file's VS_VERSION_INFO data. +// VS_FF_PATCHED The file has been modified and is not identical to the original shipping file of the same version number. +// VS_FF_PRERELEASE The file is a development version, not a commercially released product. +// VS_FF_PRIVATEBUILD The file was not built using standard release procedures. If this flag is set, +// the StringFileInfo structure should contain a PrivateBuild entry. +// VS_FF_SPECIALBUILD The file was built by the original company using standard release procedures +// but is a variation of the normal file of the same version number. +// If this flag is set, the StringFileInfo structure should contain a SpecialBuild + + if (CFixedFileinfo.dwFileFlags and VS_FF_DEBUG <> 0) then + Caption := Format('%s (%s)', [Caption, _('Internal development release')]) + else if (CFixedFileinfo.dwFileFlags and VS_FF_PRERELEASE <> 0) then + Caption := Format('%s (%s)', [Caption, _('BETA')]) + else if (CFixedFileinfo.dwFileFlags and VS_FF_PRIVATEBUILD <> 0) then + Caption := Format('%s (%s)', [Caption, _('Private release')]) + else if (CFixedFileinfo.dwFileFlags and VS_FF_SPECIALBUILD <> 0) then + Caption := Format('%s (%s)', [Caption, _('Special release')]); + + FixAlign(sbOpenFile, 8); + FixAlign(sbSaveFile, 8); + FixAlign(edInputFile, 8, sbOpenFile); + FixAlign(edOutputFile, 8, sbSaveFile); + + FixAlign(cbInputLang, 8); + btnInputOpts.Left := lbInputOpts.Left + lbInputOpts.Width + 8; + edInputOpts.Left := btnInputOpts.Left + btnInputOpts.Width + 4; + edInputOpts.Width := cbInputLang.Left - edInputOpts.Left - 4; + + FixAlign(cbOutputLang, 8); + btnOutputOpts.Left := lbOutputOpts.Left + lbOutputOpts.Width + 8; + edOutputOpts.Left := btnOutputOpts.Left + btnOutputOpts.Width + 4; + edOutputOpts.Width := cbOutputLang.Left - edOutputOpts.Left - 4; + + FixAlign(btnProcess, 8); + FixAlign(btnFilter, 16, btnProcess); + + gbInput.Caption := '>>> ' + _('Input'); + gbOutput.Caption := '<<< ' + _('Output'); + chbInputDevice.Caption := '[' + chbInputDevice.Caption + ']'; + chbOutputDevice.Caption := '[' + chbOutputDevice.Caption + ']'; + + acOptionsSourceFormat.Caption := _('Input') + ': ' + FFmtIn; + acOptionsTargetFormat.Caption := _('Output') + ': ' + FFmtOut; + + btnInputOpts.Caption := ''; + btnOutputOpts.Caption := ''; +end; + +procedure TfrmMain.FormCreate(Sender: TObject); +begin + MakeFirstTranslation(Self); + FFirstShow := True; + + RestoreBounds('main_form', Self); + + TP_Ignore(mnuDebug, 'mnuDebug'); +{$IFOPT D-} + mnuDebug.Visible := False; +{$ENDIF} + LoadLanguages; + + memoOutput.Lines.Clear; + + FCaps := TCapabilities.Create; + FOpts := TOptions.Create(FCaps); + + dlgFileOpen.InitialDir := ReadProfile(dlgFileOpen.Tag); + dlgFileSave.InitialDir := ReadProfile(dlgFileSave.Tag); + + if not ComboBoxSelect(cbInputDevice, ReadProfile(cbInputDevice.Tag)) then + cbInputDevice.ItemIndex := 0; + + if not ComboBoxSelect(cbOutputDevice, ReadProfile(cbOutputDevice.Tag)) then + cbOutputDevice.ItemIndex := 0; + + edInputFile.Text := ReadProfile(edInputFile.Tag); + + cbInputLang.ItemIndex := 0; + cbOutputLang.ItemIndex := 0; + + Application.OnIdle := Self.DoOnIdle; + + RefreshDesign(True); + HandleParams; +end; + +procedure TfrmMain.LoadLanguages; +begin + FLang := TStringList.Create; + + DefaultInstance.GetListOfLanguages('default', FLang); + if (FLang.IndexOf('en') < 0) then + FLang.Add('en'); + acFileChangeLanguage.Visible := (FLang.Count > 1); +end; + +procedure TfrmMain.LoadFileFormats; +var + l: TStrings; +begin + l := TStringList.Create; + try + + if (gpsbabel_vfmt >= '001.002.008') then + gpsbabel('-^3', l) + else if (gpsbabel_vfmt >= '001.002.005') then + gpsbabel('-^2', l) + else begin + MessageBox(0, PChar(gpsbabel_vfmt), 'Release info', MB_OK); + MessageDlg(_('The file "gpsbabel.exe" found in current directory is too old!'), + mtError, [mbOK], 0); + Halt(1); + end; + + FCaps.List := l; + FOpts.List := l; + InitCombo(cbInputFormatDevice, True, True); + InitCombo(cbOutputFormatDevice, False, True); + InitCombo(cbInputFormat, True, False); + InitCombo(cbOutputFormat, False, False); + finally + l.Free; + end; +end; + +procedure TfrmMain.FormShow(Sender: TObject); +begin + if not(FFirstShow) then Exit; + +{$IFDEF VER120} + // -------------------- + // Bug (?) Delphi4-Std./Sp3 + FixAlign(btnProcess, 8); + FixAlign(btnFilter, 16, btnProcess); + // -------------------- +{$ENDIF} + + FFirstShow := False; + PostMessage(SELF.Handle, WM_STARTUP, 0, 0); // keep sure our window is visible +end; + +procedure TfrmMain.WMSTARTUP(var Msg: TMessage); +var + s: string; +begin +// gpsbabel_ini := TIniFile.Create('gpsbabel.ini'); + LoadVersion; + EnableOptions(gpsbabel_vfmt); + LoadFileFormats; + + // ? valid README form + s := ExtractFilePath(ParamStr(0)) + 'gpsbabel.html'; + acHelpDoc.Enabled := FileExists(s); + + InitializeSerialPorts; +end; + +procedure TfrmMain.InitCombo(Target: TComboBox; IsInput, ForDevice: Boolean); +var + i: Integer; + OK: Boolean; + s: string; +begin + for i := 0 to FCaps.Count - 1 do + begin + if (ForDevice and not(FCaps.IsDevice(i))) then Continue; + if not(ForDevice) and not FCaps.IsFile(i) then Continue; + + if (IsInput) then + OK := FCaps.CanReadAny(i) + else + OK := FCaps.CanWriteAny(i); + if OK then + Target.Items.Add(FCaps.GetDescr(i)); + end; + + s := ReadProfile(Target.Tag); + ComboBoxSelect(Target, s); + + ComboBoxChanged(Target.Text, IsInput, not(ForDevice)); +end; + +procedure TfrmMain.OpenButtonClick(Sender: TObject); +var + s: string; + i: Integer; +begin + dlgFileOpen.Filter := ''; + dlgFileOpen.DefaultExt := '*.*'; + + if (cbInputFormat.Text <> '') then + s := cbInputFormat.Text + '|*.' + FCaps.GetExt(cbInputFormat.Text) + '|'; + s := s + _('All files|*.*'); + + dlgFileOpen.Filter := s; + if not SELF.dlgFileOpen.Execute then Exit; + + edInputFile.Text := ''; + for i := 0 to dlgFileOpen.Files.Count - 1 do + begin + s := dlgFileOpen.Files[i]; + if (s[1] <> '"') or (s[Length(s)] <> '"') then + s := AnsiQuotedStr(s, '"'); + if (edInputFile.Text <> '') then edInputFile.Text := edInputFile.Text + ', '; + edInputFile.Text := edInputFile.Text + s; + end; + + CheckInput; +end; + +procedure TfrmMain.ComboBoxChanged(const Format: string; IsInput, IsFile: Boolean); +var + caps: Integer; + ext: string; + ac: TAction; +begin + caps := FCaps.GetCaps(Format); + ext := FCaps.GetExt(Format); + if IsFile and FOutHandmade and (ext = '') then + begin + ext := SysUtils.ExtractFileExt(edOutputFile.Text); + if (ext <> '') and (ext[1] = '.') then Delete(ext, 1, 1); + end; + + if IsInput then + begin + FFmtIn := Format; + wptInputOK.Enabled := (caps and 1 <> 0); + trkInputOK.Enabled := (caps and 4 <> 0); + rteInputOK.Enabled := (caps and 16 <> 0); + end + else + begin + FFmtOut := Format; + wptOutputOK.Enabled := (caps and 2 <> 0); + trkOutputOK.Enabled := (caps and 8 <> 0); + rteOutputOK.Enabled := (caps and 32 <> 0); + if IsFile and (edOutputFile.Text <> '') and (edOutputFile.Text <> '-') then + begin + if (ext <> '') then FOutHandmade := False; + edOutputFile.Text := SysUtils.ChangeFileExt(edOutputFile.Text, '.' + ext); + end; + end; + + CheckInput; + + if IsInput then + begin + edInputOpts.Text := ''; + edInputOpts.Items.Clear; + + ac := acOptionsSourceFormat; + acOptionsSourceFormat.Caption := _('Input') + ': ' + Format; + btnInputOpts.Caption := ''; + end + else begin + edOutputOpts.Text := ''; + edOutputOpts.Items.Clear; + + ac := acOptionsTargetFormat; + acOptionsTargetFormat.Caption := _('Output') + ': ' + Format; + btnOutputOpts.Caption := ''; + end; + + ac.Enabled := FOpts.HasFormatOpts(Format); + if ac.Enabled then + begin + ac.Hint := SysUtils.Format(_('Select and edit options for "%s"'), [Format]); + end + else + begin + ac.Hint := SysUtils.Format(_('No options available for "%s"'), [Format]); + end; +end; + +procedure TfrmMain.edInputFileChange(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.CheckInput; +begin + acLetsGo.Enabled := + (cbWaypoints.Checked or cbRoutes.Checked or cbTracks.Checked) + and + ( + ((chbInputDevice.Checked and + (cbInputDevice.Text <> '') and + (cbInputFormatDevice.Text <> '')) + or + (not(chbInputDevice.Checked) and + (edInputFile.Text <> '') and + (cbInputFormat.Text <> ''))) + and + ((chbOutputDevice.Checked and + (cbOutputDevice.Text <> '') and + (cbOutputFormatDevice.Text <> '')) + or + (not(chbOutputDevice.Checked) and + (edOutputFile.Text <> '') and + (cbOutputFormat.Text <> ''))) + ); +end; + +procedure TfrmMain.edOutputFileChange(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.cbWaypointsClick(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.cbRoutesClick(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.cbTracksClick(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.sbSaveFileClick(Sender: TObject); +var + s: string; +begin + dlgFileSave.Filter := ''; + dlgFileSave.DefaultExt := '*.*'; + + if (cbOutputFormat.Text <> '') then + s := cbOutputFormat.Text + '|*.' + FCaps.GetExt(cbOutputFormat.Text) + '|'; + s := s + _('All files|*.*'); + + dlgFileSave.Filter := s; + if not SELF.dlgFileSave.Execute then Exit; + + edOutputFile.Text := dlgFileSave.FileName; + CheckInput; +end; + +procedure TfrmMain.acLetsGoExecute(Sender: TObject); +var + cmdline: string; + list, files: TStrings; + CSave: TCursor; + str: TStream; + s, tmp: string; + i: Integer; + IFormat, OFormat, IFiles: string; + Fatal: Boolean; + sp: PChar; + +begin + acLetsGo.Enabled := False; + try + acFinalizeDropDownsExecute(nil); + + cmdline := ''; + if gpsbabel_knows_inifile then cmdline := '-p ""'; + + if chbInputDevice.Checked then + IFormat := FCaps.GetName(cbInputFormatDevice.Text) + else + IFormat := FCaps.GetName(cbInputFormat.Text); + if chbOutputDevice.Checked then + OFormat := FCaps.GetName(cbOutputFormatDevice.Text) + else + OFormat := FCaps.GetName(cbOutputFormat.Text); + + if cbWaypoints.Checked then cmdline := cmdline + ' -w'; + if cbRoutes.Checked then cmdline := cmdline + ' -r'; + if cbTracks.Checked then cmdline := cmdline + ' -t'; + + if acOptionsSynthesizeShortNames.Checked then cmdline := cmdline + ' -s'; + + if chbInputDevice.Checked then + begin + IFiles := '-f ' + SysUtils.AnsiLowerCase(cbInputDevice.Text) + ':'; +// if (s = 'usb:') then +// s := s + '-1'; + end + else + begin + IFiles := ''; + files := TStringList.Create; + try + if (edInputFile.Text[1] <> '"') then + files.CommaText := AnsiQuotedStr(edInputFile.Text, '"') + else + files.CommaText := edInputFile.Text; + for i := 0 to files.Count - 1 do + begin + s := files.Strings[i]; + if not(FileExists(s)) then + raise eGPSBabelError.CreateFmt(_('File %s not found.'), [s]); + if (IFiles <> '') then IFiles := IFiles + ' '; + IFiles := IFiles + '-f ' + AnsiQuotedStr(s, '"'); + end; + finally + files.Free; + end; + end; + + // Input character set + + if acOptionsEnableCharactersetTransformation.Checked and + (cbInputLang.ItemIndex > 0) then + cmdline := Format('%s -c %s', + [cmdline, cbInputLang.Text]); + + if (Trim(edInputOpts.Text) <> '') then + cmdline := Format('%s -i %s,%s %s', + [cmdline, IFormat, Trim(edInputOpts.Text), IFiles]) + else + cmdline := Format('%s -i %s %s', + [cmdline, IFormat, IFiles]); + + if mnuOptionsForceDataType.Checked then + begin + s := ''; + if not(cbWaypoints.Checked) then + s := s + ',waypoints'; + if not(cbRoutes.Checked) then + s := s + ',routes'; + if not(cbTracks.Checked) then + s := s + ',tracks'; + if (s <> '') then + cmdline := Format('%s -x nuketypes%s', [cmdline, s]); + end; + + // Add filter options + + if (frmFilter <> nil) then + cmdline := cmdline + frmFilter.CmdLine; + + // Output character set + + if acOptionsEnableCharactersetTransformation.Checked and + (cbOutputLang.ItemIndex > 0) then + cmdline := Format('%s -c %s', + [cmdline, cbOutputLang.Text]); + + if (chbOutputDevice.Checked) then + begin + if (cbOutputDevice.Text = 'SCREEN') then + s := '-' + else begin + s := AnsiLowerCase(cbOutputDevice.Text + ':'); +// if (s = 'usb:') then +// s := s + '-1'; + end; + end + else begin + s := Trim(edOutputFile.Text); + if (s <> '') and (s[1] <> '"') then s := AnsiQuotedStr(s, '"'); + if (CharCount(s, '"') mod 2 <> 0) then + begin + MessageDlg(_('Invalid usage of character ''"''!'), mtError, [mbOK], 0); + Exit; + end; + sp := PChar(s); + tmp := AnsiExtractQuotedStr(sp, '"'); + if (tmp <> '') then s := tmp; + + if (s <> '-') then + begin + if FileExists(s) then + begin + if (MessageDlg(Format(_('File "%s" exists ! Overwrite ?'), [s]), + mtWarning, [mbYes, mbNO], 0) <> mrYes) then Exit; + end + else + begin + str := TFileStream.Create(s, fmCreate); + str.Free; + end; + s := AnsiQuotedStr(s, '"'); + end + else + s := '-'; + end; + + if (Trim(edOutputOpts.Text) <> '') then + cmdline := Format('%s -o %s,%s -F %s', + [cmdline, OFormat, Trim(edOutputOpts.Text), s]) + else + cmdline := Format('%s -o %s -F %s', + [cmdline, OFormat, s]); + + while (cmdline[1] = ' ') do System.Delete(cmdline, 1, 1); + + s := 'gpsbabel.exe ' + cmdline; + AddToOutput(s); + + CSave := Cursor; + list := TStringList.Create; + try + Cursor := crHourGlass; // doesn't work ??? + Application.ProcessMessages; // doesn't work ??? + Sleep(50); + + if not gpsbabel(cmdline, list, @Fatal, False) then + raise eGPSBabelError.Create(_('Could not run "gpsbabel.exe"!')); + + if (list.Count > 0) then + begin + AddToOutput(''); + AddToOutput(string(list.GetText)); + end; + + if (Fatal) then + MessageDlg(_('Sorry, gpsbabel.exe reported problems!'), mtError, [mbOK], 0) + else + MessageDlg(Format(_('Converted successfully from "%s" to "%s".'), [IFormat, OFormat]), + mtInformation, [mbOK], 0); + + finally + + Cursor := CSave; + list.Free; + + end; + + finally + acLetsGo.Enabled := True; + end; +end; + +procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean); +begin + CanClose := True; +end; + +procedure TfrmMain.acFilterSelectExecute(Sender: TObject); +begin + if (frmFilter = nil) then + Application.CreateForm(TfrmFilter, frmFilter); + if not(frmFilter.ShowModal = mrOk) then Exit; +end; + +procedure TfrmMain.AddToOutput(const Str: string); +begin + memoOutput.Lines.Add(Str); +end; + +procedure TfrmMain.AddToOutputFmt(const Format: string; + const Args: array of const); +begin + AddToOutput(SysUtils.Format(Format, Args)); +end; + +procedure TfrmMain.acFileExitExecute(Sender: TObject); +begin + PostMessage(SELF.Handle, WM_CLOSE, 0, 0); +end; + +procedure TfrmMain.LoadVersion; +var + l, l2: TStringList; + i: Integer; + s: string; + cx: PChar; + + procedure SpaceDelimited(const str: string; list: TStrings); + var + s: string; + cin, cend, cx: PChar; + begin + s := Trim(str); + cin := PChar(s); + cend := cin + StrLen(cin); + while (cin < cend) do + begin + while (cin^ = ' ') do cin := cin + 1; + cx := StrScan(cin, ' '); + if (cx = nil) then cx := cend; + cx^ := #0; + list.Add(string(cin)); + cin := cx + 1; + end; + end; + +begin + gpsbabel_major := 0; + gpsbabel_minor := 0; + gpsbabel_release := 0; + + l := TStringList.Create; + try + + try + if not gpsbabel('-p "" -V', l) then + PostMessage(Self.Handle, WM_QUIT, 0, 0); + except + on E: Exception do + begin + ShowException(E, nil); + PostMessage(Self.Handle, WM_QUIT, 0, 0); + end; + end; + + for i := 0 to l.Count - 1 do + begin + s := Trim(l.Strings[i]); + if (Copy(AnsiUpperCase(s), 1, 8) = 'GPSBABEL') then + begin + l2 := TStringList.Create; + try + SpaceDelimited(s, l2); + gpsbabel_version := l2[2]; + cx := PChar(gpsbabel_version); + gpsbabel_major := atoi(cx); + cx := StrScan(cx, '.'); + if (cx <> nil) then + begin + gpsbabel_minor := atoi(cx + 1); + cx := StrScan(cx + 1, '.'); + if (cx <> nil) then + gpsbabel_release := atoi(cx + 1); + end; + + gpsbabel_vfmt := Format('%3.3d.%3.3d.%3.3d', [ + gpsbabel_major, gpsbabel_minor, gpsbabel_release]); + + s := Format(_('GPSBabel, version %s'), [gpsbabel_version]); + stbMain.Panels[0].Text := s; + stbMain.Panels[0].Width := stbMain.Canvas.TextWidth(s) + + Trunc((Length(s)* 1.5)); + Break; + finally + l2.Free; + end; + end; + end; + + finally + l.Free; + end; +end; + +procedure TfrmMain.acHelpAboutExecute(Sender: TObject); +begin + if (frmAbout = nil) then + Application.CreateForm(TfrmAbout, frmAbout); + frmAbout.ShowModal; +end; + +procedure TfrmMain.chbInputDeviceClick(Sender: TObject); +begin + if not(Sender is TCheckBox) then Exit; + + if TCheckBox(Sender).Checked then + begin + edInputFile.Visible := False; + sbOpenFile.Visible := False; + cbInputFormat.Visible := False; + cbInputDevice.Visible := True; + cbInputFormatDevice.Visible := True; + lbInputFile.Caption := _('Port'); + FFmtIn := cbInputFormatDevice.Text; + end + else + begin + cbInputFormat.Visible := True; + cbInputFormatDevice.Visible := False; + cbInputDevice.Visible := False; + edInputFile.Visible := True; + cbInputDevice.Visible := False; + sbOpenFile.Visible := True; + lbInputFile.Caption := _('File'); + FFmtIn := cbInputFormat.Text; + end; + acOptionsSourceFormat.Caption := _('Input') + ': ' + FFmtIn; + acOptionsSourceFormat.Enabled := (FOpts.FormatOpts(FFmtIn) <> nil); + CheckInput; +end; + +procedure TfrmMain.StoreProfiles; +var + s: string; +begin + if (dlgFileOpen.Files.Count > 0) then + s := SysUtils.ExtractFilePath(dlgFileOpen.Files[0]) + else + s := SysUtils.ExtractFilePath(dlgFileOpen.FileName); + if (s <> '') then + StoreProfile(dlgFileOpen.Tag, s); + if (edOutputFile.Text = '-') then + s := dlgFileSave.InitialDir + else + s := SysUtils.ExtractFilePath(edOutputFile.Text); + if (s <> '') then + StoreProfile(dlgFileSave.Tag, s); + StoreProfile(cbInputFormat.Tag, cbInputFormat.Text); + StoreProfile(cbOutputFormat.Tag, cbOutputFormat.Text); + StoreProfile(cbInputDevice.Tag, cbInputDevice.Text); + StoreProfile(cbInputFormatDevice.Tag, cbInputFormatDevice.Text); + StoreProfile(cbOutputDevice.Tag, cbOutputDevice.Text); + StoreProfile(cbOutputFormatDevice.Tag, cbOutputFormatDevice.Text); + StoreProfile(edInputFile.Tag, edInputFile.Text); + StoreProfile(edOutputFile.Tag, edOutputFile.Text); +end; + +procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction); +begin + StoreProfiles; + StoreBounds('main_form', Self); +end; + +procedure TfrmMain.chbOutputDeviceClick(Sender: TObject); +begin + if not(Sender is TCheckBox) then Exit; + + if TCheckBox(Sender).Checked then + begin + cbOutputFormatDevice.Visible := True; + cbOutputDevice.Visible := True; + edOutputFile.Visible := False; + sbSaveFile.Visible := False; + cbOutputFormat.Visible := False; + lbOutputFile.Caption := _('Port'); + FFmtOut := cbOutputFormatDevice.Text; + end + else + begin + cbOutputFormat.Visible := True; + sbSaveFile.Visible := True; + edOutputFile.Visible := True; + cbOutputDevice.Visible := False; + cbOutputFormatDevice.Visible := False; + lbOutputFile.Caption := _('File'); + FFmtOut := cbOutputFormat.Text; + end; + acOptionsTargetFormat.Caption := _('Output') + ': ' + FFmtOut; + acOptionsTargetFormat.Enabled := (FOpts.FormatOpts(FFmtOut) <> nil); + CheckInput; +end; + +procedure TfrmMain.acHelpDocExecute(Sender: TObject); +var + s: string; +begin + s := ExtractFilePath(ParamStr(0)) + 'gpsbabel.html'; + if FileExists(s) then + WinOpenFile(s, '') // new gpsbabel.html +end; + +procedure TfrmMain.edOutputFileKeyPress(Sender: TObject; var Key: Char); +begin + FOutHandmade := True; +end; + +procedure TfrmMain.cbInputFormatDeviceChange(Sender: TObject); +begin + ComboBoxChanged(cbInputFormatDevice.Text, True, False); +end; + +procedure TfrmMain.cbOutputFormatDeviceChange(Sender: TObject); +begin + ComboBoxChanged(cbOutputFormatDevice.Text, False, False); +end; + +procedure TfrmMain.cbInputFormatChange(Sender: TObject); +begin + ComboBoxChanged(cbInputFormat.Text, True, True); +end; + +procedure TfrmMain.cbOutputFormatChange(Sender: TObject); +begin + ComboBoxChanged(cbOutputFormat.Text, False, True); +end; + +procedure TfrmMain.acOptionsSourceFormatExecute(Sender: TObject); +begin + if chbInputDevice.Checked then + HandleOptions(cbInputFormatDevice.Text, edInputOpts, True) + else + HandleOptions(cbInputFormat.Text, edInputOpts, True) +end; + +procedure TfrmMain.DoOnIdle(Sender: TObject; var Done: Boolean); +begin + inherited; + acFileClearMemo.Enabled := (memoOutput.Lines.Count > 0); + Done := True; +end; + +procedure TfrmMain.EnableOptions(const Version: string); +begin + if (Version >= '001.002.008') then + mnuOptionsForceDataType.Enabled := True; + if (version >= '001.002.007') then + acOptionsEnableCharactersetTransformation.Enabled := True; +end; + +function TfrmMain.HandleOptions(const Format: string; AObject: TObject; IsInput: Boolean): Boolean; +var + s: string; + ok: Boolean; +begin + s := GetStrProp(AObject, 'Text'); + if HandleOptionsDlg(Format, s, IsInput) then + begin + SetStrProp(AObject, 'Text', s); + Result := True; + end + else + Result := False; +end; + +function TfrmMain.HandleOptionsDlg(const Format: string; var str: string; IsInput: Boolean): Boolean; +begin + Application.CreateForm(TfrmOptions, frmOptions); + try + frmOptions.Caption := SysUtils.Format(_('Options for "%s"'), [Format]); + frmOptions.FIsInput := IsInput; + frmOptions.Opts := FOpts.FormatOpts(Format); + frmOptions.OptsStr := str; + Result := (frmOptions.ShowModal = mrOk); + if (Result) then + begin + str := frmOptions.OptsStr; + PostMessage(Self.Handle, WM_OPTIONS_CHANGED, 0, 0); + end; + finally + frmOptions.Release; + end; +end; + +procedure TfrmMain.acOptionsTargetFormatExecute(Sender: TObject); +begin + if chbOutputDevice.Checked then + HandleOptions(cbOutputFormatDevice.Text, edOutputOpts, False) + else + HandleOptions(cbOutputFormat.Text, edOutputOpts, False); +end; + +procedure TfrmMain.btnInputOptsClick(Sender: TObject); +begin + acOptionsSourceFormat.Execute; +end; + +procedure TfrmMain.acFileClearMemoExecute(Sender: TObject); +begin + memoOutput.Clear; +end; + +procedure TfrmMain.acFinalizeDropDownsExecute(Sender: TObject); +var + i, j: Integer; + c: TComponent; + cb: TComboBox; +begin + for i := 0 to ComponentCount - 1 do + begin + c := Components[i]; + if not(c is TComboBox) then Continue; + cb := Pointer(c); + if (cb.Style <> csDropDown) or (cb.Text = '') then Continue; + j := cb.Items.IndexOf(cb.Text); + if (j < 0) then + cb.Items.Insert(0, cb.Text); + end; +end; + +procedure TfrmMain.WMOPTIONSCHANGED(var Msg: TMessage); +begin + acFinalizeDropDowns.Execute; +end; + +procedure TfrmMain.acOptionsEnableCharactersetTransformationExecute( + Sender: TObject); +begin + acOptionsEnableCharactersetTransformation.Checked := not ( + acOptionsEnableCharactersetTransformation.Checked); + + cbInputLang.Enabled := acOptionsEnableCharactersetTransformation.Checked; + cbOutputLang.Enabled := acOptionsEnableCharactersetTransformation.Checked; +end; + +procedure TfrmMain.acFileOutputToScreenExecute(Sender: TObject); +begin + if (chbOutputDevice.Checked) then + begin + chbOutputDevice.Checked := False; + chbOutputDeviceClick(chbOutputDevice); + Application.ProcessMessages; + end; + + acFileOutputToScreen.Checked := not (acFileOutputToScreen.Checked); + if acFileOutputToScreen.Checked then + begin + chbOutputDevice.Enabled := False; + HistoryChanged(edOutputFile); + edOutputFile.Text := '-'; + edOutputFile.Enabled := False; + edOutputFile.Color := clInactiveBorder; + sbSaveFile.Enabled := False; + end + else + begin + edOutputFile.Color := edInputFile.Color; + chbOutputDevice.Enabled := True; + edOutputFile.Enabled := True; + edOutputFile.Text := ''; + HistoryChanged(edOutputFile, True); + sbSaveFile.Enabled := True; + end; + CheckInput; +end; + +procedure TfrmMain.HandleParams; +var + i: Integer; + s: string; +begin + for i := 1 to ParamCount do + begin + s := ParamStr(i); + if (i = 0) then + edInputFile.Text := s + else begin + if (i = 1) then + edInputFile.Items.Add(edInputFile.Text); + edInputFile.Items.Add(s); + end; + end; +end; + +procedure TfrmMain.HistoryChanged(Box: TComboBox; Swap: Boolean); +var + index: Integer; + item: string; +begin + item := Trim(Box.Text); + if (item <> '') then + begin + index := Box.Items.IndexOf(item); + if (index < 0) then + Box.Items.Insert(0, item) + else + Box.Items.Move(index, 0); + end; + if (swap and (Box.Items.Count > 1)) then + Box.ItemIndex := 1; +end; + +procedure TfrmMain.acDebugCreatePoExecute(Sender: TObject); +var + l: TStringList; + i, j, len: Integer; + s: string; + f: TFileStream; + + procedure WriteLn(Str: string); + begin + Str := Str + #13#10; + f.Write(PChar(Str)^, Length(Str)); + end; + +begin + l := TStringList.Create; + try + FOpts.DebugGetHints(l); + f := TFileStream.Create('..\gpsbabel.po', fmCreate); + try + WriteLn('msgid ""'); + WriteLn('msgstr ""'); + WriteLn(''); + + for i := 0 to l.Count - 1 do + begin + s := l.Strings[i]; + len := Length(s); + for j := len downto 1 do + begin + if (s[j] = '"') then + begin + Insert('\', s, j); + end; + end; + WriteLn('msgid "' + s + '"'); + WriteLn('msgstr ""'); + WriteLn(''); + end; + MessageDlg('..\gpsbabel.po created!', mtInformation, [mbok], 0); + finally + f.Free; + end; + finally + l.Free; + end; +end; + +procedure TfrmMain.acFileChangeLanguageExecute(Sender: TObject); +var + lang: string; + form: TForm; + title: string; +begin + Title := _('Choose language') + ' ' + _('for GUIBabelGUI'); + if SelectLanguage(Title, FLang, lang) and + (CompareText(lang, Copy(GetCurrentLanguage, 1, 2)) <> 0) then + begin + StoreProfile(11, lang); + UseLanguage(lang); + RefreshDesign; + form := frmFilter; + frmFilter := nil; + if (Form <> nil) then Form.Release; + form := frmAbout; + frmAbout := nil; + if (Form <> nil) then Form.Release; + end; +end; + +procedure TfrmMain.acFileExportCSVExecute(Sender: TObject); +const + init_dir: string = ''; + file_name: string = 'gpsbabel.csv'; +var + i, j, len: Integer; + s, lang, curr_lang: string; + o: POption; + f: TFileStream; + l: TStrings; + + function _translate(const Domain, MsgID: string): WideString; + var + i: Integer; + tmp: WideString; + boo: Boolean; + begin + tmp := MsgID; + Result := dgettext(Domain, tmp); + if (Result = tmp) then + Result := _(MsgID); + if (Result = tmp) then + Result := '' + else begin + boo := False; + i := Length(Result); + while (i >= 1) do + begin + if (Result[i] = '"') then + begin + Insert('"', Result, i); + boo := True; + end; + Dec(i); + end; + if (boo) then + begin + memoOutput.Lines.Add('Warning: ''"'' found in translation!'); + memoOutput.Lines.Add(Result); + end; + end; + end; + + procedure _line(const Prefix, MsgID: string); + begin + UniWriteLn(f, Prefix + ',"' + MsgID + '","' + + _translate(GPSBabel_Domain, MsgID) + '"'); + end; + +begin + if not SelectLanguage( + _('Choose language') + ' ' + _('for export'), + FLang, lang) then Exit; + + if (sdOptional.InitialDir = '') then + GetDir(0, init_dir); + + sdOptional.InitialDir := init_dir; + sdOptional.FileName := file_name; + + if not(sdOptional.Execute) then Exit; + + init_dir := sdOptional.InitialDir; + file_name := sdOptional.FileName; + + curr_lang := GetCurrentLanguage; + try + + UseLanguage(lang); + + f := TFileStream.Create(sdOptional.FileName, fmCreate); + try + + UniWriteLn(f, Format('code,en,%s', [lang])); + + _line('options:-w', 'Process waypoint information'); + _line('options:-r', 'Process route information'); + _line('options:-t', 'Process track information'); + + _line('options:-s', 'Synthesize shortnames'); + _line('options:-c', 'Character set for next operation'); + + + for i := 0 to FCaps.Count - 1 do + begin + if not FCaps.IsFile(i) then Continue; + + s := FCaps.GetDescr(i); + UniWrite(f, Format('format:%s,', [FCaps.GetName(s)])); + UniWriteLn(f, '"' + s + '","' + _translate(GPSBabel_Domain, s) + '"'); + + l := FOpts.FormatOpts(s); + if (l = nil) then Continue; + + for j := 0 to l.Count - 1 do + begin + o := Pointer(l.Objects[j]); + UniWrite(f, Format('format:%s:%s,', [o.format, o.name])); + UniWriteLn(f, '"' + o.hint + '","' + _translate(GPSBabel_Domain, o.hint) + '"'); + end; + end; + + finally + f.Free; + end; + + finally + UseLanguage(curr_lang); + end; +end; + +procedure TfrmMain.cbOutputDeviceChange(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.cbInputDeviceChange(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.InitializeSerialPorts; +var + port: string; + i: Integer; + config: TCommConfig; + cfsize: DWORD; +begin + for i := 1 to MAX_NO_OF_SERIAL_PORTS do + begin + port := Format('COM%d', [i]); + cfsize := sizeof(config); + if GetDefaultCommConfig(PChar(port), config, cfsize) then + begin + cbInputDevice.Items.Add(Format('COM%d', [i])); + cbOutputDevice.Items.Add(Format('COM%d', [i])); + end; + end; +end; + +procedure TfrmMain.acSelectAllExecute(Sender: TObject); +begin + memoOutput.SetFocus; + memoOutput.SelectAll; +end; + +procedure TfrmMain.acCopySelectedExecute(Sender: TObject); +begin + memoOutput.SetFocus; + memoOutput.CopyToClipboard; +end; + +procedure TfrmMain.PopupMenuPopup(Sender: TObject); +begin + pmnuSelectAll.Caption := dgettext('delphi', pmnuSelectAll.Caption); + pmnuCopySelected.Caption := dgettext('delphi', pmnuCopySelected.Caption); + pmnuClearOutput.Caption := dgettext('delphi', pmnuClearOutput.Caption); + + pmnuSelectAll.Enabled := (memoOutput.Lines.Count > 0); + pmnuCopySelected.Enabled := (memoOutput.Lines.Count > 0); + pmnuClearOutput.Enabled := (memoOutput.Lines.Count > 0); +end; + +procedure TfrmMain.acOptionsSynthesizeShortNamesExecute(Sender: TObject); +begin + acOptionsSynthesizeShortNames.Checked := not(acOptionsSynthesizeShortNames.Checked); +end; + +procedure TfrmMain.acOptionsNukeTypesExecute(Sender: TObject); +begin + acOptionsNukeTypes.Checked := not(acOptionsNukeTypes.Checked); +end; + +end. diff --git a/win32/gui-2/options.dfm b/win32/gui-2/options.dfm new file mode 100644 index 0000000000000000000000000000000000000000..e9114954d2f614314e10de207a88080ea1869eb8 GIT binary patch literal 1332 zcmb_c%Z}496m`<3&Z9HK0v4?3f^{_#U(lvgI_h*1H9=h=a8tLn>e!KE=J6N&1Y*I@ zu;(X`5F0k&*lAP2W`t&E$GPX+bI!GY`yd_9XHlG9M%M{AfAYcsAdSc8LAn-sR7k>E z={L*v6<*8Mjnztd(RytKLoQZWB=VkO=q}3*>;o0b7Ja}`Jz6&RVd2*5Z=2Vk(GrAyb#cxx5Cj)(8(Cwd|-d&>{cTQ$WFF~yA zC0LNPsn=oy;7{>=EbtA%x87+)SE0a2;;6F2bz@$V$~t&j@FWu$vry^A0!A#Pyu?s( zh+HpS^+}gP1+Tv8wHGl3KjOCxs@_CiZ%$%zhiMsOamli+{ob#duiHKWois)aQ@3D4 zE+x-(RyNR4eFe_mi%s2U^*mHrQj?ji>4;^ZyL&O8zej1 z13iZW)eRSA;GmtF3y5~}DqwH~sD+bk2Yn5wa?f_{sR{tLm%C`%5PIr7L@dM9kPh{z z{THca2;g!zSaKm74yZULm=?yMc4g3k;O#+G)4hG@zFSuw_1{_UDl7o@{(A+h$Nne) z`yc;XDw0D0<{mhqq_0NaV+`?+hYfKMBcTRU^SZv-RMYP^;w|8$Gn{iT&lgBA!Zt>h zc>=!db$zn-#=V4UjuOcWx6x+?%+q>vMF?Gq%#En;{Aor9nIt#ZJSdN0!9(xyvFbTS YtBBEiuh9>J1!8iJ nil) then + begin + SetOrdProp(Control, auto, Integer(True)); + Result := Control.BoundsRect.BottomRight; + Exit; + end; + + info := GetPropInfo(Control, 'Font'); + if (info = nil) then Exit; + + font := Pointer(GetObjectProp(Control, info)); + + info := GetPropInfo(Control, 'ParentFont'); + if (info <> nil) then + parentf := Boolean(GetOrdProp(Control, info)) else + parentf := False; + +// Controls with Caption but without AutoSize +// TCheckBox, TRadioButton + + s := TStaticText.Create(Control.Owner); + try + s.Font := font; + s.ParentFont := parentf; + s.Visible := False; + s.Parent := Control.Parent; + s.BoundsRect := Control.BoundsRect; + s.AutoSize := True; + s.Caption := ACaption; + Control.Width := 18 + s.Width; + if (Control.Height < s.Height) then + Control.Height := s.Height; + Result := Control.BoundsRect.BottomRight; + finally + s.Free; + end; +end; + +{ TfrmOptions } + +constructor TfrmOptions.Create(AOwner: TComponent); // override; +begin + inherited Create(AOwner); + TranslateComponent(Self); + FCanvas := Main.frmMain.stbMain.Canvas; + mmWarning.Lines.Add(_('Be aware, that most options are made for the output side. ')); + mmWarning.Lines.Add(_('Currently we don''t have a flag which tells us which direction is used by the options.')); +end; + +procedure TfrmOptions.SetOpts(AList: TStringList); +var + i, j: Integer; + c: TComponent; + wc: TControl; + o: POption; + chb: TCheckBox; + xy, _xy: TPoint; + xmax: Integer; + lb: TLabel; + us: string; + +begin + if (AList = nil) then Exit; + + FOpts := AList; + + xy.x := 0; + xy.y := 8; + xmax := 0; + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + + o.chb := nil; + o.edit := nil; + + if (o.dir <> 3) then + begin + if (FIsInput and (o.dir and 1 = 0)) then Continue + else if (not(FIsInput) and (o.dir and 2 = 0)) then Continue; + end; + + if (FFormat = '') then + begin + FFormat := o.format; + btnHelp.Hint := readme_html_path + '#' + FFormat; + btnHelp.ShowHint := True; + end; + + us := AnsiLowerCase(o.hint); + if FIsInput and (AnsiPos('read', us) = 0) and + ( + (AnsiPos('generate ', us) <> 0) or + (AnsiPos(' generate', us) <> 0) or + (AnsiPos('output ', us) <> 0) or + (AnsiPos(' output', us) <> 0) or + (AnsiPos('write', us) <> 0) or + (AnsiPos(' write', us) <> 0) + ) then Continue; + + chb := TCheckBox.Create(nil); + o.chb := chb; + chb.Name := '___' + o.name; + chb.OnClick := CheckBoxClicked; + chb.Tag := i + 1; + + InsertComponent(chb); + + chb.ParentFont := False; + chb.Font := pnOptions.Font; + chb.Left := 8; + chb.Top := xy.y; + _xy := SetCaption(chb, dgettext(GPSBabel_Domain, o.Hint)); + chb.Alignment := taRightJustify; +// chb.Checked := (gpsbabel_ini.ReadString(o.format, o.name, #1) <> #1); + chb.Parent := pnOptions; + + chb.Hint := SysUtils.Format(_('Short "%s"'), [o.defname]); + chb.ShowHint := True; + + if (o.format = 'xcsv') and (o.defname = 'style') then + begin + chb.Checked := True; + end; + + xy.y := xy.y + chb.Height + 8; + if (o.otype <> 4) then + if (chb.Width > xy.x) then xy.x := chb.Width; + if (chb.Width > xy.x) then + xmax := chb.Width; + + if (o.otype = 4) and (o.def <> nil) and (atoi(o.def) <> 0) then + begin + chb.AllowGrayed := True; + chb.State := cbGrayed; + end; + end; + + xy.y := 8; + xy.X := xy.X + 8; + if (xy.X < 42) then xy.X := 42; + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + o.edit := nil; + + if (o.chb = nil) then Continue; + + // ('unknown', 'integer', 'float', 'string', 'boolean', 'file', 'outfile'); + case o.otype of + 1: CreateIntegerOption(xy.X, xy.Y - 2, i + 1, o, xmax); + 2, 3: CreateStringOption(xy.X, xy.Y - 2, i + 1, o, xmax); + 4: ; + 5: CreateFileOption(xy.X, xy.Y - 2, i + 1, o, True, xmax); + 6: if not FIsInput then CreateFileOption(xy.X, xy.Y - 2, i + 1, o, False, xmax); + end; + if (o.edit <> nil) then + o.edit.Enabled := False; + xy.y := xy.y + o.chb.Height + 8; + end; + + xy.X := 0; + xy.Y := 0; + + for i := 0 to ComponentCount - 1 do + begin + c := Components[i]; + if not c.InheritsFrom(TControl) then Continue; + if (c is TPanel) then Continue; + wc := Pointer(c); + if (wc.Parent <> pnOptions) then Continue; + + j := wc.Left + wc.Width; + if (j > xy.X) then xy.X := j; + j := wc.Top + wc.Height; + if (j > xy.Y) then xy.Y := j; + if ( wc.Name = '' ) then Continue; + end; + + Self.Width := xy.X + 8 + (Self.Width - Self.ClientWidth); + Self.Height := xy.Y + 8 + + mmWarning.Height + + pnBottom.Height + + (Self.Height - Self.ClientHeight); + + i := btnCancel.Left - btnOK.Left; + btnCancel.Left := pnBottom.Width - btnCancel.Width - btnHelp.Left; + btnOK.Left := btnCancel.Left - i; + + LoadSettingsFromRegistry(); +end; + +function TfrmOptions.GetOptsStr: string; +var + i: Integer; + o: POption; + c: TComponent; + s: string; +begin + Result := ''; + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) then Continue; + + if o.chb.AllowGrayed then + begin + if (o.chb.State = cbGrayed) then Continue + end + else if not(o.chb.Checked) then Continue; + + if (Result <> '') then + Result := Result + ','; + Result := Result + o.defname; + + if (o.edit = nil) then + begin + if o.chb.Checked then + Result := Result + '=1' + else + Result := Result + '=0'; + Continue; + end; + s := GetStrProp(o.edit, 'Text'); + if (Pos(' ', s) <> 0) or (Pos('"', s) <> 0) or (Pos(',', s) <> 0) then + s := SysUtils.AnsiQuotedStr(s, '"'); + Result := SysUtils.Format('%s=%s', [Result, s]); + end; +end; + +procedure TfrmOptions.SetOptsStr(const AValue: string); +var + l: TStrings; + i, j, k: Integer; + s, name, value, name_out: string; + o: POption; + ud: TUpDown; +begin + l := TStringList.Create; + try + + try + ParseOptsLine(AValue, l); + except + on E: exception do + raise eParserError.Create(_('Invalid line format!')); + end; + + for i := 0 to l.Count - 1 do + begin + s := l.Strings[i]; + j := Pos('=', s); + if (j > 0) then + begin + name := Copy(s, 1, j - 1); + value := Copy(s, j + 1, Length(s) - j); + end + else + begin + Name := s; + Value := ''; + end; + if (name = '') then Continue; + + j := FOpts.IndexOf(name); + if (j < 0) then + raise eUnknownOption.CreateFmt(_('Unknown option "%s"!'), [name]) + else if not(FIsInput) then + begin + name_out := name + '_out'; + k := FOpts.IndexOf(name); + if (k >= 0) then + begin + name := name_out; + j := k; + end; + end; + + o := Pointer(FOpts.Objects[j]); + if (o.edit <> nil) then + begin + o.chb.Checked := True; + ud := FindUpDown(o.Edit); + if (ud <> nil) then + ud.Position := StrToInt(Value) + else + SetStrProp(o.edit, 'Text', Value); + end + else if (o.otype = 4) then + o.chb.Checked := (value = '') or (value <> '0'); + end; + finally + l.Free; + end; + FInitialOpts := GetOptsStr; +end; + +procedure TfrmOptions.CheckBoxClicked(Sender: TObject); +var + i: Integer; + c: TComponent; + chb: TCheckBox; + ctrl: TWinControl; +begin + if (Sender = nil) or not (Sender is TCheckBox) then Exit; + chb := Pointer(Sender); + + for i := 0 to ComponentCount - 1 do + begin + c := Components[i]; + if (c = chb) or not(c.InheritsFrom(TWinControl)) then Continue; + if (c.Tag <> chb.Tag) then Continue; + ctrl := Pointer(c); + ctrl.Enabled := chb.Checked; + end; +end; + +procedure TfrmOptions.CreateStringOption(const x, y, tag: Integer; o: POption; xmax: Integer); +var + ed: TEdit; +begin + ed := TEdit.Create(Self); + o.edit := ed; + + ed.Left := x; + ed.Top := y; + ed.Tag := tag; + ed.Parent := pnOptions; + + if (o.def <> nil) then + ed.Text := string(o.def); +end; + +procedure TfrmOptions.CreateIntegerOption(const x, y, tag: Integer; o: POption; xmax: Integer); +var + ed: TEdit; + cb: TComboBox; + up: TUpDown; + i: Integer; +begin + if (o.min <> nil) and (o.max <> nil) and + ((StrToInt(o.max) - StrToInt(o.min)) < 32) then + begin + cb := TComboBox.Create(Self); + o.edit := cb; + cb.Left := x; + cb.Top := y; + cb.Tag := tag; + if (cb.Left + cb.Width < xmax) then + cb.Left := xmax - cb.Width; + cb.Parent := pnOptions; + + for i := StrToInt(o.min) to StrToInt(o.max) do + cb.Items.Add(IntToStr(i)); + if (o.def <> nil) then + cb.Text := o.def + else + cb.ItemIndex := 0; + Exit; + end; + + ed := TEdit.Create(Self); + o.edit := ed; + + ed.Left := x; + ed.Top := y; + ed.Tag := tag; + ed.Parent := pnOptions; + + up := TUpDown.Create(Self); + up.Parent := pnOptions; + + ed.Width := ed.Width - up.Width; + up.Left := ed.Left + ed.Width; + up.Top := ed.Top; + if (o.min <> nil) then + up.Min := StrToInt(o.min) + else + up.Min := -(MAXSHORT-1); + if (o.max <> nil) then + up.Max := StrToInt(o.max) + else + up.Max := MAXSHORT; + if (o.def <> nil) then + up.Position := StrToInt(o.def); + up.Associate := ed; +end; + +procedure TfrmOptions.FormCreate(Sender: TObject); +begin + TranslateComponent(Self); + RestoreBounds('options_form', Self); +end; + +procedure TfrmOptions.btnHelpClick(Sender: TObject); +begin + WinOpenURL(readme_html_path + '#fmt_' + FFormat); +end; + +procedure TfrmOptions.CreateFileOption(const x, y, tag: Integer; + o: POption; IsInput: Boolean; xmax: Integer = -1); +var + ed: TEdit; + btn: TSpeedButton; +begin + ed := TEdit.Create(Self); + o.edit := ed; + + ed.Left := x; + ed.Top := y; + ed.Tag := tag; + ed.Parent := pnOptions; + + btn := TSpeedButton.Create(Self); + btn.Parent := pnOptions; + btn.Tag := tag; + ed.Width := ed.Width - btn.Width; + btn.Left := ed.Left + ed.Width; + btn.Top := ed.top; + + if IsInput then + begin + btn.OnClick := Self.OptionOpenFile; + frmMain.ImageList1.GetBitmap(15, btn.Glyph); + end + else + begin + btn.OnClick := Self.OptionSaveFile; + frmMain.ImageList1.GetBitmap(17, btn.Glyph); + end; +end; + +procedure TfrmOptions.OptionOpenFile(Sender: TObject); +var + c: TControl; + i: Integer; + o: POption; + d: TOpenDialog; +begin + if (Sender = nil) or not(Sender is TControl) then Exit; + + c := Pointer(Sender); + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) or (o.chb.Tag <> c.Tag) then Continue; + + d := TOpenDialog.Create(Self); + try + d.FileName := GetStrProp(o.edit, 'Text'); + if d.Execute then + SetStrProp(o.edit, 'Text', d.FileName); + finally + d.Free; + end; + end; +end; + +procedure TfrmOptions.OptionSaveFile(Sender: TObject); +var + c: TControl; + i: Integer; + o: POption; + d: TSaveDialog; +begin + if (Sender = nil) or not(Sender is TControl) then Exit; + + c := Pointer(Sender); + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) or (o.chb.Tag <> c.Tag) then Continue; + + d := TSaveDialog.Create(Self); + try + d.FileName := GetStrProp(o.edit, 'Text'); + if d.Execute then + SetStrProp(o.edit, 'Text', d.FileName); + finally + d.Free; + end; + end; +end; + +function TfrmOptions.ParseOptsLine(const Line: string; List: TStrings): Integer; +var + s, name, val: string; + cin, cend: PChar; + c1, c2: PChar; + ins: Boolean; +begin + List.Clear; + s := Trim(line); + while ((s <> '') and (s[Length(s)] = ',')) do SetLength(s, Length(s) - 1); + s := s + ','; + + cin := PChar(s); + cend := cin + StrLen(cin); + + while (cin < cend) do + begin + c1 := StrScan(cin, '='); + c2 := StrScan(cin, ','); + if (c1 > c2) then c1 := nil; + + if (c1 <> nil) then + begin + c1^ := #0; + name := string(cin); + val := ''; + + c1 := c1 + 1; + while (c1^ > #0) and (c1^ <= ' ') do c1 := c1 + 1; + + if (c1^ = '"') then // dequote + begin + while (c1 < cend) do + begin + c1 := c1 + 1; + if (c1^ = '"') then + begin + if ((c1+1)^ = '"') then + c1 := c1 + 1 + else + Break; + end; + val := val + c1^; + end; + c2 := StrScan(c1 + 1, ','); + end + else + begin + c2^ := #0; + val := string(c1); + end; + end + else + begin + c2^ := #0; + name := string(cin); + end; + + if (name <> '') then + begin + if (val <> '') then + list.Add(Format('%s=%s', [name, val])) + else + list.Add(name); + end; + + if (c2 = nil) then + Break + else + cin := c2 + 1; + end; + + Result := List.Count; +end; + +function TfrmOptions.FindUpDown(AControl: TControl): TUpDown; +var + i: Integer; + c: TComponent; +begin + Result := nil; + for i := 0 to ComponentCount - 1 do + begin + c := Components[i]; + if c.InheritsFrom(TUpDown) and (TUpDown(c).Associate = AControl) then + begin + Result := Pointer(c); + Exit; + end; + end; +end; + +procedure TfrmOptions.FormKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +var + str: string; +begin + if (Key <> 27) then Exit; + + str := GetOptsStr; + if (str <> FInitialOpts) then + begin + if not(MessageDlg(_('Discard changes?'), mtWarning, mbOKCancel, 0) = mrOK) then + Exit; + end; + ModalResult := mrCancel; +end; + +procedure TfrmOptions.StoreOptionsToInifile(); +var + i: Integer; + o: POption; + c: TComponent; + s, value: string; +begin +(* + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) then Continue; + + if o.chb.AllowGrayed then + begin + if (o.chb.State = cbGrayed) then + begin + gpsbabel_ini.DeleteKey(o.format, o.name); + Continue; + end; + end + else if not(o.chb.Checked) then + begin + gpsbabel_ini.DeleteKey(o.format, o.name); + Continue; + end; + + if (o.edit = nil) then + begin + if o.chb.Checked then + value := '1' + else + value := '0'; + end + else value := GetStrProp(o.edit, 'Text'); + if (o.gbdef <> nil) and (StrPas(o.gbdef) = value) then + gpsbabel_ini.DeleteKey(o.format, o.name) + else + gpsbabel_ini.WriteString(o.format, o.name, value); + end; +*) +end; + +procedure TfrmOptions.StoreOptionsToRegistry(); +var + i: Integer; + o: POption; + c: TComponent; + s, key, value: string; + r: TRegistry; +begin + r := TRegistry.Create; + try + r.RootKey := HKEY_CURRENT_USER; + if not(r.OpenKey('\Software\GPSBabel', True)) then Exit; + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) then Continue; + + key := o.format + ':' + o.name; + + if o.chb.AllowGrayed then + begin + if (o.chb.State = cbGrayed) then + begin + r.DeleteValue(key); + Continue; + end; + end + else if not(o.chb.Checked) then + begin + r.DeleteValue(key); + Continue; + end; + + if (o.edit = nil) then + begin + if o.chb.Checked then + value := '1' + else + value := '0'; + end + else value := GetStrProp(o.edit, 'Text'); + if (o.gbdef <> nil) and (StrPas(o.gbdef) = value) then + r.WriteString(key, '(default)') + else + r.WriteString(key, value); + end; + finally + r.Free; + end; +end; + +procedure TfrmOptions.LoadSettingsFromRegistry(); +var + i: Integer; + o: POption; + c: TComponent; + s, key, value: string; + r: TRegistry; + u: TUpDown; + v: Integer; +begin + r := TRegistry.Create; + try + r.RootKey := HKEY_CURRENT_USER; + if not(r.OpenKeyReadOnly('\Software\GPSBabel')) then Exit; + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) then Continue; + + key := o.format + ':' + o.name; + if not r.ValueExists(key) then Continue; + + Value := r.ReadString(key); + if (o.edit = nil) then + begin + if o.chb.AllowGrayed then + begin + if (value = '1') then + o.chb.State := cbChecked + else + o.chb.State := cbUnChecked; + end + else o.chb.Checked := True; + end + else + begin + o.chb.Checked := True; + if (value <> '(default)') then + begin + if HasUpDown(TEdit(o.edit), u) then + begin + if (o.def <> nil) then + v := StrToIntDef(o.def, 0) else + v := 0; + u.Position := StrToIntDef(value, v); + end + else + SetStrProp(o.edit, 'Text', value); + end; + o.edit.Enabled := True; + end; + end; + finally + r.Free; + end; +end; + +procedure TfrmOptions.btnOKClick(Sender: TObject); +begin +//StoreOptionsToInifile(); + StoreOptionsToRegistry(); +end; + +procedure TfrmOptions.FormClose(Sender: TObject; var Action: TCloseAction); +begin + StoreBounds('options_form', Self); +end; + +end. diff --git a/win32/gui-2/readme.dfm b/win32/gui-2/readme.dfm new file mode 100644 index 0000000000000000000000000000000000000000..3036ad2a07926f655b66e75feb1d84e4a9a5c2e1 GIT binary patch literal 687 zcmYLH!H(K65Oop~CjoYQ=w)w6y;u7SBtW-f*+j(c-r720SS%bHIbK*kpkGm`pVL3; zxpm?QE|zD;esAWz`4=OySg+Re>1;Je_wRnW2$6hoACs-B*FZNlM3>v(5w_a<=6FON zygSE#W*fcp-n+pAu$P_o{x~?L2hF4iZa?KkLQCKi3+<HDK3PF62i?)?>Y`Rw z7xk)+E~@@?{3&NI0*92RoSE)=F@uV)K)i;nO_|{5C^iE~&J&|4j+^EyD9tL$Lqf}L zTH`GWNKOUt@E{VYwX8c&Ew^Wwtfd!n_rsOjzK;_)0?%HJL^vpqPg1}Y-$9rpOdE^+ zQj2V97v^`jFfO*>?!I3a_YO~uE>bl^pYF}f#j5M7%O8wf45m*f_yJ@gc{@`aotaG;3-0fDO=+r=!wV(}ug`MO0ys<@%3 zQq>>RLw-pQRn)E$&X4Y?3EVIO`wHuvkz3O`8ZQ*N*5U*8x zoAvt9sKYq(WoGRq>#Q#mUyOt&#)*QFFZ(h$XRZikB)Dbst`5jmMATzZM_zGe+1<&0 zK)E>GaCyK&dBB3xflQ>0oL-*AH6pKa72?~Xg5(S%9s`F^!l z{!sTmx(DTUr|M<(u8P_4`AHD=#D&K$WlnAAD(0VzS{>67OXnM%?G6nm+Z`4KeI2ik zm?O`cyyr%YO4h`K+jcY5OABbxNc-t#*cpfm%SH&jd@HzQe9~gkVdxLcPgyJ<7tWKk z*PTIeD zrV(fRY^<{VdXz1e*7o^f*cX-I|4?@EG-b1gl8s_b3fUHo;09nz?1x`SR$|%Xup*=s zqX&8=K%IXCGq>;c(){~u2C=+KAmI+Bx-x7Y=_~tPOP|!4Oh4Aj+_K8hIuT8BDLRDa zSajIN>j|Q-8<0GLyJaQ2!{!lLC(l4~mxey$y1*;lji(n#>*$Q-(yNwYrNwwUIa@dm;0oK+ zcxf?r_5fE{ae7nSbez(nw77HTh&cchHRjBxu!Goc5eDQ0O388V6c30KdCmp94D(j@S*J4~ZppM2+EhVBxtlox`MJUm_Q=J4IAA lV7a>mQwj4erz;E)JxViumeo3b6OuVT8>yyGO!yZd '') then + begin + i := frmSelect.lbSelect.Items.IndexOf(str); + if (i >= 0) then + frmSelect.lbSelect.ItemIndex := i; + end; + res := frmSelect.ShowModal; + Result := (res = mrOk); + i := frmSelect.lbSelect.ItemIndex; + if Result and (i >= 0) then + Str := frmSelect.lbSelect.Items[i]; + finally + frmSelect.Release; + end; +end; + +function SelectLanguage(const Title: string; const Builtin: TStrings; var Lang: string; const Default: string = ''): Boolean; +var + i: Integer; + s, sx, sy: string; + l: TStringList; + +begin + Result := False; + + if (Default = '') then + Lang := Copy(gnugettext.GetCurrentLanguage, 1, 2); + + l := TStringList.Create; + try + l.Sorted := True; + + sy := ''; + for i := 0 to Builtin.Count - 1 do + begin + s := Builtin.Strings[i]; + if (s = '') then Continue; + + if (CompareText(s, 'de') = 0) then sx := _('German') else + if (CompareText(s, 'es') = 0) then sx := _('Spanish') else + if (CompareText(s, 'fr') = 0) then sx := _('French') else + if (CompareText(s, 'en') = 0) then sx := _('English') else + if (CompareText(s, 'hu') = 0) then sx := _('Hungarian') else + sx := '???'; + + sx := Format('%s - %s', [s, sx]); + if (CompareText(s, Lang) = 0) then sy := sx; + + l.Add(sx); + end; + + if SelectFromStringList(Title, l, sy) then + begin + Lang := Copy(sy, 1, 2); + Result := True; + end; + + finally + l.Free; + end; +end; + +{ TfrmSelect } + +procedure TfrmSelect.FormCreate(Sender: TObject); +begin + TranslateComponent(Self); + +// !!! work-arround !!! + btnOK.Caption := dgettext('delphi', 'OK'); + btnCancel.Caption := dgettext('delphi', 'Abort'); +// !!! work-arround !!! +end; + +procedure TfrmSelect.FormShow(Sender: TObject); +var + i: Integer; + s: string; + t: TLabel; +begin + t := TLabel.Create(Self); + try + + t.Caption := ''; + t.Font := lbSelect.Font; + t.ParentFont := lbSelect.ParentFont; + t.Parent := lbSelect.Parent; + + for i := 0 to lbSelect.Items.Count - 1 do + begin + s := Copy(lbSelect.Items[i], 1, 4); + while (t.Canvas.TextWidth(s) < 32) do + s := s + ' '; + s := s + Copy(lbSelect.Items[i], 5, 256); + lbSelect.Items[i] := s; + end; + + finally + t.Free; + end; +end; + +end. diff --git a/win32/gui-2/utils.pas b/win32/gui-2/utils.pas new file mode 100644 index 000000000..a6a54d11c --- /dev/null +++ b/win32/gui-2/utils.pas @@ -0,0 +1,525 @@ +unit utils; + +{ + Copyright (C) 2005-2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +} + +{ + function gpsbabel created from old gui GPSBabelGUIDialogU.pas +} + +interface + +uses + gnugettext, + Windows, SysUtils, Classes, StdCtrls, ComCtrls, + Registry, ShellAPI, Forms; + +type + PBoolean = ^Boolean; + +function gpsbabel(const CommandLine: string; Output: TStrings; + Fatal: PBoolean = nil; OEMStrings: Boolean = True): Boolean; + +function GetShortName(const PathName: string): string; + +procedure StoreProfile(const Tag: Integer; const Value: string); overload; +procedure StoreProfile(const Tag, Value: string); overload; + +function ReadProfile(const Tag: Integer; const Default: string = ''): string; overload; +function ReadProfile(const Name: string; const Default: string = ''): string; overload; + +function BackupProperties(Instance: TObject; Properties: TStrings; Backup: TStringList): Boolean; +procedure RestoreProperties(Instance: TObject; Backup: TStringList); + +procedure FixStaticText(AComponent: TComponent); + +function WinOpenFile(const AFile, AParams: string): Boolean; +procedure WinOpenURL(const AURL: string); + +procedure UniWrite(Target: TStream; const Str: WideString); +procedure UniWriteLn(Target: TStream; const Str: WideString); + +procedure MakeFirstTranslation(AComponent: TComponent); + +function readme_html_path: string; + +function HasUpDown(E: TEdit; var UpDown: TUpdown): Boolean; + +procedure StoreBounds(const Name: string; AForm: TForm); +procedure RestoreBounds(const Name: string; AForm: TForm); + +function CharCount(const Str: string; const Ch: Char): Integer; + +implementation + +uses + common; + +function GetShortName(const PathName: string): string; +var + buffer: array[0..4095] of Char; + len: DWORD; +begin + len := Windows.GetShortPathName(PChar(PathName), @buffer, sizeof(buffer)); + SetString(Result, buffer, len); +end; + +function gpsbabel(const CommandLine: string; Output: TStrings; + Fatal: PBoolean; OEMStrings: Boolean): Boolean; + +// bigger buffer_size speeds up conversion to screen + +const + BUFFER_SIZE = $20000; + +var + hRead, hWrite: THandle; + ProcessInfo: TProcessInformation; + SecurityAttr: TSecurityAttributes; + StartupInfo: TStartupInfo; + sCmd: string; + + BytesRead, BytesDone: DWORD; + buffer_string: string; + buffer: PChar; + Error: DWORD; + Wait_Result: DWORD; + s: string; + i: Integer; + +begin + Result := False; + + // strings are released automatical + // so we don't need a try/finally construct for our read buffer + + SetLength(buffer_string, BUFFER_SIZE); + buffer := PChar(buffer_string); + + if (Fatal <> nil) then Fatal^ := False; + + if (Copy(CommandLine, 1, 1) = '~') then + sCmd := System.Copy(CommandLine, 2, Length(CommandLine) - 1) + else + sCmd := SysUtils.Format('"%s" %s ', [gpsbabel_exe, CommandLine]); + + SecurityAttr.nLength := sizeof(TSECURITYATTRIBUTES); + SecurityAttr.bInheritHandle := true; + SecurityAttr.lpSecurityDescriptor := nil; + + if not CreatePipe(hRead, hWrite, @SecurityAttr, $8000) then + raise eGPSBabelError.Create(_('Error WINAPI: Could not create "NamedPipe"!')); + + try + + if not FileExists(gpsbabel_exe) then + raise eGPSBabelError.Create(_('"gpsbabel.exe" not found!!!')); + + FillChar (StartupInfo, Sizeof (StartupInfo), #0); + + StartupInfo.cb := Sizeof (StartupInfo); + StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; + StartupInfo.wShowWindow := {SW_HIDE or} SW_SHOWMINNOACTIVE; + StartupInfo.hStdInput := GetStdHandle (STD_INPUT_HANDLE); + StartupInfo.hStdOutput:= hWrite; + StartupInfo.hStdError := hWrite; + + FillChar(ProcessInfo, SizeOf(ProcessInfo), #0); + + if not CreateProcess(nil, + pchar(sCmd), nil, nil, true, CREATE_NEW_CONSOLE, // dwCreationFlags, // creation flags + nil, nil, StartupInfo, ProcessInfo) then + begin + Error := GetLastError; + raise eGPSBabelError.CreateFmt( + _('Could not run "gpsbabel.exe" (Error %d)!'), [Error]); + end; + + s := ''; + Error := 0; + + repeat + Wait_Result := WaitforSingleObject(ProcessInfo.hProcess, 10); + if PeekNamedPipe(hRead, nil, 0, nil, @BytesRead, nil) then + begin + if (BytesRead > 0) then + Application.ProcessMessages; + while (BytesRead > 0) do + begin + BytesDone := BytesRead; + if (BytesDone > (BUFFER_SIZE - 1)) then BytesDone := BUFFER_SIZE - 1; + ReadFile(hRead, buffer^, BytesDone, BytesDone, nil); + if (BytesDone > 0) then + begin + buffer[BytesDone] := #0; + if OEMStrings then + OemToCharBuff(buffer, buffer, BytesDone); + s := s + string(buffer); + Dec(BytesRead, BytesDone); + end; + end + end; + until (Wait_Result = WAIT_OBJECT_0); + + if (Error = 0) then + if not GetExitCodeProcess(ProcessInfo.hProcess, Error) then Error := 0; + + if (Error <> 0) and (Error <> 1) then + raise eGPSBabelError.CreateFmt(_('"gpsbabel.exe" returned error 0x%x (%d)'), [Error, Error]); + + Output.Clear; + while True do + begin + i := Pos(#13#13, s); + if (i <> 0) then System.Delete(s, i, 1) + else break; + end; + Output.SetText(PChar(s)); + + Result := True; + if (Fatal <> nil) then + Fatal^ := (Error = 1); + + finally + CloseHandle (hRead); + CloseHandle (hWrite); + end; +end; + +procedure StoreProfile(const Tag: Integer; const Value: string); +var + reg: TRegistry; + str: string; +begin + if (Tag <= 0) or (Tag > High(Profile)) then Exit; + + str := Profile[Tag]; + reg := TRegistry.Create; + try + reg.RootKey := HKEY_CURRENT_USER; + if reg.OpenKey('\SOFTWARE\GPSBabel', True) then + begin + reg.WriteString(str, Value); + end; + finally + reg.Free; + end; +end; + +procedure StoreProfile(const Tag, Value: string); +var + reg: TRegistry; +begin + reg := TRegistry.Create; + try + reg.RootKey := HKEY_CURRENT_USER; + if reg.OpenKey('\SOFTWARE\GPSBabel', True) then + begin + reg.WriteString(Tag, Value); + end; + finally + reg.Free; + end; +end; + +function ReadProfile(const Tag: Integer; const Default: string): string; // overload; +var + str: string; +begin + if (Tag <= 0) or (Tag > High(Profile)) then Exit; + str := Profile[Tag]; + Result := ReadProfile(str, Default); +end; + +function ReadProfile(const Name: string; const Default: string = ''): string; // overload; +var + reg: TRegistry; +begin + reg := TRegistry.Create; + try + reg.RootKey := HKEY_CURRENT_USER; + if reg.OpenKey('\SOFTWARE\GPSBabel', True) then + begin + try + Result := reg.ReadString(Name); + except + Result := Default; + end; + end; + finally + reg.Free; + end; +end; + +function BackupProperties(Instance: TObject; Properties: TStrings; Backup: TStringList): Boolean; +var + List: TStringList; +begin + List := TStringList.Create; + try + Backup.Assign(List); + finally + List.Free; + end; +end; + +procedure RestoreProperties(Instance: TObject; Backup: TStringList); +begin +end; + +procedure FixStaticText(AComponent: TComponent); +var + i, j: Integer; + c: TComponent; + s: TStaticText; +begin + j := AComponent.ComponentCount; + for i := 0 to j - 1 do + begin + c := AComponent.Components[i]; + if (c.ComponentCount > 0) then FixStaticText(c); + + if not c.InheritsFrom(TStaticText) then Continue; + + s := c as TStaticText; + if (s.BorderStyle = sbsNone) then Continue; + + if (s.Alignment = taLeftJustify) then + s.Caption := ' ' + s.Caption + else if (s.Alignment = taRightJustify) then + s.Caption := s.Caption + ' '; + end; +end; + +function WinOpenFile(const AFile, AParams: string): Boolean; +var + p: PChar; +begin + if (AParams = '') then + p := nil else + p := PChar(AParams); + Result := (ShellExecute(0, 'open', PChar(AFile), p, nil, SW_SHOW) > 32); +end; + +procedure WinOpenURL(const AURL: string); +var + i: Integer; + reg: TRegistry; + cmd: string; + prg: string; + url: string; +begin + url := AURL; + reg := TRegistry.Create; + try + reg.RootKey := HKEY_LOCAL_MACHINE; + if reg.OpenKeyReadOnly('Software\Classes\HTTP\Shell\Open\Command') then + begin + prg := reg.ReadString(''); + if (prg <> '') then + begin + i := Pos('%1', prg); + if (i <> 0) then + begin + System.Delete(prg, i, 2); + System.Insert(url, prg, i); + url := ''; + end; + + if (prg[1] = '"') then + begin + i := Pos('"', Copy(prg, 2, Length(prg))); + if (i = 0) then Exit; + cmd := Copy(prg, 2, i - 1); + Delete(prg, 1, i + 1); + prg := Trim(prg); + if (url <> '') then + begin + if (prg = '') then + prg := URL else + prg := prg + ' ' + URL; + end; + if WinOpenFile(cmd, PChar(prg)) then Exit + end + else + if (Pos(' ', prg) <> 0) then + begin + i := Pos(' ', prg); + cmd := Trim(Copy(prg, 1, i - 1)); + prg := Trim(Copy(prg, i + 1, Length(prg))); + if (url <> '') then + begin + if (prg = '') then + prg := URL + else + prg := Trim(prg) + ' ' + URL; + end; + if WinOpenFile(cmd, PChar(prg)) then Exit; + end + else + if WinOpenFile(prg, PChar(URL)) then Exit; + end; + end; + finally + reg.Free; + end; + WinOpenFile(AURL, ''); +end; + +procedure UniWrite(Target: TStream; const Str: WideString); +const + UniHeader: array[0..1] of Byte = ($FF, $FE); +var + len: Integer; +begin + if (Target.Size = 0) then Target.Write(UniHeader, SizeOf(UniHeader)); + len := Length(Str); + if (len > 0) then + Target.Write(PWideChar(Str)^, len * 2); +end; + +procedure UniWriteLn(Target: TStream; const Str: WideString); +begin + UniWrite(Target, Str); + UniWrite(Target, #13#10); +end; + +procedure MakeFirstTranslation(AComponent: TComponent); +var + lang: string; +begin +// !!! TRICK !!! + lang := GetCurrentLanguage; + UseLanguage('en'); + TranslateComponent(AComponent); + if (Copy(lang, 1, 2) <> 'en') then + begin + UseLanguage(lang); + ReTranslateComponent(AComponent); + end; +// !!! TRICK !!! +end; + +function readme_html_path: string; +begin + Result := ExtractFilePath(ParamStr(0)) + 'gpsbabel.html'; + if FileExists(Result) then + begin + while (Pos('\', Result) <> 0) do + Result[Pos('\', Result)] := '/'; + Result := 'file:///' + Result; + end + else + Result := SGPSBabelURL + '/gpsbabel.html'; +end; + +function HasUpDown(E: TEdit; var UpDown: TUpdown): Boolean; +var + i: Integer; + c: TComponent; + o: TComponent; +begin + Result := False; + o := E.Owner; + for i := 0 to o.ComponentCount - 1 do + begin + c := o.Components[i]; + if (c is TUpDown) and (TUpDown(c).Associate = E) then + begin + UpDown := TUpDown(c); + Result := True; + Exit; + end; + end; +end; + +procedure StoreBounds(const Name: string; AForm: TForm); +var + str: string; +begin + if (AForm = nil) then Exit; + + if (AForm.WindowState = wsMaximized) then str := 'Y' else str := 'N'; + str := Format('%s,%d,%d,%d,%d', [str, + AForm.Left, AForm.Top, AForm.Width, AForm.Height]); + StoreProfile(Name, str); +end; + +procedure RestoreBounds(const Name: string; AForm: TForm); +var + str: string; + idx: Integer; + lst: TStringList; + bds: TRect; +begin + if (AForm = nil) then Exit; + + str := ReadProfile(Name); + if (str = '') then Exit; + + lst := TStringList.Create; + try + lst.Sorted := False; + lst.Duplicates := dupAccept; + lst.CommaText := str; + try + AForm.Position := poDesigned; + + if (StrUpper(PChar(lst[0])) = 'Y') then AForm.WindowState := wsMaximized + else AForm.WindowState := wsNormal; + + bds.Left := StrToInt(lst[1]); + bds.Top := StrToInt(lst[2]); + bds.Right := bds.Left + StrToInt(lst[3]); + bds.Bottom := bds.Top + StrToInt(lst[4]); + + AForm.BoundsRect := bds; + + except + on E: Exception do; + end; + finally + lst.Free; + end; +end; + +function CharCount(const Str: string; const Ch: Char): Integer; +var + i, len: Integer; +begin + Result := 0; + len := Length(Str); + for i := 1 to len do + if (Str[i] = Ch) then + Inc(Result); +end; + +var + hMutex: THandle; + +initialization + + // Flag for InnoSetup + hMutex := CreateMutex(nil, True, 'GPSBabelGUI_mutex'); + +finalization + + if (hMutex <> 0) then + CloseHandle(hMutex); + +end. diff --git a/win32/gui/AboutDialogU.ddp b/win32/gui/AboutDialogU.ddp new file mode 100644 index 0000000000000000000000000000000000000000..4370276c196a7fa73d6f8917622cba1c4e033dee GIT binary patch literal 51 zcmZRVaB=ks@bJ`g@pN<#a`e>;@DB=c^Y`)e=VxGe;K0Pl$;KI)SCUzhlbT}4#=r!G E07ZHWvj6}9 literal 0 HcmV?d00001 diff --git a/win32/gui/AboutDialogU.dfm b/win32/gui/AboutDialogU.dfm new file mode 100644 index 000000000..8c0b177ce --- /dev/null +++ b/win32/gui/AboutDialogU.dfm @@ -0,0 +1,1151 @@ +object AboutBox: TAboutBox + Left = 713 + Top = 118 + BorderIcons = [] + BorderStyle = bsNone + BorderWidth = 3 + ClientHeight = 215 + ClientWidth = 316 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = True + Position = poScreenCenter + Visible = True + OnCreate = FormCreate + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object pnlOuter: TPanel + Left = 0 + Top = 0 + Width = 316 + Height = 216 + BevelInner = bvLowered + BevelWidth = 4 + Caption = 'pnlOuter' + TabOrder = 1 + end + object pnlInner: TPanel + Left = 27 + Top = 27 + Width = 262 + Height = 162 + BevelInner = bvRaised + BevelOuter = bvLowered + BevelWidth = 2 + ParentColor = True + TabOrder = 0 + object lblVersion: TLabel + Left = 121 + Top = 80 + Width = 136 + Height = 13 + Alignment = taCenter + AutoSize = False + Caption = 'Version ' + IsControl = True + end + object lblCopyright: TLabel + Left = 5 + Top = 124 + Width = 252 + Height = 13 + Alignment = taCenter + AutoSize = False + Caption = 'Copyright' + IsControl = True + end + object lblLicense: TLabel + Left = 5 + Top = 137 + Width = 252 + Height = 13 + Alignment = taCenter + AutoSize = False + Caption = 'License' + Layout = tlCenter + end + object lblProductName: TLabel + Left = 121 + Top = 38 + Width = 136 + Height = 19 + Alignment = taCenter + AutoSize = False + Caption = 'GPSBabelGUI' + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -15 + Font.Name = 'Times New Roman' + Font.Style = [fsBold, fsItalic] + ParentFont = False + end + object ProgramIcon: TImage + Left = 11 + Top = 10 + Width = 110 + Height = 110 + Picture.Data = { + 07544269746D6170C6820000424DC6820000000000003604000028000000B400 + 0000B40000000100080000000000907E0000232E0000232E0000000100000000 + 0000B3D6E000ADD5DE00A7D4E000ADCEDE00A5CEDE009FCCE000ADCCD500A6CD + D500A4C8DC009DC6DB00A5C6D60099CCCC00A5C5CE009CC4D6009DC3CE009AC0 + D4009BC5C600A9C3C40094C5C6009CBECE0094BDCE00A3BFC50094C5BD008FC2 + C2009CBDC500A7BEBD0093BDC4009CBDBE0095BDBD009AB8C4008DBEBD0094B6 + C6009DBAB6008CB5C50095BAB6009BB5BC0094B5BD008DB5BE00A3B6B5009CB5 + B50093B5B50079AEC9008BB5B50093B0BB009CB4AF0084ACC60084B4B50083AE + BC0094AEB50094B2AD008CACBD008CB2AE008CADB50099AEAD0085ACB50094AD + AD0084ADAD008CACAD007BADAD0092ACA60079A4BC008DACA60083A6B50085AA + A7008AA6AC0092A7A4007BA3B40084A4AE007CA5AD008CA5A50084A5A60073A5 + A5007BA3A6008DA39C0085A49D00799DAD008A9F9D00829EA3007B9CA500849D + 9C008B9E96007B9D9B007499A5006D9D9C00859B94007E9C95007B979C008398 + 94006699990073959D00739596007B9494006B939000738E920070928C00738C + 8C006B8C8D00628C8D005A8B8C006C8985006B848400628483005A8382005384 + 84005B7C7C00517B7B004A7B7A0051757300427373004A7271003D707000436B + 69003B6A6B00336666003A63630029585A002558580029555300215052001C4F + 4F001F4C4B00104A4A001949480011424100083A3A0000333300000000000000 + 000000ECFD0020002200C22DF80070F1FC007294F8005894F800080200001A02 + 000018A51A00080000000E0000000C0000000000000001350000100000000200 + 00003477120008771200000000002E4502000100000064AAFF00000000004300 + 00009E7512002000000040000000030000000000000020000800000000002000 + 220000ECFD000000000043000000A07512000000000000000000200000000000 + 0000A803130010A51A0000E0FD0000E0FD00E0771200A79DFB007894F800FFFF + FF00F07712001A02000008000000F0771200C22DF80070F1FC005696F8002E96 + F80000ECFD000000000001800000000000000000000000000000000000000200 + 000063003A005C00740065006D0070005C0073006800690070002E0067006900 + 66000000000000000000000000007774E80090020000E8751200F07512000800 + 00000E000000407D120020D6FF000A0000000000000000000000000000000000 + 0000000000000000000000000000000000000001000000000000407D12009720 + 650090020000000000000000000001000000A544620090020000000000000100 + 00001E456200407D1200000000000100000006734200407D1200407D120020D6 + FF00000100000A000000D0CF1100A1B11A000067610054C1CE008553000000A1 + F9000000000000000000C029F80000010000D80A600017000000A87800006C76 + 12000B0B0B1010102A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A + 2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A + 2A2A2A3F3F3F3F462A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A + 2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A + 2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A + 2A2A2A2A2A2A2A2A2A2A2A1E1E1E1E1212120B0B0B0B0B0B0B10101038383838 + 3838383838333338383838383838383838383833333838383838383838383838 + 3838333338383838383838383838383833333838383838383838333338383838 + 3838383838383838383833333838383838383838383838383333383838383838 + 3838383838383833333838383838383838383838383333383838383838383833 + 3338383838383838383838383833333838383838383838383838383333332A2A + 2A1E1E1E1212120B0B0B0B0B0B10101C3F3F3F2A2A2A2A2A2A2A2A2A2A2A2A2A + 2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A + 2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A + 2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A + 2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A + 2A2A2A2A2A2A2A2A2A2A2A2A2A3F3F3F3F3F33332A2A1C1C1212120B0B0B0B0B + 0B1212123F3F3F38383838383333383838383838383838383838333338383838 + 3838383838383833383838383838383838383838333338383838383838383838 + 3838333338383838383838383838383838383333383838383838383838383838 + 3333383838383838383838383838383333383838383838383838383838333338 + 3838383838383833333838383838383838383838383333383838383838383838 + 384646463F3F3F333333221C1C12120B0B0B0B0B0B0B1010101C1E3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F464646463F3F3F3933281C + 1C1212120B0B0B0B0B0B12121C282A3F46464646463F3F3F3F3F3F3F4646463F + 3F3F3F3F3F3F3F3F46464646463F3F3F3F3F3F3F3F3F4646463F3F3F3F3F3F3F + 3F3F46464646463F3F46463F3F3F3F3F3F3F3F3F3F4646464646463F3F3F3F3F + 3F3F4646463F3F3F3F3F3F3F3F3F46464646463F3F3F3F3F3F3F3F3F463F4646 + 463F3F3F3F3F3F3F3F3F46464646463F3F3F3F3F3F3F3F3F4646464646463F3F + 3F3F3F3F3F3F3F46464A4A4A4A3D3D3D333328281C1212120B0B0B0B0B101010 + 1C282A3838383838333338383838383838383333383838383838383838383838 + 3333383338383838383838383333383838383838383838383333383338383333 + 3838383838333338383838383838333338383838383838383333383838383838 + 3838383838383333383838383838383838383838333338383838383838383838 + 38383333383838383838383838383838383333383838383838383838384A4A3D + 3D31313122221C1C1C12120B0B0B0B0B0B1010101C222A2A38613F3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F1B1B393F3F3F3F3F3F3F3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F + 38383838383F3F3F3F3F3F3F3F3F3F3F3F39313120202019191919101010100B + 0B0B0B0B0B10101C31313D3D3D31313D3D3F31313D3D3D31313D3D3F3F3F3F3F + 3F3F3F3F46464646463F3F3F3F3F3F3F3F3F4646463F3F3F3F3F3F3F3F3F4646 + 463F3F33383838383338383846463F3F3F4646464646463F3F3F3F3F3F3F4646 + 463F3F3F3F3F3F3F3F3F46464646463F3F3F3F3F3F3F3F3F463F4646463F3F3F + 3F3F3F3F3F3F46464646463F3F3F3F3F3F3F3F3F3F3F3F3F3F4A3F3F3F3F3F3F + 3F27272727272C2C2C2C2C2C201B1B1B101010100B0B0B0B0B12121211192020 + 20202020202C1119202020202020201920352C1919192031313D3D3D31313D3D + 191B1B1B38383338383838333838381B1B1B1B0C0C1B1B1B1B1B1B1B1B1B1B1B + 0C0C0C0C00003838383833333838383838383838333338383838383838383838 + 3838333338383838383838383838383833333838383838383838383838383333 + 38383838383838383F3F3F3F3F3931313D3D31315E3B2C2C2C3B494945454545 + 313128281C1212120B0B0B0B0B0B121219191920352C19192C3F19191920352C + 19192C31313D3D3D31313D3D1920202006000600000C0C0C1B1B1B1B1B1B1B1B + 1B1B1B0C0C0C0C03060C0C0C0C0C0C0C0C0C0C0C06060606061506000600003F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F + 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F38383838 + 3831202020202020654F4F4F4F55555555554F464639392A1C1C1C120B0B0B0B + 0B1010101C281E100C1920202020202020202020202019111920202020202020 + 1919060006000006150603060C0C0C0C0C0C0C0C0C0C0C060606060303030306 + 030303030000110611060600060011061106153F3F3F3F3F3F3F3F3F46464646 + 463F3F3F3F3F3F3F3F3F4646464646463F3F3F3F3F3F3F3F3F46464646463F3F + 3F3F3F3F3F3F3F46464631313D3D31312020202020202C19192C3B415555555B + 5B5B5B5B5B51514D4D3F392A2A1C1C120B0B0B0B0B1010101C22100C07191920 + 352C19191920352C19191919191920352C19192C2C1911061106150003030003 + 0606060606060606060606030306060303030303030006110600060000201106 + 1106153131313D3D3D31313D3D3131313F3F31313D3D3D31313D3D3131313F3F + 3131313D3D3D31313D3D3131313F3F31313D3D3D31313D3D3131313F3F312020 + 202020202C19192C3B4155555563685B5B5B5B5B5B5B5B5B5B51514D4646392A + 2A1C12120B0B0B0B0B10101C1C2210101019191920352C19191920352C191919 + 1920352C19191920352C19191906000600000003030303030303030303030303 + 030303060006030300060C191106110615191920203131201119202020202020 + 2020202031312019202020202020202020203131201119202020202020202020 + 2031312019202020202020202020203131202C19192C3B415B5B5B5B5B5B5B5B + 5B5D5D5D5D5B5B5B5B5B5B5B5B5B51514646382A2A1E17120B0B0B0B0B121212 + 1C222828283D45455B656550505049495054545454545050505045352C2C4149 + 491106110615060603030003060603030303000603030011060C0600002C452C + 19191920352C191941413B3B19191920352C19192C3B4141413B3B191920352C + 19192C3B4141413B3B19191920352C19192C3B4141413B3B191920352C19192C + 3B4141413B3B4F5B5B5B5D5D5D5D5D5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B + 5B5B51514646382A2A1E12120B0B0B0B0B0B12121C2833333D454A4A4F4F4F50 + 5050505050505454545450505050494141414950505050504920110C06000006 + 150C06000600000C0600002C2C2C455B4D4D4D4D4D4D4D4D4E4E4E4E4E4E5959 + 4F3B3B4A55554F4F5A60606064646464645F5F5F4F3737454F4F454F5B5B4519 + 19223F4F3B222222394F4F493B3B494F412C3B4F5B5B5B5B5B5B5F5F5F5B5B5B + 5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B51514646382A2A1C1C12 + 0B0B0B0B0B1010101C28333D3D45494950505050505050505050545454545450 + 50505050505050505050505049412C2C455B201135201106110615412C2C455B + 5B5B5B5B5B5B5B5B5B5B5B5B5B5D5D5D5D5D5D5D5D5D5D5F6364646464646565 + 65656464645F5F5F5F55555D5D5D5A5A5A56463B3B4D565656564D4D565D5D5D + 5B5B5B5B4F4F5B5D5D5D5D5F5F5F5D5D5D5B5B5D5D5D5D5D5D5D5D5D5D5D5D5D + 5B5B5B5B5B5B5B5B5B5B5B51514638332A1E17120B0B0B0B0B1010101C223333 + 3D454C4C50505050505054545450505050505050505054545454545454545450 + 505054505050412C49412C2C2C2C455B5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F63 + 636364646464646464646465656565656564646464646464635F5F5F5F5F5F5F + 5F5A5A5A5A565656565A5D5D5D5D5D5D5D5D5D5F5F5F5F5D5D5D5D5D5D5D5D5D + 5D5D5D5D5D5D5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5D5D5D5D5D5D5D5B5B5B51 + 514638332A1E17120B0B0B0B0B10101C1C2233333D45454C4C4C545454545454 + 5454545454545454545454545454545454545454545450505054545454545454 + 50505B5B5D5D5D5D5D5D5F5F5F5F5F5F5F5F5F5F636464646464646464656565 + 6565646464646464646464635F5F5F5F5F5D5B5B5B5B5B5B5A5A5A5D5D5D5D5D + 5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5F5F5F5F5F5D + 5D5D5D5D5B5B5B5B5B5B565656564D4D4D4D46393934342A1C1C12120B0B0B0B + 0B1212121C2233333D3D49495454545454545454545454545454545454545454 + 5454545454505050505050505054545457575757575B5D5F5F5F5F5F5F5F5F5F + 5F5F5F5F5F5F5F5F63646464656565646464646464646464646464646464645F + 5F5D5D5D5D5B5B5B5B5B5B5B5D5D5D5D5D5D5D5D5B5B5B5B5B5B5D5D5D5D5D5D + 5D5D5D5D5D5D5D5D5D5D5D5B51515D5D5D5D5D5B55555B554A3D454530302318 + 181818181818180C0C0C1C1C1010100B0B0B0B0B0B1212121C22333345454A4A + 5454545454545454545454545454545454545454545454545454545454545454 + 54545457575757575B5B5D5F5F5F5F5F5F5F5F5F5F6363636363636363646464 + 646464646464646464646464646464646464635F5F5D5D5D5D5D5D5F5F5F5D5D + 5D5D5D5A5A5A5A5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D564D + 4D4D554F4F4F4F454A4A4A452820201D0E15150C0C0C0C0C0C0C0C0C0C102222 + 1C1212120B0B0B0B0B1010101C1C33333D454A4A545454545454545454545454 + 54545454545454545454545454545B575757505050505757575757575D5D5D5F + 5F5F5F5F5F5F5F5F636363646464646464646464646464646464646464646464 + 64646464645F5F5F5F5F5D5D5D5D5F5F5F5F5A5A5A5D5D5D5D5D5F5F5F5F5F5F + 5F5B5B5B5B5F5F5D5D5D5B5B5B5B55554C4039394545454545454545454A4A37 + 23282824181119202015151520201515151C22221C1C12120B0B0B0B0B0B1212 + 1C1C33333D3D4A4F4F4F57575757575754545454545454545454545454545454 + 545B5B57575454545454545454545B5B5F6363635F5F5F636363636363646464 + 6464646464646464646464646464646464646464646464645F5F5F5F5F5F5D5D + 5D5F5F5F5D5D5D5D5F5F5F5F5F5F5F5F5F5F5F5D5B5B5B5B5B5B5B554F4F4F4C + 4C393939303030373B414141454545454545452824343E342719273937202020 + 20201B1B1B2222221C1C12120B0B0B0B0B0B12121C1C28333939454A4A4F5757 + 57575757575757575757575757575454545454545B5B5B4F5757575757575B5B + 5B5B5F5F5F5F5F5F636363646464646464646464646464646464646464646464 + 646464646464646464645F5F5F5D5D5D5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F + 5F5F5F5F5B5B5B5555564E4E4E4E45453B3B3B3B352727272731313D3D454545 + 454545453740391B1B2F3E34271928453B262626261B1B1B2222221C1C101010 + 0B0B0B0B0B1010101C1C2833333945454C4C4F54545454545454545457575757 + 57575754545454545B5B574F54545454545B5B5B5B5F5F59525252595D636464 + 64646464646464646565656565656464646464646464646464646464635F5F5F + 5F5F5F5F5F5F5F5F5F5F5F5F5F5D5D5D5D5D5D5B5B5B5B5B4F4F454A4A3E3E3E + 3E343535353541372727272727373D3D3D3D3D3D3D454537372828281D2F2F2B + 1B1B2737372626261B1B1B282828281C1C1010100B0B0B0B0B1010101C1C2828 + 37373D45454C4C4C4C4C4C4F4F4F4F4F4F57575757575757575757575B5B5454 + 545454545B5B5B5952525242424242525A646464646464646464646464646464 + 6464646464646464646464636363636363636363635F5F5F5F5F5F5F5F5F5F5F + 5D5A5B5B5B5B5B4F4F4F4F4F45454545402F3E3E3E24273B3B3B3B2727272727 + 3737454545453B3B3B3B3030301A1A34342F2F2323232327262626261B1B3028 + 2828281C1C1010100B0B0B0B0B0B12121C1C282839394545454549494949494C + 4C4C4C4C4C4F4F57575757575757575B5B5B5457575757575B594B3C3C3C3C4B + 5D5D52595D646464646464646464646464646464646464646464646464646464 + 64646464646363635F5F5F5F60606060605D5D5D5B515151464545454A4A4A4A + 4F4F4F45342F2F3E3418233B3B3728283527273745454545453B3B3B3B3B2828 + 341F1F3232322B2020202026262C2C2C2C3131313128281C1C1010100B0B0B0B + 0B0B12121C1C282837373D45454549494949494949494949494F4F4F57575757 + 5757575B5B575757575B4E4B4B4B3C3C42424B5A63635F5F5F5F636363646464 + 646464646464646464646464645F6364646464646464635F5F5F5F5F5F5F5F60 + 60605D5D564F4F4F45454545454545454A4A4A4F4F4F4F392F2F2F3E30151B37 + 302327272727313B3B3B3B3B3B373737373728283424181F2D2D282020202626 + 2C2C2C2C373737373728281C1C1C10100B0B0B0B0B0B10101C1C282837374141 + 4141494945454545494949494949494F4F4F57575757575B5B4F4F575B4E3C29 + 293C3C4B52595D5F63636363635F5F5F5F5F6363636464646464646464646464 + 645D5D6464646464605F5F5F5F636363635F5F5B5B554C453B3B4A4A4A45454F + 4F4A4A4A4A4F4F4F4F4F45342F2F3E4334181828232323232330373737373737 + 373737373730301A1A1A1A212D322326262626262C2C2C2C282828282828281C + 1C12120B0B0B0B0B0B0B10101C1C222231313B3B414141414141414545454545 + 454545454C4F4F4F4F4F4F5B5B57574E3C29293C3C3C3C525A5F636363646464 + 6363636363635F5F5F5F5F636364646464646464645D5D646464646464646060 + 5D5D5A564D4D4D4545453B373D4A4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F3D34 + 2D2F3E3E3931241D1D27272727373737373737373737373730302B1A0E0E1F2D + 2F2B1B262626262C272727282828282828281B1B1B12120B0B0B0B0B0B0B1010 + 1C1C222231313B414141414141414141414145454545454C4C4C4C4C4C4F5B5B + 5B5B563C3C3C4B595952595D5F636363636363636363636363636363635F5F5F + 5F636363636363635F5F5F646464635F5F5F55392434343425303B3737373737 + 454F4F4F4F4A4A4A4A45454F4F4F4F4F4F4539322D3E3E4037371C0E1B272727 + 273737373737373737372727272424241A0E142D3E2319262626262626262C2C + 2C37373727271B1B1B12120B0B0B0B0B0B0B10101C1C22282837373B41414141 + 414141414145454545454C4C4C4C4C4C4C4F5B55555D5D59595D5D5F5F5F5F64 + 64646464636363636364646464636364646464636363636360606060605B5B5A + 5A5A514D4D4D3B15030E212121373B3B3B3B3B4545454545454545454545454D + 4D4D4D4D4545393E3E3E43373737241823232323313737373737373737272727 + 23243434240E143C321B1B262727272727273137373737272020201C1C10100B + 0B0B0B0B0B0B10101C1C22282837373B3B4141414141414141454545454C4C4C + 4F4F4F4F4F4F5B5B5B5F5F5F6363635F5F5D5B5D606063636363636464646464 + 646464636363636363635F5F5F5D5D5D5D5643434B4D45454545350C03081F25 + 34393B3B3B3B454545454545454545454545454D4D4D4D454545342F3E3E403B + 3B302B28282828283737373737373737372727231D2534341D0D213C2B191926 + 2C2C2020273737373737272020201C1C1010100B0B0B0B0B0B0B10101C1C2228 + 31313B3B4145454545454545454545454F4F4F4F4F4F4F45454F5B5F5F5F5F5F + 5F5D5D564D404040464D4D56565B5D5D5D5B5B5B5B5B5B5B5656565B5B5B5B5B + 55554D4D4D4D3E3E3E4645454545310C0303133239393B3B3B45454545454545 + 454545454545454D4D4D4D454545362D3E434039342525282828282837374545 + 372C373727271B18181A25250A092D3E2323232C2C2626273737373737272727 + 27271C1C1010100B0B0B0B0B0B0B1010101C222831313B3B4145454545454545 + 4545454A4A4A4A4A4A4545454A5D5D5D5D5B5B5B5B4F45393030303025303737 + 37414545453B393939394046464646564D454545454539394646424242464545 + 4545350C0303031834393939454545454546464646463D3D454545454D4D4646 + 4545362F2F43342B212128282828373737374C4C353535352727180E0E25250E + 04143C341920202020202037373737372626262727221C1C1010100B0B0B0B0B + 0B0B1010101C222831313B3B414545454141414141454A4A45454F4F45454545 + 4F5D5D5D5D5D564F453730303037372525303737373B3B3B3B3B454545454545 + 4545454E453737454545393946442F3E464545454545370C0303030318304040 + 464646464646464645453B45454545464646454545403E2F3636321F1F343737 + 28283939373746403030302727230E0D1F34340D08213C2B1927272727272737 + 373737272727272722221C1C1010100B0B0B0B0B0B0B1010101C222831313B41 + 41414141414141414C4C45454C4C454545453B45565D5D5D5B4D373737373030 + 30303025253939454545454545454545454545454545454D453B3B4A4A4A3939 + 4D442F3E4D4D49494949370C01040101061830404D4D4D4D4D4D4D453B3B3B45 + 4545454545454545393936323232212121343728283737393939434337372727 + 271808081F341F070D2D3E272727272727373737372C2626262C2C2323231C1C + 1010100B0B0B0B0B0B0B10101C1C222831313B3B414141414141454545454545 + 4A454545454543424B4E403940463B3535353537373739393945454545454539 + 39393941414141414141454545454545453939433E3E3E46464F4F45454C370C + 010401010A18243040404D4D4D4D453B3B3B4545454545454545453434323232 + 3232212134393024303B3B3939393737373727271B0E0408242B0F030F293E27 + 2727272727373737372626262C2C232322221B1B1010100B0B0B0B0B0B0B1010 + 1C1C282831313B3B41414141414C4A4A4A45454545454D4D4B422F2F39392B28 + 3745454537374545453939363639393930303030373741414141414141414141 + 41393945453434362D2D434A454D4D4A4A4A3B15030303080D18182424344046 + 46393030394545454545453934342B2B21212525252525253437271A25404039 + 37373737372727271808040D32320A08143C3427272727273039393527272727 + 27271B1B281B1B1B1B10100B0B0B0B0B0B0B10101C1C222831313B4141414145 + 454545454545454D4D4D4D443E323437373737373745454D4545454539302525 + 252537373737373741414141414141414141414141373745331C2B2F293C4B46 + 39394F4F4F49411B0303080D0D1D242424243636251F1F1F343443393939321F + 1F1F1F1F1F25252525252532343023233436363636393B3B2C2727230E04040F + 211F0A0A2D2F30262626273739393527262626151B1B2323231B1B1B1010100B + 0B0B0B0B0B0B1010101C1C282837373B3B4145454545454545454B4B56564039 + 39393D3D3D40404040373745453B3737371D1D21212130303737414141414141 + 4141414141414141413737403424323C3C423E34343434464F4C412706060D0D + 14212121212525130D0F141F2532323232321F1F1F1F1F1F1F2B2B2B2B323232 + 30302323393934252532404027272718040408131F1F13142D34272727273740 + 403527262626261515232323231B1B1B1010100B0B0B0B0B0B0B1010101C1C28 + 282837373B454C4C45454646464444445B5B4537414145393939373030303030 + 3939353535180E2121213037373B414141414141414141414141414137373734 + 34403E29423E212121212134464639280E0A0A0E1A1F1F1F1F1F0A03080D0D1F + 32321F1F25251F1F1F1F2525252525323232323234301D1D4040372824242121 + 2B2B2B0C0303080E24342D292D302626263740403526262626262C2323232320 + 20201B1B1010100B0B0B0B0B0B0B1010101C1C1C28282839454F4F46464B4242 + 4234344A5B4F4539393939302424303030303030303D3D3D3D1D0A142525303B + 3B3B3B414141414141414141414141413739343232432F2D3E32131F32212121 + 34433424180A0D1A1A1A1A1A1A0A010103030C1F251D1D1D251F1F1F1F1F1F2B + 2B2B2B343421213434281818343939373727130F213632140D04040D32432F2D + 2F3019233745453526262626262C2723232323232323231B1010100B0B0B0B0B + 0B0B1010101C1C1C1C2828454D4D4D4343433636333337454545373737372828 + 1C2430303030303030304545391D0A0D1F252537414141414141454545414141 + 414141413936323236362D2D3E1F0E252525252525343425180E1F1F1F1F1F1F + 080101010103131F1313131F1F14141F1F1F2B34342B2B323232323230241D1D + 3437373737371B152436362D140909142F34212D34231B374645352626262626 + 2C271B232827202020201B1B1010100B0B0B0B0B0B0B1010101C1C1C28284046 + 4843343434343737282828282828282828282828283428282323282828303939 + 301D0E040A1F25343B3B3B3B3B3B45454541414141413934343221323E3E2D42 + 3E0E08252525252525253434281A25251A21210801010101010E1F0E0A131313 + 1313131F1F1F2B2B2B32323232323232342418182439393737272727271D1D21 + 140F1F2F342B2F3E2B1B2745452C272727272727271B1B2828272727271B1B1B + 1010100B0B0B0B0B0B0B1010101C1C2834343E3E252428283737373724242427 + 272727272727272730343423232323303030242434280E02020A1325343B3B3B + 3B3B3B3B3B3B3B3B393934323232323236362D42340A0A252525252525252546 + 46282525251F0902010101010714140A0A131313131313131F1F2B2B2B2B3232 + 323232323928180E1830303030272731280708130A0414322B343E3218183745 + 3527272727272727271B283527272727271B1B101010100B0B0B0B0B0B0B1010 + 101A1A2A2A1A1A2424243030303030301B1B282828282828282828282834342B + 2B30303030242424393918040404040D1D2B3939393939393939303434342532 + 32323232362F2F422B030834342525252525344F4F392424240D010101010101 + 0F1408040D0D0D08080D0D131F2424242432323232323232392B0E0E0E232837 + 2C2727301801040D0D0D0D0D0F3E3E242424373727272727272727271B243030 + 27272727271B1B101010100B0B0B0B0B0B0B1010101A1A252512182828282828 + 282828281B1D2B28282828282828282839393232322B2B242424242437453007 + 02020208080D141F1F2B3232323232323225323232323232362F2F3E18010A34 + 342525252525404F4F4F2A1F0D0101020202020D140D040408080803030A0A13 + 1F2424242424243232323232391D0E0E0A0A28372C2C37280A03030414322815 + 0D2534342424302626272727272727182430302727272727271B1B1B1010100B + 0B0B0B0B0B0B101010101C1C1C1C1C3030282828282727271D1D2B2B27272727 + 2730303030343232322B242424243030303B3B18020404040404080D0D141F21 + 212121252525323232323232362F3E3E0C000D343425252525344A4A4A4F380E + 01010101010108140D0404090908010104040A1D242424242424243232323232 + 2B180F0F03031D283535351803030309142B3B30141F34391D24403427272727 + 27271D24343737373737372727271B1B1010100B0B0B0B0B0B0B101010101C1C + 1C1C282828282727272727271B1A303027272727303030303939252525253030 + 303037373737372B0A0202020202020808080F141F1F1F252532323232323232 + 362F42400C000D323232252534464F4F4F4F460E010101010108140F04040909 + 0902020202020A1D1F1F1F1F1F1F25323232323224180D030007070C3045280C + 03030D21232339433E3E464023233E3E3E302727271B1B303027273030303027 + 271B1B1B1B10100B0B0B0B0B0B0B101010101C1C1C2828282828272727272727 + 1B1B30302727272730302730393925252534393737373737373737371D040404 + 0404040404040A0D141F1F32323232323232323232324B400C010A2B2B2B2B2B + 404D4D4D4D4545300A02020202141408020809090401010101040E1D1D131313 + 1F1F1F2B2B2B2B342B130400010A03031D39270A0A0F1F1B27404D4D4E4E4E43 + 39272734343434342323282827272727272727271B1B1B1B1010100B0B0B0B0B + 0B0B0B1010101C1C1C2424243030303030282828232330272727272727272730 + 39393232323037373737373737373737370E040404040404040404080D131F25 + 2525323232323232323E4E390C000A3232242B40464D4D4D453B3B4523040101 + 0D140D020409090901010101010A18180D0A0E0E1F1F1F25252525342B0A0000 + 0404000A131D1D0C0D212B1924424E4E4E4E4E4E43392C26232B343434343027 + 272727272727271B1B1B1B1B1010100B0B0B0B0B0B0B0B101010101C1C282828 + 2828282828282828282828282727272730303030393932322B2B2B2B30303030 + 3737373737240E040404020202040404040A131F1F1F25252525253236444D37 + 0C00082525253646464F4F4545453745450E02090F0F04040404090401010101 + 0813130A03080A13131F1F1F2B2B2B361F0100020202020C0C0C0E0E14242727 + 2B2F424E4E4E4E4E4E4E433027272324344343372727272727271B1B1B1B1B1B + 1010100B0B0B0B0B0B0B0B101010101C1C242823232828282828282828283434 + 2727272727272730393934252528282828282828282837373728180D04020202 + 0202020202020A131F1F25323232323236434D370C01081F3434434D4D4D4545 + 4545453034340E0E0E080408080808020101010413130A0101080A13131F1F1F + 1F2525362403000404010A0A0A0A13141F1F273737303E4B4334343440404039 + 30271B24303034344037272727271B1B1B1B1B1B1010100B0B0B0B0B0B0B0B10 + 1010101C1C1C2823232828272727273728283434282727272731313139393425 + 2B2B2B2B2B2B2B2B3737373737371B1309020202020404040404040A13131F25 + 32323232324345370C010A1F3939464D4D454545454530242440401A09040808 + 080802010101010A130D010101030A0E0E1F1F1F1F1F25362B07010303070E08 + 08080D131F1F1F303030434B3E1B1B2737373737271D1D282828282834404040 + 2727271B1B1B1B101010100B0B0B0B0B0B0B0B101010101C1C1C28281D243027 + 27273030272734343430302C2C37373737392B2B303030303030303037373737 + 373D37180E08020202040404040404040A0A141F32323232324040370E020D25 + 464D4D4D4545454545371D1D25404F390E040909090401010101041313020202 + 0203030A13131F1F1F1F1F32320E0000040D0D010808080E0E0E141F24344B4E + 341B2727373737271D1D283737272727273039393939271B1B1B1B101010100B + 0B0B0B0B0B0B0B101010101C1C1C28281D2430272727303027272B3434343430 + 303939373739342530303030303030303737373737374527130D040102020504 + 02020202020A131F1F322525253445370E040E344D4D4D4545454545451B151F + 34404A4A30130D0D0801010101010F1408010101010101080E0E1F1F1F1F1F1F + 341300000D0D030308080808080F0F14141F32362B2323373737271D1D283737 + 3727272727272727392B2B2B231B1B101010100B0B0B0B0B0B0B0B101010101C + 1C1C28281B1B3428282828372823283432323234343434373739343428283030 + 3030303030303737373745341B130A01010404040202020404040A131F252525 + 253434300E08254D564D393941454545300C15243945454545391D0A04040101 + 010D140D02010101010101030A131F1F1F1F1F1F321801041308000404040401 + 010A0E141414141F1F1F24303030231D273737272727272727272723231D1D28 + 281C1C101010100B0B0B0B0B0B0B0B101010101C2424243023182B3030272737 + 3727273434253232323230303939342B2B313030303131313131313939392B2B + 2B27130401010404040404040404040A1321212525323428181A46564D34343D + 3D3D45451506153446453737454A4018040404010A1F0E020202020201010101 + 0A131F1F1F1F1F1F251F0A0A0A0101080808020000030A0F141F1F1F1F1F1F25 + 34241D2B3737372B2B2B2B2B2B2B2B242424242424241B1B1010100B0B0B0B0B + 0B0B0B1010101C1C1C1C1C302318213434282828373728343434343434343431 + 3139343030303037373737373737373737231F25393B28180701010505020202 + 020202080E1F25323232343434434D4D3424343D3D3D3D2806031540463D3D3D + 3D4646371B0E08081318030101010101010101010A141F1F1F1F1F1F1F251D0A + 0301040404040101010103080F141F1F1F1F1F1F25252B2B3232323232322121 + 21212121242427271B1B1B1B1010100B0B0B0B0B0B0B0B1010101C1C1C282828 + 2818143634342B2B373727303934342B2B2B2B35354034343030303737373737 + 3737373723182134373737372408020404040404040404040A141F2525253434 + 464D341A2525343B3B453B1503031839393939393939454537231818180D0401 + 01010103030303030D131F1F1F1F1F1F1F2B1F07010108080802010101010108 + 0E141F1F1F1F1F1F2B342B21212121212121212121212B2B27272727271B1B1B + 1010100B0B0B0B0B0B0B0B1010101C1C1C28282828150E343434343434303030 + 3934323232323030303934343131373737373737373737371518213437373737 + 391804040404040404040404080E1F1F2525323446390A0A252539414145370C + 030A1834393939393939394545372B2B1D0E0D04040403030303030A0F0F141F + 1F1F1F1F1F251F0701080404040101010101010813131F1F1F1F1F1F34341F1F + 1F1F1F1F1F1F1F1F2430302727272727271B1B1B1010100B0B0B0B0B0B0B0B10 + 10101C1C1C282828281B0C253432323232322B2B3434342B2B2B2B3535393930 + 30303030373737373737371B0C1F25303030303737371B070404040404040404 + 0808131F25252534340E01082434394141452706031313153745393939393939 + 45372424241313130A0D0D0D0D0D0D131414141F1F1F1F1F1F321F0A03080404 + 04010404040404080A13131F1F1F1F343424242424242424241F1F3230302727 + 27272727271B1B1B1010100B0B0B0B0B0B0B0B1010101C1C1C28282837230A1F + 3632323232322B2B30343425252530303039393030303030303030303737270C + 0C1F253030373737374545280C04040404040404080808131F1F1F322B0A0008 + 1F343741414115030E180A062345393939373737402B2B2B37241D1313131313 + 131314141414141F1F1F1F1F1F252513080808080404040403030303080D131F + 1F1F34342B2B2B2B2B2B1F1F1F1F32303027272727272727271B1B1B1010100B + 0B0B0B0B0B0B0B1010101C1C1C28282837280C0D323232323232282837392B2B + 2B343030303939303030313131313137373715030A1F32393737373737374545 + 30130A08040404080808080D141F1F25251803031434394149370C0C1F0A0101 + 18394539373737372B2525373737372514141313131313131414141F1F1F1F1F + 1F1F321F0A0A0D080404040101010303030A13131F1F1F1F1F252525251F1F1F + 1F32302727272727272727271B1B1B1B1010100B0B0B0B0B0B0B0B1010101C1C + 1C28282837370C04253434323232303030393425253437373739393030303131 + 3131313131270C030A18343937373737373737454537231308080808080D0D0D + 131F1F1F25240C031334394141270C1313010108081B4545373737281A243939 + 394545403221141414141414141414141F1F1F1F1F1F2525130D080401010101 + 01010101010813131F1F131F1F1F25252525252525302727272727272323231B + 1B1B1B1B1010100B0B0B0B0B0B0B101010101C1C1C1C2828283718011A343434 + 343430303039342B2B34373737373939283030303030303037150303030C3039 + 3737373737373737454545301D0E0E0E0E0E131313131F1F1F321D0A13403D3D + 3D23180F03000404040A23404545301D1D244545454545464B43251A14141414 + 14141414141F1F1F1F1F1F321F080202010101010101010101030D1F1F1F1F1F + 1F242424242424322B272727272723232323231B1B1B1B101010100B0B0B0B0B + 0B0B101010101C1C1C282828283723030E343434343430303039393434343737 + 373739392828282828282837270C010303032439393037373737373739464545 + 402514131313131313131F1F1F3232180E34454545280E0400030A040404061D + 3D30242418283D4545454544444E4D34251F1F14141F1F1F1414141F1F1F1F25 + 250C0104040101010101010101030D1F251F1F1F1F2424242424322B2B202323 + 232323232323231B1B1B1B101010100B0B0B0B0B0B0B101010101C1C1C1C2828 + 2837300A0325342B2B2B2B313131393434343737373739393030303030303037 + 2306010101010E303B3737373737373737404641402F2F2B1F1313141414141F + 1F2525250E1F404545240701010A04040A0A010618181839393937374D464342 + 4B4D4D4D45302414141F1F1F1F1414141F1F1F1F251D03030303030303010101 + 010313241F1F1F1F1F1F2B2B2B2B2B2B2727272723232327272727271B1B1B1B + 1010100B0B0B0B0B0B0B0B1010101C1C1C1C28282837370E010E323232323030 + 3030393434343737373739393131303030303030150303030303081D37373737 + 37373737373D4646433C4E4E341F14141F1F1F1F1F1F25251F1F404A451D0303 + 08080308080303030A0E243939393939434E4E4E4E4E4646453737241F1F1F1F + 1F141F1F1F1F1F1F1F2B0C010101010303010101010A181F141F1F1F1F1F2B2B + 2B2B2B27272727272727272727272727271B1B1B1010100B0B0B0B0B0B0B1010 + 10101C1C1C242430303030180108253434343437282839343434343131313939 + 31313030303037270C0101010103030D2B393737373737373737464E4E4B5656 + 5640241F1F1F1F1F1F1F1F252525404F390C03030A030308030303080A0A1824 + 3037343E4E4E4E4E4E434343393930303030241F14141F1F1F1F1F1F1F251D03 + 0101010104040401030C1313131F1F1F1F1F1F25252B27272727272727272727 + 27272727271B1B1B1010100B0B0B0B0B0B0B101010101C1C1C24243030303030 + 03011F3434343431313131393434343131313939372730303030392306010101 + 0303030A142B373737373737404D4E4E4E4E4E4E4E463930241F1F1F1F1F1F25 + 2525344023060A0E08030A0A0100030A0A0A0A0A1D373E3C4E4E4B4B4B4B4D4D + 4040373737373734241F1F1F1F1F1F1F1F1F2B1803000000020202020D0D0D0D + 141F1F1F1F2525252B2B2727272727272C2C2C2727272727271B1B1B1010100B + 0B0B0B0B0B0B10101010101C1C1C2430303030300C000D343434343030303039 + 3934303030303040372727303737371503030202020208080814303937373730 + 3E52524B4B4E4E4E4E4D454139301F1F1F1F1F1F2525253415030A130A0A0A01 + 01010808030A030308182B3E4B4B4B4E4E4E4E4E4E464040373737372B1D1313 + 13141F1F1F1F25250E0301010101010A0E0A0A0E1F1F1F1F1F1F1F2530353535 + 3535353535353535352C272727271B1B1B10100B0B0B0B0B0B0B0B101010101C + 1C1C1C28282828281801011F3434343030303039393430303030304037272730 + 3037370C0303030303030808080A1F34393937302F4B524E4E4E4E4E4E4E4D4D + 454539241F1F1F1F1F2525251D0C06060E0E080000080801080801010408131F + 2F424B4B4343434E4E4646392834404030241D0E0E14141F1F1F1F2B2B0E0303 + 0301040A0A03030E1F1F1F1F1F1F25253035373737373737372C2C2C2C2C2C2C + 27271B1B1B10100B0B0B0B0B0B0B0B101010101C1C1C1C28282828282807000D + 34343430272727393939393030303040392C2C303030230A0302020202020202 + 02080F1F2B343939303E4B4B4E4E4E4E4E4E4E4E46454545342B2B1F1F1F1F25 + 25250C060C0E0A0308080404040101010104040D1F2F3E3E2424404640404034 + 34393939303024180E04040F1F1F1F1F32240C030303080A0300030D141F1F1F + 1F32322B272727272737373737272C2C2C2C2C272727221C1C1010100B0B0B0B + 0B0B0B101010101C1C28282828373730300E01041F3634342727273040403430 + 303030393935303030301B03030303040404040404040D0D142434393737434B + 4B3E3E3E46464646464541414141302B2B1F1F1F252525180A030A0E0E040108 + 040001010103030A1314212124243939393939303039392B2B30183418010104 + 040F14141F3232180C0C0A0A0000080E0E1D1D1D25252B272727272727272727 + 27272727272727272222221C1C1010100B0B0B0B0B0B0B1010101C1C1C1C2828 + 28373728282304010D3434342727273039393430303030393937303030301503 + 020202040404040404040A0A13131F323439434E4E32243145454545453B3B3B + 3B3B3B341D14141F25253232180A0A1F1F0A040401010101010104080D131314 + 1F3439393940343434393030301D0E34371507070000040A0A14323636251807 + 0303030D131F1F1F1F2524232323232323232323232323232727272727271C1C + 1C1010100B0B0B0B0B0B101010101C1C1C1C28282837282828280A01021F3934 + 282828283939393030303030393737373737150302020202040404040404040A + 0E0E1F1F1F323E4B4B2B2B394545454545453B3B3B3B45390A03132525252525 + 25252D2D2F250E0401010101010103030A0F0F141F1F25343434343434343439 + 39180E2440371B0701010303030A1D3443433E321A07070D14141F1F1F2B2B1B + 1B1B1B1B1B232323232323202020202727271B1B1B1010100B0B0B0B0B0B0B10 + 10101B1B1B1B28283030303030301803010F3639282823233739392828282828 + 3939273030300C030202020202020202020202080A0E0E1F1F25323434343434 + 344545393939393939394A3D0C01132418181F1F2525363E3E3E250F04040101 + 00000303080D1313131F1F1F2532323234343434341D181D343430180E0E1818 + 181F2525251814212F1D0A0A13131F1F1F24241B1B1B1B1B1B1B1B1B1B1B1B1B + 1B1B1B2727271C1C1C1010100B0B0B0B0B0B0B1010101C1C1C1C282828282828 + 2828230A010425403030232330393930302727303939282828280A0302020202 + 02020202040404040A0A0E0E1F25252525323434343440393939393939454545 + 23071818180E0E0E1F1F24343E42422F1F14090404040404040A13131F1F1F1F + 1F1F1F1F2525252525252525252525252525251F1F3232130803030808080A0A + 0F0F1F1F1F1F231B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B272727221C1C10100B + 0B0B0B0B0B0B0B1010101C1C1C1C2424243030302424301302020D3639282828 + 28393939282727273939282828230A040404040404020202040404040A0A0A13 + 1F1F252525323636363636343434343434343434342B2B2B2B2B1F1F1F323232 + 1F13142D2D0D05050909020202080D13131F1F1F1F1F1F1F1F1F1F2525252525 + 2525323232212121211F0A030303030300030A0E0E0E1D1D24241B1B1B1B1B1B + 1B1B1B1B1B1B1B1B1B1B1B1B2222221C1C10100B0B0B0B0B0B0B101010101C1C + 1C1C242424303030232337230701021443302727303039392828232339392828 + 28280A04040404040404040404040404040A0A131D1D25323232323636363636 + 3636363636363636363636363632323232321F0D030303090902020202020203 + 03030A0A131F1F1F1F1F1F1F1F25252521212121213232323221211F1F0A0300 + 0003030000030A0A1313131F2B232323231B1B1B1B1B1B1B1B1B1B1B1B1B1B1B + 1B1B1C1C1C10100B0B0B0B0B0B0B0B1010101C1C1C1C24242424242424243030 + 180202043239282828283939372727273440303030300C040404040404040404 + 0404040404080A131F1F1F323234343434363636363636363636363632323232 + 323232321F0D04010101010101010101010101010101080A131F1F1F1F1F1F25 + 25252525252525253232323232322424180A0A0303030303030A0A0A1313131F + 2B2B2727271B1B232323231B1B1B1B1B1B1B1B1B1B1B1B1B1010100B0B0B0B0B + 0B0B0B101010101C1C1C1C282828282828232330230A01010F40302727303939 + 392727273040392730300E0404040404040404040404040404040E0E141D1D25 + 2534343436363636363636363636363232323232323232140801010104040404 + 04020101010101010101030A0E0E1F1F1F1F1F25252525252525253232323232 + 322B2B3430180D0D0A0A0A0A0A0A0A0A13131324303030272323232323231B1B + 1B1B1B1B1B1B1B1B1B1B1B1B1010100B0B0B0B0B0B0B0B101010101C1C1C2424 + 2424242424242424301804020421342828282839393030272739392727270A04 + 04040404040404040404040404040D0D131F1F1F323232363636363636363636 + 3636323232323232321F13040101010404040202020201010101010103030308 + 0D13131F1F1F1F1F252525253232323232323232303030394D391D1313131313 + 0A0A0A0E0E0E1F2B373737373737272727271B1B1B1B1B1B1B1B1B2727271C1C + 1C1010100B0B0B0B0B0B10101010101C1C1C2424242424242424242430270E04 + 04092B3030303039393928282828393030230A04040404040404040404040404 + 0408080A131F1F1F32323236363636363636363632323232323232321F130A03 + 03030304040402020202020202010101030303080D13131F1F1F1F1F1F253232 + 3232323232323239393939454D4D401D13131313131313131313132B373B3B3B + 3B3B3B353535272727272727272727272727221C1C1010100B0B0B0B0B0B0B10 + 1010101C1C1C2424242424242424242430301D0802021F393123233039392828 + 2828393930230A040404040404040404040404040808080A13131F1F25253436 + 3636363636363636363632323232341818180404040404040404040404020202 + 02010101010303080A13131F1F1F1F1F1F25253434323232362B1D2440394545 + 4D4D4537270E0E13131313131313132B3B3B3B3B3B3B3B3B3B3B3B3535353535 + 353535352828221C1C1010100B0B0B0B0B0B0B101010101C1C1C1C2828282828 + 232323232B2B2B180402092B37232328374037272727393928230A0204040404 + 04040404040404040404040A0E0E1F1F25253232323636363636363636323232 + 32393923230E010404040404040402020202020202010101010103080813131F + 1F1F1F1F1F3232343434343434130718404030434E463B3B3B27180D0D131313 + 13131F2B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3737373737372828221C1C101010 + 0B0B0B0B0B0B0B101010101C1C1C1C2828282828232323232B2B2B230C02020F + 2B2B2727304040282828283928230A040404040404040404040404040404040A + 0A131F1F2525323236363636363636363636363640454530240D020202020202 + 080802020202020202010101010103030A0A131F1F1F1F1F2525323434343434 + 130404131F342B3446463D3B3B3B3B230E0E13131313132B3B3B3B3B3B3B3B3B + 3B3B3B3B3B3B3B3B3B3B37373728221C1C1010100B0B0B0B0B0B0B1010101C1C + 1C1C1C28282828282823232323303023230A0104213927272330403027273039 + 39230C04040404040404040404040404040404080A131F1F1F25323236363636 + 363636363636364045454528180D040404040404040404040202020202010101 + 010101040A0A0E141F1F1F1F252532323434320F04040A0A0A1F343E40404A45 + 45454541311D0D0D1313132B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B37373737 + 3722221C1C1C10100B0B0B0B0B0B0B1010101C1C1C1C1C242424243024232323 + 2328282323230702092B37232323393928232834393018040404040404040404 + 04040404040404080A13131F1F25253436363634343434343434454545453928 + 180D040404040404040404040404040401010101010101080A0A0E141F242424 + 2432323636210D0202080A0A0A13243230454545454545454C4124181313132B + 414141414141414141413B3B3B3B3B3B373737372828221C1C1C12120B0B0B0B + 0B0B0B101010101C1C1C1C2424242424242323232323302323301803010E3430 + 23151D403723233039301B0A040404040404040405050505050505080A0E0E1F + 1F25253434343434343434343445454545393937180D04040404040404040404 + 040404020101010101010108080D13131F1F1F25253434341F040202080D0808 + 0A0E0E0E24303030394145454545453728231D2B45414141414141414141413B + 3B3B3B3B3B3B37373728281C1C1C10100B0B0B0B0B0B0B101010101C1C1C1C1D + 1D24242424232323232330242424281501021434271B0C1F393023283434230A + 04040404040404040505050404040408080D131F1F2532343434343434343434 + 4545454545244545180D08010404040404040202020202020201010101010308 + 0A0A13131F1F252534343424080104090F0802020A0A0A131F1F1F2424303039 + 393939454537243443464541414141414141413B3B3B3B3B3B3B37373728281C + 1C1010100B0B0B0B0B0B0B101010101B1B1B1D1D1D1D1D1D242424241D1D2B2B + 232323230E02082B37271509243928283434230C040404040404040404040404 + 04040808080D131F1F253434343434343434344045454545301C4545230E0A01 + 04040404040402020202020202020101010101080A0A13131F1F2B2B3443340C + 0208080F0902020A04040A13131D1D1D24242424242424243234373943434545 + 41414141414141413B3B3B3B3B3B37373728281C1C1C10100B0B0B0B0B0B0B10 + 1010101C1C1D1D1D1D1D1D1D242424242424242424242424240C020D3430300A + 092530232B39300C04050505040404040404040404040408080E0E1F1F252534 + 3434343434344045454545453939454537180D02020404040402020202020202 + 02020203030303030A0E0E1F1F2525253643300C0404040404040D0801030A0E + 0E1D1D24242421212121212134343B3B3B3B45454545453B3B3B3B3B3B3B3B3B + 3B3B3B313128281C1C1C10100B0B0B0B0B0B0B101010102424181D1D1D1D1D1D + 24242323232323303023232323230A041434301B051434272439391504050505 + 0404040404040404040404040A0E0E1F1F253434343434343440454545454539 + 3945454545280E0303030308040404020202010101010101040408080D13131F + 1F1F252532403715020208040408080202030A0A131D1D252525252525252539 + 454141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B313128281C1C1C1010 + 0B0B0B0B0B0B0B101010101C1C1D1D1D1D1D1D1D24242323232323232B2B2B2B + 2B2B1D0A042430300E091F372334401B03040404040404040404040404080808 + 080D131F1F25343434343434394545454545453945454545493B180801010104 + 0404010101010101010101010104040A0E141F1F1F3232323439391D01040404 + 080802020203080A131D1D253232323232323945454141414141414141413B3B + 3B3B3B3B3B3B3B3B3B3B3B313128281C1C1C10100B0B0B0B0B0B0B1010101018 + 181818181D1D1D1D1D2B2323232323232B2B2B23232323230C0A2430230C0D2B + 2B2B40300A040505050404040404040404040408080D131F1F25343434343434 + 4545454545454545454545454545341A03030303030303030303010101010103 + 0303030A0E141F1F2B2B3434393939240C040404080401020202030A131F1F25 + 32323232344045454545454141413B3B3B3B3B3B3B3B3B4141413B3B3B3B3B37 + 372828281C1C12120B0B0B0B0B0B0B0B10101018181818181D24242424242424 + 242424242B2B2B2B23232323230C1325301D0E18302434391802020505050505 + 0504040404040404080A131F1F25252525253439454545454545454545454545 + 39344030040303030303040404040101010101040303030A13131F1F2B323640 + 3B302B3423040408040101040404030A131F1F1F323232344045454545454141 + 413B3B3B3B3B3B3B3B3B3B414141414141414137372828281C1C12120B0B0B0B + 0B0B0B0B0B101018181818182323232323232323232424242430242323232323 + 232318182B2B1B1B34282436240A0404040404040404040404040404040A131F + 1F2525252525343D454545454545454545454537252545390A03030303030303 + 03030101010104030303080A131F1F252534344537151A3630180D0401010104 + 040101030E1D2424243234404545454545414141414141414141414141414141 + 414141414141413B313128281C1C12120B0B0B0B0B0B0B0B1010101010101D1D + 1D2424232323232323242424243030232323232323232318243023233439212F + 30180D05040404040404040404040404080D13131F3232323234394545454545 + 393945454545271D253945452303030303030303030303030303030303030A0E + 1D1D242434343945230C1A3439391D0401010101010101030E1D1D1D25253945 + 4545454545454545414141414141414141414141414141414141413B3131281C + 1C1C12120B0B0B0B0B0B0B0B101010101010101D1D1D24232323232323232323 + 2330302323231D1D1D1D24232334301D2439323239270E040404040404040404 + 08080808080D13131F252525253945454545453B3B3B454545280A14343D3D3D + 451B0A0A040303030303030303030303030A0A141F1F1F25343445370C0C2439 + 45453713030303030303030313131F1F24344545454545454545454545414141 + 414141414141414141414141414141373728281C1C1C12120B0B0B0B0B0B0B0B + 0B101010101313131D1D1D1D1D1D242423232323232330231D1D1D1D1D1D2424 + 242439231D25363434371B0A040404040808080808080404080D13131F252525 + 34394545454545373D3D3D3D370C0C243939454545451B0C0803030303030303 + 08080808080E0E1F1F2525253440492302022445454545240E0A0A030303030A + 13131F1F34454545454545454545414141414141414141414141414141414141 + 414141373728281C1C1C12120B0B0B0B0B0B0B0B0B0E0E0E0E13131313131D1D + 1D1D1D24241D23232323232323231D1D1D1D2323232332300C1F3E343434270C + 0A0A040404040409080404040A0E0E1F1F252525343D45454545393939454545 + 23060C2B40454545454C37180A0707070703030A0A0A0A0A13131F1F1F242424 + 39454518010113454C3D3D3D1D13130A0A0A0A0A13131F2B3945454545454545 + 4141414141414141414141414141414141414141414141373728281C1C1C1212 + 0B0B0B0B0B0B0B0B0B0E0E0E0E13131313181D23232323232323232323232323 + 23231D1D1D1D1D1D1D1D1D24151432393030301B0E0E08040404040404080808 + 080F0F1F1F32323239454545454537373D3D45300C030A2B4545454539454537 + 180A0A0A0A0A0A0A0A0A0A0E0E1F1F1F1F1F25254045450C03030A2445454541 + 391F13131313131313131F2B4045454545454545414141414141414141414141 + 4141414141414141414137373728281C1C1C12120B0B0B0B0B0B0B0B0B0E0E0E + 0E131313131D232323232323232323232323232B2B23231D1D1D1D1D1D1D1D1D + 1D3221343434303024130A0A0A0A0A04040408080D0D141F2525253440403D3D + 3D3D37373745452303030324454545453945454530180C130E0E0E0E0E0E0E0E + 1F1F1F1F1F25252539493B0A0408080C2B454541464324131313131313131F34 + 454545454545454141413B3B3B3B414141414141414141414141414141413737 + 3728281C1C1C10100B0B0B0B0B0B0B0B0B101010131313131D1D232323232323 + 23232323231D1D24241D1D1D181818181818180A13362B2434342B2B2B230E0A + 0A0A0A0A030303080A131321212B323939454537373737373745370C03030318 + 4545454545394C4C4C391D1313131313131313131F1F1F1F1F32322B3745300A + 040908030E304545464D3923130F131313131F394541414141414141413B3B3B + 3B3B3B3B3B3B41414141414141414141413737373728281C1C1C10100B0B0B0B + 0B0B0B0B1010101010181818232323232323232323232323231D1D1D241D1D1D + 1D18181818180C03081F39242434343030301D1D0E0A0A0A0A0808080D131F25 + 252525253D45454537373737374028060101030A374C454545394545454D341F + 1F1F1F1F1F1F1F1F1F242424242434394141270A0A0802020218303043464137 + 281A1313131324404541414141414141414141413B3B3B3B3B3B414141414141 + 41414141413737373728281C1C1C10100B0B0B0B0B0B0B0B101010101010101D + 1D1D23232323232323232323232318181D1D18181818181818180A03030D2434 + 2B2B343427272724140F0F0A0A0A0A0A13131F25253224243745454539393939 + 39391B03030303031845454545374545454D4D40241F1F1F1F1F1F1F24242424 + 242434454545280C04040101010A182B40403B3B45391D131313243D45414141 + 414141414141414141414141414141414141414141414141414137373728281C + 1C1C10100B0B0B0B0B0B0B0B1010101010101010101D1D232323232323232323 + 2323231818241818131313131D130404040A132B3434343428282828251F1413 + 1313131313141F25253234373737453737414141413715030303030303234545 + 45453945454D564D2B2B1F1F1F1F1F1F1F1F1F2B2B2B34454545280A01010101 + 0108132534343B4545453B2318132441414141414141414141413B3B3B3B3B41 + 414141414141414141414141413737373728281C1C1C10100B0B0B0B0B0B0B0B + 101010101010101010101D2323232323232323232323231818241D1813131313 + 130C03030808131D2B34283434272730432F1F1F1F1F1F1F1F1F1F2525254045 + 373739393941414141370C0000030308080C284545453939464E4E392439341F + 1F1F1F1F24242424242439454539280A03040404040A0E0E14253939393B3B3B + 28131F45414141414141414141413B3B3B3B3B41414141414141414141414141 + 413737373728281C1C1C10100B0B0B0B0B0B0B0B0B1010101818181818181823 + 231D1D1D1D2323232323231818181D1313131313130A03030808131D1D243434 + 342823344E4E321F1F1F1F1F1F1F1F1F32323939373737373B3B3B3B45270600 + 010101010A0A15304545373446564637374545341F1F1F1F1F1F1F2525253941 + 3730300C08080808080D0D0E1824323234343434342424434541413B3B3B3B3B + 3B3B3B3B3B3B3B414141413B3B3B41414141413B3B3B3B373728281C1C1C1010 + 0B0B0B0B0B0B0B0B1010101018181818181818181D1D1D1D1D1D24241D181818 + 18181D1D131313181808030303080F1F1F1F253440392343564634251F1F1F1F + 1F1F1F1F323239414130303D3D3D3D3D4527030001010101080808133445452B + 434E3931454545454525251F1F1F1F2525344545373737070404040404040404 + 0A1F1F1F25323232323939393B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B4141413B + 3B3B3B4141414141414141373728281C1C1C10100B0B0B0B0B0B0B0B10101010 + 181818181D1D1D1D1D1D181818181D1D181818181818181D1313131818040404 + 040409141F23232334242448564528282B1F21211F1F1F1F3232394141303045 + 45454545452303010101010404040A0F1D30463E3E3E46464C41414141413421 + 21212B2B253445453939410C020205040401030308131F21212121343941413B + 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B41414141414141414137 + 3728281C1C1C12120B0B0B0B0B0B0B0B10101010131313131D1D1D1D1D1D1D18 + 18181818181818181818181D181818180E0804040404040D142B2B231A1A4352 + 4E402727302B211F1F1F1F1F323237414131314545454545452703030404040A + 0A0A0A13132436424246464D4D4D454541414140322121212134454539394923 + 0102050202020303030C1D212125343D4141413B3B3B3B3B3B3B3B3B3B3B3B3B + 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3131281C1C1C10100B0B0B0B + 0B0B0B0B10101010101313131313131818181818181818181818181818181818 + 181818180C040404040404080F1F322B232B4B4B43433928282828251F1F1F1F + 323437414137373D4545454545270A040808080D0A0A0A0A131F1F323E45454F + 4F4F4F454545454C4C403232253434283D3D493B0C02020101010101030A1321 + 323941414141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B + 3B3B3B3B3B3737373728281C1C1C10100B0B0B0B0B0B0B0B0B0E0E0E13131313 + 131313131318181818181818180E0E0E0E181818181818180C04040404080808 + 08132132304342363446463939393939251F1F25253439393939393945453737 + 37230A04040404040404040A0E0E0E1F253439393B4545454545454949494940 + 32323224304141492303010101010101040A1324344141414141414141413B3B + 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3737373728281C + 1C1C10100B0B0B0B0B0B0B0B1010101013131313131313131313130E0E0E0E0E + 0E0E0E0E131313131D1D1D1D0A040404040404040A0D142525363636373D3D3D + 394040404032212121343B3B3B3B393939393939392707010101010101040404 + 040A13131F25252530303939454545454545454534343E3E2437414141150101 + 0101010103080E24394141414141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B + 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B313122221C1C10100B0B0B0B0B0B0B10 + 1010101313131313131313131313130E0E0E0E0E0E0E0E0E0E0E0E181D1D1D1D + 0A040404040404040808131F1F25253434343030303B39394545342121343930 + 39393939393939454C300601010101040408040103080E0E1F1F252525253434 + 343434343434343434344343433B3B3B493B0C010101010101030E2437413B3B + 3B41414141414141414141414141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B + 3B3B3B3B313122221C1C10100B0B0B0B0B0B0B10101010131313131313131313 + 1313130E0E0E0E0E13131313131313181824241D0A0404040404040808080D14 + 1F1F25323232322B34373737374539343434341D1D394545454545454C300701 + 010104090902020202080A131D1D2525253434343434343232323434343D4141 + 4643393B3B41350C0202020203030E2B41413B3B3B4141414145414141414141 + 4141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B313122221C1C1010 + 0B0B0B0B0B0B0B101010101313131313131313131313130E0E0E0E0E0E181818 + 18181818182424180A040404040404080808080F141F1F252525253234343434 + 3434343434344B3627374545454545454535070102020808040202020202080E + 181F25323232323232323232323945393945454541393939393B3B3414070104 + 0404133041414141414141414141414141414141414141413B3B3B3B3B3B3B3B + 3B3B3B3B3B3B3B3B3B3B3B3B313122221C1C10100B0B0B0B0B0B0B0B10101010 + 131313131313131313131313130E0E0E0E181818181818181824241B0A040404 + 040404040404080D13131F1F2525323232323232323232323737434B433B3B45 + 454545454C370A0108080404040404040404040C131D25323232323232323232 + 40403B3B414141413945453B3B3B3B3636280C020203183741413B3B3B3B3B41 + 41414141414141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B + 313122221C1010100B0B0B0B0B0B0B0B10101010131313131313131313131313 + 130E0E0E0E0E0E0E181818181D1D28230A04040405050505050508080F0F141F + 253232323232323221212B2B3737374040404041414141454C41150308020202 + 0202020202030A0A0E1F1F2B3232323232323639394137374141413728284045 + 453B30364545371B07030C37413B3B3B3B3B3B3B3B3B3B414141414141414141 + 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B373728281C1C1010100B0B0B0B + 0B0B0B0B0B101010101013131313131313131313130E0E0E0E0E0E0E18181B1B + 1B1B2B2B0C040404050505050404040808131414212121323232323232323131 + 373737373939393D3D3D374545451B030303030302020202020808080C131F1F + 252532323236393941373741413B3B3B37232B2B2B3940404141414127151834 + 3D3B3B3B3B3B41414141414141414141414141413B3B3B3B3B3B3B3B3B3B3B3B + 3B3B3B3B3B3B3B313128281C1C1010100B0B0B0B0B0B0B0B0B10101018181818 + 181313131313131313130E0E0E0E181818182323232323281504040405050505 + 04040404080F14141F252532323232322B3037373737373737373D4545454539 + 393924030101030303030303030A03030A131F1F3232343436363B3B3B373741 + 413737373737271D131F3636414141373737283434373B3B3B3B414141414141 + 41414141414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B313128281C + 1C1010100B0B0B0B0B0B0B0B1010101018181818181813131313131313131313 + 13131818181823232323232318070404050505050404040409090F141F1F2525 + 252525253030303037373737373D3D45454545393939340C0101010102020202 + 040404040A131F1F32323236364545453939414137373737373737371B0D0D1F + 2B3737373737373737373B3B3B3B3B3B3B3B3B3B414141414141414141414141 + 414141414141413B3B3B3B3B3B3B3B373728281C1C1010100B0B0B0B0B0B0B0B + 1010101018181818181818181313130E0E0E0E0E0E0E18181818232323232323 + 230C0304040404040404040808080D131F1F1F25252525303030303037373737 + 3D3D3D3D45454530243440270303030303030303080404040A131F2424323234 + 3D4949403945453B3B3B3B2C2C37373737180E18181830373737373737373B3B + 3B3B3B3B3B4141414141414141414141414141414141414141413B3B3B3B3B3B + 3B3B3B313128281C1C1010100B0B0B0B0B0B0B0B101010101818181818181813 + 13130E0E0E0E0E0E0E0E0E1D1D1D1D1D1B1B1B24341803030505050404040408 + 0808080F1F1F1F252525303030373737373737373D3D3D3D3939392314344A45 + 1807070404040404080404040A131F1F25253440454545394545453B3B3B3737 + 373737372834403B271B1D243437373737373B3B3B3B3B3B3B3B414141414141 + 414141414141414141414141413B3B3B3B3B3B3B3B3B37372828281C1C101010 + 0B0B0B0B0B0B0B0B1010101018181818181813131313131313130E0E0E0E0E1D + 1D1D1D1D1D1D1D2434240A030404040404040408080D0D0D141F2525252B2B31 + 31373737373737373D3D3D3D3D45270E143445453B180E040404040404030303 + 0A131F1F323239454545373741413B3B3B3B3737373737373034393537373737 + 3030303B3B3B3B3B3B3B3B3B3B3B41414141414141414141414141414141413B + 3B3B3B3B3B3B3B3B3B3B37372828221C1C1010100B0B0B0B0B0B0B0B10101010 + 181818181818131313131313131313131313131D1D1D1D1D1D1D1D2424241808 + 0D08080404040408080D0D0D141F252525303030373737373737374545453439 + 45450C0C2539454545370E0404040404040303030A131F1F3234393945453741 + 4137373737373737373737373939373737373737373737373B3B3B3B3B3B3B3B + 4141414141414141414141414141414141414141414141414141414141373737 + 2828221C1C1010100B0B0B0B0B0B0B0B10101010181818181813131313131313 + 1818181818181818241D1D1D1D1D181F2424240E0E0808080808080808080D0D + 141F2525253030373737373737374545453039454528030C344040454545300A + 03030303030303070C181F252534394141414141373737373737373737373737 + 3939353535373737373737373B3B3B3B3B414141414141414141414141414141 + 414141414141414141414141413B3B3B3B3B37372727221C1C1010100B0B0B0B + 0B0B0B0B10101010181818180E0E1818180E0E0E181818181818181824241818 + 18180E1F2424241D0E0808080808080808080D0D141F1F253030303737373737 + 3737454539394545450C010E40404040454545240A0A0A0A0A0A0A0E181F2525 + 2539414141373737373737373737373737373737343737373535353737373737 + 373B3B3B3B414141414141414141413B3B3B4141414141414141413B3B3B3B3B + 3B3B3B3B3B3B37372828281C1C1010100B0B0B0B0B0B0B0B1010101018181818 + 180E0E181813131313131D181818181824241D1D1D150A1F2424242418180A04 + 040404040A0A0D0D141F21253030303737373737373D3D33394545453007010A + 394C45394545454524130E0E0E0E18181F1F1F323445454530303737373B3B3B + 3737373737373734343535373737373737373737373B3B3B4141414141414141 + 414141414141414141414141414141413B3B3B3B3B3B3B3B3B3B3B313128281C + 1C1C10100B0B0B0B0B0B0B0B0B10101018181818181313131313131313131D1D + 181818181D241D1D1D0C08182424242424241304040404080A0A0A0E141F2525 + 303030373737373737373739454545451B030303234C4C393945454C43211414 + 1F1F1F1F1F1F1F2B344545373737373741414137373737373737373230353737 + 37373737373737373B3B3B414141414141414141414141414141414141414141 + 41414141413B3B3B3B3B3B3B3B3B3B313128221C1C1010100B0B0B0B0B0B0B0B + 0B1010101818181813131313131313131818181818181D1D1D1D1D1D1D0A040E + 1D1D1D2424242413080808080808080D141F252B2B2B30373737373737373745 + 454545450E0404010C404F453945454C442F251F1F1F1F1F1F1F1F3239393939 + 393B3B3B45453B37373737303030303230303737373737373737373737373741 + 414141414141414141414141414141414141414141414141414141413B3B3B3B + 3B3B3B37372822221C1010100B0B0B0B0B0B0B0B0B1010101018181813131313 + 131313131313131D1D1D1D1D1D1D241D180A0408132323242423232F25130D0D + 0D0D0D0D131F252B2B2B39373737373737373D3D3D3D45450E040404011D4C4C + 45394545464E462B1F1F1F1F1F1F1F34404039393B3B3B3B3B45453737373728 + 2828252B2B35373737373737373B3B3B3B3B3B3B3B3B454545453B3B3B3B4141 + 414141414141414141414141414141413B3B3B3B3B3B3B373728281C1C101010 + 0B0B0B0B0B0B0B0B0B100E0E0E0E0E0E13131313131313131313181D1D1D1D1D + 1D1D2424180A08080F1D1D1D24242444482B131313131313131F252B2B2B2B39 + 37373737373D3D3D3D3D45370A0404040107304C454545454D4D4A452B1F1F1F + 1F1F1F34454531313B3B3B3B373737373737372727272430373737373737373B + 3B3B3B3B3B3B3B4141414141413B3B3B3B3B4141414141414141414141414141 + 414141413B3B3B3B3B3B3B373728281C1C1C10100B0B0B0B0B0B0B0B0B0E1010 + 10101313131313131313131313131D1D1D1D1D1D1D1D2424130808080D1F1F23 + 2324244E4E24242414141414141424302828283737373737373B454545454530 + 0704040404040E344C4530344B4D454545341F141F1F1F3445453037373D3D37 + 3737373737372727272730303737373737373B3B3B3B3B3B3B3B3B3B3B414141 + 3B3B3B3B3B3B3B3B3B3B4141414141414141414141414141413B3B3B3B3B3B37 + 3728281C1C1C12120B0B0B0B0B0B0B0B0B0E1010101010101018181818181818 + 1D1D1D1D1D1D1D1D1D1D24240E08080808131D242418364E401B1B24241F1414 + 141F253030303030303939393B3B454545454530070404040404041330454543 + 434537404045341F1F1F253445303039414141413B3737373727272727272737 + 37373737373B3B3B3B3B3B3B3B4141413B3B3B3B3B3B3B3B3B3B3B3B3B414141 + 414141414141414141414141413B3B3B3B3B3B31313122221C1C12120B0B0B0B + 0B0B0B0B0B1010101818181818131313131D1D1D1D1D1D1D1D1D1D1D1D1D1D1D + 0C0404080808132424244848281B2330302B1F14141F25303030303030393B3B + 3B3B4545454545280A05050504040404132439434D454545454545392B1F1F32 + 30303D3D3D3D3D3D3D3D37372727272727272737373737373737413B3B3B3B3B + 3B4141413B3B3B3B3B3B3B3B4141414141414141414141414141414141414141 + 3B3B3B3B3B3B3B313128281C1C1C10100B0B0B0B0B0B0B0B0B10101010181818 + 18181818181D1D1D1D1D1D1D1D1D1D1D1D1D1D1D0E04040909080D1425344439 + 2728282828282424241F1F2B2B2B2B343439393939394545454545310A040404 + 0404080808131F32404545454545454949372B25343441414141414141413737 + 3737372727272730303030373737413B3B3B3B3B3B3B41414141413B3B3B3B41 + 41414141414141414141414141414141414141413B3B3B3B3B3B37373728281C + 1C1C10100B0B0B0B0B0B0B0B101010101018181818181D1D1D1D1D1D1D1D1D1D + 1D1D1D1818181818180808080808080D131F322B2B393928282828282824242B + 2B2B2B393939393939454545454545370C0404040404040404040F1D25343439 + 39454545454545344343394545454545453B3B37373737372C2C2C2C2C2C2C37 + 37373B3B3B3B3B3B3B3B41414141414141414141414141414141414141414141 + 4141414141414141413B3B3B3B3B37373728281C1C1C10100B0B0B0B0B0B0B10 + 10101010181818181D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1818181818180D0808 + 080808080E0E1F25252534343028282828283434342430393939394545454545 + 4545453B0E0404090904040404040A131F1F25343440404040404040404D4545 + 4545454541414141413737373737373727272737373737373B3B3B3B3B3B3B3B + 3B3B3B3B3B4141413B3B3B4141414141414141414141414141413B3B3B3B3B3B + 3B3B37373728281C1C1C10100B0B0B0B0B0B0B10101010101A1A1D1D1D1D1D1D + 1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D0D0808080808080D0D131F1F252534 + 3434343434343434342B2B373737373745454545454545452304040804040404 + 0404040A141F25253236363636363645454545454545454541414141413B3737 + 3737313131303030373737373B3B3B3B3B3B3B3B3B3B3B3B4141413B3B3B4141 + 414141414141414141414141413B3B3B3B3B373737373131313122221C1C1010 + 0B0B0B0B0B0B0B0B0B0E10101010101010181818181818181D1D1D1D1D1D1818 + 18232323230E090909090909090A0E1F1F323232323232323232303030393737 + 373737373D4545454545454530070404090404040404040A131F252532323636 + 364045454545454545454545454141413B3B3B3B373737373737373737373737 + 373B3B3B3B414141414141414141414141414141414141414141414141373737 + 3737373535353535353531313128281C1C1C10100B0B0B0B0B0B0B0B0B101010 + 1818181818131313131D1D1D1D1D1D1D1D1D1D1D1D232323230E080909090909 + 09090E141F25323232323232343737373737373737373D3D3D45454545454545 + 370C040408080404040404040D141F2525323636404041414141414545454545 + 45454545453B3B3B3B3B3B3B3B3737373737373737373B3B3B3B414141414141 + 4141413B3B3B3B3B3B3B3B3B3B3B3B3B3B353535353535353535353535353535 + 2828281C1C1C10100B0B0B0B0B0B0B0B0B1010101018181818181818181D1D1D + 1D1D1D1D1D1D1D1D1D23232323230E050808080808080D131F1F252525252534 + 373737373B3B3B3D3D3D3D3D3D3D45454141414145300A040409090505050508 + 08131F1F253434344545454545454541414141454545454545413B3B3B3B3B3B + 3B3B3B3B3B3535373737373737373737414141413B3B3B3B3B3B3B3B3B3B3737 + 3737353535353535353535353535353535313131272722221C1C10100B0B0B0B + 0B0B0B0B101010101018181818181D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D23 + 232323090909090909090909131F2525252534393737373737373D3D3D3D3D3D + 3D3D3D4545454545454527080509090404040404040A18243236364545454545 + 453B3B3B3B3B45454545454545453B3B3B3B3B3B3B3B3B373737373737373737 + 373737373737413B3B3B3B3B3B3B3B3B3B353535353535353535272727272735 + 352C2C2C2C2C2C2C2C2222221C1C12120B0B0B0B0B0B0B101010101018181818 + 1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D232323301D0A0808080808080D + 131F1F252525393939373737373D3D3D45454545454545454545454545454523 + 080505040404040404040E1D32364041413D3D3D3B3B3B3B3B3B454545454545 + 45453B3B3B373737373737373737373737373737373737373737373737373737 + 3737373737372C2C272727272727272727272727272727272727272722222222 + 1C1C12120B0B0B0B0B0B0B0B0B0B10101A1A1D1D1D1D1D1D1D1D1D1D1D1D1D1D + 1D1D1D1D1D1D1D23232323301D0A040409090909131A1A212530373737373737 + 3939393939454545454545454545454545454545230804040404040404040A14 + 253645454545453B3B3B414141414545454545414141413B3B3B3B3B3B3B3B3B + 37373737373737373737373737373535352C2C2C2C2C2C2C2C27272727272727 + 272727272727272727272727272727272727221C1C1C10100B0B0B0B0B0B0B0B + 0B0B101018181D1D1D1D1D1D1D1D1D1D1D1D181818181D1D1D1D1D2323232330 + 30230F08080808080D131F252537373737373737373737373D3D454545454545 + 454545454545454545230A040404040404040A14254045454545373737414141 + 41414141413B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B37373737373737373535 + 3535353535272727272727272727272727272727272727272727272727272727 + 2727272727271C1C1C1C10100B0B0B0B0B0B0B0B0B0B0B0B0E10101010101010 + 181818181818181D1D1D1D1D1D1D1D282828232328343E1F0A0808080D131F32 + 3937373737373737373737373D3D4545454545454545454545454545454C300D + 0404040404040413344545454545373737373D4141413B3B3B3B3B3B3B3B3B3B + 3B3B3737373B3B3B3B3B3B373737373737373535353535353535272727272727 + 2727272727272727272727272720202020272727272727272727221C1C1C1010 + 0B0B0B0B0B0B0B0B0B0B0B0B1010101818181818131313131D1D1D1D1D1D1D1D + 1D1D232323282828282F4B4F390E04040A131F343939393939393B3D3D3D3D3D + 3D3D45454145454545454545454545454545422F18040404040404133445453B + 3B3737373737373D3D3D3D3D3D37373737373737373737373737373737373737 + 3737373737373737373737272727272727272727272727272727272727272727 + 272727272727272727313131313122221C1C12120B0B0B0B0B0B0B0B0B0B0B0B + 1010101018181818181818181D1D1D1D1D1D1D1D1D1D2323233030272B424E57 + 57371B0A0A0A1F3439393939393B3D3D3B3D3D3D3D3D3D3D4545414545454539 + 4545454545403C44451B07040404040E34454537373737373737373737373737 + 3737373737373737373737373737373737373737373737373737373737373727 + 2727272723232323232727272727272727272C2C2C2C2C2C3535353537373737 + 3728281C1C1C12120B0B0B0B0B0B0B0B0B0B0B101010101018181818181D1D1D + 1D1D1D1D1D1D1D2323231D1D23454545394242494545454515070F3439393939 + 39393D3D3D3D3D3D3D3D3D3D3D45454541454545454545454543424D4A453115 + 0404040E303D3D3D3D3737373737373737373737373737373737373737373737 + 3737373737373535353535353535353535352727232323232323232323232323 + 23232323232C2C3737373737373737373B3B3B373728281C1C1C12120B0B0B0B + 0B0B0B0B0B0B1010101010181818181D1D1D1D1D1D1D1D1D1D1D1D2323233939 + 394545392F424D41414141415E39183239373737373939393D3D454545454545 + 4545454545454545454545454543424D4545453B230A030A303D3D3D3D373737 + 3737373737373737373737373737373737373737373737373737372727272727 + 27272727272723232323232323232323232323232323232323232C2C37373737 + 3B3B3B3B3B3B3B3B313122221C1C10100B0B0B0B0B0B0B0B0B0B10101010101A + 1A1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D233434342424303E48454545453B3B + 3737373739393937373737373939394545454545454545454540454545454545 + 394242494545454545371B1B3440403737373731313131313137373737373737 + 3737373737372727272727272727272727272727272727272723232323232323 + 2323231B1B1B1B1B1B1B1B1B1B2727272737373737413B3B3B3B3B3B31312222 + 1C1010100B0B0B0B0B0B0B0B0B0B0B0E10101010101010181818181818181D1D + 1D1D1D1D1D232323301313323224394F453B3737373737373737373737373737 + 37373D3D454545454545454545393939394545392F424D414141414141414137 + 3434373737373737373737373535353537373737373737373727272727272727 + 2727272727272727272727272723232323232323231B1B1B1B1B1B1B1B232323 + 23272727353737373B3B3B3B3B3B3B313128281C1C10100B0B0B0B0B0B0B0B0B + 0B0B0B10101018181818181D1D1D1D1D1D1D1D1D1D1D1D1D1D2323232345241A + 130D2556453B3B3737373737373737373737393939373D3D4545454545454545 + 453D3434342424303E48454545453B3B3B3B3B3B303030302727272730303030 + 3030272737373737373737272727272727272727232323232727272723232323 + 231B1B1B1B1B1B1B1B1B1B1B1B1B1B1B2323232727272735373737373B3B3B3B + 373737372828281C1C1010100B0B0B0B0B0B0B0B0B0B0B10101010181818181D + 1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D23234545321A252D2D2B2B343737373737 + 393937373737373739393D3D454545454545454545454545301313323224394F + 453B373737373728283131312727272727272727272727272727272727313127 + 27272727272723232323232323232323232323231B1B1B1B1B1B1B1B1B1B1B1B + 1B1B1B232323272727272735373737373B3B3B37373737372828281C1C101010 + 0B0B0B0B0B0B0B0B0B0B1010101818181818131313131D1D1D181818181D1D1D + 1D1D23232345454246464B3E2824242437373737373737373737373737373939 + 3945454545454541454545454545241A130D2556453B3B373737373737372C27 + 27272723232323232323232323232323232C2C2C272323232323232323232323 + 23232323231B1B1B1B1B1B1B1B1B1B1B1B1B1B23232323232323232727272727 + 3737373737373737373737373728281C1C1010100B0B0B0B0B0B0B0B0B0B1010 + 10101818181818181818181818181D1D1D1D1D1D1D1D2828284539424D494545 + 3B3B3030373737373737373737393939373737373D3D45454545454545454545 + 454545321A252D2D2B2B34373728282828282827272727272323232323232323 + 2323232323232727272323232323232323232323231B1B1B1B1B1B1B1B1B1B1B + 1B1B1B1B1B1B1B23232323232323232323232335353535353535353535353535 + 3528281C1C1010100B0B0B0B0B0B0B0B0B101010101018181818181D1D1D1D1D + 1D1D1D1D1D1D1D1D1D23232328453E4345453B3B3B3B3B373737373739393937 + 37373737393939373D3D454545454545454545454545454246464B3E28242424 + 34343030303030303027272727272727232323232323231B1B1B232323232323 + 23232727272723232323231B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B2323232727 + 27272727272735353535353535353535353737373728281C1C1010100B0B0B0B + 0B0B0B0B0B10101010181818181D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D232323 + 45453E46453B3B3B3737373737373737373737373737373737373739453D3D3D + 3D3D3D4545454545454539424D4945453B3B3030343434313131313131303030 + 30303027272323231B1B1B1B1B1B1B1B1B1B1B1B1B1B27272727272323232323 + 1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B2327272727272727272735353535353535 + 35353535353535353128281C1C10100B0B0B0B0B0B0B0B0B0B0B0B10101A1A1D + 1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D23232323233D383E403D3D3D3D37373737 + 37373737373737373737373737373737373D3D45454545454545454545453E43 + 45453B3B3B3B3B3737373737373737373737373737372827272723232323231B + 1B1B1B1B1B1B23232323232323272727272323232323231B1B1B1B1B1B1B1B1B + 232323272727272727272735353535353535353535353535353535352828281C + 1C1C100B0B0B0B0B0B0B0B0B0B0B0B101018181D1D1D1D1D1D1D1D1D1D1D1D1D + 1D1D1D2323232828373636393939393131282828373737313131313131313131 + 3131282828393939454545454545454545453E46453B3B3B3737373737373737 + 3737373737373737373737282828232323232323232323232323232323232323 + 2727272727272323232323231B1B1B1B1B1B1B1B232323232727272727272727 + 2727272727272C2C2C2C3737313131272222221C1C10100B0B0B0B0B0B0B0B0B + 0B0B0B101010181818181010101818181D1D1D1D1D1D1D1D2323282828252828 + 282828282828282828282828282828282828282828282828282828283D45453D + 3D3D3D3D3D383E403D3D3D3D3737373731313131313131313131312828282828 + 2823232323232323232323232323232323232727272727272727272323232323 + 231B1B1B1B1B1B1B232323232727272727272727272727272727272727353535 + 3535272727271B1B1010100B0B0B0B0B0B0B0B0B0B0B0B101010101818181818 + 18131D1D1D1D1D1D1D1D1D1D2828222222252222222222222222222228282828 + 282823232323222828282828282323233D454539373737373736363939393931 + 3128282828282828282828282828282823232323231B1B1B1B1B1B1B1B232323 + 23232323272727272727272727272323232323231B1B1B1B1B1B1B1B1B1B2727 + 272727272727272727272727272727273131313131312727271B1B1B1010100B + 0B0B0B0B0B0B0B0B0B0B101010181818181823231B1B1B1B1B1B1B1B1B1B1B1B + 28281C1C1C1C1C1C1C1C1C1C1C1C1C1C22222222221B1B1B1B1B1C2222222228 + 282828282828282828312828282528282828282828282828282828232323231B + 1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B22222828282828282828 + 282323231B1B1B1B1B1B1B1B1B1B1B1B1B222828282828282828282828282828 + 2828282831313128282828281C1C1C1C1010100B0B0B0B0B0B0B0B0B0B0B1010 + 1010181818181B1B1B1B1B1B1B18181818181818232323231B1B1B1B1B1B1B1B + 1B1B1B1B1C1C1C1B1B1B18181818181818181822282828282828232323222222 + 22252222222222222222222222221B1B1B1B1B1B1B1B1B1B1818181818181818 + 181B1B1B1B1B1B1B2222222222222222222222222222221B1B1B1B1B1B181818 + 18181C2222222228282828282828282828282828282828282828282822222222 + 1C1C1C1C1010100B0B0B0B0B0B0B0B0B0B101010101018181818181818181818 + 18181818181818181B1B1B1B1B1B1B1B1B181818181818181010101010101010 + 101010101010181C22222222221B1B1B1B1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C + 1B1B1B1818181818181818181818181818181818181B1B1B1B1B1B1B1B222222 + 22222222222222221C1C1C1C1C1B1B1B181818181C1C1C1C2222222222222222 + 2222222222222222222222222222222222221C1C1C1C1C1010100B0B0B0B0B0B + 0B0B0B0B0B10101010181818181D101010101010101010101010101018181818 + 1818181818181818181818181010101010101010101010101010181818181D24 + 1D1D101C1C1C1C1C1A1A10101010101010101010101010101010101010101010 + 101010101010101010101B1B1B1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C + 1C1C1C1C1C101010101C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C + 1C1C1C1C1C1C1C1C1C1C101010100B0B0B0B0B0B0B0B0B0B0B0B0B10101A1A1D + 1D1D101010101010101010101010101010101010101010101010101010101010 + 10101010101010101010101010101010101010101010101C1010101010101010 + 1010101010101010101010101010101010101010101010101010101010101010 + 10101C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1010101010101010101C + 1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1010101010 + 100B0B0B0B0B0B0B0B0B0B0B0B0B0B101018181D1D1D10101010101010101010 + 1010101010101010101010101010101010101010101010101010101010101010 + 1010101010101010101010101010101010101010101010101010101010101010 + 1010101010101010101010101010101010101010101010101010101010101010 + 1010101010101010101010101010101010101010101010121212121212121212 + 12121210101010101010101010101010101010100B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0E1010101010101010101010101010101010101010101010101010 + 10101010101010100B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B12 + 1212121210101010101010101010101010101010101010101010101010101010 + 1010101010101010101010101010101010101010101010101010101010101010 + 1010101010101010101010101010101010101010101010101010101010101010 + 1010101010100B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B101010101010101010101010100B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B + 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B} + Stretch = True + IsControl = True + end + end + object tmrAboutBox: TTimer + Enabled = False + Interval = 5000 + OnTimer = tmrAboutBoxTimer + Left = 293 + Top = 12 + end +end diff --git a/win32/gui/AboutDialogU.pas b/win32/gui/AboutDialogU.pas new file mode 100644 index 000000000..e5db9933d --- /dev/null +++ b/win32/gui/AboutDialogU.pas @@ -0,0 +1,67 @@ +unit AboutDialogU; + +interface + +uses + Buttons, Classes, Controls, Dialogs, ExtCtrls, Forms, Graphics, Messages, StdCtrls, SysUtils, Windows, + VersionInfo; + +type + TAboutBox = class (TForm) + private // invisible outside of the unit + protected // visible in the unit and in descended classes + public // visible wherever the class can be referenced + published // like public, but generates RTTI info + lblCopyright: TLabel; + lblLicense: TLabel; + lblProductName: TLabel; + lblVersion: TLabel; + + pnlInner: TPanel; + pnlOuter: TPanel; + ProgramIcon: TImage; + + tmrAboutBox: TTimer; + + procedure FormCreate (Sender: TObject); + procedure FormShow (Sender: TObject); + procedure tmrAboutBoxTimer (Sender: TObject); + end; + +var + AboutBox: TAboutBox; + +implementation + +{$R *.DFM} + +procedure TAboutBox.FormCreate (Sender: TObject); +var s: string; +begin + lblCopyright.Caption := GetVersionString ('LegalCopyright'); + lblLicense.Caption := GetVersionString ('License'); + lblProductName.Caption := GetVersionString ('ProductName'); + Caption := lblProductName.Caption; + lblVersion.Caption := lblVersion.Caption + GetFileVersion (TFileVersionLong); + + ShortDateFormat := 'yyyy'; + s := DateToStr (Date); + if s <> Copy (lblCopyright.Caption, Length(lblCopyright.Caption)-3,4) then // year of original copyright + lblCopyright.Caption := lblCopyright.Caption + ', ' + s; +end; + +procedure TAboutBox.FormShow (Sender: TObject); +begin + tmrAboutBox.Enabled := true; +end; + +procedure TAboutBox.tmrAboutBoxTimer (Sender: TObject); +begin + tmrAboutBox.Enabled := false; + AboutBox.Visible := false; +end; + +initialization +end. + + diff --git a/win32/gui/GPSBabelGUI.cfg b/win32/gui/GPSBabelGUI.cfg new file mode 100644 index 000000000..9d13f677c --- /dev/null +++ b/win32/gui/GPSBabelGUI.cfg @@ -0,0 +1,38 @@ +-$A8 +-$B- +-$C+ +-$D+ +-$E- +-$F- +-$G+ +-$H+ +-$I+ +-$J- +-$K- +-$L+ +-$M- +-$N+ +-$O+ +-$P+ +-$Q- +-$R- +-$S- +-$T- +-$U- +-$V+ +-$W- +-$X+ +-$YD +-$Z1 +-cg +-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +-H+ +-W+ +-M +-$M16384,1048576 +-K$00400000 +-LE"c:\program files\borland\delphi7\Projects\Bpl" +-LN"c:\program files\borland\delphi7\Projects\Bpl" +-w-UNSAFE_TYPE +-w-UNSAFE_CODE +-w-UNSAFE_CAST diff --git a/win32/gui/GPSBabelGUI.dof b/win32/gui/GPSBabelGUI.dof new file mode 100644 index 000000000..ba85469af --- /dev/null +++ b/win32/gui/GPSBabelGUI.dof @@ -0,0 +1,137 @@ +[FileVersion] +Version=7.0 +[Compiler] +A=8 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=0 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +NamespacePrefix= +SymbolDeprecated=1 +SymbolLibrary=1 +SymbolPlatform=1 +UnitLibrary=1 +UnitPlatform=1 +UnitDeprecated=1 +HResultCompat=1 +HidingMember=1 +HiddenVirtual=1 +Garbage=1 +BoundsError=1 +ZeroNilCompat=1 +StringConstTruncated=1 +ForLoopVarVarPar=1 +TypedConstVarPar=1 +AsgToTypedConst=1 +CaseLabelRange=1 +ForVariable=1 +ConstructingAbstract=1 +ComparisonFalse=1 +ComparisonTrue=1 +ComparingSignedUnsigned=1 +CombiningSignedUnsigned=1 +UnsupportedConstruct=1 +FileOpen=1 +FileOpenUnitSrc=1 +BadGlobalSymbol=1 +DuplicateConstructorDestructor=1 +InvalidDirective=1 +PackageNoLink=1 +PackageThreadVar=1 +ImplicitImport=1 +HPPEMITIgnored=1 +NoRetVal=1 +UseBeforeDef=1 +ForLoopVarUndef=1 +UnitNameMismatch=1 +NoCFGFileFound=1 +MessageDirective=1 +ImplicitVariants=1 +UnicodeToLocale=1 +LocaleToUnicode=1 +ImagebaseMultiple=1 +SuspiciousTypecast=1 +PrivatePropAccessor=1 +UnsafeType=0 +UnsafeCode=0 +UnsafeCast=0 +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir= +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath= +Packages=vcl;rtl;vclx;indy;vclie;xmlrtl;inetdbbde;inet;inetdbxpress;dbrtl;soaprtl;dsnap;VclSmp;dbexpress;vcldb;dbxcds;inetdb;bdertl;vcldbx;adortl;teeui;teedb;tee;ibxpress;visualclx;visualdbclx;vclactnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL;dclaxserver +Conditionals= +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +Launcher= +UseLauncher=0 +DebugCWD= +[Language] +ActiveLang= +ProjectLang= +RootDir= +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=0 +MajorVer=2 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1033 +CodePage=1252 +[Version Info Keys] +CompanyName=Down East Engineering +FileDescription= +FileVersion=2.0.0.0 +InternalName= +LegalCopyright=© Down East Engineering 2005 +LegalTrademarks= +OriginalFilename= +ProductName=GPSBabelGUI +ProductVersion=2.0.0.0 +Comments= +License=Subject to terms of the GNU General Public License diff --git a/win32/gui/GPSBabelGUI.dpr b/win32/gui/GPSBabelGUI.dpr new file mode 100644 index 000000000..b943c1f16 --- /dev/null +++ b/win32/gui/GPSBabelGUI.dpr @@ -0,0 +1,17 @@ +program GPSBabelGUI; + +{%ToDo 'GPSBabelGUI.todo'} + +uses + Forms, + GPSBabelGUIDialogU in 'GPSBabelGUIDialogU.pas' {GPSBabelGUIDialog}, + AboutDialogU in 'AboutDialogU.pas' {AboutBox}; + +{$R *.res} + +begin + Application.Initialize; + Application.Title := 'GPSBabelGUI'; + Application.CreateForm(TGPSBabelGUIDialog, GPSBabelGUIDialog); + Application.Run; +end. diff --git a/win32/gui/GPSBabelGUI.ico b/win32/gui/GPSBabelGUI.ico new file mode 100644 index 0000000000000000000000000000000000000000..76a19fd4f8255c3c2e0030659d9d33beef9973bc GIT binary patch literal 766 zcmcIiF%H5o47?(Sj!euQc?Lhjqo380p;8{vg(omXm@{cn9JL!bJ=@o_<3tM3aSg)> zZjS?SX1ovsaV0t&=>eg(Z9MIDk^== z(brrR-n7=kGZyS|FRkm94Pn1_9vj@&{Vek)X3sr76}#{0>`!K??oXB*o+4*Us85kk m*3>tgbzD;r6i z#Ko+QV%AO)NRY!rRs^iG1)9Yt4Dj;h>oGuv%V(BG#?N*3+>S5n{ES~1v&hCT%ra*$ ze48O2e&O45lf&n1mh<^8=f0is!*-j*DgS?}3_{UXWvq%P+_VD>Nw>55Kp+;(+Y=L zZ-;9cpTZxcDe>;1S$$W%KuB$~ryEqC6;j6(V{|b<8#~lJw3vB-6AX#@pqMf$?DP($ zLJq>HhD*%1O-vsnG>L!9uA8)4TA)hL8}3HLH!)!iSxF74)Z)+81g zj~Lfwrh(>^sf=O<+t56d3}y>Ah;agJYHsOgs@MV9^gO1(b6g>+Mt@tq($$Fl2*Wly zj08TC|KIl%VT&xvxTU;pf2aAMGIJ9zSg%h##w+&ghQ%JFwdJgYue%qq+zA7>ah|*% z6FX$K*F3YS*V!(8bv$6q5o`6Zi)Xx9@c!fs{kZ%|=Fjo6o};~QVIb$}Sii$fJ-;p) zh-boCMxC6F@RF7=izq{#;@DB=c^Y`)e=VxGe;K0Pl$;KI)SCUzhlbT}4#=r!G E07ZHWvj6}9 literal 0 HcmV?d00001 diff --git a/win32/gui/GPSBabelGUIDialogU.dfm b/win32/gui/GPSBabelGUIDialogU.dfm new file mode 100644 index 000000000..916e23b8a --- /dev/null +++ b/win32/gui/GPSBabelGUIDialogU.dfm @@ -0,0 +1,218 @@ +object GPSBabelGUIDialog: TGPSBabelGUIDialog + Left = 461 + Top = 119 + BorderStyle = bsDialog + Caption = 'GPSBabelGUI' + ClientHeight = 258 + ClientWidth = 380 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + Position = poScreenCenter + DesignSize = ( + 380 + 258) + PixelsPerInch = 96 + TextHeight = 13 + object lblGPSBabelURI: TLabel + Left = 66 + Top = 237 + Width = 250 + Height = 13 + Anchors = [akLeft, akBottom] + Caption = 'GPSBabel: http://www.gpsbabel.org' + end + object lblInputFileName: TLabel + Left = 17 + Top = 17 + Width = 43 + Height = 13 + Alignment = taRightJustify + Caption = 'Input file:' + end + object lblOutputFileName: TLabel + Left = 9 + Top = 97 + Width = 51 + Height = 13 + Alignment = taRightJustify + Caption = 'Output file:' + end + object bvlGPSBabelURI: TBevel + Left = 0 + Top = 222 + Width = 380 + Height = 4 + Anchors = [akLeft, akBottom] + end + object lblOutputFormat: TLabel + Left = 25 + Top = 73 + Width = 35 + Height = 13 + Alignment = taRightJustify + Caption = 'Format:' + end + object lblInputFormat: TLabel + Left = 25 + Top = 41 + Width = 35 + Height = 13 + Alignment = taRightJustify + Caption = 'Format:' + end + object btnInputFileDialog: TSpeedButton + Left = 339 + Top = 12 + Width = 23 + Height = 22 + Glyph.Data = { + 76010000424D7601000000000000760000002800000020000000100000000100 + 04000000000000010000120B0000120B00001000000000000000000000000000 + 800000800000008080008000000080008000808000007F7F7F00BFBFBF000000 + FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00555555555555 + 5555555555555555555555555555555555555555555555555555555555555555 + 555555555555555555555555555555555555555FFFFFFFFFF555550000000000 + 55555577777777775F55500B8B8B8B8B05555775F555555575F550F0B8B8B8B8 + B05557F75F555555575F50BF0B8B8B8B8B0557F575FFFFFFFF7F50FBF0000000 + 000557F557777777777550BFBFBFBFB0555557F555555557F55550FBFBFBFBF0 + 555557F555555FF7555550BFBFBF00055555575F555577755555550BFBF05555 + 55555575FFF75555555555700007555555555557777555555555555555555555 + 5555555555555555555555555555555555555555555555555555} + NumGlyphs = 2 + OnClick = btnInputFileDialogClick + end + object btnOutputFileDialog: TSpeedButton + Left = 339 + Top = 92 + Width = 23 + Height = 22 + Glyph.Data = { + 76010000424D7601000000000000760000002800000020000000100000000100 + 04000000000000010000120B0000120B00001000000000000000000000000000 + 800000800000008080008000000080008000808000007F7F7F00BFBFBF000000 + FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00333333333333 + 333333FFFFFFFFFFFFF33000077777770033377777777777773F000007888888 + 00037F3337F3FF37F37F00000780088800037F3337F77F37F37F000007800888 + 00037F3337F77FF7F37F00000788888800037F3337777777337F000000000000 + 00037F3FFFFFFFFFFF7F00000000000000037F77777777777F7F000FFFFFFFFF + 00037F7F333333337F7F000FFFFFFFFF00037F7F333333337F7F000FFFFFFFFF + 00037F7F333333337F7F000FFFFFFFFF00037F7F333333337F7F000FFFFFFFFF + 00037F7F333333337F7F000FFFFFFFFF07037F7F33333333777F000FFFFFFFFF + 0003737FFFFFFFFF7F7330099999999900333777777777777733} + NumGlyphs = 2 + OnClick = btnOutputFileDialogClick + end + object comboInput: TComboBox + Left = 64 + Top = 37 + Width = 300 + Height = 21 + Style = csDropDownList + ItemHeight = 13 + TabOrder = 1 + end + object eInput: TEdit + Left = 64 + Top = 13 + Width = 273 + Height = 21 + TabOrder = 0 + end + object eOutput: TEdit + Left = 64 + Top = 93 + Width = 273 + Height = 21 + TabOrder = 2 + end + object comboOutput: TComboBox + Left = 64 + Top = 69 + Width = 300 + Height = 21 + Style = csDropDownList + ItemHeight = 13 + TabOrder = 3 + end + object btnProcess: TButton + Left = 232 + Top = 141 + Width = 132 + Height = 25 + Caption = '&Process' + TabOrder = 5 + OnClick = btnProcessClick + end + object cbIgnoreShort: TCheckBox + Left = 64 + Top = 145 + Width = 121 + Height = 17 + Caption = 'Ignore "short" names' + TabOrder = 4 + end + object btnExit: TButton + Left = 319 + Top = 184 + Width = 45 + Height = 25 + Caption = 'E&xit' + TabOrder = 6 + OnClick = btnExitClick + end + object btnAbout: TButton + Left = 64 + Top = 184 + Width = 45 + Height = 25 + Caption = '&About' + TabOrder = 7 + OnClick = btnAboutClick + end + object btnIntro: TButton + Left = 149 + Top = 184 + Width = 45 + Height = 25 + Caption = '&Intro' + TabOrder = 8 + OnClick = btnIntroClick + end + object btnUseDefaultOutput: TButton + Left = 64 + Top = 117 + Width = 114 + Height = 19 + Caption = '&Use Default Filename' + TabOrder = 9 + OnClick = btnUseDefaultOutputClick + end + object btnHowTo: TButton + Left = 234 + Top = 184 + Width = 48 + Height = 25 + Caption = '&How to...' + TabOrder = 10 + OnClick = btnHowToClick + end + object dlgOpenInput: TOpenDialog + Options = [ofEnableSizing] + Left = 363 + Top = 9 + end + object dlgSaveOutput: TSaveDialog + Left = 363 + Top = 88 + end + object TimerLoadFormats: TTimer + OnTimer = TimerLoadFormatsTimer + Left = 350 + Top = 229 + end +end diff --git a/win32/gui/GPSBabelGUIDialogU.pas b/win32/gui/GPSBabelGUIDialogU.pas new file mode 100644 index 000000000..e60a410f1 --- /dev/null +++ b/win32/gui/GPSBabelGUIDialogU.pas @@ -0,0 +1,480 @@ +{ + Copyright © Richard L Messeder, Down East Engineering, www.DownEastEngineering.com and others listed below + Delphi 5, 6 & 7 Version + v02.00.00 Add About. + v02.00.00 Add Exit button. + v02.00.00 Add Help. + v02.00.00 Add hotkeys for most common buttons. + v02.00.00 Add timer to load formats after form is created. + v02.00.00 Align controls on dialog. + v02.00.00 Don't permit file processing unless GPSBabel is OK. + v02.00.00 Evaluate need for memoStdErr vs. Message dialog. + v02.00.00 Include all project management and Delphi project files in upload. + v02.00.00 LoadFormatsFromGPSBabelExe: Delete unused AllocConsole. + v02.00.00 LoadFormatsFromGPSBabelExe: don't continue if GPSBabel not found. + v02.00.00 Look for GPSBabel.exe before attempting to open it. + v02.00.00 Modify to use input filename and output type to generate default output filename. + v02.00.00 Output file dialog: fill in filename and filetype, if possible. + v02.00.00 Port to Delphi 7. + v02.00.00 Process: Delete unused AllocConsole. + v02.00.00 Process: handle cases where input/output file is a dir. + v02.00.00 Process: don't allow processing null, or undefined, files. + v02.00.00 Remove unused console invocations. + v02.00.00 Remove unused variable declarations. + v02.00.00 Rewrite to eliminate 'exit;'. + v02.00.00 Sort default file types by alpha; add sort routine: CANCELLED: placed in GPSBabel. +} +{ + Copyright (C) 2002 Josh M. McKee, mrsnazz@users.sourceforge.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +} + +{ + 1.0.2 JMc - Added LoadFormats to call the new -^ switch, to dynamically + load the supported GPSDataFormats from gpsbabel.exe. + 1.0.1 JMc - Switched to using AddFormat for populating the GPSDataFormats table + - Updated GPSDataFormats table to include currently supported GPSDataFormats + - Switched to using CreateProcess rather than WinExec, so that + we can display data from stderr to the user. + 1.0.0 JMc First release +} + +unit GPSBabelGUIDialogU; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, + Buttons, ExtCtrls, StdCtrls, StrUtils; + +const + CR = chr ($0D); + LF = chr ($0A); + Tab = chr ($09); + +type + TGPSDataFormat = record + sType: string; // type to be passed to GPSBabel + sExt: string; // default file extension + sDesc: string; // description of format + end; + + TGPSBabelGUIDialog = class (TForm) + private // invisible outside of the unit + OKtoRun: boolean; + BytesRead: DWord; + Buffer: array [0..4095] of char; + BufferIndex, TokenIndex, nFormats: integer; + sCmd, sGPSBabelMsg, sIgnoreShort: string; + Tokens: array [0..2] of string; + GPSDataFormats: array of TGPSDataFormat; + hRead, hWrite: THandle; + ProcessInfo: TProcessInformation; + SecurityAttr: TSecurityAttributes; + StartupInfo: TStartupInfo; + procedure LoadFormatsFromGPSBabelExe; + procedure PopulateCombos; + procedure PopulateDialogs; + protected // visible in the unit and in descended classes + public // visible wherever the class can be referenced + published // like public, but generates RTTI info + btnAbout: TButton; + btnExit: TButton; + btnHowTo: TButton; + btnInputFileDialog: TSpeedButton; + btnIntro: TButton; + btnOutputFileDialog: TSpeedButton; + btnProcess: TButton; + btnUseDefaultOutput: TButton; + bvlGPSBabelURI: TBevel; + cbIgnoreShort: TCheckBox; + comboInput: TComboBox; + comboOutput: TComboBox; + dlgOpenInput: TOpenDialog; + dlgSaveOutput: TSaveDialog; + eInput: TEdit; + eOutput: TEdit; + lblGPSBabelURI: TLabel; + lblInputFileName: TLabel; + lblInputFormat: TLabel; + lblOutputFileName: TLabel; + lblOutputFormat: TLabel; + TimerLoadFormats: TTimer; + + procedure TimerLoadFormatsTimer(Sender: TObject); + procedure btnAboutClick(Sender: TObject); + procedure btnExitClick(Sender: TObject); + procedure btnHowToClick(Sender: TObject); + procedure btnInputFileDialogClick (Sender: TObject); + procedure btnIntroClick(Sender: TObject); + procedure btnOutputFileDialogClick (Sender: TObject); + procedure btnProcessClick (Sender: TObject); + procedure btnUseDefaultOutputClick(Sender: TObject); + end; + +var + GPSBabelGUIDialog: TGPSBabelGUIDialog; + +implementation + +uses AboutDialogU; + +{$R *.dfm} + +procedure TGPSBabelGUIDialog.TimerLoadFormatsTimer (Sender: TObject); +// This could have been in FormCreate, but this way the form is shown +// before the 'formats loaded' message. +begin + TimerLoadFormats.Enabled := false; + nFormats := 0; + LoadFormatsFromGPSBabelExe; +end; + +procedure TGPSBabelGUIDialog.LoadFormatsFromGPSBabelExe; + procedure AddFormat (sType, sExt, sDesc: string); + begin + inc (nFormats); + // changes the size of the GPSDataFormats array + // initialized at nil, so the first pass sets it to 1 row, addressed as [0] + SetLength (GPSDataFormats, nFormats); + + GPSDataFormats [nFormats-1].sType := sType; // [n-1] because array is zero-based + GPSDataFormats [nFormats-1].sExt := sExt; + GPSDataFormats [nFormats-1].sDesc := sDesc; + end; + +begin + sCmd := 'GPSBabel -^'; // internal gpsbabel command -^ + + SecurityAttr.nLength := sizeof (TSECURITYATTRIBUTES); + SecurityAttr.bInheritHandle := true; + SecurityAttr.lpSecurityDescriptor := nil; + + OKtoRun := false; + if CreatePipe (hRead, hWrite, @SecurityAttr, 0) then begin + FillChar (StartupInfo, Sizeof (StartupInfo), #0); + StartupInfo.cb := Sizeof (StartupInfo); + StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; + StartupInfo.wShowWindow := SW_HIDE and SW_SHOWMINNOACTIVE; + StartupInfo.hStdInput := GetStdHandle (STD_INPUT_HANDLE); + StartupInfo.hStdOutput:= hWrite; + StartupInfo.hStdError := hWrite; + + if FileExists ('GPSBabel.exe') then begin + if CreateProcess ( + nil, // lpApplicationName // pointer to name of executable module + // sCmd includes both the exec name and the command line parms in this call + pchar (sCmd), // lpCommandLine, // pointer to command line string + nil, // lpProcessAttributes, // pointer to process security attributes + nil, // lpThreadAttributes, // pointer to thread security attributes + true, // bInheritHandles, // handle inheritance flag + CREATE_NEW_CONSOLE, // dwCreationFlags, // creation flags + nil, // lpEnvironment, // pointer to new environment block + nil, // lpCurrentDirectory, // pointer to current directory name + StartupInfo, // lpStartupInfo, // pointer to STARTUPINFO + ProcessInfo) // lpProcessInformation // pointer to PROCESS_INFORMATION + then begin + + while (WaitforSingleObject (ProcessInfo.hProcess, 0)) <> WAIT_OBJECT_0 do; + + PeekNamedPipe (hRead, nil, 0, nil, @BytesRead, nil); + ReadFile (hRead, Buffer, 4096, BytesRead, nil); + // The data passed by GPSBabel.exe should exceed 1500 bytes, but this provides some slack. + // (v2.0.0) We're discussing the possibility of having some sort of byte count passed by gpsbabel, + // e.g., 'byte count=1234'; we could then check for 'byte count=', and if we don't get it + // then we know that there is an error. + if BytesRead > 1000 then begin + BufferIndex := 0; + TokenIndex := 0; + FillChar (Tokens, SizeOf(Tokens), 0); + + // Process the buffer into Types, Extensions, and Descriptions + while BufferIndex < BytesRead do begin + if Buffer [BufferIndex] in [Tab,CR,LF] then // Tab between fields, CRLF between rows + inc (TokenIndex) + else + Tokens [TokenIndex] := Tokens [TokenIndex] + Buffer [BufferIndex]; + if TokenIndex = 3 then begin + TokenIndex := 0; + inc (BufferIndex); // Because we point to CR and must skip the LF + AddFormat (Tokens[0], Tokens[1], Tokens[2]); + FillChar(Tokens, SizeOf (Tokens), 0); + end; + inc (BufferIndex); + end; + + PopulateCombos; + PopulateDialogs; + OKtoRun := true; + MessageDlg ('GPS file formats loaded from GPSBabel.exe.', mtInformation, [mbOk], 0); + end // if BytesRead > 0 + else begin + sGPSBabelMsg := copy (Buffer, 1, BytesRead); + MessageBox (0, pchar (sGPSBabelMsg),'GPSBabel Error', MB_OK); + end + end + else + MessageDlg ('Unable to execute GPSBabel.exe.', mtError, [mbOk], 0); + end + else + MessageDlg ('Can''t find GPSBabel.exe.', mtError, [mbOk], 0); + + CloseHandle (hRead); + CloseHandle (hWrite); + end + else + MessageDlg ('Unable to create pipe!', mtError, [mbOk], 0); +end; + +procedure TGPSBabelGUIDialog.PopulateCombos; +var + i: integer; +begin + for i:=0 to nFormats-1 do begin + comboInput.items.add (GPSDataFormats[i].sDesc); + comboOutput.items.add (GPSDataFormats[i].sDesc); + end; +end; + +procedure TGPSBabelGUIDialog.PopulateDialogs; +var + i: integer; +begin + dlgOpenInput.Filter := ''; + dlgSaveOutput.Filter := ''; + for i:=0 to nFormats-1 do begin + if (GPSDataFormats[i].sExt<>'') then begin + dlgOpenInput.Filter := dlgOpenInput.Filter + + GPSDataFormats[i].sDesc + ' (*.' + + GPSDataFormats[i].sExt + ')|*.' + + uppercase (GPSDataFormats[i].sExt) + '|'; + + dlgSaveOutput.Filter := dlgSaveOutput.Filter + + GPSDataFormats[i].sDesc + ' (*.' + + GPSDataFormats[i].sExt + ')|*.' + + uppercase (GPSDataFormats[i].sExt) + '|'; + end; + end; + + dlgOpenInput.Filter := dlgOpenInput.Filter + 'All files (*.*)|*.*'; + dlgSaveOutput.Filter := dlgSaveOutput.Filter + 'All files (*.*)|*.*'; +end; + +procedure TGPSBabelGUIDialog.btnAboutClick(Sender: TObject); +begin + if AboutBox = nil then begin + Application.CreateForm (TAboutBox, AboutBox); + AboutBox.Left := (Screen.Width - AboutBox.Width) div 2; + AboutBox.Top := (Screen.Height - AboutBox.Height) div 2; + end; + AboutBox.Show; +end; + +procedure TGPSBabelGUIDialog.btnExitClick (Sender: TObject); +begin + Application.Terminate; +end; + +procedure TGPSBabelGUIDialog.btnHowToClick(Sender: TObject); +begin + MessageBox (0, PChar ( + 'Begin using GPSBabelGUI by:' +CR+ + ' Defining an input file. If the file has an extension that' +CR+ + ' GPSBabelGUI recognizes, the format will be automatically' +CR+ + ' selected.' +CR+CR+ + ' If the selected input file format is not correct, select the correct' +CR+ + ' format from the Format dropdown list.' +CR+CR+ + ' Select an output format.' +CR+CR+ + ' Select Use Default Filename.' +CR+CR+ + ' GPSBabelGUI will fill in the default output directory/filename' +CR+ + ' using the input directory and filename. To change it, edit the' +CR+ + ' name directly or use the Save As dialog.' +CR+CR+ + ' Select any options for GPSBabel to use during processing.' +CR+CR+ + ' Select Process.' + ), 'How To...', MB_OK); +end; + +procedure TGPSBabelGUIDialog.btnInputFileDialogClick (Sender: TObject); +var + sExt: string; + i: integer; +begin + if OKtoRun then + if dlgOpenInput.Execute then begin + eInput.Text := dlgOpenInput.filename; + sExt := uppercase (ExtractFileExt (eInput.text)); + for i := 0 to nFormats-1 do + if '.' + uppercase (GPSDataFormats[i].sExt) = sExt then + comboInput.ItemIndex := i; + end; +end; + +procedure TGPSBabelGUIDialog.btnIntroClick(Sender: TObject); +begin + MessageBox (0, PChar ( + 'GPSBabelGUI is simply a GUI front end for GPSBabel.exe.' +CR+CR+ + 'GPSBabelGUI''s only purpose is to make it easier to call' +CR+ + 'GPSBabel.exe, so it must be able to find it. The easiest' +CR+ + 'way for GPSBabelGUI to find GPSBabel.exe is for both of' +CR+ + 'them to be in the same directory.' +CR+CR+ + 'GPSBabelGUI will not permit any processing to take place' +CR+ + 'if there is an error during startup, or if it cannot find' +CR+ + 'GPSBabel.exe.' +CR+CR+ + 'There are 3 classes of messages to expect:' +CR+Tab+ + '°Errors' +CR+Tab+ + '°Warnings' +CR+Tab+ + '°Information' +CR+CR+ + '°If you receive an Error, such as ''GPSBabel can''t be found'',' +CR+ + 'something has gone seriously amiss and must be corrected' +CR+ + 'before trying to run GPSBabelGUI again.' +CR+CR+ + '°Warnings simply indicate that you are trying to do something' +CR+ + 'out of order, such as attempting to Process before defining' +CR+ + 'an input or output file.' +CR+CR+ + '°Information dialogs provide you with useful information, such' +CR+ + 'as letting you know that a conversion has completed.' +CR+CR+ + 'The About box displays copyright information for several seconds.' + ), 'Introduction', MB_OK); +end; + +procedure TGPSBabelGUIDialog.btnOutputFileDialogClick (Sender: TObject); +var + sExt: string; + i: integer; +begin + if OKtoRun then begin + dlgSaveOutput.filename := eOutput.Text; + if dlgSaveOutput.Execute then begin + eOutput.Text := dlgSaveOutput.filename; + sExt := uppercase (ExtractFileExt (eOutput.text)); + for i := 0 to nFormats-1 do + if '.' + uppercase (GPSDataFormats[i].sExt) = sExt then + comboOutput.ItemIndex := i; + end; + end; +end; + +procedure TGPSBabelGUIDialog.btnProcessClick (Sender: TObject); +var + f: file; +begin + if OKtoRun then begin + if eInput.text <> '' then begin + if FileExists (eInput.text) then begin + if (comboInput.ItemIndex) > -1 then begin // Input type is selected + if ((eOutput.text <> '') and (not DirectoryExists (eOutput.text))) then begin + // The output file must exist, or else ExtractShortPathName will not function + if not FileExists (eOutput.text) then begin + system.assign (f, eOutput.text); + system.rewrite (f); + system.close (f); + end; + + if (comboOutput.ItemIndex) > -1 then begin // Output type is selected + if cbIgnoreShort.checked then + sIgnoreShort := '-s' + else + sIgnoreShort := ''; + + // Construct the command line to execute gpsbabel.exe. ExtractShortPathName + // is used to reduce any "long" file/directory names in the paths down to + // 8.3 dos format names (this removes spaces, etc). + sCmd := 'GPSBabel '+sIgnoreShort // +'-i garmin -f usb:' // for testing + +' -i ' + GPSDataFormats [comboInput.ItemIndex].sType + +' -f ' + ExtractShortPathName (eInput.text) + +' -o ' + GPSDataFormats [comboOutput.ItemIndex].sType + +' -F ' + ExtractShortPathName (eOutput.text); + + SecurityAttr.nLength := sizeof (TSECURITYATTRIBUTES); + SecurityAttr.bInheritHandle := true; + SecurityAttr.lpSecurityDescriptor := nil; + + if CreatePipe (hRead, hWrite, @SecurityAttr, 0) then begin + FillChar (StartupInfo, Sizeof (StartupInfo), 0); + StartupInfo.cb := Sizeof (StartupInfo); + StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; + StartupInfo.wShowWindow := SW_HIDE and SW_SHOWMINNOACTIVE; + StartupInfo.hStdInput := GetStdHandle (STD_INPUT_HANDLE); + StartupInfo.hStdOutput:= hWrite; + StartupInfo.hStdError := hWrite; + + if CreateProcess ( + nil, // lpApplicationName // pointer to name of executable module + // sCmd includes both the exec name and the command line parms in this call + pchar (sCmd), // lpCommandLine, // pointer to command line string + nil, // lpProcessAttributes, // pointer to process security attributes + nil, // lpThreadAttributes, // pointer to thread security attributes + true, // bInheritHandles, // handle inheritance flag + CREATE_NEW_CONSOLE, // dwCreationFlags, // creation flags + nil, // lpEnvironment, // pointer to new environment block + nil, // lpCurrentDirectory, // pointer to current directory name + StartupInfo, // lpStartupInfo, // pointer to STARTUPINFO + ProcessInfo) // lpProcessInformation // pointer to PROCESS_INFORMATION + then begin + + while (WaitForSingleObject (ProcessInfo.hProcess, 0)) <> WAIT_OBJECT_0 do; + + PeekNamedPipe (hRead, nil, 0, nil, @BytesRead, nil); + if BytesRead > 0 then begin // pipe not empty + ReadFile (hRead, Buffer, 4096, BytesRead, nil); + sGPSBabelMsg := copy (Buffer, 1, BytesRead); + MessageBox (0, pchar (sGPSBabelMsg),'Attention! Message from GPSBabel', MB_OK); + end + else // pipe is empty + MessageDlg ('File conversion complete.', mtInformation, [mbOk], 0); + end + else + MessageDlg ('Unable to execute GPSBabel.exe.', mtError, [mbOk], 0); + + CloseHandle (hRead); + CloseHandle (hWrite); + end + else + MessageDlg ('Unable to create pipe!', mtError, [mbOk], 0); + end + else + MessageDlg ('You must select the output file format.', mtWarning, [mbOk], 0); + end + else + MessageDlg ('Output file is not defined.', mtWarning, [mbOk], 0); + end + else + MessageDlg ('You must select the input file format.', mtWarning, [mbOk], 0); + end + else + MessageDlg ('Input file was not found.', mtWarning, [mbOk], 0); + end + else + MessageDlg ('Input file is not defined.', mtWarning, [mbOk], 0); + end + else + MessageDlg ('Can''t run.', mtError, [mbOk], 0); +end; + +procedure TGPSBabelGUIDialog.btnUseDefaultOutputClick(Sender: TObject); +begin + if eInput.text <> '' then begin + if (comboOutput.ItemIndex)> -1 then // Output type is selected + eOutput.text := LeftStr (eInput.text, AnsiPos (ExtractFileExt (eInput.text), eInput.text)) + + GPSDataFormats [comboOutput.ItemIndex].sExt + else + MessageDlg ('You must select the output file format.', mtWarning, [mbOk], 0); + end + else + MessageDlg ('Input file is not defined.', mtWarning, [mbOk], 0); +end; + +initialization +end. diff --git a/win32/gui/README.txt b/win32/gui/README.txt new file mode 100644 index 000000000..e7f3ff303 --- /dev/null +++ b/win32/gui/README.txt @@ -0,0 +1,4 @@ +This is a Windows (95/98/NT4/2K/XP) front-end for GPSBabel. +It is a stand-alone program in that it doesn't install any other files or change the registry. +It must able to find GPSBabel; the best place for it is in the same directory as GPSBabel. +Further help is available in GPSBabelGUI. diff --git a/win32/gui/VersionInfo.pas b/win32/gui/VersionInfo.pas new file mode 100644 index 000000000..683a1359a --- /dev/null +++ b/win32/gui/VersionInfo.pas @@ -0,0 +1,99 @@ +unit VersionInfo; + +interface + +uses + SysUtils, Windows; + +const + vsComments = 'Comments'; + vsCompanyName = 'CompanyName'; + vsFileDescription = 'FileDescription'; + vsFileVersion = 'FileVersion'; + vsInternalName = 'InternalName'; + vsLegalCopyright = 'LegalCopyright'; + vsLegalTrademarks = 'LegalTrademarks'; + vsOriginalFilename = 'OriginalFilename'; + vsPrivateBuild = 'PrivateBuild'; + vsProductName = 'ProductName'; + vsProductVersion = 'ProductVersion'; + vsSpecialBuild = 'SpecialBuild'; + +type + TFileInfo = (TFileVersion, TFileVersionLong, TProductVersion, TProductVersionLong); + +function GetVersionString (const vsKey: string): string; +function GetFileVersion (const fInfo: TFileInfo): string; + +implementation + +var + VerInfoPresent: Boolean; // True if "pVersionBuffer" contains valid information + pVersionBuffer: Pointer; // The file information is stored in this location + +function SwapLong (L: LongInt): LongInt; assembler; +asm + rol eax, 16; +end; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// ex: GetVersionString (vsCompanyName); returns "Down East Engineering" +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +function GetVersionString (const vsKey: string): string; +var + KeyPath: array [0..255] of char; + p: pointer; + Len: cardinal; +begin + Result := ''; + if VerInfoPresent then + if VerQueryValue (pVersionBuffer, '\VarFileInfo\Translation', p, Len) then begin + StrLFmt (KeyPath, 255, '\StringFileInfo\%.8x\%s', [SwapLong (LongInt (p^)), vsKey]); + if VerQueryValue (pVersionBuffer, KeyPath, p, Len) then + Result := strPas (PChar (p)); + end; +end; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// GetFileVersion (TFileVersionLong); returns "1.0.0.0" +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +function GetFileVersion (const fInfo: TFileInfo): string; +var + Len: cardinal; + pVerInfo: PVSFixedFileInfo; +begin + Result := ''; + if VerInfoPresent then + if VerQueryValue (pVersionBuffer, '\', Pointer (pVerInfo), Len) then + case fInfo of + TFileVersion: + with pVerInfo^ do + Result := Format('%d.%d', + [dwFileVersionMS shr 16, dwFileVersionMS and $FFFF]); + TFileVersionLong: + with pVerInfo^ do + Result := Format('%d.%d.%d.%d', + [dwFileVersionMS shr 16, dwFileVersionMS and $FFFF, + dwFileVersionLS shr 16, dwFileVersionLS and $FFFF]); + end; +end; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Here is where the information is actually read from the EXE file. +// Data is read once, when the unit is initialized, and stored in 'pVersionBuffer' +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +var + fname: array [0..MAX_PATH] of char; + bufsize: integer; + pVersionHandle: cardinal; + +initialization + StrPLCopy (fname, ParamStr(0), MAX_PATH); // fully qualified Application.ExeName + bufsize := GetFileVersionInfoSize (fname, pVersionHandle); + GetMem (pVersionBuffer, bufsize); + VerInfoPresent := (bufsize > 0) and GetFileVersionInfo (fname, 0, bufsize, pVersionBuffer); + +finalization + FreeMem (pVersionBuffer, bufsize); +end. + diff --git a/win32/gui/filelist.txt b/win32/gui/filelist.txt new file mode 100644 index 000000000..4405fa44e --- /dev/null +++ b/win32/gui/filelist.txt @@ -0,0 +1,17 @@ +AboutDialogU.ddp +AboutDialogU.dfm +AboutDialogU.pas +filelist.txt +GPSBabel Windows GUI 2.00.00 Project Plan.pdf +GPSBabelGUI.cfg +GPSBabelGUI.dof +GPSBabelGUI.dpr +GPSBabelGUI.exe +GPSBabelGUI.ico +GPSBabelGUI.res +GPSBabelGUI.todo +GPSBabelGUIDialogU.ddp +GPSBabelGUIDialogU.dfm +GPSBabelGUIDialogU.pas +README.txt +VersionInfo.pas diff --git a/xcsv.c b/xcsv.c new file mode 100644 index 000000000..4dbc437e1 --- /dev/null +++ b/xcsv.c @@ -0,0 +1,664 @@ +/* + XCSV - X Character Separated Values (.???) + + A hopefully not too feeble attempt at parsing whatever separated values + files into the waypoint structure and back out again. This is a config- + file wrapper around csv_util.c. + + Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include "defs.h" +#include "csv_util.h" +#include "jeeps/gpsmath.h" + +#if CSVFMTS_ENABLED +#define MYNAME "XCSV" +#define ISSTOKEN(a,b) (strncmp(a,b, strlen(b)) == 0) + +static char *styleopt = NULL; +static char *snlenopt = NULL; +static char *snwhiteopt = NULL; +static char *snupperopt = NULL; +static char *snuniqueopt = NULL; +char *prefer_shortnames = NULL; +char *xcsv_urlbase = NULL; +static char *opt_datum; + +static const char *intstylebuf = NULL; + +static +arglist_t xcsv_args[] = { + {"style", &styleopt, "Full path to XCSV style file", NULL, + ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX }, + {"snlen", &snlenopt, "Max synthesized shortname length", NULL, + ARGTYPE_INT, "1", NULL}, + {"snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"snupper", &snupperopt, "UPPERCASE synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"snunique", &snuniqueopt, "Make synth. shortnames unique", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"urlbase", &xcsv_urlbase, "Basename prepended to URL on output", + NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"prefer_shortnames", &prefer_shortnames, + "Use shortname instead of description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"datum", &opt_datum, "GPS datum (def. WGS 84)", + "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +/* a table of config file constants mapped to chars */ +static +char_map_t xcsv_char_table[] = { + { "COMMA", "," }, + { "COMMASPACE", ", " }, + { "SINGLEQUOTE", "'" }, + { "DOUBLEQUOTE", "\"" }, + { "COLON", ":" }, + { "SEMICOLON", ";" }, + { "NEWLINE", "\n" }, + { "CR", "\n" }, + { "CRNEWLINE", "\r\n" }, + { "TAB", "\t" }, + { "SPACE", " " }, + { "HASH", "#" }, + { "WHITESPACE", "\\w" }, + { "PIPE", "|" }, + { NULL, NULL } +}; + +void +xcsv_destroy_style(void) +{ + queue *elem, *tmp; + field_map_t *fmp; + ogue_t *ogp; + int internal = 0; + + /* + * If this xcsv_file struct came from a file we can free it all. + * If not, we can at least free the queue elements. + */ + + /* destroy the prologue */ + QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { + ogp = (ogue_t *)elem; + if (ogp->val) + xfree(ogp->val); + if (elem) + xfree(elem); + } + + /* destroy the epilogue */ + QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { + ogp = (ogue_t *)elem; + if (ogp->val) + xfree(ogp->val); + if (elem) + xfree(elem); + } + + /* destroy the ifields */ + QUEUE_FOR_EACH(&xcsv_file.ifield, elem, tmp) { + fmp = (field_map_t *) elem; + if (fmp->key) + xfree(fmp->key); + if (fmp->val) + xfree(fmp->val); + if (fmp->printfc) + xfree(fmp->printfc); + if (elem) + xfree(elem); + } + + /* destroy the ofields, if they are not re-mapped to ifields. */ + if (xcsv_file.ofield != &xcsv_file.ifield) { + QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { + fmp = (field_map_t *) elem; + if (fmp->key) + xfree(fmp->key); + if (fmp->val) + xfree(fmp->val); + if (fmp->printfc) + xfree(fmp->printfc); + if (elem) + xfree(elem); + } + + if (xcsv_file.ofield) + xfree(xcsv_file.ofield); + } + + /* other alloc'd glory */ + if (xcsv_file.field_delimiter) + xfree(xcsv_file.field_delimiter); + + if (xcsv_file.record_delimiter) + xfree(xcsv_file.record_delimiter); + + if (xcsv_file.badchars) + xfree(xcsv_file.badchars); + + if (xcsv_file.description) + xfree(xcsv_file.description); + + if (xcsv_file.extension) + xfree(xcsv_file.extension); + + if (xcsv_file.mkshort_handle) + mkshort_del_handle(&xcsv_file.mkshort_handle); + + /* return everything to zeros */ + internal = xcsv_file.is_internal; + memset(&xcsv_file, '\0', sizeof(xcsv_file)); + xcsv_file.is_internal = internal; +} + +const char * +xcsv_get_char_from_constant_table(char *key) +{ + char_map_t *cm = xcsv_char_table; + + while ((cm->key) && (strcmp(key, cm->key) != 0)) { + cm++; + } + + return (cm->chars); +} + +static void +xcsv_parse_style_line(const char *sbuff) +{ + int i, linecount = 0; + char *s, *p, *sp; + const char *cp; + char *key, *val, *pfc; + + /* + * tokens should be parsed longest to shortest, unless something + * requires a previously set value. This way something like + * SHORT and SHORTNAME don't collide. + */ + + /* whack off any comments */ + if ((p = strchr(sbuff, '#')) != NULL) { + if ((p > sbuff) && p[-1] == '\\') { + memmove(p-1, p, strlen(p)); + p[strlen(p)-1] = '\0'; + } else { + *p = '\0'; + } + } + + if (strlen(sbuff)) { + if (ISSTOKEN(sbuff, "FIELD_DELIMITER")) { + sp = csv_stringtrim(&sbuff[16], "\"", 1); + cp = xcsv_get_char_from_constant_table(sp); + if (cp) { + xcsv_file.field_delimiter = xstrdup(cp); + xfree(sp); + } + else + xcsv_file.field_delimiter = sp; + + p = csv_stringtrim(xcsv_file.field_delimiter, " ", 0); + + /* field delimiters are always bad characters */ + if (0 == strcmp(p, "\\w")) { + char *s = xstrappend(xcsv_file.badchars, " \n\r"); + if (xcsv_file.badchars) xfree(xcsv_file.badchars); + xcsv_file.badchars = s; + } else { + xcsv_file.badchars = xstrappend(xcsv_file.badchars, p); + } + + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "RECORD_DELIMITER")) { + sp = csv_stringtrim(&sbuff[17], "\"", 1); + cp = xcsv_get_char_from_constant_table(sp); + if (cp) { + xcsv_file.record_delimiter = xstrdup(cp); + xfree(sp); + } + else + xcsv_file.record_delimiter = sp; + + p = csv_stringtrim(xcsv_file.record_delimiter, " ", 0); + + /* record delimiters are always bad characters */ + if (xcsv_file.badchars) { + xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, + strlen(xcsv_file.badchars) + + strlen(p) + 1); + } else { + xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); + } + + strcat(xcsv_file.badchars, p); + + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "FORMAT_TYPE")) { + const char *p; + for (p = &sbuff[11]; *p && isspace(*p); p++) { + ; + } + if (ISSTOKEN(p, "INTERNAL")) { + xcsv_file.type = ff_type_internal; + } + /* this is almost inconcievable... */ + if (ISSTOKEN(p, "SERIAL")) { + xcsv_file.type = ff_type_serial; + } + } else + + if (ISSTOKEN(sbuff, "DESCRIPTION")) { + xcsv_file.description = csv_stringtrim(&sbuff[11],"", 0); + } else + + if (ISSTOKEN(sbuff, "EXTENSION")) { + xcsv_file.extension = csv_stringtrim(&sbuff[10],"", 0); + } else + + if (ISSTOKEN(sbuff, "SHORTLEN")) { + if (xcsv_file.mkshort_handle) + setshort_length(xcsv_file.mkshort_handle, atoi(&sbuff[9])); + } else + + if (ISSTOKEN(sbuff, "SHORTWHITE")) { + if (xcsv_file.mkshort_handle) + setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(&sbuff[12])); + } else + + if (ISSTOKEN(sbuff, "BADCHARS")) { + sp = csv_stringtrim(&sbuff[9], "\"", 1); + cp = xcsv_get_char_from_constant_table(sp); + + if (cp) { + p = xstrdup(cp); + xfree(sp); + } + else + p = sp; + + if (xcsv_file.badchars) { + xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, + strlen(xcsv_file.badchars) + + strlen(p) + 1); + } else { + xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); + } + + strcat(xcsv_file.badchars, p); + + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "PROLOGUE")) { + xcsv_prologue_add(xstrdup(&sbuff[9])); + } else + + if (ISSTOKEN(sbuff, "EPILOGUE")) { + xcsv_epilogue_add(xstrdup(&sbuff[9])); + } else + + if (ISSTOKEN(sbuff, "ENCODING")) { + p = csv_stringtrim(&sbuff[8], "\"", 1); + cet_convert_init(p, 1); + xfree(p); + } else + + if (ISSTOKEN(sbuff, "DATUM")) { + p = csv_stringtrim(&sbuff[5], "\"", 1); + xcsv_file.gps_datum = GPS_Lookup_Datum_Index(p); + is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", p); + xfree(p); + } else + + if (ISSTOKEN(sbuff, "DATATYPE")) { + p = csv_stringtrim(&sbuff[8], "\"", 1); + if (case_ignore_strcmp(p, "TRACK") == 0) { + xcsv_file.datatype = trkdata; + } + else if (case_ignore_strcmp(p, "ROUTE") == 0) { + xcsv_file.datatype = rtedata; + } + else if (case_ignore_strcmp(p, "WAYPOINT") == 0) { + xcsv_file.datatype = wptdata; + } + else { + fatal(MYNAME ": Unknown data type \"%s\"!\n", p); + } + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "IFIELD")) { + key = val = pfc = NULL; + + s = csv_lineparse(&sbuff[6], ",", "", linecount); + + i = 0; + while (s) { + switch(i) { + case 0: + /* key */ + key = csv_stringtrim(s, "\"", 1); + break; + case 1: + /* default value */ + val = csv_stringtrim(s, "\"", 1); + break; + case 2: + /* printf conversion */ + pfc = csv_stringtrim(s, "\"", 1); + break; + default: + break; + } + i++; + + s = csv_lineparse(NULL, ",", "", linecount); + } + + xcsv_ifield_add(key, val, pfc); + + } else + + /* + * as OFIELDs are implemented as an after-thought, I'll + * leave this as it's own parsing for now. We could + * change the world on ifield vs ofield format later.. + */ + if (ISSTOKEN(sbuff, "OFIELD")) { + int options = 0; + key = val = pfc = NULL; + + s = csv_lineparse(&sbuff[6], ",", "", linecount); + + i = 0; + while (s) { + switch(i) { + case 0: + /* key */ + key = csv_stringtrim(s, "\"", 1); + break; + case 1: + /* default value */ + val = csv_stringtrim(s, "\"", 1); + break; + case 2: + /* printf conversion */ + pfc = csv_stringtrim(s, "\"", 1); + break; + case 3: + /* Any additional options. */ + if (strstr(s, "no_delim_before")) { + options |= OPTIONS_NODELIM; + } + if (strstr(s, "absolute")) { + options |= OPTIONS_ABSOLUTE; + } + if (strstr(s, "optional")) { + options |= OPTIONS_OPTIONAL; + } + default: + break; + } + i++; + s = csv_lineparse(NULL, ",", "", linecount); + } + + xcsv_ofield_add(key, val, pfc, options); + } + } +} + + +/* + * A wrapper for xcsv_parse_style_line that reads until it hits + * a terminating null. Makes multiple calls to that function so + * that "ignore to end of line" comments work right. + */ +static void +xcsv_parse_style_buff(const char *sbuff) +{ + char ibuf[256]; + char *ibufp; + size_t i; + + while (*sbuff) { + ibuf[0] = 0; + i = 0; + for (ibufp = ibuf; *sbuff != '\n' && i++ < sizeof(ibuf); ) { + *ibufp++ = *sbuff++; + } + while (*sbuff == '\n' || *sbuff == '\r') + sbuff++; + *ibufp = 0; + xcsv_parse_style_line(ibuf); + } +} + +static void +xcsv_read_style(const char *fname) +{ + char *sbuff; + gbfile *fp; + + xcsv_file_init(); + + fp = gbfopen(fname, "rb", MYNAME); + + while ((sbuff = gbfgetstr(fp))) { + sbuff = lrtrim(sbuff); + xcsv_parse_style_line(sbuff); + } while (!gbfeof(fp)); + + /* if we have no output fields, use input fields as output fields */ + if (xcsv_file.ofield_ct == 0) { + if (xcsv_file.ofield) + xfree(xcsv_file.ofield); + xcsv_file.ofield = &xcsv_file.ifield; + xcsv_file.ofield_ct = xcsv_file.ifield_ct; + } + gbfclose(fp); +} + +/* + * Passed a pointer to an internal buffer that would be identical + * to the series of bytes that would be in a style file, we set up + * the xcsv parser and make it ready for general use. + */ +void +xcsv_read_internal_style(const char *style_buf) +{ + xcsv_file_init(); + xcsv_file.is_internal = 1; + + xcsv_parse_style_buff(style_buf); + + /* if we have no output fields, use input fields as output fields */ + if (xcsv_file.ofield_ct == 0) { + if (xcsv_file.ofield) + xfree(xcsv_file.ofield); + xcsv_file.ofield = &xcsv_file.ifield; + xcsv_file.ofield_ct = xcsv_file.ifield_ct; + } +} + +void +xcsv_setup_internal_style(const char *style_buf) +{ + xcsv_file_init(); + xcsv_destroy_style(); + xcsv_file.is_internal = !!style_buf; + intstylebuf = style_buf; +} + + +static void +xcsv_rd_init(const char *fname) +{ + + /* + * if we don't have an internal style defined, we need to + * read it from a user-supplied style file, or die trying. + */ + if (xcsv_file.is_internal ) { + xcsv_read_internal_style( intstylebuf ); + } + else { + if (!styleopt) + fatal(MYNAME ": XCSV input style not declared. Use ... -i xcsv,style=path/to/file.style\n"); + + xcsv_read_style(styleopt); + } + + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) { + if (global_opts.masked_objective & (TRKDATAMASK|RTEDATAMASK)) { + warning(MYNAME " attempt to read %s as a track or route, but this format only supports waypoints on read. Reading as waypoints instead.\n", fname); + } + } + + xcsv_file.xcsvfp = gbfopen(fname, "r", MYNAME); + xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum); + is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum); +} + +static void +xcsv_rd_deinit(void) +{ + gbfclose(xcsv_file.xcsvfp); + + xcsv_destroy_style(); +} + +static void +xcsv_wr_init(const char *fname) +{ + /* if we don't have an internal style defined, we need to + * read it from a user-supplied style file, or die trying. + */ + if (xcsv_file.is_internal ) { + xcsv_read_internal_style( intstylebuf ); + } + else { + + if (!styleopt) + fatal(MYNAME ": XCSV output style not declared. Use ... -o xcsv,style=path/to/file.style\n"); + + xcsv_read_style(styleopt); + } + + xcsv_file.xcsvfp = gbfopen(fname, "w", MYNAME); + xcsv_file.fname = (char *)fname; + + /* set mkshort options from the command line */ + if (global_opts.synthesize_shortnames) { + + if (snlenopt) + setshort_length(xcsv_file.mkshort_handle, atoi(snlenopt)); + + if (snwhiteopt) + setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(snwhiteopt)); + + if (snupperopt) + setshort_mustupper(xcsv_file.mkshort_handle, atoi(snupperopt)); + + if (snuniqueopt) + setshort_mustuniq(xcsv_file.mkshort_handle, atoi(snuniqueopt)); + + setshort_badchars(xcsv_file.mkshort_handle, xcsv_file.badchars); + + } + xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum); + is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum); +} + +static void +xcsv_wr_position_init(const char *fname) +{ + xcsv_wr_init(fname); +} + +static void +xcsv_wr_deinit(void) +{ + gbfclose(xcsv_file.xcsvfp); + + xcsv_destroy_style(); +} + +static void +xcsv_wr_position_deinit(void) +{ + xcsv_wr_deinit(); +} + + +static void +xcsv_wr_position(waypoint *wpt) +{ + /* Tweak incoming name if we don't have a fix */ + switch(wpt->fix) { + case fix_none: + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup("ESTIMATED Position"); + break; + default: + break; + } + + waypt_add(wpt); + xcsv_data_write(); + waypt_del(wpt); + + gbfflush(xcsv_file.xcsvfp); +} + +ff_vecs_t xcsv_vecs = { + ff_type_internal, + FF_CAP_RW_WPT, /* This is a bit of a lie for now... */ + xcsv_rd_init, + xcsv_wr_init, + xcsv_rd_deinit, + xcsv_wr_deinit, + xcsv_data_read, + xcsv_data_write, + NULL, + xcsv_args, + CET_CHARSET_ASCII, 0, /* CET-REVIEW */ + { NULL, NULL, NULL, xcsv_wr_position_init, xcsv_wr_position, xcsv_wr_position_deinit } + +}; +#else +void xcsv_read_internal_style(const char *style_buf) {} +void xcsv_setup_internal_style(const char *style_buf) {} +#endif //CSVFMTS_ENABLED diff --git a/xcsv_tokens.gperf b/xcsv_tokens.gperf new file mode 100644 index 000000000..728fdc837 --- /dev/null +++ b/xcsv_tokens.gperf @@ -0,0 +1,289 @@ +/* ANSI-C code produced by gperf version 3.0.2 */ +/* Command-line: gperf -L ANSI-C -D -t xcsv_tokens.in */ +/* Computed positions: -k'2,4-5,12' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "xcsv_tokens.in" +struct xt_mapping {char *name; int xt_token; }; + +#define TOTAL_KEYWORDS 69 +#define MIN_WORD_LENGTH 3 +#define MAX_WORD_LENGTH 21 +#define MIN_HASH_VALUE 7 +#define MAX_HASH_VALUE 148 +/* maximum key range = 142, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash (register const char *str, register unsigned int len) +{ + static unsigned char asso_values[] = + { + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 0, 149, 0, 10, 5, + 55, 40, 20, 0, 149, 60, 30, 40, 0, 20, + 70, 149, 50, 45, 30, 149, 30, 149, 40, 10, + 149, 149, 149, 149, 149, 0, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[11]]; + /*FALLTHROUGH*/ + case 11: + case 10: + case 9: + case 8: + case 7: + case 6: + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + case 2: + hval += asso_values[(unsigned char)str[1]]; + break; + } + return hval; +} + +#ifdef __GNUC__ +__inline +#endif +struct xt_mapping * +in_word_set (register const char *str, register unsigned int len) +{ + static struct xt_mapping wordlist[] = + { +#line 5 "xcsv_tokens.in" + {"ANYNAME", XT_ANYNAME}, +#line 43 "xcsv_tokens.in" + {"LAT_NMEA", XT_LAT_NMEA}, +#line 31 "xcsv_tokens.in" + {"ICON_DESCR", XT_ICON_DESCR}, +#line 6 "xcsv_tokens.in" + {"CADENCE", XT_CADENCE}, +#line 7 "xcsv_tokens.in" + {"CITY", XT_CITY}, +#line 52 "xcsv_tokens.in" + {"MAP_EN_BNG", XT_MAP_EN_BNG}, +#line 39 "xcsv_tokens.in" + {"LAT_DIR", XT_LAT_DIR}, +#line 15 "xcsv_tokens.in" + {"GEOCACHE_HINT", XT_GEOCACHE_HINT}, +#line 19 "xcsv_tokens.in" + {"GEOCACHE_PLACER", XT_GEOCACHE_PLACER}, +#line 37 "xcsv_tokens.in" + {"LAT_DECIMAL", XT_LAT_DECIMAL}, +#line 13 "xcsv_tokens.in" + {"GEOCACHE_CONTAINER", XT_GEOCACHE_CONTAINER}, +#line 16 "xcsv_tokens.in" + {"GEOCACHE_ISARCHIVED", XT_GEOCACHE_ISARCHIVED}, +#line 17 "xcsv_tokens.in" + {"GEOCACHE_ISAVAILABLE", XT_GEOCACHE_ISAVAILABLE}, +#line 51 "xcsv_tokens.in" + {"LON_NMEA", XT_LON_NMEA}, +#line 60 "xcsv_tokens.in" + {"PATH_SPEED", XT_PATH_SPEED}, +#line 54 "xcsv_tokens.in" + {"PATH_COURSE", XT_PATH_COURSE}, +#line 61 "xcsv_tokens.in" + {"PHONE_NR", XT_PHONE_NR}, +#line 36 "xcsv_tokens.in" + {"LAT_DECIMALDIR", XT_LAT_DECIMALDIR}, +#line 55 "xcsv_tokens.in" + {"PATH_DISTANCE_KM", XT_PATH_DISTANCE_KM}, +#line 48 "xcsv_tokens.in" + {"LON_DIR", XT_LON_DIR}, +#line 12 "xcsv_tokens.in" + {"FACILITY", XT_FACILITY}, +#line 56 "xcsv_tokens.in" + {"PATH_DISTANCE_MILES", XT_PATH_DISTANCE_MILES}, +#line 46 "xcsv_tokens.in" + {"LON_DECIMAL", XT_LON_DECIMAL}, +#line 40 "xcsv_tokens.in" + {"LAT_HUMAN_READABLE", XT_LAT_HUMAN_READABLE}, +#line 67 "xcsv_tokens.in" + {"TIMET_TIME", XT_TIMET_TIME}, +#line 33 "xcsv_tokens.in" + {"INDEX", XT_INDEX}, +#line 66 "xcsv_tokens.in" + {"STREET_ADDR", XT_STREET_ADDR}, +#line 41 "xcsv_tokens.in" + {"LAT_INT32DEG", XT_LAT_INT32DEG}, +#line 70 "xcsv_tokens.in" + {"URL", XT_URL}, +#line 45 "xcsv_tokens.in" + {"LON_DECIMALDIR", XT_LON_DECIMALDIR}, +#line 9 "xcsv_tokens.in" + {"COUNTRY", XT_COUNTRY}, +#line 44 "xcsv_tokens.in" + {"LOCAL_TIME", XT_LOCAL_TIME}, +#line 62 "xcsv_tokens.in" + {"POSTAL_CODE", XT_POSTAL_CODE}, +#line 49 "xcsv_tokens.in" + {"LON_HUMAN_READABLE", XT_LON_HUMAN_READABLE}, +#line 38 "xcsv_tokens.in" + {"LAT_DIRDECIMAL", XT_LAT_DIRDECIMAL}, +#line 63 "xcsv_tokens.in" + {"ROUTE_NAME", XT_ROUTE_NAME}, +#line 10 "xcsv_tokens.in" + {"DESCRIPTION", XT_DESCRIPTION}, +#line 20 "xcsv_tokens.in" + {"GEOCACHE_TERR", XT_GEOCACHE_TERR}, +#line 18 "xcsv_tokens.in" + {"GEOCACHE_LAST_FOUND", XT_GEOCACHE_LAST_FOUND}, +#line 65 "xcsv_tokens.in" + {"STATE", XT_STATE}, +#line 42 "xcsv_tokens.in" + {"LATLON_HUMAN_READABLE", XT_LATLON_HUMAN_READABLE}, +#line 50 "xcsv_tokens.in" + {"LON_INT32DEG", XT_LON_INT32DEG}, +#line 14 "xcsv_tokens.in" + {"GEOCACHE_DIFF", XT_GEOCACHE_DIFF}, +#line 59 "xcsv_tokens.in" + {"PATH_SPEED_MPH", XT_PATH_SPEED_MPH}, +#line 53 "xcsv_tokens.in" + {"NOTES", XT_NOTES}, +#line 22 "xcsv_tokens.in" + {"GMT_TIME", XT_GMT_TIME}, +#line 30 "xcsv_tokens.in" + {"HMSL_TIME", XT_HMSL_TIME}, +#line 4 "xcsv_tokens.in" + {"ALT_METERS", XT_ALT_METERS}, +#line 35 "xcsv_tokens.in" + {"ISO_TIME", XT_ISO_TIME}, +#line 47 "xcsv_tokens.in" + {"LON_DIRDECIMAL", XT_LON_DIRDECIMAL}, +#line 11 "xcsv_tokens.in" + {"EXCEL_TIME", XT_EXCEL_TIME}, +#line 34 "xcsv_tokens.in" + {"ISO_TIME_MS", XT_ISO_TIME_MS}, +#line 21 "xcsv_tokens.in" + {"GEOCACHE_TYPE", XT_GEOCACHE_TYPE}, +#line 29 "xcsv_tokens.in" + {"HMSG_TIME", XT_HMSG_TIME}, +#line 3 "xcsv_tokens.in" + {"ALT_FEET", XT_ALT_FEET}, +#line 58 "xcsv_tokens.in" + {"PATH_SPEED_KPH", XT_PATH_SPEED_KPH}, +#line 28 "xcsv_tokens.in" + {"HEART_RATE", XT_HEART_RATE}, +#line 57 "xcsv_tokens.in" + {"PATH_SPEED_KNOTS", XT_PATH_SPEED_KNOTS}, +#line 24 "xcsv_tokens.in" + {"GPS_HDOP", XT_GPS_HDOP}, +#line 8 "xcsv_tokens.in" + {"CONSTANT", XT_CONSTANT}, +#line 27 "xcsv_tokens.in" + {"GPS_VDOP", XT_GPS_VDOP}, +#line 64 "xcsv_tokens.in" + {"SHORTNAME", XT_SHORTNAME}, +#line 71 "xcsv_tokens.in" + {"YYYYMMDD_TIME", XT_YYYYMMDD_TIME}, +#line 32 "xcsv_tokens.in" + {"IGNORE", XT_IGNORE}, +#line 68 "xcsv_tokens.in" + {"TRACK_NAME", XT_TRACK_NAME}, +#line 26 "xcsv_tokens.in" + {"GPS_SAT", XT_GPS_SAT}, +#line 23 "xcsv_tokens.in" + {"GPS_FIX", XT_GPS_FIX}, +#line 69 "xcsv_tokens.in" + {"URL_LINK_TEXT", XT_URL_LINK_TEXT}, +#line 25 "xcsv_tokens.in" + {"GPS_PDOP", XT_GPS_PDOP} + }; + + static signed char lookup[] = + { + -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 2, -1, 3, -1, + 4, 5, -1, 6, 7, -1, 8, 9, -1, 10, 11, 12, -1, -1, + 13, -1, 14, 15, -1, 16, 17, -1, 18, 19, 20, 21, -1, 22, + -1, 23, -1, 24, -1, -1, -1, -1, 25, 26, 27, 28, 29, -1, + -1, 30, -1, -1, 31, 32, -1, 33, 34, 35, 36, -1, 37, 38, + 39, 40, 41, 42, 43, 44, -1, -1, 45, 46, 47, -1, -1, 48, + 49, 50, 51, -1, 52, 53, -1, -1, -1, 54, 55, 56, 57, -1, + 58, -1, -1, -1, -1, 59, -1, -1, -1, -1, 60, 61, -1, -1, + -1, 62, -1, -1, 63, -1, -1, -1, 64, -1, 65, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 66, 67, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 68 + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int index = lookup[key]; + + if (index >= 0) + { + register const char *s = wordlist[index].name; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &wordlist[index]; + } + } + } + return 0; +} diff --git a/xcsv_tokens.in b/xcsv_tokens.in new file mode 100644 index 000000000..460ed0003 --- /dev/null +++ b/xcsv_tokens.in @@ -0,0 +1,71 @@ +struct xt_mapping {char *name; int xt_token; }; +%% +ALT_FEET, XT_ALT_FEET +ALT_METERS, XT_ALT_METERS +ANYNAME, XT_ANYNAME +CADENCE, XT_CADENCE +CITY, XT_CITY +CONSTANT, XT_CONSTANT +COUNTRY, XT_COUNTRY +DESCRIPTION, XT_DESCRIPTION +EXCEL_TIME, XT_EXCEL_TIME +FACILITY, XT_FACILITY +GEOCACHE_CONTAINER, XT_GEOCACHE_CONTAINER +GEOCACHE_DIFF, XT_GEOCACHE_DIFF +GEOCACHE_HINT, XT_GEOCACHE_HINT +GEOCACHE_ISARCHIVED, XT_GEOCACHE_ISARCHIVED +GEOCACHE_ISAVAILABLE, XT_GEOCACHE_ISAVAILABLE +GEOCACHE_LAST_FOUND, XT_GEOCACHE_LAST_FOUND +GEOCACHE_PLACER, XT_GEOCACHE_PLACER +GEOCACHE_TERR, XT_GEOCACHE_TERR +GEOCACHE_TYPE, XT_GEOCACHE_TYPE +GMT_TIME, XT_GMT_TIME +GPS_FIX, XT_GPS_FIX +GPS_HDOP, XT_GPS_HDOP +GPS_PDOP, XT_GPS_PDOP +GPS_SAT, XT_GPS_SAT +GPS_VDOP, XT_GPS_VDOP +HEART_RATE, XT_HEART_RATE +HMSG_TIME, XT_HMSG_TIME +HMSL_TIME, XT_HMSL_TIME +ICON_DESCR, XT_ICON_DESCR +IGNORE, XT_IGNORE +INDEX, XT_INDEX +ISO_TIME_MS, XT_ISO_TIME_MS +ISO_TIME, XT_ISO_TIME +LAT_DECIMALDIR, XT_LAT_DECIMALDIR +LAT_DECIMAL, XT_LAT_DECIMAL +LAT_DIRDECIMAL, XT_LAT_DIRDECIMAL +LAT_DIR, XT_LAT_DIR +LAT_HUMAN_READABLE, XT_LAT_HUMAN_READABLE +LAT_INT32DEG, XT_LAT_INT32DEG +LATLON_HUMAN_READABLE, XT_LATLON_HUMAN_READABLE +LAT_NMEA, XT_LAT_NMEA +LOCAL_TIME, XT_LOCAL_TIME +LON_DECIMALDIR, XT_LON_DECIMALDIR +LON_DECIMAL, XT_LON_DECIMAL +LON_DIRDECIMAL, XT_LON_DIRDECIMAL +LON_DIR, XT_LON_DIR +LON_HUMAN_READABLE, XT_LON_HUMAN_READABLE +LON_INT32DEG, XT_LON_INT32DEG +LON_NMEA, XT_LON_NMEA +MAP_EN_BNG, XT_MAP_EN_BNG +NOTES, XT_NOTES +PATH_COURSE, XT_PATH_COURSE +PATH_DISTANCE_KM, XT_PATH_DISTANCE_KM +PATH_DISTANCE_MILES, XT_PATH_DISTANCE_MILES +PATH_SPEED_KNOTS, XT_PATH_SPEED_KNOTS +PATH_SPEED_KPH, XT_PATH_SPEED_KPH +PATH_SPEED_MPH, XT_PATH_SPEED_MPH +PATH_SPEED, XT_PATH_SPEED +PHONE_NR, XT_PHONE_NR +POSTAL_CODE, XT_POSTAL_CODE +ROUTE_NAME, XT_ROUTE_NAME +SHORTNAME, XT_SHORTNAME +STATE, XT_STATE +STREET_ADDR, XT_STREET_ADDR +TIMET_TIME, XT_TIMET_TIME +TRACK_NAME, XT_TRACK_NAME +URL_LINK_TEXT, XT_URL_LINK_TEXT +URL, XT_URL +YYYYMMDD_TIME, XT_YYYYMMDD_TIME diff --git a/xhtmlent.c b/xhtmlent.c new file mode 100644 index 000000000..499122dd7 --- /dev/null +++ b/xhtmlent.c @@ -0,0 +1,515 @@ +char *xhtml_entities = +"\n" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +" \n" +" \n" +"\n" +" \n" +" \n" +" \n" +"\n" +"\n" +" \n" +" \n" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +" \n" +"\n" +"\n" +"\n" +" \n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +" \n" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +" \n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +" \n" +" \n" +"\n" +" \n" +" \n" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +" \n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +" \n" +"\n" +"\n" +"\n" +" \n" +"\n" +"\n" +" \n" +"\n" +" \n" +" \n" +" \n" +; diff --git a/xmldoc/.cvsignore b/xmldoc/.cvsignore new file mode 100644 index 000000000..b4dd115d7 --- /dev/null +++ b/xmldoc/.cvsignore @@ -0,0 +1 @@ +makedoc diff --git a/xmldoc/autogen/.cvsignore b/xmldoc/autogen/.cvsignore new file mode 100644 index 000000000..6722cd96e --- /dev/null +++ b/xmldoc/autogen/.cvsignore @@ -0,0 +1 @@ +*.xml diff --git a/xmldoc/babelmain.xsl b/xmldoc/babelmain.xsl new file mode 100644 index 000000000..1bcac1910 --- /dev/null +++ b/xmldoc/babelmain.xsl @@ -0,0 +1,35 @@ + + + + + +http://www.gpsbabel.org/style3.css +1 +1 +1 + + + + + + #include virtual="../navbar.inc" + #include virtual="../doc-header.inc" + + + + + + + + + + #include virtual="../doc-footer.inc" + + + + + + diff --git a/xmldoc/babelpdf.xsl b/xmldoc/babelpdf.xsl new file mode 100644 index 000000000..1036c6c56 --- /dev/null +++ b/xmldoc/babelpdf.xsl @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100% + + + + + + + + + fixed + + + + + + + + + + 1 + + + + + + + + + + + 1 + + + + + + + + + diff --git a/xmldoc/chapters/_chapters.xml b/xmldoc/chapters/_chapters.xml new file mode 100644 index 000000000..c7c29b8ab --- /dev/null +++ b/xmldoc/chapters/_chapters.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/xmldoc/chapters/allchapters.xml b/xmldoc/chapters/allchapters.xml new file mode 100644 index 000000000..71400b93d --- /dev/null +++ b/xmldoc/chapters/allchapters.xml @@ -0,0 +1,9 @@ +&chap_preface; +&chap_build; +&chap_use; +&chap_formats; +&chap_filters; +&app_datums; +&app_garmin_icons; +&app_styles; +&app_glossary; diff --git a/xmldoc/chapters/build.xml b/xmldoc/chapters/build.xml new file mode 100644 index 000000000..eb4e4f92c --- /dev/null +++ b/xmldoc/chapters/build.xml @@ -0,0 +1,64 @@ + + Getting it and Building it + +GPSBabel is distributed "ready to run" on most common +operating systems via the +download page. + + As GPSBabel runs on a wide variety of operating systems, +be sure to visit the +OS-Specific notes for +additional information. + + + For operating systems where no binary is provided or if +you want the latest development version, you will have to build it from +source. The code should be compilable on any system with +ISO C89 compilers. It's been tested on UnixWare, OpenServer, OS/X, +Linux, Solaris, and a variety of processors and compilers. + + + In most cases, the code is as simple to build as running: + + ./configure && make + Expat +is strongly recommended for source builds as it is +required for reading all the XML formats such as GPX. Fedora users +may need to 'yum install expat-devel'. Ubuntu users may need to +'apt-get install expat libexpat-dev'. + + libusb +is recommended for OS/X and Linux if you want to use a USB Garmin. +Fedora users may need to 'yum install expat-devel'. Ubuntu users may +need to 'apt-get install libusb-dev'. + +There are additional flags that can be passed to configure to + customize your build of GPSBabel. + +./configure --help + +lists all the supported options, but of interest we have: + Excludes the shapefile support. + + + Excludes the Palm database support and all formats that rely on it. + + + Excludes all support for our something-separated formats. + + + Excludes all filter support. + + + Activate debugging mode for gpsbabel-debug. + + + dir Specifies that the doc should be created and installed in dir. + + + Disables use of libusb, even it's it's available. + + + By default, we use our own version of zlib. If you specify the system zlib is used. A value of (or --without-zlib) disables zlib. + + diff --git a/xmldoc/chapters/datums.xml b/xmldoc/chapters/datums.xml new file mode 100644 index 000000000..202077d56 --- /dev/null +++ b/xmldoc/chapters/datums.xml @@ -0,0 +1,138 @@ + +Supported Datums + +Some formats in GPSBabel support multiple datums. For example, the + option to the +garmin_txt format allows you to specify +a datum for the output file. + + +The following is a list of the datums supported by GPSBabel. + + + +Adindan +AFG +Ain-El-Abd +Alaska-NAD27 +Alaska-Canada +Anna-1-Astro +ARC 1950 Mean +ARC 1960 Mean +Asc Island 58 +Astro B4 +Astro Beacon E +Astro pos 71/4 +Astro stn 52 +Australia Geo 1984 +Bahamas NAD27 +Bellevue IGN +Bermuda 1957 +Bukit Rimpah +Camp_Area_Astro +Campo_Inchauspe +Canada_Mean(NAD27) +Canal_Zone_(NAD27) +Canton_Island_1966 +Cape +Cape_Canaveral_mean +Carribean NAD27 +Carthage +Cent America NAD27 +Chatham 1971 +Chua Astro +Corrego Alegre +Cuba NAD27 +Cyprus +Djakarta(Batavia) +DOS 1968 +Easter lsland 1967 +Egypt +European 1950 +European 1950 mean +European 1979 mean +Finnish Nautical +Gandajika Base +Geodetic Datum 49 +Ghana +Greenland NAD27 +Guam 1963 +Gunung Segara +Gunung Serindung 1962 +GUX1 Astro +Herat North +Hjorsey 1955 +Hong Kong 1963 +Hu-Tzu-Shan +Indian +Iran +Ireland 1965 +ISTS 073 Astro 69 +Johnston Island 61 +Kandawala +Kerguelen Island +Kertau 48 +L.C. 5 Astro +La Reunion +Liberia 1964 +Luzon +Mahe 1971 +Marco Astro +Masirah Is. Nahrwan +Massawa +Merchich +Mexico NAD27 +Midway Astro 61 +Mindanao +Minna +Montjong Lowe +Nahrwan +Naparima BWI +North America 83 +N. America 1927 mean +Observatorio 1966 +Old Egyptian +Old Hawaiian_mean +Old Hawaiian Kauai +Old Hawaiian Maui +Old Hawaiian Oahu +Oman +OSGB36 +Pico De Las Nieves +Pitcairn Astro 67 +S. Am. 1956 mean(P) +S. Chilean 1963 (P) +Puerto Rico +Pulkovo 1942 +Qornoq +Quatar National +Rome 1940 +S-42(Pulkovo1942) +S.E.Asia_(Indian) +SAD-69/Brazil +Santa Braz +Santo (DOS) +Sapper Hill 43 +Schwarzeck +Sicily +Sierra Leone 1960 +S. Am. 1969 mean +South Asia +Southeast Base +Southwest Base +Tananarive Obs 25 +Thai/Viet (Indian) +Timbalai 1948 +Tokyo mean +Tristan Astro 1968 +United Arab Emirates +Viti Levu 1916 +Wake Eniwetok 60 +WGS 72 +WGS 84 +Yacare +Zanderij +Sweden + + + diff --git a/xmldoc/chapters/filters.xml b/xmldoc/chapters/filters.xml new file mode 100644 index 000000000..e5b18c8da --- /dev/null +++ b/xmldoc/chapters/filters.xml @@ -0,0 +1,23 @@ + + Data Filters + GPSBabel supports data filtering. Data filters are + invoked from the command line via the '-x' option. It should be + noted that data filters are invoked in the internal pipeline at + the point that corresponds to their position on the + command. This implies that specifying a filter before reading + any data ('-x <filter> -f <file>'), despite being + legal, will not have any effect. The advantage is that filters + can be used intermittently between several variations of input + and output functions. It should also be noted that filtering + data from different input types can sometimes produce + undesirable results due to differences in the native data + formats. + + Beware that most filters only apply to a certain kind of + data. This is usually indicated below by referring to points, + tracks or routes in the first sentence which describes each + filter or in the table at gpsbabel.org + . + + &filters; + diff --git a/xmldoc/chapters/formats.xml b/xmldoc/chapters/formats.xml new file mode 100644 index 000000000..a06e0be6b --- /dev/null +++ b/xmldoc/chapters/formats.xml @@ -0,0 +1,4 @@ + + The Formats + &formats; + diff --git a/xmldoc/chapters/garmin_icons.xml b/xmldoc/chapters/garmin_icons.xml new file mode 100644 index 000000000..e9ee8a06f --- /dev/null +++ b/xmldoc/chapters/garmin_icons.xml @@ -0,0 +1,314 @@ + +Garmin Icons + +Following is a list of the valid values for the +garmin option. +These values are also used internally by the +GDB, +BCR, +Mapsource, +Geoniche, +GPilotS, +PCX, and +PSITrex +formats. + + + +ATV +Airport +Amusement Park +Anchor +Anchor Prohibited +Animal Tracks +Asian Food +Bait and Tackle +Ball Park +Bank +Bar +Beach +Beacon +Bell +Big Game +Bike Trail +Blind +Block, Blue +Block, Green +Block, Red +Blood Trail +Boat Ramp +Border Crossing (Port Of Entry) +Bottom Conditions +Bowling +Bridge +Building +Buoy, White +Campground +Car +Car Rental +Car Repair +Cemetery +Church +Circle with X +Circle, Blue +Circle, Green +Circle, Red +City (Capitol) +City (Large) +City (Medium) +City (Small) +City Hall +Civil +Coast Guard +Contact, Afro +Contact, Alien +Contact, Ball Cap +Contact, Big Ears +Contact, Biker +Contact, Blonde +Contact, Bug +Contact, Cat +Contact, Clown +Contact, Dog +Contact, Dreadlocks +Contact, Female1 +Contact, Female2 +Contact, Female3 +Contact, Glasses +Contact, Goatee +Contact, Kung-Fu +Contact, Panda +Contact, Pig +Contact, Pirate +Contact, Ranger +Contact, Smiley +Contact, Spike +Contact, Sumo +Controlled Area +Convenience Store +Cover +Covey +Crossing +Dam +Danger Area +Deli +Department Store +Diamond, Blue +Diamond, Green +Diamond, Red +Diver Down Flag 1 +Diver Down Flag 2 +Dock +Dot, White +Drinking Water +Dropoff +Elevation point +Event Cache +Exit +Exit without services +Fast Food +First approach fix +Fishing Area +Fishing Hot Spot Facility +Fitness Center +Flag +Flag, Blue +Flag, Green +Flag, Red +Food Source +Forest +Furbearer +Gambling/casino +Gas Station +Geocache +Geocache Found +Geographic place name, Man-made +Geographic place name, land +Geographic place name, water +Ghost Town +Glider Area +Golf Course +Ground Transportation +Heliport +Horn +Hotel +House +Hunting Area +Ice Skating +Information +Intersection +Intl freeway hwy +Intl national hwy +Italian food +Large Ramp intersection +Large exit without services +Letter A, Blue +Letter A, Green +Letter A, Red +Letter B, Blue +Letter B, Green +Letter B, Red +Letter C, Blue +Letter C, Green +Letter C, Red +Letter D, Blue +Letter D, Green +Letter D, Red +Letterbox Cache +Levee +Library +Light +Live Theater +Localizer Outer Marker +Locationless (Reverse) Cache +Lodge +Lodging +Man Overboard +Marina +Medical Facility +Micro-Cache +Mile Marker +Military +Mine +Missed approach point +Movie Theater +Multi-Cache +Multi-Cache +Museum +Navaid, Amber +Navaid, Black +Navaid, Blue +Navaid, Green +Navaid, Green/Red +Navaid, Green/White +Navaid, Orange +Navaid, Red +Navaid, Red/Green +Navaid, Red/White +Navaid, Violet +Navaid, White +Navaid, White/Green +Navaid, White/Red +Non-directional beacon +Null +Number 0, Blue +Number 0, Green +Number 0, Red +Number 1, Blue +Number 1, Green +Number 1, Red +Number 2, Blue +Number 2, Green +Number 2, Red +Number 3, Blue +Number 3, Green +Number 3, Red +Number 4, Blue +Number 4, Green +Number 4, Red +Number 5, Blue +Number 5, Green +Number 5, Red +Number 6, Blue +Number 6, Green +Number 6, Red +Number 7, Blue +Number 7, Green +Number 7, Red +Number 8, Blue +Number 8, Green +Number 8, Red +Number 9, Blue +Number 9, Green +Number 9, Red +Oil Field +Open 24 Hours +Oval, Blue +Oval, Green +Oval, Red +Parachute Area +Park +Parking Area +Pharmacy +Picnic Area +Pin, Blue +Pin, Green +Pin, Red +Pizza +Police Station +Post Office +Post Office +Private Field +Puzzle Cache +RV Park +Radio Beacon +Ramp intersection +Rectangle, Blue +Rectangle, Green +Rectangle, Red +Reef +Residence +Restaurant +Restricted Area +Restroom +Scales +Scenic Area +School +Seafood +Seaplane Base +Shipwreck +Shopping Center +Short Tower +Shower +Ski Resort +Skiing Area +Skull and Crossbones +Small City +Small Game +Soft Field +Square, Blue +Square, Green +Square, Red +Stadium +State Hwy +Steak +Street Intersection +Stump +Summit +Swimming Area +TACAN +Tall Tower +Telephone +Tide/Current PRediction Station +Toll Booth +TracBack Point +Trail Head +Tree Stand +Treed Quarry +Triangle, Blue +Triangle, Green +Triangle, Red +Truck +Truck Stop +Tunnel +U Marina +U stump +US hwy +Ultralight Area +Unknown Cache +Upland Game +VHF Omni-range +VOR-DME +VOR/TACAN +Virtual cache +Water Hydrant +Water Source +Waterfowl +Waypoint +Webcam Cache +Weed Bed +Winery +Wrecker +Zoo + + diff --git a/xmldoc/chapters/glossary.xml b/xmldoc/chapters/glossary.xml new file mode 100644 index 000000000..4dd7effe4 --- /dev/null +++ b/xmldoc/chapters/glossary.xml @@ -0,0 +1,75 @@ + + Glossary + Terms that are used in conjunction with GPSBabel. + + G + + Geocaching + + GPS based "paper chase", see + + + + + + I + + Itinerary + + same as a Route (e.g. used by TomTom) + + + + + P + + Points of Interest (POI) + + a collection of gas stations, post boxes, shops and + like. + + + + + R + + Route + + a list of geopoints (often with names) connected in + a specific order. Usually a collection of geopoints + defining the route you want to pass while traveling, + created by PC software, or generated inside a GPS device. + They can be composed of existing waypoints, or new + "routepoints" might be generated. + + + + + T + + Track + + a collection of geopoints recorded by your GPS + device while traveling -- "breadcrumb trails". The order + of trackpoints within the track is important. Usually a + trackpoint doesn't have a name or comment, but a + timestamp. This distinguishes a trackpoint from a + waypoint. + + + + + W + + Waypoints + + are geopoints that are not necessarily connected to + other points, and their order is unimportant. They can be + entered before, while or after you actually visit the + place and might have tags like name, comment and the + like. Usually used to mark special locations as your + home, a hotel or a geocache. + + + + diff --git a/xmldoc/chapters/preface.xml b/xmldoc/chapters/preface.xml new file mode 100644 index 000000000..eba95ebc0 --- /dev/null +++ b/xmldoc/chapters/preface.xml @@ -0,0 +1,36 @@ + + Introduction +
                    + The Problem: Too many incompatible GPS file formats + There are simply too many gratuitously different file formats +to hold waypoint, track, and route information in various programs +used by computers and GPS receivers. +GPX defines a +standard in XML to contain all the data, but there are too many +programs that don't understand it yet and too much data in +alternate formats. + + +Perhaps you have an Explorist 600 and your friend has a StreetPilot 2720. +You've collected a a list of your favorite locations as waypoints and you'd +like to be able to share them. Unfortunately, his copy of Garmin Mapsource +won't read data created by your copy of Magellan Mapsend DirectRoute. What you need +is a program that converts data bewteen the two programs. + + +GPSBabel actually solves that problem for you and much more... + +
                    +
                    + The Solution + The original author of GPSBabel, Robert Lipe, needed to convert waypoints between a couple of formats, so he +whipped up a converter and designed it upon an extensible foundation so +that it was easy to add new formats and made the program freely available. Many others have contributed to the program since then. + Most file formats added so far have taken under 200 + lines of reasonable ISO C so they can be stamped + out pretty trivially. Formats that are ASCII text delimited in some + fixed way can be added with no programming at all via our + style mechanism. + +
                    +
                    diff --git a/xmldoc/chapters/styles.xml b/xmldoc/chapters/styles.xml new file mode 100644 index 000000000..4223913a2 --- /dev/null +++ b/xmldoc/chapters/styles.xml @@ -0,0 +1,1290 @@ + +GPSBabel XCSV Style Files + +
                    +Introduction + +Often it is desirable to add a new file format for "one-off" work (perhaps +you want to export something to a spreadsheet or graphing program) or to read +a format that GPSBabel does not yet support. For suitably simple formats, +this can be done by a user with no programming experience by providing a +GPSBabel style file. + + +For a format to be described by a style file, it must be predictable and +generally readable by humant. Formats with binary or unreadable content +are not good fits for this scheme. It should have: + +A fixed header at the beginning, if it has any at all. This is called a 'prologue'. +Waypoints that are grouped by fixed separators, often a newline. In style file parlance, this is called a 'record'. +Traits of that waypoint described in that record. In the style files, these are called 'fields' and examples may include longitude or a name. +Fields that are grouped by fixed separators, often a comma or a tab. In the style files, this is called the field separator. +A fixed footer at the end, if it has any at all. This is called the 'epilogue'. + + + +Once you have created a style file that describes the file format you have +or want, you must tell GPSBabel to use the xcsv format and have the xcsv +format use that file. If you created a new style file called +"mystyle.style" and you want to write the waypoints from +a GPX file named "mine.gpx" to it, you would issue a command like: + +gpsbabel -i gpx -f mine.gpx -o xcsv,style=mystyle.style -F mine.new + +You might then examine mine.new to see if it met +your expectations. If not, you could continue to tweak +mystyle.style until it did, rerunning the above +command each time. If 'mystyle' is a format +that describes a popular program or is likely to be of use to others, you can +then share mystyle.style with other GPSBabel users. +Send it along with a coherent descripton to the GPSBabel-misc mailing +list for consideration to be included in a future version. + +
                    +
                    +Style file overview + +The first and foremost important step is understanding how the style +file is laid out itself. The format is: + +DIRECTIVE<whitespace>VALUE + +Where <whitespace> is one or more spaces or tabs. There should +be no spaces or tabs at the beginning of the line; all directives start +at the left edge in column zero. + + +An example style format is shown here: + + +# Format: MS S&T 2002/2003 +# Author: Alex Mottram +# Date: 12/09/2002 +# + +DESCRIPTION Microsoft Streets and Trips 2002-2006 +EXTENSION txt + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER TAB +RECORD_DELIMITER NEWLINE +BADCHARS ," + +PROLOGUE Name Latitude Longitude Description URL Type Container Diff Terr + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# NOTE: MS S&T ONLY IMPORTS DATA, IT DOESN'T +# EXPORT THIS ANYWHERE SO WE CAN HAVE OUR +# WAY WITH THE FORMATTING. +# +IFIELD SHORTNAME, "", "%s" # Name +IFIELD LAT_DECIMAL, "", "%f" # Latitude +IFIELD LON_DECIMAL, "", "%f" # Longitude +IFIELD DESCRIPTION, "", "%s" # Name 2 (Big Description) +IFIELD URL, "", "%s" # URL +IFIELD GEOCACHE_TYPE, "", "%s" # Geocache Type +IFIELD GEOCACHE_CONTAINER, "", "%s" # Geocache Type +IFIELD GEOCACHE_DIFF, "", "%3.1f" # Geocache Type +IFIELD GEOCACHE_TERR, "", "%3.1f" # Geocache Type + +Each of these lines will be explained in the following sections. + +
                    + +
                    +Internal Constants + +A few internal constants are defined in the XCSV parser to make the style +file simpler. They may or may not be used and are optional in most cases. +Note that only certain style file directives map these constants. + + + + +Style Constant +Maps to Char(s) + +COMMA, + + +COMMASPACE,<space> + + +SINGLEQUOTE' + + +DOUBLEQUOTE" + + +COLON: + + +SEMICOLON; + + +NEWLINE\n + + +CR\r + + +CRNEWLINE\r\n + + +TAB\t + + +SPACE<space> + + +HASH# + + +PIPE| + + +WHITESPACEsee below + + + +
                    +WHITESPACE + +The WHITESPACE constant has special properties. When reading data, +WHITESPACE refers to sequential runs of SPACES and/or TABS. When +writing data, WHITESPACE is always a single SPACE. + + +For example, the following line: + +SOME_NAME 30.1208 -91.1365 SOME OTHER NAME + + +Parses into the following data fields: + +SOME_NAME,30.1208,-91.1365,SOME,OTHER,NAME + +
                    + +
                    +COMMENTS + +Anything after a hash (#) on a line is not parsed. For example: + +#THIS ENTIRE LINE IS A COMMENT. +#FIELD LAT_DECIMAL, "", "%f" THIS ENTIRE LINE IS A COMMENT +FIELD LAT_DECIMAL, "", "%f" # ONLY THIS SENTENCE IS A COMMENT. + +
                    +
                    + +
                    +Global Properties of the File + +There are a few available directives to describe general traits of the +file being described and not specific data within the file itself. + +
                    +DESCRIPTION + +This is the description of the file format being described. This text +appears in the help screens and in menus used by the various GUI wrappers. + +
                    +
                    +EXTENSION + +This directive gives the filename extension generally associated with +this file. + +
                    +
                    +ENCODING + +Describes the character set used by this format. The value given +must be one listed by 'gpsbabel -l'. example: + + ENCODING UTF-8 # Use UTF-8 for input and output. + +
                    +
                    +DATUM + +This value specifies the GPS datum to be used on read or write. Valid values for this +option are listed in . + + DATUM European 1950 + +
                    +
                    +DATATYPE + +Specifies the kind of data we have to read or write. + + +By default all data are seen as waypoint data. With DATATYPE you are now able to bind +a specific type to this format. Possible values are WAYPOINT, ROUTE or TRACK. + + DATATYPE ROUTE # route-only format + +
                    +
                    + +
                    +GPSBabel Behavior Directives + +There are a few available directives to control some of the internal +processing functions of GPSbabel. + +
                    +SHORTLEN + + This sets the maximum allowed shortname length when using the internal + shortname synthesizer. + + + example: + + SHORTLEN 16 # shortnames will be at most 16 characters long. + +
                    + +
                    +SHORTWHITE + + This tells the shortname synthesizer whether or not to allow whitespace + in the synthesized shortnames. Allowed values are zero and one. + + + example: + + SHORTWHITE 0 # Do not allow whitespace in shortname. + SHORTWHITE 1 # Allow whitespace in shortname. + +
                    +
                    + +
                    +Defining the Layout of the File + +The first few directives define the layout the physical file itself: + + +
                    +FIELD_DELIMITER + + The field delimiter defines the character(s) that separate the fields in + the rows of data inside the XCSV file. Common field delimiters are commas + and tabs. (referred to as "comma separated values" and "tab separated + values") + + + examples: + + FIELD_DELIMITER COMMA + FIELD_DELIMITER ~ + + + The directive FIELD_DELIMITER is parsed for STYLE CONSTANTS as defined in + the table above. + +
                    + +
                    +RECORD_DELIMITER + + The record delimiter defines that character(s) that separate ROWS of + data (FIELDS) in the XCSV file. The most common record delimiters + are NEWLINE and CR (carriage return). + + + examples: + + RECORD_DELIMITER NEWLINE + RECORD_DELIMITER | + + + The directive RECORD_DELIMITER is parsed for STYLE CONSTANTS as defined + in the table above. + +
                    + +
                    +BADCHARS + + Bad characters are things that should *never* be written into the XCSV + file as data on output. GPSBabel automatically includes any non-blank + FIELD_DELIMITER and RECORD_DELIMITER characters as BADCHARS by default. + + + examples: + + BADCHARS COMMA + BADCHARS ~| + + + The directive BADCHARS is parsed for STYLE CONSTANTS as defined in the + table above. + +
                    + +
                    +PROLOGUE + + A prologue is basically constant data that is written to the output + file BEFORE any waypoints are processed. PROLOGUE can be defined + multiple times in the style file, once for each "line" before the data + begins. This is commonly used in XCSV files as a "header" row. + + + examples: + + PROLOGUE OziExplorer Waypoint File Version 1.1 + PROLOGUE WGS 84 + PROLOGUE Symbol,Name,Latitude,Longitude + +
                    + +
                    +EPILOGUE + + An Epilogue is the same as a prologue, except this data is written at + the END of the file. See the examples for PROLOGUE above. + +
                    +
                    + +
                    +Defining Fields Within the File + +A field defines data. There are two different classifications of FIELDS, +IFIELD (file input) and OFIELD (file output). In the absence of any OFIELDS, +IFIELDS are use as both input and output. The existence of OFIELDS is +primarily to allow more flexible mapping of GPSBabel data to output data +(say, for instance, to map the internal GPSBabel "description" variable to +two or more fields on output). For all practical purposes, IFIELDS and +OFIELDS are defined the same way in the style file. +The following per-field options are defined: + + + + + "no_delim_before" is supported on in OFIELD tags to specify that this + field should be written without a field delimiter before it. It's + useful for limited field concatenation. + + + + + + "absolute" is supported on OFIELD tags for lat and lon to indicate + that only absolute values (never negative) are to be printed. + + + + + + "optional" is supported only OFIELD tags and indicates that the + field may or may not be available in the source data. If the + field is absent, no trailing field separator is written. + + + This attribute is most useful when paired with "no_delim_before" as + it allows you to concatenate fields without concern for whether those + fields are actually populated or not. + + + + + + +There are several different types of fields that may be defined. Each field +consists of three pieces of information: the FIELD TYPE, a DEFAULT VALUE, and +a PRINTF CONVERSION (for output). In many cases, not all pieces are used, +but all 3 pieces are required. Additionally, an fourth field is supported +that modifies the behaviour of the field being described. + + +FIELDS should be defined in the style file in the logical order that they +appear in the data, from left to right. This is the order in which they are +parsed from input and written to output. + + +The fields used by the XCSV parser are as follows: + + +
                    +IGNORE + + IGNORE fields are, guess what, ignored on input. Internally, IGNORE + fields are treated as CHARACTER data, and as such, require a printf + conversion for a character array. + + +examples: + + IFIELD IGNORE,"","%14.14s" # (writes a 14 character blank field) + IFIELD IGNORE,"","%s" # (writes a blank field on output) + +
                    + +
                    +CONSTANT + + CONSTANT fields are, of course, constant. They are ignored on input, + however they write CONSTANT data on output. As such, they require a + DEFAULT VALUE and a printf conversion for a character array. + + +examples: + + IFIELD CONSTANT,"FFFFFF","%s" # (writes "FFFFFF" in the field) + IFIELD CONSTANT,"01/01/70","%s" # (a constant date field) + +
                    + +
                    +INDEX + + An INDEX field is used ONLY on output. The INDEX constant defines a field + that, at output, contains the sequence number of the waypoint being + written, starting at 0. An index is managed internally as an INTEGER + and requires an INTEGER printf conversion. An INDEX has one special + property. The DEFAULT VALUE of the index is added to the index + on each iteration (to allow indexes starting at 1, 100, etc..). + + +examples: + + IFIELD INDEX,"0","%04d" # (Starts counting at zero) + IFIELD INDEX,"","%04d" # (Starts counting at zero) + IFIELD INDEX,"1","%04d" # (Starts counting at one) + +
                    + +
                    +SHORTNAME + + A SHORTNAME is generally the waypoint name of the data being processed. + SHORTNAME maps directly to the GPSBabel variable ->shortname. A SHORTNAME + is CHARACTER data and requires a character array printf conversion. + + +example: + + IFIELD SHORTNAME,"","%s" + +
                    + +
                    +DESCRIPTION + + A DESCRIPTION is generally a long description of the waypoint. A + DESCRIPTION maps to the GPSBabel variable ->description and is otherwise + handled exactly like a SHORTNAME. + + +examples: + + IFIELD DESCRIPTION,"","%s" + +
                    + +
                    +NOTES + + NOTES are generally everything else about a waypoints. NOTES map to the + GPSBabel variable ->notes and is otherwise handled exactly like a + SHORTNAME. + +
                    + +
                    +URL + + URL is a URL for the waypoint. URL maps to the GPSBabel variable + ->url and is otherwise handled exactly like a SHORTNAME. + + +example: + + IFIELD URL,"","%s" + +
                    + +
                    +URL_LINK_TEXT + + URL_LINK_TEXT is a textual description of where a URL points. + URL_LINK_TEXT maps to the GPSBabel variable ->url_link_text and + is otherwise handled exactly like a SHORTNAME. + + +example: + + IFIELD URL_LINK_TEXT,"","%s" + +
                    + +
                    +ICON_DESCR + + ICON_DESCR is a textual description of an icon type for a waypoint. + ICON_DESCR maps to the GPSBabel variable ->icon_desc and is otherwise + handled exactly like a SHORTNAME. + + +example: + + IFIELD ICON_DESCR,"","%s" + +
                    + +
                    +LAT_DECIMAL + + LAT_DECIMAL defines LATITUDE in DECIMAL format. Note that this is a PURE + signed decimal format (i.e. -91.0000). This data is handled internally as + a DOUBLE PRECISION FLOAT and requires a FLOATING POINT printf conversion. + + +example: + + IFIELD LAT_DECIMAL,"","%f" + +
                    + + +
                    +LON_DECIMAL + + See LAT_DECIMAL, except LON_DECIMAL defines LONGITUDE. + +
                    + +
                    +LAT_INT32DEG + + LAT_INT32DEG defines LATITUDE in what I call INT32DEGREES. This value is + a signed LONG INTEGER and requires a LONG INTEGER printf conversion. + (This format is only used by some DeLorme products.) + + +example: + + IFIELD LAT_INT32DEG,"","%ld" + +
                    + +
                    +LON_INT32DEG + + See LON_INT32DEG except LON_INT32DEG defines LONGITUDE. + +
                    + +
                    +LAT_DECIMALDIR / LAT_DIRDECIMAL + + LAT_DECIMALDIR and LAT_DIRDECIMAL define LATITUDE in DECIMAL format + with the added bonus of a 'N/S' or 'E/W' direction character. This data + is handled internally as a DOUBLE PRECISION FLOAT and a single + CHARACTER and requires a FLOATING POINT as well as a CHARACTER printf + conversion. The only difference between the two is whether the directional + character appears before (LAT_DIRDECIMAL) or after (LAT_DECIMALDIR) the + decimal number. + + +examples: + + IFIELD LAT_DECIMALDIR,"","%f %c" # (writes 31.333 N) + IFIELD LAT_DIRDECIMAL,"","%c %f" # (writes N 31.333) + +
                    + +
                    +LON_DECIMALDIR / LON_DIRDECIMAL + + Same as LAT_DECIMALDIR / LAT_DIRDECIMAL except LON_ defines LONGITUDE. + +
                    + +
                    +LAT_DIR / LON_DIR + + LAT_DIR returns the single character 'N' or 'S' depending on the + hemisphere of the latitude. LON_DIR returns 'E' or 'W' depending on + the hemisphere of the longitude. + +
                    + +
                    +LAT_HUMAN_READABLE + + LAT_HUMAN_READABLE defines LATITUDE in a human-readable format. This + format is probably the most expressive format. It is similar to + LAT_DECIMALDIR in that it requires multiple printf conversions, but it + is far more flexible as to the contents of those conversions. On read, + the printf conversions are ignored and GPSBabel attempts to determine the + latitude and longitude based on what is in the file. + + +examples: + + + # (writes N 31 40.000) + IFIELD LAT_HUMAN_READABLE,"","%c %d %f" + # (writes "31 deg 40.000 min N") + IFIELD LAT_HUMAN_READABLE,"","%d deg %f min %c" + # Note that this string will confuse the reading routine due + # to the letter "n" in "min" and the letter "e" in "deg." + # (writes 31 40 00.000N) + IFIELD LAT_HUMAN_READABLE,"","%d %d %f%c" + +
                    + +
                    +MAP_EN_BNG + + MAP_EN_BNG converts coordinates from/to British National Grid (BNG). + + + The only supported order of the items is: Map,Easting,Northing. + During output all coordinates have to be located within this limited area. + + +examples: + + + IFIELD MAP_EN_BNG,"","%s%5d %5d" # (writes i.e. "SJ00001 00001") + IFIELD MAP_EN_BNG,"","%s %d %d" # (writes i.e. "TQ 888 999") + +
                    + +
                    +LON_HUMAN_READABLE + + See LAT_HUMAN_READABLE except LON_HUMAN_READABLE defines LONGITUDE. + +
                    + +
                    +LATLON_HUMAN_READABLE + + LATLON_HUMAN_READABLE is like LAT_HUMAN_READABLE and LON_HUMAN_READABLE + except that it reads and writes both latitude and longitude as a single + field. On write, the same format specifier is used for both coordinates. + On read, GPSBabel does exactly the same thing it does for + LAT_HUMAN_READABLE or LON_HUMAN_READABLE. + + +example: + + IFIELD LATLON_HUMAN_READABLE,"","%c %d %f" + # (writes "N 31 40.126 W 85 09.62" as a single field) + +
                    + +
                    +LAT_NMEA + + Defines the latitude in the format used by the NMEA standard which is + degrees multiplied by 100 plus decimal minutes. + + +example: + + IFIELD LAT_NMEA, "%f", "%08.3f" # (writes 3558.322) + +
                    + +
                    +LON_NMEA + + Defines the longitude in the format used by the NMEA standard which is + degrees multiplied by 100 plus decimal minutes. + + +example: + + IFIELD LON_NMEA, "%f", "%010.3f" # (writes -08708.082) + +
                    + +
                    +LAT_10EX / LON_10EX + + Defines the latitude or longitude in the format used i.e. by TomTom Navigator + itinerary files. It is degress multiplied by 10 power X. X have to be replaced with + a valid decimal value. A factor of 10000 would be generated by LAT_10E5 as shown + in the examples below. + + +examples: + + IFIELD LAT_10E5, "%f", "%.f" # (writes 3558322) + + IFIELD LON_10E5, "%f", "%.f" # (writes -8708082) + +
                    + +
                    +ALT_FEET + + ALT_FEET is the position's ALTITUDE in FEET. This value is treated as + a SIGNED DOUBLE PRECISION FLOAT and requires a FLOATING POINT printf + conversion. + + +example: + + IFIELD ALT_FEET,"","%.0f" + +
                    + +
                    +ALT_METERS + + ALT_METERS is identical to ALT_FEET with the exception that the altitude + is in METERS. + +
                    + +
                    +HEART_RATE + + Heart rate, measured in beats per minute. Only valid for units with + heart rate monitor features (i.e. Garmin Forerunner 301). + + +example: + + IFIELD HEART_RATE,"","%d" + +
                    + +
                    +CADENCE + + Cadence in revolutions per minute. Only valid for units with + heart rate monitor features (i.e. Garmin Edge 305). + + +example: + + IFIELD CADENCE,"","%d" + +
                    + +
                    +EXCEL_TIME + + EXCEL_TIME is the waypoint's creation time, if any. This is actually + the decimal days since 1/1/1900 and is handled internally as a DOUBLE + PRECISION FLOAT and requires a FLOATING POINT printf conversion. + + +example: + + IFIELD EXCEL_TIME,"","%11.5f" + +
                    + +
                    +TIMET_TIME + + TIMET_TIME is the waypoint's creation time, if any. This is actually + the integer seconds since 1/1/1970 (let's not start the holy war) and + is handled internally as a LONG INTEGER and requires a LONG INTEGER + printf conversion. + + +example: + + IFIELD TIMET_TIME,"","%ld" + +
                    + +
                    +YYYYMMDD_TIME + + YYYYMMDD_TIME is the waypoint's creation time, if any. It's a single + decimal field containing four digits of year, two digits of month, + and two digits of date. Internally it is a LONG INTEGER and thus + requires a LONG INTEGER printf conversion. + + +example: + + IFIELD YYYYMMDD_TIME,"","%ld" + +
                    + +
                    +GMT_TIME + + GMT_TIME is the waypoint's creation time, in UTC time zone. It uses the + strptime conversion format tags. + + +example: + + IFIELD GMT_TIME,"","%m/%d/%Y %I:%M:%D %p" + + + Search the web for 'strptime man page' for details strptime, but one + such page can be found at +http://www.die.net/doc/linux/man/man3/strptime.3.html + +
                    + +
                    +LOCAL_TIME + + LOCAL_TIME is the waypoint's creation time, in the local + time zone. It uses strptime conversion format tags. See GMT_TIME for a + reference. + + +example: + + IFIELD LOCAL_TIME,"","%y-%m-%d" + +
                    + +
                    +HMSG_TIME + + HMSG_TIME parses up to three time parts and am/pm string to add + this value to the previously parsed *_TIME field that contains + only a date. On output, will print the time in UTC. + + +example: + + IFIELD HMSG_TIME,"","%d:%d:%d %s" + +
                    + +
                    +HMSL_TIME + + HMSG_TIME parses up to three time parts and am/pm string to add + this value to the previously parsed *_TIME field that contains + only a date. On output, will print the time in local time. + + +example: + + IFIELD HMSL_TIME,"","%dh%dm" + +
                    + +
                    +ISO_TIME + + ISO_TIME is the waypoint's creation time, in ISO 8601 format, + which include time zone information. + It is expected to be in the format yyyy-mm-ddThh:mm:sszzzzz + where zzzzzz is the local time offset or the character Z + for UTC time. + On output, UTC 'Z' time zone will always be used. + + +example: + + IFIELD ISO_TIME,"","%s" + +
                    + +
                    +ISO_TIME_MS + + ISO_TIME_MS is much like ISO_TIME, but expresses milliseconds at the + end of the timestamp. + It is thus in the format yyyy-mm-ddThh:mm:ss.SSSzzzzz + where 'SSS' is milliseconds and zzzzzz is the local time offset + or the character Z for UTC time. + On output, UTC 'Z' time zone will always be used. + + +example: + + IFIELD ISO_TIME_MS,"","%s" + +
                    + +
                    +GEOCACHE_DIFF + + GEOCACHE_DIFF is valid only for geocaches and represents a DOUBLE + PRECISION FLOAT. This is the geocache "difficulty" rating as defined by + Groundspeak. A "three and a half star" cache would therefore be "3.5" + + +example: + + IFIELD GEOCACHE_DIFF,"","%3.1f" + +
                    + +
                    +GEOCACHE_TERR + + GEOCACHE_TERR is valid only for geocaches and represents a DOUBLE + PRECISION FLOAT. This is the geocache "terrain" rating as defined + by Groundspeak. A "three and a half star" cache would therefore be "3.5" + + +example: + + IFIELD GEOCACHE_TERR,"","%3.1f" + +
                    + +
                    +GEOCACHE_CONTAINER + + GEOCACHE_CONTAINER is valid only for geocaches and is heavily influenced + by the Groundspeak container types. Examples would include "Micro" + and "Virtual". + + +example: + + GEOCACHE_CONTAINER,"","%s" + +
                    + +
                    +GEOCACHE_TYPE + + GEOCACHE_TYPE is valid only for geocaches and is heavily influenced + by the Groundspeak cache types. Examples would include "Event cache" + and "Multi-Cache". + + +example: + + GEOCACHE_TYPE,"","%s" + +
                    + +
                    +GEOCACHE_PLACER + + GEOCACHE_PLACER is a string containing the name of the placer of a + geocache. + + +example: + + GEOCACHE_PLACER,"","%s" + +
                    + +
                    +GEOCACHE_ISAVAILABLE + + GEOCACHE_ISAVAILABLE is a string containing "True" or "False" + indicating whether a geocache is currently available or not. + + +example: + + GEOCACHE_ISAVAILABLE,"","%s" + +
                    + +
                    +GEOCACHE_ISARCHIVED + + GEOCACHE_ISARCHIVED is a string containing "True" or "False" + indicating whether a geocache has been archived. + + +example: + + GEOCACHE_ISARCHIVED,"","%s" + +
                    + +
                    +GEOCACHE_LAST_FOUND + + A long integer in format YYYYMMDD containing the last time this geocache + was found. + + +example: + + GEOCACHE_LAST_FOUND,"","%ld" + +
                    + +
                    +GEOCACHE_HINT + + The hint for this geocache. No additional transformation (such as rot13) + will be performed on this string. + + +example: + + GEOCACHE_HINT,"","%s" + +
                    + +
                    +PATH_DISTANCE_MILES + + PATH_DISTANCE_MILES outputs the total length of the route or track from + the start point to the current point, in miles. This and the altitude + could be used to create an elevation profile. PATH_DISTANCE_MILES is + a DOUBLE PRECISION FLOAT. + + + PATH_DISTANCE_MILES is not valid as an input field. + + + PATH_DISTANCE_MILES is only meaningful if the data comes from a track + or a route; waypoint data will generate essentially meaningless output. + + +example: + + PATH_DISTANCE_MILES,"","%f" + +
                    + +
                    +PATH_DISTANCE_KM + + PATH_DISTANCE_KM is like PATH_DISTANCE_MILES except it outputs the + length in kilometers. + +
                    + +
                    +PATH_SPEED + + Speed in meters per second. Gpsbabel does NOT calculate this data by + default; it is read from the input file if present. (If not present, + it may be calculated with the track + filter.) + + +example: + + PATH_SPEED,"","%f" + +
                    + +
                    +PATH_SPEED_KPH + + Like PATH_SPEED but means kilometers per hour. + + +example: + + PATH_SPEED_KPH,"","%.1f" + +
                    + +
                    +PATH_SPEED_MPH + + Like PATH_SPEED but means miles per hour. + + +example: + + PATH_SPEED_MPH,"","%.1f" + +
                    + +
                    +PATH_SPEED_KNOTS + + Like PATH_SPEED but means knots (nautical). + + +example: + + PATH_SPEED_KNOTS,"","%.1f" + +
                    + +
                    +PATH_COURSE + + Course in degerees. Gpsbabel does not calculate this data by default; + it is read from the input file if present. (If not present, it may be + calculated with the track filter.) + + +example: + + PATH_COURSE,"","%f" + +
                    + +
                    +GPS_HDOP / GPS_VDOP / GPS_PDOP + + GPS horizontal / vertical / positional dilution of precision + parameters. Needs float conversion. + + +example: + + GPS_HDOP,"","%f" + +
                    + +
                    +GPS_SAT + + Number of satellites used for determination of the position. Needs + integer conversion. + + +example: + + GPS_SAT,"","%d" + +
                    + +
                    +GPS_FIX + + Type of fix (see GPX spec or track +filter). Needs string conversion. + + +example: + + GPS_FIX,"","%s" + +
                    + +
                    +TRACK_NAME +The name of the track currently being operated on. Needs string conversion.example:TRACK_NAME, "", "%s"
                    + +
                    +ROUTE_NAME +The name of the route currently being operated on. Needs string conversion.example:ROUTE_NAME, "", "%s"
                    + +
                    +STREET_NAME +Street address including house number. Notice that this is not used for any geocoding, it's merely textual description associated with a position. +example:STREET_ADDR, "", "%s" +
                    + +
                    +CITY +The name of a city. Sometimes part of "Points of Interest". This is simple textual data associated with a position, no geocoding will be done.. +example:CITY, "", "%s" +
                    + +
                    +COUNTRY +The name of a country associated with a position. +example:COUNTRY, "", "%s" +
                    + +
                    +FACILITY +The name of a facility to associate with a position. +example:FACILITY, "", "%s" +
                    + +
                    +PHONE_NR +A phone number associated with a position. This is just textual data attached for convenience. +example:PHONE_NR, "", "%s" +
                    + +
                    +POSTAL_CODE +A postal code to associate with a position. It is freeform text and is not used by GPSBabel for any geocoding or such. +example:POSTAL_CODE, "", "%s" +
                    + +
                    + +
                    +Examples + +Here is one example style file from the GPSBabel source. + +# gpsbabel XCSV style file +# +# Format: Garmin POI +# Author: Robert Lipe +# Date: 10/07/2005 +# Reference: http://forums.groundspeak.com/GC/index.php?showtopic=110641&st=0&#entry1752204 +# +DESCRIPTION Garmin POI database +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA +SHORTLEN 24 + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LON_HUMAN_READABLE, "", "%08.5f" +IFIELD LAT_HUMAN_READABLE, "", "%08.5f" +IFIELD SHORTNAME, "", "%s" +IFIELD DESCRIPTION, "", "%s" + +OFIELD LON_DECIMAL, "", "%08.5f" +OFIELD LAT_DECIMAL, "", "%08.5f" +OFIELD SHORTNAME, "", "%-.24s" +OFIELD GEOCACHE_TYPE, "", " %-.4s", "no_delim_before,optional" +OFIELD GEOCACHE_CONTAINER, "", "/%-.4s ", "no_delim_before,optional" +OFIELD GEOCACHE_DIFF, "", "(%3.1f", "no_delim_before,optional" +OFIELD GEOCACHE_TERR, "", "/%3.1f)", "no_delim_before,optional" +OFIELD DESCRIPTION, "", "%-.50s" + +When used on a Groundspeak Pocket Query, it will output lines that +look like: + +-76.76234,38.39123,GC5370 Loca/Virt (1.0/1.0),Dude.. Wheres my Limo?? +-90.42345,38.55234,GCC8B Trad/Regu (2.0/2.0),Sweet Reward +-90.81456,38.62456,GC3091 Trad/Regu (1.5/2.0),Matson Hill + +that are suitable for Garmin's POI loader. + + +For additional examples, please see the +*.style files in the +style/ subdirectory of GPSBabel or at the online source tree. + +
                    + +
                    +Miscellaneous Notes +
                    +Default Values + +Default values are supported for any output fields that contain pure + character data output such as URL and NOTES. Default values are only + written on output and are not used to supplement missing input. When + using default values your mileage will vary greatly depending on the + input formats used to populate waypoint data. + +
                    +
                    + +
                    diff --git a/xmldoc/chapters/use.xml b/xmldoc/chapters/use.xml new file mode 100644 index 000000000..6c5a2970b --- /dev/null +++ b/xmldoc/chapters/use.xml @@ -0,0 +1,333 @@ + + Usage + + Invocation + +If you're using GPSBabel, you will need to know how to do at least two things: +read data from a file, and write it to another file. There are four basic +options you need to know to do those things: + + + +Command +Meaning + + format + Set input format + + + filename + Read file + + + format + Set output format + + + filename + Write output file + + + + +Case matters. Notably (lowercase) sets the input file. (uppercase) sets the output file. + + + + +The format parameters in the above list +refer to the names of formats or file types supported by GPSBabel. + +gpsbabel -? +will always show you the supported file types. In this document, the +various supported formats are listed in . The +name that you would use on the command line follows the format name in +parentheses. + + +Options are always processed in order from left to right. +In practical terms, this means that things you want to read should appear +in the command before things you want to write. This sometimes surprises +new users as adding options to turn on debugging at the end, for example, +doesn't work as the debugging is turned on after all the interesting work is +done. The reason for this strict ordering becomes more apparent once you +learn about mixing formats and filters. + + +The filename parameters specify the +name of a file to be read or written. + + +To use + GPSBabel in its simplest form, just tell it what you're reading, where to read + it from, what you're writing, and what to write it to. For + example: + gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx + tells it to read the file /tmp/geocaching.loc in geocaching.com + format and create a new file /tmp/geocaching.gpx in GPX format. It's important to note that the names have nothing to do with the formats actually used. + This command will read from a Magellan unit attached + to the first serial port on a Linux system (device names will + vary on other OSes; typically COMx: on WIndows) and write them as a geocaching loc file. + + Command showing Linux download from Magellan serial and writing to .loc file + gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc + + This second command does the same on Microsoft Windows. + + Command showing Windows download from Magellan serial and writing to .loc file + gpsbabel -i magellan -f com1 -o geo -F mag.loc + + Optionally, you may specify -s in any command line. This + causes the program to ignore any "short" names that may be + present in the source data format and synthesize one from the + long name. This is particularly useful if you're writing to + a target format that isn't the lowest common denominator but + the source data was written for the lowest common + denominator. This is useful for writing data from geocaching.com + to a GPS so my waypoints have "real" names instead of + the 'GC1234' ones that are optimized for receivers of the lowest + common denominator. + A geocacher using Linux with a Magellan receiver may thus find commands + like this useful. + gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0 + His counterpart on Windows will find this equivalent + gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1 + + + Suboptions + + Many of the available format options in GPSBabel can themselves + take options. While we try to make all the formats do the most + sensible thing possible without any extra options; this allows + great power and flexibility in the operation of the program. + + + Suboptions are comma separated and immediately follow the option + itself. The available suboptions are listed on the individual + format pages. We'll make an example from : + + gpsbabel -i gpx -f file.gpx -o kml,deficon="file://myicon.png",lines=0 -F one.kml -o kml -F two.kml + + This command will read the GPX file file.gpx + and create two KML files. one.kml will + have the given icon and no lines between track and routepoints. + two.kml will be created with the defaults used + in the KML writer. + + + Suboptions for the various formats allow you to change serial speeds, + pass arguments to filters, change the type of file written, override + icon defaults, and lots of other things. The suboptions for each + filetype are documented on the page in this document that describes + the option itself. + + + + Advanced Usage + Argument are processed in the order they appear on the command +line and are translated internally into a pipeline that data flows +through when executed. Normally one would: + + read from one input + optionally apply filters + write into one output + + but GPSBabel is flexible enough to allow more complicated +operations such as reading from several files (potentially of +different types), applying a filter, reading more data, then writing the +merged data to multiple destinations. + + The input file type remains unchanged until a new + -i argument is seen. + Files are read in the order they appear. So you could merge + three input files into one output file with: + + Merging multiple files into one + gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc + + You can merge files of different types: + + Merging multiple files of differing types. + gpsbabel -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx -o gpsutil -F big.gps + + + Writing the same data in multiple output formats. + You can write the same data in different output formats: + + gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx -F 1.wpt + + If you want to change the character set of input or/and + output side you can do this with the option . You can get a complete list + of supported character sets with "gpsbabel -l". To change + the character set on both sides you should do this: + gpsbabel -i xcsv,style=foo.style -c latin1 -f foo -o xcsv,style=bar.style -c ms-ansi -F bar + Note, that some formats have a fixed character set and ignore this option. + + + Route and Track Modes + Most formats supported by GPSBabel will make a reasonable attempt to work + transparently with waypoints, tracks, and routes. Some + formats, like garmin and magellan require the -t flag to work with tracks and + -r to work with + routes. -w is for + waypoints, and is the default. So if you wanted to read all + data from a Magellan Meridian GPS receiver into a gpx file, you might use a command + like: + gpsbabel -t -r -w -i magellan -f com1: -o gpx -F backup.gpx + Tracks and routes are advanced features and don't try + to handle every possible hazard that can be encountered + during a conversion. If you're merging or converting files + of similar limitations, things work very well. + Many of those hazards can be overcome with our filters + but there are often compromises to be made. For example, if you + have a GPX route that contains 150 turn points but you're sending + the route to a GPS receiver that supports only 30 turnpoints, something has + to go. One might use our 'simplify' filter to produce a route that + retained the 30 most mathematically significant turnpoints but that + may not really be the route you had in mind. + + Tracks and routes will sometimes be converted to a + list of waypoints when necessary, One example is when writing into one + of the CSV formats. The inverse operation is not supported + right now, so reading the converted track back from CSV will + always result in a list of waypoints, not the original track. + + The presence of -s on the command line tends to + creats havoc on tracks and routes since many of these formats + rely on internal linkages between such points and renaming + them may break those linkages. In general, don't use + -s when tracks or + routes are present. + + + + Working with predefined options + + GPSBabel can read a file on startup to set defaults for options. All + module and filter options may be set this way. + + + + The format of the file is identical to the inifile-format often seen + on Windows. Here is an example: + + + + [Common format settings] + snupper=Y + snlen=10 + [gpx] + gpxver=1.1 + [magellan] + baud=115200 + [tiger] + [Garmin categories] + ; any # from 1 to 16 + 1=fixed waypoints + 2=temporary waypoints + + + Each section of the file starts with a '[section]' header followed by any + number of lines formatted option=value. Leading and trailing whitespace + will be + automatically removed from header, option and value items. + + Lines starting + with '#' or ';' will be treated as comments and ignored. + + + + There are three optional sections. + + + Common format settings. + Any option from any of the formats listed here will be used by + GPSBabel unless explictly provided on the command line. + + + + Common filter settings. + As above, but for filters. + + + Garmin categories + This allows you to give readable names to the numeric categories + used internally in some Garmin devices and the Mapsource formats + such as GDB and MPS. This is information is also used by our GPX + and garmin_txt formats as well. + + + + + + By default, GPSBabel tries at startup to load the file named + gpsbabel.ini from the following locations: + + + current working directory + Windows: all paths "APPDATA", "WINDIR", "SYSTEMROOT" declared in environment. + Unix like OS'ses: ${HOME}/.gpsbabel/, /usr/local/etc/ and /etc/ + + + If the option is specified, the above locations are not searched. + Only the filename specified by that option will be used. + + + There may be situations where predefined values are not useable + (i.e. wrapper applications using GPSBabel in the background). + The inifile mechanism can be disabled with an empty filename. + + gpsbabel -p "" -i gpx -f something.gpx -o tiger -F - + + + Realtime tracking + + Introduced in GPSBabel 1.3.1, we now have an experimental feature for realtime tracking via the new option. This reads position reports from selected formats and writes an output file when a position report is received. + + + As of this writing, Garmin's PVT protocol and NMEA are supported + inputs. KML, NMEA, and the variou XCSV formats are supported on + output. Additional formats may be added by interested parties + later. + + + Read realtime positioning from Garmin USB, write to Keyhole Markup + gpsbabel -T -i garmin -f usb: -o kml -F xxx.kml + + + Will read the USB-connected Garmin and rewrite 'xxx.kml' atomically, + suitable for a self-refreshing network link in Google Earth. + + + + + Batch mode (command files) + + In addition to reading arguments from the command line, GPSBabel can + read directions from batch (or command) files via the option. + + + These files are ideal for holding long command lines, long file lists, complex filters + and so on. You can use all GPSBabel options and combinations when writing + such files. Nesting batch files by using the option within a batch file is supported. + + + Here is an example demonstrating segmenting a large command line + by placing the input and filtering directives in a file called 'all_my_files'. + + gpsbabel -b all_my_files -o gdb -F all_my_tracks.gdb + + 'all_my_files' could look like this: + + + -i gpx + -f saxony_in_summer_2004.gpx -f austria_2005.gpx + -i gdb + -f croatia_2006.gdb + -x nuketypes,waypoints,routes + -x track,pack,split,title="LOG # %Y%m%d" + + + diff --git a/xmldoc/filters/arc.xml b/xmldoc/filters/arc.xml new file mode 100644 index 000000000..3b901a28e --- /dev/null +++ b/xmldoc/filters/arc.xml @@ -0,0 +1,42 @@ + +This filter keeps or removes waypoints based on their proximity to an arc, +which is a series of connected line segments similar to a route or a track +but without any associated data other than the coordinates. + + + +The arc is defined in a file whose name must be provided with the +. That file contains pairs of coordinates for the +vertices of the arc, one coordinate pair per line. Comments may be +included by preceding them with a '#' character. An arc file looks +something like this sample: + + + +# Lima Road/SR3 north of Fort Wayne, Indiana +41.150064468 -85.166207433 +41.150064468 -85.165371895 +41.149034500 -85.165157318 +41.147832870 -85.164771080 +41.146631241 -85.164384842 +41.144270897 -85.163655281 +41.141953468 -85.162882805 + + + +An arc file may optionally contain gaps in the arc. You may specify +such a gap by inserting a line containing "#break" either on a line by +itself or after the coordinates of the starting point of the new arc segment. + + + +Using the arc filter + +Assuming the arc above is in a file called +lima_rd.txt, the following command line +would include only points within one mile of the section of Lima Road +covered by the arc. + +gpsbabel -i geo -f 1.loc -x arc,file=lima_rd.txt,distance=1 -o mapsend -F 2.wpt + + diff --git a/xmldoc/filters/discard.xml b/xmldoc/filters/discard.xml new file mode 100644 index 000000000..9b2a2ad26 --- /dev/null +++ b/xmldoc/filters/discard.xml @@ -0,0 +1,26 @@ + +This filter is used to "fix" unreliable GPS data by discarding points +that are believed to be unreliable. You may specify an +HDOP and/or VDOP above a specified limit, a minimum number of satellits +that must have been in view for a fix to be considered, or both. + + +HDOP and VDOP are measures of the best possible horizontal or vertical precision for a given configuration of GPS satellites. Higher numbers indicate a higher dilution of precision and therefore mathematically less useful. + + + +Using the discard filter for HDOP and VDOP. + gpsbabel -i gpx -f in.gpx -x discard,hdop=10,vdop=20,hdopandvdop -o gpx -F out.gpx + + + +You may specify a minimmum number of satellites. + + + +Using the discard filter to require at least three satellites. + gpsbabel -i gpx -f in.gpx -x discard,sat=3 -o gpx -F out.gpx + + + Contributed by Tobias Minich and Serge Droz. + diff --git a/xmldoc/filters/duplicate.xml b/xmldoc/filters/duplicate.xml new file mode 100644 index 000000000..2d5558d3f --- /dev/null +++ b/xmldoc/filters/duplicate.xml @@ -0,0 +1,20 @@ + +The duplicate filter is designed to remove duplicate points based on their +short name (traditionally a waypoint's name on the GPS receiver), and/or +their location (to a precision of 6 decimals). This filter supports two +options that specify how duplicates will be recognized, + and . +Generally, at least one of these options is required. + + + Using the duplicate filter to suppress points with the same + name and location + + This command line removes points that have duplicate short names + and duplicate locations. The result would be a + gpx file that more than likely + contains only unique points and point data. + + gpsbabel -i gpx -f 1.gpx -f 2.gpx -x duplicate,location,shortname -o gpx -F merged_with_no_dupes.gpx + + diff --git a/xmldoc/filters/interpolate.xml b/xmldoc/filters/interpolate.xml new file mode 100644 index 000000000..5f5f5a16f --- /dev/null +++ b/xmldoc/filters/interpolate.xml @@ -0,0 +1,30 @@ + +This filter modifies any tracks so that either the distance or the time +between consecutive points is no less than the specified interval. Where +points are missing, the filter fills them in by following a straight +line (actually a great circle) between the adjacent points. You +must specify either the + or the option. + + +Using the interpolate filter + +This command line reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 10 seconds apart: + +gpsbabel -i gpx -f track.gpx -x interpolate,time=10 -o gpx -F newtrack.gpx + + +This command reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 15 kilometers apart: + + +gpsbabel -i gpx -f track.gpx -x interpolate,distance=15k -o gpx -F newtrack.gpx + + +This command reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 2 miles apart: + + +gpsbabel -i gpx -f track.gpx -x interpolate,distance=2m -o gpx -F newtrack.gpx + diff --git a/xmldoc/filters/nuketypes.xml b/xmldoc/filters/nuketypes.xml new file mode 100644 index 000000000..21e9aa8fa --- /dev/null +++ b/xmldoc/filters/nuketypes.xml @@ -0,0 +1,16 @@ + +There are three main types of data that GPSBabel deals with: +waypoints, tracks, and routes. The nuketypes filter allows +removing all the data of any or all of those three types. + + +Filtering data types with nuketypes + +If you have a GPX file that contains routes, tracks, and +waypoints and you want a GPX file that contains only tracks, +you may use this filter to remove the waypoints and the routes +with this command: + +gpsbabel -i gpx -f bigfile.gpx -x nuketypes,waypoints,routes -o gpx -F tracksonly.gpx + + diff --git a/xmldoc/filters/options/arc-distance.xml b/xmldoc/filters/options/arc-distance.xml new file mode 100644 index 000000000..83a3189ec --- /dev/null +++ b/xmldoc/filters/options/arc-distance.xml @@ -0,0 +1,14 @@ + +This option is not required, but if it is not specified the distance +defaults to zero miles, which isn't very useful. + + +This option specifies the maximum distance a point may be from the arc +without being discarded. Points that are closer to the arc are kept, while +points that are further away are discarded. + + +Distances may be specified in miles (3M) or kilometers (5K). If no units +are specified, the distance is assumed to be in miles. + + diff --git a/xmldoc/filters/options/arc-exclude.xml b/xmldoc/filters/options/arc-exclude.xml new file mode 100644 index 000000000..37f84b3ba --- /dev/null +++ b/xmldoc/filters/options/arc-exclude.xml @@ -0,0 +1,6 @@ + +When this option is specified, the usual sense of the arc filter is reversed. +That is, points that are closer than distance are discarded +while points that are further away are kept. + + diff --git a/xmldoc/filters/options/arc-file.xml b/xmldoc/filters/options/arc-file.xml new file mode 100644 index 000000000..6316b64c4 --- /dev/null +++ b/xmldoc/filters/options/arc-file.xml @@ -0,0 +1,13 @@ + +This option is required. + + +This option specifies the name of the file containing the arc to use for +filtering. The format of the file is as described above. + + +GPSBabel supports converting any route or track to a file usable by this +filter; simply read it in the normal way and write it using the +arc file format. + + diff --git a/xmldoc/filters/options/arc-points.xml b/xmldoc/filters/options/arc-points.xml new file mode 100644 index 000000000..5f1c7d347 --- /dev/null +++ b/xmldoc/filters/options/arc-points.xml @@ -0,0 +1,11 @@ + +When this option is specified, only points that are within the specified +distance of one of the vertices of the arc are kept. This differs from the +normal mode of operation in that in the normal mode, points that are close to +the lines between points are also kept. + + +This option makes the arc filter act like a multi-point version of the +radius filter. + + diff --git a/xmldoc/filters/options/discard-hdop.xml b/xmldoc/filters/options/discard-hdop.xml new file mode 100644 index 000000000..8fcc16080 --- /dev/null +++ b/xmldoc/filters/options/discard-hdop.xml @@ -0,0 +1,7 @@ + +This option specifies the maximum allowable Horizontal Dilution of +Precision (HDOP). By default, any point with an HDOP in excess of +this value will be discarded regardless of its VDOP, but see +. + + diff --git a/xmldoc/filters/options/discard-hdopandvdop.xml b/xmldoc/filters/options/discard-hdopandvdop.xml new file mode 100644 index 000000000..d07dd4144 --- /dev/null +++ b/xmldoc/filters/options/discard-hdopandvdop.xml @@ -0,0 +1,6 @@ + +If this option is used, only points that exceed both the maximum +allowable HDOP and the maximum allowable VDOP will be discarded. This +option requires that both the and + options be specified. + diff --git a/xmldoc/filters/options/discard-sat.xml b/xmldoc/filters/options/discard-sat.xml new file mode 100644 index 000000000..10d2c14c4 --- /dev/null +++ b/xmldoc/filters/options/discard-sat.xml @@ -0,0 +1,4 @@ + +This option specifies the minimum required number of satelites. + + diff --git a/xmldoc/filters/options/discard-vdop.xml b/xmldoc/filters/options/discard-vdop.xml new file mode 100644 index 000000000..f8701abd8 --- /dev/null +++ b/xmldoc/filters/options/discard-vdop.xml @@ -0,0 +1,7 @@ + +This option specifies the maximum allowable Vertical Dilution of +Precision (VDOP). By default, any point with an VDOP in excess of +this value will be discarded regardless of its HDOP, but see +. + + diff --git a/xmldoc/filters/options/duplicate-all.xml b/xmldoc/filters/options/duplicate-all.xml new file mode 100644 index 000000000..bdbcfab60 --- /dev/null +++ b/xmldoc/filters/options/duplicate-all.xml @@ -0,0 +1,17 @@ + +When this option is specified, GPSBabel will remove all instances of a +duplicated waypoint, not just the second and subsequent instances. If +your input file contains waypoints A, B, B, and C, the output file will +contain waypoints A, B, and C without the option, +or just A and C with the option. + + +Using the duplicate filter to implement an "ignore list." + +This option may be used to implement an "ignore list." In the following +example, the duplicate filter is used to remove a list of waypoints to be +ignored from a larger collection of waypoints: + +gpsbabel -i gpx -f waypoints.gpx -i csv -f to_ignore.csv -x duplicate,shortname,all -o gpx -F filtered.gpx + + diff --git a/xmldoc/filters/options/duplicate-correct.xml b/xmldoc/filters/options/duplicate-correct.xml new file mode 100644 index 000000000..8faefd587 --- /dev/null +++ b/xmldoc/filters/options/duplicate-correct.xml @@ -0,0 +1,21 @@ + +This option is used to change the locations of waypoints without losing any +of the other associated information. When this option is specified, the +latitude and longitude from later duplicates will replace the latitude and +longitude in the original waypoint. + + +As an example, this option may be used to adjust the locations of "puzzle" +geocaches in a Groundspeak pocket query: + + +Using the duplicate filter to correct the locations of "puzzle" +geocaches +gpsbabel -i gpx -f 43622.gpx -i csv -f corrections.csv -x duplicate,shortname,correct -o gpx -F 43622-corrected.gpx + +After this command is run, the waypoints in the output file will have all +of the descriptive information from 43622.gpx, but +waypoints that were also found in corrections.csv +will have their coordinates replaced with the coordinates from that file. + + diff --git a/xmldoc/filters/options/duplicate-location.xml b/xmldoc/filters/options/duplicate-location.xml new file mode 100644 index 000000000..910bfc30c --- /dev/null +++ b/xmldoc/filters/options/duplicate-location.xml @@ -0,0 +1,9 @@ + +This option causes the duplicate filter to remove any additional waypoint +that has the same coordinates (to six decimal degrees) as a waypoint that +came before. This option may be used to remove duplicate waypoints if the +names are not expected to be the same. It also might be used along with the + option to remove duplicate waypoints if the names +of several unrelated groups of waypoints might be the same. + + diff --git a/xmldoc/filters/options/duplicate-shortname.xml b/xmldoc/filters/options/duplicate-shortname.xml new file mode 100644 index 000000000..72f88c2fc --- /dev/null +++ b/xmldoc/filters/options/duplicate-shortname.xml @@ -0,0 +1,9 @@ + +This option is the one most often used with the duplicate filter. This +option instructs the duplicate filter to remove any waypoints that share +a short name with a waypoint that has come before. This option might be +used to remove duplicates if you are merging two datasets that were +each created in part from a common ancestor dataset. + + + diff --git a/xmldoc/filters/options/interpolate-distance.xml b/xmldoc/filters/options/interpolate-distance.xml new file mode 100644 index 000000000..4cef24f6b --- /dev/null +++ b/xmldoc/filters/options/interpolate-distance.xml @@ -0,0 +1,13 @@ + +This option specifies the maximum allowable distance between points in the +track. If two points in the track are further apart than this value, new +points will be inserted between them. + + +This value may be specified in units of miles (3M) or kilometers (5K). If +no units are specified, the units are assumed to be miles. + + +Either this option or the must be specified. + + diff --git a/xmldoc/filters/options/interpolate-route.xml b/xmldoc/filters/options/interpolate-route.xml new file mode 100644 index 000000000..1605b9f6c --- /dev/null +++ b/xmldoc/filters/options/interpolate-route.xml @@ -0,0 +1,5 @@ + +If this option is specified, the interpolate filter interpolates routes +rather than tracks. Because route points do not have time stamps, it is an +error to use this option with the option. + diff --git a/xmldoc/filters/options/interpolate-time.xml b/xmldoc/filters/options/interpolate-time.xml new file mode 100644 index 000000000..4bdfe5669 --- /dev/null +++ b/xmldoc/filters/options/interpolate-time.xml @@ -0,0 +1,12 @@ + +This option specifies the maximum allowable time interval between points in the +track. If two points in the track are further apart than this value, new +points will be inserted between them. + + +This value is always specified in units of seconds. + + +Either this option or the must be specified. + + diff --git a/xmldoc/filters/options/nuketypes-routes.xml b/xmldoc/filters/options/nuketypes-routes.xml new file mode 100644 index 000000000..9c70b59ba --- /dev/null +++ b/xmldoc/filters/options/nuketypes-routes.xml @@ -0,0 +1,4 @@ + +This option causes the nuketypes filter to discard all route data. + + diff --git a/xmldoc/filters/options/nuketypes-tracks.xml b/xmldoc/filters/options/nuketypes-tracks.xml new file mode 100644 index 000000000..536c9d6cc --- /dev/null +++ b/xmldoc/filters/options/nuketypes-tracks.xml @@ -0,0 +1,4 @@ + +This option causes the nuketypes filter to discard all track data. + + diff --git a/xmldoc/filters/options/nuketypes-waypoints.xml b/xmldoc/filters/options/nuketypes-waypoints.xml new file mode 100644 index 000000000..26c71901e --- /dev/null +++ b/xmldoc/filters/options/nuketypes-waypoints.xml @@ -0,0 +1,5 @@ + +This option causes the nuketypes filter to discard all waypoints that are not +associated with a track or route. + + diff --git a/xmldoc/filters/options/polygon-exclude.xml b/xmldoc/filters/options/polygon-exclude.xml new file mode 100644 index 000000000..6a68bdfa2 --- /dev/null +++ b/xmldoc/filters/options/polygon-exclude.xml @@ -0,0 +1,6 @@ + +When this option is specified, the usual sense of the polygon filter is +reversed. That is, points that are inside the polygon are discarded +while points that are further away are kept. + + diff --git a/xmldoc/filters/options/polygon-file.xml b/xmldoc/filters/options/polygon-file.xml new file mode 100644 index 000000000..032b595c1 --- /dev/null +++ b/xmldoc/filters/options/polygon-file.xml @@ -0,0 +1,16 @@ + +This option is required. + + +This option specifies the name of the file containing the polygon to use for +filtering. The format of the file is as described above. + + +GPSBabel supports converting any route or track to a file usable by this +filter; simply read it in the normal way and write it using the +arc file format. Afterward, you will +need to make sure that the first point and the last point in the +file are the same, as the polygon filter depends on that. You can do so +with any text editor. + + diff --git a/xmldoc/filters/options/position-all.xml b/xmldoc/filters/options/position-all.xml new file mode 100644 index 000000000..16e59e5a8 --- /dev/null +++ b/xmldoc/filters/options/position-all.xml @@ -0,0 +1,8 @@ + +This option causes the position filter to remove all points that are within +the specified distance of one another, rather than leaving just one of them. + + +This option may be used to entirely remove clusters of points. + + diff --git a/xmldoc/filters/options/position-distance.xml b/xmldoc/filters/options/position-distance.xml new file mode 100644 index 000000000..ebd18d5d9 --- /dev/null +++ b/xmldoc/filters/options/position-distance.xml @@ -0,0 +1,9 @@ + +This option specifies the minimum allowable distance between two points. If +two points are closer than this distance, only one of them is kept. + + +Distances may be expressed in feet (30f) or meters (10m). If no unit is +specified, the distance is assumed to be in feet. + + diff --git a/xmldoc/filters/options/radius-asroute.xml b/xmldoc/filters/options/radius-asroute.xml new file mode 100644 index 000000000..4cd6539f9 --- /dev/null +++ b/xmldoc/filters/options/radius-asroute.xml @@ -0,0 +1,13 @@ + +This option specifies the name of a route. If this option is specified, the +radius filter puts all points that are kept into a route with the given name. +The order of points in the route is by distance from the center (unless the + option is also specified.) + + +Note that this route is not necessarily the most efficient route to visit +all of the points. In fact, for some data sets, it might be the least +efficient route. + + + diff --git a/xmldoc/filters/options/radius-distance.xml b/xmldoc/filters/options/radius-distance.xml new file mode 100644 index 000000000..7e4ff8212 --- /dev/null +++ b/xmldoc/filters/options/radius-distance.xml @@ -0,0 +1,13 @@ + +This option is required. + + +This option specifies the maximum distance a point may be from the central +point in order to remain in the dataset. Points closer than this distance +will be kept and points further away will be removed (unless the + option is specified.) + + +Distances may be expressed in miles (3M) or kilometers (4K). If no units +are provided, the distance is assumed to be in miles. + diff --git a/xmldoc/filters/options/radius-exclude.xml b/xmldoc/filters/options/radius-exclude.xml new file mode 100644 index 000000000..434a35b80 --- /dev/null +++ b/xmldoc/filters/options/radius-exclude.xml @@ -0,0 +1,5 @@ + +If this option is included, the action of the radius filter will be reversed: +points within the given distance will be removed, and points further away +will be kept. + diff --git a/xmldoc/filters/options/radius-lat.xml b/xmldoc/filters/options/radius-lat.xml new file mode 100644 index 000000000..bfe5c23e9 --- /dev/null +++ b/xmldoc/filters/options/radius-lat.xml @@ -0,0 +1,8 @@ + +This option is required. + + +This option specifies the latitude of the central point in decimal degrees. +South latitudes should be expressed as a negative number. Valid values for +this option are from -90 to 90. + diff --git a/xmldoc/filters/options/radius-lon.xml b/xmldoc/filters/options/radius-lon.xml new file mode 100644 index 000000000..cca861e5a --- /dev/null +++ b/xmldoc/filters/options/radius-lon.xml @@ -0,0 +1,8 @@ + +This option is required. + + +This option specifies the longitude of the central point in decimal degrees. +West longitudes should be expressed as a negative number. Valid values for +this option are from -180 to 180. + diff --git a/xmldoc/filters/options/radius-maxcount.xml b/xmldoc/filters/options/radius-maxcount.xml new file mode 100644 index 000000000..2ca05844d --- /dev/null +++ b/xmldoc/filters/options/radius-maxcount.xml @@ -0,0 +1,22 @@ + +This option specifies the maximum number of points that the radius filter may +keep. If there are more than this number of points within the specified +distance of the center, the more distant points will be discarded even though +they are within the specified distance. If this option is not specified, +all points are kept regardless of how many there are. + + +Note that if the option is also specified, this +option will instead keep points based on their position within the input +file rather than on their distance from the center. This may or may not be +what you want. + + +Note, too, that this option may be used with the +option, but the results might not be what you expect. In particular, the +results will not be the same as if you had kept all of the points you'd +otherwise throw away. You will still get no more than +maxcount points, but they will all be at least +distance away from the center. (And possibly sorted.) + + diff --git a/xmldoc/filters/options/radius-nosort.xml b/xmldoc/filters/options/radius-nosort.xml new file mode 100644 index 000000000..42ba6d5e5 --- /dev/null +++ b/xmldoc/filters/options/radius-nosort.xml @@ -0,0 +1,6 @@ + +If this option is specified, the radius filter will not sort the remaining +points by distance from the center. They will remain in whatever order they +were originally. + + diff --git a/xmldoc/filters/options/simplify-count.xml b/xmldoc/filters/options/simplify-count.xml new file mode 100644 index 000000000..9b268a3c9 --- /dev/null +++ b/xmldoc/filters/options/simplify-count.xml @@ -0,0 +1,8 @@ + +This option specifies the maximum number of points which may appear in the +simplified route. For example, if you specify "count=50", all resulting +routes will contain 50 points or fewer. + + +You must specify either this option or the option. + diff --git a/xmldoc/filters/options/simplify-crosstrack.xml b/xmldoc/filters/options/simplify-crosstrack.xml new file mode 100644 index 000000000..3b3c2831e --- /dev/null +++ b/xmldoc/filters/options/simplify-crosstrack.xml @@ -0,0 +1,11 @@ + +This option instructs GPSBabel to remove points that have the smallest +overall effect on the overall shape of the route. Using this method, the +first point to be removed will be the one that is closest to a line drawn +between the two points adjacent to it. + + +If neither this option nor the option is specified, +this is the default. + + diff --git a/xmldoc/filters/options/simplify-error.xml b/xmldoc/filters/options/simplify-error.xml new file mode 100644 index 000000000..dec87de10 --- /dev/null +++ b/xmldoc/filters/options/simplify-error.xml @@ -0,0 +1,13 @@ + +This option specifies the maximum allowable error that may be introduced +by removing a single point. The value of this option is a distance, +specified in miles by default. You may also specify the distance in +kilometers by adding a 'k' to the end of the number. + + +How the error is determined depends on whether the +or method is used. If you are using the length +method, the error is the change in the length of the route introduced by +removing a point. If you are using the crosstrack method, the error is the +distance from the point to the line that results if that point is removed. + diff --git a/xmldoc/filters/options/simplify-length.xml b/xmldoc/filters/options/simplify-length.xml new file mode 100644 index 000000000..0842f2f1f --- /dev/null +++ b/xmldoc/filters/options/simplify-length.xml @@ -0,0 +1,4 @@ + +This option instructs GPSBabel to simplify by removing points that cause the +smallest change in the overall length of the route first. + diff --git a/xmldoc/filters/options/sort-description.xml b/xmldoc/filters/options/sort-description.xml new file mode 100644 index 000000000..c629fce01 --- /dev/null +++ b/xmldoc/filters/options/sort-description.xml @@ -0,0 +1,8 @@ + +This option causes the waypoints to be sorted in alphabetical order by +description. + + +This option is not valid in combination with any other option. + + diff --git a/xmldoc/filters/options/sort-gcid.xml b/xmldoc/filters/options/sort-gcid.xml new file mode 100644 index 000000000..c2431b778 --- /dev/null +++ b/xmldoc/filters/options/sort-gcid.xml @@ -0,0 +1,8 @@ + +If the data contains Groundspeak geocache IDs, this option causes the +waypoints to be sorted in alphabetical order by geocache ID. + + +This option is not valid in combination with any other option. + + diff --git a/xmldoc/filters/options/sort-shortname.xml b/xmldoc/filters/options/sort-shortname.xml new file mode 100644 index 000000000..cd4075ccb --- /dev/null +++ b/xmldoc/filters/options/sort-shortname.xml @@ -0,0 +1,8 @@ + +This option causes the waypoints to be sorted in alphabetical order by +short name. + + +This option is not valid in combination with any other option. + + diff --git a/xmldoc/filters/options/sort-time.xml b/xmldoc/filters/options/sort-time.xml new file mode 100644 index 000000000..c43f60902 --- /dev/null +++ b/xmldoc/filters/options/sort-time.xml @@ -0,0 +1,8 @@ + +This option causes the waypoints to be sorted in chronological order by +creation time. + + +This option is not valid in combination with any other option. + + diff --git a/xmldoc/filters/options/stack-append.xml b/xmldoc/filters/options/stack-append.xml new file mode 100644 index 000000000..eb4299e05 --- /dev/null +++ b/xmldoc/filters/options/stack-append.xml @@ -0,0 +1,5 @@ + +This option is only valid in conjunction with the . +When it is specified, the topmost collection of data from the stack is +appended to the current collection of data. + diff --git a/xmldoc/filters/options/stack-copy.xml b/xmldoc/filters/options/stack-copy.xml new file mode 100644 index 000000000..ae9fe8449 --- /dev/null +++ b/xmldoc/filters/options/stack-copy.xml @@ -0,0 +1,6 @@ + +This option is only valid when used with the option. +When this option is specified, a copy of the current state is pushed onto +the stack but the current state is left unchanged. Otherwise, the push +operation clears the current data collection. + diff --git a/xmldoc/filters/options/stack-depth.xml b/xmldoc/filters/options/stack-depth.xml new file mode 100644 index 000000000..2103d5d59 --- /dev/null +++ b/xmldoc/filters/options/stack-depth.xml @@ -0,0 +1,6 @@ + +This option is only valid when used along with the +option. If specified, it indicates which item on the stack should be +swapped with the current state. The default value is 1, which corresponds +to the top of the stack. + diff --git a/xmldoc/filters/options/stack-discard.xml b/xmldoc/filters/options/stack-discard.xml new file mode 100644 index 000000000..a4765b69d --- /dev/null +++ b/xmldoc/filters/options/stack-discard.xml @@ -0,0 +1,5 @@ + +This option is only valid when used with the option. +When this option is specified, the popped state is discarded and the current +state remains unchanged. + diff --git a/xmldoc/filters/options/stack-pop.xml b/xmldoc/filters/options/stack-pop.xml new file mode 100644 index 000000000..0bfb71660 --- /dev/null +++ b/xmldoc/filters/options/stack-pop.xml @@ -0,0 +1,9 @@ + +This is one of three "primary" options to the stack filter. + + +This option "pops" the collection of data from the top of the stack. +By default, the saved state replaces the current state, but see the + and options for +alternatives. + diff --git a/xmldoc/filters/options/stack-push.xml b/xmldoc/filters/options/stack-push.xml new file mode 100644 index 000000000..8f76ad567 --- /dev/null +++ b/xmldoc/filters/options/stack-push.xml @@ -0,0 +1,8 @@ + +This is one of three "primary" options to the stack filter. + + +When this option is specified, the current state is pushed onto the top of +the stack. By default, the current state is then cleared, but the + option can be used to cause it to be saved. + diff --git a/xmldoc/filters/options/stack-replace.xml b/xmldoc/filters/options/stack-replace.xml new file mode 100644 index 000000000..2e967fdba --- /dev/null +++ b/xmldoc/filters/options/stack-replace.xml @@ -0,0 +1,8 @@ + +This option is only valid when used with the option. +This is the default behavior of the option, so you +should never need to specify it, but it is included for the sake of +readability. When this option is specified, the popped state replaces +the current state. + + diff --git a/xmldoc/filters/options/stack-swap.xml b/xmldoc/filters/options/stack-swap.xml new file mode 100644 index 000000000..b96874456 --- /dev/null +++ b/xmldoc/filters/options/stack-swap.xml @@ -0,0 +1,10 @@ + +This is one of three "primary" options to the stack filter. + + +When this option is specified, the current state is swapped with a saved +state from the stack. By default, it is swapped with the top of the stack, +but the can be used to specify a different saved +state. + + diff --git a/xmldoc/filters/options/track-course.xml b/xmldoc/filters/options/track-course.xml new file mode 100644 index 000000000..36b83f29a --- /dev/null +++ b/xmldoc/filters/options/track-course.xml @@ -0,0 +1,10 @@ + +This option computes (or recomputes) a value for the GPS heading at each +trackpoint. This is most useful with trackpoints from formats that don't +support heading information or for trackpoints synthesized by the +interpolate +filter. The heading at each trackpoint is simply the course from the +previous trackpoint in the track. The first trackpoint in each track +is arbitrarily assigned a heading of 0 degrees. + + diff --git a/xmldoc/filters/options/track-fix.xml b/xmldoc/filters/options/track-fix.xml new file mode 100644 index 000000000..4cd9f303a --- /dev/null +++ b/xmldoc/filters/options/track-fix.xml @@ -0,0 +1,9 @@ + +This option sets the GPS fix status for all trackpoints to the specified +value. Valid values for this option are PPS, DGPS, 3D, 2D, or NONE. + + +This option is most useful when converting from a format that doesn't +contain GPS fix status to one that requires it. + + diff --git a/xmldoc/filters/options/track-merge.xml b/xmldoc/filters/options/track-merge.xml new file mode 100644 index 000000000..91b4cb3b9 --- /dev/null +++ b/xmldoc/filters/options/track-merge.xml @@ -0,0 +1,14 @@ + +This option puts all track points from all tracks into a single track +and sorts them by time stamp. Points with identical time stamps will be +dropped. + + +Merging tracks with the track filter + +Suppose you want to merge tracks recorded with two different GPS devices +at the same time. To do that, use this command line: + +gpsbabel -t -i gpx -f john.gpx -i gpx -f doe.gpx -x track,merge,title="COMBINED LOG" -o gpx -F john_doe.gpx + + diff --git a/xmldoc/filters/options/track-move.xml b/xmldoc/filters/options/track-move.xml new file mode 100644 index 000000000..22452828a --- /dev/null +++ b/xmldoc/filters/options/track-move.xml @@ -0,0 +1,13 @@ + +This option changes the time of all trackpoints. This might be useful if +your track must be moved by one or more hours because of an incorrect +time zone. + + +Time-shifting a track with the track filter + +The following command line will shift all tracks to be one hour later. + +gpsbabel -t -i gpx -f in.gpx -x track,move=+1h -o gpx -F out.gpx + + diff --git a/xmldoc/filters/options/track-name.xml b/xmldoc/filters/options/track-name.xml new file mode 100644 index 000000000..930b88bf7 --- /dev/null +++ b/xmldoc/filters/options/track-name.xml @@ -0,0 +1,7 @@ + +With the name option you can filter out a track by title. + + +The comparison is always non-case-sensitive. Wildcards are allowed. + + diff --git a/xmldoc/filters/options/track-pack.xml b/xmldoc/filters/options/track-pack.xml new file mode 100644 index 000000000..c65f6893f --- /dev/null +++ b/xmldoc/filters/options/track-pack.xml @@ -0,0 +1,12 @@ + +This option causes all tracks to be appended to one another to form a single +track. This option does not work if any two tracks overlap in time; in that +case, consider using the option. + + +This option is most useful for rejoining tracks that might have +been interrupted by an equipment malfunction or an overnight stop. + + +If no other option is given to the track filter, this option is assumed. + diff --git a/xmldoc/filters/options/track-sdistance.xml b/xmldoc/filters/options/track-sdistance.xml new file mode 100644 index 000000000..65a40ae68 --- /dev/null +++ b/xmldoc/filters/options/track-sdistance.xml @@ -0,0 +1,36 @@ + The input track will be split into several tracks + if the distance between successive track points + is greater than the distance given as a parameter. + The distance must be numeric and can be in miles or kilometers, + expressed as one of the character "k", or "m". + If sdistance is given no parameters, this option has the same + effect as the split option without parameters. If there is more + than one track, + use the pack option before before using this. + + For example, to split the track if the distance between + points is greater than 100 meters, use this: + +gpsbabel -t + -i gpx -f in.gpx + -x track,pack,sdistance=0.1k" + -o gpx -F out.gpx + + The sdistance option can be combined with the split option. + The track then will be split only if both time and distance + interval exceeds the supplied values. This technique can be used to + filter out gaps from + the tracklog. The gap is kept only if the gps device is without + signal for longer time than that given and during that time it moves + a distance over that given. + This example splits the track + if the device is without signal for at least 5 minutes + and during this time moves more than 300 meters: + +gpsbabel -t + -i gpx -f in.gpx + -x track,pack,sdistance=0.3k,split=5m + -o gpx -F out.gpx + + + diff --git a/xmldoc/filters/options/track-speed.xml b/xmldoc/filters/options/track-speed.xml new file mode 100644 index 000000000..32d640bdf --- /dev/null +++ b/xmldoc/filters/options/track-speed.xml @@ -0,0 +1,9 @@ + +This option computes a value for the GPS speed at each trackpoint. +This is most useful with trackpoints from formats that don't support +speed information or for trackoints synthesized by the +interpolate +filter. The speed at each trackpoint is the average speed from the +previous trackpoint (distance divided by time). The first trackpoint +in each track is assigned a speed of "unknown." + diff --git a/xmldoc/filters/options/track-split.xml b/xmldoc/filters/options/track-split.xml new file mode 100644 index 000000000..b8df748f1 --- /dev/null +++ b/xmldoc/filters/options/track-split.xml @@ -0,0 +1,28 @@ + The input track will be split into several tracks + depending on date of track points. If there is more than one + track, use the pack option before before using this. To + split a single tracks into separate tracks for each day and + name them, use this: + + gpsbabel -t -i gpx -f in.gpx -x track,split,title="ACTIVE LOG # %Y%m%d" -o gpx -F out.gpx + If the input has multiple tracks, pack them together before +splitting them back apart per day thusly: + gpsbabel -t -i gpx -f in.gpx + -x track,pack,split,title="ACTIVE LOG # %D" + -o gpx -F out.gpx + Additionally you can add an interval to the split + option. With this the track will be split if the time + between two points is greater than this parameter. The + interval must be numeric and can be int days, hours, minutes + or seconds, expressed as one of the character "d", "h", "m", + or "s". If no trailing character is present, the units are + assumed to be in seconds. + + For example, to split a track based on an four hour + interval, use this: + +gpsbabel -t + -i gpx -f in.gpx + -x track,pack,split=4h,title="LOG # %c" + -o gpx -F out.gpx + diff --git a/xmldoc/filters/options/track-start.xml b/xmldoc/filters/options/track-start.xml new file mode 100644 index 000000000..143e05d22 --- /dev/null +++ b/xmldoc/filters/options/track-start.xml @@ -0,0 +1,24 @@ + +This option is used along with the to discard +trackpoints that were recorded outside of a specific period of time. +This option specifies the beginning of the time period. + + +If this option is not specified, the time period is assumed to begin at the +dawn of time or January 1, 1970, whichever was later. The time for this +option is expressed in UTC. + + +The value of this option must be in the form of YYYYMMDDHHMMSS, but it is +not necessary to specify the smaller time units if they are not needed. +That is, if you only care about points logged between 10 AM and 6 PM on a +given date, you need not specify the minutes or seconds. + + +Extracting a period of time with the track filter + +To get only the parts of a track that were mapped on 20 July 2005 +between 10 AM and 6 PM, use this command line: + +gpsbabel -t -i gpx -f in.gpx -x track,start=2005072010,stop=2005072018 -o gpx -F out.gpx + diff --git a/xmldoc/filters/options/track-stop.xml b/xmldoc/filters/options/track-stop.xml new file mode 100644 index 000000000..a86755aeb --- /dev/null +++ b/xmldoc/filters/options/track-stop.xml @@ -0,0 +1,15 @@ + +This option is used in conjunction with the option to +discard all trackpoints outside of a given period of time. This option +defines the end of the time period. + + +If this option is not specified, the time period is assumed to end at the +end of civilization as we know it or the year 2038, whichever comes first. +The time for this option is expressed in UTC. + + +See the option for the format of this value and an +example of usage. + + diff --git a/xmldoc/filters/options/track-title.xml b/xmldoc/filters/options/track-title.xml new file mode 100644 index 000000000..be578bd46 --- /dev/null +++ b/xmldoc/filters/options/track-title.xml @@ -0,0 +1,10 @@ + +This option specifies a title for tracks generated by the track filter. +By default, the title of the new track is composed of the start time of +the track appended to this value. + + +If this value contains a percent (%) character, it is treated as a format +string for the POSIX strftime function, allowing custom time-based +track names. + diff --git a/xmldoc/filters/options/transform-del.xml b/xmldoc/filters/options/transform-del.xml new file mode 100644 index 000000000..46b78d6bb --- /dev/null +++ b/xmldoc/filters/options/transform-del.xml @@ -0,0 +1,9 @@ + +This option, when used in connction with the wpt, rte, or trk options, tells +GPSBabel to delete the source data after conversion. This is most useful if +you are trying to avoid duplicated data in the output. + + +Convert a GPX track to GPX waypoints, tossing the original track +gpsbabel -i gpx -f blah.gpx -x transform,wpt=trk,del -o gpx -F converted.gpx + diff --git a/xmldoc/filters/options/transform-rte.xml b/xmldoc/filters/options/transform-rte.xml new file mode 100644 index 000000000..4382e0f5b --- /dev/null +++ b/xmldoc/filters/options/transform-rte.xml @@ -0,0 +1,11 @@ + +This option selects the destination type of this filter to be routes. Choose this when you want to convert tracks into waypoints routes. A single route will be created in the sequence they appear in the input. + + +Converting a pile of waypoints to a GPX route + +Say you you have a data file that came from CSV file that you want to convert +to a GPX route that can be loaded into Mapsource. Use the following command: + +gpsbabel -i csv -f blah.txt -x transform,rte=wpt -o gdb -F blah.gdb + diff --git a/xmldoc/filters/options/transform-trk.xml b/xmldoc/filters/options/transform-trk.xml new file mode 100644 index 000000000..d17d98b9f --- /dev/null +++ b/xmldoc/filters/options/transform-trk.xml @@ -0,0 +1,13 @@ + +This option selects the destination type of this filter to be tracks. +Choose this when you want to create tracks from a list of waypoints or routes. +A single track will be created in the sequence they appear in the input. + + +Converting a pile of waypoints to a GPX track + +Say you you have a data file that came from CSV file that you want to convert +to a GPX track that can be loaded into Mapsource. Use the following command: + +gpsbabel -i csv -f blah.txt -x transform,trk=wpt -o gdb -F blah.gdb + diff --git a/xmldoc/filters/options/transform-wpt.xml b/xmldoc/filters/options/transform-wpt.xml new file mode 100644 index 000000000..513b5ef07 --- /dev/null +++ b/xmldoc/filters/options/transform-wpt.xml @@ -0,0 +1,11 @@ + +This option selects the destination type of this filter to be waypoints. +Choose this when you want to convert tracks or routes into waypoints. + + +Converting a track to a sequence of waypoints + +Say you you have a KML file that contains a track but you want to convert it to a CSV file that can contain only waypoints, perhaps to import into a spreadsheet. Use the following command: + +gpsbabel -i kml -f blah.kml -x transform,wpt=trk -o csv -F blah.txt + diff --git a/xmldoc/filters/polygon.xml b/xmldoc/filters/polygon.xml new file mode 100644 index 000000000..ddf2699f6 --- /dev/null +++ b/xmldoc/filters/polygon.xml @@ -0,0 +1,78 @@ + +The polygon filter includes points if they are inside +of a polygon. A polygon file looks like an +arc file, except +that the arc it describes must be a closed cycle. That is, +for a simple polygon, the first and last points must be the +same. Here's a square: + + +# A square (not really) polygon +41.0000 -85.0000 +41.0000 -86.0000 +42.0000 -86.0000 +42.0000 -85.0000 +41.0000 -85.0000 + + +Polygons may include islands and holes. To include an +island or a hole, just append it to the main polygon. + + +# A square polygon with a triangular hole +41.0000 -85.0000 +41.0000 -86.0000 +42.0000 -86.0000 +42.0000 -85.0000 +41.0000 -85.0000 +# The hole begins here +41.5000 -85.5000 +41.6000 -85.5000 +41.6000 -85.6000 +41.5000 -85.5000 + + +As with the arc filter, you define a polygon by +giving the name of the file that contains it, using +the option. + + +Note that this filter currently will not work properly +if your polygon contains one or both poles or if it spans the +line of 180 degrees east or west longitude. + + +Using the polygon filter + +Suppose you have a polygon file that defines the border of your county, +called mycounty.txt. This command line will give you only the points +in your county: + +gpsbabel -i geo -f 1.loc -x polygon,file=mycounty.txt -o mapsend -F 2.wpt + + +Using the polygon and arc filters to find points in or nearly in a +polygon + +Because the polygon and arc filters use +the same file format, you can use them together to find all points that are +"in or nearly in" a polygon. This can be useful if your waypoints or the +boundaries of your polygon are not quite perfect, so you want to provide a +buffer zone around it in case there are points nearby that should be in the +polygon but aren't quite. + + +gpsbabel -i gpx -f points.gpx -x stack,push -x polygon,file=mycounty.txt +-x stack,swap -x arc,file=mycounty.txt,distance=1k -x stack,pop,append +-x duplicate,shortname -o gpx -F nearmycounty.gpx + + +This command makes a copy of the points, finds the ones that are in your +your county, swaps that result with the copy of the original set of points, +finds the ones from that set that are within 1 km of the border of the county, +puts the two lists together, and then filters out any points that appear twice +(This step is necessary because points inside the county but near the county +line will be kept by both the polygon and the arc filter.) + + + diff --git a/xmldoc/filters/position.xml b/xmldoc/filters/position.xml new file mode 100644 index 000000000..01df222c7 --- /dev/null +++ b/xmldoc/filters/position.xml @@ -0,0 +1,15 @@ + +This filter removes points based on their proximity to each other. A +point is removed if it is within the specified distance of a point that +has come before. + + + +Using the position filter to suppress close points + +The following command removes multiple points that are within +one foot of each other, leaving just one. + +gpsbabel -i geo -f 1.loc -f 2.loc -x position,distance=1f -o mapsend -F 3.wpt + + diff --git a/xmldoc/filters/radius.xml b/xmldoc/filters/radius.xml new file mode 100644 index 000000000..1e3f4ffd7 --- /dev/null +++ b/xmldoc/filters/radius.xml @@ -0,0 +1,17 @@ + +This filter includes or excludes waypoints based on their proximity to a +central point. All waypoints more than the specified distance from the +specified point will be removed from the dataset. + + +By default, all remaining points are sorted so that points closer to the +center appear earlier in the output file. + + + Using the radius filter to find points close to a given point + This example command line would include only points within 1 1/2 miles + of N30.000 W 90.000 + +gpsbabel -i geo -f 1.loc -x radius,distance=1.5M,lat=30.0,lon=-90.0 -o mapsend -F 2.wpt + + diff --git a/xmldoc/filters/reverse.xml b/xmldoc/filters/reverse.xml new file mode 100644 index 000000000..31cfe9062 --- /dev/null +++ b/xmldoc/filters/reverse.xml @@ -0,0 +1,19 @@ + + + The reverse filter is used to reverse tracks and routes. + It's mostly useful for those few formats where track/route + sequence matters and there isn't a way to reverse them using + the program itself. + The reversal is performed in the laziest way possible. + Timestamps are kept with the original waypoints so the + resulting track or route will have the interesting + characteristic that time runs backwards. This tends to make + Magellan Mapsend, in particular, do a wierd thing and place + each waypoint on a separate day. + + Additionally, if you're using this to reverse a route + that navigates, say, an exit ramp or a one way street, you + will be in for unpleasant ride. application cares about + timestamps + + diff --git a/xmldoc/filters/simplify.xml b/xmldoc/filters/simplify.xml new file mode 100644 index 000000000..026551bc0 --- /dev/null +++ b/xmldoc/filters/simplify.xml @@ -0,0 +1,21 @@ + +The Simplify filter is used to simplify routes and tracks for use with +formats that limit the number of points they can contain or just to +reduce the complexity of a route. + + +The filter attempts to remove points from each route until the number +of points or the error is within the given bounds, while also attempting +to preserve the shape of the original route as much as possible. + + +The quality of the results will vary depending on the density of points +in the original route and the length of the original route. + + +For example, suppose you have a route from Street Atlas 2003 that you +wish to use with a Magellan GPS receiver that only supports up to 50 points +in a route: + +gpsbabel -r -i saroute -f RoadTrip.anr -x simplify,count=50 -o magellan -F grocery.rte + diff --git a/xmldoc/filters/sort.xml b/xmldoc/filters/sort.xml new file mode 100644 index 000000000..da4ad375e --- /dev/null +++ b/xmldoc/filters/sort.xml @@ -0,0 +1,5 @@ + +This filter sorts waypoints into alphabetical order by the selected field. +You must specify exactly one of the options. + + diff --git a/xmldoc/filters/stack.xml b/xmldoc/filters/stack.xml new file mode 100644 index 000000000..833012355 --- /dev/null +++ b/xmldoc/filters/stack.xml @@ -0,0 +1,49 @@ + +This filter is designed to solve advanced problems that involve shuffling +multiple lists of waypoints, tracks, or routes. + + +The stack filter can be used to save the current state of the entire +collection of data. That state is placed on top of a stack of collections, +so you can simultaneously have as many stored collections of data as you +can fit in your computer's memory. + + + The stack filter can be used in conjunction with other + filters to implement a "union" or "logical or" functionality. + The basic idea is to use the stack to store copies of the + original list of waypoints, then use the 'swap' function to + replace each copy with a filtered list. Finally, append all + of the filtered lists to create one big list, which is then + output. The following example finds a list of all points + that are either inside county A or inside county B. Any + points that are inside both counties are duplicated (but the + duplicates can be removed with the DUPLICATE filter; see + above.) + + +gpsbabel -i gpx -f in.gpx + -x stack,push,copy + -x polygon,file=county_a.txt + -x stack,swap + -x polygon,file=county_b.txt + -x stack,pop,append + -o gpx -F out.gpx + + This example reads a large list of waypoints and + extracts the points within 20 miles of each of two cities, + writing the waypoint descriptions into two different PalmDoc + files and exporting all of the points to the GPS receiver: + + +gpsbabel -i gpx -f indiana.gpx + -x stack,push,copy + -x radius,lat=41.0765,lon=-85.1365,distance=20m + -o palmdoc,dbname=Fort\ Wayne -F fortwayne.pdb + -x stack,swap + -x radius,lat=39.7733,lon=-86.1433,distance=20m + -o palmdoc,dbname=Indianapolis -F indianapolis.pdb + -x stack,pop,append + -o magellan -F fwaind.wpt + + diff --git a/xmldoc/filters/track.xml b/xmldoc/filters/track.xml new file mode 100644 index 000000000..cf6c39494 --- /dev/null +++ b/xmldoc/filters/track.xml @@ -0,0 +1,8 @@ + +WARNING: This filter always drops empty tracks. + + +This filter performs various operations on track data. + + + diff --git a/xmldoc/filters/transform.xml b/xmldoc/filters/transform.xml new file mode 100644 index 000000000..ddb82ca11 --- /dev/null +++ b/xmldoc/filters/transform.xml @@ -0,0 +1,18 @@ + + This filter can be used to convert GPS data between different data types. + + + Some GPS data formats support only some subset of waypoints, tracks, + and routes. The transform filter allows you to convert between these + types. For example, it can be used to convert a pile of waypoints (such + as those from a CSV file) into a track or vice versa. + + + The following example show you how to create a route from a waypoint table. + + gpsbabel -i csv waypts.txt -x transform,rte=wpt -o gpx -F route.gpx + + Only the first letter of option value decides which transformation will be done. + Depending on the used option it can be only 'W' for waypoints, 'R' for routes or + 'T' for tracks. + diff --git a/xmldoc/formats/alantrl.xml b/xmldoc/formats/alantrl.xml new file mode 100644 index 000000000..19fff93f3 --- /dev/null +++ b/xmldoc/formats/alantrl.xml @@ -0,0 +1,29 @@ + +GPSBabel supports .wpr and .trl files for Alan Map500 devices running operating +system versions 2.xx. + + + +.trl contain files tracklogs. If you use a CF-Card based +operating system, tracklog files must have a .TRL extension when +copied to the CF-Card. The default filename is TEMP_TRK.TRL. +Only one .TRL file may be present. + + + +Alan's operating system 3.0 for Map500 is not supported yet. +At the time of this writing, OS3 is still beta. +Documentation on the new dataformats is sparse. + + + +The Alan Map500 handheld GPSr is identical to the Holux GM101. +This GPSBabel module has only been tested against the Alan Map500. +Still, if you use a GM101, GPSBabel will probably be able to convert +your waypoints, routes and tracklogs. + + + +For more information on the Alan Map500 visit +Alan Germany. There is very informative forum, too. The forum language is German but posts in English will be answered, too. + diff --git a/xmldoc/formats/alanwpr.xml b/xmldoc/formats/alanwpr.xml new file mode 100644 index 000000000..645925b8e --- /dev/null +++ b/xmldoc/formats/alanwpr.xml @@ -0,0 +1,30 @@ + +GPSBabel supports .wpr and .trl files for Alan Map500 devices running operating +system versions 2.xx. + + + +.wpr files contain waypoints and routes. If you use a CF-Card based +operating system, waypoint files must have a .WPR extension when +copied to the CF-Card. The default filename is TEMPWPRT.WPR. +Only one .WPR file may be present. + + + +Alan's operating system 3.0 for Map500 is not supported yet. +At the time of this writing, OS3 is still beta. +Documentation on the new dataformats is sparse. + + + +The Alan Map500 handheld GPSr is identical to the Holux GM101. +This GPSBabel module has only been tested against the Alan Map500. +Still, if you use a GM101, GPSBabel will probably be able to convert +your waypoints, routes and tracklogs. + + + +For more information on the Alan Map500 visit +Alan Germany. There is very informative forum, too. Forum language is German but posts in English will be answered, +too. + diff --git a/xmldoc/formats/an1.xml b/xmldoc/formats/an1.xml new file mode 100644 index 000000000..96ee14435 --- /dev/null +++ b/xmldoc/formats/an1.xml @@ -0,0 +1,15 @@ + +This format supports the DeLorme ".an1" drawing file format. It can +currently be used to either read or write drawing files. If you use +this format to create drawing files with routes or waypoints from another +source, by default it will create "Red Flag" symbols for waypoints, and +thick red lines for routes or tracks. It is possible to merge two drawing +layers by doing something like this: + + +gpsbabel -i an1 -f one.an1 -f two.an1 -o an1 -F merged.an1 + + +In this case, the merged data will contain all of the +properties of the original data. + diff --git a/xmldoc/formats/arc.xml b/xmldoc/formats/arc.xml new file mode 100644 index 000000000..4365cce28 --- /dev/null +++ b/xmldoc/formats/arc.xml @@ -0,0 +1,14 @@ + +This format is used by GPSBabel itself as the input to the +arc and +polygon filters. See those filters +for more information. + + +The arc format reads two numeric fields, a latitude and a longitude, +in any format recognized as human +readable and writes as simple degrees decimal. It really is +intended for GPSBabel's own internal use more than general use, though +it turns out to be a convenient way of expressing simple polylines and +polygons. + diff --git a/xmldoc/formats/axim_gpb.xml b/xmldoc/formats/axim_gpb.xml new file mode 100644 index 000000000..002a0aae7 --- /dev/null +++ b/xmldoc/formats/axim_gpb.xml @@ -0,0 +1,10 @@ + + This format reads the binary (.gpb) track logs recorded on + Dell Axim Navigation Systems. + + + + This is a read-only format for now as the format was reverse + engineered and there are many unknown bytes. We can successfully + extract the common GPS data. + diff --git a/xmldoc/formats/baroiq.xml b/xmldoc/formats/baroiq.xml new file mode 100644 index 000000000..cd3d8fd11 --- /dev/null +++ b/xmldoc/formats/baroiq.xml @@ -0,0 +1,5 @@ +Serial download protocol for the Brauniger IQ series of +barograph recording flight instruments. This format creates a +track of altitude vs time which can be merged with a GPS track +of the same flight to create a three dimensional IGC file. + diff --git a/xmldoc/formats/bcr.xml b/xmldoc/formats/bcr.xml new file mode 100644 index 000000000..76915df69 --- /dev/null +++ b/xmldoc/formats/bcr.xml @@ -0,0 +1,21 @@ + +This file format (extension .bcr) is used in Map&Guide +Motorrad Routenplaner 2002 and later versions. +BCR is a route-only format. If you own a newer release (2005 or later) you +may also use the XML export with GPSBabel's tef +input format. + + +There may be other products from Map&Guide that use this format as well. + + +Coordinates are stored in a BCR file in a Mercator projection. The +conversion from the Mercator projection to polar (latitude/longitude) +coordinates and back again may result in visible differences. Experience +reports are welcome. + + + Sample BCR command with all options + gpsbabel -r -i gpx -f in.gpx -o bcr,index=1,name="From A to B",radius=6371012 -F a_to_b.bcr + + diff --git a/xmldoc/formats/cambridge.xml b/xmldoc/formats/cambridge.xml new file mode 100644 index 000000000..5d8d79b9d --- /dev/null +++ b/xmldoc/formats/cambridge.xml @@ -0,0 +1,8 @@ + + + + Support for +Cambridge +and Winpilot + flight analysis and planning software for glider pilots. + diff --git a/xmldoc/formats/cetus.xml b/xmldoc/formats/cetus.xml new file mode 100644 index 000000000..ef9031f23 --- /dev/null +++ b/xmldoc/formats/cetus.xml @@ -0,0 +1,7 @@ + + + + Cetus GPS is a program for +Palm/OS. Working with Ron Parker and Kjeld Jensen, we can now read +and write files for that program. + diff --git a/xmldoc/formats/coastexp.xml b/xmldoc/formats/coastexp.xml new file mode 100644 index 000000000..3356a9fff --- /dev/null +++ b/xmldoc/formats/coastexp.xml @@ -0,0 +1,8 @@ + + + + This is the format used by CoastalExplorer. The +format is XML with items uniquely identified by Windows-style UUIDs. +http://www.rosepointnav.com + + diff --git a/xmldoc/formats/compegps.xml b/xmldoc/formats/compegps.xml new file mode 100644 index 000000000..177a6a57e --- /dev/null +++ b/xmldoc/formats/compegps.xml @@ -0,0 +1,14 @@ + +CompeGPS data files are "character" separated text files like +the pcx format. "Character" means special data lines can have their +own separator. + + +Since release 6.1 of CompeGPS, GPX is also a +supported import/export format for waypoints, routes and tracks. + + +For more information please have a look at +http://www.compegps.com + + diff --git a/xmldoc/formats/copilot.xml b/xmldoc/formats/copilot.xml new file mode 100644 index 000000000..6eb5272de --- /dev/null +++ b/xmldoc/formats/copilot.xml @@ -0,0 +1,17 @@ + + + + This code is mostly intended to convert CoPilot Flight +Planner for Palm/OS" databases into other formats. You probably should +not use this to write CoPilot databases, although the code is there, +because GPSBabel doesn't convert magnetic declination values. +This version now reads all CoPilot file versions up to 4, but only +writes version 4 files. If you have a need for a version flag, please let +me know. + Questions, bug reports, etc, to ptomblin at +xcski.com + + http://xcski.com/~ptomblin/CoPilot/ +and http://navaid.com/CoPilot + + diff --git a/xmldoc/formats/coto.xml b/xmldoc/formats/coto.xml new file mode 100644 index 000000000..34d9a89d5 --- /dev/null +++ b/xmldoc/formats/coto.xml @@ -0,0 +1,20 @@ + +This format supports cotoGPS, a Palm GPS program. +It can read both track and marker (waypoint) files. It is currently unable +to write track files, so only marker files can be written. The marker +categories are written to and read from the icon description. The 'Not +Assigned' category leaves the icon description empty on read. +Currently geocache info is ignored. + + In addition to the documented options, this format also has a +debugging option called which takes an XCSV +delimiter value. It writes some internal values (distance, arc, x and y) +of the cotoGPS track format to the notes field. + + +Contributed by Tobias Minich. + + +cotoGPS + + diff --git a/xmldoc/formats/cst.xml b/xmldoc/formats/cst.xml new file mode 100644 index 000000000..aa1c0868f --- /dev/null +++ b/xmldoc/formats/cst.xml @@ -0,0 +1,9 @@ + + + + With this format we can read CarteSurTable data files. + CarteSurTable is a shareware program widely used in France. The data +inside have to be seen as a mixture of a waypoints list, one route and +several tracks. + + diff --git a/xmldoc/formats/csv.xml b/xmldoc/formats/csv.xml new file mode 100644 index 000000000..feb3caf9e --- /dev/null +++ b/xmldoc/formats/csv.xml @@ -0,0 +1,27 @@ + + + There are a billion variants of Comma Separated Value +data. This is the one specifically that makes Delorme S&A Deluxe 9 happy. It's +also a very simple program and useful for many other programs like +spreadsheets. + CSV is also the correct format for + Lowrance MapCreate, +their commercial mapping program, or GDM6 (their free waypoint +manager) for iFinder which is available at lowrance.com + + + On write, this format writes simple "latitude, longitude" pairs, but +on read it will read anything supported by our human readable definition. + + + For something-separated data that has headers identifying the various + fields, see our universal csv format. + +Example 'csv' file + +35.97203, -87.13470, Mountain Bike Heaven by susy1313 +36.09068, -86.67955, The Troll by a182pilot & Family +35.99627, -86.62012, Dive Bomber by JoGPS & family +36.03848, -86.64862, FOSTER by JoGPS & Family + + diff --git a/xmldoc/formats/cup.xml b/xmldoc/formats/cup.xml new file mode 100644 index 000000000..487060288 --- /dev/null +++ b/xmldoc/formats/cup.xml @@ -0,0 +1,14 @@ + + This format supports flight analysis data from the + See You + program. + + + Position information is preserved, but the aviation-specific + information such as runway length and airport frequency, are + written as blanks and ignored on read. + + + Tasks are not supported. + + diff --git a/xmldoc/formats/custom.xml b/xmldoc/formats/custom.xml new file mode 100644 index 000000000..fdb1ef7e9 --- /dev/null +++ b/xmldoc/formats/custom.xml @@ -0,0 +1,9 @@ + +This format is not actually used by any real product. It is most useful +for debugging purposes when developing a new format module for GPSBabel. + + +To understand the contents of this file, look at the +style/custom.style file in the GPSBabel source +distribution as well as . + diff --git a/xmldoc/formats/destinator_itn.xml b/xmldoc/formats/destinator_itn.xml new file mode 100644 index 000000000..f39ff240a --- /dev/null +++ b/xmldoc/formats/destinator_itn.xml @@ -0,0 +1,18 @@ + + Support for Destinator itinerary files. + + + These have (mostly) extension .dat and are binary files. The file structure is undocumented + and so this format was reverse engineered from some .dat files. + At this time we can read and write name, comment and the coordinates of the route points. + + + Destinator by + Destinator Technologies + is a software for PNDs, Smartphones and PDAs. + + + + gpsbabel -i destinator_itn -f from_A_to_B.dat -o gpx -F from_A_to_B.gpx + + diff --git a/xmldoc/formats/destinator_poi.xml b/xmldoc/formats/destinator_poi.xml new file mode 100644 index 000000000..9cd439649 --- /dev/null +++ b/xmldoc/formats/destinator_poi.xml @@ -0,0 +1,19 @@ + + Support for Destinator binary POI files (.dat). + + + The basic information was found at mozoft.com. + GPSBabel can read and write all fields described at this document. Please note that 'house number' isn't + supported as a separate field. This field, if available in any source file, will be stored together with 'street' + into GSPBabel's internal 'address' field. + + + Destinator by + Destinator Technologies + is a software for PNDs, Smartphones and PDAs. + + + + gpsbabel -i destinator_poi -f interesting_places.dat -o gpx -F interesting_places.gpx + + diff --git a/xmldoc/formats/destinator_trl.xml b/xmldoc/formats/destinator_trl.xml new file mode 100644 index 000000000..5b33dd4b9 --- /dev/null +++ b/xmldoc/formats/destinator_trl.xml @@ -0,0 +1,18 @@ + + Support for Destinator binary tracklogs (.dat). + + + The basic information was found at mozoft.com. + In addition to the standard GPS track data of coordinates and timestamp, this format also stores the + position fix and the number of satelites seen during recording. + + + Destinator by + Destinator Technologies + is a software for PNDs, Smartphones and PDAs. + + + + gpsbabel -i destinator_trl -f last_trip.dat -o gpx -F last_trip.gpx + + diff --git a/xmldoc/formats/dg-100.xml b/xmldoc/formats/dg-100.xml new file mode 100644 index 000000000..35b95bb62 --- /dev/null +++ b/xmldoc/formats/dg-100.xml @@ -0,0 +1,19 @@ +Serial download protocol for the GlobalSat DG-100 GPS data logger. Although untested it is expected that this will also support the BT-335. +While the DG-100 has a button to record waypoints, they seem to be indistinguishable from trackpoints. Therefore, all points will be presented as trackpoints, disregarding whether they were recorded automatically or manually. + +GlobalSat DG-100 + + + Command showing DG-100 download and erase on Linux + gpsbabel -t -i dg-100,erase -o gpx /dev/ttyUSB0 outputfile.gpx + + + +The DG-100 provides a physical USB interface to the host computer, but +internally it uses a Prolific PL-2303 chip to do this. So you must have +drivers installed on your computer to recognize the PL-2303 and provide +that data as a serial port to software like GPSBabel. Such software +comes with the unit for Windows. Prolific provides software for Mac OS/X, +but unfortunately their driver has a defect which makes it unusable with +GPSBabel. + diff --git a/xmldoc/formats/dmtlog.xml b/xmldoc/formats/dmtlog.xml new file mode 100644 index 000000000..44d44bf86 --- /dev/null +++ b/xmldoc/formats/dmtlog.xml @@ -0,0 +1,10 @@ + + This format can be used to convert files from + TrackLogs Digital Mapping. The files + have extension .trl and can contain waypoints and tracks. + + + We have seen three different types of this format. Two are binary + and one is an XML based format. All three types are supported + by our reader. + diff --git a/xmldoc/formats/dna.xml b/xmldoc/formats/dna.xml new file mode 100644 index 000000000..8e12bb670 --- /dev/null +++ b/xmldoc/formats/dna.xml @@ -0,0 +1,8 @@ + + + + Navitrak DNA marker format - Another CSV format file. This +is the format that is compatible with the DNA Desktop import/export +command. Reading the binary Markers.jwp format directly off the data +card is not supported yet. Contributed by Tim Zickus. + diff --git a/xmldoc/formats/easygps.xml b/xmldoc/formats/easygps.xml new file mode 100644 index 000000000..3f940d3da --- /dev/null +++ b/xmldoc/formats/easygps.xml @@ -0,0 +1,12 @@ + + + + This is the binary file format used by EasyGPS +format is seemingly being phased out in favor of GPX in newer versions +of EasyGPS, but this allows conversions to and from the old binary +.loc format. + + Information about and sketchy code to implement this file +format were provided by Eric Cloninger. + + diff --git a/xmldoc/formats/exif.xml b/xmldoc/formats/exif.xml new file mode 100644 index 000000000..4d6958638 --- /dev/null +++ b/xmldoc/formats/exif.xml @@ -0,0 +1,12 @@ + + This format reads GPS information embedded in + EXIF , + the Exchangeable Image Format, data. EXIF is a standardized method + of encoding data in pictures such as JPEG, TIFF, and WAV and is frequently + used by mobile phones with cameras, cameras with built-in GPS. + + + EXIF is frequently used for Geolocating photographs so their images can be + correlated with time and location. + + diff --git a/xmldoc/formats/fugawi.xml b/xmldoc/formats/fugawi.xml new file mode 100644 index 000000000..51b819f79 --- /dev/null +++ b/xmldoc/formats/fugawi.xml @@ -0,0 +1,27 @@ + + + + This was a requested CSV format, and is not the proprietary +binary format used by Fugawi. Like any other CSV format, GPSBabel +cannot read tracks in this format, but converting a track into it and +then importing as track in Fugawi works. + It is known to work with Fugawi V3.1.4.635. When +importing/exporting waypoints, one has to specify the order of fields +as follows (names of fields may depend on the language used by +Fugawi): + + - Name + - Comment + - Description + - Latidude + - Longitude + - Altitude (metres) + - Date (yyyymmdd/yymmdd) + - Time of day (hhmmss) + + When importing tracks, use "[ignore]" instead of "Name", +"Comment" and "Description". + + http://www.fugawi.com/ + + diff --git a/xmldoc/formats/g7towin.xml b/xmldoc/formats/g7towin.xml new file mode 100644 index 000000000..db734eb4c --- /dev/null +++ b/xmldoc/formats/g7towin.xml @@ -0,0 +1,9 @@ + + Like GPSBabel, G7ToWin is a program which allows uploading and + downloading information from several GPS devices (Garmin, Lowrance/Eagle, Magellan). + G7ToWin has its own data format, which is an enhanced format used in Gardown. + + + + This format can read both file types, G7ToWin (.g7t) and Gardown (.gdn). + diff --git a/xmldoc/formats/garmin.xml b/xmldoc/formats/garmin.xml new file mode 100644 index 000000000..879dcdc7a --- /dev/null +++ b/xmldoc/formats/garmin.xml @@ -0,0 +1,265 @@ + + GPSBabel supports a wide variety of Garmin hardware via serial + on most operating systems and USB on Windows, Linux, and OS X. + + + + For serial models, be sure the GPS is set for "Garmin + mode" in setup and that nothing else (PDA hotsync programs, gpsd, + getty, pppd, etc.) is using the serial port. + + + + Supported Garmin GPS receivers with USB include + +Astro +Edge 205 +Edge 305 +eTrex Legend C +eTrex Legend Cx +eTrex Legend HCx +eTrex Summit Cx +eTrex Summit HC +eTrex Venture C +eTrex Venture Cx +eTrex Venture HC +eTrex Vista C +eTrex Vista Cx +eTrex Vista HCx +Forerunner 205 +Forerunner 301 +Forerunner 305 +Foretrex 201 +Foretrex 301 +GPS 18This model does not support transfer of waypoints, tracks, or routes, but may be used with the realtime tracking feature. +GPSMAP 195 +GPSMAP 276C +GPSMAP 295 +GPSMAP 296C +GPSMAP 378 +GPSMAP 396 +GPSMAP 478 +GPSMAP 496 +GPSMAP 60C +GPSMAP 60CS +GPSMAP 60CSx +GPSMAP 60Cx +GPSMAP 76C +GPSMAP 76CS +GPSMAP 76CSX +GPSMAP 76Cx +GPSMAP 96 +GPSMAP 96C +Quest +Quest II +Rhino 520 +Rhino 530 +Rhino 520 HCx +Rhino 530 HCx +StreetPilot 2610 +StreetPilot 2620 +StreetPilot 2650 +StreetPilot 2720 +StreetPilot 2730 +StreetPilot 2820 +StreetPilot 7200 +StreetPilot 7500 +StreetPilot c310 +StreetPilot c320 +StreetPilot c330 +StreetPilot c340 +StreetPilot i2 +StreetPilot i3 +StreetPilot i5 + + +the following Bluetooth Garmin products: + +GPS 10 + + + + +and most serial Garmin GPS receivers including: + +eMap +eTrex Camo +eTrex Legend +eTrex Summit +eTrex Venture +eTrex Vista +eTrex (Basic Yellow) +eTrex H +Forerunner 201 +Foretrex 201 +Geko 201 +Geko 301 +GPS 12CX +GPS 12Map +GPS 12 +GPS 12XL +GPS III +GPS III+ +GPS II +GPS II+ +GPS V +Rhino 110 +Rhino 120 +Rhino 130 +StreetPilot III +StreetPilot III+ + + + + +The following Garmin GPS receivers are supported, but they do not +support Garmin communication protocol and don't work with the + option. To use these receivers, read or write +GPX files from the mass storage device as mounted on your computer. + +Colorado 300 +Colorado 400c +Colorado 400i +Colorado 400t +Nuvi 200 +Nuvi 205 +Nuvi 200W +Nuvi 205W +Nuvi 250 +Nuvi 255 +Nuvi 250W +Nuvi 255W +Nuvi 260 +Nuvi 260W +Nuvi 270 +Nuvi 300This unit uses GPX format, not Garmin protocol. Therefore one should communicate with it by reading and writing GPX files instead of using this format. Members of this class of products do not support realtime positioning protocol. +Nuvi 310 +Nuvi 350 +Nuvi 370 +Nuvi 600 +Nuvi 650 +Nuvi 650FM +Nuvi 660 +Nuvi 670 +Nuvi 680 +Nuvi 750 +Nuvi 760 +Nuvi 770 +Nuvi 780 +Nuvi 880 +StreetPilot c510 +StreetPilot c530 +StreetPilot c550 +StreetPilot c580 +Zumo 450 +Zumo 500 +Zumo 550 + + + + + None of the GPSBabel developers has access to every model on that + list, but we've received reports of success and/or have reasonable + expectations that the above models work. If you succeed with + a model that is not on that list, please send a message to the + gpsbabel-misc mailing list with the details so that we may add it. + + + + Not every feature on every model is supported. For example, + while we do extract data such as heart rate and temperature from + tracks on the sporting models like Edge and Forerunner, GPSBabel + is not a fitness program at its core and does not support features + like courses or calorie/fitness zone data. + + + + To communicate with a Garmin GPS serially, use the name of that + serial port such as COM1 or /dev/cu.serial. + + + To communicate via USB use usb: as the filename on all OSes. + Thus, to read the waypoints from a Garmin USB receiver and write + them to a GPX file: + + + gpsbabel -i garmin -f usb: -o gpx -F blah.gpx + + + If you have multiple units attached via USB, you may provide + a unit number, with zero being the implied default. So if you + have three USB models on your system, they can be addressed as + usb:0, usb:1, and usb:2. To get a list of recognized devices, + specifiy a negative number such as: + + gpsbabel -i garmin -f usb:-1 + + +When reporting problems with the Garmin format, be sure to include +the full unit model, firmware version, and be prepared to offer +debugging dumps by adding to the command line, like: + + + gpsbabel -D9 -i garmin -f usb: -o gpx -F blah.gpx + + +Custom icons are supported on units that support that. +Neither GPSBabel nor your firmware know what is associated with any +given slot number. They don't know that the picture you placed in the +first slot is a happy face, they only know they're in the lowest +numbered slot. GPSBabel names the them consistently with Mapsource, +so they are named 'Custom 0' through 'Custom 511'. + + + For models where the connection on the GPS is a serial interface, + be sure the GPS is set for "Garmin + mode" in setup and that nothing else (PDA hotsync programs, gpsd, + getty, pppd, etc.) is using the serial port. + + + For models connected via USB, we recommend use of the usb: + filename. For this to work on Windows, you must install + the Garmin driver. For Linux, this will fail if have the garmin_gps + kernel module loaded. + See the Operating System Notes for details. + + + +This module also supports realtime tracking +which allows realtime position reports from a Garmin GPS receiver over USB +or serial. + + + +The following Garmin units do not follow the standard Garmin +communications protocol and are not supported +by GPSBabel. + +Marine plotters: + +GPSMap 420 +GPSMap 430 +GPSMap 440 +GPSMap 450 +GPSMap 520 +GPSMap 525 +GPSMap 530 +GPSMap 535 +GPSMap 540 +GPSMap 545 +GPSMap 550 +GPSMap 555 + + + +The PDA products + +iQue 3000 +iQue 3200 +iQue 3600 +iQue M3 +iQue M4 +iQue M5 + + + diff --git a/xmldoc/formats/garmin301.xml b/xmldoc/formats/garmin301.xml new file mode 100644 index 000000000..f9c7d39fc --- /dev/null +++ b/xmldoc/formats/garmin301.xml @@ -0,0 +1,13 @@ + + + This is a very simple format that +is most useful for exporting data from units that support heart rate +data such as +Garmin Forerunner 301, +Garmin Forerunner 305, and +Garmin Edge 305, and +to other programs +for analysis. It's a simple comma delimited format that includes the +timestamp, 3D position information and heart rate so you can pull it +into a spreadsheet or graphing program. + diff --git a/xmldoc/formats/garmin_gpi.xml b/xmldoc/formats/garmin_gpi.xml new file mode 100644 index 000000000..5472e7859 --- /dev/null +++ b/xmldoc/formats/garmin_gpi.xml @@ -0,0 +1,37 @@ + + The format garmin_gpi supports the binary POI (.gpi) files that are useable + on newer Garmin GPS receivers. See garmin_poi for additional information about Garmin's own Poiloader program. + Garmin POI-Loader is the standard application that creates GPI files + with all possible features. + + + The layout of GPI files isn't documented and our module was created + via reverse engeneering. If you get a problem on reading or writing + a GPI file, please provide that file (mailto:gpsbabel-misc@lists.sourceforge.net). + + + At this time we don't support special features as "Tour-Guide" or links + to sounds and pictures. + + + + Creation timestamp issue: See option sleep !!! + + + This module does not support direct transfer of .GPI files to + receivers in Garmin protocol mode. For units like Nuvi, Zumo, or + Streetpilot, just choose a file that's on the drive where your + GPS is mounted. For units like the X series (GPSMap 60CSx, GPSMap 60Cx, Legend Hcx, etc.) + you must explictly put the unit in mass storage mode or mount + the memory chip in an external reader and transfer the file + directly. + + + + Command showing garmin_gpi output example + + + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,category="Nice Restaurants",bitmap=restaurant.bmp,notes -F "My Points.gpi" + + + diff --git a/xmldoc/formats/garmin_poi.xml b/xmldoc/formats/garmin_poi.xml new file mode 100644 index 000000000..dcf877cf7 --- /dev/null +++ b/xmldoc/formats/garmin_poi.xml @@ -0,0 +1,9 @@ + + + + The Garmin POI loader +loads custom points of interest into certain models of +Garmin GPS receivers. (As of this writing, only the models introduced +in 2005 and later are supported. See Garmin's site for more info.) +This is the format readable that that program. + diff --git a/xmldoc/formats/garmin_txt.xml b/xmldoc/formats/garmin_txt.xml new file mode 100644 index 000000000..b9a9c88d1 --- /dev/null +++ b/xmldoc/formats/garmin_txt.xml @@ -0,0 +1,23 @@ + +This is a textual format that contains nearly all of the information +contained in the MapSource main format, GDB. +This format also contains some computed values such as distances between +routepoints and trackpoints, speed, and course (heading). + + +The main goal of garmin_txt is to make aviation data more available. Because +MapSource supports only the export, GPSBabel gives you the possibility to +bring aviation data into MapSource. + + +During the export with MapSource, some fields are written using local settings +of MapSource and Windows. These include grid format, gps datum, distance and +temperature units, and the representation of date and time fields. GPSBabel +tries to read all items automatically. Problems with date and time format can +be solved with the 'date' and 'time' options. + + + Command showing garmin_txt output with all options + gpsbabel -i garmin_txt,date="MM/DD/YYYY",time="hh:mm:ss xx" -f in.txt -o garmin_txt,date="DD.MM.YYYY",datum="WGS 72",dist=m,prec=6,temp=c,time="HH:mm:ss",utc=+2 -F out.txt + + diff --git a/xmldoc/formats/gcdb.xml b/xmldoc/formats/gcdb.xml new file mode 100644 index 000000000..d9e1d4d53 --- /dev/null +++ b/xmldoc/formats/gcdb.xml @@ -0,0 +1,7 @@ + + This is format for the + +GeocachingDB program by DougsBrat. It works with v2 +and v3 of this program. + + diff --git a/xmldoc/formats/gdb.xml b/xmldoc/formats/gdb.xml new file mode 100644 index 000000000..80788965e --- /dev/null +++ b/xmldoc/formats/gdb.xml @@ -0,0 +1,12 @@ + +Support for the "Garmin GPS Database" format used by +default in MapSource versions since release 6.0 of +that product. By default GPSBabel creates +gdb files of version 2. Version 2 is used in Mapsource 6.3 and 6.5. + + +Garmin GPS database is an undocumented file format. The +basic info for this module came from the existing MapSource +conversion code. + + diff --git a/xmldoc/formats/geo.xml b/xmldoc/formats/geo.xml new file mode 100644 index 000000000..42c1b22a1 --- /dev/null +++ b/xmldoc/formats/geo.xml @@ -0,0 +1,11 @@ + +This format supports the Geocaching.com/EasyGPS ".loc" format. This format +was created specifically for Geocaching.com and is not the same as the +standard EasyGPS .loc format. See the EasyGPS +or GPX formats for more general EasyGPS support. + + +This is a simple XML-based format containing only very basic information +about geocaches. If you can use the GPX +format instead, you should consider doing so as it is a much richer format. + diff --git a/xmldoc/formats/geonet.xml b/xmldoc/formats/geonet.xml new file mode 100644 index 000000000..44e255ed8 --- /dev/null +++ b/xmldoc/formats/geonet.xml @@ -0,0 +1,8 @@ + + + + Input support for the GEOnet Names Server (GNS) country +file structure. Export to this format is not possible, as this format +has too many fields that we never get populated by any other +format. + diff --git a/xmldoc/formats/geoniche.xml b/xmldoc/formats/geoniche.xml new file mode 100644 index 000000000..9b6d9c97e --- /dev/null +++ b/xmldoc/formats/geoniche.xml @@ -0,0 +1,7 @@ + + + + Geoniche is a Palm/OS application oriented for the +off-road user. This module was contributed by Rick Richardson. + + diff --git a/xmldoc/formats/ggv_log.xml b/xmldoc/formats/ggv_log.xml new file mode 100644 index 000000000..9b76cc725 --- /dev/null +++ b/xmldoc/formats/ggv_log.xml @@ -0,0 +1,12 @@ + + Binary track logs used by the Geogrid-Viewer, a very + popular product in Germany. + + + GPSBabel has full support for version 1.0 of this file format. + + + We can also read some GPS data (including coordinates) from version 2.5. But + it seems, that this newer version no longer stores time stamps. This can be + a problem when converting to other formats or if you want to use our track filter. + diff --git a/xmldoc/formats/glogbook.xml b/xmldoc/formats/glogbook.xml new file mode 100644 index 000000000..bbaa7b02b --- /dev/null +++ b/xmldoc/formats/glogbook.xml @@ -0,0 +1,11 @@ + + + + This is the XML format used by the Garmin Logbook product +that ships with Forerunner and Foretrex. +As of early 2006, this program is apparently been discontinued in favor of +Garmin Training Center. + +See: http://www.garmin.com + + diff --git a/xmldoc/formats/google.xml b/xmldoc/formats/google.xml new file mode 100644 index 000000000..2145bc922 --- /dev/null +++ b/xmldoc/formats/google.xml @@ -0,0 +1,36 @@ + + + + This format is designed to read the XML emitted when you +tack "&output=js" onto the end of a Google Maps route URL (use +the "link to this page" option to get a usable URL.) This allows you +to plan a route using Google Maps, then download it and use it in your +own mapping program or GPS receiver. To get a file suitable for use +with GPSBabel, plan your route as usual with Google Maps. Once you've +got it the way you want it, click the "Link to this page" link in the +upper right-hand corner of the Google Maps page. Then, edit the URL +that appears in your address bar by adding "&output=js" (without +the quotes) onto the end. Hit enter, and the resulting page will be +mostly empty. It doesn't look like much, but it contains exactly what +GPSBabel needs. Save it to disk using whatever menu option your web +browser provides. + + +Note that if you are using Microsoft Internet Explorer, you should make sure +to save the web page as "Web Page, HTML Only". If you save it as "Web Page, +Complete", it will be reformatted into a non-XHTML format that GPSBabel +cannot read. + + +If you use a Unix-compatible +operating system, this shell script might be useful: + + +#!/bin/sh +FROM="233 S. Upper Wacker Dr, Chicago, IL" +TO="1060 W. Addison St, Chicago, IL" +wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" \ +2&>/dev/null >google_map.js +gpsbabel -i google -f google_map.js -o gpx -F google_map.gpx + + diff --git a/xmldoc/formats/gpilots.xml b/xmldoc/formats/gpilots.xml new file mode 100644 index 000000000..ffb947cdd --- /dev/null +++ b/xmldoc/formats/gpilots.xml @@ -0,0 +1,10 @@ + + + + This is a Palm/OS file format for + GPilotS. + It was tested against version 6.2 of GPilotsS + + Neither tracks nor routes are supported at this +time. + diff --git a/xmldoc/formats/gpl.xml b/xmldoc/formats/gpl.xml new file mode 100644 index 000000000..cace2eaa4 --- /dev/null +++ b/xmldoc/formats/gpl.xml @@ -0,0 +1,8 @@ + + + + This is the 'gpl' format as used in Delorme mapping +products. It is a track format and contains little more than the +tracklog of a GPS that was attached while driving. frontiernet.net + + diff --git a/xmldoc/formats/gpsdrive.xml b/xmldoc/formats/gpsdrive.xml new file mode 100644 index 000000000..c69eb2c2a --- /dev/null +++ b/xmldoc/formats/gpsdrive.xml @@ -0,0 +1,7 @@ + + + + GpsDrive way.txt file format. A space seperated format +file. Tested against GpsDrive v 1.30 found at gpsdrive.de. +Contributed by Alan Curry. + diff --git a/xmldoc/formats/gpsdrivetrack.xml b/xmldoc/formats/gpsdrivetrack.xml new file mode 100644 index 000000000..dc127adc6 --- /dev/null +++ b/xmldoc/formats/gpsdrivetrack.xml @@ -0,0 +1,7 @@ + + + + Format used by GpsDrive to save tracks. Like GPSDRIVE a +space seperated format file. See above for a link to GpsDrive. +Contributed by Tobias Minich. + diff --git a/xmldoc/formats/gpsman.xml b/xmldoc/formats/gpsman.xml new file mode 100644 index 000000000..b1b0a6ede --- /dev/null +++ b/xmldoc/formats/gpsman.xml @@ -0,0 +1,13 @@ + + + + GPS Manager +can read and write formats GPSBabel doesn't understand. The format defaults +(WGS84, DDD) work reliably. Tracks, routes, and non-default format options +are not supported. + + + This format is documented at the GPS Manager + doc site. + + diff --git a/xmldoc/formats/gpspilot.xml b/xmldoc/formats/gpspilot.xml new file mode 100644 index 000000000..26ab9000b --- /dev/null +++ b/xmldoc/formats/gpspilot.xml @@ -0,0 +1,10 @@ + + + + The file format for GPSPILOT gpspilot.com was provided by Ron +Parker. The output from this module has been tested with GPSPilot +Tracker v5.05sx, but it is based on reverse-engineering so it may not +work with all versions of all GPSPilot products. It had read-only +support for Airport, Navaid, City and Landmark files but will read and +write Point files. + diff --git a/xmldoc/formats/gpssim.xml b/xmldoc/formats/gpssim.xml new file mode 100644 index 000000000..c318310ff --- /dev/null +++ b/xmldoc/formats/gpssim.xml @@ -0,0 +1,9 @@ + + This is a write-only format used to feed waypoints, tracks, and routes + into Franson Technolgies' + GpsGate simulator. + + + To use these files in GpsGate, select 'Simulator' and then + "File->Open". + diff --git a/xmldoc/formats/gpsutil.xml b/xmldoc/formats/gpsutil.xml new file mode 100644 index 000000000..d39bd8d79 --- /dev/null +++ b/xmldoc/formats/gpsutil.xml @@ -0,0 +1,12 @@ + + + + The format we call gpsutil is a simple file format used by a program that runs +on POSIX- compliant OSes like UNIX and Linux. Reads and writes of +this format are very reliable. (The lead +developer of GPSBabel also contributed to this that 'gpsutil' +the early days.) + + Note that 'gpsutil' is a different format - and program - than the one called GPS Utility; for that one, you should probably use our PCX module. + + diff --git a/xmldoc/formats/gpx.xml b/xmldoc/formats/gpx.xml new file mode 100644 index 000000000..d70cb77af --- /dev/null +++ b/xmldoc/formats/gpx.xml @@ -0,0 +1,14 @@ + + + + This is the most capable and expressive of all the file +formats supplied. It is described at topografix.com and is +supported by EasyGPS, ExpertGPS, and many other programs described at +topografix.com + + + GPSBabel's reader of this module attempts to preserve tags it doesn't + really understand. It also tries to glean interesting data from + pocket queries from Geocaching.com and Garmin's "gpxx" GPX extensions. + + diff --git a/xmldoc/formats/gtm.xml b/xmldoc/formats/gtm.xml new file mode 100644 index 000000000..8b28f36e4 --- /dev/null +++ b/xmldoc/formats/gtm.xml @@ -0,0 +1,5 @@ + Input and output support for waypoints, tracks and routes in + the GPS TrackMaker + binary format. + Code implemented by Gustavo Niemeyer. + diff --git a/xmldoc/formats/gtrnctr.xml b/xmldoc/formats/gtrnctr.xml new file mode 100644 index 000000000..34c59528d --- /dev/null +++ b/xmldoc/formats/gtrnctr.xml @@ -0,0 +1,16 @@ + +GPSBabel has limited support for Garmin Training Center files. That program is the successor to Garmin' Logbook program for their workout units. It is a free upgrade. + + +This format is somewhat underachieving in GPSBabel. It is a write-only +format; we never read it. The bigger problem, however, is a fundamental +impedance mismatch between this format and most of what we support. GPSBabel +fundamentally deals in waypoints, tracks, and routes. While we do record +things like heart rate and temperature when we know it, the fundamentals +of Training Center are different - it deals in concepts like laps and calories +which are rather alien to GPSBabel and most of the formats we support. As +such, while we can describe the tracks pretty accurately, things like +calories and heart zone tracking are not supported. + + + diff --git a/xmldoc/formats/hiketech.xml b/xmldoc/formats/hiketech.xml new file mode 100644 index 000000000..65d69bf7d --- /dev/null +++ b/xmldoc/formats/hiketech.xml @@ -0,0 +1,8 @@ + + + + This is the .gps format used by the Mac OS X applications +written by HikeTech. These include TopoDraw, Link2GPS, and GPSWrite. +More information about these products can be found at hiketech.com + + diff --git a/xmldoc/formats/holux.xml b/xmldoc/formats/holux.xml new file mode 100644 index 000000000..8524b1483 --- /dev/null +++ b/xmldoc/formats/holux.xml @@ -0,0 +1,28 @@ + + + + The Holux gm-100 (e-fox) gps receiver uses standard +compact flash cards. File formats were provided by Holux-Taiwan +holux.com to the author. +The code was tested against version 2.27E1; other versions and +receivers may work but have not been explictly tested. Anyone with +information on other Holux receivers is encouraged to contact +jochen@bauerbahn.net. + + When copying the .wpo file to a flash card, the file must +be named tempwprt.wpo as the +receiver will ignore all other files. + + Comparing the waypoints of a .wpo files against other +formats like .gpx you may notice a small difference in the latitude +and longitude values. The reason is the low resolution of the +coordinates in the wpo file format. In a .wpo file the reolution is +1/10"; in gpx for example it is 1/100". A a practical matter, this +loss is only about 1.7 meters (5 feet). + + The generated waypoint failes can also be used by MapShow +version 1.14. This program is free of charge from the Holux web site. + + This format was contributed by Jochen Becker. + + diff --git a/xmldoc/formats/hsandv.xml b/xmldoc/formats/hsandv.xml new file mode 100644 index 000000000..88847d68c --- /dev/null +++ b/xmldoc/formats/hsandv.xml @@ -0,0 +1,8 @@ + + + + HSA Systems Endeavour Navigator format - will import both +the old version 4.x binary files, and the newer XML based ones. Only +writes the new XML (5.0 and above) format. (use the .exp +extension) + diff --git a/xmldoc/formats/html.xml b/xmldoc/formats/html.xml new file mode 100644 index 000000000..211da87ff --- /dev/null +++ b/xmldoc/formats/html.xml @@ -0,0 +1,16 @@ + GPSBabel's HTML output generates a single HTML file of all of the +waypoints in the input file. It supports a number of Groundspeak GPX +extensions and filters out potentially harmful HTML from the +input file while maintaining almost all of the source HTML formatting. +This makes this format well suited for generating HTML to hand to programs +like Plucker for putting in a PDA and especially so for "paperless caching" +for Geocachers with pocket queries. + +This format is similar to the text format. + + The following command line reads a GPX file with +Groundspeak extensions and writes an HTML file with encrypted hints +that is rendered using a custom stylesheet: + +gpsbabel -i gpx -f 12345.gpx -o html,stylesheet=green.css,encrypt -F 12345.html + diff --git a/xmldoc/formats/igc.xml b/xmldoc/formats/igc.xml new file mode 100644 index 000000000..57e330b13 --- /dev/null +++ b/xmldoc/formats/igc.xml @@ -0,0 +1,134 @@ + +FAI/IGC Data File -- Used by the international gliding +community to record gliding flights. IGC files can be converted to +and from tracks representing recorded flights, and routes representing +task declarations in other formats. + + +
                    +IGC Data Format Notes + +Refer to Appendix 1 of +http://www.fai.org:81/gliding/gnss/tech_spec_gnss.asp +for the specification of the IGC data format. + + +A sample list of software applications that use data in IGC format can be +found at +http://www.fai.org:81/gliding/gnss/gnss_analysis_software.pdf + + +GPSBabel can be used to translate data in IGC format to and from various other +formats. + + +Routes in other formats are used to represent IGC task declarations. + + +Tracks in other formats are used to represent IGC recorded flights. + +
                    + +
                    +Converting to IGC format + +IGC files generated by GPSBabel will NOT pass security validation tests since +the data they contain cannot be proven to originate from an approved flight +recorder. For most software applications that use IGC files this is not an +issue but for competition scoring, record and badge claims the generated files +will not be accepted as proof of a flight. + + +A track stored in another format (GPX for example) representing a recorded +flight can be converted into an IGC file: + +gpsbabel -i gpx -f mytrk.gpx -o igc -F myflight.igc + +If multiple track segments are provided in the input file, the one with the +most points will be used. + + +A route stored in another format representing a task declaration can be +converted into an IGC file: + +gpsbabel -i gpx -f myrte.gpx -o igc -F mytask.igc + +A route and a track in other formats can be included into a single IGC file: + +gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -o igc -F myflight.igc + +A similar result can be obtained by downloading the track log and routes +directly from a GPS device connected to a PC. For example to create an IGC +file from data recorded in a Garmin GPS connected to the first serial port of +a PC running Linux: + +gpsbabel -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc + +For Windows operating systems: + +gpsbabel -t -r -i garmin -f com1 -o igc -F myflight.igc + +A waypoint file in another format containing a waypoint whose short name is +"PILOT" can be merged into an IGC file. The description field of the waypoint +will be used for the pilot name in the IGC file header: + +gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -f mywpt.gpx -o igc -F myflight.igc +gpsbabel -w -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc + +Some formats such as GPX allow routes, tracks and waypoints to exist in the +same file and can be used to fully populate an IGC file: + +gpsbabel -i gpx -f myall.gpx -o igc -F myflight.igc +
                    + +
                    +Converting from IGC format + +Data in an IGC file can be converted into other formats. For example to +generate OziExplorer files containing tracks representing the recorded +flight (myozi.plt) and routes representing declared tasks (myozi.rte): + +gpsbabel -i igc -f myflight.igc -o ozi -F myozi + +Or to GPX format: + +gpsbabel -i igc -f myflight.igc -o gpx -F myflight.gpx + +Header information from the IGC file will be written to the description field +of the track(s). + + +If both pressure altitude and GNSS altitude are recorded in the IGC file, two +tracks will be written to the new track file, representing the two altitude +tracks. The latitude, longitude and timestamps in the tracks will be identical. + +
                    + +
                    +Merging into IGC format + +A route stored in another format can be merged with an existing IGC file that +has no task declaration, to generate a new IGC file with a task declaration: + +gpsbabel -i igc -f myflight.igc -i gpx -f myrte.gpx -o igc -F mynew.igc + +A two dimensional (lat/lon) track recorded during a flight by a GPS receiver +can be merged with a one dimensional (altitude) track recorded during the same +flight by a barograph instrument. The result is a three dimensional IGC file +representing the flight: + +gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc -F my3D.igc + +The same can be acheived by downloading directly from a barograph instrument +supported by GPSBabel. For example with a Brauniger IQ Comp GPS variometer: + +gpsbabel -i baroiq -f /dev/ttyS0 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc + +or: + +gpsbabel -i baroiq -f com1 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc + +(Documentation contributed by Chris Jones, Aug 2004) + +
                    + diff --git a/xmldoc/formats/ignrando.xml b/xmldoc/formats/ignrando.xml new file mode 100644 index 000000000..aedde6626 --- /dev/null +++ b/xmldoc/formats/ignrando.xml @@ -0,0 +1,6 @@ + +This format supports IGN Rando track files. IGN Rando is a program mainly +used in France for Topo maps. The files are XML based and are "windows-1252" +encoded. Trackpoints do not have time stamps. + + diff --git a/xmldoc/formats/ik3d.xml b/xmldoc/formats/ik3d.xml new file mode 100644 index 000000000..d23ed7817 --- /dev/null +++ b/xmldoc/formats/ik3d.xml @@ -0,0 +1,11 @@ + + This is the format for MagicMaps project (.ikt) files. + + + MagicMaps "Das interaktive Kartenwerk" is a Software from Germany. It's a + route-planning software with a 3-dimensional envirounment. + + + The project files are XML based and we can read the main GPS items (names and coordinates). + For an output these files are too complex. + diff --git a/xmldoc/formats/kml.xml b/xmldoc/formats/kml.xml new file mode 100644 index 000000000..e51a42573 --- /dev/null +++ b/xmldoc/formats/kml.xml @@ -0,0 +1,33 @@ + +KML, the Keyhole Markup Language, is used by Keyhole and +Google Earth. + +There are concepts in KML that GPSBabel can't support very well on +read becuase they don't map well into other programs. For example, KML has +ideas of camera views and names and descriptions can have arbitrarily +complicated HTML in them. KML files may have tiered "Styles" which +can identify sizing info and URLs of associated icons. Reading such +files with GPSBabel - even if your goal it to out to KML - can often +have suprising results. Simple files with waypoints and paths (which +GPSBabel represents internally as tracks) work fine. + + +Google Earth also uses GPSBabel internally for receiver communications +and several file format imports and exports. + + +In general, GPSBabel's KML writer is relatively strong. GPSBabel handles simple KML on read fairly well, but if you're dealing with handcrafted KML that uses extensive features that have no analog in other formats like nested folders, ringgeometry, camera angles, and such, don't expect GPSBabel to do well with them on read. + + + Google Earth 4.0 and later have a feature that can suprise users of this + format. Earth's "time slider" feature controls what timestamped data + gets displayed. If you're using data that has timestampes (e.g. GPX + points that contain time or almost any track data) this will be important + to you. The time slider defaults to the far left position and fully closed. + This means that only the first data point will be displayed. You can + tweak Earth's settings to "view->show time->never" or + you can widen the time slider to show the range of data of interest. + + + See Google Earth's documentation on timelines for more info. + diff --git a/xmldoc/formats/kompass_tk.xml b/xmldoc/formats/kompass_tk.xml new file mode 100644 index 000000000..6b49141a7 --- /dev/null +++ b/xmldoc/formats/kompass_tk.xml @@ -0,0 +1,8 @@ + + This module supports track files used by Kompass and DAV "Deutscher Alpenverein". + + + Kompass is a publishing company from Austria. + If you want to get more information about DAV, the German alpine association, + and if you are familiar with the german language, please have a look at their homepage. + diff --git a/xmldoc/formats/kompass_wp.xml b/xmldoc/formats/kompass_wp.xml new file mode 100644 index 000000000..6ef21ccce --- /dev/null +++ b/xmldoc/formats/kompass_wp.xml @@ -0,0 +1,7 @@ + + This module supports waypoint files used by Kompass and DAV "Deutscher Alpenverein". + + + Some more information under kompass_tk format. + + diff --git a/xmldoc/formats/ktf2.xml b/xmldoc/formats/ktf2.xml new file mode 100644 index 000000000..31fd17dbf --- /dev/null +++ b/xmldoc/formats/ktf2.xml @@ -0,0 +1,3 @@ + + Support for Kartex 5 trackfiles. For more info see kwf2. + diff --git a/xmldoc/formats/kwf2.xml b/xmldoc/formats/kwf2.xml new file mode 100644 index 000000000..307caa1ff --- /dev/null +++ b/xmldoc/formats/kwf2.xml @@ -0,0 +1,9 @@ + + + + Support for Kartex 5 waypoint files. Kartex is a Swedish + map and GPS positioning system. GPSBabel can read and write + files from Kartex 4 and 5 with WGS84 coordinates. UTM or + Swedish grid are not supported. + + diff --git a/xmldoc/formats/lmx.xml b/xmldoc/formats/lmx.xml new file mode 100644 index 000000000..8f512a87b --- /dev/null +++ b/xmldoc/formats/lmx.xml @@ -0,0 +1,6 @@ + +This format supports Nokia Landmark Exchange (LMX) files used by several +Nokia phones. GPSBabel supports only the traditional XML format and +not the compressed binary format. + + diff --git a/xmldoc/formats/lowranceusr.xml b/xmldoc/formats/lowranceusr.xml new file mode 100644 index 000000000..99fe49495 --- /dev/null +++ b/xmldoc/formats/lowranceusr.xml @@ -0,0 +1,9 @@ + +The Lowrance iFinder GPS series has the unique capability +to output its data to an MMC card. The data is saved to the card as a +.USR file and can be read by your computer using a card reader. +Waypoints, icons, routes, tracks are supported. Event marker icons contain a symbol, name, latitude and longitude +only. By default, Event marker +icons are converted to waypoints on read. On write, you are able to create icons from waypoints. + + diff --git a/xmldoc/formats/mag_pdb.xml b/xmldoc/formats/mag_pdb.xml new file mode 100644 index 000000000..eff15549d --- /dev/null +++ b/xmldoc/formats/mag_pdb.xml @@ -0,0 +1,10 @@ + + + + With this format we support the Palm/OS export for +Map&Guide based products like "PowerRoute", +"Motorrad-Routenplaner" and (maybe) other software. The exported files +can contain maps and/or route descriptions. The reader for this format +has been tested with PowerRoute 5+6, Motorrad-Routenplaner +2002(-2006). + diff --git a/xmldoc/formats/magellan.xml b/xmldoc/formats/magellan.xml new file mode 100644 index 000000000..7cb28f149 --- /dev/null +++ b/xmldoc/formats/magellan.xml @@ -0,0 +1,38 @@ +GPSBabel supports the following Magellan receivers: + + 310 + 315 + Map330 + SporTrak Map Color + SporTrak Map + SporTrak Map Pro + SporTrak Map Topo + Meridian (green or yellow) + Meridian Gold + Meridian Platinum + Meridian Color + Explorist 100 (with aftermarket cable) + Explorist 200 (with aftermarket cable) + Explorist 300 (with aftermarket cable) + Explorist 210 + Explorist 300 + Explorist 400 + Explorist 500 + Explorist 600 + Explorist XL + + + + + This format is used for both the serial protocol used on the + devices with serial ports such as Map330 and Meridian and for + the files stored either in either the unit's internal memory + (Explorist 210, Explorist 400, Explorist 500, Explorist 600, + Explorist XL) or on removable memory. + + + If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyS0") + to be read or written, GPSBabel will use serial protocol. Specifying + a file, either on local filesystem or on a mounted flash card reader, + will results in the file-based format being used. + diff --git a/xmldoc/formats/magellan1.xml b/xmldoc/formats/magellan1.xml new file mode 100644 index 000000000..831285c8b --- /dev/null +++ b/xmldoc/formats/magellan1.xml @@ -0,0 +1,96 @@ +GPSBabel supports the following Magellan receivers: + + 310 + 315 + Map330 + SporTrak Map Color + SporTrak Map + SporTrak Map Pro + SporTrak Map Topo + Meridian (green or yellow) + Meridian Gold + Meridian Platinum + Meridian Color + Explorist 100 (with aftermarket cable) + Explorist 200 (with aftermarket cable) + Explorist 300 (with aftermarket cable) + Explorist 210 + Explorist 300 + Explorist 400 + Explorist 500 + Explorist 600 + Explorist XL + + + +The RoadMate family of products is not supported. + + + + This format is used for both the serial protocol used on the + devices with serial ports such as Map330 and Meridian and for + the files stored either in either the unit's internal memory + (Explorist 210, 400, 500, 600, XL) or on removable memory. + + + If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyS0") + to be read or written, GPSBabel will use serial protocol. Specifying + a file, either on local filesystem or on a mounted flash card reader, + will result in the file-based format being used. + + + Users of the Explorist generation of receivers should probably + prefer to use the magellanx + format over this one. + + + + +This module does not support the units that do not follow Magellan's +documented communications protocols including: + +Maestro 3100 +Maestro 3140 +Maestro 3200 +Maestro 3210 +Maestro 3220 +Maestro 3225 +Maestro 3250 +Maestro 4000 +Maestro 4040 +Maestro 4050 +Maestro 4200 +Maestro 4210 +Maestro 4220 +Maestro 4250 +Maestro 5310 + + RoadMate 300 + RoadMate 360 + RoadMate 500 + RoadMate 700 + RoadMate 760 + RoadMate 800 + RoadMate 860T + RoadMate 1200 + RoadMate 1400 + RoadMate 1412 + RoadMate 1430 + RoadMate 2000 + RoadMate 2000 + RoadMate 2200T + RoadMate 3000T + RoadMate 3050T + RoadMate 6000T + RoadMate AAA + + Triton 200 + Triton 300 + Triton 400 + Triton 500 + Triton 1500 + Triton 2000 + + + + diff --git a/xmldoc/formats/magellanx.xml b/xmldoc/formats/magellanx.xml new file mode 100644 index 000000000..ffb219fb5 --- /dev/null +++ b/xmldoc/formats/magellanx.xml @@ -0,0 +1,14 @@ + + This is the SD card format used by the Magellan Explorist 400, + Explorist 500, Explorist 600, and Explorist XL and internally on those devices plus the + Explorist 210. Stored waypoints are identical to the Magellan SD format + used by Meridian, but the newer models allow longer waypoint names. Routes are + subtly different. + + + You should name any file containing waypoints created with + this format with a ".upt" extension so the firmware can read it. + Similarly, routes should be named ".rte" and tracks should be + named ".log". + + diff --git a/xmldoc/formats/maggeo.xml b/xmldoc/formats/maggeo.xml new file mode 100644 index 000000000..43aa3c392 --- /dev/null +++ b/xmldoc/formats/maggeo.xml @@ -0,0 +1,12 @@ + + + + This format support the on-card format used by the Magellan Explorist 400, +Explorist 500, Explorist 600, Explorist 210, and Explorist XL +to describe geocaches. Notice what while the format can +hold an infinite number of geocaches, the unit will read and silently +discard all but 200 geocache POIs at a time. + You should name any file created with this format with a +".gs" extension so the firmware can read it. + + diff --git a/xmldoc/formats/magnav.xml b/xmldoc/formats/magnav.xml new file mode 100644 index 000000000..765111705 --- /dev/null +++ b/xmldoc/formats/magnav.xml @@ -0,0 +1,44 @@ + +Magellan NAV Companion for Palm/OS is not really designed +for this sort of use, but its file format is supported and with a +little bit of patience you can both read and write NAV Companion +waypoints. This conversion is based on +partially incomplete reverse-engineering of the record format, so it +may not work with all versions of NAV Companion. It has been tested +with version 2.10 and 3.20. + + +Translating NAV Companion waypoints to another format is as easy +as with any other format. Just find the Companion_Waypoints database +in your palm backup directory and use it as the input file. + + +When translating waypoints back to NAV Companion, though, you need +to jump through some hoops: + + +First, you must merge any waypoints that already exist in the database +in your Palm Backup directory with the ones you are adding; failure to +do so will result in only the new points being available in NAV Companion, +even if you give the new database a different name (it will overwrite +the old database, even in your backup directory. That's a feature of +PalmOS, not of NAV Companion.) + + +To merge the databases, use a command line like the following: + +gpsbabel -i magnav -f Companion_Waypoints.PDB -i geo -f geocaching.loc -o magnav -F merged.pdb + +Second, you must use the installer to install your new PDB file. Don't +make the mistake of copying it over the existing Companion_Waypoints.PDB +file; the one on the handheld will overwrite it rather than merging with +it. + + +Finally, because NAV Companion is not designed to work with desktop +applications, you must tell NAV Companion that its waypoints database +has changed out from under it. One way to do this is to go to the +waypoints screen and attempt to scroll; that will force it to reread +the database and fix the record pointers that it keeps on the heap. + + diff --git a/xmldoc/formats/mapconverter.xml b/xmldoc/formats/mapconverter.xml new file mode 100644 index 000000000..3c9fa9dab --- /dev/null +++ b/xmldoc/formats/mapconverter.xml @@ -0,0 +1,61 @@ + +Mapconverter is a format that is read by Mapopolis.com's +mapconverter application. + + +Mapconverter is an application used to create userland maps and map data for +Mapopolis.com's Mapopolis program. The mapconverter format is essentially +waypoint data prepared in a format that the mapconverter application will +accept. + + +The steps for using GPSBabel and Mapconverter go something like this: + + +Step 1: Create a mapconverter file using gpsbabel. + +gpsbabel -i geo -f geocaching.loc -o mapconverter -F foo.txt + +Step 2: Launch mapconverter.exe and choose foo.txt as your input file. + Click the begin button to have mapconverter process foo.txt. + + +If all goes successfully, you should have a file called "foo.pdb" ready +for syncing with your PDA. Put it wherever Mapopolis thinks it should be +on your PDA. + +
                    +Notes + + + +GPSBabel will write the name of its own output file in the output file + it creates as the input for Mapconverter. Mapconverter will replace + the extension of this filename with ".pdb". + + + + +The PocketPC version of Mapopolis doesn't notice files with the ".pdb" + extension. To make this work, change the extension to ".mlp" when + copying the mapconverter output to your PocketPC PDA. + + + + +Mapconverter only works with Mapopolis version 3.x. Mapopolis version + 4 will refuse to load mapconverter maps. There is no known work-around + for this at the time of this writing. + + + + +Mapconverter is no longer available from the Mapopolis website. If you + need a copy of mapconverter, ask on your local GPS Software discussion + forum and I'm sure someone will have it. As far as I know, It was never + actually acknowledged/supported by Mapopolis to begin with. + + + +
                    + diff --git a/xmldoc/formats/mapsend.xml b/xmldoc/formats/mapsend.xml new file mode 100644 index 000000000..a33cdc3bc --- /dev/null +++ b/xmldoc/formats/mapsend.xml @@ -0,0 +1,8 @@ + +This format supports the Magellan MapSend native +file format. + + +Kudos to Magellan for having the foresight to document their file formats, +making software like this possible. + diff --git a/xmldoc/formats/mapsource.xml b/xmldoc/formats/mapsource.xml new file mode 100644 index 000000000..7460e008b --- /dev/null +++ b/xmldoc/formats/mapsource.xml @@ -0,0 +1,28 @@ + +This format supports the Garmin Mapsource +product family. + + +This format is based on significant reverse-engineering and guesswork. +GPSBabel's output appears to be compatible with the various versions of +MapSource. Icon mapping is attempted between different MapSource versions. +Altitude is supported, but proximity and depth are not. + + +Naming files *.mps will allow file->open in Mapsource to find the files +more easily. + + +Versions 3, 4, and 5 of the Mapsource data format are handled automatically +on input. By default the output is version 5. (Until 3/2004, it was +version 3, but since Mapsource updates are free, the convenience of +having modern icon sets outweighs the backward compatibility concern. +Users of other versions can either upgrade or specify the switches to +get output in a compatible format.) Waypoints, routes, and tracklogs are +all handled, but map sets are ignored. + + +Information on the Garmin Mapsource format was provided by Ian Cowley and +Mark Bradley. The code was implemented by Robert Lipe and Mark Bradley. + + diff --git a/xmldoc/formats/msroute.xml b/xmldoc/formats/msroute.xml new file mode 100644 index 000000000..d1d4d36b2 --- /dev/null +++ b/xmldoc/formats/msroute.xml @@ -0,0 +1,22 @@ + + + + Input support for Microsoft AutoRoute 2002-2006 .axe files +and Microsoft Streets and Trips .est files. This is for reading routes +created this program and is different than the +s_and_t format used for writing pushpins. +These files contains only routes. We can extract the coordinates and +the names of the points within route. An export to this format will +not be supported. + Only the start, stops, and end points are stored in the +.est/.axe/.ptm files. Turn-by-turn route data is not stored in the +.est/.axe/.ptm files, and is recalculated by the Microsoft title each +time on opening the file. This means that the output of GPSBabel will +not contain turns needed for driving directions. + One possible approach to achieve similar results is to +use the Streets and Trips drawing tools to trace a line over the +interesting parts of the route to capture intersections or key turns. +GPSBabel will capture stops in the route and insert those as turns, so +adding stops at intersections can also improve the results when converting. + + diff --git a/xmldoc/formats/msroute1.xml b/xmldoc/formats/msroute1.xml new file mode 100644 index 000000000..d1d4d36b2 --- /dev/null +++ b/xmldoc/formats/msroute1.xml @@ -0,0 +1,22 @@ + + + + Input support for Microsoft AutoRoute 2002-2006 .axe files +and Microsoft Streets and Trips .est files. This is for reading routes +created this program and is different than the +s_and_t format used for writing pushpins. +These files contains only routes. We can extract the coordinates and +the names of the points within route. An export to this format will +not be supported. + Only the start, stops, and end points are stored in the +.est/.axe/.ptm files. Turn-by-turn route data is not stored in the +.est/.axe/.ptm files, and is recalculated by the Microsoft title each +time on opening the file. This means that the output of GPSBabel will +not contain turns needed for driving directions. + One possible approach to achieve similar results is to +use the Streets and Trips drawing tools to trace a line over the +interesting parts of the route to capture intersections or key turns. +GPSBabel will capture stops in the route and insert those as turns, so +adding stops at intersections can also improve the results when converting. + + diff --git a/xmldoc/formats/mtk-bin.xml b/xmldoc/formats/mtk-bin.xml new file mode 100644 index 000000000..6d5b0578b --- /dev/null +++ b/xmldoc/formats/mtk-bin.xml @@ -0,0 +1,26 @@ +Binary file protocol converter for MTK based GPS loggers. +This format reads the raw binary format created by the MTK Windows application +and outputs to other formats supported by GPSBabel +When using the csv option a MTK application compatible output file will also be created. + +It has been tested with Transystem i-Blue 747 but other devices should +work as well (Qstarz BT-Q1000, iTrek Z1, ...) + +All position items (including button push) will be listed as trackpoints in the output. +Log items due to button push are presented as waypoints. +In theory we would not add waypoints to the list of trackpoints. But as the MTK logger restart the +log session from the button press we would loose a trackpoint unless we include/duplicate it. + + + +Transystem i-Blue 747 + + + Convert MTK binary trackpoints to GPX + + gpsbabel -t -i mtk-bin,csv=extra.csv -f data.bin -o gpx -F out.gpx + Additionally a CSV output file is created. + + + + diff --git a/xmldoc/formats/mtk.xml b/xmldoc/formats/mtk.xml new file mode 100644 index 000000000..196b6a36c --- /dev/null +++ b/xmldoc/formats/mtk.xml @@ -0,0 +1,21 @@ +Serial download protocol for the i-Blue 747 and other MTK based GPS data loggers. Observe that it is only possible to download data using USB cable, Bluetooth requires a hardware modification. + +Transystem i-Blue 747 +Downloaded data will be stored in data.bin file in the current directory together with +the choosen output format. + +It has been tested with Transystem i-Blue 747 but other devices should work as well (Qstarz BT-Q1000, iTrek Z1, ...) + +See mtk-bin on how trackpoints/waypoints are handled + + Command showing MTK download track and waypoints and erase on Linux + gpsbabel -t -w -i mtk,erase -f /dev/ttyUSB0 -o gpx -F out.gpx + + + + For more info and tweaks on MTK based loggers: + MTK Tips ans Tweaks + iBlue 747 Logger + For info about the used log format: + MTK binary format + diff --git a/xmldoc/formats/mxf.xml b/xmldoc/formats/mxf.xml new file mode 100644 index 000000000..c5b511c46 --- /dev/null +++ b/xmldoc/formats/mxf.xml @@ -0,0 +1,8 @@ + + + + Maptech Exchange Format - Another CSV format file. This +format complies with (at least) Maptech Terrain Navigator, Terrain +Professional, Take a Hike, and ExpertGPS import/export MFX. +Contributed by Alex Mottram. + diff --git a/xmldoc/formats/navicache.xml b/xmldoc/formats/navicache.xml new file mode 100644 index 000000000..6400ce3c4 --- /dev/null +++ b/xmldoc/formats/navicache.xml @@ -0,0 +1,9 @@ + + + + This is the XML format that's used by Navicache.com for +their geocaching data. There are a number of fields in it that are +marked "required" but are Navicache-specific, so GPSBabel can not +write these files, but we can still read them. navicache.com + + diff --git a/xmldoc/formats/navilink.xml b/xmldoc/formats/navilink.xml new file mode 100644 index 000000000..aae598562 --- /dev/null +++ b/xmldoc/formats/navilink.xml @@ -0,0 +1,32 @@ + + GPSBabel supports the Navilink protocol used by the + Locosys GT-11 + GPS receivers. These are sold under a variety of names including: + + NaviGPS + NaviGPS-BT + GT-11 + BGT-11 + Amaryllo + + + + This format is used for both the serial protocol used on + the USB link and for the files which can be copied from the + internal memory to the SD card using recent firmware versions. + + + If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyUSB0") + to be read or written, GPSBabel will use the serial protocol. Specifying + a file, either on local filesystem or on a mounted flash card reader, + will results in the file-based format being used. + + + To access the device using the serial protocol over USB the + device needs to be in Navilink mode, which can be activated + from the main menu of the device. + + + Details of the Navilink serial protocol can be found + here. + diff --git a/xmldoc/formats/netstumbler.xml b/xmldoc/formats/netstumbler.xml new file mode 100644 index 000000000..4bdbfc777 --- /dev/null +++ b/xmldoc/formats/netstumbler.xml @@ -0,0 +1,21 @@ + +This format reads summary files from NetStumbler +0.4 or MacStumbler. + + +The default behavior when creating waypoints is to use the SSID for +the short name, and information about the access point for the +description. When the SSID is not unique, is not available, or +consists of whitespace, a short name is synthesized. + + +Different icons are assigned to encrypted, +non-encrypted, stealth, and non-stealth access points; these may be +changed with options. + + +NetStumbler + + +MacStumbler + diff --git a/xmldoc/formats/nima.xml b/xmldoc/formats/nima.xml new file mode 100644 index 000000000..ea2790de4 --- /dev/null +++ b/xmldoc/formats/nima.xml @@ -0,0 +1,6 @@ + + + + This is a CSV format from the National Imagery and Mapping +Agency. + diff --git a/xmldoc/formats/nmea.xml b/xmldoc/formats/nmea.xml new file mode 100644 index 000000000..590155956 --- /dev/null +++ b/xmldoc/formats/nmea.xml @@ -0,0 +1,53 @@ + + + This format is the file representation of the NMEA +(National Marine Electronics Association) 0183 +log and waypoint format for GPS devices. Some hardware and software +that work with NMEA-0183 formatted data include: + + + + GPS Data Logger + + + GPS TrackMaker + + + GPSMaster + + + NMEAlog + + + VisualGPS + + + GPS Utility + + + GeoConv + + + CommLinx GPS recorder + + + SparkFun GPS Datalogger + + + Sony GPS-CS1 + + + +This module also supports realtime tracking +which allows realtime position reports from a GPS, such as one connected +serially, over Bluetooth, or a USB module emulating a serial port, to be used +with selected output formats. + + +When used in realtime tracking mode, if +GPSBabel does not sense incoming NMEA sentences arriving from the port, it +will send Sirf "reset to NMEA" commands to the port at a variety of speeds +in an attempt to communicate with an attached GPS. This lets devices +like the Microsoft GPS or Pharos GPS that are Sirf chips with an integrated +USB/Serial adapter work with this input format. + diff --git a/xmldoc/formats/nmn4.xml b/xmldoc/formats/nmn4.xml new file mode 100644 index 000000000..8442ccbd0 --- /dev/null +++ b/xmldoc/formats/nmn4.xml @@ -0,0 +1,10 @@ + + + + Support for Navigon Mobile Navigator route (.rte) files. +This is a very simple text format that only requires coordinates, but +has fields for many other things. We only write coordinates as fields +like 'city' and 'street' cannot typically be populated from other +formats. www.navigon.com + + diff --git a/xmldoc/formats/openoffice.xml b/xmldoc/formats/openoffice.xml new file mode 100644 index 000000000..56d50f1c0 --- /dev/null +++ b/xmldoc/formats/openoffice.xml @@ -0,0 +1,11 @@ + + + + Tab seperated export-all (except geocaching data) file +format. Intended to serve as source for number-processing +applications like OpenOffice, Ploticus and others. Tab was chosen as +delimiter because it is a) supported by both OpenOffice and Ploticus +and b) is not ',', so you can use sed -i +"s/./,/g" <x>.csv' to adapt it to locales where ',' is +used as decimal seperator. Contributed by Tobias Minich. + diff --git a/xmldoc/formats/options/an1-color.xml b/xmldoc/formats/options/an1-color.xml new file mode 100644 index 000000000..eb6e9d691 --- /dev/null +++ b/xmldoc/formats/options/an1-color.xml @@ -0,0 +1,4 @@ + This option allows you to specify the color for +line or mapnote data. It accepts color names of the form "#FF0000" (red) or any +of the color names from the Cascading Style Sheets (CSS) +specification. diff --git a/xmldoc/formats/options/an1-deficon.xml b/xmldoc/formats/options/an1-deficon.xml new file mode 100644 index 000000000..04238310d --- /dev/null +++ b/xmldoc/formats/options/an1-deficon.xml @@ -0,0 +1,7 @@ + +This option allows you to specify which symbol to use for points that +don't have a symbol already. It defaults to "Red Flag" but it accepts +any symbol name you can put in a DeLorme export file. To find the name +of a specific symbol in Street Atlas, let the mouse pointer hover over +it for a few seconds and the name will be displayed. + diff --git a/xmldoc/formats/options/an1-nogc.xml b/xmldoc/formats/options/an1-nogc.xml new file mode 100644 index 000000000..2dfa4c589 --- /dev/null +++ b/xmldoc/formats/options/an1-nogc.xml @@ -0,0 +1,8 @@ + +If your original data contains geocaching-specific information such as +difficulty and terrain, GPSBabel will automatically include that information +in the waypoint descriptions in the generated drawing file. If you do not +want that, specify the "nogc" option on the command line: + +gpsbabel -i gpx -f 12345.gpx -o an1,nogc -F 12345.an1 + diff --git a/xmldoc/formats/options/an1-nourl.xml b/xmldoc/formats/options/an1-nourl.xml new file mode 100644 index 000000000..e4504df34 --- /dev/null +++ b/xmldoc/formats/options/an1-nourl.xml @@ -0,0 +1,12 @@ + +If your original waypoint data contains URLs, GPSBabel will include them as +links in the generated drawing file. This causes the waypoint symbol to have +a blue border, and it causes the waypoint text to be drawn in blue with an +underline. + + +If you do not want this behavior, specify the "nourl" option on the command +line: + +gpsbabel -i gpx -f 12345.gpx -o an1,nourl -F 12345.an1 + diff --git a/xmldoc/formats/options/an1-radius.xml b/xmldoc/formats/options/an1-radius.xml new file mode 100644 index 000000000..f919776fd --- /dev/null +++ b/xmldoc/formats/options/an1-radius.xml @@ -0,0 +1,5 @@ + +If the waypoint type is "circle", the "radius" option specifies +the radius of the circles. By default, this is in miles, but it may be +specified in kilometers by adding a 'k'. The default radius is 1/10 mile. + diff --git a/xmldoc/formats/options/an1-road.xml b/xmldoc/formats/options/an1-road.xml new file mode 100644 index 000000000..1c32d7e71 --- /dev/null +++ b/xmldoc/formats/options/an1-road.xml @@ -0,0 +1,79 @@ + +If you are creating a road layer, you may use the "road" option, which +allows you to change the types of roads based on their names. You can +change multiple roads at the same time. Currently supported types are + + + + +Type +Meaning + + limited + Limited-access freeways + + + toll + Limited-access toll highways + + + ramp + Access ramps for limited-access highways + + + us + National highways (e.g. US routes) + + + primary + Primary State/Provincial routes + + + state + State/Provincial routes + + + major + Major Connectors + + + ferry + Ferry Routes + + + local + Local Roads + + + editable + User-drawn Roads + + + + +GPSBabel defaults to creating editable roads. These are routed just like +local roads, but may be edited with the drawing tools in Street Atlas. + + + +This option has a special format that is best demonstrated by example: + + + "road=I-599!limited!Beecher St.!major" + + +This option will cause any road named "I-599" to become a limited-access +highway and any road named "Beecher St." to become a major connector. Note +that roads that have had their types changed in this way are not editable +in Street Atlas, so make sure they are where you want them before you +change them, and make sure to keep a backup of your original road layer. +Note that the ! is a shell metacharacter in bash and possibly other shells, +so you may have to use single quotes or some other escape mechanism. + + + +There is a tutorial on +how +to create an onramp for a limited access highway in Street Atlas USA +using GPSBabel. + diff --git a/xmldoc/formats/options/an1-type.xml b/xmldoc/formats/options/an1-type.xml new file mode 100644 index 000000000..aa21357ff --- /dev/null +++ b/xmldoc/formats/options/an1-type.xml @@ -0,0 +1,7 @@ + This option specifies the type of the drawing layer +to be created. The supported values are "drawing", "road", "trail", +"waypoint", or "track". If you do not specify a type, the default +will be either the type of the previous an1 file or "drawing" if there +is no previous file. This lets you merge, for example, two road layers +without having to specify "type=road" for the output. + diff --git a/xmldoc/formats/options/an1-wpt_type.xml b/xmldoc/formats/options/an1-wpt_type.xml new file mode 100644 index 000000000..dbea684a2 --- /dev/null +++ b/xmldoc/formats/options/an1-wpt_type.xml @@ -0,0 +1,13 @@ + +This option specifies how to represent point data in the draw file. +Valid waypoint types are "symbol", "text", "mapnote", "circle", and "image". +The default is "symbol". + + +If you specify a waypoint type of "image", you should make sure that the +icon descriptions of your waypoints are the full names, including drive letters +and full path, of image files in a format that works with your DeLorme +product. Note that this means that the .an1 file you generate will not work +on any computer that does not have those images in the same place; this is +part of the design of the an1 format and cannot be avoided. + diff --git a/xmldoc/formats/options/an1-zoom.xml b/xmldoc/formats/options/an1-zoom.xml new file mode 100644 index 000000000..ddfe572b3 --- /dev/null +++ b/xmldoc/formats/options/an1-zoom.xml @@ -0,0 +1,7 @@ + +This option specifies at what zoom level Street Atlas will begin showing +reduced versions of your symbols. The default is 10. Setting zoom to 0 will +disable this feature. Setting it to anything but the default will override +the zoom level specified on any waypoints that were read from an existing +an1 file; this is by design. + diff --git a/xmldoc/formats/options/bcr-index.xml b/xmldoc/formats/options/bcr-index.xml new file mode 100644 index 000000000..2e960277d --- /dev/null +++ b/xmldoc/formats/options/bcr-index.xml @@ -0,0 +1,9 @@ + +Because the format supports only one route, this option may be used +on output to select a single route from a collection of +routes read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. + +gpsbabel -i gpx -f routes.gpx -o bcr,index=1 -F route1.bcr -o bcr,index=2 -F route2.bcr + diff --git a/xmldoc/formats/options/bcr-name.xml b/xmldoc/formats/options/bcr-name.xml new file mode 100644 index 000000000..575866e3a --- /dev/null +++ b/xmldoc/formats/options/bcr-name.xml @@ -0,0 +1,5 @@ + +This route specifies the name of the route. This is particularly useful if +the route came from an input format that did not support named routes, but +it may also be used to rename a route. + diff --git a/xmldoc/formats/options/bcr-prefer_shortnames.xml b/xmldoc/formats/options/bcr-prefer_shortnames.xml new file mode 100644 index 000000000..2674f59a5 --- /dev/null +++ b/xmldoc/formats/options/bcr-prefer_shortnames.xml @@ -0,0 +1,4 @@ + +This option causes GPSBabel to use the short name of the waypoint instead +of the description. + diff --git a/xmldoc/formats/options/bcr-radius.xml b/xmldoc/formats/options/bcr-radius.xml new file mode 100644 index 000000000..f41a98fa5 --- /dev/null +++ b/xmldoc/formats/options/bcr-radius.xml @@ -0,0 +1,9 @@ + +This option instructs GPSBabel to use a different value for the radius of +the earth when converting between the Mercator projection and geographic +coordinates. The default value is 6371000.0 meters. + + +Careful experimentation with this value may help to reduce conversion +errors. + diff --git a/xmldoc/formats/options/cetus-appendicon.xml b/xmldoc/formats/options/cetus-appendicon.xml new file mode 100644 index 000000000..9a52e4eef --- /dev/null +++ b/xmldoc/formats/options/cetus-appendicon.xml @@ -0,0 +1,7 @@ + +This option will add the icon description to the end of the waypoint +description on output. This can be useful if the icon is used to convey +important information about the waypoint. For example, the icon might be +"found geocache" or "unfound geocache"; it might be useful to know that when +looking at a list of icons in Cetus. + diff --git a/xmldoc/formats/options/cetus-dbname.xml b/xmldoc/formats/options/cetus-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/cetus-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/compegps-deficon.xml b/xmldoc/formats/options/compegps-deficon.xml new file mode 100644 index 000000000..959502d59 --- /dev/null +++ b/xmldoc/formats/options/compegps-deficon.xml @@ -0,0 +1,3 @@ + +This option specifies the default icon name on output. + diff --git a/xmldoc/formats/options/compegps-index.xml b/xmldoc/formats/options/compegps-index.xml new file mode 100644 index 000000000..b82e931dd --- /dev/null +++ b/xmldoc/formats/options/compegps-index.xml @@ -0,0 +1,8 @@ + +Because this format supports only one route or track, this option may be used +on output to select a single route or track from a collection of routes and +tracks read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. + +gpsbabel -i gpx -f routes.gpx -o compegps,index=1 -F route1.txt -o compegps,index=2 -F route2.txt diff --git a/xmldoc/formats/options/compegps-radius.xml b/xmldoc/formats/options/compegps-radius.xml new file mode 100644 index 000000000..de60e1a79 --- /dev/null +++ b/xmldoc/formats/options/compegps-radius.xml @@ -0,0 +1,3 @@ + +This option specifies the default proximity for waypoints and route points. + diff --git a/xmldoc/formats/options/compegps-snlen.xml b/xmldoc/formats/options/compegps-snlen.xml new file mode 100644 index 000000000..54248cfda --- /dev/null +++ b/xmldoc/formats/options/compegps-snlen.xml @@ -0,0 +1,4 @@ + +This option specifies the default length for short names generated on output. +The default length is 16. + diff --git a/xmldoc/formats/options/coto-zerocat.xml b/xmldoc/formats/options/coto-zerocat.xml new file mode 100644 index 000000000..a8230f5f0 --- /dev/null +++ b/xmldoc/formats/options/coto-zerocat.xml @@ -0,0 +1,4 @@ + +This option specifies a name for the "Not Assigned" category in the Palm +database. The default is "Not Assigned". + diff --git a/xmldoc/formats/options/dg-100-erase.xml b/xmldoc/formats/options/dg-100-erase.xml new file mode 100644 index 000000000..95424f0dd --- /dev/null +++ b/xmldoc/formats/options/dg-100-erase.xml @@ -0,0 +1 @@ +This option erases the track log from the device after download. diff --git a/xmldoc/formats/options/dmtlog-index.xml b/xmldoc/formats/options/dmtlog-index.xml new file mode 100644 index 000000000..69cfb72c7 --- /dev/null +++ b/xmldoc/formats/options/dmtlog-index.xml @@ -0,0 +1,16 @@ + + Convert track number 'index' from source into dmtlog format. + + + The known variants of Tracklog 'digital mapping' files supports only + one track per file. If you have more than one track in source + (f.e MapSource and many others can do such heavy things), you + can specify which track should by used for the conversion. + + + The default index is 1 (the first track of a possible list of tracks). + + + An example usage you can find at the ignrando format, + which uses option index in same manner. + diff --git a/xmldoc/formats/options/exif-filename.xml b/xmldoc/formats/options/exif-filename.xml new file mode 100644 index 000000000..58f90f2bb --- /dev/null +++ b/xmldoc/formats/options/exif-filename.xml @@ -0,0 +1,10 @@ + + With this default option waypoint names are generated from source filename. + + + + gpsbabel -i exif -f "C:\Pictures\IMG_1199.JPG",filename=Y -o gpx -F OUT.GPX + + The resulting waypoint in OUT.GPX has name IMG_1199. + + diff --git a/xmldoc/formats/options/garmin-bitscategory.xml b/xmldoc/formats/options/garmin-bitscategory.xml new file mode 100644 index 000000000..5b2c8d668 --- /dev/null +++ b/xmldoc/formats/options/garmin-bitscategory.xml @@ -0,0 +1,19 @@ + + This option is closely related to the 'category' option. While category + allows you to choose a single category that waypoints should appear in, + this options allows you to specify a bitmask to be used for the category. + Options may be specified in either decimal or hex. + + + Example for garmin bitcategory option to put all waypoints in categories 1 and 16. + + The following two commands are equivalent. They place a the point in both the first and last of the sixteen available categories. + + gpsbabel -i gpx -f PocketQuery.gpx -o garmin,bitcategory=32769 -F usb: + + + gpsbabel -i gpx -f PocketQuery.gpx -o garmin,bitcategory=0x8001 -F usb: + + + + diff --git a/xmldoc/formats/options/garmin-category.xml b/xmldoc/formats/options/garmin-category.xml new file mode 100644 index 000000000..83ed08f2c --- /dev/null +++ b/xmldoc/formats/options/garmin-category.xml @@ -0,0 +1,3 @@ +This numeric option will force waypoints to be written with that +category number when sending to a Garmin receiver that has category +support. It is ignored on receivers without that capability. diff --git a/xmldoc/formats/options/garmin-deficon.xml b/xmldoc/formats/options/garmin-deficon.xml new file mode 100644 index 000000000..26ff03d89 --- /dev/null +++ b/xmldoc/formats/options/garmin-deficon.xml @@ -0,0 +1,17 @@ + +This option specifies the icon or waypoint type to write for each waypoint on +output. + + +If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. + + +Value specified may be a number from the Garmin Protocol Spec or a name +as described in the . + + +This option has no effect on input. + + diff --git a/xmldoc/formats/options/garmin-get_posn.xml b/xmldoc/formats/options/garmin-get_posn.xml new file mode 100644 index 000000000..b7baac3b6 --- /dev/null +++ b/xmldoc/formats/options/garmin-get_posn.xml @@ -0,0 +1,5 @@ +This options gets the current longtitude and latitude from the attached GPS device +and returns it as a single waypoint for further processing. For example, +to return the current position from a USB Garmin to a KML file: + +gpsbabel -i garmin,get_posn -f usb: -o kml -F myposition.kml diff --git a/xmldoc/formats/options/garmin-power_off.xml b/xmldoc/formats/options/garmin-power_off.xml new file mode 100644 index 000000000..0c1b945fc --- /dev/null +++ b/xmldoc/formats/options/garmin-power_off.xml @@ -0,0 +1,8 @@ +This command forces an immediate powerdown of the addressed Garmin +receiver. It is ignored on hardware that does not support this command. +Obviously, further processing once you have sent a "power off" command to +a unit that supports it is rather futile, so place this option carefully +in your command. + + +gpsbabel -o garmin,power_off -F /dev/ttyS0 diff --git a/xmldoc/formats/options/garmin-resettime.xml b/xmldoc/formats/options/garmin-resettime.xml new file mode 100644 index 000000000..151a43f7a --- /dev/null +++ b/xmldoc/formats/options/garmin-resettime.xml @@ -0,0 +1,10 @@ + + This option is experimental and was added to solve a very specific problem. + Certain Garmin units (the original black and white Vista is known to have + this) will sometimes scramble their clock crazy far into the future (like + 2066). When this happens, the GPS itself may or may not work and + later conversations with GPSBabel may fail as the time overflows the + documented range. The use of brings the GPS's internal clock + back close enough to reality that the GPS itself can then "fix" it when + it has next a lock. + diff --git a/xmldoc/formats/options/garmin-snlen.xml b/xmldoc/formats/options/garmin-snlen.xml new file mode 100644 index 000000000..3aa721c67 --- /dev/null +++ b/xmldoc/formats/options/garmin-snlen.xml @@ -0,0 +1,7 @@ +This option overrides the internal logic to figure out how many +characters an addressed Garmin GPS will support when using the '-s' smartname +option. This should be necessary only if you have a receiver type that +GPSBabel doesn't know about or if you want to "dumb down" one unit to match +another, such as wanting waypoint names in a StreetPilot 2720 (which supports +20 character names) to exactly match those in a 60CS (which supports 10). + diff --git a/xmldoc/formats/options/garmin-snwhite.xml b/xmldoc/formats/options/garmin-snwhite.xml new file mode 100644 index 000000000..8a2f1987a --- /dev/null +++ b/xmldoc/formats/options/garmin-snwhite.xml @@ -0,0 +1,2 @@ +This options controls whether spaces are allowed in generated +smart names when using the '-s' option. diff --git a/xmldoc/formats/options/garmin_gpi-alerts.xml b/xmldoc/formats/options/garmin_gpi-alerts.xml new file mode 100644 index 000000000..e02e13c30 --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-alerts.xml @@ -0,0 +1,15 @@ + + Because speed isn't a real member of a normal waypoint, you can put the speed values into + the waypoint names. "Point@30" will result in a speed value of 30. By default we assume these + values are in kilometers per hour. + + + Proximity distance is also supported by GPX, Garmin GDB, OZI Explorer, + CompeGPS and Universal CSV. + + + + gpsbabel -i gpx -f "warnings.gpx" -o garmin_gpi,alerts=1 -F "warnings.gpi" + + + diff --git a/xmldoc/formats/options/garmin_gpi-bitmap.xml b/xmldoc/formats/options/garmin_gpi-bitmap.xml new file mode 100644 index 000000000..48317bb17 --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-bitmap.xml @@ -0,0 +1,13 @@ + + The bitmap (BMP) should be 24x24 (or smaller) and can be in + RGB-colors (24- and 32-bit) or 8-bit indexed color format. + + + A color value of 0xFF00FF (blue=255, green=0, red=255), + also called "Magenta", can be used for transparent areas. + + + + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,bitmap="tux.bmp" -F "My Points.gpi" + + diff --git a/xmldoc/formats/options/garmin_gpi-category.xml b/xmldoc/formats/options/garmin_gpi-category.xml new file mode 100644 index 000000000..4f8c8bfe0 --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-category.xml @@ -0,0 +1,9 @@ + + With this option you can specify the category which is primary + visible on the device (default is "My points"). + + + + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,category="Best Restaurants" -F "My Points.gpi" + + diff --git a/xmldoc/formats/options/garmin_gpi-descr.xml b/xmldoc/formats/options/garmin_gpi-descr.xml new file mode 100644 index 000000000..6bcd4e4c1 --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-descr.xml @@ -0,0 +1,10 @@ + + The GPI address field is often visible in lists on the device. Use this + option if you want to see the waypoint description (which can be an address too) + in this lists. + + + + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,descr -F "My Points.gpi" + + diff --git a/xmldoc/formats/options/garmin_gpi-hide.xml b/xmldoc/formats/options/garmin_gpi-hide.xml new file mode 100644 index 000000000..bed5ff9df --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-hide.xml @@ -0,0 +1,10 @@ + + For a large list of points (or whyever) it can be useful when + no bitmaps are displayed on device. With this option no bitmap + is stored and displayed. + + + + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,hide -F "My Points.gpi" + + diff --git a/xmldoc/formats/options/garmin_gpi-notes.xml b/xmldoc/formats/options/garmin_gpi-notes.xml new file mode 100644 index 000000000..c9d5382b6 --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-notes.xml @@ -0,0 +1,11 @@ + + The GPI address field is often visible in lists on the device. Use this + option if you want to see the waypoint notes (which can be an address too) + in this lists. + + + + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,notes -F "My Points.gpi" + + + diff --git a/xmldoc/formats/options/garmin_gpi-position.xml b/xmldoc/formats/options/garmin_gpi-position.xml new file mode 100644 index 000000000..0ce0a1006 --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-position.xml @@ -0,0 +1,9 @@ + + The GPI address field is often visible in lists on the device. Use this + option if you want to see the waypoint position (coordinates) in this lists. + + + + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,position -F "My Points.gpi" + + diff --git a/xmldoc/formats/options/garmin_gpi-proximity.xml b/xmldoc/formats/options/garmin_gpi-proximity.xml new file mode 100644 index 000000000..7b3d51917 --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-proximity.xml @@ -0,0 +1,64 @@ + + When no proximity data is available in the source input, GPSBabel uses this as the default proximity value. + The parameter has to be in meters, or, when units=s specified, in miles. + alerts are automatically enabled. + + +Read GPX file, create GPI to alert when you're 1/2 mile from a speed camera. + + + gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,units=s,proximity=0.5 -F "SpeedCameras.gpi" + + + + + Its also possible to append a specific distance unit to the parameter. + + + + gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,proximity=500m -F "SpeedCameras.gpi" + + + + + Supported distance units + + + + Unit + Description + + + + + fa + Fathoms + + + feet + Feet + + + ft + Feet + + + km + Kilometers + + + m + Meters + + + mi + Miles + + + nm + Nautical miles + + + +
                    +
                    diff --git a/xmldoc/formats/options/garmin_gpi-sleep.xml b/xmldoc/formats/options/garmin_gpi-sleep.xml new file mode 100644 index 000000000..094fb5f9e --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-sleep.xml @@ -0,0 +1,16 @@ + + The Garmin units seem to use the creation timestamp of GPI files for internal purposes. + In other words, if you load GPI files with same creation timestamp on your device, + strange things will happen, such as having missing or repeated POIs. With the sleep option, GPSBabel waits a given + number of seconds after the GPI file was written. + + + In the normal case of using GPSBabel from the command line or from the GUI, the chance of creating files + with the same timestamp is in the nearly ZERO. In scripts or batch files where you are writing multiple files - even from different GPSBabel instances - the odds of this happening is rather good. + The sleep option forces GPSBabel to wait after creating a file to ensure the timestamps are unique. Values are specified in seconds and can be 1 or more. + + + + gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,sleep=1 -F "SpeedCameras.gpi" + + diff --git a/xmldoc/formats/options/garmin_gpi-speed.xml b/xmldoc/formats/options/garmin_gpi-speed.xml new file mode 100644 index 000000000..61ca35681 --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-speed.xml @@ -0,0 +1,66 @@ + + When no speed data is available in the source input, GPSBabel uses this as the default speed value. + The parameter has to be in kilometers per hour, or, when units=s specified, + in miles per hour. alerts are + automatically enabled. + + + + gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,units=s,speed=30 -F "SpeedCameras.gpi" + + + + Its also possible to append a specific speed unit to the parameter. + + + + gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,speed=30mph -F "SpeedCameras.gpi" + + + + + Supported speed units + + + + Unit + Description + + + + + km/h + Kilometers per hour + + + kmh + Kilometers per hour + + + kph + Kilometers per hour + + + kt + Knots + + + knot + Knots + + + m/s + Meters per second + + + mps + Meters per second + + + mi/h + Miles per hour + + + +
                    +
                    diff --git a/xmldoc/formats/options/garmin_gpi-unique.xml b/xmldoc/formats/options/garmin_gpi-unique.xml new file mode 100644 index 000000000..3985fa9c2 --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-unique.xml @@ -0,0 +1,9 @@ + + Don't create unique names sample: + + + + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,unique=0 -F "My Points.gpi" + + + diff --git a/xmldoc/formats/options/garmin_gpi-units.xml b/xmldoc/formats/options/garmin_gpi-units.xml new file mode 100644 index 000000000..fc344b750 --- /dev/null +++ b/xmldoc/formats/options/garmin_gpi-units.xml @@ -0,0 +1,7 @@ + + Sample command tells GPSBabel to handle speed values in miles per hour: + + gpsbabel -i gpx -f "My Points.gpx" -o garmin_gpi,units=s -F "My Points.gpi" + + + diff --git a/xmldoc/formats/options/garmin_txt-date.xml b/xmldoc/formats/options/garmin_txt-date.xml new file mode 100644 index 000000000..2f1a3ee59 --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-date.xml @@ -0,0 +1,4 @@ + +This option specifies the input and output format for the date. The format +is written similarly to those in Windows. An example format is "YYYY/MM/DD". + diff --git a/xmldoc/formats/options/garmin_txt-datum.xml b/xmldoc/formats/options/garmin_txt-datum.xml new file mode 100644 index 000000000..ce1cadb23 --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-datum.xml @@ -0,0 +1,4 @@ + +This option specifies the datum to be used on output. Valid values for this +option are listed in . + diff --git a/xmldoc/formats/options/garmin_txt-dist.xml b/xmldoc/formats/options/garmin_txt-dist.xml new file mode 100644 index 000000000..f3a48251e --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-dist.xml @@ -0,0 +1,5 @@ + +This option specifies the unit to be used when outputting distance +values. Valid values are M for metric (m/km/kph) or S for statute +(ft/mi/mph). + diff --git a/xmldoc/formats/options/garmin_txt-grid.xml b/xmldoc/formats/options/garmin_txt-grid.xml new file mode 100644 index 000000000..4db42f886 --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-grid.xml @@ -0,0 +1,62 @@ + + This value specifies the grid to be used on write. + + +Grid values for garmin_txt + + + + # idx + short + file-header + sample + + + + + 0 + ddd + Lat/Lon hddd.ddddd + S26.25333 E27.92333 + + + 1 + dmm + Lat/Lon hddd°mm.mm + N33 56.539 W118 24.471 + + + 2 + dms + Lat/Lon hddd°mm'ss.s + S25 25 26.8 E28 06 07.3 + + + 3 + bng + British National Grid + TQ 18919 69392 + + + 4 + utm + Universal Transverse Mercator + 33 U 318293 5637154 + + + 5 + swiss + Swiss grid + 776519 167359 + + + +
                    + + + + + Idx or short are valid params for this option. + + + diff --git a/xmldoc/formats/options/garmin_txt-prec.xml b/xmldoc/formats/options/garmin_txt-prec.xml new file mode 100644 index 000000000..962de067f --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-prec.xml @@ -0,0 +1,5 @@ + +This option specifies the precision to be used when writing coordinate values. +Precision is the number of digits after the decimal point. The default +precision is 3. + diff --git a/xmldoc/formats/options/garmin_txt-temp.xml b/xmldoc/formats/options/garmin_txt-temp.xml new file mode 100644 index 000000000..f1de8e27a --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-temp.xml @@ -0,0 +1,4 @@ + +This option specifies the unit to be used when writing temperature values. +Valid values are C for Celsius or F for Fahrenheit. + diff --git a/xmldoc/formats/options/garmin_txt-time.xml b/xmldoc/formats/options/garmin_txt-time.xml new file mode 100644 index 000000000..145c9a4e3 --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-time.xml @@ -0,0 +1,4 @@ + +This option specifies the input and output format for the time. The format +is written similarly to those in Windows. An example format is "hh:mm:ss xx". + diff --git a/xmldoc/formats/options/garmin_txt-utc.xml b/xmldoc/formats/options/garmin_txt-utc.xml new file mode 100644 index 000000000..4c2964e0e --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-utc.xml @@ -0,0 +1,5 @@ + +This option specifies the local time zone to use when writing times. It +is specified as an offset from Universal Coordinated Time (UTC) in hours. +Valid values are from -23 to +23. + diff --git a/xmldoc/formats/options/gdb-bitscategory.xml b/xmldoc/formats/options/gdb-bitscategory.xml new file mode 100644 index 000000000..32f3815db --- /dev/null +++ b/xmldoc/formats/options/gdb-bitscategory.xml @@ -0,0 +1,19 @@ + + This option is closely related to the 'category' option. While category + allows you to choose a single category that waypoints should appear in, + this options allows you to specify a bitmask to be used for the category. + Options may be specified in either decimal or hex. + + + Example for gdb bitcategory option to put all waypoints in categories 1 and 16. + + The following two commands are equivalent. They place a the point in both the first and last of the sixteen available categories. + + gpsbabel -i gpx -f PocketQuery.gpx -o gdb,bitscategory=32769 -F foo.gdb + + + gpsbabel -i gpx -f PocketQuery.gpx -o gdb,bitscategory=0x8001 -F foo.gdb + + + + diff --git a/xmldoc/formats/options/gdb-cat.xml b/xmldoc/formats/options/gdb-cat.xml new file mode 100644 index 000000000..6b876e911 --- /dev/null +++ b/xmldoc/formats/options/gdb-cat.xml @@ -0,0 +1,4 @@ + +This option specifies the default category for gdb output. It should be a +number from 1 to 16. + diff --git a/xmldoc/formats/options/gdb-roadbook.xml b/xmldoc/formats/options/gdb-roadbook.xml new file mode 100644 index 000000000..296d7b03f --- /dev/null +++ b/xmldoc/formats/options/gdb-roadbook.xml @@ -0,0 +1,19 @@ + + If this option is specified, GPSBabel drops all calculated route points, + with exception of points with a description (i.e. "Make U-turns until you know where you are."). + The priority of this option is higher than of the option. + A value of 1 or y overwrites the settings. + + + Using gdb option <option>roadbook</option> to create simple html roadbook + + + gpsbabel -i gdb,roadbook -f sample.gdb -x nuketypes,waypoints,tracks -x transform,wpt=rte -o html -F roadbook.html + + + + Because gdb internally creates a route AND a waypoint list, you have to drop all + waypoints and transform the route into waypoints in order to get a well ordered + html output. We suggest these steps for all waypoint-only formats as html. + + diff --git a/xmldoc/formats/options/gdb-ver.xml b/xmldoc/formats/options/gdb-ver.xml new file mode 100644 index 000000000..6b736592e --- /dev/null +++ b/xmldoc/formats/options/gdb-ver.xml @@ -0,0 +1,5 @@ + +This option specifies the data format version for the output file. Version +2 is the default. Currently, the only other valid values for this option are +1 and 3. + diff --git a/xmldoc/formats/options/gdb-via.xml b/xmldoc/formats/options/gdb-via.xml new file mode 100644 index 000000000..0df42530c --- /dev/null +++ b/xmldoc/formats/options/gdb-via.xml @@ -0,0 +1,5 @@ + +This option instructs GPSBabel to drop hidden (calculated) points from +routes. + + diff --git a/xmldoc/formats/options/geo-deficon.xml b/xmldoc/formats/options/geo-deficon.xml new file mode 100644 index 000000000..96d6f27c9 --- /dev/null +++ b/xmldoc/formats/options/geo-deficon.xml @@ -0,0 +1,17 @@ + +This option specifies the icon or waypoint type to write for each waypoint on +output. + + +If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. + + +There is no list of valid values for this option. + + +This option has no effect on input. + + + diff --git a/xmldoc/formats/options/geo-nuke_placer.xml b/xmldoc/formats/options/geo-nuke_placer.xml new file mode 100644 index 000000000..50d5a92da --- /dev/null +++ b/xmldoc/formats/options/geo-nuke_placer.xml @@ -0,0 +1,9 @@ + +If this option is specified, GPSBabel will not read geocache placer information +from a .loc file on input. That is, it will ignore any placeer names in the +input file. + + +This option has no effect on output. + + diff --git a/xmldoc/formats/options/geoniche-category.xml b/xmldoc/formats/options/geoniche-category.xml new file mode 100644 index 000000000..7060b96b0 --- /dev/null +++ b/xmldoc/formats/options/geoniche-category.xml @@ -0,0 +1,6 @@ + +This option specifies the name of the category in which to place the +waypoints. If this option is not specified, the default category is +"Cache". + + diff --git a/xmldoc/formats/options/geoniche-dbname.xml b/xmldoc/formats/options/geoniche-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/geoniche-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/gpilots-dbname.xml b/xmldoc/formats/options/gpilots-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/gpilots-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/gpspilot-dbname.xml b/xmldoc/formats/options/gpspilot-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/gpspilot-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/gpssim-split.xml b/xmldoc/formats/options/gpssim-split.xml new file mode 100644 index 000000000..51dad87f7 --- /dev/null +++ b/xmldoc/formats/options/gpssim-split.xml @@ -0,0 +1,17 @@ +When this option is specified, GPSBabel will split + split the output into multiple files using the output filename + as a base. For example, if you specify an output file of 'mytrip', + + mytrip-waypoints.gpssim - will contain the waypoints. + mytrip-track0000.gpssim - will contain the first track. + mytrip-track0001.gpssim - will contain the second track. + ... and so on. + mytrip-route0000.gpssim - will contain the first route. + mytrip-route0001.gpssim - will contain the seconds route. + ... and so on. + + + + +Valid values for this option are 0 (off) and 1 (on). The default is '0'. + diff --git a/xmldoc/formats/options/gpssim-wayptspd.xml b/xmldoc/formats/options/gpssim-wayptspd.xml new file mode 100644 index 000000000..ca23812dc --- /dev/null +++ b/xmldoc/formats/options/gpssim-wayptspd.xml @@ -0,0 +1,3 @@ + + This option specifies the speed of the simulation in knots. + diff --git a/xmldoc/formats/options/gpx-gpxver.xml b/xmldoc/formats/options/gpx-gpxver.xml new file mode 100644 index 000000000..8e2ccc3ad --- /dev/null +++ b/xmldoc/formats/options/gpx-gpxver.xml @@ -0,0 +1,11 @@ + +This option specifies the version of the GPX specification to use for +output. The default version is 1.0. The only other valid value for this +option is 1.1. + + +Notice that this is not a full scale XML schema conversion. In particular, +if you have a GPX 1.0 file that has extended namespaces in it (such as a +pocket query from Geocaching.com) just writing it with this option will +result in a horribly mangled GPX file as we can't convert the schema data. + diff --git a/xmldoc/formats/options/gpx-logpoint.xml b/xmldoc/formats/options/gpx-logpoint.xml new file mode 100644 index 000000000..2739b4889 --- /dev/null +++ b/xmldoc/formats/options/gpx-logpoint.xml @@ -0,0 +1,6 @@ + + When reading Groundspeak Pocket Queries , the option creates additional waypoints from the log entries. + + + A typical use for this is to get coordinates read from "corrected coordinates" logs. + diff --git a/xmldoc/formats/options/gpx-snlen.xml b/xmldoc/formats/options/gpx-snlen.xml new file mode 100644 index 000000000..999bb2589 --- /dev/null +++ b/xmldoc/formats/options/gpx-snlen.xml @@ -0,0 +1,3 @@ + + When used with the to control shortnames, the snlen suboption to GPX controls how long the generated smartname will be. This can be useful for cases like writing GPX files to a GPS that has a fixed waypoint name length. + diff --git a/xmldoc/formats/options/gpx-suppresswhite.xml b/xmldoc/formats/options/gpx-suppresswhite.xml new file mode 100644 index 000000000..e5fc04063 --- /dev/null +++ b/xmldoc/formats/options/gpx-suppresswhite.xml @@ -0,0 +1,3 @@ + +When used with the to generate smart shortnames, this suboption controls whether whitespace is allowed in the generated shortnames. + diff --git a/xmldoc/formats/options/gpx-urlbase.xml b/xmldoc/formats/options/gpx-urlbase.xml new file mode 100644 index 000000000..fefa663cf --- /dev/null +++ b/xmldoc/formats/options/gpx-urlbase.xml @@ -0,0 +1,4 @@ + + This is a fairly esoteric option. If the GPX file you are reading has only base pathnames (e.g "foo.html") the value you specify to this argument will be prepended to that. For example, "-o gpx,urlbase=c:\My Documents\Whatever" would result in the link to that waypoint being written to refer to c:\My Document\WHatever\foo.html + + diff --git a/xmldoc/formats/options/html-altunits.xml b/xmldoc/formats/options/html-altunits.xml new file mode 100644 index 000000000..586dee672 --- /dev/null +++ b/xmldoc/formats/options/html-altunits.xml @@ -0,0 +1,4 @@ + +This option should be 'f' if you want the altitude expressed in feet and +'m' for meters. The default is 'f'. + diff --git a/xmldoc/formats/options/html-degformat.xml b/xmldoc/formats/options/html-degformat.xml new file mode 100644 index 000000000..25d45942b --- /dev/null +++ b/xmldoc/formats/options/html-degformat.xml @@ -0,0 +1,5 @@ + +When GPSBabel writes coordinates, this option is consulted to see if it +should write decimal degrees ('ddd') decimal minutes ('dmm') or degrees, +minutes, seconds ('dms'). The default is 'dmm'. + diff --git a/xmldoc/formats/options/html-encrypt.xml b/xmldoc/formats/options/html-encrypt.xml new file mode 100644 index 000000000..2d7d96091 --- /dev/null +++ b/xmldoc/formats/options/html-encrypt.xml @@ -0,0 +1,3 @@ + +Use this option to encrypt hints from Groundspeak GPX files. + diff --git a/xmldoc/formats/options/html-logs.xml b/xmldoc/formats/options/html-logs.xml new file mode 100644 index 000000000..9e25a13ea --- /dev/null +++ b/xmldoc/formats/options/html-logs.xml @@ -0,0 +1,3 @@ + +Use this option to include Groundspeak cache logs in the created document. + diff --git a/xmldoc/formats/options/html-stylesheet.xml b/xmldoc/formats/options/html-stylesheet.xml new file mode 100644 index 000000000..82f38d356 --- /dev/null +++ b/xmldoc/formats/options/html-stylesheet.xml @@ -0,0 +1,4 @@ + +Use this option to specify a CSS style sheet to be used with the +resulting HTML file. + diff --git a/xmldoc/formats/options/igc-timeadj.xml b/xmldoc/formats/options/igc-timeadj.xml new file mode 100644 index 000000000..eb345d9b8 --- /dev/null +++ b/xmldoc/formats/options/igc-timeadj.xml @@ -0,0 +1,16 @@ + +Sometimes there is a discrepancy between the internal clock in the barograph +instrument and GPS time which can result in the altitude and ground positions +not correlating correctly. This can be corrected manually by passing the time +difference in seconds between the two time domains through the "timeadj" +parameter. This can be any positive or negative integer: + +gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=27 -F my3D.igc + +GPSBabel can also attempt to deduce the time difference automatically. This +is done by comparing the time that it thinks that you landed on the GPS track +and the barograph and adjusting accordingly: + +gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc + + diff --git a/xmldoc/formats/options/ignrando-index.xml b/xmldoc/formats/options/ignrando-index.xml new file mode 100644 index 000000000..f61f0e790 --- /dev/null +++ b/xmldoc/formats/options/ignrando-index.xml @@ -0,0 +1,9 @@ + +Because the format supports only one track, this option may be used +on output to select a single track from a collection of +tracks read from a more expressive format. If you have, say, a +gpx file that contains two tracks, you may +use this option to write them one at a time to individual files. + +gpsbabel -i gpx -f tracks.gpx -o ignrando,index=1 -F track1.txt -o ignrando,index=2 -F track2.txt + diff --git a/xmldoc/formats/options/kml-deficon.xml b/xmldoc/formats/options/kml-deficon.xml new file mode 100644 index 000000000..5f94e2595 --- /dev/null +++ b/xmldoc/formats/options/kml-deficon.xml @@ -0,0 +1,3 @@ + +This option specifies the default name for waypoint icons + diff --git a/xmldoc/formats/options/kml-extrude.xml b/xmldoc/formats/options/kml-extrude.xml new file mode 100644 index 000000000..2cb3a4027 --- /dev/null +++ b/xmldoc/formats/options/kml-extrude.xml @@ -0,0 +1,7 @@ + +This option is a boolean flag to specicy whether Google Earth should +draw lines from trackpoints to the ground. It defaults to '0', which +means no extrusion lines are drawn. The option of '1' is, of course, +most useful for points that aren't actually on the ground such as those +be captured from planes. + diff --git a/xmldoc/formats/options/kml-floating.xml b/xmldoc/formats/options/kml-floating.xml new file mode 100644 index 000000000..6a26606d0 --- /dev/null +++ b/xmldoc/formats/options/kml-floating.xml @@ -0,0 +1,9 @@ + +When this option is nonzero, altitudes are allowed to float above or below +the ground surface. By default, this option is zero so that altitudes are +clamped to the ground. Specify to allow them to +float. + + +This option is more useful to pilots than to hikers. + diff --git a/xmldoc/formats/options/kml-labels.xml b/xmldoc/formats/options/kml-labels.xml new file mode 100644 index 000000000..1caf013b7 --- /dev/null +++ b/xmldoc/formats/options/kml-labels.xml @@ -0,0 +1,4 @@ + +When this option is zero, no labels are added for track and route points. +This option defaults to one, so labels are added by default. + diff --git a/xmldoc/formats/options/kml-line_color.xml b/xmldoc/formats/options/kml-line_color.xml new file mode 100644 index 000000000..33892c4c7 --- /dev/null +++ b/xmldoc/formats/options/kml-line_color.xml @@ -0,0 +1,5 @@ + +This option specifies the line color as a hexadecimal number in +AABBGGRR format, where A is alpha, B is blue, G is green, and R is red. + + diff --git a/xmldoc/formats/options/kml-line_width.xml b/xmldoc/formats/options/kml-line_width.xml new file mode 100644 index 000000000..0dfb9b040 --- /dev/null +++ b/xmldoc/formats/options/kml-line_width.xml @@ -0,0 +1,4 @@ + +This option specifies the width of the drawn lines in pixels. The default +value is six pixels. + diff --git a/xmldoc/formats/options/kml-lines.xml b/xmldoc/formats/options/kml-lines.xml new file mode 100644 index 000000000..fbe2dafaa --- /dev/null +++ b/xmldoc/formats/options/kml-lines.xml @@ -0,0 +1,6 @@ + +When this option is nonzero, GPSBabel draws lines between points in +tracks and routes. The default value for this option is 1, which causes +lines to be drawn by default. To disable line-drawing, specify +. + diff --git a/xmldoc/formats/options/kml-max_position_points.xml b/xmldoc/formats/options/kml-max_position_points.xml new file mode 100644 index 000000000..6698c2dd2 --- /dev/null +++ b/xmldoc/formats/options/kml-max_position_points.xml @@ -0,0 +1,4 @@ + + This option allows you to specify the number of points kept + in the 'snail trail' generated in the realtime tracking mode. + diff --git a/xmldoc/formats/options/kml-points.xml b/xmldoc/formats/options/kml-points.xml new file mode 100644 index 000000000..3f8241d46 --- /dev/null +++ b/xmldoc/formats/options/kml-points.xml @@ -0,0 +1,6 @@ + +When this option is nonzero, GPSBabel draws placemarks for tracks and routes. +The default value for this option is 1, which causes placemarks to be drawn. +To disable drawing of placemarks, specify . + + diff --git a/xmldoc/formats/options/kml-trackdata.xml b/xmldoc/formats/options/kml-trackdata.xml new file mode 100644 index 000000000..a27154033 --- /dev/null +++ b/xmldoc/formats/options/kml-trackdata.xml @@ -0,0 +1,8 @@ + +This is a boolean flag that controls +whether GPSBabel writes extensive data for each trackpoint generated. +By default computed speed, timestamps, and so on are written with the default +of '1' for this option. If you are writing large tracks and do not value +this information, you can reduce the size of the generated file substantially +by turning this flag off by setting it to '0'. + diff --git a/xmldoc/formats/options/kml-trackdirection.xml b/xmldoc/formats/options/kml-trackdirection.xml new file mode 100644 index 000000000..6449dd03d --- /dev/null +++ b/xmldoc/formats/options/kml-trackdirection.xml @@ -0,0 +1,4 @@ + + If set, this options creates directional icons for trackpoints. Arrows + will show the direction of travel on drawn tracks and routes. + diff --git a/xmldoc/formats/options/kml-units.xml b/xmldoc/formats/options/kml-units.xml new file mode 100644 index 000000000..7d2db21f5 --- /dev/null +++ b/xmldoc/formats/options/kml-units.xml @@ -0,0 +1,5 @@ + +Units is a simple option. Specify 's' for "statute" (miles, feet, and +other things that don't sensibly convert to each other, but are craved +by Americans) or 'm' for "metric". + diff --git a/xmldoc/formats/options/lowranceusr-break.xml b/xmldoc/formats/options/lowranceusr-break.xml new file mode 100644 index 000000000..ce686ac47 --- /dev/null +++ b/xmldoc/formats/options/lowranceusr-break.xml @@ -0,0 +1,4 @@ + +(USR input) Break track segments into separate tracks. +file. + diff --git a/xmldoc/formats/options/lowranceusr-ignoreicons.xml b/xmldoc/formats/options/lowranceusr-ignoreicons.xml new file mode 100644 index 000000000..8f5c37374 --- /dev/null +++ b/xmldoc/formats/options/lowranceusr-ignoreicons.xml @@ -0,0 +1,4 @@ + +This option instructs GPSBabel to not convert icons to waypoints on input, +but to instead disregard them altogether + diff --git a/xmldoc/formats/options/lowranceusr-merge.xml b/xmldoc/formats/options/lowranceusr-merge.xml new file mode 100644 index 000000000..e1ea03bb5 --- /dev/null +++ b/xmldoc/formats/options/lowranceusr-merge.xml @@ -0,0 +1,3 @@ + +(USR output) This option merges all tracks into a single track with multiple segments. + diff --git a/xmldoc/formats/options/lowranceusr-writeasicons.xml b/xmldoc/formats/options/lowranceusr-writeasicons.xml new file mode 100644 index 000000000..aaf2aec90 --- /dev/null +++ b/xmldoc/formats/options/lowranceusr-writeasicons.xml @@ -0,0 +1,3 @@ + +(USR output) This option converts the waypoint information to an event marker icon. + diff --git a/xmldoc/formats/options/magellan-deficon.xml b/xmldoc/formats/options/magellan-deficon.xml new file mode 100644 index 000000000..5e05476af --- /dev/null +++ b/xmldoc/formats/options/magellan-deficon.xml @@ -0,0 +1,3 @@ + + The deficon option is used to control the icon output when writing to this format. It overrides any icon informatino that might be present in the source data. + diff --git a/xmldoc/formats/options/magellan-maxcmts.xml b/xmldoc/formats/options/magellan-maxcmts.xml new file mode 100644 index 000000000..1c46dd108 --- /dev/null +++ b/xmldoc/formats/options/magellan-maxcmts.xml @@ -0,0 +1,13 @@ + +The maxcmts option allows you to specify the number comments that will +be sent to the unit. + + +Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. + diff --git a/xmldoc/formats/options/magellan1-baud.xml b/xmldoc/formats/options/magellan1-baud.xml new file mode 100644 index 000000000..0682faa0a --- /dev/null +++ b/xmldoc/formats/options/magellan1-baud.xml @@ -0,0 +1,8 @@ + + This option causes GPSBabel to use the given baud rate for serial + communications. It must match the given baud rate on the receiver. The + default value matches the default on the receiver, 4800. + + + Valid options are 1200, 2400, 4800, 9600, 19200, 57600, and 115200. + diff --git a/xmldoc/formats/options/magellan1-deficon.xml b/xmldoc/formats/options/magellan1-deficon.xml new file mode 100644 index 000000000..f1d272b05 --- /dev/null +++ b/xmldoc/formats/options/magellan1-deficon.xml @@ -0,0 +1,15 @@ + +This option specifies the icon or waypoint type to write for each waypoint on +output. + + +If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. + + + +This option has no effect on input. + diff --git a/xmldoc/formats/options/magellan1-maxcmts.xml b/xmldoc/formats/options/magellan1-maxcmts.xml new file mode 100644 index 000000000..1c46dd108 --- /dev/null +++ b/xmldoc/formats/options/magellan1-maxcmts.xml @@ -0,0 +1,13 @@ + +The maxcmts option allows you to specify the number comments that will +be sent to the unit. + + +Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. + diff --git a/xmldoc/formats/options/magellan1-noack.xml b/xmldoc/formats/options/magellan1-noack.xml new file mode 100644 index 000000000..f8d84cab2 --- /dev/null +++ b/xmldoc/formats/options/magellan1-noack.xml @@ -0,0 +1,17 @@ + +Magellan's protocol specification strongly encourages the use of software +acknowledgements on every packets. This is a simple "this is what I think +I heard. If you agree that I heard it correctly, let's go to the next packet" +handshake that is used to ensure the integrity of the data transfer. + + +Certain firmware versions have problems handling this which makes transfers +unnecessarily slow. Transfers on all units at high serial speeds are also +severely restricted by this process. + + +In controlled environments (good cables, low electrical noise, receiving +from the unit, not doing donuts with the unit set to "track up" at a 150 +mile scale with 500 waypoints on the screen) it is sometimes useful to +release that safety belt by using the "noack" suboption. + diff --git a/xmldoc/formats/options/magellan1-nukewpt.xml b/xmldoc/formats/options/magellan1-nukewpt.xml new file mode 100644 index 000000000..5ca891611 --- /dev/null +++ b/xmldoc/formats/options/magellan1-nukewpt.xml @@ -0,0 +1,10 @@ + +This option erases all waypoints in the receiver before doing a transfer. + + +This is a convenient option to use in automated processes where you want +to ensure the units starts with a clean state before sending waypoints to +it. Using this option on transmit is a better idea than doing it on +receive since the latter would erase all the waypoints before asking the +unit to send all the waypoints. + diff --git a/xmldoc/formats/options/magellanx-deficon.xml b/xmldoc/formats/options/magellanx-deficon.xml new file mode 100644 index 000000000..5e05476af --- /dev/null +++ b/xmldoc/formats/options/magellanx-deficon.xml @@ -0,0 +1,3 @@ + + The deficon option is used to control the icon output when writing to this format. It overrides any icon informatino that might be present in the source data. + diff --git a/xmldoc/formats/options/magellanx-maxcmts.xml b/xmldoc/formats/options/magellanx-maxcmts.xml new file mode 100644 index 000000000..1c46dd108 --- /dev/null +++ b/xmldoc/formats/options/magellanx-maxcmts.xml @@ -0,0 +1,13 @@ + +The maxcmts option allows you to specify the number comments that will +be sent to the unit. + + +Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. + diff --git a/xmldoc/formats/options/mapsend-trkver.xml b/xmldoc/formats/options/mapsend-trkver.xml new file mode 100644 index 000000000..5e5421081 --- /dev/null +++ b/xmldoc/formats/options/mapsend-trkver.xml @@ -0,0 +1,6 @@ + +This option sets the MapSend version to generate TRK files, +since new MapSend versions can't open version 3 files. +Valid values are 3 (MapSend v3.0) or 4 (MapSend v4.0 and v4.1). + + diff --git a/xmldoc/formats/options/mapsource-mpsmergeout.xml b/xmldoc/formats/options/mapsource-mpsmergeout.xml new file mode 100644 index 000000000..8b06e42d2 --- /dev/null +++ b/xmldoc/formats/options/mapsource-mpsmergeout.xml @@ -0,0 +1,5 @@ + +This option causes the output to be merged with a pre-existing output file. +This allows MapSource sections that aren't handled by GPSBabel (e.g. map sets) +to be preserved. + diff --git a/xmldoc/formats/options/mapsource-mpsusedepth.xml b/xmldoc/formats/options/mapsource-mpsusedepth.xml new file mode 100644 index 000000000..08b6dfd34 --- /dev/null +++ b/xmldoc/formats/options/mapsource-mpsusedepth.xml @@ -0,0 +1,5 @@ + +This option causes GPSBabel to write depth values for waypoints. Most +input formats do not support depth values, so the default is to not write +them. + diff --git a/xmldoc/formats/options/mapsource-mpsuseprox.xml b/xmldoc/formats/options/mapsource-mpsuseprox.xml new file mode 100644 index 000000000..c09a64b5f --- /dev/null +++ b/xmldoc/formats/options/mapsource-mpsuseprox.xml @@ -0,0 +1,5 @@ + +This option causes GPSBabel to write proximity values for waypoints. Most +input formats do not support proximity values, so the default is to not write +them. + diff --git a/xmldoc/formats/options/mapsource-mpsverout.xml b/xmldoc/formats/options/mapsource-mpsverout.xml new file mode 100644 index 000000000..6aa3d7bbd --- /dev/null +++ b/xmldoc/formats/options/mapsource-mpsverout.xml @@ -0,0 +1,5 @@ + +This option specifies the format version for the output file. The default +is version 5, as noted above. Supported versions are 3, 4, and 5. + + diff --git a/xmldoc/formats/options/mapsource-snlen.xml b/xmldoc/formats/options/mapsource-snlen.xml new file mode 100644 index 000000000..40e494453 --- /dev/null +++ b/xmldoc/formats/options/mapsource-snlen.xml @@ -0,0 +1,4 @@ + +This option specifies the length of generated short names on output. The +default is 10 characters. + diff --git a/xmldoc/formats/options/mapsource-snwhite.xml b/xmldoc/formats/options/mapsource-snwhite.xml new file mode 100644 index 000000000..0655b1894 --- /dev/null +++ b/xmldoc/formats/options/mapsource-snwhite.xml @@ -0,0 +1,4 @@ + +This option specifies whether to allow whitespace (space, tab, etc.) in +generated short names on output. The default is to not allow whitespace. + diff --git a/xmldoc/formats/options/mtk-bin-csv.xml b/xmldoc/formats/options/mtk-bin-csv.xml new file mode 100644 index 000000000..5426f27f5 --- /dev/null +++ b/xmldoc/formats/options/mtk-bin-csv.xml @@ -0,0 +1,8 @@ + + Specifies a filename into which MTK-compatible CSV output will be written. + + + Note that this option is a bit of an oddity in the GPSBabel arsenal. This + should probably be a "real" output type of its own instead of being bolted + onto an input type. + diff --git a/xmldoc/formats/options/mtk-csv.xml b/xmldoc/formats/options/mtk-csv.xml new file mode 100644 index 000000000..eed4a2ffa --- /dev/null +++ b/xmldoc/formats/options/mtk-csv.xml @@ -0,0 +1,2 @@ +This option will create an additional CSV output file. +The CSV file is compatible with the original MTK logger application. diff --git a/xmldoc/formats/options/mtk-erase.xml b/xmldoc/formats/options/mtk-erase.xml new file mode 100644 index 000000000..95424f0dd --- /dev/null +++ b/xmldoc/formats/options/mtk-erase.xml @@ -0,0 +1 @@ +This option erases the track log from the device after download. diff --git a/xmldoc/formats/options/navicache-noretired.xml b/xmldoc/formats/options/navicache-noretired.xml new file mode 100644 index 000000000..e93b2e21c --- /dev/null +++ b/xmldoc/formats/options/navicache-noretired.xml @@ -0,0 +1,3 @@ + + If this option is present, retired (archived) caches will be suppressed on write. + diff --git a/xmldoc/formats/options/navilink-nukerte.xml b/xmldoc/formats/options/navilink-nukerte.xml new file mode 100644 index 000000000..2a3bfed47 --- /dev/null +++ b/xmldoc/formats/options/navilink-nukerte.xml @@ -0,0 +1,10 @@ + +This option erases all routes in the receiver before doing a transfer. + + +This is a convenient option to use in automated processes where you want +to ensure the units starts with a clean state before sending routes to +it. Using this option on transmit is a better idea than doing it on +receive since the latter would erase all the waypoints before asking the +unit to send all the waypoints. + diff --git a/xmldoc/formats/options/navilink-nuketrk.xml b/xmldoc/formats/options/navilink-nuketrk.xml new file mode 100644 index 000000000..e9a5f4b9c --- /dev/null +++ b/xmldoc/formats/options/navilink-nuketrk.xml @@ -0,0 +1,10 @@ + +This option erases all track data in the receiver before doing a transfer. + + +This is a convenient option to use in automated processes where you want +to ensure the units starts with a clean state before sending track data to +it. Using this option on transmit is a better idea than doing it on +receive since the latter would erase all the waypoints before asking the +unit to send all the waypoints. + diff --git a/xmldoc/formats/options/navilink-nukewpt.xml b/xmldoc/formats/options/navilink-nukewpt.xml new file mode 100644 index 000000000..5ca891611 --- /dev/null +++ b/xmldoc/formats/options/navilink-nukewpt.xml @@ -0,0 +1,10 @@ + +This option erases all waypoints in the receiver before doing a transfer. + + +This is a convenient option to use in automated processes where you want +to ensure the units starts with a clean state before sending waypoints to +it. Using this option on transmit is a better idea than doing it on +receive since the latter would erase all the waypoints before asking the +unit to send all the waypoints. + diff --git a/xmldoc/formats/options/navilink-power_off.xml b/xmldoc/formats/options/navilink-power_off.xml new file mode 100644 index 000000000..b679373df --- /dev/null +++ b/xmldoc/formats/options/navilink-power_off.xml @@ -0,0 +1,4 @@ + +This options powers down the Navilink receiver once any transfers are +complete. + diff --git a/xmldoc/formats/options/netstumbler-nseicon.xml b/xmldoc/formats/options/netstumbler-nseicon.xml new file mode 100644 index 000000000..4a6d622e8 --- /dev/null +++ b/xmldoc/formats/options/netstumbler-nseicon.xml @@ -0,0 +1,4 @@ + +This option specifies the name of the icon to use for +non-stealth, encrypted access points. + diff --git a/xmldoc/formats/options/netstumbler-nsneicon.xml b/xmldoc/formats/options/netstumbler-nsneicon.xml new file mode 100644 index 000000000..bf0f7cc35 --- /dev/null +++ b/xmldoc/formats/options/netstumbler-nsneicon.xml @@ -0,0 +1,4 @@ + +This option specifies the name of the icon to use for +non-stealth, non-encrypted access points. + diff --git a/xmldoc/formats/options/netstumbler-seicon.xml b/xmldoc/formats/options/netstumbler-seicon.xml new file mode 100644 index 000000000..3f0accbdc --- /dev/null +++ b/xmldoc/formats/options/netstumbler-seicon.xml @@ -0,0 +1,4 @@ + +This option specifies the name of the icon to use for +stealth, encrypted access points. + diff --git a/xmldoc/formats/options/netstumbler-sneicon.xml b/xmldoc/formats/options/netstumbler-sneicon.xml new file mode 100644 index 000000000..174ad2b32 --- /dev/null +++ b/xmldoc/formats/options/netstumbler-sneicon.xml @@ -0,0 +1,4 @@ + +This option specifies the name of the icon to use for +stealth, non-encrypted access points. + diff --git a/xmldoc/formats/options/netstumbler-snmac.xml b/xmldoc/formats/options/netstumbler-snmac.xml new file mode 100644 index 000000000..db2a39481 --- /dev/null +++ b/xmldoc/formats/options/netstumbler-snmac.xml @@ -0,0 +1,4 @@ + +This option causes GPSBabel to use the MAC address as the short name for the +waypoint. The unmodified SSID is included in the waypoint description. + diff --git a/xmldoc/formats/options/nmea-append_positioning.xml b/xmldoc/formats/options/nmea-append_positioning.xml new file mode 100644 index 000000000..1706e47db --- /dev/null +++ b/xmldoc/formats/options/nmea-append_positioning.xml @@ -0,0 +1,5 @@ + + When writing NMEA realtime positioning data, append to the + output file instead of truncating it on each successive position + fix. + diff --git a/xmldoc/formats/options/nmea-baud.xml b/xmldoc/formats/options/nmea-baud.xml new file mode 100644 index 000000000..5aff834a1 --- /dev/null +++ b/xmldoc/formats/options/nmea-baud.xml @@ -0,0 +1,4 @@ + +To the "nmea" module, the "baud" option specifies the baud rate of the +serial connection when used with the real-time tracking option. + diff --git a/xmldoc/formats/options/nmea-date.xml b/xmldoc/formats/options/nmea-date.xml new file mode 100644 index 000000000..81467a8c9 --- /dev/null +++ b/xmldoc/formats/options/nmea-date.xml @@ -0,0 +1,10 @@ + +On input, track points with times but no dates will have this date applied. + + +This is necessary because some NMEA sentences contain times but no dates. If +this option is not specified and the date cannot be determined from one or +more of the available NMEA sentences, the tracks will be discarded. + + + diff --git a/xmldoc/formats/options/nmea-get_posn.xml b/xmldoc/formats/options/nmea-get_posn.xml new file mode 100644 index 000000000..dbc7b2ce6 --- /dev/null +++ b/xmldoc/formats/options/nmea-get_posn.xml @@ -0,0 +1,3 @@ +This options, when specified, returns the current position as a single +waypoint. + diff --git a/xmldoc/formats/options/nmea-gisteq.xml b/xmldoc/formats/options/nmea-gisteq.xml new file mode 100644 index 000000000..259529400 --- /dev/null +++ b/xmldoc/formats/options/nmea-gisteq.xml @@ -0,0 +1,17 @@ + + This option writes the Gisteq format - which has the extension of .GPS - + to allow third-party GPS hardware with the Gisteq PhotoTrackr software. + + + The Gisteq PhotoTrackr is a GPS data logger hardware and software package + that allows one to easily record the locations of where the user has taken + photos. The PhotoTrackr software works by comparing EXIF timestamps in + digital photos with the timestamps in the tracking data. In doing so, the + software plots the locations of the photos using Google Maps. The logging + format used by the Gisteq hardware is very close to NMEA format, but with a + few small quirks. + + +More information can be found at the +Gisteq site. + diff --git a/xmldoc/formats/options/nmea-gpgga.xml b/xmldoc/formats/options/nmea-gpgga.xml new file mode 100644 index 000000000..2b89b5072 --- /dev/null +++ b/xmldoc/formats/options/nmea-gpgga.xml @@ -0,0 +1,8 @@ + +This option tells GPSBabel whether to read (on input) or write (on output) +GPGGA sentences. The default is to read or write GPGGA sentences. To +disable GPGGA sentences, specify . + + +GPGGA sentences contain the location and quality of the GPS position fix. + diff --git a/xmldoc/formats/options/nmea-gpgsa.xml b/xmldoc/formats/options/nmea-gpgsa.xml new file mode 100644 index 000000000..40412dd84 --- /dev/null +++ b/xmldoc/formats/options/nmea-gpgsa.xml @@ -0,0 +1,12 @@ + +This option tells GPSBabel whether to read (on input) or write (on output) +GPGSA sentences. The default is to read or write GPGSA sentences. To +disable GPGSA sentences, specify . + + +GPGSA sentences contain information on the quality of the positional fix +and the individual satellites from which it was derived. However, GPSBabel +neither reads nor writes the individual satellite data. On input, the +satellite fields are ignored and on output they are left blank. + + diff --git a/xmldoc/formats/options/nmea-gprmc.xml b/xmldoc/formats/options/nmea-gprmc.xml new file mode 100644 index 000000000..d6b3f2d1e --- /dev/null +++ b/xmldoc/formats/options/nmea-gprmc.xml @@ -0,0 +1,11 @@ + +This option tells GPSBabel whether to read (on input) or write (on output) +GPRMC sentences. The default is to read or write GPRMC sentences. To +disable GPRMC sentences, specify . + + +GPRMC sentences contain the "recommended mimimum" positional information, +including date and time, heading, and velocity. Note that they do not +include altitude. For altitude, you will have to include GPGGA sentences. + + diff --git a/xmldoc/formats/options/nmea-gpvtg.xml b/xmldoc/formats/options/nmea-gpvtg.xml new file mode 100644 index 000000000..85d587517 --- /dev/null +++ b/xmldoc/formats/options/nmea-gpvtg.xml @@ -0,0 +1,11 @@ + +This option tells GPSBabel whether to read (on input) or write (on output) +GPVTG sentences. The default is to read or write GPVTG sentences. To +disable GPVTG sentences, specify . + + +GPVTG sentences contain information about the heading and the speed at the +time of the fix. They do not contain any location information; for that +you will need either or both of GPGGA or GPRMC. + + diff --git a/xmldoc/formats/options/nmea-pause.xml b/xmldoc/formats/options/nmea-pause.xml new file mode 100644 index 000000000..72e42ec73 --- /dev/null +++ b/xmldoc/formats/options/nmea-pause.xml @@ -0,0 +1,31 @@ + +This option tells GPSBabel to pause between individual track records when +used on output. This may be used with appropriate external software or +hardware to simulate a GPS receiver for testing purposes. On Unix, for +example, you may use a named pipe to feed the output from GPSBabel to gpsd. + + +If a value for this option is specified, it is in seconds and it may be +either a whole number of seconds or a fraction (e.g. 0.5 for a 1/2 second +pause between trackpoints.) + + +If this option is specified without a value, the time between adjacent +trackpoints will be computed and used for the length of the pause. That is, +if your trackpoints are 5 seconds apart, GPSBabel will pause 5 seconds +between trackpoints. + + +Note that very long tracks may be subject to clock drift, as GPSBabel does +not take into account the amount of time it may take to write the NMEA +sentences. Also, there is no guarantee that it will pause for exactly the +specified number of seconds between samples; different operating systems +will allow greater or lesser precision for timers, so actual precision may +be as much as plus or minus 100 milliseconds. + + +If you are using this option with compressed or simplified tracks from +your handheld GPS receiver, you might find the +interpolate filter useful. + + diff --git a/xmldoc/formats/options/nmea-snlen.xml b/xmldoc/formats/options/nmea-snlen.xml new file mode 100644 index 000000000..36e9c734b --- /dev/null +++ b/xmldoc/formats/options/nmea-snlen.xml @@ -0,0 +1,6 @@ + +This option specifies the maximum length to be used for waypoint names in +the GPWPL sentence. Longer names will be shortened to no more than this +length, but all waypoint names will remain unique. + + diff --git a/xmldoc/formats/options/nmn4-index.xml b/xmldoc/formats/options/nmn4-index.xml new file mode 100644 index 000000000..e5fa3f103 --- /dev/null +++ b/xmldoc/formats/options/nmn4-index.xml @@ -0,0 +1,9 @@ + +Because the format supports only one route, this option may be used +on output to select a single route from a collection of +routes read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. + +gpsbabel -i gpx -f routes.gpx -o nmn4,index=1 -F route1.rte -o nmn4,index=2 -F route2.rte + diff --git a/xmldoc/formats/options/osm-tag.xml b/xmldoc/formats/options/osm-tag.xml new file mode 100644 index 000000000..752fa5508 --- /dev/null +++ b/xmldoc/formats/options/osm-tag.xml @@ -0,0 +1,6 @@ + + With this option you can preset OSM features (tags) on all exported ways. + + + gpsbabel -i gdb -f ways.gdb -o osm,tag="highway:motorway" -F ways.osm + diff --git a/xmldoc/formats/options/osm-tagnd.xml b/xmldoc/formats/options/osm-tagnd.xml new file mode 100644 index 000000000..f9b10abc9 --- /dev/null +++ b/xmldoc/formats/options/osm-tagnd.xml @@ -0,0 +1,6 @@ + + With this option you can preset OSM features (tags) on every written nodes. + + + gpsbabel -i gdb -f nodes.gdb -o osm,tagnd="amenity:pub;building:yes" -F nodes.osm + diff --git a/xmldoc/formats/options/ozi-pack.xml b/xmldoc/formats/options/ozi-pack.xml new file mode 100644 index 000000000..1586c74cb --- /dev/null +++ b/xmldoc/formats/options/ozi-pack.xml @@ -0,0 +1,10 @@ + + In normal case GPSBabel creates for each track a separate file (track.plt, track-1.plt, ...). + With this option all tracks will be written into one file. A '1' in the third field of the + trackpoint record signals the beginning of a new track. + + + + gpsbabel -i gpx -f tracks.gpx -o ozi,pack -F track + + diff --git a/xmldoc/formats/options/ozi-proximity.xml b/xmldoc/formats/options/ozi-proximity.xml new file mode 100644 index 000000000..650aad86b --- /dev/null +++ b/xmldoc/formats/options/ozi-proximity.xml @@ -0,0 +1,4 @@ + + This option, specified in meters, allows you to set the proximity of +written in waypoints. + diff --git a/xmldoc/formats/options/ozi-snlen.xml b/xmldoc/formats/options/ozi-snlen.xml new file mode 100644 index 000000000..f7eb60b14 --- /dev/null +++ b/xmldoc/formats/options/ozi-snlen.xml @@ -0,0 +1,3 @@ + + This option allows you to specify the length of waypoint names written to this format when used with the option. + diff --git a/xmldoc/formats/options/ozi-snunique.xml b/xmldoc/formats/options/ozi-snunique.xml new file mode 100644 index 000000000..1e83a5d92 --- /dev/null +++ b/xmldoc/formats/options/ozi-snunique.xml @@ -0,0 +1,3 @@ + + When specified, this option will force the generated waypoint names to be unique. + diff --git a/xmldoc/formats/options/ozi-snupper.xml b/xmldoc/formats/options/ozi-snupper.xml new file mode 100644 index 000000000..608e6bb2f --- /dev/null +++ b/xmldoc/formats/options/ozi-snupper.xml @@ -0,0 +1,3 @@ + + When specified, this option will force generated shortnames to be in all uppercase letters. + diff --git a/xmldoc/formats/options/ozi-snwhite.xml b/xmldoc/formats/options/ozi-snwhite.xml new file mode 100644 index 000000000..80b964efa --- /dev/null +++ b/xmldoc/formats/options/ozi-snwhite.xml @@ -0,0 +1,3 @@ + + This option forces waypoint names generated with to allow whitespace in the names. + diff --git a/xmldoc/formats/options/ozi-wptbgcolor.xml b/xmldoc/formats/options/ozi-wptbgcolor.xml new file mode 100644 index 000000000..0b5fa134a --- /dev/null +++ b/xmldoc/formats/options/ozi-wptbgcolor.xml @@ -0,0 +1,3 @@ + + This option allows you to specify a background color of a waypoint. You can specify it as either a decimal number or one of the standard web colors. + diff --git a/xmldoc/formats/options/ozi-wptfgcolor.xml b/xmldoc/formats/options/ozi-wptfgcolor.xml new file mode 100644 index 000000000..fbaa20a8c --- /dev/null +++ b/xmldoc/formats/options/ozi-wptfgcolor.xml @@ -0,0 +1,3 @@ + + This option allows you to specify a foreground color of a waypoint. You can specify it as either a decimal number or one of the standard web colors. + diff --git a/xmldoc/formats/options/palmdoc-bookmarks_short.xml b/xmldoc/formats/options/palmdoc-bookmarks_short.xml new file mode 100644 index 000000000..b1c22efb5 --- /dev/null +++ b/xmldoc/formats/options/palmdoc-bookmarks_short.xml @@ -0,0 +1,9 @@ + +If you would like the generated bookmarks to start with +the short name for the waypoint, specify this option. + + +This is particularly useful when used in combination with the 'sort' +filter. + + diff --git a/xmldoc/formats/options/palmdoc-dbname.xml b/xmldoc/formats/options/palmdoc-dbname.xml new file mode 100644 index 000000000..626baaa86 --- /dev/null +++ b/xmldoc/formats/options/palmdoc-dbname.xml @@ -0,0 +1,5 @@ + +This option specifies the internal name for the document. This is the name +that appears in your document reader, not the name of the file that is created +on your computer. + diff --git a/xmldoc/formats/options/palmdoc-encrypt.xml b/xmldoc/formats/options/palmdoc-encrypt.xml new file mode 100644 index 000000000..2d7d96091 --- /dev/null +++ b/xmldoc/formats/options/palmdoc-encrypt.xml @@ -0,0 +1,3 @@ + +Use this option to encrypt hints from Groundspeak GPX files. + diff --git a/xmldoc/formats/options/palmdoc-logs.xml b/xmldoc/formats/options/palmdoc-logs.xml new file mode 100644 index 000000000..9e25a13ea --- /dev/null +++ b/xmldoc/formats/options/palmdoc-logs.xml @@ -0,0 +1,3 @@ + +Use this option to include Groundspeak cache logs in the created document. + diff --git a/xmldoc/formats/options/palmdoc-nosep.xml b/xmldoc/formats/options/palmdoc-nosep.xml new file mode 100644 index 000000000..75e79abf7 --- /dev/null +++ b/xmldoc/formats/options/palmdoc-nosep.xml @@ -0,0 +1,3 @@ + +To suppress the dashed lines between waypoints, use this option. + diff --git a/xmldoc/formats/options/pathaway-date.xml b/xmldoc/formats/options/pathaway-date.xml new file mode 100644 index 000000000..e505b5eb7 --- /dev/null +++ b/xmldoc/formats/options/pathaway-date.xml @@ -0,0 +1,4 @@ + +This option specifies the input and output format for the date. The format +is written similarly to those in Windows. An example format is "YYMMDD". + diff --git a/xmldoc/formats/options/pathaway-dbname.xml b/xmldoc/formats/options/pathaway-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/pathaway-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/pathaway-deficon.xml b/xmldoc/formats/options/pathaway-deficon.xml new file mode 100644 index 000000000..5e05476af --- /dev/null +++ b/xmldoc/formats/options/pathaway-deficon.xml @@ -0,0 +1,3 @@ + + The deficon option is used to control the icon output when writing to this format. It overrides any icon informatino that might be present in the source data. + diff --git a/xmldoc/formats/options/pathaway-snlen.xml b/xmldoc/formats/options/pathaway-snlen.xml new file mode 100644 index 000000000..f7eb60b14 --- /dev/null +++ b/xmldoc/formats/options/pathaway-snlen.xml @@ -0,0 +1,3 @@ + + This option allows you to specify the length of waypoint names written to this format when used with the option. + diff --git a/xmldoc/formats/options/pcx-cartoexploreur.xml b/xmldoc/formats/options/pcx-cartoexploreur.xml new file mode 100644 index 000000000..17bc9721b --- /dev/null +++ b/xmldoc/formats/options/pcx-cartoexploreur.xml @@ -0,0 +1,4 @@ + + Carto Exploreur requires a slightly incompatible variation of the PCX format +when written. Specifying this option on write tells us to create that strain of PCX. + diff --git a/xmldoc/formats/options/pcx-deficon.xml b/xmldoc/formats/options/pcx-deficon.xml new file mode 100644 index 000000000..5e05476af --- /dev/null +++ b/xmldoc/formats/options/pcx-deficon.xml @@ -0,0 +1,3 @@ + + The deficon option is used to control the icon output when writing to this format. It overrides any icon informatino that might be present in the source data. + diff --git a/xmldoc/formats/options/quovadis-dbname.xml b/xmldoc/formats/options/quovadis-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/quovadis-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/raymarine-location.xml b/xmldoc/formats/options/raymarine-location.xml new file mode 100644 index 000000000..eb56b6a60 --- /dev/null +++ b/xmldoc/formats/options/raymarine-location.xml @@ -0,0 +1,7 @@ + + With this option you can specify the name of the folder + where the waypoints are placed. + + + This name is also limited to 16 characters. + diff --git a/xmldoc/formats/options/saroute-controls.xml b/xmldoc/formats/options/saroute-controls.xml new file mode 100644 index 000000000..e532c0c6d --- /dev/null +++ b/xmldoc/formats/options/saroute-controls.xml @@ -0,0 +1,10 @@ +This option lets you read the control points +(start, end, vias, and stops) for your route as well as the route +itself. The default for this option is 'none', which won't read the +control points. You may also specify 'waypoints', which reads the +control points as waypoints, or 'route', which creates an extra route +named 'control points' containing just the control points in order. +Note that if your goal is to create an arc or other CSV file, you +should use 'none' (or not use this option, which is the same +thing.) + diff --git a/xmldoc/formats/options/saroute-split.xml b/xmldoc/formats/options/saroute-split.xml new file mode 100644 index 000000000..e83fd4d17 --- /dev/null +++ b/xmldoc/formats/options/saroute-split.xml @@ -0,0 +1,5 @@ + This option causes GPSBabel to create separate +routes for each street, creating a new route at each turn point. For +obvious reasons, 'split' cannot be used at the same time as the +'turns_only' or 'turns_important' options. + diff --git a/xmldoc/formats/options/saroute-times.xml b/xmldoc/formats/options/saroute-times.xml new file mode 100644 index 000000000..857b3d3ce --- /dev/null +++ b/xmldoc/formats/options/saroute-times.xml @@ -0,0 +1,5 @@ + This option causes GPSBabel to read the route as if +it were a track, synthesizing times starting from the current time, using +the estimated travel times specified in your route file (you can change your +travel speeds in the DeLorme product you used to create the route file.) + diff --git a/xmldoc/formats/options/saroute-turns_important.xml b/xmldoc/formats/options/saroute-turns_important.xml new file mode 100644 index 000000000..82b793a09 --- /dev/null +++ b/xmldoc/formats/options/saroute-turns_important.xml @@ -0,0 +1,6 @@ + This option only makes sense in +conjunction with the 'simplify' filter. It ensures that the route +simplification process will remove the points corresponding to turns +only after it has removed all other route points. + + diff --git a/xmldoc/formats/options/saroute-turns_only.xml b/xmldoc/formats/options/saroute-turns_only.xml new file mode 100644 index 000000000..1c35dc5d8 --- /dev/null +++ b/xmldoc/formats/options/saroute-turns_only.xml @@ -0,0 +1,4 @@ + This option causes GPSBabel to read only the +waypoints associated with named turns. This should create a list of +waypoints that correspond to the itinerary from Street Atlas. + diff --git a/xmldoc/formats/options/stmsdf-index.xml b/xmldoc/formats/options/stmsdf-index.xml new file mode 100644 index 000000000..f42f1c99e --- /dev/null +++ b/xmldoc/formats/options/stmsdf-index.xml @@ -0,0 +1,15 @@ + + Convert route number 'index' from source into sdf format. + + + We have a lot of more expressive formats thats support more than one route. + At this place sdf files are limited to only one single route. With option index + you can specify which route from source should be converted. + + + Our default index is 1. + + + This example will convert route number two and three into separate sdf files: + + gpsbabel -i gdb -f routes.gdb -r -o stmsdf,index=2 -F route-one.sdf -r -o stmsdf,index=3 -F route-three.sdf diff --git a/xmldoc/formats/options/stmwpp-index.xml b/xmldoc/formats/options/stmwpp-index.xml new file mode 100644 index 000000000..c43659c2f --- /dev/null +++ b/xmldoc/formats/options/stmwpp-index.xml @@ -0,0 +1,9 @@ + +Because the format supports only one route or track, this option may be used +on output to select a single route or track from a collection of routes and +tracks read from a more expressive format. If you have, say, a +gpx file that contains three routes, you may +use this option to write them one at a time to individual files. + +gpsbabel -i gpx -f routes.gpx -o stmwpp,index=1 -F route1.txt -o stmwpp,index=2 -F route2.txt -o stmwpp,index=3 -F route3.txt + diff --git a/xmldoc/formats/options/tef-routevia.xml b/xmldoc/formats/options/tef-routevia.xml new file mode 100644 index 000000000..b57880554 --- /dev/null +++ b/xmldoc/formats/options/tef-routevia.xml @@ -0,0 +1,3 @@ + +This option may be used to eliminate calculated route points from the route. + diff --git a/xmldoc/formats/options/text-altunits.xml b/xmldoc/formats/options/text-altunits.xml new file mode 100644 index 000000000..788f88674 --- /dev/null +++ b/xmldoc/formats/options/text-altunits.xml @@ -0,0 +1,4 @@ + +This option should be 'f' if you want the altitude expressed in feet and +'m' for meters. The default is 'f'. + \ No newline at end of file diff --git a/xmldoc/formats/options/text-degformat.xml b/xmldoc/formats/options/text-degformat.xml new file mode 100644 index 000000000..25d45942b --- /dev/null +++ b/xmldoc/formats/options/text-degformat.xml @@ -0,0 +1,5 @@ + +When GPSBabel writes coordinates, this option is consulted to see if it +should write decimal degrees ('ddd') decimal minutes ('dmm') or degrees, +minutes, seconds ('dms'). The default is 'dmm'. + diff --git a/xmldoc/formats/options/text-encrypt.xml b/xmldoc/formats/options/text-encrypt.xml new file mode 100644 index 000000000..2d7d96091 --- /dev/null +++ b/xmldoc/formats/options/text-encrypt.xml @@ -0,0 +1,3 @@ + +Use this option to encrypt hints from Groundspeak GPX files. + diff --git a/xmldoc/formats/options/text-logs.xml b/xmldoc/formats/options/text-logs.xml new file mode 100644 index 000000000..9e25a13ea --- /dev/null +++ b/xmldoc/formats/options/text-logs.xml @@ -0,0 +1,3 @@ + +Use this option to include Groundspeak cache logs in the created document. + diff --git a/xmldoc/formats/options/text-nosep.xml b/xmldoc/formats/options/text-nosep.xml new file mode 100644 index 000000000..75e79abf7 --- /dev/null +++ b/xmldoc/formats/options/text-nosep.xml @@ -0,0 +1,3 @@ + +To suppress the dashed lines between waypoints, use this option. + diff --git a/xmldoc/formats/options/text-splitoutput.xml b/xmldoc/formats/options/text-splitoutput.xml new file mode 100644 index 000000000..5bf9d4c41 --- /dev/null +++ b/xmldoc/formats/options/text-splitoutput.xml @@ -0,0 +1,15 @@ + + Splits output into separate files for each waypoint by appending a + decimal number to the output filename. + + + Example for splitoutput option to text format + + If "MyPQ.gpx" contains five waypoints, + + gpsbabel -i gpx -f MyPocketQuery -o text,split -F blah + + will result in files named blah1 ... blah5, each containing info + from one of those waypoints. + + diff --git a/xmldoc/formats/options/tiger-genurl.xml b/xmldoc/formats/options/tiger-genurl.xml new file mode 100644 index 000000000..03ebc6d99 --- /dev/null +++ b/xmldoc/formats/options/tiger-genurl.xml @@ -0,0 +1,20 @@ + +genurl is a convenience option for generating the scaling paramaters +when accessing the Tiger servers. It will output the latitude, longitude, +height, and width parameters in a form suitable for use in the URL to generate +a map that will hold all the points to be displayed and is suitably scaled +and centered. + +For example: +gpsbabel -i geo -f geocaching.loc -o tiger,genurl=tiger.ctr -F tiger.dat + +may create tiger.ctr with + +lat=36.042108&lon=-86.877408&ht=0.161172&wid=0.591771&iwd=768&iht=768 + +After uploading tiger.dat to a public server, a request to + http://tiger.census.gov/cgi-bin/mapgen?murl=$THATFILE$(cat tiger.ctr) +will return a gif file from the tiger server that's suitably scaled. + + + diff --git a/xmldoc/formats/options/tiger-iconismarker.xml b/xmldoc/formats/options/tiger-iconismarker.xml new file mode 100644 index 000000000..899aed557 --- /dev/null +++ b/xmldoc/formats/options/tiger-iconismarker.xml @@ -0,0 +1,4 @@ + This options signifies that the icon in the incoming format is to be used +without change in the generated Tiger output file. Without this option, +GPSBabel tries to color pins based on their creation time and certain +Geocaching traits when available. diff --git a/xmldoc/formats/options/tiger-margin.xml b/xmldoc/formats/options/tiger-margin.xml new file mode 100644 index 000000000..e9b58184a --- /dev/null +++ b/xmldoc/formats/options/tiger-margin.xml @@ -0,0 +1,7 @@ +This option specifies a margin around the maps for the genurl options. +The margin may be specified in either decimal degrees or as a +percentage. + +This option is most useful for ensuring there is adaequate space for +the label around the markers when generating automatically scaled maps. + diff --git a/xmldoc/formats/options/tiger-newmarker.xml b/xmldoc/formats/options/tiger-newmarker.xml new file mode 100644 index 000000000..ec3af7c12 --- /dev/null +++ b/xmldoc/formats/options/tiger-newmarker.xml @@ -0,0 +1,3 @@ +This option specifies the pin to be used if a waypoint has a creation +time older than 'oldthresh' days. +The default is "greenpin". diff --git a/xmldoc/formats/options/tiger-nolabels.xml b/xmldoc/formats/options/tiger-nolabels.xml new file mode 100644 index 000000000..33ec2c1cb --- /dev/null +++ b/xmldoc/formats/options/tiger-nolabels.xml @@ -0,0 +1,3 @@ +This option tells GPSBabel to not generate labels on the pins. If +this is true, the description of the incoming waypoints are ignored and not +placed on the pins. diff --git a/xmldoc/formats/options/tiger-oldmarker.xml b/xmldoc/formats/options/tiger-oldmarker.xml new file mode 100644 index 000000000..abce81d92 --- /dev/null +++ b/xmldoc/formats/options/tiger-oldmarker.xml @@ -0,0 +1,3 @@ +This option specifies the pin to be used if a waypoint has a creation +time newer than 'oldthresh' days. +The default is "redpin". diff --git a/xmldoc/formats/options/tiger-oldthresh.xml b/xmldoc/formats/options/tiger-oldthresh.xml new file mode 100644 index 000000000..919026372 --- /dev/null +++ b/xmldoc/formats/options/tiger-oldthresh.xml @@ -0,0 +1,5 @@ +This options allows you to control the threshold in days between +whether a pin is considered "new" (and thus potentially governed by the +'newmarker' option) or "old" (and thus potentially governed by the +'oldmarker' option). + diff --git a/xmldoc/formats/options/tiger-snlen.xml b/xmldoc/formats/options/tiger-snlen.xml new file mode 100644 index 000000000..ae39cd736 --- /dev/null +++ b/xmldoc/formats/options/tiger-snlen.xml @@ -0,0 +1,5 @@ + +The snlen option controls the maximum length of names generated by the '-s' +option. It's particularly useful in Tiger maps to avoid the amount of clutter +generated by potentially lengthy labels on the markers. + diff --git a/xmldoc/formats/options/tiger-suppresswhite.xml b/xmldoc/formats/options/tiger-suppresswhite.xml new file mode 100644 index 000000000..6576ef45c --- /dev/null +++ b/xmldoc/formats/options/tiger-suppresswhite.xml @@ -0,0 +1,4 @@ + +When set, this options tells the '-s' smartname generator to not allow +any spaces in the labels generated for markers. + diff --git a/xmldoc/formats/options/tiger-unfoundmarker.xml b/xmldoc/formats/options/tiger-unfoundmarker.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/tiger-unfoundmarker.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/tiger-xpixels.xml b/xmldoc/formats/options/tiger-xpixels.xml new file mode 100644 index 000000000..a857af3ed --- /dev/null +++ b/xmldoc/formats/options/tiger-xpixels.xml @@ -0,0 +1,3 @@ +The xpixels argument lets you specify the number of pixels to be +generated by the Tiger server along the horizontal axis when using the +'genurl' option. diff --git a/xmldoc/formats/options/tiger-ypixels.xml b/xmldoc/formats/options/tiger-ypixels.xml new file mode 100644 index 000000000..846de24a4 --- /dev/null +++ b/xmldoc/formats/options/tiger-ypixels.xml @@ -0,0 +1,4 @@ +The ypixels argument lets you specify the number of pixels to be +generated by the Tiger server along the vertical axis when using the +'genurl' option. + diff --git a/xmldoc/formats/options/tpg-datum.xml b/xmldoc/formats/options/tpg-datum.xml new file mode 100644 index 000000000..f215467ff --- /dev/null +++ b/xmldoc/formats/options/tpg-datum.xml @@ -0,0 +1,6 @@ + The option 'datum="datum name"' can be used to override +the default of NAD27 ("N. America 1927 mean") which is correct for the +continental U.S. Any legal datum supported +by GPSBabel may be used. For example, points in Hawaii should +use "Old Hawaiian_mean". + diff --git a/xmldoc/formats/options/unicsv-datum.xml b/xmldoc/formats/options/unicsv-datum.xml new file mode 100644 index 000000000..b4d56af7f --- /dev/null +++ b/xmldoc/formats/options/unicsv-datum.xml @@ -0,0 +1,4 @@ + + This option specifies the datum to be used on output. Valid values for this + option are listed in . + diff --git a/xmldoc/formats/options/unicsv-grid.xml b/xmldoc/formats/options/unicsv-grid.xml new file mode 100644 index 000000000..7d6cab0a4 --- /dev/null +++ b/xmldoc/formats/options/unicsv-grid.xml @@ -0,0 +1,8 @@ + + This value specifies the grid to be used on write. It is similar to + the grid option of garmin_txt (see ). The only difference is that unicsv does not + write a degree sign (°) into the output file. + + + Without this option unicsv writes the coordinates as simple numbers like in the samples above. + diff --git a/xmldoc/formats/options/unicsv-utc.xml b/xmldoc/formats/options/unicsv-utc.xml new file mode 100644 index 000000000..4c2964e0e --- /dev/null +++ b/xmldoc/formats/options/unicsv-utc.xml @@ -0,0 +1,5 @@ + +This option specifies the local time zone to use when writing times. It +is specified as an offset from Universal Coordinated Time (UTC) in hours. +Valid values are from -23 to +23. + diff --git a/xmldoc/formats/options/vcard-encrypt.xml b/xmldoc/formats/options/vcard-encrypt.xml new file mode 100644 index 000000000..1ba2851e2 --- /dev/null +++ b/xmldoc/formats/options/vcard-encrypt.xml @@ -0,0 +1,4 @@ + +By default geocaching hints are unencrypted; use this option to encrypt them. + + diff --git a/xmldoc/formats/options/wbt-erase.xml b/xmldoc/formats/options/wbt-erase.xml new file mode 100644 index 000000000..71aaf2c54 --- /dev/null +++ b/xmldoc/formats/options/wbt-erase.xml @@ -0,0 +1 @@ +This option erases the track log from the device after download. \ No newline at end of file diff --git a/xmldoc/formats/options/wfff-ahcicon.xml b/xmldoc/formats/options/wfff-ahcicon.xml new file mode 100644 index 000000000..35d45508d --- /dev/null +++ b/xmldoc/formats/options/wfff-ahcicon.xml @@ -0,0 +1,3 @@ + +This options lets you specify an icon for an Ad-hoc, closed, waypoint. + diff --git a/xmldoc/formats/options/wfff-ahoicon.xml b/xmldoc/formats/options/wfff-ahoicon.xml new file mode 100644 index 000000000..5961bdc10 --- /dev/null +++ b/xmldoc/formats/options/wfff-ahoicon.xml @@ -0,0 +1,4 @@ + + +This options lets you specify an icon for an Ad-hoc, open, waypoint. + diff --git a/xmldoc/formats/options/wfff-aicicon.xml b/xmldoc/formats/options/wfff-aicicon.xml new file mode 100644 index 000000000..4fe063f52 --- /dev/null +++ b/xmldoc/formats/options/wfff-aicicon.xml @@ -0,0 +1,3 @@ + +This option lets you specify an icon for infrastructure closed points. + diff --git a/xmldoc/formats/options/wfff-aioicon.xml b/xmldoc/formats/options/wfff-aioicon.xml new file mode 100644 index 000000000..9bba54594 --- /dev/null +++ b/xmldoc/formats/options/wfff-aioicon.xml @@ -0,0 +1,4 @@ + + +This option lets you specify an icon for infrastructure open points. + diff --git a/xmldoc/formats/options/wfff-snmac.xml b/xmldoc/formats/options/wfff-snmac.xml new file mode 100644 index 000000000..d8ad46984 --- /dev/null +++ b/xmldoc/formats/options/wfff-snmac.xml @@ -0,0 +1,3 @@ + + This options lets you specify that the shortname of the waypoint is the MAC address. + diff --git a/xmldoc/formats/options/xcsv-datum.xml b/xmldoc/formats/options/xcsv-datum.xml new file mode 100644 index 000000000..26519942f --- /dev/null +++ b/xmldoc/formats/options/xcsv-datum.xml @@ -0,0 +1,4 @@ + +This option specifies the GPS datum to be used on read or write. Valid values for this +option are listed in . + diff --git a/xmldoc/formats/options/xcsv-prefer_shortnames.xml b/xmldoc/formats/options/xcsv-prefer_shortnames.xml new file mode 100644 index 000000000..e3103bd2d --- /dev/null +++ b/xmldoc/formats/options/xcsv-prefer_shortnames.xml @@ -0,0 +1,7 @@ + +This option causes GPSBabel to use the short name of the waypoint instead +of the description. This overrides the style file. + + +Valid values for this option are 0 (off) and 1 (on). + diff --git a/xmldoc/formats/options/xcsv-snlen.xml b/xmldoc/formats/options/xcsv-snlen.xml new file mode 100644 index 000000000..9318463ce --- /dev/null +++ b/xmldoc/formats/options/xcsv-snlen.xml @@ -0,0 +1,8 @@ + +This option specifies the maximum allowable length for a short name on +output. This option overrides the style file. + + +Valid values for this option are 0 (off) and 1 (on). + + diff --git a/xmldoc/formats/options/xcsv-snunique.xml b/xmldoc/formats/options/xcsv-snunique.xml new file mode 100644 index 000000000..1687cbec1 --- /dev/null +++ b/xmldoc/formats/options/xcsv-snunique.xml @@ -0,0 +1,8 @@ + +When this option is specified, GPSBabel will ensure that all short names are +unique within the output file. This option overrides the style file. + + +Valid values for this option are 0 (off) and 1 (on). + + diff --git a/xmldoc/formats/options/xcsv-snupper.xml b/xmldoc/formats/options/xcsv-snupper.xml new file mode 100644 index 000000000..99400ee91 --- /dev/null +++ b/xmldoc/formats/options/xcsv-snupper.xml @@ -0,0 +1,8 @@ + +When this option is specified, GPSBabel will make all short names contain +only UPPERCASE characters. This option overrides the style file. + + +Valid values for this option are 0 (off) and 1 (on). + + diff --git a/xmldoc/formats/options/xcsv-snwhite.xml b/xmldoc/formats/options/xcsv-snwhite.xml new file mode 100644 index 000000000..1688f0bc9 --- /dev/null +++ b/xmldoc/formats/options/xcsv-snwhite.xml @@ -0,0 +1,7 @@ + +When this option is specified, GPSBabel will allow whitespace (spaces or tabs) +in generated short names. This option overrides the style file. + + +Valid values for this option are 0 (off) and 1 (on). + diff --git a/xmldoc/formats/options/xcsv-style.xml b/xmldoc/formats/options/xcsv-style.xml new file mode 100644 index 000000000..43baf0378 --- /dev/null +++ b/xmldoc/formats/options/xcsv-style.xml @@ -0,0 +1,10 @@ + +This option specifies the style file that defines the records to be read on +input or written on output. This is not a valid option for the various +built-in xcsv-based styles; they have prebuilt style definitions. + + +For information on the format of xcsv style files, see +. + + diff --git a/xmldoc/formats/options/xcsv-urlbase.xml b/xmldoc/formats/options/xcsv-urlbase.xml new file mode 100644 index 000000000..781e75c4c --- /dev/null +++ b/xmldoc/formats/options/xcsv-urlbase.xml @@ -0,0 +1,5 @@ + +This option specifies the base name to prepend to a URL on output. This +might be useful if an input file contains URLs in a relative format and you +need them to be in an absolute format. + diff --git a/xmldoc/formats/options/yahoo-addrsep.xml b/xmldoc/formats/options/yahoo-addrsep.xml new file mode 100644 index 000000000..249ca3cb4 --- /dev/null +++ b/xmldoc/formats/options/yahoo-addrsep.xml @@ -0,0 +1,9 @@ + +This option specifies the string GPSBabel should use to separate the parts +of the street address. Since most other formats supported by GPSBabel do +not support street addresses, the street address fields from the Yahoo file +are concatenated into the waypoint "notes" field. + + +The default value for this option is a comma followed by a space (", "). + diff --git a/xmldoc/formats/osm.xml b/xmldoc/formats/osm.xml new file mode 100644 index 000000000..9ebc8ed62 --- /dev/null +++ b/xmldoc/formats/osm.xml @@ -0,0 +1,13 @@ + + This format is used to exchange data with the OpenStreetMap project. + The main goal of this collaborative project is to create free editable maps. + + + These data files are XML based. Every GPS element (way or node) described by the files has a unique + number as identifier. When we write OSM data files and don't know something about the id's, + negative numbers will be used as identifier. This has been tested with JOSM. + + + Because the resulting timestamps of OSM ways differ from real GPS tracks, + we read OSM ways into routes. On the output side we write all available routes and tracks into the osm target file. + diff --git a/xmldoc/formats/ozi.xml b/xmldoc/formats/ozi.xml new file mode 100644 index 000000000..1e3819a0e --- /dev/null +++ b/xmldoc/formats/ozi.xml @@ -0,0 +1,7 @@ + + + + OziExplorer Waypoint Format - Another CSV format file. +Tested against OziExplorer v 3.90.3a / Shareware. Contributed by Alex +Mottram + diff --git a/xmldoc/formats/palmdoc.xml b/xmldoc/formats/palmdoc.xml new file mode 100644 index 000000000..2ed7ff68b --- /dev/null +++ b/xmldoc/formats/palmdoc.xml @@ -0,0 +1,13 @@ + +PalmDoc output is similar to Text +output, except that it generates a Palm Database (PDB) file suitable for +use with programs like CSpotRun, TealDoc, AportisDoc, Palm Reader, and +others. The resulting file also contains bookmarks to make it easy to jump +to a particular waypoint. + + +The following command line reads a GPX file with Groundspeak extensions +and writes a Palm document with encrypted hints and logs: + +gpsbabel -i gpx -f 12345.gpx -o "palmdoc,dbname=Unfound Geocaches,encrypt,logs" -F 12345.pdb + diff --git a/xmldoc/formats/pathaway.xml b/xmldoc/formats/pathaway.xml new file mode 100644 index 000000000..435adff4d --- /dev/null +++ b/xmldoc/formats/pathaway.xml @@ -0,0 +1,10 @@ + + + + PathAway is a Palm software designed for handling "most" +GPS devices (including BlueTooth). In this time (I mean 2005) a free +tool to convert this database is located on the homepage of PathAway +(www.pathaway.com). But I've read there ... for windows and the output +formats are also very limited. + + diff --git a/xmldoc/formats/pcx.xml b/xmldoc/formats/pcx.xml new file mode 100644 index 000000000..60abecec5 --- /dev/null +++ b/xmldoc/formats/pcx.xml @@ -0,0 +1,16 @@ + + + + Garmin documents only PCX5, an older format limited to +the lame NMEA six-character waypoint names that's treated as a +second-class citizien in current versions of MapSource. In Mapsource, +use file->import to read these files. If you name the files *.wpt, +Mapsource will find them more easily. + + In general, you should prefer the "mapsource" file format +to this one. + + This format has been extended to handle many - but not all - + files from GPS Utility. If you encounter something that GPSBabel does not handle well, use +the free version of GPSUtil to read it and save as something more common. + diff --git a/xmldoc/formats/psitrex.xml b/xmldoc/formats/psitrex.xml new file mode 100644 index 000000000..b9c59537f --- /dev/null +++ b/xmldoc/formats/psitrex.xml @@ -0,0 +1,10 @@ + + + + This is a text format created by KuDaTa's PsiTrex program +for the Psion PDAs. The format can't be readily handled by XCSV, so +this format is handled explicitly. Waypoints, routes and tracks are +all handled, with icon names used corresponding to verison 1.13 of +PsiTrex. This module was contributed to GPSBabel by Mark +Bradley. + diff --git a/xmldoc/formats/psp.xml b/xmldoc/formats/psp.xml new file mode 100644 index 000000000..70838c26b --- /dev/null +++ b/xmldoc/formats/psp.xml @@ -0,0 +1,223 @@ + +Microsoft's PocketStreets 2002 Pushpin (.PSP) format is +not yet completely documented. The .PSP module does not work with +MS Streets & Trips 2002 .EST files To create .PSP files from +Streets & Trips 2002, you will need to have PocketStreets support +installed. + + +Please note that MS Streets & Trips only exports +.PSP files. It does not import them. MS Streets & Trips 2002 only +imports CSV files. To use .PSP files, simply copy them over to the +same folder on the mobile device as the map (.MPS), and open +PocketStreets. It should also be noted that in the case a pushpin is +outside of the exported map area, the pin will be "grayed-out" and +unused in PocketStreets. This is a good thing as it allows us to +create one big .PSP file that covers multiple .MPS files. +Unfortunately, you need one .PSP file for every .MPS file. + +
                    +Frequently Asked Questions + + + + +Why should I use GPSBabel/psp to make pushpins when Streets & Trips (S&T) + already does that for me? + + + + +GPSBabel/psp has the advantage of being able to create pushpins +without + creating the associated map file and the need to "import" the waypoint + data into S&T. Through a series of scripts, you can create a dozen + or so PSP files in a few seconds as opposed to a few weeks using the + S&T interface. The maps are not going to change between sessions, + only the pins will. Why waste all that time creating maps when all you + really want are updated pins? As an aside, GPSBabel/psp creates points + with the proper coordinates + where S&T does not in some areas of the U.S. + (Nashville, TN for instance). + + + + + + +I keep getting a blank (32 byte) PSP file. + + + + +There are either no points to write, or you have botched the command + line for GPSBabel. GPSBabel is sensitive to UPPER and lower case + on the command line. A simple command line to create PSP files + looks like this: + +gpsbabel -i geo -f geocaching.loc -o psp -F NewOrleans.psp + + Note the use of "-f" for INPUT files and "-F" for OUTPUT files. + + + + + + +I've created a PSP file, now what do I do with it? + + + + +To use pushpins in Pocketstreets, you need to have both a map and a + pushpin file. These two files must exist in the same folder and have + exactly the same base name as the map. For example, the pins that + correspond to the map "NewOrleans.mps" should be named "NewOrleans.psp". + + + + + + +I don't have a map. What do I do now? + + + + +Create one using the "Export map to Pocketstreets" option in S&T. You + can also pick up some major city maps on the web from the MS Pocketstreets + website if you are interested in seeing how it works. + + + + + + +I have .EST files, not .PSP files. What's up with that? + + + + +In order to make PSP files, you need to use the "Export map to + Pocketstreets" function in S&T. .EST files are for use in S&T, not + Pocketstreets. + + + + + + + The .PSP files differ when I use GPSBabel/psp versus Pocketstreets to + create them. What's up? + + + + +Pocketstreets makes corrections to the S&T waypoint data upon initial + loading. GPSBabel/psp writes PSP files with these corrections already made. + Ask MS. + + + + + + +Does GPSBabel/psp work with (Autoroute, Mappoint, etc..) .PSP files? + + + + +As of this writing, I haven't seen any so I can't be sure. If they + follow the same layout as S&T 2002, I'd imagine so. + + + + + + + Does GPSBabel/psp work with (S&T 2001, S&T 2002, etc...) files? + + + + +MS changed the file layout between S&T 2001 and S&T 2002. The GPSBabel psp + module is known to work fine with S&T 2002 and 2003. + + + + + + +Does GPSBabel/psp work with (insert your country/location here) maps? + + + + +If it doesn't, feel free to inquire on the +GPSBabel-Misc +mailing list. + + + + + + +What do you mean S&T writes points with the wrong coordinates? + + + + +At some point in the "Export map to Pocketstreets" function in S&T, + it goofs the lat/long data. Points in Nashville tended to shift + 1.4 miles WEST of their original location. I'm not a geometry buff, + but I'd imagine they have a reference point for generating coordinates + that's wrong in (at least) that area. + + + + + + +I have 800 waypoints that cover a dozen or so Pocketstreets maps. + Do I need to to split my points up into smaller chunks to match the + area covered by the maps? + + + + + No. Pocketstreets will "ignore" points that are outside of the map + area. Points that are not on the current map will be "grayed out" + in pushpin explorer in Pocketsreets. This is the reason the PSP + module was written for GPSBabel in the first place. + + + + + + +Where can I find documentation for the layout of PSP files? + + + + +Just about everything I know about the PSP file format is documented + in the source. To the best of my knowledge, there is no documentation + (and for good reason, I've come to discover). + + + + + + +I have some other problem, what do I do? + + + + +Ask your question on the GPSBabel-Misc mailing list. + + + + +
                    + diff --git a/xmldoc/formats/quovadis.xml b/xmldoc/formats/quovadis.xml new file mode 100644 index 000000000..516601e76 --- /dev/null +++ b/xmldoc/formats/quovadis.xml @@ -0,0 +1,21 @@ + + + + QuoVadis for Palm OS marcosoft.com is a program for +Palm/OS. Working with record definitions provided by MarcoSoft and +further experimentation by Bruce Thompson and "Fuzzy" from the +Geocaching Forums to nail down the format precisely. + Should work fine for import and export. + One thing of note, QuoVadis stores all waypoints in a +single Palm Database without using categories. This means that it may +be difficult to keep personal waypoints separate from generated +waypoints. What Bruce recommends is taking the QuoVadisMarkerDB.PDB +file synced down from your Palm Powered device and extract the +waypoints you personally set to a GPX file. Then using GPSBabel's +joining capabilities generate a new PDB file from the personal file +and the other waypoint files of interest. + Currently the selection of icons to display and the scale +at which to display them is hardcoded. Also there is no support for +notes associated with waypoints. This will be addressed in a future +revision. + diff --git a/xmldoc/formats/raymarine.xml b/xmldoc/formats/raymarine.xml new file mode 100644 index 000000000..258c12edf --- /dev/null +++ b/xmldoc/formats/raymarine.xml @@ -0,0 +1,7 @@ + + This format supports the "Raymarine Waypoint File" format (.rwf). + More information to Raymarine you'll find at their homepage. + + + Known limits: max. 16 characters for waypoint names and max. 50 waypoints per route. + diff --git a/xmldoc/formats/s_and_t.xml b/xmldoc/formats/s_and_t.xml new file mode 100644 index 000000000..2eb0956e1 --- /dev/null +++ b/xmldoc/formats/s_and_t.xml @@ -0,0 +1,13 @@ + + + + This is a format for creating data to be read by + Microsoft Streets and +Trips. It's been exercised on versions from 2003 through 2008. Detailed +instructions on how to use it, including preserving hyperlinks, are at +gpsbabel.org + + + This format has nothing to do with the .est/axe format used by this program to store routes. + + diff --git a/xmldoc/formats/saplus.xml b/xmldoc/formats/saplus.xml new file mode 100644 index 000000000..2c30a046d --- /dev/null +++ b/xmldoc/formats/saplus.xml @@ -0,0 +1,17 @@ + + + + This format is for Delorme Street Atlas USA 2004 Plus and later. + + For geocachers importing data from a tool like GSAK or +Spinner, import the file twice in XData. One will create a file with +the Cache description as a hyperlink on the flag. This can clutter up +the screen and when you try to zoom in, it causes problems. So the +second one will only have a flag. Thus you can turn off and on which +one you want to view. The first time you import the file, in the +assign field types, check the circle above Full Name and then next. +The second time you import the file do not check any circle and in the +second to last column, change URL to none and then click next. Use the +same name you used the first time but add -Flag to it. + + diff --git a/xmldoc/formats/saroute.xml b/xmldoc/formats/saroute.xml new file mode 100644 index 000000000..d0db6155c --- /dev/null +++ b/xmldoc/formats/saroute.xml @@ -0,0 +1,9 @@ + +This format reads route files from many Delorme mapping products. +It supports the anr, rte, and rtd formats as either tracks or +routes. + All options only apply to route files from newer (anr) +versions of DeLorme software; older versions didn't store the turn +information with the route. + + diff --git a/xmldoc/formats/shape.xml b/xmldoc/formats/shape.xml new file mode 100644 index 000000000..fc97f6946 --- /dev/null +++ b/xmldoc/formats/shape.xml @@ -0,0 +1,15 @@ + This format reads and writes ESRI shapefiles as best it can. The +reality is that shapefiles can contain a lot of map-oriented data that does +not convert well to our model of waypoints, tracks, and routes. Points are +mapped to waypoints. Arcs are mapped to tracks. + +If a field is named 'NAME', that will be used for hte shortname. Likewise +for a field named 'URL'. + + +Given the forced fit nature of conversions between shapefiles and other +formats, the results of these conversions are frequently disappointing. +A custom converter (perhaps via a modification to our source) will frequently +deliver better results. + + diff --git a/xmldoc/formats/sportsim.xml b/xmldoc/formats/sportsim.xml new file mode 100644 index 000000000..2be80258a --- /dev/null +++ b/xmldoc/formats/sportsim.xml @@ -0,0 +1,14 @@ + + With this format we support Sportsim trackfiles located in zipped .ssz archives. + + + Currently we cannot read zipped files directly with GPSBabel. So you have + to extract the archive before you can use any file. The trackfiles have .txt extensions. + + +From the Sportsim homepage: + + + Sportsim provide software applications and web-based graphically + simulated performance information and image solutions to outdoor active people. + diff --git a/xmldoc/formats/stmsdf.xml b/xmldoc/formats/stmsdf.xml new file mode 100644 index 000000000..9e2f9e01c --- /dev/null +++ b/xmldoc/formats/stmsdf.xml @@ -0,0 +1,21 @@ + + This format supports the .sdf files from the Suunto product family + 'Suunto Trek Manager', 'Suunto Ski Manager' and 'Suunto Sail Manager'. + The contents of the sdf file depends on the used product and can + be one route or one track. Thatswhy when you want to use sdf on the + output side you have to use the + -r OR the -t option. This will tell + GPSBabel which type of data should be written. + + + Currently we can read the following file types: + + 4 = M9 TrackLog + 5 = Route + 28 = X9 TrackLog + + + gpsbabel -i gpx -f some-routes.gpx -r -o stmsdf,index=3 -F single-route.sdf + + Suunto Website + diff --git a/xmldoc/formats/stmwpp.xml b/xmldoc/formats/stmwpp.xml new file mode 100644 index 000000000..e7129e7db --- /dev/null +++ b/xmldoc/formats/stmwpp.xml @@ -0,0 +1,10 @@ + +This format supports the Suunto Trek Manager (STM) WaypointPlus format. +This is a simple format with coordinates and a time stamp. Route points +also have a short name. A single file may only contain one route or one +track. + + +Suunto Website + + diff --git a/xmldoc/formats/tabsep.xml b/xmldoc/formats/tabsep.xml new file mode 100644 index 000000000..04f7d1fcf --- /dev/null +++ b/xmldoc/formats/tabsep.xml @@ -0,0 +1,12 @@ + +This format, like the custom format, is +mainly used for the purpose of testing GPSBabel. It is supposed to contain +one field for each piece of information supported by the +xcsv format writer, but it may not be entirely +in sync with the documentation at . + + +For a list of fields, see the style/tabsep.style file in the GPSBabel source +distribution. + + diff --git a/xmldoc/formats/tef.xml b/xmldoc/formats/tef.xml new file mode 100644 index 000000000..592632d69 --- /dev/null +++ b/xmldoc/formats/tef.xml @@ -0,0 +1,15 @@ + +TEF, internally called "TourExchangeFormat", is an XML based export format +used by Map&Guide Motorrad-Routenplaner 2005/06. + + +Because this is only an export format, GPSBabel does not support writing to +this format. + + +GPSBabel also supports the bcr format, which +may also be used with this program and supports both reading and writing. + + + gpsbabel -r -i tef,routevia -f in.xml -o gpx -F out.gpx + diff --git a/xmldoc/formats/text.xml b/xmldoc/formats/text.xml new file mode 100644 index 000000000..28431160b --- /dev/null +++ b/xmldoc/formats/text.xml @@ -0,0 +1,8 @@ + This is a simple human readable version of the data file, +handy for listings of any type of waypoint files. + + The following command line reads a GPX file with +Groundspeak extensions and writes a text file with encrypted hints: + +gpsbabel -i gpx -f 12345.gpx -o text,encrypt -F 12345.txt + diff --git a/xmldoc/formats/tiger.xml b/xmldoc/formats/tiger.xml new file mode 100644 index 000000000..0a736c0d2 --- /dev/null +++ b/xmldoc/formats/tiger.xml @@ -0,0 +1,9 @@ + + + + The U.S. Census Bureau provides online mapping facilities. +This format is described at: tiger.census.gov. +Do notice that this format is not the actual Tiger line mapping +records, but rather the interface to their online mapping +program. + diff --git a/xmldoc/formats/tmpro.xml b/xmldoc/formats/tmpro.xml new file mode 100644 index 000000000..255b92762 --- /dev/null +++ b/xmldoc/formats/tmpro.xml @@ -0,0 +1,10 @@ + + + + Reads and writes places files for +use in TopoMapPro places files. As this file +type can store links other than web links, anything that is not a http +url will be discarded. Note that this does not do datum conversions, +so if your input file does not have WGS84/NZGD2000 data, your output +file won't either. Colour of waypoint icons defaults to red. + diff --git a/xmldoc/formats/tomtom.xml b/xmldoc/formats/tomtom.xml new file mode 100644 index 000000000..5da5edc35 --- /dev/null +++ b/xmldoc/formats/tomtom.xml @@ -0,0 +1,15 @@ + + + + This format can read and write TomTom .ov2 (POI) files, +as used by the TomTom GO and TomTom Navigator. It has been tested +with an original TomTom GO running version 5.00 of the TomTom +software. There may be some records that confuse the input module - +if you have an example of such a record "in the wild", and you aren't +restricted from sharing it, we encourage you to post to the +gpsbabel-misc mailing list to contact a developer. + Note that in addition to the .ov2 file, you will need a +.bmp file for the icon. It should be 22x22 and 16 colors, and have +the same name (not including the extension) as the .ov2 file. + + diff --git a/xmldoc/formats/tomtom_asc.xml b/xmldoc/formats/tomtom_asc.xml new file mode 100644 index 000000000..d1209146d --- /dev/null +++ b/xmldoc/formats/tomtom_asc.xml @@ -0,0 +1,5 @@ + + With this format you can read and write TomTom + Points of Interest - POI (ascii) files. + It is a simple text (csv) format with only latitude, longitude and a short name. + diff --git a/xmldoc/formats/tomtom_itn.xml b/xmldoc/formats/tomtom_itn.xml new file mode 100644 index 000000000..dc71e6cd0 --- /dev/null +++ b/xmldoc/formats/tomtom_itn.xml @@ -0,0 +1,3 @@ + + tomtom_itn can be used to read and write TomTom Navigator Itineraries (Routes). + diff --git a/xmldoc/formats/tpg.xml b/xmldoc/formats/tpg.xml new file mode 100644 index 000000000..68cbada63 --- /dev/null +++ b/xmldoc/formats/tpg.xml @@ -0,0 +1,8 @@ + + + + National Geographic Topo! Waypoint and Route Format. This module +reads and writes .TPG files created by various editions of NG Topo! +Reading/writing of route data is not supported yet. +Contributed by Alex Mottram. + diff --git a/xmldoc/formats/tpo.xml b/xmldoc/formats/tpo.xml new file mode 100644 index 000000000..9b9149dfd --- /dev/null +++ b/xmldoc/formats/tpo.xml @@ -0,0 +1,12 @@ + + + + This module reads .TPO files created by various editions +of NG Topo!. For version 2.x files it will only read tracks. For +version 3.x files it will read Tracks/Routes/Waypoints/Map +Notes/Symbols/Text Notes. The latter three are converted to +waypoints. + 2.x support contributed by Steve Chamberlin. 3.x support +contributed by Curt Mills. + + diff --git a/xmldoc/formats/tpo2.xml b/xmldoc/formats/tpo2.xml new file mode 100644 index 000000000..fe1cde696 --- /dev/null +++ b/xmldoc/formats/tpo2.xml @@ -0,0 +1,9 @@ + + This module reads tracks from .TPO files created by + National Geographic Topo! version 2.x + + + Contributed by Steve Chamberlin. + + + diff --git a/xmldoc/formats/tpo3.xml b/xmldoc/formats/tpo3.xml new file mode 100644 index 000000000..ce5d0ff40 --- /dev/null +++ b/xmldoc/formats/tpo3.xml @@ -0,0 +1,6 @@ +This module reads .TPO files created by National Geographic Topo! version +3.x and 4.x. It will read tracks, routes, waypoints, map notes, symbols, and +text notes. The latter three are converted to waypoints. + +Contributed by Curt Mills. + diff --git a/xmldoc/formats/unicsv.xml b/xmldoc/formats/unicsv.xml new file mode 100644 index 000000000..d3162b52c --- /dev/null +++ b/xmldoc/formats/unicsv.xml @@ -0,0 +1,105 @@ + + Unicsv examines the first line of a file to determine the field + order and field separator in that file. On write, it tries to + figure out what data it has and writes headers and all the data it can. + + + If the first line contains any tabs, the data lines are assumed + to be tab separated. Otherwise the fields are assumed to be + separated by commas. + + + The list of keywords include: + + alt = Elevation (in meters) of the point + bng_e = British National Grid's easting + bng = full coordinate in BNG format (zone easting northing) + bng_pos = full coordinate in BNG format (zone easting northing) + bng_n = British National Grid's northing + bng_z = British National Grid's zone + caden = Cadence + comment = Notes + cour = Heading / Course true + date = Date (yyyy/mm/dd) + depth = Depth + desc = Description + ele = Elevation (in meters) of the point + e/w = 'e' for eastern hemisphere, 'w' for western + fix = 3d, 2d, etc. + geschw = Geschwindigkeit (speed) + hdop = Horizontal dilution of precision + head = Heading / Course true + heart = Heartrate + height = Elevation (in meters) of the point + icon = Symbol (icon) name + lat = Latitude + lon = Longitude + name = Waypoint name ("Shortname") + n/s = 'n' for northern hemisphere, 's' for southern + notes = Notes + pdop = Position dilution of precision + prox = Proximity + sat = Number of sats used for fix + speed = Speed + symb = Symbol (icon) name + tempf = Temperature (degrees Fahrenheit) + temp = Temperature (degrees Celsius) + time = Time (hh:mm:ss[.msec]) + url = URL + utc_d = UTC date + utc_t = UTC time + utm_c = UTM zone character + utm_e = UTM easting + utm = full coordinate in UTM format (zone zone-ch easting northing) + utm_pos = full coordinate in UTM format (zone zone-ch easting northing) + utm_n = UTM northing + utm_z = UTM zone + vdop = Vertical dilution of precision + x = Longitude + x_pos = Longitude + y = Latitude + y_pos = Latitude + z = Altitude (elevation) + + We support some enhanced Garmin attributes. They are also available in + gpx, gdb, + garmin_gpi and partly + garmin_txt. These entities are currently + not visible in MapSource (6.12.4), but are NOT dropped + when working with GDB (version 3) or GPX files. + + Please note, that these do NOT provide a geocoding service; don't expect + to "convert" a street address to a latitude and longitude. + + addr = Street address + city = City + country = Country + faci = Facility (not available in GPX) + phone = Phone number + post = Postal code + state = State + + Fuller spellings (i.e. "longitude") may be used. You can also + use keywords with a whitespace instead of an underscore. + + + A typical file may be: + + Name, Latitude, Longitude, Description + GCEBB,35.972033,-87.134700,Mountain Bike Heaven by susy1313 + GC1A37,36.090683,-86.679550,The Troll by a182pilot & Family + + + + + On the output side unicsv writes fixed number of columns (waypoint index, latitude and longitude) + followed by a variable column list depending on internal data. + + + With at least ONE valid timestamp in data a unicsv output may look like that: + + No,Name,Latitude,Longitude,Description,Date,Time + 1,"GCEBB",35.972033,-87.134700,"Mountain Bike Heaven by susy1313",2003/06/29,09:00:00 + 2,"GC1A37",36.090683,-86.679550,"The Troll by a182pilot & Family",, + + diff --git a/xmldoc/formats/vcard.xml b/xmldoc/formats/vcard.xml new file mode 100644 index 000000000..f365dadb0 --- /dev/null +++ b/xmldoc/formats/vcard.xml @@ -0,0 +1,13 @@ + + + + The vCard output is intended to be in a format that +enables waypoints to be viewed with an Apple iPod. This is achieved by +mapping waypoint fields into vCard fields that can be displayed as +'Contacts' on the iPod. With the iPod mounted as a hard disk (see your +iPod manual for instructions), the resulting VCF file should be moved +into the iPod 'Contacts' folder. As an alternative, Mac OS X users may +prefer to drag the VCF file into their address book and synchronize +with the iPod using iSync. + + diff --git a/xmldoc/formats/vidaone.xml b/xmldoc/formats/vidaone.xml new file mode 100644 index 000000000..8cf1447a6 --- /dev/null +++ b/xmldoc/formats/vidaone.xml @@ -0,0 +1,7 @@ + + This format supports the VidaOne GPS for pocket PC GPB file type. + + + This is have a very simple binary format which stores only the coordinates + in the tracklog (.gpb) files. + diff --git a/xmldoc/formats/vitosmt.xml b/xmldoc/formats/vitosmt.xml new file mode 100644 index 000000000..31b80dd4f --- /dev/null +++ b/xmldoc/formats/vitosmt.xml @@ -0,0 +1,10 @@ + + + + Vito Navigator II is a Pocket PC GPS application. This +format reads a Vito Navigator II .SMT track file and can work in +either waypoint or track mode. The speed, heading and Dilution of +Position data is written in the notes field. + Support for writing .SMT tracks is very experimental and +may crash VitoNavigator II on the Pocket PC. + diff --git a/xmldoc/formats/vitovtt.xml b/xmldoc/formats/vitovtt.xml new file mode 100644 index 000000000..8003461f3 --- /dev/null +++ b/xmldoc/formats/vitovtt.xml @@ -0,0 +1,117 @@ + + This format reads the binary (.vtt) track logs recorded by + + VITO SmartMap for Nokia Series 60 + 1.0, a GPS application for smartphones connected to + NMEA 0183-compatible Bluetooth GPS receivers. It may work + with .vtt files produced by versions of VITO SmartMap + for other platforms. + + + + This format was reverse engineered from a .vtt file. + Currently, the coordinates, altitude, and time are + available for each point recorded in a track. + The course speed and heading fields have been identified, + but the units are not certain and so those fields are ignored. + The rest of the entry has not yet been decoded. The format + uses little-endian byte ordering. The application displays + metric units by default. Time is UTC. + + + + track file header (8 bytes) + + + + Position + Field info + + + + + bytes 0-3 + Probably a version field. Int value is 3 in sample file. + + + bytes 4-7 + Number of points in file as int. + + + +
                    + + + track point (32 bytes) + + + + Position + Field info + + + + + bytes 0-3 + Decimal latitude multiplied by 20000000 as int. + + + bytes 4-7 + Decimal longitude multiplied by 10000000 as int. + + + bytes 8-11 + Altitude in meters as float. + + + bytes 12-13 + Year, with century, as int. + + + byte 14 + Month, ranging 1-12. + + + byte 15 + Day of month, ranging 1-31. + + + byte 16 + Hour, ranging 0-23. + + + byte 17 + Minute, ranging 0-59. + + + bytes 18-21 + Decimal second multiplied by 30000000 as int. + + + bytes 22-25 + + Probably speed in meters per second as float. + Ranges 0-~3 in file, seems reasonable since sample + file was acquired on foot. + + + + bytes 26-27 + + Probably decimal heading multiplied by something. + Ranges between min and max values possible when + decoded as integer. Doesn't change when speed field is 0. + Doesn't change smoothly, jumps around a bit. + + + + bytes 28-31 + + Status field of some kind. Changes only twice in file. + May contain satellite count or PDOP info, as both are + reported by the application's GUI. + + + + +
                    diff --git a/xmldoc/formats/wbt-bin.xml b/xmldoc/formats/wbt-bin.xml new file mode 100644 index 000000000..867822664 --- /dev/null +++ b/xmldoc/formats/wbt-bin.xml @@ -0,0 +1,12 @@ +File protocol for the Wintec WBT-200 +and Wintec WBT-201 (sometimes called the G-Rays 2)GPS data loggers. This format reads the binary file format created +by Wintec's Windows application. + +Wintec WBT-201 + + + Command showing conversion of a Wintec binary file to GPX + gpsbabel -i wbt-bin -f tracks.bin -o +gpx -F out.gpx + + diff --git a/xmldoc/formats/wbt-tk1.xml b/xmldoc/formats/wbt-tk1.xml new file mode 100644 index 000000000..4fba4bca0 --- /dev/null +++ b/xmldoc/formats/wbt-tk1.xml @@ -0,0 +1,11 @@ +File protocol for the Wintec WBT-201 / G-Rays 2 +GPS data logger. This format reads the binary file format created +by Wintec's Time Machine X application. + +Wintec WBT-201 + + + Command showing conversion of a Wintec binary file to GPX + gpsbabel -w -t -i wbt-tk1 -f tracks.tk1 -o gpx -F out.gpx + + diff --git a/xmldoc/formats/wbt.xml b/xmldoc/formats/wbt.xml new file mode 100644 index 000000000..8a1845077 --- /dev/null +++ b/xmldoc/formats/wbt.xml @@ -0,0 +1,26 @@ +Serial download protocol for the +Wintec WBT-200 and +Wintec WBT-201 +GPS data loggers. Although untested it is expected that this will also support the WBT-100. + +Wintec WBT-201 + + + Command showing WBT-200 download and erase over Bluetooth on Mac OS X + gpsbabel -t -w -i wbt,erase -f /dev/cu.WBT200-SPPslave-1 -o gpx -F out.gpx + + + +Internally, this is actually a serial device that has a serial/USB adapter +built into it. It uses the CP210x chip by Silicon labs. You will probably +need a driver for this chip. The product ships with one for Windows. +The Linux 210x driver seems to work fine. Mac users will need to download +the Mac driver for CP210x. + + + +GPSBabel does not try to offer an interface to configure these units. That +is left to the Windows software that comes with it or tools like the +WBT 201 Viewer for Mac OS/X +and Linux. + diff --git a/xmldoc/formats/wfff.xml b/xmldoc/formats/wfff.xml new file mode 100644 index 000000000..ac5ebaf1f --- /dev/null +++ b/xmldoc/formats/wfff.xml @@ -0,0 +1,7 @@ + + + + WFFF is the export format for Aspecto Software's WiFiFoFum 2.0 for Windows Mobile PCs. + It is a simple XML format that is read-only to GPSBabel and stores information about a WiFi stumbling session. + All WiFi-specific elements are written in the description field, similar to the netstumbler format. + diff --git a/xmldoc/formats/xcsv.xml b/xmldoc/formats/xcsv.xml new file mode 100644 index 000000000..cc2e9e2ab --- /dev/null +++ b/xmldoc/formats/xcsv.xml @@ -0,0 +1,14 @@ + +This format is a very flexible module that can be used to read or write +nearly any plain-text record-based waypoint file. This flexibility is +achieved by combining this format with "style" files that describe the +format of the waypoint files. + + +There are several formats built in to GPSBabel that use the underlying xcsv +machinery. Each of those formats takes the same options as the xcsv format, +with the obvious exception of the option. +Those formats are all based on style files that can be found in +the "style" directory in the GPSBabel source distribution. + + diff --git a/xmldoc/formats/xmap.xml b/xmldoc/formats/xmap.xml new file mode 100644 index 000000000..5d843e9dd --- /dev/null +++ b/xmldoc/formats/xmap.xml @@ -0,0 +1,10 @@ + + + + Delorme TopoUSA/XMap Conduit is one of the bazillion +CSV variants +variants mentioned above. It's just like Delorme Streets & Atlas with the addition of +a completely pointless line at the beginning and end of the file. This +is the format used to hot-sync to XMap from withing TopoUSA. Done with +help of Dan Edwards. + diff --git a/xmldoc/formats/xmap2006.xml b/xmldoc/formats/xmap2006.xml new file mode 100644 index 000000000..530403ef8 --- /dev/null +++ b/xmldoc/formats/xmap2006.xml @@ -0,0 +1,12 @@ + + + + Delorme XMap2006 Conduit is just like +XMap +, except there are + no spaces between fields and the coordinate format is slightly + different. The completely pointless header and footer lines + are the same, at least. Use this to create the XMapHHWptsSend.txt + file needed to sync to Street Atlas Handheld 2006. + Note that in order to keep from creating duplicates on your handheld, you must first remove the file "XMapWptsDB" from your handheld, restart SAHH2006 on the handheld to create an empty database, and THEN sync the new file. + diff --git a/xmldoc/formats/xmapwpt.xml b/xmldoc/formats/xmapwpt.xml new file mode 100644 index 000000000..3fcb674c7 --- /dev/null +++ b/xmldoc/formats/xmapwpt.xml @@ -0,0 +1,80 @@ + +Delorme XMapHandHeld Street Atlas USA is another of the +billion CSV variants. +This is the format used by XmapHH SA USA on (at least) PocketPC O/S. + + +This XMap is not the same as the simpler +XMap format, which is used with Topo USA 4.0 +and XMapHH for Palm. + + +Delorme XMap Handheld .WPT for PocketPC is a bit of a kludge. This +chapter covers XMap Handheld Street Atlas USA edition. + + +XMap on the PocketPC stores its waypoints in individual .wpt files. +For example, waypoints generated by XMap on the PocketPC are stored +by default in the "My Documents" folder using the sequential names +"XMap1.wpt", "XMap2.wpt", ad nauseum. Needless to say, this is not very +efficient. + + +As writing multiple waypoint files is outside of the scope of GPSBabel, +GPSBabel chooses to write one big file, one waypoint per line. +Extracting lines from this file is left as an exercise for the end user. +A simple Perl script to handle this conversion is included at the end +of this chapter. + + +It should also be noted that reading multiple files +is indeed possible, but if you have more than a few points, it can be a task. +For example: + +gpsbabel -i xmapwpt -f Xmap1.wpt -f Xmap2.wpt -o mapsend -F mapsend.wpt + +will read the two Xmap .wpt files and write one mapsend file. This +is fine for a small handful of points, but could be quite cumbersome +for folks like me who have 100+ waypoints loaded into XMap. For *nix +folks, something as simple as: + +cat *.wpt > /tmp/foo.wpt +gpsbabel -i xmapwpt -f foo.wpt -o mapsend -F mapsend.wpt + +will do the trick just fine. + + +#!/full/path/to/perl +$INPUTFILE = @ARGV[0]; +$TARGETDIR = @ARGV[1]; +$FILENAME = @ARGV[2]; + +if (! $FILENAME) { + print "Usage: xmap_split.pl " . + "INPUT_FILE OUTPUT_DIRECTORY FILENAME_BASE\n"; + print " (i.e. xmapl_split.pl points.wpt /tmp/points GPSB)\n"; + print " (created GPSB0001-GPSBXXXX " . + " in /tmp/points/ from points.wpt)\n"; + exit; +} + +open (INFILE, $INPUTFILE) || die "Cannot open $INPUTFILE for read!\n"; + +while (<INFILE>) { + $lc++; + $filename = sprintf("%s/Gpsb%04d.wpt", $TARGETDIR, $lc); + + open (OUTFILE, ">$filename") || + die "Cannot open $filename for write!\n"; + + print OUTFILE $_; + + close(OUTFILE); +} + +exit; + + + +Contributed to GPSBabel by Alex Mottram. + diff --git a/xmldoc/formats/xol.xml b/xmldoc/formats/xol.xml new file mode 100644 index 000000000..9910e16bb --- /dev/null +++ b/xmldoc/formats/xol.xml @@ -0,0 +1,7 @@ + + This module reads and writes xml based (.xol) files used by + Swiss Map software. + + + These files uses the "Swiss national grid" (CS-1903) to store coordinates. + diff --git a/xmldoc/formats/yahoo.xml b/xmldoc/formats/yahoo.xml new file mode 100644 index 000000000..af379358d --- /dev/null +++ b/xmldoc/formats/yahoo.xml @@ -0,0 +1,7 @@ + +This format reads output from the +Yahoo geocoding API. +This feature of GPSBabel makes it easy to get geocoded results from +Yahoo into your favorite mapping program, GPS receiver, or other format. + + diff --git a/xmldoc/gpsbabel_man.xml b/xmldoc/gpsbabel_man.xml new file mode 100644 index 000000000..ed3a54bc2 --- /dev/null +++ b/xmldoc/gpsbabel_man.xml @@ -0,0 +1,92 @@ + + + + +gpsbabel +1 + + + +gpsbabel + + convert and manipulate waypoints, tracks, and routes between formats. + + + + + +gpsbabel + + + +file + + + +Description + + GPSBabel converts waypoints, tracks, and routes from one format to + another. GPSBabel also downloads and uploads waypoints, tracks, + and routes to and from a GPS receiver (such as those by Garmin and + Magellan) connected by a serial or USB port. + + +
                    + By flattening the Tower of Babel that the authors of various programs + for manipulating GPS data have imposed upon us, it returns to us the + ability to freely move our own waypoint data between the programs and + hardware we choose to use. +
                    + + It contains extensive data +manipulation abilities making it a convenient for server-side processing +or as the backend for other tools. + +Options + + GPSBabel accepts the following options and processes them in order + from left to right.. Additional options are documented in the + docbook help. + + + + format + Use format as the type file to read. + + + name + Use name as the filename to read. + + + format + Use format as the type of file to read. + + + name + Use name as the filename to write. + + + filter + Invoke an internal filter on the data. + + + + Generate smart names for waypoints on output. + + + format + Display help that is more exhaustive than this page. If format is given, provide help for only that format. + + +Lists of filters and formats are given in the doc at http://www.gpsbabel.org. + + +See Also + + http://www.gpsbabel.org + + + + + diff --git a/xmldoc/makedoc.in b/xmldoc/makedoc.in new file mode 100755 index 000000000..e807de9da --- /dev/null +++ b/xmldoc/makedoc.in @@ -0,0 +1,217 @@ +#!/usr/bin/perl + +# +# makedoc.in is used to generate makedoc. +# + +sub expandrw { + my $read = shift; + my $write = shift; + my $type = shift; + + my $res = ""; + if ( ($read eq 'r') || ($write eq 'w')) { + $res .= " \n \n "; + if ( ($read eq 'r') && ($write eq 'w')) { + $res .= "read and write $type"; + } + elsif ( $read eq 'r' ) { + $res .= "read $type"; + } + elsif ( $write eq 'w' ) { + $res .= "write $type"; + } + $res .= "\n \n \n"; + } + $res; +} + +sub expandoptions { + my $opts = shift; + my $res = " \n This format can...\n \n"; + + $res .= expandrw( substr($opts,0,1), substr($opts,1,1), 'waypoints' ); + $res .= expandrw( substr($opts,2,1), substr($opts,3,1), 'tracks' ); + $res .= expandrw( substr($opts,4,1), substr($opts,5,1), 'routes' ); + + $res .= " \n"; + + $res; +} + +sub include { + my $name=shift; + my $dir2=shift; + + $name2 = $name; + $name2 =~ s/-/_/g; + $d2 = $dir2; + $d2 =~ s:/.*::; + $name2 = $d2.'_'.$name2; + print PARTS qq(\n); + print FILE "\&inc_$name2;\n"; + if (! -e "$dir/$dir2/$name.xml") { + open TMP, ">$dir/$dir2/$name.xml"; + print TMP "\n"; + close TMP; + } +} + +sub includef { + my $name=shift; + + $name2 = $name; + $name2 =~ s/-/_/g; + print PARTS qq(\n); + print FORMATS "\&inc_$name2;\n"; +} + + + +@dir=`mkdir -p @DOCDIR@`; +$dir = $0; +$dir =~ s:/.*$::; + + +open PARTS, ">$dir/autogen/_parts.xml"; +print PARTS qq(\n); +print PARTS qq(\n); +print PARTS qq(\n); + +open FORMATS, ">$dir/autogen/_formats.xml"; +print FORMATS qq(\n); + +@formats = `./gpsbabel -^3`; + +$going = 0; +$dooptions = 0; + + +for (@formats) { + chomp; + s/\&/\&/g; + s//\>/g; + @line = split "\t"; + + if ( $line[0] eq 'internal') { + if ($going) { + print FILE "
  • XN#ER2?u9#LNI-XvxSW+PvCN`EBKXPpAVyuq- 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%0D{sq_jCa)6jNvG?sAPg(SoK=YZ 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%0Dia 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�{$M!5! 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 x&TMdD^woF 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 z�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

    \n"; + close FILE; + $going = 0; + } + if ( $line[5] eq 'xcsv' ) { + $line[0] = 'file'; + } + } + + if (($line[0] eq 'file') || ($line[0] eq 'serial')) { + if ($going) { + print FILE "\n"; + close FILE; + } + $id = $line[2]; + if ( $fmts{$id} ) { + $id .= $fmts{$id}++; + } + else { + $fmts{$id} = 1; + } + includef( 'fmt_'.$id ); + open FILE, ">$dir/autogen/fmt_$id.xml"; + print FILE < +
    + $line[4] ($line[2]) +END + print FILE expandoptions($line[1]); + $going = 1; + $dooptions = 1; + if ( defined($line[5]) && ($line[5] ne $line[2]) ) { + print FILE < +This format is derived from the $line[5] +format, so it has all of the same options as that format. + +END + if ($line[5] eq 'xcsv' ) { + $dooptions=0; + } + } + include($id,"formats"); + } + elsif ($going && $dooptions && ($line[0] eq 'option')) { + $nid = 'fmt_'.$id.'_o_'.$line[2]; + print FILE < + <option>$line[2]</option> option + + $line[3]. + +END + include($id.'-'.$line[2],"formats/options"); + print FILE < +END + } +} + +if ($going) { + print FILE "
    \n"; + close FILE; + $going = 0; +} + + +open FORMATS, ">$dir/autogen/_filters.xml"; +print FORMATS qq(\n); + +@filters = `./gpsbabel -%1`; + +$going = 0; + +for (@filters) { + chomp; + s/\&/\&/g; + s//\>/g; + @line = split "\t"; + + if ($going && ($line[0] eq 'option')) { + print FILE < + $line[2] option + + $line[3]. + +END + include($line[1].'-'.$line[2],"filters/options"); + print FILE < +END + } + else { + if ($going) { + print FILE "\n"; + close FILE; + } + includef( 'filter_'.$line[0] ); + open FILE, ">$dir/autogen/filter_$line[0].xml"; + print FILE < +
    + $line[1] ($line[0]) +END + include($line[0],"filters"); + $going = $line[0]; + } +} + + +if ($going) { + print FILE "
    \n"; + close FILE; + $going = 0; +} +close FORMATS; +close PARTS; diff --git a/xmldoc/old/extract b/xmldoc/old/extract new file mode 100755 index 000000000..9b8424bdc --- /dev/null +++ b/xmldoc/old/extract @@ -0,0 +1,4 @@ +#!/bin/sh + +xsltproc --stringparam id $1 extract.xsl ../readme.xml + diff --git a/xmldoc/old/extract.xsl b/xmldoc/old/extract.xsl new file mode 100644 index 000000000..3a0cfb9f0 --- /dev/null +++ b/xmldoc/old/extract.xsl @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/xmldoc/old/readme.xml b/xmldoc/old/readme.xml new file mode 100644 index 000000000..fd26feac0 --- /dev/null +++ b/xmldoc/old/readme.xml @@ -0,0 +1,2296 @@ + + + + + + + GPSBabel Documentation + + + + Introduction +
    + The Problem + There are simply too many gratuitously different file formats +to hold waypoint, track, and route information in various programs +used by computers. GPX (http://www.topografix.com/gpx.asp) defines a +standard in XML to contain all the data, but there are too many +programs that don't understand it yet and too much data that are in an +alternate formats. + +
    +
    + THE SOLUTION + I needed to convert waypoints between a couple of formats, so I +whipped up a converter and based it on an extensible foundation so +that it was easy to add new formats. Most file formats added so far +have taken under 200 lines of reasonable ISO C so they can be stamped +out pretty trivially. Formats that are ASCII text delimited in some +fixed way can be added with no programming at all via our 'style' +mechanism. + +
    +
    + + Getting it and Building it + GPSBabel is distributed in source format that will work on +about any operating system and as ready-to-run binaries for some +operating systems, notably Windows. See the "OS-Specific notes" at +gpsbabel.org for +instructions on those binary kits. + + For operating systems where no binary is provided, you will +have to build it. The code should be compilable on any system with +ISO C89 compilers. It's been tested on UnixWare, OpenServer, OS/X, +Linux, Solaris, and a variety of processors and compilers. + + Libexpat is required for source builds. If you get errors +about expat.h being missing, you must either edit the Makefile to tell +the compiler where it is or install it in a sensible place. Expat can +be downloaded from http://expat.sourceforge.net and is part of Apache so it's very portable. + + + + Usage + + Invocation + Invocation was meant to be flexible. Unfortunately, + that can sometimes lead to unwieldy command lines. + gpsbabel -? + will always show you the supported file types. To use + this program, just tell it what you're reading, where to read + it from, what you're writing, and what to write it to. For + example: + gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx + tells it to read the first file in geocaching.com + format and create a new file in GPX format. + This command will read from a Magellan unit attached + to the first serial port on a Linux system (device names will + vary on other OSes) and write them as a geocaching loc file. + The second command does the same for windows. + gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc + gpsbabel -i magellan -f com1 -o geo -F mag.loc + Optionally, you may specify "-s" in any command line. This + causes the program to ignore any "short" names that may be + present in the source data format and synthesize one from the + long name. This is particularly useful if you're writing to + a target format that isn't the lowest common denominator but + the source data was written for the lowest common + denominator. I use this for writing data from geocaching.com + to my Magellan so my waypoints have "real" names instead of + the 'GC1234' ones that are optimized for NMEA-only receivers. + A geocacher with a Magellan receiver may thus find commands + like this useful. + gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0 + gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1 + + + ADVANCED USAGE + Argument are processed in the order they appear on the command +line and are translated internally into a pipeline that data flows +through when executed. Normally one would: + + read from one input + optionally apply filters + write into one output + + but GPSBabel is flexible enough to allow more complicated +operations such as reading from several files (potentially of +different types), applying a filter, reading more data, then write the +merged data to multiple destinations. + + The input file type remains unchanged until a new + -i argument is seen. + Files are read in the order they appear. So you could merge + three input files into one output file with: + gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc + You can merge files of different types: + gpsbabel -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx \ +-o gpsutil -F big.gps + You can write the same data in different output formats: + gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx 1.wpt + If you want to change the character set of input or/and + output side you can do this with the option . You can get a complete list + of supported character sets with "gpsbabel -l". To change + the character set on both sides you should do this: + gpsbabel -i xcsv,style=foo.style -c latin1 -f foo \ + -o xcsv,style=bar.style -c ms-ansi -F bar + Note, that some formats has a fixed character set and ignore this option. + + + ROUTE AND TRACK MODES + Most formats will make reasonable attempt to work + transparently with waypoints, tracks, and routes. Some + formats, like 'garmin' and 'magellan' require the -t flag to work with tracks and + -r to work with + routes. -w is for + waypoints, and is the default. So if you wanted to read all + data from your unit into a gpx file, you might use a command + like: + gpsbabel -t -r -w -i magellan -f com1: -o gpx -F backup.gpx + Tracks and routes are advanced features and don't try + to handle every possible hazard that can be encountered + during a conversion. If you're merging or converting files + of similar limitations, things work very well. + Tracks and routes will sometimes be converted to a + list of waypoints when necessary, f.i. when writing into one + of the CSV formats. The inverse operation is not supported + right now, so reading the converted track back from CSV will + always result in a list of waypoints, not the original track. + + The presence of -s on the command line tends to + creats havoc on tracks and routes since many of these formats + rely on internal linkages between such points and renaming + them may break those linkages. In general, don't use + -s when tracks or + routes are present. + + + + + The Formats +
    + + DeLorme format + + AN1 + This format supports the DeLorme ".an1" drawing file +format. It can currently be used to either read or write drawing +files. If you use this format to create drawing files with routes or +waypoints from another source, it will currently create "Red Flag" +symbols for waypoints, and thick red lines for routes or tracks. It +is possible to merge two drawing layers by doing something like this: + + gpsbabel -i an1 -f one.an1 -f two.an1 -o an1 -F merged.an1 + In this case, the merged data will contain all of the +properties of the original data. + + If your original data contains geocaching-specific +information such as difficulty and terrain, GPSBabel will +automatically include that information in the waypoint descriptions in +the generated drawing file. If you do not want that, specify the +"nogc" option on the command line: + gpsbabel -i gpx -f 12345.gpx -o an1,nogc -F 12345.an1 + The "deficon" option allows you to specify which symbol to +use for points that don't have a symbol already. It defaults to "Red +Flag" but it accepts any symbol name you can put in a DeLorme export +file. To find the name of a specific symbol in Street Atlas, let the +mouse pointer hover over it for a few seconds and the name will be +displayed. + The "color" option allows you to specify the color for +line or mapnote data. It accepts color names of the form "#FF0000" (red) or any +of the color names from the Cascading Style Sheets (CSS) +specification.i + The "wpt_type" option specifies how to represent point data +in the draw file. Valid waypoint types are "marker", "text", "mapnote", +and "circle". The default is "marker". + If the waypoint type is "circle", the "radius" option specifies +the radius of the circles. By default, this is in miles, but it may be +specified in kilometers by adding a 'k'. The default radius is 1/10 mile. + + The "zoom" option specifies at what zoom level Street +Atlas will begin showing reduced versions of your symbols. The default +is 10. Setting zoom to 0 will disable this feature. Setting it to +anything but the default will override the zoom level specified on any +waypoints that were read from an existing an1 file; this is by design. + + GPSBabel has limited experimental support for other types +of layers besides the default "drawing" layer with the use of two +options: + + The "type" option specifies the type of the drawing layer +to be created. The supported values are "drawing", "road", "trail", +"waypoint", or "track". If you do not specify a type, the default +will be either the type of the previous an1 file or "drawing" if there +is no previous file. This lets you merge, for example, two road layers +without having to specify "type=road" for the output. + If you are creating a road layer, you may also use the +"road" option, which allows you to change the types of roads based on +their names. You can change multiple roads at the same time. +Currently supported types are + + + limited +Limited-access freeways + + toll +Limited-access toll highways + + ramp Access +ramps for limited-access highways + + us National +highways (e.g. US routes) + + primary Primary +State/Provincial routes + + state +State/Provincial routes + + major Major +Connectors + + ferry Ferry +Routes + + local Local +Roads + + editable +User-drawn Roads + + + GPSBabel defaults to creating editable roads. These are +routed just like local roads, but may be edited with the drawing tools +in Street Atlas. + This option has a special format that is best +demonstrated by example: + "road=I-599!limited!Beecher St.!major" + + This option will cause any road named "I-599" to become a +limited- access highway and any road named "Beecher St." to become a +major connector. Note that roads that have had their types changed in +this way are not editable in Street Atlas, so make sure they are where +you want them before you change them, and make sure to keep a backup +of your original road layer. Note that the ! is a shell metacharacter +in bash and possibly other shells, so you may have to use single +quotes or some other escape mechanism. + + There is a tutorial how to create an onramp for a limited access highway in Street Atlas USA using GPSBabel. + +
    +
    + + Dell Axim Navigation System tracklogs + + axim_gdb + This reads the binary .gpb tracks recorded by Dell Axim. + The structure has a fixed record length with + many unknown bytes, but we can extract the common gps data + we need to create nice tracks in any format. For this reason, + this track format is read-only. + +
    + +
    + + Brauniger IQ series + + BAROIQ + Serial download protocol for the Brauniger IQ series of +barograph recording flight instruments. Creates a track of altitude +vs time which can be merged with a GPS track of the same flight to +create a three dimensional IGC file. +
    +
    + + Motorrad Routeplanner 2002 - + + BCR + This file format (extension .bcr) is used in "Motorrad +Routenplaner 2002-..." by Map&Guide. It is a route-onle +format. If you own a newer release (2005...) you can also use the XML +export and convert via gpsbabel ... -i tef +... to your preferred format. May be there are other +products from Map&Guide using the format. + + Coordinates are stored in Mercator format. The +calculation between this and our internal format can result in visible +differences. Experience reports are welcome. + Options: + + - If more then one route are +present in source data, with this option you can determine, which of +this should used for the output. The range is 1 to number routes in +input. If you don't use this, only the first route will be converted. + + + - Not every input format has a real +name for routes in their data. So you can give the route a nice +name. + + - Overwrites the default value of +6371000.0 meters for the earth radius. My be this can help to reduce +differences. + + + Sample BCR command with all options + gpsbabel -r -i gpx -f in.gpx -o bcr,index=1,name="From A to B",radius=6371012 -F a_to_b.bcr + +
    +
    + + Cambridge/Winpilot flight analysis and planning software. + + Cambridge + Support for Cambridge/Winpilot flight analysis and planning software for + glider pilots. +
    +
    + + Cetus, for Palm OS + + CETUS + Cetus GPS www.cetusgps.dk is a program for +Palm/OS. Working with Ron Parker and Kjeld Jensen, we can now read +and write files for that program. +
    +
    + + CompeGPS + + compegps + Suppport for CompeGPS data files. + These data files are "character" separated text files like +the pcx format. "Character" means special data lines can have their +own separator. + Since release 6.1 GPX is also a supported import/export +format for waypoints, routes and tracks. + For more information please have a look at http://www.compegps.com + + Options: + Default Icon name. + Use route/track number +<index> from input data for output. + Give points (waypoints/route +points) a default radius (proximity) + Length of generated short names +(default 16). +
    +
    + + CoastalExplorer (tm) + + coastexp + This is the format used by CoastalExplorer (tm). The +format is XML with items uniquely identified by Windows-style UUIDs. +http://www.rosepointnav.com + +
    +
    + + CoPilot Flight Planner for Palm OS + + CoPilot + This code is mostly intended to convert CoPilot Flight +Planner for Palmd/OS atabases into other formats. You probably should +not use this to write CoPilot databases, although the code is there, +because GPSBabel doesn't convert magnetic declination values. + Questions, bug reports, etc, to ptomblin at +xcski.com + + http://xcski.com/~ptomblin/CoPilot/ +and http://navaid.com/CoPilot + +
    +
    + + cotoGPS, a Palm GPS program + + COTO + Format for cotoGPS, a Palm GPS program. It can read both +track and marker (waypoint) files. It is currently unable to write +track files, so only marker files can be written. The marker +categories are written to and read from the icon description. The 'Not +Assigned' category leaves the icon description empty on read. +Currently geocache info is ignored. + + Options: + + (output) - Name for the Palm 'Not +Assigned' category. Defaults to 'Not Assigned'. + + There is also a debugging option called 'internals' which +takes a XCSV delimiter value. It writes some internal values +(distance, arc, x and y) of the cotoGPS track format to the notes +field. URL: core.de/~coto +Contributed by Tobias Minich. + +
    +
    + + CarteSurTable - French shareware + + CST + With this format we can read CarteSurTable data files. +CarteSurTable is a shareware program widely used in France. The data +inside have to be seen as a mixture of a waypoints list, one route and +several tracks. phgiraud.free.fr + +
    +
    + + Comma Separated Variable, for Delorme S&A +Deluxe + + CSV + There are a billion variants of Comma Separated Value +data. This is the one that makes Delorme S&A Deluxe 9 happy. It's +also a very simple program and useful for many other programs like +spreadsheets. + CSV is also the correct format for Lowrance MapCreate, +their commercial mapping program, or GDM6 (their free waypoint +manager) for iFinder which is available at lowrance.com + +
    +
    + + Plain CSV + + custom + This is a "kitchen sink" CSV format. No known program +will read it, but it's handy for simply converting an arbitrary file +to text so it can be pulled into a spreadsheet or manipulated with +text processing tools. +
    +
    + + Nivitrak DNA marker format + + DNA + Navitrak DNA marker format - Another CSV format file. This +is the format that is compatible with the DNA Desktop import/export +command. Reading the binary Markers.jwp format directly off the data +card is not supported yet. Contributed by Tim Zickus. +
    +
    + + EasyGPS binary format + + EasyGPS + This is the binary file format used by EasyGPS. This +format is seemingly being phased out in favor of GPX in newer versions +of EasyGPS, but this allows conversions to and from the old binary +.loc format. + + + http://www.easygps.com/ + + Information about and sketchy code to implement this file +format were provided by Eric Cloninger. + +
    +
    + + Fugawi CSV format + + Fugawi + This was a requested CSV format, *not* the proprietary +binary format used by Fugawi. Like any other CSV format, GPSBabel +cannot read tracks in this format, but converting a track into it and +then importing as track in Fugawi works. + It is known to work with Fugawi V3.1.4.635. When +importing/exporting waypoints, one has to specify the order of fields +as follows (names of fields may depend on the language used by +Fugawi): + + - Name + - Comment + - Description + - Latidude + - Longitude + - Altitude (metres) + - Date (yyyymmdd/yymmdd) + - Time of day (hhmmss) + + When importing tracks, use "[ignore]" instead of "Name", +"Comment" and "Description". + + http://www.fugawi.com/ + +
    +
    + + Garmin waypoint format + + GARMIN + Waypoint serial upload and download works reliably under +both POSIX and Windows. I originally tested it with a Vista, a V, and +a base eTrex, all graciously provided on loan by Joe Armstrong, but +it's now regularly exercised on a 60CS (USB and serial) and many other +models. The communications library used, jeeps, claims to support +most models of Garmin hardware. Be sure the GPS is set for "Garmin +mode" in setup and that nothing else (PDA hotsync programs, gpsd, +getty, pppd, etc.) is using the serial port. + + GPSBabel supports the USB Garmins under Windows and on +Linux and OS/X via libusb. It's reported successful with VistaC, +SummitC, 60C, 60CS, 76C, 76CS, 96C, and Quest. Some users report +success with StreetPilot 2610 and some do not, but nobody's followed +up with details on that. + + Currently, only a single USB unit at a time can be +supported. The device name to use on the command line is "usb:" Thus, +to read the waypoints from a Garmin USB unit and write them to a GPX +file: + + gpsbabel -i garmin -f usb: -o gpx -F blah.gpx + When reporting problems with Garmin, be sure to include +the full unit model, firmware version, and be prepared to offer +debugging dumps by adding "-D9" to the command line, like: + + gpsbabel -D9 -i garmin -f usb: -o gpx -F blah.gpx + Custom icons are supported on units that support that. +Neither GPSBabel nor your firmware know what is associated with any +given slot number. They don't know that the picture you placed in the +first slot is a happy face, they only know they're in the lowest +numbered slot. GPSBabel names the them consistently with Mapsource, +so they are named 'Custom 0' through 'Custom 23'. + +
    + +
    + + Garmin POI Database. + + garmin_poi + The Garmin POI loader +loads custom points of interest into certain models of +Garmin GPS receivers. (As of this writing, only the models introduced +in 2005 and later are supported. See Garmin's site for more info.) +This is the format readable that that program. +
    + +
    + + Garmin MapSource Text Export (tab delimited). + + garmin_txt + + garmin_txt is a format that contains nearly all information as in the MapSource main format, GDB. +garmin_txt has some computed values like distances between routepoints and trackpoints, speed, and course (heading) in addition to the standard data fields. + + +The main goal of garmin_txt is to make aviation data more available. Because +MapSource supports only the export, GPSBabel gives you the possibility to +bring aviation data into MapSource. + + +During the export with MapSource, some fields are written using local settings +of MapSource and Windows. These include grid format, gps datum, distance and +temperature units, and the representation of date and time fields. GPSBabel +tries to read all items automatically. Problems with date and time format can +be solved with the options 'date' and 'time'. + + Options: + - input/output date format (Windows-like. For example "YYYY/MM/DD") + - write coodinates using this (GPSBabel known!) datum + - output unit for distance values, M (=metric, m/km/kph) or S (=statue, ft/mi/mph) + - write coordinates with precision # (# numbers behind dot) + - output unit for temperature values, C (=celsius) or F (=fahrenheit) + - input/output time format (Windows-like For example, "hh:mm:ss xx") + - write timestamps x hours relative to UTC + + Command showing garmin_txt output with all options + gpsbabel -i garmin_txt,date="MM/DD/YYYY",time="hh:mm:ss xx" \ + -f in.txt \ + -o garmin_txt,date="DD.MM.YYYY",datum="WGS 72",dist=m,prec=6,temp=c,time="HH:mm:ss",utc=+2 \ + -F out.txt + + +
    + +
    + Garmin 301 data. + garmin301 This is a very simple format that +is most useful for exporting data from a Garmin301 to other programs +for analysis. It's a simple comma delimited format that includes the +timestamp, 3D position information and heart rate so you can pull it +into a spreadsheet or graphing program. +
    + +
    + + GeocachingDB format + + Gcdb + This is the GeocachingDB by DougsBrat. It works with v2 +and v3 of this program. See vip.hyperusa.com + +
    +
    + + Garmin GPS Database (as in MapSource) +format + + GDB + Support for the "Garmin GPS Database" format used by +default in MapSource versions since release 6.0. By default we create +gdb's of version 2. Version 2 is used in Mapsource 6.3 and 6.5. + + Garmin GPS database is an undocumented file format. The +basic info for this module comes from the existing MapSource +conversion code. + + Additional options: + + - set the data format version of the +output file (currently 1 or 2); 2 is our default. + + - Drop hidden route points (means +calculated stuff) + + - default category on output +(1..16) +
    +
    + + geocaching.com .loc file format + + GEO + geocaching.com spits up geocaching.loc files that are +XML-ish but not quite GPX. Becuase it's so close to GPX, this format +is very well supported. +
    +
    + + GeocachingDB PDA format + + Geocaching DB + This is a PDA file format. It was tested against version +2 of GeocachingDB and a development snapshot of version 3. Information +on the file format came from Dougs Brat and Ron Parker. A +particularly handy way to use GPSBabel on these files is to use +GPSBabel to read a GPX file with Groundspeak (geocaching.com) +extensions and let it write you a GeocachingDB file that contains the +cache names, difficulty, terrain, and such. + + vip.hyperusa.com + +
    +
    + + GEOnet Names Server country file format +(input) + + GEOnet + Input support for the GEOnet Names Server (GNS) country +file structure. Export to this format is not possible, as this format +has too many fields that we never get populated by any other +format. +
    +
    + + Geoniche - Palm format for off-road users + + geoniche + Geoniche is a Palm/OS application oriented for the +off-road user. This module was contributed by Rick Richardson. See +nwlink.com + +
    +
    + + Garmin logbook format for Forerunner and +ForeTrex + + glogbook + This is the XML format used by the Garmin Logbook product +that ships with Forerunner and Foretrex. http://www.garmin.com + +
    +
    + + Google maps routes + + GOOGLE + This format is designed to read the XML emitted when you +tack "&output=js" onto the end of a Google Maps route URL (use +the "link to this page" option to get a usable URL.) This allows you +to plan a route using Google Maps, then download it and use it in your +own mapping program or GPS receiver. If you use a Unix-compatible +operating system, this shell script might be useful: + + +#!/bin/sh +FROM="233 S. Upper Wacker Dr, Chicago, IL" +TO="1060 W. Addison St, Chicago, IL" +wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" \ +2&>/dev/null >google_map.js +gpsbabel -i google -f google_map.js -o gpx -F google_map.gpx + + Note that Internet Explorer has been observed to damage +the XHTML beyond recognition so use a better browser to save the pages +such as Firefox or Mozilla. + +
    +
    + + Palm OS format for GPilots + + GpilotS + This is a Palm/OS file format for GPilotS. It was tested +against version 6.2. + + + http://www.cru.fr/perso/cc/GPilotS/ + + Neither tracks nor routes are supported at this +time. +
    +
    + + Delorme gpl format + + gpl + This is the 'gpl' format as used in Delorme mapping +products. It is a track format and contains little more than the +tracklog of a GPS that was attached while driving. frontiernet.net + +
    +
    + + GpsDrive way.txt file format. + + GPSDRIVE + GpsDrive way.txt file format. A space seperated format +file. Tested against GpsDrive v 1.30 found at kraftvoll.at. +Contributed by Alan Curry. +
    +
    + + GpsDrive saved track format + + GPSDRIVETRACK + Format used by GpsDrive to save tracks. Like GPSDRIVE a +space seperated format file. See above for a link to GpsDrive. +Contributed by Tobias Minich. +
    +
    + + GPS Manager format (WGS84, DDD) + + GPSMAN + GPS Manager can read and write formats that this +converter doesn't understand. The default formats (WGS84, DDD) work +reliably. +
    +
    + + GPSPILOT file format + + GPSPILOT + The file format for GPSPILOT gpspilot.com was provided by Ron +Parker. The output from this module has been tested with GPSPilot +Tracker v5.05sx, but it is based on reverse-engineering so it may not +work with all versions of all GPSPilot products. It had read-only +support for Airport, Navaid, City and Landmark files but will read and +write Point files. +
    +
    + + GPSUtil file format + + GPSUTIL + GPSUtil has a simple file format of this program that runs +on POSIX- compliant OSes like UNIX and Linux. Reads and writes of +this format are reliable. (I've also contributed to this program.) +It's available at cs.uakron.edu. +
    +
    + + EasyGPS, ExpertGPS etc format. + + GPX + This is the most capable and expressive of all the file +formats supplied. It is described at topografix.com and is +supported by EasyGPS, ExpertGPS, and many other programs described at +topografix.com + +
    +
    + + GPS TrackMaker format. + + GTM + Input and output support for waypoints, tracks and routes in + the GPS TrackMaker + binary format. + Code implemented by Gustavo Niemeyer. +
    +
    + + Mac OS HikeTech formats. TopoDraw, Link2GPS & +GPSWrite + + Hiketech + This is the .gps format used by the Mac OS X applications +written by HikeTech. These include TopoDraw, Link2GPS, and GPSWrite. +More information about these products can be found at hiketech.com + +
    +
    + + Holux format (Holuxgm-100) + + HOLUX + The Holuxgm-100 (e-fox) gps receiver uses standard +compact flash cards. File formats were provided by Holux-Taiwan +holux.com to the author. +The code was tested against version 2.27E1; other versions and +receivers may work but have not been explictly tested. Anyone with +information on other Holux receivers is encouraged to contact +jochen@bauerbahn.net. + + When copying the .wpo file to a flash card, the file must +be named tempwprt.wpo as the +receiver will ignore all other files. + + Comparing the waypoints of a .wpo files against other +formats like .gpx you may notice a small difference in the latitude +and longitude values. The reason is the low resolution of the +coordinates in the wpo file format. In a .wpo file the reolution is +1/10"; in gpx for example it is 1/100". A a practical matter, this +loss is only about 1.7 meters (5 feet). + + The generated waypoint failes can also be used by MapShow +version 1.14. This program is free of charge from the Holux web site. + + This format was contributed by Jochen Becker. + +
    +
    + + HSA Systems Endeavour Navigator format + + hsandv + HSA Systems Endeavour Navigator format - will import both +the old version 4.x binary files, and the newer XML based ones. Only +writes the new XML (5.0 and above) format. (use the .exp +extension) +
    +
    + + HTML format + + HTML + HTML output generates a single HTML file of all of the +waypoints in the input file. It supports a number of Geocaching GPX +extensions, as well as filters out potentially harmful HTML from the +input file while maintaining almost all of the source HTML formatting. +Use the 'stylesheet' option to specify a CSS stylesheet to be used +with the resulting HTML file. Use the 'encrypt' option to encrypt +hints from Groundspeak GPX files. Use the 'logs' option to include +Groundspeak cache logs. + + The following command line reads a GPX file with +Groundspeak extensions and writes an HTML file with encrypted hints +that is rendered using a custom stylesheet: + + gpsbabel -i gpx -f 12345.gpx \ + -o html,stylesheet=green.css,encrypt -F 12345.html + +
    +
    + + FAI/IGC Data file format + + IGC + FAI/IGC Data File -- Used by the international gliding +community to record gliding flights. IGC files can be converted to +and from tracks representing recorded flights, and routes representing +task declarations in other formats. +
    +
    + + IGN Rando track file format + + IGNRando + Input and output support for IGN Rando track files. IGN +Rando is a program mainly used in France for Topo maps. The files are +XML based and are "windows-1252" encoded. Trackpoints come without +timestamp. + + Options: + + + - Use track number <index> +from input data for output. The range is 1 to number of tracks in +input. + +
    +
    + + Keyhole Markup Language format. + + KML + KML, the Keyhole Markup Language, is used by Keyhole and +Google Earth. (Google Earth uses GPSBabel internally for receiver +communications and several file format imports and exports. There are +features in this file format that we don't support such as camera +views, but waypoints, tracks, and routes work well. + Additional options: + + (default n=1) Draws lines between +points in tracks and routes when n is non-zero. + + (default n=1) Draws placemarks +for tracks and routes when n is non-zero. + + (default n=6) Width of drawn +lines, in pixels. + + (default=65eeee17) Line +colour specified in hex AABBGGRR. + + (default n=0) Altitudes are +not clamped to ground when n is non-zero. This option is more useful +to pilots than to hikers. +
    +
    + + Kartex 5 waypoint + + kwf2 + Support for Kartex 5 waypoint files. Kartex is a Swedish + map and GPS positioning system. GPSBabel can read and write + files from Kartex 4 and 5 with WGS84 coordinates. UTM or + Swedish grid are not supported. + +
    +
    + + Kartex 5 trackfiles + + ktf2 + Support for Kartex 5 trackfiles. For more info see kwf2. +
    +
    + + Lowrance iFinder .USR format + + LowranceUSR + The Lowrance iFinder GPS series has the unique capability +to output its data to an MMC card. The data is saved to the card as a +.USR file and can be read by your computer using a card reader. +Waypoints, routes, tracks are supported. By default, Event marker +icons are converted to waypoints. Symbols tend to get lost in the +translation. + Additional options: ignoreicons - don't convert icons to +waypoints merge - (USR output) merge all tracks into a single track +with segments break - (USR input) break track segments into separate +tracks +
    +
    + + Palm OS for Map & Guide format + + mag_pdb + With this format we support the Palm/OS export for +Map&Guide based products like "PowerRoute", +"Motorrad-Routenplaner" and (maybe) other software. The exported files +can contain maps and/or route descriptions. The reader for this format +has been tested with PowerRoute 5+6, Motorrad-Routenplaner +2002(-2006). +
    +
    + + Magellan format + + MAGELLAN + Waypoint serial upload and download works reliably to the +315, 330, Meridian, and SportTrak family. I expect it to work on any +modern Magellan unit. + As of 08/30/02, GPSBabel can also read and write the +files that can be stuck on the SD memory cards with the Meridian +models. Simply specify a file instead of a serial port. + Communication errors are handled robustly and +verification of data is enabled. + Additional suboptions: baud: may be 1200, 2400, 4800, 9600, +19200, but must match receiver. +
    +
    + + Magellan Explorist format + + MAGELLANX + The SD card format used by the Magellan Explorist 400, +500, and 600. It's identical to the Magellan SD format used by +Meridian, but allows longer waypoint names. + You should name any file created with this format with a +".upt" extension so the firmware can read it. +
    +
    + + Magellan SD card format + + MAGGEO + The SD card format used by the Magellan Explorist 400, +500, and 600 to describe geocaches. Notice what while the format can +hold an infinite number of geocaches, the unit will read and silently +discard all but 200 geocache POIs at a time. + You should name any file created with this format with a +".gs" extension so the firmware can read it. + +
    +
    + + Magellan Nav Companion format + + MAGNAV + Magellan NAV Companion for Palm/OS is not really designed +for this sort of use, but its file format is supported and with a +little bit of patience you can both read and write NAV Companion +waypoints. Please read README.magnav for further tips on getting +waypoints in and out of NAV Companion. This conversion is based on +partially incomplete reverse-engineering of the record format, so it +may not work with all versions of NAV Companion. It has been tested +with version 2.10 and 3.20. +
    +
    + + Mapconverter format from Mapopolis + + mapconverter + Mapconverter is a format this is read by Mapopolis.com's +mapconverter application. Full details of it's usage are available in +the file README.mapconverter. +
    +
    + + Magellan Mapsend format + + MAPSEND + Magellan was smart enough to document their file format to +make creating software like this possible. + Additional options: + + - set the MapSend version to generate TRK files, +since new MapSend versions can't open V3 files. Options are 3 (MapSend v3.0) or +4 (MapSend v4.0 and v4.1). + +
    +
    + + Garmin Mapsource format + + MAPSOURCE + Garmin Mapsource format appears compatible with the +various members of that product family. Icon mapping is attempted +between different MapSource versions. Altitude is supported, but +proximity and depth are not. Naming files *.mps will allow +file->open in Mapsource to find the files more easily. Versions 3, +4 and 5 of the Mapsource data format are handled automatically on +input and by default the output is version 5. (Until 3/2004, it was +version 3, but since Mapsource updates are free, the convenience of +having modern icon sets outweighs the backward compatibility concern. +Users of other versions can either upgrade or specify the switches to +get get output in a compatible format.) Waypoints, routes and +tracklogs are all handled, but maps sets are ignored. + + Information on the Garmin Mapsource format was provided +by Ian Cowley and Mark Bradley. The code was implemented by Robert +Lipe and Mark Bradley. + Additional options: + + - set the length of generated +shortnames + + - set the data format version +of the output file (3,4 or 5) + + - if the output file already +exists, then the output is merged with it. This allows MapSource +sections not being handled to remain intact (e.g. map sets) +
    +
    + + Microsoft Autoroute 2002-2006 reader + Microsoft Streets and Trips reader + + MSroute + Input support for Microsoft AutoRoute 2002-2006 .axe files +and Microsoft Streets and Trips .est files. +These files contains only routes. We can extract the coordinates and +the names of the points within route. An export to this format will +not be supported. + Only the start, stops, and end points are stored in the +.est/.axe/.ptm files. Turn-by-turn route data is not stored in the +.est/.axe/.ptm files, and is recalculated by the Microsoft title each +time on opening the file. This means that the output of GPSBabel will +not contain turns needed for driving directions. + One possible approach to achieve similar results is to +use the Streets and Trips drawing tools to trace a line over the +interesting parts of the route to capture intersections or key turns. +GPSBabel will capture stops in the route and insert those as turns, so +adding stops at intersections can also improve the results when converting. + +
    +
    + + Maptech Exchange format. + + MXF + Maptech Exchange Format - Another CSV format file. This +format complies with (at least) Maptech Terrain Navigator, Terrain +Professional, Take a Hike, and ExpertGPS import/export MFX. +Contributed by Alex Mottram. +
    + +
    + + NetStumbler CSV summary file format + + Netstumbler + NetStumbler 0.4 Summary File -- Another CSV format file. +The default behavior when creating waypoints is to use the SSID for +the short name, and information about the access point for the +description. When the SSID is not unique, is not available, or +consists of whitespace, a shortname is synthesized. The snmac option +uses the MAC address for the shortname, and includes the unmodified +SSID in the description. Different icons are assigned to encrypted, +non-encrypted, stealth, and non-stealth access points; these may be +changed with options. Import only. + +This format also works with MacStumbler. + Additional options: + + - Name of icon used for +non-stealth non-encrypted access points + + - Name of icon used for stealth +encrypted access points + + - Name of icon used for stealth +non-encrypted access points + + - Always use the MAC address as the +shortname. +
    +
    + + National Imagery and Mapping agency +format + + NIMA + This is a CSV format from the National Imagery and Mapping +Agency. +
    +
    + + NMEA0183 log and waypoint format + + nmea + This format is the file representation of the NMEA0183 +log and waypoint format. Representative programs include: + + genimap.fi + + + homepages.tig.com.au + + + gpstm.com + + + gpsmaster.nl + + + silcom.com/~rwhately + + + visualgps.net + + + gpsu.co.uk + + + kolumbus.fi + + + commlinkx.com + +
    +
    + + Navigon Mobile Navigator route (.rte) +files. + + nmn4 + Support for Navigon Mobile Navigator route (.rte) files. +This is a very simple text format that only requires coordinates, but +has fields for many other things. We only write coordinates as fields +like 'city' and 'street' cannot typically be populated from other +formats. www.navigon.com + +
    +
    + + Tab seperated file format - numerical +processing + + OPENOFFICE + Tab seperated export-all (except geocaching data) file +format. Intended to serve as source for number-processing +applications like OpenOffice, Ploticus and others. Tab was chosen as +delimiter because it is a) supported by both OpenOffice and Ploticus +and b) is not ',', so you can use sed -i +"s/./,/g" <x>.csv' to adapt it to locales where ',' is +used as decimal seperator. Contributed by Tobias Minich. +
    +
    + + OziExplorer Waypoint Format + + OZI + OziExplorer Waypoint Format - Another CSV format file. +Tested against OziExplorer v 3.90.3a / Shareware. Contributed by Alex +Mottram +
    +
    + + PalmDoc output format + + PALMDOC + PalmDoc output is similar to Text output, except that it +generates a Palm Database (PDB) file suitable for use with programs +like CSpotRun, TealDoc, AportisDoc, Palm Reader, and others. The +resulting file also contains bookmarks to make it easy to jump to a +particular waypoint. To suppress the dashed lines between waypoints, +use the 'nosep' option. To specify a name for the document, use the +'dbname' option. Use the 'encrypt' option to encrypt hints from +Groundspeak GPX files. Use the 'logs' option to include Groundspeak +cache logs. If you would like the generated bookmarks to start with +the short name for the waypoint, specify the 'bookmarks_short' option. +This is particularly useful when used in combination with the 'sort' +filter. + + The following command line reads a GPX file with +Groundspeak extensions and writes a Palm document with encrypted hints +and logs: + + gpsbabel -i gpx -f 12345.gpx \ -o + "palmdoc,dbname=Unfound Geocaches,encrypt,logs" \ + -F 12345.pdb + +
    +
    + + PathAway for Palm file format + + PathAway + PathAway is a Palm software designed for handling "most" +GPS devices (including BlueTooth). In this time (I mean 2005) a free +tool to convert this database is located on the homepage of PathAway +(www.pathaway.com). But I've read there ... for windows and the output +formats are also very limited. + +
    +
    + + Garmin PCX format + + PCX + Garmin documents only PCX5, an older format limited to +the lame NMEA six-character waypoint names that's treated as a +second-class citizien in current versions of MapSource. In Mapsource, +use file->import to read these files. If you name the files *.wpt, +Mapsource will find them easier. + + In general, you should prefer the "mapsource" file format +to this one. + +
    +
    + + KuData's Psion PDA format + + PsiTrex + This is a text format created by KuDaTa's PsiTrex program +for the Psion PDAs. The format can't be readily handled by XCSV, so +this format is handled explicitly. Waypoints, routes and tracks are +all handled, with icon names used corresponding to verison 1.13 of +PsiTrex. This module was contributed to GPSBabel by Mark +Bradley. +
    +
    + + Microsoft PocketStrees 2002 pushpin +format + + PSP + Microsoft's PocketStreets 2002 Pushpin (.PSP) format is +not yet completely documented. THE .PSP MODULE DOES NOT WORK WITH MS +STREETS & TRIPS 2002 .EST FILES. To create .PSP files from +Streets & Trips 2002, you will need to have PocketStreets support +installed. + + Please note that MS Streets & Trips only *EXPORTS* +.PSP files. It does not import them. MS Streets & Trips 2002 only +imports CSV files. To use .PSP files, simply copy them over to the +same folder on the mobile device as the map (.MPS), and open +PocketStreets. It should also be noted that in the case a pushpin is +outside of the exported map area, the pin will be "grayed-out" and +unused in PocketStreets. This is a good thing as it allows us to +create one big .PSP file that covers multiple .MPS files. +Unfortunately, you need one .PSP file for every .MPS file. :( +
    +
    + + QuoVadis for Palm OS format + + QUOVADIS + QuoVadis for Palm OS marcosoft.com is a program for +Palm/OS. Working with record definitions provided by MarcoSoft and +further experimentation by Bruce Thompson and "Fuzzy" from the +Geocaching Forums to nail down the format precisely. + Should work fine for import and export. + One thing of note, QuoVadis stores all waypoints in a +single Palm Database without using categories. This means that it may +be difficult to keep personal waypoints separate from generated +waypoints. What Bruce recommends is taking the QuoVadisMarkerDB.PDB +file synced down from your Palm Powered device and extract the +waypoints you personally set to a GPX file. Then using GPSBabel's +joining capabilities generate a new PDB file from the personal file +and the other waypoint files of interest. + Currently the selection of icons to display and the scale +at which to display them is hardcoded. Also there is no support for +notes associated with waypoints. This will be addressed in a future +revision. +
    +
    + + Microsoft Streets and Trips import format + + s_and_t + This is a format for importing into Microsoft Streets and +Trips. It's been exercised on versions 2003, 2004, and 2005. Detailed +instructions on how to use it, including preserving hyperlinks, are at +gpsbabel.org + +
    +
    + + Street Atlas USA 2004 Plus format + + saplus + This format is for Street Atlas USA 2004 Plus. + + For geocachers importing data from a tool like GSAK or +Spinner, import the file twice in XData. One will create a file with +the Cache description as a hyperlink on the flag. This can clutter up +the screen and when you try to zoom in, it causes problems. So the +second one will only have a flag. Thus you can turn off and on which +one you want to view. The first time you import the file, in the +assign field types, check the circle above Full Name and then next. +The second time you import the file do not check any circle and in the +second to last column, change URL to none and then click next. Use the +same name you used the first time but add -Flag to it. + +
    +
    + + Delorme (anr, rte, rtd files) + + saroute + This is a catch-all used by many Delorme mapping products +and reads the anr, rte, and rtd formats as either tracks or +routes. + The 'turns_only' option causes GPSBabel to read only the +waypoints associated with named turns. This should create a list of +waypoints that correspond to the itinerary from Street Atlas. + The 'turns_important' option only makes sense in +conjunction with the 'simplify' filter. It ensures that the route +simplification process will remove the points corresponding to turns +only after it has removed all other route points. + + The 'split' option causes GPSBabel to create separate +routes for each street, creating a new route at each turn point. For +obvious reasons, 'split' cannot be used at the same time as the +'turns_only' or 'turns_important' options. + The 'controls' option lets you read the control points +(start, end, vias, and stops) for your route as well as the route +itself. The default for this option is 'none', which won't read the +control points. You may also specify 'waypoints', which reads the +control points as waypoints, or 'route', which creates an extra route +named 'control points' containing just the control points in order. +Note that if your goal is to create an arc or other CSV file, you +should use 'none' (or not use this option, which is the same +thing.) + The 'times' option causes GPSBabel to read the route as if +it were a track, synthesizing times starting from the current time, using +the estimated travel times specified in your route file (you can change your +travel speeds in the DeLorme product you used to create the route file.) + All options only apply to route files from newer (anr) +versions of DeLorme software; older versions didn't store the turn +information with the route. + +
    +
    + + SeeYou flight analysis and planning software. + + SeeYou + Support for SeeYou flight analysis and planning software for + glider pilots. Tasks, runway info, and most other data specific + for glider pilots is not preserved, but this is a convenient way + to get your flight data in other programs. www.seeyou.ws +
    +
    + + Suunto Trek Manager WaypointPlus format. + + STMwpp + Support for Suunto Trek Manager (STM) WaypointPlus +format.. Simple structure with coordinates and timestamp. Route +points (waypoints) have additionaly shortname. The files can only +contain one route or one track. www.suunto.fi + + + Options: + + + - Use route/track number +<index> from input data for output. + +
    +
    + + Unix tab seperated file format + + tabsep + Dumps all fields in a traditional Unix tab separated +style. +
    +
    + + TourExchangeFormat. for Map&Guide + + TEF + TEF, internal called "TourExchangeFormat", is a XML based +export format, used by Map&Guide "Motorrad-Routenplaner 2005/06". +Another posibility to exchange data with this are the .bcr files, +which are supported by GPSbabel in both directions (see BCR). + + Via XML this software can only export routing data. So we +don't support writing. With the option "routevia" you can eliminate +calculated route points from tef source file. + gpsbabel -r -i tef,routevia -f in.xml -o gpx -F out.gpx +
    +
    + + Plain text, for people + + TEXT + This is a simple human readable version of the data file, +handy for listings of any type of waypoint files. Use the 'nosep' +option to suppress the lines of dashes between entries. Use the +'encrypt' option to encrypt hints from Groundspeak GPX files. Use the +'logs' option to include Groundspeak cache logs. + + The following command line reads a GPX file with +Groundspeak extensions and writes a text file with encrypted hints: + + gpsbabel -i gpx -f 12345.gpx -o text,encrypt -F 12345.txt + +
    +
    + + US Census Bureau mapping format + + TIGER + The U.S. Census Bureau provides online mapping facilities. +This format is described at: tiger.census.gov. +Do notice that this format is not the actual Tiger line mapping +records, but rather the interface to their online mapping +program. +
    +
    + + TopoMapPro places file + + TMPRO + TopoMapPro Places File. Reads and writes places files for +use in TopoMapPro topomappro.com). As this file +type can store links other than web links, anything that is not a http +url will be discarded. Note that this does not do datum conversions, +so if your input file does not have WGS84/NZGD2000 data, your output +file won't either. Colour of waypoint icons defaults to red. +
    +
    + + TomTom .ov2 POI files + + TomTom + This format can read and write TomTom .ov2 (POI) files, +as used by the TomTom GO and TomTom Navigator. It has been tested +with an original TomTom GO running version 5.00 of the TomTom +software. There may be some records that confuse the input module - +if you have an example of such a record "in the wild", and you aren't +restricted from sharing it, we encourage you to post to the +gpsbabel-misc mailing list to contact a developer. + Note that in addition to the .ov2 file, you will need a +.bmp file for the icon. It should be 22x22 and 16 colors, and have +the same name (not including the extension) as the .ov2 file. + +
    +
    + + National Geographic Topo Waypoint format. + + TPG + National Geographic Topo! Waypoint and Route Format. This module +reads and writes .TPG files created by various editions of NG Topo! +Reading/writing of route data is not supported yet. +Contributed by Alex Mottram. + The option 'datum="datum name"' can be used to override +the default of NAD27 ("N. America 1927 mean") which is correct for the +continental U.S. Points in Hawaii should use "Old +Hawaiian_mean" + Contributed by Alex Mottram. +
    +
    + + National Geographic Topo! Track Format. + + TPO + This module reads .TPO files created by various editions +of NG Topo!. For version 2.x files it will only read tracks. For +version 3.x files it will read Tracks/Routes/Waypoints/Map +Notes/Symbols/Text Notes. The latter three are converted to +waypoints. + 2.x support contributed by Steve Chamberlin. 3.x support +contributed by Curt Mills. + +
    +
    + + Universal csv with field structure in first line. + + unicsv + + Unicsv examines the first line of a file to determine the field + order and field separator in that file. It is thus read-only format. + + + If the first line contains any tabs, the data lines are assumed + to be tab separated. Otherwise the fields are assumed to be + separated by commas. + + + The list of keywords include "lat", "lon", "desc", "name", + "notes", "alt", "urm z", "utm n", "utm e", and "url". + Fuller spellings (i.e. "longitude") may be used. + + + A typical file may be: + + Name, Latitude, Longitude, Description + GCEBB,35.972033,-87.134700,Mountain Bike Heaven by susy1313 + GC1A37,36.090683,-86.679550,The Troll by a182pilot & Family + + +
    +
    + + vCard format for Apple iPod etc. + + vCARD + The vCard output is intended to be in a format that +enables waypoints to be viewed with an Apple iPod. This is achieved by +mapping waypoint fields into vCard fields that can be displayed as +'Contacts' on the iPod. With the iPod mounted as a hard disk (see your +iPod manual for instructions), the resulting VCF file should be moved +into the iPod 'Contacts' folder. As an alternative, Mac OS X users may +prefer to drag the VCF file into their address book and synchronize +with the iPod using iSync. By default hints are unencrypted; use the +'encrypt' option to encrypt the hints. +
    +
    + + Vito Navigator II format + + VitoSMT + Vito Navigator II is a Pocket PC GPS application. This +format reads a Vito Navigator II .SMT track file and can work in +either waypoint or track mode. The speed, heading and Dilution of +Position data is written in the notes field. + Support for writing .SMT tracks is very experimental and +may crash VitoNavigator II on the Pocket PC. +
    +
    + + Aspecto Software's WiFiFoFum + + wfff + WFFF is the export format for Aspecto Software's WiFiFoFum 2.0 for Windows Mobile PCs. + It is a simple XML format that is read-only to GPSBabel and stores information about a WiFi stumbling session. + All WiFi-specific elements are written in the description field, similar to the netstumbler format. +
    +
    + + For user supplied style files + + XCSV + XCSV is an open-ended "Whatever Separated Values" parser +/ writer designed to work with user-supplied "style" files. It should +handle at least a few thousand of the billion CSV variants available. +By itself, it doesn't comply to any format, however *most* CSV +variants can be described as a "style" and fine-tuned by the end user. +For more information on it's use, please see README.style in the +style/ sub-directory of GPSBabel. +For an example of using the XCSV module within your C program, look at +the ozi.c, mxf.c, and xmapwpt.c sources in the GPSBabel +directory. This module was contributed to GPSBabel by Alex +Mottram. + Additional Options: + + - **REQUIRED** Path to +XCSV style file. + + - Maximum length of +synthesized shortnames. + + - Switch defining +whether or not to allow whitespace in synthesized shortnames. (0 = NO +WHITESPACE, 1 = WHITESPACE OK). + + - Switch defining +whether or not to force uppercase in shortnames. (0 = LEAVE AS IS, 1 += UPPERCASE ALL). NOTE: sn* options require use of the '-s' command +line option. + + xcsv Command options + gpsbabel -i xcsv,style=foo.style -f foo \ + -o xcsv,style=bar.style \ + -F bar + + gpsbabel -s -i gpx -f foo.gpx \ +-o xcsv,style=my.style,snlen=8 -F bar + +
    +
    + + Delorme TopoUSA/XMap Conduit format + + XMap + Delorme TopoUSA/XMap Conduit is one of the billion CSV +variants mentioned above. It's just like S&A with the addition of +a completely pointless line at the beginning and end of the file. This +is the format used to hot-sync to XMap from withing TopoUSA. Done with +help of Dan Edwards. +
    +
    + + + Delorme XMap/Street Atlas 2006 Handheld Conduit format + + + XMap2006 + Delorme XMap2006 Conduit is just like XMap, except there are + no spaces between fields and the coordinate format is slightly + different. The completely pointless header and footer lines + are the same, at least. Use this to create the XMapHHWptsSend.txt + file needed to sync to Street Atlas Handheld 2006. + Note that in order to keep from creating duplicates on your handheld, you must first remove the file "XMapWptsDB" from your handheld, restart SAHH2006 on the handheld to create an empty database, and THEN sync the new file. +
    +
    + + Delorme XMapHandHeld street Atlas format. + + XMapWpt + Delorme XMapHandHeld Street Atlas USA is another of the +billion CSV variants. This is the format used by XmapHH SA USA on (at +least) PocketPC O/S. Please see README.xmapwpt for more information +on it's intricacies. This XMap is not to be confused with the XMap +mentioned above. Contributed to GPSBabel by Alex Mottram. +
    +
    + + DATA FILTERS + GPSBabel supports data filtering. Data filters are + invoked from the command line via the '-x' option. It should be + noted that data filters are invoked in the internal pipeline at + the point that corresponds to their position on the + command. This implies that specifying a filter before reading + any data ('-x <filter> -f <file>'), despite being + legal, will not have any effect. The advantage is that filters + can be used intermittently between several variations of input + and output functions. It should also be noted that filtering + data from different input types can sometimes produce + undesirable results due to differences in the native data + formats. + + Beware that most filters only apply to a certain kind of + data. This is usually indicated below by referring to points, + tracks or routes in the first sentence which describes each + filter or in the table at gpsbabel.org + . + +
    + POSITION + The position filter is designed to remove points based + on their proximity to each other. Distances can be passed on + the command line by passing the distance=XXX option to the + filter. Distance options may be expressed in feet + (distance=3f) or + meters (distance=1m). + The default is zero feet, essentially a duplicate position. + + + Using position filter to suppress close points + gpsbabel -i geo -f 1.loc -f 2.loc -x position,distance=1f \ + -o mapsend -F 3.wpt + + would remove multiple points that are within 1 foot of + each other, leaving just one. + You can also specify the "all" option, which would + remove all of the points rather than leaving one. +
    +
    + RADIUS + The radius filter is designed to include points based + on their proximity to a central point. Distances and the + central point are declared on the command line by passing the + , + , and + options to + the filter. Distance options may be expressed in miles + () or + kilometers (). The default is + zero miles. Additionally, the exclude option may be + specified to reverse the effect of the filter, so that points + further from the center are kept and closer points are + discarded. + + Using radius filter to identify points close to a given point + gpsbabel -i geo -f 1.loc \ + -x radius,distance=1.5M,lat=30.0,lon=-90.0 \ + -o mapsend \ + -F 2.wpt + + would include only points within 1.5 miles of N30.000 + W90.000 + +
    +
    + DUPLICATE + The duplicate filter is designed to remove duplicate + points based on their shortname (traditionally a waypoint's + name on the GPS receiver), and/or their location (to a + precision of 6 decimals). This filter supports two options + that specify how duplicates will be recognized, "shortname" and "location". Generally, at least + one of these options is REQUIRED. + + Using duplicate filter to suppress points with same name and locations + gpsbabel -i gpx -f 1.gpx -f 2.gpx -x duplicate,location,shortname \ + -o gpx -F merged_with_no_dupes.gpx + + would remove points that have duplicate shortnames + *AND* duplicate locations. The result would be a GPX file + that more than likely contains only unique points and point + data. + The duplicate filter can also take an "all" option. + If you specify that option, all instances of a duplicated + waypoint will be removed, not just the second and subsequent + instances. If your input file contains waypoints A, B, B, + and C, the output file will contain waypoints A, B, and C + without the "all" option, or just A and C with the "all" + option. This option can be useful as an "ignore list" in + some circumstances. + + Finally, the duplicate filter takes a + "" option. If you specify that + option, the latitude and longitude frmo later duplicates will + replace the latitude and longitude in earlier waypoints. You + can use this to apply a list of "waypoint corrections" to a larger + file, while keeping all of the other details from the larger + file. +
    +
    + DISTANCE FROM A ROUTE (ARC) ARC + The arc filter is designed to include points based on + their proximity to an arc, which is a series of connected + line segments similar to a route or a track but without any + associated data other than the coordinates. + + The arc is defined in a file whose name must be + provided with the option to the filter. + That file contains pairs of coordinates for the vertices of + the arc, one coordinate pair per line. Comments may be + included by preceding them with a '#' character. An arc file + looks something like this sample: + + +# Lima Road/SR3 north of Fort Wayne, Indiana +41.150064468 -85.166207433 +41.150064468 -85.165371895 +41.149034500 -85.165157318 +41.147832870 -85.164771080 +41.146631241 -85.164384842 +41.144270897 -85.163655281 +41.141953468 -85.162882805 + An arc file may optionally contain gaps in the arc. You can + specify such a gap by inserting a line containing "#break" + either on a line by itself or after the coordinates of the + starting point of the new arc segment. + + In addition to the file containing the arc, you should + also specify the maximum distance from the arc that will be + accepted; that distance is declared on the command line with + the + option to the filter. Distance options may be expressed in + miles () or + kilometers (). The default is + zero miles. You may also specify the exclude option, which + causes GPSBabel to only include points that are further than + the specified distance from the arc. + + For example, assuming the arc above is in a file called lima_rd.txt: + gpsbabel -i geo -f 1.loc + -x arc,file=lima_rd.txt,distance=1 \ + -o mapsend -F 2.wpt + would include only points within one mile of the + section of Lima Road covered by the arc. +
    +
    + POLYGON + The polygon filter includes points if they are inside + of a polygon. A polygon file looks like an arc file, except + that the arc it describes must be a closed cycle. That is, + for a simple polygon, the first and last points must be the + same. Here's a square: + + + # A square (not really) polygon + 41.0000 -85.0000 + 41.0000 -86.0000 + 42.0000 -86.0000 + 42.0000 -85.0000 + 41.0000 -85.0000 + + Polygons may include islands and holes. To specify an + island or a hole, just append it to the main polygon. + + As with the arc filter, you specify a polygon by + specifying the name of the file that contains it, using + the file option. You can also specify the exclude option, + which reverses the operation of the filter so that it only + includes points that are NOT in the polygon. + + Note that this filter currently will not work properly + if your polygon contains one or both poles or if it spans the + line of 180 degrees east or west longitude. + + For example, assume you have a polygon file that + defines the border of your county, called mycounty.txt. This + command line will give you only the points in your county: + + gpsbabel -i geo -f 1.loc -x polygon,file=mycounty.txt \ +-o mapsend -F 2.wpt +
    +
    + SIMPLIFY + The Simplify filter is used to simplify routes and + tracks for use with formats that limit the number of points + they can contain or just to reduce the complexity of a route. + The Simplify filter attempts to remove points from each + route until the number of points or the error is within the given + bounds, while also attempting to preserve the shape of the original + route as much as possible. + You must specify either the "count" option or the "error" option. + The count option requires a number, which is the maximum number + of points that will appear in the simplified track. The error + option takes a distance, optionally followed by an 'm' for miles or + a 'k' for kilometers. That distance specifies the maximum error; + how that error is determined depends on the simplification method, + described next. + You may also specify the method by which the filter chooses + which points to remove. The options are "length", which tries to + remove points that have the smallest effect on the overall length + of the route, or "crosstrack", which tries to remove points that + have the smallest overall effect on the shape of the route. The + default, if you don't specify either option, is "crosstrack". + The quality of the results will vary depending on the + density of points in the original route and the length of the + original route. + For example, suppose you have a route from Street + Atlas 2003 that you wish to use with a Magellan GPS receiver + that only supports up to 50 points in a route: + gpsbabel -r -i saroute -f RoadTrip.anr \ + -x simplify,count=50 \ + -o magellan -F grocery.rte + +
    +
    + REVERSE + The reverse filter is used to reverse tracks and routes. + It's mostly useful for those few formats where track/route + sequence matters and there isn't a way to reverse them using + the program itself. + The reversal is performed in the laziest way possible. + Timestamps are kept with the original waypoints so the + resulting track or route will have the interesting + characteristic that time runs backwards. This tends to make + Magellan Mapsend, in particular, do a wierd thing and place + each waypoint on a separate day. + + Additionally, if you're using this to reverse a route + that navigates, say, an exit ramp or a one way street, you + will be in for unpleasant ride. application cares about + timestamps + +
    +
    + SORT + This simple filter allows you to alphabetize waypoints + by shortname or by description. It has a special suboption + (gcid) to sort by geocaching.com waypoint ID's when the input + comes from a GPX file that has GC numbers in it. + +
    +
    + STACK + This filter is designed to solve advanced problems + that involve shuffling multiple lists of waypoints. It has + three distinct sets of suboptions: + PUSH + Pushes the current list of waypoints onto the stack. + If the 'copy' suboption is specified, a copy of the current + list is pushed onto the stack; otherwise, the current list is + cleared. + +-x stack,push +-x stack,push,copy + + POP + 'Pops' the top list of waypoints off of the stack. + What is done with that list depends on the suboption + specified. If the 'append' suboption is specified, the top + list of waypoints from the stack is added to the end of the + current list of waypoints. If the 'discard' option is + specified, the top list of waypoints is removed from the + stack and discarded, leaving the current list of waypoints + unchanged. If the 'replace' option is specified, or if no + option is specified, the top list of waypoints from the stack + replaces the current list of waypoints; the previous contents + of the current list are discarded. + +-x stack,pop +-x stack,pop,discard +-x stack,pop,append + + SWAP + Swaps the current list of waypoints with a list from + the stack. If no further options are specified, the current + list is swapped with the top list on the stack. If the + 'depth' option is specified, it indicates which item on the + stack should be swapped. + +-x stack,swap +-x stack,swap,depth=2 + + The stack can be used in conjunction with other + filters to implement a "union" or "logical or" functionality. + The basic idea is to use the stack to store copies of the + original list of waypoints, then use the 'swap' function to + replace each copy with a filtered list. Finally, append all + of the filtered lists to create one big list, which is then + output. The following example finds a list of all points + that are either inside county A or inside county B. Any + points that are inside both counties are duplicated (but the + duplicates can be removed with the DUPLICATE filter; see + above.) + + +gpsbabel -i gpx -f in.gpx \ + -x stack,push,copy \ + -x polygon,file=county_a.txt \ + -x stack,swap \ + -x polygon,file=county_b.txt \ + -x stack,pop,append \ + -o gpx -F out.gpx + + This example reads a large list of waypoints and + extracts the points within 20 miles of each of two cities, + writing the waypoint descriptions into two different PalmDoc + files and exporting all of the points to the GPS receiver: + + +gpsbabel -i gpx -f indiana.gpx \ + -x stack,push,copy \ + -x radius,lat=41.0765,lon=-85.1365,distance=20m \ + -o palmdoc,dbname=Fort\ Wayne -F fortwayne.pdb \ + -x stack,swap \ + -x radius,lat=39.7733,lon=-86.1433,distance=20m \ + -o palmdoc,dbname=Indianapolis -F indianapolis.pdb \ + -x stack,pop,append \ + -o magellan -F fwaind.wpt + + +
    +
    + TRACK + ( !!! This filter always drops empty tracks !!! ) + + The track filter is a tool for manipulating track lists. The +following options are available: + TITLE + Gives the new track(s) a basic title. Basic means if + more than one track is created by filter the title will be + expanded with the date the new track. Special formats (see + UNIX date or strftime for details) are possible. + + +gpsbabel -t \ + -i gpx -f in.gpx \ -x track,pack,split,title="ACTIVE LOG-%D" \ +-o gpx -F out.gpx PACK + + MOVE + Change the time of all trackpoints. This is useful if + your track has moved by one or more hours through a time zone + problem. The following example will shift your track to be + one hour later. + +gpsbabel -t -i gpx -f in.gpx \ + -x track,move=+1h,pack,title="ACTIVE LOG" \ + -o gpx -F out.gpx + START / STOP + Filter tracks against time borders. All points outside + this range will be dropped. The date-time paramters have to + be in form of YYYYMMDDHHMMSS; but you may specify only the + most significant portion represented in the the leftmost + fields. See the example, where the time is specified only + through the hour. If you only want to get a track mapped on + 20 july 2005 from 10 am to 6pm, you should use this: + +gpsbabel -t -i gpx -f in.gpx -x \ + track,start=2005072010,stop=2005072018 \ + -o gpx -F out.gpx + PACK + With this default option all tracks from input will be + packed into one track. If tracks overlaps in time, the filter + stops working. To pack all the tracks together into one + track and give it a name, use this: + +gpsbabel -t -i gpx -f in.gpx -x track,pack,title="ACTIVE LOG" \ + -o gpx -F out.gpx + SPLIT + The input track will be split into several tracks + depending on date of track points. If there is more than one + track, use the pack option before before using this. To + split a single tracks into separate tracks for each day and + name them, use this: + + +gpsbabel -t -i gpx -f in.gpx -x \ + track,split,title="ACTIVE LOG \ + # %Y%m%d" -o gpx -F out.gpx + If the input has multiple tracks, pack them together before +splitting them back apart per day thusly: + +gpsbabel -t -i gpx -f in.gpx \ + -x track,pack,split,title="ACTIVE LOG # %D" \ + -o gpx -F out.gpx + Additionally you can add an interval to the split + option. With this the track will be split if the time + between two points is greater than this parameter. The + interval must be numeric and can be int days, hours, minutes + or seconds, expressed as one of the character "d", "h", "m", + or "s". If no trailing character is present, the units are + assumed to be in seconds. + + For example, to split a track based on an four hour + interval, use this: + +gpsbabel -t \ + -i gpx -f in.gpx \ + -x track,pack,split=4h,title="LOG # %c" \ + -o gpx -F out.gpx + + MERGE + Merge puts all track points into one single track and + sort them by time. Points with identical time stamp will be + dropped !!! + If you want to merge tracks from different devices but + from same trip, use this: + +gpsbabel -t \ + -i gpx -f john.gpx \ + -i gpx -f doe.gpx \ + -x track,merge,title="COMBINED LOG" \ + -o gpx -F john_doe.gpx + + FIX + Fix forces the GPS fix status for all trackpoints to the + specified value. The value may be PPS, DGPS, 3D, 2D, or NONE. + + + gpsbabel -i gpx -f trk.gpx -x track,fix=3D -o nmea -F - + + + COURSE + Course computes a value for the GPS heading at each trackpoint. + This is most useful with trackpoints from formats that don't support + heading information or for trackpoints synthesized by the interpolate + filter. The heading at each trackpoint is simply the course from the + previous trackpoint in the track. The first trackpoint in each track + is arbitrarily assigned a heading of 0 degrees. + + gpsbabel -i gpx -f trk.gpx -x track,course,speed -o nmea -F - + + + SPEED + Course computes a value for the GPS speed at each trackpoint. + This is most useful with trackpoints from formats that don't support + speed information or for trackoints synthesized by the interpolate + filter. The speed at each trackpoint is the average speed from the + previous trackpoint (distance/time). The first trackpoint in each + track is assigned a speed of "unknown." + + gpsbabel -i gpx -f trk.gpx -x track,course,speed -o nmea -F - + + +
    +
    + DISCARD + This filter 'fixes' gps data by discarding points with + a hdop and/or vdop over a set limit. If you give both the + hdop and a vdop options, by default points that exceed EITHER + are discarded (OR). This filter processes waypoints, tracks, + and routes. + + HDOP (float) + Points with a hdop exceeding the given value are + discarded. + + VDOP (float) + Points with a vdop exceeding the given value are + discarded. + HDOPANDVDOP + Only useful if both hdop and vdop are given. Now + logical AND is used, i.e. only points exceeding both given + values are discarded. + + Example: + gpsbabel \ + -i gpx -f in.gpx \ + -x discard,hdop=10,vdop=20,hdopandvdop \ + -o gpx -F out.gpx + + Contributed by Tobias Minich. +
    +
    + NUKETYPES + + There are three main types of data that GPSBabel deals with: + waypoints, tracks, and routes. The nuketypes filter allows + removing all the data of any or all of those three types. + + - Removes all waypoints. + - Removes all routes. + - Removes all routes. + + For example, if you have a GPX file that contains routes, tracks, and + waypoints and you want a GPX file that contains only tracks, + you can use this filter to remove the waypoints with this command: + + gpsbabel -i gpx -f bigfile.gpx -x nuketypes,waypoints,routes -o gpx -F tracksonly.gpx + +
    +
    + INTERPOLATE + + This filter modifies any tracks so that either the distance or the time + between consecutive points is no less than the specified interval. Where + points are missing, the filter fills them in by following a straight + line (actually a great circle) between the adjacent points. You + must specify either the "distance" or the "time" option. + + gpsbabel -i gpx -f track.gpx -x interpolate,time=10 -o gpx -f newtrack.gpx + Reads track.gpx and inserts points wherever two adjacent + trackpoints are more than 10 seconds apart + gpsbabel -i gpx -f track.gpx -x interpolate,distance=15k -o gpx -f newtrack.gpx + Reads track.gpx and inserts points wherever two adjacent + trackpoints are more than 15 kilometers apart + gpsbabel -i gpx -f track.gpx -x interpolate,distance=2m -o gpx -f newtrack.gpx + Reads track.gpx and inserts points wherever two adjacent + trackpoints are more than 2 miles apart +
    + + +
    +
    diff --git a/xmldoc/readme.xml b/xmldoc/readme.xml new file mode 100644 index 000000000..2115729dc --- /dev/null +++ b/xmldoc/readme.xml @@ -0,0 +1,20 @@ + + + + %parts; + + %chaps; +] +> + + + + GPSBabel Documentation + + + &allchapters; + + diff --git a/xmlgeneric.c b/xmlgeneric.c new file mode 100644 index 000000000..d83faceb2 --- /dev/null +++ b/xmlgeneric.c @@ -0,0 +1,365 @@ +/* + Common utilities for XML-based formats. + + Copyright (C) 2004, 2005, 2006, 2007 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "xmlgeneric.h" +#include "cet_util.h" + +#if HAVE_LIBEXPAT + #include + static XML_Parser psr; +#endif + +static vmem_t current_tag; +static vmem_t cdatastr; +static gbfile *ifd; +static xg_tag_mapping *xg_tag_tbl; +static const char **xg_ignore_taglist; + +#define MY_CBUF 4096 + +#define MYNAME "XML Reader" + +void +write_xml_header(gbfile *ofd) +{ + char buff[128]; + cet_cs_vec_t *cs = cet_find_cs_by_name(CET_CHARSET_ASCII); + + if ((global_opts.charset != NULL) && (global_opts.charset != cs)) + snprintf(buff, sizeof(buff), " encoding=\"%s\"", global_opts.charset_name); + else + buff[0] = 0; + gbfprintf(ofd, "\n", buff); +} + +void +write_xml_entity(gbfile *ofd, const char *indent, + const char *tag, const char *value) +{ + char *tmp_ent = xml_entitize(value); + gbfprintf(ofd, "%s<%s>%s\n", indent, tag, tmp_ent, tag); + xfree(tmp_ent); +} + +void +write_optional_xml_entity(gbfile *ofd, const char *indent, + const char *tag, const char *value) +{ + if (value && *value) + write_xml_entity(ofd, indent, tag, value); +} + +void +write_xml_entity_begin0(gbfile *ofd, const char *indent, + const char *tag) +{ + gbfprintf(ofd, "%s<%s>\n", indent, tag); +} + +void +write_xml_entity_begin1(gbfile *ofd, const char *indent, + const char *tag, const char *attr, + const char *attrval) +{ + gbfprintf(ofd, "%s<%s %s=\"%s\">\n", indent, tag, attr, attrval); +} + +void +write_xml_entity_begin2(gbfile *ofd, const char *indent, + const char *tag, const char *attr1, + const char *attrval1, const char *attr2, + const char *attrval2) +{ + gbfprintf(ofd, "%s<%s %s=\"%s\" %s=\"%s\">\n", indent, tag, attr1, attrval1, attr2, attrval2); +} + +void +write_xml_entity_end(gbfile *ofd, const char *indent, + const char *tag) +{ + gbfprintf(ofd, "%s\n", indent, tag); +} + +void +xml_fill_in_time(char *time_string, const time_t timep, int microseconds, int long_or_short) +{ + struct tm *tm = gmtime(&timep); + char *format; + int n; + + if (!tm) { + *time_string = 0; + return; + } + + if (long_or_short == XML_LONG_TIME) + format = "%02d-%02d-%02dT%02d:%02d:%02d"; + else + format = "%02d%02d%02dT%02d%02d%02d"; + n = sprintf(time_string, format, + tm->tm_year+1900, + tm->tm_mon+1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + if (microseconds) { + n += sprintf(time_string + n, ".%03d", microseconds / 1000); + } + time_string[n++] = 'Z'; + time_string[n++] = '\0'; + +} + +void +xml_write_time(gbfile *ofd, const time_t timep, int microseconds, char *elname) +{ + char time_string[64]; + xml_fill_in_time(time_string, timep, microseconds, XML_LONG_TIME); + if (time_string[0]) { + gbfprintf(ofd, "<%s>%s\n", + elname, + time_string, + elname + ); + } + +} + +/*********************************************************************** + * These implement a simple interface for "generic" XML that + * maps reasonably close to 1:1 between XML tags and internal data + * structures. + * + * It doesn't work well for formats (like GPX) that really are "real" + * XML with extended namespaces and such, but it handles many simpler + * xml strains and insulates us from a lot of the grubbiness of expat. + */ + +xg_callback * +xml_tbl_lookup(const char *tag, xg_cb_type cb_type) +{ + xg_tag_mapping *tm; + for (tm = xg_tag_tbl; tm->tag_cb != NULL; tm++) { + if (str_match(tag, tm->tag_name) && (cb_type == tm->cb_type)) { + return tm->tag_cb; + } + } + return NULL; +} + +/* + * See if tag element 't' is in our list of things to ignore. + * Returns 0 if it is not on the list. + */ +static int +xml_consider_ignoring(const char *t) +{ + const char **il; + + if (!xg_ignore_taglist) { + return 0; + } + + for (il = xg_ignore_taglist; *il; il++) { + if (0 == strcmp(*il, t)) { + return 1; + } + } + return 0; +} + + +static void +xml_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) +{ + char *e; + char *ep; + xg_callback *cb; + const char *el; + const char **attrs; + + el = xml_convert_to_char_string(xml_el); + attrs = xml_convert_attrs_to_char_string(xml_attr); + + if (xml_consider_ignoring(el)) + return; + + vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); + + e = current_tag.mem; + ep = e + strlen(e); + *ep++ = '/'; + strcpy(ep, el); + + memset(cdatastr.mem, 0, cdatastr.size); + + cb = xml_tbl_lookup(e, cb_start); + if (cb) { + (*cb)(NULL, attrs); + } + xml_free_converted_string(el); + xml_free_converted_attrs(attrs); +} + +#if HAVE_LIBEXPAT +static void +xml_cdata(void *dta, const XML_Char *xml_s, int len) +{ + char *estr; + const char *s = xml_convert_to_char_string_n(xml_s, &len); + + vmem_realloc(&cdatastr, 1 + len + strlen(cdatastr.mem)); + estr = (char *) cdatastr.mem + strlen(cdatastr.mem); + memcpy(estr, s, len); + estr[len] = 0; + xml_free_converted_string(s); +} + +static void +xml_end(void *data, const XML_Char *xml_el) +{ + char *s = strrchr(current_tag.mem, '/'); + const char *el = xml_convert_to_char_string(xml_el); + xg_callback *cb; + + if (xml_consider_ignoring(el)) + return; + + if (strcmp(s + 1, el)) { + fprintf(stderr, "Mismatched tag %s\n", el); + } + cb = xml_tbl_lookup(current_tag.mem, cb_cdata); + if (cb) { + (*cb)( (char *) cdatastr.mem, NULL); + } + + cb = xml_tbl_lookup(current_tag.mem, cb_end); + if (cb) { + (*cb)(el, NULL); + } + *s = 0; + xml_free_converted_string(el); +} + +void xml_read(void) +{ + int len; + char buf[MY_CBUF]; + + while ((len = gbfread(buf, 1, sizeof(buf), ifd))) { + if (!XML_Parse(psr, buf, len, gbfeof(ifd))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + XML_ParserFree(psr); + +} + +void xml_readstring( char *str ) +{ + int len = strlen(str); + if (!XML_Parse(psr, str, len, 1)) { + fatal( MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + XML_ParserFree(psr); +} + +void xml_readprefixstring( char *str ) +{ + int len = strlen(str); + if (!XML_Parse(psr, str, len, 0)) { + fatal( MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } +} + +void xml_ignore_tags(const char **taglist) +{ + xg_ignore_taglist = taglist; +} + +void +xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) +{ + if (fname) { + ifd = gbfopen(fname, "r", MYNAME); + } else { + ifd = NULL; + } + + current_tag = vmem_alloc(1,0); + *((char *)current_tag.mem) = '\0'; + + psr = XML_ParserCreate((const XML_Char *)encoding); + if (!psr) { + fatal(MYNAME ": Cannot create XML Parser\n"); + } + + cdatastr = vmem_alloc(1, 0); + *((char *)cdatastr.mem) = '\0'; + + xg_tag_tbl = tbl; + + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, xml_start, xml_end); + XML_SetCharacterDataHandler(psr, xml_cdata); +} + +void +xml_deinit(void) +{ + vmem_free(¤t_tag); + vmem_free(&cdatastr); + if (ifd) { + gbfclose(ifd); + ifd = NULL; + } + xg_ignore_taglist = NULL; +} +#else /* HAVE_LIBEXPAT */ +void +xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) +{ + fatal("This format does not support reading XML files as libexpat was not present."); +} + +void xml_read(void) +{ +} + +void xml_deinit(void) +{ +} + +void xml_readstring(char *unused) +{ +} + +#endif /* HAVE_LIBEXPAT */ + +/******************************************/ diff --git a/xmlgeneric.h b/xmlgeneric.h new file mode 100644 index 000000000..0ce0834b9 --- /dev/null +++ b/xmlgeneric.h @@ -0,0 +1,63 @@ +/* + Header for our common utilities for XML-based formats. + + Copyright (C) 2004, 2005, 2006, 2007 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + + +typedef enum { + cb_start = 1, + cb_cdata, + cb_end, +} xg_cb_type; + +typedef void (xg_callback) (const char *, const char **); + +typedef struct xg_tag_mapping { + xg_callback *tag_cb; + xg_cb_type cb_type; + const char *tag_name; +} xg_tag_mapping; + +extern char *xhtml_entities; + +void write_xml_entity(gbfile *ofd, const char *indent, + const char *tag, const char *value); +void write_xml_entity_begin0(gbfile *ofd, const char *indent, + const char *tag); +void write_xml_entity_begin1(gbfile *ofd, const char *indent, const char *tag, + const char *attr1, const char *attrval1); +void write_xml_entity_begin2(gbfile *ofd, const char *indent, const char *tag, + const char *attr1, const char *attrval1, + const char *attr2, const char *attrval2); +void write_xml_entity_end(gbfile *ofd, const char *indent, const char *tag); + +void write_optional_xml_entity(gbfile *ofd, const char *indent, + const char *tag, const char *value); +void xml_write_time(gbfile *ofd, const time_t timep, int microseconds, char *elname); +void xml_fill_in_time(char *time_string, const time_t timep, int microseconds, + int long_or_short); +void write_xml_header(gbfile *ofd); +void xml_ignore_tags(const char **taglist); + +void xml_init(const char *fname, xg_tag_mapping *tbl,const char *encoding); +void xml_read(void); +void xml_readstring(char *str); +void xml_readprefixstring(char *str); +void xml_deinit(void); diff --git a/xmltag.c b/xmltag.c new file mode 100644 index 000000000..50c4a46ee --- /dev/null +++ b/xmltag.c @@ -0,0 +1,156 @@ +/* + Functions to deal with xml_tags + + Copyright (C) 2005 Ron Parker and Robert Lipe. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include + +#include "defs.h" + +void free_xml_tag( xml_tag *tag ) +{ + xml_tag *next = NULL; + char **ap; + + while ( tag ) { + if (tag->cdata) { + xfree(tag->cdata); + } + if (tag->child) { + free_gpx_extras(tag->child); + } + if (tag->parentcdata) { + xfree(tag->parentcdata); + } + if (tag->tagname) { + xfree(tag->tagname); + } + if (tag->attributes) { + ap = tag->attributes; + + while (*ap) + xfree(*ap++); + + xfree(tag->attributes); + } + + next = tag->sibling; + xfree(tag); + tag = next; + } +} + +void copy_xml_tag( xml_tag **copy, xml_tag *src, xml_tag *parent ) { + xml_tag *res = NULL; + char **ap = NULL; + char **ap2 = NULL; + int count = 0; + + if ( !src ) { + *copy = NULL; + return; + } + + res = xcalloc( 1, sizeof(xml_tag)); + *copy = res; + + memcpy( res, src, sizeof(xml_tag)); + res->tagname = xstrdup( src->tagname ); + res->cdata = xstrdup( src->cdata ); + res->parentcdata = xstrdup( src->parentcdata ); + if ( src->attributes ) { + ap = src->attributes; + while ( *ap ) { + count++; + ap++; + } + res->attributes = (char **)xcalloc( count+1, sizeof(char *)); + ap = src->attributes; + ap2 = res->attributes; + while (*ap) { + *ap2 = xstrdup(*ap); + ap++; + ap2++; + } + } + res->parent = parent; + copy_xml_tag( &(res->sibling), src->sibling, parent ); + copy_xml_tag( &(res->child), src->child, res ); +} + +static void +convert_xml_tag( xml_tag *tag ) { + char **ap = NULL; + + if (tag == NULL) return; + + tag->cdata = cet_convert_string(tag->cdata); + tag->parentcdata = cet_convert_string(tag->parentcdata); + + ap = tag->attributes; + while (*ap) + { + *ap = cet_convert_string(*ap); + ap++; + } + convert_xml_tag(tag->sibling); + convert_xml_tag(tag->child); +} + +fs_xml *fs_xml_alloc( long type ); + +void fs_xml_destroy( void *fs ) { + fs_xml *xml = (fs_xml *)fs; + if ( xml ) { + free_xml_tag( xml->tag ); + } + xfree( fs ); +} + +void fs_xml_copy( void **copy, void *source ) { + fs_xml *src = (fs_xml *)source; + if ( !source ) { + *copy = NULL; + return; + } + *copy = (void *)fs_xml_alloc( src->fs.type ); + memcpy( *copy, source, sizeof(fs_xml) ); + copy_xml_tag( &(((fs_xml *)(*copy))->tag), src->tag, NULL ); +} + +void fs_xml_convert( void *fs ) { + fs_xml *xml = (fs_xml *)fs; + if ( xml ) { + convert_xml_tag( xml->tag ); + } +} + +fs_xml *fs_xml_alloc( long type ) { + fs_xml *result = NULL; + + result = (fs_xml *)xcalloc( 1, sizeof(fs_xml)); + result->fs.type = type; + result->fs.copy = fs_xml_copy; + result->fs.destroy = fs_xml_destroy; + result->fs.convert = fs_xml_convert; + return result; +} + diff --git a/xol.c b/xol.c new file mode 100644 index 000000000..f0349a725 --- /dev/null +++ b/xol.c @@ -0,0 +1,354 @@ +/* + + Support for Swiss Map # (.xol) format + + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#include "defs.h" +#include "xmlgeneric.h" +#include "jeeps/gpsmath.h" +#include "garmin_tables.h" + +static waypoint *wpt; +static route_head *trk; +static gbfile *fout; +static int space; +static bounds all_bounds; +static short_handle short_h; + +static arglist_t xol_args[] = +{ + ARG_TERMINATOR +}; + +#define MYNAME "xol" + +#if ! HAVE_LIBEXPAT +void +xol_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded \"" MYNAME "\" support because expat was not installed.\n"); +} + +void +xol_read(void) +{ +} + +#else + +static xg_callback xol_shape, xol_shape_end; +static xg_callback xol_waypt, xol_overlay; + +#define XOL "/overlays/overlay" + +static +xg_tag_mapping xol_map[] = { + { xol_overlay, cb_start, XOL }, + { xol_shape, cb_start, XOL "/shapes/*shape" }, + { xol_shape_end, cb_end, XOL "/shapes/*shape" }, + { xol_waypt, cb_start, XOL "/shapes/shape/*points/point" }, + { NULL, 0, NULL } +}; + + +static void +xol_overlay(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "version") == 0) { + if (strcmp(avp[1], "1.0") != 0) + fatal(MYNAME ": Unsupported version %s.\n", avp[1]); + } + + avp+=2; + } +} + +static void +xol_shape(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "type") == 0) { + if (strcmp(avp[1], "waypoint") == 0) { + wpt = waypt_new(); + } + else if (strcmp(avp[1], "polyline") == 0) { + trk = route_head_alloc(); + track_add_head(trk); + } + } + else if (strcmp(avp[0], "name") == 0) { + if (wpt) wpt->shortname = xstrdup(avp[1]); + else if (trk) trk->rte_name = xstrdup(avp[1]); + } + else if (strcmp(avp[0], "comment") == 0) { + if (wpt) wpt->notes = xstrdup(avp[1]); + } + else if (strcmp(avp[0], "alt") == 0) { + if (wpt) wpt->altitude = atof(avp[1]); + } + else if (strcmp(avp[0], "timestamp") == 0) { + if (wpt) wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds); + } + else if (strcmp(avp[0], "icon") == 0) { + if (wpt) { + wpt->icon_descr = xstrdup(avp[1]); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + } + } + + avp+=2; + } +} + +static void +xol_shape_end(const char *args, const char **unused) +{ + if (wpt) { + if (trk) track_add_wpt(trk, wpt); + else waypt_add(wpt); + wpt = NULL; + } + else if (trk) { + if (trk->rte_waypt_ct == 0) track_del_head(trk); + trk = NULL; + } +} + +static void +xol_waypt(const char *args, const char **attrv) { + const char **avp = &attrv[0]; + int x=0, y=0; + + while (*avp) { + if (strcmp(avp[0], "y") == 0) + y = atoi(avp[1]); + else if (strcmp(avp[0], "x") == 0) + x = atoi(avp[1]); + avp+=2; + } + + GPS_Math_CH1903_NGEN_To_WGS84((double)x, (double)y, &wpt->latitude, &wpt->longitude); +} + +static void +xol_rd_init(const char *fname) +{ + trk = NULL; + wpt = NULL; + + xml_init(fname, xol_map, NULL); +} + +static void +xol_read(void) +{ + xml_read(); +} + +#endif + +static void +xol_rd_deinit(void) +{ + xml_deinit(); +} + +/* writer */ + +static void +xol_fatal_outside(const waypoint *wpt) +{ + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": %s (%s) is outside of convertable area \"%s\"!\n", + wpt->shortname ? wpt->shortname : "Waypoint", + pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), + gt_get_mps_grid_longname(grid_swiss, MYNAME)); +} + + +static void +xol_write_time(const waypoint *wpt) +{ + char time_string[64]; + + xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); + if (time_string[0]) { + gbfprintf(fout, " timestamp=\"%s\"", time_string); + } +} + +static void +xol_write_string(const char *name, const char *str) +{ + if (str && *str) { + char *temp = strenquote(str, '"'); + gbfprintf(fout, " %s=%s", name, temp); + xfree(temp); + } +} + +static void +xol_waypt_bound_calc(const waypoint *wpt) +{ + waypt_add_to_bounds(&all_bounds, wpt); +} + +static void +xol_wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); + + space = 1; + waypt_init_bounds(&all_bounds); + short_h = mkshort_new_handle(); + + setshort_length(short_h, 1024); /* ??? */ + setshort_badchars(short_h, "\r\n\t"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 1); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 1); + setshort_defname(short_h, "Waypoint"); +} + +static void +xol_wr_deinit(void) +{ + mkshort_del_handle(&short_h); + gbfclose(fout); +} + +static void +xol_waypt_disp_cb(const waypoint *wpt) +{ + double x, y; + char *name; + + name = wpt->shortname; + if ((name == NULL) || (*name == '\0') || global_opts.synthesize_shortnames) + name = mkshort_from_wpt(short_h, wpt); + else + name = mkshort(short_h, name); + + if (! GPS_Math_WGS84_To_CH1903_NGEN(wpt->latitude, wpt->longitude, &x, &y)) + xol_fatal_outside(wpt); + + gbfprintf(fout, "%*snotes); + xol_write_string("icon", wpt->icon_descr); + if (wpt->creation_time) xol_write_time(wpt); + if (wpt->altitude != unknown_alt) gbfprintf(fout, " alt=\"%.f\"", wpt->altitude); + gbfprintf(fout, ">\n"); + + gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*s\n", space*2, "", x, y); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); + + xfree(name); +} + +static void +xol_track_hdr_disp_cb(const route_head *trk) +{ + gbfprintf(fout, "%*srte_name); + gbfprintf(fout, " lineSize=\"3\" lineColor=\"#e60000\" lineStyle=\"solid\">\n"); + gbfprintf(fout, "%*s\n", space++*2, ""); +} + +static void +xol_track_tlr_disp_cb(const route_head *trk) +{ + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); +} + +static void +xol_trkpt_disp_cb(const waypoint *wpt) +{ + double x, y; + + if (! GPS_Math_WGS84_To_CH1903_NGEN(wpt->latitude, wpt->longitude, &x, &y)) + xol_fatal_outside(wpt); + + gbfprintf(fout, "%*screation_time) xol_write_time(wpt); + if (wpt->altitude != unknown_alt) gbfprintf(fout, " alt=\"%.f\"", wpt->altitude); + gbfprintf(fout, ">\n"); + gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*s\n", space*2, "", x, y); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); +} + +static void +xol_write(void) +{ + double x, y; + + waypt_disp_all(xol_waypt_bound_calc); + track_disp_all(NULL, NULL, xol_waypt_bound_calc); + + if (! waypt_bounds_valid(&all_bounds)) { + fatal(MYNAME ": No data available!\n"); + } + + if (! GPS_Math_WGS84_To_CH1903_NGEN( + (all_bounds.min_lat + all_bounds.max_lat) / 2, + (all_bounds.min_lon + all_bounds.max_lon) / 2, &x, &y)) { + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": At least one point is outside of convertable area \"%s\"!\n", + gt_get_mps_grid_longname(grid_swiss, MYNAME)); + } + + gbfprintf(fout, "\n", global_opts.charset_name); + gbfprintf(fout, "\n"); + gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*s
    \n", space*2, "", x, y); + gbfprintf(fout, "%*s\n", space++*2, ""); + waypt_disp_all(xol_waypt_disp_cb); + track_disp_all(xol_track_hdr_disp_cb, xol_track_tlr_disp_cb, xol_trkpt_disp_cb); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "\n"); +} + +ff_vecs_t xol_vecs = { + ff_type_file, + { ff_cap_read | ff_cap_write, /* waypoints */ + ff_cap_read | ff_cap_write, /* tracks */ + ff_cap_none }, /* routes */ + xol_rd_init, + xol_wr_init, + xol_rd_deinit, + xol_wr_deinit, + xol_read, + xol_write, + NULL, + xol_args, + CET_CHARSET_UTF8, 0 +}; diff --git a/yahoo.c b/yahoo.c new file mode 100644 index 000000000..8a98668fd --- /dev/null +++ b/yahoo.c @@ -0,0 +1,119 @@ +/* + Read Yahoo Geocoded files. + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "xmlgeneric.h" + +static waypoint *wpt_tmp; +static char *as; + +#define MYNAME "yahoo" + +static +arglist_t yahoo_args[] = { + {"addrsep", &as, + "String to separate concatenated address fields (default=\", \")", + ", ", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static xg_callback wpt_s, wpt_lat, wpt_lon, wpt_e; +static xg_callback wpt_addr /*, wpt_city, wpt_state, wpt_zip, wpt_country*/; + +static xg_tag_mapping gl_map[] = { + { wpt_s, cb_start, "/ResultSet/Result" }, + { wpt_lat, cb_cdata, "/ResultSet/Result/Latitude" }, + { wpt_lon, cb_cdata, "/ResultSet/Result/Longitude" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Address" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/City" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/State" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Zip" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Country" }, + { wpt_e, cb_end, "/ResultSet/Result" }, + { NULL, 0, NULL} +}; + +static void +yahoo_rd_init(const char *fname) +{ + xml_init(fname, gl_map, NULL); +} + +static void +yahoo_read(void) +{ + xml_read(); +} + +static void +yahoo_rd_deinit(void) +{ + xml_deinit(); +} + +static void +yahoo_wr_init(const char *fname) +{ + fatal("Writing file of type %s is not supported\n", MYNAME); +} + +void wpt_s(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); +} + +void wpt_e(const char *args, const char **unused) +{ + waypt_add(wpt_tmp); + wpt_tmp = NULL; +} + +void wpt_lat(const char *args, const char **unused) +{ + wpt_tmp->latitude = atof(args); +} + +void wpt_lon(const char *args, const char **unused) +{ + wpt_tmp->longitude = atof(args); +} + +void wpt_addr(const char *args, const char **unused) +{ + if (wpt_tmp->notes) { + wpt_tmp->notes = xstrappend(wpt_tmp->notes, as); + } + wpt_tmp->notes = xstrappend(wpt_tmp->notes, args); +} + +ff_vecs_t yahoo_vecs = { + ff_type_file, + { ff_cap_read }, + yahoo_rd_init, + yahoo_wr_init, + yahoo_rd_deinit, + NULL, + yahoo_read, + NULL, + NULL, + yahoo_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/zlib/.cvsignore b/zlib/.cvsignore new file mode 100644 index 000000000..c6cac6926 --- /dev/null +++ b/zlib/.cvsignore @@ -0,0 +1 @@ +empty diff --git a/zlib/ChangeLog b/zlib/ChangeLog new file mode 100644 index 000000000..1724324fb --- /dev/null +++ b/zlib/ChangeLog @@ -0,0 +1,860 @@ + + ChangeLog file for zlib + +Changes in 1.2.3.f-GPSBabel (17 July 2006) +- Change ZLIB_VERSION to "1.2.3.f-GPSBabel" and ZLIB_VERNUM to 0x123f +- When pathname is "-" assign stdin or stdout to [gzfile]->file (gzio.c/gz_open) +- WIN32 target: Add missing "b" to file open mode (gzio.c/gz_open) + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Added zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id: ChangeLog,v 1.1 2006/07/22 20:34:06 oliskoli Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/zlib/FAQ b/zlib/FAQ new file mode 100644 index 000000000..441d910da --- /dev/null +++ b/zlib/FAQ @@ -0,0 +1,339 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://www.zlib.org which may have more recent information. +The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. + See the file win32/DLL_FAQ.txt in the zlib distribution. + Pointers to the precompiled DLL are found in the zlib web site at + http://www.zlib.org. + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm + * contrib/visual-basic.txt in the zlib distribution + * win32/DLL_FAQ.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR. + + Make sure that before the call of compress, the length of the compressed + buffer is equal to the total size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR. + + Before making the call, make sure that avail_in and avail_out are not + zero. When setting the parameter flush equal to Z_FINISH, also make sure + that avail_out is big enough to allow processing all pending input. + Note that a Z_BUF_ERROR is not fatal--another call to deflate() or + inflate() can be made with more input or output space. A Z_BUF_ERROR + may in fact be unavoidable depending on how the functions are used, since + it is not possible to tell whether or not there is more output pending + when strm.avail_out returns with zero. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h for the moment, and Francis S. Lin has converted it to a + web page zlib.html. Volunteers to transform this to Unix-style man pages, + please contact us (zlib@gzip.org). Examples of zlib usage are in the files + example.c and minigzip.c. + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple + package. zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of + zlib. Please try to reproduce the problem with a small program and send + the corresponding source to us at zlib@gzip.org . Do not send + multi-megabyte data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + Not by itself, no. See the directory contrib/minizip in the zlib + distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + make clean + ./configure -s + make + +14. How do I install a shared zlib library on Unix? + + After the above, then: + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to it. + +15. I have a question about OttoPDF. + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site: Joel Hainley, jhainley@myndkryme.com. + +16. Can zlib decode Flate data in an Adobe PDF file? + + Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ . + To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ . + +17. Why am I getting this "register_frame_info not found" error on Solaris? + + After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib + generates an error such as: + + ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: + symbol __register_frame_info: referenced symbol not found + + The symbol __register_frame_info is not part of zlib, it is generated by + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See + http://www.sunfreeware.com for Solaris versions of zlib and applications + using zlib. + +18. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip + formats use the same compressed data format internally, but have different + headers and trailers around the compressed data. + +19. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about + a single file, such as the name and last modification date. The zlib + format on the other hand was designed for in-memory and communication + channel applications, and has a much more compact header and trailer and + uses a faster integrity check than gzip. + +20. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode + the gzip format using inflateInit2(). Read zlib.h for more details. + +21. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's Init functions allow + for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +22. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +23. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +24. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +25. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +26. Will zlib work on a 64-bit machine? + + It should. It has been tested on 64-bit machines, and has no dependence + on any data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +27. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format + than does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +28. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically + use Z_FULL_FLUSH, carefully write all the pending data at those points, + and keep an index of those locations, then you can start decompression + at those points. You have to be careful to not use Z_FULL_FLUSH too + often, since it can significantly degrade compression. + +29. Does zlib work on MVS, OS/390, CICS, etc.? + + We don't know for sure. We have heard occasional reports of success on + these systems. If you do use it on one of these, please provide us with + a report, instructions, and patches that we can reference when we get + these questions. Thanks. + +30. Is there some simpler, easier to read version of inflate I can look at + to understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +31. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + http://www.gzip.org/#faq11 + +32. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit + only if the compiler's "long" type is 32 bits. If the compiler's "long" + type is 64 bits, then the limit is 16 exabytes. + +33. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib + is compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of a 4K string space, other than the caller of + gzprintf() assuring that the output will not exceed 4K. On the other + hand, if zlib is compiled to use snprintf() or vsnprintf(), which should + normally be the case, then there is no vulnerability. The ./configure + script will display warnings if an insecure variation of sprintf() will + be used by gzprintf(). Also the zlibCompileFlags() function will return + information on what variant of sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + http://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability. + +34. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: http://www.zlib.org/ + +35. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pedantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly. So now, we simply make sure that the code always + works. + +36. Valgrind (or some similar memory access checker) says that deflate is + performing a conditional jump that depends on an uninitialized value. + Isn't that a bug? + + No. That is intentional for performance reasons, and the output of + deflate is not affected. This only started showing up recently since + zlib 1.2.x uses malloc() by default for allocations, whereas earlier + versions used calloc(), which zeros out the allocated memory. + +37. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +38. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very weak + and can be broken with freely available programs. To get strong encryption, + use GnuPG, http://www.gnupg.org/ , which already includes zlib compression. + For PKZIP compatible "encryption", look at http://www.info-zip.org/ + +39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion + with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specficiation in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +40. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. + In any case, the compression improvements are so modest compared to other + more modern approaches, that it's not worth the effort to implement. + +41. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/zlib/Makefile.in.zlib b/zlib/Makefile.in.zlib new file mode 100644 index 000000000..2fd6e45c4 --- /dev/null +++ b/zlib/Makefile.in.zlib @@ -0,0 +1,154 @@ +# Makefile for zlib +# Copyright (C) 1995-2005 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# The call of configure is optional if you don't have special requirements +# If you wish to build zlib as a shared library, use: ./configure -s + +# To use the asm code, type: +# cp contrib/asm?86/match.S ./match.S +# make LOC=-DASMV OBJA=match.o + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +LDFLAGS=libz.a +LDSHARED=$(CC) +CPP=$(CC) -E + +LIBS=libz.a +SHAREDLIB=libz.so +SHAREDLIBV=libz.so.1.2.3 +SHAREDLIBM=libz.so.1 + +AR=ar rc +RANLIB=ranlib +TAR=tar +SHELL=/bin/sh +EXE= + +prefix = /usr/local +exec_prefix = ${prefix} +libdir = ${exec_prefix}/lib +includedir = ${prefix}/include +mandir = ${prefix}/share/man +man3dir = ${mandir}/man3 + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infback.o inftrees.o inffast.o + +OBJA = +# to use the asm code: make OBJA=match.o + +TEST_OBJS = example.o minigzip.o + +all: example$(EXE) minigzip$(EXE) + +check: test +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +libz.a: $(OBJS) $(OBJA) + $(AR) $@ $(OBJS) $(OBJA) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +match.o: match.S + $(CPP) match.S > _match.s + $(CC) -c _match.s + mv _match.o match.o + rm -f _match.s + +$(SHAREDLIBV): $(OBJS) + $(LDSHARED) -o $@ $(OBJS) + rm -f $(SHAREDLIB) $(SHAREDLIBM) + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIBM) + +example$(EXE): example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip$(EXE): minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +install: $(LIBS) + -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi + -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi + -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi + -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi + cp zlib.h zconf.h $(includedir) + chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h + cp $(LIBS) $(libdir) + cd $(libdir); chmod 755 $(LIBS) + -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 + cd $(libdir); if test -f $(SHAREDLIBV); then \ + rm -f $(SHAREDLIB) $(SHAREDLIBM); \ + ln -s $(SHAREDLIBV) $(SHAREDLIB); \ + ln -s $(SHAREDLIBV) $(SHAREDLIBM); \ + (ldconfig || true) >/dev/null 2>&1; \ + fi + cp zlib.3 $(man3dir) + chmod 644 $(man3dir)/zlib.3 +# The ranlib in install is needed on NeXTSTEP which checks file times +# ldconfig is for Linux + +uninstall: + cd $(includedir); \ + cd $(libdir); rm -f libz.a; \ + if test -f $(SHAREDLIBV); then \ + rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ + fi + cd $(man3dir); rm -f zlib.3 + +mostlyclean: clean +clean: + rm -f *.o *~ example$(EXE) minigzip$(EXE) \ + libz.* foo.gz so_locations \ + _match.s maketree contrib/infback9/*.o + +maintainer-clean: distclean +distclean: clean + cp -p Makefile.in Makefile + cp -p zconf.in.h zconf.h + rm -f .DS_Store + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: crc32.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/zlib/README b/zlib/README new file mode 100644 index 000000000..758cc5002 --- /dev/null +++ b/zlib/README @@ -0,0 +1,125 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.3 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) +and rfc1952.txt (gzip format). These documents are also available in other +formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file example.c which also tests that the library +is working correctly. Another example is given in the file minigzip.c. The +compression library itself is composed of all source files except example.c and +minigzip.c. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile. In short "make test; make install" should work for most +machines. For Unix: "./configure; make test; make install". For MSDOS, use one +of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, +please check this site to verify that you have the latest version of zlib; +otherwise get the latest version and check whether the problem still exists or +not. + +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking +for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available in +http://dogma.net/markn/articles/zlibtool/zlibtool.htm + +The changes made in version 1.2.3 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory "contrib". + +A Java implementation of zlib is available in the Java Development Kit +http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html +See the zlib home page http://www.zlib.org for details. + +A Perl interface to zlib written by Paul Marquess is in the +CPAN (Comprehensive Perl Archive Network) sites +http://www.cpan.org/modules/by-module/Compress/ + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://www.python.org/doc/lib/module-zlib.html + +A zlib binding for TCL written by Andreas Kupries is +availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + +- When building a shared, i.e. dynamic library on Mac OS X, the library must be + installed before testing (do "make install" before "make test"), since the + library location is specified in the library. + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate + and zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; + they are too numerous to cite here. + +Copyright notice: + + (C) 1995-2004 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. Please +read the FAQ for more information on the distribution of modified source +versions. diff --git a/zlib/README.gpsbabel b/zlib/README.gpsbabel new file mode 100644 index 000000000..08f223ab8 --- /dev/null +++ b/zlib/README.gpsbabel @@ -0,0 +1,3 @@ +Subset of zlib-1.2.3. All changes we made within the GPSBabel source +tree are documented in ChangeLog. + diff --git a/zlib/adler32.c b/zlib/adler32.c new file mode 100644 index 000000000..847a20dfd --- /dev/null +++ b/zlib/adler32.c @@ -0,0 +1,149 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: adler32.c,v 1.1 2006/07/22 20:34:06 oliskoli Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 > BASE) sum1 -= BASE; + if (sum1 > BASE) sum1 -= BASE; + if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 > BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} diff --git a/zlib/algorithm.txt b/zlib/algorithm.txt new file mode 100644 index 000000000..b022dde31 --- /dev/null +++ b/zlib/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend two much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +http://www.ietf.org/rfc/rfc1951.txt diff --git a/zlib/compress.c b/zlib/compress.c new file mode 100644 index 000000000..7ef8d6e5e --- /dev/null +++ b/zlib/compress.c @@ -0,0 +1,79 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: compress.c,v 1.1 2006/07/22 20:34:06 oliskoli Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; +} diff --git a/zlib/crc32.c b/zlib/crc32.c new file mode 100644 index 000000000..1b7bd1a06 --- /dev/null +++ b/zlib/crc32.c @@ -0,0 +1,423 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id: crc32.c,v 1.1 2006/07/22 20:34:06 oliskoli Exp $ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case */ + if (len2 == 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320L; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} diff --git a/zlib/crc32.h b/zlib/crc32.h new file mode 100644 index 000000000..8053b6117 --- /dev/null +++ b/zlib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/zlib/deflate.c b/zlib/deflate.c new file mode 100644 index 000000000..3babea592 --- /dev/null +++ b/zlib/deflate.c @@ -0,0 +1,1736 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id: deflate.c,v 1.1 2006/07/22 20:34:07 oliskoli Exp $ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifndef FASTEST +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif +#endif +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds + * for every combination of windowBits and memLevel, as well as wrap. + * But even the conservative upper bound of about 14% expansion does not + * seem onerous for output buffer allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong destLen; + + /* conservative upper bound */ + destLen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + + /* if can't get parameters, return conservative bound */ + if (strm == Z_NULL || strm->state == Z_NULL) + return destLen; + + /* if not default parameters, return conservative bound */ + s = strm->state; + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return destLen; + + /* default settings: return tight bound for that case */ + return compressBound(sourceLen); +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ +#endif /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 or strategy == Z_RLE only + */ +local uInt longest_match_fast(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + /* %%% avoid this when Z_RLE */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifdef FASTEST + if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || + (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { + s->match_length = longest_match_fast (s, hash_head); + } +#else + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } +#endif + /* longest_match() or longest_match_fast() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } + /* longest_match() or longest_match_fast() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +#if 0 +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt run; /* length of run */ + uInt max; /* maximum length of run */ + uInt prev; /* byte at distance one to match */ + Bytef *scan; /* scan for end of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + run = 0; + if (s->strstart > 0) { /* if there is a previous byte, that is */ + max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; + scan = s->window + s->strstart - 1; + prev = *scan++; + do { + if (*scan++ != prev) + break; + } while (++run < max); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (run >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, run); + _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); + s->lookahead -= run; + s->strstart += run; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif diff --git a/zlib/deflate.h b/zlib/deflate.h new file mode 100644 index 000000000..78449ca42 --- /dev/null +++ b/zlib/deflate.h @@ -0,0 +1,331 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2004 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: deflate.h,v 1.1 2006/07/22 20:34:07 oliskoli Exp $ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/zlib/empty.in b/zlib/empty.in new file mode 100644 index 000000000..e69de29bb diff --git a/zlib/gzio.c b/zlib/gzio.c new file mode 100644 index 000000000..13f73cd11 --- /dev/null +++ b/zlib/gzio.c @@ -0,0 +1,1026 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. + */ + +/* @(#) $Id: gzio.c,v 1.3 2006/08/13 17:08:00 oliskoli Exp $ */ + +#include + +#include "zutil.h" + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#ifdef __MVS__ +# pragma map (fdopen , "\174\174FDOPEN") + FILE *fdopen(int, const char *); +#endif + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern void free OF((voidpf ptr)); +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + z_off_t start; /* start of compressed data in file (header skipped) */ + z_off_t in; /* bytes into deflate or inflate */ + z_off_t out; /* bytes out of deflate or inflate */ + int back; /* one character push-back */ + int last; /* true if push-back is last character */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->in = 0; + s->out = 0; + s->back = EOF; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else if (*p == 'R') { + strategy = Z_RLE; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->start = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * start anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->start = ftell(s->file) - s->stream.avail_in; + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[46]; /* allow for up to 128-bit integers */ + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Assure two bytes in the buffer so we can peek ahead -- handle case + where first byte of header is at the end of the buffer after the last + gzip segment */ + len = s->stream.avail_in; + if (len < 2) { + if (len) s->inbuf[0] = s->stream.next_in[0]; + errno = 0; + len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); + if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; + s->stream.avail_in += len; + s->stream.next_in = s->inbuf; + if (s->stream.avail_in < 2) { + s->transparent = s->stream.avail_in; + return; + } + } + + /* Peek ahead to check the gzip magic header */ + if (s->stream.next_in[0] != gz_magic[0] || + s->stream.next_in[1] != gz_magic[1]) { + s->transparent = 1; + return; + } + s->stream.avail_in -= 2; + s->stream.next_in += 2; + + /* Check the rest of the gzip header */ + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + if (s->stream.avail_out && s->back != EOF) { + *next_out++ = s->back; + s->stream.next_out++; + s->stream.avail_out--; + s->back = EOF; + s->out++; + start++; + if (s->last) { + s->z_err = Z_STREAM_END; + return 1; + } + } + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= + (uInt)fread(next_out, 1, s->stream.avail_out, s->file); + } + len -= s->stream.avail_out; + s->in += len; + s->out += len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may be + * different from s->out in case of concatenated .gz files. + * Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + if (len == s->stream.avail_out && + (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) + return -1; + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Push one byte back onto the stream. +*/ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; + s->back = c; + s->out--; + s->last = (s->z_err == Z_STREAM_END); + if (s->last) s->z_err = Z_OK; + s->z_eof = 0; + return c; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_GZCOMPRESS +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + buf[sizeof(buf) - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(buf, format, va); + va_end(va); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = vsprintf(buf, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + len = strlen(buf); +# else + len = vsnprintf(buf, sizeof(buf), format, va); + va_end(va); +# endif +#endif + if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + + buf[sizeof(buf) - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(buf); +# else + len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), flush); + s->out -= s->stream.avail_out; + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_GZCOMPRESS */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + if (s->inbuf == Z_NULL) return -1L; + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return s->in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->in = s->out = offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if (offset >= s->out) { + offset -= s->out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + if (s->outbuf == Z_NULL) return -1L; + } + if (offset && s->back != EOF) { + s->back = EOF; + s->out++; + offset--; + if (s->last) s->z_err = Z_STREAM_END; + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return s->out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + if (!s->transparent) (void)inflateReset(&s->stream); + s->in = 0; + s->out = 0; + return fseek(s->file, s->start, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + /* With concatenated compressed files that can have embedded + * crc trailers, z_eof is no longer the only/best indicator of EOF + * on a gz_stream. Handle end-of-stream error explicitly here. + */ + if (s == NULL || s->mode != 'r') return 0; + if (s->z_eof) return 1; + return s->z_err == Z_STREAM_END; +} + +/* =========================================================================== + Returns 1 if reading and doing so transparently, otherwise zero. +*/ +int ZEXPORT gzdirect (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return 0; + return s->transparent; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return Z_STREAM_ERROR; +#else + if (do_flush (file, Z_FINISH) != Z_OK) + return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, (uLong)(s->in & 0xffffffff)); +#endif + } + return destroy((gz_stream*)file); +} + +#ifdef STDC +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +/* =========================================================================== + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char * ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} + +/* =========================================================================== + Clear the error and end-of-file flags, and do the same for the real file. +*/ +void ZEXPORT gzclearerr (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return; + if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; + s->z_eof = 0; + clearerr(s->file); +} diff --git a/zlib/infback.c b/zlib/infback.c new file mode 100644 index 000000000..455dbc9ee --- /dev/null +++ b/zlib/infback.c @@ -0,0 +1,623 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->write = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + + /* process literal */ + if (this.op == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/zlib/inffast.c b/zlib/inffast.c new file mode 100644 index 000000000..bbee92ed1 --- /dev/null +++ b/zlib/inffast.c @@ -0,0 +1,318 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code this; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + write = state->write; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = lcode[hold & lmask]; + dolen: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op == 0) { /* literal */ + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + PUP(out) = (unsigned char)(this.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = dcode[hold & dmask]; + dodist: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + from = window - OFF; + if (write == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (write < op) { /* wrap around window */ + from += wsize + write - op; + op -= write; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (write < len) { /* some from start of window */ + op = write; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += write - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + this = dcode[this.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + this = lcode[this.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and write == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/zlib/inffast.h b/zlib/inffast.h new file mode 100644 index 000000000..1e88d2d97 --- /dev/null +++ b/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/zlib/inffixed.h b/zlib/inffixed.h new file mode 100644 index 000000000..75ed4b597 --- /dev/null +++ b/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/zlib/inflate.c b/zlib/inflate.c new file mode 100644 index 000000000..792fdee8e --- /dev/null +++ b/zlib/inflate.c @@ -0,0 +1,1368 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common write == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->write = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + if (windowBits < 0) { + state->wrap = 0; + windowBits = -windowBits; + } + else { + state->wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) windowBits &= 15; +#endif + } + if (windowBits < 8 || windowBits > 15) { + ZFREE(strm, state); + strm->state = Z_NULL; + return Z_STREAM_ERROR; + } + state->wbits = (unsigned)windowBits; + state->window = Z_NULL; + return inflateReset(strm); +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->write = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->write = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->write; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->write, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->write = copy; + state->whave = state->wsize; + } + else { + state->write += dist; + if (state->write == state->wsize) state->write = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + break; + } + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + if ((int)(this.op) == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + state->mode = LIT; + break; + } + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(this.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->mode = DIST; + case DIST: + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + state->extra = (unsigned)(this.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + if (state->offset > state->whave + out - left) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->write) { + copy -= state->write; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->write - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} diff --git a/zlib/inflate.h b/zlib/inflate.h new file mode 100644 index 000000000..07bd3e78a --- /dev/null +++ b/zlib/inflate.h @@ -0,0 +1,115 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN, /* i: waiting for length/lit code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD or MEM mode -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME + NAME -> COMMENT -> HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or CHECK + STORED -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/zlib/inftrees.c b/zlib/inftrees.c new file mode 100644 index 000000000..8a9c13ff0 --- /dev/null +++ b/zlib/inftrees.c @@ -0,0 +1,329 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code this; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)1; + this.val = (unsigned short)0; + *(*table)++ = this; /* make a table to force an error */ + *(*table)++ = this; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked when a LENS table is being made + against the space in *table, ENOUGH, minus the maximum space needed by + the worst case distance code, MAXD. This should never happen, but the + sufficiency of ENOUGH has not been proven exhaustively, hence the check. + This assumes that when type == LENS, bits == 9. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + this.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + this.op = (unsigned char)0; + this.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + this.op = (unsigned char)(extra[work[sym]]); + this.val = base[work[sym]]; + } + else { + this.op = (unsigned char)(32 + 64); /* end of block */ + this.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = this; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)(len - drop); + this.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + this.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = this; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/zlib/inftrees.h b/zlib/inftrees.h new file mode 100644 index 000000000..b1104c87e --- /dev/null +++ b/zlib/inftrees.h @@ -0,0 +1,55 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1444 code structures (852 for length/literals + and 592 for distances, the latter actually the result of an + exhaustive search). The true maximum is not known, but the value + below is more than safe. */ +#define ENOUGH 2048 +#define MAXD 592 + +/* Type of code to build for inftable() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/zlib/trees.c b/zlib/trees.c new file mode 100644 index 000000000..7a66ddaa8 --- /dev/null +++ b/zlib/trees.c @@ -0,0 +1,1219 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2005 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id: trees.c,v 1.1 2006/07/22 20:34:08 oliskoli Exp $ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) + set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to BINARY or TEXT, using a crude approximation: + * set it to Z_TEXT if all symbols are either printable characters (33 to 255) + * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local void set_data_type(s) + deflate_state *s; +{ + int n; + + for (n = 0; n < 9; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + if (n == 9) + for (n = 14; n < 32; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/zlib/trees.h b/zlib/trees.h new file mode 100644 index 000000000..72facf900 --- /dev/null +++ b/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/zlib/uncompr.c b/zlib/uncompr.c new file mode 100644 index 000000000..cf608299d --- /dev/null +++ b/zlib/uncompr.c @@ -0,0 +1,61 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: uncompr.c,v 1.1 2006/07/22 20:34:08 oliskoli Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/zlib/zconf.h b/zlib/zconf.h new file mode 100644 index 000000000..58af16be8 --- /dev/null +++ b/zlib/zconf.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.h,v 1.1 2006/07/22 20:34:08 oliskoli Exp $ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/zlib/zconf.in.h b/zlib/zconf.in.h new file mode 100644 index 000000000..7c70c966d --- /dev/null +++ b/zlib/zconf.in.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.in.h,v 1.1 2006/07/22 20:34:11 oliskoli Exp $ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/zlib/zlib.3 b/zlib/zlib.3 new file mode 100644 index 000000000..90b816287 --- /dev/null +++ b/zlib/zlib.3 @@ -0,0 +1,159 @@ +.TH ZLIB 3 "18 July 2005" +.SH NAME +zlib \- compression/decompression library +.SH SYNOPSIS +[see +.I zlib.h +for full description] +.SH DESCRIPTION +The +.I zlib +library is a general purpose data compression library. +The code is thread safe. +It provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method (deflation) +but other algorithms will be added later +and will have the same stream interface. +.LP +Compression can be done in a single step if the buffers are large enough +(for example if an input file is mmap'ed), +or can be done by repeated calls of the compression function. +In the latter case, +the application must provide more input and/or consume the output +(providing more output space) before each call. +.LP +The library also supports reading and writing files in +.IR gzip (1) +(.gz) format +with an interface similar to that of stdio. +.LP +The library does not install any signal handler. +The decoder checks the consistency of the compressed data, +so the library should never crash even in case of corrupted input. +.LP +All functions of the compression library are documented in the file +.IR zlib.h . +The distribution source includes examples of use of the library +in the files +.I example.c +and +.IR minigzip.c . +.LP +Changes to this version are documented in the file +.I ChangeLog +that accompanies the source, +and are concerned primarily with bug fixes and portability enhancements. +.LP +A Java implementation of +.I zlib +is available in the Java Development Kit 1.1: +.IP +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html +.LP +A Perl interface to +.IR zlib , +written by Paul Marquess (pmqs@cpan.org), +is available at CPAN (Comprehensive Perl Archive Network) sites, +including: +.IP +http://www.cpan.org/modules/by-module/Compress/ +.LP +A Python interface to +.IR zlib , +written by A.M. Kuchling (amk@magnet.com), +is available in Python 1.5 and later versions: +.IP +http://www.python.org/doc/lib/module-zlib.html +.LP +A +.I zlib +binding for +.IR tcl (1), +written by Andreas Kupries (a.kupries@westend.com), +is availlable at: +.IP +http://www.westend.com/~kupries/doc/trf/man/man.html +.LP +An experimental package to read and write files in .zip format, +written on top of +.I zlib +by Gilles Vollant (info@winimage.com), +is available at: +.IP +http://www.winimage.com/zLibDll/unzip.html +and also in the +.I contrib/minizip +directory of the main +.I zlib +web site. +.SH "SEE ALSO" +The +.I zlib +web site can be found at either of these locations: +.IP +http://www.zlib.org +.br +http://www.gzip.org/zlib/ +.LP +The data format used by the zlib library is described by RFC +(Request for Comments) 1950 to 1952 in the files: +.IP +http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format) +.br +http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format) +.br +http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format) +.LP +These documents are also available in other formats from: +.IP +ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html +.LP +Mark Nelson (markn@ieee.org) wrote an article about +.I zlib +for the Jan. 1997 issue of Dr. Dobb's Journal; +a copy of the article is available at: +.IP +http://dogma.net/markn/articles/zlibtool/zlibtool.htm +.SH "REPORTING PROBLEMS" +Before reporting a problem, +please check the +.I zlib +web site to verify that you have the latest version of +.IR zlib ; +otherwise, +obtain the latest version and see if the problem still exists. +Please read the +.I zlib +FAQ at: +.IP +http://www.gzip.org/zlib/zlib_faq.html +.LP +before asking for help. +Send questions and/or comments to zlib@gzip.org, +or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). +.SH AUTHORS +Version 1.2.3 +Copyright (C) 1995-2005 Jean-loup Gailly (jloup@gzip.org) +and Mark Adler (madler@alumni.caltech.edu). +.LP +This software is provided "as-is," +without any express or implied warranty. +In no event will the authors be held liable for any damages +arising from the use of this software. +See the distribution directory with respect to requirements +governing redistribution. +The deflate format used by +.I zlib +was defined by Phil Katz. +The deflate and +.I zlib +specifications were written by L. Peter Deutsch. +Thanks to all the people who reported problems and suggested various +improvements in +.IR zlib ; +who are too numerous to cite here. +.LP +UNIX manual page by R. P. C. Rodgers, +U.S. National Library of Medicine (rodgers@nlm.nih.gov). +.\" end of man page diff --git a/zlib/zlib.h b/zlib/zlib.h new file mode 100644 index 000000000..a4431229e --- /dev/null +++ b/zlib/zlib.h @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3.f-GPSBabel" +#define ZLIB_VERNUM 0x123f + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/zlib/zutil.c b/zlib/zutil.c new file mode 100644 index 000000000..5f50b2471 --- /dev/null +++ b/zlib/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zutil.c,v 1.1 2006/07/22 20:34:11 oliskoli Exp $ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch (sizeof(uInt)) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch (sizeof(uLong)) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch (sizeof(voidpf)) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch (sizeof(z_off_t)) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/zlib/zutil.h b/zlib/zutil.h new file mode 100644 index 000000000..2045fda8a --- /dev/null +++ b/zlib/zutil.h @@ -0,0 +1,269 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: zutil.h,v 1.1 2006/07/22 20:34:11 oliskoli Exp $ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef STDC +# ifndef _WIN32_WCE +# include +# endif +# include +# include +#endif +#ifdef NO_ERRNO_H +# ifdef _WIN32_WCE + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. We rename it to + * avoid conflict with other libraries that use the same workaround. + */ +# define errno z_errno +# endif + extern int errno; +#else +# ifndef _WIN32_WCE +# include +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 + #include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# define vsnprintf _vsnprintf +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ -- 2.30.2